]>
Commit | Line | Data |
---|---|---|
7d475eab MT |
1 | diff -up bash-4.1/builtins.h.requires bash-4.1/builtins.h |
2 | --- bash-4.1/builtins.h.requires 2009-01-04 20:32:23.000000000 +0100 | |
3 | +++ bash-4.1/builtins.h 2010-08-02 17:42:41.000000000 +0200 | |
4 | @@ -41,6 +41,8 @@ | |
5 | #define SPECIAL_BUILTIN 0x08 /* This is a Posix `special' builtin. */ | |
6 | #define ASSIGNMENT_BUILTIN 0x10 /* This builtin takes assignment statements. */ | |
7 | #define POSIX_BUILTIN 0x20 /* This builtins is special in the Posix command search order. */ | |
8 | +#define REQUIRES_BUILTIN 0x40 /* This builtin requires other files. */ | |
9 | + | |
10 | ||
11 | #define BASE_INDENT 4 | |
12 | ||
13 | diff -up bash-4.1/builtins/mkbuiltins.c.requires bash-4.1/builtins/mkbuiltins.c | |
14 | --- bash-4.1/builtins/mkbuiltins.c.requires 2009-01-04 20:32:23.000000000 +0100 | |
15 | +++ bash-4.1/builtins/mkbuiltins.c 2010-08-02 17:42:41.000000000 +0200 | |
16 | @@ -69,9 +69,15 @@ extern char *strcpy (); | |
17 | #define whitespace(c) (((c) == ' ') || ((c) == '\t')) | |
18 | ||
19 | /* Flag values that builtins can have. */ | |
20 | +/* These flags are for the C code generator, | |
21 | + the C which is produced (./builtin.c) | |
22 | + includes the flags definitions found | |
23 | + in ../builtins.h */ | |
24 | #define BUILTIN_FLAG_SPECIAL 0x01 | |
25 | #define BUILTIN_FLAG_ASSIGNMENT 0x02 | |
26 | #define BUILTIN_FLAG_POSIX_BUILTIN 0x04 | |
27 | +#define BUILTIN_FLAG_REQUIRES 0x08 | |
28 | + | |
29 | ||
30 | #define BASE_INDENT 4 | |
31 | ||
32 | @@ -163,10 +169,18 @@ char *posix_builtins[] = | |
33 | (char *)NULL | |
34 | }; | |
35 | ||
36 | +/* The builtin commands that cause requirements on other files. */ | |
37 | +static char *requires_builtins[] = | |
38 | +{ | |
39 | + ".", "command", "exec", "source", "inlib", | |
40 | + (char *)NULL | |
41 | +}; | |
42 | + | |
43 | /* Forward declarations. */ | |
44 | static int is_special_builtin (); | |
45 | static int is_assignment_builtin (); | |
46 | static int is_posix_builtin (); | |
47 | +static int is_requires_builtin (); | |
48 | ||
49 | #if !defined (HAVE_RENAME) | |
50 | static int rename (); | |
51 | @@ -812,6 +826,9 @@ builtin_handler (self, defs, arg) | |
52 | new->flags |= BUILTIN_FLAG_ASSIGNMENT; | |
53 | if (is_posix_builtin (name)) | |
54 | new->flags |= BUILTIN_FLAG_POSIX_BUILTIN; | |
55 | + if (is_requires_builtin (name)) | |
56 | + new->flags |= BUILTIN_FLAG_REQUIRES; | |
57 | + | |
58 | ||
59 | array_add ((char *)new, defs->builtins); | |
60 | building_builtin = 1; | |
61 | @@ -1229,11 +1246,12 @@ write_builtins (defs, structfile, extern | |
62 | else | |
63 | fprintf (structfile, "(sh_builtin_func_t *)0x0, "); | |
64 | ||
65 | - fprintf (structfile, "%s%s%s%s, %s_doc,\n", | |
66 | + fprintf (structfile, "%s%s%s%s%s, %s_doc,\n", | |
67 | "BUILTIN_ENABLED | STATIC_BUILTIN", | |
68 | (builtin->flags & BUILTIN_FLAG_SPECIAL) ? " | SPECIAL_BUILTIN" : "", | |
69 | (builtin->flags & BUILTIN_FLAG_ASSIGNMENT) ? " | ASSIGNMENT_BUILTIN" : "", | |
70 | (builtin->flags & BUILTIN_FLAG_POSIX_BUILTIN) ? " | POSIX_BUILTIN" : "", | |
71 | + (builtin->flags & BUILTIN_FLAG_REQUIRES) ? " | REQUIRES_BUILTIN" : "", | |
72 | document_name (builtin)); | |
73 | ||
56ba7d19 | 74 | if (inhibit_functions) |
7d475eab MT |
75 | @@ -1581,6 +1599,13 @@ is_posix_builtin (name) |
76 | return (_find_in_table (name, posix_builtins)); | |
77 | } | |
78 | ||
79 | +static int | |
80 | +is_requires_builtin (name) | |
81 | + char *name; | |
82 | +{ | |
83 | + return (_find_in_table (name, requires_builtins)); | |
84 | +} | |
85 | + | |
86 | #if !defined (HAVE_RENAME) | |
87 | static int | |
88 | rename (from, to) | |
89 | diff -up bash-4.1/doc/bash.1.requires bash-4.1/doc/bash.1 | |
90 | --- bash-4.1/doc/bash.1.requires 2010-08-02 17:42:41.000000000 +0200 | |
91 | +++ bash-4.1/doc/bash.1 2010-08-02 18:09:27.000000000 +0200 | |
92 | @@ -231,6 +231,14 @@ The shell becomes restricted (see | |
93 | .B "RESTRICTED SHELL" | |
94 | below). | |
95 | .TP | |
96 | +.B \-\-rpm-requires | |
97 | +Produce the list of files that are required for the | |
98 | +shell script to run. This implies '-n' and is subject | |
99 | +to the same limitations as compile time error checking checking; | |
100 | +Command substitutions, Conditional expressions and | |
101 | +.BR eval | |
102 | +builtin are not parsed so some dependencies may be missed. | |
103 | +.TP | |
104 | .B \-\-verbose | |
105 | Equivalent to \fB\-v\fP. | |
106 | .TP | |
107 | diff -up bash-4.1/doc/bashref.texi.requires bash-4.1/doc/bashref.texi | |
108 | --- bash-4.1/doc/bashref.texi.requires 2010-08-02 17:42:41.000000000 +0200 | |
109 | +++ bash-4.1/doc/bashref.texi 2010-08-02 18:11:58.000000000 +0200 | |
110 | @@ -5343,6 +5343,13 @@ standard. @xref{Bash POSIX Mode}, for a | |
111 | @item --restricted | |
112 | Make the shell a restricted shell (@pxref{The Restricted Shell}). | |
113 | ||
114 | +@item --rpm-requires | |
115 | +Produce the list of files that are required for the | |
116 | +shell script to run. This implies '-n' and is subject | |
117 | +to the same limitations as compile time error checking checking; | |
118 | +Command substitutions, Conditional expressions and @command{eval} | |
119 | +are not parsed so some dependencies may be missed. | |
120 | + | |
121 | @item --verbose | |
122 | Equivalent to @option{-v}. Print shell input lines as they're read. | |
123 | ||
124 | diff -up bash-4.1/eval.c.requires bash-4.1/eval.c | |
125 | --- bash-4.1/eval.c.requires 2009-01-04 20:32:26.000000000 +0100 | |
126 | +++ bash-4.1/eval.c 2010-08-02 17:42:41.000000000 +0200 | |
127 | @@ -53,6 +53,7 @@ extern int last_command_exit_value, stdi | |
128 | extern int need_here_doc; | |
129 | extern int current_command_number, current_command_line_count, line_number; | |
130 | extern int expand_aliases; | |
131 | +extern int rpm_requires; | |
132 | ||
56ba7d19 MT |
133 | #if defined (HAVE_POSIX_SIGNALS) |
134 | extern sigset_t top_level_mask; | |
7d475eab MT |
135 | @@ -136,7 +137,7 @@ reader_loop () |
136 | ||
137 | if (read_command () == 0) | |
138 | { | |
139 | - if (interactive_shell == 0 && read_but_dont_execute) | |
140 | + if (interactive_shell == 0 && (read_but_dont_execute && !rpm_requires)) | |
141 | { | |
142 | last_command_exit_value = EXECUTION_SUCCESS; | |
143 | dispose_command (global_command); | |
144 | diff -up bash-4.1/execute_cmd.c.requires bash-4.1/execute_cmd.c | |
145 | --- bash-4.1/execute_cmd.c.requires 2010-08-02 17:42:41.000000000 +0200 | |
146 | +++ bash-4.1/execute_cmd.c 2010-08-02 17:42:41.000000000 +0200 | |
147 | @@ -503,6 +503,8 @@ async_redirect_stdin () | |
148 | ||
149 | #define DESCRIBE_PID(pid) do { if (interactive) describe_pid (pid); } while (0) | |
150 | ||
151 | +extern int rpm_requires; | |
152 | + | |
56ba7d19 | 153 | /* Execute the command passed in COMMAND, perhaps doing it asynchronously. |
7d475eab MT |
154 | COMMAND is exactly what read_command () places into GLOBAL_COMMAND. |
155 | ASYNCHROUNOUS, if non-zero, says to do this command in the background. | |
156 | @@ -534,7 +536,13 @@ execute_command_internal (command, async | |
56ba7d19 | 157 | |
7d475eab MT |
158 | if (breaking || continuing) |
159 | return (last_command_exit_value); | |
160 | - if (command == 0 || read_but_dont_execute) | |
161 | + if (command == 0 || (read_but_dont_execute && !rpm_requires)) | |
162 | + return (EXECUTION_SUCCESS); | |
163 | + if (rpm_requires && command->type == cm_function_def) | |
164 | + return last_command_exit_value = | |
165 | + execute_intern_function (command->value.Function_def->name, | |
166 | + command->value.Function_def->command); | |
167 | + if (read_but_dont_execute) | |
168 | return (EXECUTION_SUCCESS); | |
7d475eab | 169 | |
56ba7d19 | 170 | QUIT; |
7d475eab MT |
171 | @@ -5066,7 +5074,7 @@ execute_intern_function (name, function) |
172 | ||
173 | if (check_identifier (name, posixly_correct) == 0) | |
174 | { | |
175 | - if (posixly_correct && interactive_shell == 0) | |
176 | + if (posixly_correct && interactive_shell == 0 && rpm_requires == 0) | |
177 | { | |
178 | last_command_exit_value = EX_BADUSAGE; | |
179 | jump_to_top_level (ERREXIT); | |
180 | diff -up bash-4.1/execute_cmd.h.requires bash-4.1/execute_cmd.h | |
181 | --- bash-4.1/execute_cmd.h.requires 2009-01-16 22:20:15.000000000 +0100 | |
182 | +++ bash-4.1/execute_cmd.h 2010-08-02 17:42:41.000000000 +0200 | |
183 | @@ -22,6 +22,8 @@ | |
184 | #define _EXECUTE_CMD_H_ | |
185 | ||
186 | #include "stdc.h" | |
187 | +#include "variables.h" | |
188 | +#include "command.h" | |
189 | ||
190 | extern struct fd_bitmap *new_fd_bitmap __P((int)); | |
191 | extern void dispose_fd_bitmap __P((struct fd_bitmap *)); | |
192 | diff -up bash-4.1/make_cmd.c.requires bash-4.1/make_cmd.c | |
193 | --- bash-4.1/make_cmd.c.requires 2009-09-11 23:26:12.000000000 +0200 | |
194 | +++ bash-4.1/make_cmd.c 2010-08-02 17:42:41.000000000 +0200 | |
195 | @@ -42,11 +42,15 @@ | |
196 | #include "flags.h" | |
197 | #include "make_cmd.h" | |
198 | #include "dispose_cmd.h" | |
199 | +#include "execute_cmd.h" | |
200 | #include "variables.h" | |
201 | #include "subst.h" | |
202 | #include "input.h" | |
203 | #include "ocache.h" | |
204 | #include "externs.h" | |
205 | +#include "builtins.h" | |
206 | + | |
207 | +#include "builtins/common.h" | |
208 | ||
209 | #if defined (JOB_CONTROL) | |
210 | #include "jobs.h" | |
211 | @@ -56,6 +60,10 @@ | |
212 | ||
213 | extern int line_number, current_command_line_count, parser_state; | |
214 | extern int last_command_exit_value; | |
215 | +extern int rpm_requires; | |
216 | + | |
217 | +static char *alphabet_set = "abcdefghijklmnopqrstuvwxyz" | |
218 | + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
219 | ||
220 | /* Object caching */ | |
221 | sh_obj_cache_t wdcache = {0, 0, 0}; | |
222 | @@ -820,6 +828,27 @@ make_coproc_command (name, command) | |
223 | return (make_command (cm_coproc, (SIMPLE_COM *)temp)); | |
224 | } | |
225 | ||
226 | +static void | |
227 | +output_requirement (deptype, filename) | |
228 | +const char *deptype; | |
229 | +char *filename; | |
230 | +{ | |
231 | + if (strchr(filename, '$') || (filename[0] != '/' && strchr(filename, '/'))) | |
232 | + return; | |
233 | + | |
234 | + /* | |
235 | + if the executable is called via variable substitution we can | |
236 | + not dermine what it is at compile time. | |
237 | + | |
238 | + if the executable consists only of characters not in the | |
239 | + alphabet we do not consider it a dependency just an artifact | |
240 | + of shell parsing (ex "exec < ${infile}"). | |
241 | + */ | |
242 | + | |
243 | + if (strpbrk(filename, alphabet_set)) | |
244 | + printf ("%s(%s)\n", deptype, filename); | |
245 | +} | |
246 | + | |
247 | /* Reverse the word list and redirection list in the simple command | |
248 | has just been parsed. It seems simpler to do this here the one | |
249 | time then by any other method that I can think of. */ | |
250 | @@ -837,6 +866,27 @@ clean_simple_command (command) | |
251 | REVERSE_LIST (command->value.Simple->redirects, REDIRECT *); | |
252 | } | |
253 | ||
254 | + if (rpm_requires && command->value.Simple->words) | |
255 | + { | |
256 | + char *cmd0; | |
257 | + char *cmd1; | |
258 | + struct builtin *b; | |
259 | + | |
260 | + cmd0 = command->value.Simple->words->word->word; | |
261 | + b = builtin_address_internal (cmd0, 0); | |
262 | + cmd1 = 0; | |
263 | + if (command->value.Simple->words->next) | |
264 | + cmd1 = command->value.Simple->words->next->word->word; | |
265 | + | |
266 | + if (b) { | |
267 | + if ( (b->flags & REQUIRES_BUILTIN) && cmd1) | |
268 | + output_requirement ("executable", cmd1); | |
269 | + } else { | |
270 | + if (!assignment(cmd0, 0)) | |
271 | + output_requirement (find_function(cmd0) ? "function" : "executable", cmd0); | |
272 | + } | |
273 | + } /*rpm_requires*/ | |
274 | + | |
275 | parser_state &= ~PST_REDIRLIST; | |
276 | return (command); | |
277 | } | |
278 | diff -up bash-4.1/shell.c.requires bash-4.1/shell.c | |
279 | --- bash-4.1/shell.c.requires 2010-08-02 17:42:41.000000000 +0200 | |
280 | +++ bash-4.1/shell.c 2010-08-02 17:42:41.000000000 +0200 | |
281 | @@ -193,6 +193,9 @@ int have_devfd = 0; | |
282 | /* The name of the .(shell)rc file. */ | |
283 | static char *bashrc_file = "~/.bashrc"; | |
284 | ||
285 | +/* Non-zero if we are finding the scripts requirements. */ | |
286 | +int rpm_requires; | |
287 | + | |
288 | /* Non-zero means to act more like the Bourne shell on startup. */ | |
289 | static int act_like_sh; | |
290 | ||
291 | @@ -251,6 +254,7 @@ static const struct { | |
7d475eab | 292 | { "protected", Int, &protected_mode, (char **)0x0 }, |
56ba7d19 | 293 | #endif |
7d475eab MT |
294 | { "rcfile", Charp, (int *)0x0, &bashrc_file }, |
295 | + { "rpm-requires", Int, &rpm_requires, (char **)0x0 }, | |
296 | #if defined (RESTRICTED_SHELL) | |
297 | { "restricted", Int, &restricted, (char **)0x0 }, | |
298 | #endif | |
299 | @@ -485,6 +489,12 @@ main (argc, argv, env) | |
300 | if (dump_translatable_strings) | |
301 | read_but_dont_execute = 1; | |
302 | ||
303 | + if (rpm_requires) | |
304 | + { | |
305 | + read_but_dont_execute = 1; | |
306 | + initialize_shell_builtins (); | |
307 | + } | |
308 | + | |
309 | if (running_setuid && privileged_mode == 0) | |
310 | disable_priv_mode (); | |
311 |