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[512];
  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, 512)) > 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, 512)) > 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, 512)) > 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 = 512;
 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 -= 512;
 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: }

Defined functions

bamatch defined in line 581; used 2 times
cleanup defined in line 420; used 1 times
copyfil defined in line 515; used 12 times
dcmd defined in line 182; used 2 times
done defined in line 384; used 16 times
getaf defined in line 329; used 6 times
getdir defined in line 546; used 6 times
getqf defined in line 343; used 1 times
init defined in line 314; used 3 times
install defined in line 440; used 3 times
longt defined in line 658; used 1 times
main defined in line 53; never used
match defined in line 565; used 6 times
mcmd defined in line 244; used 2 times
mesg defined in line 614; used 10 times
morefil defined in line 409; used 1 times
movefil defined in line 479; used 3 times
noar defined in line 372; used 5 times
notfound defined in line 396; used 1 times
pcmd defined in line 226; used 2 times
phserr defined in line 608; used 1 times
pmode defined in line 681; used 1 times
qcmd defined in line 285; used 2 times
rcmd defined in line 150; used 3 times
select defined in line 689; used 1 times
setcom defined in line 139; used 8 times
sigdone defined in line 379; used 2 times
stats defined in line 497; used 3 times
tcmd defined in line 270; used 2 times
trim defined in line 622; used 5 times
usage defined in line 366; used 2 times
wrerr defined in line 701; used 7 times
xcmd defined in line 200; used 2 times

Defined variables

af defined in line 41; used 22 times
arbuf defined in line 7; used 24 times
arnam defined in line 31; used 13 times
bastate defined in line 46; used 4 times
buf defined in line 47; used 8 times
file defined in line 39; used 19 times
flg defined in line 28; used 17 times
m defined in line 679; used 2 times
  • in line 685(2)
m1 defined in line 669; used 1 times
m2 defined in line 670; used 1 times
m3 defined in line 671; used 1 times
m4 defined in line 672; used 1 times
m5 defined in line 673; used 1 times
m6 defined in line 674; used 1 times
m7 defined in line 675; used 1 times
m8 defined in line 676; used 1 times
m9 defined in line 677; used 1 times
man defined in line 14; used 3 times
namc defined in line 30; used 12 times
name defined in line 40; used 2 times
namv defined in line 29; used 12 times
opt defined in line 15; used 1 times
ponam defined in line 32; used 2 times
qf defined in line 45; used 7 times
signum defined in line 17; used 7 times
stbuf defined in line 6; used 7 times
tf defined in line 42; used 15 times
tf1 defined in line 43; used 5 times
tf1nam defined in line 37; used 7 times
tf2 defined in line 44; used 5 times
tf2nam defined in line 38; used 6 times
tfnam defined in line 36; used 6 times
tmp1nam defined in line 34; used 2 times
tmp2nam defined in line 35; used 2 times
tmpnam defined in line 33; used 2 times

Defined macros

HEAD defined in line 12; used 6 times
IFMT defined in line 642; never used
IODD defined in line 10; used 12 times
ISARG defined in line 643; never used
LARGE defined in line 644; never used
OODD defined in line 11; used 6 times
RGRP defined in line 650; used 1 times
ROTH defined in line 653; used 1 times
ROWN defined in line 647; used 1 times
SGID defined in line 646; used 1 times
SKIP defined in line 9; used 6 times
STXT defined in line 656; used 1 times
SUID defined in line 645; used 1 times
WGRP defined in line 651; used 1 times
WOTH defined in line 654; used 1 times
WOWN defined in line 648; used 1 times
XGRP defined in line 652; used 1 times
XOTH defined in line 655; used 1 times
XOWN defined in line 649; used 1 times
Last modified: 1981-07-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2646
Valid CSS Valid XHTML 1.0 Strict