Annotation of coherent/d/bin/dd.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * DD - file conversion and copying
                      3:  */
                      4: 
                      5: #include <stdio.h>
                      6: #include <ctype.h>
                      7: #include <signal.h>
                      8: #ifndef        TYPES_H
                      9: #include <sys/types.h>
                     10: #include <sys/mdata.h>
                     11: #endif
                     12: 
                     13: /* Conversions */
                     14: #define        DD_ASC  01              /* EBCDIC->ASCII */
                     15: #define        DD_EBC  02              /* ASCII->EBCDIC */
                     16: #define        DD_IBM  04              /* ASCII-> special print EBCDIC */
                     17: #define        DD_LCA  010             /* alphabetics to lower case */
                     18: #define        DD_UCA  020             /* alphabetics to upper case */
                     19: #define        DD_SWAB 040             /* Swap byte pairs */
                     20: #define        DD_NERR 0100            /* Ignore errors */
                     21: #define        DD_SYNC 0200            /* Pad input records to `ibs' */
                     22: #define        DD_COPY (DD_ASC|DD_EBC|DD_IBM)  /* Requires copy */
                     23: 
                     24: #define        BSIZE   BUFSIZ
                     25: #define        streq(a,b)      strcmp(a,b)==0
                     26: 
                     27: /*
                     28:  * Conversion table from EBCDIC to ASCII.
                     29:  * This is from Nov. 1968, CACM (p 788).
                     30:  * It includes conversions of some controls in
                     31:  * EBCDIC up to characters that are >0200 which
                     32:  * is somewhat non-standard.
                     33:  */
                     34: char   etoatab[256] = {
                     35:        0000 /*NUL*/,   0001 /*SOH*/,   0002 /*STX*/,   0003 /*ETX*/,
                     36:        0234 /*K28*/,   0011 /*HT */,   0206 /*K6 */,   0177 /*DEL*/,
                     37:        0227 /*K23*/,   0215 /*K13*/,   0216 /*K14*/,   0013 /*VT */,
                     38:        0014 /*FF */,   0015 /*CR */,   0016 /*SO */,   0017 /*SI */,
                     39:        0020 /*DLE*/,   0021/*DC1*/,    0022 /*DC2*/,   0023 /*DC3*/,
                     40:        0235 /*K29*/,   0205 /*K5 */,   0010 /*BS */,   0207 /*K7 */,
                     41:        0030 /*CAN*/,   0031 /*EM */,   0222 /*K18*/,   0217 /*K15*/,
                     42:        0034 /*FS */,   0035 /*GS */,   0036 /*RS */,   0037 /*US */,
                     43:        0200 /*K0 */,   0201 /*K1 */,   0202 /*K2 */,   0203 /*K3 */,
                     44:        0204 /*K4 */,   0012 /*LF */,   0027 /*ETB*/,   0033 /*ESC*/,
                     45:        0210 /*K8 */,   0211 /*K9 */,   0212 /*K10*/,   0213 /*K11*/,
                     46:        0214 /*K12*/,   0005 /*ENQ*/,   0006 /*ACK*/,   0007 /*BEL*/,
                     47:        0220 /*K16*/,   0221 /*K17*/,   0026 /*SYN*/,   0223 /*K19*/,
                     48:        0224 /*K20*/,   0225 /*K21*/,   0226 /*K22*/,   0004 /*EOT*/,
                     49:        0230 /*K24*/,   0231 /*K25*/,   0232 /*K26*/,   0233 /*K27*/,
                     50:        0024 /*DC4*/,   0025 /*NAK*/,   0236 /*K30*/,   0032 /*SUB*/,
                     51:        0040 /*   */,   0240 /*N0 */,   0241 /*N1 */,   0242 /*N2 */,
                     52:        0243 /*N3 */,   0244 /*N4 */,   0245 /*N5 */,   0246 /*N6 */,
                     53:        0247 /*N7 */,   0250 /*N8 */,   0133 /* [ */,   0056 /* . */,
                     54:        0074 /* < */,   0050 /* ( */,   0053 /* + */,   0041 /* ! */,
                     55:        0046 /* & */,   0251 /*N9 */,   0252 /*N10*/,   0253 /*N11*/,
                     56:        0254 /*N12*/,   0255 /*N13*/,   0256 /*N14*/,   0257 /*N15*/,
                     57:        0260 /*N16*/,   0261 /*N17*/,   0135 /* ] */,   0044 /* $ */,
                     58:        0052 /* * */,   0051 /* ) */,   0073 /* ; */,   0136 /* ^ */,
                     59:        0055 /* - */,   0057 /* / */,   0262 /*N18*/,   0263 /*N19*/,
                     60:        0264 /*N20*/,   0265 /*N21*/,   0266 /*N22*/,   0267 /*N23*/,
                     61:        0270 /*N24*/,   0271 /*N25*/,   0174 /* | */,   0054 /* , */,
                     62:        0045 /* % */,   0137 /* _ */,   0076 /* > */,   0077 /* ? */,
                     63:        0272 /*N26*/,   0273 /*N27*/,   0274 /*N28*/,   0275 /*N29*/,
                     64:        0276 /*N30*/,   0277 /*N31*/,   0300 /*N32*/,   0301 /*N33*/,
                     65:        0302 /*N34*/,   0140 /* ` */,   0072 /* : */,   0043 /* # */,
                     66:        0100 /* @ */,   0047 /* ' */,   0075 /* = */,   0042 /* " */,
                     67:        0303 /*N35*/,   0141 /* a */,   0142 /* b */,   0143 /* c */,
                     68:        0144 /* d */,   0145 /* e */,   0146 /* f */,   0147 /* g */,
                     69:        0150 /* h */,   0151 /* i */,   0304 /*N36*/,   0305 /*N37*/,
                     70:        0306 /*N38*/,   0307 /*N39*/,   0310 /*N40*/,   0311 /*N41*/,
                     71:        0312 /*N42*/,   0152 /* j */,   0153 /* k */,   0154 /* l */,
                     72:        0155 /* m */,   0156 /* n */,   0157 /* o */,   0160 /* p */,
                     73:        0161 /* q */,   0162 /* r */,   0313 /*N43*/,   0314 /*N44*/,
                     74:        0315 /*N45*/,   0316 /*N46*/,   0317 /*N47*/,   0320 /*N48*/,
                     75:        0321 /*N49*/,   0176 /* ~ */,   0163 /* s */,   0164 /* t */,
                     76:        0165 /* u */,   0166 /* v */,   0167 /* w */,   0170 /* x */,
                     77:        0171 /* y */,   0172 /* z */,   0322 /*N50*/,   0323 /*N51*/,
                     78:        0324 /*N52*/,   0325 /*N53*/,   0326 /*N54*/,   0327 /*N55*/,
                     79:        0330 /*N56*/,   0331 /*N57*/,   0332 /*N58*/,   0333 /*N59*/,
                     80:        0334 /*N60*/,   0335 /*N61*/,   0336 /*N62*/,   0337 /*N63*/,
                     81:        0340 /*G0 */,   0341 /*G1 */,   0342 /*G2 */,   0343 /*G3 */,
                     82:        0344 /*G4 */,   0345 /*G5 */,   0346 /*G6 */,   0347 /*G7 */,
                     83:        0173 /* { */,   0101 /* A */,   0102 /* B */,   0103 /* C */,
                     84:        0104 /* D */,   0105 /* E */,   0106 /* F */,   0107 /* G */,
                     85:        0110 /* H */,   0111 /* I */,   0350 /*G8 */,   0351 /*G9 */,
                     86:        0352 /*G10*/,   0353 /*G11*/,   0354 /*G12*/,   0355 /*G13*/,
                     87:        0175 /* } */,   0112 /* J */,   0113 /* K */,   0114 /* L */,
                     88:        0115 /* M */,   0116 /* N */,   0117 /* O */,   0120 /* P */,
                     89:        0121 /* Q */,   0122 /* R */,   0356 /*G14*/,   0357 /*G15*/,
                     90:        0360 /*G16*/,   0361 /*G17*/,   0362 /*G18*/,   0363 /*G19*/,
                     91:        0134 /* \ */,   0237 /*K31*/,   0123 /* S */,   0124 /* T */,
                     92:        0125 /* U */,   0126 /* V */,   0127 /* W */,   0130 /* X */,
                     93:        0131 /* Y */,   0132 /* Z */,   0364 /*G20*/,   0365 /*G21*/,
                     94:        0366 /*G22*/,   0367 /*G23*/,   0370 /*G24*/,   0371 /*G25*/,
                     95:        0060 /* 0 */,   0061 /* 1 */,   0062 /* 2 */,   0063 /* 3 */,
                     96:        0064 /* 4 */,   0065 /* 5 */,   0066 /* 6 */,   0067 /* 7 */,
                     97:        0070 /* 8 */,   0071 /* 9 */,   0372 /*G26*/,   0373 /*G27*/,
                     98:        0374 /*G28*/,   0375 /*G29*/,   0376 /*G30*/,   0377 /*EO */,
                     99: };
                    100: 
                    101: /*
                    102:  * Conversion table from ASCII to standard
                    103:  * EBCDIC (CACM).
                    104:  */
                    105: char   atoetab[128] = {
                    106:        0x00 /*NUL*/,   0x01 /*SOH*/,   0x02 /*STX*/,   0x03 /*ETX*/,
                    107:        0x37 /*EOT*/,   0x2D /*ENQ*/,   0x2E /*ACK*/,   0x2F /*BEL*/,
                    108:        0x16 /*BS */,   0x05 /*HT */,   0x25 /*LF */,   0x0B /*VT */,
                    109:        0x0C /*FF */,   0x0D /*CR */,   0x0E /*SO */,   0x0F /*SI */,
                    110:        0x10 /*DLE*/,   0x11 /*DC1*/,   0x12 /*DC2*/,   0x13 /*DC3*/,
                    111:        0x3C /*DC4*/,   0x3D /*NAK*/,   0x32 /*SYN*/,   0x26 /*ETB*/,
                    112:        0x18 /*CAN*/,   0x19 /*EM */,   0x3F /*SUB*/,   0x27 /*ESC*/,
                    113:        0x1C /*FS */,   0x1D /*GS */,   0x1E /*RS */,   0x1F /*US */,
                    114:        0x40 /*   */,   0x4F /* ! */,   0x7F /* " */,   0x7B /* # */,
                    115:        0x5B /* $ */,   0x6C /* % */,   0x50 /* & */,   0x7D /* ' */,
                    116:        0x4D /* ( */,   0x5D /* ) */,   0x5C /* * */,   0x4E /* + */,
                    117:        0x6B /* , */,   0x60 /* - */,   0x4B /* . */,   0x61 /* / */,
                    118:        0xF0 /* 0 */,   0xF1 /* 1 */,   0xF2 /* 2 */,   0xF3 /* 3 */,
                    119:        0xF4 /* 4 */,   0xF5 /* 5 */,   0xF6 /* 6 */,   0xF7 /* 7 */,
                    120:        0xF8 /* 8 */,   0xF9 /* 9 */,   0x7A /* : */,   0x5E /* ; */,
                    121:        0x4C /* < */,   0x7E /* = */,   0x6E /* > */,   0x6F /* ? */,
                    122:        0x7C /* @ */,   0xC1 /* A */,   0xC2 /* B */,   0xC3 /* C */,
                    123:        0xC4 /* D */,   0xC5 /* E */,   0xC6 /* F */,   0xC7 /* G */,
                    124:        0xC8 /* H */,   0xC9 /* I */,   0xD1 /* J */,   0xD2 /* K */,
                    125:        0xD3 /* L */,   0xD4 /* M */,   0xD5 /* N */,   0xD6 /* O */,
                    126:        0xD7 /* P */,   0xD8 /* Q */,   0xD9 /* R */,   0xE2 /* S */,
                    127:        0xE3 /* T */,   0xE4 /* U */,   0xE5 /* V */,   0xE6 /* W */,
                    128:        0xE7 /* X */,   0xE8 /* Y */,   0xE9 /* Z */,   0x4A /* [ */,
                    129:        0xE0 /* \ */,   0x5A /* ] */,   0x5F /* ^ */,   0x6D /* _ */,
                    130:        0x79 /* ` */,   0x81 /* a */,   0x82 /* b */,   0x83 /* c */,
                    131:        0x84 /* d */,   0x85 /* e */,   0x86 /* f */,   0x87 /* g */,
                    132:        0x88 /* h */,   0x89 /* i */,   0x91 /* j */,   0x92 /* k */,
                    133:        0x93 /* l */,   0x94 /* m */,   0x95 /* n */,   0x96 /* o */,
                    134:        0x97 /* p */,   0x98 /* q */,   0x99 /* r */,   0xA2 /* s */,
                    135:        0xA3 /* t */,   0xA4 /* u */,   0xA5 /* v */,   0xA6 /* w */,
                    136:        0xA7 /* x */,   0xA8 /* y */,   0xA9 /* z */,   0xC0 /* { */,
                    137:        0x6A /* | */,   0xD0 /* } */,   0xA1 /* ~ */,   0x07 /*DEL*/,
                    138: };
                    139: 
                    140: /*
                    141:  * Conversion table from ASCII to ibm print
                    142:  * codes (a version of EBCDIC that may be more
                    143:  * useful).
                    144:  */
                    145: char   atoietab[128] = {
                    146:        0x00 /*NUL*/,   0x01 /*SOH*/,   0x02 /*STX*/,   0x03 /*ETX*/,
                    147:        0x37 /*EOT*/,   0x2D /*ENQ*/,   0x2E /*ACK*/,   0x2F /*BEL*/,
                    148:        0x16 /*BS */,   0x05 /*HT */,   0x25 /*LF */,   0x0B /*VT */,
                    149:        0x0C /*FF */,   0x0D /*CR */,   0x0E /*SO */,   0x0F /*SI */,
                    150:        0x10 /*DLE*/,   0x11 /*DC1*/,   0x12 /*DC2*/,   0x13 /*DC3*/,
                    151:        0x3C /*DC4*/,   0x3D /*NAK*/,   0x32 /*SYN*/,   0x26 /*ETB*/,
                    152:        0x18 /*CAN*/,   0x19 /*EM */,   0x3F /*SUB*/,   0x27 /*ESC*/,
                    153:        0x1C /*FS */,   0x1D /*GS */,   0x1E /*RS */,   0x1F /*US */,
                    154:        0x40 /*   */,   0x5A /* !**/,   0x7F /* " */,   0x7B /* # */,
                    155:        0x5B /* $ */,   0x6C /* % */,   0x50 /* & */,   0x7D /* ' */,
                    156:        0x4D /* ( */,   0x5D /* ) */,   0x5C /* * */,   0x4E /* + */,
                    157:        0x6B /* , */,   0x60 /* - */,   0x4B /* . */,   0x61 /* / */,
                    158:        0xF0 /* 0 */,   0xF1 /* 1 */,   0xF2 /* 2 */,   0xF3 /* 3 */,
                    159:        0xF4 /* 4 */,   0xF5 /* 5 */,   0xF6 /* 6 */,   0xF7 /* 7 */,
                    160:        0xF8 /* 8 */,   0xF9 /* 9 */,   0x7A /* : */,   0x5E /* ; */,
                    161:        0x4C /* < */,   0x7E /* = */,   0x6E /* > */,   0x6F /* ? */,
                    162:        0x7C /* @ */,   0xC1 /* A */,   0xC2 /* B */,   0xC3 /* C */,
                    163:        0xC4 /* D */,   0xC5 /* E */,   0xC6 /* F */,   0xC7 /* G */,
                    164:        0xC8 /* H */,   0xC9 /* I */,   0xD1 /* J */,   0xD2 /* K */,
                    165:        0xD3 /* L */,   0xD4 /* M */,   0xD5 /* N */,   0xD6 /* O */,
                    166:        0xD7 /* P */,   0xD8 /* Q */,   0xD9 /* R */,   0xE2 /* S */,
                    167:        0xE3 /* T */,   0xE4 /* U */,   0xE5 /* V */,   0xE6 /* W */,
                    168:        0xE7 /* X */,   0xE8 /* Y */,   0xE9 /* Z */,   0xAD /* [**/,
                    169:        0xE0 /* \ */,   0xBD /* ]**/,   0x4A /* ^**/,   0x6D /* _ */,
                    170:        0x7D /* `**/,   0x81 /* a */,   0x82 /* b */,   0x83 /* c */,
                    171:        0x84 /* d */,   0x85 /* e */,   0x86 /* f */,   0x87 /* g */,
                    172:        0x88 /* h */,   0x89 /* i */,   0x91 /* j */,   0x92 /* k */,
                    173:        0x93 /* l */,   0x94 /* m */,   0x95 /* n */,   0x96 /* o */,
                    174:        0x97 /* p */,   0x98 /* q */,   0x99 /* r */,   0xA2 /* s */,
                    175:        0xA3 /* t */,   0xA4 /* u */,   0xA5 /* v */,   0xA6 /* w */,
                    176:        0xA7 /* x */,   0xA8 /* y */,   0xA9 /* z */,   0x8B /* {**/,
                    177:        0x4F /* |**/,   0x9B /* }**/,   0x5F /* ~**/,   0x07 /*DEL*/,
                    178: };
                    179: 
                    180: /*
                    181:  * Variables from options.
                    182:  */
                    183: char   *ifname;
                    184: char   *ofname;
                    185: FILE   *ifp = stdin;
                    186: FILE   *ofp = stdout;
                    187: int    ibs;
                    188: int    obs;
                    189: int    cbs;
                    190: char   *ibp;                   /* Input buffer ptr. */
                    191: char   *obp;                   /* Output buffer ptr. */
                    192: char   *cbp;                   /* Intermediate conversion buffer (ebcdic) */
                    193: long   skip;
                    194: unsigned long  files;
                    195: fsize_t        seek;
                    196: unsigned long  count = MAXULONG; /* Limit on records */
                    197: int    conv;                   /* Flags above */
                    198: 
                    199: long   nfri;                   /* Full records in */
                    200: long   npri;                   /* Partial records in */
                    201: long   nfro;                   /* Full records out */
                    202: long   npro;                   /* Partial records out */
                    203: 
                    204: char   nospace[] = "Out of memory for buffers";
                    205: 
                    206: int    stats();
                    207: long   number();
                    208: FILE   *openfile();
                    209: 
                    210: extern int     errno;
                    211: 
                    212: main(argc, argv)
                    213: char *argv[];
                    214: {
                    215:        register char *op;
                    216:        register char *ov;
                    217:        register int i;
                    218:        register int difbuf = 0;
                    219:        extern char *index();
                    220: 
                    221:        if (signal(SIGINT, SIG_IGN) != SIG_IGN)
                    222:                signal(SIGINT, stats);
                    223:        for (i=1; i<argc; i++) {
                    224:                if ((ov = index(op=argv[i], '=')) == NULL)
                    225:                        dderr("Missing `=' in option `%s'", op);
                    226:                *ov++ = '\0';
                    227:                if (*ov == '\0')
                    228:                        dderr("Missing value in option `%s'", op);
                    229:                if (streq(op, "if"))
                    230:                        ifp = openfile(ov, &ifname, 0);
                    231:                else if (streq(op, "of"))
                    232:                        ofp = openfile(ov, &ofname, 1);
                    233:                else if (streq(op, "ibs")) {
                    234:                        ibs = number(ov);
                    235:                        difbuf++;
                    236:                } else if (streq(op, "obs")) {
                    237:                        obs = number(ov);
                    238:                        difbuf++;
                    239:                } else if (streq(op, "bs"))
                    240:                        obs = ibs = number(ov);
                    241:                else if (streq(op, "cbs")) {
                    242:                        cbs = number(ov);
                    243:                        difbuf++;
                    244:                } else if (streq(op, "skip"))
                    245:                        skip = number(ov);
                    246:                else if (streq(op, "files"))
                    247:                        files = number(ov);
                    248:                else if (streq(op, "seek"))
                    249:                        seek = number(ov);
                    250:                else if (streq(op, "count"))
                    251:                        count = number(ov);
                    252:                else if (streq(op, "conv"))
                    253:                        conversions(ov);
                    254:                else
                    255:                        dderr("`%s' is a bad option", op);
                    256:        }
                    257:        if (ifname == NULL)
                    258:                ifname = "(stdin)";
                    259:        if (ofname == NULL)
                    260:                ofname = "(stdout)";
                    261:        if (conv & (DD_EBC|DD_IBM|DD_ASC)) {
                    262:                difbuf++;
                    263:                if ((conv&(DD_ASC|DD_EBC))==(DD_ASC|DD_EBC)
                    264:                 || (conv&(DD_ASC|DD_IBM))==(DD_ASC|DD_IBM)
                    265:                 || (conv&(DD_UCA|DD_LCA))==(DD_UCA|DD_LCA))
                    266:                        dderr("Conflicting case or character set conversions");
                    267:        }
                    268:        if (ibs == 0)
                    269:                ibs = BSIZE;
                    270:        if (obs == 0)
                    271:                obs = BSIZE;
                    272:        if ((ibp = malloc(ibs)) == NULL)
                    273:                dderr(nospace);
                    274:        if (difbuf) {
                    275:                if ((obp = malloc(obs)) == NULL)
                    276:                        dderr(nospace);
                    277:        } else
                    278:                obp = ibp;
                    279:        if (conv & (DD_EBC|DD_IBM|DD_ASC)) {
                    280:                if (cbs == 0)
                    281:                        cbs = ibs;
                    282:                if ((cbp = malloc(cbs+1)) == NULL)
                    283:                        dderr(nospace);
                    284:        }
                    285:        seek *= obs;
                    286:        stats(dd());
                    287: }
                    288: 
                    289: /*
                    290:  * Do the actual data copying and
                    291:  * conversion operations.
                    292:  * Count down all the files.
                    293:  */
                    294: dd()
                    295: {
                    296:        register int nf;
                    297:        register int rstat = 0;
                    298:        register int ddstat;
                    299:        register int n;
                    300: 
                    301:        if (seek != 0)
                    302:                lseek(fileno(ofp), seek, 0);
                    303:        while (skip != 0) {
                    304:                skip--;
                    305:                if ((n = read(fileno(ifp), ibp, ibs))==0 || n==-1)
                    306:                        break;
                    307:        }
                    308:        if ((nf = files) == 0)
                    309:                nf = 1;
                    310:        do {
                    311:                ddstat = cbp==NULL ? dd1() : dd2();
                    312:                rstat |= ddstat;
                    313:                if (ddstat)
                    314:                        return (rstat);
                    315:        } while (--nf);
                    316:        return (rstat);
                    317: }
                    318: 
                    319: /*
                    320:  * Easy version of dd.
                    321:  * No ebcdic, ascii, or ibm conversions.
                    322:  */
                    323: dd1()
                    324: {
                    325:        register int n;
                    326: 
                    327:        while (count-- != 0) {
                    328:                if ((n = ddread(fileno(ifp), ibp, ibs)) == 0)
                    329:                        break;
                    330:                if (n == -1) {
                    331:                        if (conv && DD_NERR)
                    332:                                continue;
                    333:                        else
                    334:                                return (1);
                    335:                }
                    336:                ddconv(ibp, n);
                    337:                if (ddput(ibp, n))
                    338:                        return (1);
                    339:        }
                    340:        return (ddput(NULL, 0));
                    341: }
                    342: 
                    343: /*
                    344:  * More complicated version of dd that uses
                    345:  * the conversion intermediate buffering
                    346:  * for ebcdic/ibm or ascii conversions.
                    347:  */
                    348: dd2()
                    349: {
                    350:        static char *ecbp;
                    351:        register char *bp;
                    352:        register char *wcbp;
                    353:        register int nb;
                    354:        register int n;
                    355:        register int s = 0;
                    356: 
                    357:        ecbp = cbp+cbs;
                    358:        wcbp = cbp;
                    359:        while (count-- != 0) {
                    360:                if ((nb = ddread(fileno(ifp), ibp, ibs)) == 0)
                    361:                        break;
                    362:                if (nb == -1) {
                    363:                        if ((conv & DD_NERR) == 0)
                    364:                                return (1);
                    365:                        else {
                    366:                                s = 1;
                    367:                                continue;
                    368:                        }
                    369:                }
                    370:                bp = ibp;
                    371:                if (conv & (DD_IBM|DD_EBC)) {
                    372:                        do {
                    373:                                if ((n = *wcbp++ = *bp++)=='\n' || wcbp>=ecbp) {
                    374:                                        if (n == '\n')
                    375:                                                wcbp--;
                    376:                                        n = ddconv(cbp, wcbp-cbp);
                    377:                                        if (ddput(cbp, n))
                    378:                                                if ((conv & DD_NERR) == 0)
                    379:                                                        return (1);
                    380:                                                else
                    381:                                                        s = 1;
                    382:                                        wcbp = cbp;
                    383:                                }
                    384:                        } while(--nb);
                    385:                } else {
                    386:                        do {
                    387:                                *wcbp++ = *bp++;
                    388:                                if (wcbp >= ecbp) {
                    389:                                        n = ddconv(cbp, cbs);
                    390:                                        if (ddput(cbp, n))
                    391:                                                if ((conv & DD_NERR) == 0)
                    392:                                                        return (1);
                    393:                                                else
                    394:                                                        s = 1;
                    395:                                        wcbp = cbp;
                    396:                                }
                    397:                        } while (--nb);
                    398:                }
                    399:        }
                    400:        if ((n = wcbp-cbp) != 0) {
                    401:                n = ddconv(cbp, n);
                    402:                if (ddput(cbp, n))
                    403:                        if ((conv & DD_NERR) == 0)
                    404:                                return (1);
                    405:                        else
                    406:                                s = 1;
                    407:        }
                    408:        s |= ddput(NULL, 0);
                    409:        return (s);
                    410: }
                    411: 
                    412: /*
                    413:  * Do output conversions (e.g. swab)
                    414:  * and write the record.  Account
                    415:  * for partial records.
                    416:  * Return non-zero if non-repeatable error.
                    417:  */
                    418: ddwrite(bp, nb)
                    419: register char *bp;
                    420: register unsigned nb;
                    421: {
                    422:        register unsigned wnb;
                    423: 
                    424:        if (nb == 0)
                    425:                return (0);
                    426:        if (conv & DD_SWAB)
                    427:                swab(bp, bp, nb);
                    428:        if ((wnb = write(fileno(ofp), bp, nb)) == nb) {
                    429:                if (nb == obs)
                    430:                        nfro++; else
                    431:                        npro++;
                    432:        } else
                    433:                perror("dd");
                    434:        if (wnb!=nb && (conv&DD_NERR)==0)
                    435:                return (1);
                    436:        return (0);
                    437: }
                    438: 
                    439: /*
                    440:  * Put `n' bytes into the output buffer.
                    441:  * This is maintained internally, and
                    442:  * flushed when full.   Also, if called
                    443:  * with 0 bytes (at end) flush as well.
                    444:  */
                    445: ddput(bp, nb)
                    446: register char *bp;
                    447: register unsigned nb;
                    448: {
                    449:        static char *eobp;
                    450:        static char *cobp;
                    451:        register char *wobp;
                    452:        register int s = 0;
                    453: 
                    454:        if (eobp == NULL) {
                    455:                /*
                    456:                 * Initialisation.
                    457:                 */
                    458:                if (ibp == obp)
                    459:                        return (ddwrite(bp, nb));
                    460:                eobp = obp + obs;
                    461:                cobp = obp;
                    462:        }
                    463:        wobp = cobp;
                    464:        if (nb == 0) {
                    465:                /*
                    466:                 * Flush at end.
                    467:                 */
                    468:                if ((nb = wobp-obp) == 0)
                    469:                        return (0);
                    470:                if (ddwrite(obp, nb) != nb)
                    471:                        if ((conv & DD_NERR) == 0)
                    472:                                return (1);
                    473:                return (0);
                    474:        }
                    475:        do {
                    476:                *wobp++ = *bp++;
                    477:                if (wobp >= eobp) {
                    478:                        if (ddwrite(obp, obs))
                    479:                                if ((conv & DD_NERR) == 0)
                    480:                                        return (1);
                    481:                                else
                    482:                                        s = 1;
                    483:                        wobp = obp;
                    484:                }
                    485:        } while (--nb);
                    486:        cobp = wobp;
                    487:        return (s);
                    488: }
                    489: 
                    490: /*
                    491:  * Read in data.  increment proper counts,
                    492:  * do conv=sync and noerrors checking.
                    493:  */
                    494: ddread(fd, bp, nb)
                    495: int fd;
                    496: register char *bp;
                    497: register int nb;
                    498: {
                    499:        register int n;
                    500: 
                    501:        if ((n = read(fd, bp, nb)) == -1)
                    502:                perror("dd");
                    503:        else if (n != 0) {
                    504:                if (n == nb)
                    505:                        nfri++; else
                    506:                        npri++;
                    507:                if (conv&DD_SYNC && n<nb) {
                    508:                        bp += n;
                    509:                        n = nb-n;
                    510:                        while (n--)
                    511:                                *bp++ = 0;
                    512:                        n = nb;
                    513:                }
                    514:        }
                    515:        return (n);
                    516: }
                    517: 
                    518: /*
                    519:  * Do other conversions.
                    520:  * Return new `nb' (useful only for ascii/ebcdic
                    521:  * conversions).
                    522:  */
                    523: ddconv(bp, nb)
                    524: char *bp;
                    525: unsigned nb;
                    526: {
                    527:        register char *cp;
                    528:        register unsigned n;
                    529:        register int c;
                    530: 
                    531:        if (conv & DD_ASC) {
                    532:                etoa(bp, bp, n=nb);
                    533:                for (cp=bp+n; cp>bp; )
                    534:                        if (*--cp != ' ') {
                    535:                                cp++;
                    536:                                break;
                    537:                        }
                    538:                *cp++ = '\n';
                    539:                nb = cp-bp;
                    540:        }
                    541:        if (conv & DD_UCA) {
                    542:                for (cp=bp, n=nb; n-- != 0; cp++)
                    543:                        if (isascii(c=*cp) && islower(c))
                    544:                                *cp = toupper(c);
                    545:        }
                    546:        if (conv & DD_LCA) {
                    547:                for (cp=bp, n=nb; n-- != 0; cp++)
                    548:                        if (isascii(c=*cp) && isupper(c))
                    549:                                *cp = tolower(c);
                    550:        }
                    551:        if (conv & (DD_EBC|DD_IBM)) {
                    552:                if (nb < cbs) {
                    553:                        n = cbs-nb;
                    554:                        cp = bp+nb;
                    555:                        while (n--)
                    556:                                *cp++ = ' ';
                    557:                }
                    558:                nb = n = cbs;
                    559:                if (conv & DD_IBM)
                    560:                        atoie(bp, bp, n); else
                    561:                        atoe(bp, bp, n);
                    562:        }
                    563:        return (nb);
                    564: }
                    565: 
                    566: /*
                    567:  * Open a file on the input line.
                    568:  * `f' is 0 for read, 1 for write.
                    569:  */
                    570: FILE *
                    571: openfile(fn, fnp, f)
                    572: register char *fn;
                    573: register char **fnp;
                    574: int f;
                    575: {
                    576:        register FILE *fp;
                    577:        register int errsave;
                    578: 
                    579:        if (*fnp != NULL)
                    580:                dderr("more than one `%s' specified", f ? "of=" : "if=");
                    581:        *fnp = fn;
                    582:        if ((fp = fopen(fn, f?"w":"r")) == NULL) {
                    583:                errsave = errno;
                    584:                fprintf(stderr, "dd: ");
                    585:                errno = errsave;
                    586:                perror(fn);
                    587:                exit(1);
                    588:        }
                    589:        return (fp);
                    590: }
                    591: 
                    592: /*
                    593:  * Read a number, scaled by the
                    594:  * multipliers `k', `b', or `w'.
                    595:  */
                    596: long
                    597: number(num)
                    598: char *num;
                    599: {
                    600:        register char *s = num;
                    601:        long rn, n;
                    602:        register int base;
                    603: 
                    604:        rn = 1;
                    605: again:
                    606:        n = 0;
                    607:        base = 10;
                    608:        if (*s == '0') {
                    609:                base = 8;
                    610:                s++;
                    611:        }
                    612:        while (isdigit(*s))
                    613:                n = n*base + *s++ - '0';
                    614:        for (; *s!='\0'; s++)
                    615:                if (*s=='b')
                    616:                        n *= BSIZE;
                    617:                else if (*s == 'w')
                    618:                        n *= sizeof(int);
                    619:                else if (*s == 'k')
                    620:                        n *= 1024;
                    621:                else if (*s == 'x') {
                    622:                        s++;
                    623:                        rn *= n;
                    624:                        goto again;
                    625:                } else
                    626:                        dderr("bad number `%s'", num);
                    627:        if (rn != 1)
                    628:                return (n*rn);
                    629:        return (n);
                    630: }
                    631: 
                    632: /*
                    633:  * Read in the conversions from
                    634:  * the string given.
                    635:  */
                    636: conversions(s)
                    637: register char *s;
                    638: {
                    639:        register char *np = s;
                    640: 
                    641:        for (;;) {
                    642:                for (;; np++) {
                    643:                        if (*np == ',')
                    644:                                *np++ = '\0';
                    645:                        else if (*np == '\0')
                    646:                                np = NULL;
                    647:                        else
                    648:                                continue;
                    649:                        break;
                    650:                }
                    651:                if (streq(s, "ascii"))
                    652:                        conv |= DD_ASC;
                    653:                else if (streq(s, "ebcdic"))
                    654:                        conv |= DD_EBC;
                    655:                else if (streq(s, "ibm"))
                    656:                        conv |= DD_IBM;
                    657:                else if (streq(s, "lcase"))
                    658:                        conv |= DD_LCA;
                    659:                else if (streq(s, "ucase"))
                    660:                        conv |= DD_UCA;
                    661:                else if (streq(s, "swab"))
                    662:                        conv |= DD_SWAB;
                    663:                else if (streq(s, "noerror"))
                    664:                        conv |= DD_NERR;
                    665:                else if (streq(s, "sync"))
                    666:                        conv |= DD_SYNC;
                    667:                else
                    668:                        dderr("`%s' is an illegal conversion", s);
                    669:                if (np == NULL)
                    670:                        break;
                    671:                s = np;
                    672:        }
                    673: }
                    674: 
                    675: /*
                    676:  * Convert ascii to ebcdic.
                    677:  * This is the CACM standard one.
                    678:  */
                    679: atoe(ip, op, n)
                    680: register unsigned char *ip;
                    681: register unsigned char *op;
                    682: register unsigned n;
                    683: {
                    684:        if (n)
                    685:                do {
                    686:                        if (isascii(*ip))
                    687:                                *op++ = atoetab[*ip++];
                    688:                        else {
                    689:                                *op++ = 0;
                    690:                                ip++;
                    691:                        }
                    692:                } while (--n);
                    693: }
                    694: 
                    695: /*
                    696:  * Convert ascii to `ibm' ebcdic.
                    697:  * This is the more reasonable one
                    698:  * for printers.
                    699:  */
                    700: atoie(ip, op, n)
                    701: register unsigned char *ip;
                    702: register unsigned char *op;
                    703: register unsigned n;
                    704: {
                    705:        if (n)
                    706:                do {
                    707:                        if (isascii(*ip))
                    708:                                *op++ = atoietab[*ip++];
                    709:                        else {
                    710:                                *op++ = 0;
                    711:                                ip++;
                    712:                        }
                    713:                } while (--n);
                    714: }
                    715: 
                    716: /*
                    717:  * Convert EBCDIC to ASCII.
                    718:  * As it turns out, the mappings
                    719:  * are both the same.
                    720:  */
                    721: etoa(ip, op, n)
                    722: register unsigned char *ip;
                    723: register unsigned char *op;
                    724: register unsigned n;
                    725: {
                    726:        if (n)
                    727:                do {
                    728:                        *op++ = etoatab[*ip++];
                    729:                } while (--n);
                    730: }
                    731: 
                    732: /*
                    733:  * Print statistics and exit.
                    734:  */
                    735: stats(s)
                    736: {
                    737:        fprintf(stderr, "%ld+%ld records in\n", nfri, npri);
                    738:        fprintf(stderr, "%ld+%ld records out\n", nfro, npro);
                    739:        exit(s);
                    740: }
                    741: 
                    742: usage()
                    743: {
                    744:        fprintf(stderr, "Usage: dd [option=value] ...\n");
                    745:        exit(1);
                    746: }
                    747: 
                    748: /* VARARGS */
                    749: dderr(x)
                    750: {
                    751:        fprintf(stderr, "dd: %r\n", &x);
                    752:        exit(1);
                    753: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.