home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Tools / Tapes / newoldar.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-25  |  10.7 KB  |  731 lines

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