1/* shell.c -- GNU's idea of the POSIX shell specification. */
2
3/* Copyright (C) 1987-2005 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
8   under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 2, or (at your option)
10   any later version.
11
12   Bash is distributed in the hope that it will be useful, but WITHOUT
13   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15   License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with Bash; see the file COPYING.  If not, write to the Free
19   Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
20
21  Birthdate:
22  Sunday, January 10th, 1988.
23  Initial author: Brian Fox
24*/
25#define INSTALL_DEBUG_MODE
26
27#include "config.h"
28
29#include "bashtypes.h"
30#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)
31#  include <sys/file.h>
32#endif
33#include "posixstat.h"
34#include "posixtime.h"
35#include "bashansi.h"
36#include <stdio.h>
37#include <signal.h>
38#include <errno.h>
39#include "filecntl.h"
40#include <pwd.h>
41
42#if defined (HAVE_UNISTD_H)
43#  include <unistd.h>
44#endif
45
46#if defined(__APPLE__)
47#include <get_compat.h>
48#endif /* __APPLE__ */
49
50#include "bashintl.h"
51
52#define NEED_SH_SETLINEBUF_DECL		/* used in externs.h */
53
54#include "shell.h"
55#include "flags.h"
56#include "trap.h"
57#include "mailcheck.h"
58#include "builtins.h"
59#include "builtins/common.h"
60
61#if defined (JOB_CONTROL)
62#include "jobs.h"
63#endif /* JOB_CONTROL */
64
65#include "input.h"
66#include "execute_cmd.h"
67#include "findcmd.h"
68
69#if defined (USING_BASH_MALLOC) && defined (DEBUG) && !defined (DISABLE_MALLOC_WRAPPERS)
70#  include <malloc/shmalloc.h>
71#endif
72
73#if defined (HISTORY)
74#  include "bashhist.h"
75#  include <readline/history.h>
76#endif
77
78#include <tilde/tilde.h>
79#include <glob/strmatch.h>
80
81#if defined (__OPENNT)
82#  include <opennt/opennt.h>
83#endif
84
85#if !defined (HAVE_GETPW_DECLS)
86extern struct passwd *getpwuid ();
87#endif /* !HAVE_GETPW_DECLS */
88
89#if !defined (errno)
90extern int errno;
91#endif
92
93#if defined (NO_MAIN_ENV_ARG)
94extern char **environ;	/* used if no third argument to main() */
95#endif
96
97extern char *dist_version, *release_status;
98extern int patch_level, build_version;
99extern int shell_level;
100extern int subshell_environment;
101extern int last_command_exit_value;
102extern int line_number;
103extern int expand_aliases;
104extern int array_needs_making;
105extern int gnu_error_format;
106extern char *primary_prompt, *secondary_prompt;
107extern char *this_command_name;
108
109/* Non-zero means that this shell has already been run; i.e. you should
110   call shell_reinitialize () if you need to start afresh. */
111int shell_initialized = 0;
112
113COMMAND *global_command = (COMMAND *)NULL;
114
115/* Information about the current user. */
116struct user_info current_user =
117{
118  (uid_t)-1, (uid_t)-1, (gid_t)-1, (gid_t)-1,
119  (char *)NULL, (char *)NULL, (char *)NULL
120};
121
122/* The current host's name. */
123char *current_host_name = (char *)NULL;
124
125/* Non-zero means that this shell is a login shell.
126   Specifically:
127   0 = not login shell.
128   1 = login shell from getty (or equivalent fake out)
129  -1 = login shell from "--login" (or -l) flag.
130  -2 = both from getty, and from flag.
131 */
132int login_shell = 0;
133
134/* Non-zero means that at this moment, the shell is interactive.  In
135   general, this means that the shell is at this moment reading input
136   from the keyboard. */
137int interactive = 0;
138
139/* Non-zero means that the shell was started as an interactive shell. */
140int interactive_shell = 0;
141
142/* Non-zero means to send a SIGHUP to all jobs when an interactive login
143   shell exits. */
144int hup_on_exit = 0;
145
146/* Tells what state the shell was in when it started:
147	0 = non-interactive shell script
148	1 = interactive
149	2 = -c command
150	3 = wordexp evaluation
151   This is a superset of the information provided by interactive_shell.
152*/
153int startup_state = 0;
154
155/* Special debugging helper. */
156int debugging_login_shell = 0;
157
158/* The environment that the shell passes to other commands. */
159char **shell_environment;
160
161/* Non-zero when we are executing a top-level command. */
162int executing = 0;
163
164/* The number of commands executed so far. */
165int current_command_number = 1;
166
167/* Non-zero is the recursion depth for commands. */
168int indirection_level = 0;
169
170/* The name of this shell, as taken from argv[0]. */
171char *shell_name = (char *)NULL;
172
173/* time in seconds when the shell was started */
174time_t shell_start_time;
175
176/* Are we running in an emacs shell window? */
177int running_under_emacs;
178
179/* The name of the .(shell)rc file. */
180static char *bashrc_file = "~/.bashrc";
181
182/* Non-zero means to act more like the Bourne shell on startup. */
183static int act_like_sh;
184
185/* Non-zero if this shell is being run by `su'. */
186static int su_shell;
187
188/* Non-zero if we have already expanded and sourced $ENV. */
189static int sourced_env;
190
191/* Is this shell running setuid? */
192static int running_setuid;
193
194/* Values for the long-winded argument names. */
195static int debugging;			/* Do debugging things. */
196static int no_rc;			/* Don't execute ~/.bashrc */
197static int no_profile;			/* Don't execute .profile */
198static int do_version;			/* Display interesting version info. */
199static int make_login_shell;		/* Make this shell be a `-bash' shell. */
200static int want_initial_help;		/* --help option */
201
202int debugging_mode = 0;		/* In debugging mode with --debugger */
203int no_line_editing = 0;	/* Don't do fancy line editing. */
204int dump_translatable_strings;	/* Dump strings in $"...", don't execute. */
205int dump_po_strings;		/* Dump strings in $"..." in po format */
206int wordexp_only = 0;		/* Do word expansion only */
207int protected_mode = 0;		/* No command substitution with --wordexp */
208
209#if defined (STRICT_POSIX)
210int posixly_correct = 1;	/* Non-zero means posix.2 superset. */
211#else
212int posixly_correct = 0;	/* Non-zero means posix.2 superset. */
213#endif
214
215
216/* Some long-winded argument names.  These are obviously new. */
217#define Int 1
218#define Charp 2
219struct {
220  char *name;
221  int type;
222  int *int_value;
223  char **char_value;
224} long_args[] = {
225  { "debug", Int, &debugging, (char **)0x0 },
226#if defined (DEBUGGER)
227  { "debugger", Int, &debugging_mode, (char **)0x0 },
228#endif
229  { "dump-po-strings", Int, &dump_po_strings, (char **)0x0 },
230  { "dump-strings", Int, &dump_translatable_strings, (char **)0x0 },
231  { "help", Int, &want_initial_help, (char **)0x0 },
232  { "init-file", Charp, (int *)0x0, &bashrc_file },
233  { "login", Int, &make_login_shell, (char **)0x0 },
234  { "noediting", Int, &no_line_editing, (char **)0x0 },
235  { "noprofile", Int, &no_profile, (char **)0x0 },
236  { "norc", Int, &no_rc, (char **)0x0 },
237  { "posix", Int, &posixly_correct, (char **)0x0 },
238  { "protected", Int, &protected_mode, (char **)0x0 },
239  { "rcfile", Charp, (int *)0x0, &bashrc_file },
240#if defined (RESTRICTED_SHELL)
241  { "restricted", Int, &restricted, (char **)0x0 },
242#endif
243  { "verbose", Int, &echo_input_at_read, (char **)0x0 },
244  { "version", Int, &do_version, (char **)0x0 },
245  { "wordexp", Int, &wordexp_only, (char **)0x0 },
246  { (char *)0x0, Int, (int *)0x0, (char **)0x0 }
247};
248
249/* These are extern so execute_simple_command can set them, and then
250   longjmp back to main to execute a shell script, instead of calling
251   main () again and resulting in indefinite, possibly fatal, stack
252   growth. */
253procenv_t subshell_top_level;
254int subshell_argc;
255char **subshell_argv;
256char **subshell_envp;
257
258#if defined (BUFFERED_INPUT)
259/* The file descriptor from which the shell is reading input. */
260int default_buffered_input = -1;
261#endif
262
263/* The following two variables are not static so they can show up in $-. */
264int read_from_stdin;		/* -s flag supplied */
265int want_pending_command;	/* -c flag supplied */
266
267/* This variable is not static so it can be bound to $BASH_EXECUTION_STRING */
268char *command_execution_string;	/* argument to -c option */
269
270int malloc_trace_at_exit = 0;
271
272static int shell_reinitialized = 0;
273
274static FILE *default_input;
275
276static STRING_INT_ALIST *shopt_alist;
277static int shopt_ind = 0, shopt_len = 0;
278
279static int parse_long_options __P((char **, int, int));
280static int parse_shell_options __P((char **, int, int));
281static int bind_args __P((char **, int, int, int));
282
283static void start_debugger __P((void));
284
285static void add_shopt_to_alist __P((char *, int));
286static void run_shopt_alist __P((void));
287
288static void execute_env_file __P((char *));
289static void run_startup_files __P((void));
290static int open_shell_script __P((char *));
291static void set_bash_input __P((void));
292static int run_one_command __P((char *));
293static int run_wordexp __P((char *));
294
295static int uidget __P((void));
296
297static void init_interactive __P((void));
298static void init_noninteractive __P((void));
299
300static void set_shell_name __P((char *));
301static void shell_initialize __P((void));
302static void shell_reinitialize __P((void));
303
304static void show_shell_usage __P((FILE *, int));
305
306#ifdef __CYGWIN__
307static void
308_cygwin32_check_tmp ()
309{
310  struct stat sb;
311
312  if (stat ("/tmp", &sb) < 0)
313    internal_warning (_("could not find /tmp, please create!"));
314  else
315    {
316      if (S_ISDIR (sb.st_mode) == 0)
317	internal_warning (_("/tmp must be a valid directory name"));
318    }
319}
320#endif /* __CYGWIN__ */
321
322#ifdef __APPLE__
323static int tiger_mode = 0;
324#endif	/* __APPLE__ */
325#if defined (NO_MAIN_ENV_ARG)
326/* systems without third argument to main() */
327int
328main (argc, argv)
329     int argc;
330     char **argv;
331#else /* !NO_MAIN_ENV_ARG */
332int
333main (argc, argv, env)
334     int argc;
335     char **argv, **env;
336#endif /* !NO_MAIN_ENV_ARG */
337{
338  register int i;
339  int code, old_errexit_flag;
340#if defined (RESTRICTED_SHELL)
341  int saverst;
342#endif
343  volatile int locally_skip_execution;
344  volatile int arg_index, top_level_arg_index;
345#ifdef __OPENNT
346  char **env;
347
348  env = environ;
349#endif /* __OPENNT */
350
351  USE_VAR(argc);
352  USE_VAR(argv);
353  USE_VAR(env);
354  USE_VAR(code);
355  USE_VAR(old_errexit_flag);
356#if defined (RESTRICTED_SHELL)
357  USE_VAR(saverst);
358#endif
359
360  /* Catch early SIGINTs. */
361  code = setjmp (top_level);
362  if (code)
363    exit (2);
364#if defined(__APPLE__)
365  if (!COMPAT_MODE("bin/sh", "Unix2003")) {
366#if defined(STRICT_POSIX)
367    execv("/bin/bash", argv);
368    exit (2);
369#else	/* !STRICT_POSIX */
370    tiger_mode = 1;	/* act like Tiger wrt setuid and #!/bin/sh */
371#endif	/* STRICT_POSIX */
372  }
373#endif /* __APPLE__ */
374#if defined (USING_BASH_MALLOC) && defined (DEBUG) && !defined (DISABLE_MALLOC_WRAPPERS)
375#  if 1
376  malloc_set_register (1);
377#  endif
378#endif
379
380  check_dev_tty ();
381
382#ifdef __CYGWIN__
383  _cygwin32_check_tmp ();
384#endif /* __CYGWIN__ */
385
386  /* Wait forever if we are debugging a login shell. */
387  while (debugging_login_shell) sleep (3);
388
389  set_default_locale ();
390
391  running_setuid = uidget ();
392
393  if (getenv ("POSIXLY_CORRECT") || getenv ("POSIX_PEDANTIC"))
394    posixly_correct = 1;
395
396#if defined (USE_GNU_MALLOC_LIBRARY)
397  mcheck (programming_error, (void (*) ())0);
398#endif /* USE_GNU_MALLOC_LIBRARY */
399
400  if (setjmp (subshell_top_level))
401    {
402      argc = subshell_argc;
403      argv = subshell_argv;
404      env = subshell_envp;
405      sourced_env = 0;
406    }
407
408  shell_reinitialized = 0;
409
410  /* Initialize `local' variables for all `invocations' of main (). */
411  arg_index = 1;
412  if (arg_index > argc)
413    arg_index = argc;
414  command_execution_string = (char *)NULL;
415  want_pending_command = locally_skip_execution = read_from_stdin = 0;
416  default_input = stdin;
417#if defined (BUFFERED_INPUT)
418  default_buffered_input = -1;
419#endif
420
421  /* Fix for the `infinite process creation' bug when running shell scripts
422     from startup files on System V. */
423  login_shell = make_login_shell = 0;
424
425  /* If this shell has already been run, then reinitialize it to a
426     vanilla state. */
427  if (shell_initialized || shell_name)
428    {
429      /* Make sure that we do not infinitely recurse as a login shell. */
430      if (*shell_name == '-')
431	shell_name++;
432
433      shell_reinitialize ();
434      if (setjmp (top_level))
435	exit (2);
436    }
437
438  shell_environment = env;
439  set_shell_name (argv[0]);
440  shell_start_time = NOW;	/* NOW now defined in general.h */
441
442  /* Parse argument flags from the input line. */
443
444  /* Find full word arguments first. */
445  arg_index = parse_long_options (argv, arg_index, argc);
446
447  if (want_initial_help)
448    {
449      show_shell_usage (stdout, 1);
450      exit (EXECUTION_SUCCESS);
451    }
452
453  if (do_version)
454    {
455      show_shell_version (1);
456      exit (EXECUTION_SUCCESS);
457    }
458
459  /* All done with full word options; do standard shell option parsing.*/
460  this_command_name = shell_name;	/* for error reporting */
461  arg_index = parse_shell_options (argv, arg_index, argc);
462
463  /* If user supplied the "--login" (or -l) flag, then set and invert
464     LOGIN_SHELL. */
465  if (make_login_shell)
466    {
467      login_shell++;
468      login_shell = -login_shell;
469    }
470
471  set_login_shell (login_shell != 0);
472
473  if (dump_po_strings)
474    dump_translatable_strings = 1;
475
476  if (dump_translatable_strings)
477    read_but_dont_execute = 1;
478#ifdef __APPLE__
479  if (privileged_mode == 0 && act_like_sh)
480    privileged_mode = (getenv("_BASH_IMPLICIT_DASH_PEE") != NULL);
481  if (running_setuid && privileged_mode == 0 && (tiger_mode ? (act_like_sh == 0) : 1))
482    disable_priv_mode ();
483  else if (running_setuid && privileged_mode != 0) {
484    uid_t euid = geteuid();
485    uid_t ruid = getuid();
486    if (-1 == setuid(euid))
487      internal_error( _("setuid(%u) failed: %s"), euid, strerror(errno));
488    if (-1 == setreuid(ruid, euid))
489      internal_error( _("setreuid(%u,%u) failed: %s"), ruid, euid, strerror(errno));
490  }
491#else  /* !__APPLE__ */
492  if (running_setuid && privileged_mode == 0)
493    disable_priv_mode ();
494#endif	/* __APPLE__ */
495  /* Need to get the argument to a -c option processed in the
496     above loop.  The next arg is a command to execute, and the
497     following args are $0...$n respectively. */
498  if (want_pending_command)
499    {
500      command_execution_string = argv[arg_index];
501      if (command_execution_string == 0)
502	{
503	  report_error (_("%s: option requires an argument"), "-c");
504	  exit (EX_BADUSAGE);
505	}
506      arg_index++;
507    }
508  this_command_name = (char *)NULL;
509
510  cmd_init();		/* initialize the command object caches */
511
512  /* First, let the outside world know about our interactive status.
513     A shell is interactive if the `-i' flag was given, or if all of
514     the following conditions are met:
515	no -c command
516	no arguments remaining or the -s flag given
517	standard input is a terminal
518	standard error is a terminal
519     Refer to Posix.2, the description of the `sh' utility. */
520
521  if (forced_interactive ||		/* -i flag */
522      (!command_execution_string &&	/* No -c command and ... */
523       wordexp_only == 0 &&		/* No --wordexp and ... */
524       ((arg_index == argc) ||		/*   no remaining args or... */
525	read_from_stdin) &&		/*   -s flag with args, and */
526       isatty (fileno (stdin)) &&	/* Input is a terminal and */
527       isatty (fileno (stderr))))	/* error output is a terminal. */
528    init_interactive ();
529  else
530    init_noninteractive ();
531
532#define CLOSE_FDS_AT_LOGIN
533#if defined (CLOSE_FDS_AT_LOGIN)
534  /*
535   * Some systems have the bad habit of starting login shells with lots of open
536   * file descriptors.  For instance, most systems that have picked up the
537   * pre-4.0 Sun YP code leave a file descriptor open each time you call one
538   * of the getpw* functions, and it's set to be open across execs.  That
539   * means one for login, one for xterm, one for shelltool, etc.
540   */
541  if (login_shell && interactive_shell)
542    {
543      for (i = 3; i < 20; i++)
544	close (i);
545    }
546#endif /* CLOSE_FDS_AT_LOGIN */
547
548  /* If we're in a strict Posix.2 mode, turn on interactive comments,
549     alias expansion in non-interactive shells, and other Posix.2 things. */
550  if (posixly_correct)
551    {
552      bind_variable ("POSIXLY_CORRECT", "y", 0);
553      sv_strict_posix ("POSIXLY_CORRECT");
554    }
555
556  /* Now we run the shopt_alist and process the options. */
557  if (shopt_alist)
558    run_shopt_alist ();
559
560  /* From here on in, the shell must be a normal functioning shell.
561     Variables from the environment are expected to be set, etc. */
562  shell_initialize ();
563
564  set_default_lang ();
565  set_default_locale_vars ();
566
567  if (interactive_shell)
568    {
569      char *term, *emacs;
570
571      term = get_string_value ("TERM");
572      no_line_editing |= term && (STREQ (term, "emacs"));
573      emacs = get_string_value ("EMACS");
574      running_under_emacs = emacs ? ((strstr (emacs, "term") != 0) ? 2 : 1) : 0;
575#if 0
576      no_line_editing |= emacs && emacs[0] == 't' && emacs[1] == '\0';
577#else
578      no_line_editing |= emacs && emacs[0] == 't' && emacs[1] == '\0' && STREQ (term, "dumb");
579#endif
580      if (running_under_emacs)
581	gnu_error_format = 1;
582    }
583
584  top_level_arg_index = arg_index;
585  old_errexit_flag = exit_immediately_on_error;
586
587  /* Give this shell a place to longjmp to before executing the
588     startup files.  This allows users to press C-c to abort the
589     lengthy startup. */
590  code = setjmp (top_level);
591  if (code)
592    {
593      if (code == EXITPROG || code == ERREXIT)
594	exit_shell (last_command_exit_value);
595      else
596	{
597#if defined (JOB_CONTROL)
598	  /* Reset job control, since run_startup_files turned it off. */
599	  set_job_control (interactive_shell);
600#endif
601	  /* Reset value of `set -e', since it's turned off before running
602	     the startup files. */
603	  exit_immediately_on_error += old_errexit_flag;
604	  locally_skip_execution++;
605	}
606    }
607
608  arg_index = top_level_arg_index;
609
610  /* Execute the start-up scripts. */
611
612  if (interactive_shell == 0)
613    {
614      unbind_variable ("PS1");
615      unbind_variable ("PS2");
616      interactive = 0;
617#if 0
618      /* This has already been done by init_noninteractive */
619      expand_aliases = posixly_correct;
620#endif
621    }
622  else
623    {
624      change_flag ('i', FLAG_ON);
625      interactive = 1;
626    }
627
628#if defined (RESTRICTED_SHELL)
629  /* Set restricted_shell based on whether the basename of $0 indicates that
630     the shell should be restricted or if the `-r' option was supplied at
631     startup. */
632  restricted_shell = shell_is_restricted (shell_name);
633
634  /* If the `-r' option is supplied at invocation, make sure that the shell
635     is not in restricted mode when running the startup files. */
636  saverst = restricted;
637  restricted = 0;
638#endif
639
640  /* The startup files are run with `set -e' temporarily disabled. */
641  if (locally_skip_execution == 0 && running_setuid == 0)
642    {
643      old_errexit_flag = exit_immediately_on_error;
644      exit_immediately_on_error = 0;
645
646      run_startup_files ();
647      exit_immediately_on_error += old_errexit_flag;
648    }
649
650  /* If we are invoked as `sh', turn on Posix mode. */
651  if (act_like_sh)
652    {
653      bind_variable ("POSIXLY_CORRECT", "y", 0);
654      sv_strict_posix ("POSIXLY_CORRECT");
655    }
656
657#if defined (RESTRICTED_SHELL)
658  /* Turn on the restrictions after executing the startup files.  This
659     means that `bash -r' or `set -r' invoked from a startup file will
660     turn on the restrictions after the startup files are executed. */
661  restricted = saverst || restricted;
662  if (shell_reinitialized == 0)
663    maybe_make_restricted (shell_name);
664#endif /* RESTRICTED_SHELL */
665
666  if (wordexp_only)
667    {
668      startup_state = 3;
669      last_command_exit_value = run_wordexp (argv[arg_index]);
670      exit_shell (last_command_exit_value);
671    }
672
673  if (command_execution_string)
674    {
675      arg_index = bind_args (argv, arg_index, argc, 0);
676      startup_state = 2;
677
678      if (debugging_mode)
679	start_debugger ();
680
681#if defined (ONESHOT)
682      executing = 1;
683      run_one_command (command_execution_string);
684      exit_shell (last_command_exit_value);
685#else /* ONESHOT */
686      with_input_from_string (command_execution_string, "-c");
687      goto read_and_execute;
688#endif /* !ONESHOT */
689    }
690
691  /* Get possible input filename and set up default_buffered_input or
692     default_input as appropriate. */
693  if (arg_index != argc && read_from_stdin == 0)
694    {
695      open_shell_script (argv[arg_index]);
696      arg_index++;
697    }
698  else if (interactive == 0)
699    /* In this mode, bash is reading a script from stdin, which is a
700       pipe or redirected file. */
701#if defined (BUFFERED_INPUT)
702    default_buffered_input = fileno (stdin);	/* == 0 */
703#else
704    setbuf (default_input, (char *)NULL);
705#endif /* !BUFFERED_INPUT */
706
707  set_bash_input ();
708
709  /* Bind remaining args to $1 ... $n */
710  arg_index = bind_args (argv, arg_index, argc, 1);
711
712  if (debugging_mode && locally_skip_execution == 0 && running_setuid == 0)
713    start_debugger ();
714
715  /* Do the things that should be done only for interactive shells. */
716  if (interactive_shell)
717    {
718      /* Set up for checking for presence of mail. */
719      remember_mail_dates ();
720      reset_mail_timer ();
721
722#if defined (HISTORY)
723      /* Initialize the interactive history stuff. */
724      bash_initialize_history ();
725      /* Don't load the history from the history file if we've already
726	 saved some lines in this session (e.g., by putting `history -s xx'
727	 into one of the startup files). */
728      if (shell_initialized == 0 && history_lines_this_session == 0)
729	load_history ();
730#endif /* HISTORY */
731
732      /* Initialize terminal state for interactive shells after the
733	 .bash_profile and .bashrc are interpreted. */
734      get_tty_state ();
735    }
736
737#if !defined (ONESHOT)
738 read_and_execute:
739#endif /* !ONESHOT */
740
741  shell_initialized = 1;
742
743  /* Read commands until exit condition. */
744  reader_loop ();
745  exit_shell (last_command_exit_value);
746}
747
748static int
749parse_long_options (argv, arg_start, arg_end)
750     char **argv;
751     int arg_start, arg_end;
752{
753  int arg_index, longarg, i;
754  char *arg_string;
755
756  arg_index = arg_start;
757  while ((arg_index != arg_end) && (arg_string = argv[arg_index]) &&
758	 (*arg_string == '-'))
759    {
760      longarg = 0;
761
762      /* Make --login equivalent to -login. */
763      if (arg_string[1] == '-' && arg_string[2])
764	{
765	  longarg = 1;
766	  arg_string++;
767	}
768
769      for (i = 0; long_args[i].name; i++)
770	{
771	  if (STREQ (arg_string + 1, long_args[i].name))
772	    {
773	      if (long_args[i].type == Int)
774		*long_args[i].int_value = 1;
775	      else if (argv[++arg_index] == 0)
776		{
777		  report_error (_("%s: option requires an argument"), long_args[i].name);
778		  exit (EX_BADUSAGE);
779		}
780	      else
781		*long_args[i].char_value = argv[arg_index];
782
783	      break;
784	    }
785	}
786      if (long_args[i].name == 0)
787	{
788	  if (longarg)
789	    {
790	      report_error (_("%s: invalid option"), argv[arg_index]);
791	      show_shell_usage (stderr, 0);
792	      exit (EX_BADUSAGE);
793	    }
794	  break;		/* No such argument.  Maybe flag arg. */
795	}
796
797      arg_index++;
798    }
799
800  return (arg_index);
801}
802
803static int
804parse_shell_options (argv, arg_start, arg_end)
805     char **argv;
806     int arg_start, arg_end;
807{
808  int arg_index;
809  int arg_character, on_or_off, next_arg, i;
810  char *o_option, *arg_string;
811
812  arg_index = arg_start;
813  while (arg_index != arg_end && (arg_string = argv[arg_index]) &&
814	 (*arg_string == '-' || *arg_string == '+'))
815    {
816      /* There are flag arguments, so parse them. */
817      next_arg = arg_index + 1;
818
819      /* A single `-' signals the end of options.  From the 4.3 BSD sh.
820	 An option `--' means the same thing; this is the standard
821	 getopt(3) meaning. */
822      if (arg_string[0] == '-' &&
823	   (arg_string[1] == '\0' ||
824	     (arg_string[1] == '-' && arg_string[2] == '\0')))
825	return (next_arg);
826
827      i = 1;
828      on_or_off = arg_string[0];
829      while (arg_character = arg_string[i++])
830	{
831	  switch (arg_character)
832	    {
833	    case 'c':
834	      want_pending_command = 1;
835	      break;
836
837	    case 'l':
838	      make_login_shell = 1;
839	      break;
840
841	    case 's':
842	      read_from_stdin = 1;
843	      break;
844
845	    case 'o':
846	      o_option = argv[next_arg];
847	      if (o_option == 0)
848		{
849		  list_minus_o_opts (-1, (on_or_off == '-') ? 0 : 1);
850		  break;
851		}
852	      if (set_minus_o_option (on_or_off, o_option) != EXECUTION_SUCCESS)
853		exit (EX_BADUSAGE);
854	      next_arg++;
855	      break;
856
857	    case 'O':
858	      /* Since some of these can be overridden by the normal
859		 interactive/non-interactive shell initialization or
860		 initializing posix mode, we save the options and process
861		 them after initialization. */
862	      o_option = argv[next_arg];
863	      if (o_option == 0)
864		{
865		  shopt_listopt (o_option, (on_or_off == '-') ? 0 : 1);
866		  break;
867		}
868	      add_shopt_to_alist (o_option, on_or_off);
869	      next_arg++;
870	      break;
871
872	    case 'D':
873	      dump_translatable_strings = 1;
874	      break;
875
876	    default:
877	      if (change_flag (arg_character, on_or_off) == FLAG_ERROR)
878		{
879		  report_error (_("%c%c: invalid option"), on_or_off, arg_character);
880		  show_shell_usage (stderr, 0);
881		  exit (EX_BADUSAGE);
882		}
883	    }
884	}
885      /* Can't do just a simple increment anymore -- what about
886	 "bash -abouo emacs ignoreeof -hP"? */
887      arg_index = next_arg;
888    }
889
890  return (arg_index);
891}
892
893/* Exit the shell with status S. */
894void
895exit_shell (s)
896     int s;
897{
898  /* Do trap[0] if defined.  Allow it to override the exit status
899     passed to us. */
900  if (signal_is_trapped (0))
901    s = run_exit_trap ();
902
903#if defined (PROCESS_SUBSTITUTION)
904  unlink_fifo_list ();
905#endif /* PROCESS_SUBSTITUTION */
906
907#if defined (HISTORY)
908  if (interactive_shell)
909    maybe_save_shell_history ();
910#endif /* HISTORY */
911
912#if defined (JOB_CONTROL)
913  /* If the user has run `shopt -s huponexit', hangup all jobs when we exit
914     an interactive login shell.  ksh does this unconditionally. */
915  if (interactive_shell && login_shell && hup_on_exit)
916    hangup_all_jobs ();
917
918  /* If this shell is interactive, terminate all stopped jobs and
919     restore the original terminal process group.  Don't do this if we're
920     in a subshell and calling exit_shell after, for example, a failed
921     word expansion. */
922  if (subshell_environment == 0)
923    end_job_control ();
924#endif /* JOB_CONTROL */
925
926  /* Always return the exit status of the last command to our parent. */
927  sh_exit (s);
928}
929
930/* A wrapper for exit that (optionally) can do other things, like malloc
931   statistics tracing. */
932void
933sh_exit (s)
934     int s;
935{
936#if defined (MALLOC_DEBUG) && defined (USING_BASH_MALLOC)
937  if (malloc_trace_at_exit)
938    trace_malloc_stats (get_name_for_error (), (char *)NULL);
939#endif
940
941  exit (s);
942}
943
944/* Source the bash startup files.  If POSIXLY_CORRECT is non-zero, we obey
945   the Posix.2 startup file rules:  $ENV is expanded, and if the file it
946   names exists, that file is sourced.  The Posix.2 rules are in effect
947   for interactive shells only. (section 4.56.5.3) */
948
949/* Execute ~/.bashrc for most shells.  Never execute it if
950   ACT_LIKE_SH is set, or if NO_RC is set.
951
952   If the executable file "/usr/gnu/src/bash/foo" contains:
953
954   #!/usr/gnu/bin/bash
955   echo hello
956
957   then:
958
959	 COMMAND	    EXECUTE BASHRC
960	 --------------------------------
961	 bash -c foo		NO
962	 bash foo		NO
963	 foo			NO
964	 rsh machine ls		YES (for rsh, which calls `bash -c')
965	 rsh machine foo	YES (for shell started by rsh) NO (for foo!)
966	 echo ls | bash		NO
967	 login			NO
968	 bash			YES
969*/
970
971static void
972execute_env_file (env_file)
973      char *env_file;
974{
975  char *fn;
976
977  if (env_file && *env_file)
978    {
979      fn = expand_string_unsplit_to_string (env_file, Q_DOUBLE_QUOTES);
980      if (fn && *fn)
981	maybe_execute_file (fn, 1);
982      FREE (fn);
983    }
984}
985
986static void
987run_startup_files ()
988{
989#if defined (JOB_CONTROL)
990  int old_job_control;
991#endif
992  int sourced_login, run_by_ssh;
993
994  /* get the rshd/sshd case out of the way first. */
995  if (interactive_shell == 0 && no_rc == 0 && login_shell == 0 &&
996      act_like_sh == 0 && command_execution_string)
997    {
998#ifdef SSH_SOURCE_BASHRC
999      run_by_ssh = (find_variable ("SSH_CLIENT") != (SHELL_VAR *)0) ||
1000		   (find_variable ("SSH2_CLIENT") != (SHELL_VAR *)0);
1001#else
1002      run_by_ssh = 0;
1003#endif
1004
1005      /* If we were run by sshd or we think we were run by rshd, execute
1006	 ~/.bashrc if we are a top-level shell. */
1007      if ((run_by_ssh || isnetconn (fileno (stdin))) && shell_level < 2)
1008	{
1009#ifdef SYS_BASHRC
1010#  if defined (__OPENNT)
1011	  maybe_execute_file (_prefixInstallPath(SYS_BASHRC, NULL, 0), 1);
1012#  else
1013	  maybe_execute_file (SYS_BASHRC, 1);
1014#  endif
1015#endif
1016	  maybe_execute_file (bashrc_file, 1);
1017	  return;
1018	}
1019    }
1020
1021#if defined (JOB_CONTROL)
1022  /* Startup files should be run without job control enabled. */
1023  old_job_control = interactive_shell ? set_job_control (0) : 0;
1024#endif
1025
1026  sourced_login = 0;
1027
1028  /* A shell begun with the --login (or -l) flag that is not in posix mode
1029     runs the login shell startup files, no matter whether or not it is
1030     interactive.  If NON_INTERACTIVE_LOGIN_SHELLS is defined, run the
1031     startup files if argv[0][0] == '-' as well. */
1032#if defined (NON_INTERACTIVE_LOGIN_SHELLS)
1033  if (login_shell && posixly_correct == 0)
1034#else
1035  if (login_shell < 0 && posixly_correct == 0)
1036#endif
1037    {
1038      /* We don't execute .bashrc for login shells. */
1039      no_rc++;
1040
1041      /* Execute /etc/profile and one of the personal login shell
1042	 initialization files. */
1043      if (no_profile == 0)
1044	{
1045	  maybe_execute_file (SYS_PROFILE, 1);
1046
1047	  if (act_like_sh)	/* sh */
1048	    maybe_execute_file ("~/.profile", 1);
1049	  else if ((maybe_execute_file ("~/.bash_profile", 1) == 0) &&
1050		   (maybe_execute_file ("~/.bash_login", 1) == 0))	/* bash */
1051	    maybe_execute_file ("~/.profile", 1);
1052	}
1053
1054      sourced_login = 1;
1055    }
1056
1057  /* A non-interactive shell not named `sh' and not in posix mode reads and
1058     executes commands from $BASH_ENV.  If `su' starts a shell with `-c cmd'
1059     and `-su' as the name of the shell, we want to read the startup files.
1060     No other non-interactive shells read any startup files. */
1061  if (interactive_shell == 0 && !(su_shell && login_shell))
1062    {
1063      if (posixly_correct == 0 && act_like_sh == 0 && privileged_mode == 0 &&
1064	    sourced_env++ == 0)
1065	execute_env_file (get_string_value ("BASH_ENV"));
1066      return;
1067    }
1068
1069  /* Interactive shell or `-su' shell. */
1070  { int posixly_correct = 0;	/* Solaris 10 sources /etc/profile and
1071				 * $HOME/profile in /usr/xpg4/bin/sh
1072				 * if argv[0][0] == '-' */
1073
1074  if (posixly_correct == 0)		  /* bash, sh */
1075    {
1076      if (login_shell && sourced_login++ == 0)
1077	{
1078	  /* We don't execute .bashrc for login shells. */
1079	  no_rc++;
1080
1081	  /* Execute /etc/profile and one of the personal login shell
1082	     initialization files. */
1083	  if (no_profile == 0)
1084	    {
1085	      maybe_execute_file (SYS_PROFILE, 1);
1086
1087	      if (act_like_sh)	/* sh */
1088		maybe_execute_file ("~/.profile", 1);
1089	      else if ((maybe_execute_file ("~/.bash_profile", 1) == 0) &&
1090		       (maybe_execute_file ("~/.bash_login", 1) == 0))	/* bash */
1091		maybe_execute_file ("~/.profile", 1);
1092	    }
1093	}
1094
1095      /* bash */
1096      if (act_like_sh == 0 && no_rc == 0)
1097	{
1098#ifdef SYS_BASHRC
1099#  if defined (__OPENNT)
1100	  maybe_execute_file (_prefixInstallPath(SYS_BASHRC, NULL, 0), 1);
1101#  else
1102	  maybe_execute_file (SYS_BASHRC, 1);
1103#  endif
1104#endif
1105	  maybe_execute_file (bashrc_file, 1);
1106	}
1107      /* sh */
1108      else if (act_like_sh && privileged_mode == 0 && sourced_env++ == 0)
1109	execute_env_file (get_string_value ("ENV"));
1110    }
1111  else		/* bash --posix, sh --posix */
1112    {
1113      /* bash and sh */
1114      if (interactive_shell && privileged_mode == 0 && sourced_env++ == 0)
1115	execute_env_file (get_string_value ("ENV"));
1116    }
1117  }
1118#if defined (JOB_CONTROL)
1119  set_job_control (old_job_control);
1120#endif
1121}
1122
1123#if defined (RESTRICTED_SHELL)
1124/* Return 1 if the shell should be a restricted one based on NAME or the
1125   value of `restricted'.  Don't actually do anything, just return a
1126   boolean value. */
1127int
1128shell_is_restricted (name)
1129     char *name;
1130{
1131  char *temp;
1132
1133  if (restricted)
1134    return 1;
1135  temp = base_pathname (name);
1136  if (*temp == '-')
1137    temp++;
1138  return (STREQ (temp, RESTRICTED_SHELL_NAME));
1139}
1140
1141/* Perhaps make this shell a `restricted' one, based on NAME.  If the
1142   basename of NAME is "rbash", then this shell is restricted.  The
1143   name of the restricted shell is a configurable option, see config.h.
1144   In a restricted shell, PATH, SHELL, ENV, and BASH_ENV are read-only
1145   and non-unsettable.
1146   Do this also if `restricted' is already set to 1; maybe the shell was
1147   started with -r. */
1148int
1149maybe_make_restricted (name)
1150     char *name;
1151{
1152  char *temp;
1153
1154  temp = base_pathname (name);
1155  if (*temp == '-')
1156    temp++;
1157  if (restricted || (STREQ (temp, RESTRICTED_SHELL_NAME)))
1158    {
1159      set_var_read_only ("PATH");
1160      set_var_read_only ("SHELL");
1161      set_var_read_only ("ENV");
1162      set_var_read_only ("BASH_ENV");
1163      restricted = 1;
1164    }
1165  return (restricted);
1166}
1167#endif /* RESTRICTED_SHELL */
1168
1169/* Fetch the current set of uids and gids and return 1 if we're running
1170   setuid or setgid. */
1171static int
1172uidget ()
1173{
1174  uid_t u;
1175
1176  u = getuid ();
1177  if (current_user.uid != u)
1178    {
1179      FREE (current_user.user_name);
1180      FREE (current_user.shell);
1181      FREE (current_user.home_dir);
1182      current_user.user_name = current_user.shell = current_user.home_dir = (char *)NULL;
1183    }
1184  current_user.uid = u;
1185  current_user.gid = getgid ();
1186  current_user.euid = geteuid ();
1187  current_user.egid = getegid ();
1188
1189  /* See whether or not we are running setuid or setgid. */
1190  return (current_user.uid != current_user.euid) ||
1191	   (current_user.gid != current_user.egid);
1192}
1193
1194void
1195disable_priv_mode ()
1196{
1197  setuid (current_user.uid);
1198  setgid (current_user.gid);
1199  current_user.euid = current_user.uid;
1200  current_user.egid = current_user.gid;
1201}
1202
1203static int
1204run_wordexp (words)
1205     char *words;
1206{
1207  int code, nw, nb;
1208  WORD_LIST *wl, *tl, *result;
1209
1210  code = setjmp (top_level);
1211
1212  if (code != NOT_JUMPED)
1213    {
1214      switch (code)
1215	{
1216	  /* Some kind of throw to top_level has occured. */
1217	case FORCE_EOF:
1218	  return last_command_exit_value = 127;
1219	case ERREXIT:
1220	case EXITPROG:
1221	  return last_command_exit_value;
1222	case DISCARD:
1223	  return last_command_exit_value = 1;
1224	default:
1225	  command_error ("run_wordexp", CMDERR_BADJUMP, code, 0);
1226	}
1227    }
1228
1229  /* Run it through the parser to get a list of words and expand them */
1230  if (words && *words)
1231    {
1232      with_input_from_string (words, "--wordexp");
1233      if (parse_command () != 0)
1234	return (126);
1235      if (global_command == 0)
1236	{
1237	  printf ("0\n0\n");
1238	  return (0);
1239	}
1240      if (global_command->type != cm_simple)
1241	return (126);
1242      wl = global_command->value.Simple->words;
1243      if (protected_mode)
1244	for (tl = wl; tl; tl = tl->next)
1245	  tl->word->flags |= W_NOCOMSUB|W_NOPROCSUB;
1246      result = wl ? expand_words_no_vars (wl) : (WORD_LIST *)0;
1247    }
1248  else
1249    result = (WORD_LIST *)0;
1250
1251  last_command_exit_value = 0;
1252
1253  if (result == 0)
1254    {
1255      printf ("0\n0\n");
1256      return (0);
1257    }
1258
1259  /* Count up the number of words and bytes, and print them.  Don't count
1260     the trailing NUL byte. */
1261  for (nw = nb = 0, wl = result; wl; wl = wl->next)
1262    {
1263      nw++;
1264      nb += strlen (wl->word->word);
1265    }
1266  printf ("%u\n%u\n", nw, nb);
1267  /* Print each word on a separate line.  This will have to be changed when
1268     the interface to glibc is completed. */
1269  for (wl = result; wl; wl = wl->next)
1270    printf ("%s\n", wl->word->word);
1271
1272  return (0);
1273}
1274
1275#if defined (ONESHOT)
1276/* Run one command, given as the argument to the -c option.  Tell
1277   parse_and_execute not to fork for a simple command. */
1278static int
1279run_one_command (command)
1280     char *command;
1281{
1282  int code;
1283
1284  code = setjmp (top_level);
1285
1286  if (code != NOT_JUMPED)
1287    {
1288#if defined (PROCESS_SUBSTITUTION)
1289      unlink_fifo_list ();
1290#endif /* PROCESS_SUBSTITUTION */
1291      switch (code)
1292	{
1293	  /* Some kind of throw to top_level has occured. */
1294	case FORCE_EOF:
1295	  return last_command_exit_value = 127;
1296	case ERREXIT:
1297	case EXITPROG:
1298	  return last_command_exit_value;
1299	case DISCARD:
1300	  return last_command_exit_value = 1;
1301	default:
1302	  command_error ("run_one_command", CMDERR_BADJUMP, code, 0);
1303	}
1304    }
1305   return (parse_and_execute (savestring (command), "-c", SEVAL_NOHIST));
1306}
1307#endif /* ONESHOT */
1308
1309static int
1310bind_args (argv, arg_start, arg_end, start_index)
1311     char **argv;
1312     int arg_start, arg_end, start_index;
1313{
1314  register int i;
1315  WORD_LIST *args;
1316
1317  for (i = arg_start, args = (WORD_LIST *)NULL; i < arg_end; i++)
1318    args = make_word_list (make_word (argv[i]), args);
1319  if (args)
1320    {
1321      args = REVERSE_LIST (args, WORD_LIST *);
1322      if (start_index == 0)	/* bind to $0...$n for sh -c command */
1323	{
1324	  /* Posix.2 4.56.3 says that the first argument after sh -c command
1325	     becomes $0, and the rest of the arguments become $1...$n */
1326	  shell_name = savestring (args->word->word);
1327	  FREE (dollar_vars[0]);
1328	  dollar_vars[0] = savestring (args->word->word);
1329	  remember_args (args->next, 1);
1330	  push_args (args->next);	/* BASH_ARGV and BASH_ARGC */
1331	}
1332      else			/* bind to $1...$n for shell script */
1333        {
1334	  remember_args (args, 1);
1335	  push_args (args);		/* BASH_ARGV and BASH_ARGC */
1336        }
1337
1338      dispose_words (args);
1339    }
1340
1341  return (i);
1342}
1343
1344void
1345unbind_args ()
1346{
1347  remember_args ((WORD_LIST *)NULL, 1);
1348  pop_args ();				/* Reset BASH_ARGV and BASH_ARGC */
1349}
1350
1351static void
1352start_debugger ()
1353{
1354#if defined (DEBUGGER) && defined (DEBUGGER_START_FILE)
1355  int old_errexit;
1356
1357  old_errexit = exit_immediately_on_error;
1358  exit_immediately_on_error = 0;
1359
1360  maybe_execute_file (DEBUGGER_START_FILE, 1);
1361  function_trace_mode = 1;
1362
1363  exit_immediately_on_error += old_errexit;
1364#endif
1365}
1366
1367static int
1368open_shell_script (script_name)
1369     char *script_name;
1370{
1371  int fd, e, fd_is_tty;
1372  char *filename, *path_filename, *t;
1373  char sample[80];
1374  int sample_len;
1375  struct stat sb;
1376#if defined (ARRAY_VARS)
1377  SHELL_VAR *funcname_v, *bash_source_v, *bash_lineno_v;
1378  ARRAY *funcname_a, *bash_source_a, *bash_lineno_a;
1379#endif
1380
1381  filename = savestring (script_name);
1382
1383  fd = open (filename, O_RDONLY);
1384  if ((fd < 0) && (errno == ENOENT) && (absolute_program (filename) == 0))
1385    {
1386      e = errno;
1387      /* If it's not in the current directory, try looking through PATH
1388	 for it. */
1389      path_filename = find_path_file (script_name);
1390      if (path_filename)
1391	{
1392	  free (filename);
1393	  filename = path_filename;
1394	  fd = open (filename, O_RDONLY);
1395	}
1396      else
1397	errno = e;
1398    }
1399
1400  if (fd < 0)
1401    {
1402      e = errno;
1403      file_error (filename);
1404      exit ((e == ENOENT) ? EX_NOTFOUND : EX_NOINPUT);
1405    }
1406
1407  free (dollar_vars[0]);
1408  dollar_vars[0] = savestring (script_name);
1409
1410#if defined (ARRAY_VARS)
1411  GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a);
1412  GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
1413  GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a);
1414
1415  array_push (bash_source_a, filename);
1416  if (bash_lineno_a)
1417    {
1418      t = itos (executing_line_number ());
1419      array_push (bash_lineno_a, t);
1420      free (t);
1421    }
1422  array_push (funcname_a, "main");
1423#endif
1424
1425#ifdef HAVE_DEV_FD
1426  fd_is_tty = isatty (fd);
1427#else
1428  fd_is_tty = 0;
1429#endif
1430
1431  /* Only do this with non-tty file descriptors we can seek on. */
1432  if (fd_is_tty == 0 && (lseek (fd, 0L, 1) != -1))
1433    {
1434      /* Check to see if the `file' in `bash file' is a binary file
1435	 according to the same tests done by execute_simple_command (),
1436	 and report an error and exit if it is. */
1437      sample_len = read (fd, sample, sizeof (sample));
1438      if (sample_len < 0)
1439	{
1440	  e = errno;
1441	  if ((fstat (fd, &sb) == 0) && S_ISDIR (sb.st_mode))
1442	    internal_error (_("%s: is a directory"), filename);
1443	  else
1444	    {
1445	      errno = e;
1446	      file_error (filename);
1447	    }
1448	  exit (EX_NOEXEC);
1449	}
1450      else if (sample_len > 0 && (check_binary_file (sample, sample_len)))
1451	{
1452	  internal_error ("%s: cannot execute binary file", filename);
1453	  exit (EX_BINARY_FILE);
1454	}
1455      /* Now rewind the file back to the beginning. */
1456      lseek (fd, 0L, 0);
1457    }
1458
1459  /* Open the script.  But try to move the file descriptor to a randomly
1460     large one, in the hopes that any descriptors used by the script will
1461     not match with ours. */
1462  fd = move_to_high_fd (fd, 0, -1);
1463
1464#if defined (__CYGWIN__) && defined (O_TEXT)
1465  setmode (fd, O_TEXT);
1466#endif
1467
1468#if defined (BUFFERED_INPUT)
1469  default_buffered_input = fd;
1470  SET_CLOSE_ON_EXEC (default_buffered_input);
1471#else /* !BUFFERED_INPUT */
1472  default_input = fdopen (fd, "r");
1473
1474  if (default_input == 0)
1475    {
1476      file_error (filename);
1477      exit (EX_NOTFOUND);
1478    }
1479
1480  SET_CLOSE_ON_EXEC (fd);
1481  if (fileno (default_input) != fd)
1482    SET_CLOSE_ON_EXEC (fileno (default_input));
1483#endif /* !BUFFERED_INPUT */
1484
1485  /* Just about the only way for this code to be executed is if something
1486     like `bash -i /dev/stdin' is executed. */
1487  if (interactive_shell && fd_is_tty)
1488    {
1489      dup2 (fd, 0);
1490      close (fd);
1491      fd = 0;
1492#if defined (BUFFERED_INPUT)
1493      default_buffered_input = 0;
1494#else
1495      fclose (default_input);
1496      default_input = stdin;
1497#endif
1498    }
1499  else if (forced_interactive && fd_is_tty == 0)
1500    /* But if a script is called with something like `bash -i scriptname',
1501       we need to do a non-interactive setup here, since we didn't do it
1502       before. */
1503    init_noninteractive ();
1504
1505  free (filename);
1506  return (fd);
1507}
1508
1509/* Initialize the input routines for the parser. */
1510static void
1511set_bash_input ()
1512{
1513  /* Make sure the fd from which we are reading input is not in
1514     no-delay mode. */
1515#if defined (BUFFERED_INPUT)
1516  if (interactive == 0)
1517    sh_unset_nodelay_mode (default_buffered_input);
1518  else
1519#endif /* !BUFFERED_INPUT */
1520    sh_unset_nodelay_mode (fileno (stdin));
1521
1522  /* with_input_from_stdin really means `with_input_from_readline' */
1523  if (interactive && no_line_editing == 0)
1524    with_input_from_stdin ();
1525#if defined (BUFFERED_INPUT)
1526  else if (interactive == 0)
1527    with_input_from_buffered_stream (default_buffered_input, dollar_vars[0]);
1528#endif /* BUFFERED_INPUT */
1529  else
1530    with_input_from_stream (default_input, dollar_vars[0]);
1531}
1532
1533/* Close the current shell script input source and forget about it.  This is
1534   extern so execute_cmd.c:initialize_subshell() can call it.  If CHECK_ZERO
1535   is non-zero, we close default_buffered_input even if it's the standard
1536   input (fd 0). */
1537void
1538unset_bash_input (check_zero)
1539     int check_zero;
1540{
1541#if defined (BUFFERED_INPUT)
1542  if ((check_zero && default_buffered_input >= 0) ||
1543      (check_zero == 0 && default_buffered_input > 0))
1544    {
1545      close_buffered_fd (default_buffered_input);
1546      default_buffered_input = bash_input.location.buffered_fd = -1;
1547    }
1548#else /* !BUFFERED_INPUT */
1549  if (default_input)
1550    {
1551      fclose (default_input);
1552      default_input = (FILE *)NULL;
1553    }
1554#endif /* !BUFFERED_INPUT */
1555}
1556
1557
1558#if !defined (PROGRAM)
1559#  define PROGRAM "bash"
1560#endif
1561
1562static void
1563set_shell_name (argv0)
1564     char *argv0;
1565{
1566  /* Here's a hack.  If the name of this shell is "sh", then don't do
1567     any startup files; just try to be more like /bin/sh. */
1568  shell_name = argv0 ? base_pathname (argv0) : PROGRAM;
1569
1570  if (argv0 && *argv0 == '-')
1571    {
1572      if (*shell_name == '-')
1573	shell_name++;
1574      login_shell++;
1575    }
1576
1577  if (shell_name[0] == 's' && shell_name[1] == 'h' && shell_name[2] == '\0')
1578    act_like_sh++;
1579  if (shell_name[0] == 's' && shell_name[1] == 'u' && shell_name[2] == '\0')
1580    su_shell++;
1581
1582  shell_name = argv0 ? argv0 : PROGRAM;
1583  FREE (dollar_vars[0]);
1584  dollar_vars[0] = savestring (shell_name);
1585
1586  /* A program may start an interactive shell with
1587	  "execl ("/bin/bash", "-", NULL)".
1588     If so, default the name of this shell to our name. */
1589  if (!shell_name || !*shell_name || (shell_name[0] == '-' && !shell_name[1]))
1590    shell_name = PROGRAM;
1591}
1592
1593static void
1594init_interactive ()
1595{
1596  interactive_shell = startup_state = interactive = 1;
1597  expand_aliases = 1;
1598}
1599
1600static void
1601init_noninteractive ()
1602{
1603#if defined (HISTORY)
1604  bash_history_reinit (0);
1605#endif /* HISTORY */
1606  interactive_shell = startup_state = interactive = 0;
1607  expand_aliases = posixly_correct;	/* XXX - was 0 not posixly_correct */
1608  no_line_editing = 1;
1609#if defined (JOB_CONTROL)
1610  set_job_control (0);
1611#endif /* JOB_CONTROL */
1612}
1613
1614void
1615get_current_user_info ()
1616{
1617  struct passwd *entry;
1618
1619  /* Don't fetch this more than once. */
1620  if (current_user.user_name == 0)
1621    {
1622      entry = getpwuid (current_user.uid);
1623      if (entry)
1624	{
1625	  current_user.user_name = savestring (entry->pw_name);
1626	  current_user.shell = (entry->pw_shell && entry->pw_shell[0])
1627				? savestring (entry->pw_shell)
1628				: savestring ("/bin/sh");
1629	  current_user.home_dir = savestring (entry->pw_dir);
1630	}
1631      else
1632	{
1633	  current_user.user_name = _("I have no name!");
1634	  current_user.user_name = savestring (current_user.user_name);
1635	  current_user.shell = savestring ("/bin/sh");
1636	  current_user.home_dir = savestring ("/");
1637	}
1638      endpwent ();
1639    }
1640}
1641
1642/* Do whatever is necessary to initialize the shell.
1643   Put new initializations in here. */
1644static void
1645shell_initialize ()
1646{
1647  char hostname[256];
1648
1649  /* Line buffer output for stderr and stdout. */
1650  if (shell_initialized == 0)
1651    {
1652      sh_setlinebuf (stderr);
1653      sh_setlinebuf (stdout);
1654    }
1655
1656  /* Sort the array of shell builtins so that the binary search in
1657     find_shell_builtin () works correctly. */
1658  initialize_shell_builtins ();
1659
1660  /* Initialize the trap signal handlers before installing our own
1661     signal handlers.  traps.c:restore_original_signals () is responsible
1662     for restoring the original default signal handlers.  That function
1663     is called when we make a new child. */
1664  initialize_traps ();
1665  initialize_signals (0);
1666
1667  /* It's highly unlikely that this will change. */
1668  if (current_host_name == 0)
1669    {
1670      /* Initialize current_host_name. */
1671      if (gethostname (hostname, 255) < 0)
1672	current_host_name = "??host??";
1673      else
1674	current_host_name = savestring (hostname);
1675    }
1676
1677  /* Initialize the stuff in current_user that comes from the password
1678     file.  We don't need to do this right away if the shell is not
1679     interactive. */
1680  if (interactive_shell)
1681    get_current_user_info ();
1682
1683  /* Initialize our interface to the tilde expander. */
1684  tilde_initialize ();
1685
1686  /* Initialize internal and environment variables.  Don't import shell
1687     functions from the environment if we are running in privileged or
1688     restricted mode or if the shell is running setuid. */
1689#if defined (RESTRICTED_SHELL)
1690  initialize_shell_variables (shell_environment, privileged_mode||restricted||running_setuid);
1691#else
1692  initialize_shell_variables (shell_environment, privileged_mode||running_setuid);
1693#endif
1694
1695  /* Initialize the data structures for storing and running jobs. */
1696  initialize_job_control (0);
1697
1698  /* Initialize input streams to null. */
1699  initialize_bash_input ();
1700
1701  initialize_flags ();
1702
1703  /* Initialize the shell options.  Don't import the shell options
1704     from the environment variable $SHELLOPTS if we are running in
1705     privileged or restricted mode or if the shell is running setuid. */
1706#if defined (RESTRICTED_SHELL)
1707  initialize_shell_options (privileged_mode||restricted||running_setuid);
1708#else
1709  initialize_shell_options (privileged_mode||running_setuid);
1710#endif
1711}
1712
1713/* Function called by main () when it appears that the shell has already
1714   had some initialization performed.  This is supposed to reset the world
1715   back to a pristine state, as if we had been exec'ed. */
1716static void
1717shell_reinitialize ()
1718{
1719  /* The default shell prompts. */
1720  primary_prompt = PPROMPT;
1721  secondary_prompt = SPROMPT;
1722
1723  /* Things that get 1. */
1724  current_command_number = 1;
1725
1726  /* We have decided that the ~/.bashrc file should not be executed
1727     for the invocation of each shell script.  If the variable $ENV
1728     (or $BASH_ENV) is set, its value is used as the name of a file
1729     to source. */
1730  no_rc = no_profile = 1;
1731
1732  /* Things that get 0. */
1733  login_shell = make_login_shell = interactive = executing = 0;
1734  debugging = do_version = line_number = last_command_exit_value = 0;
1735  forced_interactive = interactive_shell = subshell_environment = 0;
1736  expand_aliases = 0;
1737
1738#if defined (HISTORY)
1739  bash_history_reinit (0);
1740#endif /* HISTORY */
1741
1742#if defined (RESTRICTED_SHELL)
1743  restricted = 0;
1744#endif /* RESTRICTED_SHELL */
1745
1746  /* Ensure that the default startup file is used.  (Except that we don't
1747     execute this file for reinitialized shells). */
1748  bashrc_file = "~/.bashrc";
1749
1750  /* Delete all variables and functions.  They will be reinitialized when
1751     the environment is parsed. */
1752  delete_all_contexts (shell_variables);
1753  delete_all_variables (shell_functions);
1754
1755  shell_reinitialized = 1;
1756}
1757
1758static void
1759show_shell_usage (fp, extra)
1760     FILE *fp;
1761     int extra;
1762{
1763  int i;
1764  char *set_opts, *s, *t;
1765
1766  if (extra)
1767    fprintf (fp, "GNU bash, version %s-(%s)\n", shell_version_string (), MACHTYPE);
1768  fprintf (fp, _("Usage:\t%s [GNU long option] [option] ...\n\t%s [GNU long option] [option] script-file ...\n"),
1769	     shell_name, shell_name);
1770  fputs (_("GNU long options:\n"), fp);
1771  for (i = 0; long_args[i].name; i++)
1772    fprintf (fp, "\t--%s\n", long_args[i].name);
1773
1774  fputs (_("Shell options:\n"), fp);
1775  fputs (_("\t-irsD or -c command or -O shopt_option\t\t(invocation only)\n"), fp);
1776
1777  for (i = 0, set_opts = 0; shell_builtins[i].name; i++)
1778    if (STREQ (shell_builtins[i].name, "set"))
1779      set_opts = savestring (shell_builtins[i].short_doc);
1780  if (set_opts)
1781    {
1782      s = xstrchr (set_opts, '[');
1783      if (s == 0)
1784	s = set_opts;
1785      while (*++s == '-')
1786	;
1787      t = xstrchr (s, ']');
1788      if (t)
1789	*t = '\0';
1790      fprintf (fp, _("\t-%s or -o option\n"), s);
1791      free (set_opts);
1792    }
1793
1794  if (extra)
1795    {
1796      fprintf (fp, _("Type `%s -c \"help set\"' for more information about shell options.\n"), shell_name);
1797      fprintf (fp, _("Type `%s -c help' for more information about shell builtin commands.\n"), shell_name);
1798      fprintf (fp, _("Use the `bashbug' command to report bugs.\n"));
1799    }
1800}
1801
1802static void
1803add_shopt_to_alist (opt, on_or_off)
1804     char *opt;
1805     int on_or_off;
1806{
1807  if (shopt_ind >= shopt_len)
1808    {
1809      shopt_len += 8;
1810      shopt_alist = (STRING_INT_ALIST *)xrealloc (shopt_alist, shopt_len * sizeof (shopt_alist[0]));
1811    }
1812  shopt_alist[shopt_ind].word = opt;
1813  shopt_alist[shopt_ind].token = on_or_off;
1814  shopt_ind++;
1815}
1816
1817static void
1818run_shopt_alist ()
1819{
1820  register int i;
1821
1822  for (i = 0; i < shopt_ind; i++)
1823    if (shopt_setopt (shopt_alist[i].word, (shopt_alist[i].token == '-')) != EXECUTION_SUCCESS)
1824      exit (EX_BADUSAGE);
1825  free (shopt_alist);
1826  shopt_alist = 0;
1827  shopt_ind = shopt_len = 0;
1828}
1829