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