440 |
buffer->change_dir = change_dir; |
buffer->change_dir = change_dir; |
441 |
strcpy (buffer->name, name); |
strcpy (buffer->name, name); |
442 |
buffer->next = 0; |
buffer->next = 0; |
443 |
buffer->found = 0; |
buffer->found_count = 0; |
444 |
|
|
445 |
namelist = buffer; |
namelist = buffer; |
446 |
nametail = &namelist->next; |
nametail = &namelist->next; |
497 |
|
|
498 |
name->next = 0; |
name->next = 0; |
499 |
name->length = length; |
name->length = length; |
500 |
name->found = 0; |
name->found_count = 0; |
501 |
name->regexp = 0; /* assume not a regular expression */ |
name->regexp = 0; /* assume not a regular expression */ |
502 |
name->firstch = 1; /* assume first char is literal */ |
name->firstch = 1; /* assume first char is literal */ |
503 |
name->change_dir = change_dir; |
name->change_dir = change_dir; |
566 |
cursor = namelist_match (path, length); |
cursor = namelist_match (path, length); |
567 |
if (cursor) |
if (cursor) |
568 |
{ |
{ |
569 |
cursor->found = 1; /* remember it matched */ |
if (!(ISSLASH (path[cursor->length]) && recursion_option) |
570 |
|
|| cursor->found_count == 0) |
571 |
|
cursor->found_count++; /* remember it matched */ |
572 |
if (starting_file_option) |
if (starting_file_option) |
573 |
{ |
{ |
574 |
free (namelist); |
free (namelist); |
578 |
chdir_do (cursor->change_dir); |
chdir_do (cursor->change_dir); |
579 |
|
|
580 |
/* We got a match. */ |
/* We got a match. */ |
581 |
return 1; |
return ISFOUND (cursor); |
582 |
} |
} |
583 |
|
|
584 |
/* Filename from archive not found in namelist. If we have the whole |
/* Filename from archive not found in namelist. If we have the whole |
585 |
namelist here, just return 0. Otherwise, read the next name in and |
namelist here, just return 0. Otherwise, read the next name in and |
586 |
compare it. If this was the last name, namelist->found will remain |
compare it. If this was the last name, namelist->found_count will |
587 |
on. If not, we loop to compare the newly read name. */ |
remain on. If not, we loop to compare the newly read name. */ |
588 |
|
|
589 |
if (same_order_option && namelist->found) |
if (same_order_option && namelist->found_count) |
590 |
{ |
{ |
591 |
name_gather (); /* read one more */ |
name_gather (); /* read one more */ |
592 |
if (namelist->found) |
if (namelist->found_count) |
593 |
return 0; |
return 0; |
594 |
} |
} |
595 |
else |
else |
597 |
} |
} |
598 |
} |
} |
599 |
|
|
600 |
/* Returns true if all names from the namelist were processed */ |
/* Returns true if all names from the namelist were processed. |
601 |
|
P is the stat_info of the most recently processed entry. |
602 |
|
The decision is postponed until the next entry is read if: |
603 |
|
|
604 |
|
1) P ended with a slash (i.e. it was a directory) |
605 |
|
2) P matches any entry from the namelist *and* represents a subdirectory |
606 |
|
or a file lying under this entry (in the terms of directory structure). |
607 |
|
|
608 |
|
This is necessary to handle contents of directories. */ |
609 |
bool |
bool |
610 |
names_done () |
all_names_found (struct tar_stat_info *p) |
611 |
{ |
{ |
612 |
struct name const *cursor; |
struct name const *cursor; |
613 |
|
size_t len = strlen (p->file_name); |
614 |
|
if (occurrence_option == 0 || p->had_trailing_slash) |
615 |
|
return false; |
616 |
for (cursor = namelist; cursor; cursor = cursor->next) |
for (cursor = namelist; cursor; cursor = cursor->next) |
617 |
if (cursor->regexp || (!cursor->found && !cursor->fake)) |
{ |
618 |
return false; |
if (cursor->regexp |
619 |
|
|| (!WASFOUND(cursor) && !cursor->fake) |
620 |
|
|| (len >= cursor->length && ISSLASH (p->file_name[cursor->length]))) |
621 |
|
return false; |
622 |
|
} |
623 |
return true; |
return true; |
624 |
} |
} |
625 |
|
|
630 |
struct name const *cursor; |
struct name const *cursor; |
631 |
|
|
632 |
for (cursor = namelist; cursor; cursor = cursor->next) |
for (cursor = namelist; cursor; cursor = cursor->next) |
633 |
if (!cursor->found && !cursor->fake) |
if (!WASFOUND(cursor) && !cursor->fake) |
634 |
ERROR ((0, 0, _("%s: Not found in archive"), |
{ |
635 |
quotearg_colon (cursor->name))); |
if (cursor->found_count == 0) |
636 |
|
ERROR ((0, 0, _("%s: Not found in archive"), |
637 |
|
quotearg_colon (cursor->name))); |
638 |
|
else |
639 |
|
ERROR ((0, 0, _("%s: Required occurence not found in archive"), |
640 |
|
quotearg_colon (cursor->name))); |
641 |
|
} |
642 |
|
|
643 |
/* Don't bother freeing the name list; we're about to exit. */ |
/* Don't bother freeing the name list; we're about to exit. */ |
644 |
namelist = 0; |
namelist = 0; |
645 |
nametail = &namelist; |
nametail = &namelist; |
648 |
{ |
{ |
649 |
char *name; |
char *name; |
650 |
|
|
651 |
while (name = name_next (1), name) |
while ((name = name_next (1)) != NULL) |
652 |
ERROR ((0, 0, _("%s: Not found in archive"), |
ERROR ((0, 0, _("%s: Not found in archive"), |
653 |
quotearg_colon (name))); |
quotearg_colon (name))); |
654 |
} |
} |
737 |
static int |
static int |
738 |
compare_names (struct name const *n1, struct name const *n2) |
compare_names (struct name const *n1, struct name const *n2) |
739 |
{ |
{ |
740 |
int found_diff = n2->found - n1->found; |
int found_diff = WASFOUND(n2) - WASFOUND(n1); |
741 |
return found_diff ? found_diff : strcmp (n1->name, n2->name); |
return found_diff ? found_diff : strcmp (n1->name, n2->name); |
742 |
} |
} |
743 |
|
|
823 |
for (name = namelist; name; name = next_name) |
for (name = namelist; name; name = next_name) |
824 |
{ |
{ |
825 |
next_name = name->next; |
next_name = name->next; |
826 |
if (name->found || name->dir_contents) |
if (name->found_count || name->dir_contents) |
827 |
continue; |
continue; |
828 |
if (name->regexp) /* FIXME: just skip regexps for now */ |
if (name->regexp) /* FIXME: just skip regexps for now */ |
829 |
continue; |
continue; |
841 |
} |
} |
842 |
if (S_ISDIR (statbuf.st_mode)) |
if (S_ISDIR (statbuf.st_mode)) |
843 |
{ |
{ |
844 |
name->found = 1; |
name->found_count++; |
845 |
add_hierarchy_to_namelist (name, statbuf.st_dev); |
add_hierarchy_to_namelist (name, statbuf.st_dev); |
846 |
} |
} |
847 |
} |
} |
852 |
namelist = merge_sort (namelist, num_names, compare_names); |
namelist = merge_sort (namelist, num_names, compare_names); |
853 |
|
|
854 |
for (name = namelist; name; name = name->next) |
for (name = namelist; name; name = name->next) |
855 |
name->found = 0; |
name->found_count = 0; |
856 |
} |
} |
857 |
|
|
858 |
/* This is like name_match, except that it returns a pointer to the |
/* This is like name_match, except that it returns a pointer to the |
872 |
|
|
873 |
/* Filename from archive not found in namelist. If we have the whole |
/* Filename from archive not found in namelist. If we have the whole |
874 |
namelist here, just return 0. Otherwise, read the next name in and |
namelist here, just return 0. Otherwise, read the next name in and |
875 |
compare it. If this was the last name, namelist->found will remain |
compare it. If this was the last name, namelist->found_count will |
876 |
on. If not, we loop to compare the newly read name. */ |
remain on. If not, we loop to compare the newly read name. */ |
877 |
|
|
878 |
if (same_order_option && namelist && namelist->found) |
if (same_order_option && namelist && namelist->found_count) |
879 |
{ |
{ |
880 |
name_gather (); /* read one more */ |
name_gather (); /* read one more */ |
881 |
if (namelist->found) |
if (namelist->found_count) |
882 |
return 0; |
return 0; |
883 |
} |
} |
884 |
else |
else |
896 |
{ |
{ |
897 |
if (!gnu_list_name) |
if (!gnu_list_name) |
898 |
gnu_list_name = namelist; |
gnu_list_name = namelist; |
899 |
while (gnu_list_name && (gnu_list_name->found | gnu_list_name->fake)) |
while (gnu_list_name && (gnu_list_name->found_count || gnu_list_name->fake)) |
900 |
gnu_list_name = gnu_list_name->next; |
gnu_list_name = gnu_list_name->next; |
901 |
if (gnu_list_name) |
if (gnu_list_name) |
902 |
{ |
{ |
903 |
gnu_list_name->found = 1; |
gnu_list_name->found_count++; |
904 |
chdir_do (gnu_list_name->change_dir); |
chdir_do (gnu_list_name->change_dir); |
905 |
return gnu_list_name->name; |
return gnu_list_name->name; |
906 |
} |
} |
914 |
|
|
915 |
gnu_list_name = 0; |
gnu_list_name = 0; |
916 |
for (name = namelist; name; name = name->next) |
for (name = namelist; name; name = name->next) |
917 |
name->found = 0; |
name->found_count = 0; |
918 |
} |
} |
919 |
|
|
920 |
/* Yield a newly allocated file name consisting of PATH concatenated to |
/* Yield a newly allocated file name consisting of PATH concatenated to |