#528542 support "include" statements in group files

Package:
dsh
Source:
dsh
Description:
dancer's shell, or distributed shell
Submitter:
Christoph Anton Mitterer
Date:
2018-12-14 07:39:06 UTC
Severity:
wishlist
#528542#5
Date:
2009-05-13 14:14:04 UTC
From:
To:
Hi.

It would be very nice if group files, and files for the -f option
would support kind of an #include <file> statement.

Very often the cluster consists of different groups and sub-groups, e.g.
Complete Cluster
-Compute Element
--Worker Nodes
--Service Nodes
-Storage Element
--Pool Nodes
--Service Nodes
etc.

An include statement would make like much easier, as the higher level
groups could simply include the subgroups.

Best wishes,
Chris.
----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.

#528542#10
Date:
2009-05-14 11:34:09 UTC
From:
To:
Patch welcome for parameter.c:read_machinelist.

Adding '@' netgroup parsing code there might be nice.

At Wed, 13 May 2009 16:14:04 +0200,
Christoph Anton Mitterer wrote:

#528542#15
Date:
2011-03-09 10:15:01 UTC
From:
To:
$ diff -u clean/dsh-0.25.10/parameter.c dsh-0.25.10/parameter.c
--- clean/dsh-0.25.10/parameter.c       2007-08-15 00:23:42.000000000 +0100
+++ dsh-0.25.10/parameter.c     2011-03-09 09:50:22.000000000 +0000
@@ -170,7 +170,16 @@
        {
          const char * strippedstring = stripwhitespace(buf);
          if (strippedstring)
-           machinelist=machinelist_lladd(machinelist,strippedstring);
+            {
+              if ((0 == strncmp(". ", strippedstring, 2)))
+                {
+                  machinelist=read_machinelist(machinelist,
&strippedstring[2], NULL);
+                }
+                else
+                {
+                  machinelist=machinelist_lladd(machinelist,strippedstring);
+                }
+            }
        }
       fclose(f);
     }

#528542#20
Date:
2011-03-09 10:45:53 UTC
From:
To:
Actually obviously doesn't work properly as I've done nothing with directories.
I settled on
. filename
as the syntax (almost like bash) as # is the comment delimiter.
Perhaps I should use

p path
g group
@ netgroup

and factor out the dir lookup elsewhere in parameter.c to use the
appropriate source.

Thoughts?

#528542#25
Date:
2011-03-09 15:25:50 UTC
From:
To:
Simply
if a line starts with @ the rest is assumed to be a netgroup
if a line starts with + the rest is assumed to be a "dsh" group
if a line starts with < the rest is assumed to be a filename
for the last one, filenames that start with "/" are taken as is
otherwise they're assumed to be relative to the file where they're
listed.

Craig

diff -u dsh-0.25.10.orig/parameter.c dsh-0.25.10
--- dsh-0.25.10.orig/parameter.c        2007-08-15 00:23:42.000000000 +0100
+++ dsh-0.25.10/parameter.c     2011-03-09 14:34:54.000000000 +0000
@@ -46,6 +46,12 @@
 #include "gettext.h"
 #define _(A) gettext(A)

+/*
+ * Forward declare as used by add_machine_group and uses add_machine_group
+ *
+ */
+linkedlist* read_machinelist(linkedlist *, const char *, const char*);
+
 /**
  * allocate memory, and abort with error
  *
@@ -154,6 +160,37 @@

 }

+static
+linkedlist* add_machine_group (linkedlist* machinelist, int
is_netgroup, const char* group_name)
+{
+  if (is_netgroup)
+    {                  /* using libc call for using netgroup. */
+      /* +1 to skip @ */
+      if (verbose_flag) printf (_("Adding netgroup %s to the
list\n"), group_name);
+      machinelist = read_machinenetgroup(machinelist, group_name);
+    }
+  else
+    {
+      char * buf1, *buf2;
+      if (verbose_flag) printf (_("Adding group %s to the list\n"),
group_name);
+      if (asprintf(&buf1, DSHCONFDIR"/group/%s", group_name) < 0)
+        {
+          fprintf (stderr, _("%s: asprintf failed\n"), PACKAGE);
+          return NULL;
+        }
+
+      if (asprintf(&buf2, "%s/.dsh/group/%s", getenv("HOME"), group_name)<0)
+        {
+          fprintf (stderr, _("%s: asprintf failed\n"), PACKAGE);
+          return NULL;
+        }
+
+      machinelist = read_machinelist (machinelist, buf2, buf1);
+      free(buf1);free(buf2);
+    }
+  return machinelist;
+}
+
 /**
  * read the machine list file from file.
  */
