#include <fido.h>	/* Fido v12's structures */

/*
	Generate a set of SYSTEMn.BBS files
	from FIDO.SYS

	Tom Jennings 18 Oct 87
	(k) All rights reversed

*/

/* Structure for each virtual bulletin board. */

/* OBSO */

struct _sys {
	unsigned ls_caller;	/* LS word of callers */
	int priv;		/* min. privelege to access this */
	char msgpath[40];	/* path for message base, */
	char bbspath[40];	/* path for .BBS files, */
	char hlppath[40];	/* path for HLP files, */
	char uppath[40];	/* path for uploads, */
	char filepath[40];	/* path for file area, */
	int attrib;		/* attributes */
	unsigned ms_caller;	/* MS word of callers */
	long quote_pos;		/* quote file index */
};
#define SYSMAIL 1		/* is a mail area */

int _stack = 4000;		/* Lattice kludge */

struct _fido fido;		/* *GLOBAL* v12 FIDO.SYS structure */

main() {
struct _sys sys;		/* v11 SYSTEMn.BBS file */
int f;				/* some old integer */
int i;				/* every program must have i, right? */
char fname[80];			/* a filename */
long off;			/* offset into FIDO.SYS file */

	printf("Generating disgusting SYSTEMn.BBS files\r\n");
	printf("T. Jennings 18 Oct 87\r\n");
	printf("(k) all rights reversed\r\n");

	f= open("fido.sys",0);			/* read FIDO.SYS */
	if (f == -1) {
		printf("Can't find FIDO.SYS!\r\n");
		exit(1);
	}
	read(f,&fido,sizeof(struct _fido));	/* too lazy to error check */
	if (fido.fido_version != FIDOVER) {
		printf("FIDO.SYS version doesn't match\r\n");
		close(f);
		exit(1);
	}
	for (i= 0; i < fido.marea_max; i++) 	/* do all Msg Areas */
		do_area(f,i,0);
	for (i= 0; i < fido.farea_max; i++) 	/* do all File Areas */
		do_area(f,i,1);

	close(f);				/* we're done with it */
	exit(0);
}


/* Convert (Msg, File) Area #(i) to a matching SYSTEMn.BBS, creating
the file if necessary. */

do_area(f,n,fa)
int f;		/* open FIDO.SYS handle */
int n;		/* area # */
int fa;		/* 0 == msg else file */
{
struct _area area;	/* v12 msg/file area */
struct _sys sys;	/* v11 SYSTEMn.BBS structure */
char fname[80];		/* v11 SYSTEMn filename */
int o;
char *cp;
int i;

	if (n) sprintf(fname,"SYSTEM%d.BBS",n);	/* goofy name */
	else strcpy(fname,"SYSTEM.BBS");

	o= open(fname,2);			/* try to open it, */
	if (o == -1) {				/* if doesnt exist (yet) */
		cp= (char *) &sys;		/* clear it out, */
		for (o= sizeof(struct _sys); o--;) *cp++= 0;
		o= creat(fname,2);		/* create it */
		if (o == -1) {
			printf("Can't create %s?\r\n",fname);
			return;
		}
	} else {
		read(o,&sys,sizeof(struct _sys)); /* preload existing stuff */
		lseek(o,0L,0);			/* seek for write out */
	}

	i= getarea(f,n,&area,fa);			/* get the right area, */
	switch (area.priv) {			/* translate priv */
		case 0: sys.priv= -1; break;	/* TWIT */
		case 1: sys.priv= 0; break;	/* DISGRACE */
		case 2: sys.priv= 2; break;	/* NORMAL */
		case 3: sys.priv= 4; break;	/* PRIVEL */
		case 4: sys.priv= 6; break;	/* EXTRA */
		case 7: sys.priv= 10; break;	/* SYSOP */
	}

	if (fa) {				/* if file area, */
		strcpy(sys.filepath,area.path);	/* copy both paths */
		strcpy(sys.uppath,area.upath);
		if (n == fido.netfarea) sys.attrib |= SYSMAIL;
		printf("File Area %d: %s\r\n",n,sys.filepath);

	} else {
		strcpy(sys.msgpath,area.path);	/* else single path */
		if (n == fido.netmarea) sys.attrib |= SYSMAIL;
		printf("Message Area %d: %s\r\n",n,sys.msgpath);
	}
	i= write(o,&sys,sizeof(struct _sys));	/* write it out, */
	close(o);
}


/* Get message or file area #n; return 0 if not set, illegal number
or other error. You could use this code in YOUR program. (hint hint) */

getarea(f,n,a,fa)
int f;			/* open FIDO.SYS handle */
int n;			/* area number */
struct _area *a;	/* struct to load */
int fa;			/* 1 == get a file area */
{
int i;
long off;

	if (n < 0) return(0);				/* no such area */
	off= 0L + sizeof(struct _fido);			/* offset to beg msg areas */
	if (fa) {					/* if a file area, */
		if (n >= fido.farea_max) return(0);	/* bound it */
		off += (long)(sizeof(struct _area) * fido.marea_max); /* beg file areas */

	} else if (n >= fido.marea_max) return(0);	/* msg area max */

	off += (long)(n * sizeof(struct _area));	/* offset plus area # */
	lseek(f,off,0);					/* seek there, */
	i= read(f,a,sizeof(struct _area));		/* read some, */

	if (i != sizeof(struct _area)) return(0);	/* check read error */
	a-> number= n;					/* set the path number */
	return(*a-> path != '\0');			/* invalid if no path set */
}
