/*
FILE 
	main.c
	$Id: main.c 10 2005-12-03 15:14:38Z ggw $
PURPOSE
	mysqlRAD2.cgi created application file for mysqlSendmail.cgi
	(tAuthorize.cPasswd template set)
AUTHOR
	Template and mysqlRAD2 author: (c) Gary Wallis 2001,2002.
	GPL License applies, see www.fsf.org for details.

	mysqlSendmail GPL license included in distribution.
	(C) 2001-2004, Gary Wallis.
OTHER
	See local.h, makefile and docs as well as tConfiguration.cComment's
	
	
HELP
	support @ openisp . net

*/

#include "mysqlrad.h"
#include <ctype.h>
#ifdef Solaris
        char *crypt(char *passwd, char *salt);
#endif

#include "language.h"
#include "local.h"

//Global vars
unsigned uGlobalSSLConnection=0;
#define SHOWPAGE 30
MYSQL mysql;
MYSQL mysql2;
unsigned long rowid;
unsigned start;
unsigned end;
unsigned i;
unsigned n=SHOWPAGE;
char command[100];
char filter[100];
char find[100];
char table[100];
int mode;

int uPermLevel=0;
unsigned uLoginClient=0;
unsigned uReseller=0;
char cUser[100]={""};
char cHost[100]={""};
char cHostname[100]={""};

 //SSLLoginCookie()
char cCookie[1024]={""};
char cLogin[100]={""};
char cPasswd[100]={""};
unsigned uSSLCookieLogin=0;

char function[100]={""};
char query[8192]={""};
char *qstr=query;

 //Local
void Footer_ism3(void);
void Header_ism3(char *msg, int js);
char *EmailInput(char *cInput);
void GetClientOwner(unsigned uClient, unsigned *uOwner);
char *cGetUserPasswd(char *cLogin);
//uPermLevel==5 experimental feature functions
typedef struct t_template {
        char *name[8];//pointers to var_name strings
        char *value[8];//pointers to substitution strings
} t_template ;
void tUserChangePasswd(char *cMsg);
void tUserChangedPasswdOk(char *cMsg);
int htmlStructTemplate(char *cTemplateName,struct t_template *ptrTemplate);
void Template(char *cTemplate, struct t_template *template, FILE *fp);
void htmlTemplatePage(char *cPage);
void GetuUseruServer(char *cUser,unsigned *uUser,unsigned *uServer);


 //Ext
int ExtMainCommands(pentry entries[], int x);
void ExtMainContent(void);
void ExtMainShell(int argc, char *argv[]);
void tUserChangePasswdLogin(char *cMsg);//tuserfunc.h

 //Only local
void ConnectDb(void);
void NoSuchFunction(void);
void mysqlSendmail(const char *result);
void InitialInstall(void);
char *UserLevel(unsigned uPermLevel);

int ValidLogin(int mode);
void SSLCookieLogin(void);
void SetLogin(unsigned uMode);
void EncryptPasswdWithSalt(char *pw, char *salt);
void GetPLAndClient(char *cUser);
void GetUserPLAndClient(char *cUser);
void htmlSSLLogin(void);

static unsigned uAllowUserFormOnly=1;

