Welcome to little lamb

Code » anopa » commit aceafd9

start/stop/enable/status/reset: Support reading from stdin

author Olivier Brunel
2015-07-24 12:04:14 UTC
committer Olivier Brunel
2015-07-26 16:26:58 UTC
parent 880d5ad62414eb1fa1ca5f3abe45be6fcf7d58dd

start/stop/enable/status/reset: Support reading from stdin

Use "-" as service name on the command line to read them (one per line)
from stdin.
Useful to read them from a file, or pipe a --dry-list output.

doc/aa-enable.pod +3 -0
doc/aa-reset.pod +3 -0
doc/aa-start.pod +3 -0
doc/aa-status.pod +3 -0
doc/aa-stop.pod +3 -0
src/anopa/aa-enable.c +8 -2
src/anopa/aa-reset.c +9 -3
src/anopa/aa-start.c +9 -3
src/anopa/aa-status.c +7 -1
src/anopa/aa-stop.c +10 -4
src/anopa/util.c +37 -0
src/anopa/util.h +3 -0

diff --git a/doc/aa-enable.pod b/doc/aa-enable.pod
index c7d7538..da09956 100644
--- a/doc/aa-enable.pod
+++ b/doc/aa-enable.pod
@@ -98,6 +98,9 @@ Also note that by default B<aa-enable>(1) will auto-enable any service whose
 name was found in a directory I<need> or I<wants> of a created servicedir. This
 can be turned off via B<--no-needs> and/or B<--no-wants> if needed.
 
+You can use B<-> as service name to read actual service names from stdin, where
+there must be one name per line.
+
 =head2 Enabling a service / Creating a servicedir
 
 Instead of simply creating the repository ahead of time, and copying it all on
diff --git a/doc/aa-reset.pod b/doc/aa-reset.pod
index b8b7924..aa2c6a5 100644
--- a/doc/aa-reset.pod
+++ b/doc/aa-reset.pod
@@ -57,3 +57,6 @@ specified:
 failed" to "Started"; and "Stopping failed" and "Stop failed" to "Stopped"
 
 Note that a service either "Starting" or "Stopping" will never be reset.
+
+You can use B<-> as service name to read actual service names from stdin, where
+there must be one name per line.
diff --git a/doc/aa-start.pod b/doc/aa-start.pod
index 5e0a955..6d25132 100644
--- a/doc/aa-start.pod
+++ b/doc/aa-start.pod
@@ -64,6 +64,9 @@ B<aa-start>(1) allows to start one or more services. By default, any services
 found in directories I<needs> or I<wants> are also auto-started, though it is
 possible not to auto-start the ones from I<wants> via B<--no-wants>.
 
+You can use B<-> as service name to read actual service names from stdin, where
+there must be one name per line.
+
 Refer to B<anopa>(1) for descriptions of servicedirs and service dependencies.
 
 =head1 TIMEOUTS
diff --git a/doc/aa-status.pod b/doc/aa-status.pod
index c0edf74..b079339 100644
--- a/doc/aa-status.pod
+++ b/doc/aa-status.pod
@@ -71,6 +71,9 @@ For long-run services it will also check for the I<ready> file to determine
 whether the service is "Up" or "Ready" (using the timestamp from the I<ready>
 file in the later case).
 
+You can use B<-> as service name to read actual service names from stdin, where
+there must be one name per line.
+
 =head1 FILTERING
 
 You can use B<--filter> to filter which services to process amongst those
diff --git a/doc/aa-stop.pod b/doc/aa-stop.pod
index 51779da..17fdafe 100644
--- a/doc/aa-stop.pod
+++ b/doc/aa-stop.pod
@@ -79,6 +79,9 @@ That is to say if service A was to be started after service B, then it will be
 stopped before B. And if A had a dependency (I<needs>) on C, then stopping C
 will also cause for A to be stopped.
 
+You can use B<-> as service name to read actual service names from stdin, where
+there must be one name per line.
+
 Refer to B<anopa>(1) for descriptions of servicedirs and service dependencies.
 
 B<aa-stop>(1) works in a very similar manner as B<aa-start>(1), with the
diff --git a/src/anopa/aa-enable.c b/src/anopa/aa-enable.c
index f5c9441..bcd9939 100644
--- a/src/anopa/aa-enable.c
+++ b/src/anopa/aa-enable.c
@@ -90,7 +90,7 @@ ae_cb (const char *name, aa_enable_flags type)
 }
 
 static int
-enable_service (const char *name, int from_next)
+enable_service (const char *name, intptr_t from_next)
 {
     int offset;
     int r;
@@ -322,7 +322,13 @@ main (int argc, char * const argv[])
     }
 
     for (i = 0; i < argc; ++i)
-        enable_service (argv[i], 0);
+        if (str_equal (argv[i], "-"))
+        {
+            if (process_names_from_stdin ((names_cb) enable_service, NULL) < 0)
+                strerr_diefu1sys (ERR_IO, "process names from stdin");
+        }
+        else
+            enable_service (argv[i], 0);
 
     while (genalloc_len (int, &ga_next) > 0)
     {
diff --git a/src/anopa/aa-reset.c b/src/anopa/aa-reset.c
index a331bb4..1a1cef4 100644
--- a/src/anopa/aa-reset.c
+++ b/src/anopa/aa-reset.c
@@ -46,7 +46,7 @@ enum
 };
 
 static void
