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

  1. #include <stdio.h>
  2. #include <signal.h>
  3.  
  4. #define    BIG    32767
  5. #define    LCASE    01
  6. #define    UCASE    02
  7. #define    SWAB    04
  8. #define NERR    010
  9. #define SYNC    020
  10. int    cflag;
  11. int    fflag;
  12. int    skip;
  13. int    seekn;
  14. int    count;
  15. int    files    = 1;
  16. char    *string;
  17. char    *ifile;
  18. char    *ofile;
  19. char    *ibuf;
  20. char    *obuf;
  21. char    *sbrk();
  22. int    ibs    = 512;
  23. int    obs    = 512;
  24. int    bs;
  25. int    cbs;
  26. int    ibc;
  27. int    obc;
  28. int    cbc;
  29. int    nifr;
  30. int    nipr;
  31. int    nofr;
  32. int    nopr;
  33. int    ntrunc;
  34. int    ibf;
  35. int    obf;
  36. char    *op;
  37. int    nspace;
  38. char    etoa[] = {
  39.     0000,0001,0002,0003,0234,0011,0206,0177,
  40.     0227,0215,0216,0013,0014,0015,0016,0017,
  41.     0020,0021,0022,0023,0235,0205,0010,0207,
  42.     0030,0031,0222,0217,0034,0035,0036,0037,
  43.     0200,0201,0202,0203,0204,0012,0027,0033,
  44.     0210,0211,0212,0213,0214,0005,0006,0007,
  45.     0220,0221,0026,0223,0224,0225,0226,0004,
  46.     0230,0231,0232,0233,0024,0025,0236,0032,
  47.     0040,0240,0241,0242,0243,0244,0245,0246,
  48.     0247,0250,0133,0056,0074,0050,0053,0041,
  49.     0046,0251,0252,0253,0254,0255,0256,0257,
  50.     0260,0261,0135,0044,0052,0051,0073,0136,
  51.     0055,0057,0262,0263,0264,0265,0266,0267,
  52.     0270,0271,0174,0054,0045,0137,0076,0077,
  53.     0272,0273,0274,0275,0276,0277,0300,0301,
  54.     0302,0140,0072,0043,0100,0047,0075,0042,
  55.     0303,0141,0142,0143,0144,0145,0146,0147,
  56.     0150,0151,0304,0305,0306,0307,0310,0311,
  57.     0312,0152,0153,0154,0155,0156,0157,0160,
  58.     0161,0162,0313,0314,0315,0316,0317,0320,
  59.     0321,0176,0163,0164,0165,0166,0167,0170,
  60.     0171,0172,0322,0323,0324,0325,0326,0327,
  61.     0330,0331,0332,0333,0334,0335,0336,0337,
  62.     0340,0341,0342,0343,0344,0345,0346,0347,
  63.     0173,0101,0102,0103,0104,0105,0106,0107,
  64.     0110,0111,0350,0351,0352,0353,0354,0355,
  65.     0175,0112,0113,0114,0115,0116,0117,0120,
  66.     0121,0122,0356,0357,0360,0361,0362,0363,
  67.     0134,0237,0123,0124,0125,0126,0127,0130,
  68.     0131,0132,0364,0365,0366,0367,0370,0371,
  69.     0060,0061,0062,0063,0064,0065,0066,0067,
  70.     0070,0071,0372,0373,0374,0375,0376,0377,
  71. };
  72. char    atoe[] = {
  73.     0000,0001,0002,0003,0067,0055,0056,0057,
  74.     0026,0005,0045,0013,0014,0015,0016,0017,
  75.     0020,0021,0022,0023,0074,0075,0062,0046,
  76.     0030,0031,0077,0047,0034,0035,0036,0037,
  77.     0100,0117,0177,0173,0133,0154,0120,0175,
  78.     0115,0135,0134,0116,0153,0140,0113,0141,
  79.     0360,0361,0362,0363,0364,0365,0366,0367,
  80.     0370,0371,0172,0136,0114,0176,0156,0157,
  81.     0174,0301,0302,0303,0304,0305,0306,0307,
  82.     0310,0311,0321,0322,0323,0324,0325,0326,
  83.     0327,0330,0331,0342,0343,0344,0345,0346,
  84.     0347,0350,0351,0112,0340,0132,0137,0155,
  85.     0171,0201,0202,0203,0204,0205,0206,0207,
  86.     0210,0211,0221,0222,0223,0224,0225,0226,
  87.     0227,0230,0231,0242,0243,0244,0245,0246,
  88.     0247,0250,0251,0300,0152,0320,0241,0007,
  89.     0040,0041,0042,0043,0044,0025,0006,0027,
  90.     0050,0051,0052,0053,0054,0011,0012,0033,
  91.     0060,0061,0032,0063,0064,0065,0066,0010,
  92.     0070,0071,0072,0073,0004,0024,0076,0341,
  93.     0101,0102,0103,0104,0105,0106,0107,0110,
  94.     0111,0121,0122,0123,0124,0125,0126,0127,
  95.     0130,0131,0142,0143,0144,0145,0146,0147,
  96.     0150,0151,0160,0161,0162,0163,0164,0165,
  97.     0166,0167,0170,0200,0212,0213,0214,0215,
  98.     0216,0217,0220,0232,0233,0234,0235,0236,
  99.     0237,0240,0252,0253,0254,0255,0256,0257,
  100.     0260,0261,0262,0263,0264,0265,0266,0267,
  101.     0270,0271,0272,0273,0274,0275,0276,0277,
  102.     0312,0313,0314,0315,0316,0317,0332,0333,
  103.     0334,0335,0336,0337,0352,0353,0354,0355,
  104.     0356,0357,0372,0373,0374,0375,0376,0377,
  105. };
  106. char    atoibm[] =
  107. {
  108.     0000,0001,0002,0003,0067,0055,0056,0057,
  109.     0026,0005,0045,0013,0014,0015,0016,0017,
  110.     0020,0021,0022,0023,0074,0075,0062,0046,
  111.     0030,0031,0077,0047,0034,0035,0036,0037,
  112.     0100,0132,0177,0173,0133,0154,0120,0175,
  113.     0115,0135,0134,0116,0153,0140,0113,0141,
  114.     0360,0361,0362,0363,0364,0365,0366,0367,
  115.     0370,0371,0172,0136,0114,0176,0156,0157,
  116.     0174,0301,0302,0303,0304,0305,0306,0307,
  117.     0310,0311,0321,0322,0323,0324,0325,0326,
  118.     0327,0330,0331,0342,0343,0344,0345,0346,
  119.     0347,0350,0351,0255,0340,0275,0137,0155,
  120.     0171,0201,0202,0203,0204,0205,0206,0207,
  121.     0210,0211,0221,0222,0223,0224,0225,0226,
  122.     0227,0230,0231,0242,0243,0244,0245,0246,
  123.     0247,0250,0251,0300,0117,0320,0241,0007,
  124.     0040,0041,0042,0043,0044,0025,0006,0027,
  125.     0050,0051,0052,0053,0054,0011,0012,0033,
  126.     0060,0061,0032,0063,0064,0065,0066,0010,
  127.     0070,0071,0072,0073,0004,0024,0076,0341,
  128.     0101,0102,0103,0104,0105,0106,0107,0110,
  129.     0111,0121,0122,0123,0124,0125,0126,0127,
  130.     0130,0131,0142,0143,0144,0145,0146,0147,
  131.     0150,0151,0160,0161,0162,0163,0164,0165,
  132.     0166,0167,0170,0200,0212,0213,0214,0215,
  133.     0216,0217,0220,0232,0233,0234,0235,0236,
  134.     0237,0240,0252,0253,0254,0255,0256,0257,
  135.     0260,0261,0262,0263,0264,0265,0266,0267,
  136.     0270,0271,0272,0273,0274,0275,0276,0277,
  137.     0312,0313,0314,0315,0316,0317,0332,0333,
  138.     0334,0335,0336,0337,0352,0353,0354,0355,
  139.     0356,0357,0372,0373,0374,0375,0376,0377,
  140. };
  141.  
  142.  
  143. main(argc, argv)
  144. int    argc;
  145. char    **argv;
  146. {
  147.     int (*conv)();
  148.     register char *ip;
  149.     register c;
  150.     int ebcdic(), ibm(), ascii(), null(), cnull(), term();
  151.     int a;
  152.  
  153.     conv = null;
  154.     for(c=1; c<argc; c++) {
  155.         string = argv[c];
  156.         if(match("ibs=")) {
  157.             ibs = number(BIG);
  158.             continue;
  159.         }
  160.         if(match("obs=")) {
  161.             obs = number(BIG);
  162.             continue;
  163.         }
  164.         if(match("cbs=")) {
  165.             cbs = number(BIG);
  166.             continue;
  167.         }
  168.         if (match("bs=")) {
  169.             bs = number(BIG);
  170.             continue;
  171.         }
  172.         if(match("if=")) {
  173.             ifile = string;
  174.             continue;
  175.         }
  176.         if(match("of=")) {
  177.             ofile = string;
  178.             continue;
  179.         }
  180.         if(match("skip=")) {
  181.             skip = number(BIG);
  182.             continue;
  183.         }
  184.         if(match("seek=")) {
  185.             seekn = number(BIG);
  186.             continue;
  187.         }
  188.         if(match("count=")) {
  189.             count = number(BIG);
  190.             continue;
  191.         }
  192.         if(match("files=")) {
  193.             files = number(BIG);
  194.             continue;
  195.         }
  196.         if(match("conv=")) {
  197.         cloop:
  198.             if(match(","))
  199.                 goto cloop;
  200.             if(*string == '\0')
  201.                 continue;
  202.             if(match("ebcdic")) {
  203.                 conv = ebcdic;
  204.                 goto cloop;
  205.             }
  206.             if(match("ibm")) {
  207.                 conv = ibm;
  208.                 goto cloop;
  209.             }
  210.             if(match("ascii")) {
  211.                 conv = ascii;
  212.                 goto cloop;
  213.             }
  214.             if(match("lcase")) {
  215.                 cflag |= LCASE;
  216.                 goto cloop;
  217.             }
  218.             if(match("ucase")) {
  219.                 cflag |= UCASE;
  220.                 goto cloop;
  221.             }
  222.             if(match("swab")) {
  223.                 cflag |= SWAB;
  224.                 goto cloop;
  225.             }
  226.             if(match("noerror")) {
  227.                 cflag |= NERR;
  228.                 goto cloop;
  229.             }
  230.             if(match("sync")) {
  231.                 cflag |= SYNC;
  232.                 goto cloop;
  233.             }
  234.         }
  235.         fprintf(stderr,"bad arg: %s\n", string);
  236.         exit(0);
  237.     }
  238.     if(conv == null && cflag&(LCASE|UCASE))
  239.         conv = cnull;
  240.     if (ifile)
  241.         ibf = open(ifile, 0);
  242.     else
  243.         ibf = dup(0);
  244.     if(ibf < 0) {
  245.         fprintf(stderr,"cannot open: %s\n", ifile);
  246.         exit(0);
  247.     }
  248.     if (ofile)
  249.         obf = creat(ofile, 0666);
  250.     else
  251.         obf = dup(1);
  252.     if(obf < 0) {
  253.         fprintf(stderr,"cannot create: %s\n", ofile);
  254.         exit(0);
  255.     }
  256.     if (bs) {
  257.         ibs = obs = bs;
  258.         if (conv == null)
  259.             fflag++;
  260.     }
  261.     if(ibs == 0 || obs == 0) {
  262.         fprintf(stderr,"counts: cannot be zero\n");
  263.         exit(0);
  264.     }
  265.     ibuf = sbrk(ibs);
  266.     if (fflag)
  267.         obuf = ibuf;
  268.     else
  269.         obuf = sbrk(obs);
  270.     sbrk(64);    /* For good measure */
  271.     if(ibuf == (char *)-1 || obuf == (char *)-1) {
  272.         fprintf(stderr, "not enough memory\n");
  273.         exit(0);
  274.     }
  275.     ibc = 0;
  276.     obc = 0;
  277.     cbc = 0;
  278.     op = obuf;
  279.  
  280.     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
  281.         signal(SIGINT, term);
  282.     while(skip) {
  283.         read(ibf, ibuf, ibs);
  284.         skip--;
  285.     }
  286.     while(seekn) {
  287.         lseek(obf, (long)obs, 1);
  288.         seekn--;
  289.     }
  290.  
  291. loop:
  292.     if(ibc-- == 0) {
  293.         ibc = 0;
  294.         if(count==0 || nifr+nipr!=count) {
  295.             if(cflag&(NERR|SYNC))
  296.             for(ip=ibuf+ibs; ip>ibuf;)
  297.                 *--ip = 0;
  298.             ibc = read(ibf, ibuf, ibs);
  299.         }
  300.         if(ibc == -1) {
  301.             perror("read");
  302.             if((cflag&NERR) == 0) {
  303.                 flsh();
  304.                 term();
  305.             }
  306.             ibc = 0;
  307.             for(c=0; c<ibs; c++)
  308.                 if(ibuf[c] != 0)
  309.                     ibc = c;
  310.             stats();
  311.         }
  312.         if(ibc == 0 && --files<=0) {
  313.             flsh();
  314.             term();
  315.         }
  316.         if(ibc != ibs) {
  317.             nipr++;
  318.             if(cflag&SYNC)
  319.                 ibc = ibs;
  320.         } else
  321.             nifr++;
  322.         ip = ibuf;
  323.         c = (ibc>>1) & ~1;
  324.         if(cflag&SWAB && c)
  325.         do {
  326.             a = *ip++;
  327.             ip[-1] = *ip;
  328.             *ip++ = a;
  329.         } while(--c);
  330.         ip = ibuf;
  331.         if (fflag) {
  332.             obc = ibc;
  333.             flsh();
  334.             ibc = 0;
  335.         }
  336.         goto loop;
  337.     }
  338.     c = 0;
  339.     c |= *ip++;
  340.     c &= 0377;
  341.     (*conv)(c);
  342.     goto loop;
  343. }
  344.  
  345. flsh()
  346. {
  347.     register c;
  348.  
  349.     if(obc) {
  350.         if(obc == obs)
  351.             nofr++; else
  352.             nopr++;
  353.         c = write(obf, obuf, obc);
  354.         if(c != obc) {
  355.             perror("write");
  356.             term();
  357.         }
  358.         obc = 0;
  359.     }
  360. }
  361.  
  362. match(s)
  363. char *s;
  364. {
  365.     register char *cs;
  366.  
  367.     cs = string;
  368.     while(*cs++ == *s)
  369.         if(*s++ == '\0')
  370.             goto true;
  371.     if(*s != '\0')
  372.         return(0);
  373.  
  374. true:
  375.     cs--;
  376.     string = cs;
  377.     return(1);
  378. }
  379.  
  380. number(big)
  381. {
  382.     register char *cs;
  383.     long n;
  384.  
  385.     cs = string;
  386.     n = 0;
  387.     while(*cs >= '0' && *cs <= '9')
  388.         n = n*10 + *cs++ - '0';
  389.     for(;;)
  390.     switch(*cs++) {
  391.  
  392.     case 'k':
  393.         n *= 1024;
  394.         continue;
  395.  
  396.     case 'w':
  397.         n *= sizeof(int);
  398.         continue;
  399.  
  400.     case 'b':
  401.         n *= 512;
  402.         continue;
  403.  
  404.     case '*':
  405.     case 'x':
  406.         string = cs;
  407.         n *= number(BIG);
  408.  
  409.     case '\0':
  410.         if (n>=big || n<0) {
  411.             fprintf(stderr, "dd: argument %D out of range\n", n);
  412.             exit(1);
  413.         }
  414.         return(n);
  415.     }
  416.     /* never gets here */
  417. }
  418.  
  419. cnull(cc)
  420. {
  421.     register c;
  422.  
  423.     c = cc;
  424.     if(cflag&UCASE && c>='a' && c<='z')
  425.         c += 'A'-'a';
  426.     if(cflag&LCASE && c>='A' && c<='Z')
  427.         c += 'a'-'A';
  428.     null(c);
  429. }
  430.  
  431. null(c)
  432. {
  433.  
  434.     *op = c;
  435.     op++;
  436.     if(++obc >= obs) {
  437.         flsh();
  438.         op = obuf;
  439.     }
  440. }
  441.  
  442. ascii(cc)
  443. {
  444.     register c;
  445.  
  446.     c = etoa[cc] & 0377;
  447.     if(cbs == 0) {
  448.         cnull(c);
  449.         return;
  450.     }
  451.     if(c == ' ') {
  452.         nspace++;
  453.         goto out;
  454.     }
  455.     while(nspace > 0) {
  456.         null(' ');
  457.         nspace--;
  458.     }
  459.     cnull(c);
  460.  
  461. out:
  462.     if(++cbc >= cbs) {
  463.         null('\n');
  464.         cbc = 0;
  465.         nspace = 0;
  466.     }
  467. }
  468.  
  469. ebcdic(cc)
  470. {
  471.     register c;
  472.  
  473.     c = cc;
  474.     if(cflag&UCASE && c>='a' && c<='z')
  475.         c += 'A'-'a';
  476.     if(cflag&LCASE && c>='A' && c<='Z')
  477.         c += 'a'-'A';
  478.     c = atoe[c] & 0377;
  479.     if(cbs == 0) {
  480.         null(c);
  481.         return;
  482.     }
  483.     if(cc == '\n') {
  484.         while(cbc < cbs) {
  485.             null(atoe[' ']);
  486.             cbc++;
  487.         }
  488.         cbc = 0;
  489.         return;
  490.     }
  491.     if(cbc == cbs)
  492.         ntrunc++;
  493.     cbc++;
  494.     if(cbc <= cbs)
  495.         null(c);
  496. }
  497.  
  498. ibm(cc)
  499. {
  500.     register c;
  501.  
  502.     c = cc;
  503.     if(cflag&UCASE && c>='a' && c<='z')
  504.         c += 'A'-'a';
  505.     if(cflag&LCASE && c>='A' && c<='Z')
  506.         c += 'a'-'A';
  507.     c = atoibm[c] & 0377;
  508.     if(cbs == 0) {
  509.         null(c);
  510.         return;
  511.     }
  512.     if(cc == '\n') {
  513.         while(cbc < cbs) {
  514.             null(atoibm[' ']);
  515.             cbc++;
  516.         }
  517.         cbc = 0;
  518.         return;
  519.     }
  520.     if(cbc == cbs)
  521.         ntrunc++;
  522.     cbc++;
  523.     if(cbc <= cbs)
  524.         null(c);
  525. }
  526.  
  527. term()
  528. {
  529.  
  530.     stats();
  531.     exit(0);
  532. }
  533.  
  534. stats()
  535. {
  536.  
  537.     fprintf(stderr,"%u+%u records in\n", nifr, nipr);
  538.     fprintf(stderr,"%u+%u records out\n", nofr, nopr);
  539.     if(ntrunc)
  540.         fprintf(stderr,"%u truncated records\n", ntrunc);
  541. }
  542.