+/* Remember to restore stat attributes (owner, group, mode and times)
+ for the directory FILE_NAME, using information given in *STAT_INFO,
+ once we stop extracting files into that directory.
+ If not restoring permissions, remember to invert the
+ INVERT_PERMISSIONS bits from the file's current permissions.
+ PERMSTATUS specifies the status of the file's permissions. */
+static void
+delay_set_stat (char const *file_name, struct stat const *stat_info,
+ mode_t invert_permissions, enum permstatus permstatus)
+{
+ size_t file_name_len = strlen (file_name);
+ struct delayed_set_stat *data =
+ xmalloc (offsetof (struct delayed_set_stat, file_name)
+ + file_name_len + 1);
+ data->file_name_len = file_name_len;
+ strcpy (data->file_name, file_name);
+ data->invert_permissions = invert_permissions;
+ data->permstatus = permstatus;
+ data->after_symlinks = 0;
+ data->stat_info = *stat_info;
+ data->next = delayed_set_stat_head;
+ delayed_set_stat_head = data;
+}
+
+/* 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. */
+static void
+repair_delayed_set_stat (char const *dir,
+ struct stat const *dir_stat_info)
+{
+ struct delayed_set_stat *data;
+ for (data = delayed_set_stat_head; data; data = data->next)
+ {
+ struct stat st;
+ if (stat (data->file_name, &st) != 0)
+ {
+ stat_error (data->file_name);
+ return;
+ }
+
+ if (st.st_dev == dir_stat_info->st_dev
+ && st.st_ino == dir_stat_info->st_ino)
+ {
+ data->stat_info = current_stat_info.stat;
+ data->invert_permissions =
+ (MODE_RWX & (current_stat_info.stat.st_mode ^ st.st_mode));
+ data->permstatus = ARCHIVED_PERMSTATUS;
+ return;
+ }
+ }
+
+ ERROR ((0, 0, _("%s: Unexpected inconsistency when making directory"),
+ quotearg_colon (dir)));
+}