/*
		                  LCRZO
                             Network library
             Copyright(c) 1999,2000,2001,2002 Laurent Constantin
                                  -----

  Main server    : http://www.laurentconstantin.com/
  Backup servers : http://go.to/laurentconstantin/
                   http://laurentconstantin.est-la.com/
                   http://laurentconstantin.free.fr/
                   http://lauconstantin.multimania.com/
  [my current email address is on the web servers]

                                  -----
  This file is part of Lcrzo.

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

  Lcrzo 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
  Lesser General Public License for more details (http://www.gnu.org).

------------------------------------------------------------------------
*/

/* -- Note about comments and variable names --
   In versions 1.00 up to 2.08, lcrzo was only written in French (my
   mother tongue). Since version 3.00, lcrzo is written in English, but
   most of comments and variable names are still in French.
   In future versions, I'll try to translate everything into English,
   but as you may guess, that's a quite big work...
   So, for the moment, here are some word translation, if you want to
   be able to understand what's going on in the functions :
     afficher - print     ;  ajouter - add         ;  copie - copy
     dernier - last       ;  donnee - data         ;  ecrire - write
     entete - header      ;  envoye - sent         ;  ferme - close
     fichier - file       ;  lire - read           ;  masque - mask 
     nboct - byte number  ;  ouvre, ouvrir - open  ;  paq, paquet - packet
     plage - range        ;  premier - first       ;  recu - received
     reseau - network     ;  retour - return       ;  taille - size
     tunnel - pipe

*/

#include "lcrzo_incl.h"


/*-------------------------------------------------------------*/
#include "sysdep/lcrzo_priv_rand_seed.c"

