- 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));
- retval = false;
- break;
- }
-
- if (re_protect)
- {
- struct ptr_list *new = (struct ptr_list *)
- alloca (sizeof *new);
- new->dirname_end = slash;
- new->next = leading_dirs;
- leading_dirs = new;
- }
- }
- else if (errno == EEXIST || errno == ENOSYS)
- {
- /* A file is already there. Perhaps it is a directory.
- If not, it will be diagnosed later.
-
- The ENOSYS is for Solaris 8 NFS clients, which can
- fail with errno == ENOSYS if mkdir is invoked on an
- NFS mount point. */
- }
- else
- {
- error (0, errno, _("cannot create directory %s"), quote (dir));
- retval = false;
- break;
- }
-
- /* 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
- 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));
- retval = false;
- break;
- }
-
- *slash++ = '/';
-
- /* Avoid unnecessary calls to mkdir 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 (retval)
- {
- if (mkdir (basename_dir, mode) != 0)
- {
- error (0, errno, _("cannot create directory %s"), quote (dir));
- retval = false;
- }
- else
- {
- if (verbose_fmt_string)
- error (0, 0, verbose_fmt_string, quote (dir));
- fixup_permissions_dir = basename_dir;
- }
- }
- }
-
- if (fixup_permissions_dir)
- {
- /* chown must precede chmod because on some systems,
- chown clears the set[ug]id bits for non-superusers,
- resulting in incorrect permissions.
- On System V, users can give away files with chown and then not
- be able to chmod them. So don't give files away. */
-
- if (owner != (uid_t) -1 || group != (gid_t) -1)
- {
- if (chown (fixup_permissions_dir, owner, group) != 0
-#ifdef AFS
- && errno != EPERM
-#endif
- )
- {
- error (0, errno, _("cannot change owner and/or group of %s"),
- quote (full_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 (fixup_permissions_dir, mode) != 0)
- {
- error (0, errno, _("cannot change permissions of %s"),
- quote (full_dir));
- retval = false;
- }
- }
-
- if (do_chdir)
- {
- if (restore_cwd (&cwd) != 0)
- {
- *cwd_errno = errno;
- cwd_problem = true;
- }
- free_cwd (&cwd);
- }