Ejemplo n.º 1
0
svn_error_t *
svn_cl__try(svn_error_t *err,
            apr_array_header_t *errors_seen,
            svn_boolean_t quiet,
            ...)
{
  if (err)
    {
      apr_status_t apr_err;
      va_list ap;

      va_start(ap, quiet);
      while ((apr_err = va_arg(ap, apr_status_t)) != APR_SUCCESS)
        {
          if (errors_seen)
            {
              int i;
              svn_boolean_t add = TRUE;

              /* Don't report duplicate error codes. */
              for (i = 0; i < errors_seen->nelts; i++)
                {
                  if (APR_ARRAY_IDX(errors_seen, i,
                                    apr_status_t) == err->apr_err)
                    {
                      add = FALSE;
                      break;
                    }
                }
              if (add)
                APR_ARRAY_PUSH(errors_seen, apr_status_t) = err->apr_err;
            }
          if (err->apr_err == apr_err)
            {
              if (! quiet)
                svn_handle_warning2(stderr, err, "svn: ");
              svn_error_clear(err);
              return SVN_NO_ERROR;
            }
        }
      va_end(ap);
    }

  return svn_error_trace(err);
}
Ejemplo n.º 2
0
static void fcgi_write_response(mapcache_context_fcgi *ctx, mapcache_http_response *response)
{
  if(response->code != 200) {
    printf("Status: %ld %s\r\n",response->code, err_msg(response->code));
  }
  if(response->headers && !apr_is_empty_table(response->headers)) {
    const apr_array_header_t *elts = apr_table_elts(response->headers);
    int i;
    for(i=0; i<elts->nelts; i++) {
      apr_table_entry_t entry = APR_ARRAY_IDX(elts,i,apr_table_entry_t);
      printf("%s: %s\r\n", entry.key, entry.val);
    }
  }
  if(response->mtime) {
    char *datestr;
    char *if_modified_since = getenv("HTTP_IF_MODIFIED_SINCE");

    datestr = apr_palloc(ctx->ctx.pool, APR_RFC822_DATE_LEN);
    apr_rfc822_date(datestr, response->mtime);
    printf("Last-Modified: %s\r\n", datestr);

    if(if_modified_since) {
      apr_time_t ims_time;
      apr_int64_t ims,mtime;


      mtime =  apr_time_sec(response->mtime);
      ims_time = apr_date_parse_http(if_modified_since);
      ims = apr_time_sec(ims_time);
      if(ims >= mtime) {
        printf("Status: 304 Not Modified\r\n");
	/*
	 * "The 304 response MUST NOT contain a message-body"
	 * https://tools.ietf.org/html/rfc2616#section-10.3.5
	 */
	printf("\r\n");
	return;
      }
    }
  }
  if(response->data) {
    printf("Content-Length: %ld\r\n\r\n", response->data->size);
    fwrite((char*)response->data->buf, response->data->size,1,stdout);
  }
}
Ejemplo n.º 3
0
/** Modify codec list according to capabilities specified */
MPF_DECLARE(apt_bool_t) mpf_codec_list_modify(mpf_codec_list_t *codec_list, const mpf_codec_capabilities_t *capabilities)
{
    int i;
    mpf_codec_descriptor_t *descriptor;
    if(!capabilities) {
        return FALSE;
    }

    for(i=0; i<codec_list->descriptor_arr->nelts; i++) {
        descriptor = &APR_ARRAY_IDX(codec_list->descriptor_arr,i,mpf_codec_descriptor_t);
        /* match capabilities */
        if(!mpf_codec_capabilities_attribs_find(capabilities,descriptor)) {
            descriptor->enabled = FALSE;
        }
    }

    return TRUE;
}
Ejemplo n.º 4
0
svn_error_t *svn_ra_svn_set_capabilities(svn_ra_svn_conn_t *conn,
                                         const apr_array_header_t *list)
{
  int i;
  svn_ra_svn_item_t *item;
  const char *word;

  for (i = 0; i < list->nelts; i++)
    {
      item = &APR_ARRAY_IDX(list, i, svn_ra_svn_item_t);
      if (item->kind != SVN_RA_SVN_WORD)
        return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                _("Capability entry is not a word"));
      word = apr_pstrdup(conn->pool, item->u.word);
      apr_hash_set(conn->capabilities, word, APR_HASH_KEY_STRING, word);
    }
  return SVN_NO_ERROR;
}
Ejemplo n.º 5
0
/* Throw an SVN_ERR_CLIENT_IS_BINARY_FILE error if PROP_DIFFS indicates a
   binary MIME type.  Else, return SVN_NO_ERROR. */
static svn_error_t *
check_mimetype(const apr_array_header_t *prop_diffs, const char *target,
               apr_pool_t *pool)
{
  int i;

  for (i = 0; i < prop_diffs->nelts; ++i)
    {
      const svn_prop_t *prop = &APR_ARRAY_IDX(prop_diffs, i, svn_prop_t);
      if (strcmp(prop->name, SVN_PROP_MIME_TYPE) == 0
          && prop->value
          && svn_mime_type_is_binary(prop->value->data))
        return svn_error_createf
          (SVN_ERR_CLIENT_IS_BINARY_FILE, 0,
           _("Cannot calculate blame information for binary file '%s'"),
           svn_dirent_local_style(target, pool));
    }
  return SVN_NO_ERROR;
}
Ejemplo n.º 6
0
svn_error_t *
svn_fs_x__write_changes(svn_stream_t *stream,
                        svn_fs_t *fs,
                        apr_hash_t *changes,
                        svn_boolean_t terminate_list,
                        apr_pool_t *scratch_pool)
{
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
  apr_array_header_t *sorted_changed_paths;
  int i;

  /* For the sake of the repository administrator sort the changes so
     that the final file is deterministic and repeatable, however the
     rest of the FSX code doesn't require any particular order here.

     Also, this sorting is only effective in writing all entries with
     a single call as write_final_changed_path_info() does.  For the
     list being written incrementally during transaction, we actually
     *must not* change the order of entries from different calls.
   */
  sorted_changed_paths = svn_sort__hash(changes,
                                        svn_sort_compare_items_lexically,
                                        scratch_pool);

  /* Write all items to disk in the new order. */
  for (i = 0; i < sorted_changed_paths->nelts; ++i)
    {
      svn_fs_x__change_t *change;

      svn_pool_clear(iterpool);
      change = APR_ARRAY_IDX(sorted_changed_paths, i, svn_sort__item_t).value;

      /* Write out the new entry into the final rev-file. */
      SVN_ERR(write_change_entry(stream, change, iterpool));
    }

  if (terminate_list)
    svn_stream_puts(stream, "\n");

  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}
/* Implements svn_ra_serf__request_body_delegate_t */
static svn_error_t *
create_get_locations_body(serf_bucket_t **body_bkt,
                          void *baton,
                          serf_bucket_alloc_t *alloc,
                          apr_pool_t *pool)
{
    serf_bucket_t *buckets;
    loc_context_t *loc_ctx = baton;
    int i;

    buckets = serf_bucket_aggregate_create(alloc);

    svn_ra_serf__add_open_tag_buckets(buckets, alloc,
                                      "S:get-locations",
                                      "xmlns:S", SVN_XML_NAMESPACE,
                                      "xmlns:D", "DAV:",
                                      NULL);

    svn_ra_serf__add_tag_buckets(buckets,
                                 "S:path", loc_ctx->path,
                                 alloc);

    svn_ra_serf__add_tag_buckets(buckets,
                                 "S:peg-revision", apr_ltoa(pool, loc_ctx->peg_revision),
                                 alloc);

    for (i = 0; i < loc_ctx->location_revisions->nelts; i++)
    {
        svn_revnum_t rev = APR_ARRAY_IDX(loc_ctx->location_revisions, i, svn_revnum_t);
        svn_ra_serf__add_tag_buckets(buckets,
                                     "S:location-revision", apr_ltoa(pool, rev),
                                     alloc);
    }

    svn_ra_serf__add_close_tag_buckets(buckets, alloc,
                                       "S:get-locations");

    *body_bkt = buckets;
    return SVN_NO_ERROR;
}
Ejemplo n.º 8
0
/**
 * \private \memberof mapcache_source_wms
 * \sa mapcache_source::render_map()
 */
