[alt.sources] FIDOGATE 06/06

mj@dfv.rwth-aachen.de (Martin Junius) (05/24/91)

---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is part 06 of a multipart archive
# ============= nodelist.c ==============
if test -f 'nodelist.c' -a X"$1" != X"-c"; then
    echo 'x - skipping nodelist.c (File already exists)'
else
echo 'x - extracting nodelist.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'nodelist.c' &&
/*:ts=4*/
/*****************************************************************************
X * FIDOGATE --- Gateway software UNIX <-> FIDO
X *
X * $Id: nodelist.c,v 1.8 90/12/13 20:05:57 mj Exp $
X *
X * Routines to get and translate information in nodelist.
X *
X * $Log:   nodelist.c,v $
X * Revision 1.8  90/12/13  20:05:57  mj
X * Removed some unused functions.
X * 
X * Revision 1.7  90/12/02  21:22:12  mj
X * Changed program header to mention both authors of the original
X * software posted to alt.sources.
X * 
X * Revision 1.6  90/11/05  20:50:48  mj
X * Changed my signature in all program headers.
X * 
X * Revision 1.5  90/09/03  17:57:25  mj
X * Moved function stripbad() to funpack.c
X * 
X * Revision 1.4  90/08/02  19:09:16  mj
X * Fixed a bug in stripbad(). Digit are now allowed in user
X * names.
X * 
X * Revision 1.3  90/07/01  15:20:26  mj
X * Fixed some bugs in funpack caused by the removal of alloca().
X * No more core dumps, but heaven knows, why it works now. Strange.
X * 
X * Revision 1.2  90/07/01  13:45:58  mj
X * Removed all calls to alloca(). All unsave malloc()'s without
X * checking the returned pointer are now done via xmalloc().
X * Fixed a malloc() error in rmail.
X * 
X * Revision 1.1  90/06/28  22:04:29  mj
X * Much rework of the sources, no more hsu.h and other clean up.
X * rmail improved, now handles special XENIX quirks.
X * 
X * Revision 1.0  90/06/19  18:32:43  mj
X * Initial revision
X * 
X *
X *****************************************************************************
X * This version hacked and maintained by:
X *    _____ _____
X *   |     |___  |   Martin Junius     FIDO:    2:242/6.1   2:242/6.0
X *   | | | |   | |   Republikplatz 3   DOMAIN:  mju@dfv.rwth-aachen.de
X *   |_|_|_|_____|   D-5100 Aachen     Tel. (Voice) 0241-86931
X *
X * Original version of these programs and files:
X *
X *   Teemu Torma
X *   Heikki Suonsivu   FIDO: 2:504/1   UUCP: ...!mcsun!santra!hsu
X *
X *****************************************************************************/
X
/*
X  Sat Oct  8 17:36:11 1988
X  Rewrote nodelist index handling and reading. Now index is kept
X  in memory, and has zones also.
X  */
X
#include "fidogate.h"
X
#include <values.h>
#include <sys/stat.h>
X
X
X
#ifndef SEEK_SET
#define SEEK_SET 0
#endif
#ifndef SEEK_CUR
#define SEEK_CUR 1
#endif
#ifndef SEEK_END
#define SEEK_END 2
#endif
X
extern long atol();
Node originnode;
NODEINDEX *nodeindex = NULL;
NAMEINDEX *nameindex = NULL;
int nodes, names, compile_zone, compile_region, compile_net;
X
/* Compare two strings, considering '_' and ' ', and converting
X   {|}[\] to aoaAOA instead, and ignoring case.
X
X   ascii_convert(string) does conversion.
X   */
X
char *ascii_convert(s)
X     char *s;
{
X  char *p;
X
X  p = s;
X  while (*s) {
X    switch (*s) {
X     case '_':
X      *s = ' ';
X      break;
#if 0
X     case '{':
X     case '}':
X     case '[':
X     case ']':
X      *s = 'a';
X      break;
X     case '|':
X     case '\\':
X      *s = 'o';
X      break;
X     default:
X      *s = tolower(*s);
#endif
X    }
X    s++;
X  }
X  return p;
}
X
X
X
/* Compare nodelist index entry (for qsort) */
cmpnodeindex(node1, node2)
X     NODEINDEX *node1, *node2;
{
X  if (node1->zone < node2->zone) return -1;
X  if (node1->zone > node2->zone) return 1;
X  if (node1->net < node2->net) return -1;
X  if (node1->net > node2->net) return 1;
X  if (node1->node < node2->node) return -1;
X  if (node1->node > node2->node) return 1;
X  return 0; /* Same node */
}
X
cmpnameindex(name1, name2)
X     NAMEINDEX *name1, *name2;
{
X  int n;
X  n = strcmp(name1->name, name2->name);
X  /* debug(9, "name1 %s name2 %s = %d", name1->name, name2->name, n); */
X  return n;
}
X
X
X
#ifdef NODELIST_SUPPORT
/* Read file in to a buffer allocating buffer for it */
X
long read_file(buffer, name)
char **buffer, *name;
{
FILE *fp;
long size = 0;
X
X  if (fp = fopen(name, "r")) {
X    fseek(fp, 0L, SEEK_END);
X    size = ftell(fp);
X
X    /* Apparently we are on 16-bit? */
X    if (size > MAXINT)
X      {
X    log("Brain damaged CPU architecture reading file?");
X    size = 0;
X    goto out;
X      }
X
X    fseek(fp, 0L, SEEK_SET);
X
X    if (*buffer)
X      *buffer = xrealloc( *buffer, (unsigned) size);
X    else
X      *buffer = xmalloc( (unsigned) size);
X
X    debug(2, "Reading %d bytes from %s", size, name);
X    if (fread( *buffer, 1, (int) size, fp) != size) size = 0;
X    fclose(fp);
X  }
X
X out:
X  return size;
}
X
write_file(buffer, name, size)
X     char *buffer, *name;
X     int size;
{
X  FILE *fp;
X  int rvalue = 0;
X
X  if (fp = fopen(name, "w+"))
X    {
X      debug(2, "Writing %d bytes to %s", size, name);
X      if (fwrite(buffer, 1, size, fp) != size) rvalue = -1;
X      fclose(fp);
X    }
X
X  return rvalue;
}
X
read_nodeindex()
{
X  nodes = read_file( (char **) &nodeindex,
X            sprintfs("%s/%s", LIBDIR, INODELIST)) / sizeof(NODEINDEX);
X  return nodes == 0L;
}
X
read_nameindex()
{
X  names = read_file( (char **) &nameindex,
X            sprintfs("%s/%s", LIBDIR, NAMELIST)) / sizeof(NAMEINDEX);
X  return names == 0L;
}
X
write_nodeindex()
{
X  return write_file( (char *) nodeindex,
X            sprintfs("%s/%s", LIBDIR, INODELIST),
X            (int) (nodes * sizeof(NODEINDEX)));
}
X
write_nameindex()
{
X  return write_file( (char *) nameindex,
X            sprintfs("%s/%s", LIBDIR, NAMELIST),
X            (int) (names * sizeof(NAMEINDEX)));
}
X
/* Make nodelist's index-file. That index-file will be used to search
X   desired net/region from nodelist.
X   Return NULL if everything was fine, otherwise error-message string. */
X
char *
update_index()
{
X  struct stat nlstat, inlstat;
X  FILE *nl = NULL, *nlidx = NULL, *namefp = NULL;
X  char nodelist[BUFLEN], inodelist[BUFLEN], namelist[BUFLEN];
X  char buffer[BUFSIZ];
X  long offset;
X  char *error;
X  Node node;
X  NODEINDEX nodei;
X  NAMEINDEX namei;
X  extern void qsort();
X
X  /* generate nodelist and index-file names */
X  (void) sprintf(nodelist, "%s/%s", LIBDIR, NODELIST);
X  (void) sprintf(inodelist, "%s/%s", LIBDIR, INODELIST);
X  (void) sprintf(namelist, "%s/%s", LIBDIR, NAMELIST);
X
X  /* get statuses of nodelist and index */
X  if (stat(nodelist, &nlstat) == -1)
X    return "$Error in getting nodelist status";
X
X  errno = 0;
X  if (stat(inodelist, &inlstat) == -1 && errno != ENOENT)
X    return "$Error in getting status of existing nodelist-index";
X
X  /* If index-file does exists then check modification times and
X     first lines. If nodelist is older and first lines are the same,
X     no update is needed. If index-file should be rebuild, assume
X     also rebuilding namelist. */
X
X  if (errno == 0 && nlstat.st_mtime <= inlstat.st_mtime)
X    {
X      error = NULL;
X      goto done;
X    }
X  else
X    log("Update nodelist-index: nodelist is newer than index");
X
X  /* open index-file for writing */
X  if (nlidx != NULL)
X    (void) fclose(nlidx);
X  if ((nlidx = fopen(inodelist, "w")) == NULL)
X    {
X      error = "$Unable to open nodelist-index for writing";
X      goto done;
X    }
X  if (namefp)
X    (void) fclose(namefp);
X  if ((namefp = fopen(namelist, "w")) == NULL)
X    {
X      error = "$Unable to open namelist-index for writing";
X      goto done;
X    }
X
X  if (!nl)
X    if ((nl = fopen(nodelist, "r")) == NULL)
X      return "$Unable to open nodelist";
X
X  (void) rewind(nl);
X
X  compile_zone = MY_ZONE;
X  compile_region = MY_REGION;
X  compile_net = MY_NET;
X  nodes = 0;
X  names = 0;
X
X  /* save host/region offsets */
X  for (offset = ftell(nl); fgets(buffer, BUFSIZ, nl); offset = ftell(nl))
X    {
X      if (*buffer == '\n' || *buffer == ';') continue;
X
X      parse_entry(&node, buffer);
X
X      nodei.zone = node.zone;
X      nodei.net = node.net;
X      nodei.node = node.node;
X      nodei.offset = offset;
X
#ifdef NEEDED
X      debug(8, "%s", buffer);
X      debug(8, "writing %d:%d/%d", node.zone, node.net, node.node);
#endif
X      fwrite( (char *) &nodei, sizeof(NODEINDEX), 1, nlidx);
X      if (ferror(nlidx))
X    {
X      error = "$Cannot write index, no space?";
X      goto done;
X    }
X
X      if (node.type != REGION && node.type != HOST &&
X      node.type != ZONE && node.type != KENL && node.type != HUB)
X    {
X      strcpy(namei.name, node.sysop);
X      namei.offset = offset;
X      namei.zone = compile_zone;
X      namei.net = compile_net;
X      names++;
X      fwrite( (char *) &namei, sizeof(NAMEINDEX), 1, namefp);
X      if (ferror(namefp))
X        {
X          error = "$Cannot write name index, no space?";
X          goto done;
X        }
X    }
X
X      nodes++;
X    }
X  error = NULL;
X
X  /* Ok, now get both indices back and qsort them */
X
X  (void) fclose(nl);
X  nl = NULL;
X  (void) fclose(nlidx);
X  nlidx = NULL;
X  (void) fclose(namefp);
X  namefp = NULL;
X
X  if (read_nodeindex())
X    {
X      error = "$Cannot read nodelist index";
X      goto done;
X    }
X  if (read_nameindex())
X    {
X      error = "$Cannot read name index";
X      goto done;
X    }
X
X  log("Sorting nodelist index");
X  (void) qsort( (char *) nodeindex, (unsigned) nodes,
X           sizeof(NODEINDEX), cmpnodeindex);
X  log("Sorting name index");
X  (void) qsort( (char *) nameindex, (unsigned) names,
X           sizeof(NAMEINDEX), cmpnameindex);
X  log("Sorted indices");
X
X  if (write_nodeindex())
X    {
X      error = "$Cannot write nodelist index";
X      goto done;
X    }
X  if (write_nameindex())
X    {
X      error = "$Cannot write name index";
X      goto done;
X    }
X
X  /* done, close files and return error message */
X done:
X  if (nl)
X    (void) fclose(nl);
X  if (nlidx)
X    (void) fclose(nlidx);
X  if (namefp)
X    (void) fclose(namefp);
X  return error;
}
X
X
X
/* Convert underscores in string to spaces. In nodelist there is always
X   underscore insted of space (flags is special case). */
X
void
convert_space(s)
X     register char *s;
{
X  while (*s)
X    {
X      if (*s == '_')
X        *s = ' ';
X      s++;
X    }
}
X
/* Get one comma-terminated field from buffer, retrun pointer to right
X   after terminating comma. Convert underscores to spaces in string. */
X
char *
parse_field(buffer, entry, size)
X     char *buffer, *entry;
X     int size;
{
X  char *np = entry;
X
X  /* copy string */
X  while (--size >= 0 && *buffer && *buffer != ',')
X    *entry++ = *buffer++;
X  *entry = 0;
X
X  switch (*buffer)
X    {
X    case 0:
X      /* end of buffer */
X      log("No closing comma in field");
X      return (char *) 0;
X    case ',':
X      /* succesful copy */
X      convert_space(np);
X      return buffer + 1;
X    default:
X      /* buffer too long, find comma */
X      while (*buffer && *buffer != ',')
X        buffer++;
X      if (*buffer)
X        {
X          convert_space(np);
X          return buffer + 1;
X        }
X      else
X        {
X          log("Missing comma in field");
X          return (char *) 0;
X        }
X    }
X  /* NOTREACHED */
}
X
/* Parse one line of nodelist to node structure. Return NULL is there
X   was error's in that line or missing fields. */
X
Node *
parse_entry(entry, buffer)
X     Node *entry;
X     char *buffer;
{
X  char *cp;
X  int n;
X
X  /* strip newline if exists */
X  if (cp = strchr(buffer, '\n'))
X    *cp = 0;
X
X  /* get type of entry */
X  if (!strncmp("Zone,", buffer, 5))
X    entry->type = ZONE;
X  else if (!strncmp("Region,", buffer, 7))
X    entry->type = REGION;
X  else if (!strncmp("Host,", buffer, 5))
X    entry->type = HOST;
X  else if (!strncmp("Hub,", buffer, 4))
X    entry->type = HUB;
X  else if (!strncmp("Pvt,", buffer, 4))
X    entry->type = PVT;
X  else if (!strncmp("Hold,", buffer, 5))
X    entry->type = HOLD;
X  else if (!strncmp("Down,", buffer, 5))
X    entry->type = DOWN;
X  else if (!strncmp("Kenl,", buffer, 5))
X    entry->type = KENL;
X  else if (*buffer == ',')
X    entry->type = NORMAL;
X  else
X    {
X      log("Unknown type in line '%s'", buffer);
X      return (Node *) 0;
X    }
X
X  /* get net/region/node number */
X  if ((cp = strchr(buffer, ',')) == NULL)
X    {
X      log("Missing zone/net/node/region in line '%s'", buffer);
X      return (Node *) 0;
X    }
X  if ((n = atoi(++cp)) == 0)
X    {
X      log("Value of zone/net/node/region is 0 in line '%s'", buffer);
X      return (Node *) 0;
X    }
X  if (entry->type == ZONE)
X    {
X      entry->zone = n;
X      entry->net = 0;
X      entry->node = 0;
X      entry->point = 0;
X      compile_zone = n;
X      debug(8, "Zone %d", compile_zone);
X    }
X  else if (entry->type == REGION)
X    {
X      entry->zone = compile_zone;
X      entry->region = n;
X      entry->net = n;    /* For compatibility with old version */
X      entry->node = 0;
X      entry->point = 0;
X      compile_region = n;
X      compile_net = n;    /* For compatibility with old version */
X      debug(8, "Region %d", compile_region);
X    }
X  else if (entry->type == HOST)
X    {
X      entry->zone = compile_zone;
X      entry->region = compile_region;
X      entry->net = n;
X      entry->node = 0;
X      entry->point = 0;
X      compile_net = n;
X      debug(8, "Net %d", compile_net);
X    }
X  else
X    {
X      entry->zone = compile_zone;
X      entry->region = compile_region;
X      entry->net = compile_net;
X      entry->node = n;
X      entry->point = 0;
X    }
X  while (*cp && *cp++ != ',');
X
X  /* get node/net/region name */
X  if ((cp = parse_field(cp, entry->name, sizeof(entry->name))) == NULL)
X    {
X      log("Invalid name in line '%s'", buffer);
X      return (Node *) 0;
X    }
X
X  /* get city */
X  if ((cp = parse_field(cp, entry->city, sizeof(entry->city))) == NULL)
X    {
X      log("Invalid city in line '%s'", buffer);
X      return (Node *) 0;
X    }
X
X  /* get sysop */
X  if ((cp = parse_field(cp, entry->sysop, sizeof(entry->sysop))) == NULL)
X    {
X      log("Invalid sysop in line '%s'", buffer);
X      return (Node *) 0;
X    }
X
X  /* get phone number */
X  if ((cp = parse_field(cp, entry->phone, sizeof(entry->phone))) == NULL)
X    {
X      log("Invalid phone-number in line '%s'", buffer);
X      return (Node *) 0;
X    }
X
X  /* get maximum baud rate */
X  if ((n = atoi(cp)) == 0)
X    {
X      log("Baud rate is 0 in line '%s'", buffer);
X      return (Node *) 0;
X    }
X  entry->speed = n;
X  while (*cp && *cp++ != ',');
X
X  /* get flags */
X  (void) strncpy(entry->flags, cp, sizeof(entry->flags));
X  entry->flags[sizeof(entry->flags) - 1] = 0;
X
X  /* all done */
X  return entry;
}
X
/* Get entry for one node from nodelist. Return NULL, if there is no
X   entry for that node. */
X
Node *
node_entry(node)
X     Node node;
{
X  static Node entry;
X  FILE *fp;
X  char buffer[BUFSIZ];
X  extern char *bsearch();
X  long offset;
X  NODEINDEX *nodeip, nodei;
X
X  /* Read index file into memory */
X
X  if (!nodeindex)
X    if (read_nodeindex())
X      {
X    log("$Unable to read nodelist");
X    return (Node *) 0;
X      }
X
X  nodei.zone = node.zone;
X  nodei.net = node.net;
X  nodei.node = node.node;
X
X  debug(2, "Searching %s from %d nodes", ascnodei(nodei), nodes);
X  nodeip = (NODEINDEX *) bsearch( (char *) &nodei, (char *) nodeindex,
X                 (unsigned) nodes, sizeof(NODEINDEX),
X                 cmpnodeindex);
X
X  if (nodeip) {
X    offset = nodeip->offset;
X
X    /* open nodelist */
X    (void) sprintf(buffer, "%s/%s", LIBDIR, NODELIST);
X    if ((fp = fopen(buffer, "r")) == NULL)
X      {
X    log("$Unable to open %s", buffer);
X    return (Node *) 0;
X      }
X
X    if (fseek(fp, offset, 0))
X      {
X    log("$Seek error on nodelist");
X    (void) fclose(fp);
X    return (Node *) 0;
X      }
X
X    fgets(buffer, BUFSIZ, fp);
X    fclose(fp);
X
X    compile_zone = nodeip->zone;
X    compile_net = nodeip->net;
X    return parse_entry(&entry, buffer);
X  }
X
X  log("Could not find node %s", ascnodei(nodei));
X
X  /* we didn't find net/region */
X  (void) fclose(fp);
X  return (Node *) 0;
}
X
char *dialtable[] = { DIALTABLE };
X
dial_translation(dest, source)
X     char *dest, *source;
{
X  register int count = 0;
X
X  for (;;) {
X    if (!*dialtable[count] ||
X    !strncmp(dialtable[count], source, strlen(dialtable[count]))) {
X
X      /* Matched, take prefix, */
X      strcpy(dest, dialtable[count + 1]);
X
X      /* Then add phone number */
X      strcat(dest, source + strlen(dialtable[count]));
X      return;
X    }
X    count += 2;
X  }
}
X
static char **aliastable = NULL;
static allocated = 0;
static aliases = 0;
X
expand_aliastable()
{
X  if (!aliastable)
X    {
X      aliastable = (char **) xmalloc(sizeof(char *) * 20);
X      if (aliastable) allocated = 20;
X    }
X
X  if (aliases == allocated) /* Need more pointers */
X    {
X      allocated += 20;
X      aliastable = (char **) xrealloc( (char *) aliastable,
X                     sizeof(char *) * allocated);
X      if (!aliastable)
X    {
X      log("Cannot realloc %d bytes", sizeof(char *) * allocated);
X      return -1;
X    }
X    }
X  return 0;
}
X
#define FILENAME_SIZE 256
X
search_name(name)
X     char *name;
{
X  Node entry;
X  FILE *fp;
X  char buffer[BUFSIZ];
X  extern char *bsearch();
X  char *nlname;
X  long offset;
X  NAMEINDEX *nameip, namei;
X
X  if (!nameindex)
X    if (read_nameindex())
X      {
X    log("$Unable to read namelist");
X    return -1;
X      }
X
X  strncpy(namei.name, name, 36);
X  namei.name[35] = 0;
X
X  nameip = (NAMEINDEX *) bsearch( (char *) &namei, (char *) nameindex,
X                 (unsigned) names, sizeof(NAMEINDEX),
X                 cmpnameindex);
X
X  if (nameip)
X    {
X      offset = nameip->offset;
X
X      /* Open nodelist */
X      if ((fp =
X       fopen(nlname = sprintfs("%s/%s", LIBDIR, NODELIST), "r")) == NULL)
X    {
X      log("$Unable to open nodelist %s", nlname);
X      return -1;
X    }
X
X      if (fseek(fp, offset, 0))
X    {
X      log("$Seek error on nodelist");
X      (void) fclose(fp);
X      return -1;
X    }
X
X      fgets(buffer, BUFSIZ, fp);
X      fclose(fp);
X
X      compile_zone = nameip->zone;
X      compile_net = nameip->net;
X      if (parse_entry(&entry, buffer) == NULL) return -1;
X
X      debug(1, "Search name %s returns %d:%d/%d.%d", name,
X        entry.zone, entry.net, entry.node, entry.point);
X      memcpy( (char *) &originnode, (char *) &entry, sizeof(Node));
X      return 0;
X    }
X
X  debug(1, "Search name %s return no node", name);
X  return -1;
}
#endif /**NODELIST_SUPPORT**/
SHAR_EOF
chmod 0644 nodelist.c ||
echo 'restore of nodelist.c failed'
Wc_c="`wc -c < 'nodelist.c'`"
test 17722 -eq "$Wc_c" ||
    echo 'nodelist.c: original size 17722, current size' "$Wc_c"
