/*
 *				nodelist.c
 *
 * Generates list of rooms shared with each node.
 */

/*
 *				history
 *
 * 89Aug14 HAW  Handle virtual rooms as well.
 * 87Dec06 HAW  Created.
 */

#include "ctdl.h"    /* header file  */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <time.h>
#include <proto/exec.h>
#include <dos/dos.h>
#include <pragmas/dos_pragmas.h>
#include "exec/memory.h"
#include "exec/ports.h"
#include "exec/exec.h"

/*
 *				contents
 *
 *	crashout()		irrecoverable error
 *	main()			Main controller for this program
 *	openFile()		opens a .sys file
 */

extern rTable *roomTab;		/* RAM index of rooms		*/
extern CONFIG cfg;		/* A buncha variables		*/
extern FILE	*netfl;
extern NetBuffer netBuf;
extern NetTable *netTab;
extern VirtualRoom *VRoomTab;
extern char VirtualInUse;
extern VirtNet	*VirtNetList;
extern int  thisNet, VirtSize, VNetSize;
FILE *netLog;

int ListNodes(int alive);
int ListByNodes(void);
void CheckNet(int i, int roomSlot);
void CheckVirt(int TheVirt, int NetRover);
void PrintNetRooms(void);
void PrintVirtuals(void);

/*
 * crashout()
 *
 * This function handles an irrecoverable error.
 */
void crashout(str)
char *str;
{
    exit(printf(str));
}

/*
 * main()
 *
 * This is the main controller.
 */
int main(int, char **);
int main(argc, argv)
int argc;
char **argv;
{
    SYS_FILE netFile;
    int Index, NetRover;

    cfg.weAre = UTILITY;
    fprintf(stderr, "Node list generator, V3.41\n%s\n", COPYRIGHT);
    if (readSysTab(FALSE, TRUE)) {
	mvToHomeDisk(&cfg.homeArea);
	makeSysName(netFile, "ctdlnet.sys", &cfg.netArea);
	openFile(netFile, &netfl);
	initNetBuf(&netBuf);

	if (argc != 1) {
	    if (strCmp(argv[1], "-n") == SAMESTRING)
		return ListNodes(TRUE);
	    if (strCmp(argv[1], "-nd") == SAMESTRING)
		return ListNodes(FALSE);
	    if (strCmp(argv[1], "-s") == SAMESTRING)
		return ListByNodes();
	}

	printf("%s\n", cfg.codeBuf + cfg.nodeName);
	for (Index = AIDEROOM + 1;		/* First 3 never shared */
	    Index < MAXROOMS; Index++) {
	    if (  roomTab[Index].rtflags.INUSE &&
			roomTab[Index].rtflags.SHARED) {
		printf("%s\n", roomTab[Index].rtname);
		for (NetRover = 0; NetRover < cfg.netSize; NetRover++) {
		    CheckNet(NetRover, Index);
		}
		printf("\n");
	    }
	}
	VirtInit();
	if (VirtualInUse) {
	    for (Index = 0; Index < VirtSize; Index++) {
		if (strLen(VRoomTab[Index].vrName) != 0) {
		    printf("%s (Virtual)\n", VRoomTab[Index].vrName);
		    for (NetRover = 0; NetRover < cfg.netSize; NetRover++) {
			CheckVirt(Index, NetRover);
		    }
		    printf("\n");
		}
	    }
	}
    }
}

/*
 * CheckVirt()
 *
 * This processes a virtual room.
 */
void CheckVirt(int TheVirt, int NetRover)
{
    int i;

    for (i = 0; i < VIRT_LIMIT; i++) {
	if (VirtNetList[NetRover].VirtList[i].WhichVirt == TheVirt) {
	    getNet(NetRover, &netBuf);
	    if (netBuf.nbflags.in_use) {
		printf("        %s", netBuf.netName);
		switch (GetMode(VirtNetList[NetRover].VirtList[i].mode)) {
		    case PEON: printf(" (Peon)\n"); break;
		    case ACTIVE_BACKBONE:
			printf(" (Backbone - Active)\n"); break;
		    case PASS_BACKBONE:
			printf(" (Backbone - Passive)\n"); break;
		}
	    }
	}
    }
}

/*
 * CheckNet()
 *
 * This checks to see if the given room is shared with this node and does
 * the requisite print.
 */
