shell_new.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * shell_new.c
  3. */
  4. #include "private.h"
  5. #include <assert.h>
  6. #include <stdlib.h>
  7. #include <sys/types.h>
  8. #include <unistd.h>
  9. #include <syslog.h>
  10. #include <limits.h>
  11. #include "lub/string.h"
  12. #include "lub/db.h"
  13. #include "lub/list.h"
  14. #include "clish/plugin.h"
  15. /*-------------------------------------------------------- */
  16. static void clish_shell_init(clish_shell_t * this,
  17. FILE * istream, FILE * ostream, bool_t stop_on_error)
  18. {
  19. clish_ptype_t *tmp_ptype = NULL;
  20. int i;
  21. char template[PATH_MAX];
  22. /* Initialise VIEW list */
  23. this->view_tree = lub_list_new(clish_view_compare, clish_view_delete);
  24. /* Init PTYPE list */
  25. this->ptype_tree = lub_list_new(clish_ptype_compare, clish_ptype_free);
  26. /* Initialize plugin list */
  27. this->plugins = lub_list_new(NULL, clish_plugin_free);
  28. /* Initialise the list of unresolved (yet) symbols */
  29. this->syms = lub_list_new(clish_sym_compare, clish_sym_free);
  30. /* Create userdata storage */
  31. this->udata = lub_list_new(clish_udata_compare, clish_udata_delete);
  32. /* Hooks */
  33. for (i = 0; i < CLISH_SYM_TYPE_MAX; i++) {
  34. this->hooks[i] = clish_sym_new(NULL, NULL, i);
  35. this->hooks_use[i] = BOOL_FALSE;
  36. }
  37. /* Set up defaults */
  38. this->global = NULL;
  39. this->startup = NULL;
  40. this->idle_timeout = 0; /* No idle timeout by default */
  41. this->wdog = NULL;
  42. this->wdog_timeout = 0; /* No watchdog timeout by default */
  43. this->wdog_active = BOOL_FALSE;
  44. this->state = SHELL_STATE_INITIALISING;
  45. this->overview = NULL;
  46. this->tinyrl = clish_shell_tinyrl_new(istream, ostream, 0);
  47. this->current_file = NULL;
  48. this->pwdv = NULL;
  49. this->pwdc = 0;
  50. this->depth = -1; /* Current depth is undefined */
  51. this->client = NULL;
  52. this->lockfile = lub_string_dup(CLISH_LOCK_PATH);
  53. this->default_shebang = lub_string_dup("/bin/sh");
  54. this->interactive = BOOL_TRUE; /* The interactive shell by default. */
  55. this->log = BOOL_FALSE; /* Disable logging by default */
  56. this->log_facility = LOG_LOCAL0; /* LOCAL0 for compatibility */
  57. this->dryrun = BOOL_FALSE; /* Disable dry-run by default */
  58. this->user = lub_db_getpwuid(getuid()); /* Get user information */
  59. this->default_plugin = BOOL_TRUE; /* Load default plugin by default */
  60. this->canon_out = BOOL_FALSE; /* A canonical output is needed in special cases only */
  61. /* Create template (string) for FIFO name generation */
  62. snprintf(template, sizeof(template),
  63. "%s/klish.fifo.%u.XXXXXX", "/tmp", getpid());
  64. template[sizeof(template) - 1] = '\0';
  65. this->fifo_temp = lub_string_dup(template);
  66. /* Create internal ptypes and params */
  67. /* Args */
  68. tmp_ptype = clish_shell_find_create_ptype(this,
  69. "__ptype_ARGS",
  70. "Arguments", "[^\\\\]+",
  71. CLISH_PTYPE_METHOD_REGEXP,
  72. CLISH_PTYPE_PRE_NONE);
  73. assert(tmp_ptype);
  74. /* Push non-NULL istream */
  75. if (istream)
  76. clish_shell_push_fd(this, istream, stop_on_error);
  77. }
  78. /*--------------------------------------------------------- */
  79. static void clish_shell_fini(clish_shell_t *this)
  80. {
  81. unsigned int i;
  82. /* Free all loaded plugins */
  83. lub_list_free_all(this->plugins);
  84. /* Delete each VIEW */
  85. lub_list_free_all(this->view_tree);
  86. /* Delete each PTYPE */
  87. lub_list_free_all(this->ptype_tree);
  88. /* Free empty hooks */
  89. for (i = 0; i < CLISH_SYM_TYPE_MAX; i++) {
  90. if (clish_sym__get_name(this->hooks[i]))
  91. continue;
  92. clish_sym_free(this->hooks[i]);
  93. }
  94. /* Free symbol list */
  95. lub_list_free_all(this->syms);
  96. /* Free user data storage */
  97. lub_list_free_all(this->udata);
  98. /* free the textual details */
  99. lub_string_free(this->overview);
  100. /* Remove the startup command */
  101. if (this->startup)
  102. clish_command_delete(this->startup);
  103. /* Remove the watchdog command */
  104. if (this->wdog)
  105. clish_command_delete(this->wdog);
  106. /* clean up the file stack */
  107. while (!clish_shell_pop_file(this));
  108. /* delete the tinyrl object */
  109. clish_shell_tinyrl_delete(this->tinyrl);
  110. /* finalize each of the pwd strings */
  111. for (i = 0; i < this->pwdc; i++) {
  112. clish_shell__fini_pwd(this->pwdv[i]);
  113. free(this->pwdv[i]);
  114. }
  115. /* free the pwd vector */
  116. free(this->pwdv);
  117. konf_client_free(this->client);
  118. lub_string_free(this->lockfile);
  119. lub_string_free(this->default_shebang);
  120. free(this->user);
  121. if (this->fifo_temp)
  122. lub_string_free(this->fifo_temp);
  123. }
  124. /*-------------------------------------------------------- */
  125. clish_shell_t *clish_shell_new(
  126. FILE * istream,
  127. FILE * ostream,
  128. bool_t stop_on_error)
  129. {
  130. clish_shell_t *this = malloc(sizeof(clish_shell_t));
  131. if (this)
  132. clish_shell_init(this, istream, ostream, stop_on_error);
  133. return this;
  134. }
  135. /*--------------------------------------------------------- */
  136. void clish_shell_delete(clish_shell_t *this)
  137. {
  138. clish_shell_fini(this);
  139. free(this);
  140. }
  141. CLISH_GET(shell, struct passwd *, user);