summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2014-07-10 14:26:17 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2014-07-10 14:26:17 +0000
commit73b3f24907775fefb7f5c4b0a1f81f3045136d71 (patch)
treef7b166138b17e864c88f4ec3a0eb9fd806294f67 /usr.bin
parentb0be8b9a780ed8e79ebc40e2b09e90de8607a1e6 (diff)
Snakes. Why'd it have to be snakes?
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/oldrdist/Makefile16
-rw-r--r--usr.bin/oldrdist/defs.h179
-rw-r--r--usr.bin/oldrdist/docmd.c668
-rw-r--r--usr.bin/oldrdist/expand.c666
-rw-r--r--usr.bin/oldrdist/gram.y495
-rw-r--r--usr.bin/oldrdist/lookup.c161
-rw-r--r--usr.bin/oldrdist/main.c296
-rw-r--r--usr.bin/oldrdist/oldrdist.1460
-rw-r--r--usr.bin/oldrdist/pathnames.h35
-rw-r--r--usr.bin/oldrdist/server.c1592
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);
-}