]> git.ipfire.org Git - thirdparty/bash.git/blob - shell.c
Imported from ../bash-2.0.tar.gz.
[thirdparty/bash.git] / shell.c
1 /* shell.c -- GNU's idea of the POSIX shell specification.
2
3 This file is part of Bash, the Bourne Again SHell. Bash is free
4 software; no one can prevent you from reading the source code, or
5 giving it to someone else. This file is copyrighted under the GNU
6 General Public License, which can be found in the file called
7 COPYING.
8
9 Copyright (C) 1988, 1991 Free Software Foundation, Inc.
10
11 This file is part of GNU Bash.
12
13 Bash is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY. No author or distributor accepts responsibility to
15 anyone for the consequences of using it or for whether it serves
16 any particular purpose or works at all, unless he says so in
17 writing. Refer to the GNU Emacs General Public License for full
18 details.
19
20 Everyone is granted permission to copy, modify and redistribute
21 Bash, but only under the conditions described in the GNU General
22 Public License. A copy of this license is supposed to have been
23 given to you along with GNU Emacs so you can know your rights and
24 responsibilities. It should be in a file named COPYING.
25
26 Among other things, the copyright notice and this notice must be
27 preserved on all copies.
28
29 Birthdate:
30 Sunday, January 10th, 1988.
31 Initial author: Brian Fox
32 */
33 #define INSTALL_DEBUG_MODE
34
35 #include "config.h"
36
37 #include "bashtypes.h"
38 #include <sys/file.h>
39 #include "posixstat.h"
40 #include "bashansi.h"
41 #include <stdio.h>
42 #include <signal.h>
43 #include <errno.h>
44 #include "filecntl.h"
45 #include <pwd.h>
46
47 #if defined (HAVE_UNISTD_H)
48 # include <unistd.h>
49 #endif
50
51 #include "shell.h"
52 #include "flags.h"
53 #include "trap.h"
54 #include "mailcheck.h"
55 #include "builtins.h"
56 #include "builtins/common.h"
57
58 #if defined (JOB_CONTROL)
59 #include "jobs.h"
60 #endif /* JOB_CONTROL */
61
62 #include "input.h"
63 #include "execute_cmd.h"
64
65 #if defined (HISTORY)
66 # include "bashhist.h"
67 # include <readline/history.h>
68 #endif
69
70 #include <tilde/tilde.h>
71 #include <glob/fnmatch.h>
72
73 #if !defined (HAVE_GETPW_DECLS)
74 extern struct passwd *getpwuid ();
75 #endif /* !HAVE_GETPW_DECLS */
76
77 #if !defined (errno)
78 extern int errno;
79 #endif
80
81 extern char *dist_version, *release_status;
82 extern int patch_level, build_version;
83 extern int subshell_environment;
84 extern int last_command_exit_value;
85 extern int line_number;
86 extern char *primary_prompt, *secondary_prompt;
87 extern int expand_aliases;
88 extern char *this_command_name;
89
90 /* Non-zero means that this shell has already been run; i.e. you should
91 call shell_reinitialize () if you need to start afresh. */
92 int shell_initialized = 0;
93
94 COMMAND *global_command = (COMMAND *)NULL;
95
96 /* Information about the current user. */
97 struct user_info current_user =
98 {
99 -1, -1, -1, -1, (char *)NULL, (char *)NULL, (char *)NULL
100 };
101
102 /* The current host's name. */
103 char *current_host_name = (char *)NULL;
104
105 /* Non-zero means that this shell is a login shell.
106 Specifically:
107 0 = not login shell.
108 1 = login shell from getty (or equivalent fake out)
109 -1 = login shell from "-login" flag.
110 -2 = both from getty, and from flag.
111 */
112 int login_shell = 0;
113
114 /* Non-zero means that at this moment, the shell is interactive. In
115 general, this means that the shell is at this moment reading input
116 from the keyboard. */
117 int interactive = 0;
118
119 /* Non-zero means that the shell was started as an interactive shell. */
120 int interactive_shell = 0;
121
122 /* Tells what state the shell was in when it started:
123 0 = non-interactive shell script
124 1 = interactive
125 2 = -c command
126 This is a superset of the information provided by interactive_shell.
127 */
128 int startup_state = 0;
129
130 /* Special debugging helper. */
131 int debugging_login_shell = 0;
132
133 /* The environment that the shell passes to other commands. */
134 char **shell_environment;
135
136 /* Non-zero when we are executing a top-level command. */
137 int executing = 0;
138
139 /* The number of commands executed so far. */
140 int current_command_number = 1;
141
142 /* Non-zero is the recursion depth for commands. */
143 int indirection_level = 0;
144
145 /* The name of this shell, as taken from argv[0]. */
146 char *shell_name = (char *)NULL;
147
148 /* time in seconds when the shell was started */
149 time_t shell_start_time;
150
151 /* Are we running in an emacs shell window? */
152 int running_under_emacs;
153
154 /* The name of the .(shell)rc file. */
155 static char *bashrc_file = "~/.bashrc";
156
157 /* Non-zero means to act more like the Bourne shell on startup. */
158 static int act_like_sh;
159
160 /* Non-zero if this shell is being run by `su'. */
161 static int su_shell;
162
163 /* Non-zero if we have already expanded and sourced $ENV. */
164 static int sourced_env;
165
166 /* Is this shell running setuid? */
167 static int running_setuid;
168
169 /* Values for the long-winded argument names. */
170 static int debugging; /* Do debugging things. */
171 static int no_rc; /* Don't execute ~/.bashrc */
172 static int no_profile; /* Don't execute .profile */
173 static int do_version; /* Display interesting version info. */
174 static int make_login_shell; /* Make this shell be a `-bash' shell. */
175 static int want_initial_help; /* --help option */
176
177 int no_line_editing = 0; /* Don't do fancy line editing. */
178 int posixly_correct = 0; /* Non-zero means posix.2 superset. */
179 int dump_translatable_strings; /* Dump strings in $"...", don't execute. */
180
181 /* Some long-winded argument names. These are obviously new. */
182 #define Int 1
183 #define Charp 2
184 struct {
185 char *name;
186 int type;
187 int *int_value;
188 char **char_value;
189 } long_args[] = {
190 { "debug", Int, &debugging, (char **)0x0 },
191 { "dump-strings", Int, &dump_translatable_strings, (char **)0x0 },
192 { "help", Int, &want_initial_help, (char **)0x0 },
193 { "login", Int, &make_login_shell, (char **)0x0 },
194 { "noediting", Int, &no_line_editing, (char **)0x0 },
195 { "noprofile", Int, &no_profile, (char **)0x0 },
196 { "norc", Int, &no_rc, (char **)0x0 },
197 { "posix", Int, &posixly_correct, (char **)0x0 },
198 { "rcfile", Charp, (int *)0x0, &bashrc_file },
199 #if defined (RESTRICTED_SHELL)
200 { "restricted", Int, &restricted, (char **)0x0 },
201 #endif
202 { "verbose", Int, &echo_input_at_read, (char **)0x0 },
203 { "version", Int, &do_version, (char **)0x0 },
204 { (char *)0x0, Int, (int *)0x0, (char **)0x0 }
205 };
206
207 /* These are extern so execute_simple_command can set them, and then
208 longjmp back to main to execute a shell script, instead of calling
209 main () again and resulting in indefinite, possibly fatal, stack
210 growth. */
211 procenv_t subshell_top_level;
212 int subshell_argc;
213 char **subshell_argv;
214 char **subshell_envp;
215
216 #if defined (BUFFERED_INPUT)
217 /* The file descriptor from which the shell is reading input. */
218 int default_buffered_input = -1;
219 #endif
220
221 static int read_from_stdin; /* -s flag supplied */
222 static int want_pending_command; /* -c flag supplied */
223 static char *local_pending_command;
224
225 static FILE *default_input;
226
227 static int parse_long_options ();
228 static int parse_shell_options ();
229 static void run_startup_files ();
230 static int bind_args ();
231 static int open_shell_script ();
232 static void set_bash_input ();
233 static int run_one_command ();
234
235 static int uidget ();
236 static int isnetconn ();
237
238 static void init_interactive (), init_noninteractive ();
239 static void set_shell_name ();
240 static void shell_initialize ();
241 static void shell_reinitialize ();
242
243 static void show_shell_usage ();
244
245 int
246 main (argc, argv, env)
247 int argc;
248 char **argv, **env;
249 {
250 register int i;
251 int code;
252 volatile int locally_skip_execution;
253 volatile int arg_index, top_level_arg_index;
254
255 /* Catch early SIGINTs. */
256 code = setjmp (top_level);
257 if (code)
258 exit (2);
259
260 check_dev_tty ();
261
262 /* Wait forever if we are debugging a login shell. */
263 while (debugging_login_shell);
264
265 set_default_locale ();
266
267 running_setuid = uidget ();
268
269 posixly_correct = (getenv ("POSIXLY_CORRECT") != (char *)NULL) ||
270 (getenv ("POSIX_PEDANTIC") != (char *)NULL);
271
272 #if defined (USE_GNU_MALLOC_LIBRARY)
273 mcheck (programming_error, (void (*) ())0);
274 #endif /* USE_GNU_MALLOC_LIBRARY */
275
276 if (setjmp (subshell_top_level))
277 {
278 argc = subshell_argc;
279 argv = subshell_argv;
280 env = subshell_envp;
281 sourced_env = 0;
282 }
283
284 /* Initialize `local' variables for all `invocations' of main (). */
285 arg_index = 1;
286 local_pending_command = (char *)NULL;
287 want_pending_command = locally_skip_execution = read_from_stdin = 0;
288 default_input = stdin;
289 #if defined (BUFFERED_INPUT)
290 default_buffered_input = -1;
291 #endif
292
293 /* Fix for the `infinite process creation' bug when running shell scripts
294 from startup files on System V. */
295 login_shell = make_login_shell = 0;
296
297 /* If this shell has already been run, then reinitialize it to a
298 vanilla state. */
299 if (shell_initialized || shell_name)
300 {
301 /* Make sure that we do not infinitely recurse as a login shell. */
302 if (*shell_name == '-')
303 shell_name++;
304
305 shell_reinitialize ();
306 if (setjmp (top_level))
307 exit (2);
308 }
309
310 shell_environment = env;
311 set_shell_name (argv[0]);
312 shell_start_time = NOW; /* NOW now defined in general.h */
313
314 /* Parse argument flags from the input line. */
315
316 /* Find full word arguments first. */
317 arg_index = parse_long_options (argv, arg_index, argc);
318
319 if (want_initial_help)
320 {
321 show_shell_usage (stdout);
322 exit (EXECUTION_SUCCESS);
323 }
324
325 if (do_version)
326 {
327 show_shell_version (1);
328 exit (EXECUTION_SUCCESS);
329 }
330
331 /* If user supplied the "--login" flag, then set and invert LOGIN_SHELL. */
332 if (make_login_shell)
333 {
334 login_shell++;
335 login_shell = -login_shell;
336 }
337
338 /* All done with full word options; do standard shell option parsing.*/
339 this_command_name = shell_name; /* for error reporting */
340 arg_index = parse_shell_options (argv, arg_index, argc);
341
342 if (dump_translatable_strings)
343 read_but_dont_execute = 1;
344
345 /* If we're in a strict Posix.2 mode, turn on interactive comments and
346 other Posix.2 things. */
347 if (posixly_correct)
348 posix_initialize (posixly_correct);
349
350 if (running_setuid && privileged_mode == 0)
351 disable_priv_mode ();
352
353 /* Need to get the argument to a -c option processed in the
354 above loop. The next arg is a command to execute, and the
355 following args are $0...$n respectively. */
356 if (want_pending_command)
357 {
358 local_pending_command = argv[arg_index];
359 if (local_pending_command == 0)
360 {
361 report_error ("option `-c' requires an argument");
362 exit (EX_USAGE);
363 }
364 arg_index++;
365 }
366 this_command_name = (char *)NULL;
367
368 /* First, let the outside world know about our interactive status.
369 A shell is interactive if the `-i' flag was given, or if all of
370 the following conditions are met:
371 no -c command
372 no arguments remaining or the -s flag given
373 standard input is a terminal
374 standard output is a terminal
375 Refer to Posix.2, the description of the `sh' utility. */
376
377 if (forced_interactive || /* -i flag */
378 (!local_pending_command && /* No -c command and ... */
379 ((arg_index == argc) || /* no remaining args or... */
380 read_from_stdin) && /* -s flag with args, and */
381 isatty (fileno (stdin)) && /* Input is a terminal and */
382 isatty (fileno (stdout)))) /* output is a terminal. */
383 init_interactive ();
384 else
385 init_noninteractive ();
386
387 #define CLOSE_FDS_AT_LOGIN
388 #if defined (CLOSE_FDS_AT_LOGIN)
389 /*
390 * Some systems have the bad habit of starting login shells with lots of open
391 * file descriptors. For instance, most systems that have picked up the
392 * pre-4.0 Sun YP code leave a file descriptor open each time you call one
393 * of the getpw* functions, and it's set to be open across execs. That
394 * means one for login, one for xterm, one for shelltool, etc.
395 */
396 if (login_shell && interactive_shell)
397 {
398 for (i = 3; i < 20; i++)
399 close (i);
400 }
401 #endif /* CLOSE_FDS_AT_LOGIN */
402
403 /* From here on in, the shell must be a normal functioning shell.
404 Variables from the environment are expected to be set, etc. */
405 shell_initialize ();
406
407 set_default_locale_vars ();
408
409 if (interactive_shell)
410 {
411 char *term;
412
413 term = getenv ("TERM");
414 no_line_editing |= term && (STREQ (term, "emacs"));
415 term = getenv ("EMACS");
416 running_under_emacs = term ? ((fnmatch ("*term*", term, 0) == 0) ? 2 : 1)
417 : 0;
418 }
419
420 top_level_arg_index = arg_index;
421
422 /* Give this shell a place to longjmp to before executing the
423 startup files. This allows users to press C-c to abort the
424 lengthy startup. */
425 code = setjmp (top_level);
426 if (code)
427 {
428 if (code == EXITPROG)
429 exit_shell (last_command_exit_value);
430 else
431 locally_skip_execution++;
432 }
433
434 arg_index = top_level_arg_index;
435
436 /* Execute the start-up scripts. */
437
438 if (interactive_shell == 0)
439 {
440 makunbound ("PS1", shell_variables);
441 makunbound ("PS2", shell_variables);
442 interactive = expand_aliases = 0;
443 }
444 else
445 {
446 change_flag ('i', FLAG_ON);
447 interactive = 1;
448 }
449
450 if (locally_skip_execution == 0 && running_setuid == 0)
451 run_startup_files ();
452
453 /* If we are invoked as `sh', turn on Posix mode. */
454 if (act_like_sh)
455 posix_initialize (posixly_correct = 1);
456
457 #if defined (RESTRICTED_SHELL)
458 /* Turn on the restrictions after parsing the startup files. */
459 maybe_make_restricted (shell_name);
460 #endif /* RESTRICTED_SHELL */
461
462 if (local_pending_command)
463 {
464 arg_index = bind_args (argv, arg_index, argc, 0);
465
466 startup_state = 2;
467 #if defined (ONESHOT)
468 run_one_command (local_pending_command);
469 exit_shell (last_command_exit_value);
470 #else /* ONESHOT */
471 with_input_from_string (local_pending_command, "-c");
472 goto read_and_execute;
473 #endif /* !ONESHOT */
474 }
475
476 /* Get possible input filename and set up default_buffered_input or
477 default_input as appropriate. */
478 if (arg_index != argc && read_from_stdin == 0)
479 {
480 open_shell_script (argv[arg_index]);
481 arg_index++;
482 }
483 else if (interactive == 0)
484 /* In this mode, bash is reading a script from stdin, which is a
485 pipe or redirected file. */
486 #if defined (BUFFERED_INPUT)
487 default_buffered_input = fileno (stdin); /* == 0 */
488 #else
489 setbuf (default_input, (char *)NULL);
490 #endif /* !BUFFERED_INPUT */
491
492 set_bash_input ();
493
494 /* Bind remaining args to $1 ... $n */
495 arg_index = bind_args (argv, arg_index, argc, 1);
496
497 /* Do the things that should be done only for interactive shells. */
498 if (interactive_shell)
499 {
500 /* Set up for checking for presence of mail. */
501 remember_mail_dates ();
502 reset_mail_timer ();
503
504 #if defined (HISTORY)
505 /* Initialize the interactive history stuff. */
506 bash_initialize_history ();
507 if (shell_initialized == 0)
508 load_history ();
509 #endif /* HISTORY */
510
511 /* Initialize terminal state for interactive shells after the
512 .bash_profile and .bashrc are interpreted. */
513 get_tty_state ();
514 }
515
516 #if !defined (ONESHOT)
517 read_and_execute:
518 #endif /* !ONESHOT */
519
520 shell_initialized = 1;
521
522 /* Read commands until exit condition. */
523 reader_loop ();
524 exit_shell (last_command_exit_value);
525 }
526
527 static int
528 parse_long_options (argv, arg_start, arg_end)
529 char **argv;
530 int arg_start, arg_end;
531 {
532 int arg_index, longarg, i;
533 char *arg_string;
534
535 arg_index = arg_start;
536 while ((arg_index != arg_end) && (arg_string = argv[arg_index]) &&
537 (*arg_string == '-'))
538 {
539 longarg = 0;
540
541 /* Make --login equivalent to -login. */
542 if (arg_string[1] == '-' && arg_string[2])
543 {
544 longarg = 1;
545 arg_string++;
546 }
547
548 for (i = 0; long_args[i].name; i++)
549 {
550 if (STREQ (arg_string + 1, long_args[i].name))
551 {
552 if (long_args[i].type == Int)
553 *long_args[i].int_value = 1;
554 else if (argv[++arg_index] == 0)
555 {
556 report_error ("option `%s' requires an argument",
557 long_args[i].name);
558 exit (EX_USAGE);
559 }
560 else
561 *long_args[i].char_value = argv[arg_index];
562
563 break;
564 }
565 }
566 if (long_args[i].name == 0)
567 {
568 if (longarg)
569 {
570 report_error ("%s: unrecognized option", argv[arg_index]);
571 exit (EX_USAGE);
572 }
573 break; /* No such argument. Maybe flag arg. */
574 }
575
576 arg_index++;
577 }
578
579 return (arg_index);
580 }
581
582 static int
583 parse_shell_options (argv, arg_start, arg_end)
584 char **argv;
585 int arg_start, arg_end;
586 {
587 int arg_index;
588 int arg_character, on_or_off, next_arg, i;
589 char *o_option, *arg_string;
590
591 arg_index = arg_start;
592 while (arg_index != arg_end && (arg_string = argv[arg_index]) &&
593 (*arg_string == '-' || *arg_string == '+'))
594 {
595 /* There are flag arguments, so parse them. */
596 next_arg = arg_index + 1;
597
598 /* A single `-' signals the end of options. From the 4.3 BSD sh.
599 An option `--' means the same thing; this is the standard
600 getopt(3) meaning. */
601 if (arg_string[0] == '-' &&
602 (arg_string[1] == '\0' ||
603 (arg_string[1] == '-' && arg_string[2] == '\0')))
604 return (next_arg);
605
606 i = 1;
607 on_or_off = arg_string[0];
608 while (arg_character = arg_string[i++])
609 {
610 switch (arg_character)
611 {
612 case 'c':
613 want_pending_command = 1;
614 break;
615
616 case 's':
617 read_from_stdin = 1;
618 break;
619
620 case 'o':
621 o_option = argv[next_arg];
622 if (o_option == 0)
623 {
624 list_minus_o_opts ();
625 break;
626 }
627 if (set_minus_o_option (on_or_off, o_option) != EXECUTION_SUCCESS)
628 exit (EX_USAGE);
629 next_arg++;
630 break;
631
632 case 'D':
633 dump_translatable_strings = 1;
634 break;
635
636 default:
637 if (change_flag (arg_character, on_or_off) == FLAG_ERROR)
638 {
639 report_error ("%c%c: unrecognized option", on_or_off, arg_character);
640 exit (EX_USAGE);
641 }
642 }
643 }
644 /* Can't do just a simple increment anymore -- what about
645 "bash -abouo emacs ignoreeof -hP"? */
646 arg_index = next_arg;
647 }
648
649 return (arg_index);
650 }
651
652 /* Exit the shell with status S. */
653 int
654 exit_shell (s)
655 int s;
656 {
657 /* Do trap[0] if defined. Allow it to override the exit status
658 passed to us. */
659 if (signal_is_trapped (0))
660 s = run_exit_trap ();
661
662 #if defined (PROCESS_SUBSTITUTION)
663 unlink_fifo_list ();
664 #endif /* PROCESS_SUBSTITUTION */
665
666 #if defined (HISTORY)
667 if (interactive_shell)
668 maybe_save_shell_history ();
669 #endif /* HISTORY */
670
671 #if defined (JOB_CONTROL)
672 /* If this shell is interactive, terminate all stopped jobs and
673 restore the original terminal process group. */
674 end_job_control ();
675 #endif /* JOB_CONTROL */
676
677 /* Always return the exit status of the last command to our parent. */
678 exit (s);
679 }
680
681 /* Source the bash startup files. If POSIXLY_CORRECT is non-zero, we obey
682 the Posix.2 startup file rules: $ENV is expanded, and if the file it
683 names exists, that file is sourced. The Posix.2 rules are in effect
684 for interactive shells only. (section 4.56.5.3) */
685
686 /* Execute ~/.bashrc for most shells. Never execute it if
687 ACT_LIKE_SH is set, or if NO_RC is set.
688
689 If the executable file "/usr/gnu/src/bash/foo" contains:
690
691 #!/usr/gnu/bin/bash
692 echo hello
693
694 then:
695
696 COMMAND EXECUTE BASHRC
697 --------------------------------
698 bash -c foo NO
699 bash foo NO
700 foo NO
701 rsh machine ls YES (for rsh, which calls `bash -c')
702 rsh machine foo YES (for shell started by rsh) NO (for foo!)
703 echo ls | bash NO
704 login NO
705 bash YES
706 */
707
708 static void
709 execute_env_file (env_file)
710 char *env_file;
711 {
712 char *fn;
713 WORD_LIST *list;
714
715 if (env_file && *env_file)
716 {
717 list = expand_string_unsplit (env_file, Q_DOUBLE_QUOTES);
718 if (list)
719 {
720 fn = string_list (list);
721 dispose_words (list);
722
723 if (fn && *fn)
724 maybe_execute_file (fn, 1);
725 FREE (fn);
726 }
727 }
728 }
729
730 static void
731 run_startup_files ()
732 {
733 /* get the rshd case out of the way first. */
734 if (interactive_shell == 0 && no_rc == 0 && login_shell == 0 &&
735 act_like_sh == 0 && local_pending_command && isnetconn (fileno (stdin)))
736 {
737 #ifdef SYS_BASHRC
738 maybe_execute_file (SYS_BASHRC, 1);
739 #endif
740 maybe_execute_file (bashrc_file, 1);
741 return;
742 }
743
744 /* A non-interactive shell not named `sh' and not in posix mode reads and
745 executes commands from $BASH_ENV. If `su' starts a shell with `-c cmd'
746 and `-su' as the name of the shell, we want to read the startup files.
747 No other non-interactive shells read any startup files. */
748 if (interactive_shell == 0 && !(su_shell && login_shell))
749 {
750 if (posixly_correct == 0 && act_like_sh == 0 && privileged_mode == 0 &&
751 sourced_env++ == 0)
752 execute_env_file (get_string_value ("BASH_ENV"));
753 return;
754 }
755
756 /* Interactive shell or `-su' shell. */
757 if (posixly_correct == 0) /* bash, sh */
758 {
759 /* We don't execute .bashrc for login shells. */
760 if (login_shell)
761 no_rc++;
762
763 /* Execute /etc/profile and one of the personal login shell
764 initialization files. */
765 if (login_shell && no_profile == 0)
766 {
767 maybe_execute_file (SYS_PROFILE, 1);
768
769 if (act_like_sh) /* sh */
770 maybe_execute_file ("~/.profile", 1);
771 else if ((maybe_execute_file ("~/.bash_profile", 1) == 0) &&
772 (maybe_execute_file ("~/.bash_login", 1) == 0)) /* bash */
773 maybe_execute_file ("~/.profile", 1);
774 }
775
776 /* bash */
777 if (act_like_sh == 0 && no_rc == 0)
778 {
779 #ifdef SYS_BASHRC
780 maybe_execute_file (SYS_BASHRC, 1);
781 #endif
782 maybe_execute_file (bashrc_file, 1);
783 }
784 /* sh */
785 else if (act_like_sh && privileged_mode == 0 && sourced_env++ == 0)
786 execute_env_file (get_string_value ("ENV"));
787 }
788 else /* bash --posix, sh --posix */
789 {
790 /* bash and sh */
791 if (interactive_shell && privileged_mode == 0 && sourced_env++ == 0)
792 execute_env_file (get_string_value ("ENV"));
793 }
794 }
795
796 #if defined (RESTRICTED_SHELL)
797 /* Perhaps make this shell a `restricted' one, based on NAME. If the
798 basename of NAME is "rbash", then this shell is restricted. The
799 name of the restricted shell is a configurable option, see config.h.
800 In a restricted shell, PATH and SHELL are read-only and non-unsettable.
801 Do this also if `restricted' is already set to 1; maybe the shell was
802 started with -r. */
803 int
804 maybe_make_restricted (name)
805 char *name;
806 {
807 char *temp;
808
809 temp = base_pathname (shell_name);
810 if (restricted || (STREQ (temp, RESTRICTED_SHELL_NAME)))
811 {
812 set_var_read_only ("PATH");
813 set_var_read_only ("SHELL");
814 restricted++;
815 }
816 return (restricted);
817 }
818 #endif /* RESTRICTED_SHELL */
819
820 /* Fetch the current set of uids and gids and return 1 if we're running
821 setuid or setgid. */
822 static int
823 uidget ()
824 {
825 uid_t u;
826
827 u = getuid ();
828 if (current_user.uid != u)
829 {
830 FREE (current_user.user_name);
831 FREE (current_user.shell);
832 FREE (current_user.home_dir);
833 current_user.user_name = current_user.shell = current_user.home_dir = (char *)NULL;
834 }
835 current_user.uid = u;
836 current_user.gid = getgid ();
837 current_user.euid = geteuid ();
838 current_user.egid = getegid ();
839
840 /* See whether or not we are running setuid or setgid. */
841 return (current_user.uid != current_user.euid) ||
842 (current_user.gid != current_user.egid);
843 }
844
845 void
846 disable_priv_mode ()
847 {
848 setuid (current_user.uid);
849 setgid (current_user.gid);
850 current_user.euid = current_user.uid;
851 current_user.egid = current_user.gid;
852 }
853
854 #if defined (ONESHOT)
855 /* Run one command, given as the argument to the -c option. Tell
856 parse_and_execute not to fork for a simple command. */
857 static int
858 run_one_command (command)
859 char *command;
860 {
861 int code;
862
863 code = setjmp (top_level);
864
865 if (code != NOT_JUMPED)
866 {
867 #if defined (PROCESS_SUBSTITUTION)
868 unlink_fifo_list ();
869 #endif /* PROCESS_SUBSTITUTION */
870 switch (code)
871 {
872 /* Some kind of throw to top_level has occured. */
873 case FORCE_EOF:
874 return last_command_exit_value = 127;
875 case EXITPROG:
876 return last_command_exit_value;
877 case DISCARD:
878 return last_command_exit_value = 1;
879 default:
880 programming_error ("run_one_command: bad jump: code %d", code);
881 }
882 }
883 return (parse_and_execute (savestring (command), "-c", -1));
884 }
885 #endif /* ONESHOT */
886
887 static int
888 bind_args (argv, arg_start, arg_end, start_index)
889 char **argv;
890 int arg_start, arg_end, start_index;
891 {
892 register int i;
893 WORD_LIST *args;
894
895 for (i = arg_start, args = (WORD_LIST *)NULL; i != arg_end; i++)
896 args = make_word_list (make_word (argv[i]), args);
897 if (args)
898 {
899 args = REVERSE_LIST (args, WORD_LIST *);
900 if (start_index == 0) /* bind to $0...$n for sh -c command */
901 {
902 /* Posix.2 4.56.3 says that the first argument after sh -c command
903 becomes $0, and the rest of the arguments become $1...$n */
904 shell_name = savestring (args->word->word);
905 dollar_vars[0] = savestring (args->word->word);
906 remember_args (args->next, 1);
907 }
908 else /* bind to $1...$n for shell script */
909 remember_args (args, 1);
910
911 dispose_words (args);
912 }
913
914 return (i);
915 }
916
917 void
918 unbind_args ()
919 {
920 remember_args ((WORD_LIST *)NULL, 1);
921 }
922
923 static int
924 open_shell_script (script_name)
925 char *script_name;
926 {
927 int fd;
928 char *filename, *path_filename;
929 unsigned char sample[80];
930 int sample_len;
931
932 free (dollar_vars[0]);
933 dollar_vars[0] = savestring (script_name);
934 filename = savestring (script_name);
935
936 fd = open (filename, O_RDONLY);
937 if ((fd < 0) && (errno == ENOENT) && (absolute_program (filename) == 0))
938 {
939 /* If it's not in the current directory, try looking through PATH
940 for it. */
941 path_filename = find_path_file (script_name);
942 if (path_filename)
943 {
944 free (filename);
945 filename = path_filename;
946 fd = open (filename, O_RDONLY);
947 }
948 }
949
950 if (fd < 0)
951 {
952 int e = errno;
953 file_error (filename);
954 exit ((e == ENOENT) ? EX_NOTFOUND : EX_NOINPUT);
955 }
956
957 /* Only do this with file descriptors we can seek on. */
958 if (lseek (fd, 0L, 1) != -1)
959 {
960 /* Check to see if the `file' in `bash file' is a binary file
961 according to the same tests done by execute_simple_command (),
962 and report an error and exit if it is. */
963 sample_len = read (fd, sample, sizeof (sample));
964 if (sample_len > 0 && (check_binary_file (sample, sample_len)))
965 {
966 internal_error ("%s: cannot execute binary file", filename);
967 exit (EX_BINARY_FILE);
968 }
969 /* Now rewind the file back to the beginning. */
970 lseek (fd, 0L, 0);
971 }
972
973 #if defined (BUFFERED_INPUT)
974 default_buffered_input = fd;
975 if (default_buffered_input == -1)
976 {
977 file_error (filename);
978 exit (EX_NOTFOUND);
979 }
980 SET_CLOSE_ON_EXEC (default_buffered_input);
981 #else /* !BUFFERED_INPUT */
982 /* Open the script. But try to move the file descriptor to a randomly
983 large one, in the hopes that any descriptors used by the script will
984 not match with ours. */
985 fd = move_to_high_fd (fd, 0);
986
987 default_input = fdopen (fd, "r");
988
989 if (default_input == 0)
990 {
991 file_error (filename);
992 exit (EX_NOTFOUND);
993 }
994
995 SET_CLOSE_ON_EXEC (fd);
996 if (fileno (default_input) != fd)
997 SET_CLOSE_ON_EXEC (fileno (default_input));
998 #endif /* !BUFFERED_INPUT */
999
1000 if (interactive_shell == 0 || isatty (fd) == 0)
1001 init_noninteractive ();
1002 else
1003 {
1004 /* I don't believe that this code is ever executed, even in
1005 the presence of /dev/fd. */
1006 dup2 (fd, 0);
1007 close (fd);
1008 fd = 0;
1009 #if defined (BUFFERED_INPUT)
1010 default_buffered_input = 0;
1011 #else
1012 fclose (default_input);
1013 default_input = stdin;
1014 #endif
1015 }
1016 free (filename);
1017 return (fd);
1018 }
1019
1020 /* Initialize the input routines for the parser. */
1021 static void
1022 set_bash_input ()
1023 {
1024 /* Make sure the fd from which we are reading input is not in
1025 no-delay mode. */
1026 #if defined (BUFFERED_INPUT)
1027 if (interactive == 0)
1028 unset_nodelay_mode (default_buffered_input);
1029 else
1030 #endif /* !BUFFERED_INPUT */
1031 unset_nodelay_mode (fileno (stdin));
1032
1033 /* with_input_from_stdin really means `with_input_from_readline' */
1034 if (interactive && no_line_editing == 0)
1035 with_input_from_stdin ();
1036 else
1037 #if defined (BUFFERED_INPUT)
1038 {
1039 if (interactive == 0)
1040 with_input_from_buffered_stream (default_buffered_input, dollar_vars[0]);
1041 else
1042 with_input_from_stream (default_input, dollar_vars[0]);
1043 }
1044 #else /* !BUFFERED_INPUT */
1045 with_input_from_stream (default_input, dollar_vars[0]);
1046 #endif /* !BUFFERED_INPUT */
1047 }
1048
1049 #if !defined (PROGRAM)
1050 # define PROGRAM "bash"
1051 #endif
1052
1053 static void
1054 set_shell_name (argv0)
1055 char *argv0;
1056 {
1057 /* Here's a hack. If the name of this shell is "sh", then don't do
1058 any startup files; just try to be more like /bin/sh. */
1059 shell_name = base_pathname (argv0);
1060 if (*shell_name == '-')
1061 shell_name++;
1062 if (shell_name[0] == 's' && shell_name[1] == 'h' && shell_name[2] == '\0')
1063 act_like_sh++;
1064 if (shell_name[0] == 's' && shell_name[1] == 'u' && shell_name[2] == '\0')
1065 su_shell++;
1066
1067 shell_name = argv0;
1068 FREE (dollar_vars[0]);
1069 dollar_vars[0] = savestring (shell_name);
1070
1071 if (*shell_name == '-')
1072 {
1073 shell_name++;
1074 login_shell++;
1075 }
1076
1077 /* A program may start an interactive shell with
1078 "execl ("/bin/bash", "-", NULL)".
1079 If so, default the name of this shell to our name. */
1080 if (!shell_name || !*shell_name || (shell_name[0] == '-' && !shell_name[1]))
1081 shell_name = PROGRAM;
1082 }
1083
1084 static void
1085 init_interactive ()
1086 {
1087 interactive_shell = startup_state = interactive = 1;
1088 expand_aliases = 1;
1089 }
1090
1091 static void
1092 init_noninteractive ()
1093 {
1094 #if defined (HISTORY)
1095 bash_history_reinit (0);
1096 #endif /* HISTORY */
1097 interactive_shell = startup_state = interactive = 0;
1098 expand_aliases = 0;
1099 no_line_editing = 1;
1100 #if defined (JOB_CONTROL)
1101 set_job_control (0);
1102 #endif /* JOB_CONTROL */
1103 }
1104
1105 /* Do whatever is necessary to initialize the shell.
1106 Put new initializations in here. */
1107 static void
1108 shell_initialize ()
1109 {
1110 struct passwd *entry;
1111 char hostname[256];
1112
1113 /* Line buffer output for stderr and stdout. */
1114 setlinebuf (stderr);
1115 setlinebuf (stdout);
1116
1117 /* Sort the array of shell builtins so that the binary search in
1118 find_shell_builtin () works correctly. */
1119 initialize_shell_builtins ();
1120
1121 /* Initialize the trap signal handlers before installing our own
1122 signal handlers. traps.c:restore_original_signals () is responsible
1123 for restoring the original default signal handlers. That function
1124 is called when we make a new child. */
1125 initialize_traps ();
1126 initialize_signals ();
1127
1128 /* It's highly unlikely that this will change. */
1129 if (current_host_name == 0)
1130 {
1131 /* Initialize current_user.name and current_host_name. */
1132 if (gethostname (hostname, 255) < 0)
1133 current_host_name = "??host??";
1134 else
1135 current_host_name = savestring (hostname);
1136 }
1137
1138 /* Don't fetch this more than once. */
1139 if (current_user.user_name == 0)
1140 {
1141 entry = getpwuid (current_user.uid);
1142 if (entry)
1143 {
1144 current_user.user_name = savestring (entry->pw_name);
1145 current_user.shell = (entry->pw_shell && entry->pw_shell[0])
1146 ? savestring (entry->pw_shell)
1147 : savestring ("/bin/sh");
1148 current_user.home_dir = savestring (entry->pw_dir);
1149 }
1150 else
1151 {
1152 current_user.user_name = savestring ("I have no name!");
1153 current_user.shell = savestring ("/bin/sh");
1154 current_user.home_dir = savestring ("/");
1155 }
1156 endpwent ();
1157 }
1158
1159 /* Initialize our interface to the tilde expander. */
1160 tilde_initialize ();
1161
1162 /* Initialize internal and environment variables. Don't import shell
1163 functions from the environment if we are running in privileged or
1164 restricted mode or if the shell is running setuid. */
1165 #if defined (RESTRICTED_SHELL)
1166 initialize_shell_variables (shell_environment, privileged_mode||restricted||running_setuid);
1167 #else
1168 initialize_shell_variables (shell_environment, privileged_mode||running_setuid);
1169 #endif
1170
1171 /* Initialize filename hash tables. */
1172 initialize_filename_hashing ();
1173
1174 /* Initialize the data structures for storing and running jobs. */
1175 initialize_jobs ();
1176
1177 /* Initialize input streams to null. */
1178 initialize_bash_input ();
1179
1180 /* Initialize the shell options. */
1181 initialize_shell_options ();
1182 }
1183
1184 /* Function called by main () when it appears that the shell has already
1185 had some initialization performed. This is supposed to reset the world
1186 back to a pristine state, as if we had been exec'ed. */
1187 static void
1188 shell_reinitialize ()
1189 {
1190 /* The default shell prompts. */
1191 primary_prompt = PPROMPT;
1192 secondary_prompt = SPROMPT;
1193
1194 /* Things that get 1. */
1195 current_command_number = 1;
1196
1197 /* We have decided that the ~/.bashrc file should not be executed
1198 for the invocation of each shell script. If the variable $ENV
1199 (or $BASH_ENV) is set, its value is used as the name of a file
1200 to source. */
1201 no_rc = no_profile = 1;
1202
1203 /* Things that get 0. */
1204 login_shell = make_login_shell = interactive = executing = 0;
1205 debugging = do_version = line_number = last_command_exit_value = 0;
1206 forced_interactive = interactive_shell = subshell_environment = 0;
1207 expand_aliases = 0;
1208
1209 #if defined (HISTORY)
1210 bash_history_reinit (0);
1211 #endif /* HISTORY */
1212
1213 #if defined (RESTRICTED_SHELL)
1214 restricted = 0;
1215 #endif /* RESTRICTED_SHELL */
1216
1217 /* Ensure that the default startup file is used. (Except that we don't
1218 execute this file for reinitialized shells). */
1219 bashrc_file = "~/.bashrc";
1220
1221 /* Delete all variables and functions. They will be reinitialized when
1222 the environment is parsed. */
1223 delete_all_variables (shell_variables);
1224 delete_all_variables (shell_functions);
1225
1226 #if 0
1227 /* Pretend the PATH variable has changed. */
1228 flush_hashed_filenames ();
1229 #endif
1230 }
1231
1232 static void
1233 show_shell_usage (fp)
1234 FILE *fp;
1235 {
1236 int i;
1237 char *set_opts, *s, *t;
1238
1239 fprintf (fp, "GNU bash, version %s-(%s)\n", shell_version_string (), MACHTYPE);
1240 fprintf (fp, "Usage:\t%s [GNU long option] [option] ...\n\t%s [GNU long option] [option] script-file ...\n",
1241 shell_name, shell_name);
1242 fputs ("GNU long options:\n", fp);
1243 for (i = 0; long_args[i].name; i++)
1244 fprintf (fp, "\t--%s\n", long_args[i].name);
1245
1246 fputs ("Shell options:\n", fp);
1247 fputs ("\t-irsD or -c command\t\t(invocation only)\n", fp);
1248
1249 for (i = 0, set_opts = 0; shell_builtins[i].name; i++)
1250 if (STREQ (shell_builtins[i].name, "set"))
1251 set_opts = savestring (shell_builtins[i].short_doc);
1252 if (set_opts)
1253 {
1254 s = strchr (set_opts, '[');
1255 if (s == 0)
1256 s = set_opts;
1257 while (*++s == '-')
1258 ;
1259 t = strchr (s, ']');
1260 if (t)
1261 *t = '\0';
1262 fprintf (fp, "\t-%s or -o option\n", s);
1263 free (set_opts);
1264 }
1265
1266 fprintf (fp, "Type `%s -c \"help set\"' for more information about shell options.\n", shell_name);
1267 fprintf (fp, "Type `%s -c help' for more information about shell builtin commands.\n", shell_name);
1268 fprintf (fp, "Use the `bashbug' command to report bugs.\n");
1269 }
1270
1271 /* The second and subsequent conditions must match those used to decide
1272 whether or not to call getpeername() in isnetconn(). */
1273 #if defined (HAVE_SYS_SOCKET_H) && defined (HAVE_GETPEERNAME) && !defined (SVR4_2)
1274 # include <sys/socket.h>
1275 #endif
1276
1277 /* Is FD a socket or network connection? */
1278 static int
1279 isnetconn (fd)
1280 int fd;
1281 {
1282 #if defined (HAVE_GETPEERNAME) && !defined (SVR4_2)
1283 int rv, l;
1284 struct sockaddr sa;
1285
1286 l = sizeof(sa);
1287 rv = getpeername(0, &sa, &l);
1288 /* Solaris 2.5 getpeername() returns EINVAL if the fd is not a socket. */
1289 return ((rv < 0 && (errno == ENOTSOCK || errno == EINVAL)) ? 0 : 1);
1290 #else /* !HAVE_GETPEERNAME || SVR4_2 */
1291 # if defined (SVR4) || defined (SVR4_2)
1292 /* Sockets on SVR4 and SVR4.2 are character special (streams) devices. */
1293 struct stat sb;
1294
1295 if (isatty (fd))
1296 return (0);
1297 if (fstat (fd, &sb) < 0)
1298 return (0);
1299 # if defined (S_ISFIFO)
1300 if (S_ISFIFO (sb.st_mode))
1301 return (0);
1302 # endif /* S_ISFIFO */
1303 return (S_ISCHR (sb.st_mode));
1304 # else /* !SVR4 && !SVR4_2 */
1305 # if defined (S_ISSOCK)
1306 struct stat sb;
1307
1308 if (fstat (fd, &sb) < 0)
1309 return (0);
1310 return (S_ISSOCK (sb.st_mode));
1311 # else /* !S_ISSOCK */
1312 return (0);
1313 # endif /* !S_ISSOCK */
1314 # endif /* !SVR4 && !SVR4_2 */
1315 #endif /* !HAVE_GETPEERNAME || SVR4_2 */
1316 }