added this file
This commit is contained in:
813
aliases.c
813
aliases.c
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* aliases.c
|
||||
* Implementation of shell alias functionality
|
||||
* Implementation of shell alias functionality this is a test
|
||||
*/
|
||||
|
||||
#include "aliases.h"
|
||||
@@ -21,496 +21,501 @@ char aliases_file_path[PATH_MAX];
|
||||
* Initialize the alias system
|
||||
*/
|
||||
void init_aliases(void) {
|
||||
// Set initial capacity
|
||||
alias_capacity = 10;
|
||||
aliases = (AliasEntry*)malloc(alias_capacity * sizeof(AliasEntry));
|
||||
|
||||
if (!aliases) {
|
||||
fprintf(stderr, "lsh: allocation error in init_aliases\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine aliases file location - in user's home directory
|
||||
char *home_dir = getenv("HOME");
|
||||
if (home_dir) {
|
||||
snprintf(aliases_file_path, PATH_MAX, "%s/.lsh_aliases", home_dir);
|
||||
} else {
|
||||
// Fallback to current directory if HOME not available
|
||||
strcpy(aliases_file_path, ".lsh_aliases");
|
||||
}
|
||||
|
||||
// Load aliases from file
|
||||
load_aliases();
|
||||
// Set initial capacity
|
||||
alias_capacity = 10;
|
||||
aliases = (AliasEntry *)malloc(alias_capacity * sizeof(AliasEntry));
|
||||
|
||||
if (!aliases) {
|
||||
fprintf(stderr, "lsh: allocation error in init_aliases\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine aliases file location - in user's home directory
|
||||
char *home_dir = getenv("HOME");
|
||||
if (home_dir) {
|
||||
snprintf(aliases_file_path, PATH_MAX, "%s/.lsh_aliases", home_dir);
|
||||
} else {
|
||||
// Fallback to current directory if HOME not available
|
||||
strcpy(aliases_file_path, ".lsh_aliases");
|
||||
}
|
||||
|
||||
// Load aliases from file
|
||||
load_aliases();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up the alias system
|
||||
*/
|
||||
void cleanup_aliases(void) {
|
||||
if (!aliases) return;
|
||||
|
||||
// Free all alias entries
|
||||
for (int i = 0; i < alias_count; i++) {
|
||||
free(aliases[i].name);
|
||||
free(aliases[i].command);
|
||||
}
|
||||
|
||||
// Free the array
|
||||
free(aliases);
|
||||
aliases = NULL;
|
||||
alias_count = 0;
|
||||
alias_capacity = 0;
|
||||
if (!aliases)
|
||||
return;
|
||||
|
||||
// Free all alias entries
|
||||
for (int i = 0; i < alias_count; i++) {
|
||||
free(aliases[i].name);
|
||||
free(aliases[i].command);
|
||||
}
|
||||
|
||||
// Free the array
|
||||
free(aliases);
|
||||
aliases = NULL;
|
||||
alias_count = 0;
|
||||
alias_capacity = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown the alias system
|
||||
*/
|
||||
void shutdown_aliases(void) {
|
||||
// Clean up (don't save here since we save immediately on changes)
|
||||
cleanup_aliases();
|
||||
// Clean up (don't save here since we save immediately on changes)
|
||||
cleanup_aliases();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load aliases from file
|
||||
*/
|
||||
int load_aliases(void) {
|
||||
FILE *fp = fopen(aliases_file_path, "r");
|
||||
if (!fp) {
|
||||
return 0; // File doesn't exist or can't be opened
|
||||
FILE *fp = fopen(aliases_file_path, "r");
|
||||
if (!fp) {
|
||||
return 0; // File doesn't exist or can't be opened
|
||||
}
|
||||
|
||||
// Set loading flag to prevent saving during loading
|
||||
loading_aliases = 1;
|
||||
|
||||
char line[LSH_RL_BUFSIZE];
|
||||
char name[LSH_RL_BUFSIZE / 2];
|
||||
char command[LSH_RL_BUFSIZE / 2];
|
||||
|
||||
while (fgets(line, sizeof(line), fp)) {
|
||||
// Skip comments and empty lines
|
||||
if (line[0] == '#' || line[0] == '\n') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Set loading flag to prevent saving during loading
|
||||
loading_aliases = 1;
|
||||
|
||||
char line[LSH_RL_BUFSIZE];
|
||||
char name[LSH_RL_BUFSIZE / 2];
|
||||
char command[LSH_RL_BUFSIZE / 2];
|
||||
|
||||
while (fgets(line, sizeof(line), fp)) {
|
||||
// Skip comments and empty lines
|
||||
if (line[0] == '#' || line[0] == '\n') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Parse alias definitions (name=command)
|
||||
char *equals = strchr(line, '=');
|
||||
if (equals) {
|
||||
*equals = '\0';
|
||||
char *line_name = line;
|
||||
char *line_command = equals + 1;
|
||||
|
||||
// Remove newline from command if present
|
||||
char *newline = strchr(line_command, '\n');
|
||||
if (newline) {
|
||||
*newline = '\0';
|
||||
}
|
||||
|
||||
// Trim whitespace
|
||||
while (*line_name == ' ' || *line_name == '\t') line_name++;
|
||||
while (*line_command == ' ' || *line_command == '\t') line_command++;
|
||||
|
||||
if (*line_name && *line_command) {
|
||||
add_alias(line_name, line_command);
|
||||
}
|
||||
}
|
||||
|
||||
// Parse alias definitions (name=command)
|
||||
char *equals = strchr(line, '=');
|
||||
if (equals) {
|
||||
*equals = '\0';
|
||||
char *line_name = line;
|
||||
char *line_command = equals + 1;
|
||||
|
||||
// Remove newline from command if present
|
||||
char *newline = strchr(line_command, '\n');
|
||||
if (newline) {
|
||||
*newline = '\0';
|
||||
}
|
||||
|
||||
// Trim whitespace
|
||||
while (*line_name == ' ' || *line_name == '\t')
|
||||
line_name++;
|
||||
while (*line_command == ' ' || *line_command == '\t')
|
||||
line_command++;
|
||||
|
||||
if (*line_name && *line_command) {
|
||||
add_alias(line_name, line_command);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear loading flag
|
||||
loading_aliases = 0;
|
||||
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Clear loading flag
|
||||
loading_aliases = 0;
|
||||
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save aliases to file
|
||||
*/
|
||||
int save_aliases(void) {
|
||||
FILE *fp = fopen(aliases_file_path, "w");
|
||||
if (!fp) {
|
||||
fprintf(stderr, "lsh: error saving aliases to %s\n", aliases_file_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Write file header
|
||||
time_t t = time(NULL);
|
||||
struct tm *tm_info = localtime(&t);
|
||||
char timestamp[26];
|
||||
strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", tm_info);
|
||||
|
||||
fprintf(fp, "# LSH Aliases - Last updated: %s\n\n", timestamp);
|
||||
|
||||
// Write each alias
|
||||
for (int i = 0; i < alias_count; i++) {
|
||||
fprintf(fp, "%s=%s\n", aliases[i].name, aliases[i].command);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return 1;
|
||||
FILE *fp = fopen(aliases_file_path, "w");
|
||||
if (!fp) {
|
||||
fprintf(stderr, "lsh: error saving aliases to %s\n", aliases_file_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Write file header
|
||||
time_t t = time(NULL);
|
||||
struct tm *tm_info = localtime(&t);
|
||||
char timestamp[26];
|
||||
strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", tm_info);
|
||||
|
||||
fprintf(fp, "# LSH Aliases - Last updated: %s\n\n", timestamp);
|
||||
|
||||
// Write each alias
|
||||
for (int i = 0; i < alias_count; i++) {
|
||||
fprintf(fp, "%s=%s\n", aliases[i].name, aliases[i].command);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new alias
|
||||
*/
|
||||
int add_alias(const char *name, const char *command) {
|
||||
if (!name || !command) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check if alias already exists, update it if it does
|
||||
for (int i = 0; i < alias_count; i++) {
|
||||
if (strcmp(aliases[i].name, name) == 0) {
|
||||
// Update existing alias
|
||||
free(aliases[i].command);
|
||||
aliases[i].command = strdup(command);
|
||||
// Save aliases immediately after updating (unless loading)
|
||||
if (!loading_aliases) {
|
||||
save_aliases();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we need to expand the array
|
||||
if (alias_count >= alias_capacity) {
|
||||
alias_capacity *= 2;
|
||||
AliasEntry *new_aliases = (AliasEntry*)realloc(aliases, alias_capacity * sizeof(AliasEntry));
|
||||
if (!new_aliases) {
|
||||
fprintf(stderr, "lsh: allocation error in add_alias\n");
|
||||
return 0;
|
||||
}
|
||||
aliases = new_aliases;
|
||||
}
|
||||
|
||||
// Add new alias
|
||||
aliases[alias_count].name = strdup(name);
|
||||
aliases[alias_count].command = strdup(command);
|
||||
alias_count++;
|
||||
|
||||
// Save aliases immediately after adding (unless loading)
|
||||
if (!loading_aliases) {
|
||||
if (!name || !command) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check if alias already exists, update it if it does
|
||||
for (int i = 0; i < alias_count; i++) {
|
||||
if (strcmp(aliases[i].name, name) == 0) {
|
||||
// Update existing alias
|
||||
free(aliases[i].command);
|
||||
aliases[i].command = strdup(command);
|
||||
// Save aliases immediately after updating (unless loading)
|
||||
if (!loading_aliases) {
|
||||
save_aliases();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Check if we need to expand the array
|
||||
if (alias_count >= alias_capacity) {
|
||||
alias_capacity *= 2;
|
||||
AliasEntry *new_aliases =
|
||||
(AliasEntry *)realloc(aliases, alias_capacity * sizeof(AliasEntry));
|
||||
if (!new_aliases) {
|
||||
fprintf(stderr, "lsh: allocation error in add_alias\n");
|
||||
return 0;
|
||||
}
|
||||
aliases = new_aliases;
|
||||
}
|
||||
|
||||
// Add new alias
|
||||
aliases[alias_count].name = strdup(name);
|
||||
aliases[alias_count].command = strdup(command);
|
||||
alias_count++;
|
||||
|
||||
// Save aliases immediately after adding (unless loading)
|
||||
if (!loading_aliases) {
|
||||
save_aliases();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an alias
|
||||
*/
|
||||
int remove_alias(const char *name) {
|
||||
if (!name) {
|
||||
return 0;
|
||||
if (!name) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < alias_count; i++) {
|
||||
if (strcmp(aliases[i].name, name) == 0) {
|
||||
// Free memory for this alias
|
||||
free(aliases[i].name);
|
||||
free(aliases[i].command);
|
||||
|
||||
// Shift remaining aliases down
|
||||
for (int j = i; j < alias_count - 1; j++) {
|
||||
aliases[j] = aliases[j + 1];
|
||||
}
|
||||
|
||||
alias_count--;
|
||||
// Save aliases immediately after removing (unless loading)
|
||||
if (!loading_aliases) {
|
||||
save_aliases();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < alias_count; i++) {
|
||||
if (strcmp(aliases[i].name, name) == 0) {
|
||||
// Free memory for this alias
|
||||
free(aliases[i].name);
|
||||
free(aliases[i].command);
|
||||
|
||||
// Shift remaining aliases down
|
||||
for (int j = i; j < alias_count - 1; j++) {
|
||||
aliases[j] = aliases[j + 1];
|
||||
}
|
||||
|
||||
alias_count--;
|
||||
// Save aliases immediately after removing (unless loading)
|
||||
if (!loading_aliases) {
|
||||
save_aliases();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0; // Alias not found
|
||||
}
|
||||
|
||||
return 0; // Alias not found
|
||||
}
|
||||
|
||||
/**
|
||||
* Find an alias by name
|
||||
*/
|
||||
AliasEntry* find_alias(const char *name) {
|
||||
for (int i = 0; i < alias_count; i++) {
|
||||
if (strcmp(aliases[i].name, name) == 0) {
|
||||
return &aliases[i];
|
||||
}
|
||||
AliasEntry *find_alias(const char *name) {
|
||||
for (int i = 0; i < alias_count; i++) {
|
||||
if (strcmp(aliases[i].name, name) == 0) {
|
||||
return &aliases[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand a command line by replacing aliases
|
||||
*/
|
||||
char* expand_aliases(const char *command) {
|
||||
if (!command) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *result = strdup(command);
|
||||
if (!result) return NULL;
|
||||
|
||||
// Copy the command for tokenization
|
||||
char *cmd_copy = strdup(result);
|
||||
if (!cmd_copy) {
|
||||
free(result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Extract the first word (command name)
|
||||
char *token = strtok(cmd_copy, " \t");
|
||||
if (!token) {
|
||||
free(cmd_copy);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Look up the alias
|
||||
AliasEntry *alias = find_alias(token);
|
||||
if (alias) {
|
||||
// Get the args after the command
|
||||
char *args = strchr(command, ' ');
|
||||
|
||||
// Allocate new buffer for expanded command
|
||||
free(result);
|
||||
if (args) {
|
||||
// Concatenate alias command and original args
|
||||
result = malloc(strlen(alias->command) + strlen(args) + 1);
|
||||
if (result) {
|
||||
strcpy(result, alias->command);
|
||||
strcat(result, args);
|
||||
}
|
||||
} else {
|
||||
// No args, just use alias command
|
||||
result = strdup(alias->command);
|
||||
}
|
||||
}
|
||||
|
||||
char *expand_aliases(const char *command) {
|
||||
if (!command) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *result = strdup(command);
|
||||
if (!result)
|
||||
return NULL;
|
||||
|
||||
// Copy the command for tokenization
|
||||
char *cmd_copy = strdup(result);
|
||||
if (!cmd_copy) {
|
||||
free(result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Extract the first word (command name)
|
||||
char *token = strtok(cmd_copy, " \t");
|
||||
if (!token) {
|
||||
free(cmd_copy);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Look up the alias
|
||||
AliasEntry *alias = find_alias(token);
|
||||
if (alias) {
|
||||
// Get the args after the command
|
||||
char *args = strchr(command, ' ');
|
||||
|
||||
// Allocate new buffer for expanded command
|
||||
free(result);
|
||||
if (args) {
|
||||
// Concatenate alias command and original args
|
||||
result = malloc(strlen(alias->command) + strlen(args) + 1);
|
||||
if (result) {
|
||||
strcpy(result, alias->command);
|
||||
strcat(result, args);
|
||||
}
|
||||
} else {
|
||||
// No args, just use alias command
|
||||
result = strdup(alias->command);
|
||||
}
|
||||
}
|
||||
|
||||
free(cmd_copy);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Command handler for the "alias" command
|
||||
*/
|
||||
int lsh_alias(char **args) {
|
||||
// No arguments - list all aliases
|
||||
if (args[1] == NULL) {
|
||||
for (int i = 0; i < alias_count; i++) {
|
||||
printf("alias %s='%s'\n", aliases[i].name, aliases[i].command);
|
||||
}
|
||||
return 1;
|
||||
// No arguments - list all aliases
|
||||
if (args[1] == NULL) {
|
||||
for (int i = 0; i < alias_count; i++) {
|
||||
printf("alias %s='%s'\n", aliases[i].name, aliases[i].command);
|
||||
}
|
||||
|
||||
// Pre-defined aliases
|
||||
if (strcmp(args[1], "vim-mode") == 0) {
|
||||
// Configure aliases for Vim-like operation
|
||||
add_alias("v", "vim");
|
||||
|
||||
// Check for neovim first
|
||||
FILE *test_nvim = popen("which nvim 2>/dev/null", "r");
|
||||
if (test_nvim) {
|
||||
char buffer[128];
|
||||
if (fgets(buffer, sizeof(buffer), test_nvim) != NULL) {
|
||||
// Neovim found, use it as preferred editor
|
||||
pclose(test_nvim);
|
||||
add_alias("e", "nvim");
|
||||
printf("Vim mode activated (using Neovim)\n");
|
||||
return 1;
|
||||
}
|
||||
pclose(test_nvim);
|
||||
|
||||
// Check for regular vim
|
||||
FILE *test_vim = popen("which vim 2>/dev/null", "r");
|
||||
if (test_vim) {
|
||||
char buffer[128];
|
||||
if (fgets(buffer, sizeof(buffer), test_vim) != NULL) {
|
||||
// Vim found
|
||||
pclose(test_vim);
|
||||
add_alias("e", "vim");
|
||||
printf("Vim mode activated\n");
|
||||
return 1;
|
||||
}
|
||||
pclose(test_vim);
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to vi if neither vim nor neovim is found
|
||||
add_alias("e", "vi");
|
||||
printf("Vim mode activated (using vi)\n");
|
||||
return 1;
|
||||
} else if (strcmp(args[1], "emacs-mode") == 0) {
|
||||
// Configure aliases for Emacs-like operation
|
||||
FILE *test_emacs = popen("which emacs 2>/dev/null", "r");
|
||||
if (test_emacs) {
|
||||
char buffer[128];
|
||||
if (fgets(buffer, sizeof(buffer), test_emacs) != NULL) {
|
||||
pclose(test_emacs);
|
||||
add_alias("e", "emacs -nw");
|
||||
printf("Emacs mode activated\n");
|
||||
return 1;
|
||||
}
|
||||
pclose(test_emacs);
|
||||
}
|
||||
|
||||
printf("Emacs not found. Emacs mode not activated.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Format: alias name=command
|
||||
char *equals = strchr(args[1], '=');
|
||||
if (equals) {
|
||||
// Split at equals sign
|
||||
*equals = '\0';
|
||||
char *name = args[1];
|
||||
char *command = equals + 1;
|
||||
|
||||
// Remove quotes around command if present
|
||||
if (*command == '\'' || *command == '"') {
|
||||
command++;
|
||||
char *end = command + strlen(command) - 1;
|
||||
if (*end == '\'' || *end == '"') {
|
||||
*end = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
add_alias(name, command);
|
||||
printf("Alias added: %s='%s'\n", name, command);
|
||||
} else if (args[2] != NULL) {
|
||||
// Format: alias name command
|
||||
add_alias(args[1], args[2]);
|
||||
printf("Alias added: %s='%s'\n", args[1], args[2]);
|
||||
} else {
|
||||
// Just a name - show this specific alias
|
||||
AliasEntry *alias = find_alias(args[1]);
|
||||
if (alias) {
|
||||
printf("alias %s='%s'\n", alias->name, alias->command);
|
||||
} else {
|
||||
printf("Alias '%s' not found\n", args[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Pre-defined aliases
|
||||
if (strcmp(args[1], "vim-mode") == 0) {
|
||||
// Configure aliases for Vim-like operation
|
||||
add_alias("v", "vim");
|
||||
|
||||
// Check for neovim first
|
||||
FILE *test_nvim = popen("which nvim 2>/dev/null", "r");
|
||||
if (test_nvim) {
|
||||
char buffer[128];
|
||||
if (fgets(buffer, sizeof(buffer), test_nvim) != NULL) {
|
||||
// Neovim found, use it as preferred editor
|
||||
pclose(test_nvim);
|
||||
add_alias("e", "nvim");
|
||||
printf("Vim mode activated (using Neovim)\n");
|
||||
return 1;
|
||||
}
|
||||
pclose(test_nvim);
|
||||
|
||||
// Check for regular vim
|
||||
FILE *test_vim = popen("which vim 2>/dev/null", "r");
|
||||
if (test_vim) {
|
||||
char buffer[128];
|
||||
if (fgets(buffer, sizeof(buffer), test_vim) != NULL) {
|
||||
// Vim found
|
||||
pclose(test_vim);
|
||||
add_alias("e", "vim");
|
||||
printf("Vim mode activated\n");
|
||||
return 1;
|
||||
}
|
||||
pclose(test_vim);
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to vi if neither vim nor neovim is found
|
||||
add_alias("e", "vi");
|
||||
printf("Vim mode activated (using vi)\n");
|
||||
return 1;
|
||||
} else if (strcmp(args[1], "emacs-mode") == 0) {
|
||||
// Configure aliases for Emacs-like operation
|
||||
FILE *test_emacs = popen("which emacs 2>/dev/null", "r");
|
||||
if (test_emacs) {
|
||||
char buffer[128];
|
||||
if (fgets(buffer, sizeof(buffer), test_emacs) != NULL) {
|
||||
pclose(test_emacs);
|
||||
add_alias("e", "emacs -nw");
|
||||
printf("Emacs mode activated\n");
|
||||
return 1;
|
||||
}
|
||||
pclose(test_emacs);
|
||||
}
|
||||
|
||||
printf("Emacs not found. Emacs mode not activated.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Format: alias name=command
|
||||
char *equals = strchr(args[1], '=');
|
||||
if (equals) {
|
||||
// Split at equals sign
|
||||
*equals = '\0';
|
||||
char *name = args[1];
|
||||
char *command = equals + 1;
|
||||
|
||||
// Remove quotes around command if present
|
||||
if (*command == '\'' || *command == '"') {
|
||||
command++;
|
||||
char *end = command + strlen(command) - 1;
|
||||
if (*end == '\'' || *end == '"') {
|
||||
*end = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
add_alias(name, command);
|
||||
printf("Alias added: %s='%s'\n", name, command);
|
||||
} else if (args[2] != NULL) {
|
||||
// Format: alias name command
|
||||
add_alias(args[1], args[2]);
|
||||
printf("Alias added: %s='%s'\n", args[1], args[2]);
|
||||
} else {
|
||||
// Just a name - show this specific alias
|
||||
AliasEntry *alias = find_alias(args[1]);
|
||||
if (alias) {
|
||||
printf("alias %s='%s'\n", alias->name, alias->command);
|
||||
} else {
|
||||
printf("Alias '%s' not found\n", args[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Command handler for the "unalias" command
|
||||
*/
|
||||
int lsh_unalias(char **args) {
|
||||
if (args[1] == NULL) {
|
||||
printf("unalias: missing argument\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (remove_alias(args[1])) {
|
||||
printf("Alias '%s' removed\n", args[1]);
|
||||
} else {
|
||||
printf("Alias '%s' not found\n", args[1]);
|
||||
}
|
||||
|
||||
if (args[1] == NULL) {
|
||||
printf("unalias: missing argument\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (remove_alias(args[1])) {
|
||||
printf("Alias '%s' removed\n", args[1]);
|
||||
} else {
|
||||
printf("Alias '%s' not found\n", args[1]);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Command handler to show all aliases
|
||||
*/
|
||||
int lsh_aliases(char **args) {
|
||||
for (int i = 0; i < alias_count; i++) {
|
||||
printf("alias %s='%s'\n", aliases[i].name, aliases[i].command);
|
||||
}
|
||||
return 1;
|
||||
for (int i = 0; i < alias_count; i++) {
|
||||
printf("alias %s='%s'\n", aliases[i].name, aliases[i].command);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get alias names for tab completion
|
||||
*/
|
||||
char** get_alias_names(int *count) {
|
||||
if (alias_count == 0 || !count) {
|
||||
*count = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char **names = (char**)malloc(alias_count * sizeof(char*));
|
||||
if (!names) {
|
||||
*count = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < alias_count; i++) {
|
||||
names[i] = strdup(aliases[i].name);
|
||||
}
|
||||
|
||||
*count = alias_count;
|
||||
return names;
|
||||
char **get_alias_names(int *count) {
|
||||
if (alias_count == 0 || !count) {
|
||||
*count = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char **names = (char **)malloc(alias_count * sizeof(char *));
|
||||
if (!names) {
|
||||
*count = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < alias_count; i++) {
|
||||
names[i] = strdup(aliases[i].name);
|
||||
}
|
||||
|
||||
*count = alias_count;
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand alias in args array
|
||||
*/
|
||||
char** expand_alias(char **args) {
|
||||
if (!args || !args[0]) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Check if the command is an alias
|
||||
AliasEntry *alias = find_alias(args[0]);
|
||||
if (!alias) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Count tokens in alias command
|
||||
char *alias_copy = strdup(alias->command);
|
||||
if (!alias_copy) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char **alias_tokens = malloc(LSH_TOK_BUFSIZE * sizeof(char*));
|
||||
if (!alias_tokens) {
|
||||
free(alias_copy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *token, *rest = alias_copy;
|
||||
int token_count = 0;
|
||||
|
||||
while ((token = strtok_r(rest, " \t", &rest)) != NULL) {
|
||||
alias_tokens[token_count++] = strdup(token);
|
||||
|
||||
if (token_count >= LSH_TOK_BUFSIZE) {
|
||||
fprintf(stderr, "lsh: alias expansion: too many tokens\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char **expand_alias(char **args) {
|
||||
if (!args || !args[0]) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Check if the command is an alias
|
||||
AliasEntry *alias = find_alias(args[0]);
|
||||
if (!alias) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Count tokens in alias command
|
||||
char *alias_copy = strdup(alias->command);
|
||||
if (!alias_copy) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char **alias_tokens = malloc(LSH_TOK_BUFSIZE * sizeof(char *));
|
||||
if (!alias_tokens) {
|
||||
free(alias_copy);
|
||||
|
||||
// Count original arguments
|
||||
int arg_count = 0;
|
||||
while (args[arg_count] != NULL) {
|
||||
arg_count++;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *token, *rest = alias_copy;
|
||||
int token_count = 0;
|
||||
|
||||
while ((token = strtok_r(rest, " \t", &rest)) != NULL) {
|
||||
alias_tokens[token_count++] = strdup(token);
|
||||
|
||||
if (token_count >= LSH_TOK_BUFSIZE) {
|
||||
fprintf(stderr, "lsh: alias expansion: too many tokens\n");
|
||||
break;
|
||||
}
|
||||
|
||||
// Allocate space for expanded command
|
||||
char **expanded_args = malloc((token_count + arg_count) * sizeof(char*));
|
||||
if (!expanded_args) {
|
||||
for (int i = 0; i < token_count; i++) {
|
||||
free(alias_tokens[i]);
|
||||
}
|
||||
free(alias_tokens);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Copy alias tokens
|
||||
}
|
||||
|
||||
free(alias_copy);
|
||||
|
||||
// Count original arguments
|
||||
int arg_count = 0;
|
||||
while (args[arg_count] != NULL) {
|
||||
arg_count++;
|
||||
}
|
||||
|
||||
// Allocate space for expanded command
|
||||
char **expanded_args = malloc((token_count + arg_count) * sizeof(char *));
|
||||
if (!expanded_args) {
|
||||
for (int i = 0; i < token_count; i++) {
|
||||
expanded_args[i] = alias_tokens[i];
|
||||
free(alias_tokens[i]);
|
||||
}
|
||||
|
||||
// Copy remaining arguments (skip the command)
|
||||
for (int i = 1; i < arg_count; i++) {
|
||||
expanded_args[token_count + i - 1] = strdup(args[i]);
|
||||
}
|
||||
|
||||
// Null-terminate the array
|
||||
expanded_args[token_count + arg_count - 1] = NULL;
|
||||
|
||||
free(alias_tokens);
|
||||
return expanded_args;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Copy alias tokens
|
||||
for (int i = 0; i < token_count; i++) {
|
||||
expanded_args[i] = alias_tokens[i];
|
||||
}
|
||||
|
||||
// Copy remaining arguments (skip the command)
|
||||
for (int i = 1; i < arg_count; i++) {
|
||||
expanded_args[token_count + i - 1] = strdup(args[i]);
|
||||
}
|
||||
|
||||
// Null-terminate the array
|
||||
expanded_args[token_count + arg_count - 1] = NULL;
|
||||
|
||||
free(alias_tokens);
|
||||
return expanded_args;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user