diff options
author | Ted Unangst <tedu@cvs.openbsd.org> | 2014-07-10 14:26:17 +0000 |
---|---|---|
committer | Ted Unangst <tedu@cvs.openbsd.org> | 2014-07-10 14:26:17 +0000 |
commit | 73b3f24907775fefb7f5c4b0a1f81f3045136d71 (patch) | |
tree | f7b166138b17e864c88f4ec3a0eb9fd806294f67 /usr.bin | |
parent | b0be8b9a780ed8e79ebc40e2b09e90de8607a1e6 (diff) |
Snakes. Why'd it have to be snakes?
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/oldrdist/Makefile | 16 | ||||
-rw-r--r-- | usr.bin/oldrdist/defs.h | 179 | ||||
-rw-r--r-- | usr.bin/oldrdist/docmd.c | 668 | ||||
-rw-r--r-- | usr.bin/oldrdist/expand.c | 666 | ||||
-rw-r--r-- | usr.bin/oldrdist/gram.y | 495 | ||||
-rw-r--r-- | usr.bin/oldrdist/lookup.c | 161 | ||||
-rw-r--r-- | usr.bin/oldrdist/main.c | 296 | ||||
-rw-r--r-- | usr.bin/oldrdist/oldrdist.1 | 460 | ||||
-rw-r--r-- | usr.bin/oldrdist/pathnames.h | 35 | ||||
-rw-r--r-- | usr.bin/oldrdist/server.c | 1592 |
10 files changed, 0 insertions, 4568 deletions
diff --git a/usr.bin/oldrdist/Makefile b/usr.bin/oldrdist/Makefile deleted file mode 100644 index e82932c2bbb..00000000000 --- a/usr.bin/oldrdist/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# $OpenBSD: Makefile,v 1.6 1997/04/27 20:56:51 millert Exp $ - -PROG= rdist -CFLAGS+=-I${.CURDIR} -SRCS= docmd.c expand.c lookup.c main.c server.c -OBJS+= gram.o -BINOWN= root -BINMODE=555 -CLEANFILES=y.tab.h -MAN= oldrdist.1 - -realinstall: - ${INSTALL} ${INSTALL_COPY} ${INSTALL_STRIP} -o ${BINOWN} -g ${BINGRP} \ - -m ${BINMODE} ${PROG} ${DESTDIR}${BINDIR}/oldrdist - -.include <bsd.prog.mk> diff --git a/usr.bin/oldrdist/defs.h b/usr.bin/oldrdist/defs.h deleted file mode 100644 index 3793b07d3db..00000000000 --- a/usr.bin/oldrdist/defs.h +++ /dev/null @@ -1,179 +0,0 @@ -/* * $OpenBSD: defs.h,v 1.13 2013/06/02 06:20:35 guenther Exp $*/ -/* - * Copyright (c) 1983, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)defs.h 8.1 (Berkeley) 6/9/93 - */ - -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/time.h> - -#include <netinet/in.h> - -#include <errno.h> -#include <dirent.h> -#include <fcntl.h> -#include <pwd.h> -#include <grp.h> -#include <stdio.h> -#include <ctype.h> -#include <unistd.h> -#include <string.h> -#include <stdlib.h> -#include "pathnames.h" - -/* - * The version number should be changed whenever the protocol changes. - */ -#define VERSION 3 - - /* defines for yacc */ -#define EQUAL 1 -#define LP 2 -#define RP 3 -#define SM 4 -#define ARROW 5 -#define COLON 6 -#define DCOLON 7 -#define NAME 8 -#define STRING 9 -#define INSTALL 10 -#define NOTIFY 11 -#define EXCEPT 12 -#define PATTERN 13 -#define SPECIAL 14 -#define OPTION 15 - - /* lexical definitions */ -#define QUOTE 0200 /* used internally for quoted characters */ -#define TRIM 0177 /* Mask to strip quote bit */ - - /* table sizes */ -#define HASHSIZE 1021 -#define INMAX 3500 - - /* option flags */ -#define VERIFY 0x1 -#define WHOLE 0x2 -#define YOUNGER 0x4 -#define COMPARE 0x8 -#define REMOVE 0x10 -#define FOLLOW 0x20 -#define IGNLNKS 0x40 - - /* expand type definitions */ -#define E_VARS 0x1 -#define E_SHELL 0x2 -#define E_TILDE 0x4 -#define E_ALL 0x7 - - /* actions for lookup() */ -#define LOOKUP 0 -#define INSERT 1 -#define REPLACE 2 - -#define ISDIR(m) (((m) & S_IFMT) == S_IFDIR) - -#define ALLOC(x) (struct x *) malloc(sizeof(struct x)) - -struct namelist { /* for making lists of strings */ - char *n_name; - struct namelist *n_next; -}; - -struct subcmd { - short sc_type; /* type - INSTALL,NOTIFY,EXCEPT,SPECIAL */ - short sc_options; - char *sc_name; - struct namelist *sc_args; - struct subcmd *sc_next; -}; - -struct cmd { - int c_type; /* type - ARROW,DCOLON */ - char *c_name; /* hostname or time stamp file name */ - char *c_label; /* label for partial update */ - struct namelist *c_files; - struct subcmd *c_cmds; - struct cmd *c_next; -}; - -struct linkbuf { - ino_t inum; - dev_t devnum; - int count; - char pathname[BUFSIZ]; - char src[BUFSIZ]; - char target[BUFSIZ]; - struct linkbuf *nextp; -}; - -extern int debug; /* debugging flag */ -extern int nflag; /* NOP flag, don't execute commands */ -extern int qflag; /* Quiet. don't print messages */ -extern int options; /* global options */ - -extern int nerrs; /* number of errors seen */ -extern int rem; /* remote file descriptor */ -extern int iamremote; /* acting as remote server */ -extern char tempfile[]; /* file name for logging changes */ -extern struct linkbuf *ihead; /* list of files with more than one link */ -extern struct passwd *pw; /* pointer to static area used by getpwent */ -extern struct group *gr; /* pointer to static area used by getgrent */ -extern char host[]; /* host name of master copy */ -extern char buf[BUFSIZ]; /* general purpose buffer */ -extern char target[BUFSIZ]; /* target/source directory name */ - -int any(int, char *); -char *colon(char *); -void cleanup(int); -void define(char *); -void docmds(char **, int, char **); -void error(const char *, ...); -int except(char *); -struct namelist * - expand(struct namelist *, int); -char *exptilde(char [], char *, int); -void fatal(const char *, ...); -int inlist(struct namelist *, char *); -void insert(char *, struct namelist *, struct namelist *, struct subcmd *); -void install(char *, char *, int, int); -void logit(FILE *, const char *, ...); -struct namelist * - lookup(char *, int, struct namelist *); -void lostconn(int); -struct namelist * - makenl(char *); -struct subcmd * - makesubcmd(int); -void prnames(struct namelist *); -void server(void); -void yyerror(char *); -int yyparse(void); -char *xbasename(char *); diff --git a/usr.bin/oldrdist/docmd.c b/usr.bin/oldrdist/docmd.c deleted file mode 100644 index 5825bc2d665..00000000000 --- a/usr.bin/oldrdist/docmd.c +++ /dev/null @@ -1,668 +0,0 @@ -/* $OpenBSD: docmd.c,v 1.23 2013/06/02 06:20:35 guenther Exp $ */ - -/* - * Copyright (c) 1983, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "defs.h" -#include <setjmp.h> -#include <netdb.h> -#include <regex.h> - -FILE *lfp; /* log file for recording files updated */ -struct subcmd *subcmds; /* list of sub-commands for current cmd */ -jmp_buf env; - -static int makeconn(char *); -static int okname(char *); -static void closeconn(void); -static void cmptime(char *); -static void doarrow(char **, struct namelist *, char *, struct subcmd *); -static void dodcolon(char **, struct namelist *, char *, struct subcmd *); -static void notify(char *, char *, struct namelist *, time_t); -static void rcmptime(struct stat *); - -/* - * Do the commands in cmds (initialized by yyparse). - */ -void -docmds(dhosts, argc, argv) - char **dhosts; - int argc; - char **argv; -{ - struct cmd *c; - struct namelist *f; - char **cpp; - extern struct cmd *cmds; - - signal(SIGHUP, cleanup); - signal(SIGINT, cleanup); - signal(SIGQUIT, cleanup); - signal(SIGTERM, cleanup); - - for (c = cmds; c != NULL; c = c->c_next) { - if (dhosts != NULL && *dhosts != NULL) { - for (cpp = dhosts; *cpp; cpp++) - if (strcmp(c->c_name, *cpp) == 0) - goto fndhost; - continue; - } - fndhost: - if (argc) { - for (cpp = argv; *cpp; cpp++) { - if (c->c_label != NULL && - strcmp(c->c_label, *cpp) == 0) { - cpp = NULL; - goto found; - } - for (f = c->c_files; f != NULL; f = f->n_next) - if (strcmp(f->n_name, *cpp) == 0) - goto found; - } - continue; - } else - cpp = NULL; - found: - switch (c->c_type) { - case ARROW: - doarrow(cpp, c->c_files, c->c_name, c->c_cmds); - break; - case DCOLON: - dodcolon(cpp, c->c_files, c->c_name, c->c_cmds); - break; - default: - fatal("illegal command type %d\n", c->c_type); - } - } - closeconn(); -} - -/* - * Process commands for sending files to other machines. - */ -static void -doarrow(filev, files, rhost, cmds) - char **filev; - struct namelist *files; - char *rhost; - struct subcmd *cmds; -{ - struct namelist *f; - struct subcmd *sc; - char **cpp; - int n, ddir, opts = options; - - if (debug) - printf("doarrow(%lx, %s, %lx)\n", (long)files, rhost, (long)cmds); - - if (files == NULL) { - error("no files to be updated\n"); - return; - } - - subcmds = cmds; - ddir = files->n_next != NULL; /* destination is a directory */ - if (nflag) - printf("updating host %s\n", rhost); - else { - int fd; - - if (setjmp(env)) - goto done; - signal(SIGPIPE, lostconn); - if (!makeconn(rhost)) - return; - if ((fd = open(tempfile, O_CREAT|O_EXCL|O_WRONLY, 0600)) < 0 || - (lfp = fdopen(fd, "w")) == NULL) { - if (fd >= 0) - (void) close(fd); - fatal("cannot open %s\n", tempfile); - exit(1); - } - } - for (f = files; f != NULL; f = f->n_next) { - if (filev) { - for (cpp = filev; *cpp; cpp++) - if (strcmp(f->n_name, *cpp) == 0) - goto found; - if (!nflag && lfp) { - (void) fclose(lfp); - lfp = NULL; - } - continue; - } - found: - n = 0; - for (sc = cmds; sc != NULL; sc = sc->sc_next) { - if (sc->sc_type != INSTALL) - continue; - n++; - install(f->n_name, sc->sc_name, - sc->sc_name == NULL ? 0 : ddir, sc->sc_options); - opts = sc->sc_options; - } - if (n == 0) - install(f->n_name, NULL, 0, options); - } -done: - if (!nflag) { - (void) signal(SIGPIPE, cleanup); - if (lfp) - (void) fclose(lfp); - lfp = NULL; - } - for (sc = cmds; sc != NULL; sc = sc->sc_next) - if (sc->sc_type == NOTIFY) - notify(tempfile, rhost, sc->sc_args, 0); - if (!nflag) { - struct linkbuf *nextihead; - - (void) unlink(tempfile); - for (; ihead != NULL; ihead = nextihead) { - nextihead = ihead->nextp; - if ((opts & IGNLNKS) || ihead->count == 0) - continue; - logit(lfp, "%s: Warning: missing links\n", - ihead->pathname); - free(ihead); - } - } -} - -/* - * Create a connection to the rdist server on the machine rhost. - */ -static int -makeconn(rhost) - char *rhost; -{ - char *ruser, *cp; - static char *cur_host = NULL; -#if defined(DIRECT_RCMD) - static int port = -1; -#endif /* DIRECT_RCMD */ - char tuser[20]; - int n; - extern char user[]; -#if defined(DIRECT_RCMD) - extern uid_t userid; -#endif - - if (debug) - printf("makeconn(%s)\n", rhost); - - if (cur_host != NULL && rem >= 0) { - if (strcmp(cur_host, rhost) == 0) - return(1); - closeconn(); - } - cur_host = rhost; - cp = strchr(rhost, '@'); - if (cp != NULL) { - char c = *cp; - - *cp = '\0'; - strncpy(tuser, rhost, sizeof(tuser)-1); - *cp = c; - rhost = cp + 1; - ruser = tuser; - if (*ruser == '\0') - ruser = user; - else if (!okname(ruser)) - return(0); - } else - ruser = user; - if (!qflag) - printf("updating host %s\n", rhost); - (void) snprintf(buf, sizeof(buf), "%s -Server%s", _PATH_RDIST, - qflag ? " -q" : ""); -#if defined(DIRECT_RCMD) - if (port < 0) { - struct servent *sp; - - if ((sp = getservbyname("shell", "tcp")) == NULL) - fatal("shell/tcp: unknown service"); - port = sp->s_port; - } -#endif /* !DIRECT_RCMD */ - - if (debug) { -#if defined(DIRECT_RCMD) - printf("port = %d, luser = %s, ruser = %s\n", ntohs(port), user, ruser); -#else /* !DIRECT_RCMD */ - printf("luser = %s, ruser = %s\n", user, ruser); -#endif /* !DIRECT_RCMD */ - printf("buf = %s\n", buf); - } - - fflush(stdout); -#if defined(DIRECT_RCMD) - seteuid(0); - rem = rcmd(&rhost, port, user, ruser, buf, 0); - seteuid(userid); -#else /* !DIRECT_RCMD */ - rem = rcmdsh(&rhost, -1, user, ruser, buf, NULL); -#endif /* !DIRECT_RCMD */ - if (rem < 0) - return(0); - cp = buf; - if (read(rem, cp, 1) != 1) - lostconn(0); - if (*cp == 'V') { - do { - if (read(rem, cp, 1) != 1) - lostconn(0); - } while (*cp++ != '\n' && cp < &buf[BUFSIZ]); - *--cp = '\0'; - cp = buf; - n = 0; - while (*cp >= '0' && *cp <= '9') - n = (n * 10) + (*cp++ - '0'); - if (*cp == '\0' && n == VERSION) - return(1); - error("connection failed: version numbers don't match (local %d, remote %d)\n", VERSION, n); - } else { - error("connection failed: version numbers don't match\n"); - error("got unexpected input:"); - do { - error("%c", *cp); - } while (*cp != '\n' && read(rem, cp, 1) == 1); - } - closeconn(); - return(0); -} - -/* - * Signal end of previous connection. - */ -static void -closeconn() -{ - if (debug) - printf("closeconn()\n"); - - if (rem >= 0) { - void (*osig)(); - osig = signal(SIGPIPE, SIG_IGN); - (void) write(rem, "\2\n", 2); - (void) signal(SIGPIPE, osig); - (void) close(rem); - rem = -1; - } -} - -void -lostconn(signo) - int signo; -{ - if (iamremote) - cleanup(0); - logit(lfp, "rdist: lost connection\n"); - if (rem >= 0) { - (void) close(rem); - rem = -1; - } - longjmp(env, 1); -} - -static int -okname(name) - char *name; -{ - char *cp = name; - int c; - - do { - c = *cp; - if (c & 0200) - goto bad; - if (!isalpha(c) && !isdigit(c) && c != '_' && c != '-') - goto bad; - cp++; - } while (*cp); - return(1); -bad: - error("invalid user name %s\n", name); - return(0); -} - -time_t lastmod; -FILE *tfp; -extern char *tp; - -/* - * Process commands for comparing files to time stamp files. - */ -static void -dodcolon(filev, files, stamp, cmds) - char **filev; - struct namelist *files; - char *stamp; - struct subcmd *cmds; -{ - struct subcmd *sc; - struct namelist *f; - char **cpp; - struct timeval tv[2]; - struct stat stb; - - if (debug) - printf("dodcolon()\n"); - - if (files == NULL) { - error("no files to be updated\n"); - return; - } - if (stat(stamp, &stb) < 0) { - error("%s: %s\n", stamp, strerror(errno)); - return; - } - if (debug) - printf("%s: %lld\n", stamp, (long long)stb.st_mtime); - - subcmds = cmds; - lastmod = stb.st_mtime; - if (nflag || (options & VERIFY)) - tfp = NULL; - else { - int fd; - - if ((fd = open(tempfile, O_CREAT|O_EXCL|O_WRONLY, 0600)) < 0 || - (tfp = fdopen(fd, "w")) == NULL) { - error("%s: %s\n", tempfile, strerror(errno)); - if (fd >= 0) - (void) close(fd); - return; - } - (void) gettimeofday(&tv[0], NULL); - tv[1] = tv[0]; - (void) utimes(stamp, tv); - } - - for (f = files; f != NULL; f = f->n_next) { - if (filev) { - for (cpp = filev; *cpp; cpp++) - if (strcmp(f->n_name, *cpp) == 0) - goto found; - continue; - } - found: - tp = NULL; - cmptime(f->n_name); - } - - if (tfp != NULL) - (void) fclose(tfp); - for (sc = cmds; sc != NULL; sc = sc->sc_next) - if (sc->sc_type == NOTIFY) - notify(tempfile, NULL, sc->sc_args, lastmod); - if (!nflag && !(options & VERIFY)) - (void) unlink(tempfile); -} - -/* - * Compare the mtime of file to the list of time stamps. - */ -static void -cmptime(name) - char *name; -{ - struct stat stb; - - if (debug) - printf("cmptime(%s)\n", name); - - if (except(name)) - return; - - if (nflag) { - printf("comparing dates: %s\n", name); - return; - } - - /* - * first time cmptime() is called? - */ - if (tp == NULL) { - if (exptilde(target, name, sizeof (target)) == NULL) - return; - tp = name = target; - while (*tp) - tp++; - } - if (access(name, 4) < 0 || stat(name, &stb) < 0) { - error("%s: %s\n", name, strerror(errno)); - return; - } - - switch (stb.st_mode & S_IFMT) { - case S_IFREG: - break; - - case S_IFDIR: - rcmptime(&stb); - return; - - default: - error("%s: not a plain file\n", name); - return; - } - - if (stb.st_mtime > lastmod) - logit(tfp, "new: %s\n", name); -} - -static void -rcmptime(st) - struct stat *st; -{ - DIR *d; - struct dirent *dp; - char *cp; - char *otp; - int len; - - if (debug) - printf("rcmptime(%lx)\n", (long)st); - - if ((d = opendir(target)) == NULL) { - error("%s: %s\n", target, strerror(errno)); - return; - } - otp = tp; - len = tp - target; - while (dp = readdir(d)) { - if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) - continue; - if (len + 1 + strlen(dp->d_name) >= BUFSIZ - 1) { - error("%s/%s: Name too long\n", target, dp->d_name); - continue; - } - tp = otp; - *tp++ = '/'; - cp = dp->d_name; - while (*tp++ = *cp++) - ; - tp--; - cmptime(target); - } - closedir(d); - tp = otp; - *tp = '\0'; -} - -/* - * Notify the list of people the changes that were made. - * rhost == NULL if we are mailing a list of changes compared to at time - * stamp file. - */ -static void -notify(file, rhost, to, lmod) - char *file, *rhost; - struct namelist *to; - time_t lmod; -{ - int fd, len; - struct stat stb; - FILE *pf; - - if ((options & VERIFY) || to == NULL) - return; - if (!qflag) { - printf("notify "); - if (rhost) - printf("@%s ", rhost); - prnames(to); - } - if (nflag) - return; - - if ((fd = open(file, O_RDONLY)) < 0) { - error("%s: %s\n", file, strerror(errno)); - return; - } - if (fstat(fd, &stb) < 0) { - error("%s: %s\n", file, strerror(errno)); - (void) close(fd); - return; - } - if (stb.st_size == 0) { - (void) close(fd); - return; - } - /* - * Create a pipe to a mail program. - */ - (void) snprintf(buf, sizeof(buf), "%s -oi -t", _PATH_SENDMAIL); - pf = popen(buf, "w"); - if (pf == NULL) { - error("notify: \"%s\" failed\n", _PATH_SENDMAIL); - (void) close(fd); - return; - } - /* - * Output the proper header information. - */ - fprintf(pf, "Auto-Submitted: auto-generated\n"); - fprintf(pf, "From: rdist (Remote distribution program)\n"); - fprintf(pf, "To:"); - if (!any('@', to->n_name) && rhost != NULL) - fprintf(pf, " %s@%s", to->n_name, rhost); - else - fprintf(pf, " %s", to->n_name); - to = to->n_next; - while (to != NULL) { - if (!any('@', to->n_name) && rhost != NULL) - fprintf(pf, ", %s@%s", to->n_name, rhost); - else - fprintf(pf, ", %s", to->n_name); - to = to->n_next; - } - putc('\n', pf); - if (rhost != NULL) - fprintf(pf, "Subject: files updated by rdist from %s to %s\n", - host, rhost); - else - fprintf(pf, "Subject: files updated after %s\n", ctime(&lmod)); - putc('\n', pf); - - while ((len = read(fd, buf, BUFSIZ)) > 0) - (void) fwrite(buf, 1, len, pf); - (void) close(fd); - (void) pclose(pf); -} - -/* - * Return true if name is in the list. - */ -int -inlist(list, file) - struct namelist *list; - char *file; -{ - struct namelist *nl; - - for (nl = list; nl != NULL; nl = nl->n_next) - if (!strcmp(file, nl->n_name)) - return(1); - return(0); -} - -/* - * Return TRUE if file is in the exception list. - */ -int -except(file) - char *file; -{ - struct subcmd *sc; - struct namelist *nl; - regex_t s; - int err; - - if (debug) - printf("except(%s)\n", file); - - for (sc = subcmds; sc != NULL; sc = sc->sc_next) { - if (sc->sc_type != EXCEPT && sc->sc_type != PATTERN) - continue; - for (nl = sc->sc_args; nl != NULL; nl = nl->n_next) { - if (sc->sc_type == EXCEPT) { - if (!strcmp(file, nl->n_name)) - return(1); - continue; - } - if ((err = regcomp(&s, nl->n_name, 0)) != 0) { - (void) regerror(err, &s, buf, sizeof(buf)); - error("%s: %s\n", nl->n_name, buf); - } - if (regexec(&s, file, 0, NULL, 0) == 0) { - regfree(&s); - return(1); - } - regfree(&s); - } - } - return(0); -} - -char * -colon(cp) - char *cp; -{ - - while (*cp) { - if (*cp == ':') - return(cp); - if (*cp == '/') - return(0); - cp++; - } - return(0); -} diff --git a/usr.bin/oldrdist/expand.c b/usr.bin/oldrdist/expand.c deleted file mode 100644 index 0acdf757aea..00000000000 --- a/usr.bin/oldrdist/expand.c +++ /dev/null @@ -1,666 +0,0 @@ -/* $OpenBSD: expand.c,v 1.15 2013/06/02 06:20:35 guenther Exp $ */ - -/* - * Copyright (c) 1983, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "defs.h" - -#define GAVSIZ NCARGS / 6 -#define LC '{' -#define RC '}' - -static char shchars[] = "${[*?"; - -int which; /* bit mask of types to expand */ -int eargc; /* expanded arg count */ -char **eargv; /* expanded arg vectors */ -char pathbuf[BUFSIZ]; -char *path; -char *pathp; -char *lastpathp; -char *tilde; /* "~user" if not expanding tilde, else "" */ -char *tpathp; -int nleft; - -int expany; /* any expansions done? */ -char *entp; -char **sortbase; - -#define sort() qsort((char *)sortbase, &eargv[eargc] - sortbase, \ - sizeof(*sortbase), argcmp), sortbase = &eargv[eargc] - -static void Cat(char *, char *); -static void addpath(int); -static int amatch(char *, char *); -static int argcmp(const void *, const void *); -static int execbrc(char *, char *); -static void expsh(char *); -static void expstr(char *); -static int match(char *, char *); -static void matchdir(char *); -static int smatch(char *, char *); - -/* - * Take a list of names and expand any macros, etc. - * wh = E_VARS if expanding variables. - * wh = E_SHELL if expanding shell characters. - * wh = E_TILDE if expanding `~'. - * or any of these or'ed together. - * - * Major portions of this were snarfed from csh/sh.glob.c. - */ -struct namelist * -expand(list, wh) - struct namelist *list; - int wh; -{ - struct namelist *nl, *prev; - int n; - char *argvbuf[GAVSIZ]; - - if (debug) { - printf("expand(%lx, %d)\nlist = ", (long)list, wh); - prnames(list); - } - - if (wh == 0) { - char *cp; - - for (nl = list; nl != NULL; nl = nl->n_next) - for (cp = nl->n_name; *cp; cp++) - *cp = *cp & TRIM; - return(list); - } - - which = wh; - path = tpathp = pathp = pathbuf; - *pathp = '\0'; - lastpathp = &path[sizeof pathbuf - 2]; - tilde = ""; - eargc = 0; - eargv = sortbase = argvbuf; - *eargv = 0; - nleft = NCARGS - 4; - /* - * Walk the name list and expand names into eargv[]; - */ - for (nl = list; nl != NULL; nl = nl->n_next) - expstr(nl->n_name); - /* - * Take expanded list of names from eargv[] and build a new list. - */ - list = prev = NULL; - for (n = 0; n < eargc; n++) { - nl = makenl(NULL); - nl->n_name = eargv[n]; - if (prev == NULL) - list = prev = nl; - else { - prev->n_next = nl; - prev = nl; - } - } - if (debug) { - printf("expanded list = "); - prnames(list); - } - return(list); -} - -static void -expstr(s) - char *s; -{ - char *cp, *cp1; - struct namelist *tp; - char *tail; - char buf[BUFSIZ]; - int savec, oeargc; - extern char homedir[]; - - if (s == NULL || *s == '\0') - return; - - if ((which & E_VARS) && (cp = strchr(s, '$')) != NULL) { - *cp++ = '\0'; - if (*cp == '\0') { - yyerror("no variable name after '$'"); - return; - } - if (*cp == LC) { - cp++; - if ((tail = strchr(cp, RC)) == NULL) { - yyerror("unmatched '{'"); - return; - } - *tail++ = savec = '\0'; - if (*cp == '\0') { - yyerror("no variable name after '$'"); - return; - } - } else { - tail = cp + 1; - savec = *tail; - *tail = '\0'; - } - tp = lookup(cp, LOOKUP, 0); - if (savec != '\0') - *tail = savec; - if (tp != NULL) { - for (; tp != NULL; tp = tp->n_next) { - snprintf(buf, sizeof(buf), "%s%s%s", s, - tp->n_name, tail); - expstr(buf); - } - return; - } - snprintf(buf, sizeof(buf), "%s%s", s, tail); - expstr(buf); - return; - } - if ((which & ~E_VARS) == 0 || !strcmp(s, "{") || !strcmp(s, "{}")) { - Cat(s, ""); - sort(); - return; - } - if (*s == '~') { - cp = ++s; - if (*cp == '\0' || *cp == '/') { - tilde = "~"; - cp1 = homedir; - } else { - tilde = cp1 = buf; - *cp1++ = '~'; - do - *cp1++ = *cp++; - while (*cp && *cp != '/'); - *cp1 = '\0'; - if (pw == NULL || strcmp(pw->pw_name, buf+1) != 0) { - if ((pw = getpwnam(buf+1)) == NULL) { - strlcat(buf, ": unknown user name", - sizeof buf); - yyerror(buf+1); - return; - } - } - cp1 = pw->pw_dir; - s = cp; - } - for (cp = path; *cp++ = *cp1++; ) - ; - tpathp = pathp = cp - 1; - } else { - tpathp = pathp = path; - tilde = ""; - } - *pathp = '\0'; - if (!(which & E_SHELL)) { - if (which & E_TILDE) - Cat(path, s); - else - Cat(tilde, s); - sort(); - return; - } - oeargc = eargc; - expany = 0; - expsh(s); - if (eargc == oeargc) - Cat(s, ""); /* "nonomatch" is set */ - sort(); -} - -static int -argcmp(a1, a2) - const void *a1, *a2; -{ - - return (strcmp(*(char **)a1, *(char **)a2)); -} - -/* - * If there are any Shell meta characters in the name, - * expand into a list, after searching directory - */ -static void -expsh(s) - char *s; -{ - char *cp; - char *spathp, *oldcp; - struct stat stb; - - spathp = pathp; - cp = s; - while (!any(*cp, shchars)) { - if (*cp == '\0') { - if (!expany || stat(path, &stb) >= 0) { - if (which & E_TILDE) - Cat(path, ""); - else - Cat(tilde, tpathp); - } - goto endit; - } - addpath(*cp++); - } - oldcp = cp; - while (cp > s && *cp != '/') - cp--, pathp--; - if (*cp == '/') - cp++, pathp++; - *pathp = '\0'; - if (*oldcp == '{') { - execbrc(cp, NULL); - return; - } - matchdir(cp); -endit: - pathp = spathp; - *pathp = '\0'; -} - -static void -matchdir(pattern) - char *pattern; -{ - struct stat stb; - struct dirent *dp; - DIR *dirp; - - dirp = opendir(path); - if (dirp == NULL) { - if (expany) - return; - goto patherr2; - } - if (fstat(dirfd(dirp), &stb) < 0) - goto patherr1; - if (!ISDIR(stb.st_mode)) { - errno = ENOTDIR; - goto patherr1; - } - while ((dp = readdir(dirp)) != NULL) - if (match(dp->d_name, pattern)) { - if (which & E_TILDE) - Cat(path, dp->d_name); - else { - strlcpy(pathp, dp->d_name, - pathbuf + sizeof pathbuf - pathp); - Cat(tilde, tpathp); - *pathp = '\0'; - } - } - closedir(dirp); - return; - -patherr1: - closedir(dirp); -patherr2: - strlcat(path, ": ", pathbuf + sizeof pathbuf - path); - strlcat(path, strerror(errno), pathbuf + sizeof pathbuf - path); - yyerror(path); -} - -static int -execbrc(p, s) - char *p, *s; -{ - char restbuf[BUFSIZ + 2]; - char *pe, *pm, *pl; - int brclev = 0; - char *lm, savec, *spathp; - - for (lm = restbuf; *p != '{'; *lm++ = *p++) - continue; - for (pe = ++p; *pe; pe++) - switch (*pe) { - - case '{': - brclev++; - continue; - - case '}': - if (brclev == 0) - goto pend; - brclev--; - continue; - - case '[': - for (pe++; *pe && *pe != ']'; pe++) - continue; - if (!*pe) - yyerror("Missing ']'"); - continue; - } -pend: - if (brclev || !*pe) { - yyerror("Missing '}'"); - return (0); - } - for (pl = pm = p; pm <= pe; pm++) - switch (*pm & (QUOTE|TRIM)) { - - case '{': - brclev++; - continue; - - case '}': - if (brclev) { - brclev--; - continue; - } - goto doit; - - case ',': - if (brclev) - continue; -doit: - savec = *pm; - *pm = 0; - strlcpy(lm, pl, restbuf + sizeof restbuf - lm); - strlcat(restbuf, pe + 1, sizeof restbuf); - *pm = savec; - if (s == 0) { - spathp = pathp; - expsh(restbuf); - pathp = spathp; - *pathp = 0; - } else if (amatch(s, restbuf)) - return (1); - sort(); - pl = pm + 1; - continue; - - case '[': - for (pm++; *pm && *pm != ']'; pm++) - continue; - if (!*pm) - yyerror("Missing ']'"); - continue; - } - return (0); -} - -static int -match(s, p) - char *s, *p; -{ - int c; - char *sentp; - char sexpany = expany; - - if (*s == '.' && *p != '.') - return (0); - sentp = entp; - entp = s; - c = amatch(s, p); - entp = sentp; - expany = sexpany; - return (c); -} - -static int -amatch(s, p) - char *s, *p; -{ - int scc; - int ok, lc; - char *spathp; - struct stat stb; - int c, cc; - - expany = 1; - for (;;) { - scc = *s++ & TRIM; - switch (c = *p++) { - - case '{': - return (execbrc(p - 1, s - 1)); - - case '[': - ok = 0; - lc = 077777; - while (cc = *p++) { - if (cc == ']') { - if (ok) - break; - return (0); - } - if (cc == '-') { - if (lc <= scc && scc <= *p++) - ok++; - } else - if (scc == (lc = cc)) - ok++; - } - if (cc == 0) { - yyerror("Missing ']'"); - return (0); - } - continue; - - case '*': - if (!*p) - return (1); - if (*p == '/') { - p++; - goto slash; - } - for (s--; *s; s++) - if (amatch(s, p)) - return (1); - return (0); - - case '\0': - return (scc == '\0'); - - default: - if ((c & TRIM) != scc) - return (0); - continue; - - case '?': - if (scc == '\0') - return (0); - continue; - - case '/': - if (scc) - return (0); -slash: - s = entp; - spathp = pathp; - while (*s) - addpath(*s++); - addpath('/'); - if (stat(path, &stb) == 0 && ISDIR(stb.st_mode)) - if (*p == '\0') { - if (which & E_TILDE) - Cat(path, ""); - else - Cat(tilde, tpathp); - } else - expsh(p); - pathp = spathp; - *pathp = '\0'; - return (0); - } - } -} - -static int -smatch(s, p) - char *s, *p; -{ - int scc; - int ok, lc; - int c, cc; - - for (;;) { - scc = *s++ & TRIM; - switch (c = *p++) { - - case '[': - ok = 0; - lc = 077777; - while (cc = *p++) { - if (cc == ']') { - if (ok) - break; - return (0); - } - if (cc == '-') { - if (lc <= scc && scc <= *p++) - ok++; - } else - if (scc == (lc = cc)) - ok++; - } - if (cc == 0) { - yyerror("Missing ']'"); - return (0); - } - continue; - - case '*': - if (!*p) - return (1); - for (s--; *s; s++) - if (smatch(s, p)) - return (1); - return (0); - - case '\0': - return (scc == '\0'); - - default: - if ((c & TRIM) != scc) - return (0); - continue; - - case '?': - if (scc == 0) - return (0); - continue; - - } - } -} - -static void -Cat(s1, s2) - char *s1, *s2; -{ - int len = strlen(s1) + strlen(s2) + 1; - char *s; - - nleft -= len; - if (nleft <= 0 || ++eargc >= GAVSIZ) - yyerror("Arguments too long"); - eargv[eargc] = 0; - eargv[eargc - 1] = s = malloc(len); - if (s == NULL) - fatal("ran out of memory\n"); - while (*s++ = *s1++ & TRIM) - ; - s--; - while (*s++ = *s2++ & TRIM) - ; -} - -static void -addpath(c) - int c; -{ - - if (pathp >= lastpathp) - yyerror("Pathname too long"); - else { - *pathp++ = c & TRIM; - *pathp = '\0'; - } -} - -/* - * Expand file names beginning with `~' into the - * user's home directory path name. Return a pointer in buf to the - * part corresponding to `file'. - */ -char * -exptilde(buf, file, maxlen) - char buf[]; - char *file; - int maxlen; -{ - char *s1, *s2, *s3; - extern char homedir[]; - - if (*file != '~') { - strlcpy(buf, file, maxlen); - return(buf); - } - if (*++file == '\0') { - s2 = homedir; - s3 = NULL; - } else if (*file == '/') { - s2 = homedir; - s3 = file; - } else { - s3 = file; - while (*s3 && *s3 != '/') - s3++; - if (*s3 == '/') - *s3 = '\0'; - else - s3 = NULL; - if (pw == NULL || strcmp(pw->pw_name, file) != 0) { - if ((pw = getpwnam(file)) == NULL) { - error("%s: unknown user name\n", file); - if (s3 != NULL) - *s3 = '/'; - return(NULL); - } - } - if (s3 != NULL) - *s3 = '/'; - s2 = pw->pw_dir; - } - for (s1 = buf; (*s1++ = *s2++) && s1 < buf+maxlen; ) - ; - s2 = --s1; - if (s3 != NULL && s1 < buf+maxlen) { - s2++; - while ((*s1++ = *s3++) && s1 < buf+maxlen) - ; - } - if (s1 == buf+maxlen) - return (NULL); - return(s2); -} diff --git a/usr.bin/oldrdist/gram.y b/usr.bin/oldrdist/gram.y deleted file mode 100644 index 3b1f83adbdb..00000000000 --- a/usr.bin/oldrdist/gram.y +++ /dev/null @@ -1,495 +0,0 @@ -%{ -/* - * Copyright (c) 1983, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "defs.h" - -struct cmd *cmds = NULL; -struct cmd *last_cmd; -struct namelist *last_n; -struct subcmd *last_sc; - -static char *makestr(char *); - -%} - -%term EQUAL 1 -%term LP 2 -%term RP 3 -%term SM 4 -%term ARROW 5 -%term COLON 6 -%term DCOLON 7 -%term NAME 8 -%term STRING 9 -%term INSTALL 10 -%term NOTIFY 11 -%term EXCEPT 12 -%term PATTERN 13 -%term SPECIAL 14 -%term OPTION 15 - -%union { - int intval; - char *string; - struct subcmd *subcmd; - struct namelist *namel; -} - -%type <intval> OPTION, options -%type <string> NAME, STRING -%type <subcmd> INSTALL, NOTIFY, EXCEPT, PATTERN, SPECIAL, cmdlist, cmd -%type <namel> namelist, names, opt_namelist - -%% - -file: /* VOID */ - | file command - ; - -command: NAME EQUAL namelist = { - (void) lookup($1, INSERT, $3); - } - | namelist ARROW namelist cmdlist = { - insert(NULL, $1, $3, $4); - } - | NAME COLON namelist ARROW namelist cmdlist = { - insert($1, $3, $5, $6); - } - | namelist DCOLON NAME cmdlist = { - append(NULL, $1, $3, $4); - } - | NAME COLON namelist DCOLON NAME cmdlist = { - append($1, $3, $5, $6); - } - | error - ; - -namelist: NAME = { - $$ = makenl($1); - } - | LP names RP = { - $$ = $2; - } - ; - -names: /* VOID */ { - $$ = last_n = NULL; - } - | names NAME = { - if (last_n == NULL) - $$ = last_n = makenl($2); - else { - last_n->n_next = makenl($2); - last_n = last_n->n_next; - $$ = $1; - } - } - ; - -cmdlist: /* VOID */ { - $$ = last_sc = NULL; - } - | cmdlist cmd = { - if (last_sc == NULL) - $$ = last_sc = $2; - else { - last_sc->sc_next = $2; - last_sc = $2; - $$ = $1; - } - } - ; - -cmd: INSTALL options opt_namelist SM = { - register struct namelist *nl; - - $1->sc_options = $2 | options; - if ($3 != NULL) { - nl = expand($3, E_VARS); - if (nl) { - if (nl->n_next != NULL) - yyerror("only one name allowed\n"); - $1->sc_name = nl->n_name; - free(nl); - } else - $1->sc_name = NULL; - } - $$ = $1; - } - | NOTIFY namelist SM = { - if ($2 != NULL) - $1->sc_args = expand($2, E_VARS); - $$ = $1; - } - | EXCEPT namelist SM = { - if ($2 != NULL) - $1->sc_args = expand($2, E_ALL); - $$ = $1; - } - | PATTERN namelist SM = { - if ($2 != NULL) - $1->sc_args = expand($2, E_VARS); - $$ = $1; - } - | SPECIAL opt_namelist STRING SM = { - if ($2 != NULL) - $1->sc_args = expand($2, E_ALL); - $1->sc_name = $3; - $$ = $1; - } - ; - -options: /* VOID */ = { - $$ = 0; - } - | options OPTION = { - $$ |= $2; - } - ; - -opt_namelist: /* VOID */ = { - $$ = NULL; - } - | namelist = { - $$ = $1; - } - ; - -%% - -int yylineno = 1; -extern FILE *fin; - -int -yylex() -{ - static char yytext[INMAX]; - register int c; - register char *cp1, *cp2; - static char quotechars[] = "[]{}*?$"; - -again: - switch (c = getc(fin)) { - case EOF: /* end of file */ - return(0); - - case '#': /* start of comment */ - while ((c = getc(fin)) != EOF && c != '\n') - ; - if (c == EOF) - return(0); - case '\n': - yylineno++; - case ' ': - case '\t': /* skip blanks */ - goto again; - - case '=': /* EQUAL */ - return(EQUAL); - - case '(': /* LP */ - return(LP); - - case ')': /* RP */ - return(RP); - - case ';': /* SM */ - return(SM); - - case '-': /* -> */ - if ((c = getc(fin)) == '>') - return(ARROW); - ungetc(c, fin); - c = '-'; - break; - - case '"': /* STRING */ - cp1 = yytext; - cp2 = &yytext[INMAX - 1]; - for (;;) { - if (cp1 >= cp2) { - yyerror("command string too long\n"); - break; - } - c = getc(fin); - if (c == EOF || c == '"') - break; - if (c == '\\') { - if ((c = getc(fin)) == EOF) { - *cp1++ = '\\'; - break; - } - } - if (c == '\n') { - yylineno++; - c = ' '; /* can't send '\n' */ - } - *cp1++ = c; - } - if (c != '"') - yyerror("missing closing '\"'\n"); - *cp1 = '\0'; - yylval.string = makestr(yytext); - return(STRING); - - case ':': /* : or :: */ - if ((c = getc(fin)) == ':') - return(DCOLON); - ungetc(c, fin); - return(COLON); - } - cp1 = yytext; - cp2 = &yytext[INMAX - 1]; - for (;;) { - if (cp1 >= cp2) { - yyerror("input line too long\n"); - break; - } - if (c == '\\') { - if ((c = getc(fin)) != EOF) { - if (any(c, quotechars)) - c |= QUOTE; - } else { - *cp1++ = '\\'; - break; - } - } - *cp1++ = c; - c = getc(fin); - if (c == EOF || any(c, " \"'\t()=;:\n")) { - ungetc(c, fin); - break; - } - } - *cp1 = '\0'; - if (yytext[0] == '-' && yytext[2] == '\0') { - switch (yytext[1]) { - case 'b': - yylval.intval = COMPARE; - return(OPTION); - - case 'R': - yylval.intval = REMOVE; - return(OPTION); - - case 'v': - yylval.intval = VERIFY; - return(OPTION); - - case 'w': - yylval.intval = WHOLE; - return(OPTION); - - case 'y': - yylval.intval = YOUNGER; - return(OPTION); - - case 'h': - yylval.intval = FOLLOW; - return(OPTION); - - case 'i': - yylval.intval = IGNLNKS; - return(OPTION); - } - } - if (!strcmp(yytext, "install")) - c = INSTALL; - else if (!strcmp(yytext, "notify")) - c = NOTIFY; - else if (!strcmp(yytext, "except")) - c = EXCEPT; - else if (!strcmp(yytext, "except_pat")) - c = PATTERN; - else if (!strcmp(yytext, "special")) - c = SPECIAL; - else { - yylval.string = makestr(yytext); - return(NAME); - } - yylval.subcmd = makesubcmd(c); - return(c); -} - -int -any(c, str) - register int c; - register char *str; -{ - while (*str) - if (c == *str++) - return(1); - return(0); -} - -/* - * Insert or append ARROW command to list of hosts to be updated. - */ -void -insert(label, files, hosts, subcmds) - char *label; - struct namelist *files, *hosts; - struct subcmd *subcmds; -{ - register struct cmd *c, *prev, *nc; - register struct namelist *h, *nexth; - - files = expand(files, E_VARS|E_SHELL); - hosts = expand(hosts, E_ALL); - for (h = hosts; h != NULL; nexth = h->n_next, free(h), h = nexth) { - /* - * Search command list for an update to the same host. - */ - for (prev = NULL, c = cmds; c!=NULL; prev = c, c = c->c_next) { - if (strcmp(c->c_name, h->n_name) == 0) { - do { - prev = c; - c = c->c_next; - } while (c != NULL && - strcmp(c->c_name, h->n_name) == 0); - break; - } - } - /* - * Insert new command to update host. - */ - nc = ALLOC(cmd); - if (nc == NULL) - fatal("ran out of memory\n"); - nc->c_type = ARROW; - nc->c_name = h->n_name; - nc->c_label = label; - nc->c_files = files; - nc->c_cmds = subcmds; - nc->c_next = c; - if (prev == NULL) - cmds = nc; - else - prev->c_next = nc; - /* update last_cmd if appending nc to cmds */ - if (c == NULL) - last_cmd = nc; - } -} - -/* - * Append DCOLON command to the end of the command list since these are always - * executed in the order they appear in the distfile. - */ -void -append(label, files, stamp, subcmds) - char *label; - struct namelist *files; - char *stamp; - struct subcmd *subcmds; -{ - register struct cmd *c; - - c = ALLOC(cmd); - if (c == NULL) - fatal("ran out of memory\n"); - c->c_type = DCOLON; - c->c_name = stamp; - c->c_label = label; - c->c_files = expand(files, E_ALL); - c->c_cmds = subcmds; - c->c_next = NULL; - if (cmds == NULL) - cmds = last_cmd = c; - else { - last_cmd->c_next = c; - last_cmd = c; - } -} - -/* - * Error printing routine in parser. - */ -void -yyerror(s) - char *s; -{ - ++nerrs; - fflush(stdout); - fprintf(stderr, "rdist: line %d: %s\n", yylineno, s); -} - -/* - * Return a copy of the string. - */ -static char * -makestr(str) - char *str; -{ - register char *cp, *s; - - str = cp = malloc(strlen(s = str) + 1); - if (cp == NULL) - fatal("ran out of memory\n"); - while (*cp++ = *s++) - ; - return(str); -} - -/* - * Allocate a namelist structure. - */ -struct namelist * -makenl(name) - char *name; -{ - register struct namelist *nl; - - nl = ALLOC(namelist); - if (nl == NULL) - fatal("ran out of memory\n"); - nl->n_name = name; - nl->n_next = NULL; - return(nl); -} - -/* - * Make a sub command for lists of variables, commands, etc. - */ -struct subcmd * -makesubcmd(type) - int type; -{ - register struct subcmd *sc; - - sc = ALLOC(subcmd); - if (sc == NULL) - fatal("ran out of memory\n"); - sc->sc_type = type; - sc->sc_args = NULL; - sc->sc_next = NULL; - sc->sc_name = NULL; - return(sc); -} diff --git a/usr.bin/oldrdist/lookup.c b/usr.bin/oldrdist/lookup.c deleted file mode 100644 index 82ae7379cc9..00000000000 --- a/usr.bin/oldrdist/lookup.c +++ /dev/null @@ -1,161 +0,0 @@ -/* $OpenBSD: lookup.c,v 1.10 2009/10/27 23:59:41 deraadt Exp $ */ - -/* - * Copyright (c) 1983, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "defs.h" - - /* symbol types */ -#define VAR 1 -#define CONST 2 - -struct syment { - int s_type; - char *s_name; - struct namelist *s_value; - struct syment *s_next; -}; - -static struct syment *hashtab[HASHSIZE]; - -/* - * Define a variable from a command line argument. - */ -void -define(name) - char *name; -{ - char *cp, *s; - struct namelist *nl; - struct namelist *value; - - if (debug) - printf("define(%s)\n", name); - - cp = strchr(name, '='); - if (cp == NULL) - value = NULL; - else if (cp[1] == '\0') { - *cp = '\0'; - value = NULL; - } else if (cp[1] != '(') { - *cp++ = '\0'; - value = makenl(cp); - } else { - nl = NULL; - *cp++ = '\0'; - do - cp++; - while (*cp == ' ' || *cp == '\t'); - for (s = cp; ; s++) { - switch (*s) { - case ')': - *s = '\0'; - case '\0': - break; - case ' ': - case '\t': - *s++ = '\0'; - while (*s == ' ' || *s == '\t') - s++; - if (*s == ')') - *s = '\0'; - break; - default: - continue; - } - if (nl == NULL) - value = nl = makenl(cp); - else { - nl->n_next = makenl(cp); - nl = nl->n_next; - } - if (*s == '\0') - break; - cp = s; - } - } - (void) lookup(name, REPLACE, value); -} - -/* - * Lookup name in the table and return a pointer to it. - * LOOKUP - just do lookup, return NULL if not found. - * INSERT - insert name with value, error if already defined. - * REPLACE - insert or replace name with value. - */ - -struct namelist * -lookup(name, action, value) - char *name; - int action; - struct namelist *value; -{ - unsigned int n; - char *cp; - struct syment *s; - char buf[BUFSIZ]; - - if (debug) - printf("lookup(%s, %d, %p)\n", name, action, value); - - n = 0; - for (cp = name; *cp; ) - n += *cp++; - n %= HASHSIZE; - - for (s = hashtab[n]; s != NULL; s = s->s_next) { - if (strcmp(name, s->s_name)) - continue; - if (action != LOOKUP) { - if (action != INSERT || s->s_type != CONST) { - (void)snprintf(buf, sizeof(buf), - "%s redefined", name); - yyerror(buf); - } - } - return(s->s_value); - } - - if (action == LOOKUP) { - (void)snprintf(buf, sizeof(buf), "%s undefined", name); - yyerror(buf); - return(NULL); - } - - s = ALLOC(syment); - if (s == NULL) - fatal("ran out of memory\n"); - s->s_next = hashtab[n]; - hashtab[n] = s; - s->s_type = action == INSERT ? VAR : CONST; - s->s_name = name; - s->s_value = value; - return(value); -} diff --git a/usr.bin/oldrdist/main.c b/usr.bin/oldrdist/main.c deleted file mode 100644 index 3b1a0a972c3..00000000000 --- a/usr.bin/oldrdist/main.c +++ /dev/null @@ -1,296 +0,0 @@ -/* $OpenBSD: main.c,v 1.22 2012/02/24 06:19:00 guenther Exp $ */ - -/* - * Copyright (c) 1983, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <stdarg.h> -#include <libgen.h> -#include "defs.h" - -#define NHOSTS 100 - -/* - * Remote distribution program. - */ - -char *distfile = NULL; -#define _RDIST_TMP "rdistXXXXXXXXXX" -char tempfile[sizeof _PATH_TMP + sizeof _RDIST_TMP - 1]; -char *tempname; - -int debug; /* debugging flag */ -int nflag; /* NOP flag, just print commands without executing */ -int qflag; /* Quiet. Don't print messages */ -int options; /* global options */ -int iamremote; /* act as remote server for transferring files */ - -FILE *fin = NULL; /* input file pointer */ -int rem = -1; /* file descriptor to remote source/sink process */ -char host[MAXHOSTNAMELEN]; /* host name */ -int nerrs; /* number of errors while sending/receiving */ -char user[MAXLOGNAME]; /* user's name */ -char homedir[MAXPATHLEN]; /* user's home directory */ -uid_t userid; /* user's user ID */ -gid_t groupid; /* user's group ID */ - -struct passwd *pw; /* pointer to static area used by getpwent */ -struct group *gr; /* pointer to static area used by getgrent */ - -static void usage(void); -static void docmdargs(int, char *[]); - -int -main(argc, argv) - int argc; - char *argv[]; -{ - char *arg; - int cmdargs = 0; - char *dhosts[NHOSTS], **hp = dhosts; - - pw = getpwuid(userid = getuid()); - if (pw == NULL) { - fprintf(stderr, "%s: Who are you?\n", argv[0]); - exit(1); - } - strlcpy(user, pw->pw_name, sizeof user); - strlcpy(homedir, pw->pw_dir, sizeof homedir); - groupid = pw->pw_gid; - gethostname(host, sizeof(host)); - strlcpy(tempfile, _PATH_TMP, sizeof tempfile); - strlcat(tempfile, _RDIST_TMP, sizeof tempfile); - tempname = basename(tempfile); - - while (--argc > 0) { - if ((arg = *++argv)[0] != '-') - break; - if (!strcmp(arg, "-Server")) - iamremote++; - else while (*++arg) - switch (*arg) { - case 'f': - if (--argc <= 0) - usage(); - distfile = *++argv; - if (distfile[0] == '-' && distfile[1] == '\0') - fin = stdin; - break; - - case 'm': - if (--argc <= 0) - usage(); - if (hp >= &dhosts[NHOSTS-2]) { - fprintf(stderr, "rdist: too many destination hosts\n"); - exit(1); - } - *hp++ = *++argv; - break; - - case 'd': - if (--argc <= 0) - usage(); - define(*++argv); - break; - - case 'D': - debug++; - break; - - case 'c': - cmdargs++; - break; - - case 'n': - if (options & VERIFY) { - printf("rdist: -n overrides -v\n"); - options &= ~VERIFY; - } - nflag++; - break; - - case 'q': - qflag++; - break; - - case 'b': - options |= COMPARE; - break; - - case 'R': - options |= REMOVE; - break; - - case 'v': - if (nflag) { - printf("rdist: -n overrides -v\n"); - break; - } - options |= VERIFY; - break; - - case 'w': - options |= WHOLE; - break; - - case 'y': - options |= YOUNGER; - break; - - case 'h': - options |= FOLLOW; - break; - - case 'i': - options |= IGNLNKS; - break; - - default: - usage(); - } - } - *hp = NULL; - -#if defined(DIRECT_RCMD) - seteuid(userid); -#else /* DIRECT_RCMD */ - if (!iamremote && getuid() != geteuid()) { - error("This version of rdist should not be installed setuid.\n"); - exit(1); - } -#endif /* DIRECT_RCMD */ - - if (mktemp(tempfile) == NULL) - fatal("cannot get temp file\n"); - - if (iamremote) { - server(); - exit(nerrs != 0); - } - - if (cmdargs) - docmdargs(argc, argv); - else { - if (fin == NULL) { - if (distfile == NULL) { - if ((fin = fopen("distfile","r")) == NULL) - fin = fopen("Distfile", "r"); - } else - fin = fopen(distfile, "r"); - if (fin == NULL) { - perror(distfile ? distfile : "distfile"); - exit(1); - } - } - yyparse(); - if (nerrs == 0) - docmds(dhosts, argc, argv); - } - - exit(nerrs != 0); -} - -static void -usage() -{ - printf( - "usage: rdist [-bhinqRvwy] [-d var=value] [-f distfile] [-m host] [name ...]\n" - " rdist [-bhinqRvwy] -c name ... [login@]host[:dest]\n"); - exit(1); -} - -/* - * rcp like interface for distributing files. - */ -static void -docmdargs(nargs, args) - int nargs; - char *args[]; -{ - struct namelist *nl, *prev; - char *cp; - struct namelist *files, *hosts; - struct subcmd *cmds; - char *dest; - static struct namelist tnl = { NULL, NULL }; - int i; - - if (nargs < 2) - usage(); - - prev = NULL; - for (i = 0; i < nargs - 1; i++) { - nl = makenl(args[i]); - if (prev == NULL) - files = prev = nl; - else { - prev->n_next = nl; - prev = nl; - } - } - - cp = args[i]; - if ((dest = strchr(cp, ':')) != NULL) - *dest++ = '\0'; - tnl.n_name = cp; - hosts = expand(&tnl, E_ALL); - if (nerrs) - exit(1); - - if (dest == NULL || *dest == '\0') - cmds = NULL; - else { - cmds = makesubcmd(INSTALL); - cmds->sc_options = options; - cmds->sc_name = dest; - } - - if (debug) { - printf("docmdargs()\nfiles = "); - prnames(files); - printf("hosts = "); - prnames(hosts); - } - insert(NULL, files, hosts, cmds); - docmds(NULL, 0, NULL); -} - -/* - * Print a list of NAME blocks (mostly for debugging). - */ -void -prnames(nl) - struct namelist *nl; -{ - printf("( "); - while (nl != NULL) { - printf("%s ", nl->n_name); - nl = nl->n_next; - } - printf(")\n"); -} diff --git a/usr.bin/oldrdist/oldrdist.1 b/usr.bin/oldrdist/oldrdist.1 deleted file mode 100644 index 98f551a609f..00000000000 --- a/usr.bin/oldrdist/oldrdist.1 +++ /dev/null @@ -1,460 +0,0 @@ -.\" $OpenBSD: oldrdist.1,v 1.21 2013/07/16 06:48:36 jmc Exp $ -.\" -.\" Copyright (c) 1985, 1990, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" from: @(#)rdist.1 8.2 (Berkeley) 12/30/93 -.\" -.Dd $Mdocdate: July 16 2013 $ -.Dt OLDRDIST 1 -.Os -.Sh NAME -.Nm oldrdist -.Nd remote file distribution program -.Sh SYNOPSIS -.Nm oldrdist -.Op Fl bhinqRvwy -.Op Fl d Ar var=value -.Op Fl f Ar distfile -.Op Fl m Ar host -.Op Ar name ... -.Nm oldrdist -.Op Fl bhinqRvwy -.Fl c -.Ar name ... -.Oo login@ Oc Ns Ar host Ns Op :dest -.Sh DESCRIPTION -.Nm -is a program to maintain identical copies of files over multiple hosts. -It preserves the owner, group, mode, and mtime of files if possible and -can update programs that are executing. -.Nm -reads commands from -.Ar distfile -to direct the updating of files and/or directories. -.Pp -Options specific to the first SYNOPSIS form: -.Bl -tag -width "-f distfile" -.It Fl f Ar distfile -Use the specified -.Ar distfile . -If -.Ar distfile -is -.Sq - , -the standard input is used. -.El -.Pp -If the -.Fl f -option is not specified, the program looks first for -.Dq Pa distfile , -then -.Dq Pa Distfile -to use as the input. -If no names are specified on the command line, -.Nm -will update all of the files and directories listed in -.Ar distfile . -Otherwise, the argument is taken to be the name of a file to be updated -or the label of a command to execute. -If label and file names conflict, it is assumed to be a label. -These may be used together to update specific files -using specific commands. -.Pp -Options specific to the second SYNOPSIS form: -.Bl -tag -width "Fl c" -.It Fl c -Forces -.Nm -to interpret the remaining arguments as a small -.Ar distfile . -.Pp -The equivalent distfile is as follows: -.Bd -filled -offset indent -.Pq Ar name ... -.Li -> -.Op Ar login@ -.Ar host -.Ed -.Bd -filled -offset indent-two -compact -.Li install -.Op Ar dest ; -.Ed -.El -.Pp -Options common to both forms: -.Bl -tag -width "Fl b" -.It Fl b -Binary comparison. -Perform a binary comparison and update files if they differ -rather than comparing dates and sizes. -.It Fl d Ar var=value -Define -.Ar var -to have -.Ar value . -The -.Fl d -option is used to define or override variable definitions in the -.Ar distfile . -.Ar Value -can be the empty string, one name, or a list of names surrounded by -parentheses and separated by tabs and/or spaces. -.It Fl h -Follow symbolic links. -Copy the file that the link points to rather than the link itself. -.It Fl i -Ignore unresolved links. -.Nm -will normally try to maintain the link structure of files being transferred -and warn the user if all the links cannot be found. -.It Fl m Ar host -Limit which machines are to be updated. -Multiple -.Fl m -arguments can be given to limit updates to a subset of the hosts listed in the -.Ar distfile . -.It Fl n -Print the commands without executing them. -This option is useful for debugging -.Ar distfile . -.It Fl q -Quiet mode. -Files that are being modified are normally printed on standard output. -The -.Fl q -option suppresses this. -.It Fl R -Remove extraneous files. -If a directory is being updated, any files that exist -on the remote host that do not exist in the master directory are removed. -This is useful for maintaining truly identical copies of directories. -.It Fl v -Verify that the files are up to date on all the hosts. -Any files -that are out of date will be displayed but no files will be changed -nor any mail sent. -.It Fl w -Whole mode. -The whole file name is appended to the destination directory -name. -Normally, only the last component of a name is used when renaming files. -This will preserve the directory structure of the files being -copied instead of flattening the directory structure. -For example, -renaming a list of files such as ( dir1/f1 dir2/f2 ) to dir3 would create -files dir3/dir1/f1 and dir3/dir2/f2 instead of dir3/f1 and dir3/f2. -.It Fl y -Younger mode. -Files are normally updated if their -.Ar mtime -and -.Ar size -(see -.Xr stat 2 ) -disagree. -The -.Fl y -option causes -.Nm -not to update files that are younger than the master copy. -This can be used -to prevent newer copies on other hosts from being replaced. -A warning message is printed for files which are newer than the master copy. -.El -.Pp -.Ar distfile -contains a sequence of entries that specify the files -to be copied, the destination hosts, and what operations to perform -to do the updating. -Each entry has one of the following formats: -.Bd -literal -offset indent -<variable name> `=' <name list> -[label:]<source list> `\->' <destination list> <command list> -[label:]<source list> `::' <time_stamp file> <command list> -.Ed -.Pp -The first format is used for defining variables. -The second format is used for distributing files to other hosts. -The third format is used for making lists of files that have been changed -since some given date. -The -.Ar source list -specifies a -list of files and/or directories on the local host which are to be used -as the master copy for distribution. -The -.Ar destination list -is the list of hosts to which these files are to be -copied. -Each file in the source list is added to a list of changes -if the file is out of date on the host which is being updated (second format) or -the file is newer than the time stamp file (third format). -.Pp -Labels are optional. -They are used to identify a command for partial updates. -.Pp -Newlines, tabs, and blanks are only used as separators and are -otherwise ignored. -Comments begin with -.Ql # -and end with a newline. -.Pp -Variables to be expanded begin with -.Ql $ -followed by one character or -a name enclosed in curly braces (see the examples at the end). -.Pp -The source and destination lists have the following format: -.Bd -literal -offset indent -<name> -.Ed -or -.Bd -literal -offset indent -compact -`(' <zero or more names separated by whitespace> `)' -.Ed -.Pp -The shell meta-characters -.Ql \&[ , -.Ql \&] , -.Ql { , -.Ql } , -.Ql * , -and -.Ql \&? -are recognized and expanded (on the local host only) in the same way as -.Xr csh 1 . -They can be escaped with a backslash. -The -.Ql ~ -character is also expanded in the same way as -.Xr csh 1 -but is expanded separately on the local and destination hosts. -When the -.Fl w -option is used with a file name that begins with -.Ql ~ , -everything except the -home directory is appended to the destination name. -File names which do not begin with -.Ql / -or -.Ql ~ -use the destination user's -home directory as the root directory for the rest of the file name. -.Pp -The command list consists of zero or more commands of the following -format: -.Bl -column "`except_pat'" "<pattern list>" "opt_dest_name" "`;'" -offset indent -.It `install' Ta "<options>" Ta opt_dest_name Ta `;' -.It `notify' Ta "<name list>" Ta "" Ta `;' -.It `except' Ta "<name list>" Ta "" Ta `;' -.It `except_pat' Ta "<pattern list>" Ta "" Ta `;' -.It `special' Ta "<name list>" Ta string Ta `;' -.El -.Pp -The -.Ic install -command is used to copy out of date files and/or directories. -Each source file is copied to each host in the destination list. -Directories are recursively copied in the same way. -.Ar opt_dest_name -is an optional parameter to rename files. -If no -.Ic install -command appears in the command list or -the destination name is not specified, -the source file name is used. -Directories in the path name will be created if they -do not exist on the remote host. -.Pp -To help prevent disasters, a non-empty directory on a target host will -never be replaced with a regular file or a symbolic link. -However, under the -.Fl R -option a non-empty directory will be removed -if the corresponding filename is completely absent on the master host. -The -.Ar options -are -.Fl R , -.Fl h , -.Fl i , -.Fl v , -.Fl w , -.Fl y , -and -.Fl b -and have the same semantics as -options on the command line except they only apply to the files -in the source list. -The login name used on the destination host is the same as the local host -unless the destination name is of the format -.Dq login@host . -.Pp -The -.Ic notify -command is used to mail the list of files updated (and any errors -that may have occurred) to the listed names. -If no -.Ql @ -appears in the name, the destination host is appended to the name -(e.g., name1@host, name2@host, ...). -.Pp -The -.Ic except -command is used to update all of the files in the source list except -for the files listed in -.Ar name list . -This is usually used to copy everything in a directory except certain files. -.Pp -The -.Ic except_pat -command is like the -.Ic except -command except that -.Ar pattern list -is a list of regular expressions -(see -.Xr ed 1 -for details). -If one of the patterns matches some string within a file name, that file will -be ignored. -Note that since -.Ql \e -is a quote character, it must be doubled to become -part of the regular expression. -Variables are expanded in -.Ar pattern list -but not shell file pattern matching characters. -To include a -.Ql $ , -it must be escaped with -.Ql \e . -.Pp -The -.Ic special -command is used to specify -.Xr sh 1 -commands that are to be executed on the -remote host after the file in -.Ar name list -is updated or installed. -If the -.Ar name list -is omitted then the shell commands will be executed -for every file updated or installed. -The shell variable FILE is set -to the current filename before executing the commands in -.Ar string . -.Ar string -starts and ends with -.Ql \&" -and can cross multiple lines in -.Ar distfile . -Multiple commands to the shell should be separated by -.Ql \&; . -Commands are executed in the user's home directory on the host -being updated. -The -.Ar special -command can be used to rebuild private databases, etc. -after a program has been updated. -.Pp -The following is a small example: -.Bd -literal -offset indent -HOSTS = ( matisse root@arpa ) - -FILES = ( /bin /lib /usr/bin /usr/games -\t/usr/include/{*.h,{stand,sys,vax*,pascal,machine}/*.h} -\t/usr/lib /usr/man/man? /usr/ucb /usr/local/rdist ) - -EXLIB = ( Mail.rc aliases aliases.dir aliases.pag crontab dshrc -\tsendmail.cf sendmail.fc sendmail.hf sendmail.st uucp vfont ) - -${FILES} -> ${HOSTS} -\tinstall -R ; -\texcept /usr/lib/${EXLIB} ; -\texcept /usr/games/lib ; -\tspecial /usr/lib/sendmail "/usr/lib/sendmail -bz" ; - -srcs: -/usr/src/bin -> arpa -\texcept_pat ( \e\e.o\e$ /SCCS\e$ ) ; - -IMAGEN = (ips dviimp catdvi) - -imagen: -/usr/local/${IMAGEN} -> arpa -\tinstall /usr/local/lib ; -\tnotify ralph ; - -${FILES} :: stamp.cory -\tnotify root@cory ; -.Ed -.Sh FILES -.Bl -tag -width /tmp/rdist* -compact -.It Pa distfile -input command file -.It Pa /tmp/rdist* -temporary file for update lists -.El -.Sh DIAGNOSTICS -A complaint about mismatch of -.Nm -version numbers may really stem -from some problem with starting your shell, e.g., you are in too many groups. -.Sh SEE ALSO -.Xr csh 1 , -.Xr sh 1 , -.Xr stat 2 -.Sh HISTORY -The -.Nm -command appeared in -.Bx 4.3 . -.Sh BUGS -Source files must reside on the local host where -.Nm -is executed. -.Pp -There is no easy way to have a special command executed after all files -in a directory have been updated. -.Pp -Variable expansion only works for name lists; there should be a general macro -facility. -.Pp -.Nm -aborts on files which have a negative mtime (before Jan 1, 1970). -.Pp -There should be a -.Dq force -option to allow replacement of non-empty directories -by regular files or symlinks. -A means of updating file modes and owners -of otherwise identical files is also needed. diff --git a/usr.bin/oldrdist/pathnames.h b/usr.bin/oldrdist/pathnames.h deleted file mode 100644 index d1c032aa915..00000000000 --- a/usr.bin/oldrdist/pathnames.h +++ /dev/null @@ -1,35 +0,0 @@ -/* * $OpenBSD: pathnames.h,v 1.5 2003/06/03 02:56:14 millert Exp $*/ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)pathnames.h 8.1 (Berkeley) 6/9/93 - */ - -#include <paths.h> - -#define _PATH_RDIST "rdist" diff --git a/usr.bin/oldrdist/server.c b/usr.bin/oldrdist/server.c deleted file mode 100644 index 2ace4222d39..00000000000 --- a/usr.bin/oldrdist/server.c +++ /dev/null @@ -1,1592 +0,0 @@ -/* $OpenBSD: server.c,v 1.34 2013/06/02 06:20:35 guenther Exp $ */ - -/* - * Copyright (c) 1983, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/wait.h> - -#include <stdarg.h> -#include <libgen.h> - -#include "defs.h" - -#define ack() (void) write(rem, "\0\n", 2) -#define err() (void) write(rem, "\1\n", 2) - -struct linkbuf *ihead; /* list of files with more than one link */ -char buf[BUFSIZ]; /* general purpose buffer */ -char target[BUFSIZ]; /* target/source directory name */ -char source[BUFSIZ]; /* source directory name */ -char *tp; /* pointer to end of target name */ -char *Tdest; /* pointer to last T dest*/ -int catname; /* cat name to target name */ -char *stp[32]; /* stack of saved tp's for directories */ -int oumask; /* old umask for creating files */ - -extern FILE *lfp; /* log file for mailing changes */ - -static int chkparent(char *); -static void clean(char *); -static void comment(char *); -static void dospecial(char *); -static int fchog(int, char *, char *, char *, int); -static void hardlink(char *); -static void note(const char *, ...); -static void query(char *); -static void recvf(char *, int); -static void removeit(struct stat *); -static int response(void); -static void rmchk(int); -static struct linkbuf * - savelink(struct stat *); -static void sendf(char *, int); -static int update(char *, int, struct stat *); - -/* - * Server routine to read requests and process them. - * Commands are: - * Tname - Transmit file if out of date - * Vname - Verify if file out of date or not - * Qname - Query if file exists. Return mtime & size if it does. - */ -void -server() -{ - char cmdbuf[BUFSIZ]; - char *cp; - - signal(SIGHUP, cleanup); - signal(SIGINT, cleanup); - signal(SIGQUIT, cleanup); - signal(SIGTERM, cleanup); - signal(SIGPIPE, cleanup); - - rem = 0; - oumask = umask(0); - (void) snprintf(buf, sizeof(buf), "V%d\n", VERSION); - (void) write(rem, buf, strlen(buf)); - -#if !defined(DIRECT_RCMD) - if (getuid() != geteuid()) { - error("This version of rdist should not be installed setuid.\n"); - return; - } -#endif /* DIRECT_RCMD */ - - for (;;) { - cp = cmdbuf; - if (read(rem, cp, 1) <= 0) - return; - if (*cp++ == '\n') { - error("server: expected control record\n"); - continue; - } - do { - if (read(rem, cp, 1) != 1) - cleanup(0); - } while (*cp++ != '\n' && cp < &cmdbuf[BUFSIZ]); - *--cp = '\0'; - cp = cmdbuf; - switch (*cp++) { - case 'T': /* init target file/directory name */ - catname = 1; /* target should be directory */ - goto dotarget; - - case 't': /* init target file/directory name */ - catname = 0; - dotarget: - if (exptilde(target, cp, sizeof (target)) == NULL) - continue; - tp = target; - while (*tp) - tp++; - ack(); - continue; - - case 'R': /* Transfer a regular file. */ - recvf(cp, S_IFREG); - continue; - - case 'D': /* Transfer a directory. */ - recvf(cp, S_IFDIR); - continue; - - case 'K': /* Transfer symbolic link. */ - recvf(cp, S_IFLNK); - continue; - - case 'k': /* Transfer hard link. */ - hardlink(cp); - continue; - - case 'E': /* End. (of directory) */ - *tp = '\0'; - if (catname <= 0) { - error("server: too many 'E's\n"); - continue; - } - tp = stp[--catname]; - *tp = '\0'; - ack(); - continue; - - case 'C': /* Clean. Cleanup a directory */ - clean(cp); - continue; - - case 'Q': /* Query. Does the file/directory exist? */ - query(cp); - continue; - - case 'S': /* Special. Execute commands */ - dospecial(cp); - continue; - -#ifdef notdef - /* - * These entries are reserved but not currently used. - * The intent is to allow remote hosts to have master copies. - * Currently, only the host rdist runs on can have masters. - */ - case 'X': /* start a new list of files to exclude */ - except = bp = NULL; - case 'x': /* add name to list of files to exclude */ - if (*cp == '\0') { - ack(); - continue; - } - if (*cp == '~') { - if (exptilde(buf, cp, sizeof (buf)) == NULL) - continue; - cp = buf; - } - if (bp == NULL) - except = bp = expand(makeblock(NAME, cp), E_VARS); - else - bp->b_next = expand(makeblock(NAME, cp), E_VARS); - while (bp->b_next != NULL) - bp = bp->b_next; - ack(); - continue; - - case 'I': /* Install. Transfer file if out of date. */ - opts = 0; - while (*cp >= '0' && *cp <= '7') - opts = (opts << 3) | (*cp++ - '0'); - if (*cp++ != ' ') { - error("server: options not delimited\n"); - return; - } - install(cp, opts); - continue; - - case 'L': /* Log. save message in log file */ - logit(lfp, "%s", cp); - continue; -#endif - - case '\1': - nerrs++; - continue; - - case '\2': - return; - - default: - error("server: unknown command '%s'\n", cp); - case '\0': - continue; - } - } -} - -/* - * Update the file(s) if they are different. - * destdir = 1 if destination should be a directory - * (i.e., more than one source is being copied to the same destination). - */ -void -install(src, dest, destdir, opts) - char *src, *dest; - int destdir, opts; -{ - char *rname; - char destcopy[BUFSIZ]; - - if (opts & WHOLE) - source[0] = '\0'; - else - strlcpy(source, src, sizeof source); - - if (dest == NULL) { - opts &= ~WHOLE; /* WHOLE mode only useful if renaming */ - dest = src; - } - - if (nflag || debug) { - printf("%s%s%s%s%s %s %s\n", opts & VERIFY ? "verify":"install", - opts & WHOLE ? " -w" : "", - opts & YOUNGER ? " -y" : "", - opts & COMPARE ? " -b" : "", - opts & REMOVE ? " -R" : "", src, dest); - if (nflag) - return; - } - - rname = exptilde(target, src, sizeof(target)); - if (rname == NULL) - return; - tp = target; - while (*tp) - tp++; - /* - * If we are renaming a directory and we want to preserve - * the directory hierarchy (-w), we must strip off the leading - * directory name and preserve the rest. - */ - if (opts & WHOLE) { - while (*rname == '/') - rname++; - destdir = 1; - } else { - rname = basename(target); - } - if (debug) - printf("target = %s, rname = %s\n", target, rname); - /* - * Pass the destination file/directory name to remote. - */ - (void) snprintf(buf, sizeof(buf), "%c%s\n", destdir ? 'T' : 't', dest); - if (debug) - printf("buf = %s", buf); - (void) write(rem, buf, strlen(buf)); - if (response() < 0) - return; - - /* - * Save the name of the remote target destination if we are - * in WHOLE mode (destdir > 0) or if the source and destination - * are not the same. This info will be used later for maintaining - * hardlink info. - */ - if (destdir || (src && dest && strcmp(src, dest))) { - strlcpy(destcopy, dest, sizeof destcopy); - Tdest = destcopy; - } - sendf(rname, opts); - Tdest = 0; -} - -static char * -remotename(pathname, src) - char *pathname; - char *src; -{ - char *cp; - int len; - - cp = pathname; - len = strlen(src); - if (0 == strncmp(pathname, src, len)) - cp += len; - if (*cp == '/') - cp ++; - return(cp); -} - -void -installlink(lp, rname, opts) - struct linkbuf *lp; - char *rname; - int opts; -{ - if (*lp->target == 0) - (void) snprintf(buf, sizeof(buf), "k%o %s %s\n", - opts, lp->pathname, rname); - else - (void) snprintf(buf, sizeof(buf), "k%o %s/%s %s\n", - opts, lp->target, - remotename(lp->pathname, lp->src), rname); - - if (debug) { - printf("lp->src = %s\n", lp->src); - printf("lp->target = %s\n", lp->target); - printf("lp->pathname = %s\n", lp->pathname); - printf("rname = %s\n", rname); - printf("buf = %s", buf); - } - (void) write(rem, buf, strlen(buf)); - (void) response(); -} - -#define protoname() (pw ? pw->pw_name : user) -#define protogroup() (gr ? gr->gr_name : group) -/* - * Transfer the file or directory in target[]. - * rname is the name of the file on the remote host. - */ -static void -sendf(rname, opts) - char *rname; - int opts; -{ - struct subcmd *sc; - struct stat stb; - int sizerr, f, u, len; - off_t i; - DIR *d; - struct dirent *dp; - char *otp, *cp; - extern struct subcmd *subcmds; - static char user[15], group[15]; - - if (debug) - printf("sendf(%s, %x)\n", rname, opts); - - if (except(target)) - return; - if ((opts & FOLLOW ? stat(target, &stb) : lstat(target, &stb)) < 0) { - error("%s: %s\n", target, strerror(errno)); - return; - } - if ((u = update(rname, opts, &stb)) == 0) { - if ((stb.st_mode & S_IFMT) == S_IFREG && stb.st_nlink > 1) - (void) savelink(&stb); - return; - } - - if (pw == NULL || pw->pw_uid != stb.st_uid) - if ((pw = getpwuid(stb.st_uid)) == NULL) { - logit(lfp, "%s: no password entry for uid %u \n", - target, stb.st_uid); - pw = NULL; - (void) snprintf(user, sizeof(user), ":%u", stb.st_uid); - } - if (gr == NULL || gr->gr_gid != stb.st_gid) - if ((gr = getgrgid(stb.st_gid)) == NULL) { - logit(lfp, "%s: no name for group %u\n", - target, stb.st_gid); - gr = NULL; - (void) snprintf(group, sizeof(group), ":%u", - stb.st_gid); - } - if (u == 1) { - if (opts & VERIFY) { - logit(lfp, "need to install: %s\n", target); - goto dospecial; - } - logit(lfp, "installing: %s\n", target); - opts &= ~(COMPARE|REMOVE); - } - - switch (stb.st_mode & S_IFMT) { - case S_IFDIR: - if ((d = opendir(target)) == NULL) { - error("%s: %s\n", target, strerror(errno)); - return; - } - (void) snprintf(buf, sizeof(buf), "D%o %04o 0 0 %s %s %s\n", - opts, stb.st_mode & 07777, protoname(), protogroup(), - rname); - if (debug) - printf("buf = %s", buf); - (void) write(rem, buf, strlen(buf)); - if (response() < 0) { - closedir(d); - return; - } - - if (opts & REMOVE) - rmchk(opts); - - otp = tp; - len = tp - target; - while (dp = readdir(d)) { - if (!strcmp(dp->d_name, ".") || - !strcmp(dp->d_name, "..")) - continue; - if (len + 1 + strlen(dp->d_name) >= BUFSIZ - 1) { - error("%s/%s: Name too long\n", target, - dp->d_name); - continue; - } - tp = otp; - *tp++ = '/'; - cp = dp->d_name; - while (*tp++ = *cp++) - ; - tp--; - sendf(dp->d_name, opts); - } - closedir(d); - (void) write(rem, "E\n", 2); - (void) response(); - tp = otp; - *tp = '\0'; - return; - - case S_IFLNK: - if (u != 1) - opts |= COMPARE; - if (stb.st_nlink > 1) { - struct linkbuf *lp; - - if ((lp = savelink(&stb)) != NULL) { - installlink(lp, rname, opts); - return; - } - } - (void) snprintf(buf, sizeof(buf), "K%o %o %qd %ld %s %s %s\n", - opts, stb.st_mode & 07777, stb.st_size, - (long)stb.st_mtime, protoname(), protogroup(), rname); - if (debug) - printf("buf = %s", buf); - (void) write(rem, buf, strlen(buf)); - if (response() < 0) - return; - sizerr = (readlink(target, buf, BUFSIZ-1) != stb.st_size); - (void) write(rem, buf, stb.st_size); - if (debug) - printf("readlink = %.*s\n", (int)stb.st_size, buf); - goto done; - - case S_IFREG: - break; - - default: - error("%s: not a file or directory\n", target); - return; - } - - if (u == 2) { - if (opts & VERIFY) { - logit(lfp, "need to update: %s\n", target); - goto dospecial; - } - logit(lfp, "updating: %s\n", target); - } - - if (stb.st_nlink > 1) { - struct linkbuf *lp; - - if ((lp = savelink(&stb)) != NULL) { - installlink(lp, rname, opts); - return; - } - } - - if ((f = open(target, O_RDONLY)) < 0) { - error("%s: %s\n", target, strerror(errno)); - return; - } - (void) snprintf(buf, sizeof(buf), "R%o %o %qd %ld %s %s %s\n", opts, - stb.st_mode & 07777, stb.st_size, (long)stb.st_mtime, - protoname(), protogroup(), rname); - if (debug) - printf("buf = %s", buf); - (void) write(rem, buf, strlen(buf)); - if (response() < 0) { - (void) close(f); - return; - } - sizerr = 0; - for (i = 0; i < stb.st_size; i += BUFSIZ) { - int amt = BUFSIZ; - if (i + amt > stb.st_size) - amt = stb.st_size - i; - if (sizerr == 0 && read(f, buf, amt) != amt) - sizerr = 1; - (void) write(rem, buf, amt); - } - (void) close(f); -done: - if (sizerr) { - error("%s: file changed size\n", target); - err(); - } else - ack(); - f = response(); - if (f < 0 || f == 0 && (opts & COMPARE)) - return; -dospecial: - for (sc = subcmds; sc != NULL; sc = sc->sc_next) { - if (sc->sc_type != SPECIAL) - continue; - if (sc->sc_args != NULL && !inlist(sc->sc_args, target)) - continue; - logit(lfp, "special \"%s\"\n", sc->sc_name); - if (opts & VERIFY) - continue; - (void) snprintf(buf, sizeof(buf), "SFILE=%s;%s\n", target, - sc->sc_name); - if (debug) - printf("buf = %s", buf); - (void) write(rem, buf, strlen(buf)); - while (response() > 0) - ; - } -} - -static struct linkbuf * -savelink(stp) - struct stat *stp; -{ - struct linkbuf *lp; - - for (lp = ihead; lp != NULL; lp = lp->nextp) - if (lp->inum == stp->st_ino && lp->devnum == stp->st_dev) { - lp->count--; - return(lp); - } - lp = (struct linkbuf *) malloc(sizeof(*lp)); - if (lp == NULL) - logit(lfp, "out of memory, link information lost\n"); - else { - lp->nextp = ihead; - ihead = lp; - lp->inum = stp->st_ino; - lp->devnum = stp->st_dev; - lp->count = stp->st_nlink - 1; - strlcpy(lp->pathname, target, sizeof lp->pathname); - strlcpy(lp->src, source, sizeof lp->src); - if (Tdest) - strlcpy(lp->target, Tdest, sizeof lp->target); - else - *lp->target = 0; - } - return(NULL); -} - -/* - * Check to see if file needs to be updated on the remote machine. - * Returns 0 if no update, 1 if remote doesn't exist, 2 if out of date - * and 3 if comparing binaries to determine if out of date. - */ -static int -update(rname, opts, stp) - char *rname; - int opts; - struct stat *stp; -{ - char *cp, *s; - off_t size; - time_t mtime; - - if (debug) - printf("update(%s, %x, %p)\n", rname, opts, stp); - - /* - * Check to see if the file exists on the remote machine. - */ - (void) snprintf(buf, sizeof(buf), "Q%s\n", rname); - if (debug) - printf("buf = %s", buf); - (void) write(rem, buf, strlen(buf)); -again: - cp = s = buf; - do { - if (read(rem, cp, 1) != 1) - lostconn(0); - } while (*cp++ != '\n' && cp < &buf[BUFSIZ]); - - switch (*s++) { - case 'Y': - break; - - case 'N': /* file doesn't exist so install it */ - return(1); - - case '\1': - nerrs++; - if (*s != '\n') { - if (!iamremote) { - fflush(stdout); - (void) write(STDERR_FILENO, s, cp - s); - } - if (lfp != NULL) - (void) fwrite(s, 1, cp - s, lfp); - } - return(0); - - case '\3': - *--cp = '\0'; - if (lfp != NULL) - logit(lfp, "update: note: %s\n", s); - goto again; - - default: - *--cp = '\0'; - error("update: unexpected response '%s'\n", s); - return(0); - } - - if (*s == '\n') - return(2); - - if (opts & COMPARE) - return(3); - - size = 0; - while (isdigit(*s)) - size = size * 10 + (*s++ - '0'); - if (*s++ != ' ') { - error("update: size not delimited\n"); - return(0); - } - mtime = 0; - while (isdigit(*s)) - mtime = mtime * 10 + (*s++ - '0'); - if (*s != '\n') { - error("update: mtime not delimited\n"); - return(0); - } - /* - * File needs to be updated? - */ - if (opts & YOUNGER) { - if (stp->st_mtime == mtime) - return(0); - if (stp->st_mtime < mtime) { - logit(lfp, "Warning: %s: remote copy is newer\n", target); - return(0); - } - } else if (stp->st_mtime == mtime && stp->st_size == size) - return(0); - return(2); -} - -/* - * Query. Check to see if file exists. Return one of the following: - * N\n - doesn't exist - * Ysize mtime\n - exists and its a regular file (size & mtime of file) - * Y\n - exists and its a directory or symbolic link - * ^Aerror message\n - */ -static void -query(name) - char *name; -{ - struct stat stb; - - if (catname) - (void) snprintf(tp, sizeof(target) - (tp - target), - "/%s", name); - - if (lstat(target, &stb) < 0) { - if (errno == ENOENT) - (void) write(rem, "N\n", 2); - else - error("%s:%s: %s\n", host, target, strerror(errno)); - *tp = '\0'; - return; - } - - switch (stb.st_mode & S_IFMT) { - case S_IFREG: - (void) snprintf(buf, sizeof(buf), "Y%qd %ld\n", stb.st_size, - (long)stb.st_mtime); - (void) write(rem, buf, strlen(buf)); - break; - - case S_IFLNK: - case S_IFDIR: - (void) write(rem, "Y\n", 2); - break; - - default: - error("%s: not a file or directory\n", name); - break; - } - *tp = '\0'; -} - -static void -recvf(cmd, type) - char *cmd; - int type; -{ - char *cp = cmd; - int f = -1, mode, opts = 0, wrerr, olderrno; - off_t i, size; - time_t mtime; - struct stat stb; - struct timeval tvp[2]; - char *owner, *group; - char new[BUFSIZ]; - extern char *tempname; - - while (*cp >= '0' && *cp <= '7') - opts = (opts << 3) | (*cp++ - '0'); - if (*cp++ != ' ') { - error("recvf: options not delimited\n"); - return; - } - mode = 0; - while (*cp >= '0' && *cp <= '7') - mode = (mode << 3) | (*cp++ - '0'); - if (*cp++ != ' ') { - error("recvf: mode not delimited\n"); - return; - } - size = 0; - while (isdigit(*cp)) - size = size * 10 + (*cp++ - '0'); - if (*cp++ != ' ') { - error("recvf: size not delimited\n"); - return; - } - mtime = 0; - while (isdigit(*cp)) - mtime = mtime * 10 + (*cp++ - '0'); - if (*cp++ != ' ') { - error("recvf: mtime not delimited\n"); - return; - } - owner = cp; - while (*cp && *cp != ' ') - cp++; - if (*cp != ' ') { - error("recvf: owner name not delimited\n"); - return; - } - *cp++ = '\0'; - group = cp; - while (*cp && *cp != ' ') - cp++; - if (*cp != ' ') { - error("recvf: group name not delimited\n"); - return; - } - *cp++ = '\0'; - - if (type == S_IFDIR) { - if (catname >= sizeof(stp)) { - error("%s:%s: too many directory levels\n", - host, target); - return; - } - stp[catname] = tp; - if (catname++) { - *tp++ = '/'; - while (*tp++ = *cp++) - ; - tp--; - } - if (opts & VERIFY) { - ack(); - return; - } - if (lstat(target, &stb) == 0) { - if (ISDIR(stb.st_mode)) { - if ((stb.st_mode & 07777) == mode) { - ack(); - return; - } - buf[0] = '\0'; - (void) snprintf(buf + 1, sizeof(buf) - 1, - "%s: Warning: remote mode %o != local mode %o\n", - target, stb.st_mode & 07777, mode); - (void) write(rem, buf, strlen(buf + 1) + 1); - return; - } - errno = ENOTDIR; - } else if (errno == ENOENT && (mkdir(target, mode) == 0 || - chkparent(target) == 0 && mkdir(target, mode) == 0)) { - if (fchog(-1, target, owner, group, mode) == 0) - ack(); - return; - } - error("%s:%s: %s\n", host, target, strerror(errno)); - tp = stp[--catname]; - *tp = '\0'; - return; - } - - if (catname) - (void) snprintf(tp, sizeof(target) - (tp - target), "/%s", cp); - cp = strrchr(target, '/'); - if (cp == NULL) - strlcpy(new, tempname, sizeof new); - else if (cp == target) - (void) snprintf(new, sizeof(new), "/%s", tempname); - else { - *cp = '\0'; - (void) snprintf(new, sizeof(new), "%s/%s", target, tempname); - *cp = '/'; - } - - if (type == S_IFLNK) { - int j; - - ack(); - cp = buf; - for (i = 0; i < size; i += j) { - if ((j = read(rem, cp, size - i)) <= 0) - cleanup(0); - cp += j; - } - *cp = '\0'; - if (response() < 0) { - err(); - return; - } - if (symlink(buf, new) < 0) { - if (errno != ENOENT || chkparent(new) < 0 || - symlink(buf, new) < 0) - goto badnew1; - } - mode &= 0777; - if (opts & COMPARE) { - char tbuf[BUFSIZ]; - - if ((i = readlink(target, tbuf, BUFSIZ)) >= 0 && - i == size && strncmp(buf, tbuf, size) == 0) { - (void) unlink(new); - ack(); - return; - } - if (opts & VERIFY) - goto differ; - } - goto fixup; - } - - if ((f = creat(new, mode)) < 0) { - if (errno != ENOENT || chkparent(new) < 0 || - (f = creat(new, mode)) < 0) - goto badnew1; - } - - ack(); - wrerr = 0; - for (i = 0; i < size; i += BUFSIZ) { - int amt = BUFSIZ; - - cp = buf; - if (i + amt > size) - amt = size - i; - do { - int j = read(rem, cp, amt); - - if (j <= 0) { - (void) close(f); - (void) unlink(new); - cleanup(0); - } - amt -= j; - cp += j; - } while (amt > 0); - amt = BUFSIZ; - if (i + amt > size) - amt = size - i; - if (wrerr == 0 && write(f, buf, amt) != amt) { - olderrno = errno; - wrerr++; - } - } - if (response() < 0) { - err(); - goto badnew2; - } - if (wrerr) - goto badnew1; - if (opts & COMPARE) { - FILE *f1, *f2; - int c; - - if ((f1 = fopen(target, "r")) == NULL) - goto badtarget; - if ((f2 = fopen(new, "r")) == NULL) { -badnew1: error("%s:%s: %s\n", host, new, strerror(errno)); - goto badnew2; - } - while ((c = getc(f1)) == getc(f2)) - if (c == EOF) { - (void) fclose(f1); - (void) fclose(f2); - ack(); - goto badnew2; - } - (void) fclose(f1); - (void) fclose(f2); - if (opts & VERIFY) { -differ: buf[0] = '\0'; - (void) snprintf(buf + 1, sizeof(buf) - 1, - "need to update: %s\n",target); - (void) write(rem, buf, strlen(buf + 1) + 1); - goto badnew2; - } - } - - /* - * Set last modified time - */ - tvp[0].tv_sec = time(NULL); - tvp[0].tv_usec = 0; - tvp[1].tv_sec = mtime; - tvp[1].tv_usec = 0; - if (utimes(new, tvp) < 0) - note("%s: utimes failed %s: %s\n", host, new, strerror(errno)); - - if (fchog(f, new, owner, group, mode) < 0) { -badnew2: - if (f >= 0) - (void) close(f); - (void) unlink(new); - return; - } - (void) close(f); - -fixup: if (rename(new, target) < 0) { -badtarget: error("%s:%s: %s\n", host, target, strerror(errno)); - (void) unlink(new); - return; - } - - if (opts & COMPARE) { - buf[0] = '\0'; - (void) snprintf(buf + 1, sizeof(buf) - 1, - "updated %s\n", target); - (void) write(rem, buf, strlen(buf + 1) + 1); - } else - ack(); -} - -/* - * Creat a hard link to existing file. - */ -static void -hardlink(cmd) - char *cmd; -{ - char *cp = cmd; - struct stat stb; - char *oldname; - int opts = 0, exists = 0; - - while (*cp >= '0' && *cp <= '7') - opts = (opts << 3) | (*cp++ - '0'); - if (*cp++ != ' ') { - error("hardlink: options not delimited\n"); - return; - } - oldname = cp; - while (*cp && *cp != ' ') - cp++; - if (*cp != ' ') { - error("hardlink: oldname name not delimited\n"); - return; - } - *cp++ = '\0'; - - if (catname) { - (void) snprintf(tp, sizeof(target) - (tp - target), "/%s", cp); - } - if (lstat(target, &stb) == 0) { - int mode = stb.st_mode & S_IFMT; - if (mode != S_IFREG && mode != S_IFLNK) { - error("%s:%s: not a regular file\n", host, target); - return; - } - exists = 1; - } - if (chkparent(target) < 0 ) { - error("%s:%s: %s (no parent)\n", - host, target, strerror(errno)); - return; - } - if (exists && (unlink(target) < 0)) { - error("%s:%s: %s (unlink)\n", - host, target, strerror(errno)); - return; - } - if (link(oldname, target) < 0) { - error("%s:can't link %s to %s\n", - host, target, oldname); - return; - } - ack(); -} - -/* - * Check to see if parent directory exists and create one if not. - */ -static int -chkparent(name) - char *name; -{ - char *cp; - struct stat stb; - - cp = strrchr(name, '/'); - if (cp == NULL || cp == name) - return(0); - *cp = '\0'; - if (lstat(name, &stb) < 0) { - if (errno == ENOENT && chkparent(name) >= 0 && - mkdir(name, 0777 & ~oumask) >= 0) { - *cp = '/'; - return(0); - } - } else if (ISDIR(stb.st_mode)) { - *cp = '/'; - return(0); - } - *cp = '/'; - return(-1); -} - -/* - * Change owner, group and mode of file. - */ -static int -fchog(fd, file, owner, group, mode) - int fd; - char *file, *owner, *group; - int mode; -{ - int i; - uid_t uid; - gid_t gid; - extern char user[]; - extern uid_t userid; - - uid = userid; - if (userid == 0) { - if (*owner == ':') { - uid = atoi(owner + 1); - } else if (pw == NULL || strcmp(owner, pw->pw_name) != 0) { - if ((pw = getpwnam(owner)) == NULL) { - if (mode & 04000) { - note("%s:%s: unknown login name, clearing setuid", - host, owner); - mode &= ~04000; - uid = 0; - } - } else - uid = pw->pw_uid; - } else - uid = pw->pw_uid; - if (*group == ':') { - gid = atoi(group + 1); - goto ok; - } - } else if ((mode & 04000) && strcmp(user, owner) != 0) - mode &= ~04000; - gid = -1; - if (gr == NULL || strcmp(group, gr->gr_name) != 0) { - if ((*group == ':' && (getgrgid(gid = atoi(group + 1)) == NULL)) - || ((gr = getgrnam(group)) == NULL)) { - if (mode & 02000) { - note("%s:%s: unknown group", host, group); - mode &= ~02000; - } - } else - gid = gr->gr_gid; - } else - gid = gr->gr_gid; - if (userid && gid >= 0) { - if (gr) for (i = 0; gr->gr_mem[i] != NULL; i++) - if (!(strcmp(user, gr->gr_mem[i]))) - goto ok; - mode &= ~02000; - gid = -1; - } -ok: if (fd != -1 && fchown(fd, uid, gid) < 0 || chown(file, uid, gid) < 0) - note("%s: %s chown: %s", host, file, strerror(errno)); - else if (mode & 07000 && - (fd != -1 && fchmod(fd, mode) < 0 || chmod(file, mode) < 0)) - note("%s: %s chmod: %s", host, file, strerror(errno)); - return(0); -} - -/* - * Check for files on the machine being updated that are not on the master - * machine and remove them. - */ -static void -rmchk(opts) - int opts; -{ - char *cp, *s; - struct stat stb; - - if (debug) - printf("rmchk()\n"); - - /* - * Tell the remote to clean the files from the last directory sent. - */ - (void) snprintf(buf, sizeof(buf), "C%o\n", opts & VERIFY); - if (debug) - printf("buf = %s", buf); - (void) write(rem, buf, strlen(buf)); - if (response() < 0) - return; - for (;;) { - cp = s = buf; - do { - if (read(rem, cp, 1) != 1) - lostconn(0); - } while (*cp++ != '\n' && cp < &buf[BUFSIZ]); - - switch (*s++) { - case 'Q': /* Query if file should be removed */ - /* - * Return the following codes to remove query. - * N\n -- file exists - DON'T remove. - * Y\n -- file doesn't exist - REMOVE. - */ - *--cp = '\0'; - (void) snprintf(tp, sizeof(target) - (tp - target), - "/%s", s); - if (debug) - printf("check %s\n", target); - if (except(target)) - (void) write(rem, "N\n", 2); - else if (lstat(target, &stb) < 0) - (void) write(rem, "Y\n", 2); - else - (void) write(rem, "N\n", 2); - break; - - case '\0': - *--cp = '\0'; - if (*s != '\0') - logit(lfp, "%s\n", s); - break; - - case 'E': - *tp = '\0'; - ack(); - return; - - case '\1': - case '\2': - nerrs++; - if (*s != '\n') { - if (!iamremote) { - fflush(stdout); - (void) write(STDERR_FILENO, s, cp - s); - } - if (lfp != NULL) - (void) fwrite(s, 1, cp - s, lfp); - } - if (buf[0] == '\2') - lostconn(0); - break; - - default: - error("rmchk: unexpected response '%s'\n", buf); - err(); - } - } -} - -/* - * Check the current directory (initialized by the 'T' command to server()) - * for extraneous files and remove them. - */ -static void -clean(cp) - char *cp; -{ - DIR *d; - struct dirent *dp; - struct stat stb; - char *otp; - int len, opts; - - opts = 0; - while (*cp >= '0' && *cp <= '7') - opts = (opts << 3) | (*cp++ - '0'); - if (*cp != '\0') { - error("clean: options not delimited\n"); - return; - } - if ((d = opendir(target)) == NULL) { - error("%s:%s: %s\n", host, target, strerror(errno)); - return; - } - ack(); - - otp = tp; - len = tp - target; - while (dp = readdir(d)) { - if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) - continue; - if (len + 1 + strlen(dp->d_name) >= BUFSIZ - 1) { - error("%s:%s/%s: Name too long\n", - host, target, dp->d_name); - continue; - } - tp = otp; - *tp++ = '/'; - cp = dp->d_name; - while (*tp++ = *cp++) - ; - tp--; - if (lstat(target, &stb) < 0) { - error("%s:%s: %s\n", host, target, strerror(errno)); - continue; - } - (void) snprintf(buf, sizeof(buf), "Q%s\n", dp->d_name); - (void) write(rem, buf, strlen(buf)); - cp = buf; - do { - if (read(rem, cp, 1) != 1) - cleanup(0); - } while (*cp++ != '\n' && cp < &buf[BUFSIZ]); - *--cp = '\0'; - cp = buf; - if (*cp != 'Y') - continue; - if (opts & VERIFY) { - cp = buf; - *cp++ = '\0'; - (void) snprintf(cp, sizeof(buf) - 1, - "need to remove: %s\n", target); - (void) write(rem, buf, strlen(cp) + 1); - } else - removeit(&stb); - } - closedir(d); - (void) write(rem, "E\n", 2); - (void) response(); - tp = otp; - *tp = '\0'; -} - -/* - * Remove a file or directory (recursively) and send back an acknowledge - * or an error message. - */ -static void -removeit(stp) - struct stat *stp; -{ - DIR *d; - struct dirent *dp; - char *cp; - struct stat stb; - char *otp; - int len; - - switch (stp->st_mode & S_IFMT) { - case S_IFREG: - case S_IFLNK: - if (unlink(target) < 0) - goto bad; - goto removed; - - case S_IFDIR: - break; - - default: - error("%s:%s: not a plain file\n", host, target); - return; - } - - if ((d = opendir(target)) == NULL) - goto bad; - - otp = tp; - len = tp - target; - while (dp = readdir(d)) { - if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) - continue; - if (len + 1 + strlen(dp->d_name) >= BUFSIZ - 1) { - error("%s:%s/%s: Name too long\n", - host, target, dp->d_name); - continue; - } - tp = otp; - *tp++ = '/'; - cp = dp->d_name; - while (*tp++ = *cp++) - ; - tp--; - if (lstat(target, &stb) < 0) { - error("%s:%s: %s\n", host, target, strerror(errno)); - continue; - } - removeit(&stb); - } - closedir(d); - tp = otp; - *tp = '\0'; - if (rmdir(target) < 0) { -bad: - error("%s:%s: %s\n", host, target, strerror(errno)); - return; - } -removed: - cp = buf; - *cp++ = '\0'; - (void) snprintf(cp, sizeof(buf) - 1, "removed %s\n", target); - (void) write(rem, buf, strlen(cp) + 1); -} - -/* - * Execute a shell command to handle special cases. - */ -static void -dospecial(cmd) - char *cmd; -{ - int fd[2], status; - char *cp, *s; - char sbuf[BUFSIZ]; - pid_t pid, i; -#if defined(DIRECT_RCMD) - extern uid_t userid; - extern gid_t groupid; -#endif /* DIRECT_RCMD */ - - if (pipe(fd) < 0) { - error("%s\n", strerror(errno)); - return; - } - if ((pid = fork()) == 0) { - /* - * Return everything the shell commands print. - */ - (void) close(0); - (void) close(1); - (void) close(2); - (void) open(_PATH_DEVNULL, O_RDONLY); - (void) dup(fd[1]); - (void) dup(fd[1]); - (void) close(fd[0]); - (void) close(fd[1]); -#if defined(DIRECT_RCMD) - if (setgroups(1, &groupid) == -1 || - setresgid(groupid, groupid, groupid) == -1 || - setresuid(userid, userid, userid) == -1) - _exit(127); -#endif /* DIRECT_RCMD */ - execl(_PATH_BSHELL, "sh", "-c", cmd, (char *)NULL); - _exit(127); - } - (void) close(fd[1]); - s = sbuf; - *s++ = '\0'; - while ((i = read(fd[0], buf, sizeof(buf))) > 0) { - cp = buf; - do { - *s++ = *cp++; - if (cp[-1] != '\n') { - if (s < &sbuf[sizeof(sbuf)-1]) - continue; - *s++ = '\n'; - } - /* - * Throw away blank lines. - */ - if (s == &sbuf[2]) { - s--; - continue; - } - (void) write(rem, sbuf, s - sbuf); - s = &sbuf[1]; - } while (--i); - } - if (s > &sbuf[1]) { - *s++ = '\n'; - (void) write(rem, sbuf, s - sbuf); - } - while ((i = wait(&status)) != pid && i != -1) - ; - if (i == -1) - status = -1; - (void) close(fd[0]); - if (status) - error("shell returned %d\n", status); - else - ack(); -} - -void -logit(FILE *fp, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - /* Print changes locally if not quiet mode */ - if (!qflag) - (void) vprintf(fmt, ap); - - /* Save changes (for mailing) if really updating files */ - if (!(options & VERIFY) && fp != NULL) - (void) vfprintf(fp, fmt, ap); - va_end(ap); -} - -void -error(const char *fmt, ...) -{ - static FILE *fp; - va_list ap; - - va_start(ap, fmt); - ++nerrs; - if (iamremote) { - if (!fp && (rem < 0 || !(fp = fdopen(rem, "w")))) - return; - (void) fprintf(fp, "%crdist: ", 0x01); - (void) vfprintf(fp, fmt, ap); - fflush(fp); - } - else { - fflush(stdout); - (void) fprintf(stderr, "rdist: "); - (void) vfprintf(stderr, fmt, ap); - fflush(stderr); - } - if (lfp != NULL) { - (void) fprintf(lfp, "rdist: "); - (void) vfprintf(lfp, fmt, ap); - fflush(lfp); - } - va_end(ap); -} - -void -fatal(const char *fmt, ...) -{ - static FILE *fp; - va_list ap; - - va_start(ap, fmt); - ++nerrs; - if (!fp && !(fp = fdopen(rem, "w"))) - return; - if (iamremote) { - (void) fprintf(fp, "%crdist: ", 0x02); - (void) vfprintf(fp, fmt, ap); - fflush(fp); - } - else { - fflush(stdout); - (void) fprintf(stderr, "rdist: "); - (void) vfprintf(stderr, fmt, ap); - fflush(stderr); - } - if (lfp != NULL) { - (void) fprintf(lfp, "rdist: "); - (void) vfprintf(lfp, fmt, ap); - fflush(lfp); - } - va_end(ap); - cleanup(0); -} - -static int -response() -{ - char *cp, *s; - char resp[BUFSIZ]; - - if (debug) - printf("response()\n"); - - cp = s = resp; - do { - if (read(rem, cp, 1) != 1) - lostconn(0); - } while (*cp++ != '\n' && cp < &resp[BUFSIZ]); - - switch (*s++) { - case '\0': - *--cp = '\0'; - if (*s != '\0') { - logit(lfp, "%s\n", s); - return(1); - } - return(0); - case '\3': - *--cp = '\0'; - logit(lfp, "Note: %s\n",s); - return(response()); - - default: - s--; - /* fall into... */ - case '\1': - case '\2': - nerrs++; - if (*s != '\n') { - if (!iamremote) { - fflush(stdout); - (void) write(STDERR_FILENO, s, cp - s); - } - if (lfp != NULL) - (void) fwrite(s, 1, cp - s, lfp); - } - if (resp[0] == '\2') - lostconn(0); - return(-1); - } -} - -/* - * Remove temporary files and do any cleanup operations before exiting. - */ -void -cleanup(signo) - int signo; -{ - (void) unlink(tempfile); - exit(1); -} - -static void -note(const char *fmt, ...) -{ - static char buf[BUFSIZ]; - va_list ap; - - va_start(ap, fmt); - (void) vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - comment(buf); -} - -static void -comment(s) - char *s; -{ - char c; - - c = '\3'; - write(rem, &c, 1); - write(rem, s, strlen(s)); - c = '\n'; - write(rem, &c, 1); -} |