/* System-dependent definitions of various files, spool directories, etc */
/* Mods by PA0GRI */
#include "global.h"
#ifndef MSDOS
#include "ctype.h"
#endif
#include "commands.h"
#include "netuser.h"
#include "files.h"
#include "mailbox.h"


#if !defined(_lint)
static char rcsid[] OPTIONAL = "$Id: files.c,v 1.32 2000/05/09 16:48:25 brian Exp $";
#endif

const char *Alias	  = "etc/alias";		/* the alias file */
const char *ANSIArea	  = "etc/menus/areas.bbs";	/* ANSI areas file */
const char *ANSILogin	  = "etc/menus/login.bbs";	/* ANSI login file */
const char *AreaData	  = "etc/help/areas.hlp";	/* Descriptions of message areas */
const char *AreaSlist	  = "etc/areas.sys";		/* List of message areas for sysops */
const char *CommandHelp   = "etc/help/command.hlp";	/* Command Session Help file */
const char *ConfNews	  = "etc/help/confnews.txt";	/* conference bridge news file */
const char *DomainFile	  = "spool/domain.txt";		/* Domain cache */
const char *EditorHelp	  = "etc/help/editor.hlp";	/* Mini-Editor Help file */
const char *ETCdir	  = "etc";			/* the ETC direcory */
const char *Fdbase	  = "finger/dbase.dat";		/* Finger database */
const char *FingerDir	  = "finger";			/* Finger info directory */
static const char *FileStructure = "structur.fil";	/* Runtime listing of filename used */
const char *FTPHelp	  = "etc/help/ftp.hlp";		/* FTP Help file */
const char *Ftpmotd	  = "etc/ftpmotd";		/* FTP message of the day */
const char *Group	  = "etc/groups";		/* the groups file */
const char *Hostfile	  = "etc/net.rc";		/* hosts and passwords */
const char *LOGdir	  = "spool/log";		/* log directory */
const char *Maillog	  = "spool/log/mail.log";	/* mail log */
const char *Mailqdir	  = "spool/mqueue";		/* Outgoing mail spool */
const char *Mailqueue	  = "spool/mqueue/*.wrk";	/* Outgoing mail work files */
const char *Mailrelay     = "etc/mailrelay";    /* Who we relay mail for */
const char *Mailspool	  = "spool/mail";		/* Incoming mail */
const char *MANdir	  = "man";			/* Manual pages base directory */
const char *PBBSHelp	  = "etc/help/pbbs.hlp";	/* PBBS Help file */
const char *MOTDfile	  = "etc/motd";			/* Mailbox MOTD file */
const char *MOTDsysfile   = "etc/motd.sys";		/* Mailbox MOTD file for SYSOPs */
const char *NEWUSERfile   = "etc/newuser";		/* New Pbbs User file */
const char *Onexit	  = "onexit.nos";		/* Commands to be executed on exiting */
const char *PublicDir	  = "public";			/* Public directory */
const char *Quotes	  = "etc/quotes";		/* List of quotes of the day */
const char *Rewritefile   = "etc/rewrite";		/* Address rewrite file */
const char *Routeqdir	  = "spool/rqueue";		/* queue for router */
const char *SMILEYFile	  = "etc/help/smileys.txt";	/* conf smiley file */
const char *Spool	  = "spool";			/* Spool directory */
const char *Startup	  = "autoexec.nos";		/* Initialization file */
const char *Userfile	  = "etc/security";		/* Authorized users and passwords */
const char *VersionFile   = "etc/help/version.hlp";	/* Command Session version file */

#ifdef ASKHOME
const char *AskhomeFile   = "etc/askhome.dat";		/* Askhome prompt */
#endif

#ifdef BBSEXPORT
const char *EXPORTDir	  = "spool/export";		/* Export directory */
#endif

#ifdef BBSIMPORT
const char *IMPORTDir	  = "spool/import";		/* Import directory */
#endif

