OrionUserland
Barry Importing existing Orion Userland 19aefaa (2 years, 4 months ago)diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.o diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..85d9ce7 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +PROGS=$(shell basename -a $(shell find . -mindepth 1 -maxdepth 1 -type d -not -path '*/.*')) + +.PHONY: clean all install + +all: + @$(foreach prog,$(PROGS),$(MAKE) -s -C $(prog);) + +clean: + @$(foreach prog,$(PROGS),$(MAKE) -s -C $(prog) clean;) + +install: + @$(foreach prog,$(PROGS),$(MAKE) -s -C $(prog) install;) diff --git a/cat/Makefile b/cat/Makefile new file mode 100644 index 0000000..5254c7c --- /dev/null +++ b/cat/Makefile @@ -0,0 +1,46 @@ +PRODUCT=$(notdir $(abspath $(CURDIR))) + +CC=i686-orion-gcc +CFLAGS= + +AS=i686-orion-as +AFLAGS= + +LD=i686-orion-gcc +LFLAGS= + +AS_SOURCES := $(shell find . -name '*.S') +OBJS = $(sort $(subst ./,build/,$(subst .S,.o,$(AS_SOURCES)))) + +C_SOURCES := $(shell find . -name '*.c') +OBJS += $(sort $(subst ./,build/,$(subst .c,.o,$(C_SOURCES)))) + +.PHONY: clean all install + +all: $(PRODUCT) + +clean: + @echo "REMOVING OBJECT FILES" + @mkdir -p build + @rm -rf build + @touch $(PRODUCT) + @rm $(PRODUCT) + +install: $(PRODUCT) + @echo "INSTALLING $^" + @mkdir -p ${SYSROOT}/bin/ + @install -Dm 755 $(PRODUCT) -t ${SYSROOT}/bin/ + +$(PRODUCT): $(OBJS) + @echo "LINKING $@" + @$(LD) -o $@ $^ $(LFLAGS) + +build/%.o: %.c + @echo "COMPILING $<" + @mkdir -p $(@D) + @$(CC) -c $< -o $@ $(CFLAGS) + +build/%.o: %.S + @echo "ASSEMBLING $<" + @mkdir -p $(@D) + @$(AS) $< -o $@ $(AFLAGS) diff --git a/cat/cat b/cat/cat new file mode 100755 index 0000000..7b4fdb6 Binary files /dev/null and b/cat/cat differ diff --git a/cat/main.c b/cat/main.c new file mode 100644 index 0000000..f1570bc --- /dev/null +++ b/cat/main.c @@ -0,0 +1,44 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <sys/stat.h> +#include <dirent.h> + +/* Main function */ +int +main(int argc, char *argv[]) +{ + int fd, sz, i; + char *buf; + struct stat statbuf; + + if (argc < 2) { + printf("Usage: %s <file> [<file>...]\n"); + return 0; + } + + for (i = 1; i < argc; i++) { + fd = open(argv[i], O_RDONLY); + if (fd < 0) { + printf("%s: %s: ", argv[0], argv[i]); + perror(NULL); + continue; + } + + stat(argv[i], &statbuf); + if (S_ISREG(statbuf.mode)) { + sz = lseek(fd, 0, SEEK_END); + buf = malloc(sz + 1); + lseek(fd, 0, SEEK_SET); + read(fd, buf, sz); + printf("%s", buf); + free(buf); + } + + close(fd); + } + + return 0; +} diff --git a/clear/Makefile b/clear/Makefile new file mode 100644 index 0000000..5254c7c --- /dev/null +++ b/clear/Makefile @@ -0,0 +1,46 @@ +PRODUCT=$(notdir $(abspath $(CURDIR))) + +CC=i686-orion-gcc +CFLAGS= + +AS=i686-orion-as +AFLAGS= + +LD=i686-orion-gcc +LFLAGS= + +AS_SOURCES := $(shell find . -name '*.S') +OBJS = $(sort $(subst ./,build/,$(subst .S,.o,$(AS_SOURCES)))) + +C_SOURCES := $(shell find . -name '*.c') +OBJS += $(sort $(subst ./,build/,$(subst .c,.o,$(C_SOURCES)))) + +.PHONY: clean all install + +all: $(PRODUCT) + +clean: + @echo "REMOVING OBJECT FILES" + @mkdir -p build + @rm -rf build + @touch $(PRODUCT) + @rm $(PRODUCT) + +install: $(PRODUCT) + @echo "INSTALLING $^" + @mkdir -p ${SYSROOT}/bin/ + @install -Dm 755 $(PRODUCT) -t ${SYSROOT}/bin/ + +$(PRODUCT): $(OBJS) + @echo "LINKING $@" + @$(LD) -o $@ $^ $(LFLAGS) + +build/%.o: %.c + @echo "COMPILING $<" + @mkdir -p $(@D) + @$(CC) -c $< -o $@ $(CFLAGS) + +build/%.o: %.S + @echo "ASSEMBLING $<" + @mkdir -p $(@D) + @$(AS) $< -o $@ $(AFLAGS) diff --git a/clear/clear b/clear/clear new file mode 100755 index 0000000..59b13f6 Binary files /dev/null and b/clear/clear differ diff --git a/clear/main.c b/clear/main.c new file mode 100644 index 0000000..fefc064 --- /dev/null +++ b/clear/main.c @@ -0,0 +1,10 @@ +#include <stdio.h> + +/* Main function */ +int +main(int argc, char *argv[]) +{ + printf("\033[H\033[2J"); + + return 0; +} diff --git a/date/Makefile b/date/Makefile new file mode 100644 index 0000000..5254c7c --- /dev/null +++ b/date/Makefile @@ -0,0 +1,46 @@ +PRODUCT=$(notdir $(abspath $(CURDIR))) + +CC=i686-orion-gcc +CFLAGS= + +AS=i686-orion-as +AFLAGS= + +LD=i686-orion-gcc +LFLAGS= + +AS_SOURCES := $(shell find . -name '*.S') +OBJS = $(sort $(subst ./,build/,$(subst .S,.o,$(AS_SOURCES)))) + +C_SOURCES := $(shell find . -name '*.c') +OBJS += $(sort $(subst ./,build/,$(subst .c,.o,$(C_SOURCES)))) + +.PHONY: clean all install + +all: $(PRODUCT) + +clean: + @echo "REMOVING OBJECT FILES" + @mkdir -p build + @rm -rf build + @touch $(PRODUCT) + @rm $(PRODUCT) + +install: $(PRODUCT) + @echo "INSTALLING $^" + @mkdir -p ${SYSROOT}/bin/ + @install -Dm 755 $(PRODUCT) -t ${SYSROOT}/bin/ + +$(PRODUCT): $(OBJS) + @echo "LINKING $@" + @$(LD) -o $@ $^ $(LFLAGS) + +build/%.o: %.c + @echo "COMPILING $<" + @mkdir -p $(@D) + @$(CC) -c $< -o $@ $(CFLAGS) + +build/%.o: %.S + @echo "ASSEMBLING $<" + @mkdir -p $(@D) + @$(AS) $< -o $@ $(AFLAGS) diff --git a/date/date b/date/date new file mode 100755 index 0000000..0e0bee7 Binary files /dev/null and b/date/date differ diff --git a/date/main.c b/date/main.c new file mode 100644 index 0000000..2e35681 --- /dev/null +++ b/date/main.c @@ -0,0 +1,39 @@ +#include <stdio.h> +#include <time.h> + +#define LEAP_YEAR(x) ((((x % 4) == 0) && ((x % 100) != 0)) || ((x % 400) == 0)) + +/* Main function */ +int +main(int argc, char *argv[]) +{ + /* Length of months for normal and leap years */ + const uint16_t monthLen[2][12] = { + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} + }; + + uint8_t second, minute, hour, day, month; + time_t now = time(NULL); + uint32_t year = 1970, dayclock = now % 86400, dayno = now / 86400; + + second = dayclock % 60; + minute = (dayclock % 3600) / 60; + hour = dayclock / 3600; + while (dayno >= (LEAP_YEAR(year) ? 366 : 365)) { + dayno -= (LEAP_YEAR(year) ? 366 : 365); + year++; + } + year -= 1970; + month = 0; + while (dayno >= monthLen[LEAP_YEAR(year)][month]) { + dayno -= monthLen[LEAP_YEAR(year)][month]; + month++; + } + day = dayno + 1; + + printf("%.4d/%.2d/%.2d %.2d:%.2d:%.2d UTC\n", + year+1970, month+1, day+1, hour, minute, second); + + return 0; +} diff --git a/init/Makefile b/init/Makefile new file mode 100644 index 0000000..5254c7c --- /dev/null +++ b/init/Makefile @@ -0,0 +1,46 @@ +PRODUCT=$(notdir $(abspath $(CURDIR))) + +CC=i686-orion-gcc +CFLAGS= + +AS=i686-orion-as +AFLAGS= + +LD=i686-orion-gcc +LFLAGS= + +AS_SOURCES := $(shell find . -name '*.S') +OBJS = $(sort $(subst ./,build/,$(subst .S,.o,$(AS_SOURCES)))) + +C_SOURCES := $(shell find . -name '*.c') +OBJS += $(sort $(subst ./,build/,$(subst .c,.o,$(C_SOURCES)))) + +.PHONY: clean all install + +all: $(PRODUCT) + +clean: + @echo "REMOVING OBJECT FILES" + @mkdir -p build + @rm -rf build + @touch $(PRODUCT) + @rm $(PRODUCT) + +install: $(PRODUCT) + @echo "INSTALLING $^" + @mkdir -p ${SYSROOT}/bin/ + @install -Dm 755 $(PRODUCT) -t ${SYSROOT}/bin/ + +$(PRODUCT): $(OBJS) + @echo "LINKING $@" + @$(LD) -o $@ $^ $(LFLAGS) + +build/%.o: %.c + @echo "COMPILING $<" + @mkdir -p $(@D) + @$(CC) -c $< -o $@ $(CFLAGS) + +build/%.o: %.S + @echo "ASSEMBLING $<" + @mkdir -p $(@D) + @$(AS) $< -o $@ $(AFLAGS) diff --git a/init/init b/init/init new file mode 100755 index 0000000..5b641ac Binary files /dev/null and b/init/init differ diff --git a/init/main.c b/init/main.c new file mode 100644 index 0000000..0eb2b3b --- /dev/null +++ b/init/main.c @@ -0,0 +1,42 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/wait.h> + +/* Main function */ +int +main(int argc, char *argv[]) +{ + if (getpid() != 1) { + printf("init will not run except as PID#1"); + abort(); + } + + dbgprintf("Starting init"); + + /* Open standard descriptors */ + open("/dev/tty", O_RDONLY); + open("/dev/tty", O_WRONLY); + dup(1); + + printf("Welcome to \033[1;32mOrion\033[0m!\n"); + + int status; + pid_t child; + while (1) { + child = fork(); + if (!child) { + char *v[] = { "login", NULL }; + int err = execve("/bin/login", v, NULL); + if (err < 0) { + printf("init: %s: ", "/bin/login"); + perror(NULL); + while (1); + } + } else { + waitpid(child, &status, 0); + } + printf("\033[H\033[2J"); /* Clear screen */ + } +} diff --git a/login/Makefile b/login/Makefile new file mode 100644 index 0000000..5254c7c --- /dev/null +++ b/login/Makefile @@ -0,0 +1,46 @@ +PRODUCT=$(notdir $(abspath $(CURDIR))) + +CC=i686-orion-gcc +CFLAGS= + +AS=i686-orion-as +AFLAGS= + +LD=i686-orion-gcc +LFLAGS= + +AS_SOURCES := $(shell find . -name '*.S') +OBJS = $(sort $(subst ./,build/,$(subst .S,.o,$(AS_SOURCES)))) + +C_SOURCES := $(shell find . -name '*.c') +OBJS += $(sort $(subst ./,build/,$(subst .c,.o,$(C_SOURCES)))) + +.PHONY: clean all install + +all: $(PRODUCT) + +clean: + @echo "REMOVING OBJECT FILES" + @mkdir -p build + @rm -rf build + @touch $(PRODUCT) + @rm $(PRODUCT) + +install: $(PRODUCT) + @echo "INSTALLING $^" + @mkdir -p ${SYSROOT}/bin/ + @install -Dm 755 $(PRODUCT) -t ${SYSROOT}/bin/ + +$(PRODUCT): $(OBJS) + @echo "LINKING $@" + @$(LD) -o $@ $^ $(LFLAGS) + +build/%.o: %.c + @echo "COMPILING $<" + @mkdir -p $(@D) + @$(CC) -c $< -o $@ $(CFLAGS) + +build/%.o: %.S + @echo "ASSEMBLING $<" + @mkdir -p $(@D) + @$(AS) $< -o $@ $(AFLAGS) diff --git a/login/login b/login/login new file mode 100755 index 0000000..b45884b Binary files /dev/null and b/login/login differ diff --git a/login/main.c b/login/main.c new file mode 100644 index 0000000..d1bfd55 --- /dev/null +++ b/login/main.c @@ -0,0 +1,74 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <limits.h> +#include <sys/ioctl.h> +#include <termios.h> +#include <pwd.h> + +#define MANUAL_LOGIN + +/* Main function */ +int +main(int argc, char *argv[]) +{ + int fd, sz; + char *buf, *line, *input = malloc(1024); + + Passwd *pwd; + Termios tcold, tcnew; + + while (1) { + printf("\nUsername: "); + memset(input, 0, 1024); +#ifdef MANUAL_LOGIN + sz = read(STDIN_FILENO, input, 1024); +#else + printf("root\n"); + sz = 5; + memcpy(input, "root", 5); +#endif + input[--sz] = '\0'; + if (sz < 1) + continue; + + pwd = getpwname(input); + if (!pwd) + continue; + + printf("Password: "); + memset(input, 0, 1024); + ioctl(STDIN_FILENO, TCGETS, &tcold); + memcpy(&tcnew, &tcold, sizeof(Termios)); + tcnew.lflag &= ~ECHO; + ioctl(STDIN_FILENO, TCSETS, &tcnew); +#ifdef MANUAL_LOGIN + sz = read(STDIN_FILENO, input, 1024); +#else + printf("password\n"); + sz = 9; + memcpy(input, "password", 9); +#endif + input[--sz] = '\0'; + if (sz < 1) + continue; + ioctl(STDIN_FILENO, TCSETS, &tcold); + + if (!strcmp(input, pwd->password)) + break; + printf("Login incorrect\n"); + } + printf("\n"); + + dbgprintf("Authenticating \"%s\" (%d:%d) -> \"%s\" @ \"%s\"", + pwd->username, pwd->uid, pwd->gid, pwd->shell, pwd->homedir); + chdir(pwd->homedir); + setuid(pwd->uid); + setgid(pwd->gid); + char *v[] = { "sh", NULL }; + execve(pwd->shell, v, NULL); + + return 0; +} diff --git a/ls/Makefile b/ls/Makefile new file mode 100644 index 0000000..5254c7c --- /dev/null +++ b/ls/Makefile @@ -0,0 +1,46 @@ +PRODUCT=$(notdir $(abspath $(CURDIR))) + +CC=i686-orion-gcc +CFLAGS= + +AS=i686-orion-as +AFLAGS= + +LD=i686-orion-gcc +LFLAGS= + +AS_SOURCES := $(shell find . -name '*.S') +OBJS = $(sort $(subst ./,build/,$(subst .S,.o,$(AS_SOURCES)))) + +C_SOURCES := $(shell find . -name '*.c') +OBJS += $(sort $(subst ./,build/,$(subst .c,.o,$(C_SOURCES)))) + +.PHONY: clean all install + +all: $(PRODUCT) + +clean: + @echo "REMOVING OBJECT FILES" + @mkdir -p build + @rm -rf build + @touch $(PRODUCT) + @rm $(PRODUCT) + +install: $(PRODUCT) + @echo "INSTALLING $^" + @mkdir -p ${SYSROOT}/bin/ + @install -Dm 755 $(PRODUCT) -t ${SYSROOT}/bin/ + +$(PRODUCT): $(OBJS) + @echo "LINKING $@" + @$(LD) -o $@ $^ $(LFLAGS) + +build/%.o: %.c + @echo "COMPILING $<" + @mkdir -p $(@D) + @$(CC) -c $< -o $@ $(CFLAGS) + +build/%.o: %.S + @echo "ASSEMBLING $<" + @mkdir -p $(@D) + @$(AS) $< -o $@ $(AFLAGS) diff --git a/ls/arg.h b/ls/arg.h new file mode 100644 index 0000000..9022339 --- /dev/null +++ b/ls/arg.h @@ -0,0 +1,42 @@ +#ifndef ARG_H +#define ARG_H + +extern char *progname; + +#define ARGBEGIN for (progname = *argv, argv++, argc--; \ + argc && argv[0] && argv[0][0] == '-' \ + && argv[0][1]; \ + argc--, argv++) { \ + char argc_, **argv_; \ + int brk_; \ + if (argv[0][1] == '-' && argv[0][2] == '\0') { \ + argv++; \ + argc--; \ + break; \ + } \ + int i_; \ + for (i_ = 1, brk_ = 0, argv_ = argv; \ + argv[0][i_] && !brk_; \ + i_++) { \ + if (argv_ != argv) \ + break; \ + argc_ = argv[0][i_]; \ + switch (argc_) +#define ARGEND } \ + } + +#define ARGC() argc_ + +#define EARGF(x) ((argv[0][i_+1] == '\0' && argv[1] == NULL) ? \ + ((x), abort(), (char *) 0) : \ + (brk_ = 1, (argv[0][i_+1] != '\0') ? \ + (&argv[0][i_+1]) : \ + (argc--, argv++, argv[0]))) + +#define ARGF() ((argv[0][i_+1] == '\0' && argv[1] == NULL) ? \ + (char *) 0 : \ + (brk_ = 1, (argv[0][i_+1] != '\0') ? \ + (&argv[0][i_+1]) : \ + (argc--, argv++, argv[0]))) + +#endif diff --git a/ls/ls b/ls/ls new file mode 100755 index 0000000..0921d86 Binary files /dev/null and b/ls/ls differ diff --git a/ls/main.c b/ls/main.c new file mode 100644 index 0000000..27b754c --- /dev/null +++ b/ls/main.c @@ -0,0 +1,320 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <dirent.h> +#include <termios.h> +#include <pwd.h> +#include <grp.h> + +char *progname; +#include "arg.h" + +Winsize termsz; +int allFlag = 0; +int longFlag = 0; + +/* Structure for a result */ +typedef struct Result Result; +struct Result { + Result *next, *prev; + ino_t ino; + enum DirType type; + size_t namelen; + char name[255]; + Stat stat; +}; + +/* Compare results by name */ +static int +compare_name(Result *a, Result *b) +{ + return (strcmp(a->name, b->name) < 0); +} + +/* Compare results by type */ +static int +compare_type(Result *a, Result *b) +{ + return (a->type == DT_DIR && b->type != DT_DIR); +} + +/* Sort a list of results */ +static Result * +sort_results(Result *head, int (*compare)(Result *, Result *)) +{ + Result *curr, *shead = NULL, *slast, *scurr; + int i, len = 0; + for (curr = head; curr; curr = curr->next) + len++; + + /* Sort */ + for (i = 0; i < len; i++) { + scurr = head; + for (curr = head->next; curr; curr = curr->next) { + if (compare(curr, scurr)) + scurr = curr; + } + + /* Unlink from old list */ + if (scurr == head) + head = scurr->next; + if (scurr->next) + scurr->next->prev = scurr->prev; + if (scurr->prev) + scurr->prev->next = scurr->next; + scurr->prev = scurr->next = NULL; + + /* Add to sorted list */ + if (!shead) { + shead = scurr; + } else { + scurr->prev = slast; + slast->next = scurr; + } + slast = scurr; + } + + return shead; +} + +/* Print normal results */ +static void +print_normal(Result *head) +{ + Result *curr, *next, *prev; + size_t printed = 0; + + for (curr = head; curr; curr = next) { + prev = curr->prev; + next = curr->next; + + int executable = 0; + if ((curr->stat.mode & S_IXUSR) + || (curr->stat.mode & S_IXGRP) + || (curr->stat.mode & S_IXOTH)) + executable = 1; + + if (curr->type == DT_DIR) + printf("\033[1;34m%s\033[0m ", curr->name); + else if (curr->type == DT_CHR || curr->type == DT_BLK) + printf("\033[1;33m%s\033[0m ", curr->name); + else if (curr->type == DT_LNK) + printf("\033[1;36m%s\033[0m ", curr->name); + else if (curr->type == DT_REG && executable) + printf("\033[1;32m%s\033[0m ", curr->name); + else + printf("%s ", curr->name); + printed++; + + /* Remove from list */ + if (prev) + prev->next = next; + if (next) + next->prev = prev; + if (curr == head) + head = next; + free(curr); + } + if (printed) + putchar('\n'); +} + +/* Print long results */ +static void +print_long(Result *head) +{ + Result *curr, *next, *prev; + size_t printed = 0; + + /* Find max column widths */ + size_t total = 0; + int linkWidth = 0, unameWidth = 0, groupWidth = 0, sizeWidth = 0; + for (curr = head; curr; curr = curr->next) { + int linkTmp = curr->stat.nlink, linkWidthTmp = 1; + while (linkTmp /= 10) + linkWidthTmp++; + if (linkWidthTmp > linkWidth) + linkWidth = linkWidthTmp; + + Passwd *pwd = getpwuid(curr->stat.uid); + if (strlen(pwd->username) > unameWidth) + unameWidth = strlen(pwd->username); + Group *grp = getgrgid(curr->stat.gid); + if (strlen(grp->name) > groupWidth) + groupWidth = strlen(grp->name); + + int sizeTmp = curr->stat.size, sizeWidthTmp = 1; + while (sizeTmp /= 10) + sizeWidthTmp++; + if (sizeWidthTmp > sizeWidth) + sizeWidth = sizeWidthTmp; + + total += (curr->stat.size + (1024 - 1)) / 1024; + } + + /* Print out */ + printf("total %d\n", total); + for (curr = head; curr; curr = next) { + prev = curr->prev; + next = curr->next; + + char perm[] = "----------"; + char type[] = "?-dcbfsl"; + char uname[33], group[33]; + int executable = 0; + perm[0] = type[curr->type]; + perm[1] = (curr->stat.mode & S_IRUSR) ? 'r' : '-'; + perm[2] = (curr->stat.mode & S_IWUSR) ? 'w' : '-'; + perm[3] = (curr->stat.mode & S_IXUSR) ? 'x' : '-'; + perm[4] = (curr->stat.mode & S_IRGRP) ? 'r' : '-'; + perm[5] = (curr->stat.mode & S_IWGRP) ? 'w' : '-'; + perm[6] = (curr->stat.mode & S_IXGRP) ? 'x' : '-'; + perm[7] = (curr->stat.mode & S_IROTH) ? 'r' : '-'; + perm[8] = (curr->stat.mode & S_IWOTH) ? 'w' : '-'; + perm[9] = (curr->stat.mode & S_IXOTH) ? 'x' : '-'; + Passwd *pwd = getpwuid(curr->stat.uid); + Group *grp = getgrgid(curr->stat.gid); + if ((curr->stat.mode & S_IXUSR) + || (curr->stat.mode & S_IXGRP) + || (curr->stat.mode & S_IXOTH)) + executable = 1; + + printf("%s %*d %*s %*s %*d ", perm, + linkWidth, curr->stat.nlink, + -unameWidth, pwd->username, + -groupWidth, grp->name, + sizeWidth, curr->stat.size); + + if (curr->type == DT_DIR) + printf("\033[1;34m%s\033[0m\n", curr->name); + else if (curr->type == DT_CHR || curr->type == DT_BLK) + printf("\033[1;33m%s\033[0m\n", curr->name); + else if (curr->type == DT_LNK) + printf("\033[1;36m%s\033[0m\n", curr->name); + else if (curr->type == DT_REG && executable) + printf("\033[1;32m%s\033[0m\n", curr->name); + else + printf("%s\n", curr->name); + printed++; + + /* Remove from list */ + if (prev) + prev->next = next; + if (next) + next->prev = prev; + if (curr == head) + head = next; + free(curr); + } +} + +/* List files in a directory */ +static void +ls(char *name) +{ + int fd, sz, i; + char *buf, cwd[1024]; + struct stat statbuf; + struct dirent *de; + + Result *head = NULL, *prev = NULL, *next, *curr; + size_t len = 0, longest = 0; + + fd = open(name, O_RDONLY); + if (fd < 0) { + printf("%s: %s: ", progname, name); + perror(NULL); + return; + } + + stat(name, &statbuf); + if (!S_ISDIR(statbuf.mode)) { + close(fd); + return; + } + + getcwd(cwd, 1024); + chdir(name); + + /* Get Directory Entries */ + buf = malloc(512); + sz = getdents(fd, buf, 512); + for (de = (void *) buf; + de < (struct dirent *) (buf + sz); + de = (void *) de + de->namelen + sizeof(struct dirent)) { + if (de->name[0] == '.' && !allFlag) + continue; + curr = malloc(sizeof(Result)); + curr->next = NULL; + curr->prev = prev; + curr->ino = de->ino; + curr->type = de->type; + curr->namelen = de->namelen; + memcpy(curr->name, de->name, de->namelen); + curr->name[de->namelen] = '\0'; + stat(curr->name, &curr->stat); + if (prev) + prev->next = curr; + else + head = curr; + prev = curr; + len++; + + if (longest < curr->namelen) + longest = curr->namelen; + } + free(buf); + close(fd); + + head = sort_results(head, compare_name); + head = sort_results(head, compare_type); + + if (longFlag) + print_long(head); + else + print_normal(head); + + chdir(cwd); +} + +/* Main function */ +int +main(int argc, char *argv[]) +{ + int i; + ioctl(STDOUT_FILENO, TCGWINSZ, &termsz); + + ARGBEGIN { + case 'a': + allFlag = 1; + break; + case 'l': + longFlag = 1; + break; + default: + printf("Usage:\n"); + } ARGEND; + + if (argc == 0) { + ls("."); + return 0; + } + + if (argc == 1) { + ls(argv[0]); + return 0; + } + + for (i = 0; i < argc; i++) { + printf("%s:\n", argv[i]); + ls(argv[i]); + if (i < argc-1) + printf("\n"); + } + + return 0; +} diff --git a/pwd/Makefile b/pwd/Makefile new file mode 100644 index 0000000..5254c7c --- /dev/null +++ b/pwd/Makefile @@ -0,0 +1,46 @@ +PRODUCT=$(notdir $(abspath $(CURDIR))) + +CC=i686-orion-gcc +CFLAGS= + +AS=i686-orion-as +AFLAGS= + +LD=i686-orion-gcc +LFLAGS= + +AS_SOURCES := $(shell find . -name '*.S') +OBJS = $(sort $(subst ./,build/,$(subst .S,.o,$(AS_SOURCES)))) + +C_SOURCES := $(shell find . -name '*.c') +OBJS += $(sort $(subst ./,build/,$(subst .c,.o,$(C_SOURCES)))) + +.PHONY: clean all install + +all: $(PRODUCT) + +clean: + @echo "REMOVING OBJECT FILES" + @mkdir -p build + @rm -rf build + @touch $(PRODUCT) + @rm $(PRODUCT) + +install: $(PRODUCT) + @echo "INSTALLING $^" + @mkdir -p ${SYSROOT}/bin/ + @install -Dm 755 $(PRODUCT) -t ${SYSROOT}/bin/ + +$(PRODUCT): $(OBJS) + @echo "LINKING $@" + @$(LD) -o $@ $^ $(LFLAGS) + +build/%.o: %.c + @echo "COMPILING $<" + @mkdir -p $(@D) + @$(CC) -c $< -o $@ $(CFLAGS) + +build/%.o: %.S + @echo "ASSEMBLING $<" + @mkdir -p $(@D) + @$(AS) $< -o $@ $(AFLAGS) diff --git a/pwd/main.c b/pwd/main.c new file mode 100644 index 0000000..be5c76f --- /dev/null +++ b/pwd/main.c @@ -0,0 +1,14 @@ +#include <stdio.h> +#include <unistd.h> +#include <sys/limits.h> + +/* Main function */ +int +main(int argc, char *argv[]) +{ + char cwd[PATH_MAX]; + getcwd(cwd, PATH_MAX); + printf("%s\n", cwd); + + return 0; +} diff --git a/pwd/pwd b/pwd/pwd new file mode 100755 index 0000000..4cc5f35 Binary files /dev/null and b/pwd/pwd differ diff --git a/sh/Makefile b/sh/Makefile new file mode 100644 index 0000000..5254c7c --- /dev/null +++ b/sh/Makefile @@ -0,0 +1,46 @@ +PRODUCT=$(notdir $(abspath $(CURDIR))) + +CC=i686-orion-gcc +CFLAGS= + +AS=i686-orion-as +AFLAGS= + +LD=i686-orion-gcc +LFLAGS= + +AS_SOURCES := $(shell find . -name '*.S') +OBJS = $(sort $(subst ./,build/,$(subst .S,.o,$(AS_SOURCES)))) + +C_SOURCES := $(shell find . -name '*.c') +OBJS += $(sort $(subst ./,build/,$(subst .c,.o,$(C_SOURCES)))) + +.PHONY: clean all install + +all: $(PRODUCT) + +clean: + @echo "REMOVING OBJECT FILES" + @mkdir -p build + @rm -rf build + @touch $(PRODUCT) + @rm $(PRODUCT) + +install: $(PRODUCT) + @echo "INSTALLING $^" + @mkdir -p ${SYSROOT}/bin/ + @install -Dm 755 $(PRODUCT) -t ${SYSROOT}/bin/ + +$(PRODUCT): $(OBJS) + @echo "LINKING $@" + @$(LD) -o $@ $^ $(LFLAGS) + +build/%.o: %.c + @echo "COMPILING $<" + @mkdir -p $(@D) + @$(CC) -c $< -o $@ $(CFLAGS) + +build/%.o: %.S + @echo "ASSEMBLING $<" + @mkdir -p $(@D) + @$(AS) $< -o $@ $(AFLAGS) diff --git a/sh/main.c b/sh/main.c new file mode 100644 index 0000000..d1319ad --- /dev/null +++ b/sh/main.c @@ -0,0 +1,131 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/mount.h> +#include <limits.h> +#include <sys/wait.h> +#include <signal.h> +#include <dirent.h> +#include <errno.h> +#include <pwd.h> + +#define PS1 "\033[1;31m%s\033[0m@\033[1m%s\033[0m:\033[1;32m%s\033[0m$> " + +int argparser(char *str, char **res); + +/* Get the nice current working directory */ +static void +shell_getcwd(char *cwd, char *homedir) +{ + getcwd(cwd, PATH_MAX); + /* Replace the homedir with "~" */ + if (!strncmp(cwd, homedir, strlen(homedir))) { + strncpy(cwd + 1, cwd + strlen(homedir), + PATH_MAX - strlen(homedir)); + cwd[0] = '~'; + } +} + +/* Main function */ +int +main(int argc, char *argv[]) +{ + int fd, sz, i; + char *buf; + struct stat statbuf; + struct dirent *de; + + /* Get username */ + uid_t uid = getuid(); + char *hostname, *username, *cwd, *homedir, *line, *ptr; + username = malloc(33); + homedir = malloc(PATH_MAX); + Passwd *pwd = getpwuid(uid); + strcpy(username, pwd->username); + strcpy(homedir, pwd->homedir); + + /* Get hostname */ + hostname = malloc(HOST_NAME_MAX + 1); + fd = open("/etc/hostname", O_RDONLY); + sz = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + read(fd, hostname, sz - 1); + close(fd); + + /* Get current working directory */ + cwd = malloc(PATH_MAX); + shell_getcwd(cwd, homedir); + + line = malloc(1024); + pid_t child; + int err, count, status; + char *v[256], filename[PATH_MAX] = {'/','b','i','n','/'}; + while (1) { + printf(PS1, username, hostname, cwd); + memset(line, 0, 1024); + sz = read(STDIN_FILENO, line, 1024); + + line[--sz] = '\0'; + if (sz < 1) + continue; + + count = argparser(line, v); + + /* Change directory (built-in) */ + if (!strcmp(v[0], "cd")) { + err = chdir(v[1]); + if (err < 0) { + printf("%s: cd: ", argv[0]); + perror(NULL); + } else { + shell_getcwd(cwd, homedir); + } + continue; + } + /* Exit (built-in) */ + if (!strcmp(v[0], "exit")) + exit(0); + + /* Check if program exists */ + memcpy(filename+5, v[0], PATH_MAX-5); + err = stat(filename, NULL); + if (err < 0) { + if (errno == ENOENT) { + printf("%s: %s: Command not found\n", + argv[0], v[0]); + } else { + printf("%s: %s: ", argv[0], v[0]); + perror(NULL); + } + continue; + } + + /* Execute program */ + child = fork(); + if (!child) { + err = execv(filename, v); + if (err < 0) { + printf("%s: %s: ", argv[0], v[0]); + perror(NULL); + } + exit(EXIT_FAILURE); + } else { + if (waitpid(child, &status, 0) < 0) + perror("waitpid"); + if (WIFEXITED(status) && WEXITSTATUS(status)) + printf("Exited with status %d\n", + WEXITSTATUS(status)); + if (WIFSIGNALED(status) && WTERMSIG(status)) { + switch (WTERMSIG(status)) { + case SIGSEGV: + printf("Segmentation fault\n"); + break; + } + } + } + child = 0; + } +} diff --git a/sh/parser.c b/sh/parser.c new file mode 100644 index 0000000..6c0af04 --- /dev/null +++ b/sh/parser.c @@ -0,0 +1,24 @@ +#include <string.h> + +/* Split a string into separate strings */ +int +argparser(char *str, char **res) +{ + int count = 0; + char *finder; + + memset(res, 0, 1024); + finder = str; + while (*finder == ' ') finder++; + res[count++] = finder; + while (*finder) { + if (*finder == ' ') { + res[count++] = finder + 1; + *finder = '\0'; + } + finder++; + } + res[count] = NULL; + + return count; +} diff --git a/sh/sh b/sh/sh new file mode 100755 index 0000000..6326a89 Binary files /dev/null and b/sh/sh differ diff --git a/time/Makefile b/time/Makefile new file mode 100644 index 0000000..5254c7c --- /dev/null +++ b/time/Makefile @@ -0,0 +1,46 @@ +PRODUCT=$(notdir $(abspath $(CURDIR))) + +CC=i686-orion-gcc +CFLAGS= + +AS=i686-orion-as +AFLAGS= + +LD=i686-orion-gcc +LFLAGS= + +AS_SOURCES := $(shell find . -name '*.S') +OBJS = $(sort $(subst ./,build/,$(subst .S,.o,$(AS_SOURCES)))) + +C_SOURCES := $(shell find . -name '*.c') +OBJS += $(sort $(subst ./,build/,$(subst .c,.o,$(C_SOURCES)))) + +.PHONY: clean all install + +all: $(PRODUCT) + +clean: + @echo "REMOVING OBJECT FILES" + @mkdir -p build + @rm -rf build + @touch $(PRODUCT) + @rm $(PRODUCT) + +install: $(PRODUCT) + @echo "INSTALLING $^" + @mkdir -p ${SYSROOT}/bin/ + @install -Dm 755 $(PRODUCT) -t ${SYSROOT}/bin/ + +$(PRODUCT): $(OBJS) + @echo "LINKING $@" + @$(LD) -o $@ $^ $(LFLAGS) + +build/%.o: %.c + @echo "COMPILING $<" + @mkdir -p $(@D) + @$(CC) -c $< -o $@ $(CFLAGS) + +build/%.o: %.S + @echo "ASSEMBLING $<" + @mkdir -p $(@D) + @$(AS) $< -o $@ $(AFLAGS) diff --git a/time/main.c b/time/main.c new file mode 100644 index 0000000..89ef9ab --- /dev/null +++ b/time/main.c @@ -0,0 +1,44 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/times.h> +#include <sys/wait.h> +#include <errno.h> + +/* Main function */ +int +main(int argc, char *argv[]) +{ + pid_t pid; + Times tms; + clock_t r0, r1; + int status, ret = 0; + + if (argc < 2) + return 0; + + r0 = times(&tms); + + pid = fork(); + if (!pid) { + execv(argv[1], argv + 1); + printf("exec: %s: ", argv[1]); + perror(NULL); + exit(EXIT_FAILURE); + } + waitpid(pid, &status, 0); + + if ((r1 = times(&tms)) == (clock_t) -1) { + perror("times"); + exit(EXIT_FAILURE); + } + + printf("\nreal %dms\nuser %dms\nsys %dms\n", + (r1 - r0), tms.cutime, tms.cstime); +// printf("\nreal %f\nuser %f\nsys %f\n", +// (r1 - r0) / (double) 1000, +// tms.cutime / (double) 1000, +// tms.cstime / (double) 1000); + + return 0; +} diff --git a/time/time b/time/time new file mode 100755 index 0000000..cf03725 Binary files /dev/null and b/time/time differ