+/* Recursively scan the given directory. */
+static void
+scan_directory (struct obstack *stk, char *dir_name, dev_t device)
+{
+ char *dirp = savedir (dir_name); /* for scanning directory */
+ char const *entry; /* directory entry being scanned */
+ size_t entrylen; /* length of directory entry */
+ char *name_buffer; /* directory, `/', and directory member */
+ size_t name_buffer_size; /* allocated size of name_buffer, minus 2 */
+ size_t name_length; /* used length in name_buffer */
+ enum children children;
+ struct stat stat_data;
+
+ if (! dirp)
+ savedir_error (dir_name);
+
+ name_buffer_size = strlen (dir_name) + NAME_FIELD_SIZE;
+ name_buffer = xmalloc (name_buffer_size + 2);
+ strcpy (name_buffer, dir_name);
+ if (! ISSLASH (dir_name[strlen (dir_name) - 1]))
+ strcat (name_buffer, "/");
+ name_length = strlen (name_buffer);
+
+ if (deref_stat (dereference_option, name_buffer, &stat_data))
+ {
+ stat_diag (name_buffer);
+ children = CHANGED_CHILDREN;
+ }
+ else
+ children = procdir (name_buffer, &stat_data, device, NO_CHILDREN, false);
+
+ if (dirp && children != NO_CHILDREN)
+ for (entry = dirp;
+ (entrylen = strlen (entry)) != 0;
+ entry += entrylen + 1)
+ {
+ if (name_buffer_size <= entrylen + name_length)
+ {
+ do
+ name_buffer_size += NAME_FIELD_SIZE;
+ while (name_buffer_size <= entrylen + name_length);
+ name_buffer = xrealloc (name_buffer, name_buffer_size + 2);
+ }
+ strcpy (name_buffer + name_length, entry);
+
+ if (excluded_name (name_buffer))
+ obstack_1grow (stk, 'N');
+ else
+ {
+
+ if (deref_stat (dereference_option, name_buffer, &stat_data))
+ {
+ stat_diag (name_buffer);
+ continue;
+ }
+
+ if (S_ISDIR (stat_data.st_mode))
+ {
+ procdir (name_buffer, &stat_data, device, children,
+ verbose_option);
+ obstack_1grow (stk, 'D');
+ }
+
+ else if (one_file_system_option && device != stat_data.st_dev)
+ obstack_1grow (stk, 'N');