-reset_service (const char *name, int mode)
+reset_service (const char *name, intptr_t mode)
 {
     aa_service *s;
     int si;
@@ -149,7 +149,7 @@ main (int argc, char * const argv[])
     PROG = "aa-reset";
     const char *path_repo = "/run/services";
     int mode_both = 0;
-    int mode = MODE_NONE;
+    intptr_t mode = MODE_NONE;
     int i;
     int r;
 
@@ -216,7 +216,13 @@ main (int argc, char * const argv[])
         strerr_diefu2sys (2, "init repository ", path_repo);
 
     for (i = 0; i < argc; ++i)
-        reset_service (argv[i], mode);
+        if (str_equal (argv[i], "-"))
+        {
+            if (process_names_from_stdin ((names_cb) reset_service, (void *) mode) < 0)
+                strerr_diefu1sys (ERR_IO, "process names from stdin");
+        }
+        else
+            reset_service (argv[i], mode);
 
     return 0;
 }
diff --git a/src/anopa/aa-start.c b/src/anopa/aa-start.c
index 2c08943..75c1354 100644
--- a/src/anopa/aa-start.c
+++ b/src/anopa/aa-start.c
@@ -112,7 +112,7 @@ load_fail_cb (int si, aa_lf lf, const char *name, int err)
 }
 
 static int
-add_service (const char *name)
+add_service (const char *name, void *data)
 {
     int si = -1;
     int type;
@@ -194,7 +194,7 @@ it_start (direntry *d, void *data)
     if (*d->d_name == '.')
         return 0;
     tain_now_g ();
-    add_service (d->d_name);
+    add_service (d->d_name, NULL);
     return 0;
 }
 
@@ -332,7 +332,13 @@ main (int argc, char * const argv[])
     tain_now_g ();
 
     for (i = 0; i < argc; ++i)
-        add_service (argv[i]);
+        if (str_equal (argv[i], "-"))
+        {
+            if (process_names_from_stdin ((names_cb) add_service, NULL) < 0)
+                strerr_diefu1sys (ERR_IO, "process names from stdin");
+        }
+        else
+            add_service (argv[i], NULL);
 
     mainloop (mode, scan_cb);
 
diff --git a/src/anopa/aa-status.c b/src/anopa/aa-status.c
index 7829cfe..52366ab 100644
--- a/src/anopa/aa-status.c
+++ b/src/anopa/aa-status.c
@@ -814,7 +814,13 @@ main (int argc, char * const argv[])
     }
     else
         for (i = 0; i < argc; ++i)
-            load_service (argv[i], &cfg);
+            if (str_equal (argv[i], "-"))
+            {
+                if (process_names_from_stdin ((names_cb) load_service, &cfg) < 0)
+                    strerr_diefu1sys (ERR_IO, "process names from stdin");
+            }
+            else
+                load_service (argv[i], &cfg);
 
     for (i = 0; i < genalloc_len (struct serv, &ga_serv); ++i)
         status_service (&genalloc_s (struct serv, &ga_serv)[i], &cfg);
diff --git a/src/anopa/aa-stop.c b/src/anopa/aa-stop.c
index fe19b71..e340e8d 100644
--- a/src/anopa/aa-stop.c
+++ b/src/anopa/aa-stop.c
@@ -119,7 +119,7 @@ it_preload (direntry *d, void *data)
 }
 
 static int
-add_service (const char *name)
+add_service (const char *name, void *data)
 {
     int si = -1;
     int type;
@@ -191,7 +191,7 @@ add_service (const char *name)
             for (i = 0; i < genalloc_len (int, &aa_service (si)->needs); ++i)
             {
                 int sni = list_get (&aa_service (si)->needs, i);
-                add_service (aa_service_name (aa_service (sni)));
+                add_service (aa_service_name (aa_service (sni)), NULL);
             }
         }
     }
@@ -206,7 +206,7 @@ it_stop (direntry *d, void *data)
         return 0;
 
     tain_now_g ();
-    add_service (d->d_name);
+    add_service (d->d_name, NULL);
 
     return 0;
 }
@@ -384,7 +384,13 @@ main (int argc, char * const argv[])
     }
     else
         for (i = 0; i < argc; ++i)
-            add_service (argv[i]);
+            if (str_equal (argv[i], "-"))
+            {
+                if (process_names_from_stdin ((names_cb) add_service, NULL) < 0)
+                    strerr_diefu1sys (ERR_IO, "process names from stdin");
+            }
+            else
+                add_service (argv[i], NULL);
 
     tain_now_g ();
 
diff --git a/src/anopa/util.c b/src/anopa/util.c
index 4208225..84e019d 100644
--- a/src/anopa/util.c
+++ b/src/anopa/util.c
@@ -20,7 +20,44 @@
  * anopa. If not, see http://www.gnu.org/licenses/
  */
 
+#include <skalibs/buffer.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/skamisc.h>
 #include <string.h>
+#include <errno.h>
+#include "util.h"
+
+int
+process_names_from_stdin (names_cb process_name, void *data)
+{
+    int salen = satmp.len;
+    int r;
+
+    for (;;)
+    {
+        satmp.len = salen;
+        r = skagetlnsep (buffer_0small, &satmp, "\n", 1);
+        if (r < 0)
+        {
+            if (errno != EPIPE)
+                break;
+        }
+        else if (r == 0)
+            break;
+        else
+            satmp.len--;
+
+        if (!stralloc_0 (&satmp))
+        {
+            r = -1;
+            break;
+        }
+        process_name (satmp.s + salen, data);
+    }
+
+    satmp.len = salen;
+    return r;
+}
 
 void
 unslash (char *s)
diff --git a/src/anopa/util.h b/src/anopa/util.h
index 5fa5aea..16f3872 100644
--- a/src/anopa/util.h
+++ b/src/anopa/util.h
@@ -23,6 +23,9 @@
 #ifndef AA_UTIL_H
 #define AA_UTIL_H
 
+typedef void (*names_cb) (const char *name, void *data);
+
+int process_names_from_stdin (names_cb process_name, void *data);
 void unslash (char *s);
 
 #endif /* AA_UTIL_H */