1 /* Various processing of names.
3 Copyright 1988, 1992, 1994, 1996-2001, 2003-2007, 2009, 2013-2014
4 Free 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 3, 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, see <http://www.gnu.org/licenses/>. */
24 #include <wordsplit.h>
29 /* User and group names. */
31 /* Make sure you link with the proper libraries if you are running the
32 Yellow Peril (thanks for the good laugh, Ian J.!), or, euh... NIS.
33 This code should also be modified for non-UNIX systems to do something
36 static char *cached_uname
;
37 static char *cached_gname
;
39 static uid_t cached_uid
; /* valid only if cached_uname is not empty */
40 static gid_t cached_gid
; /* valid only if cached_gname is not empty */
42 /* These variables are valid only if nonempty. */
43 static char *cached_no_such_uname
;
44 static char *cached_no_such_gname
;
46 /* These variables are valid only if nonzero. It's not worth optimizing
47 the case for weird systems where 0 is not a valid uid or gid. */
48 static uid_t cached_no_such_uid
;
49 static gid_t cached_no_such_gid
;
51 /* Given UID, find the corresponding UNAME. */
53 uid_to_uname (uid_t uid
, char **uname
)
55 struct passwd
*passwd
;
57 if (uid
!= 0 && uid
== cached_no_such_uid
)
59 *uname
= xstrdup ("");
63 if (!cached_uname
|| uid
!= cached_uid
)
65 passwd
= getpwuid (uid
);
69 assign_string (&cached_uname
, passwd
->pw_name
);
73 cached_no_such_uid
= uid
;
74 *uname
= xstrdup ("");
78 *uname
= xstrdup (cached_uname
);
81 /* Given GID, find the corresponding GNAME. */
83 gid_to_gname (gid_t gid
, char **gname
)
87 if (gid
!= 0 && gid
== cached_no_such_gid
)
89 *gname
= xstrdup ("");
93 if (!cached_gname
|| gid
!= cached_gid
)
95 group
= getgrgid (gid
);
99 assign_string (&cached_gname
, group
->gr_name
);
103 cached_no_such_gid
= gid
;
104 *gname
= xstrdup ("");
108 *gname
= xstrdup (cached_gname
);
111 /* Given UNAME, set the corresponding UID and return 1, or else, return 0. */
113 uname_to_uid (char const *uname
, uid_t
*uidp
)
115 struct passwd
*passwd
;
117 if (cached_no_such_uname
118 && strcmp (uname
, cached_no_such_uname
) == 0)
122 || uname
[0] != cached_uname
[0]
123 || strcmp (uname
, cached_uname
) != 0)
125 passwd
= getpwnam (uname
);
128 cached_uid
= passwd
->pw_uid
;
129 assign_string (&cached_uname
, passwd
->pw_name
);
133 assign_string (&cached_no_such_uname
, uname
);
141 /* Given GNAME, set the corresponding GID and return 1, or else, return 0. */
143 gname_to_gid (char const *gname
, gid_t
*gidp
)
147 if (cached_no_such_gname
148 && strcmp (gname
, cached_no_such_gname
) == 0)
152 || gname
[0] != cached_gname
[0]
153 || strcmp (gname
, cached_gname
) != 0)
155 group
= getgrnam (gname
);
158 cached_gid
= group
->gr_gid
;
159 assign_string (&cached_gname
, gname
);
163 assign_string (&cached_no_such_gname
, gname
);
173 make_name (const char *file_name
)
175 struct name
*p
= xzalloc (sizeof (*p
));
178 p
->name
= xstrdup (file_name
);
179 p
->length
= strlen (p
->name
);
184 free_name (struct name
*p
)
195 /* Names from the command call. */
197 static struct name
*namelist
; /* first name in list, if any */
198 static struct name
*nametail
; /* end of name list */
200 /* File name arguments are processed in two stages: first a
201 name element list (see below) is filled, then the names from it
202 are moved into the namelist.
204 This awkward process is needed only to implement --same-order option,
205 which is meant to help process large archives on machines with
206 limited memory. With this option on, namelist contains at most one
207 entry, which diminishes the memory consumption.
209 However, I very much doubt if we still need this -- Sergey */
211 /* A name_list element contains entries of three types: */
213 #define NELT_NAME 0 /* File name */
214 #define NELT_CHDIR 1 /* Change directory request */
215 #define NELT_FMASK 2 /* Change fnmatch options request */
216 #define NELT_FILE 3 /* Read file names from that file */
217 #define NELT_NOOP 4 /* No operation */
219 struct name_elt
/* A name_array element. */
221 struct name_elt
*next
, *prev
;
222 char type
; /* Element type, see NELT_* constants above */
225 const char *name
; /* File or directory name */
226 int matching_flags
;/* fnmatch options if type == NELT_FMASK */
227 struct /* File, if type == NELT_FILE */
229 const char *name
;/* File name */
230 int term
; /* File name terminator in the list */
236 static struct name_elt
*name_head
; /* store a list of names */
237 size_t name_count
; /* how many of the entries are names? */
239 static struct name_elt
*
240 name_elt_alloc (void)
242 struct name_elt
*elt
;
244 elt
= xmalloc (sizeof (*elt
));
248 name_head
->prev
= name_head
->next
= NULL
;
249 name_head
->type
= NELT_NOOP
;
250 elt
= xmalloc (sizeof (*elt
));
253 elt
->prev
= name_head
->prev
;
255 name_head
->prev
->next
= elt
;
256 elt
->next
= name_head
;
257 name_head
->prev
= elt
;
261 static struct name_elt
*
262 name_elt_alloc_matflags (int matflags
)
264 static int prev_flags
= 0; /* FIXME: Or EXCLUDE_ANCHORED? */
265 struct name_elt
*ep
= name_elt_alloc ();
266 if (prev_flags
!= matflags
)
268 ep
->type
= NELT_FMASK
;
269 ep
->v
.matching_flags
= matflags
;
270 prev_flags
= matflags
;
271 ep
= name_elt_alloc ();
277 name_list_adjust (void)
280 while (name_head
->prev
)
281 name_head
= name_head
->prev
;
285 name_list_advance (void)
287 struct name_elt
*elt
= name_head
;
288 name_head
= elt
->next
;
290 name_head
->prev
= NULL
;
295 /* Add to name_array the file NAME with fnmatch options MATFLAGS */
297 name_add_name (const char *name
, int matflags
)
299 struct name_elt
*ep
= name_elt_alloc_matflags (matflags
);
301 ep
->type
= NELT_NAME
;
306 /* Add to name_array a chdir request for the directory NAME */
308 name_add_dir (const char *name
)
310 struct name_elt
*ep
= name_elt_alloc ();
311 ep
->type
= NELT_CHDIR
;
316 name_add_file (const char *name
, int term
, int matflags
)
318 struct name_elt
*ep
= name_elt_alloc_matflags (matflags
);
320 ep
->type
= NELT_FILE
;
321 ep
->v
.file
.name
= name
;
322 ep
->v
.file
.term
= term
;
323 ep
->v
.file
.fp
= NULL
;
326 /* Names from external name file. */
328 static char *name_buffer
; /* buffer to hold the current file name */
329 static size_t name_buffer_length
; /* allocated length of name_buffer */
331 /* Set up to gather file names for tar. They can either come from a
332 file or were saved from decoding arguments. */
336 name_buffer
= xmalloc (NAME_FIELD_SIZE
+ 2);
337 name_buffer_length
= NAME_FIELD_SIZE
;
347 /* Prevent recursive inclusion of the same file */
350 struct file_id_list
*next
;
353 const char *from_file
;
356 static struct file_id_list
*file_id_list
;
358 /* Return the name of the file from which the file names and options
362 file_list_name (void)
364 struct name_elt
*elt
;
366 for (elt
= name_head
; elt
; elt
= elt
->next
)
367 if (elt
->type
== NELT_FILE
&& elt
->v
.file
.fp
)
368 return elt
->v
.file
.name
;
369 return _("command line");
373 add_file_id (const char *filename
)
375 struct file_id_list
*p
;
377 const char *reading_from
;
379 if (stat (filename
, &st
))
380 stat_fatal (filename
);
381 reading_from
= file_list_name ();
382 for (p
= file_id_list
; p
; p
= p
->next
)
383 if (p
->ino
== st
.st_ino
&& p
->dev
== st
.st_dev
)
385 int oldc
= set_char_quoting (NULL
, ':', 1);
387 _("%s: file list requested from %s already read from %s"),
388 quotearg_n (0, filename
),
389 reading_from
, p
->from_file
));
390 set_char_quoting (NULL
, ':', oldc
);
393 p
= xmalloc (sizeof *p
);
394 p
->next
= file_id_list
;
397 p
->from_file
= reading_from
;
402 /* Chop trailing slashes. */
404 chopslash (char *str
)
406 char *p
= str
+ strlen (str
) - 1;
407 while (p
> str
&& ISSLASH (*p
))
411 enum read_file_list_state
/* Result of reading file name from the list file */
413 file_list_success
, /* OK, name read successfully */
414 file_list_end
, /* End of list file */
415 file_list_zero
, /* Zero separator encountered where it should not */
416 file_list_skip
/* Empty (zero-length) entry encountered, skip it */
419 /* Read from FP a sequence of characters up to TERM and put them
422 static enum read_file_list_state
423 read_name_from_file (struct name_elt
*ent
)
427 FILE *fp
= ent
->v
.file
.fp
;
428 int term
= ent
->v
.file
.term
;
430 for (c
= getc (fp
); c
!= EOF
&& c
!= term
; c
= getc (fp
))
432 if (counter
== name_buffer_length
)
433 name_buffer
= x2realloc (name_buffer
, &name_buffer_length
);
434 name_buffer
[counter
++] = c
;
437 /* We have read a zero separator. The file possibly is
439 return file_list_zero
;
443 if (counter
== 0 && c
!= EOF
)
444 return file_list_skip
;
446 if (counter
== name_buffer_length
)
447 name_buffer
= x2realloc (name_buffer
, &name_buffer_length
);
448 name_buffer
[counter
] = 0;
449 chopslash (name_buffer
);
450 return (counter
== 0 && c
== EOF
) ? file_list_end
: file_list_success
;
454 handle_option (const char *str
)
459 while (*str
&& isspace (*str
))
465 if (wordsplit (str
, &ws
, WRDSF_DEFFLAGS
|WRDSF_DOOFFS
))
466 FATAL_ERROR ((0, 0, _("cannot split string '%s': %s"),
467 str
, wordsplit_strerror (&ws
)));
468 ws
.ws_wordv
[0] = program_invocation_short_name
;
469 more_options (ws
.ws_wordc
+ws
.ws_offs
, ws
.ws_wordv
);
470 for (i
= 0; i
< ws
.ws_wordc
+ws
.ws_offs
; i
++)
471 ws
.ws_wordv
[i
] = NULL
;
473 wordsplit_free (&ws
);
478 read_next_name (struct name_elt
*ent
, struct name_elt
*ret
)
482 if (!strcmp (ent
->v
.file
.name
, "-"))
484 request_stdin ("-T");
485 ent
->v
.file
.fp
= stdin
;
489 if (add_file_id (ent
->v
.file
.name
))
491 name_list_advance ();
494 if ((ent
->v
.file
.fp
= fopen (ent
->v
.file
.name
, "r")) == NULL
)
495 open_fatal (ent
->v
.file
.name
);
501 switch (read_name_from_file (ent
))
507 WARNOPT (WARN_FILENAME_WITH_NULS
,
508 (0, 0, N_("%s: file name read contains nul character"),
509 quotearg_colon (ent
->v
.file
.name
)));
510 ent
->v
.file
.term
= 0;
512 case file_list_success
:
514 unquote_string (name_buffer
);
515 if (handle_option (name_buffer
) == 0)
520 ret
->type
= NELT_NAME
;
521 ret
->v
.name
= name_buffer
;
525 if (strcmp (ent
->v
.file
.name
, "-"))
526 fclose (ent
->v
.file
.fp
);
527 ent
->v
.file
.fp
= NULL
;
528 name_list_advance ();
535 copy_name (struct name_elt
*ep
)
541 source_len
= strlen (source
);
542 if (name_buffer_length
< source_len
)
546 name_buffer_length
*= 2;
547 if (! name_buffer_length
)
550 while (name_buffer_length
< source_len
);
553 name_buffer
= xmalloc(name_buffer_length
+ 2);
555 strcpy (name_buffer
, source
);
556 chopslash (name_buffer
);
560 static int matching_flags
; /* exclude_fnmatch options */
562 /* Get the next NELT_NAME element from name_array. Result is in
563 static storage and can't be relied upon across two calls.
565 If CHANGE_DIRS is true, treat any entries of type NELT_CHDIR as
566 the request to change to the given directory.
568 Entries of type NELT_FMASK cause updates of the matching_flags
571 static struct name_elt
*
572 name_next_elt (int change_dirs
)
574 static struct name_elt entry
;
577 while ((ep
= name_head
) != NULL
)
582 name_list_advance ();
586 matching_flags
= ep
->v
.matching_flags
;
587 recursion_option
= matching_flags
& FNM_LEADING_DIR
;
588 name_list_advance ();
592 if (read_next_name (ep
, &entry
) == 0)
599 chdir_do (chdir_arg (xstrdup (ep
->v
.name
)));
600 name_list_advance ();
607 unquote_string (name_buffer
);
608 entry
.type
= ep
->type
;
609 entry
.v
.name
= name_buffer
;
610 name_list_advance ();
619 name_next (int change_dirs
)
621 struct name_elt
*nelt
= name_next_elt (change_dirs
);
622 return nelt
? nelt
->v
.name
: NULL
;
625 /* Gather names in a list for scanning. Could hash them later if we
628 If the names are already sorted to match the archive, we just read
629 them one by one. name_gather reads the first one, and it is called
630 by name_match as appropriate to read the next ones. At EOF, the
631 last name read is just left in the buffer. This option lets users
632 of small machines extract an arbitrary number of files by doing
633 "tar t" and editing down the list of files. */
638 /* Buffer able to hold a single name. */
639 static struct name
*buffer
= NULL
;
643 if (same_order_option
)
645 static int change_dir
;
647 while ((ep
= name_next_elt (0)) && ep
->type
== NELT_CHDIR
)
648 change_dir
= chdir_arg (xstrdup (ep
->v
.name
));
653 buffer
= make_name (ep
->v
.name
);
654 buffer
->change_dir
= change_dir
;
656 buffer
->found_count
= 0;
657 buffer
->matching_flags
= matching_flags
;
658 buffer
->directory
= NULL
;
659 buffer
->parent
= NULL
;
660 buffer
->cmdline
= true;
662 namelist
= nametail
= buffer
;
665 addname (0, change_dir
, false, NULL
);
669 /* Non sorted names -- read them all in. */
674 int change_dir0
= change_dir
;
675 while ((ep
= name_next_elt (0)) && ep
->type
== NELT_CHDIR
)
676 change_dir
= chdir_arg (xstrdup (ep
->v
.name
));
679 addname (ep
->v
.name
, change_dir
, true, NULL
);
682 if (change_dir
!= change_dir0
)
683 addname (NULL
, change_dir
, false, NULL
);
690 /* Add a name to the namelist. */
692 addname (char const *string
, int change_dir
, bool cmdline
, struct name
*parent
)
694 struct name
*name
= make_name (string
);
696 name
->prev
= nametail
;
698 name
->found_count
= 0;
699 name
->matching_flags
= matching_flags
;
700 name
->change_dir
= change_dir
;
701 name
->directory
= NULL
;
702 name
->parent
= parent
;
703 name
->cmdline
= cmdline
;
706 nametail
->next
= name
;
713 /* Find a match for FILE_NAME (whose string length is LENGTH) in the name
716 namelist_match (char const *file_name
, size_t length
)
720 for (p
= namelist
; p
; p
= p
->next
)
723 && exclude_fnmatch (p
->name
, file_name
, p
->matching_flags
))
731 remname (struct name
*name
)
735 if ((p
= name
->prev
) != NULL
)
736 p
->next
= name
->next
;
738 namelist
= name
->next
;
740 if ((p
= name
->next
) != NULL
)
741 p
->prev
= name
->prev
;
743 nametail
= name
->prev
;
746 /* Return true if and only if name FILE_NAME (from an archive) matches any
747 name from the namelist. */
749 name_match (const char *file_name
)
751 size_t length
= strlen (file_name
);
755 struct name
*cursor
= namelist
;
760 if (cursor
->name
[0] == 0)
762 chdir_do (cursor
->change_dir
);
768 cursor
= namelist_match (file_name
, length
);
771 if (!(ISSLASH (file_name
[cursor
->length
]) && recursion_option
)
772 || cursor
->found_count
== 0)
773 cursor
->found_count
++; /* remember it matched */
774 if (starting_file_option
)
780 chdir_do (cursor
->change_dir
);
782 /* We got a match. */
783 return ISFOUND (cursor
);
786 /* Filename from archive not found in namelist. If we have the whole
787 namelist here, just return 0. Otherwise, read the next name in and
788 compare it. If this was the last name, namelist->found_count will
789 remain on. If not, we loop to compare the newly read name. */
791 if (same_order_option
&& namelist
->found_count
)
793 name_gather (); /* read one more */
794 if (namelist
->found_count
)
802 /* Returns true if all names from the namelist were processed.
803 P is the stat_info of the most recently processed entry.
804 The decision is postponed until the next entry is read if:
806 1) P ended with a slash (i.e. it was a directory)
807 2) P matches any entry from the namelist *and* represents a subdirectory
808 or a file lying under this entry (in the terms of directory structure).
810 This is necessary to handle contents of directories. */
812 all_names_found (struct tar_stat_info
*p
)
814 struct name
const *cursor
;
817 if (!p
->file_name
|| occurrence_option
== 0 || p
->had_trailing_slash
)
819 len
= strlen (p
->file_name
);
820 for (cursor
= namelist
; cursor
; cursor
= cursor
->next
)
822 if ((cursor
->name
[0] && !WASFOUND (cursor
))
823 || (len
>= cursor
->length
&& ISSLASH (p
->file_name
[cursor
->length
])))
830 regex_usage_warning (const char *name
)
832 static int warned_once
= 0;
834 if (warn_regex_usage
&& fnmatch_pattern_has_wildcards (name
, 0))
838 _("Pattern matching characters used in file names")));
840 _("Use --wildcards to enable pattern matching,"
841 " or --no-wildcards to suppress this warning")));
846 /* Print the names of things in the namelist that were not matched. */
848 names_notfound (void)
850 struct name
const *cursor
;
852 for (cursor
= namelist
; cursor
; cursor
= cursor
->next
)
853 if (!WASFOUND (cursor
) && cursor
->name
[0])
855 regex_usage_warning (cursor
->name
);
857 (cursor
->found_count
== 0) ?
858 _("%s: Not found in archive") :
859 _("%s: Required occurrence not found in archive"),
860 quotearg_colon (cursor
->name
)));
863 /* Don't bother freeing the name list; we're about to exit. */
867 if (same_order_option
)
871 while ((name
= name_next (1)) != NULL
)
873 regex_usage_warning (name
);
874 ERROR ((0, 0, _("%s: Not found in archive"),
875 quotearg_colon (name
)));
881 label_notfound (void)
883 struct name
const *cursor
;
888 for (cursor
= namelist
; cursor
; cursor
= cursor
->next
)
889 if (WASFOUND (cursor
))
893 error (0, 0, _("Archive label mismatch"));
894 set_exit_status (TAREXIT_DIFFERS
);
896 for (cursor
= namelist
; cursor
; cursor
= cursor
->next
)
898 if (regex_usage_warning (cursor
->name
))
902 /* Don't bother freeing the name list; we're about to exit. */
906 if (same_order_option
)
910 while ((name
= name_next (1)) != NULL
911 && regex_usage_warning (name
) == 0)
916 /* Sorting name lists. */
918 /* Sort *singly* linked LIST of names, of given LENGTH, using COMPARE
919 to order names. Return the sorted list. Note that after calling
920 this function, the 'prev' links in list elements are messed up.
922 Apart from the type 'struct name' and the definition of SUCCESSOR,
923 this is a generic list-sorting function, but it's too painful to
924 make it both generic and portable
928 merge_sort_sll (struct name
*list
, int length
,
929 int (*compare
) (struct name
const*, struct name
const*))
931 struct name
*first_list
;
932 struct name
*second_list
;
936 struct name
**merge_point
;
940 # define SUCCESSOR(name) ((name)->next)
947 if ((*compare
) (list
, SUCCESSOR (list
)) > 0)
949 result
= SUCCESSOR (list
);
950 SUCCESSOR (result
) = list
;
951 SUCCESSOR (list
) = 0;
958 first_length
= (length
+ 1) / 2;
959 second_length
= length
/ 2;
960 for (cursor
= list
, counter
= first_length
- 1;
962 cursor
= SUCCESSOR (cursor
), counter
--)
964 second_list
= SUCCESSOR (cursor
);
965 SUCCESSOR (cursor
) = 0;
967 first_list
= merge_sort_sll (first_list
, first_length
, compare
);
968 second_list
= merge_sort_sll (second_list
, second_length
, compare
);
970 merge_point
= &result
;
971 while (first_list
&& second_list
)
972 if ((*compare
) (first_list
, second_list
) < 0)
974 cursor
= SUCCESSOR (first_list
);
975 *merge_point
= first_list
;
976 merge_point
= &SUCCESSOR (first_list
);
981 cursor
= SUCCESSOR (second_list
);
982 *merge_point
= second_list
;
983 merge_point
= &SUCCESSOR (second_list
);
984 second_list
= cursor
;
987 *merge_point
= first_list
;
989 *merge_point
= second_list
;
996 /* Sort doubly linked LIST of names, of given LENGTH, using COMPARE
997 to order names. Return the sorted list. */
999 merge_sort (struct name
*list
, int length
,
1000 int (*compare
) (struct name
const*, struct name
const*))
1002 struct name
*head
, *p
, *prev
;
1003 head
= merge_sort_sll (list
, length
, compare
);
1004 /* Fixup prev pointers */
1005 for (prev
= NULL
, p
= head
; p
; prev
= p
, p
= p
->next
)
1010 /* A comparison function for sorting names. Put found names last;
1011 break ties by string comparison. */
1014 compare_names_found (struct name
const *n1
, struct name
const *n2
)
1016 int found_diff
= WASFOUND (n2
) - WASFOUND (n1
);
1017 return found_diff
? found_diff
: strcmp (n1
->name
, n2
->name
);
1020 /* Simple comparison by names. */
1022 compare_names (struct name
const *n1
, struct name
const *n2
)
1024 return strcmp (n1
->name
, n2
->name
);
1028 /* Add all the dirs under ST to the namelist NAME, descending the
1029 directory hierarchy recursively. */
1032 add_hierarchy_to_namelist (struct tar_stat_info
*st
, struct name
*name
)
1036 name
->directory
= scan_directory (st
);
1037 buffer
= directory_contents (name
->directory
);
1040 struct name
*child_head
= NULL
, *child_tail
= NULL
;
1041 size_t name_length
= name
->length
;
1042 size_t allocated_length
= (name_length
>= NAME_FIELD_SIZE
1043 ? name_length
+ NAME_FIELD_SIZE
1045 char *namebuf
= xmalloc (allocated_length
+ 1);
1046 /* FIXME: + 2 above? */
1048 size_t string_length
;
1049 int change_dir
= name
->change_dir
;
1051 strcpy (namebuf
, name
->name
);
1052 if (! ISSLASH (namebuf
[name_length
- 1]))
1054 namebuf
[name_length
++] = '/';
1055 namebuf
[name_length
] = '\0';
1058 for (string
= buffer
; *string
; string
+= string_length
+ 1)
1060 string_length
= strlen (string
);
1064 struct tar_stat_info subdir
;
1067 if (allocated_length
<= name_length
+ string_length
)
1071 allocated_length
*= 2;
1072 if (! allocated_length
)
1075 while (allocated_length
<= name_length
+ string_length
);
1077 namebuf
= xrealloc (namebuf
, allocated_length
+ 1);
1079 strcpy (namebuf
+ name_length
, string
+ 1);
1080 np
= addname (namebuf
, change_dir
, false, name
);
1084 child_tail
->sibling
= np
;
1087 tar_stat_init (&subdir
);
1095 subfd
= subfile_open (st
, string
+ 1,
1096 open_read_flags
| O_DIRECTORY
);
1098 open_diag (namebuf
);
1102 if (fstat (subfd
, &subdir
.stat
) != 0)
1103 stat_diag (namebuf
);
1104 else if (! (O_DIRECTORY
|| S_ISDIR (subdir
.stat
.st_mode
)))
1107 open_diag (namebuf
);
1111 subdir
.orig_file_name
= xstrdup (namebuf
);
1112 add_hierarchy_to_namelist (&subdir
, np
);
1113 restore_parent_fd (&subdir
);
1117 tar_stat_destroy (&subdir
);
1122 name
->child
= child_head
;
1126 /* Auxiliary functions for hashed table of struct name's. */
1129 name_hash (void const *entry
, size_t n_buckets
)
1131 struct name
const *name
= entry
;
1132 return hash_string (name
->caname
, n_buckets
);
1135 /* Compare two directories for equality of their names. */
1137 name_compare (void const *entry1
, void const *entry2
)
1139 struct name
const *name1
= entry1
;
1140 struct name
const *name2
= entry2
;
1141 return strcmp (name1
->caname
, name2
->caname
) == 0;
1145 /* Rebase 'name' member of CHILD and all its siblings to
1148 rebase_child_list (struct name
*child
, struct name
*parent
)
1150 size_t old_prefix_len
= child
->parent
->length
;
1151 size_t new_prefix_len
= parent
->length
;
1152 char *new_prefix
= parent
->name
;
1154 for (; child
; child
= child
->sibling
)
1156 size_t size
= child
->length
- old_prefix_len
+ new_prefix_len
;
1157 char *newp
= xmalloc (size
+ 1);
1158 strcpy (newp
, new_prefix
);
1159 strcat (newp
, child
->name
+ old_prefix_len
);
1162 child
->length
= size
;
1164 rebase_directory (child
->directory
,
1165 child
->parent
->name
, old_prefix_len
,
1166 new_prefix
, new_prefix_len
);
1170 /* Collect all the names from argv[] (or whatever), expand them into a
1171 directory tree, and sort them. This gets only subdirectories, not
1175 collect_and_sort_names (void)
1178 struct name
*next_name
, *prev_name
= NULL
;
1180 Hash_table
*nametab
;
1185 addname (".", 0, false, NULL
);
1187 if (listed_incremental_option
)
1189 switch (chdir_count ())
1195 if (namelist
->change_dir
== 0)
1197 _("Using -C option inside file list is not "
1198 "allowed with --listed-incremental")));
1203 _("Only one -C option is allowed with "
1204 "--listed-incremental")));
1207 read_directory_file ();
1211 for (name
= namelist
; name
; name
= name
->next
, num_names
++)
1213 struct tar_stat_info st
;
1215 if (name
->found_count
|| name
->directory
)
1217 if (name
->matching_flags
& EXCLUDE_WILDCARDS
)
1218 /* NOTE: EXCLUDE_ANCHORED is not relevant here */
1219 /* FIXME: just skip regexps for now */
1221 chdir_do (name
->change_dir
);
1223 if (name
->name
[0] == 0)
1226 tar_stat_init (&st
);
1228 if (deref_stat (name
->name
, &st
.stat
) != 0)
1230 stat_diag (name
->name
);
1233 if (S_ISDIR (st
.stat
.st_mode
))
1235 int dir_fd
= openat (chdir_fd
, name
->name
,
1236 open_read_flags
| O_DIRECTORY
);
1238 open_diag (name
->name
);
1242 if (fstat (dir_fd
, &st
.stat
) != 0)
1243 stat_diag (name
->name
);
1244 else if (O_DIRECTORY
|| S_ISDIR (st
.stat
.st_mode
))
1246 st
.orig_file_name
= xstrdup (name
->name
);
1247 name
->found_count
++;
1248 add_hierarchy_to_namelist (&st
, name
);
1253 tar_stat_destroy (&st
);
1256 namelist
= merge_sort (namelist
, num_names
, compare_names
);
1259 nametab
= hash_initialize (0, 0, name_hash
, name_compare
, NULL
);
1260 for (name
= namelist
; name
; name
= next_name
)
1262 next_name
= name
->next
;
1263 name
->caname
= normalize_filename (name
->change_dir
, name
->name
);
1266 struct name
*p
= hash_lookup (nametab
, name
);
1269 /* Keep the one listed in the command line */
1273 rebase_child_list (p
->child
, name
);
1274 hash_delete (nametab
, name
);
1275 /* FIXME: remove_directory (p->caname); ? */
1283 rebase_child_list (name
->child
, p
);
1284 /* FIXME: remove_directory (name->caname); ? */
1291 name
->found_count
= 0;
1292 if (!hash_insert (nametab
, name
))
1297 nametail
= prev_name
;
1298 hash_free (nametab
);
1300 namelist
= merge_sort (namelist
, num_names
, compare_names_found
);
1302 if (listed_incremental_option
)
1304 for (name
= namelist
; name
&& name
->name
[0] == 0; name
++)
1307 append_incremental_renames (name
->directory
);
1311 /* This is like name_match, except that
1312 1. It returns a pointer to the name it matched, and doesn't set FOUND
1313 in structure. The caller will have to do that if it wants to.
1314 2. If the namelist is empty, it returns null, unlike name_match, which
1317 name_scan (const char *file_name
)
1319 size_t length
= strlen (file_name
);
1323 struct name
*cursor
= namelist_match (file_name
, length
);
1327 /* Filename from archive not found in namelist. If we have the whole
1328 namelist here, just return 0. Otherwise, read the next name in and
1329 compare it. If this was the last name, namelist->found_count will
1330 remain on. If not, we loop to compare the newly read name. */
1332 if (same_order_option
&& namelist
&& namelist
->found_count
)
1334 name_gather (); /* read one more */
1335 if (namelist
->found_count
)
1343 /* This returns a name from the namelist which doesn't have ->found
1344 set. It sets ->found before returning, so successive calls will
1345 find and return all the non-found names in the namelist. */
1346 struct name
*gnu_list_name
;
1349 name_from_list (void)
1352 gnu_list_name
= namelist
;
1353 while (gnu_list_name
1354 && (gnu_list_name
->found_count
|| gnu_list_name
->name
[0] == 0))
1355 gnu_list_name
= gnu_list_name
->next
;
1358 gnu_list_name
->found_count
++;
1359 chdir_do (gnu_list_name
->change_dir
);
1360 return gnu_list_name
;
1366 blank_name_list (void)
1371 for (name
= namelist
; name
; name
= name
->next
)
1372 name
->found_count
= 0;
1375 /* Yield a newly allocated file name consisting of FILE_NAME concatenated to
1376 NAME, with an intervening slash if FILE_NAME does not already end in one. */
1378 new_name (const char *file_name
, const char *name
)
1380 size_t file_name_len
= strlen (file_name
);
1381 size_t namesize
= strlen (name
) + 1;
1382 int slash
= file_name_len
&& ! ISSLASH (file_name
[file_name_len
- 1]);
1383 char *buffer
= xmalloc (file_name_len
+ slash
+ namesize
);
1384 memcpy (buffer
, file_name
, file_name_len
);
1385 buffer
[file_name_len
] = '/';
1386 memcpy (buffer
+ file_name_len
+ slash
, name
, namesize
);
1392 /* Return the size of the prefix of FILE_NAME that is removed after
1393 stripping NUM leading file name components. NUM must be
1397 stripped_prefix_len (char const *file_name
, size_t num
)
1399 char const *p
= file_name
+ FILE_SYSTEM_PREFIX_LEN (file_name
);
1400 while (ISSLASH (*p
))
1404 bool slash
= ISSLASH (*p
);
1409 return p
- file_name
;
1410 while (ISSLASH (*p
))
1417 /* Return nonzero if NAME contains ".." as a file name component. */
1419 contains_dot_dot (char const *name
)
1421 char const *p
= name
+ FILE_SYSTEM_PREFIX_LEN (name
);
1425 if (p
[0] == '.' && p
[1] == '.' && (ISSLASH (p
[2]) || !p
[2]))
1428 while (! ISSLASH (*p
))