1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #ifndef lint 35 char copyright[] = 36 "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 37 All rights reserved.\n"; 38 #endif /* not lint */ 39 40 #ifndef lint 41 static char sccsid[] = "@(#)mkdir.c 5.7 (Berkeley) 5/31/90"; 42 static char rcsid[] = "$Header: /cvsroot/src/bin/mkdir/mkdir.c,v 1.4 1993/07/20 22:27:08 jtc Exp $"; 43 #endif /* not lint */ 44 45 #include <sys/types.h> 46 #include <sys/stat.h> 47 #include <errno.h> 48 #include <stdio.h> 49 #include <string.h> 50 #include <stdlib.h> 51 52 extern int errno; 53 extern void *setmode(); 54 extern mode_t getmode(); 55 56 main(argc, argv) 57 int argc; 58 char **argv; 59 { 60 int ch, exitval, pflag; 61 void *set; 62 mode_t mode, dir_mode; 63 64 /* default file mode is a=rwx (777) with selected permissions 65 removed in accordance with the file mode creation mask. 66 For intermediate path name components, the mode is the default 67 modified by u+wx so that the subdirectories can always be 68 created. */ 69 mode = 0777 & ~umask(0); 70 dir_mode = mode | S_IWUSR | S_IXUSR; 71 72 pflag = 0; 73 while ((ch = getopt(argc, argv, "pm:")) != EOF) 74 switch(ch) { 75 case 'p': 76 pflag = 1; 77 break; 78 case 'm': 79 if ((set = setmode(optarg)) == NULL) { 80 (void)fprintf(stderr, 81 "mkdir: invalid file mode.\n"); 82 exit(1); 83 } 84 mode = getmode (set, S_IRWXU | S_IRWXG | S_IRWXO); 85 break; 86 case '?': 87 default: 88 usage(); 89 } 90 91 if (!*(argv += optind)) 92 usage(); 93 94 for (exitval = 0; *argv; ++argv) { 95 if (pflag) 96 exitval |= build(*argv, mode, dir_mode); 97 else if (mkdir(*argv, mode) < 0) { 98 (void)fprintf(stderr, "mkdir: %s: %s\n", 99 *argv, strerror(errno)); 100 exitval = 1; 101 } 102 } 103 exit(exitval); 104 } 105 106 /* 107 * build -- create directories. 108 * mode - file mode of terminal directory 109 * dir_mode - file mode of intermediate directories 110 */ 111 build(path, mode, dir_mode) 112 char *path; 113 mode_t mode; 114 mode_t dir_mode; 115 { 116 register char *p; 117 struct stat sb; 118 int ch; 119 120 for (p = path;; ++p) { 121 if (!*p || *p == '/') { 122 ch = *p; 123 *p = '\0'; 124 if (stat(path, &sb)) { 125 if (errno != ENOENT || mkdir(path, (ch) ? dir_mode : mode) < 0) { 126 (void)fprintf(stderr, "mkdir: %s: %s\n", 127 path, strerror(errno)); 128 return(1); 129 } 130 } 131 if (!(*p = ch)) 132 break; 133 } 134 } 135 return(0); 136 } 137 138 usage() 139 { 140 (void)fprintf(stderr, "usage: mkdir [-p] [-m mode] dirname ...\n"); 141 exit(1); 142 } 143