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