/*------------------------------------------------
//
// Module: nph-prot.c
//
// Objet : protection de document par code d'acces
//
// ToDo  : 
//
//
//
// Maintenance :
//
//     Auteur  : Olivier Booklage
//     Version : V1.0
//     Date    : 20/04/1998
//     Remarq. :
//
//
//
//-----------------------------------------------*/


/* ---       Includes externes       -- */

#include	<stdio.h>
#include	<stdlib.h>
#include	<tos.h>
#include	<string.h>
#include	<ctype.h>
#include	<process.h>
#include	<portab.h>
#include	<nkcc.h>	/* v2.93 */

/* ---       Includes internes       -- */

/* --- Constantes globales internes --- */

#define MAXLINE 500
/* #define LF 10 */
/* #define CR 13 */
#define HTML_HEADER	"<HTML><TITLE>NPH-PROT message</TITLE><BODY>"
#define HTML_FOOTER	"</BODY></HTML>"

/* --- Structures globales internes --- */

/* --- Variables globales  internes --- */

char line[MAXLINE];
char errstr[MAXLINE];

char statement[MAXLINE];
char par1[MAXLINE];
char par2[MAXLINE];
char par3[MAXLINE];
char cbuf[127];

char path[127];
char file[127];

/* ---     Prototypage interne      --- */

int main (int argc, const char *argv[]);
static void ProcessLine(BYTE *line, BYTE *s, BYTE *p1, BYTE *p2, BYTE *p3,LONG limit);
static void servererr(char *status, char *msg);
static BYTE *trim (BYTE *str);
VOID file_splitt(const UBYTE *fullname, UBYTE *path, UBYTE *name);
BOOLEAN SetPath(UBYTE *unixpath);

/* ---         Fonctions            --- */

int main (int argc, const char *argv[])
{
FILE *fp = NULL;
char *ref, *ident;
char CONF_FILE[]="nph-prot.inf";
BOOLEAN ref_found = FALSE;
INT i;

	ref=getenv("PATH_INFO");
	if((ref== NULL) || (!ref[0]))
		servererr("200", "No PATH_INFO given. Please read the bodygard documentation.<P>");

	ident=getenv("REMOTE_IDENT");
	if((ident== NULL) || (!ident[0]))
		servererr("401", "No REMOTE_IDENT given. I need an Autentification.<P>");

/* Ouverture du fichier de configuration */

	fp = fopen(CONF_FILE,"r");
	if( fp == NULL)
	{
		sprintf(errstr, "Couldn't open configuration file: %s", CONF_FILE);
		servererr("200",errstr);
	}

	while ( fgets(line, MAXLINE, fp) != NULL )
	{
		if ( (*line != ';') && (*line != '#') )
		{
			ProcessLine(line, statement, par1, par2, par3, MAXLINE);
			if ( ( *statement != EOS ) && ( *par1 != EOS ) )
			{
				if ( stricmp( ref, statement) == SUCCESS )
				{

/* fprintf(stderr,"\a url <%s> code <%s> you = <%s>\n", statement, par1 ,ident); */

					ref_found = TRUE;
					if ( stricmp( ident, par1) == SUCCESS )		goto found;
				}
			}
		}
	}

	if ( ref_found == TRUE )
		servererr("401", "Your name or password is WRONG, access denied.");
	else
		servererr("200","PATH_INFO not found in the CONF_FILE. Contact administrator.");

found :

	fclose(fp);

	if ( *par2 == 0 )
	{
		servererr("200","Program parameter not found in the CONF_FILE. Contact administrator.");
	}

	cbuf[0] = 0; /* Length zero */
	cbuf[1] = 0;

	if( *par3 != 0 )
	{
		strncat( &cbuf[1], par3, 126 );
	}

	if ( argc >1 )
	{
		for (i=1;i<argc;i++)
		{
			if( ( (*par3 != 0) && (i == 1) ) || ( i != 1) )
				strncat ( &cbuf[1], " ", 126);
			strncat ( &cbuf[1], argv[i], 126);
		}
	}

	cbuf[127] = 0;
	cbuf[0] = (int)strlen( &cbuf[1] );

	file_splitt(par2,path,file);
	if ( SetPath(path) != TRUE )
	{
		sprintf(errstr, "SetPath(%s) error", path);
		servererr("200",errstr);
		return(0);
	}

return( (INT)Pexec( 0, par2, cbuf, NULL ) );
}

