|
|
1.1 ! root 1: /* docmd.c -- driver for the whole thing */ ! 2: ! 3: /* ! 4: * $Header: /f/osi/others/idist/RCS/docmd.c,v 7.0 89/11/23 21:58:24 mrose Rel $ ! 5: * ! 6: * The major alterations to this file are the replacing of the ! 7: * connection stuff with the ISODE functions necessary. These new ! 8: * functions appear in a new file. ! 9: * ! 10: * Julian Onions <[email protected]> ! 11: * Nottingham University, Computer Science. ! 12: * ! 13: * ! 14: * $Log: docmd.c,v $ ! 15: * Revision 7.0 89/11/23 21:58:24 mrose ! 16: * Release 6.0 ! 17: * ! 18: */ ! 19: ! 20: ! 21: /* ! 22: * Copyright (c) 1983 Regents of the University of California. ! 23: * All rights reserved. The Berkeley software License Agreement ! 24: * specifies the terms and conditions for redistribution. ! 25: */ ! 26: ! 27: #ifndef lint ! 28: static char sccsid[] = "@(#)docmd.c 5.1 (Berkeley) 6/6/85"; ! 29: static char *rcsid = "$Header: /f/osi/others/idist/RCS/docmd.c,v 7.0 89/11/23 21:58:24 mrose Rel $"; ! 30: #endif ! 31: ! 32: #include "defs.h" ! 33: #include <setjmp.h> ! 34: #include <sys/file.h> ! 35: ! 36: FILE *lfp; /* log file for recording files updated */ ! 37: struct subcmd *subcmds; /* list of sub-commands for current cmd */ ! 38: jmp_buf env; ! 39: ! 40: int cleanup(); ! 41: int lostconn(); ! 42: ! 43: /* ! 44: * Do the commands in cmds (initialized by yyparse). ! 45: */ ! 46: docmds(dhosts, argc, argv) ! 47: char **dhosts; ! 48: int argc; ! 49: char **argv; ! 50: { ! 51: register struct cmd *c; ! 52: register struct namelist *f; ! 53: register char **cpp; ! 54: extern struct cmd *cmds; ! 55: ! 56: (void) signal(SIGHUP, cleanup); ! 57: (void) signal(SIGINT, cleanup); ! 58: (void) signal(SIGQUIT, cleanup); ! 59: (void) signal(SIGTERM, cleanup); ! 60: ! 61: for (c = cmds; c != NULL; c = c->c_next) { ! 62: if (dhosts != NULL && *dhosts != NULL) { ! 63: for (cpp = dhosts; *cpp; cpp++) ! 64: if (strcmp(c->c_name, *cpp) == 0) ! 65: goto fndhost; ! 66: continue; ! 67: } ! 68: fndhost: ! 69: if (argc) { ! 70: for (cpp = argv; *cpp; cpp++) { ! 71: if (c->c_label != NULL && ! 72: strcmp(c->c_label, *cpp) == 0) { ! 73: cpp = NULL; ! 74: goto found; ! 75: } ! 76: for (f = c->c_files; f != NULL; f = f->n_next) ! 77: if (strcmp(f->n_name, *cpp) == 0) ! 78: goto found; ! 79: } ! 80: continue; ! 81: } else ! 82: cpp = NULL; ! 83: found: ! 84: switch (c->c_type) { ! 85: case ARROW: ! 86: doarrow(cpp, c->c_files, c->c_name, c->c_cmds); ! 87: break; ! 88: case DCOLON: ! 89: dodcolon(cpp, c->c_files, c->c_name, c->c_cmds); ! 90: break; ! 91: default: ! 92: adios (NULLCP, "illegal command type %d\n", c->c_type); ! 93: } ! 94: } ! 95: closeconn(); ! 96: } ! 97: ! 98: /* ! 99: * Process commands for sending files to other machines. ! 100: */ ! 101: doarrow(filev, files, rhost, scmds) ! 102: char **filev; ! 103: struct namelist *files; ! 104: char *rhost; ! 105: struct subcmd *scmds; ! 106: { ! 107: register struct namelist *f; ! 108: register struct subcmd *sc; ! 109: register char **cpp; ! 110: int n, ddir, opts = options; ! 111: ! 112: if (debug) ! 113: printf("doarrow(%x, %s, %x)\n", files, rhost, scmds); ! 114: ! 115: if (files == NULL) { ! 116: advise(NULLCP, "no files to be updated"); ! 117: return; ! 118: } ! 119: ! 120: subcmds = scmds; ! 121: ddir = files->n_next != NULL; /* destination is a directory */ ! 122: if (nflag) ! 123: printf("updating host %s\n", rhost); ! 124: else { ! 125: if (setjmp(env)) ! 126: goto done; ! 127: (void) signal(SIGPIPE, lostconn); ! 128: if (!makeconn(rhost)) ! 129: return; ! 130: if ((lfp = fopen(utmpfile, "w")) == NULL) ! 131: adios (utmpfile, "cannot open file"); ! 132: } ! 133: for (f = files; f != NULL; f = f->n_next) { ! 134: if (filev) { ! 135: for (cpp = filev; *cpp; cpp++) ! 136: if (strcmp(f->n_name, *cpp) == 0) ! 137: goto found; ! 138: if (!nflag) ! 139: (void) fclose(lfp); ! 140: continue; ! 141: } ! 142: found: ! 143: n = 0; ! 144: for (sc = scmds; sc != NULL; sc = sc->sc_next) { ! 145: if (sc->sc_type != INSTALL) ! 146: continue; ! 147: n++; ! 148: install(f->n_name, sc->sc_name, ! 149: sc->sc_name == NULL ? 0 : ddir, sc->sc_options); ! 150: opts = sc->sc_options; ! 151: } ! 152: if (n == 0) ! 153: install(f->n_name, (char *)NULL, 0, options); ! 154: } ! 155: done: ! 156: if (!nflag) { ! 157: (void) signal(SIGPIPE, cleanup); ! 158: (void) fclose(lfp); ! 159: lfp = NULL; ! 160: } ! 161: for (sc = scmds; sc != NULL; sc = sc->sc_next) ! 162: if (sc->sc_type == NOTIFY) ! 163: notify(utmpfile, rhost, sc->sc_args, 0L); ! 164: if (!nflag) { ! 165: (void) unlink(utmpfile); ! 166: for (; ihead != NULL; ihead = ihead->nextp) { ! 167: free((char *)ihead); ! 168: if ((opts & IGNLNKS) || ihead->count == 0) ! 169: continue; ! 170: log(lfp, "%s: Warning: missing links\n", ! 171: ihead->pathname); ! 172: } ! 173: } ! 174: } ! 175: ! 176: ! 177: lostconn() ! 178: { ! 179: log(lfp, "idist: lost connection\n"); ! 180: longjmp(env, 1); ! 181: } ! 182: ! 183: ! 184: time_t lastmod; ! 185: FILE *tfp; ! 186: extern char target[], *tp; ! 187: ! 188: /* ! 189: * Process commands for comparing files to time stamp files. ! 190: */ ! 191: dodcolon(filev, files, stamp, scmds) ! 192: char **filev; ! 193: struct namelist *files; ! 194: char *stamp; ! 195: struct subcmd *scmds; ! 196: { ! 197: register struct subcmd *sc; ! 198: register struct namelist *f; ! 199: register char **cpp; ! 200: struct timeval tv[2]; ! 201: struct timezone tz; ! 202: struct stat stb; ! 203: ! 204: if (debug) ! 205: printf("dodcolon()\n"); ! 206: ! 207: if (files == NULL) { ! 208: advise (NULLCP, "no files to be updated"); ! 209: return; ! 210: } ! 211: if (stat(stamp, &stb) < 0) { ! 212: advise(stamp, "Can't stat"); ! 213: return; ! 214: } ! 215: if (debug) ! 216: printf("%s: %d\n", stamp, stb.st_mtime); ! 217: ! 218: subcmds = scmds; ! 219: lastmod = stb.st_mtime; ! 220: if (nflag || (options & VERIFY)) ! 221: tfp = NULL; ! 222: else { ! 223: if ((tfp = fopen(utmpfile, "w")) == NULL) { ! 224: advise (utmpfile, "Can't open file"); ! 225: return; ! 226: } ! 227: (void) gettimeofday(&tv[0], &tz); ! 228: tv[1] = tv[0]; ! 229: (void) utimes(stamp, tv); ! 230: } ! 231: ! 232: for (f = files; f != NULL; f = f->n_next) { ! 233: if (filev) { ! 234: for (cpp = filev; *cpp; cpp++) ! 235: if (strcmp(f->n_name, *cpp) == 0) ! 236: goto found; ! 237: continue; ! 238: } ! 239: found: ! 240: tp = NULL; ! 241: cmptime(f->n_name); ! 242: } ! 243: ! 244: if (tfp != NULL) ! 245: (void) fclose(tfp); ! 246: for (sc = scmds; sc != NULL; sc = sc->sc_next) ! 247: if (sc->sc_type == NOTIFY) ! 248: notify(utmpfile, (char *)NULL, sc->sc_args, lastmod); ! 249: if (!nflag && !(options & VERIFY)) ! 250: (void) unlink(utmpfile); ! 251: } ! 252: ! 253: /* ! 254: * Compare the mtime of file to the list of time stamps. ! 255: */ ! 256: cmptime(name) ! 257: char *name; ! 258: { ! 259: struct stat stb; ! 260: ! 261: if (debug) ! 262: printf("cmptime(%s)\n", name); ! 263: ! 264: if (except(name)) ! 265: return; ! 266: ! 267: if (nflag) { ! 268: printf("comparing dates: %s\n", name); ! 269: return; ! 270: } ! 271: ! 272: /* ! 273: * first time cmptime() is called? ! 274: */ ! 275: if (tp == NULL) { ! 276: if (exptilde(target, name) == NULL) ! 277: return; ! 278: tp = name = target; ! 279: while (*tp) ! 280: tp++; ! 281: } ! 282: if (access(name, 4) < 0 || stat(name, &stb) < 0) { ! 283: advise (name, "Can't access"); ! 284: return; ! 285: } ! 286: ! 287: switch (stb.st_mode & S_IFMT) { ! 288: case S_IFREG: ! 289: break; ! 290: ! 291: case S_IFDIR: ! 292: rcmptime(&stb); ! 293: return; ! 294: ! 295: default: ! 296: advise(NULLCP, "%s not a plain file", name); ! 297: return; ! 298: } ! 299: ! 300: if (stb.st_mtime > lastmod) ! 301: log(tfp, "new: %s\n", name); ! 302: } ! 303: ! 304: rcmptime(st) ! 305: struct stat *st; ! 306: { ! 307: register DIR *d; ! 308: register struct direct *dp; ! 309: register char *cp; ! 310: char *otp; ! 311: int len; ! 312: ! 313: if (debug) ! 314: printf("rcmptime(%x)\n", st); ! 315: ! 316: if ((d = opendir(target)) == NULL) { ! 317: advise (target, "can't open directory"); ! 318: return; ! 319: } ! 320: otp = tp; ! 321: len = tp - target; ! 322: while (dp = readdir(d)) { ! 323: if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) ! 324: continue; ! 325: if (len + 1 + strlen(dp->d_name) >= BUFSIZ - 1) { ! 326: advise (NULLCP, "%s/%s name too long", ! 327: target, dp->d_name); ! 328: continue; ! 329: } ! 330: tp = otp; ! 331: *tp++ = '/'; ! 332: cp = dp->d_name; ! 333: while (*tp++ = *cp++) ! 334: ; ! 335: tp--; ! 336: cmptime(target); ! 337: } ! 338: closedir(d); ! 339: tp = otp; ! 340: *tp = '\0'; ! 341: } ! 342: ! 343: /* ! 344: * Notify the list of people the changes that were made. ! 345: * rhost == NULL if we are mailing a list of changes compared to at time ! 346: * stamp file. ! 347: */ ! 348: notify(file, rhost, to, lmod) ! 349: char *file, *rhost; ! 350: register struct namelist *to; ! 351: time_t lmod; ! 352: { ! 353: register int fd, len; ! 354: FILE *pf, *popen(); ! 355: struct stat stb; ! 356: char buf[BUFSIZ]; ! 357: ! 358: if ((options & VERIFY) || to == NULL) ! 359: return; ! 360: if (!qflag) { ! 361: printf("notify "); ! 362: if (rhost) ! 363: printf("@%s ", rhost); ! 364: prnames(to); ! 365: } ! 366: if (nflag) ! 367: return; ! 368: ! 369: if ((fd = open(file, O_RDONLY, 0)) < 0) { ! 370: advise (file, "Can't open file"); ! 371: return; ! 372: } ! 373: if (fstat(fd, &stb) < 0) { ! 374: advise (file, "Can't stat"); ! 375: (void) close(fd); ! 376: return; ! 377: } ! 378: if (stb.st_size == 0) { ! 379: (void) close(fd); ! 380: return; ! 381: } ! 382: /* ! 383: * Create a pipe to mailling program. ! 384: */ ! 385: pf = popen(MAILCMD, "w"); ! 386: if (pf == NULL) { ! 387: advise (NULLCP, "notify: \"%s\" failed", MAILCMD); ! 388: (void) close(fd); ! 389: return; ! 390: } ! 391: /* ! 392: * Output the proper header information. ! 393: */ ! 394: fprintf(pf, "From: idist (Remote ISO distribution program)\n"); ! 395: fprintf(pf, "To:"); ! 396: if (!any('@', to->n_name) && rhost != NULL) ! 397: fprintf(pf, " %s@%s", to->n_name, rhost); ! 398: else ! 399: fprintf(pf, " %s", to->n_name); ! 400: to = to->n_next; ! 401: while (to != NULL) { ! 402: if (!any('@', to->n_name) && rhost != NULL) ! 403: fprintf(pf, ", %s@%s", to->n_name, rhost); ! 404: else ! 405: fprintf(pf, ", %s", to->n_name); ! 406: to = to->n_next; ! 407: } ! 408: (void) putc('\n', pf); ! 409: if (rhost != NULL) ! 410: fprintf(pf, "Subject: files updated by idist from %s to %s\n", ! 411: host, rhost); ! 412: else ! 413: fprintf(pf, "Subject: files updated after %s\n", ctime(&lmod)); ! 414: (void) putc('\n', pf); ! 415: ! 416: while ((len = read(fd, buf, BUFSIZ)) > 0) ! 417: (void) fwrite(buf, 1, len, pf); ! 418: (void) close(fd); ! 419: (void) pclose(pf); ! 420: } ! 421: ! 422: /* ! 423: * Return true if name is in the list. ! 424: */ ! 425: inlist(list, file) ! 426: struct namelist *list; ! 427: char *file; ! 428: { ! 429: register struct namelist *nl; ! 430: ! 431: for (nl = list; nl != NULL; nl = nl->n_next) ! 432: if (!strcmp(file, nl->n_name)) ! 433: return(1); ! 434: return(0); ! 435: } ! 436: ! 437: /* ! 438: * Return TRUE if file is in the exception list. ! 439: */ ! 440: except(file) ! 441: char *file; ! 442: { ! 443: register struct subcmd *sc; ! 444: register struct namelist *nl; ! 445: char *p, *re_comp (); ! 446: ! 447: if (debug) ! 448: printf("except(%s)\n", file); ! 449: ! 450: for (sc = subcmds; sc != NULL; sc = sc->sc_next) { ! 451: if (sc->sc_type != EXCEPT && sc->sc_type != PATTERN) ! 452: continue; ! 453: for (nl = sc->sc_args; nl != NULL; nl = nl->n_next) { ! 454: if (sc->sc_type == EXCEPT) { ! 455: if (!strcmp(file, nl->n_name)) ! 456: return(1); ! 457: continue; ! 458: } ! 459: if (p = re_comp(nl->n_name)) { ! 460: advise (NULLCP, "'%s' - %s", nl -> n_name, p); ! 461: continue; ! 462: } ! 463: if (re_exec(file) > 0) ! 464: return(1); ! 465: } ! 466: } ! 467: return(0); ! 468: } ! 469: ! 470: char * ! 471: colon(cp) ! 472: register char *cp; ! 473: { ! 474: ! 475: while (*cp) { ! 476: if (*cp == ':') ! 477: return(cp); ! 478: if (*cp == '/') ! 479: return(0); ! 480: cp++; ! 481: } ! 482: return(0); ! 483: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.