|
|
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: extern char *dkerror; ! 37: ! 38: if (argc <= 1) { ! 39: printf("track [-nvtr] {-f description | directory} machine\n"); ! 40: exit(0); ! 41: } ! 42: for (;;) { ! 43: switch (getopt(argc, argv, "vnrtf:d:")) { ! 44: ! 45: case 'v': ! 46: vflag++; ! 47: continue; ! 48: ! 49: case 'r': ! 50: rflag++; ! 51: continue; ! 52: ! 53: case 'n': ! 54: nflag++; ! 55: continue; ! 56: ! 57: case 't': ! 58: tflag++; ! 59: continue; ! 60: ! 61: case 'f': ! 62: descfile = optarg; ! 63: continue; ! 64: ! 65: case 'd': ! 66: strcpy(prefix, optarg); ! 67: continue; ! 68: case '?': ! 69: exit(1); ! 70: ! 71: case EOF: ! 72: default: ! 73: break; ! 74: } ! 75: break; ! 76: } ! 77: if (setjmp(almbuf)) { ! 78: if (rflag==0) ! 79: printf("track: alarm talking to %s\n", argv[optind]); ! 80: exit(1); ! 81: } ! 82: if (rflag) ! 83: remote(); ! 84: if (descfile) { ! 85: descfd = open(descfile, 0); ! 86: if (descfd <= 0) { ! 87: printf("track: can't open description %s", descfile); ! 88: exit(1); ! 89: } ! 90: } else { ! 91: if (optind >= argc) { ! 92: printf("track: no description file\n"); ! 93: exit(1); ! 94: } ! 95: descfile = argv[optind]; ! 96: optind++; ! 97: } ! 98: if (optind >= argc) { ! 99: printf("track: no machine given\n"); ! 100: exit(1); ! 101: } ! 102: rem = tdkexec(argv[optind], "track -r"); ! 103: if (rem < 0) { ! 104: printf("track: %s call failed: %s\n", argv[optind], dkerror); ! 105: exit(1); ! 106: } ! 107: torem = fdopen(rem, "w"); ! 108: fprintf(torem, "testing 123\n"); ! 109: fflush(torem); ! 110: vgetline(rem, buf, "<startup>"); ! 111: if (strncmp(buf, "ok", 2) !=0) { ! 112: printf("track: can't talk to remote\n"); ! 113: exit(1); ! 114: } ! 115: mktemp(tempfile); ! 116: if (descfd <= 0) { ! 117: if (prefix[0]) ! 118: nsize = strlen(descfile); ! 119: ftw(descfile, consider, 10); ! 120: } else { ! 121: while (getline(descfd, buf)) { ! 122: if (prefix[0]) ! 123: nsize = strlen(buf); ! 124: ftw(buf, consider, 10); ! 125: } ! 126: } ! 127: unlink(tempfile); ! 128: exit(1); ! 129: } ! 130: ! 131: remote() ! 132: { ! 133: char buf[1024]; ! 134: struct stat statb; ! 135: char name[128]; ! 136: int x, ofd; ! 137: char obuf[BUFSIZ]; ! 138: ! 139: setbuf(stdout, obuf); ! 140: while (getline(0, buf) != 0) { ! 141: if (sscanf(buf, "testing %d", &x) == 1) { ! 142: printf("ok\n"); ! 143: fflush(stdout); ! 144: continue; ! 145: } ! 146: if (sscanf(buf, "stat %s", name) == 1) { ! 147: if (stat(name, &statb) < 0) { ! 148: printf("ng\n"); ! 149: fflush(stdout); ! 150: continue; ! 151: } ! 152: printf("ok %ld %ld\n", statb.st_size, statb.st_mtime); ! 153: fflush(stdout); ! 154: continue; ! 155: } ! 156: if (sscanf(buf, "sum %s", name) == 1) { ! 157: printf("ok %ld\n", (long)getsum(name)); ! 158: fflush(stdout); ! 159: continue; ! 160: } ! 161: if (sscanf(buf, "send %s", name) == 1) { ! 162: ofd = open(name, 0); ! 163: if (ofd < 0) { ! 164: printf("ng\n"); ! 165: fflush(stdout); ! 166: continue; ! 167: } ! 168: printf("ok\n"); ! 169: fflush(stdout); ! 170: while ((x = read(ofd, buf, 1024)) > 0) ! 171: write(1, buf, x); ! 172: close(ofd); ! 173: write(1, buf, 0); ! 174: continue; ! 175: } ! 176: break; ! 177: } ! 178: exit(0); ! 179: } ! 180: ! 181: consider(name, statp, flag) ! 182: char *name; ! 183: struct stat *statp; ! 184: { ! 185: char buf[128]; ! 186: long lsum, rsum; ! 187: long size; ! 188: time_t date; ! 189: ! 190: switch (flag) { ! 191: ! 192: case FTW_F: ! 193: break; ! 194: ! 195: default: ! 196: printf("track: trouble with %s\n", name); ! 197: case FTW_D: ! 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.