1/* Various processing of names.
2
3   Copyright (C) 1988, 1992, 1994, 1996, 1997, 1998, 1999, 2000, 2001,
4   2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5
6   This program is free software; you can redistribute it and/or modify it
7   under the terms of the GNU General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any later
9   version.
10
11   This program is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
14   Public License for more details.
15
16   You should have received a copy of the GNU General Public License along
17   with this program; if not, write to the Free Software Foundation, Inc.,
18   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
19
20#include <system.h>
21
22#include <fnmatch.h>
23#include <hash.h>
24#include <quotearg.h>
25
26#include "common.h"
27
28/* User and group names.  */
29
30struct group *getgrnam ();
31struct passwd *getpwnam ();
32#if ! HAVE_DECL_GETPWUID
33struct passwd *getpwuid ();
34#endif
35#if ! HAVE_DECL_GETGRGID
36struct group *getgrgid ();
37#endif
38
39/* Make sure you link with the proper libraries if you are running the
40   Yellow Peril (thanks for the good laugh, Ian J.!), or, euh... NIS.
41   This code should also be modified for non-UNIX systems to do something
42   reasonable.  */
43
44static char *cached_uname;
45static char *cached_gname;
46
47static uid_t cached_uid;	/* valid only if cached_uname is not empty */
48static gid_t cached_gid;	/* valid only if cached_gname is not empty */
49
50/* These variables are valid only if nonempty.  */
51static char *cached_no_such_uname;
52static char *cached_no_such_gname;
53
54/* These variables are valid only if nonzero.  It's not worth optimizing
55   the case for weird systems where 0 is not a valid uid or gid.  */
56static uid_t cached_no_such_uid;
57static gid_t cached_no_such_gid;
58
59static void register_individual_file (char const *name);
60
61/* Given UID, find the corresponding UNAME.  */
62void
63uid_to_uname (uid_t uid, char **uname)
64{
65  struct passwd *passwd;
66
67  if (uid != 0 && uid == cached_no_such_uid)
68    {
69      *uname = xstrdup ("");
70      return;
71    }
72
73  if (!cached_uname || uid != cached_uid)
74    {
75      passwd = getpwuid (uid);
76      if (passwd)
77	{
78	  cached_uid = uid;
79	  assign_string (&cached_uname, passwd->pw_name);
80	}
81      else
82	{
83	  cached_no_such_uid = uid;
84	  *uname = xstrdup ("");
85	  return;
86	}
87    }
88  *uname = xstrdup (cached_uname);
89}
90
91/* Given GID, find the corresponding GNAME.  */
92void
93gid_to_gname (gid_t gid, char **gname)
94{
95  struct group *group;
96
97  if (gid != 0 && gid == cached_no_such_gid)
98    {
99      *gname = xstrdup ("");
100      return;
101    }
102
103  if (!cached_gname || gid != cached_gid)
104    {
105      group = getgrgid (gid);
106      if (group)
107	{
108	  cached_gid = gid;
109	  assign_string (&cached_gname, group->gr_name);
110	}
111      else
112	{
113	  cached_no_such_gid = gid;
114	  *gname = xstrdup ("");
115	  return;
116	}
117    }
118  *gname = xstrdup (cached_gname);
119}
120
121/* Given UNAME, set the corresponding UID and return 1, or else, return 0.  */
122int
123uname_to_uid (char const *uname, uid_t *uidp)
124{
125  struct passwd *passwd;
126
127  if (cached_no_such_uname
128      && strcmp (uname, cached_no_such_uname) == 0)
129    return 0;
130
131  if (!cached_uname
132      || uname[0] != cached_uname[0]
133      || strcmp (uname, cached_uname) != 0)
134    {
135      passwd = getpwnam (uname);
136      if (passwd)
137	{
138	  cached_uid = passwd->pw_uid;
139	  assign_string (&cached_uname, passwd->pw_name);
140	}
141      else
142	{
143	  assign_string (&cached_no_such_uname, uname);
144	  return 0;
145	}
146    }
147  *uidp = cached_uid;
148  return 1;
149}
150
151/* Given GNAME, set the corresponding GID and return 1, or else, return 0.  */
152int
153gname_to_gid (char const *gname, gid_t *gidp)
154{
155  struct group *group;
156
157  if (cached_no_such_gname
158      && strcmp (gname, cached_no_such_gname) == 0)
159    return 0;
160
161  if (!cached_gname
162      || gname[0] != cached_gname[0]
163      || strcmp (gname, cached_gname) != 0)
164    {
165      group = getgrnam (gname);
166      if (group)
167	{
168	  cached_gid = group->gr_gid;
169	  assign_string (&cached_gname, gname);
170	}
171      else
172	{
173	  assign_string (&cached_no_such_gname, gname);
174	  return 0;
175	}
176    }
177  *gidp = cached_gid;
178  return 1;
179}
180
181
182/* Names from the command call.  */
183
184static struct name *namelist;	/* first name in list, if any */
185static struct name **nametail = &namelist;	/* end of name list */
186
187/* File name arguments are processed in two stages: first a
188   name_array (see below) is filled, then the names from it
189   are moved into the namelist.
190
191   This awkward process is needed only to implement --same-order option,
192   which is meant to help process large archives on machines with
193   limited memory.  With this option on, namelist contains at most one
194   entry, which diminishes the memory consumption.
195
196   However, I very much doubt if we still need this -- Sergey */
197
198/* A name_array element contains entries of three types: */
199
200#define NELT_NAME  0   /* File name */
201#define NELT_CHDIR 1   /* Change directory request */
202#define NELT_FMASK 2   /* Change fnmatch options request */
203
204struct name_elt        /* A name_array element. */
205{
206  char type;           /* Element type, see NELT_* constants above */
207  union
208  {
209    const char *name;  /* File or directory name */
210    int matching_flags;/* fnmatch options if type == NELT_FMASK */
211  } v;
212};
213
214static struct name_elt *name_array;  /* store an array of names */
215static size_t allocated_names;	 /* how big is the array? */
216static size_t names;		 /* how many entries does it have? */
217static size_t name_index;	 /* how many of the entries have we scanned? */
218
219/* Check the size of name_array, reallocating it as necessary.  */
220static void
221check_name_alloc ()
222{
223  if (names == allocated_names)
224    {
225      if (allocated_names == 0)
226	allocated_names = 10; /* Set initial allocation */
227      name_array = x2nrealloc (name_array, &allocated_names,
228			       sizeof (name_array[0]));
229    }
230}
231
232/* Add to name_array the file NAME with fnmatch options MATCHING_FLAGS */
233void
234name_add_name (const char *name, int matching_flags)
235{
236  static int prev_flags = 0; /* FIXME: Or EXCLUDE_ANCHORED? */
237  struct name_elt *ep;
238
239  check_name_alloc ();
240  ep = &name_array[names++];
241  if (prev_flags != matching_flags)
242    {
243      ep->type = NELT_FMASK;
244      ep->v.matching_flags = matching_flags;
245      prev_flags = matching_flags;
246      check_name_alloc ();
247      ep = &name_array[names++];
248    }
249  ep->type = NELT_NAME;
250  ep->v.name = name;
251}
252
253/* Add to name_array a chdir request for the directory NAME */
254void
255name_add_dir (const char *name)
256{
257  struct name_elt *ep;
258  check_name_alloc ();
259  ep = &name_array[names++];
260  ep->type = NELT_CHDIR;
261  ep->v.name = name;
262}
263
264
265/* Names from external name file.  */
266
267static char *name_buffer;	/* buffer to hold the current file name */
268static size_t name_buffer_length; /* allocated length of name_buffer */
269
270/* Set up to gather file names for tar.  They can either come from a
271   file or were saved from decoding arguments.  */
272void
273name_init (void)
274{
275  name_buffer = xmalloc (NAME_FIELD_SIZE + 2);
276  name_buffer_length = NAME_FIELD_SIZE;
277}
278
279void
280name_term (void)
281{
282  free (name_buffer);
283  free (name_array);
284}
285
286static int matching_flags; /* exclude_fnmatch options */
287
288/* Get the next NELT_NAME element from name_array.  Result is in
289   static storage and can't be relied upon across two calls.
290
291   If CHANGE_DIRS is true, treat any entries of type NELT_CHDIR as
292   the request to change to the given directory.  If filename_terminator
293   is NUL, CHANGE_DIRS is effectively always false.
294
295   Entries of type NELT_FMASK cause updates of the matching_flags
296   value. */
297struct name_elt *
298name_next_elt (int change_dirs)
299{
300  static struct name_elt entry;
301  const char *source;
302  char *cursor;
303
304  if (filename_terminator == '\0')
305    change_dirs = 0;
306
307  while (name_index != names)
308    {
309      struct name_elt *ep;
310      size_t source_len;
311
312      ep = &name_array[name_index++];
313      if (ep->type == NELT_FMASK)
314	{
315	  matching_flags = ep->v.matching_flags;
316	  continue;
317	}
318
319      source = ep->v.name;
320      source_len = strlen (source);
321      if (name_buffer_length < source_len)
322	{
323	  do
324	    {
325	      name_buffer_length *= 2;
326	      if (! name_buffer_length)
327		xalloc_die ();
328	    }
329	  while (name_buffer_length < source_len);
330
331	  free (name_buffer);
332	  name_buffer = xmalloc (name_buffer_length + 2);
333	}
334      strcpy (name_buffer, source);
335
336      /* Zap trailing slashes.  */
337
338      cursor = name_buffer + strlen (name_buffer) - 1;
339      while (cursor > name_buffer && ISSLASH (*cursor))
340	*cursor-- = '\0';
341
342      if (change_dirs && ep->type == NELT_CHDIR)
343	{
344	  if (chdir (name_buffer) < 0)
345	    chdir_fatal (name_buffer);
346	}
347      else
348	{
349	  if (unquote_option)
350	    unquote_string (name_buffer);
351	  if (incremental_option)
352	    register_individual_file (name_buffer);
353	  entry.type = ep->type;
354	  entry.v.name = name_buffer;
355	  return &entry;
356	}
357    }
358
359  return NULL;
360}
361
362const char *
363name_next (int change_dirs)
364{
365  struct name_elt *nelt = name_next_elt (change_dirs);
366  return nelt ? nelt->v.name : NULL;
367}
368
369/* Gather names in a list for scanning.  Could hash them later if we
370   really care.
371
372   If the names are already sorted to match the archive, we just read
373   them one by one.  name_gather reads the first one, and it is called
374   by name_match as appropriate to read the next ones.  At EOF, the
375   last name read is just left in the buffer.  This option lets users
376   of small machines extract an arbitrary number of files by doing
377   "tar t" and editing down the list of files.  */
378
379void
380name_gather (void)
381{
382  /* Buffer able to hold a single name.  */
383  static struct name *buffer;
384  static size_t allocated_size;
385
386  struct name_elt *ep;
387
388  if (same_order_option)
389    {
390      static int change_dir;
391
392      if (allocated_size == 0)
393	{
394	  allocated_size = offsetof (struct name, name) + NAME_FIELD_SIZE + 1;
395	  buffer = xmalloc (allocated_size);
396	  /* FIXME: This memset is overkill, and ugly...  */
397	  memset (buffer, 0, allocated_size);
398	}
399
400      while ((ep = name_next_elt (0)) && ep->type == NELT_CHDIR)
401	change_dir = chdir_arg (xstrdup (ep->v.name));
402
403      if (ep)
404	{
405	  size_t needed_size;
406
407	  buffer->length = strlen (ep->v.name);
408	  needed_size = offsetof (struct name, name) + buffer->length + 1;
409	  if (allocated_size < needed_size)
410	    {
411	      do
412		{
413		  allocated_size *= 2;
414		  if (! allocated_size)
415		    xalloc_die ();
416		}
417	      while (allocated_size < needed_size);
418
419	      buffer = xrealloc (buffer, allocated_size);
420	    }
421	  buffer->change_dir = change_dir;
422	  strcpy (buffer->name, ep->v.name);
423	  buffer->next = 0;
424	  buffer->found_count = 0;
425	  buffer->matching_flags = matching_flags;
426
427	  namelist = buffer;
428	  nametail = &namelist->next;
429	}
430      else if (change_dir)
431	addname (0, change_dir);
432    }
433  else
434    {
435      /* Non sorted names -- read them all in.  */
436      int change_dir = 0;
437
438      for (;;)
439	{
440	  int change_dir0 = change_dir;
441	  while ((ep = name_next_elt (0)) && ep->type == NELT_CHDIR)
442	    change_dir = chdir_arg (xstrdup (ep->v.name));
443
444	  if (ep)
445	    addname (ep->v.name, change_dir);
446	  else
447	    {
448	      if (change_dir != change_dir0)
449		addname (0, change_dir);
450	      break;
451	    }
452	}
453    }
454}
455
456/*  Add a name to the namelist.  */
457struct name *
458addname (char const *string, int change_dir)
459{
460  size_t length = string ? strlen (string) : 0;
461  struct name *name = xmalloc (offsetof (struct name, name) + length + 1);
462
463  if (string)
464    strcpy (name->name, string);
465  else
466    name->name[0] = 0;
467
468  name->next = NULL;
469  name->length = length;
470  name->found_count = 0;
471  name->matching_flags = matching_flags;
472  name->change_dir = change_dir;
473  name->dir_contents = NULL;
474
475  *nametail = name;
476  nametail = &name->next;
477  return name;
478}
479
480/* Find a match for FILE_NAME (whose string length is LENGTH) in the name
481   list.  */
482static struct name *
483namelist_match (char const *file_name, size_t length)
484{
485  struct name *p;
486
487  for (p = namelist; p; p = p->next)
488    {
489      if (p->name[0]
490	  && exclude_fnmatch (p->name, file_name, p->matching_flags))
491	return p;
492    }
493
494  return NULL;
495}
496
497/* Return true if and only if name FILE_NAME (from an archive) matches any
498   name from the namelist.  */
499bool
500name_match (const char *file_name)
501{
502  size_t length = strlen (file_name);
503
504  while (1)
505    {
506      struct name *cursor = namelist;
507
508      if (!cursor)
509	return true;
510
511      if (cursor->name[0] == 0)
512	{
513	  chdir_do (cursor->change_dir);
514	  namelist = 0;
515	  nametail = &namelist;
516	  return true;
517	}
518
519      cursor = namelist_match (file_name, length);
520      if (cursor)
521	{
522	  if (!(ISSLASH (file_name[cursor->length]) && recursion_option)
523	      || cursor->found_count == 0)
524	    cursor->found_count++; /* remember it matched */
525	  if (starting_file_option)
526	    {
527	      free (namelist);
528	      namelist = 0;
529	      nametail = &namelist;
530	    }
531	  chdir_do (cursor->change_dir);
532
533	  /* We got a match.  */
534	  return ISFOUND (cursor);
535	}
536
537      /* Filename from archive not found in namelist.  If we have the whole
538	 namelist here, just return 0.  Otherwise, read the next name in and
539	 compare it.  If this was the last name, namelist->found_count will
540	 remain on.  If not, we loop to compare the newly read name.  */
541
542      if (same_order_option && namelist->found_count)
543	{
544	  name_gather ();	/* read one more */
545	  if (namelist->found_count)
546	    return false;
547	}
548      else
549	return false;
550    }
551}
552
553/* Returns true if all names from the namelist were processed.
554   P is the stat_info of the most recently processed entry.
555   The decision is postponed until the next entry is read if:
556
557   1) P ended with a slash (i.e. it was a directory)
558   2) P matches any entry from the namelist *and* represents a subdirectory
559   or a file lying under this entry (in the terms of directory structure).
560
561   This is necessary to handle contents of directories. */
562bool
563all_names_found (struct tar_stat_info *p)
564{
565  struct name const *cursor;
566  size_t len;
567
568  if (test_label_option)
569    return true;
570  if (!p->file_name || occurrence_option == 0 || p->had_trailing_slash)
571    return false;
572  len = strlen (p->file_name);
573  for (cursor = namelist; cursor; cursor = cursor->next)
574    {
575      if ((cursor->name[0] && !WASFOUND (cursor))
576	  || (len >= cursor->length && ISSLASH (p->file_name[cursor->length])))
577	return false;
578    }
579  return true;
580}
581
582static inline int
583is_pattern (const char *string)
584{
585  return strchr (string, '*') || strchr (string, '[') || strchr (string, '?');
586}
587
588static void
589regex_usage_warning (const char *name)
590{
591  static int warned_once = 0;
592
593  if (warn_regex_usage && is_pattern (name))
594    {
595      warned_once = 1;
596      WARN ((0, 0,
597	     /* TRANSLATORS: The following three msgids form a single sentence.
598	      */
599	     _("Pattern matching characters used in file names. Please,")));
600      WARN ((0, 0,
601	     _("use --wildcards to enable pattern matching, or --no-wildcards to")));
602      WARN ((0, 0,
603	     _("suppress this warning.")));
604    }
605}
606
607/* Print the names of things in the namelist that were not matched.  */
608void
609names_notfound (void)
610{
611  struct name const *cursor;
612
613  for (cursor = namelist; cursor; cursor = cursor->next)
614    if (!WASFOUND (cursor) && cursor->name[0])
615      {
616	regex_usage_warning (cursor->name);
617	if (cursor->found_count == 0)
618	  ERROR ((0, 0, _("%s: Not found in archive"),
619		  quotearg_colon (cursor->name)));
620	else
621	  ERROR ((0, 0, _("%s: Required occurrence not found in archive"),
622		  quotearg_colon (cursor->name)));
623      }
624
625  /* Don't bother freeing the name list; we're about to exit.  */
626  namelist = 0;
627  nametail = &namelist;
628
629  if (same_order_option)
630    {
631      const char *name;
632
633      while ((name = name_next (1)) != NULL)
634	{
635	  regex_usage_warning (name);
636	  ERROR ((0, 0, _("%s: Not found in archive"),
637		  quotearg_colon (name)));
638	}
639    }
640}
641
642/* Sorting name lists.  */
643
644/* Sort linked LIST of names, of given LENGTH, using COMPARE to order
645   names.  Return the sorted list.  Apart from the type `struct name'
646   and the definition of SUCCESSOR, this is a generic list-sorting
647   function, but it's too painful to make it both generic and portable
648   in C.  */
649
650static struct name *
651merge_sort (struct name *list, int length,
652	    int (*compare) (struct name const*, struct name const*))
653{
654  struct name *first_list;
655  struct name *second_list;
656  int first_length;
657  int second_length;
658  struct name *result;
659  struct name **merge_point;
660  struct name *cursor;
661  int counter;
662
663# define SUCCESSOR(name) ((name)->next)
664
665  if (length == 1)
666    return list;
667
668  if (length == 2)
669    {
670      if ((*compare) (list, SUCCESSOR (list)) > 0)
671	{
672	  result = SUCCESSOR (list);
673	  SUCCESSOR (result) = list;
674	  SUCCESSOR (list) = 0;
675	  return result;
676	}
677      return list;
678    }
679
680  first_list = list;
681  first_length = (length + 1) / 2;
682  second_length = length / 2;
683  for (cursor = list, counter = first_length - 1;
684       counter;
685       cursor = SUCCESSOR (cursor), counter--)
686    continue;
687  second_list = SUCCESSOR (cursor);
688  SUCCESSOR (cursor) = 0;
689
690  first_list = merge_sort (first_list, first_length, compare);
691  second_list = merge_sort (second_list, second_length, compare);
692
693  merge_point = &result;
694  while (first_list && second_list)
695    if ((*compare) (first_list, second_list) < 0)
696      {
697	cursor = SUCCESSOR (first_list);
698	*merge_point = first_list;
699	merge_point = &SUCCESSOR (first_list);
700	first_list = cursor;
701      }
702    else
703      {
704	cursor = SUCCESSOR (second_list);
705	*merge_point = second_list;
706	merge_point = &SUCCESSOR (second_list);
707	second_list = cursor;
708      }
709  if (first_list)
710    *merge_point = first_list;
711  else
712    *merge_point = second_list;
713
714  return result;
715
716#undef SUCCESSOR
717}
718
719/* A comparison function for sorting names.  Put found names last;
720   break ties by string comparison.  */
721
722static int
723compare_names (struct name const *n1, struct name const *n2)
724{
725  int found_diff = WASFOUND(n2) - WASFOUND(n1);
726  return found_diff ? found_diff : strcmp (n1->name, n2->name);
727}
728
729/* Add all the dirs under NAME, which names a directory, to the namelist.
730   If any of the files is a directory, recurse on the subdirectory.
731   DEVICE is the device not to leave, if the -l option is specified.  */
732
733static void
734add_hierarchy_to_namelist (struct name *name, dev_t device)
735{
736  char *file_name = name->name;
737  char *buffer = get_directory_contents (file_name, device);
738
739  if (! buffer)
740    name->dir_contents = "\0\0\0\0";
741  else
742    {
743      size_t name_length = name->length;
744      size_t allocated_length = (name_length >= NAME_FIELD_SIZE
745				 ? name_length + NAME_FIELD_SIZE
746				 : NAME_FIELD_SIZE);
747      char *namebuf = xmalloc (allocated_length + 1);
748				/* FIXME: + 2 above?  */
749      char *string;
750      size_t string_length;
751      int change_dir = name->change_dir;
752
753      name->dir_contents = buffer;
754      strcpy (namebuf, file_name);
755      if (! ISSLASH (namebuf[name_length - 1]))
756	{
757	  namebuf[name_length++] = '/';
758	  namebuf[name_length] = '\0';
759	}
760
761      for (string = buffer; *string; string += string_length + 1)
762	{
763	  string_length = strlen (string);
764	  if (*string == 'D')
765	    {
766	      struct name *np;
767
768	      if (allocated_length <= name_length + string_length)
769		{
770		  do
771		    {
772		      allocated_length *= 2;
773		      if (! allocated_length)
774			xalloc_die ();
775		    }
776		  while (allocated_length <= name_length + string_length);
777
778		  namebuf = xrealloc (namebuf, allocated_length + 1);
779		}
780	      strcpy (namebuf + name_length, string + 1);
781	      np = addname (namebuf, change_dir);
782	      add_hierarchy_to_namelist (np, device);
783	    }
784	}
785
786      free (namebuf);
787    }
788}
789
790/* Collect all the names from argv[] (or whatever), expand them into a
791   directory tree, and sort them.  This gets only subdirectories, not
792   all files.  */
793
794void
795collect_and_sort_names (void)
796{
797  struct name *name;
798  struct name *next_name;
799  int num_names;
800  struct stat statbuf;
801
802  name_gather ();
803
804  if (listed_incremental_option)
805    read_directory_file ();
806
807  if (!namelist)
808    addname (".", 0);
809
810  for (name = namelist; name; name = next_name)
811    {
812      next_name = name->next;
813      if (name->found_count || name->dir_contents)
814	continue;
815      if (name->matching_flags & EXCLUDE_WILDCARDS)
816	/* NOTE: EXCLUDE_ANCHORED is not relevant here */
817	/* FIXME: just skip regexps for now */
818	continue;
819      chdir_do (name->change_dir);
820      if (name->name[0] == 0)
821	continue;
822
823      if (deref_stat (dereference_option, name->name, &statbuf) != 0)
824	{
825	  stat_diag (name->name);
826	  continue;
827	}
828      if (S_ISDIR (statbuf.st_mode))
829	{
830	  name->found_count++;
831	  add_hierarchy_to_namelist (name, statbuf.st_dev);
832	}
833    }
834
835  num_names = 0;
836  for (name = namelist; name; name = name->next)
837    num_names++;
838  namelist = merge_sort (namelist, num_names, compare_names);
839
840  for (name = namelist; name; name = name->next)
841    name->found_count = 0;
842
843  if (listed_incremental_option)
844    {
845      for (name = namelist; name && name->name[0] == 0; name++)
846	;
847      if (name)
848	name->dir_contents = append_incremental_renames (name->dir_contents);
849    }
850}
851
852/* This is like name_match, except that
853    1. It returns a pointer to the name it matched, and doesn't set FOUND
854    in structure. The caller will have to do that if it wants to.
855    2. If the namelist is empty, it returns null, unlike name_match, which
856    returns TRUE. */
857struct name *
858name_scan (const char *file_name)
859{
860  size_t length = strlen (file_name);
861
862  while (1)
863    {
864      struct name *cursor = namelist_match (file_name, length);
865      if (cursor)
866	return cursor;
867
868      /* Filename from archive not found in namelist.  If we have the whole
869	 namelist here, just return 0.  Otherwise, read the next name in and
870	 compare it.  If this was the last name, namelist->found_count will
871	 remain on.  If not, we loop to compare the newly read name.  */
872
873      if (same_order_option && namelist && namelist->found_count)
874	{
875	  name_gather ();	/* read one more */
876	  if (namelist->found_count)
877	    return 0;
878	}
879      else
880	return 0;
881    }
882}
883
884/* This returns a name from the namelist which doesn't have ->found
885   set.  It sets ->found before returning, so successive calls will
886   find and return all the non-found names in the namelist.  */
887struct name *gnu_list_name;
888
889char *
890name_from_list (void)
891{
892  if (!gnu_list_name)
893    gnu_list_name = namelist;
894  while (gnu_list_name
895	 && (gnu_list_name->found_count || gnu_list_name->name[0] == 0))
896    gnu_list_name = gnu_list_name->next;
897  if (gnu_list_name)
898    {
899      gnu_list_name->found_count++;
900      chdir_do (gnu_list_name->change_dir);
901      return gnu_list_name->name;
902    }
903  return 0;
904}
905
906void
907blank_name_list (void)
908{
909  struct name *name;
910
911  gnu_list_name = 0;
912  for (name = namelist; name; name = name->next)
913    name->found_count = 0;
914}
915
916/* Yield a newly allocated file name consisting of FILE_NAME concatenated to
917   NAME, with an intervening slash if FILE_NAME does not already end in one. */
918char *
919new_name (const char *file_name, const char *name)
920{
921  size_t file_name_len = strlen (file_name);
922  size_t namesize = strlen (name) + 1;
923  int slash = file_name_len && ! ISSLASH (file_name[file_name_len - 1]);
924  char *buffer = xmalloc (file_name_len + slash + namesize);
925  memcpy (buffer, file_name, file_name_len);
926  buffer[file_name_len] = '/';
927  memcpy (buffer + file_name_len + slash, name, namesize);
928  return buffer;
929}
930
931/* Return nonzero if file NAME is excluded.  */
932bool
933excluded_name (char const *name)
934{
935  return excluded_file_name (excluded, name + FILE_SYSTEM_PREFIX_LEN (name));
936}
937
938/* Names to avoid dumping.  */
939static Hash_table *avoided_name_table;
940
941/* Remember to not archive NAME.  */
942void
943add_avoided_name (char const *name)
944{
945  hash_string_insert (&avoided_name_table, name);
946}
947
948/* Should NAME be avoided when archiving?  */
949bool
950is_avoided_name (char const *name)
951{
952  return hash_string_lookup (avoided_name_table, name);
953}
954
955
956static Hash_table *individual_file_table;
957
958static void
959register_individual_file (char const *name)
960{
961  struct stat st;
962
963  if (deref_stat (dereference_option, name, &st) != 0)
964    return; /* Will be complained about later */
965  if (S_ISDIR (st.st_mode))
966    return;
967
968  hash_string_insert (&individual_file_table, name);
969}
970
971bool
972is_individual_file (char const *name)
973{
974  return hash_string_lookup (individual_file_table, name);
975}
976
977
978
979/* Return the size of the prefix of FILE_NAME that is removed after
980   stripping NUM leading file name components.  NUM must be
981   positive.  */
982
983size_t
984stripped_prefix_len (char const *file_name, size_t num)
985{
986  char const *p = file_name + FILE_SYSTEM_PREFIX_LEN (file_name);
987  while (ISSLASH (*p))
988    p++;
989  while (*p)
990    {
991      bool slash = ISSLASH (*p);
992      p++;
993      if (slash)
994	{
995	  if (--num == 0)
996	    return p - file_name;
997	  while (ISSLASH (*p))
998	    p++;
999	}
1000    }
1001  return -1;
1002}
1003
1004/* Return nonzero if NAME contains ".." as a file name component.  */
1005bool
1006contains_dot_dot (char const *name)
1007{
1008  char const *p = name + FILE_SYSTEM_PREFIX_LEN (name);
1009
1010  for (;; p++)
1011    {
1012      if (p[0] == '.' && p[1] == '.' && (ISSLASH (p[2]) || !p[2]))
1013	return 1;
1014
1015      while (! ISSLASH (*p))
1016	{
1017	  if (! *p++)
1018	    return 0;
1019	}
1020    }
1021}
1022