#include <fido.h>
#include <ascii.h>

#define same(s1,s2) (strcmp(s1,s2)==0)

/*
	This is the v11 to v12 convertor program; it contains
a hardcoded copy of the old FIDO.H file.

*/

/*
	Big Fido include file
	T. Jennings 1 Aug 86 

NOTE: "OBSO" means "Obsolete"; they exist currently, but may not 
in the future. Please use only structures defined as "PUBLIC".
Structures not marked "PUBLIC" may change at any time.

*/

#define OLDMAXLREAD 10

struct  _oldusr {
	char name[36];		/* callers ASCII name, */
	char city[36];		/* city and state, */

/* This structure takes exactly 40 bytes, and replaces the old 
first date. (Which was luckily int[20] by mistake!) */

	struct {
		int area;	/* message area */
		int msg;	/* last msg read */
	} lastmsg[OLDMAXLREAD];

	char pwd[16];		/* what else, */
	int times;		/* # times called, */
	int help;		/* last help setting, */
	int tabs;		/* 1 == expand tabs, */
	int nulls;		/* number of nulls after CR, */
	int msg;		/* last selected message area, */
	int more;		/* last MORE setting, */
	int priv;		/* caller privelege level, */
	char ldate[20];		/* last time called, */
	int time;		/* total time on system in 1 day, */
	unsigned bits;		/* various bit flags, */
	unsigned upld;		/* total K byte uploaded, */
	unsigned dnld;		/* total K bytes downloaded, */
	unsigned dnldl;		/* download, for limiting, */
	int files;		/* last selected file area, */
	char width;		/* screen width, */
	char len;		/* screen length, */
	int credit;		/* credit, in cents, */
	int debit;		/* debit, in cents, */
};

/* 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 */

/* MAIL.SYS file structure. The contents of this does not conform
to internal standards; it is for export to other programs. */

/* OBSO */

struct _mail {
	int node;		/* local node number, */
	float fudge;		/* obs */
	int rate;		/* obs */
	char msgpath[80];	/* path to find mail in */
	char filepath[80];	/* mail file path */
	int net;		/* net number */
	int alt_node;		/* alternate node number */
	int alt_net;		/* alternate net number */
};

#define OLDSCHEDS (5 * DAYS_WK)	/* size of time table */

/* Standard time of day structure. */

struct _time {
	int year,month,day,daywk;
	int hour,mins,sec;
};

/* Scheduler time structure. */

struct _oldsched {
	struct _time time;
	int len;
	int enable;		/* 1 == enabled -1 == disabled 0 == deleted */
	int trigger;
	int result;		/* returned value */
	char tag;		/* schedule tag */
	int a,b,c,d,e;

};
char dayname[8][4] = {
	"Sun",
	"Mon",
	"Tue",
	"Wed",
	"Thu",
	"Fri",
	"Sat",
	"All"
};

unsigned _stack = 18000;

char path[SS];		/* where we put files */

main() {

char buff[SS];

	printf("11-TO-12 (1 Jan 90) Fido Version 11 Converter for ");
	copr();
	allmem();
	fastfile(8);

	buff[0]= NUL;
	while (1) {
		cputs("\r\nDrive or subdirectory to put the version 12 files,\r\nor blank for current directory: ");
		getstring(buff);
		cputs("\r\n");
		buff[PS]= NUL;				/* truncate to fit */
		if (! isdir(buff)) {			/* if its not valid, */
			if (ask("Subdirectory doesn't exist, create it now")) mkdir(buff);
			else continue;			/* make it or quit now */
			if (isdir(buff)) break;
			cprintf("Can't create it!\r\n");

		} else break;				/* OK as is */
	}
	fixdir(buff);					/* append / *.* */
	strip_path(path,buff);				/* copy prefix only */
	cvtfido();
	cvtcaller();
	cvtareas();
	cvtevents();
	cvtbat();		/* this creates v11FIDO.INI */
	cvtmdm();
	cvtmail();
	cvtbbs();
}
/* Do FIDOMDM.BBS */

