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

Defined functions

bamatch defined in line 536; used 2 times
cleanup defined in line 371; used 1 times
copyfil defined in line 463; used 12 times
dcmd defined in line 197; used 2 times
done defined in line 346; used 13 times
getaf defined in line 313; used 6 times
getdir defined in line 498; used 6 times
init defined in line 298; used 3 times
install defined in line 391; used 3 times
longt defined in line 613; used 1 times
main defined in line 75; never used
match defined in line 520; used 6 times
mcmd defined in line 257; used 2 times
mesg defined in line 569; used 9 times
movefil defined in line 425; used 2 times
noar defined in line 334; used 5 times
notfound defined in line 358; used 1 times
pcmd defined in line 239; used 2 times
phserr defined in line 563; used 1 times
pmode defined in line 636; used 1 times
rcmd defined in line 162; used 3 times
select defined in line 644; used 1 times
setcom defined in line 151; used 7 times
sigdone defined in line 341; used 2 times
stats defined in line 445; used 2 times
swaphdr defined in line 663; used 2 times
tcmd defined in line 283; used 2 times
trim defined in line 577; used 5 times
usage defined in line 328; used 2 times
wrerr defined in line 656; used 6 times
xcmd defined in line 215; used 2 times

Defined variables

af defined in line 64; used 21 times
ar_date defined in line 17; used 5 times
ar_size defined in line 18; used 8 times
arbuf defined in line 35; used 21 times
arnam defined in line 57; used 7 times
bastate defined in line 68; used 4 times
buf defined in line 69; used 8 times
file defined in line 62; used 16 times
flg defined in line 54; used 13 times
m defined in line 634; used 2 times
  • in line 640(2)
m1 defined in line 624; used 1 times
m2 defined in line 625; used 1 times
m3 defined in line 626; used 1 times
m4 defined in line 627; used 1 times
m5 defined in line 628; used 1 times
m6 defined in line 629; used 1 times
m7 defined in line 630; used 1 times
m8 defined in line 631; used 1 times
m9 defined in line 632; used 1 times
man defined in line 42; used 3 times
namc defined in line 56; used 9 times
name defined in line 63; used 2 times
namv defined in line 55; used 9 times
opt defined in line 43; used 1 times
ponam defined in line 58; used 2 times
sccsid defined in line 1; never used
signum defined in line 45; used 5 times
stbuf defined in line 34; used 7 times
tf defined in line 65; used 13 times
tf1 defined in line 66; used 5 times
tf1nam defined in line 60; used 7 times
tf2 defined in line 67; used 5 times
tf2nam defined in line 61; used 6 times
tfnam defined in line 59; used 5 times

Defined struct's

ar_hdr defined in line 9; used 10 times

Defined macros

ARMAG defined in line 8; used 2 times
HEAD defined in line 40; used 6 times
IFMT defined in line 597; never used
IODD defined in line 38; used 12 times
ISARG defined in line 598; never used
LARGE defined in line 599; never used
OODD defined in line 39; used 6 times
RGRP defined in line 605; used 1 times
ROTH defined in line 608; used 1 times
ROWN defined in line 602; used 1 times
SGID defined in line 601; used 1 times
SKIP defined in line 37; used 6 times
STXT defined in line 611; used 1 times
SUID defined in line 600; used 1 times
WGRP defined in line 606; used 1 times
WOTH defined in line 609; used 1 times
WOWN defined in line 603; used 1 times
XGRP defined in line 607; used 1 times
XOTH defined in line 610; used 1 times
XOWN defined in line 604; used 1 times
fixhdr defined in line 30; used 2 times
fixshort defined in line 27; used 7 times
mklong defined in line 28; used 2 times
unmklong defined in line 29; used 2 times
Last modified: 1983-03-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2476
Valid CSS Valid XHTML 1.0 Strict