コード例 #1
0
ファイル: time-test.c プロジェクト: aosm/subversion
static svn_error_t *
test_time_invariant(const char **msg,
                    svn_boolean_t msg_only,
                    svn_test_opts_t *opts,
                    apr_pool_t *pool)
{
  apr_time_t current_timestamp = apr_time_now();
  const char *timestring;
  apr_time_t timestamp;

  *msg = "test svn_time_[to/from]_cstring() invariant";

  if (msg_only)
    return SVN_NO_ERROR;

  timestring = svn_time_to_cstring(current_timestamp, pool);
  SVN_ERR(svn_time_from_cstring(&timestamp, timestring, pool));

  if (timestamp != current_timestamp)
    {
      return svn_error_createf
        (SVN_ERR_TEST_FAILED, NULL,
         "svn_time_from_cstring ( svn_time_to_cstring (n) ) returned time '%"
         APR_TIME_T_FMT
         "' instead of '%" APR_TIME_T_FMT "'",
         timestamp,current_timestamp);
    }

  return SVN_NO_ERROR;
}
コード例 #2
0
ファイル: time-test.c プロジェクト: aosm/subversion
static svn_error_t *
test_time_from_cstring(const char **msg,
                       svn_boolean_t msg_only,
                       svn_test_opts_t *opts,
                       apr_pool_t *pool)
{
  apr_time_t timestamp;

  *msg = "test svn_time_from_cstring";

  if (msg_only)
    return SVN_NO_ERROR;

  SVN_ERR(svn_time_from_cstring(&timestamp, test_timestring, pool));

  if (timestamp != test_timestamp)
    {
      return svn_error_createf
        (SVN_ERR_TEST_FAILED, NULL,
         "svn_time_from_cstring (%s) returned time '%" APR_TIME_T_FMT
         "' instead of '%" APR_TIME_T_FMT "'",
         test_timestring,timestamp,test_timestamp);
    }

  return SVN_NO_ERROR;
}
コード例 #3
0
ファイル: fs-wrap.c プロジェクト: sessaidi/freebsd
svn_error_t *
svn_repos__validate_prop(const char *name,
                         const svn_string_t *value,
                         apr_pool_t *pool)
{
    svn_prop_kind_t kind = svn_property_kind2(name);

    /* Allow deleting any property, even a property we don't allow to set. */
    if (value == NULL)
        return SVN_NO_ERROR;

    /* Disallow setting non-regular properties. */
    if (kind != svn_prop_regular_kind)
        return svn_error_createf
               (SVN_ERR_REPOS_BAD_ARGS, NULL,
                _("Storage of non-regular property '%s' is disallowed through the "
                  "repository interface, and could indicate a bug in your client"),
                name);

    /* Validate "svn:" properties. */
    if (svn_prop_is_svn_prop(name) && value != NULL)
    {
        /* Validate that translated props (e.g., svn:log) are UTF-8 with
         * LF line endings. */
        if (svn_prop_needs_translation(name))
        {
            if (!svn_utf__is_valid(value->data, value->len))
            {
                return svn_error_createf
                       (SVN_ERR_BAD_PROPERTY_VALUE, NULL,
                        _("Cannot accept '%s' property because it is not encoded in "
                          "UTF-8"), name);
            }

            /* Disallow inconsistent line ending style, by simply looking for
             * carriage return characters ('\r'). */
            if (strchr(value->data, '\r') != NULL)
            {
                return svn_error_createf
                       (SVN_ERR_BAD_PROPERTY_VALUE, NULL,
                        _("Cannot accept non-LF line endings in '%s' property"),
                        name);
            }
        }

        /* "svn:date" should be a valid date. */
        if (strcmp(name, SVN_PROP_REVISION_DATE) == 0)
        {
            apr_time_t temp;
            svn_error_t *err;

            err = svn_time_from_cstring(&temp, value->data, pool);
            if (err)
                return svn_error_create(SVN_ERR_BAD_PROPERTY_VALUE,
                                        err, NULL);
        }
    }

    return SVN_NO_ERROR;
}
コード例 #4
0
ファイル: dump.c プロジェクト: mommel/alien-svn
/* Helper for svn_repos_dump_fs.

   Write a revision record of REV in FS to writable STREAM, using POOL.
 */
static svn_error_t *
write_revision_record(svn_stream_t *stream,
                      svn_fs_t *fs,
                      svn_revnum_t rev,
                      apr_pool_t *pool)
{
  apr_size_t len;
  apr_hash_t *props;
  svn_stringbuf_t *encoded_prophash;
  apr_time_t timetemp;
  svn_string_t *datevalue;
  svn_stream_t *propstream;

  /* Read the revision props even if we're aren't going to dump
     them for verification purposes */
  SVN_ERR(svn_fs_revision_proplist(&props, fs, rev, pool));

  /* Run revision date properties through the time conversion to
     canonicalize them. */
  /* ### Remove this when it is no longer needed for sure. */
  datevalue = apr_hash_get(props, SVN_PROP_REVISION_DATE,
                           APR_HASH_KEY_STRING);
  if (datevalue)
    {
      SVN_ERR(svn_time_from_cstring(&timetemp, datevalue->data, pool));
      datevalue = svn_string_create(svn_time_to_cstring(timetemp, pool),
                                    pool);
      apr_hash_set(props, SVN_PROP_REVISION_DATE, APR_HASH_KEY_STRING,
                   datevalue);
    }

  encoded_prophash = svn_stringbuf_create_ensure(0, pool);
  propstream = svn_stream_from_stringbuf(encoded_prophash, pool);
  SVN_ERR(svn_hash_write2(props, propstream, "PROPS-END", pool));
  SVN_ERR(svn_stream_close(propstream));

  /* ### someday write a revision-content-checksum */

  SVN_ERR(svn_stream_printf(stream, pool,
                            SVN_REPOS_DUMPFILE_REVISION_NUMBER
                            ": %ld\n", rev));
  SVN_ERR(svn_stream_printf(stream, pool,
                            SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH
                            ": %" APR_SIZE_T_FMT "\n",
                            encoded_prophash->len));

  /* Write out a regular Content-length header for the benefit of
     non-Subversion RFC-822 parsers. */
  SVN_ERR(svn_stream_printf(stream, pool,
                            SVN_REPOS_DUMPFILE_CONTENT_LENGTH
                            ": %" APR_SIZE_T_FMT "\n\n",
                            encoded_prophash->len));

  len = encoded_prophash->len;
  SVN_ERR(svn_stream_write(stream, encoded_prophash->data, &len));

  len = 1;
  return svn_stream_write(stream, "\n", &len);
}
コード例 #5
0
ファイル: time-test.c プロジェクト: aosm/subversion
static svn_error_t *
test_time_from_cstring_old(const char **msg,
                           svn_boolean_t msg_only,
                           svn_test_opts_t *opts,
                           apr_pool_t *pool)
{
  apr_time_t timestamp;
  const char **ft;

  *msg = "test svn_time_from_cstring (old format)";

  if (msg_only)
    return SVN_NO_ERROR;

  SVN_ERR(svn_time_from_cstring(&timestamp, test_old_timestring, pool));

  if (timestamp != test_timestamp)
    {
      return svn_error_createf
        (SVN_ERR_TEST_FAILED, NULL,
         "svn_time_from_cstring (%s) returned time '%" APR_TIME_T_FMT
         "' instead of '%" APR_TIME_T_FMT "'",
         test_old_timestring,timestamp,test_timestamp);
    }

    /* These tests should fail.  They've been added to cover a string overflow
     * found in our code.  However, even if they fail that may not indicate
     * that there is no problem.  The strings being tested need to be
     * sufficently long to cause a segmentation fault in order to exercise
     * this bug.  Unfortunately due to differences in compilers, architectures,
     * etc. there is no way to be sure that the bug is being exerercised on
     * all platforms. */
    for (ft = failure_old_tests; *ft; ft++)
      {
        svn_error_t *err = svn_time_from_cstring(&timestamp, *ft, pool);
        if (! err)
          return svn_error_createf
            (SVN_ERR_TEST_FAILED, NULL,
             "svn_time_from_cstring (%s) succeeded when it should have failed",
             *ft);
        svn_error_clear(err);
      }

  return SVN_NO_ERROR;
}
コード例 #6
0
ファイル: svn-log-command.c プロジェクト: VujinovM/anjuta
static svn_error_t *
log_callback (void *baton,
			  apr_hash_t *changed_paths,
			  svn_revnum_t revision,
			  const char *author,
			  const char *date,
			  const char *message,
			  apr_pool_t *pool)
{
	SvnLogCommand *self;
	SvnLogEntry *log_entry;
	gchar *entry_author;
	const gchar *human_date;
	gchar *entry_date;
	apr_time_t entry_time;
	gchar *entry_message;
	
	self = SVN_LOG_COMMAND (baton);
	
	/* Libsvn docs say author, date, and message might be NULL. */
	if (author)
		entry_author = g_strdup (author);
	else 
		entry_author = g_strdup ("(none)");
	
	if (date && date[0])
	{
		svn_time_from_cstring (&entry_time, date,
							   svn_command_get_pool (SVN_COMMAND (self)));
		human_date = svn_time_to_human_cstring (entry_time,
												svn_command_get_pool (SVN_COMMAND (self)));
		entry_date = g_strdup (human_date);
	}
	else
		entry_date = g_strdup ("(none)");
	
	if (message)
		entry_message = g_strdup (message);
	else
		entry_message = g_strdup ("empty log message"); /* Emulate ViewCVS */
	
	log_entry = svn_log_entry_new (entry_author, entry_date, revision, 
								   entry_message);

	g_free (entry_author);
	g_free (entry_date);
	g_free (entry_message);
	
	anjuta_async_command_lock (ANJUTA_ASYNC_COMMAND (self));
	g_queue_push_head (self->priv->log_entry_queue, log_entry);
	anjuta_async_command_unlock (ANJUTA_ASYNC_COMMAND (self));
	
	anjuta_command_notify_data_arrived (ANJUTA_COMMAND (self));
	
	return SVN_NO_ERROR;
}
コード例 #7
0
ファイル: log_entry.cpp プロジェクト: MIRAvzw/svnqt
  void LogEntry::setDate(const char*date_)
  {
      apr_time_t date__ = 0;
      if (date_ != 0)
      {
          Pool pool;

          if (svn_time_from_cstring (&date__, date_, pool) != 0)
              date__ = 0;
      }
      date = date__;
  }