int main(int argc, char *argv[])
{
	pentry entries[64];
	entry gentries[16];
	char *gcl;
	register int x;
	int cl=0;

#if defined(Linux)
	gethostname(cHostname, 98);
#else
	//Solaris
	sysinfo(SI_HOSTNAME, cHostname, 98);
#endif

	//Special user form must be called via
	//symbolic link or program name change
	if(strstr(argv[0],"mysqlSendmail.cgi"))
		uAllowUserFormOnly=0;

	if(getenv("REMOTE_HOST")!=NULL)
	{
		ConnectDb();
		sprintf(cHost,"%.99s",getenv("REMOTE_HOST"));
	}
	else if(getenv("REMOTE_ADDR")!=NULL)
	{
		ConnectDb();
		sprintf(cHost,"%.99s",getenv("REMOTE_ADDR"));
	}
	else
	{
		ExtMainShell(argc,argv);
	}


	if(strcmp(getenv("REQUEST_METHOD"),"POST"))
	{

		SSLCookieLogin();

	        gcl = getenv("QUERY_STRING");

	        for(x=0;gcl[0] != '\0' && x<8;x++)
		{
               		getword(gentries[x].val,gcl,'&');
               		plustospace(gentries[x].val);
               		unescape_url(gentries[x].val);
               		getword(gentries[x].name,gentries[x].val,'=');

			//basic anti hacker
			escape_shell_cmd(gentries[x].val);

			//Local vars
			if(!strcmp(gentries[x].name,"function")) 
				sprintf(function,"%.99s",gentries[x].val);
		}

		if(function[0])
		{
			if(!strcmp(function,"Main"))
			{
				sprintf(query,"%s %s",RELEASE,cHostname);
				mysqlSendmail(query);
			}
			else if(!strcmp(function,"Logout"))
			{
				printf("Set-Cookie: mysqlSendmailLogin=; expires=0\n");
				printf("Set-Cookie: mysqlSendmailPasswd=; expires=0\n");
				cCookie[0]=0;
                                uPermLevel=0;
                                uLoginClient=0;
                                cUser[0]=0;
                                uSSLCookieLogin=0;
                                htmlSSLLogin();
			}
			else if(!strcmp(function,"tUser"))
				ExttUserGetHook(gentries,x);
			else if(!strcmp(function,"tAlias"))
				ExttAliasGetHook(gentries,x);
			else if(!strcmp(function,"tDomain"))
				ExttDomainGetHook(gentries,x);
			else if(!strcmp(function,"tVUT"))
				ExttVUTGetHook(gentries,x);
			else if(!strcmp(function,"tVUTEntries"))
				ExttVUTEntriesGetHook(gentries,x);
			else if(!strcmp(function,"tDUL"))
				ExttDULGetHook(gentries,x);
			else if(!strcmp(function,"tAccess"))
				ExttAccessGetHook(gentries,x);
			else if(!strcmp(function,"tLocal"))
				ExttLocalGetHook(gentries,x);
			else if(!strcmp(function,"tJob"))
				ExttJobGetHook(gentries,x);
			else if(!strcmp(function,"tUsage"))
				ExttUsageGetHook(gentries,x);
			else if(!strcmp(function,"tConfiguration"))
				ExttConfigurationGetHook(gentries,x);
			else if(!strcmp(function,"tServer"))
				ExttServerGetHook(gentries,x);
			else if(!strcmp(function,"tJobStatus"))
				ExttJobStatusGetHook(gentries,x);
			else if(!strcmp(function,"tStatus"))
				ExttStatusGetHook(gentries,x);
			else if(!strcmp(function,"tHDQuota"))
				ExttHDQuotaGetHook(gentries,x);
			else if(!strcmp(function,"tTrafficQuota"))
				ExttTrafficQuotaGetHook(gentries,x);
			else if(!strcmp(function,"tMailFilter"))
				ExttMailFilterGetHook(gentries,x);
			else if(!strcmp(function,"tClient"))
				ExttClientGetHook(gentries,x);
			else if(!strcmp(function,"tAuthorize"))
				ExttAuthorizeGetHook(gentries,x);


		}

		//End user interface get force logged in page
		if(uPermLevel==5)
			tUserChangePasswd("Please enter your new password twice");

		mysqlSendmail(ISPNAME);

	}//end get method interface section

	//Post method interface
	cl = atoi(getenv("CONTENT_LENGTH"));
	for(x=0;cl && (!feof(stdin)) && x<64 ;x++)
	{
		entries[x].val = fmakeword(stdin,'&',&cl);
		plustospace(entries[x].val);
		unescape_url(entries[x].val);
		entries[x].name = makeword(entries[x].val,'=');

		//basic anti hacker
		//Allow posted page cursors. See PageMachine()
		//escape_shell_cmd(entries[x].val);

		if(!strcmp(entries[x].name,"function")) 
			sprintf(function,"%.99s",entries[x].val);
		else if(!strcmp(entries[x].name,"cLogin"))
			sprintf(cLogin,"%.99s",entries[x].val);
                else if(!strcmp(entries[x].name,"cPasswd"))
			sprintf(cPasswd,"%.99s",entries[x].val);
	}

	//SSLCookieLogin()
        if(!strcmp(function,"UserLogin")) SetLogin(1);
        if(!strcmp(function,"Login")) SetLogin(0);

        if(!uPermLevel || !cUser[0] || !uLoginClient)
                SSLCookieLogin();

	//Main Post Menu
	tUserCommands(entries,x);

	if(uPermLevel>5)
	{
		tAliasCommands(entries,x);
		tDomainCommands(entries,x);
		tVUTCommands(entries,x);
		tVUTEntriesCommands(entries,x);
		tDULCommands(entries,x);
		tAccessCommands(entries,x);
		tLocalCommands(entries,x);
		tJobCommands(entries,x);
		tUsageCommands(entries,x);
		tConfigurationCommands(entries,x);
		tServerCommands(entries,x);
		tJobStatusCommands(entries,x);
		tStatusCommands(entries,x);
		tHDQuotaCommands(entries,x);
		tTrafficQuotaCommands(entries,x);
		tMailFilterCommands(entries,x);
		tClientCommands(entries,x);
		tAuthorizeCommands(entries,x);


		ExtMainCommands(entries,x);

		NoSuchFunction();
	}
	else
		SetLogin(1);

	return(0);

}//end of main()

#include "mainfunc.h"

void mysqlSendmail(const char *result)
{
	Header_ism3("Main",0);

	printf("<table border=0 width=900>"); 
	printf("<tr><td bgcolor=#9BC1B3>");
	printf("<font face=Arial,Helvetica>%s",result);
	printf("</td>");
	printf("</tr>");
	printf("</table>\n");

	printf("<table border=0 width=900>\n"); 
	printf("<tr><td>");
	ExtMainContent();
	printf("</td></tr>");
	printf("</table>\n");

	Footer_ism3();

}//void mysqlSendmail(char *result)


void StyleSheet(void)
{
        printf("<style type=\"text/css\">\n");
        printf("<!--\n");

        printf("input.smallButton {width:50px;}\n");
        printf("input.medButton {width:100px;}\n");
        printf("input.largeButton {width:150px;}\n");
        printf("input.warnButton {color:red;}\n");
        printf("input.lwarnButton {color:red;width:150px;}\n");
        printf("input.alertButton {color:yellow;}\n");
        printf("input.lalertButton {color:yellow;width:150px;}\n");
        printf("input.revButton {color:white;background:black;}\n");
        printf("input.lrevButton {color:white;background:black;width:150px;}\n");
        printf("A.darkLink {color:black; text-decoration:none;}\n");
	printf("A.darkLink:hover {color:yellow; text-decoration:underline;}\n");
        printf("A:hover {color:yellow; text-decoration:underline;}\n");

	printf("textarea {font-family: Arial,Helvetica; font-size: 11px;}\n");
	printf("pre {font-family: Arial,Helvetica; font-size: 11px;}\n");
	//printf("input {font-family: Arial,Helvetica; font-size: 11px;}\n");
	printf("select {font-family: Arial,Helvetica;}\n");
	//printf("body {font-family: Arial,Helvetica; font-size: 11px;}\n");


        printf("-->\n");
        printf("</style>\n");

}//void StyleSheet(void)

