From f80020a36d34beeb78d7d0ec4bcdb8cd73c85f26 Mon Sep 17 00:00:00 2001 From: joerg Date: Mon, 18 Mar 1996 23:08:29 +0000 Subject: 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) --- gnu/usr.bin/cpio/copyin.c | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) (limited to 'gnu/usr.bin/cpio') 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; +} -- cgit v1.1