/* Various processing of names.
- Copyright 1988, 92, 94, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
+
+ Copyright 1988, 1992, 1994, 1996, 1997, 1998, 1999, 2000, 2001 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
{
if (counter == name_buffer_length)
{
- name_buffer_length += NAME_FIELD_SIZE;
+ if (name_buffer_length * 2 < name_buffer_length)
+ xalloc_die ();
+ name_buffer_length *= 2;
name_buffer = xrealloc (name_buffer, name_buffer_length + 2);
}
name_buffer[counter++] = character;
if (counter == name_buffer_length)
{
- name_buffer_length += NAME_FIELD_SIZE;
+ if (name_buffer_length * 2 < name_buffer_length)
+ xalloc_die ();
+ name_buffer_length *= 2;
name_buffer = xrealloc (name_buffer, name_buffer_length + 2);
}
name_buffer[counter] = '\0';
}
else
{
+ size_t source_len;
source = name_array[name_index++];
- if (strlen (source) > name_buffer_length)
+ source_len = strlen (source);
+ if (name_buffer_length < source_len)
{
+ do
+ {
+ name_buffer_length *= 2;
+ if (! name_buffer_length)
+ xalloc_die ();
+ }
+ while (name_buffer_length < source_len);
+
free (name_buffer);
- name_buffer_length = strlen (source);
name_buffer = xmalloc (name_buffer_length + 2);
}
strcpy (name_buffer, source);
/* Zap trailing slashes. */
cursor = name_buffer + strlen (name_buffer) - 1;
- while (cursor > name_buffer && *cursor == '/')
+ while (cursor > name_buffer && ISSLASH (*cursor))
*cursor-- = '\0';
if (chdir_flag)
{
/* Buffer able to hold a single name. */
static struct name *buffer;
- static size_t allocated_length;
+ static size_t allocated_size;
char const *name;
{
static int change_dir;
- if (allocated_length == 0)
+ if (allocated_size == 0)
{
- allocated_length = sizeof (struct name) + NAME_FIELD_SIZE;
- buffer = xmalloc (allocated_length);
+ allocated_size = offsetof (struct name, name) + NAME_FIELD_SIZE + 1;
+ buffer = xmalloc (allocated_size);
/* FIXME: This memset is overkill, and ugly... */
- memset (buffer, 0, allocated_length);
+ memset (buffer, 0, allocated_size);
}
while ((name = name_next (0)) && strcmp (name, "-C") == 0)
if (name)
{
+ size_t needed_size;
buffer->length = strlen (name);
- if (sizeof (struct name) + buffer->length >= allocated_length)
+ needed_size = offsetof (struct name, name) + buffer->length + 1;
+ if (allocated_size < needed_size)
{
- allocated_length = sizeof (struct name) + buffer->length;
- buffer = xrealloc (buffer, allocated_length);
+ do
+ {
+ allocated_size *= 2;
+ if (! allocated_size)
+ xalloc_die ();
+ }
+ while (allocated_size < needed_size);
+
+ buffer = xrealloc (buffer, allocated_size);
}
buffer->change_dir = change_dir;
- memcpy (buffer->name, name, buffer->length + 1);
+ strcpy (buffer->name, name);
buffer->next = 0;
buffer->found = 0;
struct name *
addname (char const *string, int change_dir)
{
- struct name *name;
- size_t length;
-
- length = string ? strlen (string) : 0;
- name = xmalloc (sizeof (struct name) + length);
- memset (name, 0, sizeof (struct name) + length);
- name->next = 0;
+ size_t length = string ? strlen (string) : 0;
+ struct name *name = xmalloc (offsetof (struct name, name) + length + 1);
if (string)
{
name->fake = 0;
- name->length = length;
- memcpy (name->name, string, length + 1);
+ strcpy (name->name, string);
}
else
- name->fake = 1;
+ {
+ name->fake = 1;
+ /* FIXME: This initialization (and the byte of memory that it
+ initializes) is probably not needed, but we are currently in
+ bug-fix mode so we'll leave it in for now. */
+ name->name[0] = 0;
+ }
+
+ name->next = 0;
+ name->length = length;
name->found = 0;
name->regexp = 0; /* assume not a regular expression */
name->firstch = 1; /* assume first char is literal */
if (p->regexp
? fnmatch (p->name, path, recursion_option) == 0
: (p->length <= length
- && (path[p->length] == '\0' || path[p->length] == '/')
+ && (path[p->length] == '\0' || ISSLASH (path[p->length]))
&& memcmp (path, p->name, p->length) == 0))
return p;
}
}
\f
/* Add all the dirs under NAME, which names a directory, to the namelist.
- DIRSIZE is the size of the directory, or -1 if not known.
If any of the files is a directory, recurse on the subdirectory.
DEVICE is the device not to leave, if the -l option is specified. */
static void
-add_hierarchy_to_namelist (struct name *name, off_t dirsize, dev_t device)
+add_hierarchy_to_namelist (struct name *name, dev_t device)
{
char *path = name->name;
- char *buffer = get_directory_contents (path, dirsize, device);
+ char *buffer = get_directory_contents (path, device);
if (! buffer)
name->dir_contents = "\0\0\0\0";
name->dir_contents = buffer;
strcpy (name_buffer, path);
- if (name_buffer[name_length - 1] != '/')
+ if (! ISSLASH (name_buffer[name_length - 1]))
{
name_buffer[name_length++] = '/';
name_buffer[name_length] = '\0';
string_length = strlen (string);
if (*string == 'D')
{
- if (name_length + string_length >= allocated_length)
+ if (allocated_length <= name_length + string_length)
{
- while (name_length + string_length >= allocated_length)
- allocated_length += NAME_FIELD_SIZE;
+ do
+ {
+ allocated_length *= 2;
+ if (! allocated_length)
+ xalloc_die ();
+ }
+ while (allocated_length <= name_length + string_length);
+
name_buffer = xrealloc (name_buffer, allocated_length + 1);
}
strcpy (name_buffer + name_length, string + 1);
add_hierarchy_to_namelist (addname (name_buffer, change_dir),
- -1, device);
+ device);
}
}
if (deref_stat (dereference_option, name->name, &statbuf) != 0)
{
- stat_error (name->name);
+ if (ignore_failed_read_option)
+ stat_warn (name->name);
+ else
+ stat_error (name->name);
continue;
}
if (S_ISDIR (statbuf.st_mode))
{
name->found = 1;
- add_hierarchy_to_namelist (name, statbuf.st_size, statbuf.st_dev);
+ add_hierarchy_to_namelist (name, statbuf.st_dev);
}
}
{
size_t pathlen = strlen (path);
size_t namesize = strlen (name) + 1;
- int slash = pathlen && path[pathlen - 1] != '/';
+ int slash = pathlen && ! ISSLASH (path[pathlen - 1]);
char *buffer = xmalloc (pathlen + slash + namesize);
memcpy (buffer, path, pathlen);
buffer[pathlen] = '/';
/* Return nonzero if file NAME is excluded. Exclude a name if its
prefix matches a pattern that contains slashes, or if one of its
components matches a pattern that contains no slashes. */
-int
+bool
excluded_name (char const *name)
{
- char const *p;
- name += FILESYSTEM_PREFIX_LEN (name);
-
- if (excluded_filename (excluded_with_slash, name,
- FNM_FILE_NAME | recursion_option))
- return 1;
-
- for (p = name; *p; p++)
- if (((p == name || ISSLASH (p[-1])) && !ISSLASH (p[0]))
- && excluded_filename (excluded_without_slash, p,
- FNM_FILE_NAME | FNM_LEADING_DIR))
- return 1;
-
- return 0;
+ return excluded_filename (excluded, name + FILESYSTEM_PREFIX_LEN (name));
}
\f
/* Names to avoid dumping. */