cvtmdm() {
int f,i;
char buff[SS];

	i= open("fidomdm.bbs",0);
	if (i == -1) return;

	printf("\r\n");
	printf("+-----------------------------------------------------------\r\n");
	printf("This step puts one line of the special modem initialization\r\n");
	printf("file \"FIDOMDM.BBS\" into the V11FIDO.INI file. Only one\r\n");
	printf("line of the file will be used. This step is optional; most\r\n");
	printf("installations don't even have a \"FIDOMDM.BBS\" file.\r\n");
	printf("\r\nIMPORTANT: Fido's modem handling is radically different than\r\n");
	printf("before; for instance the modem should NOT be in auto-answer. Refer\r\n");
	printf("to the \"Modem Basics\" Appendix in the manual before using this\r\n");
	printf("special initialization.\r\n");
	if (! ask("Do you want to do this")) {
		close(i);
		return;
	}

	rline(i,&buff,sizeof(buff));		/* line from FIDOMDM.BBS */
	close(i);

	sprintf(buff,"%sv11fido.ini",path);
	f= open(buff,2);			/* open or create */
	while (rline(f,buff,sizeof(buff)));	/* got to EOF */
	fprintf(f,";MAKE SURE the modem is NOT in auto-answer (ATS0=1)\r\n");
	fprintf(f,";Please refer to the \"Modem Basics\" appendix\r\n");
	fprintf(f,";modem-string %s   ;special initialization\r\n",buff);
	close(f);

	printf("\r\n\r\n");
}

/* Convert the .BBS text files. Basically rename copies. */

cvtbbs() {

	printf("\r\n");
	printf("+-----------------------------------------------------------\r\n");
	printf("This step will make copies of all the .BBS text files\r\n");
	printf("whose names changed from v11 to v12. You can find a full list\r\n");
	printf("and description in the manual, but the file name changes are listed\r\n");
	printf("below. (If you specified a subdirectory to put the v12 files in,\r\n");
	printf("this will also make duplicate copies of the files that didn't\r\n");
	printf("change for your convenience.)\r\n");
	printf("\r\n");
	printf("NEWUSER1.BBS becomes NEWCLR1.BBS\r\n");
	printf("NEWUSER2.BBS becomes NEWCLR2.BBS\r\n");
	printf("QNEWUSER.BBS becomes NEWCLR.QST\r\n");
	printf("ANEWUSER.BBS becomes NEWCLR.ANS\r\n");
	printf("BULLETIN.BBS becomes BULLETIN.1\r\n");
	printf("QUESTION.BBS becomes MAINSECT.QST\r\n");
	printf("ANSWERS.BBS  becomes MAINSECT.ANS\r\n");
	printf("C.HLP        becomes CHANGE.HLP\r\n");
	printf("YELL.BBS     becomes PAGE.BBS\r\n");
	printf("SYSOP.LOG    becomes FIDO.LOG\r\n");
	printf("MAILER.LOG   becomes FIDONET.LOG\r\n");
	if (! ask("Do you want to do this")) return;

	printf("\r\n\r\n");

	if (! copyfile("newuser1.bbs","newclr1.bbs")) return;
	if (! copyfile("newuser2.bbs","newclr2.bbs")) return;
	if (! copyfile("qnewuser.bbs","newclr.qst")) return;
	if (! copyfile("anewuser.bbs","newclr.ans")) return;
	if (! copyfile("bulletin.bbs","bulletin.1")) return;
	if (! copyfile("question.bbs","mainsect.qst")) return;
	if (! copyfile("answers.bbs","mainsect.ans")) return;
	if (! copyfile("yell.bbs","page.bbs")) return;

	if (*path) {
		if (! copyfile("welcome1.bbs","")) return;
		if (! copyfile("welcome2.bbs","")) return;
		if (! copyfile("nopwd.bbs","")) return;
		if (! copyfile("dnldl.bbs","")) return;
		if (! copyfile("quotes.bbs","")) return;
	}
	if (! copyfile("mailer.log","fidonet.log")) return;
	if (! copyfile("sysop.log","fido.log")) return;
}
/* Copy file A to file B. */

