Blame SOURCES/bash-requires.patch

e6eb8e
diff --git a/builtins.h b/builtins.h
e6eb8e
index 0cfea18..a6ef958 100644
e6eb8e
--- a/builtins.h
e6eb8e
+++ b/builtins.h
e6eb8e
@@ -42,6 +42,7 @@
e6eb8e
 #define ASSIGNMENT_BUILTIN 0x10	/* This builtin takes assignment statements. */
e6eb8e
 #define POSIX_BUILTIN	0x20	/* This builtins is special in the Posix command search order. */
e6eb8e
 #define LOCALVAR_BUILTIN   0x40	/* This builtin creates local variables */
e6eb8e
+#define REQUIRES_BUILTIN 0x80  /* This builtin requires other files. */
e6eb8e
 
e6eb8e
 #define BASE_INDENT	4
e6eb8e
 
e6eb8e
diff --git a/builtins/mkbuiltins.c b/builtins/mkbuiltins.c
e6eb8e
index 4f51201..283bfea 100644
e6eb8e
--- a/builtins/mkbuiltins.c
e6eb8e
+++ b/builtins/mkbuiltins.c
e6eb8e
@@ -69,10 +69,15 @@ extern char *strcpy ();
e6eb8e
 #define whitespace(c) (((c) == ' ') || ((c) == '\t'))
e6eb8e
 
e6eb8e
 /* Flag values that builtins can have. */
e6eb8e
+/*  These flags are for the C code generator, 
e6eb8e
+    the C which is produced (./builtin.c)
e6eb8e
+    includes the flags definitions found 
e6eb8e
+    in ../builtins.h */
e6eb8e
 #define BUILTIN_FLAG_SPECIAL	0x01
e6eb8e
 #define BUILTIN_FLAG_ASSIGNMENT 0x02
e6eb8e
 #define BUILTIN_FLAG_LOCALVAR	0x04
e6eb8e
 #define BUILTIN_FLAG_POSIX_BUILTIN 0x08
e6eb8e
+#define BUILTIN_FLAG_REQUIRES  0x10
e6eb8e
 
e6eb8e
 #define BASE_INDENT	4
e6eb8e
 
e6eb8e
@@ -173,11 +178,20 @@ char *posix_builtins[] =
e6eb8e
   (char *)NULL
e6eb8e
 };
e6eb8e
 
e6eb8e
+/* The builtin commands that cause requirements on other files. */
e6eb8e
+static char *requires_builtins[] =
e6eb8e
+{
e6eb8e
+  ".", "command", "exec", "source", "inlib",
e6eb8e
+  (char *)NULL
e6eb8e
+};
e6eb8e
+
e6eb8e
+
e6eb8e
 /* Forward declarations. */
e6eb8e
 static int is_special_builtin ();
e6eb8e
 static int is_assignment_builtin ();
e6eb8e
 static int is_localvar_builtin ();
e6eb8e
 static int is_posix_builtin ();
e6eb8e
+static int is_requires_builtin ();
e6eb8e
 
e6eb8e
 #if !defined (HAVE_RENAME)
e6eb8e
 static int rename ();
e6eb8e
@@ -831,6 +845,9 @@ builtin_handler (self, defs, arg)
e6eb8e
     new->flags |= BUILTIN_FLAG_LOCALVAR;
e6eb8e
   if (is_posix_builtin (name))
e6eb8e
     new->flags |= BUILTIN_FLAG_POSIX_BUILTIN;
e6eb8e
+  if (is_requires_builtin (name))
e6eb8e
+    new->flags |= BUILTIN_FLAG_REQUIRES;
e6eb8e
+
e6eb8e
 
e6eb8e
   array_add ((char *)new, defs->builtins);
e6eb8e
   building_builtin = 1;
e6eb8e
@@ -1250,12 +1267,13 @@ write_builtins (defs, structfile, externfile)
e6eb8e
 		  else
e6eb8e
 		    fprintf (structfile, "(sh_builtin_func_t *)0x0, ");
e6eb8e
 
