Browse Source

Merge some changes from branch 'gtk2' into main

Conflicts:
	AUTHORS
	ChangeLog
	NEWS
	src/mssh-window.h
Héctor García 4 years ago
parent
commit
721a328aa3
10 changed files with 255 additions and 19 deletions
  1. 3 0
      AUTHORS
  2. 18 4
      ChangeLog
  3. 2 0
      Makefile.am
  4. 5 0
      NEWS
  5. 39 0
      mssh.1
  6. 38 0
      mssh.bash-completion
  7. 27 14
      src/mssh-terminal.c
  8. 50 1
      src/mssh-window.c
  9. 3 0
      src/mssh-window.h
  10. 70 0
      src/mssh.c

+ 3 - 0
AUTHORS

@@ -9,3 +9,6 @@ Founder and Lead Developer:
 Contributors
 ----------------------------------------------------------------------------
     Balint Deak  <dbalint@gmail.com>
+    Francisco Licerán <francisco@intelligenia.com>
+    Mario J. Barchéin <mario@intelligenia.com>
+    Oscar Fernandez <oscaretu@gmail.com>

+ 18 - 4
ChangeLog

@@ -8,6 +8,24 @@
 
 	Added support to create a new session. Patch from Balint Deak.
 
+2014-03-13  Héctor García  <hector@debian.org>
+
+	Added a new feature to the aliases file. Now you can define aliases for command line text to send using {}
+
+2014-01-20  Héctor García  <hector@debian.org>
+
+	Make paste with mouse middle button focus on terminal
+
+2014-01-15  Héctor García  <hector@debian.org>
+
+	Added patch from Oscar Fernandez to support comments on configuration archive
+
+	Added patch from Mario J. Barchéin and Francisco Licerán to support port numbers on host
+
+	Copy Debian's mssh man page to upstream and added Karl Goetz <karl@kgoetz.id.au> patch
+
+	Allow window to be smaller than 1024x768. Patch from Lorenzo Masini <rugginoso@develer.com>
+
 2014-01-15  Héctor García  <hector@debian.org>
 
 	Bumped version to 2.0 gtk3 support
@@ -22,10 +40,6 @@
 
 	Change table where to place terminals to grid
 
-2014-01-15  Héctor García  <hector@debian.org>
-
-	Bumped version to 1.3 gtk2 deprecated symbols free
-
 	Replaced GDK_<keyname> with GDK_KEY_<keyname>
 
 	Changed direct access to use accessor for terminal->parent

+ 2 - 0
Makefile.am

@@ -11,3 +11,5 @@ if GCONF_SCHEMAS_INSTALL
 install-data-local:
 	GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $(top_builddir)/$(schema_DATA)
 endif
+
+man1_MANS = mssh.1

+ 5 - 0
NEWS

@@ -4,3 +4,8 @@
     New ctrl + shift + n combinatio to add a new server.
 
     Now you can have different colors on select terminal. MUST update mssh.schema or mssh will crash.
+
+2014-01-17
+    Since around 15 Jan 2014 I (Héctor García) did take over code development and maintenance.
+
+    Hope Bradley Smith can come around some time in the future to get his great project back.

+ 39 - 0
mssh.1

@@ -0,0 +1,39 @@
+.TH MSSH 1
+.SH NAME
+mssh \- tool to administrate multiple servers at once
+.SH SYNOPSIS
+.B mssh
+[\fIOPTION\fR]... (\-a \fIALIAS\fR | \fIHOSTS\fR[\fI:PORT\fR])
+.SH DESCRIPTION
+.B MultiSSH
+is a GTK+ based ssh client to issue the same commands to multiple servers.
+
+.B MultiSSH
+will connect to the servers specified in \fIHOSTS\fR into optional \fIPORT\fR.
+.SH OPTIONS
+.TP
+\fB-a\fR, \fB\-\-alias\fR=\fIALIAS\fR
+Open hosts associated with named alias
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+Display this help and exit
+.TP
+\fB\-V\fR, \fB\-\-version\fR
+Output version information and exit
+.SH CONFIGURATION
+The configuration file for
+.B MultiSSH
+should be located in
+.B $HOME/.mssh_clusters
+
+It uses a simple key: pair system with an alias on the left of the
+colon and a space separated list of hosts on the right.
+
+.SH AUTHOR
+.B MultiSSH
+was originally written by Bradley Smith <brad@brad\-smith.co.uk> and it is currently develop by Héctor García <hector@debian.org>
+.SH COPYRIGHT
+Copyright (C) 2014 Héctor García <hector@debian.org>
+Copyright (C) 2009 Bradley Smith <brad@brad\-smith.co.uk>
+.SH REPORTING BUGS
+Report bugs to <hector@debian.org>.