copyfile(filea,fileb)
char *filea,*fileb;
{
int n,i,o;
char buff[10240];

	if (! *fileb) fileb= filea;
	printf("Copying %s to %s%s: ",filea,fileb);

	i= open(filea,0);
	if (i == -1) {
		printf("original doesn't exist, skipping it\r\n",filea);
		return(1);
	}
	o= make(fileb);
	if (o == -1) {
		printf("can't create the new file?\r\n");
		close(i);
		return(0);
	}
	while (n= read(i,&buff,sizeof(buff))) {
		if (write(o,&buff,n) != n) {
			printf("Disk Full!\r\n");
			close(i);
			close(o);
			return(0);
		}
	}
	close(i); close(o);
	printf("complete\r\n");
	return(1);
}

/* Convert the old events. */

cvtevents() {
struct _oldsched sched;
int f,o,i;
char buff[256];

	printf("\r\n");
	printf("+-----------------------------------------------------------\r\n");
	printf("This step will convert v11's scheduled events (stored\r\n");
	printf("in SCHED.BBS) into a v12 V11EVENTS.INI configuration file.\r\n");
	printf("You can replace the Fido-Software supplied EVENTS.INI with\r\n");
	printf("V11EVENTS.INI, but it is suggested that you preserve the\r\n");
	printf("documentation contained in the sample file, in order to take\r\n");
	printf("advantage of extentions and additions to the software.\r\n");
	if (! ask("Do you want to do this")) return;

	f= open("sched.bbs",0);
	if (f == -1) {
		printf("Can't find SCHED.BBS, skipping this step.\r\n\r\n");
		return;
	}
	o= make("v11events.ini",2);

	while (1) {
		if (read(f,&sched,sizeof(sched)) != sizeof(sched)) break;

		*buff= 0;
		if (sched.enable == 0) continue;
		if (sched.enable == -1) strcat(buff,";");

		sprintf(&buff[strlen(buff)],"%s ",dayname[sched.time.daywk]);
		sprintf(&buff[strlen(buff)],"%2d:%02d ",sched.time.hour,sched.time.mins);
		sprintf(&buff[strlen(buff)],"%4d ",sched.len);
		switch (sched.tag) {
			case 'X':
			case 'Z':	/* next best */
				sprintf(&buff[strlen(buff)],"Errorlevel %2d  ; old Schedule %c",sched.result,sched.tag);
				break;

			case 'Y':
				sprintf(&buff[strlen(buff)],"Page           ; same as before");
				break;

			default:
				sprintf(&buff[strlen(buff)],"FidoNet %c ",sched.tag);
				break;
		}
		fprintf(o,"%s\r\n",buff);
	}
	close(f);
	close(o);
	printf("\r\n\r\n");
}

/* Create FIDO.SYS with the numebr of callers, etc */

cvtfido() {
int f;
char *p;
struct _sys sys;
struct _fido fido;
long l;

	printf("\r\n");
	printf("+-----------------------------------------------------------\r\n");
	printf("This step will create a basic v12 FIDO.SYS that contains \r\n");
	printf("v11's number of of callers, quote file position, etc.\r\n");

	if (! ask("Do you want to do this")) return;

	f= open("system.bbs",0);
	if (f == -1) {
		printf("Can't find SYSTEM.BBS? which contains the info\r\n");
		printf("mentioned above.\r\n\r\n\r\n");
		return;
	}
	read(f,&sys,sizeof(sys));
	close(f);

	p= (char *) &fido;			/* clear out the structure */
	for (f= sizeof(struct _fido); f--;) *p++= 0;

	l= sys.ms_callers; l <<= 16L;		/* make a long */
	l += sys.ls_callers;
	fido.callers= l;
	fido.quote_pos= sys.quote_pos;

	f= make("fido.sys");
	write(f,&fido,sizeof(fido));
	close(f);
	printf("\r\n\r\n");
}