@@ -163,14 +200,59 @@
   FILE * f;
   size_t bufferlen = 1024;
   char * buf = malloc_with_error(bufferlen);
+  const char* reading = listfile;

-  if ((f = fopen (listfile, "r")) || ((NULL != alternatelistfile) &&
(f=fopen(alternatelistfile, "r"))))
+  if ((f = fopen (listfile, "r")) || ((NULL != alternatelistfile) &&
(f=fopen(reading=alternatelistfile, "r"))))
     {
       while (-1 != getline (&buf, &bufferlen, f))
        {
          const char * strippedstring = stripwhitespace(buf);
          if (strippedstring)
-           machinelist=machinelist_lladd(machinelist,strippedstring);
+            {
+              switch (strippedstring[0])
+                {
+                  case '@':
+                    if (!(machinelist =
add_machine_group(machinelist, 1, &strippedstring[1])))
+                      exit (1);
+                    break;
+
+                  case '+':
+                    if (!(machinelist =
add_machine_group(machinelist, 0, &strippedstring[1])))
+                      exit (1);
+                    break;
+
+                  case '<':
+                    if ('/' == strippedstring[1])
+                      {
+                        /* absolute path */
+                        machinelist = read_machinelist (machinelist,
&strippedstring[1], NULL);
+                      }
+                      else
+                      {
+                        /* relative path */
+                        /* includING file has a slash, get that dir,
use with includED file */
+                        const char* slash = strrchr(reading, '/');
+                        if (slash)
+                          {
+                            size_t dirlen = slash - reading + 1; /*
includes the / */
+                            char* path = malloc_with_error(dirlen +
strlen(&strippedstring[1]) + 1 /* NUL */);
+                            strncpy(path, reading, dirlen);
+                            strcpy(path + dirlen, &strippedstring[1]);
+                            machinelist = read_machinelist
(machinelist, path, NULL);
+                            free(path);
+                          }
+                        else
+                          {
+                            machinelist = read_machinelist
(machinelist, &strippedstring[1], NULL);
+                          }
+                      }
+                    break;
+
+                  default:
+                    machinelist=machinelist_lladd(machinelist,strippedstring);
+                    break;
+                }
+            }
        }
       fclose(f);
     }
@@ -452,28 +534,11 @@
          {
             if ('@' == *optarg)
               {                        /* using libc call for using
netgroup. */
-                /* +1 to skip @ */
-               if (verbose_flag) printf (_("Adding netgroup %s to the
list\n"), optarg + 1);
-                machinelist = read_machinenetgroup(machinelist, optarg+1);
+                machinelist = add_machine_group(machinelist, 1, optarg + 1);
               }
             else
               {                        /* using dsh's own method. */
-               char * buf1, *buf2;
-               if (verbose_flag) printf (_("Adding group %s to the
list\n"), optarg);
-               if (asprintf(&buf1, DSHCONFDIR"/group/%s", optarg) < 0)
-                 {
-                   fprintf (stderr, _("%s: asprintf failed\n"), PACKAGE);
-                   return 1;
-                 }
-
-               if (asprintf(&buf2, "%s/.dsh/group/%s",
getenv("HOME"), optarg)<0)
-                 {
-                   fprintf (stderr, _("%s: asprintf failed\n"), PACKAGE);
-                   return 1;
-                 }
-
-               machinelist = read_machinelist (machinelist, buf2, buf1);
-               free(buf1);free(buf2);
+                machinelist = add_machine_group(machinelist, 0, optarg);
              }
          }
          break;