int main (void) { ipc_structure_type ipc_structure; mailbox_id_type mailbox_id[10]; unsigned int services = 10; system_process_name_set (PACKAGE_NAME); system_thread_name_set ("Initialising"); if (log_init (&log_structure, PACKAGE_NAME, &empty_tag) != LOG_RETURN_SUCCESS) { return -1; } /* Create our service. */ if (ipc_service_create ("file_system", &ipc_structure, &empty_tag) != STORM_RETURN_SUCCESS) { log_print (&log_structure, LOG_URGENCY_EMERGENCY, "Couldn't create a file system service."); return -1; } system_call_process_parent_unblock (); if (ipc_service_resolve ("virtual_file_system", mailbox_id, &services, 0, &empty_tag) != IPC_RETURN_SUCCESS) { log_print (&log_structure, LOG_URGENCY_EMERGENCY, "Couldn't resolve VFS service."); return -1; } ipc_structure.output_mailbox_id = mailbox_id[0]; ipc_service_connection_request (&ipc_structure); handle_connection (&ipc_structure); return 0; }
// Initialise the IPv4 support (by contacting the IPv4 server). return_type ipv4_init(ipc_structure_type *ipv4_structure, tag_type *tag) { mailbox_id_type mailbox_id[10]; unsigned int services = 10; // Try to resolve the IPv4 service. if (ipc_service_resolve("ipv4", mailbox_id, &services, 5, tag) != IPC_RETURN_SUCCESS) { return IPV4_RETURN_SERVICE_UNAVAILABLE; } ipv4_structure->output_mailbox_id = mailbox_id[0]; // Connect to this service. if (ipc_service_connection_request(ipv4_structure) != IPC_RETURN_SUCCESS) { return IPV4_RETURN_SERVICE_UNAVAILABLE; } return IPV4_RETURN_SUCCESS; }
void handle_connection(mailbox_id_type *reply_mailbox_id) { system_thread_name_set("Handling connection"); message_parameter_type message_parameter; bool done = FALSE; bool mounted = FALSE; fat_info_type fat_info; ipc_structure_type ipc_structure; uint8_t *data; uint8_t **data_pointer = &data; unsigned int data_size = 16384; memory_allocate((void **) data_pointer, data_size); // Accept the connection. ipc_structure.output_mailbox_id = *reply_mailbox_id; if (ipc_connection_establish(&ipc_structure) != IPC_RETURN_SUCCESS) { return; } message_parameter.block = TRUE; while (!done) { message_parameter.data = data; message_parameter.protocol = IPC_PROTOCOL_FILE; message_parameter.message_class = IPC_CLASS_NONE; message_parameter.length = data_size; if (ipc_receive(ipc_structure.input_mailbox_id, &message_parameter, &data_size) != IPC_RETURN_SUCCESS) { continue; } switch (message_parameter.message_class) { // Read one or more directory entries. case IPC_FILE_DIRECTORY_ENTRY_READ: { if (mounted) { file_directory_entry_read_type *directory_entry_read = (file_directory_entry_read_type *) data; if (!fat_directory_entry_read(directory_entry_read, &fat_info)) { directory_entry_read->entries = 0; } message_parameter.length = sizeof(file_directory_entry_read_type) + sizeof(file_directory_entry_type) * directory_entry_read->entries ; // log_print_formatted (0, PACKAGE, "Successfully read %u entries", // directory_entry_read->entries); // log_print_formatted (0, PACKAGE, "max: %u\n", directory_entry_read->entries); ipc_send(ipc_structure.output_mailbox_id, &message_parameter); } break; } case IPC_FILE_GET_INFO: { if (mounted) { file_verbose_directory_entry_type *directory_entry = (file_verbose_directory_entry_type *) data; if (!fat_file_get_info(&fat_info, directory_entry)) { return_type return_value = FILE_RETURN_FILE_ABSENT; log_print_formatted(&log_structure, LOG_URGENCY_ERROR, "IPC_FILE_GET_INFO failed"); message_parameter.message_class = IPC_FILE_RETURN_VALUE; message_parameter.data = &return_value; message_parameter.length = sizeof(return_type); } ipc_send(ipc_structure.output_mailbox_id, &message_parameter); } break; } case IPC_FILE_MOUNT_VOLUME: { mailbox_id_type *mailbox = (mailbox_id_type *) data; fat_info.block_structure.output_mailbox_id = *mailbox; if (ipc_service_connection_request(&fat_info.block_structure) != IPC_RETURN_SUCCESS) { break; } // Check if we have a FAT file system at this location. if (!detect_fat(&fat_info)) { log_print(&log_structure, LOG_URGENCY_ERROR, "No FAT filesystem detected."); break; } mounted = TRUE; break; } case IPC_FILE_OPEN: { ipc_file_open_type *open = (ipc_file_open_type *) data; if (!fat_file_open(&fat_info, open)) { log_print(&log_structure, LOG_URGENCY_ERROR, "Failed to open file."); } ipc_send(ipc_structure.output_mailbox_id, &message_parameter); break; } case IPC_FILE_READ: { file_read_type *read = (file_read_type *) data; uint8_t *read_buffer; uint8_t **read_buffer_pointer = &read_buffer; memory_allocate((void **) read_buffer_pointer, read->bytes); if (!fat_file_read(&fat_info, read->file_handle, read_buffer, read->bytes)) { log_print(&log_structure, LOG_URGENCY_ERROR, "Failed to read from file."); } message_parameter.data = read_buffer; message_parameter.length = read->bytes; #ifdef DEBUG log_print_formatted(&log_structure, LOG_URGENCY_DEBUG, "Sending %lu", read->bytes); #endif ipc_send(ipc_structure.output_mailbox_id, &message_parameter); memory_deallocate((void **) read_buffer_pointer); break; } // Unsupported functions. case IPC_FILE_CLOSE: case IPC_FILE_SEEK: case IPC_FILE_WRITE: case IPC_FILE_ACL_READ: case IPC_FILE_ACL_WRITE: case IPC_FILE_UNMOUNT_VOLUME: default: { return_type return_value = IPC_RETURN_FILE_FUNCTION_UNSUPPORTED; message_parameter.data = &return_value; message_parameter.length = sizeof(return_type); ipc_send(ipc_structure.output_mailbox_id, &message_parameter); break; } } } }
int main (void) { #if FALSE virtual_file_system_mount_type mount; mailbox_id_type mailbox_id[10]; ipc_structure_type vfs_structure; message_parameter_type message_parameter; file_read_type read; file_handle_type handle; file_verbose_directory_entry_type directory_entry; u8 *buffer; u8 *server_name_buffer; char *server[MAX_SERVERS]; unsigned int where, number_of_servers = 0, server_number; process_id_type process_id; unsigned int bytes_read; unsigned int services = 10; #endif /* Set our name. */ system_process_name_set (PACKAGE_NAME); system_thread_name_set ("Initialising"); if (log_init (&log_structure, PACKAGE_NAME, &empty_tag) != LOG_RETURN_SUCCESS) { return -1; } #if FALSE /* Mount the initial ramdisk as //ramdisk. To do this, we must first hook up a connection to the VFS service and resolve the first block service. */ if (ipc_service_resolve ("virtual_file_system", mailbox_id, &services, 5, &empty_tag) != IPC_RETURN_SUCCESS) { log_print (&log_structure, LOG_URGENCY_EMERGENCY, "Couldn't resolve the VFS service."); return -1; } vfs_structure.output_mailbox_id = mailbox_id[0]; if (ipc_service_connection_request (&vfs_structure) != IPC_RETURN_SUCCESS) { log_print (&log_structure, LOG_URGENCY_EMERGENCY, "Couldn't connect to the VFS service."); return -1; } services = 1; if (ipc_service_resolve ("block", mailbox_id, &services, 5, &empty_tag) != IPC_RETURN_SUCCESS) { log_print (&log_structure, LOG_URGENCY_EMERGENCY, "No block services found."); return -1; } mount.mailbox_id = mailbox_id[0]; string_copy (mount.location, "ramdisk"); /* That's it. Send the message. */ message_parameter.protocol = IPC_PROTOCOL_VIRTUAL_FILE_SYSTEM; message_parameter.message_class = IPC_VIRTUAL_FILE_SYSTEM_MOUNT; message_parameter.data = &mount; message_parameter.length = sizeof (virtual_file_system_mount_type); message_parameter.block = TRUE; ipc_send (vfs_structure.output_mailbox_id, &message_parameter); log_print (&log_structure, LOG_URGENCY_DEBUG, "Mounted the first available block service as //ramdisk."); /* Now, read the list of servers to start from here. */ log_print (&log_structure, LOG_URGENCY_DEBUG, "Reading startup script..."); string_copy (directory_entry.path_name, STARTUP_FILE); if (file_get_info (&vfs_structure, &directory_entry) != FILE_RETURN_SUCCESS) { log_print (&log_structure, LOG_URGENCY_ERROR, STARTUP_FILE " not found."); return -1; } memory_allocate ((void **) &server_name_buffer, directory_entry.size); file_open (&vfs_structure, STARTUP_FILE, FILE_MODE_READ, &handle); file_read (&vfs_structure, handle, directory_entry.size, &server_name_buffer); /* Parse the file. */ server[0] = &server_name_buffer[0]; number_of_servers++; for (where = 1; where < directory_entry.size; where++) { if (server_name_buffer[where] == '\n') { server_name_buffer[where] = '\0'; if (where + 1 < directory_entry.size) { server[number_of_servers] = &server_name_buffer[where + 1]; number_of_servers++; } } } log_print_formatted (&log_structure, LOG_URGENCY_DEBUG, "Starting %u servers.", number_of_servers); for (server_number = 0; server_number < number_of_servers; server_number++) { log_print_formatted (&log_structure, LOG_URGENCY_INFORMATIVE, "Starting %s.", server[server_number]); string_copy (directory_entry.path_name, server[server_number]); if (file_get_info (&vfs_structure, &directory_entry) != FILE_RETURN_SUCCESS) { log_print_formatted (&log_structure, LOG_URGENCY_ERROR, "'%s' could not be accessed!", server[server_number]); continue; } /* Open the file. */ file_open (&vfs_structure, server[server_number], FILE_MODE_READ, &handle); read.file_handle = handle; bytes_read = 0; log_print_formatted (&log_structure, LOG_URGENCY_DEBUG, "Allocating %lu bytes for %s.", directory_entry.size, server[server_number]); memory_allocate ((void **) &buffer, directory_entry.size); log_print_formatted (&log_structure, LOG_URGENCY_DEBUG, "Buffer is at %p.", buffer); while (bytes_read < directory_entry.size) { unsigned int bytes; /* Read the file. */ bytes = directory_entry.size - bytes_read; if (bytes > 32 * KB) { bytes = 32 * KB; } file_read (&vfs_structure, handle, bytes, &buffer[bytes_read]); bytes_read += bytes; } switch (execute_elf ((elf_header_type *) buffer, "", &process_id)) { case EXECUTE_ELF_RETURN_SUCCESS: { log_print_formatted (&log_structure, LOG_URGENCY_INFORMATIVE, "New process ID %lu.", process_id); break; } case EXECUTE_ELF_RETURN_IMAGE_INVALID: { log_print (&log_structure, LOG_URGENCY_ERROR, "Invalid ELF image."); break; } case EXECUTE_ELF_RETURN_ELF_UNSUPPORTED: { log_print (&log_structure, LOG_URGENCY_ERROR, "Unsupported ELF."); break; } case EXECUTE_ELF_RETURN_FAILED: { log_print (&log_structure, LOG_URGENCY_ERROR, "system_process_create failed."); break; } } memory_deallocate ((void **) &buffer); } #endif system_call_process_parent_unblock (); log_print (&log_structure, LOG_URGENCY_DEBUG, "surf"); return 0; }