chiark / gitweb /
Include `%'-escape substitution.
[sw-tools] / src / sw_build.c
index cfa765bb0eb4855c925fddb73f0df524423dcc12..493336388f064573d64e80471c399d1c39f7d276 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: sw_build.c,v 1.2 1999/07/16 12:50:24 mdw Exp $
+ * $Id: sw_build.c,v 1.3 1999/09/10 15:27:33 mdw Exp $
  *
  * Management of build processes
  *
@@ -29,6 +29,9 @@
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: sw_build.c,v $
+ * Revision 1.3  1999/09/10 15:27:33  mdw
+ * Include `%'-escape substitution.
+ *
  * Revision 1.2  1999/07/16 12:50:24  mdw
  * Improve exit status display.  New interface from `doto' project.
  *
@@ -56,6 +59,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/wait.h>
+#include <sys/utsname.h>
 
 #ifndef DECL_ENVIRON
   extern char **environ;
@@ -227,13 +231,92 @@ int sw_run(int argc, char *argv[])
 
     {
       archcons *aa;
+      dstr d = DSTR_INIT;
+      char **av;
+      struct utsname u;
+
+      /* --- Fill in the hostname --- */
+
+      if (uname(&u))
+       strcpy(u.nodename, "<unknown>");
+
+      /* --- If necessary, set up the output @argv@ array --- */
+
+      if (opt_flags & optFlag_percent)
+       av = xmalloc(argc * sizeof(char *));
+      else
+       av = argv + 1;
+
+      /* --- Run through the target build hosts --- */
 
       FD_ZERO(&fdin);
       for (aa = a; aa; aa = aa->cdr) {
        archent *e = aa->car;
        sw_remote *r = e->r;
+
+       /* --- If necessary, translate `%'-escapes --- */
+
+       if (opt_flags & optFlag_percent) {
+         char **pp, **qq;
+
+         for (pp = argv + 1, qq = av; *pp; pp++, qq++) {
+           if (strchr(*pp, '%') == 0)
+             *qq = *pp;
+           else {
+             char *p;
+             char *q = *pp;
+             for (p = *pp; *p; p++) {
+               if (*p == '%') {
+                 DPUTM(&d, q, p - q);
+                 p++;
+                 switch (*p) {
+                   case 0:
+                     DPUTC(&d, '%');
+                     goto done_arg;
+                   case '%':
+                     DPUTC(&d, '%');
+                     break;
+                   case 'a':
+                     dstr_puts(&d, e->arch);
+                     break;
+                   case 'h':
+                     dstr_puts(&d, e->flags & archFlag_home ?
+                                     u.nodename : e->host);
+                     break;
+                   case 'P':
+                     dstr_puts(&d, PREFIX);
+                     break;
+                   case 'p':
+                     dstr_puts(&d, sw.package);
+                     break;
+                   case 'v':
+                     dstr_puts(&d, sw.version);
+                     break;
+                   case 'u':
+                     dstr_puts(&d, sw.maintainer);
+                     break;
+                   default:
+                     DPUTC(&d, '%');
+                     DPUTC(&d, *p);
+                     break;
+                 }
+                 q = p + 1;
+               }
+             }
+             DPUTM(&d, q, p - q);
+           done_arg:
+             DPUTZ(&d);
+             *qq = xstrdup(d.buf);
+             DRESET(&d);
+           }
+         }
+         *qq++ = 0;
+       }
+
+       /* --- Start a new process off --- */
+
        if (swrsh(r, e->flags & archFlag_home ? 0 : e->host,
-                 "build", argv + 1)) {
+                 "build", av)) {
          dstr d = DSTR_INIT;
          dstr_putf(&d, "%s: couldn't start build for architecture `%s': %s",
                    QUIS, e->arch, strerror(errno));
@@ -248,7 +331,21 @@ int sw_run(int argc, char *argv[])
          active++;
          FD_SET(fd, &fdin);
        }
+
+       /* --- Free up the argument array --- */
+
+       if (opt_flags & optFlag_percent) {
+         char **pp, **qq;
+
+         for (pp = argv + 1, qq = av; *pp; pp++, qq++) {
+           if (*pp != *qq)
+             free(*qq);
+         }
+       }
       }
+
+      if (opt_flags & optFlag_percent)
+       free(av);
     }
 
     /* --- Watch the builds until they do something interesting --- */
@@ -429,7 +526,7 @@ void swrsh_build(sw_remote *r, char *argv[], char *env[])
   int fd[2];
   pid_t kid;
 
-  /* --- Validate arguments --- */
+  /* --- Validate the arguments --- */
 
   if (!argv[0])
     swdie(r, 1, "Usage: build COMMAND [ARG...]");
@@ -453,7 +550,10 @@ void swrsh_build(sw_remote *r, char *argv[], char *env[])
     struct tm *tm;
     char buf[64];
     char **p;
+    struct utsname u;
 
+    if (uname(&u))
+      swdie(r, 1, "couldn't get hostname: %s", strerror(errno));
     if (logfd < 0)
       swdie(r, 1, "couldn't open `.build-log' file: %s", strerror(errno));
     if ((logfp = fdopen(logfd, "a")) == 0) {
@@ -463,7 +563,8 @@ void swrsh_build(sw_remote *r, char *argv[], char *env[])
     t = time(0);
     tm = localtime(&t);
     strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm);
-    fprintf(logfp, "\n\n*** %s: started build: %s", buf, argv[0]);
+    fprintf(logfp, "\n\n*** %s: %s started build: %s",
+           buf, u.nodename, argv[0]);
     for (p = argv + 1; *p; p++)
       fprintf(logfp, " %s", *p);
     fputs("\n\n", logfp);
@@ -499,7 +600,7 @@ void swrsh_build(sw_remote *r, char *argv[], char *env[])
     if (!n)
       break;
     if (n < 0) {
-      putf(r, logfp, "*** error reading from pipe: %s\n", strerror(errno));
+      putf(r, logfp, "\n*** error reading from pipe: %s\n", strerror(errno));
       kill(kid, SIGTERM);
       break;
     }
@@ -512,15 +613,16 @@ void swrsh_build(sw_remote *r, char *argv[], char *env[])
 
   {
     int status;
-    if (waitpid(kid, &status, 0) < 0)
-      putf(r, logfp, "*** error reading exit status: %s\n", strerror(errno));
-    else {
+    if (waitpid(kid, &status, 0) < 0) {
+      putf(r, logfp, "\n*** error reading exit status: %s\n",
+          strerror(errno));
+    } else {
       if (WIFSIGNALED(status))
-       fprintf(logfp, "*** exited on signal %i\n", WTERMSIG(status));
+       fprintf(logfp, "\n*** exited on signal %i\n", WTERMSIG(status));
       else if (WIFEXITED(status))
-       fprintf(logfp, "*** exited with status %i\n", WEXITSTATUS(status));
+       fprintf(logfp, "\n*** exited with status %i\n", WEXITSTATUS(status));
       else
-       fprintf(logfp, "*** reaped, but didn't exit.  Strange\n");
+       fprintf(logfp, "\n*** reaped, but didn't exit.  Strange\n");
     }
     fclose(logfp);
     swwait(r, status);