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

📄 version.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 4 页
字号:
     long as that pool. */
  apr_pool_t *pool;
};


/* APR pool cleanup function to deltify against a just-committed
   revision.  DATA is a 'struct cleanup_deltify_baton *'.

   If any errors occur, log them in the httpd server error log, but
   return APR_SUCCESS no matter what, as this is a pool cleanup
   function and deltification is not a matter of correctness
   anyway. */
static apr_status_t cleanup_deltify(void *data)
{
  struct cleanup_deltify_baton *cdb = data;
  svn_repos_t *repos;
  svn_error_t *err;

  /* It's okay to allocate in the pool that's being cleaned up, and
     it's also okay to register new cleanups against that pool.  But
     if you create subpools of it, you must make sure to destroy them
     at the end of the cleanup.  So we do all our work in this
     subpool, then destroy it before exiting. */
  apr_pool_t *subpool = svn_pool_create(cdb->pool);

  err = svn_repos_open(&repos, cdb->repos_path, subpool);
  if (err)
    {
      ap_log_perror(APLOG_MARK, APLOG_ERR, err->apr_err, cdb->pool,
                    "cleanup_deltify: error opening repository '%s'",
                    cdb->repos_path);
      svn_error_clear(err);
      goto cleanup;
    }

  err = svn_fs_deltify_revision(svn_repos_fs(repos),
                                cdb->revision, subpool);
  if (err)
    {
      ap_log_perror(APLOG_MARK, APLOG_ERR, err->apr_err, cdb->pool,
                    "cleanup_deltify: error deltifying against revision %ld"
                    " in repository '%s'",
                    cdb->revision, cdb->repos_path);
      svn_error_clear(err);
    }

 cleanup:
  svn_pool_destroy(subpool);

  return APR_SUCCESS;
}


/* Register the cleanup_deltify function on POOL, which should be the
   connection pool for the request.  This way the time needed for
   deltification won't delay the response to the client.

   REPOS is the repository in which deltify, and REVISION is the
   revision against which to deltify.  POOL is both the pool on which
   to register the cleanup function and the pool that will be used for
   temporary allocations while deltifying. */
static void register_deltification_cleanup(svn_repos_t *repos,
                                           svn_revnum_t revision,
                                           apr_pool_t *pool)
{
  struct cleanup_deltify_baton *cdb = apr_palloc(pool, sizeof(*cdb));
  
  cdb->repos_path = svn_repos_path(repos, pool);
  cdb->revision = revision;
  cdb->pool = pool;
  
  apr_pool_cleanup_register(pool, cdb, cleanup_deltify, apr_pool_cleanup_null);
}


dav_error *dav_svn_checkin(dav_resource *resource,
                           int keep_checked_out,
                           dav_resource **version_resource)
{
  svn_error_t *serr;
  dav_error *err;
  const char *uri;

  /* ### mod_dav has a flawed architecture, in the sense that it first
     tries to auto-checkin the modified resource, then attempts to
     auto-checkin the parent resource (if the parent resource was
     auto-checked-out).  Instead, the provider should be in charge:
     mod_dav should provide a *set* of resources that need
     auto-checkin, and the provider can decide how to do it.  (One
     txn?  Many txns?  Etc.) */

  if (resource->type != DAV_RESOURCE_TYPE_WORKING)
    return dav_new_error_tag(resource->pool, HTTP_INTERNAL_SERVER_ERROR,
                             SVN_ERR_UNSUPPORTED_FEATURE,
                             "CHECKIN called on non-working resource.",
                             SVN_DAV_ERROR_NAMESPACE,
                             SVN_DAV_ERROR_TAG);

  /* Try to commit the txn if it exists. */
  if (resource->info->root.txn_name)
    {
      svn_fs_txn_t *txn;
      const char *conflict_msg;
      svn_revnum_t new_rev;

      err = open_txn(&txn, resource->info->repos->fs,
                     resource->info->root.txn_name, resource->pool);
      
      /* If we failed to open the txn, don't worry about it.  It may
         have already been committed when a child resource was
         checked in.  */
      if (! err)
        {
          err = set_auto_log_message(resource);
          if (err)
            return err;

          serr = svn_repos_fs_commit_txn(&conflict_msg,
                                         resource->info->repos->repos,
                                         &new_rev, 
                                         resource->info->root.txn,
                                         resource->pool);
          if (serr != NULL)
            {
              const char *msg;
              svn_error_clear(svn_fs_abort_txn(resource->info->root.txn,
                                               resource->pool));
              
              if (serr->apr_err == SVN_ERR_FS_CONFLICT)
                {
                  msg = apr_psprintf(resource->pool,
                                     "A conflict occurred during the CHECKIN "
                                     "processing. The problem occurred with  "
                                     "the \"%s\" resource.",
                                     conflict_msg);
                }
              else
                msg = "An error occurred while committing the transaction.";
              
              return dav_svn_convert_err(serr, HTTP_CONFLICT, msg,
                                         resource->pool);
            }

          /* Commit was successful, so schedule deltification. */
          register_deltification_cleanup(resource->info->repos->repos,
                                         new_rev,
                                         resource->info->r->connection->pool);

          /* If caller wants it, return the new VR that was created by
             the checkin. */
          if (version_resource)
            {
              uri = dav_svn_build_uri(resource->info->repos,
                                      DAV_SVN_BUILD_URI_VERSION,
                                      new_rev, resource->info->repos_path,
                                      0, resource->pool);

              err = dav_svn_create_version_resource(version_resource, uri,
                                                    resource->pool);
              if (err)
                return err;
            }
        }

      /* whether the txn was committed, aborted, or inaccessible,
         it's gone now.  the resource needs to lose all knowledge
         of it. */
      resource->info->root.txn_name = NULL;
      resource->info->root.txn = NULL;
    }

  /* Convert the working resource back into an regular one. */
  if (! keep_checked_out)
    {
      resource->info->auto_checked_out = FALSE;
      return dav_svn_working_to_regular_resource(resource);
    } 

  return NULL;
}