#ifdef BROWSER
const char *Cookiejar	  = "spool/cookie.jar";		/* cookies received by local browser */
const char *IncomingURLs  = "spool/incoming";		/* directory for files received by local browser */
const char *CheckedURLs	  = "spool/checked.url";	/* files with checked URL data */
#endif

#ifdef CATALOG
const char *CATALOGfile   = "etc/catalog.cat";		/* String Catalog file */
#endif

#ifdef CONVERS
const char *ConfHlp	  = "etc/help/confmode.hlp";
const char *ConfInfo	  = "spool/confinfo";		/* Conferenge bridge user info */
const char *NetControlHlp = "etc/help/netcntrl.hlp";
#endif

#ifdef CRONTAB
const char *CRONTABFile	  = "spool/crontab";		/* Crontab file */
#endif

#ifdef DELEGATE
const char *DelegateFile  = "spool/mail/delegate";	/* delegation data file */
#endif

#ifdef ENCAP
const char *EncapRoutes	  = "etc/encap-rt.dat";		/* Dynamic encap routes */
#endif

#ifdef EXPIRY
const char *Expirefile	  = "etc/expire.dat";		/* Message expiration control file */
#endif

#ifdef FIFOSERVER
const char *FIFO_IN	  = "spool/fifo_in";		/* FIFO input */
const char *FIFO_OUT	  = "spool/fifo_out";		/* FIFO output */
#endif

#ifdef GPS
const char *GPSfile	  = "spool/GPSfile";		/* All heard GPS position data */
#endif

#ifdef HOLDMODS
const char *Holdqdir  = "spool/hqueue";             /* Held mailqueue  */
const char *UserHoldFile  = "etc/userhold.dat";		/* file w/user name to hold mail from */
const char *WordHoldFile  = "etc/wordhold.dat";		/* file w/words to hold mail if found in */
#endif

#ifdef HTTP
const char *Cookiefile	  = "spool/cookie.cnt";		/* last cookie number assigned */
const char *Cookiedata	  = "spool/cookies.dat";	/* cookies assigned */
const char *HTTPdir	  = "http";			/* http root directory */
const char *HTTPheadfile  = "wwwpre.cat";		/* http directory 'head' file */
#ifdef UNIX
const char *HTTPinclude	  = ".message";			/* http directory 'include' file */
#else
const char *HTTPinclude	  = "message.dat";		/* http directory 'include' file */
#endif
const char *HTTPtailfile  = "wwwpost.cat";		/* http directory 'tail' file */
#endif

#if defined(MAILBOX) || defined(DELEGATE) || defined(REQSVR) || defined(MAILFILTER)
const char *Helpdir	  = "etc/help";			/* Mailbox help file directory */
#endif

#ifdef MAILBOX
const char *Historyfile   = "spool/history";		/* Message ID history file */
const char *Signature	  = "spool/signatur";		/* Mail signature file directory */
#endif

#ifdef MAILCMDS
const char *Arealist	  = "etc/areas";		/* List of message areas */
#endif

#ifdef MAILFILTER
const char *FilterFile	  = "etc/mbfilter.dat";		/* Mail filter data file */
#endif

#ifdef MBFWD
const char *Forwardfile   = "etc/forward.bbs";		/* Mail forwarding file */
#endif

#ifdef NETROM
const char *Netromfile	  = "spool/netrom.sav";		/* Netrom node save file */
#endif

#ifdef NODECALL
const char *NODEHelp	  = "etc/help/node.hlp";	/* NODE Help file */
const char *NODEInfo	  = "etc/help/nodeinfo.hlp";	/* NODE Info file */
#endif

#if (defined(NNTP) || defined(NNTPS))
const char *NNTPdir	  = "spool/nnews";		/* News messages and NNTP data */
const char *NNTPaccess	  = "spool/nnews/access";
#endif

