| 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 |