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