1 /* Various processing of names.
2 Copyright 1988, 92, 94, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 2, or (at your option) any later
9 This program is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
12 Public License for more details.
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
28 /* User and group names. */
30 struct group
*getgrnam ();
31 struct passwd
*getpwnam ();
32 #if ! HAVE_DECL_GETPWUID
33 struct passwd
*getpwuid ();
35 #if ! HAVE_DECL_GETGRGID
36 struct group
*getgrgid ();
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
44 static char cached_uname
[UNAME_FIELD_SIZE
];
45 static char cached_gname
[GNAME_FIELD_SIZE
];
47 static uid_t cached_uid
; /* valid only if cached_uname is not empty */
48 static gid_t cached_gid
; /* valid only if cached_gname is not empty */
50 /* These variables are valid only if nonempty. */
51 static char cached_no_such_uname
[UNAME_FIELD_SIZE
];
52 static char cached_no_such_gname
[GNAME_FIELD_SIZE
];
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. */
56 static uid_t cached_no_such_uid
;
57 static gid_t cached_no_such_gid
;
59 /* Given UID, find the corresponding UNAME. */
61 uid_to_uname (uid_t uid
, char uname
[UNAME_FIELD_SIZE
])
63 struct passwd
*passwd
;
65 if (uid
!= 0 && uid
== cached_no_such_uid
)
71 if (!cached_uname
[0] || uid
!= cached_uid
)
73 passwd
= getpwuid (uid
);
77 strncpy (cached_uname
, passwd
->pw_name
, UNAME_FIELD_SIZE
);
81 cached_no_such_uid
= uid
;
86 strncpy (uname
, cached_uname
, UNAME_FIELD_SIZE
);
89 /* Given GID, find the corresponding GNAME. */
91 gid_to_gname (gid_t gid
, char gname
[GNAME_FIELD_SIZE
])
95 if (gid
!= 0 && gid
== cached_no_such_gid
)
101 if (!cached_gname
[0] || gid
!= cached_gid
)
103 group
= getgrgid (gid
);
107 strncpy (cached_gname
, group
->gr_name
, GNAME_FIELD_SIZE
);
111 cached_no_such_gid
= gid
;
116 strncpy (gname
, cached_gname
, GNAME_FIELD_SIZE
);
119 /* Given UNAME, set the corresponding UID and return 1, or else, return 0. */
121 uname_to_uid (char uname
[UNAME_FIELD_SIZE
], uid_t
*uidp
)
123 struct passwd
*passwd
;
125 if (cached_no_such_uname
[0]
126 && strncmp (uname
, cached_no_such_uname
, UNAME_FIELD_SIZE
) == 0)
130 || uname
[0] != cached_uname
[0]
131 || strncmp (uname
, cached_uname
, UNAME_FIELD_SIZE
) != 0)
133 passwd
= getpwnam (uname
);
136 cached_uid
= passwd
->pw_uid
;
137 strncpy (cached_uname
, uname
, UNAME_FIELD_SIZE
);
141 strncpy (cached_no_such_uname
, uname
, UNAME_FIELD_SIZE
);
149 /* Given GNAME, set the corresponding GID and return 1, or else, return 0. */
151 gname_to_gid (char gname
[GNAME_FIELD_SIZE
], gid_t
*gidp
)
155 if (cached_no_such_gname
[0]
156 && strncmp (gname
, cached_no_such_gname
, GNAME_FIELD_SIZE
) == 0)
160 || gname
[0] != cached_gname
[0]
161 || strncmp (gname
, cached_gname
, GNAME_FIELD_SIZE
) != 0)
163 group
= getgrnam (gname
);
166 cached_gid
= group
->gr_gid
;
167 strncpy (cached_gname
, gname
, GNAME_FIELD_SIZE
);
171 strncpy (cached_no_such_gname
, gname
, GNAME_FIELD_SIZE
);
179 /* Names from the command call. */
181 static struct name
*namelist
; /* first name in list, if any */
182 static struct name
**nametail
= &namelist
; /* end of name list */
183 static const char **name_array
; /* store an array of names */
184 static int allocated_names
; /* how big is the array? */
185 static int names
; /* how many entries does it have? */
186 static int name_index
; /* how many of the entries have we scanned? */
188 /* Initialize structures. */
192 allocated_names
= 10;
193 name_array
= xmalloc (sizeof (const char *) * allocated_names
);
197 /* Add NAME at end of name_array, reallocating it as necessary. */
199 name_add (const char *name
)
201 if (names
== allocated_names
)
203 allocated_names
*= 2;
205 xrealloc (name_array
, sizeof (const char *) * allocated_names
);
207 name_array
[names
++] = name
;
210 /* Names from external name file. */
212 static FILE *name_file
; /* file to read names from */
213 static char *name_buffer
; /* buffer to hold the current file name */
214 static size_t name_buffer_length
; /* allocated length of name_buffer */
216 /* FIXME: I should better check more closely. It seems at first glance that
217 is_pattern is only used when reading a file, and ignored for all
218 command line arguments. */
221 is_pattern (const char *string
)
223 return strchr (string
, '*') || strchr (string
, '[') || strchr (string
, '?');
226 /* Set up to gather file names for tar. They can either come from a
227 file or were saved from decoding arguments. */
229 name_init (int argc
, char *const *argv
)
231 name_buffer
= xmalloc (NAME_FIELD_SIZE
+ 2);
232 name_buffer_length
= NAME_FIELD_SIZE
;
234 if (files_from_option
)
236 if (!strcmp (files_from_option
, "-"))
238 request_stdin ("-T");
241 else if (name_file
= fopen (files_from_option
, "r"), !name_file
)
242 open_fatal (files_from_option
);
253 /* Read the next filename from name_file and null-terminate it. Put
254 it into name_buffer, reallocating and adjusting name_buffer_length
255 if necessary. Return 0 at end of file, 1 otherwise. */
257 read_name_from_file (void)
262 /* FIXME: getc may be called even if character was EOF the last time here. */
264 /* FIXME: This + 2 allocation might serve no purpose. */
266 while (character
= getc (name_file
),
267 character
!= EOF
&& character
!= filename_terminator
)
269 if (counter
== name_buffer_length
)
271 name_buffer_length
+= NAME_FIELD_SIZE
;
272 name_buffer
= xrealloc (name_buffer
, name_buffer_length
+ 2);
274 name_buffer
[counter
++] = character
;
277 if (counter
== 0 && character
== EOF
)
280 if (counter
== name_buffer_length
)
282 name_buffer_length
+= NAME_FIELD_SIZE
;
283 name_buffer
= xrealloc (name_buffer
, name_buffer_length
+ 2);
285 name_buffer
[counter
] = '\0';
290 /* Get the next name from ARGV or the file of names. Result is in
291 static storage and can't be relied upon across two calls.
293 If CHANGE_DIRS is true, treat a filename of the form "-C" as
294 meaning that the next filename is the name of a directory to change
295 to. If filename_terminator is NUL, CHANGE_DIRS is effectively
298 name_next (int change_dirs
)
304 if (filename_terminator
== '\0')
309 /* Get a name, either from file or from saved arguments. */
311 if (name_index
== names
)
315 if (! read_name_from_file ())
320 source
= name_array
[name_index
++];
321 if (strlen (source
) > name_buffer_length
)
324 name_buffer_length
= strlen (source
);
325 name_buffer
= xmalloc (name_buffer_length
+ 2);
327 strcpy (name_buffer
, source
);
330 /* Zap trailing slashes. */
332 cursor
= name_buffer
+ strlen (name_buffer
) - 1;
333 while (cursor
> name_buffer
&& *cursor
== '/')
338 if (chdir (name_buffer
) < 0)
339 chdir_fatal (name_buffer
);
342 else if (change_dirs
&& strcmp (name_buffer
, "-C") == 0)
346 unquote_string (name_buffer
);
351 /* No more names in file. */
353 if (name_file
&& chdir_flag
)
354 FATAL_ERROR ((0, 0, _("Missing file name after -C")));
359 /* Close the name file, if any. */
363 if (name_file
&& name_file
!= stdin
)
364 if (fclose (name_file
) != 0)
365 close_error (name_buffer
);
368 /* Gather names in a list for scanning. Could hash them later if we
371 If the names are already sorted to match the archive, we just read
372 them one by one. name_gather reads the first one, and it is called
373 by name_match as appropriate to read the next ones. At EOF, the
374 last name read is just left in the buffer. This option lets users
375 of small machines extract an arbitrary number of files by doing
376 "tar t" and editing down the list of files. */
381 /* Buffer able to hold a single name. */
382 static struct name
*buffer
;
383 static size_t allocated_length
;
387 if (same_order_option
)
389 static int change_dir
;
391 if (allocated_length
== 0)
393 allocated_length
= sizeof (struct name
) + NAME_FIELD_SIZE
;
394 buffer
= xmalloc (allocated_length
);
395 /* FIXME: This memset is overkill, and ugly... */
396 memset (buffer
, 0, allocated_length
);
399 while ((name
= name_next (0)) && strcmp (name
, "-C") == 0)
401 char const *dir
= name_next (0);
403 FATAL_ERROR ((0, 0, _("Missing file name after -C")));
404 change_dir
= chdir_arg (xstrdup (dir
));
409 buffer
->length
= strlen (name
);
410 if (sizeof (struct name
) + buffer
->length
>= allocated_length
)
412 allocated_length
= sizeof (struct name
) + buffer
->length
;
413 buffer
= xrealloc (buffer
, allocated_length
);
415 buffer
->change_dir
= change_dir
;
416 memcpy (buffer
->name
, name
, buffer
->length
+ 1);
421 nametail
= &namelist
->next
;
426 /* Non sorted names -- read them all in. */
431 int change_dir0
= change_dir
;
432 while ((name
= name_next (0)) && strcmp (name
, "-C") == 0)
434 char const *dir
= name_next (0);
436 FATAL_ERROR ((0, 0, _("Missing file name after -C")));
437 change_dir
= chdir_arg (xstrdup (dir
));
440 addname (name
, change_dir
);
443 if (change_dir
!= change_dir0
)
444 addname (0, change_dir
);
451 /* Add a name to the namelist. */
453 addname (char const *string
, int change_dir
)
458 length
= string
? strlen (string
) : 0;
459 name
= xmalloc (sizeof (struct name
) + length
);
460 memset (name
, 0, sizeof (struct name
) + length
);
466 name
->length
= length
;
467 memcpy (name
->name
, string
, length
+ 1);
473 name
->regexp
= 0; /* assume not a regular expression */
474 name
->firstch
= 1; /* assume first char is literal */
475 name
->change_dir
= change_dir
;
476 name
->dir_contents
= 0;
478 if (string
&& is_pattern (string
))
481 if (string
[0] == '*' || string
[0] == '[' || string
[0] == '?')
486 nametail
= &name
->next
;
490 /* Find a match for PATH (whose string length is LENGTH) in the name
493 namelist_match (char const *path
, size_t length
)
497 for (p
= namelist
; p
; p
= p
->next
)
499 /* If first chars don't match, quick skip. */
501 if (p
->firstch
&& p
->name
[0] != path
[0])
505 ? fnmatch (p
->name
, path
, recursion_option
) == 0
506 : (p
->length
<= length
507 && (path
[p
->length
] == '\0' || path
[p
->length
] == '/')
508 && memcmp (path
, p
->name
, p
->length
) == 0))
515 /* Return true if and only if name PATH (from an archive) matches any
516 name from the namelist. */
518 name_match (const char *path
)
520 size_t length
= strlen (path
);
524 struct name
*cursor
= namelist
;
527 return ! files_from_option
;
531 chdir_do (cursor
->change_dir
);
533 nametail
= &namelist
;
534 return ! files_from_option
;
537 cursor
= namelist_match (path
, length
);
540 cursor
->found
= 1; /* remember it matched */
541 if (starting_file_option
)
545 nametail
= &namelist
;
547 chdir_do (cursor
->change_dir
);
549 /* We got a match. */
553 /* Filename from archive not found in namelist. If we have the whole
554 namelist here, just return 0. Otherwise, read the next name in and
555 compare it. If this was the last name, namelist->found will remain
556 on. If not, we loop to compare the newly read name. */
558 if (same_order_option
&& namelist
->found
)
560 name_gather (); /* read one more */
569 /* Print the names of things in the namelist that were not matched. */
571 names_notfound (void)
573 struct name
const *cursor
;
575 for (cursor
= namelist
; cursor
; cursor
= cursor
->next
)
576 if (!cursor
->found
&& !cursor
->fake
)
577 ERROR ((0, 0, _("%s: Not found in archive"),
578 quotearg_colon (cursor
->name
)));
580 /* Don't bother freeing the name list; we're about to exit. */
582 nametail
= &namelist
;
584 if (same_order_option
)
588 while (name
= name_next (1), name
)
589 ERROR ((0, 0, _("%s: Not found in archive"),
590 quotearg_colon (name
)));
594 /* Sorting name lists. */
596 /* Sort linked LIST of names, of given LENGTH, using COMPARE to order
597 names. Return the sorted list. Apart from the type `struct name'
598 and the definition of SUCCESSOR, this is a generic list-sorting
599 function, but it's too painful to make it both generic and portable
603 merge_sort (struct name
*list
, int length
,
604 int (*compare
) (struct name
const*, struct name
const*))
606 struct name
*first_list
;
607 struct name
*second_list
;
611 struct name
**merge_point
;
615 # define SUCCESSOR(name) ((name)->next)
622 if ((*compare
) (list
, SUCCESSOR (list
)) > 0)
624 result
= SUCCESSOR (list
);
625 SUCCESSOR (result
) = list
;
626 SUCCESSOR (list
) = 0;
633 first_length
= (length
+ 1) / 2;
634 second_length
= length
/ 2;
635 for (cursor
= list
, counter
= first_length
- 1;
637 cursor
= SUCCESSOR (cursor
), counter
--)
639 second_list
= SUCCESSOR (cursor
);
640 SUCCESSOR (cursor
) = 0;
642 first_list
= merge_sort (first_list
, first_length
, compare
);
643 second_list
= merge_sort (second_list
, second_length
, compare
);
645 merge_point
= &result
;
646 while (first_list
&& second_list
)
647 if ((*compare
) (first_list
, second_list
) < 0)
649 cursor
= SUCCESSOR (first_list
);
650 *merge_point
= first_list
;
651 merge_point
= &SUCCESSOR (first_list
);
656 cursor
= SUCCESSOR (second_list
);
657 *merge_point
= second_list
;
658 merge_point
= &SUCCESSOR (second_list
);
659 second_list
= cursor
;
662 *merge_point
= first_list
;
664 *merge_point
= second_list
;
671 /* A comparison function for sorting names. Put found names last;
672 break ties by string comparison. */
675 compare_names (struct name
const *n1
, struct name
const *n2
)
677 int found_diff
= n2
->found
- n1
->found
;
678 return found_diff
? found_diff
: strcmp (n1
->name
, n2
->name
);
681 /* Add all the dirs under NAME, which names a directory, to the namelist.
682 DIRSIZE is the size of the directory, or -1 if not known.
683 If any of the files is a directory, recurse on the subdirectory.
684 DEVICE is the device not to leave, if the -l option is specified. */
687 add_hierarchy_to_namelist (struct name
*name
, off_t dirsize
, dev_t device
)
689 char *path
= name
->name
;
690 char *buffer
= get_directory_contents (path
, dirsize
, device
);
693 name
->dir_contents
= "\0\0\0\0";
696 size_t name_length
= name
->length
;
697 size_t allocated_length
= (name_length
>= NAME_FIELD_SIZE
698 ? name_length
+ NAME_FIELD_SIZE
700 char *name_buffer
= xmalloc (allocated_length
+ 1);
701 /* FIXME: + 2 above? */
703 size_t string_length
;
704 int change_dir
= name
->change_dir
;
706 name
->dir_contents
= buffer
;
707 strcpy (name_buffer
, path
);
708 if (name_buffer
[name_length
- 1] != '/')
710 name_buffer
[name_length
++] = '/';
711 name_buffer
[name_length
] = '\0';
714 for (string
= buffer
; *string
; string
+= string_length
+ 1)
716 string_length
= strlen (string
);
719 if (name_length
+ string_length
>= allocated_length
)
721 while (name_length
+ string_length
>= allocated_length
)
722 allocated_length
+= NAME_FIELD_SIZE
;
723 name_buffer
= xrealloc (name_buffer
, allocated_length
+ 1);
725 strcpy (name_buffer
+ name_length
, string
+ 1);
726 add_hierarchy_to_namelist (addname (name_buffer
, change_dir
),
735 /* Collect all the names from argv[] (or whatever), expand them into a
736 directory tree, and sort them. This gets only subdirectories, not
740 collect_and_sort_names (void)
743 struct name
*next_name
;
749 if (listed_incremental_option
)
750 read_directory_file ();
755 for (name
= namelist
; name
; name
= next_name
)
757 next_name
= name
->next
;
758 if (name
->found
|| name
->dir_contents
)
760 if (name
->regexp
) /* FIXME: just skip regexps for now */
762 chdir_do (name
->change_dir
);
766 if (deref_stat (dereference_option
, name
->name
, &statbuf
) != 0)
768 stat_error (name
->name
);
771 if (S_ISDIR (statbuf
.st_mode
))
774 add_hierarchy_to_namelist (name
, statbuf
.st_size
, statbuf
.st_dev
);
779 for (name
= namelist
; name
; name
= name
->next
)
781 namelist
= merge_sort (namelist
, num_names
, compare_names
);
783 for (name
= namelist
; name
; name
= name
->next
)
787 /* This is like name_match, except that it returns a pointer to the
788 name it matched, and doesn't set FOUND in structure. The caller
789 will have to do that if it wants to. Oh, and if the namelist is
790 empty, it returns null, unlike name_match, which returns TRUE. */
792 name_scan (const char *path
)
794 size_t length
= strlen (path
);
798 struct name
*cursor
= namelist_match (path
, length
);
802 /* Filename from archive not found in namelist. If we have the whole
803 namelist here, just return 0. Otherwise, read the next name in and
804 compare it. If this was the last name, namelist->found will remain
805 on. If not, we loop to compare the newly read name. */
807 if (same_order_option
&& namelist
&& namelist
->found
)
809 name_gather (); /* read one more */
818 /* This returns a name from the namelist which doesn't have ->found
819 set. It sets ->found before returning, so successive calls will
820 find and return all the non-found names in the namelist. */
821 struct name
*gnu_list_name
;
824 name_from_list (void)
827 gnu_list_name
= namelist
;
828 while (gnu_list_name
&& (gnu_list_name
->found
| gnu_list_name
->fake
))
829 gnu_list_name
= gnu_list_name
->next
;
832 gnu_list_name
->found
= 1;
833 chdir_do (gnu_list_name
->change_dir
);
834 return gnu_list_name
->name
;
840 blank_name_list (void)
845 for (name
= namelist
; name
; name
= name
->next
)
849 /* Yield a newly allocated file name consisting of PATH concatenated to
850 NAME, with an intervening slash if PATH does not already end in one. */
852 new_name (const char *path
, const char *name
)
854 size_t pathlen
= strlen (path
);
855 size_t namesize
= strlen (name
) + 1;
856 int slash
= pathlen
&& path
[pathlen
- 1] != '/';
857 char *buffer
= xmalloc (pathlen
+ slash
+ namesize
);
858 memcpy (buffer
, path
, pathlen
);
859 buffer
[pathlen
] = '/';
860 memcpy (buffer
+ pathlen
+ slash
, name
, namesize
);
864 /* Return nonzero if file NAME is excluded. Exclude a name if its
865 prefix matches a pattern that contains slashes, or if one of its
866 components matches a pattern that contains no slashes. */
868 excluded_name (char const *name
)
871 name
+= FILESYSTEM_PREFIX_LEN (name
);
873 if (excluded_filename (excluded_with_slash
, name
,
874 FNM_FILE_NAME
| recursion_option
))
877 for (p
= name
; *p
; p
++)
878 if (((p
== name
|| ISSLASH (p
[-1])) && !ISSLASH (p
[0]))
879 && excluded_filename (excluded_without_slash
, p
,
880 FNM_FILE_NAME
| FNM_LEADING_DIR
))
886 /* Names to avoid dumping. */
887 static Hash_table
*avoided_name_table
;
889 /* Calculate the hash of an avoided name. */
891 hash_avoided_name (void const *name
, unsigned n_buckets
)
893 return hash_string (name
, n_buckets
);
896 /* Compare two avoided names for equality. */
898 compare_avoided_names (void const *name1
, void const *name2
)
900 return strcmp (name1
, name2
) == 0;
903 /* Remember to not archive NAME. */
905 add_avoided_name (char const *name
)
907 if (! ((avoided_name_table
908 || (avoided_name_table
= hash_initialize (0, 0, hash_avoided_name
,
909 compare_avoided_names
, 0)))
910 && hash_insert (avoided_name_table
, xstrdup (name
))))
914 /* Should NAME be avoided when archiving? */
916 is_avoided_name (char const *name
)
918 return avoided_name_table
&& hash_lookup (avoided_name_table
, name
);