blob: 9df39d8b6e6907758ea4bd6de92d0bcd325a339f [file] [log] [blame]
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Originally developed by Aaron Bannert and Justin Erenkrantz, eBuilt.
*/
#include <apr_general.h> /* For apr_initialize */
#include <apr_strings.h>
#include <apr_file_io.h>
#include <apr_pools.h>
#if APR_HAVE_STDLIB_H
#include <stdlib.h> /* rand/strtol */
#endif
#if APR_HAVE_UNISTD_H
#include <unistd.h> /* For pause */
#endif
#include "config.h"
#include "flood_profile.h"
#include "flood_farm.h"
#include "flood_farmer.h"
#include "flood_config.h"
#if FLOOD_HAS_OPENSSL
#include "flood_net_ssl.h" /* For ssl_init_socket */
#endif /* FLOOD_HAS_OPENSSL */
/* Win32 doesn't have stdout or stderr. */
apr_file_t *local_stdin, *local_stdout, *local_stderr;
/* Should be the new apr_sms_t struct? Not ready yet. */
apr_pool_t *local_pool;
static apr_status_t set_seed(config_t *config)
{
apr_status_t stat;
struct apr_xml_elem *root_elem, *seed_elem;
char *xml_seed = XML_SEED;
unsigned int seed;
/* get the root config node */
if ((stat = retrieve_root_xml_elem(&root_elem, config)) != APR_SUCCESS) {
return stat;
}
/* get the seed node from config */
if ((stat = retrieve_xml_elem_child(&seed_elem, root_elem, xml_seed)) != APR_SUCCESS) {
seed = 1; /* default if not found */
}
else {
if (seed_elem->first_cdata.first && seed_elem->first_cdata.first->text) {
char *endptr;
seed = (unsigned int) strtoll(seed_elem->first_cdata.first->text,
&endptr, 10);
if (*endptr != '\0') {
apr_file_printf(local_stderr,
"XML Node %s has invalid value '%s'.\n",
XML_SEED, seed_elem->first_cdata.first->text);
return APR_EGENERAL;
}
}
else {
seed = 1;
}
}
/* actually set the seed */
#if FLOOD_USE_RAND
srand(seed);
#elif FLOOD_USE_RAND48
srand48(seed);
#elif FLOOD_USE_RANDOM
srandom(seed);
#endif
return APR_SUCCESS;
}
/* check if config file version matches flood config file version */
static apr_status_t check_versions(config_t *config)
{
apr_status_t stat;
char *endptr = NULL;
apr_int64_t flood_version = 0;
apr_int64_t config_version = 0;
struct apr_xml_elem *root_elem;
/* we assume that CONFIG_VERSION is sane */
flood_version = apr_strtoi64(CONFIG_VERSION, NULL, 0);
/* get the root element */
if ((stat = retrieve_root_xml_elem(&root_elem, config)) != APR_SUCCESS) {
return stat;
}
if (root_elem->attr) {
apr_xml_attr *attr = root_elem->attr;
while (attr) {
if (!strncasecmp(attr->name, XML_FLOOD_CONFIG_VERSION,
FLOOD_STRLEN_MAX)) {
config_version = apr_strtoi64(attr->value, &endptr, 0);
if (*endptr != '\0') {
apr_file_printf(local_stderr,
"invalid config version '%s'.\n",
attr->value);
return APR_EGENERAL;
}
}
attr = attr->next;
}
}
if (config_version != flood_version) {
apr_file_printf(local_stderr,
"your config file version '%lli' doesn't match flood config file version '%lli'.\n",
config_version, flood_version);
}
return APR_SUCCESS;
}
int main(int argc, char** argv)
{
apr_status_t stat;
config_t *config;
/* FIXME: Where is Roy's change to return the global pool... */
apr_initialize();
atexit(apr_terminate);
apr_pool_create(&local_pool, NULL);
#if FLOOD_HAS_OPENSSL
/* FIXME: HHAAAAAAAAAAAAAAACCCCCCCCCCCKKKKKKKKKKK! */
/* Should be a run-time option with SSL, but Justin hates singleton. */
ssl_init_socket(local_pool);
#endif /* FLOOD_HAS_OPENSSL */
apr_file_open_stdout(&local_stdout, local_pool);
apr_file_open_stderr(&local_stderr, local_pool);
if (argc == 1) {
apr_file_open_stdin(&local_stdin, local_pool);
}
else if ((stat = apr_file_open(&local_stdin, argv[1], APR_READ,
APR_OS_DEFAULT, local_pool)) != APR_SUCCESS)
{
char buf[256];
apr_strerror(stat, (char*) &buf, sizeof(buf));
apr_file_printf(local_stderr,
"Error opening configuration file: %s.\n",
(char*)&buf);
exit(-1);
}
/* parse the config */
config = parse_config(local_stdin, local_pool);
if ((stat = set_seed(config)) != APR_SUCCESS) {
char buf[256];
apr_strerror(stat, (char*) &buf, 256);
apr_file_printf(local_stderr, "Error running test profile: %s.\n",
(char*)&buf);
exit(-1);
}
if ((stat = check_versions(config)) != APR_SUCCESS) {
exit(-1);
}
if ((stat = run_farm(config, "Bingo", local_pool)) != APR_SUCCESS) {
char buf[256];
apr_strerror(stat, (char*) &buf, 256);
apr_file_printf(local_stderr, "Error running test profile: %s.\n",
(char*)&buf);
exit(-1);
}
/* report results -- for now just print results to stdout */
return EXIT_SUCCESS;
}