/* System-dependent definitions of various files, spool directories, etc */
/* Mods by PA0GRI */
#include <stdio.h>
#include "global.h"
#include "config.h"
#include "netuser.h"
#include "files.h"
#include "md5.h"

#if defined(MSDOS) || defined(TNOS_68K)
#ifdef MSDOS
char System[] = "MSDOS";
#else
char System[] = "OSK";
#endif
char *Startup	= "/autoexec.nos";		/* Initialization file */
char *Userfile	= "/ftpusers";			/* Authorized FTP users and passwords */
char *Hostfile	= "/net.rc";			/* hosts and passwords */
char *Maillog	= "/spool/mail.log";		/* mail log */
char *Mailspool	= "/spool/mail";		/* Incoming mail */
char *Mailqdir	= "/spool/mqueue";		/* Outgoing mail spool */
char *Mailqueue	= "/spool/mqueue/*.wrk";	/* Outgoing mail work files */
char *Routeqdir	= "/spool/rqueue";		/* queue for router */
char *Alias	= "/alias";			/* the alias file */
char *Group	= "/groups";			/* the group file */
char *Dfile	= "/domain.txt";		/* Domain cache */
char *Fdir	= "/finger";			/* Finger info directory */
char *Fdbase	= "/finger/dbase.dat";		/* Finger database */
char *Quotes	= "/spool/quotes";		/* List of quotes of the day */
#ifdef TUTOR
char *Tutor     = "/spool/tutor";		/* Tutorial Server directory */
char *Info      = "/spool/info";		/* Information Center directory */
char *News      = "/spool/news";		/* News Center directory */
char *UserCmds	= "/spool/cmds";		/* BBS CMD directory */
char *UCmdsHelp	= "/spool/help/usercmds.hlp";	/* BBS CMD help file */
#endif
char *Spool	= "/spool";			/* Spool directory */
char *Arealist	= "/spool/areas";		/* List of message areas */
char *AreaSlist	= "/spool/areas.sys";		/* List of message areas for sysops */
char *Rewritefile = "/spool/rewrite";       /* Address rewrite file */
#ifdef MAILBOX
char *Signature = "/spool/signatur";        /* Mail signature file directory */
char *Historyfile = "/spool/history";       /* Message ID history file */
char *Helpdir   = "/spool/help";        /* Mailbox help file directory */
#ifdef USERLOG
char *UDefaults = "/spool/users.dat";       /* User preference file */
char *UDefbak = "/spool/users.bak";
#endif
#endif /* MAILBOX */
#if (defined(POP) || defined(POP2CLIENT) || defined(POP2SERVER) || defined(POP3CLIENT) || defined(POP3SERVER))
char *Popusers  = "/popusers";          /* POP user and password file */
#endif
#if (defined(NNTP) || defined(NNTPS))
char *Newsdir   = "/spool/nnews";        /* News messages and NNTP data */
#endif
#ifdef MBFWD
char *Forwardfile = "/spool/forward.bbs";   /* Mail forwarding file */
#endif
#ifdef NETROM
char *Netromfile = "/netrom.sav";       /* Netrom node save file */
#endif
char *Onexit = "/onexit.nos";           /* Commands to be executed on exiting */
#ifdef EXPIRY
char *Expirefile = "/spool/expire.dat"; /* Message expiration control file */
#endif
char *FTPHelp = "/spool/help/ftp.hlp";		/* FTP Help file */
char *Ftpmotd = "/spool/ftpmotd";		/* FTP message of the day */
char *EditorHelp = "/spool/help/editor.hlp";	/* Mini-Editor Help file */
char *MOTDfile = "/spool/motd";			/* Mailbox MOTD file */
char *MOTDsysfile = "/spool/motd.sys";		/* Mailbox MOTD file for SYSOPs */
char *NEWUSERfile = "/spool/newuser";		/* New Mbox User file */
char *WhitePagesBBS = "/spool/wpagebbs";	/* White Pages bbs log file */
char *WhitePages = "/spool/wpages";		/* White Pages user log file */
#ifdef  CONVERS
char *ConfInfo	= "/spool/confinfo";		/* Conferenge bridge user info */
char *ConfHlp = "/spool/help/confmode.hlp";
char *NetControlHlp = "/spool/help/netcntrl.hlp";
#endif
#ifdef	NNTPS
char *Active	= "/spool/nnews/active";		/* */
char *Pointer	= "/spool/nnews/pointer";	/* */
char *NInfo	= "/spool/nnews/info";		/* */
char *Nhelp	= "/spool/nnews/help";		/* */
char *History	= "/spool/nnews/history";	/* */
char *Forward	= "/spool/nnews/forward";	/* */
char *Poll	= "/spool/nnews/poll";		/* */
#endif
char *MBOXHelp	= "/spool/help/mbox.hlp";	/* MBOX Help file */
char *CommandHelp = "/spool/help/command.hlp";	/* Command Session Help file */
char *VersionFile = "/spool/help/version.hlp";  /* Command Session version file */
#ifndef TNOS_68K
char Eol[]	= "\r\n";
#else
char Eol[]	= "\n";
#endif
#ifdef GPS
char *GPSfile = "/GPSfile";	/* All heard GPS position data */
#endif
char *ANSIArea = "/spool/menus/areas.bbs";	/* ANSI areas file */
char *ANSILogin = "/spool/menus/login.bbs";	/* ANSI login file */
char *SMILEYFile = "/spool/help/smileys.txt";	/* conf smiley file */
char *ConfNews = "/spool/help/confnews.txt";	/* conference bridge news file */
#ifdef DELEGATE
char *DelegateFile = "/spool/mail/delegate";	/* delegation data file */
#endif
#define	SEPARATOR	"/"
#define ROOTDIR "/"
#endif

