Commit | Line | Data |
---|---|---|
d95ba5f0 JB |
1 | /* Make all the directories along a path. |
2 | Copyright (C) 1992 Free Software Foundation, Inc. | |
3 | ||
4 | This file is part of GNU Emacs. | |
5 | ||
6 | GNU Emacs is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
566c662e | 8 | the Free Software Foundation; either version 2, or (at your option) |
d95ba5f0 JB |
9 | any later version. |
10 | ||
11 | GNU Emacs is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with GNU Emacs; see the file COPYING. If not, write to | |
18 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
19 | ||
20 | /* This program works like mkdir, except that it generates | |
21 | intermediate directories if they don't exist. This is just like | |
22 | the `mkdir -p' command on most systems; unfortunately, the mkdir | |
23 | command on some of the purer BSD systems (like Mt. Xinu) don't have | |
24 | that option. */ | |
25 | ||
26 | #include <sys/types.h> | |
27 | #include <sys/stat.h> | |
28 | #include <stdio.h> | |
29 | #include <errno.h> | |
30 | ||
31 | extern int errno; | |
32 | ||
33 | char *prog_name; | |
34 | ||
cc162c53 RS |
35 | /* Create directory DIRNAME if it does not exist already. |
36 | Then give permission for everyone to read and search it. | |
37 | Return 0 if successful, 1 if not. */ | |
38 | ||
39 | int | |
40 | touchy_mkdir (dirname) | |
41 | char *dirname; | |
d95ba5f0 JB |
42 | { |
43 | struct stat buf; | |
44 | ||
cc162c53 RS |
45 | /* If DIRNAME already exists and is a directory, don't create. */ |
46 | if (! (stat (dirname, &buf) >= 0 | |
47 | && (buf.st_mode & S_IFMT) == S_IFDIR)) | |
48 | { | |
49 | /* Otherwise, try to make it. If DIRNAME exists but isn't a directory, | |
50 | this will signal an error. */ | |
51 | if (mkdir (dirname, 0777) < 0) | |
52 | { | |
53 | fprintf (stderr, "%s: ", prog_name); | |
54 | perror (dirname); | |
55 | return 1; | |
56 | } | |
57 | } | |
d95ba5f0 | 58 | |
cc162c53 RS |
59 | /* Make sure everyone can look at this directory. */ |
60 | if (stat (dirname, &buf) < 0) | |
d95ba5f0 JB |
61 | { |
62 | fprintf (stderr, "%s: ", prog_name); | |
cc162c53 | 63 | perror (dirname); |
566c662e | 64 | return 1; |
d95ba5f0 | 65 | } |
cc162c53 RS |
66 | if (chmod (dirname, 0555 | (buf.st_mode & 0777)) < 0) |
67 | { | |
68 | fprintf (stderr, "%s: ", prog_name); | |
69 | perror (dirname); | |
70 | } | |
d95ba5f0 JB |
71 | |
72 | return 0; | |
73 | } | |
74 | ||
75 | int | |
76 | main (argc, argv) | |
77 | int argc; | |
78 | char **argv; | |
79 | { | |
80 | prog_name = *argv; | |
81 | ||
82 | for (argc--, argv++; argc > 0; argc--, argv++) | |
83 | { | |
cc162c53 | 84 | char *dirname = *argv; |
d95ba5f0 JB |
85 | int i; |
86 | ||
cc162c53 | 87 | /* Stop at each slash in dirname and try to create the directory. |
d95ba5f0 | 88 | Skip any initial slash. */ |
cc162c53 RS |
89 | for (i = (dirname[0] == '/') ? 1 : 0; dirname[i]; i++) |
90 | if (dirname[i] == '/') | |
d95ba5f0 | 91 | { |
cc162c53 RS |
92 | dirname[i] = '\0'; |
93 | if (touchy_mkdir (dirname) < 0) | |
94 | goto next_dirname; | |
95 | dirname[i] = '/'; | |
d95ba5f0 JB |
96 | } |
97 | ||
cc162c53 | 98 | touchy_mkdir (dirname); |
d95ba5f0 | 99 | |
cc162c53 | 100 | next_dirname: |
d95ba5f0 JB |
101 | ; |
102 | } | |
ef7054f5 RS |
103 | |
104 | return 0; | |
d95ba5f0 | 105 | } |