#ifdef NNTPS
const char *NNTPactive	  = "spool/nnews/active";	/* */
const char *NNTPdist      = "etc/distmap";          /* nntp <> pbbs distribution mapping*/
const char *NNTPforward	  = "spool/nnews/forward";	/* */
const char *NNTPhistory	  = "spool/nnews/history";	/* */
const char *NEWS2Mail	  = "etc/news2mail";		/* */
const char *NNTPhelp	  = "spool/nnews/help";		/* */
const char *NNTPinfo	  = "spool/nnews/info";		/* */
const char *NNTPpointer	  = "spool/nnews/pointer";	/* */
const char *NNTPpoll	  = "spool/nnews/poll";		/* */
const char *UKIPNEWS2Mail = "etc/gateway.txt";      /* UKIP nntp newsgroup <> pbbs */
#endif

#if (defined(POP) || defined(POP2CLIENT) || defined(POP2SERVER) || defined(POP3CLIENT) || defined(POP3SERVER))
const char *Popusers	  = "etc/popusers";		/* POP user and password file */
#endif

#ifdef REJECT
const char *REJECTFile	  = "etc/reject.dat";		/* Message rejection file */
#endif

#ifdef ROUTESERVER
const char *RouteServer	  = "etc/routesvr.dat";		/* Enabled remote encap routes */
#endif

#ifdef STATS
const char *STATSDir	  = "spool/stats";		/* Statistics directory */
#endif

#ifdef TUTOR
const char *Info	  = "spool/info";		/* Information Center directory */
const char *News	  = "spool/news";		/* News Center directory */
const char *Tutor	  = "spool/tutor";		/* Tutorial Server directory */
const char *UCmdsHelp	  = "etc/help/usercmds.hlp";	/* BBS CMD help file */
const char *UserCmds	  = "spool/cmds";		/* BBS CMD directory */
#endif

#ifdef USERLOG
const char *UDefaults	  = "spool/users.dat";		/* User preference file */
const char *UDefbak	  = "spool/users.bak";
#endif

#ifdef WPAGES
const char *WhitePages	  = "spool/wpages";		/* White Pages user log file */
const char *WhitePagesBBS = "spool/wpagebbs";		/* White Pages bbs log file */
const char *WPUpdateFile  = "spool/update.wp";		/* White Pages update temp file */
#endif

#define	SEPARATOR	'/'

#ifdef UNIX
#define ROOTDIR "."
#else
#define ROOTDIR "/"
#endif

#ifdef MSDOS
const char System[] = "MSDOS";
const char Eol[]	= "\r\n";
#endif

#ifdef TNOS_68K
const char System[] = "OSK";
const char Eol[]	= "\n";
#endif

#ifdef	UNIX
const char System[] = "UNIX";
const char Eol[]	= "\n";
const char *Command_sessmgr = "";
const char *Trace_sessmgr = "";
#endif


const char *rootdir = ROOTDIR;
static int Assigned;
int Initroot;
extern char *firstMsg;

static const char * setname (const char *name,char *file);


/* Concatenate root, separator and arg strings into a malloc'ed output
 * buffer, then remove repeated occurrences of the separator char
 */
void
rootdircat(filenameptr)
char const **filenameptr;
{
char *out;
char const *filename = *filenameptr;

	if (rootdir && *rootdir)	{
		if (*filename == SEPARATOR)
			filename++;
		out = mallocw (strlen (rootdir) + strlen (filename) + 2);
		sprintf (out, "%s%c%s", rootdir, SEPARATOR, filename);
		*filenameptr =  out;
	}
}


struct filenaming {
	const char *name;
	int rootdircat;
	char const **value;
};

