Annotation of coherent/d/bin/dd.c, revision 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.