1*41ffc556Sclaudio /* $OpenBSD: mkpath.c,v 1.5 2021/05/17 11:52:10 claudio Exp $ */
260a32ee9Sbenno /*
360a32ee9Sbenno * Copyright (c) 1983, 1992, 1993
460a32ee9Sbenno * The Regents of the University of California. All rights reserved.
560a32ee9Sbenno *
660a32ee9Sbenno * Redistribution and use in source and binary forms, with or without
760a32ee9Sbenno * modification, are permitted provided that the following conditions
860a32ee9Sbenno * are met:
960a32ee9Sbenno * 1. Redistributions of source code must retain the above copyright
1060a32ee9Sbenno * notice, this list of conditions and the following disclaimer.
1160a32ee9Sbenno * 2. Redistributions in binary form must reproduce the above copyright
1260a32ee9Sbenno * notice, this list of conditions and the following disclaimer in the
1360a32ee9Sbenno * documentation and/or other materials provided with the distribution.
1460a32ee9Sbenno * 3. Neither the name of the University nor the names of its contributors
1560a32ee9Sbenno * may be used to endorse or promote products derived from this software
1660a32ee9Sbenno * without specific prior written permission.
1760a32ee9Sbenno *
1860a32ee9Sbenno * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1960a32ee9Sbenno * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2060a32ee9Sbenno * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2160a32ee9Sbenno * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2260a32ee9Sbenno * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2360a32ee9Sbenno * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2460a32ee9Sbenno * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2560a32ee9Sbenno * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2660a32ee9Sbenno * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2760a32ee9Sbenno * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2860a32ee9Sbenno * SUCH DAMAGE.
2960a32ee9Sbenno */
3060a32ee9Sbenno
3160a32ee9Sbenno #include <sys/types.h>
3260a32ee9Sbenno #include <sys/stat.h>
3360a32ee9Sbenno #include <errno.h>
3460a32ee9Sbenno #include <stdint.h>
3560a32ee9Sbenno #include <string.h>
3660a32ee9Sbenno
3760a32ee9Sbenno #include "extern.h"
3860a32ee9Sbenno
3960a32ee9Sbenno /* Code taken directly from mkdir(1).
4060a32ee9Sbenno
4160a32ee9Sbenno * mkpath -- create directories.
4260a32ee9Sbenno * path - path
4360a32ee9Sbenno */
4460a32ee9Sbenno int
mkpath(char * path)45ba617adaSbenno mkpath(char *path)
4660a32ee9Sbenno {
4760a32ee9Sbenno struct stat sb;
4860a32ee9Sbenno char *slash;
49*41ffc556Sclaudio int done;
5060a32ee9Sbenno
5160a32ee9Sbenno slash = path;
5260a32ee9Sbenno
53*41ffc556Sclaudio for (;;) {
5460a32ee9Sbenno slash += strspn(slash, "/");
5560a32ee9Sbenno slash += strcspn(slash, "/");
5660a32ee9Sbenno
5760a32ee9Sbenno done = (*slash == '\0');
5860a32ee9Sbenno *slash = '\0';
5960a32ee9Sbenno
60*41ffc556Sclaudio if (mkdir(path, 0777) != 0) {
61*41ffc556Sclaudio int mkdir_errno = errno;
62*41ffc556Sclaudio
63*41ffc556Sclaudio if (stat(path, &sb) == -1) {
64*41ffc556Sclaudio /* Not there; use mkdir()s errno */
65*41ffc556Sclaudio errno = mkdir_errno;
6660a32ee9Sbenno return (-1);
6760a32ee9Sbenno }
68*41ffc556Sclaudio if (!S_ISDIR(sb.st_mode)) {
69*41ffc556Sclaudio /* Is there, but isn't a directory */
7060a32ee9Sbenno errno = ENOTDIR;
7160a32ee9Sbenno return (-1);
7260a32ee9Sbenno }
73*41ffc556Sclaudio }
74*41ffc556Sclaudio
75*41ffc556Sclaudio if (done)
76*41ffc556Sclaudio break;
7760a32ee9Sbenno
7860a32ee9Sbenno *slash = '/';
7960a32ee9Sbenno }
8060a32ee9Sbenno
8160a32ee9Sbenno return (0);
8260a32ee9Sbenno }
83