From 024fde5b7acb80896574ef506eebe08594fd3c15 Mon Sep 17 00:00:00 2001 From: Ralph Campbell Date: Wed, 26 Oct 1983 19:42:50 -0800 Subject: [PATCH] added -b option for binary compare. Fixed -r w/ except. SCCS-vsn: usr.bin/rdist/defs.h 4.6 SCCS-vsn: usr.bin/rdist/docmd.c 4.6 SCCS-vsn: usr.bin/rdist/gram.y 4.6 SCCS-vsn: usr.bin/rdist/main.c 4.7 SCCS-vsn: usr.bin/rdist/server.c 4.6 --- usr/src/usr.bin/rdist/defs.h | 7 +- usr/src/usr.bin/rdist/docmd.c | 57 ++++++++--- usr/src/usr.bin/rdist/gram.y | 11 +- usr/src/usr.bin/rdist/main.c | 10 +- usr/src/usr.bin/rdist/server.c | 182 ++++++++++++++++++++------------- 5 files changed, 174 insertions(+), 93 deletions(-) diff --git a/usr/src/usr.bin/rdist/defs.h b/usr/src/usr.bin/rdist/defs.h index 2ee3d1e33d..1f62f5d232 100644 --- a/usr/src/usr.bin/rdist/defs.h +++ b/usr/src/usr.bin/rdist/defs.h @@ -1,4 +1,4 @@ -/* defs.h 4.5 83/10/20 */ +/* defs.h 4.6 83/10/26 */ #include #include @@ -43,8 +43,9 @@ #define VERIFY 0x1 #define WHOLE 0x2 #define YOUNGER 0x4 -#define STRIP 0x8 -#define REMOVE 0x10 +#define COMPARE 0x8 +#define STRIP 0x10 +#define REMOVE 0x20 #define ISDIR(m) (((m) & S_IFMT) == S_IFDIR) diff --git a/usr/src/usr.bin/rdist/docmd.c b/usr/src/usr.bin/rdist/docmd.c index f9c4b73959..e1037ab2b9 100644 --- a/usr/src/usr.bin/rdist/docmd.c +++ b/usr/src/usr.bin/rdist/docmd.c @@ -1,5 +1,5 @@ #ifndef lint -static char *sccsid = "@(#)docmd.c 4.5 (Berkeley) 83/10/20"; +static char *sccsid = "@(#)docmd.c 4.6 (Berkeley) 83/10/26"; #endif #include "defs.h" @@ -14,19 +14,45 @@ dohcmds(files, hosts, cmds) { register struct block *h, *f, *c; register char **cpp; + static struct block excpt = { EXCEPT }; + char *cp; int n, ddir; if (debug) printf("dohcmds(%x, %x, %x)\n", files, hosts, cmds); files = expand(files, 0); + if (files == NULL) { + error("no files to be updated\n"); + return; + } hosts = expand(hosts, 1); - if (files == NULL) - fatal("no files to be updated\n"); - if (hosts == NULL) - fatal("empty list of hosts to be updated\n"); - except = cmds; + if (hosts == NULL) { + error("empty list of hosts to be updated\n"); + return; + } ddir = files->b_next != NULL; + f = NULL; + except = NULL; + for (c = cmds; c != NULL; c = c->b_next) { + if (c->b_type != EXCEPT) + continue; + if (except == NULL) + except = &excpt; + for (h = c->b_args; h != NULL; h = h->b_next) { + cp = h->b_name; + if (*cp == '~') { + (void) exptilde(buf, cp); + cp = buf; + } + if (f == NULL) + except->b_args = f = expand(makeblock(NAME, cp), 0); + else { + f->b_next = expand(makeblock(NAME, cp), 0); + f = f->b_next; + } + } + } for (h = hosts; h != NULL; h = h->b_next) { if (!qflag) @@ -44,9 +70,8 @@ dohcmds(files, hosts, cmds) for (cpp = filev; *cpp; cpp++) if (!strcmp(f->b_name, *cpp)) goto found; - if (!nflag) { + if (!nflag) (void) fclose(lfp); - } continue; } found: @@ -83,6 +108,7 @@ dohcmds(files, hosts, cmds) makeconn(rhost) char *rhost; { + register struct block *c; register char *ruser; extern char user[]; @@ -127,9 +153,10 @@ install(src, dest, destdir, opts) return; if (nflag || debug) { - printf("%s%s%s%s %s %s\n", opts & VERIFY ? "verify":"install", + 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; @@ -178,11 +205,15 @@ dofcmds(files, stamps, cmds) printf("dofcmds()\n"); files = expand(files, 0); + if (files == NULL){ + error("no files to be updated\n"); + return; + } stamps = expand(stamps, 0); - if (files == NULL) - fatal("no files to be updated\n"); - if (stamps == NULL) - fatal("empty time stamp file list\n"); + if (stamps == NULL) { + error("empty time stamp file list\n"); + return; + } except = cmds; t = ts; diff --git a/usr/src/usr.bin/rdist/gram.y b/usr/src/usr.bin/rdist/gram.y index ee73c995b7..172cbbbc3c 100644 --- a/usr/src/usr.bin/rdist/gram.y +++ b/usr/src/usr.bin/rdist/gram.y @@ -1,6 +1,6 @@ %{ #ifndef lint -static char *sccsid = "@(#)gram.y 4.5 (Berkeley) 83/10/20"; +static char *sccsid = "@(#)gram.y 4.6 (Berkeley) 83/10/26"; #endif #include "defs.h" @@ -93,7 +93,7 @@ cmd: INSTALL options opt_name SM = { if ($3 != NULL) { b = expand($3, 0); if (b->b_next != NULL) - fatal("exactly one name allowed\n"); + yyerror("only one name allowed\n"); $1->b_name = b->b_name; } $$ = $1; @@ -103,7 +103,7 @@ cmd: INSTALL options opt_name SM = { $$ = $1; } | EXCEPT namelist SM = { - $1->b_args = expand($2, 0); + $1->b_args = $2; $$ = $1; } ; @@ -203,6 +203,10 @@ again: *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); @@ -251,5 +255,6 @@ yyerror(s) extern int yychar; errs++; + fflush(stdout); fprintf(stderr, "rdist: line %d: %s\n", yylineno, s); } diff --git a/usr/src/usr.bin/rdist/main.c b/usr/src/usr.bin/rdist/main.c index faa120b2e4..dc8bc82dcc 100644 --- a/usr/src/usr.bin/rdist/main.c +++ b/usr/src/usr.bin/rdist/main.c @@ -1,5 +1,5 @@ #ifndef lint -static char *sccsid = "@(#)main.c 4.6 (Berkeley) 83/10/20"; +static char *sccsid = "@(#)main.c 4.7 (Berkeley) 83/10/26"; #endif #include "defs.h" @@ -88,6 +88,10 @@ main(argc, argv) qflag++; break; + case 'b': + options |= COMPARE; + break; + case 'r': options |= REMOVE; break; @@ -138,8 +142,8 @@ main(argc, argv) usage() { - printf("Usage: rdist [-nqvwyD] [-f distfile] [-d var=value] [file ...]\n"); - printf("or: rdist [-nqvwyD] -c source [...] machine[:dest]\n"); + printf("Usage: rdist [-nqbrvwyD] [-f distfile] [-d var=value] [file ...]\n"); + printf("or: rdist [-nqbrvwyD] -c source [...] machine[:dest]\n"); exit(1); } diff --git a/usr/src/usr.bin/rdist/server.c b/usr/src/usr.bin/rdist/server.c index 33a0acd60f..6f328a90a5 100644 --- a/usr/src/usr.bin/rdist/server.c +++ b/usr/src/usr.bin/rdist/server.c @@ -1,10 +1,10 @@ #ifndef lint -static char *sccsid = "@(#)server.c 4.5 (Berkeley) 83/10/20"; +static char *sccsid = "@(#)server.c 4.6 (Berkeley) 83/10/26"; #endif #include "defs.h" -#define ga() (void) write(rem, "", 1) +#define ga() (void) write(rem, "\0\n", 2) char buf[BUFSIZ]; /* general purpose buffer */ char target[BUFSIZ]; /* target/source directory name */ @@ -32,7 +32,6 @@ server() char cmdbuf[BUFSIZ]; register char *cp; register struct block *bp, *last = NULL; - static struct block cmdblk = { EXCEPT }; int opts; sumask = umask(0); @@ -56,19 +55,15 @@ server() case 'X': /* add name to list of files to exclude */ if (*cp == '\0') continue; - bp = ALLOC(block); - if (bp == NULL) - fatal("ran out of memory\n"); - bp->b_type = NAME; - bp->b_next = bp->b_args = NULL; - bp->b_name = cp = malloc(strlen(cp) + 1); - if (cp == NULL) - fatal("ran out of memory\n"); - strcpy(cp, &cmdbuf[1]); - if (last == NULL) { - except = &cmdblk; - cmdblk.b_args = last = bp; - } else { + if (*cp == '~') { + exptilde(buf, cp); + cp = buf; + } + bp = makeblock(EXCEPT); + bp->b_args = expand(makeblock(NAME, cp), 0); + if (last == NULL) + except = last = bp; + else { last->b_next = bp; last = bp; } @@ -170,9 +165,6 @@ sendf(lname, rname, opts) printf("sendf(%s, %s, %x)\n", lname, rname != NULL ? rname : "NULL", opts); - if (exclude(lname)) - return; - /* * First time sendf() is called? */ @@ -203,6 +195,8 @@ sendf(lname, rname, opts) rname++; } } + if (exclude(lname)) + return; if (access(lname, 4) < 0 || stat(lname, &stb) < 0) { error("%s: %s\n", lname, sys_errlist[errno]); return; @@ -212,14 +206,22 @@ sendf(lname, rname, opts) if (p == NULL || p->pw_uid != stb.st_uid) if ((p = getpwuid(stb.st_uid)) == NULL) { - error("no password entry for uid %d\n", stb.st_uid); + error("%s: no password entry for uid %d\n", + lname, stb.st_uid); return; } if (g == NULL || g->gr_gid != stb.st_gid) if ((g = getgrgid(stb.st_gid)) == NULL) { - error("no name for group %d\n", stb.st_gid); + error("%s: no name for group %d\n", + lname, stb.st_gid); return; } + if (u == 1) { + log(lfp, "installing: %s\n", lname); + if (opts & VERIFY) + return; + opts &= ~COMPARE; + } switch (stb.st_mode & S_IFMT) { case S_IFREG: @@ -234,16 +236,17 @@ sendf(lname, rname, opts) return; } - log(lfp, "%s: %s\n", u == 2 ? "updating" : "installing", lname); - - if (opts & VERIFY) - return; + if (u == 2) { + log(lfp, "updating: %s\n", lname); + if (opts & VERIFY) + return; + } if ((f = open(lname, 0)) < 0) { error("%s: %s\n", lname, sys_errlist[errno]); return; } - (void) sprintf(buf, "R%1o %04o %D %D %s %s %s\n", opts, + (void) sprintf(buf, "R%o %04o %D %D %s %s %s\n", opts, stb.st_mode & 07777, stb.st_size, stb.st_mtime, p->pw_name, g->gr_name, rname); if (debug) @@ -289,7 +292,7 @@ rsendf(lname, rname, opts, st, owner, group) error("%s: %s\n", lname, sys_errlist[errno]); return; } - (void) sprintf(buf, "D%1o %04o 0 0 %s %s %s\n", opts, + (void) sprintf(buf, "D%o %04o 0 0 %s %s %s\n", opts, st->st_mode & 07777, owner, group, rname); if (debug) printf("buf = %s", buf); @@ -379,6 +382,9 @@ update(lname, rname, opts, st) if (*cp == '\n') return(2); + if (opts & COMPARE) + return(3); + size = 0; while (isdigit(*cp)) size = size * 10 + (*cp++ - '0'); @@ -417,6 +423,7 @@ update(lname, rname, opts, st) */ query(name, isdir) char *name; + int isdir; { struct stat stb; @@ -460,7 +467,7 @@ recvf(cmd, isdir) int isdir; { register char *cp; - int f, mode, opts, wrerr, olderrno; + int f, mode, opts, wrerr, olderrno, u; off_t i, size; time_t mtime; struct stat stb; @@ -469,25 +476,17 @@ recvf(cmd, isdir) char new[BUFSIZ]; extern char *tmpname; - cp = cmd; - if (*cp < '0' || *cp > '7') { - error("bad options\n"); - return; - } - opts = *cp++ - '0'; + opts = 0; + while (*cp >= '0' && *cp <= '7') + opts = (opts << 3) | (*cp++ - '0'); if (*cp++ != ' ') { error("options not delimited\n"); return; } mode = 0; - while (cp < cmd+6) { - if (*cp < '0' || *cp > '7') { - error("bad mode\n"); - return; - } + while (*cp >= '0' && *cp <= '7') mode = (mode << 3) | (*cp++ - '0'); - } if (*cp++ != ' ') { error("mode not delimited\n"); return; @@ -574,7 +573,9 @@ recvf(cmd, isdir) error("%s: not a regular file\n", target); return; } - } + u = 2; + } else + u = 1; if (chkparent(target) < 0) goto bad; cp = rindex(target, '/'); @@ -625,20 +626,44 @@ recvf(cmd, isdir) wrerr++; } } + (void) close(f); (void) response(); if (wrerr) { error("%s: %s\n", cp, sys_errlist[olderrno]); - (void) close(f); (void) unlink(new); return; } + if (opts & COMPARE) { + FILE *f1, *f2; + int c; + + if ((f1 = fopen(target, "r")) == NULL) + goto bad; + if ((f2 = fopen(new, "r")) == NULL) + goto bad1; + while ((c = getc(f1)) == getc(f2)) + if (c == EOF) { + (void) fclose(f1); + (void) fclose(f2); + (void) unlink(new); + ga(); + return; + } + (void) fclose(f1); + (void) fclose(f2); + if (opts & VERIFY) { + (void) unlink(new); + buf[0] = '\0'; + sprintf(buf + 1, "updating %s:%s\n", host, target); + (void) write(rem, buf, strlen(buf + 1) + 1); + return; + } + } /* * Set last modified time */ - (void) fstat(f, &stb); - (void) close(f); - tvp[0].tv_sec = stb.st_atime; + tvp[0].tv_sec = stb.st_atime; /* old accessed time from target */ tvp[0].tv_usec = 0; tvp[1].tv_sec = mtime; tvp[1].tv_usec = 0; @@ -657,7 +682,12 @@ bad: (void) unlink(new); return; } - ga(); + if (opts & COMPARE) { + buf[0] = '\0'; + sprintf(buf + 1, "updated %s:%s\n", host, target); + (void) write(rem, buf, strlen(buf + 1) + 1); + } else + ga(); } /* @@ -772,9 +802,6 @@ rmchk(lname, rname, opts) printf("rmchk(%s, %s, %x)\n", lname, rname != NULL ? rname : "NULL", opts); - if (exclude(lname)) - return; - /* * First time rmchk() is called? */ @@ -805,14 +832,15 @@ rmchk(lname, rname, opts) rname++; } } - if (debug) - printf("lname = %s, rname = %s\n", lname, rname); + if (exclude(lname)) + return; if (access(lname, 4) < 0 || stat(lname, &stb) < 0) { error("%s: %s\n", lname, sys_errlist[errno]); return; } if (!ISDIR(stb.st_mode)) return; + /* * Tell the remote to clean the files from the last directory sent. */ @@ -830,17 +858,23 @@ rmchk(lname, rname, opts) lostconn(); } while (*cp++ != '\n' && cp < &buf[BUFSIZ]); - if (debug) { - printf("readbuf = "); - fwrite(buf, 1, cp - buf, stdout); - } switch (buf[0]) { case 'Q': /* its a directory on the remote end */ case 'q': /* its a regular file on the remote end */ + /* + * Return the following codes to remove query. + * N\n -- file does not exisit, remove. + * Y\n -- file exists and is a directory. + * y\n -- file exists and is a regular file. + */ *--cp = '\0'; (void) sprintf(tp, "/%s", buf + 1); if (debug) printf("check %s\n", target); + if (exclude(target)) { + (void) write(rem, "y\n", 2); + break; + } if (stat(target, &stb) < 0) (void) write(rem, "N\n", 2); else if (buf[0] == 'Q' && ISDIR(stb.st_mode)) { @@ -870,7 +904,7 @@ rmchk(lname, rname, opts) case '\0': *--cp = '\0'; - if (buf[1]) + if (buf[1] != '\0') log(lfp, "%s\n", buf + 1); break; @@ -896,7 +930,8 @@ rmchk(lname, rname, opts) } /* - * Check the directory for extraneous files and remove them. + * Check the directory initialized by the 'T' command to server() + * for extraneous files and remove them. */ clean(lname, opts, first) char *lname; @@ -938,6 +973,7 @@ clean(lname, opts, first) goto done; } } + if (access(target, 6) < 0 || (d = opendir(target)) == NULL) goto bad; ga(); @@ -1102,37 +1138,39 @@ fatal(fmt, a1, a2,a3) response() { - char resp, *cp = buf; + char *cp, *s; if (debug) printf("response()\n"); - if (read(rem, &resp, 1) != 1) - lostconn(); + cp = s = buf; + do { + if (read(rem, cp, 1) != 1) + lostconn(); + } while (*cp++ != '\n' && cp < &buf[BUFSIZ]); - switch (resp) { + switch (*s++) { case '\0': + *--cp = '\0'; + if (*s != '\0') + log(lfp, "%s\n", s); return(0); default: - *cp++ = resp; + s--; /* fall into... */ case '\1': case '\2': errs++; - do { - if (read(rem, cp, 1) != 1) - lostconn(); - } while (*cp++ != '\n' && cp < &buf[BUFSIZ]); - if (buf[0] != '\n') { + if (*s != '\n') { if (!iamremote) { fflush(stdout); - (void) write(2, buf, cp - buf); + (void) write(2, s, cp - s); } if (lfp != NULL) - (void) fwrite(buf, 1, cp - buf, lfp); + (void) fwrite(s, 1, cp - s, lfp); } - if (resp == '\1') + if (buf[0] == '\1') return(-1); cleanup(); } @@ -1141,7 +1179,9 @@ response() lostconn() { - if (!iamremote) + if (!iamremote) { + fflush(stdout); fprintf(stderr, "rdist: lost connection\n"); + } cleanup(); } -- 2.20.1