#endif
#include <sys/types.h>
#include <time.h>
-time_t time();
+time_t time ();
#ifdef BSD42
#include <sys/file.h>
long actime;
long modtime;
};
+
#endif
extern FILE *msg_file;
-extern union record *head; /* Points to current tape header */
-extern struct stat hstat; /* Stat struct corresponding */
-extern int head_standard; /* Tape header is in ANSI format */
+extern union record *head; /* Points to current tape header */
+extern struct stat hstat; /* Stat struct corresponding */
+extern int head_standard; /* Tape header is in ANSI format */
extern char *save_name;
extern long save_totsize;
extern long save_sizeleft;
-int confirm();
-void decode_header();
-void extract_mangle();
-void extract_sparse_file();
-long from_oct();
-void gnu_restore();
-extern void print_header();
-extern void skip_file();
-extern void skip_extended_headers();
-extern void pr_mkdir();
-void saverec();
+int confirm ();
+void decode_header ();
+void extract_mangle ();
+void extract_sparse_file ();
+long from_oct ();
+void gnu_restore ();
+extern void print_header ();
+extern void skip_file ();
+extern void skip_extended_headers ();
+extern void pr_mkdir ();
+void saverec ();
-int make_dirs(); /* Makes required directories */
+int make_dirs (); /* Makes required directories */
-static time_t now = 0; /* Current time */
-static we_are_root = 0; /* True if our effective uid == 0 */
-static int notumask = ~0; /* Masks out bits user doesn't want */
+static time_t now = 0; /* Current time */
+static we_are_root = 0; /* True if our effective uid == 0 */
+static int notumask = ~0; /* Masks out bits user doesn't want */
/*
* "Scratch" space to store the information about a sparse file before
int mtime;
struct saved_dir_info *next;
};
-
+
struct saved_dir_info *saved_dir_info_head;
/*
* Set up to extract files.
*/
void
-extr_init()
+extr_init ()
{
- int ourmask;
+ int ourmask;
- now = time((time_t *)0);
- if (geteuid() == 0)
- we_are_root = 1;
+ now = time ((time_t *) 0);
+ if (geteuid () == 0)
+ we_are_root = 1;
- /*
+ /*
* We need to know our umask. But if f_use_protection is set,
* leave our kernel umask at 0, and our "notumask" at ~0.
*/
- ourmask = umask(0); /* Read it */
- if (!f_use_protection) {
- (void) umask (ourmask); /* Set it back how it was */
- notumask = ~ourmask; /* Make umask override permissions */
- }
+ ourmask = umask (0); /* Read it */
+ if (!f_use_protection)
+ {
+ (void) umask (ourmask); /* Set it back how it was */
+ notumask = ~ourmask; /* Make umask override permissions */
+ }
}
* Extract a file from the archive.
*/
void
-extract_archive()
+extract_archive ()
{
- register char *data;
- int fd, check, namelen, written, openflag;
- long size;
- struct utimbuf acc_upd_times;
- register int skipcrud;
- register int i;
-/* int sparse_ind = 0;*/
- union record *exhdr;
- struct saved_dir_info *tmp;
-/* int end_nulls; */
- char **longp;
- char *bp;
-
- saverec(&head); /* Make sure it sticks around */
- userec(head); /* And go past it in the archive */
- decode_header(head, &hstat, &head_standard, 1); /* Snarf fields */
-
- if(f_confirm && !confirm("extract",current_file_name)) {
- if (head->header.isextended)
- skip_extended_headers();
- skip_file((long)hstat.st_size);
- saverec((union record **)0);
- return;
- }
+ register char *data;
+ int fd, check, namelen, written, openflag;
+ long size;
+ struct utimbuf acc_upd_times;
+ register int skipcrud;
+ register int i;
+ /* int sparse_ind = 0;*/
+ union record *exhdr;
+ struct saved_dir_info *tmp;
+ /* int end_nulls; */
+ char **longp;
+ char *bp;
+
+ saverec (&head); /* Make sure it sticks around */
+ userec (head); /* And go past it in the archive */
+ decode_header (head, &hstat, &head_standard, 1); /* Snarf fields */
- /* Print the record from 'head' and 'hstat' */
- if (f_verbose)
- print_header();
+ if (f_confirm && !confirm ("extract", current_file_name))
+ {
+ if (head->header.isextended)
+ skip_extended_headers ();
+ skip_file ((long) hstat.st_size);
+ saverec ((union record **) 0);
+ return;
+ }
- /*
+ /* Print the record from 'head' and 'hstat' */
+ if (f_verbose)
+ print_header ();
+
+ /*
* Check for fully specified pathnames and other atrocities.
*
* Note, we can't just make a pointer to the new file name,
* We have to start from "head" every time we want to touch
* the header record.
*/
- skipcrud = 0;
- while (!f_absolute_paths
- && '/' == current_file_name[skipcrud]) {
- static int warned_once = 0;
+ skipcrud = 0;
+ while (!f_absolute_paths
+ && '/' == current_file_name[skipcrud])
+ {
+ static int warned_once = 0;
- skipcrud++; /* Force relative path */
- if (!warned_once++) {
- msg("Removing leading / from absolute path names in the archive.");
- }
- }
+ skipcrud++; /* Force relative path */
+ if (!warned_once++)
+ {
+ msg ("Removing leading / from absolute path names in the archive.");
+ }
+ }
- switch (head->header.linkflag) {
+ switch (head->header.linkflag)
+ {
- default:
- msg("Unknown file type '%c' for %s, extracted as normal file",
- head->header.linkflag, skipcrud+current_file_name);
- /* FALL THRU */
+ default:
+ msg ("Unknown file type '%c' for %s, extracted as normal file",
+ head->header.linkflag, skipcrud + current_file_name);
+ /* FALL THRU */
- /*
+ /*
* JK - What we want to do if the file is sparse is loop through
* the array of sparse structures in the header and read in
* and translate the character strings representing 1) the offset
* the tar file that had to deal with a sparse file.
*
* After we read in the first five (at most) sparse structures,
- * we check to see if the file has an extended header, i.e.,
+ * we check to see if the file has an extended header, i.e.,
* if more sparse structures are needed to describe the contents
* of the new file. If so, we read in the extended headers
* and continue to store their contents into the sparsearray.
*/
- case LF_SPARSE:
- sp_array_size = 10;
- sparsearray = (struct sp_array *) malloc(sp_array_size * sizeof(struct sp_array));
- for (i = 0; i < SPARSE_IN_HDR; i++) {
- sparsearray[i].offset =
- from_oct(1+12, head->header.sp[i].offset);
- sparsearray[i].numbytes =
- from_oct(1+12, head->header.sp[i].numbytes);
- if (!sparsearray[i].numbytes)
- break;
- }
-
- /* end_nulls = from_oct(1+12, head->header.ending_blanks);*/
-
- if (head->header.isextended) {
- /* read in the list of extended headers
- and translate them into the sparsearray
+ case LF_SPARSE:
+ sp_array_size = 10;
+ sparsearray = (struct sp_array *) malloc (sp_array_size * sizeof (struct sp_array));
+ for (i = 0; i < SPARSE_IN_HDR; i++)
+ {
+ sparsearray[i].offset =
+ from_oct (1 + 12, head->header.sp[i].offset);
+ sparsearray[i].numbytes =
+ from_oct (1 + 12, head->header.sp[i].numbytes);
+ if (!sparsearray[i].numbytes)
+ break;
+ }
+
+ /* end_nulls = from_oct(1+12, head->header.ending_blanks);*/
+
+ if (head->header.isextended)
+ {
+ /* read in the list of extended headers
+ and translate them into the sparsearray
as before */
- /* static */ int ind = SPARSE_IN_HDR;
+ /* static */ int ind = SPARSE_IN_HDR;
- for (;;) {
+ for (;;)
+ {
- exhdr = findrec();
- for (i = 0; i < SPARSE_EXT_HDR; i++) {
+ exhdr = findrec ();
+ for (i = 0; i < SPARSE_EXT_HDR; i++)
+ {
- if (i+ind > sp_array_size-1) {
- /*
+ if (i + ind > sp_array_size - 1)
+ {
+ /*
* realloc the scratch area
* since we've run out of room --
*/
- sparsearray = (struct sp_array *)
- realloc(sparsearray,
- 2 * sp_array_size * (sizeof(struct sp_array)));
- sp_array_size *= 2;
- }
- if (!exhdr->ext_hdr.sp[i].numbytes)
- break;
- sparsearray[i+ind].offset =
- from_oct(1+12, exhdr->ext_hdr.sp[i].offset);
- sparsearray[i+ind].numbytes =
- from_oct(1+12, exhdr->ext_hdr.sp[i].numbytes);
- }
- if (!exhdr->ext_hdr.isextended)
- break;
- else {
- ind += SPARSE_EXT_HDR;
- userec(exhdr);
- }
- }
- userec(exhdr);
- }
-
- /* FALL THRU */
- case LF_OLDNORMAL:
- case LF_NORMAL:
- case LF_CONTIG:
- /*
+ sparsearray = (struct sp_array *)
+ realloc (sparsearray,
+ 2 * sp_array_size * (sizeof (struct sp_array)));
+ sp_array_size *= 2;
+ }
+ if (!exhdr->ext_hdr.sp[i].numbytes)
+ break;
+ sparsearray[i + ind].offset =
+ from_oct (1 + 12, exhdr->ext_hdr.sp[i].offset);
+ sparsearray[i + ind].numbytes =
+ from_oct (1 + 12, exhdr->ext_hdr.sp[i].numbytes);
+ }
+ if (!exhdr->ext_hdr.isextended)
+ break;
+ else
+ {
+ ind += SPARSE_EXT_HDR;
+ userec (exhdr);
+ }
+ }
+ userec (exhdr);
+ }
+
+ /* FALL THRU */
+ case LF_OLDNORMAL:
+ case LF_NORMAL:
+ case LF_CONTIG:
+ /*
* Appears to be a file.
* See if it's really a directory.
*/
- namelen = strlen(skipcrud+current_file_name)-1;
- if (current_file_name[skipcrud+namelen] == '/')
- goto really_dir;
-
- /* FIXME, deal with protection issues */
- again_file:
- openflag = (f_keep?
- O_BINARY|O_NDELAY|O_WRONLY|O_CREAT|O_EXCL:
- O_BINARY|O_NDELAY|O_WRONLY|O_CREAT|O_TRUNC)
- | ((head->header.linkflag == LF_SPARSE) ? 0 : O_APPEND);
- /*
+ namelen = strlen (skipcrud + current_file_name) - 1;
+ if (current_file_name[skipcrud + namelen] == '/')
+ goto really_dir;
+
+ /* FIXME, deal with protection issues */
+ again_file:
+ openflag = (f_keep ?
+ O_BINARY | O_NDELAY | O_WRONLY | O_CREAT | O_EXCL :
+ O_BINARY | O_NDELAY | O_WRONLY | O_CREAT | O_TRUNC)
+ | ((head->header.linkflag == LF_SPARSE) ? 0 : O_APPEND);
+ /*
* JK - The last | is a kludge to solve the problem
* the O_APPEND flag causes with files we are
* trying to make sparse: when a file is opened
* me to waste a good deal of time, I might add)
*/
- if(f_exstdout) {
- fd = 1;
- goto extract_file;
- }
+ if (f_exstdout)
+ {
+ fd = 1;
+ goto extract_file;
+ }
#ifdef O_CTG
- /*
+ /*
* Contiguous files (on the Masscomp) have to specify
* the size in the open call that creates them.
*/
- if (head->header.linkflag == LF_CONTIG)
- fd = open((longname ? longname : head->header.name)
- + skipcrud,
- openflag | O_CTG,
- hstat.st_mode, hstat.st_size);
- else
+ if (head->header.linkflag == LF_CONTIG)
+ fd = open ((longname ? longname : head->header.name)
+ + skipcrud,
+ openflag | O_CTG,
+ hstat.st_mode, hstat.st_size);
+ else
#endif
- {
+ {
#ifdef NO_OPEN3
- /*
+ /*
* On raw V7 we won't let them specify -k (f_keep), but
* we just bull ahead and create the files.
*/
- fd = creat((longname
- ? longname
- : head->header.name) + skipcrud,
- hstat.st_mode);
+ fd = creat ((longname
+ ? longname
+ : head->header.name) + skipcrud,
+ hstat.st_mode);
#else
- /*
+ /*
* With 3-arg open(), we can do this up right.
*/
- fd = open(skipcrud + current_file_name,
- openflag, hstat.st_mode);
+ fd = open (skipcrud + current_file_name,
+ openflag, hstat.st_mode);
#endif
- }
-
- if (fd < 0) {
- if (make_dirs(skipcrud + current_file_name))
- goto again_file;
- msg_perror("Could not create file %s",
- skipcrud + current_file_name);
- if (head->header.isextended)
- skip_extended_headers();
- skip_file((long)hstat.st_size);
- goto quit;
- }
-
- extract_file:
- if (head->header.linkflag == LF_SPARSE) {
- char *name;
- int namelen;
-
- /*
+ }
+
+ if (fd < 0)
+ {
+ if (make_dirs (skipcrud + current_file_name))
+ goto again_file;
+ msg_perror ("Could not create file %s",
+ skipcrud + current_file_name);
+ if (head->header.isextended)
+ skip_extended_headers ();
+ skip_file ((long) hstat.st_size);
+ goto quit;
+ }
+
+ extract_file:
+ if (head->header.linkflag == LF_SPARSE)
+ {
+ char *name;
+ int namelen;
+
+ /*
* Kludge alert. NAME is assigned to header.name
* because during the extraction, the space that
* contains the header will get scribbled on, and
* that happen to contain the filename will look
* REAL interesting unless we do this.
*/
- namelen = strlen(skipcrud + current_file_name);
- name = (char *) malloc((sizeof(char)) * namelen);
- bcopy(skipcrud+current_file_name, name, namelen);
- size = hstat.st_size;
- extract_sparse_file(fd, &size, hstat.st_size, name);
- }
- else
- for (size = hstat.st_size;
- size > 0;
- size -= written) {
-
- /* long offset,
+ namelen = strlen (skipcrud + current_file_name);
+ name = (char *) malloc ((sizeof (char)) * namelen);
+ bcopy (skipcrud + current_file_name, name, namelen);
+ size = hstat.st_size;
+ extract_sparse_file (fd, &size, hstat.st_size, name);
+ }
+ else
+ for (size = hstat.st_size;
+ size > 0;
+ size -= written)
+ {
+
+ /* long offset,
numbytes;*/
- if(f_multivol) {
- save_name=current_file_name;
- save_totsize=hstat.st_size;
- save_sizeleft=size;
- }
+ if (f_multivol)
+ {
+ save_name = current_file_name;
+ save_totsize = hstat.st_size;
+ save_sizeleft = size;
+ }
- /*
+ /*
* Locate data, determine max length
* writeable, write it, record that
* we have used the data, then check
* if the write worked.
*/
- data = findrec()->charptr;
- if (data == NULL) { /* Check it... */
- msg("Unexpected EOF on archive file");
- break;
- }
- /*
+ data = findrec ()->charptr;
+ if (data == NULL)
+ { /* Check it... */
+ msg ("Unexpected EOF on archive file");
+ break;
+ }
+ /*
* JK - If the file is sparse, use the sparsearray
* that we created before to lseek into the new
* file the proper amount, and to see how many
* bytes we want to write at that position.
*/
- /* if (head->header.linkflag == LF_SPARSE) {
+ /* if (head->header.linkflag == LF_SPARSE) {
off_t pos;
pos = lseek(fd, (off_t) sparsearray[sparse_ind].offset, 0);
printf("%d at %d\n", (int) pos, sparse_ind);
written = sparsearray[sparse_ind++].numbytes;
} else*/
- written = endofrecs()->charptr - data;
- if (written > size)
- written = size;
- errno = 0;
- check = write(fd, data, written);
- /*
+ written = endofrecs ()->charptr - data;
+ if (written > size)
+ written = size;
+ errno = 0;
+ check = write (fd, data, written);
+ /*
* The following is in violation of strict
* typing, since the arg to userec
* should be a struct rec *. FIXME.
*/
- userec((union record *)(data + written - 1));
- if (check == written) continue;
- /*
+ userec ((union record *) (data + written - 1));
+ if (check == written)
+ continue;
+ /*
* Error in writing to file.
* Print it, skip to next file in archive.
*/
- if(check<0)
- msg_perror("couldn't write to file %s",
- skipcrud + current_file_name);
- else
- msg("could only write %d of %d bytes to file %s",
- written,check,skipcrud + current_file_name);
- skip_file((long)(size - written));
- break; /* Still do the close, mod time, chmod, etc */
- }
-
- if(f_multivol)
- save_name = 0;
-
- /* If writing to stdout, don't try to do anything
+ if (check < 0)
+ msg_perror ("couldn't write to file %s",
+ skipcrud + current_file_name);
+ else
+ msg ("could only write %d of %d bytes to file %s",
+ written, check, skipcrud + current_file_name);
+ skip_file ((long) (size - written));
+ break; /* Still do the close, mod time, chmod, etc */
+ }
+
+ if (f_multivol)
+ save_name = 0;
+
+ /* If writing to stdout, don't try to do anything
to the filename; it doesn't exist, or we don't
want to touch it anyway */
- if(f_exstdout)
- break;
+ if (f_exstdout)
+ break;
- /* if (head->header.isextended) {
+ /* if (head->header.isextended) {
register union record *exhdr;
register int i;
}*/
- check = close(fd);
- if (check < 0) {
- msg_perror("Error while closing %s",
- skipcrud + current_file_name);
- }
+ check = close (fd);
+ if (check < 0)
+ {
+ msg_perror ("Error while closing %s",
+ skipcrud + current_file_name);
+ }
- set_filestat:
+ set_filestat:
- /*
+ /*
* If we are root, set the owner and group of the extracted
* file. This does what is wanted both on real Unix and on
* System V. If we are running as a user, we extract as that
* user; if running as root, we extract as the original owner.
*/
- if (we_are_root || f_do_chown) {
- if (chown(skipcrud + current_file_name,
- hstat.st_uid, hstat.st_gid) < 0) {
- msg_perror("cannot chown file %s to uid %d gid %d",
- skipcrud + current_file_name,
- hstat.st_uid,hstat.st_gid);
- }
- }
+ if (we_are_root || f_do_chown)
+ {
+ if (chown (skipcrud + current_file_name,
+ hstat.st_uid, hstat.st_gid) < 0)
+ {
+ msg_perror ("cannot chown file %s to uid %d gid %d",
+ skipcrud + current_file_name,
+ hstat.st_uid, hstat.st_gid);
+ }
+ }
- /*
+ /*
* Set the modified time of the file.
- *
+ *
* Note that we set the accessed time to "now", which
* is really "the time we started extracting files".
* unless f_gnudump is used, in which case .st_atime is used
*/
- if (!f_modified) {
- /* fixme if f_gnudump should set ctime too, but how? */
- if(f_gnudump)
- acc_upd_times.actime=hstat.st_atime;
- else
- acc_upd_times.actime = now; /* Accessed now */
- acc_upd_times.modtime = hstat.st_mtime; /* Mod'd */
- if (utime(skipcrud + current_file_name,
- &acc_upd_times) < 0) {
- msg_perror("couldn't change access and modification times of %s",skipcrud + current_file_name);
- }
- }
- /* We do the utime before the chmod because some versions of
+ if (!f_modified)
+ {
+ /* fixme if f_gnudump should set ctime too, but how? */
+ if (f_gnudump)
+ acc_upd_times.actime = hstat.st_atime;
+ else
+ acc_upd_times.actime = now; /* Accessed now */
+ acc_upd_times.modtime = hstat.st_mtime; /* Mod'd */
+ if (utime (skipcrud + current_file_name,
+ &acc_upd_times) < 0)
+ {
+ msg_perror ("couldn't change access and modification times of %s", skipcrud + current_file_name);
+ }
+ }
+ /* We do the utime before the chmod because some versions of
utime are broken and trash the modes of the file. Since
we then change the mode anyway, we don't care. . . */
- /*
+ /*
* If '-k' is not set, open() or creat() could have saved
* the permission bits from a previously created file,
* ignoring the ones we specified.
* skip the chmod. This works because we did umask(0) if -p
* is set, so umask will have left the specified mode alone.
*/
- if ((!f_keep)
- || (hstat.st_mode & (S_ISUID|S_ISGID|S_ISVTX))) {
- if (chmod(skipcrud + current_file_name,
- notumask & (int)hstat.st_mode) < 0) {
- msg_perror("cannot change mode of file %s to %ld",
- skipcrud + current_file_name,
- notumask & (int)hstat.st_mode);
- }
- }
-
- quit:
- break;
-
- case LF_LINK:
- again_link:
+ if ((!f_keep)
+ || (hstat.st_mode & (S_ISUID | S_ISGID | S_ISVTX)))
{
- struct stat st1,st2;
-
- check = link (current_link_name, skipcrud + current_file_name);
-
- if (check == 0)
- break;
- if (make_dirs(skipcrud + current_file_name))
- goto again_link;
- if(f_gnudump && errno==EEXIST)
- break;
- if(stat(current_link_name, &st1) == 0
- && stat(current_file_name + skipcrud, &st2)==0
- && st1.st_dev==st2.st_dev
- && st1.st_ino==st2.st_ino)
- break;
- msg_perror("Could not link %s to %s",
- skipcrud + current_file_name,
- current_link_name);
+ if (chmod (skipcrud + current_file_name,
+ notumask & (int) hstat.st_mode) < 0)
+ {
+ msg_perror ("cannot change mode of file %s to %ld",
+ skipcrud + current_file_name,
+ notumask & (int) hstat.st_mode);
+ }
}
- break;
+
+ quit:
+ break;
+
+ case LF_LINK:
+ again_link:
+ {
+ struct stat st1, st2;
+
+ check = link (current_link_name, skipcrud + current_file_name);
+
+ if (check == 0)
+ break;
+ if (make_dirs (skipcrud + current_file_name))
+ goto again_link;
+ if (f_gnudump && errno == EEXIST)
+ break;
+ if (stat (current_link_name, &st1) == 0
+ && stat (current_file_name + skipcrud, &st2) == 0
+ && st1.st_dev == st2.st_dev
+ && st1.st_ino == st2.st_ino)
+ break;
+ msg_perror ("Could not link %s to %s",
+ skipcrud + current_file_name,
+ current_link_name);
+ }
+ break;
#ifdef S_ISLNK
- case LF_SYMLINK:
- again_symlink:
- check = symlink(current_link_name,
- skipcrud + current_file_name);
- /* FIXME, don't worry uid, gid, etc... */
- if (check == 0)
- break;
- if (make_dirs(current_file_name + skipcrud))
- goto again_symlink;
- msg_perror("Could not create symlink to %s",
- current_link_name);
- break;
+ case LF_SYMLINK:
+ again_symlink:
+ check = symlink (current_link_name,
+ skipcrud + current_file_name);
+ /* FIXME, don't worry uid, gid, etc... */
+ if (check == 0)
+ break;
+ if (make_dirs (current_file_name + skipcrud))
+ goto again_symlink;
+ msg_perror ("Could not create symlink to %s",
+ current_link_name);
+ break;
#endif
#ifdef S_IFCHR
- case LF_CHR:
- hstat.st_mode |= S_IFCHR;
- goto make_node;
+ case LF_CHR:
+ hstat.st_mode |= S_IFCHR;
+ goto make_node;
#endif
#ifdef S_IFBLK
- case LF_BLK:
- hstat.st_mode |= S_IFBLK;
+ case LF_BLK:
+ hstat.st_mode |= S_IFBLK;
#endif
#if defined(S_IFCHR) || defined(S_IFBLK)
- make_node:
- check = mknod(current_file_name + skipcrud,
- (int) hstat.st_mode, (int) hstat.st_rdev);
- if (check != 0) {
- if (make_dirs(skipcrud + current_file_name))
- goto make_node;
- msg_perror("Could not make %s",
- current_file_name + skipcrud);
- break;
- };
- goto set_filestat;
+ make_node:
+ check = mknod (current_file_name + skipcrud,
+ (int) hstat.st_mode, (int) hstat.st_rdev);
+ if (check != 0)
+ {
+ if (make_dirs (skipcrud + current_file_name))
+ goto make_node;
+ msg_perror ("Could not make %s",
+ current_file_name + skipcrud);
+ break;
+ };
+ goto set_filestat;
#endif
#ifdef S_ISFIFO
- /* If local system doesn't support FIFOs, use default case */
- case LF_FIFO:
- make_fifo:
- check = mkfifo(current_file_name + skipcrud,
- (int) hstat.st_mode);
- if (check != 0) {
- if (make_dirs(current_file_name + skipcrud))
- goto make_fifo;
- msg_perror("Could not make %s",
- skipcrud + current_file_name);
- break;
- };
- goto set_filestat;
+ /* If local system doesn't support FIFOs, use default case */
+ case LF_FIFO:
+ make_fifo:
+ check = mkfifo (current_file_name + skipcrud,
+ (int) hstat.st_mode);
+ if (check != 0)
+ {
+ if (make_dirs (current_file_name + skipcrud))
+ goto make_fifo;
+ msg_perror ("Could not make %s",
+ skipcrud + current_file_name);
+ break;
+ };
+ goto set_filestat;
#endif
- case LF_DIR:
- case LF_DUMPDIR:
- namelen = strlen(current_file_name) + skipcrud - 1;
- really_dir:
- /* Check for trailing /, and zap as many as we find. */
- while (namelen
- && current_file_name[skipcrud+namelen] == '/')
- current_file_name[skipcrud+namelen--] = '\0';
- if(f_gnudump) { /* Read the entry and delete files
+ case LF_DIR:
+ case LF_DUMPDIR:
+ namelen = strlen (current_file_name) + skipcrud - 1;
+ really_dir:
+ /* Check for trailing /, and zap as many as we find. */
+ while (namelen
+ && current_file_name[skipcrud + namelen] == '/')
+ current_file_name[skipcrud + namelen--] = '\0';
+ if (f_gnudump)
+ { /* Read the entry and delete files
that aren't listed in the archive */
- gnu_restore(skipcrud);
-
- } else if(head->header.linkflag==LF_DUMPDIR)
- skip_file((long)(hstat.st_size));
-
-
- again_dir:
- check = mkdir(skipcrud+current_file_name,
- (we_are_root ? 0 : 0300) | (int)hstat.st_mode);
- if (check != 0) {
- struct stat st1;
-
- if (make_dirs(skipcrud+current_file_name))
- goto again_dir;
- /* If we're trying to create '.', let it be. */
- if (current_file_name[skipcrud+namelen] == '.' &&
- (namelen==0 ||
- current_file_name[skipcrud+namelen-1]=='/'))
- goto check_perms;
- if( errno==EEXIST
- && stat(skipcrud+current_file_name,&st1)==0
- && (S_ISDIR(st1.st_mode)))
- break;
- msg_perror("Could not create directory %s",skipcrud+current_file_name);
- break;
- }
-
- check_perms:
- if (!we_are_root && 0300 != (0300 & (int) hstat.st_mode)) {
- hstat.st_mode |= 0300;
- msg("Added write and execute permission to directory %s",
- skipcrud+current_file_name);
- }
+ gnu_restore (skipcrud);
- if (f_modified)
- goto set_filestat;
- tmp = (struct saved_dir_info *) malloc (sizeof (struct saved_dir_info));
- tmp->path = malloc (strlen (skipcrud + current_file_name) + 1);
- strcpy (tmp->path, skipcrud + current_file_name);
- tmp->mode = hstat.st_mode;
- tmp->atime = hstat.st_atime;
- tmp->mtime = hstat.st_mtime;
- tmp->next = saved_dir_info_head;
- saved_dir_info_head = tmp;
- case LF_VOLHDR:
- if(f_verbose) {
- printf("Reading %s\n", current_file_name);
- }
- break;
+ }
+ else if (head->header.linkflag == LF_DUMPDIR)
+ skip_file ((long) (hstat.st_size));
- case LF_NAMES:
- extract_mangle(head);
- break;
- case LF_MULTIVOL:
- msg("Can't extract '%s'--file is continued from another volume\n",current_file_name);
- skip_file((long)hstat.st_size);
- break;
+ again_dir:
+ check = mkdir (skipcrud + current_file_name,
+ (we_are_root ? 0 : 0300) | (int) hstat.st_mode);
+ if (check != 0)
+ {
+ struct stat st1;
+
+ if (make_dirs (skipcrud + current_file_name))
+ goto again_dir;
+ /* If we're trying to create '.', let it be. */
+ if (current_file_name[skipcrud + namelen] == '.' &&
+ (namelen == 0 ||
+ current_file_name[skipcrud + namelen - 1] == '/'))
+ goto check_perms;
+ if (errno == EEXIST
+ && stat (skipcrud + current_file_name, &st1) == 0
+ && (S_ISDIR (st1.st_mode)))
+ break;
+ msg_perror ("Could not create directory %s", skipcrud + current_file_name);
+ break;
+ }
+
+ check_perms:
+ if (!we_are_root && 0300 != (0300 & (int) hstat.st_mode))
+ {
+ hstat.st_mode |= 0300;
+ msg ("Added write and execute permission to directory %s",
+ skipcrud + current_file_name);
+ }
- case LF_LONGNAME:
- case LF_LONGLINK:
- msg ("Visible long name error\n");
- skip_file ((long)hstat.st_size);
- break;
- }
-
- /* We don't need to save it any longer. */
- saverec((union record **) 0); /* Unsave it */
+ if (f_modified)
+ goto set_filestat;
+ tmp = (struct saved_dir_info *) malloc (sizeof (struct saved_dir_info));
+ tmp->path = malloc (strlen (skipcrud + current_file_name) + 1);
+ strcpy (tmp->path, skipcrud + current_file_name);
+ tmp->mode = hstat.st_mode;
+ tmp->atime = hstat.st_atime;
+ tmp->mtime = hstat.st_mtime;
+ tmp->next = saved_dir_info_head;
+ saved_dir_info_head = tmp;
+ case LF_VOLHDR:
+ if (f_verbose)
+ {
+ printf ("Reading %s\n", current_file_name);
+ }
+ break;
+
+ case LF_NAMES:
+ extract_mangle (head);
+ break;
+
+ case LF_MULTIVOL:
+ msg ("Can't extract '%s'--file is continued from another volume\n", current_file_name);
+ skip_file ((long) hstat.st_size);
+ break;
+
+ case LF_LONGNAME:
+ case LF_LONGLINK:
+ msg ("Visible long name error\n");
+ skip_file ((long) hstat.st_size);
+ break;
+ }
+
+ /* We don't need to save it any longer. */
+ saverec ((union record **) 0);/* Unsave it */
}
/*
* so, create all required dirs.
*/
int
-make_dirs(pathname)
- char *pathname;
+make_dirs (pathname)
+ char *pathname;
{
- char *p; /* Points into path */
- int madeone = 0; /* Did we do anything yet? */
- int save_errno = errno; /* Remember caller's errno */
- int check;
-
- if (errno != ENOENT)
- return 0; /* Not our problem */
-
- for (p = index(pathname, '/'); p != NULL; p = index(p+1, '/')) {
- /* Avoid mkdir of empty string, if leading or double '/' */
- if (p == pathname || p[-1] == '/')
- continue;
- /* Avoid mkdir where last part of path is '.' */
- if (p[-1] == '.' && (p == pathname+1 || p[-2] == '/'))
- continue;
- *p = 0; /* Truncate the path there */
- check = mkdir (pathname, 0777); /* Try to create it as a dir */
- if (check == 0) {
- /* Fix ownership */
- if (we_are_root) {
- if (chown(pathname, hstat.st_uid,
- hstat.st_gid) < 0) {
- msg_perror("cannot change owner of %s to uid %d gid %d",pathname,hstat.st_uid,hstat.st_gid);
- }
- }
- pr_mkdir(pathname, p-pathname, notumask&0777);
- madeone++; /* Remember if we made one */
- *p = '/';
- continue;
+ char *p; /* Points into path */
+ int madeone = 0; /* Did we do anything yet? */
+ int save_errno = errno; /* Remember caller's errno */
+ int check;
+
+ if (errno != ENOENT)
+ return 0; /* Not our problem */
+
+ for (p = index (pathname, '/'); p != NULL; p = index (p + 1, '/'))
+ {
+ /* Avoid mkdir of empty string, if leading or double '/' */
+ if (p == pathname || p[-1] == '/')
+ continue;
+ /* Avoid mkdir where last part of path is '.' */
+ if (p[-1] == '.' && (p == pathname + 1 || p[-2] == '/'))
+ continue;
+ *p = 0; /* Truncate the path there */
+ check = mkdir (pathname, 0777); /* Try to create it as a dir */
+ if (check == 0)
+ {
+ /* Fix ownership */
+ if (we_are_root)
+ {
+ if (chown (pathname, hstat.st_uid,
+ hstat.st_gid) < 0)
+ {
+ msg_perror ("cannot change owner of %s to uid %d gid %d", pathname, hstat.st_uid, hstat.st_gid);
}
- *p = '/';
- if (errno == EEXIST) /* Directory already exists */
- continue;
- /*
+ }
+ pr_mkdir (pathname, p - pathname, notumask & 0777);
+ madeone++; /* Remember if we made one */
+ *p = '/';
+ continue;
+ }
+ *p = '/';
+ if (errno == EEXIST) /* Directory already exists */
+ continue;
+ /*
* Some other error in the mkdir. We return to the caller.
*/
- break;
- }
+ break;
+ }
- errno = save_errno; /* Restore caller's errno */
- return madeone; /* Tell them to retry if we made one */
+ errno = save_errno; /* Restore caller's errno */
+ return madeone; /* Tell them to retry if we made one */
}
void
-extract_sparse_file(fd, sizeleft, totalsize, name)
- int fd;
- long *sizeleft,
- totalsize;
- char *name;
-{
-/* register char *data;*/
- union record *datarec;
- int sparse_ind = 0;
- int written,
- count;
-
- /* assuming sizeleft is initially totalsize */
-
-
- while (*sizeleft > 0) {
- datarec = findrec();
- if (datarec == NULL) {
- msg("Unexpected EOF on archive file");
- return;
- }
- lseek(fd, sparsearray[sparse_ind].offset, 0);
- written = sparsearray[sparse_ind++].numbytes;
- while (written > RECORDSIZE) {
- count = write(fd, datarec->charptr, RECORDSIZE);
- if (count < 0)
- msg_perror("couldn't write to file %s", name);
- written -= count;
- *sizeleft -= count;
- userec(datarec);
- datarec = findrec();
- }
+extract_sparse_file (fd, sizeleft, totalsize, name)
+ int fd;
+ long *sizeleft, totalsize;
+ char *name;
+{
+ /* register char *data;*/
+ union record *datarec;
+ int sparse_ind = 0;
+ int written, count;
+
+ /* assuming sizeleft is initially totalsize */
- count = write(fd, datarec->charptr, written);
-
- if (count < 0) {
- msg_perror("couldn't write to file %s", name);
- } else if (count != written) {
- msg("could only write %d of %d bytes to file %s", totalsize - *sizeleft, totalsize, name);
- skip_file((long) (*sizeleft));
- }
- written -= count;
- *sizeleft -= count;
- userec(datarec);
+ while (*sizeleft > 0)
+ {
+ datarec = findrec ();
+ if (datarec == NULL)
+ {
+ msg ("Unexpected EOF on archive file");
+ return;
}
- free(sparsearray);
-/* if (end_nulls) {
+ lseek (fd, sparsearray[sparse_ind].offset, 0);
+ written = sparsearray[sparse_ind++].numbytes;
+ while (written > RECORDSIZE)
+ {
+ count = write (fd, datarec->charptr, RECORDSIZE);
+ if (count < 0)
+ msg_perror ("couldn't write to file %s", name);
+ written -= count;
+ *sizeleft -= count;
+ userec (datarec);
+ datarec = findrec ();
+ }
+
+ count = write (fd, datarec->charptr, written);
+
+ if (count < 0)
+ {
+ msg_perror ("couldn't write to file %s", name);
+ }
+ else if (count != written)
+ {
+ msg ("could only write %d of %d bytes to file %s", totalsize - *sizeleft, totalsize, name);
+ skip_file ((long) (*sizeleft));
+ }
+
+ written -= count;
+ *sizeleft -= count;
+ userec (datarec);
+ }
+ free (sparsearray);
+ /* if (end_nulls) {
register int i;
printf("%d\n", (int) end_nulls);
for (i = 0; i < end_nulls; i++)
write(fd, "\000", 1);
}*/
- userec(datarec);
+ userec (datarec);
}
/* Set back the utime and mode for all the extracted directories. */
-void restore_saved_dir_info ()
+void
+restore_saved_dir_info ()
{
struct utimbuf acc_upd_times;
struct saved_dir_info *tmp;
while (saved_dir_info_head != NULL)
{
/* fixme if f_gnudump should set ctime too, but how? */
- if(f_gnudump)
- acc_upd_times.actime=saved_dir_info_head -> atime;
- else
- acc_upd_times.actime = now; /* Accessed now */
- acc_upd_times.modtime = saved_dir_info_head -> mtime; /* Mod'd */
- if (utime(saved_dir_info_head -> path, &acc_upd_times) < 0) {
- msg_perror("couldn't change access and modification times of %s",
- saved_dir_info_head -> path);
- }
- if ((!f_keep) || (saved_dir_info_head -> mode & (S_ISUID|S_ISGID|S_ISVTX)))
+ if (f_gnudump)
+ acc_upd_times.actime = saved_dir_info_head->atime;
+ else
+ acc_upd_times.actime = now; /* Accessed now */
+ acc_upd_times.modtime = saved_dir_info_head->mtime; /* Mod'd */
+ if (utime (saved_dir_info_head->path, &acc_upd_times) < 0)
{
- if (chmod(saved_dir_info_head -> path,
- notumask & saved_dir_info_head -> mode) < 0) {
- msg_perror("cannot change mode of file %s to %ld",
- saved_dir_info_head -> path,
- notumask & saved_dir_info_head -> mode);
- }
+ msg_perror ("couldn't change access and modification times of %s",
+ saved_dir_info_head->path);
+ }
+ if ((!f_keep) || (saved_dir_info_head->mode & (S_ISUID | S_ISGID | S_ISVTX)))
+ {
+ if (chmod (saved_dir_info_head->path,
+ notumask & saved_dir_info_head->mode) < 0)
+ {
+ msg_perror ("cannot change mode of file %s to %ld",
+ saved_dir_info_head->path,
+ notumask & saved_dir_info_head->mode);
+ }
}
- saved_dir_info_head = saved_dir_info_head -> next;
+ saved_dir_info_head = saved_dir_info_head->next;
}
}