void _mapcache_source_wms_render_map(mapcache_context *ctx, mapcache_map *map)
{
  mapcache_source_wms *wms = (mapcache_source_wms*)map->tileset->source;
  apr_table_t *params = apr_table_clone(ctx->pool,wms->wms_default_params);
  apr_table_setn(params,"BBOX",apr_psprintf(ctx->pool,"%f,%f,%f,%f",
                 map->extent.minx,map->extent.miny,map->extent.maxx,map->extent.maxy));
  apr_table_setn(params,"WIDTH",apr_psprintf(ctx->pool,"%d",map->width));
  apr_table_setn(params,"HEIGHT",apr_psprintf(ctx->pool,"%d",map->height));
  apr_table_setn(params,"FORMAT","image/png");
  apr_table_setn(params,"SRS",map->grid_link->grid->srs);

  apr_table_overlap(params,wms->getmap_params,APR_OVERLAP_TABLES_SET);
  if(map->dimensions && !apr_is_empty_table(map->dimensions)) {
    const apr_array_header_t *elts = apr_table_elts(map->dimensions);
    int i;
    for(i=0; i<elts->nelts; i++) {
      apr_table_entry_t entry = APR_ARRAY_IDX(elts,i,apr_table_entry_t);
      apr_table_setn(params,entry.key,entry.val);
    }

  }

  /* if the source has no LAYERS parameter defined, then use the tileset name
   * as the LAYERS to request. When using mirror-mode, the source has no layers
   * defined, it is added based on the incoming request
   */
  if(!apr_table_get(params,"layers")) {
    apr_table_set(params,"LAYERS",map->tileset->name);
  }

  map->encoded_data = mapcache_buffer_create(30000,ctx->pool);
  mapcache_http_do_request_with_params(ctx,wms->http,params,map->encoded_data,NULL,NULL);
  GC_CHECK_ERROR(ctx);

  if(!mapcache_imageio_is_valid_format(ctx,map->encoded_data)) {
    char *returned_data = apr_pstrndup(ctx->pool,(char*)map->encoded_data->buf,map->encoded_data->size);
    ctx->set_error(ctx, 502, "wms request for tileset %s returned an unsupported format:\n%s",
                   map->tileset->name, returned_data);
  }
}
Ejemplo n.º 9
0
static dav_error *dav_acl_patch_exec(const dav_resource * resource,
                                     const apr_xml_elem * elem,
                                     int operation,
                                     void *context,
                                     dav_liveprop_rollback **rollback_ctx)
{
    dav_repos_resource *db_r = resource->info->db_r;
    const dav_repos_db *db = resource->info->db;
    dav_elem_private *priv = elem->priv;
    dav_error *err = NULL;

    if (priv->propid == DAV_PROPID_group_member_set) {
        apr_hash_t *new_members = (apr_hash_t*)context;
        apr_array_header_t *to_remove = (apr_array_header_t *)apr_hash_get
          (new_members, "-to-remove-", APR_HASH_KEY_STRING);
        apr_hash_set(new_members, "-to-remove-", APR_HASH_KEY_STRING, NULL);
        dav_repos_resource *prin = NULL;
        int i = 0;
        for (i = 0; to_remove && i < to_remove->nelts; i++) {
            prin = &APR_ARRAY_IDX(to_remove, i, dav_repos_resource);
            err = sabridge_rem_prin_frm_grp
              (db_r->p, db, db_r->serialno, prin->serialno);
            if (err) return err;
        }
        
        apr_hash_index_t *iter = apr_hash_first(db_r->p, new_members);
        while (iter) {
            apr_hash_this(iter, NULL, NULL, (void *)&prin);
            err = sabridge_add_prin_to_grp
              (db_r->p, db, db_r->serialno, prin->serialno);
            if (err) return err;
            iter = apr_hash_next(iter);
        }
    }
    return NULL;
}
Ejemplo n.º 10
0
static int _sqlite_set_pragmas(apr_pool_t *pool, mapcache_cache_sqlite* cache, struct sqlite_conn *conn)
{
  if (cache->pragmas && !apr_is_empty_table(cache->pragmas)) {
    const apr_array_header_t *elts = apr_table_elts(cache->pragmas);
    /* FIXME dynamically allocate this string */
    int i,ret;
    char *pragma_stmt;
    for (i = 0; i < elts->nelts; i++) {
      apr_table_entry_t entry = APR_ARRAY_IDX(elts, i, apr_table_entry_t);
      pragma_stmt = apr_psprintf(pool,"PRAGMA %s=%s",entry.key,entry.val);
      do {
        ret = sqlite3_exec(conn->handle, pragma_stmt, 0, 0, NULL);
        if (ret != SQLITE_OK && ret != SQLITE_BUSY && ret != SQLITE_LOCKED) {
          break;
        }
      } while (ret == SQLITE_BUSY || ret == SQLITE_LOCKED);
      if (ret != SQLITE_OK) {
        conn->errmsg = apr_psprintf(pool,"failed to execute pragma statement %s",pragma_stmt);
        return MAPCACHE_FAILURE;
      }
    }
  }
  return MAPCACHE_SUCCESS;
}
Ejemplo n.º 11
0
static int write_http_response(mapcache_context_apache_request *ctx, mapcache_http_response *response)
{
  request_rec *r = ctx->request;
  int rc;
  char *timestr;

  if(response->mtime) {
    ap_update_mtime(r, response->mtime);
    if((rc = ap_meets_conditions(r)) != OK) {
      return rc;
    }
    timestr = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
    apr_rfc822_date(timestr, response->mtime);
    apr_table_setn(r->headers_out, "Last-Modified", timestr);
  }
  if(response->headers && !apr_is_empty_table(response->headers)) {
    const apr_array_header_t *elts = apr_table_elts(response->headers);
    int i;
    for(i=0; i<elts->nelts; i++) {
      apr_table_entry_t entry = APR_ARRAY_IDX(elts,i,apr_table_entry_t);
      if(!strcasecmp(entry.key,"Content-Type")) {
        ap_set_content_type(r,entry.val);
      } else {
        apr_table_set(r->headers_out, entry.key, entry.val);
      }
    }
  }
  if(response->data) {
    ap_set_content_length(r,response->data->size);
    ap_rwrite((void*)response->data->buf, response->data->size, r);
  }

  r->status = response->code;
  return OK;

}
Ejemplo n.º 12
0
void _mapcache_source_wms_query(mapcache_context *ctx, mapcache_feature_info *fi)
{
  mapcache_map *map = (mapcache_map*)fi;
  mapcache_http *http;
  mapcache_source_wms *wms = (mapcache_source_wms*)map->tileset->source;

  apr_table_t *params = apr_table_clone(ctx->pool,wms->wms_default_params);
  apr_table_overlap(params,wms->getmap_params,0);
  apr_table_setn(params,"BBOX",apr_psprintf(ctx->pool,"%f,%f,%f,%f",
                 map->extent.minx,map->extent.miny,map->extent.maxx,map->extent.maxy));
  apr_table_setn(params,"REQUEST","GetFeatureInfo");
  apr_table_setn(params,"WIDTH",apr_psprintf(ctx->pool,"%d",map->width));
  apr_table_setn(params,"HEIGHT",apr_psprintf(ctx->pool,"%d",map->height));
  apr_table_setn(params,"SRS",map->grid_link->grid->srs);
  apr_table_setn(params,"X",apr_psprintf(ctx->pool,"%d",fi->i));
  apr_table_setn(params,"Y",apr_psprintf(ctx->pool,"%d",fi->j));
  apr_table_setn(params,"INFO_FORMAT",fi->format);

  apr_table_overlap(params,wms->getfeatureinfo_params,0);
  if(map->dimensions && !apr_is_empty_table(map->dimensions)) {
    const apr_array_header_t *elts = apr_table_elts(map->dimensions);
    int i;
    for(i=0; i<elts->nelts; i++) {
      apr_table_entry_t entry = APR_ARRAY_IDX(elts,i,apr_table_entry_t);
      apr_table_setn(params,entry.key,entry.val);
    }

  }

  fi->data = mapcache_buffer_create(30000,ctx->pool);
  http = mapcache_http_clone(ctx, wms->http);
  http->url = mapcache_http_build_url(ctx,http->url,params);
  mapcache_http_do_request(ctx,http,fi->data,NULL,NULL);
  GC_CHECK_ERROR(ctx);

}
Ejemplo n.º 13
0
/** Generate SDP media by MRCP control media descriptor */
static apr_size_t sdp_control_media_generate(char *buffer, apr_size_t size, const mrcp_session_descriptor_t *descriptor, const mrcp_control_descriptor_t *control_media, apt_bool_t offer)
{
	int i;
	apr_size_t offset = 0;
	const apt_str_t *proto;
	const apt_str_t *setup_type;
	const apt_str_t *connection_type;
	proto = mrcp_proto_get(control_media->proto);
	setup_type = mrcp_setup_type_get(control_media->setup_type);
	connection_type = mrcp_connection_type_get(control_media->connection_type);
	if(offer == TRUE) { /* offer */
		if(control_media->port) {
			offset += snprintf(buffer+offset,size-offset,
				"m=application %d %s 1\r\n"
				"a=setup:%s\r\n"
				"a=connection:%s\r\n"
				"a=resource:%s\r\n",
				control_media->port,
				proto ? proto->buf : "",
				setup_type ? setup_type->buf : "",
				connection_type ? connection_type->buf : "",
				control_media->resource_name.buf);

		}
		else {
			offset += snprintf(buffer+offset,size-offset,
				"m=application %d %s 1\r\n"
				"a=resource:%s\r\n",
				control_media->port,
				proto ? proto->buf : "",
				control_media->resource_name.buf);
		}
	}
	else { /* answer */
		if(control_media->port) {
			offset += snprintf(buffer+offset,size-offset,
				"m=application %d %s 1\r\n"
				"a=setup:%s\r\n"
				"a=connection:%s\r\n"
				"a=channel:%s@%s\r\n",
				control_media->port,
				proto ? proto->buf : "",
				setup_type ? setup_type->buf : "",
				connection_type ? connection_type->buf : "",
				control_media->session_id.buf,
				control_media->resource_name.buf);
		}
		else {
			offset += snprintf(buffer+offset,size-offset,
				"m=application %d %s 1\r\n"
				"a=channel:%s@%s\r\n",
				control_media->port,
				proto ? proto->buf : "",
				control_media->session_id.buf,
				control_media->resource_name.buf);
		}
	}

	for(i=0; i<control_media->cmid_arr->nelts; i++) {
		offset += snprintf(buffer+offset,size-offset,
			"a=cmid:%"APR_SIZE_T_FMT"\r\n",
			APR_ARRAY_IDX(control_media->cmid_arr,i,apr_size_t));
	}

	return offset;
}
Ejemplo n.º 14
0
void
svn_handle_error2(svn_error_t *err,
                  FILE *stream,
                  svn_boolean_t fatal,
                  const char *prefix)
{
  /* In a long error chain, there may be multiple errors with the same
     error code and no custom message.  We only want to print the
     default message for that code once; printing it multiple times
     would add no useful information.  The 'empties' array below
     remembers the codes of empty errors already seen in the chain.

     We could allocate it in err->pool, but there's no telling how
     long err will live or how many times it will get handled.  So we
     use a subpool. */
  apr_pool_t *subpool;
  apr_array_header_t *empties;
  svn_error_t *tmp_err;

  /* ### The rest of this file carefully avoids using svn_pool_*(),
     preferring apr_pool_*() instead.  I can't remember why -- it may
     be an artifact of r843793, or it may be for some deeper reason --
     but I'm playing it safe and using apr_pool_*() here too. */
  apr_pool_create(&subpool, err->pool);
  empties = apr_array_make(subpool, 0, sizeof(apr_status_t));

  tmp_err = err;
  while (tmp_err)
    {
      svn_boolean_t printed_already = FALSE;

      if (! tmp_err->message)
        {
          int i;

          for (i = 0; i < empties->nelts; i++)
            {
              if (tmp_err->apr_err == APR_ARRAY_IDX(empties, i, apr_status_t) )
                {
                  printed_already = TRUE;
                  break;
                }
            }
        }

      if (! printed_already)
        {
          print_error(tmp_err, stream, prefix);
          if (! tmp_err->message)
            {
              APR_ARRAY_PUSH(empties, apr_status_t) = tmp_err->apr_err;
            }
        }

      tmp_err = tmp_err->child;
    }

  svn_pool_destroy(subpool);

  fflush(stream);
  if (fatal)
    {
      /* Avoid abort()s in maintainer mode. */
      svn_error_clear(err);

      /* We exit(1) here instead of abort()ing so that atexit handlers
         get called. */
      exit(EXIT_FAILURE);
    }
}
Ejemplo n.º 15
0
Py::Object pysvn_client::cmd_ls( const Py::Tuple &a_args, const Py::Dict &a_kws )
{
    static argument_description args_desc[] =
    {
    { true,  name_url_or_path },
    { false, name_revision },
    { false, name_recurse },
#if defined( PYSVN_HAS_CLIENT_LS2 )
    { false, name_peg_revision },
#endif
    { false, NULL }
    };
    FunctionArguments args( "ls", args_desc, a_args, a_kws );
    args.check();

    std::string path( args.getUtf8String( name_url_or_path ) );
    bool recurse = args.getBoolean( name_recurse, false );
    svn_opt_revision_t revision = args.getRevision( name_revision, svn_opt_revision_head );

    SvnPool pool( m_context );
    apr_hash_t *hash = NULL;
    std::string norm_path( svnNormalisedIfPath( path, pool ) );
#if defined( PYSVN_HAS_CLIENT_LS2 )
    svn_opt_revision_t peg_revision = args.getRevision( name_peg_revision, revision );
#endif

    bool is_url = is_svn_url( path );
#if defined( PYSVN_HAS_CLIENT_LS2 )
    revisionKindCompatibleCheck( is_url, peg_revision, name_peg_revision, name_url_or_path );
#endif
    revisionKindCompatibleCheck( is_url, revision, name_revision, name_url_or_path );

    try
    {
        checkThreadPermission();

        PythonAllowThreads permission( m_context );

#if defined( PYSVN_HAS_CLIENT_LS2 )
        svn_error_t *error = svn_client_ls2
            (
            &hash,
            norm_path.c_str(),
            &peg_revision,
            &revision,
            recurse,
            m_context,
            pool
            );
#else
        svn_error_t *error = svn_client_ls
            (
            &hash,
            norm_path.c_str(),
            &revision,
            recurse,
            m_context,
            pool
            );
#endif
        permission.allowThisThread();
        if( error != 0 )
            throw SvnException( error );
    }
    catch( SvnException &e )
    {
        // use callback error over ClientException
        m_context.checkForError( m_module.client_error );

        throw_client_error( e );
    }


    apr_array_header_t *array = svn_sort__hash( hash, compare_items_as_paths, pool );

    std::string base_path;
    if( !norm_path.empty() )
    {
        base_path = norm_path;
        base_path += '/';
    }

    // convert the entries into python objects
    Py::List entries_list;

    for( int i = 0; i < array->nelts; ++i )
    {
        svn_sort__item_t *item = &APR_ARRAY_IDX( array, i, svn_sort__item_t );

        const char *utf8_entryname = static_cast<const char *>( item->key );
        svn_dirent_t *dirent = static_cast<svn_dirent_t *>( apr_hash_get( hash, utf8_entryname, item->klen ) );

        std::string full_name( base_path );
        full_name += utf8_entryname;

        Py::Dict entry_dict;
        entry_dict[ *py_name_name ] = Py::String( full_name, name_utf8 );
        entry_dict[ *py_name_kind ] = toEnumValue( dirent->kind );
        entry_dict[ *py_name_has_props ] = Py::Int( dirent->has_props );
        entry_dict[ *py_name_size ] = Py::Long( Py::Float( double( static_cast<signed_int64>( dirent->size ) ) ) );
        entry_dict[ *py_name_created_rev ] = Py::asObject( new pysvn_revision( svn_opt_revision_number, 0, dirent->created_rev ) );
        entry_dict[ *py_name_time ] = toObject( dirent->time );
        entry_dict[ *py_name_last_author ] = utf8_string_or_none( dirent->last_author );

        entries_list.append( m_wrapper_dirent.wrapDict( entry_dict ) );
    }

    return entries_list;
}
static apt_bool_t mrcp_client_session_terminate(mrcp_client_session_t *session)
{
	mrcp_profile_t *profile;
	mrcp_channel_t *channel;
	rtp_termination_slot_t *slot;
	int i;
	
	apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,session->base.log_obj,"Terminate Session "APT_NAMESID_FMT, 
		MRCP_SESSION_NAMESID(session));
	profile = session->profile;

	mrcp_client_session_state_set(session,SESSION_STATE_TERMINATING);
	if(session->context) {
		/* first destroy existing topology */
		if(mpf_engine_topology_message_add(
					session->profile->media_engine,
					MPF_DESTROY_TOPOLOGY,session->context,
					&session->mpf_task_msg) == TRUE){
			mrcp_client_session_subrequest_add(session);
		}
	}
	/* remove existing control channels */
	for(i=0; i<session->channels->nelts; i++) {
		/* get existing channel */
		channel = APR_ARRAY_IDX(session->channels,i,mrcp_channel_t*);
		if(!channel) continue;

		if(channel->control_channel) {
			/* remove channel */
			apt_obj_log(APT_LOG_MARK,APT_PRIO_DEBUG,session->base.log_obj,"Remove Control Channel "APT_NAMESID_FMT, 
				MRCP_SESSION_NAMESID(session));
			if(mrcp_client_control_channel_remove(channel->control_channel) == TRUE) {
				channel->waiting_for_channel = TRUE;
				mrcp_client_session_subrequest_add(session);
			}
		}

		/* send subtract termination request */
		if(channel->termination) {
			apt_obj_log(APT_LOG_MARK,APT_PRIO_DEBUG,session->base.log_obj,"Subtract Media Termination "APT_NAMESIDRES_FMT, 
				MRCP_SESSION_NAMESID(session),
				mpf_termination_name_get(channel->termination));
			if(mpf_engine_termination_message_add(
					profile->media_engine,
					MPF_SUBTRACT_TERMINATION,session->context,channel->termination,NULL,
					&session->mpf_task_msg) == TRUE) {
				channel->waiting_for_termination = TRUE;
				mrcp_client_session_subrequest_add(session);
			}
		}
	}

	if(session->context) {
		/* subtract existing terminations */
		for(i=0; i<session->terminations->nelts; i++) {
			/* get existing termination */
			slot = &APR_ARRAY_IDX(session->terminations,i,rtp_termination_slot_t);
			if(!slot || !slot->termination) continue;

			/* send subtract termination request */
			apt_obj_log(APT_LOG_MARK,APT_PRIO_DEBUG,session->base.log_obj,"Subtract Media Termination "APT_NAMESIDRES_FMT, 
				MRCP_SESSION_NAMESID(session),
				mpf_termination_name_get(slot->termination));
			if(mpf_engine_termination_message_add(
					profile->media_engine,
					MPF_SUBTRACT_TERMINATION,session->context,slot->termination,NULL,
					&session->mpf_task_msg) == TRUE) {
				slot->waiting = TRUE;
				mrcp_client_session_subrequest_add(session);
			}
		}

		mpf_engine_message_send(profile->media_engine,&session->mpf_task_msg);
	}

	mrcp_client_session_subrequest_add(session);
	mrcp_session_terminate_request(&session->base);
	return TRUE;
}
Ejemplo n.º 17
0
static apt_bool_t mrcp_server_session_terminate_process(mrcp_server_session_t *session)
{
	mrcp_channel_t *channel;
	mrcp_termination_slot_t *slot;
	int i;
	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Receive Terminate Request "APT_SID_FMT,MRCP_SESSION_SID(&session->base));

	mrcp_server_session_state_set(session,SESSION_STATE_TERMINATING);

	if(session->context) {
		/* first, destroy existing topology */
		if(mpf_engine_topology_message_add(
					session->profile->media_engine,
					MPF_RESET_ASSOCIATIONS,session->context,
					&session->mpf_task_msg) == TRUE){
			mrcp_server_session_subrequest_add(session);
		}
	}

	for(i=0; i<session->channels->nelts; i++) {
		channel = APR_ARRAY_IDX(session->channels,i,mrcp_channel_t*);
		if(!channel) continue;

		/* send remove channel request */
		apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Remove Control Channel [%d]",i);
		if(channel->control_channel) {
			if(mrcp_server_control_channel_remove(channel->control_channel) == TRUE) {
				channel->waiting_for_channel = TRUE;
				mrcp_server_session_subrequest_add(session);
			}
		}

		if(channel->engine_channel) {
			mpf_termination_t *termination = channel->engine_channel->termination;
			/* send subtract termination request */
			if(termination) {
				apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Subtract Channel Termination");
				if(mpf_engine_termination_message_add(
							session->profile->media_engine,
							MPF_SUBTRACT_TERMINATION,session->context,termination,NULL,
							&session->mpf_task_msg) == TRUE) {
					channel->waiting_for_termination = TRUE;
					mrcp_server_session_subrequest_add(session);
				}
			}

			/* close engine channel */
			if(mrcp_engine_channel_virtual_close(channel->engine_channel) == TRUE) {
				mrcp_server_session_subrequest_add(session);
			}
		}
	}
	for(i=0; i<session->terminations->nelts; i++) {
		/* get existing termination */
		slot = &APR_ARRAY_IDX(session->terminations,i,mrcp_termination_slot_t);
		if(!slot || !slot->termination) continue;

		/* send subtract termination request */
		apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Subtract RTP Termination [%d]",i);
		if(mpf_engine_termination_message_add(
				session->profile->media_engine,
				MPF_SUBTRACT_TERMINATION,session->context,slot->termination,NULL,
				&session->mpf_task_msg) == TRUE) {
			slot->waiting = TRUE;
			mrcp_server_session_subrequest_add(session);
		}
	}

	if(session->context) {
		mpf_engine_message_send(session->profile->media_engine,&session->mpf_task_msg);
	}

	mrcp_server_session_remove(session);

	if(!session->subrequest_count) {
		mrcp_server_session_terminate_send(session);
	}

	return TRUE;
}
Ejemplo n.º 18
0
/** Intersect two codec lists */
MPF_DECLARE(apt_bool_t) mpf_codec_lists_intersect(mpf_codec_list_t *codec_list1, mpf_codec_list_t *codec_list2)
{
    int i;
    mpf_codec_descriptor_t *descriptor1;
    mpf_codec_descriptor_t *descriptor2;
    codec_list1->primary_descriptor = NULL;
    codec_list1->event_descriptor = NULL;
    codec_list2->primary_descriptor = NULL;
    codec_list2->event_descriptor = NULL;
    /* find only one match for primary and named event descriptors,
    set the matched descriptors as preffered, disable the others */
    for(i=0; i<codec_list1->descriptor_arr->nelts; i++) {
        descriptor1 = &APR_ARRAY_IDX(codec_list1->descriptor_arr,i,mpf_codec_descriptor_t);
        if(descriptor1->enabled == FALSE) {
            /* this descriptor has been already disabled, process only enabled ones */
            continue;
        }

        /* check whether this is a named event descriptor */
        if(mpf_event_descriptor_check(descriptor1) == TRUE) {
            /* named event descriptor */
            if(codec_list1->event_descriptor) {
                /* named event descriptor has been already set, disable this one */
                descriptor1->enabled = FALSE;
            }
            else {
                /* find if there is a match */
                descriptor2 = mpf_codec_list_descriptor_find(codec_list2,descriptor1);
                if(descriptor2 && descriptor2->enabled == TRUE) {
                    descriptor1->enabled = TRUE;
                    codec_list1->event_descriptor = descriptor1;
                    codec_list2->event_descriptor = descriptor2;
                }
                else {
                    /* no match found, disable this descriptor */
                    descriptor1->enabled = FALSE;
                }
            }
        }
        else {
            /* primary descriptor */
            if(codec_list1->primary_descriptor) {
                /* primary descriptor has been already set, disable this one */
                descriptor1->enabled = FALSE;
            }
            else {
                /* find if there is a match */
                descriptor2 = mpf_codec_list_descriptor_find(codec_list2,descriptor1);
                if(descriptor2 && descriptor2->enabled == TRUE) {
                    descriptor1->enabled = TRUE;
                    codec_list1->primary_descriptor = descriptor1;
                    codec_list2->primary_descriptor = descriptor2;
                }
                else {
                    /* no match found, disable this descriptor */
                    descriptor1->enabled = FALSE;
                }
            }
        }
    }

    for(i=0; i<codec_list2->descriptor_arr->nelts; i++) {
        descriptor2 = &APR_ARRAY_IDX(codec_list2->descriptor_arr,i,mpf_codec_descriptor_t);
        if(descriptor2 == codec_list2->primary_descriptor || descriptor2 == codec_list2->event_descriptor) {
            descriptor2->enabled = TRUE;
        }
        else {
            descriptor2->enabled = FALSE;
        }
    }

    return TRUE;
}
Ejemplo n.º 19
0
/* Implement `svn_log_entry_receiver_t', printing the logs in
 * a human-readable and machine-parseable format.
 *
 * BATON is of type `struct log_receiver_baton'.
 *
 * First, print a header line.  Then if CHANGED_PATHS is non-null,
 * print all affected paths in a list headed "Changed paths:\n",
 * immediately following the header line.  Then print a newline
 * followed by the message body, unless BATON->omit_log_message is true.
 *
 * Here are some examples of the output:
 *
 * $ svn log -r1847:1846
 * ------------------------------------------------------------------------
 * rev 1847:  cmpilato | Wed 1 May 2002 15:44:26 | 7 lines
 *
 * Fix for Issue #694.
 *
 * * subversion/libsvn_repos/delta.c
 *   (delta_files): Rework the logic in this function to only call
 * send_text_deltas if there are deltas to send, and within that case,
 * only use a real delta stream if the caller wants real text deltas.
 *
 * ------------------------------------------------------------------------
 * rev 1846:  whoever | Wed 1 May 2002 15:23:41 | 1 line
 *
 * imagine an example log message here
 * ------------------------------------------------------------------------
 *
 * Or:
 *
 * $ svn log -r1847:1846 -v
 * ------------------------------------------------------------------------
 * rev 1847:  cmpilato | Wed 1 May 2002 15:44:26 | 7 lines
 * Changed paths:
 *    M /trunk/subversion/libsvn_repos/delta.c
 *
 * Fix for Issue #694.
 *
 * * subversion/libsvn_repos/delta.c
 *   (delta_files): Rework the logic in this function to only call
 * send_text_deltas if there are deltas to send, and within that case,
 * only use a real delta stream if the caller wants real text deltas.
 *
 * ------------------------------------------------------------------------
 * rev 1846:  whoever | Wed 1 May 2002 15:23:41 | 1 line
 * Changed paths:
 *    M /trunk/notes/fs_dumprestore.txt
 *    M /trunk/subversion/libsvn_repos/dump.c
 *
 * imagine an example log message here
 * ------------------------------------------------------------------------
 *
 * Or:
 *
 * $ svn log -r1847:1846 -q
 * ------------------------------------------------------------------------
 * rev 1847:  cmpilato | Wed 1 May 2002 15:44:26
 * ------------------------------------------------------------------------
 * rev 1846:  whoever | Wed 1 May 2002 15:23:41
 * ------------------------------------------------------------------------
 *
 * Or:
 *
 * $ svn log -r1847:1846 -qv
 * ------------------------------------------------------------------------
 * rev 1847:  cmpilato | Wed 1 May 2002 15:44:26
 * Changed paths:
 *    M /trunk/subversion/libsvn_repos/delta.c
 * ------------------------------------------------------------------------
 * rev 1846:  whoever | Wed 1 May 2002 15:23:41
 * Changed paths:
 *    M /trunk/notes/fs_dumprestore.txt
 *    M /trunk/subversion/libsvn_repos/dump.c
 * ------------------------------------------------------------------------
 *
 */
static svn_error_t *
log_entry_receiver(void *baton,
                   svn_log_entry_t *log_entry,
                   apr_pool_t *pool)
{
  struct log_receiver_baton *lb = baton;
  const char *author;
  const char *date;
  const char *message;

  /* Number of lines in the msg. */
  int lines;

  if (lb->cancel_func)
    SVN_ERR(lb->cancel_func(lb->cancel_baton));

  svn_compat_log_revprops_out(&author, &date, &message, log_entry->revprops);

  if (log_entry->revision == 0 && message == NULL)
    return SVN_NO_ERROR;

  if (! SVN_IS_VALID_REVNUM(log_entry->revision))
    {
      apr_array_pop(lb->merge_stack);
      return SVN_NO_ERROR;
    }

  /* ### See http://subversion.tigris.org/issues/show_bug.cgi?id=807
     for more on the fallback fuzzy conversions below. */

  if (author == NULL)
    author = _("(no author)");

  if (date && date[0])
    /* Convert date to a format for humans. */
    SVN_ERR(svn_cl__time_cstring_to_human_cstring(&date, date, pool));
  else
    date = _("(no date)");

  if (! lb->omit_log_message && message == NULL)
    message = "";

  SVN_ERR(svn_cmdline_printf(pool,
                             SEP_STRING "r%ld | %s | %s",
                             log_entry->revision, author, date));

  if (message != NULL)
    {
      lines = svn_cstring_count_newlines(message) + 1;
      SVN_ERR(svn_cmdline_printf(pool,
                                 (lines != 1)
                                 ? " | %d lines"
                                 : " | %d line", lines));
    }

  SVN_ERR(svn_cmdline_printf(pool, "\n"));

  if (log_entry->changed_paths)
    {
      apr_array_header_t *sorted_paths;
      int i;

      /* Get an array of sorted hash keys. */
      sorted_paths = svn_sort__hash(log_entry->changed_paths,
                                    svn_sort_compare_items_as_paths, pool);

      SVN_ERR(svn_cmdline_printf(pool,
                                 _("Changed paths:\n")));
      for (i = 0; i < sorted_paths->nelts; i++)
        {
          svn_sort__item_t *item = &(APR_ARRAY_IDX(sorted_paths, i,
                                                   svn_sort__item_t));
          const char *path = item->key;
          svn_log_changed_path_t *log_item
            = apr_hash_get(log_entry->changed_paths, item->key, item->klen);
          const char *copy_data = "";

          if (log_item->copyfrom_path
              && SVN_IS_VALID_REVNUM(log_item->copyfrom_rev))
            {
              copy_data
                = apr_psprintf(pool,
                               _(" (from %s:%ld)"),
                               log_item->copyfrom_path,
                               log_item->copyfrom_rev);
            }
          SVN_ERR(svn_cmdline_printf(pool, "   %c %s%s\n",
                                     log_item->action, path,
                                     copy_data));
        }
    }

  if (lb->merge_stack->nelts > 0)
    {
      int i;

      /* Print the result of merge line */
      SVN_ERR(svn_cmdline_printf(pool, _("Merged via:")));
      for (i = 0; i < lb->merge_stack->nelts; i++)
        {
          svn_revnum_t rev = APR_ARRAY_IDX(lb->merge_stack, i, svn_revnum_t);

          SVN_ERR(svn_cmdline_printf(pool, " r%ld%c", rev,
                                     i == lb->merge_stack->nelts - 1 ?
                                                                  '\n' : ','));
        }
    }

  if (message != NULL)
    {
      /* A blank line always precedes the log message. */
      SVN_ERR(svn_cmdline_printf(pool, "\n%s\n", message));
    }

  SVN_ERR(svn_cmdline_fflush(stdout));

  if (log_entry->has_children)
    APR_ARRAY_PUSH(lb->merge_stack, svn_revnum_t) = log_entry->revision;

  return SVN_NO_ERROR;
}
Ejemplo n.º 20
0
/* Implements svn_hash_write2 and svn_hash_write_incremental. */
static svn_error_t *
hash_write(apr_hash_t *hash, apr_hash_t *oldhash, svn_stream_t *stream,
           const char *terminator, apr_pool_t *pool)
{
  apr_pool_t *subpool;
  apr_size_t len;
  apr_array_header_t *list;
  int i;

  subpool = svn_pool_create(pool);

  list = svn_sort__hash(hash, svn_sort_compare_items_lexically, pool);
  for (i = 0; i < list->nelts; i++)
    {
      svn_sort__item_t *item = &APR_ARRAY_IDX(list, i, svn_sort__item_t);
      svn_string_t *valstr = item->value;

      svn_pool_clear(subpool);

      /* Don't output entries equal to the ones in oldhash, if present. */
      if (oldhash)
        {
          svn_string_t *oldstr = apr_hash_get(oldhash, item->key, item->klen);

          if (oldstr && svn_string_compare(valstr, oldstr))
            continue;
        }

      /* Write it out. */
      SVN_ERR(svn_stream_printf(stream, subpool,
                                "K %" APR_SSIZE_T_FMT "\n%s\n"
                                "V %" APR_SIZE_T_FMT "\n",
                                item->klen, (const char *) item->key,
                                valstr->len));
      len = valstr->len;
      SVN_ERR(svn_stream_write(stream, valstr->data, &len));
      SVN_ERR(svn_stream_printf(stream, subpool, "\n"));
    }

  if (oldhash)
    {
      /* Output a deletion entry for each property in oldhash but not hash. */
      list = svn_sort__hash(oldhash, svn_sort_compare_items_lexically,
                            pool);
      for (i = 0; i < list->nelts; i++)
        {
          svn_sort__item_t *item = &APR_ARRAY_IDX(list, i, svn_sort__item_t);

          svn_pool_clear(subpool);

          /* If it's not present in the new hash, write out a D entry. */
          if (! apr_hash_get(hash, item->key, item->klen))
            SVN_ERR(svn_stream_printf(stream, subpool,
                                      "D %" APR_SSIZE_T_FMT "\n%s\n",
                                      item->klen, (const char *) item->key));
        }
    }

  if (terminator)
    SVN_ERR(svn_stream_printf(stream, subpool, "%s\n", terminator));

  svn_pool_destroy(subpool);
  return SVN_NO_ERROR;
}
static void ngx_http_mapcache_write_response(mapcache_context *ctx, ngx_http_request_t *r,
      mapcache_http_response *response) {
   if(response->mtime) {
      time_t  if_modified_since;
      if(r->headers_in.if_modified_since) {
         if_modified_since = ngx_http_parse_time(r->headers_in.if_modified_since->value.data,
               r->headers_in.if_modified_since->value.len);
         if (if_modified_since != NGX_ERROR) {
            apr_time_t apr_if_m_s;
            apr_time_ansi_put	(	&apr_if_m_s, if_modified_since);
            if(apr_if_m_s<response->mtime) {
               r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
               ngx_http_send_header(r);
               return;
            }
         }
      }
      char *datestr;
      datestr = apr_palloc(ctx->pool, APR_RFC822_DATE_LEN);
      apr_rfc822_date(datestr, response->mtime);
      apr_table_setn(response->headers,"Last-Modified",datestr);
   }
   if(response->headers && !apr_is_empty_table(response->headers)) {
      const apr_array_header_t *elts = apr_table_elts(response->headers);
      int i;
      for(i=0;i<elts->nelts;i++) {
         apr_table_entry_t entry = APR_ARRAY_IDX(elts,i,apr_table_entry_t);
         if(!strcasecmp(entry.key,"Content-Type")) {
            r->headers_out.content_type.len = strlen(entry.val);
            r->headers_out.content_type.data = (u_char*)entry.val;
         } else {
            ngx_table_elt_t   *h;
            h = ngx_list_push(&r->headers_out.headers);
            if (h == NULL) {
               return;
            }
            h->key.len = strlen(entry.key) ;
            h->key.data = (u_char*)entry.key ;
            h->value.len = strlen(entry.val) ;
            h->value.data = (u_char*)entry.val ;
            h->hash = 1;
         }
      }
   }
   if(response->data) {
      r->headers_out.content_length_n = response->data->size;
   }
   int rc;
   r->headers_out.status = response->code;
   rc = ngx_http_send_header(r);
   if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
      return;
   }

   if(response->data) {
      ngx_buf_t    *b;
      ngx_chain_t   out;
      b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
      if (b == NULL) {
         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, 
               "Failed to allocate response buffer.");
         return;
      }

      b->pos = ngx_pcalloc(r->pool,response->data->size);
      memcpy(b->pos,response->data->buf,response->data->size);
      b->last = b->pos + response->data->size;
      b->memory = 1;
      b->last_buf = 1;
      b->flush = 1;
      out.buf = b;
      out.next = NULL;
      ngx_http_output_filter(r, &out);
   }

}
Ejemplo n.º 22
0
/**
 * \brief return filename for given tile
 * 
 * \param tile the tile to get the key from
 * \param path pointer to a char* that will contain the filename
 * \param r 
 * \private \memberof mapcache_cache_tiff
 */
static void _mapcache_cache_tiff_tile_key(mapcache_context *ctx, mapcache_tile *tile, char **path) {
   mapcache_cache_tiff *dcache = (mapcache_cache_tiff*)tile->tileset->cache;
   *path = dcache->filename_template;

   /*
    * generic template substitutions
    */
   if(strstr(*path,"{tileset}"))
      *path = mapcache_util_str_replace(ctx->pool,*path, "{tileset}",
            tile->tileset->name);
   if(strstr(*path,"{grid}"))
      *path = mapcache_util_str_replace(ctx->pool,*path, "{grid}",
            tile->grid_link->grid->name);
   if(tile->dimensions && strstr(*path,"{dim}")) {
      char *dimstring="";
      const apr_array_header_t *elts = apr_table_elts(tile->dimensions);
      int i = elts->nelts;
      while(i--) {
         apr_table_entry_t *entry = &(APR_ARRAY_IDX(elts,i,apr_table_entry_t));
         const char *dimval = mapcache_util_str_sanitize(ctx->pool,entry->val,"/.",'#');
         dimstring = apr_pstrcat(ctx->pool,dimstring,"#",dimval,NULL);
      }
      *path = mapcache_util_str_replace(ctx->pool,*path, "{dim}", dimstring);
   }
   
   
   while(strstr(*path,"{z}"))
      *path = mapcache_util_str_replace(ctx->pool,*path, "{z}",
            apr_psprintf(ctx->pool,dcache->z_fmt,tile->z));
   /*
    * x and y replacing, when the tiff files are numbered with an increasing
    * x,y scheme (adjacent tiffs have x-x'=1 or y-y'=1
    */
   while(strstr(*path,"{div_x}"))
      *path = mapcache_util_str_replace(ctx->pool,*path, "{div_x}",
            apr_psprintf(ctx->pool,dcache->div_x_fmt,tile->x/dcache->count_x));
   while(strstr(*path,"{div_y}"))
      *path = mapcache_util_str_replace(ctx->pool,*path, "{div_y}",
            apr_psprintf(ctx->pool,dcache->div_y_fmt,tile->y/dcache->count_y));
   while(strstr(*path,"{inv_div_y}"))
      *path = mapcache_util_str_replace(ctx->pool,*path, "{inv_div_y}",
            apr_psprintf(ctx->pool,dcache->inv_div_y_fmt,(tile->grid_link->grid->levels[tile->z]->maxy - tile->y - 1)/dcache->count_y));
   while(strstr(*path,"{inv_div_x}"))
      *path = mapcache_util_str_replace(ctx->pool,*path, "{inv_div_x}",
            apr_psprintf(ctx->pool,dcache->inv_div_x_fmt,(tile->grid_link->grid->levels[tile->z]->maxx - tile->x - 1)/dcache->count_x));
   
   /*
    * x and y replacing, when the tiff files are numbered with the index
    * of their bottom-left tile
    * adjacent tiffs have x-x'=count_x or y-y'=count_y
    */
   while(strstr(*path,"{x}"))
      *path = mapcache_util_str_replace(ctx->pool,*path, "{x}",
            apr_psprintf(ctx->pool,dcache->x_fmt,tile->x/dcache->count_x*dcache->count_x));
   while(strstr(*path,"{y}"))
      *path = mapcache_util_str_replace(ctx->pool,*path, "{y}",
            apr_psprintf(ctx->pool,dcache->y_fmt,tile->y/dcache->count_y*dcache->count_y));
   while(strstr(*path,"{inv_y}"))
      *path = mapcache_util_str_replace(ctx->pool,*path, "{inv_y}",
            apr_psprintf(ctx->pool,dcache->inv_y_fmt,(tile->grid_link->grid->levels[tile->z]->maxy - tile->y - 1)/dcache->count_y*dcache->count_y));
   while(strstr(*path,"{inv_x}"))
      *path = mapcache_util_str_replace(ctx->pool,*path, "{inv_x}",
            apr_psprintf(ctx->pool,dcache->inv_x_fmt,(tile->grid_link->grid->levels[tile->z]->maxx - tile->x - 1)/dcache->count_x*dcache->count_y));
   if(!*path) {
      ctx->set_error(ctx,500, "failed to allocate tile key");
   }
}
Ejemplo n.º 23
0
/* Print the properties in PROPS to the stream OUT. PROPS is a hash mapping
 * (const char *) path to (svn_string_t) property value.
 * If IS_URL is true, all paths are URLs, else all paths are local paths.
 * PNAME_UTF8 is the property name of all the properties.
 * If PRINT_FILENAMES is true, print the item's path before each property.
 * If OMIT_NEWLINE is true, don't add a newline at the end of each property.
 * If LIKE_PROPLIST is true, print everything in a more verbose format
 * like "svn proplist -v" does.
 * */