/*-------------------------------------------------------------*/
int lcrzo_priv_randomvars_init(lcrzo_priv_randomvars *ptr)
{ 
  lcrzo_er(lcrzo_priv_rand_seed(&(ptr->seed)));
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_priv_randomvars_close(lcrzo_priv_randomvars *ptr)
{ 
  ptr->seed=0;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_priv_randomvars_ptr_get(lcrzo_priv_randomvars **pptr)
{ lcrzo_priv_globalvars *ptrglo;

  lcrzo_er(lcrzo_priv_globalvars_ptr_get(&ptrglo));
    
  if (pptr!=NULL)
  { *pptr=&(ptrglo->randomvars);
  }
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_priv_randomvars_copy(lcrzo_priv_randomvars *srcptr,
                               lcrzo_priv_randomvars *dstptr)
{ /* do not copy the seed : it is random */
  return(LCRZO_ERR_OK);
  srcptr=srcptr;
  dstptr=dstptr;
}

/*-------------------------------------------------------------*/
int lcrzo_priv_rand(lcrzo_uint32 *prand);
int lcrzo_priv_rand(lcrzo_uint32 *prand)
{ lcrzo_priv_randomvars *ptr;
  lcrzo_int32 fortest;

  lcrzo_er(lcrzo_priv_randomvars_ptr_get(&ptr));

  /*
   Random generation using linear congruential generators
   T+1 = ( aT ) % m           (may overflow)
       = ( a * (T%q)) - rT/q  (doesn't overflow)
   with :
     a = 16807
     m = 2147483647
     q = (m / a) = 127773
     r = (m % a) = 2836
   */
  fortest = 16807*(ptr->seed%127773) - 2836*(ptr->seed/127773);
  if (fortest > 0)
    ptr->seed = fortest;
  else
    ptr->seed = fortest+2147483647;

  if (prand!=NULL) *prand=ptr->seed;
  
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
/*-------------------------------------------------------------*/
/*-------------------------------------------------------------*/
/*-------------------------------------------------------------*/

/*-------------------------------------------------------------*/
#include "sysdep/lcrzo_init.c"
#include "sysdep/lcrzo_close.c"

/*-------------------------------------------------------------*/
int lcrzo_init_forthreadonly(void)
{
  lcrzo_er(lcrzo_priv_globalvars_init());

  /* do not initialize WinSock*/

  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_close_forthreadonly(void)
{
  /* do not close WinSock*/
  lcrzo_er(lcrzo_priv_globalvars_close());

  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_rand_init(lcrzo_uint32 seed)
{ lcrzo_priv_randomvars *ptr;

  lcrzo_er(lcrzo_priv_randomvars_ptr_get(&ptr));

  if (seed==0)
  { lcrzo_er(lcrzo_priv_rand_seed(&(ptr->seed)));
  }
  else
    ptr->seed=seed;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_uint32_init_rand(lcrzo_uint32 min,
		      lcrzo_uint32 max, 
		      lcrzo_uint32 *prand)
{ lcrzo_uint32 alea;

  if (min>max) return(LCRZO_ERR_PAINFHIGHERSUP);

  /*genere l'alea demande*/
  lcrzo_er(lcrzo_priv_rand(&alea));
  if (prand!=NULL)
  { if ( min==0 && max==0xFFFFFFFFU ) *prand=alea;
    else *prand= min + alea%(max-min+1);
  }

  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_int32_init_rand(lcrzo_int32 min,
		     lcrzo_int32 max, 
		     lcrzo_int32 *pnumber)
{ lcrzo_uint32 alea;

  if (min>max) return(LCRZO_ERR_PAINFHIGHERSUP);

  /*genere l'alea demande*/
  lcrzo_er(lcrzo_priv_rand(&alea));
  if (pnumber!=NULL)
  { if ( min==(-2147483647-1) && max==2147483647 ) *pnumber=alea;  
    else *pnumber= min + alea%(max-min+1);
  }

  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_uint16_init_rand(lcrzo_uint16 min,
		      lcrzo_uint16 max, 
		      lcrzo_uint16 *pnumber)
{ lcrzo_uint32 alea;

  lcrzo_er(lcrzo_uint32_init_rand(min, max, &alea));
  if (pnumber!=NULL) *pnumber=(lcrzo_uint16)alea;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_int16_init_rand(lcrzo_int16 min,
		     lcrzo_int16 max, 
		     lcrzo_int16 *pnumber)
{ lcrzo_int32 alea;

  lcrzo_er(lcrzo_int32_init_rand(min, max, &alea));
  if (pnumber!=NULL) *pnumber=(lcrzo_int16)alea;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_uint8_init_rand(lcrzo_uint8 min,
		     lcrzo_uint8 max, 
		     lcrzo_uint8 *pnumber)
{ lcrzo_uint32 alea;

  lcrzo_er(lcrzo_uint32_init_rand(min, max, &alea));
  if (pnumber!=NULL) *pnumber=(lcrzo_uint8)alea;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_int8_init_rand(lcrzo_int8 min,
		    lcrzo_int8 max, 
		    lcrzo_int8 *pnumber)
{ lcrzo_int32 alea;

  lcrzo_er(lcrzo_int32_init_rand(min, max, &alea));
  if (pnumber!=NULL) *pnumber=(lcrzo_int8)alea;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_bool_init_rand(lcrzo_bool *pnumber)
{ lcrzo_uint32 alea;

  lcrzo_er(lcrzo_uint32_init_rand(0, 0xFFFFFFFFu, &alea));
  if (pnumber!=NULL) *pnumber=(lcrzo_bool)(alea&0x100);
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_priv_global_set_errmsglcrzo_int(lcrzo_conststring bad);
int lcrzo_priv_global_set_errmsglcrzo_int(lcrzo_conststring bad)
{ int ret;
  lcrzo_int16 language;
  lcrzo_string msg;

  lcrzo_er(lcrzo_global_get_language(&language));
  if ( language==LCRZO_GLOBAL_LANG_FR ) 
  { ret=lcrzo_string_initm_text("Le mauvais entier est : ", &msg);
  }
  else
  { ret=lcrzo_string_initm_text("The bad integer is : ", &msg);
  }
  if (ret==LCRZO_ERR_OK)
  { ret=lcrzo_string_appendm_text(bad, &msg);
    if (ret==LCRZO_ERR_OK)
    { ret=lcrzo_priv_global_set_errmsglcrzo(msg);
    }
    lcrzo_string_free(msg);
  }

  return(ret);
}

/*-------------------------------------------------------------*/
int lcrzo_uint32_init_text(lcrzo_conststring str,
			   lcrzo_uint32 *pnumber)
{ unsigned long int number;
  lcrzo_string string;
  char *p;

  lcrzo_er(lcrzo_string_initm_coretext(str, &string));

  /* special case */
  if ( strlen(string)==0 )
  { lcrzo_priv_global_set_errmsglcrzo_int(str);
    lcrzo_string_free(string);
    return(LCRZO_ERR_FMNOTINT);
  }

  /* find number */
  number=strtoul(string, &p, 10);
  if ( *p != '\0' )
  { lcrzo_priv_global_set_errmsglcrzo_int(str);
    lcrzo_string_free(string);
    return(LCRZO_ERR_FMNOTINT);
  }
  lcrzo_string_free(string);

  /* number is too big*/
  if ( number==ULONG_MAX && errno==ERANGE )
  { errno=0;
    return(LCRZO_ERR_PATOOBIG);
  }

  /* on 64 bit */
  if ( sizeof(number)>4 && number>0xFFFFFFFFu )
    return(LCRZO_ERR_PATOOBIG);

  if (pnumber!=NULL) *pnumber=number;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_int32_init_text(lcrzo_conststring str,
			  lcrzo_int32 *pnumber)
{ long int number;
  lcrzo_string string;
  char *p;

  lcrzo_er(lcrzo_string_initm_coretext(str, &string));

  /* special case */
  if ( strlen(string)==0 )
  { lcrzo_priv_global_set_errmsglcrzo_int(str);
    lcrzo_string_free(string);
    return(LCRZO_ERR_FMNOTINT);
  }

  /* find number */
  number=strtol(string, &p, 10);
  if ( *p != '\0' )
  { lcrzo_priv_global_set_errmsglcrzo_int(str);
    lcrzo_string_free(string);
    return(LCRZO_ERR_FMNOTINT);
  }
  lcrzo_string_free(string);

  /* number is too big*/
  if ( errno==ERANGE )
  { errno=0;
    if (number==LONG_MAX) return(LCRZO_ERR_PATOOBIG);
    else if (number==LONG_MIN) return(LCRZO_ERR_PATOOLOW);  
  }

  /* on 64 bit */
  if ( sizeof(number)>4 )
  { if (number>2147483647) return(LCRZO_ERR_PATOOBIG);
    else if (number<-2147483647-1) return(LCRZO_ERR_PATOOLOW);  
  }

  if (pnumber!=NULL) *pnumber=number;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_uint16_init_text(lcrzo_conststring str,
			   lcrzo_uint16 *pnumber)
{ lcrzo_uint32 number;

  lcrzo_er(lcrzo_uint32_init_text(str, &number));

  if (number>0xFFFF) return(LCRZO_ERR_PATOOBIG);

  if (pnumber!=NULL) *pnumber=(lcrzo_uint16)number;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_int16_init_text(lcrzo_conststring str,
			  lcrzo_int16 *pnumber)
{ lcrzo_int32 number;

  lcrzo_er(lcrzo_int32_init_text(str, &number));

  if (number>0x7FFF) return(LCRZO_ERR_PATOOBIG);
  if (number<-0x8000) return(LCRZO_ERR_PATOOLOW);

  if (pnumber!=NULL) *pnumber=(lcrzo_int16)number;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_uint8_init_text(lcrzo_conststring str,
			  lcrzo_uint8 *pnumber)
{ lcrzo_uint32 number;

  lcrzo_er(lcrzo_uint32_init_text(str, &number));

  if (number>0xFF) return(LCRZO_ERR_PATOOBIG);

  if (pnumber!=NULL) *pnumber=(lcrzo_uint8)number;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_int8_init_text(lcrzo_conststring str,
			 lcrzo_int8 *pnumber)
{ lcrzo_int32 number;

  lcrzo_er(lcrzo_int32_init_text(str, &number));

  if (number>0x7F) return(LCRZO_ERR_PATOOBIG);
  if (number<-0x80) return(LCRZO_ERR_PATOOLOW);

  if (pnumber!=NULL) *pnumber=(lcrzo_int8)number;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_bool_init_text(lcrzo_conststring str,
			 lcrzo_bool *pnumber)
{ lcrzo_uint32 number;

  lcrzo_er(lcrzo_uint32_init_text(str, &number));

  if (number>1) return(LCRZO_ERR_PATOOBIG);

  if (pnumber!=NULL) *pnumber=(lcrzo_bool)number;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_uint32_fprint(LCRZOFILE *pf,
			lcrzo_conststring startstring,
			lcrzo_uint32 number,
			lcrzo_conststring fmt,
			lcrzo_conststring endstring)
{ lcrzo_string newfmt;

  /*parameters verification*/
  if (pf==NULL) return(LCRZO_ERR_PANULLPTR);

  if (startstring!=NULL) fprintf(pf, "%s", startstring);
#if LCRZODEF_INT32_ARELONGS == 1
  lcrzo_er(lcrzo_priv_int_fmt_check(fmt, LCRZO_TRUE, &newfmt));
#else
  lcrzo_er(lcrzo_priv_int_fmt_check(fmt, LCRZO_FALSE, &newfmt));
#endif
  fprintf(pf, newfmt, number);
  lcrzo_string_free(newfmt);
  if (endstring!=NULL) fprintf(pf, "%s", endstring);
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_int32_fprint(LCRZOFILE *pf,
		       lcrzo_conststring startstring,
		       lcrzo_int32 number,
		       lcrzo_conststring fmt,	
		       lcrzo_conststring endstring)
{ lcrzo_string newfmt;

  /*parameters verification*/
  if (pf==NULL) return(LCRZO_ERR_PANULLPTR);

  if (startstring!=NULL) fprintf(pf, "%s", startstring);
#if LCRZODEF_INT32_ARELONGS == 1
  lcrzo_er(lcrzo_priv_int_fmt_check(fmt, LCRZO_TRUE, &newfmt));
#else
  lcrzo_er(lcrzo_priv_int_fmt_check(fmt, LCRZO_FALSE, &newfmt));
#endif
  fprintf(pf, newfmt, number);
  lcrzo_string_free(newfmt);
  if (endstring!=NULL) fprintf(pf, "%s", endstring);
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_uint16_fprint(LCRZOFILE *pf,
			lcrzo_conststring startstring,
			lcrzo_uint16 number,
			lcrzo_conststring fmt,
			lcrzo_conststring endstring)
{ lcrzo_string newfmt;

  /*parameters verification*/
  if (pf==NULL) return(LCRZO_ERR_PANULLPTR);

  if (startstring!=NULL) fprintf(pf, "%s", startstring);
  lcrzo_er(lcrzo_priv_int_fmt_check(fmt, LCRZO_FALSE, &newfmt));
  fprintf(pf, newfmt, number);
  lcrzo_string_free(newfmt);
  if (endstring!=NULL) fprintf(pf, "%s", endstring);
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_int16_fprint(LCRZOFILE *pf,
		       lcrzo_conststring startstring,
		       lcrzo_int16 number,
		       lcrzo_conststring fmt,
		       lcrzo_conststring endstring)
{ lcrzo_string newfmt;

  /*parameters verification*/
  if (pf==NULL) return(LCRZO_ERR_PANULLPTR);

  if (startstring!=NULL) fprintf(pf, "%s", startstring);
  lcrzo_er(lcrzo_priv_int_fmt_check(fmt, LCRZO_FALSE, &newfmt));
  fprintf(pf, newfmt, number);
  lcrzo_string_free(newfmt);
  if (endstring!=NULL) fprintf(pf, "%s", endstring);
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_uint8_fprint(LCRZOFILE *pf,
		       lcrzo_conststring startstring,
		       lcrzo_uint8 number,
		       lcrzo_conststring fmt,
		       lcrzo_conststring endstring)
{ lcrzo_string newfmt;

  /*parameters verification*/
  if (pf==NULL) return(LCRZO_ERR_PANULLPTR);

  if (startstring!=NULL) fprintf(pf, "%s", startstring);
  lcrzo_er(lcrzo_priv_int_fmt_check(fmt, LCRZO_FALSE, &newfmt));
  fprintf(pf, newfmt, number);
  lcrzo_string_free(newfmt);
  if (endstring!=NULL) fprintf(pf, "%s", endstring);
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_int8_fprint(LCRZOFILE *pf,
		      lcrzo_conststring startstring,
		      lcrzo_int8 number,
		      lcrzo_conststring fmt,
		      lcrzo_conststring endstring)
{ lcrzo_string newfmt;

  /*parameters verification*/
  if (pf==NULL) return(LCRZO_ERR_PANULLPTR);

  if (startstring!=NULL) fprintf(pf, "%s", startstring);
  lcrzo_er(lcrzo_priv_int_fmt_check(fmt, LCRZO_FALSE, &newfmt));
  fprintf(pf, newfmt, number);
  lcrzo_string_free(newfmt);
  if (endstring!=NULL) fprintf(pf, "%s", endstring);
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_bool_fprint(LCRZOFILE *pf,
		      lcrzo_conststring startstring,
		      lcrzo_bool number,
		      lcrzo_conststring endstring)
{ 
  /*parameters verification*/
  if (pf==NULL) return(LCRZO_ERR_PANULLPTR);
  lcrzo_bool_verifbof(number);

  if (startstring!=NULL) fprintf(pf, "%s", startstring);
  fprintf(pf, "%d", number);
  if (endstring!=NULL) fprintf(pf, "%s", endstring);
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_stream_flush(LCRZOFILE *pstream)
{ lcrzo_file file;

  lcrzo_er(lcrzo_file_init_stream(pstream, &file));
  if ( file.fd == 0 )
  { /* do not check error code */
    lcrzo_file_readm(&file, LCRZO_WAIT_NODELAY, NULL, NULL);
  }
  lcrzo_er(lcrzo_file_flush(&file));
  lcrzo_er(lcrzo_file_close(&file));
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
#include "sysdep/lcrzo_stdin_press.c"

/*-------------------------------------------------------------*/
#include "sysdep/lcrzo_stdin_char.c"

/*-------------------------------------------------------------*/
int lcrzo_uint32_init_stdin(const char *message,
		       lcrzo_uint32 min, lcrzo_uint32 max, 
		       lcrzo_uint32 nbdefaut, lcrzo_uint32 *pnb)
{ char *pptr, prompt;
  lcrzo_string usertext;
  lcrzo_uint32 nb;
  lcrzo_int16 language;

  /*verification des parametres*/
  if (min>max) return(LCRZO_ERR_PAINFHIGHERSUP);
  if (nbdefaut>max) return(LCRZO_ERR_PADEFAULTNOTINRANGE);
  if (nbdefaut<min) return(LCRZO_ERR_PADEFAULTNOTINRANGE);

  /* just for the compiler warning */
  nb=0;

  /*boucle pour demander a l'utilisateur*/
  prompt=':';
  lcrzo_er(lcrzo_global_get_language(&language));
  while(LCRZO_TRUE)
  { if (message!=NULL) if (message[0]!='\0')
    { printf("%s ", message);
      if (language==LCRZO_GLOBAL_LANG_FR)
      { lcrzo_uint32_print("(entre ", min, "%u", "");
        lcrzo_uint32_print(" et ", max, "%u", ")");
	lcrzo_uint32_print("[", nbdefaut, "%u", "]");
      }
      else
      { lcrzo_uint32_print("(between ", min, "%u", "");
        lcrzo_uint32_print(" and ", max, "%u", ")");
	lcrzo_uint32_print("[", nbdefaut, "%u", "]");
      }
      printf("%c ", prompt);
    }
    prompt='>'; /*si erreur, utilise ce prompt*/
    /*saisie du nombre de l'utilisateur*/
    lcrzo_er(lcrzo_priv_stdin(&usertext, NULL));
    /*si rien n'a ete entre, on prend le defaut*/
    if (strlen(usertext)==0)
    { lcrzo_string_free(usertext);
      nb=nbdefaut;
      break;
    }
    /*on convertit la chaine entree en long*/
    nb=strtoul(usertext, &pptr, 10);
    if ( !errno ) /*sinon le nombre est sup a 0xffffffff*/
    { if ( *pptr == '\0' )
      { if ( (nb>=min) && (nb<=max) )
        { lcrzo_string_free(usertext);
          break;
        }
      }
    }
    lcrzo_string_free(usertext);
  }

  if (pnb!=NULL) *pnb=nb;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_int32_init_stdin(const char *message,
		      lcrzo_int32 min, 
		      lcrzo_int32 max, 
		      lcrzo_int32 defaultnumber, 
		      lcrzo_int32 *pnumber)
{ char *pptr, prompt;
  lcrzo_string usertext;
  lcrzo_int32 nb;
  lcrzo_int16 language;

  /*verification des parametres*/
  if (min>max) return(LCRZO_ERR_PAINFHIGHERSUP);
  if (defaultnumber>max) return(LCRZO_ERR_PADEFAULTNOTINRANGE);
  if (defaultnumber<min) return(LCRZO_ERR_PADEFAULTNOTINRANGE);

  /* just for the compiler warning */
  nb=0;

  /*boucle pour demander a l'utilisateur*/
  prompt=':';
  lcrzo_er(lcrzo_global_get_language(&language));
  while(LCRZO_TRUE)
  { if (message!=NULL) if (message[0]!='\0')
    { printf("%s ", message);
      if (language==LCRZO_GLOBAL_LANG_FR)
      { lcrzo_uint32_print("(entre ", min, "%d", "");
        lcrzo_uint32_print(" et ", max, "%d", ")");
	lcrzo_uint32_print("[", defaultnumber, "%d", "]");
      }
      else
      { lcrzo_uint32_print("(between ", min, "%d", "");
        lcrzo_uint32_print(" and ", max, "%d", ")");
	lcrzo_uint32_print("[", defaultnumber, "%d", "]");
      }
      printf("%c ", prompt);
    }
    prompt='>'; /*si erreur, utilise ce prompt*/
    /*saisie du nombre de l'utilisateur*/
    lcrzo_er(lcrzo_priv_stdin(&usertext, NULL));
    /*si rien n'a ete entre, on prend le defaut*/
    if (strlen(usertext)==0)
    { lcrzo_string_free(usertext);
      nb=defaultnumber;
      break;
    }
    /*on convertit la chaine entree en long*/
    nb=strtol(usertext, &pptr, 10);
    if ( !errno ) /*sinon le nombre est sup a 0xffffffff*/
    { if ( *pptr == '\0' )
      { if ( (nb>=min) && (nb<=max) )
        { lcrzo_string_free(usertext);
          break;
        }
      }
    }
    lcrzo_string_free(usertext);
  }

  if (pnumber!=NULL) *pnumber=nb;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_uint16_init_stdin(const char *message,
		       lcrzo_uint16 min, 
		       lcrzo_uint16 max, 
		       lcrzo_uint16 defaultnumber, 
		       lcrzo_uint16 *pnumber)
{ lcrzo_uint32 n;
  lcrzo_er(lcrzo_uint32_init_stdin(message,
			      min, max, defaultnumber, 
			      &n));
  if (pnumber!=NULL) *pnumber=(lcrzo_uint16)n;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_int16_init_stdin(const char *message,
		      lcrzo_int16 min, 
		      lcrzo_int16 max, 
		      lcrzo_int16 defaultnumber, 
		      lcrzo_int16 *pnumber)
{ lcrzo_int32 n;
  lcrzo_er(lcrzo_int32_init_stdin(message,
			     min, max, defaultnumber, 
			     &n));
  if (pnumber!=NULL) *pnumber=(lcrzo_int16)n;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_uint8_init_stdin(const char *message,
		      lcrzo_uint8 min, 
		      lcrzo_uint8 max, 
		      lcrzo_uint8 defaultnumber, 
		      lcrzo_uint8 *pnumber)
{ lcrzo_uint32 n;
  lcrzo_er(lcrzo_uint32_init_stdin(message,
			      min, max, defaultnumber, 
			      &n));
  if (pnumber!=NULL) *pnumber=(lcrzo_uint8)n;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_int8_init_stdin(const char *message,
		     lcrzo_int8 min, 
		     lcrzo_int8 max, 
		     lcrzo_int8 defaultnumber, 
		     lcrzo_int8 *pnumber)
{ lcrzo_int32 n;
  lcrzo_er(lcrzo_int32_init_stdin(message,
			     min, max, defaultnumber, 
			     &n));
  if (pnumber!=NULL) *pnumber=(lcrzo_int8)n;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_bool_init_stdin(const char *message,
			  lcrzo_bool defaultnumber, 
			  lcrzo_bool *pnumber)
{ lcrzo_uint32 n;
  lcrzo_er(lcrzo_uint32_init_stdin(message,
				   0, 1, defaultnumber, 
				   &n));
  if (pnumber!=NULL) *pnumber=(lcrzo_bool)n;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_compilparam_check(void)
{ lcrzo_int16 language;
  union {
    struct { lcrzo_uint8 a; lcrzo_uint8 b; 
             lcrzo_uint8 c; lcrzo_uint8 d; } un;
    lcrzo_uint32 deux;
  } u;

  lcrzo_er(lcrzo_global_get_language(&language));

  /*verification des tailles*/
  if (CHAR_BIT*sizeof(lcrzo_int8)!=8)
  { if (language==LCRZO_GLOBAL_LANG_FR)
      fprintf(stderr, "Erreur : lcrzo_int8 doit avoir une taille de 8 bits\n");
    else
      fprintf(stderr, "Error : lcrzo_int8 must have an 8 bit size\n");
    return(LCRZO_ERR_IEBADSIZEOF);
  }
  if (CHAR_BIT*sizeof(lcrzo_uint8)!=8)
  { if (language==LCRZO_GLOBAL_LANG_FR)
      fprintf(stderr, 
	      "Erreur : lcrzo_uint8 doit avoir une taille de 8 bits\n");
    else
      fprintf(stderr, "Error : lcrzo_uint8 must have an 8 bit size\n");
    return(LCRZO_ERR_IEBADSIZEOF);
  }
  if (CHAR_BIT*sizeof(lcrzo_int16)!=16)
  { if (language==LCRZO_GLOBAL_LANG_FR)
      fprintf(stderr, 
	      "Erreur : lcrzo_int16 doit avoir une taille de 16 bits\n");
    else
      fprintf(stderr, "Error : lcrzo_int16 must have a 16 bit size\n");
    return(LCRZO_ERR_IEBADSIZEOF);
  }
  if (CHAR_BIT*sizeof(lcrzo_uint16)!=16)
  { if (language==LCRZO_GLOBAL_LANG_FR)
      fprintf(stderr, 
	      "Erreur : lcrzo_uint16 doit avoir une taille de 16 bits\n");
    else
      fprintf(stderr, "Error : lcrzo_uint16 must have a 16 bit size\n");
    return(LCRZO_ERR_IEBADSIZEOF);
  }
  if (CHAR_BIT*sizeof(lcrzo_int32)!=32)
  { if (language==LCRZO_GLOBAL_LANG_FR)
      fprintf(stderr, 
	      "Erreur : lcrzo_int32 doit avoir une taille de 32 bits\n");
    else
      fprintf(stderr, "Error : lcrzo_int32 must have a 32 bit size\n");
    return(LCRZO_ERR_IEBADSIZEOF);
  }
  if (CHAR_BIT*sizeof(lcrzo_uint32)!=32)
  { if (language==LCRZO_GLOBAL_LANG_FR)
      fprintf(stderr, 
	      "Erreur : lcrzo_uint32 doit avoir une taille de 32 bits\n");
    else
      fprintf(stderr, "Error : lcrzo_uint32 must have a 32 bit size\n");
    return(LCRZO_ERR_IEBADSIZEOF);
  }

  /* check packing */
  if ( sizeof(lcrzo_hdrpeth)!=14 )
  { if (language==LCRZO_GLOBAL_LANG_FR)
      fprintf(stderr, 
	      "Erreur : lcrzo_hdrpeth doit avoir une taille de 14 octets\n");
    else
      fprintf(stderr, "Error : lcrzo_hdrpeth must have a 14 bytes size\n");
    return(LCRZO_ERR_IEBADSIZEOF);
  }
  if ( sizeof(lcrzo_hdrpip)!=20 )
  { if (language==LCRZO_GLOBAL_LANG_FR)
      fprintf(stderr, 
	      "Erreur : lcrzo_hdrpip doit avoir une taille de 20 octets\n");
    else
      fprintf(stderr, "Error : lcrzo_hdrpip must have a 20 bytes size\n");
    return(LCRZO_ERR_IEBADSIZEOF);
  }
  if ( sizeof(lcrzo_hdrpudp)!=8 )
  { if (language==LCRZO_GLOBAL_LANG_FR)
      fprintf(stderr, 
	      "Erreur : lcrzo_hdrpudp doit avoir une taille de 8 octets\n");
    else
      fprintf(stderr, "Error : lcrzo_hdrpudp must have an 8 bytes size\n");
    return(LCRZO_ERR_IEBADSIZEOF);
  }
  if ( sizeof(lcrzo_hdrptcp)!=20 )
  { if (language==LCRZO_GLOBAL_LANG_FR)
      fprintf(stderr, 
	      "Erreur : lcrzo_hdrptcp doit avoir une taille de 20 octets\n");
    else
      fprintf(stderr, "Error : lcrzo_hdrptcp must have a 20 bytes size\n");
    return(LCRZO_ERR_IEBADSIZEOF);
  }
  if ( sizeof(lcrzo_hdrpicmp)!=4 )
  { if (language==LCRZO_GLOBAL_LANG_FR)
      fprintf(stderr, 
	      "Erreur : lcrzo_hdrpicmp doit avoir une taille de 4 octets\n");
    else
      fprintf(stderr, "Error : lcrzo_hdrpicmp must have an 4 bytes size\n");
    return(LCRZO_ERR_IEBADSIZEOF);
  }
  if ( sizeof(lcrzo_hdrparp)!=28 )
  { if (language==LCRZO_GLOBAL_LANG_FR)
      fprintf(stderr, 
	      "Erreur : lcrzo_hdrparp doit avoir une taille de 28 octets\n");
    else
      fprintf(stderr, "Error : lcrzo_hdrparp must have a 28 bytes size\n");
    return(LCRZO_ERR_IEBADSIZEOF);
  }

  /*verification de l'endianness*/
  u.deux=0x12345678;
  if (LCRZODEF_ENDIANLITTLE)
  { if ( u.un.a!=0x78 || u.un.b!=0x56 || u.un.c!=0x34 || u.un.d!=0x12 )
    { if (language==LCRZO_GLOBAL_LANG_FR)
        fprintf(stderr, "Erreur : la machine n'est pas little endian\n");
      else
        fprintf(stderr, "Error : this computer is not a little endian\n");
      return(LCRZO_ERR_IEBADENDIAN);
    }
  }
  else if (LCRZODEF_ENDIANBIG)
  { if ( u.un.a!=0x12 || u.un.b!=0x34 || u.un.c!=0x56 || u.un.d!=0x78 )
    { if (language==LCRZO_GLOBAL_LANG_FR)
        fprintf(stderr, "Erreur : la machine n'est pas big endian\n");
      else
        fprintf(stderr, "Error : this computer is not a big endian\n");
      return(LCRZO_ERR_IEBADENDIAN);
    }
  }
  else
  { return(lcrzo_ie("lcrzo_compilparam_check", 
		    "ni LCRZODEF_ENDIANLITTLE, ni LCRZODEF_ENDIANBIG",
		    "nor LCRZODEF_ENDIANLITTLE, nor LCRZODEF_ENDIANBIG"));
  }
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_compilparam_get(lcrzo_conststring wantedparameter,
			  lcrzo_string *pparametervalue)
{
  if (!strcmp(wantedparameter, "LANG"))
  { return(lcrzo_string_initm_int(LCRZODEF_LANG, "%d", pparametervalue));
  }
  if (!strcmp(wantedparameter, "SYS"))
  { return(lcrzo_string_initm_text(LCRZODEF_SYS, pparametervalue));
  }
  if (!strcmp(wantedparameter, "SYSTEM"))
  { return(lcrzo_string_initm_text(LCRZODEF_SYSTEM, pparametervalue));
  }
  if (!strcmp(wantedparameter, "SYSVER"))
  { return(lcrzo_string_initm_text(LCRZODEF_SYSVER, pparametervalue));
  }
  if (!strcmp(wantedparameter, "SYSTEMVERS"))
  { return(lcrzo_string_initm_text(LCRZODEF_SYSTEMVERS, pparametervalue));
  }
  if (!strcmp(wantedparameter, "SYSTEMARCH"))
  { return(lcrzo_string_initm_text(LCRZODEF_SYSTEMARCH, pparametervalue));
  }
  if (!strcmp(wantedparameter, "ENDIANLITTLE"))
  { return(lcrzo_string_initm_int(LCRZODEF_ENDIANLITTLE, "%d", 
				  pparametervalue));
  }
  if (!strcmp(wantedparameter, "ENDIANBIG"))
  { return(lcrzo_string_initm_int(LCRZODEF_ENDIANBIG, "%d", 
				  pparametervalue));
  }
  if (!strcmp(wantedparameter, "VERSION"))
  { return(lcrzo_string_initm_text(LCRZODEF_VERSION, pparametervalue));
  }
  if (!strcmp(wantedparameter, "VERSIONMAJOR"))
  { return(lcrzo_string_initm_int(LCRZODEF_VERSIONMAJOR, "%d", 
				  pparametervalue));
  }
  if (!strcmp(wantedparameter, "VERSIONMINOR"))
  { return(lcrzo_string_initm_int(LCRZODEF_VERSIONMINOR, "%d", 
				  pparametervalue));
  }
  if (!strcmp(wantedparameter, "LIBPCAPINSTALLED"))
  { return(lcrzo_string_initm_int(LCRZODEF_LIBPCAPINSTALLED, "%d", 
				  pparametervalue));
  }
  if (!strcmp(wantedparameter, "LIBPCAPFROMREDHAT"))
  { return(lcrzo_string_initm_int(LCRZODEF_LIBPCAPFROMREDHAT, "%d", 
				  pparametervalue));
  }
  if (!strcmp(wantedparameter, "LIBNETINSTALLED"))
  { return(lcrzo_string_initm_int(LCRZODEF_LIBNETINSTALLED, "%d", 
				  pparametervalue));
  }
  if (!strcmp(wantedparameter, "PROGCC"))
  { return(lcrzo_string_initm_text(LCRZODEF_PROGCC, pparametervalue));
  }
  if (!strcmp(wantedparameter, "PROGAR"))
  { return(lcrzo_string_initm_text(LCRZODEF_PROGAR, pparametervalue));
  }
  if (!strcmp(wantedparameter, "PROGRANLIB"))
  { return(lcrzo_string_initm_text(LCRZODEF_PROGRANLIB, pparametervalue));
  }
  if (!strcmp(wantedparameter, "INSTINCLUDE"))
  { return(lcrzo_string_initm_text(LCRZODEF_INSTINCLUDE, pparametervalue));
  }
  if (!strcmp(wantedparameter, "INSTLIB"))
  { return(lcrzo_string_initm_text(LCRZODEF_INSTLIB, pparametervalue));
  }
  if (!strcmp(wantedparameter, "INSTBIN"))
  { return(lcrzo_string_initm_text(LCRZODEF_INSTBIN, pparametervalue));
  }
  if (!strcmp(wantedparameter, "INSTMAN1"))
  { return(lcrzo_string_initm_text(LCRZODEF_INSTMAN1, pparametervalue));
  }
  if (!strcmp(wantedparameter, "INSTMAN3"))
  { return(lcrzo_string_initm_text(LCRZODEF_INSTMAN3, pparametervalue));
  }
  if (!strcmp(wantedparameter, "INSTUSERGROUP"))
  { return(lcrzo_string_initm_text(LCRZODEF_INSTUSERGROUP, pparametervalue));
  }
  if (!strcmp(wantedparameter, "HAVEFONC_ETHER_NTOHOST"))
  { return(lcrzo_string_initm_int(LCRZODEF_HAVEFONC_ETHER_NTOHOST, "%d", 
				  pparametervalue));
  }
  if (!strcmp(wantedparameter, "HAVEFONC_ETHER_HOSTTON"))
  { return(lcrzo_string_initm_int(LCRZODEF_HAVEFONC_ETHER_HOSTTON, "%d", 
				  pparametervalue));
  }
  if (!strcmp(wantedparameter, "HAVEFONC_HSTRERROR"))
  { return(lcrzo_string_initm_int(LCRZODEF_HAVEFONC_HSTRERROR, "%d", 
				  pparametervalue));
  }
  if (!strcmp(wantedparameter, "HAVEFONC_SNPRINTF"))
  { return(lcrzo_string_initm_int(LCRZODEF_HAVEFONC_SNPRINTF, "%d", 
				  pparametervalue));
  }
  if (!strcmp(wantedparameter, "HAVEFONC_IOCTL_BIOCSHDRCMPLT"))
  { return(lcrzo_string_initm_int(LCRZODEF_HAVEFONC_IOCTL_BIOCSHDRCMPLT, "%d", 
				  pparametervalue));
  }
  if (!strcmp(wantedparameter, "HAVEFONC_PCAP_FREECODE"))
  { return(lcrzo_string_initm_int(LCRZODEF_HAVEFONC_PCAP_FREECODE, "%d", 
				  pparametervalue));
  }
  if (!strcmp(wantedparameter, "HAVEFONC_PCAP_OPENDEAD"))
  { return(lcrzo_string_initm_int(LCRZODEF_HAVEFONC_PCAP_OPENDEAD, "%d", 
				  pparametervalue));
  }
  if (!strcmp(wantedparameter, "HAVEFONC_POLL"))
  { return(lcrzo_string_initm_int(LCRZODEF_HAVEFONC_POLL, "%d", 
				  pparametervalue));
  }
  if (!strcmp(wantedparameter, "HAVEINCL_NETPACKET_PACKET"))
  { return(lcrzo_string_initm_int(LCRZODEF_HAVEINCL_NETPACKET_PACKET, "%d", 
				  pparametervalue));
  }
  if (!strcmp(wantedparameter, "HAVEINCL_SYS_BUFMOD"))
  { return(lcrzo_string_initm_int(LCRZODEF_HAVEINCL_SYS_BUFMOD, "%d", 
				  pparametervalue));
  }

  return(LCRZO_ERR_PAUNKNOWNTYPE);
}

/*-------------------------------------------------------------*/
#include "sysdep/lcrzo_compilparam_fprint.c"

/*-------------------------------------------------------------*/
#include "sysdep/lcrzo_windows_getsystemversion.c"
