예제 #1
0
static bool
decode_signed_num (intmax_t *num, char const *arg,
		   intmax_t minval, uintmax_t maxval,
		   char const *keyword)
{
  char *arg_lim;
  intmax_t u = strtosysint (arg, &arg_lim, minval, maxval);

  if (errno == EINVAL || *arg_lim)
    {
      ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"),
	      keyword, arg));
      return false;
    }

  if (errno == ERANGE)
    {
      out_of_range_header (keyword, arg, minval, maxval);
      return false;
    }

  *num = u;
  return true;
}
예제 #2
0
파일: incremen.c 프로젝트: Distrotech/tar
/* Read incremental snapshot formats 0 and 1 */
static void
read_incr_db_01 (int version, const char *initbuf)
{
  int n;
  uintmax_t u;
  char *buf = NULL;
  size_t bufsize = 0;
  char *ebuf;
  long lineno = 1;

  if (version == 1)
    {
      if (getline (&buf, &bufsize, listed_incremental_stream) <= 0)
	{
	  read_error (listed_incremental_option);
	  free (buf);
	  return;
	}
      ++lineno;
    }
  else
    {
      buf = strdup (initbuf);
      bufsize = strlen (buf) + 1;
    }

  newer_mtime_option = decode_timespec (buf, &ebuf, false);

  if (! valid_timespec (newer_mtime_option))
    ERROR ((0, errno, "%s:%ld: %s",
	    quotearg_colon (listed_incremental_option),
	    lineno,
	    _("Invalid time stamp")));
  else
    {
      if (version == 1 && *ebuf)
	{
	  char const *buf_ns = ebuf + 1;
	  errno = 0;
	  u = strtoumax (buf_ns, &ebuf, 10);
	  if (!errno && BILLION <= u)
	    errno = ERANGE;
	  if (errno || buf_ns == ebuf)
	    {
	      ERROR ((0, errno, "%s:%ld: %s",
		      quotearg_colon (listed_incremental_option),
		      lineno,
		      _("Invalid time stamp")));
	      newer_mtime_option.tv_sec = TYPE_MINIMUM (time_t);
	      newer_mtime_option.tv_nsec = -1;
	    }
	  else
	    newer_mtime_option.tv_nsec = u;
	}
    }

  while (0 < (n = getline (&buf, &bufsize, listed_incremental_stream)))
    {
      dev_t dev;
      ino_t ino;
      bool nfs = buf[0] == '+';
      char *strp = buf + nfs;
      struct timespec mtime;

      lineno++;

      if (buf[n - 1] == '\n')
	buf[n - 1] = '\0';

      if (version == 1)
	{
	  mtime = decode_timespec (strp, &ebuf, false);
	  strp = ebuf;
	  if (!valid_timespec (mtime) || *strp != ' ')
	    ERROR ((0, errno, "%s:%ld: %s",
		    quotearg_colon (listed_incremental_option), lineno,
		    _("Invalid modification time")));

	  errno = 0;
	  u = strtoumax (strp, &ebuf, 10);
	  if (!errno && BILLION <= u)
	    errno = ERANGE;
	  if (errno || strp == ebuf || *ebuf != ' ')
	    {
	      ERROR ((0, errno, "%s:%ld: %s",
		      quotearg_colon (listed_incremental_option), lineno,
		      _("Invalid modification time (nanoseconds)")));
	      mtime.tv_nsec = -1;
	    }
	  else
	    mtime.tv_nsec = u;
	  strp = ebuf;
	}
      else
	mtime.tv_sec = mtime.tv_nsec = 0;

      dev = strtosysint (strp, &ebuf,
			 TYPE_MINIMUM (dev_t), TYPE_MAXIMUM (dev_t));
      strp = ebuf;
      if (errno || *strp != ' ')
	ERROR ((0, errno, "%s:%ld: %s",
		quotearg_colon (listed_incremental_option), lineno,
		_("Invalid device number")));

      ino = strtosysint (strp, &ebuf,
			 TYPE_MINIMUM (ino_t), TYPE_MAXIMUM (ino_t));
      strp = ebuf;
      if (errno || *strp != ' ')
	ERROR ((0, errno, "%s:%ld: %s",
		quotearg_colon (listed_incremental_option), lineno,
		_("Invalid inode number")));

      strp++;
      unquote_string (strp);
      note_directory (strp, mtime, dev, ino, nfs, false, NULL);
    }
  free (buf);
}
예제 #3
0
파일: incremen.c 프로젝트: Distrotech/tar
static bool
read_num (FILE *fp, char const *fieldname,
	  intmax_t min_val, uintmax_t max_val, intmax_t *pval)
{
  int i;
  char buf[INT_BUFSIZE_BOUND (intmax_t)];
  char offbuf[INT_BUFSIZE_BOUND (off_t)];
  char minbuf[INT_BUFSIZE_BOUND (intmax_t)];
  char maxbuf[INT_BUFSIZE_BOUND (intmax_t)];
  int conversion_errno;
  int c = getc (fp);
  bool negative = c == '-';

  for (i = 0; (i == 0 && negative) || ISDIGIT (c); i++)
    {
      buf[i] = c;
      if (i == sizeof buf - 1)
	FATAL_ERROR ((0, 0,
		      _("%s: byte %s: %s %.*s... too long"),
		      quotearg_colon (listed_incremental_option),
		      offtostr (ftello (fp), offbuf),
		      fieldname, i + 1, buf));
      c = getc (fp);
    }

  buf[i] = 0;

  if (c < 0)
    {
      if (ferror (fp))
	read_fatal (listed_incremental_option);
      if (i != 0)
	FATAL_ERROR ((0, 0, "%s: %s",
		      quotearg_colon (listed_incremental_option),
		      _("Unexpected EOF in snapshot file")));
      return false;
    }

  if (c)
    {
      unsigned uc = c;
      FATAL_ERROR ((0, 0,
		    _("%s: byte %s: %s %s followed by invalid byte 0x%02x"),
		    quotearg_colon (listed_incremental_option),
		    offtostr (ftello (fp), offbuf),
		    fieldname, buf, uc));
    }

  *pval = strtosysint (buf, NULL, min_val, max_val);
  conversion_errno = errno;

  switch (conversion_errno)
    {
    case ERANGE:
      FATAL_ERROR ((0, conversion_errno,
		    _("%s: byte %s: (valid range %s..%s)\n\t%s %s"),
		    quotearg_colon (listed_incremental_option),
		    offtostr (ftello (fp), offbuf),
		    imaxtostr (min_val, minbuf),
		    umaxtostr (max_val, maxbuf), fieldname, buf));
    default:
      FATAL_ERROR ((0, conversion_errno,
		    _("%s: byte %s: %s %s"),
		    quotearg_colon (listed_incremental_option),
		    offtostr (ftello (fp), offbuf), fieldname, buf));
    case 0:
      break;
    }

  return true;
}