static svn_error_t *
print_properties(svn_stream_t *out,
                 svn_boolean_t is_url,
                 const char *pname_utf8,
                 apr_hash_t *props,
                 svn_boolean_t print_filenames,
                 svn_boolean_t omit_newline,
                 svn_boolean_t like_proplist,
                 apr_pool_t *pool)
{
  apr_array_header_t *sorted_props;
  int i;
  apr_pool_t *iterpool = svn_pool_create(pool);
  const char *path_prefix;

  SVN_ERR(svn_dirent_get_absolute(&path_prefix, "", pool));

  sorted_props = svn_sort__hash(props, svn_sort_compare_items_as_paths, pool);
  for (i = 0; i < sorted_props->nelts; i++)
    {
      svn_sort__item_t item = APR_ARRAY_IDX(sorted_props, i, svn_sort__item_t);
      const char *filename = item.key;
      svn_string_t *propval = item.value;

      svn_pool_clear(iterpool);

      if (print_filenames)
        {
          const char *header;

          /* Print the file name. */

          if (! is_url)
            filename = svn_cl__local_style_skip_ancestor(path_prefix, filename,
                                                         iterpool);

          /* In verbose mode, print exactly same as "proplist" does;
           * otherwise, print a brief header. */
          header = apr_psprintf(iterpool, like_proplist
                                ? _("Properties on '%s':\n")
                                : "%s - ", filename);
          SVN_ERR(svn_cmdline_cstring_from_utf8(&header, header, iterpool));
          SVN_ERR(svn_subst_translate_cstring2(header, &header,
                                               APR_EOL_STR,  /* 'native' eol */
                                               FALSE, /* no repair */
                                               NULL,  /* no keywords */
                                               FALSE, /* no expansion */
                                               iterpool));
          SVN_ERR(stream_write(out, header, strlen(header)));
        }

      if (like_proplist)
        {
          /* Print the property name and value just as "proplist -v" does */
          apr_hash_t *hash = apr_hash_make(iterpool);

          apr_hash_set(hash, pname_utf8, APR_HASH_KEY_STRING, propval);
          SVN_ERR(svn_cl__print_prop_hash(out, hash, FALSE, iterpool));
        }
      else
        {
          /* If this is a special Subversion property, it is stored as
             UTF8, so convert to the native format. */
          if (svn_prop_needs_translation(pname_utf8))
            SVN_ERR(svn_subst_detranslate_string(&propval, propval,
                                                 TRUE, iterpool));

          SVN_ERR(stream_write(out, propval->data, propval->len));

          if (! omit_newline)
            SVN_ERR(stream_write(out, APR_EOL_STR,
                                 strlen(APR_EOL_STR)));
        }
    }

  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}
Ejemplo n.º 24
0
/** Generate SDP media by RTP media descriptor */
static apr_size_t sdp_rtp_media_generate(char *buffer, apr_size_t size, const mrcp_session_descriptor_t *descriptor, const mpf_rtp_media_descriptor_t *audio_media)
{
	apr_size_t offset = 0;
	if(audio_media->state == MPF_MEDIA_ENABLED) {
		int codec_count = 0;
		int i;
		mpf_codec_descriptor_t *codec_descriptor;
		apr_array_header_t *descriptor_arr = audio_media->codec_list.descriptor_arr;
		const apt_str_t *direction_str;
		if(!descriptor_arr) {
			return 0;
		}

		offset += snprintf(buffer+offset,size-offset,"m=audio %d RTP/AVP",audio_media->port);
		for(i=0; i<descriptor_arr->nelts; i++) {
			codec_descriptor = &APR_ARRAY_IDX(descriptor_arr,i,mpf_codec_descriptor_t);
			if(codec_descriptor->enabled == TRUE) {
				offset += snprintf(buffer+offset,size-offset," %d",codec_descriptor->payload_type);
				codec_count++;
			}
		}
		if(!codec_count){
			/* SDP m line should have at least one media format listed; use a reserved RTP payload type */
			offset += snprintf(buffer+offset,size-offset," %d",RTP_PT_RESERVED);
		}
		offset += snprintf(buffer+offset,size-offset,"\r\n");
		
		if(descriptor->ip.length && audio_media->ip.length && 
			apt_string_compare(&descriptor->ip,&audio_media->ip) != TRUE) {
			const char *media_ip = audio_media->ext_ip.buf ? audio_media->ext_ip.buf : audio_media->ip.buf;
			offset += snprintf(buffer+offset,size-offset,"c=IN IP4 %s\r\n",media_ip);
		}
		
		for(i=0; i<descriptor_arr->nelts; i++) {
			codec_descriptor = &APR_ARRAY_IDX(descriptor_arr,i,mpf_codec_descriptor_t);
			if(codec_descriptor->enabled == TRUE && codec_descriptor->name.buf) {
				offset += snprintf(buffer+offset,size-offset,"a=rtpmap:%d %s/%d\r\n",
					codec_descriptor->payload_type,
					codec_descriptor->name.buf,
					codec_descriptor->sampling_rate);
				if(codec_descriptor->format.buf) {
					offset += snprintf(buffer+offset,size-offset,"a=fmtp:%d %s\r\n",
						codec_descriptor->payload_type,
						codec_descriptor->format.buf);
				}
			}
		}
		
		direction_str = mpf_rtp_direction_str_get(audio_media->direction);
		if(direction_str) {
			offset += snprintf(buffer+offset,size-offset,"a=%s\r\n",direction_str->buf);
		}
		
		if(audio_media->ptime) {
			offset += snprintf(buffer+offset,size-offset,"a=ptime:%hu\r\n",audio_media->ptime);
		}
	}
	else {
		offset += snprintf(buffer+offset,size-offset,"m=audio 0 RTP/AVP %d\r\n",RTP_PT_RESERVED);
	}

	offset += snprintf(buffer+offset,size-offset,"a=mid:%"APR_SIZE_T_FMT"\r\n",audio_media->mid);
	return offset;
}
Ejemplo n.º 25
0
/* This implements the `svn_opt_subcommand_t' interface. */
svn_error_t *
svn_cl__add(apr_getopt_t *os,
            void *baton,
            apr_pool_t *pool)
{
  svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
  svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
  apr_array_header_t *targets;
  int i;
  apr_pool_t *iterpool;
  apr_array_header_t *errors = apr_array_make(pool, 0, sizeof(apr_status_t));

  SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                      opt_state->targets,
                                                      ctx, FALSE, pool));

  if (! targets->nelts)
    return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);

  if (opt_state->depth == svn_depth_unknown)
    opt_state->depth = svn_depth_infinity;

  SVN_ERR(svn_cl__eat_peg_revisions(&targets, targets, pool));

  SVN_ERR(svn_cl__check_targets_are_local_paths(targets));

  iterpool = svn_pool_create(pool);
  for (i = 0; i < targets->nelts; i++)
    {
      const char *target = APR_ARRAY_IDX(targets, i, const char *);

      svn_pool_clear(iterpool);
      SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton));
      SVN_ERR(svn_cl__try
              (svn_client_add5(target,
                               opt_state->depth,
                               opt_state->force, opt_state->no_ignore,
                               opt_state->no_autoprops, opt_state->parents,
                               ctx, iterpool),
               errors, opt_state->quiet,
               SVN_ERR_ENTRY_EXISTS,
               SVN_ERR_WC_PATH_NOT_FOUND,
               0));
    }

  svn_pool_destroy(iterpool);

  if (errors->nelts > 0)
    {
      svn_error_t *err;

      err = svn_error_create(SVN_ERR_ILLEGAL_TARGET, NULL, NULL);
      for (i = 0; i < errors->nelts; i++)
        {
          apr_status_t status = APR_ARRAY_IDX(errors, i, apr_status_t);
          if (status == SVN_ERR_WC_PATH_NOT_FOUND)
            err = svn_error_quick_wrap(err,
                                       _("Could not add all targets because "
                                         "some targets don't exist"));
          else if (status == SVN_ERR_ENTRY_EXISTS)
            err = svn_error_quick_wrap(err,
                                       _("Could not add all targets because "
                                         "some targets are already versioned"));
        }

      return svn_error_trace(err);
    }

  return SVN_NO_ERROR;
}
Ejemplo n.º 26
0
/* Perform status operations on each external in EXTERNAL_MAP, a const char *
   local_abspath of all externals mapping to the const char* defining_abspath.
   All other options are the same as those passed to svn_client_status().

   If ANCHOR_ABSPATH and ANCHOR-RELPATH are not null, use them to provide
   properly formatted relative paths */
