예제 #1
0
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;
}
예제 #2
0
파일: cftp.c 프로젝트: FuangCao/cavan
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;
}
예제 #3
0
파일: cftp.c 프로젝트: FuangCao/cavan
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;
}
예제 #4
0
파일: cftp.c 프로젝트: FuangCao/cavan
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;
}
예제 #5
0
파일: cftp.c 프로젝트: FuangCao/cavan
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;
}
예제 #6
0
파일: dd.c 프로젝트: Jack19881218/cavan
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;
}
예제 #7
0
파일: fdisk.c 프로젝트: Jack19881218/cavan
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;
}