|
youterm@26
|
1 |
/*
|
|
pancake@1242
|
2 |
* Copyright (C) 2007, 2008, 2009
|
|
youterm@55
|
3 |
* pancake <youterm.com>
|
|
youterm@26
|
4 |
*
|
|
youterm@26
|
5 |
* dietline is free software; you can redistribute it and/or modify
|
|
youterm@26
|
6 |
* it under the terms of the GNU General Public License as published by
|
|
youterm@26
|
7 |
* the Free Software Foundation; either version 2 of the License, or
|
|
youterm@26
|
8 |
* (at your option) any later version.
|
|
youterm@26
|
9 |
*
|
|
youterm@26
|
10 |
* dietline is distributed in the hope that it will be useful,
|
|
youterm@26
|
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
youterm@26
|
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
youterm@26
|
13 |
* GNU General Public License for more details.
|
|
youterm@26
|
14 |
*
|
|
youterm@26
|
15 |
* You should have received a copy of the GNU General Public License
|
|
youterm@26
|
16 |
* along with dietline; if not, write to the Free Software
|
|
youterm@26
|
17 |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
youterm@26
|
18 |
*
|
|
youterm@26
|
19 |
*/
|
|
youterm@26
|
20 |
|
|
youterm@219
|
21 |
#include "dietline.h"
|
|
youterm@219
|
22 |
|
|
youterm@26
|
23 |
/* dietline is a lighweight and portable library similar to GNU readline */
|
|
youterm@26
|
24 |
|
|
youterm@27
|
25 |
#if RADARE_CORE
|
|
youterm@26
|
26 |
#include "main.h"
|
|
youterm@27
|
27 |
#else
|
|
youterm@184
|
28 |
static void cons_set_raw(int b);
|
|
youterm@184
|
29 |
static int cons_get_real_columns();
|
|
youterm@27
|
30 |
#define __UNIX__ 1
|
|
youterm@27
|
31 |
#endif
|
|
youterm@27
|
32 |
|
|
youterm@26
|
33 |
#include <string.h>
|
|
youterm@26
|
34 |
#include <stdlib.h>
|
|
youterm@26
|
35 |
|
|
youterm@26
|
36 |
#if __WINDOWS__
|
|
youterm@26
|
37 |
#include <windows.h>
|
|
youterm@26
|
38 |
#else
|
|
youterm@52
|
39 |
#include <sys/ioctl.h>
|
|
youterm@26
|
40 |
#include <termios.h>
|
|
youterm@26
|
41 |
#include <signal.h>
|
|
youterm@26
|
42 |
#endif
|
|
youterm@26
|
43 |
|
|
youterm@26
|
44 |
/* line input */
|
|
youterm@219
|
45 |
int dl_echo = 1;
|
|
youterm@26
|
46 |
const char *dl_prompt = "> ";
|
|
youterm@219
|
47 |
const char *dl_clipboard = NULL;
|
|
youterm@219
|
48 |
static char *dl_nullstr = "";
|
|
youterm@26
|
49 |
static char dl_buffer[DL_BUFSIZE];
|
|
youterm@26
|
50 |
static int dl_buffer_len = 0;
|
|
youterm@26
|
51 |
static int dl_buffer_idx = 0;
|
|
youterm@26
|
52 |
|
|
youterm@219
|
53 |
/* autocompletion callback */
|
|
youterm@219
|
54 |
char **(*dl_callback)(const char *text, int start, int end) = NULL;
|
|
youterm@219
|
55 |
|
|
youterm@26
|
56 |
/* history */
|
|
youterm@219
|
57 |
char **dl_history = NULL;
|
|
youterm@26
|
58 |
int dl_histsize = DL_HISTSIZE;
|
|
youterm@26
|
59 |
int dl_histidx = 0;
|
|
youterm@26
|
60 |
int dl_autosave = 0; // TODO
|
|
youterm@26
|
61 |
int dl_disable = 0; // TODO use fgets..no autocompletion
|
|
youterm@26
|
62 |
|
|
youterm@87
|
63 |
// TODO : FULL READLINE COMPATIBILITY
|
|
youterm@87
|
64 |
// rl_attempted_completion_function = rad_autocompletion;
|
|
youterm@87
|
65 |
// char **rad_autocompletion(const char *text, int start, int end)
|
|
youterm@87
|
66 |
// return matches = rl_completion_matches (text, rad_offset_matches);
|
|
youterm@87
|
67 |
|
|
youterm@219
|
68 |
int dl_readchar()
|
|
youterm@26
|
69 |
{
|
|
youterm@26
|
70 |
char buf[2];
|
|
youterm@26
|
71 |
#if __WINDOWS__
|
|
youterm@26
|
72 |
LPDWORD out;
|
|
youterm@26
|
73 |
BOOL ret;
|
|
pancake@1245
|
74 |
DWORD mode;
|
|
youterm@26
|
75 |
HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
|
|
youterm@26
|
76 |
|
|
youterm@26
|
77 |
GetConsoleMode(h, &mode);
|
|
youterm@26
|
78 |
SetConsoleMode(h, 0); // RAW
|
|
youterm@26
|
79 |
ret = ReadConsole(h, buf,1, &out, NULL);
|
|
youterm@55
|
80 |
if (!ret) {
|
|
youterm@55
|
81 |
// wine hack-around
|
|
youterm@55
|
82 |
if (read(0,buf,1) == 1)
|
|
youterm@55
|
83 |
return buf[0];
|
|
youterm@26
|
84 |
return -1;
|
|
youterm@55
|
85 |
}
|
|
youterm@26
|
86 |
SetConsoleMode(h, mode);
|
|
youterm@26
|
87 |
#else
|
|
youterm@219
|
88 |
int ret = read(0,buf,1);
|
|
youterm@219
|
89 |
if (ret <1)
|
|
youterm@55
|
90 |
return -1;
|
|
youterm@26
|
91 |
#endif
|
|
youterm@26
|
92 |
return buf[0];
|
|
youterm@26
|
93 |
}
|
|
youterm@26
|
94 |
|
|
youterm@509
|
95 |
/* scripting */
|
|
youterm@509
|
96 |
|
|
youterm@509
|
97 |
#define BLOCK 4096
|
|
youterm@509
|
98 |
static char *labels = NULL;
|
|
pancake@907
|
99 |
static unsigned int size = 0;
|
|
pancake@907
|
100 |
static unsigned int lsize = 0;
|
|
youterm@509
|
101 |
|
|
pancake@1242
|
102 |
static int label_get(const char *name)
|
|
youterm@509
|
103 |
{
|
|
youterm@509
|
104 |
int i, n;
|
|
youterm@509
|
105 |
for(i=0;i<size;i++) {
|
|
youterm@509
|
106 |
if (!strcmp(name, labels+i+4)) {
|
|
youterm@509
|
107 |
memcpy(&n, labels+i, 4);
|
|
youterm@509
|
108 |
return n;
|
|
youterm@509
|
109 |
}
|
|
youterm@509
|
110 |
i+=strlen(labels+i+4)+4;
|
|
youterm@509
|
111 |
}
|
|
youterm@509
|
112 |
return -1;
|
|
youterm@509
|
113 |
}
|
|
youterm@509
|
114 |
|
|
youterm@509
|
115 |
static void label_add (const char *str) {
|
|
pancake@907
|
116 |
unsigned int size = dl_histidx;
|
|
pancake@907
|
117 |
unsigned int len = strlen(str)-1;
|
|
youterm@542
|
118 |
|
|
pancake@907
|
119 |
//eprintf("New label(%s)\n",str);
|
|
youterm@509
|
120 |
memset(labels+lsize+4, '\0', BLOCK-((lsize+len+4)%BLOCK));
|
|
youterm@509
|
121 |
memcpy(labels+lsize, &size, 4);
|
|
youterm@509
|
122 |
memcpy(labels+lsize+4, str, len);
|
|
youterm@509
|
123 |
lsize+=len+4+1;
|
|
youterm@509
|
124 |
}
|
|
youterm@509
|
125 |
|
|
youterm@509
|
126 |
void dl_label_show()
|
|
youterm@509
|
127 |
{
|
|
pancake@907
|
128 |
unsigned int i, p, n = 0;
|
|
youterm@509
|
129 |
for(i=0;i<lsize;i++,n++) {
|
|
youterm@509
|
130 |
memcpy(&p, labels+i, 4);
|
|
youterm@542
|
131 |
printf(" %03d %03d %s\n", i, p, labels+i+4);
|
|
youterm@509
|
132 |
i+=strlen(labels+i+4)+4;
|
|
youterm@509
|
133 |
}
|
|
youterm@509
|
134 |
}
|
|
youterm@509
|
135 |
|
|
youterm@509
|
136 |
static void label_reset()
|
|
youterm@509
|
137 |
{
|
|
youterm@509
|
138 |
lsize = 0;
|
|
youterm@509
|
139 |
free(labels);
|
|
youterm@509
|
140 |
labels = NULL;
|
|
youterm@509
|
141 |
}
|
|
youterm@509
|
142 |
|
|
youterm@509
|
143 |
static int is_label(const char *str)
|
|
youterm@509
|
144 |
{
|
|
@788
|
145 |
/* crappy hack */
|
|
@788
|
146 |
return 0;
|
|
@788
|
147 |
|
|
youterm@542
|
148 |
if (str[0]=='\0')
|
|
youterm@542
|
149 |
return 0;
|
|
youterm@509
|
150 |
if (str[strlen(str)-1]==':') {
|
|
youterm@542
|
151 |
if (str[0]==':') {
|
|
youterm@509
|
152 |
dl_label_show();
|
|
youterm@509
|
153 |
return 2;
|
|
youterm@509
|
154 |
}
|
|
youterm@509
|
155 |
return 1;
|
|
youterm@509
|
156 |
}
|
|
youterm@509
|
157 |
return 0;
|
|
youterm@509
|
158 |
}
|
|
youterm@26
|
159 |
|
|
youterm@26
|
160 |
/* history stuff */
|
|
youterm@509
|
161 |
|
|
youterm@509
|
162 |
int dl_hist_label(const char *label, void (*cb)(const char*))
|
|
youterm@509
|
163 |
{
|
|
@590
|
164 |
int i;
|
|
youterm@787
|
165 |
#if 1
|
|
youterm@787
|
166 |
/* labelling stuff */
|
|
youterm@509
|
167 |
if (label[0]=='.') {
|
|
youterm@509
|
168 |
if (!is_label(label+1))
|
|
youterm@509
|
169 |
return 0;
|
|
youterm@509
|
170 |
} else {
|
|
youterm@509
|
171 |
switch(is_label(label)) {
|
|
youterm@509
|
172 |
case 0:
|
|
youterm@509
|
173 |
case 2:
|
|
youterm@509
|
174 |
return 0;
|
|
youterm@509
|
175 |
}
|
|
youterm@509
|
176 |
}
|
|
youterm@509
|
177 |
|
|
youterm@509
|
178 |
i = label_get(label);
|
|
youterm@509
|
179 |
if (i == -1) {
|
|
youterm@509
|
180 |
label_add(label);
|
|
youterm@509
|
181 |
return 1;
|
|
youterm@509
|
182 |
}
|
|
youterm@787
|
183 |
#endif
|
|
youterm@509
|
184 |
if (dl_history != NULL)
|
|
pancake@1242
|
185 |
for(i=0; i<dl_histsize; i++) {
|
|
youterm@509
|
186 |
if (dl_history[i] == NULL)
|
|
youterm@509
|
187 |
break;
|
|
@590
|
188 |
fprintf(stderr, "%s\n", dl_history[i]);
|
|
youterm@509
|
189 |
if (cb != NULL)
|
|
youterm@509
|
190 |
cb(dl_history[i]);
|
|
@590
|
191 |
else fprintf(stderr, "%s\n", dl_history[i]);
|
|
youterm@509
|
192 |
}
|
|
youterm@509
|
193 |
|
|
youterm@509
|
194 |
return 1;
|
|
youterm@509
|
195 |
}
|
|
youterm@509
|
196 |
|
|
youterm@26
|
197 |
int dl_hist_add(const char *line)
|
|
youterm@26
|
198 |
{
|
|
youterm@345
|
199 |
#if HAVE_LIB_READLINE
|
|
youterm@345
|
200 |
add_history(line);
|
|
youterm@542
|
201 |
#endif
|
|
youterm@107
|
202 |
if (dl_histidx>=dl_histsize)
|
|
youterm@107
|
203 |
dl_histidx = 0; // workaround
|
|
youterm@107
|
204 |
if (*line) { // && dl_histidx < dl_histsize) {
|
|
youterm@26
|
205 |
dl_history[dl_histidx++] = strdup(line);
|
|
youterm@26
|
206 |
return 1;
|
|
youterm@26
|
207 |
}
|
|
youterm@26
|
208 |
return 0;
|
|
youterm@542
|
209 |
//#endif
|
|
youterm@26
|
210 |
}
|
|
youterm@26
|
211 |
|
|
youterm@26
|
212 |
int dl_hist_up()
|
|
youterm@26
|
213 |
{
|
|
youterm@26
|
214 |
if (dl_histidx>0) {
|
|
youterm@26
|
215 |
strncpy(dl_buffer, dl_history[--dl_histidx], DL_BUFSIZE-1);
|
|
youterm@82
|
216 |
dl_buffer_idx=
|
|
youterm@26
|
217 |
dl_buffer_len = strlen(dl_buffer);
|
|
youterm@26
|
218 |
return 1;
|
|
youterm@26
|
219 |
}
|
|
youterm@26
|
220 |
return 0;
|
|
youterm@26
|
221 |
}
|
|
youterm@26
|
222 |
|
|
youterm@26
|
223 |
int dl_hist_down()
|
|
youterm@26
|
224 |
{
|
|
youterm@26
|
225 |
dl_buffer_idx=0;
|
|
youterm@26
|
226 |
if (dl_histidx<dl_histsize) {
|
|
youterm@82
|
227 |
if (dl_history[dl_histidx] == NULL) {
|
|
youterm@82
|
228 |
dl_buffer[0]='\0';
|
|
youterm@82
|
229 |
dl_buffer_idx = dl_buffer_len = 0;
|
|
youterm@26
|
230 |
return 0;
|
|
youterm@82
|
231 |
}
|
|
youterm@26
|
232 |
strncpy(dl_buffer, dl_history[dl_histidx++], DL_BUFSIZE-1);
|
|
youterm@82
|
233 |
dl_buffer_idx=
|
|
youterm@26
|
234 |
dl_buffer_len = strlen(dl_buffer);
|
|
youterm@26
|
235 |
return 1;
|
|
youterm@26
|
236 |
}
|
|
youterm@26
|
237 |
return 0;
|
|
youterm@26
|
238 |
}
|
|
youterm@26
|
239 |
|
|
youterm@219
|
240 |
int dl_hist_list()
|
|
youterm@219
|
241 |
{
|
|
@297
|
242 |
int i = 0;
|
|
youterm@219
|
243 |
|
|
youterm@219
|
244 |
if (dl_history != NULL)
|
|
youterm@219
|
245 |
for(i=0;i<dl_histsize; i++) {
|
|
youterm@219
|
246 |
if (dl_history[i] == NULL)
|
|
youterm@219
|
247 |
break;
|
|
youterm@219
|
248 |
printf("%.3d %s\n", i, dl_history[i]);
|
|
youterm@219
|
249 |
}
|
|
youterm@263
|
250 |
|
|
youterm@263
|
251 |
return i;
|
|
youterm@219
|
252 |
}
|
|
youterm@219
|
253 |
|
|
youterm@26
|
254 |
int dl_hist_free()
|
|
youterm@26
|
255 |
{
|
|
youterm@26
|
256 |
int i;
|
|
youterm@219
|
257 |
if (dl_history != NULL)
|
|
youterm@219
|
258 |
for(i=0;i<dl_histsize; i++) {
|
|
youterm@26
|
259 |
free(dl_history[i]);
|
|
youterm@26
|
260 |
dl_history[i] = NULL;
|
|
youterm@26
|
261 |
}
|
|
youterm@26
|
262 |
return dl_histidx=0, dl_histsize;
|
|
youterm@26
|
263 |
}
|
|
youterm@26
|
264 |
|
|
youterm@26
|
265 |
void dl_free()
|
|
youterm@26
|
266 |
{
|
|
youterm@26
|
267 |
printf("Bye!\n");
|
|
youterm@26
|
268 |
dl_hist_free();
|
|
@590
|
269 |
label_reset();
|
|
youterm@26
|
270 |
free(dl_history);
|
|
youterm@26
|
271 |
}
|
|
youterm@26
|
272 |
|
|
youterm@26
|
273 |
/* load history from file. if file == NULL load from ~/.<prg>.history or so */
|
|
youterm@26
|
274 |
int dl_hist_load(const char *file)
|
|
youterm@26
|
275 |
{
|
|
youterm@354
|
276 |
#if HAVE_LIB_READLINE
|
|
youterm@354
|
277 |
rad_readline_init();
|
|
youterm@354
|
278 |
return 0;
|
|
youterm@354
|
279 |
#else
|
|
youterm@107
|
280 |
char buf[1024];
|
|
youterm@107
|
281 |
FILE *fd;
|
|
youterm@107
|
282 |
|
|
pancake@1201
|
283 |
snprintf(buf, 1023, "%s/%s", get_home_directory(), file);
|
|
youterm@107
|
284 |
fd = fopen(buf, "r");
|
|
youterm@107
|
285 |
if (fd == NULL)
|
|
youterm@107
|
286 |
return 0;
|
|
youterm@107
|
287 |
|
|
youterm@107
|
288 |
fgets(buf, 1023, fd);
|
|
youterm@107
|
289 |
while (!feof(fd)) {
|
|
youterm@107
|
290 |
buf[strlen(buf)-1]='\0';
|
|
youterm@107
|
291 |
dl_hist_add(buf);
|
|
youterm@107
|
292 |
fgets(buf, 1023, fd);
|
|
youterm@107
|
293 |
}
|
|
youterm@107
|
294 |
fclose(fd);
|
|
youterm@107
|
295 |
|
|
youterm@107
|
296 |
return 1;
|
|
youterm@354
|
297 |
#endif
|
|
youterm@26
|
298 |
}
|
|
youterm@26
|
299 |
|
|
youterm@26
|
300 |
int dl_hist_save(const char *file)
|
|
youterm@26
|
301 |
{
|
|
youterm@375
|
302 |
#if HAVE_LIB_READLINE
|
|
youterm@375
|
303 |
rad_readline_finish();
|
|
youterm@375
|
304 |
#else
|
|
youterm@107
|
305 |
char buf[1024];
|
|
youterm@107
|
306 |
FILE *fd;
|
|
youterm@107
|
307 |
int i;
|
|
youterm@107
|
308 |
|
|
pancake@1201
|
309 |
snprintf(buf, 1023, "%s/%s", get_home_directory(), file);
|
|
@148
|
310 |
fd = fopen(buf, "w");
|
|
youterm@107
|
311 |
if (fd == NULL)
|
|
youterm@107
|
312 |
return 0;
|
|
youterm@107
|
313 |
for(i=0;i<dl_histidx;i++) {
|
|
youterm@107
|
314 |
fputs(dl_history[i], fd);
|
|
youterm@107
|
315 |
fputs("\n", fd);
|
|
youterm@107
|
316 |
}
|
|
youterm@107
|
317 |
fclose(fd);
|
|
youterm@107
|
318 |
|
|
youterm@107
|
319 |
return 1;
|
|
youterm@375
|
320 |
#endif
|
|
youterm@107
|
321 |
}
|
|
youterm@107
|
322 |
|
|
youterm@107
|
323 |
int dl_hist_chop(const char *file, int limit)
|
|
youterm@107
|
324 |
{
|
|
youterm@107
|
325 |
/* TODO */
|
|
youterm@72
|
326 |
return 0;
|
|
youterm@26
|
327 |
}
|
|
youterm@26
|
328 |
|
|
youterm@26
|
329 |
/* initialize history stuff */
|
|
youterm@26
|
330 |
int dl_init()
|
|
youterm@26
|
331 |
{
|
|
@348
|
332 |
#if HAVE_LIB_READLINE
|
|
@348
|
333 |
rad_readline_init();
|
|
@348
|
334 |
#endif
|
|
youterm@509
|
335 |
if (labels==NULL)
|
|
youterm@509
|
336 |
labels = malloc(BLOCK);
|
|
youterm@26
|
337 |
dl_history = (char **)malloc(dl_histsize*sizeof(char *));
|
|
youterm@72
|
338 |
if (dl_history==NULL)
|
|
youterm@72
|
339 |
return 0;
|
|
youterm@219
|
340 |
memset(dl_history, '\0', dl_histsize*sizeof(char *));
|
|
youterm@26
|
341 |
dl_histidx = 0;
|
|
youterm@219
|
342 |
dl_histsize = DL_HISTSIZE;
|
|
youterm@219
|
343 |
dl_histidx = 0;
|
|
youterm@219
|
344 |
dl_autosave = 0;
|
|
youterm@219
|
345 |
dl_disable = 0;
|
|
youterm@72
|
346 |
return 1;
|
|
youterm@26
|
347 |
}
|
|
youterm@26
|
348 |
|
|
youterm@26
|
349 |
/* test */
|
|
youterm@26
|
350 |
int dl_printchar()
|
|
youterm@26
|
351 |
{
|
|
youterm@26
|
352 |
unsigned char buf[10];
|
|
youterm@26
|
353 |
|
|
youterm@184
|
354 |
cons_set_raw(1);
|
|
youterm@26
|
355 |
buf[0]=dl_readchar();
|
|
youterm@26
|
356 |
|
|
youterm@26
|
357 |
switch(buf[0]) {
|
|
youterm@26
|
358 |
case 226:
|
|
youterm@26
|
359 |
case 197:
|
|
youterm@26
|
360 |
case 195:
|
|
youterm@26
|
361 |
case 194:
|
|
youterm@26
|
362 |
buf[0] = dl_readchar();
|
|
youterm@26
|
363 |
printf("unicode-%02x-%02x\n", buf[0],buf[1]);
|
|
youterm@26
|
364 |
break;
|
|
youterm@115
|
365 |
case 8: // wtf is 127?
|
|
youterm@26
|
366 |
case 127: printf("backspace\n"); break;
|
|
youterm@26
|
367 |
case 32: printf("space\n"); break;
|
|
youterm@26
|
368 |
case 27:
|
|
youterm@26
|
369 |
read(0, buf, 5);
|
|
youterm@26
|
370 |
printf("esc-%02x-%02x-%02x-%02x\n",
|
|
youterm@26
|
371 |
buf[0],buf[1],buf[2],buf[3]);
|
|
youterm@26
|
372 |
break;
|
|
youterm@26
|
373 |
case 12: printf("^L\n"); break;
|
|
youterm@26
|
374 |
case 13: printf("intro\n"); break;
|
|
youterm@82
|
375 |
case 18: printf("^R\n"); break;
|
|
youterm@26
|
376 |
case 9: printf("tab\n"); break;
|
|
youterm@26
|
377 |
case 3: printf("control-c\n"); break;
|
|
youterm@26
|
378 |
case 0: printf("control-space\n"); break;
|
|
youterm@26
|
379 |
default:
|
|
youterm@26
|
380 |
printf("(code:%d)\n", buf[0]);
|
|
youterm@26
|
381 |
break;
|
|
youterm@26
|
382 |
}
|
|
youterm@26
|
383 |
|
|
youterm@184
|
384 |
cons_set_raw(0);
|
|
youterm@263
|
385 |
|
|
youterm@263
|
386 |
return buf[0];
|
|
youterm@26
|
387 |
}
|
|
youterm@26
|
388 |
|
|
youterm@26
|
389 |
/* main readline function */
|
|
youterm@107
|
390 |
char *dl_readline(int argc, const char **argv)
|
|
youterm@26
|
391 |
{
|
|
youterm@26
|
392 |
int buf[10];
|
|
@297
|
393 |
int i, len = 0;
|
|
@297
|
394 |
int opt = 0;
|
|
youterm@184
|
395 |
int columns = cons_get_real_columns()-2;
|
|
youterm@26
|
396 |
|
|
youterm@26
|
397 |
dl_buffer_idx = dl_buffer_len = 0;
|
|
youterm@30
|
398 |
dl_buffer[0]='\0';
|
|
youterm@26
|
399 |
|
|
youterm@494
|
400 |
#if RADARE_CORE
|
|
youterm@477
|
401 |
dl_echo = config.verbose;
|
|
youterm@494
|
402 |
#endif
|
|
youterm@477
|
403 |
|
|
youterm@26
|
404 |
if (dl_disable) {
|
|
youterm@26
|
405 |
dl_buffer[0]='\0';
|
|
youterm@26
|
406 |
fgets(dl_buffer, DL_BUFSIZE-1, stdin);
|
|
youterm@26
|
407 |
dl_buffer[strlen(dl_buffer)] = '\0';
|
|
youterm@26
|
408 |
return (*dl_buffer)? dl_buffer : NULL;
|
|
youterm@26
|
409 |
}
|
|
youterm@26
|
410 |
|
|
youterm@26
|
411 |
memset(&buf,0,sizeof buf);
|
|
youterm@184
|
412 |
cons_set_raw(1);
|
|
youterm@26
|
413 |
|
|
youterm@219
|
414 |
if (dl_echo) {
|
|
youterm@219
|
415 |
printf("%s", dl_prompt);
|
|
youterm@219
|
416 |
fflush(stdout);
|
|
youterm@219
|
417 |
}
|
|
youterm@26
|
418 |
|
|
youterm@30
|
419 |
#if __UNIX__
|
|
youterm@30
|
420 |
if (feof(stdin))
|
|
youterm@30
|
421 |
return NULL;
|
|
youterm@30
|
422 |
#endif
|
|
youterm@30
|
423 |
|
|
youterm@26
|
424 |
while(1) {
|
|
youterm@219
|
425 |
#if 0
|
|
youterm@26
|
426 |
if (dl_echo) {
|
|
youterm@26
|
427 |
printf(" (");
|
|
youterm@26
|
428 |
for(i=1;i<argc;i++) {
|
|
youterm@26
|
429 |
if (dl_buffer_len==0||!strncmp(argv[i], dl_buffer, dl_buffer_len)) {
|
|
youterm@26
|
430 |
len+=strlen(argv[i])+1;
|
|
youterm@26
|
431 |
if (len+dl_buffer_len+4 >= columns) break;
|
|
youterm@26
|
432 |
printf("%s ", argv[i]);
|
|
youterm@26
|
433 |
}
|
|
youterm@26
|
434 |
}
|
|
youterm@26
|
435 |
printf(")");
|
|
youterm@26
|
436 |
fflush(stdout);
|
|
youterm@26
|
437 |
}
|
|
youterm@219
|
438 |
#endif
|
|
youterm@26
|
439 |
|
|
youterm@26
|
440 |
dl_buffer[dl_buffer_len]='\0';
|
|
youterm@26
|
441 |
buf[0] = dl_readchar();
|
|
youterm@52
|
442 |
|
|
pancake@402
|
443 |
// printf("\x1b[K\r");
|
|
youterm@184
|
444 |
columns = cons_get_real_columns()-2;
|
|
youterm@219
|
445 |
if (columns <1)
|
|
youterm@219
|
446 |
columns = 40;
|
|
youterm@477
|
447 |
if (dl_echo)
|
|
youterm@26
|
448 |
printf("\r%*c\r", columns, ' ');
|
|
youterm@26
|
449 |
|
|
youterm@26
|
450 |
switch(buf[0]) {
|
|
youterm@55
|
451 |
case -1:
|
|
youterm@55
|
452 |
return NULL;
|
|
youterm@84
|
453 |
case 0: // control-space
|
|
youterm@84
|
454 |
/* ignore atm */
|
|
youterm@84
|
455 |
break;
|
|
youterm@26
|
456 |
case 1: // ^A
|
|
youterm@26
|
457 |
dl_buffer_idx = 0;
|
|
youterm@26
|
458 |
break;
|
|
youterm@26
|
459 |
case 5: // ^E
|
|
youterm@26
|
460 |
dl_buffer_idx = dl_buffer_len;
|
|
youterm@26
|
461 |
break;
|
|
youterm@26
|
462 |
case 3: // ^C
|
|
youterm@477
|
463 |
if (dl_echo)
|
|
youterm@477
|
464 |
printf("\n^C\n");
|
|
youterm@26
|
465 |
dl_buffer[dl_buffer_idx = dl_buffer_len = 0] = '\0';
|
|
youterm@26
|
466 |
goto _end;
|
|
youterm@26
|
467 |
case 4: // ^D
|
|
youterm@477
|
468 |
if (dl_echo)
|
|
youterm@477
|
469 |
printf("^D\n");
|
|
youterm@26
|
470 |
if (!dl_buffer[0]) { /* eof */
|
|
youterm@184
|
471 |
cons_set_raw(0);
|
|
youterm@26
|
472 |
return NULL;
|
|
youterm@26
|
473 |
}
|
|
youterm@26
|
474 |
break;
|
|
youterm@219
|
475 |
case 10: // ^J -- ignore
|
|
youterm@219
|
476 |
return dl_buffer;
|
|
youterm@219
|
477 |
case 11: // ^K -- ignore
|
|
youterm@219
|
478 |
break;
|
|
youterm@26
|
479 |
case 19: // ^S -- backspace
|
|
youterm@26
|
480 |
dl_buffer_idx = dl_buffer_idx?dl_buffer_idx-1:0;
|
|
youterm@26
|
481 |
break;
|
|
youterm@26
|
482 |
case 12: // ^L -- right
|
|
youterm@26
|
483 |
dl_buffer_idx = dl_buffer_idx<dl_buffer_len?dl_buffer_idx+1:dl_buffer_len;
|
|
youterm@477
|
484 |
if (dl_echo)
|
|
youterm@477
|
485 |
printf("\x1b[2J\x1b[0;0H");
|
|
youterm@110
|
486 |
fflush(stdout);
|
|
youterm@26
|
487 |
break;
|
|
youterm@219
|
488 |
case 21: // ^U - cut
|
|
youterm@219
|
489 |
dl_clipboard = strdup(dl_buffer);
|
|
youterm@219
|
490 |
dl_buffer[0]='\0';
|
|
youterm@219
|
491 |
dl_buffer_len = 0;
|
|
youterm@219
|
492 |
dl_buffer_idx = 0;
|
|
youterm@219
|
493 |
break;
|
|
youterm@84
|
494 |
case 23: // ^W
|
|
youterm@26
|
495 |
if (dl_buffer_idx>0) {
|
|
youterm@84
|
496 |
for(i=dl_buffer_idx-1;i&&dl_buffer[i]==' ';i--);
|
|
youterm@228
|
497 |
for(;i&&dl_buffer[i]!=' ';i--);
|
|
youterm@228
|
498 |
for(;i>0&&dl_buffer[i]==' ';i--);
|
|
youterm@228
|
499 |
if (i>1) {
|
|
youterm@228
|
500 |
if (dl_buffer[i+1]==' ')
|
|
youterm@84
|
501 |
i+=2;
|
|
youterm@228
|
502 |
} else if (i<0) i=0;
|
|
youterm@26
|
503 |
strcpy(dl_buffer+i, dl_buffer+dl_buffer_idx);
|
|
youterm@26
|
504 |
dl_buffer_len = strlen(dl_buffer);
|
|
youterm@110
|
505 |
dl_buffer_idx = i;
|
|
youterm@26
|
506 |
}
|
|
youterm@26
|
507 |
break;
|
|
youterm@219
|
508 |
case 25: // ^Y - paste
|
|
youterm@219
|
509 |
if (dl_clipboard != NULL) {
|
|
youterm@219
|
510 |
dl_buffer_len += strlen(dl_clipboard);
|
|
youterm@219
|
511 |
// TODO: support endless strings
|
|
youterm@219
|
512 |
if (dl_buffer_len < DL_BUFSIZE) {
|
|
youterm@219
|
513 |
dl_buffer_idx = dl_buffer_len;
|
|
youterm@219
|
514 |
strcat(dl_buffer, dl_clipboard);
|
|
youterm@219
|
515 |
} else dl_buffer_len -= strlen(dl_clipboard);
|
|
youterm@219
|
516 |
}
|
|
youterm@219
|
517 |
break;
|
|
youterm@26
|
518 |
case 16:
|
|
youterm@26
|
519 |
dl_hist_up();
|
|
youterm@26
|
520 |
break;
|
|
youterm@26
|
521 |
case 14:
|
|
youterm@26
|
522 |
dl_hist_down();
|
|
youterm@26
|
523 |
break;
|
|
youterm@26
|
524 |
case 27: //esc-5b-41-00-00
|
|
youterm@26
|
525 |
buf[0] = dl_readchar();
|
|
youterm@26
|
526 |
buf[1] = dl_readchar();
|
|
youterm@26
|
527 |
if (buf[0]==0x5b) {
|
|
youterm@26
|
528 |
switch(buf[1]) {
|
|
youterm@26
|
529 |
case 0x33: // supr
|
|
youterm@26
|
530 |
if (dl_buffer_idx<dl_buffer_len)
|
|
youterm@26
|
531 |
strcpy(dl_buffer, dl_buffer+1);
|
|
youterm@26
|
532 |
break;
|
|
youterm@26
|
533 |
/* arrows */
|
|
youterm@26
|
534 |
case 0x41:
|
|
youterm@26
|
535 |
dl_hist_up();
|
|
youterm@26
|
536 |
break;
|
|
youterm@26
|
537 |
case 0x42:
|
|
youterm@26
|
538 |
dl_hist_down();
|
|
youterm@26
|
539 |
break;
|
|
youterm@26
|
540 |
case 0x43:
|
|
youterm@26
|
541 |
dl_buffer_idx = dl_buffer_idx<dl_buffer_len?dl_buffer_idx+1:dl_buffer_len;
|
|
youterm@26
|
542 |
break;
|
|
youterm@26
|
543 |
case 0x44:
|
|
youterm@26
|
544 |
dl_buffer_idx = dl_buffer_idx?dl_buffer_idx-1:0;
|
|
youterm@26
|
545 |
break;
|
|
youterm@26
|
546 |
}
|
|
youterm@26
|
547 |
}
|
|
youterm@26
|
548 |
|
|
youterm@26
|
549 |
break;
|
|
youterm@26
|
550 |
case 8:
|
|
youterm@26
|
551 |
case 127:
|
|
youterm@26
|
552 |
if (dl_buffer_idx < dl_buffer_len) {
|
|
youterm@26
|
553 |
if (dl_buffer_idx>0) {
|
|
youterm@26
|
554 |
dl_buffer_idx--;
|
|
youterm@26
|
555 |
memcpy(dl_buffer+dl_buffer_idx, dl_buffer+dl_buffer_idx+1,strlen(dl_buffer+dl_buffer_idx));
|
|
youterm@26
|
556 |
}
|
|
youterm@26
|
557 |
} else {
|
|
youterm@26
|
558 |
dl_buffer_idx = --dl_buffer_len;
|
|
youterm@26
|
559 |
if (dl_buffer_len<0) dl_buffer_len=0;
|
|
youterm@26
|
560 |
dl_buffer[dl_buffer_len]='\0';
|
|
youterm@26
|
561 |
}
|
|
youterm@115
|
562 |
if (dl_buffer_idx<0)
|
|
youterm@115
|
563 |
dl_buffer_idx = 0;
|
|
youterm@26
|
564 |
break;
|
|
youterm@26
|
565 |
case 9:// tab
|
|
youterm@26
|
566 |
/* autocomplete */
|
|
youterm@26
|
567 |
// XXX does not autocompletes correctly
|
|
youterm@26
|
568 |
// XXX needs to check if valid results have the same prefix (from 1 to N)
|
|
youterm@219
|
569 |
if (dl_callback != NULL) {
|
|
youterm@263
|
570 |
//const char *from = strrchr(dl_buffer, ' ');
|
|
youterm@263
|
571 |
//char **res = dl_callback(dl_buffer, (from==NULL)?dl_buffer_idx:from-dl_buffer, dl_buffer_len);
|
|
youterm@219
|
572 |
/* TODO: manage res */
|
|
youterm@219
|
573 |
} else {
|
|
youterm@219
|
574 |
if (dl_buffer_idx>0)
|
|
youterm@219
|
575 |
for(i=1,opt=0;i<argc;i++)
|
|
youterm@219
|
576 |
if (!strncmp(argv[i], dl_buffer, dl_buffer_idx))
|
|
youterm@219
|
577 |
opt++;
|
|
youterm@26
|
578 |
|
|
youterm@219
|
579 |
if (dl_buffer_len>0&&opt==1)
|
|
youterm@219
|
580 |
for(i=1;i<argc;i++) {
|
|
youterm@221
|
581 |
if (!strncmp(dl_buffer, argv[i], dl_buffer_len)) {
|
|
youterm@219
|
582 |
strcpy(dl_buffer, argv[i]);
|
|
youterm@219
|
583 |
dl_buffer_idx = dl_buffer_len = strlen(dl_buffer);
|
|
youterm@219
|
584 |
// TODO: if only 1 keyword hits:
|
|
youterm@219
|
585 |
// if (argv[i][dl_buffer_len]=='\0') {
|
|
youterm@219
|
586 |
// strcat(dl_buffer, " ");
|
|
youterm@219
|
587 |
// dl_buffer_len++;
|
|
youterm@219
|
588 |
// }
|
|
youterm@219
|
589 |
break;
|
|
youterm@219
|
590 |
}
|
|
youterm@26
|
591 |
}
|
|
youterm@219
|
592 |
|
|
youterm@219
|
593 |
/* show options */
|
|
youterm@219
|
594 |
if (dl_buffer_idx==0 || opt>1) {
|
|
youterm@477
|
595 |
if (dl_echo)
|
|
youterm@477
|
596 |
printf("%s%s\n",dl_prompt,dl_buffer);
|
|
youterm@219
|
597 |
for(i=1;i<argc;i++) {
|
|
youterm@219
|
598 |
if (dl_buffer_len==0||!strncmp(argv[i], dl_buffer, dl_buffer_len)) {
|
|
youterm@219
|
599 |
len+=strlen(argv[i]);
|
|
youterm@219
|
600 |
// if (len+dl_buffer_len+4 >= columns) break;
|
|
youterm@477
|
601 |
if (dl_echo)
|
|
youterm@477
|
602 |
printf("%s ", argv[i]);
|
|
youterm@219
|
603 |
}
|
|
youterm@219
|
604 |
}
|
|
youterm@477
|
605 |
if (dl_echo)
|
|
youterm@477
|
606 |
printf("\n");
|
|
youterm@26
|
607 |
}
|
|
youterm@219
|
608 |
fflush(stdout);
|
|
youterm@26
|
609 |
}
|
|
youterm@26
|
610 |
break;
|
|
youterm@82
|
611 |
case 18:
|
|
youterm@82
|
612 |
// TODO: SUPPORT FOR ^R (search command in history)
|
|
youterm@82
|
613 |
break;
|
|
youterm@26
|
614 |
case 13:
|
|
youterm@26
|
615 |
goto _end;
|
|
youterm@26
|
616 |
#if 0
|
|
youterm@26
|
617 |
// force command fit
|
|
youterm@26
|
618 |
for(i=1;i<argc;i++) {
|
|
youterm@26
|
619 |
if (dl_buffer_len==0 || !strncmp(argv[i], dl_buffer, dl_buffer_len)) {
|
|
youterm@26
|
620 |
printf("%*c", columns, ' ');
|
|
youterm@26
|
621 |
printf("\r");
|
|
youterm@26
|
622 |
printf("\n\n(%s)\n\n", dl_buffer);
|
|
youterm@184
|
623 |
cons_set_raw(0);
|
|
youterm@26
|
624 |
return dl_buffer;
|
|
youterm@26
|
625 |
}
|
|
youterm@26
|
626 |
}
|
|
youterm@26
|
627 |
#endif
|
|
youterm@26
|
628 |
default:
|
|
youterm@26
|
629 |
/* XXX use ^A & ^E */
|
|
youterm@26
|
630 |
if (dl_buffer_idx<dl_buffer_len) {
|
|
youterm@26
|
631 |
for(i = ++dl_buffer_len;i>dl_buffer_idx;i--)
|
|
youterm@26
|
632 |
dl_buffer[i] = dl_buffer[i-1];
|
|
youterm@26
|
633 |
dl_buffer[dl_buffer_idx] = buf[0];
|
|
youterm@26
|
634 |
} else {
|
|
youterm@26
|
635 |
dl_buffer[dl_buffer_len]=buf[0];
|
|
youterm@26
|
636 |
dl_buffer_len++;
|
|
youterm@26
|
637 |
if (dl_buffer_len>1000)
|
|
youterm@26
|
638 |
dl_buffer_len--;
|
|
youterm@26
|
639 |
dl_buffer[dl_buffer_len]='\0';
|
|
youterm@26
|
640 |
}
|
|
youterm@26
|
641 |
dl_buffer_idx++;
|
|
youterm@26
|
642 |
break;
|
|
youterm@26
|
643 |
}
|
|
youterm@219
|
644 |
if (dl_echo) {
|
|
youterm@219
|
645 |
printf("\r%s%s", dl_prompt, dl_buffer);
|
|
youterm@219
|
646 |
printf("\r%s", dl_prompt);
|
|
youterm@219
|
647 |
|
|
youterm@219
|
648 |
for(i=0;i<dl_buffer_idx;i++)
|
|
youterm@219
|
649 |
printf("%c", dl_buffer[i]);
|
|
youterm@219
|
650 |
fflush(stdout);
|
|
youterm@219
|
651 |
}
|
|
youterm@26
|
652 |
}
|
|
youterm@26
|
653 |
|
|
youterm@26
|
654 |
_end:
|
|
youterm@184
|
655 |
cons_set_raw(0);
|
|
youterm@219
|
656 |
if (dl_echo) {
|
|
youterm@219
|
657 |
printf("\r%s%s\n", dl_prompt, dl_buffer);
|
|
youterm@219
|
658 |
fflush(stdout);
|
|
youterm@219
|
659 |
}
|
|
youterm@219
|
660 |
|
|
youterm@219
|
661 |
if (dl_buffer[0]=='!' && dl_buffer[1]=='\0') {
|
|
youterm@219
|
662 |
dl_hist_list();
|
|
youterm@219
|
663 |
return dl_nullstr;
|
|
youterm@219
|
664 |
}
|
|
youterm@30
|
665 |
//write(1,"\n",1);
|
|
youterm@26
|
666 |
return dl_buffer;
|
|
youterm@26
|
667 |
}
|
|
youterm@26
|
668 |
|
|
youterm@26
|
669 |
#ifndef RADARE_CORE
|
|
youterm@26
|
670 |
|
|
youterm@110
|
671 |
|
|
youterm@110
|
672 |
#if __UNIX__
|
|
youterm@110
|
673 |
static struct termios tio_old, tio_new;
|
|
youterm@110
|
674 |
#include "main.h"
|
|
youterm@110
|
675 |
#include <stdarg.h>
|
|
youterm@110
|
676 |
#include <termios.h>
|
|
youterm@110
|
677 |
#include <sys/ioctl.h>
|
|
youterm@110
|
678 |
#include <sys/wait.h>
|
|
youterm@110
|
679 |
#include <sys/socket.h>
|
|
youterm@110
|
680 |
#endif
|
|
youterm@110
|
681 |
|
|
youterm@184
|
682 |
static void cons_set_raw(int b)
|
|
youterm@26
|
683 |
{
|
|
youterm@26
|
684 |
#if __UNIX__
|
|
youterm@26
|
685 |
if (b) {
|
|
youterm@26
|
686 |
tcgetattr(0, &tio_old);
|
|
youterm@26
|
687 |
memcpy ((char *)&tio_new, (char *)&tio_old, sizeof(struct termios));
|
|
youterm@26
|
688 |
tio_new.c_iflag &= ~(BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
|
|
youterm@26
|
689 |
tio_new.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
|
|
youterm@26
|
690 |
tio_new.c_cflag &= ~(CSIZE|PARENB);
|
|
youterm@26
|
691 |
tio_new.c_cflag |= CS8;
|
|
youterm@26
|
692 |
tio_new.c_cc[VMIN]=1; // Solaris stuff hehe
|
|
youterm@26
|
693 |
tcsetattr(0, TCSANOW, &tio_new);
|
|
youterm@26
|
694 |
fflush(stdout);
|
|
youterm@26
|
695 |
return;
|
|
youterm@26
|
696 |
}
|
|
youterm@26
|
697 |
|
|
youterm@26
|
698 |
tcsetattr(0, TCSANOW, &tio_old);
|
|
youterm@26
|
699 |
fflush(stdout);
|
|
youterm@26
|
700 |
#endif
|
|
youterm@26
|
701 |
}
|
|
youterm@26
|
702 |
|
|
youterm@184
|
703 |
static int cons_get_real_columns()
|
|
youterm@52
|
704 |
{
|
|
youterm@52
|
705 |
#if __WINDOWS__
|
|
youterm@52
|
706 |
return 78;
|
|
youterm@52
|
707 |
#endif
|
|
youterm@52
|
708 |
struct winsize win;
|
|
youterm@52
|
709 |
|
|
youterm@52
|
710 |
if (ioctl(1, TIOCGWINSZ, &win)) {
|
|
youterm@52
|
711 |
/* default values */
|
|
youterm@52
|
712 |
// win.ws_col = 80;
|
|
youterm@52
|
713 |
// win.ws_row = 23;
|
|
youterm@52
|
714 |
}
|
|
youterm@52
|
715 |
|
|
youterm@52
|
716 |
return win.ws_col;
|
|
youterm@52
|
717 |
}
|
|
youterm@26
|
718 |
|
|
youterm@219
|
719 |
int main(int argc, const char **argv)
|
|
youterm@26
|
720 |
{
|
|
youterm@26
|
721 |
char *ret;
|
|
youterm@26
|
722 |
|
|
youterm@26
|
723 |
dl_histsize = 100;
|
|
youterm@26
|
724 |
dl_prompt = "$ ";
|
|
youterm@26
|
725 |
dl_init();
|
|
youterm@26
|
726 |
|
|
youterm@26
|
727 |
dl_printchar();
|
|
youterm@26
|
728 |
|
|
youterm@26
|
729 |
do {
|
|
youterm@26
|
730 |
ret = dl_readline(argc, argv);
|
|
youterm@26
|
731 |
if (ret) {
|
|
youterm@26
|
732 |
printf(" [line] '%s'\n", ret);
|
|
youterm@26
|
733 |
dl_hist_add(ret);
|
|
youterm@26
|
734 |
}
|
|
youterm@26
|
735 |
} while(ret!=NULL);
|
|
youterm@26
|
736 |
dl_free();
|
|
youterm@26
|
737 |
return 0;
|
|
youterm@26
|
738 |
}
|
|
youterm@26
|
739 |
|
|
youterm@26
|
740 |
#endif
|