void CheckNet(i, roomSlot)
int i, roomSlot;
{
    int j;

    if (netTab[i].ntflags.in_use) {
	for (j = 0; j < SHARED_ROOMS; j++) {
	    if (isSharedRoom(i, j)) {
		if (netTabRoomSlot(i, j) == roomSlot &&
			roomTab[roomSlot].rtgen == netGen(i, j)) {
		    getNet(i, &netBuf);
		    printf("        %s", netBuf.netName);
		    if (roomTab[netRoomSlot(j)].rtShareType == PEON)
			printf(" (Peon)\n");
		    else switch (GetMode(netTab[i].netTRooms[j].mode)) {
		    case PEON:
			printf(" (Peon)\n");	break;
		    case ACTIVE_BACKBONE:
			printf(" (Active Backbone)\n");	break;
		    case PASS_BACKBONE:
			printf(" (Passive Backbone)\n");	break;
		    }
		    return;
		}
	    }
	}
    }
}

/*
 * ListNodes()
 *
 * This just prints the list of nodes.  If alive is set, then only print those
 * nodes not disabled.
 */
int ListNodes(alive)
int alive;
{
    int i;
    static char *bauds[] = {
    "300", "1200", "2400", "4800", "9600", "14400", "19200", "38400", "57600"
    };

    for (i = 0; i < cfg.netSize; i++) {
	getNet(i, &netBuf);
	if (netBuf.nbflags.in_use &&
		(!alive || (netBuf.MemberNets & ALL_NETS))) {
	    printf("%3d. %-21s%-21s%-11s%s\n", i, netBuf.netName, netBuf.netId,
		(netBuf.nbflags.local) ? "local" : "non-local",
		bauds[netBuf.baudCode]);
	}
    }
}

/*
 * ListByNodes()
 *
 * This prints out nodes and the rooms shared.
 */
int ListByNodes()
{
    int i;

    VirtInit();
    for (i = 0; i < cfg.netSize; i++) {
	getNet(i, &netBuf);
	if (netBuf.nbflags.in_use) {
	    if (CheckForShared()) {
		printf("%s\n", netBuf.netName);
		PrintNetRooms();
		PrintVirtuals();
		printf("\n");
	    }
	}
    }

    return 0;
}

/*
 * CheckForShared()
 *
 * This decides if this node has any shared rooms at all.
 */
int CheckForShared()
{
    int rover, x;

    for (rover = 0; rover < SHARED_ROOMS; rover++)
	if (isSharedRoom(thisNet, rover) && roomValidate(thisNet, rover))
	    return TRUE;

    if (!VirtualInUse) return FALSE;

    for (rover = 0; rover < VIRT_LIMIT; rover++) {
	x = VirtNetList[thisNet].VirtList[rover].WhichVirt;
	if (x != -1 && (x >= VirtSize || x < 0 || !VRoomInuse(x)))
	    VirtNetList[thisNet].VirtList[rover].WhichVirt = -1;

	if ((x = VirtNetList[thisNet].VirtList[rover].WhichVirt) != -1)
	    return TRUE;
    }
    return FALSE;
}

/*
 * PrintNetRooms()
 *
 * This prints out all the net rooms for the current node.
 */
void PrintNetRooms()
{
    int rover;

    for (rover = 0; rover < SHARED_ROOMS; rover++)
	if (isSharedRoom(thisNet, rover) && roomValidate(thisNet, rover))
	    printf("     %s\n", roomTab[netTabRoomSlot(thisNet, rover)].rtname);
}

/*
 * PrintVirtuals()
 *
 * This prints out all the virtual rooms for the current node.
 */
void PrintVirtuals()
{
    int rover, x;

    if (!VirtualInUse) return ;

    for (rover = 0; rover < VIRT_LIMIT; rover++) {
	x = VirtNetList[thisNet].VirtList[rover].WhichVirt;
	if (x != -1 && (x >= VirtSize || x < 0 || !VRoomInuse(x)))
	    VirtNetList[thisNet].VirtList[rover].WhichVirt = -1;

	if ((x = VirtNetList[thisNet].VirtList[rover].WhichVirt) != -1)
	    printf("     %s\n", VRoomTab[x].vrName);
    }
}

