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
__P ((int));
99 static int bit_count
__P ((register unsigned int i
));
100 static int parse_integer
__P ((char *str
));
101 static void apply_translations
__P ((void));
102 static void copy
__P ((void));
103 static void copy_simple
__P ((unsigned char *buf
, int nread
));
104 static void copy_with_block
__P ((unsigned char *buf
, int nread
));
105 static void copy_with_unblock
__P ((unsigned char *buf
, int nread
));
106 static void parse_conversion
__P ((char *str
));
107 static void print_stats
__P ((void));
108 static void translate_charset
__P ((const unsigned char *new_trans
));
109 static void quit
__P ((int code
));
110 static void scanargs
__P ((int argc
, char **argv
));
111 static void skip
__P ((int fdesc
, char *file
, long int records
,
112 long int blocksize
, unsigned char *buf
));
113 static void usage
__P ((int status
));
114 static void write_output
__P ((void));
116 /* The name this program was run with. */
119 /* The name of the input file, or NULL for the standard input. */
120 static char *input_file
= NULL
;
122 /* The input file descriptor. */
123 static int input_fd
= 0;
125 /* The name of the output file, or NULL for the standard output. */
126 static char *output_file
= NULL
;
128 /* The output file descriptor. */
129 static int output_fd
= 1;
131 /* The number of bytes in which atomic reads are done. */
132 static long input_blocksize
= -1;
134 /* The number of bytes in which atomic writes are done. */
135 static long output_blocksize
= -1;
137 /* Conversion buffer size, in bytes. 0 prevents conversions. */
138 static long conversion_blocksize
= 0;
140 /* Skip this many records of `input_blocksize' bytes before input. */
141 static long skip_records
= 0;
143 /* Skip this many records of `output_blocksize' bytes before output. */
144 static long seek_record
= 0;
146 /* Copy only this many records. <0 means no limit. */
147 static int max_records
= -1;
149 /* Bit vector of conversions to apply. */
150 static int conversions_mask
= 0;
152 /* If nonzero, filter characters through the translation table. */
153 static int translation_needed
= 0;
155 /* Number of partial blocks written. */
156 static unsigned w_partial
= 0;
158 /* Number of full blocks written. */
159 static unsigned w_full
= 0;
161 /* Number of partial blocks read. */
162 static unsigned r_partial
= 0;
164 /* Number of full blocks read. */
165 static unsigned r_full
= 0;
167 /* Records truncated by conv=block. */
168 static unsigned r_truncate
= 0;
170 /* Output representation of newline and space characters.
171 They change if we're converting to EBCDIC. */
172 static unsigned char newline_character
= '\n';
173 static unsigned char space_character
= ' ';
181 static struct conversion conversions
[] =
183 {"ascii", C_ASCII
| C_TWOBUFS
}, /* EBCDIC to ASCII. */
184 {"ebcdic", C_EBCDIC
| C_TWOBUFS
}, /* ASCII to EBCDIC. */
185 {"ibm", C_IBM
| C_TWOBUFS
}, /* Slightly different ASCII to EBCDIC. */
186 {"block", C_BLOCK
| C_TWOBUFS
}, /* Variable to fixed length records. */
187 {"unblock", C_UNBLOCK
| C_TWOBUFS
}, /* Fixed to variable length records. */
188 {"lcase", C_LCASE
| C_TWOBUFS
}, /* Translate upper to lower case. */
189 {"ucase", C_UCASE
| C_TWOBUFS
}, /* Translate lower to upper case. */
190 {"swab", C_SWAB
| C_TWOBUFS
}, /* Swap bytes of input. */
191 {"noerror", C_NOERROR
}, /* Ignore i/o errors. */
192 {"notrunc", C_NOTRUNC
}, /* Do not truncate output file. */
193 {"sync", C_SYNC
}, /* Pad input records to ibs with NULs. */
197 /* Translation table formed by applying successive transformations. */
198 static unsigned char trans_table
[256];
200 static unsigned char const ascii_to_ebcdic
[] =
202 0, 01, 02, 03, 067, 055, 056, 057,
203 026, 05, 045, 013, 014, 015, 016, 017,
204 020, 021, 022, 023, 074, 075, 062, 046,
205 030, 031, 077, 047, 034, 035, 036, 037,
206 0100, 0117, 0177, 0173, 0133, 0154, 0120, 0175,
207 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
208 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
209 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
210 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
211 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
212 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
213 0347, 0350, 0351, 0112, 0340, 0132, 0137, 0155,
214 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
215 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
216 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
217 0247, 0250, 0251, 0300, 0152, 0320, 0241, 07,
218 040, 041, 042, 043, 044, 025, 06, 027,
219 050, 051, 052, 053, 054, 011, 012, 033,
220 060, 061, 032, 063, 064, 065, 066, 010,
221 070, 071, 072, 073, 04, 024, 076, 0341,
222 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
223 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
224 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
225 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
226 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
227 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
228 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
229 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
230 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
231 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
232 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
233 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377
236 static unsigned char const ascii_to_ibm
[] =
238 0, 01, 02, 03, 067, 055, 056, 057,
239 026, 05, 045, 013, 014, 015, 016, 017,
240 020, 021, 022, 023, 074, 075, 062, 046,
241 030, 031, 077, 047, 034, 035, 036, 037,
242 0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175,
243 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
244 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
245 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
246 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
247 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
248 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
249 0347, 0350, 0351, 0255, 0340, 0275, 0137, 0155,
250 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
251 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
252 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
253 0247, 0250, 0251, 0300, 0117, 0320, 0241, 07,
254 040, 041, 042, 043, 044, 025, 06, 027,
255 050, 051, 052, 053, 054, 011, 012, 033,
256 060, 061, 032, 063, 064, 065, 066, 010,
257 070, 071, 072, 073, 04, 024, 076, 0341,
258 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
259 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
260 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
261 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
262 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
263 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
264 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
265 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
266 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
267 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
268 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
269 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377
272 static unsigned char const ebcdic_to_ascii
[] =
274 0, 01, 02, 03, 0234, 011, 0206, 0177,
275 0227, 0215, 0216, 013, 014, 015, 016, 017,
276 020, 021, 022, 023, 0235, 0205, 010, 0207,
277 030, 031, 0222, 0217, 034, 035, 036, 037,
278 0200, 0201, 0202, 0203, 0204, 012, 027, 033,
279 0210, 0211, 0212, 0213, 0214, 05, 06, 07,
280 0220, 0221, 026, 0223, 0224, 0225, 0226, 04,
281 0230, 0231, 0232, 0233, 024, 025, 0236, 032,
282 040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
283 0247, 0250, 0133, 056, 074, 050, 053, 041,
284 046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
285 0260, 0261, 0135, 044, 052, 051, 073, 0136,
286 055, 057, 0262, 0263, 0264, 0265, 0266, 0267,
287 0270, 0271, 0174, 054, 045, 0137, 076, 077,
288 0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
289 0302, 0140, 072, 043, 0100, 047, 075, 042,
290 0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
291 0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
292 0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
293 0161, 0162, 0313, 0314, 0315, 0316, 0317, 0320,
294 0321, 0176, 0163, 0164, 0165, 0166, 0167, 0170,
295 0171, 0172, 0322, 0323, 0324, 0325, 0326, 0327,
296 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
297 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
298 0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
299 0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
300 0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
301 0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
302 0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
303 0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
304 060, 061, 062, 063, 064, 065, 066, 067,
305 070, 071, 0372, 0373, 0374, 0375, 0376, 0377
308 /* If nonzero, display usage information and exit. */
309 static int show_help
;
311 /* If nonzero, print the version on standard output and exit. */
312 static int show_version
;
314 static struct option
const long_options
[] =
316 {"help", no_argument
, &show_help
, 1},
317 {"version", no_argument
, &show_version
, 1},
322 main (int argc
, char **argv
)
324 #ifdef _POSIX_VERSION
325 struct sigaction sigact
;
326 #endif /* _POSIX_VERSION */
329 program_name
= argv
[0];
330 setlocale (LC_ALL
, "");
331 bindtextdomain (PACKAGE
, LOCALEDIR
);
332 textdomain (PACKAGE
);
334 /* Initialize translation table to identity translation. */
335 for (i
= 0; i
< 256; i
++)
338 /* Decode arguments. */
339 scanargs (argc
, argv
);
343 printf ("dd - %s\n", version_string
);
350 apply_translations ();
352 if (input_file
!= NULL
)
354 input_fd
= open (input_file
, O_RDONLY
);
356 error (1, errno
, "%s", input_file
);
359 input_file
= _("standard input");
361 if (input_fd
== output_fd
)
362 error (1, 0, _("%s is closed"), (input_fd
== 0
363 ? _("standard input")
364 : _("standard output")));
366 if (output_file
!= NULL
)
368 int omode
= O_RDWR
| O_CREAT
;
370 if (seek_record
== 0 && !(conversions_mask
& C_NOTRUNC
))
372 output_fd
= open (output_file
, omode
, 0666);
374 error (1, errno
, "%s", output_file
);
375 #ifdef HAVE_FTRUNCATE
376 if (seek_record
> 0 && !(conversions_mask
& C_NOTRUNC
))
378 if (ftruncate (output_fd
, seek_record
* output_blocksize
) < 0)
379 error (0, errno
, "%s", output_file
);
384 output_file
= _("standard output");
386 #ifdef _POSIX_VERSION
387 sigaction (SIGINT
, NULL
, &sigact
);
388 if (sigact
.sa_handler
!= SIG_IGN
)
390 sigact
.sa_handler
= interrupt_handler
;
391 sigemptyset (&sigact
.sa_mask
);
393 sigaction (SIGINT
, &sigact
, NULL
);
395 sigaction (SIGPIPE
, NULL
, &sigact
);
396 if (sigact
.sa_handler
!= SIG_IGN
)
398 sigact
.sa_handler
= interrupt_handler
;
399 sigemptyset (&sigact
.sa_mask
);
401 sigaction (SIGPIPE
, &sigact
, NULL
);
403 #else /* !_POSIX_VERSION */
404 if (signal (SIGINT
, SIG_IGN
) != SIG_IGN
)
405 signal (SIGINT
, interrupt_handler
);
406 if (signal (SIGPIPE
, SIG_IGN
) != SIG_IGN
)
407 signal (SIGPIPE
, interrupt_handler
);
408 #endif /* !_POSIX_VERSION */
412 /* Throw away RECORDS blocks of BLOCKSIZE bytes on file descriptor FDESC,
413 which is open with read permission for FILE. Store up to BLOCKSIZE
414 bytes of the data at a time in BUF, if necessary. */
417 skip (int fdesc
, char *file
, long int records
, long int blocksize
,
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 (unsigned char *buf
, int nread
)
470 register unsigned char *cp
;
473 for (i
= nread
, cp
= buf
; i
; i
--, cp
++)
474 *cp
= trans_table
[*cp
];
477 /* If nonnzero, the last char from the previous call to `swab_buffer'
478 is saved in `saved_char'. */
479 static int char_is_saved
= 0;
481 /* Odd char from previous call. */
482 static unsigned char saved_char
;
484 /* Swap NREAD bytes in BUF, plus possibly an initial char from the
485 previous call. If NREAD is odd, save the last char for the
486 next call. Return the new start of the BUF buffer. */
488 static unsigned char *
489 swab_buffer (unsigned char *buf
, int *nread
)
491 unsigned char *bufstart
= buf
;
492 register unsigned char *cp
;
495 /* Is a char left from last time? */
498 *--bufstart
= saved_char
;
505 /* An odd number of chars are in the buffer. */
506 saved_char
= bufstart
[--*nread
];
510 /* Do the byte-swapping by moving every second character two
511 positions toward the end, working from the end of the buffer
512 toward the beginning. This way we only move half of the data. */
514 cp
= bufstart
+ *nread
; /* Start one char past the last. */
515 for (i
= *nread
/ 2; i
; i
--, cp
-= 2)
522 static unsigned char *obuf
;
524 /* Current index into `obuf'. */
527 /* Index into current line, for `conv=block' and `conv=unblock'. */
535 unsigned char *ibuf
, *bufstart
; /* Input buffer. */
536 int nread
; /* Bytes read in the current block. */
539 /* Leave at least one extra byte at the beginning and end of `ibuf'
540 for conv=swab, but keep the buffer address even. But some peculiar
541 device drivers work only with word-aligned buffers, so leave an
544 ibuf
= (unsigned char *) xmalloc (input_blocksize
+ 2 * SWAB_ALIGN_OFFSET
);
545 ibuf
+= SWAB_ALIGN_OFFSET
;
547 if (conversions_mask
& C_TWOBUFS
)
548 obuf
= (unsigned char *) xmalloc (output_blocksize
);
552 if (skip_records
> 0)
553 skip (input_fd
, input_file
, skip_records
, input_blocksize
, ibuf
);
556 skip (output_fd
, output_file
, seek_record
, output_blocksize
, obuf
);
558 if (max_records
== 0)
563 if (max_records
>= 0 && r_partial
+ r_full
>= max_records
)
566 /* Zero the buffer before reading, so that if we get a read error,
567 whatever data we are able to read is followed by zeros.
568 This minimizes data loss. */
569 if ((conversions_mask
& C_SYNC
) && (conversions_mask
& C_NOERROR
))
570 memset ((char *) ibuf
, 0, input_blocksize
);
572 nread
= safe_read (input_fd
, ibuf
, input_blocksize
);
579 error (0, errno
, "%s", input_file
);
580 if (conversions_mask
& C_NOERROR
)
583 /* Seek past the bad block if possible. */
584 lseek (input_fd
, input_blocksize
, SEEK_CUR
);
585 if (conversions_mask
& C_SYNC
)
586 /* Replace the missing input with null bytes and
594 /* Write any partial block. */
600 if (nread
< input_blocksize
)
603 if (conversions_mask
& C_SYNC
)
605 if (!(conversions_mask
& C_NOERROR
))
606 /* If C_NOERROR, we zeroed the block before reading. */
607 memset ((char *) (ibuf
+ nread
), 0, input_blocksize
- nread
);
608 nread
= input_blocksize
;
614 if (ibuf
== obuf
) /* If not C_TWOBUFS. */
616 int nwritten
= full_write (output_fd
, obuf
, nread
);
619 error (0, errno
, "%s", output_file
);
622 else if (nread
== input_blocksize
)
629 /* Do any translations on the whole buffer at once. */
631 if (translation_needed
)
632 translate_buffer (ibuf
, nread
);
634 if (conversions_mask
& C_SWAB
)
635 bufstart
= swab_buffer (ibuf
, &nread
);
639 if (conversions_mask
& C_BLOCK
)
640 copy_with_block (bufstart
, nread
);
641 else if (conversions_mask
& C_UNBLOCK
)
642 copy_with_unblock (bufstart
, nread
);
644 copy_simple (bufstart
, nread
);
647 /* If we have a char left as a result of conv=swab, output it. */
650 if (conversions_mask
& C_BLOCK
)
651 copy_with_block (&saved_char
, 1);
652 else if (conversions_mask
& C_UNBLOCK
)
653 copy_with_unblock (&saved_char
, 1);
655 output_char (saved_char
);
658 if ((conversions_mask
& C_BLOCK
) && col
> 0)
660 /* If the final input line didn't end with a '\n', pad
661 the output block to `conversion_blocksize' chars. */
662 int pending_spaces
= max (0, conversion_blocksize
- col
);
663 while (pending_spaces
)
665 output_char (space_character
);
670 if ((conversions_mask
& C_UNBLOCK
) && col
== conversion_blocksize
)
671 /* Add a final '\n' if there are exactly `conversion_blocksize'
672 characters in the final record. */
673 output_char (newline_character
);
675 /* Write out the last block. */
678 int nwritten
= full_write (output_fd
, obuf
, oc
);
683 error (0, errno
, "%s", output_file
);
688 free (ibuf
- SWAB_ALIGN_OFFSET
);
695 /* Copy NREAD bytes of BUF, with no conversions. */
698 copy_simple (unsigned char *buf
, int nread
)
700 int nfree
; /* Number of unused bytes in `obuf'. */
701 unsigned char *start
= buf
; /* First uncopied char in BUF. */
705 nfree
= output_blocksize
- oc
;
709 memcpy ((char *) (obuf
+ oc
), (char *) start
, nfree
);
711 nread
-= nfree
; /* Update the number of bytes left to copy. */
714 if (oc
>= output_blocksize
)
720 /* Copy NREAD bytes of BUF, doing conv=block
721 (pad newline-terminated records to `conversion_blocksize',
722 replacing the newline with trailing spaces). */
725 copy_with_block (unsigned char *buf
, int nread
)
729 for (i
= nread
; i
; i
--, buf
++)
731 if (*buf
== newline_character
)
733 int pending_spaces
= max (0, conversion_blocksize
- col
);
734 while (pending_spaces
)
736 output_char (space_character
);
743 if (col
== conversion_blocksize
)
745 else if (col
< conversion_blocksize
)
752 /* Copy NREAD bytes of BUF, doing conv=unblock
753 (replace trailing spaces in `conversion_blocksize'-sized records
757 copy_with_unblock (unsigned char *buf
, int nread
)
760 register unsigned char c
;
761 static int pending_spaces
= 0;
763 for (i
= 0; i
< nread
; i
++)
767 if (col
++ >= conversion_blocksize
)
769 col
= pending_spaces
= 0; /* Wipe out any pending spaces. */
770 i
--; /* Push the char back; get it later. */
771 output_char (newline_character
);
773 else if (c
== space_character
)
777 /* `c' is the character after a run of spaces that were not
778 at the end of the conversion buffer. Output them. */
779 while (pending_spaces
)
781 output_char (space_character
);
789 /* Write, then empty, the output buffer `obuf'. */
794 int nwritten
= full_write (output_fd
, obuf
, output_blocksize
);
795 if (nwritten
!= output_blocksize
)
797 error (0, errno
, "%s", output_file
);
808 scanargs (int argc
, char **argv
)
813 while ((c
= getopt_long (argc
, argv
, "", long_options
, (int *) 0)) != EOF
)
825 for (i
= optind
; i
< argc
; i
++)
830 val
= strchr (name
, '=');
833 error (0, 0, _("unrecognized option `%s'"), name
);
838 if (equal (name
, "if"))
840 else if (equal (name
, "of"))
842 else if (equal (name
, "conv"))
843 parse_conversion (val
);
846 n
= parse_integer (val
);
848 error (1, 0, _("invalid number `%s'"), val
);
850 if (equal (name
, "ibs"))
853 conversions_mask
|= C_TWOBUFS
;
855 else if (equal (name
, "obs"))
857 output_blocksize
= n
;
858 conversions_mask
|= C_TWOBUFS
;
860 else if (equal (name
, "bs"))
861 output_blocksize
= input_blocksize
= n
;
862 else if (equal (name
, "cbs"))
863 conversion_blocksize
= n
;
864 else if (equal (name
, "skip"))
866 else if (equal (name
, "seek"))
868 else if (equal (name
, "count"))
872 error (0, 0, _("unrecognized option `%s=%s'"), name
, val
);
878 /* If bs= was given, both `input_blocksize' and `output_blocksize' will
879 have been set to non-negative values. If either has not been set,
880 bs= was not given, so make sure two buffers are used. */
881 if (input_blocksize
== -1 || output_blocksize
== -1)
882 conversions_mask
|= C_TWOBUFS
;
883 if (input_blocksize
== -1)
884 input_blocksize
= DEFAULT_BLOCKSIZE
;
885 if (output_blocksize
== -1)
886 output_blocksize
= DEFAULT_BLOCKSIZE
;
887 if (conversion_blocksize
== 0)
888 conversions_mask
&= ~(C_BLOCK
| C_UNBLOCK
);
891 /* Return the value of STR, interpreted as a non-negative decimal integer,
892 optionally multiplied by various values.
893 Return -1 if STR does not represent a number in this format. */
895 /* FIXME: use xstrtou?l */
898 parse_integer (char *str
)
902 register char *p
= str
;
906 n
= n
* 10 + *p
- '0';
926 temp
= parse_integer (p
);
937 /* Interpret one "conv=..." option. */
940 parse_conversion (char *str
)
947 new = strchr (str
, ',');
950 for (i
= 0; conversions
[i
].convname
!= NULL
; i
++)
951 if (equal (conversions
[i
].convname
, str
))
953 conversions_mask
|= conversions
[i
].conversion
;
956 if (conversions
[i
].convname
== NULL
)
958 error (0, 0, _("%s: invalid conversion"), str
);
962 } while (new != NULL
);
965 /* Fix up translation table. */
968 apply_translations (void)
972 #define MX(a) (bit_count (conversions_mask & (a)))
973 if ((MX (C_ASCII
| C_EBCDIC
| C_IBM
) > 1)
974 || (MX (C_BLOCK
| C_UNBLOCK
) > 1)
975 || (MX (C_LCASE
| C_UCASE
) > 1)
976 || (MX (C_UNBLOCK
| C_SYNC
) > 1))
979 only one conv in {ascii,ebcdic,ibm}, {lcase,ucase}, {block,unblock}, {unblock,sync}"));
983 if (conversions_mask
& C_ASCII
)
984 translate_charset (ebcdic_to_ascii
);
986 if (conversions_mask
& C_UCASE
)
988 for (i
= 0; i
< 256; i
++)
989 if (ISLOWER (trans_table
[i
]))
990 trans_table
[i
] = toupper (trans_table
[i
]);
991 translation_needed
= 1;
993 else if (conversions_mask
& C_LCASE
)
995 for (i
= 0; i
< 256; i
++)
996 if (ISUPPER (trans_table
[i
]))
997 trans_table
[i
] = tolower (trans_table
[i
]);
998 translation_needed
= 1;
1001 if (conversions_mask
& C_EBCDIC
)
1003 translate_charset (ascii_to_ebcdic
);
1004 newline_character
= ascii_to_ebcdic
['\n'];
1005 space_character
= ascii_to_ebcdic
[' '];
1007 else if (conversions_mask
& C_IBM
)
1009 translate_charset (ascii_to_ibm
);
1010 newline_character
= ascii_to_ibm
['\n'];
1011 space_character
= ascii_to_ibm
[' '];
1016 translate_charset (const unsigned char *new_trans
)
1020 for (i
= 0; i
< 256; i
++)
1021 trans_table
[i
] = new_trans
[trans_table
[i
]];
1022 translation_needed
= 1;
1025 /* Return the number of 1 bits in `i'. */
1028 bit_count (register unsigned int i
)
1030 register int set_bits
;
1032 for (set_bits
= 0; i
!= 0; set_bits
++)
1040 fprintf (stderr
, _("%u+%u records in\n"), r_full
, r_partial
);
1041 fprintf (stderr
, _("%u+%u records out\n"), w_full
, w_partial
);
1043 fprintf (stderr
, _("%u truncated record%s\n"), r_truncate
,
1044 r_truncate
== 1 ? "" : "s");
1051 if (close (input_fd
) < 0)
1052 error (1, errno
, "%s", input_file
);
1053 if (close (output_fd
) < 0)
1054 error (1, errno
, "%s", output_file
);
1065 interrupt_handler (int sig
)
1068 struct sigaction sigact
;
1070 sigact
.sa_handler
= SIG_DFL
;
1071 sigemptyset (&sigact
.sa_mask
);
1072 sigact
.sa_flags
= 0;
1073 sigaction (sig
, &sigact
, NULL
);
1074 #else /* !SA_INTERRUPT */
1075 signal (sig
, SIG_DFL
);
1076 #endif /* SA_INTERRUPT */
1078 kill (getpid (), sig
);
1085 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
1089 printf (_("Usage: %s [OPTION]...\n"), program_name
);
1091 Copy a file, converting and formatting according to the options.\n\
1093 bs=BYTES force ibs=BYTES and obs=BYTES\n\
1094 cbs=BYTES convert BYTES bytes at a time\n\
1095 conv=KEYWORDS convert the file as per the comma separated keyword list\n\
1096 count=BLOCKS copy only BLOCKS input blocks\n\
1097 ibs=BYTES read BYTES bytes at a time\n\
1098 if=FILE read from FILE instead of stdin\n\
1099 obs=BYTES write BYTES bytes at a time\n\
1100 of=FILE write to FILE instead of stdout, don't truncate file\n\
1101 seek=BLOCKS skip BLOCKS obs-sized blocks at start of output\n\
1102 skip=BLOCKS skip BLOCKS ibs-sized blocks at start of input\n\
1103 --help display this help and exit\n\
1104 --version output version information and exit\n\
1106 BYTES may be suffixed: by xM for multiplication by M, by c for x1,\n\
1107 by w for x2, by b for x512, by k for x1024. Each KEYWORD may be:\n\
1109 ascii from EBCDIC to ASCII\n\
1110 ebcdic from ASCII to EBCDIC\n\
1111 ibm from ASCII to alternated EBCDIC\n\
1112 block pad newline-terminated records with spaces to cbs-size \n\
1113 unblock replace trailing spaces in cbs-size records with newline\n\
1114 lcase change upper case to lower case\n\
1115 ucase change lower case to upper case\n\
1116 swab swap every pair of input bytes\n\
1117 noerror continue after read errors\n\
1118 sync pad every input block with NULs to ibs-size\n"));