You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
310 lines
10 KiB
310 lines
10 KiB
diff -up bash-4.1/builtins.h.requires bash-4.1/builtins.h |
|
--- bash-4.1/builtins.h.requires 2009-01-04 20:32:23.000000000 +0100 |
|
+++ bash-4.1/builtins.h 2010-08-02 17:42:41.000000000 +0200 |
|
@@ -41,6 +41,8 @@ |
|
#define SPECIAL_BUILTIN 0x08 /* This is a Posix `special' builtin. */ |
|
#define ASSIGNMENT_BUILTIN 0x10 /* This builtin takes assignment statements. */ |
|
#define POSIX_BUILTIN 0x20 /* This builtins is special in the Posix command search order. */ |
|
+#define REQUIRES_BUILTIN 0x40 /* This builtin requires other files. */ |
|
+ |
|
|
|
#define BASE_INDENT 4 |
|
|
|
diff -up bash-4.1/builtins/mkbuiltins.c.requires bash-4.1/builtins/mkbuiltins.c |
|
--- bash-4.1/builtins/mkbuiltins.c.requires 2009-01-04 20:32:23.000000000 +0100 |
|
+++ bash-4.1/builtins/mkbuiltins.c 2010-08-02 17:42:41.000000000 +0200 |
|
@@ -69,9 +69,15 @@ extern char *strcpy (); |
|
#define whitespace(c) (((c) == ' ') || ((c) == '\t')) |
|
|
|
/* Flag values that builtins can have. */ |
|
+/* These flags are for the C code generator, |
|
+ the C which is produced (./builtin.c) |
|
+ includes the flags definitions found |
|
+ in ../builtins.h */ |
|
#define BUILTIN_FLAG_SPECIAL 0x01 |
|
#define BUILTIN_FLAG_ASSIGNMENT 0x02 |
|
#define BUILTIN_FLAG_POSIX_BUILTIN 0x04 |
|
+#define BUILTIN_FLAG_REQUIRES 0x08 |
|
+ |
|
|
|
#define BASE_INDENT 4 |
|
|
|
@@ -163,10 +169,18 @@ char *posix_builtins[] = |
|
(char *)NULL |
|
}; |
|
|
|
+/* The builtin commands that cause requirements on other files. */ |
|
+static char *requires_builtins[] = |
|
+{ |
|
+ ".", "command", "exec", "source", "inlib", |
|
+ (char *)NULL |
|
+}; |
|
+ |
|
/* Forward declarations. */ |
|
static int is_special_builtin (); |
|
static int is_assignment_builtin (); |
|
static int is_posix_builtin (); |
|
+static int is_requires_builtin (); |
|
|
|
#if !defined (HAVE_RENAME) |
|
static int rename (); |
|
@@ -812,6 +826,9 @@ builtin_handler (self, defs, arg) |
|
new->flags |= BUILTIN_FLAG_ASSIGNMENT; |
|
if (is_posix_builtin (name)) |
|
new->flags |= BUILTIN_FLAG_POSIX_BUILTIN; |
|
+ if (is_requires_builtin (name)) |
|
+ new->flags |= BUILTIN_FLAG_REQUIRES; |
|
+ |
|
|
|
array_add ((char *)new, defs->builtins); |
|
building_builtin = 1; |
|
@@ -1229,11 +1246,12 @@ write_builtins (defs, structfile, extern |
|
else |
|
fprintf (structfile, "(sh_builtin_func_t *)0x0, "); |
|
|
|
- fprintf (structfile, "%s%s%s%s, %s_doc,\n", |
|
+ fprintf (structfile, "%s%s%s%s%s, %s_doc,\n", |
|
"BUILTIN_ENABLED | STATIC_BUILTIN", |
|
(builtin->flags & BUILTIN_FLAG_SPECIAL) ? " | SPECIAL_BUILTIN" : "", |
|
(builtin->flags & BUILTIN_FLAG_ASSIGNMENT) ? " | ASSIGNMENT_BUILTIN" : "", |
|
(builtin->flags & BUILTIN_FLAG_POSIX_BUILTIN) ? " | POSIX_BUILTIN" : "", |
|
+ (builtin->flags & BUILTIN_FLAG_REQUIRES) ? " | REQUIRES_BUILTIN" : "", |
|
document_name (builtin)); |
|
|
|
fprintf |
|
@@ -1581,6 +1599,13 @@ is_posix_builtin (name) |
|
return (_find_in_table (name, posix_builtins)); |
|
} |
|
|
|
+static int |
|
+is_requires_builtin (name) |
|
+ char *name; |
|
+{ |
|
+ return (_find_in_table (name, requires_builtins)); |
|
+} |
|
+ |
|
#if !defined (HAVE_RENAME) |
|
static int |
|
rename (from, to) |
|
diff -up bash-4.1/doc/bash.1.requires bash-4.1/doc/bash.1 |
|
--- bash-4.1/doc/bash.1.requires 2010-08-02 17:42:41.000000000 +0200 |
|
+++ bash-4.1/doc/bash.1 2010-08-02 18:09:27.000000000 +0200 |
|
@@ -231,6 +231,14 @@ The shell becomes restricted (see |
|
.B "RESTRICTED SHELL" |
|
below). |
|
.TP |
|
+.B \-\-rpm-requires |
|
+Produce the list of files that are required for the |
|
+shell script to run. This implies '-n' and is subject |
|
+to the same limitations as compile time error checking checking; |
|
+Command substitutions, Conditional expressions and |
|
+.BR eval |
|
+builtin are not parsed so some dependencies may be missed. |
|
+.TP |
|
.B \-\-verbose |
|
Equivalent to \fB\-v\fP. |
|
.TP |
|
diff -up bash-4.1/doc/bashref.texi.requires bash-4.1/doc/bashref.texi |
|
--- bash-4.1/doc/bashref.texi.requires 2010-08-02 17:42:41.000000000 +0200 |
|
+++ bash-4.1/doc/bashref.texi 2010-08-02 18:11:58.000000000 +0200 |
|
@@ -5343,6 +5343,13 @@ standard. @xref{Bash POSIX Mode}, for a |
|
@item --restricted |
|
Make the shell a restricted shell (@pxref{The Restricted Shell}). |
|
|
|
+@item --rpm-requires |
|
+Produce the list of files that are required for the |
|
+shell script to run. This implies '-n' and is subject |
|
+to the same limitations as compile time error checking checking; |
|
+Command substitutions, Conditional expressions and @command{eval} |
|
+are not parsed so some dependencies may be missed. |
|
+ |
|
@item --verbose |
|
Equivalent to @option{-v}. Print shell input lines as they're read. |
|
|
|
diff -up bash-4.1/eval.c.requires bash-4.1/eval.c |
|
--- bash-4.1/eval.c.requires 2009-01-04 20:32:26.000000000 +0100 |
|
+++ bash-4.1/eval.c 2010-08-02 17:42:41.000000000 +0200 |
|
@@ -53,6 +53,7 @@ extern int last_command_exit_value, stdi |
|
extern int need_here_doc; |
|
extern int current_command_number, current_command_line_count, line_number; |
|
extern int expand_aliases; |
|
+extern int rpm_requires; |
|
|
|
static void send_pwd_to_eterm __P((void)); |
|
static sighandler alrm_catcher __P((int)); |
|
@@ -136,7 +137,7 @@ reader_loop () |
|
|
|
if (read_command () == 0) |
|
{ |
|
- if (interactive_shell == 0 && read_but_dont_execute) |
|
+ if (interactive_shell == 0 && (read_but_dont_execute && !rpm_requires)) |
|
{ |
|
last_command_exit_value = EXECUTION_SUCCESS; |
|
dispose_command (global_command); |
|
diff -up bash-4.1/execute_cmd.c.requires bash-4.1/execute_cmd.c |
|
--- bash-4.1/execute_cmd.c.requires 2010-08-02 17:42:41.000000000 +0200 |
|
+++ bash-4.1/execute_cmd.c 2010-08-02 17:42:41.000000000 +0200 |
|
@@ -503,6 +503,8 @@ async_redirect_stdin () |
|
|
|
#define DESCRIBE_PID(pid) do { if (interactive) describe_pid (pid); } while (0) |
|
|
|
+extern int rpm_requires; |
|
+ |
|
/* Execute the command passed in COMMAND, perhaps doing it asynchrounously. |
|
COMMAND is exactly what read_command () places into GLOBAL_COMMAND. |
|
ASYNCHROUNOUS, if non-zero, says to do this command in the background. |
|
@@ -534,7 +536,13 @@ execute_command_internal (command, async |
|
#else |
|
if (breaking || continuing) |
|
return (last_command_exit_value); |
|
- if (command == 0 || read_but_dont_execute) |
|
+ if (command == 0 || (read_but_dont_execute && !rpm_requires)) |
|
+ return (EXECUTION_SUCCESS); |
|
+ if (rpm_requires && command->type == cm_function_def) |
|
+ return last_command_exit_value = |
|
+ execute_intern_function (command->value.Function_def->name, |
|
+ command->value.Function_def->command); |
|
+ if (read_but_dont_execute) |
|
return (EXECUTION_SUCCESS); |
|
#endif |
|
|
|
@@ -5066,7 +5074,7 @@ execute_intern_function (name, function) |
|
|
|
if (check_identifier (name, posixly_correct) == 0) |
|
{ |
|
- if (posixly_correct && interactive_shell == 0) |
|
+ if (posixly_correct && interactive_shell == 0 && rpm_requires == 0) |
|
{ |
|
last_command_exit_value = EX_BADUSAGE; |
|
jump_to_top_level (ERREXIT); |
|
diff -up bash-4.1/execute_cmd.h.requires bash-4.1/execute_cmd.h |
|
--- bash-4.1/execute_cmd.h.requires 2009-01-16 22:20:15.000000000 +0100 |
|
+++ bash-4.1/execute_cmd.h 2010-08-02 17:42:41.000000000 +0200 |
|
@@ -22,6 +22,8 @@ |
|
#define _EXECUTE_CMD_H_ |
|
|
|
#include "stdc.h" |
|
+#include "variables.h" |
|
+#include "command.h" |
|
|
|
extern struct fd_bitmap *new_fd_bitmap __P((int)); |
|
extern void dispose_fd_bitmap __P((struct fd_bitmap *)); |
|
diff -up bash-4.1/make_cmd.c.requires bash-4.1/make_cmd.c |
|
--- bash-4.1/make_cmd.c.requires 2009-09-11 23:26:12.000000000 +0200 |
|
+++ bash-4.1/make_cmd.c 2010-08-02 17:42:41.000000000 +0200 |
|
@@ -42,11 +42,15 @@ |
|
#include "flags.h" |
|
#include "make_cmd.h" |
|
#include "dispose_cmd.h" |
|
+#include "execute_cmd.h" |
|
#include "variables.h" |
|
#include "subst.h" |
|
#include "input.h" |
|
#include "ocache.h" |
|
#include "externs.h" |
|
+#include "builtins.h" |
|
+ |
|
+#include "builtins/common.h" |
|
|
|
#if defined (JOB_CONTROL) |
|
#include "jobs.h" |
|
@@ -56,6 +60,10 @@ |
|
|
|
extern int line_number, current_command_line_count, parser_state; |
|
extern int last_command_exit_value; |
|
+extern int rpm_requires; |
|
+ |
|
+static char *alphabet_set = "abcdefghijklmnopqrstuvwxyz" |
|
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; |
|
|
|
/* Object caching */ |
|
sh_obj_cache_t wdcache = {0, 0, 0}; |
|
@@ -820,6 +828,27 @@ make_coproc_command (name, command) |
|
return (make_command (cm_coproc, (SIMPLE_COM *)temp)); |
|
} |
|
|
|
+static void |
|
+output_requirement (deptype, filename) |
|
+const char *deptype; |
|
+char *filename; |
|
+{ |
|
+ if (strchr(filename, '$') || (filename[0] != '/' && strchr(filename, '/'))) |
|
+ return; |
|
+ |
|
+ /* |
|
+ if the executable is called via variable substitution we can |
|
+ not dermine what it is at compile time. |
|
+ |
|
+ if the executable consists only of characters not in the |
|
+ alphabet we do not consider it a dependency just an artifact |
|
+ of shell parsing (ex "exec < ${infile}"). |
|
+ */ |
|
+ |
|
+ if (strpbrk(filename, alphabet_set)) |
|
+ printf ("%s(%s)\n", deptype, filename); |
|
+} |
|
+ |
|
/* Reverse the word list and redirection list in the simple command |
|
has just been parsed. It seems simpler to do this here the one |
|
time then by any other method that I can think of. */ |
|
@@ -837,6 +866,27 @@ clean_simple_command (command) |
|
REVERSE_LIST (command->value.Simple->redirects, REDIRECT *); |
|
} |
|
|
|
+ if (rpm_requires && command->value.Simple->words) |
|
+ { |
|
+ char *cmd0; |
|
+ char *cmd1; |
|
+ struct builtin *b; |
|
+ |
|
+ cmd0 = command->value.Simple->words->word->word; |
|
+ b = builtin_address_internal (cmd0, 0); |
|
+ cmd1 = 0; |
|
+ if (command->value.Simple->words->next) |
|
+ cmd1 = command->value.Simple->words->next->word->word; |
|
+ |
|
+ if (b) { |
|
+ if ( (b->flags & REQUIRES_BUILTIN) && cmd1) |
|
+ output_requirement ("executable", cmd1); |
|
+ } else { |
|
+ if (!assignment(cmd0, 0)) |
|
+ output_requirement (find_function(cmd0) ? "function" : "executable", cmd0); |
|
+ } |
|
+ } /*rpm_requires*/ |
|
+ |
|
parser_state &= ~PST_REDIRLIST; |
|
return (command); |
|
} |
|
diff -up bash-4.1/shell.c.requires bash-4.1/shell.c |
|
--- bash-4.1/shell.c.requires 2010-08-02 17:42:41.000000000 +0200 |
|
+++ bash-4.1/shell.c 2010-08-02 17:42:41.000000000 +0200 |
|
@@ -193,6 +193,9 @@ int have_devfd = 0; |
|
/* The name of the .(shell)rc file. */ |
|
static char *bashrc_file = "~/.bashrc"; |
|
|
|
+/* Non-zero if we are finding the scripts requirements. */ |
|
+int rpm_requires; |
|
+ |
|
/* Non-zero means to act more like the Bourne shell on startup. */ |
|
static int act_like_sh; |
|
|
|
@@ -251,6 +254,7 @@ static const struct { |
|
{ "posix", Int, &posixly_correct, (char **)0x0 }, |
|
{ "protected", Int, &protected_mode, (char **)0x0 }, |
|
{ "rcfile", Charp, (int *)0x0, &bashrc_file }, |
|
+ { "rpm-requires", Int, &rpm_requires, (char **)0x0 }, |
|
#if defined (RESTRICTED_SHELL) |
|
{ "restricted", Int, &restricted, (char **)0x0 }, |
|
#endif |
|
@@ -485,6 +489,12 @@ main (argc, argv, env) |
|
if (dump_translatable_strings) |
|
read_but_dont_execute = 1; |
|
|
|
+ if (rpm_requires) |
|
+ { |
|
+ read_but_dont_execute = 1; |
|
+ initialize_shell_builtins (); |
|
+ } |
|
+ |
|
if (running_setuid && privileged_mode == 0) |
|
disable_priv_mode ();
|
|
|