fi
# ============= gethost.c ==============
if test -f 'gethost.c' -a X"$1" != X"-c"; then
    echo 'x - skipping gethost.c (File already exists)'
else
echo 'x - extracting gethost.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'gethost.c' &&
/*:ts=4*/
/*****************************************************************************
X * FIDOGATE --- Gateway software UNIX <-> FIDO
X *
X * $Id: gethost.c,v 1.2 90/12/02 21:22:08 mj Exp $
X *
X * gethostname()
X *
X * $Log:   gethost.c,v $
X * Revision 1.2  90/12/02  21:22:08  mj
X * Changed program header to mention both authors of the original
X * software posted to alt.sources.
X * 
X * Revision 1.1  90/11/05  20:50:42  mj
X * Changed my signature in all program headers.
X * 
X * Revision 1.0  90/06/19  18:35:36  mj
X * Initial revision
X * 
X *
X *****************************************************************************
X * This version hacked and maintained by:
X *    _____ _____
X *   |     |___  |   Martin Junius     FIDO:    2:242/6.1   2:242/6.0
X *   | | | |   | |   Republikplatz 3   DOMAIN:  mju@dfv.rwth-aachen.de
X *   |_|_|_|_____|   D-5100 Aachen     Tel. (Voice) 0241-86931
X *
X * Original version of these programs and files:
X *
X *   Teemu Torma
X *   Heikki Suonsivu   FIDO: 2:504/1   UUCP: ...!mcsun!santra!hsu
X *
X *****************************************************************************/
X
#include "fidogate.h"
X
#include <sys/utsname.h>
X
/* Get name of this uucp-node. Name is stored in buffer. Len in maximum
X   length of buffer. Return -1 if can not do uname(2), otherwise 0. */
X
int
gethostname(buffer, len)
X     char *buffer;
X     int len;
{
#ifdef MY_HOSTNAME
X   strncpy(buffer, MY_HOSTNAME, len);
X   buffer[len - 1] = 0;
#else
struct utsname name;
X
X   if (uname(&name) == -1)
X       return -1;
X   (void) strncpy(buffer, name.nodename, len);
X   buffer[len - 1] = 0;
#endif
X   return 0;
}
SHAR_EOF
chmod 0644 gethost.c ||
echo 'restore of gethost.c failed'
Wc_c="`wc -c < 'gethost.c'`"
test 1592 -eq "$Wc_c" ||
    echo 'gethost.c: original size 1592, current size' "$Wc_c"