e6eb8e
-		  fprintf (structfile, "%s%s%s%s%s, %s_doc,\n",
e6eb8e
+		  fprintf (structfile, "%s%s%s%s%s%s, %s_doc,\n",
e6eb8e
 		    "BUILTIN_ENABLED | STATIC_BUILTIN",
e6eb8e
 		    (builtin->flags & BUILTIN_FLAG_SPECIAL) ? " | SPECIAL_BUILTIN" : "",
e6eb8e
 		    (builtin->flags & BUILTIN_FLAG_ASSIGNMENT) ? " | ASSIGNMENT_BUILTIN" : "",
e6eb8e
 		    (builtin->flags & BUILTIN_FLAG_LOCALVAR) ? " | LOCALVAR_BUILTIN" : "",
e6eb8e
 		    (builtin->flags & BUILTIN_FLAG_POSIX_BUILTIN) ? " | POSIX_BUILTIN" : "",
e6eb8e
+		    (builtin->flags & BUILTIN_FLAG_REQUIRES) ? " | REQUIRES_BUILTIN" : "",
e6eb8e
 		    document_name (builtin));
e6eb8e
 
e6eb8e
 		  /* Don't translate short document summaries that are identical
e6eb8e
@@ -1645,6 +1663,13 @@ is_posix_builtin (name)
e6eb8e
   return (_find_in_table (name, posix_builtins));
e6eb8e
 }
e6eb8e
 
e6eb8e
+static int
e6eb8e
+is_requires_builtin (name)
e6eb8e
+     char *name;
e6eb8e
+{
e6eb8e
+  return (_find_in_table (name, requires_builtins));
e6eb8e
+}
e6eb8e
+
e6eb8e
 #if !defined (HAVE_RENAME)
e6eb8e
 static int
e6eb8e
 rename (from, to)
e6eb8e
diff --git a/doc/bash.1 b/doc/bash.1
e6eb8e
index c21e877..04ce845 100644
e6eb8e
--- a/doc/bash.1
e6eb8e
+++ b/doc/bash.1
e6eb8e
@@ -238,6 +238,14 @@ The shell becomes restricted (see
e6eb8e
 .B "RESTRICTED SHELL"
e6eb8e
 below).
e6eb8e
 .TP
e6eb8e
+.B \-\-rpm-requires
e6eb8e
+Produce the list of files that are required for the 
e6eb8e
+shell script to run.  This implies '-n' and is subject
e6eb8e
+to the same limitations as compile time error checking checking;
e6eb8e
+Command substitutions, Conditional expressions and
e6eb8e
+.BR eval
e6eb8e
+builtin are not parsed so some dependencies may be missed.
e6eb8e
+.TP
e6eb8e
 .B \-\-verbose
e6eb8e
 Equivalent to \fB\-v\fP.
e6eb8e
 .TP
e6eb8e
diff --git a/doc/bashref.texi b/doc/bashref.texi
e6eb8e
index 06957b6..e3fe925 100644
e6eb8e
--- a/doc/bashref.texi
e6eb8e
+++ b/doc/bashref.texi
e6eb8e
@@ -6243,6 +6243,13 @@ standard.  @xref{Bash POSIX Mode}, for a description of the Bash
e6eb8e
 @item --restricted
e6eb8e
 Make the shell a restricted shell (@pxref{The Restricted Shell}).
e6eb8e
 
e6eb8e
+@item --rpm-requires
e6eb8e
+Produce the list of files that are required for the 
e6eb8e
+shell script to run.  This implies '-n' and is subject
e6eb8e
+to the same limitations as compile time error checking checking;
e6eb8e
+Command substitutions, Conditional expressions and @command{eval}
e6eb8e
+are not parsed so some dependencies may be missed.
e6eb8e
+
e6eb8e
 @item --verbose
e6eb8e
 Equivalent to @option{-v}.  Print shell input lines as they're read.
e6eb8e
 
e6eb8e
diff --git a/eval.c b/eval.c
e6eb8e
index db863e7..5a5af32 100644
e6eb8e
--- a/eval.c
e6eb8e
+++ b/eval.c
e6eb8e
@@ -56,6 +56,7 @@ extern int need_here_doc;
e6eb8e
 extern int current_command_number, current_command_line_count, line_number;
e6eb8e
 extern int expand_aliases;
e6eb8e
 extern char *ps0_prompt;
e6eb8e
+extern int rpm_requires;
e6eb8e
 
e6eb8e
 #if defined (HAVE_POSIX_SIGNALS)
e6eb8e
 extern sigset_t top_level_mask;
e6eb8e
@@ -148,7 +149,7 @@ reader_loop ()
e6eb8e
 
e6eb8e
       if (read_command () == 0)
e6eb8e
 	{
e6eb8e
-	  if (interactive_shell == 0 && read_but_dont_execute)
e6eb8e
+	  if (interactive_shell == 0 && (read_but_dont_execute && !rpm_requires))
e6eb8e
 	    {
e6eb8e
 	      last_command_exit_value = EXECUTION_SUCCESS;
e6eb8e
 	      dispose_command (global_command);
e6eb8e
diff --git a/execute_cmd.c b/execute_cmd.c
e6eb8e
index b5cd405..88c7a5c 100644
e6eb8e
--- a/execute_cmd.c
e6eb8e
+++ b/execute_cmd.c
e6eb8e
@@ -533,6 +533,8 @@ async_redirect_stdin ()
e6eb8e
 
e6eb8e
 #define DESCRIBE_PID(pid) do { if (interactive) describe_pid (pid); } while (0)
e6eb8e
 
e6eb8e
+extern int rpm_requires;
e6eb8e
+
e6eb8e
 /* Execute the command passed in COMMAND, perhaps doing it asynchronously.
e6eb8e
    COMMAND is exactly what read_command () places into GLOBAL_COMMAND.
e6eb8e
    ASYNCHROUNOUS, if non-zero, says to do this command in the background.
e6eb8e
@@ -565,7 +567,13 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
e6eb8e
 
e6eb8e
   if (breaking || continuing)
e6eb8e
     return (last_command_exit_value);
e6eb8e
-  if (command == 0 || read_but_dont_execute)
e6eb8e
+  if (command == 0 || (read_but_dont_execute && !rpm_requires))
e6eb8e
+    return (EXECUTION_SUCCESS);
e6eb8e
+  if (rpm_requires && command->type == cm_function_def)
e6eb8e
+    return last_command_exit_value =
e6eb8e
+      execute_intern_function (command->value.Function_def->name,
e6eb8e
+                              command->value.Function_def);
e6eb8e
+  if (read_but_dont_execute)
e6eb8e
     return (EXECUTION_SUCCESS);
e6eb8e
 
e6eb8e
   QUIT;
e6eb8e
@@ -5752,7 +5760,7 @@ execute_intern_function (name, funcdef)
e6eb8e
 
e6eb8e
   if (check_identifier (name, posixly_correct) == 0)
e6eb8e
     {
e6eb8e
-      if (posixly_correct && interactive_shell == 0)
e6eb8e
+      if (posixly_correct && interactive_shell == 0 && rpm_requires == 0)
e6eb8e
 	{
e6eb8e
 	  last_command_exit_value = EX_BADUSAGE;
e6eb8e
 	  jump_to_top_level (ERREXIT);
e6eb8e
diff --git a/execute_cmd.h b/execute_cmd.h
e6eb8e
index 62bec82..d42dc85 100644
e6eb8e
--- a/execute_cmd.h
e6eb8e
+++ b/execute_cmd.h
e6eb8e
@@ -22,6 +22,8 @@
e6eb8e
 #define _EXECUTE_CMD_H_
e6eb8e
 
e6eb8e
 #include "stdc.h"
e6eb8e
+#include "variables.h"
e6eb8e
+#include "command.h"
e6eb8e
 
e6eb8e
 #if defined (ARRAY_VARS)
e6eb8e
 struct func_array_state
e6eb8e
diff --git a/make_cmd.c b/make_cmd.c
e6eb8e
index b42e9ff..a982fe0 100644
e6eb8e
--- a/make_cmd.c
e6eb8e
+++ b/make_cmd.c
e6eb8e
@@ -42,11 +42,15 @@
e6eb8e
 #include "flags.h"
e6eb8e
 #include "make_cmd.h"
e6eb8e
 #include "dispose_cmd.h"
e6eb8e
+#include "execute_cmd.h"
e6eb8e
 #include "variables.h"
e6eb8e
 #include "subst.h"
e6eb8e
 #include "input.h"
e6eb8e
 #include "ocache.h"
e6eb8e
 #include "externs.h"
e6eb8e
+#include "builtins.h"
e6eb8e
+
e6eb8e
+#include "builtins/common.h"
e6eb8e
 
e6eb8e
 #if defined (JOB_CONTROL)
e6eb8e
 #include "jobs.h"
e6eb8e
@@ -57,6 +61,10 @@
e6eb8e
 extern int line_number, current_command_line_count, parser_state;
e6eb8e
 extern int last_command_exit_value;
e6eb8e
 extern int shell_initialized;
e6eb8e
+extern int rpm_requires;
e6eb8e
+
e6eb8e
+static char *alphabet_set = "abcdefghijklmnopqrstuvwxyz"
e6eb8e
+                     "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
e6eb8e
 
e6eb8e
 int here_doc_first_line = 0;
e6eb8e
 
e6eb8e
@@ -839,6 +847,27 @@ make_coproc_command (name, command)
e6eb8e
   return (make_command (cm_coproc, (SIMPLE_COM *)temp));
e6eb8e
 }
e6eb8e
 
e6eb8e
+static void
e6eb8e
+output_requirement (deptype, filename)
e6eb8e
+const char *deptype;
e6eb8e
+char *filename;
e6eb8e
+{
e6eb8e
+  if (strchr(filename, '$') || (filename[0] != '/' && strchr(filename, '/')))
e6eb8e
+    return;
e6eb8e
+
e6eb8e
+  /* 
e6eb8e
+      if the executable is called via variable substitution we can
e6eb8e
+      not dermine what it is at compile time.  
e6eb8e
+
e6eb8e
+      if the executable consists only of characters not in the
e6eb8e
+      alphabet we do not consider it a dependency just an artifact
e6eb8e
+      of shell parsing (ex "exec < ${infile}").
e6eb8e
+  */
e6eb8e
+
e6eb8e
+  if (strpbrk(filename, alphabet_set))
e6eb8e
+    printf ("%s(%s)\n", deptype, filename);
e6eb8e
+}
e6eb8e
+
e6eb8e
 /* Reverse the word list and redirection list in the simple command
e6eb8e
    has just been parsed.  It seems simpler to do this here the one
e6eb8e
    time then by any other method that I can think of. */