char *UserLevel(unsigned uPermLevel)
{
	switch(uPermLevel)
	{
		case 12:
			return("Root");
		break;
		case 10:
			return("Admin");
		break;
		case 8:
			return("Reseller");
		break;
		case 7:
			return("Customer");
		break;
		case 5:
			return("User");
		break;
		default:
			return("---");
		break;
	}

}//char *UserLevel(unsigned uPermLevel)


void Header_ism3(char *title, int js)
{
	printf("Content-type: text/html\n\n");
	printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");
        printf("<html><head><title>mysqlSendmail %s </title>",title);
	printf("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n");
	StyleSheet();
	printf("</head>\n<body vlink=#d0d0d0 link=#ffffff bgcolor=#76A7CB ><font face=Arial,Helvetica>\n");

	//For optional Java Scripts	
	/*
	if(js)
	{
		switch(js)
		{
			case 1:
			break;

			case 2:
			break;

			default:
			break;
		}
	}
	*/

	printf("<center><table border=0 cellspacing=0 cellpadding=0 width=900 bgcolor=#000000><tr><td width=400 valign=center>\n");
        printf("<font size=4 face=Arial,Helvetica color=#ffffff >mysqlSendmail %s",title);

        printf("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
	printf("<td width=500 valign=bottom><font face=Arial,Helvetica size=1 color=white>");
	printf("<a title='Start page' href=mysqlSendmail.cgi?function=Main>Main</a> ");

	//Generate Menu Items
#ifdef PERMLEVEL
	if(uPermLevel>=5)
#endif
	printf("<a title='Pop3 Users' href=mysqlSendmail.cgi?function=tUser>tUser</a>\n");
#ifdef PERMLEVEL
	if(uPermLevel>=10)
#endif
	printf("<a title='sendmail aliases file image' href=mysqlSendmail.cgi?function=tAlias>tAlias</a>\n");
#ifdef PERMLEVEL
	if(uPermLevel>=8)
#endif
	printf("<a title='Domains' href=mysqlSendmail.cgi?function=tDomain>tDomain</a>\n");
#ifdef PERMLEVEL
	if(uPermLevel>=7)
#endif
	printf("<a title='sendmail virtual user table domains' href=mysqlSendmail.cgi?function=tVUT>tVUT</a>\n");

/*
#ifdef PERMLEVEL
	if(uPermLevel>=12)
#endif
	printf("<a title='sendmail virtual user table entries' href=mysqlSendmail.cgi?function=tVUTEntries>tVUTEntries</a>\n");
*/

#ifdef PERMLEVEL
	if(uPermLevel>=10)
#endif
	printf("<a title='Dialup user list of relay authorized IPs' href=mysqlSendmail.cgi?function=tDUL>tDUL</a>\n");
#ifdef PERMLEVEL
	if(uPermLevel>=8)
#endif
	printf("<a title='Sendmail relay file' href=mysqlSendmail.cgi?function=tAccess>tAccess</a>\n");
#ifdef PERMLEVEL
	if(uPermLevel>=8)
#endif
	printf("<a title='Sendmail cw file of local domains' href=mysqlSendmail.cgi?function=tLocal>tLocal</a>\n");
#ifdef PERMLEVEL
	if(uPermLevel>=7)
#endif
	printf("<a title='Local job queue' href=mysqlSendmail.cgi?function=tJob>tJob</a>\n");
#ifdef PERMLEVEL
	if(uPermLevel>=10)
#endif
	printf("<a title='SMTP and POP3 traffic per uClient' href=mysqlSendmail.cgi?function=tUsage>tUsage</a>\n");
#ifdef PERMLEVEL
	if(uPermLevel>=10)
#endif
	printf("<a title='Configuration' href=mysqlSendmail.cgi?function=tConfiguration>tConfiguration</a>\n");
#ifdef PERMLEVEL
	if(uPermLevel>=12)
#endif
	printf("<a title='Target Server' href=mysqlSendmail.cgi?function=tServer>tServer</a>\n");

/*
#ifdef PERMLEVEL
	if(uPermLevel>=12)
#endif
	printf("<a title='Job queue entry status' href=mysqlSendmail.cgi?function=tJobStatus>tJobStatus</a>\n");

#ifdef PERMLEVEL
	if(uPermLevel>=12)
#endif
	printf("<a title='User status' href=mysqlSendmail.cgi?function=tStatus>tStatus</a>\n");
#ifdef PERMLEVEL
	if(uPermLevel>=12)
#endif
	printf("<a title='Preset HD quotas' href=mysqlSendmail.cgi?function=tHDQuota>tHDQuota</a>\n");
#ifdef PERMLEVEL
	if(uPermLevel>=12)
#endif
	printf("<a title='Preset traffic quotas' href=mysqlSendmail.cgi?function=tTrafficQuota>tTrafficQuota</a>\n");
#ifdef PERMLEVEL
	if(uPermLevel>=12)
#endif
	printf("<a title='Mail filter' href=mysqlSendmail.cgi?function=tMailFilter>tMailFilter</a>\n");
*/


#ifdef PERMLEVEL
	if(uPermLevel>=8)
#endif
	printf("<a title='Client Info' href=mysqlSendmail.cgi?function=tClient>tClient</a>\n");

/*
#ifdef PERMLEVEL
	if(uPermLevel>=8)
#endif
	printf("<a title='Login Authorization' href=mysqlSendmail.cgi?function=tAuthorize>tAuthorize</a>\n");
*/


	printf("<br><font size=3></font><font color=red>%s logged in from %s [%s]",cUser,cHost,UserLevel(uPermLevel));

	if(uSSLCookieLogin)
		printf(" <a title='Erase login cookies' href=mysqlSendmail.cgi?function=Logout>Logout</a> ");

        printf("</td></tr></table>");


}//Header_ism3(char *title, int js)

void Footer_ism3(void)
{
printf("<center><hr width=900><font face=Arial,Helvetica color=#c0c0c0 size=1>\n");
printf("<a href=http://%s>%s</a> Powered: &copy; <a href=http://www.unixservice.com>Unixservice</a>, 2002-2005</body></html>\n",EXTISPURL,EXTISPNAME);

mysql_close(&mysql);

exit(0);

}//Footer_ism3(void)


//MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag)
void ConnectDb(void)
{
        mysql_init(&mysql);
        if (!mysql_real_connect(&mysql,DBIP,DBLOGIN,DBPASSWD,DBNAME,DBPORT,DBSOCKET,0))
                mysqlSendmail("Database server unavailable. Did you run mysqlISP.cgi Initialize &lt;mysqlpwd&gt;?");

}//end of ConnectDb()


void NoSuchFunction(void)
{
	 
	sprintf(query,"[%s] Not Recognized",function);
	mysqlSendmail(query);
}

void ProcessControlVars(pentry entries[], int x)
{
	register int i;

	for(i=0;i<x;i++)
	{
		if(!strcmp(entries[i].name,"filter"))
			strcpy(filter,entries[i].val);
		else if(!strcmp(entries[i].name,"command"))
			strcpy(command,entries[i].val);
		else if(!strcmp(entries[i].name,"find"))
			strcpy(find,entries[i].val);
		else if(!strcmp(entries[i].name,"rowid"))
			sscanf(entries[i].val,"%lu",&rowid);
	}
}

void PageMachine(char *funcName, int lmode, char *msg)
{
	
if(lmode)
{
	//List mode
	
	if(rowid<1) rowid=1;
	if(rowid>(n=((i/SHOWPAGE)+1))) rowid=n;

	if(!strcmp(find," >"))
	{
		//If NOT on last page show next page
		if( rowid >= n-1 )
		{
			//If on last page adjust end
			start= ((i/SHOWPAGE)*SHOWPAGE) + 1;
			end=i;
		}
		else
		{
			start=((rowid)*SHOWPAGE)+1;
			end=start+SHOWPAGE-1;
			rowid++;
		}
	}
	else if(!strcmp(find,"< "))
	{
		if(rowid>1 )
		{
			rowid--;
			start=(rowid)*SHOWPAGE-SHOWPAGE+1;
			end=start+SHOWPAGE-1;
		}
		else
		{
			start=1;
			if(i > SHOWPAGE)
			{
				end=SHOWPAGE;
			}
			else
			{
				end=i;
			}
			rowid=1;
		}
	}
	else if(!strcmp(find,">>"))
	{
		start= ((i/SHOWPAGE)*SHOWPAGE) + 1;
		end=i;
		rowid=n;
	}
	else if(1)
	{
		start=1;
		if(i > SHOWPAGE)
		{
			end=SHOWPAGE;
		}
		else
		{
			end=i;
		}
		rowid=1;
	}

	Header_ism3(funcName,0);

	if(!i) 
        {
                printf(LANG_PAGEMACHINE_HINT);

        }
 

        printf("</center><form action=mysqlSendmail.cgi method=post >\n");

        printf("<font size=2><table width=900 border=0 ><tr><td>");
        printf("<input style='width:20px;' type=submit name=find value=\"<<\" >");
        printf("<input style='width:20px;' type=submit name=find value=\"< \" >");
        printf(LANG_PAGEMACHINE_SEARCH);
        printf("<input style='width:20px;' type=submit name=find value=\" >\" >");
        printf("<input style='width:20px;' type=submit name=find value=\">>\" >\n");
        printf(LANG_PAGEMACHINE_SHOWING,1+(start/SHOWPAGE),n,start,end,i);


	printf("<input type=hidden name=rowid value=%lu>",rowid);
	printf("<input type=hidden name=function value=%s >\n",funcName);
	if(table[0])
	{
		printf("<input type=hidden name=table value=%s >\n",table);
		printf(" <font color=blue>%s</font>",table);
	}
	
}
else
{
	//Page mode
	//on entry i has number of rows
	//on entry rowid has current position unless i=1
	//if i=1 then we need to figure out real i

	n=i;

	if(rowid<1)
	{
		rowid=1;
		return;
	}
	
	if(!strcmp(find," >"))
	{
		//If on last page stay there
		if( rowid >= i )
		{
			//If on last page adjust end
			rowid=i;
		}
		else
		{
			rowid++;
		}
	}
	else if(!strcmp(find,"< "))
	{
		if(rowid>1 )
		{
			rowid--;
		}
		else
		{
			rowid=1;
		}
	}
	else if(!strcmp(find,">>"))
	{
		rowid=i;
	}
	else if(!strcmp(find,"<<"))
	{
		rowid=1;
	}
	else if(1)
	{
		//If on last page stay there
		if( rowid >= i )
		{
			rowid=i;
		}
	}

}//end lmode

}//PageMachine()


void OpenRow(char *label, char *color)
{
	printf("<tr><td width=25%% valign=top><font size=2 face=Arial,Helvetica color=%s>%s</td><td valign=top><font size=2 face=Arial,Helvetica color=black>",
			color,label);

}//void OpenRow(char *label)


void tTablePullDownOwner(char *cTableName, char *cFieldName,
                        char *cOrderby, int unsigned uSelector)
{
        char label[128];
        MYSQL_RES *res;         
        MYSQL_ROW field;

        char cSelectName[34]={""};
        char cLocalTableName[256]={""};
        char *cp;

        register int i,n;
      
        if(!cTableName[0] || !cFieldName[0] || !cOrderby[0])
        {
                printf("Invalid input tTablePullDown()");
                return;
        }

        //Extended functionality
        strncpy(cLocalTableName,cTableName,255);
        if((cp=strchr(cLocalTableName,';')))
        {
                strncpy(cSelectName,cp+1,32);
                cSelectName[32]=0;
                *cp=0;
        }


	if(uPermLevel<10)
        	sprintf(query,"SELECT _rowid,%s FROM %s WHERE uOwner=%u ORDER BY %s",
                                cFieldName,cLocalTableName,uLoginClient,cOrderby);
	else
        	sprintf(query,"SELECT _rowid,%s FROM %s ORDER BY %s",
                                cFieldName,cLocalTableName,cOrderby);

        mysql_query(&mysql,query);
	if(mysql_errno(&mysql))
        {
                printf("%s",mysql_error(&mysql));
                return;
        }
	res=mysql_store_result(&mysql);
	i=mysql_num_rows(res);

	if(cSelectName[0])
                sprintf(label,"%s",cSelectName);
        else
                sprintf(label,"%s_%sPullDown",cLocalTableName,cFieldName);

        if(i>0)
        {
                printf("<select name=%s>\n",label);

                //Default no selection
                printf("<option>---</option>\n");

                for(n=0;n<i;n++)
                {
                        int unsigned field0=0;

                        field=mysql_fetch_row(res);
                        sscanf(field[0],"%u",&field0);

                        if(uSelector != field0)
                        {
                                printf("<option>%s</option>\n",field[1]);
                        }
                        else
                        {
                                printf("<option selected>%s</option>\n",field[1]);
                        }
                }
        }
        else
        {
        printf("<select name=%s><option>---</option></select>\n"
                        ,label);
        }
        printf("</select>\n");

}//tTablePullDownOwner()


void tTablePullDown(char *cTableName, char *cFieldName,
                        char *cOrderby, int unsigned uSelector)
{
        char label[128];
        MYSQL_RES *res;         
        MYSQL_ROW field;

        char cSelectName[34]={""};
        char cLocalTableName[256]={""};
        char *cp;

        register int i,n;
      
        if(!cTableName[0] || !cFieldName[0] || !cOrderby[0])
        {
                printf("Invalid input tTablePullDown()");
                return;
        }

        //Extended functionality
        strncpy(cLocalTableName,cTableName,255);
        if((cp=strchr(cLocalTableName,';')))
        {
                strncpy(cSelectName,cp+1,32);
                cSelectName[32]=0;
                *cp=0;
        }


        sprintf(query,"select _rowid,%s from %s order by %s",
                                cFieldName,cLocalTableName,cOrderby);

        mysql_query(&mysql,query);
	if(mysql_errno(&mysql))
        {
                printf("%s",mysql_error(&mysql));
                return;
        }
	res=mysql_store_result(&mysql);
	i=mysql_num_rows(res);

	if(cSelectName[0])
                sprintf(label,"%s",cSelectName);
        else
                sprintf(label,"%s_%sPullDown",cLocalTableName,cFieldName);

        if(i>0)
        {
                printf("<select name=%s>\n",label);

                //Default no selection
                printf("<option>---</option>\n");

                for(n=0;n<i;n++)
                {
                        int unsigned field0=0;

                        field=mysql_fetch_row(res);
                        sscanf(field[0],"%u",&field0);

                        if(uSelector != field0)
                        {
                                printf("<option>%s</option>\n",field[1]);
                        }
                        else
                        {
                                printf("<option selected>%s</option>\n",field[1]);
                        }
                }
        }
        else
        {
        printf("<select name=%s><option>---</option></select>\n"
                        ,label);
        }
        printf("</select>\n");

}//tTablePullDown()


void tTablePullDownReadOnly(char *cTableName, char *cFieldName,
                        char *cOrderby, int unsigned uSelector)
{
        MYSQL_RES *res;         
        MYSQL_ROW field;

        char cSelectName[34]={""};
        char label[100]={""};
        char cLocalTableName[256]={""};
        char *cp;

        if(!cTableName[0] || !cFieldName[0] || !cOrderby[0])
        {
                printf("Invalid input tTablePullDown()");
                return;
        }

        //Extended functionality
        strncpy(cLocalTableName,cTableName,255);
        if((cp=strchr(cLocalTableName,';')))
        {
                strncpy(cSelectName,cp+1,32);
                cSelectName[32]=0;
                *cp=0;
        }

	sprintf(query,"select _rowid,%s from %s where _rowid=%u",
                                cFieldName,cLocalTableName,uSelector);

        mysql_query(&mysql,query);
        if(mysql_errno(&mysql))
        {
                printf("%s",mysql_error(&mysql));
                return;
        }
        res=mysql_store_result(&mysql);

        if(cSelectName[0])
                sprintf(label,"%s",cSelectName);
        else
                sprintf(label,"%s_%sPullDown",cLocalTableName,cFieldName);


        if(mysql_num_rows(res))
        {
                field=mysql_fetch_row(res);
                printf("%s\n",field[1]);
                printf("<input type=hidden value=\"%s\" name=%s>",
                                                field[1],label);
        }
        else
        {
                printf("---\n");
        }

}//tTablePullDownReadOnly()


int ReadPullDown(char *cTableName,char *cFieldName,char *cLabel)
{
        MYSQL_RES *res;
        MYSQL_ROW field;

        unsigned int rowid=0;//Not found

        sprintf(query,"select _rowid from %s where %s='%s'",
                        cTableName,cFieldName,TextAreaSave(cLabel));
        mysql_query(&mysql,query);
        if(mysql_errno(&mysql)) mysqlSendmail(mysql_error(&mysql));
        res=mysql_store_result(&mysql);
        if((field=mysql_fetch_row(res)))
        	sscanf(field[0],"%u",&rowid);
        mysql_free_result(res);
        return(rowid);

}//ReadPullDown(char *cTableName,char *cLabel)


const char *TextAreaSave(const char *cField)
{
	register unsigned int i=0,j=0,uNum=0,uCtrlM=0;
	char *cCopy=NULL;

	for(i=0;cField[i];i++)
	{
		if(cField[i]=='\'' || cField[i]=='\\') uNum++;
		if(cField[i]=='\r') uCtrlM++;
	}
	if(!uNum && !uCtrlM) return(cField);

	if(uNum)
		cCopy=(char *)malloc( ( (strlen(cField)) + (uNum*2) + 1 ));
	else
		cCopy=(char *)cField;

	if(!cCopy) mysqlSendmail("TextAreaInput() malloc error");

	i=0;
	while(cField[i])
	{
		if( cField[i]=='\'' )
		{
			cCopy[j++]='\\';
			cCopy[j++]='\'';
		}
		else if( cField[i]=='\\')
		{
			cCopy[j++]='\\';
			cCopy[j++]='\\';
		}
		
		//Remove nasty ctrl-m's. fsck /u Bill!
		else if(cField[i]!='\r')
		{
			cCopy[j++]=cField[i];
		}
		i++;
	}

	cCopy[j]=0;
	return(cCopy);

}//char *TextAreaSave(char *cField)


const char *TransformAngleBrackets(const char *cField)
{
	register unsigned int i=0,j=0,uNum=0;
	char *cCopy=NULL;

	for(i=0;cField[i];i++)
		if(cField[i]=='<' || cField[i]=='>') uNum++;
	if(!uNum) return(cField);
	cCopy=(char *)malloc( ( (strlen(cField)) + (uNum*4) + 1 ));

	if(!cCopy) mysqlSendmail("TransformAngleBrackets() malloc error");

	i=0;
	while(cField[i])
	{
		//Expand angle brackets into HTML codes
		if( cField[i]=='<' )
		{
			cCopy[j++]='&';
			cCopy[j++]='l';
			cCopy[j++]='t';
			cCopy[j++]=';';
		}
		else if( cField[i]=='>' )
		{
			cCopy[j++]='&';
			cCopy[j++]='g';
			cCopy[j++]='t';
			cCopy[j++]=';';
		}
		else if(1)
                {
                        cCopy[j++]=cField[i];
                }
		i++;
	}

	cCopy[j]=0;
	return(cCopy);

}//char *TransformAngleBrackets(char *cField)


const char *EncodeDoubleQuotes(const char *cField)
{
	register unsigned int i=0,j=0,uNum=0;
	char *cCopy=NULL;

	for(i=0;cField[i];i++)
		if(cField[i]=='"') uNum++;
	if(!uNum) return(cField);
	cCopy=(char *)malloc( ( (strlen(cField)) + (uNum*5) + 1 ));

	if(!cCopy) mysqlSendmail("EncodeDoubleQuotes() malloc error");

	i=0;
	while(cField[i])
	{
		//Expand double quote into HTML codes
		if( cField[i]=='"' )
		{
			cCopy[j++]='&';
			cCopy[j++]='q';
			cCopy[j++]='u';
			cCopy[j++]='o';
			cCopy[j++]='t';
			cCopy[j++]=';';
		}
		else if(1)
                {
                        cCopy[j++]=cField[i];
                }
		i++;
	}

	cCopy[j]=0;
	return(cCopy);

}//char *EncodeDoubleQuotes(char *cField)


void YesNo(unsigned uSelect)
{
        if(uSelect)
                printf("Yes");
        else
                printf("No");

}//YesNo()


void YesNoPullDown(char *cFieldName, unsigned uSelect)
{
	printf("<select name=cYesNo%s>\n",cFieldName);
        if(uSelect==0)
                printf("<option selected>No</option>\n");
        else
                printf("<option>No</option>\n");
        if(uSelect==1)
                printf("<option selected>Yes</option>\n");
        else    
                printf("<option>Yes</option>\n");

        printf("</select>\n");

}//YesNoPullDown()


int ReadYesNoPullDown(char *cLabel)
{
        if(!strcmp(cLabel,"Yes"))
                return(1);
        else
                return(0);

}//ReadYesNoPullDown(char *cLabel)


const char *ForeignKey(const char *cTableName, const char *cFieldName, unsigned uKey)
{
        MYSQL_RES *res;
        MYSQL_ROW field;

        sprintf(query,"SELECT %s FROM %s WHERE _rowid=%u",
                        cFieldName,cTableName,uKey);
        mysql_query(&mysql,query);
        if(mysql_errno(&mysql)) return(mysql_error(&mysql));

        res=mysql_store_result(&mysql);
        if(mysql_num_rows(res)==1)
        {
                field=mysql_fetch_row(res);
                return(field[0]);
        }

        return("---");

}//char *ForeignKey(char *cTableName, char *cFieldName, unsigned uKey)


void InitialInstall(void)
{
	mysqlSendmail("Please run\
		mysqlSendmail.cgi Initialize &lt;mysqlpwd&gt; from the command line");

}//void InitialInstall(void)


char *IPNumber(char *cInput)
{
	unsigned a=0,b=0,c=0,d=0;

	sscanf(cInput,"%u.%u.%u.%u",&a,&b,&c,&d);

	if(a>255) a=0;
	if(b>255) b=0;
	if(c>255) c=0;
	if(d>255) d=0;

	sprintf(cInput,"%u.%u.%u.%u",a,b,c,d);

	return(cInput);

}//char *IPNumber(char *cInput)

 //tValidFunc functions: Form validation feedback

char *IsZero(unsigned uInput)
{
        if(uInput)
                return("white");
        else
                return("red");

}//char *IsZero(unsigned uInput)
 
char *BadIPNum(char *cInput)
{ 
        if( cInput!=NULL && cInput[0] && strcmp(cInput,"0.0.0.0"))
                return("white");
        else
                return("red");

}//char *BadIPNum(char *cInput)

char *EmptyString(char *cInput)
{
        if(cInput!=NULL && cInput[0])
                return("white");
        else
                return("red");

}//char *EmptyString(char *cInput) 


 //tInputFunc functions: Save data to table

char *EmailInput(char *cInput)
{
	register int i;

	for(i=0;cInput[i];i++)
	{
	
		if(!isalnum(cInput[i]) && cInput[i]!='.'  && cInput[i]!='-' 
				&& cInput[i]!='@' && cInput[i]!='_')
			break;
		if(isupper(cInput[i])) cInput[i]=tolower(cInput[i]);
	}
	cInput[i]=0;

	return(cInput);

}//char *EmailInput(char *cInput)


char *FQDomainName(char *cInput)
{
	register int i;

	for(i=0;cInput[i];i++)
	{
	
		if(!isalnum(cInput[i]) && cInput[i]!='.'  && cInput[i]!='-' )
			break;
		if(isupper(cInput[i])) cInput[i]=tolower(cInput[i]);
	}
	cInput[i]=0;

	return(cInput);

}//char *FQDomainName(char *cInput)


char *WordToLower(char *cInput)
{
	register int i;

	for(i=0;cInput[i];i++)
	{
	
		if(!isalnum(cInput[i]) && cInput[i]!='_' 
					&& cInput[i]!='-' 
					&& cInput[i]!='.' ) 
							break;
		if(isupper(cInput[i])) cInput[i]=tolower(cInput[i]);
	}
	cInput[i]=0;

	return(cInput);

}//char *WordToLower(char *cInput)


char *EmailUser(char *cInput)
{
	register int i;

	for(i=0;cInput[i];i++)
	{

		if(i==0 && isdigit(cInput[i])) break;
		if(!isalnum(cInput[i]) && cInput[i]!='_' && cInput[i]!='-' 
				&& cInput[i]!='.' ) break;
		if(isupper(cInput[i])) cInput[i]=tolower(cInput[i]);
	}
	cInput[i]=0;

	return(cInput);

}//char *EmailUser(char *cInput)


void SetLogin(unsigned uMode)
{
	if( ValidLogin(0) )
	{
		printf("Set-Cookie: mysqlSendmailLogin=%s;\n",cLogin);
		printf("Set-Cookie: mysqlSendmailPasswd=%s;\n",cPasswd);
		strncpy(cUser,cLogin,41);
		GetPLAndClient(cUser);
		if(!uPermLevel)
			GetUserPLAndClient(cUser);
		uSSLCookieLogin=1;
		if(uPermLevel==5)
			tUserChangePasswd("Please enter your new password twice");
		else
			mysqlSendmail("Logged in");
	}
	else
	{
		uSSLCookieLogin=0;
		if(!uMode)
			SSLCookieLogin();
		else
			tUserChangePasswdLogin(cHost);
	}
				
}//void SetLogin(unsigned uMode)


char *cGetPasswd(char *cLogin);
int ValidLogin(int mode)
{
	char cSalt[16];
	char cPassword[100]={""};

	//Notes:
	//Mode=1 means we have encrypted passwd from cookie

	strcpy(cPassword,cGetPasswd(cLogin));
	if(cPassword[0])
	{
		if(!mode)
		{
			sprintf(cSalt,"%.12s",cPassword);
			//MD5 Hack
			//$1$abcdefgh$
			if(cSalt[0]!='$') cSalt[2]=0;
			EncryptPasswdWithSalt(cPasswd,cSalt);
			if(!strcmp(cPasswd,cPassword)) return 1;
		}
		else
		{
			if(!strcmp(cPasswd,cPassword)) return 1;
		}
	}
	//Experimental code for all users to get auto enabled uPermLevel=5
	else
	{
		strcpy(cPassword,cGetUserPasswd(cLogin));
		if(cPassword[0])
		{
			if(!mode)
			{
				sprintf(cSalt,"%.12s",cPassword);
				if(cSalt[0]!='$') cSalt[2]=0;
				EncryptPasswdWithSalt(cPasswd,cSalt);
				if(!strcmp(cPasswd,cPassword)) return 1;
			}
			else
			{
				if(!strcmp(cPasswd,cPassword)) return 1;
			}
		}

		return(0);
	}
	return 0;

}//ValidLogin()


char *cGetUserPasswd(char *cLogin)
{
	static char cPasswd[100]={""};
        MYSQL_RES *res;
        MYSQL_ROW field;

	sprintf(query,"SELECT cPasswd FROM tUser WHERE cLogin='%s'",
			cLogin);
	mysql_query(&mysql,query);
	if(mysql_errno(&mysql))
			mysqlSendmail(mysql_error(&mysql));
	res=mysql_store_result(&mysql);
	cPasswd[0]=0;
	if((field=mysql_fetch_row(res)))
		strcpy(cPasswd,field[0]);
	mysql_free_result(res);
	
	return(cPasswd);

}//char *cGetUserPasswd(char *cLogin)


char *cGetPasswd(char *cLogin)
{
	static char cPasswd[100]={""};
        MYSQL_RES *res;
        MYSQL_ROW field;

	sprintf(query,"SELECT cPasswd FROM tAuthorize WHERE cLabel='%s'",
			cLogin);
	mysql_query(&mysql,query);
	if(mysql_errno(&mysql))
			mysqlSendmail(mysql_error(&mysql));
	res=mysql_store_result(&mysql);
	cPasswd[0]=0;
	if((field=mysql_fetch_row(res)))
		strcpy(cPasswd,field[0]);
	mysql_free_result(res);
	
	return(cPasswd);

}//char *cGetPasswd(char *cLogin)


void SSLCookieLogin(void)
{
	char *ptr,*ptr2;

	//Parse out login and passwd from cookies
#ifdef SSLONLY
	if(getenv("HTTPS")==NULL) 
		mysqlSendmail("Non SSL access denied");
	else
		uGlobalSSLConnection=1;
#endif

	if(getenv("HTTP_COOKIE")!=NULL)
		sprintf(cCookie,"%.1022s",getenv("HTTP_COOKIE"));
	
	if(cCookie[0])
	{

	if((ptr=strstr(cCookie,"mysqlSendmailLogin=")))
	{
		ptr+=strlen("mysqlSendmailLogin=");
		if((ptr2=strchr(ptr,';')))
		{
			*ptr2=0;
			sprintf(cLogin,"%.99s",ptr);
			*ptr2=';';
		}
		else
		{
			sprintf(cLogin,"%.99s",ptr);
		}
	}
	if((ptr=strstr(cCookie,"mysqlSendmailPasswd=")))
	{
		ptr+=strlen("mysqlSendmailPasswd=");
		if((ptr2=strchr(ptr,';')))
		{
			*ptr2=0;
			sprintf(cPasswd,"%.64s",ptr);
			*ptr2=';';
		}
		else
		{
			sprintf(cPasswd,"%.64s",ptr);
		}
	}
	
	}//if cCookie[0] time saver

	if(!ValidLogin(1))
		htmlSSLLogin();

	strncpy(cUser,cLogin,41);
	GetPLAndClient(cUser);
	//Experimental feature for end user passwd change
	if(!uPermLevel)
		GetUserPLAndClient(cUser);
	if(!uPermLevel || !uLoginClient)
		mysqlSendmail("Access denied");
	cPasswd[0]=0;
	uSSLCookieLogin=1;

}//SSLCookieLogin()


void htmlSSLLogin(void)
{
	if(!uAllowUserFormOnly)
	{
	        Header_ism3("",0);
		printf("<p><table width=900><tr><td><font face=arial,helvetica size=2><form action=mysqlSendmail.cgi method=post>\n");
		printf("Login: <input type=text size=20 maxlength=98 name=cLogin>\n");
		printf(" Passwd: <input type=password size=20 maxlength=20 name=cPasswd>\n");
		printf("<font size=1> <input type=submit name=function value=Login></form></td></tr></table>\n");
		Footer_ism3();

	}
	else
	{
		tUserChangePasswdLogin(cHost);
	}

}//void htmlSSLLogin(void)



void EncryptPasswdWithSalt(char *pw, char *salt)
{
	char passwd[102]={""};
	char *cpw;
			
	strcpy(passwd,pw);
				
	cpw=crypt(passwd,salt);

	strcpy(pw,cpw);

}//void EncryptPasswdWithSalt(char *pw, char *salt)


void GetPLAndClient(char *cUser)
{
        MYSQL_RES *res;
        MYSQL_ROW field;

	sprintf(query,"SELECT uPerm,uCertClient FROM tAuthorize WHERE cLabel='%s'",cUser);
	mysql_query(&mysql,query);
	if(mysql_errno(&mysql))
		mysqlSendmail(mysql_error(&mysql));
	res=mysql_store_result(&mysql);
	if(mysql_num_rows(res))
	{
		field=mysql_fetch_row(res);
		sscanf(field[0],"%d",&uPermLevel);
		sscanf(field[1],"%u",&uLoginClient);
	}
	mysql_free_result(res);

}//void GetPLAndClient()


void GetUserPLAndClient(char *cUser)
{
	uPermLevel=5;
	uLoginClient= -1;

}//void GetUserPLAndClient()


void GetClientOwner(unsigned uClient, unsigned *uOwner)
{
        MYSQL_RES *res;
        MYSQL_ROW field;

        char query[254];

        sprintf(query,"SELECT uOwner FROM tClient WHERE uClient=%u",uClient);

        mysql_query(&mysql,query);
        if(mysql_errno(&mysql))
                mysqlSendmail(mysql_error(&mysql));
        res=mysql_store_result(&mysql);
        *uOwner=0;
        if((field=mysql_fetch_row(res)))
                sscanf(field[0],"%u",uOwner);
        mysql_free_result(res);

}//void GetClientOwner(unsigned uClient, unsigned *uOwner)



