#include "bbs.h"

boolean userlogin(confrecordtyp *confrecord, const char *uname)
{
  int n, k;
  boolean ok = FALSE;
  char c, path[PATH_MAX+1], username[S_STRLEN+1];
  FILE *fp;

  if (buildhelppath(path,"login",sprachensuffix[confrecord->userrecord.lang],
                    confrecord) == NULL) {
    errormsg(E_LOGFILE|E_USER,confrecord,"bbs","userlogin",
		 "path to login too long");
    return(-1);
  }
  if ((fp=fopen(path,"r")) == NULL) {
    errormsg(E_LOGFILE|E_USER,confrecord,"bbs","userlogin",
             "cannot fopen %s: %m", path);
    return(-1);
  }
  while (fgets(path,PATH_MAX,fp) != NULL) {
    fputs(path,stdout);
  }
  fclose(fp);  
  
  n = 1;
  do {
    if (*uname == '\0' || n > 1) {
      printf("Login:");
      k = 0;
      do {
	c = getchar();
	username[k++] = c;
      } while (c != NEWLINE_KEY && c != RETURN_KEY && k < S_STRLEN);
      username[k-1] = '\0';
    }
    else {
      strmaxcpy(username,uname,S_STRLEN);
    }
    if (*username == '\0')  strcpy(username,NOUSER);
    
    if (getuserrecord(&(confrecord->userrecord),username,confrecord)) {
      if (*(confrecord->userrecord.passwd) == '\0') {
	ok = TRUE;
      }
      else {
        if (strncmp(confrecord->userrecord.passwd,
	    CRYPTFUNC(getpass("Password:"),confrecord->userrecord.passwd),
	    PASSCRYPTED_LEN)==0) {
          ok = TRUE;
	}
      }
    }
    if (! ok) {
      bbslog(LOG_FILE,confrecord,"Login try %i: %s\n",n,username);
    }
    n++;
  } while (n<=confrecord->maxversuche && !ok);
  if (!ok) {
    return FALSE;
  }
  else {
    return TRUE;
  }
}


int usergreeting(confrecordtyp *confrecord)
{
  int n;
  char buf[PATH_MAX+1], termstr[S_STRLEN+1], c;
  FILE *fp;
  
  if (buildhelppath(buf,"greeting",sprachensuffix[confrecord->userrecord.lang],confrecord) == NULL) {
    errormsg(E_LOGFILE|E_USER,confrecord,"bbs","usergreeting",
		 "path to greeting too long");
    return(-1);
  }
  if ((fp=fopen(buf,"r")) == NULL) {
    errormsg(E_LOGFILE|E_USER,confrecord,"bbs","usergreeting",
             "cannot fopen %s: %m", buf);
    return(-1);
  }
  while (fgets(buf,PATH_MAX,fp) != NULL) {
    fputs(buf,stdout);
  }
  fclose(fp);
  printf(msg("usergreeting",0,confrecord->lang),confrecord->userrecord.term);
  do {
    n = 0;
    do {
      c = getchar();
      termstr[n++] = c;
    } while (c != NEWLINE_KEY && c != RETURN_KEY && n < S_STRLEN);
    termstr[n-1] = '\0';
    if (n > 1 && ! termexists(termstr)) {
      printf(msg("usergreeting",1,confrecord->lang),termstr);
    }
  } while (n > 1 && ! termexists(termstr));
  if (n > 1) {
    if (strlen(termstr)+100 > PATH_MAX) {
      errormsg(E_LOGFILE|E_USER,confrecord,"bbs","usergreeting",
	       "line too long");
      return(-1);
    }
    sprintf(buf,"%s %d %d",termstr, confrecord->userrecord.lines,
            confrecord->userrecord.columns);
    do_term(buf,&(confrecord->userrecord),confrecord);
  }

  return(n);
}


int writetouser(confrecordtyp *confrecord, const char *fmt, ...)
{
  va_list ap;
  char str[STRLEN+1];
  
  va_start(ap, fmt);
  vsprintf(str,fmt,ap);
  va_end(ap);
  if (confrecord->curses_on) {
    windowtext(str," BBS: ",0,confrecord);
  }
  else {
    printf("%s",str);
  }
  return 0;
}


