source: trunk/essentials/app-arch/cpio/src/util.c

Last change on this file was 3332, checked in by bird, 18 years ago

cpio 2.7

File size: 35.6 KB
Line 
1/* util.c - Several utility routines for cpio.
2 Copyright (C) 1990, 1991, 1992, 2001, 2004,
3 2006 Free Software Foundation, Inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public
16 License along with this program; if not, write to the Free
17 Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301 USA. */
19
20#include <system.h>
21
22#include <stdio.h>
23#include <sys/types.h>
24#include <sys/stat.h>
25#include "cpiohdr.h"
26#include "dstring.h"
27#include "extern.h"
28#include <paxlib.h>
29#include "filetypes.h"
30#include <safe-read.h>
31#include <full-write.h>
32#include <rmt.h>
33#include <hash.h>
34#include <utimens.h>
35
36#include <sys/ioctl.h>
37
38#ifdef HAVE_SYS_MTIO_H
39# ifdef HAVE_SYS_IO_TRIOCTL_H
40# include <sys/io/trioctl.h>
41# endif
42# include <sys/mtio.h>
43#endif
44
45#if !HAVE_DECL_ERRNO
46extern int errno;
47#endif
48
49/* Write `output_size' bytes of `output_buffer' to file
50 descriptor OUT_DES and reset `output_size' and `out_buff'. */
51
52void
53tape_empty_output_buffer (int out_des)
54{
55 int bytes_written;
56
57#ifdef BROKEN_LONG_TAPE_DRIVER
58 static long output_bytes_before_lseek = 0;
59
60 /* Some tape drivers seem to have a signed internal seek pointer and
61 they lose if it overflows and becomes negative (e.g. when writing
62 tapes > 2Gb). Doing an lseek (des, 0, SEEK_SET) seems to reset the
63 seek pointer and prevent it from overflowing. */
64 if (output_is_special
65 && ( (output_bytes_before_lseek += output_size) >= 1073741824L) )
66 {
67 lseek(out_des, 0L, SEEK_SET);
68 output_bytes_before_lseek = 0;
69 }
70#endif
71
72 bytes_written = rmtwrite (out_des, output_buffer, output_size);
73 if (bytes_written != output_size)
74 {
75 int rest_bytes_written;
76 int rest_output_size;
77
78 if (output_is_special
79 && (bytes_written >= 0
80 || (bytes_written < 0
81 && (errno == ENOSPC || errno == EIO || errno == ENXIO))))
82 {
83 get_next_reel (out_des);
84 if (bytes_written > 0)
85 rest_output_size = output_size - bytes_written;
86 else
87 rest_output_size = output_size;
88 rest_bytes_written = rmtwrite (out_des, output_buffer,
89 rest_output_size);
90 if (rest_bytes_written != rest_output_size)
91 error (1, errno, _("write error"));
92 }
93 else
94 error (1, errno, _("write error"));
95 }
96 output_bytes += output_size;
97 out_buff = output_buffer;
98 output_size = 0;
99}
100
101/* Write `output_size' bytes of `output_buffer' to file
102 descriptor OUT_DES and reset `output_size' and `out_buff'.
103 If `swapping_halfwords' or `swapping_bytes' is set,
104 do the appropriate swapping first. Our callers have
105 to make sure to only set these flags if `output_size'
106 is appropriate (a multiple of 4 for `swapping_halfwords',
107 2 for `swapping_bytes'). The fact that DISK_IO_BLOCK_SIZE
108 must always be a multiple of 4 helps us (and our callers)
109 insure this. */
110
111void
112disk_empty_output_buffer (int out_des)
113{
114 int bytes_written;
115
116 if (swapping_halfwords || swapping_bytes)
117 {
118 if (swapping_halfwords)
119 {
120 int complete_words;
121 complete_words = output_size / 4;
122 swahw_array (output_buffer, complete_words);
123 if (swapping_bytes)
124 swab_array (output_buffer, 2 * complete_words);
125 }
126 else
127 {
128 int complete_halfwords;
129 complete_halfwords = output_size /2;
130 swab_array (output_buffer, complete_halfwords);
131 }
132 }
133
134 if (sparse_flag)
135 bytes_written = sparse_write (out_des, output_buffer, output_size);
136 else
137 bytes_written = write (out_des, output_buffer, output_size);
138
139 if (bytes_written != output_size)
140 {
141 error (1, errno, _("write error"));
142 }
143 output_bytes += output_size;
144 out_buff = output_buffer;
145 output_size = 0;
146}
147
148/* Exchange the halfwords of each element of the array of COUNT longs
149 starting at PTR. PTR does not have to be aligned at a word
150 boundary. */
151
152void
153swahw_array (char *ptr, int count)
154{
155 char tmp;
156
157 for (; count > 0; --count)
158 {
159 tmp = *ptr;
160 *ptr = *(ptr + 2);
161 *(ptr + 2) = tmp;
162 ++ptr;
163 tmp = *ptr;
164 *ptr = *(ptr + 2);
165 *(ptr + 2) = tmp;
166 ptr += 3;
167 }
168}
169
170/* Read at most NUM_BYTES or `io_block_size' bytes, whichever is smaller,
171 into the start of `input_buffer' from file descriptor IN_DES.
172 Set `input_size' to the number of bytes read and reset `in_buff'.
173 Exit with an error if end of file is reached. */
174
175#ifdef BROKEN_LONG_TAPE_DRIVER
176static long input_bytes_before_lseek = 0;
177#endif
178
179static void
180tape_fill_input_buffer (int in_des, int num_bytes)
181{
182#ifdef BROKEN_LONG_TAPE_DRIVER
183 /* Some tape drivers seem to have a signed internal seek pointer and
184 they lose if it overflows and becomes negative (e.g. when writing
185 tapes > 4Gb). Doing an lseek (des, 0, SEEK_SET) seems to reset the
186 seek pointer and prevent it from overflowing. */
187 if (input_is_special
188 && ( (input_bytes_before_lseek += num_bytes) >= 1073741824L) )
189 {
190 lseek(in_des, 0L, SEEK_SET);
191 input_bytes_before_lseek = 0;
192 }
193#endif
194 in_buff = input_buffer;
195 num_bytes = (num_bytes < io_block_size) ? num_bytes : io_block_size;
196 input_size = rmtread (in_des, input_buffer, num_bytes);
197 if (input_size == 0 && input_is_special)
198 {
199 get_next_reel (in_des);
200 input_size = rmtread (in_des, input_buffer, num_bytes);
201 }
202 if (input_size < 0)
203 error (1, errno, _("read error"));
204 if (input_size == 0)
205 {
206 error (0, 0, _("premature end of file"));
207 exit (1);
208 }
209 input_bytes += input_size;
210}
211
212/* Read at most NUM_BYTES or `DISK_IO_BLOCK_SIZE' bytes, whichever is smaller,
213 into the start of `input_buffer' from file descriptor IN_DES.
214 Set `input_size' to the number of bytes read and reset `in_buff'.
215 Exit with an error if end of file is reached. */
216
217static int
218disk_fill_input_buffer (int in_des, off_t num_bytes)
219{
220 in_buff = input_buffer;
221 num_bytes = (num_bytes < DISK_IO_BLOCK_SIZE) ? num_bytes : DISK_IO_BLOCK_SIZE;
222 input_size = read (in_des, input_buffer, num_bytes);
223 if (input_size < 0)
224 {
225 input_size = 0;
226 return (-1);
227 }
228 else if (input_size == 0)
229 return (1);
230 input_bytes += input_size;
231 return (0);
232}
233
234
235/* Copy NUM_BYTES of buffer IN_BUF to `out_buff', which may be partly full.
236 When `out_buff' fills up, flush it to file descriptor OUT_DES. */
237
238void
239tape_buffered_write (char *in_buf, int out_des, off_t num_bytes)
240{
241 off_t bytes_left = num_bytes; /* Bytes needing to be copied. */
242 off_t space_left; /* Room left in output buffer. */
243
244 while (bytes_left > 0)
245 {
246 space_left = io_block_size - output_size;
247 if (space_left == 0)
248 tape_empty_output_buffer (out_des);
249 else
250 {
251 if (bytes_left < space_left)
252 space_left = bytes_left;
253 memcpy (out_buff, in_buf, (unsigned) space_left);
254 out_buff += space_left;
255 output_size += space_left;
256 in_buf += space_left;
257 bytes_left -= space_left;
258 }
259 }
260}
261
262/* Copy NUM_BYTES of buffer IN_BUF to `out_buff', which may be partly full.
263 When `out_buff' fills up, flush it to file descriptor OUT_DES. */
264
265void
266disk_buffered_write (char *in_buf, int out_des, off_t num_bytes)
267{
268 off_t bytes_left = num_bytes; /* Bytes needing to be copied. */
269 off_t space_left; /* Room left in output buffer. */
270
271 while (bytes_left > 0)
272 {
273 space_left = DISK_IO_BLOCK_SIZE - output_size;
274 if (space_left == 0)
275 disk_empty_output_buffer (out_des);
276 else
277 {
278 if (bytes_left < space_left)
279 space_left = bytes_left;
280 memcpy (out_buff, in_buf, (unsigned) space_left);
281 out_buff += space_left;
282 output_size += space_left;
283 in_buf += space_left;
284 bytes_left -= space_left;
285 }
286 }
287}
288
289/* Copy NUM_BYTES of buffer `in_buff' into IN_BUF.
290 `in_buff' may be partly full.
291 When `in_buff' is exhausted, refill it from file descriptor IN_DES. */
292
293void
294tape_buffered_read (char *in_buf, int in_des, off_t num_bytes)
295{
296 off_t bytes_left = num_bytes; /* Bytes needing to be copied. */
297 off_t space_left; /* Bytes to copy from input buffer. */
298
299 while (bytes_left > 0)
300 {
301 if (input_size == 0)
302 tape_fill_input_buffer (in_des, io_block_size);
303 if (bytes_left < input_size)
304 space_left = bytes_left;
305 else
306 space_left = input_size;
307 memcpy (in_buf, in_buff, (unsigned) space_left);
308 in_buff += space_left;
309 in_buf += space_left;
310 input_size -= space_left;
311 bytes_left -= space_left;
312 }
313}
314
315/* Copy the the next NUM_BYTES bytes of `input_buffer' into PEEK_BUF.
316 If NUM_BYTES bytes are not available, read the next `io_block_size' bytes
317 into the end of `input_buffer' and update `input_size'.
318
319 Return the number of bytes copied into PEEK_BUF.
320 If the number of bytes returned is less than NUM_BYTES,
321 then EOF has been reached. */
322
323int
324tape_buffered_peek (char *peek_buf, int in_des, int num_bytes)
325{
326 long tmp_input_size;
327 long got_bytes;
328 char *append_buf;
329
330#ifdef BROKEN_LONG_TAPE_DRIVER
331 /* Some tape drivers seem to have a signed internal seek pointer and
332 they lose if it overflows and becomes negative (e.g. when writing
333 tapes > 4Gb). Doing an lseek (des, 0, SEEK_SET) seems to reset the
334 seek pointer and prevent it from overflowing. */
335 if (input_is_special
336 && ( (input_bytes_before_lseek += num_bytes) >= 1073741824L) )
337 {
338 lseek(in_des, 0L, SEEK_SET);
339 input_bytes_before_lseek = 0;
340 }
341#endif
342
343 while (input_size < num_bytes)
344 {
345 append_buf = in_buff + input_size;
346 if ( (append_buf - input_buffer) >= input_buffer_size)
347 {
348 /* We can keep up to 2 "blocks" (either the physical block size
349 or 512 bytes(the size of a tar record), which ever is
350 larger) in the input buffer when we are peeking. We
351 assume that our caller will never be interested in peeking
352 ahead at more than 512 bytes, so we know that by the time
353 we need a 3rd "block" in the buffer we can throw away the
354 first block to make room. */
355 int half;
356 half = input_buffer_size / 2;
357 memmove (input_buffer, input_buffer + half, half);
358 in_buff = in_buff - half;
359 append_buf = append_buf - half;
360 }
361 tmp_input_size = rmtread (in_des, append_buf, io_block_size);
362 if (tmp_input_size == 0)
363 {
364 if (input_is_special)
365 {
366 get_next_reel (in_des);
367 tmp_input_size = rmtread (in_des, append_buf, io_block_size);
368 }
369 else
370 break;
371 }
372 if (tmp_input_size < 0)
373 error (1, errno, _("read error"));
374 input_bytes += tmp_input_size;
375 input_size += tmp_input_size;
376 }
377 if (num_bytes <= input_size)
378 got_bytes = num_bytes;
379 else
380 got_bytes = input_size;
381 memcpy (peek_buf, in_buff, (unsigned) got_bytes);
382 return got_bytes;
383}
384
385
386/* Skip the next NUM_BYTES bytes of file descriptor IN_DES. */
387
388void
389tape_toss_input (int in_des, long num_bytes)
390{
391 register long bytes_left = num_bytes; /* Bytes needing to be copied. */
392 register long space_left; /* Bytes to copy from input buffer. */
393
394 while (bytes_left > 0)
395 {
396 if (input_size == 0)
397 tape_fill_input_buffer (in_des, io_block_size);
398 if (bytes_left < input_size)
399 space_left = bytes_left;
400 else
401 space_left = input_size;
402
403 if (crc_i_flag && only_verify_crc_flag)
404 {
405 int k;
406 for (k = 0; k < space_left; ++k)
407 crc += in_buff[k] & 0xff;
408 }
409
410 in_buff += space_left;
411 input_size -= space_left;
412 bytes_left -= space_left;
413 }
414}
415
416
417void
418write_nuls_to_file (off_t num_bytes, int out_des,
419 void (*writer) (char *in_buf, int out_des, off_t num_bytes))
420{
421 off_t blocks;
422 off_t extra_bytes;
423 off_t i;
424 static char zeros_512[512];
425
426 blocks = num_bytes / sizeof zeros_512;
427 extra_bytes = num_bytes % sizeof zeros_512;
428 for (i = 0; i < blocks; ++i)
429 writer (zeros_512, out_des, sizeof zeros_512);
430 if (extra_bytes)
431 writer (zeros_512, out_des, extra_bytes);
432}
433
434
435/* Copy a file using the input and output buffers, which may start out
436 partly full. After the copy, the files are not closed nor the last
437 block flushed to output, and the input buffer may still be partly
438 full. If `crc_i_flag' is set, add each byte to `crc'.
439 IN_DES is the file descriptor for input;
440 OUT_DES is the file descriptor for output;
441 NUM_BYTES is the number of bytes to copy. */
442
443void
444copy_files_tape_to_disk (int in_des, int out_des, off_t num_bytes)
445{
446 long size;
447 long k;
448
449 while (num_bytes > 0)
450 {
451 if (input_size == 0)
452 tape_fill_input_buffer (in_des, io_block_size);
453 size = (input_size < num_bytes) ? input_size : num_bytes;
454 if (crc_i_flag)
455 {
456 for (k = 0; k < size; ++k)
457 crc += in_buff[k] & 0xff;
458 }
459 disk_buffered_write (in_buff, out_des, size);
460 num_bytes -= size;
461 input_size -= size;
462 in_buff += size;
463 }
464}
465/* Copy a file using the input and output buffers, which may start out
466 partly full. After the copy, the files are not closed nor the last
467 block flushed to output, and the input buffer may still be partly
468 full. If `crc_i_flag' is set, add each byte to `crc'.
469 IN_DES is the file descriptor for input;
470 OUT_DES is the file descriptor for output;
471 NUM_BYTES is the number of bytes to copy. */
472
473void
474copy_files_disk_to_tape (int in_des, int out_des, off_t num_bytes,
475 char *filename)
476{
477 long size;
478 long k;
479 int rc;
480 off_t original_num_bytes;
481
482 original_num_bytes = num_bytes;
483
484 while (num_bytes > 0)
485 {
486 if (input_size == 0)
487 if (rc = disk_fill_input_buffer (in_des,
488 num_bytes < DISK_IO_BLOCK_SIZE ?
489 num_bytes : DISK_IO_BLOCK_SIZE))
490 {
491 if (rc > 0)
492 {
493 char buf[UINTMAX_STRSIZE_BOUND];
494 error (0, 0,
495 ngettext ("File %s shrunk by %s byte, padding with zeros",
496 "File %s shrunk by %s bytes, padding with zeros",
497 num_bytes),
498 filename, STRINGIFY_BIGINT (num_bytes, buf));
499 }
500 else
501 error (0, 0, _("Read error at byte %lld in file %s, padding with zeros"),
502 original_num_bytes - num_bytes, filename);
503 write_nuls_to_file (num_bytes, out_des, tape_buffered_write);
504 break;
505 }
506 size = (input_size < num_bytes) ? input_size : num_bytes;
507 if (crc_i_flag)
508 {
509 for (k = 0; k < size; ++k)
510 crc += in_buff[k] & 0xff;
511 }
512 tape_buffered_write (in_buff, out_des, size);
513 num_bytes -= size;
514 input_size -= size;
515 in_buff += size;
516 }
517}
518/* Copy a file using the input and output buffers, which may start out
519 partly full. After the copy, the files are not closed nor the last
520 block flushed to output, and the input buffer may still be partly
521 full. If `crc_i_flag' is set, add each byte to `crc'.
522 IN_DES is the file descriptor for input;
523 OUT_DES is the file descriptor for output;
524 NUM_BYTES is the number of bytes to copy. */
525
526void
527copy_files_disk_to_disk (int in_des, int out_des, off_t num_bytes,
528 char *filename)
529{
530 long size;
531 long k;
532 off_t original_num_bytes;
533 int rc;
534
535 original_num_bytes = num_bytes;
536 while (num_bytes > 0)
537 {
538 if (input_size == 0)
539 if (rc = disk_fill_input_buffer (in_des, num_bytes))
540 {
541 if (rc > 0)
542 {
543 char buf[UINTMAX_STRSIZE_BOUND];
544 error (0, 0,
545 ngettext ("File %s shrunk by %s byte, padding with zeros",
546 "File %s shrunk by %s bytes, padding with zeros",
547 num_bytes),
548 filename, STRINGIFY_BIGINT (num_bytes, buf));
549 }
550 else
551 error (0, 0, _("Read error at byte %lld in file %s, padding with zeros"),
552 original_num_bytes - num_bytes, filename);
553 write_nuls_to_file (num_bytes, out_des, disk_buffered_write);
554 break;
555 }
556 size = (input_size < num_bytes) ? input_size : num_bytes;
557 if (crc_i_flag)
558 {
559 for (k = 0; k < size; ++k)
560 crc += in_buff[k] & 0xff;
561 }
562 disk_buffered_write (in_buff, out_des, size);
563 num_bytes -= size;
564 input_size -= size;
565 in_buff += size;
566 }
567}
568
569
570/* Warn if file changed while it was being copied. */
571
572void
573warn_if_file_changed (char *file_name, unsigned long old_file_size,
574 unsigned long old_file_mtime)
575{
576 struct stat new_file_stat;
577 if ((*xstat) (file_name, &new_file_stat) < 0)
578 {
579 stat_error (file_name);
580 return;
581 }
582
583 /* Only check growth, shrinkage detected in copy_files_disk_to_{disk,tape}()
584 */
585 if (new_file_stat.st_size > old_file_size)
586 error (0, 0, _("File %s grew, %ld new bytes not copied"),
587 file_name, (long)(new_file_stat.st_size - old_file_size));
588
589 else if (new_file_stat.st_mtime != old_file_mtime)
590 error (0, 0, _("File %s was modified while being copied"), file_name);
591}
592
593
594/* Create all directories up to but not including the last part of NAME.
595 Do not destroy any nondirectories while creating directories. */
596
597void
598create_all_directories (char *name)
599{
600 char *dir;
601 int mode;
602#ifdef HPUX_CDF
603 int cdf;
604#endif
605
606 dir = dir_name (name);
607 mode = 0700;
608#ifdef HPUX_CDF
609 cdf = islastparentcdf (name);
610 if (cdf)
611 {
612 dir [strlen (dir) - 1] = '\0'; /* remove final + */
613 mode = 04700;
614 }
615
616#endif
617
618 if (dir == NULL)
619 error (2, 0, _("virtual memory exhausted"));
620
621 if (dir[0] != '.' || dir[1] != '\0')
622 make_path (dir, mode, 0700, -1, -1, (char *) NULL);
623
624 free (dir);
625}
626
627/* Prepare to append to an archive. We have been in
628 process_copy_in, keeping track of the position where
629 the last header started in `last_header_start'. Now we
630 have the starting position of the last header (the TRAILER!!!
631 header, or blank record for tar archives) and we want to start
632 writing (appending) over the last header. The last header may
633 be in the middle of a block, so to keep the buffering in sync
634 we lseek back to the start of the block, read everything up
635 to but not including the last header, lseek back to the start
636 of the block, and then do a copy_buf_out of what we read.
637 Actually, we probably don't have to worry so much about keeping the
638 buffering perfect since you can only append to archives that
639 are disk files. */
640
641void
642prepare_append (int out_file_des)
643{
644 int start_of_header;
645 int start_of_block;
646 int useful_bytes_in_block;
647 char *tmp_buf;
648
649 start_of_header = last_header_start;
650 /* Figure out how many bytes we will rewrite, and where they start. */
651 useful_bytes_in_block = start_of_header % io_block_size;
652 start_of_block = start_of_header - useful_bytes_in_block;
653
654 if (lseek (out_file_des, start_of_block, SEEK_SET) < 0)
655 error (1, errno, _("cannot seek on output"));
656 if (useful_bytes_in_block > 0)
657 {
658 tmp_buf = (char *) xmalloc (useful_bytes_in_block);
659 read (out_file_des, tmp_buf, useful_bytes_in_block);
660 if (lseek (out_file_des, start_of_block, SEEK_SET) < 0)
661 error (1, errno, _("cannot seek on output"));
662 /* fix juo -- is this copy_tape_buf_out? or copy_disk? */
663 tape_buffered_write (tmp_buf, out_file_des, useful_bytes_in_block);
664 free (tmp_buf);
665 }
666
667 /* We are done reading the archive, so clear these since they
668 will now be used for reading in files that we are appending
669 to the archive. */
670 input_size = 0;
671 input_bytes = 0;
672 in_buff = input_buffer;
673}
674
675/* Support for remembering inodes with multiple links. Used in the
676 "copy in" and "copy pass" modes for making links instead of copying
677 the file. */
678
679struct inode_val
680{
681 unsigned long inode;
682 unsigned long major_num;
683 unsigned long minor_num;
684 char *file_name;
685};
686
687/* Inode hash table. Allocated by first call to add_inode. */
688static Hash_table *hash_table = NULL;
689
690static size_t
691inode_val_hasher (const void *val, size_t n_buckets)
692{
693 const struct inode_val *ival = val;
694 return ival->inode % n_buckets;
695}
696
697static bool
698inode_val_compare (const void *val1, const void *val2)
699{
700 const struct inode_val *ival1 = val1;
701 const struct inode_val *ival2 = val2;
702 return ival1->inode == ival2->inode
703 && ival1->major_num == ival2->major_num
704 && ival1->minor_num == ival2->minor_num;
705}
706
707char *
708find_inode_file (unsigned long node_num, unsigned long major_num,
709 unsigned long minor_num)
710{
711 struct inode_val sample;
712 struct inode_val *ival;
713
714 if (!hash_table)
715 return NULL;
716
717 sample.inode = node_num;
718 sample.major_num = major_num;
719 sample.minor_num = minor_num;
720 ival = hash_lookup (hash_table, &sample);
721 return ival ? ival->file_name : NULL;
722}
723
724/* Associate FILE_NAME with the inode NODE_NUM. (Insert into hash table.) */
725
726void
727add_inode (unsigned long node_num, char *file_name, unsigned long major_num,
728 unsigned long minor_num)
729{
730 struct inode_val *temp;
731 struct inode_val *e;
732
733 /* Create new inode record. */
734 temp = (struct inode_val *) xmalloc (sizeof (struct inode_val));
735 temp->inode = node_num;
736 temp->major_num = major_num;
737 temp->minor_num = minor_num;
738 temp->file_name = xstrdup (file_name);
739
740 if (!((hash_table
741 || (hash_table = hash_initialize (0, 0, inode_val_hasher,
742 inode_val_compare, 0)))
743 && (e = hash_insert (hash_table, temp))))
744 xalloc_die ();
745 /* FIXME: e is not used */
746}
747
748
749
750/* Open FILE in the mode specified by the command line options
751 and return an open file descriptor for it,
752 or -1 if it can't be opened. */
753
754int
755open_archive (char *file)
756{
757 int fd;
758 void (*copy_in) (); /* Workaround for pcc bug. */
759
760 copy_in = process_copy_in;
761
762 if (copy_function == copy_in)
763 fd = rmtopen (file, O_RDONLY | O_BINARY, MODE_RW, rsh_command_option);
764 else
765 {
766 if (!append_flag)
767 fd = rmtopen (file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, MODE_RW,
768 rsh_command_option);
769 else
770 fd = rmtopen (file, O_RDWR | O_BINARY, MODE_RW, rsh_command_option);
771 }
772
773 return fd;
774}
775
776/* Attempt to rewind the tape drive on file descriptor TAPE_DES
777 and take it offline. */
778
779void
780tape_offline (int tape_des)
781{
782#if defined(MTIOCTOP) && defined(MTOFFL)
783 struct mtop control;
784
785 control.mt_op = MTOFFL;
786 control.mt_count = 1;
787 rmtioctl (tape_des, MTIOCTOP, (char*) &control); /* Don't care if it fails. */
788#endif
789}
790
791/* The file on file descriptor TAPE_DES is assumed to be magnetic tape
792 (or floppy disk or other device) and the end of the medium
793 has been reached. Ask the user for to mount a new "tape" to continue
794 the processing. If the user specified the device name on the
795 command line (with the -I, -O, -F or --file options), then we can
796 automatically re-open the same device to use the next medium. If the
797 user did not specify the device name, then we have to ask them which
798 device to use. */
799
800void
801get_next_reel (int tape_des)
802{
803 static int reel_number = 1;
804 FILE *tty_in; /* File for interacting with user. */
805 FILE *tty_out; /* File for interacting with user. */
806 int old_tape_des;
807 char *next_archive_name;
808 dynamic_string new_name;
809 char *str_res;
810
811 ds_init (&new_name, 128);
812
813 /* Open files for interactive communication. */
814 tty_in = fopen (TTY_NAME, "r");
815 if (tty_in == NULL)
816 error (2, errno, TTY_NAME);
817 tty_out = fopen (TTY_NAME, "w");
818 if (tty_out == NULL)
819 error (2, errno, TTY_NAME);
820
821 old_tape_des = tape_des;
822 tape_offline (tape_des);
823 rmtclose (tape_des);
824
825 /* Give message and wait for carrage return. User should hit carrage return
826 only after loading the next tape. */
827 ++reel_number;
828 if (new_media_message)
829 fprintf (tty_out, "%s", new_media_message);
830 else if (new_media_message_with_number)
831 fprintf (tty_out, "%s%d%s", new_media_message_with_number, reel_number,
832 new_media_message_after_number);
833 else if (archive_name)
834 fprintf (tty_out, _("Found end of tape. Load next tape and press RETURN. "));
835 else
836 fprintf (tty_out, _("Found end of tape. To continue, type device/file name when ready.\n"));
837
838 fflush (tty_out);
839
840 if (archive_name)
841 {
842 int c;
843
844 do
845 c = getc (tty_in);
846 while (c != EOF && c != '\n');
847
848 tape_des = open_archive (archive_name);
849 if (tape_des == -1)
850 open_error (archive_name);
851 }
852 else
853 {
854 do
855 {
856 if (tape_des < 0)
857 {
858 fprintf (tty_out,
859 _("To continue, type device/file name when ready.\n"));
860 fflush (tty_out);
861 }
862
863 str_res = ds_fgets (tty_in, &new_name);
864 if (str_res == NULL || str_res[0] == '\0')
865 exit (1);
866 next_archive_name = str_res;
867
868 tape_des = open_archive (next_archive_name);
869 if (tape_des == -1)
870 open_error (next_archive_name);
871 }
872 while (tape_des < 0);
873 }
874
875 /* We have to make sure that `tape_des' has not changed its value even
876 though we closed it and reopened it, since there are local
877 copies of it in other routines. This works fine on Unix (even with
878 rmtread and rmtwrite) since open will always return the lowest
879 available file descriptor and we haven't closed any files (e.g.,
880 stdin, stdout or stderr) that were opened before we originally opened
881 the archive. */
882
883 if (tape_des != old_tape_des)
884 error (1, 0, _("internal error: tape descriptor changed from %d to %d"),
885 old_tape_des, tape_des);
886
887 free (new_name.ds_string);
888 fclose (tty_in);
889 fclose (tty_out);
890}
891
892/* If MESSAGE does not contain the string "%d", make `new_media_message'
893 a copy of MESSAGE. If MESSAGES does contain the string "%d", make
894 `new_media_message_with_number' a copy of MESSAGE up to, but
895 not including, the string "%d", and make `new_media_message_after_number'
896 a copy of MESSAGE after the string "%d". */
897
898void
899set_new_media_message (char *message)
900{
901 char *p;
902 int prev_was_percent;
903
904 p = message;
905 prev_was_percent = 0;
906 while (*p != '\0')
907 {
908 if (*p == 'd' && prev_was_percent)
909 break;
910 prev_was_percent = (*p == '%');
911 ++p;
912 }
913 if (*p == '\0')
914 {
915 new_media_message = xstrdup (message);
916 }
917 else
918 {
919 int length = p - message - 1;
920
921 new_media_message_with_number = xmalloc (length + 1);
922 strncpy (new_media_message_with_number, message, length);
923 new_media_message_with_number[length] = '\0';
924 length = strlen (p + 1);
925 new_media_message_after_number = xmalloc (length + 1);
926 strcpy (new_media_message_after_number, p + 1);
927 }
928}
929
930#ifdef SYMLINK_USES_UMASK
931/* Most machines always create symlinks with rwxrwxrwx protection,
932 but some (HP/UX 8.07; maybe DEC's OSF on MIPS, too?) use the
933 umask when creating symlinks, so if your umask is 022 you end
934 up with rwxr-xr-x symlinks (although HP/UX seems to completely
935 ignore the protection). There doesn't seem to be any way to
936 manipulate the modes once the symlinks are created (e.g.
937 a hypothetical "lchmod"), so to create them with the right
938 modes we have to set the umask first. */
939
940int
941umasked_symlink (char *name1, char *name2, int mode)
942{
943 int old_umask;
944 int rc;
945 mode = ~(mode & 0777) & 0777;
946 old_umask = umask (mode);
947 rc = symlink (name1, name2);
948 umask (old_umask);
949 return rc;
950}
951#endif /* SYMLINK_USES_UMASK */
952
953#ifdef HPUX_CDF
954/* When we create a cpio archive we mark CDF's by putting an extra `/'
955 after their component name so we can distinguish the CDF's when we
956 extract the archive (in case the "hidden" directory's files appear
957 in the archive before the directory itself). E.g., in the path
958 "a/b+/c", if b+ is a CDF, we will write this path as "a/b+//c" in
959 the archive so when we extract the archive we will know that b+
960 is actually a CDF, and not an ordinary directory whose name happens
961 to end in `+'. We also do the same thing internally in copypass.c. */
962
963
964/* Take an input pathname and check it for CDF's. Insert an extra
965 `/' in the pathname after each "hidden" directory. If we add
966 any `/'s, return a malloced string instead of the original input
967 string.
968 FIXME: This creates a memory leak.
969*/
970
971char *
972add_cdf_double_slashes (char *input_name)
973{
974 static char *ret_name = NULL; /* re-usuable return buffer (malloc'ed) */
975 static int ret_size = -1; /* size of return buffer. */
976 char *p;
977 char *q;
978 int n;
979 struct stat dir_stat;
980
981 /* Search for a `/' preceeded by a `+'. */
982
983 for (p = input_name; *p != '\0'; ++p)
984 {
985 if ( (*p == '+') && (*(p + 1) == '/') )
986 break;
987 }
988
989 /* If we didn't find a `/' preceeded by a `+' then there are
990 no CDF's in this pathname. Return the original pathname. */
991
992 if (*p == '\0')
993 return input_name;
994
995 /* There was a `/' preceeded by a `+' in the pathname. If it is a CDF
996 then we will need to copy the input pathname to our return
997 buffer so we can insert the extra `/'s. Since we can't tell
998 yet whether or not it is a CDF we will just always copy the
999 string to the return buffer. First we have to make sure the
1000 buffer is large enough to hold the string and any number of
1001 extra `/'s we might add. */
1002
1003 n = 2 * (strlen (input_name) + 1);
1004 if (n >= ret_size)
1005 {
1006 if (ret_size < 0)
1007 ret_name = (char *) malloc (n);
1008 else
1009 ret_name = (char *)realloc (ret_name, n);
1010 ret_size = n;
1011 }
1012
1013 /* Clear the `/' after this component, so we can stat the pathname
1014 up to and including this component. */
1015 ++p;
1016 *p = '\0';
1017 if ((*xstat) (input_name, &dir_stat) < 0)
1018 {
1019 stat_error (input_name);
1020 return input_name;
1021 }
1022
1023 /* Now put back the `/' after this component and copy the pathname up to
1024 and including this component and its trailing `/' to the return
1025 buffer. */
1026 *p++ = '/';
1027 strncpy (ret_name, input_name, p - input_name);
1028 q = ret_name + (p - input_name);
1029
1030 /* If it was a CDF, add another `/'. */
1031 if (S_ISDIR (dir_stat.st_mode) && (dir_stat.st_mode & 04000) )
1032 *q++ = '/';
1033
1034 /* Go through the rest of the input pathname, copying it to the
1035 return buffer, and adding an extra `/' after each CDF. */
1036 while (*p != '\0')
1037 {
1038 if ( (*p == '+') && (*(p + 1) == '/') )
1039 {
1040 *q++ = *p++;
1041
1042 *p = '\0';
1043 if ((*xstat) (input_name, &dir_stat) < 0)
1044 {
1045 stat_error (input_name);
1046 return input_name;
1047 }
1048 *p = '/';
1049
1050 if (S_ISDIR (dir_stat.st_mode) && (dir_stat.st_mode & 04000) )
1051 *q++ = '/';
1052 }
1053 *q++ = *p++;
1054 }
1055 *q = '\0';
1056
1057 return ret_name;
1058}
1059
1060/* Is the last parent directory (e.g., c in a/b/c/d) a CDF? If the
1061 directory name ends in `+' and is followed by 2 `/'s instead of 1
1062 then it is. This is only the case for cpio archives, but we don't
1063 have to worry about tar because tar always has the directory before
1064 its files (or else we lose). */
1065int
1066islastparentcdf (char *path)
1067{
1068 char *newpath;
1069 char *slash;
1070 int slash_count;
1071 int length; /* Length of result, not including NUL. */
1072
1073 slash = strrchr (path, '/');
1074 if (slash == 0)
1075 return 0;
1076 else
1077 {
1078 slash_count = 0;
1079 while (slash > path && *slash == '/')
1080 {
1081 ++slash_count;
1082 --slash;
1083 }
1084
1085
1086 if ( (*slash == '+') && (slash_count >= 2) )
1087 return 1;
1088 }
1089 return 0;
1090}
1091#endif
1092
1093#define DISKBLOCKSIZE (512)
1094
1095enum sparse_write_states { begin, in_zeros, not_in_zeros };
1096
1097
1098static int
1099buf_all_zeros (char *buf, int bufsize)
1100{
1101 int i;
1102 for (i = 0; i < bufsize; ++i)
1103 {
1104 if (*buf++ != '\0')
1105 return 0;
1106 }
1107 return 1;
1108}
1109
1110int delayed_seek_count = 0;
1111
1112/* Write NBYTE bytes from BUF to remote tape connection FILDES.
1113 Return the number of bytes written on success, -1 on error. */
1114
1115int
1116sparse_write (int fildes, char *buf, unsigned int nbyte)
1117{
1118 int complete_block_count;
1119 int leftover_bytes_count;
1120 int seek_count;
1121 int write_count;
1122 char *cur_write_start;
1123 int lseek_rc;
1124 int write_rc;
1125 int i;
1126 enum sparse_write_states state;
1127
1128 complete_block_count = nbyte / DISKBLOCKSIZE;
1129 leftover_bytes_count = nbyte % DISKBLOCKSIZE;
1130
1131 if (delayed_seek_count != 0)
1132 state = in_zeros;
1133 else
1134 state = begin;
1135
1136 seek_count = delayed_seek_count;
1137
1138 for (i = 0; i < complete_block_count; ++i)
1139 {
1140 switch (state)
1141 {
1142 case begin :
1143 if (buf_all_zeros (buf, DISKBLOCKSIZE))
1144 {
1145 seek_count = DISKBLOCKSIZE;
1146 state = in_zeros;
1147 }
1148 else
1149 {
1150 cur_write_start = buf;
1151 write_count = DISKBLOCKSIZE;
1152 state = not_in_zeros;
1153 }
1154 buf += DISKBLOCKSIZE;
1155 break;
1156 case in_zeros :
1157 if (buf_all_zeros (buf, DISKBLOCKSIZE))
1158 {
1159 seek_count += DISKBLOCKSIZE;
1160 }
1161 else
1162 {
1163 lseek (fildes, seek_count, SEEK_CUR);
1164 cur_write_start = buf;
1165 write_count = DISKBLOCKSIZE;
1166 state = not_in_zeros;
1167 }
1168 buf += DISKBLOCKSIZE;
1169 break;
1170 case not_in_zeros :
1171 if (buf_all_zeros (buf, DISKBLOCKSIZE))
1172 {
1173 write_rc = write (fildes, cur_write_start, write_count);
1174 seek_count = DISKBLOCKSIZE;
1175 state = in_zeros;
1176 }
1177 else
1178 {
1179 write_count += DISKBLOCKSIZE;
1180 }
1181 buf += DISKBLOCKSIZE;
1182 break;
1183 }
1184 }
1185
1186 switch (state)
1187 {
1188 case begin :
1189 case in_zeros :
1190 delayed_seek_count = seek_count;
1191 break;
1192 case not_in_zeros :
1193 write_rc = write (fildes, cur_write_start, write_count);
1194 delayed_seek_count = 0;
1195 break;
1196 }
1197
1198 if (leftover_bytes_count != 0)
1199 {
1200 if (delayed_seek_count != 0)
1201 {
1202 lseek_rc = lseek (fildes, delayed_seek_count, SEEK_CUR);
1203 delayed_seek_count = 0;
1204 }
1205 write_rc = write (fildes, buf, leftover_bytes_count);
1206 }
1207 return nbyte;
1208}
1209
1210void
1211stat_to_cpio (struct cpio_file_stat *hdr, struct stat *st)
1212{
1213 hdr->c_dev_maj = major (st->st_dev);
1214 hdr->c_dev_min = minor (st->st_dev);
1215 hdr->c_ino = st->st_ino;
1216 /* For POSIX systems that don't define the S_IF macros,
1217 we can't assume that S_ISfoo means the standard Unix
1218 S_IFfoo bit(s) are set. So do it manually, with a
1219 different name. Bleah. */
1220 hdr->c_mode = (st->st_mode & 07777);
1221 if (S_ISREG (st->st_mode))
1222 hdr->c_mode |= CP_IFREG;
1223 else if (S_ISDIR (st->st_mode))
1224 hdr->c_mode |= CP_IFDIR;
1225#ifdef S_ISBLK
1226 else if (S_ISBLK (st->st_mode))
1227 hdr->c_mode |= CP_IFBLK;
1228#endif
1229#ifdef S_ISCHR
1230 else if (S_ISCHR (st->st_mode))
1231 hdr->c_mode |= CP_IFCHR;
1232#endif
1233#ifdef S_ISFIFO
1234 else if (S_ISFIFO (st->st_mode))
1235 hdr->c_mode |= CP_IFIFO;
1236#endif
1237#ifdef S_ISLNK
1238 else if (S_ISLNK (st->st_mode))
1239 hdr->c_mode |= CP_IFLNK;
1240#endif
1241#ifdef S_ISSOCK
1242 else if (S_ISSOCK (st->st_mode))
1243 hdr->c_mode |= CP_IFSOCK;
1244#endif
1245#ifdef S_ISNWK
1246 else if (S_ISNWK (st->st_mode))
1247 hdr->c_mode |= CP_IFNWK;
1248#endif
1249 hdr->c_uid = st->st_uid;
1250 hdr->c_gid = st->st_gid;
1251 hdr->c_nlink = st->st_nlink;
1252 hdr->c_rdev_maj = major (st->st_rdev);
1253 hdr->c_rdev_min = minor (st->st_rdev);
1254 hdr->c_mtime = st->st_mtime;
1255 hdr->c_filesize = st->st_size;
1256 hdr->c_chksum = 0;
1257 hdr->c_tar_linkname = NULL;
1258}
1259
1260void
1261set_perms (struct cpio_file_stat *header)
1262{
1263 if (!no_chown_flag)
1264 {
1265 uid_t uid = set_owner_flag ? set_owner : header->c_uid;
1266 gid_t gid = set_group_flag ? set_group : header->c_gid;
1267 if ((chown (header->c_name, uid, gid) < 0) && errno != EPERM)
1268 chown_error_details (header->c_name, uid, gid);
1269 }
1270 /* chown may have turned off some permissions we wanted. */
1271 if (chmod (header->c_name, header->c_mode) < 0)
1272 chmod_error_details (header->c_name, header->c_mode);
1273#ifdef HPUX_CDF
1274 if ((header->c_mode & CP_IFMT) && cdf_flag)
1275 /* Once we "hide" the directory with the chmod(),
1276 we have to refer to it using name+ instead of name. */
1277 file_hdr->c_name [cdf_char] = '+';
1278#endif
1279 if (retain_time_flag)
1280 set_file_times (header->c_name, header->c_mtime, header->c_mtime);
1281}
1282
1283void
1284set_file_times (const char *name, unsigned long atime, unsigned long mtime)
1285{
1286 struct timespec ts[2];
1287
1288 memset (&ts, 0, sizeof ts);
1289
1290 ts[0].tv_sec = atime;
1291 ts[1].tv_sec = mtime;
1292
1293 /* Silently ignore EROFS because reading the file won't have upset its timestamp
1294 if it's on a read-only filesystem. */
1295 if (utimens (name, ts) < 0 && errno != EROFS)
1296 utime_error (name);
1297}
1298
1299/* Do we have to ignore absolute paths, and if so, does the filename
1300 have an absolute path? */
1301void
1302cpio_safer_name_suffix (char *name, bool link_target, bool absolute_names,
1303 bool strip_leading_dots)
1304{
1305 char *p = safer_name_suffix (name, link_target, absolute_names);
1306 if (strip_leading_dots && strcmp (p, "./"))
1307 /* strip leading `./' from the filename. */
1308 while (*p == '.' && *(p + 1) == '/')
1309 {
1310 ++p;
1311 while (*p == '/')
1312 ++p;
1313 }
1314 if (p != name)
1315 memmove (name, p, (size_t)(strlen (p) + 1));
1316}
1317
Note: See TracBrowser for help on using the repository browser.