Added routing table

This commit is contained in:
Michiel Broek 2002-07-16 21:05:00 +00:00
parent 54f228d5b6
commit bad388e2ae
8 changed files with 226 additions and 33 deletions

View File

@ -1,5 +1,11 @@
$Id$ $Id$
WARNING WARNING WARNING WARNING
DO NOT USE ON PRODUCTION SYSTEMS, ONLY FOR TESTING
MBSEBBS History. MBSEBBS History.
v0.35.03 06-Jul-2002 v0.35.03 06-Jul-2002
@ -24,6 +30,7 @@ v0.35.03 06-Jul-2002
When a new tic area was created the first file received for When a new tic area was created the first file received for
that area was refused. that area was refused.
Fixed a few problems with local UUCP created netmails. Fixed a few problems with local UUCP created netmails.
Added very experimental routing table.
newuser: newuser:
Check for Unix accounts is now case sensitive. Check for Unix accounts is now case sensitive.
@ -50,6 +57,7 @@ v0.35.03 06-Jul-2002
When a JAM messagebase path is changed in one of the message When a JAM messagebase path is changed in one of the message
area, filefind and newfiles records are automatic updated if area, filefind and newfiles records are automatic updated if
they were connected to that area. they were connected to that area.
Added setup for routing table.
script: script:
The bbsdoor.sh and rundoor.sh scripts are now only installed The bbsdoor.sh and rundoor.sh scripts are now only installed

4
TODO
View File

@ -60,7 +60,7 @@ mbfido:
N: Process To: and Cc: lines in messages gated from Fido to Internet. N: Process To: and Cc: lines in messages gated from Fido to Internet.
U: Add routing table to override standard routing. U: Add routing table to override standard routing. UNDER TEST NOW!
N: Add traffic to html.nodes N: Add traffic to html.nodes
@ -68,6 +68,8 @@ mbfido:
N: Add macro's for stats of all months. N: Add macro's for stats of all months.
L: A separate log for processed area/filemgr requests.
mbcico: mbcico:
L: Implement modem connect response translation for ISDN lines, i.e. L: Implement modem connect response translation for ISDN lines, i.e.
make the CAUSE responses human readable. see McMail for this make the CAUSE responses human readable. see McMail for this

View File

@ -118,7 +118,7 @@ struct _newfiles newfiles;
struct _scanmgrhdr scanmgrhdr; /* Filefind areas */ struct _scanmgrhdr scanmgrhdr; /* Filefind areas */
struct _scanmgr scanmgr; struct _scanmgr scanmgr;
struct _routehdr routerhdr; /* Routing file */ struct _routehdr routehdr; /* Routing file */
struct _route route; struct _route route;
#endif #endif

View File

@ -56,7 +56,7 @@ typedef enum {E_NOISP, E_TMPISP, E_PRMISP} EMODE;
typedef enum {AREAMGR, FILEMGR, EMAIL} SERVICE; typedef enum {AREAMGR, FILEMGR, EMAIL} SERVICE;
typedef enum {FEEDINN, FEEDRNEWS, FEEDUUCP} NEWSFEED; typedef enum {FEEDINN, FEEDRNEWS, FEEDUUCP} NEWSFEED;
typedef enum {S_DIRECT, S_DIR, S_FTP} SESSIONTYPE; typedef enum {S_DIRECT, S_DIR, S_FTP} SESSIONTYPE;
typedef enum {R_ROUTE, R_NEWDEST, R_BOUNCE, R_CC} ROUTER; typedef enum {RT_ROUTE, RT_DIRECT, RT_DEFAULT, RT_REDIRECT, RT_BOUNCE, RT_CC} ROUTER;
/*********************************************************************** /***********************************************************************
@ -1585,6 +1585,8 @@ struct _route {
int routetype; /* What to do with it */ int routetype; /* What to do with it */
fidoaddr dest; /* Destination address */ fidoaddr dest; /* Destination address */
char dname[37]; /* Destination name */ char dname[37]; /* Destination name */
unsigned Active : 1; /* Is record active */
unsigned Deleted : 1; /* Is record deleted */
}; };

View File