+ 38 - 0
mssh.bash-completion

@@ -0,0 +1,38 @@
+# bash completion for mssh
+# Written by Héctor García <hector@debian.org>
+
+_mssh_alias()
+{
+  if [ -f ~/.mssh_clusters ]; then
+    COMPREPLY=( $( compgen -W '$( command cat ~/.mssh_clusters 2>/dev/null \
+       | grep -v "^\s*$" | grep -v "^#" | sed -e "s/:.*$//" )' -- $cur ) )
+  fi
+
+  return 0
+}  
+
+_mssh()
+{
+  local cur=${COMP_WORDS[COMP_CWORD]} 
+  local prev=${COMP_WORDS[COMP_CWORD-1]}
+
+  COMPREPLY=()
+
+  case "$prev" in
+   -a)
+     _mssh_alias
+     return 0
+     ;;
+  esac
+
+  # completing -a option
+  if [[ "$cur" == -* ]]; then
+    COMPREPLY=( $( compgen -W "-a" -- $cur ) )
+    return 0
+  fi
+
+  _known_hosts_real "$cur"
+
+}
+
+complete -F _mssh mssh

+ 27 - 14
src/mssh-terminal.c

@@ -47,23 +47,36 @@ void mssh_terminal_init_session(MSSHTerminal *terminal, char *hostname)
 
 void mssh_terminal_start_session(MSSHTerminal *terminal, char **env)
 {
-    char *args[3];
+    char *args[5];
+    char *fullhost;
+    char *host = NULL;
+    char *port = NULL;
+
+    fullhost = strdup(terminal->hostname);
+    host = strtok(fullhost, ":");
+    port = strtok(NULL, "");
 
     args[0] = strdup("ssh");
-    args[1] = terminal->hostname;
-    args[2] = NULL;
-
-    vte_terminal_fork_command_full(  VTE_TERMINAL(terminal), 
-                                     VTE_PTY_DEFAULT,
-                                     NULL,  /* working dir */
-                                     args,
-                                     env, 
-                                     G_SPAWN_SEARCH_PATH,
-                                     NULL,  /* child_setup */
-                                     NULL,  /* child_setup_data */
-                                     NULL,  /* *child_pid */
-                                     NULL); /* Error handling */
+    args[1] = host;
+
+    if (!port)
+        args[2] = NULL;
+    else {
+         args[2] = strdup("-p");
+         args[3] = port;
+         args[4] = NULL;
+    }
 
+    vte_terminal_fork_command_full(VTE_TERMINAL(terminal),
+                                   VTE_PTY_NO_LASTLOG|VTE_PTY_NO_UTMP|VTE_PTY_NO_WTMP,
+                                   NULL,  /* working dir */
+                                   args,
+                                   env,
+                                   G_SPAWN_SEARCH_PATH,
+                                   NULL,  /* child_setup */
+                                   NULL,  /* child_setup_data */
+                                   NULL,  /* *child_pid */
+                                   NULL); /* Error handling */
 
     free(args[0]);
 }

+ 50 - 1
src/mssh-window.c

@@ -25,6 +25,8 @@ static gboolean mssh_window_entry_focused(GtkWidget *widget,
 static gboolean mssh_window_session_close(gpointer data);
 static void mssh_window_session_focused(MSSHTerminal *terminal,
     gpointer data);
+static gboolean mssh_window_mouse_paste_cb(MSSHTerminal *terminal,
+    gpointer data);
 static void mssh_window_insert(GtkWidget *widget, gchar *new_text,
     gint new_text_length, gint *position, gpointer data);
 static void mssh_window_add_session(MSSHWindow *window, char *hostname);
@@ -63,6 +65,24 @@ static void mssh_window_sendhost(GtkWidget *widget, gpointer data)
     }
 }
 
