Author | Jamozed <[email protected]> |
Date | 2020-10-26 00:02:06 |
Commit | 5d4006feae8295410753eb72161fce42e38dd56d |
Parent | eb8174b7e31dbb41b6c37282370c2a0dcbe85f5e |
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