|
|
1.1 ! root 1: ! 2: /* ar11 - archiver for PDP-11 formatted archives */ ! 3: ! 4: #include <signal.h> ! 5: #include <stdio.h> ! 6: #include <sys/types.h> ! 7: #include <sys/stat.h> ! 8: #define ARMAG -155 /* 017545 */ ! 9: struct ar_hdr { ! 10: char ar_name[14]; ! 11: short ar_date1; ! 12: short ar_date2; ! 13: char ar_uid; ! 14: char ar_gid; ! 15: short ar_mode; ! 16: short ar_size1; ! 17: short ar_size2; ! 18: }; ! 19: int ar_date; ! 20: int ar_size; ! 21: #include <signal.h> ! 22: struct stat stbuf; ! 23: struct ar_hdr arbuf; ! 24: union ints ! 25: { ! 26: struct fun ! 27: { ! 28: short h1; ! 29: short h2; ! 30: }; ! 31: int w1; ! 32: } x; ! 33: ! 34: #define SKIP 1 ! 35: #define IODD 2 ! 36: #define OODD 4 ! 37: #define HEAD 8 ! 38: ! 39: char *man = { "mrxtdp" }; ! 40: char *opt = { "uvnbai" }; ! 41: ! 42: int signum[] = {SIGHUP, SIGINT, SIGQUIT, 0}; ! 43: int sigdone(); ! 44: int rcmd(); ! 45: int dcmd(); ! 46: int xcmd(); ! 47: int tcmd(); ! 48: int pcmd(); ! 49: int mcmd(); ! 50: int (*comfun)(); ! 51: char flg[26]; ! 52: char **namv; ! 53: int namc; ! 54: char *arnam; ! 55: char *ponam; ! 56: char *tfnam; ! 57: char *tf1nam; ! 58: char *tf2nam; ! 59: char *file; ! 60: char name[16]; ! 61: int af; ! 62: int tf; ! 63: int tf1; ! 64: int tf2; ! 65: int bastate; ! 66: char buf[512]; ! 67: ! 68: char *trim(); ! 69: char *mktemp(); ! 70: char *ctime(); ! 71: ! 72: main(argc, argv) ! 73: char *argv[]; ! 74: { ! 75: register i; ! 76: register char *cp; ! 77: ! 78: for(i=0; signum[i]; i++) ! 79: if(signal(signum[i], SIG_IGN) != SIG_IGN) ! 80: signal(signum[i], sigdone); ! 81: if(argc < 3) ! 82: usage(); ! 83: cp = argv[1]; ! 84: for(cp = argv[1]; *cp; cp++) ! 85: switch(*cp) { ! 86: case 'c': ! 87: case 'v': ! 88: case 'u': ! 89: case 'n': ! 90: case 'a': ! 91: case 'b': ! 92: case 'i': ! 93: flg[*cp - 'a']++; ! 94: continue; ! 95: ! 96: case 'r': ! 97: setcom(rcmd); ! 98: continue; ! 99: ! 100: case 'd': ! 101: setcom(dcmd); ! 102: continue; ! 103: ! 104: case 'x': ! 105: setcom(xcmd); ! 106: continue; ! 107: ! 108: case 't': ! 109: setcom(tcmd); ! 110: continue; ! 111: ! 112: case 'p': ! 113: setcom(pcmd); ! 114: continue; ! 115: ! 116: case 'm': ! 117: setcom(mcmd); ! 118: continue; ! 119: ! 120: default: ! 121: fprintf(stderr, "ar11: bad option `%c'\n", *cp); ! 122: done(1); ! 123: } ! 124: if(flg['i'-'a']) ! 125: flg['b'-'a']++; ! 126: if(flg['a'-'a'] || flg['b'-'a']) { ! 127: bastate = 1; ! 128: ponam = trim(argv[2]); ! 129: argv++; ! 130: argc--; ! 131: if(argc < 3) ! 132: usage(); ! 133: } ! 134: arnam = argv[2]; ! 135: namv = argv+3; ! 136: namc = argc-3; ! 137: if(comfun == 0) { ! 138: if(flg['u'-'a'] == 0) { ! 139: fprintf(stderr, "ar11: one of [%s] must be specified\n", man); ! 140: done(1); ! 141: } ! 142: setcom(rcmd); ! 143: } ! 144: (*comfun)(); ! 145: done(notfound()); ! 146: } ! 147: ! 148: setcom(fun) ! 149: int (*fun)(); ! 150: { ! 151: ! 152: if(comfun != 0) { ! 153: fprintf(stderr, "ar11: only one of [%s] allowed\n", man); ! 154: done(1); ! 155: } ! 156: comfun = fun; ! 157: } ! 158: ! 159: rcmd() ! 160: { ! 161: register f; ! 162: ! 163: init(); ! 164: if(getaf() && flg['c'-'a']==0) { ! 165: fprintf(stderr, "ar11: %s does not exist\n", arnam); ! 166: done(1); ! 167: } ! 168: while(!getdir()) { ! 169: bamatch(); ! 170: if(namc == 0 || match()) { ! 171: f = stats(); ! 172: if(f < 0) { ! 173: if(namc) ! 174: fprintf(stderr, "ar11: cannot open %s\n", file); ! 175: goto cp; ! 176: } ! 177: if(flg['u'-'a']) ! 178: if(stbuf.st_mtime <= ar_date) { ! 179: close(f); ! 180: goto cp; ! 181: } ! 182: mesg('r'); ! 183: copyfil(af, -1, IODD+SKIP); ! 184: movefil(f); ! 185: continue; ! 186: } ! 187: cp: ! 188: mesg('c'); ! 189: copyfil(af, tf, IODD+OODD+HEAD); ! 190: } ! 191: cleanup(); ! 192: } ! 193: ! 194: dcmd() ! 195: { ! 196: ! 197: init(); ! 198: if(getaf()) ! 199: noar(); ! 200: while(!getdir()) { ! 201: if(match()) { ! 202: mesg('d'); ! 203: copyfil(af, -1, IODD+SKIP); ! 204: continue; ! 205: } ! 206: mesg('c'); ! 207: copyfil(af, tf, IODD+OODD+HEAD); ! 208: } ! 209: install(); ! 210: } ! 211: ! 212: xcmd() ! 213: { ! 214: register f; ! 215: ! 216: if(getaf()) ! 217: noar(); ! 218: while(!getdir()) { ! 219: if(namc == 0 || match()) { ! 220: f = creat(file, arbuf.ar_mode & 0777); ! 221: if(f < 0) { ! 222: fprintf(stderr, "ar11: %s cannot create\n", file); ! 223: goto sk; ! 224: } ! 225: mesg('x'); ! 226: copyfil(af, f, IODD); ! 227: close(f); ! 228: continue; ! 229: } ! 230: sk: ! 231: mesg('c'); ! 232: copyfil(af, -1, IODD+SKIP); ! 233: } ! 234: } ! 235: ! 236: pcmd() ! 237: { ! 238: ! 239: if(getaf()) ! 240: noar(); ! 241: while(!getdir()) { ! 242: if(namc == 0 || match()) { ! 243: if(flg['v'-'a']) { ! 244: printf("\n<%s>\n\n", file); ! 245: fflush(stdout); ! 246: } ! 247: copyfil(af, 1, IODD); ! 248: continue; ! 249: } ! 250: copyfil(af, -1, IODD+SKIP); ! 251: } ! 252: } ! 253: ! 254: mcmd() ! 255: { ! 256: ! 257: init(); ! 258: if(getaf()) ! 259: noar(); ! 260: tf2nam = mktemp("/tmp/v2XXXXX"); ! 261: close(creat(tf2nam, 0600)); ! 262: tf2 = open(tf2nam, 2); ! 263: if(tf2 < 0) { ! 264: fprintf(stderr, "ar11: cannot create third temp\n"); ! 265: done(1); ! 266: } ! 267: while(!getdir()) { ! 268: bamatch(); ! 269: if(match()) { ! 270: mesg('m'); ! 271: copyfil(af, tf2, IODD+OODD+HEAD); ! 272: continue; ! 273: } ! 274: mesg('c'); ! 275: copyfil(af, tf, IODD+OODD+HEAD); ! 276: } ! 277: install(); ! 278: } ! 279: ! 280: tcmd() ! 281: { ! 282: ! 283: if(getaf()) ! 284: noar(); ! 285: while(!getdir()) { ! 286: if(namc == 0 || match()) { ! 287: if(flg['v'-'a']) ! 288: longt(); ! 289: printf("%s\n", trim(file)); ! 290: } ! 291: copyfil(af, -1, IODD+SKIP); ! 292: } ! 293: } ! 294: ! 295: init() ! 296: { ! 297: static short mbuf = ARMAG; ! 298: ! 299: tfnam = mktemp("/tmp/vXXXXX"); ! 300: close(creat(tfnam, 0600)); ! 301: tf = open(tfnam, 2); ! 302: if(tf < 0) { ! 303: fprintf(stderr, "ar11: cannot create temp file\n"); ! 304: done(1); ! 305: } ! 306: if (write(tf, (char *)&mbuf, sizeof(short)) != sizeof(short)) ! 307: wrerr(); ! 308: } ! 309: ! 310: getaf() ! 311: { ! 312: short mbuf; ! 313: ! 314: af = open(arnam, 0); ! 315: if(af < 0) ! 316: return(1); ! 317: if (read(af, (char *)&mbuf, sizeof(short)) != sizeof(short) || mbuf!=ARMAG) { ! 318: fprintf(stderr, "ar11: %s not in PDP-11 archive format\n", arnam); ! 319: done(1); ! 320: } ! 321: return(0); ! 322: } ! 323: ! 324: usage() ! 325: { ! 326: printf("usage: ar11 [%s][%s] archive files ...\n", opt, man); ! 327: done(1); ! 328: } ! 329: ! 330: noar() ! 331: { ! 332: ! 333: fprintf(stderr, "ar11: %s does not exist\n", arnam); ! 334: done(1); ! 335: } ! 336: ! 337: sigdone() ! 338: { ! 339: done(100); ! 340: } ! 341: ! 342: done(c) ! 343: { ! 344: ! 345: if(tfnam) ! 346: unlink(tfnam); ! 347: if(tf1nam) ! 348: unlink(tf1nam); ! 349: if(tf2nam) ! 350: unlink(tf2nam); ! 351: exit(c); ! 352: } ! 353: ! 354: notfound() ! 355: { ! 356: register i, n; ! 357: ! 358: n = 0; ! 359: for(i=0; i<namc; i++) ! 360: if(namv[i]) { ! 361: fprintf(stderr, "ar11: %s not found\n", namv[i]); ! 362: n++; ! 363: } ! 364: return(n); ! 365: } ! 366: ! 367: cleanup() ! 368: { ! 369: register i, f; ! 370: ! 371: for(i=0; i<namc; i++) { ! 372: file = namv[i]; ! 373: if(file == 0) ! 374: continue; ! 375: namv[i] = 0; ! 376: mesg('a'); ! 377: f = stats(); ! 378: if(f < 0) { ! 379: fprintf(stderr, "ar11: %s cannot open\n", file); ! 380: continue; ! 381: } ! 382: movefil(f); ! 383: } ! 384: install(); ! 385: } ! 386: ! 387: install() ! 388: { ! 389: register i; ! 390: ! 391: for(i=0; signum[i]; i++) ! 392: signal(signum[i], (int (*)())1); ! 393: close(af); ! 394: af = creat(arnam, 0666); ! 395: if(af < 0) { ! 396: fprintf(stderr, "ar11: cannot create %s\n", arnam); ! 397: done(1); ! 398: } ! 399: lseek(tf, 0l, 0); ! 400: while((i = read(tf, buf, 512)) > 0) ! 401: if (write(af, buf, i) != i) ! 402: wrerr(); ! 403: if(tf2nam) { ! 404: lseek(tf2, 0l, 0); ! 405: while((i = read(tf2, buf, 512)) > 0) ! 406: if (write(af, buf, i) != i) ! 407: wrerr(); ! 408: } ! 409: if(tf1nam) { ! 410: lseek(tf1, 0l, 0); ! 411: while((i = read(tf1, buf, 512)) > 0) ! 412: if (write(af, buf, i) != i) ! 413: wrerr(); ! 414: } ! 415: } ! 416: ! 417: /* ! 418: * insert the file 'file' ! 419: * into the temporary file ! 420: */ ! 421: movefil(f) ! 422: { ! 423: register char *cp; ! 424: register i; ! 425: ! 426: cp = trim(file); ! 427: for(i=0; i<14; i++) ! 428: if(arbuf.ar_name[i] = *cp) ! 429: cp++; ! 430: x.w1 = stbuf.st_size; ! 431: arbuf.ar_size1 = x.h2; ! 432: arbuf.ar_size2 = x.h1; ! 433: x.w1 = stbuf.st_mtime; ! 434: arbuf.ar_date1 = x.h2; ! 435: arbuf.ar_date2 = x.h1; ! 436: arbuf.ar_uid = stbuf.st_uid; ! 437: arbuf.ar_gid = stbuf.st_gid; ! 438: arbuf.ar_mode = stbuf.st_mode; ! 439: copyfil(f, tf, OODD+HEAD); ! 440: close(f); ! 441: } ! 442: ! 443: stats() ! 444: { ! 445: register f; ! 446: ! 447: f = open(file, 0); ! 448: if(f < 0) ! 449: return(f); ! 450: if(fstat(f, &stbuf) < 0) { ! 451: close(f); ! 452: return(-1); ! 453: } ! 454: return(f); ! 455: } ! 456: ! 457: /* ! 458: * copy next file ! 459: * size given in arbuf ! 460: */ ! 461: copyfil(fi, fo, flag) ! 462: { ! 463: register i, o; ! 464: int pe; ! 465: ! 466: if(flag & HEAD) ! 467: if (write(fo, (char *)&arbuf, sizeof arbuf) != sizeof arbuf) ! 468: wrerr(); ! 469: pe = 0; ! 470: while(ar_size > 0) { ! 471: i = o = 512; ! 472: if(ar_size < i) { ! 473: i = o = ar_size; ! 474: if(i&1) { ! 475: if(flag & IODD) ! 476: i++; ! 477: if(flag & OODD) ! 478: o++; ! 479: } ! 480: } ! 481: if(read(fi, buf, i) != i) ! 482: pe++; ! 483: if((flag & SKIP) == 0) ! 484: if (write(fo, buf, o) != o) ! 485: wrerr(); ! 486: ar_size -= 512; ! 487: } ! 488: if(pe) ! 489: phserr(); ! 490: } ! 491: ! 492: getdir() ! 493: { ! 494: register i; ! 495: ! 496: i = read(af, (char *)&arbuf, sizeof arbuf); ! 497: if(i != sizeof arbuf) { ! 498: if(tf1nam) { ! 499: i = tf; ! 500: tf = tf1; ! 501: tf1 = i; ! 502: } ! 503: return(1); ! 504: } ! 505: for(i=0; i<14; i++) ! 506: { ! 507: name[i] = arbuf.ar_name[i]; ! 508: } ! 509: file = name; ! 510: ar_date = swap(&arbuf.ar_date1); ! 511: ar_size = swap(&arbuf.ar_size1); ! 512: return(0); ! 513: } ! 514: ! 515: match() ! 516: { ! 517: register i; ! 518: ! 519: for(i=0; i<namc; i++) { ! 520: if(namv[i] == 0) ! 521: continue; ! 522: if(strcmp(trim(namv[i]), file) == 0) { ! 523: file = namv[i]; ! 524: namv[i] = 0; ! 525: return(1); ! 526: } ! 527: } ! 528: return(0); ! 529: } ! 530: ! 531: bamatch() ! 532: { ! 533: register f; ! 534: ! 535: switch(bastate) { ! 536: ! 537: case 1: ! 538: if(strcmp(file, ponam) != 0) ! 539: return; ! 540: bastate = 2; ! 541: if(flg['a'-'a']) ! 542: return; ! 543: ! 544: case 2: ! 545: bastate = 0; ! 546: tf1nam = mktemp("/tmp/v1XXXXX"); ! 547: close(creat(tf1nam, 0600)); ! 548: f = open(tf1nam, 2); ! 549: if(f < 0) { ! 550: fprintf(stderr, "ar11: cannot create second temp\n"); ! 551: return; ! 552: } ! 553: tf1 = tf; ! 554: tf = f; ! 555: } ! 556: } ! 557: ! 558: phserr() ! 559: { ! 560: ! 561: fprintf(stderr, "ar11: phase error on %s\n", file); ! 562: } ! 563: ! 564: mesg(c) ! 565: { ! 566: ! 567: if(flg['v'-'a']) ! 568: if(c != 'c' || flg['v'-'a'] > 1) ! 569: printf("%c - %s\n", c, file); ! 570: } ! 571: ! 572: char * ! 573: trim(s) ! 574: char *s; ! 575: { ! 576: register char *p1, *p2; ! 577: ! 578: for(p1 = s; *p1; p1++) ! 579: ; ! 580: while(p1 > s) { ! 581: if(*--p1 != '/') ! 582: break; ! 583: *p1 = 0; ! 584: } ! 585: p2 = s; ! 586: for(p1 = s; *p1; p1++) ! 587: if(*p1 == '/') ! 588: p2 = p1+1; ! 589: return(p2); ! 590: } ! 591: ! 592: #define IFMT 060000 ! 593: #define ISARG 01000 ! 594: #define LARGE 010000 ! 595: #define SUID 04000 ! 596: #define SGID 02000 ! 597: #define ROWN 0400 ! 598: #define WOWN 0200 ! 599: #define XOWN 0100 ! 600: #define RGRP 040 ! 601: #define WGRP 020 ! 602: #define XGRP 010 ! 603: #define ROTH 04 ! 604: #define WOTH 02 ! 605: #define XOTH 01 ! 606: #define STXT 01000 ! 607: ! 608: longt() ! 609: { ! 610: register char *cp; ! 611: ! 612: pmode(); ! 613: printf("%3d/%1d", arbuf.ar_uid, arbuf.ar_gid); ! 614: printf("%7D", ar_size); ! 615: cp = ctime(&ar_date); ! 616: printf(" %-12.12s %-4.4s ", cp+4, cp+20); ! 617: } ! 618: ! 619: int m1[] = { 1, ROWN, 'r', '-' }; ! 620: int m2[] = { 1, WOWN, 'w', '-' }; ! 621: int m3[] = { 2, SUID, 's', XOWN, 'x', '-' }; ! 622: int m4[] = { 1, RGRP, 'r', '-' }; ! 623: int m5[] = { 1, WGRP, 'w', '-' }; ! 624: int m6[] = { 2, SGID, 's', XGRP, 'x', '-' }; ! 625: int m7[] = { 1, ROTH, 'r', '-' }; ! 626: int m8[] = { 1, WOTH, 'w', '-' }; ! 627: int m9[] = { 2, STXT, 't', XOTH, 'x', '-' }; ! 628: ! 629: int *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9}; ! 630: ! 631: pmode() ! 632: { ! 633: register int **mp; ! 634: ! 635: for (mp = &m[0]; mp < &m[9];) ! 636: select(*mp++); ! 637: } ! 638: ! 639: select(pairp) ! 640: int *pairp; ! 641: { ! 642: register int n, *ap; ! 643: ! 644: ap = pairp; ! 645: n = *ap++; ! 646: while (--n>=0 && (arbuf.ar_mode&*ap++)==0) ! 647: ap++; ! 648: putchar(*ap); ! 649: } ! 650: ! 651: wrerr() ! 652: { ! 653: perror("ar write error"); ! 654: done(1); ! 655: } ! 656: ! 657: swap(word) ! 658: short *word; ! 659: { ! 660: x.h1 = ((struct fun *)word)->h2; ! 661: x.h2 = ((struct fun *)word)->h1; ! 662: ! 663: return(x.w1); ! 664: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.