esh_init.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. #include "esh_types.h"
  2. #include "esh_misc.h"
  3. #include "esh_init.h"
  4. EShInfo* esh_info_global;
  5. void EShInit(int argc, char** argv) {
  6. EShInitInfo(argc, argv);
  7. EShParseCommandLineArgs(argc, argv);
  8. EShProcessConfigFile();
  9. EShProcessHistoryFile();
  10. printf("\n"
  11. "===================================\n"
  12. "Hello, %s!\n"
  13. "This is Endevir Shell (ESh)\n"
  14. "ESh build %.8s\n"
  15. "\n"
  16. "Home directory: %s\n"
  17. "Default shell program: %s\n"
  18. "Config file path: %s\n"
  19. "===================================\n"
  20. "\n",
  21. esh_info_global->user_data->pw_name,
  22. esh_info_global->build_ref,
  23. esh_info_global->user_data->pw_dir,
  24. esh_info_global->user_data->pw_shell,
  25. esh_info_global->config_file_path);
  26. }
  27. void EShInitInfo(int argc, char** argv) {
  28. esh_info_global = malloc(sizeof(EShInfo));
  29. esh_info_global->build_ref = malloc((strlen(BUILD_REF) + 1) * sizeof(char));
  30. strcpy(esh_info_global->build_ref, BUILD_REF);
  31. esh_info_global->user_data = getpwuid(geteuid());
  32. esh_info_global->current_working_dir = malloc((PATH_MAX + 1) * sizeof(char));
  33. memset(esh_info_global->current_working_dir, 0, (PATH_MAX + 1) * sizeof(char));
  34. getcwd(esh_info_global->current_working_dir, PATH_MAX);
  35. EShOptimiseCurrentWorkingDirectory();
  36. esh_info_global->config_file_path = malloc((PATH_MAX + 1) * sizeof(char));
  37. memset(esh_info_global->config_file_path, 0, (PATH_MAX + 1) * sizeof(char));
  38. strcat(esh_info_global->config_file_path, esh_info_global->user_data->pw_dir);
  39. strcat(esh_info_global->config_file_path, "/.esh_conf");
  40. esh_info_global->history_file_path = malloc((PATH_MAX + 1) * sizeof(char));
  41. memset(esh_info_global->history_file_path, 0, (PATH_MAX + 1) * sizeof(char));
  42. strcat(esh_info_global->history_file_path, esh_info_global->user_data->pw_dir);
  43. strcat(esh_info_global->history_file_path, "/.esh_history");
  44. esh_info_global->history_limit = 5000;
  45. esh_info_global->max_jobs_number = 64;
  46. esh_info_global->max_command_length = 512;
  47. esh_info_global->max_command_tokens = 16;
  48. esh_info_global->max_command_token_size = 256;
  49. esh_info_global->jobs_number = 0;
  50. esh_info_global->history_command_list = malloc((esh_info_global->history_limit + 1) * sizeof(char*));
  51. esh_info_global->history_command_list_size = 0;
  52. esh_info_global->max_invite_message_len = 2048;
  53. esh_info_global->invite_message = malloc((esh_info_global->max_invite_message_len + 1) * sizeof(char));
  54. EShUpdateInviteMessage();
  55. esh_info_global->exited = 0;
  56. }
  57. void EShParseCommandLineArgs(int argc, char** argv) {
  58. for (int i = 1; i < argc; i += 2) {
  59. if (strcmp(argv[i], "-h") == 0) {
  60. EShShowHelpAndExit();
  61. }
  62. if (i + 1 >= argc) {
  63. printf("ERROR: Incorrect command-line parameters number!");
  64. exit(1);
  65. }
  66. if (strcmp(argv[i], "-config") == 0) {
  67. strcpy(esh_info_global->config_file_path, argv[i + 1]);
  68. }
  69. if (strcmp(argv[i], "-history_path") == 0) {
  70. strcpy(esh_info_global->history_file_path, argv[i + 1]);
  71. }
  72. if (strcmp(argv[i], "-history_limit") == 0) {
  73. sscanf(argv[i + 1], "%d", &esh_info_global->history_limit);
  74. }
  75. if (strcmp(argv[i], "-max_active_jobs") == 0) {
  76. sscanf(argv[i + 1], "%d", &esh_info_global->max_jobs_number);
  77. }
  78. if (strcmp(argv[i], "-max_command_length") == 0) {
  79. sscanf(argv[i + 1], "%d", &esh_info_global->max_command_length);
  80. }
  81. }
  82. }
  83. void EShProcessConfigFile() {
  84. FILE* file = fopen(esh_info_global->config_file_path, "r");
  85. if (!file) {
  86. return;
  87. }
  88. char* line = NULL;
  89. ssize_t len = 0;
  90. int line_length = 0;
  91. while ((line_length = getline(&line, &len, file)) != -1) {
  92. if (line[line_length - 1] == '\n') {
  93. line[line_length - 1] = '\0';
  94. --line_length;
  95. }
  96. if (strstr(line, "history_path=") == line) {
  97. strcpy(esh_info_global->history_file_path, line + strlen("history_path="));
  98. }
  99. if (strstr(line, "history_limit=") == line) {
  100. sscanf(line + strlen("history_limit="), "%d", &esh_info_global->history_limit);
  101. }
  102. if (strstr(line, "max_active_jobs=") == line) {
  103. sscanf(line + strlen("max_active_jobs="), "%d", &esh_info_global->max_jobs_number);
  104. }
  105. if (strstr(line, "max_command_length=") == line) {
  106. sscanf(line + strlen("max_command_length="), "%d", &esh_info_global->max_command_length);
  107. }
  108. }
  109. fclose(file);
  110. }
  111. void EShProcessHistoryFile() {
  112. FILE* file = fopen(esh_info_global->history_file_path, "r");
  113. if (!file) {
  114. return;
  115. }
  116. char* line = NULL;
  117. ssize_t len = 0;
  118. int line_length = 0;
  119. while ((line_length = getline(&line, &len, file)) != -1) {
  120. if (line[line_length - 1] == '\n') {
  121. line[line_length - 1] = '\0';
  122. --line_length;
  123. }
  124. esh_info_global->history_command_list[esh_info_global->history_command_list_size] = malloc(strlen(line) + 1);
  125. strcpy(esh_info_global->history_command_list[esh_info_global->history_command_list_size], line);
  126. ++esh_info_global->history_command_list_size;
  127. }
  128. fclose(file);
  129. }
  130. void EShInitJob(EShJob* job) {
  131. job->command = malloc(esh_info_global->max_command_length);
  132. memset(job->command, 0, esh_info_global->max_command_length);
  133. job->command_tokens = malloc(esh_info_global->max_command_tokens * sizeof(char*));
  134. for (int i = 0; i < esh_info_global->max_command_tokens; ++i) {
  135. job->command_tokens[i] = malloc(esh_info_global->max_command_token_size);
  136. memset(job->command_tokens[i], 0, esh_info_global->max_command_token_size);
  137. }
  138. job->command_tokens_num = 0;
  139. job->job_type = FOREGROUND;
  140. job->job_start_condition = NO_CONDITION;
  141. job->job_pid = -1;
  142. job->stdin_fd = -1;
  143. job->stdout_fd = -1;
  144. job->stderr_fd = -1;
  145. }
  146. EShJob* EShMakeJobsList() {
  147. EShJob* jobs_list = malloc(esh_info_global->max_jobs_number * sizeof(EShJob));
  148. for (int i = 0; i < esh_info_global->max_jobs_number; ++i) {
  149. EShInitJob(&jobs_list[i]);
  150. }
  151. return jobs_list;
  152. }