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

📄 create.c

📁 gnu tar 源码包。 tar 软件是 Unix 系统下的一个打包软件
💻 C
📖 第 1 页 / 共 4 页
字号:
{  uid_t r;#ifdef UID_NOBODY  r = UID_NOBODY;#else  static uid_t uid_nobody;  if (!uid_nobody && !uname_to_uid ("nobody", &uid_nobody))    uid_nobody = -2;  r = uid_nobody;#endif  *negative = r < 0;  return r;}booluid_to_chars (uid_t v, char *p, size_t s){  return to_chars (v < 0, (uintmax_t) v, sizeof v, uid_substitute, p, s, "uid_t");}booluintmax_to_chars (uintmax_t v, char *p, size_t s){  return to_chars (0, v, sizeof v, 0, p, s, "uintmax_t");}voidstring_to_chars (char const *str, char *p, size_t s){  tar_copy_str (p, str, s);  p[s - 1] = '\0';}/* A file is considered dumpable if it is sparse and both --sparse and --totals   are specified.   Otherwise, it is dumpable unless any of the following conditions occur:   a) it is empty *and* world-readable, or   b) current archive is /dev/null */boolfile_dumpable_p (struct tar_stat_info *st){  if (dev_null_output)    return totals_option && sparse_option && ST_IS_SPARSE (st->stat);  return !(st->archive_file_size == 0	   && (st->stat.st_mode & MODE_R) == MODE_R);}/* Writing routines.  *//* Write the EOT block(s).  Zero at least two blocks, through the end   of the record.  Old tar, as previous versions of GNU tar, writes   garbage after two zeroed blocks.  */voidwrite_eot (void){  union block *pointer = find_next_block ();  memset (pointer->buffer, 0, BLOCKSIZE);  set_next_block_after (pointer);  pointer = find_next_block ();  memset (pointer->buffer, 0, available_space_after (pointer));  set_next_block_after (pointer);}/* Write a "private" header */union block *start_private_header (const char *name, size_t size){  time_t t;  union block *header = find_next_block ();  memset (header->buffer, 0, sizeof (union block));  tar_name_copy_str (header->header.name, name, NAME_FIELD_SIZE);  OFF_TO_CHARS (size, header->header.size);  time (&t);  TIME_TO_CHARS (t, header->header.mtime);  MODE_TO_CHARS (S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, header->header.mode);  UID_TO_CHARS (getuid (), header->header.uid);  GID_TO_CHARS (getgid (), header->header.gid);  MAJOR_TO_CHARS (0, header->header.devmajor);  MINOR_TO_CHARS (0, header->header.devminor);  strncpy (header->header.magic, TMAGIC, TMAGLEN);  strncpy (header->header.version, TVERSION, TVERSLEN);  return header;}/* Create a new header and store there at most NAME_FIELD_SIZE bytes of   the file name */static union block *write_short_name (struct tar_stat_info *st){  union block *header = find_next_block ();  memset (header->buffer, 0, sizeof (union block));  tar_name_copy_str (header->header.name, st->file_name, NAME_FIELD_SIZE);  return header;}#define FILL(field,byte) do {            \  memset(field, byte, sizeof(field)-1);  \  (field)[sizeof(field)-1] = 0;          \} while (0)/* Write a GNUTYPE_LONGLINK or GNUTYPE_LONGNAME block.  */static voidwrite_gnu_long_link (struct tar_stat_info *st, const char *p, char type){  size_t size = strlen (p) + 1;  size_t bufsize;  union block *header;  char *tmpname;  header = start_private_header ("././@LongLink", size);  FILL(header->header.mtime, '0');  FILL(header->header.mode, '0');  FILL(header->header.uid, '0');  FILL(header->header.gid, '0');  FILL(header->header.devmajor, 0);  FILL(header->header.devminor, 0);  uid_to_uname (0, &tmpname);  UNAME_TO_CHARS (tmpname, header->header.uname);  free (tmpname);  gid_to_gname (0, &tmpname);  GNAME_TO_CHARS (tmpname, header->header.gname);  free (tmpname);  strcpy (header->header.magic, OLDGNU_MAGIC);  header->header.typeflag = type;  finish_header (st, header, -1);  header = find_next_block ();  bufsize = available_space_after (header);  while (bufsize < size)    {      memcpy (header->buffer, p, bufsize);      p += bufsize;      size -= bufsize;      set_next_block_after (header + (bufsize - 1) / BLOCKSIZE);      header = find_next_block ();      bufsize = available_space_after (header);    }  memcpy (header->buffer, p, size);  memset (header->buffer + size, 0, bufsize - size);  set_next_block_after (header + (size - 1) / BLOCKSIZE);}static size_tsplit_long_name (const char *name, size_t length){  size_t i;  if (length > PREFIX_FIELD_SIZE)    length = PREFIX_FIELD_SIZE + 1;  for (i = length - 1; i > 0; i--)    if (ISSLASH (name[i]))      break;  return i;}static union block *write_ustar_long_name (const char *name){  size_t length = strlen (name);  size_t i;  union block *header;  if (length > PREFIX_FIELD_SIZE + NAME_FIELD_SIZE + 1)    {      ERROR ((0, 0, _("%s: file name is too long (max %d); not dumped"),	      quotearg_colon (name),	      PREFIX_FIELD_SIZE + NAME_FIELD_SIZE + 1));      return NULL;    }  i = split_long_name (name, length);  if (i == 0 || length - i - 1 > NAME_FIELD_SIZE)    {      ERROR ((0, 0,	      _("%s: file name is too long (cannot be split); not dumped"),	      quotearg_colon (name)));      return NULL;    }  header = find_next_block ();  memset (header->buffer, 0, sizeof (header->buffer));  memcpy (header->header.prefix, name, i);  memcpy (header->header.name, name + i + 1, length - i - 1);  return header;}/* Write a long link name, depending on the current archive format */static voidwrite_long_link (struct tar_stat_info *st){  switch (archive_format)    {    case POSIX_FORMAT:      xheader_store ("linkpath", st, NULL);      break;    case V7_FORMAT:			/* old V7 tar format */    case USTAR_FORMAT:    case STAR_FORMAT:      ERROR ((0, 0,	      _("%s: link name is too long; not dumped"),	      quotearg_colon (st->link_name)));      break;    case OLDGNU_FORMAT:    case GNU_FORMAT:      write_gnu_long_link (st, st->link_name, GNUTYPE_LONGLINK);      break;    default:      abort(); /*FIXME*/    }}static union block *write_long_name (struct tar_stat_info *st){  switch (archive_format)    {    case POSIX_FORMAT:      xheader_store ("path", st, NULL);      break;    case V7_FORMAT:      if (strlen (st->file_name) > NAME_FIELD_SIZE-1)	{	  ERROR ((0, 0, _("%s: file name is too long (max %d); not dumped"),		  quotearg_colon (st->file_name),		  NAME_FIELD_SIZE - 1));	  return NULL;	}      break;    case USTAR_FORMAT:    case STAR_FORMAT:      return write_ustar_long_name (st->file_name);    case OLDGNU_FORMAT:    case GNU_FORMAT:      write_gnu_long_link (st, st->file_name, GNUTYPE_LONGNAME);      break;    default:      abort(); /*FIXME*/    }  return write_short_name (st);}union block *write_extended (bool global, struct tar_stat_info *st, union block *old_header){  union block *header, hp;  char *p;  int type;  if (st->xhdr.buffer || st->xhdr.stk == NULL)    return old_header;  xheader_finish (&st->xhdr);  memcpy (hp.buffer, old_header, sizeof (hp));  if (global)    {      type = XGLTYPE;      p = xheader_ghdr_name ();    }  else    {      type = XHDTYPE;      p = xheader_xhdr_name (st);    }  xheader_write (type, p, &st->xhdr);  free (p);  header = find_next_block ();  memcpy (header, &hp.buffer, sizeof (hp.buffer));  return header;}static union block *write_header_name (struct tar_stat_info *st){  if (archive_format == POSIX_FORMAT && !string_ascii_p (st->file_name))    {      xheader_store ("path", st, NULL);      return write_short_name (st);    }  else if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT)	   < strlen (st->file_name))    return write_long_name (st);  else    return write_short_name (st);}/* Header handling.  *//* Make a header block for the file whose stat info is st,   and return its address.  */union block *start_header (struct tar_stat_info *st){  union block *header;  header = write_header_name (st);  if (!header)    return NULL;  /* Override some stat fields, if requested to do so.  */  if (owner_option != (uid_t) -1)    st->stat.st_uid = owner_option;  if (group_option != (gid_t) -1)    st->stat.st_gid = group_option;  if (mode_option)    st->stat.st_mode =      ((st->stat.st_mode & ~MODE_ALL)       | mode_adjust (st->stat.st_mode, S_ISDIR (st->stat.st_mode) != 0,		      initial_umask, mode_option, NULL));  /* Paul Eggert tried the trivial test ($WRITER cf a b; $READER tvf a)     for a few tars and came up with the following interoperability     matrix:	      WRITER	1 2 3 4 5 6 7 8 9   READER	. . . . . . . . .   1 = SunOS 4.2 tar	# . . # # . . # #   2 = NEC SVR4.0.2 tar	. . . # # . . # .   3 = Solaris 2.1 tar	. . . . . . . . .   4 = GNU tar 1.11.1	. . . . . . . . .   5 = HP-UX 8.07 tar	. . . . . . . . .   6 = Ultrix 4.1	. . . . . . . . .   7 = AIX 3.2	. . . . . . . . .   8 = Hitachi HI-UX 1.03	. . . . . . . . .   9 = Omron UNIOS-B 4.3BSD 1.60Beta	     . = works	     # = ``impossible file type''     The following mask for old archive removes the `#'s in column 4     above, thus making GNU tar both a universal donor and a universal     acceptor for Paul's test.  */  if (archive_format == V7_FORMAT || archive_format == USTAR_FORMAT)    MODE_TO_CHARS (st->stat.st_mode & MODE_ALL, header->header.mode);  else    MODE_TO_CHARS (st->stat.st_mode, header->header.mode);  {    uid_t uid = st->stat.st_uid;    if (archive_format == POSIX_FORMAT	&& MAX_OCTAL_VAL (header->header.uid) < uid)      {	xheader_store ("uid", st, NULL);	uid = 0;      }    if (!UID_TO_CHARS (uid, header->header.uid))      return NULL;  }  {    gid_t gid = st->stat.st_gid;    if (archive_format == POSIX_FORMAT	&& MAX_OCTAL_VAL (header->header.gid) < gid)      {	xheader_store ("gid", st, NULL);	gid = 0;      }    if (!GID_TO_CHARS (gid, header->header.gid))      return NULL;  }  {    off_t size = st->stat.st_size;    if (archive_format == POSIX_FORMAT	&& MAX_OCTAL_VAL (header->header.size) < size)      {	xheader_store ("size", st, NULL);	size = 0;      }    if (!OFF_TO_CHARS (size, header->header.size))      return NULL;  }  {    struct timespec mtime = set_mtime_option ? mtime_option : st->mtime;    if (archive_format == POSIX_FORMAT)      {	if (MAX_OCTAL_VAL (header->header.mtime) < mtime.tv_sec	    || mtime.tv_nsec != 0)	  xheader_store ("mtime", st, &mtime);	if (MAX_OCTAL_VAL (header->header.mtime) < mtime.tv_sec)	  mtime.tv_sec = 0;      }    if (!TIME_TO_CHARS (mtime.tv_sec, header->header.mtime))      return NULL;  }  /* FIXME */  if (S_ISCHR (st->stat.st_mode)      || S_ISBLK (st->stat.st_mode))    {      major_t devmajor = major (st->stat.st_rdev);      minor_t devminor = minor (st->stat.st_rdev);      if (archive_format == POSIX_FORMAT	  && MAX_OCTAL_VAL (header->header.devmajor) < devmajor)	{	  xheader_store ("devmajor", st, NULL);	  devmajor = 0;	}      if (!MAJOR_TO_CHARS (devmajor, header->header.devmajor))	return NULL;      if (archive_format == POSIX_FORMAT	  && MAX_OCTAL_VAL (header->header.devminor) < devminor)	{	  xheader_store ("devminor", st, NULL);	  devminor = 0;	}      if (!MINOR_TO_CHARS (devminor, header->header.devminor))	return NULL;    }  else if (archive_format != GNU_FORMAT && archive_format != OLDGNU_FORMAT)    {      if (!(MAJOR_TO_CHARS (0, header->header.devmajor)	    && MINOR_TO_CHARS (0, header->header.devminor)))	return NULL;    }  if (archive_format == POSIX_FORMAT)    {      xheader_store ("atime", st, NULL);      xheader_store ("ctime", st, NULL);    }  else if (incremental_option)    if (archive_format == OLDGNU_FORMAT || archive_format == GNU_FORMAT)

⌨️ 快捷键说明

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