⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 names.c

📁 gnu tar 源码包。 tar 软件是 Unix 系统下的一个打包软件
💻 C
📖 第 1 页 / 共 2 页
字号:
	{	  chdir_do (cursor->change_dir);	  namelist = 0;	  nametail = &namelist;	  return true;	}      cursor = namelist_match (file_name, length);      if (cursor)	{	  if (!(ISSLASH (file_name[cursor->length]) && recursion_option)	      || cursor->found_count == 0)	    cursor->found_count++; /* remember it matched */	  if (starting_file_option)	    {	      free (namelist);	      namelist = 0;	      nametail = &namelist;	    }	  chdir_do (cursor->change_dir);	  /* We got a match.  */	  return ISFOUND (cursor);	}      /* Filename from archive not found in namelist.  If we have the whole	 namelist here, just return 0.  Otherwise, read the next name in and	 compare it.  If this was the last name, namelist->found_count will	 remain on.  If not, we loop to compare the newly read name.  */      if (same_order_option && namelist->found_count)	{	  name_gather ();	/* read one more */	  if (namelist->found_count)	    return false;	}      else	return false;    }}/* Returns true if all names from the namelist were processed.   P is the stat_info of the most recently processed entry.   The decision is postponed until the next entry is read if:   1) P ended with a slash (i.e. it was a directory)   2) P matches any entry from the namelist *and* represents a subdirectory   or a file lying under this entry (in the terms of directory structure).   This is necessary to handle contents of directories. */boolall_names_found (struct tar_stat_info *p){  struct name const *cursor;  size_t len;  if (test_label_option)    return true;  if (!p->file_name || occurrence_option == 0 || p->had_trailing_slash)    return false;  len = strlen (p->file_name);  for (cursor = namelist; cursor; cursor = cursor->next)    {      if ((cursor->name[0] && !WASFOUND (cursor))	  || (len >= cursor->length && ISSLASH (p->file_name[cursor->length])))	return false;    }  return true;}static inline intis_pattern (const char *string){  return strchr (string, '*') || strchr (string, '[') || strchr (string, '?');}static voidregex_usage_warning (const char *name){  static int warned_once = 0;  if (warn_regex_usage && is_pattern (name))    {      warned_once = 1;      WARN ((0, 0,	     /* TRANSLATORS: The following three msgids form a single sentence.	      */	     _("Pattern matching characters used in file names. Please,")));      WARN ((0, 0,	     _("use --wildcards to enable pattern matching, or --no-wildcards to")));      WARN ((0, 0,	     _("suppress this warning.")));    }}/* Print the names of things in the namelist that were not matched.  */voidnames_notfound (void){  struct name const *cursor;  for (cursor = namelist; cursor; cursor = cursor->next)    if (!WASFOUND (cursor) && cursor->name[0])      {	regex_usage_warning (cursor->name);	if (cursor->found_count == 0)	  ERROR ((0, 0, _("%s: Not found in archive"),		  quotearg_colon (cursor->name)));	else	  ERROR ((0, 0, _("%s: Required occurrence not found in archive"),		  quotearg_colon (cursor->name)));        }  /* Don't bother freeing the name list; we're about to exit.  */  namelist = 0;  nametail = &namelist;  if (same_order_option)    {      const char *name;      while ((name = name_next (1)) != NULL)	{	  regex_usage_warning (name);	  ERROR ((0, 0, _("%s: Not found in archive"),		  quotearg_colon (name)));	}    }}/* Sorting name lists.  *//* Sort linked LIST of names, of given LENGTH, using COMPARE to order   names.  Return the sorted list.  Apart from the type `struct name'   and the definition of SUCCESSOR, this is a generic list-sorting   function, but it's too painful to make it both generic and portable   in C.  */static struct name *merge_sort (struct name *list, int length,	    int (*compare) (struct name const*, struct name const*)){  struct name *first_list;  struct name *second_list;  int first_length;  int second_length;  struct name *result;  struct name **merge_point;  struct name *cursor;  int counter;# define SUCCESSOR(name) ((name)->next)  if (length == 1)    return list;  if (length == 2)    {      if ((*compare) (list, SUCCESSOR (list)) > 0)	{	  result = SUCCESSOR (list);	  SUCCESSOR (result) = list;	  SUCCESSOR (list) = 0;	  return result;	}      return list;    }  first_list = list;  first_length = (length + 1) / 2;  second_length = length / 2;  for (cursor = list, counter = first_length - 1;       counter;       cursor = SUCCESSOR (cursor), counter--)    continue;  second_list = SUCCESSOR (cursor);  SUCCESSOR (cursor) = 0;  first_list = merge_sort (first_list, first_length, compare);  second_list = merge_sort (second_list, second_length, compare);  merge_point = &result;  while (first_list && second_list)    if ((*compare) (first_list, second_list) < 0)      {	cursor = SUCCESSOR (first_list);	*merge_point = first_list;	merge_point = &SUCCESSOR (first_list);	first_list = cursor;      }    else      {	cursor = SUCCESSOR (second_list);	*merge_point = second_list;	merge_point = &SUCCESSOR (second_list);	second_list = cursor;      }  if (first_list)    *merge_point = first_list;  else    *merge_point = second_list;  return result;#undef SUCCESSOR}/* A comparison function for sorting names.  Put found names last;   break ties by string comparison.  */static intcompare_names (struct name const *n1, struct name const *n2){  int found_diff = WASFOUND(n2) - WASFOUND(n1);  return found_diff ? found_diff : strcmp (n1->name, n2->name);}/* Add all the dirs under NAME, which names a directory, to the namelist.   If any of the files is a directory, recurse on the subdirectory.   DEVICE is the device not to leave, if the -l option is specified.  */static voidadd_hierarchy_to_namelist (struct name *name, dev_t device){  char *file_name = name->name;  const char *buffer = get_directory_contents (file_name, device);  if (! buffer)    name->dir_contents = "\0\0\0\0";  else    {      size_t name_length = name->length;      size_t allocated_length = (name_length >= NAME_FIELD_SIZE				 ? name_length + NAME_FIELD_SIZE				 : NAME_FIELD_SIZE);      char *namebuf = xmalloc (allocated_length + 1);				/* FIXME: + 2 above?  */      const char *string;      size_t string_length;      int change_dir = name->change_dir;      name->dir_contents = buffer;      strcpy (namebuf, file_name);      if (! ISSLASH (namebuf[name_length - 1]))	{	  namebuf[name_length++] = '/';	  namebuf[name_length] = '\0';	}      for (string = buffer; *string; string += string_length + 1)	{	  string_length = strlen (string);	  if (*string == 'D')	    {	      struct name *np;	      if (allocated_length <= name_length + string_length)		{		  do		    {		      allocated_length *= 2;		      if (! allocated_length)			xalloc_die ();		    }		  while (allocated_length <= name_length + string_length);		  namebuf = xrealloc (namebuf, allocated_length + 1);		}	      strcpy (namebuf + name_length, string + 1);	      np = addname (namebuf, change_dir);	      add_hierarchy_to_namelist (np, device);	    }	}      free (namebuf);    }}/* Collect all the names from argv[] (or whatever), expand them into a   directory tree, and sort them.  This gets only subdirectories, not   all files.  */voidcollect_and_sort_names (void){  struct name *name;  struct name *next_name;  int num_names;  struct stat statbuf;  name_gather ();  if (listed_incremental_option)    read_directory_file ();  if (!namelist)    addname (".", 0);  for (name = namelist; name; name = next_name)    {      next_name = name->next;      if (name->found_count || name->dir_contents)	continue;      if (name->matching_flags & EXCLUDE_WILDCARDS)	/* NOTE: EXCLUDE_ANCHORED is not relevant here */	/* FIXME: just skip regexps for now */	continue;      chdir_do (name->change_dir);      if (name->name[0] == 0)	continue;      if (deref_stat (dereference_option, name->name, &statbuf) != 0)	{	  stat_diag (name->name);	  continue;	}      if (S_ISDIR (statbuf.st_mode))	{	  name->found_count++;	  add_hierarchy_to_namelist (name, statbuf.st_dev);	}    }  num_names = 0;  for (name = namelist; name; name = name->next)    num_names++;  namelist = merge_sort (namelist, num_names, compare_names);  for (name = namelist; name; name = name->next)    name->found_count = 0;  if (listed_incremental_option)    {      for (name = namelist; name && name->name[0] == 0; name++)	;      if (name)	name->dir_contents = append_incremental_renames (name->dir_contents);    }}/* This is like name_match, except that    1. It returns a pointer to the name it matched, and doesn't set FOUND    in structure. The caller will have to do that if it wants to.    2. If the namelist is empty, it returns null, unlike name_match, which    returns TRUE. */struct name *name_scan (const char *file_name){  size_t length = strlen (file_name);  while (1)    {      struct name *cursor = namelist_match (file_name, length);      if (cursor)	return cursor;      /* Filename from archive not found in namelist.  If we have the whole	 namelist here, just return 0.  Otherwise, read the next name in and	 compare it.  If this was the last name, namelist->found_count will	 remain on.  If not, we loop to compare the newly read name.  */      if (same_order_option && namelist && namelist->found_count)	{	  name_gather ();	/* read one more */	  if (namelist->found_count)	    return 0;	}      else	return 0;    }}/* This returns a name from the namelist which doesn't have ->found   set.  It sets ->found before returning, so successive calls will   find and return all the non-found names in the namelist.  */struct name *gnu_list_name;char *name_from_list (void){  if (!gnu_list_name)    gnu_list_name = namelist;  while (gnu_list_name	 && (gnu_list_name->found_count || gnu_list_name->name[0] == 0))    gnu_list_name = gnu_list_name->next;  if (gnu_list_name)    {      gnu_list_name->found_count++;      chdir_do (gnu_list_name->change_dir);      return gnu_list_name->name;    }  return 0;}voidblank_name_list (void){  struct name *name;  gnu_list_name = 0;  for (name = namelist; name; name = name->next)    name->found_count = 0;}/* Yield a newly allocated file name consisting of FILE_NAME concatenated to   NAME, with an intervening slash if FILE_NAME does not already end in one. */char *new_name (const char *file_name, const char *name){  size_t file_name_len = strlen (file_name);  size_t namesize = strlen (name) + 1;  int slash = file_name_len && ! ISSLASH (file_name[file_name_len - 1]);  char *buffer = xmalloc (file_name_len + slash + namesize);  memcpy (buffer, file_name, file_name_len);  buffer[file_name_len] = '/';  memcpy (buffer + file_name_len + slash, name, namesize);  return buffer;}/* Return nonzero if file NAME is excluded.  */boolexcluded_name (char const *name){  return excluded_file_name (excluded, name + FILE_SYSTEM_PREFIX_LEN (name));}/* Names to avoid dumping.  */static Hash_table *avoided_name_table;/* Remember to not archive NAME.  */voidadd_avoided_name (char const *name){  hash_string_insert (&avoided_name_table, name);}/* Should NAME be avoided when archiving?  */boolis_avoided_name (char const *name){  return hash_string_lookup (avoided_name_table, name);}static Hash_table *individual_file_table;static voidregister_individual_file (char const *name){  struct stat st;  if (deref_stat (dereference_option, name, &st) != 0)    return; /* Will be complained about later */  if (S_ISDIR (st.st_mode))    return;  hash_string_insert (&individual_file_table, name);}boolis_individual_file (char const *name){  return hash_string_lookup (individual_file_table, name);}/* Return the size of the prefix of FILE_NAME that is removed after   stripping NUM leading file name components.  NUM must be   positive.  */size_tstripped_prefix_len (char const *file_name, size_t num){  char const *p = file_name + FILE_SYSTEM_PREFIX_LEN (file_name);  while (ISSLASH (*p))    p++;  while (*p)    {      bool slash = ISSLASH (*p);      p++;      if (slash)	{	  if (--num == 0)	    return p - file_name;	  while (ISSLASH (*p))	    p++;	}    }  return -1;}/* Return nonzero if NAME contains ".." as a file name component.  */boolcontains_dot_dot (char const *name){  char const *p = name + FILE_SYSTEM_PREFIX_LEN (name);  for (;; p++)    {      if (p[0] == '.' && p[1] == '.' && (ISSLASH (p[2]) || !p[2]))	return 1;      while (! ISSLASH (*p))	{	  if (! *p++)	    return 0;	}    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -