コード例 #1
0
ファイル: template.c プロジェクト: diroussel/lua-web-tools
/*
 * Processes a 'for' element.
 */
static apr_status_t process_for (parser_rec *p, const char *element,
		int states, apr_table_t *attrs) {
	template_node_t *n;
	block_t *block;
	apr_status_t status;
	const char *names;
	char *name, *last;
	const char *sep = ", \t";

	if ((states & TEMPLATE_SOPEN) != 0) {
		n = (template_node_t *) apr_array_push(p->t);
		n->type = TEMPLATE_TFOR_INIT;
		n->for_init_in = apr_table_get(attrs, "in");
		if (n->for_init_in == NULL) {
			return parse_error(p, "missing attribute 'in'");
		}
		if ((status = compile_exp(p, n->for_init_in,
				&n->for_init_index)) != APR_SUCCESS) {
			return status;
		}

		block = (block_t *) apr_array_push(p->b);
		block->type = TEMPLATE_TFOR_NEXT;
		block->for_start = p->t->nelts;

		n = (template_node_t *) apr_array_push(p->t);
		n->type = TEMPLATE_TFOR_NEXT;
		n->for_next_names = apr_array_make(p->pool, 2,
				sizeof(const char *));
		names = apr_table_get(attrs, "names");
		if (names == NULL) {
			return parse_error(p, "missing attribute 'names'");
		}
		name = apr_strtok(apr_pstrdup(p->pool, names), sep, &last);
		while (name != NULL) {
			*((char **) apr_array_push(n->for_next_names)) = name;	
			name = apr_strtok(NULL, sep, &last);
		}
		if (n->for_next_names->nelts == 0) {
			return parse_error(p, "empty 'names'");
		}
		n->for_next_next = -1;
	}

	if ((states & TEMPLATE_SCLOSE) != 0) {
		block = (block_t *) apr_array_pop(p->b);
                if (block == NULL || block->type != TEMPLATE_TFOR_NEXT) {
                        return parse_error(p, "no 'for' to close");
		}

		n = (template_node_t *) apr_array_push(p->t);
		n->type = TEMPLATE_TJUMP;
		n->jump_next = block->for_start;

                n = ((template_node_t *) p->t->elts) + block->for_start;
                n->for_next_next = p->t->nelts;
        }

	return APR_SUCCESS;
}
コード例 #2
0
Params *getPostParms(request_rec *r, apr_off_t * postSize) {
    apr_array_header_t *pairs = NULL;
    apr_off_t len;
    apr_size_t size;
    int res;
    int i = 0;
    char *buffer;
    Params *params = NULL;
    
    res = ap_parse_form_data(r, NULL, &pairs, -1, HUGE_STRING_LEN);
    if (res != OK || !pairs) return NULL; 
    params = apr_pcalloc(r->pool, sizeof(Params) * (pairs->nelts + 1));
    while (pairs && !apr_is_empty_array(pairs)) {
        ap_form_pair_t *pair = (ap_form_pair_t *) apr_array_pop(pairs);
        apr_brigade_length(pair->value, 1, &len);
        size = (apr_size_t) len;
        buffer = apr_palloc(r->pool, size + 1);
        apr_brigade_flatten(pair->value, buffer, &size);
        buffer[len] = 0;
        params[i].key = apr_pstrdup(r->pool, pair->name);
        params[i].val = buffer;
        params[i].length = strlen(buffer);
        //ap_rprintf(r,"key : val : len: is %s : %s : %d ===", params[i].key, params[i].val, params[i].length);
        i++;
    }
    *postSize = i;

    return params;
}
コード例 #3
0
ファイル: gpmondb.c プロジェクト: karthijrk/gpdb
// Find all files start with 'gpdb-alert' under GPMON_LOG directory, sort it and
// remove the latest one 'gpdb-alert-*.csv' as it is still used by GPDB.
static void get_alert_log_tail_files(apr_array_header_t *tail_files, apr_pool_t *pool)
{
	apr_dir_t *dir;
	apr_status_t status = apr_dir_open(&dir, GPMON_LOG, pool);
	if (status != APR_SUCCESS)
	{
		gpmon_warningx(FLINE, status, "failed opening directory:%s", GPMON_LOG);
		return;
	}

	apr_finfo_t dirent;
	static const char gpdb_prefix[] = "gpdb-alert";
	while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dir) == APR_SUCCESS)
	{
		if (strncmp(dirent.name, gpdb_prefix, sizeof(gpdb_prefix) - 1) == 0)
		{
			void *file_slot = apr_array_push(tail_files);
			if (! file_slot)
			{
				gpmon_warningx(FLINE, 0, "failed getting alert tail log:%s due to out of memory", dirent.name);
				continue;
			}
			(*(const char**)file_slot) = apr_pstrcat(pool, GPMON_LOG, "/", dirent.name, NULL);
		}
	}

	// We only want to use qsort in stdlib.h, not the macro qsort in port.h.
	(qsort)(tail_files->elts, tail_files->nelts, tail_files->elt_size, cmp_string);
	(void)apr_array_pop(tail_files);
	apr_dir_close(dir);
}
コード例 #4
0
static llzr_conn* get_post_data(request_rec* r)
{
    GTable *request_post_data = g_hash_table_new(g_str_hash, g_str_equal);
    apr_array_header_t *pairs = NULL;
    apr_off_t len;
    apr_size_t size;
    int res;
    char *buffer;

    res = ap_parse_form_data(r, NULL, &pairs, -1, HUGE_STRING_LEN);
    if (res != OK || !pairs) return NULL; /* Return NULL if we failed or if there are is no POST data */

    while (pairs && !apr_is_empty_array(pairs)) {
        ap_form_pair_t *pair = (ap_form_pair_t *) apr_array_pop(pairs);
        apr_brigade_length(pair->value, 1, &len);
        size = (apr_size_t) len;
        buffer = apr_palloc(r->pool, size + 1);
        apr_brigade_flatten(pair->value, buffer, &size);
        buffer[len] = 0;

        g_hash_table_insert( request_post_data, apr_pstrdup(r->pool, pair->name), buffer);
    }

    return request_post_data;
}
コード例 #5
0
ファイル: mod_lily.c プロジェクト: mvader/lily
static void bind_post(int *count, lily_parse_state *parser, request_rec *r)
{
    if (*count == -1)
        return;

    lily_var *post_var = bind_hash_str_str_var(parser->symtab, "post");
    lily_hash_val *hash_val = post_var->value.hash;

    apr_array_header_t *pairs;
    apr_off_t len;
    apr_size_t size;
    char *buffer;
    char *sipkey = parser->vm->sipkey;
    lily_class *string_cls = lily_class_by_id(parser->symtab, SYM_CLASS_STRING);
    lily_sig *string_sig = string_cls->sig;

    /* Credit: I found out how to use this by reading httpd 2.4's mod_lua
       (specifically req_parsebody of lua_request.c). */
    int res = ap_parse_form_data(r, NULL, &pairs, -1, 1024 * 8);
    if (res == OK) {
        while (pairs && !apr_is_empty_array(pairs)) {
            ap_form_pair_t *pair = (ap_form_pair_t *) apr_array_pop(pairs);
            apr_brigade_length(pair->value, 1, &len);
            size = (apr_size_t) len;
            buffer = lily_malloc(size + 1);
            if (buffer == NULL) {
                *count = -1;
                return;
            }

            apr_brigade_flatten(pair->value, buffer, &size);
            buffer[len] = 0;

            lily_value *elem_key = bind_string(string_sig, pair->name);
            /* Give the buffer to the value to save memory. */
            lily_value *elem_value = bind_string_and_buffer(string_sig, buffer);
            lily_hash_elem *new_elem = bind_hash_elem_with_values(sipkey,
                    elem_key, elem_value);

            if (elem_key == NULL || elem_value == NULL || new_elem == NULL) {
                lily_free(new_elem);
                deref_destroy_value(elem_key);
                deref_destroy_value(elem_value);
                *count = -1;
                return;
            }

            new_elem->next = hash_val->elem_chain;
            hash_val->elem_chain = new_elem;
        }
    }

    (*count)++;
}
コード例 #6
0
ファイル: root_pools.c プロジェクト: 2asoft/freebsd
/* Return a currently unused connection pool in *POOL. If no such pool
 * exists, create a new root pool and return that in *POOL.
 */
static svn_error_t *
acquire_pool_internal(apr_pool_t **pool,
                      svn_root_pools__t *pools)
{
  SVN_ERR(svn_mutex__lock(pools->mutex));
  *pool = pools->unused_pools->nelts
        ? *(apr_pool_t **)apr_array_pop(pools->unused_pools)
        : apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
  SVN_ERR(svn_mutex__unlock(pools->mutex, SVN_NO_ERROR));

  return SVN_NO_ERROR;
}
コード例 #7
0
ファイル: gpmondb.c プロジェクト: karthijrk/gpdb
void gpdb_import_alert_log(apr_pool_t *pool)
{
	// Get alert log files to be imported.
	apr_array_header_t* tail_files = apr_array_make(pool, 10, sizeof(char*));
	apr_array_header_t* success_append_files = apr_array_make(pool, 10, sizeof(char*));
	get_alert_log_tail_files(tail_files, pool);

	// Create or truncate stage file.
	char *dst_file = apr_pstrcat(pool, GPMON_LOG, "/", GPMON_ALERT_LOG_STAGE, NULL);
	apr_status_t status = truncate_file(dst_file, pool);
	if (status != APR_SUCCESS)
	{
	    gpmon_warningx(FLINE, 0, "failed truncating stage file:%s", dst_file);
	    return;
	}

	// Append alert log tail file to stage file
	void *tail_file = NULL;
	while ((tail_file = apr_array_pop(tail_files)))
	{
		char *filename = *(char**)tail_file;
		void *success_file_slot = apr_array_push(success_append_files);
		if (!success_file_slot)
		{
			gpmon_warningx(
				FLINE, 0, "failed appending file:%s to stage file:%s due to out of memory",
				filename, dst_file);
			continue;
		}
		(*(char**)success_file_slot) = NULL;

	    status = apr_file_append(filename, dst_file, APR_FILE_SOURCE_PERMS, pool);
	    if (status != APR_SUCCESS)
	    {
			gpmon_warningx(FLINE, status, "failed appending file:%s to stage file:%s", filename, dst_file);
			continue;
		}
	    else
	    {
			(*(char**)success_file_slot) = filename;
	    	TR1(("success appending file:%s to stage file:%s\n", filename, dst_file));
	    }
	}

	// Insert tail file to history table.
	if (gpdb_insert_alert_log())
	{
		// Delete tail file
		gpdb_remove_success_files(success_append_files, pool);
		truncate_file(dst_file, pool);
	}
}
コード例 #8
0
/* Called after configuration is set, to finalise it. */
static int post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
{

    /* Create the caches, if required. */
    unsigned cache_max_entries
        = parse_number(authnz_crowd_process_config.cache_max_entries_string, "CrowdCacheMaxEntries", 0, UINT_MAX, 500,
        s);
    if (cache_max_entries > 0) {
        apr_time_t cache_max_age
            = apr_time_from_sec(parse_number(authnz_crowd_process_config.cache_max_age_string, "CrowdCacheMaxAge", 1,
            APR_INT64_MAX, 60, s));
        if (!crowd_cache_create(pconf, cache_max_age, cache_max_entries)) {
            exit(1);
        }
    }

    if (dir_configs != NULL) {

        /* Iterate over each directory config */
        authnz_crowd_dir_config **dir_config;
        while ((dir_config = apr_array_pop(dir_configs)) != NULL) {

            /* If any of the configuration parameters are specified, ensure that all mandatory parameters are
               specified. */
            crowd_config *crowd_config = (*dir_config)->crowd_config;
            if ((crowd_config->crowd_app_name != NULL || crowd_config->crowd_app_password != NULL
                || crowd_config->crowd_url != NULL)
                && (crowd_config->crowd_app_name == NULL || crowd_config->crowd_app_password == NULL
                || crowd_config->crowd_url == NULL)) {
                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
                    "Missing CrowdAppName, CrowdAppPassword or CrowdURL for a directory.");
                exit(1);
            }

            /* Parse the timeout parameter, if specified */
            crowd_config->crowd_timeout
                = parse_number((*dir_config)->crowd_timeout_string, "CrowdTimeout", 0, LONG_MAX, 0, s);

            /* If no basic auth character encodings are specified, setup ISO-8859-1. */
            if (apr_is_empty_array((*dir_config)->basic_auth_xlates)) {
                const char *error = add_basic_auth_conversion("ISO-8859-1", *dir_config, pconf, ptemp);
                if (error != NULL) {
                    ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
                        "Could not configure default Basic Authentication translation.  %s", error);
                    exit(1);
                }
            }

        }
    }
    return OK;
}
コード例 #9
0
ファイル: serf_spider.c プロジェクト: atkonn/mod_chxj
static void * APR_THREAD_FUNC parser_thread(apr_thread_t *thread, void *data)
{
    apr_status_t status;
    apr_pool_t *pool, *subpool;
    parser_baton_t *ctx;

    ctx = (parser_baton_t*)data;
    pool = apr_thread_pool_get(thread);

    apr_pool_create(&subpool, pool);

    while (1) {
        doc_path_t *dup;

        apr_pool_clear(subpool);

        /* Grab it. */
        apr_thread_mutex_lock(ctx->mutex);
        /* Sleep. */
        apr_thread_cond_wait(ctx->condvar, ctx->mutex);

        /* Fetch the doc off the list. */
        if (ctx->doc_queue->nelts) {
            dup = *(doc_path_t**)(apr_array_pop(ctx->doc_queue));
            /* dup = (ctx->doc_queue->conns->elts)[0]; */
        }
        else {
            dup = NULL;
        }

        /* Don't need the mutex now. */
        apr_thread_mutex_unlock(ctx->mutex);

        /* Parse the doc/url pair. */
        if (dup) {
            status = find_href_doc(dup->doc, dup->path, ctx, subpool);
            if (status) {
                printf("Error finding hrefs: %d %s\n", status, dup->path);
            }
            /* Free the doc pair and its pool. */
            apr_pool_destroy(dup->pool);
            serf_bucket_mem_free(ctx->doc_queue_alloc, dup->path);
            serf_bucket_mem_free(ctx->doc_queue_alloc, dup);
        }

        /* Hey are we done? */
        if (!apr_atomic_read32(ctx->requests_outstanding)) {
            break;
        }
    }
    return NULL;
}
コード例 #10
0
ファイル: apr_crypto_nss.c プロジェクト: Alivx/apache2nginx
/**
 * @brief Clean encryption / decryption context.
 * @note After cleanup, a context is free to be reused if necessary.
 * @param f The context to use.
 * @return Returns APR_ENOTIMPL if not supported.
 */
static apr_status_t crypto_cleanup(apr_crypto_t *f)
{
    apr_crypto_key_t *key;
    if (f->keys) {
        while ((key = apr_array_pop(f->keys))) {
            if (key->symKey) {
                PK11_FreeSymKey(key->symKey);
                key->symKey = NULL;
            }
        }
    }
    return APR_SUCCESS;
}
コード例 #11
0
ファイル: acmp.c プロジェクト: AntBean/ModSecurity
/**
 * Constructs fail paths on keyword trie
 */
static apr_status_t acmp_connect_fail_branches(ACMP *parser) {
    /* Already connected ? */
    acmp_node_t *child, *node, *goto_node;
    apr_array_header_t *arr, *arr2, *tmp;

    if (parser->is_failtree_done != 0) return APR_SUCCESS;

    parser->root_node->text = "";
    arr  = apr_array_make(parser->pool, 32, sizeof(acmp_node_t *));
    arr2 = apr_array_make(parser->pool, 32, sizeof(acmp_node_t *));

    parser->root_node->fail = parser->root_node;

    /* All first-level children will fail back to root node */
    for (child = parser->root_node->child; child != NULL; child = child->sibling) {
        child->fail = parser->root_node;
        *(acmp_node_t **)apr_array_push(arr) = child;
#ifdef DEBUG_ACMP
        fprintf(stderr, "fail direction: *%s* => *%s*\n", child->text, child->fail->text);
#endif
    }

    for (;;) {
        while (apr_is_empty_array(arr) == 0) {
            node = *(acmp_node_t **)apr_array_pop(arr);
            node->fail = parser->root_node;
            if (node->parent != parser->root_node) {
                goto_node = acmp_child_for_code(node->parent->fail, node->letter);
                node->fail = (goto_node != NULL) ? goto_node : parser->root_node;
            }
#ifdef DEBUG_ACMP
            fprintf(stderr, "fail direction: *%s* => *%s*\n", node->text, node->fail->text);
#endif
            child = node->child;
            while (child != NULL) {
                *(acmp_node_t **)apr_array_push(arr2) = child;
                child = child->sibling;
            }
        }
        if (apr_is_empty_array(arr2) != 0) break;

        tmp = arr;
        arr = arr2;
        arr2 = tmp;
    }
    acmp_connect_other_matches(parser, parser->root_node);
    if (parser->root_node->child != NULL) acmp_build_binary_tree(parser, parser->root_node);
    parser->is_failtree_done = 1;
    return APR_SUCCESS;
}
コード例 #12
0
ファイル: gpmondb.c プロジェクト: karthijrk/gpdb
static void gpdb_remove_success_files(apr_array_header_t *success_append_files, apr_pool_t *pool)
{
	void *file_slot = NULL;
	while ((file_slot = apr_array_pop(success_append_files)))
	{
		const char *file_name = (*(char**)file_slot);
		if (file_name)
		{
			if (apr_file_remove(file_name, pool) != APR_SUCCESS)
			{
				gpmon_warningx(FLINE, 0, "failed removing file:%s", file_name);
			}
		}
	}
}
コード例 #13
0
/* output:p_ipsubnet_list */
static void get_ipsubnet_list_from_file_content (request_rec *r,
                                                 apr_pool_t *mp,
                                                 char *file_content,
                                                 apr_int64_t file_len,
                                                 apr_array_header_t **p_ipsubnet_list)
{
    int i, j, k;
    int cr = 0, cn = 0;
    apr_status_t rv;
    char *tp;
    apr_ipsubnet_t **pip;
    char errmsg_buf[120];

    *p_ipsubnet_list = apr_array_make (mp, 0, sizeof(apr_ipsubnet_t*));
    for (i = j = 0; i <= file_len; i++) {
        if (file_content[i] == '\r' || file_content[i] == '\n') {
            file_content[i] == '\r' ? cr++ : cn++;
            for (k = j; k < i; k++) {
                if (file_content[i] != ' ')
                    break;
            }
                /*be sure not a blank line */
            if (k < i) {
                pip = apr_array_push (*p_ipsubnet_list);
                file_content[i] = '\0';
                if (tp = ap_strchr (file_content + j, '/')) {
                    *tp++ = '\0';
                    rv = apr_ipsubnet_create (pip, file_content + j, tp, mp);
                }
                else {
                    rv = apr_ipsubnet_create (pip, file_content + j, NULL, mp);
                }
                if (rv != APR_SUCCESS) {
                    apr_array_pop (*p_ipsubnet_list);
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                                  "invalid ipsubnet address at line %d",
                                  MAX (cr, cn));
#ifdef DEBUG
                    apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf));
                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                                  "%s", errmsg_buf);
#endif
                }
            }
            j = i + 1;
        }
    }
}
コード例 #14
0
ファイル: h2_from_h1.c プロジェクト: LPardue/mod_h2
static apr_status_t parse_header(h2_from_h1 *from_h1, ap_filter_t* f, 
                                 char *line) {
    if (line[0] == ' ' || line[0] == '\t') {
        /* continuation line from the header before this */
        while (line[0] == ' ' || line[0] == '\t') {
            ++line;
        }
        
        char **plast = apr_array_pop(from_h1->hlines);
        if (plast == NULL) {
            /* not well formed */
            return APR_EINVAL;
        }
        APR_ARRAY_PUSH(from_h1->hlines, const char*) = apr_psprintf(from_h1->pool, "%s %s", *plast, line);
    }
    else {
コード例 #15
0
ファイル: template.c プロジェクト: diroussel/lua-web-tools
/*
 * Processes a 'if' element.
 */
static apr_status_t process_if (parser_rec *p, const char *element,
		int states, apr_table_t *attrs) {
	block_t *block;
	template_node_t *n;
	apr_status_t status;

	if ((states & TEMPLATE_SOPEN) != 0) {
		block = (block_t *) apr_array_push(p->b);
		block->type = TEMPLATE_TIF;
		block->if_start = p->t->nelts;	
		block->if_last = p->t->nelts;
		block->if_cnt = 0;

		n = (template_node_t *) apr_array_push(p->t);
		n->type = TEMPLATE_TIF;
		n->if_cond = apr_table_get(attrs, "cond");
		if (n->if_cond == NULL) {
			return parse_error(p, "missing attribute 'cond'");
		}
		if ((status = compile_exp(p, n->if_cond, &n->if_index))
				!= APR_SUCCESS) {
			return status;
		}
		n->if_next = -1;
	}	

	if ((states & TEMPLATE_SCLOSE) != 0) {
		block = (block_t *) apr_array_pop(p->b);
		if (block == NULL || block->type != TEMPLATE_TIF) {
			return parse_error(p, "no 'if' to close");
		}

		if (block->if_last != -1) {
			n = ((template_node_t *) p->t->elts) + block->if_last;
			n->if_next = p->t->nelts;
		}

		n = ((template_node_t *) p->t->elts) + block->if_start;
		while (block->if_cnt > 0) {
			n = ((template_node_t *) p->t->elts) + n->if_next;
			(n - 1)->jump_next = p->t->nelts;
			block->if_cnt--;
		}
	}
	
	return APR_SUCCESS;
}
コード例 #16
0
ファイル: mod_lily.c プロジェクト: akavi/lily
/**
var post: Hash[String, Tainted[String]]

This contains key+value pairs that were sent to the server as POST variables.
Any pair that has a key or a value that is not valid utf-8 will not be present.
*/
static lily_value *load_var_post(lily_options *options, uint16_t *unused)
{
    lily_value *v = lily_new_empty_value();
    lily_move_hash_f(MOVE_DEREF_NO_GC, v, lily_new_hash_val());
    lily_hash_val *hash_val = v->value.hash;
    request_rec *r = (request_rec *)options->data;

    apr_array_header_t *pairs;
    apr_off_t len;
    apr_size_t size;
    char *buffer;

    /* Credit: I found out how to use this by reading httpd 2.4's mod_lua
       (specifically req_parsebody of lua_request.c). */
    int res = ap_parse_form_data(r, NULL, &pairs, -1, 1024 * 8);
    if (res == OK) {
        while (pairs && !apr_is_empty_array(pairs)) {
            ap_form_pair_t *pair = (ap_form_pair_t *) apr_array_pop(pairs);
            if (lily_is_valid_utf8(pair->name) == 0)
                continue;

            apr_brigade_length(pair->value, 1, &len);
            size = (apr_size_t) len;
            buffer = lily_malloc(size + 1);

            if (lily_is_valid_utf8(buffer) == 0) {
                lily_free(buffer);
                continue;
            }

            apr_brigade_flatten(pair->value, buffer, &size);
            buffer[len] = 0;

            lily_value *elem_key = lily_new_string(pair->name);
            /* Give the buffer to the value to save memory. */
            lily_value *elem_raw_value = lily_new_string_take(buffer);
            lily_value *elem_value = bind_tainted_of(elem_raw_value);

            apache_add_unique_hash_entry(options->sipkey, hash_val, elem_key,
                    elem_value);
        }
    }

    return v;
}
コード例 #17
0
ファイル: io_dir.c プロジェクト: LuaDist/lua-apr
int lua_apr_dir_remove_recursive(lua_State *L)
{
  apr_status_t status;
  apr_pool_t *outer_pool; /* used to store todo/done arrays and directory pathnames */
  apr_pool_t *middle_pool; /* used to store directory handles (apr_dir_t structs) */
  apr_pool_t *inner_pool; /* used to store pathnames of non-subdirectory entries */
  apr_array_header_t *todo, *done;
  apr_dir_t *directory;
  apr_finfo_t info;
  char **top, *tmp;
  const char *filepath;
  int allocation_counter;

  directory = NULL;
  outer_pool = middle_pool = inner_pool = NULL;
  filepath = luaL_checkstring(L, 1);
  allocation_counter = 0;

  status = apr_pool_create(&outer_pool, NULL);
  if (APR_SUCCESS == status)
    status = apr_pool_create(&middle_pool, NULL);
  if (APR_SUCCESS == status)
    status = apr_pool_create(&inner_pool, NULL);
  if (APR_SUCCESS != status)
    goto cleanup;

# define out_of_memory do { \
    status = APR_ENOMEM; \
    goto cleanup; \
  } while (0)

# define push_filepath(stack, filepath) do { \
    const char **p = apr_array_push(stack); \
    if (p != NULL) *p = filepath; else out_of_memory; \
  } while (0)

  todo = apr_array_make(outer_pool, 0, sizeof filepath);
  done = apr_array_make(outer_pool, 0, sizeof filepath);
  if (todo == NULL || done == NULL)
    out_of_memory;

  push_filepath(todo, filepath);

  while ((top = apr_array_pop(todo))) {
    filepath = *(char**)top;
    apr_pool_clear(middle_pool);
    status = apr_dir_open(&directory, filepath, middle_pool);
    if (status != APR_SUCCESS) {
      directory = NULL;
      goto cleanup;
    }
    for (;;) {
      /* This is a compromise between having `inner_pool' grow almost unbounded
       * on very large directories (e.g. ~/Maildir/) and clearing it for every
       * non-subdirectory pathname that's allocated (very inefficient). */
      if (allocation_counter % 1000 == 0)
        apr_pool_clear(inner_pool);
      /* FIXME?! apr_dir_read() uses directory->pool (middle_pool) for allocation */
      status = apr_dir_read(&info, APR_FINFO_NAME|APR_FINFO_TYPE|APR_FINFO_LINK, directory);
      if (APR_STATUS_IS_ENOENT(status))
        break; /* no more entries */
      else if (status != APR_SUCCESS && status != APR_INCOMPLETE)
        goto cleanup; /* something went wrong */
      else if (filename_symbolic(info.name))
        continue; /* bogus entry */
      else if (info.filetype == APR_DIR) {
        /* recurse into subdirectory */
        status = apr_filepath_merge(&tmp, filepath, info.name, 0, outer_pool);
        if (status != APR_SUCCESS)
          goto cleanup;
        push_filepath(todo, tmp);
      } else {
        /* delete non-subdirectory entry */
        status = apr_filepath_merge(&tmp, filepath, info.name, 0, inner_pool);
        allocation_counter++;
        if (APR_SUCCESS == status)
          status = apr_file_remove(tmp, inner_pool);
        if (APR_SUCCESS != status)
          goto cleanup;
      }
    }
    status = apr_dir_close(directory);
    directory = NULL;
    if (status != APR_SUCCESS)
      goto cleanup;
    push_filepath(done, filepath);
  }

# undef out_of_memory
# undef push_filepath

  while ((top = apr_array_pop(done))) {
    filepath = *(char**)top;
    if (allocation_counter++ % 100 == 0)
      apr_pool_clear(middle_pool);
    status = apr_dir_remove(filepath, middle_pool);
    if (status != APR_SUCCESS)
      goto cleanup;
  }

cleanup:

  if (directory != NULL)
    apr_dir_close(directory);
  if (inner_pool != NULL)
    apr_pool_destroy(inner_pool);
  if (middle_pool != NULL)
    apr_pool_destroy(middle_pool);
  if (outer_pool != NULL)
    apr_pool_destroy(outer_pool);

  return push_status(L, status);
}
コード例 #18
0
ファイル: compat.c プロジェクト: 2asoft/freebsd
/* Implements svn_log_entry_receiver_t; helper for slow_get_locations.
   As input, takes log_receiver_baton (defined above) and attempts to
   "fill in" locations in the baton over the course of many
   iterations. */
static svn_error_t *
log_receiver(void *baton,
             svn_log_entry_t *log_entry,
             apr_pool_t *pool)
{
  struct log_receiver_baton *lrb = baton;
  apr_pool_t *hash_pool = apr_hash_pool_get(lrb->locations);
  const char *current_path = lrb->last_path;
  const char *prev_path;

  /* No paths were changed in this revision.  Nothing to do. */
  if (! log_entry->changed_paths2)
    return SVN_NO_ERROR;

  /* If we've run off the end of the path's history, there's nothing
     to do.  (This should never happen with a properly functioning
     server, since we'd get no more log messages after the one where
     path was created.  But a malfunctioning server shouldn't cause us
     to trigger an assertion failure.) */
  if (! current_path)
    return SVN_NO_ERROR;

  /* If we haven't found our peg path yet, and we are now looking at a
     revision equal to or older than the peg revision, then our
     "current" path is our peg path. */
  if ((! lrb->peg_path) && (log_entry->revision <= lrb->peg_revision))
    lrb->peg_path = apr_pstrdup(lrb->pool, current_path);

  /* Determine the paths for any of the revisions for which we haven't
     gotten paths already. */
  while (lrb->location_revisions->nelts)
    {
      svn_revnum_t next = APR_ARRAY_IDX(lrb->location_revisions,
                                        lrb->location_revisions->nelts - 1,
                                        svn_revnum_t);
      if (log_entry->revision <= next)
        {
          apr_hash_set(lrb->locations,
                       apr_pmemdup(hash_pool, &next, sizeof(next)),
                       sizeof(next),
                       apr_pstrdup(hash_pool, current_path));
          apr_array_pop(lrb->location_revisions);
        }
      else
        break;
    }

  /* Figure out at which repository path our object of interest lived
     in the previous revision. */
  SVN_ERR(prev_log_path(&prev_path, NULL, NULL, log_entry->changed_paths2,
                        current_path, lrb->kind, log_entry->revision, pool));

  /* Squirrel away our "next place to look" path (suffer the strcmp
     hit to save on allocations). */
  if (! prev_path)
    lrb->last_path = NULL;
  else if (strcmp(prev_path, current_path) != 0)
    lrb->last_path = apr_pstrdup(lrb->pool, prev_path);

  return SVN_NO_ERROR;
}
コード例 #19
0
ファイル: mod_pgasp.c プロジェクト: Maxime2/pgasp
static int pgasp_handler (request_rec * r)
{
   char cursor_string[256];
   pgasp_config* config = (pgasp_config*) ap_get_module_config(r->server->module_config, &pgasp_module ) ;
   pgasp_dir_config* dir_config = (pgasp_dir_config*) ap_get_module_config(r->per_dir_config, &pgasp_module ) ;
   apr_table_t * GET = NULL, *GETargs = NULL;
   apr_array_header_t * POST;
   PGconn * pgc;
   PGresult * pgr;
   int i, j, allowed_to_serve, filename_length = 0;
   int field_count, tuple_count;
   char * requested_file;
   char *basename;
   params_t params;

   /* PQexecParams doesn't seem to like zero-length strings, so we feed it a dummy */
   const char * dummy_get = "nothing";
   const char * dummy_user = "******";

   const char * cursor_values[2] = { r -> args ? apr_pstrdup(r->pool, r -> args) : dummy_get, r->user ? r->user : dummy_user };
   int cursor_value_lengths[2] = { strlen(cursor_values[0]), strlen(cursor_values[1]) };
   int cursor_value_formats[2] = { 0, 0 };

   if (!r -> handler || strcmp (r -> handler, "pgasp-handler") ) return DECLINED;
   if (!r -> method || (strcmp (r -> method, "GET") && strcmp (r -> method, "POST")) ) return DECLINED;

   if (config->is_enabled != true) return OK; /* pretending we have responded, may return DECLINED in the future */

   requested_file = apr_pstrdup (r -> pool, r -> path_info /*filename*/);
   i = strlen(requested_file) - 1;

   while (i > 0)
   {
     if (requested_file[i] == '.') filename_length = i;
     if (requested_file[i] == '/') break;
     i--;
   }

   if (i >= 0) {
     requested_file += i+1; /* now pointing to foo.pgasp instead of /var/www/.../foo.pgasp */
     if (filename_length > i) filename_length -= i+1;
   }

   allowed_to_serve = false;

   for (i = 0; i < config->allowed_count; i++)
   {
      if (!strcmp(config->allowed[i], requested_file))
      {
         allowed_to_serve = true;
         break;
      }
   }
   if (config->allowed_count == 0) allowed_to_serve = true;

   if (!allowed_to_serve)
   {
      ap_set_content_type(r, "text/plain");
      ap_rprintf(r, "Hello there\nThis is PGASP\nEnabled: %s\n", config->is_enabled ? "On" : "Off");
      ap_rprintf(r, "Requested: %s\n", requested_file);
      ap_rprintf(r, "Allowed: %s\n", allowed_to_serve ? "Yes" : "No");

      return OK; /* pretending we have served the file, may return HTTP_FORDIDDEN in the future */
   }

   if (filename_length == 0) {
     basename = requested_file;
   } else {
     basename = apr_pstrndup(r->pool, requested_file, filename_length);
   }

   ap_args_to_table(r, &GETargs);
   if (OK != ap_parse_form_data(r, NULL, &POST, -1, (~((apr_size_t)0)))) {
     __(r->server, " ** ap_parse_form_data is NOT OK");
   }
   GET = (NULL == GET) ? GETargs : apr_table_overlay(r->pool, GETargs, GET);

   // move all POST parameters into GET table
   {
     ap_form_pair_t *pair;
     char *buffer;
     apr_off_t len;
     apr_size_t size;
     while (NULL != (pair = apr_array_pop(POST))) {
       apr_brigade_length(pair->value, 1, &len);
       size = (apr_size_t) len;
       buffer = apr_palloc(r->pool, size + 1);
       apr_brigade_flatten(pair->value, buffer, &size);
       buffer[len] = 0;
       apr_table_setn(GET, apr_pstrdup(r->pool, pair->name), buffer); //should name and value be ap_unescape_url() -ed?
       //       __(r->server, "POST[%s]: %s", pair->name, buffer);
     }
   }

   params.r = r;
   params.args = NULL;
   apr_table_do(tab_args, &params, GET, NULL);
   params.args = apr_pstrcat(r->pool, "&", params.args, "&", NULL);

   cursor_values[0] = params.args;
   cursor_value_lengths[0] = strlen(cursor_values[0]);

   /* set response content type according to configuration or to default value */
   ap_set_content_type(r, dir_config->content_type_set ? dir_config->content_type : "text/html");

   /* now connecting to Postgres, getting function output, and printing it */

   pgc = pgasp_pool_open (r->server);

   if (PQstatus(pgc) != CONNECTION_OK)
   {
      spit_pg_error ("connect");
      pgasp_pool_close(r->server, pgc);
      return OK;
   }

   /* removing extention (.pgasp or other) from file name, and adding "f_" for function name, i.e. foo.pgasp becomes psp_foo() */
   snprintf(cursor_string,
	    sizeof(cursor_string),
	    "select * from f_%s($1::varchar)",
	    basename);

   /* passing GET as first (and only) parameter */
   if (0 == PQsendQueryParams (pgc, cursor_string, 1, NULL, cursor_values, cursor_value_lengths, cursor_value_formats, 0)) {
      spit_pg_error ("sending async query with params");
      return clean_up_connection(r->server);
   }

   if (0 == PQsetSingleRowMode(pgc)) {
     ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server, "can not fall into single raw mode to fetch data");
   }

   while (NULL != (pgr = PQgetResult(pgc))) {

     if (PQresultStatus(pgr) != PGRES_TUPLES_OK && PQresultStatus(pgr) != PGRES_SINGLE_TUPLE) {
       spit_pg_error ("fetch data");
       return clean_up_connection(r->server);
     }

     /* the following counts and for-loop may seem excessive as it's just 1 row/1 field, but might need it in the future */

     field_count = PQnfields(pgr);
     tuple_count = PQntuples(pgr);

     for (i = 0; i < tuple_count; i++)
       {
	 for (j = 0; j < field_count; j++) ap_rprintf(r, "%s", PQgetvalue(pgr, i, j));
	 ap_rprintf(r, "\n");
       }
     PQclear (pgr);
   }
   pgasp_pool_close(r->server, pgc);

   return OK;
}
コード例 #20
0
ファイル: engine_config.c プロジェクト: David-Hiker/waf-pe
/**********************************************************
 * 黑白名单相关的处理函数
 **********************************************************/
