#include <fido.h>

/*
	Dump the contents of NODELIST.NMP

*/

int nodefile;
int ntcfile;
int ndatfile;
int idxfile;
int ndxfile;
int zdxfile;

struct _nmap nmap;
struct _ndat ndat;
struct _ntc ntc;

int nodetotal;				/* satisfy link */
struct _fido fido;			/* satisfy link */
int connect_tries,dial_tries;		/* satisfy link */

char nodepath[80] = "";			/* current directory */

struct _node id;
struct _node altid;

main(argc,argv)
int argc;
char **argv;
{
int n,i;
struct _rptrcd rptrcd;
unsigned bits;
char *cp,name[SS],buff[SS];
char tag;

	printf("DumpNMP (13 Apr 90) NodeList Database Display for ");
	copr();
	allmem();
	fastfile(6);

	n= open("fido.sys",0);				/* load system stuff */
	if (n == -1) {
		clprintf("The Fido system file \"FIDO.SYS\" is missing!\r\n");
		exit(1);
	}
	read(n,&fido,sizeof(fido));
	close(n);
	if (fido.fido_version != FIDOVER) {
		clprintf("Wrong Fido/FidoNet or FidoMail version!\r\n");
		exit(1);
	}
	id.zone= fido.zone;			/* node ID */
	id.net= fido.net;
	id.number= fido.number;
	id.point= fido.point;

	altid.zone= fido.altzone;		/* alternate ID */
	altid.net= fido.altnet;
	altid.number= fido.altnumber;
	altid.point= fido.altpoint;

	tag= 0;
	if (--argc) {				/* possible schedule tag */
		cpyarg(buff,*++argv);		/* from command line */
		tag= *buff;
	}

	open_node();				/* basic files, */
	open_nmap(fido.event);			/* specific nodemap */
	if (node_files()) {
		printf("Can't find one or more of the nodelist files.\r\n");
		exit(1);
	}

/* Open the nodemap for the tag on the command line, if any. */

	if (tag) {
		sprintf(buff,"NODEMAP.%c",toupper(tag));
		makenname(name,buff);
		close(nodefile);			/* replace NODELIST.NMP */
		nodefile= open(name,2);			/* with this */
		if (nodefile == -1) {
			cprintf("There is no %s\r\n",name);
			return;
		}
	}

/* Load the repeat record and dump it. */

	lseek(nodefile,0L,0);
	read(nodefile,&rptrcd,sizeof(struct _rptrcd));
	for (cp= rptrcd.mdmstr; *cp; cp++)		/* delete the CR */
		if (*cp < ' ') *cp= '\0';		/* it messes up the display */

	printf("(FILE VERSION . . . . . . . . . . . . . . %d)\r\n",rptrcd.revision);
	printf("(SCHEDULE . . . . . . . . . . . . . . . . %c)\r\n",rptrcd.tag);
	printf("send-only . . . . . . . . . . . . . . . . %s\r\n",(rptrcd.bits >> RPT_SO) & 1 ? "Yes" : "No");
	printf("recv-only . . . . . . . . . . . . . . . . %s\r\n",(rptrcd.bits >> RPT_RO) & 1 ? "Yes" : "No");
	printf("external-mail . . . . . . . . . . . . . . %s\r\n",(rptrcd.bits >> RPT_EXT) & 1 ? "Yes" : "No");
	printf("dial-tries  . . . . . . . . . . . . . . . %u\r\n",rptrcd.dial_tries);
	printf("connect-tries . . . . . . . . . . . . . . %u\r\n",rptrcd.connect_tries);
	printf("dial-interval . . . . . . . . . . . . . . %u\r\n",rptrcd.dial_interval);
	printf("cont-interval . . . . . . . . . . . . . . %u\r\n",rptrcd.cont_interval);
	printf("mail-errorlevel . . . . . . . . . . . . . %u\r\n",rptrcd.mailcode);
	printf("file-errorlevel . . . . . . . . . . . . . %u\r\n",rptrcd.filecode);
	printf("rings . . . . . . . . . . . . . . . . . . %u\r\n",rptrcd.rings);      
	printf("io-port . . . . . . . . . . . . . . . . . %u\r\n",rptrcd.iodev);
	printf("modem-type  . . . . . . . . . . . . . . . %u\r\n",rptrcd.mdmtype);
	printf("max-baud  . . . . . . . . . . . . . . . . %u\r\n",rptrcd.maxbaud);
	printf("cd-bit  . . . . . . . . . . . . . . . . . %u\r\n",rptrcd.cd_bit);
	printf("modem-string  . . . . . . . . . . . . . . \"%s\"\r\n",rptrcd.mdmstr);
	printf("dial-prefix . . . . . . . . . . . . . . . \"%s\"\r\n",rptrcd.dial_prefix);	
	printf("\r\n\r\n");

	printf("NTC records:\r\n");
	printf("                                                           cnct   peak\r\n");
	printf("      Node     | try  | cnct | msgs | file | time | KBs  | BPS  | BPS  | Done?\r\n");
	printf("---------------+------+------+------+------+------+------+------+------+------\r\n");
	for (i= 0; get_ntc(i) != -1; i++) {
		printf("%14s | %4u | %4u | %4u | %4u | ",str_node(&ntc.node),ntc.tries,ntc.connects,ntc.msgs,ntc.files);
		printf("%02u:%02u  ",ntc.time / 60,ntc.time % 60);
		printf("%4u | %4u | %4u | ",(int)((ntc.bytes + 1023L) / 1024L),
		    (int)(ntc.bytes / ntc.xfer_time),(int)(ntc.bytes / ntc.time));

		if (ntc.bits & NTC_PD) printf("PU.");
		else if (ntc.bits & NTC_SUCCESS) printf("Yes");
		else printf("No ");
		printf("\r\n");
	}
	if (! i) printf("NONE\r\n");
	printf("\r\n\r\n");

	printf("NMP records:\r\n");
	printf("              Node         Route-To                 bits ...\r\n");
	for (i= 1; get_node(i) != -1; ++i) {
		fix_node(&nmap.node);
		printf("%4d: ",i);
		printf(" %12s ",str_node(&nmap.node));		/* orig. node */
		bits= nmap.bits;

		get_node(nmap.route_recd);
		fix_node(&nmap.node);				/* route-to node */
		printf("%12s  ",str_node(&nmap.node));

		if (nmap.bits & NMAP_REGION) printf("REG. ");
		else printf("     ");				/* too many bits over */

		for (n= 0; n < 8; n++) {
			switch (bits & (1 << n)) {
				case NMAP_ACCEPT:	printf("AcpF "); break;
				case NMAP_PU:		printf("PkUp "); break;
				case NMAP_POLL:		printf("Poll "); break;
				case NMAP_SEND:		printf("SdTo "); break;
				case NMAP_HOLD:		printf("Hold "); break;
				case NMAP_ALIAS:	printf("Alias"); break;
				default:		printf("     "); break;
			}
		}
		printf("\r\n");
	}
	close_node();
	exit(0);
}

lprintf(f)
char *f;
{
char buf[400],*p;

	_spr(buf,&f);
	p= buf;
	while (*p) bdos(2,*p++);
}

clprintf(f)
char *f;
{
char buf[400],*p;

	_spr(buf,&f);
	p= buf;
	while (*p) bdos(2,*p++);
}
/* Return true if the FBIT is set. */

fbit(bit)
int bit;
{
	return(fido.fbits[bit / sizeof(char)] & (1 << bit % sizeof(char)));
}
