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