コード例 #8
0
ファイル: old-and-busted.c プロジェクト: Ranga123/test1
/* Read a timestamp from [*BUF, END) stopping at the terminator.
   Set *RESULT to the resulting timestamp, or 0 if there is none.  Use
   POOL for temporary allocations.  Make *BUF point after the
   terminator. */
static svn_error_t *
read_time(apr_time_t *result,
          char **buf, const char *end,
          apr_pool_t *pool)
{
    const char *val;

    SVN_ERR(read_val(&val, buf, end));
    if (val)
        SVN_ERR(svn_time_from_cstring(result, val, pool));
    else
        *result = 0;

    return SVN_NO_ERROR;
}
コード例 #9
0
ファイル: util.c プロジェクト: 2asoft/freebsd
svn_error_t *
svn_cl__time_cstring_to_human_cstring(const char **human_cstring,
                                      const char *data,
                                      apr_pool_t *pool)
{
  svn_error_t *err;
  apr_time_t when;

  err = svn_time_from_cstring(&when, data, pool);
  if (err && err->apr_err == SVN_ERR_BAD_DATE)
    {
      svn_error_clear(err);

      *human_cstring = _("(invalid date)");
      return SVN_NO_ERROR;
    }
  else if (err)
    return svn_error_trace(err);

  *human_cstring = svn_time_to_human_cstring(when, pool);

  return SVN_NO_ERROR;
}
コード例 #10
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. */
dav_error *
dav_svn__dated_rev_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, SVN_DAV__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_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0,
                                "The request does not contain a valid "
                                "'DAV:" SVN_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_svn__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:" SVN_DAV__VERSION_NAME ">%ld</D:"
                       SVN_DAV__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);

  return dav_svn__final_flush_or_error(resource->info->r, bb, output,
                                       derr, resource->pool);
}
コード例 #11
0
svn_error_t* CSVNLogQuery::LogReceiver ( void *baton
                                       , svn_log_entry_t *log_entry
                                       , apr_pool_t *pool)
{
    // a few globals

    static const std::string svnLog (SVN_PROP_REVISION_LOG);
    static const std::string svnDate (SVN_PROP_REVISION_DATE);
    static const std::string svnAuthor (SVN_PROP_REVISION_AUTHOR);

    // just in case ...

    if (log_entry == NULL)
        return NULL;

    // where to send the pre-processed in-format

    SBaton* receiverBaton = reinterpret_cast<SBaton*>(baton);
    ILogReceiver* receiver = receiverBaton->receiver;
    assert (receiver != NULL);

    // parse revprops

    std::string author;
    std::string message;
    __time64_t timeStamp = 0;

    UserRevPropArray userRevProps;

    try
    {
        if (   (log_entry->revision != SVN_INVALID_REVNUM)
            && (log_entry->revprops != NULL))
        {
            for ( apr_hash_index_t *index
                    = apr_hash_first (pool, log_entry->revprops)
                ; index != NULL
                ; index = apr_hash_next (index))
            {
                // extract next entry from hash

                const char* key = NULL;
                ptrdiff_t keyLen;
                const char** val = NULL;

                apr_hash_this ( index
                              , reinterpret_cast<const void**>(&key)
                              , &keyLen
                              , reinterpret_cast<void**>(&val));

                // decode / dispatch it

                std::string name = key;
                std::string value = *val;

                if (name == svnLog)
                    message = value;
                else if (name == svnAuthor)
                    author = value;
                else if (name == svnDate)
                {
                    timeStamp = NULL;
                    if (value[0])
                        SVN_ERR (svn_time_from_cstring (&timeStamp, *val, pool));
                }
                else
                {
                    userRevProps.Add (name, value);
                }
            }
        }
    }
    catch (CMemoryException * e)
    {
        e->Delete();
    }

    StandardRevProps standardRevProps (author, message, timeStamp);

    // the individual changes

    TChangedPaths changedPaths;
    try
    {
        if (log_entry->changed_paths2 != NULL)
        {
            apr_array_header_t *sorted_paths
                = svn_sort__hash (log_entry->changed_paths2, svn_sort_compare_items_as_paths, pool);

            for (int i = 0, count = sorted_paths->nelts; i < count; ++i)
            {
                changedPaths.push_back (SChangedPath());
                SChangedPath& entry = changedPaths.back();

                // find the item in the hash

                svn_sort__item_t *item = &(APR_ARRAY_IDX ( sorted_paths
                    , i
                    , svn_sort__item_t));

                // extract the path name

                entry.path = SVN::MakeUIUrlOrPath ((const char *)item->key);

                // decode the action

                svn_log_changed_path2_t *log_item
                    = (svn_log_changed_path2_t *) apr_hash_get ( log_entry->changed_paths2
                    , item->key
                    , item->klen);
                static const char actionKeys[7] = "AMRDVE";
                const char* actionKey = strchr (actionKeys, log_item->action);

                entry.action = actionKey == NULL
                    ? 0
                    : 1 << (actionKey - actionKeys);

                // node type

                entry.nodeKind = log_item->node_kind;

                // decode copy-from info

                if (    log_item->copyfrom_path
                     && SVN_IS_VALID_REVNUM (log_item->copyfrom_rev))
                {
                    entry.copyFromPath = SVN::MakeUIUrlOrPath (log_item->copyfrom_path);
                    entry.copyFromRev = log_item->copyfrom_rev;
                }
                else
                {
                    entry.copyFromRev = 0;
                }

                entry.text_modified = log_item->text_modified;
                entry.props_modified = log_item->props_modified;
            }
        }
        else if (log_entry->changed_paths != NULL)
        {
            apr_array_header_t *sorted_paths
                = svn_sort__hash (log_entry->changed_paths, svn_sort_compare_items_as_paths, pool);

            for (int i = 0, count = sorted_paths->nelts; i < count; ++i)
            {
                changedPaths.push_back (SChangedPath());
                SChangedPath& entry = changedPaths.back();

                // find the item in the hash

                svn_sort__item_t *item = &(APR_ARRAY_IDX ( sorted_paths
                                                         , i
                                                         , svn_sort__item_t));

                // extract the path name

                entry.path = SVN::MakeUIUrlOrPath ((const char *)item->key);

                // decode the action

                svn_log_changed_path_t *log_item
                    = (svn_log_changed_path_t *) apr_hash_get ( log_entry->changed_paths
                                                              , item->key
                                                              , item->klen);
                static const char actionKeys[7] = "AMRDVE";
                const char* actionKey = strchr (actionKeys, log_item->action);

                entry.action = actionKey == NULL
                    ? 0
                    : 1 << (actionKey - actionKeys);

                // node type

                entry.nodeKind = svn_node_unknown;

                // decode copy-from info

                if (    log_item->copyfrom_path
                     && SVN_IS_VALID_REVNUM (log_item->copyfrom_rev))
                {
                    entry.copyFromPath = SVN::MakeUIUrlOrPath (log_item->copyfrom_path);
                    entry.copyFromRev = log_item->copyfrom_rev;
                }
                else
                {
                    entry.copyFromRev = 0;
                }

                entry.text_modified = svn_tristate_unknown;
                entry.props_modified = svn_tristate_unknown;
            }
        }
    }
    catch (CMemoryException * e)
    {
        e->Delete();
    }

    // now, report the change

    try
    {
        // treat revision 0 special: only report/show it if either the author or a message is set, or if user props are set
        if (   log_entry->revision
            || userRevProps.GetCount()
            || !standardRevProps.GetAuthor().empty()
            || !standardRevProps.GetMessage().empty())
        {
            MergeInfo mergeInfo = { log_entry->has_children != FALSE
                                  , log_entry->non_inheritable != FALSE
                                  , log_entry->subtractive_merge != FALSE };

            receiver->ReceiveLog ( receiverBaton->includeChanges
                                       ? &changedPaths
                                       : NULL
                                 , log_entry->revision
                                 , receiverBaton->includeStandardRevProps
                                       ? &standardRevProps
                                       : NULL
                                 , receiverBaton->includeUserRevProps
                                       ? &userRevProps
                                       : NULL
                                 , &mergeInfo);
        }
    }
    catch (SVNError& e)
    {
        return svn_error_create (e.GetCode(), NULL, e.GetMessage());
    }
    catch (...)
    {
        // we must not leak exceptions back into SVN
    }

    return NULL;
}
コード例 #12
0
ファイル: list.c プロジェクト: svn2github/subversion
/* Conforms to svn_ra_serf__xml_closed_t  */
static svn_error_t *
item_closed(svn_ra_serf__xml_estate_t *xes,
            void *baton,
            int leaving_state,
            const svn_string_t *cdata,
            apr_hash_t *attrs,
            apr_pool_t *scratch_pool)
{
  list_context_t *list_ctx = baton;

  if (leaving_state == AUTHOR)
    {
      /* For compatibility with liveprops, current servers will not use
       * base64-encoding for "binary" user names bu simply drop the
       * offending control chars.
       *
       * We might want to switch to revprop-style encoding, though,
       * and this is the code to do that. */
      const char *encoding = svn_hash_gets(attrs, "encoding");
      if (encoding)
        {
          /* Check for a known encoding type.  This is easy -- there's
             only one.  */
          if (strcmp(encoding, "base64") != 0)
            {
              return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                                       _("Unsupported encoding '%s'"),
                                       encoding);
            }

          cdata = svn_base64_decode_string(cdata, scratch_pool);
        }

      /* Remember until the next ITEM closing tag. */
      svn_stringbuf_set(list_ctx->author_buf, cdata->data);
      list_ctx->author = list_ctx->author_buf->data;
    }
  else if (leaving_state == ITEM)
    {
      const char *dirent_path = cdata->data;
      const char *kind_word, *date, *crev, *size;
      svn_dirent_t dirent = { 0 };

      kind_word = svn_hash_gets(attrs, "node-kind");
      size = svn_hash_gets(attrs, "size");

      dirent.has_props = svn_hash__get_bool(attrs, "has-props", FALSE);
      crev = svn_hash_gets(attrs, "created-rev");
      date = svn_hash_gets(attrs, "date");

      /* Convert data. */
      dirent.kind = svn_node_kind_from_word(kind_word);

      if (size)
        SVN_ERR(svn_cstring_atoi64(&dirent.size, size));
      else
        dirent.size = SVN_INVALID_FILESIZE;

      if (crev)
        SVN_ERR(svn_revnum_parse(&dirent.created_rev, crev, NULL));
      else
        dirent.created_rev = SVN_INVALID_REVNUM;

      if (date)
        SVN_ERR(svn_time_from_cstring(&dirent.time, date, scratch_pool));

      if (list_ctx->author)
        dirent.last_author = list_ctx->author;

      /* Invoke RECEIVER */
      SVN_ERR(list_ctx->receiver(dirent_path, &dirent,
                                 list_ctx->receiver_baton, scratch_pool));

      /* Reset buffered info. */
      list_ctx->author = NULL;
    }

  return SVN_NO_ERROR;
}
コード例 #13
0
/* Given a mod_dav_svn @a resource, set @a *timeval and @a *datestring
   to the last-modified-time of the resource.  The datestring will be
   formatted according to @a format.  Use @a pool for both
   scratchwork, and to allocate @a *datestring.

   If @a timeval or @a datestring is NULL, don't touch it.

   Return zero on success, non-zero if an error occurs. */
