From: utzoo!decvax!cca!mclure@sri-unix
Newsgroups: net.notes
Title: Re: Router/buildtable.c wastes space - (nf)
Article-I.D.: sri-unix.3309
Posted: Thu Sep 16 21:50:16 1982
Received: Fri Sep 17 03:31:40 1982
#R:sri-unix:1000021:sri-unix:1000022:000:6626
sri-unix!mclure Sep 16 21:47:00 1982
Here's a copy of Router/buildtable.c which we have modified so that it
can work with much larger uucpnet maps. Formerly, it blew up in
various unpleasant ways on 11's and the increasing size of the net map.
The sites struct has been changed to use pointers to strings rather
than allocating full fixed arrays which eats up space quickly. Also,
it discards "(null)" paths produced by buildlink as being unreachable
sites. In these cases, getpath returns the normal error code. It
finally works for the latest map I have (314 sites). You might want to
increase PATHLEN if you are in a particularly distant portion of the
universe.
Stuart
#include
/*
* format.c
*
* This program takes a file of the form:
* site intermediary1intermediary2...site
*
* and produces a file of the form:
* site complete address to this site with embedded %s for user.
*
* Addressing convention is one of the following:
*
* @ Arpa address format (user@site)
* ! Uucp address format (site!user)
* : Berknet address (site:user)
* . "dot" addressing, don't know the real name
* (user.site)
*
*
* Original Coding:
* Ray Essick June 14, 1982
*/
#define NOSITE 'N' /* no site, simple formatting */
#define ARPA '@' /* address format identifiers */
#define UUCP '!'
#define BERK ':'
#define DOT '.'
#define DFLTSCHEME '!'
#define LOCALSCHEME '!'
#define SITES 350 /* max sites we can handle */
#define PATHLEN 128
#define SYSNAME 20
struct site_f
{ /* structure for a site's information */
char *s_name; /* name of system */
char *s_rawpath; /* path to there */
char *s_fmtpath; /* formatted path */
int s_scheme; /* site's addr scheme */
};
struct site_f site[SITES]; /* set up tables */
int nsites; /* number of active sites in the table */
char *map,
*memp,
*links,
*malloc ();
main (argc, argv)
char **argv;
{
FILE * fp; /* for reading the files */
if (argc != 3) /* fixed format */
{
fprintf (stdout, "Usage: %s paths map\n", argv[0]);
exit (1);
}
links = argv[1];
map = argv[2];
if (getsites () < 0)
exit (1); /* read in the site list */
format (); /* formats the tables */
dumpem (); /* dump out the formatted tables */
}
getsites ()
{
FILE * fp;
char asite[SYSNAME]; /* hold system name */
char rawpath[PATHLEN]; /* and the raw path */
int c; /* scratch character */
int i;
nsites = 0; /* empty table */
if ((fp = fopen (links, "r")) == NULL)
return - 1;
while (1)
{
asite[0] = rawpath[0] = '\0';/* init the paths */
i = 0;
while ((c = getc (fp)) != ' ' && c != '\t' && c != '\n')
if (i < SYSNAME)
asite[i++] = c;
asite[i++] = '\0'; /* null terminate */
if (c == '\n')
goto process; /* no links, must be our local site! */
while ((c = getc (fp)) == ' ' || c == '\t');/* skip white space */
if (c == '\n')
goto process; /* null links */
rawpath[0] = c; /* insert first character */
i = 1;
while ((c = getc (fp)) != ' ' && c != '\t' && c != '\n')
if (i < PATHLEN)
rawpath[i++] = c;
else
{
fprintf (stdout, "Site %s: path too long, ignored\n", site);
asite[0] = '\0';
while (getc (fp) != '\n');
break;
}
rawpath[i++] = '\0'; /* null terminate */
process: /* process the stuff */
if (asite[0] && (strcmp (rawpath, "(null)") != 0))
{ /* if we got a valid site */
printf ("%d\n", nsites);
if ((memp = malloc (strlen (asite) + 1)) != NULL)
{
site[nsites].s_name = memp;
strcpy (memp, asite);
}
else
{
fprintf (stdout, "No memory left!\n");
exit (1);
}
if ((memp = malloc (strlen (rawpath) + 1)) != NULL)
{
site[nsites].s_rawpath = memp;
strcpy (memp, rawpath);
}
else
{
fprintf (stdout, "No memory left!\n");
exit (1);
}
site[nsites].s_fmtpath = '\0';
site[nsites].s_scheme = DFLTSCHEME;
if (++nsites == SITES)
{
fprintf (stdout, "Too many sites, change SITES constant\n");
exit (1);
}
}
if ((c = getc (fp)) == EOF)
break;
else
ungetc (c, fp);
}
fclose (fp); /* return the file descriptor */
}
/*
* dumpem
*
* dump out the formatted tables
*/
dumpem ()
{
FILE * fp;
int i;
if ((fp = fopen (map, "w")) == NULL)
{
fprintf (stdout, "Failed while writing\n");
exit (1);
}
for (i = 0; i < nsites; i++)
fprintf (fp, "%s\t%s\n", site[i].s_name, site[i].s_fmtpath);
fclose (fp);
}
/*
* format()
*
* using the information contained in the tables, go figure out
* a formatted path with the appropriate addressing information
* in it.
*/
format ()
{
int i;
char apath[PATHLEN],
tempfmt[PATHLEN];
char *p,
*q;
for (i = 0; i < nsites; i++)
{
parse (LOCALSCHEME, site[i].s_rawpath, tempfmt);
if ((memp = malloc (strlen (tempfmt) + 1)) != NULL)
{
site[i].s_fmtpath = memp;
strcpy (memp, tempfmt);
}
else
{
fprintf (stderr, "No more memory in format!\n");
exit (1);
}
}
}
/*
* parse(scheme,user, buffer)
*
* arranges a string in the buffer with the correct addressing
* to reach "user" using "scheme" for the first hop
* and recursing to get the other hops
*/
parse (scheme, user, buffer)
char *user;
char buffer[PATHLEN];
{
char *p,
*q,
*r;
char *tosite;
char *touser;
int i,
done,
j,
k;
int nscheme;
char tmpbuf[PATHLEN];
if (user == NULL || *user == '\0')
{
sprintf (buffer, "%s", "%s");/* simple format */
return;
}
p = user; /* parse site!user */
while (*p != '\0' && *p != UUCP && *p != BERK &&
*p != DOT && *p != ARPA)
p++; /* skip site */
if (*p == '\0')
{
p = NULL;
}
else
{
nscheme = *p; /* mark the scheme */
*p = '\0';
p++;
}
parse (nscheme, p, tmpbuf); /* recurse */
touser = tmpbuf; /* point at the user */
tosite = user; /* and the destination site */
if (tosite == NULL || *tosite == '\0')
scheme = NOSITE;
switch (scheme)
{
case NOSITE:
sprintf (buffer, "%s", touser);
break;
case ARPA:
sprintf (buffer, "%s@%s", touser, tosite);
break;
case UUCP:
sprintf (buffer, "%s!%s", tosite, touser);
break;
case BERK:
sprintf (buffer, "%s:%s", tosite, touser);
break;
case DOT:
sprintf (buffer, "%s.%s", touser, tosite);
break;
default:
fprintf (stdout, "Invalid addr mode: %c\n", scheme);
exit (1);
}
}