(main, skip): Add casts to avoid warnings about
[platform/upstream/coreutils.git] / src / dd.c
1 /* dd -- convert a file while copying it.
2    Copyright (C) 85, 90, 91, 1995-2002 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 #if HAVE_INTTYPES_H
26 # include <inttypes.h>
27 #endif
28 #include <sys/types.h>
29 #include <signal.h>
30 #include <getopt.h>
31
32 #include "system.h"
33 #include "closeout.h"
34 #include "error.h"
35 #include "full-write.h"
36 #include "getpagesize.h"
37 #include "human.h"
38 #include "long-options.h"
39 #include "quote.h"
40 #include "safe-read.h"
41 #include "xstrtol.h"
42
43 /* The official name of this program (e.g., no `g' prefix).  */
44 #define PROGRAM_NAME "dd"
45
46 #define AUTHORS N_ ("Paul Rubin, David MacKenzie, and Stuart Kemp")
47
48 #ifndef SIGINFO
49 # define SIGINFO SIGUSR1
50 #endif
51
52 #ifndef S_TYPEISSHM
53 # define S_TYPEISSHM(Stat_ptr) 0
54 #endif
55
56 #define ROUND_UP_OFFSET(X, M) ((M) - 1 - (((X) + (M) - 1) % (M)))
57 #define PTR_ALIGN(Ptr, M) ((Ptr) \
58                            + ROUND_UP_OFFSET ((char *)(Ptr) - (char *)0, (M)))
59
60 #define max(a, b) ((a) > (b) ? (a) : (b))
61 #define output_char(c)                          \
62   do                                            \
63     {                                           \
64       obuf[oc++] = (c);                         \
65       if (oc >= output_blocksize)               \
66         write_output ();                        \
67     }                                           \
68   while (0)
69
70 /* Default input and output blocksize. */
71 #define DEFAULT_BLOCKSIZE 512
72
73 /* Conversions bit masks. */
74 #define C_ASCII 01
75 #define C_EBCDIC 02
76 #define C_IBM 04
77 #define C_BLOCK 010
78 #define C_UNBLOCK 020
79 #define C_LCASE 040
80 #define C_UCASE 0100
81 #define C_SWAB 0200
82 #define C_NOERROR 0400
83 #define C_NOTRUNC 01000
84 #define C_SYNC 02000
85 /* Use separate input and output buffers, and combine partial input blocks. */
86 #define C_TWOBUFS 04000
87
88 /* The name this program was run with. */
89 char *program_name;
90
91 /* The name of the input file, or NULL for the standard input. */
92 static char const *input_file = NULL;
93
94 /* The name of the output file, or NULL for the standard output. */
95 static char const *output_file = NULL;
96
97 /* The number of bytes in which atomic reads are done. */
98 static size_t input_blocksize = 0;
99
100 /* The number of bytes in which atomic writes are done. */
101 static size_t output_blocksize = 0;
102
103 /* Conversion buffer size, in bytes.  0 prevents conversions. */
104 static size_t conversion_blocksize = 0;
105
106 /* Skip this many records of `input_blocksize' bytes before input. */
107 static uintmax_t skip_records = 0;
108
109 /* Skip this many records of `output_blocksize' bytes before output. */
110 static uintmax_t seek_records = 0;
111
112 /* Copy only this many records.  The default is effectively infinity.  */
113 static uintmax_t max_records = (uintmax_t) -1;
114
115 /* Bit vector of conversions to apply. */
116 static int conversions_mask = 0;
117
118 /* If nonzero, filter characters through the translation table.  */
119 static int translation_needed = 0;
120
121 /* Number of partial blocks written. */
122 static uintmax_t w_partial = 0;
123
124 /* Number of full blocks written. */
125 static uintmax_t w_full = 0;
126
127 /* Number of partial blocks read. */
128 static uintmax_t r_partial = 0;
129
130 /* Number of full blocks read. */
131 static uintmax_t r_full = 0;
132
133 /* Records truncated by conv=block. */
134 static uintmax_t r_truncate = 0;
135
136 /* Output representation of newline and space characters.
137    They change if we're converting to EBCDIC.  */
138 static char newline_character = '\n';
139 static char space_character = ' ';
140
141 /* Output buffer. */
142 static char *obuf;
143
144 /* Current index into `obuf'. */
145 static size_t oc = 0;
146
147 /* Index into current line, for `conv=block' and `conv=unblock'.  */
148 static size_t col = 0;
149
150 struct conversion
151 {
152   char *convname;
153   int conversion;
154 };
155
156 static struct conversion conversions[] =
157 {
158   {"ascii", C_ASCII | C_TWOBUFS},       /* EBCDIC to ASCII. */
159   {"ebcdic", C_EBCDIC | C_TWOBUFS},     /* ASCII to EBCDIC. */
160   {"ibm", C_IBM | C_TWOBUFS},   /* Slightly different ASCII to EBCDIC. */
161   {"block", C_BLOCK | C_TWOBUFS},       /* Variable to fixed length records. */
162   {"unblock", C_UNBLOCK | C_TWOBUFS},   /* Fixed to variable length records. */
163   {"lcase", C_LCASE | C_TWOBUFS},       /* Translate upper to lower case. */
164   {"ucase", C_UCASE | C_TWOBUFS},       /* Translate lower to upper case. */
165   {"swab", C_SWAB | C_TWOBUFS}, /* Swap bytes of input. */
166   {"noerror", C_NOERROR},       /* Ignore i/o errors. */
167   {"notrunc", C_NOTRUNC},       /* Do not truncate output file. */
168   {"sync", C_SYNC},             /* Pad input records to ibs with NULs. */
169   {NULL, 0}
170 };
171
172 /* Translation table formed by applying successive transformations. */
173 static unsigned char trans_table[256];
174
175 static char const ascii_to_ebcdic[] =
176 {
177   '\000', '\001', '\002', '\003', '\067', '\055', '\056', '\057',
178   '\026', '\005', '\045', '\013', '\014', '\015', '\016', '\017',
179   '\020', '\021', '\022', '\023', '\074', '\075', '\062', '\046',
180   '\030', '\031', '\077', '\047', '\034', '\035', '\036', '\037',
181   '\100', '\117', '\177', '\173', '\133', '\154', '\120', '\175',
182   '\115', '\135', '\134', '\116', '\153', '\140', '\113', '\141',
183   '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
184   '\370', '\371', '\172', '\136', '\114', '\176', '\156', '\157',
185   '\174', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
186   '\310', '\311', '\321', '\322', '\323', '\324', '\325', '\326',
187   '\327', '\330', '\331', '\342', '\343', '\344', '\345', '\346',
188   '\347', '\350', '\351', '\112', '\340', '\132', '\137', '\155',
189   '\171', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
190   '\210', '\211', '\221', '\222', '\223', '\224', '\225', '\226',
191   '\227', '\230', '\231', '\242', '\243', '\244', '\245', '\246',
192   '\247', '\250', '\251', '\300', '\152', '\320', '\241', '\007',
193   '\040', '\041', '\042', '\043', '\044', '\025', '\006', '\027',
194   '\050', '\051', '\052', '\053', '\054', '\011', '\012', '\033',
195   '\060', '\061', '\032', '\063', '\064', '\065', '\066', '\010',
196   '\070', '\071', '\072', '\073', '\004', '\024', '\076', '\341',
197   '\101', '\102', '\103', '\104', '\105', '\106', '\107', '\110',
198   '\111', '\121', '\122', '\123', '\124', '\125', '\126', '\127',
199   '\130', '\131', '\142', '\143', '\144', '\145', '\146', '\147',
200   '\150', '\151', '\160', '\161', '\162', '\163', '\164', '\165',
201   '\166', '\167', '\170', '\200', '\212', '\213', '\214', '\215',
202   '\216', '\217', '\220', '\232', '\233', '\234', '\235', '\236',
203   '\237', '\240', '\252', '\253', '\254', '\255', '\256', '\257',
204   '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
205   '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
206   '\312', '\313', '\314', '\315', '\316', '\317', '\332', '\333',
207   '\334', '\335', '\336', '\337', '\352', '\353', '\354', '\355',
208   '\356', '\357', '\372', '\373', '\374', '\375', '\376', '\377'
209 };
210
211 static char const ascii_to_ibm[] =
212 {
213   '\000', '\001', '\002', '\003', '\067', '\055', '\056', '\057',
214   '\026', '\005', '\045', '\013', '\014', '\015', '\016', '\017',
215   '\020', '\021', '\022', '\023', '\074', '\075', '\062', '\046',
216   '\030', '\031', '\077', '\047', '\034', '\035', '\036', '\037',
217   '\100', '\132', '\177', '\173', '\133', '\154', '\120', '\175',
218   '\115', '\135', '\134', '\116', '\153', '\140', '\113', '\141',
219   '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
220   '\370', '\371', '\172', '\136', '\114', '\176', '\156', '\157',
221   '\174', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
222   '\310', '\311', '\321', '\322', '\323', '\324', '\325', '\326',
223   '\327', '\330', '\331', '\342', '\343', '\344', '\345', '\346',
224   '\347', '\350', '\351', '\255', '\340', '\275', '\137', '\155',
225   '\171', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
226   '\210', '\211', '\221', '\222', '\223', '\224', '\225', '\226',
227   '\227', '\230', '\231', '\242', '\243', '\244', '\245', '\246',
228   '\247', '\250', '\251', '\300', '\117', '\320', '\241', '\007',
229   '\040', '\041', '\042', '\043', '\044', '\025', '\006', '\027',
230   '\050', '\051', '\052', '\053', '\054', '\011', '\012', '\033',
231   '\060', '\061', '\032', '\063', '\064', '\065', '\066', '\010',
232   '\070', '\071', '\072', '\073', '\004', '\024', '\076', '\341',
233   '\101', '\102', '\103', '\104', '\105', '\106', '\107', '\110',
234   '\111', '\121', '\122', '\123', '\124', '\125', '\126', '\127',
235   '\130', '\131', '\142', '\143', '\144', '\145', '\146', '\147',
236   '\150', '\151', '\160', '\161', '\162', '\163', '\164', '\165',
237   '\166', '\167', '\170', '\200', '\212', '\213', '\214', '\215',
238   '\216', '\217', '\220', '\232', '\233', '\234', '\235', '\236',
239   '\237', '\240', '\252', '\253', '\254', '\255', '\256', '\257',
240   '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
241   '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
242   '\312', '\313', '\314', '\315', '\316', '\317', '\332', '\333',
243   '\334', '\335', '\336', '\337', '\352', '\353', '\354', '\355',
244   '\356', '\357', '\372', '\373', '\374', '\375', '\376', '\377'
245 };
246
247 static char const ebcdic_to_ascii[] =
248 {
249   '\000', '\001', '\002', '\003', '\234', '\011', '\206', '\177',
250   '\227', '\215', '\216', '\013', '\014', '\015', '\016', '\017',
251   '\020', '\021', '\022', '\023', '\235', '\205', '\010', '\207',
252   '\030', '\031', '\222', '\217', '\034', '\035', '\036', '\037',
253   '\200', '\201', '\202', '\203', '\204', '\012', '\027', '\033',
254   '\210', '\211', '\212', '\213', '\214', '\005', '\006', '\007',
255   '\220', '\221', '\026', '\223', '\224', '\225', '\226', '\004',
256   '\230', '\231', '\232', '\233', '\024', '\025', '\236', '\032',
257   '\040', '\240', '\241', '\242', '\243', '\244', '\245', '\246',
258   '\247', '\250', '\133', '\056', '\074', '\050', '\053', '\041',
259   '\046', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
260   '\260', '\261', '\135', '\044', '\052', '\051', '\073', '\136',
261   '\055', '\057', '\262', '\263', '\264', '\265', '\266', '\267',
262   '\270', '\271', '\174', '\054', '\045', '\137', '\076', '\077',
263   '\272', '\273', '\274', '\275', '\276', '\277', '\300', '\301',
264   '\302', '\140', '\072', '\043', '\100', '\047', '\075', '\042',
265   '\303', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
266   '\150', '\151', '\304', '\305', '\306', '\307', '\310', '\311',
267   '\312', '\152', '\153', '\154', '\155', '\156', '\157', '\160',
268   '\161', '\162', '\313', '\314', '\315', '\316', '\317', '\320',
269   '\321', '\176', '\163', '\164', '\165', '\166', '\167', '\170',
270   '\171', '\172', '\322', '\323', '\324', '\325', '\326', '\327',
271   '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
272   '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
273   '\173', '\101', '\102', '\103', '\104', '\105', '\106', '\107',
274   '\110', '\111', '\350', '\351', '\352', '\353', '\354', '\355',
275   '\175', '\112', '\113', '\114', '\115', '\116', '\117', '\120',
276   '\121', '\122', '\356', '\357', '\360', '\361', '\362', '\363',
277   '\134', '\237', '\123', '\124', '\125', '\126', '\127', '\130',
278   '\131', '\132', '\364', '\365', '\366', '\367', '\370', '\371',
279   '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
280   '\070', '\071', '\372', '\373', '\374', '\375', '\376', '\377'
281 };
282
283 void
284 usage (int status)
285 {
286   if (status != 0)
287     fprintf (stderr, _("Try `%s --help' for more information.\n"),
288              program_name);
289   else
290     {
291       printf (_("Usage: %s [OPTION]...\n"), program_name);
292       fputs (_("\
293 Copy a file, converting and formatting according to the options.\n\
294 \n\
295   bs=BYTES        force ibs=BYTES and obs=BYTES\n\
296   cbs=BYTES       convert BYTES bytes at a time\n\
297   conv=KEYWORDS   convert the file as per the comma separated keyword list\n\
298   count=BLOCKS    copy only BLOCKS input blocks\n\
299   ibs=BYTES       read BYTES bytes at a time\n\
300 "), stdout);
301       fputs (_("\
302   if=FILE         read from FILE instead of stdin\n\
303   obs=BYTES       write BYTES bytes at a time\n\
304   of=FILE         write to FILE instead of stdout\n\
305   seek=BLOCKS     skip BLOCKS obs-sized blocks at start of output\n\
306   skip=BLOCKS     skip BLOCKS ibs-sized blocks at start of input\n\
307 "), stdout);
308       fputs (HELP_OPTION_DESCRIPTION, stdout);
309       fputs (VERSION_OPTION_DESCRIPTION, stdout);
310       fputs (_("\
311 \n\
312 BLOCKS and BYTES may be followed by the following multiplicative suffixes:\n\
313 xM M, c 1, w 2, b 512, kB 1000, K 1024, MB 1,000,000, M 1,048,576,\n\
314 GB 1,000,000,000, G 1,073,741,824, and so on for T, P, E, Z, Y.\n\
315 Each KEYWORD may be:\n\
316 \n\
317 "), stdout);
318       fputs (_("\
319   ascii     from EBCDIC to ASCII\n\
320   ebcdic    from ASCII to EBCDIC\n\
321   ibm       from ASCII to alternated EBCDIC\n\
322   block     pad newline-terminated records with spaces to cbs-size\n\
323   unblock   replace trailing spaces in cbs-size records with newline\n\
324   lcase     change upper case to lower case\n\
325 "), stdout);
326       fputs (_("\
327   notrunc   do not truncate the output file\n\
328   ucase     change lower case to upper case\n\
329   swab      swap every pair of input bytes\n\
330   noerror   continue after read errors\n\
331   sync      pad every input block with NULs to ibs-size; when used\n\
332               with block or unblock, pad with spaces rather than NULs\n\
333 "), stdout);
334       printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
335     }
336   exit (status);
337 }
338
339 static void
340 translate_charset (char const *new_trans)
341 {
342   int i;
343
344   for (i = 0; i < 256; i++)
345     trans_table[i] = new_trans[trans_table[i]];
346   translation_needed = 1;
347 }
348
349 /* Return the number of 1 bits in `i'. */
350
351 static int
352 bit_count (register int i)
353 {
354   register int set_bits;
355
356   for (set_bits = 0; i != 0; set_bits++)
357     i &= i - 1;
358   return set_bits;
359 }
360
361 static void
362 print_stats (void)
363 {
364   char buf[2][LONGEST_HUMAN_READABLE + 1];
365   fprintf (stderr, _("%s+%s records in\n"),
366            human_readable (r_full, buf[0], 1, 1),
367            human_readable (r_partial, buf[1], 1, 1));
368   fprintf (stderr, _("%s+%s records out\n"),
369            human_readable (w_full, buf[0], 1, 1),
370            human_readable (w_partial, buf[1], 1, 1));
371   if (r_truncate > 0)
372     {
373       fprintf (stderr, "%s %s\n",
374                human_readable (r_truncate, buf[0], 1, 1),
375                (r_truncate == 1
376                 ? _("truncated record")
377                 : _("truncated records")));
378     }
379 }
380
381 static void
382 cleanup (void)
383 {
384   print_stats ();
385   if (close (STDIN_FILENO) < 0)
386     error (EXIT_FAILURE, errno,
387            _("closing input file %s"), quote (input_file));
388   if (close (STDOUT_FILENO) < 0)
389     error (EXIT_FAILURE, errno,
390            _("closing output file %s"), quote (output_file));
391 }
392
393 static inline void
394 quit (int code)
395 {
396   cleanup ();
397   exit (code);
398 }
399
400 static RETSIGTYPE
401 interrupt_handler (int sig)
402 {
403 #ifdef SA_NOCLDSTOP
404   struct sigaction sigact;
405
406   sigact.sa_handler = SIG_DFL;
407   sigemptyset (&sigact.sa_mask);
408   sigact.sa_flags = 0;
409   sigaction (sig, &sigact, NULL);
410 #else
411   signal (sig, SIG_DFL);
412 #endif
413   cleanup ();
414   kill (getpid (), sig);
415 }
416
417 static RETSIGTYPE
418 siginfo_handler (int sig ATTRIBUTE_UNUSED)
419 {
420   print_stats ();
421 }
422
423 /* Encapsulate portability mess of establishing signal handlers.  */
424
425 static void
426 install_handler (int sig_num, RETSIGTYPE (*sig_handler) (int sig))
427 {
428 #ifdef SA_NOCLDSTOP
429   struct sigaction sigact;
430   sigaction (sig_num, NULL, &sigact);
431   if (sigact.sa_handler != SIG_IGN)
432     {
433       sigact.sa_handler = sig_handler;
434       sigemptyset (&sigact.sa_mask);
435       sigact.sa_flags = 0;
436       sigaction (sig_num, &sigact, NULL);
437     }
438 #else
439   if (signal (sig_num, SIG_IGN) != SIG_IGN)
440     signal (sig_num, sig_handler);
441 #endif
442 }
443
444 /* Open a file to a particular file descriptor.  This is like standard
445    `open', except it always returns DESIRED_FD if successful.  */
446 static int
447 open_fd (int desired_fd, char const *filename, int options, mode_t mode)
448 {
449   int fd;
450   close (desired_fd);
451   fd = open (filename, options, mode);
452   if (fd < 0)
453     return -1;
454
455   if (fd != desired_fd)
456     {
457       if (dup2 (fd, desired_fd) != desired_fd)
458         desired_fd = -1;
459       if (close (fd) != 0)
460         return -1;
461     }
462
463   return desired_fd;
464 }
465
466 /* Write, then empty, the output buffer `obuf'. */
467
468 static void
469 write_output (void)
470 {
471   size_t nwritten = full_write (STDOUT_FILENO, obuf, output_blocksize);
472   if (nwritten != output_blocksize)
473     {
474       error (0, errno, _("writing to %s"), quote (output_file));
475       if (nwritten != 0)
476         w_partial++;
477       quit (1);
478     }
479   else
480     w_full++;
481   oc = 0;
482 }
483
484 /* Interpret one "conv=..." option.
485    As a by product, this function replaces each `,' in STR with a NUL byte.  */
486
487 static void
488 parse_conversion (char *str)
489 {
490   char *new;
491   int i;
492
493   do
494     {
495       new = strchr (str, ',');
496       if (new != NULL)
497         *new++ = '\0';
498       for (i = 0; conversions[i].convname != NULL; i++)
499         if (STREQ (conversions[i].convname, str))
500           {
501             conversions_mask |= conversions[i].conversion;
502             break;
503           }
504       if (conversions[i].convname == NULL)
505         {
506           error (0, 0, _("invalid conversion: %s"), quote (str));
507           usage (EXIT_FAILURE);
508         }
509       str = new;
510   } while (new != NULL);
511 }
512
513 /* Return the value of STR, interpreted as a non-negative decimal integer,
514    optionally multiplied by various values.
515    Assign nonzero to *INVALID if STR does not represent a number in
516    this format. */
517
518 static uintmax_t
519 parse_integer (const char *str, int *invalid)
520 {
521   uintmax_t n;
522   char *suffix;
523   enum strtol_error e = xstrtoumax (str, &suffix, 10, &n, "bcEGkKMPTwYZ0");
524
525   if (e == LONGINT_INVALID_SUFFIX_CHAR && *suffix == 'x')
526     {
527       uintmax_t multiplier = parse_integer (suffix + 1, invalid);
528
529       if (multiplier != 0 && n * multiplier / multiplier != n)
530         {
531           *invalid = 1;
532           return 0;
533         }
534
535       n *= multiplier;
536     }
537   else if (e != LONGINT_OK)
538     {
539       *invalid = 1;
540       return 0;
541     }
542
543   return n;
544 }
545
546 static void
547 scanargs (int argc, char **argv)
548 {
549   int i;
550
551   --argc;
552   ++argv;
553
554   for (i = optind; i < argc; i++)
555     {
556       char *name, *val;
557
558       name = argv[i];
559       val = strchr (name, '=');
560       if (val == NULL)
561         {
562           error (0, 0, _("unrecognized option %s"), quote (name));
563           usage (EXIT_FAILURE);
564         }
565       *val++ = '\0';
566
567       if (STREQ (name, "if"))
568         input_file = val;
569       else if (STREQ (name, "of"))
570         output_file = val;
571       else if (STREQ (name, "conv"))
572         parse_conversion (val);
573       else
574         {
575           int invalid = 0;
576           uintmax_t n = parse_integer (val, &invalid);
577
578           if (STREQ (name, "ibs"))
579             {
580               input_blocksize = n;
581               invalid |= input_blocksize != n || input_blocksize == 0;
582               conversions_mask |= C_TWOBUFS;
583             }
584           else if (STREQ (name, "obs"))
585             {
586               output_blocksize = n;
587               invalid |= output_blocksize != n || output_blocksize == 0;
588               conversions_mask |= C_TWOBUFS;
589             }
590           else if (STREQ (name, "bs"))
591             {
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           ssize_t nread = safe_read (fdesc, buf, blocksize);
813           if (nread < 0)
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   ssize_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 < 0)
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   program_name = argv[0];
1144   setlocale (LC_ALL, "");
1145   bindtextdomain (PACKAGE, LOCALEDIR);
1146   textdomain (PACKAGE);
1147
1148   /* Arrange to close stdout if parse_long_options exits.  */
1149   atexit (close_stdout_wrapper);
1150
1151   parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE, VERSION,
1152                       AUTHORS, usage);
1153
1154   /* Don't close stdout on exit from here on.  */
1155   closeout_func = NULL;
1156
1157   /* Initialize translation table to identity translation. */
1158   for (i = 0; i < 256; i++)
1159     trans_table[i] = i;
1160
1161   /* Decode arguments. */
1162   scanargs (argc, argv);
1163
1164   apply_translations ();
1165
1166   if (input_file != NULL)
1167     {
1168       if (open_fd (STDIN_FILENO, input_file, O_RDONLY, 0) < 0)
1169         error (EXIT_FAILURE, errno, _("opening %s"), quote (input_file));
1170     }
1171   else
1172     input_file = _("standard input");
1173
1174   if (output_file != NULL)
1175     {
1176       mode_t perms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
1177       int opts
1178         = (O_CREAT
1179            | (seek_records || (conversions_mask & C_NOTRUNC) ? 0 : O_TRUNC));
1180
1181       /* Open the output file with *read* access only if we might
1182          need to read to satisfy a `seek=' request.  If we can't read
1183          the file, go ahead with write-only access; it might work.  */
1184       if ((! seek_records
1185            || open_fd (STDOUT_FILENO, output_file, O_RDWR | opts, perms) < 0)
1186           && open_fd (STDOUT_FILENO, output_file, O_WRONLY | opts, perms) < 0)
1187         error (EXIT_FAILURE, errno, _("opening %s"), quote (output_file));
1188
1189 #if HAVE_FTRUNCATE
1190       if (seek_records != 0 && !(conversions_mask & C_NOTRUNC))
1191         {
1192           struct stat stdout_stat;
1193           off_t o = seek_records * output_blocksize;
1194           if ((uintmax_t) o / output_blocksize != seek_records)
1195             error (EXIT_FAILURE, 0, _("file offset out of range"));
1196
1197           if (fstat (STDOUT_FILENO, &stdout_stat) != 0)
1198             error (EXIT_FAILURE, errno, _("cannot fstat %s"),
1199                    quote (output_file));
1200
1201           /* Complain only when ftruncate fails on a regular file, a
1202              directory, or a shared memory object, as the 2000-08
1203              POSIX draft specifies ftruncate's behavior only for these
1204              file types.  For example, do not complain when Linux 2.4
1205              ftruncate fails on /dev/fd0.  */
1206           if (ftruncate (STDOUT_FILENO, o) != 0
1207               && (S_ISREG (stdout_stat.st_mode)
1208                   || S_ISDIR (stdout_stat.st_mode)
1209                   || S_TYPEISSHM (&stdout_stat)))
1210             {
1211               char buf[LONGEST_HUMAN_READABLE + 1];
1212               error (EXIT_FAILURE, errno,
1213                      _("advancing past %s bytes in output file %s"),
1214                      human_readable (o, buf, 1, 1),
1215                      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 }