#ifdef	UNIX
char System[] = "UNIX";
char *Startup	= "./autoexec.nos";		/* Initialization file */
char *Config	= "./config.nos";		/* Device configuration list */
char *Hostfile	= "./net.rc";			/* hosts and passwords */
char *Userfile	= "./ftpusers";
char *Mailspool	= "./spool/mail";
char *Maillog	= "./spool/mail.log";		/* mail log */
char *Mailqdir	= "./spool/mqueue";
char *Mailqueue	= "./spool/mqueue/*.wrk";
char *Routeqdir	= "./spool/rqueue";		/* queue for router */
char *Alias	= "./alias";			/* the alias file */
char *Group	= "./group";			/* the group file */
char *Dfile	= "./domain.txt";		/* Domain cache */
char *Fdir	= "./finger";			/* Finger info directory */
char *Fdbase 	= "./finger/dbase.dat";		/* Finger database */
char *Quotes	= "./spool/quotes";		/* List of quotes of the day */
#ifdef TUTOR
char *Tutor     = "./spool/tutor";		/* Tutorial Server directory */
char *Info      = "./spool/info";		/* Information Center directory */
char *News      = "./spool/news";		/* News Center directory */
char *UserCmds	= "./spool/cmds";		/* BBS CMD directory */
char *UCmdsHelp	= "./spool/help/usercmds.hlp";	/* BBS CMD help file */
#endif
char *Spool	= "./spool";			/* Spool directory */
char *Arealist	= "./spool/areas";		/* List of message areas */
char *AreaSlist	= "./spool/areas.sys";		/* List of message areas for sysops */
char *Helpdir	= "./spool/help";		/* Mailbox help file directory */
char *Rewritefile = "./spool/rewrite";		/* Address rewrite file */
char *Signature	= "./spool/signatur";		/* Mail signature file directory */
char *Popusers	= "./popusers";			/* POP user and password file */
char *Newsdir	= "./spool/nnews";		/* News messages and NNTP data */
char *Forwardfile = "./spool/forward.bbs";	/* Mail forwarding file */
char *Historyfile = "./spool/history";		/* Message ID history file */
char *Netromfile = "./netrom.sav";		/* Netrom node save file */
char *UDefaults = "./spool/users.dat";		/* User preference file */
char *UDefbak = "./spool/users.bak";
char *Onexit = "./onexit.nos";           	/* Commands to be executed on exiting */
char *Expirefile = "./spool/expire.dat";	/* Message expiration control file */
char *EditorHelp = "./spool/help/editor.hlp";		/* Mini-Editor Help file */
char *FTPHelp = "./spool/help/ftp.hlp";		/* FTP Help file */
char *Ftpmotd = "./spool/ftpmotd";		/* FTP message of the day */
char *MOTDfile = "./spool/motd";		/* Mailbox MOTD file */
char *MOTDsysfile = "./spool/motd.sys";		/* Mailbox MOTD file for SYSOPs */
char *NEWUSERfile = "./spool/newuser";		/* New Mbox User file */
char *WhitePagesBBS = "./spool/wpagebbs";	/* White Pages BBS log file */
char *WhitePages = "./spool/wpages";		/* White Pages user log file */
#ifdef  CONVERS
char *ConfInfo	= "./spool/confinfo";		/* Conferenge bridge config */
char *ConfHlp = "./spool/help/confmode.hlp";
char *NetControlHlp = "./spool/help/netcntrl.hlp";
#endif
#ifdef	NNTPS
char *Active	= "./spool/nnews/active";		/* */
char *Pointer	= "./spool/nnews/pointer";	/* */
char *NInfo	= "./spool/nnews/info";		/* */
char *Nhelp	= "./spool/nnews/help";		/* */
char *History	= "./spool/nnews/history";	/* */
char *Forward	= "./spool/nnews/forward";	/* */
char *Poll	= "./spool/nnews/poll";		/* */
#endif
char *MBOXHelp	= "./spool/help/mbox.hlp";	/* MBOX Help file */
char *CommandHelp = "./spool/help/command.hlp";	/* Command Session Help file */
char *VersionFile = "./spool/help/version.hlp";  /* Command Session version file */
char Eol[]	= "\n";
#ifdef GPS
char *GPSfile = "/GPSfile";	/* All heard GPS position data */
#endif
char *ANSIArea = "./spool/menus/areas.bbs";	/* ANSI areas file */
char *ANSILogin = "./spool/menus/login.bbs";	/* ANSI login file */
char *SMILEYFile = "./spool/help/smileys.txt";	/* conf smiley file */
char *ConfNews = "./spool/help/confnews.txt";	/* conference bridge news file */
#ifdef DELEGATE
char *DelegateFile = "./spool/mail/delegate";	/* delegation data file */
#endif
#define	SEPARATOR	"/"
#define ROOTDIR "."
char *Command_sessmgr = "";
char *Trace_sessmgr = "";
#endif

