home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / ar.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-01-10  |  10.0 KB  |  706 lines

  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. }
  706.