/* Convert MAIL.SYS */

cvtmail() {

struct _mail mail;
int n,f;
char buff[256];

	printf("\r\n");
	printf("+-----------------------------------------------------------\r\n");
	printf("This step converts your node number stored in MAIL.SYS, that you\r\n");
	printf("set with the '4' command, into text commands in the configuration\r\n");
	printf("file \"V11FIDO.INI\".\r\n");

	if (! ask("Do you want to do this")) return;

	f= open("mail.sys",0);
	if (f != -1) {
		n= read(f,&mail,sizeof(mail));
		close(f);
	}
	if ((f == -1) || (n != sizeof(mail))) {
		printf("\"MAIL.SYS\" is missing or damaged\r\n\r\n");
		return;
	}
	sprintf(buff,"%sv11fido.ini",path);
	f= open(buff,2);		/* open or create */
	if (f != -1) while (rline(f,buff,sizeof(buff)));
	else f= make("v11fido.ini");

	if (mail.node < 0) mail.node= 0;
	if (mail.net < 0) mail.net= 0;
	if (mail.alt_node < 0) mail.alt_node= 0;
	if (mail.alt_net < 0) mail.alt_net= 0;

	fprintf(f,"node %d              ;your node number\r\n",mail.node);
	fprintf(f,"net %d               ;your net number\r\n",mail.net);
	if (mail.node != mail.alt_node) {
		fprintf(f,"alt_node %d          ;your alternate node number\r\n",mail.alt_node);
		fprintf(f,"alt_net %d           ;your alternate net number\r\n",mail.alt_net);
	}
	close(f);
	printf("\r\n\r\n");
}
		
/* Convert the batch file and MAIL.SYS to V11FIDO.INI and a new batch file. */

