1 /* Various processing of names.
2
3 Copyright 1988-2021 Free Software Foundation, Inc.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 3, or (at your option) any later
8 version.
9
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13 Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18 #include <system.h>
19
20 #include <fnmatch.h>
21 #include <hash.h>
22 #include <quotearg.h>
23 #include <wordsplit.h>
24 #include <argp.h>
25
26 #include "common.h"
27
28 static void name_add_option (int option, const char *arg);
29 static void name_add_dir (const char *name);
30 static void name_add_file (const char *name);
31
32 enum
33 {
34 ADD_FILE_OPTION = 256,
35 EXCLUDE_BACKUPS_OPTION,
36 EXCLUDE_CACHES_OPTION,
37 EXCLUDE_CACHES_UNDER_OPTION,
38 EXCLUDE_CACHES_ALL_OPTION,
39 EXCLUDE_OPTION,
40 EXCLUDE_IGNORE_OPTION,
41 EXCLUDE_IGNORE_RECURSIVE_OPTION,
42 EXCLUDE_TAG_OPTION,
43 EXCLUDE_TAG_UNDER_OPTION,
44 EXCLUDE_TAG_ALL_OPTION,
45 EXCLUDE_VCS_OPTION,
46 EXCLUDE_VCS_IGNORES_OPTION,
47 IGNORE_CASE_OPTION,
48 NO_IGNORE_CASE_OPTION,
49 ANCHORED_OPTION,
50 NO_ANCHORED_OPTION,
51 RECURSION_OPTION,
52 NO_RECURSION_OPTION,
53 UNQUOTE_OPTION,
54 NO_UNQUOTE_OPTION,
55 NO_VERBATIM_FILES_FROM_OPTION,
56 NO_WILDCARDS_MATCH_SLASH_OPTION,
57 NO_WILDCARDS_OPTION,
58 NULL_OPTION,
59 NO_NULL_OPTION,
60 VERBATIM_FILES_FROM_OPTION,
61 WILDCARDS_MATCH_SLASH_OPTION,
62 WILDCARDS_OPTION
63 };
64
65 enum
66 {
67 GRH_LOCAL,
68 GRID_LOCAL,
69 GRH_MATCH,
70 GRID_MATCH,
71 };
72
73 static struct argp_option names_options[] = {
74 {NULL, 0, NULL, 0,
75 N_("Local file name selection:"), GRH_LOCAL },
76
77 {"add-file", ADD_FILE_OPTION, N_("FILE"), 0,
78 N_("add given FILE to the archive (useful if its name starts with a dash)"), GRID_LOCAL },
79 {"directory", 'C', N_("DIR"), 0,
80 N_("change to directory DIR"), GRID_LOCAL },
81 {"files-from", 'T', N_("FILE"), 0,
82 N_("get names to extract or create from FILE"), GRID_LOCAL },
83 {"null", NULL_OPTION, 0, 0,
84 N_("-T reads null-terminated names; implies --verbatim-files-from"),
85 GRID_LOCAL },
86 {"no-null", NO_NULL_OPTION, 0, 0,
87 N_("disable the effect of the previous --null option"), GRID_LOCAL },
88 {"unquote", UNQUOTE_OPTION, 0, 0,
89 N_("unquote input file or member names (default)"), GRID_LOCAL },
90 {"no-unquote", NO_UNQUOTE_OPTION, 0, 0,
91 N_("do not unquote input file or member names"), GRID_LOCAL },
92 {"verbatim-files-from", VERBATIM_FILES_FROM_OPTION, 0, 0,
93 N_("-T reads file names verbatim (no escape or option handling)"), GRID_LOCAL },
94 {"no-verbatim-files-from", NO_VERBATIM_FILES_FROM_OPTION, 0, 0,
95 N_("-T treats file names starting with dash as options (default)"),
96 GRID_LOCAL },
97 {"exclude", EXCLUDE_OPTION, N_("PATTERN"), 0,
98 N_("exclude files, given as a PATTERN"), GRID_LOCAL },
99 {"exclude-from", 'X', N_("FILE"), 0,
100 N_("exclude patterns listed in FILE"), GRID_LOCAL },
101 {"exclude-caches", EXCLUDE_CACHES_OPTION, 0, 0,
102 N_("exclude contents of directories containing CACHEDIR.TAG, "
103 "except for the tag file itself"), GRID_LOCAL },
104 {"exclude-caches-under", EXCLUDE_CACHES_UNDER_OPTION, 0, 0,
105 N_("exclude everything under directories containing CACHEDIR.TAG"),
106 GRID_LOCAL },
107 {"exclude-caches-all", EXCLUDE_CACHES_ALL_OPTION, 0, 0,
108 N_("exclude directories containing CACHEDIR.TAG"), GRID_LOCAL },
109 {"exclude-tag", EXCLUDE_TAG_OPTION, N_("FILE"), 0,
110 N_("exclude contents of directories containing FILE, except"
111 " for FILE itself"), GRID_LOCAL },
112 {"exclude-ignore", EXCLUDE_IGNORE_OPTION, N_("FILE"), 0,
113 N_("read exclude patterns for each directory from FILE, if it exists"),
114 GRID_LOCAL },
115 {"exclude-ignore-recursive", EXCLUDE_IGNORE_RECURSIVE_OPTION, N_("FILE"), 0,
116 N_("read exclude patterns for each directory and its subdirectories "
117 "from FILE, if it exists"), GRID_LOCAL },
118 {"exclude-tag-under", EXCLUDE_TAG_UNDER_OPTION, N_("FILE"), 0,
119 N_("exclude everything under directories containing FILE"), GRID_LOCAL },
120 {"exclude-tag-all", EXCLUDE_TAG_ALL_OPTION, N_("FILE"), 0,
121 N_("exclude directories containing FILE"), GRID_LOCAL },
122 {"exclude-vcs", EXCLUDE_VCS_OPTION, NULL, 0,
123 N_("exclude version control system directories"), GRID_LOCAL },
124 {"exclude-vcs-ignores", EXCLUDE_VCS_IGNORES_OPTION, NULL, 0,
125 N_("read exclude patterns from the VCS ignore files"), GRID_LOCAL },
126 {"exclude-backups", EXCLUDE_BACKUPS_OPTION, NULL, 0,
127 N_("exclude backup and lock files"), GRID_LOCAL },
128 {"recursion", RECURSION_OPTION, 0, 0,
129 N_("recurse into directories (default)"), GRID_LOCAL },
130 {"no-recursion", NO_RECURSION_OPTION, 0, 0,
131 N_("avoid descending automatically in directories"), GRID_LOCAL },
132
133 {NULL, 0, NULL, 0,
134 N_("File name matching options (affect both exclude and include patterns):"),
135 GRH_MATCH },
136 {"anchored", ANCHORED_OPTION, 0, 0,
137 N_("patterns match file name start"), GRID_MATCH },
138 {"no-anchored", NO_ANCHORED_OPTION, 0, 0,
139 N_("patterns match after any '/' (default for exclusion)"), GRID_MATCH },
140 {"ignore-case", IGNORE_CASE_OPTION, 0, 0,
141 N_("ignore case"), GRID_MATCH },
142 {"no-ignore-case", NO_IGNORE_CASE_OPTION, 0, 0,
143 N_("case sensitive matching (default)"), GRID_MATCH },
144 {"wildcards", WILDCARDS_OPTION, 0, 0,
145 N_("use wildcards (default for exclusion)"), GRID_MATCH },
146 {"no-wildcards", NO_WILDCARDS_OPTION, 0, 0,
147 N_("verbatim string matching"), GRID_MATCH },
148 {"wildcards-match-slash", WILDCARDS_MATCH_SLASH_OPTION, 0, 0,
149 N_("wildcards match '/' (default for exclusion)"), GRID_MATCH },
150 {"no-wildcards-match-slash", NO_WILDCARDS_MATCH_SLASH_OPTION, 0, 0,
151 N_("wildcards do not match '/'"), GRID_MATCH },
152
153 {NULL}
154 };
155
156 static struct argp_option const *
file_selection_option(int key)157 file_selection_option (int key)
158 {
159 struct argp_option *p;
160
161 for (p = names_options;
162 !(p->name == NULL && p->key == 0 && p->doc == NULL); p++)
163 if (p->key == key)
164 return p;
165 return NULL;
166 }
167
168 static char const *
file_selection_option_name(int key)169 file_selection_option_name (int key)
170 {
171 struct argp_option const *opt = file_selection_option (key);
172 return opt ? opt->name : NULL;
173 }
174
175 static bool
is_file_selection_option(int key)176 is_file_selection_option (int key)
177 {
178 return file_selection_option (key) != NULL;
179 }
180
181 /* Either NL or NUL, as decided by the --null option. */
182 static char filename_terminator = '\n';
183 /* Treat file names read from -T input verbatim */
184 static bool verbatim_files_from_option;
185
186 static error_t
names_parse_opt(int key,char * arg,struct argp_state * state)187 names_parse_opt (int key, char *arg, struct argp_state *state)
188 {
189 switch (key)
190 {
191 case 'C':
192 name_add_dir (arg);
193 break;
194
195 case 'T':
196 name_add_file (arg);
197 break;
198
199 case ADD_FILE_OPTION:
200 name_add_name (arg);
201 break;
202
203 case ARGP_KEY_ERROR:
204 {
205 struct tar_args *args = state->input;
206 if (args->loc->source == OPTS_FILE)
207 {
208 error (0, 0, _("%s:%lu: unrecognized option"), args->loc->name,
209 (unsigned long) args->loc->line);
210 set_exit_status (TAREXIT_FAILURE);
211 }
212 return ARGP_ERR_UNKNOWN;
213 }
214
215 default:
216 if (is_file_selection_option (key))
217 name_add_option (key, arg);
218 else
219 return ARGP_ERR_UNKNOWN;
220
221 }
222 return 0;
223 }
224
225 /* Wildcard matching settings */
226 enum wildcards
227 {
228 default_wildcards, /* For exclusion == enable_wildcards,
229 for inclusion == disable_wildcards */
230 disable_wildcards,
231 enable_wildcards
232 };
233
234 static enum wildcards wildcards = default_wildcards;
235 /* Wildcard settings (--wildcards/--no-wildcards) */
236 static int matching_flags = 0;
237 /* exclude_fnmatch options */
238 static int include_anchored = EXCLUDE_ANCHORED;
239 /* Pattern anchoring options used for file inclusion */
240
241 #define EXCLUDE_OPTIONS \
242 (((wildcards != disable_wildcards) ? EXCLUDE_WILDCARDS : 0) \
243 | matching_flags \
244 | recursion_option)
245
246 #define INCLUDE_OPTIONS \
247 (((wildcards == enable_wildcards) ? EXCLUDE_WILDCARDS : 0) \
248 | include_anchored \
249 | matching_flags \
250 | recursion_option)
251
252 static char const * const vcs_file_table[] = {
253 /* CVS: */
254 "CVS",
255 ".cvsignore",
256 /* RCS: */
257 "RCS",
258 /* SCCS: */
259 "SCCS",
260 /* SVN: */
261 ".svn",
262 /* git: */
263 ".git",
264 ".gitignore",
265 ".gitattributes",
266 ".gitmodules",
267 /* Arch: */
268 ".arch-ids",
269 "{arch}",
270 "=RELEASE-ID",
271 "=meta-update",
272 "=update",
273 /* Bazaar */
274 ".bzr",
275 ".bzrignore",
276 ".bzrtags",
277 /* Mercurial */
278 ".hg",
279 ".hgignore",
280 ".hgtags",
281 /* darcs */
282 "_darcs",
283 NULL
284 };
285
286 static char const * const backup_file_table[] = {
287 ".#*",
288 "*~",
289 "#*#",
290 NULL
291 };
292
293 static void
add_exclude_array(char const * const * fv,int opts)294 add_exclude_array (char const * const * fv, int opts)
295 {
296 int i;
297
298 for (i = 0; fv[i]; i++)
299 add_exclude (excluded, fv[i], opts);
300 }
301
302 static void
handle_file_selection_option(int key,const char * arg)303 handle_file_selection_option (int key, const char *arg)
304 {
305 switch (key)
306 {
307 case EXCLUDE_BACKUPS_OPTION:
308 add_exclude_array (backup_file_table, EXCLUDE_WILDCARDS);
309 break;
310
311 case EXCLUDE_OPTION:
312 add_exclude (excluded, arg, EXCLUDE_OPTIONS);
313 break;
314
315 case EXCLUDE_CACHES_OPTION:
316 add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_contents,
317 cachedir_file_p);
318 break;
319
320 case EXCLUDE_CACHES_UNDER_OPTION:
321 add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_under,
322 cachedir_file_p);
323 break;
324
325 case EXCLUDE_CACHES_ALL_OPTION:
326 add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_all,
327 cachedir_file_p);
328 break;
329
330 case EXCLUDE_IGNORE_OPTION:
331 excfile_add (arg, EXCL_NON_RECURSIVE);
332 break;
333
334 case EXCLUDE_IGNORE_RECURSIVE_OPTION:
335 excfile_add (arg, EXCL_RECURSIVE);
336 break;
337
338 case EXCLUDE_TAG_OPTION:
339 add_exclusion_tag (arg, exclusion_tag_contents, NULL);
340 break;
341
342 case EXCLUDE_TAG_UNDER_OPTION:
343 add_exclusion_tag (arg, exclusion_tag_under, NULL);
344 break;
345
346 case EXCLUDE_TAG_ALL_OPTION:
347 add_exclusion_tag (arg, exclusion_tag_all, NULL);
348 break;
349
350 case EXCLUDE_VCS_OPTION:
351 add_exclude_array (vcs_file_table, 0);
352 break;
353
354 case EXCLUDE_VCS_IGNORES_OPTION:
355 exclude_vcs_ignores ();
356 break;
357
358 case RECURSION_OPTION:
359 recursion_option = FNM_LEADING_DIR;
360 break;
361
362 case NO_RECURSION_OPTION:
363 recursion_option = 0;
364 break;
365
366 case UNQUOTE_OPTION:
367 unquote_option = true;
368 break;
369
370 case NO_UNQUOTE_OPTION:
371 unquote_option = false;
372 break;
373
374 case NULL_OPTION:
375 filename_terminator = '\0';
376 verbatim_files_from_option = true;
377 break;
378
379 case NO_NULL_OPTION:
380 filename_terminator = '\n';
381 verbatim_files_from_option = false;
382 break;
383
384 case 'X':
385 if (add_exclude_file (add_exclude, excluded, arg, EXCLUDE_OPTIONS, '\n')
386 != 0)
387 {
388 int e = errno;
389 FATAL_ERROR ((0, e, "%s", quotearg_colon (arg)));
390 }
391 break;
392
393 case ANCHORED_OPTION:
394 matching_flags |= EXCLUDE_ANCHORED;
395 break;
396
397 case NO_ANCHORED_OPTION:
398 include_anchored = 0; /* Clear the default for comman line args */
399 matching_flags &= ~ EXCLUDE_ANCHORED;
400 break;
401
402 case IGNORE_CASE_OPTION:
403 matching_flags |= FNM_CASEFOLD;
404 break;
405
406 case NO_IGNORE_CASE_OPTION:
407 matching_flags &= ~ FNM_CASEFOLD;
408 break;
409
410 case WILDCARDS_OPTION:
411 wildcards = enable_wildcards;
412 break;
413
414 case NO_WILDCARDS_OPTION:
415 wildcards = disable_wildcards;
416 break;
417
418 case WILDCARDS_MATCH_SLASH_OPTION:
419 matching_flags &= ~ FNM_FILE_NAME;
420 break;
421
422 case NO_WILDCARDS_MATCH_SLASH_OPTION:
423 matching_flags |= FNM_FILE_NAME;
424 break;
425
426 case VERBATIM_FILES_FROM_OPTION:
427 verbatim_files_from_option = true;
428 break;
429
430 case NO_VERBATIM_FILES_FROM_OPTION:
431 verbatim_files_from_option = false;
432 break;
433
434 default:
435 FATAL_ERROR ((0, 0, "unhandled positional option %d", key));
436 }
437 }
438
439 struct argp names_argp = {
440 names_options,
441 names_parse_opt,
442 NULL,
443 NULL,
444 NULL,
445 NULL,
446 NULL
447 };
448
449
450 /* User and group names. */
451
452 /* Make sure you link with the proper libraries if you are running the
453 Yellow Peril (thanks for the good laugh, Ian J.!), or, euh... NIS.
454 This code should also be modified for non-UNIX systems to do something
455 reasonable. */
456
457 static char *cached_uname;
458 static char *cached_gname;
459
460 static uid_t cached_uid; /* valid only if cached_uname is not empty */
461 static gid_t cached_gid; /* valid only if cached_gname is not empty */
462
463 /* These variables are valid only if nonempty. */
464 static char *cached_no_such_uname;
465 static char *cached_no_such_gname;
466
467 /* These variables are valid only if nonzero. It's not worth optimizing
468 the case for weird systems where 0 is not a valid uid or gid. */
469 static uid_t cached_no_such_uid;
470 static gid_t cached_no_such_gid;
471
472 /* Given UID, find the corresponding UNAME. */
473 void
uid_to_uname(uid_t uid,char ** uname)474 uid_to_uname (uid_t uid, char **uname)
475 {
476 struct passwd *passwd;
477
478 if (uid != 0 && uid == cached_no_such_uid)
479 {
480 *uname = xstrdup ("");
481 return;
482 }
483
484 if (!cached_uname || uid != cached_uid)
485 {
486 passwd = getpwuid (uid);
487 if (passwd)
488 {
489 cached_uid = uid;
490 assign_string (&cached_uname, passwd->pw_name);
491 }
492 else
493 {
494 cached_no_such_uid = uid;
495 *uname = xstrdup ("");
496 return;
497 }
498 }
499 *uname = xstrdup (cached_uname);
500 }
501
502 /* Given GID, find the corresponding GNAME. */
503 void
gid_to_gname(gid_t gid,char ** gname)504 gid_to_gname (gid_t gid, char **gname)
505 {
506 struct group *group;
507
508 if (gid != 0 && gid == cached_no_such_gid)
509 {
510 *gname = xstrdup ("");
511 return;
512 }
513
514 if (!cached_gname || gid != cached_gid)
515 {
516 group = getgrgid (gid);
517 if (group)
518 {
519 cached_gid = gid;
520 assign_string (&cached_gname, group->gr_name);
521 }
522 else
523 {
524 cached_no_such_gid = gid;
525 *gname = xstrdup ("");
526 return;
527 }
528 }
529 *gname = xstrdup (cached_gname);
530 }
531
532 /* Given UNAME, set the corresponding UID and return 1, or else, return 0. */
533 int
uname_to_uid(char const * uname,uid_t * uidp)534 uname_to_uid (char const *uname, uid_t *uidp)
535 {
536 struct passwd *passwd;
537
538 if (cached_no_such_uname
539 && strcmp (uname, cached_no_such_uname) == 0)
540 return 0;
541
542 if (!cached_uname
543 || uname[0] != cached_uname[0]
544 || strcmp (uname, cached_uname) != 0)
545 {
546 passwd = getpwnam (uname);
547 if (passwd)
548 {
549 cached_uid = passwd->pw_uid;
550 assign_string (&cached_uname, passwd->pw_name);
551 }
552 else
553 {
554 assign_string (&cached_no_such_uname, uname);
555 return 0;
556 }
557 }
558 *uidp = cached_uid;
559 return 1;
560 }
561
562 /* Given GNAME, set the corresponding GID and return 1, or else, return 0. */
563 int
gname_to_gid(char const * gname,gid_t * gidp)564 gname_to_gid (char const *gname, gid_t *gidp)
565 {
566 struct group *group;
567
568 if (cached_no_such_gname
569 && strcmp (gname, cached_no_such_gname) == 0)
570 return 0;
571
572 if (!cached_gname
573 || gname[0] != cached_gname[0]
574 || strcmp (gname, cached_gname) != 0)
575 {
576 group = getgrnam (gname);
577 if (group)
578 {
579 cached_gid = group->gr_gid;
580 assign_string (&cached_gname, gname);
581 }
582 else
583 {
584 assign_string (&cached_no_such_gname, gname);
585 return 0;
586 }
587 }
588 *gidp = cached_gid;
589 return 1;
590 }
591
592
593 static struct name *
make_name(const char * file_name)594 make_name (const char *file_name)
595 {
596 struct name *p = xzalloc (sizeof (*p));
597 if (!file_name)
598 file_name = "";
599 p->name = xstrdup (file_name);
600 p->length = strlen (p->name);
601 return p;
602 }
603
604 static void
free_name(struct name * p)605 free_name (struct name *p)
606 {
607 if (p)
608 {
609 free (p->name);
610 free (p->caname);
611 free (p);
612 }
613 }
614
615
616 /* Names from the command call. */
617
618 static struct name *namelist; /* first name in list, if any */
619 static struct name *nametail; /* end of name list */
620
621 /* File name arguments are processed in two stages: first a
622 name element list (see below) is filled, then the names from it
623 are moved into the namelist.
624
625 This awkward process is needed only to implement --same-order option,
626 which is meant to help process large archives on machines with
627 limited memory. With this option on, namelist contains at most one
628 entry, which diminishes the memory consumption.
629
630 However, I very much doubt if we still need this -- Sergey */
631
632 /* A name_list element contains entries of three types: */
633
634 enum nelt_type
635 {
636 NELT_NAME, /* File name */
637 NELT_CHDIR, /* Change directory request */
638 NELT_FILE, /* Read file names from that file */
639 NELT_NOOP, /* No operation */
640 NELT_OPTION /* Filename-selection option */
641 };
642
643 struct name_elt /* A name_array element. */
644 {
645 struct name_elt *next, *prev;
646 enum nelt_type type; /* Element type, see NELT_* constants above */
647 union
648 {
649 const char *name; /* File or directory name */
650 struct /* File, if type == NELT_FILE */
651 {
652 const char *name;/* File name */
653 size_t line; /* Input line number */
654 int term; /* File name terminator in the list */
655 bool verbatim; /* Verbatim handling of file names: no white-space
656 trimming, no option processing */
657 FILE *fp;
658 } file;
659 struct
660 {
661 int option;
662 char const *arg;
663 } opt; /* NELT_OPTION */
664 } v;
665 };
666
667 static struct name_elt *name_head; /* store a list of names */
668
669 /* how many of the entries are file names? */
670 enum files_count filename_args = FILES_NONE;
671
672 static struct name_elt *
name_elt_alloc(void)673 name_elt_alloc (void)
674 {
675 struct name_elt *elt;
676
677 elt = xmalloc (sizeof (*elt));
678 if (!name_head)
679 {
680 name_head = elt;
681 name_head->prev = name_head->next = NULL;
682 name_head->type = NELT_NOOP;
683 elt = xmalloc (sizeof (*elt));
684 }
685
686 elt->prev = name_head->prev;
687 if (name_head->prev)
688 name_head->prev->next = elt;
689 elt->next = name_head;
690 name_head->prev = elt;
691 return elt;
692 }
693
694 static void
name_list_adjust(void)695 name_list_adjust (void)
696 {
697 if (name_head)
698 while (name_head->prev)
699 name_head = name_head->prev;
700 }
701
702 /* For error-reporting purposes, keep a doubly-linked list of unconsumed file
703 selection options. The option is deemed unconsumed unless followed by one
704 or more file/member name arguments. When archive creation is requested,
705 each file selection option encountered is pushed into the list. The list
706 is cleared upon encountering a file name argument.
707
708 If the list is not empty when all arguments have been processed, an error
709 message is issued reporting the options that had no effect.
710
711 For simplicity, only a tail pointer of the list is maintained.
712 */
713
714 struct name_elt *unconsumed_option_tail;
715
716 /* Push an option to the list */
717 static void
unconsumed_option_push(struct name_elt * elt)718 unconsumed_option_push (struct name_elt *elt)
719 {
720 elt->next = NULL;
721 elt->prev = unconsumed_option_tail;
722 if (unconsumed_option_tail)
723 unconsumed_option_tail->next = elt;
724 unconsumed_option_tail = elt;
725 }
726
727 /* Clear the unconsumed option list */
728 static void
unconsumed_option_free(void)729 unconsumed_option_free (void)
730 {
731 while (unconsumed_option_tail)
732 {
733 struct name_elt *elt = unconsumed_option_tail;
734 unconsumed_option_tail = unconsumed_option_tail->prev;
735 free (elt);
736 }
737 }
738
739 /* Report any options that have not been consumed */
740 static void
unconsumed_option_report(void)741 unconsumed_option_report (void)
742 {
743 if (unconsumed_option_tail)
744 {
745 struct name_elt *elt;
746
747 ERROR ((0, 0, _("The following options were used after any non-optional arguments in archive create or update mode. These options are positional and affect only arguments that follow them. Please, rearrange them properly.")));
748
749 elt = unconsumed_option_tail;
750 while (elt->prev)
751 elt = elt->prev;
752
753 while (elt)
754 {
755 switch (elt->type)
756 {
757 case NELT_CHDIR:
758 ERROR ((0, 0, _("-C %s has no effect"), quote (elt->v.name)));
759 break;
760
761 case NELT_OPTION:
762 if (elt->v.opt.arg)
763 ERROR ((0, 0, _("--%s %s has no effect"),
764 file_selection_option_name (elt->v.opt.option),
765 quote (elt->v.opt.arg)));
766 else
767 ERROR ((0, 0, _("--%s has no effect"),
768 file_selection_option_name (elt->v.opt.option)));
769 break;
770
771 default:
772 break;
773 }
774 elt = elt->next;
775 }
776
777 unconsumed_option_free ();
778 }
779 }
780
781 static void
name_list_advance(void)782 name_list_advance (void)
783 {
784 struct name_elt *elt = name_head;
785 name_head = elt->next;
786 if (name_head)
787 name_head->prev = NULL;
788 if (elt->type == NELT_OPTION || elt->type == NELT_CHDIR)
789 {
790 if (subcommand_option == CREATE_SUBCOMMAND
791 || subcommand_option == UPDATE_SUBCOMMAND)
792 unconsumed_option_push (elt);
793 }
794 else
795 {
796 if (elt->type != NELT_NOOP)
797 unconsumed_option_free ();
798 free (elt);
799 }
800 }
801
802 /* Add to name_array the file NAME with fnmatch options MATFLAGS */
803 void
name_add_name(const char * name)804 name_add_name (const char *name)
805 {
806 struct name_elt *ep = name_elt_alloc ();
807
808 ep->type = NELT_NAME;
809 ep->v.name = name;
810
811 switch (filename_args)
812 {
813 case FILES_NONE:
814 filename_args = FILES_ONE;
815 break;
816
817 case FILES_ONE:
818 filename_args = FILES_MANY;
819 break;
820
821 default:
822 break;
823 }
824 }
825
826 static void
name_add_option(int option,const char * arg)827 name_add_option (int option, const char *arg)
828 {
829 struct name_elt *elt = name_elt_alloc ();
830 elt->type = NELT_OPTION;
831 elt->v.opt.option = option;
832 elt->v.opt.arg = arg;
833 }
834
835 /* Add to name_array a chdir request for the directory NAME */
836 static void
name_add_dir(const char * name)837 name_add_dir (const char *name)
838 {
839 struct name_elt *ep = name_elt_alloc ();
840 ep->type = NELT_CHDIR;
841 ep->v.name = name;
842 }
843
844 static void
name_add_file(const char * name)845 name_add_file (const char *name)
846 {
847 struct name_elt *ep = name_elt_alloc ();
848
849 ep->type = NELT_FILE;
850 ep->v.file.name = name;
851 ep->v.file.line = 0;
852 ep->v.file.fp = NULL;
853
854 /* We don't know beforehand how many files are listed.
855 Assume more than one. */
856 filename_args = FILES_MANY;
857 }
858
859 /* Names from external name file. */
860
861 static char *name_buffer; /* buffer to hold the current file name */
862 static size_t name_buffer_length; /* allocated length of name_buffer */
863
864 /* Set up to gather file names for tar. They can either come from a
865 file or were saved from decoding arguments. */
866 void
name_init(void)867 name_init (void)
868 {
869 name_buffer = xmalloc (NAME_FIELD_SIZE + 2);
870 name_buffer_length = NAME_FIELD_SIZE;
871 name_list_adjust ();
872 }
873
874 void
name_term(void)875 name_term (void)
876 {
877 free (name_buffer);
878 }
879
880 /* Prevent recursive inclusion of the same file */
881 struct file_id_list
882 {
883 struct file_id_list *next;
884 ino_t ino;
885 dev_t dev;
886 const char *from_file;
887 };
888
889 static struct file_id_list *file_id_list;
890
891 /* Return the name of the file from which the file names and options
892 are being read.
893 */
894 static const char *
file_list_name(void)895 file_list_name (void)
896 {
897 struct name_elt *elt;
898
899 for (elt = name_head; elt; elt = elt->next)
900 if (elt->type == NELT_FILE && elt->v.file.fp)
901 return elt->v.file.name;
902 return _("command line");
903 }
904
905 static int
add_file_id(const char * filename)906 add_file_id (const char *filename)
907 {
908 struct file_id_list *p;
909 struct stat st;
910 const char *reading_from;
911
912 if (stat (filename, &st))
913 stat_fatal (filename);
914 reading_from = file_list_name ();
915 for (p = file_id_list; p; p = p->next)
916 if (p->ino == st.st_ino && p->dev == st.st_dev)
917 {
918 int oldc = set_char_quoting (NULL, ':', 1);
919 ERROR ((0, 0,
920 _("%s: file list requested from %s already read from %s"),
921 quotearg_n (0, filename),
922 reading_from, p->from_file));
923 set_char_quoting (NULL, ':', oldc);
924 return 1;
925 }
926 p = xmalloc (sizeof *p);
927 p->next = file_id_list;
928 p->ino = st.st_ino;
929 p->dev = st.st_dev;
930 p->from_file = reading_from;
931 file_id_list = p;
932 return 0;
933 }
934
935 /* Chop trailing slashes. */
936 static void
chopslash(char * str)937 chopslash (char *str)
938 {
939 char *p = str + strlen (str) - 1;
940 while (p > str && ISSLASH (*p))
941 *p-- = '\0';
942 }
943
944 enum read_file_list_state /* Result of reading file name from the list file */
945 {
946 file_list_success, /* OK, name read successfully */
947 file_list_end, /* End of list file */
948 file_list_zero, /* Zero separator encountered where it should not */
949 file_list_skip /* Empty (zero-length) entry encountered, skip it */
950 };
951
952 /* Read from FP a sequence of characters up to TERM and put them
953 into STK.
954 */
955 static enum read_file_list_state
read_name_from_file(struct name_elt * ent)956 read_name_from_file (struct name_elt *ent)
957 {
958 int c;
959 size_t counter = 0;
960 FILE *fp = ent->v.file.fp;
961 int term = ent->v.file.term;
962
963 ++ent->v.file.line;
964 for (c = getc (fp); c != EOF && c != term; c = getc (fp))
965 {
966 if (counter == name_buffer_length)
967 name_buffer = x2realloc (name_buffer, &name_buffer_length);
968 name_buffer[counter++] = c;
969 if (c == 0)
970 {
971 /* We have read a zero separator. The file possibly is
972 zero-separated */
973 return file_list_zero;
974 }
975 }
976
977 if (counter == 0 && c != EOF)
978 return file_list_skip;
979
980 if (counter == name_buffer_length)
981 name_buffer = x2realloc (name_buffer, &name_buffer_length);
982 name_buffer[counter] = 0;
983 chopslash (name_buffer);
984 return (counter == 0 && c == EOF) ? file_list_end : file_list_success;
985 }
986
987 static int
handle_option(const char * str,struct name_elt const * ent)988 handle_option (const char *str, struct name_elt const *ent)
989 {
990 struct wordsplit ws;
991 int i;
992 struct option_locus loc;
993
994 while (*str && isspace (*str))
995 ++str;
996 if (*str != '-')
997 return 1;
998
999 ws.ws_offs = 1;
1000 if (wordsplit (str, &ws, WRDSF_DEFFLAGS|WRDSF_DOOFFS))
1001 FATAL_ERROR ((0, 0, _("cannot split string '%s': %s"),
1002 str, wordsplit_strerror (&ws)));
1003 ws.ws_wordv[0] = (char *) program_name;
1004 loc.source = OPTS_FILE;
1005 loc.name = ent->v.file.name;
1006 loc.line = ent->v.file.line;
1007 more_options (ws.ws_wordc+ws.ws_offs, ws.ws_wordv, &loc);
1008 for (i = 0; i < ws.ws_wordc+ws.ws_offs; i++)
1009 ws.ws_wordv[i] = NULL;
1010
1011 wordsplit_free (&ws);
1012 return 0;
1013 }
1014
1015 static int
read_next_name(struct name_elt * ent,struct name_elt * ret)1016 read_next_name (struct name_elt *ent, struct name_elt *ret)
1017 {
1018 if (!ent->v.file.fp)
1019 {
1020 if (!strcmp (ent->v.file.name, "-"))
1021 {
1022 request_stdin ("-T");
1023 ent->v.file.fp = stdin;
1024 }
1025 else
1026 {
1027 if (add_file_id (ent->v.file.name))
1028 {
1029 name_list_advance ();
1030 return 1;
1031 }
1032 if ((ent->v.file.fp = fopen (ent->v.file.name, "r")) == NULL)
1033 open_fatal (ent->v.file.name);
1034 }
1035 ent->v.file.term = filename_terminator;
1036 ent->v.file.verbatim = verbatim_files_from_option;
1037 }
1038
1039 while (1)
1040 {
1041 switch (read_name_from_file (ent))
1042 {
1043 case file_list_skip:
1044 continue;
1045
1046 case file_list_zero:
1047 WARNOPT (WARN_FILENAME_WITH_NULS,
1048 (0, 0, N_("%s: file name read contains nul character"),
1049 quotearg_colon (ent->v.file.name)));
1050 ent->v.file.term = 0;
1051 FALLTHROUGH;
1052 case file_list_success:
1053 if (!ent->v.file.verbatim)
1054 {
1055 if (unquote_option)
1056 unquote_string (name_buffer);
1057 if (handle_option (name_buffer, ent) == 0)
1058 {
1059 name_list_adjust ();
1060 return 1;
1061 }
1062 }
1063 ret->type = NELT_NAME;
1064 ret->v.name = name_buffer;
1065 return 0;
1066
1067 case file_list_end:
1068 if (strcmp (ent->v.file.name, "-"))
1069 fclose (ent->v.file.fp);
1070 ent->v.file.fp = NULL;
1071 name_list_advance ();
1072 return 1;
1073 }
1074 }
1075 }
1076
1077 static void
copy_name(struct name_elt * ep)1078 copy_name (struct name_elt *ep)
1079 {
1080 const char *source;
1081 size_t source_len;
1082
1083 source = ep->v.name;
1084 source_len = strlen (source);
1085 while (name_buffer_length <= source_len)
1086 name_buffer = x2realloc(name_buffer, &name_buffer_length);
1087 strcpy (name_buffer, source);
1088 chopslash (name_buffer);
1089 }
1090
1091
1092 /* Get the next NELT_NAME element from name_array. Result is in
1093 static storage and can't be relied upon across two calls.
1094
1095 If CHANGE_DIRS is true, treat any entries of type NELT_CHDIR as
1096 the request to change to the given directory.
1097
1098 */
1099 static struct name_elt *
name_next_elt(int change_dirs)1100 name_next_elt (int change_dirs)
1101 {
1102 static struct name_elt entry;
1103 struct name_elt *ep;
1104
1105 while ((ep = name_head) != NULL)
1106 {
1107 switch (ep->type)
1108 {
1109 case NELT_NOOP:
1110 name_list_advance ();
1111 break;
1112
1113 case NELT_FILE:
1114 if (read_next_name (ep, &entry) == 0)
1115 return &entry;
1116 continue;
1117
1118 case NELT_CHDIR:
1119 if (change_dirs)
1120 {
1121 chdir_do (chdir_arg (xstrdup (ep->v.name)));
1122 name_list_advance ();
1123 break;
1124 }
1125 FALLTHROUGH;
1126 case NELT_NAME:
1127 copy_name (ep);
1128 if (unquote_option)
1129 unquote_string (name_buffer);
1130 entry.type = ep->type;
1131 entry.v.name = name_buffer;
1132 name_list_advance ();
1133 return &entry;
1134
1135 case NELT_OPTION:
1136 handle_file_selection_option (ep->v.opt.option, ep->v.opt.arg);
1137 name_list_advance ();
1138 continue;
1139 }
1140 }
1141
1142 unconsumed_option_report ();
1143
1144 return NULL;
1145 }
1146
1147 const char *
name_next(int change_dirs)1148 name_next (int change_dirs)
1149 {
1150 struct name_elt *nelt = name_next_elt (change_dirs);
1151 return nelt ? nelt->v.name : NULL;
1152 }
1153
1154 /* Gather names in a list for scanning. Could hash them later if we
1155 really care.
1156
1157 If the names are already sorted to match the archive, we just read
1158 them one by one. name_gather reads the first one, and it is called
1159 by name_match as appropriate to read the next ones. At EOF, the
1160 last name read is just left in the buffer. This option lets users
1161 of small machines extract an arbitrary number of files by doing
1162 "tar t" and editing down the list of files. */
1163
1164 void
name_gather(void)1165 name_gather (void)
1166 {
1167 /* Buffer able to hold a single name. */
1168 static struct name *buffer = NULL;
1169
1170 struct name_elt *ep;
1171
1172 if (same_order_option)
1173 {
1174 static int change_dir;
1175
1176 while ((ep = name_next_elt (0)) && ep->type == NELT_CHDIR)
1177 change_dir = chdir_arg (xstrdup (ep->v.name));
1178
1179 if (ep)
1180 {
1181 free_name (buffer);
1182 buffer = make_name (ep->v.name);
1183 buffer->change_dir = change_dir;
1184 buffer->next = 0;
1185 buffer->found_count = 0;
1186 buffer->matching_flags = INCLUDE_OPTIONS;
1187 buffer->directory = NULL;
1188 buffer->parent = NULL;
1189 buffer->cmdline = true;
1190
1191 namelist = nametail = buffer;
1192 }
1193 else if (change_dir)
1194 addname (0, change_dir, false, NULL);
1195 }
1196 else
1197 {
1198 /* Non sorted names -- read them all in. */
1199 int change_dir = 0;
1200
1201 for (;;)
1202 {
1203 int change_dir0 = change_dir;
1204 while ((ep = name_next_elt (0)) && ep->type == NELT_CHDIR)
1205 change_dir = chdir_arg (xstrdup (ep->v.name));
1206
1207 if (ep)
1208 addname (ep->v.name, change_dir, true, NULL);
1209 else
1210 {
1211 if (change_dir != change_dir0)
1212 addname (NULL, change_dir, false, NULL);
1213 break;
1214 }
1215 }
1216 }
1217 }
1218
1219 /* Add a name to the namelist. */
1220 struct name *
addname(char const * string,int change_dir,bool cmdline,struct name * parent)1221 addname (char const *string, int change_dir, bool cmdline, struct name *parent)
1222 {
1223 struct name *name = make_name (string);
1224
1225 name->prev = nametail;
1226 name->next = NULL;
1227 name->found_count = 0;
1228 name->matching_flags = INCLUDE_OPTIONS;
1229 name->change_dir = change_dir;
1230 name->directory = NULL;
1231 name->parent = parent;
1232 name->cmdline = cmdline;
1233
1234 if (nametail)
1235 nametail->next = name;
1236 else
1237 namelist = name;
1238 nametail = name;
1239 return name;
1240 }
1241
1242 void
add_starting_file(char const * file_name)1243 add_starting_file (char const *file_name)
1244 {
1245 struct name *name = make_name (file_name);
1246
1247 if (starting_file_option)
1248 {
1249 struct name *head = namelist;
1250 remname (head);
1251 free_name (head);
1252 }
1253
1254 name->prev = NULL;
1255 name->next = namelist;
1256 namelist = name;
1257 if (!nametail)
1258 nametail = namelist;
1259
1260 name->found_count = 0;
1261 name->matching_flags = INCLUDE_OPTIONS;
1262 name->change_dir = 0;
1263 name->directory = NULL;
1264 name->parent = NULL;
1265 name->cmdline = true;
1266
1267 starting_file_option = true;
1268 }
1269
1270 /* Find a match for FILE_NAME (whose string length is LENGTH) in the name
1271 list. */
1272 static struct name *
namelist_match(char const * file_name,size_t length)1273 namelist_match (char const *file_name, size_t length)
1274 {
1275 struct name *p;
1276
1277 for (p = namelist; p; p = p->next)
1278 {
1279 if (p->name[0]
1280 && exclude_fnmatch (p->name, file_name, p->matching_flags))
1281 return p;
1282 }
1283
1284 return NULL;
1285 }
1286
1287 void
remname(struct name * name)1288 remname (struct name *name)
1289 {
1290 struct name *p;
1291
1292 if ((p = name->prev) != NULL)
1293 p->next = name->next;
1294 else
1295 namelist = name->next;
1296
1297 if ((p = name->next) != NULL)
1298 p->prev = name->prev;
1299 else
1300 nametail = name->prev;
1301 }
1302
1303 /* Return true if and only if name FILE_NAME (from an archive) matches any
1304 name from the namelist. */
1305 bool
name_match(const char * file_name)1306 name_match (const char *file_name)
1307 {
1308 size_t length = strlen (file_name);
1309
1310 while (1)
1311 {
1312 struct name *cursor = namelist;
1313
1314 if (!cursor)
1315 return true;
1316
1317 if (cursor->name[0] == 0)
1318 {
1319 chdir_do (cursor->change_dir);
1320 namelist = NULL;
1321 nametail = NULL;
1322 return true;
1323 }
1324
1325 cursor = namelist_match (file_name, length);
1326 if (starting_file_option)
1327 {
1328 /* If starting_file_option is set, the head of the list is the name
1329 of the member to start extraction from. Skip the match unless it
1330 is head. */
1331 if (cursor == namelist)
1332 starting_file_option = false;
1333 else
1334 cursor = NULL;
1335 }
1336 if (cursor)
1337 {
1338 if (!(ISSLASH (file_name[cursor->length]) && recursion_option)
1339 || cursor->found_count == 0)
1340 cursor->found_count++; /* remember it matched */
1341 chdir_do (cursor->change_dir);
1342 /* We got a match. */
1343 return ISFOUND (cursor);
1344 }
1345
1346 /* Filename from archive not found in namelist. If we have the whole
1347 namelist here, just return 0. Otherwise, read the next name in and
1348 compare it. If this was the last name, namelist->found_count will
1349 remain on. If not, we loop to compare the newly read name. */
1350
1351 if (same_order_option && namelist->found_count)
1352 {
1353 name_gather (); /* read one more */
1354 if (namelist->found_count)
1355 return false;
1356 }
1357 else
1358 return false;
1359 }
1360 }
1361
1362 /* Returns true if all names from the namelist were processed.
1363 P is the stat_info of the most recently processed entry.
1364 The decision is postponed until the next entry is read if:
1365
1366 1) P ended with a slash (i.e. it was a directory)
1367 2) P matches any entry from the namelist *and* represents a subdirectory
1368 or a file lying under this entry (in the terms of directory structure).
1369
1370 This is necessary to handle contents of directories. */
1371 bool
all_names_found(struct tar_stat_info * p)1372 all_names_found (struct tar_stat_info *p)
1373 {
1374 struct name const *cursor;
1375 size_t len;
1376
1377 if (!p->file_name || occurrence_option == 0 || p->had_trailing_slash)
1378 return false;
1379 len = strlen (p->file_name);
1380 for (cursor = namelist; cursor; cursor = cursor->next)
1381 {
1382 if ((cursor->name[0] && !WASFOUND (cursor))
1383 || (len >= cursor->length && ISSLASH (p->file_name[cursor->length])))
1384 return false;
1385 }
1386 return true;
1387 }
1388
1389 static int
regex_usage_warning(const char * name)1390 regex_usage_warning (const char *name)
1391 {
1392 static int warned_once = 0;
1393
1394 /* Warn about implicit use of the wildcards in command line arguments.
1395 (Default for tar prior to 1.15.91, but changed afterwards) */
1396 if (wildcards == default_wildcards
1397 && fnmatch_pattern_has_wildcards (name, 0))
1398 {
1399 warned_once = 1;
1400 WARN ((0, 0,
1401 _("Pattern matching characters used in file names")));
1402 WARN ((0, 0,
1403 _("Use --wildcards to enable pattern matching,"
1404 " or --no-wildcards to suppress this warning")));
1405 }
1406 return warned_once;
1407 }
1408
1409 /* Print the names of things in the namelist that were not matched. */
1410 void
names_notfound(void)1411 names_notfound (void)
1412 {
1413 struct name const *cursor;
1414
1415 for (cursor = namelist; cursor; cursor = cursor->next)
1416 if (!WASFOUND (cursor) && cursor->name[0])
1417 {
1418 regex_usage_warning (cursor->name);
1419 ERROR ((0, 0,
1420 (cursor->found_count == 0) ?
1421 _("%s: Not found in archive") :
1422 _("%s: Required occurrence not found in archive"),
1423 quotearg_colon (cursor->name)));
1424 }
1425
1426 /* Don't bother freeing the name list; we're about to exit. */
1427 namelist = NULL;
1428 nametail = NULL;
1429
1430 if (same_order_option)
1431 {
1432 const char *name;
1433
1434 while ((name = name_next (1)) != NULL)
1435 {
1436 regex_usage_warning (name);
1437 ERROR ((0, 0, _("%s: Not found in archive"),
1438 quotearg_colon (name)));
1439 }
1440 }
1441 }
1442
1443 void
label_notfound(void)1444 label_notfound (void)
1445 {
1446 struct name const *cursor;
1447
1448 if (!namelist)
1449 return;
1450
1451 for (cursor = namelist; cursor; cursor = cursor->next)
1452 if (WASFOUND (cursor))
1453 return;
1454
1455 if (verbose_option)
1456 error (0, 0, _("Archive label mismatch"));
1457 set_exit_status (TAREXIT_DIFFERS);
1458
1459 for (cursor = namelist; cursor; cursor = cursor->next)
1460 {
1461 if (regex_usage_warning (cursor->name))
1462 break;
1463 }
1464
1465 /* Don't bother freeing the name list; we're about to exit. */
1466 namelist = NULL;
1467 nametail = NULL;
1468
1469 if (same_order_option)
1470 {
1471 const char *name;
1472
1473 while ((name = name_next (1)) != NULL
1474 && regex_usage_warning (name) == 0)
1475 ;
1476 }
1477 }
1478
1479 /* Sorting name lists. */
1480
1481 /* Sort *singly* linked LIST of names, of given LENGTH, using COMPARE
1482 to order names. Return the sorted list. Note that after calling
1483 this function, the 'prev' links in list elements are messed up.
1484
1485 Apart from the type 'struct name' and the definition of SUCCESSOR,
1486 this is a generic list-sorting function, but it's too painful to
1487 make it both generic and portable
1488 in C. */
1489
1490 static struct name *
merge_sort_sll(struct name * list,int length,int (* compare)(struct name const *,struct name const *))1491 merge_sort_sll (struct name *list, int length,
1492 int (*compare) (struct name const*, struct name const*))
1493 {
1494 struct name *first_list;
1495 struct name *second_list;
1496 int first_length;
1497 int second_length;
1498 struct name *result;
1499 struct name **merge_point;
1500 struct name *cursor;
1501 int counter;
1502
1503 # define SUCCESSOR(name) ((name)->next)
1504
1505 if (length == 1)
1506 return list;
1507
1508 if (length == 2)
1509 {
1510 if ((*compare) (list, SUCCESSOR (list)) > 0)
1511 {
1512 result = SUCCESSOR (list);
1513 SUCCESSOR (result) = list;
1514 SUCCESSOR (list) = 0;
1515 return result;
1516 }
1517 return list;
1518 }
1519
1520 first_list = list;
1521 first_length = (length + 1) / 2;
1522 second_length = length / 2;
1523 for (cursor = list, counter = first_length - 1;
1524 counter;
1525 cursor = SUCCESSOR (cursor), counter--)
1526 continue;
1527 second_list = SUCCESSOR (cursor);
1528 SUCCESSOR (cursor) = 0;
1529
1530 first_list = merge_sort_sll (first_list, first_length, compare);
1531 second_list = merge_sort_sll (second_list, second_length, compare);
1532
1533 merge_point = &result;
1534 while (first_list && second_list)
1535 if ((*compare) (first_list, second_list) < 0)
1536 {
1537 cursor = SUCCESSOR (first_list);
1538 *merge_point = first_list;
1539 merge_point = &SUCCESSOR (first_list);
1540 first_list = cursor;
1541 }
1542 else
1543 {
1544 cursor = SUCCESSOR (second_list);
1545 *merge_point = second_list;
1546 merge_point = &SUCCESSOR (second_list);
1547 second_list = cursor;
1548 }
1549 if (first_list)
1550 *merge_point = first_list;
1551 else
1552 *merge_point = second_list;
1553
1554 return result;
1555
1556 #undef SUCCESSOR
1557 }
1558
1559 /* Sort doubly linked LIST of names, of given LENGTH, using COMPARE
1560 to order names. Return the sorted list. */
1561 static struct name *
merge_sort(struct name * list,int length,int (* compare)(struct name const *,struct name const *))1562 merge_sort (struct name *list, int length,
1563 int (*compare) (struct name const*, struct name const*))
1564 {
1565 struct name *head, *p, *prev;
1566 head = merge_sort_sll (list, length, compare);
1567 /* Fixup prev pointers */
1568 for (prev = NULL, p = head; p; prev = p, p = p->next)
1569 p->prev = prev;
1570 return head;
1571 }
1572
1573 /* A comparison function for sorting names. Put found names last;
1574 break ties by string comparison. */
1575
1576 static int
compare_names_found(struct name const * n1,struct name const * n2)1577 compare_names_found (struct name const *n1, struct name const *n2)
1578 {
1579 int found_diff = WASFOUND (n2) - WASFOUND (n1);
1580 return found_diff ? found_diff : strcmp (n1->name, n2->name);
1581 }
1582
1583 /* Simple comparison by names. */
1584 static int
compare_names(struct name const * n1,struct name const * n2)1585 compare_names (struct name const *n1, struct name const *n2)
1586 {
1587 return strcmp (n1->name, n2->name);
1588 }
1589
1590
1591 /* Add all the dirs under ST to the namelist NAME, descending the
1592 directory hierarchy recursively. */
1593
1594 static void
add_hierarchy_to_namelist(struct tar_stat_info * st,struct name * name)1595 add_hierarchy_to_namelist (struct tar_stat_info *st, struct name *name)
1596 {
1597 const char *buffer;
1598
1599 name->directory = scan_directory (st);
1600 buffer = directory_contents (name->directory);
1601 if (buffer)
1602 {
1603 struct name *child_head = NULL, *child_tail = NULL;
1604 size_t name_length = name->length;
1605 size_t allocated_length = (name_length >= NAME_FIELD_SIZE
1606 ? name_length + NAME_FIELD_SIZE
1607 : NAME_FIELD_SIZE) + 2;
1608 char *namebuf = xmalloc (allocated_length);
1609 const char *string;
1610 size_t string_length;
1611 int change_dir = name->change_dir;
1612
1613 strcpy (namebuf, name->name);
1614 if (! ISSLASH (namebuf[name_length - 1]))
1615 {
1616 namebuf[name_length++] = '/';
1617 namebuf[name_length] = '\0';
1618 }
1619
1620 for (string = buffer; *string; string += string_length + 1)
1621 {
1622 string_length = strlen (string);
1623 if (*string == 'D')
1624 {
1625 struct name *np;
1626 struct tar_stat_info subdir;
1627 int subfd;
1628
1629 /* need to have at least string_length bytes above the
1630 name_length, this includes the trailing null character */
1631 while (allocated_length < name_length + string_length)
1632 namebuf = x2realloc (namebuf, &allocated_length);
1633 strcpy (namebuf + name_length, string + 1);
1634 np = addname (namebuf, change_dir, false, name);
1635 if (!child_head)
1636 child_head = np;
1637 else
1638 child_tail->sibling = np;
1639 child_tail = np;
1640
1641 tar_stat_init (&subdir);
1642 subdir.parent = st;
1643 if (st->fd < 0)
1644 {
1645 subfd = -1;
1646 errno = - st->fd;
1647 }
1648 else
1649 subfd = subfile_open (st, string + 1,
1650 open_read_flags | O_DIRECTORY);
1651 if (subfd < 0)
1652 open_diag (namebuf);
1653 else
1654 {
1655 subdir.fd = subfd;
1656 if (fstat (subfd, &subdir.stat) != 0)
1657 stat_diag (namebuf);
1658 else if (! (O_DIRECTORY || S_ISDIR (subdir.stat.st_mode)))
1659 {
1660 errno = ENOTDIR;
1661 open_diag (namebuf);
1662 }
1663 else
1664 {
1665 subdir.orig_file_name = xstrdup (namebuf);
1666 add_hierarchy_to_namelist (&subdir, np);
1667 restore_parent_fd (&subdir);
1668 }
1669 }
1670
1671 tar_stat_destroy (&subdir);
1672 }
1673 }
1674
1675 free (namebuf);
1676 name->child = child_head;
1677 }
1678 }
1679
1680 /* Auxiliary functions for hashed table of struct name's. */
1681
1682 static size_t
name_hash(void const * entry,size_t n_buckets)1683 name_hash (void const *entry, size_t n_buckets)
1684 {
1685 struct name const *name = entry;
1686 return hash_string (name->caname, n_buckets);
1687 }
1688
1689 /* Compare two directories for equality of their names. */
1690 static bool
name_compare(void const * entry1,void const * entry2)1691 name_compare (void const *entry1, void const *entry2)
1692 {
1693 struct name const *name1 = entry1;
1694 struct name const *name2 = entry2;
1695 return strcmp (name1->caname, name2->caname) == 0;
1696 }
1697
1698
1699 /* Rebase 'name' member of CHILD and all its siblings to
1700 the new PARENT. */
1701 static void
rebase_child_list(struct name * child,struct name * parent)1702 rebase_child_list (struct name *child, struct name *parent)
1703 {
1704 size_t old_prefix_len = child->parent->length;
1705 size_t new_prefix_len = parent->length;
1706 char *new_prefix = parent->name;
1707
1708 for (; child; child = child->sibling)
1709 {
1710 size_t size = child->length - old_prefix_len + new_prefix_len;
1711 char *newp = xmalloc (size + 1);
1712 strcpy (newp, new_prefix);
1713 strcat (newp, child->name + old_prefix_len);
1714 free (child->name);
1715 child->name = newp;
1716 child->length = size;
1717
1718 rebase_directory (child->directory,
1719 child->parent->name, old_prefix_len,
1720 new_prefix, new_prefix_len);
1721 }
1722 }
1723
1724 /* Collect all the names from argv[] (or whatever), expand them into a
1725 directory tree, and sort them. This gets only subdirectories, not
1726 all files. */
1727
1728 void
collect_and_sort_names(void)1729 collect_and_sort_names (void)
1730 {
1731 struct name *name;
1732 struct name *next_name, *prev_name = NULL;
1733 int num_names;
1734 Hash_table *nametab;
1735
1736 name_gather ();
1737
1738 if (!namelist)
1739 addname (".", 0, false, NULL);
1740
1741 if (listed_incremental_option)
1742 {
1743 switch (chdir_count ())
1744 {
1745 case 0:
1746 break;
1747
1748 case 1:
1749 if (namelist->change_dir == 0)
1750 USAGE_ERROR ((0, 0,
1751 _("Using -C option inside file list is not "
1752 "allowed with --listed-incremental")));
1753 break;
1754
1755 default:
1756 USAGE_ERROR ((0, 0,
1757 _("Only one -C option is allowed with "
1758 "--listed-incremental")));
1759 }
1760
1761 read_directory_file ();
1762 }
1763
1764 num_names = 0;
1765 for (name = namelist; name; name = name->next, num_names++)
1766 {
1767 struct tar_stat_info st;
1768
1769 if (name->found_count || name->directory)
1770 continue;
1771 if (name->matching_flags & EXCLUDE_WILDCARDS)
1772 /* NOTE: EXCLUDE_ANCHORED is not relevant here */
1773 /* FIXME: just skip regexps for now */
1774 continue;
1775 chdir_do (name->change_dir);
1776
1777 if (name->name[0] == 0)
1778 continue;
1779
1780 tar_stat_init (&st);
1781
1782 if (deref_stat (name->name, &st.stat) != 0)
1783 {
1784 stat_diag (name->name);
1785 continue;
1786 }
1787 if (S_ISDIR (st.stat.st_mode))
1788 {
1789 int dir_fd = openat (chdir_fd, name->name,
1790 open_read_flags | O_DIRECTORY);
1791 if (dir_fd < 0)
1792 open_diag (name->name);
1793 else
1794 {
1795 st.fd = dir_fd;
1796 if (fstat (dir_fd, &st.stat) != 0)
1797 stat_diag (name->name);
1798 else if (O_DIRECTORY || S_ISDIR (st.stat.st_mode))
1799 {
1800 st.orig_file_name = xstrdup (name->name);
1801 name->found_count++;
1802 add_hierarchy_to_namelist (&st, name);
1803 }
1804 else
1805 {
1806 errno = ENOTDIR;
1807 open_diag (name->name);
1808 }
1809 }
1810 }
1811
1812 tar_stat_destroy (&st);
1813 }
1814
1815 namelist = merge_sort (namelist, num_names, compare_names);
1816
1817 num_names = 0;
1818 nametab = hash_initialize (0, 0, name_hash, name_compare, NULL);
1819 for (name = namelist; name; name = next_name)
1820 {
1821 next_name = name->next;
1822 name->caname = normalize_filename (name->change_dir, name->name);
1823 if (prev_name)
1824 {
1825 struct name *p = hash_lookup (nametab, name);
1826 if (p)
1827 {
1828 /* Keep the one listed in the command line */
1829 if (!name->parent)
1830 {
1831 if (p->child)
1832 rebase_child_list (p->child, name);
1833 hash_remove (nametab, name);
1834 /* FIXME: remove_directory (p->caname); ? */
1835 remname (p);
1836 free_name (p);
1837 num_names--;
1838 }
1839 else
1840 {
1841 if (name->child)
1842 rebase_child_list (name->child, p);
1843 /* FIXME: remove_directory (name->caname); ? */
1844 remname (name);
1845 free_name (name);
1846 continue;
1847 }
1848 }
1849 }
1850 name->found_count = 0;
1851 if (!hash_insert (nametab, name))
1852 xalloc_die ();
1853 prev_name = name;
1854 num_names++;
1855 }
1856 nametail = prev_name;
1857 hash_free (nametab);
1858
1859 namelist = merge_sort (namelist, num_names, compare_names_found);
1860
1861 if (listed_incremental_option)
1862 {
1863 for (name = namelist; name && name->name[0] == 0; name = name->next)
1864 ;
1865 if (name)
1866 append_incremental_renames (name->directory);
1867 }
1868 }
1869
1870 /* This is like name_match, except that
1871 1. It returns a pointer to the name it matched, and doesn't set FOUND
1872 in structure. The caller will have to do that if it wants to.
1873 2. If the namelist is empty, it returns null, unlike name_match, which
1874 returns TRUE. */
1875 struct name *
name_scan(const char * file_name)1876 name_scan (const char *file_name)
1877 {
1878 size_t length = strlen (file_name);
1879
1880 while (1)
1881 {
1882 struct name *cursor = namelist_match (file_name, length);
1883 if (cursor)
1884 return cursor;
1885
1886 /* Filename from archive not found in namelist. If we have the whole
1887 namelist here, just return 0. Otherwise, read the next name in and
1888 compare it. If this was the last name, namelist->found_count will
1889 remain on. If not, we loop to compare the newly read name. */
1890
1891 if (same_order_option && namelist && namelist->found_count)
1892 {
1893 name_gather (); /* read one more */
1894 if (namelist->found_count)
1895 return 0;
1896 }
1897 else
1898 return 0;
1899 }
1900 }
1901
1902 /* This returns a name from the namelist which doesn't have ->found
1903 set. It sets ->found before returning, so successive calls will
1904 find and return all the non-found names in the namelist. */
1905 struct name *gnu_list_name;
1906
1907 struct name const *
name_from_list(void)1908 name_from_list (void)
1909 {
1910 if (!gnu_list_name)
1911 gnu_list_name = namelist;
1912 while (gnu_list_name
1913 && (gnu_list_name->found_count || gnu_list_name->name[0] == 0))
1914 gnu_list_name = gnu_list_name->next;
1915 if (gnu_list_name)
1916 {
1917 gnu_list_name->found_count++;
1918 chdir_do (gnu_list_name->change_dir);
1919 return gnu_list_name;
1920 }
1921 return NULL;
1922 }
1923
1924 void
blank_name_list(void)1925 blank_name_list (void)
1926 {
1927 struct name *name;
1928
1929 gnu_list_name = 0;
1930 for (name = namelist; name; name = name->next)
1931 name->found_count = 0;
1932 }
1933
1934 /* Yield a newly allocated file name consisting of DIR_NAME concatenated to
1935 NAME, with an intervening slash if DIR_NAME does not already end in one. */
1936 char *
make_file_name(const char * directory_name,const char * name)1937 make_file_name (const char *directory_name, const char *name)
1938 {
1939 size_t dirlen = strlen (directory_name);
1940 size_t namelen = strlen (name) + 1;
1941 int slash = dirlen && ! ISSLASH (directory_name[dirlen - 1]);
1942 char *buffer = xmalloc (dirlen + slash + namelen);
1943 memcpy (buffer, directory_name, dirlen);
1944 buffer[dirlen] = '/';
1945 memcpy (buffer + dirlen + slash, name, namelen);
1946 return buffer;
1947 }
1948
1949
1950
1951 /* Return the size of the prefix of FILE_NAME that is removed after
1952 stripping NUM leading file name components. NUM must be
1953 positive. */
1954
1955 size_t
stripped_prefix_len(char const * file_name,size_t num)1956 stripped_prefix_len (char const *file_name, size_t num)
1957 {
1958 char const *p = file_name + FILE_SYSTEM_PREFIX_LEN (file_name);
1959 while (ISSLASH (*p))
1960 p++;
1961 while (*p)
1962 {
1963 bool slash = ISSLASH (*p);
1964 p++;
1965 if (slash)
1966 {
1967 if (--num == 0)
1968 return p - file_name;
1969 while (ISSLASH (*p))
1970 p++;
1971 }
1972 }
1973 return -1;
1974 }
1975
1976 /* Return nonzero if NAME contains ".." as a file name component. */
1977 bool
contains_dot_dot(char const * name)1978 contains_dot_dot (char const *name)
1979 {
1980 char const *p = name + FILE_SYSTEM_PREFIX_LEN (name);
1981
1982 for (;; p++)
1983 {
1984 if (p[0] == '.' && p[1] == '.' && (ISSLASH (p[2]) || !p[2]))
1985 return 1;
1986
1987 while (! ISSLASH (*p))
1988 {
1989 if (! *p++)
1990 return 0;
1991 }
1992 }
1993 }
1994