/*
    Raydium - CQFD Corp.
    http://raydium.org/
    Released under both BSD license and Lesser GPL library license.
    See "license.txt" file.
*/

#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/file.h"
#include "headers/rayphp.h"
#endif

// proto
void raydium_path_resolv(char *in, char *out, char mode);


// far better than glibc's 'dirname' (and portable)
void raydium_file_dirname(char *dest,char *from)
{
char *c;
int n;

c=strrchr(from,'/'); // Unix
if(!c)
      c=strrchr(from,'\\'); // win32

if(!c)
    {
    strcpy(dest,"./");
    return;
    }
n=c-from;
memcpy(dest,from,n+1);
dest[n+1]=0;
}

void raydium_file_basename(char *dest,char *from)
{
char *c;
int n;

c=strrchr(from,'/'); // Unix
if(!c)
    c=strrchr(from,'\\'); // win32

if(!c)
    {
    strcpy(dest,from);
    return;
    }
n=(c-from+1);

if(n==(int)strlen(from))
    {
    dest[0]=0;
    return;
    }

strcpy(dest,from+n);
}

void raydium_file_ext(char *dest, char *from)
{
char name[RAYDIUM_MAX_DIR_LEN];
char *c;

dest[0]=0;

raydium_file_basename(name,from);
if( (c=strrchr(name,'.')) )
    if(c[1]!=0)
        strcpy(dest,c+1);
}

signed char raydium_file_isdir(char *path)
{
DIR * rphp;
rphp=opendir(path);

if (rphp)
	{
	closedir(rphp);
	return 1;
	}
return 0;
}

signed char raydium_file_directory_writable(char *path)
{
char file[RAYDIUM_MAX_NAME_LEN];
FILE *fp;

snprintf(file,RAYDIUM_MAX_NAME_LEN,"%s/RAYDIUM-WRITE-TEST.delme",path);
fp=fopen(file,"wb");
if(!fp)
    return 0;

fclose(fp);
unlink(file);
return 1;
}

signed char raydium_file_readable(char *filename)
{
FILE *fp;
fp=fopen(filename,"r");
if(!fp)
    return 0;
fclose(fp);
return 1;
}

void raydium_file_log_fopen_display(void)
{
int i;
char tmp[RAYDIUM_MAX_DIR_LEN];

raydium_log("List of all opened files:");
raydium_log("-------------------------");

for(i=0;i<raydium_file_log_fopen_index;i++)
    {
    if(raydium_file_log_fopen_status[i]==RAYDIUM_FILE_FOUND)
    	{
    	raydium_path_resolv(raydium_file_log_fopen[i],tmp,'r');
	if(strcmp(raydium_file_log_fopen[i],tmp))
	    raydium_log("> %s (%s)",raydium_file_log_fopen[i],tmp);
	else
	    raydium_log("> %s",raydium_file_log_fopen[i]);
	}
    else
    	raydium_log("> %s (**MISSING**)",raydium_file_log_fopen[i],tmp);
    }

}

void raydium_file_cache_flush(void)
{
int i,j;

i=j=0;
for(j=0;j<raydium_file_log_fopen_index;j++)
    {
    if (raydium_file_log_fopen_status[j]==RAYDIUM_FILE_FOUND)
    	{
        if (j==i)
            i++; // Nothing to copy.
        else
            {
            strcpy(raydium_file_log_fopen[i],raydium_file_log_fopen[j]);
            raydium_file_log_fopen_status[i]=raydium_file_log_fopen_status[j];
            i++;
            }
	}
    }
raydium_file_log_fopen_index=i;
}

FILE *raydium_file_fopen(char *file, char *mode)
{
FILE *fp=NULL;
int i;
char found=0;
char file2[RAYDIUM_MAX_DIR_LEN];

if(!file || !strlen(file))
    return NULL;

for(i=0;i<raydium_file_log_fopen_index;i++)
    if(!strcmp(raydium_file_log_fopen[i],file))
        {
        if(raydium_file_log_fopen_status[i]==RAYDIUM_FILE_NOT_FOUND)
	    {
	    if(strchr(mode,'w')) // a previous read failed, but now we're creating it (or trying to)
		raydium_file_log_fopen_status[i]=RAYDIUM_FILE_FOUND;
	    else
	    	return NULL;
	    }
        found=1;
        break;
        }

// use paths
raydium_path_resolv(file,file2,mode[0]);

do {
    // local mode ?
    if(strchr(mode,'l') || raydium_init_cli_option("repository-disable",NULL))
        {
	char mode2[16];
	strcpy(mode2,mode);
	raydium_parser_remove(mode2,'l'); // since win32 refuse to open a file with a unknown option ...
        fp= fopen(file2,mode2);
        break;
        }

    if(strchr(mode,'w'))
        {
        fp= fopen(file2,mode);
        break;
        }

    if( !raydium_init_cli_option("repository-refresh",NULL) &&
        !raydium_init_cli_option("repository-force",NULL) )
        {
        fp=fopen(file2,mode);
        if(fp) break;
        }
    raydium_rayphp_repository_file_get(file2);
    fp=fopen(file2,mode);
    }
while(0);

if(!found)
    {
    strcpy(raydi