cvtbat() {
char c,*cp,*op,arg[SS],buff[SS];
int f,n,i,o;

	printf("\r\n");
	printf("+-----------------------------------------------------------\r\n");
	printf("This step converts the command line switches in your v11 .BAT batch file\r\n");
	printf("into a v12 configuration file V11FIDO.INI, and generates a new .BAT file\r\n");
	printf("called \"FIDOV12.BAT\".\r\n");

	if (! ask("Do you want to do this")) return;

	while (1) {
		printf("Enter the name of your batch file: ");
		getstring(buff);
		cputs("\r\n");
		cp= buff;
		if (! *cp) {
			cprintf("No Batch File specified, skipping this step\r\n");
			return;
		}
		while (*cp) {			/* search for any extention */
			if (*cp == '.') break;
			++cp;
		}
		strcpy(cp,".bat");		/* add .BAT */
		stoupper(buff);			/* make it pretty, */
		i= open(buff,0);
		if (i != -1) break;
		printf("Can't find your batch file \"%s\"\r\n",buff);
	}
	o= make("fidov12.bat");			/* new batch file, */
	f= make("v11fido.ini");			/* FIDO.INI file */

	while (rline(i,buff,sizeof(buff))) {
		cp= skip_delim(buff);		/* skip leading trash */
		cpyarg(arg,cp);			/* copy of first word, */
		stolower(arg);			/* look for FIDO_xxx */
		arg[5]= NUL;			/* check for "fido_" */
		if (same(arg,"fido_")) {	/* if we found it, */
			op= &cp[4];		/* point to the "_" */

			while (isalpha(*cp) || (*cp == '_'))
				++cp;		/* skip rest of program name */

			strcpy(op," ");		/* make it now "fido " */

			stolower(cp);
			while (*cp) {		/* process all/any switches */
				if (isdigit(*cp)) {
					n= atoi(cp);
					while (isdigit(*cp)) ++cp;
					--cp;

				} else if (*cp == '%') {
					sprintf(&op[strlen(op)]," \%%c",++cp);

				} else if (*cp == '/') switch (*++cp) {
					case 'j': fprintf(f,"Modem-type %-3d        ;refer to manual\r\n",n); break;
					case 'y': fprintf(f,"path-display no      ;(yes,no) paths displayed in A)rea command\r\n"); break;
					case 'i': sprintf(&op[strlen(op)]," %3d/i",n); break;
					case 'm': fprintf(f,"private yes          ;(yes,no) private; no new caller logins\r\n"); break;
					case 'p': fprintf(f,"default-priv %-3d      ;0 - 7; 2 is NORMAL, 5 is EXTRA\r\n",DISGRACE); break;
					case 'f': fprintf(f,"first-limit %-3d       ;minutes\r\n",n); break;
					case 'l': fprintf(f,"normal-limit %-3d      ;minutes\r\n",n); break;
					case 's': fprintf(f,"signon-limit %-3d      ;minutes\r\n",n); break;
					case 'd': fprintf(f,"daily-limit %-3d       ;minutes per 24 hr period\r\n",n); break;
					case 'k': fprintf(f,"K-limit %-3d           ;Kbyte/day download limit\r\n",n); break;
					case 'v': fprintf(f,"cd-bit %-3d            ;serial status port mask bit; 1,2,4,8...128\r\n",n); break;
					case 'u': fprintf(f,"xfer-display no      ;(yes,no) display running status on all file transfers\r\n"); break;
					case 'g': fprintf(f,"connect-tries %-3d     ;Fidonet dial attempts, with connect\r\n",n); break;
					case '2': strcat(&op[strlen(op)]," /2"); break;
				}
				++cp;
			}
		}
		fprintf(o,"%s\r\n",buff);	/* new .BAT file line */
	}
	close(i);
	close(o);
	close(f);
	printf("\r\n\r\n");
}
/* Convert the old SYSTEM.BBS files into an AREAS.INI */

cvtareas() {
int s,o;
char *p;

	printf("\r\n");
	printf("+-----------------------------------------------------------\r\n");
	printf("Convert v11's SYSTEMn.BBS files into a v12 AREAS.INI\r\n");
	printf("configuration file. You can replace the Fido Software-supplied\r\n");
	printf("AREAS.INI with this file, but it is suggested that you\r\n");
	printf("preserve the documentation contained in the sample file, in\r\n");
	printf("order to take advantage of extentions and additions to the\r\n");
	printf("software.\r\n");

	if (! ask("Do you want to do this")) return;

	o= make("V11AREAS.INI");

	fprintf(o,";\r\n; Message Areas\r\n;\r\n");
	for (s= 0; s < 100; s++) cvtsys(0,s,o);		/* do msg areas */
	fprintf(o,";\r\n; File Areas\r\n;\r\n");
	for (s= 0; s < 100; s++) cvtsys(1,s,o);		/* do file areas */
	close(o);
	printf("\r\n\r\n");
}

/* Convert the msg or file area in this system file to a line for the
.INI file. */

