1 /* Various processing of names.
3 Copyright 1988, 1992, 1994, 1996, 1997, 1998, 1999, 2000, 2001 Free
4 Software Foundation, Inc.
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
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.
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 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
30 /* User and group names. */
32 struct group
*getgrnam ();
33 struct passwd
*getpwnam ();
34 #if ! HAVE_DECL_GETPWUID
35 struct passwd
*getpwuid ();
37 #if ! HAVE_DECL_GETGRGID
38 struct group
*getgrgid ();
41 /* Make sure you link with the proper libraries if you are running the
42 Yellow Peril (thanks for the good laugh, Ian J.!), or, euh... NIS.
43 This code should also be modified for non-UNIX systems to do something
46 static char cached_uname
[UNAME_FIELD_SIZE
];
47 static char cached_gname
[GNAME_FIELD_SIZE
];
49 static uid_t cached_uid
; /* valid only if cached_uname is not empty */
50 static gid_t cached_gid
; /* valid only if cached_gname is not empty */
52 /* These variables are valid only if nonempty. */
53 static char cached_no_such_uname
[UNAME_FIELD_SIZE
];
54 static char cached_no_such_gname
[GNAME_FIELD_SIZE
];
56 /* These variables are valid only if nonzero. It's not worth optimizing
57 the case for weird systems where 0 is not a valid uid or gid. */
58 static uid_t cached_no_such_uid
;
59 static gid_t cached_no_such_gid
;
61 /* Given UID, find the corresponding UNAME. */
63 uid_to_uname (uid_t uid
, char uname
[UNAME_FIELD_SIZE
])
65 struct passwd
*passwd
;
67 if (uid
!= 0 && uid
== cached_no_such_uid
)
73 if (!cached_uname
[0] || uid
!= cached_uid
)
75 passwd
= getpwuid (uid
);
79 strncpy (cached_uname
, passwd
->pw_name
, UNAME_FIELD_SIZE
);
83 cached_no_such_uid
= uid
;
88 strncpy (uname
, cached_uname
, UNAME_FIELD_SIZE
);
91 /* Given GID, find the corresponding GNAME. */
93 gid_to_gname (gid_t gid
, char gname
[GNAME_FIELD_SIZE
])
97 if (gid
!= 0 && gid
== cached_no_such_gid
)
103 if (!cached_gname
[0] || gid
!= cached_gid
)
105 group
= getgrgid (gid
);
109 strncpy (cached_gname
, group
->gr_name
, GNAME_FIELD_SIZE
);
113 cached_no_such_gid
= gid
;
118 strncpy (gname
, cached_gname
, GNAME_FIELD_SIZE
);
121 /* Given UNAME, set the corresponding UID and return 1, or else, return 0. */
123 uname_to_uid (char uname
[UNAME_FIELD_SIZE
], uid_t
*uidp
)
125 struct passwd
*passwd
;
127 if (cached_no_such_uname
[0]
128 && strncmp (uname
, cached_no_such_uname
, UNAME_FIELD_SIZE
) == 0)
132 || uname
[0] != cached_uname
[0]
133 || strncmp (uname
, cached_uname
, UNAME_FIELD_SIZE
) != 0)
135 passwd
= getpwnam (uname
);
138 cached_uid
= passwd
->pw_uid
;
139 strncpy (cached_uname
, uname
, UNAME_FIELD_SIZE
);
143 strncpy (cached_no_such_uname
, uname
, UNAME_FIELD_SIZE
);
151 /* Given GNAME, set the corresponding GID and return 1, or else, return 0. */
153 gname_to_gid (char gname
[GNAME_FIELD_SIZE
], gid_t
*gidp
)
157 if (cached_no_such_gname
[0]
158 && strncmp (gname
, cached_no_such_gname
, GNAME_FIELD_SIZE
) == 0)
162 || gname
[0] != cached_gname
[0]
163 || strncmp (gname
, cached_gname
, GNAME_FIELD_SIZE
) != 0)
165 group
= getgrnam (gname
);
168 cached_gid
= group
->gr_gid
;
169 strncpy (cached_gname
, gname
, GNAME_FIELD_SIZE
);
173 strncpy (cached_no_such_gname
, gname
, GNAME_FIELD_SIZE
);
181 /* Names from the command call. */
183 static struct name
*namelist
; /* first name in list, if any */
184 static struct name
**nametail
= &namelist
; /* end of name list */
185 static const char **name_array
; /* store an array of names */
186 static int allocated_names
; /* how big is the array? */
187 static int names
; /* how many entries does it have? */
188 static int name_index
; /* how many of the entries have we scanned? */
190 /* Initialize structures. */
194 allocated_names
= 10;
195 name_array
= xmalloc (sizeof (const char *) * allocated_names
);
199 /* Add NAME at end of name_array, reallocating it as necessary. */
201 name_add (const char *name
)
203 if (names
== allocated_names
)
205 allocated_names
*= 2;
207 xrealloc (name_array
, sizeof (const char *) * allocated_names
);
209 name_array
[names
++] = name
;
212 /* Names from external name file. */
214 static FILE *name_file
; /* file to read names from */
215 static char *name_buffer
; /* buffer to hold the current file name */
216 static size_t name_buffer_length
; /* allocated length of name_buffer */
218 /* FIXME: I should better check more closely. It seems at first glance that
219 is_pattern is only used when reading a file, and ignored for all
220 command line arguments. */
223 is_pattern (const char *string
)
225 return strchr (string
, '*') || strchr (string
, '[') || strchr (string
, '?');
228 /* Set up to gather file names for tar. They can either come from a
229 file or were saved from decoding arguments. */
231 name_init (int argc
, char *const *argv
)
233 name_buffer
= xmalloc (NAME_FIELD_SIZE
+ 2);
234 name_buffer_length
= NAME_FIELD_SIZE
;
236 if (files_from_option
)
238 if (!strcmp (files_from_option
, "-"))
240 request_stdin ("-T");
243 else if (name_file
= fopen (files_from_option
, "r"), !name_file
)
244 open_fatal (files_from_option
);
255 /* Read the next filename from name_file and null-terminate it. Put
256 it into name_buffer, reallocating and adjusting name_buffer_length
257 if necessary. Return 0 at end of file, 1 otherwise. */
259 read_name_from_file (void)
264 /* FIXME: getc may be called even if character was EOF the last time here. */
266 /* FIXME: This + 2 allocation might serve no purpose. */
268 while (character
= getc (name_file
),
269 character
!= EOF
&& character
!= filename_terminator
)
271 if (counter
== name_buffer_length
)
273 if (name_buffer_length
* 2 < name_buffer_length
)
275 name_buffer_length
*= 2;
276 name_buffer
= xrealloc (name_buffer
, name_buffer_length
+ 2);
278 name_buffer
[counter
++] = character
;
281 if (counter
== 0 && character
== EOF
)
284 if (counter
== name_buffer_length
)
286 if (name_buffer_length
* 2 < name_buffer_length
)
288 name_buffer_length
*= 2;
289 name_buffer
= xrealloc (name_buffer
, name_buffer_length
+ 2);
291 name_buffer
[counter
] = '\0';
296 /* Get the next name from ARGV or the file of names. Result is in
297 static storage and can't be relied upon across two calls.
299 If CHANGE_DIRS is true, treat a filename of the form "-C" as
300 meaning that the next filename is the name of a directory to change
301 to. If filename_terminator is NUL, CHANGE_DIRS is effectively
304 name_next (int change_dirs
)
310 if (filename_terminator
== '\0')
315 /* Get a name, either from file or from saved arguments. */
317 if (name_index
== names
)
321 if (! read_name_from_file ())
327 source
= name_array
[name_index
++];
328 source_len
= strlen (source
);
329 if (name_buffer_length
< source_len
)
333 name_buffer_length
*= 2;
334 if (! name_buffer_length
)
337 while (name_buffer_length
< source_len
);
340 name_buffer
= xmalloc (name_buffer_length
+ 2);
342 strcpy (name_buffer
, source
);
345 /* Zap trailing slashes. */
347 cursor
= name_buffer
+ strlen (name_buffer
) - 1;
348 while (cursor
> name_buffer
&& ISSLASH (*cursor
))
353 if (chdir (name_buffer
) < 0)
354 chdir_fatal (name_buffer
);
357 else if (change_dirs
&& strcmp (name_buffer
, "-C") == 0)
361 unquote_string (name_buffer
);
366 /* No more names in file. */
368 if (name_file
&& chdir_flag
)
369 FATAL_ERROR ((0, 0, _("Missing file name after -C")));
374 /* Close the name file, if any. */
378 if (name_file
&& name_file
!= stdin
)
379 if (fclose (name_file
) != 0)
380 close_error (name_buffer
);
383 /* Gather names in a list for scanning. Could hash them later if we
386 If the names are already sorted to match the archive, we just read
387 them one by one. name_gather reads the first one, and it is called
388 by name_match as appropriate to read the next ones. At EOF, the
389 last name read is just left in the buffer. This option lets users
390 of small machines extract an arbitrary number of files by doing
391 "tar t" and editing down the list of files. */
396 /* Buffer able to hold a single name. */
397 static struct name
*buffer
;
398 static size_t allocated_size
;
402 if (same_order_option
)
404 static int change_dir
;
406 if (allocated_size
== 0)
408 allocated_size
= offsetof (struct name
, name
) + NAME_FIELD_SIZE
+ 1;
409 buffer
= xmalloc (allocated_size
);
410 /* FIXME: This memset is overkill, and ugly... */
411 memset (buffer
, 0, allocated_size
);
414 while ((name
= name_next (0)) && strcmp (name
, "-C") == 0)
416 char const *dir
= name_next (0);
418 FATAL_ERROR ((0, 0, _("Missing file name after -C")));
419 change_dir
= chdir_arg (xstrdup (dir
));
425 buffer
->length
= strlen (name
);
426 needed_size
= offsetof (struct name
, name
) + buffer
->length
+ 1;
427 if (allocated_size
< needed_size
)
432 if (! allocated_size
)
435 while (allocated_size
< needed_size
);
437 buffer
= xrealloc (buffer
, allocated_size
);
439 buffer
->change_dir
= change_dir
;
440 strcpy (buffer
->name
, name
);
445 nametail
= &namelist
->next
;
450 /* Non sorted names -- read them all in. */
455 int change_dir0
= change_dir
;
456 while ((name
= name_next (0)) && strcmp (name
, "-C") == 0)
458 char const *dir
= name_next (0);
460 FATAL_ERROR ((0, 0, _("Missing file name after -C")));
461 change_dir
= chdir_arg (xstrdup (dir
));
464 addname (name
, change_dir
);
467 if (change_dir
!= change_dir0
)
468 addname (0, change_dir
);
475 /* Add a name to the namelist. */
477 addname (char const *string
, int change_dir
)
479 size_t length
= string
? strlen (string
) : 0;
480 struct name
*name
= xmalloc (offsetof (struct name
, name
) + length
+ 1);
485 strcpy (name
->name
, string
);
491 /* FIXME: This initialization (and the byte of memory that it
492 initializes) is probably not needed, but we are currently in
493 bug-fix mode so we'll leave it in for now. */
498 name
->length
= length
;
500 name
->regexp
= 0; /* assume not a regular expression */
501 name
->firstch
= 1; /* assume first char is literal */
502 name
->change_dir
= change_dir
;
503 name
->dir_contents
= 0;
505 if (string
&& is_pattern (string
))
508 if (string
[0] == '*' || string
[0] == '[' || string
[0] == '?')
513 nametail
= &name
->next
;
517 /* Find a match for PATH (whose string length is LENGTH) in the name
520 namelist_match (char const *path
, size_t length
)
524 for (p
= namelist
; p
; p
= p
->next
)
526 /* If first chars don't match, quick skip. */
528 if (p
->firstch
&& p
->name
[0] != path
[0])
532 ? fnmatch (p
->name
, path
, recursion_option
) == 0
533 : (p
->length
<= length
534 && (path
[p
->length
] == '\0' || ISSLASH (path
[p
->length
]))
535 && memcmp (path
, p
->name
, p
->length
) == 0))
542 /* Return true if and only if name PATH (from an archive) matches any
543 name from the namelist. */
545 name_match (const char *path
)
547 size_t length
= strlen (path
);
551 struct name
*cursor
= namelist
;
554 return ! files_from_option
;
558 chdir_do (cursor
->change_dir
);
560 nametail
= &namelist
;
561 return ! files_from_option
;
564 cursor
= namelist_match (path
, length
);
567 cursor
->found
= 1; /* remember it matched */
568 if (starting_file_option
)
572 nametail
= &namelist
;
574 chdir_do (cursor
->change_dir
);
576 /* We got a match. */
580 /* Filename from archive not found in namelist. If we have the whole
581 namelist here, just return 0. Otherwise, read the next name in and
582 compare it. If this was the last name, namelist->found will remain
583 on. If not, we loop to compare the newly read name. */
585 if (same_order_option
&& namelist
->found
)
587 name_gather (); /* read one more */
596 /* Print the names of things in the namelist that were not matched. */
598 names_notfound (void)
600 struct name
const *cursor
;
602 for (cursor
= namelist
; cursor
; cursor
= cursor
->next
)
603 if (!cursor
->found
&& !cursor
->fake
)
604 ERROR ((0, 0, _("%s: Not found in archive"),
605 quotearg_colon (cursor
->name
)));
607 /* Don't bother freeing the name list; we're about to exit. */
609 nametail
= &namelist
;
611 if (same_order_option
)
615 while (name
= name_next (1), name
)
616 ERROR ((0, 0, _("%s: Not found in archive"),
617 quotearg_colon (name
)));
621 /* Sorting name lists. */
623 /* Sort linked LIST of names, of given LENGTH, using COMPARE to order
624 names. Return the sorted list. Apart from the type `struct name'
625 and the definition of SUCCESSOR, this is a generic list-sorting
626 function, but it's too painful to make it both generic and portable
630 merge_sort (struct name
*list
, int length
,
631 int (*compare
) (struct name
const*, struct name
const*))
633 struct name
*first_list
;
634 struct name
*second_list
;
638 struct name
**merge_point
;
642 # define SUCCESSOR(name) ((name)->next)
649 if ((*compare
) (list
, SUCCESSOR (list
)) > 0)
651 result
= SUCCESSOR (list
);
652 SUCCESSOR (result
) = list
;
653 SUCCESSOR (list
) = 0;
660 first_length
= (length
+ 1) / 2;
661 second_length
= length
/ 2;
662 for (cursor
= list
, counter
= first_length
- 1;
664 cursor
= SUCCESSOR (cursor
), counter
--)
666 second_list
= SUCCESSOR (cursor
);
667 SUCCESSOR (cursor
) = 0;
669 first_list
= merge_sort (first_list
, first_length
, compare
);
670 second_list
= merge_sort (second_list
, second_length
, compare
);
672 merge_point
= &result
;
673 while (first_list
&& second_list
)
674 if ((*compare
) (first_list
, second_list
) < 0)
676 cursor
= SUCCESSOR (first_list
);
677 *merge_point
= first_list
;
678 merge_point
= &SUCCESSOR (first_list
);
683 cursor
= SUCCESSOR (second_list
);
684 *merge_point
= second_list
;
685 merge_point
= &SUCCESSOR (second_list
);
686 second_list
= cursor
;
689 *merge_point
= first_list
;
691 *merge_point
= second_list
;
698 /* A comparison function for sorting names. Put found names last;
699 break ties by string comparison. */
702 compare_names (struct name
const *n1
, struct name
const *n2
)
704 int found_diff
= n2
->found
- n1
->found
;
705 return found_diff
? found_diff
: strcmp (n1
->name
, n2
->name
);
708 /* Add all the dirs under NAME, which names a directory, to the namelist.
709 If any of the files is a directory, recurse on the subdirectory.
710 DEVICE is the device not to leave, if the -l option is specified. */
713 add_hierarchy_to_namelist (struct name
*name
, dev_t device
)
715 char *path
= name
->name
;
716 char *buffer
= get_directory_contents (path
, device
);
719 name
->dir_contents
= "\0\0\0\0";
722 size_t name_length
= name
->length
;
723 size_t allocated_length
= (name_length
>= NAME_FIELD_SIZE
724 ? name_length
+ NAME_FIELD_SIZE
726 char *name_buffer
= xmalloc (allocated_length
+ 1);
727 /* FIXME: + 2 above? */
729 size_t string_length
;
730 int change_dir
= name
->change_dir
;
732 name
->dir_contents
= buffer
;
733 strcpy (name_buffer
, path
);
734 if (! ISSLASH (name_buffer
[name_length
- 1]))
736 name_buffer
[name_length
++] = '/';
737 name_buffer
[name_length
] = '\0';
740 for (string
= buffer
; *string
; string
+= string_length
+ 1)
742 string_length
= strlen (string
);
745 if (allocated_length
<= name_length
+ string_length
)
749 allocated_length
*= 2;
750 if (! allocated_length
)
753 while (allocated_length
<= name_length
+ string_length
);
755 name_buffer
= xrealloc (name_buffer
, allocated_length
+ 1);
757 strcpy (name_buffer
+ name_length
, string
+ 1);
758 add_hierarchy_to_namelist (addname (name_buffer
, change_dir
),
767 /* Collect all the names from argv[] (or whatever), expand them into a
768 directory tree, and sort them. This gets only subdirectories, not
772 collect_and_sort_names (void)
775 struct name
*next_name
;
781 if (listed_incremental_option
)
782 read_directory_file ();
787 for (name
= namelist
; name
; name
= next_name
)
789 next_name
= name
->next
;
790 if (name
->found
|| name
->dir_contents
)
792 if (name
->regexp
) /* FIXME: just skip regexps for now */
794 chdir_do (name
->change_dir
);
798 if (deref_stat (dereference_option
, name
->name
, &statbuf
) != 0)
800 if (ignore_failed_read_option
)
801 stat_warn (name
->name
);
803 stat_error (name
->name
);
806 if (S_ISDIR (statbuf
.st_mode
))
809 add_hierarchy_to_namelist (name
, statbuf
.st_dev
);
814 for (name
= namelist
; name
; name
= name
->next
)
816 namelist
= merge_sort (namelist
, num_names
, compare_names
);
818 for (name
= namelist
; name
; name
= name
->next
)
822 /* This is like name_match, except that it returns a pointer to the
823 name it matched, and doesn't set FOUND in structure. The caller
824 will have to do that if it wants to. Oh, and if the namelist is
825 empty, it returns null, unlike name_match, which returns TRUE. */
827 name_scan (const char *path
)
829 size_t length
= strlen (path
);
833 struct name
*cursor
= namelist_match (path
, length
);
837 /* Filename from archive not found in namelist. If we have the whole
838 namelist here, just return 0. Otherwise, read the next name in and
839 compare it. If this was the last name, namelist->found will remain
840 on. If not, we loop to compare the newly read name. */
842 if (same_order_option
&& namelist
&& namelist
->found
)
844 name_gather (); /* read one more */
853 /* This returns a name from the namelist which doesn't have ->found
854 set. It sets ->found before returning, so successive calls will
855 find and return all the non-found names in the namelist. */
856 struct name
*gnu_list_name
;
859 name_from_list (void)
862 gnu_list_name
= namelist
;
863 while (gnu_list_name
&& (gnu_list_name
->found
| gnu_list_name
->fake
))
864 gnu_list_name
= gnu_list_name
->next
;
867 gnu_list_name
->found
= 1;
868 chdir_do (gnu_list_name
->change_dir
);
869 return gnu_list_name
->name
;
875 blank_name_list (void)
880 for (name
= namelist
; name
; name
= name
->next
)
884 /* Yield a newly allocated file name consisting of PATH concatenated to
885 NAME, with an intervening slash if PATH does not already end in one. */
887 new_name (const char *path
, const char *name
)
889 size_t pathlen
= strlen (path
);
890 size_t namesize
= strlen (name
) + 1;
891 int slash
= pathlen
&& ! ISSLASH (path
[pathlen
- 1]);
892 char *buffer
= xmalloc (pathlen
+ slash
+ namesize
);
893 memcpy (buffer
, path
, pathlen
);
894 buffer
[pathlen
] = '/';
895 memcpy (buffer
+ pathlen
+ slash
, name
, namesize
);
899 /* Return nonzero if file NAME is excluded. Exclude a name if its
900 prefix matches a pattern that contains slashes, or if one of its
901 components matches a pattern that contains no slashes. */
903 excluded_name (char const *name
)
905 return excluded_filename (excluded
, name
+ FILESYSTEM_PREFIX_LEN (name
));
908 /* Names to avoid dumping. */
909 static Hash_table
*avoided_name_table
;
911 /* Calculate the hash of an avoided name. */
913 hash_avoided_name (void const *name
, unsigned n_buckets
)
915 return hash_string (name
, n_buckets
);
918 /* Compare two avoided names for equality. */
920 compare_avoided_names (void const *name1
, void const *name2
)
922 return strcmp (name1
, name2
) == 0;
925 /* Remember to not archive NAME. */
927 add_avoided_name (char const *name
)
929 if (! ((avoided_name_table
930 || (avoided_name_table
= hash_initialize (0, 0, hash_avoided_name
,
931 compare_avoided_names
, 0)))
932 && hash_insert (avoided_name_table
, xstrdup (name
))))
936 /* Should NAME be avoided when archiving? */
938 is_avoided_name (char const *name
)
940 return avoided_name_table
&& hash_lookup (avoided_name_table
, name
);