|
|
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.