fi
# ============= address.c ==============
if test -f 'address.c' -a X"$1" != X"-c"; then
    echo 'x - skipping address.c (File already exists)'
else
echo 'x - extracting address.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'address.c' &&
/*:ts=4*/
/*****************************************************************************
X * FIDOGATE --- Gateway software UNIX <-> FIDO
X *
X * $Id: address.c,v 1.14 91/05/19 17:21:17 mj Exp Locker: mj $
X *
X * Address format is (domain style addresses for FIDO):
X *     <name>@p<point>.f<node>.n<net>.z<zone>.FIDODOMAIN
X * FIDODOMAIN is defined in config.h
X *
X * $Log:   address.c,v $
X * Revision 1.14  91/05/19  17:21:17  mj
X * Ignores case when looking for FIDO address.
X * 
X * Revision 1.13  91/05/07  23:55:59  mj
X * Changed parsing of FIDO Internet addresses. The old style is no longer
X * supported, p.f.n.z accepts lower and upper case, new FIDO domains
X * p.f.n.z.HOSTNAME and p.f.n.z.HOSTNAME.DOMAIN.
X * 
X * Revision 1.12  91/03/29  18:07:56  mj
X * Some changes. (what?)
X * 
X * Revision 1.11  90/12/13  20:04:41  mj
X * Fixed a bug in parsefnetaddress().
X * 
X * Revision 1.10  90/12/02  21:21:07  mj
X * Changed program header to mention both authors of the original
X * software posted to alt.sources.
X * 
X * Revision 1.9  90/11/20  21:07:24  mj
X * New function ascnoden(): convert node address to string, point not
X * included.
X * 
X * Revision 1.8  90/11/05  20:48:49  mj
X * Changed my signature in all program headers.
X * 
X * Revision 1.7  90/09/30  14:39:52  mj
X * Better parsing for FIDO addresses including domain.
X * (e.g. "2:242/6@fidonet")
X * 
X * Revision 1.6  90/09/16  17:35:07  mj
X * Always output zone address in internode().
X * 
X * Revision 1.5  90/08/12  14:12:38  mj
X * Output of ascnode() now <zone>:<net>/<node> for non-point addresses.
X * 
X * Revision 1.4  90/07/30  19:58:57  mj
X * Added support for new style FIDO addresses:
X *     p<point>.f<node>.n<net>.z<zone>.FIDODOMAIN
X * FIDODOMAIN is defined in config.h
X * 
X * Revision 1.3  90/07/11  17:03:58  mj
X * Removed a bug in address parsing, when address is of type
X * `domain!name'.
X * 
X * Revision 1.2  90/07/01  13:27:11  mj
X * Removed all calls to alloca(). All unsave malloc()'s without
X * checking the returned pointer are now done via xmalloc().
X * Fixed a malloc() error in rmail.
X * 
X * Revision 1.1  90/06/28  22:02:46  mj
X * Much rework of the sources, no more hsu.h and other clean up.
X * rmail improved, now handles special XENIX quirks.
X * 
X * Revision 1.0  90/06/19  18:31:45  mj
X * Initial revision
X * 
X *
X *****************************************************************************
X * This version hacked and maintained by:
X *    _____ _____
X *   |     |___  |   Martin Junius     FIDO:    2:242/6.1   2:242/6.0
X *   | | | |   | |   Republikplatz 3   DOMAIN:  mju@dfv.rwth-aachen.de
X *   |_|_|_|_____|   D-5100 Aachen     Tel. (Voice) 0241-86931
X *
X * Original version of these programs and files:
X *
X *   Teemu Torma
X *   Heikki Suonsivu   FIDO: 2:504/1   UUCP: ...!mcsun!santra!hsu
X *
X *****************************************************************************/
X
#include "fidogate.h"
X
#include "shuffle.h"
X
X
X
/*
X * int parse_address()  ---  parse fidonet address to name, net/node
X *
X * Parameters: char *address   --- address string
X *             char *name      --- pointer to return name
X *             Node *node      --- pointer to return node address
X *
X * Return:     0 = o.k., -1 = error
X *
X * Two types of addresses are understood:
X * Domain:     name@p.f.n.z[.FIDODOMAIN]
X *             name%p.f.n.z[.FIDODOMAIN]
X * Bang:       p.f.n.z[.FIDODOMAIN]!name
X */
X
int parse_address(address, name, node)
char *address, *name;
Node *node;
{
static char error[64];
register char *cp;
register int cnt;
char *p;
X
X   /* make address to lowercase */
X   for (cp = address; *cp; cp++)
X       if (isupper(*cp))
X           *cp = tolower(*cp);
X
X   /* Get name. We assume that name has space at least 36 charcers (maximum
X      length of name in fido). First check whether format is name@domain
X      of domain!name format. */
X   if(cp = strchr(address, '!')) {
X       debug(2, "Fidonet address domain!name");
X       for (cp++, cnt = 0; *cp && cnt < 35; cnt++, cp++)
X           name[cnt] = *cp;
X       name[cnt] = 0;
X       cp = address;
X       debug(3, "Name %s", name);
X   }
X   else {
X       p = strrchr(address, '@');
X       if(!p)
X           p = strrchr(address, '%');
X       if(!p)
X           return -1;
X           
X       debug(2, "Fidonet address name[@%]domain");
X       for (cp = address, cnt = 0; *cp && cnt<35 && cp!=p; cp++, cnt++)
X           name[cnt] = *cp;
X       name[cnt] = 0;
X       debug(3, "Name %s", name);
X
X       cp = p + 1;
X   }
X
X   debug(2, "Address %s, up to '!' or end", cp);
X
X   return parseinternode(cp, node);
}
X
X
X
returnbad(errtype, s, node)
char *errtype, *s;
Node *node;
{
X   node->zone = MY_ZONE;
X   node->net = MY_NET;
X   node->node = MY_NODE;
X   node->point = MY_POINT;
X   return -1;
}
X
X
X
/***** isfido() --- Check for FIDO Internet address **************************/
X
int isfido(address)
char *address;
{
char name[128];
Node node;
X
X   return parse_address(address, name, &node) == 0;
}
X
X
X
/***** parseinternode() --- Convert FIDO Internet address to Node struct *****/
X
int parseinternode(address, node)
char *address;
Node *node;
{
char *p, *s;
char domain[128];
int len, dlen;
X
X   s = strsave(address);
X
X   /* Remove `!...' */
X   if(p = strrchr(s, '!'))
X       *p = 0;
X
X   /*
X    * Check for possible domains and remove them.
X    * Currently the following domains are recognized:
X    *         FIDODOMAIN
X    * e.g.    ".fidonet.org"
X    *         .MY_HOSTNAME
X    * e.g.    ".hippo"
X    *         .MY_HOSTNAME.MY_DOMAIN
X    * e.g.    ".hippo.dfv.rwth-aachen.de"
X    */
X   len  = strlen(s);
X   while(1) {
X       strcpy(domain, FIDODOMAIN);
X       dlen = strlen(domain);
X       if(len > dlen  &&  !stricmp(s + len - dlen, domain)) {
X           s[len - dlen] = 0;
X           break;
X       }
X
X       strcpy(domain, ".");
X       strcat(domain, MY_HOSTNAME);
X       dlen = strlen(domain);
X       if(len > dlen  &&  !stricmp(s + len - dlen, domain)) {
X           s[len - dlen] = 0;
X           break;
X       }
X
X       strcat(domain, MY_DOMAIN);
X       dlen = strlen(domain);
X       if(len > dlen  &&  !stricmp(s + len - dlen, domain))
X           s[len - dlen] = 0;
X       
X       break;
X   }
X
X   /*
X    * Address format: p<point>.f<node>.n<net>.z<zone>
X    */
X   node->zone  = REAL_ZONE;
X   node->net   = REAL_NET;
X   node->node  = REAL_NODE;
X   node->point = 0;
X   
X   for(p=strtok(s, "."); p; p = strtok(NULL, "."))
X       switch(*p) {
X           case 'p':
X           case 'P':
X               if(!isdigit(p[1])) {
X                   free(s);
X                   return -1;
X               }
X               node->point = atoi(p+1);
X               break;
X           case 'f':
X           case 'F':
X               if(!isdigit(p[1])) {
X                   free(s);
X                   return -1;
X               }
X               node->node  = atoi(p+1);
X               break;
X           case 'n':
X           case 'N':
X               if(!isdigit(p[1])) {
X                   free(s);
X                   return -1;
X               }
X               node->net   = atoi(p+1);
X               break;
X           case 'z':
X           case 'Z':
X               if(!isdigit(p[1])) {
X                   free(s);
X                   return -1;
X               }
X               node->zone  = atoi(p+1);
X               break;
X           default:
X               free(s);
X               return -1;
X               break;
X       }
X
X   return 0;
}
X
X
X
/*
X * Parse FIDO address  <zone>:<net>/<node>.<point> into
X * Node structure. Leading non-digits are ignored.
X */
X
parsefnetaddress(s, node)
char *s;
Node *node;
{
char *p, *lastnumber;
char nodenbuf[100];
int point_flag = 0;
X
X   strncpy(nodenbuf, s, 99);
X   nodenbuf[99] = 0;
X   s = nodenbuf;
X
X   node->zone  = 0;
X   node->net   = 0;
X   node->node  = 0;
X   node->point = 0;
X   p = s;
X
X   /* skip non-digits */
X   while (!isdigit(*p) && *p) p++;
X
X   lastnumber = NULL;
X
X   while (1) {
X       switch (*p) {
X           case '0':  case '1':  case '2': case '3':
X           case '4':  case '5':  case '6': case '7':
X           case '8':  case '9':
X               lastnumber = p;
X               while (isdigit(*++p));
X               continue;
X               break;
X           case ':':
X               /* Previous number is zone */
X               if (node->zone) return returnbad("two zones", s, node);
X               node->zone = atoi(lastnumber);
X               lastnumber = p + 1;
X               break;
X           case '/':
X               /* Previous number is net */
X               if (node->net) return returnbad("two nets", s, node);
X               node->net = atoi(lastnumber);
X               lastnumber = p + 1;
X               break;
X           case '.':
X               /* Previous number is node */
X               if (node->node) return returnbad("two nodes", s, node);
X               node->node = atoi(lastnumber);
X               lastnumber = p + 1;
X               point_flag = 1;
X               break;
X           case 0:                 /* Terminated by end of string or '@' */
X           case '@':               /* starting domain part of address    */
X               if(!lastnumber)
X                   return returnbad("empty address", s, node);
X               if(point_flag)
X                   node->point = atoi(lastnumber);
X               else
X                   node->node  = atoi(lastnumber);
X               if (node->zone == 0) node->zone = MY_ZONE;
X               if (node->net == 0) node->net = MY_NET;
X               return 0;
X               break;
X           default:
X               return returnbad("bad char", s, node);
X       }
X       p++;
X   }
X   if (node->zone == 0) node->zone = MY_ZONE;
X   if (node->net == 0) return returnbad("no net", s, node);
X   if (node->node == 0)
X       node->node = atoi(lastnumber);
X
X   return 0;
}
X
X
X
/* Return address in string format */
X
char *ascnode(node)
Node node;
{
X   SHUFFLEBUFFERS;
X
X   if(node.point)
X       sprintf(tcharp, "%d:%d/%d.%d", node.zone, node.net, node.node, node.point);
X   else
X       sprintf(tcharp, "%d:%d/%d", node.zone, node.net, node.node);
X   return tcharp;
}
X
X
char *ascnoden(node)
Node node;
{
X   SHUFFLEBUFFERS;
X
X   sprintf(tcharp, "%d:%d/%d", node.zone, node.net, node.node);
X   return tcharp;
}
X
X
X
/* Internet format */
char *internode(node)
Node node;
{
X   SHUFFLEBUFFERS;
X
X   if(node.point)
X       sprintf(tcharp, "p%d.f%d.n%d.z%d%s", node.point, node.node,
X                                            node.net,   node.zone,
X                                            FIDODOMAIN         );
X   else
X       sprintf(tcharp, "f%d.n%d.z%d%s", node.node, node.net,
X                                        node.zone, FIDODOMAIN );
X
X   return tcharp;
}
X
X
X
/***** Internet format without FIDODOMAIN ************************************/
X
char *internodex(node)
Node node;
{
X   SHUFFLEBUFFERS;
X   if(node.point)
X       sprintf(tcharp, "p%d.f%d.n%d.z%d", node.point, node.node,
X                                          node.net,   node.zone );
X   else
X       sprintf(tcharp, "f%d.n%d.z%d", node.node, node.net, node.zone);
X   return tcharp;
}
X
X
X
/* same for index node structure */
X
char *ascnodei(node)
NODEINDEX node;
{
X   SHUFFLEBUFFERS;
X
X   sprintf(tcharp, "%d:%d/%d", node.zone, node.net, node.node);
X   return tcharp;
}
SHAR_EOF
chmod 0644 address.c ||
echo 'restore of address.c failed'
Wc_c="`wc -c < 'address.c'`"
test 9687 -eq "$Wc_c" ||
    echo 'address.c: original size 9687, current size' "$Wc_c"