cvtsys(mf,s,o)
int mf;		/* 1 == file area */
int s;		/* SYSTEMn.BBS */
{
int v,a,f,i;
char *cp,ln[SS];
struct _sys sys;


	if (s) sprintf(ln,"system%d.bbs",s);
	else strcpy(ln,"system.bbs");
	f= open(ln,0);
	if (f == -1) return;

/* AARGH: As shipped, I was supplying SYSTEM1.BBS that is short; its actually 
a v10 file! Skip read error check. 

	if (read(f,&sys,sizeof(sys)) != sizeof(sys)) return;
*/
	read(f,&sys,sizeof(sys));
	close(f);

	switch (sys.priv) {
		case -2: v= TWIT; break;
		case 0: v= DISGRACE; break;
		case 4: v= PRIVEL; break;
		case 6: v= EXTRA; break;
		case 10: v= SYSOP; break;
		case 2: 
		default:
			v= NORMAL; break;
	}

	if (s == 0) v= SYSOP;			/* area 0 always sysop */

	if (*sys.msgpath && !mf) {
		strcpy(ln,sys.msgpath);		/* try to load DIR.BBS */
		strcat(ln,"dir.bbs");
		a= open(ln,0);
		if (a != -1) {
			rline(a,ln,sizeof(ln));
			close(a);
			for (cp= ln; *cp; cp++) {
				if (*cp < ' ') *cp= 0;
			}

		} else strcpy(ln,"No msg area description!");

		strippdelim(sys.msgpath);	/* strip trailing /'s */
		fprintf(o,"MsgArea = %s D=\"%s\" P=%d",sys.msgpath,ln,v);
		if (s == 0) fprintf(o," O=G)oodBye"); 
		if (s == 1) fprintf(o," O=NewCaller"); 
		if (sys.attrib & SYSMAIL) fprintf(o," O=FidoNet"); 
		fprintf(o," ; was v11 msg area #%d\r\n",s);
	}
	if (*sys.filepath && mf) {
		strcpy(ln,sys.filepath);	/* try to load DIR.BBS */
		strcat(ln,"dir.bbs");
		a= open(ln,0);
		if (a != -1) {
			rline(a,ln,sizeof(ln));
			close(a);
			for (cp= ln; *cp; cp++) {
				if (*cp < ' ') *cp= 0;
			}

		} else strcpy(ln,"No file area description!");

		strippdelim(sys.filepath);		/* strip trailing \'s */
		fprintf(o,"FileArea = %s D=\"%s\" P=%d",sys.filepath,ln,v);

		strippdelim(sys.uppath);
		if (*sys.uppath) {
			fprintf(o," U=\"%s\"",sys.uppath);
			if (! same(sys.filepath,sys.uppath)) fprintf(o," O=OverWrite ");
		}
		if (s == 1) fprintf(o," O=Newcaller");
		if (sys.attrib & SYSMAIL) fprintf(o," O=FidoNet"); 
		fprintf(o," ; was v11 file area #%d\r\n",s);
	}
	close(f);
}
/* Strip any trailing path delimiters from the v11 path prefix. */

strippdelim(cp)
char *cp;
{
	if (strlen(cp) > 1) {		/* dont strip \ by itself! */
		while (*cp) ++cp;	/* find the end, */
		--cp;			/* strip trailing */
		if (ispath_delim(*cp))	/* path delimiters */
			*cp= NUL;
	}
}

/* Convert the caller file */

