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