(add_tabstop): Give correct size when reallocating tab_list buffer.
[platform/upstream/coreutils.git] / src / dd.c
1 /* dd -- convert a file while copying it.
2    Copyright (C) 1985, 1990, 1991, 1995 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
16    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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 "version.h"
67 #include "error.h"
68
69 #define equal(p, q) (strcmp ((p),(q)) == 0)
70 #define max(a, b) ((a) > (b) ? (a) : (b))
71 #define output_char(c) \
72   do { \
73   obuf[oc++] = (c); if (oc >= output_blocksize) write_output (); \
74   } while (0)
75
76 /* Default input and output blocksize. */
77 #define DEFAULT_BLOCKSIZE 512
78
79 /* Conversions bit masks. */
80 #define C_ASCII 01
81 #define C_EBCDIC 02
82 #define C_IBM 04
83 #define C_BLOCK 010
84 #define C_UNBLOCK 020
85 #define C_LCASE 040
86 #define C_UCASE 0100
87 #define C_SWAB 0200
88 #define C_NOERROR 0400
89 #define C_NOTRUNC 01000
90 #define C_SYNC 02000
91 /* Use separate input and output buffers, and combine partial input blocks. */
92 #define C_TWOBUFS 04000
93
94 char *xmalloc ();
95 int safe_read ();
96 int full_write ();
97
98 static RETSIGTYPE interrupt_handler ();
99 static int bit_count ();
100 static int parse_integer ();
101 static void apply_translations ();
102 static void copy ();
103 static void copy_simple ();
104 static void copy_with_block ();
105 static void copy_with_unblock ();
106 static void parse_conversion ();
107 static void print_stats ();
108 static void translate_charset ();
109 static void quit ();
110 static void scanargs ();
111 static void skip ();
112 static void usage ();
113 static void write_output ();
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 non-zero, display usage information and exit.  */
308 static int show_help;
309
310 /* If non-zero, 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 void
321 main (argc, argv)
322      int argc;
323      char **argv;
324 {
325 #ifdef _POSIX_VERSION
326   struct sigaction sigact;
327 #endif /* _POSIX_VERSION */
328   int i;
329
330   program_name = argv[0];
331
332   /* Initialize translation table to identity translation. */
333   for (i = 0; i < 256; i++)
334     trans_table[i] = i;
335
336   /* Decode arguments. */
337   scanargs (argc, argv);
338
339   if (show_version)
340     {
341       printf ("%s\n", version_string);
342       exit (0);
343     }
344
345   if (show_help)
346     usage (0);
347
348   apply_translations ();
349
350   if (input_file != NULL)
351     {
352       input_fd = open (input_file, O_RDONLY);
353       if (input_fd < 0)
354         error (1, errno, "%s", input_file);
355     }
356   else
357     input_file = "standard input";
358
359   if (input_fd == output_fd)
360     error (1, 0, "standard %s is closed", input_fd == 0 ? "input" : "output");
361
362   if (output_file != NULL)
363     {
364       int omode = O_RDWR | O_CREAT;
365
366       if (seek_record == 0 && !(conversions_mask & C_NOTRUNC))
367         omode |= O_TRUNC;
368       output_fd = open (output_file, omode, 0666);
369       if (output_fd < 0)
370         error (1, errno, "%s", output_file);
371 #ifdef HAVE_FTRUNCATE
372       if (seek_record > 0 && !(conversions_mask & C_NOTRUNC))
373         {
374           if (ftruncate (output_fd, seek_record * output_blocksize) < 0)
375             error (0, errno, "%s", output_file);
376         }
377 #endif
378     }
379   else
380     output_file = "standard output";
381
382 #ifdef _POSIX_VERSION
383   sigaction (SIGINT, NULL, &sigact);
384   if (sigact.sa_handler != SIG_IGN)
385     {
386       sigact.sa_handler = interrupt_handler;
387       sigemptyset (&sigact.sa_mask);
388       sigact.sa_flags = 0;
389       sigaction (SIGINT, &sigact, NULL);
390     }
391   sigaction (SIGPIPE, NULL, &sigact);
392   if (sigact.sa_handler != SIG_IGN)
393     {
394       sigact.sa_handler = interrupt_handler;
395       sigemptyset (&sigact.sa_mask);
396       sigact.sa_flags = 0;
397       sigaction (SIGPIPE, &sigact, NULL);
398     }
399 #else                           /* !_POSIX_VERSION */
400   if (signal (SIGINT, SIG_IGN) != SIG_IGN)
401     signal (SIGINT, interrupt_handler);
402   if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
403     signal (SIGPIPE, interrupt_handler); 
404 #endif                          /* !_POSIX_VERSION */
405   copy ();
406 }
407
408 /* Throw away RECORDS blocks of BLOCKSIZE bytes on file descriptor FDESC,
409    which is open with read permission for FILE.  Store up to BLOCKSIZE
410    bytes of the data at a time in BUF, if necessary. */
411
412 static void
413 skip (fdesc, file, records, blocksize, buf)
414      int fdesc;
415      char *file;
416      long records;
417      long blocksize;
418      char *buf;
419 {
420   struct stat stats;
421
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))
427     {
428       error (0, errno, "%s", file);
429       quit (1);
430     }
431
432   /* FIXME: why use lseek only on regular files?
433      Better: try lseek and if an error indicates it was an inappropriate
434      operation, fall back on using read.  */
435   if (S_ISREG (stats.st_mode))
436     {
437       if (lseek (fdesc, records * blocksize, SEEK_SET) < 0)
438         {
439           error (0, errno, "%s", file);
440           quit (1);
441         }
442     }
443   else
444     {
445       while (records-- > 0)
446         {
447           int nread;
448
449           nread = safe_read (fdesc, buf, blocksize);
450           if (nread < 0)
451             {
452               error (0, errno, "%s", file);
453               quit (1);
454             }
455           /* POSIX doesn't say what to do when dd detects it has been
456              asked to skip past EOF, so I assume it's non-fatal.
457              FIXME: maybe give a warning.  */
458           if (nread == 0)
459             break;
460         }
461     }
462 }
463
464 /* Apply the character-set translations specified by the user
465    to the NREAD bytes in BUF.  */
466
467 static void
468 translate_buffer (buf, nread)
469      unsigned char *buf;
470      int nread;
471 {
472   register unsigned char *cp;
473   register int i;
474
475   for (i = nread, cp = buf; i; i--, cp++)
476     *cp = trans_table[*cp];
477 }
478
479 /* If nonnzero, the last char from the previous call to `swab_buffer'
480    is saved in `saved_char'.  */
481 static int char_is_saved = 0;
482
483 /* Odd char from previous call.  */
484 static unsigned char saved_char;
485
486 /* Swap NREAD bytes in BUF, plus possibly an initial char from the
487    previous call.  If NREAD is odd, save the last char for the
488    next call.   Return the new start of the BUF buffer.  */
489
490 static unsigned char *
491 swab_buffer (buf, nread)
492      unsigned char *buf;
493      int *nread;
494 {
495   unsigned char *bufstart = buf;
496   register unsigned char *cp;
497   register int i;
498
499   /* Is a char left from last time?  */
500   if (char_is_saved)
501     {
502       *--bufstart = saved_char;
503       (*nread)++;
504       char_is_saved = 0;
505     }
506
507   if (*nread & 1)
508     {
509       /* An odd number of chars are in the buffer.  */
510       saved_char = bufstart[--*nread];
511       char_is_saved = 1;
512     }
513
514   /* Do the byte-swapping by moving every second character two
515      positions toward the end, working from the end of the buffer
516      toward the beginning.  This way we only move half of the data.  */
517
518   cp = bufstart + *nread;       /* Start one char past the last.  */
519   for (i = *nread / 2; i; i--, cp -= 2)
520     *cp = *(cp - 2);
521
522   return ++bufstart;
523 }
524
525 /* Output buffer. */
526 static unsigned char *obuf;
527
528 /* Current index into `obuf'. */
529 static int oc = 0;
530
531 /* Index into current line, for `conv=block' and `conv=unblock'.  */
532 static int col = 0;
533
534 /* The main loop.  */
535
536 static void
537 copy ()
538 {
539   unsigned char *ibuf, *bufstart; /* Input buffer. */
540   int nread;                    /* Bytes read in the current block. */
541   int exit_status = 0;
542
543   /* Leave at least one extra byte at the beginning and end of `ibuf'
544      for conv=swab, but keep the buffer address even.  But some peculiar
545      device drivers work only with word-aligned buffers, so leave an
546      extra two bytes.  */
547
548   ibuf = (unsigned char *) xmalloc (input_blocksize + 2 * SWAB_ALIGN_OFFSET);
549   ibuf += SWAB_ALIGN_OFFSET;
550
551   if (conversions_mask & C_TWOBUFS)
552     obuf = (unsigned char *) xmalloc (output_blocksize);
553   else
554     obuf = ibuf;
555
556   if (skip_records > 0)
557     skip (input_fd, input_file, skip_records, input_blocksize, ibuf);
558
559   if (seek_record > 0)
560     skip (output_fd, output_file, seek_record, output_blocksize, obuf);
561
562   if (max_records == 0)
563     quit (exit_status);
564
565   while (1)
566     {
567       if (max_records >= 0 && r_partial + r_full >= max_records)
568         break;
569
570       /* Zero the buffer before reading, so that if we get a read error,
571          whatever data we are able to read is followed by zeros.
572          This minimizes data loss. */
573       if ((conversions_mask & C_SYNC) && (conversions_mask & C_NOERROR))
574         memset (ibuf, 0, input_blocksize);
575
576       nread = safe_read (input_fd, ibuf, input_blocksize);
577
578       if (nread == 0)
579         break;                  /* EOF.  */
580
581       if (nread < 0)
582         {
583           error (0, errno, "%s", input_file);
584           if (conversions_mask & C_NOERROR)
585             {
586               print_stats ();
587               /* Seek past the bad block if possible. */
588               lseek (input_fd, input_blocksize, SEEK_CUR);
589               if (conversions_mask & C_SYNC)
590                 /* Replace the missing input with null bytes and
591                    proceed normally.  */
592                 nread = 0;
593               else
594                 continue;
595             }
596           else
597             {
598               /* Write any partial block. */
599               exit_status = 2;
600               break;
601             }
602         }
603
604       if (nread < input_blocksize)
605         {
606           r_partial++;
607           if (conversions_mask & C_SYNC)
608             {
609               if (!(conversions_mask & C_NOERROR))
610                 /* If C_NOERROR, we zeroed the block before reading. */
611                 memset (ibuf + nread, 0, input_blocksize - nread);
612               nread = input_blocksize;
613             }
614         }
615       else
616         r_full++;
617
618       if (ibuf == obuf)         /* If not C_TWOBUFS. */
619         {
620           int nwritten = full_write (output_fd, obuf, nread);
621           if (nwritten != nread)
622             {
623               error (0, errno, "%s", output_file);
624               if (nwritten > 0)
625                 w_partial++;
626               quit (1);
627             }
628           else if (nread == input_blocksize)
629             w_full++;
630           else
631             w_partial++;
632           continue;
633         }
634
635       /* Do any translations on the whole buffer at once.  */
636
637       if (translation_needed)
638         translate_buffer (ibuf, nread);
639
640       if (conversions_mask & C_SWAB)
641         bufstart = swab_buffer (ibuf, &nread);
642       else
643         bufstart = ibuf;
644
645       if (conversions_mask & C_BLOCK)
646         copy_with_block (bufstart, nread);
647       else if (conversions_mask & C_UNBLOCK)
648         copy_with_unblock (bufstart, nread);
649       else
650         copy_simple (bufstart, nread);
651     }
652
653   /* If we have a char left as a result of conv=swab, output it.  */
654   if (char_is_saved)
655     {
656       if (conversions_mask & C_BLOCK)
657         copy_with_block (&saved_char, 1);
658       else if (conversions_mask & C_UNBLOCK)
659         copy_with_unblock (&saved_char, 1);
660       else
661         output_char (saved_char);
662     }
663
664   if ((conversions_mask & C_BLOCK) && col > 0)
665     {
666       /* If the final input line didn't end with a '\n', pad
667          the output block to `conversion_blocksize' chars.  */
668       int pending_spaces = max (0, conversion_blocksize - col);
669       while (pending_spaces)
670         {
671           output_char (space_character);
672           --pending_spaces;
673         }
674     }
675
676   if ((conversions_mask & C_UNBLOCK) && col == conversion_blocksize)
677     /* Add a final '\n' if there are exactly `conversion_blocksize'
678        characters in the final record. */
679     output_char (newline_character);
680
681   /* Write out the last block. */
682   if (oc > 0)
683     {
684       int nwritten = full_write (output_fd, obuf, oc);
685       if (nwritten > 0)
686         w_partial++;
687       if (nwritten != oc)
688         {
689           error (0, errno, "%s", output_file);
690           quit (1);
691         }
692     }
693
694   free (ibuf - SWAB_ALIGN_OFFSET);
695   if (obuf != ibuf)
696     free (obuf);
697
698   quit (exit_status);
699 }
700
701 /* Copy NREAD bytes of BUF, with no conversions.  */
702
703 static void
704 copy_simple (buf, nread)
705      unsigned char *buf;
706      int nread;
707 {
708   int nfree;                    /* Number of unused bytes in `obuf'.  */
709   unsigned char *start = buf; /* First uncopied char in BUF.  */
710
711   do
712     {
713       nfree = output_blocksize - oc;
714       if (nfree > nread)
715         nfree = nread;
716
717       memcpy (obuf + oc, start, nfree);
718
719       nread -= nfree;           /* Update the number of bytes left to copy. */
720       start += nfree;
721       oc += nfree;
722       if (oc >= output_blocksize)
723         write_output ();
724     }
725   while (nread > 0);
726 }
727
728 /* Copy NREAD bytes of BUF, doing conv=block
729    (pad newline-terminated records to `conversion_blocksize',
730    replacing the newline with trailing spaces).  */
731
732 static void
733 copy_with_block (buf, nread)
734      unsigned char *buf;
735      int nread;
736 {
737   register int i;
738
739   for (i = nread; i; i--, buf++)
740     {
741       if (*buf == newline_character)
742         {
743           int pending_spaces = max (0, conversion_blocksize - col);
744           while (pending_spaces)
745             {
746               output_char (space_character);
747               --pending_spaces;
748             }
749           col = 0;
750         }
751       else
752         {
753           if (col == conversion_blocksize)
754             r_truncate++;
755           else if (col < conversion_blocksize)
756             output_char (*buf);
757           col++;
758         }
759     }
760 }
761
762 /* Copy NREAD bytes of BUF, doing conv=unblock
763    (replace trailing spaces in `conversion_blocksize'-sized records
764    with a newline).  */
765
766 static void
767 copy_with_unblock (buf, nread)
768      unsigned char *buf;
769      int nread;
770 {
771   register int i;
772   register unsigned char c;
773   static int pending_spaces = 0;
774
775   for (i = 0; i < nread; i++)
776     {
777       c = buf[i];
778
779       if (col++ >= conversion_blocksize)
780         {
781           col = pending_spaces = 0; /* Wipe out any pending spaces.  */
782           i--;                  /* Push the char back; get it later. */
783           output_char (newline_character);
784         }
785       else if (c == space_character)
786         pending_spaces++;
787       else
788         {
789           /* `c' is the character after a run of spaces that were not
790              at the end of the conversion buffer.  Output them.  */
791           while (pending_spaces)
792             {
793               output_char (space_character);
794               --pending_spaces;
795             }
796           output_char (c);
797         }
798     }
799 }
800
801 /* Write, then empty, the output buffer `obuf'. */
802
803 static void
804 write_output ()
805 {
806   int nwritten = full_write (output_fd, obuf, output_blocksize);
807   if (nwritten != output_blocksize)
808     {
809       error (0, errno, "%s", output_file);
810       if (nwritten > 0)
811         w_partial++;
812       quit (1);
813     }
814   else
815     w_full++;
816   oc = 0;
817 }
818
819 static void
820 scanargs (argc, argv)
821      int argc;
822      char **argv;
823 {
824   int i, n;
825   int c;
826
827   while ((c = getopt_long (argc, argv, "", long_options, (int *) 0)) != EOF)
828     {
829       switch (c)
830         {
831         case 0:
832           break;
833
834         default:
835           usage (1);
836         }
837     }
838
839   for (i = optind; i < argc; i++)
840     {
841       char *name, *val;
842
843       name = argv[i];
844       val = strchr (name, '=');
845       if (val == NULL)
846         {
847           error (0, 0, "unrecognized option `%s'", name);
848           usage (1);
849         }
850       *val++ = '\0';
851
852       if (equal (name, "if"))
853         input_file = val;
854       else if (equal (name, "of"))
855         output_file = val;
856       else if (equal (name, "conv"))
857         parse_conversion (val);
858       else
859         {
860           n = parse_integer (val);
861           if (n < 0)
862             error (1, 0, "invalid number `%s'", val);
863
864           if (equal (name, "ibs"))
865             {
866               input_blocksize = n;
867               conversions_mask |= C_TWOBUFS;
868             }
869           else if (equal (name, "obs"))
870             {
871               output_blocksize = n;
872               conversions_mask |= C_TWOBUFS;
873             }
874           else if (equal (name, "bs"))
875             output_blocksize = input_blocksize = n;
876           else if (equal (name, "cbs"))
877             conversion_blocksize = n;
878           else if (equal (name, "skip"))
879             skip_records = n;
880           else if (equal (name, "seek"))
881             seek_record = n;
882           else if (equal (name, "count"))
883             max_records = n;
884           else
885             {
886               error (0, 0, "unrecognized option `%s=%s'", name, val);
887               usage (1);
888             }
889         }
890     }
891
892   /* If bs= was given, both `input_blocksize' and `output_blocksize' will
893      have been set to non-negative values.  If either has not been set,
894      bs= was not given, so make sure two buffers are used. */
895   if (input_blocksize == -1 || output_blocksize == -1)
896     conversions_mask |= C_TWOBUFS;
897   if (input_blocksize == -1)
898     input_blocksize = DEFAULT_BLOCKSIZE;
899   if (output_blocksize == -1)
900     output_blocksize = DEFAULT_BLOCKSIZE;
901   if (conversion_blocksize == 0)
902     conversions_mask &= ~(C_BLOCK | C_UNBLOCK);
903 }
904
905 /* Return the value of STR, interpreted as a non-negative decimal integer,
906    optionally multiplied by various values.
907    Return -1 if STR does not represent a number in this format. */
908
909 /* FIXME: use xstrtou?l */
910
911 static int
912 parse_integer (str)
913      char *str;
914 {
915   register int n = 0;
916   register int temp;
917   register char *p = str;
918
919   while (ISDIGIT (*p))
920     {
921       n = n * 10 + *p - '0';
922       p++;
923     }
924 loop:
925   switch (*p++)
926     {
927     case '\0':
928       return n;
929     case 'b':
930       n *= 512;
931       goto loop;
932     case 'c':
933       goto loop;
934     case 'k':
935       n *= 1024;
936       goto loop;
937     case 'w':
938       n *= 2;
939       goto loop;
940     case 'x':
941       temp = parse_integer (p);
942       if (temp == -1)
943         return -1;
944       n *= temp;
945       break;
946     default:
947       return -1;
948     }
949   return n;
950 }
951
952 /* Interpret one "conv=..." option. */
953
954 static void
955 parse_conversion (str)
956      char *str;
957 {
958   char *new;
959   int i;
960
961   do
962     {
963       new = strchr (str, ',');
964       if (new != NULL)
965         *new++ = '\0';
966       for (i = 0; conversions[i].convname != NULL; i++)
967         if (equal (conversions[i].convname, str))
968           {
969             conversions_mask |= conversions[i].conversion;
970             break;
971           }
972       if (conversions[i].convname == NULL)
973         {
974           error (0, 0, "%s: invalid conversion", str);
975           usage (1);
976         }
977       str = new;
978   } while (new != NULL);
979 }
980
981 /* Fix up translation table. */
982
983 static void
984 apply_translations ()
985 {
986   int i;
987
988 #define MX(a) (bit_count (conversions_mask & (a)))
989   if ((MX (C_ASCII | C_EBCDIC | C_IBM) > 1)
990       || (MX (C_BLOCK | C_UNBLOCK) > 1)
991       || (MX (C_LCASE | C_UCASE) > 1)
992       || (MX (C_UNBLOCK | C_SYNC) > 1))
993     {
994       error (1, 0, "\
995 only one conv in {ascii,ebcdic,ibm}, {lcase,ucase}, {block,unblock}, {unblock,sync}");
996     }
997 #undef MX
998
999   if (conversions_mask & C_ASCII)
1000     translate_charset (ebcdic_to_ascii);
1001
1002   if (conversions_mask & C_UCASE)
1003     {
1004       for (i = 0; i < 256; i++)
1005         if (ISLOWER (trans_table[i]))
1006           trans_table[i] = toupper (trans_table[i]);
1007       translation_needed = 1;
1008     }
1009   else if (conversions_mask & C_LCASE)
1010     {
1011       for (i = 0; i < 256; i++)
1012         if (ISUPPER (trans_table[i]))
1013           trans_table[i] = tolower (trans_table[i]);
1014       translation_needed = 1;
1015     }
1016
1017   if (conversions_mask & C_EBCDIC)
1018     {
1019       translate_charset (ascii_to_ebcdic);
1020       newline_character = ascii_to_ebcdic['\n'];
1021       space_character = ascii_to_ebcdic[' '];
1022     }
1023   else if (conversions_mask & C_IBM)
1024     {
1025       translate_charset (ascii_to_ibm);
1026       newline_character = ascii_to_ibm['\n'];
1027       space_character = ascii_to_ibm[' '];
1028     }
1029 }
1030
1031 static void
1032 translate_charset (new_trans)
1033      unsigned char *new_trans;
1034 {
1035   int i;
1036
1037   for (i = 0; i < 256; i++)
1038     trans_table[i] = new_trans[trans_table[i]];
1039   translation_needed = 1;
1040 }
1041
1042 /* Return the number of 1 bits in `i'. */
1043
1044 static int
1045 bit_count (i)
1046      register unsigned int i;
1047 {
1048   register int set_bits;
1049
1050   for (set_bits = 0; i != 0; set_bits++)
1051     i &= i - 1;
1052   return set_bits;
1053 }
1054
1055 static void
1056 print_stats ()
1057 {
1058   fprintf (stderr, "%u+%u records in\n", r_full, r_partial);
1059   fprintf (stderr, "%u+%u records out\n", w_full, w_partial);
1060   if (r_truncate > 0)
1061     fprintf (stderr, "%u truncated record%s\n", r_truncate,
1062              r_truncate == 1 ? "" : "s");
1063 }
1064
1065 static void
1066 quit (code)
1067      int code;
1068 {
1069   int errcode = code ? code : 1;
1070   print_stats ();
1071   if (close (input_fd) < 0)
1072     error (errcode, errno, "%s", input_file);
1073   if (close (output_fd) < 0)
1074     error (errcode, errno, "%s", output_file);
1075   exit (code);
1076 }
1077
1078 static RETSIGTYPE
1079 interrupt_handler ()
1080 {
1081   quit (1);
1082 }
1083
1084 static void
1085 usage (status)
1086      int status;
1087 {
1088   if (status != 0)
1089     fprintf (stderr, "Try `%s --help' for more information.\n",
1090              program_name);
1091   else
1092     {
1093       printf ("Usage: %s [OPTION]...\n", program_name);
1094       printf ("\
1095 \n\
1096   bs=BYTES        force ibs=BYTES and obs=BYTES\n\
1097   cbs=BYTES       convert BYTES bytes at a time\n\
1098   conv=KEYWORDS   convert the file as per the comma separated keyword list\n\
1099   count=BLOCKS    copy only BLOCKS input blocks\n\
1100   ibs=BYTES       read BYTES bytes at a time\n\
1101   if=FILE         read from FILE instead of stdin\n\
1102   obs=BYTES       write BYTES bytes at a time\n\
1103   of=FILE         write to FILE instead of stdout, don't truncate file\n\
1104   seek=BLOCKS     skip BLOCKS obs-sized blocks at start of output\n\
1105   skip=BLOCKS     skip BLOCKS ibs-sized blocks at start of input\n\
1106       --help      display this help and exit\n\
1107       --version   output version information and exit\n\
1108 \n\
1109 BYTES may be suffixed: by xM for multiplication by M, by c for x1,\n\
1110 by w for x2, by b for x512, by k for x1024.  Each KEYWORD may be:\n\
1111 \n\
1112   ascii     from EBCDIC to ASCII\n\
1113   ebcdic    from ASCII to EBCDIC\n\
1114   ibm       from ASCII to alternated EBCDIC\n\
1115   block     pad newline-terminated records with spaces to cbs-size \n\
1116   unblock   replace trailing spaces in cbs-size records with newline\n\
1117   lcase     change upper case to lower case\n\
1118   ucase     change lower case to upper case\n\
1119   swab      swap every pair of input bytes\n\
1120   noerror   continue after read errors\n\
1121   sync      pad every input block with NULs to ibs-size\n");
1122     }
1123   exit (status);
1124 }