1 /* dd -- convert a file while copying it.
2 Copyright (C) 85, 90, 91, 95, 1996 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 Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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>
68 #define equal(p, q) (strcmp ((p),(q)) == 0)
69 #define max(a, b) ((a) > (b) ? (a) : (b))
70 #define output_char(c) \
72 obuf[oc++] = (c); if (oc >= output_blocksize) write_output (); \
75 /* Default input and output blocksize. */
76 #define DEFAULT_BLOCKSIZE 512
78 /* Conversions bit masks. */
87 #define C_NOERROR 0400
88 #define C_NOTRUNC 01000
90 /* Use separate input and output buffers, and combine partial input blocks. */
91 #define C_TWOBUFS 04000
97 static RETSIGTYPE interrupt_handler
__P ((int));
98 static int bit_count
__P ((register unsigned int i
));
99 static int parse_integer
__P ((char *str
));
100 static void apply_translations
__P ((void));
101 static void copy
__P ((void));
102 static void copy_simple
__P ((unsigned char *buf
, int nread
));
103 static void copy_with_block
__P ((unsigned char *buf
, int nread
));
104 static void copy_with_unblock
__P ((unsigned char *buf
, int nread
));
105 static void parse_conversion
__P ((char *str
));
106 static void print_stats
__P ((void));
107 static void translate_charset
__P ((const unsigned char *new_trans
));
108 static void quit
__P ((int code
));
109 static void scanargs
__P ((int argc
, char **argv
));
110 static void skip
__P ((int fdesc
, char *file
, long int records
,
111 long int blocksize
, unsigned char *buf
));
112 static void usage
__P ((int status
));
113 static void write_output
__P ((void));
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 nonzero, display usage information and exit. */
308 static int show_help
;
310 /* If nonzero, 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},
321 main (int argc
, char **argv
)
323 #ifdef _POSIX_VERSION
324 struct sigaction sigact
;
325 #endif /* _POSIX_VERSION */
328 program_name
= argv
[0];
329 setlocale (LC_ALL
, "");
330 bindtextdomain (PACKAGE
, LOCALEDIR
);
331 textdomain (PACKAGE
);
333 /* Initialize translation table to identity translation. */
334 for (i
= 0; i
< 256; i
++)
337 /* Decode arguments. */
338 scanargs (argc
, argv
);
342 printf ("dd - %s\n", PACKAGE_VERSION
);
349 apply_translations ();
351 if (input_file
!= NULL
)
353 input_fd
= open (input_file
, O_RDONLY
);
355 error (1, errno
, "%s", input_file
);
358 input_file
= _("standard input");
360 if (input_fd
== output_fd
)
361 error (1, 0, _("%s is closed"), (input_fd
== 0
362 ? _("standard input")
363 : _("standard output")));
365 if (output_file
!= NULL
)
367 int omode
= O_RDWR
| O_CREAT
;
369 if (seek_record
== 0 && !(conversions_mask
& C_NOTRUNC
))
371 output_fd
= open (output_file
, omode
, 0666);
373 error (1, errno
, "%s", output_file
);
374 #ifdef HAVE_FTRUNCATE
375 if (seek_record
> 0 && !(conversions_mask
& C_NOTRUNC
))
377 if (ftruncate (output_fd
, seek_record
* output_blocksize
) < 0)
378 error (0, errno
, "%s", output_file
);
383 output_file
= _("standard output");
385 #ifdef _POSIX_VERSION
386 sigaction (SIGINT
, NULL
, &sigact
);
387 if (sigact
.sa_handler
!= SIG_IGN
)
389 sigact
.sa_handler
= interrupt_handler
;
390 sigemptyset (&sigact
.sa_mask
);
392 sigaction (SIGINT
, &sigact
, NULL
);
394 sigaction (SIGPIPE
, NULL
, &sigact
);
395 if (sigact
.sa_handler
!= SIG_IGN
)
397 sigact
.sa_handler
= interrupt_handler
;
398 sigemptyset (&sigact
.sa_mask
);
400 sigaction (SIGPIPE
, &sigact
, NULL
);
402 #else /* !_POSIX_VERSION */
403 if (signal (SIGINT
, SIG_IGN
) != SIG_IGN
)
404 signal (SIGINT
, interrupt_handler
);
405 if (signal (SIGPIPE
, SIG_IGN
) != SIG_IGN
)
406 signal (SIGPIPE
, interrupt_handler
);
407 #endif /* !_POSIX_VERSION */
411 /* Throw away RECORDS blocks of BLOCKSIZE bytes on file descriptor FDESC,
412 which is open with read permission for FILE. Store up to BLOCKSIZE
413 bytes of the data at a time in BUF, if necessary. */
416 skip (int fdesc
, char *file
, long int records
, long int blocksize
,
421 /* Use fstat instead of checking for errno == ESPIPE because
422 lseek doesn't work on some special files but doesn't return an
424 /* FIXME: can this really happen? What system? */
425 if (fstat (fdesc
, &stats
))
427 error (0, errno
, "%s", file
);
431 /* FIXME: why use lseek only on regular files?
432 Better: try lseek and if an error indicates it was an inappropriate
433 operation, fall back on using read. */
434 if (S_ISREG (stats
.st_mode
))
436 if (lseek (fdesc
, records
* blocksize
, SEEK_SET
) < 0)
438 error (0, errno
, "%s", file
);
444 while (records
-- > 0)
448 nread
= safe_read (fdesc
, buf
, blocksize
);
451 error (0, errno
, "%s", file
);
454 /* POSIX doesn't say what to do when dd detects it has been
455 asked to skip past EOF, so I assume it's non-fatal.
456 FIXME: maybe give a warning. */
463 /* Apply the character-set translations specified by the user
464 to the NREAD bytes in BUF. */
467 translate_buffer (unsigned char *buf
, int nread
)
469 register unsigned char *cp
;
472 for (i
= nread
, cp
= buf
; i
; i
--, cp
++)
473 *cp
= trans_table
[*cp
];
476 /* If nonnzero, the last char from the previous call to `swab_buffer'
477 is saved in `saved_char'. */
478 static int char_is_saved
= 0;
480 /* Odd char from previous call. */
481 static unsigned char saved_char
;
483 /* Swap NREAD bytes in BUF, plus possibly an initial char from the
484 previous call. If NREAD is odd, save the last char for the
485 next call. Return the new start of the BUF buffer. */
487 static unsigned char *
488 swab_buffer (unsigned char *buf
, int *nread
)
490 unsigned char *bufstart
= buf
;
491 register unsigned char *cp
;
494 /* Is a char left from last time? */
497 *--bufstart
= saved_char
;
504 /* An odd number of chars are in the buffer. */
505 saved_char
= bufstart
[--*nread
];
509 /* Do the byte-swapping by moving every second character two
510 positions toward the end, working from the end of the buffer
511 toward the beginning. This way we only move half of the data. */
513 cp
= bufstart
+ *nread
; /* Start one char past the last. */
514 for (i
= *nread
/ 2; i
; i
--, cp
-= 2)
521 static unsigned char *obuf
;
523 /* Current index into `obuf'. */
526 /* Index into current line, for `conv=block' and `conv=unblock'. */
534 unsigned char *ibuf
, *bufstart
; /* Input buffer. */
535 int nread
; /* Bytes read in the current block. */
538 /* Leave at least one extra byte at the beginning and end of `ibuf'
539 for conv=swab, but keep the buffer address even. But some peculiar
540 device drivers work only with word-aligned buffers, so leave an
543 ibuf
= (unsigned char *) xmalloc (input_blocksize
+ 2 * SWAB_ALIGN_OFFSET
);
544 ibuf
+= SWAB_ALIGN_OFFSET
;
546 if (conversions_mask
& C_TWOBUFS
)
547 obuf
= (unsigned char *) xmalloc (output_blocksize
);
551 if (skip_records
> 0)
552 skip (input_fd
, input_file
, skip_records
, input_blocksize
, ibuf
);
555 skip (output_fd
, output_file
, seek_record
, output_blocksize
, obuf
);
557 if (max_records
== 0)
562 if (max_records
>= 0 && r_partial
+ r_full
>= max_records
)
565 /* Zero the buffer before reading, so that if we get a read error,
566 whatever data we are able to read is followed by zeros.
567 This minimizes data loss. */
568 if ((conversions_mask
& C_SYNC
) && (conversions_mask
& C_NOERROR
))
569 memset ((char *) ibuf
, 0, input_blocksize
);
571 nread
= safe_read (input_fd
, ibuf
, input_blocksize
);
578 error (0, errno
, "%s", input_file
);
579 if (conversions_mask
& C_NOERROR
)
582 /* Seek past the bad block if possible. */
583 lseek (input_fd
, input_blocksize
, SEEK_CUR
);
584 if (conversions_mask
& C_SYNC
)
585 /* Replace the missing input with null bytes and
593 /* Write any partial block. */
599 if (nread
< input_blocksize
)
602 if (conversions_mask
& C_SYNC
)
604 if (!(conversions_mask
& C_NOERROR
))
605 /* If C_NOERROR, we zeroed the block before reading. */
606 memset ((char *) (ibuf
+ nread
), 0, input_blocksize
- nread
);
607 nread
= input_blocksize
;
613 if (ibuf
== obuf
) /* If not C_TWOBUFS. */
615 int nwritten
= full_write (output_fd
, obuf
, nread
);
618 error (0, errno
, "%s", output_file
);
621 else if (nread
== input_blocksize
)
628 /* Do any translations on the whole buffer at once. */
630 if (translation_needed
)
631 translate_buffer (ibuf
, nread
);
633 if (conversions_mask
& C_SWAB
)
634 bufstart
= swab_buffer (ibuf
, &nread
);
638 if (conversions_mask
& C_BLOCK
)
639 copy_with_block (bufstart
, nread
);
640 else if (conversions_mask
& C_UNBLOCK
)
641 copy_with_unblock (bufstart
, nread
);
643 copy_simple (bufstart
, nread
);
646 /* If we have a char left as a result of conv=swab, output it. */
649 if (conversions_mask
& C_BLOCK
)
650 copy_with_block (&saved_char
, 1);
651 else if (conversions_mask
& C_UNBLOCK
)
652 copy_with_unblock (&saved_char
, 1);
654 output_char (saved_char
);
657 if ((conversions_mask
& C_BLOCK
) && col
> 0)
659 /* If the final input line didn't end with a '\n', pad
660 the output block to `conversion_blocksize' chars. */
661 int pending_spaces
= max (0, conversion_blocksize
- col
);
662 while (pending_spaces
)
664 output_char (space_character
);
669 if ((conversions_mask
& C_UNBLOCK
) && col
== conversion_blocksize
)
670 /* Add a final '\n' if there are exactly `conversion_blocksize'
671 characters in the final record. */
672 output_char (newline_character
);
674 /* Write out the last block. */
677 int nwritten
= full_write (output_fd
, obuf
, oc
);
682 error (0, errno
, "%s", output_file
);
687 free (ibuf
- SWAB_ALIGN_OFFSET
);
694 /* Copy NREAD bytes of BUF, with no conversions. */
697 copy_simple (unsigned char *buf
, int nread
)
699 int nfree
; /* Number of unused bytes in `obuf'. */
700 unsigned char *start
= buf
; /* First uncopied char in BUF. */
704 nfree
= output_blocksize
- oc
;
708 memcpy ((char *) (obuf
+ oc
), (char *) start
, nfree
);
710 nread
-= nfree
; /* Update the number of bytes left to copy. */
713 if (oc
>= output_blocksize
)
719 /* Copy NREAD bytes of BUF, doing conv=block
720 (pad newline-terminated records to `conversion_blocksize',
721 replacing the newline with trailing spaces). */
724 copy_with_block (unsigned char *buf
, int nread
)
728 for (i
= nread
; i
; i
--, buf
++)
730 if (*buf
== newline_character
)
732 int pending_spaces
= max (0, conversion_blocksize
- col
);
733 while (pending_spaces
)
735 output_char (space_character
);
742 if (col
== conversion_blocksize
)
744 else if (col
< conversion_blocksize
)
751 /* Copy NREAD bytes of BUF, doing conv=unblock
752 (replace trailing spaces in `conversion_blocksize'-sized records
756 copy_with_unblock (unsigned char *buf
, int nread
)
759 register unsigned char c
;
760 static int pending_spaces
= 0;
762 for (i
= 0; i
< nread
; i
++)
766 if (col
++ >= conversion_blocksize
)
768 col
= pending_spaces
= 0; /* Wipe out any pending spaces. */
769 i
--; /* Push the char back; get it later. */
770 output_char (newline_character
);
772 else if (c
== space_character
)
776 /* `c' is the character after a run of spaces that were not
777 at the end of the conversion buffer. Output them. */
778 while (pending_spaces
)
780 output_char (space_character
);
788 /* Write, then empty, the output buffer `obuf'. */
793 int nwritten
= full_write (output_fd
, obuf
, output_blocksize
);
794 if (nwritten
!= output_blocksize
)
796 error (0, errno
, "%s", output_file
);
807 scanargs (int argc
, char **argv
)
812 while ((c
= getopt_long (argc
, argv
, "", long_options
, (int *) 0)) != EOF
)
824 for (i
= optind
; i
< argc
; i
++)
829 val
= strchr (name
, '=');
832 error (0, 0, _("unrecognized option `%s'"), name
);
837 if (equal (name
, "if"))
839 else if (equal (name
, "of"))
841 else if (equal (name
, "conv"))
842 parse_conversion (val
);
845 n
= parse_integer (val
);
847 error (1, 0, _("invalid number `%s'"), val
);
849 if (equal (name
, "ibs"))
852 conversions_mask
|= C_TWOBUFS
;
854 else if (equal (name
, "obs"))
856 output_blocksize
= n
;
857 conversions_mask
|= C_TWOBUFS
;
859 else if (equal (name
, "bs"))
860 output_blocksize
= input_blocksize
= n
;
861 else if (equal (name
, "cbs"))
862 conversion_blocksize
= n
;
863 else if (equal (name
, "skip"))
865 else if (equal (name
, "seek"))
867 else if (equal (name
, "count"))
871 error (0, 0, _("unrecognized option `%s=%s'"), name
, val
);
877 /* If bs= was given, both `input_blocksize' and `output_blocksize' will
878 have been set to non-negative values. If either has not been set,
879 bs= was not given, so make sure two buffers are used. */
880 if (input_blocksize
== -1 || output_blocksize
== -1)
881 conversions_mask
|= C_TWOBUFS
;
882 if (input_blocksize
== -1)
883 input_blocksize
= DEFAULT_BLOCKSIZE
;
884 if (output_blocksize
== -1)
885 output_blocksize
= DEFAULT_BLOCKSIZE
;
886 if (conversion_blocksize
== 0)
887 conversions_mask
&= ~(C_BLOCK
| C_UNBLOCK
);
890 /* Return the value of STR, interpreted as a non-negative decimal integer,
891 optionally multiplied by various values.
892 Return -1 if STR does not represent a number in this format. */
894 /* FIXME: use xstrtou?l */
897 parse_integer (char *str
)
901 register char *p
= str
;
905 n
= n
* 10 + *p
- '0';
925 temp
= parse_integer (p
);
936 /* Interpret one "conv=..." option. */
939 parse_conversion (char *str
)
946 new = strchr (str
, ',');
949 for (i
= 0; conversions
[i
].convname
!= NULL
; i
++)
950 if (equal (conversions
[i
].convname
, str
))
952 conversions_mask
|= conversions
[i
].conversion
;
955 if (conversions
[i
].convname
== NULL
)
957 error (0, 0, _("%s: invalid conversion"), str
);
961 } while (new != NULL
);
964 /* Fix up translation table. */
967 apply_translations (void)
971 #define MX(a) (bit_count (conversions_mask & (a)))
972 if ((MX (C_ASCII
| C_EBCDIC
| C_IBM
) > 1)
973 || (MX (C_BLOCK
| C_UNBLOCK
) > 1)
974 || (MX (C_LCASE
| C_UCASE
) > 1)
975 || (MX (C_UNBLOCK
| C_SYNC
) > 1))
978 only one conv in {ascii,ebcdic,ibm}, {lcase,ucase}, {block,unblock}, {unblock,sync}"));
982 if (conversions_mask
& C_ASCII
)
983 translate_charset (ebcdic_to_ascii
);
985 if (conversions_mask
& C_UCASE
)
987 for (i
= 0; i
< 256; i
++)
988 if (ISLOWER (trans_table
[i
]))
989 trans_table
[i
] = toupper (trans_table
[i
]);
990 translation_needed
= 1;
992 else if (conversions_mask
& C_LCASE
)
994 for (i
= 0; i
< 256; i
++)
995 if (ISUPPER (trans_table
[i
]))
996 trans_table
[i
] = tolower (trans_table
[i
]);
997 translation_needed
= 1;
1000 if (conversions_mask
& C_EBCDIC
)
1002 translate_charset (ascii_to_ebcdic
);
1003 newline_character
= ascii_to_ebcdic
['\n'];
1004 space_character
= ascii_to_ebcdic
[' '];
1006 else if (conversions_mask
& C_IBM
)
1008 translate_charset (ascii_to_ibm
);
1009 newline_character
= ascii_to_ibm
['\n'];
1010 space_character
= ascii_to_ibm
[' '];
1015 translate_charset (const unsigned char *new_trans
)
1019 for (i
= 0; i
< 256; i
++)
1020 trans_table
[i
] = new_trans
[trans_table
[i
]];
1021 translation_needed
= 1;
1024 /* Return the number of 1 bits in `i'. */
1027 bit_count (register unsigned int i
)
1029 register int set_bits
;
1031 for (set_bits
= 0; i
!= 0; set_bits
++)
1039 fprintf (stderr
, _("%u+%u records in\n"), r_full
, r_partial
);
1040 fprintf (stderr
, _("%u+%u records out\n"), w_full
, w_partial
);
1042 fprintf (stderr
, "%u %s\n", r_truncate
,
1044 ? _("truncated record")
1045 : _("truncated records")));
1052 if (close (input_fd
) < 0)
1053 error (1, errno
, "%s", input_file
);
1054 if (close (output_fd
) < 0)
1055 error (1, errno
, "%s", output_file
);
1066 interrupt_handler (int sig
)
1069 struct sigaction sigact
;
1071 sigact
.sa_handler
= SIG_DFL
;
1072 sigemptyset (&sigact
.sa_mask
);
1073 sigact
.sa_flags
= 0;
1074 sigaction (sig
, &sigact
, NULL
);
1075 #else /* !SA_INTERRUPT */
1076 signal (sig
, SIG_DFL
);
1077 #endif /* SA_INTERRUPT */
1079 kill (getpid (), sig
);
1086 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
1090 printf (_("Usage: %s [OPTION]...\n"), program_name
);
1092 Copy a file, converting and formatting according to the options.\n\
1094 bs=BYTES force ibs=BYTES and obs=BYTES\n\
1095 cbs=BYTES convert BYTES bytes at a time\n\
1096 conv=KEYWORDS convert the file as per the comma separated keyword list\n\
1097 count=BLOCKS copy only BLOCKS input blocks\n\
1098 ibs=BYTES read BYTES bytes at a time\n\
1099 if=FILE read from FILE instead of stdin\n\
1100 obs=BYTES write BYTES bytes at a time\n\
1101 of=FILE write to FILE instead of stdout, don't truncate file\n\
1102 seek=BLOCKS skip BLOCKS obs-sized blocks at start of output\n\
1103 skip=BLOCKS skip BLOCKS ibs-sized blocks at start of input\n\
1104 --help display this help and exit\n\
1105 --version output version information and exit\n\
1107 BYTES may be suffixed: by xM for multiplication by M, by c for x1,\n\
1108 by w for x2, by b for x512, by k for x1024. Each KEYWORD may be:\n\
1110 ascii from EBCDIC to ASCII\n\
1111 ebcdic from ASCII to EBCDIC\n\
1112 ibm from ASCII to alternated EBCDIC\n\
1113 block pad newline-terminated records with spaces to cbs-size\n\
1114 unblock replace trailing spaces in cbs-size records with newline\n\
1115 lcase change upper case to lower case\n\
1116 ucase change lower case to upper case\n\
1117 swab swap every pair of input bytes\n\
1118 noerror continue after read errors\n\
1119 sync pad every input block with NULs to ibs-size\n\
1121 puts (_("\nReport bugs to bug-gnu-utils@gnu.ai.mit.edu"));