/*------------------------------------------------------------------------
 Module:        /extra/development/xamime/xamime_working/ripmime/filename-filters.c
 Author:        Paul L Daniels
 Project:       ripMIME
 State:         Release
 Creation Date: 01 Jan 03
 Description:   Filename Filters is a module which is designed to check and 'safety-enhance'
                filenames which are passed to it.  This may include things like removing
                directory risers ( ../.. ), root directory attempts ( / ), and parameter passing.
------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <syslog.h>
#include <ctype.h>


#include "pldstr.h"
#include "logger.h"
#include "filename-filters.h"


#define _SL 1

#define FNFILTER_DEBUG_PEDANTIC 10
#define FNFILTER_DEBUG_NORMAL 1

// Debug precodes
#define FNFILTER_DPEDANTIC ((glb.debug >= FNFILTER_DEBUG_PEDANTIC))
#define FNFILTER_DNORMAL   ((glb.debug >= FNFILTER_DEBUG_NORMAL  ))


struct FNFILTER_globals {
	int debug;
	int verbose;
	int paranoid;
};

static struct FNFILTER_globals glb;


int FNFILTER_init( void )
{
	glb.debug = 0;
	glb.verbose = 0;
	glb.paranoid = 0;

	return 0;
}


int FNFILTER_set_debug( int level )
{
	glb.debug = level;

	return glb.debug;
}

int FNFILTER_set_verbose( int level )
{
	glb.verbose = level;

	return glb.verbose;
}

int FNFILTER_set_paranoid( int level )
{
	glb.paranoid = level;

	return glb.paranoid;
}


/*------------------------------------------------------------------------
Procedure:     quick_clean_filename ID:1
Purpose:       Removes non-7bit characers from the filename
Input:         char *fname: Null terminated string
Output:
Errors:
------------------------------------------------------------------------*/
int FNFILTER_paranoid_filter( char *fname, int size )
{
	char tmp[1024];
	char *p = strrchr(fname,'/');

	/* scan out any directory separators */

	if (p)
	{
		// Check to see that this seperator isn't the -last- char in the string
		if (*(p+1) == '\0') *p = '\0';
		else
		{
			p++;
			PLD_strncpy(tmp,p,sizeof(tmp));
			PLD_strncpy(fname,tmp,size);
		}
	}
	else if ( (p = strrchr(fname,'\\')))
	{
		// Check to see that this seperator isn't the -last- char in the string
		if (*(p+1) == '\0') *p = '\0';
		else
		{
			p++;
			PLD_strncpy(tmp,p,sizeof(tmp));
			PLD_strncpy(fname,tmp,size);
		}
	}


	if ( glb.paranoid > 0 )
	{
		// If we're really paranoid, then we go along and convert anything we don't like
		//	the look of into 7-bit
		//
		//	These days we shouldn't be using this any more as there are many filenames
		//	which require > 7-bit charsets.

		while (*fname)
		{
			if( !isalnum(*fname) && (*fname != '.') ) *fname='_';
			if( (*fname < ' ')||(*fname > '~') ) *fname='_';
			fname++;
		}
	}

	return 0;
}









/*------------------------------------------------------------------------
Procedure:     MIME_decode_filename ID:1
Purpose:       Removed spurilous characters from filename strings.
Input:         char *fname: null terminated character string
Output:
Errors:
------------------------------------------------------------------------*/
int FNFILTER_filter( char *fname, int size )
{
	int fnl = strlen(fname);
	char tmp[1024];
	char *p;

	/* scan out any directory separators */


	if (FNFILTER_DNORMAL) {
		LOGGER_log("FNFILTER_filter:%s:%d: fname = %s\n", __FILE__, __LINE__, fname );
		fflush(stdout);
	}

	if ( fnl > 0 )
	{

		/* if the MIME_filename starts and ends with "'s */
		if ((fname[0] == '\"') && (fname[fnl-1] == '\"'))
		{
			/* reduce the file namelength by two*/
			fnl = fnl -2; // 17-11-2002: was =-2, thanks to Vasily Chernikov for spotting the glaring error!

			/* shuffle the MIME_filename chars down */
			memmove(fname,fname+1,fnl);

			/* terminate the string */
			fname[fnl] = '\0';
		} /* if */
	} /* if */

	p = strrchr(fname,'/');
	if (p)
	{
		p++;
		PLD_strncpy( tmp, p, sizeof(tmp) );
		PLD_strncpy( fname, tmp, size);

	}
	else {


		// Check for Windows/DOS backslash seperator

		p = strrchr( fname, '\\' );
		if ( p )
		{
			if ( *(p+1) != '"' )
			{
				p++;
				PLD_strncpy( tmp, p, sizeof(tmp) );
				PLD_strncpy( fname, tmp, size );
			}
		}
	}

	// Scan for ? symbols - these are often used to make the email client pass paremeters to the filename
	// 	Check though to see that the previous character is not a '=' symbol, because if it is, then we
	//	actually have an ISO encoded filename

	p = strchr( fname, '?' );
	if (( p ) && ( *(p-1) != '=' ))
	{
		*p = '\0';
	}


	FNFILTER_paranoid_filter( fname, strlen( fname ) );

	return 0;
}





