(usage): remove spurious trailing \n in puts.
[coreutils.git] / src / dd.c
blob60bfce57638fc587df5e834031cc182e7f530d7c
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)
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 /* 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 "error.h"
68 #define equal(p, q) (strcmp ((p),(q)) == 0)
69 #define max(a, b) ((a) > (b) ? (a) : (b))
70 #define output_char(c) \
71 do { \
72 obuf[oc++] = (c); if (oc >= output_blocksize) write_output (); \
73 } while (0)
75 /* Default input and output blocksize. */
76 #define DEFAULT_BLOCKSIZE 512
78 /* Conversions bit masks. */
79 #define C_ASCII 01
80 #define C_EBCDIC 02
81 #define C_IBM 04
82 #define C_BLOCK 010
83 #define C_UNBLOCK 020
84 #define C_LCASE 040
85 #define C_UCASE 0100
86 #define C_SWAB 0200
87 #define C_NOERROR 0400
88 #define C_NOTRUNC 01000
89 #define C_SYNC 02000
90 /* Use separate input and output buffers, and combine partial input blocks. */
91 #define C_TWOBUFS 04000
93 char *xmalloc ();
94 int safe_read ();
95 int full_write ();
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. */
116 char *program_name;
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 = ' ';
174 struct conversion
176 char *convname;
177 int conversion;
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. */
193 {NULL, 0}
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},
317 {0, 0, 0, 0}
321 main (int argc, char **argv)
323 #ifdef _POSIX_VERSION
324 struct sigaction sigact;
325 #endif /* _POSIX_VERSION */
326 int i;
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++)
335 trans_table[i] = i;
337 /* Decode arguments. */
338 scanargs (argc, argv);
340 if (show_version)
342 printf ("dd - %s\n", PACKAGE_VERSION);
343 exit (0);
346 if (show_help)
347 usage (0);
349 apply_translations ();
351 if (input_file != NULL)
353 input_fd = open (input_file, O_RDONLY);
354 if (input_fd < 0)
355 error (1, errno, "%s", input_file);
357 else
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))
370 omode |= O_TRUNC;
371 output_fd = open (output_file, omode, 0666);
372 if (output_fd < 0)
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);
380 #endif
382 else
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);
391 sigact.sa_flags = 0;
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);
399 sigact.sa_flags = 0;
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 */
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, long int records, long int blocksize,
417 unsigned char *buf)
419 struct stat stats;
421 /* Use fstat instead of checking for errno == ESPIPE because
422 lseek doesn't work on some special files but doesn't return an
423 error, either. */
424 /* FIXME: can this really happen? What system? */
425 if (fstat (fdesc, &stats))
427 error (0, errno, "%s", file);
428 quit (1);
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);
439 quit (1);
442 else
444 while (records-- > 0)
446 int nread;
448 nread = safe_read (fdesc, buf, blocksize);
449 if (nread < 0)
451 error (0, errno, "%s", file);
452 quit (1);
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. */
457 if (nread == 0)
458 break;
463 /* Apply the character-set translations specified by the user
464 to the NREAD bytes in BUF. */
466 static void
467 translate_buffer (unsigned char *buf, int nread)
469 register unsigned char *cp;
470 register int i;
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;
492 register int i;
494 /* Is a char left from last time? */
495 if (char_is_saved)
497 *--bufstart = saved_char;
498 (*nread)++;
499 char_is_saved = 0;
502 if (*nread & 1)
504 /* An odd number of chars are in the buffer. */
505 saved_char = bufstart[--*nread];
506 char_is_saved = 1;
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)
515 *cp = *(cp - 2);
517 return ++bufstart;
520 /* Output buffer. */
521 static unsigned char *obuf;
523 /* Current index into `obuf'. */
524 static int oc = 0;
526 /* Index into current line, for `conv=block' and `conv=unblock'. */
527 static int col = 0;
529 /* The main loop. */
531 static void
532 copy (void)
534 unsigned char *ibuf, *bufstart; /* Input buffer. */
535 int nread; /* Bytes read in the current block. */
536 int exit_status = 0;
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
541 extra two bytes. */
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);
548 else
549 obuf = ibuf;
551 if (skip_records > 0)
552 skip (input_fd, input_file, skip_records, input_blocksize, ibuf);
554 if (seek_record > 0)
555 skip (output_fd, output_file, seek_record, output_blocksize, obuf);
557 if (max_records == 0)
558 quit (exit_status);
560 while (1)
562 if (max_records >= 0 && r_partial + r_full >= max_records)
563 break;
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);
573 if (nread == 0)
574 break; /* EOF. */
576 if (nread < 0)
578 error (0, errno, "%s", input_file);
579 if (conversions_mask & C_NOERROR)
581 print_stats ();
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
586 proceed normally. */
587 nread = 0;
588 else
589 continue;
591 else
593 /* Write any partial block. */
594 exit_status = 2;
595 break;
599 if (nread < input_blocksize)
601 r_partial++;
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;
610 else
611 r_full++;
613 if (ibuf == obuf) /* If not C_TWOBUFS. */
615 int nwritten = full_write (output_fd, obuf, nread);
616 if (nwritten < 0)
618 error (0, errno, "%s", output_file);
619 quit (1);
621 else if (nread == input_blocksize)
622 w_full++;
623 else
624 w_partial++;
625 continue;
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);
635 else
636 bufstart = ibuf;
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);
642 else
643 copy_simple (bufstart, nread);
646 /* If we have a char left as a result of conv=swab, output it. */
647 if (char_is_saved)
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);
653 else
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);
665 --pending_spaces;
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 int pending_spaces = max (0, conversion_blocksize - col);
733 while (pending_spaces)
735 output_char (space_character);
736 --pending_spaces;
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, n;
810 int c;
812 while ((c = getopt_long (argc, argv, "", long_options, (int *) 0)) != EOF)
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 (equal (name, "if"))
838 input_file = val;
839 else if (equal (name, "of"))
840 output_file = val;
841 else if (equal (name, "conv"))
842 parse_conversion (val);
843 else
845 n = parse_integer (val);
846 if (n < 0)
847 error (1, 0, _("invalid number `%s'"), val);
849 if (equal (name, "ibs"))
851 input_blocksize = n;
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"))
864 skip_records = n;
865 else if (equal (name, "seek"))
866 seek_record = n;
867 else if (equal (name, "count"))
868 max_records = n;
869 else
871 error (0, 0, _("unrecognized option `%s=%s'"), name, val);
872 usage (1);
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 */
896 static int
897 parse_integer (char *str)
899 register int n = 0;
900 register int temp;
901 register char *p = str;
903 while (ISDIGIT (*p))
905 n = n * 10 + *p - '0';
906 p++;
908 loop:
909 switch (*p++)
911 case '\0':
912 return n;
913 case 'b':
914 n *= 512;
915 goto loop;
916 case 'c':
917 goto loop;
918 case 'k':
919 n *= 1024;
920 goto loop;
921 case 'w':
922 n *= 2;
923 goto loop;
924 case 'x':
925 temp = parse_integer (p);
926 if (temp == -1)
927 return -1;
928 n *= temp;
929 break;
930 default:
931 return -1;
933 return n;
936 /* Interpret one "conv=..." option. */
938 static void
939 parse_conversion (char *str)
941 char *new;
942 int i;
946 new = strchr (str, ',');
947 if (new != NULL)
948 *new++ = '\0';
949 for (i = 0; conversions[i].convname != NULL; i++)
950 if (equal (conversions[i].convname, str))
952 conversions_mask |= conversions[i].conversion;
953 break;
955 if (conversions[i].convname == NULL)
957 error (0, 0, _("%s: invalid conversion"), str);
958 usage (1);
960 str = new;
961 } while (new != NULL);
964 /* Fix up translation table. */
966 static void
967 apply_translations (void)
969 int i;
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))
977 error (1, 0, _("\
978 only one conv in {ascii,ebcdic,ibm}, {lcase,ucase}, {block,unblock}, {unblock,sync}"));
980 #undef MX
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[' '];
1014 static void
1015 translate_charset (const unsigned char *new_trans)
1017 int i;
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'. */
1026 static int
1027 bit_count (register unsigned int i)
1029 register int set_bits;
1031 for (set_bits = 0; i != 0; set_bits++)
1032 i &= i - 1;
1033 return set_bits;
1036 static void
1037 print_stats (void)
1039 fprintf (stderr, _("%u+%u records in\n"), r_full, r_partial);
1040 fprintf (stderr, _("%u+%u records out\n"), w_full, w_partial);
1041 if (r_truncate > 0)
1042 fprintf (stderr, "%u %s\n", r_truncate,
1043 (r_truncate == 1
1044 ? _("truncated record")
1045 : _("truncated records")));
1048 static void
1049 cleanup (void)
1051 print_stats ();
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);
1058 static void
1059 quit (int code)
1061 cleanup ();
1062 exit (code);
1065 static RETSIGTYPE
1066 interrupt_handler (int sig)
1068 #ifdef SA_INTERRUPT
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 */
1078 cleanup ();
1079 kill (getpid (), sig);
1082 static void
1083 usage (int status)
1085 if (status != 0)
1086 fprintf (stderr, _("Try `%s --help' for more information.\n"),
1087 program_name);
1088 else
1090 printf (_("Usage: %s [OPTION]...\n"), program_name);
1091 printf (_("\
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\
1120 "));
1121 puts (_("\nReport bugs to bug-gnu-utils@gnu.ai.mit.edu"));
1123 exit (status);