aboutsummaryrefslogtreecommitdiff
path: root/src/directive.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/directive.c')
-rw-r--r--src/directive.c1152
1 files changed, 558 insertions, 594 deletions
diff --git a/src/directive.c b/src/directive.c
index cb656e7..ac7c4cc 100644
--- a/src/directive.c
+++ b/src/directive.c
@@ -1,5 +1,5 @@
/* wydawca - automatic release submission daemon
- Copyright (C) 2007-2008, 2010-2012 Sergey Poznyakoff
+ Copyright (C) 2007-2008, 2010-2013 Sergey Poznyakoff
Wydawca is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
@@ -20,70 +20,68 @@
/* Parse directives from TRP->blurb. Fill TRP->directive */
int
-directive_parse (struct file_triplet *trp)
+directive_parse(struct file_triplet *trp)
{
- size_t dcount, i, j;
- char *p;
-
- if (debug_level > 2)
- logmsg (LOG_DEBUG, _("%s: parsing directive blurb: %s"),
- trp->file[file_directive].name, trp->blurb);
-
- dcount = 0;
- for (p = trp->blurb; *p; p++)
- if (*p == '\n')
- dcount++;
-
- trp->directive = grecs_calloc (dcount + 1, sizeof trp->directive[0]);
- p = trp->blurb;
- for (i = j = 0; i < dcount; i++)
- {
- trp->directive[j] = p;
- p = strchr (p, '\n');
- if (p)
- *p++ = 0;
- if (trim (trp->directive[j]) == 0) /* ignore empty lines */
- continue;
- if (strchr (trp->directive[j], ':') == NULL)
- {
- logmsg (LOG_ERR, _("%s: invalid line: %s"),
- trp->file[file_directive].name, trp->directive[j]);
- free (trp->directive);
- trp->directive = NULL;
- return 1;
+ size_t dcount, i, j;
+ char *p;
+
+ if (debug_level > 2)
+ logmsg(LOG_DEBUG, _("%s: parsing directive blurb: %s"),
+ trp->file[file_directive].name, trp->blurb);
+
+ dcount = 0;
+ for (p = trp->blurb; *p; p++)
+ if (*p == '\n')
+ dcount++;
+
+ trp->directive = grecs_calloc(dcount + 1, sizeof trp->directive[0]);
+ p = trp->blurb;
+ for (i = j = 0; i < dcount; i++) {
+ trp->directive[j] = p;
+ p = strchr(p, '\n');
+ if (p)
+ *p++ = 0;
+ if (trim(trp->directive[j]) == 0) /* ignore empty lines */
+ continue;
+ if (strchr(trp->directive[j], ':') == NULL) {
+ logmsg(LOG_ERR, _("%s: invalid line: %s"),
+ trp->file[file_directive].name,
+ trp->directive[j]);
+ free(trp->directive);
+ trp->directive = NULL;
+ return 1;
+ }
+ j++;
+ if (!p)
+ break;
}
- j++;
- if (!p)
- break;
- }
- trp->directive[j] = NULL;
- return 0;
+ trp->directive[j] = NULL;
+ return 0;
}
/* If a directive KEY exists in the triplet TRP, return 0 and point PVAL
(unless it is NULL) to its value. Othervise, return 1. */
int
-directive_get_value (struct file_triplet *trp, const char *key,
- const char **pval)
+directive_get_value(struct file_triplet *trp, const char *key,
+ const char **pval)
{
- int keylen = strlen (key);
- int i;
-
- for (i = 0; trp->directive[i]; i++)
- {
- char *str = trp->directive[i];
- int len = strlen (str);
- if (len > keylen && memcmp (str, key, keylen) == 0 && str[keylen] == ':')
- {
- str += keylen + 1;
- while (*str && isspace (*str))
- str++;
- if (pval)
- *pval = str;
- return 0;
+ int keylen = strlen(key);
+ int i;
+
+ for (i = 0; trp->directive[i]; i++) {
+ char *str = trp->directive[i];
+ int len = strlen(str);
+ if (len > keylen && memcmp(str, key, keylen) == 0
+ && str[keylen] == ':') {
+ str += keylen + 1;
+ while (*str && isspace(*str))
+ str++;
+ if (pval)
+ *pval = str;
+ return 0;
+ }
}
- }
- return 1;
+ return 1;
}
/* Auxiliary function for sequential access to directories from TRP.
@@ -97,622 +95,588 @@ directive_get_value (struct file_triplet *trp, const char *key,
If N points past all the directive, the function returns 0. */
static int
-_directive_seq_get (int n, struct file_triplet *trp,
- const char **pkey, const char **pval)
+_directive_seq_get(int n, struct file_triplet *trp,
+ const char **pkey, const char **pval)
{
- char *p;
- size_t len;
-
- if (trp->directive[n] == NULL)
- return 0;
-
- p = strchr (trp->directive[n], ':');
- len = p - trp->directive[n];
- if (len + 1 > trp->tmpsize)
- {
- trp->tmpsize = len + 1;
- trp->tmp = grecs_realloc (trp->tmp, trp->tmpsize);
- }
- memcpy (trp->tmp, trp->directive[n], len);
- trp->tmp[len] = 0;
- *pkey = trp->tmp;
- for (p++; *p && isspace (*p); p++)
- ;
- if (pval)
- *pval = p;
- return ++n;
+ char *p;
+ size_t len;
+
+ if (trp->directive[n] == NULL)
+ return 0;
+
+ p = strchr(trp->directive[n], ':');
+ len = p - trp->directive[n];
+ if (len + 1 > trp->tmpsize) {
+ trp->tmpsize = len + 1;
+ trp->tmp = grecs_realloc(trp->tmp, trp->tmpsize);
+ }
+ memcpy(trp->tmp, trp->directive[n], len);
+ trp->tmp[len] = 0;
+ *pkey = trp->tmp;
+ for (p++; *p && isspace(*p); p++) ;
+ if (pval)
+ *pval = p;
+ return ++n;
}
/* Get the first directive from TRP. Point *PKEY to its keyword and
*PVAL to its value. Return 1 on success, 0 on failure. */
int
-directive_first (struct file_triplet *trp,
- const char **pkey, const char **pval)
+directive_first(struct file_triplet *trp, const char **pkey, const char **pval)
{
- int n = 0;
- return _directive_seq_get (n, trp, pkey, pval);
+ int n = 0;
+ return _directive_seq_get(n, trp, pkey, pval);
}
/* Get the first directive from TRP. Point *PKEY to its keyword and
*PVAL to its value. Return 1 on success, 0 on failure.
Return non-0 on success, 0 on failure */
int
-directive_next (struct file_triplet *trp, int n,
- const char **pkey, const char **pval)
+directive_next(struct file_triplet *trp, int n,
+ const char **pkey, const char **pval)
{
- return _directive_seq_get (n, trp, pkey, pval);
+ return _directive_seq_get(n, trp, pkey, pval);
}
/* Pack a directive string VAL into an unsigned number */
int
-directive_pack_version (const char *val, unsigned *pversion)
+directive_pack_version(const char *val, unsigned *pversion)
{
- char *p;
- unsigned v;
-
- v = strtoul (val, &p, 10);
- if (*p != '.')
- return 1;
- p++;
- v *= 100;
- v += strtoul (p, &p, 10);
- if (*p && *p != '.')
- return 1;
- *pversion = v;
- return 0;
+ char *p;
+ unsigned v;
+
+ v = strtoul(val, &p, 10);
+ if (*p != '.')
+ return 1;
+ p++;
+ v *= 100;
+ v += strtoul(p, &p, 10);
+ if (*p && *p != '.')
+ return 1;
+ *pversion = v;
+ return 0;
}
int
-directive_unpack_version (unsigned version, char **pbuf, size_t *psize)
+directive_unpack_version(unsigned version, char **pbuf, size_t * psize)
{
- return grecs_asprintf (pbuf, psize, "%u.%u",
- version / 100, version % 100);
+ return grecs_asprintf(pbuf, psize, "%u.%u",
+ version / 100, version % 100);
}
-
+
/* Return true if the directory file version of the triplet TRP
is within the inclusive range FROM and TO (packed) */
int
-directive_version_in_range_p (struct file_triplet *trp,
- unsigned from, unsigned to)
+directive_version_in_range_p(struct file_triplet *trp,
+ unsigned from, unsigned to)
{
- const char *val;
- unsigned version;
-
- if (directive_get_value (trp, "version", &val))
- {
- logmsg (LOG_ERR, _("%s: missing `version' directive"),
- trp->file[file_directive].name);
- return 0;
- }
-
- if (directive_pack_version (val, &version))
- {
- logmsg (LOG_ERR, _("%s: unparsable version: %s"),
- trp->file[file_directive].name, val);
- return 0;
- }
- logmsg (LOG_NOTICE, _("%s: VERSION: %s"),
- trp->file[file_directive].name, val);
-
- trp->version = version;
-
- if (from <= version && version <= to)
- return 1;
-
- logmsg (LOG_ERR, _("%s: version %s is not in the allowed range"),
- trp->file[file_directive].name, val);
- return 0;
+ const char *val;
+ unsigned version;
+
+ if (directive_get_value(trp, "version", &val)) {
+ logmsg(LOG_ERR, _("%s: missing `version' directive"),
+ trp->file[file_directive].name);
+ return 0;
+ }
+
+ if (directive_pack_version(val, &version)) {
+ logmsg(LOG_ERR, _("%s: unparsable version: %s"),
+ trp->file[file_directive].name, val);
+ return 0;
+ }
+ logmsg(LOG_NOTICE, _("%s: VERSION: %s"),
+ trp->file[file_directive].name, val);
+
+ trp->version = version;
+
+ if (from <= version && version <= to)
+ return 1;
+
+ logmsg(LOG_ERR, _("%s: version %s is not in the allowed range"),
+ trp->file[file_directive].name, val);
+ return 0;
}
-enum directive
- {
- unknown_dir,
- comment_dir,
- directory_dir,
- version_dir,
- filename_dir,
- rmsymlink_dir,
- archive_dir,
- symlink_dir,
- replace_dir
- };
-
-struct directive_table
-{
- const char *name;
- enum directive dir;
+enum directive {
+ unknown_dir,
+ comment_dir,
+ directory_dir,
+ version_dir,
+ filename_dir,
+ rmsymlink_dir,
+ archive_dir,
+ symlink_dir,
+ replace_dir
+};
+
+struct directive_table {
+ const char *name;
+ enum directive dir;
};
static struct directive_table directive_table[] = {
- { "comment", comment_dir },
- { "directory", directory_dir },
- { "version", version_dir },
- { "filename", filename_dir },
- { "symlink", symlink_dir },
- { "rmsymlink", rmsymlink_dir },
- { "archive", archive_dir },
- { "replace", replace_dir },
- { NULL }
+ { "comment", comment_dir },
+ { "directory", directory_dir },
+ { "version", version_dir },
+ { "filename", filename_dir },
+ { "symlink", symlink_dir },
+ { "rmsymlink", rmsymlink_dir },
+ { "archive", archive_dir },
+ { "replace", replace_dir },
+ { NULL }
};
static enum directive
-find_directive (const char *key)
+find_directive(const char *key)
{
- int i;
+ int i;
- for (i = 0; directive_table[i].name; i++)
- if (strcmp (directive_table[i].name, key) == 0)
- return directive_table[i].dir;
- return unknown_dir;
+ for (i = 0; directive_table[i].name; i++)
+ if (strcmp(directive_table[i].name, key) == 0)
+ return directive_table[i].dir;
+ return unknown_dir;
}
/* Return 0 if the directory file format of the triplet TRP is OK. */
int
-verify_directive_format (struct file_triplet *trp)
+verify_directive_format(struct file_triplet *trp)
{
- int n, dnum;
- const char *key;
-
- if (!directive_version_in_range_p (trp, min_directive_version,
- max_directive_version))
- return 1;
-
- dnum = 0;
- for (n = directive_first (trp, &key, NULL); n;
- n = directive_next (trp, n, &key, NULL))
- {
- if (strcmp (key, "comment") == 0)
- continue;
- dnum++;
- switch (dnum)
- {
- case 1:
- if (strcmp (key, "version"))
- {
- logmsg (LOG_ERR, _("%s:%d: expected `%s' but found `%s'"),
- trp->file[file_directive].name, n, "version", key);
- return 1;
- }
- break;
-
- case 2:
- if (strcmp (key, "directory"))
- {
- logmsg (LOG_ERR, _("%s:%d: expected `%s' but found `%s'"),
- trp->file[file_directive].name, n, "directory", key);
- return 1;
- }
- break;
-
- default:
- if (find_directive (key) == unknown_dir)
- {
- logmsg (LOG_ERR, _("%s:%d: unknown directive `%s'"),
- trp->file[file_directive].name, n, key);
- return 1;
- }
- }
- }
-
- if (trp->file[file_dist].name && trp->file[file_signature].name)
- {
- const char *filename;
- if (directive_get_value (trp, "filename", &filename))
- {
- logmsg (LOG_ERR, _("%s: missing `filename' directive"),
- trp->file[file_directive].name);
- return 1;
+ int n, dnum;
+ const char *key;
+
+ if (!directive_version_in_range_p(trp, min_directive_version,
+ max_directive_version))
+ return 1;
+
+ dnum = 0;
+ for (n = directive_first(trp, &key, NULL); n;
+ n = directive_next(trp, n, &key, NULL)) {
+ if (strcmp(key, "comment") == 0)
+ continue;
+ dnum++;
+ switch (dnum) {
+ case 1:
+ if (strcmp(key, "version")) {
+ logmsg(LOG_ERR,
+ _("%s:%d: expected `%s' but found `%s'"),
+ trp->file[file_directive].name, n,
+ "version", key);
+ return 1;
+ }
+ break;
+
+ case 2:
+ if (strcmp(key, "directory")) {
+ logmsg(LOG_ERR,
+ _("%s:%d: expected `%s' but found `%s'"),
+ trp->file[file_directive].name, n,
+ "directory", key);
+ return 1;
+ }
+ break;
+
+ default:
+ if (find_directive(key) == unknown_dir) {
+ logmsg(LOG_ERR,
+ _("%s:%d: unknown directive `%s'"),
+ trp->file[file_directive].name, n, key);
+ return 1;
+ }
+ }
}
- if (strcmp (filename, trp->file[file_dist].name))
- {
- logmsg (LOG_ERR, _("%s: filename %s does not match actual name"),
- trp->file[file_dist].name, filename);
- return 1;
+
+ if (trp->file[file_dist].name && trp->file[file_signature].name) {
+ const char *filename;
+ if (directive_get_value(trp, "filename", &filename)) {
+ logmsg(LOG_ERR, _("%s: missing `filename' directive"),
+ trp->file[file_directive].name);
+ return 1;
+ }
+ if (strcmp(filename, trp->file[file_dist].name)) {
+ logmsg(LOG_ERR,
+ _("%s: filename %s does not match actual name"),
+ trp->file[file_dist].name, filename);
+ return 1;
+ }
}
- }
- return 0;
+ return 0;
}
-
-
static char *
-save_script (const char *script)
+save_script(const char *script)
{
- char *file_name;
- mode_t old_mask;
- int fd;
- size_t length;
-
- file_name = concat_dir (temp_homedir, "chkXXXXXX", NULL);
- old_mask = umask (0077);
- fd = mkstemp (file_name);
- umask (old_mask);
- if (fd == -1)
- {
- logmsg (LOG_CRIT, _("cannot create temporary script file %s: %s"),
- file_name, strerror (errno));
- free (file_name);
- return NULL;
- }
-
- length = strlen (script);
- while (length)
- {
- ssize_t wrb = write (fd, script, length);
- if (wrb == -1)
- {
- logmsg (LOG_CRIT, _("error writing to temporary script file %s: %s"),
- file_name, strerror (errno));
- break;
- }
- if (wrb == 0)
- {
- logmsg (LOG_CRIT, _("short write to temporary script file %s"),
- file_name);
- break;
+ char *file_name;
+ mode_t old_mask;
+ int fd;
+ size_t length;
+
+ file_name = concat_dir(temp_homedir, "chkXXXXXX", NULL);
+ old_mask = umask(0077);
+ fd = mkstemp(file_name);
+ umask(old_mask);
+ if (fd == -1) {
+ logmsg(LOG_CRIT,
+ _("cannot create temporary script file %s: %s"),
+ file_name, strerror(errno));
+ free(file_name);
+ return NULL;
}
- length -= wrb;
- script += wrb;
- }
- close (fd);
- if (length)
- {
- free (file_name);
- return NULL;
- }
- return file_name;
+ length = strlen(script);
+ while (length) {
+ ssize_t wrb = write(fd, script, length);
+ if (wrb == -1) {
+ logmsg(LOG_CRIT,
+ _("error writing to temporary script "
+ "file %s: %s"),
+ file_name, strerror(errno));
+ break;
+ }
+ if (wrb == 0) {
+ logmsg(LOG_CRIT,
+ _("short write to temporary script file %s"),
+ file_name);
+ break;
+ }
+
+ length -= wrb;
+ script += wrb;
+ }
+ close(fd);
+ if (length) {
+ free(file_name);
+ return NULL;
+ }
+ return file_name;
}
static int
-stderr_redirector (const char *tag)
+stderr_redirector(const char *tag)
{
- int p[2];
- pid_t pid;
-
- if (pipe (p))
- {
- logmsg (LOG_CRIT, "redirector pipe: %s", strerror (errno));
- return -1;
- }
-
- pid = fork ();
- if (pid == -1)
- {
- logmsg (LOG_CRIT, "redirector fork: %s", strerror (errno));
- return -1;
- }
-
- if (pid == 0)
- {
- FILE *fp;
- size_t size = 0;
- char *buf = NULL;
-
- close (p[1]);
- fp = fdopen (p[0], "r");
- if (!fp)
- _exit (127);
- while (grecs_getline (&buf, &size, fp) >= 0)
- {
- trim_crlf (buf);
- logmsg (LOG_NOTICE, "%s: %s", tag, buf);
+ int p[2];
+ pid_t pid;
+
+ if (pipe(p)) {
+ logmsg(LOG_CRIT, "redirector pipe: %s", strerror(errno));
+ return -1;
+ }
+
+ pid = fork();
+ if (pid == -1) {
+ logmsg(LOG_CRIT, "redirector fork: %s", strerror(errno));
+ return -1;
+ }
+
+ if (pid == 0) {
+ FILE *fp;
+ size_t size = 0;
+ char *buf = NULL;
+
+ close(p[1]);
+ fp = fdopen(p[0], "r");
+ if (!fp)
+ _exit(127);
+ while (grecs_getline(&buf, &size, fp) >= 0) {
+ trim_crlf(buf);
+ logmsg(LOG_NOTICE, "%s: %s", tag, buf);
+ }
+ _exit(0);
}
- _exit (0);
- }
- close (p[0]);
- return p[1];
+ close(p[0]);
+ return p[1];
}
static int
-run_check_script (const char *script, struct file_triplet *trp,
- const char *descr)
+run_check_script(const char *script, struct file_triplet *trp,
+ const char *descr)
{
- static char *script_file;
- pid_t pid;
- int status;
- int p[2];
- RETSIGTYPE (*oldsig)();
- FILE *fp;
- char *buf;
- size_t size, total;
-
- if (debug_level > 1)
- logmsg (LOG_DEBUG, _("prep script: %20.20s%s"),
- script, strlen (script) > 20 ? "..." : "");
- script_file = save_script (script);
- if (!script_file)
- return 1;
- if (debug_level > 1)
- logmsg (LOG_DEBUG, _("script file: %s"), script_file);
-
- if (pipe (p))
- {
- logmsg (LOG_CRIT, "pipe: %s", strerror (errno));
- return 1;
- }
- oldsig = signal (SIGCHLD, SIG_DFL);
- pid = fork ();
- if (pid == -1)
- {
- logmsg (LOG_CRIT, "fork: %s", strerror (errno));
- free (script_file);
- close (p[0]);
- close (p[1]);
- signal (SIGCHLD, oldsig);
- return 1;
- }
- if (pid == 0)
- {
- int i;
- int efd;
- char *argv[4];
- const struct spool *spool = trp->spool;
-
- signal (SIGHUP, SIG_DFL);
- signal (SIGTERM, SIG_DFL);
- signal (SIGQUIT, SIG_DFL);
- signal (SIGINT, SIG_DFL);
- signal (SIGCHLD, SIG_DFL);
- signal (SIGALRM, SIG_DFL);
-
- efd = stderr_redirector (script_file);
- if (efd == -1)
- _exit (127);
-
- for (i = getdtablesize (); i >= 0; i--)
- {
- if (i != p[1] && i != efd)
- close (i);
+ static char *script_file;
+ pid_t pid;
+ int status;
+ int p[2];
+ RETSIGTYPE(*oldsig) ();
+ FILE *fp;
+ char *buf;
+ size_t size, total;
+
+ if (debug_level > 1)
+ logmsg(LOG_DEBUG, _("prep script: %20.20s%s"),
+ script, strlen(script) > 20 ? "..." : "");
+ script_file = save_script(script);
+ if (!script_file)
+ return 1;
+ if (debug_level > 1)
+ logmsg(LOG_DEBUG, _("script file: %s"), script_file);
+
+ if (pipe(p)) {
+ logmsg(LOG_CRIT, "pipe: %s", strerror(errno));
+ return 1;
+ }
+ oldsig = signal(SIGCHLD, SIG_DFL);
+ pid = fork();
+ if (pid == -1) {
+ logmsg(LOG_CRIT, "fork: %s", strerror(errno));
+ free(script_file);
+ close(p[0]);
+ close(p[1]);
+ signal(SIGCHLD, oldsig);
+ return 1;
+ }
+ if (pid == 0) {
+ int i;
+ int efd;
+ char *argv[4];
+ const struct spool *spool = trp->spool;
+
+ signal(SIGHUP, SIG_DFL);
+ signal(SIGTERM, SIG_DFL);
+ signal(SIGQUIT, SIG_DFL);
+ signal(SIGINT, SIG_DFL);
+ signal(SIGCHLD, SIG_DFL);
+ signal(SIGALRM, SIG_DFL);
+
+ efd = stderr_redirector(script_file);
+ if (efd == -1)
+ _exit(127);
+
+ for (i = getdtablesize(); i >= 0; i--) {
+ if (i != p[1] && i != efd)
+ close(i);
+ }
+
+ if (p[1] != 1 && dup2(p[1], 1) != 1) {
+ logmsg(LOG_CRIT,
+ "cannot duplicate script's stdout: %s",
+ strerror(errno));
+ _exit(127);
+ }
+
+ if (efd != 2 && dup2(efd, 2) != 2) {
+ logmsg(LOG_CRIT,
+ "cannot duplicate script's stderr: %s",
+ strerror(errno));
+ _exit(127);
+ }
+
+ setenv("WYDAWCA_SPOOL", spool->tag, 1);
+ setenv("WYDAWCA_SOURCE", spool->source_dir, 1);
+ setenv("WYDAWCA_DEST", spool->dest_dir, 1);
+ setenv("WYDAWCA_URL", spool->url, 1);
+ setenv("WYDAWCA_TRIPLET_BASE", trp->name, 1);
+ setenv("WYDAWCA_DIST_FILE", trp->file[file_dist].name, 1);
+
+ if (chdir(temp_homedir)) {
+ logmsg(LOG_CRIT, "cannot change to %s: %s",
+ temp_homedir, strerror(errno));
+ _exit(127);
+ }
+
+ argv[0] = "sh";
+ argv[1] = script_file;
+ argv[2] = NULL;
+
+ execv("/bin/sh", argv);
+ _exit(127);
}
- if (p[1] != 1 && dup2 (p[1], 1) != 1)
- {
- logmsg (LOG_CRIT, "cannot duplicate script's stdout: %s",
- strerror (errno));
- _exit (127);
+ /* Master */
+ free(script_file);
+ close(p[1]);
+ fp = fdopen(p[0], "r");
+ buf = NULL;
+ size = total = 0;
+ if (debug_level > 2)
+ logmsg(LOG_DEBUG, _("reading script output..."));
+ while (grecs_getline(&buf, &size, fp) > 0) {
+ size_t len = strlen(buf);
+ if (debug_level > 2)
+ logmsg(LOG_DEBUG, _("read: %s"), buf);
+ txtacc_grow(trp->acc, buf, len);
+ total += size;
}
-
- if (efd != 2 && dup2 (efd, 2) != 2)
- {
- logmsg (LOG_CRIT, "cannot duplicate script's stderr: %s",
- strerror (errno));
- _exit (127);
+ txtacc_1grow(trp->acc, 0);
+ if (debug_level > 2)
+ logmsg(LOG_DEBUG, _("bytes read: %lu"), (unsigned long)total);
+
+ fclose(fp);
+
+ waitpid(pid, &status, 0);
+ signal(SIGCHLD, oldsig);
+
+ if (total)
+ trp->check_diag = txtacc_finish(trp->acc, 0);
+
+ trp->check_result = status;
+ if (WIFEXITED(status)) {
+ status = WEXITSTATUS(status);
+ if (status) {
+ logmsg(LOG_ERR, "%s for %s@%s returned %d",
+ descr, trp->name, trp->spool->tag, status);
+ return 1;
+ } else if (debug_level > 2)
+ logmsg(LOG_DEBUG, "%s for %s@%s returned %d",
+ descr, trp->name, trp->spool->tag, status);
+ } else if (WIFSIGNALED(status)) {
+ int sig = WTERMSIG(status);
+ logmsg(LOG_NOTICE,
+ "%s for %s@%s terminated on signal %d",
+ descr, trp->name, trp->spool->tag, sig);
+ return 1;
+ } else {
+ logmsg(LOG_NOTICE,
+ "%s for %s@%s terminated with unhandled status",
+ descr, trp->name, trp->spool->tag);
+ return 1;
}
+ return 0;
+}
- setenv ("WYDAWCA_SPOOL", spool->tag, 1);
- setenv ("WYDAWCA_SOURCE", spool->source_dir, 1);
- setenv ("WYDAWCA_DEST", spool->dest_dir, 1);
- setenv ("WYDAWCA_URL", spool->url, 1);
- setenv ("WYDAWCA_TRIPLET_BASE", trp->name, 1);
- setenv ("WYDAWCA_DIST_FILE", trp->file[file_dist].name, 1);
-
- if (chdir (temp_homedir))
- {
- logmsg (LOG_CRIT, "cannot change to %s: %s",
- temp_homedir, strerror (errno));
- _exit (127);
+static int
+external_check(struct file_triplet *trp)
+{
+ int rc;
+ const struct spool *spool = trp->spool;
+ char *file;
+
+ if (!trp->file[file_dist].name)
+ return 0;
+ if (!spool->check_script && !default_check_script)
+ return 0;
+
+ file = concat_dir(temp_homedir, trp->file[file_dist].name, NULL);
+ if (copy_file(trp->file[file_dist].name, file)) {
+ free(file);
+ return 1;
}
- argv[0] = "sh";
- argv[1] = script_file;
- argv[2] = NULL;
-
- execv ("/bin/sh", argv);
- _exit (127);
- }
-
- /* Master */
- free (script_file);
- close (p[1]);
- fp = fdopen (p[0], "r");
- buf = NULL;
- size = total = 0;
- if (debug_level > 2)
- logmsg (LOG_DEBUG, _("reading script output..."));
- while (grecs_getline (&buf, &size, fp) > 0)
- {
- size_t len = strlen (buf);
- if (debug_level > 2)
- logmsg (LOG_DEBUG, _("read: %s"), buf);
- txtacc_grow (trp->acc, buf, len);
- total += size;
- }
- txtacc_1grow (trp->acc, 0);
- if (debug_level > 2)
- logmsg (LOG_DEBUG, _("bytes read: %lu"), (unsigned long)total);
-
- fclose (fp);
-
- waitpid (pid, &status, 0);
- signal (SIGCHLD, oldsig);
-
- if (total)
- trp->check_diag = txtacc_finish (trp->acc, 0);
-
- trp->check_result = status;
- if (WIFEXITED (status))
- {
- status = WEXITSTATUS (status);
- if (status)
- {
- logmsg (LOG_ERR, "%s for %s@%s returned %d",
- descr, trp->name, trp->spool->tag, status);
- return 1;
+ rc = 0;
+ if (spool->check_script)
+ rc |= run_check_script(spool->check_script, trp,
+ _("spool check script"));
+
+ if (rc == 0 && default_check_script)
+ rc |= run_check_script(default_check_script, trp,
+ _("default check script"));
+
+ free(file);
+
+ if (rc) {
+ UPDATE_STATS(STAT_CHECK_FAIL);
+ notify(spool->notification, trp, ev_check_fail);
}
- else if (debug_level > 2)
- logmsg (LOG_DEBUG, "%s for %s@%s returned %d",
- descr, trp->name, trp->spool->tag, status);
- }
- else if (WIFSIGNALED (status))
- {
- int sig = WTERMSIG (status);
- logmsg (LOG_NOTICE,
- "%s for %s@%s terminated on signal %d",
- descr, trp->name, trp->spool->tag, sig);
- return 1;
- }
- else
- {
- logmsg (LOG_NOTICE,
- "%s for %s@%s terminated with unhandled status",
- descr, trp->name, trp->spool->tag);
- return 1;
- }
- return 0;
+
+ return rc;
}
static int
-external_check (struct file_triplet *trp)
+symlink_filelist(struct file_triplet *trp, const char *key, const char *val)
{
- int rc;
- const struct spool *spool = trp->spool;
- char *file;
-
- if (!trp->file[file_dist].name)
- return 0;
- if (!spool->check_script && !default_check_script)
- return 0;
-
- file = concat_dir (temp_homedir, trp->file[file_dist].name, NULL);
- if (copy_file (trp->file[file_dist].name, file))
- {
- free (file);
- return 1;
- }
-
- rc = 0;
- if (spool->check_script)
- rc |= run_check_script (spool->check_script, trp,
- _("spool check script"));
-
- if (rc == 0 && default_check_script)
- rc |= run_check_script (default_check_script, trp,
- _("default check script"));
-
- free (file);
-
- if (rc)
- {
- UPDATE_STATS (STAT_CHECK_FAIL);
- notify (spool->notification, trp, ev_check_fail);
- }
-
- return rc;
+ int rc = 0;
+ struct wordsplit ws;
+
+ if (wordsplit(val, &ws, WRDSF_DEFFLAGS)) {
+ logmsg(LOG_ERR,
+ _("cannot parse symlink value `%s'"), val);
+ return 1;
+ }
+
+ if (ws.ws_wordc != 2) {
+ rc = 1;
+ logmsg(LOG_ERR,
+ _("wrong number of arguments to %s directive: `%s'"),
+ key, val);
+ } else
+ rc = symlink_file(trp, ws.ws_wordv[0], ws.ws_wordv[1]);
+
+ wordsplit_free(&ws);
+ return rc;
}
/* Process the directives from TRP */
int
-process_directives (struct file_triplet *trp)
+process_directives(struct file_triplet *trp)
{
- int rc, n;
- const char *key, *val;
- const struct spool *spool;
-
- ASGN_SPOOL (spool, trp, return 1);
- UPDATE_STATS (STAT_COMPLETE_TRIPLETS);
- timer_start ("triplet");
- report_init ();
- for (n = directive_first (trp, &key, &val); n;
- n = directive_next (trp, n, &key, &val))
- {
- enum directive d = find_directive (key);
- switch (d)
- {
- case unknown_dir:
- /* should not happen */
- abort ();
-
- case comment_dir:
- logmsg (LOG_NOTICE, _("%s: COMMENT: %s"),
- trp->file[file_directive].name, val);
- break;
-
- case directory_dir:
- /* already processed (see fill_project_name in verify.c */
- break;
-
- case filename_dir:
- rc = verify_detached_signature (trp);
- if (rc == 0)
- {
- if (external_check (trp))
- return 1;
- if (move_file (trp, file_dist)
- || move_file (trp, file_signature))
- return 1;
- }
- else
- {
- logmsg (LOG_ERR, _("invalid detached signature for %s"),
- trp->name);
- return 1;
- }
- break;
-
- case version_dir:
- /* Already processed. See directive_version_in_range_p,
- called by verify_directive_format */
- break;
-
- case archive_dir:
- if (archive_file (trp, val))
- return 1;
- break;
-
- case symlink_dir:
- {
- int rc = 0;
- struct wordsplit ws;
-
- if (wordsplit (val, &ws, WRDSF_DEFFLAGS))
- {
- logmsg (LOG_ERR, _("cannot parse symlink value `%s'"),
- val);
- return 1;
- }
+ int rc, n;
+ const char *key, *val;
+ const struct spool *spool;
+
+ ASGN_SPOOL(spool, trp, return 1);
+ UPDATE_STATS(STAT_COMPLETE_TRIPLETS);
+ timer_start("triplet");
+ report_init();
+ for (n = directive_first(trp, &key, &val); n;
+ n = directive_next(trp, n, &key, &val)) {
+ enum directive d = find_directive(key);
+ switch (d) {
+ case unknown_dir:
+ /* should not happen */
+ abort();
+
+ case comment_dir:
+ logmsg(LOG_NOTICE, _("%s: COMMENT: %s"),
+ trp->file[file_directive].name, val);
+ break;
+
+ case directory_dir:
+ /* already processed (see fill_project_name in
+ verify.c */
+ break;
+
+ case filename_dir:
+ rc = verify_detached_signature(trp);
+ if (rc == 0) {
+ if (external_check(trp))
+ return 1;
+ if (move_file(trp, file_dist) ||
+ move_file(trp, file_signature))
+ return 1;
+ } else {
+ logmsg(LOG_ERR,
+ _("invalid detached signature for %s"),
+ trp->name);
+ return 1;
+ }
+ break;
+
+ case version_dir:
+ /* Already processed. See directive_version_in_range_p,
+ called by verify_directive_format */
+ break;
+
+ case archive_dir:
+ if (archive_file(trp, val))
+ return 1;
+ break;
+
+ case symlink_dir:
+ if (symlink_filelist(trp, key, val))
+ return 1;
+ break;
+
+ case rmsymlink_dir:
+ if (rmsymlink_file(trp, val))
+ return 1;
+
+ case replace_dir:
+ if (trp->version < 102) {
+ rc = 1;
+ logmsg(LOG_ERR,
+ _("\"replace\" directive is invalid "
+ "for version %d"),
+ trp->version);
+ }
+ }
+ }
- if (ws.ws_wordc != 2)
- {
- rc = 1;
- logmsg (LOG_ERR,
- _("wrong number of arguments to %s directive: `%s'"),
- key, val);
- }
- else
- rc = symlink_file (trp, ws.ws_wordv[0], ws.ws_wordv[1]);
-
- wordsplit_free (&ws);
- if (rc)
- return 1;
- }
- break;
-
- case rmsymlink_dir:
- if (rmsymlink_file (trp, val))
- return 1;
-
- case replace_dir:
- if (trp->version < 102)
- {
- rc = 1;
- logmsg (LOG_ERR,
- _("\"replace\" directive is invalid for version %d"),
- trp->version);
- }
+ if (!dry_run_mode && unlink(trp->file[file_directive].name)) {
+ logmsg(LOG_CRIT, _("%s: cannot unlink directive file: %s"),
+ trp->file[file_directive].name, strerror(errno));
}
- }
-
- if (!dry_run_mode && unlink (trp->file[file_directive].name))
- {
- logmsg (LOG_CRIT, _("%s: cannot unlink directive file: %s"),
- trp->file[file_directive].name, strerror (errno));
- }
-
- UPDATE_STATS (STAT_TRIPLET_SUCCESS);
- report_finish ();
- timer_stop ("triplet");
- notify (spool->notification, trp, ev_success);
- return 0;
+
+ UPDATE_STATS(STAT_TRIPLET_SUCCESS);
+ report_finish();
+ timer_stop("triplet");
+ notify(spool->notification, trp, ev_success);
+ return 0;
}

Return to:

Send suggestions and report system problems to the System administrator.