#ifdef	AMIGA
char System[] = "AMIGA";
char *Startup	= "TCPIP:nos-startup";
char *Config	= "TCPIP:config.nos";		/* Device configuration list */
char *Hostfile	= "TCPIP:net.rc";		/* hosts and passwords */
char *Userfile	= "TCPIP:ftpusers";
char *Mailspool	= "TCPIP:spool/mail";
char *Maillog	= "TCPIP:spool/mail.log";
char *Mailqdir	= "TCPIP:spool/mqueue";
char *Mailqueue	= "TCPIP:spool/mqueue/#?.wrk";
char *Routeqdir	= "TCPIP:spool/rqueue";		/* queue for router */
char *Alias	= "TCPIP:alias";		/* the alias file */
char *Group	= "TCPIP:group";		/* the group file */
char *Dfile	= "TCPIP:domain.txt";		/* Domain cache */
char *Fdir	= "TCPIP:finger";		/* Finger info directory */
char *Fdbase 	= "TCPIP:finger/dbase.dat";	/* Finger database */
char *Quotes	= "TCPIP:spool/quotes";		/* List of quotes of the day */
#ifdef TUTOR
char *Tutor     = "TCPIP:spool/tutor";		/* Tutorial Server directory */
char *Info      = "TCPIP:spool/info";		/* Information Center directory */
char *News      = "TCPIP:spool/news";		/* News Center directory */
#endif
char *Spool	= "TCPIP:spool";		/* Spool directory */
char *Arealist	= "TCPIP:spool/areas";		/* List of message areas */
char *AreaSlist	= "TCPIP:spool/areas.sys";	/* List of message areas for sysops */
char *Helpdir	= "TCPIP:spool/help";		/* Mailbox help file directory */
char *Rewritefile = "TCPIP:spool/rewrite";	/* Address rewrite file */
char *Signature	= "TCPIP:spool/signatur";	/* Mail signature file directory */
char *Popusers	= "TCPIP:/popusers";		/* POP user and password file */
char *Newsdir	= "TCPIP:spool/nnews";		/* News messages and NNTP data */
char *Forwardfile = "TCPIP:spool/forward.bbs";	/* Mail forwarding file */
char *Historyfile = "TCPIP:spool/history";	/* Message ID history file */
char *UDefaults = "TCPIP:spool/users.dat";  /* User preference file */
char *Netromfile = "TCPIP:netrom.sav";      /* Netrom node save file */
char *Onexit = "TCPIP:onexit.nos";           /* Commands to be executed on exiting */
char *Expirefile = "TCPIP:spool/expire.dat"; /* Message expiration control file */
char *EditorHelp = "TCPIP:spool/help/editor.hlp";	/* Mini-Editor Help file */
char *FTPHelp = "TCPIP:spool/help/ftp.hlp";	/* FTP Help file */
char *MOTDfile = "TCPIP:spool/motd";		/* Mailbox MOTD file */
char *MOTDsysfile = "TCPIP:spool/motd.sys";	/* Mailbox MOTD file for SYSOPs */
char *NEWUSERfile = "TCPIP:spool/newuser";	/* New Mbox User file */
char *WhitePagesBBS = "TCPIP:spool/wpagebbs";	/* White Pages BBS log file */
char *WhitePages = "TCPIP:spool/wpages";	/* White Pages user log file */
#ifdef  CONVERS
char *ConfInfo	= "TCPIP:spool/confinfo";	/* Conferenge bridge config */
char *ConfHlp = "TCPIP:spool/help/confmode.hlp";
char *NetControlHlp = "TCPIP:spool/help/netcntrl.hlp";
#endif
#ifdef	NNTPS
char *Active    = "TCPIP:spool/nnews/active";     /* */
char *Pointer   = "TCPIP:spool/nnews/pointer";    /* */
char *NInfo = "TCPIP:spool/nnews/info";       /* */
char *Nhelp = "TCPIP:spool/nnews/help";       /* */
char *History   = "TCPIP:spool/nnews/history";    /* */
char *Forward   = "TCPIP:spool/nnews/forward";    /* */
char *Poll  = "TCPIP:spool/nnews/poll";       /* */
#endif
char *MBOXHelp	= "TCPIP:spool/help/mbox.hlp";	/* MBOX Help file */
char *CommandHelp = "TCPIP:spool/help/command.hlp";	/* Command Session Help file */
char *VersionFile = "TCPIP:spool/help/version.hlp";  /* Command Session version file */
char Eol[]	= "\r\n";
#define	SEPARATOR	"/"
#endif

