diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2003-05-14 01:34:36 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2003-05-14 01:34:36 +0000 |
commit | 78d690b47a336b8bcd3499e23f5dea0c6ed41974 (patch) | |
tree | cafaae88066e64d99b18606b48ea90621aab6fb3 /usr.bin/rdist/client.c | |
parent | 968f100607f98e659a5ce90c71e5949d09d4898a (diff) |
o Sync w/ freerdist 0.92 minus the compress option
o KNF and ANSIfy the function headers
Sparse file support is currently a no-op since it didn't work.
Proper sparse file support will be added later.
Diffstat (limited to 'usr.bin/rdist/client.c')
-rw-r--r-- | usr.bin/rdist/client.c | 490 |
1 files changed, 266 insertions, 224 deletions
diff --git a/usr.bin/rdist/client.c b/usr.bin/rdist/client.c index 0d50be51ed7..7455d514d76 100644 --- a/usr.bin/rdist/client.c +++ b/usr.bin/rdist/client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: client.c,v 1.17 2003/05/06 22:10:11 millert Exp $ */ +/* $OpenBSD: client.c,v 1.18 2003/05/14 01:34:35 millert Exp $ */ /* * Copyright (c) 1983 Regents of the University of California. @@ -33,18 +33,22 @@ * SUCH DAMAGE. */ +#include "defs.h" +#include "y.tab.h" + #ifndef lint #if 0 -static char RCSid[] = -"$From: client.c,v 6.80 1996/02/28 20:34:27 mcooper Exp $"; +static char RCSid[] __attribute__((__unused__)) = +"$From: client.c,v 1.13 1999/11/01 00:22:14 christos Exp $"; #else -static char RCSid[] = -"$OpenBSD: client.c,v 1.17 2003/05/06 22:10:11 millert Exp $"; +static char RCSid[] __attribute__((__unused__)) = +"$OpenBSD: client.c,v 1.18 2003/05/14 01:34:35 millert Exp $"; #endif -static char sccsid[] = "@(#)client.c"; +static char sccsid[] __attribute__((__unused__)) = +"@(#)client.c"; -static char copyright[] = +static char copyright[] __attribute__((__unused__)) = "@(#) Copyright (c) 1983 Regents of the University of California.\n\ All rights reserved.\n"; #endif /* not lint */ @@ -53,8 +57,6 @@ static char copyright[] = * Routines used in client mode to communicate with remove server. */ -#include "defs.h" -#include "y.tab.h" /* * Update status @@ -63,7 +65,7 @@ static char copyright[] = #define US_NOENT 1 /* Entry does not exist */ #define US_OUTDATE 2 /* Entry is out of date */ #define US_DOCOMP 3 /* Do a binary comparison */ -#define US_MODE 4 /* Modes of file differ */ +#define US_CHMOG 4 /* Modes or ownership of file differ */ struct linkbuf *ihead = NULL; /* list of files with more than one link */ char buf[BUFSIZ]; /* general purpose buffer */ @@ -74,14 +76,26 @@ char *ptarget; /* pointer to end of target name */ char *Tdest; /* pointer to last T dest*/ struct namelist *updfilelist = NULL; /* List of updated files */ -static int sendit(); +static void runspecial(char *, opt_t, char *, int); +static void addcmdspecialfile(char *, char *, int); +static void freecmdspecialfiles(void); +static struct linkbuf *linkinfo(struct stat *); +static int sendhardlink(opt_t, struct linkbuf *, char *, int); +static int sendfile(char *, opt_t, struct stat *, char *, char *, int); +static int rmchk(opt_t); +static int senddir(char *, opt_t, struct stat *, char *, char *, int); +static int sendlink(char *, opt_t, struct stat *, char *, char *, int); +static int update(char *, opt_t, struct stat *); +static int dostat(char *, struct stat *, opt_t); +static int statupdate(int, char *, opt_t, char *, int, struct stat *, char *, char *); +static int fullupdate(int, char *, opt_t, char *, int, struct stat *, char *, char *); +static int sendit(char *, opt_t, int); /* * return remote file pathname (relative from target) */ -char *remfilename(src, dest, path, rname, destdir) - char *src, *dest, *path, *rname; - int destdir; +char * +remfilename(char *src, char *dest, char *path, char *rname, int destdir) { extern struct namelist *filelist; char *lname, *cp; @@ -109,7 +123,7 @@ char *remfilename(src, dest, path, rname, destdir) if (path && *path) { cp = strrchr(path, '/'); if (cp == NULL) - (void) snprintf(buff, sizeof buff, "%s/%s", dest, path); + (void) snprintf(buff, sizeof(buff), "%s/%s", dest, path); else { srclen = strlen(src); pathlen = strlen(path); @@ -127,14 +141,14 @@ char *remfilename(src, dest, path, rname, destdir) } } if ((*cp != '/') && *cp) - (void) snprintf(buff, sizeof buff, - "%s/%s", dest, cp); + (void) snprintf(buff, sizeof(buff), "%s/%s", + dest, cp); else - (void) snprintf(buff, sizeof buff, - "%s%s", dest, cp); + (void) snprintf(buff, sizeof(buff), "%s%s", + dest, cp); } } else - strlcpy(lname, dest, buf + sizeof buff - lname); + (void) strlcpy(lname, dest, buf + sizeof buff - lname); debugmsg(DM_MISC, "remfilename: remote filename=%s\n", lname); @@ -144,9 +158,8 @@ char *remfilename(src, dest, path, rname, destdir) /* * Return true if name is in the list. */ -int inlist(list, file) - struct namelist *list; - char *file; +int +inlist(struct namelist *list, char *file) { struct namelist *nl; @@ -159,11 +172,8 @@ int inlist(list, file) /* * Run any special commands for this file */ -static void runspecial(starget, opts, rname, destdir) - char *starget; - opt_t opts; - char *rname; - int destdir; +static void +runspecial(char *starget, opt_t opts, char *rname, int destdir) { struct subcmd *sc; extern struct subcmd *subcmds; @@ -195,10 +205,8 @@ static void runspecial(starget, opts, rname, destdir) * If we're doing a target with a "cmdspecial" in it, then * save the name of the file being updated for use with "cmdspecial". */ -static void addcmdspecialfile(starget, rname, destdir) - char *starget; - char *rname; - int destdir; +static void +addcmdspecialfile(char *starget, char *rname, int destdir) { char *rfile; struct namelist *new; @@ -228,7 +236,8 @@ static void addcmdspecialfile(starget, rname, destdir) /* * Free the file list */ -static void freecmdspecialfiles() +static void +freecmdspecialfiles(void) { struct namelist *ptr, *save; @@ -247,10 +256,8 @@ static void freecmdspecialfiles() /* * Run commands for an entire cmd */ -extern void runcmdspecial(cmd, filev, opts) - struct cmd *cmd; - char **filev; - opt_t opts; +void +runcmdspecial(struct cmd *cmd, opt_t opts) { struct subcmd *sc; struct namelist *f; @@ -292,8 +299,8 @@ extern void runcmdspecial(cmd, filev, opts) /* * For security, reject filenames that contains a newline */ -int checkfilename(name) - char *name; +int +checkfilename(char *name) { char *cp; @@ -310,8 +317,8 @@ int checkfilename(name) return(0); } -void freelinkinfo(lp) - struct linkbuf *lp; +void +freelinkinfo(struct linkbuf *lp) { if (lp->pathname) free(lp->pathname); @@ -325,8 +332,8 @@ void freelinkinfo(lp) /* * Save and retrieve hard link info */ -static struct linkbuf *linkinfo(statp) - struct stat *statp; +static struct linkbuf * +linkinfo(struct stat *statp) { struct linkbuf *lp; @@ -356,29 +363,31 @@ static struct linkbuf *linkinfo(statp) /* * Send a hardlink */ -static int sendhardlink(opts, lp, rname, destdir) - opt_t opts; - struct linkbuf *lp; - char *rname; - int destdir; +static int +sendhardlink(opt_t opts, struct linkbuf *lp, char *rname, int destdir) { static char buff[MAXPATHLEN]; + char *lname; /* name of file to link to */ + char ername[MAXPATHLEN*4], elname[MAXPATHLEN*4]; debugmsg(DM_MISC, "sendhardlink: rname='%s' pathname='%s' src='%s' target='%s'\n", - rname, lp->pathname ? lp->pathname : "(null)", lp->src - ? lp->src : "(null)", lp->target ? lp->target : "(null)"); + rname, lp->pathname ? lp->pathname : "", + lp->src ? lp->src : "", lp->target ? lp->target : ""); if (lp->target == NULL) - (void) sendcmd(C_RECVHARDLINK, "%o %s %s", - opts, lp->pathname, rname); + lname = lp->pathname; else { - strlcpy(buff, remfilename(lp->src, lp->target, - lp->pathname, rname, destdir), sizeof buff); - debugmsg(DM_MISC, "sendhardlink: lname=%s\n", buff); - (void) sendcmd(C_RECVHARDLINK, "%o %s %s", - opts, buff, rname); + lname = buff; + strlcpy(lname, remfilename(lp->src, lp->target, + lp->pathname, rname, + destdir), sizeof(buff)); + debugmsg(DM_MISC, "sendhardlink: lname=%s\n", lname); } + ENCODE(elname, lname); + ENCODE(ername, rname); + (void) sendcmd(C_RECVHARDLINK, "%o %s %s", + opts, elname, ername); return(response()); } @@ -386,15 +395,13 @@ static int sendhardlink(opts, lp, rname, destdir) /* * Send a file */ -static int sendfile(rname, opts, stb, user, group, destdir) - char *rname; - opt_t opts; - struct stat *stb; - char *user, *group; - int destdir; +static int +sendfile(char *rname, opt_t opts, struct stat *stb, char *user, + char *group, int destdir) { int goterr, f; off_t i; + char ername[MAXPATHLEN*4]; if (stb->st_nlink > 1) { struct linkbuf *lp; @@ -411,18 +418,20 @@ static int sendfile(rname, opts, stb, user, group, destdir) /* * Send file info */ + ENCODE(ername, rname); + (void) sendcmd(C_RECVREG, "%o %04o %ld %ld %ld %s %s %s", - opts, stb->st_mode & 07777, - (long) stb->st_size, + opts, stb->st_mode & 07777, (long) stb->st_size, stb->st_mtime, stb->st_atime, - user, group, rname); + user, group, ername); if (response() < 0) { (void) close(f); return(-1); } - debugmsg(DM_MISC, "Send file '%s' %d bytes\n", - rname, (long) stb->st_size); + + debugmsg(DM_MISC, "Send file '%s' %ld bytes\n", rname, + (long) stb->st_size); /* * Set remote time out alarm handler. @@ -434,12 +443,12 @@ static int sendfile(rname, opts, stb, user, group, destdir) */ goterr = 0; for (i = 0; i < stb->st_size; i += BUFSIZ) { - int amt = BUFSIZ; + off_t amt = BUFSIZ; (void) alarm(rtimeout); if (i + amt > stb->st_size) amt = stb->st_size - i; - if (read(f, buf, amt) != amt) { + if (read(f, buf, (size_t) amt) != (ssize_t) amt) { error("%s: File changed size", target); err(); ++goterr; @@ -451,8 +460,8 @@ static int sendfile(rname, opts, stb, user, group, destdir) * this situation gracefully. */ } - if (xwrite(rem_w, buf, amt) < 0) { - error("%s: Error writing to client: %s", + if (xwrite(rem_w, buf, (size_t) amt) < 0) { + error("%s: Error writing to client: %s", target, SYSERR); err(); ++goterr; @@ -495,13 +504,14 @@ static int sendfile(rname, opts, stb, user, group, destdir) * Return 0 if nothing happened. * Return > 0 if anything is updated. */ -static int rmchk(opts) - opt_t opts; +static int +rmchk(opt_t opts) { u_char *s; struct stat stb; int didupdate = 0; int n; + char targ[MAXPATHLEN*4]; debugmsg(DM_CALL, "rmchk()\n"); @@ -526,8 +536,15 @@ static int rmchk(opts) * CC_NO -- file exists - DON'T remove. * CC_YES -- file doesn't exist - REMOVE. */ - snprintf(ptarget, target + sizeof(target) - ptarget, - "%s%s", (ptarget[-1] == '/' ? "" : "/"), s); + if (DECODE(targ, (char *) s) == -1) { + error("rmchk: cannot decode file"); + return(-1); + } + (void) snprintf(ptarget, + sizeof(target) - (ptarget - target), + "%s%s", + (ptarget[-1] == '/' ? "" : "/"), + targ); debugmsg(DM_MISC, "check %s\n", target); if (except(target)) (void) sendcmd(CC_NO, NULL); @@ -577,45 +594,44 @@ static int rmchk(opts) * Return 0 if nothing happened. * Return > 0 if anything is updated. */ -static int senddir(rname, opts, stb, user, group, destdir) - char *rname; - opt_t opts; - struct stat *stb; - char *user, *group; - int destdir; +static int +senddir(char *rname, opt_t opts, struct stat *stb, char *user, + char *group, int destdir) { DIRENTRY *dp; DIR *d; char *optarget, *cp; int len; int didupdate = 0; - - /* - * Don't descend into directory - */ - if (IS_ON(opts, DO_NODESCEND)) - return(0); - - if ((d = opendir(target)) == NULL) { - error("%s: opendir failed: %s", target, SYSERR); - return(-1); - } + char ername[MAXPATHLEN*4]; /* * Send recvdir command in recvit() format. */ + ENCODE(ername, rname); (void) sendcmd(C_RECVDIR, "%o %04o 0 0 0 %s %s %s", - opts, stb->st_mode & 07777, user, group, rname); + opts, stb->st_mode & 07777, user, group, ername); if (response() < 0) return(-1); + /* + * Don't descend into directory + */ + if (IS_ON(opts, DO_NODESCEND)) + return(0); + if (IS_ON(opts, DO_REMOVE)) if (rmchk(opts) > 0) ++didupdate; + if ((d = opendir(target)) == NULL) { + error("%s: opendir failed: %s", target, SYSERR); + return(-1); + } + optarget = ptarget; len = ptarget - target; - while ((dp = readdir(d))) { + while ((dp = readdir(d)) != NULL) { if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue; @@ -628,8 +644,8 @@ static int senddir(rname, opts, stb, user, group, destdir) if (ptarget[-1] != '/') *ptarget++ = '/'; cp = dp->d_name; - while ((*ptarget++ = *cp++)) - ; + while ((*ptarget++ = *cp++) != '\0') + continue; ptarget--; if (sendit(dp->d_name, opts, destdir) > 0) didupdate = 1; @@ -648,18 +664,15 @@ static int senddir(rname, opts, stb, user, group, destdir) /* * Send a link */ -static int sendlink(rname, opts, stb, user, group, destdir) - char *rname; - opt_t opts; - struct stat *stb; - char *user; - char *group; - int destdir; +static int +sendlink(char *rname, opt_t opts, struct stat *stb, char *user, + char *group, int destdir) { int f, n; static char tbuf[BUFSIZ]; char lbuf[MAXPATHLEN]; u_char *s; + char ername[MAXPATHLEN*4]; debugmsg(DM_CALL, "sendlink(%s, %x, stb, %d)\n", rname, opts, destdir); @@ -673,11 +686,11 @@ static int sendlink(rname, opts, stb, user, group, destdir) /* * Gather and send basic link info */ + ENCODE(ername, rname); (void) sendcmd(C_RECVSYMLINK, "%o %04o %ld %ld %ld %s %s %s", - opts, stb->st_mode & 07777, - (long) stb->st_size, + opts, stb->st_mode & 07777, (long) stb->st_size, stb->st_mtime, stb->st_atime, - user, group, rname); + user, group, ername); if (response() < 0) return(-1); @@ -690,8 +703,9 @@ static int sendlink(rname, opts, stb, user, group, destdir) error("%s: readlink failed", target); err(); } - (void) snprintf(tbuf, sizeof tbuf, "%.*s", (int) stb->st_size, lbuf); - (void) sendcmd(C_NONE, "%s\n", tbuf); + (void) snprintf(tbuf, sizeof(tbuf), "%.*s", (int) stb->st_size, lbuf); + ENCODE(ername, tbuf); + (void) sendcmd(C_NONE, "%s\n", ername); if (n != stb->st_size) { error("%s: file changed size", target); @@ -765,12 +779,10 @@ static int sendlink(rname, opts, stb, user, group, destdir) * US_NOENT - remote doesn't exist * US_OUTDATE - out of date * US_DOCOMP - comparing binaries to determine if out of date - * US_MODE - File modes do not match + * US_CHMOG - File modes or ownership do not match */ -static int update(rname, opts, statp) - char *rname; - opt_t opts; - struct stat *statp; +static int +update(char *rname, opt_t opts, struct stat *statp) { off_t size; time_t mtime; @@ -779,6 +791,7 @@ static int update(rname, opts, statp) char *owner = NULL, *group = NULL; int done, n; u_char *cp; + char ername[MAXPATHLEN*4]; debugmsg(DM_CALL, "update(%s, 0x%x, 0x%x)\n", rname, opts, statp); @@ -791,7 +804,8 @@ static int update(rname, opts, statp) /* * Check to see if the file exists on the remote machine. */ - (void) sendcmd(C_QUERY, "%s", rname); + ENCODE(ername, rname); + (void) sendcmd(C_QUERY, "%s", ername); for (done = 0; !done;) { n = remline(cp = respbuff, sizeof(respbuff), TRUE); @@ -843,7 +857,7 @@ static int update(rname, opts, statp) /* Goto top of loop */ default: - error("update: unexpected response to query '%s'", cp); + error("update: unexpected response to query '%s'", respbuff); return(US_NOTHING); } } @@ -860,7 +874,7 @@ static int update(rname, opts, statp) /* * Parse size */ - size = strtol(cp, (char **)&cp, 10); + size = (off_t) strtol(cp, (char **)&cp, 10); if (*cp++ != ' ') { error("update: size not delimited"); return(US_NOTHING); @@ -912,8 +926,8 @@ static int update(rname, opts, statp) debugmsg(DM_MISC, "update(%s,) local mode %04o remote mode %04o\n", rname, lmode, rmode); - debugmsg(DM_MISC, "update(%s,) size %d mtime %d owner '%s' grp '%s'\n", - rname, (int) size, mtime, owner, group); + debugmsg(DM_MISC, "update(%s,) size %ld mtime %d owner '%s' grp '%s'\n", + rname, (long) size, mtime, owner, group); if (statp->st_mtime != mtime) { if (statp->st_mtime < mtime && IS_ON(opts, DO_YOUNGER)) { @@ -925,24 +939,18 @@ static int update(rname, opts, statp) return(US_OUTDATE); } - /* - * If the mode of a file does not match the local mode, the - * whole file is updated. This is done both to insure that - * a bogus version of the file has not been installed and to - * avoid having to handle weird cases of chmod'ing symlinks - * and such. - */ + if (statp->st_size != size) { + debugmsg(DM_MISC, "size does not match (%ld != %ld).\n", + (long) statp->st_size, (long) size); + return(US_OUTDATE); + } + if (!IS_ON(opts, DO_NOCHKMODE) && lmode != rmode) { debugmsg(DM_MISC, "modes do not match (%04o != %04o).\n", lmode, rmode); - return(US_OUTDATE); + return(US_CHMOG); } - if (statp->st_size != size) { - debugmsg(DM_MISC, "size does not match (%d != %d).\n", - (int) statp->st_size, size); - return(US_OUTDATE); - } /* * Check ownership @@ -956,20 +964,21 @@ static int update(rname, opts, statp) "owner does not match (%s != %s).\n", getusername(statp->st_uid, target, opts), owner); - return(US_OUTDATE); + return(US_CHMOG); } } else { /* * Check numerically. * Allow negative numbers. */ - while (*owner && !isdigit(*owner) && (*owner != '-')) + while (*owner && !isdigit((unsigned char)*owner) && + (*owner != '-')) ++owner; - if (owner && atoi(owner) != statp->st_uid) { + if (owner && (UID_T) atoi(owner) != statp->st_uid) { debugmsg(DM_MISC, "owner does not match (%d != %s).\n", statp->st_uid, owner); - return(US_OUTDATE); + return(US_CHMOG); } } } @@ -983,18 +992,19 @@ static int update(rname, opts, statp) "group does not match (%s != %s).\n", getgroupname(statp->st_gid, target, opts), group); - return(US_OUTDATE); + return(US_CHMOG); } } else { /* Check numerically */ /* Allow negative gid */ - while (*group && !isdigit(*group) && (*group != '-')) + while (*group && !isdigit((unsigned char) *group) && + (*group != '-')) ++group; - if (group && atoi(group) != statp->st_gid) { + if (group && (UID_T) atoi(group) != statp->st_gid) { debugmsg(DM_MISC, "group does not match (%d != %s).\n", statp->st_gid, group); - return(US_OUTDATE); + return(US_CHMOG); } } } @@ -1005,10 +1015,8 @@ static int update(rname, opts, statp) /* * Stat a file */ -static int dostat(file, statbuf, opts) - char *file; - struct stat *statbuf; - opt_t opts; +static int +dostat(char *file, struct stat *statbuf, opt_t opts) { int s; @@ -1024,6 +1032,96 @@ static int dostat(file, statbuf, opts) } /* + * We need to just change file info. + */ +static int +statupdate(int u, char *target, opt_t opts, char *rname, int destdir, + struct stat *st, char *user, char *group) +{ + int rv = 0; + char ername[MAXPATHLEN*4]; + int lmode = st->st_mode & 07777; + + if (u == US_CHMOG) { + if (IS_ON(opts, DO_VERIFY)) { + message(MT_INFO, + "%s: need to change to perm %04o, owner %s, group %s", + target, lmode, user, group); + runspecial(target, opts, rname, destdir); + } + else { + message(MT_CHANGE, "%s: change to perm %04o, owner %s, group %s", + target, lmode, user, group); + ENCODE(ername, rname); + (void) sendcmd(C_CHMOG, "%o %04o %s %s %s", + opts, lmode, user, group, ername); + (void) response(); + } + rv = 1; + } + return(rv); +} + + +/* + * We need to install/update: + */ +static int +fullupdate(int u, char *target, opt_t opts, char *rname, int destdir, + struct stat *st, char *user, char *group) +{ + /* + * No entry - need to install + */ + if (u == US_NOENT) { + if (IS_ON(opts, DO_VERIFY)) { + message(MT_INFO, "%s: need to install", target); + runspecial(target, opts, rname, destdir); + return(1); + } + if (!IS_ON(opts, DO_QUIET)) + message(MT_CHANGE, "%s: installing", target); + FLAG_OFF(opts, (DO_COMPARE|DO_REMOVE)); + } + + /* + * Handle special file types, including directories and symlinks + */ + if (S_ISDIR(st->st_mode)) { + if (senddir(rname, opts, st, user, group, destdir) > 0) + return(1); + return(0); + } else if (S_ISLNK(st->st_mode)) { + if (u == US_NOENT) + FLAG_ON(opts, DO_COMPARE); + /* + * Since we always send link info to the server + * so the server can determine if the remote link + * is correct, we never get any acknowledge meant + * from the server whether the link was really + * updated or not. + */ + (void) sendlink(rname, opts, st, user, group, destdir); + return(0); + } else if (S_ISREG(st->st_mode)) { + if (u == US_OUTDATE) { + if (IS_ON(opts, DO_VERIFY)) { + message(MT_INFO, "%s: need to update", target); + runspecial(target, opts, rname, destdir); + return(1); + } + if (!IS_ON(opts, DO_QUIET)) + message(MT_CHANGE, "%s: updating", target); + } + return (sendfile(rname, opts, st, user, group, destdir) == 0); + } else { + message(MT_INFO, "%s: unknown file type 0%o", target, + st->st_mode); + return(0); + } +} + +/* * Transfer the file or directory in target[]. * rname is the name of the file on the remote host. * @@ -1031,16 +1129,12 @@ static int dostat(file, statbuf, opts) * Return 0 if nothing happened. * Return > 0 if anything is updated. */ -static int sendit(rname, opts, destdir) - char *rname; - opt_t opts; - int destdir; +static int +sendit(char *rname, opt_t opts, int destdir) { static struct stat stb; - extern struct subcmd *subcmds; char *user, *group; int u, len; - int didupdate = 0; /* * Remove possible accidental newline @@ -1077,80 +1171,28 @@ static int sendit(rname, opts, destdir) return(0); } - /* - * File mode needs changing - */ - if (u == US_MODE) { - if (IS_ON(opts, DO_VERIFY)) { - message(MT_INFO, "%s: need to chmod to %04o", - target, stb.st_mode & 07777); - runspecial(target, opts, rname, destdir); - return(1); - } - message(MT_CHANGE, "%s: chmod to %04o", - target, stb.st_mode & 07777); - (void) sendcmd(C_CHMOD, "%o %04o %s", - opts, stb.st_mode & 07777, rname); - (void) response(); - return(1); - } - user = getusername(stb.st_uid, target, opts); group = getgroupname(stb.st_gid, target, opts); - /* - * No entry - need to install - */ - if (u == US_NOENT) { - if (IS_ON(opts, DO_VERIFY)) { - message(MT_INFO, "%s: need to install", target); - runspecial(target, opts, rname, destdir); - return(1); - } - if (!IS_ON(opts, DO_QUIET)) - message(MT_CHANGE, "%s: installing", target); - FLAG_OFF(opts, (DO_COMPARE|DO_REMOVE)); - } + if (u == US_CHMOG && IS_OFF(opts, DO_UPDATEPERM)) + u = US_OUTDATE; - /* - * Handle special file types, including directories and symlinks - */ - if (S_ISDIR(stb.st_mode)) { - if (senddir(rname, opts, &stb, user, group, destdir) > 0) - didupdate = 1; - } else if (S_ISLNK(stb.st_mode)) { - if (u != US_NOENT) - FLAG_ON(opts, DO_COMPARE); - /* - * Since we always send link info to the server - * so the server can determine if the remote link - * is correct, we never get any acknowledge meant - * from the server whether the link was really - * updated or not. - */ - (void) sendlink(rname, opts, &stb, user, group, destdir); - } else if (S_ISREG(stb.st_mode)) { - if (u == US_OUTDATE) { - if (IS_ON(opts, DO_VERIFY)) { - message(MT_INFO, "%s: need to update", target); - runspecial(target, opts, rname, destdir); - return(1); - } - if (!IS_ON(opts, DO_QUIET)) - message(MT_CHANGE, "%s: updating", target); - } - if (sendfile(rname, opts, &stb, user, group, destdir) == 0) - didupdate = 1; - } else - error("%s: unknown file type", target); + if (u == US_NOENT || u == US_OUTDATE || u == US_DOCOMP) + return(fullupdate(u, target, opts, rname, destdir, &stb, + user, group)); - return(didupdate); + if (u == US_CHMOG) + return(statupdate(u, target, opts, rname, destdir, &stb, + user, group)); + + return(0); } /* * Remove temporary files and do any cleanup operations before exiting. */ -extern void cleanup() +void +cleanup(int dummy) { char *file; #ifdef USE_STATDB @@ -1159,7 +1201,7 @@ extern void cleanup() (void) unlink(statfile); #endif - if ((file = getnotifyfile())) + if ((file = getnotifyfile()) != NULL) (void) unlink(file); } @@ -1172,14 +1214,13 @@ extern void cleanup() * Return 0 if nothing updated. * Return > 0 if something was updated. */ -extern int install(src, dest, ddir, destdir, opts) - char *src, *dest; - int ddir, destdir; - opt_t opts; +int +install(char *src, char *dest, int ddir, int destdir, opt_t opts) { static char destcopy[MAXPATHLEN]; char *rname; int didupdate = 0; + char ername[MAXPATHLEN*4]; debugmsg(DM_CALL, "install(src=%s,dest=%s,ddir=%d,destdir=%d,opts=%d) start\n", @@ -1190,7 +1231,7 @@ extern int install(src, dest, ddir, destdir, opts) if (IS_ON(opts, DO_WHOLE)) source[0] = CNULL; else - (void) strlcpy(source, src, sizeof source); + (void) strlcpy(source, src, sizeof(source)); if (dest == NULL) { FLAG_OFF(opts, DO_WHOLE); /* WHOLE only useful if renaming */ @@ -1205,7 +1246,7 @@ extern int install(src, dest, ddir, destdir, opts) char *cp; cp = getondistoptlist(opts); - (void) snprintf(buff, sizeof buff, "%s%s%s %s %s", + (void) snprintf(buff, sizeof(buff), "%s%s%s %s %s", IS_ON(opts, DO_VERIFY) ? "verify" : "install", (cp) ? " -o" : "", (cp) ? cp : "", src, dest); @@ -1250,10 +1291,11 @@ extern int install(src, dest, ddir, destdir, opts) /* * Pass the destination file/directory name to remote. */ + ENCODE(ername, dest); if (ddir) - (void) sendcmd(C_DIRTARGET, "%o %s", opts, dest); + (void) sendcmd(C_DIRTARGET, "%o %s", opts, ername); else - (void) sendcmd(C_TARGET, "%o %s", opts, dest); + (void) sendcmd(C_TARGET, "%o %s", opts, ername); if (response() < 0) return(-1); @@ -1264,7 +1306,7 @@ extern int install(src, dest, ddir, destdir, opts) * hardlink info. */ if (destdir || (src && dest && strcmp(src, dest))) { - (void) strlcpy(destcopy, dest, sizeof destcopy); + (void) strlcpy(destcopy, dest, sizeof(destcopy)); Tdest = destcopy; } |