/**
 * @brief Print Error Data
 * @ingroup globus_openssl_error_object 
 * @details
 * Return an allocated string of the OpenSSL error from the instance data
 * 
 * @param error
 *        The error object to retrieve the data from.
 * @return
 *        String containing the OpenSSL error if it exists, NULL
 *        otherwise.
 */
static
char *
globus_l_error_openssl_printable(
    globus_object_t *                   error)
{
    globus_openssl_error_handle_t       handle;
    char *                              error_string;
    static char *                       _function_name_ =
        "globus_l_error_openssl_printable";

    GLOBUS_I_GSI_OPENSSL_ERROR_DEBUG_ENTER;

    if(!error)
    {
        error_string = NULL;
        goto done;
    }

    handle = (globus_openssl_error_handle_t)
             globus_object_get_local_instance_data(error);

    if(globus_openssl_error_handle_get_data_flags(handle) & ERR_TXT_STRING)
    {
        error_string = globus_common_create_string(
            _GOESL("OpenSSL Error: %s:%d: in library: %s, function %s: %s %s"),
            globus_openssl_error_handle_get_filename(handle) == NULL ? "(null)" :
            globus_openssl_error_handle_get_filename(handle),
            globus_openssl_error_handle_get_linenumber(handle),
            globus_openssl_error_handle_get_library(handle) == NULL ? "(null)" :
            globus_openssl_error_handle_get_library(handle),
            globus_openssl_error_handle_get_function(handle) == NULL ? "(null)" :
            globus_openssl_error_handle_get_function(handle),
            globus_openssl_error_handle_get_reason(handle) == NULL ? "(null)" :
            globus_openssl_error_handle_get_reason(handle),
            globus_openssl_error_handle_get_data(handle));
    }
    else
    {
        error_string = globus_common_create_string(
            _GOESL("OpenSSL Error: %s:%d: in library: %s, function %s: %s"),
            globus_openssl_error_handle_get_filename(handle) == NULL ? "(null)" :
            globus_openssl_error_handle_get_filename(handle),
            globus_openssl_error_handle_get_linenumber(handle),
            globus_openssl_error_handle_get_library(handle) == NULL ? "(null)" :
            globus_openssl_error_handle_get_library(handle),
            globus_openssl_error_handle_get_function(handle) == NULL ? "(null)" :
            globus_openssl_error_handle_get_function(handle),
            globus_openssl_error_handle_get_reason(handle) == NULL ? "(null)" :
            globus_openssl_error_handle_get_reason(handle));        
    }

 done:

    GLOBUS_I_GSI_OPENSSL_ERROR_DEBUG_EXIT;
    return error_string;
}/* globus_l_error_openssl_printable */
static void
globus_l_gsc_send_perf(
    globus_gridftp_server_control_op_t      op,
    int                                     stripe_ndx,
    int                                     stripe_count,
    globus_off_t                            nbytes)
{
    char *                                  msg;
    struct timeval                          now;
    GlobusGridFTPServerName(globus_l_gsc_send_perf);
                                                                                
    gettimeofday(&now, NULL);
    msg = globus_common_create_string(
        "112-Perf Marker\r\n"
        " Timestamp:  %ld.%01ld\r\n"
        " Stripe Index: %d\r\n"
        " Stripe Bytes Transferred: %"GLOBUS_OFF_T_FORMAT"\r\n"
        " Total Stripe Count: %d\r\n"
        "112 End.\r\n",
            now.tv_sec, now.tv_usec / 100000,
            stripe_ndx,
            nbytes,
            stripe_count);
    globus_i_gsc_intermediate_reply(op, msg);
    globus_free(msg);
}
globus_result_t
globus_gridftp_server_control_attr_add_mode(
    globus_gridftp_server_control_attr_t    in_attr,
    char                                    mode)
{
    char                                    ch;
    char *                                  tmp_str;
    globus_i_gsc_attr_t *                   attr;
    globus_result_t                         res;
    GlobusGridFTPServerName(globus_gridftp_server_control_attr_add_mode);

    GlobusGridFTPServerDebugEnter();
    if(in_attr == NULL)
    {
        res = GlobusGridFTPServerErrorParameter("in_attr");
        goto err;
    }
    attr = in_attr;

    ch = toupper(mode);
    tmp_str = globus_common_create_string("%s%c", attr->modes, ch);
    globus_free(attr->modes);
    attr->modes = tmp_str;

    GlobusGridFTPServerDebugExit();
    return GLOBUS_SUCCESS;

  err:

    GlobusGridFTPServerDebugExitWithError();

    return res;
}
static
globus_bool_t
globus_l_next_file_exists(
    globus_l_job_manager_logfile_state_t *      state)
{
    struct tm                           next_day;
    char *                              next_log;
    globus_bool_t                       file_exists = GLOBUS_FALSE;

    next_day = state->start_timestamp;
    next_day.tm_mday++;
    globus_l_job_manager_normalize_date(&next_day);
    next_day.tm_sec = 0;
    next_day.tm_min = 0;
    next_day.tm_hour = 0;

    next_log = globus_common_create_string(
                "%s/%4d%02d%02d",
                state->log_dir,
                next_day.tm_year+1900,
                next_day.tm_mon+1,
                next_day.tm_mday);
    if (access(next_log, R_OK) == 0)
    {
        file_exists = GLOBUS_TRUE;
    }
    free(next_log);

    return file_exists;
}
static void
globus_l_gsc_send_restart(
    globus_gridftp_server_control_op_t  op,
    globus_range_list_t                 range_list)
{
    int                                 ctr;
    char *                              tmp_msg;
    char *                              msg;
    int                                 size;
    globus_off_t                        offset;
    globus_off_t                        length;
    globus_range_list_t                 new_range_list;

    globus_range_list_merge(
        &new_range_list, op->perf_range_list, range_list);
    globus_range_list_destroy(op->perf_range_list);
    op->perf_range_list = new_range_list;

    size = globus_range_list_size(range_list);
    if(size < 1)
    {
        /* sending 0-0 is useless, and it causes a problem with our client
            when markers are sent before the retr begins
        msg = globus_common_create_string("111 Range Marker 0-0\r\n"); */
    }
    else
    {    
        msg = globus_common_create_string("111 Range Marker");
        for(ctr = 0; ctr < size; ctr++)
        {
            globus_range_list_at(range_list, ctr, &offset, &length);
    
            tmp_msg = globus_common_create_string("%s%c%"
                GLOBUS_OFF_T_FORMAT"-%"GLOBUS_OFF_T_FORMAT,
                 msg, ctr ? ',' : ' ', offset, offset + length);
            globus_free(msg);
            msg = tmp_msg;
        }
        tmp_msg = globus_common_create_string("%s%s", msg, "\r\n");
        globus_free(msg);
        msg = tmp_msg;
        
        globus_i_gsc_intermediate_reply(op, msg);
        globus_free(msg);
    }    
}
static 
globus_result_t
globus_l_net_manager_context_load_entry(
    const char *                            name,
    globus_i_net_manager_context_entry_t ** entry)
{
    globus_extension_handle_t               ext_handle;
    globus_net_manager_t *                  loaded_manager;
    char *                                  dll_name = NULL;
    globus_i_net_manager_context_entry_t *  ent;
    int                                     rc;
    globus_result_t                         result = GLOBUS_SUCCESS;
    GlobusNetManagerName(globus_l_net_manager_context_load_entry);

    /* is module already in registry? */
    loaded_manager = (globus_net_manager_t *) globus_extension_lookup(
        &ext_handle, GLOBUS_NET_MANAGER_REGISTRY, (void *) name);
    if(loaded_manager == NULL)
    {
        /* load and activate the dll */
        dll_name = globus_common_create_string(
            "globus_net_manager_%s", name);

        rc = globus_extension_activate(dll_name);        
        if(rc != GLOBUS_SUCCESS)
        {
            result = GlobusNetManagerErrorManager(
                rc, name, "attempting to activate module.");
            goto error_activate;
        }
    
        /* now module should be in registry */
        loaded_manager = (globus_net_manager_t *) globus_extension_lookup(
            &ext_handle, GLOBUS_NET_MANAGER_REGISTRY, (void *) name);
        if(loaded_manager == NULL)
        {
            result = GlobusNetManagerErrorManager(
                rc, name, "attempting to load activated module.");
            goto error_activate;
        }
    }
    ent = globus_calloc(1, sizeof(globus_i_net_manager_context_entry_t));
    ent->manager = loaded_manager;
    ent->ext_handle = ext_handle;
    ent->name = strdup(name);
    ent->dll_name = dll_name;
    
    *entry = ent;
    return GLOBUS_SUCCESS;
    
error_activate:
    globus_free(dll_name);
    *entry = NULL;
    return result;
}
/*
 * PURPOSE:
 *     Verify that
 *     globus_gram_protocol_unpack_job_request_reply_with_extensions()
 *     catches protocol mismatch errors.
 * TEST STEPS:
 *   - Manually construct status update message with version equal to
 *     GLOBUS_GRAM_PROTOCOL_VERSION + 1
 *   - Call globus_gram_protocol_unpack_job_request_reply_with_extensions() and
 *     expect a VERSION_MISMATCH error
 */
int test_version_mismatch(void)
{
    char *                              message;
    globus_size_t                       message_size;
    int                                 rc;
    globus_hashtable_t                  hashtable;
    int                                 status;
    char *                              job_contact;

    message = globus_common_create_string(
        "protocol-version: %d\r\n"
        "status: %d\r\n"
        "failure-code: %d\r\n"
        "job-failure-code: %d\r\n",
        GLOBUS_GRAM_PROTOCOL_VERSION + 1,
        GLOBUS_GRAM_PROTOCOL_JOB_STATE_ACTIVE,
        0,
        0);
    test_assert(message != NULL,
            ("Error creating message (out of memory?)\n"));
    message_size = strlen(message) + 1;

    rc = globus_gram_protocol_unpack_job_request_reply_with_extensions(
            (globus_byte_t *) message,
            message_size,
            &status,
            &job_contact,
            &hashtable);
    test_assert(rc == GLOBUS_GRAM_PROTOCOL_ERROR_VERSION_MISMATCH,
            ("Expected GLOBUS_GRAM_PROTOCOL_ERROR_VERSION_MISMATCH, "
            "got %d (%s)\n",
            rc, 
            globus_gram_protocol_error_string(rc)));

    if (hashtable != NULL)
    {
        globus_gram_protocol_hash_destroy(&hashtable);
    }
    free(message);

    return 0;
}
/*
 * PURPOSE:
 *     Verify that
 *     globus_gram_protocol_unpack_job_request_reply_with_extensions()
 *     deals with messages missing attributes from GRAM2 protocol.
 * TEST STEPS:
 *   - Manually construct status update messages with each piece of the GRAM2
 *     protocol missing
 *   - Call globus_gram_protocol_unpack_job_request_reply_with_extensions() and
 *     expect an UNPACK_FAILED error
 */
int test_missing_attribute()
{
    char *                              message;
    globus_size_t                       message_size;
    int                                 rc;
    globus_hashtable_t                  hashtable;
    int                                 i;
    char *                              lines[] =
    {
        "protocol-version: 2\r\n",
        "status: 2\r\n"
    };
    int                                 status;
    char *                              job_contact;

    for (i = 0; i < ARRAY_LEN(lines); i++)
    {
        message = globus_common_create_string(
                "%s",
                lines[i % ARRAY_LEN(lines)]);

        test_assert(message != NULL,
                ("Error creating message (out of memory?)\n"));
        message_size = strlen(message) + 1;

        rc = globus_gram_protocol_unpack_job_request_reply_with_extensions(
                (globus_byte_t *) message,
                message_size,
                &status,
                &job_contact,
                &hashtable);
        test_assert(rc == GLOBUS_GRAM_PROTOCOL_ERROR_HTTP_UNPACK_FAILED,
                ("Expected GLOBUS_GRAM_PROTOCOL_ERROR_HTTP_UNPACK_FAILED, "
                "got %d (%s)\n",
                rc, 
                globus_gram_protocol_error_string(rc)));
        free(message);
    }

    return 0;
}
int main()
{
    globus_object_t * err;
    char * s;
    char * t;
    static char * myname = "main";

    printf("1..1\n");

    globus_module_activate(GLOBUS_COMMON_MODULE);

#line myline
    err = globus_error_construct_string(GLOBUS_COMMON_MODULE, GLOBUS_ERROR_NO_INFO, "[%s]: Error doing something hard at %s:%d\n", GLOBUS_COMMON_MODULE->module_name, myname, __LINE__);
    s = globus_object_printable_to_string(err);
#line myline
    t = globus_common_create_string( "[%s]: Error doing something hard at %s:%d\n", GLOBUS_COMMON_MODULE->module_name, myname, __LINE__);
    ok(strcmp(s, t) == 0, "globus_common_error_string");
    free(s);
    free(t);

    return TEST_EXIT_CODE;
}
extern
int
globus_gram_job_manager_validation_update(
    globus_gram_job_manager_t *         manager)
{
    time_t                              validation_timestamp = time(NULL);
    int                                 rc = GLOBUS_SUCCESS;
    globus_result_t                     result;
    struct stat                         st;
    globus_bool_t                       do_update = GLOBUS_FALSE;

    if (validation_timestamp <= manager->validation_record_timestamp)
    {
        goto skip_update_check;
    }

    if (validation_filename == NULL)
    {
        result = globus_eval_path(
                "${datadir}/globus/globus_gram_job_manager/globus-gram-job-manager.rvf",
                &validation_filename);
        if (result != GLOBUS_SUCCESS || validation_filename == NULL)
        {
            rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;
            goto validation_filename_failed;
        }
    }

    if (site_validation_filename == NULL)
    {
        result = globus_eval_path(
                "${sysconfdir}/globus/gram/job-manager.rvf",
                &site_validation_filename);
        if (result != GLOBUS_SUCCESS || site_validation_filename == NULL)
        {
            rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;

            goto site_validation_filename_failed;
        }
    }
    if (lrm_validation_filename_pattern == NULL)
    {
        lrm_validation_filename_pattern = globus_common_create_string(
                "${datadir}/globus/globus_gram_job_manager/%s.rvf",
                manager->config->jobmanager_type);
        if(lrm_validation_filename_pattern == NULL)
        {
            rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;
            goto lrm_validation_filename_pattern_failed;
        }
    }

    if (lrm_validation_filename == NULL)
    {
        result = globus_eval_path(
                lrm_validation_filename_pattern,
                &lrm_validation_filename);
        if (result != GLOBUS_SUCCESS || lrm_validation_filename == NULL)
        {
            rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;
            goto lrm_validation_filename_failed;
        }
    }

    if (site_lrm_validation_filename_pattern == NULL)
    {
        site_lrm_validation_filename_pattern = globus_common_create_string(
                "${sysconfdir}/globus/gram/%s.rvf",
                manager->config->jobmanager_type);
        if(site_lrm_validation_filename_pattern == NULL)
        {
            rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;
            goto site_lrm_validation_filename_pattern_failed;
        }
    }

    if (site_lrm_validation_filename == NULL)
    {
        result = globus_eval_path(site_lrm_validation_filename_pattern,
            &site_lrm_validation_filename);
        if (result != GLOBUS_SUCCESS || site_lrm_validation_filename == NULL)
        {
            rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;
            goto site_lrm_validation_filename_failed;
        }
    }

    rc = stat(validation_filename, &st);
    if ((rc == GLOBUS_SUCCESS
            && ((!manager->validation_file_exists[0]) ||
                st.st_mtime > manager->validation_record_timestamp)) ||
        (rc != GLOBUS_SUCCESS
            && errno == ENOENT && manager->validation_file_exists[0]))
    {
        do_update = GLOBUS_TRUE;
    }

    if (!do_update)
    {
        rc = stat(lrm_validation_filename, &st);
        if ((rc == GLOBUS_SUCCESS
                && ((!manager->validation_file_exists[1]) ||
                    st.st_mtime > manager->validation_record_timestamp)) ||
            (rc != GLOBUS_SUCCESS
                && errno == ENOENT && manager->validation_file_exists[1]))
        {
            do_update = GLOBUS_TRUE;
        }
    }

    if (!do_update)
    {
        rc = stat(site_validation_filename, &st);
        if ((rc == GLOBUS_SUCCESS
                && ((!manager->validation_file_exists[2]) ||
                    st.st_mtime > manager->validation_record_timestamp)) ||
            (rc != GLOBUS_SUCCESS
                && errno == ENOENT && manager->validation_file_exists[2]))
        {
            do_update = GLOBUS_TRUE;
        }
    }

    if (!do_update)
    {
        rc = stat(site_lrm_validation_filename, &st);
        if ((rc == GLOBUS_SUCCESS
                && ((!manager->validation_file_exists[3]) ||
                    st.st_mtime > manager->validation_record_timestamp)) ||
            (rc != GLOBUS_SUCCESS
                && errno == ENOENT && manager->validation_file_exists[3]))
        {
            do_update = GLOBUS_TRUE;
        }
    }

    if (do_update)
    {
        /* Free old validation entries */
        globus_gram_job_manager_validation_destroy(
                manager->validation_records);
        manager->validation_records = NULL;

        rc = globus_gram_job_manager_validation_init(manager);
    }
    else
    {
        rc = GLOBUS_SUCCESS;
    }

site_lrm_validation_filename_failed:
site_lrm_validation_filename_pattern_failed:
lrm_validation_filename_failed:
lrm_validation_filename_pattern_failed:
site_validation_filename_failed:
validation_filename_failed:
skip_update_check:
    return rc;
}
/**
 * Validate RSL attributes
 *
 * Checks that all of the RSL attributes in the request's RSL match
 * a validation record. If an RSL has an enumerated list of values,
 * then the value of the RSL is compared against that list.
 *
 * @param request
 *        The job request containing the RSL to validate.
 * @param when
 *        Which RSL validation time scope we will use to decide
 *        whether to use the default values or not.
 */
