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