.
[coreutils.git] / src / dd.c
blob36a0f2288e934a7a2614a719ca3819c9e11474bb
1 /* dd -- convert a file while copying it.
2 Copyright (C) 1985, 1990, 1991, 1995 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18 /* Written by Paul Rubin, David MacKenzie, and Stuart Kemp. */
20 /* Options:
22 Numbers can be followed by a multiplier:
23 b=512, c=1, k=1024, w=2, xm=number m
25 if=FILE Read from FILE instead of stdin.
26 of=FILE Write to FILE instead of stdout; don't
27 truncate FILE.
28 ibs=BYTES Read BYTES bytes at a time.
29 obs=BYTES Write BYTES bytes at a time.
30 bs=BYTES Override ibs and obs.
31 cbs=BYTES Convert BYTES bytes at a time.
32 skip=BLOCKS Skip BLOCKS ibs-sized blocks at
33 start of input.
34 seek=BLOCKS Skip BLOCKS obs-sized blocks at
35 start of output.
36 count=BLOCKS Copy only BLOCKS input blocks.
37 conv=CONVERSION[,CONVERSION...]
39 Conversions:
40 ascii Convert EBCDIC to ASCII.
41 ebcdic Convert ASCII to EBCDIC.
42 ibm Convert ASCII to alternate EBCDIC.
43 block Pad newline-terminated records to size of
44 cbs, replacing newline with trailing spaces.
45 unblock Replace trailing spaces in cbs-sized block
46 with newline.
47 lcase Change upper case characters to lower case.
48 ucase Change lower case characters to upper case.
49 swab Swap every pair of input bytes.
50 Unlike the Unix dd, this works when an odd
51 number of bytes are read.
52 noerror Continue after read errors.
53 sync Pad every input block to size of ibs with
54 trailing NULs. */
56 #include <config.h>
57 #include <stdio.h>
59 #define SWAB_ALIGN_OFFSET 2
61 #include <sys/types.h>
62 #include <signal.h>
63 #include <getopt.h>
65 #include "system.h"
66 #include "version.h"
67 #include "error.h"
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)
76 /* Default input and output blocksize. */
77 #define DEFAULT_BLOCKSIZE 512
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
94 char *xmalloc ();
95 int safe_read ();
96 int full_write ();
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 ();
115 /* The name this program was run with. */
116 char *program_name;
118 /* The name of the input file, or NULL for the standard input. */
119 static char *input_file = NULL;
121 /* The input file descriptor. */
122 static int input_fd = 0;
124 /* The name of the output file, or NULL for the standard output. */
125 static char *output_file = NULL;
127 /* The output file descriptor. */
128 static int output_fd = 1;
130 /* The number of bytes in which atomic reads are done. */
131 static long input_blocksize = -1;
133 /* The number of bytes in which atomic writes are done. */
134 static long output_blocksize = -1;
136 /* Conversion buffer size, in bytes. 0 prevents conversions. */
137 static long conversion_blocksize = 0;
139 /* Skip this many records of `input_blocksize' bytes before input. */
140 static long skip_records = 0;
142 /* Skip this many records of `output_blocksize' bytes before output. */
143 static long seek_record = 0;
145 /* Copy only this many records. <0 means no limit. */
146 static int max_records = -1;
148 /* Bit vector of conversions to apply. */
149 static int conversions_mask = 0;
151 /* If nonzero, filter characters through the translation table. */
152 static int translation_needed = 0;
154 /* Number of partial blocks written. */
155 static unsigned w_partial = 0;
157 /* Number of full blocks written. */
158 static unsigned w_full = 0;
160 /* Number of partial blocks read. */
161 static unsigned r_partial = 0;
163 /* Number of full blocks read. */
164 static unsigned r_full = 0;
166 /* Records truncated by conv=block. */
167 static unsigned r_truncate = 0;
169 /* Output representation of newline and space characters.
170 They change if we're converting to EBCDIC. */
171 static unsigned char newline_character = '\n';
172 static unsigned char space_character = ' ';
174 struct conversion
176 char *convname;
177 int conversion;
180 static struct conversion conversions[] =
182 {"ascii", C_ASCII | C_TWOBUFS}, /* EBCDIC to ASCII. */
183 {"ebcdic", C_EBCDIC | C_TWOBUFS}, /* ASCII to EBCDIC. */
184 {"ibm", C_IBM | C_TWOBUFS}, /* Slightly different ASCII to EBCDIC. */
185 {"block", C_BLOCK | C_TWOBUFS}, /* Variable to fixed length records. */
186 {"unblock", C_UNBLOCK | C_TWOBUFS}, /* Fixed to variable length records. */
187 {"lcase", C_LCASE | C_TWOBUFS}, /* Translate upper to lower case. */
188 {"ucase", C_UCASE | C_TWOBUFS}, /* Translate lower to upper case. */
189 {"swab", C_SWAB | C_TWOBUFS}, /* Swap bytes of input. */
190 {"noerror", C_NOERROR}, /* Ignore i/o errors. */
191 {"notrunc", C_NOTRUNC}, /* Do not truncate output file. */
192 {"sync", C_SYNC}, /* Pad input records to ibs with NULs. */
193 {NULL, 0}
196 /* Translation table formed by applying successive transformations. */
197 static unsigned char trans_table[256];
199 static unsigned char const ascii_to_ebcdic[] =
201 0, 01, 02, 03, 067, 055, 056, 057,
202 026, 05, 045, 013, 014, 015, 016, 017,
203 020, 021, 022, 023, 074, 075, 062, 046,
204 030, 031, 077, 047, 034, 035, 036, 037,
205 0100, 0117, 0177, 0173, 0133, 0154, 0120, 0175,
206 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
207 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
208 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
209 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
210 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
211 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
212 0347, 0350, 0351, 0112, 0340, 0132, 0137, 0155,
213 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
214 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
215 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
216 0247, 0250, 0251, 0300, 0152, 0320, 0241, 07,
217 040, 041, 042, 043, 044, 025, 06, 027,
218 050, 051, 052, 053, 054, 011, 012, 033,
219 060, 061, 032, 063, 064, 065, 066, 010,
220 070, 071, 072, 073, 04, 024, 076, 0341,
221 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
222 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
223 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
224 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
225 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
226 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
227 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
228 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
229 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
230 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
231 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
232 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377
235 static unsigned char const ascii_to_ibm[] =
237 0, 01, 02, 03, 067, 055, 056, 057,
238 026, 05, 045, 013, 014, 015, 016, 017,
239 020, 021, 022, 023, 074, 075, 062, 046,
240 030, 031, 077, 047, 034, 035, 036, 037,
241 0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175,
242 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
243 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
244 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
245 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
246 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
247 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
248 0347, 0350, 0351, 0255, 0340, 0275, 0137, 0155,
249 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
250 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
251 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
252 0247, 0250, 0251, 0300, 0117, 0320, 0241, 07,
253 040, 041, 042, 043, 044, 025, 06, 027,
254 050, 051, 052, 053, 054, 011, 012, 033,
255 060, 061, 032, 063, 064, 065, 066, 010,
256 070, 071, 072, 073, 04, 024, 076, 0341,
257 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
258 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
259 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
260 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
261 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
262 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
263 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
264 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
265 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
266 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
267 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
268 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377
271 static unsigned char const ebcdic_to_ascii[] =
273 0, 01, 02, 03, 0234, 011, 0206, 0177,
274 0227, 0215, 0216, 013, 014, 015, 016, 017,
275 020, 021, 022, 023, 0235, 0205, 010, 0207,
276 030, 031, 0222, 0217, 034, 035, 036, 037,
277 0200, 0201, 0202, 0203, 0204, 012, 027, 033,
278 0210, 0211, 0212, 0213, 0214, 05, 06, 07,
279 0220, 0221, 026, 0223, 0224, 0225, 0226, 04,
280 0230, 0231, 0232, 0233, 024, 025, 0236, 032,
281 040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
282 0247, 0250, 0133, 056, 074, 050, 053, 041,
283 046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
284 0260, 0261, 0135, 044, 052, 051, 073, 0136,
285 055, 057, 0262, 0263, 0264, 0265, 0266, 0267,
286 0270, 0271, 0174, 054, 045, 0137, 076, 077,
287 0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
288 0302, 0140, 072, 043, 0100, 047, 075, 042,
289 0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
290 0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
291 0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
292 0161, 0162, 0313, 0314, 0315, 0316, 0317, 0320,
293 0321, 0176, 0163, 0164, 0165, 0166, 0167, 0170,
294 0171, 0172, 0322, 0323, 0324, 0325, 0326, 0327,
295 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
296 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
297 0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
298 0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
299 0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
300 0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
301 0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
302 0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
303 060, 061, 062, 063, 064, 065, 066, 067,
304 070, 071, 0372, 0373, 0374, 0375, 0376, 0377
307 /* If non-zero, display usage information and exit. */
308 static int show_help;
310 /* If non-zero, print the version on standard output and exit. */
311 static int show_version;
313 static struct option const long_options[] =
315 {"help", no_argument, &show_help, 1},
316 {"version", no_argument, &show_version, 1},
317 {0, 0, 0, 0}
320 void
321 main (argc, argv)
322 int argc;
323 char **argv;
325 #ifdef _POSIX_VERSION
326 struct sigaction sigact;
327 #endif /* _POSIX_VERSION */
328 int i;
330 program_name = argv[0];
332 /* Initialize translation table to identity translation. */
333 for (i = 0; i < 256; i++)
334 trans_table[i] = i;
336 /* Decode arguments. */
337 scanargs (argc, argv);
339 if (show_version)
341 printf ("dd - %s\n", version_string);
342 exit (0);
345 if (show_help)
346 usage (0);
348 apply_translations ();
350 if (input_file != NULL)
352 input_fd = open (input_file, O_RDONLY);
353 if (input_fd < 0)
354 error (1, errno, "%s", input_file);
356 else
357 input_file = "standard input";
359 if (input_fd == output_fd)
360 error (1, 0, "standard %s is closed", input_fd == 0 ? "input" : "output");
362 if (output_file != NULL)
364 int omode = O_RDWR | O_CREAT;
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))
374 if (ftruncate (output_fd, seek_record * output_blocksize) < 0)
375 error (0, errno, "%s", output_file);
377 #endif
379 else
380 output_file = "standard output";
382 #ifdef _POSIX_VERSION
383 sigaction (SIGINT, NULL, &sigact);
384 if (sigact.sa_handler != SIG_IGN)
386 sigact.sa_handler = interrupt_handler;
387 sigemptyset (&sigact.sa_mask);
388 sigact.sa_flags = 0;
389 sigaction (SIGINT, &sigact, NULL);
391 sigaction (SIGPIPE, NULL, &sigact);
392 if (sigact.sa_handler != SIG_IGN)
394 sigact.sa_handler = interrupt_handler;
395 sigemptyset (&sigact.sa_mask);
396 sigact.sa_flags = 0;
397 sigaction (SIGPIPE, &sigact, NULL);
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 ();
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. */
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;
420 struct stat stats;
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))
428 error (0, errno, "%s", file);
429 quit (1);
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))
437 if (lseek (fdesc, records * blocksize, SEEK_SET) < 0)
439 error (0, errno, "%s", file);
440 quit (1);
443 else
445 while (records-- > 0)
447 int nread;
449 nread = safe_read (fdesc, buf, blocksize);
450 if (nread < 0)
452 error (0, errno, "%s", file);
453 quit (1);
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;
464 /* Apply the character-set translations specified by the user
465 to the NREAD bytes in BUF. */
467 static void
468 translate_buffer (buf, nread)
469 unsigned char *buf;
470 int nread;
472 register unsigned char *cp;
473 register int i;
475 for (i = nread, cp = buf; i; i--, cp++)
476 *cp = trans_table[*cp];
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;
483 /* Odd char from previous call. */
484 static unsigned char saved_char;
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. */
490 static unsigned char *
491 swab_buffer (buf, nread)
492 unsigned char *buf;
493 int *nread;
495 unsigned char *bufstart = buf;
496 register unsigned char *cp;
497 register int i;
499 /* Is a char left from last time? */
500 if (char_is_saved)
502 *--bufstart = saved_char;
503 (*nread)++;
504 char_is_saved = 0;
507 if (*nread & 1)
509 /* An odd number of chars are in the buffer. */
510 saved_char = bufstart[--*nread];
511 char_is_saved = 1;
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. */
518 cp = bufstart + *nread; /* Start one char past the last. */
519 for (i = *nread / 2; i; i--, cp -= 2)
520 *cp = *(cp - 2);
522 return ++bufstart;
525 /* Output buffer. */
526 static unsigned char *obuf;
528 /* Current index into `obuf'. */
529 static int oc = 0;
531 /* Index into current line, for `conv=block' and `conv=unblock'. */
532 static int col = 0;
534 /* The main loop. */
536 static void
537 copy ()
539 unsigned char *ibuf, *bufstart; /* Input buffer. */
540 int nread; /* Bytes read in the current block. */
541 int exit_status = 0;
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. */
548 ibuf = (unsigned char *) xmalloc (input_blocksize + 2 * SWAB_ALIGN_OFFSET);
549 ibuf += SWAB_ALIGN_OFFSET;
551 if (conversions_mask & C_TWOBUFS)
552 obuf = (unsigned char *) xmalloc (output_blocksize);
553 else
554 obuf = ibuf;
556 if (skip_records > 0)
557 skip (input_fd, input_file, skip_records, input_blocksize, ibuf);
559 if (seek_record > 0)
560 skip (output_fd, output_file, seek_record, output_blocksize, obuf);
562 if (max_records == 0)
563 quit (exit_status);
565 while (1)
567 if (max_records >= 0 && r_partial + r_full >= max_records)
568 break;
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);
576 nread = safe_read (input_fd, ibuf, input_blocksize);
578 if (nread == 0)
579 break; /* EOF. */
581 if (nread < 0)
583 error (0, errno, "%s", input_file);
584 if (conversions_mask & C_NOERROR)
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;
596 else
598 /* Write any partial block. */
599 exit_status = 2;
600 break;
604 if (nread < input_blocksize)
606 r_partial++;
607 if (conversions_mask & C_SYNC)
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;
615 else
616 r_full++;
618 if (ibuf == obuf) /* If not C_TWOBUFS. */
620 int nwritten = full_write (output_fd, obuf, nread);
621 if (nwritten != nread)
623 error (0, errno, "%s", output_file);
624 if (nwritten > 0)
625 w_partial++;
626 quit (1);
628 else if (nread == input_blocksize)
629 w_full++;
630 else
631 w_partial++;
632 continue;
635 /* Do any translations on the whole buffer at once. */
637 if (translation_needed)
638 translate_buffer (ibuf, nread);
640 if (conversions_mask & C_SWAB)
641 bufstart = swab_buffer (ibuf, &nread);
642 else
643 bufstart = ibuf;
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);
653 /* If we have a char left as a result of conv=swab, output it. */
654 if (char_is_saved)
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);
664 if ((conversions_mask & C_BLOCK) && col > 0)
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)
671 output_char (space_character);
672 --pending_spaces;
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);
681 /* Write out the last block. */
682 if (oc > 0)
684 int nwritten = full_write (output_fd, obuf, oc);
685 if (nwritten > 0)
686 w_partial++;
687 if (nwritten != oc)
689 error (0, errno, "%s", output_file);
690 quit (1);
694 free (ibuf - SWAB_ALIGN_OFFSET);
695 if (obuf != ibuf)
696 free (obuf);
698 quit (exit_status);
701 /* Copy NREAD bytes of BUF, with no conversions. */
703 static void
704 copy_simple (buf, nread)
705 unsigned char *buf;
706 int nread;
708 int nfree; /* Number of unused bytes in `obuf'. */
709 unsigned char *start = buf; /* First uncopied char in BUF. */
713 nfree = output_blocksize - oc;
714 if (nfree > nread)
715 nfree = nread;
717 memcpy (obuf + oc, start, nfree);
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 ();
725 while (nread > 0);
728 /* Copy NREAD bytes of BUF, doing conv=block
729 (pad newline-terminated records to `conversion_blocksize',
730 replacing the newline with trailing spaces). */
732 static void
733 copy_with_block (buf, nread)
734 unsigned char *buf;
735 int nread;
737 register int i;
739 for (i = nread; i; i--, buf++)
741 if (*buf == newline_character)
743 int pending_spaces = max (0, conversion_blocksize - col);
744 while (pending_spaces)
746 output_char (space_character);
747 --pending_spaces;
749 col = 0;
751 else
753 if (col == conversion_blocksize)
754 r_truncate++;
755 else if (col < conversion_blocksize)
756 output_char (*buf);
757 col++;
762 /* Copy NREAD bytes of BUF, doing conv=unblock
763 (replace trailing spaces in `conversion_blocksize'-sized records
764 with a newline). */
766 static void
767 copy_with_unblock (buf, nread)
768 unsigned char *buf;
769 int nread;
771 register int i;
772 register unsigned char c;
773 static int pending_spaces = 0;
775 for (i = 0; i < nread; i++)
777 c = buf[i];
779 if (col++ >= conversion_blocksize)
781 col = pending_spaces = 0; /* Wipe out any pending spaces. */
782 i--; /* Push the char back; get it later. */
783 output_char (newline_character);
785 else if (c == space_character)
786 pending_spaces++;
787 else
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)
793 output_char (space_character);
794 --pending_spaces;
796 output_char (c);
801 /* Write, then empty, the output buffer `obuf'. */
803 static void
804 write_output ()
806 int nwritten = full_write (output_fd, obuf, output_blocksize);
807 if (nwritten != output_blocksize)
809 error (0, errno, "%s", output_file);
810 if (nwritten > 0)
811 w_partial++;
812 quit (1);
814 else
815 w_full++;
816 oc = 0;
819 static void
820 scanargs (argc, argv)
821 int argc;
822 char **argv;
824 int i, n;
825 int c;
827 while ((c = getopt_long (argc, argv, "", long_options, (int *) 0)) != EOF)
829 switch (c)
831 case 0:
832 break;
834 default:
835 usage (1);
839 for (i = optind; i < argc; i++)
841 char *name, *val;
843 name = argv[i];
844 val = strchr (name, '=');
845 if (val == NULL)
847 error (0, 0, "unrecognized option `%s'", name);
848 usage (1);
850 *val++ = '\0';
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
860 n = parse_integer (val);
861 if (n < 0)
862 error (1, 0, "invalid number `%s'", val);
864 if (equal (name, "ibs"))
866 input_blocksize = n;
867 conversions_mask |= C_TWOBUFS;
869 else if (equal (name, "obs"))
871 output_blocksize = n;
872 conversions_mask |= C_TWOBUFS;
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
886 error (0, 0, "unrecognized option `%s=%s'", name, val);
887 usage (1);
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);
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. */
909 /* FIXME: use xstrtou?l */
911 static int
912 parse_integer (str)
913 char *str;
915 register int n = 0;
916 register int temp;
917 register char *p = str;
919 while (ISDIGIT (*p))
921 n = n * 10 + *p - '0';
922 p++;
924 loop:
925 switch (*p++)
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;
949 return n;
952 /* Interpret one "conv=..." option. */
954 static void
955 parse_conversion (str)
956 char *str;
958 char *new;
959 int i;
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))
969 conversions_mask |= conversions[i].conversion;
970 break;
972 if (conversions[i].convname == NULL)
974 error (0, 0, "%s: invalid conversion", str);
975 usage (1);
977 str = new;
978 } while (new != NULL);
981 /* Fix up translation table. */
983 static void
984 apply_translations ()
986 int i;
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))
994 error (1, 0, "\
995 only one conv in {ascii,ebcdic,ibm}, {lcase,ucase}, {block,unblock}, {unblock,sync}");
997 #undef MX
999 if (conversions_mask & C_ASCII)
1000 translate_charset (ebcdic_to_ascii);
1002 if (conversions_mask & C_UCASE)
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;
1009 else if (conversions_mask & C_LCASE)
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;
1017 if (conversions_mask & C_EBCDIC)
1019 translate_charset (ascii_to_ebcdic);
1020 newline_character = ascii_to_ebcdic['\n'];
1021 space_character = ascii_to_ebcdic[' '];
1023 else if (conversions_mask & C_IBM)
1025 translate_charset (ascii_to_ibm);
1026 newline_character = ascii_to_ibm['\n'];
1027 space_character = ascii_to_ibm[' '];
1031 static void
1032 translate_charset (new_trans)
1033 unsigned char *new_trans;
1035 int i;
1037 for (i = 0; i < 256; i++)
1038 trans_table[i] = new_trans[trans_table[i]];
1039 translation_needed = 1;
1042 /* Return the number of 1 bits in `i'. */
1044 static int
1045 bit_count (i)
1046 register unsigned int i;
1048 register int set_bits;
1050 for (set_bits = 0; i != 0; set_bits++)
1051 i &= i - 1;
1052 return set_bits;
1055 static void
1056 print_stats ()
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");
1065 static void
1066 quit (code)
1067 int code;
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);
1078 static RETSIGTYPE
1079 interrupt_handler ()
1081 quit (1);
1084 static void
1085 usage (status)
1086 int status;
1088 if (status != 0)
1089 fprintf (stderr, "Try `%s --help' for more information.\n",
1090 program_name);
1091 else
1093 printf ("Usage: %s [OPTION]...\n", program_name);
1094 printf ("\
1095 Copy a file, converting and formatting according to the options.\n\
1097 bs=BYTES force ibs=BYTES and obs=BYTES\n\
1098 cbs=BYTES convert BYTES bytes at a time\n\
1099 conv=KEYWORDS convert the file as per the comma separated keyword list\n\
1100 count=BLOCKS copy only BLOCKS input blocks\n\
1101 ibs=BYTES read BYTES bytes at a time\n\
1102 if=FILE read from FILE instead of stdin\n\
1103 obs=BYTES write BYTES bytes at a time\n\
1104 of=FILE write to FILE instead of stdout, don't truncate file\n\
1105 seek=BLOCKS skip BLOCKS obs-sized blocks at start of output\n\
1106 skip=BLOCKS skip BLOCKS ibs-sized blocks at start of input\n\
1107 --help display this help and exit\n\
1108 --version output version information and exit\n\
1110 BYTES may be suffixed: by xM for multiplication by M, by c for x1,\n\
1111 by w for x2, by b for x512, by k for x1024. Each KEYWORD may be:\n\
1113 ascii from EBCDIC to ASCII\n\
1114 ebcdic from ASCII to EBCDIC\n\
1115 ibm from ASCII to alternated EBCDIC\n\
1116 block pad newline-terminated records with spaces to cbs-size \n\
1117 unblock replace trailing spaces in cbs-size records with newline\n\
1118 lcase change upper case to lower case\n\
1119 ucase change lower case to upper case\n\
1120 swab swap every pair of input bytes\n\
1121 noerror continue after read errors\n\
1122 sync pad every input block with NULs to ibs-size\n");
1124 exit (status);