+static void mssh_window_sendcommand(GtkWidget *widget, gpointer data)
+{
+    int i;
+    char *command;
+
+    MSSHWindow *window = MSSH_WINDOW(data);
+    GtkMenuItem *item = (GtkMenuItem *)widget;
+
+    command = g_datalist_get_data(MSSH_WINDOW(data)->commands, gtk_menu_item_get_label (item));
+
+    for(i = 0; i < window->terminals->len; i++)
+    {
+        mssh_terminal_send_string(g_array_index(window->terminals,
+            MSSHTerminal*, i), command);
+    }
+
+}
+
 static void mssh_window_destroy(GtkWidget *widget, gpointer data)
 {
     gtk_main_quit();
@@ -286,6 +306,14 @@ void mssh_window_session_closed(MSSHTerminal *terminal, gpointer data)
     }
 }
 
+static gboolean mssh_window_mouse_paste_cb(MSSHTerminal *terminal,
+    gpointer data)
+{
+    gtk_widget_grab_focus(GTK_WIDGET(terminal));
+
+    return FALSE;
+}
+
 static void mssh_window_session_focused(MSSHTerminal *terminal,
     gpointer data)
 {
@@ -422,6 +450,8 @@ static void mssh_window_add_session(MSSHWindow *window, char *hostname)
         G_CALLBACK(mssh_window_session_closed), window);
     g_signal_connect(G_OBJECT(terminal), "session-focused",
         G_CALLBACK(mssh_window_session_focused), window);
+    g_signal_connect(GTK_WIDGET(terminal), "button-release-event",
+        G_CALLBACK(mssh_window_mouse_paste_cb), window);
 
     mssh_terminal_init_session(terminal, hostname);
 
@@ -443,6 +473,7 @@ static void mssh_window_init(MSSHWindow* window)
     GtkWidget *file_item = gtk_menu_item_new_with_label("File");
     GtkWidget *edit_item = gtk_menu_item_new_with_label("Edit");
     GtkWidget *server_item = gtk_menu_item_new_with_label("Servers");
+    GtkWidget *command_item = gtk_menu_item_new_with_label("Commands");
 
     GtkWidget *file_quit = gtk_image_menu_item_new_from_stock(
         GTK_STOCK_QUIT, NULL);
@@ -460,6 +491,8 @@ static void mssh_window_init(MSSHWindow* window)
 
     window->server_menu = gtk_menu_new();
 
+    window->command_menu = gtk_menu_new();
+
     window->global_entry = entry;
 
     window->last_closed = -1;
@@ -476,6 +509,8 @@ static void mssh_window_init(MSSHWindow* window)
     gtk_menu_item_set_submenu(GTK_MENU_ITEM(edit_item), edit_menu);
     gtk_menu_item_set_submenu(GTK_MENU_ITEM(server_item),
         window->server_menu);
+    gtk_menu_item_set_submenu(GTK_MENU_ITEM(command_item),
+        window->command_menu);
 
     gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), file_add);
     gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), file_sendhost);
@@ -493,6 +528,7 @@ static void mssh_window_init(MSSHWindow* window)
     gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), file_item);
     gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), edit_item);
     gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), server_item);
+    gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), command_item);
 
     g_signal_connect(G_OBJECT(entry), "key-press-event",
         G_CALLBACK(mssh_window_key_press), window);
@@ -511,7 +547,8 @@ static void mssh_window_init(MSSHWindow* window)
 
     gtk_container_add(GTK_CONTAINER(window), vbox);
 
-    gtk_widget_set_size_request(GTK_WIDGET(window), 1024, 768);
+    gtk_widget_set_size_request(GTK_WIDGET(window), 0, 0);
+    gtk_window_set_default_size(GTK_WINDOW(window), 1024, 768);
     gtk_window_set_title(GTK_WINDOW(window), PACKAGE_NAME);
 
     client = gconf_client_get_default();
@@ -609,6 +646,18 @@ void mssh_window_start_session(MSSHWindow* window, char **env,
     mssh_window_relayout(window);
 }
 
+void mssh_window_add_command(GQuark key_id, gpointer data, gpointer user_data)
+{
+    GtkWidget *menu_item;
+    GtkWidget* window = (GtkWidget *)user_data;
+
+    menu_item = gtk_menu_item_new_with_label(g_quark_to_string (key_id));
+
+    gtk_menu_shell_append(GTK_MENU_SHELL(MSSH_WINDOW(window)->command_menu), menu_item);
+    g_signal_connect(G_OBJECT(menu_item), "activate",
+        G_CALLBACK(mssh_window_sendcommand), window);
+}
+
 static void mssh_window_class_init(MSSHWindowClass *klass)
 {
 }

