Bash-4.2 patch 27
[platform/upstream/bash.git] / findcmd.c
1 /* findcmd.c -- Functions to search for commands by name. */
2
3 /* Copyright (C) 1997-2009 Free Software Foundation, Inc.
4
5    This file is part of GNU Bash, the Bourne Again SHell.
6
7    Bash is free software: you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation, either version 3 of the License, or
10    (at your option) any later version.
11
12    Bash is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "config.h"
22
23 #include <stdio.h>
24 #include "chartypes.h"
25 #include "bashtypes.h"
26 #if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)
27 #  include <sys/file.h>
28 #endif
29 #include "filecntl.h"
30 #include "posixstat.h"
31
32 #if defined (HAVE_UNISTD_H)
33 #  include <unistd.h>
34 #endif
35 #include <errno.h>
36
37 #include "bashansi.h"
38
39 #include "memalloc.h"
40 #include "shell.h"
41 #include "flags.h"
42 #include "hashlib.h"
43 #include "pathexp.h"
44 #include "hashcmd.h"
45 #include "findcmd.h"    /* matching prototypes and declarations */
46
47 #if !defined (errno)
48 extern int errno;
49 #endif
50
51 extern int posixly_correct;
52
53 /* Static functions defined and used in this file. */
54 static char *_find_user_command_internal __P((const char *, int));
55 static char *find_user_command_internal __P((const char *, int));
56 static char *find_user_command_in_path __P((const char *, char *, int));
57 static char *find_in_path_element __P((const char *, char *, int, int, struct stat *));
58 static char *find_absolute_program __P((const char *, int));
59
60 static char *get_next_path_element __P((char *, int *));
61
62 /* The file name which we would try to execute, except that it isn't
63    possible to execute it.  This is the first file that matches the
64    name that we are looking for while we are searching $PATH for a
65    suitable one to execute.  If we cannot find a suitable executable
66    file, then we use this one. */
67 static char *file_to_lose_on;
68
69 /* Non-zero if we should stat every command found in the hash table to
70    make sure it still exists. */
71 int check_hashed_filenames;
72
73 /* DOT_FOUND_IN_SEARCH becomes non-zero when find_user_command ()
74    encounters a `.' as the directory pathname while scanning the
75    list of possible pathnames; i.e., if `.' comes before the directory
76    containing the file of interest. */
77 int dot_found_in_search = 0;
78
79 /* Return some flags based on information about this file.
80    The EXISTS bit is non-zero if the file is found.
81    The EXECABLE bit is non-zero the file is executble.
82    Zero is returned if the file is not found. */
83 int
84 file_status (name)
85      const char *name;
86 {
87   struct stat finfo;
88   int r;
89
90   /* Determine whether this file exists or not. */
91   if (stat (name, &finfo) < 0)
92     return (0);
93
94   /* If the file is a directory, then it is not "executable" in the
95      sense of the shell. */
96   if (S_ISDIR (finfo.st_mode))
97     return (FS_EXISTS|FS_DIRECTORY);
98
99   r = FS_EXISTS;
100
101 #if defined (HAVE_EACCESS)
102   /* Use eaccess(2) if we have it to take things like ACLs and other
103      file access mechanisms into account.  eaccess uses the effective
104      user and group IDs, not the real ones.  We could use sh_eaccess,
105      but we don't want any special treatment for /dev/fd. */
106   if (eaccess (name, X_OK) == 0)
107     r |= FS_EXECABLE;
108   if (eaccess (name, R_OK) == 0)
109     r |= FS_READABLE;
110
111   return r;
112 #elif defined (AFS)
113   /* We have to use access(2) to determine access because AFS does not
114      support Unix file system semantics.  This may produce wrong
115      answers for non-AFS files when ruid != euid.  I hate AFS. */
116   if (access (name, X_OK) == 0)
117     r |= FS_EXECABLE;
118   if (access (name, R_OK) == 0)
119     r |= FS_READABLE;
120
121   return r;
122 #else /* !HAVE_EACCESS && !AFS */
123
124   /* Find out if the file is actually executable.  By definition, the
125      only other criteria is that the file has an execute bit set that
126      we can use.  The same with whether or not a file is readable. */
127
128   /* Root only requires execute permission for any of owner, group or
129      others to be able to exec a file, and can read any file. */
130   if (current_user.euid == (uid_t)0)
131     {
132       r |= FS_READABLE;
133       if (finfo.st_mode & S_IXUGO)
134         r |= FS_EXECABLE;
135       return r;
136     }
137
138   /* If we are the owner of the file, the owner bits apply. */
139   if (current_user.euid == finfo.st_uid)
140     {
141       if (finfo.st_mode & S_IXUSR)
142         r |= FS_EXECABLE;
143       if (finfo.st_mode & S_IRUSR)
144         r |= FS_READABLE;
145     }
146
147   /* If we are in the owning group, the group permissions apply. */
148   else if (group_member (finfo.st_gid))
149     {
150       if (finfo.st_mode & S_IXGRP)
151         r |= FS_EXECABLE;
152       if (finfo.st_mode & S_IRGRP)
153         r |= FS_READABLE;
154     }
155
156   /* Else we check whether `others' have permission to execute the file */
157   else
158     {
159       if (finfo.st_mode & S_IXOTH)
160         r |= FS_EXECABLE;
161       if (finfo.st_mode & S_IROTH)
162         r |= FS_READABLE;
163     }
164
165   return r;
166 #endif /* !AFS */
167 }
168
169 /* Return non-zero if FILE exists and is executable.
170    Note that this function is the definition of what an
171    executable file is; do not change this unless YOU know
172    what an executable file is. */
173 int
174 executable_file (file)
175      const char *file;
176 {
177   int s;
178
179   s = file_status (file);
180 #if defined EISDIR
181   if (s & FS_DIRECTORY)
182     errno = EISDIR;     /* let's see if we can improve error messages */
183 #endif
184   return ((s & FS_EXECABLE) && ((s & FS_DIRECTORY) == 0));
185 }
186
187 int
188 is_directory (file)
189      const char *file;
190 {
191   return (file_status (file) & FS_DIRECTORY);
192 }
193
194 int
195 executable_or_directory (file)
196      const char *file;
197 {
198   int s;
199
200   s = file_status (file);
201   return ((s & FS_EXECABLE) || (s & FS_DIRECTORY));
202 }
203
204 /* Locate the executable file referenced by NAME, searching along
205    the contents of the shell PATH variable.  Return a new string
206    which is the full pathname to the file, or NULL if the file
207    couldn't be found.  If a file is found that isn't executable,
208    and that is the only match, then return that. */
209 char *
210 find_user_command (name)
211      const char *name;
212 {
213   return (find_user_command_internal (name, FS_EXEC_PREFERRED|FS_NODIRS));
214 }
215
216 /* Locate the file referenced by NAME, searching along the contents
217    of the shell PATH variable.  Return a new string which is the full
218    pathname to the file, or NULL if the file couldn't be found.  This
219    returns the first readable file found; designed to be used to look
220    for shell scripts or files to source. */
221 char *
222 find_path_file (name)
223      const char *name;
224 {
225   return (find_user_command_internal (name, FS_READABLE));
226 }
227
228 static char *
229 _find_user_command_internal (name, flags)
230      const char *name;
231      int flags;
232 {
233   char *path_list, *cmd;
234   SHELL_VAR *var;
235
236   /* Search for the value of PATH in both the temporary environments and
237      in the regular list of variables. */
238   if (var = find_variable_internal ("PATH", 1)) /* XXX could be array? */
239     path_list = value_cell (var);
240   else
241     path_list = (char *)NULL;
242
243   if (path_list == 0 || *path_list == '\0')
244     return (savestring (name));
245
246   cmd = find_user_command_in_path (name, path_list, flags);
247
248   return (cmd);
249 }
250
251 static char *
252 find_user_command_internal (name, flags)
253      const char *name;
254      int flags;
255 {
256 #ifdef __WIN32__
257   char *res, *dotexe;
258
259   dotexe = (char *)xmalloc (strlen (name) + 5);
260   strcpy (dotexe, name);
261   strcat (dotexe, ".exe");
262   res = _find_user_command_internal (dotexe, flags);
263   free (dotexe);
264   if (res == 0)
265     res = _find_user_command_internal (name, flags);
266   return res;
267 #else
268   return (_find_user_command_internal (name, flags));
269 #endif
270 }
271
272 /* Return the next element from PATH_LIST, a colon separated list of
273    paths.  PATH_INDEX_POINTER is the address of an index into PATH_LIST;
274    the index is modified by this function.
275    Return the next element of PATH_LIST or NULL if there are no more. */
276 static char *
277 get_next_path_element (path_list, path_index_pointer)
278      char *path_list;
279      int *path_index_pointer;
280 {
281   char *path;
282
283   path = extract_colon_unit (path_list, path_index_pointer);
284
285   if (path == 0)
286     return (path);
287
288   if (*path == '\0')
289     {
290       free (path);
291       path = savestring (".");
292     }
293
294   return (path);
295 }
296
297 /* Look for PATHNAME in $PATH.  Returns either the hashed command
298    corresponding to PATHNAME or the first instance of PATHNAME found
299    in $PATH.  Returns a newly-allocated string. */
300 char *
301 search_for_command (pathname)
302      const char *pathname;
303 {
304   char *hashed_file, *command;
305   int temp_path, st;
306   SHELL_VAR *path;
307
308   hashed_file = command = (char *)NULL;
309
310   /* If PATH is in the temporary environment for this command, don't use the
311      hash table to search for the full pathname. */
312   path = find_variable_internal ("PATH", 1);
313   temp_path = path && tempvar_p (path);
314   if (temp_path == 0 && path)
315     path = (SHELL_VAR *)NULL;
316
317   /* Don't waste time trying to find hashed data for a pathname
318      that is already completely specified or if we're using a command-
319      specific value for PATH. */
320   if (path == 0 && absolute_program (pathname) == 0)
321     hashed_file = phash_search (pathname);
322
323   /* If a command found in the hash table no longer exists, we need to
324      look for it in $PATH.  Thank you Posix.2.  This forces us to stat
325      every command found in the hash table. */
326
327   if (hashed_file && (posixly_correct || check_hashed_filenames))
328     {
329       st = file_status (hashed_file);
330       if ((st & (FS_EXISTS|FS_EXECABLE)) != (FS_EXISTS|FS_EXECABLE))
331         {
332           phash_remove (pathname);
333           free (hashed_file);
334           hashed_file = (char *)NULL;
335         }
336     }
337
338   if (hashed_file)
339     command = hashed_file;
340   else if (absolute_program (pathname))
341     /* A command containing a slash is not looked up in PATH or saved in
342        the hash table. */
343     command = savestring (pathname);
344   else
345     {
346       /* If $PATH is in the temporary environment, we've already retrieved
347          it, so don't bother trying again. */
348       if (temp_path)
349         {
350           command = find_user_command_in_path (pathname, value_cell (path),
351                                                FS_EXEC_PREFERRED|FS_NODIRS);
352         }
353       else
354         command = find_user_command (pathname);
355       if (command && hashing_enabled && temp_path == 0)
356         phash_insert ((char *)pathname, command, dot_found_in_search, 1);       /* XXX fix const later */
357     }
358   return (command);
359 }
360
361 char *
362 user_command_matches (name, flags, state)
363      const char *name;
364      int flags, state;
365 {
366   register int i;
367   int  path_index, name_len;
368   char *path_list, *path_element, *match;
369   struct stat dotinfo;
370   static char **match_list = NULL;
371   static int match_list_size = 0;
372   static int match_index = 0;
373
374   if (state == 0)
375     {
376       /* Create the list of matches. */
377       if (match_list == 0)
378         {
379           match_list_size = 5;
380           match_list = strvec_create (match_list_size);
381         }
382
383       /* Clear out the old match list. */
384       for (i = 0; i < match_list_size; i++)
385         match_list[i] = 0;
386
387       /* We haven't found any files yet. */
388       match_index = 0;
389
390       if (absolute_program (name))
391         {
392           match_list[0] = find_absolute_program (name, flags);
393           match_list[1] = (char *)NULL;
394           path_list = (char *)NULL;
395         }
396       else
397         {
398           name_len = strlen (name);
399           file_to_lose_on = (char *)NULL;
400           dot_found_in_search = 0;
401           stat (".", &dotinfo);
402           path_list = get_string_value ("PATH");
403           path_index = 0;
404         }
405
406       while (path_list && path_list[path_index])
407         {
408           path_element = get_next_path_element (path_list, &path_index);
409
410           if (path_element == 0)
411             break;
412
413           match = find_in_path_element (name, path_element, flags, name_len, &dotinfo);
414
415           free (path_element);
416
417           if (match == 0)
418             continue;
419
420           if (match_index + 1 == match_list_size)
421             {
422               match_list_size += 10;
423               match_list = strvec_resize (match_list, (match_list_size + 1));
424             }
425
426           match_list[match_index++] = match;
427           match_list[match_index] = (char *)NULL;
428           FREE (file_to_lose_on);
429           file_to_lose_on = (char *)NULL;
430         }
431
432       /* We haven't returned any strings yet. */
433       match_index = 0;
434     }
435
436   match = match_list[match_index];
437
438   if (match)
439     match_index++;
440
441   return (match);
442 }
443
444 static char *
445 find_absolute_program (name, flags)
446      const char *name;
447      int flags;
448 {
449   int st;
450
451   st = file_status (name);
452
453   /* If the file doesn't exist, quit now. */
454   if ((st & FS_EXISTS) == 0)
455     return ((char *)NULL);
456
457   /* If we only care about whether the file exists or not, return
458      this filename.  Otherwise, maybe we care about whether this
459      file is executable.  If it is, and that is what we want, return it. */
460   if ((flags & FS_EXISTS) || ((flags & FS_EXEC_ONLY) && (st & FS_EXECABLE)))
461     return (savestring (name));
462
463   return (NULL);
464 }
465
466 static char *
467 find_in_path_element (name, path, flags, name_len, dotinfop)
468      const char *name;
469      char *path;
470      int flags, name_len;
471      struct stat *dotinfop;
472 {
473   int status;
474   char *full_path, *xpath;
475
476   xpath = (*path == '~') ? bash_tilde_expand (path, 0) : path;
477
478   /* Remember the location of "." in the path, in all its forms
479      (as long as they begin with a `.', e.g. `./.') */
480   if (dot_found_in_search == 0 && *xpath == '.')
481     dot_found_in_search = same_file (".", xpath, dotinfop, (struct stat *)NULL);
482
483   full_path = sh_makepath (xpath, name, 0);
484
485   status = file_status (full_path);
486
487   if (xpath != path)
488     free (xpath);
489
490   if ((status & FS_EXISTS) == 0)
491     {
492       free (full_path);
493       return ((char *)NULL);
494     }
495
496   /* The file exists.  If the caller simply wants the first file, here it is. */
497   if (flags & FS_EXISTS)
498     return (full_path);
499
500   /* If we have a readable file, and the caller wants a readable file, this
501      is it. */
502   if ((flags & FS_READABLE) && (status & FS_READABLE))
503     return (full_path);
504
505   /* If the file is executable, then it satisfies the cases of
506       EXEC_ONLY and EXEC_PREFERRED.  Return this file unconditionally. */
507   if ((status & FS_EXECABLE) && (flags & (FS_EXEC_ONLY|FS_EXEC_PREFERRED)) &&
508       (((flags & FS_NODIRS) == 0) || ((status & FS_DIRECTORY) == 0)))
509     {
510       FREE (file_to_lose_on);
511       file_to_lose_on = (char *)NULL;
512       return (full_path);
513     }
514
515   /* The file is not executable, but it does exist.  If we prefer
516      an executable, then remember this one if it is the first one
517      we have found. */
518   if ((flags & FS_EXEC_PREFERRED) && file_to_lose_on == 0)
519     file_to_lose_on = savestring (full_path);
520
521   /* If we want only executable files, or we don't want directories and
522      this file is a directory, or we want a readable file and this file
523      isn't readable, fail. */
524   if ((flags & (FS_EXEC_ONLY|FS_EXEC_PREFERRED)) ||
525       ((flags & FS_NODIRS) && (status & FS_DIRECTORY)) ||
526       ((flags & FS_READABLE) && (status & FS_READABLE) == 0))
527     {
528       free (full_path);
529       return ((char *)NULL);
530     }
531   else
532     return (full_path);
533 }
534
535 /* This does the dirty work for find_user_command_internal () and
536    user_command_matches ().
537    NAME is the name of the file to search for.
538    PATH_LIST is a colon separated list of directories to search.
539    FLAGS contains bit fields which control the files which are eligible.
540    Some values are:
541       FS_EXEC_ONLY:             The file must be an executable to be found.
542       FS_EXEC_PREFERRED:        If we can't find an executable, then the
543                                 the first file matching NAME will do.
544       FS_EXISTS:                The first file found will do.
545       FS_NODIRS:                Don't find any directories.
546 */
547 static char *
548 find_user_command_in_path (name, path_list, flags)
549      const char *name;
550      char *path_list;
551      int flags;
552 {
553   char *full_path, *path;
554   int path_index, name_len;
555   struct stat dotinfo;
556
557   /* We haven't started looking, so we certainly haven't seen
558      a `.' as the directory path yet. */
559   dot_found_in_search = 0;
560
561   if (absolute_program (name))
562     {
563       full_path = find_absolute_program (name, flags);
564       return (full_path);
565     }
566
567   if (path_list == 0 || *path_list == '\0')
568     return (savestring (name));         /* XXX */
569
570   file_to_lose_on = (char *)NULL;
571   name_len = strlen (name);
572   stat (".", &dotinfo);
573   path_index = 0;
574
575   while (path_list[path_index])
576     {
577       /* Allow the user to interrupt out of a lengthy path search. */
578       QUIT;
579
580       path = get_next_path_element (path_list, &path_index);
581       if (path == 0)
582         break;
583
584       /* Side effects: sets dot_found_in_search, possibly sets
585          file_to_lose_on. */
586       full_path = find_in_path_element (name, path, flags, name_len, &dotinfo);
587       free (path);
588
589       /* This should really be in find_in_path_element, but there isn't the
590          right combination of flags. */
591       if (full_path && is_directory (full_path))
592         {
593           free (full_path);
594           continue;
595         }
596
597       if (full_path)
598         {
599           FREE (file_to_lose_on);
600           return (full_path);
601         }
602     }
603
604   /* We didn't find exactly what the user was looking for.  Return
605      the contents of FILE_TO_LOSE_ON which is NULL when the search
606      required an executable, or non-NULL if a file was found and the
607      search would accept a non-executable as a last resort.  If the
608      caller specified FS_NODIRS, and file_to_lose_on is a directory,
609      return NULL. */
610   if (file_to_lose_on && (flags & FS_NODIRS) && is_directory (file_to_lose_on))
611     {
612       free (file_to_lose_on);
613       file_to_lose_on = (char *)NULL;
614     }
615
616   return (file_to_lose_on);
617 }