coreutils

General Software Utilities
git clone http://git.omkov.net/coreutils
Log | Tree | Refs | README | LICENCE | Download

coreutils/src/mkdir.c (125 lines, 3.2 KiB) -rw-r--r-- file download

88802f3 Jamozed 2020-09-26 00:40:39
0
// mkdir.c, version 1.0.4
d3522e7 Jamozed 2020-06-26 18:42:30
1
// OMKOV coreutils implementation of POSIX mkdir
d3522e7 Jamozed 2020-06-26 18:42:30
2
// Copyright (C) 2020, Jakob Wakeling
e2140ec Jamozed 2022-03-06 15:27:45
3
// MIT Licence
d3522e7 Jamozed 2020-06-26 18:42:30
4
88802f3 Jamozed 2020-09-26 00:40:39
5
/*
88802f3 Jamozed 2020-09-26 00:40:39
6
	TODO Cleanup p flag handling
88802f3 Jamozed 2020-09-26 00:40:39
7
	TODO Handle copying permissions
88802f3 Jamozed 2020-09-26 00:40:39
8
*/
88802f3 Jamozed 2020-09-26 00:40:39
9
b181413 Jamozed 2022-02-05 22:32:00
10
#include "util/error.h"
b181413 Jamozed 2022-02-05 22:32:00
11
#include "util/mode.h"
b181413 Jamozed 2022-02-05 22:32:00
12
#include "util/optget.h"
d3522e7 Jamozed 2020-06-26 18:42:30
13
d3522e7 Jamozed 2020-06-26 18:42:30
14
#include <sys/stat.h>
d3522e7 Jamozed 2020-06-26 18:42:30
15
d3522e7 Jamozed 2020-06-26 18:42:30
16
#include <errno.h>
d3522e7 Jamozed 2020-06-26 18:42:30
17
#include <stdbool.h>
d3522e7 Jamozed 2020-06-26 18:42:30
18
#include <stdio.h>
bcc3fa8 Jamozed 2020-11-13 00:11:41
19
#include <stdlib.h>
76371b7 Jamozed 2020-07-06 22:52:45
20
88802f3 Jamozed 2020-09-26 00:40:39
21
#define VERSION "1.0.4"
d3522e7 Jamozed 2020-06-26 18:42:30
22
30cf081 Jamozed 2020-08-28 23:01:02
23
static struct lop lops[] = {
30cf081 Jamozed 2020-08-28 23:01:02
24
	{ "help",    ARG_NUL, 256 },
30cf081 Jamozed 2020-08-28 23:01:02
25
	{ "version", ARG_NUL, 257 },
30cf081 Jamozed 2020-08-28 23:01:02
26
	{ NULL, 0, 0 }
30cf081 Jamozed 2020-08-28 23:01:02
27
};
30cf081 Jamozed 2020-08-28 23:01:02
28
88802f3 Jamozed 2020-09-26 00:40:39
29
static char *mopt;
88802f3 Jamozed 2020-09-26 00:40:39
30
static bool  pflag;
d3522e7 Jamozed 2020-06-26 18:42:30
31
88802f3 Jamozed 2020-09-26 00:40:39
32
static mode_t mask;
d3522e7 Jamozed 2020-06-26 18:42:30
33
88802f3 Jamozed 2020-09-26 00:40:39
34
static inline int makedir(const char *path, chmod_t *m);
d3522e7 Jamozed 2020-06-26 18:42:30
35
30cf081 Jamozed 2020-08-28 23:01:02
36
static void hlp(void);
30cf081 Jamozed 2020-08-28 23:01:02
37
static void ver(void);
d3522e7 Jamozed 2020-06-26 18:42:30
38
76371b7 Jamozed 2020-07-06 22:52:45
39
int main(int ac, char *av[]) { A0 = av[0];
30cf081 Jamozed 2020-08-28 23:01:02
40
	struct opt opt = OPTGET_INIT; opt.str = "m:p"; opt.lops = lops;
30cf081 Jamozed 2020-08-28 23:01:02
41
	for (int o; (o = optget(&opt, av, 1)) != -1;) switch (o) {
d3522e7 Jamozed 2020-06-26 18:42:30
42
	case 'm': { mopt = opt.arg; break; }
d3522e7 Jamozed 2020-06-26 18:42:30
43
	case 'p': { pflag = true; break; }
30cf081 Jamozed 2020-08-28 23:01:02
44
	case 256: { hlp(); return 0; }
30cf081 Jamozed 2020-08-28 23:01:02
45
	case 257: { ver(); return 0; }
d3522e7 Jamozed 2020-06-26 18:42:30
46
	default: { return 1; }
d3522e7 Jamozed 2020-06-26 18:42:30
47
	}
d3522e7 Jamozed 2020-06-26 18:42:30
48
	
76371b7 Jamozed 2020-07-06 22:52:45
49
	if (opt.ind == ac) { error(1, "missing operand"); }
d3522e7 Jamozed 2020-06-26 18:42:30
50
	
88802f3 Jamozed 2020-09-26 00:40:39
51
	chmod_t *m = NULL; if (mopt) {
88802f3 Jamozed 2020-09-26 00:40:39
52
		mask = umask(0); m = strmode(mopt);
88802f3 Jamozed 2020-09-26 00:40:39
53
		if (!m) { error(1, "%s: invalid mode", mopt); }
88802f3 Jamozed 2020-09-26 00:40:39
54
	}
88802f3 Jamozed 2020-09-26 00:40:39
55
	
88802f3 Jamozed 2020-09-26 00:40:39
56
	bool warned = false;
d3522e7 Jamozed 2020-06-26 18:42:30
57
	
88802f3 Jamozed 2020-09-26 00:40:39
58
	for (char **p = &av[opt.ind]; *p; ++p) {
88802f3 Jamozed 2020-09-26 00:40:39
59
		if (pflag) { // Create directory hierarchy if p flag is set
88802f3 Jamozed 2020-09-26 00:40:39
60
			char *q = *p; for (; *q == '/'; ++q) {}
88802f3 Jamozed 2020-09-26 00:40:39
61
			for (; *q; ++q) {
88802f3 Jamozed 2020-09-26 00:40:39
62
				if (*q != '/' || *(q + 1) == '/') { continue; } *q = 0;
88802f3 Jamozed 2020-09-26 00:40:39
63
				if (mkdir(*p, (S_IWUSR | S_IXUSR | ~mask) & 0777) &&
88802f3 Jamozed 2020-09-26 00:40:39
64
						errno != EEXIST) {
88802f3 Jamozed 2020-09-26 00:40:39
65
					warn("%s: %s", *p, serr()); continue;
88802f3 Jamozed 2020-09-26 00:40:39
66
				} *q = '/';
d3522e7 Jamozed 2020-06-26 18:42:30
67
			}
d3522e7 Jamozed 2020-06-26 18:42:30
68
		}
88802f3 Jamozed 2020-09-26 00:40:39
69
		
88802f3 Jamozed 2020-09-26 00:40:39
70
		if (makedir(*p, m)) { warn("%s: %s", *p, serr()); warned = true; }
d3522e7 Jamozed 2020-06-26 18:42:30
71
	}
d3522e7 Jamozed 2020-06-26 18:42:30
72
	
72364dd Jamozed 2020-11-17 01:23:57
73
	free(m); return warned;
d3522e7 Jamozed 2020-06-26 18:42:30
74
}
d3522e7 Jamozed 2020-06-26 18:42:30
75
88802f3 Jamozed 2020-09-26 00:40:39
76
/* Make directory with specified permissions */
88802f3 Jamozed 2020-09-26 00:40:39
77
static inline int makedir(const char *path, chmod_t *m) {
88802f3 Jamozed 2020-09-26 00:40:39
78
	// If no chmod is given, use default mode
88802f3 Jamozed 2020-09-26 00:40:39
79
	if (!m) { if (mkdir(path, 0777)) { return 1; } return 0; }
d3522e7 Jamozed 2020-06-26 18:42:30
80
	
88802f3 Jamozed 2020-09-26 00:40:39
81
	// Create directory with no permissions
88802f3 Jamozed 2020-09-26 00:40:39
82
	if (mkdir(path, 0)) { return 1; } mode_t mode = 0777;
d3522e7 Jamozed 2020-06-26 18:42:30
83
	
88802f3 Jamozed 2020-09-26 00:40:39
84
	// Handle each chmod_t
88802f3 Jamozed 2020-09-26 00:40:39
85
	for (int i = 0;; ++i) switch (m[i].flag) {
88802f3 Jamozed 2020-09-26 00:40:39
86
	case MF_NORM: case MF_XIFX: {
88802f3 Jamozed 2020-09-26 00:40:39
87
		// If ref is null, use the file mode creation mask
88802f3 Jamozed 2020-09-26 00:40:39
88
		if (!m[i].ref) { m[i].ref = M_ALL & ~mask; }
d3522e7 Jamozed 2020-06-26 18:42:30
89
		
88802f3 Jamozed 2020-09-26 00:40:39
90
		switch (m[i].op) {
88802f3 Jamozed 2020-09-26 00:40:39
91
		case '+': { mode |= m[i].ref & m[i].mod; break; }
88802f3 Jamozed 2020-09-26 00:40:39
92
		case '-': { mode &= (~(m[i].ref & m[i].mod) & 07777); break; }
88802f3 Jamozed 2020-09-26 00:40:39
93
		case '=': { mode &= ~m[i].ref; mode |= m[i].ref & m[i].mod; break; }
d3522e7 Jamozed 2020-06-26 18:42:30
94
		}
88802f3 Jamozed 2020-09-26 00:40:39
95
		
88802f3 Jamozed 2020-09-26 00:40:39
96
		// If the XIFX flag is set, set execute permission
88802f3 Jamozed 2020-09-26 00:40:39
97
		if (m[i].flag == MF_XIFX) { mode |= m[i].ref & M_EX; } break;
d3522e7 Jamozed 2020-06-26 18:42:30
98
	}
88802f3 Jamozed 2020-09-26 00:40:39
99
	case MF_COPY: { /* TODO */ }
88802f3 Jamozed 2020-09-26 00:40:39
100
	case MF_NULL: { goto end; }
88802f3 Jamozed 2020-09-26 00:40:39
101
	} end:;
d3522e7 Jamozed 2020-06-26 18:42:30
102
	
88802f3 Jamozed 2020-09-26 00:40:39
103
	// Set permissions of directory to the calculated mode
88802f3 Jamozed 2020-09-26 00:40:39
104
	if (chmod(path, mode)) { return 1; } return 0;
d3522e7 Jamozed 2020-06-26 18:42:30
105
}
d3522e7 Jamozed 2020-06-26 18:42:30
106
88802f3 Jamozed 2020-09-26 00:40:39
107
/* Print help information */
30cf081 Jamozed 2020-08-28 23:01:02
108
static void hlp(void) {
d3522e7 Jamozed 2020-06-26 18:42:30
109
	puts("mkdir - make directories\n");
d3522e7 Jamozed 2020-06-26 18:42:30
110
	puts("usage: mkdir [-p] [-m mode] dir...\n");
d3522e7 Jamozed 2020-06-26 18:42:30
111
	puts("options:");
d3522e7 Jamozed 2020-06-26 18:42:30
112
	puts("  -p         Create all parent directories as required");
d3522e7 Jamozed 2020-06-26 18:42:30
113
	puts("  -m mode    Set the file mode of the created directory");
d3522e7 Jamozed 2020-06-26 18:42:30
114
	puts("  --help     Display help information");
d3522e7 Jamozed 2020-06-26 18:42:30
115
	puts("  --version  Display version information");
d3522e7 Jamozed 2020-06-26 18:42:30
116
}
d3522e7 Jamozed 2020-06-26 18:42:30
117
88802f3 Jamozed 2020-09-26 00:40:39
118
/* Print version information */
30cf081 Jamozed 2020-08-28 23:01:02
119
static void ver(void) {
76371b7 Jamozed 2020-07-06 22:52:45
120
	puts("OMKOV coreutils mkdir, version " VERSION);
d3522e7 Jamozed 2020-06-26 18:42:30
121
	puts("Copyright (C) 2020, Jakob Wakeling");
e2140ec Jamozed 2022-03-06 15:27:45
122
	puts("MIT Licence (https://opensource.org/licenses/MIT)");
d3522e7 Jamozed 2020-06-26 18:42:30
123
}
124