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