@ -44,6 +44,95 @@
extern char nodes_fil[81]; extern char nodes_fil[81];
extern long nodes_pos; extern long nodes_pos;
/*
* Parse the mask from the routing table. If all 4d address parts
* are 0, then something is wrong. This cannot happen because the
* syntax is checked in mbsetup.
* Matched values return the actual value, the "All" masks return 65535.
*/
void ParseMask(char *, fidoaddr *);
void ParseMask(char *s, fidoaddr *addr)
{
char *buf, *str, *p;
int good = TRUE;
memset(addr, 0, sizeof(fidoaddr));
if (s == NULL)
return;
str = buf = xstrcpy(s);
addr->zone = 65535;
if ((p = strchr(str, ':'))) {
*(p++) = '\0';
if (strspn(str, "0123456789") == strlen(str))
addr->zone = atoi(str);
else
if (strcmp(str,"All"))
good = FALSE;
str = p;
}
addr->net = 65535;
if ((p = strchr(str, '/'))) {
*(p++) = '\0';
if (strspn(str, "0123456789") == strlen(str))
addr->net = atoi(str);
else
if (strcmp(str, "All"))
good = FALSE;
str = p;
}
if ((p=strchr(str, '.'))) {
*(p++) = '\0';
if (strspn(str, "0123456789") == strlen(str))
addr->node = atoi(str);
else
if (strcmp(str, "All") == 0)
addr->node = 65535;
else
good = FALSE;
str = p;
} else {
if (strspn(str, "0123456789") == strlen(str))
addr->node = atoi(str);
else
if (strcmp(str, "All") == 0)
addr->node = 65535;
else
good = FALSE;
str = NULL;
}
if (str) {
if (strspn(str, "0123456789") == strlen(str))
addr->point = atoi(str);
else
if (strcmp(str, "All") == 0)
addr->point = 65535;
else
good = FALSE;
}
if (buf)
free(buf);
if (!good) {
addr->zone = 0;
addr->net = 0;
addr->node = 0;
addr->point = 0;
}
return;
}
/* /*
* Netmail tracker. Return TRUE if we found a valid route. * Netmail tracker. Return TRUE if we found a valid route.
* If we did find a route, it is returned in the route pointer. * If we did find a route, it is returned in the route pointer.
@ -177,11 +266,13 @@ int GetRoute(char *ftn, fidoaddr *res)
node *dnlent, *bnlent; node *dnlent, *bnlent;
unsigned short myregion; unsigned short myregion;
faddr *dest, *best, *maddr; faddr *dest, *best, *maddr;
fidoaddr *fido; fidoaddr *fido, mask;
int me_host = -1, me_hub = -1; int me_host = -1, me_hub = -1;
int i; int i, match, last;
fidoaddr dir; fidoaddr dir;
FILE *fil; FILE *fil;
char *temp;
long ptr;
memset(res, 0, sizeof(fidoaddr)); memset(res, 0, sizeof(fidoaddr));
dest = parsefnode(ftn); dest = parsefnode(ftn);
@ -194,6 +285,83 @@ int GetRoute(char *ftn, fidoaddr *res)
Syslog('r', "Get route for: %s", ascfnode(dest, 0xff)); Syslog('r', "Get route for: %s", ascfnode(dest, 0xff));
Syslog('r', "Our best aka is: %s", ascfnode(best, 0xff)); Syslog('r', "Our best aka is: %s", ascfnode(best, 0xff));
/*
* Check routing table
*/
temp = calloc(PATH_MAX, sizeof(char));
sprintf(temp, "%s/etc/route.data", getenv("MBSE_ROOT"));
if ((fil = fopen(temp, "r")) != NULL) {
fread(&routehdr, sizeof(routehdr), 1, fil);
match = last = METRIC_MAX;
ptr = ftell(fil);
while (fread(&route, routehdr.recsize, 1, fil) == 1) {
if (route.Active) {
ParseMask(route.mask, &mask);
Syslog('r', "Table %s => %s", route.mask, aka2str(route.dest));
match = METRIC_MAX;
if (mask.zone) {
if ((mask.zone == 65535) || (mask.zone == dest->zone)) {
match = METRIC_ZONE;
if ((mask.net == 65535) || (mask.net == dest->net)) {
match = METRIC_NET;
if ((mask.node == 65535) || (mask.node == dest->node)) {
match = METRIC_NODE;
if ((mask.point == 65535) || (mask.point == dest->point))
match = METRIC_POINT;
}
}
}
if (match < last) {
Syslog('r', "Best util now");
last = match;
ptr = ftell(fil) - routehdr.recsize;
}
switch (match) {
case METRIC_MAX: Syslog('r', "Match MAX");
break;
case METRIC_ZONE: Syslog('r', "Match ZONE");
break;
case METRIC_NET: Syslog('r', "Match NET");
break;
case METRIC_NODE: Syslog('r', "Match NODE");
break;
case METRIC_POINT: Syslog('r', "Match POINT");
break;
}
} else {
Syslog('r', "Error in table");
}
}
}
if (last < METRIC_MAX) {
fseek(fil, ptr, SEEK_SET);
fread(&route, routehdr.recsize, 1, fil);
fclose(fil);
Syslog('r', "Route selected %s %d %s", route.mask, route.routetype, aka2str(route.dest));
/*
* Found a route record that matches. Return to caller with the result except
* when the result is RT_DEFAULT, which means fall down to the default router below.
* This is also true for routes that don't match at all.
*/
if (route.routetype == RT_ROUTE) {
Syslog('+', "R: %s Routing table: Route => %s", ascfnode(dest, 0xff), aka2str(route.dest));
memcpy(res, &route.dest, sizeof(fidoaddr));
return R_ROUTE;
}
if (route.routetype == RT_DIRECT) {
Syslog('+', "R: %s Routing table: Direct => %s", ascfnode(dest, 0xff), aka2str(route.dest));
memcpy(res, &route.dest, sizeof(fidoaddr));
return R_DIRECT;
}
} else {
fclose(fil);
}
}
free(temp);
/* /*
* Check if the destination is ourself. * Check if the destination is ourself.
*/ */