AP_DECLARE(int) ap_access_list_handle(int lst)
{
    apr_status_t rv;
    ap_directive_t *newdir;
    ap_directive_t *current;
    ap_directive_t *conftree;
    apr_array_header_t *acl_config;
    apr_pool_t *ptemp;
    char *cmd_name;
    const char **cmd_args;

    if ((lst < IP_BLACK) || (lst > ALL_LIST)) {
        return DECLINED;
    }

    /* 配置处理过程中的临时数据放在临时内存池里面 */
    apr_pool_create(&ptemp, pconf);
    apr_pool_tag(ptemp, "ptemp");

    /* 读取黑白名单的指令 */
    acl_config  = apr_array_make(ptemp, 1, sizeof(char *));
    rv = convert_access_list_query(lst, &acl_config);
    if (rv != OK) {
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
                     "query access list %d error", lst);
        return DECLINED;
    }

    /* 建立一颗临时的配置树 */
    conftree = NULL;
    current = conftree;

    while (1) {
        cmd_args = (const char **)apr_array_pop(acl_config);
        if (!cmd_args) {
            break;
        }
        cmd_name = ap_getword_conf(ptemp, cmd_args);
        newdir = (ap_directive_t *)apr_pcalloc(ptemp, sizeof(ap_directive_t));
        newdir->filename = "access list";
        newdir->line_num = (current == NULL) ? 1 : (current->line_num + 1);
        newdir->directive = apr_pstrdup(ptemp, cmd_name);
        newdir->args = apr_pstrdup(ptemp, *cmd_args);
        current = ap_add_node(&conftree, current, newdir, 0);
        if (conftree == NULL && current != NULL) {
            conftree = current;
        }
    }

    /* 指令下发调试 */
    for (current = conftree; current != NULL; current = current->next) {
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_main_server,
                     "%s: line[%d] directive[%s] args[%s]",
                     current->filename, current->line_num,
                     current->directive, current->args);
    }

    /* 处理黑白名单的指令 */
    if (conftree) {
        rv = ap_process_config_tree(ap_main_server, conftree,
                                    pconf, ptemp);
    }

    apr_pool_destroy(ptemp);

    return rv;
}
コード例 #21
0
static svn_error_t *
resolve_relative_external_url(const char **resolved_url,
                              const svn_wc_external_item2_t *item,
                              const char *repos_root_url,
                              const char *parent_dir_url,
                              apr_pool_t *result_pool,
                              apr_pool_t *scratch_pool)
{
  const char *url = item->url;
  apr_uri_t parent_dir_uri;
  apr_status_t status;

  *resolved_url = item->url;

  /* If the URL is already absolute, there is nothing to do. */
  if (svn_path_is_url(url))
    {
      /* "http://server/path" */
      *resolved_url = svn_uri_canonicalize(url, result_pool);
      return SVN_NO_ERROR;
    }

  if (url[0] == '/')
    {
      /* "/path", "//path", and "///path" */
      int num_leading_slashes = 1;
      if (url[1] == '/')
        {
          num_leading_slashes++;
          if (url[2] == '/')
            num_leading_slashes++;
        }

      /* "//schema-relative" and in some cases "///schema-relative".
         This last format is supported on file:// schema relative. */
      url = apr_pstrcat(scratch_pool,
                        apr_pstrndup(scratch_pool, url, num_leading_slashes),
                        svn_relpath_canonicalize(url + num_leading_slashes,
                                                 scratch_pool),
                        (char*)NULL);
    }
  else
    {
      /* "^/path" and "../path" */
      url = svn_relpath_canonicalize(url, scratch_pool);
    }

  /* Parse the parent directory URL into its parts. */
  status = apr_uri_parse(scratch_pool, parent_dir_url, &parent_dir_uri);
  if (status)
    return svn_error_createf(SVN_ERR_BAD_URL, 0,
                             "Illegal parent directory URL '%s'",
                             parent_dir_url);

  /* If the parent directory URL is at the server root, then the URL
     may have no / after the hostname so apr_uri_parse() will leave
     the URL's path as NULL. */
  if (! parent_dir_uri.path)
    parent_dir_uri.path = apr_pstrmemdup(scratch_pool, "/", 1);
  parent_dir_uri.query = NULL;
  parent_dir_uri.fragment = NULL;

  /* Handle URLs relative to the current directory or to the
     repository root.  The backpaths may only remove path elements,
     not the hostname.  This allows an external to refer to another
     repository in the same server relative to the location of this
     repository, say using SVNParentPath. */
  if ((0 == strncmp("../", url, 3)) ||
      (0 == strncmp("^/", url, 2)))
    {
      apr_array_header_t *base_components;
      apr_array_header_t *relative_components;
      int i;

      /* Decompose either the parent directory's URL path or the
         repository root's URL path into components.  */
      if (0 == strncmp("../", url, 3))
        {
          base_components = svn_path_decompose(parent_dir_uri.path,
                                               scratch_pool);
          relative_components = svn_path_decompose(url, scratch_pool);
        }
      else
        {
          apr_uri_t repos_root_uri;

          status = apr_uri_parse(scratch_pool, repos_root_url,
                                 &repos_root_uri);
          if (status)
            return svn_error_createf(SVN_ERR_BAD_URL, 0,
                                     "Illegal repository root URL '%s'",
                                     repos_root_url);

          /* If the repository root URL is at the server root, then
             the URL may have no / after the hostname so
             apr_uri_parse() will leave the URL's path as NULL. */
          if (! repos_root_uri.path)
            repos_root_uri.path = apr_pstrmemdup(scratch_pool, "/", 1);

          base_components = svn_path_decompose(repos_root_uri.path,
                                               scratch_pool);
          relative_components = svn_path_decompose(url + 2, scratch_pool);
        }

      for (i = 0; i < relative_components->nelts; ++i)
        {
          const char *component = APR_ARRAY_IDX(relative_components,
                                                i,
                                                const char *);
          if (0 == strcmp("..", component))
            {
              /* Constructing the final absolute URL together with
                 apr_uri_unparse() requires that the path be absolute,
                 so only pop a component if the component being popped
                 is not the component for the root directory. */
              if (base_components->nelts > 1)
                apr_array_pop(base_components);
            }
          else
            APR_ARRAY_PUSH(base_components, const char *) = component;
        }

      parent_dir_uri.path = (char *)svn_path_compose(base_components,
                                                     scratch_pool);
      *resolved_url = svn_uri_canonicalize(apr_uri_unparse(scratch_pool,
                                                           &parent_dir_uri, 0),
                                       result_pool);
      return SVN_NO_ERROR;
    }
コード例 #22
0
ファイル: move-cmd.c プロジェクト: aosm/subversion
/* This implements the `svn_opt_subcommand_t' interface. */
svn_error_t *
svn_cl__move(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;
  const char *dst_path;
  svn_commit_info_t *commit_info = NULL;
  svn_error_t *err;

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

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

  if (opt_state->start_revision.kind != svn_opt_revision_unspecified
      && opt_state->start_revision.kind != svn_opt_revision_head)
    {
      return svn_error_create
        (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
         _("Cannot specify revisions (except HEAD) with move operations"));
    }

  if (! opt_state->quiet)
    svn_cl__get_notifier(&ctx->notify_func2, &ctx->notify_baton2, FALSE,
                         FALSE, FALSE, pool);

  dst_path = APR_ARRAY_IDX(targets, targets->nelts - 1, const char *);
  apr_array_pop(targets);

  if (! svn_path_is_url(dst_path))
    {
      ctx->log_msg_func3 = NULL;
      if (opt_state->message || opt_state->filedata || opt_state->revprop_table)
        return svn_error_create
          (SVN_ERR_CL_UNNECESSARY_LOG_MESSAGE, NULL,
           _("Local, non-commit operations do not take a log message "
             "or revision properties"));
    }

  if (ctx->log_msg_func3)
    SVN_ERR(svn_cl__make_log_msg_baton(&(ctx->log_msg_baton3), opt_state,
                                       NULL, ctx->config, pool));

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

  err = svn_client_move5(&commit_info, targets, dst_path, opt_state->force,
                         TRUE, opt_state->parents, opt_state->revprop_table,
                         ctx, pool);

  if (err)
    err = svn_cl__may_need_force(err);

  if (ctx->log_msg_func3)
    SVN_ERR(svn_cl__cleanup_log_msg(ctx->log_msg_baton3, err, pool));
  else if (err)
    return err;

  if (commit_info && ! opt_state->quiet)
    SVN_ERR(svn_cl__print_commit_info(commit_info, pool));

  return SVN_NO_ERROR;
}
コード例 #23
0
ファイル: run_code.c プロジェクト: aidanhs/teeterl
term_t proc_main(process_t *proc, int reductions, term_t *retval)
{
	int allocated_reductions = reductions;		//save initial value to update global counter on return
	apr_time_t main_started = apr_time_now();	//NB: possible performance hit
	apr_interval_time_t elapsed;

	term_t exc_class;
	term_t reason;

	apr_array_header_t *cs = proc->cstack;
	apr_array_header_t *ds = proc->dstack;

	while (reductions > 0)
	{
		apr_byte_t opcode;

resume_after_catch:

		if (proc->stopped_on_breakpoint)
		{
			opcode = proc->breakpoint_command;
			proc->stopped_on_breakpoint = 0;
		}
		else
		{
			opcode = (apr_byte_t)*proc->ip++;
		} 

		switch (opcode)
		{
#include "run_cases.inc"
		default:
			fatal_err("Bad opcode");
		}
	}
	
	// update global reductions counts
	g_reductions += (allocated_reductions - reductions);
	g_reductions0 += (allocated_reductions - reductions);
	
	// update global runtime measures
	elapsed = apr_time_now() - main_started;
	g_runtime += elapsed;
	g_runtime0 += elapsed;

	return AI_YIELD;

cellar:
	// before we forget many stack frames, should be done even outside catch
	proc_trace_stack(proc);
	proc_trace_locals(proc);

	if (proc->catches->nelts > 0)
	{
		catch_t *cat = ((catch_t *)proc->catches->elts)+ proc->catches->nelts-1;

		proc->cstack->nelts = cat->csp;
		proc->dstack->nelts = cat->dsp;
		proc->ebp = cat->ebp;

		proc->mod_index = cat->mod_index;
		proc->code = code_base_starts(proc->base, proc->mod_index);
		proc->ip = cat->ip;

		apr_array_pop(proc->catches);

		push(exc_class);
		push(reason);
		
		// NB: yielding now may cause a performance hit as compiler invisibly
		// generates helluva catches in guards, try to continue without yielding
		//return AI_YIELD;
		
		goto resume_after_catch;
	}
	else
	{
		g_reductions += (allocated_reductions - reductions);
		g_reductions0 += (allocated_reductions - reductions);

		elapsed = apr_time_now() - main_started;
		g_runtime += elapsed;
		g_runtime0 += elapsed;
		
		*retval = reason;
		return exc_class;
	}
}
コード例 #24
0
ファイル: log-cmd.c プロジェクト: niallo/mwbuild
/* This implements `svn_log_entry_receiver_t', printing the logs in XML.
 *
 * BATON is of type `struct log_receiver_baton'.
 *
 * Here is an example of the output; note that the "<log>" and
 * "</log>" tags are not emitted by this function:
 *
 * $ svn log --xml -r 1648:1649
 * <log>
 * <logentry
 *    revision="1648">
 * <author>david</author>
 * <date>2002-04-06T16:34:51.428043Z</date>
 * <msg> * packages/rpm/subversion.spec : Now requires apache 2.0.36.
 * </msg>
 * </logentry>
 * <logentry
 *    revision="1649">
 * <author>cmpilato</author>
 * <date>2002-04-06T17:01:28.185136Z</date>
 * <msg>Fix error handling when the $EDITOR is needed but unavailable.  Ah
 * ... now that&apos;s *much* nicer.
 *
 * * subversion/clients/cmdline/util.c
 *   (svn_cl__edit_externally): Clean up the &quot;no external editor&quot;
 *   error message.
 *   (svn_cl__get_log_message): Wrap &quot;no external editor&quot;
 *   errors with helpful hints about the -m and -F options.
 *
 * * subversion/libsvn_client/commit.c
 *   (svn_client_commit): Actually capture and propogate &quot;no external
 *   editor&quot; errors.</msg>
 * </logentry>
 * </log>
 *
 */
static svn_error_t *
log_entry_receiver_xml(void *baton,
                       svn_log_entry_t *log_entry,
                       apr_pool_t *pool)
{
  struct log_receiver_baton *lb = baton;
  /* Collate whole log message into sb before printing. */
  svn_stringbuf_t *sb = svn_stringbuf_create("", pool);
  char *revstr;
  const char *author;
  const char *date;
  const char *message;

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

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

  if (author)
    author = svn_xml_fuzzy_escape(author, pool);
  if (date)
    date = svn_xml_fuzzy_escape(date, pool);
  if (message)
    message = svn_xml_fuzzy_escape(message, pool);

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

  if (! SVN_IS_VALID_REVNUM(log_entry->revision))
    {
      svn_xml_make_close_tag(&sb, pool, "logentry");
      SVN_ERR(svn_cl__error_checked_fputs(sb->data, stdout));
      apr_array_pop(lb->merge_stack);

      return SVN_NO_ERROR;
    }

  revstr = apr_psprintf(pool, "%ld", log_entry->revision);
  /* <logentry revision="xxx"> */
  svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "logentry",
                        "revision", revstr, NULL);

  /* <author>xxx</author> */
  svn_cl__xml_tagged_cdata(&sb, pool, "author", author);

  /* Print the full, uncut, date.  This is machine output. */
  /* According to the docs for svn_log_entry_receiver_t, either
     NULL or the empty string represents no date.  Avoid outputting an
     empty date element. */
  if (date && date[0] == '\0')
    date = NULL;
  /* <date>xxx</date> */
  svn_cl__xml_tagged_cdata(&sb, pool, "date", date);

  if (log_entry->changed_paths)
    {
      apr_hash_index_t *hi;
      char *path;

      /* <paths> */
      svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "paths",
                            NULL);

      for (hi = apr_hash_first(pool, log_entry->changed_paths);
           hi != NULL;
           hi = apr_hash_next(hi))
        {
          void *val;
          char action[2];
          svn_log_changed_path_t *log_item;

          apr_hash_this(hi, (void *) &path, NULL, &val);
          log_item = val;

          action[0] = log_item->action;
          action[1] = '\0';
          if (log_item->copyfrom_path
              && SVN_IS_VALID_REVNUM(log_item->copyfrom_rev))
            {
              /* <path action="X" copyfrom-path="xxx" copyfrom-rev="xxx"> */
              svn_stringbuf_t *escpath = svn_stringbuf_create("", pool);
              svn_xml_escape_attr_cstring(&escpath,
                                          log_item->copyfrom_path, pool);
              revstr = apr_psprintf(pool, "%ld",
                                    log_item->copyfrom_rev);
              svn_xml_make_open_tag(&sb, pool, svn_xml_protect_pcdata, "path",
                                    "action", action,
                                    "copyfrom-path", escpath->data,
                                    "copyfrom-rev", revstr, NULL);
            }
          else
            {
              /* <path action="X"> */
              svn_xml_make_open_tag(&sb, pool, svn_xml_protect_pcdata, "path",
                                    "action", action, NULL);
            }
          /* xxx</path> */
          svn_xml_escape_cdata_cstring(&sb, path, pool);
          svn_xml_make_close_tag(&sb, pool, "path");
        }

      /* </paths> */
      svn_xml_make_close_tag(&sb, pool, "paths");
    }

  if (message != NULL)
    {
      /* <msg>xxx</msg> */
      svn_cl__xml_tagged_cdata(&sb, pool, "msg", message);
    }

  svn_compat_log_revprops_clear(log_entry->revprops);
  if (log_entry->revprops && apr_hash_count(log_entry->revprops) > 0)
    {
      svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "revprops", NULL);
      SVN_ERR(svn_cl__print_xml_prop_hash(&sb, log_entry->revprops,
                                          FALSE, /* name_only */
                                          pool));
      svn_xml_make_close_tag(&sb, pool, "revprops");
    }

  if (log_entry->has_children)
    APR_ARRAY_PUSH(lb->merge_stack, svn_revnum_t) = log_entry->revision;
  else
    svn_xml_make_close_tag(&sb, pool, "logentry");

  SVN_ERR(svn_cl__error_checked_fputs(sb->data, stdout));

  return SVN_NO_ERROR;
}
コード例 #25
0
ファイル: log-cmd.c プロジェクト: niallo/mwbuild
/* 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;
}
コード例 #26
0
CStringA CPathUtils::GetAbsoluteURL
    ( const CStringA& URL
    , const CStringA& repositoryRootURL
    , const CStringA& parentPathURL)
{
    CStringA errorResult;
    SVNPool pool;

    /* If the URL is already absolute, there is nothing to do. */

    const char *canonicalized_url = svn_uri_canonicalize (URL, pool);
    if (svn_path_is_url (canonicalized_url))
        return canonicalized_url;

    /* Parse the parent directory URL into its parts. */

    apr_uri_t parent_dir_parsed_uri;
    if (apr_uri_parse (pool, parentPathURL, &parent_dir_parsed_uri))
        return errorResult;

    /* If the parent directory URL is at the server root, then the URL
       may have no / after the hostname so apr_uri_parse() will leave
       the URL's path as NULL. */

    if (! parent_dir_parsed_uri.path)
        parent_dir_parsed_uri.path = apr_pstrmemdup (pool, "/", 1);

    /* Handle URLs relative to the current directory or to the
       repository root.  The backpaths may only remove path elements,
       not the hostname.  This allows an external to refer to another
       repository in the same server relative to the location of this
       repository, say using SVNParentPath. */

    if ((0 == strncmp("../", URL, 3)) || (0 == strncmp("^/", URL, 2)))
    {
        apr_array_header_t *base_components = NULL;
        apr_array_header_t *relative_components = NULL;

        /* Decompose either the parent directory's URL path or the
           repository root's URL path into components.  */

        if (0 == strncmp ("../", URL, 3))
        {
            base_components
                = svn_path_decompose (parent_dir_parsed_uri.path, pool);
            relative_components
                = svn_path_decompose (canonicalized_url, pool);
        }
        else
        {
            apr_uri_t repos_root_parsed_uri;
            if (apr_uri_parse(pool, repositoryRootURL, &repos_root_parsed_uri))
                return errorResult;

            /* If the repository root URL is at the server root, then
               the URL may have no / after the hostname so
               apr_uri_parse() will leave the URL's path as NULL. */

            if (! repos_root_parsed_uri.path)
                repos_root_parsed_uri.path = apr_pstrmemdup (pool, "/", 1);

            base_components
                = svn_path_decompose (repos_root_parsed_uri.path, pool);
            relative_components
                = svn_path_decompose (canonicalized_url + 2, pool);
        }

        for (int i = 0; i < relative_components->nelts; ++i)
        {
            const char *component
                = APR_ARRAY_IDX(relative_components, i, const char *);

            if (0 == strcmp("..", component))
            {
                /* Constructing the final absolute URL together with
                   apr_uri_unparse() requires that the path be absolute,
                   so only pop a component if the component being popped
                   is not the component for the root directory. */

                if (base_components->nelts > 1)
                    apr_array_pop (base_components);
            }
            else
                APR_ARRAY_PUSH (base_components, const char *) = component;
        }

        parent_dir_parsed_uri.path = (char *)svn_path_compose(base_components,
                                                            pool);
        parent_dir_parsed_uri.query = NULL;
        parent_dir_parsed_uri.fragment = NULL;

        return apr_uri_unparse (pool, &parent_dir_parsed_uri, 0);
    }
