ftp.nice.ch/pub/next/unix/communication/ft_bbs.1.0.s.tar.gz#/ft_bbs-1.0/bbsdstuff-com.c

This is bbsdstuff-com.c in view mode; [Download] [Up]

/* $Id: bbsdstuff-com.c,v 1.1 1995/12/19 19:30:47 eilts Exp eilts $ */
#include "bbs.h"

int bbslog(const int level, const confrecordtyp *confrecord,
           const char *fmt, ...)
  /*
  Stellt einen String zusammen vom Format:
  PID <pid>, <datum>: msg\n
  und sendet ihn an den Daemon zum Eintragen in das Logfile,
  dabei kann fuer 'fmt' ein Format wie fuer 'printf' eingesetzt werden,
  zusaetzlich wird '%m' durch den aktuellen errno-String ersetzt.
  Ist level==LOG_CONSOLE, so wird der Text zusaetzlich auf DEV_CONSOLE
  ausgegeben,
  ist level==LOG_NEVER, so wird nichts ausgegeben
  
  errno wird erhalten
  
  bbslog darf nicht vom Daemon (bbsd) aufgerufen werden
  */
{
  va_list ap;
  SIZE_T msglen;
  int saved_errno, n=0, logs, logc;
  char c, *cp1, *cp2, str[MSG_MAX+1], fmt_cpy[MSG_MAX+1];

  if (level==LOG_NEVER)  return 0;

  saved_errno = errno;
  
  if (bbsdaemon) {
    bgerror("bbslog","bbslog cannot be used from daemon");
    return(-2);
  }
  if ((logs=connect2bbsd(confrecord))<0) {
    errormsg(E_SYSLOG|E_USER|E_CONSOLE,confrecord,"bbs","bbslog",
             "connection to daemon failed");
    exit(1);
  }
  sprintf(str,"#%2d\n",DO_LOG);
  sendn(logs,(void *)str,(SIZE_T)BEFSTRLEN,0);
  
  sprintf(str,"%.15s[%ld]: ",gettime()+4*sizeof(char),(long)getpid());

  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';
  
  for (cp1=str; *cp1!='\0'; ++cp1);
  vsprintf(cp1,fmt_cpy,ap);
  va_end(ap);
  msglen = strlen(str) - 1;
  if (str[msglen++]!='\n') {
    str[msglen++] = '\n';
    str[msglen] = '\0';
  }
  sendn(logs,(void *)&msglen,(SIZE_T)sizeof(SIZE_T),0);
  sendn(logs,(void *)str,msglen,0);
  recvn(logs,(void *)&n,(SIZE_T)sizeof(int),0);
  unconnect2bbsd(logs,confrecord);
  if (n<0) {
    errormsg(E_SYSLOG|E_USER|E_CONSOLE,confrecord,"bbs","bbslog",
             "command bbslog wrongly executed by bbsd");
    n = -1;
  }
  
  if (level==LOG_CONSOLE) {
    if ((logc=open(DEV_CONSOLE,O_WRONLY))<0) {
      errormsg(E_SYSLOG|E_USER,confrecord,"bbs","bbslog","open %s: %m",
               DEV_CONSOLE);
      n += -2;
    }
    else {
      writen(logc,(void *)str,msglen);
      close(logc);
    }
  }
  
  errno = saved_errno;
  return n;
}


