1 /* evalfile.c - read and evaluate commands from a file or file descriptor */
2 
3 /* Copyright (C) 1996-2017 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
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation, either version 3 of the License, or
10    (at your option) any later version.
11 
12    Bash is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #include <config.h>
22 
23 #if defined (HAVE_UNISTD_H)
24 #  include <unistd.h>
25 #endif
26 
27 #include "../bashtypes.h"
28 #include "posixstat.h"
29 #include "filecntl.h"
30 
31 #include <stdio.h>
32 #include <signal.h>
33 #include <errno.h>
34 
35 #include "../bashansi.h"
36 #include "../bashintl.h"
37 
38 #include "../shell.h"
39 #include "../parser.h"
40 #include "../jobs.h"
41 #include "../builtins.h"
42 #include "../flags.h"
43 #include "../input.h"
44 #include "../execute_cmd.h"
45 #include "../trap.h"
46 
47 #include <y.tab.h>
48 
49 #if defined (HISTORY)
50 #  include "../bashhist.h"
51 #endif
52 
53 #include <typemax.h>
54 
55 #include "common.h"
56 
57 #if !defined (errno)
58 extern int errno;
59 #endif
60 
61 /* Flags for _evalfile() */
62 #define FEVAL_ENOENTOK		0x001
63 #define FEVAL_BUILTIN		0x002
64 #define FEVAL_UNWINDPROT	0x004
65 #define FEVAL_NONINT		0x008
66 #define FEVAL_LONGJMP		0x010
67 #define FEVAL_HISTORY		0x020
68 #define FEVAL_CHECKBINARY	0x040
69 #define FEVAL_REGFILE		0x080
70 #define FEVAL_NOPUSHARGS	0x100
71 
72 /* How many `levels' of sourced files we have. */
73 int sourcelevel = 0;
74 
75 static int
_evalfile(filename,flags)76 _evalfile (filename, flags)
77      const char *filename;
78      int flags;
79 {
80   volatile int old_interactive;
81   procenv_t old_return_catch;
82   int return_val, fd, result, pflags, i, nnull;
83   ssize_t nr;			/* return value from read(2) */
84   char *string;
85   struct stat finfo;
86   size_t file_size;
87   sh_vmsg_func_t *errfunc;
88 #if defined (ARRAY_VARS)
89   SHELL_VAR *funcname_v, *bash_source_v, *bash_lineno_v;
90   ARRAY *funcname_a, *bash_source_a, *bash_lineno_a;
91   struct func_array_state *fa;
92 #  if defined (DEBUGGER)
93   SHELL_VAR *bash_argv_v, *bash_argc_v;
94   ARRAY *bash_argv_a, *bash_argc_a;
95 #  endif
96   char *t, tt[2];
97 #endif
98 
99   USE_VAR(pflags);
100 
101 #if defined (ARRAY_VARS)
102   GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a);
103   GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
104   GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a);
105 #  if defined (DEBUGGER)
106   GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
107   GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
108 #  endif
109 #endif
110 
111   fd = open (filename, O_RDONLY);
112 
113   if (fd < 0 || (fstat (fd, &finfo) == -1))
114     {
115       i = errno;
116       if (fd >= 0)
117 	close (fd);
118       errno = i;
119 
120 file_error_and_exit:
121       if (((flags & FEVAL_ENOENTOK) == 0) || errno != ENOENT)
122 	file_error (filename);
123 
124       if (flags & FEVAL_LONGJMP)
125 	{
126 	  last_command_exit_value = EXECUTION_FAILURE;
127 	  jump_to_top_level (EXITPROG);
128 	}
129 
130       return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE
131       				      : ((errno == ENOENT && (flags & FEVAL_ENOENTOK) != 0) ? 0 : -1));
132     }
133 
134   errfunc = ((flags & FEVAL_BUILTIN) ? builtin_error : internal_error);
135 
136   if (S_ISDIR (finfo.st_mode))
137     {
138       (*errfunc) (_("%s: is a directory"), filename);
139       close (fd);
140       return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
141     }
142   else if ((flags & FEVAL_REGFILE) && S_ISREG (finfo.st_mode) == 0)
143     {
144       (*errfunc) (_("%s: not a regular file"), filename);
145       close (fd);
146       return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
147     }
148 
149   file_size = (size_t)finfo.st_size;
150   /* Check for overflow with large files. */
151   if (file_size != finfo.st_size || file_size + 1 < file_size)
152     {
153       (*errfunc) (_("%s: file is too large"), filename);
154       close (fd);
155       return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
156     }
157 
158   if (S_ISREG (finfo.st_mode) && file_size <= SSIZE_MAX)
159     {
160       string = (char *)xmalloc (1 + file_size);
161       nr = read (fd, string, file_size);
162       if (nr >= 0)
163 	string[nr] = '\0';
164     }
165   else
166     nr = zmapfd (fd, &string, 0);
167 
168   return_val = errno;
169   close (fd);
170   errno = return_val;
171 
172   if (nr < 0)		/* XXX was != file_size, not < 0 */
173     {
174       free (string);
175       goto file_error_and_exit;
176     }
177 
178   if (nr == 0)
179     {
180       free (string);
181       return ((flags & FEVAL_BUILTIN) ? EXECUTION_SUCCESS : 1);
182     }
183 
184   if ((flags & FEVAL_CHECKBINARY) &&
185       check_binary_file (string, (nr > 80) ? 80 : nr))
186     {
187       free (string);
188       (*errfunc) (_("%s: cannot execute binary file"), filename);
189       return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1);
190     }
191 
192   i = strlen (string);
193   if (i < nr)
194     {
195       for (nnull = i = 0; i < nr; i++)
196 	if (string[i] == '\0')
197           {
198 	    memmove (string+i, string+i+1, nr - i);
199 	    nr--;
200 	    /* Even if the `check binary' flag is not set, we want to avoid
201 	       sourcing files with more than 256 null characters -- that
202 	       probably indicates a binary file. */
203 	    if ((flags & FEVAL_BUILTIN) && ++nnull > 256)
204 	      {
205 		free (string);
206 		(*errfunc) (_("%s: cannot execute binary file"), filename);
207 		return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1);
208 	      }
209           }
210     }
211 
212   if (flags & FEVAL_UNWINDPROT)
213     {
214       begin_unwind_frame ("_evalfile");
215 
216       unwind_protect_int (return_catch_flag);
217       unwind_protect_jmp_buf (return_catch);
218       if (flags & FEVAL_NONINT)
219 	unwind_protect_int (interactive);
220       unwind_protect_int (sourcelevel);
221     }
222   else
223     {
224       COPY_PROCENV (return_catch, old_return_catch);
225       if (flags & FEVAL_NONINT)
226 	old_interactive = interactive;
227     }
228 
229   if (flags & FEVAL_NONINT)
230     interactive = 0;
231 
232   return_catch_flag++;
233   sourcelevel++;
234 
235 #if defined (ARRAY_VARS)
236   array_push (bash_source_a, (char *)filename);
237   t = itos (executing_line_number ());
238   array_push (bash_lineno_a, t);
239   free (t);
240   array_push (funcname_a, "source");	/* not exactly right */
241 
242   fa = (struct func_array_state *)xmalloc (sizeof (struct func_array_state));
243   fa->source_a = bash_source_a;
244   fa->source_v = bash_source_v;
245   fa->lineno_a = bash_lineno_a;
246   fa->lineno_v = bash_lineno_v;
247   fa->funcname_a = funcname_a;
248   fa->funcname_v = funcname_v;
249   if (flags & FEVAL_UNWINDPROT)
250     add_unwind_protect (restore_funcarray_state, fa);
251 
252 #  if defined (DEBUGGER)
253   /* Have to figure out a better way to do this when `source' is supplied
254      arguments */
255   if ((flags & FEVAL_NOPUSHARGS) == 0)
256     {
257       if (shell_compatibility_level <= 44)
258 	init_bash_argv ();
259       array_push (bash_argv_a, (char *)filename);	/* XXX - unconditionally? */
260       tt[0] = '1'; tt[1] = '\0';
261       array_push (bash_argc_a, tt);
262       if (flags & FEVAL_UNWINDPROT)
263 	add_unwind_protect (pop_args, 0);
264     }
265 #  endif
266 #endif
267 
268   /* set the flags to be passed to parse_and_execute */
269   pflags = SEVAL_RESETLINE;
270   pflags |= (flags & FEVAL_HISTORY) ? 0 : SEVAL_NOHIST;
271 
272   if (flags & FEVAL_BUILTIN)
273     result = EXECUTION_SUCCESS;
274 
275   return_val = setjmp_nosigs (return_catch);
276 
277   /* If `return' was seen outside of a function, but in the script, then
278      force parse_and_execute () to clean up. */
279   if (return_val)
280     {
281       parse_and_execute_cleanup (-1);
282       result = return_catch_value;
283     }
284   else
285     result = parse_and_execute (string, filename, pflags);
286 
287   if (flags & FEVAL_UNWINDPROT)
288     run_unwind_frame ("_evalfile");
289   else
290     {
291       if (flags & FEVAL_NONINT)
292 	interactive = old_interactive;
293 #if defined (ARRAY_VARS)
294       restore_funcarray_state (fa);
295 #  if defined (DEBUGGER)
296       if ((flags & FEVAL_NOPUSHARGS) == 0)
297 	{
298 	  /* Don't need to call pop_args here until we do something better
299 	     when source is passed arguments (see above). */
300 	  array_pop (bash_argc_a);
301 	  array_pop (bash_argv_a);
302 	}
303 #  endif
304 #endif
305       return_catch_flag--;
306       sourcelevel--;
307       COPY_PROCENV (old_return_catch, return_catch);
308     }
309 
310   /* If we end up with EOF after sourcing a file, which can happen when the file
311      doesn't end with a newline, pretend that it did. */
312   if (current_token == yacc_EOF)
313     push_token ('\n');		/* XXX */
314 
315   return ((flags & FEVAL_BUILTIN) ? result : 1);
316 }
317 
318 int
maybe_execute_file(fname,force_noninteractive)319 maybe_execute_file (fname, force_noninteractive)
320      const char *fname;
321      int force_noninteractive;
322 {
323   char *filename;
324   int result, flags;
325 
326   filename = bash_tilde_expand (fname, 0);
327   flags = FEVAL_ENOENTOK;
328   if (force_noninteractive)
329     flags |= FEVAL_NONINT;
330   result = _evalfile (filename, flags);
331   free (filename);
332   return result;
333 }
334 
335 int
force_execute_file(fname,force_noninteractive)336 force_execute_file (fname, force_noninteractive)
337      const char *fname;
338      int force_noninteractive;
339 {
340   char *filename;
341   int result, flags;
342 
343   filename = bash_tilde_expand (fname, 0);
344   flags = 0;
345   if (force_noninteractive)
346     flags |= FEVAL_NONINT;
347   result = _evalfile (filename, flags);
348   free (filename);
349   return result;
350 }
351 
352 #if defined (HISTORY)
353 int
fc_execute_file(filename)354 fc_execute_file (filename)
355      const char *filename;
356 {
357   int flags;
358 
359   /* We want these commands to show up in the history list if
360      remember_on_history is set.  We use FEVAL_BUILTIN to return
361      the result of parse_and_execute. */
362   flags = FEVAL_ENOENTOK|FEVAL_HISTORY|FEVAL_REGFILE|FEVAL_BUILTIN;
363   return (_evalfile (filename, flags));
364 }
365 #endif /* HISTORY */
366 
367 int
source_file(filename,sflags)368 source_file (filename, sflags)
369      const char *filename;
370      int sflags;
371 {
372   int flags, rval;
373 
374   flags = FEVAL_BUILTIN|FEVAL_UNWINDPROT|FEVAL_NONINT;
375   if (sflags)
376     flags |= FEVAL_NOPUSHARGS;
377   /* POSIX shells exit if non-interactive and file error. */
378   if (posixly_correct && interactive_shell == 0 && executing_command_builtin == 0)
379     flags |= FEVAL_LONGJMP;
380   rval = _evalfile (filename, flags);
381 
382   run_return_trap ();
383   return rval;
384 }
385