#include "esh_types.h" #include "esh_misc.h" #include "esh_init.h" EShInfo* esh_info_global; void EShInit(int argc, char** argv) { EShInitInfo(argc, argv); EShParseCommandLineArgs(argc, argv); EShProcessConfigFile(); EShProcessHistoryFile(); printf("\n" "===================================\n" "Hello, %s!\n" "This is Endevir Shell (ESh)\n" "ESh build %.8s\n" "\n" "Home directory: %s\n" "Default shell program: %s\n" "Config file path: %s\n" "===================================\n" "\n", esh_info_global->user_data->pw_name, esh_info_global->build_ref, esh_info_global->user_data->pw_dir, esh_info_global->user_data->pw_shell, esh_info_global->config_file_path); } void EShInitInfo(int argc, char** argv) { esh_info_global = malloc(sizeof(EShInfo)); esh_info_global->build_ref = malloc((strlen(BUILD_REF) + 1) * sizeof(char)); strcpy(esh_info_global->build_ref, BUILD_REF); esh_info_global->user_data = getpwuid(geteuid()); esh_info_global->current_working_dir = malloc((PATH_MAX + 1) * sizeof(char)); memset(esh_info_global->current_working_dir, 0, (PATH_MAX + 1) * sizeof(char)); getcwd(esh_info_global->current_working_dir, PATH_MAX); EShOptimiseCurrentWorkingDirectory(); esh_info_global->config_file_path = malloc((PATH_MAX + 1) * sizeof(char)); memset(esh_info_global->config_file_path, 0, (PATH_MAX + 1) * sizeof(char)); strcat(esh_info_global->config_file_path, esh_info_global->user_data->pw_dir); strcat(esh_info_global->config_file_path, "/.esh_conf"); esh_info_global->history_file_path = malloc((PATH_MAX + 1) * sizeof(char)); memset(esh_info_global->history_file_path, 0, (PATH_MAX + 1) * sizeof(char)); strcat(esh_info_global->history_file_path, esh_info_global->user_data->pw_dir); strcat(esh_info_global->history_file_path, "/.esh_history"); esh_info_global->history_limit = 5000; esh_info_global->max_jobs_number = 64; esh_info_global->max_command_length = 512; esh_info_global->max_command_tokens = 16; esh_info_global->max_command_token_size = 256; esh_info_global->jobs_number = 0; esh_info_global->history_command_list = malloc((esh_info_global->history_limit + 1) * sizeof(char*)); esh_info_global->history_command_list_size = 0; esh_info_global->max_invite_message_len = 2048; esh_info_global->invite_message = malloc((esh_info_global->max_invite_message_len + 1) * sizeof(char)); EShUpdateInviteMessage(); esh_info_global->exited = 0; } void EShParseCommandLineArgs(int argc, char** argv) { for (int i = 1; i < argc; i += 2) { if (strcmp(argv[i], "-h") == 0) { EShShowHelpAndExit(); } if (i + 1 >= argc) { printf("ERROR: Incorrect command-line parameters number!"); exit(1); } if (strcmp(argv[i], "-config") == 0) { strcpy(esh_info_global->config_file_path, argv[i + 1]); } if (strcmp(argv[i], "-history_path") == 0) { strcpy(esh_info_global->history_file_path, argv[i + 1]); } if (strcmp(argv[i], "-history_limit") == 0) { sscanf(argv[i + 1], "%d", &esh_info_global->history_limit); } if (strcmp(argv[i], "-max_active_jobs") == 0) { sscanf(argv[i + 1], "%d", &esh_info_global->max_jobs_number); } if (strcmp(argv[i], "-max_command_length") == 0) { sscanf(argv[i + 1], "%d", &esh_info_global->max_command_length); } } } void EShProcessConfigFile() { FILE* file = fopen(esh_info_global->config_file_path, "r"); if (!file) { return; } char* line = NULL; ssize_t len = 0; int line_length = 0; while ((line_length = getline(&line, &len, file)) != -1) { if (line[line_length - 1] == '\n') { line[line_length - 1] = '\0'; --line_length; } if (strstr(line, "history_path=") == line) { strcpy(esh_info_global->history_file_path, line + strlen("history_path=")); } if (strstr(line, "history_limit=") == line) { sscanf(line + strlen("history_limit="), "%d", &esh_info_global->history_limit); } if (strstr(line, "max_active_jobs=") == line) { sscanf(line + strlen("max_active_jobs="), "%d", &esh_info_global->max_jobs_number); } if (strstr(line, "max_command_length=") == line) { sscanf(line + strlen("max_command_length="), "%d", &esh_info_global->max_command_length); } } fclose(file); } void EShProcessHistoryFile() { FILE* file = fopen(esh_info_global->history_file_path, "r"); if (!file) { return; } char* line = NULL; ssize_t len = 0; int line_length = 0; while ((line_length = getline(&line, &len, file)) != -1) { if (line[line_length - 1] == '\n') { line[line_length - 1] = '\0'; --line_length; } esh_info_global->history_command_list[esh_info_global->history_command_list_size] = malloc(strlen(line) + 1); strcpy(esh_info_global->history_command_list[esh_info_global->history_command_list_size], line); ++esh_info_global->history_command_list_size; } fclose(file); } void EShInitJob(EShJob* job) { job->command = malloc(esh_info_global->max_command_length); memset(job->command, 0, esh_info_global->max_command_length); job->command_tokens = malloc(esh_info_global->max_command_tokens * sizeof(char*)); for (int i = 0; i < esh_info_global->max_command_tokens; ++i) { job->command_tokens[i] = malloc(esh_info_global->max_command_token_size); memset(job->command_tokens[i], 0, esh_info_global->max_command_token_size); } job->command_tokens_num = 0; job->job_type = FOREGROUND; job->job_start_condition = NO_CONDITION; job->job_pid = -1; job->stdin_fd = -1; job->stdout_fd = -1; job->stderr_fd = -1; } EShJob* EShMakeJobsList() { EShJob* jobs_list = malloc(esh_info_global->max_jobs_number * sizeof(EShJob)); for (int i = 0; i < esh_info_global->max_jobs_number; ++i) { EShInitJob(&jobs_list[i]); } return jobs_list; }