int bbslogn(const int level, const confrecordtyp *confrecord,
            const char *fmt, ...)
  /*
  Stellt einen String zusammen vom Format:
  PID <pid>, <datum>: msg\n
  und sendet ihn an den Daemon zum Eintragen in das Logfile,
  dabei kann fuer 'fmt' ein Format wie fuer 'printf' eingesetzt werden,
  zusaetzlich wird '%m' durch den aktuellen errno-String ersetzt.
  Ist level==LOG_CONSOLE, so wird der Text zusaetzlich auf DEV_CONSOLE
  ausgegeben,
  ist level==LOG_NEVER, so wird nichts ausgegeben
  
  errno wird erhalten
  
  bbslogn darf nicht vom Daemon (bbsd) aufgerufen werden
  */
{
  va_list ap;
  SIZE_T msglen;
  SSIZE_T maxmsglen;
  int saved_errno, n=0, logs, logc;
  char c, *cp1, *cp2, *str, *fmt_cpy;

  if (level==LOG_NEVER)  return 0;

  saved_errno = errno;
  
  if (bbsdaemon) {
    bgerror("bbslogn","bbslogn cannot be used from daemon");
    return(-2);
  }

  va_start(ap, fmt);
  if ((maxmsglen=vfstrlen(fmt,ap)) < 0) {
    bgerror("bbslogn","cannot guess memory");
    return(-3);    
  }
  maxmsglen += 100;
  if ((str=(char *)malloc((SIZE_T)maxmsglen)) == NULL ||
      (fmt_cpy=(char *)malloc((SIZE_T)maxmsglen)) == NULL) {
    bgerror("bbslogn","cannot allocate memory");
    return(-3);
  }

  if ((logs=connect2bbsd(confrecord))<0) {
    errormsg(E_SYSLOG|E_USER|E_CONSOLE,confrecord,"bbs","bbslogn",
             "connection to daemon failed");
    exit(1);
  }

  sprintf(str,"#%2d\n",DO_LOG);
  sendn(logs,(void *)str,(SIZE_T)BEFSTRLEN,0);
  
  sprintf(str,"%.15s[%ld]: ",gettime()+4*sizeof(char),(long)getpid());

  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';
  
  for (cp1=str; *cp1!='\0'; ++cp1);
  vsprintf(cp1,fmt_cpy,ap);
  va_end(ap);
  msglen = strlen(str) - 1;
  if (str[msglen++]!='\n') {
    str[msglen++] = '\n';
    str[msglen] = '\0';
  }
  sendn(logs,(void *)&msglen,(SIZE_T)sizeof(SIZE_T),0);
  sendn(logs,(void *)str,msglen,0);
  recvn(logs,(void *)&n,(SIZE_T)sizeof(int),0);
  unconnect2bbsd(logs,confrecord);
  if (n<0) {
    errormsg(E_SYSLOG|E_USER|E_CONSOLE,confrecord,"bbs","bbslog",
             "command bbslogn wrongly executed by bbsd");
    n = -1;
  }
  
  if (level==LOG_CONSOLE) {
    if ((logc=open(DEV_CONSOLE,O_WRONLY))<0) {
      errormsg(E_SYSLOG|E_USER,confrecord,"bbs","bbslogn","open %s: %m",
               DEV_CONSOLE);
      n += -2;
    }
    else {
      writen(logc,(void *)str,msglen);
      close(logc);
    }
  }
  free((void *)str);
  free((void *)fmt_cpy);
  
  errno = saved_errno;
  return n;
}


int getsessions(sessionrecordtyp sessionrecords[], const int maxn,
                const confrecordtyp *confrecord)
  /*
  Erfragt vom Daemon alle sessionrecords der laufenden bbs und gibt sie
  in sessionrecords zurueck, der Rueckgabewert von getsessions ist die
  Anzahl der sessions.
  maxn begrenzt die maximale Anzahl der sessions
  */
{
  int sockd, n=-1;
  char bstr[BEFSTRLEN+1];
  sessionrecordtyp sr;
  
  if ((sockd=connect2bbsd(confrecord))<0) {
    errormsg(E_SYSLOG|E_USER|E_CONSOLE,confrecord,"bbs","getsessions",
             "connection to daemon failed");
    exit(1);
  }
  sprintf(bstr,"#%2d\n",DO_GETSESSIONS);
  sendn(sockd,(void *)bstr,(SIZE_T)BEFSTRLEN,0);
  if (maxn>0) {
    do {
      n++;
      recvn(sockd,(void *)&(sessionrecords[n]),(SIZE_T)sizeof(sessionrecordtyp),0);
    } while (sessionrecords[n].pid!=0 && n<maxn-1);
    sr.pid = sessionrecords[n].pid;
  }
  else {
    sr.pid = 1;
  }
  while (sr.pid!=0) {
    recvn(sockd,(void *)&sr,(SIZE_T)sizeof(sessionrecordtyp),0);
  }
  recvn(sockd,(void *)&n,(SIZE_T)sizeof(int),0);
  unconnect2bbsd(sockd,confrecord);
  if (n<0) {
    errormsg(E_SYSLOG|E_USER|E_CONSOLE,confrecord,"bbs","getsessions",
             "command getsessions wrongly executed by bbsd");
    return -1;
  }
  return n;
}


