/*

Name:
MARCHIVE.C

Description:
These routines are used to detect different archive/compression formats and
decompress/de-archive the mods from them if necessary

Portability:
All systems - all compilers

Steve McIntyre <stevem@chiark.greenend.org.uk>

Feel free to use/modify this code if you like, let me know if you improve
it! 

HISTORY
=======

v1.00 (06/12/96) - first "versioned" version
v1.01 (03/01/97) - Changed from #defined archiver markers and commands
	to an array to be stepped through. Should be easier for users to add
	their own commands later.
v1.02 (10/01/97) - minor changes for compilation with -Wall
v1.03 (09/02/97) - now loads supplied file from supplied archive...
			a little kludgy, but works (Peter Amstutz)
v1.04 (20/04/97) - de-kludged it :)  Now works somewhat better.  Pass
			archive & file you want out of it, and it passes back the
			filename to find the decompressed file
*/

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

#ifdef NEED_UNISTD
#include <unistd.h>
#endif /* NEED_UNISTD */

#include "mikmod.h"

/* 
	==================================================================
	Use similar signature idea to "file" to see what format we have...
	==================================================================
*/

ARCHIVE MA_archiver[]={
/* 
location marker  command 
*/

    {0,	"PK",	"unzip -p"},     /* PKZIP archive */
    {2,	"-l",	"lha pq"},       /* LHA/LZH archive */
    {1,	"ê",	"unarj c"},	/* ARJ */
    {0,	"",	"gzip -dc"},     /* GZIP */
    {0,	"ZOO",	"zoo xpq"},	/* ZOO */
    {0, NULL,   NULL}		/* needed to end the array... */
};

int *MA_identify(char *filename, int header_location, char *header_string)
{
	FILE *fp;
	char id[16]; /* hopefully should be big enough for "signature" */

	if((fp=fopen(filename,"rb"))==NULL){
		_mm_error="Error opening file";
		return NULL;
	}
	modfp=fp;
	_mm_rewind(modfp);
	if(header_location)
		_mm_fseek(modfp,header_location,SEEK_SET);
	if(!fread(id,strlen(header_string),1,modfp)) 
	{
		fclose(fp);
		return 0;
	}
	if(!memcmp(id,(char *)header_string,strlen(header_string))) 
	{
		fclose(fp);
		 return (int *) 1;
	}
	fclose(fp);

	return 0;
}

char *MA_dearchive(char *arc, char *file)
{
	int t;
	char *tmp_file;
	char command_buff[512];
	char *vc;
	extern ARCHIVE MA_archiver[];

	int archive=0;
	tmp_file=(char *)malloc(256);

	if(arc==NULL || arc[0]==0)
	{
		strcpy(tmp_file,file);
		return tmp_file;
	}

	if ((vc=getenv("HOME"))) {
      		strcpy(tmp_file, vc);
	} else {
      		strcpy(tmp_file, "/tmp");
	}
 	strcat(tmp_file, "/.modXXXXX");

	for(t=0; MA_archiver[t].command!=NULL; t++)
	  	{
		if(MA_identify(arc,MA_archiver[t].location,MA_archiver[t].marker))
	   		{
			sprintf(command_buff,"%s %s \"%s\" >%s 2>/dev/null",MA_archiver[t].command,arc,file,tmp_file);
			archive=1;
			break;
			}
		}

	if(archive){
		/* display "loading" message, as this may take some time... */
		system(command_buff);
	}

	return (char *) tmp_file;
}
