aboutsummaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
authoriceyrazor <iceyrazor@mailfence.com>2026-02-09 13:24:11 -0600
committericeyrazor <iceyrazor@mailfence.com>2026-02-09 13:24:11 -0600
commited16684cf50e2525072861cfd06e19ca4410b54f (patch)
treef22adc89e78371535dcc0414515c1edb3aef5838 /src/main.c
init
Diffstat (limited to 'src/main.c')
-rwxr-xr-xsrc/main.c239
1 files changed, 239 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
new file mode 100755
index 0000000..e07319a
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,239 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#define LSH_RL_BUFSIZE 1024
+char *lsh_read_line(void)
+{
+ int bufsize = LSH_RL_BUFSIZE;
+ int position = 0;
+ char *buffer = malloc(sizeof(char) * bufsize);
+ int c;
+
+ if (!buffer) {
+ fprintf(stderr, "lsh: allocation error\n");
+ exit(EXIT_FAILURE);
+ }
+
+ while (1) {
+ // Read a character
+ c = getchar();
+
+ // If we hit EOF, replace it with a null character and return.
+ if (c == EOF || c == '\n') {
+ buffer[position] = '\0';
+ return buffer;
+ } else {
+ buffer[position] = c;
+ }
+ position++;
+
+ // If we have exceeded the buffer, reallocate.
+ if (position >= bufsize) {
+ bufsize += LSH_RL_BUFSIZE;
+ buffer = realloc(buffer, bufsize);
+ if (!buffer) {
+ fprintf(stderr, "lsh: allocation error\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+ }
+}
+
+#define LSH_TOK_BUFSIZE 64
+#define LSH_TOK_DELIM " \t\r\n\a"
+char **lsh_split_line(char *line)
+{
+ int bufsize = LSH_TOK_BUFSIZE, position = 0;
+ char **tokens = malloc(bufsize * sizeof(char*));
+ char *token;
+
+ if (!tokens) {
+ fprintf(stderr, "lsh: allocation error\n");
+ exit(EXIT_FAILURE);
+ }
+
+ token = strtok(line, LSH_TOK_DELIM);
+ while (token != NULL) {
+ tokens[position] = token;
+ position++;
+
+ if (position >= bufsize) {
+ bufsize += LSH_TOK_BUFSIZE;
+ tokens = realloc(tokens, bufsize * sizeof(char*));
+ if (!tokens) {
+ fprintf(stderr, "lsh: allocation error\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ token = strtok(NULL, LSH_TOK_DELIM);
+ }
+ tokens[position] = NULL;
+ return tokens;
+}
+
+int lsh_launch(char **args)
+{
+ pid_t pid, wpid;
+ int status;
+
+ pid = fork();
+ if (pid == 0) {
+ // Child process
+ if (execvp(args[0], args) == -1) {
+ perror("lsh");
+ }
+ exit(EXIT_FAILURE);
+ } else if (pid < 0) {
+ // Error forking
+ perror("lsh");
+ } else {
+ // Parent process
+ do {
+ wpid = waitpid(pid, &status, WUNTRACED);
+ } while (!WIFEXITED(status) && !WIFSIGNALED(status));
+ }
+
+ return 1;
+}
+
+/*
+ Function Declarations for builtin shell commands:
+ */
+int lsh_cd(char **args);
+int lsh_help(char **args);
+int lsh_exit(char **args);
+
+/*
+ List of builtin commands, followed by their corresponding functions.
+ */
+char *builtin_str[] = {
+ "cd",
+ "help",
+ "exit"
+};
+
+int (*builtin_func[]) (char **) = {
+ &lsh_cd,
+ &lsh_help,
+ &lsh_exit
+};
+
+int lsh_num_builtins() {
+ return sizeof(builtin_str) / sizeof(char *);
+}
+
+/*
+ Builtin function implementations.
+*/
+int lsh_cd(char **args)
+{
+ if (args[1] == NULL) {
+ fprintf(stderr, "lsh: expected argument to \"cd\"\n");
+ } else {
+ if (chdir(args[1]) != 0) {
+ perror("lsh");
+ }
+ }
+ return 1;
+}
+
+int lsh_help(char **args)
+{
+ int i;
+ printf("Stephen Brennan's LSH\n");
+ printf("Type program names and arguments, and hit enter.\n");
+ printf("The following are built in:\n");
+
+ for (i = 0; i < lsh_num_builtins(); i++) {
+ printf(" %s\n", builtin_str[i]);
+ }
+
+ printf("Use the man command for information on other programs.\n");
+ return 1;
+}
+
+int lsh_exit(char **args)
+{
+ return 0;
+}
+
+
+
+int lsh_execute(char **args)
+{
+ int i;
+
+ if (args[0] == NULL) {
+ // An empty command was entered.
+ return 1;
+ }
+
+ for (i = 0; i < lsh_num_builtins(); i++) {
+ if (strcmp(args[0], builtin_str[i]) == 0) {
+ return (*builtin_func[i])(args);
+ }
+ }
+
+ return lsh_launch(args);
+}
+
+
+typedef struct{
+ char *prompt;
+} SHELL_OB;
+
+void lsh_loop(SHELL_OB *shell_obj)
+{
+ char *line;
+ char **args;
+ int status;
+
+ do {
+ printf("%s",shell_obj->prompt);
+ line = lsh_read_line();
+ args = lsh_split_line(line);
+ status = lsh_execute(args);
+
+ free(line);
+ free(args);
+ } while (status);
+}
+
+int main(int argc, char **argv){
+ SHELL_OB shell_obj;
+
+ //very jank lol
+ char *hostname = NULL;
+ long file_size;
+ FILE *hostfile = fopen("/etc/hostname","r");
+ if (hostfile != NULL){
+ fseek(hostfile, 0, SEEK_END);
+ file_size = ftell(hostfile);
+ rewind(hostfile);
+
+ hostname = (char *)malloc(file_size + 1 + 24);
+ fread(hostname, file_size, 1, hostfile);
+ hostname[file_size+1] = '\0';
+
+ fclose(hostfile);
+
+ for (int i = file_size-1; i > -1; i--){
+ hostname[i+1] = hostname[i];
+ }
+ hostname[0] = '@';
+ hostname[file_size] = '\0';
+ } else {
+ hostname = (char *)malloc(1);
+ hostname[0] = '\0';
+ }
+ shell_obj.prompt=strcat(strcat(getenv("USER"), (char *)hostname), "> ");
+
+ lsh_loop(&shell_obj);
+
+ free(hostname);
+ return EXIT_SUCCESS;
+}