Browse Source

Merge some changes from branch 'gtk2' into main

Conflicts:
	AUTHORS
	ChangeLog
	NEWS
	src/mssh-window.h
Héctor García 10 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
 Contributors
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
     Balint Deak  <[email protected]>
     Balint Deak  <[email protected]>
+    Francisco Licerán <[email protected]>
+    Mario J. Barchéin <[email protected]>
+    Oscar Fernandez <[email protected]>

+ 18 - 4
ChangeLog

@@ -8,6 +8,24 @@
 
 
 	Added support to create a new session. Patch from Balint Deak.
 	Added support to create a new session. Patch from Balint Deak.
 
 
+2014-03-13  Héctor García  <[email protected]>
+
+	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  <[email protected]>
+
+	Make paste with mouse middle button focus on terminal
+
+2014-01-15  Héctor García  <[email protected]>
+
+	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 <[email protected]> patch
+
+	Allow window to be smaller than 1024x768. Patch from Lorenzo Masini <[email protected]>
+
 2014-01-15  Héctor García  <[email protected]>
 2014-01-15  Héctor García  <[email protected]>
 
 
 	Bumped version to 2.0 gtk3 support
 	Bumped version to 2.0 gtk3 support
@@ -22,10 +40,6 @@
 
 
 	Change table where to place terminals to grid
 	Change table where to place terminals to grid
 
 
-2014-01-15  Héctor García  <[email protected]>
-
-	Bumped version to 1.3 gtk2 deprecated symbols free
-
 	Replaced GDK_<keyname> with GDK_KEY_<keyname>
 	Replaced GDK_<keyname> with GDK_KEY_<keyname>
 
 
 	Changed direct access to use accessor for terminal->parent
 	Changed direct access to use accessor for terminal->parent

+ 2 - 0
Makefile.am

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

+ 5 - 0
NEWS

@@ -4,3 +4,8 @@
     New ctrl + shift + n combinatio to add a new server.
     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.
     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 <[email protected]>
+.SH COPYRIGHT
+Copyright (C) 2014 Héctor García <[email protected]>
+Copyright (C) 2009 Bradley Smith <brad@brad\-smith.co.uk>
+.SH REPORTING BUGS
+Report bugs to <[email protected]>.

+ 38 - 0
mssh.bash-completion

@@ -0,0 +1,38 @@
+# bash completion for mssh
+# Written by Héctor García <[email protected]>
+
+_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)
 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[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]);
     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 gboolean mssh_window_session_close(gpointer data);
 static void mssh_window_session_focused(MSSHTerminal *terminal,
 static void mssh_window_session_focused(MSSHTerminal *terminal,
     gpointer data);
     gpointer data);
+static gboolean mssh_window_mouse_paste_cb(MSSHTerminal *terminal,
+    gpointer data);
 static void mssh_window_insert(GtkWidget *widget, gchar *new_text,
 static void mssh_window_insert(GtkWidget *widget, gchar *new_text,
     gint new_text_length, gint *position, gpointer data);
     gint new_text_length, gint *position, gpointer data);
 static void mssh_window_add_session(MSSHWindow *window, char *hostname);
 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)
 static void mssh_window_destroy(GtkWidget *widget, gpointer data)
 {
 {
     gtk_main_quit();
     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,
 static void mssh_window_session_focused(MSSHTerminal *terminal,
     gpointer data)
     gpointer data)
 {
 {
@@ -422,6 +450,8 @@ static void mssh_window_add_session(MSSHWindow *window, char *hostname)
         G_CALLBACK(mssh_window_session_closed), window);
         G_CALLBACK(mssh_window_session_closed), window);
     g_signal_connect(G_OBJECT(terminal), "session-focused",
     g_signal_connect(G_OBJECT(terminal), "session-focused",
         G_CALLBACK(mssh_window_session_focused), window);
         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);
     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 *file_item = gtk_menu_item_new_with_label("File");
     GtkWidget *edit_item = gtk_menu_item_new_with_label("Edit");
     GtkWidget *edit_item = gtk_menu_item_new_with_label("Edit");
     GtkWidget *server_item = gtk_menu_item_new_with_label("Servers");
     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(
     GtkWidget *file_quit = gtk_image_menu_item_new_from_stock(
         GTK_STOCK_QUIT, NULL);
         GTK_STOCK_QUIT, NULL);
@@ -460,6 +491,8 @@ static void mssh_window_init(MSSHWindow* window)
 
 
     window->server_menu = gtk_menu_new();
     window->server_menu = gtk_menu_new();
 
 
+    window->command_menu = gtk_menu_new();
+
     window->global_entry = entry;
     window->global_entry = entry;
 
 
     window->last_closed = -1;
     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(edit_item), edit_menu);
     gtk_menu_item_set_submenu(GTK_MENU_ITEM(server_item),
     gtk_menu_item_set_submenu(GTK_MENU_ITEM(server_item),
         window->server_menu);
         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_add);
     gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), file_sendhost);
     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), file_item);
     gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), edit_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), server_item);
