int main(int argc, char *argv[]) { /* allocates the space for the "final" result code that is going to be returned as part of the normal command execution, a positive or negative values should idicate an error, a zero value indicates that a normal execution has just finished */ ERROR_CODE return_value; /* allocates space for the name of the program (process) to be executed */ char *program_name; /* allocates the map that will contain the various processed arguments, indexed by name */ struct hash_map_t *arguments; /* prints a debug message */ V_DEBUG_F("Receiving %d argument(s)\n", argc); /* in case the number of arguments is less than one (exception case) returns in error */ if(argc < 1) { cleanup(NULL); RAISE_ERROR_S(1); } /* retrieves the first argument value as the name of the process (program) to be executed */ program_name = argv[0]; /* processes the various arguments into a map and then executes the corresponding (initial) actions */ process_arguments(argc, argv, &arguments); return_value = execute_arguments(program_name, arguments); /* cleans the current process information so that no remaining structure or resource is left in an invalid or erroneous state */ cleanup(arguments); /* deletes the processed arguments and then cleans up the pool based memory allocation system releasing all of its memory before the exit (no leaks) */ delete_arguments(arguments); cleanup_palloc(); /* prints a debug message about the ending of the sytem for the execution of the service and then returns the normal return code (success status) to the caller process */ V_DEBUG_F( "Finishing process [%ld pending]\n", (long int) ALLOCATIONS ); RAISE_AGAIN(return_value); }
ERROR_CODE stop_module_diag(struct environment_t *environment, struct module_t *module) { /* retrieves the name, version and description of the current module loaded */ unsigned char *name = name_viriatum_mod_diag(); unsigned char *version = version_viriatum_mod_diag(); unsigned char *description = description_viriatum_mod_diag(); /* retrieves the (environment) service, that is going to be used for certain global operations */ struct service_t *service = environment->service; /* retrieves the mod diag module (from the module) and uses it to retrieve the create http handler */ struct mod_diag_module_t *mod_diag_module = (struct mod_diag_module_t *) module->lower; struct http_handler_t *http_handler = mod_diag_module->http_handler; /* prints a debug message about the unloading of the current module, for debugging purposes */ V_DEBUG_F("Stopping the module '%s' (%s) v%s\n", name, description, version); /* removes the http handler from the service, it can no longer be used to handle any request from this point on, then deletes both the http handler and the mod diag module (to avoid memory leaks) */ service->remove_http_handler(service, http_handler); if(http_handler != NULL) { service->delete_http_handler(service, http_handler); } delete_mod_diag_module(mod_diag_module); /* cleans up the pool based memory allocation system releasing all of its memory before the exit (no leaks) then returns the control flow to the caller function with success state */ cleanup_palloc(); RAISE_NO_ERROR; }
ERROR_CODE start_module_diag(struct environment_t *environment, struct module_t *module) { /* allocates the http handler pointer value to be used in the creation of the "new" http handler */ struct http_handler_t *http_handler; /* allocates the memory for the referece to mod gid module structure used to store the details about this module */ struct mod_diag_module_t *mod_diag_module; /* retrieves the name, version and description of the current module loaded, values to be displayed */ unsigned char *name = name_viriatum_mod_diag(); unsigned char *version = version_viriatum_mod_diag(); unsigned char *description = description_viriatum_mod_diag(); /* retrieves the (environment) service that is going to be used for certain creation operations */ struct service_t *service = environment->service; /* prints a debug message about the module that is currently being loaded */ V_DEBUG_F("Starting the module '%s' (%s) v%s\n", name, description, version); /* creates the mo diag module with the provided module reference and then initializes the new diag module with the currently defined state for it including definitions */ create_mod_diag_module(&mod_diag_module, module); info_module_diag(module); /* creates a new http handler for the diag module, this is the handler structure to be used in the request */ service->create_http_handler(service, &http_handler, (unsigned char *) "diag"); /* sets the http handler attributes */ http_handler->resolve_index = 0; http_handler->set = set_handler_diag; http_handler->unset = unset_handler_diag; http_handler->reset = NULL; /* sets the mod diag module attributes */ mod_diag_module->http_handler = http_handler; /* adds the http handler to the service, this operation should enable the handling of request using the (empty) diag based handler, in case they are correclty routed */ service->add_http_handler(service, http_handler); /* raises no error */ RAISE_NO_ERROR; }
ERROR_CODE write_http_error_a( struct connection_t *connection, char *buffer, size_t size, enum http_version_e version, int error_code, char *error_message, char *error_description, char *realm, enum http_keep_alive_e keep_alive, connection_data_callback_hu callback, void *callback_parameters ) { /* allocates space for the result buffer related variables (for both the buffer pointer and size) */ size_t result_length; unsigned char *result_buffer; /* allocates space for the references the string buffer and template handler structures */ struct string_buffer_t *string_buffer; struct template_handler_t *template_handler; /* allocates space for the "possible" locally generated error description (format based generation) */ char _error_description[1024]; /* allocates space to the path to the template file to be used for template generation */ unsigned char template_path[VIRIATUM_MAX_PATH_SIZE]; /* retrieves the service from the connection structure and then uses it to retrieve its options */ struct service_t *service = connection->service; struct service_options_t *options = service->options; /* allocates the headers buffer (it will be releases automatically by the writter) it need to be allocated in the heap so it gets throught the request cycle */ char *headers_buffer = buffer == NULL ? MALLOC(VIRIATUM_HTTP_SIZE) : buffer; size = size == 0 ? VIRIATUM_HTTP_SIZE : size; #ifndef VIRIATUM_DEBUG /* sets the error description as null in order to avoid any display of the (internal) message, otherwise a possible security hole would be created */ error_description = NULL; #endif /* in case the use template flag is set the error should be displayed using the template */ if(options->use_template) { /* creates the complete path to the template file */ SPRINTF( (char *) template_path, sizeof(template_path), "%s%s", VIRIATUM_RESOURCES_PATH, VIRIATUM_ERROR_PATH ); /* prints a debug message */ V_DEBUG_F("Processing template file '%s'\n", template_path); /* creates the template handler that will hold the error information contents */ create_template_handler(&template_handler); /* assigns the various error related variables into the template handler to be used, they may be used to display information arround the error, note that the error description value is conditional and may not be set */ assign_integer_template_handler(template_handler, (unsigned char *) "error_code", error_code); assign_string_template_handler(template_handler, (unsigned char *) "error_message", error_message); if(error_description != NULL) { assign_string_template_handler(template_handler, (unsigned char *) "error_description", error_description); } /* processes the file as a template handler, at this point the output buffer of the template engine should be populated with the complete header information, the apropriate header writing method is chosen based on the existence or not of the realm authorization field */ process_template_handler(template_handler, template_path); realm == NULL ? write_http_headers_c( connection, headers_buffer, size, version, error_code, error_message, keep_alive, strlen((char *) template_handler->string_value), NO_CACHE, TRUE ) : write_http_headers_a( connection, headers_buffer, size, version, error_code, error_message, keep_alive, strlen((char *) template_handler->string_value), NO_CACHE, realm, TRUE ); /* creates a new string buffer to hold the complete set of contents to be sent to the client then first writes the buffer containing the headers and then the resulting contents from the template handler */ create_string_buffer(&string_buffer); append_string_buffer(string_buffer, (unsigned char *) headers_buffer); append_string_buffer(string_buffer, template_handler->string_value); join_string_buffer(string_buffer, &result_buffer); result_length = string_buffer->string_length; delete_string_buffer(string_buffer); /* deletes the template handler as all the processing on it has been done (buffer generated) */ delete_template_handler(template_handler); /* releases the contents of the headers buffer, no more need to continue using them (not requried) */ FREE(headers_buffer); /* writes the resulting buffer into the connection in order to be sent to the client (sends the template results) in one chunk */ write_connection( connection, result_buffer, (unsigned int) result_length, (connection_data_callback) callback, callback_parameters ); } else { /* "stringfies" a possible null error description into a description string in order to be correctly displayed then formats the error message using the code, message and description */ error_description = error_description == NULL ? (char *) service->description : error_description; SPRINTF( _error_description, sizeof(_error_description), "%d - %s - %s", error_code, error_message, error_description ); /* writes the http static headers to the response and then writes the error description itself */ write_http_headers_m( connection, headers_buffer, size, version, error_code, error_message, keep_alive, strlen(_error_description), NO_CACHE, _error_description ); /* writes both the headers to the connection, an then registers for the appropriate callbacks */ write_connection( connection, (unsigned char *) headers_buffer, (unsigned int) strlen(headers_buffer), (connection_data_callback) callback, callback_parameters ); } /* raises no error */ RAISE_NO_ERROR; }