/* XPK - General XPK file-to-file packer/unpacker */

#include <proto/exec.h>
#include <proto/dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libraries/xpk.h>

struct Library *XpkBase;
char errbuf[XPKERRMSGSIZE+1];                      /* +1 to make room for '\n'*/

int  chkabort(void) { return 0; }                  /* disable SAS ^C handling */
void print(char *s) { Write(Output(),s,strlen(s));}

long __asm 
chunkfunc(register __a1 struct XpkProgress *prog)
{
	char buf[120];

	if( prog->Type==XPKPROG_START )
		print("\033[0 p");

	if( prog->Type!=XPKPROG_END )
		sprintf(buf,
		  "\r%4s: %-8s (%3ld%% done, %2ld%% CF, %6ld cps) %s\033[K",
		   prog->PackerName,  prog->Activity,   prog->Done,
		   prog->CF,          prog->Speed,      prog->FileName);
	else 
		sprintf(buf,
		  "\r%4s: %-8s (%3ldK, %2ld%% CF, %6ld cps) %s\033[K\n",
		   prog->PackerName,  prog->Activity,   prog->ULen/1024,
		   prog->CF,          prog->Speed,      prog->FileName);

	print( buf );

	if( prog->Type==XPKPROG_END )
		print("\033[1 p");

	return (long)SetSignal(0, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C;
}
struct Hook chunkhook = {{0},chunkfunc};


char namebuf[200];

char *tempname( char *name )
{
	strcpy( namebuf, name );
	for( name=namebuf+strlen(namebuf); name>namebuf; name-- )
		if( name[-1]=='/' || name[-1]==':' )
			break;
	sprintf(name,"tmp%lx",&name);
	return namebuf;
}

void end( char *text )
{
	if( text )    print( text );
	if( XpkBase ) CloseLibrary( XpkBase );
	exit(text ? 10 : 0);
}

char usage[]="Usage: XPK [-s][-p password] method files\n";

void main(int argc, char *argv[])
{
	char *method= NULL, *password= NULL;
	int  i=1, suffix=0;

	if(!(XpkBase=OpenLibrary(XPKNAME,0)))
		end("Cannot open "XPKNAME"\n");

	if( stricmp(argv[0],"XPK"))
		method=argv[0];
	else if( argc<2 || !strcmp(argv[1],"?"))
		end(usage);

	if( i<argc && !strcmp( argv[i],"-s" ))
		suffix=1, i++;

	if( i+1<argc && !strcmp( argv[i],"-p" ))
		password=argv[++i], i++;

	if( !method )
		if( i<argc )
			method=argv[i++];
		else 
			end(usage);

	if( i==argc )
		end(usage);

	for( ; i<argc; i++ ) {
		tempname(argv[i]); 
		if( suffix )
			sprintf( namebuf, "%s.xpk", argv[i]);

		if( XpkPackTags(               
			XPK_InName,      argv[i],
			XPK_OutName,     namebuf,
			XPK_ChunkHook,   &chunkhook,
			XPK_GetError,    errbuf,
			XPK_FindMethod,  method,
			XPK_Password,    password,
			XPK_NoClobber,   TRUE,
			TAG_DONE
		))
			end(strcat(errbuf,"\n"));

		if( !suffix ) {
			if(!DeleteFile(argv[i]))
				end("Cannot delete input file\n");
			if( !Rename(namebuf,argv[i]))
				end("Cannot rename tempfile\n");
		}
	}

	end(NULL);
}
