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

📄 fs_fs.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 5 页
字号:
      local_value = apr_pstrdup (pool, value);

      apr_hash_set (*headers, local_name, APR_HASH_KEY_STRING, local_value);
    }

  return SVN_NO_ERROR;
}

/* Open the revision file for revision REV in filesystem FS and store
   the newly opened file in FILE.  Seek to location OFFSET before
   returning.  Perform temporary allocations in POOL. */
static svn_error_t *
open_and_seek_revision (apr_file_t **file,
                        svn_fs_t *fs,
                        svn_revnum_t rev,
                        apr_off_t offset,
                        apr_pool_t *pool)
{
  apr_file_t *rev_file;

  SVN_ERR (svn_io_file_open (&rev_file, path_rev (fs, rev, pool),
                             APR_READ | APR_BUFFERED, APR_OS_DEFAULT, pool));

  SVN_ERR (svn_io_file_seek (rev_file, APR_SET, &offset, pool));

  *file = rev_file;

  return SVN_NO_ERROR;
}

/* Open the representation for a node-revision in transaction TXN_ID
   in filesystem FS and store the newly opened file in FILE.  Seek to
   location OFFSET before returning.  Perform temporary allocations in
   POOL.  Only appropriate for file contents, nor props or directory
   contents. */
static svn_error_t *
open_and_seek_transaction (apr_file_t **file,
                           svn_fs_t *fs,
                           const char *txn_id,
                           representation_t *rep,
                           apr_pool_t *pool)
{
  apr_file_t *rev_file;
  apr_off_t offset;

  SVN_ERR (svn_io_file_open (&rev_file, path_txn_proto_rev (fs, txn_id, pool),
                             APR_READ | APR_BUFFERED, APR_OS_DEFAULT, pool));

  offset = rep->offset;
  SVN_ERR (svn_io_file_seek (rev_file, APR_SET, &offset, pool));

  *file = rev_file;

  return SVN_NO_ERROR;
}

/* Given a node-id ID, and a representation REP in filesystem FS, open
   the correct file and seek to the correction location.  Store this
   file in *FILE_P.  Perform any allocations in POOL. */
static svn_error_t *
open_and_seek_representation (apr_file_t **file_p,
                              svn_fs_t *fs,
                              representation_t *rep,
                              apr_pool_t *pool)
{
  if (! rep->txn_id)
    return open_and_seek_revision (file_p, fs, rep->revision, rep->offset,
                                   pool);
  else
    return open_and_seek_transaction (file_p, fs, rep->txn_id, rep, pool);
}

/* Parse the description of a representation from STRING and store it
   into *REP_P.  If the representation is mutable (the revision is
   given as -1), then use TXN_ID for the representation's txn_id
   field.  If MUTABLE_REP_TRUNCATED is true, then this representation
   is for property or directory contents, and no information will be
   expected except the "-1" revision number for a mutable
   representation.  Allocate *REP_P in POOL. */