e6eb8e
@@ -856,6 +885,27 @@ clean_simple_command (command)
e6eb8e
 	REVERSE_LIST (command->value.Simple->redirects, REDIRECT *);
e6eb8e
     }
e6eb8e
 
e6eb8e
+  if (rpm_requires && command->value.Simple->words)
e6eb8e
+    {
e6eb8e
+      char *cmd0;
e6eb8e
+      char *cmd1;
e6eb8e
+      struct builtin *b;
e6eb8e
+
e6eb8e
+      cmd0 = command->value.Simple->words->word->word;
e6eb8e
+      b = builtin_address_internal (cmd0, 0);
e6eb8e
+      cmd1 = 0;
e6eb8e
+      if (command->value.Simple->words->next)
e6eb8e
+        cmd1 = command->value.Simple->words->next->word->word;
e6eb8e
+
e6eb8e
+      if (b) {
e6eb8e
+        if ( (b->flags & REQUIRES_BUILTIN) && cmd1)
e6eb8e
+          output_requirement ("executable", cmd1);
e6eb8e
+      } else {
e6eb8e
+        if (!assignment(cmd0, 0))
e6eb8e
+          output_requirement (find_function(cmd0) ? "function" : "executable", cmd0);
e6eb8e
+      }
e6eb8e
+    } /*rpm_requires*/
e6eb8e
+
e6eb8e
   parser_state &= ~PST_REDIRLIST;
