in flood_farmer.c [44:183]
apr_status_t run_farmer(config_t *config, const char *farmer_name, apr_pool_t *pool)
{
apr_status_t stat;
int count, i, j, useprofile_count;
char *xml_farmer, **useprofile_names;
struct apr_xml_elem *e, *root_elem, *farmer_elem, *count_elem, *time_elem;
apr_pool_t *farmer_pool;
apr_time_t stop_time;
#ifdef FARMER_DEBUG
apr_file_printf(local_stderr, "Running farmer '%s'.\n",
farmer_name);
#endif /* FARMER_DEBUG */
xml_farmer = apr_pstrdup(pool, XML_FARMER);
/* get the root config node */
if ((stat = retrieve_root_xml_elem(&root_elem, config)) != APR_SUCCESS) {
return stat;
}
/* get farmer node from config */
if ((stat = retrieve_xml_elem_with_childmatch(
&farmer_elem, root_elem,
xml_farmer, XML_FARMER_NAME, farmer_name)) != APR_SUCCESS)
return stat;
/* get count */
if ((stat = retrieve_xml_elem_child(
&count_elem, farmer_elem, XML_FARMER_COUNT)) != APR_SUCCESS) {
/* if it's missing, default to 1 */
count = 1;
} else {
if (count_elem->first_cdata.first &&
count_elem->first_cdata.first->text) {
count = strtol(count_elem->first_cdata.first->text, NULL, 10);
if (count == LONG_MAX || count == LONG_MIN)
/* error, over/under-flow */
return errno;
} else {
apr_file_printf(local_stderr,
"Farmer '%s' has element <%s> with no value, assuming 1.\n",
farmer_name, XML_FARMER_COUNT);
count = 1;
}
}
/* get timer (optional) */
stop_time = -1;
stat = retrieve_xml_elem_child(&time_elem, farmer_elem, XML_FARMER_TIME);
if (stat == APR_SUCCESS && time_elem->first_cdata.first &&
time_elem->first_cdata.first->text) {
char *endptr;
stop_time = strtoll(time_elem->first_cdata.first->text,
&endptr, 10);
if (*endptr != '\0' || stop_time < 0)
{
apr_file_printf(local_stderr,
"Attribute %s has invalid value %s.\n",
XML_FARMER_TIME,
time_elem->first_cdata.first->text);
return APR_EGENERAL;
}
stop_time *= APR_USEC_PER_SEC;
}
/* count the number of "useprofile" children */
useprofile_count = count_xml_elem_child(farmer_elem, XML_FARMER_USEPROFILE);
if (useprofile_count <= 0) {
apr_file_printf(local_stderr,
"Farmer '%s' has no <%s> elements to run!\n",
farmer_name, XML_FARMER_USEPROFILE);
return APR_EGENERAL;
}
/* create each of the children and put their names in an array */
useprofile_names = apr_palloc(pool, sizeof(char*) * (useprofile_count + 1));
/* set the sentinel (no need for pcalloc()) */
useprofile_names[useprofile_count] = NULL;
i = 0;
for (e = farmer_elem->first_child; e; e = e->next) {
if (strncasecmp(e->name, XML_FARMER_USEPROFILE,
FLOOD_STRLEN_MAX) == 0) {
useprofile_names[i++] = apr_pstrdup(pool,
e->first_cdata.first->text);
}
}
/* now run each of the profiles */
if (stop_time == -1)
{
for (i = 0; i < count; i++) {
if ((stat = apr_pool_create(&farmer_pool, pool)) != APR_SUCCESS) {
return stat;
}
for (j = 0; j < useprofile_count; j++) {
if ((stat = run_profile(farmer_pool, config,
useprofile_names[j])) != APR_SUCCESS) {
return stat;
}
apr_pool_clear(farmer_pool);
}
apr_pool_destroy(farmer_pool);
}
}
else
{
apr_time_t time;
time = apr_time_now();
stop_time += time;
while (1)
{
time = apr_time_now();
if (stop_time <= time || time >= stop_time)
break;
if ((stat = apr_pool_create(&farmer_pool, pool)) != APR_SUCCESS) {
return stat;
}
for (j = 0; j < useprofile_count; j++) {
if ((stat = run_profile(farmer_pool, config,
useprofile_names[j])) != APR_SUCCESS) {
return stat;
}
apr_pool_clear(farmer_pool);
}
apr_pool_destroy(farmer_pool);
}
}
return APR_SUCCESS;
}