]> git.ipfire.org Git - thirdparty/bash.git/blob - shell.c
Imported from ../bash-2.01.1.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, saverst;
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, 1);
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 (running_setuid && privileged_mode == 0)
346 disable_priv_mode ();
347
348 /* Need to get the argument to a -c option processed in the
349 above loop. The next arg is a command to execute, and the
350 following args are $0...$n respectively. */
351 if (want_pending_command)
352 {
353 local_pending_command = argv[arg_index];
354 if (local_pending_command == 0)
355 {
356 report_error ("option `-c' requires an argument");
357 exit (EX_USAGE);
358 }
359 arg_index++;
360 }
361 this_command_name = (char *)NULL;
362
363 /* First, let the outside world know about our interactive status.
364 A shell is interactive if the `-i' flag was given, or if all of
365 the following conditions are met:
366 no -c command
367 no arguments remaining or the -s flag given
368 standard input is a terminal
369 standard output is a terminal
370 Refer to Posix.2, the description of the `sh' utility. */
371
372 if (forced_interactive || /* -i flag */
373 (!local_pending_command && /* No -c command and ... */
374 ((arg_index == argc) || /* no remaining args or... */
375 read_from_stdin) && /* -s flag with args, and */
376 isatty (fileno (stdin)) && /* Input is a terminal and */
377 isatty (fileno (stdout)))) /* output is a terminal. */
378 init_interactive ();
379 else
380 init_noninteractive ();
381
382 #define CLOSE_FDS_AT_LOGIN
383 #if defined (CLOSE_FDS_AT_LOGIN)
384 /*
385 * Some systems have the bad habit of starting login shells with lots of open
386 * file descriptors. For instance, most systems that have picked up the
387 * pre-4.0 Sun YP code leave a file descriptor open each time you call one
388 * of the getpw* functions, and it's set to be open across execs. That
389 * means one for login, one for xterm, one for shelltool, etc.
390 */
391 if (login_shell && interactive_shell)
392 {
393 for (i = 3; i < 20; i++)
394 close (i);
395 }
396 #endif /* CLOSE_FDS_AT_LOGIN */
397
398 /* If we're in a strict Posix.2 mode, turn on interactive comments and
399 other Posix.2 things. */
400 if (posixly_correct)
401 {
402 posix_initialize (posixly_correct);
403 #if defined (READLINE)
404 if (interactive_shell)
405 posix_readline_initialize (posixly_correct);
406 #endif
407 }
408
409 /* From here on in, the shell must be a normal functioning shell.
410 Variables from the environment are expected to be set, etc. */
411 shell_initialize ();
412
413 set_default_locale_vars ();
414
415 if (interactive_shell)
416 {
417 char *term;
418
419 term = getenv ("TERM");
420 no_line_editing |= term && (STREQ (term, "emacs"));
421 term = getenv ("EMACS");
422 running_under_emacs = term ? ((fnmatch ("*term*", term, 0) == 0) ? 2 : 1)
423 : 0;
424 }
425
426 top_level_arg_index = arg_index;
427
428 /* Give this shell a place to longjmp to before executing the
429 startup files. This allows users to press C-c to abort the
430 lengthy startup. */
431 code = setjmp (top_level);
432 if (code)
433 {
434 if (code == EXITPROG)
435 exit_shell (last_command_exit_value);
436 else
437 {
438 #if defined (JOB_CONTROL)
439 /* Reset job control, since run_startup_files turned it off. */
440 set_job_control (interactive_shell);
441 #endif
442 locally_skip_execution++;
443 }
444 }
445
446 arg_index = top_level_arg_index;
447
448 /* Execute the start-up scripts. */
449
450 if (interactive_shell == 0)
451 {
452 makunbound ("PS1", shell_variables);
453 makunbound ("PS2", shell_variables);
454 interactive = expand_aliases = 0;
455 }
456 else
457 {
458 change_flag ('i', FLAG_ON);
459 interactive = 1;
460 }
461
462 #if defined (RESTRICTED_SHELL)
463 /* If the `-r' option is supplied at invocation, make sure that the shell
464 is not in restricted mode when running the startup files. */
465 saverst = restricted;
466 restricted = 0;
467 #endif
468
469 if (locally_skip_execution == 0 && running_setuid == 0)
470 run_startup_files ();
471
472 /* If we are invoked as `sh', turn on Posix mode. */
473 if (act_like_sh)
474 {
475 posix_initialize (posixly_correct = 1);
476 #if defined (READLINE)
477 if (interactive_shell)
478 posix_readline_initialize (posixly_correct);
479 #endif
480 }
481
482 #if defined (RESTRICTED_SHELL)
483 /* Turn on the restrictions after parsing the startup files. This
484 means that `bash -r' or `set -r' invoked from a startup file will
485 turn on the restrictions after the startup files are executed. */
486 restricted = saverst || restricted;
487 maybe_make_restricted (shell_name);
488 #endif /* RESTRICTED_SHELL */
489
490 if (local_pending_command)
491 {
492 arg_index = bind_args (argv, arg_index, argc, 0);
493
494 startup_state = 2;
495 #if defined (ONESHOT)
496 run_one_command (local_pending_command);
497 exit_shell (last_command_exit_value);
498 #else /* ONESHOT */
499 with_input_from_string (local_pending_command, "-c");
500 goto read_and_execute;
501 #endif /* !ONESHOT */
502 }
503
504 /* Get possible input filename and set up default_buffered_input or
505 default_input as appropriate. */
506 if (arg_index != argc && read_from_stdin == 0)
507 {
508 open_shell_script (argv[arg_index]);
509 arg_index++;
510 }
511 else if (interactive == 0)
512 /* In this mode, bash is reading a script from stdin, which is a
513 pipe or redirected file. */
514 #if defined (BUFFERED_INPUT)
515 default_buffered_input = fileno (stdin); /* == 0 */
516 #else
517 setbuf (default_input, (char *)NULL);
518 #endif /* !BUFFERED_INPUT */
519
520 set_bash_input ();
521
522 /* Bind remaining args to $1 ... $n */
523 arg_index = bind_args (argv, arg_index, argc, 1);
524
525 /* Do the things that should be done only for interactive shells. */
526 if (interactive_shell)
527 {
528 /* Set up for checking for presence of mail. */
529 remember_mail_dates ();
530 reset_mail_timer ();
531
532 #if defined (HISTORY)
533 /* Initialize the interactive history stuff. */
534 bash_initialize_history ();
535 if (shell_initialized == 0)
536 load_history ();
537 #endif /* HISTORY */
538
539 /* Initialize terminal state for interactive shells after the
540 .bash_profile and .bashrc are interpreted. */
541 get_tty_state ();
542 }
543
544 #if !defined (ONESHOT)
545 read_and_execute:
546 #endif /* !ONESHOT */
547
548 shell_initialized = 1;
549
550 /* Read commands until exit condition. */
551 reader_loop ();
552 exit_shell (last_command_exit_value);
553 }
554
555 static int
556 parse_long_options (argv, arg_start, arg_end)
557 char **argv;
558 int arg_start, arg_end;
559 {
560 int arg_index, longarg, i;
561 char *arg_string;
562
563 arg_index = arg_start;
564 while ((arg_index != arg_end) && (arg_string = argv[arg_index]) &&
565 (*arg_string == '-'))
566 {
567 longarg = 0;
568
569 /* Make --login equivalent to -login. */
570 if (arg_string[1] == '-' && arg_string[2])
571 {
572 longarg = 1;
573 arg_string++;
574 }
575
576 for (i = 0; long_args[i].name; i++)
577 {
578 if (STREQ (arg_string + 1, long_args[i].name))
579 {
580 if (long_args[i].type == Int)
581 *long_args[i].int_value = 1;
582 else if (argv[++arg_index] == 0)
583 {
584 report_error ("option `%s' requires an argument",
585 long_args[i].name);
586 exit (EX_USAGE);
587 }
588 else
589 *long_args[i].char_value = argv[arg_index];
590
591 break;
592 }
593 }
594 if (long_args[i].name == 0)
595 {
596 if (longarg)
597 {
598 report_error ("%s: unrecognized option", argv[arg_index]);
599 show_shell_usage (stderr, 0);
600 exit (EX_USAGE);
601 }
602 break; /* No such argument. Maybe flag arg. */
603 }
604
605 arg_index++;
606 }
607
608 return (arg_index);
609 }
610
611 static int
612 parse_shell_options (argv, arg_start, arg_end)
613 char **argv;
614 int arg_start, arg_end;
615 {
616 int arg_index;
617 int arg_character, on_or_off, next_arg, i;
618 char *o_option, *arg_string;
619
620 arg_index = arg_start;
621 while (arg_index != arg_end && (arg_string = argv[arg_index]) &&
622 (*arg_string == '-' || *arg_string == '+'))
623 {
624 /* There are flag arguments, so parse them. */
625 next_arg = arg_index + 1;
626
627 /* A single `-' signals the end of options. From the 4.3 BSD sh.
628 An option `--' means the same thing; this is the standard
629 getopt(3) meaning. */
630 if (arg_string[0] == '-' &&
631 (arg_string[1] == '\0' ||
632 (arg_string[1] == '-' && arg_string[2] == '\0')))
633 return (next_arg);
634
635 i = 1;
636 on_or_off = arg_string[0];
637 while (arg_character = arg_string[i++])
638 {
639 switch (arg_character)
640 {
641 case 'c':
642 want_pending_command = 1;
643 break;
644
645 case 's':
646 read_from_stdin = 1;
647 break;
648
649 case 'o':
650 o_option = argv[next_arg];
651 if (o_option == 0)
652 {
653 list_minus_o_opts (-1);
654 break;
655 }
656 if (set_minus_o_option (on_or_off, o_option) != EXECUTION_SUCCESS)
657 exit (EX_USAGE);
658 next_arg++;
659 break;
660
661 case 'D':
662 dump_translatable_strings = 1;
663 break;
664
665 default:
666 if (change_flag (arg_character, on_or_off) == FLAG_ERROR)
667 {
668 report_error ("%c%c: unrecognized option", on_or_off, arg_character);
669 show_shell_usage (stderr, 0);
670 exit (EX_USAGE);
671 }
672 }
673 }
674 /* Can't do just a simple increment anymore -- what about
675 "bash -abouo emacs ignoreeof -hP"? */
676 arg_index = next_arg;
677 }
678
679 return (arg_index);
680 }
681
682 /* Exit the shell with status S. */
683 int
684 exit_shell (s)
685 int s;
686 {
687 /* Do trap[0] if defined. Allow it to override the exit status
688 passed to us. */
689 if (signal_is_trapped (0))
690 s = run_exit_trap ();
691
692 #if defined (PROCESS_SUBSTITUTION)
693 unlink_fifo_list ();
694 #endif /* PROCESS_SUBSTITUTION */
695
696 #if defined (HISTORY)
697 if (interactive_shell)
698 maybe_save_shell_history ();
699 #endif /* HISTORY */
700
701 #if defined (JOB_CONTROL)
702 /* If this shell is interactive, terminate all stopped jobs and
703 restore the original terminal process group. */
704 end_job_control ();
705 #endif /* JOB_CONTROL */
706
707 /* Always return the exit status of the last command to our parent. */
708 exit (s);
709 }
710
711 /* Source the bash startup files. If POSIXLY_CORRECT is non-zero, we obey
712 the Posix.2 startup file rules: $ENV is expanded, and if the file it
713 names exists, that file is sourced. The Posix.2 rules are in effect
714 for interactive shells only. (section 4.56.5.3) */
715
716 /* Execute ~/.bashrc for most shells. Never execute it if
717 ACT_LIKE_SH is set, or if NO_RC is set.
718
719 If the executable file "/usr/gnu/src/bash/foo" contains:
720
721 #!/usr/gnu/bin/bash
722 echo hello
723
724 then:
725
726 COMMAND EXECUTE BASHRC
727 --------------------------------
728 bash -c foo NO
729 bash foo NO
730 foo NO
731 rsh machine ls YES (for rsh, which calls `bash -c')
732 rsh machine foo YES (for shell started by rsh) NO (for foo!)
733 echo ls | bash NO
734 login NO
735 bash YES
736 */
737
738 static void
739 execute_env_file (env_file)
740 char *env_file;
741 {
742 char *fn;
743 WORD_LIST *list;
744
745 if (env_file && *env_file)
746 {
747 list = expand_string_unsplit (env_file, Q_DOUBLE_QUOTES);
748 if (list)
749 {
750 fn = string_list (list);
751 dispose_words (list);
752
753 if (fn && *fn)
754 maybe_execute_file (fn, 1);
755 FREE (fn);
756 }
757 }
758 }
759
760 static void
761 run_startup_files ()
762 {
763 #if defined (JOB_CONTROL)
764 int old_job_control;
765 #endif
766
767 /* get the rshd case out of the way first. */
768 if (interactive_shell == 0 && no_rc == 0 && login_shell == 0 &&
769 act_like_sh == 0 && local_pending_command && isnetconn (fileno (stdin)))
770 {
771 #ifdef SYS_BASHRC
772 maybe_execute_file (SYS_BASHRC, 1);
773 #endif
774 maybe_execute_file (bashrc_file, 1);
775 return;
776 }
777
778 /* A non-interactive shell not named `sh' and not in posix mode reads and
779 executes commands from $BASH_ENV. If `su' starts a shell with `-c cmd'
780 and `-su' as the name of the shell, we want to read the startup files.
781 No other non-interactive shells read any startup files. */
782 if (interactive_shell == 0 && !(su_shell && login_shell))
783 {
784 if (posixly_correct == 0 && act_like_sh == 0 && privileged_mode == 0 &&
785 sourced_env++ == 0)
786 execute_env_file (get_string_value ("BASH_ENV"));
787 return;
788 }
789
790 #if defined (JOB_CONTROL)
791 /* Startup files should be run without job control enabled. */
792 old_job_control = set_job_control (0);
793 #endif
794
795 /* Interactive shell or `-su' shell. */
796 if (posixly_correct == 0) /* bash, sh */
797 {
798 /* We don't execute .bashrc for login shells. */
799 if (login_shell)
800 no_rc++;
801
802 /* Execute /etc/profile and one of the personal login shell
803 initialization files. */
804 if (login_shell && no_profile == 0)
805 {
806 maybe_execute_file (SYS_PROFILE, 1);
807
808 if (act_like_sh) /* sh */
809 maybe_execute_file ("~/.profile", 1);
810 else if ((maybe_execute_file ("~/.bash_profile", 1) == 0) &&
811 (maybe_execute_file ("~/.bash_login", 1) == 0)) /* bash */
812 maybe_execute_file ("~/.profile", 1);
813 }
814
815 /* bash */
816 if (act_like_sh == 0 && no_rc == 0)
817 {
818 #ifdef SYS_BASHRC
819 maybe_execute_file (SYS_BASHRC, 1);
820 #endif
821 maybe_execute_file (bashrc_file, 1);
822 }
823 /* sh */
824 else if (act_like_sh && privileged_mode == 0 && sourced_env++ == 0)
825 execute_env_file (get_string_value ("ENV"));
826 }
827 else /* bash --posix, sh --posix */
828 {
829 /* bash and sh */
830 if (interactive_shell && privileged_mode == 0 && sourced_env++ == 0)
831 execute_env_file (get_string_value ("ENV"));
832 }
833
834 #if defined (JOB_CONTROL)
835 set_job_control (old_job_control);
836 #endif
837 }
838
839 #if defined (RESTRICTED_SHELL)
840 /* Perhaps make this shell a `restricted' one, based on NAME. If the
841 basename of NAME is "rbash", then this shell is restricted. The
842 name of the restricted shell is a configurable option, see config.h.
843 In a restricted shell, PATH and SHELL are read-only and non-unsettable.
844 Do this also if `restricted' is already set to 1; maybe the shell was
845 started with -r. */
846 int
847 maybe_make_restricted (name)
848 char *name;
849 {
850 char *temp;
851
852 temp = base_pathname (shell_name);
853 if (restricted || (STREQ (temp, RESTRICTED_SHELL_NAME)))
854 {
855 set_var_read_only ("PATH");
856 set_var_read_only ("SHELL");
857 restricted++;
858 }
859 return (restricted);
860 }
861 #endif /* RESTRICTED_SHELL */
862
863 /* Fetch the current set of uids and gids and return 1 if we're running
864 setuid or setgid. */
865 static int
866 uidget ()
867 {
868 uid_t u;
869
870 u = getuid ();
871 if (current_user.uid != u)
872 {
873 FREE (current_user.user_name);
874 FREE (current_user.shell);
875 FREE (current_user.home_dir);
876 current_user.user_name = current_user.shell = current_user.home_dir = (char *)NULL;
877 }
878 current_user.uid = u;
879 current_user.gid = getgid ();
880 current_user.euid = geteuid ();
881 current_user.egid = getegid ();
882
883 /* See whether or not we are running setuid or setgid. */
884 return (current_user.uid != current_user.euid) ||
885 (current_user.gid != current_user.egid);
886 }
887
888 void
889 disable_priv_mode ()
890 {
891 setuid (current_user.uid);
892 setgid (current_user.gid);
893 current_user.euid = current_user.uid;
894 current_user.egid = current_user.gid;
895 }
896
897 #if defined (ONESHOT)
898 /* Run one command, given as the argument to the -c option. Tell
899 parse_and_execute not to fork for a simple command. */
900 static int
901 run_one_command (command)
902 char *command;
903 {
904 int code;
905
906 code = setjmp (top_level);
907
908 if (code != NOT_JUMPED)
909 {
910 #if defined (PROCESS_SUBSTITUTION)
911 unlink_fifo_list ();
912 #endif /* PROCESS_SUBSTITUTION */
913 switch (code)
914 {
915 /* Some kind of throw to top_level has occured. */
916 case FORCE_EOF:
917 return last_command_exit_value = 127;
918 case EXITPROG:
919 return last_command_exit_value;
920 case DISCARD:
921 return last_command_exit_value = 1;
922 default:
923 programming_error ("run_one_command: bad jump: code %d", code);
924 }
925 }
926 return (parse_and_execute (savestring (command), "-c", SEVAL_NOHIST));
927 }
928 #endif /* ONESHOT */
929
930 static int
931 bind_args (argv, arg_start, arg_end, start_index)
932 char **argv;
933 int arg_start, arg_end, start_index;
934 {
935 register int i;
936 WORD_LIST *args;
937
938 for (i = arg_start, args = (WORD_LIST *)NULL; i != arg_end; i++)
939 args = make_word_list (make_word (argv[i]), args);
940 if (args)
941 {
942 args = REVERSE_LIST (args, WORD_LIST *);
943 if (start_index == 0) /* bind to $0...$n for sh -c command */
944 {
945 /* Posix.2 4.56.3 says that the first argument after sh -c command
946 becomes $0, and the rest of the arguments become $1...$n */
947 shell_name = savestring (args->word->word);
948 FREE (dollar_vars[0]);
949 dollar_vars[0] = savestring (args->word->word);
950 remember_args (args->next, 1);
951 }
952 else /* bind to $1...$n for shell script */
953 remember_args (args, 1);
954
955 dispose_words (args);
956 }
957
958 return (i);
959 }
960
961 void
962 unbind_args ()
963 {
964 remember_args ((WORD_LIST *)NULL, 1);
965 }
966
967 static int
968 open_shell_script (script_name)
969 char *script_name;
970 {
971 int fd, e;
972 char *filename, *path_filename;
973 unsigned char sample[80];
974 int sample_len;
975 struct stat sb;
976
977 free (dollar_vars[0]);
978 dollar_vars[0] = savestring (script_name);
979 filename = savestring (script_name);
980
981 fd = open (filename, O_RDONLY);
982 if ((fd < 0) && (errno == ENOENT) && (absolute_program (filename) == 0))
983 {
984 e = errno;
985 /* If it's not in the current directory, try looking through PATH
986 for it. */
987 path_filename = find_path_file (script_name);
988 if (path_filename)
989 {
990 free (filename);
991 filename = path_filename;
992 fd = open (filename, O_RDONLY);
993 }
994 else
995 errno = e;
996 }
997
998 if (fd < 0)
999 {
1000 e = errno;
1001 file_error (filename);
1002 exit ((e == ENOENT) ? EX_NOTFOUND : EX_NOINPUT);
1003 }
1004
1005 /* Only do this with file descriptors we can seek on. */
1006 if (lseek (fd, 0L, 1) != -1)
1007 {
1008 /* Check to see if the `file' in `bash file' is a binary file
1009 according to the same tests done by execute_simple_command (),
1010 and report an error and exit if it is. */
1011 sample_len = read (fd, sample, sizeof (sample));
1012 if (sample_len < 0)
1013 {
1014 e = errno;
1015 if ((fstat (fd, &sb) == 0) && S_ISDIR (sb.st_mode))
1016 internal_error ("%s: is a directory", filename);
1017 else
1018 {
1019 errno = e;
1020 file_error (filename);
1021 }
1022 exit (EX_NOEXEC);
1023 }
1024 else if (sample_len > 0 && (check_binary_file (sample, sample_len)))
1025 {
1026 internal_error ("%s: cannot execute binary file", filename);
1027 exit (EX_BINARY_FILE);
1028 }
1029 /* Now rewind the file back to the beginning. */
1030 lseek (fd, 0L, 0);
1031 }
1032
1033 #if defined (BUFFERED_INPUT)
1034 default_buffered_input = fd;
1035 # if 0
1036 /* This is never executed. */
1037 if (default_buffered_input == -1)
1038 {
1039 file_error (filename);
1040 exit (EX_NOTFOUND);
1041 }
1042 # endif
1043 SET_CLOSE_ON_EXEC (default_buffered_input);
1044 #else /* !BUFFERED_INPUT */
1045 /* Open the script. But try to move the file descriptor to a randomly
1046 large one, in the hopes that any descriptors used by the script will
1047 not match with ours. */
1048 fd = move_to_high_fd (fd, 0, -1);
1049
1050 default_input = fdopen (fd, "r");
1051
1052 if (default_input == 0)
1053 {
1054 file_error (filename);
1055 exit (EX_NOTFOUND);
1056 }
1057
1058 SET_CLOSE_ON_EXEC (fd);
1059 if (fileno (default_input) != fd)
1060 SET_CLOSE_ON_EXEC (fileno (default_input));
1061 #endif /* !BUFFERED_INPUT */
1062
1063 if (interactive_shell == 0 || isatty (fd) == 0)
1064 /* XXX - does this really need to be called again here? */
1065 init_noninteractive ();
1066 else
1067 {
1068 /* I don't believe that this code is ever executed, even in
1069 the presence of /dev/fd. */
1070 dup2 (fd, 0);
1071 close (fd);
1072 fd = 0;
1073 #if defined (BUFFERED_INPUT)
1074 default_buffered_input = 0;
1075 #else
1076 fclose (default_input);
1077 default_input = stdin;
1078 #endif
1079 }
1080 free (filename);
1081 return (fd);
1082 }
1083
1084 /* Initialize the input routines for the parser. */
1085 static void
1086 set_bash_input ()
1087 {
1088 /* Make sure the fd from which we are reading input is not in
1089 no-delay mode. */
1090 #if defined (BUFFERED_INPUT)
1091 if (interactive == 0)
1092 unset_nodelay_mode (default_buffered_input);
1093 else
1094 #endif /* !BUFFERED_INPUT */
1095 unset_nodelay_mode (fileno (stdin));
1096
1097 /* with_input_from_stdin really means `with_input_from_readline' */
1098 if (interactive && no_line_editing == 0)
1099 with_input_from_stdin ();
1100 else
1101 #if defined (BUFFERED_INPUT)
1102 {
1103 if (interactive == 0)
1104 with_input_from_buffered_stream (default_buffered_input, dollar_vars[0]);
1105 else
1106 with_input_from_stream (default_input, dollar_vars[0]);
1107 }
1108 #else /* !BUFFERED_INPUT */
1109 with_input_from_stream (default_input, dollar_vars[0]);
1110 #endif /* !BUFFERED_INPUT */
1111 }
1112
1113 #if !defined (PROGRAM)
1114 # define PROGRAM "bash"
1115 #endif
1116
1117 static void
1118 set_shell_name (argv0)
1119 char *argv0;
1120 {
1121 /* Here's a hack. If the name of this shell is "sh", then don't do
1122 any startup files; just try to be more like /bin/sh. */
1123 shell_name = base_pathname (argv0);
1124 if (*shell_name == '-')
1125 shell_name++;
1126 if (shell_name[0] == 's' && shell_name[1] == 'h' && shell_name[2] == '\0')
1127 act_like_sh++;
1128 if (shell_name[0] == 's' && shell_name[1] == 'u' && shell_name[2] == '\0')
1129 su_shell++;
1130
1131 shell_name = argv0;
1132 FREE (dollar_vars[0]);
1133 dollar_vars[0] = savestring (shell_name);
1134
1135 if (*shell_name == '-')
1136 {
1137 shell_name++;
1138 login_shell++;
1139 }
1140
1141 /* A program may start an interactive shell with
1142 "execl ("/bin/bash", "-", NULL)".
1143 If so, default the name of this shell to our name. */
1144 if (!shell_name || !*shell_name || (shell_name[0] == '-' && !shell_name[1]))
1145 shell_name = PROGRAM;
1146 }
1147
1148 static void
1149 init_interactive ()
1150 {
1151 interactive_shell = startup_state = interactive = 1;
1152 expand_aliases = 1;
1153 }
1154
1155 static void
1156 init_noninteractive ()
1157 {
1158 #if defined (HISTORY)
1159 bash_history_reinit (0);
1160 #endif /* HISTORY */
1161 interactive_shell = startup_state = interactive = 0;
1162 expand_aliases = 0;
1163 no_line_editing = 1;
1164 #if defined (JOB_CONTROL)
1165 set_job_control (0);
1166 #endif /* JOB_CONTROL */
1167 }
1168
1169 void
1170 get_current_user_info ()
1171 {
1172 struct passwd *entry;
1173
1174 /* Don't fetch this more than once. */
1175 if (current_user.user_name == 0)
1176 {
1177 entry = getpwuid (current_user.uid);
1178 if (entry)
1179 {
1180 current_user.user_name = savestring (entry->pw_name);
1181 current_user.shell = (entry->pw_shell && entry->pw_shell[0])
1182 ? savestring (entry->pw_shell)
1183 : savestring ("/bin/sh");
1184 current_user.home_dir = savestring (entry->pw_dir);
1185 }
1186 else
1187 {
1188 current_user.user_name = savestring ("I have no name!");
1189 current_user.shell = savestring ("/bin/sh");
1190 current_user.home_dir = savestring ("/");
1191 }
1192 endpwent ();
1193 }
1194 }
1195
1196 /* Do whatever is necessary to initialize the shell.
1197 Put new initializations in here. */
1198 static void
1199 shell_initialize ()
1200 {
1201 char hostname[256];
1202
1203 /* Line buffer output for stderr and stdout. */
1204 setlinebuf (stderr);
1205 setlinebuf (stdout);
1206
1207 /* Sort the array of shell builtins so that the binary search in
1208 find_shell_builtin () works correctly. */
1209 initialize_shell_builtins ();
1210
1211 /* Initialize the trap signal handlers before installing our own
1212 signal handlers. traps.c:restore_original_signals () is responsible
1213 for restoring the original default signal handlers. That function
1214 is called when we make a new child. */
1215 initialize_traps ();
1216 initialize_signals ();
1217
1218 /* It's highly unlikely that this will change. */
1219 if (current_host_name == 0)
1220 {
1221 /* Initialize current_host_name. */
1222 if (gethostname (hostname, 255) < 0)
1223 current_host_name = "??host??";
1224 else
1225 current_host_name = savestring (hostname);
1226 }
1227
1228 /* Initialize the stuff in current_user that comes from the password
1229 file. We don't need to do this right away if the shell is not
1230 interactive. */
1231 if (interactive_shell)
1232 get_current_user_info ();
1233
1234 /* Initialize our interface to the tilde expander. */
1235 tilde_initialize ();
1236
1237 /* Initialize internal and environment variables. Don't import shell
1238 functions from the environment if we are running in privileged or
1239 restricted mode or if the shell is running setuid. */
1240 #if defined (RESTRICTED_SHELL)
1241 initialize_shell_variables (shell_environment, privileged_mode||restricted||running_setuid);
1242 #else
1243 initialize_shell_variables (shell_environment, privileged_mode||running_setuid);
1244 #endif
1245
1246 #if 0
1247 /* Initialize filename hash tables. */
1248 initialize_filename_hashing ();
1249 #endif
1250
1251 /* Initialize the data structures for storing and running jobs. */
1252 initialize_job_control (0);
1253
1254 /* Initialize input streams to null. */
1255 initialize_bash_input ();
1256
1257 /* Initialize the shell options. */
1258 initialize_shell_options ();
1259 }
1260
1261 /* Function called by main () when it appears that the shell has already
1262 had some initialization performed. This is supposed to reset the world
1263 back to a pristine state, as if we had been exec'ed. */
1264 static void
1265 shell_reinitialize ()
1266 {
1267 /* The default shell prompts. */
1268 primary_prompt = PPROMPT;
1269 secondary_prompt = SPROMPT;
1270
1271 /* Things that get 1. */
1272 current_command_number = 1;
1273
1274 /* We have decided that the ~/.bashrc file should not be executed
1275 for the invocation of each shell script. If the variable $ENV
1276 (or $BASH_ENV) is set, its value is used as the name of a file
1277 to source. */
1278 no_rc = no_profile = 1;
1279
1280 /* Things that get 0. */
1281 login_shell = make_login_shell = interactive = executing = 0;
1282 debugging = do_version = line_number = last_command_exit_value = 0;
1283 forced_interactive = interactive_shell = subshell_environment = 0;
1284 expand_aliases = 0;
1285
1286 #if defined (HISTORY)
1287 bash_history_reinit (0);
1288 #endif /* HISTORY */
1289
1290 #if defined (RESTRICTED_SHELL)
1291 restricted = 0;
1292 #endif /* RESTRICTED_SHELL */
1293
1294 /* Ensure that the default startup file is used. (Except that we don't
1295 execute this file for reinitialized shells). */
1296 bashrc_file = "~/.bashrc";
1297
1298 /* Delete all variables and functions. They will be reinitialized when
1299 the environment is parsed. */
1300 delete_all_variables (shell_variables);
1301 delete_all_variables (shell_functions);
1302
1303 #if 0
1304 /* Pretend the PATH variable has changed. */
1305 flush_hashed_filenames ();
1306 #endif
1307 }
1308
1309 static void
1310 show_shell_usage (fp, extra)
1311 FILE *fp;
1312 int extra;
1313 {
1314 int i;
1315 char *set_opts, *s, *t;
1316
1317 if (extra)
1318 fprintf (fp, "GNU bash, version %s-(%s)\n", shell_version_string (), MACHTYPE);
1319 fprintf (fp, "Usage:\t%s [GNU long option] [option] ...\n\t%s [GNU long option] [option] script-file ...\n",
1320 shell_name, shell_name);
1321 fputs ("GNU long options:\n", fp);
1322 for (i = 0; long_args[i].name; i++)
1323 fprintf (fp, "\t--%s\n", long_args[i].name);
1324
1325 fputs ("Shell options:\n", fp);
1326 fputs ("\t-irsD or -c command\t\t(invocation only)\n", fp);
1327
1328 for (i = 0, set_opts = 0; shell_builtins[i].name; i++)
1329 if (STREQ (shell_builtins[i].name, "set"))
1330 set_opts = savestring (shell_builtins[i].short_doc);
1331 if (set_opts)
1332 {
1333 s = strchr (set_opts, '[');
1334 if (s == 0)
1335 s = set_opts;
1336 while (*++s == '-')
1337 ;
1338 t = strchr (s, ']');
1339 if (t)
1340 *t = '\0';
1341 fprintf (fp, "\t-%s or -o option\n", s);
1342 free (set_opts);
1343 }
1344
1345 if (extra)
1346 {
1347 fprintf (fp, "Type `%s -c \"help set\"' for more information about shell options.\n", shell_name);
1348 fprintf (fp, "Type `%s -c help' for more information about shell builtin commands.\n", shell_name);
1349 fprintf (fp, "Use the `bashbug' command to report bugs.\n");
1350 }
1351 }
1352
1353 /* The second and subsequent conditions must match those used to decide
1354 whether or not to call getpeername() in isnetconn(). */
1355 #if defined (HAVE_SYS_SOCKET_H) && defined (HAVE_GETPEERNAME) && !defined (SVR4_2)
1356 # include <sys/socket.h>
1357 #endif
1358
1359 /* Is FD a socket or network connection? */
1360 static int
1361 isnetconn (fd)
1362 int fd;
1363 {
1364 #if defined (HAVE_GETPEERNAME) && !defined (SVR4_2)
1365 int rv, l;
1366 struct sockaddr sa;
1367
1368 l = sizeof(sa);
1369 rv = getpeername(0, &sa, &l);
1370 /* Solaris 2.5 getpeername() returns EINVAL if the fd is not a socket. */
1371 return ((rv < 0 && (errno == ENOTSOCK || errno == EINVAL)) ? 0 : 1);
1372 #else /* !HAVE_GETPEERNAME || SVR4_2 */
1373 # if defined (SVR4) || defined (SVR4_2)
1374 /* Sockets on SVR4 and SVR4.2 are character special (streams) devices. */
1375 struct stat sb;
1376
1377 if (isatty (fd))
1378 return (0);
1379 if (fstat (fd, &sb) < 0)
1380 return (0);
1381 # if defined (S_ISFIFO)
1382 if (S_ISFIFO (sb.st_mode))
1383 return (0);
1384 # endif /* S_ISFIFO */
1385 return (S_ISCHR (sb.st_mode));
1386 # else /* !SVR4 && !SVR4_2 */
1387 # if defined (S_ISSOCK)
1388 struct stat sb;
1389
1390 if (fstat (fd, &sb) < 0)
1391 return (0);
1392 return (S_ISSOCK (sb.st_mode));
1393 # else /* !S_ISSOCK */
1394 return (0);
1395 # endif /* !S_ISSOCK */
1396 # endif /* !SVR4 && !SVR4_2 */
1397 #endif /* !HAVE_GETPEERNAME || SVR4_2 */
1398 }