Kaynağa Gözat

Merge commit 'upstream/1.1'

Bradley Smith 15 yıl önce
ebeveyn
işleme
21d27137a4
9 değiştirilmiş dosya ile 203 ekleme ve 41 silme
  1. 8 0
      ChangeLog
  2. 1 1
      Makefile.am
  3. 1 1
      Makefile.in
  4. 10 10
      configure
  5. 1 1
      configure.ac
  6. 2 0
      mssh_clusters.conf
  7. 5 3
      src/mssh-window.c
  8. 2 2
      src/mssh-window.h
  9. 173 23
      src/mssh.c

+ 8 - 0
ChangeLog

@@ -1,3 +1,11 @@
+2009-09-05  Bradley Smith  <[email protected]>
+
+	Bump version to 1.1.
+
+2009-09-03  Bradley Smith  <[email protected]>
+
+	Implement .mssh_clusters config file.
+
 2009-09-02  Bradley Smith  <[email protected]>
 
 	Bump version to 1.0.

+ 1 - 1
Makefile.am

@@ -1,6 +1,6 @@
 SUBDIRS = src
 
-EXTRA_DIST = mssh.schemas
+EXTRA_DIST = mssh.schemas mssh_clusters.conf
 
 SCHEMAS_FILE = mssh.schemas
 

+ 1 - 1
Makefile.in

@@ -213,7 +213,7 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 SUBDIRS = src
-EXTRA_DIST = mssh.schemas
+EXTRA_DIST = mssh.schemas mssh_clusters.conf
 SCHEMAS_FILE = mssh.schemas
 schemadir = $(GCONF_SCHEMA_FILE_DIR)
 schema_DATA = $(SCHEMAS_FILE)

+ 10 - 10
configure

@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.64 for MultiSSH 1.0.
+# Generated by GNU Autoconf 2.64 for MultiSSH 1.1.
 #
 # Report bugs to <[email protected]>.
 #
@@ -548,8 +548,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='MultiSSH'
 PACKAGE_TARNAME='mssh'
-PACKAGE_VERSION='1.0'
-PACKAGE_STRING='MultiSSH 1.0'
+PACKAGE_VERSION='1.1'
+PACKAGE_STRING='MultiSSH 1.1'
 PACKAGE_BUGREPORT='[email protected]'
 PACKAGE_URL=''
 
