FENIX_coreutils/mkfifo.c
2020-12-12 13:33:43 -06:00

122 lines
No EOL
2.6 KiB
C

#define _POSIX_C_SOURCE 200809L
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdlib.h>
mode_t parse_mode(char *);
int main(int argc, char * argv[]) {
char c; mode_t mode; char * mode_text = NULL;
int failed = 0;
while((c = getopt(argc, argv, "m:")) != -1) {
if(c == 'm') {
mode_text = optarg;
}
}
mode = mode_text != NULL ? parse_mode(mode_text) : 0666;
for(; optind < argc; optind++) {
int ohno = mkfifo(argv[optind], mode);
if(ohno != 0) {
failed = 1;
}
}
if(failed == 0) {
return 0;
}
else {
return 1;
}
}
mode_t parse_mode(char * symbolic) {
if(symbolic[0] >= '0' && symbolic[0] <= '9') {
return strtol(symbolic, NULL, 8);
}
int i = 0; int who; int perm;
while(symbolic[i] != '+' && symbolic[i] != '-' &&
symbolic[i] != '=' && symbolic[i] != '\0') {
switch(symbolic[i++]) {
case 'u': who |= 01; break;
case 'g': who |= 02; break;
case 'o': who |= 04; break;
case 'a': who |= 07; break;
}
}
int j = i;
while(symbolic[i] != '\0' && symbolic[i] != ',') {
switch(symbolic[++i]) {
case 'r': perm |= 01; break;
case 'w': perm |= 02; break;
case 'x': perm |= 04; break;
}
}
mode_t mode = 0666;
if(symbolic[j] == '+') {
if(who & 01) {
mode |= (perm & 01) ? 0400 : 0;
mode |= (perm & 02) ? 0200 : 0;
mode |= (perm & 04) ? 0100 : 0;
}
if(who & 02) {
mode |= (perm & 01) ? 040 : 0;
mode |= (perm & 02) ? 020 : 0;
mode |= (perm & 04) ? 010 : 0;
}
if(who & 04) {
mode |= (perm & 01) ? 04 : 0;
mode |= (perm & 02) ? 02 : 0;
mode |= (perm & 04) ? 01 : 0;
}
}
else if(symbolic[j] == '=') {
mode = 0;
if(who & 01) {
mode |= (perm & 01) ? 0400 : 0;
mode |= (perm & 02) ? 0200 : 0;
mode |= (perm & 04) ? 0100 : 0;
}
if(who & 02) {
mode |= (perm & 01) ? 040 : 0;
mode |= (perm & 02) ? 020 : 0;
mode |= (perm & 04) ? 010 : 0;
}
if(who & 04) {
mode |= (perm & 01) ? 04 : 0;
mode |= (perm & 02) ? 02 : 0;
mode |= (perm & 04) ? 01 : 0;
}
}
else if(symbolic[j] == '-') {
if(who & 01) {
mode ^= (perm & 01) ? 0400 : 0;
mode ^= (perm & 02) ? 0200 : 0;
mode ^= (perm & 04) ? 0100 : 0;
}
if(who & 02) {
mode ^= (perm & 01) ? 040 : 0;
mode ^= (perm & 02) ? 020 : 0;
mode ^= (perm & 04) ? 010 : 0;
}
if(who & 04) {
mode ^= (perm & 01) ? 04 : 0;
mode ^= (perm & 02) ? 02 : 0;
mode ^= (perm & 04) ? 01 : 0;
}
}
else {
return 0000;
}
return mode;
}