static struct filenaming Files[] = {
	{ "Alias", 		1,	&Alias },
	{ "ANSIArea", 		1,	&ANSIArea },
	{ "ANSILogin",		1,	&ANSILogin },
	{ "AreaData",		1,	&AreaData },
#ifdef MAILCMDS
	{ "Arealist",		1,	&Arealist },
#endif
	{ "AreaSlist",		1,	&AreaSlist },

#ifdef ASKHOME
	{ "AskhomeFile",	1,	&AskhomeFile },
#endif
#ifdef CATALOG
	{ "CATALOGfile",	1,	&CATALOGfile },
#endif
#ifdef BROWSER
	{ "CheckedURLs",	1,	&CheckedURLs },
#endif
#ifdef UNIX
	{ "Command_sessmgr",	0,	&Command_sessmgr },
#endif
	{ "CommandHelp",	1,	&CommandHelp },
#ifdef  CONVERS
	{ "ConfHlp",		1,	&ConfHlp },
	{ "ConfInfo",		1,	&ConfInfo },
#endif
	{ "ConfNews",		1,	&ConfNews },
#ifdef HTTP
	{ "Cookiedata",		1,	&Cookiedata },
	{ "Cookiefile",		1,	&Cookiefile },
#endif
#ifdef BROWSER
	{ "Cookiejar",		1,	&Cookiejar },
#endif
#ifdef CRONTAB
	{ "CRONTABFile",	1,	&CRONTABFile },
#endif
#ifdef DELEGATE
	{ "DelegateFile",	1,	&DelegateFile },
#endif
	{ "DomainFile",		1,	&DomainFile },
	{ "EditorHelp",		1,	&EditorHelp },
#ifdef ENCAP
	{ "EncapRoutes",	1,	&EncapRoutes },
#endif
	{ "ETCdir",		1,	&ETCdir },
#ifdef EXPIRY
	{ "Expirefile",		1,	&Expirefile },
#endif
#ifdef BBSEXPORT
	{ "EXPORTDir",		1,	&EXPORTDir },
#endif
	{ "Fdbase",		1,	&Fdbase },
#ifdef FIFOSERVER
	{ "FIFO_IN",		1,	&FIFO_IN },
	{ "FIFO_OUT",		1,	&FIFO_OUT },
#endif
	{ "FileStructure",	1,	&FileStructure },
#ifdef MAILFILTER
	{ "FilterFile",		1,	&FilterFile },
#endif
	{ "FingerDir",		1,	&FingerDir },
#ifdef MBFWD
	{ "Forwardfile",	1,	&Forwardfile },
#endif
	{ "FTPHelp",		1,	&FTPHelp },
	{ "Ftpmotd",		1,	&Ftpmotd },
#ifdef GPS
	{ "GPSfile",		1,	&GPSfile },
#endif
	{ "Group",		1,	&Group },
#ifdef MAILBOX
	{ "Helpdir",		1,	&Helpdir },
	{ "Historyfile",	1,	&Historyfile },
#endif
#ifdef HOLDMODS
	{ "Holdqdir",       1,  &Holdqdir },
#endif
	{ "Hostfile",		1,	&Hostfile },
#ifdef HTTP
	{ "HTTPdir",		1,	&HTTPdir },
	{ "HTTPheadfile",	0,	&HTTPheadfile },
	{ "HTTPinclude",	0,	&HTTPinclude },
	{ "HTTPtailfile",	0,	&HTTPtailfile },
#endif
#ifdef BBSIMPORT
	{ "IMPORTDir",		1,	&IMPORTDir },
#endif
#ifdef BROWSER
	{ "IncomingURLs",	1,	&IncomingURLs },
#endif
#ifdef TUTOR
	{ "Info",		1,	&Info },
#endif
	{ "LOGdir",		1,	&LOGdir },
	{ "Maillog",		1,	&Maillog },
	{ "Mailqdir",		1,	&Mailqdir },
	{ "Mailqueue",		1,	&Mailqueue },
	{ "Mailspool",		1,	&Mailspool },
	{ "MANdir",		1,	&MANdir },
	{ "MOTDfile",		1,	&MOTDfile },
	{ "MOTDsysfile",	1,	&MOTDsysfile },
#ifdef  CONVERS
	{ "NetControlHlp",	1,	&NetControlHlp },
#endif
#ifdef NETROM
	{ "Netromfile",		1,	&Netromfile },
#endif
#ifdef TUTOR
	{ "News",		1,	&News },
#endif
#ifdef NNTPS
	{ "NEWS2Mail",		1,	&NEWS2Mail },
#endif
	{ "NEWUSERfile",	1,	&NEWUSERfile },
#ifdef NODECALL
	{ "NODEHelp",		1,	&NODEHelp },
	{ "NODEInfo",		1,	&NODEInfo },
#endif
#if (defined(NNTP) || defined(NNTPS))
	{ "NNTPaccess",		1,	&NNTPaccess },
#endif
#ifdef NNTPS
	{ "NNTPactive",		1,	&NNTPactive },
#endif
#if (defined(NNTP) || defined(NNTPS))
	{ "NNTPdir",		1,	&NNTPdir },
#endif
#ifdef NNTPS
	{ "NNTPforward",	1,	&NNTPforward },
	{ "NNTPhelp",		1,	&NNTPhelp },
	{ "NNTPhistory",	1,	&NNTPhistory },
	{ "NNTPinfo",		1,	&NNTPinfo },
	{ "NNTPpointer",	1,	&NNTPpointer },
	{ "NNTPpoll",		1,	&NNTPpoll },
#endif
	{ "Onexit",		1,	&Onexit },
	{ "PBBSHelp",		1,	&PBBSHelp },
#if (defined(POP) || defined(POP2CLIENT) || defined(POP2SERVER) || defined(POP3CLIENT) || defined(POP3SERVER))
	{ "Popusers",		1,	&Popusers },
#endif
	{ "PublicDir",		1,	&PublicDir },
	{ "Quotes",		1,	&Quotes },
#ifdef REJECT
	{ "REJECTFile",		1,	&REJECTFile },
#endif
	{ "Rewritefile",	1,	&Rewritefile },
	{ "Routeqdir",		1,	&Routeqdir },
#ifdef ROUTESERVER
	{ "RouteServer",	1,	&RouteServer },
#endif
#ifdef MAILBOX
	{ "Signature",		1,	&Signature },
#endif
	{ "SMILEYFile",		1,	&SMILEYFile },
	{ "Spool",		1,	&Spool },
	{ "Startup",		1,	&Startup },
#ifdef STATS
	{ "STATSDir",		1,	&STATSDir },
#endif
#ifdef UNIX
	{ "Trace_sessmgr",	0,	&Trace_sessmgr },
#endif
#ifdef TUTOR
	{ "Tutor",		1,	&Tutor },
	{ "UCmdsHelp",		1,	&UCmdsHelp },
#endif
#ifdef USERLOG
	{ "UDefaults",		1,	&UDefaults },
	{ "UDefbak",		1,	&UDefbak },
#endif
#ifdef TUTOR
	{ "UserCmds",		1,	&UserCmds },
#endif
	{ "Userfile",		1,	&Userfile },
#ifdef HOLDMODS
	{ "UserHoldFile",	1,	&UserHoldFile },
#endif
	{ "VersionFile",	1,	&VersionFile },
#ifdef WPAGES
	{ "WhitePages",		1,	&WhitePages },
	{ "WhitePagesBBS",	1,	&WhitePagesBBS },
#endif
#ifdef HOLDMODS
	{ "WordHoldFile",	1,	&WordHoldFile },
#endif
#ifdef WPAGES
	{ "WPUpdateFile",	1,	&WPUpdateFile },
#endif
	{ NULLCHAR,		0,	(char const **)0 }
};



