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

📄 update.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 4 页
字号:
  const char *path;
  svn_revnum_t revision;

  /* Try to use the CR, assuming the path exists in CR. */
  path = get_real_fs_path(baton, pool);
  revision = dav_svn_get_safe_cr(baton->uc->rev_root, path, pool);
    
  href = dav_svn_build_uri(baton->uc->resource->info->repos,
                           DAV_SVN_BUILD_URI_VERSION,
                           revision, path, 0 /* add_href */, pool);
  
  return send_xml(baton->uc, "<D:checked-in><D:href>%s</D:href></D:checked-in>"
                  DEBUG_CR, apr_xml_quote_string (pool, href, 1));
}

static svn_error_t * absent_helper(svn_boolean_t is_dir,
                                   const char *path,
                                   item_baton_t *parent,
                                   apr_pool_t *pool)
{
  update_ctx_t *uc = parent->uc;

  if (! uc->resource_walk)
    {
      const char *elt = apr_psprintf(pool,
                                     "<S:absent-%s name=\"%s\"/>" DEBUG_CR,
                                     DIR_OR_FILE(is_dir),
                                     svn_path_basename(path, pool));
      SVN_ERR( send_xml(uc, "%s", elt) );
    }

  return SVN_NO_ERROR;
}


static svn_error_t * upd_absent_directory(const char *path,
                                          void *parent_baton,
                                          apr_pool_t *pool)
{
  return absent_helper(TRUE, path, parent_baton, pool);
}


static svn_error_t * upd_absent_file(const char *path,
                                     void *parent_baton,
                                     apr_pool_t *pool)
{
  return absent_helper(FALSE, path, parent_baton, pool);
}


static svn_error_t * add_helper(svn_boolean_t is_dir,
                                const char *path,
                                item_baton_t *parent,
                                const char *copyfrom_path,
                                svn_revnum_t copyfrom_revision,
                                apr_pool_t *pool,
                                void **child_baton)
{
  item_baton_t *child;
  update_ctx_t *uc = parent->uc;
  const char *bc_url = NULL;

  child = make_child_baton(parent, path, pool);
  child->added = TRUE;

  if (uc->resource_walk)
    {
      SVN_ERR( send_xml(child->uc, "<S:resource path=\"%s\">" DEBUG_CR, 
                        apr_xml_quote_string(pool, child->path3, 1)) );
    }
  else
    {
      const char *qname = apr_xml_quote_string(pool, child->name, 1);
      const char *elt;
      const char *real_path = get_real_fs_path(child, pool);

      if (! is_dir)
        {
          /* files have checksums */
          unsigned char digest[APR_MD5_DIGESTSIZE];
          SVN_ERR (svn_fs_file_md5_checksum
                   (digest, uc->rev_root, real_path, pool));
          
          child->text_checksum = svn_md5_digest_to_cstring(digest, pool);
        }
      else
        {
          /* we send baseline-collection urls when we add a directory */
          svn_revnum_t revision;
          revision = dav_svn_get_safe_cr(child->uc->rev_root, real_path, pool);
          bc_url = dav_svn_build_uri(child->uc->resource->info->repos,
                                     DAV_SVN_BUILD_URI_BC,
                                     revision, real_path,
                                     0 /* add_href */, pool);

          /* ugh, build_uri ignores the path and just builds the root
             of the baseline collection.  we have to tack the
             real_path on manually, ignoring its leading slash. */
          if (real_path && (! svn_path_is_empty(real_path)))
            bc_url = svn_path_url_add_component(bc_url, real_path+1, pool);

          /* make sure that the BC_URL is xml attribute safe. */
          bc_url = apr_xml_quote_string(pool, bc_url, 1);
        }


      if (copyfrom_path == NULL)
        {
          if (bc_url)            
            elt = apr_psprintf(pool, "<S:add-%s name=\"%s\" "
                               "bc-url=\"%s\">" DEBUG_CR,
                               DIR_OR_FILE(is_dir), qname, bc_url);
          else
            elt = apr_psprintf(pool, "<S:add-%s name=\"%s\">" DEBUG_CR,
                               DIR_OR_FILE(is_dir), qname);
        }
      else
        {
          const char *qcopy = apr_xml_quote_string(pool, copyfrom_path, 1);

          if (bc_url)
            elt = apr_psprintf(pool, "<S:add-%s name=\"%s\" "
                               "copyfrom-path=\"%s\" copyfrom-rev=\"%ld\" "
                               "bc-url=\"%s\">" DEBUG_CR,
                               DIR_OR_FILE(is_dir),
                               qname, qcopy, copyfrom_revision,
                               bc_url);
          else
            elt = apr_psprintf(pool, "<S:add-%s name=\"%s\" "
                               "copyfrom-path=\"%s\""
                               " copyfrom-rev=\"%ld\">" DEBUG_CR,
                               DIR_OR_FILE(is_dir),
                               qname, qcopy, copyfrom_revision);
        }

      /* Resist the temptation to pass 'elt' as the format string.
         Because it contains URIs, it might have sequences that look
         like format string insert placeholders.  For example,
         "this%20dir" is a valid printf() format string that means
         "this[insert an integer of width 20 here]ir". */
      SVN_ERR( send_xml(child->uc, "%s", elt) );
    }

  SVN_ERR( send_vsn_url(child, pool) );

  if (uc->resource_walk)
    SVN_ERR( send_xml(child->uc, "</S:resource>" DEBUG_CR) );

  *child_baton = child;

  return SVN_NO_ERROR;
}