@@ -1202,7 +1202,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures MultiSSH 1.0 to adapt to many kinds of systems.
+\`configure' configures MultiSSH 1.1 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1268,7 +1268,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of MultiSSH 1.0:";;
+     short | recursive ) echo "Configuration of MultiSSH 1.1:";;
    esac
   cat <<\_ACEOF
 
@@ -1367,7 +1367,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-MultiSSH configure 1.0
+MultiSSH configure 1.1
 generated by GNU Autoconf 2.64
 
 Copyright (C) 2009 Free Software Foundation, Inc.
@@ -1422,7 +1422,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by MultiSSH $as_me 1.0, which was
+It was created by MultiSSH $as_me 1.1, which was
 generated by GNU Autoconf 2.64.  Invocation command line was
 
   $ $0 $@
@@ -2232,7 +2232,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='mssh'
- VERSION='1.0'
+ VERSION='1.1'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -4063,7 +4063,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by MultiSSH $as_me 1.0, which was
+This file was extended by MultiSSH $as_me 1.1, which was
 generated by GNU Autoconf 2.64.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -4127,7 +4127,7 @@ Report bugs to <[email protected]>."
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_version="\\
-MultiSSH config.status 1.0
+MultiSSH config.status 1.1
 configured by $0, generated by GNU Autoconf 2.64,
   with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 

+ 1 - 1
configure.ac

@@ -1,4 +1,4 @@
-AC_INIT([MultiSSH], [1.0], [[email protected]], [mssh])
+AC_INIT([MultiSSH], [1.1], [[email protected]], [mssh])
 AM_CONFIG_HEADER([config.h])
 AM_INIT_AUTOMAKE
 

+ 2 - 0
mssh_clusters.conf

@@ -0,0 +1,2 @@
+alias1: host1 host2
+alias2: [alias1] host3

+ 5 - 3
src/mssh-window.c

@@ -351,10 +351,11 @@ static void mssh_window_init(MSSHWindow* window)
 	gconf_client_notify(client, MSSH_GCONF_KEY_QUIT_ALL_ENDED);
 }
 
-void mssh_window_start_session(MSSHWindow* window, char **env, int nhosts,
-	char **servers)
+void mssh_window_start_session(MSSHWindow* window, char **env,
+	GArray *hosts)
 {
 	int i, j, k;
+	int nhosts = hosts->len;
 	int rows = (nhosts / 2) + (nhosts % 2);
 
 	window->env = env;
@@ -366,7 +367,8 @@ void mssh_window_start_session(MSSHWindow* window, char **env, int nhosts,
 			k = j + i*2;
 			if(k < nhosts)
 			{
-				mssh_window_add_session(window, servers[k]);
+				mssh_window_add_session(window, g_array_index(hosts,
+					char*, k));
 			}
 		}
 	}

+ 2 - 2
src/mssh-window.h

@@ -39,8 +39,8 @@ typedef struct
 GType mssh_window_get_type(void) G_GNUC_CONST;
 
 GtkWidget* mssh_window_new(void);
-void mssh_window_start_session(MSSHWindow* window, char **env, int nhosts,
-	char **servers);
+void mssh_window_start_session(MSSHWindow* window, char **env,
+	GArray *hosts);
 void mssh_window_relayout(MSSHWindow *window);
 void mssh_window_session_closed(MSSHTerminal *terminal, gpointer data);
 

+ 173 - 23
src/mssh.c

@@ -8,6 +8,7 @@
 #include "config.h"
 #include "mssh-window.h"
 
+#define CONFFILE	".mssh_clusters"
 #define PKGINFO		PACKAGE_NAME " " VERSION
 #define COPYRIGHT	"Copyright (C) 2009 Bradley Smith <[email protected]>"
 
@@ -22,38 +23,188 @@ void usage(const char *argv0)
 	fprintf(stderr, "%s\n", PKGINFO);
 	fprintf(stderr, "%s\n", COPYRIGHT);
 	fprintf(stderr, "An ssh client to issue the same commands to multiple servers\n\n");
-	fprintf(stderr, "Usage: %s [OPTION]... [HOSTS]\n\n", argv0);
+	fprintf(stderr, "Usage: %s [OPTION]... (-a ALIAS | HOSTS)\n\n",
+		argv0);
 	fprintf(stderr,
-		"  -h, --help       Display this help and exit\n");
+		"  -a, --alias=ALIAS    Open hosts associated with named alias\n");
 	fprintf(stderr,
-		"  -V, --version    Output version information and exit\n");
+		"  -h, --help           Display this help and exit\n");
+	fprintf(stderr,
+		"  -V, --version        Output version information and exit\n");
 	fprintf(stderr, "\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT);
 	exit(EXIT_FAILURE);
 }
 
+static char *fgetline(FILE *stream)
+{
+    size_t len = 64;
+    size_t pos = 0;
+    char c;
+    char *buf;
+
+    if((buf = malloc(len)) == NULL)
+    {
+        perror("malloc");
+		exit(EXIT_FAILURE);
+    }
+
+    while((c = fgetc(stream)) != EOF)
+    {
+        if(pos >= len)
+        {
+            len *= 2;
+            if((buf = realloc(buf, len)) == NULL)
+            {
+                perror("realloc");
+				exit(EXIT_FAILURE);
+            }
+        }
+        if(c == '\n')
+        {
+            buf[pos++] = '\0';
+            break;
+        }
+        else
+        {
+            buf[pos++] = c;
+        }
+    }
+
+	if(c == EOF)
+	{
+		free(buf);
+		return NULL;
+	}
+
+    return buf;
+}
+
+void append_alias(char *alias, GArray *hosts, GData **aliases, int lineno)
+{
+	int i;
+	GArray *fetched;
+
+	if((fetched = g_datalist_get_data(aliases, alias)) == NULL)
+	{
+		printf("Line %d: Alias '%s' not defined\n", lineno, alias);
+		exit(EXIT_FAILURE);
+	}
+
+	for(i = 0; i < fetched->len; i++)
+	{
+		g_array_append_val(hosts, g_array_index(fetched, char*, i));
+	}
+}
+
+GData **parse_aliases(char *conffile)
+{
+	FILE *file;
+	char *line;
+	int lineno = 0;
+
+	GData **aliases = malloc(sizeof(GData*));
+	g_datalist_init(aliases);
+
+	if((file = fopen(conffile, "r")) == NULL)
+		return aliases;
+
+	while((line = fgetline(file)) != NULL)
+	{
+		char *sep, *alias, *hoststr, *tmp;
+		GArray *hosts;
+
+		lineno++;
+
+		if(strcmp(line, "") == 0)
+			continue;
+
+		if((sep = strchr(line, ':')) == NULL)
+		{
+			printf("Line %d: Failed to parse line '%s'\n", lineno, line);
+			exit(EXIT_FAILURE);
+		}
+
+		*sep = '\0';
+		alias = line;
+		hoststr = sep + 1;
+
+		if((tmp = strtok(hoststr, " ")) == NULL)
+		{
+			printf("Line %d: Alias '%s' specifies no hosts\n", lineno,
+				alias);
+			exit(EXIT_FAILURE);
+		}
+
+		hosts = g_array_new(FALSE, TRUE, sizeof(char*));
+
+		do
+		{
+			if(tmp[0] == '[' && tmp[strlen(tmp) - 1] == ']')
+			{
+				tmp++;
+				tmp[strlen(tmp) - 1] = '\0';
+				append_alias(tmp, hosts, aliases, lineno);
+			}
+			else
+				g_array_append_val(hosts, tmp);
+		}
+		while((tmp = strtok(NULL, " ")) != NULL);
+
+		g_datalist_set_data(aliases, alias, hosts);
+	}
+
+	return aliases;
+}
+
 int main(int argc, char* argv[], char* env[])
 {
 	GtkWidget* window;
 	int c, option_index = 0;
-	int i, nhosts = 0;
-	char **hosts = NULL;
+	char *home, *conffile;
+	GData **aliases = NULL;
+	GArray *hosts = NULL;
 
 	static struct option long_options[] =
 	{
-		{"help",	no_argument,	0, 'h'},
-		{"version",	no_argument,	0, 'V'},
+		{"alias",	required_argument,	0, 'a'},
+		{"help",	no_argument,		0, 'h'},
+		{"version",	no_argument,		0, 'V'},
 		{0, 0, 0, 0}
 	};
 
+	if((home = getenv("HOME")) != NULL)
+	{
+		int len = strlen(home) + strlen(CONFFILE) + 2;
+
+		conffile = malloc(len);
+		snprintf(conffile, len, "%s/%s", home, CONFFILE);
+
+		aliases = parse_aliases(conffile);
+		free(conffile);
+	}
+	else
+	{
+		fprintf(stderr,
+			"Warning: $HOME not set, not reading config file\n");
+	}
+
 	for(;;)
 	{
-		c = getopt_long(argc, argv, "hV", long_options, &option_index);
+		c = getopt_long(argc, argv, "a:hV", long_options, &option_index);
 
 		if(c == -1)
 			break;
 
 		switch(c)
 		{
+		case 'a':
+			if(aliases && (hosts = g_datalist_get_data(aliases,
+				optarg)) == NULL)
+			{
+				fprintf(stderr, "Alias '%s' not found\n", optarg);
+				usage(argv[0]);
+			}
+			break;
 		case 'h':
 			usage(argv[0]);
 			break;
@@ -95,18 +246,22 @@ int main(int argc, char* argv[], char* env[])
 		}
 	}
 
-	if (optind < argc)
+	if(hosts == NULL)
 	{
-		hosts = malloc(sizeof(char*) * (argc - optind));
-		while (optind < argc)
+		hosts = g_array_new(FALSE, TRUE, sizeof(char*));
+		if (optind < argc)
 		{
-			hosts[nhosts++] = strdup(argv[optind++]);
+			while (optind < argc)
+			{
+				char *host = strdup(argv[optind++]);
+				g_array_append_val(hosts, host);
+			}
+		}
+		else
+		{
+			fprintf(stderr, "No hosts specified\n\n");
+			usage(argv[0]);
 		}
-	}
-	else
-	{
-		fprintf(stderr, "No hosts specified\n\n");
-		usage(argv[0]);
 	}
 
 	gtk_init(&argc, &argv);
@@ -116,15 +271,10 @@ int main(int argc, char* argv[], char* env[])
 	g_signal_connect(G_OBJECT(window), "destroy",
 		G_CALLBACK(on_mssh_destroy), NULL);
 
-	mssh_window_start_session(MSSH_WINDOW(window), env, nhosts, hosts);
+	mssh_window_start_session(MSSH_WINDOW(window), env, hosts);
 
 	gtk_widget_show_all(window);
 	gtk_main();
 
-	for(i = 0; i < nhosts; i++)
-		free(hosts[i]);
-
-	free(hosts);
-
 	return 0;
 }