/**************************************************************************
file:	split.c
author:	scott arrington
date:	april 1999
description:
	split a single file into a bunch of 1meg chunks.
***************************************************************************/

#include <stdio.h>
#include <stdlib.h>

#define DEFAULT_SEGSIZE	1048576	/* 1 meg */
#define BLOCKSIZE	4096	/* 4K, i think the default buf size for stdio */

unsigned int segsize = DEFAULT_SEGSIZE;

int copy_segment ( FILE *from, FILE *to, int len );
int split ( FILE *src, const char *outbasename );
int parse_args ( int argc, char *argv[] );


int copy_segment ( FILE *from, FILE *to, int len )
{
	static buf[BLOCKSIZE];
	int blockcount = len / BLOCKSIZE;
	int residual = len % BLOCKSIZE;
	
	while ( blockcount-- > 0 ) {
		fread(buf,1,BLOCKSIZE,from);
		fwrite(buf,1,BLOCKSIZE,to);
	}

	if ( residual ) {
		/* copy the residual */
		fread(buf,1,residual,from);
		fwrite(buf,1,residual,to);
	}
	
	return 0;
}



int split ( FILE *src, const char *outbasename )
{
	char *outputname, *namep;
	unsigned long int filelen;
	FILE *out;
	int segcount, i;

	/*
	 * create and set up a place to hold our output filenames. 
	 * each one will simply append three digits and a dot (four
	 * chars) to the outbasename.
	 */
	outputname = (char*)calloc( strlen(outbasename) + 4 + 1, sizeof(char) );
	if ( outputname == NULL ) {
		perror("malloc failed");
		return -1;
	}
	strcpy(outputname,outbasename);
	/* point namep to the part we have to change. */
	namep = outputname + strlen(outputname);
	
	/* get the file length */
	fseek(src,0,SEEK_END);
	filelen = ftell(src);

	/* go back to the beginning */
	rewind(src);


	segcount = (int)filelen / segsize;
	printf ("filelen:	%ld\n"
		"segsize:	%d\n"
		"remainder:	%ld\n"
		"segcount:	%d+%d\n",
		filelen,
		segsize,
		filelen%segsize,
		segcount,
		((filelen%segsize) != 0));

	/*
	 * copy all of the full-size segments to their own files.
	 */
	for (i=0; i<segcount; i++) {
		sprintf(namep,".%03d",i);
		out = fopen(outputname,"wb");
		if (out==NULL) {
			perror(outputname);
			exit(EXIT_FAILURE);
		}
		printf("writing %s\n",outputname);
		copy_segment(src,out,segsize);
		fclose(out);
	}

	/*
	 * if there is anything left over, write it to another file.
	 */
	if ((filelen%segsize) != 0) {
		sprintf(namep,".%03d",i);
		out = fopen(outputname,"wb");
		if (out==NULL) {
			perror(outputname);
			exit(EXIT_FAILURE);
		}
		printf("writing %s\n",outputname);
		copy_segment(src,out,(filelen%segsize));
		fclose(out);
	}
	
	free(outputname);

	return 0;
}


int parse_args ( int argc, char *argv[] )
{
	/*
	 * we should look for things like segment size and segment basename
	 * maybe even number of segments, from which we'd have to calculate
	 * a segment size
	 */
	return 0;
}



int main ( int argc, char * argv[] )
{
	FILE *in;

	if (argc < 2) {
		printf("usage: %s filename\n",argv[0]);
		exit(1);
	}
	printf("source file: %s\n",argv[1]);

	in = fopen( argv[1], "rb" );
	if (in == NULL) {
		perror(argv[1]);
		exit(EXIT_FAILURE);
	}

	split(in,argv[1]);

	fclose(in);
	return 0;
}