static svn_error_t * open_helper(svn_boolean_t is_dir,
                                 const char *path,
                                 item_baton_t *parent,
                                 svn_revnum_t base_revision,
                                 apr_pool_t *pool,
                                 void **child_baton)
{
  item_baton_t *child = make_child_baton(parent, path, pool);
  const char *qname = apr_xml_quote_string(pool, child->name, 1);

  SVN_ERR( send_xml(child->uc, "<S:open-%s name=\"%s\""
                    " rev=\"%ld\">" DEBUG_CR,
                    DIR_OR_FILE(is_dir), qname, base_revision));
  SVN_ERR( send_vsn_url(child, pool) );
  *child_baton = child;
  return SVN_NO_ERROR;
}

static svn_error_t * close_helper(svn_boolean_t is_dir, item_baton_t *baton)
{
  int i;
  
  if (baton->uc->resource_walk)
    return SVN_NO_ERROR;

  /* ### ack!  binary names won't float here! */
  if (baton->removed_props && (! baton->added))
    {
      const char *qname;

      for (i = 0; i < baton->removed_props->nelts; i++)
        {
          /* We already XML-escaped the property name in change_xxx_prop. */
          qname = ((const char **)(baton->removed_props->elts))[i];
          SVN_ERR( send_xml(baton->uc, "<S:remove-prop name=\"%s\"/>" 
                            DEBUG_CR, qname) );
        }
    }

  if ((! baton->uc->send_all) && baton->changed_props && (! baton->added))
    {
      /* Tell the client to fetch all the props */
      SVN_ERR( send_xml(baton->uc, "<S:fetch-props/>" DEBUG_CR) );
    }

  SVN_ERR( send_xml(baton->uc, "<S:prop>") );

  /* Both modern and non-modern clients need the checksum... */
  if (baton->text_checksum)
    {
      SVN_ERR( send_xml(baton->uc, "<V:md5-checksum>%s</V:md5-checksum>", 
                        baton->text_checksum) );
    }

  /* ...but only non-modern clients want the 3 CR-related properties
     sent like here, because they can't handle receiving these special
     props inline like any other prop.
     ### later on, compress via the 'scattered table' solution as
     discussed with gstein.  -bmcs */
  if (! baton->uc->send_all)
    {
      /* ### grrr, these DAV: property names are already #defined in
         ra_dav.h, and statically defined in liveprops.c.  And now
         they're hardcoded here.  Isn't there some header file that both
         sides of the network can share?? */
      
      /* ### special knowledge: svn_repos_dir_delta will never send
       *removals* of the commit-info "entry props". */
      if (baton->committed_rev)
        SVN_ERR( send_xml(baton->uc, "<D:version-name>%s</D:version-name>",
                          baton->committed_rev) );
      
      if (baton->committed_date)
        SVN_ERR( send_xml(baton->uc, "<D:creationdate>%s</D:creationdate>",
                          baton->committed_date) );
      
      if (baton->last_author)
        SVN_ERR( send_xml(baton->uc,
                          "<D:creator-displayname>%s</D:creator-displayname>",
                          baton->last_author) );

    }

  /* Close unconditionally, because we sent checksum unconditionally. */
  SVN_ERR( send_xml(baton->uc, "</S:prop>\n") );
    
  if (baton->added)
    SVN_ERR( send_xml(baton->uc, "</S:add-%s>" DEBUG_CR, 
                      DIR_OR_FILE(is_dir)) );
  else
    SVN_ERR( send_xml(baton->uc, "</S:open-%s>" DEBUG_CR, 
                      DIR_OR_FILE(is_dir)) );
  return SVN_NO_ERROR;
}


