]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/cpio/src/copyout.c
This commit was generated by cvs2svn to compensate for changes in r152058,
[FreeBSD/FreeBSD.git] / contrib / cpio / src / copyout.c
1 /* $FreeBSD$ */
2
3 /* copyout.c - create a cpio archive
4    Copyright (C) 1990, 1991, 1992, 2001, 2003, 2004 Free Software Foundation, Inc.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2, or (at your option)
9    any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License along
17    with this program; if not, write to the Free Software Foundation, Inc.,
18    59 Temple Place - Suite 330, Boston, MA 02111-1307, 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
32 static int check_rdev ();
33
34 /* Read FILE_SIZE bytes of FILE_NAME from IN_FILE_DES and
35    compute and return a checksum for them.  */
36
37 static unsigned long
38 read_for_checksum (int in_file_des, int file_size, char *file_name)
39 {
40   unsigned long crc;
41   char buf[BUFSIZ];
42   int bytes_left;
43   int bytes_read;
44   int i;
45
46   crc = 0;
47
48   for (bytes_left = file_size; bytes_left > 0; bytes_left -= bytes_read)
49     {
50       bytes_read = read (in_file_des, buf, BUFSIZ);
51       if (bytes_read < 0)
52         error (1, errno, _("cannot read checksum for %s"), file_name);
53       if (bytes_read == 0)
54         break;
55       if (bytes_left < bytes_read)
56         bytes_read = bytes_left;
57       for (i = 0; i < bytes_read; ++i)
58         crc += buf[i] & 0xff;
59     }
60   if (lseek (in_file_des, 0L, SEEK_SET))
61     error (1, errno, _("cannot read checksum for %s"), file_name);
62
63   return crc;
64 }
65
66 /* Write out NULs to fill out the rest of the current block on
67    OUT_FILE_DES.  */
68
69 static void
70 tape_clear_rest_of_block (int out_file_des)
71 {
72   while (output_size < io_block_size)
73     {
74       if ((io_block_size - output_size) > 512)
75         tape_buffered_write (zeros_512, out_file_des, 512);
76       else
77         tape_buffered_write (zeros_512, out_file_des, io_block_size - output_size);
78     }
79 }
80
81 /* Write NULs on OUT_FILE_DES to move from OFFSET (the current location)
82    to the end of the header.  */
83
84 static void
85 tape_pad_output (int out_file_des, int offset)
86 {
87   int pad;
88
89   if (archive_format == arf_newascii || archive_format == arf_crcascii)
90     pad = (4 - (offset % 4)) % 4;
91   else if (archive_format == arf_tar || archive_format == arf_ustar)
92     pad = (512 - (offset % 512)) % 512;
93   else if (archive_format != arf_oldascii && archive_format != arf_hpoldascii)
94     pad = (2 - (offset % 2)) % 2;
95   else
96     pad = 0;
97
98   if (pad != 0)
99     tape_buffered_write (zeros_512, out_file_des, pad);
100 }
101
102
103 /* When creating newc and crc archives if a file has multiple (hard)
104    links, we don't put any of them into the archive until we have seen
105    all of them (or until we get to the end of the list of files that
106    are going into the archive and know that we have seen all of the links
107    to the file that we will see).  We keep these "defered" files on
108    this list.   */
109
110 struct deferment *deferouts = NULL;
111
112 /* Count the number of other (hard) links to this file that have
113    already been defered.  */
114
115 static int
116 count_defered_links_to_dev_ino (struct new_cpio_header *file_hdr)
117 {
118   struct deferment *d;
119   int   ino;
120   int   maj;
121   int   min;
122   int   count;
123   ino = file_hdr->c_ino;
124   maj = file_hdr->c_dev_maj;
125   min = file_hdr->c_dev_min;
126   count = 0;
127   for (d = deferouts; d != NULL; d = d->next)
128     {
129       if ( (d->header.c_ino == ino) && (d->header.c_dev_maj == maj)
130           && (d->header.c_dev_min == min) )
131         ++count;
132     }
133   return count;
134 }
135
136 /* Is this file_hdr the last (hard) link to a file?  I.e., have
137    we already seen and defered all of the other links?  */
138
139 static int
140 last_link (struct new_cpio_header *file_hdr)
141 {
142   int   other_files_sofar;
143
144   other_files_sofar = count_defered_links_to_dev_ino (file_hdr);
145   if (file_hdr->c_nlink == (other_files_sofar + 1) )
146     {
147       return 1;
148     }
149   return 0;
150 }
151
152
153 /* Add the file header for a link that is being defered to the deferouts
154    list.  */
155
156 static void
157 add_link_defer (struct new_cpio_header *file_hdr)
158 {
159   struct deferment *d;
160   d = create_deferment (file_hdr);
161   d->next = deferouts;
162   deferouts = d;
163 }
164
165 /* We are about to put a file into a newc or crc archive that is
166    multiply linked.  We have already seen and defered all of the
167    other links to the file but haven't written them into the archive.
168    Write the other links into the archive, and remove them from the
169    deferouts list.  */
170
171 static void
172 writeout_other_defers (struct new_cpio_header *file_hdr, int out_des)
173 {
174   struct deferment *d;
175   struct deferment *d_prev;
176   int   ino;
177   int   maj;
178   int   min;
179   ino = file_hdr->c_ino;
180   maj = file_hdr->c_dev_maj;
181   min = file_hdr->c_dev_min;
182   d_prev = NULL;
183   d = deferouts;
184   while (d != NULL)
185     {
186       if ( (d->header.c_ino == ino) && (d->header.c_dev_maj == maj)
187           && (d->header.c_dev_min == min) )
188         {
189           struct deferment *d_free;
190           d->header.c_filesize = 0;
191           write_out_header (&d->header, out_des);
192           if (d_prev != NULL)
193             d_prev->next = d->next;
194           else
195             deferouts = d->next;
196           d_free = d;
197           d = d->next;
198           free_deferment (d_free);
199         }
200       else
201         {
202           d_prev = d;
203           d = d->next;
204         }
205     }
206   return;
207 }
208
209 /* Write a file into the archive.  This code is the same as
210    the code in process_copy_out(), but we need it here too
211    for writeout_final_defers() to call.  */
212
213 static void
214 writeout_defered_file (struct new_cpio_header *header, int out_file_des)
215 {
216   int in_file_des;
217   struct new_cpio_header file_hdr;
218   struct utimbuf times;         /* For setting file times.  */
219   /* Initialize this in case it has members we don't know to set.  */
220   bzero (&times, sizeof (struct utimbuf));
221
222   file_hdr = *header;
223
224
225   in_file_des = open (header->c_name,
226                       O_RDONLY | O_BINARY, 0);
227   if (in_file_des < 0)
228     {
229       error (0, errno, "%s", header->c_name);
230       return;
231     }
232
233   if (archive_format == arf_crcascii)
234     file_hdr.c_chksum = read_for_checksum (in_file_des,
235                                            file_hdr.c_filesize,
236                                            header->c_name);
237
238   write_out_header (&file_hdr, out_file_des);
239   copy_files_disk_to_tape (in_file_des, out_file_des, file_hdr.c_filesize, header->c_name);
240   warn_if_file_changed(header->c_name, file_hdr.c_filesize, file_hdr.c_mtime);
241
242   if (archive_format == arf_tar || archive_format == arf_ustar)
243     add_inode (file_hdr.c_ino, file_hdr.c_name, file_hdr.c_dev_maj,
244                file_hdr.c_dev_min);
245
246   tape_pad_output (out_file_des, file_hdr.c_filesize);
247
248   if (close (in_file_des) < 0)
249     error (0, errno, "%s", header->c_name);
250   if (reset_time_flag)
251     {
252       times.actime = file_hdr.c_mtime;
253       times.modtime = file_hdr.c_mtime;
254       /* Debian hack: Silently ignore EROFS because reading the file
255          won't have upset its timestamp if it's on a read-only
256          filesystem.  This has been submitted as a suggestion to
257          "bug-gnu-utils@prep.ai.mit.edu".  -BEM */
258       if (utime (file_hdr.c_name, &times) < 0
259           && errno != EROFS)
260         error (0, errno, "%s", file_hdr.c_name);
261     }
262   return;
263 }
264
265 /* When writing newc and crc format archives we defer multiply linked
266    files until we have seen all of the links to the file.  If a file
267    has links to it that aren't going into the archive, then we will
268    never see the "last" link to the file, so at the end we just write 
269    all of the leftover defered files into the archive.  */
270
271 static void
272 writeout_final_defers (int out_des)
273 {
274   struct deferment *d;
275   int other_count;
276   while (deferouts != NULL)
277     {
278       d = deferouts;
279       other_count = count_defered_links_to_dev_ino (&d->header);
280       if (other_count == 1)
281         {
282           writeout_defered_file (&d->header, out_des);
283         }
284       else
285         {
286           struct new_cpio_header file_hdr;
287           file_hdr = d->header;
288           file_hdr.c_filesize = 0;
289           write_out_header (&file_hdr, out_des);
290         }
291       deferouts = deferouts->next;
292     }
293 }
294
295 \f
296 /* Write out header FILE_HDR, including the file name, to file
297    descriptor OUT_DES.  */
298
299 void
300 write_out_header (struct new_cpio_header *file_hdr, int out_des)
301 {
302   if (archive_format == arf_newascii || archive_format == arf_crcascii)
303     {
304       char ascii_header[112];
305       char *magic_string;
306
307       if (archive_format == arf_crcascii)
308         magic_string = "070702";
309       else
310         magic_string = "070701";
311       sprintf (ascii_header,
312                "%6s%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx",
313                magic_string,
314                file_hdr->c_ino, file_hdr->c_mode, file_hdr->c_uid,
315                file_hdr->c_gid, file_hdr->c_nlink, file_hdr->c_mtime,
316              file_hdr->c_filesize, file_hdr->c_dev_maj, file_hdr->c_dev_min,
317            file_hdr->c_rdev_maj, file_hdr->c_rdev_min, file_hdr->c_namesize,
318                file_hdr->c_chksum);
319       tape_buffered_write (ascii_header, out_des, 110L);
320
321       /* Write file name to output.  */
322       tape_buffered_write (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
323       tape_pad_output (out_des, file_hdr->c_namesize + 110);
324     }
325   else if (archive_format == arf_oldascii || archive_format == arf_hpoldascii)
326     {
327       char ascii_header[78];
328       dev_t dev;
329       dev_t rdev;
330
331       if (archive_format == arf_oldascii)
332         {
333           dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
334           rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
335         }
336       else
337         {
338           /* HP/UX cpio creates archives that look just like ordinary archives,
339              but for devices it sets major = 0, minor = 1, and puts the
340              actual major/minor number in the filesize field.  */
341           switch (file_hdr->c_mode & CP_IFMT)
342             {
343               case CP_IFCHR:
344               case CP_IFBLK:
345 #ifdef CP_IFSOCK
346               case CP_IFSOCK:
347 #endif
348 #ifdef CP_IFIFO
349               case CP_IFIFO:
350 #endif
351                 file_hdr->c_filesize = makedev (file_hdr->c_rdev_maj,
352                                                 file_hdr->c_rdev_min);
353                 rdev = 1;
354                 break;
355               default:
356                 dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
357                 rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
358                 break;
359             }
360         }
361
362       if ((warn_option & CPIO_WARN_TRUNCATE) && (file_hdr->c_ino >> 16) != 0)
363         error (0, 0, _("%s: truncating inode number"), file_hdr->c_name);
364
365       /* Debian hack: The type of dev_t has changed in glibc.  Fixed output
366          to ensure that a long int is passed to sprintf.  This has been
367          reported to "bug-gnu-utils@prep.ai.mit.edu". (1998/5/26) -BEM */
368       sprintf (ascii_header,
369                "%06ho%06lo%06lo%06lo%06lo%06lo%06lo%06lo%011lo%06lo%011lo",
370                file_hdr->c_magic & 0xFFFF, (long) dev & 0xFFFF,
371                file_hdr->c_ino & 0xFFFF, file_hdr->c_mode & 0xFFFF,
372                file_hdr->c_uid & 0xFFFF, file_hdr->c_gid & 0xFFFF,
373                file_hdr->c_nlink & 0xFFFF, (long) rdev & 0xFFFF,
374                file_hdr->c_mtime, file_hdr->c_namesize & 0xFFFF,
375                file_hdr->c_filesize);
376       tape_buffered_write (ascii_header, out_des, 76L);
377
378       /* Write file name to output.  */
379       tape_buffered_write (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
380     }
381   else if (archive_format == arf_tar || archive_format == arf_ustar)
382     {
383       write_out_tar_header (file_hdr, out_des);
384     }
385   else
386     {
387       struct old_cpio_header short_hdr;
388
389       short_hdr.c_magic = 070707;
390       short_hdr.c_dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min);
391
392       if ((warn_option & CPIO_WARN_TRUNCATE) && (file_hdr->c_ino >> 16) != 0)
393         error (0, 0, _("%s: truncating inode number"), file_hdr->c_name);
394
395       short_hdr.c_ino = file_hdr->c_ino & 0xFFFF;
396       short_hdr.c_mode = file_hdr->c_mode & 0xFFFF;
397       short_hdr.c_uid = file_hdr->c_uid & 0xFFFF;
398       short_hdr.c_gid = file_hdr->c_gid & 0xFFFF;
399       short_hdr.c_nlink = file_hdr->c_nlink & 0xFFFF;
400       if (archive_format != arf_hpbinary)
401         short_hdr.c_rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
402       else
403         {
404           switch (file_hdr->c_mode & CP_IFMT)
405             {
406               /* HP/UX cpio creates archives that look just like ordinary 
407                  archives, but for devices it sets major = 0, minor = 1, and 
408                  puts the actual major/minor number in the filesize field.  */
409               case CP_IFCHR:
410               case CP_IFBLK:
411 #ifdef CP_IFSOCK
412               case CP_IFSOCK:
413 #endif
414 #ifdef CP_IFIFO
415               case CP_IFIFO:
416 #endif
417                 file_hdr->c_filesize = makedev (file_hdr->c_rdev_maj,
418                                                 file_hdr->c_rdev_min);
419                 short_hdr.c_rdev = makedev (0, 1);
420                 break;
421               default:
422                 short_hdr.c_rdev = makedev (file_hdr->c_rdev_maj, 
423                                             file_hdr->c_rdev_min);
424                 break;
425             }
426         }
427       short_hdr.c_mtimes[0] = file_hdr->c_mtime >> 16;
428       short_hdr.c_mtimes[1] = file_hdr->c_mtime & 0xFFFF;
429
430       short_hdr.c_namesize = file_hdr->c_namesize & 0xFFFF;
431
432       short_hdr.c_filesizes[0] = file_hdr->c_filesize >> 16;
433       short_hdr.c_filesizes[1] = file_hdr->c_filesize & 0xFFFF;
434
435       /* Output the file header.  */
436       tape_buffered_write ((char *) &short_hdr, out_des, 26L);
437
438       /* Write file name to output.  */
439       tape_buffered_write (file_hdr->c_name, out_des, (long) file_hdr->c_namesize);
440
441       tape_pad_output (out_des, file_hdr->c_namesize + 26);
442     }
443 }
444
445 /* Read a list of file names from the standard input
446    and write a cpio collection on the standard output.
447    The format of the header depends on the compatibility (-c) flag.  */
448
449 void
450 process_copy_out ()
451 {
452   int res;                      /* Result of functions.  */
453   dynamic_string input_name;    /* Name of file read from stdin.  */
454   struct utimbuf times;         /* For resetting file times after copy.  */
455   struct stat file_stat;        /* Stat record for file.  */
456   struct new_cpio_header file_hdr; /* Output header information.  */
457   int in_file_des;              /* Source file descriptor.  */
458   int out_file_des;             /* Output file descriptor.  */
459   char *p;
460
461   /* Initialize the copy out.  */
462   ds_init (&input_name, 128);
463   /* Initialize this in case it has members we don't know to set.  */
464   bzero (&times, sizeof (struct utimbuf));
465   file_hdr.c_magic = 070707;
466
467   /* Check whether the output file might be a tape.  */
468   out_file_des = archive_des;
469   if (_isrmt (out_file_des))
470     {
471       output_is_special = 1;
472       output_is_seekable = 0;
473     }
474   else
475     {
476       if (fstat (out_file_des, &file_stat))
477         error (1, errno, _("standard output is closed"));
478       output_is_special =
479 #ifdef S_ISBLK
480         S_ISBLK (file_stat.st_mode) ||
481 #endif
482         S_ISCHR (file_stat.st_mode);
483       output_is_seekable = S_ISREG (file_stat.st_mode);
484     }
485
486   if (append_flag)
487     {
488       process_copy_in ();
489       prepare_append (out_file_des);
490     }
491
492   /* Copy files with names read from stdin.  */
493   while (ds_fgetstr (stdin, &input_name, name_end) != NULL)
494     {
495       /* Check for blank line.  */
496       if (input_name.ds_string[0] == 0)
497         {
498           error (0, 0, _("blank line ignored"));
499           continue;
500         }
501
502       /* Process next file.  */
503       if ((*xstat) (input_name.ds_string, &file_stat) < 0)
504         error (0, errno, "%s", input_name.ds_string);
505       else
506         {
507           /* Set values in output header.  */
508           file_hdr.c_dev_maj = major (file_stat.st_dev);
509           file_hdr.c_dev_min = minor (file_stat.st_dev);
510           file_hdr.c_ino = file_stat.st_ino;
511           /* For POSIX systems that don't define the S_IF macros,
512              we can't assume that S_ISfoo means the standard Unix
513              S_IFfoo bit(s) are set.  So do it manually, with a
514              different name.  Bleah.  */
515           file_hdr.c_mode = (file_stat.st_mode & 07777);
516           if (S_ISREG (file_stat.st_mode))
517             file_hdr.c_mode |= CP_IFREG;
518           else if (S_ISDIR (file_stat.st_mode))
519             file_hdr.c_mode |= CP_IFDIR;
520 #ifdef S_ISBLK
521           else if (S_ISBLK (file_stat.st_mode))
522             file_hdr.c_mode |= CP_IFBLK;
523 #endif
524 #ifdef S_ISCHR
525           else if (S_ISCHR (file_stat.st_mode))
526             file_hdr.c_mode |= CP_IFCHR;
527 #endif
528 #ifdef S_ISFIFO
529           else if (S_ISFIFO (file_stat.st_mode))
530             file_hdr.c_mode |= CP_IFIFO;
531 #endif
532 #ifdef S_ISLNK
533           else if (S_ISLNK (file_stat.st_mode))
534             file_hdr.c_mode |= CP_IFLNK;
535 #endif
536 #ifdef S_ISSOCK
537           else if (S_ISSOCK (file_stat.st_mode))
538             file_hdr.c_mode |= CP_IFSOCK;
539 #endif
540 #ifdef S_ISNWK
541           else if (S_ISNWK (file_stat.st_mode))
542             file_hdr.c_mode |= CP_IFNWK;
543 #endif
544           file_hdr.c_uid = file_stat.st_uid;
545           file_hdr.c_gid = file_stat.st_gid;
546           file_hdr.c_nlink = file_stat.st_nlink;
547
548           /* The rdev is meaningless except for block and character
549              special files (POSIX standard) and perhaps fifos and
550              sockets.  Clear it for other types of files so that
551              check_rdev() doesn't reject files just because stat()
552              put garbage in st_rdev and so that the output doesn't
553              depend on the garbage.  */
554           switch (file_hdr.c_mode & CP_IFMT)
555             {
556               case CP_IFBLK:
557               case CP_IFCHR:
558 #ifdef CP_IFIFO
559               case CP_IFIFO:
560 #endif
561 #ifdef CP_IFSOCK
562               case CP_IFSOCK:
563 #endif
564                 file_hdr.c_rdev_maj = major (file_stat.st_rdev);
565                 file_hdr.c_rdev_min = minor (file_stat.st_rdev);
566                 break;
567               default:
568                 file_hdr.c_rdev_maj = 0;
569                 file_hdr.c_rdev_min = 0;
570                 break;
571             }
572
573           file_hdr.c_mtime = file_stat.st_mtime;
574           file_hdr.c_filesize = file_stat.st_size;
575           file_hdr.c_chksum = 0;
576           file_hdr.c_tar_linkname = NULL;
577           
578           if (archive_format == arf_tar || archive_format == arf_ustar)
579             {
580               if (file_hdr.c_mode & CP_IFDIR)
581                 {
582                   int len = strlen (input_name.ds_string);
583                   /* Make sure the name ends with a slash */
584                   if (input_name.ds_string[len-1] != '/')
585                     {
586                       ds_resize (&input_name, len + 2);
587                       input_name.ds_string[len] = '/';
588                       input_name.ds_string[len+1] = 0;
589                     }
590                 }
591             }
592           
593           /* Strip leading `./' from the filename.  */
594           p = input_name.ds_string;
595           while (*p == '.' && *(p + 1) == '/')
596             {
597               ++p;
598               while (*p == '/')
599                 ++p;
600             }
601 #ifndef HPUX_CDF
602           file_hdr.c_name = p;
603           file_hdr.c_namesize = strlen (p) + 1;
604 #else
605           if ( (archive_format != arf_tar) && (archive_format != arf_ustar) )
606             {
607               /* We mark CDF's in cpio files by adding a 2nd `/' after the
608                  "hidden" directory name.  We need to do this so we can
609                  properly recreate the directory as hidden (in case the
610                  files of a directory go into the archive before the
611                  directory itself (e.g from "find ... -depth ... | cpio")).  */
612               file_hdr.c_name = add_cdf_double_slashes (p);
613               file_hdr.c_namesize = strlen (file_hdr.c_name) + 1;
614             }
615           else
616             {
617               /* We don't mark CDF's in tar files.  We assume the "hidden"
618                  directory will always go into the archive before any of
619                  its files.  */
620               file_hdr.c_name = p;
621               file_hdr.c_namesize = strlen (p) + 1;
622             }
623 #endif
624           if ((archive_format == arf_tar || archive_format == arf_ustar)
625               && is_tar_filename_too_long (file_hdr.c_name))
626             {
627               error (0, 0, _("%s: file name too long"),
628                      file_hdr.c_name);
629               continue;
630             }
631
632           switch (check_rdev (&file_hdr))
633             {
634               case 1:
635                 error (0, 0, "%s not dumped: major number would be truncated",
636                        file_hdr.c_name);
637                 continue;
638               case 2:
639                 error (0, 0, "%s not dumped: minor number would be truncated",
640                        file_hdr.c_name);
641                 continue;
642               case 4:
643                 error (0, 0, "%s not dumped: device number would be truncated",
644                        file_hdr.c_name);
645                 continue;
646             }
647           
648           /* Copy the named file to the output.  */
649           switch (file_hdr.c_mode & CP_IFMT)
650             {
651             case CP_IFREG:
652               if (archive_format == arf_tar || archive_format == arf_ustar)
653                 {
654                   char *otherfile;
655                   if ((otherfile = find_inode_file (file_hdr.c_ino,
656                                                     file_hdr.c_dev_maj,
657                                                     file_hdr.c_dev_min)))
658                     {
659                       file_hdr.c_tar_linkname = otherfile;
660                       write_out_header (&file_hdr, out_file_des);
661                       break;
662                     }
663                 }
664               if ( (archive_format == arf_newascii || archive_format == arf_crcascii)
665                   && (file_hdr.c_nlink > 1) )
666                 {
667                   if (last_link (&file_hdr) )
668                     {
669                       writeout_other_defers (&file_hdr, out_file_des);
670                     }
671                   else
672                     {
673                       add_link_defer (&file_hdr);
674                       break;
675                     }
676                 }
677               in_file_des = open (input_name.ds_string,
678                                   O_RDONLY | O_BINARY, 0);
679               if (in_file_des < 0)
680                 {
681                   error (0, errno, "%s", input_name.ds_string);
682                   continue;
683                 }
684
685               if (archive_format == arf_crcascii)
686                 file_hdr.c_chksum = read_for_checksum (in_file_des,
687                                                        file_hdr.c_filesize,
688                                                        input_name.ds_string);
689
690               write_out_header (&file_hdr, out_file_des);
691               copy_files_disk_to_tape (in_file_des, out_file_des, file_hdr.c_filesize, input_name.ds_string);
692               warn_if_file_changed(input_name.ds_string, file_hdr.c_filesize,
693                                    file_hdr.c_mtime);
694
695               if (archive_format == arf_tar || archive_format == arf_ustar)
696                 add_inode (file_hdr.c_ino, file_hdr.c_name, file_hdr.c_dev_maj,
697                            file_hdr.c_dev_min);
698
699               tape_pad_output (out_file_des, file_hdr.c_filesize);
700
701               if (close (in_file_des) < 0)
702                 error (0, errno, "%s", input_name.ds_string);
703               if (reset_time_flag)
704                 {
705                   times.actime = file_stat.st_atime;
706                   times.modtime = file_stat.st_mtime;
707                   /* Debian hack: Silently ignore EROFS because
708                      reading the file won't have upset its timestamp
709                      if it's on a read-only filesystem.  This has been
710                      submitted as a suggestion to
711                      "bug-gnu-utils@prep.ai.mit.edu".  -BEM */
712                   if (utime (file_hdr.c_name, &times) < 0
713                       && errno != EROFS)
714                     error (0, errno, "%s", file_hdr.c_name);
715                 }
716               break;
717
718             case CP_IFDIR:
719               file_hdr.c_filesize = 0;
720               write_out_header (&file_hdr, out_file_des);
721               break;
722
723             case CP_IFCHR:
724             case CP_IFBLK:
725 #ifdef CP_IFSOCK
726             case CP_IFSOCK:
727 #endif
728 #ifdef CP_IFIFO
729             case CP_IFIFO:
730 #endif
731               if (archive_format == arf_tar)
732                 {
733                   error (0, 0, _("%s not dumped: not a regular file"),
734                          file_hdr.c_name);
735                   continue;
736                 }
737               else if (archive_format == arf_ustar)
738                 {
739                   char *otherfile;
740                   if ((otherfile = find_inode_file (file_hdr.c_ino,
741                                                     file_hdr.c_dev_maj,
742                                                     file_hdr.c_dev_min)))
743                     {
744                       /* This file is linked to another file already in the 
745                          archive, so write it out as a hard link. */
746                       file_hdr.c_mode = (file_stat.st_mode & 07777);
747                       file_hdr.c_mode |= CP_IFREG;
748                       file_hdr.c_tar_linkname = otherfile;
749                       write_out_header (&file_hdr, out_file_des);
750                       break;
751                     }
752                   add_inode (file_hdr.c_ino, file_hdr.c_name, 
753                              file_hdr.c_dev_maj, file_hdr.c_dev_min);
754                 }
755               file_hdr.c_filesize = 0;
756               write_out_header (&file_hdr, out_file_des);
757               break;
758
759 #ifdef CP_IFLNK
760             case CP_IFLNK:
761               {
762                 char *link_name = (char *) xmalloc (file_stat.st_size + 1);
763                 int link_size;
764
765                 link_size = readlink (input_name.ds_string, link_name,
766                                       file_stat.st_size);
767                 if (link_size < 0)
768                   {
769                     error (0, errno, "%s", input_name.ds_string);
770                     free (link_name);
771                     continue;
772                   }
773                 file_hdr.c_filesize = link_size;
774                 if (archive_format == arf_tar || archive_format == arf_ustar)
775                   {
776                     if (link_size + 1 > 100)
777                       {
778                         error (0, 0, _("%s: symbolic link too long"),
779                                file_hdr.c_name);
780                       }
781                     else
782                       {
783                         link_name[link_size] = '\0';
784                         file_hdr.c_tar_linkname = link_name;
785                         write_out_header (&file_hdr, out_file_des);
786                       }
787                   }
788                 else
789                   {
790                     write_out_header (&file_hdr, out_file_des);
791                     tape_buffered_write (link_name, out_file_des, link_size);
792                     tape_pad_output (out_file_des, link_size);
793                   }
794                 free (link_name);
795               }
796               break;
797 #endif
798
799             default:
800               error (0, 0, _("%s: unknown file type"), input_name.ds_string);
801             }
802
803           if (verbose_flag)
804             fprintf (stderr, "%s\n", input_name.ds_string);
805           if (dot_flag)
806             fputc ('.', stderr);
807         }
808     }
809
810   writeout_final_defers(out_file_des);
811   /* The collection is complete; append the trailer.  */
812   file_hdr.c_ino = 0;
813   file_hdr.c_mode = 0;
814   file_hdr.c_uid = 0;
815   file_hdr.c_gid = 0;
816   file_hdr.c_nlink = 1;         /* Must be 1 for crc format.  */
817   file_hdr.c_dev_maj = 0;
818   file_hdr.c_dev_min = 0;
819   file_hdr.c_rdev_maj = 0;
820   file_hdr.c_rdev_min = 0;
821   file_hdr.c_mtime = 0;
822   file_hdr.c_chksum = 0;
823
824   file_hdr.c_filesize = 0;
825   file_hdr.c_namesize = 11;
826   file_hdr.c_name = "TRAILER!!!";
827   if (archive_format != arf_tar && archive_format != arf_ustar)
828     write_out_header (&file_hdr, out_file_des);
829   else
830     {
831       tape_buffered_write (zeros_512, out_file_des, 512);
832       tape_buffered_write (zeros_512, out_file_des, 512);
833     }
834
835   /* Fill up the output block.  */
836   tape_clear_rest_of_block (out_file_des);
837   tape_empty_output_buffer (out_file_des);
838   if (dot_flag)
839     fputc ('\n', stderr);
840   if (!quiet_flag)
841     {
842       res = (output_bytes + io_block_size - 1) / io_block_size;
843       fprintf (stderr, ngettext ("%d block\n", "%d blocks\n", res), res);
844     }
845 }
846
847 static int
848 check_rdev (file_hdr)
849      struct new_cpio_header *file_hdr;
850 {
851   if (archive_format == arf_newascii || archive_format == arf_crcascii)
852     {
853       if ((file_hdr->c_rdev_maj & 0xFFFFFFFF) != file_hdr->c_rdev_maj)
854         return 1;
855       if ((file_hdr->c_rdev_min & 0xFFFFFFFF) != file_hdr->c_rdev_min)
856         return 2;
857     }
858   else if (archive_format == arf_oldascii || archive_format == arf_hpoldascii)
859     {
860 #ifndef __MSDOS__
861       dev_t rdev;
862
863       rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
864       if (archive_format == arf_oldascii)
865         {
866           if ((rdev & 0xFFFF) != rdev)
867             return 4;
868         }
869       else
870         {
871           switch (file_hdr->c_mode & CP_IFMT)
872             {
873               case CP_IFCHR:
874               case CP_IFBLK:
875 #ifdef CP_IFSOCK
876               case CP_IFSOCK:
877 #endif
878 #ifdef CP_IFIFO
879               case CP_IFIFO:
880 #endif
881                 /* We could handle one more bit if longs are >= 33 bits.  */
882                 if ((rdev & 037777777777) != rdev)
883                   return 4;
884                 break;
885               default:
886                 if ((rdev & 0xFFFF) != rdev)
887                   return 4;
888                 break;
889             }
890         }
891 #endif
892     }
893   else if (archive_format == arf_tar || archive_format == arf_ustar)
894     {
895       /* The major and minor formats are limited to 7 octal digits in ustar
896          format, and to_oct () adds a gratuitous trailing blank to further
897          limit the format to 6 octal digits.  */
898       if ((file_hdr->c_rdev_maj & 0777777) != file_hdr->c_rdev_maj)
899         return 1;
900       if ((file_hdr->c_rdev_min & 0777777) != file_hdr->c_rdev_min)
901         return 2;
902     }
903   else
904     {
905 #ifndef __MSDOS__
906       dev_t rdev;
907
908       rdev = makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
909       if (archive_format != arf_hpbinary)
910         {
911           if ((rdev & 0xFFFF) != rdev)
912         return 4;
913     }
914   else
915     {
916       switch (file_hdr->c_mode & CP_IFMT)
917         {
918           case CP_IFCHR:
919           case CP_IFBLK:
920 #ifdef CP_IFSOCK
921           case CP_IFSOCK:
922 #endif
923 #ifdef CP_IFIFO
924           case CP_IFIFO:
925 #endif
926             if ((rdev & 0xFFFFFFFF) != rdev)
927               return 4;
928             file_hdr->c_filesize = rdev;
929             rdev = makedev (0, 1);
930             break;
931           default:
932             if ((rdev & 0xFFFF) != rdev)
933               return 4;
934             break;
935         }
936     }
937 #endif
938   }
939   return 0;
940 }