static svn_error_t *
read_rep_offsets (representation_t **rep_p,
                  char *string,
                  const char *txn_id,
                  svn_boolean_t mutable_rep_truncated,
                  apr_pool_t *pool)
{
  representation_t *rep;
  char *str, *last_str;
  int i;

  rep = apr_pcalloc (pool, sizeof (*rep));
  *rep_p = rep;

  str = apr_strtok (string, " ", &last_str);
  if (str == NULL)
    return svn_error_create (SVN_ERR_FS_CORRUPT, NULL,
                             _("Malformed text rep offset line in node-rev"));


  rep->revision = SVN_STR_TO_REV (str);
  if (rep->revision == SVN_INVALID_REVNUM)
    {
      rep->txn_id = txn_id;
      if (mutable_rep_truncated)
        return SVN_NO_ERROR;
    }
  
  str = apr_strtok (NULL, " ", &last_str);
  if (str == NULL)
    return svn_error_create (SVN_ERR_FS_CORRUPT, NULL,
                             _("Malformed text rep offset line in node-rev"));
  
  rep->offset = apr_atoi64 (str);
  
  str = apr_strtok (NULL, " ", &last_str);
  if (str == NULL)
    return svn_error_create (SVN_ERR_FS_CORRUPT, NULL,
                             _("Malformed text rep offset line in node-rev"));
  
  rep->size = apr_atoi64 (str);
  
  str = apr_strtok (NULL, " ", &last_str);
  if (str == NULL)
    return svn_error_create (SVN_ERR_FS_CORRUPT, NULL,
                             _("Malformed text rep offset line in node-rev"));
  
  rep->expanded_size = apr_atoi64 (str);

  /* Read in the MD5 hash. */
  str = apr_strtok (NULL, " ", &last_str);
  if ((str == NULL) || (strlen (str) != (APR_MD5_DIGESTSIZE * 2)))
    return svn_error_create (SVN_ERR_FS_CORRUPT, NULL,
                             _("Malformed text rep offset line in node-rev"));

  /* Parse the hex MD5 hash into digest form. */
  for (i = 0; i < APR_MD5_DIGESTSIZE; i++)
    {
      if ((! isxdigit (str[i * 2])) || (! isxdigit (str[i * 2 + 1])))
        return svn_error_create
          (SVN_ERR_FS_CORRUPT, NULL,
           _("Malformed text rep offset line in node-rev"));

      str[i * 2] = tolower (str[i * 2]);
      rep->checksum[i] = (str[i * 2] -
                          ((str[i * 2] <= '9') ? '0' : ('a' - 10))) << 4;

      str[i * 2 + 1] = tolower (str[i * 2 + 1]);
      rep->checksum[i] |= (str[i * 2 + 1] -
                           ((str[i * 2 + 1] <= '9') ? '0' : ('a' - 10)));
    }
  
  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__get_node_revision (node_revision_t **noderev_p,
                              svn_fs_t *fs,
                              const svn_fs_id_t *id,
                              apr_pool_t *pool)
{
  apr_file_t *revision_file;
  apr_hash_t *headers;
  node_revision_t *noderev;
  char *value;
  svn_error_t *err;
  
  if (svn_fs_fs__id_txn_id (id))
    {
      /* This is a transaction node-rev. */
      err = svn_io_file_open (&revision_file, path_txn_node_rev (fs, id, pool),
                              APR_READ | APR_BUFFERED, APR_OS_DEFAULT, pool);
    }
  else
    {
      /* This is a revision node-rev. */
      err = open_and_seek_revision (&revision_file, fs,
                                    svn_fs_fs__id_rev (id),
                                    svn_fs_fs__id_offset (id),
                                    pool);
    }

  if (err)
    {
      if (APR_STATUS_IS_ENOENT (err->apr_err))
        {
          svn_error_clear (err);
          return svn_fs_fs__err_dangling_id (fs, id);
        }
      
      return err;
    }
  
  SVN_ERR (read_header_block (&headers, revision_file, pool) );

  noderev = apr_pcalloc (pool, sizeof (*noderev));

  /* Read the node-rev id. */
  value = apr_hash_get (headers, HEADER_ID, APR_HASH_KEY_STRING);

  SVN_ERR (svn_io_file_close (revision_file, pool));

  noderev->id = svn_fs_fs__id_parse (value, strlen (value), pool);

  /* Read the type. */
  value = apr_hash_get (headers, HEADER_TYPE, APR_HASH_KEY_STRING);

  if ((value == NULL) ||
      (strcmp (value, KIND_FILE) != 0 && strcmp (value, KIND_DIR)))
    return svn_error_create (SVN_ERR_FS_CORRUPT, NULL,
                             _("Missing kind field in node-rev"));

  noderev->kind = (strcmp (value, KIND_FILE) == 0) ? svn_node_file
    : svn_node_dir;

  /* Read the 'count' field. */
  value = apr_hash_get (headers, HEADER_COUNT, APR_HASH_KEY_STRING);
  noderev->predecessor_count = (value == NULL) ? 0 : atoi (value);

  /* Get the properties location. */
  value = apr_hash_get (headers, HEADER_PROPS, APR_HASH_KEY_STRING);
  if (value)
    {
      SVN_ERR (read_rep_offsets (&noderev->prop_rep, value,
                                 svn_fs_fs__id_txn_id (id), TRUE, pool));
    }

  /* Get the data location. */
  value = apr_hash_get (headers, HEADER_TEXT, APR_HASH_KEY_STRING);
  if (value)
    {
      SVN_ERR (read_rep_offsets (&noderev->data_rep, value,
                                 svn_fs_fs__id_txn_id (id),
                                 (noderev->kind == svn_node_dir), pool));
    }

  /* Get the created path. */
  value = apr_hash_get (headers, HEADER_CPATH, APR_HASH_KEY_STRING);
  if (value == NULL)
    {
      return svn_error_create (SVN_ERR_FS_CORRUPT, NULL,
                               _("Missing cpath in node-rev"));
    }
  else
    {
      noderev->created_path = apr_pstrdup (pool, value);
    }

  /* Get the predecessor ID. */
  value = apr_hash_get (headers, HEADER_PRED, APR_HASH_KEY_STRING);
  if (value)
    noderev->predecessor_id = svn_fs_fs__id_parse (value, strlen (value),
                                                   pool);
  
  /* Get the copyroot. */
  value = apr_hash_get (headers, HEADER_COPYROOT, APR_HASH_KEY_STRING);
  if (value == NULL)
    {
      noderev->copyroot_path = apr_pstrdup (pool, noderev->created_path);
      noderev->copyroot_rev = svn_fs_fs__id_rev (noderev->id);
    }
  else
    {
      char *str, *last_str;

      str = apr_strtok (value, " ", &last_str);
      if (str == NULL)
        return svn_error_create (SVN_ERR_FS_CORRUPT, NULL,
                                 _("Malformed copyroot line in node-rev"));

      noderev->copyroot_rev = atoi (str);
      
      if (last_str == NULL)
        return svn_error_create (SVN_ERR_FS_CORRUPT, NULL,
                                 _("Malformed copyroot line in node-rev"));
      noderev->copyroot_path = apr_pstrdup (pool, last_str);
    }

  /* Get the copyfrom. */
  value = apr_hash_get (headers, HEADER_COPYFROM, APR_HASH_KEY_STRING);
  if (value == NULL)
    {
      noderev->copyfrom_path = NULL;
      noderev->copyfrom_rev = SVN_INVALID_REVNUM;
    }
  else
    {
      char *str, *last_str;

      str = apr_strtok (value, " ", &last_str);
      if (str == NULL)
        return svn_error_create (SVN_ERR_FS_CORRUPT, NULL,
                                 _("Malformed copyfrom line in node-rev"));

      noderev->copyfrom_rev = atoi (str);
      
      if (last_str == NULL)
        return svn_error_create (SVN_ERR_FS_CORRUPT, NULL,
                                 _("Malformed copyfrom line in node-rev"));
      noderev->copyfrom_path = apr_pstrdup (pool, last_str);
    }

  *noderev_p = noderev;
  
  return SVN_NO_ERROR;
}

/* Return a formatted string that represents the location of
   representation REP.  If MUTABLE_REP_TRUNCATED is given, the rep is
   for props or dir contents, and only a "-1" revision number will be
   given for a mutable rep.  Perform the allocation from POOL.  */
static const char *
representation_string (representation_t *rep,
                       svn_boolean_t mutable_rep_truncated, apr_pool_t *pool)
{
  if (rep->txn_id && mutable_rep_truncated)
    return "-1";
  else
    return apr_psprintf (pool, "%ld %" APR_OFF_T_FMT " %" SVN_FILESIZE_T_FMT
                         " %" SVN_FILESIZE_T_FMT " %s",
                         rep->revision, rep->offset, rep->size,
                         rep->expanded_size,
                         svn_md5_digest_to_cstring (rep->checksum, pool));
}

/* Write the node-revision NODEREV into the file FILE.  Temporary
   allocations are from POOL. */
static svn_error_t *
write_noderev_txn (apr_file_t *file,
                   node_revision_t *noderev,
                   apr_pool_t *pool)
{
  svn_stream_t *outfile;

  outfile = svn_stream_from_aprfile (file, pool);

  SVN_ERR (svn_stream_printf (outfile, pool, HEADER_ID ": %s\n",
                              svn_fs_fs__id_unparse (noderev->id,
                                                     pool)->data));

  SVN_ERR (svn_stream_printf (outfile, pool, HEADER_TYPE ": %s\n",
                              (noderev->kind == svn_node_file) ?
                              KIND_FILE : KIND_DIR));

  if (noderev->predecessor_id)
    SVN_ERR (svn_stream_printf (outfile, pool, HEADER_PRED ": %s\n",
                                svn_fs_fs__id_unparse (noderev->predecessor_id,
                                                       pool)->data));

  SVN_ERR (svn_stream_printf (outfile, pool, HEADER_COUNT ": %d\n",
                              noderev->predecessor_count));

  if (noderev->data_rep)
    SVN_ERR (svn_stream_printf (outfile, pool, HEADER_TEXT ": %s\n",
                                representation_string (noderev->data_rep,
                                                       (noderev->kind
                                                        == svn_node_dir),
                                                       pool)));

  if (noderev->prop_rep)
    SVN_ERR (svn_stream_printf (outfile, pool, HEADER_PROPS ": %s\n",
                                representation_string (noderev->prop_rep, TRUE,
                                                       pool)));

  SVN_ERR (svn_stream_printf (outfile, pool, HEADER_CPATH ": %s\n",
                              noderev->created_path));

  if (noderev->copyfrom_path)
    SVN_ERR (svn_stream_printf (outfile, pool, HEADER_COPYFROM ": %ld"
                                " %s\n",
                                noderev->copyfrom_rev,
                                noderev->copyfrom_path));

  if ((noderev->copyroot_rev != svn_fs_fs__id_rev (noderev->id)) ||
      (strcmp (noderev->copyroot_path, noderev->created_path) != 0))
    SVN_ERR (svn_stream_printf (outfile, pool, HEADER_COPYROOT ": %ld"
                                " %s\n",
                                noderev->copyroot_rev,
                                noderev->copyroot_path));

  SVN_ERR (svn_stream_printf (outfile, pool, "\n"));

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_fs__put_node_revision (svn_fs_t *fs,
                              const svn_fs_id_t *id,
                              node_revision_t *noderev,
                              apr_pool_t *pool)
{
  apr_file_t *noderev_file;
  const char *txn_id = svn_fs_fs__id_txn_id (id);

⌨️ 快捷键说明

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