static int
get_last_modified_time(const char **datestring,
                       apr_time_t *timeval,
                       const dav_resource *resource,
                       enum time_format format,
                       apr_pool_t *pool)
{
  svn_revnum_t committed_rev = SVN_INVALID_REVNUM;
  svn_string_t *committed_date = NULL;
  svn_error_t *serr;
  apr_time_t timeval_tmp;

  if ((datestring == NULL) && (timeval == NULL))
    return 0;

  if (resource->baselined && resource->type == DAV_RESOURCE_TYPE_VERSION)
    {
      /* A baseline URI. */
      committed_rev = resource->info->root.rev;
    }
  else if (resource->type == DAV_RESOURCE_TYPE_REGULAR
           || resource->type == DAV_RESOURCE_TYPE_WORKING
           || resource->type == DAV_RESOURCE_TYPE_VERSION)
    {
      serr = svn_fs_node_created_rev(&committed_rev,
                                     resource->info->root.root,
                                     resource->info->repos_path, pool);
      if (serr != NULL)
        {
          svn_error_clear(serr);
          return 1;
        }
    }
  else
    {
      /* unsupported resource kind -- has no mod-time */
      return 1;
    }

  serr = get_path_revprop(&committed_date,
                          resource,
                          committed_rev,
                          SVN_PROP_REVISION_DATE,
                          pool);
  if (serr)
    {
      svn_error_clear(serr);
      return 1;
    }

  if (committed_date == NULL)
    return 1;

  /* return the ISO8601 date as an apr_time_t */
  serr = svn_time_from_cstring(&timeval_tmp, committed_date->data, pool);
  if (serr != NULL)
    {
      svn_error_clear(serr);
      return 1;
    }

  if (timeval)
    memcpy(timeval, &timeval_tmp, sizeof(*timeval));

  if (! datestring)
    return 0;

  if (format == time_format_iso8601)
    {
      *datestring = committed_date->data;
    }
  else if (format == time_format_rfc1123)
    {
      apr_time_exp_t tms;
      apr_status_t status;

      /* convert the apr_time_t into an apr_time_exp_t */
      status = apr_time_exp_gmt(&tms, timeval_tmp);
      if (status != APR_SUCCESS)
        return 1;

      /* stolen from dav/fs/repos.c   :-)  */
      *datestring = apr_psprintf(pool, "%s, %.2d %s %d %.2d:%.2d:%.2d GMT",
                                 apr_day_snames[tms.tm_wday],
                                 tms.tm_mday, apr_month_snames[tms.tm_mon],
                                 tms.tm_year + 1900,
                                 tms.tm_hour, tms.tm_min, tms.tm_sec);
    }
  else /* unknown time format */
    {
      return 1;
    }

  return 0;
}
コード例 #14
0
svn_error_t *
svn_client_cat2(svn_stream_t *out,
                const char *path_or_url,
                const svn_opt_revision_t *peg_revision,
                const svn_opt_revision_t *revision,
                svn_client_ctx_t *ctx,
                apr_pool_t *pool)
{
  svn_ra_session_t *ra_session;
  svn_revnum_t rev;
  svn_string_t *eol_style;
  svn_string_t *keywords;
  apr_hash_t *props;
  const char *url;
  svn_stream_t *output = out;
  svn_error_t *err;

  /* ### Inconsistent default revision logic in this command. */
  if (peg_revision->kind == svn_opt_revision_unspecified)
    {
      peg_revision = svn_cl__rev_default_to_head_or_working(peg_revision,
                                                            path_or_url);
      revision = svn_cl__rev_default_to_head_or_base(revision, path_or_url);
    }
  else
    {
      peg_revision = svn_cl__rev_default_to_head_or_working(peg_revision,
                                                            path_or_url);
      revision = svn_cl__rev_default_to_peg(revision, peg_revision);
    }

  if (! svn_path_is_url(path_or_url)
      && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(peg_revision->kind)
      && SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(revision->kind))
    {
      const char *local_abspath;
      svn_stream_t *normal_stream;

      SVN_ERR(svn_dirent_get_absolute(&local_abspath, path_or_url, pool));
      SVN_ERR(svn_client__get_normalized_stream(&normal_stream, ctx->wc_ctx,
                                            local_abspath, revision, TRUE, FALSE,
                                            ctx->cancel_func, ctx->cancel_baton,
                                            pool, pool));

      /* We don't promise to close output, so disown it to ensure we don't. */
      output = svn_stream_disown(output, pool);

      return svn_error_trace(svn_stream_copy3(normal_stream, output,
                                              ctx->cancel_func,
                                              ctx->cancel_baton, pool));
    }

  /* Get an RA plugin for this filesystem object. */
  SVN_ERR(svn_client__ra_session_from_path(&ra_session, &rev,
                                           &url, path_or_url, NULL,
                                           peg_revision,
                                           revision, ctx, pool));

  /* Grab some properties we need to know in order to figure out if anything
     special needs to be done with this file. */
  err = svn_ra_get_file(ra_session, "", rev, NULL, NULL, &props, pool);
  if (err)
    {
      if (err->apr_err == SVN_ERR_FS_NOT_FILE)
        {
          return svn_error_createf(SVN_ERR_CLIENT_IS_DIRECTORY, err,
                                   _("URL '%s' refers to a directory"), url);
        }
      else
        {
          return svn_error_trace(err);
        }
    }

  eol_style = apr_hash_get(props, SVN_PROP_EOL_STYLE, APR_HASH_KEY_STRING);
  keywords = apr_hash_get(props, SVN_PROP_KEYWORDS, APR_HASH_KEY_STRING);

  if (eol_style || keywords)
    {
      /* It's a file with no special eol style or keywords. */
      svn_subst_eol_style_t eol;
      const char *eol_str;
      apr_hash_t *kw;

      if (eol_style)
        svn_subst_eol_style_from_value(&eol, &eol_str, eol_style->data);
      else
        {
          eol = svn_subst_eol_style_none;
          eol_str = NULL;
        }


      if (keywords)
        {
          svn_string_t *cmt_rev, *cmt_date, *cmt_author;
          apr_time_t when = 0;

          cmt_rev = apr_hash_get(props, SVN_PROP_ENTRY_COMMITTED_REV,
                                 APR_HASH_KEY_STRING);
          cmt_date = apr_hash_get(props, SVN_PROP_ENTRY_COMMITTED_DATE,
                                  APR_HASH_KEY_STRING);
          cmt_author = apr_hash_get(props, SVN_PROP_ENTRY_LAST_AUTHOR,
                                    APR_HASH_KEY_STRING);
          if (cmt_date)
            SVN_ERR(svn_time_from_cstring(&when, cmt_date->data, pool));

          SVN_ERR(svn_subst_build_keywords2
                  (&kw, keywords->data,
                   cmt_rev->data,
                   url,
                   when,
                   cmt_author ? cmt_author->data : NULL,
                   pool));
        }
      else
        kw = NULL;

      /* Interject a translating stream */
      output = svn_subst_stream_translated(svn_stream_disown(out, pool),
                                           eol_str, FALSE, kw, TRUE, pool);
    }

  SVN_ERR(svn_ra_get_file(ra_session, "", rev, output, NULL, NULL, pool));

  if (out != output)
    /* Close the interjected stream */
    SVN_ERR(svn_stream_close(output));

  return SVN_NO_ERROR;
}
コード例 #15
0
/* Parse the file at DIGEST_PATH, populating the lock LOCK_P in that
   file (if it exists, and if *LOCK_P is non-NULL) and the hash of
   CHILDREN_P (if any exist, and if *CHILDREN_P is non-NULL).  Use POOL
   for all allocations.  */
