1 /*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * 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 5.1 (Berkeley) 01/17/91"; 13 #endif /* not lint */ 14 15 #include <sys/param.h> 16 #include <sys/time.h> 17 #include <sys/stat.h> 18 #include <sys/errno.h> 19 #include <fcntl.h> 20 #include <unistd.h> 21 #include <dirent.h> 22 #include <stdio.h> 23 #include "archive.h" 24 25 extern CHDR chdr; /* converted header */ 26 extern char *archive; /* archive name */ 27 28 /* 29 * extract -- 30 * Extract files from the named archive - if member names given only 31 * extract those members otherwise extract all members. If 'o' option 32 * selected modify date of newly created file to be same as archive 33 * members date otherwise date is time of extraction. Does not modify 34 * archive. 35 */ 36 extract(argv) 37 char **argv; 38 { 39 register int afd, all, tfd; 40 struct timeval tv[2]; 41 struct stat sb; 42 CF cf; 43 int eval; 44 char *file, *rname(); 45 46 eval = 0; 47 tv[0].tv_usec = tv[1].tv_usec = 0; 48 49 afd = open_archive(O_RDONLY); 50 51 SETCF(afd, archive, 0, 0, RPAD); 52 for (all = !*argv; get_header(afd);) { 53 if (all) 54 file = chdr.name; 55 else { 56 file = *argv; 57 if (!files(argv)) { 58 SKIP(afd, chdr.size, archive); 59 continue; 60 } 61 } 62 63 if (options & AR_U && !stat(file, &sb) && 64 sb.st_mtime > chdr.date) 65 continue; 66 67 if ((tfd = open(file, O_WRONLY|O_CREAT|O_TRUNC, S_IWUSR)) < 0) { 68 (void)fprintf(stderr, "ar: %s: %s.\n", 69 file, strerror(errno)); 70 SKIP(afd, chdr.size, archive); 71 eval = 1; 72 continue; 73 } 74 75 if (options & AR_V) 76 (void)printf("x - %s\n", rname(file)); 77 78 cf.wfd = tfd; 79 cf.wname = file; 80 copyfile(&cf, chdr.size); 81 82 if (fchmod(tfd, (short)chdr.mode)) { 83 (void)fprintf(stderr, "ar: %s: chmod: %s\n", 84 file, strerror(errno)); 85 eval = 1; 86 } 87 if (options & AR_O) { 88 tv[0].tv_sec = tv[1].tv_sec = chdr.date; 89 if (utimes(file, tv)) { 90 (void)fprintf(stderr, "ar: %s: utimes: %s\n", 91 file, strerror(errno)); 92 eval = 1; 93 } 94 } 95 (void)close(tfd); 96 if (!all && !*argv) 97 break; 98 } 99 ORPHANS; 100 close_archive(afd); 101 return(eval); 102 } 103