static
int
globus_l_gram_job_manager_check_rsl_attributes(
    globus_gram_jobmanager_request_t *  request,
    globus_rsl_t *                      rsl,
    globus_gram_job_manager_validation_when_t
                                        when)
{
    globus_list_t *                     operands;
    globus_list_t *                     node;
    globus_rsl_t *                      relation;
    char *                              attribute;
    char *                              value_str;
    globus_rvf_record_t *               record;
    globus_rsl_value_t *                value;
    int                                 rc = GLOBUS_SUCCESS;
    static const char *                 operation_types[] =
    {
        "??",
        "=",
        "!=",
        ">",
        ">=",
        "<",
        "<=",
        "??",
        "&",
        "|",
        "+"
    };

    operands = globus_rsl_boolean_get_operand_list(rsl);

    /* Check to make sure that every attribute is recognized by this
     * job manager.
     */
    while(!globus_list_empty(operands))
    {
        relation = globus_list_first(operands);
        operands = globus_list_rest(operands);

        if (!globus_rsl_is_relation(relation))
        {
            int operator = globus_rsl_boolean_get_operator(relation);
            if (operator > 10 || operator < 0)
            {
                operator = 0;
            }

            globus_gram_job_manager_request_log(
                    request,
                    GLOBUS_GRAM_JOB_MANAGER_LOG_ERROR,
                    "event=gram.validate_rsl.end "
                    "level=ERROR "
                    "msg=\"Required RSL relation, got boolean\" "
                    "operator=%s "
                    "status=%d "
                    "\n",
                    operation_types[operator],
                    -GLOBUS_GRAM_PROTOCOL_ERROR_BAD_RSL);
            if (request->gt3_failure_message == NULL)
            {
                request->gt3_failure_message = globus_common_create_string(
                        "Required RSL relation, got boolean %s",
                        operation_types[operator]);
            }
        }
        else if (!globus_rsl_is_relation_eq(relation))
        {
            int operator = globus_rsl_relation_get_operator(relation);

            if (operator > 10 || operator < 0)
            {
                operator = 0;
            }

            globus_gram_job_manager_request_log(
                    request,
                    GLOBUS_GRAM_JOB_MANAGER_LOG_ERROR,
                    "event=gram.validate_rsl.end "
                    "level=ERROR "
                    "msg=\"Unsupported RSL operation\" "
                    "attribute=%s "
                    "operator=%s "
                    "status=%d "
                    "\n",
                    globus_rsl_relation_get_attribute(relation),
                    operation_types[operator],
                    -GLOBUS_GRAM_PROTOCOL_ERROR_BAD_RSL);

            if (request->gt3_failure_message == NULL)
            {
                request->gt3_failure_message = globus_common_create_string(
                        "the job manager does not support the RSL operator "
                        "\"%s\" for the %s attribute",
                        operation_types[operator],
                        globus_rsl_relation_get_attribute(relation));
            }
            return GLOBUS_GRAM_PROTOCOL_ERROR_BAD_RSL;
        }
        attribute = globus_rsl_relation_get_attribute(relation);

        node = globus_list_search_pred(
                request->manager->validation_records,
                globus_l_gram_job_manager_attribute_match,
                attribute);

        if(!node)
        {
            globus_gram_job_manager_request_log(
                    request,
                    GLOBUS_GRAM_JOB_MANAGER_LOG_ERROR,
                    "event=gram.validate_rsl.end "
                    "level=ERROR "
                    "msg=\"Unsupported RSL attribute\" "
                    "attribute=%s "
                    "status=%d "
                    "\n",
                    globus_rsl_relation_get_attribute(relation),
                    -GLOBUS_GRAM_PROTOCOL_ERROR_BAD_RSL);

            if (request->gt3_failure_message == NULL)
            {
                request->gt3_failure_message = globus_common_create_string(
                        "the RSL attribute \"%s\" is not supported by the LRM adapter",
                        globus_rsl_relation_get_attribute(relation));
            }
            return GLOBUS_GRAM_PROTOCOL_ERROR_PARAMETER_NOT_SUPPORTED;
        }

        record = globus_list_first(node);

        /* Check valid_when */
        if((record->valid_when & when) == 0)
        {
            const char * whenstr = "unknown operation";

            switch(when)
            {
              case GLOBUS_GRAM_VALIDATE_JOB_SUBMIT:
                whenstr = "submit";
                rc = GLOBUS_GRAM_PROTOCOL_ERROR_INVALID_SUBMIT_ATTRIBUTE;
                break;
              case GLOBUS_GRAM_VALIDATE_JOB_MANAGER_RESTART:
                whenstr = "restart";
                rc = GLOBUS_GRAM_PROTOCOL_ERROR_INVALID_RESTART_ATTRIBUTE;
                break;
              case GLOBUS_GRAM_VALIDATE_STDIO_UPDATE:
                whenstr = "stdio_update";
                rc = GLOBUS_GRAM_PROTOCOL_ERROR_INVALID_STDIO_UPDATE_ATTRIBUTE;
                break;
            }

            globus_gram_job_manager_request_log(
                    request,
                    GLOBUS_GRAM_JOB_MANAGER_LOG_ERROR,
                    "event=gram.validate_rsl.end "
                    "level=ERROR "
                    "msg=\"Invalid RSL attribute for operation\" "
                    "attribute=%s "
                    "operation=%s "
                    "status=%d "
                    "\n",
                    globus_rsl_relation_get_attribute(relation),
                    whenstr,
                    -rc);
            if (request->gt3_failure_message == NULL)
            {
                request->gt3_failure_message = globus_common_create_string(
                        "Invalid RSL attribute \"%s\" for %s",
                        globus_rsl_relation_get_attribute(relation),
                        whenstr);
            }
            return rc;
        }
        /* Check enumerated values if applicable */
        if(record->enumerated_values)
        {
            value = globus_rsl_relation_get_single_value(relation);

            if(!value)
            {
                return
                    globus_l_gram_job_manager_validation_rsl_error(attribute);
            }
            value_str = globus_rsl_value_literal_get_string(value);
            if(!value_str)
            {
                return globus_l_gram_job_manager_validation_rsl_error(
                        attribute);
            }
            if(strstr(record->enumerated_values, value_str) == GLOBUS_NULL)
            {
                rc = globus_l_gram_job_manager_validation_value_error(
                            request,
                            attribute,
                            value_str,
                            record->enumerated_values);

                globus_gram_job_manager_request_log(
                        request,
                        GLOBUS_GRAM_JOB_MANAGER_LOG_ERROR,
                        "event=gram.validate_rsl.end "
                        "level=ERROR "
                        "msg=\"RSL attribute value not in enumeration\" "
                        "attribute=%s "
                        "value=%s "
                        "enumeration=\"%s\" "
                        "status=%d "
                        "\n",
                        record->attribute,
                        value_str,
                        record->enumerated_values,
                        -rc);

                return rc;
            }
        }
    }

    return GLOBUS_SUCCESS;
}
Exemplo n.º 12
0
int
main(
    int                                 argc,
    char **                             argv)
{
    int                                 rc;
    globus_gram_job_manager_config_t    config;
    globus_gram_job_manager_t           manager;
    char *                              sleeptime_str;
    long                                sleeptime = 0;
    globus_bool_t                       debug_mode_service = GLOBUS_FALSE;
    globus_bool_t                       located_active_jm = GLOBUS_FALSE;
    int                                 http_body_fd = -1;
    int                                 context_fd = -1;
    gss_cred_id_t                       cred = GSS_C_NO_CREDENTIAL;
    OM_uint32                           major_status, minor_status;
    pid_t                               forked_starter = 0;
    globus_bool_t                       cgi_invoked = GLOBUS_FALSE;
    int                                 lock_tries_left = 10;

    if ((sleeptime_str = getenv("GLOBUS_JOB_MANAGER_SLEEP")))
    {
        sleeptime = atoi(sleeptime_str);
        sleep(sleeptime);
    }
    if (getenv("GATEWAY_INTERFACE"))
    {
        cgi_invoked = GLOBUS_TRUE;
    }
    /*
     * Stdin and stdout point at socket to client
     * Make sure no buffering.
     * stderr may also, depending on the option in the grid-services
     */
    setbuf(stdout,NULL);
    /* Don't export these to the perl scripts */
    fcntl(STDIN_FILENO, F_SETFD, (int) 1);
    fcntl(STDOUT_FILENO, F_SETFD, (int) 1);
    fcntl(STDERR_FILENO, F_SETFD, (int) 1);

    /*
     * At least have minimal POSIX path for job environment via extra
     * environment values
     */
    if(getenv("PATH") == NULL)
    {
        char * path;
        char default_path[] = "/usr/bin:/bin";
        size_t pathlen;

        pathlen = confstr(_CS_PATH, NULL, (size_t) 0);

        if (pathlen < sizeof(default_path))
        {
            pathlen = sizeof(default_path);
        }
        path = malloc(pathlen);
        path[0] = 0;

        (void) confstr(_CS_PATH, path, pathlen);
        if (path[0] == 0)
        {
            strncpy(path, default_path, pathlen);
        }
        setenv("PATH", path, 1);
    }

    /* Force non-threaded execution for now */
    globus_thread_set_model(GLOBUS_THREAD_MODEL_NONE);

    /* Activate a common before parsing command-line so that
     * things work. Note that we can't activate everything yet because we might
     * set the GLOBUS_TCP_PORT_RANGE after parsing command-line args and we
     * need that set before activating XIO.
     */
    rc = globus_module_activate(GLOBUS_COMMON_MODULE);
    if (rc != GLOBUS_SUCCESS)
    {
        fprintf(stderr, "Error activating GLOBUS_COMMON_MODULE\n");
        exit(1);
    }

    /* Parse command line options to get jobmanager configuration */
    rc = globus_gram_job_manager_config_init(&config, argc, argv);
    if (rc != GLOBUS_SUCCESS)
    {
        reply_and_exit(NULL, rc, NULL);
    }

    globus_thread_key_create(
            &globus_i_gram_request_key,
            NULL);

    rc = globus_gram_job_manager_logging_init(&config);
    if (rc != GLOBUS_SUCCESS)
    {
        exit(1);
    }
    if (getenv("GRID_SECURITY_HTTP_BODY_FD") == NULL && !cgi_invoked)
    {
        debug_mode_service = GLOBUS_TRUE;
    }
    /* Set environment variables from configuration */
    if(config.globus_location != NULL)
    {
        globus_libc_setenv("GLOBUS_LOCATION",
                           config.globus_location,
                           GLOBUS_TRUE);
    }
    if(config.tcp_port_range != NULL)
    {
        globus_libc_setenv("GLOBUS_TCP_PORT_RANGE",
                           config.tcp_port_range,
                           GLOBUS_TRUE);
    }
    if(config.tcp_source_range != NULL)
    {
        globus_libc_setenv("GLOBUS_TCP_SOURCE_RANGE",
                           config.tcp_source_range,
                           GLOBUS_TRUE);
    }

    /* Activate all of the modules we will be using */
    rc = globus_l_gram_job_manager_activate();
    if(rc != GLOBUS_SUCCESS)
    {
        exit(1);
    }

    /*
     * Get the delegated credential (or the default credential if we are
     * run without a client. Don't care about errors in the latter case.
     */
    major_status = globus_gss_assist_acquire_cred(
            &minor_status,
            GSS_C_BOTH,
            &cred);
    if ((!debug_mode_service) && GSS_ERROR(major_status))
    {
        globus_gss_assist_display_status(
                stderr,
                "Error acquiring security credential\n",
                major_status,
                minor_status,
                0);
        exit(1);
    }

    if (cred != GSS_C_NO_CREDENTIAL)
    {
        unsigned long hash;
        char * newtag;

        rc = globus_gram_gsi_get_dn_hash(
                cred,
                &hash);
        if (rc == GLOBUS_SUCCESS)
        {
            newtag = globus_common_create_string("%s%s%lx",
                    strcmp(config.service_tag, "untagged") == 0
                            ? "" : config.service_tag,
                    strcmp(config.service_tag, "untagged") == 0
                            ? "" : ".",
                    hash);
            free(config.service_tag);
            config.service_tag = newtag;
        }
    }

    /*
     * Remove delegated proxy from disk.
     */
    if ((!debug_mode_service) && getenv("X509_USER_PROXY") != NULL)
    {
        remove(getenv("X509_USER_PROXY"));
        unsetenv("X509_USER_PROXY");
    }

    /* Set up LRM-specific state based on our configuration. This will create
     * the job contact listener, start the SEG if needed, and open the log
     * file if needed.
     */
    rc = globus_gram_job_manager_init(&manager, cred, &config);
    if(rc != GLOBUS_SUCCESS)
    {
        reply_and_exit(NULL, rc, manager.gt3_failure_message);
    }

    /*
     * Pull out file descriptor numbers for security context and job request
     * from the environment (set by the gatekeeper)
     */
    if (cgi_invoked)
    {
        http_body_fd = 0;
        context_fd = -1;
    }
    else if (!debug_mode_service)
    {
        char * fd_env = getenv("GRID_SECURITY_HTTP_BODY_FD");

        rc = sscanf(fd_env ? fd_env : "-1", "%d", &http_body_fd);
        if (rc != 1 || http_body_fd < 0)
        {
            fprintf(stderr, "Error locating http body fd\n");
            exit(1);
        }
        fcntl(http_body_fd, F_SETFD, 1);

        fd_env = getenv("GRID_SECURITY_CONTEXT_FD");
        rc = sscanf(fd_env ? fd_env : "-1", "%d", &context_fd);
        if (rc != 1 || context_fd < 0)
        {
            fprintf(stderr, "Error locating security context fd\n");
            exit(1);
        }
        fcntl(context_fd, F_SETFD, 1);
    }


    /* Redirect stdin from /dev/null, we'll handle stdout after the reply is
     * sent
     */
    if (!cgi_invoked)
    {
        freopen("/dev/null", "r", stdin);
    }

    /* Here we'll either become the active job manager to process all
     * jobs for this user/host/lrm combination, or we'll hand off the
     * file descriptors containing the info to the active job manager
     */
    while (!located_active_jm)
    {
        /* We'll try to get the lock file associated with being the
         * active job manager here. If we get the OLD_JM_ALIVE error
         * somebody else has it
         */
        rc = globus_gram_job_manager_startup_lock(
                &manager,
                &manager.lock_fd);
        if (rc == GLOBUS_SUCCESS)
        {
            /* We've acquired the lock. We will fork a new process to act like
             * all other job managers which don't have the lock, and continue
             * on in this process managing jobs for this LRM.  Note that the
             * child process does not inherit the lock
             */
            if (!debug_mode_service)
            {
                int save_errno = 0;

                /* We've acquired the manager lock */
                forked_starter = fork();
                save_errno = errno;

                if (forked_starter < 0)
                {
                    if (sleeptime != 0)
                    {
                        sleep(sleeptime);
                    }

                    fprintf(stderr, "fork failed: %s", strerror(save_errno));
                    exit(1);
                }
                else if (forked_starter == 0)
                {
                    /* We are the child process. We'll close our reference to
                     * the lock and let the other process deal with jobs
                     */
                    close(manager.lock_fd);
                    manager.lock_fd = -1;
                }
                globus_logging_update_pid();
                if (sleeptime != 0)
                {
                    sleep(sleeptime);
                }

            }

            if (manager.lock_fd >= 0)
            {
                /* We hold the manager lock, so we'll store our credential, and
                 * then, try to accept socket connections. If the socket
                 * connections fail, we'll exit, and another process
                 * will be forked to handle them.
                 */
                rc = globus_gram_job_manager_gsi_write_credential(
                        NULL,
                        cred,
                        manager.cred_path);

                if (rc != GLOBUS_SUCCESS)
                {
                    fprintf(stderr, "write cred failed\n");
                    exit(1);
                }
                if (!debug_mode_service)
                {
                    close(http_body_fd);
                    http_body_fd = -1;
                }

                rc = globus_gram_job_manager_startup_socket_init(
                        &manager,
                        &manager.active_job_manager_handle,
                        &manager.socket_fd);
                if (rc != GLOBUS_SUCCESS)
                {
                    /* This releases our lock. Either the child process will
                     * attempt to acquire the lock again or some another job
                     * manager will acquire the lock
                     */
                    exit(0);
                }
                assert(manager.socket_fd != -1);
            }
        }
        else if (rc != GLOBUS_GRAM_PROTOCOL_ERROR_OLD_JM_ALIVE)
        {
            /* Some system error. Try again */
            if (--lock_tries_left == 0)
            {
                reply_and_exit(NULL, rc, "Unable to create lock file");
            }
            sleep(1);
            continue;
        }

        /* If manager.socket_fd != -1 then we are the main job manager for this
         * LRM.
         * We will restart all existing jobs and then allow the startup
         * socket to accept new jobs from other job managers.
         */
        if (manager.socket_fd != -1)
        {
            /* Look up cputype/manufacturer if not known yet */
            globus_l_gram_cputype_and_manufacturer(manager.config);

            GlobusTimeAbstimeGetCurrent(manager.usagetracker->jm_start_time);            
            globus_i_gram_usage_stats_init(&manager);
            globus_i_gram_usage_start_session_stats(&manager);

            located_active_jm = GLOBUS_TRUE;

            /* Load existing jobs. The show must go on if this fails, unless it
             * fails with a misconfiguration error
             */
            rc = globus_gram_job_manager_request_load_all(
                    &manager);
            if (rc == GLOBUS_GRAM_PROTOCOL_ERROR_GATEKEEPER_MISCONFIGURED)
            {
                if (forked_starter > 0)
                {
                    kill(forked_starter, SIGTERM);
                    forked_starter = 0;
                }
                reply_and_exit(NULL, rc, manager.gt3_failure_message);
            }
            if (context_fd != -1)
            {
                close(context_fd);
                context_fd = -1;
            }
            freopen("/dev/null", "a", stdout);

            /* At this point, seg_last_timestamp is the earliest last timestamp 
             * for any pre-existing jobs. If that is 0, then we don't have any
             * existing jobs so we'll just ignore seg events prior to now.
             */
            if (manager.seg_last_timestamp == 0)
            {
                manager.seg_last_timestamp = time(NULL);
            }

            /* Start off the SEG if we need it.
             */
            if (config.seg_module != NULL || 
                strcmp(config.jobmanager_type, "fork") == 0 ||
                strcmp(config.jobmanager_type, "condor") == 0)
            {
                rc = globus_gram_job_manager_init_seg(&manager);

                /* TODO: If SEG load fails and load_all added some to the 
                 * job_id hash, they will need to be pushed into the state
                 * machine so that polling fallback can happen.
                 */
                if (rc != GLOBUS_SUCCESS)
                {
                    config.seg_module = NULL;
                }
            }
            /* GRAM-128:
             * Register a periodic event to process the GRAM jobs that were
             * reloaded from their job state files at job manager start time.
             * This will acquire and then release a reference to each job,
             * which, behind the scenes, will kick of the state machine
             * for that job if needed.
             */
            if (!globus_list_empty(manager.pending_restarts))
            {
                globus_reltime_t        restart_period;

                GlobusTimeReltimeSet(restart_period, 1, 0);

                rc = globus_callback_register_periodic(
                        &manager.pending_restart_handle,
                        NULL,
                        &restart_period,
                        globus_l_gram_process_pending_restarts,
                        &manager);
                        
            }

            {
                globus_reltime_t        expire_period;

                GlobusTimeReltimeSet(expire_period, 1, 0);

                rc = globus_callback_register_periodic(
                    &manager.expiration_handle,
                    NULL,
                    &expire_period,
                    globus_gram_job_manager_expire_old_jobs,
                    &manager);
            }

            {
                globus_reltime_t        lockcheck_period;

                GlobusTimeReltimeSet(lockcheck_period, 60, 0);

                rc = globus_callback_register_periodic(
                    &manager.lockcheck_handle,
                    NULL,
                    &lockcheck_period,
                    globus_l_gram_lockcheck,
                    &manager);
            }

            {
                globus_reltime_t        idlescript_period;

                GlobusTimeReltimeSet(idlescript_period, 60, 0);

                rc = globus_callback_register_periodic(
                    &manager.idle_script_handle,
                    NULL,
                    &idlescript_period,
                    globus_gram_script_close_idle,
                    &manager);
            }
        }
        else if (http_body_fd >= 0)
        {
            /* If manager.socket_fd == -1 then we are either the child from the
             * fork or another process started somehow (either command-line
             * invocation or via a job submit). If we have a client, then we'll
             * send our fds to the job manager with the lock and let it process
             * the job.
             *
             * If this succeeds, we set located_active_jm and leave the loop.
             * Otherwise, we try again.
             */
            if (context_fd >= 0)
            {
                rc = globus_gram_job_manager_starter_send(
                        &manager,
                        http_body_fd,
                        context_fd,
                        fileno(stdout),
                        cred);
            }
            else
            {
                rc = globus_gram_job_manager_starter_send_v2(
                        &manager,
                        cred);
            }
            if (rc == GLOBUS_SUCCESS)
            {
                located_active_jm = GLOBUS_TRUE;
                close(http_body_fd);
                if (context_fd >= 0)
                {
                    close(context_fd);
                }
                manager.done = GLOBUS_TRUE;
            }
            else
            {
                globus_libc_usleep(250000);
            }
        }
        else
        {
            /* We were started by hand, but another process is currently the
             * main job manager
             */
            unsigned long realpid = 0;
            FILE * pidin = fopen(manager.pid_path, "r");
            fscanf(pidin, "%lu", &realpid);
            fclose(pidin);

            fprintf(stderr, "Other job manager process with pid %lu running and processing jobs\n",
                    realpid);

            exit(0);
        }
    }

    /* Ignore SIGCHILD, and automatically reap child processes. Because of the
     * fork() above to delegate to another job manager process, and the use of
     * sub-processes to invoke the perl modules, we create some other
     * processes. We don't care too much how they exit, so we'll just make sure
     * we don't create zombies out of them.
     */
    {
        struct sigaction act;

        act.sa_handler = SIG_IGN;
        sigemptyset(&act.sa_mask);
        sigaddset(&act.sa_mask, SIGCHLD);
#ifdef SA_NOCLDWAIT
        act.sa_flags = SA_NOCLDWAIT;
#else
        /* This may leave zombies running on non-POSIX systems like Hurd */
        act.sa_flags = 0;
#endif
        sigaction(SIGCHLD, &act, NULL);
    }

    /* Enable log rotation via SIGUSR1 */
    {
        struct sigaction act;
        act.sa_handler = globus_i_job_manager_log_rotate;
        sigemptyset(&act.sa_mask);
        sigaddset(&act.sa_mask, SIGUSR1);
        act.sa_flags = 0;
        sigaction(SIGUSR1, &act, NULL);
    }
    
    GlobusGramJobManagerLock(&manager);
    if (manager.socket_fd != -1 &&
        globus_hashtable_empty(&manager.request_hash) &&
        manager.grace_period_timer == GLOBUS_NULL_HANDLE)
    {
        globus_gram_job_manager_set_grace_period_timer(&manager);
    }


    /* For the active job manager, this will block until all jobs have
     * terminated. For any other job manager, the monitor.done is set to
     * GLOBUS_TRUE and this falls right through.
     */
    while (! manager.done)
    {
        GlobusGramJobManagerWait(&manager);
    }
    if (manager.expiration_handle != GLOBUS_NULL_HANDLE)
    {
        globus_callback_unregister(manager.expiration_handle, NULL, NULL, NULL);
    }
    if (manager.lockcheck_handle != GLOBUS_NULL_HANDLE)
    {
        globus_callback_unregister(manager.lockcheck_handle, NULL, NULL, NULL);
    }
    if (manager.idle_script_handle != GLOBUS_NULL_HANDLE)
    {
        globus_callback_unregister(manager.idle_script_handle, NULL, NULL, NULL);
    }
    GlobusGramJobManagerUnlock(&manager);

    globus_gram_job_manager_log(
            &manager,
            GLOBUS_GRAM_JOB_MANAGER_LOG_DEBUG,
            "event=gram.end "
            "level=DEBUG "
            "\n");

    /* Clean-up to do if we are the active job manager only */
    if (manager.socket_fd != -1)
    {
        globus_gram_job_manager_script_close_all(&manager);
        globus_i_gram_usage_end_session_stats(&manager);
        globus_i_gram_usage_stats_destroy(&manager);
        remove(manager.pid_path);
        remove(manager.cred_path);
        remove(manager.socket_path);
        remove(manager.lock_path);
    }
    globus_gram_job_manager_logging_destroy();
    globus_gram_job_manager_destroy(&manager);
    globus_gram_job_manager_config_destroy(&config);

    rc = globus_l_gram_deactivate();
    if (rc != GLOBUS_SUCCESS)
    {
        fprintf(stderr, "deactivation failed with rc=%d\n",
                rc);
        exit(1);
    }

/*
    {
        const char * gk_jm_id_var = "GATEKEEPER_JM_ID";
        const char * gk_jm_id = globus_libc_getenv(gk_jm_id_var);

        globus_gram_job_manager_request_acct(
                request,
                "%s %s JM exiting\n",
                gk_jm_id_var, gk_jm_id ? gk_jm_id : "none");
    }
*/


    return(0);
}
/* Test Case:
 * Submit a job that generates output after a short time.
 * Before that output is generated, send a STDIO_UPDATE signal, to
 * direct the output to a different port.
 * Verify that the output arrives at the new port
 */
