diff --git a/usr.sbin/sup/source/log.c b/usr.sbin/sup/source/log.c index eb52ee7c5051..cd8613094446 100644 --- a/usr.sbin/sup/source/log.c +++ b/usr.sbin/sup/source/log.c @@ -1,4 +1,4 @@ -/* $NetBSD: log.c,v 1.10 2009/10/16 12:41:37 christos Exp $ */ +/* $NetBSD: log.c,v 1.11 2013/03/08 20:56:44 christos Exp $ */ /* * Copyright (c) 1992 Carnegie Mellon University @@ -63,6 +63,19 @@ logopen(char *program) opened++; } +static void +vfmtbuf(int f, char *buf, size_t bufsiz, const char *fmt, va_list ap) +{ + char hostname[MAXHOSTNAMELEN]; + char xbuf[STRINGLENGTH], ybuf[STRINGLENGTH]; + gethostname(hostname, sizeof(hostname)); + snprintf(ybuf, sizeof(ybuf), "SUP@%s%s ", hostname, f ? ":" : ""); + vsnprintf(xbuf, sizeof(xbuf), fmt, ap); + snprintf(buf, bufsiz, "%s%s", ybuf, xbuf); + return buf; +} + + void logquit(int retval, const char *fmt, ...) { @@ -70,7 +83,7 @@ logquit(int retval, const char *fmt, ...) va_list ap; va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); + vfmtbuf(1, buf, sizeof(buf), fmt, ap); va_end(ap); if (opened) { syslog(LOG_ERR, "%s", buf); @@ -87,7 +100,7 @@ logerr(const char *fmt, ...) va_list ap; va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); + vfmtbuf(1, buf, sizeof(buf), fmt, ap); va_end(ap); if (opened) { syslog(LOG_ERR, "%s", buf); @@ -104,7 +117,7 @@ loginfo(const char *fmt, ...) va_list ap; va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); + vfmtbuf(0, buf, sizeof(buf), fmt, ap); va_end(ap); if (opened) { syslog(LOG_INFO, "%s", buf); @@ -137,7 +150,7 @@ logdeny(const char *fmt, ...) va_list ap; va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); + vfmtbuf(1, buf, sizeof(buf), fmt, ap); va_end(ap); if (opened) { syslog(deny_severity, "%s", buf); @@ -154,7 +167,7 @@ logallow(const char *fmt, ...) va_list ap; va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); + vfmtbuf(1, buf, sizeof(buf), fmt, ap); va_end(ap); if (opened) { syslog(allow_severity, "%s", buf); diff --git a/usr.sbin/sup/source/scan.c b/usr.sbin/sup/source/scan.c index b3694d6e61a0..5d00ee5e4512 100644 --- a/usr.sbin/sup/source/scan.c +++ b/usr.sbin/sup/source/scan.c @@ -1,4 +1,4 @@ -/* $NetBSD: scan.c,v 1.30 2011/08/31 16:25:00 plunky Exp $ */ +/* $NetBSD: scan.c,v 1.31 2013/03/08 20:56:44 christos Exp $ */ /* * Copyright (c) 1992 Carnegie Mellon University @@ -310,7 +310,9 @@ getrelease(char *release) free(frelease); return (FALSE); } else - (void) chdir(basedir); + if (chdir(basedir) < 0) + goaway("Can't chdir to %s (%s)", + basedir, strerror(errno)); tl->TLnext = listTL; listTL = tl; if (release == NULL) @@ -363,8 +365,11 @@ makescanlists(void) prefix = saveprefix; if (prefix != NULL) { if (chdir(prefix) < 0) - goaway("Can't chdir to %s", prefix); - (void) chdir(basedir); + goaway("Can't chdir to %s (%s)", + prefix, strerror(errno)); + if (chdir(basedir) < 0) + goaway("Can't chdir to %s (%s)", + basedir, strerror(errno)); } makescan(tl->TLlist, tl->TLscan); free(tl); @@ -628,13 +633,21 @@ listentry(char *name, char *fullname, char *updir, int always) } listdir(fullname, always); if (updir == 0 || linkcount) { - (void) chdir(basedir); + if (chdir(basedir) < 0) + goaway("Can't chdir to %s (%s)", + basedir, strerror(errno)); if (prefix) - (void) chdir(prefix); + if (chdir(prefix) < 0) + goaway("Can't chdir to %s (%s)", + prefix, strerror(errno)); if (updir && *updir) - (void) chdir(updir); + if (chdir(updir) < 0) + goaway("Can't chdir to %s (%s)", + updir, strerror(errno)); } else - (void) chdir(".."); + if (chdir("..") < 0) + goaway("Can't chdir to %s (%s)", + "..", strerror(errno)); return; } if (access(name, R_OK) < 0) @@ -1009,12 +1022,16 @@ cdprefix(char *prefix) if (curprefix == NULL) { if (prefix == NULL) return; - (void) chdir(prefix); + if (chdir(prefix) < 0) + goaway("Can't chdir to %s (%s)", + prefix, strerror(errno)); curprefix = prefix; return; } if (prefix == NULL) { - (void) chdir(basedir); + if (chdir(basedir) < 0) + goaway("Can't chdir to %s (%s)", + basedir, strerror(errno)); curprefix = NULL; return; } @@ -1024,7 +1041,11 @@ cdprefix(char *prefix) curprefix = prefix; return; } - (void) chdir(basedir); - (void) chdir(prefix); + if (chdir(basedir) < 0) + goaway("Can't chdir to %s (%s)", + basedir, strerror(errno)); + if (chdir(prefix) < 0) + goaway("Can't chdir to %s (%s)", + prefix, strerror(errno)); curprefix = prefix; } diff --git a/usr.sbin/sup/source/scm.c b/usr.sbin/sup/source/scm.c index 1dc73b5553c7..52d24d1083d4 100644 --- a/usr.sbin/sup/source/scm.c +++ b/usr.sbin/sup/source/scm.c @@ -1,4 +1,4 @@ -/* $NetBSD: scm.c,v 1.29 2011/08/31 16:25:00 plunky Exp $ */ +/* $NetBSD: scm.c,v 1.30 2013/03/08 20:56:44 christos Exp $ */ /* * Copyright (c) 1992 Carnegie Mellon University @@ -445,7 +445,8 @@ request(char *server, char *hostname, int *retry) memcpy(&remoteaddr, res->ai_addr, res->ai_addrlen); remotename = estrdup(hostname); x = 0x01020304; - (void) write(netfile, &x, sizeof(int)); + if (write(netfile, &x, sizeof(int)) == -1) + return (SCMERR); swapmode = 0; /* swap only on server, not client */ freeaddrinfo(res0); return (SCMOK); @@ -655,14 +656,16 @@ int scmerr(int error, const char *fmt, ...) { va_list ap; + char hostname[MAXHOSTNAMELEN]; + gethostname(hostname, sizeof(hostname)); va_start(ap, fmt); (void) fflush(stdout); if (progpid > 0) - fprintf(stderr, "%s %d: ", program, progpid); + fprintf(stderr, "%s@%s %d: ", program, hostname, progpid); else - fprintf(stderr, "%s: ", program); + fprintf(stderr, "%s@%s: ", program, hostname); vfprintf(stderr, fmt, ap); va_end(ap); diff --git a/usr.sbin/sup/source/scmio.c b/usr.sbin/sup/source/scmio.c index 1f33a4911209..4ce83066914c 100644 --- a/usr.sbin/sup/source/scmio.c +++ b/usr.sbin/sup/source/scmio.c @@ -1,4 +1,4 @@ -/* $NetBSD: scmio.c,v 1.21 2011/08/31 16:25:00 plunky Exp $ */ +/* $NetBSD: scmio.c,v 1.22 2013/03/08 20:56:44 christos Exp $ */ /* * Copyright (c) 1992 Carnegie Mellon University @@ -667,7 +667,8 @@ readfile(int f) } else x = readdata((size_t)XFERSIZE(count), buf, false); if (x == SCMOK) { - (void) write(f, buf, (size_t)XFERSIZE(count)); + if (write(f, buf, (size_t)XFERSIZE(count)) == -1) + return SCMERR; count -= XFERSIZE(count); } } @@ -740,7 +741,8 @@ crosspatch(void) if (c <= 0) { break; } - (void) write(1, buf, (size_t)c); + if (write(1, buf, (size_t)c) == -1) + break; } } if (set[0].revents & POLLIN) { @@ -750,7 +752,8 @@ crosspatch(void) else { if (c <= 0) break; - (void) write(netfile, buf, (size_t)c); + if (write(netfile, buf, (size_t)c) == -1) + break; } } } diff --git a/usr.sbin/sup/source/setproctitle.c b/usr.sbin/sup/source/setproctitle.c index 73e55b890aca..9b038c0a20a2 100644 --- a/usr.sbin/sup/source/setproctitle.c +++ b/usr.sbin/sup/source/setproctitle.c @@ -62,12 +62,12 @@ setproctitle(const char *fmt, ...) */ /* 1 for the first entry, 1 for the NULL */ - char **args = __environ - 2, *s; + char **args = __environ - 2; #ifdef _SC_ARG_MAX s = (char *)sysconf(_SC_ARG_MAX); -#elifdef ARG_MAX +#elif defined(ARG_MAX) s = (char *)ARG_MAX; -#elifdef NCARGS +#elif defined(NCARGS) s = (char *)NCARGS; #else s = (char *)(256 * 1024); @@ -82,21 +82,23 @@ setproctitle(const char *fmt, ...) *(int *)args = 1; /* *argc = 1; */ pname = *++args; /* pname = argv[0] */ + /* In case we get called again */ + if ((p = strchr(pname, ':')) != NULL) + *p = '\0'; + /* Just the last component of the name */ if ((p = strrchr(pname, '/')) != NULL) - pname = p + 1; - - /* In case we get called again */ - if ((p = strrchr(pname, ':')) != NULL) - *p = '\0'; + p = p + 1; + else + p = pname; va_start(ap, fmt); if (fmt != NULL) { - len = snprintf(buf, sizeof(buf), "%s: ", pname); + len = snprintf(buf, sizeof(buf), "%s: ", p); if (len >= 0) (void)vsnprintf(buf + len, sizeof(buf) - len, fmt, ap); } else - (void)snprintf(buf, sizeof(buf), "%s", pname); + (void)snprintf(buf, sizeof(buf), "%s", p); va_end(ap); (void)strcpy(pname, buf); diff --git a/usr.sbin/sup/source/supcmeat.c b/usr.sbin/sup/source/supcmeat.c index 2cc391f24fc8..f8b1e4a5a00a 100644 --- a/usr.sbin/sup/source/supcmeat.c +++ b/usr.sbin/sup/source/supcmeat.c @@ -1,4 +1,4 @@ -/* $NetBSD: supcmeat.c,v 1.40 2011/09/21 19:34:54 christos Exp $ */ +/* $NetBSD: supcmeat.c,v 1.41 2013/03/08 20:56:44 christos Exp $ */ /* * Copyright (c) 1992 Carnegie Mellon University @@ -164,6 +164,15 @@ getonehost(TREE * t, void *v) return (SCMEOF); } +static char * +supctime(time_t *loc) +{ + char *p, *x = ctime(loc); + if ((p = strchr(x, '\n'))) + *p = '\0'; + return x; +} + TREE * getcollhost(int *tout, int *backoff, long int *state, int *nhostsp) { @@ -211,7 +220,7 @@ getcoll(void) t = getcollhost(&tout, &backoff, &state, &nhosts); if (t == NULL) { finishup(SCMEOF); - notify(NULL); + notify(0, NULL); return; } t->Tmode = SCMEOF; @@ -234,7 +243,7 @@ getcoll(void) thisC->Clockfd = -1; } finishup(x); - notify(NULL); + notify(0, NULL); } /*** Sign on to file server ***/ @@ -246,7 +255,7 @@ signon(TREE * t, int nhosts, int *tout) time_t tloc; if ((thisC->Cflags & CFLOCAL) == 0 && thishost(thisC->Chost->Tname)) { - vnotify("SUP: Skipping local collection %s\n", collname); + vnotify(1, "Skipping local collection %s", collname); t->Tmode = SCMEOF; return (TRUE); } @@ -260,7 +269,7 @@ signon(TREE * t, int nhosts, int *tout) *tout = timeout; if (x != SCMOK) { if (nhosts) { - notify("SUP: Can't connect to host %s\n", + notify(1, "Can't connect to host %s", thisC->Chost->Tname); t->Tmode = SCMEOF; } else @@ -275,16 +284,16 @@ signon(TREE * t, int nhosts, int *tout) if (x != SCMOK) goaway("Error reading signon reply from fileserver"); tloc = time(NULL); - vnotify("SUP Fileserver %d.%d (%s) %d on %s at %.8s\n", - protver, pgmver, scmver, fspid, remotehost(), ctime(&tloc) + 11); + vnotify(0, "Fileserver %d.%d (%s) %d on %s at %.8s", + protver, pgmver, scmver, fspid, remotehost(), supctime(&tloc) + 11); free(scmver); scmver = NULL; if (protver < 4) { dontjump = TRUE; goaway("Fileserver sup protocol version is obsolete."); - notify("SUP: This version of sup can only communicate with a fileserver using at least\n"); - notify("SUP: version 4 of the sup network protocol. You should either run a newer\n"); - notify("SUP: version of the sup fileserver or find an older version of sup.\n"); + notify(1, "This version of sup can only communicate with a fileserver using at least"); + notify(1, "version 4 of the sup network protocol. You should either run a newer"); + notify(1, "version of the sup fileserver or find an older version of sup."); t->Tmode = SCMEOF; return (TRUE); } @@ -309,7 +318,7 @@ setup(TREE * t) (void) mkdir("sup", 0755); if (stat("sup", &sbuf) < 0) goaway("Can't create directory %s/sup", thisC->Cbase); - vnotify("SUP Created directory %s/sup\n", thisC->Cbase); + vnotify(0, "Created directory %s/sup", thisC->Cbase); } if (thisC->Cprefix && chdir(thisC->Cprefix) < 0) goaway("Can't change to %s from base directory %s", @@ -319,7 +328,9 @@ setup(TREE * t) thisC->Cprefix ? "prefix" : "base", thisC->Cprefix ? thisC->Cprefix : thisC->Cbase); if (thisC->Cprefix) - (void) chdir(thisC->Cbase); + if (chdir(thisC->Cbase) < 0) + goaway("Can't chdir to %s (%s)", thisC->Cbase, + strerror(errno)); /* read time of last upgrade from when file */ if ((thisC->Cflags & CFURELSUF) && thisC->Crelease) @@ -357,21 +368,21 @@ setup(TREE * t) } switch (setupack) { case FSETUPSAME: - notify("SUP: Attempt to upgrade from same host to same directory\n"); + notify(1, "Attempt to upgrade from same host to same directory"); done(FDONESRVERROR, "Overwrite error"); case FSETUPHOST: - notify("SUP: This host has no permission to access %s\n", + notify(1, "This host has no permission to access %s", collname); done(FDONESRVERROR, "Permission denied"); case FSETUPOLD: - notify("SUP: This version of SUP is too old for the fileserver\n"); + notify(1, "This version of SUP is too old for the fileserver"); done(FDONESRVERROR, "Obsolete client"); case FSETUPRELEASE: - notify("SUP: Invalid release %s for collection %s\n", + notify(1, "Invalid release %s for collection %s", release == NULL ? DEFRELEASE : release, collname); done(FDONESRVERROR, "Invalid release"); case FSETUPBUSY: - vnotify("SUP Fileserver is currently busy\n"); + vnotify(0, "Fileserver is currently busy"); t->Tmode = SCMOK; doneack = FDONESRVERROR; donereason = "Fileserver is busy"; @@ -421,14 +432,15 @@ suplogin(void) goaway("Collection %s is locked by another sup", collname); goaway("Can't lock collection %s", collname); } - vnotify("SUP Waiting for exclusive access lock\n"); + vnotify(0, "Waiting for exclusive access lock"); if (WAITLOCK(f) < 0) { (void) close(f); goaway("Can't lock collection %s", collname); } } thisC->Clockfd = f; - vnotify("SUP Locked collection %s for exclusive access\n", collname); + vnotify(0, "Locked collection %s for exclusive access", + collname); } logcrypt = NULL; loguser = thisC->Clogin; @@ -454,10 +466,10 @@ suplogin(void) if (x != SCMOK) goaway("Error reading login reply from file server"); if (logack == FLOGNG) { - notify("SUP: %s\n", logerror); + notify(1, "%s", logerror); free(logerror); logerror = NULL; - notify("SUP: Improper login to %s account", + notify(1, "Improper login to %s account", thisC->Clogin ? thisC->Clogin : "default"); done(FDONESRVERROR, "Improper login"); } @@ -513,7 +525,7 @@ listfiles(void) } (void) fclose(f); } - vnotify("SUP Requesting changes since %s", ctime(&lasttime) + 4); + vnotify(0, "Requesting changes since %s", supctime(&lasttime) + 4); x = msgrefuse(); if (x != SCMOK) goaway("Error sending refuse list to file server"); @@ -522,7 +534,9 @@ listfiles(void) if (x != SCMOK) goaway("Error reading file list from file server"); if (thisC->Cprefix) - (void) chdir(thisC->Cprefix); + if (chdir(thisC->Cprefix) < 0) + goaway("Can't chdir to %s (%s)", + thisC->Cprefix, strerror(errno)); needT = NULL; (void) Tprocess(listT, needone, NULL); Tfree(&listT); @@ -597,7 +611,7 @@ needone(TREE * t, void *dummy __unused) static int denyone(TREE * t, void *v __unused) { - vnotify("SUP: Access denied to %s\n", t->Tname); + vnotify(1, "Access denied to %s", t->Tname); return (SCMOK); } @@ -616,41 +630,41 @@ deleteone(TREE * t, void *v __unused) /* is it a symbolic link ? */ if (S_ISLNK(sbuf.st_mode)) { if (Tlookup(refuseT, name)) { - vnotify("SUP Would not delete symbolic link %s\n", + vnotify(0, "Would not delete symbolic link %s", name); return (SCMOK); } if (thisC->Cflags & CFLIST) { - vnotify("SUP Would delete symbolic link %s\n", name); + vnotify(0, "Would delete symbolic link %s", name); return (SCMOK); } if ((thisC->Cflags & CFDELETE) == 0) { - notify("SUP Please delete symbolic link %s\n", name); + notify(0, "Please delete symbolic link %s", name); t->Tflags |= FUPDATE; return (SCMOK); } x = unlink(name); if (x < 0) { - notify("SUP: Unable to delete symbolic link %s (%s)\n", + notify(1, "Unable to delete symbolic link %s (%s)", name, strerror(errno)); t->Tflags |= FUPDATE; return (SCMOK); } - vnotify("SUP Deleted symbolic link %s\n", name); + vnotify(0, "Deleted symbolic link %s", name); return (SCMOK); } /* is it a directory ? */ if (S_ISDIR(sbuf.st_mode)) { if (Tlookup(refuseT, name)) { - vnotify("SUP Would not delete directory %s\n", name); + vnotify(0, "Would not delete directory %s", name); return (SCMOK); } if (thisC->Cflags & CFLIST) { - vnotify("SUP Would delete directory %s\n", name); + vnotify(0, "Would delete directory %s", name); return (SCMOK); } if ((thisC->Cflags & CFDELETE) == 0) { - notify("SUP Please delete directory %s\n", name); + notify(0, "Please delete directory %s", name); t->Tflags |= FUPDATE; return (SCMOK); } @@ -664,36 +678,36 @@ deleteone(TREE * t, void *v __unused) runp("rm", "rm", "-rf", name, 0); } if (rmdir(name) < 0 && errno != ENOENT) { - notify("SUP: Unable to delete directory %s (%s)\n", + notify(1, "Unable to delete directory %s (%s)", name, strerror(errno)); t->Tflags |= FUPDATE; return (SCMOK); } - vnotify("SUP Deleted directory %s\n", name); + vnotify(0, "Deleted directory %s", name); return (SCMOK); } /* it is a file */ if (Tlookup(refuseT, name)) { - vnotify("SUP Would not delete file %s\n", name); + vnotify(0, "Would not delete file %s", name); return (SCMOK); } if (thisC->Cflags & CFLIST) { - vnotify("SUP Would delete file %s\n", name); + vnotify(0, "Would delete file %s", name); return (SCMOK); } if ((thisC->Cflags & CFDELETE) == 0) { - notify("SUP Please delete file %s\n", name); + notify(0, "Please delete file %s", name); t->Tflags |= FUPDATE; return (SCMOK); } x = unlink(name); if (x < 0) { - notify("SUP: Unable to delete file %s (%s)\n", name, + notify(1, "Unable to delete file %s (%s)", name, strerror(errno)); t->Tflags |= FUPDATE; return (SCMOK); } - vnotify("SUP Deleted file %s\n", name); + vnotify(0, "Deleted file %s", name); return (SCMOK); } /*************************************** @@ -722,9 +736,9 @@ recvfiles(void) if (x != SCMOK) goaway("Error sending compression check to server"); if (docompress) - vnotify("SUP Using compressed file transfer\n"); + vnotify(0, "Using compressed file transfer"); if (thisC->Cflags & CFCANONICALIZE) - vnotify("SUP Filename canonicalization is on\n"); + vnotify(0, "Filename canonicalization is on"); } recvmore = TRUE; upgradeT = NULL; @@ -777,7 +791,7 @@ prepare(char *name, int mode, int *newp, struct stat * statp) break; } if (thisC->Cflags & CFLIST) { - vnotify("SUP Would remove %s %s\n", type, name); + vnotify(0, "Would remove %s %s", type, name); return (FALSE); } if (S_ISDIR(statp->st_mode)) { @@ -797,10 +811,10 @@ prepare(char *name, int mode, int *newp, struct stat * statp) er = errno; } if (stat(name, statp) < 0) { - vnotify("SUP Removed %s %s\n", type, name); + vnotify(0, "Removed %s %s", type, name); return (FALSE); } - notify("SUP: Couldn't remove %s %s (%s)\n", type, name, strerror(er)); + notify(1, "Couldn't remove %s %s (%s)", type, name, strerror(er)); return (TRUE); } @@ -820,13 +834,13 @@ recvone(TREE * t, va_list ap) } /* check for failed access at fileserver */ if (t->Tmode == 0) { - notify("SUP: File server unable to transfer file %s\n", + notify(1, "File server unable to transfer file %s", t->Tname); thisC->Cnogood = TRUE; return (SCMOK); } if (prepare(t->Tname, t->Tmode & S_IFMT, &new, &sbuf)) { - notify("SUP: Can't prepare path for %s (%s)\n", t->Tname, + notify(1, "Can't prepare path for %s (%s)", t->Tname, strerror(errno)); if (S_ISREG(t->Tmode)) { x = readskip(); /* skip over file */ @@ -848,7 +862,7 @@ recvone(TREE * t, va_list ap) x = recvreg(t, new, &sbuf); break; default: - goaway("Unknown file type %o\n", t->Tmode & S_IFMT); + goaway("Unknown file type %o", t->Tmode & S_IFMT); } if (x) { thisC->Cnogood = TRUE; @@ -867,11 +881,11 @@ recvdir(TREE * t, int new, struct stat * statp) if (new) { if (thisC->Cflags & CFLIST) { - vnotify("SUP Would create directory %s\n", t->Tname); + vnotify(0, "Would create directory %s", t->Tname); return (FALSE); } if (makedir(t->Tname, 0755, statp) == -1) { - notify("SUP: Can't create directory %s (%s)\n", + notify(1, "Can't create directory %s (%s)", t->Tname, strerror(errno)); return TRUE; } @@ -887,12 +901,16 @@ recvdir(TREE * t, int new, struct stat * statp) return (FALSE); } if (thisC->Cflags & CFLIST) { - vnotify("SUP Would update directory %s\n", t->Tname); + vnotify(0, "Would update directory %s", t->Tname); return (FALSE); } if ((t->Tflags & FNOACCT) == 0) { - (void) chown(t->Tname, t->Tuid, t->Tgid); - (void) chmod(t->Tname, t->Tmode & S_IMODE); + if (chown(t->Tname, t->Tuid, t->Tgid) < 0) + goaway("Can't chown %s (%s)", t->Tname, + strerror(errno)); + if (chmod(t->Tname, t->Tmode & S_IMODE) < 0) + goaway("Can't chmod %s (%s)", t->Tname, + strerror(errno)); } tbuf[0].tv_sec = time(NULL); tbuf[0].tv_usec = 0; @@ -900,7 +918,7 @@ recvdir(TREE * t, int new, struct stat * statp) tbuf[1].tv_usec = 0; if (!noutime) (void) utimes(t->Tname, tbuf); - vnotify("SUP %s directory %s\n", new ? "Created" : "Updated", t->Tname); + vnotify(0, "%s directory %s", new ? "Created" : "Updated", t->Tname); return (FALSE); } @@ -912,7 +930,7 @@ recvsym(TREE * t, int new, struct stat * statp) char *linkname; if (t->Tlink == NULL || t->Tlink->Tname == NULL) { - notify("SUP: Missing linkname for symbolic link %s\n", + notify(1, "Missing linkname for symbolic link %s", t->Tname); return (TRUE); } @@ -925,18 +943,18 @@ recvsym(TREE * t, int new, struct stat * statp) if (n >= 0) t->Tname[n] = '\0'; if (thisC->Cflags & CFLIST) { - vnotify("SUP Would %s symbolic link %s to %s\n", + vnotify(0, "Would %s symbolic link %s to %s", new ? "create" : "update", t->Tname, linkname); return (FALSE); } if (!new) (void) unlink(t->Tname); if (symlink(linkname, t->Tname) < 0 || lstat(t->Tname, statp) < 0) { - notify("SUP: Unable to create symbolic link %s (%s)\n", + notify(1, "Unable to create symbolic link %s (%s)", t->Tname, strerror(errno)); return (TRUE); } - vnotify("SUP Created symbolic link %s to %s\n", t->Tname, linkname); + vnotify(0, "SUP Created symbolic link %s to %s", t->Tname, linkname); return (FALSE); } @@ -957,7 +975,7 @@ recvreg(TREE * t, int new, struct stat * statp) noupdate = 1; break; case -1: - notify("SUP: Can't create path for %s (%s)\n", t->Tname, + notify(1, "Can't create path for %s (%s)", t->Tname, strerror(errno)); return TRUE; } @@ -977,13 +995,17 @@ recvreg(TREE * t, int new, struct stat * statp) return (FALSE); } if (thisC->Cflags & CFLIST) { - vnotify("SUP Would update file %s\n", t->Tname); + vnotify(0, "Would update file %s", t->Tname); return (FALSE); } - vnotify("SUP Updating file %s\n", t->Tname); + vnotify(0, "Updating file %s", t->Tname); if ((t->Tflags & FNOACCT) == 0) { - (void) chown(t->Tname, t->Tuid, t->Tgid); - (void) chmod(t->Tname, t->Tmode & S_IMODE); + if (chown(t->Tname, t->Tuid, t->Tgid) < 0) + goaway("Can't chown %s (%s)", t->Tname, + strerror(errno)); + if (chmod(t->Tname, t->Tmode & S_IMODE) < 0) + goaway("Can't chmod %s (%s)", t->Tname, + strerror(errno)); } tbuf[0].tv_sec = time(NULL); tbuf[0].tv_usec = 0; @@ -1002,10 +1024,10 @@ recvreg(TREE * t, int new, struct stat * statp) p = "receive old"; else p = "receive"; - vnotify("SUP Would %s file %s\n", p, t->Tname); + vnotify(0, "Would %s file %s", p, t->Tname); return (FALSE); } - vnotify("SUP Receiving file %s\n", t->Tname); + vnotify(0, "Receiving file %s", t->Tname); if (!new && S_ISREG(t->Tmode) && (t->Tflags & FBACKUP) && (thisC->Cflags & CFBACKUP)) { fin = fopen(t->Tname, "r"); /* create backup */ @@ -1013,7 +1035,7 @@ recvreg(TREE * t, int new, struct stat * statp) x = readskip(); /* skip over file */ if (x != SCMOK) goaway("Can't skip file transfer"); - notify("SUP: Can't open %s to create backup\n", + notify(1, "Can't open %s to create backup", t->Tname); return (TRUE); /* mark upgrade as nogood */ } @@ -1029,14 +1051,14 @@ recvreg(TREE * t, int new, struct stat * statp) x = readskip(); /* skip over file */ if (x != SCMOK) goaway("Can't skip file transfer"); - notify("SUP: Can't create %s for backup\n", filename); + notify(1, "Can't create %s for backup", filename); (void) fclose(fin); return (TRUE); } ffilecopy(fin, fout); (void) fclose(fin); (void) fclose(fout); - vnotify("SUP Backup of %s created\n", t->Tname); + vnotify(0, "Backup of %s created", t->Tname); } x = copyfile(t->Tname, NULL); if (x) @@ -1044,8 +1066,12 @@ recvreg(TREE * t, int new, struct stat * statp) if ((t->Tflags & FNOACCT) == 0) { /* convert user and group names to local ids */ ugconvert(t->Tuser, t->Tgroup, &t->Tuid, &t->Tgid, &t->Tmode); - (void) chown(t->Tname, t->Tuid, t->Tgid); - (void) chmod(t->Tname, t->Tmode & S_IMODE); + if (chown(t->Tname, t->Tuid, t->Tgid) < 0) + goaway("Can't chown %s (%s)", t->Tname, + strerror(errno)); + if (chmod(t->Tname, t->Tmode & S_IMODE) < 0) + goaway("Can't chmod %s (%s)", t->Tname, + strerror(errno)); } tbuf[0].tv_sec = time(NULL); tbuf[0].tv_usec = 0; @@ -1067,10 +1093,10 @@ linkone(TREE * t, void *fv) if (lstat(fname, &fbuf) < 0) { /* source file */ if (thisC->Cflags & CFLIST) { - vnotify("SUP Would link %s to %s\n", name, fname); + vnotify(0, "Would link %s to %s", name, fname); return (SCMOK); } - notify("SUP: Can't link %s to missing file %s\n", name, fname); + notify(1, "Can't link %s to missing file %s", name, fname); thisC->Cnogood = TRUE; return (SCMOK); } @@ -1082,7 +1108,7 @@ linkone(TREE * t, void *fv) fbuf.st_dev == sbuf.st_dev && fbuf.st_ino == sbuf.st_ino) return (SCMOK); if (thisC->Cflags & CFLIST) { - vnotify("SUP Would link %s to %s\n", name, fname); + notify(0, "Would link %s to %s", name, fname); return (SCMOK); } (void) unlink(name); @@ -1092,11 +1118,11 @@ linkone(TREE * t, void *fv) x = symlink(fname, name); } if (x < 0 || lstat(name, &sbuf) < 0) { - notify("SUP: Unable to create %slink %s (%s)\n", type, name, + notify(1, "Unable to create %slink %s (%s)", type, name, strerror(x)); return (TRUE); } - vnotify("SUP Created %slink %s to %s\n", type, name, fname); + vnotify(0, "Created %slink %s to %s", type, name, fname); return (SCMOK); } @@ -1106,26 +1132,26 @@ execone(TREE * t, void *v __unused) int w; if (thisC->Cflags & CFLIST) { - vnotify("SUP Would execute %s\n", t->Tname); + vnotify(0, "Would execute %s", t->Tname); return (SCMOK); } if ((thisC->Cflags & CFEXECUTE) == 0) { - notify("SUP Please execute %s\n", t->Tname); + notify(0, "Please execute %s", t->Tname); return (SCMOK); } - vnotify("SUP Executing %s\n", t->Tname); + vnotify(0, "Executing %s", t->Tname); w = system(t->Tname); if (WIFEXITED(w) && WEXITSTATUS(w) != 0) { - notify("SUP: Execute command returned failure status %#o\n", + notify(1, "Execute command returned failure status %#o", WEXITSTATUS(w)); thisC->Cnogood = TRUE; } else if (WIFSIGNALED(w)) { - notify("SUP: Execute command killed by signal %d\n", + notify(1, "Execute command killed by signal %d", WTERMSIG(w)); thisC->Cnogood = TRUE; } else if (WIFSTOPPED(w)) { - notify("SUP: Execute command stopped by signal %d\n", + notify(1, "Execute command stopped by signal %d", WSTOPSIG(w)); thisC->Cnogood = TRUE; } @@ -1202,7 +1228,7 @@ copyfile(char *to, char *from) if (from) { /* reading file */ fromf = open(from, O_RDONLY, 0); if (fromf < 0) { - notify("SUP: Can't open %s to copy to %s (%s)\n", + notify(1, "Can't open %s to copy to %s (%s)", from, to, strerror(errno)); return (TRUE); } @@ -1222,19 +1248,25 @@ copyfile(char *to, char *from) break; /* try sup directory */ if (thisC->Cprefix) - (void) chdir(thisC->Cbase); + if (chdir(thisC->Cbase) < 0) + goaway("Can't chdir to %s (%s)", thisC->Cbase, + strerror(errno)); (void) sprintf(tname, "sup/#%d.sup", thispid); tof = open(tname, (O_WRONLY | O_CREAT | O_TRUNC | O_EXCL), 0600); if (tof >= 0) { if (thisC->Cprefix) - (void) chdir(thisC->Cprefix); + if (chdir(thisC->Cprefix) < 0) + goaway("Can't chdir to %s (%s)", + thisC->Cprefix, strerror(errno)); break; } /* try base directory */ (void) sprintf(tname, "#%d.sup", thispid); tof = open(tname, (O_WRONLY | O_CREAT | O_TRUNC | O_EXCL), 0600); if (thisC->Cprefix) - (void) chdir(thisC->Cprefix); + if (chdir(thisC->Cprefix) < 0) + goaway("Can't chdir to %s (%s)", + thisC->Cprefix, strerror(errno)); if (tof >= 0) break; #ifdef VAR_TMP @@ -1262,7 +1294,7 @@ copyfile(char *to, char *from) if (tof >= 0) break; /* no luck */ - notify("SUP: Can't create %s or temp file for it (%s)\n", to, + notify(1, "Can't create %s or temp file for it (%s)", to, strerror(errno)); lockout(FALSE); if (fromf >= 0) @@ -1280,7 +1312,7 @@ copyfile(char *to, char *from) (void) close(fromf); (void) close(tof); if (x < 0) { - notify("SUP: Error in copying %s to %s\n", from, to); + notify(1, "Error in copying %s to %s", from, to); if (istemp) (void) unlink(tname); lockout(FALSE); @@ -1338,7 +1370,7 @@ copyfile(char *to, char *from) if (istemp) (void) unlink(tname); lockout(FALSE); - goaway("Error in receiving %s\n", to); + goaway("Error in receiving %s", to); } } if (!istemp) { /* no temp file used */ @@ -1369,7 +1401,7 @@ copyfile(char *to, char *from) unlink(tname) == -1 || (outfd = open(tname, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) == -1 || runiofd(av, infd, outfd, 2) != 0) { - notify("SUP: Error in uncompressing file %s (%s)\n", + notify(1, "Error in uncompressing file %s (%s)", to, tname); (void) unlink(tname); if (infd != -1) @@ -1390,7 +1422,7 @@ copyfile(char *to, char *from) } fromf = open(tname, O_RDONLY, 0); if (fromf < 0) { - notify("SUP: Error in moving temp file to %s (%s)\n", + notify(1, "Error in moving temp file to %s (%s)", to, strerror(errno)); (void) unlink(tname); lockout(FALSE); @@ -1399,7 +1431,7 @@ copyfile(char *to, char *from) tof = open(to, (O_WRONLY | O_CREAT | O_TRUNC | O_EXCL), 0600); if (tof < 0) { (void) close(fromf); - notify("SUP: Can't create %s from temp file (%s)\n", + notify(1, "Can't create %s from temp file (%s)", to, strerror(errno)); (void) unlink(tname); lockout(FALSE); @@ -1411,7 +1443,7 @@ copyfile(char *to, char *from) (void) unlink(tname); lockout(FALSE); if (x < 0) { - notify("SUP: Error in storing data in %s\n", to); + notify(1, "Error in storing data in %s", to); return (TRUE); } return (FALSE); @@ -1444,8 +1476,8 @@ finishup(int x) } tloc = time(NULL); if (x != SCMOK) { - notify("SUP: Upgrade of %s aborted at %s", - collrelname, ctime(&tloc) + 4); + notify(1, "Upgrade of %s aborted at %s", + collrelname, supctime(&tloc) + 4); Tfree(&lastT); if (protver < 6) return; @@ -1456,9 +1488,9 @@ finishup(int x) return; } if (thisC->Cnogood) { - notify("SUP: Upgrade of %s completed with errors at %s", - collrelname, ctime(&tloc) + 4); - notify("SUP: Upgrade time will not be updated\n"); + notify(1, "Upgrade of %s completed with errors at %s", + collrelname, supctime(&tloc) + 4); + notify(1, "Upgrade time will not be updated"); Tfree(&lastT); if (protver < 6) return; @@ -1467,9 +1499,11 @@ finishup(int x) return; } if (thisC->Cprefix) - (void) chdir(thisC->Cbase); - vnotify("SUP Upgrade of %s completed at %s", - collrelname, ctime(&tloc) + 4); + if (chdir(thisC->Cbase) < 0) + goaway("Can't chdir to %s (%s)", thisC->Cbase, + strerror(errno)); + vnotify(0, "Upgrade of %s completed at %s", + collrelname, supctime(&tloc) + 4); if (thisC->Cflags & CFLIST) { Tfree(&lastT); if (protver < 6) @@ -1491,7 +1525,7 @@ finishup(int x) } if (!putwhen(fname, scantime)) { int oerrno = errno; - notify("SUP: Can't record current time in %s (%s)\n", + notify(1, "Can't record current time in %s (%s)", fname, strerror(oerrno)); Tfree(&lastT); if (protver < 6) @@ -1510,7 +1544,7 @@ finishup(int x) (void) sprintf(tname, FILELASTTEMP, collname, relsufix); finishfile = fopen(tname, "w"); if (finishfile == NULL) { - notify("SUP: Can't record list of all files in %s\n", tname); + notify(1, "Can't record list of all files in %s", tname); Tfree(&lastT); return; } @@ -1518,7 +1552,7 @@ finishup(int x) (void) fclose(finishfile); (void) sprintf(fname, FILELAST, collname, relsufix); if (rename(tname, fname) < 0) - notify("SUP: Can't change %s to %s (%s)\n", tname, fname, + notify(1, "Can't change %s to %s (%s)", tname, fname, strerror(errno)); (void) unlink(tname); Tfree(&lastT); @@ -1529,7 +1563,7 @@ finishone(TREE * t, void *fv) { FILE *finishfile = fv; if ((thisC->Cflags & CFDELETE) == 0 || (t->Tflags & FUPDATE)) - fprintf(finishfile, "%s\n", t->Tname); + fprintf(finishfile, "%s", t->Tname); return (SCMOK); } @@ -1577,7 +1611,7 @@ goaway(const char *fmt, ...) (void) msggoaway(); if (fmt) { if (thisC) - notify("SUP: %s\n", buf); + notify(1, "%s", buf); else printf("SUP: %s\n", buf); } diff --git a/usr.sbin/sup/source/supcmisc.c b/usr.sbin/sup/source/supcmisc.c index 996e6a225766..9d2c9254cc70 100644 --- a/usr.sbin/sup/source/supcmisc.c +++ b/usr.sbin/sup/source/supcmisc.c @@ -1,4 +1,4 @@ -/* $NetBSD: supcmisc.c,v 1.22 2011/08/31 16:25:00 plunky Exp $ */ +/* $NetBSD: supcmisc.c,v 1.23 2013/03/08 20:56:44 christos Exp $ */ /* * Copyright (c) 1992 Carnegie Mellon University @@ -113,7 +113,7 @@ makedir(char *fname, unsigned int mode, struct stat * statp) if (lstat(fname, statp) != -1 && !S_ISDIR(statp->st_mode)) { if (unlink(fname) == -1) { - notify("SUP: Can't delete %s (%s)\n", fname, + notify(1, "Can't delete %s (%s)", fname, strerror(errno)); return -1; } @@ -142,7 +142,7 @@ estabd(char *fname, char *dname) return (FALSE); /* exists */ path(dname, dpart, fpart); if (strcmp(fpart, ".") == 0) { /* dname is / or . */ - notify("SUP: Can't create directory %s for %s (Invalid name)\n", + notify(1, "Can't create directory %s for %s (Invalid name)", dname, fname); errno = EINVAL; return (TRUE); @@ -152,12 +152,12 @@ estabd(char *fname, char *dname) return (TRUE); if (makedir(dname, 0755, &sbuf) < 0) { int oerrno = errno; - notify("SUP: Can't create directory %s for %s (%s)\n", dname, + notify(1, "Can't create directory %s for %s (%s)", dname, fname, strerror(errno)); errno = oerrno; return TRUE; } - vnotify("SUP Created directory %s for %s\n", dname, fname); + vnotify(0, "Created directory %s for %s", dname, fname); return (FALSE); } /*************************************** @@ -267,7 +267,7 @@ ugconvert(char *uname, char *gname, int *uid, int *gid, int *mode) *********************************************/ void -notify(const char *fmt, ...) +notify(int f, const char *fmt, ...) { /* record error message */ char buf[STRINGLENGTH]; char collrelname[STRINGLENGTH]; @@ -278,6 +278,7 @@ notify(const char *fmt, ...) int shouldMail = (thisC->Cflags & CFMAIL) && thisC->Cnotify; int needFile = shouldMail || silent; + (void)gethostname(hostname, sizeof(hostname)); va_start(ap, fmt); if ((thisC->Cflags & CFURELSUF) && thisC->Crelease) @@ -291,7 +292,6 @@ notify(const char *fmt, ...) FILE *outF; if (shouldMail) { - (void)gethostname(hostname, sizeof(hostname)); (void) snprintf(buf, sizeof(buf), "mail -s \"SUP Upgrade of %s on %s\" %s >" " /dev/null", collrelname, hostname, @@ -332,11 +332,13 @@ notify(const char *fmt, ...) } else noteF = stdout; tloc = time(NULL); - fprintf(noteF, "SUP Upgrade of %s at %s", + fprintf(noteF, "SUP@%s Upgrade of %s at %s", hostname, collrelname, ctime(&tloc)); (void) fflush(noteF); } + fprintf(noteF, "SUP@%s%s ", hostname, f ? ":" : ""); vfprintf(noteF, fmt, ap); + fprintf(noteF, "\n"); va_end(ap); (void) fflush(noteF); } @@ -363,10 +365,10 @@ char * fmttime(time_t time) { static char buf[STRINGLENGTH]; - unsigned int len; + char *p; - (void) strcpy(buf, ctime(&time)); - len = strlen(buf + 4) - 6; - buf[len] = '\0'; - return buf + 4; + (void) strcpy(buf, ctime(&time) + 4); + if ((p = strchr(buf, '\n')) != NULL) + *p = '\0'; + return buf; } diff --git a/usr.sbin/sup/source/supextern.h b/usr.sbin/sup/source/supextern.h index 3da777101c4b..b5acab231b4d 100644 --- a/usr.sbin/sup/source/supextern.h +++ b/usr.sbin/sup/source/supextern.h @@ -1,4 +1,4 @@ -/* $NetBSD: supextern.h,v 1.23 2011/09/21 19:32:59 christos Exp $ */ +/* $NetBSD: supextern.h,v 1.24 2013/03/08 20:56:44 christos Exp $ */ struct stat; @@ -143,8 +143,8 @@ int establishdir(char *); int makedir(char *, unsigned int, struct stat *); int estabd(char *, char *); void ugconvert(char *, char *, int *, int *, int *); -void notify(const char *, ...) - __attribute__((__format__(__printf__, 1, 2))); +void notify(int, const char *, ...) + __attribute__((__format__(__printf__, 2, 3))); void lockout(int); char *fmttime(time_t); diff --git a/usr.sbin/sup/source/supfilesrv.c b/usr.sbin/sup/source/supfilesrv.c index a4952324165e..0552c6914900 100644 --- a/usr.sbin/sup/source/supfilesrv.c +++ b/usr.sbin/sup/source/supfilesrv.c @@ -1,4 +1,4 @@ -/* $NetBSD: supfilesrv.c,v 1.47 2011/08/31 16:25:00 plunky Exp $ */ +/* $NetBSD: supfilesrv.c,v 1.48 2013/03/08 20:56:44 christos Exp $ */ /* * Copyright (c) 1992 Carnegie Mellon University @@ -370,6 +370,51 @@ int stat_info_ok(struct stat *, struct stat *); int link_nofollow(int); int link_nofollow(int); +struct hostpid { + char name[MAXHOSTNAMELEN]; + pid_t pid; +} *hp; + +static int +addchild(pid_t pid) +{ + size_t i; + for (i = 0; i < maxchildren; i++) + if (hp[i].pid == 0) { + hp[i].pid = pid; + strcpy(hp[i].name, remotehost()); + nchildren++; + return; + } + logerr("Out of space adding child %s", remotehost()); +} + +static void +removechild(pid_t pid) +{ + size_t i; + for (i = 0; i < maxchildren; i++) + if (hp[i].pid == pid) { + hp[i].pid = 0; + nchildren--; + return; + } + logerr("Child with pid %jd not found", (intmax_t)pid); +} + +static int +checkchild(void) +{ + const char *h = remotehost(); + size_t i; + for (i = 0; i < maxchildren; i++) + if (hp[i].pid && strcmp(hp[i].name, h) == 0) { + logerr("Ignoring connection frm %s", h); + return 0; + } + return 1; +} + /************************************* *** M A I N R O U T I N E *** *************************************/ @@ -395,8 +440,12 @@ main(int argc, char **argv) #ifdef HAS_DAEMON if (!live) /* if not debugging, turn into daemon */ - daemon(0, 0); + if (daemon(0, 0) == -1) + goaway("Daemon failed (%s)", strerror(errno)); #endif + hp = malloc(sizeof(*hp) * maxchildren); + if (hp == NULL) + goaway("Cannot allocate memory"); logopen("supfile"); tloc = time(NULL); @@ -447,7 +496,7 @@ main(int argc, char **argv) * If we are being bombarded, don't even spend time forking * or conversing */ - if (nchildren >= maxchildren + 5) { + if (nchildren >= maxchildren || !checkchild()) { (void) servicekill(); continue; } @@ -476,8 +525,10 @@ main(int argc, char **argv) exit(0); } (void) servicekill(); /* parent */ - if (pid > 0) - nchildren++; + if (pid > 0) { + addchild(pid); + setproctitle("Master [%d/%d]", nchildren, maxchildren); + } (void) sigprocmask(SIG_SETMASK, &oset, NULL); } } @@ -500,7 +551,7 @@ chldsig(int snum __unused) (intmax_t)pid); break; } - nchildren--; + removechild(pid); break; default: logerr("killing pid %jd: (%s)\n", (intmax_t) @@ -950,8 +1001,13 @@ srvsetup(void) (void) fclose(f); } x = stat(".", &sbuf); - if (prefix) - (void) chdir(basedir); + if (prefix) { + int serrno = errno; + if (chdir(basedir) < 0) + goaway("Can't chdir to %s (%s)", basedir, + strerror(errno)); + errno = serrno; + } if (x < 0) goaway("Can't stat base/prefix directory (%s)", strerror(errno)); @@ -1528,7 +1584,8 @@ srvfinishup(time_t starttime) ioctl(logfd, FIOCNOSPC, &l); } #endif /* MACH */ - (void) write(logfd, tmpbuf, (p - tmpbuf)); + if (write(logfd, tmpbuf, (p - tmpbuf)) == -1) + logerr("%s: write failed (%s)", remotehost(), strerror(errno)); (void) close(logfd); } /*************************************************** @@ -1565,7 +1622,7 @@ Hinsert(HASH ** table, int num1, int num2, char *name, TREE * tree) HASH *h; int hno; hno = HASHFUNC(num1, num2); - h = (HASH *) malloc(sizeof(HASH)); + h = malloc(sizeof(*h)); if (h == NULL) goaway("Cannot allocate memory"); h->Hnum1 = num1; @@ -1825,10 +1882,10 @@ fmttime(time_t time) static char buf[STRINGLENGTH]; unsigned int len; - (void) strcpy(buf, ctime(&time)); - len = strlen(buf + 4) - 6; - (void) strncpy(buf, buf + 4, len); - buf[len] = '\0'; + (void) strcpy(buf, ctime(&time) + 4); + len = strlen(buf); + if (len > 2) + buf[len - 2] = '\0'; return (buf); } /* diff --git a/usr.sbin/sup/source/supscan.c b/usr.sbin/sup/source/supscan.c index b6c50707f1ed..2952c6291bfe 100644 --- a/usr.sbin/sup/source/supscan.c +++ b/usr.sbin/sup/source/supscan.c @@ -1,4 +1,4 @@ -/* $NetBSD: supscan.c,v 1.22 2012/04/25 22:35:00 martin Exp $ */ +/* $NetBSD: supscan.c,v 1.23 2013/03/08 20:56:44 christos Exp $ */ /* * Copyright (c) 1992 Carnegie Mellon University @@ -195,7 +195,11 @@ main(int argc, char **argv) collname = c->Cname; basedir = c->Cbase; prefix = c->Cprefix; - (void) chdir(basedir); + if (chdir(basedir) < 0) { + fprintf(stderr, "supscan: Can't chdir to %s (%s)", + basedir, strerror(errno)); + return 1; + } scantime = time(NULL); if (!quiet) printf("SUP Scan for %s starting at %s", collname,