fi
# ============= sprintfs.c ==============
if test -f 'sprintfs.c' -a X"$1" != X"-c"; then
    echo 'x - skipping sprintfs.c (File already exists)'
else
echo 'x - extracting sprintfs.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'sprintfs.c' &&
/*:ts=4*/
/*****************************************************************************
X * FIDOGATE --- Gateway software UNIX <-> FIDO
X *
X * $Id: sprintfs.c,v 1.2 90/12/02 21:22:41 mj Exp $
X *
X * Special printf() function
X *
X * $Log:   sprintfs.c,v $
X * Revision 1.2  90/12/02  21:22:41  mj
X * Changed program header to mention both authors of the original
X * software posted to alt.sources.
X * 
X * Revision 1.1  90/11/05  20:51:10  mj
X * Changed my signature in all program headers.
X * 
X * Revision 1.0  90/06/21  19:10:16  mj
X * Initial revision
X * 
X *
X *****************************************************************************
X * This version hacked and maintained by:
X *    _____ _____
X *   |     |___  |   Martin Junius     FIDO:    2:242/6.1   2:242/6.0
X *   | | | |   | |   Republikplatz 3   DOMAIN:  mju@dfv.rwth-aachen.de
X *   |_|_|_|_____|   D-5100 Aachen     Tel. (Voice) 0241-86931
X *
X * Original version of these programs and files:
X *
X *   Teemu Torma
X *   Heikki Suonsivu   FIDO: 2:504/1   UUCP: ...!mcsun!santra!hsu
X *
X *****************************************************************************/
X
#include "fidogate.h"
X
#include <varargs.h>
#include "shuffle.h"
X
X
/* Strcat creating its own buffer */
X
char *sstrcat(d, s)
X     char *d, *s;
{
X  SHUFFLEBUFFERS;
X
X  (void) strncpy(tcharp, d, MAX_CONVERT_BUFLEN);
X  tcharp[MAX_CONVERT_BUFLEN - 1] = '\0';
X  (void) strncat(tcharp, s, MAX_CONVERT_BUFLEN);
X  return tcharp;
}
X
/* Sprintf with own buffer */
X
/*VARARGS1*/
char *sprintfs(fmt, va_alist)
X     char *fmt;
X     va_dcl
{
X  va_list pvar;
X
X  va_start(pvar);
X
X  SHUFFLEBUFFERS;
X
X  vsprintf(tcharp, fmt, pvar);
X
X  va_end(pvar);
X
X  return tcharp;
}
X
SHAR_EOF
chmod 0644 sprintfs.c ||
echo 'restore of sprintfs.c failed'
Wc_c="`wc -c < 'sprintfs.c'`"
test 1670 -eq "$Wc_c" ||
    echo 'sprintfs.c: original size 1670, current size' "$Wc_c"