int
test_stdio_update(void)
{
    char                                *old_listener_url, *new_listener_url;
    char                                *old_job_contact;
    int                                 rc;
    char                                *callback_contact;
    char                                *old_rsl, *new_rsl;
    test_monitor_t                      monitor;
    const char                          rsl_spec[] =
            "&(executable=/bin/sh)"
            "(arguments=-c 'sleep 30; echo hello;')"
            "(rsl_substitution = (TEST_GASS_URL %s))"
            "(stdout = $(TEST_GASS_URL)/out)";
    const char                          stdio_update_rsl_spec[] =
            "&(stdout = %s/out)";

    globus_mutex_init(&monitor.mutex, NULL);
    globus_cond_init(&monitor.cond, NULL);

    memset(monitor.old_output, 0, sizeof(monitor.old_output));
    memset(monitor.new_output, 0, sizeof(monitor.new_output));
    monitor.old_request = GLOBUS_NULL_HANDLE;
    monitor.new_request = GLOBUS_NULL_HANDLE;
    monitor.status = GLOBUS_GRAM_PROTOCOL_JOB_STATE_UNSUBMITTED;
    monitor.failure_code = 0;

    /* Create a pair of listeners and get their base URLs. The job will be
     * submitted with stdout directed to the first, then redirected to the
     * second via a stdio update signal
     */
    rc = globus_gass_transfer_create_listener(
            &monitor.old_listener,
            NULL,
            "https");
    test_assert_gram_rc_equals(rc, GLOBUS_SUCCESS);
    test_assert(monitor.old_listener != GLOBUS_NULL_HANDLE);

    old_listener_url = globus_gass_transfer_listener_get_base_url(
            monitor.old_listener);
    test_assert(old_listener_url != NULL);

    rc = globus_gass_transfer_register_listen(
            monitor.old_listener,
            test_l_old_listener_callback,
            &monitor);
    test_assert_gram_rc_equals(rc, GLOBUS_SUCCESS);

    rc = globus_gass_transfer_create_listener(
            &monitor.new_listener,
            NULL,
            "https");
    test_assert_gram_rc_equals(rc, GLOBUS_SUCCESS);
    test_assert(monitor.new_listener != GLOBUS_NULL_HANDLE);

    new_listener_url = globus_gass_transfer_listener_get_base_url(
            monitor.new_listener);
    test_assert(new_listener_url != NULL);

    rc = globus_gass_transfer_register_listen(
            monitor.new_listener,
            test_l_new_listener_callback,
            &monitor);
    test_assert(rc == GLOBUS_SUCCESS);

    old_rsl = globus_common_create_string(rsl_spec, old_listener_url);
    test_assert(old_rsl != NULL);

    /* Submit the job, do the two-phase commit, then submit a restart
     * request with the new stdout destination
     */
    rc = globus_gram_client_callback_allow(
            test_l_gram_callback,
            &monitor,
            &callback_contact);
    test_assert_gram_rc_equals(rc, GLOBUS_SUCCESS);
    test_assert(callback_contact != NULL);

    rc = globus_gram_client_job_request(
            contact_string,
            old_rsl,
            GLOBUS_GRAM_PROTOCOL_JOB_STATE_UNSUBMITTED|
            GLOBUS_GRAM_PROTOCOL_JOB_STATE_STAGE_IN|
            GLOBUS_GRAM_PROTOCOL_JOB_STATE_PENDING|
            GLOBUS_GRAM_PROTOCOL_JOB_STATE_ACTIVE|
            GLOBUS_GRAM_PROTOCOL_JOB_STATE_STAGE_OUT|
            GLOBUS_GRAM_PROTOCOL_JOB_STATE_DONE|
            GLOBUS_GRAM_PROTOCOL_JOB_STATE_FAILED,
            callback_contact,
            &old_job_contact);
    test_assert_gram_rc_equals(rc, GLOBUS_SUCCESS);
    test_assert(old_job_contact != NULL);

    globus_mutex_lock(&monitor.mutex);
    while (monitor.status == GLOBUS_GRAM_PROTOCOL_JOB_STATE_UNSUBMITTED)
    {
        globus_cond_wait(&monitor.cond, &monitor.mutex);
    }

    new_rsl = globus_common_create_string(
            stdio_update_rsl_spec, new_listener_url);
    test_assert(new_rsl != NULL);

    rc = globus_gram_client_job_signal(
            old_job_contact,
            GLOBUS_GRAM_PROTOCOL_JOB_SIGNAL_STDIO_UPDATE,
            new_rsl,
            &monitor.status,
            &monitor.failure_code);
    test_assert_gram_rc_equals(rc, GLOBUS_SUCCESS);

    /* Wait for job to complete. After it's done, check to see which
     * destination got stdout
     */
    while (monitor.status != GLOBUS_GRAM_PROTOCOL_JOB_STATE_DONE &&
           monitor.status != GLOBUS_GRAM_PROTOCOL_JOB_STATE_FAILED)
    {
        globus_cond_wait(&monitor.cond, &monitor.mutex);
    }
    if (monitor.old_request)
    {
        globus_gass_transfer_fail(monitor.old_request, test_l_gass_fail, NULL);
    }

    globus_mutex_unlock(&monitor.mutex);

    if (monitor.new_output[0] == 0)
    {
        fprintf(stderr, "Didn't get expected output to new handle\n");
        test_assert(strcmp((char *) monitor.new_output, "hello\n") == 0);
    }
    if (monitor.old_output[0] != 0)
    {
        fprintf(stderr, "Unexpected output to old handle: %s",
                monitor.old_output);
        test_assert(monitor.old_output[0] == 0);
    }

    return rc;
}
/**
 * Initialize configuration based on command-line arguments
 *
 * @param config
 *     LRMA-specific configuration state
 * @param argc
 *     Count of command-line arguments to the job manager.
 * @param argv
 *     Array of command-line arguments to the job manager.
 *
 * @retval GLOBUS_SUCCESS
 *     Success
 * @retval GLOBUS_GRAM_PROTOCOL_ERROR_GATEKEEPER_MISCONFIGURED
 *     Command-line includes -help
 */
