blob: 0b9c8fb68c98b4d9fb527aaa76fa52704a475bc0 [file] [log] [blame]
Jari Aalto726f6381996-08-26 18:22:31 +00001/* general.c -- Stuff that is used by all files. */
2
Jari Aaltob80f6442004-07-27 13:29:18 +00003/* Copyright (C) 1987-2004 Free Software Foundation, Inc.
Jari Aalto726f6381996-08-26 18:22:31 +00004
5 This file is part of GNU Bash, the Bourne Again SHell.
6
7 Bash is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with Bash; see the file COPYING. If not, write to the Free Software
Jari Aaltobb706242000-03-17 21:46:59 +000019 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
Jari Aalto726f6381996-08-26 18:22:31 +000020
Jari Aaltoccc6cda1996-12-23 17:02:34 +000021#include "config.h"
22
23#include "bashtypes.h"
Jari Aaltocce855b1998-04-17 19:52:44 +000024#ifndef _MINIX
25# include <sys/param.h>
26#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +000027#include "posixstat.h"
28
29#if defined (HAVE_UNISTD_H)
30# include <unistd.h>
31#endif
32
33#include "filecntl.h"
34#include "bashansi.h"
Jari Aalto726f6381996-08-26 18:22:31 +000035#include <stdio.h>
Jari Aaltof73dda02001-11-13 17:56:06 +000036#include "chartypes.h"
Jari Aalto726f6381996-08-26 18:22:31 +000037#include <errno.h>
Jari Aaltoccc6cda1996-12-23 17:02:34 +000038
Jari Aaltob80f6442004-07-27 13:29:18 +000039#include "bashintl.h"
40
Jari Aalto726f6381996-08-26 18:22:31 +000041#include "shell.h"
42#include <tilde/tilde.h>
43
Jari Aalto726f6381996-08-26 18:22:31 +000044#if !defined (errno)
45extern int errno;
46#endif /* !errno */
47
Jari Aaltof73dda02001-11-13 17:56:06 +000048extern int expand_aliases;
Jari Aaltoccc6cda1996-12-23 17:02:34 +000049extern int interrupt_immediately;
50extern int interactive_comments;
Jari Aalto28ef6c32001-04-06 19:14:31 +000051extern int check_hashed_filenames;
52extern int source_uses_path;
53extern int source_searches_cwd;
Jari Aaltocce855b1998-04-17 19:52:44 +000054
Jari Aalto7117c2d2002-07-17 14:10:11 +000055static char *bash_special_tilde_expansions __P((char *));
56static int unquoted_tilde_word __P((const char *));
57static void initialize_group_array __P((void));
58
Jari Aaltocce855b1998-04-17 19:52:44 +000059/* A standard error message to use when getcwd() returns NULL. */
Jari Aaltob80f6442004-07-27 13:29:18 +000060char *bash_getcwd_errstr = N_("getcwd: cannot access parent directories");
Jari Aalto726f6381996-08-26 18:22:31 +000061
Jari Aaltoccc6cda1996-12-23 17:02:34 +000062/* Do whatever is necessary to initialize `Posix mode'. */
Jari Aalto726f6381996-08-26 18:22:31 +000063void
Jari Aaltoccc6cda1996-12-23 17:02:34 +000064posix_initialize (on)
65 int on;
Jari Aalto726f6381996-08-26 18:22:31 +000066{
Jari Aalto28ef6c32001-04-06 19:14:31 +000067 /* Things that should be turned on when posix mode is enabled. */
68 if (on != 0)
69 {
70 interactive_comments = source_uses_path = expand_aliases = 1;
71 }
72
73 /* Things that should be turned on when posix mode is disabled. */
74 if (on == 0)
75 {
76 source_searches_cwd = 1;
77 expand_aliases = interactive_shell;
78 }
Jari Aalto726f6381996-08-26 18:22:31 +000079}
80
81/* **************************************************************** */
82/* */
Jari Aaltoccc6cda1996-12-23 17:02:34 +000083/* Functions to convert to and from and display non-standard types */
84/* */
85/* **************************************************************** */
86
Jari Aalto726f6381996-08-26 18:22:31 +000087#if defined (RLIMTYPE)
88RLIMTYPE
89string_to_rlimtype (s)
90 char *s;
91{
Jari Aaltocce855b1998-04-17 19:52:44 +000092 RLIMTYPE ret;
93 int neg;
Jari Aalto726f6381996-08-26 18:22:31 +000094
Jari Aaltocce855b1998-04-17 19:52:44 +000095 ret = 0;
96 neg = 0;
Jari Aalto726f6381996-08-26 18:22:31 +000097 while (s && *s && whitespace (*s))
98 s++;
99 if (*s == '-' || *s == '+')
100 {
101 neg = *s == '-';
102 s++;
103 }
Jari Aaltof73dda02001-11-13 17:56:06 +0000104 for ( ; s && *s && DIGIT (*s); s++)
105 ret = (ret * 10) + TODIGIT (*s);
Jari Aalto726f6381996-08-26 18:22:31 +0000106 return (neg ? -ret : ret);
107}
108
109void
110print_rlimtype (n, addnl)
111 RLIMTYPE n;
112 int addnl;
113{
Jari Aaltof73dda02001-11-13 17:56:06 +0000114 char s[INT_STRLEN_BOUND (RLIMTYPE) + 1], *p;
Jari Aalto726f6381996-08-26 18:22:31 +0000115
Jari Aaltof73dda02001-11-13 17:56:06 +0000116 p = s + sizeof(s);
117 *--p = '\0';
Jari Aalto726f6381996-08-26 18:22:31 +0000118
119 if (n < 0)
120 {
Jari Aaltof73dda02001-11-13 17:56:06 +0000121 do
122 *--p = '0' - n % 10;
123 while ((n /= 10) != 0);
124
125 *--p = '-';
126 }
127 else
128 {
129 do
130 *--p = '0' + n % 10;
131 while ((n /= 10) != 0);
Jari Aalto726f6381996-08-26 18:22:31 +0000132 }
133
Jari Aaltof73dda02001-11-13 17:56:06 +0000134 printf ("%s%s", p, addnl ? "\n" : "");
Jari Aalto726f6381996-08-26 18:22:31 +0000135}
136#endif /* RLIMTYPE */
137
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000138/* **************************************************************** */
139/* */
140/* Input Validation Functions */
141/* */
142/* **************************************************************** */
143
144/* Return non-zero if all of the characters in STRING are digits. */
145int
146all_digits (string)
147 char *string;
148{
Jari Aalto28ef6c32001-04-06 19:14:31 +0000149 register char *s;
150
151 for (s = string; *s; s++)
Jari Aaltof73dda02001-11-13 17:56:06 +0000152 if (DIGIT (*s) == 0)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000153 return (0);
154
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000155 return (1);
156}
157
158/* Return non-zero if the characters pointed to by STRING constitute a
159 valid number. Stuff the converted number into RESULT if RESULT is
Jari Aaltof73dda02001-11-13 17:56:06 +0000160 not null. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000161int
162legal_number (string, result)
163 char *string;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000164 intmax_t *result;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000165{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000166 intmax_t value;
Jari Aaltocce855b1998-04-17 19:52:44 +0000167 char *ep;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000168
169 if (result)
170 *result = 0;
171
Jari Aaltof73dda02001-11-13 17:56:06 +0000172 errno = 0;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000173 value = strtoimax (string, &ep, 10);
Jari Aaltof73dda02001-11-13 17:56:06 +0000174 if (errno)
175 return 0; /* errno is set on overflow or underflow */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000176
Jari Aalto7117c2d2002-07-17 14:10:11 +0000177 /* Skip any trailing whitespace, since strtoimax does not. */
Jari Aalto28ef6c32001-04-06 19:14:31 +0000178 while (whitespace (*ep))
179 ep++;
180
Jari Aaltocce855b1998-04-17 19:52:44 +0000181 /* If *string is not '\0' but *ep is '\0' on return, the entire string
182 is valid. */
183 if (string && *string && *ep == '\0')
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000184 {
185 if (result)
Jari Aaltocce855b1998-04-17 19:52:44 +0000186 *result = value;
187 /* The SunOS4 implementation of strtol() will happily ignore
188 overflow conditions, so this cannot do overflow correctly
189 on those systems. */
190 return 1;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000191 }
Jari Aaltocce855b1998-04-17 19:52:44 +0000192
193 return (0);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000194}
195
Jari Aalto726f6381996-08-26 18:22:31 +0000196/* Return 1 if this token is a legal shell `identifier'; that is, it consists
197 solely of letters, digits, and underscores, and does not begin with a
198 digit. */
199int
200legal_identifier (name)
201 char *name;
202{
203 register char *s;
Jari Aaltof73dda02001-11-13 17:56:06 +0000204 unsigned char c;
Jari Aalto726f6381996-08-26 18:22:31 +0000205
Jari Aaltof73dda02001-11-13 17:56:06 +0000206 if (!name || !(c = *name) || (legal_variable_starter (c) == 0))
Jari Aalto726f6381996-08-26 18:22:31 +0000207 return (0);
208
Jari Aaltof73dda02001-11-13 17:56:06 +0000209 for (s = name + 1; (c = *s) != 0; s++)
Jari Aalto726f6381996-08-26 18:22:31 +0000210 {
Jari Aaltof73dda02001-11-13 17:56:06 +0000211 if (legal_variable_char (c) == 0)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000212 return (0);
Jari Aalto726f6381996-08-26 18:22:31 +0000213 }
214 return (1);
215}
216
217/* Make sure that WORD is a valid shell identifier, i.e.
218 does not contain a dollar sign, nor is quoted in any way. Nor
219 does it consist of all digits. If CHECK_WORD is non-zero,
220 the word is checked to ensure that it consists of only letters,
221 digits, and underscores. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000222int
Jari Aalto726f6381996-08-26 18:22:31 +0000223check_identifier (word, check_word)
224 WORD_DESC *word;
225 int check_word;
226{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000227 if ((word->flags & (W_HASDOLLAR|W_QUOTED)) || all_digits (word->word))
Jari Aalto726f6381996-08-26 18:22:31 +0000228 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000229 internal_error (_("`%s': not a valid identifier"), word->word);
Jari Aalto726f6381996-08-26 18:22:31 +0000230 return (0);
231 }
232 else if (check_word && legal_identifier (word->word) == 0)
233 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000234 internal_error (_("`%s': not a valid identifier"), word->word);
Jari Aalto726f6381996-08-26 18:22:31 +0000235 return (0);
236 }
237 else
238 return (1);
239}
240
Jari Aaltob80f6442004-07-27 13:29:18 +0000241/* Return 1 if STRING comprises a valid alias name. The shell accepts
242 essentially all characters except those which must be quoted to the
243 parser (which disqualifies them from alias expansion anyway) and `/'. */
244int
245legal_alias_name (string, flags)
246 char *string;
247 int flags;
248{
249 register char *s;
250
251 for (s = string; *s; s++)
252 if (shellbreak (*s) || shellxquote (*s) || shellexp (*s) || (*s == '/'))
253 return 0;
254 return 1;
255}
256
Jari Aalto7117c2d2002-07-17 14:10:11 +0000257/* Returns non-zero if STRING is an assignment statement. The returned value
258 is the index of the `=' sign. */
259int
Jari Aaltob80f6442004-07-27 13:29:18 +0000260assignment (string, flags)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000261 const char *string;
Jari Aaltob80f6442004-07-27 13:29:18 +0000262 int flags;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000263{
264 register unsigned char c;
265 register int newi, indx;
266
267 c = string[indx = 0];
268
Jari Aaltob80f6442004-07-27 13:29:18 +0000269#if defined (ARRAY_VARS)
Jari Aaltoeb873672004-11-09 21:37:25 +0000270 if ((legal_variable_starter (c) == 0) && (flags == 0 || c != '[')) /* ] */
Jari Aaltob80f6442004-07-27 13:29:18 +0000271#else
Jari Aalto7117c2d2002-07-17 14:10:11 +0000272 if (legal_variable_starter (c) == 0)
Jari Aaltob80f6442004-07-27 13:29:18 +0000273#endif
Jari Aalto7117c2d2002-07-17 14:10:11 +0000274 return (0);
275
276 while (c = string[indx])
277 {
278 /* The following is safe. Note that '=' at the start of a word
279 is not an assignment statement. */
280 if (c == '=')
281 return (indx);
282
283#if defined (ARRAY_VARS)
284 if (c == '[')
285 {
286 newi = skipsubscript (string, indx);
287 if (string[newi++] != ']')
288 return (0);
289 return ((string[newi] == '=') ? newi : 0);
290 }
291#endif /* ARRAY_VARS */
292
293 /* Variable names in assignment statements may contain only letters,
294 digits, and `_'. */
295 if (legal_variable_char (c) == 0)
296 return (0);
297
298 indx++;
299 }
300 return (0);
301}
302
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000303/* **************************************************************** */
304/* */
305/* Functions to manage files and file descriptors */
306/* */
307/* **************************************************************** */
308
Jari Aalto726f6381996-08-26 18:22:31 +0000309/* A function to unset no-delay mode on a file descriptor. Used in shell.c
310 to unset it on the fd passed as stdin. Should be called on stdin if
311 readline gets an EAGAIN or EWOULDBLOCK when trying to read input. */
312
313#if !defined (O_NDELAY)
314# if defined (FNDELAY)
315# define O_NDELAY FNDELAY
316# endif
317#endif /* O_NDELAY */
318
319/* Make sure no-delay mode is not set on file descriptor FD. */
Jari Aaltobb706242000-03-17 21:46:59 +0000320int
Jari Aalto28ef6c32001-04-06 19:14:31 +0000321sh_unset_nodelay_mode (fd)
Jari Aalto726f6381996-08-26 18:22:31 +0000322 int fd;
323{
Jari Aaltobb706242000-03-17 21:46:59 +0000324 int flags, bflags;
Jari Aalto726f6381996-08-26 18:22:31 +0000325
326 if ((flags = fcntl (fd, F_GETFL, 0)) < 0)
Jari Aaltobb706242000-03-17 21:46:59 +0000327 return -1;
Jari Aalto726f6381996-08-26 18:22:31 +0000328
Jari Aaltobb706242000-03-17 21:46:59 +0000329 bflags = 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000330
331 /* This is defined to O_NDELAY in filecntl.h if O_NONBLOCK is not present
332 and O_NDELAY is defined. */
Jari Aaltobb706242000-03-17 21:46:59 +0000333#ifdef O_NONBLOCK
334 bflags |= O_NONBLOCK;
335#endif
336
337#ifdef O_NDELAY
338 bflags |= O_NDELAY;
339#endif
340
341 if (flags & bflags)
Jari Aalto726f6381996-08-26 18:22:31 +0000342 {
Jari Aaltobb706242000-03-17 21:46:59 +0000343 flags &= ~bflags;
344 return (fcntl (fd, F_SETFL, flags));
Jari Aalto726f6381996-08-26 18:22:31 +0000345 }
Jari Aalto726f6381996-08-26 18:22:31 +0000346
Jari Aaltobb706242000-03-17 21:46:59 +0000347 return 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000348}
349
Jari Aalto7117c2d2002-07-17 14:10:11 +0000350/* Return 1 if file descriptor FD is valid; 0 otherwise. */
351int
352sh_validfd (fd)
353 int fd;
354{
355 return (fcntl (fd, F_GETFD, 0) >= 0);
356}
357
Jari Aaltob72432f1999-02-19 17:11:39 +0000358/* There is a bug in the NeXT 2.1 rlogind that causes opens
359 of /dev/tty to fail. */
360
361#if defined (__BEOS__)
362/* On BeOS, opening in non-blocking mode exposes a bug in BeOS, so turn it
363 into a no-op. This should probably go away in the future. */
364# undef O_NONBLOCK
365# define O_NONBLOCK 0
366#endif /* __BEOS__ */
367
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000368void
369check_dev_tty ()
370{
371 int tty_fd;
372 char *tty;
373
Jari Aaltod166f041997-06-05 14:59:13 +0000374 tty_fd = open ("/dev/tty", O_RDWR|O_NONBLOCK);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000375
376 if (tty_fd < 0)
377 {
378 tty = (char *)ttyname (fileno (stdin));
379 if (tty == 0)
380 return;
Jari Aaltod166f041997-06-05 14:59:13 +0000381 tty_fd = open (tty, O_RDWR|O_NONBLOCK);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000382 }
383 close (tty_fd);
384}
385
386/* Return 1 if PATH1 and PATH2 are the same file. This is kind of
387 expensive. If non-NULL STP1 and STP2 point to stat structures
388 corresponding to PATH1 and PATH2, respectively. */
389int
390same_file (path1, path2, stp1, stp2)
391 char *path1, *path2;
392 struct stat *stp1, *stp2;
393{
394 struct stat st1, st2;
395
396 if (stp1 == NULL)
397 {
398 if (stat (path1, &st1) != 0)
399 return (0);
400 stp1 = &st1;
401 }
402
403 if (stp2 == NULL)
404 {
405 if (stat (path2, &st2) != 0)
406 return (0);
407 stp2 = &st2;
408 }
409
410 return ((stp1->st_dev == stp2->st_dev) && (stp1->st_ino == stp2->st_ino));
411}
412
413/* Move FD to a number close to the maximum number of file descriptors
414 allowed in the shell process, to avoid the user stepping on it with
415 redirection and causing us extra work. If CHECK_NEW is non-zero,
416 we check whether or not the file descriptors are in use before
Jari Aaltod166f041997-06-05 14:59:13 +0000417 duplicating FD onto them. MAXFD says where to start checking the
418 file descriptors. If it's less than 20, we get the maximum value
419 available from getdtablesize(2). */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000420int
Jari Aaltod166f041997-06-05 14:59:13 +0000421move_to_high_fd (fd, check_new, maxfd)
422 int fd, check_new, maxfd;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000423{
424 int script_fd, nfds, ignore;
425
Jari Aaltod166f041997-06-05 14:59:13 +0000426 if (maxfd < 20)
427 {
428 nfds = getdtablesize ();
429 if (nfds <= 0)
430 nfds = 20;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000431 if (nfds > HIGH_FD_MAX)
432 nfds = HIGH_FD_MAX; /* reasonable maximum */
Jari Aaltod166f041997-06-05 14:59:13 +0000433 }
434 else
435 nfds = maxfd;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000436
437 for (nfds--; check_new && nfds > 3; nfds--)
438 if (fcntl (nfds, F_GETFD, &ignore) == -1)
439 break;
440
Jari Aalto7117c2d2002-07-17 14:10:11 +0000441 if (nfds > 3 && fd != nfds && (script_fd = dup2 (fd, nfds)) != -1)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000442 {
443 if (check_new == 0 || fd != fileno (stderr)) /* don't close stderr */
444 close (fd);
445 return (script_fd);
446 }
447
Jari Aalto7117c2d2002-07-17 14:10:11 +0000448 /* OK, we didn't find one less than our artificial maximum; return the
449 original file descriptor. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000450 return (fd);
451}
452
453/* Return non-zero if the characters from SAMPLE are not all valid
454 characters to be found in the first line of a shell script. We
455 check up to the first newline, or SAMPLE_LEN, whichever comes first.
456 All of the characters must be printable or whitespace. */
457
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000458int
459check_binary_file (sample, sample_len)
Jari Aaltof73dda02001-11-13 17:56:06 +0000460 char *sample;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000461 int sample_len;
462{
463 register int i;
Jari Aaltof73dda02001-11-13 17:56:06 +0000464 unsigned char c;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000465
466 for (i = 0; i < sample_len; i++)
467 {
Jari Aaltof73dda02001-11-13 17:56:06 +0000468 c = sample[i];
469 if (c == '\n')
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000470 return (0);
471
Jari Aaltof73dda02001-11-13 17:56:06 +0000472 if (ISSPACE (c) == 0 && ISPRINT (c) == 0)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000473 return (1);
474 }
475
476 return (0);
477}
Jari Aalto726f6381996-08-26 18:22:31 +0000478
479/* **************************************************************** */
480/* */
Jari Aaltob80f6442004-07-27 13:29:18 +0000481/* Functions to inspect pathnames */
482/* */
483/* **************************************************************** */
484
485int
486file_isdir (fn)
487 char *fn;
488{
489 struct stat sb;
490
491 return ((stat (fn, &sb) == 0) && S_ISDIR (sb.st_mode));
492}
493
494int
495file_iswdir (fn)
496 char *fn;
497{
498 return (file_isdir (fn) && test_eaccess (fn, W_OK) == 0);
499}
500
501
502/* **************************************************************** */
503/* */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000504/* Functions to manipulate pathnames */
Jari Aalto726f6381996-08-26 18:22:31 +0000505/* */
506/* **************************************************************** */
507
Jari Aalto726f6381996-08-26 18:22:31 +0000508/* Turn STRING (a pathname) into an absolute pathname, assuming that
509 DOT_PATH contains the symbolic location of `.'. This always
510 returns a new string, even if STRING was an absolute pathname to
511 begin with. */
512char *
513make_absolute (string, dot_path)
514 char *string, *dot_path;
515{
516 char *result;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000517
Jari Aalto28ef6c32001-04-06 19:14:31 +0000518 if (dot_path == 0 || ABSPATH(string))
Jari Aaltob80f6442004-07-27 13:29:18 +0000519#ifdef __CYGWIN__
520 {
521 char pathbuf[PATH_MAX + 1];
522
523 cygwin_conv_to_full_posix_path (string, pathbuf);
524 result = savestring (pathbuf);
525 }
526#else
Jari Aalto726f6381996-08-26 18:22:31 +0000527 result = savestring (string);
Jari Aaltob80f6442004-07-27 13:29:18 +0000528#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000529 else
Jari Aaltobb706242000-03-17 21:46:59 +0000530 result = sh_makepath (dot_path, string, 0);
Jari Aalto726f6381996-08-26 18:22:31 +0000531
532 return (result);
533}
534
Jari Aalto28ef6c32001-04-06 19:14:31 +0000535/* Return 1 if STRING contains an absolute pathname, else 0. Used by `cd'
536 to decide whether or not to look up a directory name in $CDPATH. */
Jari Aalto726f6381996-08-26 18:22:31 +0000537int
538absolute_pathname (string)
Jari Aaltof73dda02001-11-13 17:56:06 +0000539 const char *string;
Jari Aalto726f6381996-08-26 18:22:31 +0000540{
Jari Aalto28ef6c32001-04-06 19:14:31 +0000541 if (string == 0 || *string == '\0')
Jari Aalto726f6381996-08-26 18:22:31 +0000542 return (0);
543
Jari Aalto28ef6c32001-04-06 19:14:31 +0000544 if (ABSPATH(string))
Jari Aalto726f6381996-08-26 18:22:31 +0000545 return (1);
546
Jari Aalto28ef6c32001-04-06 19:14:31 +0000547 if (string[0] == '.' && PATHSEP(string[1])) /* . and ./ */
548 return (1);
549
550 if (string[0] == '.' && string[1] == '.' && PATHSEP(string[2])) /* .. and ../ */
551 return (1);
552
Jari Aalto726f6381996-08-26 18:22:31 +0000553 return (0);
554}
555
556/* Return 1 if STRING is an absolute program name; it is absolute if it
557 contains any slashes. This is used to decide whether or not to look
558 up through $PATH. */
559int
560absolute_program (string)
Jari Aaltof73dda02001-11-13 17:56:06 +0000561 const char *string;
Jari Aalto726f6381996-08-26 18:22:31 +0000562{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000563 return ((char *)xstrchr (string, '/') != (char *)NULL);
Jari Aalto726f6381996-08-26 18:22:31 +0000564}
565
566/* Return the `basename' of the pathname in STRING (the stuff after the
567 last '/'). If STRING is not a full pathname, simply return it. */
568char *
569base_pathname (string)
570 char *string;
571{
572 char *p;
573
Jari Aalto28ef6c32001-04-06 19:14:31 +0000574 if (absolute_pathname (string) == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000575 return (string);
576
577 p = (char *)strrchr (string, '/');
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000578 return (p ? ++p : string);
Jari Aalto726f6381996-08-26 18:22:31 +0000579}
580
581/* Return the full pathname of FILE. Easy. Filenames that begin
582 with a '/' are returned as themselves. Other filenames have
583 the current working directory prepended. A new string is
584 returned in either case. */
585char *
586full_pathname (file)
587 char *file;
588{
Jari Aaltobb706242000-03-17 21:46:59 +0000589 char *ret;
Jari Aalto726f6381996-08-26 18:22:31 +0000590
Jari Aalto7117c2d2002-07-17 14:10:11 +0000591 file = (*file == '~') ? bash_tilde_expand (file, 0) : savestring (file);
Jari Aalto726f6381996-08-26 18:22:31 +0000592
Jari Aalto28ef6c32001-04-06 19:14:31 +0000593 if (ABSPATH(file))
Jari Aalto726f6381996-08-26 18:22:31 +0000594 return (file);
595
Jari Aaltobb706242000-03-17 21:46:59 +0000596 ret = sh_makepath ((char *)NULL, file, (MP_DOCWD|MP_RMDOT));
597 free (file);
Jari Aalto726f6381996-08-26 18:22:31 +0000598
Jari Aaltobb706242000-03-17 21:46:59 +0000599 return (ret);
Jari Aalto726f6381996-08-26 18:22:31 +0000600}
601
Jari Aalto726f6381996-08-26 18:22:31 +0000602/* A slightly related function. Get the prettiest name of this
603 directory possible. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000604static char tdir[PATH_MAX];
Jari Aalto726f6381996-08-26 18:22:31 +0000605
606/* Return a pretty pathname. If the first part of the pathname is
607 the same as $HOME, then replace that with `~'. */
608char *
609polite_directory_format (name)
610 char *name;
611{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000612 char *home;
613 int l;
Jari Aalto726f6381996-08-26 18:22:31 +0000614
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000615 home = get_string_value ("HOME");
616 l = home ? strlen (home) : 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000617 if (l > 1 && strncmp (home, name, l) == 0 && (!name[l] || name[l] == '/'))
618 {
Jari Aaltoe8ce7751997-09-22 20:22:27 +0000619 strncpy (tdir + 1, name + l, sizeof(tdir) - 2);
Jari Aalto726f6381996-08-26 18:22:31 +0000620 tdir[0] = '~';
Jari Aaltoe8ce7751997-09-22 20:22:27 +0000621 tdir[sizeof(tdir) - 1] = '\0';
Jari Aalto726f6381996-08-26 18:22:31 +0000622 return (tdir);
623 }
624 else
625 return (name);
626}
627
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000628/* Given a string containing units of information separated by colons,
629 return the next one pointed to by (P_INDEX), or NULL if there are no more.
630 Advance (P_INDEX) to the character after the colon. */
631char *
632extract_colon_unit (string, p_index)
633 char *string;
634 int *p_index;
Jari Aalto726f6381996-08-26 18:22:31 +0000635{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000636 int i, start, len;
637 char *value;
638
639 if (string == 0)
640 return (string);
641
642 len = strlen (string);
643 if (*p_index >= len)
644 return ((char *)NULL);
645
646 i = *p_index;
647
648 /* Each call to this routine leaves the index pointing at a colon if
649 there is more to the path. If I is > 0, then increment past the
650 `:'. If I is 0, then the path has a leading colon. Trailing colons
651 are handled OK by the `else' part of the if statement; an empty
652 string is returned in that case. */
653 if (i && string[i] == ':')
654 i++;
655
656 for (start = i; string[i] && string[i] != ':'; i++)
657 ;
658
659 *p_index = i;
660
661 if (i == start)
Jari Aalto726f6381996-08-26 18:22:31 +0000662 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000663 if (string[i])
664 (*p_index)++;
665 /* Return "" in the case of a trailing `:'. */
Jari Aaltof73dda02001-11-13 17:56:06 +0000666 value = (char *)xmalloc (1);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000667 value[0] = '\0';
Jari Aalto726f6381996-08-26 18:22:31 +0000668 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000669 else
Jari Aaltobb706242000-03-17 21:46:59 +0000670 value = substring (string, start, i);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000671
672 return (value);
Jari Aalto726f6381996-08-26 18:22:31 +0000673}
674
Jari Aalto726f6381996-08-26 18:22:31 +0000675/* **************************************************************** */
676/* */
677/* Tilde Initialization and Expansion */
678/* */
679/* **************************************************************** */
680
Jari Aaltocce855b1998-04-17 19:52:44 +0000681#if defined (PUSHD_AND_POPD)
682extern char *get_dirstack_from_string __P((char *));
683#endif
684
Jari Aaltof73dda02001-11-13 17:56:06 +0000685static char **bash_tilde_prefixes;
686static char **bash_tilde_suffixes;
687
Jari Aalto726f6381996-08-26 18:22:31 +0000688/* If tilde_expand hasn't been able to expand the text, perhaps it
689 is a special shell expansion. This function is installed as the
Jari Aaltocce855b1998-04-17 19:52:44 +0000690 tilde_expansion_preexpansion_hook. It knows how to expand ~- and ~+.
691 If PUSHD_AND_POPD is defined, ~[+-]N expands to directories from the
692 directory stack. */
Jari Aalto726f6381996-08-26 18:22:31 +0000693static char *
Jari Aaltod166f041997-06-05 14:59:13 +0000694bash_special_tilde_expansions (text)
Jari Aalto726f6381996-08-26 18:22:31 +0000695 char *text;
696{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000697 char *result;
Jari Aalto726f6381996-08-26 18:22:31 +0000698
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000699 result = (char *)NULL;
Jari Aaltocce855b1998-04-17 19:52:44 +0000700
701 if (text[0] == '+' && text[1] == '\0')
702 result = get_string_value ("PWD");
703 else if (text[0] == '-' && text[1] == '\0')
704 result = get_string_value ("OLDPWD");
705#if defined (PUSHD_AND_POPD)
Jari Aaltof73dda02001-11-13 17:56:06 +0000706 else if (DIGIT (*text) || ((*text == '+' || *text == '-') && DIGIT (text[1])))
Jari Aaltocce855b1998-04-17 19:52:44 +0000707 result = get_dirstack_from_string (text);
708#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000709
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000710 return (result ? savestring (result) : (char *)NULL);
Jari Aalto726f6381996-08-26 18:22:31 +0000711}
712
713/* Initialize the tilde expander. In Bash, we handle `~-' and `~+', as
714 well as handling special tilde prefixes; `:~" and `=~' are indications
715 that we should do tilde expansion. */
716void
717tilde_initialize ()
718{
719 static int times_called = 0;
720
Jari Aaltod166f041997-06-05 14:59:13 +0000721 /* Tell the tilde expander that we want a crack first. */
Jari Aaltof73dda02001-11-13 17:56:06 +0000722 tilde_expansion_preexpansion_hook = bash_special_tilde_expansions;
Jari Aalto726f6381996-08-26 18:22:31 +0000723
724 /* Tell the tilde expander about special strings which start a tilde
725 expansion, and the special strings that end one. Only do this once.
726 tilde_initialize () is called from within bashline_reinitialize (). */
Jari Aaltocce855b1998-04-17 19:52:44 +0000727 if (times_called++ == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000728 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000729 bash_tilde_prefixes = strvec_create (3);
Jari Aaltof73dda02001-11-13 17:56:06 +0000730 bash_tilde_prefixes[0] = "=~";
731 bash_tilde_prefixes[1] = ":~";
732 bash_tilde_prefixes[2] = (char *)NULL;
Jari Aalto726f6381996-08-26 18:22:31 +0000733
Jari Aaltof73dda02001-11-13 17:56:06 +0000734 tilde_additional_prefixes = bash_tilde_prefixes;
735
Jari Aalto7117c2d2002-07-17 14:10:11 +0000736 bash_tilde_suffixes = strvec_create (3);
Jari Aaltof73dda02001-11-13 17:56:06 +0000737 bash_tilde_suffixes[0] = ":";
738 bash_tilde_suffixes[1] = "=~"; /* XXX - ?? */
739 bash_tilde_suffixes[2] = (char *)NULL;
740
741 tilde_additional_suffixes = bash_tilde_suffixes;
Jari Aalto726f6381996-08-26 18:22:31 +0000742 }
Jari Aalto726f6381996-08-26 18:22:31 +0000743}
744
Jari Aaltof73dda02001-11-13 17:56:06 +0000745/* POSIX.2, 3.6.1: A tilde-prefix consists of an unquoted tilde character
746 at the beginning of the word, followed by all of the characters preceding
747 the first unquoted slash in the word, or all the characters in the word
748 if there is no slash...If none of the characters in the tilde-prefix are
749 quoted, the characters in the tilde-prefix following the tilde shell be
750 treated as a possible login name. */
751
752#define TILDE_END(c) ((c) == '\0' || (c) == '/' || (c) == ':')
753
754static int
755unquoted_tilde_word (s)
756 const char *s;
757{
758 const char *r;
759
760 for (r = s; TILDE_END(*r) == 0; r++)
761 {
762 switch (*r)
763 {
764 case '\\':
765 case '\'':
766 case '"':
767 return 0;
768 }
769 }
770 return 1;
771}
772
Jari Aalto7117c2d2002-07-17 14:10:11 +0000773/* Tilde-expand S by running it through the tilde expansion library.
774 ASSIGN_P is 1 if this is a variable assignment, so the alternate
775 tilde prefixes should be enabled (`=~' and `:~', see above). */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000776char *
Jari Aalto7117c2d2002-07-17 14:10:11 +0000777bash_tilde_expand (s, assign_p)
Jari Aaltof73dda02001-11-13 17:56:06 +0000778 const char *s;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000779 int assign_p;
Jari Aalto726f6381996-08-26 18:22:31 +0000780{
Jari Aaltof73dda02001-11-13 17:56:06 +0000781 int old_immed, r;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000782 char *ret;
Jari Aalto726f6381996-08-26 18:22:31 +0000783
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000784 old_immed = interrupt_immediately;
785 interrupt_immediately = 1;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000786 tilde_additional_prefixes = assign_p ? bash_tilde_prefixes : (char **)0;
Jari Aaltof73dda02001-11-13 17:56:06 +0000787 r = (*s == '~') ? unquoted_tilde_word (s) : 1;
788 ret = r ? tilde_expand (s) : savestring (s);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000789 interrupt_immediately = old_immed;
790 return (ret);
Jari Aalto726f6381996-08-26 18:22:31 +0000791}
Jari Aaltod166f041997-06-05 14:59:13 +0000792
793/* **************************************************************** */
794/* */
795/* Functions to manipulate and search the group list */
796/* */
797/* **************************************************************** */
798
799static int ngroups, maxgroups;
800
801/* The set of groups that this user is a member of. */
802static GETGROUPS_T *group_array = (GETGROUPS_T *)NULL;
803
804#if !defined (NOGROUP)
805# define NOGROUP (gid_t) -1
806#endif
807
Jari Aaltod166f041997-06-05 14:59:13 +0000808static void
809initialize_group_array ()
810{
811 register int i;
812
813 if (maxgroups == 0)
814 maxgroups = getmaxgroups ();
815
816 ngroups = 0;
817 group_array = (GETGROUPS_T *)xrealloc (group_array, maxgroups * sizeof (GETGROUPS_T));
818
819#if defined (HAVE_GETGROUPS)
820 ngroups = getgroups (maxgroups, group_array);
821#endif
822
823 /* If getgroups returns nothing, or the OS does not support getgroups(),
824 make sure the groups array includes at least the current gid. */
825 if (ngroups == 0)
826 {
827 group_array[0] = current_user.gid;
828 ngroups = 1;
829 }
830
831 /* If the primary group is not in the groups array, add it as group_array[0]
832 and shuffle everything else up 1, if there's room. */
833 for (i = 0; i < ngroups; i++)
834 if (current_user.gid == (gid_t)group_array[i])
835 break;
836 if (i == ngroups && ngroups < maxgroups)
837 {
838 for (i = ngroups; i > 0; i--)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000839 group_array[i] = group_array[i - 1];
Jari Aaltod166f041997-06-05 14:59:13 +0000840 group_array[0] = current_user.gid;
841 ngroups++;
842 }
Jari Aaltocce855b1998-04-17 19:52:44 +0000843
844 /* If the primary group is not group_array[0], swap group_array[0] and
845 whatever the current group is. The vast majority of systems should
846 not need this; a notable exception is Linux. */
847 if (group_array[0] != current_user.gid)
848 {
849 for (i = 0; i < ngroups; i++)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000850 if (group_array[i] == current_user.gid)
851 break;
Jari Aaltocce855b1998-04-17 19:52:44 +0000852 if (i < ngroups)
853 {
854 group_array[i] = group_array[0];
855 group_array[0] = current_user.gid;
856 }
857 }
Jari Aaltod166f041997-06-05 14:59:13 +0000858}
859
860/* Return non-zero if GID is one that we have in our groups list. */
861int
Jari Aaltocce855b1998-04-17 19:52:44 +0000862#if defined (__STDC__) || defined ( _MINIX)
863group_member (gid_t gid)
864#else
Jari Aaltod166f041997-06-05 14:59:13 +0000865group_member (gid)
866 gid_t gid;
Jari Aaltocce855b1998-04-17 19:52:44 +0000867#endif /* !__STDC__ && !_MINIX */
Jari Aaltod166f041997-06-05 14:59:13 +0000868{
869#if defined (HAVE_GETGROUPS)
870 register int i;
871#endif
872
873 /* Short-circuit if possible, maybe saving a call to getgroups(). */
874 if (gid == current_user.gid || gid == current_user.egid)
875 return (1);
876
877#if defined (HAVE_GETGROUPS)
878 if (ngroups == 0)
879 initialize_group_array ();
880
881 /* In case of error, the user loses. */
882 if (ngroups <= 0)
883 return (0);
884
885 /* Search through the list looking for GID. */
886 for (i = 0; i < ngroups; i++)
887 if (gid == (gid_t)group_array[i])
888 return (1);
889#endif
890
891 return (0);
892}
893
894char **
895get_group_list (ngp)
896 int *ngp;
897{
898 static char **group_vector = (char **)NULL;
899 register int i;
Jari Aaltod166f041997-06-05 14:59:13 +0000900
901 if (group_vector)
902 {
903 if (ngp)
904 *ngp = ngroups;
905 return group_vector;
906 }
907
908 if (ngroups == 0)
909 initialize_group_array ();
910
911 if (ngroups <= 0)
912 {
913 if (ngp)
914 *ngp = 0;
915 return (char **)NULL;
916 }
917
Jari Aalto7117c2d2002-07-17 14:10:11 +0000918 group_vector = strvec_create (ngroups);
Jari Aaltod166f041997-06-05 14:59:13 +0000919 for (i = 0; i < ngroups; i++)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000920 group_vector[i] = itos (group_array[i]);
Jari Aaltob72432f1999-02-19 17:11:39 +0000921
Jari Aaltod166f041997-06-05 14:59:13 +0000922 if (ngp)
923 *ngp = ngroups;
924 return group_vector;
925}
Jari Aaltob72432f1999-02-19 17:11:39 +0000926
927int *
928get_group_array (ngp)
929 int *ngp;
930{
931 int i;
932 static int *group_iarray = (int *)NULL;
933
934 if (group_iarray)
935 {
936 if (ngp)
937 *ngp = ngroups;
938 return (group_iarray);
939 }
940
941 if (ngroups == 0)
942 initialize_group_array ();
943
944 if (ngroups <= 0)
945 {
946 if (ngp)
947 *ngp = 0;
948 return (int *)NULL;
949 }
950
951 group_iarray = (int *)xmalloc (ngroups * sizeof (int));
952 for (i = 0; i < ngroups; i++)
953 group_iarray[i] = (int)group_array[i];
954
955 if (ngp)
956 *ngp = ngroups;
957 return group_iarray;
958}