#include "bbs.h"

#define ERRORDEST(a,b) (a&b)

void errormsg(const int destmask, confrecordtyp *confrecord,
              const char *hpname, const char *upname, const char *fmt, ...)
  /*
  Sendet eine Fehlermeldung an die angegebenen Addressen. Moeglich sind:
  E_SYSLOG (syslog), E_LOGFILE (Logfile), E_CONSOLE (DEV_CONSOLE),
  E_USER (user)
  Die Fehlermeldung 'fmt' ist dabei ein Format wie fuer 'printf', zusaetzlich
  wird '%m' durch den aktuellen errno-String ersetzt.
  Datum, PID werden ergaenzt, die Strings 'hpname' und 'upname' werden
  eingefuegt, sofern sie nicht Nullzeiger sind, und sollten den Programmnamen
  und dessen aktuelles Unterprogramm bezeichnen.
  
  errno wird erhalten
  
  E_FILE darf vom Daemon nicht benutzt werden.
  */
{
  va_list ap;
  int saved_errno, logc, len;
  char c, *cp1, *cp2, str[PATH_MAX+1], fmt_cpy[PATH_MAX+1], upstr[S_STRLEN+1],
       hpstr[S_STRLEN+1];
  
  saved_errno = errno;

  va_start(ap, fmt);
  for (cp1=fmt_cpy; (c=*fmt)!='\0'; ++fmt) {
    if (c=='%' && fmt[1]=='m') {
      ++fmt;
      for (cp2=strerror(saved_errno); (*cp1=*cp2++)!='\0'; ++cp1);
    }
    else {
      *cp1++ = c;
    }
  }
  *cp1 = '\0';
  vsprintf(str,fmt_cpy,ap);
  len = strlen(str) - 1;
  if (str[len++]!='\n') {
    str[len++] = '\n';
    str[len] = '\0';
  }
  va_end(ap);
  if (upname != NULL) {
    sprintf(upstr,"(%s): ",upname);
  }
  else {
    upstr[0] = '\0';
  }
  if (hpname != NULL) {
    strcpy(hpstr,hpname);
  }
  else {
    hpstr[0] = '\0';
  }
  if (ERRORDEST(E_USER,destmask)) {
#ifdef BBSD_SOURCE
      fprintf(stderr,"%s",str);
#else
    if (confrecord->curses_on) {
      windowtext(str," ERROR: ",0,confrecord);
    }
    else {
      fprintf(stderr,"%s",str);
    }
#endif
  }
  strprepend(str,upstr);
  if (ERRORDEST(E_SYSLOG,destmask)) {
    syslog(LOG_ERR,str);
  }
  strprepend(str,hpstr);
  if (ERRORDEST(E_LOGFILE,destmask)) {
    if (bbsdaemon) {
    syslog(LOG_ERR,"bbsd(errormsg): E_LOGFILE darf vom Daemon nicht verwendet werden");
    exit(-1);
  }

    bbslog(LOG_FILE,confrecord,str);
  }
  if (ERRORDEST(E_CONSOLE,destmask)) {
    if ((logc=open(DEV_CONSOLE,O_WRONLY))<0) {
      bgerror("errormsg",DEV_CONSOLE);
      perror(DEV_CONSOLE);
    }
    else {
      sprintf(fmt_cpy,"%.15s %s%s[%ld]: %s",gettime()+4*sizeof(char),
              hpstr,upstr,(long)getpid(),str);
      writen(logc,(void *)fmt_cpy,strlen(fmt_cpy));
      close(logc);
    }
  }
  
  errno = saved_errno;
  return;
}


void bgerror(const char *upname, const char *fmt, ...)
  /*
  Sendet 'fmt' zum syslog. Der String 'upname' muss global definiert sein
  und soll den Namen des aufrufenden Untrprogramms enthalten.
  
  errno wird erhalten
  */
{
  va_list ap;
  int saved_errno;
  char str[PATH_MAX+1];

  saved_errno = errno;
  va_start(ap, fmt);
  if (upname != NULL) {
    sprintf(str,"(%s): %s",upname,fmt);
    vsyslog(LOG_ERR,str,ap);
  }
  else {
    vsyslog(LOG_ERR,fmt,ap);
  }
  va_end(ap);

  errno = saved_errno;
  return;
}
