Don't include headers already included by system.h:
[platform/upstream/coreutils.git] / src / dd.c
1 /* dd -- convert a file while copying it.
2    Copyright (C) 85, 90, 91, 1995-2003 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 #include <config.h>
21 #include <stdio.h>
22
23 #define SWAB_ALIGN_OFFSET 2
24
25 #include <sys/types.h>
26 #include <signal.h>
27 #include <getopt.h>
28
29 #include "system.h"
30 #include "error.h"
31 #include "full-write.h"
32 #include "getpagesize.h"
33 #include "inttostr.h"
34 #include "long-options.h"
35 #include "quote.h"
36 #include "safe-read.h"
37 #include "xstrtol.h"
38
39 /* The official name of this program (e.g., no `g' prefix).  */
40 #define PROGRAM_NAME "dd"
41
42 #define AUTHORS N_ ("Paul Rubin, David MacKenzie, and Stuart Kemp")
43
44 #ifndef SIGINFO
45 # define SIGINFO SIGUSR1
46 #endif
47
48 #ifndef S_TYPEISSHM
49 # define S_TYPEISSHM(Stat_ptr) 0
50 #endif
51
52 #define ROUND_UP_OFFSET(X, M) ((M) - 1 - (((X) + (M) - 1) % (M)))
53 #define PTR_ALIGN(Ptr, M) ((Ptr) \
54                            + ROUND_UP_OFFSET ((char *)(Ptr) - (char *)0, (M)))
55
56 #define max(a, b) ((a) > (b) ? (a) : (b))
57 #define output_char(c)                          \
58   do                                            \
59     {                                           \
60       obuf[oc++] = (c);                         \
61       if (oc >= output_blocksize)               \
62         write_output ();                        \
63     }                                           \
64   while (0)
65
66 /* Default input and output blocksize. */
67 #define DEFAULT_BLOCKSIZE 512
68
69 /* Conversions bit masks. */
70 #define C_ASCII 01
71 #define C_EBCDIC 02
72 #define C_IBM 04
73 #define C_BLOCK 010
74 #define C_UNBLOCK 020
75 #define C_LCASE 040
76 #define C_UCASE 0100
77 #define C_SWAB 0200
78 #define C_NOERROR 0400
79 #define C_NOTRUNC 01000
80 #define C_SYNC 02000
81 /* Use separate input and output buffers, and combine partial input blocks. */
82 #define C_TWOBUFS 04000
83
84 /* The name this program was run with. */
85 char *program_name;
86
87 /* The name of the input file, or NULL for the standard input. */
88 static char const *input_file = NULL;
89
90 /* The name of the output file, or NULL for the standard output. */
91 static char const *output_file = NULL;
92
93 /* The number of bytes in which atomic reads are done. */
94 static size_t input_blocksize = 0;
95
96 /* The number of bytes in which atomic writes are done. */
97 static size_t output_blocksize = 0;
98
99 /* Conversion buffer size, in bytes.  0 prevents conversions. */
100 static size_t conversion_blocksize = 0;
101
102 /* Skip this many records of `input_blocksize' bytes before input. */
103 static uintmax_t skip_records = 0;
104
105 /* Skip this many records of `output_blocksize' bytes before output. */
106 static uintmax_t seek_records = 0;
107
108 /* Copy only this many records.  The default is effectively infinity.  */
109 static uintmax_t max_records = (uintmax_t) -1;
110
111 /* Bit vector of conversions to apply. */
112 static int conversions_mask = 0;
113
114 /* If nonzero, filter characters through the translation table.  */
115 static int translation_needed = 0;
116
117 /* Number of partial blocks written. */
118 static uintmax_t w_partial = 0;
119
120 /* Number of full blocks written. */
121 static uintmax_t w_full = 0;
122
123 /* Number of partial blocks read. */
124 static uintmax_t r_partial = 0;
125
126 /* Number of full blocks read. */
127 static uintmax_t r_full = 0;
128
129 /* Records truncated by conv=block. */
130 static uintmax_t r_truncate = 0;
131
132 /* Output representation of newline and space characters.
133    They change if we're converting to EBCDIC.  */
134 static char newline_character = '\n';
135 static char space_character = ' ';
136
137 /* Output buffer. */
138 static char *obuf;
139
140 /* Current index into `obuf'. */
141 static size_t oc = 0;
142
143 /* Index into current line, for `conv=block' and `conv=unblock'.  */
144 static size_t col = 0;
145
146 struct conversion
147 {
148   char *convname;
149   int conversion;
150 };
151
152 static struct conversion conversions[] =
153 {
154   {"ascii", C_ASCII | C_TWOBUFS},       /* EBCDIC to ASCII. */
155   {"ebcdic", C_EBCDIC | C_TWOBUFS},     /* ASCII to EBCDIC. */
156   {"ibm", C_IBM | C_TWOBUFS},   /* Slightly different ASCII to EBCDIC. */
157   {"block", C_BLOCK | C_TWOBUFS},       /* Variable to fixed length records. */
158   {"unblock", C_UNBLOCK | C_TWOBUFS},   /* Fixed to variable length records. */
159   {"lcase", C_LCASE | C_TWOBUFS},       /* Translate upper to lower case. */
160   {"ucase", C_UCASE | C_TWOBUFS},       /* Translate lower to upper case. */
161   {"swab", C_SWAB | C_TWOBUFS}, /* Swap bytes of input. */
162   {"noerror", C_NOERROR},       /* Ignore i/o errors. */
163   {"notrunc", C_NOTRUNC},       /* Do not truncate output file. */
164   {"sync", C_SYNC},             /* Pad input records to ibs with NULs. */
165   {NULL, 0}
166 };
167
168 /* Translation table formed by applying successive transformations. */
169 static unsigned char trans_table[256];
170
171 static char const ascii_to_ebcdic[] =
172 {
173   '\000', '\001', '\002', '\003', '\067', '\055', '\056', '\057',
174   '\026', '\005', '\045', '\013', '\014', '\015', '\016', '\017',
175   '\020', '\021', '\022', '\023', '\074', '\075', '\062', '\046',
176   '\030', '\031', '\077', '\047', '\034', '\035', '\036', '\037',
177   '\100', '\117', '\177', '\173', '\133', '\154', '\120', '\175',
178   '\115', '\135', '\134', '\116', '\153', '\140', '\113', '\141',
179   '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
180   '\370', '\371', '\172', '\136', '\114', '\176', '\156', '\157',
181   '\174', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
182   '\310', '\311', '\321', '\322', '\323', '\324', '\325', '\326',
183   '\327', '\330', '\331', '\342', '\343', '\344', '\345', '\346',
184   '\347', '\350', '\351', '\112', '\340', '\132', '\137', '\155',
185   '\171', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
186   '\210', '\211', '\221', '\222', '\223', '\224', '\225', '\226',
187   '\227', '\230', '\231', '\242', '\243', '\244', '\245', '\246',
188   '\247', '\250', '\251', '\300', '\152', '\320', '\241', '\007',
189   '\040', '\041', '\042', '\043', '\044', '\025', '\006', '\027',
190   '\050', '\051', '\052', '\053', '\054', '\011', '\012', '\033',
191   '\060', '\061', '\032', '\063', '\064', '\065', '\066', '\010',
192   '\070', '\071', '\072', '\073', '\004', '\024', '\076', '\341',
193   '\101', '\102', '\103', '\104', '\105', '\106', '\107', '\110',
194   '\111', '\121', '\122', '\123', '\124', '\125', '\126', '\127',
195   '\130', '\131', '\142', '\143', '\144', '\145', '\146', '\147',
196   '\150', '\151', '\160', '\161', '\162', '\163', '\164', '\165',
197   '\166', '\167', '\170', '\200', '\212', '\213', '\214', '\215',
198   '\216', '\217', '\220', '\232', '\233', '\234', '\235', '\236',
199   '\237', '\240', '\252', '\253', '\254', '\255', '\256', '\257',
200   '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
201   '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
202   '\312', '\313', '\314', '\315', '\316', '\317', '\332', '\333',
203   '\334', '\335', '\336', '\337', '\352', '\353', '\354', '\355',
204   '\356', '\357', '\372', '\373', '\374', '\375', '\376', '\377'
205 };
206
207 static char const ascii_to_ibm[] =
208 {
209   '\000', '\001', '\002', '\003', '\067', '\055', '\056', '\057',
210   '\026', '\005', '\045', '\013', '\014', '\015', '\016', '\017',
211   '\020', '\021', '\022', '\023', '\074', '\075', '\062', '\046',
212   '\030', '\031', '\077', '\047', '\034', '\035', '\036', '\037',
213   '\100', '\132', '\177', '\173', '\133', '\154', '\120', '\175',
214   '\115', '\135', '\134', '\116', '\153', '\140', '\113', '\141',
215   '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
216   '\370', '\371', '\172', '\136', '\114', '\176', '\156', '\157',
217   '\174', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
218   '\310', '\311', '\321', '\322', '\323', '\324', '\325', '\326',
219   '\327', '\330', '\331', '\342', '\343', '\344', '\345', '\346',
220   '\347', '\350', '\351', '\255', '\340', '\275', '\137', '\155',
221   '\171', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
222   '\210', '\211', '\221', '\222', '\223', '\224', '\225', '\226',
223   '\227', '\230', '\231', '\242', '\243', '\244', '\245', '\246',
224   '\247', '\250', '\251', '\300', '\117', '\320', '\241', '\007',
225   '\040', '\041', '\042', '\043', '\044', '\025', '\006', '\027',
226   '\050', '\051', '\052', '\053', '\054', '\011', '\012', '\033',
227   '\060', '\061', '\032', '\063', '\064', '\065', '\066', '\010',
228   '\070', '\071', '\072', '\073', '\004', '\024', '\076', '\341',
229   '\101', '\102', '\103', '\104', '\105', '\106', '\107', '\110',
230   '\111', '\121', '\122', '\123', '\124', '\125', '\126', '\127',
231   '\130', '\131', '\142', '\143', '\144', '\145', '\146', '\147',
232   '\150', '\151', '\160', '\161', '\162', '\163', '\164', '\165',
233   '\166', '\167', '\170', '\200', '\212', '\213', '\214', '\215',
234   '\216', '\217', '\220', '\232', '\233', '\234', '\235', '\236',
235   '\237', '\240', '\252', '\253', '\254', '\255', '\256', '\257',
236   '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
237   '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
238   '\312', '\313', '\314', '\315', '\316', '\317', '\332', '\333',
239   '\334', '\335', '\336', '\337', '\352', '\353', '\354', '\355',
240   '\356', '\357', '\372', '\373', '\374', '\375', '\376', '\377'
241 };
242
243 static char const ebcdic_to_ascii[] =
244 {
245   '\000', '\001', '\002', '\003', '\234', '\011', '\206', '\177',
246   '\227', '\215', '\216', '\013', '\014', '\015', '\016', '\017',
247   '\020', '\021', '\022', '\023', '\235', '\205', '\010', '\207',
248   '\030', '\031', '\222', '\217', '\034', '\035', '\036', '\037',
249   '\200', '\201', '\202', '\203', '\204', '\012', '\027', '\033',
250   '\210', '\211', '\212', '\213', '\214', '\005', '\006', '\007',
251   '\220', '\221', '\026', '\223', '\224', '\225', '\226', '\004',
252   '\230', '\231', '\232', '\233', '\024', '\025', '\236', '\032',
253   '\040', '\240', '\241', '\242', '\243', '\244', '\245', '\246',
254   '\247', '\250', '\133', '\056', '\074', '\050', '\053', '\041',
255   '\046', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
256   '\260', '\261', '\135', '\044', '\052', '\051', '\073', '\136',
257   '\055', '\057', '\262', '\263', '\264', '\265', '\266', '\267',
258   '\270', '\271', '\174', '\054', '\045', '\137', '\076', '\077',
259   '\272', '\273', '\274', '\275', '\276', '\277', '\300', '\301',
260   '\302', '\140', '\072', '\043', '\100', '\047', '\075', '\042',
261   '\303', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
262   '\150', '\151', '\304', '\305', '\306', '\307', '\310', '\311',
263   '\312', '\152', '\153', '\154', '\155', '\156', '\157', '\160',
264   '\161', '\162', '\313', '\314', '\315', '\316', '\317', '\320',
265   '\321', '\176', '\163', '\164', '\165', '\166', '\167', '\170',
266   '\171', '\172', '\322', '\323', '\324', '\325', '\326', '\327',
267   '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
268   '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
269   '\173', '\101', '\102', '\103', '\104', '\105', '\106', '\107',
270   '\110', '\111', '\350', '\351', '\352', '\353', '\354', '\355',
271   '\175', '\112', '\113', '\114', '\115', '\116', '\117', '\120',
272   '\121', '\122', '\356', '\357', '\360', '\361', '\362', '\363',
273   '\134', '\237', '\123', '\124', '\125', '\126', '\127', '\130',
274   '\131', '\132', '\364', '\365', '\366', '\367', '\370', '\371',
275   '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
276   '\070', '\071', '\372', '\373', '\374', '\375', '\376', '\377'
277 };
278
279 void
280 usage (int status)
281 {
282   if (status != 0)
283     fprintf (stderr, _("Try `%s --help' for more information.\n"),
284              program_name);
285   else
286     {
287       printf (_("Usage: %s [OPTION]...\n"), program_name);
288       fputs (_("\
289 Copy a file, converting and formatting according to the options.\n\
290 \n\
291   bs=BYTES        force ibs=BYTES and obs=BYTES\n\
292   cbs=BYTES       convert BYTES bytes at a time\n\
293   conv=KEYWORDS   convert the file as per the comma separated keyword list\n\
294   count=BLOCKS    copy only BLOCKS input blocks\n\
295   ibs=BYTES       read BYTES bytes at a time\n\
296 "), stdout);
297       fputs (_("\
298   if=FILE         read from FILE instead of stdin\n\
299   obs=BYTES       write BYTES bytes at a time\n\
300   of=FILE         write to FILE instead of stdout\n\
301   seek=BLOCKS     skip BLOCKS obs-sized blocks at start of output\n\
302   skip=BLOCKS     skip BLOCKS ibs-sized blocks at start of input\n\
303 "), stdout);
304       fputs (HELP_OPTION_DESCRIPTION, stdout);
305       fputs (VERSION_OPTION_DESCRIPTION, stdout);
306       fputs (_("\
307 \n\
308 BLOCKS and BYTES may be followed by the following multiplicative suffixes:\n\
309 xM M, c 1, w 2, b 512, kB 1000, K 1024, MB 1000*1000, M 1024*1024,\n\
310 GB 1000*1000*1000, G 1024*1024*1024, and so on for T, P, E, Z, Y.\n\
311 Each KEYWORD may be:\n\
312 \n\
313 "), stdout);
314       fputs (_("\
315   ascii     from EBCDIC to ASCII\n\
316   ebcdic    from ASCII to EBCDIC\n\
317   ibm       from ASCII to alternated EBCDIC\n\
318   block     pad newline-terminated records with spaces to cbs-size\n\
319   unblock   replace trailing spaces in cbs-size records with newline\n\
320   lcase     change upper case to lower case\n\
321 "), stdout);
322       fputs (_("\
323   notrunc   do not truncate the output file\n\
324   ucase     change lower case to upper case\n\
325   swab      swap every pair of input bytes\n\
326   noerror   continue after read errors\n\
327   sync      pad every input block with NULs to ibs-size; when used\n\
328               with block or unblock, pad with spaces rather than NULs\n\
329 "), stdout);
330       printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
331     }
332   exit (status);
333 }
334
335 static void
336 translate_charset (char const *new_trans)
337 {
338   int i;
339
340   for (i = 0; i < 256; i++)
341     trans_table[i] = new_trans[trans_table[i]];
342   translation_needed = 1;
343 }
344
345 /* Return the number of 1 bits in `i'. */
346
347 static int
348 bit_count (register int i)
349 {
350   register int set_bits;
351
352   for (set_bits = 0; i != 0; set_bits++)
353     i &= i - 1;
354   return set_bits;
355 }
356
357 static void
358 print_stats (void)
359 {
360   char buf[2][INT_BUFSIZE_BOUND (uintmax_t)];
361   fprintf (stderr, _("%s+%s records in\n"),
362            umaxtostr (r_full, buf[0]), umaxtostr (r_partial, buf[1]));
363   fprintf (stderr, _("%s+%s records out\n"),
364            umaxtostr (w_full, buf[0]), umaxtostr (w_partial, buf[1]));
365   if (r_truncate > 0)
366     {
367       fprintf (stderr, "%s %s\n",
368                umaxtostr (r_truncate, buf[0]),
369                (r_truncate == 1
370                 ? _("truncated record")
371                 : _("truncated records")));
372     }
373 }
374
375 static void
376 cleanup (void)
377 {
378   print_stats ();
379   if (close (STDIN_FILENO) < 0)
380     error (EXIT_FAILURE, errno,
381            _("closing input file %s"), quote (input_file));
382   if (close (STDOUT_FILENO) < 0)
383     error (EXIT_FAILURE, errno,
384            _("closing output file %s"), quote (output_file));
385 }
386
387 static inline void
388 quit (int code)
389 {
390   cleanup ();
391   exit (code);
392 }
393
394 static RETSIGTYPE
395 interrupt_handler (int sig)
396 {
397 #ifdef SA_NOCLDSTOP
398   struct sigaction sigact;
399
400   sigact.sa_handler = SIG_DFL;
401   sigemptyset (&sigact.sa_mask);
402   sigact.sa_flags = 0;
403   sigaction (sig, &sigact, NULL);
404 #else
405   signal (sig, SIG_DFL);
406 #endif
407   cleanup ();
408   raise (sig);
409 }
410
411 static RETSIGTYPE
412 siginfo_handler (int sig ATTRIBUTE_UNUSED)
413 {
414   print_stats ();
415 }
416
417 /* Encapsulate portability mess of establishing signal handlers.  */
418
419 static void
420 install_handler (int sig_num, RETSIGTYPE (*sig_handler) (int sig))
421 {
422 #ifdef SA_NOCLDSTOP
423   struct sigaction sigact;
424   sigaction (sig_num, NULL, &sigact);
425   if (sigact.sa_handler != SIG_IGN)
426     {
427       sigact.sa_handler = sig_handler;
428       sigemptyset (&sigact.sa_mask);
429       sigact.sa_flags = 0;
430       sigaction (sig_num, &sigact, NULL);
431     }
432 #else
433   if (signal (sig_num, SIG_IGN) != SIG_IGN)
434     signal (sig_num, sig_handler);
435 #endif
436 }
437
438 /* Open a file to a particular file descriptor.  This is like standard
439    `open', except it always returns DESIRED_FD if successful.  */
440 static int
441 open_fd (int desired_fd, char const *filename, int options, mode_t mode)
442 {
443   int fd;
444   close (desired_fd);
445   fd = open (filename, options, mode);
446   if (fd < 0)
447     return -1;
448
449   if (fd != desired_fd)
450     {
451       if (dup2 (fd, desired_fd) != desired_fd)
452         desired_fd = -1;
453       if (close (fd) != 0)
454         return -1;
455     }
456
457   return desired_fd;
458 }
459
460 /* Write, then empty, the output buffer `obuf'. */
461
462 static void
463 write_output (void)
464 {
465   size_t nwritten = full_write (STDOUT_FILENO, obuf, output_blocksize);
466   if (nwritten != output_blocksize)
467     {
468       error (0, errno, _("writing to %s"), quote (output_file));
469       if (nwritten != 0)
470         w_partial++;
471       quit (1);
472     }
473   else
474     w_full++;
475   oc = 0;
476 }
477
478 /* Interpret one "conv=..." option.
479    As a by product, this function replaces each `,' in STR with a NUL byte.  */
480
481 static void
482 parse_conversion (char *str)
483 {
484   char *new;
485   int i;
486
487   do
488     {
489       new = strchr (str, ',');
490       if (new != NULL)
491         *new++ = '\0';
492       for (i = 0; conversions[i].convname != NULL; i++)
493         if (STREQ (conversions[i].convname, str))
494           {
495             conversions_mask |= conversions[i].conversion;
496             break;
497           }
498       if (conversions[i].convname == NULL)
499         {
500           error (0, 0, _("invalid conversion: %s"), quote (str));
501           usage (EXIT_FAILURE);
502         }
503       str = new;
504   } while (new != NULL);
505 }
506
507 /* Return the value of STR, interpreted as a non-negative decimal integer,
508    optionally multiplied by various values.
509    Assign nonzero to *INVALID if STR does not represent a number in
510    this format. */
511
512 static uintmax_t
513 parse_integer (const char *str, int *invalid)
514 {
515   uintmax_t n;
516   char *suffix;
517   enum strtol_error e = xstrtoumax (str, &suffix, 10, &n, "bcEGkKMPTwYZ0");
518
519   if (e == LONGINT_INVALID_SUFFIX_CHAR && *suffix == 'x')
520     {
521       uintmax_t multiplier = parse_integer (suffix + 1, invalid);
522
523       if (multiplier != 0 && n * multiplier / multiplier != n)
524         {
525           *invalid = 1;
526           return 0;
527         }
528
529       n *= multiplier;
530     }
531   else if (e != LONGINT_OK)
532     {
533       *invalid = 1;
534       return 0;
535     }
536
537   return n;
538 }
539
540 static void
541 scanargs (int argc, char **argv)
542 {
543   int i;
544
545   --argc;
546   ++argv;
547
548   for (i = optind; i < argc; i++)
549     {
550       char *name, *val;
551
552       name = argv[i];
553       val = strchr (name, '=');
554       if (val == NULL)
555         {
556           error (0, 0, _("unrecognized option %s"), quote (name));
557           usage (EXIT_FAILURE);
558         }
559       *val++ = '\0';
560
561       if (STREQ (name, "if"))
562         input_file = val;
563       else if (STREQ (name, "of"))
564         output_file = val;
565       else if (STREQ (name, "conv"))
566         parse_conversion (val);
567       else
568         {
569           int invalid = 0;
570           uintmax_t n = parse_integer (val, &invalid);
571
572           if (STREQ (name, "ibs"))
573             {
574               /* Ensure that each blocksize is <= SSIZE_MAX.  */
575               invalid |= SSIZE_MAX < n;
576               input_blocksize = n;
577               invalid |= input_blocksize != n || input_blocksize == 0;
578               conversions_mask |= C_TWOBUFS;
579             }
580           else if (STREQ (name, "obs"))
581             {
582               /* Ensure that each blocksize is <= SSIZE_MAX.  */
583               invalid |= SSIZE_MAX < n;
584               output_blocksize = n;
585               invalid |= output_blocksize != n || output_blocksize == 0;
586               conversions_mask |= C_TWOBUFS;
587             }
588           else if (STREQ (name, "bs"))
589             {
590               /* Ensure that each blocksize is <= SSIZE_MAX.  */
591               invalid |= SSIZE_MAX < n;
592               output_blocksize = input_blocksize = n;
593               invalid |= output_blocksize != n || output_blocksize == 0;
594             }
595           else if (STREQ (name, "cbs"))
596             {
597               conversion_blocksize = n;
598               invalid |= (conversion_blocksize != n
599                           || conversion_blocksize == 0);
600             }
601           else if (STREQ (name, "skip"))
602             skip_records = n;
603           else if (STREQ (name, "seek"))
604             seek_records = n;
605           else if (STREQ (name, "count"))
606             max_records = n;
607           else
608             {
609               error (0, 0, _("unrecognized option %s=%s"),
610                      quote_n (0, name), quote_n (1, val));
611               usage (EXIT_FAILURE);
612             }
613
614           if (invalid)
615             error (EXIT_FAILURE, 0, _("invalid number %s"), quote (val));
616         }
617     }
618
619   /* If bs= was given, both `input_blocksize' and `output_blocksize' will
620      have been set to positive values.  If either has not been set,
621      bs= was not given, so make sure two buffers are used. */
622   if (input_blocksize == 0 || output_blocksize == 0)
623     conversions_mask |= C_TWOBUFS;
624   if (input_blocksize == 0)
625     input_blocksize = DEFAULT_BLOCKSIZE;
626   if (output_blocksize == 0)
627     output_blocksize = DEFAULT_BLOCKSIZE;
628   if (conversion_blocksize == 0)
629     conversions_mask &= ~(C_BLOCK | C_UNBLOCK);
630 }
631
632 /* Fix up translation table. */
633
634 static void
635 apply_translations (void)
636 {
637   int i;
638
639 #define MX(a) (bit_count (conversions_mask & (a)))
640   if ((MX (C_ASCII | C_EBCDIC | C_IBM) > 1)
641       || (MX (C_BLOCK | C_UNBLOCK) > 1)
642       || (MX (C_LCASE | C_UCASE) > 1)
643       || (MX (C_UNBLOCK | C_SYNC) > 1))
644     {
645       error (EXIT_FAILURE, 0, _("\
646 only one conv in {ascii,ebcdic,ibm}, {lcase,ucase}, {block,unblock}, {unblock,sync}"));
647     }
648 #undef MX
649
650   if (conversions_mask & C_ASCII)
651     translate_charset (ebcdic_to_ascii);
652
653   if (conversions_mask & C_UCASE)
654     {
655       for (i = 0; i < 256; i++)
656         if (ISLOWER (trans_table[i]))
657           trans_table[i] = TOUPPER (trans_table[i]);
658       translation_needed = 1;
659     }
660   else if (conversions_mask & C_LCASE)
661     {
662       for (i = 0; i < 256; i++)
663         if (ISUPPER (trans_table[i]))
664           trans_table[i] = TOLOWER (trans_table[i]);
665       translation_needed = 1;
666     }
667
668   if (conversions_mask & C_EBCDIC)
669     {
670       translate_charset (ascii_to_ebcdic);
671       newline_character = ascii_to_ebcdic['\n'];
672       space_character = ascii_to_ebcdic[' '];
673     }
674   else if (conversions_mask & C_IBM)
675     {
676       translate_charset (ascii_to_ibm);
677       newline_character = ascii_to_ibm['\n'];
678       space_character = ascii_to_ibm[' '];
679     }
680 }
681
682 /* Apply the character-set translations specified by the user
683    to the NREAD bytes in BUF.  */
684
685 static void
686 translate_buffer (char *buf, size_t nread)
687 {
688   char *cp;
689   size_t i;
690
691   for (i = nread, cp = buf; i; i--, cp++)
692     *cp = trans_table[(unsigned char) *cp];
693 }
694
695 /* If nonnzero, the last char from the previous call to `swab_buffer'
696    is saved in `saved_char'.  */
697 static int char_is_saved = 0;
698
699 /* Odd char from previous call.  */
700 static char saved_char;
701
702 /* Swap NREAD bytes in BUF, plus possibly an initial char from the
703    previous call.  If NREAD is odd, save the last char for the
704    next call.   Return the new start of the BUF buffer.  */
705
706 static char *
707 swab_buffer (char *buf, size_t *nread)
708 {
709   char *bufstart = buf;
710   register char *cp;
711   register int i;
712
713   /* Is a char left from last time?  */
714   if (char_is_saved)
715     {
716       *--bufstart = saved_char;
717       (*nread)++;
718       char_is_saved = 0;
719     }
720
721   if (*nread & 1)
722     {
723       /* An odd number of chars are in the buffer.  */
724       saved_char = bufstart[--*nread];
725       char_is_saved = 1;
726     }
727
728   /* Do the byte-swapping by moving every second character two
729      positions toward the end, working from the end of the buffer
730      toward the beginning.  This way we only move half of the data.  */
731
732   cp = bufstart + *nread;       /* Start one char past the last.  */
733   for (i = *nread / 2; i; i--, cp -= 2)
734     *cp = *(cp - 2);
735
736   return ++bufstart;
737 }
738
739 /* This is a wrapper for lseek.  It detects and warns about a kernel
740    bug that makes lseek a no-op for tape devices, even though the kernel
741    lseek return value suggests that the function succeeded.
742
743    The parameters are the same as those of the lseek function, but
744    with the addition of FILENAME, the name of the file associated with
745    descriptor FDESC.  The file name is used solely in the warning that's
746    printed when the bug is detected.  Return the same value that lseek
747    would have returned, but when the lseek bug is detected, return -1
748    to indicate that lseek failed.
749
750    The offending behavior has been confirmed with an Exabyte SCSI tape
751    drive accessed via /dev/nst0 on both Linux-2.2.17 and Linux-2.4.16.  */
752
753 #ifdef __linux__
754
755 # include <sys/mtio.h>
756
757 # define MT_SAME_POSITION(P, Q) \
758    ((P).mt_resid == (Q).mt_resid \
759     && (P).mt_fileno == (Q).mt_fileno \
760     && (P).mt_blkno == (Q).mt_blkno)
761
762 static off_t
763 skip_via_lseek (char const *filename, int fdesc, off_t offset, int whence)
764 {
765   struct mtget s1;
766   struct mtget s2;
767   off_t new_position;
768   int got_original_tape_position;
769
770   got_original_tape_position = (ioctl (fdesc, MTIOCGET, &s1) == 0);
771   /* known bad device type */
772   /* && s.mt_type == MT_ISSCSI2 */
773
774   new_position = lseek (fdesc, offset, whence);
775   if (0 <= new_position
776       && got_original_tape_position
777       && ioctl (fdesc, MTIOCGET, &s2) == 0
778       && MT_SAME_POSITION (s1, s2))
779     {
780       error (0, 0, _("warning: working around lseek kernel bug for file (%s)\n\
781   of mt_type=0x%0lx -- see <sys/mtio.h> for the list of types"),
782              filename, s2.mt_type);
783       new_position = -1;
784     }
785
786   return new_position;
787 }
788 #else
789 # define skip_via_lseek(Filename, Fd, Offset, Whence) lseek (Fd, Offset, Whence)
790 #endif
791
792 /* Throw away RECORDS blocks of BLOCKSIZE bytes on file descriptor FDESC,
793    which is open with read permission for FILE.  Store up to BLOCKSIZE
794    bytes of the data at a time in BUF, if necessary.  RECORDS must be
795    nonzero.  */
796
797 static void
798 skip (int fdesc, char const *file, uintmax_t records, size_t blocksize,
799       char *buf)
800 {
801   off_t offset = records * blocksize;
802
803   /* Try lseek and if an error indicates it was an inappropriate operation --
804      or if the the file offset is not representable as an off_t --
805      fall back on using read.  */
806
807   if ((uintmax_t) offset / blocksize != records
808       || skip_via_lseek (file, fdesc, offset, SEEK_CUR) < 0)
809     {
810       while (records--)
811         {
812           size_t nread = safe_read (fdesc, buf, blocksize);
813           if (nread == SAFE_READ_ERROR)
814             {
815               error (0, errno, _("reading %s"), quote (file));
816               quit (1);
817             }
818           /* POSIX doesn't say what to do when dd detects it has been
819              asked to skip past EOF, so I assume it's non-fatal.
820              FIXME: maybe give a warning.  */
821           if (nread == 0)
822             break;
823         }
824     }
825 }
826
827 /* Copy NREAD bytes of BUF, with no conversions.  */
828
829 static void
830 copy_simple (char const *buf, int nread)
831 {
832   int nfree;                    /* Number of unused bytes in `obuf'.  */
833   const char *start = buf;      /* First uncopied char in BUF.  */
834
835   do
836     {
837       nfree = output_blocksize - oc;
838       if (nfree > nread)
839         nfree = nread;
840
841       memcpy (obuf + oc, start, nfree);
842
843       nread -= nfree;           /* Update the number of bytes left to copy. */
844       start += nfree;
845       oc += nfree;
846       if (oc >= output_blocksize)
847         write_output ();
848     }
849   while (nread > 0);
850 }
851
852 /* Copy NREAD bytes of BUF, doing conv=block
853    (pad newline-terminated records to `conversion_blocksize',
854    replacing the newline with trailing spaces).  */
855
856 static void
857 copy_with_block (char const *buf, size_t nread)
858 {
859   size_t i;
860
861   for (i = nread; i; i--, buf++)
862     {
863       if (*buf == newline_character)
864         {
865           if (col < conversion_blocksize)
866             {
867               size_t j;
868               for (j = col; j < conversion_blocksize; j++)
869                 output_char (space_character);
870             }
871           col = 0;
872         }
873       else
874         {
875           if (col == conversion_blocksize)
876             r_truncate++;
877           else if (col < conversion_blocksize)
878             output_char (*buf);
879           col++;
880         }
881     }
882 }
883
884 /* Copy NREAD bytes of BUF, doing conv=unblock
885    (replace trailing spaces in `conversion_blocksize'-sized records
886    with a newline).  */
887
888 static void
889 copy_with_unblock (char const *buf, size_t nread)
890 {
891   size_t i;
892   char c;
893   static int pending_spaces = 0;
894
895   for (i = 0; i < nread; i++)
896     {
897       c = buf[i];
898
899       if (col++ >= conversion_blocksize)
900         {
901           col = pending_spaces = 0; /* Wipe out any pending spaces.  */
902           i--;                  /* Push the char back; get it later. */
903           output_char (newline_character);
904         }
905       else if (c == space_character)
906         pending_spaces++;
907       else
908         {
909           /* `c' is the character after a run of spaces that were not
910              at the end of the conversion buffer.  Output them.  */
911           while (pending_spaces)
912             {
913               output_char (space_character);
914               --pending_spaces;
915             }
916           output_char (c);
917         }
918     }
919 }
920
921 /* The main loop.  */
922
923 static int
924 dd_copy (void)
925 {
926   char *ibuf, *bufstart;        /* Input buffer. */
927   char *real_buf;               /* real buffer address before alignment */
928   char *real_obuf;
929   size_t nread;                 /* Bytes read in the current block. */
930   int exit_status = 0;
931   size_t page_size = getpagesize ();
932   size_t n_bytes_read;
933
934   /* Leave at least one extra byte at the beginning and end of `ibuf'
935      for conv=swab, but keep the buffer address even.  But some peculiar
936      device drivers work only with word-aligned buffers, so leave an
937      extra two bytes.  */
938
939   /* Some devices require alignment on a sector or page boundary
940      (e.g. character disk devices).  Align the input buffer to a
941      page boundary to cover all bases.  Note that due to the swab
942      algorithm, we must have at least one byte in the page before
943      the input buffer;  thus we allocate 2 pages of slop in the
944      real buffer.  8k above the blocksize shouldn't bother anyone.
945
946      The page alignment is necessary on any linux system that supports
947      either the SGI raw I/O patch or Steven Tweedies raw I/O patch.
948      It is necessary when accessing raw (i.e. character special) disk
949      devices on Unixware or other SVR4-derived system.  */
950
951   real_buf = xmalloc (input_blocksize
952                       + 2 * SWAB_ALIGN_OFFSET
953                       + 2 * page_size - 1);
954   ibuf = real_buf;
955   ibuf += SWAB_ALIGN_OFFSET;    /* allow space for swab */
956
957   ibuf = PTR_ALIGN (ibuf, page_size);
958
959   if (conversions_mask & C_TWOBUFS)
960     {
961       /* Page-align the output buffer, too.  */
962       real_obuf = xmalloc (output_blocksize + page_size - 1);
963       obuf = PTR_ALIGN (real_obuf, page_size);
964     }
965   else
966     {
967       real_obuf = NULL;
968       obuf = ibuf;
969     }
970
971   if (skip_records != 0)
972     skip (STDIN_FILENO, input_file, skip_records, input_blocksize, ibuf);
973
974   if (seek_records != 0)
975     {
976       /* FIXME: this loses for
977          % ./dd if=dd seek=1 |:
978          ./dd: standard output: Bad file descriptor
979          0+0 records in
980          0+0 records out
981          */
982
983       skip (STDOUT_FILENO, output_file, seek_records, output_blocksize, obuf);
984     }
985
986   if (max_records == 0)
987     quit (exit_status);
988
989   while (1)
990     {
991       if (r_partial + r_full >= max_records)
992         break;
993
994       /* Zero the buffer before reading, so that if we get a read error,
995          whatever data we are able to read is followed by zeros.
996          This minimizes data loss. */
997       if ((conversions_mask & C_SYNC) && (conversions_mask & C_NOERROR))
998         memset (ibuf,
999                 (conversions_mask & (C_BLOCK | C_UNBLOCK)) ? ' ' : '\0',
1000                 input_blocksize);
1001
1002       nread = safe_read (STDIN_FILENO, ibuf, input_blocksize);
1003
1004       if (nread == 0)
1005         break;                  /* EOF.  */
1006
1007       if (nread == SAFE_READ_ERROR)
1008         {
1009           error (0, errno, _("reading %s"), quote (input_file));
1010           if (conversions_mask & C_NOERROR)
1011             {
1012               print_stats ();
1013               /* Seek past the bad block if possible. */
1014               lseek (STDIN_FILENO, (off_t) input_blocksize, SEEK_CUR);
1015               if (conversions_mask & C_SYNC)
1016                 /* Replace the missing input with null bytes and
1017                    proceed normally.  */
1018                 nread = 0;
1019               else
1020                 continue;
1021             }
1022           else
1023             {
1024               /* Write any partial block. */
1025               exit_status = 2;
1026               break;
1027             }
1028         }
1029
1030       n_bytes_read = nread;
1031
1032       if (n_bytes_read < input_blocksize)
1033         {
1034           r_partial++;
1035           if (conversions_mask & C_SYNC)
1036             {
1037               if (!(conversions_mask & C_NOERROR))
1038                 /* If C_NOERROR, we zeroed the block before reading. */
1039                 memset (ibuf + n_bytes_read,
1040                         (conversions_mask & (C_BLOCK | C_UNBLOCK)) ? ' ' : '\0',
1041                         input_blocksize - n_bytes_read);
1042               n_bytes_read = input_blocksize;
1043             }
1044         }
1045       else
1046         r_full++;
1047
1048       if (ibuf == obuf)         /* If not C_TWOBUFS. */
1049         {
1050           size_t nwritten = full_write (STDOUT_FILENO, obuf, n_bytes_read);
1051           if (nwritten != n_bytes_read)
1052             {
1053               error (0, errno, _("writing %s"), quote (output_file));
1054               quit (1);
1055             }
1056           else if (n_bytes_read == input_blocksize)
1057             w_full++;
1058           else
1059             w_partial++;
1060           continue;
1061         }
1062
1063       /* Do any translations on the whole buffer at once.  */
1064
1065       if (translation_needed)
1066         translate_buffer (ibuf, n_bytes_read);
1067
1068       if (conversions_mask & C_SWAB)
1069         bufstart = swab_buffer (ibuf, &n_bytes_read);
1070       else
1071         bufstart = ibuf;
1072
1073       if (conversions_mask & C_BLOCK)
1074         copy_with_block (bufstart, n_bytes_read);
1075       else if (conversions_mask & C_UNBLOCK)
1076         copy_with_unblock (bufstart, n_bytes_read);
1077       else
1078         copy_simple (bufstart, n_bytes_read);
1079     }
1080
1081   /* If we have a char left as a result of conv=swab, output it.  */
1082   if (char_is_saved)
1083     {
1084       if (conversions_mask & C_BLOCK)
1085         copy_with_block (&saved_char, 1);
1086       else if (conversions_mask & C_UNBLOCK)
1087         copy_with_unblock (&saved_char, 1);
1088       else
1089         output_char (saved_char);
1090     }
1091
1092   if ((conversions_mask & C_BLOCK) && col > 0)
1093     {
1094       /* If the final input line didn't end with a '\n', pad
1095          the output block to `conversion_blocksize' chars.  */
1096       size_t i;
1097       for (i = col; i < conversion_blocksize; i++)
1098         output_char (space_character);
1099     }
1100
1101   if ((conversions_mask & C_UNBLOCK) && col == conversion_blocksize)
1102     /* Add a final '\n' if there are exactly `conversion_blocksize'
1103        characters in the final record. */
1104     output_char (newline_character);
1105
1106   /* Write out the last block. */
1107   if (oc != 0)
1108     {
1109       size_t nwritten = full_write (STDOUT_FILENO, obuf, oc);
1110       if (nwritten != 0)
1111         w_partial++;
1112       if (nwritten != oc)
1113         {
1114           error (0, errno, _("writing %s"), quote (output_file));
1115           quit (1);
1116         }
1117     }
1118
1119   free (real_buf);
1120   if (real_obuf)
1121     free (real_obuf);
1122
1123   return exit_status;
1124 }
1125
1126 /* This is gross, but necessary, because of the way close_stdout
1127    works and because this program closes STDOUT_FILENO directly.  */
1128 static void (*closeout_func) (void) = close_stdout;
1129
1130 static void
1131 close_stdout_wrapper (void)
1132 {
1133   if (closeout_func)
1134     (*closeout_func) ();
1135 }
1136
1137 int
1138 main (int argc, char **argv)
1139 {
1140   int i;
1141   int exit_status;
1142
1143   initialize_main (&argc, &argv);
1144   program_name = argv[0];
1145   setlocale (LC_ALL, "");
1146   bindtextdomain (PACKAGE, LOCALEDIR);
1147   textdomain (PACKAGE);
1148
1149   /* Arrange to close stdout if parse_long_options exits.  */
1150   atexit (close_stdout_wrapper);
1151
1152   parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE, VERSION,
1153                       AUTHORS, usage);
1154
1155   /* Don't close stdout on exit from here on.  */
1156   closeout_func = NULL;
1157
1158   /* Initialize translation table to identity translation. */
1159   for (i = 0; i < 256; i++)
1160     trans_table[i] = i;
1161
1162   /* Decode arguments. */
1163   scanargs (argc, argv);
1164
1165   apply_translations ();
1166
1167   if (input_file != NULL)
1168     {
1169       if (open_fd (STDIN_FILENO, input_file, O_RDONLY, 0) < 0)
1170         error (EXIT_FAILURE, errno, _("opening %s"), quote (input_file));
1171     }
1172   else
1173     input_file = _("standard input");
1174
1175   if (output_file != NULL)
1176     {
1177       mode_t perms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
1178       int opts
1179         = (O_CREAT
1180            | (seek_records || (conversions_mask & C_NOTRUNC) ? 0 : O_TRUNC));
1181
1182       /* Open the output file with *read* access only if we might
1183          need to read to satisfy a `seek=' request.  If we can't read
1184          the file, go ahead with write-only access; it might work.  */
1185       if ((! seek_records
1186            || open_fd (STDOUT_FILENO, output_file, O_RDWR | opts, perms) < 0)
1187           && open_fd (STDOUT_FILENO, output_file, O_WRONLY | opts, perms) < 0)
1188         error (EXIT_FAILURE, errno, _("opening %s"), quote (output_file));
1189
1190 #if HAVE_FTRUNCATE
1191       if (seek_records != 0 && !(conversions_mask & C_NOTRUNC))
1192         {
1193           struct stat stdout_stat;
1194           off_t o = seek_records * output_blocksize;
1195           if ((uintmax_t) o / output_blocksize != seek_records)
1196             error (EXIT_FAILURE, 0, _("file offset out of range"));
1197
1198           if (fstat (STDOUT_FILENO, &stdout_stat) != 0)
1199             error (EXIT_FAILURE, errno, _("cannot fstat %s"),
1200                    quote (output_file));
1201
1202           /* Complain only when ftruncate fails on a regular file, a
1203              directory, or a shared memory object, as the 2000-08
1204              POSIX draft specifies ftruncate's behavior only for these
1205              file types.  For example, do not complain when Linux 2.4
1206              ftruncate fails on /dev/fd0.  */
1207           if (ftruncate (STDOUT_FILENO, o) != 0
1208               && (S_ISREG (stdout_stat.st_mode)
1209                   || S_ISDIR (stdout_stat.st_mode)
1210                   || S_TYPEISSHM (&stdout_stat)))
1211             {
1212               char buf[INT_BUFSIZE_BOUND (off_t)];
1213               error (EXIT_FAILURE, errno,
1214                      _("advancing past %s bytes in output file %s"),
1215                      offtostr (o, buf), quote (output_file));
1216             }
1217         }
1218 #endif
1219     }
1220   else
1221     {
1222       output_file = _("standard output");
1223     }
1224
1225   install_handler (SIGINT, interrupt_handler);
1226   install_handler (SIGQUIT, interrupt_handler);
1227   install_handler (SIGPIPE, interrupt_handler);
1228   install_handler (SIGINFO, siginfo_handler);
1229
1230   exit_status = dd_copy ();
1231
1232   quit (exit_status);
1233 }