/*****************************************************************************
 *
 * $Id$
 * Purpose ...............: Misc functions
 *
 *****************************************************************************
 * Copyright (C) 1997-2002 
 *   
 * Michiel Broek		FIDO:		2:280/2802
 * Beekmansbos 10
 * 1971 BV IJmuiden
 * the Netherlands
 *
 * This file is part of MBSE BBS.
 *
 * This BBS is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 *
 * MBSE BBS is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with MBSE BBS; see the file COPYING.  If not, write to the Free
 * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *****************************************************************************/

#include "../lib/libs.h"
#include "../lib/mbse.h"
#include "../lib/structs.h"
#include "../lib/users.h"
#include "../lib/records.h"
#include "../lib/common.h"
#include "../lib/msgtext.h"
#include "../lib/msg.h"
#include "../lib/clcomm.h"
#include "funcs.h"


extern	pid_t mypid;		/* Original pid				   */



void UserSilent(int flag)
{
	SockS("ADIS:2,%d,%d;", mypid, flag);
}



/*
 * Check BBS open status, return FALSE if the bbs is closed.
 * Display the reason why to the user.
 */
int CheckStatus()
{
	static	char buf[81];

	sprintf(buf, "SBBS:0;");
	if (socket_send(buf) == 0) {
		strcpy(buf, socket_receive());
		if (strncmp(buf, "100:2,0", 7) == 0)
			return TRUE;
		if ((strncmp(buf, "100:2,2", 7) == 0) && (!ttyinfo.honor_zmh))
			return TRUE;
		buf[strlen(buf) -1] = '\0';
		printf("\n\n\007*** %s ***\n\n\n", buf+8);
		fflush(stdout);
	}
	return FALSE;
}



/*
 * Function to check if UserName exists and returns a 0 or 1
 */
int CheckName(char *Name)
{
	FILE	*fp;
	int	Status = FALSE;
	char	*temp, *temp1;
	struct	userhdr	ushdr;
	struct	userrec	us;

	temp   = calloc(81, sizeof(char));
	temp1  = calloc(81, sizeof(char));

	strcpy(temp1, tl(Name));

	sprintf(temp, "%s/etc/users.data", getenv("MBSE_ROOT"));
	if ((fp = fopen(temp,"rb")) != NULL) {
		fread(&ushdr, sizeof(ushdr), 1, fp);

 		while (fread(&us, ushdr.recsize, 1, fp) == 1) {
			strcpy(temp, tl(us.sUserName));

			if((strcmp(temp, temp1)) == 0) {
				Status = TRUE;
				break;
			}
 		}
		fclose(fp);
	}

	free(temp);
	free(temp1);
	return Status;
}



/*
 * Function will check and create a home directory for the user if
 * needed. It will also change into the users home directory when
 * they login.
 */
char *ChangeHomeDir(char *Name, int Mailboxes)
{
	char		*temp;
	static char	temp1[PATH_MAX];
	FILE		*fp;

	temp  = calloc(PATH_MAX, sizeof(char));

	/*
	 * set umask bits to zero's then reset with mkdir
	 */
	umask(000);
	
	/*
	 * First check to see if users home directory exists
	 * else try create directory, as set in CFG.bbs_usersdir
	 */
	if ((access(CFG.bbs_usersdir, R_OK)) != 0) {
		WriteError("$FATAL: Access to %s failed", CFG.bbs_usersdir);
		free(temp);
		ExitClient(1);
	}

	sprintf(temp1, "%s/%s", CFG.bbs_usersdir, Name);

	/*
	 * Then check to see if users directory exists in the home dir
	 */
	if ((access(temp1, R_OK)) != 0) {
		WriteError("$FATAL: Users homedir %s doesn't exist", temp1);
		free(temp);
		ExitClient(1);
	}

	/*
	 * Change to users home directory
	 */
	if (chdir(temp1) != 0) {
		WriteError("$FATAL: Can't change to users home dir, aborting: %s", temp1);
		free(temp);
		ExitClient(1);
	}
	setenv("HOME", temp1, 1);

	/*
	 * Check if user has a .signature file.
	 * If not, create a simple one.
	 */
	sprintf(temp, "%s/%s/.signature", CFG.bbs_usersdir, Name);
	if (access(temp, R_OK)) {
	    Syslog('+', "Creating users .signature file");
	    if ((fp = fopen(temp, "w")) == NULL) {
		WriteError("$Can't create %s", temp);
	    } else {
		fprintf(fp, "    Gtx, %s\n", exitinfo.sUserName);
		if (CFG.EmailMode == E_PRMISP)
		    fprintf(fp, "    email: %s@%s\n", exitinfo.Name, CFG.sysdomain);
		fclose(fp);
	    }
	}

	/*
	 * Check subdirectories, create them if they don't exist.
	 */
	sprintf(temp, "%s/wrk", temp1);
	CheckDir(temp);
	sprintf(temp, "%s/tag", temp1);
	CheckDir(temp);
	sprintf(temp, "%s/upl", temp1);
	CheckDir(temp);
	sprintf(temp, "%s/tmp", temp1);
	CheckDir(temp);
	sprintf(temp, "%s/.dosemu", temp1);
	CheckDir(temp);
	sprintf(temp, "%s/.dosemu/run", temp1);
	CheckDir(temp);
	sprintf(temp, "%s/.dosemu/tmp", temp1);
	CheckDir(temp);
	umask(007);

	/*
	 * Check users private emailboxes
	 */
	if (Mailboxes) {
		sprintf(temp, "%s/mailbox", temp1);
		if (Msg_Open(temp))
			Msg_Close();
		sprintf(temp, "%s/archive", temp1);
		if (Msg_Open(temp))
			Msg_Close();
		sprintf(temp, "%s/trash", temp1);
		if (Msg_Open(temp))
			Msg_Close();
	}
	
	free(temp);
	return temp1;
}