int readfromuser(char str[], const int mlen, const boolean echo)
{
  int k = 0;
  int n, p;
  char c;

  do {
    refresh();
    c = getch();
    if (c == ESCAPE_KEY) {
      str[0] = '\0';
      return(0);
    }
    if (k>0 && (c==BACKSPACE_KEY || c==DELETE_KEY)) {
      getyx(stdscr,n,p);
      mvdelch(n,--p);
      k--;
    }
    else {
      if (echo) {
        addch(c);
      }
      else {
        addch(' ');
      }
      str[k++] = c;
    }
  } while (c!=RETURN_KEY && c!=NEWLINE_KEY && k<mlen);
  if (c==RETURN_KEY || c==NEWLINE_KEY)  k--;    
  str[k] = '\0';
  return(k);
}


#ifndef NO_TV_USEC
char waitonkeypress(boolean minwait)
{
  char c;
  double t;

  if (minwait) {
    t = microtime();
    do {
      c = getch();
    } while(microtime()-t < KEYTIME);
  }
  else {
    c = getch();
  }
  return(c);
}
#else
char waitonkeypress(boolean minwait)
{
  return getch();
}
#endif


char getkeyonprompt(const char *prompt, char *keyset, const boolean maptoupper,
                    const boolean autozmodem, confrecordtyp *confrecord)
{
  int errs = 0;
  char *cp, key, bell=BELL_KEY;
#ifndef NO_TV_USEC
  boolean zmodem;
#endif

  move(LINES-1,0);
  clrtoeol();
  standout();
  addstr(prompt);
  standend();
  do {
    refresh();
#ifndef NO_TV_USEC
    if (autozmodem && confrecord->userrecord.autozmodem &&
        confrecord->userrecord.protokoll == ZMODEMPROTO) {
      key = autoz_getch_c(&zmodem,TRUE);
      if (zmodem) {
        bbslog(LOG_FILE,confrecord,"AutoZmodem");
        return(AUTOZDETECTED);
      }
    }
    else {
      key =  waitonkeypress(TRUE);
    }
#else
    key =  waitonkeypress(TRUE);
#endif
    if (maptoupper && islower(key)) key = toupper(key);
    if (*keyset != '\0') {
      for (cp=keyset; key!=*cp && *cp!='\0'; cp++) ;
    }
    if (errs > 2) {
      move(LINES-1,0);
      clrtoeol();
      standout();
      addstr(msg("getkeyonprompt",0,confrecord->userrecord.lang));
      standend();
      errs = 0;
    }
    if (*keyset != '\0' && key != *cp && key != ESCAPE_KEY) {
      if (key == RETURN_KEY || key == NEWLINE_KEY)  touchwin(stdscr);
      writen(2,(void *)&bell,(SIZE_T)sizeof(char));
      errs++;
    }
  } while (*keyset != '\0' && key != *cp && key != ESCAPE_KEY);

  return key;
}


int pagerstep(const char key)
{
  switch (key) {
  case BACKSPACE_KEY:
  case DELETE_KEY:
    return(-2);
    break;
  case SPACE_KEY:
    return(2);
    break;
  }
  return(0);
}


int pagerquit(const char key)
{
  switch (key) {
  case QUIT_KEY:
  case QUIT_L_KEY:
    return(1);
    break;
  case ESCAPE_KEY:
    return(-1);
    break;
  }
  return(0);
}

#ifndef NO_TV_USEC
char autoz_getch_c(boolean *zmodem, const boolean scan)
{
  double t1, t2;
  static char zmsig[] = "**\030B00";
  static char *pcp, *cp, c;
  static boolean playback = FALSE;
  
  if (playback) {
    if (pcp != cp) {
      return(*pcp++);
    }
    else {
      playback = FALSE;
      return(c);
    }
  }
  
  if (scan) {
    *zmodem = FALSE;
    t2 = microtime();
    do {
      t1 = t2;
      c = getch();
      t2 = microtime();
    } while ((c != *zmsig) && (t2-t1<KEYTIME));
    if (c != *zmsig) return c;
    cp = zmsig;
    cp++;
    c = getch();
    while (c == *cp) {
      if (*++cp == '\0') break;
      c = getch();
    }
    if (*cp == '\0') {
      *zmodem = TRUE;
      return(c);
    }
    else {
      playback = TRUE;
      pcp = zmsig;
      return(*pcp++);
    }
  }

  return getch();
}
#endif