e6eb8e
   return (command);
e6eb8e
 }
e6eb8e
diff --git a/shell.c b/shell.c
e6eb8e
index 7f63969..a0fb7ce 100644
e6eb8e
--- a/shell.c
e6eb8e
+++ b/shell.c
e6eb8e
@@ -201,6 +201,9 @@ int have_devfd = 0;
e6eb8e
 /* The name of the .(shell)rc file. */
e6eb8e
 static char *bashrc_file = DEFAULT_BASHRC;
e6eb8e
 
e6eb8e
+/* Non-zero if we are finding the scripts requirements. */
e6eb8e
+int rpm_requires;
e6eb8e
+
e6eb8e
 /* Non-zero means to act more like the Bourne shell on startup. */
e6eb8e
 static int act_like_sh;
e6eb8e
 
e6eb8e
@@ -264,6 +267,7 @@ static const struct {
e6eb8e
   { "protected", Int, &protected_mode, (char **)0x0 },
e6eb8e
 #endif
e6eb8e
   { "rcfile", Charp, (int *)0x0, &bashrc_file },
e6eb8e
+  { "rpm-requires", Int, &rpm_requires, (char **)0x0 },
e6eb8e
 #if defined (RESTRICTED_SHELL)
e6eb8e
   { "restricted", Int, &restricted, (char **)0x0 },
e6eb8e
 #endif
e6eb8e
@@ -500,6 +504,12 @@ main (argc, argv, env)
e6eb8e
   if (dump_translatable_strings)
e6eb8e
     read_but_dont_execute = 1;
e6eb8e
 
e6eb8e
+  if (rpm_requires)
e6eb8e
+    {
e6eb8e
+      read_but_dont_execute = 1;
e6eb8e
+      initialize_shell_builtins ();
e6eb8e
+    }
e6eb8e
+
e6eb8e
   if (running_setuid && privileged_mode == 0)
e6eb8e
     disable_priv_mode ();
e6eb8e
 
e6eb8e
-- 
e6eb8e
2.9.3
e6eb8e