From 49ee634822b835e56876b2900e916e20499a635e Mon Sep 17 00:00:00 2001 From: EnderIce2 Date: Sun, 16 Mar 2025 00:54:59 +0000 Subject: [PATCH] feat(userspace/coreutils): add alias command Signed-off-by: EnderIce2 --- Userspace/coreutils/src/alias.c | 225 ++++++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 Userspace/coreutils/src/alias.c diff --git a/Userspace/coreutils/src/alias.c b/Userspace/coreutils/src/alias.c new file mode 100644 index 00000000..7370cd6e --- /dev/null +++ b/Userspace/coreutils/src/alias.c @@ -0,0 +1,225 @@ +/* + This file is part of Fennix Core Utilities. + + Fennix Core Utilities is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Core Utilities is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Core Utilities. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +typedef struct alias_t +{ + char *name; + char *value; + struct alias_t *next; +} alias_t; + +alias_t *aliases = NULL; + +void FreeAliases() +{ + alias_t *current = aliases; + while (current != NULL) + { + alias_t *next = current->next; + free(current->name); + free(current->value); + free(current); + current = next; + } + aliases = NULL; +} + +alias_t *FindAlias(const char *name) +{ + alias_t *current = aliases; + while (current != NULL) + { + if (strcmp(current->name, name) == 0) + return current; + current = current->next; + } + return NULL; +} + +void AddAlias(const char *name, const char *value) +{ + alias_t *existing = FindAlias(name); + if (existing) + { + free(existing->value); + existing->value = strdup(value); + return; + } + + alias_t *new_alias = malloc(sizeof(alias_t)); + new_alias->name = strdup(name); + new_alias->value = strdup(value); + new_alias->next = aliases; + aliases = new_alias; +} + +int ReadAliases(const char *filename) +{ + FILE *file = fopen(filename, "r"); + if (!file) + return -1; + + char *line = NULL; + size_t len = 0; + ssize_t read; + + while ((read = getline(&line, &len, file)) != -1) + { + if (line[read - 1] == '\n') + line[read - 1] = '\0'; + + char *eq = strchr(line, '='); + if (!eq) + continue; + *eq = '\0'; + + AddAlias(line, eq + 1); + } + + free(line); + fclose(file); + return 0; +} + +int WriteAliases(const char *filename) +{ + FILE *file = fopen(filename, "w"); + if (!file) + { + perror("Error writing aliases"); + return -1; + } + + alias_t *current = aliases; + while (current) + { + fprintf(file, "%s=%s\n", current->name, current->value); + current = current->next; + } + + fclose(file); + return 0; +} + +char *QuoteValue(const char *value) +{ + size_t quotes = 0; + for (const char *p = value; *p; p++) + { + if (*p == '\'') + quotes++; + } + + char *quoted = malloc(strlen(value) + quotes * 4 + 3); + if (!quoted) + return NULL; + + char *dest = quoted; + *dest++ = '\''; + for (const char *p = value; *p; p++) + { + if (*p == '\'') + { + strcpy(dest, "'\\''"); + dest += 4; + } + else + *dest++ = *p; + } + *dest++ = '\''; + *dest = '\0'; + return quoted; +} + +int main(int argc, char *argv[]) +{ + const char *home = getenv("HOME"); + if (!home) + { + fprintf(stderr, "alias: HOME not set\n"); + return 2; + } + + char path[1024]; + snprintf(path, sizeof(path), "%s/.aliases", home); + + if (ReadAliases(path) == -1 && errno != ENOENT) + { + perror("Error reading aliases"); + return 2; + } + + int status = 0; + if (argc == 1) + { + alias_t *current = aliases; + while (current) + { + char *q = QuoteValue(current->value); + printf("alias %s=%s\n", current->name, q); + free(q); + current = current->next; + } + } + else + { + for (int i = 1; i < argc; i++) + { + char *arg = argv[i]; + char *eq = strchr(arg, '='); + + if (eq) + { + *eq = '\0'; + char *name = arg; + char *value = eq + 1; + AddAlias(name, value); + + char *q = QuoteValue(value); + printf("alias %s=%s\n", name, q); + free(q); + } + else + { + alias_t *a = FindAlias(arg); + if (a) + { + char *q = QuoteValue(a->value); + printf("alias %s=%s\n", a->name, q); + free(q); + } + else + { + fprintf(stderr, "alias: %s: not found\n", arg); + status = 1; + } + } + } + } + + if (WriteAliases(path) == -1) + status = 1; + FreeAliases(); + return status; +}