View File

@ -9,17 +9,19 @@ SRCS = grlist.c m_domain.c m_fgroup.c m_lang.c m_marea.c m_new.c \
m_limits.c m_menu.c m_ngroup.c m_service.c m_tty.c mutil.c m_archive.c \ m_limits.c m_menu.c m_ngroup.c m_service.c m_tty.c mutil.c m_archive.c \
m_fdb.c m_global.c m_magic.c m_mgroup.c m_node.c m_task.c m_users.c \ m_fdb.c m_global.c m_magic.c m_mgroup.c m_node.c m_task.c m_users.c \
screen.c m_bbs.c m_ff.c m_hatch.c m_mail.c m_modem.c m_ol.c m_tic.c \ screen.c m_bbs.c m_ff.c m_hatch.c m_mail.c m_modem.c m_ol.c m_tic.c \
m_virus.c stlist.c m_bbslist.c m_safe.c m_virus.c stlist.c m_bbslist.c m_safe.c m_route.c
HDRS = grlist.h m_domain.h m_fgroup.h m_lang.h m_marea.h m_new.h m_protocol.h \ HDRS = grlist.h m_domain.h m_fgroup.h m_lang.h m_marea.h m_new.h m_protocol.h \
m_ticarea.h mutil.h ledit.h m_farea.h m_fido.h m_limits.h m_menu.h \ m_ticarea.h mutil.h ledit.h m_farea.h m_fido.h m_limits.h m_menu.h \
m_ngroup.h m_service.h m_tty.h screen.h m_archive.h m_fdb.h m_global.h \ m_ngroup.h m_service.h m_tty.h screen.h m_archive.h m_fdb.h m_global.h \
m_magic.h m_mgroup.h m_node.h m_task.h m_users.h stlist.h m_bbs.h m_ff.h \ m_magic.h m_mgroup.h m_node.h m_task.h m_users.h stlist.h m_bbs.h m_ff.h \
m_hatch.h m_mail.h m_modem.h m_ol.h m_tic.h m_virus.h m_bbslist.h m_safe.h m_hatch.h m_mail.h m_modem.h m_ol.h m_tic.h m_virus.h m_bbslist.h m_safe.h \
m_route.h
OBJS = grlist.o m_domain.o m_fgroup.o m_lang.o m_marea.o m_new.o m_protocol.o \ OBJS = grlist.o m_domain.o m_fgroup.o m_lang.o m_marea.o m_new.o m_protocol.o \
m_ticarea.o mbsetup.o ledit.o m_farea.o m_fido.o m_limits.o m_menu.o \ m_ticarea.o mbsetup.o ledit.o m_farea.o m_fido.o m_limits.o m_menu.o \
m_ngroup.o m_service.o m_tty.o mutil.o m_archive.o m_fdb.o m_global.o \ m_ngroup.o m_service.o m_tty.o mutil.o m_archive.o m_fdb.o m_global.o \
m_magic.o m_mgroup.o m_node.o m_task.o m_users.o screen.o m_bbs.o m_ff.o \ m_magic.o m_mgroup.o m_node.o m_task.o m_users.o screen.o m_bbs.o m_ff.o \
m_hatch.o m_mail.o m_modem.o m_ol.o m_tic.o m_virus.o stlist.o m_bbslist.o m_safe.o m_hatch.o m_mail.o m_modem.o m_ol.o m_tic.o m_virus.o stlist.o m_bbslist.o \
m_safe.o m_route.o
LIBS += ../lib/libmemwatch.a ../lib/libclcomm.a ../lib/libcommon.a ../lib/libmsgbase.a ../lib/libdbase.a LIBS += ../lib/libmemwatch.a ../lib/libclcomm.a ../lib/libcommon.a ../lib/libmsgbase.a ../lib/libdbase.a
OTHER = Makefile OTHER = Makefile
@ -78,7 +80,7 @@ m_marea.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/u
m_new.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h screen.h mutil.h ledit.h stlist.h m_global.h grlist.h m_new.h m_lang.h m_marea.h m_ngroup.h m_new.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h screen.h mutil.h ledit.h stlist.h m_global.h grlist.h m_new.h m_lang.h m_marea.h m_ngroup.h
m_protocol.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/clcomm.h ../lib/common.h ../paths.h screen.h mutil.h ledit.h stlist.h m_global.h m_protocol.h m_protocol.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/clcomm.h ../lib/common.h ../paths.h screen.h mutil.h ledit.h stlist.h m_global.h m_protocol.h
m_ticarea.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h screen.h mutil.h ledit.h stlist.h grlist.h m_global.h m_node.h m_fgroup.h m_farea.h m_archive.h m_ticarea.h m_ticarea.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h screen.h mutil.h ledit.h stlist.h grlist.h m_global.h m_node.h m_fgroup.h m_farea.h m_archive.h m_ticarea.h
mbsetup.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h screen.h mutil.h ledit.h m_global.h m_bbs.h m_farea.h m_fgroup.h m_mail.h m_mgroup.h m_hatch.h m_tic.h m_ticarea.h m_magic.h m_fido.h m_lang.h m_archive.h m_virus.h m_tty.h m_limits.h m_users.h m_node.h m_fdb.h m_new.h m_ol.h m_bbslist.h m_safe.h m_protocol.h m_ff.h m_modem.h m_marea.h m_ngroup.h m_service.h m_domain.h m_task.h mbsetup.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h screen.h mutil.h ledit.h m_global.h m_bbs.h m_farea.h m_fgroup.h m_mail.h m_mgroup.h m_hatch.h m_tic.h m_ticarea.h m_magic.h m_fido.h m_lang.h m_archive.h m_virus.h m_tty.h m_limits.h m_users.h m_node.h m_fdb.h m_new.h m_ol.h m_bbslist.h m_safe.h m_protocol.h m_ff.h m_modem.h m_marea.h m_ngroup.h m_service.h m_domain.h m_task.h m_route.h
ledit.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/msg.h screen.h mutil.h ledit.h ledit.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/msg.h screen.h mutil.h ledit.h
m_farea.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h screen.h mutil.h ledit.h m_global.h m_fgroup.h m_archive.h m_farea.h m_fgroup.h m_ngroup.h m_farea.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h screen.h mutil.h ledit.h m_global.h m_fgroup.h m_archive.h m_farea.h m_fgroup.h m_ngroup.h
m_fido.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h screen.h mutil.h ledit.h stlist.h m_global.h m_fido.h m_fido.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h screen.h mutil.h ledit.h stlist.h m_global.h m_fido.h
@ -108,4 +110,5 @@ m_virus.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/u
stlist.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/common.h ../lib/clcomm.h stlist.h stlist.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/common.h ../lib/clcomm.h stlist.h
m_bbslist.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h screen.h mutil.h ledit.h m_global.h m_bbslist.h m_bbslist.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h screen.h mutil.h ledit.h m_global.h m_bbslist.h
m_safe.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h screen.h mutil.h ledit.h m_global.h m_safe.h m_safe.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h screen.h mutil.h ledit.h m_global.h m_safe.h
m_route.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h screen.h mutil.h ledit.h stlist.h m_global.h grlist.h m_node.h m_route.h
# End of generated dependencies # End of generated dependencies