int
globus_gram_job_manager_config_init(
    globus_gram_job_manager_config_t *  config,
    int                                 argc,
    char **                             argv)
{
    int                                 i;
    int                                 rc = 0;
    char *                              tmp;
    char                                hostname[MAXHOSTNAMELEN];
    struct utsname                      utsname;
    char *                              conf_path = NULL;
    char *                              dot;
    char *                              gatekeeper_contact;

    memset(config, 0, sizeof(globus_gram_job_manager_config_t));

    /* if -conf is passed then get the arguments from the file
     * specified
     */
    if (argc > 2 && !strcmp(argv[1],"-conf"))
    {
        char ** newargv;
        char * newbuf;
        int newargc = 52;
        int length;
        FILE *fp;

        newargv = (char**) malloc(newargc * sizeof(char *)); /* not freed */
        newargv[0] = argv[0];

        /* get file length via fseek & ftell */
        if ((fp = fopen(argv[2], "r")) == NULL)
        {
            globus_gram_job_manager_log(
                    NULL,
                    GLOBUS_GRAM_JOB_MANAGER_LOG_FATAL,
                    "event=gram.config.end level=FATAL path=\"%s\" "
                    "status=-1 msg=\"%s\" errno=%d reason=\"%s\"\n",
                    argv[2],
                    "Error opening configuration file",
                    errno,
                    strerror(errno));
            exit(1);
        }
        conf_path = argv[2];
        fseek(fp, 0, SEEK_END);
        length = ftell(fp);
        if (length <=0)
        {
            globus_gram_job_manager_log(
                    NULL,
                    GLOBUS_GRAM_JOB_MANAGER_LOG_FATAL,
                    "event=gram.config.end level=FATAL path=\"%s\" "
                    "status=-1 msg=\"%s\" errno=%d reason=\"%s\"\n",
                    conf_path,
                    "Error determining config file length",
                    errno,
                    strerror(errno));
           exit(1);
        }
        rewind(fp);

        newbuf = (char *) malloc(length+1);  /* dont free */
        i = fread(newbuf, 1, length, fp);
        if (i < 0)
        {
            globus_gram_job_manager_log(
                    NULL,
                    GLOBUS_GRAM_JOB_MANAGER_LOG_FATAL,
                    "event=gram.config.end level=FATAL path=\"%s\" "
                    "status=-1 msg=\"%s\" errno=%d reason=\"%s\"\n",
                    conf_path,
                    "Error reading configuration file",
                    errno,
                    strerror(errno));
            exit(1);
        }
        newbuf[i] = '\0';
        fclose(fp);

        newargv[0] = argv[0];
        newargc--;
        globus_l_gram_tokenize(newbuf, &newargv[1], &newargc);

        for (i=3; i<argc; i++)
            newargv[++newargc] = strdup(argv[i]);

        argv = newargv;
        argc = newargc + 1;
    }
    /* Default log level if nothing specified on command-line or config file */
    config->log_levels = -1;

    /* Default to using GLOBUS_USAGE_TARGETS environment variable.
     * If not set, use the Globus usage stats service
     * Eitehr can be overridden by using -disable-usagestats or setting
     * -usagestats-targets in the configuration file
     */
    if ((tmp = getenv("GLOBUS_USAGE_TARGETS")) != NULL)
    {
        config->usage_targets = strdup(tmp);
    }
    else
    {
        config->usage_targets = strdup("usage-stats.globus.org:4810");
    }
    /*
     * Parse the command line arguments
     */
    for (i = 1; i < argc; i++)
    {
        if (strcmp(argv[i], "-k") == 0)
        {
            config->kerberos = GLOBUS_TRUE;
        }
        else if ((strcmp(argv[i], "-home") == 0) && (i + 1 < argc))
        {
            config->globus_location = strdup(argv[++i]);
        }
        else if ((strcmp(argv[i], "-target-globus-location") == 0)
                 && (i + 1 < argc))
        {
            config->target_globus_location = strdup(argv[++i]);
        }
        else if ((strcmp(argv[i], "-type") == 0) && (i + 1 < argc))
        {
            config->jobmanager_type = strdup(argv[++i]);
        }
        else if((strcmp(argv[i], "-history") == 0) && (i + 1 < argc))
        {
            config->job_history_dir = strdup(argv[++i]);
        }
        else if (strcmp(argv[i], "-cache-location") == 0)
        {
            config->cache_location = strdup(argv[++i]);
        }
        else if (strcmp(argv[i], "-scratch-dir-base") == 0)
        {
            config->scratch_dir_base = strdup(argv[++i]);
        }
        else if ((strcmp(argv[i], "-condor-arch") == 0) && (i + 1 < argc))
        {
            config->condor_arch = strdup(argv[++i]);
        }
        else if ((strcmp(argv[i], "-condor-os") == 0) && (i + 1 < argc))
        {
            config->condor_os = strdup(argv[++i]);
        }
        else if ((strcmp(argv[i], "-globus-gatekeeper-host") == 0)
                 && (i + 1 < argc))
        {
            config->globus_gatekeeper_host = strdup(argv[++i]);
        }
        else if ((strcmp(argv[i], "-globus-gatekeeper-port") == 0)
                 && (i + 1 < argc))
        {
            config->globus_gatekeeper_port = strdup(argv[++i]);
        }
        else if ((strcmp(argv[i], "-globus-gatekeeper-subject") == 0)
                 && (i + 1 < argc))
        {
            config->globus_gatekeeper_subject = strdup(argv[++i]);
        }
        else if ((strcmp(argv[i], "-globus-host-manufacturer") == 0)
                 && (i + 1 < argc))
        {
            config->globus_host_manufacturer = strdup(argv[++i]);
        }
        else if ((strcmp(argv[i], "-globus-host-cputype") == 0)
                 && (i + 1 < argc))
        {
            config->globus_host_cputype = strdup(argv[++i]);
        }
        else if ((strcmp(argv[i], "-globus-host-osname") == 0)
                 && (i + 1 < argc))
        {
            config->globus_host_osname = strdup(argv[++i]);
        }
        else if ((strcmp(argv[i], "-globus-host-osversion") == 0)
                 && (i + 1 < argc))
        {
            config->globus_host_osversion = strdup(argv[++i]);
        }
        else if ((strcmp(argv[i], "-globus-tcp-port-range") == 0)
                 && (i + 1 < argc))
        {
            config->tcp_port_range = strdup(argv[++i]);
        }
        else if ((strcmp(argv[i], "-globus-tcp-source-range") == 0)
                 && (i + 1 < argc))
        {
            config->tcp_source_range = strdup(argv[++i]);
        }
        else if ((strcmp(argv[i], "-state-file-dir") == 0)
                 && (i + 1 < argc))
        {
            config->job_state_file_dir = strdup(argv[++i]);
        }
        else if ((strcmp(argv[i], "-x509-cert-dir") == 0)
                 && (i + 1 < argc))
        {
            config->x509_cert_dir = strdup(argv[++i]);
        }
        else if ((strcmp(argv[i], "-extra-envvars") == 0)
                 && (i + 1 < argc))
        {
            char * extra_envvars = strdup(argv[++i]);
            char *p, *q;

            p = extra_envvars;

            while (p && *p)
            {
                q = strchr(p, ',');

                if (q)
                {
                    *q = 0;
                }

                globus_list_insert(
                        &config->extra_envvars,
                        strdup(p));

                if (q)
                {
                    p = q+1;
                }
                else
                {
                    p = q;
                }
            }
            free(extra_envvars);
        }
        else if ((strcasecmp(argv[i], "-seg-module" ) == 0)
                 && (i + 1 < argc))
        {
            config->seg_module = strdup(argv[++i]);
        }
        else if ((strcmp(argv[i], "-audit-directory") == 0) 
                && (i+1 < argc))
        {
            globus_eval_path(argv[++i], &config->auditing_dir);
        }
        else if ((strcmp(argv[i], "-globus-toolkit-version") == 0)
                && (i+1 < argc))
        {
            config->globus_version = strdup(argv[++i]);
        }
        else if (strcmp(argv[i], "-disable-streaming") == 0)
        {
            /* Ignore this request, as we don't do streaming any more */
            config->streaming_disabled = GLOBUS_FALSE;
        }
        else if (strcmp(argv[i], "-service-tag") == 0
                && (i+1 < argc))
        {
            config->service_tag = strdup(argv[++i]);
        }
        else if (strcmp(argv[i], "-enable-syslog") == 0)
        {
            config->syslog_enabled = GLOBUS_TRUE;
        }
        else if (strcmp(argv[i], "-stdio-log") == 0
                && (i+1 < argc))
        {
            /* Backward-compatible definition of -stdio-log based on
             * -log-pattern implementation
             */
            config->log_pattern = globus_common_create_string(
                    "%s/gram_$(DATE).log",
                    argv[++i]);
        }
        else if (strcmp(argv[i], "-log-pattern") == 0
                && (i+1 < argc))
        {
            config->log_pattern = strdup(argv[++i]);
        }
        else if ((strcmp(argv[i], "-globus-job-dir") == 0)
                 && (i + 1 < argc))
        {
	    config->job_dir_home =
                globus_common_create_string(
                    "%s/%s",
                    argv[++i],
                    strdup(getenv("USER")));

            if (config->job_dir_home == NULL)
            {
                rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;

                goto out;
            }
	    globus_gram_job_manager_log(
                NULL,
                GLOBUS_GRAM_JOB_MANAGER_LOG_TRACE,
                "event=gram.config.info "
                "level=TRACE "
                "option=\"-globus-job-dir\" "
                "path=\"%s\" "
                "\n",
                config->job_dir_home);
        }
	else if (strcmp(argv[i], "-log-levels") == 0
                && (i+1 < argc))
        {
            rc = globus_i_gram_parse_log_levels(
                    argv[++i],
                    &config->log_levels,
                    NULL);
        }
        else if (strcmp(argv[i], "-disable-usagestats") == 0)
        {
            config->usage_disabled = GLOBUS_TRUE;
        }
        else if (strcmp(argv[i], "-usagestats-targets") == 0
                && (i+1 < argc))
        {
            if (config->usage_targets)
            {
                free(config->usage_targets);
                config->usage_targets = NULL;
            }
            config->usage_targets = strdup(argv[++i]);
        }
        else if (strcmp(argv[i], "-enable-callout") == 0)
        {
            config->enable_callout = GLOBUS_TRUE;
        }
        else if ((strcasecmp(argv[i], "-help" ) == 0) ||
                 (strcasecmp(argv[i], "--help") == 0))
        {
            fprintf(stderr,
                    "Usage: globus-gram-jobmanager\n"
                    "\n"
                    "Required Arguments:\n"
                    "\t-type jobmanager type, i.e. fork, lsf ...\n"
                    "\t-globus-host-manufacturer manufacturer\n"
                    "\t-globus-host-cputype cputype\n"
                    "\t-globus-host-osname osname\n"
                    "\t-globus-host-osversion osversion\n"
                    "\t-globus-gatekeeper-host host\n"
                    "\t-globus-gatekeeper-port port\n"
                    "\t-globus-gatekeeper-subject subject\n"
                    "\n"
                    "Options:\n"
                    "\t-home globus_location\n"
                    "\t-target-globus-location globus_location\n"
                    "\t-condor-arch arch, i.e. SUN4x\n"
                    "\t-condor-os os, i.e. SOLARIS26\n"
                    "\t-history job-history-directory\n" 
                    "\t-scratch-dir-base scratch-directory\n"
                    "\t-enable-syslog\n"
                    "\t-stdio-log DIRECTORY\n"
                    "\t-log-levels TRACE|INFO|DEBUG|WARN|ERROR|FATAL\n"
                    "\t-state-file-dir state-directory\n"
                    "\t-globus-tcp-port-range <min port #>,<max port #>\n"
                    "\t-globus-tcp-source-range <min port #>,<max port #>\n"
                    "\t-x509-cert-dir DIRECTORY\n"
                    "\t-cache-location PATH\n"
                    "\t-k\n"
                    "\t-extra-envvars VAR1,VAR2,...\n"
                    "\t-seg-module SEG-MODULE\n"
                    "\t-audit-directory DIRECTORY\n"
                    "\t-globus-toolkit-version VERSION\n"
                    "\t-usagestats-targets <host:port>[!<default | all>],...\n"
                    "\t-enable-callout\n"
		    "\t-globus-job-dir DIRECTORY\n"
                    "\n"
                    "Note: if type=condor then\n"
                    "      -condor-os & -condor-arch are required.\n"
                    "\n");
            rc = GLOBUS_GRAM_PROTOCOL_ERROR_GATEKEEPER_MISCONFIGURED;
            goto out;
        }
        else
        {
            globus_gram_job_manager_log(
                NULL,
                GLOBUS_GRAM_JOB_MANAGER_LOG_ERROR,
                "event=gram.config level=ERROR path=\"%s\" "
                "argument=%s reason=\"Invalid command-line option\"\n",
                conf_path ? conf_path : "ARGV",
                argv[i] ? argv[i] : "");
        }
    }

    /* If log levels were not specified on the command-line or configuration, set the
     * service default
     */
    if (config->log_levels == -1)
    {
        config->log_levels = 0;
    }
    /* Always have these at a minimum */
    config->log_levels |= GLOBUS_GRAM_JOB_MANAGER_LOG_FATAL
                       |  GLOBUS_GRAM_JOB_MANAGER_LOG_ERROR;

    /* Verify that required values are present */
    if(config->jobmanager_type == NULL)
    {
        globus_gram_job_manager_log(
            NULL,
            GLOBUS_GRAM_JOB_MANAGER_LOG_ERROR,
            "event=gram.config level=ERROR path=\"%s\" argument=\"-type\" reason=\"Missing -type command-line option\"\n",
            conf_path ? conf_path : "ARGV");

        rc = GLOBUS_GRAM_PROTOCOL_ERROR_GATEKEEPER_MISCONFIGURED;
        goto out;
    }

    if(config->home == NULL)
    {
        config->home =  strdup(getenv("HOME"));
	if (config->home == NULL)
	    {
		rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;

		goto out;
	    }
    }

    if (config->service_tag == NULL)
    {
        config->service_tag = strdup("untagged");
    }

    if (config->tcp_port_range == NULL)
    {
        char * ev = getenv("GLOBUS_TCP_PORT_RANGE");

        if (ev != NULL)
        {
            config->tcp_port_range = strdup(ev);
        }
    }
    if (config->tcp_source_range == NULL)
    {
        char * ev = getenv("GLOBUS_TCP_SOURCE_RANGE");

        if (ev != NULL)
        {
            config->tcp_source_range = strdup(ev);
        }
    }

    if (! globus_list_search_pred(
            config->extra_envvars, globus_l_env_present, "PATH"))
    {
        char * path = strdup("PATH");
        if (!path)
        {
            rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;

            goto out;
        }

        globus_list_insert(&config->extra_envvars, path);
    }

    /* Now initialize values from our environment */
    config->logname = strdup(getenv("LOGNAME"));
    if (config->logname == NULL)
    {
        rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;

        goto out;
    }

    if (config->globus_location == NULL)
    {
        rc = globus_location(&config->globus_location);
        if (rc != GLOBUS_SUCCESS)
        {
            rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;

            goto out;
        }
    }

    if (config->target_globus_location == NULL)
    {
        config->target_globus_location = strdup(config->globus_location);
        if (config->target_globus_location == NULL)
        {
            rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;

            goto out;
        }
    }
    if (config->job_state_file_dir == NULL)
    {
        rc = globus_eval_path("${localstatedir}/lib/globus/gram_job_state",
            &config->job_state_file_dir);

        if (rc != 0 || config->job_state_file_dir == NULL)
        {
            rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;

            goto out;
        }
    }

    if (config->job_dir_home == NULL)
    {
        config->job_dir_home = 
            globus_common_create_string("%s/%s",
                    config->job_state_file_dir,
                    config->logname);

        if (config->job_dir_home == NULL)
        {
            rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;

            goto out;
        }
    }

    if (config->scratch_dir_base == NULL)
    {
        config->scratch_dir_base = strdup(
                config->home);
        if (config->scratch_dir_base == NULL)
        {
            rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;

            goto out;
        }
    }

    rc = globus_libc_gethostname(hostname, sizeof(hostname));
    if (rc != GLOBUS_SUCCESS)
    {
        rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;
        goto out;
    }

    config->hostname = strdup(hostname);
    if (config->hostname == GLOBUS_NULL)
    {
        rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;
        goto out;
    }

    config->short_hostname = strdup(hostname);
    dot = strchr(config->short_hostname, '.');
    if (dot != NULL)
    {
        *dot = 0;
    }

    rc = uname(&utsname);

    if (rc >= 0)
    {
        if (config->globus_host_osname == NULL)
        {
            config->globus_host_osname = strdup(utsname.sysname);
        }
        if (config->globus_host_osversion == NULL)
        {
            if (strcmp(utsname.sysname, "AIX") == 0)
            {
                config->globus_host_osversion = globus_common_create_string(
                    "%s.%s",
                    utsname.version,
                    utsname.release);
            }
            else
            {
                config->globus_host_osversion = globus_common_create_string(
                    "%s",
                    utsname.release);
            }
        }
    }
    gatekeeper_contact = getenv("GLOBUS_GATEKEEPER_CONTACT_STRING");

    if (gatekeeper_contact)
    {
	char *colon;
	char *save = strdup(gatekeeper_contact);

	gatekeeper_contact = save;

	if (gatekeeper_contact)
	{
	    colon = strchr(gatekeeper_contact, ':');
	    if (colon)
	    {
		if (!config->globus_gatekeeper_host)
		{
		    *colon = '\0';
		    config->globus_gatekeeper_host = strdup(gatekeeper_contact);
		}
		gatekeeper_contact = colon + 1;

		colon = strchr(gatekeeper_contact, ':');
		if (colon)
		{
		    if (!config->globus_gatekeeper_port)
		    {
			*colon = '\0';
			config->globus_gatekeeper_port =
					strdup(gatekeeper_contact);
		    }
		    gatekeeper_contact = colon + 1;

		    if (!config->globus_gatekeeper_subject)
		    {
			config->globus_gatekeeper_subject =
			    strdup(gatekeeper_contact);
		    }
		}
	    }
	}
	free(save);
    }

    rc = globus_module_activate(GLOBUS_GSI_GSSAPI_MODULE);
    if (rc != GLOBUS_SUCCESS)
    {
        goto out;
    }

    rc = globus_gram_job_manager_gsi_get_subject(&config->subject);
    if (rc != GLOBUS_SUCCESS)
    {
        goto out;
    }

    config->proxy_timeout = 10*60;

out:
    return rc;
}
Exemplo n.º 15
0
static
globus_result_t
globus_l_extension_dlopen(
    const char *                        name,
    lt_dlhandle *                       handle)
{
    char                                library[1024];
    lt_dlhandle                         dlhandle;
    char *                              path;
    char *                              basename;
    char *                              search_path = NULL;
    char *                              save_path = NULL;
    globus_result_t                     result = GLOBUS_SUCCESS;
    GlobusFuncName(globus_l_extension_dlopen);
    
    path = globus_libc_strdup(name);
    if(path && (basename = strrchr(path, '/')))
    {
        *basename = 0;
        if(basename == path)
        {
            /* ignore root dir */
            name = path + 1;
        }
        else if(*(basename + 1) == 0)
        {
            /* ignore trailing slashes */
            name = path;
        }
        else
        {
            name = basename + 1;
            if(globus_l_globus_location)
            {
                /* if globus_location is not set, then it's likely I won't
                 * find the library
                 */
                search_path = globus_common_create_string(
                    "%s/%s", globus_l_globus_location, path);
            }
        }
    }
    
    globus_l_libtool_mutex_lock();
    
    if(search_path || globus_l_globus_location)
    {
        if((save_path = (char *) lt_dlgetsearchpath()))
        {
            /* libtool frees this pointer before setting the next one */
            save_path = globus_libc_strdup(save_path);
        }
    
        lt_dlsetsearchpath(
            search_path ? search_path : globus_l_globus_location);
    }
    
    snprintf(library, 1024, "lib%s", name);
    library[1023] = 0;
    dlhandle = lt_dlopenext(library);
    if(!dlhandle)
    {
        /* older libtools dont search the extensions correctly */
        snprintf(library, 1024, "lib%s" MY_LIB_EXT, name);
        library[1023] = 0;
        dlhandle = lt_dlopenext(library);
    }

#if USE_SYMBOL_LABELS
    if (!dlhandle)
    {
        snprintf(library, 1024, "lib%s_%s",
            name,
            (sizeof(long) == 8) ? "gcc64pthr" : "gcc32pthr");
        library[1023] = 0;
        dlhandle = lt_dlopenext(library);

        if(!dlhandle)
        {
            /* older libtools dont search the extensions correctly */
            snprintf(library, 1024, "lib%s_%s" MY_LIB_EXT, name,
                (sizeof(long) == 8) ? "gcc64pthr" : "gcc32pthr");
            library[1023] = 0;
            dlhandle = lt_dlopenext(library);
        }
    }
#endif

    if(!dlhandle)
    {
        const char *                error;
        
        error = lt_dlerror();
        
        GlobusExtensionDebugPrintf(
            GLOBUS_L_EXTENSION_DEBUG_DLL,
            (_GCSL("[%s] Couldn't dlopen %s in %s (or LD_LIBRARY_PATH): %s\n"),
             _globus_func_name, library,
             search_path ? search_path : globus_l_globus_location 
                ? globus_l_globus_location : "(default)",
             error ? error : "(null)"));
        result = globus_error_put(
            globus_error_construct_error(
                GLOBUS_EXTENSION_MODULE,
                NULL,
                GLOBUS_EXTENSION_ERROR_OPEN_FAILED,
                __FILE__,
                _globus_func_name,
                __LINE__,
                "Couldn't dlopen %s in %s (or LD_LIBRARY_PATH): %s\n",
                library,
                (search_path ? search_path : 
                               (globus_l_globus_location ? 
                                    globus_l_globus_location : 
                                "(default)")),
                error ? error : "(null)"));
    }
    
    if(search_path || globus_l_globus_location)
    {
        lt_dlsetsearchpath(save_path);
        if(save_path)
        {
            globus_free(save_path);
        }
    }
    globus_l_libtool_mutex_unlock();
    
    if(search_path)
    {
        globus_free(search_path);
    }
    
    if(path)
    {
        globus_free(path);
    }
    
    *handle = dlhandle;
    return result;
}
Exemplo n.º 16
0
/*
 * Timeout test:
 *  -t server|client
 *     Configure the server or client to cause a timeout. If server is
 *     selected, then it will delay its part of the operation longer than the
 *     timeout value, causing the client to time out (and vice versa).
 *  -T timeout-in-ms
 *     Set the timeout value in ms
 *  -a
 *     Expect / cause the accept operation to delay longer than the timeout.
 *  -r
 *     Expect / cause a read operation to delay longer than the timeout.
 *
 */
