/* -*-c-*-
*
- * $Id: sw.c,v 1.2 1999/07/16 12:50:43 mdw Exp $
+ * $Id: sw.c,v 1.3 1999/09/10 15:27:32 mdw Exp $
*
* Main driver code for sw-tools
*
/*----- Revision history --------------------------------------------------*
*
* $Log: sw.c,v $
+ * Revision 1.3 1999/09/10 15:27:32 mdw
+ * Include `%'-escape substitution.
+ *
* Revision 1.2 1999/07/16 12:50:43 mdw
* Replace deprecated `mdwopt' flag name with new version.
*
const char *opt_output = 0;
const char *opt_arch = 0;
-unsigned int opt_flags;
+unsigned int opt_flags = optFlag_percent;
/*----- Helpful GNUy message routines -------------------------------------*/
static void usage(FILE *fp)
{
- fprintf(fp, "Usage: %s [-fbi] [-a arch,...] [-o style] command [args]\n",
+ fprintf(fp, "Usage: %s [-fbip] [-a arch,...] [-o style] command [args]\n",
QUIS);
}
-b, --beep Beep when the build is complete.\n\
-i, --install Mark architectures as done when build succeeds.\n\
-f, --force Run build commands on installed architectures.\n\
+-p, --percent Enable `%'-escapes in build command arguments.\n\
-o, --output=STYLE Display output in a particular style. Use style\n\
`help' for a list.\n\
\n", fp);
{ "force", 0, 0, 'f' },
{ "install", 0, 0, 'i' },
{ "output", OPTF_ARGREQ, 0, 'o' },
- { "beep", 0, 0, 'b' },
+ { "beep", OPTF_NEGATE, 0, 'b' },
+ { "percent", OPTF_NEGATE, 0, 'p' },
+ { "escape", OPTF_NEGATE, 0, 'p' },
/* --- Internal-use-only magical options --- *
*
{ 0, 0, 0, 0 }
};
- int i = mdwopt(argc, argv, "+hHvu a:bfio:", opt, 0, 0, OPTF_ENVVAR);
+ int i = mdwopt(argc, argv, "+hHvu a:b+p+fio:", opt, 0, 0,
+ OPTF_ENVVAR | OPTF_NEGATION);
if (i < 0)
break;
case 'b':
opt_flags |= optFlag_beep;
break;
+ case 'b' | OPTF_NEGATED:
+ opt_flags &= ~optFlag_beep;
+ break;
+ case 'p':
+ opt_flags |= optFlag_percent;
+ break;
+ case 'p' | OPTF_NEGATED:
+ opt_flags &= ~optFlag_percent;
+ break;
case 'i':
opt_flags |= optFlag_install;
break;
/* -*-c-*-
*
- * $Id: sw.h,v 1.1 1999/06/02 16:53:35 mdw Exp $
+ * $Id: sw.h,v 1.2 1999/09/10 15:27:33 mdw Exp $
*
* Interface to main options parser
*
/*----- Revision history --------------------------------------------------*
*
* $Log: sw.h,v $
- * Revision 1.1 1999/06/02 16:53:35 mdw
- * Initial revision
+ * Revision 1.2 1999/09/10 15:27:33 mdw
+ * Include `%'-escape substitution.
+ *
+ * Revision 1.1.1.1 1999/06/02 16:53:35 mdw
+ * Initial import.
*
*/
enum {
optFlag_install = 1,
optFlag_force = 2,
- optFlag_beep = 4
+ optFlag_beep = 4,
+ optFlag_percent = 8
};
/*----- That's all, folks -------------------------------------------------*/
/* -*-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
*
/*----- 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.
*
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
+#include <sys/utsname.h>
#ifndef DECL_ENVIRON
extern char **environ;
{
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));
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 --- */
int fd[2];
pid_t kid;
- /* --- Validate arguments --- */
+ /* --- Validate the arguments --- */
if (!argv[0])
swdie(r, 1, "Usage: build COMMAND [ARG...]");
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) {
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);
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;
}
{
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);
.\" -*-nroff-*-
.\"
-.\" $Id: sw.1,v 1.7 1999/07/30 18:44:33 mdw Exp $
+.\" $Id: sw.1,v 1.8 1999/09/10 15:27:40 mdw Exp $
.\"
.\" Manual page for `sw'
.\"
.\"----- Revision history ---------------------------------------------------
.\"
.\" $Log: sw.1,v $
+.\" Revision 1.8 1999/09/10 15:27:40 mdw
+.\" Include `%'-escape substitution.
+.\"
.\" Revision 1.7 1999/07/30 18:44:33 mdw
.\" Improve cross-references and tidy up formatting.
.\"
\fBsw all\-arch
\fBsw arch
\fBsw commit
-\fBsw \fR[\fB\-fbi\fR] [\fB\-a \fIarch\fB,\fIarch\fR...] [\fB\-o \fIstyle\fR] \fBconfigure \fR[\fIconfigure-arg\fR...]
+\fBsw \fR[\fB\-fbip\fR] [\fB\-a \fIarch\fB,\fIarch\fR...] [\fB\-o \fIstyle\fR] \fBconfigure \fR[\fIconfigure-arg\fR...]
\fBsw host \fIarch
\fBsw \fR[\fB\-f\fR] [\fB\-a \fIarch\fB,\fIarch\fR...] \fBlinktree
\fBsw listarch
-\fBsw \fR[\fB\-fbi\fR] [\fB\-a \fIarch\fB,\fIarch\fR...] [\fB\-o \fIstyle\fR] \fBmake \fR[\fImake-arg\fR...]
+\fBsw \fR[\fB\-fbip\fR] [\fB\-a \fIarch\fB,\fIarch\fR...] [\fB\-o \fIstyle\fR] \fBmake \fR[\fImake-arg\fR...]
\fBsw only\-arch \fIarch \fR[\fIarch\fR...]
\fBsw reset
\fBsw rsh \fIhost\fR|\fIarch \fR[\fIcommand \fR[\fIargument\fR...]]
-\fBsw \fR[\fB\-fbi\fR] [\fB\-a \fIarch\fB,\fIarch\fR...] [\fB\-o \fIstyle\fR] \fBrun \fIcommand \fR[\fIargument\fR...]
+\fBsw \fR[\fB\-fbip\fR] [\fB\-a \fIarch\fB,\fIarch\fR...] [\fB\-o \fIstyle\fR] \fBrun \fIcommand \fR[\fIargument\fR...]
\fBsw setup \fIpackage version \fR[\fImaintainer\fR]
\fBsw \fR[\fB\-f\fR] [\fB\-a \fIarch\fB,\fIarch\fR...] \fBsnaplink \fIfile \fR[\fIfile\fR...]
\fBsw status
.B "\-b, \-\-beep"
For build commands: make a beep noise when the build finishes. This
provides a handy reminder if you're getting on with something else while
-waiting for a long build.
+waiting for a long build. Use
+.RB ` +b '
+or
+.RB ` \-\-no\-beep '
+to turn this option off. This option is disabled by default, although
+may be enabled in the
+.B SW
+environment variable.
+.TP
+.B "\-p, \-\percent"
+For build commands: enable translation of
+.RB ` % '-escape
+sequences in command strings. These are described in more detail
+in the section
+.B "`%'-escape sequences"
+below. Use
+.RB ` +p '
+or
+.RB ` --no-percent '
+to turn the option off. This option is enabled by default, although may
+be disabled in the
+.B SW
+environment variable.
.PP
The remaining options aren't really intended for users. They're helpful
for \*(sw's own purposes, though, and described here for completeness' sake. They
passing it the given
.IR argument s.
.PP
+The command name and arguments may be subject to
+.RB ` % '-escape
+substitution, depending on whether the
+.B \-p
+option is enabled.
+.RB ` % '-escape
+sequences are described in the section
+.B "`%'-escape sequences"
+below.
+.PP
Output from the command is both appended to the file
.IB arch/.build-log
and output in some
.
.\"--------------------------------------------------------------------------
.
+.SH "`%'-ESCAPE SUBSTITUTION"
+.
+If the
+.B \-p
+option is enabled, build commands and arguments are subject to
+.RB ` % '-escape
+substitution before being executed. Certain two-character sequences,
+with the first character
+.RB ` % '
+are replaced with strings, as follows:
+.TP
+.B %a
+The architecture name of the host executing the command.
+.TP
+.B %h
+The hostname of the host executing the command.
+.TP
+.B %P
+The directory prefix with which \*(sw was installed.
+.TP
+.B %p
+The name of the package being built.
+.TP
+.B %v
+The version number of the package being built.
+.TP
+.B %u
+The name of the maintainer of the package being built.
+.TP
+.B %%
+A literal
+.RB ` % '
+character.
+.PP
+Any
+.RB ` % '
+sequences which aren't understood are left as they are.
+.
+.\"--------------------------------------------------------------------------
+.
.SH "OUTPUT STYLES"
.
Output from a build command is presented in one of a number of named