source: trunk/server/libcli/smbreadline/smbreadline.c@ 752

Last change on this file since 752 was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 5.4 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#include "../lib/util/select.h"
23#include "system/filesys.h"
24#include "system/select.h"
25#include "system/readline.h"
26#include "libcli/smbreadline/smbreadline.h"
27
28#undef malloc
29
30#ifdef HAVE_LIBREADLINE
31# ifdef HAVE_READLINE_READLINE_H
32# include <readline/readline.h>
33# ifdef HAVE_READLINE_HISTORY_H
34# include <readline/history.h>
35# endif
36# else
37# ifdef HAVE_READLINE_H
38# include <readline.h>
39# ifdef HAVE_HISTORY_H
40# include <history.h>
41# endif
42# else
43# undef HAVE_LIBREADLINE
44# endif
45# endif
46#endif
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 char *line = NULL;
74 int fd = x_fileno(x_stdin);
75 char *ret;
76
77 /* Prompt might be NULL in non-interactive mode. */
78 if (prompt) {
79 x_fprintf(x_stdout, "%s", prompt);
80 x_fflush(x_stdout);
81 }
82
83 line = (char *)malloc(BUFSIZ);
84 if (!line) {
85 return NULL;
86 }
87
88 while (!smb_rl_done) {
89 struct pollfd pfd;
90
91 ZERO_STRUCT(pfd);
92 pfd.fd = fd;
93 pfd.events = POLLIN|POLLHUP;
94
95 if (sys_poll_intr(&pfd, 1, 5000) == 1) {
96 ret = x_fgets(line, BUFSIZ, x_stdin);
97 if (ret == 0) {
98 SAFE_FREE(line);
99 }
100 return ret;
101 }
102#ifdef __OS2__
103#include <conio.h>
104 {
105 char * cp = line;
106 char c;
107 int flag = 1;
108 while (flag && cp < line + sizeof(line) - 1)
109 {
110 c = getch();
111 switch (c)
112 {
113 case 8:
114 {
115 if (cp > line)
116 {
117 cp--;
118 putchar(8);
119 putchar(32);
120 putchar(8);
121 }
122 } break;
123 case 0: break;
124 case 10: // generally should not be
125 case 13:
126 {
127 flag = 0;
128 } break;
129 case 27:
130 {
131 for (; cp > line; cp--)
132 {
133 putchar(8);
134 putchar(32);
135 putchar(8);
136 }
137 } break;
138 default:
139 {
140 *cp++ = c;
141 putchar(c);
142 }
143 }
144 }
145 *cp = 0;
146 printf("\n");
147 return line;
148 }
149#endif /* __OS2__ */
150
151 if (callback) {
152 callback();
153 }
154 }
155 SAFE_FREE(line);
156 return NULL;
157}
158
159/****************************************************************************
160 Display the prompt and wait for input. Call callback() regularly.
161****************************************************************************/
162
163char *smb_readline(const char *prompt, void (*callback)(void),
164 char **(completion_fn)(const char *text, int start, int end))
165{
166 char *ret;
167 bool interactive;
168
169 interactive = isatty(x_fileno(x_stdin)) || getenv("CLI_FORCE_INTERACTIVE");
170 if (!interactive) {
171 return smb_readline_replacement(NULL, callback, completion_fn);
172 }
173
174#if HAVE_LIBREADLINE
175
176 /* Aargh! Readline does bizzare things with the terminal width
177 that mucks up expect(1). Set CLI_NO_READLINE in the environment
178 to force readline not to be used. */
179
180 if (getenv("CLI_NO_READLINE"))
181 return smb_readline_replacement(prompt, callback, completion_fn);
182
183 if (completion_fn) {
184 /* The callback prototype has changed slightly between
185 different versions of Readline, so the same function
186 works in all of them to date, but we get compiler
187 warnings in some. */
188 rl_attempted_completion_function = RL_COMPLETION_CAST completion_fn;
189 }
190
191#if HAVE_DECL_RL_EVENT_HOOK
192 if (callback)
193 rl_event_hook = (Function *)callback;
194#endif
195 ret = readline(prompt);
196 if (ret && *ret)
197 add_history(ret);
198
199#else
200 ret = smb_readline_replacement(prompt, callback, completion_fn);
201#endif
202
203 return ret;
204}
205
206/****************************************************************************
207 * return line buffer text
208 ****************************************************************************/
209const char *smb_readline_get_line_buffer(void)
210{
211#if defined(HAVE_LIBREADLINE)
212 return rl_line_buffer;
213#else
214 return NULL;
215#endif
216}
217
218
219/****************************************************************************
220 * set completion append character
221 ***************************************************************************/
222void smb_readline_ca_char(char c)
223{
224#if defined(HAVE_LIBREADLINE)
225 rl_completion_append_character = c;
226#endif
227}
Note: See TracBrowser for help on using the repository browser.