source: branches/samba-3.5.x/source3/lib/readline.c@ 833

Last change on this file since 833 was 593, checked in by Herwig Bauernfeind, 14 years ago

Samba 3.5: Update trunk to 3.5.7

File size: 6.1 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 Samba readline wrapper implementation
4 Copyright (C) Simo Sorce 2001
5 Copyright (C) Andrew Tridgell 2001
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19*/
20
21#include "includes.h"
22
23#ifdef HAVE_LIBREADLINE
24# ifdef HAVE_READLINE_READLINE_H
25# include <readline/readline.h>
26# ifdef HAVE_READLINE_HISTORY_H
27# include <readline/history.h>
28# endif
29# else
30# ifdef HAVE_READLINE_H
31# include <readline.h>
32# ifdef HAVE_HISTORY_H
33# include <history.h>
34# endif
35# else
36# undef HAVE_LIBREADLINE
37# endif
38# endif
39#endif
40
41#ifdef HAVE_NEW_LIBREADLINE
42# define RL_COMPLETION_CAST (rl_completion_func_t *)
43#else
44/* This type is missing from libreadline<4.0 (approximately) */
45# define RL_COMPLETION_CAST
46#endif /* HAVE_NEW_LIBREADLINE */
47
48static bool smb_rl_done;
49
50#if HAVE_LIBREADLINE
51/*
52 * MacOS/X does not have rl_done in readline.h, but
53 * readline.so has it
54 */
55extern int rl_done;
56#endif
57
58void smb_readline_done(void)
59{
60 smb_rl_done = true;
61#if HAVE_LIBREADLINE
62 rl_done = 1;
63#endif
64}
65
66/****************************************************************************
67 Display the prompt and wait for input. Call callback() regularly
68****************************************************************************/
69
70static char *smb_readline_replacement(const char *prompt, void (*callback)(void),
71 char **(completion_fn)(const char *text, int start, int end))
72{
73 fd_set fds;
74 char *line = NULL;
75 struct timeval timeout;
76 int fd = x_fileno(x_stdin);
77 char *ret;
78
79 /* Prompt might be NULL in non-interactive mode. */
80 if (prompt) {
81 x_fprintf(x_stdout, "%s", prompt);
82 x_fflush(x_stdout);
83 }
84
85 line = (char *)SMB_MALLOC(BUFSIZ);
86 if (!line) {
87 return NULL;
88 }
89
90 while (!smb_rl_done) {
91 timeout.tv_sec = 5;
92 timeout.tv_usec = 0;
93
94 if (fd < 0 || fd >= FD_SETSIZE) {
95 errno = EBADF;
96 break;
97 }
98
99 FD_ZERO(&fds);
100 FD_SET(fd,&fds);
101
102 if (sys_select_intr(fd+1,&fds,NULL,NULL,&timeout) == 1) {
103 ret = x_fgets(line, BUFSIZ, x_stdin);
104 if (ret == 0) {
105 SAFE_FREE(line);
106 }
107 return ret;
108 }
109#ifdef __OS2__
110#include <conio.h>
111 {
112 char * cp = line;
113 char c;
114 int flag = 1;
115 while (flag && cp < line + sizeof(line) - 1)
116 {
117 c = getch();
118 switch (c)
119 {
120 case 8:
121 {
122 if (cp > line)
123 {
124 cp--;
125 putchar(8);
126 putchar(32);
127 putchar(8);
128 }
129 } break;
130 case 0: break;
131 case 10: // generally should not be
132 case 13:
133 {
134 flag = 0;
135 } break;
136 case 27:
137 {
138 for (; cp > line; cp--)
139 {
140 putchar(8);
141 putchar(32);
142 putchar(8);
143 }
144 } break;
145 default:
146 {
147 *cp++ = c;
148 putchar(c);
149 }
150 }
151 }
152 *cp = 0;
153 printf("\n");
154 return line;
155 }
156#endif /* __OS2__ */
157
158 if (callback) {
159 callback();
160 }
161 }
162 SAFE_FREE(line);
163 return NULL;
164}
165
166/****************************************************************************
167 Display the prompt and wait for input. Call callback() regularly.
168****************************************************************************/
169
170char *smb_readline(const char *prompt, void (*callback)(void),
171 char **(completion_fn)(const char *text, int start, int end))
172{
173 char *ret;
174 bool interactive;
175
176 interactive = isatty(x_fileno(x_stdin)) || getenv("CLI_FORCE_INTERACTIVE");
177 if (!interactive) {
178 return smb_readline_replacement(NULL, callback, completion_fn);
179 }
180
181#if HAVE_LIBREADLINE
182
183 /* Aargh! Readline does bizzare things with the terminal width
184 that mucks up expect(1). Set CLI_NO_READLINE in the environment
185 to force readline not to be used. */
186
187 if (getenv("CLI_NO_READLINE"))
188 return smb_readline_replacement(prompt, callback, completion_fn);
189
190 if (completion_fn) {
191 /* The callback prototype has changed slightly between
192 different versions of Readline, so the same function
193 works in all of them to date, but we get compiler
194 warnings in some. */
195 rl_attempted_completion_function = RL_COMPLETION_CAST completion_fn;
196 }
197
198#if HAVE_DECL_RL_EVENT_HOOK
199 if (callback)
200 rl_event_hook = (Function *)callback;
201#endif
202 ret = readline(prompt);
203 if (ret && *ret)
204 add_history(ret);
205
206#else
207 ret = smb_readline_replacement(prompt, callback, completion_fn);
208#endif
209
210 return ret;
211}
212
213/****************************************************************************
214 * return line buffer text
215 ****************************************************************************/
216const char *smb_readline_get_line_buffer(void)
217{
218#if defined(HAVE_LIBREADLINE)
219 return rl_line_buffer;
220#else
221 return NULL;
222#endif
223}
224
225
226/****************************************************************************
227 * set completion append character
228 ***************************************************************************/
229void smb_readline_ca_char(char c)
230{
231#if defined(HAVE_LIBREADLINE)
232 rl_completion_append_character = c;
233#endif
234}
235
236/****************************************************************************
237history
238****************************************************************************/
239int cmd_history(void)
240{
241#if defined(HAVE_LIBREADLINE) && defined(HAVE_HISTORY_LIST)
242 HIST_ENTRY **hlist;
243 int i;
244
245 hlist = history_list();
246
247 for (i = 0; hlist && hlist[i]; i++) {
248 DEBUG(0, ("%d: %s\n", i, hlist[i]->line));
249 }
250#else
251 DEBUG(0,("no history without readline support\n"));
252#endif
253
254 return 0;
255}
Note: See TracBrowser for help on using the repository browser.