#ifdef	MAC
char System[] = "MACOS";
char *Startup	= "Mikes Hard Disk:nos.start";
char *Config	= "Mikes Hard Disk:config.nos";	/* Device configuration list */
char *Hostfile	= "Mikes Hard Disk:net.rc";	/* hosts and passwords */
char *Userfile	= "Mikes Hard Disk:ftpusers";
char *Mailspool	= "Mikes Hard Disk:spool:mail:";
char *Maillog	= "Mikes Hard Disk:spool:mail.log:";
char *Mailqdir	= "Mikes Hard Disk:spool:mqueue:";
char *Mailqueue	= "Mikes Hard Disk:spool:mqueue:*.wrk";
char *Routeqdir	= "Mikes Hard Disk:spool/rqueue:";	/* queue for router */
char *Alias	= "Mikes Hard Disk:alias";		/* the alias file */
char *Group	= "Mikes Hard Disk:group";		/* the group file */
char *Dfile	= "Mikes Hard Disk:domain:txt";		/* Domain cache */
char *Fdir	= "Mikes Hard Disk:finger";		/* Finger info directory */
char *Fdbase 	= "Mikes Hard Disk:finger/dbase.dat";	/* Finger database */
char *Quotes	= "Mikes Hard Disk:spool/quotes";	/* List of quotes of the day */
#ifdef TUTOR
char *Tutor     = "Mikes Hard Disk:spool/tutor";	/* Tutorial Server directory */
char *Info      = "Mikes Hard Disk:spool/info";		/* Information Center directory */
char *News      = "Mikes Hard Disk:spool/news";		/* News Center directory */
#endif
char *Spool	= "Mikes Hard Disk:spool";		/* Spool directory */
char *Arealist	= "Mikes Hard Disk:spool/areas";	/* List of message areas */
char *AreaSlist	= "Mikes Hard Disk:spool/areas.sys";	/* List of message areas for sysops */
char *Helpdir	= "Mikes Hard Disk:spool/help";		/* Mailbox help file directory */
char *Rewritefile = "Mikes Hard Disk:spool/rewrite";	/* Address rewrite file */
char *Signature	= "Mikes Hard Disk:spool/signatur";	/* Mail signature file directory */
char *Popusers	= "Mikes Hard Disk:/popusers";		/* POP user and password file */
char *Newsdir	= "Mikes Hard Disk:spool/nnews";	/* News messages and NNTP data */
char *Forwardfile = "Mikes Hard Disk:spool/forward.bbs"; /* Mail forwarding file */
char *Historyfile = "Mikes Hard Disk:spool/history";	/* Message ID history file */
char *UDefaults = "Mikes Hard Disk:spool/users.dat";  /* User preference file */
char *Netromfile = "Mikes Hard Disk:netrom.sav";    /* Netrom node save file */
char *Onexit = "Mikes Hard Disk:onexit.nos";           /* Commands to be executed on exiting */
char *Expirefile = "Mikes Hard Disk:spool/expire.dat"; /* Message expiration control file */
char *EditorHelp = "Mikes Hard Disk:spool/help/editor.hlp";	/* Mini-Editor Help file */
char *FTPHelp = "Mikes Hard Disk:spool/help/ftp.hlp";	/* FTP Help file */
char *MOTDfile = "Mikes Hard Disk:spool/motd";		/* Mailbox MOTD file */
char *MOTDsysfile = "Mikes Hard Disk:spool/motd.sys";	/* Mailbox MOTD file for SYSOPs */
char *NEWUSERfile = "Mikes Hard Disk:spool/newuser";	/* New Mbox User file */
char *WhitePagesBBS = "Mikes Hard Disk:spool/wpagebbs";	/* White Pages BBS log file */
char *WhitePages = "Mikes Hard Disk:spool/wpages";	/* White Pages user log file */
#ifdef  CONVERS
char *ConfInfo = "Mikes Hard Disk:spool/confinfo";		/* Conferenge bridge config */
char *ConfHlp = "Mikes Hard Disk:spool/help/confmode.hlp";
char *NetControlHlp = "Mikes Hard Disk:spool/help/netcntrl.hlp";
#endif
#ifdef	NNTPS
char *Active	= "Mikes Hard Disk:spool/nnews/active";		/* */
char *Pointer	= "Mikes Hard Disk:spool/nnews/pointer";	/* */
char *NInfo	= "Mikes Hard Disk:spool/nnews/info";		/* */
char *Nhelp	= "Mikes Hard Disk:spool/nnews/help";		/* */
char *History	= "Mikes Hard Disk:spool/nnews/history";	/* */
char *Forward	= "Mikes Hard Disk:spool/nnews/forward";	/* */
char *Poll	= "Mikes Hard Disk:spool/nnews/poll";		/* */
#endif
char *MBOXHelp	= "Mikes Hard Disk:spool/help/mbox.hlp";	/* MBOX Help file */
char *CommandHelp = "Mikes Hard Disk:spool/help/command.hlp";	/* Command Session Help file */
char *VersionFile = "Mikes Hard Disk:spool/help/version.hlp";  /* Command Session version file */
char Eol[]	= "\r";
#define	SEPARATOR	":"
#endif

