/*
 * Split: Datei in Stücke aufteilen, Gegenstück zu Join
 *
 * Auto: cc -wcdpur0n -sabfmnrs -pps -qf Split.c
 * Auto: ln Split.o +l amiga.lib +l -lc16
 *
 * - benötigt mindestens OS 2.04
 * - Extensionmuster kann angegeben werden (Default ".part%d")
 * - Blockgröße kann angegeben werden (Default 880000 Bytes)
 * - benutzt sprintf() aus amiga.lib (kurz da ROM-Routine)
 * - kommt auch mit wenig Speicher zurecht
 *
 * FREEWARE
 * by Michael Balzer, M.BALZER@AWORLD.ZER (.sub.org)
 *
 */
char *version = "\0$VER: Split 37.2 (" __DATE__ ")";

#include <exec/types.h>

#include <clib/exec_protos.h>
#include <pragmas/exec_lib.h>
#include <clib/dos_protos.h>
#include <pragmas/dos_lib.h>

#include <exec/memory.h>

#include <dos/dos.h>
#include <dos/rdargs.h>

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


#define TEMPLATE "FILENAME/A,EXT=EXTENSION,BS=BLOCKSIZE/N"

#define EXTHELP \
	"FILENAME  = name of the file to split (required)\n" \
	"EXTENSION = extension of the destination file(s)\n" \
	"	    (defaults to \".part%d\")\n" \
	"BLOCKSIZE = maximum size (in bytes) of the created pieces\n" \
	"	    (defaults to 880000, one FFS disk)\n"

typedef struct { char *filename, *extension; long *blocksize; } ARGS;
#define DEFAULT { NULL, ".part%d", &blocksize }

long			blocksize = 880000L;  /* Eine FFS-Disk mit Reserve */
long			buffersize;
ARGS			args = DEFAULT;
struct RDArgs	*rda = NULL;
BPTR			in = NULL, out = NULL;
char			*buffer = NULL;


void closedown( void )
{
	PrintFault( IoErr(), "Split" );
	if( out ) Close( out );
	if( in  ) Close( in  );
	if( buffer ) FreeMem( buffer, buffersize );
	if( rda )
	{
		FreeArgs( rda );
		FreeDosObject( DOS_RDARGS, rda );
	}
}


void _main( long alen, char *aptr )
{
	char name[512], *ext;
	long count, buffread;
	WORD extcnt = 0;
	
	atexit( closedown );
	
	/* Argumente parsen */
	
	rda = AllocDosObject( DOS_RDARGS, NULL );
	rda->RDA_ExtHelp = EXTHELP;
	
	if( ! ReadArgs( TEMPLATE, (LONG *) &args, rda ) )
		exit( 20 );
	
	blocksize = *args.blocksize;
	
	ext = name;
	while( *ext++ = *args.filename++ );
	--ext;
	
	/* Speicher holen */
	
	for( buffersize = blocksize;
		 !buffer && buffersize >= 512;
		 buffersize /= 2 )
	{
		buffer = AllocMem( buffersize, MEMF_ANY );
	}
	
	if( !buffer )
	{
		SetIoErr( ERROR_NO_FREE_STORE );
		exit( 20 );
	}
	
	/* Und splitten */
	
	in = Open( name, MODE_OLDFILE );
	if( !in )
		exit( 10 );
	
	do
	{
		sprintf( ext, args.extension, ++extcnt );
		
		out = Open( name, MODE_NEWFILE );
		if( !out )
			exit( 10 );
		
		count = 0;
		while( count != blocksize )
		{
			buffread = Read( in, buffer, buffersize );
			
			if( Write( out, buffer, buffread ) != buffread )
				exit( 10 );
			
			count += buffread;
			if( buffread != buffersize ) break;
		}
		
		Close( out );
		out = NULL;
	}
	while( count == blocksize );
	
	exit( 0 );
}
