Annotation of embedaddon/readline/util.c, revision 1.1.1.3
1.1 misho 1: /* util.c -- readline utility functions */
2:
1.1.1.3 ! misho 3: /* Copyright (C) 1987-2017 Free Software Foundation, Inc.
1.1 misho 4:
5: This file is part of the GNU Readline Library (Readline), a library
6: for reading lines of text with interactive input and history editing.
7:
8: Readline is free software: you can redistribute it and/or modify
9: it under the terms of the GNU General Public License as published by
10: the Free Software Foundation, either version 3 of the License, or
11: (at your option) any later version.
12:
13: Readline is distributed in the hope that it will be useful,
14: but WITHOUT ANY WARRANTY; without even the implied warranty of
15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16: GNU General Public License for more details.
17:
18: You should have received a copy of the GNU General Public License
19: along with Readline. If not, see <http://www.gnu.org/licenses/>.
20: */
21:
22: #define READLINE_LIBRARY
23:
24: #if defined (HAVE_CONFIG_H)
25: # include <config.h>
26: #endif
27:
28: #include <sys/types.h>
29: #include <fcntl.h>
30: #include "posixjmp.h"
31:
32: #if defined (HAVE_UNISTD_H)
33: # include <unistd.h> /* for _POSIX_VERSION */
34: #endif /* HAVE_UNISTD_H */
35:
36: #if defined (HAVE_STDLIB_H)
37: # include <stdlib.h>
38: #else
39: # include "ansi_stdlib.h"
40: #endif /* HAVE_STDLIB_H */
41:
42: #include <stdio.h>
43: #include <ctype.h>
44:
45: /* System-specific feature definitions and include files. */
46: #include "rldefs.h"
47: #include "rlmbutil.h"
48:
49: #if defined (TIOCSTAT_IN_SYS_IOCTL)
50: # include <sys/ioctl.h>
51: #endif /* TIOCSTAT_IN_SYS_IOCTL */
52:
53: /* Some standard library routines. */
54: #include "readline.h"
55:
56: #include "rlprivate.h"
57: #include "xmalloc.h"
1.1.1.3 ! misho 58: #include "rlshell.h"
1.1 misho 59:
60: /* **************************************************************** */
61: /* */
62: /* Utility Functions */
63: /* */
64: /* **************************************************************** */
65:
66: /* Return 0 if C is not a member of the class of characters that belong
67: in words, or 1 if it is. */
68:
69: int _rl_allow_pathname_alphabetic_chars = 0;
70: static const char * const pathname_alphabetic_chars = "/-_=~.#$";
71:
72: int
1.1.1.3 ! misho 73: rl_alphabetic (int c)
1.1 misho 74: {
75: if (ALPHABETIC (c))
76: return (1);
77:
78: return (_rl_allow_pathname_alphabetic_chars &&
79: strchr (pathname_alphabetic_chars, c) != NULL);
80: }
81:
82: #if defined (HANDLE_MULTIBYTE)
83: int
84: _rl_walphabetic (wchar_t wc)
85: {
86: int c;
87:
88: if (iswalnum (wc))
89: return (1);
90:
91: c = wc & 0177;
92: return (_rl_allow_pathname_alphabetic_chars &&
93: strchr (pathname_alphabetic_chars, c) != NULL);
94: }
95: #endif
96:
97: /* How to abort things. */
98: int
1.1.1.3 ! misho 99: _rl_abort_internal (void)
1.1 misho 100: {
101: rl_ding ();
102: rl_clear_message ();
103: _rl_reset_argument ();
104: rl_clear_pending_input ();
1.1.1.3 ! misho 105: rl_deactivate_mark ();
1.1 misho 106:
107: while (rl_executing_macro)
108: _rl_pop_executing_macro ();
1.1.1.3 ! misho 109: _rl_kill_kbd_macro ();
! 110:
! 111: RL_UNSETSTATE (RL_STATE_MULTIKEY); /* XXX */
1.1 misho 112:
113: rl_last_func = (rl_command_func_t *)NULL;
1.1.1.3 ! misho 114:
! 115: _rl_longjmp (_rl_top_level, 1);
1.1 misho 116: return (0);
117: }
118:
119: int
1.1.1.3 ! misho 120: rl_abort (int count, int key)
1.1 misho 121: {
122: return (_rl_abort_internal ());
123: }
124:
125: int
1.1.1.3 ! misho 126: _rl_null_function (int count, int key)
1.1 misho 127: {
128: return 0;
129: }
130:
131: int
1.1.1.3 ! misho 132: rl_tty_status (int count, int key)
1.1 misho 133: {
134: #if defined (TIOCSTAT)
135: ioctl (1, TIOCSTAT, (char *)0);
136: rl_refresh_line (count, key);
137: #else
138: rl_ding ();
139: #endif
140: return 0;
141: }
142:
143: /* Return a copy of the string between FROM and TO.
144: FROM is inclusive, TO is not. */
145: char *
1.1.1.3 ! misho 146: rl_copy_text (int from, int to)
1.1 misho 147: {
148: register int length;
149: char *copy;
150:
151: /* Fix it if the caller is confused. */
152: if (from > to)
153: SWAP (from, to);
154:
155: length = to - from;
156: copy = (char *)xmalloc (1 + length);
157: strncpy (copy, rl_line_buffer + from, length);
158: copy[length] = '\0';
159: return (copy);
160: }
161:
162: /* Increase the size of RL_LINE_BUFFER until it has enough space to hold
163: LEN characters. */
164: void
1.1.1.3 ! misho 165: rl_extend_line_buffer (int len)
1.1 misho 166: {
167: while (len >= rl_line_buffer_len)
168: {
169: rl_line_buffer_len += DEFAULT_BUFFER_SIZE;
170: rl_line_buffer = (char *)xrealloc (rl_line_buffer, rl_line_buffer_len);
171: }
172:
173: _rl_set_the_line ();
174: }
175:
176:
177: /* A function for simple tilde expansion. */
178: int
1.1.1.3 ! misho 179: rl_tilde_expand (int ignore, int key)
1.1 misho 180: {
181: register int start, end;
182: char *homedir, *temp;
183: int len;
184:
185: end = rl_point;
186: start = end - 1;
187:
188: if (rl_point == rl_end && rl_line_buffer[rl_point] == '~')
189: {
190: homedir = tilde_expand ("~");
191: _rl_replace_text (homedir, start, end);
192: xfree (homedir);
193: return (0);
194: }
1.1.1.3 ! misho 195: else if (start >= 0 && rl_line_buffer[start] != '~')
1.1 misho 196: {
1.1.1.3 ! misho 197: for (; start >= 0 && !whitespace (rl_line_buffer[start]); start--)
1.1 misho 198: ;
199: start++;
200: }
1.1.1.3 ! misho 201: else if (start < 0)
! 202: start = 0;
1.1 misho 203:
204: end = start;
205: do
206: end++;
207: while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end);
208:
209: if (whitespace (rl_line_buffer[end]) || end >= rl_end)
210: end--;
211:
212: /* If the first character of the current word is a tilde, perform
213: tilde expansion and insert the result. If not a tilde, do
214: nothing. */
215: if (rl_line_buffer[start] == '~')
216: {
217: len = end - start + 1;
218: temp = (char *)xmalloc (len + 1);
219: strncpy (temp, rl_line_buffer + start, len);
220: temp[len] = '\0';
221: homedir = tilde_expand (temp);
222: xfree (temp);
223:
224: _rl_replace_text (homedir, start, end);
225: xfree (homedir);
226: }
227:
228: return (0);
229: }
230:
231: #if defined (USE_VARARGS)
232: void
233: #if defined (PREFER_STDARG)
234: _rl_ttymsg (const char *format, ...)
235: #else
236: _rl_ttymsg (va_alist)
237: va_dcl
238: #endif
239: {
240: va_list args;
241: #if defined (PREFER_VARARGS)
242: char *format;
243: #endif
244:
245: #if defined (PREFER_STDARG)
246: va_start (args, format);
247: #else
248: va_start (args);
249: format = va_arg (args, char *);
250: #endif
251:
252: fprintf (stderr, "readline: ");
253: vfprintf (stderr, format, args);
254: fprintf (stderr, "\n");
255: fflush (stderr);
256:
257: va_end (args);
258:
259: rl_forced_update_display ();
260: }
261:
262: void
263: #if defined (PREFER_STDARG)
264: _rl_errmsg (const char *format, ...)
265: #else
266: _rl_errmsg (va_alist)
267: va_dcl
268: #endif
269: {
270: va_list args;
271: #if defined (PREFER_VARARGS)
272: char *format;
273: #endif
274:
275: #if defined (PREFER_STDARG)
276: va_start (args, format);
277: #else
278: va_start (args);
279: format = va_arg (args, char *);
280: #endif
281:
282: fprintf (stderr, "readline: ");
283: vfprintf (stderr, format, args);
284: fprintf (stderr, "\n");
285: fflush (stderr);
286:
287: va_end (args);
288: }
289:
290: #else /* !USE_VARARGS */
291: void
292: _rl_ttymsg (format, arg1, arg2)
293: char *format;
294: {
295: fprintf (stderr, "readline: ");
296: fprintf (stderr, format, arg1, arg2);
297: fprintf (stderr, "\n");
298:
299: rl_forced_update_display ();
300: }
301:
302: void
303: _rl_errmsg (format, arg1, arg2)
304: char *format;
305: {
306: fprintf (stderr, "readline: ");
307: fprintf (stderr, format, arg1, arg2);
308: fprintf (stderr, "\n");
309: }
310: #endif /* !USE_VARARGS */
311:
312: /* **************************************************************** */
313: /* */
314: /* String Utility Functions */
315: /* */
316: /* **************************************************************** */
317:
318: /* Determine if s2 occurs in s1. If so, return a pointer to the
319: match in s1. The compare is case insensitive. */
320: char *
1.1.1.3 ! misho 321: _rl_strindex (const char *s1, const char *s2)
1.1 misho 322: {
323: register int i, l, len;
324:
325: for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++)
326: if (_rl_strnicmp (s1 + i, s2, l) == 0)
327: return ((char *) (s1 + i));
328: return ((char *)NULL);
329: }
330:
331: #ifndef HAVE_STRPBRK
332: /* Find the first occurrence in STRING1 of any character from STRING2.
333: Return a pointer to the character in STRING1. */
334: char *
1.1.1.3 ! misho 335: _rl_strpbrk (const char *string1, const char *string2)
1.1 misho 336: {
337: register const char *scan;
338: #if defined (HANDLE_MULTIBYTE)
339: mbstate_t ps;
340: register int i, v;
341:
342: memset (&ps, 0, sizeof (mbstate_t));
343: #endif
344:
345: for (; *string1; string1++)
346: {
347: for (scan = string2; *scan; scan++)
348: {
349: if (*string1 == *scan)
350: return ((char *)string1);
351: }
352: #if defined (HANDLE_MULTIBYTE)
353: if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
354: {
355: v = _rl_get_char_len (string1, &ps);
356: if (v > 1)
357: string1 += v - 1; /* -1 to account for auto-increment in loop */
358: }
359: #endif
360: }
361: return ((char *)NULL);
362: }
363: #endif
364:
365: #if !defined (HAVE_STRCASECMP)
366: /* Compare at most COUNT characters from string1 to string2. Case
367: doesn't matter (strncasecmp). */
368: int
1.1.1.3 ! misho 369: _rl_strnicmp (const char *string1, const char *string2, int count)
1.1 misho 370: {
371: register const char *s1;
372: register const char *s2;
373: register int d;
374:
375: if (count <= 0 || (string1 == string2))
376: return 0;
377:
378: s1 = string1;
379: s2 = string2;
380: do
381: {
382: d = _rl_to_lower (*s1) - _rl_to_lower (*s2); /* XXX - cast to unsigned char? */
383: if (d != 0)
384: return d;
385: if (*s1++ == '\0')
386: break;
387: s2++;
388: }
389: while (--count != 0);
390:
391: return (0);
392: }
393:
394: /* strcmp (), but caseless (strcasecmp). */
395: int
1.1.1.3 ! misho 396: _rl_stricmp (const char *string1, const char *string2)
1.1 misho 397: {
398: register const char *s1;
399: register const char *s2;
400: register int d;
401:
402: s1 = string1;
403: s2 = string2;
404:
405: if (s1 == s2)
406: return 0;
407:
408: while ((d = _rl_to_lower (*s1) - _rl_to_lower (*s2)) == 0)
409: {
410: if (*s1++ == '\0')
411: return 0;
412: s2++;
413: }
414:
415: return (d);
416: }
417: #endif /* !HAVE_STRCASECMP */
418:
419: /* Stupid comparison routine for qsort () ing strings. */
420: int
1.1.1.3 ! misho 421: _rl_qsort_string_compare (char **s1, char **s2)
1.1 misho 422: {
423: #if defined (HAVE_STRCOLL)
424: return (strcoll (*s1, *s2));
425: #else
426: int result;
427:
428: result = **s1 - **s2;
429: if (result == 0)
430: result = strcmp (*s1, *s2);
431:
432: return result;
433: #endif
434: }
435:
436: /* Function equivalents for the macros defined in chardefs.h. */
1.1.1.3 ! misho 437: #define FUNCTION_FOR_MACRO(f) int (f) (int c) { return f (c); }
1.1 misho 438:
439: FUNCTION_FOR_MACRO (_rl_digit_p)
440: FUNCTION_FOR_MACRO (_rl_digit_value)
441: FUNCTION_FOR_MACRO (_rl_lowercase_p)
442: FUNCTION_FOR_MACRO (_rl_pure_alphabetic)
443: FUNCTION_FOR_MACRO (_rl_to_lower)
444: FUNCTION_FOR_MACRO (_rl_to_upper)
445: FUNCTION_FOR_MACRO (_rl_uppercase_p)
446:
447: /* A convenience function, to force memory deallocation to be performed
448: by readline. DLLs on Windows apparently require this. */
449: void
1.1.1.3 ! misho 450: rl_free (void *mem)
1.1 misho 451: {
452: if (mem)
453: free (mem);
454: }
455:
456: /* Backwards compatibility, now that savestring has been removed from
457: all `public' readline header files. */
458: #undef _rl_savestring
459: char *
1.1.1.3 ! misho 460: _rl_savestring (const char *s)
1.1 misho 461: {
462: return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s)));
463: }
464:
1.1.1.2 misho 465: #if defined (DEBUG)
1.1 misho 466: #if defined (USE_VARARGS)
467: static FILE *_rl_tracefp;
468:
469: void
470: #if defined (PREFER_STDARG)
471: _rl_trace (const char *format, ...)
472: #else
473: _rl_trace (va_alist)
474: va_dcl
475: #endif
476: {
477: va_list args;
478: #if defined (PREFER_VARARGS)
479: char *format;
480: #endif
481:
482: #if defined (PREFER_STDARG)
483: va_start (args, format);
484: #else
485: va_start (args);
486: format = va_arg (args, char *);
487: #endif
488:
489: if (_rl_tracefp == 0)
490: _rl_tropen ();
491: vfprintf (_rl_tracefp, format, args);
492: fprintf (_rl_tracefp, "\n");
493: fflush (_rl_tracefp);
494:
495: va_end (args);
496: }
497:
498: int
1.1.1.3 ! misho 499: _rl_tropen (void)
1.1 misho 500: {
1.1.1.3 ! misho 501: char fnbuf[128], *x;
1.1 misho 502:
503: if (_rl_tracefp)
504: fclose (_rl_tracefp);
1.1.1.3 ! misho 505: #if defined (_WIN32) && !defined (__CYGWIN__)
! 506: x = sh_get_env_value ("TEMP");
! 507: if (x == 0)
! 508: x = ".";
! 509: #else
! 510: x = "/var/tmp";
! 511: #endif
! 512: snprintf (fnbuf, sizeof (fnbuf), "%s/rltrace.%ld", x, (long)getpid());
1.1 misho 513: unlink(fnbuf);
514: _rl_tracefp = fopen (fnbuf, "w+");
515: return _rl_tracefp != 0;
516: }
517:
518: int
1.1.1.3 ! misho 519: _rl_trclose (void)
1.1 misho 520: {
521: int r;
522:
523: r = fclose (_rl_tracefp);
524: _rl_tracefp = 0;
525: return r;
526: }
527:
528: void
1.1.1.3 ! misho 529: _rl_settracefp (FILE *fp)
1.1 misho 530: {
531: _rl_tracefp = fp;
532: }
533: #endif
1.1.1.2 misho 534: #endif /* DEBUG */
1.1 misho 535:
536:
1.1.1.3 ! misho 537: #if HAVE_DECL_AUDIT_USER_TTY && defined (HAVE_LIBAUDIT_H) && defined (ENABLE_TTY_AUDIT_SUPPORT)
1.1 misho 538: #include <sys/socket.h>
1.1.1.3 ! misho 539: #include <libaudit.h>
1.1 misho 540: #include <linux/audit.h>
541: #include <linux/netlink.h>
542:
543: /* Report STRING to the audit system. */
544: void
1.1.1.3 ! misho 545: _rl_audit_tty (char *string)
1.1 misho 546: {
1.1.1.3 ! misho 547: struct audit_message req;
1.1 misho 548: struct sockaddr_nl addr;
549: size_t size;
550: int fd;
551:
1.1.1.3 ! misho 552: fd = socket (PF_NETLINK, SOCK_RAW, NETLINK_AUDIT);
1.1 misho 553: if (fd < 0)
554: return;
555: size = strlen (string) + 1;
556:
1.1.1.3 ! misho 557: if (NLMSG_SPACE (size) > MAX_AUDIT_MESSAGE_LENGTH)
! 558: return;
! 559:
! 560: memset (&req, 0, sizeof(req));
! 561: req.nlh.nlmsg_len = NLMSG_SPACE (size);
! 562: req.nlh.nlmsg_type = AUDIT_USER_TTY;
! 563: req.nlh.nlmsg_flags = NLM_F_REQUEST;
! 564: req.nlh.nlmsg_seq = 0;
! 565: if (size && string)
! 566: memcpy (NLMSG_DATA(&req.nlh), string, size);
! 567: memset (&addr, 0, sizeof(addr));
1.1 misho 568:
569: addr.nl_family = AF_NETLINK;
570: addr.nl_pid = 0;
571: addr.nl_groups = 0;
572:
1.1.1.3 ! misho 573: sendto (fd, &req, req.nlh.nlmsg_len, 0, (struct sockaddr*)&addr, sizeof(addr));
1.1 misho 574: close (fd);
575: }
576: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>