void CheckDir(char *dir)
{
	if ((access(dir, R_OK) != 0)) {
		Syslog('+', "Creating %s", dir);
		if (mkdir(dir, 0770))
			WriteError("$Can't create %s", dir);
	}
}



/*
 * Function will find where MBSE is located on system and load
 * the file $MBSE_ROOT/etc/config.data in memory.
 */
void FindMBSE()
{
	FILE		*pDataFile;
	static char	p[81];
	char		*FileName;
	struct passwd	*pw;

        FileName = calloc(PATH_MAX, sizeof(char));

	/*
	 * Check if the environment is set, if not, then we create the
	 * environment from the passwd file.
	 */
	if (getenv("MBSE_ROOT") == NULL) {
		pw = getpwnam("mbse");
		memset(&p, 0, sizeof(p));
		sprintf(p, "MBSE_ROOT=%s", pw->pw_dir);
		putenv(p);
	}

	if (getenv("MBSE_ROOT") == NULL) {
		printf("FATAL ERROR: Environment variable MBSE_ROOT not set\n");
		free(FileName);
#ifdef MEMWATCH
		mwTerm();
#endif
		exit(1);
	}
	sprintf(FileName, "%s/etc/config.data", getenv("MBSE_ROOT"));

	if(( pDataFile = fopen(FileName, "rb")) == NULL) {
		printf("FATAL ERROR: Can't open %s for reading!\n", FileName);
		printf("Please run mbsetup to create configuration file.\n");
		printf("Or check that your environment variable MBSE_ROOT is set to the BBS Path!\n");
		free(FileName);
#ifdef MEMWATCH
                mwTerm();
#endif
		exit(1);
	}

	fread(&CFG, sizeof(CFG), 1, pDataFile);
	free(FileName);
	fclose(pDataFile);
}



/* 
 * Returns Mmm in the users language.
 */
char *GetMonth(int Month)
{
	static char	month[10];

	switch (Month) {
		case 1:
			strcpy(month, *(mLanguage + 398));
			break;
		case 2:                    
			strcpy(month, *(mLanguage + 399));      
			break;                    
		case 3:                    
			strcpy(month, *(mLanguage + 400));      
			break;                    
		case 4:                    
			strcpy(month, *(mLanguage + 401));      
			break;                    
		case 5:                    
			strcpy(month, *(mLanguage + 402));      
			break;                    
		case 6:                    
			strcpy(month, *(mLanguage + 403));      
			break;                    
		case 7:                    
			strcpy(month, *(mLanguage + 404));      
			break;                    
		case 8:                    
			strcpy(month, *(mLanguage + 405));      
			break;                    
		case 9:                    
			strcpy(month, *(mLanguage + 406));      
			break;                    
		case 10:                    
			strcpy(month, *(mLanguage + 407));      
			break;                    
		case 11:                    
			strcpy(month, *(mLanguage + 408));      
			break;                    
		case 12:
			strcpy(month, *(mLanguage + 409));
			break;
		default:                        
			strcpy(month, "Unknown");      
	}                                              

	return(month);
}



/* Returns DD-Mmm-YYYY */
char *GLCdateyy()
{
	static	char	GLcdateyy[15];
	char	ntime[15];

	Time_Now = time(NULL);
	l_date = localtime(&Time_Now);

	sprintf(GLcdateyy,"%02d-",
	  l_date->tm_mday);

	sprintf(ntime,"-%02d", l_date->tm_year+1900);
	strcat(GLcdateyy, GetMonth(l_date->tm_mon+1));
	strcat(GLcdateyy,ntime);

	return(GLcdateyy);
}



/*
 * Security Access Check
 */
int Access(securityrec us, securityrec ref)
{
	Syslog('B', "User %5d %08lx %08lx", us.level, us.flags, ~us.flags);
	Syslog('B', "Ref. %5d %08lx %08lx", ref.level, ref.flags, ref.notflags);

	if (us.level < ref.level)
		return FALSE;

	if ((ref.notflags & ~us.flags) != ref.notflags)
		return FALSE;

	if ((ref.flags & us.flags) != ref.flags)
		return FALSE;

	return TRUE;
}