Ejemplo n.º 1
0
void *get_results( gearman_job_st *job, void *context, size_t *result_size, gearman_return_t *ret_ptr ) {
    int wsize;
    char workload[GM_BUFFERSIZE];
    char *decrypted_data;

    /* contect is unused */
    context = context;

    /* set size of result */
    *result_size = 0;

    /* set result pointer to success */
    *ret_ptr = GEARMAN_SUCCESS;

    /* get the data */
    wsize = gearman_job_workload_size(job);
    strncpy(workload, (const char*)gearman_job_workload(job), wsize);
    workload[wsize] = '\x0';

    /* decrypt data */
    decrypted_data   = malloc(GM_BUFFERSIZE);
    mod_gm_decrypt(&decrypted_data, workload, mod_gm_opt->transportmode);

    if(decrypted_data == NULL) {
        *ret_ptr = GEARMAN_WORK_FAIL;
        return NULL;
    }

    like(decrypted_data, "host_name=host1", "output contains host_name");
    like(decrypted_data, "output=", "output contains output");

    if(last_result != NULL)
        free(last_result);
    last_result = decrypted_data;

    return NULL;
}
Ejemplo n.º 2
0
/* create a task and send it */
int add_job_to_queue( gearman_client_st *client, char ** server_list, char * queue, char * uniq, char * data, int priority, int retries, int transport_mode, int send_now ) {
    gearman_task_st *task = NULL;
    gearman_return_t ret1, ret2;
    char * crypted_data;
    int size, free_uniq;
    struct timeval now;

    /* check too long queue names */
    if(strlen(queue) > 63) {
        gm_log( GM_LOG_ERROR, "queue name too long: '%s'\n", queue );
        return GM_ERROR;
    }

    /* cut off to long uniq ids */
    free_uniq = 0;
    if(uniq != NULL && strlen(uniq) > 63) {
        uniq = strndup(uniq, 63);
        free_uniq = 1;
    }

    signal(SIGPIPE, SIG_IGN);

    gm_log( GM_LOG_TRACE, "add_job_to_queue(%s, %s, %d, %d, %d, %d)\n", queue, uniq, priority, retries, transport_mode, send_now );
    gm_log( GM_LOG_TRACE, "%d --->%s<---\n", strlen(data), data );

    crypted_data = malloc(GM_BUFFERSIZE);
    size = mod_gm_encrypt(&crypted_data, data, transport_mode);
    gm_log( GM_LOG_TRACE, "%d +++>\n%s\n<+++\n", size, crypted_data );

#ifdef GM_DEBUG
    /* verify decrypted string is equal to the original */
    char * test;
    test = malloc(GM_BUFFERSIZE);
    mod_gm_decrypt(&test, crypted_data, transport_mode);
    gm_log( GM_LOG_TRACE, "%d ===>\n%s\n<===\n", size, test );
    if(strcmp(test, data)) {
        gm_log( GM_LOG_ERROR, "%d --->%s<---\n", strlen(data), data );
        gm_log( GM_LOG_ERROR, "%d ===>\n%s\n<===\n", size, test );
        fprintf(stderr, "encrypted string does not match\n");
        exit(EXIT_FAILURE);
    }
#endif

    if( priority == GM_JOB_PRIO_LOW ) {
        task = gearman_client_add_task_low_background( client, NULL, NULL, queue, uniq, ( void * )crypted_data, ( size_t )size, &ret1 );
        gearman_task_give_workload(task,crypted_data,size);
    }
    else if( priority == GM_JOB_PRIO_NORMAL ) {
        task = gearman_client_add_task_background( client, NULL, NULL, queue, uniq, ( void * )crypted_data, ( size_t )size, &ret1 );
        gearman_task_give_workload(task,crypted_data,size);
    }
    else if( priority == GM_JOB_PRIO_HIGH ) {
        task = gearman_client_add_task_high_background( client, NULL, NULL, queue, uniq, ( void * )crypted_data, ( size_t )size, &ret1 );
        gearman_task_give_workload(task,crypted_data,size);
    }
    else {
        gm_log( GM_LOG_ERROR, "add_job_to_queue() wrong priority: %d\n", priority );
    }

    if(send_now != TRUE)
        return GM_OK;

    ret2 = gearman_client_run_tasks( client );
    gearman_client_task_free_all( client );
    if(   ret1 != GEARMAN_SUCCESS
       || ret2 != GEARMAN_SUCCESS
       || task == NULL
       || ( gearman_client_error(client) != NULL && atof(gearman_version()) == 0.14 )
      ) {

        /* log the error */
        if(retries == 0) {
            gettimeofday(&now,NULL);
            /* only log the first error, otherwise we would fill the log very quickly */
            if( mod_gm_con_errors == 0 ) {
                gettimeofday(&mod_gm_error_time,NULL);
                gm_log( GM_LOG_ERROR, "sending job to gearmand failed: %s\n", gearman_client_error(client) );
            }
            /* or every minute to give an update */
            else if( now.tv_sec >= mod_gm_error_time.tv_sec + 60) {
                gettimeofday(&mod_gm_error_time,NULL);
                gm_log( GM_LOG_ERROR, "sending job to gearmand failed: %s (%i lost jobs so far)\n", gearman_client_error(client), mod_gm_con_errors );
            }
            mod_gm_con_errors++;
        }

        /* recreate client, otherwise gearman sigsegvs */
        gearman_client_free( client );
        create_client( server_list, client );

        /* retry as long as we have retries */
        if(retries > 0) {
            retries--;
            gm_log( GM_LOG_TRACE, "add_job_to_queue() retrying... %d\n", retries );
            return(add_job_to_queue( client, server_list, queue, uniq, data, priority, retries, transport_mode, send_now ));
        }
        /* no more retries... */
        else {
            gm_log( GM_LOG_TRACE, "add_job_to_queue() finished with errors: %d %d\n", ret1, ret2 );
            return GM_ERROR;
        }
    }

    /* reset error counter */
    mod_gm_con_errors = 0;

    if(free_uniq)
        free(uniq);

    gm_log( GM_LOG_TRACE, "add_job_to_queue() finished sucessfully: %d %d\n", ret1, ret2 );
    return GM_OK;
}
Ejemplo n.º 3
0
int main(void) {
    plan(60);

    /* lowercase */
    char test[100];
    ok(lc(NULL) == NULL, "lc(NULL)");
    strcpy(test, "Yes"); like(lc(test), "yes", "lc(yes)");
    strcpy(test, "YES"); like(lc(test), "yes", "lc(YES)");
    strcpy(test, "yeS"); like(lc(test), "yes", "lc(yeS)");


    /* trim */
    strcpy(test, "    text  "); like(ltrim(test), "text  ",   "ltrim()");
    strcpy(test, "    text  "); like(rtrim(test), "    text", "rtrim()");
    strcpy(test, "    text  "); like(trim(test),  "text",     "trim()");
    char *test2;
    test2 = strdup("   text   ");  like(trim(test2),  "text", "trim()");
    free(test2);

    /* parse_yes_or_no */
    ok(parse_yes_or_no(NULL,    GM_ENABLED)  == GM_ENABLED, "parse_yes_or_no 1");
    ok(parse_yes_or_no(NULL,    GM_DISABLED) == GM_DISABLED, "parse_yes_or_no 2");
    strcpy(test, "");      ok(parse_yes_or_no(test, GM_ENABLED)  == GM_ENABLED, "parse_yes_or_no 3");
    strcpy(test, "");      ok(parse_yes_or_no(test, GM_DISABLED) == GM_DISABLED, "parse_yes_or_no 4");
    strcpy(test, "yes");   ok(parse_yes_or_no(test, GM_ENABLED)  == GM_ENABLED, "parse_yes_or_no 5");
    strcpy(test, "true");  ok(parse_yes_or_no(test, GM_ENABLED)  == GM_ENABLED, "parse_yes_or_no 6");
    strcpy(test, "Yes");   ok(parse_yes_or_no(test, GM_ENABLED)  == GM_ENABLED, "parse_yes_or_no 7");
    strcpy(test, "1");     ok(parse_yes_or_no(test, GM_ENABLED)  == GM_ENABLED, "parse_yes_or_no 8");
    strcpy(test, "On");    ok(parse_yes_or_no(test, GM_ENABLED)  == GM_ENABLED, "parse_yes_or_no 9");
    strcpy(test, "Off");   ok(parse_yes_or_no(test, GM_ENABLED)  == GM_DISABLED, "parse_yes_or_no 10");
    strcpy(test, "false"); ok(parse_yes_or_no(test, GM_ENABLED)  == GM_DISABLED, "parse_yes_or_no 11");
    strcpy(test, "no");    ok(parse_yes_or_no(test, GM_ENABLED)  == GM_DISABLED, "parse_yes_or_no 12");
    strcpy(test, "0");     ok(parse_yes_or_no(test, GM_ENABLED)  == GM_DISABLED, "parse_yes_or_no 13");


    /* trim */
    ok(trim(NULL) == NULL, "trim(NULL)");
    strcpy(test, " test "); like(trim(test), "^test$", "trim(' test ')");
    strcpy(test, "\ntest\n"); like(trim(test), "^test$", "trim('\\ntest\\n')");

    /* reading keys */
    mod_gm_opt_t *mod_gm_opt;
    mod_gm_opt = malloc(sizeof(mod_gm_opt_t));
    int rc = set_default_options(mod_gm_opt);

    ok(rc == 0, "setting default options");
    mod_gm_opt->keyfile = strdup("t/data/test1.key");
    read_keyfile(mod_gm_opt);
    //printf_hex(mod_gm_opt->crypt_key, 32);
    test[0]='\x0';
    int i = 0;
    char hex[4];
    for(i=0; i<32; i++) {
        hex[0] = '\x0';
        snprintf(hex, 4, "%02x", mod_gm_opt->crypt_key[i]);
        strncat(test, hex, 4);
    }
    like(test, "3131313131313131313131313131313131313131313131313131313131310000", "read keyfile t/data/test1.key");

    free(mod_gm_opt->keyfile);
    mod_gm_opt->keyfile = strdup("t/data/test2.key");
    read_keyfile(mod_gm_opt);

    like(mod_gm_opt->crypt_key, "abcdef", "reading keyfile t/data/test2.key");

    free(mod_gm_opt->keyfile);
    mod_gm_opt->keyfile = strdup("t/data/test3.key");
    read_keyfile(mod_gm_opt);
    //printf_hex(mod_gm_opt->crypt_key, 32);
    like(mod_gm_opt->crypt_key, "11111111111111111111111111111111", "reading keyfile t/data/test3.key");
    ok(strlen(mod_gm_opt->crypt_key) == 32, "key size for t/data/test3.key");


    /* encrypt */
    char * key       = "test1234";
    char * encrypted = malloc(GM_BUFFERSIZE);
    char * text      = "test message";
    char * base      = "a7HqhQEE8TQBde9uknpPYQ==";
    mod_gm_crypt_init(key);
    int len;
    len = mod_gm_encrypt(&encrypted, text, GM_ENCODE_AND_ENCRYPT);
    ok(len == 24, "length of encrypted only");
    like(encrypted, base, "encrypted string");

    /* decrypt */
    char * decrypted = malloc(GM_BUFFERSIZE);
    mod_gm_decrypt(&decrypted, encrypted, GM_ENCODE_AND_ENCRYPT);
    like(decrypted, text, "decrypted text");
    free(decrypted);
    free(encrypted);

    /* base 64 */
    char * base64 = malloc(GM_BUFFERSIZE);
    len = mod_gm_encrypt(&base64, text, GM_ENCODE_ONLY);
    ok(len == 16, "length of encode only");
    like(base64, "dGVzdCBtZXNzYWdl", "base64 only string");

    /* debase 64 */
    char * debase64 = malloc(GM_BUFFERSIZE);
    mod_gm_decrypt(&debase64, base64, GM_ENCODE_ONLY);
    like(debase64, text, "debase64 text");
    free(debase64);
    free(base64);


    /* file_exists */
    ok(file_exists("01_utils") == 1, "file_exists('01_utils')");
    ok(file_exists("non-exist") == 0, "file_exists('non-exist')");

    /* nr2signal */
    char * signame1 = nr2signal(9);
    like(signame1, "SIGKILL", "get SIGKILL for 9");
    free(signame1);

    char * signame2 = nr2signal(15);
    like(signame2, "SIGTERM", "get SIGTERM for 15");
    free(signame2);


    /* string2timeval */
    struct timeval t;
    string2timeval("100.50", &t);
    ok(t.tv_sec  == 100, "string2timeval 1");
    ok(t.tv_usec == 50, "string2timeval 2");

    string2timeval("100", &t);
    ok(t.tv_sec  == 100, "string2timeval 3");
    ok(t.tv_usec == 0, "string2timeval 4");

    string2timeval("", &t);
    ok(t.tv_sec  == 0, "string2timeval 5");
    ok(t.tv_usec == 0, "string2timeval 6");

    string2timeval(NULL, &t);
    ok(t.tv_sec  == 0, "string2timeval 7");
    ok(t.tv_usec == 0, "string2timeval 8");

    /* command line parsing */
    mod_gm_free_opt(mod_gm_opt);
    mod_gm_opt = renew_opts();
    strcpy(test, "server=host:4730");
    parse_args_line(mod_gm_opt, test, 0);
    like(mod_gm_opt->server_list[0], "host:4730", "server=host:4730");
    ok(mod_gm_opt->server_num == 1, "server_number = %d", mod_gm_opt->server_num);

    mod_gm_free_opt(mod_gm_opt);
    mod_gm_opt = renew_opts();
    strcpy(test, "server=:4730");
    parse_args_line(mod_gm_opt, test, 0);
    like(mod_gm_opt->server_list[0], "localhost:4730", "server=:4730");
    ok(mod_gm_opt->server_num == 1, "server_number = %d", mod_gm_opt->server_num);

    mod_gm_free_opt(mod_gm_opt);
    mod_gm_opt = renew_opts();
    strcpy(test, "server=localhost:4730");
    parse_args_line(mod_gm_opt, test, 0);
    strcpy(test, "server=localhost:4730");
    parse_args_line(mod_gm_opt, test, 0);
    like(mod_gm_opt->server_list[0], "localhost:4730", "duplicate server");
    ok(mod_gm_opt->server_num == 1, "server_number = %d", mod_gm_opt->server_num);

    mod_gm_free_opt(mod_gm_opt);
    mod_gm_opt = renew_opts();
    strcpy(test, "server=localhost:4730,localhost:4730,:4730,host:4730,");
    parse_args_line(mod_gm_opt, test, 0);
    like(mod_gm_opt->server_list[0], "localhost:4730", "duplicate server");
    like(mod_gm_opt->server_list[1], "host:4730", "duplicate server");
    ok(mod_gm_opt->server_num == 2, "server_number = %d", mod_gm_opt->server_num);

    /* escape newlines */
    char * escaped = gm_escape_newlines(" test\n", GM_DISABLED);
    is(escaped, " test\\n", "untrimmed escape string");
    free(escaped);
    escaped = gm_escape_newlines(" test\n", GM_ENABLED);
    is(escaped, "test", "trimmed escape string");
    free(escaped);

    /* md5 sum */
    char * sum = NULL;
    strcpy(test, "");
    sum = md5sum(test);
    like(sum, "d41d8cd98f00b204e9800998ecf8427e", "md5sum()");
    free(sum);

    strcpy(test, "The quick brown fox jumps over the lazy dog.");
    sum = md5sum(test);
    like(sum, "e4d909c290d0fb1ca068ffaddf22cbd0", "md5sum()");
    free(sum);

    mod_gm_free_opt(mod_gm_opt);

    return exit_status();
}
Ejemplo n.º 4
0
/* get a job */
void *get_job( gearman_job_st *job, void *context, size_t *result_size, gearman_return_t *ret_ptr ) {
    sigset_t block_mask;
    int wsize, valid_lines;
    char workload[GM_BUFFERSIZE];
    char * decrypted_data;
    char * decrypted_data_c;
    char * decrypted_orig;
    char *ptr;

    /* reset timeout for now, will be set befor execution again */
    alarm(0);
    signal(SIGALRM, SIG_IGN);

    jobs_done++;

    /* send start signal to parent */
    set_state(GM_JOB_START);

    gm_log( GM_LOG_TRACE, "get_job()\n" );

    /* contect is unused */
    context = context;

    /* set size of result */
    *result_size = 0;

    /* reset sleep time */
    sleep_time_after_error = 1;

    /* ignore sigterms while running job */
    sigemptyset(&block_mask);
    sigaddset(&block_mask, SIGTERM);
    sigprocmask(SIG_BLOCK, &block_mask, NULL);

    /* get the data */
    current_gearman_job = job;
    wsize = gearman_job_workload_size(job);
    strncpy(workload, (const char*)gearman_job_workload(job), wsize);
    workload[wsize] = '\0';
    gm_log( GM_LOG_TRACE, "got new job %s\n", gearman_job_handle( job ) );
    gm_log( GM_LOG_TRACE, "%d +++>\n%s\n<+++\n", strlen(workload), workload );

    /* decrypt data */
    decrypted_data = malloc(GM_BUFFERSIZE);
    decrypted_data_c = decrypted_data;
    mod_gm_decrypt(&decrypted_data, workload, mod_gm_opt->transportmode);
    decrypted_orig = strdup(decrypted_data);

    if(decrypted_data == NULL) {
        *ret_ptr = GEARMAN_WORK_FAIL;
        free(decrypted_orig);
        return NULL;
    }
    gm_log( GM_LOG_TRACE, "%d --->\n%s\n<---\n", strlen(decrypted_data), decrypted_data );

    /* set result pointer to success */
    *ret_ptr= GEARMAN_SUCCESS;

    exec_job = ( gm_job_t * )malloc( sizeof *exec_job );
    set_default_job(exec_job, mod_gm_opt);

    valid_lines = 0;
    while ( (ptr = strsep(&decrypted_data, "\n" )) != NULL ) {
        char *key   = strsep( &ptr, "=" );
        char *value = strsep( &ptr, "\x0" );

        if ( key == NULL )
            continue;

        if ( value == NULL || !strcmp( value, "") )
            break;

        if ( !strcmp( key, "host_name" ) ) {
            exec_job->host_name = strdup(value);
            valid_lines++;
        } else if ( !strcmp( key, "service_description" ) ) {
            exec_job->service_description = strdup(value);
            valid_lines++;
        } else if ( !strcmp( key, "type" ) ) {
            exec_job->type = strdup(value);
            valid_lines++;
        } else if ( !strcmp( key, "result_queue" ) ) {
            exec_job->result_queue = strdup(value);
            valid_lines++;
        } else if ( !strcmp( key, "check_options" ) ) {
            exec_job->check_options = atoi(value);
            valid_lines++;
        } else if ( !strcmp( key, "scheduled_check" ) ) {
            exec_job->scheduled_check = atoi(value);
            valid_lines++;
        } else if ( !strcmp( key, "reschedule_check" ) ) {
            exec_job->reschedule_check = atoi(value);
            valid_lines++;
        } else if ( !strcmp( key, "latency" ) ) {
            exec_job->latency = atof(value);
            valid_lines++;
        } else if ( !strcmp( key, "next_check" ) ) {
            string2timeval(value, &exec_job->next_check);
            valid_lines++;
        } else if ( !strcmp( key, "start_time" ) ) {
            /* for compatibility reasons... (used by older mod-gearman neb modules) */
            string2timeval(value, &exec_job->next_check);
            string2timeval(value, &exec_job->core_time);
            valid_lines++;
        } else if ( !strcmp( key, "core_time" ) ) {
            string2timeval(value, &exec_job->core_time);
            valid_lines++;
        } else if ( !strcmp( key, "timeout" ) ) {
            exec_job->timeout = atoi(value);
            valid_lines++;
        } else if ( !strcmp( key, "command_line" ) ) {
            exec_job->command_line = strdup(value);
            valid_lines++;
        }
    }

#ifdef GM_DEBUG
    if(exec_job->next_check.tv_sec < 10000)
        write_debug_file(&decrypted_orig);
#endif

    if(valid_lines == 0) {
        gm_log( GM_LOG_ERROR, "discarded invalid job (%s), check your encryption settings\n", gearman_job_handle( job ) );
    } else {
        do_exec_job();
    }

    current_gearman_job = NULL;

    /* start listening to SIGTERMs */
    sigprocmask(SIG_UNBLOCK, &block_mask, NULL);

    free(decrypted_orig);
    free(decrypted_data_c);
    free_job(exec_job);

    /* send finish signal to parent */
    set_state(GM_JOB_END);

    if(mod_gm_opt->max_jobs > 0 && jobs_done >= mod_gm_opt->max_jobs) {
        gm_log( GM_LOG_TRACE, "jobs done: %i -> exiting...\n", jobs_done );
        clean_worker_exit(0);
        _exit( EXIT_SUCCESS );
    }

    return NULL;
}
Ejemplo n.º 5
0
/* put back the result into the core */
void *get_results( gearman_job_st *job, void *context, size_t *result_size, gearman_return_t *ret_ptr ) {
    int wsize;
    char workload[GM_BUFFERSIZE];
    char *decrypted_data;
    char *decrypted_data_c;
#ifdef GM_DEBUG
    char *decrypted_orig;
#endif
    struct timeval now, core_start_time;
    check_result * chk_result;
    int active_check = TRUE;
    char *ptr;
    double now_f, core_starttime_f, starttime_f, finishtime_f, exec_time, latency;

    /* for calculating real latency */
    gettimeofday(&now,NULL);

    /* contect is unused */
    context = context;

    /* set size of result */
    *result_size = 0;

    /* set result pointer to success */
    *ret_ptr = GEARMAN_SUCCESS;

    /* get the data */
    wsize = gearman_job_workload_size(job);
    strncpy(workload, (const char*)gearman_job_workload(job), wsize);
    workload[wsize] = '\x0';
    gm_log( GM_LOG_TRACE, "got result %s\n", gearman_job_handle( job ));
    gm_log( GM_LOG_TRACE, "%d +++>\n%s\n<+++\n", strlen(workload), workload );

    /* decrypt data */
    decrypted_data   = malloc(GM_BUFFERSIZE);
    decrypted_data_c = decrypted_data;
    mod_gm_decrypt(&decrypted_data, workload, mod_gm_opt->transportmode);

    if(decrypted_data == NULL) {
        *ret_ptr = GEARMAN_WORK_FAIL;
        return NULL;
    }
    gm_log( GM_LOG_TRACE, "%d --->\n%s\n<---\n", strlen(decrypted_data), decrypted_data );
#ifdef GM_DEBUG
    decrypted_orig   = strdup(decrypted_data);
#endif

    /*
     * save this result to a file, so when nagios crashes,
     * we have at least the crashed package
     */
    if(mod_gm_opt->debug_result == GM_ENABLED) {
        FILE * fd;
        fd = fopen( "/tmp/last_result_received.txt", "w+" );
        if(fd == NULL)
            perror("fopen");
        fputs( decrypted_data, fd );
        fclose( fd );
    }

    /* nagios will free it after processing */
    if ( ( chk_result = ( check_result * )malloc( sizeof *chk_result ) ) == 0 ) {
        *ret_ptr = GEARMAN_WORK_FAIL;
        return NULL;
    }
    init_check_result(chk_result);
    chk_result->scheduled_check     = TRUE;
    chk_result->reschedule_check    = TRUE;
    chk_result->output_file         = 0;
    chk_result->output_file_fd      = -1;

    core_start_time.tv_sec          = 0;
    core_start_time.tv_usec         = 0;

    while ( (ptr = strsep(&decrypted_data, "\n" )) != NULL ) {
        char *key   = strsep( &ptr, "=" );
        char *value = strsep( &ptr, "\x0" );

        if ( key == NULL )
            continue;

        if ( !strcmp( key, "output" ) ) {
            if ( value == NULL ) {
                chk_result->output = strdup("(null)");
            }
            else {
                chk_result->output = strdup( value );
            }
        }

        if ( value == NULL || !strcmp( value, "") )
            break;

        if ( !strcmp( key, "host_name" ) ) {
            chk_result->host_name = strdup( value );
        } else if ( !strcmp( key, "service_description" ) ) {
            chk_result->service_description = strdup( value );
        } else if ( !strcmp( key, "check_options" ) ) {
            chk_result->check_options = atoi( value );
        } else if ( !strcmp( key, "scheduled_check" ) ) {
            chk_result->scheduled_check = atoi( value );
        } else if ( !strcmp( key, "type" ) && !strcmp( value, "passive" ) ) {
            active_check=FALSE;
        } else if ( !strcmp( key, "reschedule_check" ) ) {
            chk_result->reschedule_check = atoi( value );
        } else if ( !strcmp( key, "exited_ok" ) ) {
            chk_result->exited_ok = atoi( value );
        } else if ( !strcmp( key, "early_timeout" ) ) {
            chk_result->early_timeout = atoi( value );
        } else if ( !strcmp( key, "return_code" ) ) {
            chk_result->return_code = atoi( value );
        } else if ( !strcmp( key, "core_start_time" ) ) {
            string2timeval(value, &core_start_time);
        } else if ( !strcmp( key, "start_time" ) ) {
            string2timeval(value, &chk_result->start_time);
        } else if ( !strcmp( key, "finish_time" ) ) {
            string2timeval(value, &chk_result->finish_time);
        } else if ( !strcmp( key, "latency" ) ) {
            chk_result->latency = atof( value );
        }
    }

    if ( chk_result->host_name == NULL || chk_result->output == NULL ) {
        *ret_ptr= GEARMAN_WORK_FAIL;
        gm_log( GM_LOG_ERROR, "discarded invalid result\n" );
        return NULL;
    }

    if ( chk_result->service_description != NULL ) {
        chk_result->object_check_type    = SERVICE_CHECK;
        chk_result->check_type           = SERVICE_CHECK_ACTIVE;
        if(active_check == FALSE )
            chk_result->check_type       = SERVICE_CHECK_PASSIVE;
    } else {
        chk_result->object_check_type    = HOST_CHECK;
        chk_result->check_type           = HOST_CHECK_ACTIVE;
        if(active_check == FALSE )
            chk_result->check_type       = HOST_CHECK_PASSIVE;
    }

    /* fill some maybe missing options */
    if(chk_result->start_time.tv_sec  == 0) {
        chk_result->start_time.tv_sec = (unsigned long)time(NULL);
    }
    if(chk_result->finish_time.tv_sec  == 0) {
        chk_result->finish_time.tv_sec = (unsigned long)time(NULL);
    }
    if(core_start_time.tv_sec  == 0) {
        core_start_time.tv_sec = (unsigned long)time(NULL);
    }

    /* calculate real latency */
    now_f            = (double)now.tv_sec + (double)now.tv_usec / 1000000;
    core_starttime_f = (double)core_start_time.tv_sec + (double)core_start_time.tv_usec / 1000000;
    starttime_f      = (double)chk_result->start_time.tv_sec + (double)chk_result->start_time.tv_usec / 1000000;
    finishtime_f     = (double)chk_result->finish_time.tv_sec + (double)chk_result->finish_time.tv_usec / 1000000;
    exec_time        = finishtime_f - starttime_f;
    latency          = now_f - exec_time - core_starttime_f;

    if(latency < 0)
        latency = 0;
    if(chk_result->latency < 0)
        chk_result->latency = 0;

    chk_result->latency += latency;

#ifdef GM_DEBUG
    if(chk_result->latency > 1000)
        write_debug_file(&decrypted_orig);
#endif

    /* this check is not a freshnes check */
    chk_result->check_options    = chk_result->check_options & ! CHECK_OPTION_FRESHNESS_CHECK;

    if ( chk_result->service_description != NULL ) {
#ifdef GM_DEBUG
        /* does this services exist */
        service * svc = find_service( chk_result->host_name, chk_result->service_description );
        if(svc == NULL) {
            write_debug_file(&decrypted_orig);
            gm_log( GM_LOG_ERROR, "service '%s' on host '%s' could not be found\n", chk_result->service_description, chk_result->host_name );
            return NULL;
        }
#endif
        gm_log( GM_LOG_DEBUG, "service job completed: %s %s: %d\n", chk_result->host_name, chk_result->service_description, chk_result->return_code );
    } else {
#ifdef GM_DEBUG
        /* does this host exist */
        host * hst = find_host( chk_result->host_name );
        if(hst == NULL) {
            write_debug_file(&decrypted_orig);
            gm_log( GM_LOG_ERROR, "host '%s' could not be found\n", chk_result->host_name );
            return NULL;
        }
#endif
        gm_log( GM_LOG_DEBUG, "host job completed: %s: %d\n", chk_result->host_name, chk_result->return_code );
    }

    /* add result to result list */
    mod_gm_add_result_to_list( chk_result );

    /* reset pointer */
    chk_result = NULL;

    free(decrypted_data_c);
#ifdef GM_DEBUG
    free(decrypted_orig);
#endif

    return NULL;
}