60bfce57638fc587df5e834031cc182e7f530d7c
[platform/upstream/coreutils.git] / src / dd.c
1 /* dd -- convert a file while copying it.
2    Copyright (C) 85, 90, 91, 95, 1996 Free Software Foundation, Inc.
3
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.
8
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.
13
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.  */
17
18 /* Written by Paul Rubin, David MacKenzie, and Stuart Kemp. */
19
20 /* Options:
21
22    Numbers can be followed by a multiplier:
23    b=512, c=1, k=1024, w=2, xm=number m
24
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...]
38
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. */
55
56 #include <config.h>
57 #include <stdio.h>
58
59 #define SWAB_ALIGN_OFFSET 2
60
61 #include <sys/types.h>
62 #include <signal.h>
63 #include <getopt.h>
64
65 #include "system.h"
66 #include "error.h"
67
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)
74
75 /* Default input and output blocksize. */
76 #define DEFAULT_BLOCKSIZE 512
77
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
92
93 char *xmalloc ();
94 int safe_read ();
95 int full_write ();
96
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));
114
115 /* The name this program was run with. */
116 char *program_name;
117
118 /* The name of the input file, or NULL for the standard input. */
119 static char *input_file = NULL;
120
121 /* The input file descriptor. */
122 static int input_fd = 0;
123
124 /* The name of the output file, or NULL for the standard output. */
125 static char *output_file = NULL;
126
127 /* The output file descriptor. */
128 static int output_fd = 1;
129
130 /* The number of bytes in which atomic reads are done. */
131 static long input_blocksize = -1;
132
133 /* The number of bytes in which atomic writes are done. */
134 static long output_blocksize = -1;
135
136 /* Conversion buffer size, in bytes.  0 prevents conversions. */
137 static long conversion_blocksize = 0;
138
139 /* Skip this many records of `input_blocksize' bytes before input. */
140 static long skip_records = 0;
141
142 /* Skip this many records of `output_blocksize' bytes before output. */
143 static long seek_record = 0;
144
145 /* Copy only this many records.  <0 means no limit. */
146 static int max_records = -1;
147
148 /* Bit vector of conversions to apply. */
149 static int conversions_mask = 0;
150
151 /* If nonzero, filter characters through the translation table.  */
152 static int translation_needed = 0;
153
154 /* Number of partial blocks written. */
155 static unsigned w_partial = 0;
156
157 /* Number of full blocks written. */
158 static unsigned w_full = 0;
159
160 /* Number of partial blocks read. */
161 static unsigned r_partial = 0;
162
163 /* Number of full blocks read. */
164 static unsigned r_full = 0;
165
166 /* Records truncated by conv=block. */
167 static unsigned r_truncate = 0;
168
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 = ' ';
173
174 struct conversion
175 {
176   char *convname;
177   int conversion;
178 };
179
180 static struct conversion conversions[] =
181 {
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}
194 };
195
196 /* Translation table formed by applying successive transformations. */
197 static unsigned char trans_table[256];
198
199 static unsigned char const ascii_to_ebcdic[] =
200 {
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
233 };
234
235 static unsigned char const ascii_to_ibm[] =
236 {
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
269 };
270
271 static unsigned char const ebcdic_to_ascii[] =
272 {
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
305 };
306
307 /* If nonzero, display usage information and exit.  */
308 static int show_help;
309
310 /* If nonzero, print the version on standard output and exit.  */
311 static int show_version;
312
313 static struct option const long_options[] =
314 {
315   {"help", no_argument, &show_help, 1},
316   {"version", no_argument, &show_version, 1},
317   {0, 0, 0, 0}
318 };
319
320 int
321 main (int argc, char **argv)
322 {
323 #ifdef _POSIX_VERSION
324   struct sigaction sigact;
325 #endif /* _POSIX_VERSION */
326   int i;
327
328   program_name = argv[0];
329   setlocale (LC_ALL, "");
330   bindtextdomain (PACKAGE, LOCALEDIR);
331   textdomain (PACKAGE);
332
333   /* Initialize translation table to identity translation. */
334   for (i = 0; i < 256; i++)
335     trans_table[i] = i;
336
337   /* Decode arguments. */
338   scanargs (argc, argv);
339
340   if (show_version)
341     {
342       printf ("dd - %s\n", PACKAGE_VERSION);
343       exit (0);
344     }
345
346   if (show_help)
347     usage (0);
348
349   apply_translations ();
350
351   if (input_file != NULL)
352     {
353       input_fd = open (input_file, O_RDONLY);
354       if (input_fd < 0)
355         error (1, errno, "%s", input_file);
356     }
357   else
358     input_file = _("standard input");
359
360   if (input_fd == output_fd)
361     error (1, 0, _("%s is closed"), (input_fd == 0
362                                      ? _("standard input")
363                                      : _("standard output")));
364
365   if (output_file != NULL)
366     {
367       int omode = O_RDWR | O_CREAT;
368
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))
376         {
377           if (ftruncate (output_fd, seek_record * output_blocksize) < 0)
378             error (0, errno, "%s", output_file);
379         }
380 #endif
381     }
382   else
383     output_file = _("standard output");
384
385 #ifdef _POSIX_VERSION
386   sigaction (SIGINT, NULL, &sigact);
387   if (sigact.sa_handler != SIG_IGN)
388     {
389       sigact.sa_handler = interrupt_handler;
390       sigemptyset (&sigact.sa_mask);
391       sigact.sa_flags = 0;
392       sigaction (SIGINT, &sigact, NULL);
393     }
394   sigaction (SIGPIPE, NULL, &sigact);
395   if (sigact.sa_handler != SIG_IGN)
396     {
397       sigact.sa_handler = interrupt_handler;
398       sigemptyset (&sigact.sa_mask);
399       sigact.sa_flags = 0;
400       sigaction (SIGPIPE, &sigact, NULL);
401     }
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 ();
409 }
410
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. */
414
415 static void
416 skip (int fdesc, char *file, long int records, long int blocksize,
417       unsigned char *buf)
418 {
419   struct stat stats;
420
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))
426     {
427       error (0, errno, "%s", file);
428       quit (1);
429     }
430
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))
435     {
436       if (lseek (fdesc, records * blocksize, SEEK_SET) < 0)
437         {
438           error (0, errno, "%s", file);
439           quit (1);
440         }
441     }
442   else
443     {
444       while (records-- > 0)
445         {
446           int nread;
447
448           nread = safe_read (fdesc, buf, blocksize);
449           if (nread < 0)
450             {
451               error (0, errno, "%s", file);
452               quit (1);
453             }
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;
459         }
460     }
461 }
462
463 /* Apply the character-set translations specified by the user
464    to the NREAD bytes in BUF.  */
465
466 static void
467 translate_buffer (unsigned char *buf, int nread)
468 {
469   register unsigned char *cp;
470   register int i;
471
472   for (i = nread, cp = buf; i; i--, cp++)
473     *cp = trans_table[*cp];
474 }
475
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;
479
480 /* Odd char from previous call.  */
481 static unsigned char saved_char;
482
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.  */
486
487 static unsigned char *
488 swab_buffer (unsigned char *buf, int *nread)
489 {
490   unsigned char *bufstart = buf;
491   register unsigned char *cp;
492   register int i;
493
494   /* Is a char left from last time?  */
495   if (char_is_saved)
496     {
497       *--bufstart = saved_char;
498       (*nread)++;
499       char_is_saved = 0;
500     }
501
502   if (*nread & 1)
503     {
504       /* An odd number of chars are in the buffer.  */
505       saved_char = bufstart[--*nread];
506       char_is_saved = 1;
507     }
508
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.  */
512
513   cp = bufstart + *nread;       /* Start one char past the last.  */
514   for (i = *nread / 2; i; i--, cp -= 2)
515     *cp = *(cp - 2);
516
517   return ++bufstart;
518 }
519
520 /* Output buffer. */
521 static unsigned char *obuf;
522
523 /* Current index into `obuf'. */
524 static int oc = 0;
525
526 /* Index into current line, for `conv=block' and `conv=unblock'.  */
527 static int col = 0;
528
529 /* The main loop.  */
530
531 static void
532 copy (void)
533 {
534   unsigned char *ibuf, *bufstart; /* Input buffer. */
535   int nread;                    /* Bytes read in the current block. */
536   int exit_status = 0;
537
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.  */
542
543   ibuf = (unsigned char *) xmalloc (input_blocksize + 2 * SWAB_ALIGN_OFFSET);
544   ibuf += SWAB_ALIGN_OFFSET;
545
546   if (conversions_mask & C_TWOBUFS)
547     obuf = (unsigned char *) xmalloc (output_blocksize);
548   else
549     obuf = ibuf;
550
551   if (skip_records > 0)
552     skip (input_fd, input_file, skip_records, input_blocksize, ibuf);
553
554   if (seek_record > 0)
555     skip (output_fd, output_file, seek_record, output_blocksize, obuf);
556
557   if (max_records == 0)
558     quit (exit_status);
559
560   while (1)
561     {
562       if (max_records >= 0 && r_partial + r_full >= max_records)
563         break;
564
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);
570
571       nread = safe_read (input_fd, ibuf, input_blocksize);
572
573       if (nread == 0)
574         break;                  /* EOF.  */
575
576       if (nread < 0)
577         {
578           error (0, errno, "%s", input_file);
579           if (conversions_mask & C_NOERROR)
580             {
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;
590             }
591           else
592             {
593               /* Write any partial block. */
594               exit_status = 2;
595               break;
596             }
597         }
598
599       if (nread < input_blocksize)
600         {
601           r_partial++;
602           if (conversions_mask & C_SYNC)
603             {
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;
608             }
609         }
610       else
611         r_full++;
612
613       if (ibuf == obuf)         /* If not C_TWOBUFS. */
614         {
615           int nwritten = full_write (output_fd, obuf, nread);
616           if (nwritten < 0)
617             {
618               error (0, errno, "%s", output_file);
619               quit (1);
620             }
621           else if (nread == input_blocksize)
622             w_full++;
623           else
624             w_partial++;
625           continue;
626         }
627
628       /* Do any translations on the whole buffer at once.  */
629
630       if (translation_needed)
631         translate_buffer (ibuf, nread);
632
633       if (conversions_mask & C_SWAB)
634         bufstart = swab_buffer (ibuf, &nread);
635       else
636         bufstart = ibuf;
637
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);
644     }
645
646   /* If we have a char left as a result of conv=swab, output it.  */
647   if (char_is_saved)
648     {
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);
655     }
656
657   if ((conversions_mask & C_BLOCK) && col > 0)
658     {
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)
663         {
664           output_char (space_character);
665           --pending_spaces;
666         }
667     }
668
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);
673
674   /* Write out the last block. */
675   if (oc > 0)
676     {
677       int nwritten = full_write (output_fd, obuf, oc);
678       if (nwritten > 0)
679         w_partial++;
680       if (nwritten < 0)
681         {
682           error (0, errno, "%s", output_file);
683           quit (1);
684         }
685     }
686
687   free (ibuf - SWAB_ALIGN_OFFSET);
688   if (obuf != ibuf)
689     free (obuf);
690
691   quit (exit_status);
692 }
693
694 /* Copy NREAD bytes of BUF, with no conversions.  */
695
696 static void
697 copy_simple (unsigned char *buf, int nread)
698 {
699   int nfree;                    /* Number of unused bytes in `obuf'.  */
700   unsigned char *start = buf; /* First uncopied char in BUF.  */
701
702   do
703     {
704       nfree = output_blocksize - oc;
705       if (nfree > nread)
706         nfree = nread;
707
708       memcpy ((char *) (obuf + oc), (char *) start, nfree);
709
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 ();
715     }
716   while (nread > 0);
717 }
718
719 /* Copy NREAD bytes of BUF, doing conv=block
720    (pad newline-terminated records to `conversion_blocksize',
721    replacing the newline with trailing spaces).  */
722
723 static void
724 copy_with_block (unsigned char *buf, int nread)
725 {
726   register int i;
727
728   for (i = nread; i; i--, buf++)
729     {
730       if (*buf == newline_character)
731         {
732           int pending_spaces = max (0, conversion_blocksize - col);
733           while (pending_spaces)
734             {
735               output_char (space_character);
736               --pending_spaces;
737             }
738           col = 0;
739         }
740       else
741         {
742           if (col == conversion_blocksize)
743             r_truncate++;
744           else if (col < conversion_blocksize)
745             output_char (*buf);
746           col++;
747         }
748     }
749 }
750
751 /* Copy NREAD bytes of BUF, doing conv=unblock
752    (replace trailing spaces in `conversion_blocksize'-sized records
753    with a newline).  */
754
755 static void
756 copy_with_unblock (unsigned char *buf, int nread)
757 {
758   register int i;
759   register unsigned char c;
760   static int pending_spaces = 0;
761
762   for (i = 0; i < nread; i++)
763     {
764       c = buf[i];
765
766       if (col++ >= conversion_blocksize)
767         {
768           col = pending_spaces = 0; /* Wipe out any pending spaces.  */
769           i--;                  /* Push the char back; get it later. */
770           output_char (newline_character);
771         }
772       else if (c == space_character)
773         pending_spaces++;
774       else
775         {
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)
779             {
780               output_char (space_character);
781               --pending_spaces;
782             }
783           output_char (c);
784         }
785     }
786 }
787
788 /* Write, then empty, the output buffer `obuf'. */
789
790 static void
791 write_output (void)
792 {
793   int nwritten = full_write (output_fd, obuf, output_blocksize);
794   if (nwritten != output_blocksize)
795     {
796       error (0, errno, "%s", output_file);
797       if (nwritten > 0)
798         w_partial++;
799       quit (1);
800     }
801   else
802     w_full++;
803   oc = 0;
804 }
805
806 static void
807 scanargs (int argc, char **argv)
808 {
809   int i, n;
810   int c;
811
812   while ((c = getopt_long (argc, argv, "", long_options, (int *) 0)) != EOF)
813     {
814       switch (c)
815         {
816         case 0:
817           break;
818
819         default:
820           usage (1);
821         }
822     }
823
824   for (i = optind; i < argc; i++)
825     {
826       char *name, *val;
827
828       name = argv[i];
829       val = strchr (name, '=');
830       if (val == NULL)
831         {
832           error (0, 0, _("unrecognized option `%s'"), name);
833           usage (1);
834         }
835       *val++ = '\0';
836
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
844         {
845           n = parse_integer (val);
846           if (n < 0)
847             error (1, 0, _("invalid number `%s'"), val);
848
849           if (equal (name, "ibs"))
850             {
851               input_blocksize = n;
852               conversions_mask |= C_TWOBUFS;
853             }
854           else if (equal (name, "obs"))
855             {
856               output_blocksize = n;
857               conversions_mask |= C_TWOBUFS;
858             }
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
870             {
871               error (0, 0, _("unrecognized option `%s=%s'"), name, val);
872               usage (1);
873             }
874         }
875     }
876
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);
888 }
889
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. */
893
894 /* FIXME: use xstrtou?l */
895
896 static int
897 parse_integer (char *str)
898 {
899   register int n = 0;
900   register int temp;
901   register char *p = str;
902
903   while (ISDIGIT (*p))
904     {
905       n = n * 10 + *p - '0';
906       p++;
907     }
908 loop:
909   switch (*p++)
910     {
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;
932     }
933   return n;
934 }
935
936 /* Interpret one "conv=..." option. */
937
938 static void
939 parse_conversion (char *str)
940 {
941   char *new;
942   int i;
943
944   do
945     {
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))
951           {
952             conversions_mask |= conversions[i].conversion;
953             break;
954           }
955       if (conversions[i].convname == NULL)
956         {
957           error (0, 0, _("%s: invalid conversion"), str);
958           usage (1);
959         }
960       str = new;
961   } while (new != NULL);
962 }
963
964 /* Fix up translation table. */
965
966 static void
967 apply_translations (void)
968 {
969   int i;
970
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))
976     {
977       error (1, 0, _("\
978 only one conv in {ascii,ebcdic,ibm}, {lcase,ucase}, {block,unblock}, {unblock,sync}"));
979     }
980 #undef MX
981
982   if (conversions_mask & C_ASCII)
983     translate_charset (ebcdic_to_ascii);
984
985   if (conversions_mask & C_UCASE)
986     {
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;
991     }
992   else if (conversions_mask & C_LCASE)
993     {
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;
998     }
999
1000   if (conversions_mask & C_EBCDIC)
1001     {
1002       translate_charset (ascii_to_ebcdic);
1003       newline_character = ascii_to_ebcdic['\n'];
1004       space_character = ascii_to_ebcdic[' '];
1005     }
1006   else if (conversions_mask & C_IBM)
1007     {
1008       translate_charset (ascii_to_ibm);
1009       newline_character = ascii_to_ibm['\n'];
1010       space_character = ascii_to_ibm[' '];
1011     }
1012 }
1013
1014 static void
1015 translate_charset (const unsigned char *new_trans)
1016 {
1017   int i;
1018
1019   for (i = 0; i < 256; i++)
1020     trans_table[i] = new_trans[trans_table[i]];
1021   translation_needed = 1;
1022 }
1023
1024 /* Return the number of 1 bits in `i'. */
1025
1026 static int
1027 bit_count (register unsigned int i)
1028 {
1029   register int set_bits;
1030
1031   for (set_bits = 0; i != 0; set_bits++)
1032     i &= i - 1;
1033   return set_bits;
1034 }
1035
1036 static void
1037 print_stats (void)
1038 {
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")));
1046 }
1047
1048 static void
1049 cleanup (void)
1050 {
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);
1056 }
1057
1058 static void
1059 quit (int code)
1060 {
1061   cleanup ();
1062   exit (code);
1063 }
1064
1065 static RETSIGTYPE
1066 interrupt_handler (int sig)
1067 {
1068 #ifdef SA_INTERRUPT
1069   struct sigaction sigact;
1070
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);
1080 }
1081
1082 static void
1083 usage (int status)
1084 {
1085   if (status != 0)
1086     fprintf (stderr, _("Try `%s --help' for more information.\n"),
1087              program_name);
1088   else
1089     {
1090       printf (_("Usage: %s [OPTION]...\n"), program_name);
1091       printf (_("\
1092 Copy a file, converting and formatting according to the options.\n\
1093 \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\
1106 \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\
1109 \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"));
1122     }
1123   exit (status);
1124 }