BSD 4_4 release
[unix-history] / usr / src / usr.bin / rdist / main.c
index 31e73d9..44b3279 100644 (file)
@@ -1,17 +1,58 @@
+/*
+ * 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
 #ifndef lint
-static char *sccsid = "@(#)main.c      4.8 (Berkeley) 83/11/01";
-#endif
+static char copyright[] =
+"@(#) Copyright (c) 1983, 1993\n\
+       The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)main.c     8.1 (Berkeley) 6/9/93";
+#endif /* not lint */
 
 #include "defs.h"
 
 
 #include "defs.h"
 
+#define NHOSTS 100
+
 /*
  * Remote distribution program.
  */
 
 /*
  * Remote distribution program.
  */
 
-char   *distfile = "distfile";
-char   tmpfile[] = "/tmp/rdistAXXXXXX";
-char   *tmpname = &tmpfile[5];
-char   *tmpinc = &tmpfile[10];
+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    debug;          /* debugging flag */
 int    nflag;          /* NOP flag, just print commands without executing */
@@ -19,12 +60,10 @@ int qflag;          /* Quiet. Don't print messages */
 int    options;        /* global options */
 int    iamremote;      /* act as remote server for transfering files */
 
 int    options;        /* global options */
 int    iamremote;      /* act as remote server for transfering files */
 
-int    filec;          /* number of files to update */
-char   **filev;        /* list of files/directories to update */
 FILE   *fin = NULL;    /* input file pointer */
 FILE   *fin = NULL;    /* input file pointer */
-int    rem = 0;        /* file descriptor to remote source/sink process */
+int    rem = -1;       /* file descriptor to remote source/sink process */
 char   host[32];       /* host name */
 char   host[32];       /* host name */
-int    errs;           /* number of errors while sending/receiving */
+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 */
 char   user[10];       /* user's name */
 char   homedir[128];   /* user's home directory */
 int    userid;         /* user's user ID */
@@ -33,15 +72,17 @@ int groupid;        /* user's group ID */
 struct passwd *pw;     /* pointer to static area used by getpwent */
 struct group *gr;      /* pointer to static area used by getgrent */
 
 struct passwd *pw;     /* pointer to static area used by getpwent */
 struct group *gr;      /* pointer to static area used by getgrent */
 
-int    cleanup();
-int    lostconn();
+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;
 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) {
 
        pw = getpwuid(userid = getuid());
        if (pw == NULL) {
@@ -52,6 +93,12 @@ main(argc, argv)
        strcpy(homedir, pw->pw_dir);
        groupid = pw->pw_gid;
        gethostname(host, sizeof(host));
        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] != '-')
 
        while (--argc > 0) {
                if ((arg = *++argv)[0] != '-')
@@ -68,6 +115,16 @@ main(argc, argv)
                                        fin = stdin;
                                break;
 
                                        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();
                        case 'd':
                                if (--argc <= 0)
                                        usage();
@@ -83,6 +140,10 @@ main(argc, argv)
                                break;
 
                        case 'n':
                                break;
 
                        case 'n':
+                               if (options & VERIFY) {
+                                       printf("rdist: -n overrides -v\n");
+                                       options &= ~VERIFY;
+                               }
                                nflag++;
                                break;
 
                                nflag++;
                                break;
 
@@ -94,11 +155,15 @@ main(argc, argv)
                                options |= COMPARE;
                                break;
 
                                options |= COMPARE;
                                break;
 
-                       case 'r':
+                       case 'R':
                                options |= REMOVE;
                                break;
 
                        case 'v':
                                options |= REMOVE;
                                break;
 
                        case 'v':
+                               if (nflag) {
+                                       printf("rdist: -n overrides -v\n");
+                                       break;
+                               }
                                options |= VERIFY;
                                break;
 
                                options |= VERIFY;
                                break;
 
@@ -110,91 +175,102 @@ main(argc, argv)
                                options |= YOUNGER;
                                break;
 
                                options |= YOUNGER;
                                break;
 
+                       case 'h':
+                               options |= FOLLOW;
+                               break;
+
+                       case 'i':
+                               options |= IGNLNKS;
+                               break;
+
                        default:
                                usage();
                        }
        }
                        default:
                                usage();
                        }
        }
+       *hp = NULL;
+
+       seteuid(userid);
+       mktemp(tempfile);
 
 
-       mktemp(tmpfile);
-       signal(SIGPIPE, lostconn);
        if (iamremote) {
                server();
        if (iamremote) {
                server();
-               exit(errs);
+               exit(nerrs != 0);
        }
 
        }
 
-       signal(SIGHUP, cleanup);
-       signal(SIGINT, cleanup);
-       signal(SIGQUIT, cleanup);
-       signal(SIGTERM, cleanup);
-
        if (cmdargs)
                docmdargs(argc, argv);
        else {
        if (cmdargs)
                docmdargs(argc, argv);
        else {
-               filec = argc;
-               filev = argv;
-               if (fin == NULL && (fin = fopen(distfile, "r")) == NULL) {
-                       perror(distfile);
-                       exit(1);
+               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();
                }
                yyparse();
+               if (nerrs == 0)
+                       docmds(dhosts, argc, argv);
        }
 
        }
 