static char *rootdir = ROOTDIR;
static int Assigned;
int Initroot;
extern char *firstMsg;
extern char Whitespace[];

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

	Startup = rootdircat(Startup);
	Userfile = rootdircat(Userfile);
	Hostfile = rootdircat(Hostfile);
	Maillog = rootdircat(Maillog);
	Mailspool = rootdircat(Mailspool);
	Mailqdir = rootdircat(Mailqdir);
	Mailqueue = rootdircat(Mailqueue);
	Routeqdir = rootdircat(Routeqdir);
	Alias = rootdircat(Alias);
	Group = rootdircat(Group);
	Dfile = rootdircat(Dfile);
	Fdir = rootdircat(Fdir);
	Fdbase = rootdircat(Fdbase);
	Quotes = rootdircat(Quotes);
#ifdef TUTOR
	Tutor = rootdircat(Tutor);
	Info = rootdircat(Info);
	News = rootdircat(News);
	UserCmds = rootdircat(UserCmds);
	UCmdsHelp = rootdircat(UCmdsHelp);
#endif
	Spool = rootdircat(Spool);
	Arealist = rootdircat(Arealist);
	AreaSlist = rootdircat(AreaSlist);
	Rewritefile = rootdircat(Rewritefile);
#ifdef MAILBOX
    Signature = rootdircat(Signature);
    Historyfile = rootdircat(Historyfile);
    Helpdir = rootdircat(Helpdir);
#ifdef USERLOG
    UDefaults = rootdircat(UDefaults);
    UDefbak = rootdircat(UDefbak);
#endif
#endif
#if (defined(POP) || defined(POP2CLIENT) || defined(POP2SERVER) || defined(POP3CLIENT) || defined(POP3SERVER))
    Popusers = rootdircat(Popusers);
#endif
#if (defined(NNTP) || defined(NNTPS))
    Newsdir = rootdircat(Newsdir);
#endif
#ifdef MBFWD
    Forwardfile = rootdircat(Forwardfile);
#endif
#ifdef NETROM
    Netromfile = rootdircat(Netromfile);
#endif
    Onexit = rootdircat(Onexit);
#ifdef EXPIRY
    Expirefile = rootdircat(Expirefile);
#endif
	FTPHelp = rootdircat(FTPHelp);
	Ftpmotd = rootdircat(Ftpmotd);
	EditorHelp = rootdircat(EditorHelp);
	MOTDfile = rootdircat(MOTDfile);
	MOTDsysfile = rootdircat(MOTDsysfile);
	NEWUSERfile = rootdircat(NEWUSERfile);
	WhitePagesBBS = rootdircat(WhitePagesBBS);
	WhitePages = rootdircat(WhitePages);
#ifdef  CONVERS
	ConfInfo=rootdircat(ConfInfo);
	ConfHlp=rootdircat(ConfHlp);
	NetControlHlp=rootdircat(NetControlHlp);
#endif
#ifdef	NNTPS
	Active = rootdircat(Active);
	Pointer = rootdircat(Pointer);
	NInfo = rootdircat(NInfo);
	Nhelp = rootdircat(Nhelp);
	History = rootdircat(History);
	Forward = rootdircat(Forward);
	Poll = rootdircat(Poll);
#endif
	MBOXHelp = rootdircat(MBOXHelp);
	CommandHelp = rootdircat(CommandHelp);
	VersionFile = rootdircat(VersionFile);
#ifdef GPS
	GPSfile = rootdircat(GPSfile);
#endif
	ANSIArea = rootdircat(ANSIArea);
	ANSILogin = rootdircat(ANSILogin);
	SMILEYFile = rootdircat(SMILEYFile);
	ConfNews = rootdircat(ConfNews);
#ifdef DELEGATE
	DelegateFile = rootdircat(DelegateFile);
