Blame SOURCES/bash-requires.patch

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