cdfecb8 |
Jamozed |
2022-03-06 15:11:25 |
0
|
// util/mode.c, version 1.0.3 |
b181413 |
Jamozed |
2022-02-05 22:32:00 |
1
|
// Mode source file from libutil |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
2
|
// Copyright (C) 2020, Jakob Wakeling |
cdfecb8 |
Jamozed |
2022-03-06 15:11:25 |
3
|
// MIT Licence |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
4
|
|
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
5
|
/* |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
6
|
TODO Handle copying permissions |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
7
|
*/ |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
8
|
|
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
9
|
#include "mode.h" |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
10
|
|
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
11
|
#include <sys/types.h> |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
12
|
|
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
13
|
#include <stdio.h> |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
14
|
#include <stdlib.h> |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
15
|
|
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
16
|
static inline int getop(char **s); |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
17
|
static inline mode_t getref(char **s); |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
18
|
|
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
19
|
/* Parse an octal or symbolic mode string */ |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
20
|
chmod_t *strmode(char *str) { |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
21
|
char *s = str; chmod_t *m; mode_t mode = 0; size_t i; |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
22
|
|
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
23
|
// Try and parse an octal mode |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
24
|
for (register mode_t d; *s >= '0' && *s <= '7'; ++s) { |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
25
|
d = *s - '0'; if (mode > (07777 - d) / 8) { break; } |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
26
|
mode = mode * 8 + d; |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
27
|
} |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
28
|
|
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
29
|
if (!*s) { |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
30
|
m = (chmod_t *)malloc(2 * sizeof (*m)); |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
31
|
|
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
32
|
// Construct a chmod_t from the octal mode and return it |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
33
|
m[0].flag = MF_NORM; m[1].flag = MF_NULL; |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
34
|
m[0].op = '='; m[0].ref = M_ALL; m[0].mod = mode; |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
35
|
|
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
36
|
return m; |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
37
|
} |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
38
|
|
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
39
|
// If the octal mode is invalid return NULL |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
40
|
else if (s != str) { return NULL; } |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
41
|
|
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
42
|
// Allocate necesary memory for chmod_t array |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
43
|
for (i = 1; *s; ++s) { i += (*s == '+' || *s == '-' || *s == '='); } |
4de09c8 |
Jamozed |
2020-11-13 00:11:06 |
44
|
m = (chmod_t *)malloc((i + 1) * sizeof (*m)); s = str; m[i].flag = MF_NULL; |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
45
|
|
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
46
|
i = 0; do { // Parse each part of the symbolic mode string |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
47
|
for (mode_t ref = getref(&s); ((m[i].op = getop(&s))); ++i) { |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
48
|
m[i].flag = MF_NORM; m[i].ref = ref; |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
49
|
|
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
50
|
// Process the next mode |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
51
|
for (m[i].mod = 0;;) switch (*s) { |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
52
|
case 'r': { m[i].mod |= M_RD; ++s; continue; } |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
53
|
case 'w': { m[i].mod |= M_WR; ++s; continue; } |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
54
|
case 'x': { m[i].mod |= M_EX; ++s; continue; } |
02a966d |
Jamozed |
2020-09-26 00:35:01 |
55
|
case 'X': { m[i].flag = MF_XIFX; ++s; continue; } |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
56
|
case 's': { m[i].mod |= M_ID; ++s; continue; } |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
57
|
case 't': { m[i].mod |= M_ST; ++s; continue; } |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
58
|
default: { goto end; } |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
59
|
} end:; |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
60
|
} |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
61
|
} while (*s++ == ',' && *s); |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
62
|
|
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
63
|
// If the symbolic mode is invalid return NULL |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
64
|
if (*--s) { free(m); return NULL; } return m; |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
65
|
} |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
66
|
|
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
67
|
/* Process and return next operator */ |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
68
|
static inline int getop(char **s) { |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
69
|
switch (**s) { case '+': case '-': case '=': { return *(*s)++; }} |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
70
|
return 0; |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
71
|
} |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
72
|
|
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
73
|
/* Process and return next reference */ |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
74
|
static inline mode_t getref(char **s) { |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
75
|
for (mode_t ref = 0;;) switch (**s) { |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
76
|
case 'u': { ref |= M_USR; ++*s; continue; } |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
77
|
case 'g': { ref |= M_GRP; ++*s; continue; } |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
78
|
case 'o': { ref |= M_OTH; ++*s; continue; } |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
79
|
case 'a': { ref |= M_ALL; ++*s; continue; } |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
80
|
default: { return ref; } |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
81
|
} |
fafac6a |
Jamozed |
2020-09-26 00:08:34 |
82
|
} |
|
|
|
83
|
|