static dav_error *dav_svn_avail_reports(const dav_resource *resource,
                                        const dav_report_elem **reports)
{
  /* ### further restrict to the public space? */
  if (resource->type != DAV_RESOURCE_TYPE_REGULAR) {
    *reports = NULL;
    return NULL;
  }

  *reports = avail_reports;
  return NULL;
}

static int dav_svn_report_label_header_allowed(const apr_xml_doc *doc)
{
  return 0;
}

/* Respond to a S:dated-rev-report request.  The request contains a
 * DAV:creationdate element giving the requested date; the response
 * contains a DAV:version-name element giving the most recent revision
 * as of that date. */
static dav_error * dav_svn__drev_report(const dav_resource *resource,
                                        const apr_xml_doc *doc,
                                        ap_filter_t *output)
{
  apr_xml_elem *child;
  int ns;
  apr_time_t tm = (apr_time_t) -1;
  svn_revnum_t rev;
  apr_bucket_brigade *bb;
  svn_error_t *err;
  apr_status_t apr_err;
  dav_error *derr = NULL;

  /* Find the DAV:creationdate element and get the requested time from it. */
  ns = dav_svn_find_ns(doc->namespaces, "DAV:");
  if (ns != -1)
    {
      for (child = doc->root->first_child; child != NULL; child = child->next)
        {
          if (child->ns != ns || strcmp(child->name, "creationdate") != 0)
            continue;
          /* If this fails, we'll notice below, so ignore any error for now. */
          svn_error_clear
            (svn_time_from_cstring(&tm, dav_xml_get_cdata(child,
                                                          resource->pool, 1),
                                   resource->pool));
        }
    }

  if (tm == (apr_time_t) -1)
    {
      return dav_new_error(resource->pool, HTTP_BAD_REQUEST, 0,
                           "The request does not contain a valid "
                           "'DAV:creationdate' element.");
    }

  /* Do the actual work of finding the revision by date. */
  if ((err = svn_repos_dated_revision(&rev, resource->info->repos->repos, tm,
                                      resource->pool)) != SVN_NO_ERROR)
    {
      svn_error_clear (err);
      return dav_new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
                           "Could not access revision times.");
    }

  bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
  apr_err = ap_fprintf(output, bb,
                       DAV_XML_HEADER DEBUG_CR
                       "<S:dated-rev-report xmlns:S=\"" SVN_XML_NAMESPACE "\" "
                       "xmlns:D=\"DAV:\">" DEBUG_CR
                       "<D:version-name>%ld</D:version-name>"
                       "</S:dated-rev-report>", rev);
  if (apr_err)
    derr = dav_svn_convert_err(svn_error_create(apr_err, 0, NULL),
                               HTTP_INTERNAL_SERVER_ERROR,
                               "Error writing REPORT response.",
                               resource->pool);

  /* Flush the contents of the brigade (returning an error only if we
     don't already have one). */
  if (((apr_err = ap_fflush(output, bb))) && (! derr))
    derr = dav_svn_convert_err(svn_error_create(apr_err, 0, NULL),
                               HTTP_INTERNAL_SERVER_ERROR,
                               "Error flushing brigade.",
                               resource->pool);

  return derr;
}

static apr_status_t send_get_locations_report(ap_filter_t *output,
                                              apr_bucket_brigade *bb,
                                              const dav_resource *resource,
                                              apr_hash_t *fs_locations)
{
  apr_hash_index_t *hi;
  apr_pool_t *pool;
  apr_status_t apr_err;

  pool = resource->pool;

  apr_err = ap_fprintf(output, bb, DAV_XML_HEADER DEBUG_CR
                       "<S:get-locations-report xmlns:S=\"" SVN_XML_NAMESPACE
                       "\" xmlns:D=\"DAV:\">" DEBUG_CR);
  if (apr_err)
    return apr_err;

  for (hi = apr_hash_first(pool, fs_locations); hi; hi = apr_hash_next (hi))
    {
      const void *key;
      void *value;
      const char *path_quoted;

      apr_hash_this(hi, &key, NULL, &value);
      path_quoted = apr_xml_quote_string(pool, value, 1);
      apr_err = ap_fprintf(output, bb, "<S:location "
                           "rev=\"%ld\" path=\"%s\"/>" DEBUG_CR,
                           *(svn_revnum_t *)key, path_quoted);
      if (apr_err)
        return apr_err;
    }
  return ap_fprintf(output, bb, "</S:get-locations-report>" DEBUG_CR);
}

dav_error *dav_svn__get_locations_report(const dav_resource *resource,
                                         const apr_xml_doc *doc,
                                         ap_filter_t *output)

⌨️ 快捷键说明

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