|
|
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: if(strcmp(arnam, "-") == 0) { ! 353: if(comfun != pcmd && comfun != tcmd && comfun != xcmd) { ! 354: fprintf(stderr, "ar: archive on stdin only with [pxt]\n"); ! 355: done(1); ! 356: } ! 357: af = 0; ! 358: } ! 359: else af = open(arnam, 0); ! 360: if(af < 0) ! 361: return(1); ! 362: if (READ(af, mbuf, SARMAG) != SARMAG || strncmp(mbuf, ARMAG, SARMAG)) { ! 363: fprintf(stderr, "ar: %s not in archive format\n", arnam); ! 364: done(1); ! 365: } ! 366: return(0); ! 367: } ! 368: ! 369: getqf() ! 370: { ! 371: char mbuf[SARMAG]; ! 372: ! 373: if ((qf = open(arnam, 2)) < 0) { ! 374: if(!flg['c'-'a']) ! 375: fprintf(stderr, "ar: creating %s\n", arnam); ! 376: if ((qf = creat(arnam, 0666)) < 0) { ! 377: fprintf(stderr, "ar: cannot create %s\n", arnam); ! 378: done(1); ! 379: } ! 380: if (write(qf, ARMAG, SARMAG) != SARMAG) ! 381: wrerr(); ! 382: } else if (read(qf, mbuf, SARMAG) != SARMAG ! 383: || strncmp(mbuf, ARMAG, SARMAG)) { ! 384: fprintf(stderr, "ar: %s not in archive format\n", arnam); ! 385: done(1); ! 386: } ! 387: } ! 388: ! 389: usage() ! 390: { ! 391: printf("usage: ar [%s][%s] archive files ...\n", opt, man); ! 392: done(1); ! 393: } ! 394: ! 395: noar() ! 396: { ! 397: ! 398: fprintf(stderr, "ar: %s does not exist\n", arnam); ! 399: done(1); ! 400: } ! 401: ! 402: sigdone() ! 403: { ! 404: done(100); ! 405: } ! 406: ! 407: done(c) ! 408: { ! 409: ! 410: if(tfnam) ! 411: unlink(tfnam); ! 412: if(tf1nam) ! 413: unlink(tf1nam); ! 414: if(tf2nam) ! 415: unlink(tf2nam); ! 416: exit(c); ! 417: } ! 418: ! 419: notfound() ! 420: { ! 421: register i, n; ! 422: ! 423: n = 0; ! 424: for(i=0; i<namc; i++) ! 425: if(namv[i]) { ! 426: fprintf(stderr, "ar: %s not found\n", namv[i]); ! 427: n++; ! 428: } ! 429: return(n); ! 430: } ! 431: ! 432: morefil() ! 433: { ! 434: register i, n; ! 435: ! 436: n = 0; ! 437: for(i=0; i<namc; i++) ! 438: if(namv[i]) ! 439: n++; ! 440: return(n); ! 441: } ! 442: ! 443: cleanup() ! 444: { ! 445: register i, f; ! 446: ! 447: for(i=0; i<namc; i++) { ! 448: file = namv[i]; ! 449: if(file == 0) ! 450: continue; ! 451: namv[i] = 0; ! 452: mesg('a'); ! 453: f = stats(); ! 454: if(f < 0) { ! 455: fprintf(stderr, "ar: %s cannot open\n", file); ! 456: continue; ! 457: } ! 458: movefil(f); ! 459: } ! 460: install(); ! 461: } ! 462: ! 463: install() ! 464: { ! 465: register i; ! 466: ! 467: for(i=0; signum[i]; i++) ! 468: signal(signum[i], SIG_IGN); ! 469: if(af < 0) ! 470: if(!flg['c'-'a']) ! 471: fprintf(stderr, "ar: creating %s\n", arnam); ! 472: close(af); ! 473: af = creat(arnam, 0666); ! 474: if(af < 0) { ! 475: fprintf(stderr, "ar: cannot create %s\n", arnam); ! 476: done(1); ! 477: } ! 478: if(tfnam) { ! 479: lseek(tf, 0l, 0); ! 480: while((i = read(tf, buf, BUFSIZ)) > 0) ! 481: if (write(af, buf, i) != i) ! 482: wrerr(); ! 483: } ! 484: if(tf2nam) { ! 485: lseek(tf2, 0l, 0); ! 486: while((i = read(tf2, buf, BUFSIZ)) > 0) ! 487: if (write(af, buf, i) != i) ! 488: wrerr(); ! 489: } ! 490: if(tf1nam) { ! 491: lseek(tf1, 0l, 0); ! 492: while((i = read(tf1, buf, BUFSIZ)) > 0) ! 493: if (write(af, buf, i) != i) ! 494: wrerr(); ! 495: } ! 496: } ! 497: ! 498: /* ! 499: * insert the file 'file' ! 500: * into the temporary file ! 501: */ ! 502: movefil(f) ! 503: { ! 504: char buf[SAR_HDR+1]; ! 505: ! 506: sprintf(buf, "%-16s%-12ld%-6u%-6u%-8o%-10ld%-2s", ! 507: trim(file), ! 508: stbuf.st_mtime, ! 509: stbuf.st_uid, ! 510: stbuf.st_gid, ! 511: stbuf.st_mode, ! 512: stbuf.st_size, ! 513: ARFMAG); ! 514: strncpy((char *)&arbuf, buf, SAR_HDR); ! 515: larbuf.lar_size = stbuf.st_size; ! 516: copyfil(f, tf, OODD+HEAD); ! 517: close(f); ! 518: } ! 519: ! 520: stats() ! 521: { ! 522: register f; ! 523: ! 524: f = open(file, 0); ! 525: if(f < 0) ! 526: return(f); ! 527: if(fstat(f, &stbuf) < 0) { ! 528: close(f); ! 529: return(-1); ! 530: } ! 531: return(f); ! 532: } ! 533: ! 534: /* ! 535: * copy next file ! 536: * size given in arbuf ! 537: */ ! 538: copyfil(fi, fo, flag) ! 539: { ! 540: register i, o; ! 541: int pe; ! 542: ! 543: if(flag & HEAD) { ! 544: for (i=sizeof(arbuf.ar_name)-1; i>=0; i--) { ! 545: if (arbuf.ar_name[i]==' ') ! 546: continue; ! 547: else if (arbuf.ar_name[i]=='\0') ! 548: arbuf.ar_name[i] = ' '; ! 549: else ! 550: break; ! 551: } ! 552: if (write(fo, (char *)&arbuf, SAR_HDR) != SAR_HDR) ! 553: wrerr(); ! 554: } ! 555: pe = 0; ! 556: while(larbuf.lar_size > 0) { ! 557: i = o = BUFSIZ; ! 558: if(larbuf.lar_size < i) { ! 559: i = o = larbuf.lar_size; ! 560: if(i&1) { ! 561: buf[i] = '\n'; ! 562: if(flag & IODD) ! 563: i++; ! 564: if(flag & OODD) ! 565: o++; ! 566: } ! 567: } ! 568: if(READ(fi, buf, i) != i) ! 569: pe++; ! 570: if((flag & SKIP) == 0) ! 571: if (write(fo, buf, o) != o) ! 572: wrerr(); ! 573: larbuf.lar_size -= BUFSIZ; ! 574: } ! 575: if(pe) ! 576: phserr(); ! 577: } ! 578: ! 579: getdir() ! 580: { ! 581: register char *cp; ! 582: register i; ! 583: ! 584: i = READ(af, (char *)&arbuf, SAR_HDR); ! 585: if(i != SAR_HDR) { ! 586: if(tf1nam) { ! 587: i = tf; ! 588: tf = tf1; ! 589: tf1 = i; ! 590: } ! 591: return(1); ! 592: } ! 593: if (strncmp(arbuf.ar_fmag, ARFMAG, sizeof(arbuf.ar_fmag))) { ! 594: fprintf(stderr, "ar: malformed archive (at %ld)\n", lseek(af, 0L, 1)); ! 595: done(1); ! 596: } ! 597: cp = arbuf.ar_name + sizeof(arbuf.ar_name); ! 598: while (*--cp==' ') ! 599: ; ! 600: *++cp = '\0'; ! 601: strncpy(name, arbuf.ar_name, sizeof(arbuf.ar_name)); ! 602: file = name; ! 603: strncpy(larbuf.lar_name, name, sizeof(larbuf.lar_name)); ! 604: sscanf(arbuf.ar_date, "%ld", &larbuf.lar_date); ! 605: sscanf(arbuf.ar_uid, "%hd", &larbuf.lar_uid); ! 606: sscanf(arbuf.ar_gid, "%hd", &larbuf.lar_gid); ! 607: sscanf(arbuf.ar_mode, "%ho", &larbuf.lar_mode); ! 608: sscanf(arbuf.ar_size, "%ld", &larbuf.lar_size); ! 609: return(0); ! 610: } ! 611: ! 612: match() ! 613: { ! 614: register i; ! 615: ! 616: for(i=0; i<namc; i++) { ! 617: if(namv[i] == 0) ! 618: continue; ! 619: if(strcmp(trim(namv[i]), file) == 0) { ! 620: file = namv[i]; ! 621: namv[i] = 0; ! 622: return(1); ! 623: } ! 624: } ! 625: return(0); ! 626: } ! 627: ! 628: bamatch() ! 629: { ! 630: register f; ! 631: ! 632: switch(bastate) { ! 633: ! 634: case 1: ! 635: if(strcmp(file, ponam) != 0) ! 636: return; ! 637: bastate = 2; ! 638: if(flg['a'-'a']) ! 639: return; ! 640: ! 641: case 2: ! 642: bastate = 0; ! 643: tf1nam = mktemp(tmp1nam); ! 644: close(creat(tf1nam, 0600)); ! 645: f = open(tf1nam, 2); ! 646: if(f < 0) { ! 647: fprintf(stderr, "ar: cannot create second temp\n"); ! 648: return; ! 649: } ! 650: tf1 = tf; ! 651: tf = f; ! 652: } ! 653: } ! 654: ! 655: phserr() ! 656: { ! 657: ! 658: fprintf(stderr, "ar: phase error on %s\n", file); ! 659: } ! 660: ! 661: mesg(c) ! 662: { ! 663: ! 664: if(flg['v'-'a']) ! 665: if(c != 'c' || flg['v'-'a'] > 1) ! 666: printf("%c - %s\n", c, file); ! 667: } ! 668: ! 669: char * ! 670: trim(s) ! 671: char *s; ! 672: { ! 673: register char *p1, *p2; ! 674: ! 675: for(p1 = s; *p1; p1++) ! 676: ; ! 677: while(p1 > s) { ! 678: if(*--p1 != '/') ! 679: break; ! 680: *p1 = 0; ! 681: } ! 682: p2 = s; ! 683: for(p1 = s; *p1; p1++) ! 684: if(*p1 == '/') ! 685: p2 = p1+1; ! 686: return(p2); ! 687: } ! 688: ! 689: #define IFMT 060000 ! 690: #define ISARG 01000 ! 691: #define LARGE 010000 ! 692: #define SUID 04000 ! 693: #define SGID 02000 ! 694: #define ROWN 0400 ! 695: #define WOWN 0200 ! 696: #define XOWN 0100 ! 697: #define RGRP 040 ! 698: #define WGRP 020 ! 699: #define XGRP 010 ! 700: #define ROTH 04 ! 701: #define WOTH 02 ! 702: #define XOTH 01 ! 703: #define STXT 01000 ! 704: ! 705: longt() ! 706: { ! 707: register char *cp; ! 708: ! 709: pmode(); ! 710: printf("%3d/%1d", larbuf.lar_uid, larbuf.lar_gid); ! 711: printf("%7ld", larbuf.lar_size); ! 712: cp = ctime(&larbuf.lar_date); ! 713: printf(" %-12.12s %-4.4s ", cp+4, cp+20); ! 714: } ! 715: ! 716: int m1[] = { 1, ROWN, 'r', '-' }; ! 717: int m2[] = { 1, WOWN, 'w', '-' }; ! 718: int m3[] = { 2, SUID, 's', XOWN, 'x', '-' }; ! 719: int m4[] = { 1, RGRP, 'r', '-' }; ! 720: int m5[] = { 1, WGRP, 'w', '-' }; ! 721: int m6[] = { 2, SGID, 's', XGRP, 'x', '-' }; ! 722: int m7[] = { 1, ROTH, 'r', '-' }; ! 723: int m8[] = { 1, WOTH, 'w', '-' }; ! 724: int m9[] = { 2, STXT, 't', XOTH, 'x', '-' }; ! 725: ! 726: int *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9}; ! 727: ! 728: pmode() ! 729: { ! 730: register int **mp; ! 731: ! 732: for (mp = &m[0]; mp < &m[9];) ! 733: select(*mp++); ! 734: } ! 735: ! 736: select(pairp) ! 737: int *pairp; ! 738: { ! 739: register int n, *ap; ! 740: ! 741: ap = pairp; ! 742: n = *ap++; ! 743: while (--n>=0 && (larbuf.lar_mode&*ap++)==0) ! 744: ap++; ! 745: putchar(*ap); ! 746: } ! 747: ! 748: wrerr() ! 749: { ! 750: perror("ar write error"); ! 751: done(1); ! 752: } ! 753: READ(a, b, c) ! 754: char *b; ! 755: { ! 756: int i, j; ! 757: for(i = 0; i < c && (j = read(a, b+i, c-i)) > 0; i += j); ! 758: return i; ! 759: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.