fi
# ============= strempty.c ==============
if test -f 'strempty.c' -a X"$1" != X"-c"; then
    echo 'x - skipping strempty.c (File already exists)'
else
echo 'x - extracting strempty.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'strempty.c' &&
/*:ts=4*/
/*****************************************************************************
X * FIDOGATE --- Gateway software UNIX <-> FIDO
X *
X * $Id: strempty.c,v 1.2 90/12/02 21:22:42 mj Exp $
X *
X * strempty(), strclean()
X *
X * $Log:   strempty.c,v $
X * Revision 1.2  90/12/02  21:22:42  mj
X * Changed program header to mention both authors of the original
X * software posted to alt.sources.
X * 
X * Revision 1.1  90/11/05  20:51:11  mj
X * Changed my signature in all program headers.
X * 
X * Revision 1.0  90/06/21  19:11:09  mj
X * Initial revision
X * 
X *
X *****************************************************************************
X * This version hacked and maintained by:
X *    _____ _____
X *   |     |___  |   Martin Junius     FIDO:    2:242/6.1   2:242/6.0
X *   | | | |   | |   Republikplatz 3   DOMAIN:  mju@dfv.rwth-aachen.de
X *   |_|_|_|_____|   D-5100 Aachen     Tel. (Voice) 0241-86931
X *
X * Original version of these programs and files:
X *
X *   Teemu Torma
X *   Heikki Suonsivu   FIDO: 2:504/1   UUCP: ...!mcsun!santra!hsu
X *
X *****************************************************************************/
X
#include "fidogate.h"
X
X
X
/* Check if string just consists of space (or is null). Return TRUE if so */
X
strempty(s)
X     char *s;
{
X  while (*s) if (!isspace(*s)) return FALSE; else s++;
X  return TRUE;
}
X
/* Clean up space from start and end */
X
char *strclean(s)
X     char *s;
{
X  char *d = s, *p = s;
X
X  /* Find first non-space char */
X  for (; *p; p++) if (!isspace(*p)) break;
X
X  /* Copy until end */
X  if (d != p) while (*d++ = *p++);
X
X  /* Strip space from end */
X  while (strlen(s) && isspace(s[strlen(s) - 1])) s[strlen(s) - 1] = 0;
X
X  return s;
}
X
/* Clean up whitespace from start */
char *strsclean(s)
X     char *s;
{
X  char *d = s, *p = s;
X
X  /* Find first non-space char */
X  for (; *p; p++) if (!isspace(*p)) break;
X
X  /* Copy until end */
X  if (d != p) while (*d++ = *p++);
X
X  return s;
}
SHAR_EOF
chmod 0644 strempty.c ||
echo 'restore of strempty.c failed'
Wc_c="`wc -c < 'strempty.c'`"
test 1919 -eq "$Wc_c" ||
    echo 'strempty.c: original size 1919, current size' "$Wc_c"
