/[tar]/tar/src/names.c
ViewVC logotype

Diff of /tar/src/names.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.29 by gray, Thu Oct 2 10:41:48 2003 UTC revision 1.30 by gray, Sat Oct 4 13:50:41 2003 UTC
# Line 440  name_gather (void) Line 440  name_gather (void)
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;
# Line 497  addname (char const *string, int change_ Line 497  addname (char const *string, int change_
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;
# Line 566  name_match (const char *path) Line 566  name_match (const char *path)
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);
# Line 576  name_match (const char *path) Line 578  name_match (const char *path)
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
# Line 595  name_match (const char *path) Line 597  name_match (const char *path)
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    
# Line 613  names_notfound (void) Line 630  names_notfound (void)
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;
# Line 625  names_notfound (void) Line 648  names_notfound (void)
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      }      }
# Line 714  merge_sort (struct name *list, int lengt Line 737  merge_sort (struct name *list, int lengt
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    
# Line 800  collect_and_sort_names (void) Line 823  collect_and_sort_names (void)
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;
# Line 818  collect_and_sort_names (void) Line 841  collect_and_sort_names (void)
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      }      }
# Line 829  collect_and_sort_names (void) Line 852  collect_and_sort_names (void)
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
# Line 849  name_scan (const char *path) Line 872  name_scan (const char *path)
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
# Line 873  name_from_list (void) Line 896  name_from_list (void)
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      }      }
# Line 891  blank_name_list (void) Line 914  blank_name_list (void)
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

Legend:
Removed from v.1.29  
changed lines
  Added in v.1.30

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26