Skip to content

Commit

Permalink
chmod: partial implementation of the chmod command
Browse files Browse the repository at this point in the history
  • Loading branch information
jewelcodes committed Jan 3, 2025
1 parent 6efbda6 commit 986566f
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 1 deletion.
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ all:
@make -C head
@echo "\x1B[0;1;35m make\x1B[0m utilities/reset"
@make -C reset
@echo "\x1B[0;1;35m make\x1B[0m utilities/chmod"
@make -C chmod

install:
@mkdir -p out
Expand All @@ -46,6 +48,8 @@ install:
@make install -C head
@echo "\x1B[0;1;35m make\x1B[0m install utilities/reset"
@make install -C reset
@echo "\x1B[0;1;35m make\x1B[0m install utilities/chmod"
@make install -C chmod

clean:
@echo "\x1B[0;1;35m make\x1B[0m clean utilities/hello"
Expand All @@ -69,4 +73,6 @@ clean:
@echo "\x1B[0;1;35m make\x1B[0m clean utilities/head"
@make clean -C head
@echo "\x1B[0;1;35m make\x1B[0m clean utilities/reset"
@make clean -C reset
@make clean -C reset
@echo "\x1B[0;1;35m make\x1B[0m clean utilities/chmod"
@make clean -C chmod
23 changes: 23 additions & 0 deletions chmod/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
PLATFORM=x86_64-lux
CCFLAGS=-Wall -c -O3
LDFLAGS=-llux
CC=x86_64-lux-gcc
LD=x86_64-lux-gcc
SRC:=$(shell find . -type f -name "*.c")
OBJ:=$(SRC:.c=.o)

all: chmod

%.o: %.c
@echo "\x1B[0;1;32m cc \x1B[0m $<"
@$(CC) $(CCFLAGS) -o $@ $<

chmod: $(OBJ)
@echo "\x1B[0;1;93m ld \x1B[0m chmod"
@$(LD) $(OBJ) -o chmod $(LDFLAGS)

install: chmod
@cp chmod ../out/

clean:
@rm -f chmod $(OBJ)
97 changes: 97 additions & 0 deletions chmod/chmod.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* luxOS - a unix-like operating system
* Omar Elghoul, 2024
*
* chmod: Implementation of the chmod command
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>

static const mode_t bitmap[] = {
S_IXOTH,
S_IWOTH,
S_IROTH,
S_IXGRP,
S_IWGRP,
S_IRGRP,
S_IXUSR,
S_IWUSR,
S_IRUSR
};

int parse(const char *modestr, mode_t *set, mode_t *clear) {
*set = 0;
*clear = 0;

/* numerical mode setting */
if(modestr[0] >= '0' && modestr[0] <= '9') {
int num = atoi(modestr);

for(int i = 0; i < 3; i++) {
int digit = num % 10;
num /= 10;
if(digit > 7) return 1;

if(digit & 1) { // execute
*set |= bitmap[i * 3];
} else {
*clear |= bitmap[i * 3];
}

if(digit & 2) { // write
*set |= bitmap[(i * 3) + 1];
} else {
*clear |= bitmap[(i * 3) + 1];
}

if(digit & 4) { // read
*set |= bitmap[(i * 3) + 2];
} else {
*clear |= bitmap[(i * 3) + 2];
}
}

return 0;
}

/* TODO: symbolic mode setting */
return 1;
}

int main(int argc, char **argv) {
/* TODO: add support for -R to recursively change file modes */

if(argc < 3) {
fprintf(stderr, "usage: %s [-R] mode file...\n", argv[0]);
return EXIT_FAILURE;
}

mode_t set = 0, clear = 0;
if(parse(argv[1], &set, &clear)) {
fprintf(stderr, "%s: invalid mode -- %s\n", argv[0], argv[1]);
return EXIT_FAILURE;
}

int errors = 0;

struct stat st;
for(int i = 2; i < argc; i++) {
if(stat(argv[i], &st)) {
perror(argv[i]);
errors++;
continue;
}

st.st_mode &= ~clear;
st.st_mode |= set;
if(chmod(argv[i], st.st_mode)) {
perror(argv[i]);
errors++;
}
}

return errors;
}

0 comments on commit 986566f

Please sign in to comment.