int
main(
    int                                 argc,
    char *                              argv[])
{
    int                                 rc;
    char *                              contact = NULL;
    globus_result_t                     result;
    globus_l_timeout_info_t             client_timeout_info;
    globus_l_timeout_info_t             server_timeout_info;
    globus_reltime_t                    timeout;

    client_timeout_info.cause_timeout = GLOBUS_TRUE;
    client_timeout_info.expect_timeout = GLOBUS_FALSE;
    server_timeout_info.cause_timeout = GLOBUS_FALSE;
    server_timeout_info.expect_timeout = GLOBUS_TRUE;

    client_timeout_info.timeout_state =
        GLOBUS_XIO_OPERATION_TYPE_ACCEPT;
    server_timeout_info.timeout_state =
        GLOBUS_XIO_OPERATION_TYPE_ACCEPT;
    client_timeout_info.timeout = 1000;
    server_timeout_info.timeout = 1000;

    while ((rc = getopt(argc, argv, "t:T:arh")) != EOF)
    {
        switch (rc)
        {
            case 'h':
                usage(argv[0]);
                exit(0);
            case 't':
                if (strcmp(optarg, "client") == 0)
                {
                    client_timeout_info.cause_timeout = GLOBUS_TRUE;
                    client_timeout_info.expect_timeout = GLOBUS_FALSE;
                    server_timeout_info.cause_timeout = GLOBUS_FALSE;
                    server_timeout_info.expect_timeout = GLOBUS_TRUE;
                }
                else if (strcmp(optarg, "server") == 0)
                {
                    client_timeout_info.cause_timeout = GLOBUS_FALSE;
                    client_timeout_info.expect_timeout = GLOBUS_TRUE;
                    server_timeout_info.cause_timeout = GLOBUS_TRUE;
                    server_timeout_info.expect_timeout = GLOBUS_FALSE;
                }
                else
                {
                    usage(argv[0]);
                    exit(1);
                }
                break;
            case 'T':
                client_timeout_info.timeout = atoi(optarg);
                server_timeout_info.timeout = atoi(optarg);
                break;
            case 'a':
                client_timeout_info.timeout_state =
                    GLOBUS_XIO_OPERATION_TYPE_ACCEPT;
                server_timeout_info.timeout_state =
                    GLOBUS_XIO_OPERATION_TYPE_ACCEPT;
                break;
            case 'r':
                client_timeout_info.timeout_state =
                    GLOBUS_XIO_OPERATION_TYPE_READ;
                server_timeout_info.timeout_state =
                    GLOBUS_XIO_OPERATION_TYPE_READ;
                break;
            default:
                usage(argv[0]);
                exit(1);
        }
    }

    rc = http_test_initialize(
            &globus_l_tcp_driver,
            &globus_l_http_driver,
            &globus_l_http_stack);

    if (rc != GLOBUS_SUCCESS)
    {
        exit(2);
    }

    globus_mutex_init(&lock, NULL);
    globus_cond_init(&cond, NULL);

    GlobusTimeReltimeSet(timeout,
            0,
            (server_timeout_info.timeout * 1000));

    globus_xio_attr_init(&client_timeout_info.attr);
    globus_xio_attr_init(&server_timeout_info.attr);
    switch (server_timeout_info.timeout_state)
    {
        case GLOBUS_XIO_OPERATION_TYPE_ACCEPT:
            if (client_timeout_info.cause_timeout)
            {
                globus_xio_attr_cntl(
                        server_timeout_info.attr,
                        NULL,
                        GLOBUS_XIO_ATTR_SET_TIMEOUT_ACCEPT,
                        globus_l_timeout_callback,
                        &timeout,
                        NULL);
            }
            else
            {
                fprintf(stderr,
                        "Unable to handle server-caused accept timeout\n");
                exit(6);
            }
            break;

        case GLOBUS_XIO_OPERATION_TYPE_READ:
            if (client_timeout_info.cause_timeout)
            {
                globus_xio_attr_cntl(
                        server_timeout_info.attr,
                        NULL,
                        GLOBUS_XIO_ATTR_SET_TIMEOUT_READ,
                        globus_l_timeout_callback,
                        &timeout,
                        NULL);
            }
            else
            {
                globus_xio_attr_cntl(
                        client_timeout_info.attr,
                        NULL,
                        GLOBUS_XIO_ATTR_SET_TIMEOUT_READ,
                        globus_l_timeout_callback,
                        &timeout,
                        NULL);
            }
            break;

        default:
            fprintf(stderr, "Error: invalid timeout state\n");
            exit(3);
    }

    /* Set up client attributes */
    globus_xio_attr_cntl(
            client_timeout_info.attr,
            globus_l_http_driver,
            GLOBUS_XIO_HTTP_ATTR_SET_REQUEST_METHOD,
            "POST");

    /* Modulate timeout state to causer's related state for delaying */
    if (client_timeout_info.cause_timeout)
    {
        switch (client_timeout_info.timeout_state)
        {
            case GLOBUS_XIO_OPERATION_TYPE_ACCEPT:
                client_timeout_info.timeout_state =
                    GLOBUS_XIO_OPERATION_TYPE_OPEN;
                break;

            case GLOBUS_XIO_OPERATION_TYPE_READ:
                client_timeout_info.timeout_state =
                    GLOBUS_XIO_OPERATION_TYPE_WRITE;
                break;

            case GLOBUS_XIO_OPERATION_TYPE_WRITE:
            case GLOBUS_XIO_OPERATION_TYPE_OPEN:
            case GLOBUS_XIO_OPERATION_TYPE_CLOSE:
            case GLOBUS_XIO_OPERATION_TYPE_FINISHED:
            case GLOBUS_XIO_OPERATION_TYPE_NONE:
            case GLOBUS_XIO_OPERATION_TYPE_DRIVER:
            case GLOBUS_XIO_OPERATION_TYPE_DD:
            case GLOBUS_XIO_OPERATION_TYPE_SERVER_INIT:
                fprintf(stderr,
                        "Error: unexpected state: %d\n",
                        client_timeout_info.state);
                exit(4);
        }
    }
    else
    {
        globus_assert(server_timeout_info.cause_timeout);
        switch (server_timeout_info.timeout_state)
        {
            case GLOBUS_XIO_OPERATION_TYPE_ACCEPT:
                fprintf(stderr,
                        "Invalid option (server-caused accept timeout)\n");
                exit(5);

            case GLOBUS_XIO_OPERATION_TYPE_READ:
                server_timeout_info.timeout_state =
                    GLOBUS_XIO_OPERATION_TYPE_WRITE;
                break;

            case GLOBUS_XIO_OPERATION_TYPE_WRITE:
            case GLOBUS_XIO_OPERATION_TYPE_OPEN:
            case GLOBUS_XIO_OPERATION_TYPE_CLOSE:
            case GLOBUS_XIO_OPERATION_TYPE_FINISHED:
            case GLOBUS_XIO_OPERATION_TYPE_NONE:
            case GLOBUS_XIO_OPERATION_TYPE_DRIVER:
            case GLOBUS_XIO_OPERATION_TYPE_DD:
            case GLOBUS_XIO_OPERATION_TYPE_SERVER_INIT:
                fprintf(stderr,
                        "Error: unexpected state: %d\n",
                        server_timeout_info.state);
                exit(4);
        }
    }

    /* create server */
    server_timeout_info.state = GLOBUS_XIO_OPERATION_TYPE_ACCEPT;
    server_timeout_info.handle = NULL;
    server_timeout_info.result = GLOBUS_SUCCESS;
    server_timeout_info.contact = NULL;
    result = globus_xio_server_create(
            &server_timeout_info.server,
            server_timeout_info.attr,
            globus_l_http_stack);

    result = globus_xio_server_get_contact_string(
            server_timeout_info.server,
            &contact);

    client_timeout_info.contact = globus_common_create_string("http://%s/%s",
            contact,
            "ok");

    /* create client handle */
    client_timeout_info.state = GLOBUS_XIO_OPERATION_TYPE_OPEN;
    client_timeout_info.handle = NULL;
    client_timeout_info.result = GLOBUS_SUCCESS;
    client_timeout_info.server = NULL;

    result = globus_xio_handle_create(
            &client_timeout_info.handle,
            globus_l_http_stack);

    /* oneshot to start server state machine */
    result = globus_callback_register_oneshot(
            NULL,
            &globus_i_reltime_zero,
            state_machine,
            &server_timeout_info);

    /* oneshot to start client state machine */
    result = globus_callback_register_oneshot(
            NULL,
            &globus_i_reltime_zero,
            state_machine,
            &client_timeout_info);

    /* wait for both state machines to terminate */
    globus_mutex_lock(&lock);
    while (client_timeout_info.state != GLOBUS_XIO_OPERATION_TYPE_NONE &&
           server_timeout_info.state != GLOBUS_XIO_OPERATION_TYPE_NONE)
    {
        globus_cond_wait(&cond, &lock);
    }
    globus_mutex_unlock(&lock);
    globus_mutex_destroy(&lock);

    globus_module_deactivate_all();

    return (client_timeout_info.result ||
            server_timeout_info.result ||
            client_timeout_info.expect_timeout ||
            server_timeout_info.expect_timeout);
}
/**
 * Periodic poll of file to act like tail -f
 *
 * @param user_arg
 *     Log file parsing state
 */
static
void
globus_l_job_manager_poll_callback(
    void *                              user_arg)
{
    int                                 rc;
    globus_l_job_manager_logfile_state_t *
                                        state = user_arg;
    globus_bool_t                       eof_hit = GLOBUS_FALSE;
    globus_reltime_t                    delay;
    globus_result_t                     result;
    time_t                              poll_time = time(NULL);
    struct tm                           poll_tm, *tm_result;
    struct stat                         stat;
    char *                              today;

    SEG_JOB_MANAGER_DEBUG(SEG_JOB_MANAGER_DEBUG_INFO,
            ("globus_l_job_manager_poll_callback()\n"));

    globus_mutex_lock(&globus_l_job_manager_mutex);
    if (shutdown_called)
    {
        SEG_JOB_MANAGER_DEBUG(SEG_JOB_MANAGER_DEBUG_INFO,
                ("polling while deactivating"));

        globus_mutex_unlock(&globus_l_job_manager_mutex);
        goto error;
    }
    globus_mutex_unlock(&globus_l_job_manager_mutex);

    if (state->fp != NULL)
    {
        /* Parse data */
        SEG_JOB_MANAGER_DEBUG(SEG_JOB_MANAGER_DEBUG_TRACE,
                ("parsing events\n"));
        rc = globus_l_job_manager_parse_events(state);
        if (rc == SEG_JOB_MANAGER_ERROR_LOG_EOF)
        {
            eof_hit = GLOBUS_TRUE;
        }
    }

    if (eof_hit)
    {
        tm_result = globus_libc_gmtime_r(&poll_time, &poll_tm);
        if (tm_result == NULL)
        {
            SEG_JOB_MANAGER_DEBUG(SEG_JOB_MANAGER_DEBUG_WARN,
                    ("Couldn't convert to gmtime\n"));
        }
        else
        {
            today = globus_common_create_string(
                    "%s/%4d%02d%02d",
                    state->log_dir,
                    tm_result->tm_year+1900,
                    tm_result->tm_mon+1,
                    tm_result->tm_mday);
            if (today && (strcmp(today, state->path) != 0))
            {
                /* New day... if new file exists and the old one hasn't changed since our
                 * last poll, mark it as old
                 */
                if (globus_l_next_file_exists(state))
                {
                    rc = fstat(fileno(state->fp), &stat);
                    if (rc != -1)
                    {
                        if (ftello(state->fp) == stat.st_size)
                        {
                            state->old_log = GLOBUS_TRUE;
                        }
                    }
                }
            }
            if (today)
            {
                free(today);
            }
        }
    }

    /* If end of log, close this logfile and look for a new one. Also, if
     * the current day's log doesn't exist yet, check for it
     */
    if ((eof_hit && state->old_log) || state->fp == NULL)
    {
        if (state->fp)
        {
            fclose(state->fp);
            state->fp = NULL;
            state->start_timestamp.tm_mday++;
            state->start_timestamp.tm_hour = 0;
            state->start_timestamp.tm_min = 0;
            state->start_timestamp.tm_sec = 0;
            globus_l_job_manager_normalize_date(&state->start_timestamp);
        }

        rc = globus_l_job_manager_find_logfile(state);

        if (rc == GLOBUS_SUCCESS)
        {
            /* Opening a new logfile, run w/out delay */
            state->fp = fopen(state->path, "r");
            if (state->fp == NULL)
            {
                goto error;
            }
            eof_hit = GLOBUS_FALSE;

            GlobusTimeReltimeSet(delay, 0, 0);
        }
        else if (rc == SEG_JOB_MANAGER_ERROR_LOG_NOT_PRESENT)
        {
            /* Current day's logfile not present, wait a bit longer for
             * it to show up
             */
            GlobusTimeReltimeSet(delay, 30, 0);
            eof_hit = GLOBUS_TRUE;
        }
        else
        {
            goto error;
        }
    }
    else if(eof_hit)
    {
        /* eof on current logfile, wait for new data */
        GlobusTimeReltimeSet(delay, 2, 0);
    }
    else
    {
        /* still data available in current file, hurry up! */
        GlobusTimeReltimeSet(delay, 0, 0);
    }

    result = globus_callback_register_oneshot(
            &state->callback,
            &delay,
            globus_l_job_manager_poll_callback,
            state);
    if (result != GLOBUS_SUCCESS)
    {
        goto error;
    }
    SEG_JOB_MANAGER_DEBUG(SEG_JOB_MANAGER_DEBUG_INFO,
            ("globus_l_job_manager_poll_callback() exited with/success\n"));
    return;
error:
    globus_mutex_lock(&globus_l_job_manager_mutex);
    if (shutdown_called)
    {
        callback_count--;

        if (callback_count == 0)
        {
            globus_cond_signal(&globus_l_job_manager_cond);
        }
    }
    globus_mutex_unlock(&globus_l_job_manager_mutex);

    SEG_JOB_MANAGER_DEBUG(SEG_JOB_MANAGER_DEBUG_WARN,
            ("globus_l_job_manager_poll_callback() exited with/error\n"));
    return;
}
Exemplo n.º 18
0
/* driver list stuff */
globus_result_t
globus_xio_driver_list_from_string(
    char *                              driver_string,
    globus_list_t **                    driver_list,
    globus_hashtable_t *                safe_table)
{
    globus_result_t                     result;
    globus_bool_t                       done = GLOBUS_FALSE;
    globus_bool_t                       loaded;
    char *                              opts;
    char *                              ptr;
    char *                              driver_str;
    char *                              driver_name;
    char *                              tmp_str;
    globus_xio_driver_t                 driver;
    globus_list_t *                     list = NULL;
    globus_xio_driver_list_ent_t *      list_ent;
    GlobusXIOName(globus_xio_driver_list_from_string);

    *driver_list = NULL;

    if(driver_string == NULL) 
    {
        result = GlobusXIOErrorParameter("driver_string");
        goto error_param;
    }

    driver_str = globus_libc_strdup(driver_string);
    tmp_str = driver_str;
    while(!done)
    {
        loaded = GLOBUS_FALSE;
        driver_name = tmp_str;
        ptr = strchr(driver_name, ',');
        if(ptr != NULL)
        {
            *ptr = '\0';
            tmp_str = ptr+1;
        }
        else
        {
            done = GLOBUS_TRUE;
        }
        opts = strchr(driver_name, ':');
        if(opts != NULL)
        {
            *opts = '\0';
            opts++;

            /* decode the string */
            globus_url_string_hex_decode(opts);
        }

        /* check against the safe list */
        if(safe_table != NULL)
        {
            char *                      err_str;

            list_ent = (globus_xio_driver_list_ent_t *)
                globus_hashtable_lookup(safe_table, driver_name);

            if(list_ent == NULL)
            {
                err_str = globus_common_create_string(
                    "%s driver not whitelisted", driver_name);
                result = GlobusXIOErrorParameter(err_str);
                globus_free(err_str);
                goto error_load;
            }
            driver = list_ent->driver;
        }
        else
        {
            result = globus_xio_driver_load(driver_name, &driver);
            if(result != GLOBUS_SUCCESS)
            {
                goto error_load;
            }

            loaded = GLOBUS_TRUE;
        }

        list_ent = (globus_xio_driver_list_ent_t *)
            globus_calloc(1, sizeof(globus_xio_driver_list_ent_t));
        list_ent->opts = globus_libc_strdup(opts);
        list_ent->driver = driver;
        list_ent->driver_name = globus_libc_strdup(driver_name);
        list_ent->loaded = loaded;

        globus_list_insert(&list, list_ent);
    }

    globus_free(driver_str);

    /* reverse list */
    while(!globus_list_empty(list))
    {
        globus_list_insert(driver_list, globus_list_first(list));
        globus_list_remove(&list, list);
    }

    return GLOBUS_SUCCESS;

error_load:
    globus_free(driver_str);
    while(!globus_list_empty(list))
    {
        list_ent = (globus_xio_driver_list_ent_t *)
            globus_list_remove(&list, list);

        if(list_ent->loaded)
        {
            globus_xio_driver_unload(list_ent->driver);
        }
        globus_free(list_ent->driver_name);
        if(list_ent->opts != NULL)
        {
            globus_free(list_ent->opts);
        }
        globus_free(list_ent);
    }
error_param:
    return result;
}
Exemplo n.º 19
0
 *
 ************************************************************************/
