xref: /openbsd/usr.bin/rsync/mkpath.c (revision 41ffc556)
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