/* Various processing of names.
- Copyright (C) 1988, 1992, 1994, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1988, 92, 94, 96, 97, 98, 1999 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
- 59 Place - Suite 330, Boston, MA 02111-1307, USA. */
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "system.h"
static uid_t cached_uid; /* valid only if cached_uname is not empty */
static gid_t cached_gid; /* valid only if cached_gname is not empty */
+/* These variables are valid only if nonempty. */
+static char cached_no_such_uname[UNAME_FIELD_SIZE] = "";
+static char cached_no_such_gname[GNAME_FIELD_SIZE] = "";
+
+/* These variables are valid only if nonzero. It's not worth optimizing
+ the case for weird systems where 0 is not a valid uid or gid. */
+static uid_t cached_no_such_uid = 0;
+static gid_t cached_no_such_gid = 0;
+
/*------------------------------------------.
| Given UID, find the corresponding UNAME. |
`------------------------------------------*/
{
struct passwd *passwd;
+ if (uid != 0 && uid == cached_no_such_uid)
+ {
+ *uname = '\0';
+ return;
+ }
+
if (!cached_uname[0] || uid != cached_uid)
{
passwd = getpwuid (uid);
strncpy (cached_uname, passwd->pw_name, UNAME_FIELD_SIZE);
}
else
- *uname = '\0';
+ {
+ cached_no_such_uid = uid;
+ *uname = '\0';
+ return;
+ }
}
strncpy (uname, cached_uname, UNAME_FIELD_SIZE);
}
{
struct group *group;
+ if (gid != 0 && gid == cached_no_such_gid)
+ {
+ *gname = '\0';
+ return;
+ }
+
if (!cached_gname[0] || gid != cached_gid)
{
setgrent (); /* FIXME: why?! */
strncpy (cached_gname, group->gr_name, GNAME_FIELD_SIZE);
}
else
- *gname = '\0';
+ {
+ cached_no_such_gid = gid;
+ *gname = '\0';
+ return;
+ }
}
strncpy (gname, cached_gname, GNAME_FIELD_SIZE);
}
{
struct passwd *passwd;
+ if (cached_no_such_uname[0]
+ && strncmp (uname, cached_no_such_uname, UNAME_FIELD_SIZE) == 0)
+ return 0;
+
if (!cached_uname[0]
|| uname[0] != cached_uname[0]
|| strncmp (uname, cached_uname, UNAME_FIELD_SIZE) != 0)
strncpy (cached_uname, uname, UNAME_FIELD_SIZE);
}
else
- return 0;
+ {
+ strncpy (cached_no_such_uname, uname, UNAME_FIELD_SIZE);
+ return 0;
+ }
}
*uidp = cached_uid;
return 1;
{
struct group *group;
+ if (cached_no_such_gname[0]
+ && strncmp (gname, cached_no_such_gname, GNAME_FIELD_SIZE) == 0)
+ return 0;
+
if (!cached_gname[0]
|| gname[0] != cached_gname[0]
|| strncmp (gname, cached_gname, GNAME_FIELD_SIZE) != 0)
strncpy (cached_gname, gname, GNAME_FIELD_SIZE);
}
else
- return 0;
+ {
+ strncpy (cached_no_such_gname, gname, GNAME_FIELD_SIZE);
+ return 0;
+ }
}
*gidp = cached_gid;
return 1;
name_file = stdin;
}
else if (name_file = fopen (files_from_option, "r"), !name_file)
- FATAL_ERROR ((0, errno, _("Cannot open file %s"), name_file));
+ FATAL_ERROR ((0, errno, _("Cannot open file %s"), files_from_option));
}
}
read_name_from_file (void)
{
int character;
- int counter = 0;
+ size_t counter = 0;
/* FIXME: getc may be called even if character was EOF the last time here. */
else if (change_dirs && strcmp (name_buffer, "-C") == 0)
chdir_flag = 1;
else
-#if 0
- if (!exclude_option || !check_exclude (name_buffer))
-#endif
- {
- unquote_string (name_buffer);
- return name_buffer;
- }
+ {
+ unquote_string (name_buffer);
+ return name_buffer;
+ }
}
/* No more names in file. */
{
/* Buffer able to hold a single name. */
static struct name *buffer;
- static int allocated_length = 0;
+ static size_t allocated_length = 0;
char *name;
static char *chdir_name = NULL;
struct name *name;
- int length;
+ size_t length;
if (strcmp (string, "-C") == 0)
{
}
length = string ? strlen (string) : 0;
- name = (struct name *) xmalloc ((size_t) (sizeof (struct name) + length));
+ name = (struct name *) xmalloc (sizeof (struct name) + length);
memset (name, 0, sizeof (struct name) + length);
name->next = NULL;
name->fake = 0;
name->length = length;
/* FIXME: Possibly truncating a string, here? Tss, tss, tss! */
- strncpy (name->name, string, (size_t) length);
+ strncpy (name->name, string, length);
name->name[length] = '\0';
}
else
int
name_match (const char *path)
{
- int length = strlen (path);
+ size_t length = strlen (path);
while (1)
{
&& (path[cursor->length] == '\0'
|| path[cursor->length] == '/')
/* full match on file/dirname */
- && strncmp (path, cursor->name, (size_t) cursor->length) == 0)
+ && strncmp (path, cursor->name, cursor->length) == 0)
/* name compare */
{
cursor->found = 1; /* remember it matched */
struct name *
name_scan (const char *path)
{
- int length = strlen (path);
+ size_t length = strlen (path);
while (1)
{
&& (path[cursor->length] == '\0'
|| path[cursor->length] == '/')
/* full match on file/dirname */
- && strncmp (path, cursor->name, (size_t) cursor->length) == 0)
+ && strncmp (path, cursor->name, cursor->length) == 0)
/* name compare */
return cursor; /* we got a match */
}
sprintf (buffer, "%s/%s", path, name);
return buffer;
}
-\f
-/* Excludes names. */
-
-static char *exclude_pool = NULL;
-static int exclude_pool_size = 0;
-static int allocated_exclude_pool_size = 0;
-
-static char **simple_exclude_array = NULL;
-static int simple_excludes = 0;
-static int allocated_simple_excludes = 0;
-
-static char **pattern_exclude_array = NULL;
-static int pattern_excludes = 0;
-static int allocated_pattern_excludes = 0;
-
-/*---.
-| ? |
-`---*/
-
-void
-add_exclude (char *name)
-{
- int name_size;
-
- unquote_string (name); /* FIXME: unquote in all cases? If ever? */
- name_size = strlen (name) + 1;
-
- if (exclude_pool_size + name_size > allocated_exclude_pool_size)
- {
- char *previous_exclude_pool = exclude_pool;
- char **cursor;
-
- allocated_exclude_pool_size = exclude_pool_size + name_size + 1024;
- exclude_pool = (char *)
- xrealloc (exclude_pool, (size_t) allocated_exclude_pool_size);
-
- for (cursor = simple_exclude_array;
- cursor < simple_exclude_array + simple_excludes;
- cursor++)
- *cursor = exclude_pool + (*cursor - previous_exclude_pool);
- for (cursor = pattern_exclude_array;
- cursor < pattern_exclude_array + pattern_excludes;
- cursor++)
- *cursor = exclude_pool + (*cursor - previous_exclude_pool);
- }
-
- if (is_pattern (name))
- {
- if (pattern_excludes == allocated_pattern_excludes)
- {
- allocated_pattern_excludes += 32;
- pattern_exclude_array = (char **)
- xrealloc (pattern_exclude_array,
- allocated_pattern_excludes * sizeof (char *));
- }
- pattern_exclude_array[pattern_excludes++]
- = exclude_pool + exclude_pool_size;
- }
- else
- {
- if (simple_excludes == allocated_simple_excludes)
- {
- allocated_simple_excludes += 32;
- simple_exclude_array = (char **)
- xrealloc (simple_exclude_array,
- allocated_simple_excludes * sizeof (char *));
- }
- simple_exclude_array[simple_excludes++]
- = exclude_pool + exclude_pool_size;
- }
-
- strcpy (exclude_pool + exclude_pool_size, name);
- exclude_pool_size += name_size;
-}
-
-/*---.
-| ? |
-`---*/
-
-void
-add_exclude_file (const char *name)
-{
- FILE *file;
- char buffer[1024];
-
- if (strcmp (name, "-"))
- file = fopen (name, "r");
- else
- {
- request_stdin ("-X");
- file = stdin;
- }
- if (!file)
- FATAL_ERROR ((0, errno, _("Cannot open %s"), name));
-
- while (fgets (buffer, 1024, file))
- {
- char *end_of_line = strrchr (buffer, '\n');
-
- if (end_of_line)
- *end_of_line = '\0';
- add_exclude (buffer);
- }
- if (fclose (file) == EOF)
- ERROR ((0, errno, "%s", name));
-}
-
-/*------------------------------------------------------------------.
-| Returns true if the file NAME should not be added nor extracted. |
-`------------------------------------------------------------------*/
-
-int
-check_exclude (const char *name)
-{
- int counter;
-
- for (counter = 0; counter < pattern_excludes; counter++)
- if (fnmatch (pattern_exclude_array[counter], name, FNM_LEADING_DIR) == 0)
- return 1;
-
- for (counter = 0; counter < simple_excludes; counter++)
- {
- /* Accept the output from strstr only if it is the last part of the
- string. FIXME: Find a faster way to do this. */
-
- char *string = strstr (name, simple_exclude_array[counter]);
-
- if (string
- && (string == name || string[-1] == '/')
- && string[strlen (simple_exclude_array[counter])] == '\0')
- return 1;
- }
- return 0;
-}