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