libutil

C Utility Library
git clone http://git.omkov.net/libutil
Log | Tree | Refs | README | LICENCE | Download

AuthorJamozed <[email protected]>
Date2020-10-26 00:02:06
Commit5d4006feae8295410753eb72161fce42e38dd56d
Parenteb8174b7e31dbb41b6c37282370c2a0dcbe85f5e

mode: Add mode

Diffstat

A src/lib/mode.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A src/lib/mode.h | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++

2 files changed, 164 insertions, 0 deletions

diff --git a/src/lib/mode.c b/src/lib/mode.c
new file mode 100644
index 0000000..7388077
--- /dev/null
+++ b/src/lib/mode.c
@@ -0,0 +1,110 @@
+// mode.c, version 1.0.0
+// Mode source file for OMKOV lib
+// Copyright (C) 2020, Jakob Wakeling
+// All rights reserved.
+
+/*
+OMKOV Permissive Licence, version 1.0
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimers.
+* Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimers in the documentation and/or
+  other materials provided with the distribution.
+* Neither the names of the copyright holders, nor the names of its contributors
+  may be used to endorse or promote products derived from this Software without
+  specific prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT
+HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
+*/
+
+/*
+	TODO Handle copying permissions
+*/
+
+#include "mode.h"
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static inline int getop(char **s);
+static inline mode_t getref(char **s);
+
+/* Parse an octal or symbolic mode string */
+chmod_t *strmode(char *str) {
+	char *s = str; chmod_t *m; mode_t mode = 0; size_t i;
+	
+	// Try and parse an octal mode
+	for (register mode_t d; *s >= '0' && *s <= '7'; ++s) {
+		d = *s - '0'; if (mode > (07777 - d) / 8) { break; }
+		mode = mode * 8 + d;
+	}
+	
+	if (!*s) {
+		m = (chmod_t *)malloc(2 * sizeof (*m));
+		
+		// Construct a chmod_t from the octal mode and return it
+		m[0].flag = MF_NORM; m[1].flag = MF_NULL;
+		m[0].op = '='; m[0].ref = M_ALL; m[0].mod = mode;
+		
+		return m;
+	}
+	
+	// If the octal mode is invalid return NULL
+	else if (s != str) { return NULL; }
+	
+	// Allocate necesary memory for chmod_t array
+	for (i = 1; *s; ++s) { i += (*s == '+' || *s == '-' || *s == '='); }
+	m = (chmod_t *)malloc(i * sizeof (*m)); s = str; m[i].flag = MF_NULL;
+	
+	i = 0; do { // Parse each part of the symbolic mode string
+		for (mode_t ref = getref(&s); ((m[i].op = getop(&s))); ++i) {
+			m[i].flag = MF_NORM; m[i].ref = ref;
+			
+			// Process the next mode
+			for (m[i].mod = 0;;) switch (*s) {
+				case 'r': { m[i].mod |= M_RD; ++s; continue; }
+				case 'w': { m[i].mod |= M_WR; ++s; continue; }
+				case 'x': { m[i].mod |= M_EX; ++s; continue; }
+				case 'X': { m[i].flag = MF_XIFX; ++s; continue; }
+				case 's': { m[i].mod |= M_ID; ++s; continue; }
+				case 't': { m[i].mod |= M_ST; ++s; continue; }
+				default: { goto end; }
+			} end:;
+		}
+	} while (*s++ == ',' && *s);
+	
+	// If the symbolic mode is invalid return NULL
+	if (*--s) { free(m); return NULL; } return m;
+}
+
+/* Process and return next operator */
+static inline int getop(char **s) {
+	switch (**s) { case '+': case '-': case '=': { return *(*s)++; }}
+	return 0;
+}
+
+/* Process and return next reference */
+static inline mode_t getref(char **s) {
+	for (mode_t ref = 0;;) switch (**s) {
+	case 'u': { ref |= M_USR; ++*s; continue; }
+	case 'g': { ref |= M_GRP; ++*s; continue; }
+	case 'o': { ref |= M_OTH; ++*s; continue; }
+	case 'a': { ref |= M_ALL; ++*s; continue; }
+	default: { return ref; }
+	}
+}
diff --git a/src/lib/mode.h b/src/lib/mode.h
new file mode 100644
index 0000000..ec2f45a
--- /dev/null
+++ b/src/lib/mode.h
@@ -0,0 +1,54 @@
+// mode.h, version 1.0.0
+// Mode header file for OMKOV lib
+// Copyright (C) 2020, Jakob Wakeling
+// All rights reserved.
+
+/*
+OMKOV Permissive Licence, version 1.0
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimers.
+* Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimers in the documentation and/or
+  other materials provided with the distribution.
+* Neither the names of the copyright holders, nor the names of its contributors
+  may be used to endorse or promote products derived from this Software without
+  specific prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT
+HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
+*/
+
+#ifndef OMKOV_LIB_MODE_H_0C99POMA
+#define OMKOV_LIB_MODE_H_0C99POMA
+
+#include <sys/types.h>
+
+#define M_USR 05700
+#define M_GRP 02070
+#define M_OTH 00007
+#define M_ALL 07777
+
+#define M_RD  00444
+#define M_WR  00222
+#define M_EX  00111
+#define M_ID  06000
+#define M_ST  01000
+
+typedef struct { int flag; int op; mode_t ref; mode_t mod; } chmod_t;
+enum { MF_NULL, MF_NORM, MF_XIFX, MF_COPY };
+
+extern chmod_t *strmode(char *str);
+
+#endif // OMKOV_LIB_MODE_H_0C99POMA