shell_new.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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. /*-------------------------------------------------------- */
  13. static void clish_shell_init(clish_shell_t * this,
  14. const clish_shell_hooks_t * hooks,
  15. void *cookie, FILE * istream,
  16. FILE * ostream,
  17. bool_t stop_on_error)
  18. {
  19. clish_ptype_t *tmp_ptype = NULL;
  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. assert((NULL != hooks) && (NULL != hooks->script_fn));
  33. /* set up defaults */
  34. this->client_hooks = hooks;
  35. this->client_cookie = cookie;
  36. this->global = NULL;
  37. this->startup = NULL;
  38. this->idle_timeout = 0; /* No idle timeout by default */
  39. this->wdog = NULL;
  40. this->wdog_timeout = 0; /* No watchdog timeout by default */
  41. this->wdog_active = BOOL_FALSE;
  42. this->state = SHELL_STATE_INITIALISING;
  43. this->overview = NULL;
  44. this->tinyrl = clish_shell_tinyrl_new(istream, ostream, 0);
  45. this->current_file = NULL;
  46. this->pwdv = NULL;
  47. this->pwdc = 0;
  48. this->depth = -1; /* Current depth is undefined */
  49. this->client = NULL;
  50. this->lockfile = lub_string_dup(CLISH_LOCK_PATH);
  51. this->default_shebang = lub_string_dup("/bin/sh");
  52. this->fifo_name = NULL;
  53. this->interactive = BOOL_TRUE; /* The interactive shell by default. */
  54. this->log = BOOL_FALSE; /* Disable logging by default */
  55. this->log_facility = LOG_LOCAL0; /* LOCAL0 for compatibility */
  56. this->user = lub_db_getpwuid(getuid()); /* Get user information */
  57. /* Create internal ptypes and params */
  58. /* Args */
  59. tmp_ptype = clish_shell_find_create_ptype(this,
  60. "internal_ARGS",
  61. "Arguments", "[^\\\\]+",
  62. CLISH_PTYPE_REGEXP,
  63. CLISH_PTYPE_NONE);
  64. assert(tmp_ptype);
  65. /* Push non-NULL istream */
  66. if (istream)
  67. clish_shell_push_fd(this, istream, stop_on_error);
  68. }
  69. /*--------------------------------------------------------- */
  70. static void clish_shell_fini(clish_shell_t * this)
  71. {
  72. clish_view_t *view;
  73. clish_ptype_t *ptype;
  74. clish_var_t *var;
  75. unsigned i;
  76. /* delete each VIEW held */
  77. while ((view = lub_bintree_findfirst(&this->view_tree))) {
  78. lub_bintree_remove(&this->view_tree, view);
  79. clish_view_delete(view);
  80. }
  81. /* delete each PTYPE held */
  82. while ((ptype = lub_bintree_findfirst(&this->ptype_tree))) {
  83. lub_bintree_remove(&this->ptype_tree, ptype);
  84. clish_ptype_delete(ptype);
  85. }
  86. /* delete each VAR held */
  87. while ((var = lub_bintree_findfirst(&this->var_tree))) {
  88. lub_bintree_remove(&this->var_tree, var);
  89. clish_var_delete(var);
  90. }
  91. /* free the textual details */
  92. lub_string_free(this->overview);
  93. /* Remove the startup command */
  94. if (this->startup)
  95. clish_command_delete(this->startup);
  96. /* Remove the watchdog command */
  97. if (this->wdog)
  98. clish_command_delete(this->wdog);
  99. /* clean up the file stack */
  100. while (!clish_shell_pop_file(this));
  101. /* delete the tinyrl object */
  102. clish_shell_tinyrl_delete(this->tinyrl);
  103. /* finalize each of the pwd strings */
  104. for (i = 0; i < this->pwdc; i++) {
  105. clish_shell__fini_pwd(this->pwdv[i]);
  106. free(this->pwdv[i]);
  107. }
  108. /* free the pwd vector */
  109. free(this->pwdv);
  110. konf_client_free(this->client);
  111. lub_string_free(this->lockfile);
  112. lub_string_free(this->default_shebang);
  113. free(this->user);
  114. if (this->fifo_name) {
  115. unlink(this->fifo_name);
  116. lub_string_free(this->fifo_name);
  117. }
  118. }
  119. /*-------------------------------------------------------- */
  120. clish_shell_t *clish_shell_new(const clish_shell_hooks_t * hooks,
  121. void *cookie,
  122. FILE * istream,
  123. FILE * ostream,
  124. bool_t stop_on_error)
  125. {
  126. clish_shell_t *this = malloc(sizeof(clish_shell_t));
  127. if (this) {
  128. clish_shell_init(this, hooks, cookie,
  129. istream, ostream, stop_on_error);
  130. if (hooks->init_fn) {
  131. /* now call the client initialisation */
  132. if (BOOL_TRUE != hooks->init_fn(this))
  133. this->state = SHELL_STATE_CLOSING;
  134. }
  135. }
  136. return this;
  137. }
  138. /*--------------------------------------------------------- */
  139. void clish_shell_delete(clish_shell_t * this)
  140. {
  141. /* now call the client finalisation */
  142. if (this->client_hooks->fini_fn)
  143. this->client_hooks->fini_fn(this);
  144. clish_shell_fini(this);
  145. free(this);
  146. }
  147. /*--------------------------------------------------------- */
  148. struct passwd *clish_shell__get_user(clish_shell_t * this)
  149. {
  150. return this->user;
  151. }
  152. /*-------------------------------------------------------- */