View File

@ -1769,46 +1769,49 @@ int edit_sessiontype(int y, int x, int val)
char *get_routertype(int val) char *get_routetype(int val)
{ {
switch (val) { switch (val) {
case R_ROUTE: return (char *)"Routed "; case RT_ROUTE: return (char *)"Route to ";
case R_NEWDEST: return (char *)"Redirect "; case RT_DIRECT: return (char *)"Direct ";
case R_BOUNCE: return (char *)"Bounce "; case RT_DEFAULT: return (char *)"Default ";
case R_CC: return (char *)"CarbonCopy"; case RT_REDIRECT: return (char *)"New address";
case RT_BOUNCE: return (char *)"Bounce ";
case RT_CC: return (char *)"CarbonCopy ";
default: return NULL; default: return NULL;
} }
} }
void show_routertype(int y, int x, int val) void show_routetype(int y, int x, int val)
{ {
mvprintw(y, x, get_routertype(val)); mvprintw(y, x, get_routetype(val));
} }
int edit_routertype(int y, int x, int val) int edit_routetype(int y, int x, int val)
{ {
int ch; int ch;
showhelp((char *)"Toggle ^Routing mode^ with spacebar, press <Enter> whene done."); showhelp((char *)"Toggle ^Routing mode^ with spacebar, press <Enter> whene done.");
do { do {
set_color(YELLOW, BLUE); set_color(YELLOW, BLUE);
show_routertype(y, x, val); show_routetype(y, x, val);
ch = readkey(y, x, YELLOW, BLUE); ch = readkey(y, x, YELLOW, BLUE);
if (ch == ' ') { if (ch == ' ') {
if (val < R_CC) // if (val < RT_CC)
if (val < RT_DEFAULT)
val++; val++;
else else
val = R_ROUTE; val = RT_ROUTE;
} }
} while (ch != KEY_ENTER && ch != '\012'); } while (ch != KEY_ENTER && ch != '\012');
set_color(WHITE, BLACK); set_color(WHITE, BLACK);
show_routertype(y, x, val); show_routetype(y, x, val);
return val; return val;
} }

