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