#endif
	
    Initroot = 1;
}

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

	if(strlen(rootdir) > 0){
		char *separator = SEPARATOR;
		out = mallocw(strlen(rootdir)
			+ strlen(separator)
			+ strlen(filename) +1);
		strcpy(out,rootdir);
		strcat(out,separator);
		strcat(out,filename);
		if(*separator != '\0'){
			char *p1, *p2;
		/* Remove any repeated occurrences */
			p1 = p2 = out;
			while(*p2 != '\0'){
				*p1++ = *p2++;
				while(p2[0] == p2[-1] && p2[0] == *separator)
					p2++;
			}
			*p1 = '\0';
		}
	}
	return out;
}

/* Read through FTPUSERS looking for user record
 * Returns line which matches username, or NULLCHAR when no match.
 * Each of the other variables must be copied before freeing the line.
 */
char *
userlookup(username,password,directory,permission,ip_address)
char *username;
char **password;
char **directory;
long   *permission;
int32 *ip_address;
{
	FILE *fp;
	char *buf;
	char *cp;
	char *universal = NULLCHAR;

	if((fp = fopen(Userfile,READ_TEXT)) == NULLFILE)
		/* Userfile doesn't exist */
		return NULLCHAR;

	buf = mallocw(128);
#ifdef __GNUC__
	cp = 0;			/* silence "uninitialized" warning */
#endif
	while ( fgets(buf,128,fp) != NULLCHAR ){
		if(*buf == '#')
			continue;	/* Comment */

		if((cp = strpbrk(buf," \t")) == NULLCHAR)
			/* Bogus entry */
			continue;
		*cp++ = '\0';		/* Now points to password */

		if( stricmp(username,buf) == 0 )
			break;		/* Found user */
		if(stricmp("univperm",buf) == 0)
			universal = strdup(cp);	/* remember their anon entry */
	}
	if((universal == NULLCHAR) && (feof(fp))){
		/* username not found in file, nor was univperm */
		fclose(fp);
		free(buf);
		return NULLCHAR;
	}
	if(feof(fp)){
		/* restore anonymous to the buffer */
		strcpy(cp = buf, universal);
		free(universal);
		universal = NULLCHAR;
	}
	if(universal != NULLCHAR)
		free(universal);
	fclose(fp);

	if ( password != NULL )
		*password = cp;

	/* Look for space or tab after password field in file */
	if((cp = strpbrk(cp," \t")) == NULLCHAR)	{
		/* Invalid file entry */
		free(buf);
		return NULLCHAR;
	}
	*cp++ = '\0';	/* Now points to directory field */

	if ( directory != NULL )
		*directory = cp;

	if((cp = strpbrk(cp," \t")) == NULLCHAR)	{
		/* Permission field missing */
		free(buf);
		return NULLCHAR;
	}
	*cp++ = '\0';	/* now points to permission field */

	if ( permission != NULL )	{
		if(!strnicmp(cp,"0x",2))
			*permission = htol(cp);
		else
			*permission = atol(cp);
	}

	if((cp = strpbrk(cp," \t")) == NULLCHAR)	{
		/* IP address missing */
		if ( ip_address != NULL )
			*ip_address = 0L;
	} else {
		*cp++ = '\0';	/* now points at IP address field */
		if ( ip_address != NULL )
			*ip_address = resolve( cp );
	}
	return buf;
}


/* Subroutine for logging in the user whose name is name and password is pass.
   The buffer path should be long enough to keep a line from the userfile.
   If pwdignore is true, the password check will be overridden.
   The return value is the permissions field or -1 if the login failed.
   Path is set to point at the path field, and pwdignore will be true if no
   particular password was needed for this user.
 */