コード例 #27
0
static svn_error_t *
start_element(int *elem, void *baton, int parent_state, const char *nspace,
              const char *elt_name, const char **atts)
{
  replay_baton_t *rb = baton;

  const svn_ra_neon__xml_elm_t *elm
    = svn_ra_neon__lookup_xml_elem(editor_report_elements, nspace, elt_name);

  if (! elm)
    {
      *elem = NE_XML_DECLINE;
      return SVN_NO_ERROR;
    }

  if (parent_state == ELEM_root)
    {
      /* If we're at the root of the tree, the element has to be the editor
       * report itself. */
      if (elm->id != ELEM_editor_report)
        return UNEXPECTED_ELEMENT(nspace, elt_name);
    }
  else if (parent_state != ELEM_editor_report)
    {
      /* If we're not at the root, our parent has to be the editor report,
       * since we don't actually nest any elements. */
      return UNEXPECTED_ELEMENT(nspace, elt_name);
    }

  switch (elm->id)
    {
    case ELEM_target_revision:
      {
        const char *crev = svn_xml_get_attr_value("rev", atts);
        if (! crev)
          return MISSING_ATTR(nspace, elt_name, "rev");
        else
          return rb->editor->set_target_revision(rb->edit_baton,
                                                 SVN_STR_TO_REV(crev),
                                                 rb->pool);
      }
      break;

    case ELEM_open_root:
      {
        const char *crev = svn_xml_get_attr_value("rev", atts);

        if (! crev)
          return MISSING_ATTR(nspace, elt_name, "rev");
        else
          {
            apr_pool_t *subpool = svn_pool_create(rb->pool);
            void *dir_baton;
            SVN_ERR(rb->editor->open_root(rb->edit_baton,
                                          SVN_STR_TO_REV(crev), subpool,
                                          &dir_baton));
            push_dir(rb, dir_baton, "", subpool);
          }
      }
      break;

    case ELEM_delete_entry:
      {
        const char *path = svn_xml_get_attr_value("name", atts);
        const char *crev = svn_xml_get_attr_value("rev", atts);

        if (! path)
          return MISSING_ATTR(nspace, elt_name, "name");
        else if (! crev)
          return MISSING_ATTR(nspace, elt_name, "rev");
        else
          {
            dir_item_t *di = &TOP_DIR(rb);

            SVN_ERR(rb->editor->delete_entry(path, SVN_STR_TO_REV(crev),
                                             di->baton, di->pool));
          }
      }
      break;

    case ELEM_open_directory:
    case ELEM_add_directory:
      {
        const char *crev = svn_xml_get_attr_value("rev", atts);
        const char *name = svn_xml_get_attr_value("name", atts);

        if (! name)
          return MISSING_ATTR(nspace, elt_name, "name");
        else
          {
            dir_item_t *parent = &TOP_DIR(rb);
            apr_pool_t *subpool = svn_pool_create(parent->pool);
            svn_revnum_t rev;
            void *dir_baton;

            if (crev)
              rev = SVN_STR_TO_REV(crev);
            else
              rev = SVN_INVALID_REVNUM;

            if (elm->id == ELEM_open_directory)
              SVN_ERR(rb->editor->open_directory(name, parent->baton,
                                                 rev, subpool, &dir_baton));
            else if (elm->id == ELEM_add_directory)
              {
                const char *cpath = svn_xml_get_attr_value("copyfrom-path",
                                                           atts);

                crev = svn_xml_get_attr_value("copyfrom-rev", atts);

                if (crev)
                  rev = SVN_STR_TO_REV(crev);
                else
                  rev = SVN_INVALID_REVNUM;

                SVN_ERR(rb->editor->add_directory(name, parent->baton,
                                                  cpath, rev, subpool,
                                                  &dir_baton));
              }
            else
              SVN_ERR_MALFUNCTION();

            push_dir(rb, dir_baton, name, subpool);
          }
      }
      break;

    case ELEM_open_file:
    case ELEM_add_file:
      {
        const char *path = svn_xml_get_attr_value("name", atts);
        svn_revnum_t rev;

        dir_item_t *parent = &TOP_DIR(rb);

        if (! path)
          return MISSING_ATTR(nspace, elt_name, "name");

        svn_pool_clear(parent->file_pool);

        if (elm->id == ELEM_add_file)
          {
            const char *cpath = svn_xml_get_attr_value("copyfrom-path", atts);
            const char *crev = svn_xml_get_attr_value("copyfrom-rev", atts);

            if (crev)
              rev = SVN_STR_TO_REV(crev);
            else
              rev = SVN_INVALID_REVNUM;

            SVN_ERR(rb->editor->add_file(path, parent->baton, cpath, rev,
                                         parent->file_pool, &rb->file_baton));
          }
        else
          {
            const char *crev = svn_xml_get_attr_value("rev", atts);

            if (crev)
              rev = SVN_STR_TO_REV(crev);
            else
              rev = SVN_INVALID_REVNUM;

            SVN_ERR(rb->editor->open_file(path, parent->baton, rev,
                                          parent->file_pool,
                                          &rb->file_baton));
          }
      }
      break;

    case ELEM_apply_textdelta:
      if (! rb->file_baton)
        return svn_error_create
                 (SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                  _("Got apply-textdelta element without preceding "
                    "add-file or open-file"));
      else
        {
          const char *checksum = svn_xml_get_attr_value("checksum", atts);

          SVN_ERR(rb->editor->apply_textdelta(rb->file_baton,
                                              checksum,
                                              TOP_DIR(rb).file_pool,
                                              &rb->whandler,
                                              &rb->whandler_baton));

          rb->svndiff_decoder = svn_txdelta_parse_svndiff
                                  (rb->whandler, rb->whandler_baton,
                                   TRUE, TOP_DIR(rb).file_pool);
          rb->base64_decoder = svn_base64_decode(rb->svndiff_decoder,
                                                 TOP_DIR(rb).file_pool);
        }
      break;

    case ELEM_close_file:
      if (! rb->file_baton)
        return svn_error_create
                  (SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                   _("Got close-file element without preceding "
                     "add-file or open-file"));
      else
        {
          const char *checksum = svn_xml_get_attr_value("checksum", atts);

          SVN_ERR(rb->editor->close_file(rb->file_baton,
                                         checksum,
                                         TOP_DIR(rb).file_pool));
          rb->file_baton = NULL;
        }
      break;

    case ELEM_close_directory:
      if (rb->dirs->nelts == 0)
        return svn_error_create
                 (SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                  _("Got close-directory element without ever opening "
                    "a directory"));
      else
        {
          dir_item_t *di = &TOP_DIR(rb);

          SVN_ERR(rb->editor->close_directory(di->baton, di->pool));

          svn_pool_destroy(di->pool);

          apr_array_pop(rb->dirs);
        }
      break;

    case ELEM_change_file_prop:
    case ELEM_change_dir_prop:
      {
        const char *name = svn_xml_get_attr_value("name", atts);

        if (! name)
          return MISSING_ATTR(nspace, elt_name, "name");
        else
          {
            svn_pool_clear(rb->prop_pool);

            if (svn_xml_get_attr_value("del", atts))
              rb->prop_accum = NULL;
            else
              rb->prop_accum = svn_stringbuf_create("", rb->prop_pool);

            rb->prop_name = apr_pstrdup(rb->prop_pool, name);
          }
      }
      break;
    }

  *elem = elm->id;

  return SVN_NO_ERROR;
}
コード例 #28
0
ファイル: mod_rpaf.c プロジェクト: taladar/mod_rpaf
static int rpaf_post_read_request(request_rec *r) {
    char *fwdvalue, *val, *mask, *last_val;
    int i;
    apr_port_t tmpport;
    apr_pool_t *tmppool;
    const char *header_ip = NULL, *header_host = NULL, *header_https = NULL, *header_port = NULL;
    rpaf_server_cfg *cfg = (rpaf_server_cfg *)ap_get_module_config(r->server->module_config,
                                                                   &rpaf_module);

    if (!cfg->enable)
        return DECLINED;

    /* this overcomes an issue when mod_rewrite causes this to get called again
       and the environment value is lost for HTTPS. This is the only thing that
       is lost and we do not need to process any further after restoring the
       value. Note that this check uses the *per-request* note - otherwise we
       would shortcut here for every subsequent request */
    const char *rpaf_https = apr_table_get(r->notes, "rpaf_https");
    if (rpaf_https) {
        apr_table_set(r->subprocess_env, "HTTPS", rpaf_https);
        return DECLINED;
    }

    /* check if the remote_addr is in the allowed proxy IP list */
    if (is_in_array(r->DEF_ADDR, cfg->proxy_ips) != 1) {
        if (cfg->forbid_if_not_proxy)
            return HTTP_FORBIDDEN;
        return DECLINED;
    }

    /* TODO: We should not just assume that we should fallback to
       X-Forwarded-For as this could pose a security risk, keeping
       this for now to keep our behaviour consistant */
    header_ip = cfg->headername;
    if (header_ip)
      fwdvalue = (char *)apr_table_get(r->headers_in, header_ip);
    if (!header_ip || !fwdvalue)
    {
      header_ip = "X-Forwarded-For";
      fwdvalue  = (char *)apr_table_get(r->headers_in, header_ip);
    }

    /* if there was no forwarded for header then we dont do anything */
    if (!fwdvalue)
        return DECLINED;

    /* split up the list of forwarded IPs */
    apr_array_header_t *arr = apr_array_make(r->pool, 4, sizeof(char *));
    while ((val = strsep(&fwdvalue, ",")) != NULL) {
        /* strip leading and trailing whitespace */
        while(isspace(*val))
            ++val;
        for (i = strlen(val) - 1; i > 0 && isspace(val[i]); i--)
            val[i] = '\0';
        if (rpaf_looks_like_ip(val))
            *(char **)apr_array_push(arr) = apr_pstrdup(r->pool, val);
    }

    /* if there were no IPs, then there is nothing to do */
    if (apr_is_empty_array(arr))
        return DECLINED;

    /* get the last IP and check if it is in our list of proxies */
    if ((last_val = last_not_in_array(r, arr, cfg->proxy_ips)) == NULL)
        return DECLINED;

    /* if we are cleaning up the headers then we need to correct the forwarded IP list */
    if (cfg->clean_headers)
    {
        /* pop the proxy's IP from the list */
        apr_array_pop(arr);
        if (apr_is_empty_array(arr))
            apr_table_unset(r->headers_in, header_ip);
        else {
            char *ip_list = apr_array_pstrcat(r->pool, arr, ',');
            apr_table_set(r->headers_in, header_ip, ip_list);
        }
    }

    rpaf_cleanup_rec *rcr = (rpaf_cleanup_rec *)apr_pcalloc(r->pool, sizeof(rpaf_cleanup_rec));
    rcr->old_ip = apr_pstrdup(r->DEF_POOL, r->DEF_IP);
    rcr->r = r;
    apr_pool_cleanup_register(r->pool, (void *)rcr, rpaf_cleanup, apr_pool_cleanup_null);
    r->DEF_IP = apr_pstrdup(r->DEF_POOL, last_val);
    memcpy(&rcr->old_addr, r->DEF_ADDR, sizeof(apr_sockaddr_t));

    tmppool = r->DEF_ADDR->pool;
    tmpport = r->DEF_ADDR->port;
    apr_sockaddr_t *tmpsa;
    int ret = apr_sockaddr_info_get(&tmpsa, r->DEF_IP, APR_UNSPEC, tmpport, 0, tmppool);
    if (ret == APR_SUCCESS)
        memcpy(r->DEF_ADDR, tmpsa, sizeof(apr_sockaddr_t));
    if (cfg->sethostname) {
        const char *hostvalue;
        header_host = "X-Forwarded-Host";
        hostvalue   = apr_table_get(r->headers_in, header_host);
        if (!hostvalue) {
            header_host = "X-Host";
            hostvalue   = apr_table_get(r->headers_in, header_host);
        }

        if (!hostvalue) {
            header_host = NULL;
        } else {
            apr_array_header_t *arr = apr_array_make(r->pool, 0, sizeof(char*));
            while (*hostvalue && (val = ap_get_token(r->pool, &hostvalue, 1))) {
                *(char **)apr_array_push(arr) = apr_pstrdup(r->pool, val);
                if (*hostvalue != '\0')
                  ++hostvalue;
            }

            apr_table_set(r->headers_in, "Host", apr_pstrdup(r->pool, ((char **)arr->elts)[((arr->nelts)-1)]));
            r->hostname = apr_pstrdup(r->pool, ((char **)arr->elts)[((arr->nelts)-1)]);
            ap_update_vhost_from_headers(r);
        }
    }

    if (cfg->sethttps) {
        const char *httpsvalue, *scheme;
        header_https = "X-Forwarded-HTTPS";
        httpsvalue   = apr_table_get(r->headers_in, header_https);
        if (!httpsvalue) {
            header_https = "X-HTTPS";
            httpsvalue   = apr_table_get(r->headers_in, header_https);
        }

        if (!httpsvalue) {
            header_https = "X-Forwarded-Proto";
            httpsvalue   = apr_table_get(r->headers_in, header_https);
            if (!httpsvalue) {
              header_https = "X-Forwarded-Protocol";
              httpsvalue   = apr_table_get(r->headers_in, header_https);
            }
            if (httpsvalue) {
                if (strcmp(httpsvalue, cfg->https_scheme) == 0) {
                    /* set a per-request note to get around an issue with mod_rewrite
                       (explained in an earlier comment), and a per-connection note
                       to allow our version of ssl_is_https() to work.
                     */
                    apr_table_set(r->notes, "rpaf_https", "on");
                    apr_table_set(r->connection->notes, "rpaf_https", "on");
                    apr_table_set(r->subprocess_env   , "HTTPS"     , "on");
                    scheme = cfg->https_scheme;
                } else {
                    scheme = cfg->orig_scheme;
                }
            } else {
                header_https = NULL;
                scheme       = cfg->orig_scheme;
            }
        } else {
            if(strcmp(httpsvalue, "on") == 0 || strcmp(httpsvalue, "On") == 0) {
              apr_table_set(r->notes, "rpaf_https", "on");
              apr_table_set(r->connection->notes, "rpaf_https", "on");
              apr_table_set(r->subprocess_env   , "HTTPS"     , "on");
              scheme = cfg->https_scheme;
            } else {
              scheme = cfg->orig_scheme;
            }
        }

        #if AP_SERVER_MINORVERSION_NUMBER > 1 && AP_SERVER_PATCHLEVEL_NUMBER > 2
        r->server->server_scheme = scheme;
        #endif
    }

     if (cfg->setport) {
        const char *portvalue;
        header_port = "X-Forwarded-Port";
        portvalue   = apr_table_get(r->headers_in, header_port);
        if (!portvalue) {
            header_port = "X-Port";
            portvalue   = apr_table_get(r->headers_in, header_port);
        }

        if (!portvalue) {
            header_port     = NULL;
            r->server->port = cfg->orig_port;
        } else {
            r->server->port    = atoi(portvalue);
            r->parsed_uri.port = r->server->port;
        }
    }

    if (cfg->clean_headers) {
        if (header_host ) apr_table_unset(r->headers_in, header_host );
        if (header_https) apr_table_unset(r->headers_in, header_https);
        if (header_port ) apr_table_unset(r->headers_in, header_port );
    }

    return DECLINED;
}
コード例 #29
0
ファイル: copy-cmd.c プロジェクト: aosm/subversion
/* This implements the `svn_opt_subcommand_t' interface. */
svn_error_t *
svn_cl__copy(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, *sources;
  const char *src_path, *dst_path;
  svn_boolean_t srcs_are_urls, dst_is_url;
  svn_commit_info_t *commit_info = NULL;
  svn_error_t *err;
  int i;

  SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                      opt_state->targets,
                                                      ctx, pool));
  if (targets->nelts < 2)
    return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);

  /* Get the src list and associated peg revs */
  sources = apr_array_make(pool, targets->nelts - 1,
                           sizeof(svn_client_copy_source_t *));
  for (i = 0; i < (targets->nelts - 1); i++)
    {
      const char *target = APR_ARRAY_IDX(targets, i, const char *);
      svn_client_copy_source_t *source = apr_palloc(pool, sizeof(*source));
      const char *src;
      svn_opt_revision_t *peg_revision = apr_palloc(pool,
                                                    sizeof(*peg_revision));

      SVN_ERR(svn_opt_parse_path(peg_revision, &src, target, pool));
      source->path = src;
      source->revision = &(opt_state->start_revision);
      source->peg_revision = peg_revision;

      APR_ARRAY_PUSH(sources, svn_client_copy_source_t *) = source;
    }

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

  /* Figure out which type of trace editor to use.
     If the src_paths are not homogeneous, setup_copy will return an error. */
  src_path = APR_ARRAY_IDX(targets, 0, const char *);
  srcs_are_urls = svn_path_is_url(src_path);
  dst_path = APR_ARRAY_IDX(targets, targets->nelts - 1, const char *);
  apr_array_pop(targets);
  dst_is_url = svn_path_is_url(dst_path);

  if ((! srcs_are_urls) && (! dst_is_url))
    {
      /* WC->WC */
      if (! opt_state->quiet)
        svn_cl__get_notifier(&ctx->notify_func2, &ctx->notify_baton2,
                             FALSE, FALSE, FALSE, pool);
    }
  else if ((! srcs_are_urls) && (dst_is_url))
    {
      /* WC->URL : Use notification. */
      /* ### todo:

         We'd like to use the notifier, but we MAY have a couple of
         problems with that, the same problems that used to apply to
         the old trace_editor:

         1) We don't know where the commit editor for this case will
            be anchored with respect to the repository, so we can't
            use the DST_URL.

         2) While we do know where the commit editor will be driven
            from with respect to our working copy, we don't know what
            basenames will be chosen for our committed things.  So a
            copy of dir1/foo.c to http://.../dir2/foo-copy-c would
            display like: "Adding   dir1/foo-copy.c", which could be a
            bogus path.
      */
    }
  else if ((srcs_are_urls) && (! dst_is_url))
    {
      /* URL->WC : Use checkout-style notification. */
      if (! opt_state->quiet)
        svn_cl__get_notifier(&ctx->notify_func2, &ctx->notify_baton2, TRUE,
                             FALSE, FALSE, pool);
    }
  /* else URL -> URL, meaning that no notification is needed. */

  if (! dst_is_url)
    {
      ctx->log_msg_func3 = NULL;
      if (opt_state->message || opt_state->filedata || opt_state->revprop_table)
        return svn_error_create
          (SVN_ERR_CL_UNNECESSARY_LOG_MESSAGE, NULL,
           _("Local, non-commit operations do not take a log message "
             "or revision properties"));
    }

  if (ctx->log_msg_func3)
    SVN_ERR(svn_cl__make_log_msg_baton(&(ctx->log_msg_baton3), opt_state,
                                       NULL, ctx->config, pool));

  err = svn_client_copy5(&commit_info, sources, dst_path, TRUE,
                         opt_state->parents, opt_state->ignore_externals,
                         opt_state->revprop_table, ctx, pool);

  if (ctx->log_msg_func3)
    SVN_ERR(svn_cl__cleanup_log_msg(ctx->log_msg_baton3, err, pool));
  else if (err)
    return err;

  if (commit_info && ! opt_state->quiet)
    SVN_ERR(svn_cl__print_commit_info(commit_info, pool));

  return SVN_NO_ERROR;
}
コード例 #30
0
/* This implements the `svn_opt_subcommand_t' interface. */
svn_error_t *
svn_cl__copy(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, *sources;
  const char *src_path, *dst_path;
  svn_boolean_t srcs_are_urls, dst_is_url;
  svn_error_t *err;
  int i;

  SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                      opt_state->targets,
                                                      ctx, FALSE, pool));
  if (targets->nelts < 2)
    return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);

  /* Get the src list and associated peg revs */
  sources = apr_array_make(pool, targets->nelts - 1,
                           sizeof(svn_client_copy_source_t *));
  for (i = 0; i < (targets->nelts - 1); i++)
    {
      const char *target = APR_ARRAY_IDX(targets, i, const char *);
      svn_client_copy_source_t *source = apr_palloc(pool, sizeof(*source));
      const char *src;
      svn_opt_revision_t *peg_revision = apr_palloc(pool,
                                                    sizeof(*peg_revision));

      SVN_ERR(svn_opt_parse_path(peg_revision, &src, target, pool));
      source->path = src;
      source->revision = &(opt_state->start_revision);
      source->peg_revision = peg_revision;

      APR_ARRAY_PUSH(sources, svn_client_copy_source_t *) = source;
    }

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

  /* Figure out which type of notification to use.
     (There is no need to check that the src paths are homogeneous;
     svn_client_copy6() through its subroutine try_copy() will return an
     error if they are not.) */
  src_path = APR_ARRAY_IDX(targets, 0, const char *);
  srcs_are_urls = svn_path_is_url(src_path);
  dst_path = APR_ARRAY_IDX(targets, targets->nelts - 1, const char *);
  apr_array_pop(targets);
  dst_is_url = svn_path_is_url(dst_path);

  if ((! srcs_are_urls) && (! dst_is_url))
    {
      /* WC->WC */
    }
  else if ((! srcs_are_urls) && (dst_is_url))
    {
      /* WC->URL : Use notification. */
      if (! opt_state->quiet)
        SVN_ERR(svn_cl__notifier_mark_wc_to_repos_copy(ctx->notify_baton2));
    }
  else if ((srcs_are_urls) && (! dst_is_url))
    {
     /* URL->WC : Use checkout-style notification. */
     if (! opt_state->quiet)
       SVN_ERR(svn_cl__notifier_mark_checkout(ctx->notify_baton2));
    }
  else
    {
      /* URL -> URL, meaning that no notification is needed. */
      ctx->notify_func2 = NULL;
    }

  if (! dst_is_url)
    {
      ctx->log_msg_func3 = NULL;
      if (opt_state->message || opt_state->filedata || opt_state->revprop_table)
        return svn_error_create
          (SVN_ERR_CL_UNNECESSARY_LOG_MESSAGE, NULL,
           _("Local, non-commit operations do not take a log message "
             "or revision properties"));
    }

  if (ctx->log_msg_func3)
    SVN_ERR(svn_cl__make_log_msg_baton(&(ctx->log_msg_baton3), opt_state,
                                       NULL, ctx->config, pool));

  err = svn_client_copy6(sources, dst_path, TRUE,
                         opt_state->parents, opt_state->ignore_externals,
                         opt_state->revprop_table,
                         svn_cl__print_commit_info, NULL,
                         ctx, pool);

  if (ctx->log_msg_func3)
    SVN_ERR(svn_cl__cleanup_log_msg(ctx->log_msg_baton3, err, pool));
  else if (err)
    return svn_error_trace(err);

  return SVN_NO_ERROR;
}