/*
* Generic filesystem routines and wrappers
*
* The IFILE system also allows the possibility of loading from
* an uncompressed archive, but this has been disabled for now
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#ifdef _WIN32
#include <string.h>
#else
#include <strings.h>
#include <unistd.h>
#endif
char *ifile_prefix=NULL; // No prefix by default
/*
static FILE *fpx;
#define LOGULE(x,y) {fpx=fopen("qslog","a");if(!fpx) return; fprintf(fpx,x,y); fclose(fpx);}
*/
#include "ithelib.h"
// Defines
// Variables
// Unused functions
/*
static int BSCMP(const void *key, const void *elem);
static int QSCMP(const void *elem1, const void *elem2);
*/
// Code
/*
* iopen: top level file open routine.
* Does it's own priority checking
*/
/*
* Read direct from file.
*/
IFILE *iopen(char *filename)
{
FILE *fp;
IFILE *ifp;
char buffer[1024];
fp=NULL;
// If we have a prefix, try that first
if(ifile_prefix)
{
strcpy(buffer,ifile_prefix);
strcat(buffer,filename);
#ifdef _WIN32
strwinslash(buffer);
#endif
fp = fopen(buffer,"rb");
}
// Nothing? Try without any prefix
if(!fp)
fp = fopen(filename,"rb");
if(!fp)
ithe_panic("iopen_readfile: fopen failed on file",filename);
// return NULL;
// OK, we got a result with a physical file, load it and go
ifp = (IFILE *)M_get(1,sizeof(IFILE));
ifp->length = filelength(fileno(fp));
ifp->origin = 0;
ifp->fp = fp;
ifp->truename = M_get(1,strlen(filename)+1);
strcpy(ifp->truename,filename);
return ifp;
}
/*
* Write to a file
*/
IFILE *iopen_write(char *filename)
{
FILE *fp;
IFILE *ifp;
// only physical files are supported for writing
fp = fopen(filename,"wb+");
if(!fp)
ithe_panic("iopen_write: cannot create file:",filename);
// OK, we got a result with a physical file, start it and go
ifp = (IFILE *)M_get(1,sizeof(IFILE));
ifp->length = 0;
ifp->origin = 0;
ifp->fp = fp;
ifp->truename = M_get(1,strlen(filename)+1);
strcpy(ifp->truename,filename);
return ifp;
}
/*
* Does a file exist
*/
int iexist(char *filename)
{
char buffer[1024];
if(!access(filename,F_OK))
return 2;
strcpy(buffer,ifile_prefix);
strcat(buffer,filename);
if(!access(buffer,F_OK))
return 1;
return 0;
}
/*
* Get file date
*/
time_t igettime(char *filename)
{
struct stat sb;
char buffer[1024];
if(!stat(filename,&sb))
return sb.st_mtime;
strcpy(buffer,ifile_prefix);
strcat(buffer,filename);
if(!stat(buffer,&sb))
return sb.st_mtime;
return 0;
}
/*
* Close a file
*/
void iclose(IFILE *ifp)
{
if(!ifp)
return;
fclose(ifp->fp);
M_free(ifp->truename);
M_free(ifp);
}
void iseek(IFILE *ifp, int offset, int whence)
{
if(!ifp)
return;
switch(whence)
{
case SEEK_SET:
fseek(ifp->fp,offset+ifp->origin,SEEK_SET);
break;
case SEEK_END:
fseek(ifp->fp,ifp->origin+ifp->length+offset,SEEK_SET);
break;
default:
fseek(ifp->fp,offset,SEEK_CUR);
break;
}
}
unsigned char igetc(IFILE *ifp)
{
return fgetc(ifp->fp);
}
unsigned short igetsh_reverse(IFILE *ifp)
{
unsigned char a,b;
a=igetc(ifp);
b=igetc(ifp);
return ((a<<8) + b);
}
unsigned short igetsh_native(IFILE *ifp)
{
unsigned short s=0;
iread((void *)&s,2,ifp);
return s;
}
long igetl_reverse(IFILE *ifp)
{
unsigned short a=0,b=0;
a=igetsh_reverse(ifp);
b=igetsh_reverse(ifp);
return (long)((a<<16) + b);
}
long igetl_native(IFILE *ifp)
{
long a=0;
iread((void *)&a,4,ifp);
return a;
//return getw(ifp->fp);
}
unsigned long igetlu_reverse(IFILE *ifp)
{
unsigned short a,b;
a=igetsh_reverse(ifp);
b=igetsh_reverse(ifp);
return (unsigned long)((a<<16) + b);
}
unsigned long igetlu_native(IFILE *ifp)
{
return (unsigned long)igetl_native(ifp);
//return getw(ifp->fp);
}
uqword igetll_reverse(IFILE *ifp)
{
return (((uqword)igetl_reverse(ifp) << 32) + igetl_reverse(ifp));
}
uqword igetll_native(IFILE *ifp)
{
uqword q=0;
iread((void *)&q,8,ifp);
return q;
}
int iread(unsigned char *buf, int l, IFILE *ifp)
{
return fread(buf,1,l,ifp->fp);
}
void iputc(unsigned char c, IFILE *ifp)
{
fputc(c,ifp->fp);
}
void iputsh_reverse(unsigned short s, IFILE *ifp)
{
iputc((s>>8)&0xff,ifp);
iputc(s&0xff,ifp);
}
void iputsh_native(unsigned short s, IFILE *ifp)
{
iwrite((void *)&s,2,ifp);
}
void iputl_reverse(long l, IFILE *ifp)
{
iputsh_reverse((l>>16)&0xffff,ifp);
iputsh_reverse(l&0xffff,ifp);
}
void iputl_native(long l, IFILE *ifp)
{
putw(l,ifp->fp);
}
void iputlu_reverse(unsigned long l, IFILE *ifp)
{
iputsh_reverse((l>>16)&0xffff,ifp);
iputsh_reverse(l&0xffff,ifp);
}
void iputlu_native(unsigned long l, IFILE *ifp)
{
putw(l,ifp->fp);
}
void iputll_reverse(uqword q, IFILE *ifp)
{
iputl_reverse((q>>32)&0xffffffff,ifp);
iputl_reverse(q&0xffffffff,ifp);
}
void iputll_native(uqword q, IFILE *ifp)
{
iwrite((void *)&q,8,ifp);
}
int iwrite(unsigned char *buf, int l, IFILE *ifp)
{
return fwrite(buf,1,l,ifp->fp);
}
unsigned int itell(IFILE *ifp)
{
return ftell(ifp->fp)-ifp->origin;
}
unsigned int ifilelength(IFILE *ifp)
{
return ifp->length;
}
int ieof(IFILE *ifp)
{
if(ftell(ifp->fp) >= ifp->origin+ifp->length)
return 1;
return 0;
}
// Get a home subdirectory for config settings
void ihome(char *path)
{
char *home;
char temp[1024];
home=getenv("HOME");
if(!home)
home=".";
#if defined(__SOMEUNIX__) || defined(__DJGPP__)
sprintf(temp,"%s/.ire",home);
mkdir(temp,S_IRUSR|S_IWUSR|S_IXUSR);
strcat(temp,"/");
#else
sprintf(temp,"%s/ire",home);
mkdir(temp);
strcat(temp,"/");
#ifdef _WIN32
strwinslash(temp);
#endif
#endif
strcpy(path,temp);
}
/*
*
*
* Internal functions (not for human consumption)
*
*
*/
#ifdef __BEOS__ // BEOS is not well
int getw(FILE *fp)
{
int w;
fread(&w,1,4,fp);
return w;
}
void putw(int w, FILE *fp)
{
fwrite(&w,1,4,fp);
}
#endif