fi
# ============= xalloc.c ==============
if test -f 'xalloc.c' -a X"$1" != X"-c"; then
    echo 'x - skipping xalloc.c (File already exists)'
else
echo 'x - extracting xalloc.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'xalloc.c' &&
/*:ts=4*/
/*****************************************************************************
X * FIDOGATE --- Gateway software UNIX <-> FIDO
X *
X * $Id: xalloc.c,v 1.4 90/11/05 20:51:14 mj Exp $
X *
X * Safe alloc routines.
X *
X * $Log:   xalloc.c,v $
X * Revision 1.4  90/11/05  20:51:14  mj
X * Changed my signature in all program headers.
X * 
X * Revision 1.3  90/09/08  18:49:31  mj
X * Move strsaveline() to xalloc.c
X * 
X * Revision 1.2  90/07/01  15:20:50  mj
X * Fixed some bugs in funpack caused by the removal of alloca().
X * No more core dumps, but heaven knows, why it works now. Strange.
X * 
X * Revision 1.1  90/07/01  13:46:30  mj
X * Removed all calls to alloca(). All unsave malloc()'s without
X * checking the returned pointer are now done via xmalloc().
X * Fixed a malloc() error in rmail.
X * 
X * Revision 1.0  90/06/28  21:25:56  mj
X * Initial revision
X * 
X *
X *****************************************************************************
X * This version hacked and maintained by:
X *    _____ _____
X *   |     |___  |   Martin Junius     FIDO:    2:242/6.1   2:242/6.0
X *   | | | |   | |   Republikplatz 3   DOMAIN:  mju@dfv.rwth-aachen.de
X *   |_|_|_|_____|   D-5100 Aachen     Tel. (Voice) 0241-86931
X *
X *****************************************************************************/
X
#include "fidogate.h"
X
char *malloc(), *realloc();
X
X
/*
X * xmalloc(), xrealloc()  ---  safe versions of malloc() and realloc()
X */
X
char *xmalloc(size)
int size;
{
char *p;
X
X   if(p = malloc(size))
X       return(p);
X   log("Memory exhausted.");
X   exit(EX_OSERR);
}
X
char *xrealloc(ptr, size)
char *ptr;
int size;
{
char *p;
X
X   if(p = realloc(ptr, size))
X       return(p);
X   log("Memory exhausted.");
X   exit(EX_OSERR);
}
X
X
X
/*
X * strsave()  ---  make a copy of a string
X */
X
char *strsave(s)
char *s;
{
char *p;
X
X   p = xmalloc(strlen(s) + 1);
X   strcpy(p, s);
X   return(p);
}
X
X
X
/*
X * strsaveline() --- like strsave(), but remove '\n' at end of line if any
X */
X
char *strsaveline(s)
char *s;
{
char *r;
int len;
X
X   r = strsave(s);
X   len = strlen(r);
X   if(r[len - 1] == '\n')
X       r[len - 1] = 0;
X   return(r);
}
SHAR_EOF
chmod 0644 xalloc.c ||
echo 'restore of xalloc.c failed'
Wc_c="`wc -c < 'xalloc.c'`"
test 2067 -eq "$Wc_c" ||
    echo 'xalloc.c: original size 2067, current size' "$Wc_c"
