|
|
1.1 ! root 1: /* ! 2: * track ! 3: */ ! 4: ! 5: #include <stdio.h> ! 6: #include <sys/types.h> ! 7: #include <sys/stat.h> ! 8: #include <dk.h> ! 9: #include <signal.h> ! 10: #include <setjmp.h> ! 11: #include <ftw.h> ! 12: ! 13: int vflag; /* verbose */ ! 14: int nflag; /* don't actually copy */ ! 15: int rflag; /* act as remote slave */ ! 16: int tflag; /* update only if remote is newer */ ! 17: char prefix[128]; /* alternate prefix on remote (-d flag) */ ! 18: int nsize; /* amount to strip off local name */ ! 19: ! 20: char *descfile; ! 21: extern char *optarg; ! 22: extern int optind; ! 23: FILE *torem; ! 24: int rem; ! 25: int descfd; ! 26: jmp_buf almbuf; ! 27: char tempfile[] = "/tmp/trckXXXXXX"; ! 28: unsigned getsum(); ! 29: char *remoten(); ! 30: ! 31: main(argc, argv) ! 32: char **argv; ! 33: { ! 34: int consider(); ! 35: char buf[128]; ! 36: ! 37: if (argc <= 1) { ! 38: printf("track [-nvtr] {-f description | directory} machine\n"); ! 39: exit(0); ! 40: } ! 41: for (;;) { ! 42: switch (getopt(argc, argv, "vnrtf:d:")) { ! 43: ! 44: case 'v': ! 45: vflag++; ! 46: continue; ! 47: ! 48: case 'r': ! 49: rflag++; ! 50: continue; ! 51: ! 52: case 'n': ! 53: nflag++; ! 54: continue; ! 55: ! 56: case 't': ! 57: tflag++; ! 58: continue; ! 59: ! 60: case 'f': ! 61: descfile = optarg; ! 62: continue; ! 63: ! 64: case 'd': ! 65: strcpy(prefix, optarg); ! 66: continue; ! 67: case '?': ! 68: exit(1); ! 69: ! 70: case EOF: ! 71: default: ! 72: break; ! 73: } ! 74: break; ! 75: } ! 76: if (setjmp(almbuf)) { ! 77: if (rflag==0) ! 78: printf("track: alarm talking to %s\n", argv[optind]); ! 79: exit(1); ! 80: } ! 81: if (rflag) ! 82: remote(); ! 83: if (descfile) { ! 84: descfd = open(descfile, 0); ! 85: if (descfd <= 0) { ! 86: printf("track: can't open description %s", descfile); ! 87: exit(1); ! 88: } ! 89: } else { ! 90: if (optind >= argc) { ! 91: printf("track: no description file\n"); ! 92: exit(1); ! 93: } ! 94: descfile = argv[optind]; ! 95: optind++; ! 96: } ! 97: if (optind >= argc) { ! 98: printf("track: no machine given\n"); ! 99: exit(1); ! 100: } ! 101: rem = ipcexec(argv[optind], "heavy delim", "track -r"); ! 102: if (rem < 0) { ! 103: printf("track: can't execute on %s\n", argv[optind]); ! 104: exit(1); ! 105: } ! 106: torem = fdopen(rem, "w"); ! 107: fprintf(torem, "testing 123\n"); ! 108: fflush(torem); ! 109: vgetline(rem, buf, "<startup>"); ! 110: if (strncmp(buf, "ok", 2) !=0) { ! 111: printf("track: can't talk to remote\n"); ! 112: exit(1); ! 113: } ! 114: mktemp(tempfile); ! 115: if (descfd <= 0) { ! 116: if (prefix[0]) ! 117: nsize = strlen(descfile); ! 118: ftw(descfile, consider, 10); ! 119: } else { ! 120: while (getline(descfd, buf)) { ! 121: if (prefix[0]) ! 122: nsize = strlen(buf); ! 123: ftw(buf, consider, 10); ! 124: } ! 125: } ! 126: unlink(tempfile); ! 127: exit(1); ! 128: } ! 129: ! 130: remote() ! 131: { ! 132: char buf[1024]; ! 133: struct stat statb; ! 134: char name[128]; ! 135: int x, ofd; ! 136: char obuf[BUFSIZ]; ! 137: ! 138: setbuf(stdout, obuf); ! 139: while (getline(0, buf) != 0) { ! 140: if (sscanf(buf, "testing %d", &x) == 1) { ! 141: printf("ok\n"); ! 142: fflush(stdout); ! 143: continue; ! 144: } ! 145: if (sscanf(buf, "stat %s", name) == 1) { ! 146: if (stat(name, &statb) < 0) { ! 147: printf("ng\n"); ! 148: fflush(stdout); ! 149: continue; ! 150: } ! 151: printf("ok %ld %ld\n", statb.st_size, statb.st_mtime); ! 152: fflush(stdout); ! 153: continue; ! 154: } ! 155: if (sscanf(buf, "sum %s", name) == 1) { ! 156: printf("ok %ld\n", (long)getsum(name)); ! 157: fflush(stdout); ! 158: continue; ! 159: } ! 160: if (sscanf(buf, "send %s", name) == 1) { ! 161: ofd = open(name, 0); ! 162: if (ofd < 0) { ! 163: printf("ng\n"); ! 164: fflush(stdout); ! 165: continue; ! 166: } ! 167: printf("ok\n"); ! 168: fflush(stdout); ! 169: while ((x = read(ofd, buf, 1024)) > 0) ! 170: write(1, buf, x); ! 171: close(ofd); ! 172: write(1, buf, 0); ! 173: continue; ! 174: } ! 175: break; ! 176: } ! 177: exit(0); ! 178: } ! 179: ! 180: consider(name, statp, flag) ! 181: char *name; ! 182: struct stat *statp; ! 183: { ! 184: char buf[128]; ! 185: long lsum, rsum; ! 186: long size; ! 187: time_t date; ! 188: ! 189: switch (flag) { ! 190: ! 191: case FTW_F: ! 192: break; ! 193: ! 194: default: ! 195: printf("track: trouble with %s (%d)\n", name, flag); ! 196: case FTW_D: ! 197: case FTW_DP: ! 198: return(0); ! 199: } ! 200: alarm(60); ! 201: fprintf(torem, "stat %s %ld\n", remoten(name), statp->st_size); ! 202: fflush(torem); ! 203: vgetline(rem, buf, name); ! 204: if (sscanf(buf, "ok %ld %ld", &size, &date) != 2) { ! 205: if (vflag) ! 206: printf("track: %s not found (remote)\n", remoten(name)); ! 207: return(0); ! 208: } ! 209: if (size == statp->st_size) { ! 210: fprintf(torem, "sum %s\n", remoten(name)); ! 211: fflush(torem); ! 212: lsum = getsum(name); ! 213: vgetline(rem, buf, name); ! 214: if (sscanf(buf, "ok %ld", &rsum) != 1) { ! 215: printf("track: can't read sum for %s\n", remoten(name)); ! 216: exit(1); ! 217: } ! 218: if (lsum == rsum) { ! 219: if (vflag > 1) ! 220: printf("track: %s OK\n", name); ! 221: return(0); ! 222: } ! 223: } ! 224: if (tflag && statp->st_mtime > date) { ! 225: if (vflag) ! 226: printf("track: %s newer locally\n", name); ! 227: return(0); ! 228: } ! 229: if (nflag) { ! 230: printf("track: would copy %s\n", name); ! 231: return(0); ! 232: } ! 233: printf("track: copy %s:", name); ! 234: copy(name, rem, date); ! 235: return(0); ! 236: } ! 237: ! 238: copy(name, fd, date) ! 239: char *name; ! 240: time_t date; ! 241: { ! 242: char buf[1024]; ! 243: int ofd, nfd, i, n; ! 244: time_t ut[2]; ! 245: ! 246: fprintf(torem, "send %s\n", remoten(name)); ! 247: fflush(torem); ! 248: vgetline(fd, buf, name); ! 249: if (strcmp(buf, "ok") != 0) { ! 250: printf("can't open remote\n"); ! 251: return; ! 252: } ! 253: if ((ofd = creat(tempfile, 0644)) < 0) { ! 254: printf("can't open temp\n"); ! 255: return; ! 256: } ! 257: i = 10; ! 258: while ((n = read(fd, buf, 1024)) > 0) { ! 259: if (write(ofd, buf, n) != n) { ! 260: printf("write temp file\n"); ! 261: return; ! 262: } ! 263: if (--i <= 0) { ! 264: alarm(60); ! 265: i = 10; ! 266: } ! 267: } ! 268: close(ofd); ! 269: ofd = open(tempfile, 0); ! 270: if (ofd < 0) { ! 271: printf("can't reopen temp\n"); ! 272: return; ! 273: } ! 274: nfd = creat(name, 0777); ! 275: if (nfd < 0) { ! 276: printf("can't create new version\n"); ! 277: return; ! 278: } ! 279: while ((n = read(ofd, buf, 1024)) > 0) { ! 280: if (write(nfd, buf, n) != n) { ! 281: printf("write error in copy\n"); ! 282: return; ! 283: } ! 284: } ! 285: close(ofd); ! 286: close(nfd); ! 287: ut[0] = time((time_t)NULL); ! 288: ut[1] = date; ! 289: utime(name, ut); ! 290: printf("OK\n"); ! 291: } ! 292: ! 293: char * ! 294: remoten(name) ! 295: register char *name; ! 296: { ! 297: static char rname[256]; ! 298: ! 299: if (prefix[0] == '\0') ! 300: return(name); ! 301: if (name[0] != '/') { ! 302: strcpy(rname, prefix); ! 303: strcat(rname, "/"); ! 304: strcat(rname, name); ! 305: return(rname); ! 306: } ! 307: strcpy(rname, prefix); ! 308: strcat(rname, name+nsize); ! 309: return(rname); ! 310: } ! 311: ! 312: vgetline(fd, buf, name) ! 313: char *buf, *name; ! 314: { ! 315: if (getline(fd, buf)==0) { ! 316: printf("track: EOF on remote, file %s\n", name); ! 317: exit(1); ! 318: } ! 319: } ! 320: ! 321: getline(fd, buf) ! 322: char *buf; ! 323: { ! 324: register char *bp; ! 325: ! 326: bp = buf; ! 327: for(;;) { ! 328: if (read(fd, bp, 1) <= 0) ! 329: return(0); ! 330: if (*bp == '\n') { ! 331: *bp = '\0'; ! 332: return(1); ! 333: } ! 334: if (++bp >= &buf[128]) ! 335: return(0); ! 336: } ! 337: } ! 338: ! 339: unsigned ! 340: getsum(name) ! 341: char *name; ! 342: { ! 343: register FILE *f; ! 344: register unsigned sum; ! 345: register c; ! 346: ! 347: if ((f = fopen(name, "r")) == NULL) ! 348: return(-1); ! 349: sum = 0; ! 350: while ((c = getc(f)) != EOF) { ! 351: if (sum & 01) ! 352: sum = (sum>>1) + 0x8000; ! 353: else ! 354: sum >>= 1; ! 355: sum += c; ! 356: sum &= 0xFFFF; ! 357: } ! 358: fclose(f); ! 359: return(sum); ! 360: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.