long
userlogin(name,pass,path,len,pwdignore)
char *name;
char *pass;
char **path;
int len;			/* Length of buffer pointed at by *path */
int *pwdignore;
{
	char *buf;
	char *password;
	char *directory;
	long permission;
	int anonymous;
	char *cp;
	char hashpass[16];
	MD5_CTX md;

	if ( (buf = userlookup( name, &password, &directory,
			&permission, NULL )) == NULLCHAR ) {
		return -1;
	}

	anonymous = *pwdignore;
	if(strcmp(password,"*") == 0)
		anonymous = TRUE;	/* User ID is password-free */
	if (!anonymous) {
		if(readhex(hashpass,password,sizeof(hashpass)) != sizeof(hashpass)){
			/* Invalid hashed password in file */
			free(buf);
			return -1;
		}
		MD5Init(&md);
		MD5Update(&md,name,strlen(name));
		MD5Update(&md,pass,strlen(pass));
		MD5Final(&md);
		if(memcmp(&md.digest,hashpass,sizeof(hashpass)) != 0){
			/* Incorrect password given */
			free(buf);
			return -1;
		}
	}
	if ( strlen( directory ) + 1 > len ) {
		/* not enough room for path */
		free(buf);
		return -1;
	}

#if   defined(AMIGA)
	/*
	 * Well, on the Amiga, a file can be referenced by many names:
	 * device names (DF0:) or volume names (My_Disk:).  This hunk of code
	 * passed the pathname specified in the ftpusers file, and gets the
	 * absolute path copied into the user's buffer.  We really should just
	 * allocate the buffer and return a pointer to it, since the caller
	 * really doesn't have a good idea how long the path string is..
	 */
	if ( (directory = pathname("", directory)) != NULLCHAR ) {
		strcpy(*path, directory);
		free(directory);
	} else {
		**path = '\0';
	}
#else
	strcpy(*path,directory);
	/* Convert any backslashes to forward slashes, for backward
	 * compatibility with the old NET
	 */
	while((cp = strchr(*path,'\\')) != NULLCHAR)
		*cp = '/';
#endif
	free(buf);
	*pwdignore = anonymous;
	/* Finally return the permission bits */
	return permission;
}
/* MD5 hash plaintext passwords in user file */
void
usercvt()
{
	FILE *fp,*fptmp;
	char *buf;
	char hexbuf[16];
	int needsit = 0;
	int len,nlen,plen,i;
	char *pass;
	MD5_CTX md;

	if((fp = fopen(Userfile,READ_TEXT)) == NULLFILE)
		return;		/* Userfile doesn't exist */

	buf = mallocw(BUFSIZ);
	while(fgets(buf,BUFSIZ,fp) != NULLCHAR){
		rip(buf);
		len = strlen(buf);
		if(len == 0 || *buf == '#')
			continue;	/* Blank or comment line */

		if((nlen = strcspn(buf,Whitespace)) == len)
			continue;	/* No end to the name! */

		/* Skip whitespace between name and pass */
		for(pass=&buf[nlen];isspace(*pass);pass++)
			;
		if(*pass != '\0' && *pass != '*'
		 && readhex(hexbuf,pass,sizeof(hexbuf)) != 16){
			needsit = 1;
			break;
		}
	}
	if(!needsit){
		/* Everything is in order */
		fclose(fp);
		free(buf);
		return;
	}
	/* At least one entry needs its password hashed */
	rewind(fp);
	fptmp = tmpfile();
	while(fgets(buf,BUFSIZ,fp) != NULLCHAR){
		rip(buf);
		if((len = strlen(buf)) == 0 || *buf == '#'
		 || (nlen = strcspn(buf,Whitespace)) == len){
			/* Line is blank, a comment or unparseable;
			 * copy unchanged
			 */
			fputs(buf,fptmp);
			fputc('\n',fptmp);
			continue;
		}
		/* Skip whitespace between name and pass */
		for(pass=&buf[nlen];isspace(*pass);pass++)
			;

		if(*pass == '\0' || *pass == '*'
		 || (plen = strcspn(pass,Whitespace)) == strlen(pass)
		 || readhex(hexbuf,pass,sizeof(hexbuf)) == sizeof(hexbuf)){
			/* Other fields are missing, no password is required,
			 * or password is already hashed; copy unchanged
			 */
			fputs(buf,fptmp);
			fputc('\n',fptmp);
			continue;
		}
		MD5Init(&md);
		MD5Update(&md,buf,nlen);	/* Hash name */
		MD5Update(&md,pass,plen);	/* Hash password */
		MD5Final(&md);
		fwrite(buf,1,nlen,fptmp);	/* Write name */
		fputc(' ',fptmp);		/* and space */
		for(i=0;i<16;i++)	/* Write hashed password */
			fprintf(fptmp,"%02x",md.digest[i] & 0xff);
		fputs(&pass[plen],fptmp);	/* Write remainder of line */
		fputc('\n',fptmp);
	}
	/* Now copy the temp file back into the userfile */
	fclose(fp);
	rewind(fptmp);
	if((fp = fopen(Userfile,WRITE_TEXT)) == NULLFILE){
		printf("Can't rewrite %s\n",Userfile);
		free(buf);
		return;
	}
	while(fgets(buf,BUFSIZ,fptmp) != NULLCHAR)
		fputs(buf,fp);
	fclose(fp);
	fclose(fptmp);
	free(buf);
}

static char *Files[] = {
	"Startup", "Userfile", "Hostfile", "Maillog", "Mailspool", "Mailqdir",
	"Mailqueue", "Routeqdir", "Alias", "Group", "Dfile", "Fdir", "Fdbase",
	"Quotes", "Tutor", "Info", "News", "Spool", "Arealist", "AreaSlist",
	"Rewritefile", "Signature", "Historyfile", "Helpdir", "UDefaults",
	"UDefbak", "Popusers", "Newsdir", "Forwardfile", "Netromfile",
	"Onexit", "Expirefile", "FTPHelp", "Ftpmotd", "EditorHelp",
	"MOTDfile", "MOTDsysfile", "NEWUSERfile", "WhitePagesBBS",
	"WhitePages", "ConfInfo", "ConfHlp", "NetControlHlp", "Active",
	"Pointer", "NInfo", "Nhelp", "History", "Forward", "Poll",
	"MBOXHelp", "CommandHelp", "GPSfile", "ANSIArea", "ANSILogin",
	"SMILEYFile", "ConfNews", "VersionFile", "Command", "Trace",
	"DelegateFile", "UserCmds", "UCmdsHelp", NULLCHAR
};


