home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * MBNODES.C - 10/22/87 - Grab routes from NET/ROM
- * NN port call time file
- */
-
- #include "mb.h"
-
- #if nncmd
-
- #define ntout 3 /* "got all data" timeout */
-
- short nodetime;
- PORTS *was;
- char *mp;
- short nodedone;
-
- /*
- * Node definition record.
- * One of these for each node found.
- */
-
- #define no_visit 0x01 /* Node has been visited */
- #define no_reach 0x02 /* Node can be reached */
- #define no_busy 0x08 /* Node was busy */
-
- typedef struct NODE_S
- {
- char *call; /* Call of this node */
- char *name;
- byte state; /* "visited" "can be reached" */
- byte hops; /* Distance to this node */
- struct NODE_S *found; /* Where we were when we found a path to this one */
- struct NODE_S *seen; /* Where we were when we found this one */
- struct NODE_S *next; /* Next node */
- } NODE;
-
- NODE *nodehd;
- NODE *nodetl;
- int nodecnt;
- NODE *path[8];
- int np;
-
- /*
- * Find a node.
- */
-
- NODE *findnode(cp)
- char *cp;
- {
- register NODE *n;
-
- for (n = nodehd; n isnt NULL; n = n->next) if (match(cp, n->call)) return n;
- return NULL;
- }
-
- /*
- * Find an unvisited node.
- * The one with the lowest cost path from the node we are at.
- */
-
- findunode()
- {
-
- register int h;
- register NODE *n;
-
- /*
- * Find node at min hops not yet visited.
- */
-
- if (nodedone) return false;
-
- h = 256;
- path[0] = NULL;
- for (n = nodehd; n isnt NULL; n = n->next)
- {
- if (n->state & no_reach) if (!(n->state & no_visit))
- if (n->hops < h)
- {
- h = n->hops;
- path[0] = n;
- }
- }
-
- if (path[0] is NULL) return false;
-
- for (np = 0; np < 7; np++)
- {
- if (path[np]->found is NULL) return false;
- if (path[np]->found is nodehd) return true;
- path[np + 1] = path[np]->found;
- }
- return false;
- }
-
- /*
- * Add a node.
- */
-
- NODE *addnode(tp)
- char *tp;
- {
- register NODE *n;
- register char *cp;
- register char *np;
-
- cp = tp;
- np = tp;
- for (; *tp; tp++) if (*tp is ':')
- {
- *tp = '\0';
- cp = tp + 1;
- }
-
- if ((n = findnode(cp)) isnt NULL)
- {
- if (n->name is NULL) if (np isnt cp)
- {
- n->name = (char *)mp; mp += (strlen(np) + 1);
- strcpy(n->name, np);
- }
- return n;
- }
-
- nodecnt++;
-
- n = (NODE *)mp; mp += sizeof(NODE);
- n->call = (char *)mp; mp += (strlen(cp) + 1);
- strcpy(n->call, cp);
-
- if (np is cp) n->name = NULL; else
- {
- n->name = (char *)mp; mp += (strlen(np) + 1);
- strcpy(n->name, np);
- }
-
- n->state = 0;
- n->hops = 255;
- n->found = NULL;
- n->seen = NULL;
- n->next = NULL;
- if (nodehd is NULL) nodehd = n; else nodetl->next = n;
- nodetl = n;
- return n;
- }
-
- /*
- * Connect to the local NET/ROM node.
- */
-
- clnode()
- {
- port->mode = remote;
- outstr("C "); outstr(nodehd->call); outchar('\n');
- waitcmd();
- do
- {
- if (!getit(nodetime))
- {
- if (!(port->mode & idle)) distnc();
- port->mode = idle;
- return;
- }
- }
- while (!iscon(port->line));
- }
-
- /*
- * Connect to a distant node, using NET/ROM.
- */
-
- cnode()
- {
- register int i;
-
- path[0]->state setbit no_visit;
- for (i = np; i >= 0; i--)
- {
- outstr("C "); outstr(path[i]->call); outchar('\n');
- if (getit(path[i]->hops * nodetime))
- {
- if (!match(port->fld[1], "CONNECTED"))
- {
- if (!(port->mode & idle)) distnc();
- port->mode = idle;
- return false;
- }
- }
- else
- {
- if (!(port->mode & idle)) distnc();
- port->mode = idle;
- return false;
- }
- }
- return true;
- }
-
- /*
- * Get the known nodes, links, and paths to them from THIS node.
- */
-
- getnode()
- {
- register int i;
- register int ti;
- short base;
- short tcnt;
- NODE *temp[64];
- NODE *via;
-
- fprintf(was->fl, "\nAt Node: %s\n", path[0]->call);
-
- outstr("p\n");
- if (!getit(path[0]->hops * nodetime))
- {
- if (port->mode & timeout) fprintf(was->fl, "*** Timeout\n");
- if (!(port->mode & idle)) distnc();
- port->mode = idle;
- return false;
- }
- fprintf(was->fl, "\nParams: %s", port->line);
- while (getit(ntout)) fprintf(was->fl, "Params: %s", port->line);
-
- /*
- * Get the nodes known to this node.
- */
-
- outstr("n *\n");
-
- /*
- * Get line "Nodes ..."
- */
-
- if (!getit(path[0]->hops * nodetime))
- {
- if (port->mode & timeout) fprintf(was->fl, "*** Timeout\n");
- if (!(port->mode & idle)) distnc();
- port->mode = idle;
- return false;
- }
-
- if (match(port->fld[1], "NODE"))
- {
- path[0]->state setbit no_busy;
- distnc();
- port->mode = idle;
- return false;
- }
-
- /*
- * Add known nodes to link table for this node.
- * Unknown number. Timeout to decide got 'em all.
- */
-
- tcnt = 0;
- if (getit(ntout)) do
- {
- for (i = 0; i < port->flds; i++)
- {
- temp[tcnt] = addnode(port->fld[i]);
- if (temp[tcnt]->seen is NULL) temp[tcnt]->seen = path[0];
- tcnt++;
- }
- }
- while(getit(ntout));
-
- if (port->mode & idle) return false;
-
- /*
- * For each target, get the adjacent nodes toward that target.
- */
-
- for (ti = 0; ti < tcnt; ti++)
- {
- outstr("n "); outstr(temp[ti]->call); outchar('\n');
-
- /*
- * Get line "Routes to ..."
- */
-
- if (!getit(path[0]->hops * nodetime))
- {
- if (port->mode & timeout) fprintf(was->fl, "*** Timeout\n");
- if (!(port->mode & idle)) distnc();
- port->mode = idle;
- return false;
- }
-
- if (!match(port->fld[1], "ROUTES"))
- {
- while(getit(ntout));
- fprintf(was->fl, "*** Node %s missing routes\n", temp[ti]->call);
- }
- else
- {
- addnode(port->fld[3]); /* Pick up node name ... */
-
- /*
- * Collect all the adjacent node lines.
- * Unknown number. Timeout to decide got 'em all.
- */
-
- if (getit(ntout)) do
- {
- if (*port->fld[0] is '>') base = 1; else base = 0;
- if (i = atoi(port->fld[base]))
- {
- via = addnode(port->fld[base + 3]);
- if (via->found is NULL) via->found = path[0];
- if (via->hops > path[0]->hops + 1) via->hops = path[0]->hops + 1;
- via->state setbit no_reach;
- fprintf(was->fl, " To: %-9.9s Via: %s", temp[ti]->call, port->line);
- }
- }
- while(getit(ntout));
- }
-
- if (port->mode & idle) return false;
- }
- return true;
- }
-
- /*
- * Trace out the NET/ROM routes.
- */
-
- donet()
- {
- register int i;
- register PORTS *new;
- NODE *from, *n;
-
- if (port->mode & sysop) { savecmd(); return; }
-
- if ((new = findport(*port->fld[1])) is NULL) { prtx(mnport); return; }
-
- if ((port->fl = fopen(port->fld[4], "w")) is NULL)
- { nofile(port->fld[4]); return; }
-
- nodecnt = 0;
- nodehd = NULL; nodetl = NULL;
- mp = tmp->scr;
- nodetime = atoi(port->fld[3]);
-
- /*
- * Put the local node into the node table.
- */
-
- addnode(port->fld[2]);
- nodehd->state setbit no_reach; /* Local node is reachable */
- nodehd->state setbit no_visit;
- nodehd->hops = 1;
- nodehd->found = nodehd;
- nodehd->seen = nodehd;
-
- /*
- * Remember current port.
- */
-
- was = port;
- ioport(new);
-
- /*
- * Visit the local node.
- */
-
- nodedone = false;
- path[0] = nodehd;
- clnode();
- if (port->mode & idle) { ioport(was); fclose(was->fl); return; }
- getnode();
- distnc();
- port->mode = idle;
-
- /*
- * Visit all nodes the local node knows about.
- */
-
- while (findunode())
- {
- clnode();
- if (!(port->mode & idle))
- {
- if (cnode()) getnode();
- distnc();
- port->mode = idle;
- }
- }
-
- /*
- * Put us back on the port we were on when we got here.
- */
-
- ioport(was);
-
- /*
- * Now we have all the data, print it.
- */
-
- curtim();
- fprintf(was->fl, "\n Data collected at %s %s\n\n", l_date, l_time);
-
- for (n = nodehd; n isnt NULL; n = n->next)
- {
- if (n->name is NULL)
- fprintf(was->fl, "Node: %-9.9s, No Alias, %3d hops, seen at %s",
- n->call, n->hops, n->seen->call);
- else
- fprintf(was->fl, "Node: %-9.9s, Alias %-6.6s, %3d hops, seen at %s",
- n->call, n->name, n->hops, n->seen->call);
-
- if (!(n->state & no_reach)) fprintf(was->fl, " (Not reachable)");
-
- if (n->state & no_busy) fprintf(was->fl, " (Was busy)");
-
- fprintf(was->fl, "\n");
-
- }
-
- i = (int)(mp - tmp->scr);
- fprintf(was->fl, "%d nodes, %d memory\n", nodecnt, i);
- fclose(was->fl);
- }
-
- /*
- * Get a line from the current port.
- * Handle disconnect and timeout.
- */
-
- getit(tm)
- int tm;
- {
- register short ctime;
-
- ctime = port->ctime;
- port->ctime = tm;
- while(!getdat());
- port->ctime = ctime;
-
- switch(port->mode)
- {
- case timeout :
- port->mode = remote;
- return false;
-
- case forced :
- nodedone = true;
-
- case discon :
- distnc();
- port->mode = idle;
- return false;
-
- default :
- port->mode = remote;
- parse();
- return true;
- }
- }
- #endif