/*
    $Header: Welmat:src/RCS/lookup.c,v 1.3 93/01/23 16:08:11 rwm Exp Locker: rwm $

    Nodelist lookup routines, extracted

    Copyright (C) 1992 Russell McOrmond

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#ifdef RCSID
static char RCSid[]="$Id: lookup.c,v 1.3 93/01/23 16:08:11 rwm Exp Locker: rwm $";
#endif

#include <exec/types.h>
#include <exec/libraries.h>
#include <proto/exec.h>
#include <dos/var.h>
#include <stdio.h>
#include <string.h>

#include "nl.h"

typedef struct addrdec {
  BYTE network;               /* what kind of site are we connecting to */

#define NET_FIDO       0
#define NET_UUCP       1
#define NET_SLIP       2
#define NET_OTHER      3

  union addr {             /* Site specific address */
    struct fidoaddr {
      UWORD zone;
      UWORD area;
      UWORD node;
      UWORD point;
      char domain[32];
    } fido;
    struct uucpaddr {
      UWORD fill[4];
      char uuname[32];
    } uucp;
  } address;
} addrdec;

struct NodelistBase *NodelistBase;

int decodeFidoAddress(char *raw,addrdec *cooked)
{
  char *step;
  char node,domain;

  domain=node=FALSE;
  cooked->address.fido.domain[0]='\0';
  cooked->address.fido.zone=1;
  cooked->address.fido.area=0;
  cooked->address.fido.node=0;
  cooked->address.fido.point=0;
  cooked->network=NET_FIDO;

  for(step=raw; *step!='\0'; step++) {
    if(*step==':') {
      *step++='\0';
      cooked->address.fido.zone=atoi(raw);
      raw=step;
    }
    else if(*step=='/') {
      *step++='\0';
      cooked->address.fido.area=atoi(raw);
      raw=step;
    }
    else if(*step=='.') {
      *step++='\0';
      cooked->address.fido.node=atoi(raw);
      raw=step;
      node=TRUE;
    }
    else if(*step=='@') {
      *step++='\0';
      if(node==TRUE) {
        cooked->address.fido.point=atoi(raw);
      }
      else {
        cooked->address.fido.node=atoi(raw);
        cooked->address.fido.point=0;
        node=TRUE;
      }
      strncpy(cooked->address.fido.domain,step,30);
      domain=TRUE;
      return(TRUE);
    }
    else if(*step=='#') {
      *step++='\0';
      strncpy(cooked->address.fido.domain,raw,30);
      raw=step;
      domain=TRUE;
    }
    else if(domain && !isdigit(*step)) {
      /* Bad point address! */
      return(FALSE);
    }
  }
  if(node==TRUE) {
    cooked->address.fido.point=atoi(raw);
  }
  else {
    if (isdigit(*raw)) {
       cooked->address.fido.node=atoi(raw);
       cooked->address.fido.point=0;
    } else {
       int q;
       cooked->network=NET_UUCP;
       for(q=0;q<4;q++) cooked->address.uucp.fill[q]=0;
       strncpy(cooked->address.fido.domain,raw,30);
    }
  }
  return(TRUE);
}

char *getNodeNameSafe(addrdec *s,char *sitename)
{
  switch(s->network) {
    case NET_FIDO:
      SPrintF(sitename,"%s#%lu:%lu/%lu.%lu",
                         (strlen(s->address.fido.domain)) ? 
                         (s->address.fido.domain) : "fidonet",
                         s->address.fido.zone, s->address.fido.area,
                         s->address.fido.node, s->address.fido.point);
      return(sitename);
      break;

    case NET_UUCP:
      strcpy(sitename,s->address.uucp.uuname);
      return(sitename);
      break;

  }
  return(NULL);
}

