/* Extract files from a tar archive.
- Copyright (C) 1988, 1992 Free Software Foundation
+ Copyright (C) 1988, 1992, 1993 Free Software Foundation
This file is part of GNU Tar.
*/
case LF_SPARSE:
sp_array_size = 10;
- sparsearray = (struct sp_array *) malloc (sp_array_size * sizeof (struct sp_array));
+ sparsearray = (struct sp_array *) ck_malloc (sp_array_size * sizeof (struct sp_array));
for (i = 0; i < SPARSE_IN_HDR; i++)
{
sparsearray[i].offset =
* since we've run out of room --
*/
sparsearray = (struct sp_array *)
- realloc (sparsearray,
+ ck_realloc (sparsearray,
2 * sp_array_size * (sizeof (struct sp_array)));
sp_array_size *= 2;
}
* 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);
+ namelen = strlen (skipcrud + current_file_name) + 1;
+ name = (char *) ck_malloc ((sizeof (char)) * namelen);
bcopy (skipcrud + current_file_name, name, namelen);
size = hstat.st_size;
extract_sparse_file (fd, &size, hstat.st_size, name);
skipcrud + current_file_name);
else
msg ("could only write %d of %d bytes to file %s",
- written, check, skipcrud + current_file_name);
+ check, written, skipcrud + current_file_name);
skip_file ((long) (size - written));
break; /* Still do the close, mod time, chmod, etc */
}
if (chmod (skipcrud + current_file_name,
notumask & (int) hstat.st_mode) < 0)
{
- msg_perror ("cannot change mode of file %s to %ld",
+ msg_perror ("cannot change mode of file %s to %lo",
skipcrud + current_file_name,
notumask & (int) hstat.st_mode);
}
case LF_DIR:
case LF_DUMPDIR:
- namelen = strlen (current_file_name) + skipcrud - 1;
+ namelen = strlen (current_file_name + skipcrud) - 1;
really_dir:
/* Check for trailing /, and zap as many as we find. */
while (namelen
skipcrud + current_file_name);
}
- 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;
+ /*
+ * 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 (!f_modified)
+ {
+ tmp = ((struct saved_dir_info *)
+ ck_malloc (sizeof (struct saved_dir_info)));
+ tmp->path = (char *) ck_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;
+ }
+ else
+ {
+ /* This functions exactly as the code for set_filestat above. */
+ 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 %lo",
+ skipcrud + current_file_name,
+ notumask & (int) hstat.st_mode);
+ }
+ }
+ }
+ break;
+
case LF_VOLHDR:
if (f_verbose)
{
}
else if (count != written)
{
- msg ("could only write %d of %d bytes to file %s", totalsize - *sizeleft, totalsize, name);
+ msg ("could only write %d of %d bytes to file %s", count,
+ totalsize, name);
skip_file ((long) (*sizeleft));
}
if (chmod (saved_dir_info_head->path,
notumask & saved_dir_info_head->mode) < 0)
{
- msg_perror ("cannot change mode of file %s to %ld",
+ msg_perror ("cannot change mode of file %s to %lo",
saved_dir_info_head->path,
notumask & saved_dir_info_head->mode);
}