readline.c revision 1.101 1 /* $NetBSD: readline.c,v 1.101 2012/03/21 05:33:26 matt Exp $ */
2
3 /*-
4 * Copyright (c) 1997 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jaromir Dolecek.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "config.h"
33 #if !defined(lint) && !defined(SCCSID)
34 __RCSID("$NetBSD: readline.c,v 1.101 2012/03/21 05:33:26 matt Exp $");
35 #endif /* not lint && not SCCSID */
36
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <stdio.h>
40 #include <dirent.h>
41 #include <string.h>
42 #include <pwd.h>
43 #include <ctype.h>
44 #include <stdlib.h>
45 #include <unistd.h>
46 #include <limits.h>
47 #include <errno.h>
48 #include <fcntl.h>
49 #include <setjmp.h>
50 #include <vis.h>
51
52 #include "readline/readline.h"
53 #include "el.h"
54 #include "fcns.h" /* for EL_NUM_FCNS */
55 #include "histedit.h"
56 #include "filecomplete.h"
57
58 void rl_prep_terminal(int);
59 void rl_deprep_terminal(void);
60
61 /* for rl_complete() */
62 #define TAB '\r'
63
64 /* see comment at the #ifdef for sense of this */
65 /* #define GDB_411_HACK */
66
67 /* readline compatibility stuff - look at readline sources/documentation */
68 /* to see what these variables mean */
69 const char *rl_library_version = "EditLine wrapper";
70 int rl_readline_version = RL_READLINE_VERSION;
71 static char empty[] = { '\0' };
72 static char expand_chars[] = { ' ', '\t', '\n', '=', '(', '\0' };
73 static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',
74 '>', '<', '=', ';', '|', '&', '{', '(', '\0' };
75 char *rl_readline_name = empty;
76 FILE *rl_instream = NULL;
77 FILE *rl_outstream = NULL;
78 int rl_point = 0;
79 int rl_end = 0;
80 char *rl_line_buffer = NULL;
81 VCPFunction *rl_linefunc = NULL;
82 int rl_done = 0;
83 VFunction *rl_event_hook = NULL;
84 KEYMAP_ENTRY_ARRAY emacs_standard_keymap,
85 emacs_meta_keymap,
86 emacs_ctlx_keymap;
87
88 int history_base = 1; /* probably never subject to change */
89 int history_length = 0;
90 int max_input_history = 0;
91 char history_expansion_char = '!';
92 char history_subst_char = '^';
93 char *history_no_expand_chars = expand_chars;
94 Function *history_inhibit_expansion_function = NULL;
95 char *history_arg_extract(int start, int end, const char *str);
96
97 int rl_inhibit_completion = 0;
98 int rl_attempted_completion_over = 0;
99 char *rl_basic_word_break_characters = break_chars;
100 char *rl_completer_word_break_characters = NULL;
101 char *rl_completer_quote_characters = NULL;
102 Function *rl_completion_entry_function = NULL;
103 CPPFunction *rl_attempted_completion_function = NULL;
104 Function *rl_pre_input_hook = NULL;
105 Function *rl_startup1_hook = NULL;
106 int (*rl_getc_function)(FILE *) = NULL;
107 char *rl_terminal_name = NULL;
108 int rl_already_prompted = 0;
109 int rl_filename_completion_desired = 0;
110 int rl_ignore_completion_duplicates = 0;
111 int rl_catch_signals = 1;
112 int readline_echoing_p = 1;
113 int _rl_print_completions_horizontally = 0;
114 VFunction *rl_redisplay_function = NULL;
115 Function *rl_startup_hook = NULL;
116 VFunction *rl_completion_display_matches_hook = NULL;
117 VFunction *rl_prep_term_function = (VFunction *)rl_prep_terminal;
118 VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal;
119 KEYMAP_ENTRY_ARRAY emacs_meta_keymap;
120
121 /*
122 * The current prompt string.
123 */
124 char *rl_prompt = NULL;
125 /*
126 * This is set to character indicating type of completion being done by
127 * rl_complete_internal(); this is available for application completion
128 * functions.
129 */
130 int rl_completion_type = 0;
131
132 /*
133 * If more than this number of items results from query for possible
134 * completions, we ask user if they are sure to really display the list.
135 */
136 int rl_completion_query_items = 100;
137
138 /*
139 * List of characters which are word break characters, but should be left
140 * in the parsed text when it is passed to the completion function.
141 * Shell uses this to help determine what kind of completing to do.
142 */
143 char *rl_special_prefixes = NULL;
144
145 /*
146 * This is the character appended to the completed words if at the end of
147 * the line. Default is ' ' (a space).
148 */
149 int rl_completion_append_character = ' ';
150
151 /* stuff below is used internally by libedit for readline emulation */
152
153 static History *h = NULL;
154 static EditLine *e = NULL;
155 static Function *map[256];
156 static jmp_buf topbuf;
157
158 /* internal functions */
159 static unsigned char _el_rl_complete(EditLine *, int);
160 static unsigned char _el_rl_tstp(EditLine *, int);
161 static char *_get_prompt(EditLine *);
162 static int _getc_function(EditLine *, char *);
163 static HIST_ENTRY *_move_history(int);
164 static int _history_expand_command(const char *, size_t, size_t,
165 char **);
166 static char *_rl_compat_sub(const char *, const char *,
167 const char *, int);
168 static int _rl_event_read_char(EditLine *, char *);
169 static void _rl_update_pos(void);
170
171
172 /* ARGSUSED */
173 static char *
174 _get_prompt(EditLine *el __attribute__((__unused__)))
175 {
176 rl_already_prompted = 1;
177 return rl_prompt;
178 }
179
180
181 /*
182 * generic function for moving around history
183 */
184 static HIST_ENTRY *
185 _move_history(int op)
186 {
187 HistEvent ev;
188 static HIST_ENTRY rl_he;
189
190 if (history(h, &ev, op) != 0)
191 return NULL;
192
193 rl_he.line = ev.str;
194 rl_he.data = NULL;
195
196 return &rl_he;
197 }
198
199
200 /*
201 * read one key from user defined input function
202 */
203 static int
204 /*ARGSUSED*/
205 _getc_function(EditLine *el __attribute__((__unused__)), char *c)
206 {
207 int i;
208
209 i = (*rl_getc_function)(NULL);
210 if (i == -1)
211 return 0;
212 *c = (char)i;
213 return 1;
214 }
215
216 static void
217 _resize_fun(EditLine *el, void *a)
218 {
219 const LineInfo *li;
220 char **ap = a;
221
222 li = el_line(el);
223 /* a cheesy way to get rid of const cast. */
224 *ap = memchr(li->buffer, *li->buffer, (size_t)1);
225 }
226
227 static const char *
228 _default_history_file(void)
229 {
230 struct passwd *p;
231 static char path[PATH_MAX];
232
233 if (*path)
234 return path;
235 if ((p = getpwuid(getuid())) == NULL)
236 return NULL;
237 (void)snprintf(path, sizeof(path), "%s/.history", p->pw_dir);
238 return path;
239 }
240
241 /*
242 * READLINE compatibility stuff
243 */
244
245 /*
246 * Set the prompt
247 */
248 int
249 rl_set_prompt(const char *prompt)
250 {
251 char *p;
252
253 if (!prompt)
254 prompt = "";
255 if (rl_prompt != NULL && strcmp(rl_prompt, prompt) == 0)
256 return 0;
257 if (rl_prompt)
258 el_free(rl_prompt);
259 rl_prompt = strdup(prompt);
260 if (rl_prompt == NULL)
261 return -1;
262
263 while ((p = strchr(rl_prompt, RL_PROMPT_END_IGNORE)) != NULL)
264 *p = RL_PROMPT_START_IGNORE;
265
266 return 0;
267 }
268
269 /*
270 * initialize rl compat stuff
271 */
272 int
273 rl_initialize(void)
274 {
275 HistEvent ev;
276 int editmode = 1;
277 struct termios t;
278
279 if (e != NULL)
280 el_end(e);
281 if (h != NULL)
282 history_end(h);
283
284 if (!rl_instream)
285 rl_instream = stdin;
286 if (!rl_outstream)
287 rl_outstream = stdout;
288
289 /*
290 * See if we don't really want to run the editor
291 */
292 if (tcgetattr(fileno(rl_instream), &t) != -1 && (t.c_lflag & ECHO) == 0)
293 editmode = 0;
294
295 e = el_init(rl_readline_name, rl_instream, rl_outstream, stderr);
296
297 if (!editmode)
298 el_set(e, EL_EDITMODE, 0);
299
300 h = history_init();
301 if (!e || !h)
302 return -1;
303
304 history(h, &ev, H_SETSIZE, INT_MAX); /* unlimited */
305 history_length = 0;
306 max_input_history = INT_MAX;
307 el_set(e, EL_HIST, history, h);
308
309 /* Setup resize function */
310 el_set(e, EL_RESIZE, _resize_fun, &rl_line_buffer);
311
312 /* setup getc function if valid */
313 if (rl_getc_function)
314 el_set(e, EL_GETCFN, _getc_function);
315
316 /* for proper prompt printing in readline() */
317 if (rl_set_prompt("") == -1) {
318 history_end(h);
319 el_end(e);
320 return -1;
321 }
322 el_set(e, EL_PROMPT, _get_prompt, RL_PROMPT_START_IGNORE);
323 el_set(e, EL_SIGNAL, rl_catch_signals);
324
325 /* set default mode to "emacs"-style and read setting afterwards */
326 /* so this can be overriden */
327 el_set(e, EL_EDITOR, "emacs");
328 if (rl_terminal_name != NULL)
329 el_set(e, EL_TERMINAL, rl_terminal_name);
330 else
331 el_get(e, EL_TERMINAL, &rl_terminal_name);
332
333 /*
334 * Word completion - this has to go AFTER rebinding keys
335 * to emacs-style.
336 */
337 el_set(e, EL_ADDFN, "rl_complete",
338 "ReadLine compatible completion function",
339 _el_rl_complete);
340 el_set(e, EL_BIND, "^I", "rl_complete", NULL);
341
342 /*
343 * Send TSTP when ^Z is pressed.
344 */
345 el_set(e, EL_ADDFN, "rl_tstp",
346 "ReadLine compatible suspend function",
347 _el_rl_tstp);
348 el_set(e, EL_BIND, "^Z", "rl_tstp", NULL);
349
350 /* read settings from configuration file */
351 el_source(e, NULL);
352
353 /*
354 * Unfortunately, some applications really do use rl_point
355 * and rl_line_buffer directly.
356 */
357 _resize_fun(e, &rl_line_buffer);
358 _rl_update_pos();
359
360 if (rl_startup_hook)
361 (*rl_startup_hook)(NULL, 0);
362
363 return 0;
364 }
365
366
367 /*
368 * read one line from input stream and return it, chomping
369 * trailing newline (if there is any)
370 */
371 char *
372 readline(const char *p)
373 {
374 HistEvent ev;
375 const char * volatile prompt = p;
376 int count;
377 const char *ret;
378 char *buf;
379 static int used_event_hook;
380
381 if (e == NULL || h == NULL)
382 rl_initialize();
383
384 rl_done = 0;
385
386 (void)setjmp(topbuf);
387
388 /* update prompt accordingly to what has been passed */
389 if (rl_set_prompt(prompt) == -1)
390 return NULL;
391
392 if (rl_pre_input_hook)
393 (*rl_pre_input_hook)(NULL, 0);
394
395 if (rl_event_hook && !(e->el_flags&NO_TTY)) {
396 el_set(e, EL_GETCFN, _rl_event_read_char);
397 used_event_hook = 1;
398 }
399
400 if (!rl_event_hook && used_event_hook) {
401 el_set(e, EL_GETCFN, EL_BUILTIN_GETCFN);
402 used_event_hook = 0;
403 }
404
405 rl_already_prompted = 0;
406
407 /* get one line from input stream */
408 ret = el_gets(e, &count);
409
410 if (ret && count > 0) {
411 int lastidx;
412
413 buf = strdup(ret);
414 if (buf == NULL)
415 return NULL;
416 lastidx = count - 1;
417 if (buf[lastidx] == '\n')
418 buf[lastidx] = '\0';
419 } else
420 buf = NULL;
421
422 history(h, &ev, H_GETSIZE);
423 history_length = ev.num;
424
425 return buf;
426 }
427
428 /*
429 * history functions
430 */
431
432 /*
433 * is normally called before application starts to use
434 * history expansion functions
435 */
436 void
437 using_history(void)
438 {
439 if (h == NULL || e == NULL)
440 rl_initialize();
441 }
442
443
444 /*
445 * substitute ``what'' with ``with'', returning resulting string; if
446 * globally == 1, substitutes all occurrences of what, otherwise only the
447 * first one
448 */
449 static char *
450 _rl_compat_sub(const char *str, const char *what, const char *with,
451 int globally)
452 {
453 const char *s;
454 char *r, *result;
455 size_t len, with_len, what_len;
456
457 len = strlen(str);
458 with_len = strlen(with);
459 what_len = strlen(what);
460
461 /* calculate length we need for result */
462 s = str;
463 while (*s) {
464 if (*s == *what && !strncmp(s, what, what_len)) {
465 len += with_len - what_len;
466 if (!globally)
467 break;
468 s += what_len;
469 } else
470 s++;
471 }
472 r = result = el_malloc((len + 1) * sizeof(*r));
473 if (result == NULL)
474 return NULL;
475 s = str;
476 while (*s) {
477 if (*s == *what && !strncmp(s, what, what_len)) {
478 (void)strncpy(r, with, with_len);
479 r += with_len;
480 s += what_len;
481 if (!globally) {
482 (void)strcpy(r, s);
483 return result;
484 }
485 } else
486 *r++ = *s++;
487 }
488 *r = '\0';
489 return result;
490 }
491
492 static char *last_search_pat; /* last !?pat[?] search pattern */
493 static char *last_search_match; /* last !?pat[?] that matched */
494
495 const char *
496 get_history_event(const char *cmd, int *cindex, int qchar)
497 {
498 int idx, sign, sub, num, begin, ret;
499 size_t len;
500 char *pat;
501 const char *rptr;
502 HistEvent ev;
503
504 idx = *cindex;
505 if (cmd[idx++] != history_expansion_char)
506 return NULL;
507
508 /* find out which event to take */
509 if (cmd[idx] == history_expansion_char || cmd[idx] == '\0') {
510 if (history(h, &ev, H_FIRST) != 0)
511 return NULL;
512 *cindex = cmd[idx]? (idx + 1):idx;
513 return ev.str;
514 }
515 sign = 0;
516 if (cmd[idx] == '-') {
517 sign = 1;
518 idx++;
519 }
520
521 if ('0' <= cmd[idx] && cmd[idx] <= '9') {
522 HIST_ENTRY *rl_he;
523
524 num = 0;
525 while (cmd[idx] && '0' <= cmd[idx] && cmd[idx] <= '9') {
526 num = num * 10 + cmd[idx] - '0';
527 idx++;
528 }
529 if (sign)
530 num = history_length - num + 1;
531
532 if (!(rl_he = history_get(num)))
533 return NULL;
534
535 *cindex = idx;
536 return rl_he->line;
537 }
538 sub = 0;
539 if (cmd[idx] == '?') {
540 sub = 1;
541 idx++;
542 }
543 begin = idx;
544 while (cmd[idx]) {
545 if (cmd[idx] == '\n')
546 break;
547 if (sub && cmd[idx] == '?')
548 break;
549 if (!sub && (cmd[idx] == ':' || cmd[idx] == ' '
550 || cmd[idx] == '\t' || cmd[idx] == qchar))
551 break;
552 idx++;
553 }
554 len = (size_t)idx - (size_t)begin;
555 if (sub && cmd[idx] == '?')
556 idx++;
557 if (sub && len == 0 && last_search_pat && *last_search_pat)
558 pat = last_search_pat;
559 else if (len == 0)
560 return NULL;
561 else {
562 if ((pat = el_malloc((len + 1) * sizeof(*pat))) == NULL)
563 return NULL;
564 (void)strncpy(pat, cmd + begin, len);
565 pat[len] = '\0';
566 }
567
568 if (history(h, &ev, H_CURR) != 0) {
569 if (pat != last_search_pat)
570 el_free(pat);
571 return NULL;
572 }
573 num = ev.num;
574
575 if (sub) {
576 if (pat != last_search_pat) {
577 if (last_search_pat)
578 el_free(last_search_pat);
579 last_search_pat = pat;
580 }
581 ret = history_search(pat, -1);
582 } else
583 ret = history_search_prefix(pat, -1);
584
585 if (ret == -1) {
586 /* restore to end of list on failed search */
587 history(h, &ev, H_FIRST);
588 (void)fprintf(rl_outstream, "%s: Event not found\n", pat);
589 if (pat != last_search_pat)
590 el_free(pat);
591 return NULL;
592 }
593
594 if (sub && len) {
595 if (last_search_match && last_search_match != pat)
596 el_free(last_search_match);
597 last_search_match = pat;
598 }
599
600 if (pat != last_search_pat)
601 el_free(pat);
602
603 if (history(h, &ev, H_CURR) != 0)
604 return NULL;
605 *cindex = idx;
606 rptr = ev.str;
607
608 /* roll back to original position */
609 (void)history(h, &ev, H_SET, num);
610
611 return rptr;
612 }
613
614 /*
615 * the real function doing history expansion - takes as argument command
616 * to do and data upon which the command should be executed
617 * does expansion the way I've understood readline documentation
618 *
619 * returns 0 if data was not modified, 1 if it was and 2 if the string
620 * should be only printed and not executed; in case of error,
621 * returns -1 and *result points to NULL
622 * it's callers responsibility to free() string returned in *result
623 */
624 static int
625 _history_expand_command(const char *command, size_t offs, size_t cmdlen,
626 char **result)
627 {
628 char *tmp, *search = NULL, *aptr;
629 const char *ptr, *cmd;
630 static char *from = NULL, *to = NULL;
631 int start, end, idx, has_mods = 0;
632 int p_on = 0, g_on = 0;
633
634 *result = NULL;
635 aptr = NULL;
636 ptr = NULL;
637
638 /* First get event specifier */
639 idx = 0;
640
641 if (strchr(":^*$", command[offs + 1])) {
642 char str[4];
643 /*
644 * "!:" is shorthand for "!!:".
645 * "!^", "!*" and "!$" are shorthand for
646 * "!!:^", "!!:*" and "!!:$" respectively.
647 */
648 str[0] = str[1] = '!';
649 str[2] = '0';
650 ptr = get_history_event(str, &idx, 0);
651 idx = (command[offs + 1] == ':')? 1:0;
652 has_mods = 1;
653 } else {
654 if (command[offs + 1] == '#') {
655 /* use command so far */
656 if ((aptr = el_malloc((offs + 1) * sizeof(*aptr)))
657 == NULL)
658 return -1;
659 (void)strncpy(aptr, command, offs);
660 aptr[offs] = '\0';
661 idx = 1;
662 } else {
663 int qchar;
664
665 qchar = (offs > 0 && command[offs - 1] == '"')? '"':0;
666 ptr = get_history_event(command + offs, &idx, qchar);
667 }
668 has_mods = command[offs + (size_t)idx] == ':';
669 }
670
671 if (ptr == NULL && aptr == NULL)
672 return -1;
673
674 if (!has_mods) {
675 *result = strdup(aptr ? aptr : ptr);
676 if (aptr)
677 el_free(aptr);
678 if (*result == NULL)
679 return -1;
680 return 1;
681 }
682
683 cmd = command + offs + idx + 1;
684
685 /* Now parse any word designators */
686
687 if (*cmd == '%') /* last word matched by ?pat? */
688 tmp = strdup(last_search_match? last_search_match:"");
689 else if (strchr("^*$-0123456789", *cmd)) {
690 start = end = -1;
691 if (*cmd == '^')
692 start = end = 1, cmd++;
693 else if (*cmd == '$')
694 start = -1, cmd++;
695 else if (*cmd == '*')
696 start = 1, cmd++;
697 else if (*cmd == '-' || isdigit((unsigned char) *cmd)) {
698 start = 0;
699 while (*cmd && '0' <= *cmd && *cmd <= '9')
700 start = start * 10 + *cmd++ - '0';
701
702 if (*cmd == '-') {
703 if (isdigit((unsigned char) cmd[1])) {
704 cmd++;
705 end = 0;
706 while (*cmd && '0' <= *cmd && *cmd <= '9')
707 end = end * 10 + *cmd++ - '0';
708 } else if (cmd[1] == '$') {
709 cmd += 2;
710 end = -1;
711 } else {
712 cmd++;
713 end = -2;
714 }
715 } else if (*cmd == '*')
716 end = -1, cmd++;
717 else
718 end = start;
719 }
720 tmp = history_arg_extract(start, end, aptr? aptr:ptr);
721 if (tmp == NULL) {
722 (void)fprintf(rl_outstream, "%s: Bad word specifier",
723 command + offs + idx);
724 if (aptr)
725 el_free(aptr);
726 return -1;
727 }
728 } else
729 tmp = strdup(aptr? aptr:ptr);
730
731 if (aptr)
732 el_free(aptr);
733
734 if (*cmd == '\0' || ((size_t)(cmd - (command + offs)) >= cmdlen)) {
735 *result = tmp;
736 return 1;
737 }
738
739 for (; *cmd; cmd++) {
740 if (*cmd == ':')
741 continue;
742 else if (*cmd == 'h') { /* remove trailing path */
743 if ((aptr = strrchr(tmp, '/')) != NULL)
744 *aptr = '\0';
745 } else if (*cmd == 't') { /* remove leading path */
746 if ((aptr = strrchr(tmp, '/')) != NULL) {
747 aptr = strdup(aptr + 1);
748 el_free(tmp);
749 tmp = aptr;
750 }
751 } else if (*cmd == 'r') { /* remove trailing suffix */
752 if ((aptr = strrchr(tmp, '.')) != NULL)
753 *aptr = '\0';
754 } else if (*cmd == 'e') { /* remove all but suffix */
755 if ((aptr = strrchr(tmp, '.')) != NULL) {
756 aptr = strdup(aptr);
757 el_free(tmp);
758 tmp = aptr;
759 }
760 } else if (*cmd == 'p') /* print only */
761 p_on = 1;
762 else if (*cmd == 'g')
763 g_on = 2;
764 else if (*cmd == 's' || *cmd == '&') {
765 char *what, *with, delim;
766 size_t len, from_len;
767 size_t size;
768
769 if (*cmd == '&' && (from == NULL || to == NULL))
770 continue;
771 else if (*cmd == 's') {
772 delim = *(++cmd), cmd++;
773 size = 16;
774 what = el_realloc(from, size * sizeof(*what));
775 if (what == NULL) {
776 el_free(from);
777 el_free(tmp);
778 return 0;
779 }
780 len = 0;
781 for (; *cmd && *cmd != delim; cmd++) {
782 if (*cmd == '\\' && cmd[1] == delim)
783 cmd++;
784 if (len >= size) {
785 char *nwhat;
786 nwhat = el_realloc(what,
787 (size <<= 1) *
788 sizeof(*nwhat));
789 if (nwhat == NULL) {
790 el_free(what);
791 el_free(tmp);
792 return 0;
793 }
794 what = nwhat;
795 }
796 what[len++] = *cmd;
797 }
798 what[len] = '\0';
799 from = what;
800 if (*what == '\0') {
801 el_free(what);
802 if (search) {
803 from = strdup(search);
804 if (from == NULL) {
805 el_free(tmp);
806 return 0;
807 }
808 } else {
809 from = NULL;
810 el_free(tmp);
811 return -1;
812 }
813 }
814 cmd++; /* shift after delim */
815 if (!*cmd)
816 continue;
817
818 size = 16;
819 with = el_realloc(to, size * sizeof(*with));
820 if (with == NULL) {
821 el_free(to);
822 el_free(tmp);
823 return -1;
824 }
825 len = 0;
826 from_len = strlen(from);
827 for (; *cmd && *cmd != delim; cmd++) {
828 if (len + from_len + 1 >= size) {
829 char *nwith;
830 size += from_len + 1;
831 nwith = el_realloc(with,
832 size * sizeof(*nwith));
833 if (nwith == NULL) {
834 el_free(with);
835 el_free(tmp);
836 return -1;
837 }
838 with = nwith;
839 }
840 if (*cmd == '&') {
841 /* safe */
842 (void)strcpy(&with[len], from);
843 len += from_len;
844 continue;
845 }
846 if (*cmd == '\\'
847 && (*(cmd + 1) == delim
848 || *(cmd + 1) == '&'))
849 cmd++;
850 with[len++] = *cmd;
851 }
852 with[len] = '\0';
853 to = with;
854 }
855
856 aptr = _rl_compat_sub(tmp, from, to, g_on);
857 if (aptr) {
858 el_free(tmp);
859 tmp = aptr;
860 }
861 g_on = 0;
862 }
863 }
864 *result = tmp;
865 return p_on? 2:1;
866 }
867
868
869 /*
870 * csh-style history expansion
871 */
872 int
873 history_expand(char *str, char **output)
874 {
875 int ret = 0;
876 size_t idx, i, size;
877 char *tmp, *result;
878
879 if (h == NULL || e == NULL)
880 rl_initialize();
881
882 if (history_expansion_char == 0) {
883 *output = strdup(str);
884 return 0;
885 }
886
887 *output = NULL;
888 if (str[0] == history_subst_char) {
889 /* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */
890 *output = el_malloc((strlen(str) + 4 + 1) * sizeof(**output));
891 if (*output == NULL)
892 return 0;
893 (*output)[0] = (*output)[1] = history_expansion_char;
894 (*output)[2] = ':';
895 (*output)[3] = 's';
896 (void)strcpy((*output) + 4, str);
897 str = *output;
898 } else {
899 *output = strdup(str);
900 if (*output == NULL)
901 return 0;
902 }
903
904 #define ADD_STRING(what, len, fr) \
905 { \
906 if (idx + len + 1 > size) { \
907 char *nresult = el_realloc(result, \
908 (size += len + 1) * sizeof(*nresult)); \
909 if (nresult == NULL) { \
910 el_free(*output); \
911 if (/*CONSTCOND*/fr) \
912 el_free(tmp); \
913 return 0; \
914 } \
915 result = nresult; \
916 } \
917 (void)strncpy(&result[idx], what, len); \
918 idx += len; \
919 result[idx] = '\0'; \
920 }
921
922 result = NULL;
923 size = idx = 0;
924 tmp = NULL;
925 for (i = 0; str[i];) {
926 int qchar, loop_again;
927 size_t len, start, j;
928
929 qchar = 0;
930 loop_again = 1;
931 start = j = i;
932 loop:
933 for (; str[j]; j++) {
934 if (str[j] == '\\' &&
935 str[j + 1] == history_expansion_char) {
936 (void)strcpy(&str[j], &str[j + 1]);
937 continue;
938 }
939 if (!loop_again) {
940 if (isspace((unsigned char) str[j])
941 || str[j] == qchar)
942 break;
943 }
944 if (str[j] == history_expansion_char
945 && !strchr(history_no_expand_chars, str[j + 1])
946 && (!history_inhibit_expansion_function ||
947 (*history_inhibit_expansion_function)(str,
948 (int)j) == 0))
949 break;
950 }
951
952 if (str[j] && loop_again) {
953 i = j;
954 qchar = (j > 0 && str[j - 1] == '"' )? '"':0;
955 j++;
956 if (str[j] == history_expansion_char)
957 j++;
958 loop_again = 0;
959 goto loop;
960 }
961 len = i - start;
962 ADD_STRING(&str[start], len, 0);
963
964 if (str[i] == '\0' || str[i] != history_expansion_char) {
965 len = j - i;
966 ADD_STRING(&str[i], len, 0);
967 if (start == 0)
968 ret = 0;
969 else
970 ret = 1;
971 break;
972 }
973 ret = _history_expand_command (str, i, (j - i), &tmp);
974 if (ret > 0 && tmp) {
975 len = strlen(tmp);
976 ADD_STRING(tmp, len, 1);
977 }
978 if (tmp) {
979 el_free(tmp);
980 tmp = NULL;
981 }
982 i = j;
983 }
984
985 /* ret is 2 for "print only" option */
986 if (ret == 2) {
987 add_history(result);
988 #ifdef GDB_411_HACK
989 /* gdb 4.11 has been shipped with readline, where */
990 /* history_expand() returned -1 when the line */
991 /* should not be executed; in readline 2.1+ */
992 /* it should return 2 in such a case */
993 ret = -1;
994 #endif
995 }
996 el_free(*output);
997 *output = result;
998
999 return ret;
1000 }
1001
1002 /*
1003 * Return a string consisting of arguments of "str" from "start" to "end".
1004 */
1005 char *
1006 history_arg_extract(int start, int end, const char *str)
1007 {
1008 size_t i, len, max;
1009 char **arr, *result = NULL;
1010
1011 arr = history_tokenize(str);
1012 if (!arr)
1013 return NULL;
1014 if (arr && *arr == NULL)
1015 goto out;
1016
1017 for (max = 0; arr[max]; max++)
1018 continue;
1019 max--;
1020
1021 if (start == '$')
1022 start = (int)max;
1023 if (end == '$')
1024 end = (int)max;
1025 if (end < 0)
1026 end = (int)max + end + 1;
1027 if (start < 0)
1028 start = end;
1029
1030 if (start < 0 || end < 0 || (size_t)start > max ||
1031 (size_t)end > max || start > end)
1032 goto out;
1033
1034 for (i = (size_t)start, len = 0; i <= (size_t)end; i++)
1035 len += strlen(arr[i]) + 1;
1036 len++;
1037 result = el_malloc(len * sizeof(*result));
1038 if (result == NULL)
1039 goto out;
1040
1041 for (i = (size_t)start, len = 0; i <= (size_t)end; i++) {
1042 (void)strcpy(result + len, arr[i]);
1043 len += strlen(arr[i]);
1044 if (i < (size_t)end)
1045 result[len++] = ' ';
1046 }
1047 result[len] = '\0';
1048
1049 out:
1050 for (i = 0; arr[i]; i++)
1051 el_free(arr[i]);
1052 el_free(arr);
1053
1054 return result;
1055 }
1056
1057 /*
1058 * Parse the string into individual tokens,
1059 * similar to how shell would do it.
1060 */
1061 char **
1062 history_tokenize(const char *str)
1063 {
1064 int size = 1, idx = 0, i, start;
1065 size_t len;
1066 char **result = NULL, *temp, delim = '\0';
1067
1068 for (i = 0; str[i];) {
1069 while (isspace((unsigned char) str[i]))
1070 i++;
1071 start = i;
1072 for (; str[i];) {
1073 if (str[i] == '\\') {
1074 if (str[i+1] != '\0')
1075 i++;
1076 } else if (str[i] == delim)
1077 delim = '\0';
1078 else if (!delim &&
1079 (isspace((unsigned char) str[i]) ||
1080 strchr("()<>;&|$", str[i])))
1081 break;
1082 else if (!delim && strchr("'`\"", str[i]))
1083 delim = str[i];
1084 if (str[i])
1085 i++;
1086 }
1087
1088 if (idx + 2 >= size) {
1089 char **nresult;
1090 size <<= 1;
1091 nresult = el_realloc(result, (size_t)size * sizeof(*nresult));
1092 if (nresult == NULL) {
1093 el_free(result);
1094 return NULL;
1095 }
1096 result = nresult;
1097 }
1098 len = (size_t)i - (size_t)start;
1099 temp = el_malloc((size_t)(len + 1) * sizeof(*temp));
1100 if (temp == NULL) {
1101 for (i = 0; i < idx; i++)
1102 el_free(result[i]);
1103 el_free(result);
1104 return NULL;
1105 }
1106 (void)strncpy(temp, &str[start], len);
1107 temp[len] = '\0';
1108 result[idx++] = temp;
1109 result[idx] = NULL;
1110 if (str[i])
1111 i++;
1112 }
1113 return result;
1114 }
1115
1116
1117 /*
1118 * limit size of history record to ``max'' events
1119 */
1120 void
1121 stifle_history(int max)
1122 {
1123 HistEvent ev;
1124
1125 if (h == NULL || e == NULL)
1126 rl_initialize();
1127
1128 if (history(h, &ev, H_SETSIZE, max) == 0)
1129 max_input_history = max;
1130 }
1131
1132
1133 /*
1134 * "unlimit" size of history - set the limit to maximum allowed int value
1135 */
1136 int
1137 unstifle_history(void)
1138 {
1139 HistEvent ev;
1140 int omax;
1141
1142 history(h, &ev, H_SETSIZE, INT_MAX);
1143 omax = max_input_history;
1144 max_input_history = INT_MAX;
1145 return omax; /* some value _must_ be returned */
1146 }
1147
1148
1149 int
1150 history_is_stifled(void)
1151 {
1152
1153 /* cannot return true answer */
1154 return max_input_history != INT_MAX;
1155 }
1156
1157 static const char _history_tmp_template[] = "/tmp/.historyXXXXXX";
1158
1159 int
1160 history_truncate_file (const char *filename, int nlines)
1161 {
1162 int ret = 0;
1163 FILE *fp, *tp;
1164 char template[sizeof(_history_tmp_template)];
1165 char buf[4096];
1166 int fd;
1167 char *cp;
1168 off_t off;
1169 int count = 0;
1170 ssize_t left = 0;
1171
1172 if (filename == NULL && (filename = _default_history_file()) == NULL)
1173 return errno;
1174 if ((fp = fopen(filename, "r+")) == NULL)
1175 return errno;
1176 strcpy(template, _history_tmp_template);
1177 if ((fd = mkstemp(template)) == -1) {
1178 ret = errno;
1179 goto out1;
1180 }
1181
1182 if ((tp = fdopen(fd, "r+")) == NULL) {
1183 close(fd);
1184 ret = errno;
1185 goto out2;
1186 }
1187
1188 for(;;) {
1189 if (fread(buf, sizeof(buf), (size_t)1, fp) != 1) {
1190 if (ferror(fp)) {
1191 ret = errno;
1192 break;
1193 }
1194 if (fseeko(fp, (off_t)sizeof(buf) * count, SEEK_SET) ==
1195 (off_t)-1) {
1196 ret = errno;
1197 break;
1198 }
1199 left = (ssize_t)fread(buf, (size_t)1, sizeof(buf), fp);
1200 if (ferror(fp)) {
1201 ret = errno;
1202 break;
1203 }
1204 if (left == 0) {
1205 count--;
1206 left = sizeof(buf);
1207 } else if (fwrite(buf, (size_t)left, (size_t)1, tp)
1208 != 1) {
1209 ret = errno;
1210 break;
1211 }
1212 fflush(tp);
1213 break;
1214 }
1215 if (fwrite(buf, sizeof(buf), (size_t)1, tp) != 1) {
1216 ret = errno;
1217 break;
1218 }
1219 count++;
1220 }
1221 if (ret)
1222 goto out3;
1223 cp = buf + left - 1;
1224 if(*cp != '\n')
1225 cp++;
1226 for(;;) {
1227 while (--cp >= buf) {
1228 if (*cp == '\n') {
1229 if (--nlines == 0) {
1230 if (++cp >= buf + sizeof(buf)) {
1231 count++;
1232 cp = buf;
1233 }
1234 break;
1235 }
1236 }
1237 }
1238 if (nlines <= 0 || count == 0)
1239 break;
1240 count--;
1241 if (fseeko(tp, (off_t)sizeof(buf) * count, SEEK_SET) < 0) {
1242 ret = errno;
1243 break;
1244 }
1245 if (fread(buf, sizeof(buf), (size_t)1, tp) != 1) {
1246 if (ferror(tp)) {
1247 ret = errno;
1248 break;
1249 }
1250 ret = EAGAIN;
1251 break;
1252 }
1253 cp = buf + sizeof(buf);
1254 }
1255
1256 if (ret || nlines > 0)
1257 goto out3;
1258
1259 if (fseeko(fp, (off_t)0, SEEK_SET) == (off_t)-1) {
1260 ret = errno;
1261 goto out3;
1262 }
1263
1264 if (fseeko(tp, (off_t)sizeof(buf) * count + (cp - buf), SEEK_SET) ==
1265 (off_t)-1) {
1266 ret = errno;
1267 goto out3;
1268 }
1269
1270 for(;;) {
1271 if ((left = (ssize_t)fread(buf, (size_t)1, sizeof(buf), tp)) == 0) {
1272 if (ferror(fp))
1273 ret = errno;
1274 break;
1275 }
1276 if (fwrite(buf, (size_t)left, (size_t)1, fp) != 1) {
1277 ret = errno;
1278 break;
1279 }
1280 }
1281 fflush(fp);
1282 if((off = ftello(fp)) > 0)
1283 (void)ftruncate(fileno(fp), off);
1284 out3:
1285 fclose(tp);
1286 out2:
1287 unlink(template);
1288 out1:
1289 fclose(fp);
1290
1291 return ret;
1292 }
1293
1294
1295 /*
1296 * read history from a file given
1297 */
1298 int
1299 read_history(const char *filename)
1300 {
1301 HistEvent ev;
1302
1303 if (h == NULL || e == NULL)
1304 rl_initialize();
1305 if (filename == NULL && (filename = _default_history_file()) == NULL)
1306 return errno;
1307 return history(h, &ev, H_LOAD, filename) == -1 ?
1308 (errno ? errno : EINVAL) : 0;
1309 }
1310
1311
1312 /*
1313 * write history to a file given
1314 */
1315 int
1316 write_history(const char *filename)
1317 {
1318 HistEvent ev;
1319
1320 if (h == NULL || e == NULL)
1321 rl_initialize();
1322 if (filename == NULL && (filename = _default_history_file()) == NULL)
1323 return errno;
1324 return history(h, &ev, H_SAVE, filename) == -1 ?
1325 (errno ? errno : EINVAL) : 0;
1326 }
1327
1328
1329 /*
1330 * returns history ``num''th event
1331 *
1332 * returned pointer points to static variable
1333 */
1334 HIST_ENTRY *
1335 history_get(int num)
1336 {
1337 static HIST_ENTRY she;
1338 HistEvent ev;
1339 int curr_num;
1340
1341 if (h == NULL || e == NULL)
1342 rl_initialize();
1343
1344 /* save current position */
1345 if (history(h, &ev, H_CURR) != 0)
1346 return NULL;
1347 curr_num = ev.num;
1348
1349 /* start from the oldest */
1350 if (history(h, &ev, H_LAST) != 0)
1351 return NULL; /* error */
1352
1353 /* look forwards for event matching specified offset */
1354 if (history(h, &ev, H_NEXT_EVDATA, num, &she.data))
1355 return NULL;
1356
1357 she.line = ev.str;
1358
1359 /* restore pointer to where it was */
1360 (void)history(h, &ev, H_SET, curr_num);
1361
1362 return &she;
1363 }
1364
1365
1366 /*
1367 * add the line to history table
1368 */
1369 int
1370 add_history(const char *line)
1371 {
1372 HistEvent ev;
1373
1374 if (h == NULL || e == NULL)
1375 rl_initialize();
1376
1377 (void)history(h, &ev, H_ENTER, line);
1378 if (history(h, &ev, H_GETSIZE) == 0)
1379 history_length = ev.num;
1380
1381 return !(history_length > 0); /* return 0 if all is okay */
1382 }
1383
1384
1385 /*
1386 * remove the specified entry from the history list and return it.
1387 */
1388 HIST_ENTRY *
1389 remove_history(int num)
1390 {
1391 HIST_ENTRY *he;
1392 HistEvent ev;
1393
1394 if (h == NULL || e == NULL)
1395 rl_initialize();
1396
1397 if ((he = el_malloc(sizeof(*he))) == NULL)
1398 return NULL;
1399
1400 if (history(h, &ev, H_DELDATA, num, &he->data) != 0) {
1401 el_free(he);
1402 return NULL;
1403 }
1404
1405 he->line = ev.str;
1406 if (history(h, &ev, H_GETSIZE) == 0)
1407 history_length = ev.num;
1408
1409 return he;
1410 }
1411
1412
1413 /*
1414 * replace the line and data of the num-th entry
1415 */
1416 HIST_ENTRY *
1417 replace_history_entry(int num, const char *line, histdata_t data)
1418 {
1419 HIST_ENTRY *he;
1420 HistEvent ev;
1421 int curr_num;
1422
1423 if (h == NULL || e == NULL)
1424 rl_initialize();
1425
1426 /* save current position */
1427 if (history(h, &ev, H_CURR) != 0)
1428 return NULL;
1429 curr_num = ev.num;
1430
1431 /* start from the oldest */
1432 if (history(h, &ev, H_LAST) != 0)
1433 return NULL; /* error */
1434
1435 if ((he = el_malloc(sizeof(*he))) == NULL)
1436 return NULL;
1437
1438 /* look forwards for event matching specified offset */
1439 if (history(h, &ev, H_NEXT_EVDATA, num, &he->data))
1440 goto out;
1441
1442 he->line = strdup(ev.str);
1443 if (he->line == NULL)
1444 goto out;
1445
1446 if (history(h, &ev, H_REPLACE, line, data))
1447 goto out;
1448
1449 /* restore pointer to where it was */
1450 if (history(h, &ev, H_SET, curr_num))
1451 goto out;
1452
1453 return he;
1454 out:
1455 el_free(he);
1456 return NULL;
1457 }
1458
1459 /*
1460 * clear the history list - delete all entries
1461 */
1462 void
1463 clear_history(void)
1464 {
1465 HistEvent ev;
1466
1467 (void)history(h, &ev, H_CLEAR);
1468 history_length = 0;
1469 }
1470
1471
1472 /*
1473 * returns offset of the current history event
1474 */
1475 int
1476 where_history(void)
1477 {
1478 HistEvent ev;
1479 int curr_num, off;
1480
1481 if (history(h, &ev, H_CURR) != 0)
1482 return 0;
1483 curr_num = ev.num;
1484
1485 (void)history(h, &ev, H_FIRST);
1486 off = 1;
1487 while (ev.num != curr_num && history(h, &ev, H_NEXT) == 0)
1488 off++;
1489
1490 return off;
1491 }
1492
1493
1494 /*
1495 * returns current history event or NULL if there is no such event
1496 */
1497 HIST_ENTRY *
1498 current_history(void)
1499 {
1500
1501 return _move_history(H_CURR);
1502 }
1503
1504
1505 /*
1506 * returns total number of bytes history events' data are using
1507 */
1508 int
1509 history_total_bytes(void)
1510 {
1511 HistEvent ev;
1512 int curr_num;
1513 size_t size;
1514
1515 if (history(h, &ev, H_CURR) != 0)
1516 return -1;
1517 curr_num = ev.num;
1518
1519 (void)history(h, &ev, H_FIRST);
1520 size = 0;
1521 do
1522 size += strlen(ev.str) * sizeof(*ev.str);
1523 while (history(h, &ev, H_NEXT) == 0);
1524
1525 /* get to the same position as before */
1526 history(h, &ev, H_PREV_EVENT, curr_num);
1527
1528 return (int)size;
1529 }
1530
1531
1532 /*
1533 * sets the position in the history list to ``pos''
1534 */
1535 int
1536 history_set_pos(int pos)
1537 {
1538 HistEvent ev;
1539 int curr_num;
1540
1541 if (pos >= history_length || pos < 0)
1542 return -1;
1543
1544 (void)history(h, &ev, H_CURR);
1545 curr_num = ev.num;
1546
1547 /*
1548 * use H_DELDATA to set to nth history (without delete) by passing
1549 * (void **)-1
1550 */
1551 if (history(h, &ev, H_DELDATA, pos, (void **)-1)) {
1552 (void)history(h, &ev, H_SET, curr_num);
1553 return -1;
1554 }
1555 return 0;
1556 }
1557
1558
1559 /*
1560 * returns previous event in history and shifts pointer accordingly
1561 */
1562 HIST_ENTRY *
1563 previous_history(void)
1564 {
1565
1566 return _move_history(H_PREV);
1567 }
1568
1569
1570 /*
1571 * returns next event in history and shifts pointer accordingly
1572 */
1573 HIST_ENTRY *
1574 next_history(void)
1575 {
1576
1577 return _move_history(H_NEXT);
1578 }
1579
1580
1581 /*
1582 * searches for first history event containing the str
1583 */
1584 int
1585 history_search(const char *str, int direction)
1586 {
1587 HistEvent ev;
1588 const char *strp;
1589 int curr_num;
1590
1591 if (history(h, &ev, H_CURR) != 0)
1592 return -1;
1593 curr_num = ev.num;
1594
1595 for (;;) {
1596 if ((strp = strstr(ev.str, str)) != NULL)
1597 return (int)(strp - ev.str);
1598 if (history(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0)
1599 break;
1600 }
1601 (void)history(h, &ev, H_SET, curr_num);
1602 return -1;
1603 }
1604
1605
1606 /*
1607 * searches for first history event beginning with str
1608 */
1609 int
1610 history_search_prefix(const char *str, int direction)
1611 {
1612 HistEvent ev;
1613
1614 return (history(h, &ev, direction < 0 ?
1615 H_PREV_STR : H_NEXT_STR, str));
1616 }
1617
1618
1619 /*
1620 * search for event in history containing str, starting at offset
1621 * abs(pos); continue backward, if pos<0, forward otherwise
1622 */
1623 /* ARGSUSED */
1624 int
1625 history_search_pos(const char *str,
1626 int direction __attribute__((__unused__)), int pos)
1627 {
1628 HistEvent ev;
1629 int curr_num, off;
1630
1631 off = (pos > 0) ? pos : -pos;
1632 pos = (pos > 0) ? 1 : -1;
1633
1634 if (history(h, &ev, H_CURR) != 0)
1635 return -1;
1636 curr_num = ev.num;
1637
1638 if (history_set_pos(off) != 0 || history(h, &ev, H_CURR) != 0)
1639 return -1;
1640
1641 for (;;) {
1642 if (strstr(ev.str, str))
1643 return off;
1644 if (history(h, &ev, (pos < 0) ? H_PREV : H_NEXT) != 0)
1645 break;
1646 }
1647
1648 /* set "current" pointer back to previous state */
1649 (void)history(h, &ev,
1650 pos < 0 ? H_NEXT_EVENT : H_PREV_EVENT, curr_num);
1651
1652 return -1;
1653 }
1654
1655
1656 /********************************/
1657 /* completion functions */
1658
1659 char *
1660 tilde_expand(char *name)
1661 {
1662 return fn_tilde_expand(name);
1663 }
1664
1665 char *
1666 filename_completion_function(const char *name, int state)
1667 {
1668 return fn_filename_completion_function(name, state);
1669 }
1670
1671 /*
1672 * a completion generator for usernames; returns _first_ username
1673 * which starts with supplied text
1674 * text contains a partial username preceded by random character
1675 * (usually '~'); state resets search from start (??? should we do that anyway)
1676 * it's callers responsibility to free returned value
1677 */
1678 char *
1679 username_completion_function(const char *text, int state)
1680 {
1681 #if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT)
1682 struct passwd pwres;
1683 char pwbuf[1024];
1684 #endif
1685 struct passwd *pass = NULL;
1686
1687 if (text[0] == '\0')
1688 return NULL;
1689
1690 if (*text == '~')
1691 text++;
1692
1693 if (state == 0)
1694 setpwent();
1695
1696 while (
1697 #if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT)
1698 getpwent_r(&pwres, pwbuf, sizeof(pwbuf), &pass) == 0 && pass != NULL
1699 #else
1700 (pass = getpwent()) != NULL
1701 #endif
1702 && text[0] == pass->pw_name[0]
1703 && strcmp(text, pass->pw_name) == 0)
1704 continue;
1705
1706 if (pass == NULL) {
1707 endpwent();
1708 return NULL;
1709 }
1710 return strdup(pass->pw_name);
1711 }
1712
1713
1714 /*
1715 * el-compatible wrapper to send TSTP on ^Z
1716 */
1717 /* ARGSUSED */
1718 static unsigned char
1719 _el_rl_tstp(EditLine *el __attribute__((__unused__)), int ch __attribute__((__unused__)))
1720 {
1721 (void)kill(0, SIGTSTP);
1722 return CC_NORM;
1723 }
1724
1725 /*
1726 * Display list of strings in columnar format on readline's output stream.
1727 * 'matches' is list of strings, 'len' is number of strings in 'matches',
1728 * 'max' is maximum length of string in 'matches'.
1729 */
1730 void
1731 rl_display_match_list(char **matches, int len, int max)
1732 {
1733
1734 fn_display_match_list(e, matches, (size_t)len, (size_t)max);
1735 }
1736
1737 static const char *
1738 /*ARGSUSED*/
1739 _rl_completion_append_character_function(const char *dummy
1740 __attribute__((__unused__)))
1741 {
1742 static char buf[2];
1743 buf[0] = (char)rl_completion_append_character;
1744 buf[1] = '\0';
1745 return buf;
1746 }
1747
1748
1749 /*
1750 * complete word at current point
1751 */
1752 /* ARGSUSED */
1753 int
1754 rl_complete(int ignore __attribute__((__unused__)), int invoking_key)
1755 {
1756 #ifdef WIDECHAR
1757 static ct_buffer_t wbreak_conv, sprefix_conv;
1758 #endif
1759
1760 if (h == NULL || e == NULL)
1761 rl_initialize();
1762
1763 if (rl_inhibit_completion) {
1764 char arr[2];
1765 arr[0] = (char)invoking_key;
1766 arr[1] = '\0';
1767 el_insertstr(e, arr);
1768 return CC_REFRESH;
1769 }
1770
1771 /* Just look at how many global variables modify this operation! */
1772 return fn_complete(e,
1773 (CPFunction *)rl_completion_entry_function,
1774 rl_attempted_completion_function,
1775 ct_decode_string(rl_basic_word_break_characters, &wbreak_conv),
1776 ct_decode_string(rl_special_prefixes, &sprefix_conv),
1777 _rl_completion_append_character_function,
1778 (size_t)rl_completion_query_items,
1779 &rl_completion_type, &rl_attempted_completion_over,
1780 &rl_point, &rl_end);
1781
1782
1783 }
1784
1785
1786 /* ARGSUSED */
1787 static unsigned char
1788 _el_rl_complete(EditLine *el __attribute__((__unused__)), int ch)
1789 {
1790 return (unsigned char)rl_complete(0, ch);
1791 }
1792
1793 /*
1794 * misc other functions
1795 */
1796
1797 /*
1798 * bind key c to readline-type function func
1799 */
1800 int
1801 rl_bind_key(int c, rl_command_func_t *func)
1802 {
1803 int retval = -1;
1804
1805 if (h == NULL || e == NULL)
1806 rl_initialize();
1807
1808 if (func == rl_insert) {
1809 /* XXX notice there is no range checking of ``c'' */
1810 e->el_map.key[c] = ED_INSERT;
1811 retval = 0;
1812 }
1813 return retval;
1814 }
1815
1816
1817 /*
1818 * read one key from input - handles chars pushed back
1819 * to input stream also
1820 */
1821 int
1822 rl_read_key(void)
1823 {
1824 char fooarr[2 * sizeof(int)];
1825
1826 if (e == NULL || h == NULL)
1827 rl_initialize();
1828
1829 return el_getc(e, fooarr);
1830 }
1831
1832
1833 /*
1834 * reset the terminal
1835 */
1836 /* ARGSUSED */
1837 void
1838 rl_reset_terminal(const char *p __attribute__((__unused__)))
1839 {
1840
1841 if (h == NULL || e == NULL)
1842 rl_initialize();
1843 el_reset(e);
1844 }
1845
1846
1847 /*
1848 * insert character ``c'' back into input stream, ``count'' times
1849 */
1850 int
1851 rl_insert(int count, int c)
1852 {
1853 char arr[2];
1854
1855 if (h == NULL || e == NULL)
1856 rl_initialize();
1857
1858 /* XXX - int -> char conversion can lose on multichars */
1859 arr[0] = (char)c;
1860 arr[1] = '\0';
1861
1862 for (; count > 0; count--)
1863 el_push(e, arr);
1864
1865 return 0;
1866 }
1867
1868 int
1869 rl_insert_text(const char *text)
1870 {
1871 if (!text || *text == 0)
1872 return 0;
1873
1874 if (h == NULL || e == NULL)
1875 rl_initialize();
1876
1877 if (el_insertstr(e, text) < 0)
1878 return 0;
1879 return (int)strlen(text);
1880 }
1881
1882 /*ARGSUSED*/
1883 int
1884 rl_newline(int count __attribute__((__unused__)),
1885 int c __attribute__((__unused__)))
1886 {
1887 /*
1888 * Readline-4.0 appears to ignore the args.
1889 */
1890 return rl_insert(1, '\n');
1891 }
1892
1893 /*ARGSUSED*/
1894 static unsigned char
1895 rl_bind_wrapper(EditLine *el __attribute__((__unused__)), unsigned char c)
1896 {
1897 if (map[c] == NULL)
1898 return CC_ERROR;
1899
1900 _rl_update_pos();
1901
1902 (*map[c])(NULL, c);
1903
1904 /* If rl_done was set by the above call, deal with it here */
1905 if (rl_done)
1906 return CC_EOF;
1907
1908 return CC_NORM;
1909 }
1910
1911 int
1912 rl_add_defun(const char *name, Function *fun, int c)
1913 {
1914 char dest[8];
1915 if ((size_t)c >= sizeof(map) / sizeof(map[0]) || c < 0)
1916 return -1;
1917 map[(unsigned char)c] = fun;
1918 el_set(e, EL_ADDFN, name, name, rl_bind_wrapper);
1919 vis(dest, c, VIS_WHITE|VIS_NOSLASH, 0);
1920 el_set(e, EL_BIND, dest, name);
1921 return 0;
1922 }
1923
1924 void
1925 rl_callback_read_char(void)
1926 {
1927 int count = 0, done = 0;
1928 const char *buf = el_gets(e, &count);
1929 char *wbuf;
1930
1931 if (buf == NULL || count-- <= 0)
1932 return;
1933 if (count == 0 && buf[0] == e->el_tty.t_c[TS_IO][C_EOF])
1934 done = 1;
1935 if (buf[count] == '\n' || buf[count] == '\r')
1936 done = 2;
1937
1938 if (done && rl_linefunc != NULL) {
1939 el_set(e, EL_UNBUFFERED, 0);
1940 if (done == 2) {
1941 if ((wbuf = strdup(buf)) != NULL)
1942 wbuf[count] = '\0';
1943 } else
1944 wbuf = NULL;
1945 (*(void (*)(const char *))rl_linefunc)(wbuf);
1946 //el_set(e, EL_UNBUFFERED, 1);
1947 }
1948 }
1949
1950 void
1951 rl_callback_handler_install(const char *prompt, VCPFunction *linefunc)
1952 {
1953 if (e == NULL) {
1954 rl_initialize();
1955 }
1956 (void)rl_set_prompt(prompt);
1957 rl_linefunc = linefunc;
1958 el_set(e, EL_UNBUFFERED, 1);
1959 }
1960
1961 void
1962 rl_callback_handler_remove(void)
1963 {
1964 el_set(e, EL_UNBUFFERED, 0);
1965 rl_linefunc = NULL;
1966 }
1967
1968 void
1969 rl_redisplay(void)
1970 {
1971 char a[2];
1972 a[0] = (char)e->el_tty.t_c[TS_IO][C_REPRINT];
1973 a[1] = '\0';
1974 el_push(e, a);
1975 }
1976
1977 int
1978 rl_get_previous_history(int count, int key)
1979 {
1980 char a[2];
1981 a[0] = (char)key;
1982 a[1] = '\0';
1983 while (count--)
1984 el_push(e, a);
1985 return 0;
1986 }
1987
1988 void
1989 /*ARGSUSED*/
1990 rl_prep_terminal(int meta_flag __attribute__((__unused__)))
1991 {
1992 el_set(e, EL_PREP_TERM, 1);
1993 }
1994
1995 void
1996 rl_deprep_terminal(void)
1997 {
1998 el_set(e, EL_PREP_TERM, 0);
1999 }
2000
2001 int
2002 rl_read_init_file(const char *s)
2003 {
2004 return el_source(e, s);
2005 }
2006
2007 int
2008 rl_parse_and_bind(const char *line)
2009 {
2010 const char **argv;
2011 int argc;
2012 Tokenizer *tok;
2013
2014 tok = tok_init(NULL);
2015 tok_str(tok, line, &argc, &argv);
2016 argc = el_parse(e, argc, argv);
2017 tok_end(tok);
2018 return argc ? 1 : 0;
2019 }
2020
2021 int
2022 rl_variable_bind(const char *var, const char *value)
2023 {
2024 /*
2025 * The proper return value is undocument, but this is what the
2026 * readline source seems to do.
2027 */
2028 return el_set(e, EL_BIND, "", var, value) == -1 ? 1 : 0;
2029 }
2030
2031 void
2032 rl_stuff_char(int c)
2033 {
2034 char buf[2];
2035
2036 buf[0] = (char)c;
2037 buf[1] = '\0';
2038 el_insertstr(e, buf);
2039 }
2040
2041 static int
2042 _rl_event_read_char(EditLine *el, char *cp)
2043 {
2044 int n;
2045 ssize_t num_read = 0;
2046
2047 *cp = '\0';
2048 while (rl_event_hook) {
2049
2050 (*rl_event_hook)();
2051
2052 #if defined(FIONREAD)
2053 if (ioctl(el->el_infd, FIONREAD, &n) < 0)
2054 return -1;
2055 if (n)
2056 num_read = read(el->el_infd, cp, (size_t)1);
2057 else
2058 num_read = 0;
2059 #elif defined(F_SETFL) && defined(O_NDELAY)
2060 if ((n = fcntl(el->el_infd, F_GETFL, 0)) < 0)
2061 return -1;
2062 if (fcntl(el->el_infd, F_SETFL, n|O_NDELAY) < 0)
2063 return -1;
2064 num_read = read(el->el_infd, cp, 1);
2065 if (fcntl(el->el_infd, F_SETFL, n))
2066 return -1;
2067 #else
2068 /* not non-blocking, but what you gonna do? */
2069 num_read = read(el->el_infd, cp, 1);
2070 return -1;
2071 #endif
2072
2073 if (num_read < 0 && errno == EAGAIN)
2074 continue;
2075 if (num_read == 0)
2076 continue;
2077 break;
2078 }
2079 if (!rl_event_hook)
2080 el_set(el, EL_GETCFN, EL_BUILTIN_GETCFN);
2081 return (int)num_read;
2082 }
2083
2084 static void
2085 _rl_update_pos(void)
2086 {
2087 const LineInfo *li = el_line(e);
2088
2089 rl_point = (int)(li->cursor - li->buffer);
2090 rl_end = (int)(li->lastchar - li->buffer);
2091 }
2092
2093 void
2094 rl_get_screen_size(int *rows, int *cols)
2095 {
2096 if (rows)
2097 el_get(e, EL_GETTC, "li", rows);
2098 if (cols)
2099 el_get(e, EL_GETTC, "co", cols);
2100 }
2101
2102 void
2103 rl_set_screen_size(int rows, int cols)
2104 {
2105 char buf[64];
2106 (void)snprintf(buf, sizeof(buf), "%d", rows);
2107 el_set(e, EL_SETTC, "li", buf);
2108 (void)snprintf(buf, sizeof(buf), "%d", cols);
2109 el_set(e, EL_SETTC, "co", buf);
2110 }
2111
2112 char **
2113 rl_completion_matches(const char *str, rl_compentry_func_t *fun)
2114 {
2115 size_t len, max, i, j, min;
2116 char **list, *match, *a, *b;
2117
2118 len = 1;
2119 max = 10;
2120 if ((list = el_malloc(max * sizeof(*list))) == NULL)
2121 return NULL;
2122
2123 while ((match = (*fun)(str, (int)(len - 1))) != NULL) {
2124 list[len++] = match;
2125 if (len == max) {
2126 char **nl;
2127 max += 10;
2128 if ((nl = el_realloc(list, max * sizeof(*nl))) == NULL)
2129 goto out;
2130 list = nl;
2131 }
2132 }
2133 if (len == 1)
2134 goto out;
2135 list[len] = NULL;
2136 if (len == 2) {
2137 if ((list[0] = strdup(list[1])) == NULL)
2138 goto out;
2139 return list;
2140 }
2141 qsort(&list[1], len - 1, sizeof(*list),
2142 (int (*)(const void *, const void *)) strcmp);
2143 min = SIZE_T_MAX;
2144 for (i = 1, a = list[i]; i < len - 1; i++, a = b) {
2145 b = list[i + 1];
2146 for (j = 0; a[j] && a[j] == b[j]; j++)
2147 continue;
2148 if (min > j)
2149 min = j;
2150 }
2151 if (min == 0 && *str) {
2152 if ((list[0] = strdup(str)) == NULL)
2153 goto out;
2154 } else {
2155 if ((list[0] = el_malloc((min + 1) * sizeof(*list[0]))) == NULL)
2156 goto out;
2157 (void)memcpy(list[0], list[1], min);
2158 list[0][min] = '\0';
2159 }
2160 return list;
2161
2162 out:
2163 el_free(list);
2164 return NULL;
2165 }
2166
2167 char *
2168 rl_filename_completion_function (const char *text, int state)
2169 {
2170 return fn_filename_completion_function(text, state);
2171 }
2172
2173 void
2174 rl_forced_update_display(void)
2175 {
2176 el_set(e, EL_REFRESH);
2177 }
2178
2179 int
2180 _rl_abort_internal(void)
2181 {
2182 el_beep(e);
2183 longjmp(topbuf, 1);
2184 /*NOTREACHED*/
2185 }
2186
2187 int
2188 _rl_qsort_string_compare(char **s1, char **s2)
2189 {
2190 return strcoll(*s1, *s2);
2191 }
2192
2193 HISTORY_STATE *
2194 history_get_history_state(void)
2195 {
2196 HISTORY_STATE *hs;
2197
2198 if ((hs = el_malloc(sizeof(*hs))) == NULL)
2199 return NULL;
2200 hs->length = history_length;
2201 return hs;
2202 }
2203
2204 int
2205 /*ARGSUSED*/
2206 rl_kill_text(int from __attribute__((__unused__)),
2207 int to __attribute__((__unused__)))
2208 {
2209 return 0;
2210 }
2211
2212 Keymap
2213 rl_make_bare_keymap(void)
2214 {
2215 return NULL;
2216 }
2217
2218 Keymap
2219 rl_get_keymap(void)
2220 {
2221 return NULL;
2222 }
2223
2224 void
2225 /*ARGSUSED*/
2226 rl_set_keymap(Keymap k __attribute__((__unused__)))
2227 {
2228 }
2229
2230 int
2231 /*ARGSUSED*/
2232 rl_generic_bind(int type __attribute__((__unused__)),
2233 const char * keyseq __attribute__((__unused__)),
2234 const char * data __attribute__((__unused__)),
2235 Keymap k __attribute__((__unused__)))
2236 {
2237 return 0;
2238 }
2239
2240 int
2241 /*ARGSUSED*/
2242 rl_bind_key_in_map(int key __attribute__((__unused__)),
2243 rl_command_func_t *fun __attribute__((__unused__)),
2244 Keymap k __attribute__((__unused__)))
2245 {
2246 return 0;
2247 }
2248
2249 /* unsupported, but needed by python */
2250 void
2251 rl_cleanup_after_signal(void)
2252 {
2253 }
2254
2255 int
2256 rl_on_new_line(void)
2257 {
2258 return 0;
2259 }
2260