+    gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), command_item);
 
 
     g_signal_connect(G_OBJECT(entry), "key-press-event",
     g_signal_connect(G_OBJECT(entry), "key-press-event",
         G_CALLBACK(mssh_window_key_press), window);
         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_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);
     gtk_window_set_title(GTK_WINDOW(window), PACKAGE_NAME);
 
 
     client = gconf_client_get_default();
     client = gconf_client_get_default();
@@ -609,6 +646,18 @@ void mssh_window_start_session(MSSHWindow* window, char **env,
     mssh_window_relayout(window);
     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)
 static void mssh_window_class_init(MSSHWindowClass *klass)
 {
 {
 }
 }

+ 3 - 0
src/mssh-window.h

@@ -23,6 +23,7 @@ typedef struct
     GtkWindow widget;
     GtkWindow widget;
     GtkWidget *grid;
     GtkWidget *grid;
     GtkWidget *server_menu;
     GtkWidget *server_menu;
+    GtkWidget *command_menu;
     GtkWidget *global_entry;
     GtkWidget *global_entry;
     GtkAccelGroup *accel;
     GtkAccelGroup *accel;
     GArray *terminals;
     GArray *terminals;
@@ -39,6 +40,7 @@ typedef struct
     GtkWidget *last_focus;
     GtkWidget *last_focus;
     int is_maximized;
     int is_maximized;
     gboolean recolor_focused;
     gboolean recolor_focused;
+    GData **commands;
 } MSSHWindow;
 } MSSHWindow;
 
 
 typedef struct
 typedef struct
@@ -51,6 +53,7 @@ GType mssh_window_get_type(void) G_GNUC_CONST;
 GtkWidget* mssh_window_new(void);
 GtkWidget* mssh_window_new(void);
 void mssh_window_start_session(MSSHWindow* window, char **env,
 void mssh_window_start_session(MSSHWindow* window, char **env,
     GArray *hosts, long cols);
     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_relayout(MSSHWindow *window);
 void mssh_window_session_closed(MSSHTerminal *terminal, gpointer data);
 void mssh_window_session_closed(MSSHTerminal *terminal, gpointer data);
 gboolean mssh_window_focus(GtkWidget *widget, GObject *acceleratable,
 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)
         if(strcmp(line, "") == 0)
             continue;
             continue;
 
 
+        if(*line == '#')
+            continue;
+
+        if(*line == '{')
+            continue;
+
         if((sep = strchr(line, ':')) == NULL)
         if((sep = strchr(line, ':')) == NULL)
         {
         {
             printf("Line %d: Failed to parse line '%s'\n", lineno, line);
             printf("Line %d: Failed to parse line '%s'\n", lineno, line);
@@ -159,6 +165,65 @@ GData **parse_aliases(char *conffile)
     return aliases;
     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[])
 int main(int argc, char* argv[], char* env[])
 {
 {
     GtkWidget* window;
     GtkWidget* window;
@@ -166,6 +231,7 @@ int main(int argc, char* argv[], char* env[])
     char *home, *conffile;
     char *home, *conffile;
     long cols = 0;
     long cols = 0;
     GData **aliases = NULL;
     GData **aliases = NULL;
+    GData **commands = NULL;
     GArray *hosts = NULL;
     GArray *hosts = NULL;
 
 
     static struct option long_options[] =
     static struct option long_options[] =
@@ -185,6 +251,7 @@ int main(int argc, char* argv[], char* env[])
         snprintf(conffile, len, "%s/%s", home, CONFFILE);
         snprintf(conffile, len, "%s/%s", home, CONFFILE);
 
 
         aliases = parse_aliases(conffile);
         aliases = parse_aliases(conffile);
+        commands = parse_commands(conffile);
         free(conffile);
         free(conffile);
     }
     }
     else
     else
@@ -286,7 +353,10 @@ int main(int argc, char* argv[], char* env[])
     g_signal_connect(G_OBJECT(window), "destroy",
     g_signal_connect(G_OBJECT(window), "destroy",
         G_CALLBACK(on_mssh_destroy), NULL);
         G_CALLBACK(on_mssh_destroy), NULL);
 
 
+    MSSH_WINDOW(window)->commands = commands;
+
     mssh_window_start_session(MSSH_WINDOW(window), env, hosts, cols);
     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_widget_show_all(window);
     gtk_main();
     gtk_main();