/* Send the opening tag of the update-report if it hasn't been sent
   already.

   Note: because send_xml does not return an error, this function
   never returns error either.  However, its prototype anticipates a
   day when send_xml() can return error. */
static svn_error_t * maybe_start_update_report(update_ctx_t *uc)
{
  if ((! uc->resource_walk) && (! uc->started_update))
    {
      SVN_ERR( send_xml(uc,
                        DAV_XML_HEADER DEBUG_CR
                        "<S:update-report xmlns:S=\"" SVN_XML_NAMESPACE "\" "
                        "xmlns:V=\"" SVN_DAV_PROP_NS_DAV "\" "
                        "xmlns:D=\"DAV:\" %s>" DEBUG_CR,
                        uc->send_all ? "send-all=\"true\"" : "") );
      
      uc->started_update = TRUE;
    }

  return SVN_NO_ERROR;
}


static svn_error_t * upd_set_target_revision(void *edit_baton,
                                             svn_revnum_t target_revision,
                                             apr_pool_t *pool)
{
  update_ctx_t *uc = edit_baton;

  SVN_ERR( maybe_start_update_report(uc) );

  if (! uc->resource_walk)
    SVN_ERR( send_xml(uc, "<S:target-revision rev=\"%ld"
                      "\"/>" DEBUG_CR, target_revision) );

  return SVN_NO_ERROR;
}

static svn_error_t * upd_open_root(void *edit_baton,
                                   svn_revnum_t base_revision,
                                   apr_pool_t *pool,
                                   void **root_baton)
{
  update_ctx_t *uc = edit_baton;
  item_baton_t *b = apr_pcalloc(pool, sizeof(*b));

  /* note that we create a subpool; the root_baton is passed to the
     close_directory callback, where we will destroy the pool. */

  b->uc = uc;
  b->pool = pool;
  b->path = uc->anchor;
  b->path2 = uc->dst_path;
  b->path3 = "";

  *root_baton = b;

  SVN_ERR( maybe_start_update_report(uc) );

  if (uc->resource_walk)
    {
      const char *qpath = apr_xml_quote_string(pool, b->path3, 1);
      SVN_ERR( send_xml(uc, "<S:resource path=\"%s\">" DEBUG_CR, qpath) );
    }
  else    
    {
      SVN_ERR( send_xml(uc, "<S:open-directory rev=\"%ld\">"
                        DEBUG_CR, base_revision) );
    }

  /* Only transmit the root directory's Version Resource URL if
     there's no target. */
  if (! *uc->target)
    SVN_ERR( send_vsn_url(b, pool) );

  if (uc->resource_walk)
    SVN_ERR( send_xml(uc, "</S:resource>" DEBUG_CR) );

  return SVN_NO_ERROR;
}

static svn_error_t * upd_delete_entry(const char *path,
                                      svn_revnum_t revision,
                                      void *parent_baton,
                                      apr_pool_t *pool)
{
  item_baton_t *parent = parent_baton;
  const char *qname = apr_xml_quote_string(pool, 
                                           svn_path_basename(path, pool), 1);
  return send_xml(parent->uc, "<S:delete-entry name=\"%s\"/>" DEBUG_CR, qname);
}

static svn_error_t * upd_add_directory(const char *path,
                                       void *parent_baton,
                                       const char *copyfrom_path,
                                       svn_revnum_t copyfrom_revision,
                                       apr_pool_t *pool,
                                       void **child_baton)
{
  return add_helper(TRUE /* is_dir */,
                    path, parent_baton, copyfrom_path, copyfrom_revision, pool,
                    child_baton);
}

static svn_error_t * upd_open_directory(const char *path,
                                        void *parent_baton,
                                        svn_revnum_t base_revision,
                                        apr_pool_t *pool,
                                        void **child_baton)
{
  open_helper(TRUE /* is_dir */,
              path, parent_baton, base_revision, pool, child_baton);
  return SVN_NO_ERROR;
}

static svn_error_t * upd_change_xxx_prop(void *baton,
                                         const char *name,
                                         const svn_string_t *value,
                                         apr_pool_t *pool)
{
  item_baton_t *b = baton;
  const char *qname;

  /* Resource walks say nothing about props. */
  if (b->uc->resource_walk)
    return SVN_NO_ERROR;

⌨️ 快捷键说明

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