diff -up cpio-2.9/src/extern.h.orig cpio-2.9/src/extern.h --- cpio-2.9/src/extern.h.orig 2007-06-28 14:59:38.000000000 +0200 +++ cpio-2.9/src/extern.h 2008-02-13 15:24:37.000000000 +0100 @@ -211,7 +211,7 @@ uintmax_t from_ascii (char const *where, void delay_set_stat (char const *file_name, struct stat *st, mode_t invert_permissions); -void repair_delayed_set_stat (char const *dir, +int repair_delayed_set_stat (char const *dir, struct stat *dir_stat_info); void apply_delayed_set_stat (void); diff -up cpio-2.9/src/copyin.c.orig cpio-2.9/src/copyin.c --- cpio-2.9/src/copyin.c.orig 2007-06-28 12:51:09.000000000 +0200 +++ cpio-2.9/src/copyin.c 2008-02-14 10:28:33.000000000 +0100 @@ -570,6 +570,7 @@ static void copyin_directory (struct cpio_file_stat *file_hdr, int existing_dir) { int res; /* Result of various function calls. */ + struct stat file_stat; #ifdef HPUX_CDF int cdf_flag; /* True if file is a CDF. */ int cdf_char; /* Index of `+' char indicating a CDF. */ @@ -626,7 +627,6 @@ copyin_directory (struct cpio_file_stat 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); @@ -645,7 +645,11 @@ copyin_directory (struct cpio_file_stat } } - set_perms (-1, file_hdr); + /* if the directory is queued for delayed_set_stat, + fix permissions in the queue, otherwise set the permissions now */ + cpio_to_stat(file_hdr, &file_stat); + if (repair_delayed_set_stat(file_hdr->c_name, &file_stat)) + set_perms (-1, file_hdr); } static void diff -up cpio-2.9/src/makepath.c.orig cpio-2.9/src/makepath.c diff -up cpio-2.9/src/util.c.orig cpio-2.9/src/util.c --- cpio-2.9/src/util.c.orig 2007-06-28 15:04:51.000000000 +0200 +++ cpio-2.9/src/util.c 2008-02-14 13:24:37.000000000 +0100 @@ -1265,6 +1265,16 @@ stat_to_cpio (struct cpio_file_stat *hdr hdr->c_tar_linkname = NULL; } +void +cpio_to_stat (struct cpio_file_stat *hdr, struct stat *st) +{ + stat (hdr->c_name, st); + st->st_mode = hdr->c_mode; + st->st_uid = CPIO_UID(hdr->c_uid); + st->st_gid = CPIO_GID(hdr->c_gid); + st->st_mtime = hdr->c_mtime; +} + #ifndef HAVE_FCHOWN # define fchown(fd, uid, gid) (-1) #endif @@ -1389,7 +1399,7 @@ delay_set_stat (char const *file_name, s 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. */ -void +int repair_delayed_set_stat (char const *dir, struct stat *dir_stat_info) { @@ -1400,22 +1410,19 @@ repair_delayed_set_stat (char const *dir if (stat (data->stat.c_name, &st) != 0) { stat_error (data->stat.c_name); - return; + return 0; } 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; + data->invert_permissions = 0; + return 0; } } - ERROR ((0, 0, _("%s: Unexpected inconsistency when making directory"), - quotearg_colon (dir))); + return -1; } void