summaryrefslogtreecommitdiff
path: root/src/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util.c')
-rw-r--r--src/util.c316
1 files changed, 19 insertions, 297 deletions
diff --git a/src/util.c b/src/util.c
index 00953d5..5bcc40a 100644
--- a/src/util.c
+++ b/src/util.c
@@ -1,10 +1,10 @@
/* util.c - Several utility routines for cpio.
- Copyright (C) 1990, 1991, 1992, 2001, 2004, 2006, 2007, 2010 Free
- Software Foundation, Inc.
+ Copyright (C) 1990, 1991, 1992, 2001, 2004,
+ 2006 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
+ the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
@@ -33,9 +33,7 @@
#include <hash.h>
#include <utimens.h>
-#ifdef HAVE_SYS_IOCTL_H
-# include <sys/ioctl.h>
-#endif
+#include <sys/ioctl.h>
#ifdef HAVE_SYS_MTIO_H
# ifdef HAVE_SYS_IO_TRIOCTL_H
@@ -443,8 +441,8 @@ write_nuls_to_file (off_t num_bytes, int out_des,
void
copy_files_tape_to_disk (int in_des, int out_des, off_t num_bytes)
{
- off_t size;
- off_t k;
+ long size;
+ long k;
while (num_bytes > 0)
{
@@ -474,8 +472,8 @@ void
copy_files_disk_to_tape (int in_des, int out_des, off_t num_bytes,
char *filename)
{
- off_t size;
- off_t k;
+ long size;
+ long k;
int rc;
off_t original_num_bytes;
@@ -527,8 +525,8 @@ void
copy_files_disk_to_disk (int in_des, int out_des, off_t num_bytes,
char *filename)
{
- off_t size;
- off_t k;
+ long size;
+ long k;
off_t original_num_bytes;
int rc;
@@ -569,8 +567,8 @@ copy_files_disk_to_disk (int in_des, int out_des, off_t num_bytes,
/* Warn if file changed while it was being copied. */
void
-warn_if_file_changed (char *file_name, off_t old_file_size,
- time_t old_file_mtime)
+warn_if_file_changed (char *file_name, unsigned long old_file_size,
+ off_t old_file_mtime)
{
struct stat new_file_stat;
if ((*xstat) (file_name, &new_file_stat) < 0)
@@ -620,14 +618,7 @@ create_all_directories (char *name)
error (2, 0, _("virtual memory exhausted"));
if (dir[0] != '.' || dir[1] != '\0')
- {
- const char *fmt;
- if (warn_option & CPIO_WARN_INTERDIR)
- fmt = _("Creating intermediate directory `%s'");
- else
- fmt = NULL;
- make_path (dir, -1, -1, fmt);
- }
+ make_path (dir, mode, 0700, -1, -1, (char *) NULL);
free (dir);
}
@@ -686,7 +677,7 @@ prepare_append (int out_file_des)
struct inode_val
{
- ino_t inode;
+ unsigned long inode;
unsigned long major_num;
unsigned long minor_num;
char *file_name;
@@ -713,7 +704,7 @@ inode_val_compare (const void *val1, const void *val2)
}
char *
-find_inode_file (ino_t node_num, unsigned long major_num,
+find_inode_file (unsigned long node_num, unsigned long major_num,
unsigned long minor_num)
{
struct inode_val sample;
@@ -732,7 +723,7 @@ find_inode_file (ino_t node_num, unsigned long major_num,
/* Associate FILE_NAME with the inode NODE_NUM. (Insert into hash table.) */
void
-add_inode (ino_t node_num, char *file_name, unsigned long major_num,
+add_inode (unsigned long node_num, char *file_name, unsigned long major_num,
unsigned long minor_num)
{
struct inode_val *temp;
@@ -1256,9 +1247,9 @@ stat_to_cpio (struct cpio_file_stat *hdr, struct stat *st)
else if (S_ISNWK (st->st_mode))
hdr->c_mode |= CP_IFNWK;
#endif
- hdr->c_nlink = st->st_nlink;
hdr->c_uid = CPIO_UID (st->st_uid);
hdr->c_gid = CPIO_GID (st->st_gid);
+ hdr->c_nlink = st->st_nlink;
hdr->c_rdev_maj = major (st->st_rdev);
hdr->c_rdev_min = minor (st->st_rdev);
hdr->c_mtime = st->st_mtime;
@@ -1267,54 +1258,8 @@ stat_to_cpio (struct cpio_file_stat *hdr, struct stat *st)
hdr->c_tar_linkname = NULL;
}
-void
-cpio_to_stat (struct stat *st, struct cpio_file_stat *hdr)
-{
- memset (st, 0, sizeof (*st));
- st->st_dev = makedev (hdr->c_dev_maj, hdr->c_dev_min);
- st->st_ino = hdr->c_ino;
- st->st_mode = hdr->c_mode & 0777;
- if (hdr->c_mode & CP_IFREG)
- st->st_mode |= S_IFREG;
- else if (hdr->c_mode & CP_IFDIR)
- st->st_mode |= S_IFDIR;
-#ifdef S_IFBLK
- else if (hdr->c_mode & CP_IFBLK)
- st->st_mode |= S_IFBLK;
-#endif
-#ifdef S_IFCHR
- else if (hdr->c_mode & CP_IFCHR)
- st->st_mode |= S_IFCHR;
-#endif
-#ifdef S_IFFIFO
- else if (hdr->c_mode & CP_IFIFO)
- st->st_mode |= S_IFIFO;
-#endif
-#ifdef S_IFLNK
- else if (hdr->c_mode & CP_IFLNK)
- st->st_mode |= S_IFLNK;
-#endif
-#ifdef S_IFSOCK
- else if (hdr->c_mode & CP_IFSOCK)
- st->st_mode |= S_IFSOCK;
-#endif
-#ifdef S_IFNWK
- else if (hdr->c_mode & CP_IFNWK)
- st->st_mode |= S_IFNWK;
-#endif
- st->st_nlink = hdr->c_nlink;
- st->st_uid = CPIO_UID (hdr->c_uid);
- st->st_gid = CPIO_GID (hdr->c_gid);
- st->st_rdev = makedev (hdr->c_rdev_maj, hdr->c_rdev_min);
- st->st_mtime = hdr->c_mtime;
- st->st_size = hdr->c_filesize;
-}
-
#ifndef HAVE_FCHOWN
-# define HAVE_FCHOWN 0
-#endif
-#ifndef HAVE_FCHMOD
-# define HAVE_FCHMOD 0
+# define fchown(fd, uid, gid) (-1)
#endif
int
@@ -1332,7 +1277,7 @@ fchmod_or_chmod (int fd, const char *name, mode_t mode)
if (HAVE_FCHMOD && fd != -1)
return fchmod (fd, mode);
else
- return chmod (name, mode);
+ return chmod(name, mode);
}
void
@@ -1395,226 +1340,3 @@ cpio_safer_name_suffix (char *name, bool link_target, bool absolute_names,
memmove (name, p, (size_t)(strlen (p) + 1));
}
-
-/* This is a simplified form of delayed set_stat used by GNU tar.
- With the time, both forms will merge and pass to paxutils
-
- List of directories whose statuses we need to extract after we've
- finished extracting their subsidiary files. If you consider each
- contiguous subsequence of elements of the form [D]?[^D]*, where [D]
- represents an element where AFTER_LINKS is nonzero and [^D]
- represents an element where AFTER_LINKS is zero, then the head
- of the subsequence has the longest name, and each non-head element
- in the prefix is an ancestor (in the directory hierarchy) of the
- preceding element. */
-
-struct delayed_set_stat
- {
- struct delayed_set_stat *next;
- struct cpio_file_stat stat;
- mode_t invert_permissions;
- };
-
-static struct delayed_set_stat *delayed_set_stat_head;
-
-void
-delay_cpio_set_stat (struct cpio_file_stat *file_stat,
- mode_t invert_permissions)
-{
- size_t file_name_len = strlen (file_stat->c_name);
- struct delayed_set_stat *data =
- xmalloc (sizeof (struct delayed_set_stat) + file_name_len + 1);
- data->next = delayed_set_stat_head;
- memcpy (&data->stat, file_stat, sizeof data->stat);
- data->stat.c_name = (char*) (data + 1);
- strcpy (data->stat.c_name, file_stat->c_name);
- data->invert_permissions = invert_permissions;
- delayed_set_stat_head = data;
-}
-
-void
-delay_set_stat (char const *file_name, struct stat *st,
- mode_t invert_permissions)
-{
- struct cpio_file_stat fs;
-
- stat_to_cpio (&fs, st);
- fs.c_name = (char*) file_name;
- delay_cpio_set_stat (&fs, invert_permissions);
-}
-
-/* Update the delayed_set_stat info for an intermediate directory
- created within the file name of DIR. The intermediate directory turned
- out to be the same as this directory, e.g. due to ".." or symbolic
- links. *DIR_STAT_INFO is the status of the directory. */
-int
-repair_inter_delayed_set_stat (struct stat *dir_stat_info)
-{
- struct delayed_set_stat *data;
- for (data = delayed_set_stat_head; data; data = data->next)
- {
- struct stat st;
- if (stat (data->stat.c_name, &st) != 0)
- {
- stat_error (data->stat.c_name);
- return -1;
- }
-
- if (st.st_dev == dir_stat_info->st_dev
- && st.st_ino == dir_stat_info->st_ino)
- {
- stat_to_cpio (&data->stat, dir_stat_info);
- data->invert_permissions =
- ((dir_stat_info->st_mode ^ st.st_mode)
- & MODE_RWX & ~ newdir_umask);
- return 0;
- }
- }
- return 1;
-}
-
-/* Update the delayed_set_stat info for a directory matching
- FILE_HDR.
-
- Return 0 if such info was found, 1 otherwise. */
-int
-repair_delayed_set_stat (struct cpio_file_stat *file_hdr)
-{
- struct delayed_set_stat *data;
- for (data = delayed_set_stat_head; data; data = data->next)
- {
- if (strcmp (file_hdr->c_name, data->stat.c_name) == 0)
- {
- data->invert_permissions = 0;
- memcpy (&data->stat, file_hdr,
- offsetof (struct cpio_file_stat, c_name));
- return 0;
- }
- }
- return 1;
-}
-
-void
-apply_delayed_set_stat ()
-{
- while (delayed_set_stat_head)
- {
- struct delayed_set_stat *data = delayed_set_stat_head;
- if (data->invert_permissions)
- {
- data->stat.c_mode ^= data->invert_permissions;
- }
- set_perms (-1, &data->stat);
- delayed_set_stat_head = data->next;
- free (data);
- }
-}
-
-
-static int
-cpio_mkdir (struct cpio_file_stat *file_hdr, int *setstat_delayed)
-{
- int rc;
- mode_t mode = file_hdr->c_mode;
-
- if (!(file_hdr->c_mode & S_IWUSR))
- {
- rc = mkdir (file_hdr->c_name, mode | S_IWUSR);
- if (rc == 0)
- {
- delay_cpio_set_stat (file_hdr, 0);
- *setstat_delayed = 1;
- }
- }
- else
- {
- rc = mkdir (file_hdr->c_name, mode);
- *setstat_delayed = 0;
- }
- return rc;
-}
-
-int
-cpio_create_dir (struct cpio_file_stat *file_hdr, int existing_dir)
-{
- int res; /* Result of various function calls. */
-#ifdef HPUX_CDF
- int cdf_flag; /* True if file is a CDF. */
- int cdf_char; /* Index of `+' char indicating a CDF. */
-#endif
- int setstat_delayed = 0;
-
- if (to_stdout_option)
- return 0;
-
- /* Strip any trailing `/'s off the filename; tar puts
- them on. We might as well do it here in case anybody
- else does too, since they cause strange things to happen. */
- strip_trailing_slashes (file_hdr->c_name);
-
- /* Ignore the current directory. It must already exist,
- and we don't want to change its permission, ownership
- or time. */
- if (file_hdr->c_name[0] == '.' && file_hdr->c_name[1] == '\0')
- {
- return 0;
- }
-
-#ifdef HPUX_CDF
- cdf_flag = 0;
-#endif
- if (!existing_dir)
- {
-#ifdef HPUX_CDF
- /* If the directory name ends in a + and is SUID,
- then it is a CDF. Strip the trailing + from
- the name before creating it. */
- cdf_char = strlen (file_hdr->c_name) - 1;
- if ( (cdf_char > 0) &&
- (file_hdr->c_mode & 04000) &&
- (file_hdr->c_name [cdf_char] == '+') )
- {
- file_hdr->c_name [cdf_char] = '\0';
- cdf_flag = 1;
- }
-#endif
- res = cpio_mkdir (file_hdr, &setstat_delayed);
- }
- else
- res = 0;
- if (res < 0 && create_dir_flag)
- {
- create_all_directories (file_hdr->c_name);
- res = cpio_mkdir (file_hdr, &setstat_delayed);
- }
- if (res < 0)
- {
- /* In some odd cases where the file_hdr->c_name includes `.',
- the directory may have actually been created by
- create_all_directories(), so the mkdir will fail
- because the directory exists. If that's the case,
- don't complain about it. */
- struct stat file_stat;
- if (errno != EEXIST)
- {
- mkdir_error (file_hdr->c_name);
- return -1;
- }
- if (lstat (file_hdr->c_name, &file_stat))
- {
- stat_error (file_hdr->c_name);
- return -1;
- }
- if (!(S_ISDIR (file_stat.st_mode)))
- {
- error (0, 0, _("%s is not a directory"),
- quotearg_colon (file_hdr->c_name));
- return -1;
- }
- }
-
- if (!setstat_delayed && repair_delayed_set_stat (file_hdr))
- set_perms (-1, file_hdr);
- return 0;
-}
-