static
void
globus_l_dsi_rest_recv(
    globus_gfs_operation_t              op,
    globus_gfs_transfer_info_t *        transfer_info,
    void *                              user_arg)
{
    globus_dsi_rest_gridftp_op_arg_t    gridftp_op_arg = {.op=op};
    globus_l_dsi_rest_handle_t         *dsi_rest_handle = user_arg;
    char                               *uri;
    globus_result_t                     result = GLOBUS_SUCCESS;

    uri = globus_common_create_string(
            "http://%s/%s",
            dsi_rest_handle->contact_string,
            transfer_info->pathname+1);

    if (uri == NULL)
    {
        result = GlobusGFSErrorMemory("globus_common_create_string");
        goto create_uri_fail;
    }

    globus_gridftp_server_begin_transfer(op, 0, NULL);
    do
    {
        globus_gridftp_server_get_write_range(
                gridftp_op_arg.op,
                &gridftp_op_arg.offset,
                &gridftp_op_arg.length);
Exemplo n.º 20
0
size_t
globus_i_dsi_rest_header(
    char                               *buffer,
    size_t                              size,
    size_t                              nitems,
    void                               *callback_arg)
{
    globus_result_t                     result = GLOBUS_SUCCESS;
    size_t                              total = size * nitems;
    globus_i_dsi_rest_request_t        *request = callback_arg;

    GlobusDsiRestEnter();

    if (request->response_code == 0 && request->response_reason[0] == 0)
    {
        /* Actually the status line, not a header */
        char bufferstring[total + 1];
        memcpy(bufferstring, buffer, total);
        bufferstring[total] = 0;

        GlobusDsiRestInfo("%s", buffer);

        int scans = sscanf(bufferstring, "HTTP/%*s %d %64[^\r]",
            &request->response_code,
            request->response_reason);

        if (scans != 2)
        {
            result = GlobusDsiRestErrorParse(bufferstring);
        }
        goto done;
    }
    else
    {
        GlobusDsiRestDebug("%.*s", (int) (size*nitems), buffer); 
    }

    if (request->response_callback == NULL
        && request->read_part.data_read_callback
            != globus_dsi_rest_read_multipart)
    {
        /* Don't bother parsing if client doesn't care */
        goto done;
    }

    result = globus_i_dsi_rest_header_parse(
        &request->read_part.headers,
        buffer,
        total);

    if (result != GLOBUS_SUCCESS)
    {
        if (request->result == GLOBUS_SUCCESS)
        {
            request->result = result;
        }
        goto done;
    }

    if (memcmp(buffer, "\r\n", 2) == 0)
    {
        if (request->response_code == 100)
        {
            /* If we get a 100 Continue response, we'll need to reinitialize
             * the headers and response code for the real response
             */
            request->response_code = 0;
            request->response_reason[0] = 0;
            for (size_t i = 0; i < request->read_part.headers.count; i++)
            {
                free((char *) request->read_part.headers.key_value[i].key);
                free((char *) request->read_part.headers.key_value[i].value);
            }
            free(request->read_part.headers.key_value);
            request->read_part.headers.key_value = NULL;
            request->read_part.headers.count = 0;
        }
        else
        {
            globus_dsi_rest_response_arg_t
                                       *response
                                      = request->response_callback_arg;

            if (request->response_callback == globus_dsi_rest_response)
            {
                response->request_bytes_uploaded =
                        request->request_bytes_uploaded;
                response->response_bytes_downloaded =
                        request->response_bytes_downloaded;
            }
            if (request->read_part.data_read_callback
                == globus_dsi_rest_read_multipart)
            {
                const char             *boundary = NULL;
                const char             *boundary_end = NULL;
                globus_i_dsi_rest_read_multipart_arg_t
                                       *read_multipart
                                       = request->read_part.data_read_callback_arg;

                for (size_t i = 0; i < request->read_part.headers.count; i++)
                {
                    if (strcasecmp(
                            request->read_part.headers.key_value[i].key,
                            "Content-Type") == 0
                        && strncasecmp(
                            request->read_part.headers.key_value[i].value,
                            "multipart/",
                            strlen("multipart/")) == 0)
                    {
                        boundary = strcasestr(
                            request->read_part.headers.key_value[i].value,
                            "boundary=");
                        boundary += strlen("boundary=");
                        if (*boundary == '"')
                        {
                            boundary++;
                            for (size_t b = 0; boundary[b] != 0; b++)
                            {
                                if (boundary[b] == '"')
                                {
                                    boundary_end = &boundary[b-1];
                                }
                                if (boundary[b] == '\\')
                                {
                                    b++;
                                }
                            }
                        }
                        else
                        {
                            for (size_t b = 0; boundary[b] != 0; b++)
                            {
                                if (isspace(boundary[b]))
                                {
                                    boundary_end = &boundary[b-1];
                                    break;
                                }
                            }
                        }
                    }
                }
                if (boundary != NULL)
                {
                    if (boundary_end != NULL)
                    {
                        read_multipart->boundary =
                            globus_common_create_string(
                                "%.*s",
                                (int) (boundary_end - boundary),
                                boundary);
                    }
                    else
                    {
                        read_multipart->boundary =
                            globus_common_create_string(
                                "%s", boundary);
                    }

                    read_multipart->boundary_length = strlen(
                        read_multipart->boundary);
                    /* \r\n--boundary--\r\n\0 */
                    read_multipart->boundary_buffer_length = 
                        read_multipart->boundary_length + 9;
                    read_multipart->boundary_buffer = malloc(
                        read_multipart->boundary_buffer_length);
                    read_multipart->boundary_buffer_offset = 0;
                }
            }
            if (request->response_callback != NULL)
            {
                result = request->response_callback(
                    request->response_callback_arg,
                    request->response_code,
                    request->response_reason,
                    &request->read_part.headers);
            }
        }
    }

done:
    if (result != GLOBUS_SUCCESS)
    {
        total = !total;
    }
    GlobusDsiRestExitSizeT(total);
    return total;
}
Exemplo n.º 21
0
/**
 * @brief Export a GSSAPI credential
 * @ingroup globus_gsi_gssapi_extensions
 * @details
 * Saves the credential so it can be checkpointed and 
 * imported by gss_import_cred
 *
 * @param minor_status
 * @param cred_handle
 * @param desired_mech
 *        Should either be gss_mech_globus_gssapi_openssl or
 *        NULL (in which case gss_mech_globus_gssapi_openssl is
 *        assumed).
 * @param option_req
 * @param export_buffer
 *
 * @return
 */
OM_uint32 
GSS_CALLCONV gss_export_cred(
    OM_uint32 *                         minor_status,
    const gss_cred_id_t                 cred_handle,
    const gss_OID                       desired_mech,
    OM_uint32                           option_req,
    gss_buffer_t                        export_buffer)
{
    OM_uint32                           major_status = GLOBUS_SUCCESS;
    BIO *                               bp = NULL;
    gss_cred_id_desc *                  cred_desc = NULL;
    globus_result_t                     local_result;
    char *                              proxy_filename = NULL;

    GLOBUS_I_GSI_GSSAPI_DEBUG_ENTER;

    cred_desc = (gss_cred_id_desc *) cred_handle;
    
    *minor_status = (OM_uint32) GLOBUS_SUCCESS;

    if (export_buffer == NULL ||
        export_buffer == GSS_C_NO_BUFFER)
    {
        major_status = GSS_S_FAILURE;
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
            (_GGSL("NULL or empty export_buffer parameter passed to function: %s"),
             __func__));
        goto exit;
    }

    export_buffer->length = 0;
    export_buffer->value = NULL;

    if (cred_handle == NULL)
    { 
        major_status = GSS_S_FAILURE;
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
            (_GGSL("NULL or empty export_buffer parameter passed to function: %s"),
             __func__));
        goto exit;
    }

    if(desired_mech != NULL &&
       g_OID_equal(desired_mech, (gss_OID) gss_mech_globus_gssapi_openssl))
    {
        major_status = GSS_S_BAD_MECH;
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_MECH,
            (_GGSL("The desired mechanism of: %s, is not supported by this "
             "GSS implementation"), desired_mech->elements));
        goto exit;
    }

    if(option_req == GSS_IMPEXP_OPAQUE_FORM)
    {
        /* When option_req is equal to EXPORT_OPAQUE_FORM (0), it exports
         * an opaque buffer suitable for storage in memory or on  
         * disk or passing to another process, which 
         * can import the buffer with gss_import_cred().
         */
        bp = BIO_new(BIO_s_mem());
        if(bp == NULL)
        {
            GLOBUS_GSI_GSSAPI_OPENSSL_ERROR_RESULT(
                minor_status,
                GLOBUS_GSI_GSSAPI_ERROR_WITH_OPENSSL,
                (_GGSL("Couldn't initialize IO bio for exporting credential")));
            major_status = GSS_S_FAILURE;
            goto exit;
        }

	local_result = globus_gsi_cred_write(cred_desc->cred_handle, bp);
        if(local_result != GLOBUS_SUCCESS)
        {
            GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
                minor_status, local_result,
                GLOBUS_GSI_GSSAPI_ERROR_IMPEXP_BIO_SSL);
            major_status = GSS_S_FAILURE;
            goto exit;
        }            
		
        export_buffer->length = BIO_pending(bp);
		
        if (export_buffer->length > 0)
        {
            export_buffer->value = (char *) malloc(export_buffer->length);
            if (export_buffer->value == NULL)
            {
                export_buffer->length = 0;
                GLOBUS_GSI_GSSAPI_MALLOC_ERROR(minor_status);
                major_status = GSS_S_FAILURE;
                goto exit;
            }
			
            BIO_read(bp, export_buffer->value, export_buffer->length);
        }
        else
        {
            export_buffer->value = NULL;
        }

        major_status = GSS_S_COMPLETE;
    }
    else if(option_req == GSS_IMPEXP_MECH_SPECIFIC)
    {
        /* With option_req is equal to EXPORT_MECH_SPECIFIC (1), 
         * it exports a buffer filled with mechanism-specific 
         * information that the calling application can use 
         * to pass the credentials to another process that 
         * is not written to the GSS-API.
         */
        local_result = 
            GLOBUS_GSI_SYSCONFIG_GET_UNIQUE_PROXY_FILENAME(&proxy_filename);
        if(local_result != GLOBUS_SUCCESS)
        {
            proxy_filename = NULL;
            GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
                minor_status, local_result,
                GLOBUS_GSI_GSSAPI_ERROR_WITH_GSI_PROXY);
            major_status = GSS_S_FAILURE;
            goto exit;
        }

        GLOBUS_I_GSI_GSSAPI_DEBUG_FPRINTF(
            3, (globus_i_gsi_gssapi_debug_fstream,
                "Writing exported cred to: %s\n", proxy_filename));

        local_result = globus_gsi_cred_write_proxy(cred_desc->cred_handle,
                                                   proxy_filename);
        if(local_result != GLOBUS_SUCCESS)
        {
            GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
                minor_status, local_result,
                GLOBUS_GSI_GSSAPI_ERROR_WITH_GSI_PROXY);
            major_status = GSS_S_FAILURE;
            goto exit;
        }                                       

        export_buffer->value = globus_common_create_string(
            "X509_USER_PROXY=%s",
            proxy_filename);
        export_buffer->length = strlen(export_buffer->value)+1;
    }
    else
    {
        major_status = GSS_S_FAILURE;
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
            (_GGSL("Unrecognized option_req of: %d"), option_req));
        goto exit;
    }

 exit:

    if(proxy_filename != NULL)
    { 
        free(proxy_filename);
    }
    
    if (bp) 
    {
        BIO_free(bp);
    }

    GLOBUS_I_GSI_GSSAPI_DEBUG_EXIT;
    return major_status;
}
Exemplo n.º 22
0
/**
 * Calls the SSLeay error print routines to produce a printable
 * message. This may need some work, as the SSLeay error messages 
 * are more of a trace, and my not be the best for the user. 
 * Also don't take advantage of being called in a loop. 
 *
 * @param minor_status
 * @param status_value
 * @param status_type
 * @param mech_type
 * @param message_context
 * @param status_string
 *
 * @return
 */
OM_uint32 
GSS_CALLCONV gss_display_status(
    OM_uint32 *                         minor_status,
    OM_uint32                           status_value,
    int                                 status_type,
    const gss_OID                       mech_type,
    OM_uint32 *                         message_context,
    gss_buffer_t   	                status_string)
{
    globus_object_t *                   error_obj = NULL;
    char *                              error_chain_string = NULL;
    OM_uint32                           major_status = GSS_S_COMPLETE;
    char *                              reason;
    static char *                       _function_name_ =
        "gss_display_status";
    GLOBUS_I_GSI_GSSAPI_DEBUG_ENTER;

    status_string->length = 0;
    status_string->value = NULL;

    *minor_status = (OM_uint32) GLOBUS_SUCCESS;
 
    if (status_type == GSS_C_GSS_CODE)
    {
        if (!GSS_ERROR(status_value)) 
        {
            reason = "GSS COMPLETE";
        }
        else switch (GSS_ERROR(status_value)) 
        {
        
        case GSS_S_FAILURE:
            reason = "General failure";
            break;
        
        case GSS_S_DEFECTIVE_TOKEN:
            reason = "Communications Error";
            break;
        
        case GSS_S_DEFECTIVE_CREDENTIAL:
            reason = "Authentication Failed";
            break;
        
        case GSS_S_CREDENTIALS_EXPIRED:
            reason = "Credentials Expired";
            break;
        
        case GSS_S_BAD_NAME:
            reason = "Service or hostname could "
                "not be understood";
            break;
        
        case GSS_S_UNAUTHORIZED:
            reason = "Unexpected Gatekeeper or Service Name";
            break;
        
        case GSS_S_NO_CRED:
            reason = "Problem with local credentials";			
            break;
        
        case GSS_S_BAD_SIG:
            reason = "Invalid signature on message";
            break;
        
        default:
            reason = "Some Other GSS failure";
            break;
        } 

        status_string->value = globus_common_create_string(
            "GSS Major Status: %s\n",reason);

        status_string->length = strlen(status_string->value);
        major_status = GSS_S_COMPLETE;
        goto exit;
    }
    else if(status_type == GSS_C_MECH_CODE)
    {
        error_obj = globus_error_peek((globus_result_t) status_value);
        error_chain_string = globus_error_print_friendly(error_obj);

        status_string->value = globus_common_create_string(
            "GSS Minor Status Error Chain:\n%s",
            error_chain_string == NULL ? "(null)" : error_chain_string);
        
        globus_libc_free(error_chain_string);

        status_string->length = strlen(status_string->value);
        major_status = GSS_S_COMPLETE;
        goto exit;
    }
    else 
    {
        major_status = GSS_S_BAD_STATUS;
        goto exit;
    }

 exit:
    GLOBUS_I_GSI_GSSAPI_DEBUG_EXIT;
    return major_status;
}
/**
 * Add default values to RSL and verify required parameters
 *
 * Inserts default values to RSL when an RSL parameter is not defined
 * in it. After this is complete, it checks that all RSL parameters
 * with the "required_when" flag set are present in the RSL tree.
 *
 * @param request
 *        Request which contains the RSL tree to validate.
 * @param when
 *        Which RSL validation time scope we will use to decide
 *        whether to use the default values or not.
 */
