|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.