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