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