shell_new.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. * shell_new.c
  3. */
  4. #include "private.h"
  5. #include <assert.h>
  6. #include <stdlib.h>
  7. #include <unistd.h>
  8. #include "lub/string.h"
  9. /*-------------------------------------------------------- */
  10. static void clish_shell_init(clish_shell_t * this,
  11. const clish_shell_hooks_t * hooks,
  12. void *cookie, FILE * istream,
  13. FILE * ostream,
  14. bool_t stop_on_error)
  15. {
  16. clish_ptype_t *tmp_ptype = NULL;
  17. /* initialise the tree of views */
  18. lub_bintree_init(&this->view_tree,
  19. clish_view_bt_offset(),
  20. clish_view_bt_compare, clish_view_bt_getkey);
  21. /* initialise the tree of ptypes */
  22. lub_bintree_init(&this->ptype_tree,
  23. clish_ptype_bt_offset(),
  24. clish_ptype_bt_compare, clish_ptype_bt_getkey);
  25. /* initialise the tree of vars */
  26. lub_bintree_init(&this->var_tree,
  27. clish_var_bt_offset(),
  28. clish_var_bt_compare, clish_var_bt_getkey);
  29. assert((NULL != hooks) && (NULL != hooks->script_fn));
  30. /* set up defaults */
  31. this->client_hooks = hooks;
  32. this->client_cookie = cookie;
  33. this->view = NULL;
  34. this->viewid = NULL;
  35. this->global = NULL;
  36. this->startup = NULL;
  37. this->state = SHELL_STATE_INITIALISING;
  38. this->overview = NULL;
  39. this->tinyrl = clish_shell_tinyrl_new(istream, ostream, 0);
  40. this->current_file = NULL;
  41. this->cfg_pwdv = NULL;
  42. this->cfg_pwdc = 0;
  43. this->client = NULL;
  44. this->lockfile = lub_string_dup(CLISH_LOCK_PATH);
  45. this->default_shebang = lub_string_dup("/bin/sh");
  46. this->fifo_name = NULL;
  47. this->interactive = BOOL_TRUE; /* The interactive shell by default. */
  48. /* Create internal ptypes and params */
  49. /* Current depth */
  50. tmp_ptype = clish_shell_find_create_ptype(this,
  51. "__DEPTH", "Depth", "[0-9]+",
  52. CLISH_PTYPE_REGEXP, CLISH_PTYPE_NONE);
  53. assert(tmp_ptype);
  54. this->param_depth = clish_param_new("__cur_depth",
  55. "Current depth", tmp_ptype, clish_shell_expand);
  56. clish_param__set_hidden(this->param_depth, BOOL_TRUE);
  57. /* Current pwd */
  58. tmp_ptype = clish_shell_find_create_ptype(this,
  59. "__PWD", "Path", ".+",
  60. CLISH_PTYPE_REGEXP, CLISH_PTYPE_NONE);
  61. assert(tmp_ptype);
  62. this->param_pwd = clish_param_new("__cur_pwd",
  63. "Current path", tmp_ptype, clish_shell_expand);
  64. clish_param__set_hidden(this->param_pwd, BOOL_TRUE);
  65. /* Interactive */
  66. tmp_ptype = clish_shell_find_create_ptype(this,
  67. "__INTERACTIVE", "Interactive flag", "[01]",
  68. CLISH_PTYPE_REGEXP, CLISH_PTYPE_NONE);
  69. assert(tmp_ptype);
  70. this->param_interactive = clish_param_new("__interactive",
  71. "Interactive flag", tmp_ptype, clish_shell_expand);
  72. clish_param__set_hidden(this->param_interactive, BOOL_TRUE);
  73. /* Push non-NULL istream */
  74. if (istream)
  75. clish_shell_push_fd(this, istream, stop_on_error);
  76. }
  77. /*--------------------------------------------------------- */
  78. static void clish_shell_fini(clish_shell_t * this)
  79. {
  80. clish_view_t *view;
  81. clish_ptype_t *ptype;
  82. clish_var_t *var;
  83. unsigned i;
  84. /* delete each VIEW held */
  85. while ((view = lub_bintree_findfirst(&this->view_tree))) {
  86. lub_bintree_remove(&this->view_tree, view);
  87. clish_view_delete(view);
  88. }
  89. /* delete each PTYPE held */
  90. while ((ptype = lub_bintree_findfirst(&this->ptype_tree))) {
  91. lub_bintree_remove(&this->ptype_tree, ptype);
  92. clish_ptype_delete(ptype);
  93. }
  94. /* delete each VAR held */
  95. while ((var = lub_bintree_findfirst(&this->var_tree))) {
  96. lub_bintree_remove(&this->var_tree, var);
  97. clish_var_delete(var);
  98. }
  99. /* free the textual details */
  100. lub_string_free(this->overview);
  101. lub_string_free(this->viewid);
  102. /* remove the startup command */
  103. if (this->startup)
  104. clish_command_delete(this->startup);
  105. /* clean up the file stack */
  106. while (BOOL_TRUE == clish_shell_pop_file(this));
  107. /* delete the tinyrl object */
  108. clish_shell_tinyrl_delete(this->tinyrl);
  109. /* finalize each of the pwd strings */
  110. for (i = 0; i < this->cfg_pwdc; i++) {
  111. lub_string_free(this->cfg_pwdv[i]->line);
  112. lub_string_free(this->cfg_pwdv[i]->viewid);
  113. free(this->cfg_pwdv[i]);
  114. }
  115. /* free the pwd vector */
  116. free(this->cfg_pwdv);
  117. this->cfg_pwdc = 0;
  118. this->cfg_pwdv = NULL;
  119. konf_client_free(this->client);
  120. /* Free internal params */
  121. clish_param_delete(this->param_depth);
  122. clish_param_delete(this->param_pwd);
  123. clish_param_delete(this->param_interactive);
  124. lub_string_free(this->lockfile);
  125. lub_string_free(this->default_shebang);
  126. if (this->fifo_name) {
  127. unlink(this->fifo_name);
  128. lub_string_free(this->fifo_name);
  129. }
  130. }
  131. /*-------------------------------------------------------- */
  132. clish_shell_t *clish_shell_new(const clish_shell_hooks_t * hooks,
  133. void *cookie,
  134. FILE * istream,
  135. FILE * ostream,
  136. bool_t stop_on_error)
  137. {
  138. clish_shell_t *this = malloc(sizeof(clish_shell_t));
  139. if (this) {
  140. clish_shell_init(this, hooks, cookie,
  141. istream, ostream, stop_on_error);
  142. if (hooks->init_fn) {
  143. /* now call the client initialisation */
  144. if (BOOL_TRUE != hooks->init_fn(this))
  145. this->state = SHELL_STATE_CLOSING;
  146. }
  147. }
  148. return this;
  149. }
  150. /*--------------------------------------------------------- */
  151. void clish_shell_delete(clish_shell_t * this)
  152. {
  153. /* now call the client finalisation */
  154. if (this->client_hooks->fini_fn)
  155. this->client_hooks->fini_fn(this);
  156. clish_shell_fini(this);
  157. free(this);
  158. }
  159. /*-------------------------------------------------------- */