/* This file is part of Lcrzo.
*/

/*-------------------------------------------------------------*/
int lcrzo_priv_passwd(lcrzo_string *puserstring,
		      lcrzo_int32 *puserstringsize)
{ char *ptr;
  lcrzo_int32 fgetstep, ptrallocsize, userstringsize;
  int c;
#if defined LCRZODEF_SYSTEM_Unix
  struct termios tios;
#elif defined LCRZODEF_SYSTEM_Windows
#else
 #error "Unknown value for LCRZODEF_SYSTEM"
#endif

  fgetstep=3;
  ptrallocsize=fgetstep;
  lcrzo_er(lcrzo_string_alloc(ptrallocsize, &ptr));  

  lcrzo_er(lcrzo_stream_flush(stdin));
  userstringsize=0;

#if defined LCRZODEF_SYSTEM_Unix
  if (tcgetattr(STDIN_FILENO, &tios)) return(LCRZO_ERR_FUTCGETATTR);
  tios.c_lflag &= ~ECHO;
  if (tcsetattr(STDIN_FILENO, TCSANOW,  &tios)) return(LCRZO_ERR_FUTCSETATTR);
  c=getc(stdin);  
  while ( c!=0x0D && c!=0x0A && c!=0x00 && c!=EOF )
  { ptr[userstringsize]=(char)c;
    userstringsize++;
    c=getc(stdin);
    if (userstringsize==ptrallocsize)
    { ptrallocsize+=fgetstep;
      lcrzo_er(lcrzo_string_realloc(ptrallocsize, &ptr));  
    }
  }
  tios.c_lflag |= ECHO;
  if (tcsetattr(STDIN_FILENO, TCSANOW,  &tios)) return(LCRZO_ERR_FUTCSETATTR);
#elif defined LCRZODEF_SYSTEM_Windows
  c=_getch();  
  while ( c!=0x0D && c!=0x0A && c!=0x00 && c!=EOF && c!=0xE0 )
  { ptr[userstringsize]=(char)c;
    userstringsize++;
    c=_getch();
    if (userstringsize==ptrallocsize)
    { ptrallocsize+=fgetstep;
      lcrzo_er(lcrzo_string_realloc(ptrallocsize, &ptr));  
    }
  }
  lcrzo_err_purge();
#else
 #error "Unknown value for LCRZODEF_SYSTEM"
#endif
  
  ptr[userstringsize]='\0';
  puts("");

  if (puserstring!=NULL)
  { *puserstring=ptr;
  }
  else
  { lcrzo_string_free(ptr);
  }
  if (puserstringsize!=NULL) *puserstringsize=userstringsize;

  return(LCRZO_ERR_OK);
}

