/*
  media-filesystem export utility
  tridge@samba.org, January 2001
  released under the Gnu GPL v2
*/

#include "mfs.h"

static void export_file(u32 fsid, char *dest, u64 start, u64 count)
{
	int fd;
	void *buf;
	int bufsize = 128*1024;
	int n;
	u64 ofs;
	u64 size, total=0;
	int pct, last_pct;

	ofs = start;

	fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0644);
	if (fd == -1) {
		perror(dest);
		exit(1);
	}
	buf = malloc(bufsize);
	mfs_readahead(1);
	size = mfs_fsid_size(fsid);
	printf("exporting fsid %d of size %lld to %s\n", fsid, size, dest);
	if (start > size) {
		printf("start beyond EOF!\n");
		exit(1);
	}
	if (start+count>size || count==0) {
		count = size-start;
	}
	if (start || count) {
		printf("starting at %lld for %lld bytes\n", start, count);
	}

	last_pct=0;

	while (total<count &&
	       (n=mfs_fsid_pread(fsid, buf, ofs, MIN(bufsize,count-total))) > 0) {
		if (write(fd, buf, n) != n) {
			fprintf(stderr,"failed to write to %s\n", dest);
			break;
		}
		ofs += n;
		total += n;
		pct = (100*total)/count;
		if (pct != last_pct) {
			printf("%d%%\r", pct);
			fflush(stdout);
			last_pct = pct;
		}
	}
	close(fd);
}


static void usage(void)
{
	printf("
usage: mfs_export [options] <path|fsid> <dest>

   options:
        -s <start>                     start offset
        -c <count>                     number of bytes (defaults to all)
");         
	exit(1);
}


 int main(int argc, char *argv[])
{
	int fsid;
	int c;
	u64 start=0;
	u64 count=0;

	while ((c = getopt(argc, argv, "hs:c:")) != -1 ){
		switch (c) {
		case 'h':
			usage();
			break;

		case 's':
			start = strtoll(optarg, NULL, 0);
			break;

		case 'c':
			count = strtoll(optarg, NULL, 0);
			break;			

		default:
			usage();
		}
	}

	argc -= optind;
	argv += optind;

	if (argc < 2) {
		usage();
	}

	mfs_init();
	fsid = mfs_resolve(argv[0]);
	export_file(fsid, argv[1], start, count);
	return 0;
}