int connect2bbsd(const confrecordtyp *confrecord)
  /*
  Stellt eine Verbindung zum Daemon (bbsd) her, der Deskriptor wird als
  Rueckgabewert geliefert.
  Die meisten Signale werden blockiert, wird in unconnect2bbsd restauriert
  */
{
  int sockd, len, k, n;
  static PID_T pid = 0;
  struct sockaddr_un saun;
  SIGSET_T sigset;
  
  if (pid == 0)  pid = getpid();
  if (blocksigsetstatus == SIGMASK_UNSET) {
    sigfillset(&sigset);
    sigprocmask(SIG_SETMASK,&sigset,&old_blocksigset);
    blocksigsetstatus = SIGMASK_SET;
  }
  else {
    errormsg(E_SYSLOG|E_USER|E_CONSOLE,confrecord,"bbs","connect2bbsd",
             "WARNING: old_blocksigset is in use");
  }
  if ((sockd=socket(AF_UNIX,SOCK_STREAM,0))<0) {
    errormsg(E_SYSLOG|E_USER|E_CONSOLE,confrecord,"bbs","connect2bbsd",
             "socket %s: %m",confrecord->sockpath);
    return -1;
  }
  BZERO(&saun, sizeof(saun));
  saun.sun_family = AF_UNIX;
  strcpy(saun.sun_path,confrecord->sockpath);
  len = SUN_LEN(&saun);
#ifdef SCM_RIGHTS
  saun.sun_len = len;
#endif
  k = 0;
  while ((n=connect(sockd,(struct sockaddr *)&saun,len))<0 && k<SOCKCONTRIES) {
    k++;
    sleep(1);
  }
  if (n<0) {
    errormsg(E_SYSLOG|E_USER|E_CONSOLE,confrecord,"bbs","connect2bbsd",
             "connect %s: %m",confrecord->sockpath);
    return n;
  }
  sendn(sockd,(void *)&pid,(SIZE_T)sizeof(PID_T),0);
  n = strlen(confrecord->authkey) + 1;
  sendn(sockd,(void *)&n,(SIZE_T)sizeof(int),0);
  sendn(sockd,(void *)confrecord->authkey,(SIZE_T)n,0);
  k = recvn(sockd,(void *)&n,(SIZE_T)sizeof(int),0);
  if (k<0 || n<0) {
    errormsg(E_SYSLOG|E_USER|E_CONSOLE,confrecord,"bbs","connect2bbsd",
             "wrong authorisation");
    return n;
  }
  return sockd;
}


int unconnect2bbsd(const int sockd, const confrecordtyp *confrecord)
{
  if (blocksigsetstatus == SIGMASK_SET) {
    blocksigsetstatus = SIGMASK_UNSET;
    sigprocmask(SIG_SETMASK,&old_blocksigset,NULL);
  }
  else {
    errormsg(E_SYSLOG|E_USER|E_CONSOLE,confrecord,"bbs","unconnect2bbsd",
             "WARNING: old_blocksigset is not set (nothing done)");
  }
  return close(sockd);
}


PID_T testdaemon(const char *bbsdpidpath, const confrecordtyp *confrecord)
  /*
  Prueft die Existenz eines Daemons
  Rueckgabewerte: 0, wenn kein Pidfile vom Daemon existiert
                 -1, wenn Pidfile existiert, aber nicht lesbar ist
		 -2, wenn Pidfile existiert, Muell drinsteht
		 -3, wenn Pidfile existiert, aber kill -1 liefert
		  pid des Daemons sonst
  */
{
  PID_T pid;
  int fd;
  SSIZE_T ss;
  char str[S_STRLEN+1];
  
  if (access(bbsdpidpath,F_OK) == 0) {
    if ((fd=open(bbsdpidpath,O_RDONLY)) < 0) {
      errormsg(E_SYSLOG|E_USER|E_CONSOLE,confrecord,"bbs","testdaemon",
               "open %s: %m",bbsdpidpath);
      return(-1);
    }
    if ((ss=readn(fd,(void *)str,(SIZE_T)S_STRLEN)) < 0) {
      errormsg(E_SYSLOG|E_USER|E_CONSOLE,confrecord,"bbs","testdaemon",
               "read %s: %m",bbsdpidpath);
      return(-1);
    }
    close(fd);
    if (ss == (SSIZE_T)S_STRLEN) {
      return(-2);
    }
    pid = (PID_T)atoi(str);
    if (kill(pid,0) < 0)  {
      if (errno != EPERM) {
        pid = -3;
      }
    }
  }
  else {
    pid = 0;
  }
  return pid;
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.