|
|
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 = tdkexec(argv[optind], "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\n", name); ! 196: case FTW_D: ! 197: return(0); ! 198: } ! 199: alarm(60); ! 200: fprintf(torem, "stat %s %ld\n", remoten(name), statp->st_size); ! 201: fflush(torem); ! 202: vgetline(rem, buf, name); ! 203: if (sscanf(buf, "ok %ld %ld", &size, &date) != 2) { ! 204: if (vflag) ! 205: printf("track: %s not found (remote)\n", remoten(name)); ! 206: return(0); ! 207: } ! 208: if (size == statp->st_size) { ! 209: fprintf(torem, "sum %s\n", remoten(name)); ! 210: fflush(torem); ! 211: lsum = getsum(name); ! 212: vgetline(rem, buf, name); ! 213: if (sscanf(buf, "ok %ld", &rsum) != 1) { ! 214: printf("track: can't read sum for %s\n", remoten(name)); ! 215: exit(1); ! 216: } ! 217: if (lsum == rsum) { ! 218: if (vflag > 1) ! 219: printf("track: %s OK\n", name); ! 220: return(0); ! 221: } ! 222: } ! 223: if (tflag && statp->st_mtime > date) { ! 224: if (vflag) ! 225: printf("track: %s newer locally\n", name); ! 226: return(0); ! 227: } ! 228: if (nflag) { ! 229: printf("track: would copy %s\n", name); ! 230: return(0); ! 231: } ! 232: printf("track: copy %s:", name); ! 233: copy(name, rem, date); ! 234: return(0); ! 235: } ! 236: ! 237: copy(name, fd, date) ! 238: char *name; ! 239: time_t date; ! 240: { ! 241: char buf[1024]; ! 242: int ofd, nfd, i, n; ! 243: time_t ut[2]; ! 244: ! 245: fprintf(torem, "send %s\n", remoten(name)); ! 246: fflush(torem); ! 247: vgetline(fd, buf, name); ! 248: if (strcmp(buf, "ok") != 0) { ! 249: printf("can't open remote\n"); ! 250: return; ! 251: } ! 252: if ((ofd = creat(tempfile, 0644)) < 0) { ! 253: printf("can't open temp\n"); ! 254: return; ! 255: } ! 256: i = 10; ! 257: while ((n = read(fd, buf, 1024)) > 0) { ! 258: if (write(ofd, buf, n) != n) { ! 259: printf("write temp file\n"); ! 260: return; ! 261: } ! 262: if (--i <= 0) { ! 263: alarm(60); ! 264: i = 10; ! 265: } ! 266: } ! 267: close(ofd); ! 268: ofd = open(tempfile, 0); ! 269: if (ofd < 0) { ! 270: printf("can't reopen temp\n"); ! 271: return; ! 272: } ! 273: nfd = creat(name, 0777); ! 274: if (nfd < 0) { ! 275: printf("can't create new version\n"); ! 276: return; ! 277: } ! 278: while ((n = read(ofd, buf, 1024)) > 0) { ! 279: if (write(nfd, buf, n) != n) { ! 280: printf("write error in copy\n"); ! 281: return; ! 282: } ! 283: } ! 284: close(ofd); ! 285: close(nfd); ! 286: ut[0] = time((time_t)NULL); ! 287: ut[1] = date; ! 288: utime(name, ut); ! 289: printf("OK\n"); ! 290: } ! 291: ! 292: char * ! 293: remoten(name) ! 294: register char *name; ! 295: { ! 296: static char rname[256]; ! 297: ! 298: if (prefix[0] == '\0') ! 299: return(name); ! 300: if (name[0] != '/') { ! 301: strcpy(rname, prefix); ! 302: strcat(rname, "/"); ! 303: strcat(rname, name); ! 304: return(rname); ! 305: } ! 306: strcpy(rname, prefix); ! 307: strcat(rname, name+nsize); ! 308: return(rname); ! 309: } ! 310: ! 311: vgetline(fd, buf, name) ! 312: char *buf, *name; ! 313: { ! 314: if (getline(fd, buf)==0) { ! 315: printf("track: EOF on remote, file %s\n", name); ! 316: exit(1); ! 317: } ! 318: } ! 319: ! 320: getline(fd, buf) ! 321: char *buf; ! 322: { ! 323: register char *bp; ! 324: ! 325: bp = buf; ! 326: for(;;) { ! 327: if (read(fd, bp, 1) <= 0) ! 328: return(0); ! 329: if (*bp == '\n') { ! 330: *bp = '\0'; ! 331: return(1); ! 332: } ! 333: if (++bp >= &buf[128]) ! 334: return(0); ! 335: } ! 336: } ! 337: ! 338: unsigned ! 339: getsum(name) ! 340: char *name; ! 341: { ! 342: register FILE *f; ! 343: register unsigned sum; ! 344: register c; ! 345: ! 346: if ((f = fopen(name, "r")) == NULL) ! 347: return(-1); ! 348: sum = 0; ! 349: while ((c = getc(f)) != EOF) { ! 350: if (sum & 01) ! 351: sum = (sum>>1) + 0x8000; ! 352: else ! 353: sum >>= 1; ! 354: sum += c; ! 355: sum &= 0xFFFF; ! 356: } ! 357: fclose(f); ! 358: return(sum); ! 359: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.