PageRenderTime 71ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/samba-3.5.6/source3/lib/readline.c

https://github.com/theuni/XBMC-deps
C | 201 lines | 124 code | 30 blank | 47 comment | 18 complexity | 72ba448a072a313e165ce084272823ca MD5 | raw file
  1. /*
  2. Unix SMB/CIFS implementation.
  3. Samba readline wrapper implementation
  4. Copyright (C) Simo Sorce 2001
  5. Copyright (C) Andrew Tridgell 2001
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 3 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "includes.h"
  18. #ifdef HAVE_LIBREADLINE
  19. # ifdef HAVE_READLINE_READLINE_H
  20. # include <readline/readline.h>
  21. # ifdef HAVE_READLINE_HISTORY_H
  22. # include <readline/history.h>
  23. # endif
  24. # else
  25. # ifdef HAVE_READLINE_H
  26. # include <readline.h>
  27. # ifdef HAVE_HISTORY_H
  28. # include <history.h>
  29. # endif
  30. # else
  31. # undef HAVE_LIBREADLINE
  32. # endif
  33. # endif
  34. #endif
  35. #ifdef HAVE_NEW_LIBREADLINE
  36. # define RL_COMPLETION_CAST (rl_completion_func_t *)
  37. #else
  38. /* This type is missing from libreadline<4.0 (approximately) */
  39. # define RL_COMPLETION_CAST
  40. #endif /* HAVE_NEW_LIBREADLINE */
  41. static bool smb_rl_done;
  42. #if HAVE_LIBREADLINE
  43. /*
  44. * MacOS/X does not have rl_done in readline.h, but
  45. * readline.so has it
  46. */
  47. extern int rl_done;
  48. #endif
  49. void smb_readline_done(void)
  50. {
  51. smb_rl_done = true;
  52. #if HAVE_LIBREADLINE
  53. rl_done = 1;
  54. #endif
  55. }
  56. /****************************************************************************
  57. Display the prompt and wait for input. Call callback() regularly
  58. ****************************************************************************/
  59. static char *smb_readline_replacement(const char *prompt, void (*callback)(void),
  60. char **(completion_fn)(const char *text, int start, int end))
  61. {
  62. fd_set fds;
  63. char *line = NULL;
  64. struct timeval timeout;
  65. int fd = x_fileno(x_stdin);
  66. char *ret;
  67. /* Prompt might be NULL in non-interactive mode. */
  68. if (prompt) {
  69. x_fprintf(x_stdout, "%s", prompt);
  70. x_fflush(x_stdout);
  71. }
  72. line = (char *)SMB_MALLOC(BUFSIZ);
  73. if (!line) {
  74. return NULL;
  75. }
  76. while (!smb_rl_done) {
  77. timeout.tv_sec = 5;
  78. timeout.tv_usec = 0;
  79. FD_ZERO(&fds);
  80. FD_SET(fd,&fds);
  81. if (sys_select_intr(fd+1,&fds,NULL,NULL,&timeout) == 1) {
  82. ret = x_fgets(line, BUFSIZ, x_stdin);
  83. if (ret == 0) {
  84. SAFE_FREE(line);
  85. }
  86. return ret;
  87. }
  88. if (callback) {
  89. callback();
  90. }
  91. }
  92. SAFE_FREE(line);
  93. return NULL;
  94. }
  95. /****************************************************************************
  96. Display the prompt and wait for input. Call callback() regularly.
  97. ****************************************************************************/
  98. char *smb_readline(const char *prompt, void (*callback)(void),
  99. char **(completion_fn)(const char *text, int start, int end))
  100. {
  101. char *ret;
  102. bool interactive;
  103. interactive = isatty(x_fileno(x_stdin)) || getenv("CLI_FORCE_INTERACTIVE");
  104. if (!interactive) {
  105. return smb_readline_replacement(NULL, callback, completion_fn);
  106. }
  107. #if HAVE_LIBREADLINE
  108. /* Aargh! Readline does bizzare things with the terminal width
  109. that mucks up expect(1). Set CLI_NO_READLINE in the environment
  110. to force readline not to be used. */
  111. if (getenv("CLI_NO_READLINE"))
  112. return smb_readline_replacement(prompt, callback, completion_fn);
  113. if (completion_fn) {
  114. /* The callback prototype has changed slightly between
  115. different versions of Readline, so the same function
  116. works in all of them to date, but we get compiler
  117. warnings in some. */
  118. rl_attempted_completion_function = RL_COMPLETION_CAST completion_fn;
  119. }
  120. #if HAVE_DECL_RL_EVENT_HOOK
  121. if (callback)
  122. rl_event_hook = (Function *)callback;
  123. #endif
  124. ret = readline(prompt);
  125. if (ret && *ret)
  126. add_history(ret);
  127. #else
  128. ret = smb_readline_replacement(prompt, callback, completion_fn);
  129. #endif
  130. return ret;
  131. }
  132. /****************************************************************************
  133. * return line buffer text
  134. ****************************************************************************/
  135. const char *smb_readline_get_line_buffer(void)
  136. {
  137. #if defined(HAVE_LIBREADLINE)
  138. return rl_line_buffer;
  139. #else
  140. return NULL;
  141. #endif
  142. }
  143. /****************************************************************************
  144. * set completion append character
  145. ***************************************************************************/
  146. void smb_readline_ca_char(char c)
  147. {
  148. #if defined(HAVE_LIBREADLINE)
  149. rl_completion_append_character = c;
  150. #endif
  151. }
  152. /****************************************************************************
  153. history
  154. ****************************************************************************/
  155. int cmd_history(void)
  156. {
  157. #if defined(HAVE_LIBREADLINE) && defined(HAVE_HISTORY_LIST)
  158. HIST_ENTRY **hlist;
  159. int i;
  160. hlist = history_list();
  161. for (i = 0; hlist && hlist[i]; i++) {
  162. DEBUG(0, ("%d: %s\n", i, hlist[i]->line));
  163. }
  164. #else
  165. DEBUG(0,("no history without readline support\n"));
  166. #endif
  167. return 0;
  168. }