shell_new.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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 "lub/string.h"
  11. #include "lub/db.h"
  12. #include "lub/list.h"
  13. #include "clish/plugin.h"
  14. /*-------------------------------------------------------- */
  15. static void clish_shell_init(clish_shell_t * this,
  16. FILE * istream, FILE * ostream, bool_t stop_on_error)
  17. {
  18. clish_ptype_t *tmp_ptype = NULL;
  19. int i;
  20. /* initialise the tree of views */
  21. lub_bintree_init(&this->view_tree,
  22. clish_view_bt_offset(),
  23. clish_view_bt_compare, clish_view_bt_getkey);
  24. /* initialise the tree of ptypes */
  25. lub_bintree_init(&this->ptype_tree,
  26. clish_ptype_bt_offset(),
  27. clish_ptype_bt_compare, clish_ptype_bt_getkey);
  28. /* initialise the tree of vars */
  29. lub_bintree_init(&this->var_tree,
  30. clish_var_bt_offset(),
  31. clish_var_bt_compare, clish_var_bt_getkey);
  32. /* Initialize plugin list */
  33. this->plugins = lub_list_new(NULL);
  34. /* Initialise the list of unresolved (yet) symbols */
  35. this->syms = lub_list_new(clish_sym_compare);
  36. /* Create userdata storage */
  37. this->udata = lub_list_new(clish_udata_compare);
  38. assert(this->udata);
  39. /* Hooks */
  40. for (i = 0; i < CLISH_SYM_TYPE_MAX; i++) {
  41. this->hooks[i] = clish_sym_new(NULL, NULL, i);
  42. this->hooks_use[i] = BOOL_FALSE;
  43. }
  44. /* Set up defaults */
  45. this->global = NULL;
  46. this->startup = NULL;
  47. this->idle_timeout = 0; /* No idle timeout by default */
  48. this->wdog = NULL;
  49. this->wdog_timeout = 0; /* No watchdog timeout by default */
  50. this->wdog_active = BOOL_FALSE;
  51. this->state = SHELL_STATE_INITIALISING;
  52. this->overview = NULL;
  53. this->tinyrl = clish_shell_tinyrl_new(istream, ostream, 0);
  54. this->current_file = NULL;
  55. this->pwdv = NULL;
  56. this->pwdc = 0;
  57. this->depth = -1; /* Current depth is undefined */
  58. this->client = NULL;
  59. this->lockfile = lub_string_dup(CLISH_LOCK_PATH);
  60. this->default_shebang = lub_string_dup("/bin/sh");
  61. this->fifo_name = NULL;
  62. this->interactive = BOOL_TRUE; /* The interactive shell by default. */
  63. this->log = BOOL_FALSE; /* Disable logging by default */
  64. this->log_facility = LOG_LOCAL0; /* LOCAL0 for compatibility */
  65. this->dryrun = BOOL_FALSE; /* Disable dry-run by default */
  66. this->user = lub_db_getpwuid(getuid()); /* Get user information */
  67. this->default_plugin = BOOL_TRUE; /* Load default plugin by default */
  68. /* Push non-NULL istream */
  69. if (istream)
  70. clish_shell_push_fd(this, istream, stop_on_error);
  71. }
  72. /*--------------------------------------------------------- */
  73. static void clish_shell_fini(clish_shell_t *this)
  74. {
  75. clish_view_t *view;
  76. clish_ptype_t *ptype;
  77. clish_var_t *var;
  78. unsigned i;
  79. lub_list_node_t *iter;
  80. /* Free all loaded plugins */
  81. while ((iter = lub_list__get_head(this->plugins))) {
  82. /* Remove the symbol from the list */
  83. lub_list_del(this->plugins, iter);
  84. /* Free the instance */
  85. clish_plugin_free((clish_plugin_t *)lub_list_node__get_data(iter),
  86. (void *)this);
  87. lub_list_node_free(iter);
  88. }
  89. lub_list_free(this->plugins);
  90. /* delete each VIEW held */
  91. while ((view = lub_bintree_findfirst(&this->view_tree))) {
  92. lub_bintree_remove(&this->view_tree, view);
  93. clish_view_delete(view);
  94. }
  95. /* delete each PTYPE held */
  96. while ((ptype = lub_bintree_findfirst(&this->ptype_tree))) {
  97. lub_bintree_remove(&this->ptype_tree, ptype);
  98. clish_ptype_delete(ptype);
  99. }
  100. /* delete each VAR held */
  101. while ((var = lub_bintree_findfirst(&this->var_tree))) {
  102. lub_bintree_remove(&this->var_tree, var);
  103. clish_var_delete(var);
  104. }
  105. /* Free empty hooks */
  106. for (i = 0; i < CLISH_SYM_TYPE_MAX; i++) {
  107. if (clish_sym__get_name(this->hooks[i]))
  108. continue;
  109. clish_sym_free(this->hooks[i]);
  110. }
  111. /* Free symbol list */
  112. while ((iter = lub_list__get_head(this->syms))) {
  113. /* Remove the symbol from the list */
  114. lub_list_del(this->syms, iter);
  115. /* Free the instance */
  116. clish_sym_free((clish_sym_t *)lub_list_node__get_data(iter));
  117. lub_list_node_free(iter);
  118. }
  119. lub_list_free(this->syms);
  120. /* Free user data storage */
  121. while ((iter = lub_list__get_head(this->udata))) {
  122. /* Remove the symbol from the list */
  123. lub_list_del(this->udata, iter);
  124. /* Free the instance */
  125. clish_udata_free((clish_udata_t *)lub_list_node__get_data(iter));
  126. lub_list_node_free(iter);
  127. }
  128. lub_list_free(this->udata);
  129. /* free the textual details */
  130. lub_string_free(this->overview);
  131. /* Remove the startup command */
  132. if (this->startup)
  133. clish_command_delete(this->startup);
  134. /* Remove the watchdog command */
  135. if (this->wdog)
  136. clish_command_delete(this->wdog);
  137. /* clean up the file stack */
  138. while (!clish_shell_pop_file(this));
  139. /* delete the tinyrl object */
  140. clish_shell_tinyrl_delete(this->tinyrl);
  141. /* finalize each of the pwd strings */
  142. for (i = 0; i < this->pwdc; i++) {
  143. clish_shell__fini_pwd(this->pwdv[i]);
  144. free(this->pwdv[i]);
  145. }
  146. /* free the pwd vector */
  147. free(this->pwdv);
  148. konf_client_free(this->client);
  149. lub_string_free(this->lockfile);
  150. lub_string_free(this->default_shebang);
  151. free(this->user);
  152. if (this->fifo_name) {
  153. unlink(this->fifo_name);
  154. lub_string_free(this->fifo_name);
  155. }
  156. }
  157. /*-------------------------------------------------------- */
  158. clish_shell_t *clish_shell_new(
  159. FILE * istream,
  160. FILE * ostream,
  161. bool_t stop_on_error)
  162. {
  163. clish_shell_t *this = malloc(sizeof(clish_shell_t));
  164. if (this)
  165. clish_shell_init(this, istream, ostream, stop_on_error);
  166. return this;
  167. }
  168. /*--------------------------------------------------------- */
  169. void clish_shell_delete(clish_shell_t *this)
  170. {
  171. clish_shell_fini(this);
  172. free(this);
  173. }
  174. /*--------------------------------------------------------- */
  175. struct passwd *clish_shell__get_user(clish_shell_t * this)
  176. {
  177. return this->user;
  178. }
  179. /*-------------------------------------------------------- */