static
int
globus_l_gram_job_manager_insert_default_rsl(
    globus_gram_jobmanager_request_t *  request,
    globus_rsl_t *                      rsl,
    globus_gram_job_manager_validation_when_t
                                        when)
{
    globus_rvf_record_t *               record;
    globus_list_t **                    attributes;
    globus_rsl_t *                      new_relation;
    char *                              new_relation_str;
    globus_list_t *                     validation_records;
    int                                 rc = GLOBUS_SUCCESS;

    attributes = globus_rsl_boolean_get_operand_list_ref(rsl);

    validation_records = request->manager->validation_records;

    while(!globus_list_empty(validation_records))
    {
        record = globus_list_first(validation_records);
        validation_records = globus_list_rest(validation_records);

        if(record->default_value && (record->default_when&when))
        {
            if(!globus_l_gram_job_manager_attribute_exists(
                        *attributes,
                        record->attribute))
            {
                new_relation_str = globus_common_create_string(
                        "%s = %s",
                        record->attribute,
                        record->default_value);

                globus_gram_job_manager_request_log(
                        request,
                        GLOBUS_GRAM_JOB_MANAGER_LOG_TRACE,
                        "event=gram.validate_rsl.info "
                        "level=TRACE "
                        "msg=\"Inserting default RSL for attribute\" "
                        "attribute=%s "
                        "default=\"%s\" "
                        "\n",
                        record->attribute,
                        record->default_value);

                new_relation = globus_rsl_parse(new_relation_str);

                globus_list_insert(attributes, new_relation);

                free(new_relation_str);
            }
        }
        if(record->required_when & when)
        {
            if(!globus_l_gram_job_manager_attribute_exists(
                        *attributes,
                        record->attribute))
            {
                rc = globus_l_gram_job_manager_missing_value_error(
                            record->attribute);

                globus_gram_job_manager_request_log(
                        request,
                        GLOBUS_GRAM_JOB_MANAGER_LOG_ERROR,
                        "event=gram.validate_rsl.end "
                        "level=ERROR "
                        "msg=\"RSL missing required attribute\" "
                        "attribute=%s "
                        "\n",
                        record->attribute);

                return rc;
            }
        }
    }
    return rc;
}
Exemplo n.º 24
0
int coInitConnect()
{
    const char *envStr;
    char env[256], *portStr;
    float timeout;
    int32 handshake;
    int port;

    coSimLibData.soc = -1;

#if !(defined(WIN32) || defined(WIN64))
    /* we do our own handling of broken pipes */
    signal(SIGPIPE, SIG_IGN);
#endif

    /* get environment: if variable not set, exit with error-code */
    envStr = getenv("CO_SIMLIB_CONN");
    fprintf(stdout, "SIMLIB: %s\n", envStr);
    if ((!envStr) || (strlen(envStr) > 255))
        return -1;

    /* Client connection */
    strcpy(env, envStr);
    if (*env == 'C')
    {
        size_t retval;
        isServer = 0;
        /* get adress and port */
        portStr = strchr(env, '/');
        if (!portStr)
        {
            fprintf(stderr, "error parsing environment variable [%s]\n", env);
            return -1;
        }
        *portStr = '\0';
        portStr++;
        retval = sscanf(portStr, "%d_%f_%d", &minPort, &timeout, &coSimLibData.verbose);
        if (retval != 3)
        {
            fprintf(stderr, "coInitConnect: sscanf failed\n");
            return -1;
        }
        if (minPort < 1024 || minPort > 32767)
            return -1;

#ifndef WIN32
        if (!inet_aton(env + 2, &ip))
            return -1;
#else
        ip.s_addr = inet_addr(env + 2);
        if (ip.s_addr == -1)
            return -1;
#endif
        if (coSimLibData.verbose > 0)
            fprintf(stderr, " Starting Client to %s Port %d with %f sec timeout\n",
                    inet_ntoa(ip), minPort, timeout);

        /* we try to connect now */
        if ((port = openClient(ip.s_addr, minPort, timeout)) < 0)
            return -1;
    }

    /* Server connection */
    else if (*env == 'S')
    {
        size_t retval;
        isServer = 1;
        /* get adress and port */
        portStr = strchr(env, ':');
        if (!portStr)
        {
            fprintf(stderr, "error parsing environment variable [%s]\n", env);
            return -1;
        }
        *portStr = '\0';
        portStr++;
        retval = sscanf(portStr, "%d-%d_%f_%d", &minPort, &maxPort, &timeout, &coSimLibData.verbose);
        if (retval != 4)
        {
            fprintf(stderr, "coInitConnect: sscanf failed\n");
            return -1;
        }

        if (minPort < 1024 || minPort > 32767 || maxPort < 1024 || maxPort > 32767)
            return -1;

        /* we open and wait for the other side to connect */
        if ((port = openServer(minPort, maxPort)) < 0)
        {
            fprintf(stderr, "could not open server\n");
            return -1;
        }

        if (acceptServer(timeout) < 0)
        {
            fprintf(stderr, "could not accept server\n");
            return -1;
        }
    }
    /* Neither Client nor Server = ERROR */
    else
        return -1;

    /* Handshake: send 12345 to other side, so they might determine byte-swapping */
    handshake = 12345;
    sendData(&handshake, sizeof(int32));

#ifdef HAVE_GLOBUS
    {
        globus_result_t result = GLOBUS_SUCCESS;
        xsd_any *fault;
        int err, fault_type;
        fprintf(stderr, "activate globus modules\n");
        globus_module_activate(GLOBUS_COMMON_MODULE);
        globus_module_activate(GLOBUS_SOAP_MESSAGE_MODULE);
        registerSimulationType regSimulation;
        registerSimulationResponseType *regResponse;
        registerSimulationResponseType_init(&regResponse);
        globus_soap_message_attr_init(&message_attr);
        globus_soap_message_attr_set(message_attr, GLOBUS_SOAP_MESSAGE_AUTHZ_METHOD_KEY,
                                     NULL, NULL,
                                     (void *)GLOBUS_SOAP_MESSAGE_AUTHZ_HOST);
        globus_soap_message_attr_set(message_attr, GLOBUS_SOAP_MESSAGE_AUTH_PROTECTION_KEY,
                                     NULL, NULL,
                                     (void *)GLOBUS_SOAP_MESSAGE_AUTH_PROTECTION_PRIVACY);
        if ((result = SimulationService_client_init(&client_handle, message_attr, NULL)) == GLOBUS_SUCCESS)
        {
            char hostname[128];
            struct passwd *user = getpwuid(getuid());

            gethostname(hostname, 127);
            fprintf(stderr, "globus simulation client initialized\n");

            regSimulation.user = user->pw_name;
            regSimulation.host = hostname;
            regSimulation.port = port;
            regSimulation.name = "Fenfloss";
            fprintf(stderr, "globus regSimulation: [%s] [%s] [%d] [%s]\n", regSimulation.user, regSimulation.host, regSimulation.port, regSimulation.name);
            wsa_EndpointReferenceType_init(&epr);
            wsa_AttributedURI_init_contents(&epr->Address);
            xsd_anyURI_init_contents_cstr(&epr->Address.base_value,
                                          globus_common_create_string(getenv("GLOBUS_SIMULATIONSERVICE")));
            fprintf(stderr, " [%s]\n", getenv("GLOBUS_SIMULATIONSERVICE"));
            if ((err = SimulationPortType_registerSimulation_epr(client_handle,
                                                                 epr,
                                                                 &regSimulation,
                                                                 &regResponse,
                                                                 (SimulationPortType_registerSimulation_fault_t *)&fault_type,
                                                                 &fault)) == GLOBUS_SUCCESS)
            {
                SimulationType r = regResponse->result;

                simulationID = r.id;
            }
            else
            {
                fprintf(stderr, "globus error %d: [%s] \n", err, globus_object_printable_to_string(globus_error_get(err)));
            }
        }
        else
        {
            fprintf(stderr, "globus error %d: [%s] \n", result, globus_object_printable_to_string(globus_error_get(result)));
        }
        registerSimulationResponseType_destroy(regResponse);
    }
#endif
    return 0;
}
static
int
globus_l_job_manager_module_activate(void)
{
    time_t                              timestamp_val;
    globus_l_job_manager_logfile_state_t *      
                                        logfile_state;
    int                                 rc;
    globus_reltime_t                    delay;
    globus_result_t                     result;
    char *                              scheduler;

    rc = globus_module_activate(GLOBUS_COMMON_MODULE);
    if (rc != GLOBUS_SUCCESS)
    {
        goto activate_common_failed;
    }
    rc = globus_mutex_init(&globus_l_job_manager_mutex, NULL);

    if (rc != GLOBUS_SUCCESS)
    {
        goto mutex_init_failed;
    }
    rc = globus_cond_init(&globus_l_job_manager_cond, NULL);
    if (rc != GLOBUS_SUCCESS)
    {
        goto cond_init_failed;
    }
    shutdown_called = GLOBUS_FALSE;
    callback_count = 0;

    GlobusDebugInit(
        SEG_JOB_MANAGER,
        SEG_JOB_MANAGER_DEBUG_INFO
        SEG_JOB_MANAGER_DEBUG_WARN
        SEG_JOB_MANAGER_DEBUG_ERROR
        SEG_JOB_MANAGER_DEBUG_TRACE);

    logfile_state = calloc(1, sizeof(globus_l_job_manager_logfile_state_t));
    if (logfile_state == NULL)
    {
        goto calloc_state_failed;
    }

    /* Configuration info */
    result = globus_scheduler_event_generator_get_timestamp(&timestamp_val);
    if (result != GLOBUS_SUCCESS)
    {
        goto get_timestamp_failed;
    }

    if (timestamp_val != 0)
    {
        if (globus_libc_gmtime_r(
                &timestamp_val,
                &logfile_state->start_timestamp) == NULL)
        {
            goto gmtime_failed;
        }
    }
    scheduler = globus_libc_getenv(JOB_MANAGER_SEG_SCHEDULER);
    if (scheduler == NULL)
    {
        SEG_JOB_MANAGER_DEBUG(SEG_JOB_MANAGER_DEBUG_ERROR,
            ("Error: %s not set\n", JOB_MANAGER_SEG_SCHEDULER));

        result = GLOBUS_FAILURE;
        goto get_scheduler_failed;
    }

    if (getenv(JOB_MANAGER_SEG_LOG_PATH))
    {
        logfile_state->log_dir = strdup(getenv(JOB_MANAGER_SEG_LOG_PATH));
    }
    else
    {
        char * log_dir_pattern = globus_common_create_string(
                "${localstatedir}/lib/globus/globus-seg-%s", scheduler);

        globus_eval_path(log_dir_pattern, &logfile_state->log_dir);
        free(log_dir_pattern);
    }

    if (logfile_state->log_dir == NULL)
    {
        SEG_JOB_MANAGER_DEBUG(SEG_JOB_MANAGER_DEBUG_ERROR,
            ("Error: out of memory\n"));
        goto get_path_failed;
    }

    /* Convert timestamp to filename */
    rc = globus_l_job_manager_find_logfile(logfile_state);

    if (rc == GLOBUS_SUCCESS)
    {
        logfile_state->fp = fopen(logfile_state->path, "r");

        if (logfile_state->fp == NULL)
        {
            rc = SEG_JOB_MANAGER_ERROR_OUT_OF_MEMORY;

            goto fopen_failed;
        }
        GlobusTimeReltimeSet(delay, 0, 0);
    }
    else if(rc == SEG_JOB_MANAGER_ERROR_LOG_NOT_PRESENT)
    {
        GlobusTimeReltimeSet(delay, 1, 0);
    }
    else
    {
        goto bad_log_path;
    }

    result = globus_callback_register_oneshot(
            &logfile_state->callback,
            &delay,
            globus_l_job_manager_poll_callback,
            logfile_state);
    if (result != GLOBUS_SUCCESS)
    {
        goto oneshot_failed;
    }
    callback_count++;

    return 0;
oneshot_failed:
    if (logfile_state->fp)
    {
        fclose(logfile_state->fp);
    }
fopen_failed:
    if (logfile_state->path)
    {
        free(logfile_state->path);
    }
bad_log_path:
    free(logfile_state->log_dir);
get_path_failed:
get_scheduler_failed:
get_timestamp_failed:
gmtime_failed:
    free(logfile_state);
calloc_state_failed:
    globus_cond_destroy(&globus_l_job_manager_cond);
cond_init_failed:
    globus_mutex_destroy(&globus_l_job_manager_mutex);
mutex_init_failed:
    globus_module_deactivate(GLOBUS_COMMON_MODULE);
activate_common_failed:
    return 1;
}
/**
 * Write the response to an HTTP request
 * @ingroup globus_i_xio_http_server
 *
 * Generates an HTTP response line from a handle, and passes it to the
 * transport. The globus_l_xio_http_server_write_response_callback() will
 * be called once the transport has sent the response.
 *
 * This call may be triggered by either the first write on a server handle,
 * or by calling the #GLOBUS_XIO_HTTP_HANDLE_SET_END_OF_ENTITY handle
 * control function.
 *
 * Called with my mutex lock.
 *
 * @param http_handle
 *     Handle associated with this HTTP stream.
 * @param iovec
 *     Array of globus_xio_iovec_t structs associated with the user's write.
 * @param iovec_count
 *     Length of the @a iovec array. If this is zero, we assume that the
 *     response is being generated by the
 *     #GLOBUS_XIO_HTTP_HANDLE_SET_END_OF_ENTITY control.
 * @param op
 *     Operation associated with the write. If this is NULL (in the case
 *     of the GLOBUS_XIO_HTTP_HANDLE_SET_END_OF_ENTITY control), one
 *     will be created in this function.
 *
 * This function returns GLOBUS_SUCCESS, GLOBUS_XIO_ERROR_MEMORY, or an
 * error result from globus_xio_driver_operation_create(), or
 * globus_xio_driver_pass_write().
 *
 * @retval GLOBUS_SUCCESS
 *     Response was passed to the transport for writing. If this was generated
 *     by a user writing data, then the write will occur after the 
 *     globus_l_xio_http_server_write_response_callback() has been called.
 * @retval GLOBUS_XIO_ERROR_MEMORY
 *     Unable to compose the response due to memory constraints.
 */
globus_result_t
globus_i_xio_http_server_write_response(
    globus_i_xio_http_handle_t *        http_handle,
    const globus_xio_iovec_t *          iovec,
    int                                 iovec_count,
    globus_xio_operation_t              op)
{
    globus_result_t                     result;
    globus_fifo_t                       iovecs;
    const char *                        str;
    char                                code_str[5];
    globus_xio_iovec_t *                iov;
    int                                 rc;
    int                                 i;
    int                                 send_size;
    char *                              size_buffer = NULL;
    globus_bool_t                       free_op = GLOBUS_FALSE;
    globus_xio_http_header_t *          current_header;
    GlobusXIOName(globus_i_xio_server_write_response);

    globus_assert(http_handle->send_state == GLOBUS_XIO_HTTP_STATUS_LINE);
    rc = globus_fifo_init(&iovecs);

    if (rc != GLOBUS_SUCCESS)
    {
        result = GlobusXIOErrorMemory("iovecs");

        goto error_exit;
    }

    /* Compose HTTP Response:
     * HTTP-Version SP Status-Code SP Reason-Phrase CRLF
     */
    if (http_handle->response_info.http_version == GLOBUS_XIO_HTTP_VERSION_1_0)
    {
        str = "HTTP/1.0 ";
    }
    else
    {
        http_handle->response_info.http_version = GLOBUS_XIO_HTTP_VERSION_1_1;
        str = "HTTP/1.1 ";
    }
    GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs, str, 9, free_iovecs_error);

    sprintf(code_str, "%d ", http_handle->response_info.status_code);
    GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs, code_str, 4, free_iovecs_error);

    if (http_handle->response_info.reason_phrase != NULL)
    {
        str = http_handle->response_info.reason_phrase;
    }
    else
    {
        str = globus_i_xio_http_lookup_reason(
                http_handle->response_info.status_code);
    }

    GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs, str, strlen(str), free_iovecs_error);
    GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs, "\r\n", 2, free_iovecs_error);

    current_header = globus_hashtable_first(
            &http_handle->response_info.headers.headers);

    while (current_header)
    {
        GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs,
                current_header->name,
                strlen(current_header->name),
                free_iovecs_error);

        GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs,
                ": ",
                2,
                free_iovecs_error);

        GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs,
                current_header->value,
                strlen(current_header->value),
                free_iovecs_error);

        GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs,
                "\r\n",
                2,
                free_iovecs_error);
        current_header = globus_hashtable_next(
                &http_handle->response_info.headers.headers);
    }

    /*
     * Special headers we generate.
     */
    if (GLOBUS_I_XIO_HTTP_HEADER_IS_CONNECTION_CLOSE(
                &http_handle->response_info.headers) ||
            (http_handle->request_info.http_version ==
                GLOBUS_XIO_HTTP_VERSION_1_0) ||
            (http_handle->response_info.headers.transfer_encoding
                == GLOBUS_XIO_HTTP_TRANSFER_ENCODING_IDENTITY &&
             GLOBUS_I_XIO_HTTP_HEADER_IS_CONTENT_LENGTH_SET(
                &http_handle->response_info.headers)))
    {
        http_handle->response_info.headers.flags |= 
                GLOBUS_I_XIO_HTTP_HEADER_CONNECTION_CLOSE;

        GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs,
                "Connection: close\r\n",
                19,
                free_iovecs_error);
    }
    if (iovec_count > 0)
    {
        /*
         * We are sending a body, so we'll set the appropriate entity-related
         * headers
         */
        if (http_handle->request_info.http_version
                == GLOBUS_XIO_HTTP_VERSION_1_0 ||
            (http_handle->response_info.headers.transfer_encoding
                == GLOBUS_XIO_HTTP_TRANSFER_ENCODING_IDENTITY &&
             GLOBUS_I_XIO_HTTP_HEADER_IS_CONTENT_LENGTH_SET(
                     &http_handle->response_info.headers)))
        {
            http_handle->response_info.headers.transfer_encoding
                = GLOBUS_XIO_HTTP_TRANSFER_ENCODING_IDENTITY;
            /* Transfer-Encoding mustn't be sent to a HTTP/1.0 client */
            if (http_handle->request_info.http_version
                != GLOBUS_XIO_HTTP_VERSION_1_0)
            {
                GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs,
                        "Transfer-Encoding: identity\r\n",
                        29,
                        free_iovecs_error);
            }
            /*
             * When we know the content-length beforehand we can set it here,
             * otherwise, we will use the connection: close header
             */
            if (GLOBUS_I_XIO_HTTP_HEADER_IS_CONTENT_LENGTH_SET(
                    &http_handle->response_info.headers))
            {
                GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs,
                        "Content-Length: ",
                        16,
                        free_iovecs_error);

                size_buffer = globus_common_create_string(
                        "%lu\r\n",
                        (unsigned long)
                            http_handle->response_info.headers.content_length);

                if (size_buffer == NULL)
                {
                    result = GlobusXIOErrorMemory("iovec.iov_base");

                    goto free_iovecs_error;
                }
                GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs,
                        size_buffer,
                        strlen(size_buffer),
                        free_iovecs_error);

                free(size_buffer);

                size_buffer = NULL;
            }
        }
        else
        {
            http_handle->response_info.headers.transfer_encoding
                = GLOBUS_XIO_HTTP_TRANSFER_ENCODING_CHUNKED;
            GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs,
                    "Transfer-Encoding: chunked\r\n",
                    28,
                    free_iovecs_error);
        }
    }
    GLOBUS_XIO_HTTP_COPY_BLOB(&iovecs, "\r\n", 2, free_iovecs_error);

    http_handle->header_iovcnt = globus_fifo_size(&iovecs);
    http_handle->header_iovec = globus_libc_malloc(
            http_handle->header_iovcnt * sizeof(globus_xio_iovec_t));
    if (http_handle->header_iovec == NULL)
    {
        goto free_iovecs_error;
    }

    /* Convert fifo to iovec array, counting up size for wait_for_nbytes
     * parameter to globus_xio_driver_pass_write.
     */
    for (i = 0, send_size = 0; i < http_handle->header_iovcnt; i++)
    {
        iov = globus_fifo_dequeue(&iovecs);

        globus_assert(iov != NULL);

        http_handle->header_iovec[i].iov_base = iov->iov_base;
        http_handle->header_iovec[i].iov_len = iov->iov_len;

        send_size += iov->iov_len;

        globus_libc_free(iov);
    }

    if (op == NULL)
    {
        result = globus_xio_driver_operation_create(
                &op,
                http_handle->handle);

        free_op = GLOBUS_TRUE;
        if (result != GLOBUS_SUCCESS)
        {
            goto free_headers_exit;
        }
    }

    /* Stash user buffer info until we've sent response headers */
    http_handle->write_operation.operation = op;
    http_handle->write_operation.iov = (globus_xio_iovec_t *) iovec;
    http_handle->write_operation.iovcnt = iovec_count;
    http_handle->write_operation.wait_for = 0;

    result = globus_xio_driver_pass_write(
            http_handle->write_operation.operation,
            http_handle->header_iovec,
            http_handle->header_iovcnt,
            send_size,
            globus_l_xio_http_server_write_response_callback,
            http_handle);
    if (result != GLOBUS_SUCCESS)
    {
        goto free_operation_exit;
    }
    globus_fifo_destroy(&iovecs);

    if (iovec_count == 0)
    {
        http_handle->send_state = GLOBUS_XIO_HTTP_EOF;
    }
    else if (http_handle->response_info.headers.transfer_encoding ==
            GLOBUS_XIO_HTTP_TRANSFER_ENCODING_CHUNKED)
    {
        http_handle->send_state = GLOBUS_XIO_HTTP_CHUNK_BODY;
    }
    else
    {
        http_handle->send_state = GLOBUS_XIO_HTTP_IDENTITY_BODY;
    }

    return GLOBUS_SUCCESS;

free_operation_exit:
    if (free_op)
    {
        globus_xio_driver_operation_destroy(
                http_handle->write_operation.operation);
    }
free_headers_exit:
    http_handle->write_operation.operation = NULL;
    http_handle->write_operation.driver_handle = NULL;
    http_handle->write_operation.iov = NULL;
    http_handle->write_operation.iovcnt = 0;
    http_handle->write_operation.wait_for = 0;

    for (i = 0; i < http_handle->header_iovcnt; i++)
    {
        globus_libc_free(http_handle->header_iovec[i].iov_base);
    }
    globus_libc_free(http_handle->header_iovec);

    http_handle->header_iovec = NULL;
    http_handle->header_iovcnt = 0;

