+
+ if (!destdir && (opts & WHOLE))
+ opts |= STRIP;
+ if (opts & REMOVE) {
+ opts &= ~REMOVE;
+ rmchk(src, NULL, opts);
+ }
+ sendf(src, NULL, opts);
+}
+
+struct tstamp {
+ time_t lastmod;
+ FILE *tfp;
+} ts[NSTAMPS];
+
+int nstamps;
+
+extern char target[], *tp;
+
+/*
+ * Process commands for comparing files to time stamp files.
+ */
+dofcmds(files, stamps, cmds)
+ struct block *files, *stamps, *cmds;
+{
+ register struct block *b;
+ register struct tstamp *t;
+ register char **cpp;
+ struct timeval tv[2];
+ struct timezone tz;
+ struct stat stb;
+ extern char *tmpinc;
+
+ if (debug)
+ printf("dofcmds()\n");
+
+ files = expand(files, 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");
+ except = cmds;
+
+ t = ts;
+ nstamps = 0;
+ for (b = stamps; b != NULL; b = b->b_next) {
+ if (stat(b->b_name, &stb) < 0) {
+ error("%s: %s\n", b->b_name, sys_errlist[errno]);
+ continue;
+ }
+ if (++nstamps > NSTAMPS)
+ fatal("too many time stamp files in one command\n");
+ if (debug)
+ printf("%s: %d\n", b->b_name, stb.st_mtime);
+ t->lastmod = stb.st_mtime;
+ (void) gettimeofday(&tv[0], &tz);
+ tv[1] = tv[0];
+ (void) utimes(b->b_name, tv);
+ if (!nflag && !(options & VERIFY)) {
+ if ((t->tfp = fopen(tmpfile, "w")) == NULL)
+ error("%s: %s\n", b->b_name, sys_errlist[errno]);
+ (*tmpinc)++;
+ } else
+ t->tfp = NULL;
+ t++;
+ }
+
+ for (b = files; b != NULL; b = b->b_next) {
+ if (filec) {
+ for (cpp = filev; *cpp; cpp++)
+ if (!strcmp(b->b_name, *cpp))
+ goto found;
+ continue;
+ }
+ found:
+ tp = NULL;
+ cmptime(b->b_name);
+ }
+
+ *tmpinc = 'A';
+ for (t = ts; t < &ts[nstamps]; t++) {
+ if (t->tfp != NULL)
+ (void) fclose(t->tfp);
+ for (b = cmds; b != NULL; b = b->b_next)
+ if (b->b_type == NOTIFY)
+ notify(tmpfile, NULL, b->b_args, t->lastmod);
+ if (!nflag && !(options & VERIFY))
+ (void) unlink(tmpfile);
+ (*tmpinc)++;
+ }
+}
+
+/*
+ * Compare the mtime of file to the list of time stamps.
+ */
+cmptime(name)
+ char *name;
+{
+ register struct tstamp *t;
+ struct stat stb;
+
+ if (debug)
+ printf("cmptime(%s)\n", name);
+
+ if (exclude(name))
+ return;
+
+ /*
+ * first time cmptime() is called?
+ */
+ if (tp == NULL) {
+ exptilde(target, name);
+ tp = name = target;
+ while (*tp)
+ tp++;
+ }
+ if (access(name, 4) < 0 || stat(name, &stb) < 0) {
+ error("%s: %s\n", name, sys_errlist[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;
+ }
+
+ for (t = ts; t < &ts[nstamps]; t++) {
+ if (stb.st_mtime > t->lastmod)
+ log(t->tfp, "new: %s\n", name);
+ }
+}
+
+rcmptime(st)
+ struct stat *st;
+{
+ register DIR *d;
+ register struct direct *dp;
+ register char *cp;
+ char *otp;
+ int len;
+
+ if (debug)
+ printf("rcmptime(%x)\n", st);
+
+ if ((d = opendir(target)) == NULL) {
+ error("%s: %s\n", target, sys_errlist[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';