shell.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. /*
  2. * shell.h
  3. */
  4. /**
  5. \ingroup clish
  6. \defgroup clish_shell shell
  7. @{
  8. \brief This class represents the top level container for a CLI session.
  9. */
  10. #ifndef _clish_shell_h
  11. #define _clish_shell_h
  12. #include <stdio.h>
  13. #include <pthread.h>
  14. #include "lub/c_decl.h"
  15. #include "lub/types.h"
  16. #include "lub/argv.h"
  17. #include "tinyrl/tinyrl.h"
  18. #include "clish/view.h"
  19. #include "clish/ptype.h"
  20. #include "clish/var.h"
  21. #include "konf/net.h"
  22. #define CLISH_LOCK_PATH "/tmp/clish.lock"
  23. #define CLISH_LOCK_WAIT 20
  24. typedef struct clish_context_s clish_context_t;
  25. typedef struct clish_shell_s clish_shell_t;
  26. typedef enum {
  27. SHELL_STATE_INITIALISING,
  28. SHELL_STATE_OK,
  29. SHELL_STATE_HELPING,
  30. SHELL_STATE_SCRIPT_ERROR,/* Script execution error */
  31. SHELL_STATE_EOF, /* EOF of input stream */
  32. SHELL_STATE_SYNTAX_ERROR, /* Illegal line entered */
  33. SHELL_STATE_SYSTEM_ERROR, /* Some internal system error */
  34. SHELL_STATE_CLOSING
  35. } clish_shell_state_t;
  36. _BEGIN_C_DECL
  37. /*=====================================
  38. * SHELL INTERFACE
  39. *===================================== */
  40. /**
  41. * A hook function used during the spawning of a new shell.
  42. *
  43. * This will be invoked from the context of the spawned shell's thread
  44. * and will be invoked just after the shell instance is created.
  45. *
  46. * This enables the client-specific initialisation of the spawned shell's
  47. * thread
  48. * e.g. to map the I/O streams, authenticate a user.
  49. *
  50. * N.B. It is possible for a client to have this invoked multiple times
  51. * if the user is spawning new shells using a commmand which uses the
  52. * "clish_spawn" builtin function. Hence the client should remember the
  53. * shell which first calls this function, and only assign resource (e.g.
  54. * setting up a script interpreter) for that call.
  55. *
  56. * \return
  57. * - BOOL_TRUE if everything is OK
  58. * - BOOL_FALSE if the shell should be immediately shut down.
  59. *
  60. */
  61. typedef bool_t clish_shell_init_fn_t(
  62. /**
  63. * The shell instance which invoked this call
  64. */
  65. const clish_shell_t * shell);
  66. /**
  67. * A hook function used during the shutting down of a spawned shell
  68. *
  69. * This will be invoked from the context of the spawned shell's thread
  70. * and will be invoked just before the shell is destroyed.
  71. *
  72. * This enables the client-specific finalisation to occur.
  73. * e.g. releasing any resource held by the cookie,
  74. * shutting down telnet connections
  75. *
  76. * NB. This function may be called multiple times if a user is spawning
  77. * new commands (via the "clish_spawn" builtin command), hence should use
  78. * the reference to the root shell (remembered by the first call to clish_shell_init_fn_t callback)
  79. * to signal when the cleanup should occur.
  80. */
  81. typedef void clish_shell_fini_fn_t(
  82. /**
  83. * The shell instance which invoked this call
  84. */
  85. const clish_shell_t * shell);
  86. /**
  87. * A hook function used to indicate a command line has been executed and the
  88. * shell is about to prompt for the next command.
  89. *
  90. * This will be invoked from the context of the spawned shell's thread
  91. * and will be called once an ACTION has been performed.
  92. *
  93. * A client may use this as a periodic indicator of CLI activity,
  94. * e.g. to manage session timeouts. In addition any required logging of
  95. * commands may be performed.
  96. */
  97. typedef void clish_shell_cmd_line_fn_t(
  98. /**
  99. * The shell instance which invoked this call
  100. */
  101. const clish_shell_t * instance,
  102. /**
  103. * The text of the command line entered
  104. */
  105. const char *cmd_line);
  106. /**
  107. * A hook function used to invoke the script associated with a command
  108. *
  109. * This will be invoked from the context of the spawned shell's thread
  110. * and will be invoked with the ACTION script which is to be performed.
  111. *
  112. * The clish component will only pass down a call when a command has been
  113. * correctly input.
  114. *
  115. * The client may choose to implement invocation of the script in a number of
  116. * ways, which may include forking a sub-process or thread. It is important
  117. * that the call doesn't return until the script has been fully evaluated.
  118. *
  119. * \return
  120. * - BOOL_TRUE - if the script is executed without issue
  121. * - BOOL_FALSE - if the script had an issue with execution.
  122. *
  123. * \post
  124. * - If the script executes successfully then any "view" tag associated with the
  125. * command will be honored. i.e. the CLI will switch to the new view
  126. */
  127. typedef bool_t clish_shell_script_fn_t(
  128. /**
  129. * The shell instance which invoked this call
  130. */
  131. clish_shell_t * instance,
  132. /**
  133. * The command which invoked this call
  134. */
  135. const clish_command_t * cmd,
  136. /**
  137. * The script to be evaluated
  138. */
  139. const char *script,
  140. char ** out);
  141. /**
  142. * A hook function used to control config file write
  143. *
  144. */
  145. typedef bool_t clish_shell_config_fn_t(
  146. /**
  147. * The shell instance which invoked this call
  148. */
  149. const clish_shell_t * instance,
  150. /**
  151. * The command
  152. */
  153. const clish_command_t * cmd,
  154. /**
  155. * Argument vector
  156. */
  157. clish_pargv_t * pargv);
  158. /**
  159. * A hook function used to control access for the current user.
  160. *
  161. * This will be invoked from the context of the spawned shell's thread
  162. * and will be called during the parsing of the XML files.
  163. *
  164. * The clish component will only insert a command into a view if the access
  165. * call is sucessfull.
  166. *
  167. * The client may choose to implement invocation of the script in a number of
  168. * ways, which may include forking a sub-process or thread. It is important
  169. * that the call doesn't return until the script has been fully evaluated.
  170. *
  171. * \return
  172. * - BOOL_TRUE - if the user of the current CLISH session is permitted access
  173. * - BOOL_FALSE - if the user of the current CLISH session is not permitted access
  174. *
  175. * \post
  176. * - If access is granted then the associated command will be inserted into the
  177. * appropriate view.
  178. */
  179. typedef bool_t clish_shell_access_fn_t(
  180. /**
  181. * The shell instance which invoked this call
  182. */
  183. const clish_shell_t * instance,
  184. /**
  185. * A textual string which describes a limitation for a command. This
  186. * string typically may be the name of a user group, of which the
  187. * current user must be a member to grant access to a command.
  188. */
  189. const char *access);
  190. /**
  191. * A hook function used as a built in command callback
  192. *
  193. * This will be invoked from the context of the spawned shell's thread
  194. * and will be called during the execution of a builting command.
  195. *
  196. * A client may register any number of these callbacks in its
  197. * clish_shell_builtin_cmds_t structure.
  198. *
  199. * \return
  200. * - BOOL_TRUE - if the command completes correctly
  201. * - BOOL_FALSE - if the command fails.
  202. *
  203. */
  204. typedef bool_t clish_shell_builtin_fn_t(
  205. /**
  206. * The shell instance which invoked this call
  207. */
  208. const clish_shell_t * instance,
  209. /**
  210. * A vector of textual command line arguments.
  211. */
  212. const lub_argv_t * argv);
  213. /**
  214. * A client of libclish may provide some builtin commands which will be
  215. * interpreted by the framework, instead of the client's script engine.
  216. */
  217. typedef struct {
  218. const char *name; /**< The textual name to be used in
  219. * the 'builtin' XML attribute"
  220. */
  221. clish_shell_builtin_fn_t *callback;
  222. /**< The function to be invoked */
  223. } clish_shell_builtin_t;
  224. /**
  225. * A client of libclish will provide hooks for the control of the CLI within
  226. * a particular system.
  227. * They will populate an instance of this structure and pass it into the
  228. */
  229. typedef struct {
  230. clish_shell_init_fn_t *init_fn; /**< Initialisation call */
  231. clish_shell_access_fn_t *access_fn; /**< Access control call */
  232. clish_shell_cmd_line_fn_t *cmd_line_fn;/**< Command line logging call */
  233. clish_shell_script_fn_t *script_fn; /**< script evaluation call */
  234. clish_shell_fini_fn_t *fini_fn; /**< Finalisation call */
  235. clish_shell_config_fn_t *config_fn; /**< Config call */
  236. const clish_shell_builtin_t *cmd_list;/**< NULL terminated list */
  237. } clish_shell_hooks_t;
  238. /*-----------------
  239. * meta functions
  240. *----------------- */
  241. #if 0
  242. int clish_shell_spawn_and_wait(const clish_shell_hooks_t * hooks, void *cookie);
  243. /**
  244. * This operation causes a separate (POSIX) thread of execution to
  245. * be spawned. This thread becomes responsible for the CLI session.
  246. *
  247. * This will be invoked from the context of the spawned shell's thread
  248. * and will be called during the execution of a builting command.
  249. *
  250. * A client may register any number of these callbacks in its
  251. * clish_shell_builtin_cmds_t structure.
  252. *
  253. * \return
  254. * - BOOL_TRUE - if the thread was successfully spawned
  255. * - BOOL_FALSE - if the thread failed to be spawned
  256. *
  257. */
  258. bool_t clish_shell_spawn(
  259. /**
  260. * A POSIX thread reference to fill out. This can be used
  261. * to later control the spawned thread if necessary.
  262. */
  263. pthread_t * pthread,
  264. /**
  265. * A POSIX thread attribute reference which will be used
  266. * to define the thread which will be lanched. A value of
  267. * NULL will use the system default.
  268. */
  269. const pthread_attr_t * attr,
  270. /**
  271. * A reference to the clients hooks. These are used to
  272. * communicate back the client when client-specific actions
  273. * are required.
  274. */
  275. const clish_shell_hooks_t * hooks,
  276. /**
  277. * A client specific reference which can be obtained during
  278. * a callback by invoking clish_shell__get_client_cookie()
  279. */
  280. void *cookie);
  281. #endif
  282. clish_shell_t *clish_shell_new(const clish_shell_hooks_t * hooks,
  283. void *cookie,
  284. FILE * istream,
  285. FILE * ostream,
  286. bool_t stop_on_error);
  287. /*-----------------
  288. * methods
  289. *----------------- */
  290. /*
  291. * Called to invoke the startup command for this shell
  292. */
  293. bool_t clish_shell_startup(clish_shell_t * instance);
  294. void clish_shell_delete(clish_shell_t * instance);
  295. clish_view_t *clish_shell_find_create_view(clish_shell_t * instance,
  296. const char *name,
  297. const char *prompt);
  298. clish_ptype_t *clish_shell_find_create_ptype(clish_shell_t * instance,
  299. const char *name,
  300. const char *text,
  301. const char *pattern,
  302. clish_ptype_method_e method,
  303. clish_ptype_preprocess_e preprocess);
  304. int clish_shell_xml_read(clish_shell_t * instance, const char *filename);
  305. void clish_shell_help(clish_shell_t * instance, const char *line);
  306. bool_t clish_shell_execute(clish_shell_t * instance,
  307. const clish_command_t * cmd, clish_pargv_t * pargv, char ** out);
  308. bool_t clish_shell_line(clish_shell_t * instance, const char *prompt,
  309. const clish_command_t ** cmd, clish_pargv_t ** pargv, const char *str);
  310. bool_t clish_shell_forceline(clish_shell_t *instance, const char *line, char ** out);
  311. bool_t clish_shell_readline(clish_shell_t *instance, char ** out);
  312. void clish_shell_dump(clish_shell_t * instance);
  313. void clish_shell_close(clish_shell_t * instance);
  314. /**
  315. * Push the specified file handle on to the stack of file handles
  316. * for this shell. The specified file will become the source of
  317. * commands, until it is exhausted.
  318. *
  319. * \return
  320. * BOOL_TRUE - the file was successfully associated with the shell.
  321. * BOOL_FALSE - there was insufficient resource to associate this file.
  322. */
  323. bool_t clish_shell_push_file(clish_shell_t * instance, const char * fname,
  324. bool_t stop_on_error);
  325. bool_t clish_shell_push_fd(clish_shell_t * instance, FILE * file,
  326. bool_t stop_on_error);
  327. void clish_shell_insert_var(clish_shell_t *instance, clish_var_t *var);
  328. clish_var_t *clish_shell_find_var(clish_shell_t *instance, const char *name);
  329. /*-----------------
  330. * attributes
  331. *----------------- */
  332. const clish_view_t *clish_shell__get_view(const clish_shell_t * instance);
  333. unsigned clish_shell__get_depth(const clish_shell_t * instance);
  334. const char *clish_shell__get_viewid(const clish_shell_t * instance);
  335. const char *clish_shell__get_overview(const clish_shell_t * instance);
  336. tinyrl_t *clish_shell__get_tinyrl(const clish_shell_t * instance);
  337. void *clish_shell__get_client_cookie(const clish_shell_t * instance);
  338. void
  339. clish_shell__set_pwd(clish_shell_t * instance, unsigned index,
  340. const char * line, clish_view_t * view, char * viewid);
  341. char *clish_shell__get_pwd_line(const clish_shell_t * instance,
  342. unsigned index);
  343. char *clish_shell__get_pwd_full(const clish_shell_t * instance, unsigned depth);
  344. clish_view_t *clish_shell__get_pwd_view(const clish_shell_t * instance,
  345. unsigned index);
  346. char *clish_shell__get_pwd_viewid(const clish_shell_t * instance,
  347. unsigned index);
  348. char *clish_shell__get_line(const clish_command_t * cmd, clish_pargv_t * pargv);
  349. konf_client_t *clish_shell__get_client(const clish_shell_t * instance);
  350. FILE *clish_shell__get_istream(const clish_shell_t * instance);
  351. FILE *clish_shell__get_ostream(const clish_shell_t * instance);
  352. void clish_shell__set_lockfile(clish_shell_t * instance, const char * path);
  353. char * clish_shell__get_lockfile(clish_shell_t * instance);
  354. int clish_shell__set_socket(clish_shell_t * instance, const char * path);
  355. int clish_shell_spawn(clish_shell_t * instance,
  356. const pthread_attr_t * attr);
  357. int clish_shell_wait(clish_shell_t * instance);
  358. int clish_shell_spawn_and_wait(clish_shell_t * instance,
  359. const pthread_attr_t * attr);
  360. void clish_shell_load_scheme(clish_shell_t * instance, const char * xml_path);
  361. bool_t clish_shell_loop(clish_shell_t * instance);
  362. clish_shell_state_t clish_shell__get_state(const clish_shell_t * instance);
  363. void clish_shell__set_state(clish_shell_t * instance,
  364. clish_shell_state_t state);
  365. void clish_shell__set_startup_view(clish_shell_t * instance, const char * viewname);
  366. void clish_shell__set_startup_viewid(clish_shell_t * instance, const char * viewid);
  367. void clish_shell__set_default_shebang(clish_shell_t * instance, const char * shebang);
  368. const char * clish_shell__get_default_shebang(const clish_shell_t * instance);
  369. char * clish_shell__expand_text(const clish_shell_t *instance,
  370. clish_command_t *cmd, clish_pargv_t *pargv, const char *text);
  371. char * clish_shell__expand_variable(const clish_shell_t *instance,
  372. clish_command_t *cmd, clish_pargv_t *pargv, const char *var);
  373. const char * clish_shell__get_fifo(clish_shell_t * instance);
  374. void clish_shell__set_interactive(clish_shell_t * instance, bool_t interactive);
  375. bool_t clish_shell__get_interactive(const clish_shell_t * instance);
  376. bool_t clish_shell__get_utf8(const clish_shell_t * instance);
  377. void clish_shell__set_utf8(clish_shell_t * instance, bool_t utf8);
  378. _END_C_DECL
  379. #endif /* _clish_shell_h */
  380. /** @} clish_shell */