free_iovecs_error:
    while (!globus_fifo_empty(&iovecs))
    {
        iov = globus_fifo_dequeue(&iovecs);

        globus_libc_free(iov->iov_base);
        globus_libc_free(iov);
    }
    globus_fifo_destroy(&iovecs);
    if (size_buffer != NULL)
    {
        free(size_buffer);
    }

error_exit:
    return result;
}
Exemplo n.º 27
0
static
void *
globus_l_dsi_rest_thread(
    void                               *arg)
{
    globus_l_dsi_rest_handle_t         *dsi_rest_handle = arg;
    globus_xio_data_descriptor_t        descriptor;
    size_t                              buf_size = 256;
    unsigned char                      *buf = malloc(buf_size);
    globus_size_t                       nbytes;
    char                               *encoded_uri;

    globus_mutex_lock(&dsi_rest_handle->mutex);
    while (!dsi_rest_handle->terminate)
    {
        char                       *method;
        char                       *uri;
        globus_xio_http_version_t   http_version;
        globus_hashtable_t          headers;
        globus_result_t             result;

        globus_mutex_unlock(&dsi_rest_handle->mutex);
        result = globus_xio_server_accept(
                &dsi_rest_handle->xio_handle,
                dsi_rest_handle->xio_server);
        globus_mutex_lock(&dsi_rest_handle->mutex);

        if (result != GLOBUS_SUCCESS)
        {
            continue;
        }
        result = globus_xio_open(
                dsi_rest_handle->xio_handle,
                NULL,
                NULL);
        if (result != GLOBUS_SUCCESS)
        {
            goto end_this_socket;
        }

        result = globus_xio_data_descriptor_init(&descriptor, dsi_rest_handle->xio_handle);
        if (result != GLOBUS_SUCCESS)
        {
            goto end_this_socket;
        }

        result = globus_xio_read(
                dsi_rest_handle->xio_handle,
                buf,
                0,
                0,
                &nbytes,
                descriptor);

        if (result != GLOBUS_SUCCESS)
        {
            goto end_this_socket;
        }

        result = globus_xio_data_descriptor_cntl(
                descriptor,
                dsi_rest_handle->http_driver,
                GLOBUS_XIO_HTTP_GET_REQUEST,
                &method,
                &uri,
                &http_version,
                &headers);

        globus_dsi_rest_uri_escape(uri, &encoded_uri);

        char *uripath = globus_common_create_string("%s/%s", dsi_rest_handle->root, encoded_uri);
        if (strcmp(method, "GET") == 0)
        {
            int fd;
            fd = open(uripath, O_RDONLY);
            if (fd < 0)
            {
                globus_xio_handle_cntl(
                        dsi_rest_handle->xio_handle,
                        dsi_rest_handle->http_driver,
                        GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_HEADER,
                        "Connection",
                        "Close");
                globus_xio_handle_cntl(
                        dsi_rest_handle->xio_handle,
                        dsi_rest_handle->http_driver,
                        GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_HEADER,
                        "Content-Length",
                        "0");
                globus_xio_handle_cntl(
                        dsi_rest_handle->xio_handle,
                        dsi_rest_handle->http_driver,
                        GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_STATUS_CODE,
                        404);
            }
            else
            {
                globus_size_t read_amt = 0;
                globus_xio_handle_cntl(
                        dsi_rest_handle->xio_handle,
                        dsi_rest_handle->http_driver,
                        GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_HEADER,
                        "Connection",
                        "Close");
                globus_xio_handle_cntl(
                        dsi_rest_handle->xio_handle,
                        dsi_rest_handle->http_driver,
                        GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_STATUS_CODE,
                        200);

                do
                {
                    read_amt = read(fd, buf, buf_size);
                    if (read_amt > 0)
                    {
                        globus_size_t written_amt = 0;

                        while (written_amt < read_amt)
                        {
                            globus_size_t this_write;

                            result = globus_xio_write(
                                dsi_rest_handle->xio_handle,
                                buf+written_amt,
                                read_amt-written_amt,
                                read_amt-written_amt,
                                &this_write,
                                NULL);
                            if (this_write > 0)
                            {
                                written_amt += this_write;
                            }
                            else if (result != GLOBUS_SUCCESS)
                            {
                                break;
                            }
                        }
                    }
                }
                while (read_amt > 0);
                close(fd);
            }
        }
        else
        {
            int fd = open(uripath, O_WRONLY|O_CREAT, 0700);

            if (fd < 0)
            {
                globus_xio_handle_cntl(
                        dsi_rest_handle->xio_handle,
                        dsi_rest_handle->http_driver,
                        GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_STATUS_CODE,
                        500);
                globus_xio_handle_cntl(
                        dsi_rest_handle->xio_handle,
                        dsi_rest_handle->http_driver,
                        GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_HEADER,
                        "Content-Length",
                        "0");
                globus_xio_handle_cntl(
                        dsi_rest_handle->xio_handle,
                        dsi_rest_handle->http_driver,
                        GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_HEADER,
                        "Connection",
                        "Close");
            }
            else
            {
                off_t total_written=0;

                if (nbytes > 0)
                {
                    globus_size_t written_amt = 0;

                    while (written_amt < nbytes)
                    {
                        globus_size_t this_write;

                        this_write = write(fd, buf+written_amt, nbytes-written_amt);
                        if (this_write > 0)
                        {
                            written_amt += this_write;
                            total_written += this_write;
                        }
                    }
                }
                do
                {

                    result = globus_xio_read(
                        dsi_rest_handle->xio_handle,
                        buf,
                        buf_size,
                        1,
                        &nbytes,
                        NULL);
                    if (nbytes > 0)
                    {
                        globus_size_t written_amt = 0;

                        while (written_amt < nbytes)
                        {
                            globus_size_t this_write;

                            this_write = write(fd, buf+written_amt, nbytes-written_amt);
                            if (this_write > 0)
                            {
                                written_amt += this_write;
                                total_written += this_write;
                            }
                        }
                    }
                    if (result != GLOBUS_SUCCESS)
                    {
                        if (globus_error_match(
                                globus_error_peek(result),
                                GLOBUS_XIO_MODULE,
                                GLOBUS_XIO_ERROR_EOF)
                            || globus_xio_driver_error_match(
                                    dsi_rest_handle->http_driver,
                                    globus_error_peek(result),
                                    GLOBUS_XIO_HTTP_ERROR_EOF))
                        {
                            result = GLOBUS_SUCCESS;
                            break;
                        }
                        else
                        {
                            globus_xio_handle_cntl(
                                    dsi_rest_handle->xio_handle,
                                    dsi_rest_handle->http_driver,
                                    GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_STATUS_CODE,
                                    500);
                            globus_xio_handle_cntl(
                                    dsi_rest_handle->xio_handle,
                                    dsi_rest_handle->http_driver,
                                    GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_HEADER,
                                    "Content-Length",
                                    "0");
                            globus_xio_handle_cntl(
                                    dsi_rest_handle->xio_handle,
                                    dsi_rest_handle->http_driver,
                                    GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_HEADER,
                                    "Connection",
                                    "Close");
                            goto xio_error;
                        }
                    }
                }
                while (nbytes > 0);
                close(fd);
                globus_xio_handle_cntl(
                        dsi_rest_handle->xio_handle,
                        dsi_rest_handle->http_driver,
                        GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_STATUS_CODE,
                        204);
                globus_xio_handle_cntl(
                        dsi_rest_handle->xio_handle,
                        dsi_rest_handle->http_driver,
                        GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_HEADER,
                        "Content-Length",
                        "0");
                globus_xio_handle_cntl(
                        dsi_rest_handle->xio_handle,
                        dsi_rest_handle->http_driver,
                        GLOBUS_XIO_HTTP_HANDLE_SET_RESPONSE_HEADER,
                        "Connection",
                        "Close");
            }
        }
xio_error:
        free(uripath);
        result = globus_xio_handle_cntl(
                dsi_rest_handle->xio_handle,
                dsi_rest_handle->http_driver,
                GLOBUS_XIO_HTTP_HANDLE_SET_END_OF_ENTITY);
end_this_socket:
        result = globus_xio_close(
                dsi_rest_handle->xio_handle,
                NULL);
        dsi_rest_handle->xio_handle = NULL;
    }
    dsi_rest_handle->terminate_complete = true;
    globus_cond_signal(&dsi_rest_handle->cond);
    globus_mutex_unlock(&dsi_rest_handle->mutex);

    return NULL;
}
Exemplo n.º 28
0
static
globus_result_t
globus_l_gfork_child_start(
    gfork_child_handle_t *              out_handle,
    const char *                        in_env_suffix,
    globus_gfork_open_func_t            open_cb,
    globus_gfork_closed_func_t          close_cb,
    globus_gfork_incoming_cb_t          incoming_cb,
    globus_gfork_error_func_t           error_cb,
    void *                              user_arg,
    globus_bool_t                       master)
{
    globus_result_t                     result;
    gfork_i_lib_handle_t *            handle;
    char *                              env;
    char *                              env_suffix;
    int                                 read_fd;
    int                                 write_fd;

    handle = (gfork_i_lib_handle_t *)
             globus_calloc(1, sizeof(gfork_i_lib_handle_t));

    handle->state = GFORK_STATE_OPEN;
    handle->open_cb = open_cb;
    handle->close_cb = close_cb;
    handle->error_cb = error_cb;
    handle->incoming_cb = incoming_cb;
    handle->user_arg = user_arg;
    handle->master = master;
    globus_mutex_init(&handle->mutex, NULL);
    globus_fifo_init(&handle->write_q);

    if(in_env_suffix == NULL)
    {
        env_suffix = "";
    }
    else
    {
        env_suffix = (char *) in_env_suffix;
    }
    env = globus_common_create_string("%s%s", GFORK_CHILD_READ_ENV, env_suffix);
    result = gfork_l_get_env_fd(env, &read_fd);

    globus_free(env);
    if(result != GLOBUS_SUCCESS)
    {
        goto error_read_env;
    }

    env = globus_common_create_string("%s%s",GFORK_CHILD_WRITE_ENV,env_suffix);
    result = gfork_l_get_env_fd(env, &write_fd);
    globus_free(env);
    if(result != GLOBUS_SUCCESS)
    {
        goto error_write_env;
    }

    result = gfork_i_make_xio_handle(&handle->read_xio, read_fd);
    if(result != GLOBUS_SUCCESS)
    {
        goto error_read_convert;
    }
    result = gfork_i_make_xio_handle(&handle->write_xio, write_fd);
    if(result != GLOBUS_SUCCESS)
    {
        goto error_write_convert;
    }

    globus_mutex_lock(&handle->mutex);
    {
        result = globus_xio_register_read(
                     handle->read_xio,
                     (globus_byte_t *)&handle->header,
                     sizeof(gfork_i_msg_header_t),
                     sizeof(gfork_i_msg_header_t),
                     NULL,
                     gfork_l_child_read_header_cb,
                     handle);
        if(result != GLOBUS_SUCCESS)
        {
            goto error_post;
        }
    }
    globus_mutex_unlock(&handle->mutex);

    *out_handle = handle;

    return GLOBUS_SUCCESS;

error_post:
    gfork_l_child_error(handle, result);
    globus_mutex_unlock(&handle->mutex);
error_write_convert:
    globus_xio_close(handle->read_xio, NULL);
error_read_convert:
error_write_env:
error_read_env:
    globus_fifo_destroy(&handle->write_q);
    globus_mutex_destroy(&handle->mutex);
    globus_free(handle);

    return result;
}
/**
 * @brief Parse log level specification
 * 
 * @details
 *     The globus_i_gram_parse_log_levels() function parses the log level string passed
 *     in its first argument to the mask pointed to by  the second argument.
 *     The log level string contains one or more level names combined by the
 *     "|" delimiter. The set of valid level names is:
 *     - FATAL
 *     - ERROR
 *     - WARN
 *     - INFO
 *     - DEBUG
 *     - TRACE
 *
 * @retval GLOBUS_SUCCESS
 *     Success
 * @retval GLOBUS_GRAM_PROTOCOL_ERROR_GATEKEEPER_MISCONFIGURED
 *     Server misconfigured
 */
int
globus_i_gram_parse_log_levels(
    const char *                        unparsed_string,
    int *                               log_levels,
    char **                             error_string)
{
    char *                  log_level_string = strdup(unparsed_string);
    char *                  level_string = NULL;
    char *                  last_string = NULL;
    int                     rc = GLOBUS_SUCCESS;

    if (log_level_string == NULL)
    {
        rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;

        goto error_exit;
    }
    if (error_string != NULL)
    {
        *error_string = NULL;
    }
    *log_levels = 0;

    for (level_string = strtok_r(log_level_string, "|", &last_string);
         level_string != NULL;
         level_string = strtok_r(NULL, "|", &last_string))
    {
        if (strcmp(level_string, "FATAL") == 0)
        {
            *log_levels |= GLOBUS_GRAM_JOB_MANAGER_LOG_FATAL;
        }
        else if (strcmp(level_string, "ERROR") == 0)
        {
            *log_levels |= GLOBUS_GRAM_JOB_MANAGER_LOG_ERROR;
        }
        else if (strcmp(level_string, "WARN") == 0)
        {
            *log_levels |= GLOBUS_GRAM_JOB_MANAGER_LOG_WARN;
        }
        else if (strcmp(level_string, "INFO") == 0)
        {
            *log_levels |= GLOBUS_GRAM_JOB_MANAGER_LOG_INFO;
        }
        else if (strcmp(level_string, "DEBUG") == 0)
        {
            *log_levels |= GLOBUS_GRAM_JOB_MANAGER_LOG_DEBUG;
        }
        else if (strcmp(level_string, "TRACE") == 0)
        {
            *log_levels |= GLOBUS_GRAM_JOB_MANAGER_LOG_TRACE;
        }
        else
        {
            globus_gram_job_manager_log(
                    NULL,
                    GLOBUS_GRAM_JOB_MANAGER_LOG_ERROR,
                    "event=gram.config.info "
                    "level=ERROR "
                    "status=-1 "
                    "msg=\"%s\" "
                    "string=\"%s\" "
                    "error_at=\"%s\" "
                    "\n",
                    "Error parsing log level string",
                    unparsed_string,
                    level_string);

            rc = GLOBUS_GRAM_PROTOCOL_ERROR_GATEKEEPER_MISCONFIGURED;

            if (error_string != NULL)
            {
                *error_string = globus_common_create_string(
                        "Error parsing log level string '%s' at '%s'\n",
                        unparsed_string,
                        level_string);
            }
            break;
        }
    }
    free(log_level_string);

error_exit:
    return rc;
}
int
main(
    int                                 argc,
    char **                             argv)
{
    int                                 rc = 0;
    globus_result_t                     result;
    char *                              cs;
    globus_xio_contact_t                parsed_contact;
    char *                              new_banner;
    char *                              old_banner;
    GlobusGFSName(main);

    /* activte globus stuff */    
    if((rc = globus_module_activate(GLOBUS_COMMON_MODULE)) != GLOBUS_SUCCESS ||
        (rc = globus_module_activate(
            GLOBUS_GRIDFTP_SERVER_MODULE)) != GLOBUS_SUCCESS)
    {
        fprintf(stderr,
            "Error: Failed to initialize:\n%s",
            globus_error_print_friendly(globus_error_peek(rc)));
        goto error_activate;
    }
        
    /* initialize global variables */
    globus_mutex_init(&globus_l_gfs_mutex, GLOBUS_NULL);
    globus_cond_init(&globus_l_gfs_cond, GLOBUS_NULL);
    globus_l_gfs_signal_init();

    globus_libc_printf("Embedded server starting.\n");

    globus_mutex_lock(&globus_l_gfs_mutex);
    {
        result = globus_gridftp_server_embed_init(
            &globus_l_gfs_server_handle,
            argv);
        if(result != GLOBUS_SUCCESS)
        {
            rc = 1;
            goto error_lock;
        }
                
        /* add our acl module */
        globus_gfs_acl_add_module(&globus_gfs_acl_test_module);

        /* customize some config */
        old_banner = globus_gridftp_server_embed_config_get_string(
            globus_l_gfs_server_handle, "banner");
        new_banner = globus_common_create_string(
            "%s\nEMBEDDED", old_banner);
        globus_gridftp_server_embed_config_set_ptr(
            globus_l_gfs_server_handle, 
            "banner", 
            new_banner);
        globus_free(old_banner);

        globus_gridftp_server_embed_config_set_int(
            globus_l_gfs_server_handle, 
            "connections_max", 
            10);

        globus_gridftp_server_embed_config_set_int(
            globus_l_gfs_server_handle, 
            "auth_level", 
            1 | /* identity check */
            2 | /* file access checks */
            4 | /* disable setuid (not really needed with gridmap disabled)*/
            8); /* disable gridmap lookup */
                
        result = globus_gridftp_server_embed_start(
            globus_l_gfs_server_handle,
            globus_l_gfs_event_cb,
            NULL);
        if(result != GLOBUS_SUCCESS)
        {
            rc = 1;
            goto error_lock;
        }
        globus_l_gfs_server_active = GLOBUS_TRUE;
        
        cs = globus_gridftp_server_embed_config_get_string(
            globus_l_gfs_server_handle, "contact_string");
            
        globus_xio_contact_parse(&parsed_contact, cs);
        
        globus_libc_printf(
            "Server listening on port %s.\n", parsed_contact.port);
        globus_xio_contact_destroy(&parsed_contact);
        
        /* run until we are done */ 
        while(!globus_l_gfs_terminated || globus_l_gfs_server_active)
        {
            globus_cond_wait(&globus_l_gfs_cond, &globus_l_gfs_mutex);
        }
    }
    globus_mutex_unlock(&globus_l_gfs_mutex);

    globus_module_deactivate_all();

    GlobusGFSDebugExit();
    return 0;

error_lock:
    globus_mutex_unlock(&globus_l_gfs_mutex);

error_activate:
    globus_module_deactivate_all();


    GlobusGFSDebugExitWithError();
    return rc;
}