summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/cpio
diff options
context:
space:
mode:
authorjoerg <joerg@FreeBSD.org>1996-03-18 23:08:29 +0000
committerjoerg <joerg@FreeBSD.org>1996-03-18 23:08:29 +0000
commitf80020a36d34beeb78d7d0ec4bcdb8cd73c85f26 (patch)
tree4bb9ebb133018741a19fd59ad93a0f2067bd6912 /gnu/usr.bin/cpio
parentf4fd38ee57f3bf67fc2b9eff336296dcfc2fb4fc (diff)
downloadFreeBSD-src-f80020a36d34beeb78d7d0ec4bcdb8cd73c85f26.zip
FreeBSD-src-f80020a36d34beeb78d7d0ec4bcdb8cd73c85f26.tar.gz
Fix an infinite loop for empty files in the archive, and handle
sparsely stored linked files correctly. Submitted by: haug@conterra.com (Brian R. Haug)
Diffstat (limited to 'gnu/usr.bin/cpio')
-rw-r--r--gnu/usr.bin/cpio/copyin.c37
1 files changed, 34 insertions, 3 deletions
diff --git a/gnu/usr.bin/cpio/copyin.c b/gnu/usr.bin/cpio/copyin.c
index 7c5d349..e8804de 100644
--- a/gnu/usr.bin/cpio/copyin.c
+++ b/gnu/usr.bin/cpio/copyin.c
@@ -38,6 +38,7 @@ static void skip_padding ();
static void defer_copyin ();
static void create_defered_links ();
static void create_final_defers ();
+static int check_for_deferments ();
/* Return 16-bit integer I with the bytes swapped. */
#define swab_short(i) ((((i) << 8) & 0xff00) | (((i) >> 8) & 0x00ff))
@@ -381,6 +382,7 @@ process_copy_in ()
int out_file_des; /* Output file descriptor. */
int in_file_des; /* Input file descriptor. */
char skip_file; /* Flag for use with patterns. */
+ char deferred; /* Deferred file creation, don't print name. */
int existing_dir; /* True if file is a dir & already exists. */
int i; /* Loop index variable. */
char *link_name = NULL; /* Name of hard and symbolic links. */
@@ -472,6 +474,7 @@ process_copy_in ()
break;
}
+ deferred = FALSE;
/* Does the file name match one of the given patterns? */
if (num_patterns <= 0)
skip_file = FALSE;
@@ -484,6 +487,11 @@ process_copy_in ()
if (fnmatch (save_patterns[i], file_hdr.c_name, 0) == 0)
skip_file = !copy_matching_files;
}
+ if (skip_file) {
+ skip_file = check_for_deferments(&file_hdr);
+ if (!skip_file)
+ deferred = TRUE; /* don't print this name */
+ }
}
if (skip_file)
@@ -921,9 +929,9 @@ process_copy_in ()
skip_padding (in_file_des, file_hdr.c_filesize);
}
- if (verbose_flag)
+ if (verbose_flag && !deferred)
fprintf (stderr, "%s\n", file_hdr.c_name);
- if (dot_flag)
+ if (dot_flag && !deferred)
fputc ('.', stderr);
}
}
@@ -1226,7 +1234,6 @@ create_final_defers ()
for (d = deferments; d != NULL; d = d->next)
{
- d = deferments;
link_res = link_to_maj_min_ino (d->header.c_name,
d->header.c_dev_maj, d->header.c_dev_maj,
d->header.c_ino);
@@ -1270,3 +1277,27 @@ create_final_defers ()
}
}
}
+
+static int
+check_for_deferments(struct new_cpio_header *file_hdr)
+{
+ struct deferment *d;
+ struct deferment *prev = NULL;
+
+ for (d = deferments; d != NULL; d = d->next) {
+ if (file_hdr->c_ino == d->header.c_ino &&
+ file_hdr->c_dev_maj == d->header.c_dev_maj &&
+ file_hdr->c_dev_min == d->header.c_dev_min) {
+ free(file_hdr->c_name);
+ if (prev != NULL)
+ prev->next = d->next;
+ else
+ deferments = d->next;
+ file_hdr->c_name = strdup(d->header.c_name);
+ free_deferment(d);
+ return FALSE;
+ }
+ prev = d;
+ }
+ return TRUE;
+}
OpenPOWER on IntegriCloud