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