.
[coreutils.git] / src / dd.c
blob3c1ff283c7293c08e4b947988fa5f985f6f488e7
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"
37 #ifndef SIGINFO
38 # define SIGINFO SIGUSR1
39 #endif
41 #define max(a, b) ((a) > (b) ? (a) : (b))
42 #define output_char(c) \
43 do { \
44 obuf[oc++] = (c); if (oc >= output_blocksize) write_output (); \
45 } while (0)
47 /* Default input and output blocksize. */
48 #define DEFAULT_BLOCKSIZE 512
50 /* Conversions bit masks. */
51 #define C_ASCII 01
52 #define C_EBCDIC 02
53 #define C_IBM 04
54 #define C_BLOCK 010
55 #define C_UNBLOCK 020
56 #define C_LCASE 040
57 #define C_UCASE 0100
58 #define C_SWAB 0200
59 #define C_NOERROR 0400
60 #define C_NOTRUNC 01000
61 #define C_SYNC 02000
62 /* Use separate input and output buffers, and combine partial input blocks. */
63 #define C_TWOBUFS 04000
65 int safe_read ();
66 int full_write ();
68 static RETSIGTYPE interrupt_handler PARAMS ((int));
69 static int bit_count PARAMS ((register unsigned int i));
70 static uintmax_t parse_integer PARAMS ((char *str, int *));
71 static void apply_translations PARAMS ((void));
72 static void copy PARAMS ((void));
73 static void copy_simple PARAMS ((unsigned char *buf, int nread));
74 static void copy_with_block PARAMS ((unsigned char *buf, int nread));
75 static void copy_with_unblock PARAMS ((unsigned char *buf, int nread));
76 static void parse_conversion PARAMS ((char *str));
77 static void translate_charset PARAMS ((const unsigned char *new_trans));
78 static void quit PARAMS ((int code));
79 static void scanargs PARAMS ((int argc, char **argv));
80 static void skip PARAMS ((int fdesc, char *file, uintmax_t records,
81 size_t blocksize, unsigned char *buf));
82 static void usage PARAMS ((int status));
83 static void write_output PARAMS ((void));
85 /* The name this program was run with. */
86 char *program_name;
88 /* The name of the input file, or NULL for the standard input. */
89 static char *input_file = NULL;
91 /* The input file descriptor. */
92 static int input_fd = 0;
94 /* The name of the output file, or NULL for the standard output. */
95 static char *output_file = NULL;
97 /* The output file descriptor. */
98 static int output_fd = 1;
100 /* The number of bytes in which atomic reads are done. */
101 static size_t input_blocksize = 0;
103 /* The number of bytes in which atomic writes are done. */
104 static size_t output_blocksize = 0;
106 /* Conversion buffer size, in bytes. 0 prevents conversions. */
107 static size_t conversion_blocksize = 0;
109 /* Skip this many records of `input_blocksize' bytes before input. */
110 static uintmax_t skip_records = 0;
112 /* Skip this many records of `output_blocksize' bytes before output. */
113 static uintmax_t seek_record = 0;
115 /* Copy only this many records. The default is effectively infinity. */
116 static uintmax_t max_records = (uintmax_t) -1;
118 /* Bit vector of conversions to apply. */
119 static int conversions_mask = 0;
121 /* If nonzero, filter characters through the translation table. */
122 static int translation_needed = 0;
124 /* Number of partial blocks written. */
125 static uintmax_t w_partial = 0;
127 /* Number of full blocks written. */
128 static uintmax_t w_full = 0;
130 /* Number of partial blocks read. */
131 static uintmax_t r_partial = 0;
133 /* Number of full blocks read. */
134 static uintmax_t r_full = 0;
136 /* Records truncated by conv=block. */
137 static uintmax_t r_truncate = 0;
139 /* Output representation of newline and space characters.
140 They change if we're converting to EBCDIC. */
141 static unsigned char newline_character = '\n';
142 static unsigned char space_character = ' ';
144 struct conversion
146 char *convname;
147 int conversion;
150 static struct conversion conversions[] =
152 {"ascii", C_ASCII | C_TWOBUFS}, /* EBCDIC to ASCII. */
153 {"ebcdic", C_EBCDIC | C_TWOBUFS}, /* ASCII to EBCDIC. */
154 {"ibm", C_IBM | C_TWOBUFS}, /* Slightly different ASCII to EBCDIC. */
155 {"block", C_BLOCK | C_TWOBUFS}, /* Variable to fixed length records. */
156 {"unblock", C_UNBLOCK | C_TWOBUFS}, /* Fixed to variable length records. */
157 {"lcase", C_LCASE | C_TWOBUFS}, /* Translate upper to lower case. */
158 {"ucase", C_UCASE | C_TWOBUFS}, /* Translate lower to upper case. */
159 {"swab", C_SWAB | C_TWOBUFS}, /* Swap bytes of input. */
160 {"noerror", C_NOERROR}, /* Ignore i/o errors. */
161 {"notrunc", C_NOTRUNC}, /* Do not truncate output file. */
162 {"sync", C_SYNC}, /* Pad input records to ibs with NULs. */
163 {NULL, 0}
166 /* Translation table formed by applying successive transformations. */
167 static unsigned char trans_table[256];
169 static unsigned char const ascii_to_ebcdic[] =
171 0, 01, 02, 03, 067, 055, 056, 057,
172 026, 05, 045, 013, 014, 015, 016, 017,
173 020, 021, 022, 023, 074, 075, 062, 046,
174 030, 031, 077, 047, 034, 035, 036, 037,
175 0100, 0117, 0177, 0173, 0133, 0154, 0120, 0175,
176 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
177 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
178 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
179 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
180 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
181 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
182 0347, 0350, 0351, 0112, 0340, 0132, 0137, 0155,
183 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
184 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
185 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
186 0247, 0250, 0251, 0300, 0152, 0320, 0241, 07,
187 040, 041, 042, 043, 044, 025, 06, 027,
188 050, 051, 052, 053, 054, 011, 012, 033,
189 060, 061, 032, 063, 064, 065, 066, 010,
190 070, 071, 072, 073, 04, 024, 076, 0341,
191 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
192 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
193 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
194 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
195 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
196 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
197 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
198 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
199 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
200 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
201 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
202 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377
205 static unsigned char const ascii_to_ibm[] =
207 0, 01, 02, 03, 067, 055, 056, 057,
208 026, 05, 045, 013, 014, 015, 016, 017,
209 020, 021, 022, 023, 074, 075, 062, 046,
210 030, 031, 077, 047, 034, 035, 036, 037,
211 0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175,
212 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
213 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
214 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
215 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
216 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
217 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
218 0347, 0350, 0351, 0255, 0340, 0275, 0137, 0155,
219 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
220 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
221 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
222 0247, 0250, 0251, 0300, 0117, 0320, 0241, 07,
223 040, 041, 042, 043, 044, 025, 06, 027,
224 050, 051, 052, 053, 054, 011, 012, 033,
225 060, 061, 032, 063, 064, 065, 066, 010,
226 070, 071, 072, 073, 04, 024, 076, 0341,
227 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
228 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
229 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
230 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
231 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
232 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
233 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
234 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
235 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
236 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
237 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
238 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377
241 static unsigned char const ebcdic_to_ascii[] =
243 0, 01, 02, 03, 0234, 011, 0206, 0177,
244 0227, 0215, 0216, 013, 014, 015, 016, 017,
245 020, 021, 022, 023, 0235, 0205, 010, 0207,
246 030, 031, 0222, 0217, 034, 035, 036, 037,
247 0200, 0201, 0202, 0203, 0204, 012, 027, 033,
248 0210, 0211, 0212, 0213, 0214, 05, 06, 07,
249 0220, 0221, 026, 0223, 0224, 0225, 0226, 04,
250 0230, 0231, 0232, 0233, 024, 025, 0236, 032,
251 040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
252 0247, 0250, 0133, 056, 074, 050, 053, 041,
253 046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
254 0260, 0261, 0135, 044, 052, 051, 073, 0136,
255 055, 057, 0262, 0263, 0264, 0265, 0266, 0267,
256 0270, 0271, 0174, 054, 045, 0137, 076, 077,
257 0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
258 0302, 0140, 072, 043, 0100, 047, 075, 042,
259 0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
260 0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
261 0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
262 0161, 0162, 0313, 0314, 0315, 0316, 0317, 0320,
263 0321, 0176, 0163, 0164, 0165, 0166, 0167, 0170,
264 0171, 0172, 0322, 0323, 0324, 0325, 0326, 0327,
265 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
266 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
267 0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
268 0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
269 0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
270 0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
271 0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
272 0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
273 060, 061, 062, 063, 064, 065, 066, 067,
274 070, 071, 0372, 0373, 0374, 0375, 0376, 0377
277 /* If nonzero, display usage information and exit. */
278 static int show_help;
280 /* If nonzero, print the version on standard output and exit. */
281 static int show_version;
283 static struct option const long_options[] =
285 {"help", no_argument, &show_help, 1},
286 {"version", no_argument, &show_version, 1},
287 {0, 0, 0, 0}
290 static void
291 print_stats (void)
293 char buf[2][LONGEST_HUMAN_READABLE + 1];
294 fprintf (stderr, _("%s+%s records in\n"),
295 human_readable (r_full, buf[0], 1, 1, 0),
296 human_readable (r_partial, buf[1], 1, 1, 0));
297 fprintf (stderr, _("%s+%s records out\n"),
298 human_readable (w_full, buf[0], 1, 1, 0),
299 human_readable (w_partial, buf[1], 1, 1, 0));
300 if (r_truncate > 0)
301 fprintf (stderr, "%s %s\n",
302 human_readable (r_truncate, buf[0], 1, 1, 0),
303 (r_truncate == 1
304 ? _("truncated record")
305 : _("truncated records")));
308 static RETSIGTYPE
309 siginfo_handler (int sig)
311 print_stats ();
314 /* Encapsulate portability mess of establishing signal handlers. */
316 static void
317 install_handler (int sig_num, RETSIGTYPE (*sig_handler) (int sig))
319 #ifdef _POSIX_VERSION
320 struct sigaction sigact;
321 sigaction (sig_num, NULL, &sigact);
322 if (sigact.sa_handler != SIG_IGN)
324 sigact.sa_handler = sig_handler;
325 sigemptyset (&sigact.sa_mask);
326 sigact.sa_flags = 0;
327 sigaction (sig_num, &sigact, NULL);
329 #else
330 if (signal (sig_num, SIG_IGN) != SIG_IGN)
331 signal (sig_num, sig_handler);
332 #endif
336 main (int argc, char **argv)
338 int i;
340 program_name = argv[0];
341 setlocale (LC_ALL, "");
342 bindtextdomain (PACKAGE, LOCALEDIR);
343 textdomain (PACKAGE);
345 /* Initialize translation table to identity translation. */
346 for (i = 0; i < 256; i++)
347 trans_table[i] = i;
349 /* Decode arguments. */
350 scanargs (argc, argv);
352 if (show_version)
354 printf ("dd (%s) %s\n", GNU_PACKAGE, VERSION);
355 close_stdout ();
356 exit (0);
359 if (show_help)
360 usage (0);
362 apply_translations ();
364 if (input_file != NULL)
366 input_fd = open (input_file, O_RDONLY);
367 if (input_fd < 0)
368 error (1, errno, "%s", input_file);
370 else
371 input_file = _("standard input");
373 if (input_fd == output_fd)
374 error (1, 0, _("%s is closed"), (input_fd == 0
375 ? _("standard input")
376 : _("standard output")));
378 if (output_file != NULL)
380 int omode = O_RDWR | O_CREAT;
382 if (seek_record == 0 && !(conversions_mask & C_NOTRUNC))
383 omode |= O_TRUNC;
384 output_fd = open (output_file, omode, 0666);
385 if (output_fd < 0)
386 error (1, errno, "%s", output_file);
387 #ifdef HAVE_FTRUNCATE
388 if (seek_record != 0 && !(conversions_mask & C_NOTRUNC))
390 off_t o = seek_record * output_blocksize;
391 if (o / output_blocksize != seek_record)
392 error (1, 0, _("file offset out of range"));
393 if (ftruncate (output_fd, o) < 0)
394 error (0, errno, "%s", output_file);
396 #endif
398 else
400 output_file = _("standard output");
403 install_handler (SIGINT, interrupt_handler);
404 install_handler (SIGQUIT, interrupt_handler);
405 install_handler (SIGPIPE, interrupt_handler);
406 install_handler (SIGINFO, siginfo_handler);
408 copy ();
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. */
415 static void
416 skip (int fdesc, char *file, uintmax_t records, size_t blocksize,
417 unsigned char *buf)
419 struct stat stats;
420 off_t o;
422 /* Use fstat instead of checking for errno == ESPIPE because
423 lseek doesn't work on some special files but doesn't return an
424 error, either. */
425 /* FIXME: can this really happen? What system? */
426 if (fstat (fdesc, &stats))
428 error (0, errno, "%s", file);
429 quit (1);
432 /* Try lseek and if an error indicates it was an inappropriate
433 operation, fall back on using read. */
434 o = records * blocksize;
435 if (o / blocksize != records
436 || lseek (fdesc, o, SEEK_SET) == -1)
438 while (records-- > 0)
440 int nread;
442 nread = safe_read (fdesc, buf, blocksize);
443 if (nread < 0)
445 error (0, errno, "%s", file);
446 quit (1);
448 /* POSIX doesn't say what to do when dd detects it has been
449 asked to skip past EOF, so I assume it's non-fatal.
450 FIXME: maybe give a warning. */
451 if (nread == 0)
452 break;
457 /* Apply the character-set translations specified by the user
458 to the NREAD bytes in BUF. */
460 static void
461 translate_buffer (unsigned char *buf, int nread)
463 register unsigned char *cp;
464 register int i;
466 for (i = nread, cp = buf; i; i--, cp++)
467 *cp = trans_table[*cp];
470 /* If nonnzero, the last char from the previous call to `swab_buffer'
471 is saved in `saved_char'. */
472 static int char_is_saved = 0;
474 /* Odd char from previous call. */
475 static unsigned char saved_char;
477 /* Swap NREAD bytes in BUF, plus possibly an initial char from the
478 previous call. If NREAD is odd, save the last char for the
479 next call. Return the new start of the BUF buffer. */
481 static unsigned char *
482 swab_buffer (unsigned char *buf, int *nread)
484 unsigned char *bufstart = buf;
485 register unsigned char *cp;
486 register int i;
488 /* Is a char left from last time? */
489 if (char_is_saved)
491 *--bufstart = saved_char;
492 (*nread)++;
493 char_is_saved = 0;
496 if (*nread & 1)
498 /* An odd number of chars are in the buffer. */
499 saved_char = bufstart[--*nread];
500 char_is_saved = 1;
503 /* Do the byte-swapping by moving every second character two
504 positions toward the end, working from the end of the buffer
505 toward the beginning. This way we only move half of the data. */
507 cp = bufstart + *nread; /* Start one char past the last. */
508 for (i = *nread / 2; i; i--, cp -= 2)
509 *cp = *(cp - 2);
511 return ++bufstart;
514 /* Output buffer. */
515 static unsigned char *obuf;
517 /* Current index into `obuf'. */
518 static size_t oc = 0;
520 /* Index into current line, for `conv=block' and `conv=unblock'. */
521 static size_t col = 0;
523 /* The main loop. */
525 static void
526 copy (void)
528 unsigned char *ibuf, *bufstart; /* Input buffer. */
529 int nread; /* Bytes read in the current block. */
530 int exit_status = 0;
532 /* Leave at least one extra byte at the beginning and end of `ibuf'
533 for conv=swab, but keep the buffer address even. But some peculiar
534 device drivers work only with word-aligned buffers, so leave an
535 extra two bytes. */
537 ibuf = (unsigned char *) xmalloc (input_blocksize + 2 * SWAB_ALIGN_OFFSET);
538 ibuf += SWAB_ALIGN_OFFSET;
540 if (conversions_mask & C_TWOBUFS)
541 obuf = (unsigned char *) xmalloc (output_blocksize);
542 else
543 obuf = ibuf;
545 if (skip_records != 0)
546 skip (input_fd, input_file, skip_records, input_blocksize, ibuf);
548 if (seek_record != 0)
550 /* FIXME: this loses for
551 % ./dd if=dd seek=1 |:
552 ./dd: a1 standard output: Bad file number
553 0+0 records in
554 0+0 records out
557 skip (output_fd, output_file, seek_record, output_blocksize, obuf);
560 if (max_records == 0)
561 quit (exit_status);
563 while (1)
565 if (r_partial + r_full >= max_records)
566 break;
568 /* Zero the buffer before reading, so that if we get a read error,
569 whatever data we are able to read is followed by zeros.
570 This minimizes data loss. */
571 if ((conversions_mask & C_SYNC) && (conversions_mask & C_NOERROR))
572 memset ((char *) ibuf, 0, input_blocksize);
574 nread = safe_read (input_fd, ibuf, input_blocksize);
576 if (nread == 0)
577 break; /* EOF. */
579 if (nread < 0)
581 error (0, errno, "%s", input_file);
582 if (conversions_mask & C_NOERROR)
584 print_stats ();
585 /* Seek past the bad block if possible. */
586 lseek (input_fd, (off_t) input_blocksize, SEEK_CUR);
587 if (conversions_mask & C_SYNC)
588 /* Replace the missing input with null bytes and
589 proceed normally. */
590 nread = 0;
591 else
592 continue;
594 else
596 /* Write any partial block. */
597 exit_status = 2;
598 break;
602 if (nread < input_blocksize)
604 r_partial++;
605 if (conversions_mask & C_SYNC)
607 if (!(conversions_mask & C_NOERROR))
608 /* If C_NOERROR, we zeroed the block before reading. */
609 memset ((char *) (ibuf + nread), 0, input_blocksize - nread);
610 nread = input_blocksize;
613 else
614 r_full++;
616 if (ibuf == obuf) /* If not C_TWOBUFS. */
618 int nwritten = full_write (output_fd, obuf, nread);
619 if (nwritten < 0)
621 error (0, errno, "%s", output_file);
622 quit (1);
624 else if (nread == input_blocksize)
625 w_full++;
626 else
627 w_partial++;
628 continue;
631 /* Do any translations on the whole buffer at once. */
633 if (translation_needed)
634 translate_buffer (ibuf, nread);
636 if (conversions_mask & C_SWAB)
637 bufstart = swab_buffer (ibuf, &nread);
638 else
639 bufstart = ibuf;
641 if (conversions_mask & C_BLOCK)
642 copy_with_block (bufstart, nread);
643 else if (conversions_mask & C_UNBLOCK)
644 copy_with_unblock (bufstart, nread);
645 else
646 copy_simple (bufstart, nread);
649 /* If we have a char left as a result of conv=swab, output it. */
650 if (char_is_saved)
652 if (conversions_mask & C_BLOCK)
653 copy_with_block (&saved_char, 1);
654 else if (conversions_mask & C_UNBLOCK)
655 copy_with_unblock (&saved_char, 1);
656 else
657 output_char (saved_char);
660 if ((conversions_mask & C_BLOCK) && col > 0)
662 /* If the final input line didn't end with a '\n', pad
663 the output block to `conversion_blocksize' chars. */
664 size_t i;
665 for (i = col; i < conversion_blocksize; i++)
666 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. */
675 if (oc != 0)
677 int nwritten = full_write (output_fd, obuf, oc);
678 if (nwritten > 0)
679 w_partial++;
680 if (nwritten < 0)
682 error (0, errno, "%s", output_file);
683 quit (1);
687 free (ibuf - SWAB_ALIGN_OFFSET);
688 if (obuf != ibuf)
689 free (obuf);
691 quit (exit_status);
694 /* Copy NREAD bytes of BUF, with no conversions. */
696 static void
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;
705 if (nfree > nread)
706 nfree = nread;
708 memcpy ((char *) (obuf + oc), (char *) start, nfree);
710 nread -= nfree; /* Update the number of bytes left to copy. */
711 start += nfree;
712 oc += nfree;
713 if (oc >= output_blocksize)
714 write_output ();
716 while (nread > 0);
719 /* Copy NREAD bytes of BUF, doing conv=block
720 (pad newline-terminated records to `conversion_blocksize',
721 replacing the newline with trailing spaces). */
723 static void
724 copy_with_block (unsigned char *buf, int nread)
726 register int i;
728 for (i = nread; i; i--, buf++)
730 if (*buf == newline_character)
732 if (col < conversion_blocksize)
734 size_t j;
735 for (j = col; j < conversion_blocksize; j++)
736 output_char (space_character);
738 col = 0;
740 else
742 if (col == conversion_blocksize)
743 r_truncate++;
744 else if (col < conversion_blocksize)
745 output_char (*buf);
746 col++;
751 /* Copy NREAD bytes of BUF, doing conv=unblock
752 (replace trailing spaces in `conversion_blocksize'-sized records
753 with a newline). */
755 static void
756 copy_with_unblock (unsigned char *buf, int nread)
758 register int i;
759 register unsigned char c;
760 static int pending_spaces = 0;
762 for (i = 0; i < nread; i++)
764 c = buf[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)
773 pending_spaces++;
774 else
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);
781 --pending_spaces;
783 output_char (c);
788 /* Write, then empty, the output buffer `obuf'. */
790 static void
791 write_output (void)
793 int nwritten = full_write (output_fd, obuf, output_blocksize);
794 if (nwritten != output_blocksize)
796 error (0, errno, "%s", output_file);
797 if (nwritten > 0)
798 w_partial++;
799 quit (1);
801 else
802 w_full++;
803 oc = 0;
806 static void
807 scanargs (int argc, char **argv)
809 int i;
810 int c;
812 while ((c = getopt_long (argc, argv, "", long_options, NULL)) != -1)
814 switch (c)
816 case 0:
817 break;
819 default:
820 usage (1);
824 for (i = optind; i < argc; i++)
826 char *name, *val;
828 name = argv[i];
829 val = strchr (name, '=');
830 if (val == NULL)
832 error (0, 0, _("unrecognized option `%s'"), name);
833 usage (1);
835 *val++ = '\0';
837 if (STREQ (name, "if"))
838 input_file = val;
839 else if (STREQ (name, "of"))
840 output_file = val;
841 else if (STREQ (name, "conv"))
842 parse_conversion (val);
843 else
845 int invalid = 0;
846 uintmax_t n = parse_integer (val, &invalid);
848 if (STREQ (name, "ibs"))
850 input_blocksize = n;
851 invalid |= input_blocksize != n || input_blocksize == 0;
852 conversions_mask |= C_TWOBUFS;
854 else if (STREQ (name, "obs"))
856 output_blocksize = n;
857 invalid |= output_blocksize != n || output_blocksize == 0;
858 conversions_mask |= C_TWOBUFS;
860 else if (STREQ (name, "bs"))
862 output_blocksize = input_blocksize = n;
863 invalid |= output_blocksize != n || output_blocksize == 0;
865 else if (STREQ (name, "cbs"))
867 conversion_blocksize = n;
868 invalid |= (conversion_blocksize != n
869 || conversion_blocksize == 0);
871 else if (STREQ (name, "skip"))
872 skip_records = n;
873 else if (STREQ (name, "seek"))
874 seek_record = n;
875 else if (STREQ (name, "count"))
876 max_records = n;
877 else
879 error (0, 0, _("unrecognized option `%s=%s'"), name, val);
880 usage (1);
883 if (invalid)
884 error (1, 0, _("invalid number `%s'"), val);
888 /* If bs= was given, both `input_blocksize' and `output_blocksize' will
889 have been set to positive values. If either has not been set,
890 bs= was not given, so make sure two buffers are used. */
891 if (input_blocksize == 0 || output_blocksize == 0)
892 conversions_mask |= C_TWOBUFS;
893 if (input_blocksize == 0)
894 input_blocksize = DEFAULT_BLOCKSIZE;
895 if (output_blocksize == 0)
896 output_blocksize = DEFAULT_BLOCKSIZE;
897 if (conversion_blocksize == 0)
898 conversions_mask &= ~(C_BLOCK | C_UNBLOCK);
901 /* Return the value of STR, interpreted as a non-negative decimal integer,
902 optionally multiplied by various values.
903 Assign nonzero to *INVALID if STR does not represent a number in
904 this format. */
906 /* FIXME: use xstrtou?[lq] */
908 static uintmax_t
909 parse_integer (char *str, int *invalid)
911 register uintmax_t n = 0;
912 register char *p = str;
914 while (ISDIGIT (*p))
916 uintmax_t n10 = n * 10;
917 int digit = *p - '0';
918 if (! (n10 / 10 == n && n10 <= n10 + digit))
920 *invalid = 1;
921 return 0;
923 n = n10 + digit;
924 p++;
927 for (;;)
929 uintmax_t multiplier;
931 switch (*p++)
933 case '\0':
934 return n;
935 case 'b':
936 multiplier = 512;
937 break;
938 case 'c':
939 continue;
940 case 'k':
941 multiplier = 1024;
942 break;
943 case 'w':
944 multiplier = 2;
945 break;
946 case 'x':
947 multiplier = parse_integer (p, invalid);
948 p = "";
949 break;
950 default:
952 *invalid = 1;
953 return 0;
957 if (multiplier != 0 && n * multiplier / multiplier != n)
959 *invalid = 1;
960 return 0;
963 n *= multiplier;
967 /* Interpret one "conv=..." option. */
969 static void
970 parse_conversion (char *str)
972 char *new;
973 int i;
977 new = strchr (str, ',');
978 if (new != NULL)
979 *new++ = '\0';
980 for (i = 0; conversions[i].convname != NULL; i++)
981 if (STREQ (conversions[i].convname, str))
983 conversions_mask |= conversions[i].conversion;
984 break;
986 if (conversions[i].convname == NULL)
988 error (0, 0, _("%s: invalid conversion"), str);
989 usage (1);
991 str = new;
992 } while (new != NULL);
995 /* Fix up translation table. */
997 static void
998 apply_translations (void)
1000 int i;
1002 #define MX(a) (bit_count (conversions_mask & (a)))
1003 if ((MX (C_ASCII | C_EBCDIC | C_IBM) > 1)
1004 || (MX (C_BLOCK | C_UNBLOCK) > 1)
1005 || (MX (C_LCASE | C_UCASE) > 1)
1006 || (MX (C_UNBLOCK | C_SYNC) > 1))
1008 error (1, 0, _("\
1009 only one conv in {ascii,ebcdic,ibm}, {lcase,ucase}, {block,unblock}, {unblock,sync}"));
1011 #undef MX
1013 if (conversions_mask & C_ASCII)
1014 translate_charset (ebcdic_to_ascii);
1016 if (conversions_mask & C_UCASE)
1018 for (i = 0; i < 256; i++)
1019 if (ISLOWER (trans_table[i]))
1020 trans_table[i] = toupper (trans_table[i]);
1021 translation_needed = 1;
1023 else if (conversions_mask & C_LCASE)
1025 for (i = 0; i < 256; i++)
1026 if (ISUPPER (trans_table[i]))
1027 trans_table[i] = tolower (trans_table[i]);
1028 translation_needed = 1;
1031 if (conversions_mask & C_EBCDIC)
1033 translate_charset (ascii_to_ebcdic);
1034 newline_character = ascii_to_ebcdic['\n'];
1035 space_character = ascii_to_ebcdic[' '];
1037 else if (conversions_mask & C_IBM)
1039 translate_charset (ascii_to_ibm);
1040 newline_character = ascii_to_ibm['\n'];
1041 space_character = ascii_to_ibm[' '];
1045 static void
1046 translate_charset (const unsigned char *new_trans)
1048 int i;
1050 for (i = 0; i < 256; i++)
1051 trans_table[i] = new_trans[trans_table[i]];
1052 translation_needed = 1;
1055 /* Return the number of 1 bits in `i'. */
1057 static int
1058 bit_count (register unsigned int i)
1060 register int set_bits;
1062 for (set_bits = 0; i != 0; set_bits++)
1063 i &= i - 1;
1064 return set_bits;
1067 static void
1068 cleanup (void)
1070 print_stats ();
1071 if (close (input_fd) < 0)
1072 error (1, errno, "%s", input_file);
1073 if (close (output_fd) < 0)
1074 error (1, errno, "%s", output_file);
1077 static void
1078 quit (int code)
1080 cleanup ();
1081 exit (code);
1084 static RETSIGTYPE
1085 interrupt_handler (int sig)
1087 #ifdef SA_INTERRUPT
1088 struct sigaction sigact;
1090 sigact.sa_handler = SIG_DFL;
1091 sigemptyset (&sigact.sa_mask);
1092 sigact.sa_flags = 0;
1093 sigaction (sig, &sigact, NULL);
1094 #else /* !SA_INTERRUPT */
1095 signal (sig, SIG_DFL);
1096 #endif /* SA_INTERRUPT */
1097 cleanup ();
1098 kill (getpid (), sig);
1101 static void
1102 usage (int status)
1104 if (status != 0)
1105 fprintf (stderr, _("Try `%s --help' for more information.\n"),
1106 program_name);
1107 else
1109 printf (_("Usage: %s [OPTION]...\n"), program_name);
1110 printf (_("\
1111 Copy a file, converting and formatting according to the options.\n\
1113 bs=BYTES force ibs=BYTES and obs=BYTES\n\
1114 cbs=BYTES convert BYTES bytes at a time\n\
1115 conv=KEYWORDS convert the file as per the comma separated keyword list\n\
1116 count=BLOCKS copy only BLOCKS input blocks\n\
1117 ibs=BYTES read BYTES bytes at a time\n\
1118 if=FILE read from FILE instead of stdin\n\
1119 obs=BYTES write BYTES bytes at a time\n\
1120 of=FILE write to FILE instead of stdout\n\
1121 seek=BLOCKS skip BLOCKS obs-sized blocks at start of output\n\
1122 skip=BLOCKS skip BLOCKS ibs-sized blocks at start of input\n\
1123 --help display this help and exit\n\
1124 --version output version information and exit\n\
1126 BYTES may be suffixed: by xM for multiplication by M, by c for x1,\n\
1127 by w for x2, by b for x512, by k for x1024. Each KEYWORD may be:\n\
1129 ascii from EBCDIC to ASCII\n\
1130 ebcdic from ASCII to EBCDIC\n\
1131 ibm from ASCII to alternated EBCDIC\n\
1132 block pad newline-terminated records with spaces to cbs-size\n\
1133 unblock replace trailing spaces in cbs-size records with newline\n\
1134 lcase change upper case to lower case\n\
1135 notrunc do not truncate the output file\n\
1136 ucase change lower case to upper case\n\
1137 swab swap every pair of input bytes\n\
1138 noerror continue after read errors\n\
1139 sync pad every input block with NULs to ibs-size\n\
1140 "));
1141 puts (_("\nReport bugs to <fileutils-bugs@gnu.org>."));
1142 close_stdout ();
1144 exit (status);