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