1 /* dd -- convert a file while copying it.
2 Copyright (C) 1985, 1990, 1991, 1995 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18 /* Written by Paul Rubin, David MacKenzie, and Stuart Kemp. */
22 Numbers can be followed by a multiplier:
23 b=512, c=1, k=1024, w=2, xm=number m
25 if=FILE Read from FILE instead of stdin.
26 of=FILE Write to FILE instead of stdout; don't
28 ibs=BYTES Read BYTES bytes at a time.
29 obs=BYTES Write BYTES bytes at a time.
30 bs=BYTES Override ibs and obs.
31 cbs=BYTES Convert BYTES bytes at a time.
32 skip=BLOCKS Skip BLOCKS ibs-sized blocks at
34 seek=BLOCKS Skip BLOCKS obs-sized blocks at
36 count=BLOCKS Copy only BLOCKS input blocks.
37 conv=CONVERSION[,CONVERSION...]
40 ascii Convert EBCDIC to ASCII.
41 ebcdic Convert ASCII to EBCDIC.
42 ibm Convert ASCII to alternate EBCDIC.
43 block Pad newline-terminated records to size of
44 cbs, replacing newline with trailing spaces.
45 unblock Replace trailing spaces in cbs-sized block
47 lcase Change upper case characters to lower case.
48 ucase Change lower case characters to upper case.
49 swab Swap every pair of input bytes.
50 Unlike the Unix dd, this works when an odd
51 number of bytes are read.
52 noerror Continue after read errors.
53 sync Pad every input block to size of ibs with
59 #define SWAB_ALIGN_OFFSET 2
61 #include <sys/types.h>
69 #define equal(p, q) (strcmp ((p),(q)) == 0)
70 #define max(a, b) ((a) > (b) ? (a) : (b))
71 #define output_char(c) \
73 obuf[oc++] = (c); if (oc >= output_blocksize) write_output (); \
76 /* Default input and output blocksize. */
77 #define DEFAULT_BLOCKSIZE 512
79 /* Conversions bit masks. */
88 #define C_NOERROR 0400
89 #define C_NOTRUNC 01000
91 /* Use separate input and output buffers, and combine partial input blocks. */
92 #define C_TWOBUFS 04000
98 static RETSIGTYPE
interrupt_handler ();
99 static int bit_count ();
100 static int parse_integer ();
101 static void apply_translations ();
103 static void copy_simple ();
104 static void copy_with_block ();
105 static void copy_with_unblock ();
106 static void parse_conversion ();
107 static void print_stats ();
108 static void translate_charset ();
110 static void scanargs ();
112 static void usage ();
113 static void write_output ();
115 /* The name this program was run with. */
118 /* The name of the input file, or NULL for the standard input. */
119 static char *input_file
= NULL
;
121 /* The input file descriptor. */
122 static int input_fd
= 0;
124 /* The name of the output file, or NULL for the standard output. */
125 static char *output_file
= NULL
;
127 /* The output file descriptor. */
128 static int output_fd
= 1;
130 /* The number of bytes in which atomic reads are done. */
131 static long input_blocksize
= -1;
133 /* The number of bytes in which atomic writes are done. */
134 static long output_blocksize
= -1;
136 /* Conversion buffer size, in bytes. 0 prevents conversions. */
137 static long conversion_blocksize
= 0;
139 /* Skip this many records of `input_blocksize' bytes before input. */
140 static long skip_records
= 0;
142 /* Skip this many records of `output_blocksize' bytes before output. */
143 static long seek_record
= 0;
145 /* Copy only this many records. <0 means no limit. */
146 static int max_records
= -1;
148 /* Bit vector of conversions to apply. */
149 static int conversions_mask
= 0;
151 /* If nonzero, filter characters through the translation table. */
152 static int translation_needed
= 0;
154 /* Number of partial blocks written. */
155 static unsigned w_partial
= 0;
157 /* Number of full blocks written. */
158 static unsigned w_full
= 0;
160 /* Number of partial blocks read. */
161 static unsigned r_partial
= 0;
163 /* Number of full blocks read. */
164 static unsigned r_full
= 0;
166 /* Records truncated by conv=block. */
167 static unsigned r_truncate
= 0;
169 /* Output representation of newline and space characters.
170 They change if we're converting to EBCDIC. */
171 static unsigned char newline_character
= '\n';
172 static unsigned char space_character
= ' ';
180 static struct conversion conversions
[] =
182 {"ascii", C_ASCII
| C_TWOBUFS
}, /* EBCDIC to ASCII. */
183 {"ebcdic", C_EBCDIC
| C_TWOBUFS
}, /* ASCII to EBCDIC. */
184 {"ibm", C_IBM
| C_TWOBUFS
}, /* Slightly different ASCII to EBCDIC. */
185 {"block", C_BLOCK
| C_TWOBUFS
}, /* Variable to fixed length records. */
186 {"unblock", C_UNBLOCK
| C_TWOBUFS
}, /* Fixed to variable length records. */
187 {"lcase", C_LCASE
| C_TWOBUFS
}, /* Translate upper to lower case. */
188 {"ucase", C_UCASE
| C_TWOBUFS
}, /* Translate lower to upper case. */
189 {"swab", C_SWAB
| C_TWOBUFS
}, /* Swap bytes of input. */
190 {"noerror", C_NOERROR
}, /* Ignore i/o errors. */
191 {"notrunc", C_NOTRUNC
}, /* Do not truncate output file. */
192 {"sync", C_SYNC
}, /* Pad input records to ibs with NULs. */
196 /* Translation table formed by applying successive transformations. */
197 static unsigned char trans_table
[256];
199 static unsigned char const ascii_to_ebcdic
[] =
201 0, 01, 02, 03, 067, 055, 056, 057,
202 026, 05, 045, 013, 014, 015, 016, 017,
203 020, 021, 022, 023, 074, 075, 062, 046,
204 030, 031, 077, 047, 034, 035, 036, 037,
205 0100, 0117, 0177, 0173, 0133, 0154, 0120, 0175,
206 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
207 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
208 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
209 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
210 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
211 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
212 0347, 0350, 0351, 0112, 0340, 0132, 0137, 0155,
213 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
214 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
215 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
216 0247, 0250, 0251, 0300, 0152, 0320, 0241, 07,
217 040, 041, 042, 043, 044, 025, 06, 027,
218 050, 051, 052, 053, 054, 011, 012, 033,
219 060, 061, 032, 063, 064, 065, 066, 010,
220 070, 071, 072, 073, 04, 024, 076, 0341,
221 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
222 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
223 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
224 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
225 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
226 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
227 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
228 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
229 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
230 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
231 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
232 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377
235 static unsigned char const ascii_to_ibm
[] =
237 0, 01, 02, 03, 067, 055, 056, 057,
238 026, 05, 045, 013, 014, 015, 016, 017,
239 020, 021, 022, 023, 074, 075, 062, 046,
240 030, 031, 077, 047, 034, 035, 036, 037,
241 0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175,
242 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
243 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
244 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
245 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
246 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
247 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
248 0347, 0350, 0351, 0255, 0340, 0275, 0137, 0155,
249 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
250 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
251 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
252 0247, 0250, 0251, 0300, 0117, 0320, 0241, 07,
253 040, 041, 042, 043, 044, 025, 06, 027,
254 050, 051, 052, 053, 054, 011, 012, 033,
255 060, 061, 032, 063, 064, 065, 066, 010,
256 070, 071, 072, 073, 04, 024, 076, 0341,
257 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
258 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
259 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
260 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
261 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
262 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
263 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
264 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
265 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
266 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
267 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
268 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377
271 static unsigned char const ebcdic_to_ascii
[] =
273 0, 01, 02, 03, 0234, 011, 0206, 0177,
274 0227, 0215, 0216, 013, 014, 015, 016, 017,
275 020, 021, 022, 023, 0235, 0205, 010, 0207,
276 030, 031, 0222, 0217, 034, 035, 036, 037,
277 0200, 0201, 0202, 0203, 0204, 012, 027, 033,
278 0210, 0211, 0212, 0213, 0214, 05, 06, 07,
279 0220, 0221, 026, 0223, 0224, 0225, 0226, 04,
280 0230, 0231, 0232, 0233, 024, 025, 0236, 032,
281 040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
282 0247, 0250, 0133, 056, 074, 050, 053, 041,
283 046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
284 0260, 0261, 0135, 044, 052, 051, 073, 0136,
285 055, 057, 0262, 0263, 0264, 0265, 0266, 0267,
286 0270, 0271, 0174, 054, 045, 0137, 076, 077,
287 0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
288 0302, 0140, 072, 043, 0100, 047, 075, 042,
289 0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
290 0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
291 0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
292 0161, 0162, 0313, 0314, 0315, 0316, 0317, 0320,
293 0321, 0176, 0163, 0164, 0165, 0166, 0167, 0170,
294 0171, 0172, 0322, 0323, 0324, 0325, 0326, 0327,
295 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
296 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
297 0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
298 0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
299 0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
300 0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
301 0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
302 0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
303 060, 061, 062, 063, 064, 065, 066, 067,
304 070, 071, 0372, 0373, 0374, 0375, 0376, 0377
307 /* If non-zero, display usage information and exit. */
308 static int show_help
;
310 /* If non-zero, print the version on standard output and exit. */
311 static int show_version
;
313 static struct option
const long_options
[] =
315 {"help", no_argument
, &show_help
, 1},
316 {"version", no_argument
, &show_version
, 1},
325 #ifdef _POSIX_VERSION
326 struct sigaction sigact
;
327 #endif /* _POSIX_VERSION */
330 program_name
= argv
[0];
332 /* Initialize translation table to identity translation. */
333 for (i
= 0; i
< 256; i
++)
336 /* Decode arguments. */
337 scanargs (argc
, argv
);
341 printf ("dd - %s\n", version_string
);
348 apply_translations ();
350 if (input_file
!= NULL
)
352 input_fd
= open (input_file
, O_RDONLY
);
354 error (1, errno
, "%s", input_file
);
357 input_file
= "standard input";
359 if (input_fd
== output_fd
)
360 error (1, 0, "standard %s is closed", input_fd
== 0 ? "input" : "output");
362 if (output_file
!= NULL
)
364 int omode
= O_RDWR
| O_CREAT
;
366 if (seek_record
== 0 && !(conversions_mask
& C_NOTRUNC
))
368 output_fd
= open (output_file
, omode
, 0666);
370 error (1, errno
, "%s", output_file
);
371 #ifdef HAVE_FTRUNCATE
372 if (seek_record
> 0 && !(conversions_mask
& C_NOTRUNC
))
374 if (ftruncate (output_fd
, seek_record
* output_blocksize
) < 0)
375 error (0, errno
, "%s", output_file
);
380 output_file
= "standard output";
382 #ifdef _POSIX_VERSION
383 sigaction (SIGINT
, NULL
, &sigact
);
384 if (sigact
.sa_handler
!= SIG_IGN
)
386 sigact
.sa_handler
= interrupt_handler
;
387 sigemptyset (&sigact
.sa_mask
);
389 sigaction (SIGINT
, &sigact
, NULL
);
391 sigaction (SIGPIPE
, NULL
, &sigact
);
392 if (sigact
.sa_handler
!= SIG_IGN
)
394 sigact
.sa_handler
= interrupt_handler
;
395 sigemptyset (&sigact
.sa_mask
);
397 sigaction (SIGPIPE
, &sigact
, NULL
);
399 #else /* !_POSIX_VERSION */
400 if (signal (SIGINT
, SIG_IGN
) != SIG_IGN
)
401 signal (SIGINT
, interrupt_handler
);
402 if (signal (SIGPIPE
, SIG_IGN
) != SIG_IGN
)
403 signal (SIGPIPE
, interrupt_handler
);
404 #endif /* !_POSIX_VERSION */
408 /* Throw away RECORDS blocks of BLOCKSIZE bytes on file descriptor FDESC,
409 which is open with read permission for FILE. Store up to BLOCKSIZE
410 bytes of the data at a time in BUF, if necessary. */
413 skip (fdesc
, file
, records
, blocksize
, buf
)
422 /* Use fstat instead of checking for errno == ESPIPE because
423 lseek doesn't work on some special files but doesn't return an
425 /* FIXME: can this really happen? What system? */
426 if (fstat (fdesc
, &stats
))
428 error (0, errno
, "%s", file
);
432 /* FIXME: why use lseek only on regular files?
433 Better: try lseek and if an error indicates it was an inappropriate
434 operation, fall back on using read. */
435 if (S_ISREG (stats
.st_mode
))
437 if (lseek (fdesc
, records
* blocksize
, SEEK_SET
) < 0)
439 error (0, errno
, "%s", file
);
445 while (records
-- > 0)
449 nread
= safe_read (fdesc
, buf
, blocksize
);
452 error (0, errno
, "%s", file
);
455 /* POSIX doesn't say what to do when dd detects it has been
456 asked to skip past EOF, so I assume it's non-fatal.
457 FIXME: maybe give a warning. */
464 /* Apply the character-set translations specified by the user
465 to the NREAD bytes in BUF. */
468 translate_buffer (buf
, nread
)
472 register unsigned char *cp
;
475 for (i
= nread
, cp
= buf
; i
; i
--, cp
++)
476 *cp
= trans_table
[*cp
];
479 /* If nonnzero, the last char from the previous call to `swab_buffer'
480 is saved in `saved_char'. */
481 static int char_is_saved
= 0;
483 /* Odd char from previous call. */
484 static unsigned char saved_char
;
486 /* Swap NREAD bytes in BUF, plus possibly an initial char from the
487 previous call. If NREAD is odd, save the last char for the
488 next call. Return the new start of the BUF buffer. */
490 static unsigned char *
491 swab_buffer (buf
, nread
)
495 unsigned char *bufstart
= buf
;
496 register unsigned char *cp
;
499 /* Is a char left from last time? */
502 *--bufstart
= saved_char
;
509 /* An odd number of chars are in the buffer. */
510 saved_char
= bufstart
[--*nread
];
514 /* Do the byte-swapping by moving every second character two
515 positions toward the end, working from the end of the buffer
516 toward the beginning. This way we only move half of the data. */
518 cp
= bufstart
+ *nread
; /* Start one char past the last. */
519 for (i
= *nread
/ 2; i
; i
--, cp
-= 2)
526 static unsigned char *obuf
;
528 /* Current index into `obuf'. */
531 /* Index into current line, for `conv=block' and `conv=unblock'. */
539 unsigned char *ibuf
, *bufstart
; /* Input buffer. */
540 int nread
; /* Bytes read in the current block. */
543 /* Leave at least one extra byte at the beginning and end of `ibuf'
544 for conv=swab, but keep the buffer address even. But some peculiar
545 device drivers work only with word-aligned buffers, so leave an
548 ibuf
= (unsigned char *) xmalloc (input_blocksize
+ 2 * SWAB_ALIGN_OFFSET
);
549 ibuf
+= SWAB_ALIGN_OFFSET
;
551 if (conversions_mask
& C_TWOBUFS
)
552 obuf
= (unsigned char *) xmalloc (output_blocksize
);
556 if (skip_records
> 0)
557 skip (input_fd
, input_file
, skip_records
, input_blocksize
, ibuf
);
560 skip (output_fd
, output_file
, seek_record
, output_blocksize
, obuf
);
562 if (max_records
== 0)
567 if (max_records
>= 0 && r_partial
+ r_full
>= max_records
)
570 /* Zero the buffer before reading, so that if we get a read error,
571 whatever data we are able to read is followed by zeros.
572 This minimizes data loss. */
573 if ((conversions_mask
& C_SYNC
) && (conversions_mask
& C_NOERROR
))
574 memset (ibuf
, 0, input_blocksize
);
576 nread
= safe_read (input_fd
, ibuf
, input_blocksize
);
583 error (0, errno
, "%s", input_file
);
584 if (conversions_mask
& C_NOERROR
)
587 /* Seek past the bad block if possible. */
588 lseek (input_fd
, input_blocksize
, SEEK_CUR
);
589 if (conversions_mask
& C_SYNC
)
590 /* Replace the missing input with null bytes and
598 /* Write any partial block. */
604 if (nread
< input_blocksize
)
607 if (conversions_mask
& C_SYNC
)
609 if (!(conversions_mask
& C_NOERROR
))
610 /* If C_NOERROR, we zeroed the block before reading. */
611 memset (ibuf
+ nread
, 0, input_blocksize
- nread
);
612 nread
= input_blocksize
;
618 if (ibuf
== obuf
) /* If not C_TWOBUFS. */
620 int nwritten
= full_write (output_fd
, obuf
, nread
);
621 if (nwritten
!= nread
)
623 error (0, errno
, "%s", output_file
);
628 else if (nread
== input_blocksize
)
635 /* Do any translations on the whole buffer at once. */
637 if (translation_needed
)
638 translate_buffer (ibuf
, nread
);
640 if (conversions_mask
& C_SWAB
)
641 bufstart
= swab_buffer (ibuf
, &nread
);
645 if (conversions_mask
& C_BLOCK
)
646 copy_with_block (bufstart
, nread
);
647 else if (conversions_mask
& C_UNBLOCK
)
648 copy_with_unblock (bufstart
, nread
);
650 copy_simple (bufstart
, nread
);
653 /* If we have a char left as a result of conv=swab, output it. */
656 if (conversions_mask
& C_BLOCK
)
657 copy_with_block (&saved_char
, 1);
658 else if (conversions_mask
& C_UNBLOCK
)
659 copy_with_unblock (&saved_char
, 1);
661 output_char (saved_char
);
664 if ((conversions_mask
& C_BLOCK
) && col
> 0)
666 /* If the final input line didn't end with a '\n', pad
667 the output block to `conversion_blocksize' chars. */
668 int pending_spaces
= max (0, conversion_blocksize
- col
);
669 while (pending_spaces
)
671 output_char (space_character
);
676 if ((conversions_mask
& C_UNBLOCK
) && col
== conversion_blocksize
)
677 /* Add a final '\n' if there are exactly `conversion_blocksize'
678 characters in the final record. */
679 output_char (newline_character
);
681 /* Write out the last block. */
684 int nwritten
= full_write (output_fd
, obuf
, oc
);
689 error (0, errno
, "%s", output_file
);
694 free (ibuf
- SWAB_ALIGN_OFFSET
);
701 /* Copy NREAD bytes of BUF, with no conversions. */
704 copy_simple (buf
, nread
)
708 int nfree
; /* Number of unused bytes in `obuf'. */
709 unsigned char *start
= buf
; /* First uncopied char in BUF. */
713 nfree
= output_blocksize
- oc
;
717 memcpy (obuf
+ oc
, start
, nfree
);
719 nread
-= nfree
; /* Update the number of bytes left to copy. */
722 if (oc
>= output_blocksize
)
728 /* Copy NREAD bytes of BUF, doing conv=block
729 (pad newline-terminated records to `conversion_blocksize',
730 replacing the newline with trailing spaces). */
733 copy_with_block (buf
, nread
)
739 for (i
= nread
; i
; i
--, buf
++)
741 if (*buf
== newline_character
)
743 int pending_spaces
= max (0, conversion_blocksize
- col
);
744 while (pending_spaces
)
746 output_char (space_character
);
753 if (col
== conversion_blocksize
)
755 else if (col
< conversion_blocksize
)
762 /* Copy NREAD bytes of BUF, doing conv=unblock
763 (replace trailing spaces in `conversion_blocksize'-sized records
767 copy_with_unblock (buf
, nread
)
772 register unsigned char c
;
773 static int pending_spaces
= 0;
775 for (i
= 0; i
< nread
; i
++)
779 if (col
++ >= conversion_blocksize
)
781 col
= pending_spaces
= 0; /* Wipe out any pending spaces. */
782 i
--; /* Push the char back; get it later. */
783 output_char (newline_character
);
785 else if (c
== space_character
)
789 /* `c' is the character after a run of spaces that were not
790 at the end of the conversion buffer. Output them. */
791 while (pending_spaces
)
793 output_char (space_character
);
801 /* Write, then empty, the output buffer `obuf'. */
806 int nwritten
= full_write (output_fd
, obuf
, output_blocksize
);
807 if (nwritten
!= output_blocksize
)
809 error (0, errno
, "%s", output_file
);
820 scanargs (argc
, argv
)
827 while ((c
= getopt_long (argc
, argv
, "", long_options
, (int *) 0)) != EOF
)
839 for (i
= optind
; i
< argc
; i
++)
844 val
= strchr (name
, '=');
847 error (0, 0, "unrecognized option `%s'", name
);
852 if (equal (name
, "if"))
854 else if (equal (name
, "of"))
856 else if (equal (name
, "conv"))
857 parse_conversion (val
);
860 n
= parse_integer (val
);
862 error (1, 0, "invalid number `%s'", val
);
864 if (equal (name
, "ibs"))
867 conversions_mask
|= C_TWOBUFS
;
869 else if (equal (name
, "obs"))
871 output_blocksize
= n
;
872 conversions_mask
|= C_TWOBUFS
;
874 else if (equal (name
, "bs"))
875 output_blocksize
= input_blocksize
= n
;
876 else if (equal (name
, "cbs"))
877 conversion_blocksize
= n
;
878 else if (equal (name
, "skip"))
880 else if (equal (name
, "seek"))
882 else if (equal (name
, "count"))
886 error (0, 0, "unrecognized option `%s=%s'", name
, val
);
892 /* If bs= was given, both `input_blocksize' and `output_blocksize' will
893 have been set to non-negative values. If either has not been set,
894 bs= was not given, so make sure two buffers are used. */
895 if (input_blocksize
== -1 || output_blocksize
== -1)
896 conversions_mask
|= C_TWOBUFS
;
897 if (input_blocksize
== -1)
898 input_blocksize
= DEFAULT_BLOCKSIZE
;
899 if (output_blocksize
== -1)
900 output_blocksize
= DEFAULT_BLOCKSIZE
;
901 if (conversion_blocksize
== 0)
902 conversions_mask
&= ~(C_BLOCK
| C_UNBLOCK
);
905 /* Return the value of STR, interpreted as a non-negative decimal integer,
906 optionally multiplied by various values.
907 Return -1 if STR does not represent a number in this format. */
909 /* FIXME: use xstrtou?l */
917 register char *p
= str
;
921 n
= n
* 10 + *p
- '0';
941 temp
= parse_integer (p
);
952 /* Interpret one "conv=..." option. */
955 parse_conversion (str
)
963 new = strchr (str
, ',');
966 for (i
= 0; conversions
[i
].convname
!= NULL
; i
++)
967 if (equal (conversions
[i
].convname
, str
))
969 conversions_mask
|= conversions
[i
].conversion
;
972 if (conversions
[i
].convname
== NULL
)
974 error (0, 0, "%s: invalid conversion", str
);
978 } while (new != NULL
);
981 /* Fix up translation table. */
984 apply_translations ()
988 #define MX(a) (bit_count (conversions_mask & (a)))
989 if ((MX (C_ASCII
| C_EBCDIC
| C_IBM
) > 1)
990 || (MX (C_BLOCK
| C_UNBLOCK
) > 1)
991 || (MX (C_LCASE
| C_UCASE
) > 1)
992 || (MX (C_UNBLOCK
| C_SYNC
) > 1))
995 only one conv in {ascii,ebcdic,ibm}, {lcase,ucase}, {block,unblock}, {unblock,sync}");
999 if (conversions_mask
& C_ASCII
)
1000 translate_charset (ebcdic_to_ascii
);
1002 if (conversions_mask
& C_UCASE
)
1004 for (i
= 0; i
< 256; i
++)
1005 if (ISLOWER (trans_table
[i
]))
1006 trans_table
[i
] = toupper (trans_table
[i
]);
1007 translation_needed
= 1;
1009 else if (conversions_mask
& C_LCASE
)
1011 for (i
= 0; i
< 256; i
++)
1012 if (ISUPPER (trans_table
[i
]))
1013 trans_table
[i
] = tolower (trans_table
[i
]);
1014 translation_needed
= 1;
1017 if (conversions_mask
& C_EBCDIC
)
1019 translate_charset (ascii_to_ebcdic
);
1020 newline_character
= ascii_to_ebcdic
['\n'];
1021 space_character
= ascii_to_ebcdic
[' '];
1023 else if (conversions_mask
& C_IBM
)
1025 translate_charset (ascii_to_ibm
);
1026 newline_character
= ascii_to_ibm
['\n'];
1027 space_character
= ascii_to_ibm
[' '];
1032 translate_charset (new_trans
)
1033 unsigned char *new_trans
;
1037 for (i
= 0; i
< 256; i
++)
1038 trans_table
[i
] = new_trans
[trans_table
[i
]];
1039 translation_needed
= 1;
1042 /* Return the number of 1 bits in `i'. */
1046 register unsigned int i
;
1048 register int set_bits
;
1050 for (set_bits
= 0; i
!= 0; set_bits
++)
1058 fprintf (stderr
, "%u+%u records in\n", r_full
, r_partial
);
1059 fprintf (stderr
, "%u+%u records out\n", w_full
, w_partial
);
1061 fprintf (stderr
, "%u truncated record%s\n", r_truncate
,
1062 r_truncate
== 1 ? "" : "s");
1069 int errcode
= code
? code
: 1;
1071 if (close (input_fd
) < 0)
1072 error (errcode
, errno
, "%s", input_file
);
1073 if (close (output_fd
) < 0)
1074 error (errcode
, errno
, "%s", output_file
);
1079 interrupt_handler ()
1089 fprintf (stderr
, "Try `%s --help' for more information.\n",
1093 printf ("Usage: %s [OPTION]...\n", program_name
);
1095 Copy a file, converting and formatting according to the options.\n\
1097 bs=BYTES force ibs=BYTES and obs=BYTES\n\
1098 cbs=BYTES convert BYTES bytes at a time\n\
1099 conv=KEYWORDS convert the file as per the comma separated keyword list\n\
1100 count=BLOCKS copy only BLOCKS input blocks\n\
1101 ibs=BYTES read BYTES bytes at a time\n\
1102 if=FILE read from FILE instead of stdin\n\
1103 obs=BYTES write BYTES bytes at a time\n\
1104 of=FILE write to FILE instead of stdout, don't truncate file\n\
1105 seek=BLOCKS skip BLOCKS obs-sized blocks at start of output\n\
1106 skip=BLOCKS skip BLOCKS ibs-sized blocks at start of input\n\
1107 --help display this help and exit\n\
1108 --version output version information and exit\n\
1110 BYTES may be suffixed: by xM for multiplication by M, by c for x1,\n\
1111 by w for x2, by b for x512, by k for x1024. Each KEYWORD may be:\n\
1113 ascii from EBCDIC to ASCII\n\
1114 ebcdic from ASCII to EBCDIC\n\
1115 ibm from ASCII to alternated EBCDIC\n\
1116 block pad newline-terminated records with spaces to cbs-size \n\
1117 unblock replace trailing spaces in cbs-size records with newline\n\
1118 lcase change upper case to lower case\n\
1119 ucase change lower case to upper case\n\
1120 swab swap every pair of input bytes\n\
1121 noerror continue after read errors\n\
1122 sync pad every input block with NULs to ibs-size\n");