static svn_error_t *
read_digest_file(apr_hash_t **children_p,
                 svn_lock_t **lock_p,
                 const char *fs_path,
                 const char *digest_path,
                 apr_pool_t *pool)
{
  svn_error_t *err = SVN_NO_ERROR;
  svn_lock_t *lock;
  apr_hash_t *hash;
  svn_stream_t *stream;
  const char *val;

  if (lock_p)
    *lock_p = NULL;
  if (children_p)
    *children_p = apr_hash_make(pool);

  err = svn_stream_open_readonly(&stream, digest_path, pool, pool);
  if (err && APR_STATUS_IS_ENOENT(err->apr_err))
    {
      svn_error_clear(err);
      return SVN_NO_ERROR;
    }
  SVN_ERR(err);

  /* If our caller doesn't care about anything but the presence of the
     file... whatever. */
  if (! (lock_p || children_p))
    return svn_stream_close(stream);

  hash = apr_hash_make(pool);
  if ((err = svn_hash_read2(hash, stream, SVN_HASH_TERMINATOR, pool)))
    {
      svn_error_clear(svn_stream_close(stream));
      return svn_error_createf(err->apr_err,
                               err,
                               _("Can't parse lock/entries hashfile '%s'"),
                               svn_dirent_local_style(digest_path, pool));
    }
  SVN_ERR(svn_stream_close(stream));

  /* If our caller cares, see if we have a lock path in our hash. If
     so, we'll assume we have a lock here. */
  val = hash_fetch(hash, PATH_KEY, pool);
  if (val && lock_p)
    {
      const char *path = val;

      /* Create our lock and load it up. */
      lock = svn_lock_create(pool);
      lock->path = path;

      if (! ((lock->token = hash_fetch(hash, TOKEN_KEY, pool))))
        return svn_error_trace(err_corrupt_lockfile(fs_path, path));

      if (! ((lock->owner = hash_fetch(hash, OWNER_KEY, pool))))
        return svn_error_trace(err_corrupt_lockfile(fs_path, path));

      if (! ((val = hash_fetch(hash, IS_DAV_COMMENT_KEY, pool))))
        return svn_error_trace(err_corrupt_lockfile(fs_path, path));
      lock->is_dav_comment = (val[0] == '1');

      if (! ((val = hash_fetch(hash, CREATION_DATE_KEY, pool))))
        return svn_error_trace(err_corrupt_lockfile(fs_path, path));
      SVN_ERR(svn_time_from_cstring(&(lock->creation_date), val, pool));

      if ((val = hash_fetch(hash, EXPIRATION_DATE_KEY, pool)))
        SVN_ERR(svn_time_from_cstring(&(lock->expiration_date), val, pool));

      lock->comment = hash_fetch(hash, COMMENT_KEY, pool);

      *lock_p = lock;
    }

  /* If our caller cares, see if we have any children for this path. */
  val = hash_fetch(hash, CHILDREN_KEY, pool);
  if (val && children_p)
    {
      apr_array_header_t *kiddos = svn_cstring_split(val, "\n", FALSE, pool);
      int i;

      for (i = 0; i < kiddos->nelts; i++)
        {
          apr_hash_set(*children_p, APR_ARRAY_IDX(kiddos, i, const char *),
                       APR_HASH_KEY_STRING, (void *)1);
        }
    }
コード例 #16
0
ファイル: props.c プロジェクト: aosm/subversion
svn_error_t *
svn_ra_neon__do_stat(svn_ra_session_t *session,
                     const char *path,
                     svn_revnum_t revision,
                     svn_dirent_t **dirent,
                     apr_pool_t *pool)
{
  svn_ra_neon__session_t *ras = session->priv;
  const char *url = ras->url->data;
  const char *final_url;
  apr_hash_t *resources;
  apr_hash_index_t *hi;
  svn_error_t *err;

  /* If we were given a relative path to append, append it. */
  if (path)
    url = svn_path_url_add_component(url, path, pool);

  /* Invalid revision means HEAD, which is just the public URL. */
  if (! SVN_IS_VALID_REVNUM(revision))
    {
      final_url = url;
    }
  else
    {
      /* Else, convert (rev, path) into an opaque server-generated URL. */
      svn_string_t bc_url, bc_relative;

      err = svn_ra_neon__get_baseline_info(NULL, &bc_url, &bc_relative,
                                           NULL, ras,
                                           url, revision, pool);
      if (err)
        {
          if (err->apr_err == SVN_ERR_FS_NOT_FOUND)
            {
              /* easy out: */
              svn_error_clear(err);
              *dirent = NULL;
              return SVN_NO_ERROR;
            }
          else
            return err;
        }

      final_url = svn_path_url_add_component(bc_url.data, bc_relative.data,
                                             pool);
    }

  /* Depth-zero PROPFIND is the One True DAV Way. */
  err = svn_ra_neon__get_props(&resources, ras, final_url,
                               SVN_RA_NEON__DEPTH_ZERO,
                               NULL, NULL /* all props */, pool);
  if (err)
    {
      if (err->apr_err == SVN_ERR_FS_NOT_FOUND)
        {
          /* easy out: */
          svn_error_clear(err);
          *dirent = NULL;
          return SVN_NO_ERROR;
        }
      else
        return err;
    }

  /* Copying parsing code from svn_ra_neon__get_dir() here.  The hash
     of resources only contains one item, but there's no other way to
     get the item. */
  for (hi = apr_hash_first(pool, resources); hi; hi = apr_hash_next(hi))
    {
      void *val;
      svn_ra_neon__resource_t *resource;
      const svn_string_t *propval;
      apr_hash_index_t *h;
      svn_dirent_t *entry;

      apr_hash_this(hi, NULL, NULL, &val);
      resource = val;

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

      entry->kind = resource->is_collection ? svn_node_dir : svn_node_file;

      /* entry->size is already 0 by virtue of pcalloc(). */
      if (entry->kind == svn_node_file)
        {
          propval = apr_hash_get(resource->propset,
                                 SVN_RA_NEON__PROP_GETCONTENTLENGTH,
                                 APR_HASH_KEY_STRING);
          if (propval)
            entry->size = svn__atoui64(propval->data);
        }

      /* does this resource contain any 'dead' properties? */
      for (h = apr_hash_first(pool, resource->propset);
           h; h = apr_hash_next(h))
        {
          const void *kkey;
          apr_hash_this(h, &kkey, NULL, NULL);

          if (strncmp((const char *)kkey, SVN_DAV_PROP_NS_CUSTOM,
                      sizeof(SVN_DAV_PROP_NS_CUSTOM) - 1) == 0)
            entry->has_props = TRUE;

          else if (strncmp((const char *)kkey, SVN_DAV_PROP_NS_SVN,
                           sizeof(SVN_DAV_PROP_NS_SVN) - 1) == 0)
            entry->has_props = TRUE;
        }

      /* created_rev & friends */
      propval = apr_hash_get(resource->propset,
                             SVN_RA_NEON__PROP_VERSION_NAME,
                             APR_HASH_KEY_STRING);
      if (propval != NULL)
        entry->created_rev = SVN_STR_TO_REV(propval->data);

      propval = apr_hash_get(resource->propset,
                             SVN_RA_NEON__PROP_CREATIONDATE,
                             APR_HASH_KEY_STRING);
      if (propval != NULL)
        SVN_ERR(svn_time_from_cstring(&(entry->time),
                                      propval->data, pool));

      propval = apr_hash_get(resource->propset,
                             SVN_RA_NEON__PROP_CREATOR_DISPLAYNAME,
                             APR_HASH_KEY_STRING);
      if (propval != NULL)
        entry->last_author = propval->data;

      *dirent = entry;
    }

  return SVN_NO_ERROR;
}
コード例 #17
0
ファイル: getlocks.c プロジェクト: ChaosJohn/freebsd
/* Conforms to svn_ra_serf__xml_closed_t  */
static svn_error_t *
getlocks_closed(svn_ra_serf__xml_estate_t *xes,
                void *baton,
                int leaving_state,
                const svn_string_t *cdata,
                apr_hash_t *attrs,
                apr_pool_t *scratch_pool)
{
  lock_context_t *lock_ctx = baton;

  if (leaving_state == LOCK)
    {
      const char *path = svn_hash_gets(attrs, "path");
      svn_boolean_t save_lock = FALSE;

      /* Filter out unwanted paths.  Since Subversion only allows
         locks on files, we can treat depth=immediates the same as
         depth=files for filtering purposes.  Meaning, we'll keep
         this lock if:

         a) its path is the very path we queried, or
         b) we've asked for a fully recursive answer, or
         c) we've asked for depth=files or depth=immediates, and this
            lock is on an immediate child of our query path.
      */
      if (strcmp(lock_ctx->path, path) == 0
          || lock_ctx->requested_depth == svn_depth_infinity)
        {
          save_lock = TRUE;
        }
      else if (lock_ctx->requested_depth == svn_depth_files
               || lock_ctx->requested_depth == svn_depth_immediates)
        {
          const char *relpath = svn_fspath__skip_ancestor(lock_ctx->path,
                                                          path);
          if (relpath && (svn_path_component_count(relpath) == 1))
            save_lock = TRUE;
        }

      if (save_lock)
        {
          /* We get to put the structure on the stack rather than using
             svn_lock_create(). Bwahahaha....   */
          svn_lock_t lock = { 0 };
          const char *date;
          svn_lock_t *result_lock;

          /* Note: these "attributes" came from child elements. Some of
             them may have not been sent, so the value will be NULL.  */

          lock.path = path;
          lock.token = svn_hash_gets(attrs, "token");
          lock.owner = svn_hash_gets(attrs, "owner");
          lock.comment = svn_hash_gets(attrs, "comment");

          date = svn_hash_gets(attrs, SVN_DAV__CREATIONDATE);
          if (date)
            SVN_ERR(svn_time_from_cstring(&lock.creation_date, date,
                                          scratch_pool));

          date = svn_hash_gets(attrs, "expirationdate");
          if (date)
            SVN_ERR(svn_time_from_cstring(&lock.expiration_date, date,
                                          scratch_pool));

          result_lock = svn_lock_dup(&lock, lock_ctx->pool);
          svn_hash_sets(lock_ctx->hash, result_lock->path, result_lock);
        }
    }
  else
    {
      const char *name;

      SVN_ERR_ASSERT(cdata != NULL);

      if (leaving_state == PATH)
        name = "path";
      else if (leaving_state == TOKEN)
        name = "token";
      else if (leaving_state == OWNER)
        name = "owner";
      else if (leaving_state == COMMENT)
        name = "comment";
      else if (leaving_state == CREATION_DATE)
        name = SVN_DAV__CREATIONDATE;
      else if (leaving_state == EXPIRATION_DATE)
        name = "expirationdate";
      else
        SVN_ERR_MALFUNCTION();

      /* Store the lock information onto the LOCK elemstate.  */
      svn_ra_serf__xml_note(xes, LOCK, name, cdata->data);
    }

  return SVN_NO_ERROR;
}
コード例 #18
0
ファイル: ra_plugin.c プロジェクト: aosm/subversion
/* Getting a directory's entries */
static svn_error_t *
svn_ra_local__get_dir(svn_ra_session_t *session,
                      apr_hash_t **dirents,
                      svn_revnum_t *fetched_rev,
                      apr_hash_t **props,
                      const char *path,
                      svn_revnum_t revision,
                      apr_uint32_t dirent_fields,
                      apr_pool_t *pool)
{
  svn_fs_root_t *root;
  svn_revnum_t youngest_rev;
  apr_hash_t *entries;
  apr_hash_index_t *hi;
  svn_ra_local__session_baton_t *sess = session->priv;
  apr_pool_t *subpool;
  const char *abs_path = svn_path_join(sess->fs_path->data, path, pool);

  /* Open the revision's root. */
  if (! SVN_IS_VALID_REVNUM(revision))
    {
      SVN_ERR(svn_fs_youngest_rev(&youngest_rev, sess->fs, pool));
      SVN_ERR(svn_fs_revision_root(&root, sess->fs, youngest_rev, pool));
      if (fetched_rev != NULL)
        *fetched_rev = youngest_rev;
    }
  else
    SVN_ERR(svn_fs_revision_root(&root, sess->fs, revision, pool));

  if (dirents)
    {
      /* Get the dir's entries. */
      SVN_ERR(svn_fs_dir_entries(&entries, root, abs_path, pool));

      /* Loop over the fs dirents, and build a hash of general
         svn_dirent_t's. */
      *dirents = apr_hash_make(pool);
      subpool = svn_pool_create(pool);
      for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi))
        {
          const void *key;
          void *val;
          apr_hash_t *prophash;
          const char *datestring, *entryname, *fullpath;
          svn_fs_dirent_t *fs_entry;
          svn_dirent_t *entry = apr_pcalloc(pool, sizeof(*entry));

          svn_pool_clear(subpool);

          apr_hash_this(hi, &key, NULL, &val);
          entryname = (const char *) key;
          fs_entry = (svn_fs_dirent_t *) val;

          fullpath = svn_path_join(abs_path, entryname, subpool);

          if (dirent_fields & SVN_DIRENT_KIND)
            {
              /* node kind */
              entry->kind = fs_entry->kind;
            }

          if (dirent_fields & SVN_DIRENT_SIZE)
            {
              /* size  */
              if (entry->kind == svn_node_dir)
                entry->size = 0;
              else
                SVN_ERR(svn_fs_file_length(&(entry->size), root,
                                           fullpath, subpool));
            }

          if (dirent_fields & SVN_DIRENT_HAS_PROPS)
            {
              /* has_props? */
              SVN_ERR(svn_fs_node_proplist(&prophash, root, fullpath,
                                           subpool));
              entry->has_props = (apr_hash_count(prophash) != 0);
            }

          if ((dirent_fields & SVN_DIRENT_TIME)
              || (dirent_fields & SVN_DIRENT_LAST_AUTHOR)
              || (dirent_fields & SVN_DIRENT_CREATED_REV))
            {
              /* created_rev & friends */
              SVN_ERR(svn_repos_get_committed_info(&(entry->created_rev),
                                                   &datestring,
                                                   &(entry->last_author),
                                                   root, fullpath, subpool));
              if (datestring)
                SVN_ERR(svn_time_from_cstring(&(entry->time), datestring,
                                              pool));
              if (entry->last_author)
                entry->last_author = apr_pstrdup(pool, entry->last_author);
            }

          /* Store. */
          apr_hash_set(*dirents, entryname, APR_HASH_KEY_STRING, entry);
        }
      svn_pool_destroy(subpool);
    }

  /* Handle props if requested. */
  if (props)
    SVN_ERR(get_node_props(props, sess, root, abs_path, pool));

  return SVN_NO_ERROR;
}
コード例 #19
0
/* This implements the `svn_ra_neon__endelm_cb_t' prototype. */
static svn_error_t *
getlocks_end_element(void *userdata, int state,
                     const char *ns, const char *ln)
{
  get_locks_baton_t *baton = userdata;
  const svn_ra_neon__xml_elm_t *elm;

  elm = svn_ra_neon__lookup_xml_elem(getlocks_report_elements, ns, ln);

  /* Just skip unknown elements. */
  if (elm == NULL)
    return SVN_NO_ERROR;

  switch (elm->id)
    {
    case ELEM_lock:
      /* is the final svn_lock_t valid?  all fields must be present
         except for 'comment' and 'expiration_date'. */
      if ((! baton->current_lock->path)
          || (! baton->current_lock->token)
          || (! baton->current_lock->owner)
          || (! baton->current_lock->creation_date))
        SVN_ERR(svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                                 _("Incomplete lock data returned")));

      /* Filter out unwanted paths.  Since Subversion only allows
         locks on files, we can treat depth=immediates the same as
         depth=files for filtering purposes.  Meaning, we'll keep
         this lock if:

         a) its path is the very path we queried, or
         b) we've asked for a fully recursive answer, or
         c) we've asked for depth=files or depth=immediates, and this
            lock is on an immediate child of our query path.
      */
      if ((strcmp(baton->path, baton->current_lock->path) == 0)
          || (baton->requested_depth == svn_depth_infinity))
        {
          apr_hash_set(baton->lock_hash, baton->current_lock->path,
                       APR_HASH_KEY_STRING, baton->current_lock);
        }
      else if ((baton->requested_depth == svn_depth_files) ||
               (baton->requested_depth == svn_depth_immediates))
        {
          const char *rel_uri = svn_fspath__is_child(baton->path,
                                                     baton->current_lock->path,
                                                     baton->scratchpool);
          if (rel_uri && (svn_path_component_count(rel_uri) == 1))
            apr_hash_set(baton->lock_hash, baton->current_lock->path,
                         APR_HASH_KEY_STRING, baton->current_lock);
          svn_pool_clear(baton->scratchpool);
        }
      break;

    case ELEM_lock_path:
      /* neon has already xml-unescaped the cdata for us. */
      baton->current_lock->path =
        svn_fspath__canonicalize(apr_pstrmemdup(baton->scratchpool,
                                                baton->cdata_accum->data,
                                                baton->cdata_accum->len),
                                 baton->pool);

      /* clean up the accumulator. */
      svn_stringbuf_setempty(baton->cdata_accum);
      svn_pool_clear(baton->scratchpool);
      break;

    case ELEM_lock_token:
      /* neon has already xml-unescaped the cdata for us. */
      baton->current_lock->token = apr_pstrmemdup(baton->pool,
                                                  baton->cdata_accum->data,
                                                  baton->cdata_accum->len);
      /* clean up the accumulator. */
      svn_stringbuf_setempty(baton->cdata_accum);
      svn_pool_clear(baton->scratchpool);
      break;

    case ELEM_lock_creationdate:
      SVN_ERR(svn_time_from_cstring(&(baton->current_lock->creation_date),
                                    baton->cdata_accum->data,
                                    baton->scratchpool));
      /* clean up the accumulator. */
      svn_stringbuf_setempty(baton->cdata_accum);
      svn_pool_clear(baton->scratchpool);
      break;

    case ELEM_lock_expirationdate:
      SVN_ERR(svn_time_from_cstring(&(baton->current_lock->expiration_date),
                                    baton->cdata_accum->data,
                                    baton->scratchpool));
      /* clean up the accumulator. */
      svn_stringbuf_setempty(baton->cdata_accum);
      svn_pool_clear(baton->scratchpool);
      break;

    case ELEM_lock_owner:
    case ELEM_lock_comment:
      {
        const char *final_val;

        if (baton->encoding)
          {
            /* Possibly recognize other encodings someday. */
            if (strcmp(baton->encoding, "base64") == 0)
              {
                svn_string_t *encoded_val;
                const svn_string_t *decoded_val;

                encoded_val = svn_string_create_from_buf(baton->cdata_accum,
                                                         baton->scratchpool);
                decoded_val = svn_base64_decode_string(encoded_val,
                                                       baton->scratchpool);
                final_val = decoded_val->data;
              }
            else
              return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA,
                                       NULL,
                                       _("Got unrecognized encoding '%s'"),
                                       baton->encoding);

            baton->encoding = NULL;
          }
        else
          {
            /* neon has already xml-unescaped the cdata for us. */
            final_val = baton->cdata_accum->data;
          }

        if (elm->id == ELEM_lock_owner)
          baton->current_lock->owner = apr_pstrdup(baton->pool, final_val);
        if (elm->id == ELEM_lock_comment)
          baton->current_lock->comment = apr_pstrdup(baton->pool, final_val);

        /* clean up the accumulator. */
        svn_stringbuf_setempty(baton->cdata_accum);
        svn_pool_clear(baton->scratchpool);
        break;
      }


    default:
      break;
    }

  return SVN_NO_ERROR;
}
コード例 #20
0
ファイル: old-and-busted.c プロジェクト: Ranga123/test1
/* NOTE: this is used for upgrading old XML-based entries file. Be wary of
         removing items.

   ### many attributes are no longer used within the old-style log files.
   ### These attrs need to be recognized for old entries, however. For these
   ### cases, the code will parse the attribute, but not set *MODIFY_FLAGS
   ### for that particular field. MODIFY_FLAGS is *only* used by the
   ### log-based entry modification system, and will go way once we
   ### completely move away from loggy.

   Set *NEW_ENTRY to a new entry, taking attributes from ATTS, whose
   keys and values are both char *.  Allocate the entry and copy
   attributes into POOL as needed. */
