esh_init.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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. "Commands history file path: %s\n"
  20. "Max history lines: %d\n"
  21. "Max running jobs: %d\n"
  22. "Max single command length: %d\n"
  23. "===================================\n"
  24. "\n",
  25. esh_info_global->user_data->pw_name,
  26. esh_info_global->build_ref,
  27. esh_info_global->user_data->pw_dir,
  28. esh_info_global->user_data->pw_shell,
  29. esh_info_global->config_file_path,
  30. esh_info_global->history_file_path,
  31. esh_info_global->history_limit,
  32. esh_info_global->max_jobs_number,
  33. esh_info_global->max_command_length);
  34. }
  35. void EShInitInfo(int argc, char** argv) {
  36. esh_info_global = malloc(sizeof(EShInfo));
  37. esh_info_global->build_ref = malloc((strlen(BUILD_REF) + 1) * sizeof(char));
  38. strcpy(esh_info_global->build_ref, BUILD_REF);
  39. esh_info_global->user_data = getpwuid(geteuid());
  40. esh_info_global->current_working_dir = malloc((PATH_MAX + 1) * sizeof(char));
  41. memset(esh_info_global->current_working_dir, 0, (PATH_MAX + 1) * sizeof(char));
  42. getcwd(esh_info_global->current_working_dir, PATH_MAX);
  43. EShOptimiseCurrentWorkingDirectory();
  44. esh_info_global->config_file_path = malloc((PATH_MAX + 1) * sizeof(char));
  45. memset(esh_info_global->config_file_path, 0, (PATH_MAX + 1) * sizeof(char));
  46. strcat(esh_info_global->config_file_path, esh_info_global->user_data->pw_dir);
  47. strcat(esh_info_global->config_file_path, "/.esh_conf");
  48. esh_info_global->history_file_path = malloc((PATH_MAX + 1) * sizeof(char));
  49. memset(esh_info_global->history_file_path, 0, (PATH_MAX + 1) * sizeof(char));
  50. strcat(esh_info_global->history_file_path, esh_info_global->user_data->pw_dir);
  51. strcat(esh_info_global->history_file_path, "/.esh_history");
  52. esh_info_global->history_limit = 5000;
  53. esh_info_global->max_jobs_number = 64;
  54. esh_info_global->max_command_length = 512;
  55. esh_info_global->max_command_tokens = 16;
  56. esh_info_global->max_command_token_size = 256;
  57. esh_info_global->jobs_number = 0;
  58. esh_info_global->history_command_list = malloc((esh_info_global->history_limit + 1) * sizeof(char*));
  59. esh_info_global->history_command_list_size = 0;
  60. esh_info_global->max_invite_message_len = 2048;
  61. esh_info_global->invite_message = malloc((esh_info_global->max_invite_message_len + 1) * sizeof(char));
  62. EShUpdateInviteMessage();
  63. esh_info_global->exited = 0;
  64. }
  65. void EShParseCommandLineArgs(int argc, char** argv) {
  66. for (int i = 1; i < argc; i += 2) {
  67. if (strcmp(argv[i], "-h") == 0) {
  68. EShShowHelpAndExit();
  69. }
  70. if (i + 1 >= argc) {
  71. printf("ERROR: Incorrect command-line parameters number!");
  72. exit(1);
  73. }
  74. if (strcmp(argv[i], "-config") == 0) {
  75. strcpy(esh_info_global->config_file_path, argv[i + 1]);
  76. }
  77. if (strcmp(argv[i], "-history_path") == 0) {
  78. strcpy(esh_info_global->history_file_path, argv[i + 1]);
  79. }
  80. if (strcmp(argv[i], "-history_limit") == 0) {
  81. sscanf(argv[i + 1], "%d", &esh_info_global->history_limit);
  82. }
  83. if (strcmp(argv[i], "-max_active_jobs") == 0) {
  84. sscanf(argv[i + 1], "%d", &esh_info_global->max_jobs_number);
  85. }
  86. if (strcmp(argv[i], "-max_command_length") == 0) {
  87. sscanf(argv[i + 1], "%d", &esh_info_global->max_command_length);
  88. }
  89. }
  90. }
  91. void EShProcessConfigFile() {
  92. FILE* file = fopen(esh_info_global->config_file_path, "r");
  93. if (!file) {
  94. return;
  95. }
  96. char* line = NULL;
  97. ssize_t len = 0;
  98. int line_length = 0;
  99. while ((line_length = getline(&line, &len, file)) != -1) {
  100. if (line[line_length - 1] == '\n') {
  101. line[line_length - 1] = '\0';
  102. --line_length;
  103. }
  104. if (strstr(line, "history_path=") == line) {
  105. strcpy(esh_info_global->history_file_path, line + strlen("history_path="));
  106. }
  107. if (strstr(line, "history_limit=") == line) {
  108. sscanf(line + strlen("history_limit="), "%d", &esh_info_global->history_limit);
  109. }
  110. if (strstr(line, "max_active_jobs=") == line) {
  111. sscanf(line + strlen("max_active_jobs="), "%d", &esh_info_global->max_jobs_number);
  112. }
  113. if (strstr(line, "max_command_length=") == line) {
  114. sscanf(line + strlen("max_command_length="), "%d", &esh_info_global->max_command_length);
  115. }
  116. }
  117. fclose(file);
  118. }
  119. void EShProcessHistoryFile() {
  120. FILE* file = fopen(esh_info_global->history_file_path, "r");
  121. if (!file) {
  122. return;
  123. }
  124. char* line = NULL;
  125. ssize_t len = 0;
  126. int line_length = 0;
  127. while ((line_length = getline(&line, &len, file)) != -1) {
  128. if (line[line_length - 1] == '\n') {
  129. line[line_length - 1] = '\0';
  130. --line_length;
  131. }
  132. esh_info_global->history_command_list[esh_info_global->history_command_list_size] = malloc(strlen(line) + 1);
  133. strcpy(esh_info_global->history_command_list[esh_info_global->history_command_list_size], line);
  134. ++esh_info_global->history_command_list_size;
  135. }
  136. fclose(file);
  137. }
  138. void EShInitJob(EShJob* job) {
  139. job->command = malloc(esh_info_global->max_command_length);
  140. memset(job->command, 0, esh_info_global->max_command_length);
  141. job->command_tokens = malloc(esh_info_global->max_command_tokens * sizeof(char*));
  142. for (int i = 0; i < esh_info_global->max_command_tokens; ++i) {
  143. job->command_tokens[i] = malloc(esh_info_global->max_command_token_size);
  144. memset(job->command_tokens[i], 0, esh_info_global->max_command_token_size);
  145. }
  146. job->command_tokens_num = 0;
  147. job->command_type = EXEC_CMD;
  148. job->job_type = FOREGROUND;
  149. job->job_start_condition = NO_CONDITION;
  150. job->job_pid = -1;
  151. job->job_stdin = NULL;
  152. job->job_stdout = NULL;
  153. job->job_stderr = NULL;
  154. }
  155. EShJob* EShMakeJobsList() {
  156. EShJob* jobs_list = malloc(esh_info_global->max_jobs_number * sizeof(EShJob));
  157. for (int i = 0; i < esh_info_global->max_jobs_number; ++i) {
  158. EShInitJob(&jobs_list[i]);
  159. }
  160. return jobs_list;
  161. }