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
-/* defs.h 4.5 83/10/20 */
+/* defs.h 4.6 83/10/26 */
#include <stdio.h>
#include <ctype.h>
#include <stdio.h>
#include <ctype.h>
#define VERIFY 0x1
#define WHOLE 0x2
#define YOUNGER 0x4
#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)
#define ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-static char *sccsid = "@(#)docmd.c 4.5 (Berkeley) 83/10/20";
+static char *sccsid = "@(#)docmd.c 4.6 (Berkeley) 83/10/26";
{
register struct block *h, *f, *c;
register char **cpp;
{
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);
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);
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;
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)
for (h = hosts; h != NULL; h = h->b_next) {
if (!qflag)
for (cpp = filev; *cpp; cpp++)
if (!strcmp(f->b_name, *cpp))
goto found;
for (cpp = filev; *cpp; cpp++)
if (!strcmp(f->b_name, *cpp))
goto found;
makeconn(rhost)
char *rhost;
{
makeconn(rhost)
char *rhost;
{
+ register struct block *c;
register char *ruser;
extern char user[];
register char *ruser;
extern char user[];
return;
if (nflag || debug) {
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 & WHOLE ? " -w" : "",
opts & YOUNGER ? " -y" : "",
+ opts & COMPARE ? " -b" : "",
opts & REMOVE ? " -r" : "", src, dest);
if (nflag)
return;
opts & REMOVE ? " -r" : "", src, dest);
if (nflag)
return;
printf("dofcmds()\n");
files = expand(files, 0);
printf("dofcmds()\n");
files = expand(files, 0);
+ if (files == NULL){
+ error("no files to be updated\n");
+ return;
+ }
stamps = expand(stamps, 0);
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;
+ }
-static char *sccsid = "@(#)gram.y 4.5 (Berkeley) 83/10/20";
+static char *sccsid = "@(#)gram.y 4.6 (Berkeley) 83/10/26";
if ($3 != NULL) {
b = expand($3, 0);
if (b->b_next != NULL)
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;
$1->b_name = b->b_name;
}
$$ = $1;
$$ = $1;
}
| EXCEPT namelist SM = {
$$ = $1;
}
| EXCEPT namelist SM = {
- $1->b_args = expand($2, 0);
*cp1 = '\0';
if (yytext[0] == '-' && yytext[2] == '\0') {
switch (yytext[1]) {
*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 'r':
yylval.intval = REMOVE;
return(OPTION);
extern int yychar;
errs++;
extern int yychar;
errs++;
fprintf(stderr, "rdist: line %d: %s\n", yylineno, s);
}
fprintf(stderr, "rdist: line %d: %s\n", yylineno, s);
}
-static char *sccsid = "@(#)main.c 4.6 (Berkeley) 83/10/20";
+static char *sccsid = "@(#)main.c 4.7 (Berkeley) 83/10/26";
+ case 'b':
+ options |= COMPARE;
+ break;
+
case 'r':
options |= REMOVE;
break;
case 'r':
options |= REMOVE;
break;
- 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");
-static char *sccsid = "@(#)server.c 4.5 (Berkeley) 83/10/20";
+static char *sccsid = "@(#)server.c 4.6 (Berkeley) 83/10/26";
-#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 */
char buf[BUFSIZ]; /* general purpose buffer */
char target[BUFSIZ]; /* target/source directory name */
char cmdbuf[BUFSIZ];
register char *cp;
register struct block *bp, *last = NULL;
char cmdbuf[BUFSIZ];
register char *cp;
register struct block *bp, *last = NULL;
- static struct block cmdblk = { EXCEPT };
int opts;
sumask = umask(0);
int opts;
sumask = umask(0);
case 'X': /* add name to list of files to exclude */
if (*cp == '\0')
continue;
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;
}
last->b_next = bp;
last = bp;
}
printf("sendf(%s, %s, %x)\n", lname,
rname != NULL ? rname : "NULL", opts);
printf("sendf(%s, %s, %x)\n", lname,
rname != NULL ? rname : "NULL", opts);
- if (exclude(lname))
- return;
-
/*
* First time sendf() is called?
*/
/*
* First time sendf() is called?
*/
+ if (exclude(lname))
+ return;
if (access(lname, 4) < 0 || stat(lname, &stb) < 0) {
error("%s: %s\n", lname, sys_errlist[errno]);
return;
if (access(lname, 4) < 0 || stat(lname, &stb) < 0) {
error("%s: %s\n", lname, sys_errlist[errno]);
return;
if (p == NULL || p->pw_uid != stb.st_uid)
if ((p = getpwuid(stb.st_uid)) == NULL) {
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) {
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);
+ if (u == 1) {
+ log(lfp, "installing: %s\n", lname);
+ if (opts & VERIFY)
+ return;
+ opts &= ~COMPARE;
+ }
switch (stb.st_mode & S_IFMT) {
case S_IFREG:
switch (stb.st_mode & S_IFMT) {
case S_IFREG:
- 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;
}
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)
stb.st_mode & 07777, stb.st_size, stb.st_mtime,
p->pw_name, g->gr_name, rname);
if (debug)
error("%s: %s\n", lname, sys_errlist[errno]);
return;
}
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);
st->st_mode & 07777, owner, group, rname);
if (debug)
printf("buf = %s", buf);
if (*cp == '\n')
return(2);
if (*cp == '\n')
return(2);
+ if (opts & COMPARE)
+ return(3);
+
size = 0;
while (isdigit(*cp))
size = size * 10 + (*cp++ - '0');
size = 0;
while (isdigit(*cp))
size = size * 10 + (*cp++ - '0');
*/
query(name, isdir)
char *name;
*/
query(name, isdir)
char *name;
int isdir;
{
register char *cp;
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;
off_t i, size;
time_t mtime;
struct stat stb;
char new[BUFSIZ];
extern char *tmpname;
char new[BUFSIZ];
extern char *tmpname;
- 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;
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');
mode = (mode << 3) | (*cp++ - '0');
if (*cp++ != ' ') {
error("mode not delimited\n");
return;
if (*cp++ != ' ') {
error("mode not delimited\n");
return;
error("%s: not a regular file\n", target);
return;
}
error("%s: not a regular file\n", target);
return;
}
+ u = 2;
+ } else
+ u = 1;
if (chkparent(target) < 0)
goto bad;
cp = rindex(target, '/');
if (chkparent(target) < 0)
goto bad;
cp = rindex(target, '/');
(void) response();
if (wrerr) {
error("%s: %s\n", cp, sys_errlist[olderrno]);
(void) response();
if (wrerr) {
error("%s: %s\n", cp, sys_errlist[olderrno]);
(void) unlink(new);
return;
}
(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
*/
/*
* 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;
tvp[0].tv_usec = 0;
tvp[1].tv_sec = mtime;
tvp[1].tv_usec = 0;
(void) unlink(new);
return;
}
(void) unlink(new);
return;
}
+ 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();
printf("rmchk(%s, %s, %x)\n", lname,
rname != NULL ? rname : "NULL", opts);
printf("rmchk(%s, %s, %x)\n", lname,
rname != NULL ? rname : "NULL", opts);
- if (exclude(lname))
- return;
-
/*
* First time rmchk() is called?
*/
/*
* First time rmchk() is called?
*/
- 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;
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.
*/
/*
* Tell the remote to clean the files from the last directory sent.
*/
lostconn();
} while (*cp++ != '\n' && cp < &buf[BUFSIZ]);
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 */
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);
*--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)) {
if (stat(target, &stb) < 0)
(void) write(rem, "N\n", 2);
else if (buf[0] == 'Q' && ISDIR(stb.st_mode)) {
log(lfp, "%s\n", buf + 1);
break;
log(lfp, "%s\n", buf + 1);
break;
- * 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;
*/
clean(lname, opts, first)
char *lname;
if (access(target, 6) < 0 || (d = opendir(target)) == NULL)
goto bad;
ga();
if (access(target, 6) < 0 || (d = opendir(target)) == NULL)
goto bad;
ga();
if (debug)
printf("response()\n");
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]);
+ *--cp = '\0';
+ if (*s != '\0')
+ log(lfp, "%s\n", s);
/* fall into... */
case '\1':
case '\2':
errs++;
/* 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 (!iamremote) {
fflush(stdout);
if (!iamremote) {
fflush(stdout);
- (void) write(2, buf, cp - buf);
+ (void) write(2, s, cp - s);
- (void) fwrite(buf, 1, cp - buf, lfp);
+ (void) fwrite(s, 1, cp - s, lfp);
+ if (!iamremote) {
+ fflush(stdout);
fprintf(stderr, "rdist: lost connection\n");
fprintf(stderr, "rdist: lost connection\n");