summaryrefslogtreecommitdiffstats
path: root/usr.bin/rdist
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2000-12-07 19:24:55 +0000
committerobrien <obrien@FreeBSD.org>2000-12-07 19:24:55 +0000
commit172e75f19374ae58caa1a5459a3f8a1d3a36f5de (patch)
treed09d274b31adb401922100b5a49ef6f97fab5171 /usr.bin/rdist
parentd2fca12323f8e184b45b47597f9ce026d4831358 (diff)
downloadFreeBSD-src-172e75f19374ae58caa1a5459a3f8a1d3a36f5de.zip
FreeBSD-src-172e75f19374ae58caa1a5459a3f8a1d3a36f5de.tar.gz
Retire this ancient version of rdist.
Diffstat (limited to 'usr.bin/rdist')
-rw-r--r--usr.bin/rdist/Makefile16
-rw-r--r--usr.bin/rdist/cron.entry1
-rw-r--r--usr.bin/rdist/defs.h191
-rw-r--r--usr.bin/rdist/docmd.c700
-rw-r--r--usr.bin/rdist/expand.c677
-rw-r--r--usr.bin/rdist/gram.y523
-rw-r--r--usr.bin/rdist/lookup.c171
-rw-r--r--usr.bin/rdist/main.c337
-rw-r--r--usr.bin/rdist/pathnames.h39
-rw-r--r--usr.bin/rdist/rshrcmd.c119
-rw-r--r--usr.bin/rdist/server.c1634
11 files changed, 0 insertions, 4408 deletions
diff --git a/usr.bin/rdist/Makefile b/usr.bin/rdist/Makefile
deleted file mode 100644
index ea47411..0000000
--- a/usr.bin/rdist/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-# @(#)Makefile 8.3 (Berkeley) 7/19/93
-# $FreeBSD$
-
-PROG= rdist
-SRCS= docmd.c expand.c gram.y lookup.c main.c rshrcmd.c server.c
-CFLAGS+=-I${.CURDIR}
-YFLAGS=
-
-# To use the old method, which requires setuid-root and all the baggage and
-# security holes that goes with it, uncomment:
-# CFLAGS+= -DDIRECT_RCMD
-# BINOWN= root
-# BINMODE=4555
-# INSTALLFLAGS=-fschg
-
-.include <bsd.prog.mk>
diff --git a/usr.bin/rdist/cron.entry b/usr.bin/rdist/cron.entry
deleted file mode 100644
index 90968cf..0000000
--- a/usr.bin/rdist/cron.entry
+++ /dev/null
@@ -1 +0,0 @@
-30 3 * * * /usr/bin/rdist -f /etc/Distfile >& /var/log/rdist/rdist.err 2>&1
diff --git a/usr.bin/rdist/defs.h b/usr.bin/rdist/defs.h
deleted file mode 100644
index 47fad20..0000000
--- a/usr.bin/rdist/defs.h
+++ /dev/null
@@ -1,191 +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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. 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.
- *
- * @(#)defs.h 8.1 (Berkeley) 6/9/93
- */
-
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/file.h>
-
-#include <netinet/in.h>
-
-#include <dirent.h>
-#include <errno.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))
-
-/*
- * RSH Time Out interval (in seconds).
- * Should be long enough to allow rsh to even the slowest hosts.
- */
-#define RTIMEOUT 180
-
-
-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 */
-extern char *path_rsh; /* rsh command to use */
-
-int any __P((int, char *));
-char *colon __P((char *));
-void cleanup __P((int));
-void define __P((char *));
-void docmds __P((char **, int, char **));
-void error __P((const char *, ...));
-int except __P((char *));
-struct namelist *
- expand __P((struct namelist *, int));
-char *exptilde __P((char [], char *, int));
-void fatal __P((const char *, ...));
-int inlist __P((struct namelist *, char *));
-void insert __P((char *,
- struct namelist *, struct namelist *, struct subcmd *));
-void install __P((char *, char *, int, int));
-void log __P((FILE *, const char *, ...));
-struct namelist *
- lookup __P((char *, int, struct namelist *));
-void lostconn __P((int));
-struct namelist *
- makenl __P((char *));
-struct subcmd *
- makesubcmd __P((int));
-void prnames __P((struct namelist *));
-void server __P((void));
-void yyerror __P((char *));
-int yyparse __P((void));
-int rshrcmd __P((char **, u_short, char *, char *, char *, int *));
diff --git a/usr.bin/rdist/docmd.c b/usr.bin/rdist/docmd.c
deleted file mode 100644
index 7ea9a8c..0000000
--- a/usr.bin/rdist/docmd.c
+++ /dev/null
@@ -1,700 +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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. 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.
- */
-
-#ifndef lint
-#if 0
-static char sccsid[] = "From: @(#)docmd.c 8.1 (Berkeley) 6/9/93";
-#endif
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-#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 __P((char *));
-static int okname __P((char *));
-static void closeconn __P((void));
-static void cmptime __P((char *));
-static void doarrow __P((char **,
- struct namelist *, char *, struct subcmd *));
-static void dodcolon __P((char **,
- struct namelist *, char *, struct subcmd *));
-static void notify __P((char *, char *, struct namelist *, time_t));
-static void rcmptime __P((struct stat *));
-static int remotecmd __P((char *, char *, char *, char *));
-
-/*
- * Do the commands in cmds (initialized by yyparse).
- */
-void
-docmds(dhosts, argc, argv)
- char **dhosts;
- int argc;
- char **argv;
-{
- register struct cmd *c;
- register struct namelist *f;
- register 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;
-{
- register struct namelist *f;
- register struct subcmd *sc;
- register char **cpp;
- int n, ddir, opts = options;
-
- if (debug)
- printf("doarrow(%p, %s, %p)\n", files, rhost, 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 {
- if (setjmp(env))
- goto done;
- signal(SIGPIPE, lostconn);
- if (!makeconn(rhost))
- return;
- if ((lfp = fopen(tempfile, "w")) == NULL) {
- 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)
- (void) fclose(lfp);
- 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;
- log(lfp, "%s: Warning: missing links\n",
- ihead->pathname);
- free(ihead);
- }
- }
-}
-
-static int remotecmd(rhost, luser, ruser, cmd)
- char *rhost;
- char *luser, *ruser;
- char *cmd;
-{
- int desc;
- static int port = -1;
-
- if (debug) {
- printf("local user = %s remote user = %s\n", luser, ruser);
- printf("Remote command = '%s'\n", cmd);
- }
-
- (void) fflush(stdout);
- (void) fflush(stderr);
- (void) signal(SIGALRM, cleanup);
- (void) alarm(RTIMEOUT);
-
- if (geteuid() == 0 && strcmp(path_rsh, _PATH_RSH) == 0) {
- if (debug)
- printf("I am root, therefore direct rcmd\n");
-
- (void) signal(SIGPIPE, cleanup);
-
- if (port < 0) {
- struct servent *sp;
-
- if ((sp = getservbyname("shell", "tcp")) == NULL)
- fatal("shell/tcp: unknown service");
- port = sp->s_port;
- }
-
- desc = rcmd(&rhost, port, luser, ruser, cmd, 0);
- } else {
- if (debug)
- printf("Remote shell command = '%s'\n", path_rsh);
- (void) signal(SIGPIPE, SIG_IGN);
- desc = rshrcmd(&rhost, -1, luser, ruser, cmd, 0);
- if (desc > 0)
- (void) signal(SIGPIPE, cleanup);
- }
-
- (void) alarm(0);
-
- return(desc);
-}
-
-
-/*
- * Create a connection to the rdist server on the machine rhost.
- */
-static int
-makeconn(rhost)
- char *rhost;
-{
- register char *ruser, *cp;
- static char *cur_host = NULL;
- static int port = -1;
- char tuser[20];
- int n;
- extern char user[];
-#if defined(DIRECT_RCMD)
- extern int 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 = index(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 (port < 0) {
- struct servent *sp;
-
- if ((sp = getservbyname("shell", "tcp")) == NULL)
- fatal("shell/tcp: unknown service");
- port = sp->s_port;
- }
-
- if (debug) {
- printf("port = %d, luser = %s, ruser = %s\n", ntohs(port), user, ruser);
- printf("buf = %s\n", buf);
- }
-
- fflush(stdout);
-#if defined(DIRECT_RCMD)
- seteuid(0);
- rem = rcmd(&rhost, port, user, ruser, buf, 0);
- seteuid(userid);
-#else
- rem = remotecmd(rhost, user, ruser, buf);
-#endif
- 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) write(rem, "\2\n", 2);
- (void) close(rem);
- rem = -1;
- }
-}
-
-void
-lostconn(signo)
- int signo;
-{
- if (iamremote)
- cleanup(0);
- log(lfp, "rdist: lost connection\n");
- longjmp(env, 1);
-}
-
-static int
-okname(name)
- register char *name;
-{
- register char *cp = name;
- register 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 target[], *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;
-{
- register struct subcmd *sc;
- register struct namelist *f;
- register char **cpp;
- struct timeval tv[2];
- struct timezone tz;
- 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: %ld\n", stamp, stb.st_mtime);
-
- subcmds = cmds;
- lastmod = stb.st_mtime;
- if (nflag || (options & VERIFY))
- tfp = NULL;
- else {
- if ((tfp = fopen(tempfile, "w")) == NULL) {
- error("%s: %s\n", stamp, strerror(errno));
- return;
- }
- (void) gettimeofday(&tv[0], &tz);
- 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)
- log(tfp, "new: %s\n", name);
-}
-
-static void
-rcmptime(st)
- struct stat *st;
-{
- register DIR *d;
- register struct dirent *dp;
- register char *cp;
- char *otp;
- int len;
-
- if (debug)
- printf("rcmptime(%p)\n", 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;
- register struct namelist *to;
- time_t lmod;
-{
- register 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, 0)) < 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 mailling 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, "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;
-{
- register 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;
-{
- register struct subcmd *sc;
- register struct namelist *nl;
- regex_t rx;
- int val;
-
- 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;
- }
- val = regcomp(&rx, nl->n_name,
- REG_EXTENDED | REG_NOSUB);
- if (!regexec(&rx, file, 0, 0, 0)) {
- regfree(&rx);
- return 1;
- }
- regfree(&rx);
- }
- }
- return(0);
-}
-
-char *
-colon(cp)
- register char *cp;
-{
-
- while (*cp) {
- if (*cp == ':')
- return(cp);
- if (*cp == '/')
- return(0);
- cp++;
- }
- return(0);
-}
diff --git a/usr.bin/rdist/expand.c b/usr.bin/rdist/expand.c
deleted file mode 100644
index d5f7ed4..0000000
--- a/usr.bin/rdist/expand.c
+++ /dev/null
@@ -1,677 +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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. 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.
- */
-
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)expand.c 8.1 (Berkeley) 6/9/93";
-#endif
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-#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 *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 __P((char *, char *));
-static void addpath __P((int));
-static int amatch __P((char *, char *));
-static int argcmp __P((const void *, const void *));
-static int execbrc __P((char *, char *));
-static void expsh __P((char *));
-static void expstr __P((char *));
-static int match __P((char *, char *));
-static void matchdir __P((char *));
-static int smatch __P((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;
-{
- register struct namelist *nl, *prev;
- register int n;
- char pathbuf[BUFSIZ];
- char *argvbuf[GAVSIZ];
-
- if (debug) {
- printf("expand(%p, %d)\nlist = ", list, wh);
- prnames(list);
- }
-
- if (wh == 0) {
- register 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;
-{
- register char *cp, *cp1;
- register 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 = index(s, '$')) != NULL) {
- *cp++ = '\0';
- if (*cp == '\0') {
- yyerror("no variable name after '$'");
- return;
- }
- if (*cp == LC) {
- cp++;
- if ((tail = index(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, NULL, 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) {
- strcat(buf, ": unknown user name");
- 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;
-{
- register char *cp;
- register 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;
- register struct dirent *dp;
- DIR *dirp;
-
- dirp = opendir(path);
- if (dirp == NULL) {
- if (expany)
- return;
- goto patherr2;
- }
- if (fstat(dirp->dd_fd, &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 {
- strcpy(pathp, dp->d_name);
- Cat(tilde, tpathp);
- *pathp = '\0';
- }
- }
- closedir(dirp);
- return;
-
-patherr1:
- closedir(dirp);
-patherr2:
- strcat(path, ": ");
- strcat(path, strerror(errno));
- yyerror(path);
-}
-
-static int
-execbrc(p, s)
- char *p, *s;
-{
- char restbuf[BUFSIZ + 2];
- register 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;
- strcpy(lm, pl);
- strcat(restbuf, pe + 1);
- *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;
-{
- register int c;
- register 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)
- register char *s, *p;
-{
- register 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)
- register char *s, *p;
-{
- register 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)
- register char *s1, *s2;
-{
- int len = strlen(s1) + strlen(s2) + 1;
- register 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[];
- register char *file;
- int maxlen;
-{
- register char *s1, *s2, *s3;
- extern char homedir[];
-
- if (strlen(file) >= maxlen)
- return(NULL);
- if (*file != '~') {
- strcpy(buf, file);
- 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/rdist/gram.y b/usr.bin/rdist/gram.y
deleted file mode 100644
index bd77901..0000000
--- a/usr.bin/rdist/gram.y
+++ /dev/null
@@ -1,523 +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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. 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.
- */
-
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)gram.y 8.1 (Berkeley) 6/9/93";
-#endif
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-#include "defs.h"
-#include <sys/types.h>
-#include <regex.h>
-#include <limits.h>
-
-struct cmd *cmds = NULL;
-struct cmd *last_cmd;
-struct namelist *last_n;
-struct subcmd *last_sc;
-
-static char *makestr __P((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 = {
- struct namelist *nl;
- regex_t rx;
- int val;
- char errbuf[_POSIX2_LINE_MAX];
-
- for (nl = $2; nl != NULL; nl = nl->n_next) {
- if ((val = regcomp(&rx, nl->n_name,
- REG_EXTENDED))) {
- regerror(val, &rx, errbuf,
- sizeof errbuf);
- yyerror(errbuf);
- }
- regfree(&rx);
- }
- $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, *next_h;
-
- files = expand(files, E_VARS|E_SHELL);
- hosts = expand(hosts, E_ALL);
- for (h = hosts; h != NULL; next_h = h->n_next, free(h), h = next_h) {
- /*
- * 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/rdist/lookup.c b/usr.bin/rdist/lookup.c
deleted file mode 100644
index b97ce3f..0000000
--- a/usr.bin/rdist/lookup.c
+++ /dev/null
@@ -1,171 +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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. 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.
- */
-
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)lookup.c 8.1 (Berkeley) 6/9/93";
-#endif
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-#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;
-{
- register char *cp, *s;
- register struct namelist *nl;
- struct namelist *value = NULL;
-
- if (debug)
- printf("define(%s)\n", name);
-
- cp = index(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;
-{
- register unsigned n;
- register char *cp;
- register 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/rdist/main.c b/usr.bin/rdist/main.c
deleted file mode 100644
index d4d94a2..0000000
--- a/usr.bin/rdist/main.c
+++ /dev/null
@@ -1,337 +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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. 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.
- */
-
-#ifndef lint
-static const char copyright[] =
-"@(#) Copyright (c) 1983, 1993\n\
- The Regents of the University of California. All rights reserved.\n";
-#if 0
-static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/9/93";
-#endif
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-#include "defs.h"
-
-#define NHOSTS 100
-
-/*
- * Remote distribution program.
- */
-
-char *distfile = NULL;
-#define _RDIST_TMP "/rdistXXXXXX"
-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 transfering files */
-
-FILE *fin = NULL; /* input file pointer */
-int rem = -1; /* file descriptor to remote source/sink process */
-char host[32]; /* host name */
-int nerrs; /* number of errors while sending/receiving */
-char user[10]; /* user's name */
-char homedir[128]; /* user's home directory */
-int userid; /* user's user ID */
-int groupid; /* user's group ID */
-char *path_rsh = _PATH_RSH; /* rsh (or equiv command) path */
-
-struct passwd *pw; /* pointer to static area used by getpwent */
-struct group *gr; /* pointer to static area used by getgrent */
-
-static void usage __P((void));
-static void docmdargs __P((int, char *[]));
-
-int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- register 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);
- }
- strcpy(user, pw->pw_name);
- strcpy(homedir, pw->pw_dir);
- groupid = pw->pw_gid;
- gethostname(host, sizeof(host));
- strcpy(tempfile, _PATH_TMP);
- strcat(tempfile, _RDIST_TMP);
- if ((tempname = rindex(tempfile, '/')) != 0)
- tempname++;
- else
- tempname = tempfile;
-
- while (--argc > 0) {
- if ((arg = *++argv)[0] != '-')
- break;
- if (!strcmp(arg, "-Server"))
- iamremote++;
- else while (*++arg)
- switch (*arg) {
- case 'P':
- if (--argc <= 0)
- usage();
- path_rsh = *++argv;
- break;
-
- 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;
-
- seteuid(userid);
- mktemp(tempfile);
-
- 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("%s\n%s\n%s\n",
-"usage: rdist [-nqbhirvwyD] [-P /path/to/rsh ] [-f distfile] [-d var=value]",
-" [-m host] [file ...]",
-" rdist [-nqbhirvwyD] [-P /path/to/rsh ] -c source [...] machine[:dest]");
- exit(1);
-}
-
-/*
- * rcp like interface for distributing files.
- */
-static void
-docmdargs(nargs, args)
- int nargs;
- char *args[];
-{
- register struct namelist *nl, *prev;
- register char *cp;
- struct namelist *files = NULL, *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 = index(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)
- register struct namelist *nl;
-{
- printf("( ");
- while (nl != NULL) {
- printf("%s ", nl->n_name);
- nl = nl->n_next;
- }
- printf(")\n");
-}
-
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-void
-#if __STDC__
-warn(const char *fmt, ...)
-#else
-warn(fmt, va_alist)
- char *fmt;
- va_dcl
-#endif
-{
- extern int yylineno;
- va_list ap;
-#if __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- (void)fprintf(stderr, "rdist: line %d: Warning: ", yylineno);
- (void)vfprintf(stderr, fmt, ap);
- (void)fprintf(stderr, "\n");
- va_end(ap);
-}
diff --git a/usr.bin/rdist/pathnames.h b/usr.bin/rdist/pathnames.h
deleted file mode 100644
index c772539..0000000
--- a/usr.bin/rdist/pathnames.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. 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.
- *
- * @(#)pathnames.h 8.1 (Berkeley) 6/9/93
- */
-
-#include <paths.h>
-
-#define _PATH_RDIST "rdist"
-#define _PATH_RSH "/usr/bin/rsh"
diff --git a/usr.bin/rdist/rshrcmd.c b/usr.bin/rdist/rshrcmd.c
deleted file mode 100644
index c747cc6..0000000
--- a/usr.bin/rdist/rshrcmd.c
+++ /dev/null
@@ -1,119 +0,0 @@
-
-/*
- * This is an rcmd() replacement originally by
- * Chris Siebenmann <cks@utcc.utoronto.ca>.
- */
-
-#ifndef lint
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-#include "defs.h"
-
-#if !defined(DIRECT_RCMD)
-
-#include <sys/socket.h>
-#include <sys/wait.h>
-#include <signal.h>
-#include <netdb.h>
-
-static char *
-xbasename(s)
- char *s;
-{
- char *ret;
-
- ret = strrchr(s, '/');
- if (ret && ret[1])
- return (ret + 1);
- return s;
-}
-
-
-/*
- * This is a replacement rcmd() function that uses the rsh(1c)
- * program in place of a direct rcmd() function call so as to
- * avoid having to be root.
- */
-int
-rshrcmd(ahost, port, luser, ruser, cmd, fd2p)
- char **ahost;
- u_short port;
- char *luser, *ruser, *cmd;
- int *fd2p;
-{
- int cpid;
- struct hostent *hp;
- int sp[2];
-
- /* insure that we are indeed being used as we thought. */
- if (fd2p != 0)
- return -1;
- /* validate remote hostname. */
- hp = gethostbyname(*ahost);
- if (hp == 0) {
- error("%s: unknown host", *ahost);
- return -1;
- }
- /* *ahost = hp->h_name; *//* This makes me nervous. */
-
- /* get a socketpair we'll use for stdin and stdout. */
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) < 0) {
- error("socketpair(AF_UNIX, SOCK_STREAM, 0) failed: %s.",
- strerror(errno));
- return -1;
- }
-
- cpid = fork();
- if (cpid < 0) {
- error("fork failed: %s.", strerror(errno));
- return -1; /* error. */
- }
- if (cpid == 0) {
- /* child. we use sp[1] to be stdin/stdout, and close
- sp[0]. */
- (void) close(sp[0]);
- if (dup2(sp[1], 0) < 0 || dup2(0,1) < 0) {
- error("dup2 failed: %s.", strerror(errno));
- _exit(255);
- }
- /* fork again to lose parent. */
- cpid = fork();
- if (cpid < 0) {
- error("fork to lose parent failed: %s.", strerror(errno));
- _exit(255);
- }
- if (cpid > 0)
- _exit(0);
- /* in grandchild here. */
-
- /*
- * If we are rdist'ing to "localhost" as the same user
- * as we are, then avoid running remote shell for efficiency.
- */
- if (strcmp(*ahost, "localhost") == 0 &&
- strcmp(luser, ruser) == 0) {
- execlp(_PATH_BSHELL, xbasename(_PATH_BSHELL), "-c",
- cmd, (char *) NULL);
- error("execlp %s failed: %s.", _PATH_BSHELL, strerror(errno));
- } else {
- execlp(path_rsh, xbasename(path_rsh),
- *ahost, "-l", ruser, cmd, (char *) NULL);
- error("execlp %s failed: %s.", path_rsh,
- strerror(errno));
- }
- _exit(255);
- }
- if (cpid > 0) {
- /* parent. close sp[1], return sp[0]. */
- (void) close(sp[1]);
- /* reap child. */
- (void) wait(0);
- return sp[0];
- }
- /*NOTREACHED*/
- return (-1);
-}
-
-#endif /* !DIRECT_RCMD */
diff --git a/usr.bin/rdist/server.c b/usr.bin/rdist/server.c
deleted file mode 100644
index b2ae4d3..0000000
--- a/usr.bin/rdist/server.c
+++ /dev/null
@@ -1,1634 +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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. 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.
- */
-
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)server.c 8.1 (Berkeley) 6/9/93";
-#endif
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-#include <sys/types.h>
-
-#include <sys/wait.h>
-#include "defs.h"
-
-#define ack() (void) write(rem, "\0\n", 2)
-#define err() (void) write(rem, "\1\n", 2)
-
-struct linkbuf *ihead = NULL; /* 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 __P((char *));
-static void clean __P((char *));
-static void comment __P((char *));
-static void dospecial __P((char *));
-static int fchog __P((int, char *, char *, char *, int));
-static void hardlink __P((char *));
-static void note __P((const char *, ...));
-static void query __P((char *));
-static void recvf __P((char *, int));
-static void removeit __P((struct stat *));
-static int response __P((void));
-static void rmchk __P((int));
-static struct linkbuf *
- savelink __P((struct stat *));
-static void sendf __P((char *, int));
-static int update __P((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];
- register 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));
-
- 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 */
- log(lfp, 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
- strcpy(source, src);
-
- 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 heirarchy (-w), we must strip off the leading
- * directory name and preserve the rest.
- */
- if (opts & WHOLE) {
- while (*rname == '/')
- rname++;
- destdir = 1;
- } else {
- rname = rindex(target, '/');
- if (rname == NULL)
- rname = target;
- else
- rname++;
- }
- 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))) {
- strcpy(destcopy, dest);
- 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;
-{
- register 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) {
- log(lfp, "%s: no password entry for uid %d \n",
- target, stb.st_uid);
- pw = NULL;
- (void)snprintf(user, sizeof(user), ":%lu", stb.st_uid);
- }
- if (gr == NULL || gr->gr_gid != stb.st_gid)
- if ((gr = getgrgid(stb.st_gid)) == NULL) {
- log(lfp, "%s: no name for group %d\n",
- target, stb.st_gid);
- gr = NULL;
- (void)snprintf(group, sizeof(group), ":%lu", stb.st_gid);
- }
- if (u == 1) {
- if (opts & VERIFY) {
- log(lfp, "need to install: %s\n", target);
- goto dospecial;
- }
- log(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, 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) {
- log(lfp, "need to update: %s\n", target);
- goto dospecial;
- }
- log(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)) < 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, 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;
- log(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)
- log(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;
- strcpy(lp->pathname, target);
- strcpy(lp->src, source);
- if (Tdest)
- strcpy(lp->target, Tdest);
- 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;
-{
- register char *cp, *s;
- register off_t size;
- register 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(2, s, cp - s);
- }
- if (lfp != NULL)
- (void) fwrite(s, 1, cp - s, lfp);
- }
- return(0);
-
- case '\3':
- *--cp = '\0';
- if (lfp != NULL)
- log(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) {
- log(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,
- 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;
-{
- register char *cp;
- int f = -1, mode, opts, 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;
-
- cp = cmd;
- opts = 0;
- 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 = rindex(target, '/');
- if (cp == NULL)
- strcpy(new, tempname);
- 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 - 1)) >= 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(0);
- 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 != -1) (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;
-{
- register char *cp;
- struct stat stb;
- char *oldname;
- int opts, exists = 0;
-
- cp = cmd;
- opts = 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;
-{
- register char *cp;
- struct stat stb;
-
- cp = rindex(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;
-{
- register int i;
- int uid, gid;
- extern char user[];
- extern int 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;
-{
- register 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')
- log(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(2, 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)
- register char *cp;
-{
- DIR *d;
- register 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;
- register 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, pid, i;
- register char *cp, *s;
- char sbuf[BUFSIZ];
- extern int userid, groupid;
-
- 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]);
- setgid(groupid);
- setuid(userid);
- execl(_PATH_BSHELL, "sh", "-c", cmd, 0);
- _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();
-}
-
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-void
-#if __STDC__
-log(FILE *fp, const char *fmt, ...)
-#else
-log(fp, fmt, va_alist)
- FILE *fp;
- char *fmt;
- va_dcl
-#endif
-{
- va_list ap;
-#if __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- /* 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
-#if __STDC__
-error(const char *fmt, ...)
-#else
-error(fmt, va_alist)
- char *fmt;
- va_dcl
-#endif
-{
- static FILE *fp;
- va_list ap;
-#if __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
-
- ++nerrs;
- if (!fp && !(fp = fdopen(rem, "w")))
- return;
- if (iamremote) {
- (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
-#if __STDC__
-fatal(const char *fmt, ...)
-#else
-fatal(fmt, va_alist)
- char *fmt;
- va_dcl
-#endif
-{
- static FILE *fp;
- va_list ap;
-#if __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
-
- ++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);
- }
- 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') {
- log(lfp, "%s\n", s);
- return(1);
- }
- return(0);
- case '\3':
- *--cp = '\0';
- log(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(2, 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
-#if __STDC__
-note(const char *fmt, ...)
-#else
-note(fmt, va_alist)
- char *fmt;
- va_dcl
-#endif
-{
- static char buf[BUFSIZ];
- va_list ap;
-#if __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- (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);
-}
OpenPOWER on IntegriCloud