static svn_error_t *
atts_to_entry(svn_wc_entry_t **new_entry,
              apr_hash_t *atts,
              apr_pool_t *pool)
{
    svn_wc_entry_t *entry = alloc_entry(pool);
    const char *name;

    /* Find the name and set up the entry under that name. */
    name = svn_hash_gets(atts, ENTRIES_ATTR_NAME);
    entry->name = name ? apr_pstrdup(pool, name) : SVN_WC_ENTRY_THIS_DIR;

    /* Attempt to set revision (resolve_to_defaults may do it later, too)

       ### not used by loggy; no need to set MODIFY_FLAGS  */
    {
        const char *revision_str
            = svn_hash_gets(atts, ENTRIES_ATTR_REVISION);

        if (revision_str)
            entry->revision = SVN_STR_TO_REV(revision_str);
        else
            entry->revision = SVN_INVALID_REVNUM;
    }

    /* Attempt to set up url path (again, see resolve_to_defaults).

       ### not used by loggy; no need to set MODIFY_FLAGS  */
    entry->url = extract_string(atts, ENTRIES_ATTR_URL, pool);
    if (entry->url)
        entry->url = svn_uri_canonicalize(entry->url, pool);

    /* Set up repository root.  Make sure it is a prefix of url.

       ### not used by loggy; no need to set MODIFY_FLAGS  */
    entry->repos = extract_string(atts, ENTRIES_ATTR_REPOS, pool);
    if (entry->repos)
        entry->repos = svn_uri_canonicalize(entry->repos, pool);

    if (entry->url && entry->repos
            && !svn_uri__is_ancestor(entry->repos, entry->url))
        return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
                                 _("Entry for '%s' has invalid repository "
                                   "root"),
                                 name ? name : SVN_WC_ENTRY_THIS_DIR);

    /* Set up kind. */
    /* ### not used by loggy; no need to set MODIFY_FLAGS  */
    {
        const char *kindstr
            = svn_hash_gets(atts, ENTRIES_ATTR_KIND);

        entry->kind = svn_node_none;
        if (kindstr)
        {
            if (strcmp(kindstr, ENTRIES_VALUE_FILE) == 0)
                entry->kind = svn_node_file;
            else if (strcmp(kindstr, ENTRIES_VALUE_DIR) == 0)
                entry->kind = svn_node_dir;
            else
                return svn_error_createf
                       (SVN_ERR_NODE_UNKNOWN_KIND, NULL,
                        _("Entry '%s' has invalid node kind"),
                        (name ? name : SVN_WC_ENTRY_THIS_DIR));
        }
    }

    /* Look for a schedule attribute on this entry. */
    /* ### not used by loggy; no need to set MODIFY_FLAGS  */
    {
        const char *schedulestr
            = svn_hash_gets(atts, ENTRIES_ATTR_SCHEDULE);

        entry->schedule = svn_wc_schedule_normal;
        if (schedulestr)
        {
            if (strcmp(schedulestr, ENTRIES_VALUE_ADD) == 0)
                entry->schedule = svn_wc_schedule_add;
            else if (strcmp(schedulestr, ENTRIES_VALUE_DELETE) == 0)
                entry->schedule = svn_wc_schedule_delete;
            else if (strcmp(schedulestr, ENTRIES_VALUE_REPLACE) == 0)
                entry->schedule = svn_wc_schedule_replace;
            else if (strcmp(schedulestr, "") == 0)
                entry->schedule = svn_wc_schedule_normal;
            else
                return svn_error_createf(
                           SVN_ERR_ENTRY_ATTRIBUTE_INVALID, NULL,
                           _("Entry '%s' has invalid 'schedule' value"),
                           (name ? name : SVN_WC_ENTRY_THIS_DIR));
        }
    }

    /* Is this entry in a state of mental torment (conflict)? */
    entry->prejfile = extract_string_normalize(atts,
                      ENTRIES_ATTR_PREJFILE,
                      pool);
    entry->conflict_old = extract_string_normalize(atts,
                          ENTRIES_ATTR_CONFLICT_OLD,
                          pool);
    entry->conflict_new = extract_string_normalize(atts,
                          ENTRIES_ATTR_CONFLICT_NEW,
                          pool);
    entry->conflict_wrk = extract_string_normalize(atts,
                          ENTRIES_ATTR_CONFLICT_WRK,
                          pool);

    /* Is this entry copied? */
    /* ### not used by loggy; no need to set MODIFY_FLAGS  */
    SVN_ERR(do_bool_attr(&entry->copied, atts, ENTRIES_ATTR_COPIED, name));

    /* ### not used by loggy; no need to set MODIFY_FLAGS  */
    entry->copyfrom_url = extract_string(atts, ENTRIES_ATTR_COPYFROM_URL, pool);

    /* ### not used by loggy; no need to set MODIFY_FLAGS  */
    {
        const char *revstr;

        revstr = svn_hash_gets(atts, ENTRIES_ATTR_COPYFROM_REV);
        if (revstr)
            entry->copyfrom_rev = SVN_STR_TO_REV(revstr);
    }

    /* Is this entry deleted?

       ### not used by loggy; no need to set MODIFY_FLAGS  */
    SVN_ERR(do_bool_attr(&entry->deleted, atts, ENTRIES_ATTR_DELETED, name));

    /* Is this entry absent?

       ### not used by loggy; no need to set MODIFY_FLAGS  */
    SVN_ERR(do_bool_attr(&entry->absent, atts, ENTRIES_ATTR_ABSENT, name));

    /* Is this entry incomplete?

       ### not used by loggy; no need to set MODIFY_FLAGS  */
    SVN_ERR(do_bool_attr(&entry->incomplete, atts, ENTRIES_ATTR_INCOMPLETE,
                         name));

    /* Attempt to set up timestamps. */
    /* ### not used by loggy; no need to set MODIFY_FLAGS  */
    {
        const char *text_timestr;

        text_timestr = svn_hash_gets(atts, ENTRIES_ATTR_TEXT_TIME);
        if (text_timestr)
            SVN_ERR(svn_time_from_cstring(&entry->text_time, text_timestr, pool));

        /* Note: we do not persist prop_time, so there is no need to attempt
           to parse a new prop_time value from the log. Certainly, on any
           recent working copy, there will not be a log record to alter
           the prop_time value. */
    }

    /* Checksum. */
    /* ### not used by loggy; no need to set MODIFY_FLAGS  */
    entry->checksum = extract_string(atts, ENTRIES_ATTR_CHECKSUM, pool);

    /* UUID.

       ### not used by loggy; no need to set MODIFY_FLAGS  */
    entry->uuid = extract_string(atts, ENTRIES_ATTR_UUID, pool);

    /* Setup last-committed values. */
    {
        const char *cmt_datestr, *cmt_revstr;

        cmt_datestr = svn_hash_gets(atts, ENTRIES_ATTR_CMT_DATE);
        if (cmt_datestr)
        {
            SVN_ERR(svn_time_from_cstring(&entry->cmt_date, cmt_datestr, pool));
        }
        else
            entry->cmt_date = 0;

        cmt_revstr = svn_hash_gets(atts, ENTRIES_ATTR_CMT_REV);
        if (cmt_revstr)
        {
            entry->cmt_rev = SVN_STR_TO_REV(cmt_revstr);
        }
        else
            entry->cmt_rev = SVN_INVALID_REVNUM;

        entry->cmt_author = extract_string(atts, ENTRIES_ATTR_CMT_AUTHOR, pool);
    }

    /* ### not used by loggy; no need to set MODIFY_FLAGS  */
    entry->lock_token = extract_string(atts, ENTRIES_ATTR_LOCK_TOKEN, pool);
    entry->lock_owner = extract_string(atts, ENTRIES_ATTR_LOCK_OWNER, pool);
    entry->lock_comment = extract_string(atts, ENTRIES_ATTR_LOCK_COMMENT, pool);
    {
        const char *cdate_str =
            svn_hash_gets(atts, ENTRIES_ATTR_LOCK_CREATION_DATE);
        if (cdate_str)
        {
            SVN_ERR(svn_time_from_cstring(&entry->lock_creation_date,
                                          cdate_str, pool));
        }
    }
    /* ----- end of lock handling.  */

    /* Note: if there are attributes for the (deprecated) has_props,
       has_prop_mods, cachable_props, or present_props, then we're just
       going to ignore them. */

    /* Translated size */
    /* ### not used by loggy; no need to set MODIFY_FLAGS  */
    {
        const char *val = svn_hash_gets(atts, ENTRIES_ATTR_WORKING_SIZE);
        if (val)
        {
            /* Cast to off_t; it's safe: we put in an off_t to start with... */
            entry->working_size = (apr_off_t)apr_strtoi64(val, NULL, 0);
        }
    }

    *new_entry = entry;
    return SVN_NO_ERROR;
}