main(int argc,char **argv)
{
  char *nodelist,*stem,var[32],temp[255];
  addrdec aSite;
  NodeList the_nodelist;
  NodeDesc *node_desc;
  Addr find_me;
  long ret;

  if((argc>4) || (argc<2)) {
    printf("Usage: %s address [nodelistpath [stem variable] ]\n\n",argv[0]);
    exit(99);
  }
  memset(&aSite,0,sizeof(addrdec));
  if(decodeFidoAddress(argv[1],&aSite)) {
    nodelist=(argc>2) ? argv[2] : "nodelist:";
    if(stem=(argc>3) ? argv[3] : NULL) {
      SPrintF(var,"%s.zone",stem);
      DeleteVar(var,GVF_GLOBAL_ONLY);
      SPrintF(var,"%s.net",stem);
      DeleteVar(var,GVF_GLOBAL_ONLY);
      SPrintF(var,"%s.node",stem);
      DeleteVar(var,GVF_GLOBAL_ONLY);
      SPrintF(var,"%s.point",stem);
      DeleteVar(var,GVF_GLOBAL_ONLY);
      SPrintF(var,"%s.Domain",stem);
      DeleteVar(var,GVF_GLOBAL_ONLY);
      SPrintF(var,"%s.Address",stem);
      DeleteVar(var,GVF_GLOBAL_ONLY);
      SPrintF(var,"%s.Sitename",stem);
      DeleteVar(var,GVF_GLOBAL_ONLY);
      SPrintF(var,"%s.Sysop",stem);
      DeleteVar(var,GVF_GLOBAL_ONLY);
      SPrintF(var,"%s.Number",stem);
      DeleteVar(var,GVF_GLOBAL_ONLY);
      SPrintF(var,"%s.Password",stem);
      DeleteVar(var,GVF_GLOBAL_ONLY);
      SPrintF(var,"%s.Flags",stem);
      DeleteVar(var,GVF_GLOBAL_ONLY);
      SPrintF(var,"%s.MaxBaud",stem);
      DeleteVar(var,GVF_GLOBAL_ONLY);
      SPrintF(var,"%s.Cost",stem);
      DeleteVar(var,GVF_GLOBAL_ONLY);
    }
    if(NodelistBase=OpenLibrary(NODELIST_NAME,NODELIST_VER)) {
      find_me.Zone=aSite.address.fido.zone;
      find_me.Net=aSite.address.fido.area;
      find_me.Node=aSite.address.fido.node;
      find_me.Point=aSite.address.fido.point;
      find_me.Domain=(strlen(aSite.address.fido.domain)) ?
                     (aSite.address.fido.domain) : "fidonet";
      node_desc=NULL;
      if((the_nodelist = NLOpen(nodelist, 0)) && 
         (node_desc = NLFind(the_nodelist, &find_me, 0))) {

         if (stem) {
           SPrintF(var,"%s.zone",stem);
           SPrintF(temp,"%ld",node_desc->Node.Zone);
           SetVar(var,temp,-1,GVF_GLOBAL_ONLY);
           SPrintF(var,"%s.net",stem);
           SPrintF(temp,"%ld",node_desc->Node.Net);
           SetVar(var,temp,-1,GVF_GLOBAL_ONLY);
           SPrintF(var,"%s.node",stem);
           SPrintF(temp,"%ld",node_desc->Node.Node);
           SetVar(var,temp,-1,GVF_GLOBAL_ONLY);
           SPrintF(var,"%s.point",stem);
           SPrintF(temp,"%ld",node_desc->Node.Point);
           SetVar(var,temp,-1,GVF_GLOBAL_ONLY);

           if(!node_desc->Node.Domain) node_desc->Node.Domain="fidonet";
           SPrintF(var,"%s.Domain",stem);
           SetVar(var,node_desc->Node.Domain,-1,GVF_GLOBAL_ONLY);

           aSite.address.fido.zone=node_desc->Node.Zone;
           aSite.address.fido.area=node_desc->Node.Net;
           aSite.address.fido.node=node_desc->Node.Node;
           aSite.address.fido.point=node_desc->Node.Point;
           strncpy(aSite.address.fido.domain,node_desc->Node.Domain,30);
           SPrintF(var,"%s.Address",stem);
           SetVar(var,getNodeNameSafe(&aSite,temp),-1,GVF_GLOBAL_ONLY);

           if(!node_desc->System) node_desc->System="";
           SPrintF(var,"%s.Sitename",stem);
           SetVar(var,node_desc->System,-1,GVF_GLOBAL_ONLY);

           if(!node_desc->Sysop) node_desc->Sysop="";
           SPrintF(var,"%s.Sysop",stem);
           SetVar(var,node_desc->Sysop,-1,GVF_GLOBAL_ONLY);

           if(!node_desc->Phone) node_desc->Phone="";
           SPrintF(var,"%s.Number",stem);
           SetVar(var,node_desc->Phone,-1,GVF_GLOBAL_ONLY);

           if(!node_desc->Passwd) node_desc->Passwd="";
           SPrintF(var,"%s.Password",stem);
           SetVar(var,node_desc->Passwd,-1,GVF_GLOBAL_ONLY);

           if(!node_desc->Flags) node_desc->Flags="";
           SPrintF(var,"%s.Flags",stem);
           SetVar(var,node_desc->Flags,-1,GVF_GLOBAL_ONLY);

           SPrintF(var,"%s.MaxBaud",stem);
           SPrintF(temp,"%ld",node_desc->BaudRate);
           SetVar(var,temp,-1,GVF_GLOBAL_ONLY);

           SPrintF(var,"%s.Cost",stem);
           SPrintF(temp,"%ld",node_desc->Cost);
           SetVar(var,temp,-1,GVF_GLOBAL_ONLY);
	 } else {
           printf("\rNODE: %d:%d/%d.%d ($%ld.%02ld)\n",find_me.Zone,
                 find_me.Net,find_me.Node,find_me.Point,
                 node_desc->Cost/100,node_desc->Cost%100);
           printf("Region: %d, Hub: %d\n",node_desc->Region,node_desc->HubNode);
           printf("System Name:  %s\n",node_desc->System);
           printf("Sysop Name:   %s\n",node_desc->Sysop);
           printf("Phone Number: %s\n",node_desc->Phone);
           printf("City:         %s\n",node_desc->City);
           printf("Password:     %s\n",node_desc->Passwd);
           printf("Flags:        %s\n",node_desc->Flags);
           printf("BaudRate      %ld\n",node_desc->BaudRate);
           printf("Line:%s\n",node_desc->Line);
	 }
         NLFreeNode(node_desc);
         ret=0;
        } else {
          if (!stem) 
             printf("\rCouldn't find %d:%d/%d.%d\n",find_me.Zone,
                      find_me.Net,find_me.Node,find_me.Point);
          ret=1;
	}
      if(the_nodelist) NLClose(the_nodelist);
      CloseLibrary(NodelistBase);
    } else ret=2;
  } else ret=3;
  exit(ret);
}