fi
# ============= msgidseq.c ==============
if test -f 'msgidseq.c' -a X"$1" != X"-c"; then
    echo 'x - skipping msgidseq.c (File already exists)'
else
echo 'x - extracting msgidseq.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'msgidseq.c' &&
/*:ts=4*/
/*****************************************************************************
X * FIDOGATE --- Gateway software UNIX <-> FIDO
X *
X * $Id: msgidseq.c,v 1.1 90/11/05 20:50:47 mj Exp $
X *
X * Output new message id number from sequencer file. Stand alone program
X * for use by CNews. 
X *
X * Install this program in /u/lib/newsbin or similar directory. Then change
X * Message-ID: generating software to use msgidseq, e.g. last line of
X * inject/anne.jones for CNews.
X *
X * $Log:   msgidseq.c,v $
X * Revision 1.1  90/11/05  20:50:47  mj
X * Changed my signature in all program headers.
X * 
X * Revision 1.0  90/08/18  15:43:18  mj
X * Initial revision
X * 
X *
X *****************************************************************************
X * This version hacked and maintained by:
X *    _____ _____
X *   |     |___  |   Martin Junius     FIDO:    2:242/6.1   2:242/6.0
X *   | | | |   | |   Republikplatz 3   DOMAIN:  mju@dfv.rwth-aachen.de
X *   |_|_|_|_____|   D-5100 Aachen     Tel. (Voice) 0241-86931
X *
X *****************************************************************************/
X
#include "fidogate.h"
X
X
X
int verbose = 0;
X
X
main()
{
long msgid;
X
X   msgid = sequencer(MSGIDSEQ);
X   printf("%ld\n", msgid);
}
SHAR_EOF
chmod 0644 msgidseq.c ||
echo 'restore of msgidseq.c failed'
Wc_c="`wc -c < 'msgidseq.c'`"
test 1206 -eq "$Wc_c" ||
    echo 'msgidseq.c: original size 1206, current size' "$Wc_c"
fi
exit 0

--
 _____ _____
|     |___  |   Martin Junius     FIDO:    2:242/6.1   2:242/6.0
| | | |   | |   Republikplatz 3   DOMAIN:  mj@dfv.rwth-aachen.de
|_|_|_|_____|   D-5100 Aachen     Tel. (Voice) 0241-86931