View File

@ -70,6 +70,7 @@
#include "m_service.h" #include "m_service.h"
#include "m_domain.h" #include "m_domain.h"
#include "m_task.h" #include "m_task.h"
#include "m_route.h"
mode_t oldmask; /* Old umask value */ mode_t oldmask; /* Old umask value */
@ -218,6 +219,7 @@ void site_docs(void)
page = service_doc(fp, toc, page); page = service_doc(fp, toc, page);
page = domain_doc(fp, toc, page); page = domain_doc(fp, toc, page);
page = task_doc(fp, toc, page); page = task_doc(fp, toc, page);
page = route_doc(fp, toc, page);
/* /*
* Append table of contents * Append table of contents
@ -372,6 +374,7 @@ void initdatabases(void)
InitTtyinfo(); InitTtyinfo();
InitUsers(); InitUsers();
InitVirus(); InitVirus();
InitRoute();
if (!init) { if (!init) {
working(0, 0, 0); working(0, 0, 0);
@ -448,18 +451,19 @@ int main(int argc, char *argv[])
mvprintw(14, 6, "8. Edit BBS Setup"); mvprintw(14, 6, "8. Edit BBS Setup");
mvprintw(15, 6, "9. Edit Mail Setup"); mvprintw(15, 6, "9. Edit Mail Setup");
mvprintw(16, 6, "10. Edit File Echo's setup"); mvprintw(16, 6, "10. Edit File Echo's setup");
mvprintw( 7,46, "11. Edit Newfiles Groups"); mvprintw(17, 6, "11. Edit Newfiles Groups");
mvprintw( 8,46, "12. Edit Newfiles Reports"); mvprintw( 7,46, "12. Edit Newfiles Reports");
mvprintw( 9,46, "13. Edit FileFind Setup"); mvprintw( 8,46, "13. Edit FileFind Setup");
mvprintw(10,46, "14. Edit Files Database"); mvprintw( 9,46, "14. Edit Files Database");
mvprintw(11,46, "15. Edit BBS Users"); mvprintw(10,46, "15. Edit BBS Users");
mvprintw(12,46, "16. Edit Services"); mvprintw(11,46, "16. Edit Services");
mvprintw(13,46, "17. Edit Domains"); mvprintw(12,46, "17. Edit Domains");
mvprintw(14,46, "18. Edit Task Manager"); mvprintw(13,46, "18. Edit Task Manager");
mvprintw(15,46, "19. Show software information"); mvprintw(14,46, "19. Edit Routing Table");
mvprintw(16,46, "20. Create site documents"); mvprintw(15,46, "20. Show software information");
mvprintw(16,46, "21. Create site documents");
switch(select_menu(20)) { switch(select_menu(21)) {
case 0: case 0:
loop = 0; loop = 0;
break; break;
@ -518,9 +522,12 @@ int main(int argc, char *argv[])
task_menu(); task_menu();
break; break;
case 19: case 19:
soft_info(); EditRoute();
break; break;
case 20: case 20:
soft_info();
break;
case 21:
site_docs(); site_docs();
break; break;
} }