Exemple #1
0
ERROR_CODE run_service_s(char *program_name, struct hash_map_t *arguments) {
    /* allocates space for the error value that will be used
    to check for an error in the call */
    ERROR_CODE return_value;

    /* initializes the service creating the structures and starting
    the values for the configuration of it */
    return_value = init_service(program_name, arguments);
    if(IS_ERROR_CODE(return_value)) {
        RAISE_AGAIN(return_value);
    }

    /* run the service, blocking the call until the service is
    finished, the retrives the return value from it */
    return_value = run_service();
    if(IS_ERROR_CODE(return_value)) {
        RAISE_AGAIN(return_value);
    }

    /* destroys the service eliminating any structures that have
    been created in the service life-time */
    return_value = destroy_service();
    if(IS_ERROR_CODE(return_value)) {
        RAISE_AGAIN(return_value);
    }

    /* raises no error as the execution of the service went normally
    and no problems have been issued */
    RAISE_NO_ERROR;
}
Exemple #2
0
ERROR_CODE ran_service() {
    /* allocates the return value */
    ERROR_CODE return_value;

    /* in case the service status is open */
    if(service->status == STATUS_CLOSED) {
        /* prints a debug message */
        V_DEBUG("No service to be stopped\n");
    } else {
        /* prints a debug message */
        V_DEBUG("Stopping service\n");

        /* stops the service, this call should make the
        required changes in the service structure so that
        it's stopped as soon as possible */
        return_value = stop_service(service);

        /* tests the error code for error */
        if(IS_ERROR_CODE(return_value)) {
            /* runs the socket finish so that the proper cleanup
            operations are performed and then re-raises the error*/
            SOCKET_FINISH();
            RAISE_AGAIN(return_value);
        }

        /* prints a debug message */
        V_DEBUG("Finished stopping service\n");
    }

    /* raises no error */
    RAISE_NO_ERROR;
}
Exemple #3
0
ERROR_CODE run_service() {
    /* allocates the return value to be used to gather
    the error result from the service calls */
    ERROR_CODE return_value;

    /* allocates the socket data and then initializes
    the socket infrastructure (global structures) with it */
    SOCKET_DATA socket_data;
    SOCKET_INITIALIZE(&socket_data);

    /* starts the service, this call should be able to bootstrap
    all the required structures and initialize the main loop, this
    should block the control flow fduring the run of the service */
    return_value = start_service(service);

    /* tests the error code value for error and in case there's
    one runs the appropriate measures */
    if(IS_ERROR_CODE(return_value)) {
        /* runs the socket finish so that the proper cleanup
        operations are performed and then re-raises the error*/
        SOCKET_FINISH();
        RAISE_AGAIN(return_value);
    }

    /* runs the socket finish releasing any pending memory information
    regarding the socket infra-structure */
    SOCKET_FINISH();

    /* raises no error */
    RAISE_NO_ERROR;
}
Exemple #4
0
ERROR_CODE init_service(char *program_name, struct hash_map_t *arguments) {
    /* allocates the return value to be used to gather
    the error result from the service calls */
    ERROR_CODE return_value;

    /* creates the service and loads the options
    taking into account the arguments */
    create_service(
        &service,
        (unsigned char *) VIRIATUM_NAME,
        (unsigned char *) program_name
    );
    return_value = load_specifications(service);
    if(IS_ERROR_CODE(return_value)) {
        RAISE_AGAIN(return_value);
    }
    return_value = load_options_service(service, arguments);
    if(IS_ERROR_CODE(return_value)) {
        RAISE_AGAIN(return_value);
    }
    return_value = calculate_options_service(service);
    if(IS_ERROR_CODE(return_value)) {
        RAISE_AGAIN(return_value);
    }

    /* updates the registers signals handler so that the service
    may be able to register the handlers at the proper timing */
    service->register_signals = register_signals;

    /* calculates the locations structure for the service based
    on the currently loaded configuration, this a complex operation */
    calculate_locations_service(service);

    /* runs the printing operation on the service, this should
    output the information to the standar output */
    print_options_service(service);

    /* raises no error to the caller method, normal
    exit operation (should provide no problem) */
    RAISE_NO_ERROR;
}
Exemple #5
0
ERROR_CODE decode_bencoding_file(char *file_path, struct type_t **type_pointer) {
    /* allocates space for the general (temporary) variables
    to be used durring the parsing of the file */
    ERROR_CODE return_value;
    size_t file_size;
    unsigned char *file_buffer;
    struct bencoding_engine_t *bencoding_engine;
    struct bencoding_handler_t *bencoding_handler;

    /* reads the file contained in the provided file path
    and then tests the error code for error, in case there is an
    error prints it to the error stream output */
    return_value = read_file(file_path, &file_buffer, &file_size);
    if(IS_ERROR_CODE(return_value)) {
        RAISE_ERROR_F(
            RUNTIME_EXCEPTION_ERROR_CODE,
            (unsigned char *) "Problem reading file %s",
            file_path
        );
    }

    /* starts the bencoding engine, starting all of its internal
    structures and then runs an engine tick parsing the complete
    file buffer (it's completely available) */
    _start_bencoding_engine(&bencoding_engine);
    _run_bencoding_engine(bencoding_engine, file_buffer, file_size);

    /* retieves the handler associated with the engine and then
    uses it to retrieve the top type of the parsed structure */
    bencoding_handler = (struct bencoding_handler_t *) bencoding_engine->context;
    *type_pointer = bencoding_handler->top;

    /* stops the bencoding engine releasing all of its internal
    structures, the top type is still defined */
    _stop_bencoding_engine(bencoding_engine);

    /* releases the buffer used durring the parsing of
    the configuration file */
    FREE(file_buffer);

    /* raises no error */
    RAISE_NO_ERROR;
}
Exemple #6
0
int execute_arguments(char *program_name, struct hash_map_t *arguments) {
    /* allocates space for the possible argument
    to be executed from the arguments map */
    void *value;

    /* allocates the value to be used to verify the
    exitence of error from the function */
    ERROR_CODE return_value;

    /* sets space for the flag that will control if
    the service should be run or not, this is used
    for certain situations (mostyle test) where the
    service is not meant to be run */
    char run_service = TRUE;

    /* tries to retrieve the help argument from the arguments
    map in case the value exists prints the help value and then
    exits the current system */
    get_value_string_hash_map(arguments, (unsigned char *) "help", &value);
    if(value != NULL) {
        return help();
    }

    /* tries to retrieve the version argument from the arguments
    map in case the value exists prints the version value and then
    exits the current system */
    get_value_string_hash_map(arguments, (unsigned char *) "version", &value);
    if(value != NULL) {
        return version();
    }

    /* retrieves the test argument value from the arguments map
    and in case it's set starts the test process runing a series
    of test functions in sequence */
    get_value_string_hash_map(arguments, (unsigned char *) "test", &value);
    if(value != NULL) {
        return test();
    }

    /* retrieves the speed argument value from the arguments map
    and in case it's set starts the speed measuring and disables
    the runnig of the service */
    get_value_string_hash_map(arguments, (unsigned char *) "speed", &value);
    if(value != NULL) {
        return speed();
    }

    /* tries to retrieve the daemon argument from the
    arguments map in case the value is set daemonizes
    the current process so that it remains in background
    and returns to the caller process immediately, otherwise
    prints the viriatum information into the standard
    output "file", the label should be standard */
    get_value_string_hash_map(arguments, (unsigned char *) "daemon", &value);
    if(value != NULL) {
        daemonize();
    }
    else {
        print_information();
    }

    /* tries to retrieve the local argument from the arguments
    map in case the value exists localizes the current service
    so that any file read is read from the current directory */
    get_value_string_hash_map(arguments, (unsigned char *) "local", &value);
    if(value != NULL) {
        localize();
    }

    /* in cas the flag that control if the service must be run is
    unset the control flow must be returned immediately (avoids
    running service) */
    if(run_service == FALSE) {
        RAISE_NO_ERROR;
    }

    /* runs the service, with the given arguments, this call
    should block the program control flow until an event
    stop the running of the main loop */
    return_value = run_service_s(program_name, arguments);

    /* tests the error code for error in case it exists
    prints a message indicating the problem that occurred */
    if(IS_ERROR_CODE(return_value)) {
        V_ERROR_F("Problem running service (%s)\n", (char *) GET_ERROR());
        RAISE_AGAIN(return_value);
    }

    /* returns the normal result value as no problems has
    occured during the execution of the command */
    RAISE_NO_ERROR;
}
Exemple #7
0
lxdream_file_type_t file_load_magic( const gchar *filename, gboolean wrap_exec, ERROR *err )
{
    gboolean result;
    /* Try disc types first */
    cdrom_disc_t disc = cdrom_disc_open( filename, err );
    if( disc != NULL ) {
        gdrom_mount_disc(disc);
        return FILE_DISC;
    } else if( !IS_ERROR_CODE(err,LX_ERR_FILE_UNKNOWN) ) {
        return FILE_ERROR;
    }

    int fd = open( filename, O_RDONLY );
    if( fd == -1 ) {
        SET_ERROR( err, LX_ERR_FILE_NOOPEN, "Unable to open file '%s' (%s)" ,filename, strerror(errno) );
        return FILE_ERROR;
    }

    lxdream_file_type_t type = file_identify(filename, fd, err);
    switch( type ) {
    case FILE_ERROR:
        result = FALSE;
        break;
    case FILE_ELF:
        if( wrap_exec ) {
            disc = cdrom_wrap_elf( CDROM_DISC_XA, filename, fd, err );
            result = disc != NULL;
            if( disc != NULL ) {
                gdrom_mount_disc(disc);
            }
        } else {
            result = file_load_elf( filename, fd, err );
        }
        break;
    case FILE_BINARY:
        if( wrap_exec ) {
            disc = cdrom_wrap_binary( CDROM_DISC_XA, filename, fd, err );
            result = disc != NULL;
            if( disc != NULL ) {
                gdrom_mount_disc(disc);
            }
        } else {
            result = file_load_binary( filename, fd, err );
        }
        break;
    case FILE_SAVE_STATE:
        result = dreamcast_load_state( filename );
        break;
    case FILE_ZIP:
        SET_ERROR( err, LX_ERR_FILE_UNSUP, "ZIP/SBI not currently supported" );
        result = FALSE;
        break;
    case FILE_ISO:
        SET_ERROR( err, LX_ERR_FILE_UNSUP, "ISO files are not currently supported" );
        result = FALSE;
        break;
    default:
        SET_ERROR( err, LX_ERR_FILE_UNKNOWN, "File '%s' could not be recognized", filename );
        result = FALSE;
        break;
    }
    close(fd);
    if( result ) {
        CLEAR_ERROR(err);
        return type;
    }
    return FILE_ERROR;
}
Exemple #8
0
ERROR_CODE auth_file_http(char *auth_file, char *authorization, unsigned char *result) {
    /* allocates space for the error return value to be
    used in error checking for function calls */
    ERROR_CODE return_value;

    /* allocates space for the pointer to the passwd key
    value structure to be created by parsing the auth file */
    struct hash_map_t *passwd;

    /* allocates space to the various pointer values to be
    used for the separation and treatment of the auth value */
    char *pointer;
    char *authorization_b64;
    char *authorization_d;
    char *password_pointer;

    /* allocates space for the buffers to be used for the username
    and password values extracted from the authorization token */
    char username[128];
    char password[128];
    char *password_v;

    /* allocates the various size relates values for the buffer
    variables creation */
    size_t authorization_size;
    size_t username_size;
    size_t password_size;

    /* tries to find the token that separates the authentication
    type from the authorization base 64 value in case the value
    is not found raises an error indicating the problem */
    pointer = strchr(authorization, ' ');
    if(pointer == NULL) {
        RAISE_ERROR_M(
            RUNTIME_EXCEPTION_ERROR_CODE,
            (unsigned char *) "Authorization value not valid"
        );
    }
    authorization_b64 = pointer + 1;

    /* tries to decode the authorization base 64 value into a plain
    text value in case the decoding fails, re-raises the error to
    the upper levels for caller information */
    return_value = decode_base64(
        (unsigned char *) authorization_b64,
        strlen(authorization_b64),
        (unsigned char **) &authorization_d,
        &authorization_size
    );
    if(IS_ERROR_CODE(return_value)) {
        RAISE_ERROR_M(
            RUNTIME_EXCEPTION_ERROR_CODE,
            (unsigned char *) "Problem decoding base 64 authorization"
        );
    }

    /* tries to find the token that separates the username part of the
    authorization from the password part in case the value is not found
    raises an error to the upper levels */
    pointer = memchr(authorization_d, ':', authorization_size);
    if(pointer == NULL) {
        FREE(authorization_d);
        RAISE_ERROR_M(
            RUNTIME_EXCEPTION_ERROR_CODE,
            (unsigned char *) "No password separator found in authorization"
        );
    }
    password_pointer = pointer + 1;

    /* calculates the size of both the username and the password
    from the diference between the various pointers */
    username_size = password_pointer - authorization_d - 1;
    password_size = authorization_d + authorization_size - password_pointer;

    /* copies both the username and the password values to
    the apropriate internal buffers (to be used in comparision) */
    memcpy(username, authorization_d, username_size);
    username[username_size] = '\0';
    memcpy(password, password_pointer, password_size);
    password[password_size] = '\0';

    /* processes the passwd file using the provided file path
    for it, this is an expensive io driven operation, and must
    be used wth care */
    process_passwd_file(auth_file, &passwd);

    /* retrieves the password verification value for the
    retrieved username and in case it's valid compares it
    and sets the result value accordingly */
    get_value_string_hash_map(
        passwd,
        (unsigned char *) username,
        (void **) &password_v
    );
    if(password_v != NULL && strcmp(password, password_v) == 0) {
        *result = TRUE;
    } else { *result = FALSE; }

    /* releases the memory associated with the complete set
    of values in the passwd structure and then releases the
    memory from the hash map structure itself, then releases
    the memory associated with the authorization decoded string */
    delete_values_hash_map(passwd);
    delete_hash_map(passwd);
    FREE(authorization_d);

    /* raises no error, as everything has been done as possible
    with no problems created in the processing */
    RAISE_NO_ERROR;
}
Exemple #9
0
ERROR_CODE process_ini_file(char *file_path, struct sort_map_t **configuration_pointer) {
    /* allocates space for the general (temporary) variables
    to be used durring the parsing of the file */
    ERROR_CODE return_value;
    size_t index;
    size_t file_size;
    unsigned char *file_buffer;
    unsigned char character;
    enum ini_state_e state;

    /* allocates the mark variables used to locate
    the part of context changing durring the parsing */
    unsigned char *pointer = 0;
    unsigned char *section_end_mark = 0;
    unsigned char *comment_end_mark = 0;
    unsigned char *key_end_mark = 0;
    unsigned char *value_end_mark = 0;

    /* allocates space for the settings to be used by
    the engine for the engine instance itself and for
    the handler to be used to "catch" the events, then
    retrieves the pointers to these structures*/
    struct ini_settings_t ini_settings_s;
    struct ini_engine_t ini_engine_s;
    struct ini_handler_t ini_handler_s;
    struct ini_settings_t *ini_settings = &ini_settings_s;
    struct ini_engine_t *ini_engine = &ini_engine_s;
    struct ini_handler_t *ini_handler = &ini_handler_s;

    /* allocates space for the sort map to be used for
    the configuration to be created */
    struct sort_map_t *configuration;

    /* creates the sort map that will hold the various
    arguments, then updates the configuration pointer
    with the created configuration sort map */
    create_sort_map(&configuration, 0);
    *configuration_pointer = configuration;

    /* sets the various handlers for the ini settings
    parsing, they will be used to correctly update the
    provided configuration sort map */
    ini_settings_s.on_section_start = NULL;
    ini_settings_s.on_section_end = _ini_section_end_callback;
    ini_settings_s.on_comment_start = NULL;
    ini_settings_s.on_comment_end = _ini_comment_end_callback;
    ini_settings_s.on_key_start = NULL;
    ini_settings_s.on_key_end = _ini_key_end_callback;
    ini_settings_s.on_value_start = NULL;
    ini_settings_s.on_value_end = _ini_value_end_callback;

    /* sets the configuration reference in the ini handler
    so that it may be updatd and then sets the handler in
    the ini engine instance to be used for parsing */
    ini_handler_s.configuration = configuration;
    ini_engine_s.context = ini_handler;

    /* sets the flag that controls if the trailing space
    characters should be removesd from key and values */
    ini_handler_s.remove_spaces = 1;

    /* reads the file contained in the provided file path
    and then tests the error code for error, in case there is an
    error prints it to the error stream output */
    return_value = read_file(file_path, &file_buffer, &file_size);
    if(IS_ERROR_CODE(return_value)) {
        RAISE_ERROR_F(
            RUNTIME_EXCEPTION_ERROR_CODE,
            (unsigned char *) "Problem reading file %s",
            file_path
        );
    }

    /* sets the initial state for the parsing process this
    is considered to be the "general loop" state */
    state = INI_ENGINE_NORMAL;

    /* iterates over the byte range of the file, all the bytes
    should be contained in the buffer "under" iteration */
    for(index = 0; index < file_size; index++) {
        /* retrieves the current character from the
        file buffer and the retrieves the pointer to
        its position */
        character = file_buffer[index];
        pointer = &file_buffer[index];

        switch(state) {
            case INI_ENGINE_NORMAL:
                if(character == '[') {
                    state = INI_ENGINE_SECTION;

                    INI_MARK_N(section_end, -1);
                    INI_CALLBACK(section_start);
                } else if(character == ';') {
                    state = INI_ENGINE_COMMENT;

                    INI_MARK_N(comment_end, -1);
                    INI_CALLBACK(comment_start);
                } else if(character == '\n' || character == '\r') {
                    state = INI_ENGINE_NORMAL;
                } else {
                    state = INI_ENGINE_KEY;

                    INI_MARK(key_end);
                    INI_CALLBACK(key_start);
                }

                break;

            case INI_ENGINE_SECTION:
                if(character == ']') {
                    state = INI_ENGINE_NORMAL;

                    INI_CALLBACK_DATA(section_end);
                }

                break;

            case INI_ENGINE_COMMENT:
                if(character == '\n' || character == '\r') {
                    state = INI_ENGINE_NORMAL;

                    INI_CALLBACK_DATA(comment_end);
                }

                break;

            case INI_ENGINE_KEY:
                if(character == '=') {
                    state = INI_ENGINE_VALUE;

                    INI_MARK_N(value_end, -1);
                    INI_CALLBACK_DATA(key_end);
                    INI_CALLBACK(value_start);
                }

                break;

            case INI_ENGINE_VALUE:
                if(character == '\n' || character == '\r') {
                    state = INI_ENGINE_NORMAL;

                    INI_CALLBACK_DATA(value_end);
                }

                break;
        }
    }

    /* releases the buffer used durring the parsing of
    the configuration file (avoids leaks) */
    FREE(file_buffer);

    /* raises no error */
    RAISE_NO_ERROR;
}