Imported from ../bash-2.01.tar.gz.

This commit is contained in:
Jari Aalto 1997-06-05 14:59:13 +00:00
commit d166f04881
304 changed files with 14702 additions and 13012 deletions

View file

@ -23,6 +23,10 @@
# include <config.h>
#endif
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#if defined (HAVE_STRING_H)
# include <string.h>
#else /* !HAVE_STRING_H */
@ -40,6 +44,10 @@
#include "tilde.h"
#ifdef SHELL
#include "shell.h"
#endif
#if !defined (HAVE_GETPW_DECLS)
extern struct passwd *getpwuid (), *getpwnam ();
#endif /* !HAVE_GETPW_DECLS */
@ -78,6 +86,12 @@ static char *default_prefixes[] =
static char *default_suffixes[] =
{ " ", "\n", (char *)NULL };
/* If non-null, this contains the address of a function that the application
wants called before trying the standard tilde expansions. The function
is called with the text sans tilde, and returns a malloc()'ed string
which is the expansion, or a NULL pointer if the expansion fails. */
CPFunction *tilde_expansion_preexpansion_hook = (CPFunction *)NULL;
/* If non-null, this contains the address of a function to call if the
standard meaning for expanding a tilde fails. The function is called
with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
@ -108,7 +122,7 @@ tilde_find_prefix (string, len)
string_len = strlen (string);
*len = 0;
if (!*string || *string == '~')
if (*string == '\0' || *string == '~')
return (0);
if (prefixes)
@ -135,13 +149,14 @@ tilde_find_suffix (string)
char *string;
{
register int i, j, string_len;
register char **suffixes = tilde_additional_suffixes;
register char **suffixes;
suffixes = tilde_additional_suffixes;
string_len = strlen (string);
for (i = 0; i < string_len; i++)
{
if (string[i] == '/' || !string[i])
if (string[i] == '/' /* || !string[i] */)
break;
for (j = 0; suffixes && suffixes[j]; j++)
@ -153,16 +168,28 @@ tilde_find_suffix (string)
return (i);
}
#if !defined (SHELL)
static char *
get_string_value (varname)
char *varname;
{
return ((char *)getenv (varname));
}
#endif
/* Return a new string which is the result of tilde expanding STRING. */
char *
tilde_expand (string)
char *string;
{
char *result, *tilde_expand_word ();
char *result;
int result_size, result_index;
result_size = result_index = 0;
result = (char *)NULL;
result_index = result_size = 0;
if (result = strchr (string, '~'))
result = xmalloc (result_size = (strlen (string) + 16));
else
result = xmalloc (result_size = strlen (string));
/* Scan through STRING expanding tildes as we come to them. */
while (1)
@ -215,97 +242,143 @@ tilde_expand (string)
return (result);
}
/* Take FNAME and return the tilde prefix we want expanded. If LENP is
non-null, the index of the end of the prefix into FNAME is returned in
the location it points to. */
static char *
isolate_tilde_prefix (fname, lenp)
char *fname;
int *lenp;
{
char *ret;
int i;
ret = xmalloc (strlen (fname));
for (i = 1; fname[i] && fname[i] != '/'; i++)
ret[i - 1] = fname[i];
ret[i - 1] = '\0';
if (lenp)
*lenp = i;
return ret;
}
/* Return a string that is PREFIX concatenated with SUFFIX starting at
SUFFIND. */
static char *
glue_prefix_and_suffix (prefix, suffix, suffind)
char *prefix, *suffix;
int suffind;
{
char *ret;
int plen, slen;
plen = (prefix && *prefix) ? strlen (prefix) : 0;
slen = strlen (suffix + suffind);
ret = xmalloc (plen + slen + 1);
if (prefix && *prefix)
strcpy (ret, prefix);
strcpy (ret + plen, suffix + suffind);
return ret;
}
static char *
get_home_dir ()
{
char *home_dir;
#ifdef SHELL
home_dir = (char *)NULL;
if (current_user.home_dir == 0)
get_current_user_info ();
home_dir = current_user.home_dir;
#else
struct passwd *entry;
home_dir = (char *)NULL;
entry = getpwuid (getuid ());
if (entry)
home_dir = entry->pw_dir;
#endif
return (home_dir);
}
/* Do the work of tilde expansion on FILENAME. FILENAME starts with a
tilde. If there is no expansion, call tilde_expansion_failure_hook. */
tilde. If there is no expansion, call tilde_expansion_failure_hook.
This always returns a newly-allocated string, never static storage. */
char *
tilde_expand_word (filename)
char *filename;
{
char *dirname;
char *temp_name;
char *dirname, *expansion, *username;
int user_len;
struct passwd *user_entry;
if (filename == (char *)0)
if (filename == 0)
return ((char *)NULL);
dirname = savestring (filename);
if (*filename != '~')
return (savestring (filename));
if (*dirname != '~')
return (dirname);
if (!dirname[1] || dirname[1] == '/')
/* A leading `~/' or a bare `~' is *always* translated to the value of
$HOME or the home directory of the current user, regardless of any
preexpansion hook. */
if (filename[1] == '\0' || filename[1] == '/')
{
/* Prepend $HOME to the rest of the string. */
char *temp_home = (char *)getenv ("HOME");
int home_len;
/* Prefix $HOME to the rest of the string. */
expansion = get_string_value ("HOME");
/* If there is no HOME variable, look up the directory in
the password database. */
if (!temp_home)
if (expansion == 0)
expansion = get_home_dir ();
return (glue_prefix_and_suffix (expansion, filename, 1));
}
username = isolate_tilde_prefix (filename, &user_len);
if (tilde_expansion_preexpansion_hook)
{
expansion = (*tilde_expansion_preexpansion_hook) (username);
if (expansion)
{
struct passwd *entry;
entry = getpwuid (getuid ());
if (entry)
temp_home = entry->pw_dir;
dirname = glue_prefix_and_suffix (expansion, filename, user_len);
free (username);
free (expansion);
return (dirname);
}
}
home_len = temp_home ? strlen (temp_home) : 0;
temp_name = xmalloc (1 + strlen (dirname + 1) + home_len);
if (temp_home)
strcpy (temp_name, temp_home);
strcpy (temp_name + home_len, dirname + 1);
free (dirname);
dirname = temp_name;
/* No preexpansion hook, or the preexpansion hook failed. Look in the
password database. */
dirname = (char *)NULL;
user_entry = getpwnam (username);
if (user_entry == 0)
{
/* If the calling program has a special syntax for expanding tildes,
and we couldn't find a standard expansion, then let them try. */
if (tilde_expansion_failure_hook)
{
expansion = (*tilde_expansion_failure_hook) (username);
if (expansion)
{
dirname = glue_prefix_and_suffix (expansion, filename, user_len);
free (expansion);
}
}
free (username);
/* If we don't have a failure hook, or if the failure hook did not
expand the tilde, return a copy of what we were passed. */
if (dirname == 0)
dirname = savestring (filename);
}
else
{
char *username;
struct passwd *user_entry;
int i, len;
username = xmalloc (strlen (dirname));
for (i = 1; dirname[i] && dirname[i] != '/'; i++)
username[i - 1] = dirname[i];
username[i - 1] = '\0';
if ((user_entry = getpwnam (username)) == (struct passwd *)0)
{
/* If the calling program has a special syntax for
expanding tildes, and we couldn't find a standard
expansion, then let them try. */
if (tilde_expansion_failure_hook)
{
char *expansion;
expansion = (*tilde_expansion_failure_hook) (username);
if (expansion)
{
len = strlen (expansion);
temp_name = xmalloc (1 + len + strlen (dirname + i));
strcpy (temp_name, expansion);
strcpy (temp_name + len, dirname + i);
free (expansion);
free (dirname);
dirname = temp_name;
}
}
/* We shouldn't report errors. */
}
else
{
len = strlen (user_entry->pw_dir);
temp_name = xmalloc (1 + len + strlen (dirname + i));
strcpy (temp_name, user_entry->pw_dir);
strcpy (temp_name + len, dirname + i);
free (dirname);
dirname = temp_name;
}
endpwent ();
free (username);
dirname = glue_prefix_and_suffix (user_entry->pw_dir, filename, user_len);
}
endpwent ();
return (dirname);
}