Roman Rakus 5f19b4
diff -up bash-4.1/builtins.h.requires bash-4.1/builtins.h
Roman Rakus 5f19b4
--- bash-4.1/builtins.h.requires	2009-01-04 20:32:23.000000000 +0100
Roman Rakus 5ab66f
+++ bash-4.1/builtins.h	2010-08-02 17:42:41.000000000 +0200
Roman Rakus f2e7e1
@@ -41,6 +41,8 @@
Roman Rakus f2e7e1
 #define SPECIAL_BUILTIN 0x08	/* This is a Posix `special' builtin. */
Roman Rakus f2e7e1
 #define ASSIGNMENT_BUILTIN 0x10	/* This builtin takes assignment statements. */
Roman Rakus f2e7e1
 #define POSIX_BUILTIN	0x20	/* This builtins is special in the Posix command search order. */
Roman Rakus f2e7e1
+#define REQUIRES_BUILTIN 0x40	/* This builtin requires other files. */
Tim Waugh 6353ab
+
Tim Waugh 6353ab
 
Roman Rakus f2e7e1
 #define BASE_INDENT	4
Tim Waugh 6353ab
 
Roman Rakus 5f19b4
diff -up bash-4.1/builtins/mkbuiltins.c.requires bash-4.1/builtins/mkbuiltins.c
Roman Rakus 5f19b4
--- bash-4.1/builtins/mkbuiltins.c.requires	2009-01-04 20:32:23.000000000 +0100
Roman Rakus 5ab66f
+++ bash-4.1/builtins/mkbuiltins.c	2010-08-02 17:42:41.000000000 +0200
Roman Rakus f2e7e1
@@ -69,9 +69,15 @@ extern char *strcpy ();
Roman Rakus f2e7e1
 #define whitespace(c) (((c) == ' ') || ((c) == '\t'))
Roman Rakus f2e7e1
 
Roman Rakus f2e7e1
 /* Flag values that builtins can have. */
Roman Rakus f2e7e1
+/*  These flags are for the C code generator, 
Roman Rakus f2e7e1
+    the C which is produced (./builtin.c)
Roman Rakus f2e7e1
+    includes the flags definitions found 
Roman Rakus f2e7e1
+    in ../builtins.h */
Roman Rakus f2e7e1
 #define BUILTIN_FLAG_SPECIAL	0x01
Roman Rakus f2e7e1
 #define BUILTIN_FLAG_ASSIGNMENT 0x02
Roman Rakus f2e7e1
 #define BUILTIN_FLAG_POSIX_BUILTIN 0x04
Roman Rakus f2e7e1
+#define BUILTIN_FLAG_REQUIRES	0x08
Roman Rakus d1932b
+
Tim Waugh 6353ab
 
Roman Rakus f2e7e1
 #define BASE_INDENT	4
Tim Waugh 6353ab
 
Roman Rakus f2e7e1
@@ -163,10 +169,18 @@ char *posix_builtins[] =
Roman Rakus f2e7e1
   (char *)NULL
Roman Rakus f2e7e1
 };
Roman Rakus f2e7e1
 
Roman Rakus f2e7e1
+/* The builtin commands that cause requirements on other files. */
Roman Rakus f2e7e1
+static char *requires_builtins[] =
Roman Rakus f2e7e1
+{
Roman Rakus f2e7e1
+  ".", "command", "exec", "source", "inlib",
Roman Rakus f2e7e1
+  (char *)NULL
Roman Rakus f2e7e1
+};
Tim Waugh 6353ab
+
Roman Rakus f2e7e1
 /* Forward declarations. */
Roman Rakus f2e7e1
 static int is_special_builtin ();
Roman Rakus f2e7e1
 static int is_assignment_builtin ();
Roman Rakus f2e7e1
 static int is_posix_builtin ();
Roman Rakus f2e7e1
+static int is_requires_builtin ();
Roman Rakus f2e7e1
 
Roman Rakus f2e7e1
 #if !defined (HAVE_RENAME)
Roman Rakus f2e7e1
 static int rename ();
Roman Rakus f2e7e1
@@ -812,6 +826,9 @@ builtin_handler (self, defs, arg)
Roman Rakus f2e7e1
     new->flags |= BUILTIN_FLAG_ASSIGNMENT;
Roman Rakus f2e7e1
   if (is_posix_builtin (name))
Roman Rakus f2e7e1
     new->flags |= BUILTIN_FLAG_POSIX_BUILTIN;
Roman Rakus f2e7e1
+  if (is_requires_builtin (name))
Roman Rakus f2e7e1
+    new->flags |= BUILTIN_FLAG_REQUIRES;
Roman Rakus f2e7e1
+
Roman Rakus f2e7e1
 
