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