ssize_t ext2_read_file_base(struct ext2_desc *desc, struct ext2_inode *inode, void *buff, size_t size) { int i; int block_count; size_t total_len; println("file size = %s", size2text(inode->size)); if (inode->size == 0) { return 0; } total_len = size > inode->size ? inode->size : size; block_count = cal_ext2_block_count(desc, inode); for (i = 0; i < block_count && size; i++) { off_t seek_value; ssize_t readlen; seek_value = block_index_to_offset(desc, inode->block[i]); seek_value = lseek(desc->fd, seek_value, SEEK_SET); if (seek_value < 0) { print_error("lseek"); return seek_value; } readlen = size > desc->block_size ? desc->block_size : size; readlen = read(desc->fd, buff, readlen); if (readlen < 0) { print_error("read"); return readlen; } buff = (char *) buff + readlen; } return total_len; }
int cftp_server_send_file(struct cftp_descriptor *desc, const char *filename, u32 offset, size_t size) { int fd; int ret; union cftp_message *msg; struct cftp_data_package *data_pkg; ssize_t recvlen, sendlen, readlen; u16 blk_num; struct progress_bar bar; size_t max_xfer_length, max_data_length; struct stat st; max_xfer_length = desc->max_xfer_length; max_data_length = max_xfer_length - sizeof(msg->data_pkg); msg = malloc(max_xfer_length); if (msg == NULL) { pr_err_info("malloc"); return -ENOMEM; } fd = open(filename, O_RDONLY); if (fd < 0) { pr_err_info("open file %s faild", filename); cftp_send_error_message(desc, (struct cftp_error_message *) msg, "open file %s faild", filename); ret = fd; goto out_free_msg; } ret = fstat(fd, &st); if (ret < 0) { pr_err_info("fstat"); cftp_send_error_message(desc, (struct cftp_error_message *) msg, "fstat"); goto out_close_file; } if (offset) { ret = lseek(fd, offset, SEEK_SET); if (ret < 0) { pr_err_info("lseek"); cftp_send_error_message(desc, (struct cftp_error_message *) msg, "seek file %s faild", filename); goto out_close_file; } } if (size == 0) { size = st.st_size - offset; } data_pkg = malloc(max_xfer_length); if (data_pkg == NULL) { pr_err_info("malloc"); cftp_send_error_message(desc, (struct cftp_error_message *) msg, "malloc"); ret = -ENOMEM; goto out_close_file; } println("filename = %s", filename); println("offset = %s", size2text(offset)); println("size = %s", size2text(size)); blk_num = 0; data_pkg->type = CFTP_PACKAGE_DATA; progress_bar_init(&bar, size, 0, PROGRESS_BAR_TYPE_DATA); while (1) { readlen = read(fd, data_pkg->data, max_data_length); if (readlen < 0) { pr_err_info("read file failed"); cftp_send_error_message(desc, (struct cftp_error_message *) msg, "read file failed"); ret = readlen; goto out_free_data_pkg; } data_pkg->blk_num = blk_num++; label_send_data: sendlen = cftp_send_data_retry(desc, data_pkg, sizeof(*data_pkg) + readlen, desc->retry_count); if (sendlen < 0) { pr_err_info("cftp_send_ack_message"); ret = sendlen; goto out_free_data_pkg; } recvlen = cftp_receive_data(desc, msg, max_xfer_length); if (recvlen < 0) { pr_err_info("cftp_receive_data"); cftp_send_error_message(desc, (struct cftp_error_message *) msg, "receive file failed"); ret = recvlen; goto out_free_data_pkg; } switch (msg->type) { case CFTP_PACKAGE_ERROR: show_error_message((struct cftp_error_message *) msg); ret = -EFAULT; goto out_free_data_pkg; case CFTP_PACKAGE_ACK: if (msg->ack_msg.blk_num != blk_num) { pr_warn_info("blk_num %d != %d", msg->ack_msg.blk_num, blk_num); goto label_send_data; } if ((size_t) readlen < max_data_length) { progress_bar_finish(&bar); println("Send data complete"); ret = 0; goto out_free_data_pkg; } progress_bar_add(&bar, max_data_length); break; default: pr_err_info("invalid package type"); cftp_send_error_message(desc, (struct cftp_error_message *) msg, "invalid package type"); ret = -EINVAL; goto out_free_data_pkg; } } out_free_data_pkg: free(data_pkg); out_close_file: close(fd); out_free_msg: free(msg); return ret; }
int cftp_server_receive_file(struct cftp_descriptor *desc, const char *filename, mode_t mode, u32 offset, size_t size) { int fd; int ret; union cftp_message *msg; ssize_t recvlen, sendlen; u16 blk_num; struct progress_bar bar; size_t max_xfer_length; max_xfer_length = desc->max_xfer_length; msg = malloc(max_xfer_length); if (msg == NULL) { pr_err_info("malloc"); return -ENOMEM; } fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode); if (fd < 0) { pr_err_info("open file %s faild", filename); cftp_send_error_message(desc, (struct cftp_error_message *) msg, "open file %s faild", filename); ret = fd; goto out_free_msg; } if (offset) { ret = lseek(fd, offset, SEEK_SET); if (ret < 0) { pr_err_info("lseek"); cftp_send_error_message(desc, (struct cftp_error_message *) msg, "seek file %s faild", filename); goto out_free_msg; } } println("offset = %s", size2text(offset)); println("size = %s", size2text(size)); blk_num = 0; progress_bar_init(&bar, size, 0, PROGRESS_BAR_TYPE_DATA); while (1) { sendlen = cftp_send_ack_message(desc, (struct cftp_ack_message *) msg, blk_num, desc->retry_count); if (sendlen < 0) { pr_err_info("cftp_send_ack_message"); ret = sendlen; goto out_close_file; } recvlen = cftp_receive_data(desc, msg, max_xfer_length); if (recvlen < 0) { pr_err_info("cftp_receive_data"); cftp_send_error_message(desc, (struct cftp_error_message *) msg, "receive file failed"); ret = recvlen; goto out_close_file; } switch (msg->type) { case CFTP_PACKAGE_ERROR: show_error_message((struct cftp_error_message *) msg); ret = -EFAULT; goto out_close_file; case CFTP_PACKAGE_DATA: if (msg->data_pkg.blk_num != blk_num) { pr_warn_info("blk_num %d != %d", msg->data_pkg.blk_num, blk_num); continue; } sendlen = write(fd, msg->data_pkg.data, recvlen - sizeof(msg->data_pkg)); if (sendlen < 0) { pr_err_info("write"); cftp_send_error_message(desc, (struct cftp_error_message *) msg, "write file failed"); ret = sendlen; goto out_close_file; } blk_num++; if ((size_t) recvlen < max_xfer_length) { cftp_send_ack_message(desc, (struct cftp_ack_message *) msg, blk_num, 0); progress_bar_finish(&bar); println("Receive data complete"); ret = 0; goto out_close_file; } else { progress_bar_add(&bar, sendlen); } break; default: pr_err_info("invalid package type"); cftp_send_error_message(desc, (struct cftp_error_message *) msg, "invalid package type"); ret = -EINVAL; goto out_close_file; } } out_close_file: close(fd); out_free_msg: free(msg); return ret; }
int cftp_client_send_file(struct cftp_descriptor *desc, const char *file_in, u32 offset_in, const char *file_out, u32 offset_out, size_t size) { int fd; int ret; struct stat st; ssize_t recvlen, sendlen, readlen; u16 blk_num; union cftp_message *msg; struct cftp_data_package *data_msg; size_t max_xfer_length, max_data_length; struct progress_bar bar; ret = file_lstat(file_in, &st); if (ret < 0) { pr_err_info("fstat"); return ret; } max_xfer_length = desc->max_xfer_length; msg = malloc(max_xfer_length); if (msg == NULL) { pr_err_info("malloc"); return -ENOMEM; } switch (st.st_mode & S_IFMT) { case S_IFREG: println("Send File: %s => %s", file_in, file_out); break; case S_IFBLK: case S_IFCHR: println("Send Devicce: %s => %s", file_in, file_out); return cftp_client_send_special_file(desc, &st, &msg->file_req, text_copy(msg->file_req.filename, file_out) - msg->file_req.filename + 1); case S_IFLNK: println("Send Symlink: %s => %s", file_in, file_out); { char *p; p = text_copy(msg->file_req.filename, file_out) + 1; ret = readlink(file_in, p, 1024); if (ret < 0) { pr_err_info("readlink"); return ret; } return cftp_client_send_special_file(desc, &st, &msg->file_req, p - msg->file_req.filename + ret + 1); } case S_IFDIR: println("Send Directory: %s => %s", file_in, file_out); ret = cftp_client_send_special_file(desc, &st, &msg->file_req, text_copy(msg->file_req.filename, file_out) - msg->file_req.filename + 1); if (ret < 0) { pr_err_info("cftp_client_send_special_file"); return ret; } return cftp_client_send_directory(desc, file_in, file_out); default: pr_warn_info("File %s type is unknown", file_in); return 0; } fd = open(file_in, O_RDONLY); if (fd < 0) { pr_err_info("open file %s failed", file_in); goto out_free_msg; } if (offset_in) { ret = lseek(fd, offset_in, SEEK_SET); if (ret < 0) { pr_err_info("lseek"); goto out_close_file; } } if (size == 0) { size = st.st_size - offset_in; } data_msg = malloc(max_xfer_length); if (data_msg == NULL) { pr_err_info("malloc"); ret = -ENOMEM; goto out_close_file; } sendlen = cftp_send_file_reuest(desc, (void *) msg, file_out, &st, offset_out, size, 0); if (sendlen < 0) { ret = sendlen; pr_err_info("cftp_send_data_retry"); goto out_free_data_msg; } println("seek = %s", size2text(offset_out)); println("skip = %s", size2text(offset_in)); println("size = %s", size2text(size)); blk_num = 0; data_msg->type = CFTP_PACKAGE_DATA; max_data_length = max_xfer_length - sizeof(*data_msg); progress_bar_init(&bar, size, 0, PROGRESS_BAR_TYPE_DATA); readlen = max_data_length; while (1) { recvlen = cftp_receive_data(desc, msg, max_xfer_length); if (recvlen < 0) { pr_err_info("cftp_receive_data"); ret = recvlen; goto out_free_data_msg; } switch (msg->type) { case CFTP_PACKAGE_ERROR: show_error_message((struct cftp_error_message *) msg); ret = -EFAULT; goto out_free_data_msg; case CFTP_PACKAGE_ACK: if (msg->ack_msg.blk_num == blk_num) { if ((size_t) readlen < max_data_length) { ret = 0; progress_bar_finish(&bar); println("Send data complete"); goto out_free_data_msg; } readlen = read(fd, data_msg->data, max_data_length); if (readlen < 0) { pr_err_info("read"); cftp_send_error_message(desc, (struct cftp_error_message *) msg, "read file failed"); ret = readlen; goto out_free_data_msg; } data_msg->blk_num = blk_num++; progress_bar_add(&bar, readlen); } else { pr_warn_info("%d != %d", msg->ack_msg.blk_num, blk_num); if (blk_num == 0) { continue; } } sendlen = cftp_send_data_retry(desc, data_msg, sizeof(*data_msg) + readlen, desc->retry_count); if (sendlen < 0) { pr_err_info("cftp_send_data_retry"); goto out_free_data_msg; } break; default: pr_err_info("invalid package type"); cftp_send_error_message(desc, (struct cftp_error_message *) msg, "invalid package type"); ret = -EINVAL; goto out_free_data_msg; } } out_free_data_msg: free(data_msg); out_close_file: close(fd); out_free_msg: free(msg); return ret; }
int cftp_client_receive_file(struct cftp_descriptor *desc, const char *file_in, u32 offset_in, const char *file_out, u32 offset_out, size_t size) { int fd; int ret; ssize_t recvlen, sendlen; u16 blk_num; union cftp_message *msg; size_t max_xfer_length; fd = open(file_out, O_WRONLY | O_CREAT | O_TRUNC, 0777); if (fd < 0) { pr_err_info("open file %s failed", file_out); return fd; } if (offset_out) { ret = lseek(fd, offset_out, SEEK_SET); if (ret < 0) { pr_err_info("lseek"); goto out_close_file; } } max_xfer_length = desc->max_xfer_length; msg = malloc(max_xfer_length); if (msg == NULL) { pr_err_info("malloc"); ret = -ENOMEM; goto out_close_file; } sendlen = cftp_send_file_reuest(desc, (void *) msg, file_in, NULL, offset_in, size, 1); if (sendlen < 0) { pr_err_info("cftp_send_data_retry"); ret = sendlen; goto out_free_msg; } println("Remote@%s => Local@%s", file_in, file_out); println("seek = %s", size2text(offset_out)); println("skip = %s", size2text(offset_in)); println("size = %s", size2text(size)); blk_num = 0; while (1) { recvlen = cftp_receive_data(desc, msg, max_xfer_length); if (recvlen < 0) { pr_err_info("cftp_receive_data"); ret = recvlen; goto out_free_msg; } switch (msg->type) { case CFTP_PACKAGE_ERROR: show_error_message((struct cftp_error_message *) msg); ret = -EFAULT; goto out_free_msg; case CFTP_PACKAGE_DATA: if (msg->data_pkg.blk_num == blk_num) { sendlen = write(fd, msg->data_pkg.data, recvlen - sizeof(msg->data_pkg)); if (sendlen < 0) { pr_err_info("write"); cftp_send_error_message(desc, (struct cftp_error_message *) msg, "write file failed"); ret = sendlen; goto out_free_msg; } blk_num++; if ((blk_num & 0xFF) == 0) { print_char('.'); } if ((size_t) recvlen < max_xfer_length) { println(" Receive data complete"); cftp_send_ack_message(desc, (struct cftp_ack_message *) msg, blk_num, 0); ret = 0; goto out_free_msg; } } else { pr_warn_info("%d != %d", msg->data_pkg.blk_num, blk_num); } sendlen = cftp_send_ack_message(desc, (struct cftp_ack_message *) msg, blk_num, desc->retry_count); if (sendlen < 0) { pr_err_info("cftp_send_ack_message"); ret = sendlen; goto out_free_msg; } break; default: pr_err_info("invalid package type"); cftp_send_error_message(desc, (struct cftp_error_message *) msg, "invalid package type"); ret = -EINVAL; goto out_free_msg; } } out_free_msg: free(msg); out_close_file: close(fd); return ret; }
int fcavan_dd(int fd_in, int fd_out, off_t offset_in, off_t offset_out, off_t length, off_t size) { int ret; struct stat st; println("size = %s", size2text(size)); ret = fstat(fd_in, &st); if (ret < 0) { print_error("fstat input file"); return ret; } if (length == 0) { length = st.st_size; if (length <= offset_in) { warning_msg("no data to be burn"); return 0; } length -= offset_in; } if (size && length > size) { error_msg("No space left"); ERROR_RETURN(ENOMEDIUM); } if (offset_in > 0) { ret = lseek(fd_in, offset_in, SEEK_SET); if (ret < 0) { print_error("seek input file"); return ret; } } if (offset_out > 0) { ret = lseek(fd_out, offset_out, SEEK_SET); if (ret < 0) { print_error("seek output file"); return ret; } } println("skip = %s", size2text(offset_in)); println("seek = %s", size2text(offset_out)); println("length = %s", size2text(length)); ret = ffile_ncopy(fd_in, fd_out, length); if (ret < 0) { error_msg("file_ncopy"); } return ret; }
int main(int argc, char *argv[]) { int ret; int i, j; int dev_fd; struct master_boot_sector mbs; struct hd_geometry geo; u32 total_secs; u64 total_bytes; u32 part_secs; u32 sec_size; u32 start_sec; assert(argc > 2); dev_fd = open(argv[1], O_RDWR | O_BINARY); if (dev_fd < 0) { print_error("open device \"%s\"", argv[1]); return -1; } ret = fread_master_boot_sector(dev_fd, &mbs); if (ret < 0) { error_msg("fread_master_boot_sector"); goto out_close_dev; } ret = fget_device_geometry(dev_fd, &geo); if (ret < 0) { error_msg("fget_device_geometry"); goto out_close_dev; } ret = get_sector_size(dev_fd, &sec_size); if (ret < 0) { error_msg("get_sector_size"); goto out_close_dev; } ret = fget_device_size(dev_fd, &total_bytes); if (ret < 0) { error_msg("fget_device_size"); goto out_close_dev; } total_secs = total_bytes / sec_size; println("device size = %s = %d(sector)", size2text(total_bytes), total_secs); show_geometry(&geo); memset(mbs.disk_part_tables, 0, 64); start_sec = sector_cylinder_lalignment(text2size(argv[2], NULL) / sec_size, &geo); println("start_sec = %d(sector)", start_sec); if (start_sec == 0) { start_sec = 1; } for (i = 0, j = 3; i < 4 && j < argc; i++, j++) { part_secs = sector_cylinder_alignment_auto(text2size(argv[j], NULL) / sec_size, &geo); println("partition start address = %d(sector), size = %d(sector)", start_sec, part_secs); if (start_sec + part_secs > total_secs) { ret = -1; error_msg("partition size is too large"); goto out_close_dev; } set_part_address(mbs.disk_part_tables + i, &geo, start_sec, calculate_partition_size(start_sec, part_secs, &geo)); mbs.disk_part_tables[i].file_system_mark = 0x83; start_sec += part_secs; } if (i < 4 && start_sec < total_secs) { part_secs = sector_cylinder_lalignment(total_secs - start_sec, &geo); set_part_address(mbs.disk_part_tables + i, &geo, start_sec, calculate_partition_size(start_sec, part_secs, &geo)); mbs.disk_part_tables[i].file_system_mark = 0x83; } mbs.magic_number = 0xAA55; ret = fwrite_master_boot_sector(dev_fd, &mbs); if (ret < 0) { error_msg("fwrite_master_boot_sector"); goto out_close_dev; } ret = freread_part_table(dev_fd); if (ret < 0) { error_msg("freread_part_table_retry"); goto out_close_dev; } out_close_dev: close(dev_fd); return ret; }