static void servererr(char *status, char *msg)
{

		printf("HTTP/1.0 %s ok\n",status);
		printf("Content-type: text/html%c%c",10,10);
		printf("<html><title>NPH-PROT Server Error</title>");
		printf("<body><h1>NPH-PROT Server Error</h1>");
		printf("This server encountered an error:<p>");
		printf("%s</body></html>", msg);

exit(0);
}

/* Extraction des elements (tokens) d'une chaine */

static void ProcessLine(BYTE *line, BYTE *s, BYTE *p1, BYTE *p2, BYTE *p3, LONG limit)
{
char	*pos,*token;
int i;

	for(i=0;line[i]!=0;i++)	if(line[i]==9)	line[i]=32;	/* Allow TAB */

	pos = strchr(line, ';');
	if (pos) *pos = EOS;
	
	pos = strchr(line, '\n');
	if (pos) *pos = EOS;
	
	token = strtok(line, " ");
	
	*s = *p1 = *p2 = *par3 = EOS;
	
	if (token)
	{
		*s=0;
		strncat(s, token, limit);
		strlwr(s);
		
		token = strtok(NULL, " ");
		
		if (token)
		{
			*p1=0;
			strncat(p1,	token,limit);
			token = strtok(NULL, " ");
			if (token)
			{
				*p2=0;
				strncat(p2,	token,limit);
				token = strtok(NULL, "\0");
				if (token)
				{
					*p3=0;
					strncat(p3, trim(token) ,limit);
				}
			}
		}
	}
}

/*-----------------------------------------------------------------------*
 * Suppression des espaces & tab en d‚but et fin de chaine <str>               *
 *-----------------------------------------------------------------------*/

static BYTE *trim (BYTE *str)
{
static char *s;
int i = 0;
BYTE chaine[MAXLINE+1];

  while ( (*(str + i) == ' ') || (*(str + i) == 0x09 ) )    i++;
  *chaine=0;
  strncat (chaine, (str + i),MAXLINE);

  s = chaine + strlen (chaine) - 1;
  for( ; ((*s == ' ')||(*s == 0x09)) && (s >= chaine) ; *s-- = 0);
  *str=0;
  strncat (str, chaine,MAXLINE);

return (str);
}

VOID file_splitt(const UBYTE *fullname, UBYTE *path, UBYTE *name)
{
	UBYTE	 *str;

	str = strrchr (fullname, '\\');

	if (path != NULL)
		path[0] = EOS;		/* schadet nix */
	if (name != NULL)
		name[0] = EOS;		/* ditto */

	if (str != NULL)
	{
		/* Dateinamen holen */
		if (name != NULL)
		{
			*name=0;
			strcat(name, str+1);
		}

		/* Pfad mit Laufwerk bestimmen */
		if (path != NULL)
		{
			WORD len =  (short)( str - (UBYTE *)fullname );
			strncpy(path, fullname, len);
			path[len] = EOS;
		}
	}
} /* file_split */

/* Changement de r‚pertoire , path est SANS \\ */

BOOLEAN SetPath(UBYTE *unixpath)
{
WORD	drive;

	/* Vient de QED souces (globals.c) : */

		unixpath[0] = nkc_toupper(unixpath[0]);
		if (unixpath[0] >= '1' && unixpath[0] <= '6')
			drive = unixpath[0] - '1' + 26;
		else
			drive = unixpath[0] - 'A';
		if ( Dsetdrv(drive) < 0 )			return(FALSE);
		if ( Dsetpath(unixpath + 2) ) return(FALSE);

return(TRUE);
}

/* ---          EOF                 --- */
