*** empty log message ***
[coreutils.git] / src / dd.c
blob823c8c62a7b309fb436ce440def2d5e64db53e97
1 /* dd -- convert a file while copying it.
2 Copyright (C) 85, 90, 91, 95, 96, 97, 1998 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 Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 /* Written by Paul Rubin, David MacKenzie, and Stuart Kemp. */
20 #include <config.h>
21 #include <stdio.h>
23 #define SWAB_ALIGN_OFFSET 2
25 #if HAVE_INTTYPES_H
26 # include <inttypes.h>
27 #endif
28 #include <sys/types.h>
29 #include <signal.h>
30 #include <getopt.h>
32 #include "human.h"
33 #include "system.h"
34 #include "closeout.h"
35 #include "error.h"
36 #include "safe-read.h"
38 #ifndef SIGINFO
39 # define SIGINFO SIGUSR1
40 #endif
42 #define max(a, b) ((a) > (b) ? (a) : (b))
43 #define output_char(c) \
44 do { \
45 obuf[oc++] = (c); if (oc >= output_blocksize) write_output (); \
46 } while (0)
48 /* Default input and output blocksize. */
49 #define DEFAULT_BLOCKSIZE 512
51 /* Conversions bit masks. */
52 #define C_ASCII 01
53 #define C_EBCDIC 02
54 #define C_IBM 04
55 #define C_BLOCK 010
56 #define C_UNBLOCK 020
57 #define C_LCASE 040
58 #define C_UCASE 0100
59 #define C_SWAB 0200
60 #define C_NOERROR 0400
61 #define C_NOTRUNC 01000
62 #define C_SYNC 02000
63 /* Use separate input and output buffers, and combine partial input blocks. */
64 #define C_TWOBUFS 04000
66 int full_write ();
68 /* The name this program was run with. */
69 char *program_name;
71 /* The name of the input file, or NULL for the standard input. */
72 static char *input_file = NULL;
74 /* The input file descriptor. */
75 static int input_fd = 0;
77 /* The name of the output file, or NULL for the standard output. */
78 static char *output_file = NULL;
80 /* The output file descriptor. */
81 static int output_fd = 1;
83 /* The number of bytes in which atomic reads are done. */
84 static size_t input_blocksize = 0;
86 /* The number of bytes in which atomic writes are done. */
87 static size_t output_blocksize = 0;
89 /* Conversion buffer size, in bytes. 0 prevents conversions. */
90 static size_t conversion_blocksize = 0;
92 /* Skip this many records of `input_blocksize' bytes before input. */
93 static uintmax_t skip_records = 0;
95 /* Skip this many records of `output_blocksize' bytes before output. */
96 static uintmax_t seek_record = 0;
98 /* Copy only this many records. The default is effectively infinity. */
99 static uintmax_t max_records = (uintmax_t) -1;
101 /* Bit vector of conversions to apply. */
102 static int conversions_mask = 0;
104 /* If nonzero, filter characters through the translation table. */
105 static int translation_needed = 0;
107 /* Number of partial blocks written. */
108 static uintmax_t w_partial = 0;
110 /* Number of full blocks written. */
111 static uintmax_t w_full = 0;
113 /* Number of partial blocks read. */
114 static uintmax_t r_partial = 0;
116 /* Number of full blocks read. */
117 static uintmax_t r_full = 0;
119 /* Records truncated by conv=block. */
120 static uintmax_t r_truncate = 0;
122 /* Output representation of newline and space characters.
123 They change if we're converting to EBCDIC. */
124 static unsigned char newline_character = '\n';
125 static unsigned char space_character = ' ';
127 /* Output buffer. */
128 static unsigned char *obuf;
130 /* Current index into `obuf'. */
131 static size_t oc = 0;
133 /* Index into current line, for `conv=block' and `conv=unblock'. */
134 static size_t col = 0;
136 struct conversion
138 char *convname;
139 int conversion;
142 static struct conversion conversions[] =
144 {"ascii", C_ASCII | C_TWOBUFS}, /* EBCDIC to ASCII. */
145 {"ebcdic", C_EBCDIC | C_TWOBUFS}, /* ASCII to EBCDIC. */
146 {"ibm", C_IBM | C_TWOBUFS}, /* Slightly different ASCII to EBCDIC. */
147 {"block", C_BLOCK | C_TWOBUFS}, /* Variable to fixed length records. */
148 {"unblock", C_UNBLOCK | C_TWOBUFS}, /* Fixed to variable length records. */
149 {"lcase", C_LCASE | C_TWOBUFS}, /* Translate upper to lower case. */
150 {"ucase", C_UCASE | C_TWOBUFS}, /* Translate lower to upper case. */
151 {"swab", C_SWAB | C_TWOBUFS}, /* Swap bytes of input. */
152 {"noerror", C_NOERROR}, /* Ignore i/o errors. */
153 {"notrunc", C_NOTRUNC}, /* Do not truncate output file. */
154 {"sync", C_SYNC}, /* Pad input records to ibs with NULs. */
155 {NULL, 0}
158 /* Translation table formed by applying successive transformations. */
159 static unsigned char trans_table[256];
161 static unsigned char const ascii_to_ebcdic[] =
163 0, 01, 02, 03, 067, 055, 056, 057,
164 026, 05, 045, 013, 014, 015, 016, 017,
165 020, 021, 022, 023, 074, 075, 062, 046,
166 030, 031, 077, 047, 034, 035, 036, 037,
167 0100, 0117, 0177, 0173, 0133, 0154, 0120, 0175,
168 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
169 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
170 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
171 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
172 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
173 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
174 0347, 0350, 0351, 0112, 0340, 0132, 0137, 0155,
175 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
176 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
177 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
178 0247, 0250, 0251, 0300, 0152, 0320, 0241, 07,
179 040, 041, 042, 043, 044, 025, 06, 027,
180 050, 051, 052, 053, 054, 011, 012, 033,
181 060, 061, 032, 063, 064, 065, 066, 010,
182 070, 071, 072, 073, 04, 024, 076, 0341,
183 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
184 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
185 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
186 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
187 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
188 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
189 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
190 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
191 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
192 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
193 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
194 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377
197 static unsigned char const ascii_to_ibm[] =
199 0, 01, 02, 03, 067, 055, 056, 057,
200 026, 05, 045, 013, 014, 015, 016, 017,
201 020, 021, 022, 023, 074, 075, 062, 046,
202 030, 031, 077, 047, 034, 035, 036, 037,
203 0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175,
204 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
205 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
206 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
207 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
208 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
209 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
210 0347, 0350, 0351, 0255, 0340, 0275, 0137, 0155,
211 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
212 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
213 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
214 0247, 0250, 0251, 0300, 0117, 0320, 0241, 07,
215 040, 041, 042, 043, 044, 025, 06, 027,
216 050, 051, 052, 053, 054, 011, 012, 033,
217 060, 061, 032, 063, 064, 065, 066, 010,
218 070, 071, 072, 073, 04, 024, 076, 0341,
219 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
220 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
221 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
222 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
223 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
224 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
225 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
226 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
227 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
228 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
229 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
230 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377
233 static unsigned char const ebcdic_to_ascii[] =
235 0, 01, 02, 03, 0234, 011, 0206, 0177,
236 0227, 0215, 0216, 013, 014, 015, 016, 017,
237 020, 021, 022, 023, 0235, 0205, 010, 0207,
238 030, 031, 0222, 0217, 034, 035, 036, 037,
239 0200, 0201, 0202, 0203, 0204, 012, 027, 033,
240 0210, 0211, 0212, 0213, 0214, 05, 06, 07,
241 0220, 0221, 026, 0223, 0224, 0225, 0226, 04,
242 0230, 0231, 0232, 0233, 024, 025, 0236, 032,
243 040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
244 0247, 0250, 0133, 056, 074, 050, 053, 041,
245 046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
246 0260, 0261, 0135, 044, 052, 051, 073, 0136,
247 055, 057, 0262, 0263, 0264, 0265, 0266, 0267,
248 0270, 0271, 0174, 054, 045, 0137, 076, 077,
249 0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
250 0302, 0140, 072, 043, 0100, 047, 075, 042,
251 0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
252 0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
253 0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
254 0161, 0162, 0313, 0314, 0315, 0316, 0317, 0320,
255 0321, 0176, 0163, 0164, 0165, 0166, 0167, 0170,
256 0171, 0172, 0322, 0323, 0324, 0325, 0326, 0327,
257 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
258 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
259 0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
260 0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
261 0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
262 0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
263 0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
264 0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
265 060, 061, 062, 063, 064, 065, 066, 067,
266 070, 071, 0372, 0373, 0374, 0375, 0376, 0377
269 /* If nonzero, display usage information and exit. */
270 static int show_help;
272 /* If nonzero, print the version on standard output and exit. */
273 static int show_version;
275 static struct option const long_options[] =
277 {"help", no_argument, &show_help, 1},
278 {"version", no_argument, &show_version, 1},
279 {0, 0, 0, 0}
282 void
283 usage (int status)
285 if (status != 0)
286 fprintf (stderr, _("Try `%s --help' for more information.\n"),
287 program_name);
288 else
290 printf (_("Usage: %s [OPTION]...\n"), program_name);
291 printf (_("\
292 Copy a file, converting and formatting according to the options.\n\
294 bs=BYTES force ibs=BYTES and obs=BYTES\n\
295 cbs=BYTES convert BYTES bytes at a time\n\
296 conv=KEYWORDS convert the file as per the comma separated keyword list\n\
297 count=BLOCKS copy only BLOCKS input blocks\n\
298 ibs=BYTES read BYTES bytes at a time\n\
299 if=FILE read from FILE instead of stdin\n\
300 obs=BYTES write BYTES bytes at a time\n\
301 of=FILE write to FILE instead of stdout\n\
302 seek=BLOCKS skip BLOCKS obs-sized blocks at start of output\n\
303 skip=BLOCKS skip BLOCKS ibs-sized blocks at start of input\n\
304 --help display this help and exit\n\
305 --version output version information and exit\n\
307 BYTES may be followed by the following multiplicative suffixes:\n\
308 xM M, c 1, w 2, b 512, kD 1000, k 1024, MD 1,000,000, M 1,048,576,\n\
309 GD 1,000,000,000, G 1,073,741,824, and so on for T, P, E, Z, Y.\n\
310 Each KEYWORD may be:\n\
312 ascii from EBCDIC to ASCII\n\
313 ebcdic from ASCII to EBCDIC\n\
314 ibm from ASCII to alternated EBCDIC\n\
315 block pad newline-terminated records with spaces to cbs-size\n\
316 unblock replace trailing spaces in cbs-size records with newline\n\
317 lcase change upper case to lower case\n\
318 notrunc do not truncate the output file\n\
319 ucase change lower case to upper case\n\
320 swab swap every pair of input bytes\n\
321 noerror continue after read errors\n\
322 sync pad every input block with NULs to ibs-size\n\
323 "));
324 puts (_("\nReport bugs to <bug-fileutils@gnu.org>."));
325 close_stdout ();
327 exit (status);
330 static void
331 translate_charset (const unsigned char *new_trans)
333 int i;
335 for (i = 0; i < 256; i++)
336 trans_table[i] = new_trans[trans_table[i]];
337 translation_needed = 1;
340 /* Return the number of 1 bits in `i'. */
342 static int
343 bit_count (register unsigned int i)
345 register int set_bits;
347 for (set_bits = 0; i != 0; set_bits++)
348 i &= i - 1;
349 return set_bits;
352 static void
353 print_stats (void)
355 char buf[2][LONGEST_HUMAN_READABLE + 1];
356 fprintf (stderr, _("%s+%s records in\n"),
357 human_readable (r_full, buf[0], 1, 1),
358 human_readable (r_partial, buf[1], 1, 1));
359 fprintf (stderr, _("%s+%s records out\n"),
360 human_readable (w_full, buf[0], 1, 1),
361 human_readable (w_partial, buf[1], 1, 1));
362 if (r_truncate > 0)
364 fprintf (stderr, "%s %s\n",
365 human_readable (r_truncate, buf[0], 1, 1),
366 (r_truncate == 1
367 ? _("truncated record")
368 : _("truncated records")));
372 static void
373 cleanup (void)
375 print_stats ();
376 if (close (input_fd) < 0)
377 error (1, errno, "%s", input_file);
378 if (close (output_fd) < 0)
379 error (1, errno, "%s", output_file);
382 static inline void
383 quit (int code)
385 cleanup ();
386 exit (code);
389 static RETSIGTYPE
390 interrupt_handler (int sig)
392 #ifdef SA_INTERRUPT
393 struct sigaction sigact;
395 sigact.sa_handler = SIG_DFL;
396 sigemptyset (&sigact.sa_mask);
397 sigact.sa_flags = 0;
398 sigaction (sig, &sigact, NULL);
399 #else /* !SA_INTERRUPT */
400 signal (sig, SIG_DFL);
401 #endif /* SA_INTERRUPT */
402 cleanup ();
403 kill (getpid (), sig);
406 static RETSIGTYPE
407 siginfo_handler (int sig)
409 print_stats ();
412 /* Encapsulate portability mess of establishing signal handlers. */
414 static void
415 install_handler (int sig_num, RETSIGTYPE (*sig_handler) (int sig))
417 #ifdef _POSIX_VERSION
418 struct sigaction sigact;
419 sigaction (sig_num, NULL, &sigact);
420 if (sigact.sa_handler != SIG_IGN)
422 sigact.sa_handler = sig_handler;
423 sigemptyset (&sigact.sa_mask);
424 sigact.sa_flags = 0;
425 sigaction (sig_num, &sigact, NULL);
427 #else
428 if (signal (sig_num, SIG_IGN) != SIG_IGN)
429 signal (sig_num, sig_handler);
430 #endif
433 /* Write, then empty, the output buffer `obuf'. */
435 static void
436 write_output (void)
438 int nwritten = full_write (output_fd, obuf, output_blocksize);
439 if (nwritten != output_blocksize)
441 error (0, errno, "%s", output_file);
442 if (nwritten > 0)
443 w_partial++;
444 quit (1);
446 else
447 w_full++;
448 oc = 0;
451 /* Interpret one "conv=..." option. */
453 static void
454 parse_conversion (char *str)
456 char *new;
457 int i;
461 new = strchr (str, ',');
462 if (new != NULL)
463 *new++ = '\0';
464 for (i = 0; conversions[i].convname != NULL; i++)
465 if (STREQ (conversions[i].convname, str))
467 conversions_mask |= conversions[i].conversion;
468 break;
470 if (conversions[i].convname == NULL)
472 error (0, 0, _("%s: invalid conversion"), str);
473 usage (1);
475 str = new;
476 } while (new != NULL);
479 /* Return the value of STR, interpreted as a non-negative decimal integer,
480 optionally multiplied by various values.
481 Assign nonzero to *INVALID if STR does not represent a number in
482 this format. */
484 /* FIXME: use xstrtou?[lq] */
486 static uintmax_t
487 parse_integer (char *str, int *invalid)
489 register uintmax_t n = 0;
490 register char *p = str;
492 while (ISDIGIT (*p))
494 uintmax_t n10 = n * 10;
495 int digit = *p - '0';
496 if (! (n10 / 10 == n && n10 <= n10 + digit))
498 *invalid = 1;
499 return 0;
501 n = n10 + digit;
502 p++;
505 for (;;)
507 uintmax_t multiplier;
508 int power = 0;
510 #ifdef lint
511 /* Suppress `used before initialized' warning. */
512 multiplier = 0;
513 #endif
515 switch (*p++)
517 case '\0':
518 return n;
519 case 'b':
520 multiplier = 512;
521 break;
522 case 'c':
523 continue;
524 case 'E': /* Exa */
525 power = 6;
526 break;
527 case 'G': /* Giga */
528 power = 3;
529 break;
530 case 'k': /* kilo */
531 power = 1;
532 break;
533 case 'M': /* Mega */
534 power = 2;
535 break;
536 case 'P': /* Peta */
537 power = 5;
538 break;
539 case 'T': /* Tera */
540 power = 4;
541 break;
542 case 'w':
543 multiplier = 2;
544 break;
545 case 'x':
546 multiplier = parse_integer (p, invalid);
547 p = "";
548 break;
549 case 'Y': /* Yotta */
550 power = 8;
551 break;
552 case 'Z': /* Zetta */
553 power = 7;
554 break;
555 default:
557 *invalid = 1;
558 return 0;
562 if (power)
564 int base = 1024;
566 switch (*p)
568 case 'B': p++; break;
569 case 'D': p++; base = 1000; break;
572 for (multiplier = base; --power; multiplier *= base)
573 if (multiplier * base / base != multiplier)
575 *invalid = 1;
576 return 0;
580 if (multiplier != 0 && n * multiplier / multiplier != n)
582 *invalid = 1;
583 return 0;
586 n *= multiplier;
590 static void
591 scanargs (int argc, char **argv)
593 int i;
594 int c;
596 while ((c = getopt_long (argc, argv, "", long_options, NULL)) != -1)
598 switch (c)
600 case 0:
601 break;
603 default:
604 usage (1);
608 for (i = optind; i < argc; i++)
610 char *name, *val;
612 name = argv[i];
613 val = strchr (name, '=');
614 if (val == NULL)
616 error (0, 0, _("unrecognized option `%s'"), name);
617 usage (1);
619 *val++ = '\0';
621 if (STREQ (name, "if"))
622 input_file = val;
623 else if (STREQ (name, "of"))
624 output_file = val;
625 else if (STREQ (name, "conv"))
626 parse_conversion (val);
627 else
629 int invalid = 0;
630 uintmax_t n = parse_integer (val, &invalid);
632 if (STREQ (name, "ibs"))
634 input_blocksize = n;
635 invalid |= input_blocksize != n || input_blocksize == 0;
636 conversions_mask |= C_TWOBUFS;
638 else if (STREQ (name, "obs"))
640 output_blocksize = n;
641 invalid |= output_blocksize != n || output_blocksize == 0;
642 conversions_mask |= C_TWOBUFS;
644 else if (STREQ (name, "bs"))
646 output_blocksize = input_blocksize = n;
647 invalid |= output_blocksize != n || output_blocksize == 0;
649 else if (STREQ (name, "cbs"))
651 conversion_blocksize = n;
652 invalid |= (conversion_blocksize != n
653 || conversion_blocksize == 0);
655 else if (STREQ (name, "skip"))
656 skip_records = n;
657 else if (STREQ (name, "seek"))
658 seek_record = n;
659 else if (STREQ (name, "count"))
660 max_records = n;
661 else
663 error (0, 0, _("unrecognized option `%s=%s'"), name, val);
664 usage (1);
667 if (invalid)
668 error (1, 0, _("invalid number `%s'"), val);
672 /* If bs= was given, both `input_blocksize' and `output_blocksize' will
673 have been set to positive values. If either has not been set,
674 bs= was not given, so make sure two buffers are used. */
675 if (input_blocksize == 0 || output_blocksize == 0)
676 conversions_mask |= C_TWOBUFS;
677 if (input_blocksize == 0)
678 input_blocksize = DEFAULT_BLOCKSIZE;
679 if (output_blocksize == 0)
680 output_blocksize = DEFAULT_BLOCKSIZE;
681 if (conversion_blocksize == 0)
682 conversions_mask &= ~(C_BLOCK | C_UNBLOCK);
685 /* Fix up translation table. */
687 static void
688 apply_translations (void)
690 int i;
692 #define MX(a) (bit_count (conversions_mask & (a)))
693 if ((MX (C_ASCII | C_EBCDIC | C_IBM) > 1)
694 || (MX (C_BLOCK | C_UNBLOCK) > 1)
695 || (MX (C_LCASE | C_UCASE) > 1)
696 || (MX (C_UNBLOCK | C_SYNC) > 1))
698 error (1, 0, _("\
699 only one conv in {ascii,ebcdic,ibm}, {lcase,ucase}, {block,unblock}, {unblock,sync}"));
701 #undef MX
703 if (conversions_mask & C_ASCII)
704 translate_charset (ebcdic_to_ascii);
706 if (conversions_mask & C_UCASE)
708 for (i = 0; i < 256; i++)
709 if (ISLOWER (trans_table[i]))
710 trans_table[i] = toupper (trans_table[i]);
711 translation_needed = 1;
713 else if (conversions_mask & C_LCASE)
715 for (i = 0; i < 256; i++)
716 if (ISUPPER (trans_table[i]))
717 trans_table[i] = tolower (trans_table[i]);
718 translation_needed = 1;
721 if (conversions_mask & C_EBCDIC)
723 translate_charset (ascii_to_ebcdic);
724 newline_character = ascii_to_ebcdic['\n'];
725 space_character = ascii_to_ebcdic[' '];
727 else if (conversions_mask & C_IBM)
729 translate_charset (ascii_to_ibm);
730 newline_character = ascii_to_ibm['\n'];
731 space_character = ascii_to_ibm[' '];
735 /* Apply the character-set translations specified by the user
736 to the NREAD bytes in BUF. */
738 static void
739 translate_buffer (unsigned char *buf, int nread)
741 register unsigned char *cp;
742 register int i;
744 for (i = nread, cp = buf; i; i--, cp++)
745 *cp = trans_table[*cp];
748 /* If nonnzero, the last char from the previous call to `swab_buffer'
749 is saved in `saved_char'. */
750 static int char_is_saved = 0;
752 /* Odd char from previous call. */
753 static unsigned char saved_char;
755 /* Swap NREAD bytes in BUF, plus possibly an initial char from the
756 previous call. If NREAD is odd, save the last char for the
757 next call. Return the new start of the BUF buffer. */
759 static unsigned char *
760 swab_buffer (unsigned char *buf, int *nread)
762 unsigned char *bufstart = buf;
763 register unsigned char *cp;
764 register int i;
766 /* Is a char left from last time? */
767 if (char_is_saved)
769 *--bufstart = saved_char;
770 (*nread)++;
771 char_is_saved = 0;
774 if (*nread & 1)
776 /* An odd number of chars are in the buffer. */
777 saved_char = bufstart[--*nread];
778 char_is_saved = 1;
781 /* Do the byte-swapping by moving every second character two
782 positions toward the end, working from the end of the buffer
783 toward the beginning. This way we only move half of the data. */
785 cp = bufstart + *nread; /* Start one char past the last. */
786 for (i = *nread / 2; i; i--, cp -= 2)
787 *cp = *(cp - 2);
789 return ++bufstart;
792 /* Throw away RECORDS blocks of BLOCKSIZE bytes on file descriptor FDESC,
793 which is open with read permission for FILE. Store up to BLOCKSIZE
794 bytes of the data at a time in BUF, if necessary. */
796 static void
797 skip (int fdesc, char *file, uintmax_t records, size_t blocksize,
798 unsigned char *buf)
800 struct stat stats;
801 off_t o;
803 /* Use fstat instead of checking for errno == ESPIPE because
804 lseek doesn't work on some special files but doesn't return an
805 error, either. */
806 /* FIXME: can this really happen? What system? */
807 if (fstat (fdesc, &stats))
809 error (0, errno, "%s", file);
810 quit (1);
813 /* Try lseek and if an error indicates it was an inappropriate
814 operation, fall back on using read. */
815 o = records * blocksize;
816 if (o / blocksize != records
817 || lseek (fdesc, o, SEEK_SET) == -1)
819 while (records-- > 0)
821 int nread;
823 nread = safe_read (fdesc, buf, blocksize);
824 if (nread < 0)
826 error (0, errno, "%s", file);
827 quit (1);
829 /* POSIX doesn't say what to do when dd detects it has been
830 asked to skip past EOF, so I assume it's non-fatal.
831 FIXME: maybe give a warning. */
832 if (nread == 0)
833 break;
838 /* Copy NREAD bytes of BUF, with no conversions. */
840 static void
841 copy_simple (unsigned char *buf, int nread)
843 int nfree; /* Number of unused bytes in `obuf'. */
844 unsigned char *start = buf; /* First uncopied char in BUF. */
848 nfree = output_blocksize - oc;
849 if (nfree > nread)
850 nfree = nread;
852 memcpy ((char *) (obuf + oc), (char *) start, nfree);
854 nread -= nfree; /* Update the number of bytes left to copy. */
855 start += nfree;
856 oc += nfree;
857 if (oc >= output_blocksize)
858 write_output ();
860 while (nread > 0);
863 /* Copy NREAD bytes of BUF, doing conv=block
864 (pad newline-terminated records to `conversion_blocksize',
865 replacing the newline with trailing spaces). */
867 static void
868 copy_with_block (unsigned char *buf, int nread)
870 register int i;
872 for (i = nread; i; i--, buf++)
874 if (*buf == newline_character)
876 if (col < conversion_blocksize)
878 size_t j;
879 for (j = col; j < conversion_blocksize; j++)
880 output_char (space_character);
882 col = 0;
884 else
886 if (col == conversion_blocksize)
887 r_truncate++;
888 else if (col < conversion_blocksize)
889 output_char (*buf);
890 col++;
895 /* Copy NREAD bytes of BUF, doing conv=unblock
896 (replace trailing spaces in `conversion_blocksize'-sized records
897 with a newline). */
899 static void
900 copy_with_unblock (unsigned char *buf, int nread)
902 register int i;
903 register unsigned char c;
904 static int pending_spaces = 0;
906 for (i = 0; i < nread; i++)
908 c = buf[i];
910 if (col++ >= conversion_blocksize)
912 col = pending_spaces = 0; /* Wipe out any pending spaces. */
913 i--; /* Push the char back; get it later. */
914 output_char (newline_character);
916 else if (c == space_character)
917 pending_spaces++;
918 else
920 /* `c' is the character after a run of spaces that were not
921 at the end of the conversion buffer. Output them. */
922 while (pending_spaces)
924 output_char (space_character);
925 --pending_spaces;
927 output_char (c);
932 /* The main loop. */
934 static int
935 dd_copy (void)
937 unsigned char *ibuf, *bufstart; /* Input buffer. */
938 int nread; /* Bytes read in the current block. */
939 int exit_status = 0;
941 /* Leave at least one extra byte at the beginning and end of `ibuf'
942 for conv=swab, but keep the buffer address even. But some peculiar
943 device drivers work only with word-aligned buffers, so leave an
944 extra two bytes. */
946 ibuf = (unsigned char *) xmalloc (input_blocksize + 2 * SWAB_ALIGN_OFFSET);
947 ibuf += SWAB_ALIGN_OFFSET;
949 if (conversions_mask & C_TWOBUFS)
950 obuf = (unsigned char *) xmalloc (output_blocksize);
951 else
952 obuf = ibuf;
954 if (skip_records != 0)
955 skip (input_fd, input_file, skip_records, input_blocksize, ibuf);
957 if (seek_record != 0)
959 /* FIXME: this loses for
960 % ./dd if=dd seek=1 |:
961 ./dd: a1 standard output: Bad file number
962 0+0 records in
963 0+0 records out
966 skip (output_fd, output_file, seek_record, output_blocksize, obuf);
969 if (max_records == 0)
970 quit (exit_status);
972 while (1)
974 if (r_partial + r_full >= max_records)
975 break;
977 /* Zero the buffer before reading, so that if we get a read error,
978 whatever data we are able to read is followed by zeros.
979 This minimizes data loss. */
980 if ((conversions_mask & C_SYNC) && (conversions_mask & C_NOERROR))
981 memset ((char *) ibuf, 0, input_blocksize);
983 nread = safe_read (input_fd, ibuf, input_blocksize);
985 if (nread == 0)
986 break; /* EOF. */
988 if (nread < 0)
990 error (0, errno, "%s", input_file);
991 if (conversions_mask & C_NOERROR)
993 print_stats ();
994 /* Seek past the bad block if possible. */
995 lseek (input_fd, (off_t) input_blocksize, SEEK_CUR);
996 if (conversions_mask & C_SYNC)
997 /* Replace the missing input with null bytes and
998 proceed normally. */
999 nread = 0;
1000 else
1001 continue;
1003 else
1005 /* Write any partial block. */
1006 exit_status = 2;
1007 break;
1011 if (nread < input_blocksize)
1013 r_partial++;
1014 if (conversions_mask & C_SYNC)
1016 if (!(conversions_mask & C_NOERROR))
1017 /* If C_NOERROR, we zeroed the block before reading. */
1018 memset ((char *) (ibuf + nread), 0, input_blocksize - nread);
1019 nread = input_blocksize;
1022 else
1023 r_full++;
1025 if (ibuf == obuf) /* If not C_TWOBUFS. */
1027 int nwritten = full_write (output_fd, obuf, nread);
1028 if (nwritten < 0)
1030 error (0, errno, "%s", output_file);
1031 quit (1);
1033 else if (nread == input_blocksize)
1034 w_full++;
1035 else
1036 w_partial++;
1037 continue;
1040 /* Do any translations on the whole buffer at once. */
1042 if (translation_needed)
1043 translate_buffer (ibuf, nread);
1045 if (conversions_mask & C_SWAB)
1046 bufstart = swab_buffer (ibuf, &nread);
1047 else
1048 bufstart = ibuf;
1050 if (conversions_mask & C_BLOCK)
1051 copy_with_block (bufstart, nread);
1052 else if (conversions_mask & C_UNBLOCK)
1053 copy_with_unblock (bufstart, nread);
1054 else
1055 copy_simple (bufstart, nread);
1058 /* If we have a char left as a result of conv=swab, output it. */
1059 if (char_is_saved)
1061 if (conversions_mask & C_BLOCK)
1062 copy_with_block (&saved_char, 1);
1063 else if (conversions_mask & C_UNBLOCK)
1064 copy_with_unblock (&saved_char, 1);
1065 else
1066 output_char (saved_char);
1069 if ((conversions_mask & C_BLOCK) && col > 0)
1071 /* If the final input line didn't end with a '\n', pad
1072 the output block to `conversion_blocksize' chars. */
1073 size_t i;
1074 for (i = col; i < conversion_blocksize; i++)
1075 output_char (space_character);
1078 if ((conversions_mask & C_UNBLOCK) && col == conversion_blocksize)
1079 /* Add a final '\n' if there are exactly `conversion_blocksize'
1080 characters in the final record. */
1081 output_char (newline_character);
1083 /* Write out the last block. */
1084 if (oc != 0)
1086 int nwritten = full_write (output_fd, obuf, oc);
1087 if (nwritten > 0)
1088 w_partial++;
1089 if (nwritten < 0)
1091 error (0, errno, "%s", output_file);
1092 quit (1);
1096 free (ibuf - SWAB_ALIGN_OFFSET);
1097 if (obuf != ibuf)
1098 free (obuf);
1100 return exit_status;
1104 main (int argc, char **argv)
1106 int i;
1107 int exit_status;
1109 program_name = argv[0];
1110 setlocale (LC_ALL, "");
1111 bindtextdomain (PACKAGE, LOCALEDIR);
1112 textdomain (PACKAGE);
1114 /* Initialize translation table to identity translation. */
1115 for (i = 0; i < 256; i++)
1116 trans_table[i] = i;
1118 /* Decode arguments. */
1119 scanargs (argc, argv);
1121 if (show_version)
1123 printf ("dd (%s) %s\n", GNU_PACKAGE, VERSION);
1124 close_stdout ();
1125 exit (0);
1128 if (show_help)
1129 usage (0);
1131 apply_translations ();
1133 if (input_file != NULL)
1135 input_fd = open (input_file, O_RDONLY);
1136 if (input_fd < 0)
1137 error (1, errno, "%s", input_file);
1139 else
1140 input_file = _("standard input");
1142 if (input_fd == output_fd)
1143 error (1, 0, _("%s is closed"), (input_fd == 0
1144 ? _("standard input")
1145 : _("standard output")));
1147 if (output_file != NULL)
1149 int omode = O_RDWR | O_CREAT;
1151 if (seek_record == 0 && !(conversions_mask & C_NOTRUNC))
1152 omode |= O_TRUNC;
1153 output_fd = open (output_file, omode, 0666);
1154 if (output_fd < 0)
1155 error (1, errno, "%s", output_file);
1156 #if HAVE_FTRUNCATE
1157 if (seek_record != 0 && !(conversions_mask & C_NOTRUNC))
1159 off_t o = seek_record * output_blocksize;
1160 if (o / output_blocksize != seek_record)
1161 error (1, 0, _("file offset out of range"));
1162 if (ftruncate (output_fd, o) < 0)
1163 error (0, errno, "%s", output_file);
1165 #endif
1167 else
1169 output_file = _("standard output");
1172 install_handler (SIGINT, interrupt_handler);
1173 install_handler (SIGQUIT, interrupt_handler);
1174 install_handler (SIGPIPE, interrupt_handler);
1175 install_handler (SIGINFO, siginfo_handler);
1177 exit_status = dd_copy ();
1179 quit (exit_status);