coreutils

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

coreutils/src/util/mode.c (84 lines, 2.3 KiB) -rw-r--r-- file download

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