+ again_dir:
+ check = mkdir (skipcrud + current_file_name,
+ (we_are_root ? 0 : 0300) | (int) hstat.st_mode);
+ if (check != 0)
+ {
+ struct stat st1;
+
+ if (make_dirs (skipcrud + current_file_name))
+ goto again_dir;
+ /* If we're trying to create '.', let it be. */
+ if (current_file_name[skipcrud + namelen] == '.' &&
+ (namelen == 0 ||
+ current_file_name[skipcrud + namelen - 1] == '/'))
+ goto check_perms;
+ if (errno == EEXIST
+ && stat (skipcrud + current_file_name, &st1) == 0
+ && (S_ISDIR (st1.st_mode)))
+ break;
+ msg_perror ("Could not create directory %s", skipcrud + current_file_name);
+ break;
+ }
+
+ check_perms:
+ if (!we_are_root && 0300 != (0300 & (int) hstat.st_mode))
+ {
+ hstat.st_mode |= 0300;
+ msg ("Added write and execute permission to directory %s",
+ skipcrud + current_file_name);
+ }
+
+ /*
+ * If we are root, set the owner and group of the extracted
+ * file. This does what is wanted both on real Unix and on
+ * System V. If we are running as a user, we extract as that
+ * user; if running as root, we extract as the original owner.
+ */
+ if (we_are_root || f_do_chown)
+ {
+ if (chown (skipcrud + current_file_name,
+ hstat.st_uid, hstat.st_gid) < 0)
+ {
+ msg_perror ("cannot chown file %s to uid %d gid %d",
+ skipcrud + current_file_name,
+ hstat.st_uid, hstat.st_gid);
+ }
+ }
+
+ if (!f_modified)
+ {
+ tmp = ((struct saved_dir_info *)
+ ck_malloc (sizeof (struct saved_dir_info)));
+ tmp->path = (char *) ck_malloc (strlen (skipcrud
+ + current_file_name) + 1);
+ strcpy (tmp->path, skipcrud + current_file_name);
+ tmp->mode = hstat.st_mode;
+ tmp->atime = hstat.st_atime;
+ tmp->mtime = hstat.st_mtime;
+ tmp->next = saved_dir_info_head;
+ saved_dir_info_head = tmp;
+ }
+ else
+ {
+ /* This functions exactly as the code for set_filestat above. */
+ if ((!f_keep)
+ || (hstat.st_mode & (S_ISUID | S_ISGID | S_ISVTX)))
+ {
+ if (chmod (skipcrud + current_file_name,
+ notumask & (int) hstat.st_mode) < 0)
+ {
+ msg_perror ("cannot change mode of file %s to %lo",
+ skipcrud + current_file_name,
+ notumask & (int) hstat.st_mode);
+ }
+ }
+ }
+ break;
+
+ case LF_VOLHDR:
+ if (f_verbose)
+ {
+ printf ("Reading %s\n", current_file_name);
+ }
+ break;
+
+ case LF_NAMES:
+ extract_mangle (head);
+ break;
+
+ case LF_MULTIVOL:
+ msg ("Can't extract '%s'--file is continued from another volume\n", current_file_name);
+ skip_file ((long) hstat.st_size);
+ break;
+
+ case LF_LONGNAME:
+ case LF_LONGLINK:
+ msg ("Visible long name error\n");
+ skip_file ((long) hstat.st_size);
+ break;
+ }