cvtcaller() {

struct _clr caller;		/* new */
struct _oldusr oldcaller;	/* old */

int i,j,o;
char *cp;

	printf("\r\n");
	printf("+-----------------------------------------------------------\r\n");
	printf("Creating v12's CALLER.SYS from v11's USER.BBS.\r\n");

	if (! ask("Do you want to do this")) return;

	cp= (char *) &caller;
	for (i= sizeof(caller); --i;) *cp++= 0;		/* empty it */

	o= make("caller.sys");
	i= open("USER.BBS",0);
	if (i == -1) {
		cprintf("v11's USER.BBS doesn't exist, skipping this step\r\n");
		close(o);
		printf("\r\n\r\n");
		return;
	}

	while (1) {
		if (read(i,&oldcaller,sizeof(oldcaller)) != sizeof(oldcaller)) break;
		
		caller.version= CLRVER;
		strcpy(caller.name,oldcaller.name);
		strcpy(caller.city,oldcaller.city);
		strcpy(caller.pwd,oldcaller.pwd);
		strcpy(caller.date,oldcaller.ldate);

		caller.stuff= 0L;
		caller.tleft= 0;
		caller.baud= 0;
		caller.sum= strsum(caller.name);

		for (j= 0; j < MAXLREAD; j++) caller.lastmsg[j].area= 255;

		for (j= 0; j < OLDMAXLREAD; j++) {
			if (caller.lastmsg[j].area != 0) {
				caller.lastmsg[j].area= oldcaller.lastmsg[j].area - 1;
				caller.lastmsg[j].msg= oldcaller.lastmsg[j].msg;
			}
		}

		switch (oldcaller.priv) {
			case -2: setuval(&caller,TWIT,CLR_PRV,CLR_PRVS); break;
			case 0: setuval(&caller,DISGRACE,CLR_PRV,CLR_PRVS); break;
			case 4: setuval(&caller,PRIVEL,CLR_PRV,CLR_PRVS); break;
			case 6: setuval(&caller,EXTRA,CLR_PRV,CLR_PRVS); break;
			case 10: setuval(&caller,SYSOP,CLR_PRV,CLR_PRVS); break;
			case 2: 
			default: setuval(&caller,NORMAL,CLR_PRV,CLR_PRVS); break;
		}

		switch (oldcaller.help) {
			case 2: setuval(&caller,EXPERT,CLR_HLP,CLR_HLPS); break;
			case 4: setuval(&caller,REGULAR,CLR_HLP,CLR_HLPS); break;
			case 6:
			default: setuval(&caller,NOVICE,CLR_HLP,CLR_HLPS); break;
		}

		setuval(&caller,oldcaller.width,CLR_WID,CLR_WIDS);
		setuval(&caller,oldcaller.len,CLR_LEN,CLR_LENS);
		setuval(&caller,oldcaller.more,CLR_MOR,CLR_MORS);
		setuval(&caller,oldcaller.nulls,CLR_NUL,CLR_NULS);

		caller.msg= oldcaller.msg;
		caller.files= oldcaller.files;
		caller.time= oldcaller.time;
		caller.times= oldcaller.times;
		caller.dnld= oldcaller.dnld;
		caller.dnldl= oldcaller.dnldl;
		caller.upld= oldcaller.upld;
		caller.credit= oldcaller.credit;
		caller.debit= oldcaller.debit;
		caller.keys= KNONE;

		if (write(o,&caller,sizeof(caller)) != sizeof(caller)) {
			printf("DISK FULL!!!\r\n");
			close(i);
			close(o);
			exit(1);
		}
	}
	close(i);
	close(o);

	printf("\r\n\r\n");
}

/* Return the value from the caller bit record. */

uval(caller,mask,shift)
struct _clr *caller;
int mask,shift;
{
int n;

	n= (caller-> stuff >> shift) & mask;
	return(n);
}

/* Set a field in the caller bit record. */

setuval(caller,val,mask,shift)
struct _clr *caller;
int val,mask,shift;
{
long n;

	n= mask; n <<= shift;			/* we NEED long arith */
	caller-> stuff &= ~n;			/* remove old value */

	n= val & mask; n <<= shift;		/* set it THEN shift it */
	caller-> stuff |= n;			/* add in new value */
}

/* Create the checksum of a string. */

strsum(s)
char *s;
{
int n;

	for (n= 0; *s;) n += *s++;
	return(n);
}
/* Ask a question. */

ask(s)
char *s;
{
char c,cp,buff[SS];

	while (1) {
		cputs(s);
		cputs(" [y,n]: ");
		getstring(buff);		/* get one char */
		cputs("\r\n");
		c= tolower(*buff);		/* lower case for testing */
		if (c == 'y') break;		/* Y is OK, */
		if (c == 'n') break;		/* N is OK, */
	}
	return(c == 'y');			/* return true == yes */
}

/* Write a formatted string to a file. */

fprintf(o,f)
int o;
char *f;
{
char buf[500];

	_spr(buf,&f);
	write(o,buf,strlen(buf));
}
/* Create a file in the output directory. */

make(fn)
char *fn;
{
char buff[SS];
int f;

	strcpy(buff,path);
	strcat(buff,fn);
	f= creat(buff,2);
	return(f);
}