static svn_error_t *
do_external_status(svn_client_ctx_t *ctx,
                   apr_hash_t *external_map,
                   svn_depth_t depth,
                   svn_boolean_t get_all,
                   svn_boolean_t check_out_of_date,
                   svn_boolean_t check_working_copy,
                   svn_boolean_t no_ignore,
                   const apr_array_header_t *changelists,
                   const char *anchor_abspath,
                   const char *anchor_relpath,
                   svn_client_status_func_t status_func,
                   void *status_baton,
                   apr_pool_t *scratch_pool)
{
    apr_pool_t *iterpool = svn_pool_create(scratch_pool);
    apr_array_header_t *externals;
    int i;

    externals = svn_sort__hash(external_map, svn_sort_compare_items_lexically,
                               scratch_pool);

    /* Loop over the hash of new values (we don't care about the old
       ones).  This is a mapping of versioned directories to property
       values. */
    for (i = 0; i < externals->nelts; i++)
    {
        svn_node_kind_t external_kind;
        svn_sort__item_t item = APR_ARRAY_IDX(externals, i, svn_sort__item_t);
        const char *local_abspath = item.key;
        const char *defining_abspath = item.value;
        svn_node_kind_t kind;
        svn_opt_revision_t opt_rev;
        const char *status_path;

        svn_pool_clear(iterpool);

        /* Obtain information on the expected external. */
        SVN_ERR(svn_wc__read_external_info(&external_kind, NULL, NULL, NULL,
                                           &opt_rev.value.number,
                                           ctx->wc_ctx, defining_abspath,
                                           local_abspath, FALSE,
                                           iterpool, iterpool));

        if (external_kind != svn_node_dir)
            continue;

        SVN_ERR(svn_io_check_path(local_abspath, &kind, iterpool));
        if (kind != svn_node_dir)
            continue;

        if (SVN_IS_VALID_REVNUM(opt_rev.value.number))
            opt_rev.kind = svn_opt_revision_number;
        else
            opt_rev.kind = svn_opt_revision_unspecified;

        /* Tell the client we're starting an external status set. */
        if (ctx->notify_func2)
            ctx->notify_func2(
                ctx->notify_baton2,
                svn_wc_create_notify(local_abspath,
                                     svn_wc_notify_status_external,
                                     iterpool), iterpool);

        status_path = local_abspath;
        if (anchor_abspath)
        {
            status_path = svn_dirent_join(anchor_relpath,
                                          svn_dirent_skip_ancestor(anchor_abspath,
                                                  status_path),
                                          iterpool);
        }

        /* And then do the status. */
        SVN_ERR(svn_client_status6(NULL, ctx, status_path, &opt_rev, depth,
                                   get_all, check_out_of_date,
                                   check_working_copy, no_ignore,
                                   FALSE /* ignore_exernals */,
                                   FALSE /* depth_as_sticky */,
                                   changelists, status_func, status_baton,
                                   iterpool));
    }

    /* Destroy SUBPOOL and (implicitly) ITERPOOL. */
    svn_pool_destroy(iterpool);

    return SVN_NO_ERROR;
}
Ejemplo n.º 27
0
/** Parse individual header field (name-value pair) */
APT_DECLARE(apt_header_field_t*) apt_header_field_parse(apt_text_stream_t *stream, apr_pool_t *pool)
{
	apr_size_t folding_length = 0;
	apr_array_header_t *folded_lines = NULL;
	apt_header_field_t *header_field;
	apt_str_t temp_line;
	apt_str_t *line;
	apt_pair_t pair;
	/* read name-value pair */
	if(apt_text_header_read(stream,&pair) == FALSE) {
		return NULL;
	}

	/* check folding lines (value spanning multiple lines) */
	while(stream->pos < stream->end) {
		if(apt_text_is_wsp(*stream->pos) == FALSE) {
			break;
		}

		stream->pos++;

		/* skip further white spaces (if any) */
		apt_text_white_spaces_skip(stream);

		if(!folded_lines) {
			folded_lines = apr_array_make(pool,1,sizeof(apt_str_t));
		}
		if(apt_text_line_read(stream,&temp_line) == TRUE) {
			line = apr_array_push(folded_lines);
			*line = temp_line;
			folding_length += line->length;
		}
	};

	header_field = apt_header_field_alloc(pool);
	/* copy parsed name of the header field */
	header_field->name.length = pair.name.length;
	header_field->name.buf = apr_palloc(pool, pair.name.length + 1);
	if(pair.name.length) {
		memcpy(header_field->name.buf, pair.name.buf, pair.name.length);
	}
	header_field->name.buf[header_field->name.length] = '\0';

	/* copy parsed value of the header field */
	header_field->value.length = pair.value.length + folding_length;
	header_field->value.buf = apr_palloc(pool, header_field->value.length + 1);
	if(pair.value.length) {
		memcpy(header_field->value.buf, pair.value.buf, pair.value.length);
	}

	if(folding_length) {
		int i;
		char *pos = header_field->value.buf + pair.value.length;
		/* copy parsed folding lines */
		for(i=0; i<folded_lines->nelts; i++) {
			line = &APR_ARRAY_IDX(folded_lines,i,apt_str_t);

			memcpy(pos,line->buf,line->length);
			pos += line->length;
		}
	}
	header_field->value.buf[header_field->value.length] = '\0';

	return header_field;
}
Ejemplo n.º 28
0
/* This implements the svn_repos_file_rev_handler2_t interface. */
static svn_error_t *
file_rev_handler(void *baton,
                 const char *path,
                 svn_revnum_t revnum,
                 apr_hash_t *rev_props,
                 svn_boolean_t merged_revision,
                 svn_txdelta_window_handler_t *window_handler,
                 void **window_baton,
                 apr_array_header_t *props,
                 apr_pool_t *pool)
{
  struct file_rev_baton *frb = baton;
  apr_pool_t *subpool = svn_pool_create(pool);
  apr_hash_index_t *hi;
  int i;

  SVN_ERR(maybe_send_header(frb));

  SVN_ERR(dav_svn__brigade_printf(frb->bb, frb->output,
                                  "<S:file-rev path=\"%s\" rev=\"%ld\">"
                                  DEBUG_CR,
                                  apr_xml_quote_string(pool, path, 1),
                                  revnum));

  /* Send rev props. */
  for (hi = apr_hash_first(pool, rev_props); hi; hi = apr_hash_next(hi))
    {
      const void *key;
      void *val;
      const char *pname;
      const svn_string_t *pval;

      svn_pool_clear(subpool);
      apr_hash_this(hi, &key, NULL, &val);
      pname = key;
      pval = val;
      SVN_ERR(send_prop(frb, "rev-prop", pname, pval, subpool));
    }

  /* Send file prop changes. */
  for (i = 0; i < props->nelts; ++i)
    {
      const svn_prop_t *prop = &APR_ARRAY_IDX(props, i, svn_prop_t);

      svn_pool_clear(subpool);
      if (prop->value)
        SVN_ERR(send_prop(frb, "set-prop", prop->name, prop->value,
                          subpool));
      else
        {
          /* Property was removed. */
          SVN_ERR(dav_svn__brigade_printf(frb->bb, frb->output,
                                          "<S:remove-prop name=\"%s\"/>"
                                          DEBUG_CR,
                                          apr_xml_quote_string(subpool,
                                                               prop->name,
                                                               1)));
        }
    }

  /* Send whether this was the result of a merge or not. */
  if (merged_revision)
    SVN_ERR(dav_svn__brigade_puts(frb->bb, frb->output,
                                  "<S:merged-revision/>"));

  /* Maybe send text delta. */
  if (window_handler)
    {
      svn_stream_t *base64_stream;

      base64_stream = dav_svn__make_base64_output_stream(frb->bb, frb->output,
                                                         pool);
      svn_txdelta_to_svndiff3(&frb->window_handler, &frb->window_baton,
                              base64_stream, frb->svndiff_version,
                              frb->compression_level, pool);
      *window_handler = delta_window_handler;
      *window_baton = frb;
      /* Start the txdelta element wich will be terminated by the window
         handler together with the file-rev element. */
      SVN_ERR(dav_svn__brigade_puts(frb->bb, frb->output, "<S:txdelta>"));
    }
  else
    /* No txdelta, so terminate the element here. */
    SVN_ERR(dav_svn__brigade_puts(frb->bb, frb->output,
                                  "</S:file-rev>" DEBUG_CR));

  svn_pool_destroy(subpool);

  return SVN_NO_ERROR;
}
Ejemplo n.º 29
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;
}
Ejemplo n.º 30
0
svn_error_t *
svn_opt__print_version_info(const char *pgm_name,
                            const char *footer,
                            const svn_version_extended_t *info,
                            svn_boolean_t quiet,
                            svn_boolean_t verbose,
                            apr_pool_t *pool)
{
  if (quiet)
    return svn_cmdline_printf(pool, "%s\n", SVN_VER_NUMBER);

  SVN_ERR(svn_cmdline_printf(pool, _("%s, version %s\n"
                                     "   compiled %s, %s on %s\n\n"),
                             pgm_name, SVN_VERSION,
                             svn_version_ext_build_date(info),
                             svn_version_ext_build_time(info),
                             svn_version_ext_build_host(info)));
  SVN_ERR(svn_cmdline_printf(pool, "%s\n", svn_version_ext_copyright(info)));

  if (footer)
    {
      SVN_ERR(svn_cmdline_printf(pool, "%s\n", footer));
    }

  if (verbose)
    {
      const apr_array_header_t *libs;

      SVN_ERR(svn_cmdline_fputs(_("System information:\n\n"), stdout, pool));
      SVN_ERR(svn_cmdline_printf(pool, _("* running on %s\n"),
                                 svn_version_ext_runtime_host(info)));
      if (svn_version_ext_runtime_osname(info))
        {
          SVN_ERR(svn_cmdline_printf(pool, _("  - %s\n"),
                                     svn_version_ext_runtime_osname(info)));
        }

      libs = svn_version_ext_linked_libs(info);
      if (libs && libs->nelts)
        {
          const svn_version_ext_linked_lib_t *lib;
          int i;

          SVN_ERR(svn_cmdline_fputs(_("* linked dependencies:\n"),
                                    stdout, pool));
          for (i = 0; i < libs->nelts; ++i)
            {
              lib = &APR_ARRAY_IDX(libs, i, svn_version_ext_linked_lib_t);
              if (lib->runtime_version)
                SVN_ERR(svn_cmdline_printf(pool,
                                           "  - %s %s (compiled with %s)\n",
                                           lib->name,
                                           lib->runtime_version,
                                           lib->compiled_version));
              else
                SVN_ERR(svn_cmdline_printf(pool,
                                           "  - %s %s (static)\n",
                                           lib->name,
                                           lib->compiled_version));
            }
        }

      libs = svn_version_ext_loaded_libs(info);
      if (libs && libs->nelts)
        {
          const svn_version_ext_loaded_lib_t *lib;
          int i;

          SVN_ERR(svn_cmdline_fputs(_("* loaded shared libraries:\n"),
                                    stdout, pool));
          for (i = 0; i < libs->nelts; ++i)
            {
              lib = &APR_ARRAY_IDX(libs, i, svn_version_ext_loaded_lib_t);
              if (lib->version)
                SVN_ERR(svn_cmdline_printf(pool,
                                           "  - %s   (%s)\n",
                                           lib->name, lib->version));
              else
                SVN_ERR(svn_cmdline_printf(pool, "  - %s\n", lib->name));
            }
        }
    }

  return SVN_NO_ERROR;
}