head 1.39; access; symbols netbsd-10-0-RC6:1.39 netbsd-10-0-RC5:1.39 netbsd-10-0-RC4:1.39 netbsd-10-0-RC3:1.39 netbsd-10-0-RC2:1.39 netbsd-10-0-RC1:1.39 netbsd-10:1.39.0.2 netbsd-10-base:1.39 netbsd-9-3-RELEASE:1.38.46.1 cjep_sun2x-base1:1.38 cjep_sun2x:1.38.0.52 cjep_sun2x-base:1.38 cjep_staticlib_x-base1:1.38 netbsd-9-2-RELEASE:1.38 cjep_staticlib_x:1.38.0.50 cjep_staticlib_x-base:1.38 netbsd-9-1-RELEASE:1.38 phil-wifi-20200421:1.38 phil-wifi-20200411:1.38 is-mlppp:1.38.0.48 is-mlppp-base:1.38 phil-wifi-20200406:1.38 netbsd-8-2-RELEASE:1.38 netbsd-9-0-RELEASE:1.38 netbsd-9-0-RC2:1.38 netbsd-9-0-RC1:1.38 phil-wifi-20191119:1.38 netbsd-9:1.38.0.46 netbsd-9-base:1.38 phil-wifi-20190609:1.38 netbsd-8-1-RELEASE:1.38 netbsd-8-1-RC1:1.38 pgoyette-compat-merge-20190127:1.38 pgoyette-compat-20190127:1.38 pgoyette-compat-20190118:1.38 pgoyette-compat-1226:1.38 pgoyette-compat-1126:1.38 pgoyette-compat-1020:1.38 pgoyette-compat-0930:1.38 pgoyette-compat-0906:1.38 netbsd-7-2-RELEASE:1.38 pgoyette-compat-0728:1.38 netbsd-8-0-RELEASE:1.38 phil-wifi:1.38.0.44 phil-wifi-base:1.38 pgoyette-compat-0625:1.38 netbsd-8-0-RC2:1.38 pgoyette-compat-0521:1.38 pgoyette-compat-0502:1.38 pgoyette-compat-0422:1.38 netbsd-8-0-RC1:1.38 pgoyette-compat-0415:1.38 pgoyette-compat-0407:1.38 pgoyette-compat-0330:1.38 pgoyette-compat-0322:1.38 pgoyette-compat-0315:1.38 netbsd-7-1-2-RELEASE:1.38 pgoyette-compat:1.38.0.42 pgoyette-compat-base:1.38 netbsd-7-1-1-RELEASE:1.38 matt-nb8-mediatek:1.38.0.40 matt-nb8-mediatek-base:1.38 perseant-stdc-iso10646:1.38.0.38 perseant-stdc-iso10646-base:1.38 netbsd-8:1.38.0.36 netbsd-8-base:1.38 prg-localcount2-base3:1.38 prg-localcount2-base2:1.38 prg-localcount2-base1:1.38 prg-localcount2:1.38.0.34 prg-localcount2-base:1.38 pgoyette-localcount-20170426:1.38 bouyer-socketcan-base1:1.38 pgoyette-localcount-20170320:1.38 netbsd-7-1:1.38.0.32 netbsd-7-1-RELEASE:1.38 netbsd-7-1-RC2:1.38 netbsd-7-nhusb-base-20170116:1.38 bouyer-socketcan:1.38.0.30 bouyer-socketcan-base:1.38 pgoyette-localcount-20170107:1.38 netbsd-7-1-RC1:1.38 pgoyette-localcount-20161104:1.38 netbsd-7-0-2-RELEASE:1.38 localcount-20160914:1.38 netbsd-7-nhusb:1.38.0.28 netbsd-7-nhusb-base:1.38 pgoyette-localcount-20160806:1.38 pgoyette-localcount-20160726:1.38 pgoyette-localcount:1.38.0.26 pgoyette-localcount-base:1.38 netbsd-7-0-1-RELEASE:1.38 netbsd-7-0:1.38.0.24 netbsd-7-0-RELEASE:1.38 netbsd-7-0-RC3:1.38 netbsd-7-0-RC2:1.38 netbsd-7-0-RC1:1.38 netbsd-5-2-3-RELEASE:1.37 netbsd-5-1-5-RELEASE:1.37 netbsd-6-0-6-RELEASE:1.38 netbsd-6-1-5-RELEASE:1.38 netbsd-7:1.38.0.22 netbsd-7-base:1.38 yamt-pagecache-base9:1.38 yamt-pagecache-tag8:1.38 netbsd-6-1-4-RELEASE:1.38 netbsd-6-0-5-RELEASE:1.38 tls-earlyentropy:1.38.0.20 tls-earlyentropy-base:1.38 riastradh-xf86-video-intel-2-7-1-pre-2-21-15:1.38 riastradh-drm2-base3:1.38 netbsd-6-1-3-RELEASE:1.38 netbsd-6-0-4-RELEASE:1.38 netbsd-5-2-2-RELEASE:1.37 netbsd-5-1-4-RELEASE:1.37 netbsd-6-1-2-RELEASE:1.38 netbsd-6-0-3-RELEASE:1.38 netbsd-5-2-1-RELEASE:1.37 netbsd-5-1-3-RELEASE:1.37 netbsd-6-1-1-RELEASE:1.38 riastradh-drm2-base2:1.38 riastradh-drm2-base1:1.38 riastradh-drm2:1.38.0.12 riastradh-drm2-base:1.38 netbsd-6-1:1.38.0.18 netbsd-6-0-2-RELEASE:1.38 netbsd-6-1-RELEASE:1.38 khorben-n900:1.38.0.16 netbsd-6-1-RC4:1.38 netbsd-6-1-RC3:1.38 agc-symver:1.38.0.14 agc-symver-base:1.38 netbsd-6-1-RC2:1.38 netbsd-6-1-RC1:1.38 yamt-pagecache-base8:1.38 netbsd-5-2:1.37.0.2 netbsd-6-0-1-RELEASE:1.38 yamt-pagecache-base7:1.38 netbsd-5-2-RELEASE:1.37 netbsd-5-2-RC1:1.37 matt-nb6-plus-nbase:1.38 yamt-pagecache-base6:1.38 netbsd-6-0:1.38.0.10 netbsd-6-0-RELEASE:1.38 netbsd-6-0-RC2:1.38 tls-maxphys:1.38.0.8 tls-maxphys-base:1.38 matt-nb6-plus:1.38.0.6 matt-nb6-plus-base:1.38 netbsd-6-0-RC1:1.38 yamt-pagecache-base5:1.38 yamt-pagecache-base4:1.38 netbsd-6:1.38.0.4 netbsd-6-base:1.38 netbsd-5-1-2-RELEASE:1.37 netbsd-5-1-1-RELEASE:1.37 yamt-pagecache-base3:1.38 yamt-pagecache-base2:1.38 yamt-pagecache:1.38.0.2 yamt-pagecache-base:1.38 cherry-xenmp:1.37.0.18 cherry-xenmp-base:1.37 bouyer-quota2-nbase:1.37 bouyer-quota2:1.37.0.16 bouyer-quota2-base:1.37 matt-mips64-premerge-20101231:1.37 matt-nb5-mips64-premerge-20101231:1.37 matt-nb5-pq3:1.37.0.14 matt-nb5-pq3-base:1.37 netbsd-5-1:1.37.0.12 netbsd-5-1-RELEASE:1.37 netbsd-5-1-RC4:1.37 matt-nb5-mips64-k15:1.37 netbsd-5-1-RC3:1.37 netbsd-5-1-RC2:1.37 netbsd-5-1-RC1:1.37 netbsd-5-0-2-RELEASE:1.37 matt-nb5-mips64-premerge-20091211:1.37 matt-premerge-20091211:1.37 matt-nb5-mips64-u2-k2-k4-k7-k8-k9:1.37 matt-nb4-mips64-k7-u2a-k9b:1.37 matt-nb5-mips64-u1-k1-k5:1.37 matt-nb5-mips64:1.37.0.10 netbsd-5-0-1-RELEASE:1.37 jym-xensuspend-nbase:1.37 netbsd-5-0:1.37.0.8 netbsd-5-0-RELEASE:1.37 netbsd-5-0-RC4:1.37 netbsd-5-0-RC3:1.37 netbsd-5-0-RC2:1.37 jym-xensuspend:1.37.0.6 jym-xensuspend-base:1.37 netbsd-5-0-RC1:1.37 netbsd-5:1.37.0.4 netbsd-5-base:1.37 matt-mips64-base2:1.37 matt-mips64:1.36.0.22 netbsd-4-0-1-RELEASE:1.36 wrstuden-revivesa-base-3:1.37 wrstuden-revivesa-base-2:1.37 wrstuden-fixsa-newbase:1.36 wrstuden-revivesa-base-1:1.36 yamt-pf42-base4:1.36 yamt-pf42-base3:1.36 hpcarm-cleanup-nbase:1.36 yamt-pf42-baseX:1.36 yamt-pf42-base2:1.36 wrstuden-revivesa:1.36.0.20 wrstuden-revivesa-base:1.36 yamt-pf42:1.36.0.18 yamt-pf42-base:1.36 keiichi-mipv6:1.36.0.16 keiichi-mipv6-base:1.36 matt-armv6-nbase:1.36 matt-armv6-prevmlocking:1.36 wrstuden-fixsa-base-1:1.36 netbsd-4-0:1.36.0.14 netbsd-4-0-RELEASE:1.36 cube-autoconf:1.36.0.12 cube-autoconf-base:1.36 netbsd-4-0-RC5:1.36 netbsd-4-0-RC4:1.36 netbsd-4-0-RC3:1.36 netbsd-4-0-RC2:1.36 netbsd-4-0-RC1:1.36 matt-armv6:1.36.0.10 matt-armv6-base:1.36 matt-mips64-base:1.36 hpcarm-cleanup:1.36.0.8 hpcarm-cleanup-base:1.36 netbsd-3-1-1-RELEASE:1.35 netbsd-3-0-3-RELEASE:1.35 wrstuden-fixsa:1.36.0.6 wrstuden-fixsa-base:1.36 abandoned-netbsd-4-base:1.36 abandoned-netbsd-4:1.36.0.2 netbsd-3-1:1.35.0.12 netbsd-3-1-RELEASE:1.35 netbsd-3-0-2-RELEASE:1.35 netbsd-3-1-RC4:1.35 netbsd-3-1-RC3:1.35 netbsd-3-1-RC2:1.35 netbsd-3-1-RC1:1.35 netbsd-4:1.36.0.4 netbsd-4-base:1.36 netbsd-3-0-1-RELEASE:1.35 netbsd-3-0:1.35.0.10 netbsd-3-0-RELEASE:1.35 netbsd-3-0-RC6:1.35 netbsd-3-0-RC5:1.35 netbsd-3-0-RC4:1.35 netbsd-3-0-RC3:1.35 netbsd-3-0-RC2:1.35 netbsd-3-0-RC1:1.35 netbsd-2-0-3-RELEASE:1.35 netbsd-2-1:1.35.0.8 netbsd-2-1-RELEASE:1.35 netbsd-2-1-RC6:1.35 netbsd-2-1-RC5:1.35 netbsd-2-1-RC4:1.35 netbsd-2-1-RC3:1.35 netbsd-2-1-RC2:1.35 netbsd-2-1-RC1:1.35 netbsd-2-0-2-RELEASE:1.35 netbsd-3:1.35.0.6 netbsd-3-base:1.35 netbsd-2-0-1-RELEASE:1.35 netbsd-2:1.35.0.4 netbsd-2-base:1.35 netbsd-2-0-RELEASE:1.35 netbsd-2-0-RC5:1.35 netbsd-2-0-RC4:1.35 netbsd-2-0-RC3:1.35 netbsd-2-0-RC2:1.35 netbsd-2-0-RC1:1.35 netbsd-2-0:1.35.0.2 netbsd-2-0-base:1.35 netbsd-1-6-PATCH002-RELEASE:1.26 netbsd-1-6-PATCH002:1.26 netbsd-1-6-PATCH002-RC4:1.26 netbsd-1-6-PATCH002-RC3:1.26 netbsd-1-6-PATCH002-RC2:1.26 netbsd-1-6-PATCH002-RC1:1.26 netbsd-1-6-PATCH001:1.26 netbsd-1-6-PATCH001-RELEASE:1.26 netbsd-1-6-PATCH001-RC3:1.26 netbsd-1-6-PATCH001-RC2:1.26 netbsd-1-6-PATCH001-RC1:1.26 fvdl_fs64_base:1.27 netbsd-1-6-RELEASE:1.26 netbsd-1-6-RC3:1.26 netbsd-1-6-RC2:1.26 netbsd-1-6-RC1:1.26 netbsd-1-6:1.26.0.2 netbsd-1-6-base:1.26 netbsd-1-5-PATCH003:1.23 netbsd-1-5-PATCH002:1.23 netbsd-1-5-PATCH001:1.23 netbsd-1-5-RELEASE:1.23 netbsd-1-5-BETA2:1.23 netbsd-1-5-BETA:1.23 netbsd-1-4-PATCH003:1.21 netbsd-1-5-ALPHA2:1.23 netbsd-1-5:1.23.0.8 netbsd-1-5-base:1.23 minoura-xpg4dl:1.23.0.6 minoura-xpg4dl-base:1.23 netbsd-1-4-PATCH002:1.21 wrstuden-devbsize-19991221:1.23 wrstuden-devbsize:1.23.0.4 wrstuden-devbsize-base:1.23 comdex-fall-1999:1.23.0.2 comdex-fall-1999-base:1.23 netbsd-1-4-PATCH001:1.21 netbsd-1-4-RELEASE:1.21 netbsd-1-4:1.21.0.2 netbsd-1-4-base:1.21 netbsd-1-3-PATCH003:1.17 netbsd-1-3-PATCH003-CANDIDATE2:1.17 netbsd-1-3-PATCH003-CANDIDATE1:1.17 netbsd-1-3-PATCH003-CANDIDATE0:1.17 netbsd-1-3-PATCH002:1.17 netbsd-1-3-PATCH001:1.17 netbsd-1-3-RELEASE:1.17 netbsd-1-3-BETA:1.17 netbsd-1-3:1.17.0.2 netbsd-1-3-base:1.17 netbsd-1-2-PATCH001:1.14 netbsd-1-2-RELEASE:1.14 netbsd-1-2-BETA:1.14 netbsd-1-2-base:1.14 netbsd-1-2:1.14.0.6 netbsd-1-1-PATCH001:1.14 netbsd-1-1-RELEASE:1.14 netbsd-1-1:1.14.0.2 netbsd-1-1-base:1.14 lite-2:1.1.1.2 netbsd-1-0-PATCH06:1.9 netbsd-1-0-PATCH05:1.9 netbsd-1-0-PATCH04:1.9 netbsd-1-0-PATCH03:1.9 netbsd-1-0-PATCH02:1.9 netbsd-1-0-PATCH1:1.9 netbsd-1-0-PATCH0:1.9 netbsd-1-0-RELEASE:1.9 lite-1:1.1.1.2 CSRG:1.1.1 netbsd-1-0:1.9.0.2 netbsd-1-0-base:1.9 netbsd-0-9-RELEASE:1.3 netbsd-0-9-BETA:1.3 netbsd-0-9-ALPHA2:1.3 netbsd-0-9-ALPHA:1.3 netbsd-0-9:1.3.0.2 netbsd-0-9-base:1.3 netbsd-0-8:1.3 netbsd-alpha-1:1.3 patchkit-0-2-2:1.1.1.1 WFJ-386bsd-01:1.1.1.1 WFJ-920714:1.1.1; locks; strict; comment @ * @; 1.39 date 2021.09.13.22.46.02; author kre; state Exp; branches; next 1.38; commitid 2RphfyuRHgJHAQ8D; 1.38 date 2011.08.29.14.45.28; author joerg; state Exp; branches 1.38.36.1 1.38.44.1 1.38.46.1; next 1.37; 1.37 date 2008.07.20.00.52.40; author lukem; state Exp; branches; next 1.36; 1.36 date 2005.10.01.20.22.29; author christos; state Exp; branches 1.36.20.1; next 1.35; 1.35 date 2004.01.04.16.04.18; author jschauma; state Exp; branches; next 1.34; 1.34 date 2003.09.14.19.20.21; author jschauma; state Exp; branches; next 1.33; 1.33 date 2003.09.11.17.38.12; author christos; state Exp; branches; next 1.32; 1.32 date 2003.08.13.07.34.09; author itojun; state Exp; branches; next 1.31; 1.31 date 2003.08.07.09.05.16; author agc; state Exp; branches; next 1.30; 1.30 date 2003.08.04.22.31.24; author jschauma; state Exp; branches; next 1.29; 1.29 date 2003.03.10.23.33.10; author lukem; state Exp; branches; next 1.28; 1.28 date 2003.03.05.03.58.44; author lukem; state Exp; branches; next 1.27; 1.27 date 2002.11.24.23.40.07; author chs; state Exp; branches; next 1.26; 1.26 date 2002.02.19.06.30.12; author enami; state Exp; branches; next 1.25; 1.25 date 2001.09.16.22.07.14; author wiz; state Exp; branches; next 1.24; 1.24 date 2000.10.10.14.30.40; author enami; state Exp; branches; next 1.23; 1.23 date 99.05.26.15.51.09; author kleink; state Exp; branches; next 1.22; 1.22 date 99.05.25.00.27.45; author tron; state Exp; branches; next 1.21; 1.21 date 98.10.13.20.11.42; author scw; state Exp; branches; next 1.20; 1.20 date 98.10.08.02.14.16; author wsanchez; state Exp; branches; next 1.19; 1.19 date 98.07.28.05.31.25; author mycroft; state Exp; branches; next 1.18; 1.18 date 97.11.05.21.17.35; author cgd; state Exp; branches; next 1.17; 1.17 date 97.07.20.18.55.32; author christos; state Exp; branches; next 1.16; 1.16 date 97.01.09.16.39.08; author tls; state Exp; branches; next 1.15; 1.15 date 96.08.12.22.44.53; author explorer; state Exp; branches; next 1.14; 1.14 date 95.06.25.21.59.21; author mycroft; state Exp; branches; next 1.13; 1.13 date 95.06.25.21.44.38; author mycroft; state Exp; branches; next 1.12; 1.12 date 95.03.21.07.28.54; author cgd; state Exp; branches; next 1.11; 1.11 date 95.03.01.07.52.23; author jtc; state Exp; branches; next 1.10; 1.10 date 94.09.22.09.25.39; author mycroft; state Exp; branches; next 1.9; 1.9 date 94.04.29.00.13.54; author jtc; state Exp; branches; next 1.8; 1.8 date 94.04.28.00.10.30; author jtc; state Exp; branches; next 1.7; 1.7 date 93.12.31.19.34.53; author jtc; state Exp; branches; next 1.6; 1.6 date 93.10.13.18.34.36; author jtc; state Exp; branches; next 1.5; 1.5 date 93.08.01.18.59.23; author mycroft; state Exp; branches; next 1.4; 1.4 date 93.07.20.22.27.08; author jtc; state Exp; branches; next 1.3; 1.3 date 93.03.23.00.26.15; author cgd; state Exp; branches; next 1.2; 1.2 date 93.03.22.08.04.00; author cgd; state Exp; branches; next 1.1; 1.1 date 93.03.21.09.45.37; author cgd; state Exp; branches 1.1.1.1; next ; 1.38.36.1 date 2021.09.23.10.04.53; author martin; state Exp; branches; next ; commitid J0w7V4N33hnE34aD; 1.38.44.1 date 2020.04.21.18.41.05; author martin; state dead; branches; next 1.38.44.2; commitid 86tA4aEmdr3VCh5C; 1.38.44.2 date 2020.04.21.19.37.33; author martin; state Exp; branches; next ; commitid x6IB64bYH9UmWh5C; 1.38.46.1 date 2021.09.23.10.09.20; author martin; state Exp; branches; next ; commitid NZp1ZxyMs05b54aD; 1.36.20.1 date 2008.09.18.04.27.41; author wrstuden; state Exp; branches; next ; 1.1.1.1 date 93.03.21.09.45.37; author cgd; state Exp; branches; next 1.1.1.2; 1.1.1.2 date 94.09.22.03.05.22; author mycroft; state Exp; branches; next ; desc @@ 1.39 log @PR bin/56398 The final component of both a/b/c and a/b/c/ is "c", so that's the one to which the -m arg applies. @ text @/* $NetBSD: mkdir.c,v 1.38 2011/08/29 14:45:28 joerg Exp $ */ /* * Copyright (c) 1983, 1992, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #ifndef lint __COPYRIGHT("@@(#) Copyright (c) 1983, 1992, 1993\ The Regents of the University of California. All rights reserved."); #endif /* not lint */ #ifndef lint #if 0 static char sccsid[] = "@@(#)mkdir.c 8.2 (Berkeley) 1/25/94"; #else __RCSID("$NetBSD: mkdir.c,v 1.38 2011/08/29 14:45:28 joerg Exp $"); #endif #endif /* not lint */ #include #include #include #include #include #include #include #include #include #include static int mkpath(char *, mode_t, mode_t); __dead static void usage(void); int main(int argc, char *argv[]) { int ch, exitval, pflag; void *set; mode_t mode, dir_mode; setprogname(argv[0]); (void)setlocale(LC_ALL, ""); /* * The default file mode is a=rwx (0777) with selected permissions * removed in accordance with the file mode creation mask. For * intermediate path name components, the mode is the default modified * by u+wx so that the subdirectories can always be created. */ mode = (S_IRWXU | S_IRWXG | S_IRWXO) & ~umask(0); dir_mode = mode | S_IWUSR | S_IXUSR; pflag = 0; while ((ch = getopt(argc, argv, "m:p")) != -1) switch (ch) { case 'p': pflag = 1; break; case 'm': if ((set = setmode(optarg)) == NULL) { err(EXIT_FAILURE, "Cannot set file mode `%s'", optarg); /* NOTREACHED */ } mode = getmode(set, S_IRWXU | S_IRWXG | S_IRWXO); free(set); break; case '?': default: usage(); /* NOTREACHED */ } argc -= optind; argv += optind; if (*argv == NULL) { usage(); /* NOTREACHED */ } for (exitval = EXIT_SUCCESS; *argv != NULL; ++argv) { #ifdef notdef char *slash; /* Kernel takes care of this */ /* Remove trailing slashes, per POSIX. */ slash = strrchr(*argv, '\0'); while (--slash > *argv && *slash == '/') *slash = '\0'; #endif if (pflag) { if (mkpath(*argv, mode, dir_mode) < 0) exitval = EXIT_FAILURE; } else { if (mkdir(*argv, mode) < 0) { warn("%s", *argv); exitval = EXIT_FAILURE; } else { /* * The mkdir() and umask() calls both honor * only the file permission bits, so if you try * to set a mode including the sticky, setuid, * setgid bits you lose them. So chmod(). */ if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) != 0 && chmod(*argv, mode) == -1) { warn("%s", *argv); exitval = EXIT_FAILURE; } } } } exit(exitval); /* NOTREACHED */ } /* * mkpath -- create directories. * path - path * mode - file mode of terminal directory * dir_mode - file mode of intermediate directories */ static int mkpath(char *path, mode_t mode, mode_t dir_mode) { struct stat sb; char *slash; int done, rv; done = 0; slash = path; for (;;) { slash += strspn(slash, "/"); slash += strcspn(slash, "/"); done = (*(slash + strspn(slash, "/")) == '\0'); *slash = '\0'; rv = mkdir(path, done ? mode : dir_mode); if (rv < 0) { /* * Can't create; path exists or no perms. * stat() path to determine what's there now. */ int sverrno; sverrno = errno; if (stat(path, &sb) < 0) { /* Not there; use mkdir()s error */ errno = sverrno; warn("%s", path); return -1; } if (!S_ISDIR(sb.st_mode)) { /* Is there, but isn't a directory */ errno = ENOTDIR; warn("%s", path); return -1; } } else if (done) { /* * Created ok, and this is the last element */ /* * The mkdir() and umask() calls both honor only the * file permission bits, so if you try to set a mode * including the sticky, setuid, setgid bits you lose * them. So chmod(). */ if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) != 0 && chmod(path, mode) == -1) { warn("%s", path); return -1; } } if (done) { break; } *slash = '/'; } return 0; } static void usage(void) { (void)fprintf(stderr, "usage: %s [-p] [-m mode] dirname ...\n", getprogname()); exit(EXIT_FAILURE); /* NOTREACHED */ } @ 1.38 log @static + __dead @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.37 2008/07/20 00:52:40 lukem Exp $ */ d42 1 a42 1 __RCSID("$NetBSD: mkdir.c,v 1.37 2008/07/20 00:52:40 lukem Exp $"); d165 1 a165 1 done = (*slash == '\0'); @ 1.38.46.1 log @Pull up following revision(s) (requested by kre in ticket #1347): bin/mkdir/mkdir.c: revision 1.39 PR bin/56398 The final component of both a/b/c and a/b/c/ is "c", so that's the one to which the -m arg applies. @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.38 2011/08/29 14:45:28 joerg Exp $ */ d42 1 a42 1 __RCSID("$NetBSD: mkdir.c,v 1.38 2011/08/29 14:45:28 joerg Exp $"); d165 1 a165 1 done = (*(slash + strspn(slash, "/")) == '\0'); @ 1.38.36.1 log @Pull up following revision(s) (requested by kre in ticket #1697): bin/mkdir/mkdir.c: revision 1.39 PR bin/56398 The final component of both a/b/c and a/b/c/ is "c", so that's the one to which the -m arg applies. @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.38 2011/08/29 14:45:28 joerg Exp $ */ d42 1 a42 1 __RCSID("$NetBSD: mkdir.c,v 1.38 2011/08/29 14:45:28 joerg Exp $"); d165 1 a165 1 done = (*(slash + strspn(slash, "/")) == '\0'); @ 1.38.44.1 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.38 2011/08/29 14:45:28 joerg Exp $ */ d42 1 a42 1 __RCSID("$NetBSD: mkdir.c,v 1.38 2011/08/29 14:45:28 joerg Exp $"); @ 1.38.44.2 log @Ooops, restore accidently removed files from merge mishap @ text @@ 1.37 log @Remove the \n and tabs from the __COPYRIGHT() strings. @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.36 2005/10/01 20:22:29 christos Exp $ */ d42 1 a42 1 __RCSID("$NetBSD: mkdir.c,v 1.36 2005/10/01 20:22:29 christos Exp $"); d58 2 a59 3 int mkpath(char *, mode_t, mode_t); void usage(void); int main(int, char *[]); d151 1 a151 1 int d215 1 a215 1 void @ 1.36 log @Fix setmode error handling. @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.35 2004/01/04 16:04:18 jschauma Exp $ */ d34 2 a35 2 __COPYRIGHT("@@(#) Copyright (c) 1983, 1992, 1993\n\ The Regents of the University of California. All rights reserved.\n"); d42 1 a42 1 __RCSID("$NetBSD: mkdir.c,v 1.35 2004/01/04 16:04:18 jschauma Exp $"); @ 1.36.20.1 log @Sync with wrstuden-revivesa-base-2. @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.36 2005/10/01 20:22:29 christos Exp $ */ d34 2 a35 2 __COPYRIGHT("@@(#) Copyright (c) 1983, 1992, 1993\ The Regents of the University of California. All rights reserved."); d42 1 a42 1 __RCSID("$NetBSD: mkdir.c,v 1.36 2005/10/01 20:22:29 christos Exp $"); @ 1.35 log @remove unused code left from printescaped() backput as pointed out by Jeff Ito in PR bin/23969 and PR bin/23970. @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.34 2003/09/14 19:20:21 jschauma Exp $ */ d42 1 a42 1 __RCSID("$NetBSD: mkdir.c,v 1.34 2003/09/14 19:20:21 jschauma Exp $"); d89 2 a90 2 errx(EXIT_FAILURE, "invalid file mode: %s", optarg); @ 1.34 log @Following private discussion with kleink@@ and hubertf@@ and public discussion on tech-userlevel@@, back out printescaped() functionality. kleink: ``We sell rope.'' @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.33 2003/09/11 17:38:12 christos Exp $ */ d42 1 a42 1 __RCSID("$NetBSD: mkdir.c,v 1.33 2003/09/11 17:38:12 christos Exp $"); a56 3 #include int stdout_ok; /* stdout connected to a terminal */ a108 2 stdout_ok = isatty(STDOUT_FILENO); @ 1.33 log @Comment out unneeded code now that the kernel has been fixed to ignore trailing slashes. @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.32 2003/08/13 07:34:09 itojun Exp $ */ d42 1 a42 1 __RCSID("$NetBSD: mkdir.c,v 1.32 2003/08/13 07:34:09 itojun Exp $"); a63 1 char *printescaped(const char *); d93 1 a93 1 printescaped(optarg)); d141 1 a141 4 char *fn; fn = printescaped(*argv); warn("%s", fn); free(fn); d161 1 a161 1 char *slash, *fn; a165 1 fn = printescaped(path); d186 1 a186 2 warn("%s", fn); free(fn); d192 1 a192 2 warn("%s", fn); free(fn); d207 1 a207 2 warn("%s", fn); free(fn); a217 1 free(fn); a228 24 } char * printescaped(const char *src) { size_t len; char *retval; len = strlen(src); if (len != 0 && SIZE_T_MAX/len <= 4) { errx(EXIT_FAILURE, "%s: name too long", src); /* NOTREACHED */ } retval = (char *)malloc(4*len+1); if (retval != NULL) { if (stdout_ok) (void)strvis(retval, src, VIS_NL | VIS_CSTYLE); else (void)strlcpy(retval, src, 4 * len + 1); return retval; } else errx(EXIT_FAILURE, "out of memory!"); /* NOTREACHED */ @ 1.32 log @use bounded string op @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.31 2003/08/07 09:05:16 agc Exp $ */ d42 1 a42 1 __RCSID("$NetBSD: mkdir.c,v 1.31 2003/08/07 09:05:16 agc Exp $"); d116 1 d119 1 d124 1 @ 1.31 log @Move UCB-licensed code from 4-clause to 3-clause licence. Patches provided by Joel Baker in PR 22249, verified by myself. @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.30 2003/08/04 22:31:24 jschauma Exp $ */ d42 1 a42 1 __RCSID("$NetBSD: mkdir.c,v 1.30 2003/08/04 22:31:24 jschauma Exp $"); d254 1 a254 1 (void)strcpy(retval, src); @ 1.30 log @As discusses a little while back on tech-userlevel: If stdout is a tty, use vis(3) to print any filenames to prevent garbage from being printed if the filename contains control- or other non-printable characters. While here, sprinkle some EXIT_FAILURE and NOTREACHED where appropriate. @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.29 2003/03/10 23:33:10 lukem Exp $ */ d15 1 a15 5 * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors d42 1 a42 1 __RCSID("$NetBSD: mkdir.c,v 1.29 2003/03/10 23:33:10 lukem Exp $"); @ 1.29 log @Fix typo in mkpath()'s test before chmod(). Noted in [bin/20652] by Anthony Mallet. @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.28 2003/03/05 03:58:44 lukem Exp $ */ d46 1 a46 1 __RCSID("$NetBSD: mkdir.c,v 1.28 2003/03/05 03:58:44 lukem Exp $"); d50 2 a52 1 #include d61 3 d68 1 d96 5 a100 2 if ((set = setmode(optarg)) == NULL) errx(1, "invalid file mode: %s", optarg); d107 1 d112 1 a112 1 if (*argv == NULL) d114 4 d143 4 a146 1 warn("%s", *argv); d166 1 a166 1 char *slash; d171 1 d192 2 a193 1 warn("%s", path); d199 2 a200 1 warn("%s", path); d215 2 a216 1 warn("%s", path); d226 2 d239 24 @ 1.28 log @Rework -p support again; - If mkdir() fails on a component (no matter what the error is), stat() the result. If the stat() fails, print the error mkdir() generated. Otherwise, if the result is not a directory, explicitly fail with ENOTDIR. - Move the chmod() of last element to be done only if the mkdir() succeeded (i.e, it wasn't an existing directory) Fixes problem introduced in previous commit where "mkdir -p existing" on a read-only file system would incorrectly return a non zero exit code, whilst retaining the race-condition fix of the previous commit. Thanks to simonb@@ for sanity checking my fix versus the standards. @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.27 2002/11/24 23:40:07 chs Exp $ */ d46 1 a46 1 __RCSID("$NetBSD: mkdir.c,v 1.27 2002/11/24 23:40:07 chs Exp $"); d194 1 a194 1 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXU)) != 0 && @ 1.27 log @in mkpath(), don't try to stat() the to-be-created directory beforehand, just try to create it and interpret any error appropriately. this fixes a problem where multiple "mkdir -p" processes can race, with the loser returning a spurious error. @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.26 2002/02/19 06:30:12 enami Exp $ */ d46 1 a46 1 __RCSID("$NetBSD: mkdir.c,v 1.26 2002/02/19 06:30:12 enami Exp $"); d164 35 a198 3 if (rv < 0 && errno != EEXIST) { warn("%s", path); return (-1); d200 1 d206 1 a206 31 /* * Check for the final component being something other than * a directory. */ if (rv < 0) { if (stat(path, &sb) < 0) { warn("stat %s failed", path); return (-1); } if (!S_ISDIR(sb.st_mode)) { errno = ENOTDIR; warn("%s", path); return (-1); } } /* * The mkdir() and umask() calls both honor only the * file permission bits, so if you try to set a mode * including the sticky, setuid, setgid bits you lose * them. So chmod(). */ if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXU)) != 0 && chmod(path, mode) == -1) { warn("%s", path); return (-1); } return (0); @ 1.26 log @Cosmetic changes. @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.25 2001/09/16 22:07:14 wiz Exp $ */ d46 1 a46 1 __RCSID("$NetBSD: mkdir.c,v 1.25 2001/09/16 22:07:14 wiz Exp $"); d151 1 a151 1 int done; d156 1 a156 1 while (!done) { d163 3 a165 19 if (stat(path, &sb)) { if (errno != ENOENT || mkdir(path, done ? mode : dir_mode)) { warn("%s", path); return (-1); } /* * The mkdir() and umask() calls both honor only the * file permission bits, so if you try to set a mode * including the sticky, setuid, setgid bits you lose * them. So chmod(). */ if (done && (mode & ~(S_IRWXU|S_IRWXG|S_IRWXU)) != 0 && chmod(path, mode) == -1) { warn("%s", path); return (-1); } } else if (!S_ISDIR(sb.st_mode)) { warnx("%s: %s", path, strerror(ENOTDIR)); d168 10 d179 10 a188 1 *slash = '/'; d191 12 @ 1.25 log @ANSIfy, KNF, use [gs]etprogname. By Petri Koistinen. @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.24 2000/10/10 14:30:40 enami Exp $ */ d46 1 a46 1 __RCSID("$NetBSD: mkdir.c,v 1.24 2000/10/10 14:30:40 enami Exp $"); d86 1 a86 1 switch(ch) { d105 1 a105 1 d141 1 a141 1 * mkpath -- create directories. d164 2 a165 2 if (errno != ENOENT || mkdir(path, done ? mode : dir_mode)) { d174 1 a174 1 */ d184 1 a184 1 d194 3 a196 1 (void)fprintf(stderr, "usage: %s [-p] [-m mode] dirname ...\n", getprogname()); @ 1.24 log @- The type of return value of setmode is a void * and getmode takes it, rather than mode_t *. - Free the storage allocated by setmode unless it is obvious that program exits immediately. @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.23 1999/05/26 15:51:09 kleink Exp $ */ d46 1 a46 1 __RCSID("$NetBSD: mkdir.c,v 1.23 1999/05/26 15:51:09 kleink Exp $"); d61 3 a63 3 int mkpath __P((char *, mode_t, mode_t)); void usage __P((void)); int main __P((int, char *[])); d66 1 a66 3 main(argc, argv) int argc; char *argv[]; d72 1 d147 1 a147 4 mkpath(path, mode, dir_mode) char *path; mode_t mode; mode_t dir_mode; d151 1 a151 1 int done = 0; d153 1 d192 1 a192 1 usage() d194 1 a194 2 (void)fprintf(stderr, "usage: mkdir [-p] [-m mode] dirname ...\n"); @ 1.23 log @Change previous to use symbolic names for file modes. Also, clean up some whitespace lossage and use EXIT_{SUCCESS,FAILURE}. @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.22 1999/05/25 00:27:45 tron Exp $ */ d46 1 a46 1 __RCSID("$NetBSD: mkdir.c,v 1.22 1999/05/25 00:27:45 tron Exp $"); d71 1 a71 1 mode_t *set; d95 1 @ 1.22 log @Only call chmod(2) if we create a directory with a mode which isn't accepted by mkdir(2). @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.21 1998/10/13 20:11:42 scw Exp $ */ d46 1 a46 1 __RCSID("$NetBSD: mkdir.c,v 1.21 1998/10/13 20:11:42 scw Exp $"); d82 1 a82 1 mode = 0777 & ~umask(0); d106 1 a106 1 for (exitval = 0; *argv != NULL; ++argv) { d116 1 a116 1 exitval = 1; d120 1 a120 1 exitval = 1; d124 2 a125 2 * only the low nine bits, so if you try to * set a mode including the sticky, setuid, d128 2 a129 1 if (mode > 0777 && chmod(*argv, mode) == -1) { d131 1 a131 1 exitval = 1; d171 5 a175 4 /* * The mkdir() and umask() calls both honor only the low * nine bits, so if you try to set a mode including the * sticky, setuid, setgid bits you lose them. So chmod(). d177 1 a177 1 if (done && mode > 0777 && d179 3 a181 3 warn("%s", path); return (-1); } d183 1 a183 1 warnx("%s: %s", path, strerror(ENOTDIR)); d198 1 a198 1 exit(1); @ 1.21 log @Insert a missing 'else' which caused mknod(2) to still be called even if mkdir(2) failed. At best this caused two (different) error messages to be printed. At worst, it changed the mode of an existing file/directory. @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.20 1998/10/08 02:14:16 wsanchez Exp $ */ d46 1 a46 1 __RCSID("$NetBSD: mkdir.c,v 1.20 1998/10/08 02:14:16 wsanchez Exp $"); d128 1 a128 1 if (chmod(*argv, mode) == -1) { d175 2 a176 1 if (chmod(path, done ? mode : dir_mode) == -1) { @ 1.20 log @umask()/mkdir() system calls will not set the setuid bit; the kernel intentionally discards the high bits, so "mkdir -m 1777 foo" won't set the sticky bit. So call chmod() on the directory. @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.19 1998/07/28 05:31:25 mycroft Exp $ */ d46 1 a46 1 __RCSID("$NetBSD: mkdir.c,v 1.19 1998/07/28 05:31:25 mycroft Exp $"); d121 11 a132 9 /* * The mkdir() and umask() calls both honor only the low * nine bits, so if you try to set a mode including the * sticky, setuid, setgid bits you lose them. So chmod(). */ if (chmod(*argv, mode) == -1) { warn("%s", *argv); exitval = 1; } @ 1.19 log @Delint. @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.18 1997/11/05 21:17:35 cgd Exp $ */ d46 1 a46 1 __RCSID("$NetBSD: mkdir.c,v 1.18 1997/11/05 21:17:35 cgd Exp $"); d122 9 d168 9 @ 1.18 log @lint @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.17 1997/07/20 18:55:32 christos Exp $ */ d46 1 a46 1 __RCSID("$NetBSD: mkdir.c,v 1.17 1997/07/20 18:55:32 christos Exp $"); d176 1 @ 1.17 log @Fix compiler warnings Add WARNS=1 @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.16 1997/01/09 16:39:08 tls Exp $ */ d46 1 a46 1 __RCSID("$NetBSD$"); d74 1 a74 1 setlocale(LC_ALL, ""); d125 1 @ 1.16 log @kill use of register @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.15 1996/08/12 22:44:53 explorer Exp $ */ d36 1 d38 2 a39 3 static char copyright[] = "@@(#) Copyright (c) 1983, 1992, 1993\n\ The Regents of the University of California. All rights reserved.\n"; d46 1 a46 1 static char rcsid[] = "$NetBSD: mkdir.c,v 1.15 1996/08/12 22:44:53 explorer Exp $"; d63 1 @ 1.15 log @Fix mkdir -p to not ignore terminal directory mode specified. Closes pr bin/2686. @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.14 1995/06/25 21:59:21 mycroft Exp $ */ d46 1 a46 1 static char rcsid[] = "$NetBSD: mkdir.c,v 1.14 1995/06/25 21:59:21 mycroft Exp $"; d106 1 a106 1 register char *slash; d139 1 a139 1 register char *slash; @ 1.14 log @Style and format police. @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.13 1995/06/25 21:44:38 mycroft Exp $ */ d46 1 a46 1 static char rcsid[] = "$NetBSD: mkdir.c,v 1.13 1995/06/25 21:44:38 mycroft Exp $"; d152 2 a153 1 if (errno != ENOENT || mkdir(path, dir_mode)) { @ 1.13 log @Don't complain if a directory already exists. From Greg Hudson, but slightly edited. @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.12 1995/03/21 07:28:54 cgd Exp $ */ d37 1 a37 1 char copyright[] = d46 1 a46 1 static char rcsid[] = "$NetBSD: mkdir.c,v 1.12 1995/03/21 07:28:54 cgd Exp $"; d70 1 a70 1 void *set; d75 6 a80 5 /* default file mode is a=rwx (777) with selected permissions removed in accordance with the file mode creation mask. For intermediate path name components, the mode is the default modified by u+wx so that the subdirectories can always be created. */ d85 1 a85 1 while ((ch = getopt(argc, argv, "pm:")) != -1) d91 3 a93 5 if ((set = setmode(optarg)) == NULL) { errx(1, "invalid file mode."); /* NOTREACHED */ } mode = getmode (set, S_IRWXU | S_IRWXG | S_IRWXO); d99 2 d102 1 a102 1 if (!*(argv += optind)) d105 1 a105 1 for (exitval = 0; *argv; ++argv) { d108 1 a108 1 /* delete trailing slashes */ d114 7 a120 4 exitval |= mkpath(*argv, mode, dir_mode); } else if (mkdir(*argv, mode) < 0) { warn("%s", *argv); exitval = 1; d154 1 a154 1 return 1; d158 1 a158 1 return 1; d170 1 d172 1 a172 1 exit (1); @ 1.12 log @clean up slightly; id tags, alphabetization, prototypes, etc. @ text @d1 1 a1 1 /* $NetBSD: mkdir.c,v 1.11 1995/03/01 07:52:23 jtc Exp $ */ d46 1 a46 1 static char rcsid[] = "$NetBSD: mkdir.c,v 1.11 1995/03/01 07:52:23 jtc Exp $"; d136 1 a137 1 /* skip leading slashes */ a138 2 while (*slash == '/') slash++; d140 5 a144 1 while ((slash = strchr(slash, '/')) != NULL) { d157 1 a157 9 /* skip multiple slashes */ *slash++ = '/'; while (*slash == '/') slash++; } if (mkdir (path, mode)) { warn("%s", path); return 1; d160 1 a160 1 return(0); @ 1.11 log @Revert to code before it was merged with 4.4lite. Updated to conform to new NetBSD RCS ID conventions. @ text @d1 1 a1 1 /* $NetBSD: $ */ d4 2 a5 2 * Copyright (c) 1983 Regents of the University of California. * All rights reserved. d38 2 a39 2 "@@(#) Copyright (c) 1983 Regents of the University of California.\n\ All rights reserved.\n"; d44 3 a46 1 static char sccsid[] = "@@(#)mkdir.c 5.7 (Berkeley) 5/31/90"; a47 1 static char rcsid[] = "$NetBSD: $"; d50 6 a58 4 #include #include #include #include a59 1 #include d61 4 d67 1 a67 1 char **argv; d128 1 d169 1 d173 1 a173 1 exit(1); @ 1.10 log @Merge 4.4-Lite version. @ text @d1 2 d4 2 a5 2 * Copyright (c) 1983, 1992, 1993 * The Regents of the University of California. All rights reserved. d37 3 a39 3 static char copyright[] = "@@(#) Copyright (c) 1983, 1992, 1993\n\ The Regents of the University of California. All rights reserved.\n"; d43 4 a46 2 /*static char sccsid[] = "from: @@(#)mkdir.c 8.2 (Berkeley) 1/25/94";*/ static char *rcsid = "$Id: $"; a48 6 #include #include #include #include #include d52 4 d57 1 a58 4 int build __P((char *)); void usage __P((void)); int d61 1 a61 1 char *argv[]; d63 3 a65 3 int ch, exitval, omode, pflag; mode_t *set; char *ep, *mode; d69 8 d78 1 a78 2 mode = NULL; while ((ch = getopt(argc, argv, "m:p")) != -1) d84 5 a88 1 mode = optarg; d95 1 a95 3 argc -= optind; argv += optind; if (argv[0] == NULL) d97 12 a108 27 if (mode == NULL) { omode = S_IRWXU | S_IRWXG | S_IRWXO; } else if (*mode >= '0' && *mode <= '7') { omode = (int)strtol(mode, &ep, 8); if (omode < 0 || *ep) errx(1, "invalid file mode: %s", mode); } else { if ((set = setmode(mode)) == NULL) errx(1, "invalid file mode: %s", mode); omode = getmode(set, S_IRWXU | S_IRWXG | S_IRWXO); } for (exitval = 0; *argv != NULL; ++argv) { char *p; /* Remove trailing slashes, per POSIX. */ p = *argv + strlen(*argv); while (--p > *argv && *p == '/') ; *++p = '\0'; if (pflag && build(*argv)) { exitval = 1; continue; } if (mkdir(*argv, omode) < 0) { d116 7 a122 2 int build(path) d124 2 d128 10 a137 31 mode_t numask, oumask; int first; char *p; p = path; while (p[0] == '/') /* Skip leading '/'. */ ++p; for (first = 1;; ++p) { if (p[0] == '\0') break; if (p[0] != '/') continue; *p = '\0'; if (first) { /* * POSIX 1003.2: * For each dir operand that does not name an existing * directory, effects equivalent to those cased by the * following command shall occcur: * * mkdir -p -m $(umask -S),u+wx $(dirname dir) && * mkdir [-m mode] dir * * We change the user's umask and then restore it, * instead of doing chmod's. */ oumask = umask(0); numask = oumask & ~(S_IWUSR | S_IXUSR); (void)umask(numask); first = 0; } d139 1 a139 2 if (errno != ENOENT || mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO) < 0) { d141 1 a141 1 return (1); d143 3 d147 10 a156 3 *p = '/'; while (p[1] == '/') /* Skip '/'s. */ ++p; d158 2 a159 3 if (!first) (void)umask(oumask); return (0); a161 1 void d164 2 a165 2 (void)fprintf(stderr, "usage: mkdir [-p] [-m mode] directory ...\n"); exit (1); @ 1.9 log @Strip trailing slashes, to make "mkdir -p" work as specified by POSIX.2. @ text @d2 2 a3 2 * Copyright (c) 1983 Regents of the University of California. * All rights reserved. d35 3 a37 3 char copyright[] = "@@(#) Copyright (c) 1983 Regents of the University of California.\n\ All rights reserved.\n"; d41 2 a42 2 /*static char sccsid[] = "from: @@(#)mkdir.c 5.7 (Berkeley) 5/31/90";*/ static char rcsid[] = "$Id: mkdir.c,v 1.8 1994/04/28 00:10:30 jtc Exp $"; d45 6 a53 4 #include #include #include #include a54 1 #include d56 4 d62 1 a62 1 char **argv; d64 3 a66 3 int ch, exitval, pflag; void *set; mode_t mode, dir_mode; a69 8 /* default file mode is a=rwx (777) with selected permissions removed in accordance with the file mode creation mask. For intermediate path name components, the mode is the default modified by u+wx so that the subdirectories can always be created. */ mode = 0777 & ~umask(0); dir_mode = mode | S_IWUSR | S_IXUSR; d71 2 a72 1 while ((ch = getopt(argc, argv, "pm:")) != -1) d78 1 a78 5 if ((set = setmode(optarg)) == NULL) { errx(1, "invalid file mode."); /* NOTREACHED */ } mode = getmode (set, S_IRWXU | S_IRWXG | S_IRWXO); d85 3 a87 1 if (!*(argv += optind)) d89 27 a115 12 for (exitval = 0; *argv; ++argv) { register char *slash; /* delete trailing slashes */ slash = strrchr(*argv, '\0'); while (--slash > *argv && *slash == '/') *slash = '\0'; if (pflag) { exitval |= mkpath(*argv, mode, dir_mode); } else if (mkdir(*argv, mode) < 0) { d123 2 a124 7 /* * mkpath -- create directories. * path - path * mode - file mode of terminal directory * dir_mode - file mode of intermediate directories */ mkpath(path, mode, dir_mode) a125 2 mode_t mode; mode_t dir_mode; d128 31 a158 10 register char *slash; /* skip leading slashes */ slash = path; while (*slash == '/') slash++; while ((slash = strchr(slash, '/')) != NULL) { *slash = '\0'; d160 2 a161 1 if (errno != ENOENT || mkdir(path, dir_mode)) { d163 1 a163 1 return 1; a164 3 } else if (!S_ISDIR(sb.st_mode)) { warnx("%s: %s", path, strerror(ENOTDIR)); return 1; d166 3 a168 5 /* skip multiple slashes */ *slash++ = '/'; while (*slash == '/') slash++; d170 3 a172 7 if (mkdir (path, mode)) { warn("%s", path); return 1; } return(0); d175 1 d178 2 a179 2 (void)fprintf(stderr, "usage: mkdir [-p] [-m mode] dirname ...\n"); exit(1); @ 1.8 log @simplify recursive directory create (mkdir -p) code @ text @d42 1 a42 1 static char rcsid[] = "$Id: mkdir.c,v 1.7 1993/12/31 19:34:53 jtc Exp $"; d95 7 @ 1.7 log @Localization changes. Updated to use standard error message routines. @ text @d42 1 a42 1 static char rcsid[] = "$Id: mkdir.c,v 1.6 1993/10/13 18:34:36 jtc Exp $"; d95 3 a97 3 if (pflag) exitval |= build(*argv, mode, dir_mode); else if (mkdir(*argv, mode) < 0) { d106 2 a107 1 * build -- create directories. d111 1 a111 1 build(path, mode, dir_mode) a115 1 register char *p; d117 1 a117 1 int ch; d119 12 a130 9 for (p = path;; ++p) { if (!*p || *p == '/') { ch = *p; *p = '\0'; if (stat(path, &sb)) { if (errno != ENOENT || mkdir(path, (ch) ? dir_mode : mode) < 0) { warn("%s", path); return(1); } d132 3 a134 2 if (!(*p = ch)) break; d136 5 d142 6 @ 1.6 log @#include , so getopt(), optarg, opterr, optind, and optopt declarations can be removed from . @ text @d42 1 a42 1 static char rcsid[] = "$Id: mkdir.c,v 1.5 1993/08/01 18:59:23 mycroft Exp $"; d46 1 d48 1 a48 1 #include d53 1 d63 2 d74 1 a74 1 while ((ch = getopt(argc, argv, "pm:")) != EOF) d81 2 a82 3 (void)fprintf(stderr, "mkdir: invalid file mode.\n"); exit(1); d98 1 a98 2 (void)fprintf(stderr, "mkdir: %s: %s\n", *argv, strerror(errno)); d125 1 a125 2 (void)fprintf(stderr, "mkdir: %s: %s\n", path, strerror(errno)); @ 1.5 log @Add RCS identifiers. @ text @d42 1 a42 1 static char rcsid[] = "$Id: $"; a44 3 #include #include #include d48 4 a51 4 extern int errno; extern void *setmode(); extern mode_t getmode(); @ 1.4 log @Make Posix 1003.2 (D11.2) compliant by adding -m (mode) option. @ text @d41 2 a42 2 static char sccsid[] = "@@(#)mkdir.c 5.7 (Berkeley) 5/31/90"; static char rcsid[] = "$Header: /b/source/CVS/src/bin/mkdir/mkdir.c,v 1.3 1993/03/23 00:26:15 cgd Exp $"; @ 1.3 log @changed "Id" to "Header" for rcsids @ text @d42 1 a42 1 static char rcsid[] = "$Header: mkdir.c,v 1.2 93/03/22 08:08:22 cgd Exp $"; d50 1 d53 2 a59 1 extern int optind; d61 2 d64 8 d73 1 a73 1 while ((ch = getopt(argc, argv, "p")) != EOF) d78 8 d93 2 a94 2 for (exitval = 0; *argv; ++argv) d96 2 a97 2 exitval |= build(*argv); else if (mkdir(*argv, 0777) < 0) { d102 1 d106 6 a111 1 build(path) d113 2 d118 1 a118 1 int create, ch; d120 1 a120 1 for (create = 0, p = path;; ++p) d125 1 a125 1 if (errno != ENOENT || mkdir(path, 0777) < 0) { a129 1 create = 1; a133 4 if (!create) { (void)fprintf(stderr, "mkdir: %s: %s\n", path, strerror(EEXIST)); return(1); d140 1 a140 1 (void)fprintf(stderr, "usage: mkdir [-p] dirname ...\n"); @ 1.2 log @added rcs ids to all files @ text @d42 1 a42 1 static char rcsid[] = "$Id: mkdir.c,v 1.2 93/03/21 22:12:42 cgd Exp $"; @ 1.1 log @Initial revision @ text @d42 1 @ 1.1.1.1 log @initial import of 386bsd-0.1 sources @ text @@ 1.1.1.2 log @Import original 4.4-Lite version. @ text @d2 2 a3 2 * Copyright (c) 1983, 1992, 1993 * The Regents of the University of California. All rights reserved. d35 3 a37 3 static char copyright[] = "@@(#) Copyright (c) 1983, 1992, 1993\n\ The Regents of the University of California. All rights reserved.\n"; d41 1 a41 1 static char sccsid[] = "@@(#)mkdir.c 8.2 (Berkeley) 1/25/94"; a45 2 #include a47 1 #include a48 1 #include d50 1 a50 2 int build __P((char *)); void usage __P((void)); a51 1 int d54 1 a54 1 char *argv[]; d56 2 a57 3 int ch, exitval, oct, omode, pflag; mode_t *set; char *ep, *mode; d60 1 a60 2 mode = NULL; while ((ch = getopt(argc, argv, "m:p")) != EOF) a64 3 case 'm': mode = optarg; break; d70 1 a70 3 argc -= optind; argv += optind; if (argv[0] == NULL) d73 6 a78 22 if (mode == NULL) { omode = S_IRWXU | S_IRWXG | S_IRWXO; oct = 1; } else if (*mode >= '0' && *mode <= '7') { omode = (int)strtol(mode, &ep, 8); if (omode < 0 || *ep) errx(1, "invalid file mode: %s", mode); oct = 1; } else { if ((set = setmode(mode)) == NULL) errx(1, "invalid file mode: %s", mode); oct = 0; } for (exitval = 0; *argv != NULL; ++argv) { if (pflag && build(*argv)) { exitval = 1; continue; } if (mkdir(*argv, oct ? omode : getmode(set, S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { warn("%s", *argv); a80 1 } a83 1 int d87 1 d89 13 a101 36 mode_t numask, oumask; int first; char *p; p = path; if (p[0] == '/') /* Skip leading '/'. */ ++p; for (first = 1;; ++p) { if (p[0] == '\0' || p[0] == '/' && p[1] == '\0') break; if (p[0] != '/') continue; *p = '\0'; if (first) { /* * POSIX 1003.2: * For each dir operand that does not name an existing * directory, effects equivalent to those cased by the * following command shall occcur: * * mkdir -p -m $(umask -S),u+wx $(dirname dir) && * mkdir [-m mode] dir * * We change the user's umask and then restore it, * instead of doing chmod's. */ oumask = umask(0); numask = oumask & ~(S_IWUSR | S_IXUSR); (void)umask(numask); first = 0; } if (stat(path, &sb)) { if (errno != ENOENT || mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO) < 0) { warn("%s", path); return (1); d103 2 d106 4 a109 1 *p = '/'; d111 1 a111 3 if (!first) (void)umask(oumask); return (0); a113 1 void d116 2 a117 2 (void)fprintf(stderr, "usage: mkdir [-p] [-m mode] directory ...\n"); exit (1); @