1 /*- 2 * Copyright (c) 1990, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Hugh Smith at The University of Guelph. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 static char sccsid[] = "@(#)extract.c 8.3 (Berkeley) 04/02/94"; 13 #endif /* not lint */ 14 15 #include <sys/param.h> 16 #include <sys/time.h> 17 #include <sys/stat.h> 18 19 #include <dirent.h> 20 #include <err.h> 21 #include <fcntl.h> 22 #include <stdio.h> 23 #include <string.h> 24 #include <unistd.h> 25 26 #include "archive.h" 27 #include "extern.h" 28 29 /* 30 * extract -- 31 * Extract files from the named archive - if member names given only 32 * extract those members otherwise extract all members. If 'o' option 33 * selected modify date of newly created file to be same as archive 34 * members date otherwise date is time of extraction. Does not modify 35 * archive. 36 */ 37 int 38 extract(argv) 39 char **argv; 40 { 41 char *file; 42 int afd, all, eval, tfd; 43 struct timeval tv[2]; 44 struct stat sb; 45 CF cf; 46 47 eval = 0; 48 tv[0].tv_usec = tv[1].tv_usec = 0; 49 50 afd = open_archive(O_RDONLY); 51 52 /* Read from an archive, write to disk; pad on read. */ 53 SETCF(afd, archive, 0, 0, RPAD); 54 for (all = !*argv; get_arobj(afd);) { 55 if (all) 56 file = chdr.name; 57 else if (!(file = files(argv))) { 58 skip_arobj(afd); 59 continue; 60 } 61 62 if (options & AR_U && !stat(file, &sb) && 63 sb.st_mtime > chdr.date) 64 continue; 65 66 if ((tfd = open(file, O_WRONLY|O_CREAT|O_TRUNC, S_IWUSR)) < 0) { 67 warn("%s", file); 68 skip_arobj(afd); 69 eval = 1; 70 continue; 71 } 72 73 if (options & AR_V) 74 (void)printf("x - %s\n", file); 75 76 cf.wfd = tfd; 77 cf.wname = file; 78 copy_ar(&cf, chdr.size); 79 80 if (fchmod(tfd, (short)chdr.mode)) { 81 warn("chmod: %s", file); 82 eval = 1; 83 } 84 if (options & AR_O) { 85 tv[0].tv_sec = tv[1].tv_sec = chdr.date; 86 if (utimes(file, tv)) { 87 warn("utimes: %s", file); 88 eval = 1; 89 } 90 } 91 (void)close(tfd); 92 if (!all && !*argv) 93 break; 94 } 95 close_archive(afd); 96 97 if (*argv) { 98 orphans(argv); 99 return (1); 100 } 101 return (0); 102 } 103