- /* slash points to the leftmost unprocessed component of dir. */
- basename_dir = slash;
-
- slash = strchr (slash, '/');
- if (slash == NULL)
- break;
-
- /* If we're *not* doing chdir before each mkdir, then we have to refer
- to the target using the full (multi-component) directory name. */
- if (!do_chdir)
- basename_dir = dir;
-
- *slash = '\0';
- if (! make_dir (basename_dir, dir, tmp_mode, &newly_created_dir))
- {
- CLEANUP;
- return false;
- }
-
- if (newly_created_dir)
- {
- if (verbose_fmt_string)
- error (0, 0, verbose_fmt_string, quote (dir));
-
- if ((owner != (uid_t) -1 || group != (gid_t) -1)
- && chown (basename_dir, owner, group)
-#if defined AFS && defined EPERM
- && errno != EPERM
-#endif
- )
- {
- error (0, errno, _("cannot change owner and/or group of %s"),
- quote (dir));
- CLEANUP;
- return false;
- }
-
- if (re_protect)
- {
- struct ptr_list *new = (struct ptr_list *)
- alloca (sizeof (struct ptr_list));
- new->dirname_end = slash;
- new->next = leading_dirs;
- leading_dirs = new;
- }
- }
-
- /* If we were able to save the initial working directory,
- then we can use chdir to change into each directory before
- creating an entry in that directory. This avoids making
- stat and mkdir process O(n^2) file name components. */
- if (do_chdir && chdir (basename_dir) < 0)
- {
- error (0, errno, _("cannot chdir to directory %s"),
- quote (dir));
- CLEANUP;
- return false;
- }
-
- *slash++ = '/';
-
- /* Avoid unnecessary calls to `stat' when given
- file names containing multiple adjacent slashes. */
- while (*slash == '/')
- slash++;
- }
-
- if (!do_chdir)
- basename_dir = dir;
-
- /* Done creating leading directories. Restore original umask. */
- umask (oldmask);
-
- /* We're done making leading directories.
- Create the final component of the file name. */
-
- if (! make_dir (basename_dir, dir, mode, NULL))
- {
- CLEANUP;
- return false;
- }
-
- if (verbose_fmt_string != NULL)
- error (0, 0, verbose_fmt_string, quote (dir));
-
- if (owner != (uid_t) -1 || group != (gid_t) -1)
- {
- if (chown (basename_dir, owner, group)
-#ifdef AFS
- && errno != EPERM
-#endif
- )
- {
- error (0, errno, _("cannot change owner and/or group of %s"),
- quote (dir));
- retval = false;
- }
- }
-
- /* The above chown may have turned off some permission bits in MODE.
- Another reason we may have to use chmod here is that mkdir(2) is
- required to honor only the file permission bits. In particular,
- it need not honor the `special' bits, so if MODE includes any
- special bits, set them here. */
- if ((mode & ~S_IRWXUGO)
- && chmod (basename_dir, mode))
- {
- error (0, errno, _("cannot change permissions of %s"),
- quote (dir));
- retval = false;
- }
-
- CLEANUP_CWD;
-
- /* If the mode for leading directories didn't include owner "wx"
- privileges, we have to reset their protections to the correct
- value. */
- for (p = leading_dirs; p != NULL; p = p->next)
- {
- *(p->dirname_end) = '\0';
- if (chmod (dir, parent_mode) != 0)
- {
- error (0, errno, _("cannot change permissions of %s"),
- quote (dir));
- retval = false;
- }
- }
- }
- else