+ 3 - 0
src/mssh-window.h

@@ -23,6 +23,7 @@ typedef struct
     GtkWindow widget;
     GtkWidget *grid;
     GtkWidget *server_menu;
+    GtkWidget *command_menu;
     GtkWidget *global_entry;
     GtkAccelGroup *accel;
     GArray *terminals;
@@ -39,6 +40,7 @@ typedef struct
     GtkWidget *last_focus;
     int is_maximized;
     gboolean recolor_focused;
+    GData **commands;
 } MSSHWindow;
 
 typedef struct
@@ -51,6 +53,7 @@ GType mssh_window_get_type(void) G_GNUC_CONST;
 GtkWidget* mssh_window_new(void);
 void mssh_window_start_session(MSSHWindow* window, char **env,
     GArray *hosts, long cols);
+void mssh_window_add_command(GQuark key_id, gpointer data, gpointer user_data);
 void mssh_window_relayout(MSSHWindow *window);
 void mssh_window_session_closed(MSSHTerminal *terminal, gpointer data);
 gboolean mssh_window_focus(GtkWidget *widget, GObject *acceleratable,

+ 70 - 0
src/mssh.c

@@ -121,6 +121,12 @@ GData **parse_aliases(char *conffile)
         if(strcmp(line, "") == 0)
             continue;
 
+        if(*line == '#')
+            continue;
+
+        if(*line == '{')
+            continue;
+
         if((sep = strchr(line, ':')) == NULL)
         {
             printf("Line %d: Failed to parse line '%s'\n", lineno, line);
@@ -159,6 +165,65 @@ GData **parse_aliases(char *conffile)
     return aliases;
 }
 
+GData **parse_commands(char *conffile)
+{
+    FILE *file;
+    char *line;
+    int lineno = 0;
+
+    GData **commands = malloc(sizeof(GData*));
+    g_datalist_init(commands);
+
+    if((file = fopen(conffile, "r")) == NULL)
+        return commands;
+
+    while((line = fgetline(file)) != NULL)
+    {
+        char *sep, *command, *commandline;
+
+        lineno++;
+
+        if(strcmp(line, "") == 0)
+            continue;
+
+        if(*line == '#')
+            continue;
+
+        if(*line != '{')
+            continue;
+
+        if((sep = strchr(line, '}')) == NULL)
+        {
+            printf("Line %d: Failed to parse line '%s'\n", lineno, line);
+            exit(EXIT_FAILURE);
+        }
+
+        *sep = '\0';
+        command = line + 1;
+
+        if((commandline = index(sep + 1, ' ')) == NULL)
+        {
+            printf("Line %d: Command Alias '%s' specifies no command\n", lineno,
+                command);
+            exit(EXIT_FAILURE);
+        }
+        while ( *commandline == ' ' ) { commandline++; }
+
+        sep = commandline;
+        while ( ( sep = index(sep, '\\') ) != NULL ) {
+            if ( *(sep+1) == 'n' ) {
+                *sep = ' ';
+                *(sep+1) = '\n';
+            }
+            sep++;
+        }
+
+        g_datalist_set_data(commands, command, commandline);
+    }
+
+    return commands;
+}
+
 int main(int argc, char* argv[], char* env[])
 {
     GtkWidget* window;
@@ -166,6 +231,7 @@ int main(int argc, char* argv[], char* env[])
     char *home, *conffile;
     long cols = 0;
     GData **aliases = NULL;
+    GData **commands = NULL;
     GArray *hosts = NULL;
 
     static struct option long_options[] =
@@ -185,6 +251,7 @@ int main(int argc, char* argv[], char* env[])
         snprintf(conffile, len, "%s/%s", home, CONFFILE);
 
         aliases = parse_aliases(conffile);
+        commands = parse_commands(conffile);
         free(conffile);
     }
     else
@@ -286,7 +353,10 @@ int main(int argc, char* argv[], char* env[])
     g_signal_connect(G_OBJECT(window), "destroy",
         G_CALLBACK(on_mssh_destroy), NULL);
 
+    MSSH_WINDOW(window)->commands = commands;
+
     mssh_window_start_session(MSSH_WINDOW(window), env, hosts, cols);
+    g_datalist_foreach(commands, mssh_window_add_command, window);
 
     gtk_widget_show_all(window);
     gtk_main();