/*  Asp Address Search Protocol Client (file addr.c)                       */
/*  Copyright (C) 1996-2001 Stenio Brunetta                                */
/*                                                                         */
/*  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.              */
/*                                                                         */
/*  Author's email address: stenio@brunettaeperin.it                       */

static char rcsid[] = "$Id: addr.c,v 1.14 2001/01/23 11:20:01 ste Exp $";

#include "asp.h"


void avoid_addr_rcsid_warning(void){
  rcsid[0] = 0;
}

char** get_token(int* i, char* s){
  char** pp = NULL, *aux = NULL;
  int c = 0, n;
  
  if(s != NULL){
    aux = calloc((size_t)strlen(s)+1, sizeof(char));
    strcpy(aux, s);
    
    if(strtok(aux, " \t") != NULL){
      c++;
      for(; strtok(NULL, " \t") != NULL; )
	c++;

      free(aux);
      
      /* Gli ho aggiunto un puntatore per simulare argv[0] 
       per getopt */
      pp = calloc((size_t)c+1, sizeof(char*));
      *pp = NULL;
      *(pp+1) = strtok(s, " \t");
      
      for(n=2; n <= c; n++)
	*(pp+n) = strtok(NULL, " \t");
    }
  }else{
    i = 0;
    return NULL;
  }
  *i = c;
  return pp;
}

int next_ip(char buffer[20]){
  int c, i, i1, star = 0, minus = 0, index = 0, cPoint = 0, cDigit = 0;
  char buffer1[20], *p;

  /* salta gli spazi bianchi */
  while(isspace(c = getchar()))
    ;
  
  /* fine flusso */
  if(c == EOF) return 0;

  /* rimette l'ultimo carattere che non era uno spazio */
  ungetc(c, stdin);

  /* azzera il buffer */
  bzero(buffer, 20);

  while((c = getchar()) != EOF && !isspace(c) && index < 19)
    switch(c){
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
      if(cDigit < 3 ){
        buffer[index++] = c;
        cDigit++;
      }
      else return -1; /* piu` di 3 cifre non possono esserci */
      break;
    case '.':
      if(cDigit != 0 && cPoint < 3){
	buffer[index++] = c;
	cDigit = 0;
	cPoint++;
      }else return -1;
      break;
    case '*':
      if(cPoint == 3 && cDigit == 0){
	strcat(buffer, "1-254");
	star = 1;
      }else return -1;
      break;
    case '-':
      if(cPoint == 3 && cDigit != 0){
	buffer[index++] = c;
	minus = 1;
	cDigit = 0;
      }else return -1;
      break;
    default:
      return -1;
      break;
    }

  /* usati meno di tre punti */
  if(cPoint != 3) return -1;

  /* finito col punto */
  if(cDigit == 0 && star != 1) return -1;

  /* 012.456.890.234-678 */
  if(index == 19 && !isspace(c)) return -1;

  ungetc(c, stdin);

  /* necessario poiche` la strtok sporca buffer */
  strcpy(buffer1, buffer);

  /* non possono esserci numeri negativi */
  if(atoi(strtok(buffer1, ".")) > 255)
    return -1;
  if(atoi(strtok(NULL, ".")) > 255)
    return -1;
  if(atoi(strtok(NULL, ".")) > 255)
    return -1;

  if(star == 0 && minus == 0){
    if(atoi(strtok(NULL, ".")) > 255)
    return -1;
  }else{
    p = strtok(NULL, ".");
    strcpy(buffer1, p);
    i = atoi(strtok(buffer1, "-"));
    i1 = atoi(strtok(NULL, "-"));
    if(i > 255 || i1 > 255 || i > i1)
      return -1;
  }
  
  return 1;
}

int meta(char buffer[20]){
  char* p = strchr(buffer, '*');
  if(p != NULL) return 1;
  p = strchr(buffer, '-');
  if(p != NULL) return 1;
  return 0;
}

int expand_ip(char buffer[20]){
  static int start = 0, stop = 0;
  char* p, buffer1[20];
  if(start == 0 && stop == 0){
    if((p = strchr(buffer, '*')) != NULL){
      start = 1;
      stop = 254;
    }else{
      strcpy(buffer1, buffer);
      p = strrchr(buffer1, '.');
      start = atoi(strtok(p+1, "-"));
      stop = atoi(strtok(NULL, "-"));
      p = strrchr(buffer, '.');
    }
    sprintf(p+1, "%d", start++);
    return 1;
  }
  else{
    if(start > stop){
      start = stop = 0;
      return 0;
    }
    p = strrchr(buffer, '.');
    sprintf(p+1, "%d", start++);
    return 1;
  }
}

int get_ip(char buffer[20]){
  static int m = 0;
  int stat;
  if(m == 0){
    stat = next_ip(buffer);
    if(stat < 1) return stat;
    if(meta(buffer)){
      m = 1;
      expand_ip(buffer);
      return 1;
    }
  }else
    if(expand_ip(buffer) == 0){
      m = 0;
      return get_ip(buffer);
    }
  return 1;
}
