/*
  ftn_address convers routines
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#include "config.h"

#define s2i(s) ((*(s) == '*')?-1:atoi((s)))

int strtonode(node_t *ad, const char *s, const node_t *defaddr)
{
	const char *p, *pl;
	static char domain[512];
	char *pw;
	int st;
	
	if (defaddr) memcpy(ad, defaddr, sizeof(node_t));
	else memset(ad, 0, sizeof(node_t));
	pw = domain; *pw = 0;
	ad->point = 0;

	for (st = 0, pl = p = s; ; p++) {
		switch (st) {
st_0:		case 0:	switch (*p) {
			case 'p': st = 100; goto st_100;
			case 'f': st = 102; goto st_102;
			case ':': st = 1; ad->zone= s2i(pl); pl=p+1; goto done;
			case '/': st = 2; ad->net = s2i(pl); pl=p+1; goto done;
			case '.': st = 3; if (*s != '.') ad->node = s2i(pl);
				  ad->point = s2i(p+1); goto done;
			}
			goto st_50;
			
		case 1: if (*p == '/') goto st_0;    break;
		case 2: if (*p == '.') goto st_0;
			if (*p == '@' || !*p) goto st_50;
			break;
				
st_3:		case 3: if (*p == '@') { st = 200; goto done; }
			if (!*p) goto done;
			break;
			
st_50:		case 50:switch (*p) {
			case '@': st = 200;
			case 0: if (*pl == 0) goto ret_err;
				ad->node = s2i(pl); goto done;
			}
			break;
			
st_100:		case 100:if (*p == 'p'){st = 101;ad->point=s2i(p+1);goto done;}
			 goto ret_err;
		case 101:if (*p == '.'){ st = 102; goto done; } goto st_3;
st_102:		case 102:if (*p == 'f'){st = 103; ad->node=s2i(p+1); goto done;}
			 goto ret_err;
		case 103:if (*p == '.'){ st = 104; goto done; } goto st_3;
		case 104:if (*p == 'n'){ st = 105; ad->net=s2i(p+1); goto done;}
			 goto ret_err;
		case 105:if (*p == '.'){ st = 106; goto done; } goto st_3;
		case 106:if (*p == 'z'){ st = 3; ad->zone=s2i(p+1); goto done;}
			 goto ret_err;
			 
		case 200:*pw++ = *p;
			 goto done;
		}
		
		/* skip other characters */
		if (*p == '*') {
			switch(p[1]) {
			case '.': if (st != 2 && st != 101 && st != 103 &&
				      st != 105 && st != 0) goto ret_err;
				break;
			case ':': if (st != 0) goto ret_err;
				break;
			case '/': if (st != 0 && st != 1) goto ret_err;
				break;
			case 0:
			case '@': if (st != 50 && st != 3 && st != 2 &&
				      st != 0)
					  goto ret_err;
				break;
			default: goto ret_err;
			}
		} else if (!isdigit(*p)) goto ret_err;

	done:
		if (!*p) break;
		continue;
		
	ret_err:
		return p-s+1;
	}
	if (!domain[0]) ad->domain = NULL; else ad->domain = xstrcpy(domain);
	if (ad->zone < 0 || ad->node < 0 || ad->point < 0 || ad->net < 0)
		return -1; /* we do not need wildcards in gtic */
	return 0;
}

char *nodetostr(char *str, const node_t * node)
{
  static char sstr[32];
  char *p;

  if (!str)
    p = sstr;
  else
    p = str;
  if (node->point != 0)
  {
    sprintf(p, "p%d.f%d.n%d.z%d", node->point,
	    node->node, node->net, node->zone);
  }
  else
  {
    sprintf(p, "f%d.n%d.z%d", node->node, node->net, node->zone);
  }
  if (node->domain) strcat(strcat(p,"@"), node->domain);

  return p;
}

char *nodetoftn(char *str, const node_t * node)
{
  static char sstr[FTN_MAX_SIZE];
  char *p;

  if (!str)
    p = sstr;
  else
    p = str;
  
  if (node->point != 0)
  {
    sprintf(p, "%d:%d/%d.%d", node->zone, node->net, node->node,
	    node->point);
  }
  else
    sprintf(p, "%d:%d/%d", node->zone, node->net, node->node);
  
  if (node->domain) strcat(strcat(p,"@"), node->domain);

  return p;
}

int nodecmp(node_t *dest,node_t *src)
{
  if(dest->zone!=src->zone) return 1;
  if(dest->net!=src->net) return 1;
  if(dest->node!=src->node) return 1;
  if(dest->point!=src->point) return 1;
  if((dest->domain&&!src->domain)||(!dest->domain&&src->domain)) return 1;
  if(!src->domain&&!dest->domain) return 0;
  if(!strcmp(src->domain,dest->domain)) return 1;
  return 0;
}

void nodecpy(node_t *dest,node_t *src)
{
  dest->zone=src->zone;
  dest->net=src->net;
  dest->node=src->node;
  dest->point=src->point;
  dest->domain=src->domain;
}



syntax highlighted by Code2HTML, v. 0.9.1