apr_status_t run_farmer()

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;
}