/* Establish a root directory other than the default. Can only be called
 * once, at startup time
 */
void
initroot(root)
char *root;
{
int k;
	if(Assigned) {
		firstMsg = strdup ("\007-f option used, -d ignored !\n");
		return;
	}
#ifdef  MSDOS
	undosify(root);
#endif
	if (root[strlen(root) - 1] == SEPARATOR)
		root[strlen(root) - 1] = 0;
	rootdir = strdup( root );

	/* we must re-do the original files listed, and delete the
	   one previously created
	 */
	unlink (FileStructure);
	list_filenames (2);
	
	/* loop to call rootdircat (&var) */
	for (k = 0; Files[k].name != NULLCHAR; k++)
		if (Files[k].rootdircat)
			rootdircat(Files[k].value);
	
	Initroot = 1;
}


static const char * setname (const char *name, char *file)
{
int k;

	for (k = 0; Files[k].name != NULLCHAR; k++)	{
		if (!stricmp (Files[k].name, name))
			break;
	}
	if (Files[k].name == NULLCHAR)
		return NULLCHAR;

	if (Initroot)
		free (*(Files[k].value));
	*(Files[k].value) = strdup (file);

	return (*(Files[k].value));
}


#define BUFLEN 128

void
assign_filenames(config, verbose)
const char *config;
int verbose;
{
FILE *fp;
char *name,*file,*cp;
int line;
char buf[BUFLEN+1];
char buf2[BUFLEN+1];

	strncpy (buf, config, BUFLEN);
#ifdef MSDOS
	undosify (buf);
#endif
	if ((fp = fopen (buf, "r")) == NULL) {
		if (verbose)	{
			sprintf (buf2, "Cannot open '%s'\n", buf);
			firstMsg = strdup (buf2);
		}
		return;
	}

	line = 0;
	while (fgets (buf, BUFLEN, fp) != NULL) {
		line++;
		if (*buf == '#')         /* comment */
			continue;
		rip (buf);   /* delete ending \n */
		name = skipwhite (buf);
		if (*name == '\0')      /* blank line */
			continue;
		/* Search for filename */
		if ((file = strchr (name, '=')) == NULL) {
			printf ("Need '=', line %d of %s.\n", line, config);
			continue;
		}
		*file++ = '\0';
		/* cut trailing spaces */
		if ((cp = strchr (name,' ')) != NULL)
			*cp = '\0';

		/* find start of filename */
		file = skipwhite (file);

		if (*file == '\0')
			continue;

		/* cut trailing spaces */
		if ((cp = strchr (file, ' ')) != NULL)
			*cp = '\0';

		/* Now parse the name, and assign if valid */
		(void) setname (name, file);
	}
	(void) fclose (fp);
	Assigned = 1;
}