void setname(name, file)
char *name, *file;
{
char **this = NULLCHARP;
int k;

	for (k = 0; Files[k] != NULLCHAR; k++)	{
		if (!stricmp (Files[k], name))
			break;
	}
	if (Files[k] == NULLCHAR)
		return;
	switch (k)	{
		case 0:		this = &Startup;	break;
		case 1:		this = &Userfile;	break;
		case 2:		this = &Hostfile;	break;
		case 3:		this = &Maillog;	break;
		case 4:		this = &Mailspool;	break;
		case 5:		this = &Mailqdir;	break;
		case 6:		this = &Mailqueue;	break;
		case 7:		this = &Routeqdir;	break;
		case 8:		this = &Alias;		break;
		case 9:		this = &Group;		break;
		case 10:	this = &Dfile;		break;
		case 11:	this = &Fdir;		break;
		case 12:	this = &Fdbase;		break;
		case 13:	this = &Quotes;		break;
#ifdef TUTOR
		case 14:	this = &Tutor;		break;
		case 15:	this = &Info;		break;
		case 16:	this = &News;		break;
#endif
		case 17:	this = &Spool;		break;
		case 18:	this = &Arealist;	break;
		case 19:	this = &AreaSlist;	break;
		case 20:	this = &Rewritefile;	break;
#ifdef MAILBOX
		case 21:	this = &Signature;	break;
		case 22:	this = &Historyfile;	break;
		case 23:	this = &Helpdir;	break;
#ifdef USERLOG
		case 24:	this = &UDefaults;	break;
		case 25:	this = &UDefbak;	break;
#endif
#endif
#if (defined(POP) || defined(POP2CLIENT) || defined(POP2SERVER) || defined(POP3CLIENT) || defined(POP3SERVER))
		case 26:	this = &Popusers;	break;
#endif
#if (defined(NNTP) || defined(NNTPS))
		case 27:	this = &Newsdir;	break;
#endif
#ifdef MBFWD
		case 28:	this = &Forwardfile;	break;
#endif
#ifdef NETROM
		case 29:	this = &Netromfile;	break;
#endif
		case 30:	this = &Onexit;		break;
#ifdef EXPIRY
		case 31:	this = &Expirefile;	break;
#endif
		case 32:	this = &FTPHelp;	break;
		case 33:	this = &Ftpmotd;	break;
		case 34:	this = &EditorHelp;	break;
		case 35:	this = &MOTDfile;	break;
		case 36:	this = &MOTDsysfile;	break;
		case 37:	this = &NEWUSERfile;	break;
		case 38:	this = &WhitePagesBBS;	break;
		case 39:	this = &WhitePages;	break;
#ifdef  CONVERS
		case 40:	this = &ConfInfo;	break;
		case 41:	this = &ConfHlp;	break;
		case 42:	this = &NetControlHlp;	break;
#endif
#ifdef NNTPS
		case 43:	this = &Active;		break;
		case 44:	this = &Pointer;	break;
		case 45:	this = &NInfo;		break;
		case 46:	this = &Nhelp;		break;
		case 47:	this = &History;	break;
		case 48:	this = &Forward;	break;
		case 49:	this = &Poll;		break;
#endif
		case 50:	this = &MBOXHelp;	break;
		case 51:	this = &CommandHelp;	break;
#ifdef GPS
		case 52:	this = &GPSfile;	break;
#endif
		case 53:	this = &ANSIArea;	break;
		case 54:	this = &ANSILogin;	break;
		case 55:	this = &SMILEYFile;	break;
		case 56:	this = &ConfNews;	break;
		case 57:	this = &VersionFile;	break;
#ifdef UNIX
		case 58:	this = &Command_sessmgr;break;
		case 59:	this = &Trace_sessmgr;	break;
#endif
#ifdef DELEGATE
		case 60:	this = &DelegateFile;	break;
#endif
#ifdef TUTOR
		case 61:	this = &UserCmds;	break;
		case 62:	this = &UCmdsHelp;	break;
#endif
	}
	if (this != NULLCHARP)	{
		if(Initroot)
			free (*this);
		*this = strdup(file);
	}
}

extern char *skipwhite __ARGS((char *));


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

    undosify(config);
    if((fp = fopen(config,"r")) == NULL) {
	if (verbose)	{
	        sprintf(buf, "Cannot open '%s'\n",config);
        	firstMsg = strdup (buf);
        }
        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 */
        setname(name,file);
    }
    fclose(fp);
    Assigned = 1;
}


