.
[coreutils.git] / src / dd.c
blobac43697f2cfb5dcef3408fa76b69ae6a6a746fb8
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)
7 any later version.
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. */
20 /* Options:
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
27 truncate FILE.
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
33 start of input.
34 seek=BLOCKS Skip BLOCKS obs-sized blocks at
35 start of output.
36 count=BLOCKS Copy only BLOCKS input blocks.
37 conv=CONVERSION[,CONVERSION...]
39 Conversions:
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
46 with newline.
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
54 trailing NULs. */
56 #include <config.h>
57 #include <stdio.h>
59 #define SWAB_ALIGN_OFFSET 2
61 #include <sys/types.h>
62 #include <signal.h>
63 #include <getopt.h>
65 #include "system.h"
66 #include "version.h"
67 #include "error.h"
69 #define equal(p, q) (strcmp ((p),(q)) == 0)
70 #define max(a, b) ((a) > (b) ? (a) : (b))
71 #define output_char(c) \
72 do { \
73 obuf[oc++] = (c); if (oc >= output_blocksize) write_output (); \
74 } while (0)
76 /* Default input and output blocksize. */
77 #define DEFAULT_BLOCKSIZE 512
79 /* Conversions bit masks. */
80 #define C_ASCII 01
81 #define C_EBCDIC 02
82 #define C_IBM 04
83 #define C_BLOCK 010
84 #define C_UNBLOCK 020
85 #define C_LCASE 040
86 #define C_UCASE 0100
87 #define C_SWAB 0200
88 #define C_NOERROR 0400
89 #define C_NOTRUNC 01000
90 #define C_SYNC 02000
91 /* Use separate input and output buffers, and combine partial input blocks. */
92 #define C_TWOBUFS 04000
94 char *xmalloc ();
95 int safe_read ();
96 int full_write ();
98 static RETSIGTYPE interrupt_handler __P ((void));
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, char *buf));
113 static void usage __P ((int status));
114 static void write_output __P ((void));
116 /* The name this program was run with. */
117 char *program_name;
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 = ' ';
175 struct conversion
177 char *convname;
178 int conversion;
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. */
194 {NULL, 0}
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},
318 {0, 0, 0, 0}
321 void
322 main (int argc, char **argv)
324 #ifdef _POSIX_VERSION
325 struct sigaction sigact;
326 #endif /* _POSIX_VERSION */
327 int i;
329 program_name = argv[0];
331 /* Initialize translation table to identity translation. */
332 for (i = 0; i < 256; i++)
333 trans_table[i] = i;
335 /* Decode arguments. */
336 scanargs (argc, argv);
338 if (show_version)
340 printf ("dd - %s\n", version_string);
341 exit (0);
344 if (show_help)
345 usage (0);
347 apply_translations ();
349 if (input_file != NULL)
351 input_fd = open (input_file, O_RDONLY);
352 if (input_fd < 0)
353 error (1, errno, "%s", input_file);
355 else
356 input_file = _("standard input");
358 if (input_fd == output_fd)
359 error (1, 0, _("%s is closed"), (input_fd == 0
360 ? _("standard input")
361 : _("standard output")));
363 if (output_file != NULL)
365 int omode = O_RDWR | O_CREAT;
367 if (seek_record == 0 && !(conversions_mask & C_NOTRUNC))
368 omode |= O_TRUNC;
369 output_fd = open (output_file, omode, 0666);
370 if (output_fd < 0)
371 error (1, errno, "%s", output_file);
372 #ifdef HAVE_FTRUNCATE
373 if (seek_record > 0 && !(conversions_mask & C_NOTRUNC))
375 if (ftruncate (output_fd, seek_record * output_blocksize) < 0)
376 error (0, errno, "%s", output_file);
378 #endif
380 else
381 output_file = _("standard output");
383 #ifdef _POSIX_VERSION
384 sigaction (SIGINT, NULL, &sigact);
385 if (sigact.sa_handler != SIG_IGN)
387 sigact.sa_handler = interrupt_handler;
388 sigemptyset (&sigact.sa_mask);
389 sigact.sa_flags = 0;
390 sigaction (SIGINT, &sigact, NULL);
392 sigaction (SIGPIPE, NULL, &sigact);
393 if (sigact.sa_handler != SIG_IGN)
395 sigact.sa_handler = interrupt_handler;
396 sigemptyset (&sigact.sa_mask);
397 sigact.sa_flags = 0;
398 sigaction (SIGPIPE, &sigact, NULL);
400 #else /* !_POSIX_VERSION */
401 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
402 signal (SIGINT, interrupt_handler);
403 if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
404 signal (SIGPIPE, interrupt_handler);
405 #endif /* !_POSIX_VERSION */
406 copy ();
409 /* Throw away RECORDS blocks of BLOCKSIZE bytes on file descriptor FDESC,
410 which is open with read permission for FILE. Store up to BLOCKSIZE
411 bytes of the data at a time in BUF, if necessary. */
413 static void
414 skip (int fdesc, char *file, long int records, long int blocksize, char *buf)
416 struct stat stats;
418 /* Use fstat instead of checking for errno == ESPIPE because
419 lseek doesn't work on some special files but doesn't return an
420 error, either. */
421 /* FIXME: can this really happen? What system? */
422 if (fstat (fdesc, &stats))
424 error (0, errno, "%s", file);
425 quit (1);
428 /* FIXME: why use lseek only on regular files?
429 Better: try lseek and if an error indicates it was an inappropriate
430 operation, fall back on using read. */
431 if (S_ISREG (stats.st_mode))
433 if (lseek (fdesc, records * blocksize, SEEK_SET) < 0)
435 error (0, errno, "%s", file);
436 quit (1);
439 else
441 while (records-- > 0)
443 int nread;
445 nread = safe_read (fdesc, buf, blocksize);
446 if (nread < 0)
448 error (0, errno, "%s", file);
449 quit (1);
451 /* POSIX doesn't say what to do when dd detects it has been
452 asked to skip past EOF, so I assume it's non-fatal.
453 FIXME: maybe give a warning. */
454 if (nread == 0)
455 break;
460 /* Apply the character-set translations specified by the user
461 to the NREAD bytes in BUF. */
463 static void
464 translate_buffer (unsigned char *buf, int nread)
466 register unsigned char *cp;
467 register int i;
469 for (i = nread, cp = buf; i; i--, cp++)
470 *cp = trans_table[*cp];
473 /* If nonnzero, the last char from the previous call to `swab_buffer'
474 is saved in `saved_char'. */
475 static int char_is_saved = 0;
477 /* Odd char from previous call. */
478 static unsigned char saved_char;
480 /* Swap NREAD bytes in BUF, plus possibly an initial char from the
481 previous call. If NREAD is odd, save the last char for the
482 next call. Return the new start of the BUF buffer. */
484 static unsigned char *
485 swab_buffer (unsigned char *buf, int *nread)
487 unsigned char *bufstart = buf;
488 register unsigned char *cp;
489 register int i;
491 /* Is a char left from last time? */
492 if (char_is_saved)
494 *--bufstart = saved_char;
495 (*nread)++;
496 char_is_saved = 0;
499 if (*nread & 1)
501 /* An odd number of chars are in the buffer. */
502 saved_char = bufstart[--*nread];
503 char_is_saved = 1;
506 /* Do the byte-swapping by moving every second character two
507 positions toward the end, working from the end of the buffer
508 toward the beginning. This way we only move half of the data. */
510 cp = bufstart + *nread; /* Start one char past the last. */
511 for (i = *nread / 2; i; i--, cp -= 2)
512 *cp = *(cp - 2);
514 return ++bufstart;
517 /* Output buffer. */
518 static unsigned char *obuf;
520 /* Current index into `obuf'. */
521 static int oc = 0;
523 /* Index into current line, for `conv=block' and `conv=unblock'. */
524 static int col = 0;
526 /* The main loop. */
528 static void
529 copy (void)
531 unsigned char *ibuf, *bufstart; /* Input buffer. */
532 int nread; /* Bytes read in the current block. */
533 int exit_status = 0;
535 /* Leave at least one extra byte at the beginning and end of `ibuf'
536 for conv=swab, but keep the buffer address even. But some peculiar
537 device drivers work only with word-aligned buffers, so leave an
538 extra two bytes. */
540 ibuf = (unsigned char *) xmalloc (input_blocksize + 2 * SWAB_ALIGN_OFFSET);
541 ibuf += SWAB_ALIGN_OFFSET;
543 if (conversions_mask & C_TWOBUFS)
544 obuf = (unsigned char *) xmalloc (output_blocksize);
545 else
546 obuf = ibuf;
548 if (skip_records > 0)
549 skip (input_fd, input_file, skip_records, input_blocksize, ibuf);
551 if (seek_record > 0)
552 skip (output_fd, output_file, seek_record, output_blocksize, obuf);
554 if (max_records == 0)
555 quit (exit_status);
557 while (1)
559 if (max_records >= 0 && r_partial + r_full >= max_records)
560 break;
562 /* Zero the buffer before reading, so that if we get a read error,
563 whatever data we are able to read is followed by zeros.
564 This minimizes data loss. */
565 if ((conversions_mask & C_SYNC) && (conversions_mask & C_NOERROR))
566 memset (ibuf, 0, input_blocksize);
568 nread = safe_read (input_fd, ibuf, input_blocksize);
570 if (nread == 0)
571 break; /* EOF. */
573 if (nread < 0)
575 error (0, errno, "%s", input_file);
576 if (conversions_mask & C_NOERROR)
578 print_stats ();
579 /* Seek past the bad block if possible. */
580 lseek (input_fd, input_blocksize, SEEK_CUR);
581 if (conversions_mask & C_SYNC)
582 /* Replace the missing input with null bytes and
583 proceed normally. */
584 nread = 0;
585 else
586 continue;
588 else
590 /* Write any partial block. */
591 exit_status = 2;
592 break;
596 if (nread < input_blocksize)
598 r_partial++;
599 if (conversions_mask & C_SYNC)
601 if (!(conversions_mask & C_NOERROR))
602 /* If C_NOERROR, we zeroed the block before reading. */
603 memset (ibuf + nread, 0, input_blocksize - nread);
604 nread = input_blocksize;
607 else
608 r_full++;
610 if (ibuf == obuf) /* If not C_TWOBUFS. */
612 int nwritten = full_write (output_fd, obuf, nread);
613 if (nwritten != nread)
615 error (0, errno, "%s", output_file);
616 if (nwritten > 0)
617 w_partial++;
618 quit (1);
620 else if (nread == input_blocksize)
621 w_full++;
622 else
623 w_partial++;
624 continue;
627 /* Do any translations on the whole buffer at once. */
629 if (translation_needed)
630 translate_buffer (ibuf, nread);
632 if (conversions_mask & C_SWAB)
633 bufstart = swab_buffer (ibuf, &nread);
634 else
635 bufstart = ibuf;
637 if (conversions_mask & C_BLOCK)
638 copy_with_block (bufstart, nread);
639 else if (conversions_mask & C_UNBLOCK)
640 copy_with_unblock (bufstart, nread);
641 else
642 copy_simple (bufstart, nread);
645 /* If we have a char left as a result of conv=swab, output it. */
646 if (char_is_saved)
648 if (conversions_mask & C_BLOCK)
649 copy_with_block (&saved_char, 1);
650 else if (conversions_mask & C_UNBLOCK)
651 copy_with_unblock (&saved_char, 1);
652 else
653 output_char (saved_char);
656 if ((conversions_mask & C_BLOCK) && col > 0)
658 /* If the final input line didn't end with a '\n', pad
659 the output block to `conversion_blocksize' chars. */
660 int pending_spaces = max (0, conversion_blocksize - col);
661 while (pending_spaces)
663 output_char (space_character);
664 --pending_spaces;
668 if ((conversions_mask & C_UNBLOCK) && col == conversion_blocksize)
669 /* Add a final '\n' if there are exactly `conversion_blocksize'
670 characters in the final record. */
671 output_char (newline_character);
673 /* Write out the last block. */
674 if (oc > 0)
676 int nwritten = full_write (output_fd, obuf, oc);
677 if (nwritten > 0)
678 w_partial++;
679 if (nwritten != oc)
681 error (0, errno, "%s", output_file);
682 quit (1);
686 free (ibuf - SWAB_ALIGN_OFFSET);
687 if (obuf != ibuf)
688 free (obuf);
690 quit (exit_status);
693 /* Copy NREAD bytes of BUF, with no conversions. */
695 static void
696 copy_simple (unsigned char *buf, int nread)
698 int nfree; /* Number of unused bytes in `obuf'. */
699 unsigned char *start = buf; /* First uncopied char in BUF. */
703 nfree = output_blocksize - oc;
704 if (nfree > nread)
705 nfree = nread;
707 memcpy (obuf + oc, start, nfree);
709 nread -= nfree; /* Update the number of bytes left to copy. */
710 start += nfree;
711 oc += nfree;
712 if (oc >= output_blocksize)
713 write_output ();
715 while (nread > 0);
718 /* Copy NREAD bytes of BUF, doing conv=block
719 (pad newline-terminated records to `conversion_blocksize',
720 replacing the newline with trailing spaces). */
722 static void
723 copy_with_block (unsigned char *buf, int nread)
725 register int i;
727 for (i = nread; i; i--, buf++)
729 if (*buf == newline_character)
731 int pending_spaces = max (0, conversion_blocksize - col);
732 while (pending_spaces)
734 output_char (space_character);
735 --pending_spaces;
737 col = 0;
739 else
741 if (col == conversion_blocksize)
742 r_truncate++;
743 else if (col < conversion_blocksize)
744 output_char (*buf);
745 col++;
750 /* Copy NREAD bytes of BUF, doing conv=unblock
751 (replace trailing spaces in `conversion_blocksize'-sized records
752 with a newline). */
754 static void
755 copy_with_unblock (unsigned char *buf, int nread)
757 register int i;
758 register unsigned char c;
759 static int pending_spaces = 0;
761 for (i = 0; i < nread; i++)
763 c = buf[i];
765 if (col++ >= conversion_blocksize)
767 col = pending_spaces = 0; /* Wipe out any pending spaces. */
768 i--; /* Push the char back; get it later. */
769 output_char (newline_character);
771 else if (c == space_character)
772 pending_spaces++;
773 else
775 /* `c' is the character after a run of spaces that were not
776 at the end of the conversion buffer. Output them. */
777 while (pending_spaces)
779 output_char (space_character);
780 --pending_spaces;
782 output_char (c);
787 /* Write, then empty, the output buffer `obuf'. */
789 static void
790 write_output (void)
792 int nwritten = full_write (output_fd, obuf, output_blocksize);
793 if (nwritten != output_blocksize)
795 error (0, errno, "%s", output_file);
796 if (nwritten > 0)
797 w_partial++;
798 quit (1);
800 else
801 w_full++;
802 oc = 0;
805 static void
806 scanargs (int argc, char **argv)
808 int i, n;
809 int c;
811 while ((c = getopt_long (argc, argv, "", long_options, (int *) 0)) != EOF)
813 switch (c)
815 case 0:
816 break;
818 default:
819 usage (1);
823 for (i = optind; i < argc; i++)
825 char *name, *val;
827 name = argv[i];
828 val = strchr (name, '=');
829 if (val == NULL)
831 error (0, 0, _("unrecognized option `%s'"), name);
832 usage (1);
834 *val++ = '\0';
836 if (equal (name, "if"))
837 input_file = val;
838 else if (equal (name, "of"))
839 output_file = val;
840 else if (equal (name, "conv"))
841 parse_conversion (val);
842 else
844 n = parse_integer (val);
845 if (n < 0)
846 error (1, 0, _("invalid number `%s'"), val);
848 if (equal (name, "ibs"))
850 input_blocksize = n;
851 conversions_mask |= C_TWOBUFS;
853 else if (equal (name, "obs"))
855 output_blocksize = n;
856 conversions_mask |= C_TWOBUFS;
858 else if (equal (name, "bs"))
859 output_blocksize = input_blocksize = n;
860 else if (equal (name, "cbs"))
861 conversion_blocksize = n;
862 else if (equal (name, "skip"))
863 skip_records = n;
864 else if (equal (name, "seek"))
865 seek_record = n;
866 else if (equal (name, "count"))
867 max_records = n;
868 else
870 error (0, 0, _("unrecognized option `%s=%s'"), name, val);
871 usage (1);
876 /* If bs= was given, both `input_blocksize' and `output_blocksize' will
877 have been set to non-negative values. If either has not been set,
878 bs= was not given, so make sure two buffers are used. */
879 if (input_blocksize == -1 || output_blocksize == -1)
880 conversions_mask |= C_TWOBUFS;
881 if (input_blocksize == -1)
882 input_blocksize = DEFAULT_BLOCKSIZE;
883 if (output_blocksize == -1)
884 output_blocksize = DEFAULT_BLOCKSIZE;
885 if (conversion_blocksize == 0)
886 conversions_mask &= ~(C_BLOCK | C_UNBLOCK);
889 /* Return the value of STR, interpreted as a non-negative decimal integer,
890 optionally multiplied by various values.
891 Return -1 if STR does not represent a number in this format. */
893 /* FIXME: use xstrtou?l */
895 static int
896 parse_integer (char *str)
898 register int n = 0;
899 register int temp;
900 register char *p = str;
902 while (ISDIGIT (*p))
904 n = n * 10 + *p - '0';
905 p++;
907 loop:
908 switch (*p++)
910 case '\0':
911 return n;
912 case 'b':
913 n *= 512;
914 goto loop;
915 case 'c':
916 goto loop;
917 case 'k':
918 n *= 1024;
919 goto loop;
920 case 'w':
921 n *= 2;
922 goto loop;
923 case 'x':
924 temp = parse_integer (p);
925 if (temp == -1)
926 return -1;
927 n *= temp;
928 break;
929 default:
930 return -1;
932 return n;
935 /* Interpret one "conv=..." option. */
937 static void
938 parse_conversion (char *str)
940 char *new;
941 int i;
945 new = strchr (str, ',');
946 if (new != NULL)
947 *new++ = '\0';
948 for (i = 0; conversions[i].convname != NULL; i++)
949 if (equal (conversions[i].convname, str))
951 conversions_mask |= conversions[i].conversion;
952 break;
954 if (conversions[i].convname == NULL)
956 error (0, 0, _("%s: invalid conversion"), str);
957 usage (1);
959 str = new;
960 } while (new != NULL);
963 /* Fix up translation table. */
965 static void
966 apply_translations (void)
968 int i;
970 #define MX(a) (bit_count (conversions_mask & (a)))
971 if ((MX (C_ASCII | C_EBCDIC | C_IBM) > 1)
972 || (MX (C_BLOCK | C_UNBLOCK) > 1)
973 || (MX (C_LCASE | C_UCASE) > 1)
974 || (MX (C_UNBLOCK | C_SYNC) > 1))
976 error (1, 0, _("\
977 only one conv in {ascii,ebcdic,ibm}, {lcase,ucase}, {block,unblock}, {unblock,sync}"));
979 #undef MX
981 if (conversions_mask & C_ASCII)
982 translate_charset (ebcdic_to_ascii);
984 if (conversions_mask & C_UCASE)
986 for (i = 0; i < 256; i++)
987 if (ISLOWER (trans_table[i]))
988 trans_table[i] = toupper (trans_table[i]);
989 translation_needed = 1;
991 else if (conversions_mask & C_LCASE)
993 for (i = 0; i < 256; i++)
994 if (ISUPPER (trans_table[i]))
995 trans_table[i] = tolower (trans_table[i]);
996 translation_needed = 1;
999 if (conversions_mask & C_EBCDIC)
1001 translate_charset (ascii_to_ebcdic);
1002 newline_character = ascii_to_ebcdic['\n'];
1003 space_character = ascii_to_ebcdic[' '];
1005 else if (conversions_mask & C_IBM)
1007 translate_charset (ascii_to_ibm);
1008 newline_character = ascii_to_ibm['\n'];
1009 space_character = ascii_to_ibm[' '];
1013 static void
1014 translate_charset (const unsigned char *new_trans)
1016 int i;
1018 for (i = 0; i < 256; i++)
1019 trans_table[i] = new_trans[trans_table[i]];
1020 translation_needed = 1;
1023 /* Return the number of 1 bits in `i'. */
1025 static int
1026 bit_count (register unsigned int i)
1028 register int set_bits;
1030 for (set_bits = 0; i != 0; set_bits++)
1031 i &= i - 1;
1032 return set_bits;
1035 static void
1036 print_stats (void)
1038 fprintf (stderr, _("%u+%u records in\n"), r_full, r_partial);
1039 fprintf (stderr, _("%u+%u records out\n"), w_full, w_partial);
1040 if (r_truncate > 0)
1041 fprintf (stderr, _("%u truncated record%s\n"), r_truncate,
1042 r_truncate == 1 ? "" : "s");
1045 static void
1046 quit (int code)
1048 int errcode = code ? code : 1;
1049 print_stats ();
1050 if (close (input_fd) < 0)
1051 error (errcode, errno, "%s", input_file);
1052 if (close (output_fd) < 0)
1053 error (errcode, errno, "%s", output_file);
1054 exit (code);
1057 static RETSIGTYPE
1058 interrupt_handler (void)
1060 quit (1);
1063 static void
1064 usage (int status)
1066 if (status != 0)
1067 fprintf (stderr, _("Try `%s --help' for more information.\n"),
1068 program_name);
1069 else
1071 printf (_("Usage: %s [OPTION]...\n"), program_name);
1072 printf (_("\
1073 Copy a file, converting and formatting according to the options.\n\
1075 bs=BYTES force ibs=BYTES and obs=BYTES\n\
1076 cbs=BYTES convert BYTES bytes at a time\n\
1077 conv=KEYWORDS convert the file as per the comma separated keyword list\n\
1078 count=BLOCKS copy only BLOCKS input blocks\n\
1079 ibs=BYTES read BYTES bytes at a time\n\
1080 if=FILE read from FILE instead of stdin\n\
1081 obs=BYTES write BYTES bytes at a time\n\
1082 of=FILE write to FILE instead of stdout, don't truncate file\n\
1083 seek=BLOCKS skip BLOCKS obs-sized blocks at start of output\n\
1084 skip=BLOCKS skip BLOCKS ibs-sized blocks at start of input\n\
1085 --help display this help and exit\n\
1086 --version output version information and exit\n\
1088 BYTES may be suffixed: by xM for multiplication by M, by c for x1,\n\
1089 by w for x2, by b for x512, by k for x1024. Each KEYWORD may be:\n\
1091 ascii from EBCDIC to ASCII\n\
1092 ebcdic from ASCII to EBCDIC\n\
1093 ibm from ASCII to alternated EBCDIC\n\
1094 block pad newline-terminated records with spaces to cbs-size \n\
1095 unblock replace trailing spaces in cbs-size records with newline\n\
1096 lcase change upper case to lower case\n\
1097 ucase change lower case to upper case\n\
1098 swab swap every pair of input bytes\n\
1099 noerror continue after read errors\n\
1100 sync pad every input block with NULs to ibs-size\n"));
1102 exit (status);