void
list_filenames (int create)
{
int k;
FILE *fp;
const char *mode;
char file[512];
time_t nowtime;

	
	strncpy (file, FileStructure, 512);
	mode = WRITE_TEXT;
	nowtime = time ((time_t *)0);
	switch (create)	{
		case 0:		/* use current and append */
			mode = APPEND_TEXT;
			break;
		case 2:		/* use new location and create new */
			sprintf (file, "%s/%s", rootdir, FileStructure);
			break;
		case 1:		/* use current and create new */
		default:
			break;
	}
		
	fp = fopen (file, mode);
	if (fp != NULLFILE)	{
		if (create)	{
			fprintf (fp, "#\n# Default values for configurable files, directories, and session managers\n"
				"#\n# The first section of this file lists the defaults for these\n#\n");
			fprintf (fp, "# %s\n# Created: %s#\n\n", Version, ctime (&nowtime));

		} else
			fprintf (fp, "\n#\n# Values in use for configurable files, directories, and session managers\n"
			"#\n# This section of the file can be modified and used as a configuration file\n"
			"# with the '-f' command line option, if desired.\n#\n\n");
		for (k = 0; Files[k].name != NULLCHAR; k++)
			fprintf (fp, "%-15.15s = %s\n", Files[k].name, *(Files[k].value));

		(void) fclose (fp);
	}
}