-       exit(errs);
+       exit(nerrs != 0);
 }
 
 }
 
+static void
 usage()
 {
 usage()
 {
-       printf("Usage: rdist [-nqbrvwyD] [-f distfile] [-d var=value] [file ...]\n");
-       printf("or: rdist [-nqbrvwyD] -c source [...] machine[:dest]\n");
+       printf("Usage: rdist [-nqbhirvwyD] [-f distfile] [-d var=value] [-m host] [file ...]\n");
+       printf("or: rdist [-nqbhirvwyD] -c source [...] machine[:dest]\n");
        exit(1);
 }
 
 /*
  * rcp like interface for distributing files.
  */
        exit(1);
 }
 
 /*
  * rcp like interface for distributing files.
  */
+static void
 docmdargs(nargs, args)
        int nargs;
        char *args[];
 {
 docmdargs(nargs, args)
        int nargs;
        char *args[];
 {
-       struct block *bp, *files, *hosts, *cmds, *prev;
+       register struct namelist *nl, *prev;
+       register char *cp;
+       struct namelist *files, *hosts;
+       struct subcmd *cmds;
+       char *dest;
+       static struct namelist tnl = { NULL, NULL };
        int i;
        int i;
-       char *pos, dest[BUFSIZ];
 
        if (nargs < 2)
                usage();
 
        prev = NULL;
 
        if (nargs < 2)
                usage();
 
        prev = NULL;
-       bp = files = ALLOC(block);
-       for (i = 0; i < nargs - 1; bp = ALLOC(block), i++) {
-               bp->b_type = NAME;
-               bp->b_name = args[i];
-               if (prev != NULL)
-                       prev->b_next = bp;
-               bp->b_next = bp->b_args = NULL;
-               prev = bp;
+       for (i = 0; i < nargs - 1; i++) {
+               nl = makenl(args[i]);
+               if (prev == NULL)
+                       files = prev = nl;
+               else {
+                       prev->n_next = nl;
+                       prev = nl;
+               }
        }
 
        }
 
-       hosts = ALLOC(block);
-       hosts->b_type = NAME;
-       hosts->b_name = args[i];
-       hosts->b_name = args[i];
-       hosts->b_next = hosts->b_args = NULL;
-       if ((pos = index(hosts->b_name, ':')) != NULL) {
-               *pos++ = '\0';
-               strcpy(dest, pos);
-       } else
-               dest[0] = '\0';
-
-       hosts = expand(hosts, 0);
+       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[0] == '\0')
+       if (dest == NULL || *dest == '\0')
                cmds = NULL;
        else {
                cmds = NULL;
        else {
-               cmds = ALLOC(block);
-               cmds->b_type = INSTALL;
-               cmds->b_options = options;
-               cmds->b_name = dest;
-               cmds->b_next = cmds->b_args = NULL;
+               cmds = makesubcmd(INSTALL);
+               cmds->sc_options = options;
+               cmds->sc_name = dest;
        }
 
        if (debug) {
        }
 
        if (debug) {
@@ -203,42 +279,49 @@ docmdargs(nargs, args)
                printf("hosts = ");
                prnames(hosts);
        }
                printf("hosts = ");
                prnames(hosts);
        }
-       dohcmds(files, hosts, cmds);
-}
-
-/*
- * Remove temporary files and do any cleanup operations before exiting.
- */
-cleanup()
-{
-       do {
-               (void) unlink(tmpfile);
-               (*tmpinc)--;
-       } while (*tmpinc >= 'A');
-       exit(1);
+       insert(NULL, files, hosts, cmds);
+       docmds(NULL, 0, NULL);
 }
 
 /*
  * Print a list of NAME blocks (mostly for debugging).
  */
 }
 
 /*
  * Print a list of NAME blocks (mostly for debugging).
  */
-prnames(bp)
-       register struct block *bp;
+void
+prnames(nl)
+       register struct namelist *nl;
 {
        printf("( ");
 {
        printf("( ");
-       while (bp != NULL) {
-               printf("%s ", bp->b_name);
-               bp = bp->b_next;
+       while (nl != NULL) {
+               printf("%s ", nl->n_name);
+               nl = nl->n_next;
        }
        printf(")\n");
 }
 
        }
        printf(")\n");
 }
 
-/*VARARGS*/
-warn(fmt, a1, a2,a3)
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+void
+#if __STDC__
+warn(const char *fmt, ...)
+#else
+warn(fmt, va_alist)
        char *fmt;
        char *fmt;
+        va_dcl
+#endif
 {
        extern int yylineno;
 {
        extern int yylineno;
-
-       fprintf(stderr, "rdist: line %d: Warning: ", yylineno);
-       fprintf(stderr, fmt, a1, a2, a3);
-       fputc('\n', stderr);
+       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);
 }
 }