commit bash-20051123 snapshot
[platform/upstream/bash.git] / general.c~
1 /* general.c -- Stuff that is used by all files. */
2
3 /* Copyright (C) 1987-2004 Free Software Foundation, Inc.
4
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
19    Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
20
21 #include "config.h"
22
23 #include "bashtypes.h"
24 #ifndef _MINIX
25 #  include <sys/param.h>
26 #endif
27 #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"
35 #include <stdio.h>
36 #include "chartypes.h"
37 #include <errno.h>
38
39 #include "bashintl.h"
40
41 #include "shell.h"
42 #include "test.h"
43
44 #include <tilde/tilde.h>
45
46 #if !defined (errno)
47 extern int errno;
48 #endif /* !errno */
49
50 extern int expand_aliases;
51 extern int interrupt_immediately;
52 extern int interactive_comments;
53 extern int check_hashed_filenames;
54 extern int source_uses_path;
55 extern int source_searches_cwd;
56
57 static char *bash_special_tilde_expansions __P((char *));
58 static int unquoted_tilde_word __P((const char *));
59 static void initialize_group_array __P((void));
60
61 /* A standard error message to use when getcwd() returns NULL. */
62 char *bash_getcwd_errstr = N_("getcwd: cannot access parent directories");
63
64 /* Do whatever is necessary to initialize `Posix mode'. */
65 void
66 posix_initialize (on)
67      int on;
68 {
69   /* Things that should be turned on when posix mode is enabled. */
70   if (on != 0)
71     {
72       interactive_comments = source_uses_path = expand_aliases = 1;
73     }
74
75   /* Things that should be turned on when posix mode is disabled. */
76   if (on == 0)
77     {
78       source_searches_cwd = 1;
79       expand_aliases = interactive_shell;
80     }
81 }
82
83 /* **************************************************************** */
84 /*                                                                  */
85 /*  Functions to convert to and from and display non-standard types */
86 /*                                                                  */
87 /* **************************************************************** */
88
89 #if defined (RLIMTYPE)
90 RLIMTYPE
91 string_to_rlimtype (s)
92      char *s;
93 {
94   RLIMTYPE ret;
95   int neg;
96
97   ret = 0;
98   neg = 0;
99   while (s && *s && whitespace (*s))
100     s++;
101   if (*s == '-' || *s == '+')
102     {
103       neg = *s == '-';
104       s++;
105     }
106   for ( ; s && *s && DIGIT (*s); s++)
107     ret = (ret * 10) + TODIGIT (*s);
108   return (neg ? -ret : ret);
109 }
110
111 void
112 print_rlimtype (n, addnl)
113      RLIMTYPE n;
114      int addnl;
115 {
116   char s[INT_STRLEN_BOUND (RLIMTYPE) + 1], *p;
117
118   p = s + sizeof(s);
119   *--p = '\0';
120
121   if (n < 0)
122     {
123       do
124         *--p = '0' - n % 10;
125       while ((n /= 10) != 0);
126
127       *--p = '-';
128     }
129   else
130     {
131       do
132         *--p = '0' + n % 10;
133       while ((n /= 10) != 0);
134     }
135
136   printf ("%s%s", p, addnl ? "\n" : "");
137 }
138 #endif /* RLIMTYPE */
139
140 /* **************************************************************** */
141 /*                                                                  */
142 /*                     Input Validation Functions                   */
143 /*                                                                  */
144 /* **************************************************************** */
145
146 /* Return non-zero if all of the characters in STRING are digits. */
147 int
148 all_digits (string)
149      char *string;
150 {
151   register char *s;
152
153   for (s = string; *s; s++)
154     if (DIGIT (*s) == 0)
155       return (0);
156
157   return (1);
158 }
159
160 /* Return non-zero if the characters pointed to by STRING constitute a
161    valid number.  Stuff the converted number into RESULT if RESULT is
162    not null. */
163 int
164 legal_number (string, result)
165      char *string;
166      intmax_t *result;
167 {
168   intmax_t value;
169   char *ep;
170
171   if (result)
172     *result = 0;
173
174   errno = 0;
175   value = strtoimax (string, &ep, 10);
176   if (errno)
177     return 0;   /* errno is set on overflow or underflow */
178
179   /* Skip any trailing whitespace, since strtoimax does not. */
180   while (whitespace (*ep))
181     ep++;
182
183   /* If *string is not '\0' but *ep is '\0' on return, the entire string
184      is valid. */
185   if (string && *string && *ep == '\0')
186     {
187       if (result)
188         *result = value;
189       /* The SunOS4 implementation of strtol() will happily ignore
190          overflow conditions, so this cannot do overflow correctly
191          on those systems. */
192       return 1;
193     }
194     
195   return (0);
196 }
197
198 /* Return 1 if this token is a legal shell `identifier'; that is, it consists
199    solely of letters, digits, and underscores, and does not begin with a
200    digit. */
201 int
202 legal_identifier (name)
203      char *name;
204 {
205   register char *s;
206   unsigned char c;
207
208   if (!name || !(c = *name) || (legal_variable_starter (c) == 0))
209     return (0);
210
211   for (s = name + 1; (c = *s) != 0; s++)
212     {
213       if (legal_variable_char (c) == 0)
214         return (0);
215     }
216   return (1);
217 }
218
219 /* Make sure that WORD is a valid shell identifier, i.e.
220    does not contain a dollar sign, nor is quoted in any way.  Nor
221    does it consist of all digits.  If CHECK_WORD is non-zero,
222    the word is checked to ensure that it consists of only letters,
223    digits, and underscores. */
224 int
225 check_identifier (word, check_word)
226      WORD_DESC *word;
227      int check_word;
228 {
229   if ((word->flags & (W_HASDOLLAR|W_QUOTED)) || all_digits (word->word))
230     {
231       internal_error (_("`%s': not a valid identifier"), word->word);
232       return (0);
233     }
234   else if (check_word && legal_identifier (word->word) == 0)
235     {
236       internal_error (_("`%s': not a valid identifier"), word->word);
237       return (0);
238     }
239   else
240     return (1);
241 }
242
243 /* Return 1 if STRING comprises a valid alias name.  The shell accepts
244    essentially all characters except those which must be quoted to the
245    parser (which disqualifies them from alias expansion anyway) and `/'. */
246 int
247 legal_alias_name (string, flags)
248      char *string;
249      int flags;
250 {
251   register char *s;
252
253   for (s = string; *s; s++)
254     if (shellbreak (*s) || shellxquote (*s) || shellexp (*s) || (*s == '/'))
255       return 0;
256   return 1;
257 }
258
259 /* Returns non-zero if STRING is an assignment statement.  The returned value
260    is the index of the `=' sign. */
261 int
262 assignment (string, flags)
263      const char *string;
264      int flags;
265 {
266   register unsigned char c;
267   register int newi, indx;
268
269   c = string[indx = 0];
270
271 #if defined (ARRAY_VARS)
272   if ((legal_variable_starter (c) == 0) && (flags == 0 || c != '[')) /* ] */
273 #else
274   if (legal_variable_starter (c) == 0)
275 #endif
276     return (0);
277
278   while (c = string[indx])
279     {
280       /* The following is safe.  Note that '=' at the start of a word
281          is not an assignment statement. */
282       if (c == '=')
283         return (indx);
284
285 #if defined (ARRAY_VARS)
286       if (c == '[')
287         {
288           newi = skipsubscript (string, indx);
289           if (string[newi++] != ']')
290             return (0);
291           if (string[newi] == '+' && string[newi+1] == '=')
292             return (newi + 1);
293           return ((string[newi] == '=') ? newi : 0);
294         }
295 #endif /* ARRAY_VARS */
296
297       /* Check for `+=' */
298       if (c == '+' && string[indx+1] == '=')
299         return (indx + 1);
300
301       /* Variable names in assignment statements may contain only letters,
302          digits, and `_'. */
303       if (legal_variable_char (c) == 0)
304         return (0);
305
306       indx++;
307     }
308   return (0);
309 }
310
311 /* **************************************************************** */
312 /*                                                                  */
313 /*           Functions to manage files and file descriptors         */
314 /*                                                                  */
315 /* **************************************************************** */
316
317 /* A function to unset no-delay mode on a file descriptor.  Used in shell.c
318    to unset it on the fd passed as stdin.  Should be called on stdin if
319    readline gets an EAGAIN or EWOULDBLOCK when trying to read input. */
320
321 #if !defined (O_NDELAY)
322 #  if defined (FNDELAY)
323 #    define O_NDELAY FNDELAY
324 #  endif
325 #endif /* O_NDELAY */
326
327 /* Make sure no-delay mode is not set on file descriptor FD. */
328 int
329 sh_unset_nodelay_mode (fd)
330      int fd;
331 {
332   int flags, bflags;
333
334   if ((flags = fcntl (fd, F_GETFL, 0)) < 0)
335     return -1;
336
337   bflags = 0;
338
339   /* This is defined to O_NDELAY in filecntl.h if O_NONBLOCK is not present
340      and O_NDELAY is defined. */
341 #ifdef O_NONBLOCK
342   bflags |= O_NONBLOCK;
343 #endif
344
345 #ifdef O_NDELAY
346   bflags |= O_NDELAY;
347 #endif
348
349   if (flags & bflags)
350     {
351       flags &= ~bflags;
352       return (fcntl (fd, F_SETFL, flags));
353     }
354
355   return 0;
356 }
357
358 /* Return 1 if file descriptor FD is valid; 0 otherwise. */
359 int
360 sh_validfd (fd)
361      int fd;
362 {
363   return (fcntl (fd, F_GETFD, 0) >= 0);
364 }
365
366 /* There is a bug in the NeXT 2.1 rlogind that causes opens
367    of /dev/tty to fail. */
368
369 #if defined (__BEOS__)
370 /* On BeOS, opening in non-blocking mode exposes a bug in BeOS, so turn it
371    into a no-op.  This should probably go away in the future. */
372 #  undef O_NONBLOCK
373 #  define O_NONBLOCK 0
374 #endif /* __BEOS__ */
375
376 void
377 check_dev_tty ()
378 {
379   int tty_fd;
380   char *tty;
381
382   tty_fd = open ("/dev/tty", O_RDWR|O_NONBLOCK);
383
384   if (tty_fd < 0)
385     {
386       tty = (char *)ttyname (fileno (stdin));
387       if (tty == 0)
388         return;
389       tty_fd = open (tty, O_RDWR|O_NONBLOCK);
390     }
391   close (tty_fd);
392 }
393
394 /* Return 1 if PATH1 and PATH2 are the same file.  This is kind of
395    expensive.  If non-NULL STP1 and STP2 point to stat structures
396    corresponding to PATH1 and PATH2, respectively. */
397 int
398 same_file (path1, path2, stp1, stp2)
399      char *path1, *path2;
400      struct stat *stp1, *stp2;
401 {
402   struct stat st1, st2;
403
404   if (stp1 == NULL)
405     {
406       if (stat (path1, &st1) != 0)
407         return (0);
408       stp1 = &st1;
409     }
410
411   if (stp2 == NULL)
412     {
413       if (stat (path2, &st2) != 0)
414         return (0);
415       stp2 = &st2;
416     }
417
418   return ((stp1->st_dev == stp2->st_dev) && (stp1->st_ino == stp2->st_ino));
419 }
420
421 /* Move FD to a number close to the maximum number of file descriptors
422    allowed in the shell process, to avoid the user stepping on it with
423    redirection and causing us extra work.  If CHECK_NEW is non-zero,
424    we check whether or not the file descriptors are in use before
425    duplicating FD onto them.  MAXFD says where to start checking the
426    file descriptors.  If it's less than 20, we get the maximum value
427    available from getdtablesize(2). */
428 int
429 move_to_high_fd (fd, check_new, maxfd)
430      int fd, check_new, maxfd;
431 {
432   int script_fd, nfds, ignore;
433
434   if (maxfd < 20)
435     {
436       nfds = getdtablesize ();
437       if (nfds <= 0)
438         nfds = 20;
439       if (nfds > HIGH_FD_MAX)
440         nfds = HIGH_FD_MAX;             /* reasonable maximum */
441     }
442   else
443     nfds = maxfd;
444
445   for (nfds--; check_new && nfds > 3; nfds--)
446     if (fcntl (nfds, F_GETFD, &ignore) == -1)
447       break;
448
449   if (nfds > 3 && fd != nfds && (script_fd = dup2 (fd, nfds)) != -1)
450     {
451       if (check_new == 0 || fd != fileno (stderr))      /* don't close stderr */
452         close (fd);
453       return (script_fd);
454     }
455
456   /* OK, we didn't find one less than our artificial maximum; return the
457      original file descriptor. */
458   return (fd);
459 }
460  
461 /* Return non-zero if the characters from SAMPLE are not all valid
462    characters to be found in the first line of a shell script.  We
463    check up to the first newline, or SAMPLE_LEN, whichever comes first.
464    All of the characters must be printable or whitespace. */
465
466 int
467 check_binary_file (sample, sample_len)
468      char *sample;
469      int sample_len;
470 {
471   register int i;
472   unsigned char c;
473
474   for (i = 0; i < sample_len; i++)
475     {
476       c = sample[i];
477       if (c == '\n')
478         return (0);
479
480       if (ISSPACE (c) == 0 && ISPRINT (c) == 0)
481         return (1);
482     }
483
484   return (0);
485 }
486
487 /* **************************************************************** */
488 /*                                                                  */
489 /*                  Functions to inspect pathnames                  */
490 /*                                                                  */
491 /* **************************************************************** */
492
493 int
494 file_isdir (fn)
495      char *fn;
496 {
497   struct stat sb;
498
499   return ((stat (fn, &sb) == 0) && S_ISDIR (sb.st_mode));
500 }
501
502 int
503 file_iswdir (fn)
504      char *fn;
505 {
506   return (file_isdir (fn) && test_eaccess (fn, W_OK) == 0);
507 }
508
509
510 /* **************************************************************** */
511 /*                                                                  */
512 /*                  Functions to manipulate pathnames               */
513 /*                                                                  */
514 /* **************************************************************** */
515
516 /* Turn STRING (a pathname) into an absolute pathname, assuming that
517    DOT_PATH contains the symbolic location of `.'.  This always
518    returns a new string, even if STRING was an absolute pathname to
519    begin with. */
520 char *
521 make_absolute (string, dot_path)
522      char *string, *dot_path;
523 {
524   char *result;
525
526   if (dot_path == 0 || ABSPATH(string))
527 #ifdef __CYGWIN__
528     {
529       char pathbuf[PATH_MAX + 1];
530
531       cygwin_conv_to_full_posix_path (string, pathbuf);
532       result = savestring (pathbuf);
533     }
534 #else
535     result = savestring (string);
536 #endif
537   else
538     result = sh_makepath (dot_path, string, 0);
539
540   return (result);
541 }
542
543 /* Return 1 if STRING contains an absolute pathname, else 0.  Used by `cd'
544    to decide whether or not to look up a directory name in $CDPATH. */
545 int
546 absolute_pathname (string)
547      const char *string;
548 {
549   if (string == 0 || *string == '\0')
550     return (0);
551
552   if (ABSPATH(string))
553     return (1);
554
555   if (string[0] == '.' && PATHSEP(string[1]))   /* . and ./ */
556     return (1);
557
558   if (string[0] == '.' && string[1] == '.' && PATHSEP(string[2]))       /* .. and ../ */
559     return (1);
560
561   return (0);
562 }
563
564 /* Return 1 if STRING is an absolute program name; it is absolute if it
565    contains any slashes.  This is used to decide whether or not to look
566    up through $PATH. */
567 int
568 absolute_program (string)
569      const char *string;
570 {
571   return ((char *)xstrchr (string, '/') != (char *)NULL);
572 }
573
574 /* Return the `basename' of the pathname in STRING (the stuff after the
575    last '/').  If STRING is `/', just return it. */
576 char *
577 base_pathname (string)
578      char *string;
579 {
580   char *p;
581
582 #if 0
583   if (absolute_pathname (string) == 0)
584     return (string);
585 #endif
586
587   if (string[0] == '/' && string[1] == 0)
588     return (string);
589
590   p = (char *)strrchr (string, '/');
591   return (p ? ++p : string);
592 }
593
594 /* Return the full pathname of FILE.  Easy.  Filenames that begin
595    with a '/' are returned as themselves.  Other filenames have
596    the current working directory prepended.  A new string is
597    returned in either case. */
598 char *
599 full_pathname (file)
600      char *file;
601 {
602   char *ret;
603
604   file = (*file == '~') ? bash_tilde_expand (file, 0) : savestring (file);
605
606   if (ABSPATH(file))
607     return (file);
608
609   ret = sh_makepath ((char *)NULL, file, (MP_DOCWD|MP_RMDOT));
610   free (file);
611
612   return (ret);
613 }
614
615 /* A slightly related function.  Get the prettiest name of this
616    directory possible. */
617 static char tdir[PATH_MAX];
618
619 /* Return a pretty pathname.  If the first part of the pathname is
620    the same as $HOME, then replace that with `~'.  */
621 char *
622 polite_directory_format (name)
623      char *name;
624 {
625   char *home;
626   int l;
627
628   home = get_string_value ("HOME");
629   l = home ? strlen (home) : 0;
630   if (l > 1 && strncmp (home, name, l) == 0 && (!name[l] || name[l] == '/'))
631     {
632       strncpy (tdir + 1, name + l, sizeof(tdir) - 2);
633       tdir[0] = '~';
634       tdir[sizeof(tdir) - 1] = '\0';
635       return (tdir);
636     }
637   else
638     return (name);
639 }
640
641 /* Given a string containing units of information separated by colons,
642    return the next one pointed to by (P_INDEX), or NULL if there are no more.
643    Advance (P_INDEX) to the character after the colon. */
644 char *
645 extract_colon_unit (string, p_index)
646      char *string;
647      int *p_index;
648 {
649   int i, start, len;
650   char *value;
651
652   if (string == 0)
653     return (string);
654
655   len = strlen (string);
656   if (*p_index >= len)
657     return ((char *)NULL);
658
659   i = *p_index;
660
661   /* Each call to this routine leaves the index pointing at a colon if
662      there is more to the path.  If I is > 0, then increment past the
663      `:'.  If I is 0, then the path has a leading colon.  Trailing colons
664      are handled OK by the `else' part of the if statement; an empty
665      string is returned in that case. */
666   if (i && string[i] == ':')
667     i++;
668
669   for (start = i; string[i] && string[i] != ':'; i++)
670     ;
671
672   *p_index = i;
673
674   if (i == start)
675     {
676       if (string[i])
677         (*p_index)++;
678       /* Return "" in the case of a trailing `:'. */
679       value = (char *)xmalloc (1);
680       value[0] = '\0';
681     }
682   else
683     value = substring (string, start, i);
684
685   return (value);
686 }
687
688 /* **************************************************************** */
689 /*                                                                  */
690 /*                  Tilde Initialization and Expansion              */
691 /*                                                                  */
692 /* **************************************************************** */
693
694 #if defined (PUSHD_AND_POPD)
695 extern char *get_dirstack_from_string __P((char *));
696 #endif
697
698 static char **bash_tilde_prefixes;
699 static char **bash_tilde_prefixes2;
700 static char **bash_tilde_suffixes;
701 static char **bash_tilde_suffixes2;
702
703 /* If tilde_expand hasn't been able to expand the text, perhaps it
704    is a special shell expansion.  This function is installed as the
705    tilde_expansion_preexpansion_hook.  It knows how to expand ~- and ~+.
706    If PUSHD_AND_POPD is defined, ~[+-]N expands to directories from the
707    directory stack. */
708 static char *
709 bash_special_tilde_expansions (text)
710      char *text;
711 {
712   char *result;
713
714   result = (char *)NULL;
715
716   if (text[0] == '+' && text[1] == '\0')
717     result = get_string_value ("PWD");
718   else if (text[0] == '-' && text[1] == '\0')
719     result = get_string_value ("OLDPWD");
720 #if defined (PUSHD_AND_POPD)
721   else if (DIGIT (*text) || ((*text == '+' || *text == '-') && DIGIT (text[1])))
722     result = get_dirstack_from_string (text);
723 #endif
724
725   return (result ? savestring (result) : (char *)NULL);
726 }
727
728 /* Initialize the tilde expander.  In Bash, we handle `~-' and `~+', as
729    well as handling special tilde prefixes; `:~" and `=~' are indications
730    that we should do tilde expansion. */
731 void
732 tilde_initialize ()
733 {
734   static int times_called = 0;
735
736   /* Tell the tilde expander that we want a crack first. */
737   tilde_expansion_preexpansion_hook = bash_special_tilde_expansions;
738
739   /* Tell the tilde expander about special strings which start a tilde
740      expansion, and the special strings that end one.  Only do this once.
741      tilde_initialize () is called from within bashline_reinitialize (). */
742   if (times_called++ == 0)
743     {
744       bash_tilde_prefixes = strvec_create (3);
745       bash_tilde_prefixes[0] = "=~";
746       bash_tilde_prefixes[1] = ":~";
747       bash_tilde_prefixes[2] = (char *)NULL;
748
749       bash_tilde_prefixes2 = strvec_create (2);
750       bash_tilde_prefixes2[0] = ":~";
751       bash_tilde_prefixes2[1] = (char *)NULL;
752
753       tilde_additional_prefixes = bash_tilde_prefixes;
754
755       bash_tilde_suffixes = strvec_create (3);
756       bash_tilde_suffixes[0] = ":";
757       bash_tilde_suffixes[1] = "=~";    /* XXX - ?? */
758       bash_tilde_suffixes[2] = (char *)NULL;
759
760       tilde_additional_suffixes = bash_tilde_suffixes;
761
762       bash_tilde_suffixes2 = strvec_create (2);
763       bash_tilde_suffixes2[0] = ":";
764       bash_tilde_suffixes2[1] = (char *)NULL;
765     }
766 }
767
768 /* POSIX.2, 3.6.1:  A tilde-prefix consists of an unquoted tilde character
769    at the beginning of the word, followed by all of the characters preceding
770    the first unquoted slash in the word, or all the characters in the word
771    if there is no slash...If none of the characters in the tilde-prefix are
772    quoted, the characters in the tilde-prefix following the tilde shell be
773    treated as a possible login name. */
774
775 #define TILDE_END(c)    ((c) == '\0' || (c) == '/' || (c) == ':')
776
777 static int
778 unquoted_tilde_word (s)
779      const char *s;
780 {
781   const char *r;
782
783   for (r = s; TILDE_END(*r) == 0; r++)
784     {
785       switch (*r)
786         {
787         case '\\':
788         case '\'':
789         case '"':
790           return 0;
791         }
792     }
793   return 1;
794 }
795
796 /* Find the end of the tilde-prefix starting at S, and return the tilde
797    prefix in newly-allocated memory.  Return the length of the string in
798    *LENP.  FLAGS tells whether or not we're in an assignment context --
799    if so, `:' delimits the end of the tilde prefix as well. */
800 char *
801 bash_tilde_find_word (s, flags, lenp)
802      const char *s;
803      int flags, *lenp;
804 {
805   const char *r;
806   char *ret;
807   int l;
808
809   for (r = s; *r && *r != '/'; r++)
810     {
811       /* Short-circuit immediately if we see a quote character.  Even though
812          POSIX says that `the first unquoted slash' (or `:') terminates the
813          tilde-prefix, in practice, any quoted portion of the tilde prefix
814          will cause it to not be expanded. */
815       if (*r == '\\' || *r == '\'' || *r == '"')  
816         {
817           ret = savestring (s);
818           if (lenp)
819             *lenp = 0;
820           return ret;
821         }
822       else if (flags && *r == ':')
823         break;
824     }
825   l = r - s;
826   ret = xmalloc (l + 1);
827   strncpy (ret, s, l);
828   ret[l] = '\0';
829   if (lenp)
830     *lenp = l;
831   return ret;
832 }
833     
834 /* Tilde-expand S by running it through the tilde expansion library.
835    ASSIGN_P is 1 if this is a variable assignment, so the alternate
836    tilde prefixes should be enabled (`=~' and `:~', see above).  If
837    ASSIGN_P is 2, we are expanding the rhs of an assignment statement,
838    so `=~' is not valid. */
839 char *
840 bash_tilde_expand (s, assign_p)
841      const char *s;
842      int assign_p;
843 {
844   int old_immed, r;
845   char *ret;
846
847   old_immed = interrupt_immediately;
848   interrupt_immediately = 1;
849
850   tilde_additional_prefixes = assign_p == 0 ? (char **)0
851                                             : (assign_p == 2 ? bash_tilde_prefixes2 : bash_tilde_prefixes);
852   if (assign_p == 2)
853     tilde_additional_suffixes = bash_tilde_suffixes2;
854
855   r = (*s == '~') ? unquoted_tilde_word (s) : 1;
856   ret = r ? tilde_expand (s) : savestring (s);
857   interrupt_immediately = old_immed;
858   return (ret);
859 }
860
861 /* **************************************************************** */
862 /*                                                                  */
863 /*        Functions to manipulate and search the group list         */
864 /*                                                                  */
865 /* **************************************************************** */
866
867 static int ngroups, maxgroups;
868
869 /* The set of groups that this user is a member of. */
870 static GETGROUPS_T *group_array = (GETGROUPS_T *)NULL;
871
872 #if !defined (NOGROUP)
873 #  define NOGROUP (gid_t) -1
874 #endif
875
876 static void
877 initialize_group_array ()
878 {
879   register int i;
880
881   if (maxgroups == 0)
882     maxgroups = getmaxgroups ();
883
884   ngroups = 0;
885   group_array = (GETGROUPS_T *)xrealloc (group_array, maxgroups * sizeof (GETGROUPS_T));
886
887 #if defined (HAVE_GETGROUPS)
888   ngroups = getgroups (maxgroups, group_array);
889 #endif
890
891   /* If getgroups returns nothing, or the OS does not support getgroups(),
892      make sure the groups array includes at least the current gid. */
893   if (ngroups == 0)
894     {
895       group_array[0] = current_user.gid;
896       ngroups = 1;
897     }
898
899   /* If the primary group is not in the groups array, add it as group_array[0]
900      and shuffle everything else up 1, if there's room. */
901   for (i = 0; i < ngroups; i++)
902     if (current_user.gid == (gid_t)group_array[i])
903       break;
904   if (i == ngroups && ngroups < maxgroups)
905     {
906       for (i = ngroups; i > 0; i--)
907         group_array[i] = group_array[i - 1];
908       group_array[0] = current_user.gid;
909       ngroups++;
910     }
911
912   /* If the primary group is not group_array[0], swap group_array[0] and
913      whatever the current group is.  The vast majority of systems should
914      not need this; a notable exception is Linux. */
915   if (group_array[0] != current_user.gid)
916     {
917       for (i = 0; i < ngroups; i++)
918         if (group_array[i] == current_user.gid)
919           break;
920       if (i < ngroups)
921         {
922           group_array[i] = group_array[0];
923           group_array[0] = current_user.gid;
924         }
925     }
926 }
927
928 /* Return non-zero if GID is one that we have in our groups list. */
929 int
930 #if defined (__STDC__) || defined ( _MINIX)
931 group_member (gid_t gid)
932 #else
933 group_member (gid)
934      gid_t gid;
935 #endif /* !__STDC__ && !_MINIX */
936 {
937 #if defined (HAVE_GETGROUPS)
938   register int i;
939 #endif
940
941   /* Short-circuit if possible, maybe saving a call to getgroups(). */
942   if (gid == current_user.gid || gid == current_user.egid)
943     return (1);
944
945 #if defined (HAVE_GETGROUPS)
946   if (ngroups == 0)
947     initialize_group_array ();
948
949   /* In case of error, the user loses. */
950   if (ngroups <= 0)
951     return (0);
952
953   /* Search through the list looking for GID. */
954   for (i = 0; i < ngroups; i++)
955     if (gid == (gid_t)group_array[i])
956       return (1);
957 #endif
958
959   return (0);
960 }
961
962 char **
963 get_group_list (ngp)
964      int *ngp;
965 {
966   static char **group_vector = (char **)NULL;
967   register int i;
968
969   if (group_vector)
970     {
971       if (ngp)
972         *ngp = ngroups;
973       return group_vector;
974     }
975
976   if (ngroups == 0)
977     initialize_group_array ();
978
979   if (ngroups <= 0)
980     {
981       if (ngp)
982         *ngp = 0;
983       return (char **)NULL;
984     }
985
986   group_vector = strvec_create (ngroups);
987   for (i = 0; i < ngroups; i++)
988     group_vector[i] = itos (group_array[i]);
989
990   if (ngp)
991     *ngp = ngroups;
992   return group_vector;
993 }
994
995 int *
996 get_group_array (ngp)
997      int *ngp;
998 {
999   int i;
1000   static int *group_iarray = (int *)NULL;
1001
1002   if (group_iarray)
1003     {
1004       if (ngp)
1005         *ngp = ngroups;
1006       return (group_iarray);
1007     }
1008
1009   if (ngroups == 0)
1010     initialize_group_array ();    
1011
1012   if (ngroups <= 0)
1013     {
1014       if (ngp)
1015         *ngp = 0;
1016       return (int *)NULL;
1017     }
1018
1019   group_iarray = (int *)xmalloc (ngroups * sizeof (int));
1020   for (i = 0; i < ngroups; i++)
1021     group_iarray[i] = (int)group_array[i];
1022
1023   if (ngp)
1024     *ngp = ngroups;
1025   return group_iarray;
1026 }