/*
 * $Id: support.c,v 1.1 1995/01/05 09:14:58 root Exp root $
 *
 * Support functions
 */
#include "sap.h"
#include <stdarg.h>
#include <syslog.h>
#include <sys/syslog.h>

/*
 * Line reader / pre-scanner
 */
char *getline(char *str,int cnt,FILE *fp) {
  int i,c;

  if (feof(fp)) return NULL;

  for (i=0; (c=getc(fp)) != EOF && i<cnt && c!='\n' && c!='#';)  str[i++] = c;

  if (c == '#')  while ( (c=getc(fp)) != EOF && c != '\n');
  str[i] = '\000';
  return str;
}
/***********************************************************************/
static char *skipSpace(char *p) { while (isspace(*p)) p++; return p; }

/*
 * separate line into words
 */
int parse(char *buf,char **argtab,char *z) {
  char *p;
  int argcount=0;
  for (p=skipSpace(buf) ; p && *p ; p=skipSpace(p)) {
    BOOL quote=FALSE;
    *argtab++ = z;
    argcount++;
    for ( ; *p ; p++) {
      if (quote) {
        if (*p == '"') {
	  if (p[1] == '"')
	    *z++ = *p++;
	  else
	    quote = FALSE;
	}
	else
	  *z++ = *p;
      }
      else {
        if (isspace(*p)) break;	/* Break out of the loop... */
	else if (*p == '"') quote = TRUE;
	else *z++ = *p;
      }
    }
    if (*p) p++;
    *z++ = '\000';
  } 
  *argtab = NULL;
  return argcount;
}

/*
 * ASCII Hex string to unsigned long conversion
 */
static int ascii2hex(int ch) { 
  if ('0' <= ch && ch <= '9') return ch-'0';
  if ('a' <= ch && ch <= 'f') return ch-'a'+10;
  if ('A' <= ch && ch <= 'F') return ch-'A'+10;
  return -1;
}

unsigned long gethex(char *s) {
  unsigned long hex = 0;
  while (*s) {
    hex = hex * 0x10 + ascii2hex(*s);
    s++;
  }
  return hex;
}

static void ipx_getnode(unsigned char node[],char *name) {
  /* Maybe in the future we could use names instead of node addresses */
  int x=0;
  while (*name) {
    x = !x;
    if (x)
      *node = ascii2hex(*name++)*0x10;
    else
      *node++ += ascii2hex(*name++);
  }
}

unsigned long ipx_getipxaddr(unsigned char node[],char *s) {
  unsigned long hex = 0;
  while (*s && *s != ':') {
    hex = hex * 0x10 + ascii2hex(*s);
    s++;
  }
  if (*s != ':') return 0;
  ipx_getnode(node,++s);  
  return hex;
}

/*
 * Convert frame string to a constant
 */
/* Ignore case when comparing two strings */
int ISTRCMP(char *a,char *b) {
  for (;;) {
    int x1=isupper(*a) ? tolower(*a) : *a;
    int x2=isupper(*b) ? tolower(*b) : *b;
    if (x1 != x2) return x1-x2;
    if (x1 == 0) return 0;
    a++,b++;
  } 
}

int asc2frame(char *frame) {
  if (!ISTRCMP("ethernet_ii",frame))
    return IPX_RT_BLUEBOOK;
  else if (!ISTRCMP("802.2",frame))
    return IPX_RT_8022;
  else if (!ISTRCMP("snap",frame))
    return IPX_RT_SNAP;
  else
    return 0;
}

char *ipx_ntoa(unsigned char *node) {
  static char conv[] = "0123456789ABCDEF";
  static char buf[16];
  char *d, k;
  for (k = 0, d=buf; k < 6; k++) {
    *d++ = conv[node[k]/0x10];
    *d++ = conv[node[k] & 0x0f];
  }
  *d = '\000';
  return buf;
}

void sysMsg(int lvl,int eno,char *fmt,...) {
  static char msb[1024];
  va_list ap;
  va_start(ap,fmt);
  vsprintf(msb,fmt,ap);
  if (eno != ERR_ERRNO) errno = eno;
#ifdef DEBUG
  if (errno != ERR_OK) 
    perror(msb);
  else
    fprintf(stderr,"%s\n",msb);
  fflush(stderr);
#else
#ifdef LOG_FILE
  {
    FILE *fp = fopen(LOG_FILE,"a");
    if (fp) {
      fprintf(fp,errno != ERR_OK ? "%s (%s)\n" : "%s\n" ,msb,strerror(errno));
      fclose(fp);
    }
  }
#else
  syslog(lvl ? LOG_INFO : LOG_ERR, errno == ERR_OK ? "%s" : "%s (%s)",
	 msb, strerror(errno));
#endif
#endif
  if (!lvl) exit(errno);
}

#ifdef DEBUG
void dump_pkt(void *p,unsigned int x) {
  unsigned char *z = (unsigned char *)p;
  int i,j;

  puts("OFF .0..1..2..3..4..5..6..7..8..9..A..B..C..D..E..F. 0123456789ABCDEF\
\n=== ================================================ ================");
  for (i = 0;i < x; i+= 16) {
    printf("%03X ",i);
    for (j=0; j  < 16 ; j++) 
      if (i+j < x) 
	printf("%02X ",z[i+j]);
      else
	printf("   ");
    putchar(' ');
    for (j=0; j  < 16 ; j++) 
      if (i+j < x) 
	putchar( ' ' <= z[i+j] && z[i+j] < '\177' ? z[i+j] : '.');
      else
	putchar(' ');
    putchar('\n');
  }
}
#endif