Roman Rakus f2e7e1
   array_add ((char *)new, defs->builtins);
Roman Rakus f2e7e1
   building_builtin = 1;
Roman Rakus f2e7e1
@@ -1229,11 +1246,12 @@ write_builtins (defs, structfile, extern
Roman Rakus f2e7e1
 		  else
Roman Rakus f2e7e1
 		    fprintf (structfile, "(sh_builtin_func_t *)0x0, ");
Tim Waugh 6353ab
 
Roman Rakus f2e7e1
-		  fprintf (structfile, "%s%s%s%s, %s_doc,\n",
Roman Rakus f2e7e1
+		  fprintf (structfile, "%s%s%s%s%s, %s_doc,\n",
Roman Rakus f2e7e1
 		    "BUILTIN_ENABLED | STATIC_BUILTIN",
Roman Rakus f2e7e1
 		    (builtin->flags & BUILTIN_FLAG_SPECIAL) ? " | SPECIAL_BUILTIN" : "",
Roman Rakus f2e7e1
 		    (builtin->flags & BUILTIN_FLAG_ASSIGNMENT) ? " | ASSIGNMENT_BUILTIN" : "",
Roman Rakus f2e7e1
 		    (builtin->flags & BUILTIN_FLAG_POSIX_BUILTIN) ? " | POSIX_BUILTIN" : "",
Roman Rakus f2e7e1
+		    (builtin->flags & BUILTIN_FLAG_REQUIRES) ? " | REQUIRES_BUILTIN" : "",
Roman Rakus f2e7e1
 		    document_name (builtin));
Roman Rakus f2e7e1
 
Ondrej Oprala ac881b
 		  if (inhibit_functions)
Roman Rakus f2e7e1
@@ -1581,6 +1599,13 @@ is_posix_builtin (name)
Roman Rakus f2e7e1
   return (_find_in_table (name, posix_builtins));
Roman Rakus f2e7e1
 }
Roman Rakus f2e7e1
 
Roman Rakus f2e7e1
+static int
Roman Rakus f2e7e1
+is_requires_builtin (name)
Roman Rakus f2e7e1
+     char *name;
Roman Rakus f2e7e1
+{
Roman Rakus f2e7e1
+  return (_find_in_table (name, requires_builtins));
Roman Rakus f2e7e1
+}
Roman Rakus f2e7e1
+
Roman Rakus f2e7e1
 #if !defined (HAVE_RENAME)
Roman Rakus f2e7e1
 static int
Roman Rakus f2e7e1
 rename (from, to)
Roman Rakus 5f19b4
diff -up bash-4.1/doc/bash.1.requires bash-4.1/doc/bash.1
Roman Rakus 5ab66f
--- bash-4.1/doc/bash.1.requires	2010-08-02 17:42:41.000000000 +0200
Roman Rakus 5ab66f
+++ bash-4.1/doc/bash.1	2010-08-02 18:09:27.000000000 +0200
Roman Rakus 5ab66f
@@ -231,6 +231,14 @@ 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;
Roman Rakus 5ab66f
+Command substitutions, Conditional expressions and
Roman Rakus 5ab66f
+.BR eval
Roman Rakus 5ab66f
+builtin are not parsed so some 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 5f19b4
diff -up bash-4.1/doc/bashref.texi.requires bash-4.1/doc/bashref.texi
Roman Rakus 5ab66f
--- bash-4.1/doc/bashref.texi.requires	2010-08-02 17:42:41.000000000 +0200
Roman Rakus 5ab66f
+++ bash-4.1/doc/bashref.texi	2010-08-02 18:11:58.000000000 +0200
Roman Rakus 5f19b4
@@ -5343,6 +5343,13 @@ standard.  @xref{Bash POSIX Mode}, for a
Roman Rakus f2e7e1
 @item --restricted
Roman Rakus f2e7e1
 Make the shell a restricted shell (@pxref{The Restricted Shell}).
Roman Rakus f2e7e1
 
Roman Rakus f2e7e1
+@item --rpm-requires
Roman Rakus f2e7e1
+Produce the list of files that are required for the 
Roman Rakus f2e7e1
+shell script to run.  This implies '-n' and is subject
Roman Rakus f2e7e1
+to the same limitations as compile time error checking checking;
Roman Rakus 5ab66f
+Command substitutions, Conditional expressions and @command{eval}
Roman Rakus 5ab66f
+are not parsed so some dependencies may be missed.
Roman Rakus f2e7e1
+
Roman Rakus f2e7e1
 @item --verbose
Roman Rakus f2e7e1
 Equivalent to @option{-v}.  Print shell input lines as they're read.
Roman Rakus f2e7e1
 
Roman Rakus 5f19b4
diff -up bash-4.1/eval.c.requires bash-4.1/eval.c
Roman Rakus 5f19b4
--- bash-4.1/eval.c.requires	2009-01-04 20:32:26.000000000 +0100
Roman Rakus 5ab66f
+++ bash-4.1/eval.c	2010-08-02 17:42:41.000000000 +0200
Roman Rakus f2e7e1
@@ -53,6 +53,7 @@ extern int last_command_exit_value, stdi
Roman Rakus f2e7e1
 extern int need_here_doc;
Roman Rakus f2e7e1
 extern int current_command_number, current_command_line_count, line_number;
Roman Rakus f2e7e1
 extern int expand_aliases;
Roman Rakus f2e7e1
+extern int rpm_requires;
Roman Rakus f2e7e1
 
Ondrej Oprala ac881b
 #if defined (HAVE_POSIX_SIGNALS)
Ondrej Oprala ac881b
 extern sigset_t top_level_mask;
Roman Rakus f2e7e1
@@ -136,7 +137,7 @@ reader_loop ()
Roman Rakus f2e7e1
 
Roman Rakus f2e7e1
       if (read_command () == 0)
Roman Rakus f2e7e1
 	{
Roman Rakus f2e7e1
-	  if (interactive_shell == 0 && read_but_dont_execute)
Roman Rakus f2e7e1
+	  if (interactive_shell == 0 && (read_but_dont_execute && !rpm_requires))
Roman Rakus f2e7e1
 	    {
Roman Rakus f2e7e1
 	      last_command_exit_value = EXECUTION_SUCCESS;
Roman Rakus f2e7e1
 	      dispose_command (global_command);
Roman Rakus 5f19b4
diff -up bash-4.1/execute_cmd.c.requires bash-4.1/execute_cmd.c
Roman Rakus 5ab66f
--- bash-4.1/execute_cmd.c.requires	2010-08-02 17:42:41.000000000 +0200
Roman Rakus 5ab66f
+++ bash-4.1/execute_cmd.c	2010-08-02 17:42:41.000000000 +0200
Roman Rakus 5f19b4
@@ -503,6 +503,8 @@ async_redirect_stdin ()
Roman Rakus f2e7e1
 
Roman Rakus f2e7e1
 #define DESCRIBE_PID(pid) do { if (interactive) describe_pid (pid); } while (0)
Roman Rakus f2e7e1
 
Roman Rakus f2e7e1
+extern int rpm_requires;
Roman Rakus f2e7e1
+
Ondrej Oprala ac881b
 /* Execute the command passed in COMMAND, perhaps doing it asynchronously.
Roman Rakus f2e7e1
    COMMAND is exactly what read_command () places into GLOBAL_COMMAND.
Roman Rakus f2e7e1
    ASYNCHROUNOUS, if non-zero, says to do this command in the background.
Roman Rakus 5f19b4
@@ -534,7 +536,13 @@ execute_command_internal (command, async
Ondrej Oprala ac881b
 
Roman Rakus f2e7e1
   if (breaking || continuing)
Roman Rakus f2e7e1
     return (last_command_exit_value);
Roman Rakus f2e7e1
-  if (command == 0 || read_but_dont_execute)
Roman Rakus f2e7e1
+  if (command == 0 || (read_but_dont_execute && !rpm_requires))
Roman Rakus 5f19b4
+    return (EXECUTION_SUCCESS);
Roman Rakus f2e7e1
+  if (rpm_requires && command->type == cm_function_def)
Roman Rakus f2e7e1
+    return last_command_exit_value =
Roman Rakus f2e7e1
+      execute_intern_function (command->value.Function_def->name,
Ondrej Oprala 826281
+                              command->value.Function_def);
Roman Rakus 5f19b4
+  if (read_but_dont_execute)
Roman Rakus 5f19b4
     return (EXECUTION_SUCCESS);
Roman Rakus f2e7e1
 
Ondrej Oprala ac881b
   QUIT;
Roman Rakus 5f19b4
@@ -5066,7 +5074,7 @@ execute_intern_function (name, function)
Roman Rakus f2e7e1
 
Roman Rakus f2e7e1
   if (check_identifier (name, posixly_correct) == 0)
Roman Rakus f2e7e1
     {
Roman Rakus f2e7e1
-      if (posixly_correct && interactive_shell == 0)
Roman Rakus f2e7e1
+      if (posixly_correct && interactive_shell == 0 && rpm_requires == 0)
Roman Rakus f2e7e1
 	{
Roman Rakus f2e7e1
 	  last_command_exit_value = EX_BADUSAGE;
Roman Rakus f2e7e1
 	  jump_to_top_level (ERREXIT);
Roman Rakus 5f19b4
diff -up bash-4.1/execute_cmd.h.requires bash-4.1/execute_cmd.h
Roman Rakus 5f19b4
--- bash-4.1/execute_cmd.h.requires	2009-01-16 22:20:15.000000000 +0100
Roman Rakus 5ab66f
+++ bash-4.1/execute_cmd.h	2010-08-02 17:42:41.000000000 +0200
Roman Rakus f2e7e1
@@ -22,6 +22,8 @@
Roman Rakus f2e7e1
 #define _EXECUTE_CMD_H_
Roman Rakus f2e7e1
 
Roman Rakus f2e7e1
 #include "stdc.h"
Roman Rakus f2e7e1
+#include "variables.h"
Roman Rakus f2e7e1
+#include "command.h"
Roman Rakus f2e7e1
 
Roman Rakus f2e7e1
 extern struct fd_bitmap *new_fd_bitmap __P((int));
Roman Rakus f2e7e1
 extern void dispose_fd_bitmap __P((struct fd_bitmap *));
Roman Rakus 5f19b4
diff -up bash-4.1/make_cmd.c.requires bash-4.1/make_cmd.c
Roman Rakus 5f19b4
--- bash-4.1/make_cmd.c.requires	2009-09-11 23:26:12.000000000 +0200
Roman Rakus 5ab66f
+++ bash-4.1/make_cmd.c	2010-08-02 17:42:41.000000000 +0200
Roman Rakus f2e7e1
@@ -42,11 +42,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 f2e7e1
@@ -56,6 +60,10 @@
Tim Waugh 6353ab
 
Roman Rakus f2e7e1
 extern int line_number, current_command_line_count, parser_state;
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 f2e7e1
@@ -820,6 +828,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 f2e7e1
@@ -837,6 +866,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
+
Roman Rakus f2e7e1
   parser_state &= ~PST_REDIRLIST;
Tim Waugh 6353ab
   return (command);
Tim Waugh 6353ab
 }
Roman Rakus 5f19b4
diff -up bash-4.1/shell.c.requires bash-4.1/shell.c
Roman Rakus 5ab66f
--- bash-4.1/shell.c.requires	2010-08-02 17:42:41.000000000 +0200
Roman Rakus 5ab66f
+++ bash-4.1/shell.c	2010-08-02 17:42:41.000000000 +0200
Roman Rakus f2e7e1
@@ -193,6 +193,9 @@ int have_devfd = 0;
Roman Rakus f2e7e1
 /* The name of the .(shell)rc file. */
Roman Rakus f2e7e1
 static char *bashrc_file = "~/.bashrc";
Tim Waugh 6353ab
 
Roman Rakus f2e7e1
+/* Non-zero if we are finding the scripts requirements. */
Roman Rakus f2e7e1
+int rpm_requires;
Roman Rakus 87b651
+
Roman Rakus f2e7e1
 /* Non-zero means to act more like the Bourne shell on startup. */
Roman Rakus f2e7e1
 static int act_like_sh;
Roman Rakus d1932b
 
Roman Rakus f2e7e1
@@ -251,6 +254,7 @@ static const struct {
Roman Rakus f2e7e1
   { "protected", Int, &protected_mode, (char **)0x0 },
Ondrej Oprala ac881b
 #endif
Roman Rakus f2e7e1
   { "rcfile", Charp, (int *)0x0, &bashrc_file },
Roman Rakus f2e7e1
+  { "rpm-requires", Int, &rpm_requires, (char **)0x0 },
Roman Rakus f2e7e1
 #if defined (RESTRICTED_SHELL)
Roman Rakus f2e7e1
   { "restricted", Int, &restricted, (char **)0x0 },
Roman Rakus f2e7e1
 #endif
Roman Rakus f2e7e1
@@ -485,6 +489,12 @@ main (argc, argv, env)
Roman Rakus f2e7e1
   if (dump_translatable_strings)
Roman Rakus f2e7e1
     read_but_dont_execute = 1;
Roman Rakus d1932b
 
Roman Rakus f2e7e1
+  if (rpm_requires)
Roman Rakus f2e7e1
+    {
Roman Rakus f2e7e1
+      read_but_dont_execute = 1;
Roman Rakus f2e7e1
+      initialize_shell_builtins ();
Roman Rakus f2e7e1
+    }
Roman Rakus 87b651
+
Roman Rakus f2e7e1
   if (running_setuid && privileged_mode == 0)
Roman Rakus f2e7e1
     disable_priv_mode ();
Tim Waugh 6353ab