extern int file_to_mod_time(char const * rawname, bn_long * modtime) { char const * filename; unsigned int len; if (!rawname) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL rawname"); return -1; } if (!modtime) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL modtime"); return -1; } if (!(filename = file_get_info(rawname, &len, modtime))) return -1; xfree((void *)filename); /* avoid warning */ return 0; }
int main(int argc, char **argv) { int fd_source = 0; int fd_target = 0; int count = 1024000; /* 1M */ float progress; long bytes, written=0; off_t *file_offset = 0; struct file_info *f_source; struct file_info *f_target; if (argc < 3) { print_err("Usage: fiw source.img /dev/target_device"); } f_source = file_get_info(argv[1]); f_target = file_get_info(argv[2]); if (!f_source) { print_err("Error: Invalid source"); } if (!f_target) { print_err("Error: Invalid target"); } /* Validate read access */ if (f_source->read_access == FALSE) { print_err("Error: I cannot read the source file"); } /* Check that source is a file */ if (f_source->is_file == FALSE) { print_err("Error: source is not a file"); } if (f_target->is_block == FALSE && f_target->is_char == FALSE) { print_err("Error: target must be a char or block device"); } if (f_target->write_access == FALSE) { print_err("Error: I cannot write to the target block device"); } fd_source = open(argv[1], O_RDONLY); if (fd_source == -1) { print_err("Error: open() failed on source image file"); } fd_target = open(argv[2], O_WRONLY | O_SYNC); if (fd_target == -1) { print_err("Error: open() failed on target block device"); } /* Job details */ printf("Fast Image Writer v0.1\n"); printf("+ Source file : %s\n", argv[1]); printf("+ Target device: %s\n\n", argv[2]); printf("** Progress **\n"); do { bytes = sendfile(fd_target, fd_source, file_offset, count); if (bytes > 0) { written += bytes; progress = ((written * 100.00) / f_source->size); printf("\r%2.2f%% (%li/%li bytes)", progress, written, f_source->size); fflush(stdout); } } while (bytes > 0); if (bytes < 0) { perror("sendfile"); } close(fd_source); close(fd_target); printf("\n"); return 0; }
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; }
/* Send a file. If the file doesn't exist we still need to respond * to the file request. This will set filelen to 0 and send the server * reply message and the client will be happy and not hang. */ extern int file_send(t_connection * c, char const * rawname, unsigned int adid, unsigned int etag, unsigned int startoffset, int need_header) { char const * filename; t_packet * rpacket; std::FILE * fp; unsigned int filelen; int nbytes; if (!c) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection"); return -1; } if (!rawname) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL rawname"); return -1; } if (!(rpacket = packet_create(packet_class_file))) { eventlog(eventlog_level_error,__FUNCTION__,"could not create file packet"); return -1; } packet_set_size(rpacket,sizeof(t_server_file_reply)); packet_set_type(rpacket,SERVER_FILE_REPLY); if ((filename = file_get_info(rawname,&filelen,&rpacket->u.server_file_reply.timestamp))) { if (!(fp = std::fopen(filename,"rb"))) { /* FIXME: check for lower-case version of filename */ eventlog(eventlog_level_error,__FUNCTION__, "stat() succeeded yet could not open file \"%s\" for reading (std::fopen: %s)", filename, std::strerror(errno)); filelen = 0; } xfree((void *)filename); /* avoid warning */ } else { fp = NULL; filelen = 0; bn_long_set_a_b(&rpacket->u.server_file_reply.timestamp,0,0); } if (fp) { if (startoffset<filelen) { std::fseek(fp,startoffset,SEEK_SET); } else { eventlog(eventlog_level_warn,__FUNCTION__,"[%d] startoffset is beyond end of file (%u>%u)",conn_get_socket(c),startoffset,filelen); /* Keep the real filesize. Battle.net does it the same way ... */ std::fclose(fp); fp = NULL; } } if (need_header) { /* send the header from the server with the rawname and length. */ bn_int_set(&rpacket->u.server_file_reply.filelen,filelen); bn_int_set(&rpacket->u.server_file_reply.adid,adid); bn_int_set(&rpacket->u.server_file_reply.extensiontag,etag); /* rpacket->u.server_file_reply.timestamp is set above */ packet_append_string(rpacket,rawname); conn_push_outqueue(c,rpacket); } packet_del_ref(rpacket); /* Now send the data. Since it may be longer than a packet; we use * the raw packet class. */ if (!fp) { eventlog(eventlog_level_warn,__FUNCTION__,"[%d] sending no data for file \"%s\"",conn_get_socket(c),rawname); return -1; } eventlog(eventlog_level_info,__FUNCTION__,"[%d] sending file \"%s\" of length %d",conn_get_socket(c),rawname,filelen); for (;;) { if (!(rpacket = packet_create(packet_class_raw))) { eventlog(eventlog_level_error,__FUNCTION__,"could not create raw packet"); if (std::fclose(fp)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not close file \"%s\" after reading (std::fclose: %s)",rawname,std::strerror(errno)); return -1; } if ((nbytes = std::fread(packet_get_raw_data_build(rpacket,0),1,MAX_PACKET_SIZE,fp))<(int)MAX_PACKET_SIZE) { if (nbytes>0) /* send out last portion */ { packet_set_size(rpacket,nbytes); conn_push_outqueue(c,rpacket); } packet_del_ref(rpacket); if (std::ferror(fp)) eventlog(eventlog_level_error,__FUNCTION__,"read failed before EOF on file \"%s\" (std::fread: %s)",rawname,std::strerror(errno)); break; } packet_set_size(rpacket,nbytes); conn_push_outqueue(c,rpacket); packet_del_ref(rpacket); } if (std::fclose(fp)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not close file \"%s\" after reading (std::fclose: %s)",rawname,std::strerror(errno)); return 0; }