Use BBLOCK.
[dragonfly.git] / contrib / cpio / copyin.c
blobcbef8e6fb98d8ef00855253ca85fef843441f07f
1 /* copyin.c - extract or list a cpio archive
2 Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 $FreeBSD: src/contrib/cpio/copyin.c,v 1.6.6.1 2002/03/12 19:10:14 phantom Exp $
19 $DragonFly: src/contrib/cpio/copyin.c,v 1.2 2003/06/17 04:23:58 dillon Exp $
22 #include <stdio.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #ifdef HAVE_SYS_PARAM_H
26 #include <sys/param.h>
27 #endif
28 #if (defined(BSD) && (BSD >= 199306))
29 #define HAVE_STRFTIME
30 #include <ctype.h>
31 #endif
32 #include "filetypes.h"
33 #include "system.h"
34 #include "cpiohdr.h"
35 #include "dstring.h"
36 #include "extern.h"
37 #include "defer.h"
38 #include "rmt.h"
39 #ifndef FNM_PATHNAME
40 #include <fnmatch.h>
41 #endif
42 #if defined(HAVE_STRFTIME) && defined(__FreeBSD__)
43 #include <langinfo.h>
44 #endif
46 #ifndef HAVE_LCHOWN
47 #define lchown chown
48 #endif
50 static void read_pattern_file ();
51 static void tape_skip_padding ();
52 static void defer_copyin ();
53 static void create_defered_links ();
54 static void create_final_defers ();
56 /* Return 16-bit integer I with the bytes swapped. */
57 #define swab_short(i) ((((i) << 8) & 0xff00) | (((i) >> 8) & 0x00ff))
59 /* Read the header, including the name of the file, from file
60 descriptor IN_DES into FILE_HDR. */
62 void
63 read_in_header (file_hdr, in_des)
64 struct new_cpio_header *file_hdr;
65 int in_des;
67 long bytes_skipped = 0; /* Bytes of junk found before magic number. */
69 /* Search for a valid magic number. */
71 if (archive_format == arf_unknown)
73 char tmpbuf[512];
74 int check_tar;
75 int peeked_bytes;
77 while (archive_format == arf_unknown)
79 peeked_bytes = tape_buffered_peek (tmpbuf, in_des, 512);
80 if (peeked_bytes < 6)
81 error (1, 0, "premature end of archive");
83 if (!strncmp (tmpbuf, "070701", 6))
84 archive_format = arf_newascii;
85 else if (!strncmp (tmpbuf, "070707", 6))
86 archive_format = arf_oldascii;
87 else if (!strncmp (tmpbuf, "070702", 6))
89 archive_format = arf_crcascii;
90 crc_i_flag = TRUE;
92 else if ((*((unsigned short *) tmpbuf) == 070707) ||
93 (*((unsigned short *) tmpbuf) == swab_short ((unsigned short) 070707)))
94 archive_format = arf_binary;
95 else if (peeked_bytes >= 512
96 && (check_tar = is_tar_header (tmpbuf)))
98 if (check_tar == 2)
99 archive_format = arf_ustar;
100 else
101 archive_format = arf_tar;
103 else
105 tape_buffered_read ((char *) tmpbuf, in_des, 1L);
106 ++bytes_skipped;
111 if (archive_format == arf_tar || archive_format == arf_ustar)
113 if (append_flag)
114 last_header_start = input_bytes - io_block_size +
115 (in_buff - input_buffer);
116 if (bytes_skipped > 0)
117 error (0, 0, "warning: skipped %ld bytes of junk", bytes_skipped);
118 read_in_tar_header (file_hdr, in_des);
119 return;
122 file_hdr->c_tar_linkname = NULL;
124 tape_buffered_read ((char *) file_hdr, in_des, 6L);
125 while (1)
127 if (append_flag)
128 last_header_start = input_bytes - io_block_size
129 + (in_buff - input_buffer) - 6;
130 if (archive_format == arf_newascii
131 && !strncmp ((char *) file_hdr, "070701", 6))
133 if (bytes_skipped > 0)
134 error (0, 0, "warning: skipped %ld bytes of junk", bytes_skipped);
135 read_in_new_ascii (file_hdr, in_des);
136 break;
138 if (archive_format == arf_crcascii
139 && !strncmp ((char *) file_hdr, "070702", 6))
141 if (bytes_skipped > 0)
142 error (0, 0, "warning: skipped %ld bytes of junk", bytes_skipped);
143 read_in_new_ascii (file_hdr, in_des);
144 break;
146 if ( (archive_format == arf_oldascii || archive_format == arf_hpoldascii)
147 && !strncmp ((char *) file_hdr, "070707", 6))
149 if (bytes_skipped > 0)
150 error (0, 0, "warning: skipped %ld bytes of junk", bytes_skipped);
151 read_in_old_ascii (file_hdr, in_des);
152 break;
154 if ( (archive_format == arf_binary || archive_format == arf_hpbinary)
155 && (file_hdr->c_magic == 070707
156 || file_hdr->c_magic == swab_short ((unsigned short) 070707)))
158 /* Having to skip 1 byte because of word alignment is normal. */
159 if (bytes_skipped > 0)
160 error (0, 0, "warning: skipped %ld bytes of junk", bytes_skipped);
161 read_in_binary (file_hdr, in_des);
162 break;
164 bytes_skipped++;
165 bcopy ((char *) file_hdr + 1, (char *) file_hdr, 5);
166 tape_buffered_read ((char *) file_hdr + 5, in_des, 1L);
170 /* Fill in FILE_HDR by reading an old-format ASCII format cpio header from
171 file descriptor IN_DES, except for the magic number, which is
172 already filled in. */
174 void
175 read_in_old_ascii (file_hdr, in_des)
176 struct new_cpio_header *file_hdr;
177 int in_des;
179 char ascii_header[78];
180 unsigned long dev;
181 unsigned long rdev;
183 tape_buffered_read (ascii_header, in_des, 70L);
184 ascii_header[70] = '\0';
185 sscanf (ascii_header,
186 "%6lo%6lo%6lo%6lo%6lo%6lo%6lo%11lo%6lo%11lo",
187 &dev, &file_hdr->c_ino,
188 &file_hdr->c_mode, &file_hdr->c_uid, &file_hdr->c_gid,
189 &file_hdr->c_nlink, &rdev, &file_hdr->c_mtime,
190 &file_hdr->c_namesize, &file_hdr->c_filesize);
191 file_hdr->c_dev_maj = major (dev);
192 file_hdr->c_dev_min = minor (dev);
193 file_hdr->c_rdev_maj = major (rdev);
194 file_hdr->c_rdev_min = minor (rdev);
196 /* Read file name from input. */
197 if (file_hdr->c_name != NULL)
198 free (file_hdr->c_name);
199 file_hdr->c_name = (char *) xmalloc (file_hdr->c_namesize + 1);
200 tape_buffered_read (file_hdr->c_name, in_des, (long) file_hdr->c_namesize);
201 #ifndef __MSDOS__
202 /* HP/UX cpio creates archives that look just like ordinary archives,
203 but for devices it sets major = 0, minor = 1, and puts the
204 actual major/minor number in the filesize field. See if this
205 is an HP/UX cpio archive, and if so fix it. We have to do this
206 here because process_copy_in() assumes filesize is always 0
207 for devices. */
208 switch (file_hdr->c_mode & CP_IFMT)
210 case CP_IFCHR:
211 case CP_IFBLK:
212 #ifdef CP_IFSOCK
213 case CP_IFSOCK:
214 #endif
215 #ifdef CP_IFIFO
216 case CP_IFIFO:
217 #endif
218 if (file_hdr->c_filesize != 0
219 && file_hdr->c_rdev_maj == 0
220 && file_hdr->c_rdev_min == 1)
222 file_hdr->c_rdev_maj = major (file_hdr->c_filesize);
223 file_hdr->c_rdev_min = minor (file_hdr->c_filesize);
224 file_hdr->c_filesize = 0;
226 break;
227 default:
228 break;
230 #endif /* __MSDOS__ */
233 /* Fill in FILE_HDR by reading a new-format ASCII format cpio header from
234 file descriptor IN_DES, except for the magic number, which is
235 already filled in. */
237 void
238 read_in_new_ascii (file_hdr, in_des)
239 struct new_cpio_header *file_hdr;
240 int in_des;
242 char ascii_header[112];
244 tape_buffered_read (ascii_header, in_des, 104L);
245 ascii_header[104] = '\0';
246 sscanf (ascii_header,
247 "%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx%8lx",
248 &file_hdr->c_ino, &file_hdr->c_mode, &file_hdr->c_uid,
249 &file_hdr->c_gid, &file_hdr->c_nlink, &file_hdr->c_mtime,
250 &file_hdr->c_filesize, &file_hdr->c_dev_maj, &file_hdr->c_dev_min,
251 &file_hdr->c_rdev_maj, &file_hdr->c_rdev_min, &file_hdr->c_namesize,
252 &file_hdr->c_chksum);
253 /* Read file name from input. */
254 if (file_hdr->c_name != NULL)
255 free (file_hdr->c_name);
256 file_hdr->c_name = (char *) xmalloc (file_hdr->c_namesize);
257 tape_buffered_read (file_hdr->c_name, in_des, (long) file_hdr->c_namesize);
259 /* In SVR4 ASCII format, the amount of space allocated for the header
260 is rounded up to the next long-word, so we might need to drop
261 1-3 bytes. */
262 tape_skip_padding (in_des, file_hdr->c_namesize + 110);
265 /* Fill in FILE_HDR by reading a binary format cpio header from
266 file descriptor IN_DES, except for the first 6 bytes (the magic
267 number, device, and inode number), which are already filled in. */
269 void
270 read_in_binary (file_hdr, in_des)
271 struct new_cpio_header *file_hdr;
272 int in_des;
274 struct old_cpio_header short_hdr;
276 /* Copy the data into the short header, then later transfer
277 it into the argument long header. */
278 short_hdr.c_dev = ((struct old_cpio_header *) file_hdr)->c_dev;
279 short_hdr.c_ino = ((struct old_cpio_header *) file_hdr)->c_ino;
280 tape_buffered_read (((char *) &short_hdr) + 6, in_des, 20L);
282 /* If the magic number is byte swapped, fix the header. */
283 if (file_hdr->c_magic == swab_short ((unsigned short) 070707))
285 static int warned = 0;
287 /* Alert the user that they might have to do byte swapping on
288 the file contents. */
289 if (warned == 0)
291 error (0, 0, "warning: archive header has reverse byte-order");
292 warned = 1;
294 swab_array ((char *) &short_hdr, 13);
297 file_hdr->c_dev_maj = major (short_hdr.c_dev);
298 file_hdr->c_dev_min = minor (short_hdr.c_dev);
299 file_hdr->c_ino = short_hdr.c_ino;
300 file_hdr->c_mode = short_hdr.c_mode;
301 file_hdr->c_uid = short_hdr.c_uid;
302 file_hdr->c_gid = short_hdr.c_gid;
303 file_hdr->c_nlink = short_hdr.c_nlink;
304 file_hdr->c_rdev_maj = major (short_hdr.c_rdev);
305 file_hdr->c_rdev_min = minor (short_hdr.c_rdev);
306 file_hdr->c_mtime = (unsigned long) short_hdr.c_mtimes[0] << 16
307 | short_hdr.c_mtimes[1];
309 file_hdr->c_namesize = short_hdr.c_namesize;
310 file_hdr->c_filesize = (unsigned long) short_hdr.c_filesizes[0] << 16
311 | short_hdr.c_filesizes[1];
313 /* Read file name from input. */
314 if (file_hdr->c_name != NULL)
315 free (file_hdr->c_name);
316 file_hdr->c_name = (char *) xmalloc (file_hdr->c_namesize);
317 tape_buffered_read (file_hdr->c_name, in_des, (long) file_hdr->c_namesize);
319 /* In binary mode, the amount of space allocated in the header for
320 the filename is `c_namesize' rounded up to the next short-word,
321 so we might need to drop a byte. */
322 if (file_hdr->c_namesize % 2)
323 tape_toss_input (in_des, 1L);
325 #ifndef __MSDOS__
326 /* HP/UX cpio creates archives that look just like ordinary archives,
327 but for devices it sets major = 0, minor = 1, and puts the
328 actual major/minor number in the filesize field. See if this
329 is an HP/UX cpio archive, and if so fix it. We have to do this
330 here because process_copy_in() assumes filesize is always 0
331 for devices. */
332 switch (file_hdr->c_mode & CP_IFMT)
334 case CP_IFCHR:
335 case CP_IFBLK:
336 #ifdef CP_IFSOCK
337 case CP_IFSOCK:
338 #endif
339 #ifdef CP_IFIFO
340 case CP_IFIFO:
341 #endif
342 if (file_hdr->c_filesize != 0
343 && file_hdr->c_rdev_maj == 0
344 && file_hdr->c_rdev_min == 1)
346 file_hdr->c_rdev_maj = major (file_hdr->c_filesize);
347 file_hdr->c_rdev_min = minor (file_hdr->c_filesize);
348 file_hdr->c_filesize = 0;
350 break;
351 default:
352 break;
354 #endif /* __MSDOS__ */
357 /* Exchange the bytes of each element of the array of COUNT shorts
358 starting at PTR. */
360 void
361 swab_array (ptr, count)
362 char *ptr;
363 int count;
365 char tmp;
367 while (count-- > 0)
369 tmp = *ptr;
370 *ptr = *(ptr + 1);
371 ++ptr;
372 *ptr = tmp;
373 ++ptr;
377 /* Current time for verbose table. */
378 static time_t current_time;
380 /* Read the collection from standard input and create files
381 in the file system. */
383 void
384 process_copy_in ()
386 char done = FALSE; /* True if trailer reached. */
387 int res; /* Result of various function calls. */
388 dynamic_string new_name; /* New file name for rename option. */
389 FILE *tty_in; /* Interactive file for rename option. */
390 FILE *tty_out; /* Interactive file for rename option. */
391 FILE *rename_in; /* Batch file for rename option. */
392 char *str_res; /* Result for string function. */
393 struct utimbuf times; /* For setting file times. */
394 struct stat file_stat; /* Output file stat record. */
395 struct new_cpio_header file_hdr; /* Output header information. */
396 int out_file_des; /* Output file descriptor. */
397 int in_file_des; /* Input file descriptor. */
398 char skip_file; /* Flag for use with patterns. */
399 int existing_dir; /* True if file is a dir & already exists. */
400 int i; /* Loop index variable. */
401 char *link_name = NULL; /* Name of hard and symbolic links. */
402 #ifdef HPUX_CDF
403 int cdf_flag; /* True if file is a CDF. */
404 int cdf_char; /* Index of `+' char indicating a CDF. */
405 #endif
407 /* Initialize the copy in. */
408 if (pattern_file_name)
409 read_pattern_file ();
410 file_hdr.c_name = NULL;
411 ds_init (&new_name, 128);
412 /* Initialize this in case it has members we don't know to set. */
413 bzero (&times, sizeof (struct utimbuf));
415 if (rename_batch_file)
417 rename_in = fopen (rename_batch_file, "r");
418 if (rename_in == NULL)
419 error (2, errno, CONSOLE);
421 else if (rename_flag)
423 /* Open interactive file pair for rename operation. */
424 tty_in = fopen (CONSOLE, "r");
425 if (tty_in == NULL)
426 error (2, errno, CONSOLE);
427 tty_out = fopen (CONSOLE, "w");
428 if (tty_out == NULL)
429 error (2, errno, CONSOLE);
432 /* Get date and time if needed for processing the table option. */
433 if (table_flag && verbose_flag)
434 time (&current_time);
436 #ifdef __MSDOS__
437 setmode (archive_des, O_BINARY);
438 #endif
439 /* Check whether the input file might be a tape. */
440 in_file_des = archive_des;
441 if (_isrmt (in_file_des))
443 input_is_special = 1;
444 input_is_seekable = 0;
446 else
448 if (fstat (in_file_des, &file_stat))
449 error (1, errno, "standard input is closed");
450 input_is_special =
451 #ifdef S_ISBLK
452 S_ISBLK (file_stat.st_mode) ||
453 #endif
454 S_ISCHR (file_stat.st_mode);
455 input_is_seekable = S_ISREG (file_stat.st_mode);
457 output_is_seekable = TRUE;
459 /* While there is more input in the collection, process the input. */
460 while (!done)
462 link_name = NULL;
463 swapping_halfwords = swapping_bytes = FALSE;
465 /* Start processing the next file by reading the header. */
466 read_in_header (&file_hdr, in_file_des);
468 #ifdef DEBUG_CPIO
469 if (debug_flag)
471 struct new_cpio_header *h;
472 h = &file_hdr;
473 fprintf (stderr,
474 "magic = 0%o, ino = %d, mode = 0%o, uid = %d, gid = %d\n",
475 h->c_magic, h->c_ino, h->c_mode, h->c_uid, h->c_gid);
476 fprintf (stderr,
477 "nlink = %d, mtime = %d, filesize = %d, dev_maj = 0x%x\n",
478 h->c_nlink, h->c_mtime, h->c_filesize, h->c_dev_maj);
479 fprintf (stderr,
480 "dev_min = 0x%x, rdev_maj = 0x%x, rdev_min = 0x%x, namesize = %d\n",
481 h->c_dev_min, h->c_rdev_maj, h->c_rdev_min, h->c_namesize);
482 fprintf (stderr,
483 "chksum = %d, name = \"%s\", tar_linkname = \"%s\"\n",
484 h->c_chksum, h->c_name,
485 h->c_tar_linkname ? h->c_tar_linkname : "(null)" );
488 #endif
489 /* Is this the header for the TRAILER file? */
490 if (strcmp ("TRAILER!!!", file_hdr.c_name) == 0)
492 done = TRUE;
493 break;
496 /* Do we have to ignore absolute paths, and if so, does the filename
497 have an absolute path? */
498 if (no_abs_paths_flag && file_hdr.c_name && file_hdr.c_name [0] == '/')
500 char *p;
502 p = file_hdr.c_name;
503 while (*p == '/')
504 ++p;
505 if (*p == '\0')
507 strcpy (file_hdr.c_name, ".");
509 else
511 char *non_abs_name;
513 non_abs_name = (char *) xmalloc (strlen (p) + 1);
514 strcpy (non_abs_name, p);
515 free (file_hdr.c_name);
516 file_hdr.c_name = non_abs_name;
520 /* Does the file name match one of the given patterns? */
521 if (num_patterns <= 0)
522 skip_file = FALSE;
523 else
525 skip_file = copy_matching_files;
526 for (i = 0; i < num_patterns
527 && skip_file == copy_matching_files; i++)
529 if (fnmatch (save_patterns[i], file_hdr.c_name, 0) == 0)
530 skip_file = !copy_matching_files;
534 if (skip_file)
536 tape_toss_input (in_file_des, file_hdr.c_filesize);
537 tape_skip_padding (in_file_des, file_hdr.c_filesize);
539 else if (table_flag)
541 if (verbose_flag)
543 #ifdef CP_IFLNK
544 if ((file_hdr.c_mode & CP_IFMT) == CP_IFLNK)
546 if (archive_format != arf_tar && archive_format != arf_ustar)
548 link_name = (char *) xmalloc ((unsigned int) file_hdr.c_filesize + 1);
549 link_name[file_hdr.c_filesize] = '\0';
550 tape_buffered_read (link_name, in_file_des, file_hdr.c_filesize);
551 long_format (&file_hdr, link_name);
552 free (link_name);
553 tape_skip_padding (in_file_des, file_hdr.c_filesize);
554 continue;
556 else
558 long_format (&file_hdr, file_hdr.c_tar_linkname);
559 continue;
562 else
563 #endif
564 long_format (&file_hdr, (char *) 0);
566 else
567 printf ("%s\n", file_hdr.c_name);
569 crc = 0;
570 tape_toss_input (in_file_des, file_hdr.c_filesize);
571 tape_skip_padding (in_file_des, file_hdr.c_filesize);
572 if (only_verify_crc_flag)
574 #ifdef CP_IFLNK
575 if ((file_hdr.c_mode & CP_IFMT) == CP_IFLNK)
576 continue; /* links don't have a checksum */
577 #endif
578 if (crc != file_hdr.c_chksum)
579 error (0, 0, "%s: checksum error (0x%x, should be 0x%x)",
580 file_hdr.c_name, crc, file_hdr.c_chksum);
583 else if (append_flag)
585 tape_toss_input (in_file_des, file_hdr.c_filesize);
586 tape_skip_padding (in_file_des, file_hdr.c_filesize);
588 else if (only_verify_crc_flag)
590 #ifdef CP_IFLNK
591 if ((file_hdr.c_mode & CP_IFMT) == CP_IFLNK)
593 if (archive_format != arf_tar && archive_format != arf_ustar)
595 tape_toss_input (in_file_des, file_hdr.c_filesize);
596 tape_skip_padding (in_file_des, file_hdr.c_filesize);
597 continue;
600 #endif
601 crc = 0;
602 tape_toss_input (in_file_des, file_hdr.c_filesize);
603 tape_skip_padding (in_file_des, file_hdr.c_filesize);
604 if (crc != file_hdr.c_chksum)
605 error (0, 0, "%s: checksum error (0x%x, should be 0x%x)",
606 file_hdr.c_name, crc, file_hdr.c_chksum);
608 else
610 /* Copy the input file into the directory structure. */
612 /* Do we need to rename the file? */
613 if (rename_flag || rename_batch_file)
615 if (rename_flag)
617 fprintf (tty_out, "rename %s -> ", file_hdr.c_name);
618 fflush (tty_out);
619 str_res = ds_fgets (tty_in, &new_name);
621 else
623 str_res = ds_fgetstr (rename_in, &new_name, '\n');
625 if (str_res == NULL || str_res[0] == 0)
627 tape_toss_input (in_file_des, file_hdr.c_filesize);
628 tape_skip_padding (in_file_des, file_hdr.c_filesize);
629 continue;
631 else
632 file_hdr.c_name = xstrdup (new_name.ds_string);
635 /* See if the file already exists. */
636 existing_dir = FALSE;
637 if (lstat (file_hdr.c_name, &file_stat) == 0)
639 if (S_ISDIR (file_stat.st_mode)
640 && ((file_hdr.c_mode & CP_IFMT) == CP_IFDIR))
642 /* If there is already a directory there that
643 we are trying to create, don't complain about
644 it. */
645 existing_dir = TRUE;
647 else if (!unconditional_flag
648 && file_hdr.c_mtime <= file_stat.st_mtime)
650 error (0, 0, "%s not created: newer or same age version exists",
651 file_hdr.c_name);
652 tape_toss_input (in_file_des, file_hdr.c_filesize);
653 tape_skip_padding (in_file_des, file_hdr.c_filesize);
654 continue; /* Go to the next file. */
656 else if (S_ISDIR (file_stat.st_mode)
657 ? rmdir (file_hdr.c_name)
658 : unlink (file_hdr.c_name))
660 error (0, errno, "cannot remove current %s",
661 file_hdr.c_name);
662 tape_toss_input (in_file_des, file_hdr.c_filesize);
663 tape_skip_padding (in_file_des, file_hdr.c_filesize);
664 continue; /* Go to the next file. */
668 /* Do the real copy or link. */
669 switch (file_hdr.c_mode & CP_IFMT)
671 case CP_IFREG:
672 #ifndef __MSDOS__
673 /* Can the current file be linked to a previously copied file? */
674 if (file_hdr.c_nlink > 1 && (archive_format == arf_newascii
675 || archive_format == arf_crcascii) )
677 int link_res;
678 if (file_hdr.c_filesize == 0)
680 /* The newc and crc formats store multiply linked copies
681 of the same file in the archive only once. The
682 actual data is attached to the last link in the
683 archive, and the other links all have a filesize
684 of 0. Since this file has multiple links and a
685 filesize of 0, its data is probably attatched to
686 another file in the archive. Save the link, and
687 process it later when we get the actual data. We
688 can't just create it with length 0 and add the
689 data later, in case the file is readonly. We still
690 lose if its parent directory is readonly (and we aren't
691 running as root), but there's nothing we can do about
692 that. */
693 defer_copyin (&file_hdr);
694 tape_toss_input (in_file_des, file_hdr.c_filesize);
695 tape_skip_padding (in_file_des, file_hdr.c_filesize);
696 break;
698 /* If the file has data (filesize != 0), then presumably
699 any other links have already been defer_copyin'ed(),
700 but GNU cpio version 2.0-2.2 didn't do that, so we
701 still have to check for links here (and also in case
702 the archive was created and later appeneded to). */
703 link_res = link_to_maj_min_ino (file_hdr.c_name,
704 file_hdr.c_dev_maj, file_hdr.c_dev_maj,
705 file_hdr.c_ino);
706 if (link_res == 0)
708 tape_toss_input (in_file_des, file_hdr.c_filesize);
709 tape_skip_padding (in_file_des, file_hdr.c_filesize);
710 break;
713 else if (file_hdr.c_nlink > 1 && archive_format != arf_tar
714 && archive_format != arf_ustar)
716 int link_res;
717 link_res = link_to_maj_min_ino (file_hdr.c_name,
718 file_hdr.c_dev_maj, file_hdr.c_dev_maj,
719 file_hdr.c_ino);
720 if (link_res == 0)
722 tape_toss_input (in_file_des, file_hdr.c_filesize);
723 tape_skip_padding (in_file_des, file_hdr.c_filesize);
724 break;
727 else if ((archive_format == arf_tar || archive_format == arf_ustar)
728 && file_hdr.c_tar_linkname &&
729 file_hdr.c_tar_linkname[0] != '\0')
731 int link_res;
732 link_res = link_to_name (file_hdr.c_name,
733 file_hdr.c_tar_linkname);
734 if (link_res < 0)
736 error (0, errno, "cannot link %s to %s",
737 file_hdr.c_tar_linkname, file_hdr.c_name);
739 break;
741 #endif
743 /* If not linked, copy the contents of the file. */
744 if (link_name == NULL)
746 out_file_des = open (file_hdr.c_name,
747 O_CREAT | O_WRONLY | O_BINARY, 0600);
748 if (out_file_des < 0 && create_dir_flag)
750 create_all_directories (file_hdr.c_name);
751 out_file_des = open (file_hdr.c_name,
752 O_CREAT | O_WRONLY | O_BINARY,
753 0600);
755 if (out_file_des < 0)
757 error (0, errno, "%s", file_hdr.c_name);
758 tape_toss_input (in_file_des, file_hdr.c_filesize);
759 tape_skip_padding (in_file_des, file_hdr.c_filesize);
760 continue;
763 crc = 0;
764 if (swap_halfwords_flag)
766 if ((file_hdr.c_filesize % 4) == 0)
767 swapping_halfwords = TRUE;
768 else
769 error (0, 0, "cannot swap halfwords of %s: odd number of halfwords",
770 file_hdr.c_name);
772 if (swap_bytes_flag)
774 if ((file_hdr.c_filesize % 2) == 0)
775 swapping_bytes = TRUE;
776 else
777 error (0, 0, "cannot swap bytes of %s: odd number of bytes",
778 file_hdr.c_name);
780 copy_files_tape_to_disk (in_file_des, out_file_des, file_hdr.c_filesize);
781 disk_empty_output_buffer (out_file_des);
782 if (close (out_file_des) < 0)
783 error (0, errno, "%s", file_hdr.c_name);
785 if (archive_format == arf_crcascii)
787 if (crc != file_hdr.c_chksum)
788 error (0, 0, "%s: checksum error (0x%x, should be 0x%x)",
789 file_hdr.c_name, crc, file_hdr.c_chksum);
791 /* File is now copied; set attributes. */
792 if (!no_chown_flag)
793 if ((chown (file_hdr.c_name,
794 set_owner_flag ? set_owner : file_hdr.c_uid,
795 set_group_flag ? set_group : file_hdr.c_gid) < 0)
796 && errno != EPERM)
797 error (0, errno, "%s", file_hdr.c_name);
798 /* chown may have turned off some permissions we wanted. */
799 if (chmod (file_hdr.c_name, (int) file_hdr.c_mode) < 0)
800 error (0, errno, "%s", file_hdr.c_name);
801 if (retain_time_flag)
803 times.actime = times.modtime = file_hdr.c_mtime;
804 if (utime (file_hdr.c_name, &times) < 0)
805 error (0, errno, "%s", file_hdr.c_name);
807 tape_skip_padding (in_file_des, file_hdr.c_filesize);
808 if (file_hdr.c_nlink > 1 && (archive_format == arf_newascii
809 || archive_format == arf_crcascii) )
811 /* (see comment above for how the newc and crc formats
812 store multiple links). Now that we have the data
813 for this file, create any other links to it which
814 we defered. */
815 create_defered_links (&file_hdr);
818 break;
820 case CP_IFDIR:
821 /* Strip any trailing `/'s off the filename; tar puts
822 them on. We might as well do it here in case anybody
823 else does too, since they cause strange things to happen. */
824 strip_trailing_slashes (file_hdr.c_name);
826 /* Ignore the current directory. It must already exist,
827 and we don't want to change its permission, ownership
828 or time. */
829 if (file_hdr.c_name[0] == '.' && file_hdr.c_name[1] == '\0')
830 break;
832 #ifdef HPUX_CDF
833 cdf_flag = 0;
834 #endif
835 if (!existing_dir)
838 #ifdef HPUX_CDF
839 /* If the directory name ends in a + and is SUID,
840 then it is a CDF. Strip the trailing + from
841 the name before creating it. */
842 cdf_char = strlen (file_hdr.c_name) - 1;
843 if ( (cdf_char > 0) &&
844 (file_hdr.c_mode & 04000) &&
845 (file_hdr.c_name [cdf_char] == '+') )
847 file_hdr.c_name [cdf_char] = '\0';
848 cdf_flag = 1;
850 #endif
851 res = mkdir (file_hdr.c_name, file_hdr.c_mode);
853 else
854 res = 0;
855 if (res < 0 && create_dir_flag)
857 create_all_directories (file_hdr.c_name);
858 res = mkdir (file_hdr.c_name, file_hdr.c_mode);
860 if (res < 0)
862 /* In some odd cases where the file_hdr.c_name includes `.',
863 the directory may have actually been created by
864 create_all_directories(), so the mkdir will fail
865 because the directory exists. If that's the case,
866 don't complain about it. */
867 if ( (errno != EEXIST) ||
868 (lstat (file_hdr.c_name, &file_stat) != 0) ||
869 !(S_ISDIR (file_stat.st_mode) ) )
871 error (0, errno, "%s", file_hdr.c_name);
872 continue;
875 if (!no_chown_flag)
876 if ((chown (file_hdr.c_name,
877 set_owner_flag ? set_owner : file_hdr.c_uid,
878 set_group_flag ? set_group : file_hdr.c_gid) < 0)
879 && errno != EPERM)
880 error (0, errno, "%s", file_hdr.c_name);
881 /* chown may have turned off some permissions we wanted. */
882 if (chmod (file_hdr.c_name, (int) file_hdr.c_mode) < 0)
883 error (0, errno, "%s", file_hdr.c_name);
884 #ifdef HPUX_CDF
885 if (cdf_flag)
886 /* Once we "hide" the directory with the chmod(),
887 we have to refer to it using name+ instead of name. */
888 file_hdr.c_name [cdf_char] = '+';
889 #endif
890 if (retain_time_flag)
892 times.actime = times.modtime = file_hdr.c_mtime;
893 if (utime (file_hdr.c_name, &times) < 0)
894 error (0, errno, "%s", file_hdr.c_name);
896 break;
898 #ifndef __MSDOS__
899 case CP_IFCHR:
900 case CP_IFBLK:
901 #ifdef CP_IFSOCK
902 case CP_IFSOCK:
903 #endif
904 #ifdef CP_IFIFO
905 case CP_IFIFO:
906 #endif
907 if (file_hdr.c_nlink > 1 && archive_format != arf_tar
908 && archive_format != arf_ustar)
910 int link_res;
911 link_res = link_to_maj_min_ino (file_hdr.c_name,
912 file_hdr.c_dev_maj, file_hdr.c_dev_maj,
913 file_hdr.c_ino);
914 if (link_res == 0)
915 break;
917 else if (archive_format == arf_ustar &&
918 file_hdr.c_tar_linkname &&
919 file_hdr.c_tar_linkname [0] != '\0')
921 int link_res;
922 link_res = link_to_name (file_hdr.c_name,
923 file_hdr.c_tar_linkname);
924 if (link_res < 0)
926 error (0, errno, "cannot link %s to %s",
927 file_hdr.c_tar_linkname, file_hdr.c_name);
928 /* Something must be wrong, because we couldn't
929 find the file to link to. But can we assume
930 that the device maj/min numbers are correct
931 and fall through to the mknod? It's probably
932 safer to just break, rather than possibly
933 creating a bogus device file. */
935 break;
938 #ifdef CP_IFIFO
939 if ((file_hdr.c_mode & CP_IFMT) == CP_IFIFO)
940 res = mkfifo (file_hdr.c_name, file_hdr.c_mode);
941 else
942 #endif
943 res = mknod (file_hdr.c_name, file_hdr.c_mode,
944 makedev (file_hdr.c_rdev_maj, file_hdr.c_rdev_min));
945 if (res < 0 && create_dir_flag)
947 create_all_directories (file_hdr.c_name);
948 #ifdef CP_IFIFO
949 if ((file_hdr.c_mode & CP_IFMT) == CP_IFIFO)
950 res = mkfifo (file_hdr.c_name, file_hdr.c_mode);
951 else
952 #endif
953 res = mknod (file_hdr.c_name, file_hdr.c_mode,
954 makedev (file_hdr.c_rdev_maj,
955 file_hdr.c_rdev_min));
957 if (res < 0)
959 error (0, errno, "%s", file_hdr.c_name);
960 continue;
962 if (!no_chown_flag)
963 if ((chown (file_hdr.c_name,
964 set_owner_flag ? set_owner : file_hdr.c_uid,
965 set_group_flag ? set_group : file_hdr.c_gid) < 0)
966 && errno != EPERM)
967 error (0, errno, "%s", file_hdr.c_name);
968 /* chown may have turned off some permissions we wanted. */
969 if (chmod (file_hdr.c_name, file_hdr.c_mode) < 0)
970 error (0, errno, "%s", file_hdr.c_name);
971 if (retain_time_flag)
973 times.actime = times.modtime = file_hdr.c_mtime;
974 if (utime (file_hdr.c_name, &times) < 0)
975 error (0, errno, "%s", file_hdr.c_name);
977 break;
978 #endif
980 #ifdef CP_IFLNK
981 case CP_IFLNK:
983 if (archive_format != arf_tar && archive_format != arf_ustar)
985 link_name = (char *) xmalloc ((unsigned int) file_hdr.c_filesize + 1);
986 link_name[file_hdr.c_filesize] = '\0';
987 tape_buffered_read (link_name, in_file_des, file_hdr.c_filesize);
988 tape_skip_padding (in_file_des, file_hdr.c_filesize);
990 else
992 link_name = xstrdup (file_hdr.c_tar_linkname);
995 res = UMASKED_SYMLINK (link_name, file_hdr.c_name,
996 file_hdr.c_mode);
997 if (res < 0 && create_dir_flag)
999 create_all_directories (file_hdr.c_name);
1000 res = UMASKED_SYMLINK (link_name, file_hdr.c_name,
1001 file_hdr.c_mode);
1003 if (res < 0)
1005 error (0, errno, "%s", file_hdr.c_name);
1006 free (link_name);
1007 link_name = NULL;
1008 continue;
1010 if (!no_chown_flag)
1011 if ((lchown (file_hdr.c_name,
1012 set_owner_flag ? set_owner : file_hdr.c_uid,
1013 set_group_flag ? set_group : file_hdr.c_gid) < 0)
1014 && errno != EPERM)
1015 error (0, errno, "%s", file_hdr.c_name);
1016 free (link_name);
1017 link_name = NULL;
1019 break;
1020 #endif
1022 default:
1023 error (0, 0, "%s: unknown file type", file_hdr.c_name);
1024 tape_toss_input (in_file_des, file_hdr.c_filesize);
1025 tape_skip_padding (in_file_des, file_hdr.c_filesize);
1028 if (verbose_flag)
1029 fprintf (stderr, "%s\n", file_hdr.c_name);
1030 if (dot_flag)
1031 fputc ('.', stderr);
1035 if (dot_flag)
1036 fputc ('\n', stderr);
1038 if (append_flag)
1039 return;
1041 if (archive_format == arf_newascii || archive_format == arf_crcascii)
1042 create_final_defers ();
1043 if (!quiet_flag)
1045 res = (input_bytes + io_block_size - 1) / io_block_size;
1046 if (res == 1)
1047 fprintf (stderr, "1 block\n");
1048 else
1049 fprintf (stderr, "%d blocks\n", res);
1053 /* Print the file described by FILE_HDR in long format.
1054 If LINK_NAME is nonzero, it is the name of the file that
1055 this file is a symbolic link to. */
1057 void
1058 long_format (file_hdr, link_name)
1059 struct new_cpio_header *file_hdr;
1060 char *link_name;
1062 char mbuf[11];
1063 char tbuf[40];
1064 time_t when;
1065 char *ptbuf;
1066 #ifdef HAVE_STRFTIME
1067 static int d_first = -1;
1068 #endif
1070 mode_string (file_hdr->c_mode, mbuf);
1071 mbuf[10] = '\0';
1073 /* Get time values ready to print. */
1074 when = file_hdr->c_mtime;
1075 #ifdef HAVE_STRFTIME
1076 #ifdef __FreeBSD__
1077 if (d_first < 0)
1078 d_first = (*nl_langinfo(D_MD_ORDER) == 'd');
1079 #else
1080 d_first = 0;
1081 #endif
1082 if (current_time - when > 6L * 30L * 24L * 60L * 60L
1083 || current_time - when < 0L)
1084 ptbuf = d_first ? "%e %b %Y" : "%b %e %Y";
1085 else
1086 ptbuf = d_first ? "%e %b %R" : "%b %e %R";
1087 strftime(tbuf, sizeof(tbuf), ptbuf, localtime(&when));
1088 ptbuf = tbuf;
1089 #else
1090 strcpy (tbuf, ctime (&when));
1091 if (current_time - when > 6L * 30L * 24L * 60L * 60L
1092 || current_time - when < 0L)
1094 /* The file is older than 6 months, or in the future.
1095 Show the year instead of the time of day. */
1096 strcpy (tbuf + 11, tbuf + 19);
1098 tbuf[16] = '\0';
1099 ptbuf = tbuf + 4;
1100 #endif
1102 printf ("%s %3lu ", mbuf, file_hdr->c_nlink);
1104 #ifndef __MSDOS__
1105 if (numeric_uid)
1106 #endif
1107 printf ("%-8u %-8u ", (unsigned int) file_hdr->c_uid,
1108 (unsigned int) file_hdr->c_gid);
1109 #ifndef __MSDOS__
1110 else
1111 printf ("%-8.8s %-8.8s ", getuser (file_hdr->c_uid),
1112 getgroup (file_hdr->c_gid));
1114 if ((file_hdr->c_mode & CP_IFMT) == CP_IFCHR
1115 || (file_hdr->c_mode & CP_IFMT) == CP_IFBLK)
1116 printf ("%3lu, %3lu ", file_hdr->c_rdev_maj, file_hdr->c_rdev_min);
1117 else
1118 #endif
1119 printf ("%8lu ", file_hdr->c_filesize);
1121 printf ("%s ", ptbuf);
1123 print_name_with_quoting (file_hdr->c_name);
1124 if (link_name)
1126 printf (" -> ");
1127 print_name_with_quoting (link_name);
1129 putc ('\n', stdout);
1132 void
1133 print_name_with_quoting (p)
1134 register char *p;
1136 register unsigned char c;
1138 while ( (c = *p++) )
1140 switch (c)
1142 #ifndef __MSDOS__
1143 case '\\':
1144 printf ("\\\\");
1145 break;
1146 #endif
1148 case '\n':
1149 printf ("\\n");
1150 break;
1152 case '\b':
1153 printf ("\\b");
1154 break;
1156 case '\r':
1157 printf ("\\r");
1158 break;
1160 case '\t':
1161 printf ("\\t");
1162 break;
1164 case '\f':
1165 printf ("\\f");
1166 break;
1168 case ' ':
1169 printf ("\\ ");
1170 break;
1172 case '"':
1173 printf ("\\\"");
1174 break;
1176 default:
1177 #if (defined(BSD) && (BSD >= 199306))
1178 if (isprint(c))
1179 #else
1180 if (c > 040 &&
1181 #ifdef __MSDOS__
1182 c < 0377 && c != 0177
1183 #else
1184 c < 0177
1185 #endif
1187 #endif
1188 putchar (c);
1189 else
1190 printf ("\\%03o", (unsigned int) c);
1195 /* Read a pattern file (for the -E option). Put a list of
1196 `num_patterns' elements in `save_patterns'. Any patterns that were
1197 already in `save_patterns' (from the command line) are preserved. */
1199 static void
1200 read_pattern_file ()
1202 int max_new_patterns;
1203 char **new_save_patterns;
1204 int new_num_patterns;
1205 int i;
1206 dynamic_string pattern_name;
1207 FILE *pattern_fp;
1209 if (num_patterns < 0)
1210 num_patterns = 0;
1211 max_new_patterns = 1 + num_patterns;
1212 new_save_patterns = (char **) xmalloc (max_new_patterns * sizeof (char *));
1213 new_num_patterns = num_patterns;
1214 ds_init (&pattern_name, 128);
1216 pattern_fp = fopen (pattern_file_name, "r");
1217 if (pattern_fp == NULL)
1218 error (1, errno, "%s", pattern_file_name);
1219 while (ds_fgetstr (pattern_fp, &pattern_name, '\n') != NULL)
1221 if (new_num_patterns >= max_new_patterns)
1223 max_new_patterns += 1;
1224 new_save_patterns = (char **)
1225 xrealloc ((char *) new_save_patterns,
1226 max_new_patterns * sizeof (char *));
1228 new_save_patterns[new_num_patterns] = xstrdup (pattern_name.ds_string);
1229 ++new_num_patterns;
1231 if (ferror (pattern_fp) || fclose (pattern_fp) == EOF)
1232 error (1, errno, "%s", pattern_file_name);
1234 for (i = 0; i < num_patterns; ++i)
1235 new_save_patterns[i] = save_patterns[i];
1237 save_patterns = new_save_patterns;
1238 num_patterns = new_num_patterns;
1241 /* Skip the padding on IN_FILE_DES after a header or file,
1242 up to the next header.
1243 The number of bytes skipped is based on OFFSET -- the current offset
1244 from the last start of a header (or file) -- and the current
1245 header type. */
1247 static void
1248 tape_skip_padding (in_file_des, offset)
1249 int in_file_des;
1250 int offset;
1252 int pad;
1254 if (archive_format == arf_crcascii || archive_format == arf_newascii)
1255 pad = (4 - (offset % 4)) % 4;
1256 else if (archive_format == arf_binary || archive_format == arf_hpbinary)
1257 pad = (2 - (offset % 2)) % 2;
1258 else if (archive_format == arf_tar || archive_format == arf_ustar)
1259 pad = (512 - (offset % 512)) % 512;
1260 else
1261 pad = 0;
1263 if (pad != 0)
1264 tape_toss_input (in_file_des, pad);
1268 /* The newc and crc formats store multiply linked copies of the same file
1269 in the archive only once. The actual data is attached to the last link
1270 in the archive, and the other links all have a filesize of 0. When a
1271 file in the archive has multiple links and a filesize of 0, its data is
1272 probably "attatched" to another file in the archive, so we can't create
1273 it right away. We have to "defer" creating it until we have created
1274 the file that has the data "attatched" to it. We keep a list of the
1275 "defered" links on deferments. */
1277 struct deferment *deferments = NULL;
1279 /* Add a file header to the deferments list. For now they all just
1280 go on one list, although we could optimize this if necessary. */
1282 static void
1283 defer_copyin (file_hdr)
1284 struct new_cpio_header *file_hdr;
1286 struct deferment *d;
1287 d = create_deferment (file_hdr);
1288 d->next = deferments;
1289 deferments = d;
1290 return;
1293 /* We just created a file that (probably) has some other links to it
1294 which have been defered. Go through all of the links on the deferments
1295 list and create any which are links to this file. */
1297 static void
1298 create_defered_links (file_hdr)
1299 struct new_cpio_header *file_hdr;
1301 struct deferment *d;
1302 struct deferment *d_prev;
1303 int ino;
1304 int maj;
1305 int min;
1306 int link_res;
1307 ino = file_hdr->c_ino;
1308 maj = file_hdr->c_dev_maj;
1309 min = file_hdr->c_dev_min;
1310 d = deferments;
1311 d_prev = NULL;
1312 while (d != NULL)
1314 if ( (d->header.c_ino == ino) && (d->header.c_dev_maj == maj)
1315 && (d->header.c_dev_min == min) )
1317 struct deferment *d_free;
1318 link_res = link_to_name (d->header.c_name, file_hdr->c_name);
1319 if (link_res < 0)
1321 error (0, errno, "cannot link %s to %s",
1322 d->header.c_name, file_hdr->c_name);
1324 if (d_prev != NULL)
1325 d_prev->next = d->next;
1326 else
1327 deferments = d->next;
1328 d_free = d;
1329 d = d->next;
1330 free_deferment (d_free);
1332 else
1334 d_prev = d;
1335 d = d->next;
1340 /* If we had a multiply linked file that really was empty then we would
1341 have defered all of its links, since we never found any with data
1342 "attached", and they will still be on the deferment list even when
1343 we are done reading the whole archive. Write out all of these
1344 empty links that are still on the deferments list. */
1346 static void
1347 create_final_defers ()
1349 struct deferment *d;
1350 int link_res;
1351 int out_file_des;
1352 struct utimbuf times; /* For setting file times. */
1353 /* Initialize this in case it has members we don't know to set. */
1354 bzero (&times, sizeof (struct utimbuf));
1356 for (d = deferments; d != NULL; d = d->next)
1358 link_res = link_to_maj_min_ino (d->header.c_name,
1359 d->header.c_dev_maj, d->header.c_dev_maj,
1360 d->header.c_ino);
1361 if (link_res == 0)
1363 continue;
1365 out_file_des = open (d->header.c_name,
1366 O_CREAT | O_WRONLY | O_BINARY, 0600);
1367 if (out_file_des < 0 && create_dir_flag)
1369 create_all_directories (d->header.c_name);
1370 out_file_des = open (d->header.c_name,
1371 O_CREAT | O_WRONLY | O_BINARY,
1372 0600);
1374 if (out_file_des < 0)
1376 error (0, errno, "%s", d->header.c_name);
1377 continue;
1380 if (close (out_file_des) < 0)
1381 error (0, errno, "%s", d->header.c_name);
1383 /* File is now copied; set attributes. */
1384 if (!no_chown_flag)
1385 if ((chown (d->header.c_name,
1386 set_owner_flag ? set_owner : d->header.c_uid,
1387 set_group_flag ? set_group : d->header.c_gid) < 0)
1388 && errno != EPERM)
1389 error (0, errno, "%s", d->header.c_name);
1390 /* chown may have turned off some permissions we wanted. */
1391 if (chmod (d->header.c_name, (int) d->header.c_mode) < 0)
1392 error (0, errno, "%s", d->header.c_name);
1393 if (retain_time_flag)
1395 times.actime = times.modtime = d->header.c_mtime;
1396 if (utime (d->header.c_name, &times) < 0)
1397 error (0, errno, "%s", d->header.c_name);