]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/libarchive/cpio/cpio.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / libarchive / cpio / cpio.c
1 /*-
2  * Copyright (c) 2003-2007 Tim Kientzle
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer
10  *    in this position and unchanged.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27
28 #include "cpio_platform.h"
29 __FBSDID("$FreeBSD$");
30
31 #include <sys/types.h>
32 #include <archive.h>
33 #include <archive_entry.h>
34
35 #ifdef HAVE_SYS_MKDEV_H
36 #include <sys/mkdev.h>
37 #endif
38 #ifdef HAVE_SYS_STAT_H
39 #include <sys/stat.h>
40 #endif
41 #ifdef HAVE_SYS_TIME_H
42 #include <sys/time.h>
43 #endif
44 #ifdef HAVE_ERRNO_H
45 #include <errno.h>
46 #endif
47 #ifdef HAVE_FCNTL_H
48 #include <fcntl.h>
49 #endif
50 #ifdef HAVE_GRP_H
51 #include <grp.h>
52 #endif
53 #ifdef HAVE_PWD_H
54 #include <pwd.h>
55 #endif
56 #ifdef HAVE_STDARG_H
57 #include <stdarg.h>
58 #endif
59 #ifdef HAVE_STDINT_H
60 #include <stdint.h>
61 #endif
62 #include <stdio.h>
63 #ifdef HAVE_STDLIB_H
64 #include <stdlib.h>
65 #endif
66 #ifdef HAVE_STRING_H
67 #include <string.h>
68 #endif
69 #ifdef HAVE_UNISTD_H
70 #include <unistd.h>
71 #endif
72 #ifdef HAVE_SYS_TIME_H
73 #include <sys/time.h>
74 #endif
75 #ifdef HAVE_TIME_H
76 #include <time.h>
77 #endif
78
79 #include "cpio.h"
80 #include "err.h"
81 #include "line_reader.h"
82 #include "matching.h"
83
84 /* Fixed size of uname/gname caches. */
85 #define name_cache_size 101
86
87 #ifndef O_BINARY
88 #define O_BINARY 0
89 #endif
90
91 struct name_cache {
92         int     probes;
93         int     hits;
94         size_t  size;
95         struct {
96                 id_t id;
97                 char *name;
98         } cache[name_cache_size];
99 };
100
101 static int      extract_data(struct archive *, struct archive *);
102 const char *    cpio_i64toa(int64_t);
103 static const char *cpio_rename(const char *name);
104 static int      entry_to_archive(struct cpio *, struct archive_entry *);
105 static int      file_to_archive(struct cpio *, const char *);
106 static void     free_cache(struct name_cache *cache);
107 static void     list_item_verbose(struct cpio *, struct archive_entry *);
108 static void     long_help(void);
109 static const char *lookup_gname(struct cpio *, gid_t gid);
110 static int      lookup_gname_helper(struct cpio *,
111                     const char **name, id_t gid);
112 static const char *lookup_uname(struct cpio *, uid_t uid);
113 static int      lookup_uname_helper(struct cpio *,
114                     const char **name, id_t uid);
115 static void     mode_in(struct cpio *);
116 static void     mode_list(struct cpio *);
117 static void     mode_out(struct cpio *);
118 static void     mode_pass(struct cpio *, const char *);
119 static int      restore_time(struct cpio *, struct archive_entry *,
120                     const char *, int fd);
121 static void     usage(void);
122 static void     version(void);
123
124 int
125 main(int argc, char *argv[])
126 {
127         static char buff[16384];
128         struct cpio _cpio; /* Allocated on stack. */
129         struct cpio *cpio;
130         const char *errmsg;
131         int uid, gid;
132         int opt;
133
134         cpio = &_cpio;
135         memset(cpio, 0, sizeof(*cpio));
136         cpio->buff = buff;
137         cpio->buff_size = sizeof(buff);
138
139         /* Need lafe_progname before calling lafe_warnc. */
140         if (*argv == NULL)
141                 lafe_progname = "bsdcpio";
142         else {
143 #if defined(_WIN32) && !defined(__CYGWIN__)
144                 lafe_progname = strrchr(*argv, '\\');
145 #else
146                 lafe_progname = strrchr(*argv, '/');
147 #endif
148                 if (lafe_progname != NULL)
149                         lafe_progname++;
150                 else
151                         lafe_progname = *argv;
152         }
153
154         cpio->uid_override = -1;
155         cpio->gid_override = -1;
156         cpio->argv = argv;
157         cpio->argc = argc;
158         cpio->mode = '\0';
159         cpio->verbose = 0;
160         cpio->compress = '\0';
161         cpio->extract_flags = ARCHIVE_EXTRACT_NO_AUTODIR;
162         cpio->extract_flags |= ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER;
163         cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_SYMLINKS;
164         cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_NODOTDOT;
165         cpio->extract_flags |= ARCHIVE_EXTRACT_PERM;
166         cpio->extract_flags |= ARCHIVE_EXTRACT_FFLAGS;
167         cpio->extract_flags |= ARCHIVE_EXTRACT_ACL;
168 #if !defined(_WIN32) && !defined(__CYGWIN__)
169         if (geteuid() == 0)
170                 cpio->extract_flags |= ARCHIVE_EXTRACT_OWNER;
171 #endif
172         cpio->bytes_per_block = 512;
173         cpio->filename = NULL;
174
175         while ((opt = cpio_getopt(cpio)) != -1) {
176                 switch (opt) {
177                 case '0': /* GNU convention: --null, -0 */
178                         cpio->option_null = 1;
179                         break;
180                 case 'A': /* NetBSD/OpenBSD */
181                         cpio->option_append = 1;
182                         break;
183                 case 'a': /* POSIX 1997 */
184                         cpio->option_atime_restore = 1;
185                         break;
186                 case 'B': /* POSIX 1997 */
187                         cpio->bytes_per_block = 5120;
188                         break;
189                 case 'C': /* NetBSD/OpenBSD */
190                         cpio->bytes_per_block = atoi(cpio->optarg);
191                         if (cpio->bytes_per_block <= 0)
192                                 lafe_errc(1, 0, "Invalid blocksize %s", cpio->optarg);
193                         break;
194                 case 'c': /* POSIX 1997 */
195                         cpio->format = "odc";
196                         break;
197                 case 'd': /* POSIX 1997 */
198                         cpio->extract_flags &= ~ARCHIVE_EXTRACT_NO_AUTODIR;
199                         break;
200                 case 'E': /* NetBSD/OpenBSD */
201                         lafe_include_from_file(&cpio->matching,
202                             cpio->optarg, cpio->option_null);
203                         break;
204                 case 'F': /* NetBSD/OpenBSD/GNU cpio */
205                         cpio->filename = cpio->optarg;
206                         break;
207                 case 'f': /* POSIX 1997 */
208                         lafe_exclude(&cpio->matching, cpio->optarg);
209                         break;
210                 case 'H': /* GNU cpio (also --format) */
211                         cpio->format = cpio->optarg;
212                         break;
213                 case 'h':
214                         long_help();
215                         break;
216                 case 'I': /* NetBSD/OpenBSD */
217                         cpio->filename = cpio->optarg;
218                         break;
219                 case 'i': /* POSIX 1997 */
220                         if (cpio->mode != '\0')
221                                 lafe_errc(1, 0,
222                                     "Cannot use both -i and -%c", cpio->mode);
223                         cpio->mode = opt;
224                         break;
225                 case 'J': /* GNU tar, others */
226                         cpio->compress = opt;
227                         break;
228                 case 'j': /* GNU tar, others */
229                         cpio->compress = opt;
230                         break;
231                 case OPTION_INSECURE:
232                         cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_SYMLINKS;
233                         cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT;
234                         break;
235                 case 'L': /* GNU cpio */
236                         cpio->option_follow_links = 1;
237                         break;
238                 case 'l': /* POSIX 1997 */
239                         cpio->option_link = 1;
240                         break;
241                 case OPTION_LZMA: /* GNU tar, others */
242                         cpio->compress = opt;
243                         break;
244                 case 'm': /* POSIX 1997 */
245                         cpio->extract_flags |= ARCHIVE_EXTRACT_TIME;
246                         break;
247                 case 'n': /* GNU cpio */
248                         cpio->option_numeric_uid_gid = 1;
249                         break;
250                 case OPTION_NO_PRESERVE_OWNER: /* GNU cpio */
251                         cpio->extract_flags &= ~ARCHIVE_EXTRACT_OWNER;
252                         break;
253                 case 'O': /* GNU cpio */
254                         cpio->filename = cpio->optarg;
255                         break;
256                 case 'o': /* POSIX 1997 */
257                         if (cpio->mode != '\0')
258                                 lafe_errc(1, 0,
259                                     "Cannot use both -o and -%c", cpio->mode);
260                         cpio->mode = opt;
261                         break;
262                 case 'p': /* POSIX 1997 */
263                         if (cpio->mode != '\0')
264                                 lafe_errc(1, 0,
265                                     "Cannot use both -p and -%c", cpio->mode);
266                         cpio->mode = opt;
267                         cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT;
268                         break;
269                 case OPTION_PRESERVE_OWNER:
270                         cpio->extract_flags |= ARCHIVE_EXTRACT_OWNER;
271                         break;
272                 case OPTION_QUIET: /* GNU cpio */
273                         cpio->quiet = 1;
274                         break;
275                 case 'R': /* GNU cpio, also --owner */
276                         /* TODO: owner_parse should return uname/gname
277                          * also; use that to set [ug]name_override. */
278                         errmsg = owner_parse(cpio->optarg, &uid, &gid);
279                         if (errmsg) {
280                                 lafe_warnc(-1, "%s", errmsg);
281                                 usage();
282                         }
283                         if (uid != -1) {
284                                 cpio->uid_override = uid;
285                                 cpio->uname_override = NULL;
286                         }
287                         if (gid != -1) {
288                                 cpio->gid_override = gid;
289                                 cpio->gname_override = NULL;
290                         }
291                         break;
292                 case 'r': /* POSIX 1997 */
293                         cpio->option_rename = 1;
294                         break;
295                 case 't': /* POSIX 1997 */
296                         cpio->option_list = 1;
297                         break;
298                 case 'u': /* POSIX 1997 */
299                         cpio->extract_flags
300                             &= ~ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER;
301                         break;
302                 case 'v': /* POSIX 1997 */
303                         cpio->verbose++;
304                         break;
305                 case OPTION_VERSION: /* GNU convention */
306                         version();
307                         break;
308 #if 0
309                 /*
310                  * cpio_getopt() handles -W specially, so it's not
311                  * available here.
312                  */
313                 case 'W': /* Obscure, but useful GNU convention. */
314                         break;
315 #endif
316                 case 'y': /* tar convention */
317                         cpio->compress = opt;
318                         break;
319                 case 'Z': /* tar convention */
320                         cpio->compress = opt;
321                         break;
322                 case 'z': /* tar convention */
323                         cpio->compress = opt;
324                         break;
325                 default:
326                         usage();
327                 }
328         }
329
330         /*
331          * Sanity-check args, error out on nonsensical combinations.
332          */
333         /* -t implies -i if no mode was specified. */
334         if (cpio->option_list && cpio->mode == '\0')
335                 cpio->mode = 'i';
336         /* -t requires -i */
337         if (cpio->option_list && cpio->mode != 'i')
338                 lafe_errc(1, 0, "Option -t requires -i");
339         /* -n requires -it */
340         if (cpio->option_numeric_uid_gid && !cpio->option_list)
341                 lafe_errc(1, 0, "Option -n requires -it");
342         /* Can only specify format when writing */
343         if (cpio->format != NULL && cpio->mode != 'o')
344                 lafe_errc(1, 0, "Option --format requires -o");
345         /* -l requires -p */
346         if (cpio->option_link && cpio->mode != 'p')
347                 lafe_errc(1, 0, "Option -l requires -p");
348         /* TODO: Flag other nonsensical combinations. */
349
350         switch (cpio->mode) {
351         case 'o':
352                 /* TODO: Implement old binary format in libarchive,
353                    use that here. */
354                 if (cpio->format == NULL)
355                         cpio->format = "odc"; /* Default format */
356
357                 mode_out(cpio);
358                 break;
359         case 'i':
360                 while (*cpio->argv != NULL) {
361                         lafe_include(&cpio->matching, *cpio->argv);
362                         --cpio->argc;
363                         ++cpio->argv;
364                 }
365                 if (cpio->option_list)
366                         mode_list(cpio);
367                 else
368                         mode_in(cpio);
369                 break;
370         case 'p':
371                 if (*cpio->argv == NULL || **cpio->argv == '\0')
372                         lafe_errc(1, 0,
373                             "-p mode requires a target directory");
374                 mode_pass(cpio, *cpio->argv);
375                 break;
376         default:
377                 lafe_errc(1, 0,
378                     "Must specify at least one of -i, -o, or -p");
379         }
380
381         free_cache(cpio->gname_cache);
382         free_cache(cpio->uname_cache);
383         return (cpio->return_value);
384 }
385
386 static void
387 usage(void)
388 {
389         const char      *p;
390
391         p = lafe_progname;
392
393         fprintf(stderr, "Brief Usage:\n");
394         fprintf(stderr, "  List:    %s -it < archive\n", p);
395         fprintf(stderr, "  Extract: %s -i < archive\n", p);
396         fprintf(stderr, "  Create:  %s -o < filenames > archive\n", p);
397         fprintf(stderr, "  Help:    %s --help\n", p);
398         exit(1);
399 }
400
401 static const char *long_help_msg =
402         "First option must be a mode specifier:\n"
403         "  -i Input  -o Output  -p Pass\n"
404         "Common Options:\n"
405         "  -v    Verbose\n"
406         "Create: %p -o [options]  < [list of files] > [archive]\n"
407         "  -J,-y,-z,--lzma  Compress archive with xz/bzip2/gzip/lzma\n"
408         "  --format {odc|newc|ustar}  Select archive format\n"
409         "List: %p -it < [archive]\n"
410         "Extract: %p -i [options] < [archive]\n";
411
412
413 /*
414  * Note that the word 'bsdcpio' will always appear in the first line
415  * of output.
416  *
417  * In particular, /bin/sh scripts that need to test for the presence
418  * of bsdcpio can use the following template:
419  *
420  * if (cpio --help 2>&1 | grep bsdcpio >/dev/null 2>&1 ) then \
421  *          echo bsdcpio; else echo not bsdcpio; fi
422  */
423 static void
424 long_help(void)
425 {
426         const char      *prog;
427         const char      *p;
428
429         prog = lafe_progname;
430
431         fflush(stderr);
432
433         p = (strcmp(prog,"bsdcpio") != 0) ? "(bsdcpio)" : "";
434         printf("%s%s: manipulate archive files\n", prog, p);
435
436         for (p = long_help_msg; *p != '\0'; p++) {
437                 if (*p == '%') {
438                         if (p[1] == 'p') {
439                                 fputs(prog, stdout);
440                                 p++;
441                         } else
442                                 putchar('%');
443                 } else
444                         putchar(*p);
445         }
446         version();
447 }
448
449 static void
450 version(void)
451 {
452         fprintf(stdout,"bsdcpio %s -- %s\n",
453             BSDCPIO_VERSION_STRING,
454             archive_version());
455         exit(0);
456 }
457
458 static void
459 mode_out(struct cpio *cpio)
460 {
461         struct archive_entry *entry, *spare;
462         struct lafe_line_reader *lr;
463         const char *p;
464         int r;
465
466         if (cpio->option_append)
467                 lafe_errc(1, 0, "Append mode not yet supported.");
468
469         cpio->archive_read_disk = archive_read_disk_new();
470         if (cpio->archive_read_disk == NULL)
471                 lafe_errc(1, 0, "Failed to allocate archive object");
472         if (cpio->option_follow_links)
473                 archive_read_disk_set_symlink_logical(cpio->archive_read_disk);
474         else
475                 archive_read_disk_set_symlink_physical(cpio->archive_read_disk);
476         archive_read_disk_set_standard_lookup(cpio->archive_read_disk);
477
478         cpio->archive = archive_write_new();
479         if (cpio->archive == NULL)
480                 lafe_errc(1, 0, "Failed to allocate archive object");
481         switch (cpio->compress) {
482         case 'J':
483                 r = archive_write_set_compression_xz(cpio->archive);
484                 break;
485         case OPTION_LZMA:
486                 r = archive_write_set_compression_lzma(cpio->archive);
487                 break;
488         case 'j': case 'y':
489                 r = archive_write_set_compression_bzip2(cpio->archive);
490                 break;
491         case 'z':
492                 r = archive_write_set_compression_gzip(cpio->archive);
493                 break;
494         case 'Z':
495                 r = archive_write_set_compression_compress(cpio->archive);
496                 break;
497         default:
498                 r = archive_write_set_compression_none(cpio->archive);
499                 break;
500         }
501         if (r < ARCHIVE_WARN)
502                 lafe_errc(1, 0, "Requested compression not available");
503         r = archive_write_set_format_by_name(cpio->archive, cpio->format);
504         if (r != ARCHIVE_OK)
505                 lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
506         archive_write_set_bytes_per_block(cpio->archive, cpio->bytes_per_block);
507         cpio->linkresolver = archive_entry_linkresolver_new();
508         archive_entry_linkresolver_set_strategy(cpio->linkresolver,
509             archive_format(cpio->archive));
510
511         /*
512          * The main loop:  Copy each file into the output archive.
513          */
514         r = archive_write_open_file(cpio->archive, cpio->filename);
515         if (r != ARCHIVE_OK)
516                 lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
517         lr = lafe_line_reader("-", cpio->option_null);
518         while ((p = lafe_line_reader_next(lr)) != NULL)
519                 file_to_archive(cpio, p);
520         lafe_line_reader_free(lr);
521
522         /*
523          * The hardlink detection may have queued up a couple of entries
524          * that can now be flushed.
525          */
526         entry = NULL;
527         archive_entry_linkify(cpio->linkresolver, &entry, &spare);
528         while (entry != NULL) {
529                 entry_to_archive(cpio, entry);
530                 archive_entry_free(entry);
531                 entry = NULL;
532                 archive_entry_linkify(cpio->linkresolver, &entry, &spare);
533         }
534
535         r = archive_write_close(cpio->archive);
536         if (r != ARCHIVE_OK)
537                 lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
538
539         if (!cpio->quiet) {
540                 int64_t blocks =
541                         (archive_position_uncompressed(cpio->archive) + 511)
542                         / 512;
543                 fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
544                     blocks == 1 ? "block" : "blocks");
545         }
546         archive_write_finish(cpio->archive);
547 }
548
549 /*
550  * This is used by both out mode (to copy objects from disk into
551  * an archive) and pass mode (to copy objects from disk to
552  * an archive_write_disk "archive").
553  */
554 static int
555 file_to_archive(struct cpio *cpio, const char *srcpath)
556 {
557         const char *destpath;
558         struct archive_entry *entry, *spare;
559         size_t len;
560         const char *p;
561         int r;
562
563         /*
564          * Create an archive_entry describing the source file.
565          *
566          */
567         entry = archive_entry_new();
568         if (entry == NULL)
569                 lafe_errc(1, 0, "Couldn't allocate entry");
570         archive_entry_copy_sourcepath(entry, srcpath);
571         r = archive_read_disk_entry_from_file(cpio->archive_read_disk,
572             entry, -1, NULL);
573         if (r < ARCHIVE_FAILED)
574                 lafe_errc(1, 0, "%s",
575                     archive_error_string(cpio->archive_read_disk));
576         if (r < ARCHIVE_OK)
577                 lafe_warnc(0, "%s",
578                     archive_error_string(cpio->archive_read_disk));
579         if (r <= ARCHIVE_FAILED) {
580                 cpio->return_value = 1;
581                 return (r);
582         }
583
584         if (cpio->uid_override >= 0) {
585                 archive_entry_set_uid(entry, cpio->uid_override);
586                 archive_entry_set_uname(entry, cpio->uname_override);
587         }
588         if (cpio->gid_override >= 0) {
589                 archive_entry_set_gid(entry, cpio->gid_override);
590                 archive_entry_set_gname(entry, cpio->gname_override);
591         }
592
593         /*
594          * Generate a destination path for this entry.
595          * "destination path" is the name to which it will be copied in
596          * pass mode or the name that will go into the archive in
597          * output mode.
598          */
599         destpath = srcpath;
600         if (cpio->destdir) {
601                 len = strlen(cpio->destdir) + strlen(srcpath) + 8;
602                 if (len >= cpio->pass_destpath_alloc) {
603                         while (len >= cpio->pass_destpath_alloc) {
604                                 cpio->pass_destpath_alloc += 512;
605                                 cpio->pass_destpath_alloc *= 2;
606                         }
607                         free(cpio->pass_destpath);
608                         cpio->pass_destpath = malloc(cpio->pass_destpath_alloc);
609                         if (cpio->pass_destpath == NULL)
610                                 lafe_errc(1, ENOMEM,
611                                     "Can't allocate path buffer");
612                 }
613                 strcpy(cpio->pass_destpath, cpio->destdir);
614                 p = srcpath;
615                 while (p[0] == '/')
616                         ++p;
617                 strcat(cpio->pass_destpath, p);
618                 destpath = cpio->pass_destpath;
619         }
620         if (cpio->option_rename)
621                 destpath = cpio_rename(destpath);
622         if (destpath == NULL)
623                 return (0);
624         archive_entry_copy_pathname(entry, destpath);
625
626         /*
627          * If we're trying to preserve hardlinks, match them here.
628          */
629         spare = NULL;
630         if (cpio->linkresolver != NULL
631             && archive_entry_filetype(entry) != AE_IFDIR) {
632                 archive_entry_linkify(cpio->linkresolver, &entry, &spare);
633         }
634
635         if (entry != NULL) {
636                 r = entry_to_archive(cpio, entry);
637                 archive_entry_free(entry);
638                 if (spare != NULL) {
639                         if (r == 0)
640                                 r = entry_to_archive(cpio, spare);
641                         archive_entry_free(spare);
642                 }
643         }
644         return (r);
645 }
646
647 static int
648 entry_to_archive(struct cpio *cpio, struct archive_entry *entry)
649 {
650         const char *destpath = archive_entry_pathname(entry);
651         const char *srcpath = archive_entry_sourcepath(entry);
652         int fd = -1;
653         ssize_t bytes_read;
654         int r;
655
656         /* Print out the destination name to the user. */
657         if (cpio->verbose)
658                 fprintf(stderr,"%s", destpath);
659
660         /*
661          * Option_link only makes sense in pass mode and for
662          * regular files.  Also note: if a link operation fails
663          * because of cross-device restrictions, we'll fall back
664          * to copy mode for that entry.
665          *
666          * TODO: Test other cpio implementations to see if they
667          * hard-link anything other than regular files here.
668          */
669         if (cpio->option_link
670             && archive_entry_filetype(entry) == AE_IFREG)
671         {
672                 struct archive_entry *t;
673                 /* Save the original entry in case we need it later. */
674                 t = archive_entry_clone(entry);
675                 if (t == NULL)
676                         lafe_errc(1, ENOMEM, "Can't create link");
677                 /* Note: link(2) doesn't create parent directories,
678                  * so we use archive_write_header() instead as a
679                  * convenience. */
680                 archive_entry_set_hardlink(t, srcpath);
681                 /* This is a straight link that carries no data. */
682                 archive_entry_set_size(t, 0);
683                 r = archive_write_header(cpio->archive, t);
684                 archive_entry_free(t);
685                 if (r != ARCHIVE_OK)
686                         lafe_warnc(archive_errno(cpio->archive),
687                             "%s", archive_error_string(cpio->archive));
688                 if (r == ARCHIVE_FATAL)
689                         exit(1);
690 #ifdef EXDEV
691                 if (r != ARCHIVE_OK && archive_errno(cpio->archive) == EXDEV) {
692                         /* Cross-device link:  Just fall through and use
693                          * the original entry to copy the file over. */
694                         lafe_warnc(0, "Copying file instead");
695                 } else
696 #endif
697                 return (0);
698         }
699
700         /*
701          * Make sure we can open the file (if necessary) before
702          * trying to write the header.
703          */
704         if (archive_entry_filetype(entry) == AE_IFREG) {
705                 if (archive_entry_size(entry) > 0) {
706                         fd = open(srcpath, O_RDONLY | O_BINARY);
707                         if (fd < 0) {
708                                 lafe_warnc(errno,
709                                     "%s: could not open file", srcpath);
710                                 goto cleanup;
711                         }
712                 }
713         } else {
714                 archive_entry_set_size(entry, 0);
715         }
716
717         r = archive_write_header(cpio->archive, entry);
718
719         if (r != ARCHIVE_OK)
720                 lafe_warnc(archive_errno(cpio->archive),
721                     "%s: %s",
722                     srcpath,
723                     archive_error_string(cpio->archive));
724
725         if (r == ARCHIVE_FATAL)
726                 exit(1);
727
728         if (r >= ARCHIVE_WARN && fd >= 0) {
729                 bytes_read = read(fd, cpio->buff, cpio->buff_size);
730                 while (bytes_read > 0) {
731                         r = archive_write_data(cpio->archive,
732                             cpio->buff, bytes_read);
733                         if (r < 0)
734                                 lafe_errc(1, archive_errno(cpio->archive),
735                                     "%s", archive_error_string(cpio->archive));
736                         if (r < bytes_read) {
737                                 lafe_warnc(0,
738                                     "Truncated write; file may have grown while being archived.");
739                         }
740                         bytes_read = read(fd, cpio->buff, cpio->buff_size);
741                 }
742         }
743
744         fd = restore_time(cpio, entry, srcpath, fd);
745
746 cleanup:
747         if (cpio->verbose)
748                 fprintf(stderr,"\n");
749         if (fd >= 0)
750                 close(fd);
751         return (0);
752 }
753
754 static int
755 restore_time(struct cpio *cpio, struct archive_entry *entry,
756     const char *name, int fd)
757 {
758 #ifndef HAVE_UTIMES
759         static int warned = 0;
760
761         (void)cpio; /* UNUSED */
762         (void)entry; /* UNUSED */
763         (void)name; /* UNUSED */
764
765         if (!warned)
766                 lafe_warnc(0, "Can't restore access times on this platform");
767         warned = 1;
768         return (fd);
769 #else
770 #if defined(_WIN32) && !defined(__CYGWIN__)
771         struct __timeval times[2];
772 #else
773         struct timeval times[2];
774 #endif
775
776         if (!cpio->option_atime_restore)
777                 return (fd);
778
779         times[1].tv_sec = archive_entry_mtime(entry);
780         times[1].tv_usec = archive_entry_mtime_nsec(entry) / 1000;
781
782         times[0].tv_sec = archive_entry_atime(entry);
783         times[0].tv_usec = archive_entry_atime_nsec(entry) / 1000;
784
785 #if defined(HAVE_FUTIMES) && !defined(__CYGWIN__)
786         if (fd >= 0 && futimes(fd, times) == 0)
787                 return (fd);
788 #endif
789         /*
790          * Some platform cannot restore access times if the file descriptor
791          * is still opened.
792          */
793         if (fd >= 0) {
794                 close(fd);
795                 fd = -1;
796         }
797
798 #ifdef HAVE_LUTIMES
799         if (lutimes(name, times) != 0)
800 #else
801         if ((AE_IFLNK != archive_entry_filetype(entry))
802                         && utimes(name, times) != 0)
803 #endif
804                 lafe_warnc(errno, "Can't update time for %s", name);
805 #endif
806         return (fd);
807 }
808
809
810 static void
811 mode_in(struct cpio *cpio)
812 {
813         struct archive *a;
814         struct archive_entry *entry;
815         struct archive *ext;
816         const char *destpath;
817         int r;
818
819         ext = archive_write_disk_new();
820         if (ext == NULL)
821                 lafe_errc(1, 0, "Couldn't allocate restore object");
822         r = archive_write_disk_set_options(ext, cpio->extract_flags);
823         if (r != ARCHIVE_OK)
824                 lafe_errc(1, 0, "%s", archive_error_string(ext));
825         a = archive_read_new();
826         if (a == NULL)
827                 lafe_errc(1, 0, "Couldn't allocate archive object");
828         archive_read_support_compression_all(a);
829         archive_read_support_format_all(a);
830
831         if (archive_read_open_file(a, cpio->filename, cpio->bytes_per_block))
832                 lafe_errc(1, archive_errno(a),
833                     "%s", archive_error_string(a));
834         for (;;) {
835                 r = archive_read_next_header(a, &entry);
836                 if (r == ARCHIVE_EOF)
837                         break;
838                 if (r != ARCHIVE_OK) {
839                         lafe_errc(1, archive_errno(a),
840                             "%s", archive_error_string(a));
841                 }
842                 if (lafe_excluded(cpio->matching, archive_entry_pathname(entry)))
843                         continue;
844                 if (cpio->option_rename) {
845                         destpath = cpio_rename(archive_entry_pathname(entry));
846                         archive_entry_set_pathname(entry, destpath);
847                 } else
848                         destpath = archive_entry_pathname(entry);
849                 if (destpath == NULL)
850                         continue;
851                 if (cpio->verbose)
852                         fprintf(stdout, "%s\n", destpath);
853                 if (cpio->uid_override >= 0)
854                         archive_entry_set_uid(entry, cpio->uid_override);
855                 if (cpio->gid_override >= 0)
856                         archive_entry_set_gid(entry, cpio->gid_override);
857                 r = archive_write_header(ext, entry);
858                 if (r != ARCHIVE_OK) {
859                         fprintf(stderr, "%s: %s\n",
860                             archive_entry_pathname(entry),
861                             archive_error_string(ext));
862                 } else if (archive_entry_size(entry) > 0) {
863                         r = extract_data(a, ext);
864                         if (r != ARCHIVE_OK)
865                                 cpio->return_value = 1;
866                 }
867         }
868         r = archive_read_close(a);
869         if (r != ARCHIVE_OK)
870                 lafe_errc(1, 0, "%s", archive_error_string(a));
871         r = archive_write_close(ext);
872         if (r != ARCHIVE_OK)
873                 lafe_errc(1, 0, "%s", archive_error_string(ext));
874         if (!cpio->quiet) {
875                 int64_t blocks = (archive_position_uncompressed(a) + 511)
876                               / 512;
877                 fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
878                     blocks == 1 ? "block" : "blocks");
879         }
880         archive_read_finish(a);
881         archive_write_finish(ext);
882         exit(cpio->return_value);
883 }
884
885 /*
886  * Exits if there's a fatal error.  Returns ARCHIVE_OK
887  * if everything is kosher.
888  */
889 static int
890 extract_data(struct archive *ar, struct archive *aw)
891 {
892         int r;
893         size_t size;
894         const void *block;
895         off_t offset;
896
897         for (;;) {
898                 r = archive_read_data_block(ar, &block, &size, &offset);
899                 if (r == ARCHIVE_EOF)
900                         return (ARCHIVE_OK);
901                 if (r != ARCHIVE_OK) {
902                         lafe_warnc(archive_errno(ar),
903                             "%s", archive_error_string(ar));
904                         exit(1);
905                 }
906                 r = archive_write_data_block(aw, block, size, offset);
907                 if (r != ARCHIVE_OK) {
908                         lafe_warnc(archive_errno(aw),
909                             "%s", archive_error_string(aw));
910                         return (r);
911                 }
912         }
913 }
914
915 static void
916 mode_list(struct cpio *cpio)
917 {
918         struct archive *a;
919         struct archive_entry *entry;
920         int r;
921
922         a = archive_read_new();
923         if (a == NULL)
924                 lafe_errc(1, 0, "Couldn't allocate archive object");
925         archive_read_support_compression_all(a);
926         archive_read_support_format_all(a);
927
928         if (archive_read_open_file(a, cpio->filename, cpio->bytes_per_block))
929                 lafe_errc(1, archive_errno(a),
930                     "%s", archive_error_string(a));
931         for (;;) {
932                 r = archive_read_next_header(a, &entry);
933                 if (r == ARCHIVE_EOF)
934                         break;
935                 if (r != ARCHIVE_OK) {
936                         lafe_errc(1, archive_errno(a),
937                             "%s", archive_error_string(a));
938                 }
939                 if (lafe_excluded(cpio->matching, archive_entry_pathname(entry)))
940                         continue;
941                 if (cpio->verbose)
942                         list_item_verbose(cpio, entry);
943                 else
944                         fprintf(stdout, "%s\n", archive_entry_pathname(entry));
945         }
946         r = archive_read_close(a);
947         if (r != ARCHIVE_OK)
948                 lafe_errc(1, 0, "%s", archive_error_string(a));
949         if (!cpio->quiet) {
950                 int64_t blocks = (archive_position_uncompressed(a) + 511)
951                               / 512;
952                 fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
953                     blocks == 1 ? "block" : "blocks");
954         }
955         archive_read_finish(a);
956         exit(0);
957 }
958
959 /*
960  * Display information about the current file.
961  *
962  * The format here roughly duplicates the output of 'ls -l'.
963  * This is based on SUSv2, where 'tar tv' is documented as
964  * listing additional information in an "unspecified format,"
965  * and 'pax -l' is documented as using the same format as 'ls -l'.
966  */
967 static void
968 list_item_verbose(struct cpio *cpio, struct archive_entry *entry)
969 {
970         char                     size[32];
971         char                     date[32];
972         char                     uids[16], gids[16];
973         const char              *uname, *gname;
974         FILE                    *out = stdout;
975         const char              *fmt;
976         time_t                   mtime;
977         static time_t            now;
978
979         if (!now)
980                 time(&now);
981
982         if (cpio->option_numeric_uid_gid) {
983                 /* Format numeric uid/gid for display. */
984                 strcpy(uids, cpio_i64toa(archive_entry_uid(entry)));
985                 uname = uids;
986                 strcpy(gids, cpio_i64toa(archive_entry_gid(entry)));
987                 gname = gids;
988         } else {
989                 /* Use uname if it's present, else lookup name from uid. */
990                 uname = archive_entry_uname(entry);
991                 if (uname == NULL)
992                         uname = lookup_uname(cpio, archive_entry_uid(entry));
993                 /* Use gname if it's present, else lookup name from gid. */
994                 gname = archive_entry_gname(entry);
995                 if (gname == NULL)
996                         gname = lookup_gname(cpio, archive_entry_gid(entry));
997         }
998
999         /* Print device number or file size. */
1000         if (archive_entry_filetype(entry) == AE_IFCHR
1001             || archive_entry_filetype(entry) == AE_IFBLK) {
1002                 snprintf(size, sizeof(size), "%lu,%lu",
1003                     (unsigned long)archive_entry_rdevmajor(entry),
1004                     (unsigned long)archive_entry_rdevminor(entry));
1005         } else {
1006                 strcpy(size, cpio_i64toa(archive_entry_size(entry)));
1007         }
1008
1009         /* Format the time using 'ls -l' conventions. */
1010         mtime = archive_entry_mtime(entry);
1011 #if defined(_WIN32) && !defined(__CYGWIN__)
1012         /* Windows' strftime function does not support %e format. */
1013         if (mtime - now > 365*86400/2
1014                 || mtime - now < -365*86400/2)
1015                 fmt = cpio->day_first ? "%d %b  %Y" : "%b %d  %Y";
1016         else
1017                 fmt = cpio->day_first ? "%d %b %H:%M" : "%b %d %H:%M";
1018 #else
1019         if (abs(mtime - now) > (365/2)*86400)
1020                 fmt = cpio->day_first ? "%e %b  %Y" : "%b %e  %Y";
1021         else
1022                 fmt = cpio->day_first ? "%e %b %H:%M" : "%b %e %H:%M";
1023 #endif
1024         strftime(date, sizeof(date), fmt, localtime(&mtime));
1025
1026         fprintf(out, "%s%3d %-8s %-8s %8s %12s %s",
1027             archive_entry_strmode(entry),
1028             archive_entry_nlink(entry),
1029             uname, gname, size, date,
1030             archive_entry_pathname(entry));
1031
1032         /* Extra information for links. */
1033         if (archive_entry_hardlink(entry)) /* Hard link */
1034                 fprintf(out, " link to %s", archive_entry_hardlink(entry));
1035         else if (archive_entry_symlink(entry)) /* Symbolic link */
1036                 fprintf(out, " -> %s", archive_entry_symlink(entry));
1037         fprintf(out, "\n");
1038 }
1039
1040 static void
1041 mode_pass(struct cpio *cpio, const char *destdir)
1042 {
1043         struct lafe_line_reader *lr;
1044         const char *p;
1045         int r;
1046
1047         /* Ensure target dir has a trailing '/' to simplify path surgery. */
1048         cpio->destdir = malloc(strlen(destdir) + 8);
1049         strcpy(cpio->destdir, destdir);
1050         if (destdir[strlen(destdir) - 1] != '/')
1051                 strcat(cpio->destdir, "/");
1052
1053         cpio->archive = archive_write_disk_new();
1054         if (cpio->archive == NULL)
1055                 lafe_errc(1, 0, "Failed to allocate archive object");
1056         r = archive_write_disk_set_options(cpio->archive, cpio->extract_flags);
1057         if (r != ARCHIVE_OK)
1058                 lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
1059         cpio->linkresolver = archive_entry_linkresolver_new();
1060         archive_write_disk_set_standard_lookup(cpio->archive);
1061
1062         cpio->archive_read_disk = archive_read_disk_new();
1063         if (cpio->archive_read_disk == NULL)
1064                 lafe_errc(1, 0, "Failed to allocate archive object");
1065         if (cpio->option_follow_links)
1066                 archive_read_disk_set_symlink_logical(cpio->archive_read_disk);
1067         else
1068                 archive_read_disk_set_symlink_physical(cpio->archive_read_disk);
1069         archive_read_disk_set_standard_lookup(cpio->archive_read_disk);
1070
1071         lr = lafe_line_reader("-", cpio->option_null);
1072         while ((p = lafe_line_reader_next(lr)) != NULL)
1073                 file_to_archive(cpio, p);
1074         lafe_line_reader_free(lr);
1075
1076         archive_entry_linkresolver_free(cpio->linkresolver);
1077         r = archive_write_close(cpio->archive);
1078         if (r != ARCHIVE_OK)
1079                 lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
1080
1081         if (!cpio->quiet) {
1082                 int64_t blocks =
1083                         (archive_position_uncompressed(cpio->archive) + 511)
1084                         / 512;
1085                 fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
1086                     blocks == 1 ? "block" : "blocks");
1087         }
1088
1089         archive_write_finish(cpio->archive);
1090 }
1091
1092 /*
1093  * Prompt for a new name for this entry.  Returns a pointer to the
1094  * new name or NULL if the entry should not be copied.  This
1095  * implements the semantics defined in POSIX.1-1996, which specifies
1096  * that an input of '.' means the name should be unchanged.  GNU cpio
1097  * treats '.' as a literal new name.
1098  */
1099 static const char *
1100 cpio_rename(const char *name)
1101 {
1102         static char buff[1024];
1103         FILE *t;
1104         char *p, *ret;
1105
1106         t = fopen("/dev/tty", "r+");
1107         if (t == NULL)
1108                 return (name);
1109         fprintf(t, "%s (Enter/./(new name))? ", name);
1110         fflush(t);
1111
1112         p = fgets(buff, sizeof(buff), t);
1113         fclose(t);
1114         if (p == NULL)
1115                 /* End-of-file is a blank line. */
1116                 return (NULL);
1117
1118         while (*p == ' ' || *p == '\t')
1119                 ++p;
1120         if (*p == '\n' || *p == '\0')
1121                 /* Empty line. */
1122                 return (NULL);
1123         if (*p == '.' && p[1] == '\n')
1124                 /* Single period preserves original name. */
1125                 return (name);
1126         ret = p;
1127         /* Trim the final newline. */
1128         while (*p != '\0' && *p != '\n')
1129                 ++p;
1130         /* Overwrite the final \n with a null character. */
1131         *p = '\0';
1132         return (ret);
1133 }
1134
1135 static void
1136 free_cache(struct name_cache *cache)
1137 {
1138         size_t i;
1139
1140         if (cache != NULL) {
1141                 for (i = 0; i < cache->size; i++)
1142                         free(cache->cache[i].name);
1143                 free(cache);
1144         }
1145 }
1146
1147 /*
1148  * Lookup uname/gname from uid/gid, return NULL if no match.
1149  */
1150 static const char *
1151 lookup_name(struct cpio *cpio, struct name_cache **name_cache_variable,
1152     int (*lookup_fn)(struct cpio *, const char **, id_t), id_t id)
1153 {
1154         char asnum[16];
1155         struct name_cache       *cache;
1156         const char *name;
1157         int slot;
1158
1159
1160         if (*name_cache_variable == NULL) {
1161                 *name_cache_variable = malloc(sizeof(struct name_cache));
1162                 if (*name_cache_variable == NULL)
1163                         lafe_errc(1, ENOMEM, "No more memory");
1164                 memset(*name_cache_variable, 0, sizeof(struct name_cache));
1165                 (*name_cache_variable)->size = name_cache_size;
1166         }
1167
1168         cache = *name_cache_variable;
1169         cache->probes++;
1170
1171         slot = id % cache->size;
1172         if (cache->cache[slot].name != NULL) {
1173                 if (cache->cache[slot].id == id) {
1174                         cache->hits++;
1175                         return (cache->cache[slot].name);
1176                 }
1177                 free(cache->cache[slot].name);
1178                 cache->cache[slot].name = NULL;
1179         }
1180
1181         if (lookup_fn(cpio, &name, id) == 0) {
1182                 if (name == NULL || name[0] == '\0') {
1183                         /* If lookup failed, format it as a number. */
1184                         snprintf(asnum, sizeof(asnum), "%u", (unsigned)id);
1185                         name = asnum;
1186                 }
1187                 cache->cache[slot].name = strdup(name);
1188                 if (cache->cache[slot].name != NULL) {
1189                         cache->cache[slot].id = id;
1190                         return (cache->cache[slot].name);
1191                 }
1192                 /*
1193                  * Conveniently, NULL marks an empty slot, so
1194                  * if the strdup() fails, we've just failed to
1195                  * cache it.  No recovery necessary.
1196                  */
1197         }
1198         return (NULL);
1199 }
1200
1201 static const char *
1202 lookup_uname(struct cpio *cpio, uid_t uid)
1203 {
1204         return (lookup_name(cpio, &cpio->uname_cache,
1205                     &lookup_uname_helper, (id_t)uid));
1206 }
1207
1208 static int
1209 lookup_uname_helper(struct cpio *cpio, const char **name, id_t id)
1210 {
1211         struct passwd   *pwent;
1212
1213         (void)cpio; /* UNUSED */
1214
1215         errno = 0;
1216         pwent = getpwuid((uid_t)id);
1217         if (pwent == NULL) {
1218                 *name = NULL;
1219                 if (errno != 0 && errno != ENOENT)
1220                         lafe_warnc(errno, "getpwuid(%d) failed", id);
1221                 return (errno);
1222         }
1223
1224         *name = pwent->pw_name;
1225         return (0);
1226 }
1227
1228 static const char *
1229 lookup_gname(struct cpio *cpio, gid_t gid)
1230 {
1231         return (lookup_name(cpio, &cpio->gname_cache,
1232                     &lookup_gname_helper, (id_t)gid));
1233 }
1234
1235 static int
1236 lookup_gname_helper(struct cpio *cpio, const char **name, id_t id)
1237 {
1238         struct group    *grent;
1239
1240         (void)cpio; /* UNUSED */
1241
1242         errno = 0;
1243         grent = getgrgid((gid_t)id);
1244         if (grent == NULL) {
1245                 *name = NULL;
1246                 if (errno != 0)
1247                         lafe_warnc(errno, "getgrgid(%d) failed", id);
1248                 return (errno);
1249         }
1250
1251         *name = grent->gr_name;
1252         return (0);
1253 }
1254
1255 /*
1256  * It would be nice to just use printf() for formatting large numbers,
1257  * but the compatibility problems are a big headache.  Hence the
1258  * following simple utility function.
1259  */
1260 const char *
1261 cpio_i64toa(int64_t n0)
1262 {
1263         // 2^64 =~ 1.8 * 10^19, so 20 decimal digits suffice.
1264         // We also need 1 byte for '-' and 1 for '\0'.
1265         static char buff[22];
1266         int64_t n = n0 < 0 ? -n0 : n0;
1267         char *p = buff + sizeof(buff);
1268
1269         *--p = '\0';
1270         do {
1271                 *--p = '0' + (int)(n % 10);
1272                 n /= 10;
1273         } while (n > 0);
1274         if (n0 < 0)
1275                 *--p = '-';
1276         return p;
1277 }