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

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

cpio 2.7

File size: 24.3 KB
Line 
1/* copyout.c - create a cpio archive
2 Copyright (C) 1990, 1991, 1992, 2001, 2003, 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 "filetypes.h"
26#include "cpiohdr.h"
27#include "dstring.h"
28#include "extern.h"
29#include "defer.h"
30#include <rmt.h>
31#include <paxlib.h>
32
33/* Read FILE_SIZE bytes of FILE_NAME from IN_FILE_DES and
34 compute and return a checksum for them. */
35
36static unsigned int
37read_for_checksum (int in_file_des, int file_size, char *file_name)
38{
39 unsigned int crc;
40 char buf[BUFSIZ];
41 int bytes_left;
42 int bytes_read;
43 int i;
44
45 crc = 0;
46
47 for (bytes_left = file_size; bytes_left > 0; bytes_left -= bytes_read)
48 {
49 bytes_read = read (in_file_des, buf, BUFSIZ);
50 if (bytes_read < 0)
51 error (1, errno, _("cannot read checksum for %s"), file_name);
52 if (bytes_read == 0)
53 break;
54 if (bytes_left < bytes_read)
55 bytes_read = bytes_left;
56 for (i = 0; i < bytes_read; ++i)
57 crc += buf[i] & 0xff;
58 }
59 if (lseek (in_file_des, 0L, SEEK_SET))
60 error (1, errno, _("cannot read checksum for %s"), file_name);
61
62 return crc;
63}
64
65/* Write out NULs to fill out the rest of the current block on
66 OUT_FILE_DES. */
67
68static void
69tape_clear_rest_of_block (int out_file_des)
70{
71 write_nuls_to_file (io_block_size - output_size, out_file_des,
72 tape_buffered_write);
73}
74
75/* Write NULs on OUT_FILE_DES to move from OFFSET (the current location)
76 to the end of the header. */
77
78static void
79tape_pad_output (int out_file_des, int offset)
80{
81 size_t pad;
82
83 if (archive_format == arf_newascii || archive_format == arf_crcascii)
84 pad = (4 - (offset % 4)) % 4;
85 else if (archive_format == arf_tar || archive_format == arf_ustar)
86 pad = (512 - (offset % 512)) % 512;
87 else if (archive_format != arf_oldascii && archive_format != arf_hpoldascii)
88 pad = (2 - (offset % 2)) % 2;
89 else
90 pad = 0;
91
92 if (pad != 0)
93 write_nuls_to_file (pad, out_file_des, tape_buffered_write);
94}
95
96
97/* When creating newc and crc archives if a file has multiple (hard)
98 links, we don't put any of them into the archive until we have seen
99 all of them (or until we get to the end of the list of files that
100 are going into the archive and know that we have seen all of the links
101 to the file that we will see). We keep these "defered" files on
102 this list. */
103
104struct deferment *deferouts = NULL;
105
106/* Count the number of other (hard) links to this file that have
107 already been defered. */
108
109static int
110count_defered_links_to_dev_ino (struct cpio_file_stat *file_hdr)
111{
112 struct deferment *d;
113 int ino;
114 int maj;
115 int min;
116 int count;
117 ino = file_hdr->c_ino;
118 maj = file_hdr->c_dev_maj;
119 min = file_hdr->c_dev_min;
120 count = 0;
121 for (d = deferouts; d != NULL; d = d->next)
122 {
123 if ( (d->header.c_ino == ino) && (d->header.c_dev_maj == maj)
124 && (d->header.c_dev_min == min) )
125 ++count;
126 }
127 return count;
128}
129
130/* Is this file_hdr the last (hard) link to a file? I.e., have
131 we already seen and defered all of the other links? */
132
133static int
134last_link (struct cpio_file_stat *file_hdr)
135{
136 int other_files_sofar;
137
138 other_files_sofar = count_defered_links_to_dev_ino (file_hdr);
139 if (file_hdr->c_nlink == (other_files_sofar + 1) )
140 {
141 return 1;
142 }
143 return 0;
144}
145
146
147/* Add the file header for a link that is being defered to the deferouts
148 list. */
149
150static void
151add_link_defer (struct cpio_file_stat *file_hdr)
152{
153 struct deferment *d;
154 d = create_deferment (file_hdr);
155 d->next = deferouts;
156 deferouts = d;
157}
158
159/* We are about to put a file into a newc or crc archive that is
160 multiply linked. We have already seen and deferred all of the
161 other links to the file but haven't written them into the archive.
162 Write the other links into the archive, and remove them from the
163 deferouts list. */
164
165static void
166writeout_other_defers (struct cpio_file_stat *file_hdr, int out_des)
167{
168 struct deferment *d;
169 struct deferment *d_prev;
170 int ino;
171 int maj;
172 int min;
173 ino = file_hdr->c_ino;
174 maj = file_hdr->c_dev_maj;
175 min = file_hdr->c_dev_min;
176 d_prev = NULL;
177 d = deferouts;
178 while (d != NULL)
179 {
180 if ( (d->header.c_ino == ino) && (d->header.c_dev_maj == maj)
181 && (d->header.c_dev_min == min) )
182 {
183 struct deferment *d_free;
184 d->header.c_filesize = 0;
185 write_out_header (&d->header, out_des);
186 if (d_prev != NULL)
187 d_prev->next = d->next;
188 else
189 deferouts = d->next;
190 d_free = d;
191 d = d->next;
192 free_deferment (d_free);
193 }
194 else
195 {
196 d_prev = d;
197 d = d->next;
198 }
199 }
200 return;
201}
202
203/* Write a file into the archive. This code is the same as
204 the code in process_copy_out(), but we need it here too
205 for writeout_final_defers() to call. */
206
207static void
208writeout_defered_file (struct cpio_file_stat *header, int out_file_des)
209{
210 int in_file_des;
211 struct cpio_file_stat file_hdr;
212
213 file_hdr = *header;
214
215
216 in_file_des = open (header->c_name,
217 O_RDONLY | O_BINARY, 0);
218 if (in_file_des < 0)
219 {
220 open_error (header->c_name);
221 return;
222 }
223
224 if (archive_format == arf_crcascii)
225 file_hdr.c_chksum = read_for_checksum (in_file_des,
226 file_hdr.c_filesize,
227 header->c_name);
228
229 if (write_out_header (&file_hdr, out_file_des))
230 return;
231 copy_files_disk_to_tape (in_file_des, out_file_des, file_hdr.c_filesize,
232 header->c_name);
233 warn_if_file_changed(header->c_name, file_hdr.c_filesize, file_hdr.c_mtime);
234
235 if (archive_format == arf_tar || archive_format == arf_ustar)
236 add_inode (file_hdr.c_ino, file_hdr.c_name, file_hdr.c_dev_maj,
237 file_hdr.c_dev_min);
238
239 tape_pad_output (out_file_des, file_hdr.c_filesize);
240
241 if (close (in_file_des) < 0)
242 close_error (header->c_name);
243 if (reset_time_flag)
244 set_file_times (file_hdr.c_name, file_hdr.c_mtime, file_hdr.c_mtime);
245}
246
247/* When writing newc and crc format archives we defer multiply linked
248 files until we have seen all of the links to the file. If a file
249 has links to it that aren't going into the archive, then we will
250 never see the "last" link to the file, so at the end we just write
251 all of the leftover defered files into the archive. */
252
253static void
254writeout_final_defers (int out_des)
255{
256 struct deferment *d;
257 int other_count;
258 while (deferouts != NULL)
259 {
260 d = deferouts;
261 other_count = count_defered_links_to_dev_ino (&d->header);
262 if (other_count == 1)
263 {
264 writeout_defered_file (&d->header, out_des);
265 }
266 else
267 {
268 struct cpio_file_stat file_hdr;
269 file_hdr = d->header;
270 file_hdr.c_filesize = 0;
271 write_out_header (&file_hdr, out_des);
272 }
273 deferouts = deferouts->next;
274 }
275}
276
277/* FIXME: to_ascii could be used instead of to_oct() and to_octal() from tar,
278 so it should be moved to paxutils too.
279 Allowed values for logbase are: 1 (binary), 2, 3 (octal), 4 (hex) */
280int
281to_ascii (char *where, uintmax_t v, size_t digits, unsigned logbase)
282{
283 static char codetab[] = "0123456789ABCDEF";
284 int i = digits;
285
286 do
287 {
288 where[--i] = codetab[(v & ((1 << logbase) - 1))];
289 v >>= logbase;
290 }
291 while (i);
292
293 return v != 0;
294}
295
296static void
297field_width_error (const char *filename, const char *fieldname)
298{
299 error (0, 0, _("%s: field width not sufficient for storing %s"),
300 filename, fieldname);
301}
302
303static void
304field_width_warning (const char *filename, const char *fieldname)
305{
306 if (warn_option & CPIO_WARN_TRUNCATE)
307 error (0, 0, _("%s: truncating %s"), filename, fieldname);
308}
309
310void
311to_ascii_or_warn (char *where, uintmax_t n, size_t digits,
312 unsigned logbase,
313 const char *filename, const char *fieldname)
314{
315 if (to_ascii (where, n, digits, logbase))
316 field_width_warning (filename, fieldname);
317}
318
319int
320to_ascii_or_error (char *where, uintmax_t n, size_t digits,
321 unsigned logbase,
322 const char *filename, const char *fieldname)
323{
324 if (to_ascii (where, n, digits, logbase))
325 {
326 field_width_error (filename, fieldname);
327 return 1;
328 }
329 return 0;
330}
331
332
333
334int
335write_out_new_ascii_header (const char *magic_string,
336 struct cpio_file_stat *file_hdr, int out_des)
337{
338 char ascii_header[110];
339 char *p;
340
341 p = stpcpy (ascii_header, magic_string);
342 to_ascii_or_warn (p, file_hdr->c_ino, 8, LG_16,
343 file_hdr->c_name, _("inode number"));
344 p += 8;
345 to_ascii_or_warn (p, file_hdr->c_mode, 8, LG_16, file_hdr->c_name,
346 _("file mode"));
347 p += 8;
348 to_ascii_or_warn (p, file_hdr->c_uid, 8, LG_16, file_hdr->c_name,
349 _("uid"));
350 p += 8;
351 to_ascii_or_warn (p, file_hdr->c_gid, 8, LG_16, file_hdr->c_name,
352 _("gid"));
353 p += 8;
354 to_ascii_or_warn (p, file_hdr->c_nlink, 8, LG_16, file_hdr->c_name,
355 _("number of links"));
356 p += 8;
357 to_ascii_or_warn (p, file_hdr->c_mtime, 8, LG_16, file_hdr->c_name,
358 _("modification time"));
359 p += 8;
360 if (to_ascii_or_error (p, file_hdr->c_filesize, 8, LG_16, file_hdr->c_name,
361 _("file size")))
362 return 1;
363 p += 8;
364 if (to_ascii_or_error (p, file_hdr->c_dev_maj, 8, LG_16, file_hdr->c_name,
365 _("device major number")))
366 return 1;
367 p += 8;
368 if (to_ascii_or_error (p, file_hdr->c_dev_min, 8, LG_16, file_hdr->c_name,
369 _("device minor number")))
370 return 1;
371 p += 8;
372 if (to_ascii_or_error (p, file_hdr->c_rdev_maj, 8, LG_16, file_hdr->c_name,
373 _("rdev major")))
374 return 1;
375 p += 8;
376 if (to_ascii_or_error (p, file_hdr->c_rdev_min, 8, LG_16, file_hdr->c_name,
377 _("rdev minor")))
378 return 1;
379 p += 8;
380 if (to_ascii_or_error (p, file_hdr->c_namesize, 8, LG_16, file_hdr->c_name,
381 _("name size")))
382 return 1;
383 p += 8;
384 to_ascii (p, file_hdr->c_chksum & 0xffffffff, 8, LG_16);
385
386 tape_buffered_write (ascii_header, out_des, sizeof ascii_header);
387
388 /* Write file name to output. */
389 tape_buffered_write (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
390 tape_pad_output (out_des, file_hdr->c_namesize + sizeof ascii_header);
391 return 0;
392}
393
394int
395write_out_old_ascii_header (dev_t dev, dev_t rdev,
396 struct cpio_file_stat *file_hdr, int out_des)
397{
398 char ascii_header[76];
399 char *p = ascii_header;
400
401 to_ascii (p, file_hdr->c_magic, 6, LG_8);
402 p += 6;
403 to_ascii_or_warn (p, dev, 6, LG_8, file_hdr->c_name, _("device number"));
404 p += 6;
405 to_ascii_or_warn (p, file_hdr->c_ino, 6, LG_8, file_hdr->c_name,
406 _("inode number"));
407 p += 6;
408 to_ascii_or_warn (p, file_hdr->c_mode, 6, LG_8, file_hdr->c_name,
409 _("file mode"));
410 p += 6;
411 to_ascii_or_warn (p, file_hdr->c_uid, 6, LG_8, file_hdr->c_name, _("uid"));
412 p += 6;
413 to_ascii_or_warn (p, file_hdr->c_gid, 6, LG_8, file_hdr->c_name, _("gid"));
414 p += 6;
415 to_ascii_or_warn (p, file_hdr->c_nlink, 6, LG_8, file_hdr->c_name,
416 _("number of links"));
417 p += 6;
418 to_ascii_or_warn (p, rdev, 6, LG_8, file_hdr->c_name, _("rdev"));
419 p += 6;
420 to_ascii_or_warn (p, file_hdr->c_mtime, 11, LG_8, file_hdr->c_name,
421 _("modification time"));
422 p += 11;
423 if (to_ascii_or_error (p, file_hdr->c_namesize, 6, LG_8, file_hdr->c_name,
424 _("name size")))
425 return 1;
426 p += 6;
427 if (to_ascii_or_error (p, file_hdr->c_filesize, 11, LG_8, file_hdr->c_name,
428 _("file size")))
429 return 1;
430
431 tape_buffered_write (ascii_header, out_des, sizeof ascii_header);
432
433 /* Write file name to output. */
434 tape_buffered_write (file_hdr->c_name, out_des, file_hdr->c_namesize);
435 return 0;
436}
437
438void
439hp_compute_dev (struct cpio_file_stat *file_hdr, dev_t *pdev, dev_t *prdev)
440{
441 /* HP/UX cpio creates archives that look just like ordinary archives,
442 but for devices it sets major = 0, minor = 1, and puts the
443 actual major/minor number in the filesize field. */
444 switch (file_hdr->c_mode & CP_IFMT)
445 {
446 case CP_IFCHR:
447 case CP_IFBLK:
448#ifdef CP_IFSOCK
449 case CP_IFSOCK:
450#endif
451#ifdef CP_IFIFO
452 case CP_IFIFO:
453#endif
454 file_hdr->c_filesize = makedev (file_hdr->c_rdev_maj,
455 file_hdr->c_rdev_min);
456 *pdev = *prdev = makedev (0, 1);
457 break;
458
459 default:
460 *pdev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
461 *prdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
462 break;
463 }
464}
465
466int
467write_out_binary_header (dev_t rdev,
468 struct cpio_file_stat *file_hdr, int out_des)
469{
470 struct old_cpio_header short_hdr;
471
472 short_hdr.c_magic = 070707;
473 short_hdr.c_dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
474
475 if ((warn_option & CPIO_WARN_TRUNCATE) && (file_hdr->c_ino >> 16) != 0)
476 error (0, 0, _("%s: truncating inode number"), file_hdr->c_name);
477
478 short_hdr.c_ino = file_hdr->c_ino & 0xFFFF;
479 if (short_hdr.c_ino != file_hdr->c_ino)
480 field_width_warning (file_hdr->c_name, _("inode number"));
481
482 short_hdr.c_mode = file_hdr->c_mode & 0xFFFF;
483 if (short_hdr.c_mode != file_hdr->c_mode)
484 field_width_warning (file_hdr->c_name, _("file mode"));
485
486 short_hdr.c_uid = file_hdr->c_uid & 0xFFFF;
487 if (short_hdr.c_uid != file_hdr->c_uid)
488 field_width_warning (file_hdr->c_name, _("uid"));
489
490 short_hdr.c_gid = file_hdr->c_gid & 0xFFFF;
491 if (short_hdr.c_gid != file_hdr->c_gid)
492 field_width_warning (file_hdr->c_name, _("gid"));
493
494 short_hdr.c_nlink = file_hdr->c_nlink & 0xFFFF;
495 if (short_hdr.c_nlink != file_hdr->c_nlink)
496 field_width_warning (file_hdr->c_name, _("number of links"));
497
498 short_hdr.c_rdev = rdev;
499 short_hdr.c_mtimes[0] = file_hdr->c_mtime >> 16;
500 short_hdr.c_mtimes[1] = file_hdr->c_mtime & 0xFFFF;
501
502 short_hdr.c_namesize = file_hdr->c_namesize & 0xFFFF;
503 if (short_hdr.c_namesize != file_hdr->c_namesize)
504 {
505 field_width_error (file_hdr->c_name, _("name size"));
506 return 1;
507 }
508
509 short_hdr.c_filesizes[0] = file_hdr->c_filesize >> 16;
510 short_hdr.c_filesizes[1] = file_hdr->c_filesize & 0xFFFF;
511
512 if ((short_hdr.c_filesizes[0] << 16) + short_hdr.c_filesizes[1]
513 != file_hdr->c_filesize)
514 {
515 field_width_error (file_hdr->c_name, _("file size"));
516 return 1;
517 }
518
519 /* Output the file header. */
520 tape_buffered_write ((char *) &short_hdr, out_des, 26);
521
522 /* Write file name to output. */
523 tape_buffered_write (file_hdr->c_name, out_des, file_hdr->c_namesize);
524
525 tape_pad_output (out_des, file_hdr->c_namesize + 26);
526 return 0;
527}
528
529
530
531/* Write out header FILE_HDR, including the file name, to file
532 descriptor OUT_DES. */
533
534int
535write_out_header (struct cpio_file_stat *file_hdr, int out_des)
536{
537 dev_t dev;
538 dev_t rdev;
539
540 switch (archive_format)
541 {
542 case arf_newascii:
543 return write_out_new_ascii_header ("070701", file_hdr, out_des);
544
545 case arf_crcascii:
546 return write_out_new_ascii_header ("070702", file_hdr, out_des);
547
548 case arf_oldascii:
549 return write_out_old_ascii_header (makedev (file_hdr->c_dev_maj,
550 file_hdr->c_dev_min),
551 makedev (file_hdr->c_rdev_maj,
552 file_hdr->c_rdev_min),
553 file_hdr, out_des);
554
555 case arf_hpoldascii:
556 hp_compute_dev (file_hdr, &dev, &rdev);
557 return write_out_old_ascii_header (dev, rdev, file_hdr, out_des);
558
559 case arf_tar:
560 case arf_ustar:
561 if (is_tar_filename_too_long (file_hdr->c_name))
562 {
563 error (0, 0, _("%s: file name too long"), file_hdr->c_name);
564 return 1;
565 }
566 write_out_tar_header (file_hdr, out_des); /* FIXME: No error checking */
567 return 0;
568
569 case arf_binary:
570 return write_out_binary_header (makedev (file_hdr->c_rdev_maj,
571 file_hdr->c_rdev_min),
572 file_hdr, out_des);
573
574 case arf_hpbinary:
575 hp_compute_dev (file_hdr, &dev, &rdev);
576 /* FIXME: dev ignored. Should it be? */
577 return write_out_binary_header (rdev, file_hdr, out_des);
578
579 default:
580 abort ();
581 }
582}
583
584/* Read a list of file names from the standard input
585 and write a cpio collection on the standard output.
586 The format of the header depends on the compatibility (-c) flag. */
587
588void
589process_copy_out ()
590{
591 int res; /* Result of functions. */
592 dynamic_string input_name; /* Name of file read from stdin. */
593 struct stat file_stat; /* Stat record for file. */
594 struct cpio_file_stat file_hdr; /* Output header information. */
595 int in_file_des; /* Source file descriptor. */
596 int out_file_des; /* Output file descriptor. */
597
598 /* Initialize the copy out. */
599 ds_init (&input_name, 128);
600 file_hdr.c_magic = 070707;
601
602 /* Check whether the output file might be a tape. */
603 out_file_des = archive_des;
604 if (_isrmt (out_file_des))
605 {
606 output_is_special = 1;
607 output_is_seekable = 0;
608 }
609 else
610 {
611 if (fstat (out_file_des, &file_stat))
612 error (1, errno, _("standard output is closed"));
613 output_is_special =
614#ifdef S_ISBLK
615 S_ISBLK (file_stat.st_mode) ||
616#endif
617 S_ISCHR (file_stat.st_mode);
618 output_is_seekable = S_ISREG (file_stat.st_mode);
619 }
620
621 if (append_flag)
622 {
623 process_copy_in ();
624 prepare_append (out_file_des);
625 }
626
627 /* Copy files with names read from stdin. */
628 while (ds_fgetstr (stdin, &input_name, name_end) != NULL)
629 {
630 /* Check for blank line. */
631 if (input_name.ds_string[0] == 0)
632 {
633 error (0, 0, _("blank line ignored"));
634 continue;
635 }
636
637 /* Process next file. */
638 if ((*xstat) (input_name.ds_string, &file_stat) < 0)
639 stat_error (input_name.ds_string);
640 else
641 {
642 char *orig_file_name;
643
644 /* Set values in output header. */
645 stat_to_cpio (&file_hdr, &file_stat);
646
647 if (archive_format == arf_tar || archive_format == arf_ustar)
648 {
649 if (file_hdr.c_mode & CP_IFDIR)
650 {
651 int len = strlen (input_name.ds_string);
652 /* Make sure the name ends with a slash */
653 if (input_name.ds_string[len-1] != '/')
654 {
655 ds_resize (&input_name, len + 2);
656 input_name.ds_string[len] = '/';
657 input_name.ds_string[len+1] = 0;
658 }
659 }
660 }
661
662 orig_file_name = strdup (input_name.ds_string);
663 cpio_safer_name_suffix (input_name.ds_string, false,
664 !no_abs_paths_flag, true);
665#ifndef HPUX_CDF
666 file_hdr.c_name = input_name.ds_string;
667 file_hdr.c_namesize = strlen (input_name.ds_string) + 1;
668#else
669 if ( (archive_format != arf_tar) && (archive_format != arf_ustar) )
670 {
671 /* We mark CDF's in cpio files by adding a 2nd `/' after the
672 "hidden" directory name. We need to do this so we can
673 properly recreate the directory as hidden (in case the
674 files of a directory go into the archive before the
675 directory itself (e.g from "find ... -depth ... | cpio")). */
676 file_hdr.c_name = add_cdf_double_slashes (input_name.ds_string);
677 file_hdr.c_namesize = strlen (file_hdr.c_name) + 1;
678 }
679 else
680 {
681 /* We don't mark CDF's in tar files. We assume the "hidden"
682 directory will always go into the archive before any of
683 its files. */
684 file_hdr.c_name = input_name.ds_string;
685 file_hdr.c_namesize = strlen (input_name.ds_string) + 1;
686 }
687#endif
688
689 /* Copy the named file to the output. */
690 switch (file_hdr.c_mode & CP_IFMT)
691 {
692 case CP_IFREG:
693 if (archive_format == arf_tar || archive_format == arf_ustar)
694 {
695 char *otherfile;
696 if ((otherfile = find_inode_file (file_hdr.c_ino,
697 file_hdr.c_dev_maj,
698 file_hdr.c_dev_min)))
699 {
700 file_hdr.c_tar_linkname = otherfile;
701 if (write_out_header (&file_hdr, out_file_des))
702 continue;
703 break;
704 }
705 }
706 if ( (archive_format == arf_newascii || archive_format == arf_crcascii)
707 && (file_hdr.c_nlink > 1) )
708 {
709 if (last_link (&file_hdr) )
710 {
711 writeout_other_defers (&file_hdr, out_file_des);
712 }
713 else
714 {
715 add_link_defer (&file_hdr);
716 break;
717 }
718 }
719 in_file_des = open (orig_file_name,
720 O_RDONLY | O_BINARY, 0);
721 if (in_file_des < 0)
722 {
723 open_error (orig_file_name);
724 continue;
725 }
726
727 if (archive_format == arf_crcascii)
728 file_hdr.c_chksum = read_for_checksum (in_file_des,
729 file_hdr.c_filesize,
730 orig_file_name);
731
732 if (write_out_header (&file_hdr, out_file_des))
733 continue;
734 copy_files_disk_to_tape (in_file_des,
735 out_file_des, file_hdr.c_filesize,
736 orig_file_name);
737 warn_if_file_changed(orig_file_name, file_hdr.c_filesize,
738 file_hdr.c_mtime);
739
740 if (archive_format == arf_tar || archive_format == arf_ustar)
741 add_inode (file_hdr.c_ino, orig_file_name, file_hdr.c_dev_maj,
742 file_hdr.c_dev_min);
743
744 tape_pad_output (out_file_des, file_hdr.c_filesize);
745
746 if (close (in_file_des) < 0)
747 close_error (orig_file_name);
748 if (reset_time_flag)
749 set_file_times (orig_file_name,
750 file_stat.st_atime, file_stat.st_mtime);
751 break;
752
753 case CP_IFDIR:
754 file_hdr.c_filesize = 0;
755 if (write_out_header (&file_hdr, out_file_des))
756 continue;
757 break;
758
759 case CP_IFCHR:
760 case CP_IFBLK:
761#ifdef CP_IFSOCK
762 case CP_IFSOCK:
763#endif
764#ifdef CP_IFIFO
765 case CP_IFIFO:
766#endif
767 if (archive_format == arf_tar)
768 {
769 error (0, 0, _("%s not dumped: not a regular file"),
770 orig_file_name);
771 continue;
772 }
773 else if (archive_format == arf_ustar)
774 {
775 char *otherfile;
776 if ((otherfile = find_inode_file (file_hdr.c_ino,
777 file_hdr.c_dev_maj,
778 file_hdr.c_dev_min)))
779 {
780 /* This file is linked to another file already in the
781 archive, so write it out as a hard link. */
782 file_hdr.c_mode = (file_stat.st_mode & 07777);
783 file_hdr.c_mode |= CP_IFREG;
784 file_hdr.c_tar_linkname = otherfile;
785 if (write_out_header (&file_hdr, out_file_des))
786 continue;
787 break;
788 }
789 add_inode (file_hdr.c_ino, orig_file_name,
790 file_hdr.c_dev_maj, file_hdr.c_dev_min);
791 }
792 file_hdr.c_filesize = 0;
793 if (write_out_header (&file_hdr, out_file_des))
794 continue;
795 break;
796
797#ifdef CP_IFLNK
798 case CP_IFLNK:
799 {
800 char *link_name = (char *) xmalloc (file_stat.st_size + 1);
801 int link_size;
802
803 link_size = readlink (orig_file_name, link_name,
804 file_stat.st_size);
805 if (link_size < 0)
806 {
807 readlink_warn (orig_file_name);
808 free (link_name);
809 continue;
810 }
811 cpio_safer_name_suffix (link_name, false,
812 !no_abs_paths_flag, true);
813 link_size = strlen (link_name);
814 file_hdr.c_filesize = link_size;
815 if (archive_format == arf_tar || archive_format == arf_ustar)
816 {
817 if (link_size + 1 > 100)
818 {
819 error (0, 0, _("%s: symbolic link too long"),
820 file_hdr.c_name);
821 }
822 else
823 {
824 link_name[link_size] = '\0';
825 file_hdr.c_tar_linkname = link_name;
826 if (write_out_header (&file_hdr, out_file_des))
827 continue;
828 }
829 }
830 else
831 {
832 if (write_out_header (&file_hdr, out_file_des))
833 continue;
834 tape_buffered_write (link_name, out_file_des, link_size);
835 tape_pad_output (out_file_des, link_size);
836 }
837 free (link_name);
838 }
839 break;
840#endif
841
842 default:
843 error (0, 0, _("%s: unknown file type"), orig_file_name);
844 }
845
846 if (verbose_flag)
847 fprintf (stderr, "%s\n", orig_file_name);
848 if (dot_flag)
849 fputc ('.', stderr);
850 free (orig_file_name);
851 }
852 }
853
854 writeout_final_defers(out_file_des);
855 /* The collection is complete; append the trailer. */
856 file_hdr.c_ino = 0;
857 file_hdr.c_mode = 0;
858 file_hdr.c_uid = 0;
859 file_hdr.c_gid = 0;
860 file_hdr.c_nlink = 1; /* Must be 1 for crc format. */
861 file_hdr.c_dev_maj = 0;
862 file_hdr.c_dev_min = 0;
863 file_hdr.c_rdev_maj = 0;
864 file_hdr.c_rdev_min = 0;
865 file_hdr.c_mtime = 0;
866 file_hdr.c_chksum = 0;
867
868 file_hdr.c_filesize = 0;
869 file_hdr.c_namesize = 11;
870 file_hdr.c_name = CPIO_TRAILER_NAME;
871 if (archive_format != arf_tar && archive_format != arf_ustar)
872 write_out_header (&file_hdr, out_file_des);
873 else
874 write_nuls_to_file (1024, out_file_des, tape_buffered_write);
875
876 /* Fill up the output block. */
877 tape_clear_rest_of_block (out_file_des);
878 tape_empty_output_buffer (out_file_des);
879 if (dot_flag)
880 fputc ('\n', stderr);
881 if (!quiet_flag)
882 {
883 res = (output_bytes + io_block_size - 1) / io_block_size;
884 fprintf (stderr, ngettext ("%d block\n", "%d blocks\n", res), res);
885 }
886}
887
888
Note: See TracBrowser for help on using the repository browser.