chiark / gitweb /
REORG Delete everything that's not innduct or build system or changed for innduct
[innduct.git] / frontends / ovdb_server.c
diff --git a/frontends/ovdb_server.c b/frontends/ovdb_server.c
deleted file mode 100644 (file)
index af6d7cb..0000000
+++ /dev/null
@@ -1,744 +0,0 @@
-/*
- * ovdb_server.c
- * ovdb read server
- */
-
-#include "config.h"
-#include "clibrary.h"
-#include "portable/mmap.h"
-#include "portable/time.h"
-#include "portable/setproctitle.h"
-#include "portable/socket.h"
-#include "portable/wait.h"
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
-#include <syslog.h>
-
-#ifdef HAVE_UNIX_DOMAIN_SOCKETS
-# include <sys/un.h>
-#endif
-
-#include "inn/innconf.h"
-#include "inn/messages.h"
-#include "libinn.h"
-#include "paths.h"
-#include "storage.h"
-#include "ov.h"
-
-#include "../storage/ovdb/ovdb.h"
-#include "../storage/ovdb/ovdb-private.h"
-
-#ifndef USE_BERKELEY_DB
-
-int
-main(int argc UNUSED, char **argv UNUSED)
-{
-    die("BerkeleyDB support not compiled");
-}
-
-#else /* USE_BERKELEY_DB */
-
-
-#define SELECT_TIMEOUT 15
-
-
-/* This will work unless user sets a larger clienttimeout
-   in readers.conf */
-#define CLIENT_TIMEOUT (innconf->clienttimeout + 60)
-/*#define CLIENT_TIMEOUT 3600*/
-
-
-static int listensock;
-
-#define MODE_READ   0
-#define MODE_WRITE  1
-#define MODE_CLOSED 2
-#define STATE_READCMD 0
-#define STATE_READGROUP 1
-struct reader {
-    int fd;
-    int mode;
-    int state;
-    int buflen;
-    int bufpos;
-    void *buf;
-    time_t lastactive;
-    void *currentsearch;
-};
-
-static struct reader *readertab;
-static int readertablen;
-static int numreaders;
-static time_t now;
-static pid_t parent;
-
-struct child {
-    pid_t pid;
-    int num;
-    time_t started;
-};
-static struct child *children;
-#define wholistens (children[ovdb_conf.numrsprocs].num)
-
-static int signalled = 0;
-static void
-sigfunc(int sig UNUSED)
-{
-    signalled = 1;
-}
-
-static int updated = 0;
-static void
-childsig(int sig UNUSED)
-{
-    updated = 1;
-}
-
-static void
-parentsig(int sig UNUSED)
-{
-    int i, which, smallest;
-    if(wholistens < 0) {
-       which = smallest = -1;
-       for(i = 0; i < ovdb_conf.numrsprocs; i++) {
-           if(children[i].pid == -1)
-               continue;
-           if(!ovdb_conf.maxrsconn || children[i].num <= ovdb_conf.maxrsconn) {
-               if(smallest == -1 || children[i].num < smallest) {
-                   smallest = children[i].num;
-                   which = i;
-               }
-           }
-       }
-       if(which != -1) {
-           wholistens = which;
-           kill(children[which].pid, SIGUSR1);
-       } else {
-           wholistens = -2;
-       }
-       updated = 1;
-    }
-}
-
-static int putpid(const char *path)
-{
-    char buf[30];
-    int fd = open(path, O_WRONLY|O_TRUNC|O_CREAT, 0664);
-    if(fd == -1) {
-        syswarn("cannot open %s", path);
-        return -1;
-    }
-    snprintf(buf, sizeof(buf), "%d\n", getpid());
-    if(write(fd, buf, strlen(buf)) < 0) {
-        syswarn("cannot write to %s", path);
-        close(fd);
-        return -1;
-    }
-    close(fd);
-    return 0;
-}
-
-static void
-do_groupstats(struct reader *r)
-{
-    struct rs_groupstats *reply;
-    char *group = (char *)(r->buf) + sizeof(struct rs_cmd);
-    reply = xmalloc(sizeof(struct rs_groupstats));
-
-    /*syslog(LOG_DEBUG, "OVDB: rs: do_groupstats '%s'", group);*/
-    if(ovdb_groupstats(group, &reply->lo, &reply->hi, &reply->count, &reply->flag)) {
-       reply->status = CMD_GROUPSTATS;
-       reply->aliaslen = 0;
-    } else {
-       reply->status = CMD_GROUPSTATS | RPLY_ERROR;
-    }
-    free(r->buf);
-    r->buf = reply;
-    r->buflen = sizeof(struct rs_groupstats);
-    r->bufpos = 0;
-    r->mode = MODE_WRITE;
-}
-
-static void
-do_opensrch(struct reader *r)
-{
-    struct rs_cmd *cmd = r->buf;
-    struct rs_opensrch *reply;
-    char *group = (char *)(r->buf) + sizeof(struct rs_cmd);
-    reply = xmalloc(sizeof(struct rs_opensrch));
-
-    /*syslog(LOG_DEBUG, "OVDB: rs: do_opensrch '%s' %d %d", group, cmd->artlo, cmd->arthi);*/
-
-    if(r->currentsearch != NULL) {
-       /* can only open one search at a time */
-       reply->status = CMD_OPENSRCH | RPLY_ERROR;
-    } else {
-       reply->handle = ovdb_opensearch(group, cmd->artlo, cmd->arthi);
-       if(reply->handle == NULL) {
-           reply->status = CMD_OPENSRCH | RPLY_ERROR;
-       } else {
-           reply->status = CMD_OPENSRCH;
-       }
-       r->currentsearch = reply->handle;
-    }
-    free(r->buf);
-    r->buf = reply;
-    r->buflen = sizeof(struct rs_opensrch);
-    r->bufpos = 0;
-    r->mode = MODE_WRITE;
-}
-
-static void
-do_srch(struct reader *r)
-{
-    struct rs_cmd *cmd = r->buf;
-    struct rs_srch *reply;
-    ARTNUM artnum;
-    TOKEN token;
-    time_t arrived;
-    int len;
-    char *data;
-
-    if(ovdb_search(cmd->handle, &artnum, &data, &len, &token, &arrived)) {
-       reply = xmalloc(sizeof(struct rs_srch) + len);
-       reply->status = CMD_SRCH;
-       reply->artnum = artnum;
-       reply->token = token;
-       reply->arrived = arrived;
-       reply->len = len;
-       memcpy((char *)reply + sizeof(struct rs_srch), data, len);
-       r->buflen = sizeof(struct rs_srch) + len;
-    } else {
-       reply = xmalloc(sizeof(struct rs_srch));
-       reply->status = CMD_SRCH | RPLY_ERROR;
-       r->buflen = sizeof(struct rs_srch);
-    }
-    free(r->buf);
-    r->buf = reply;
-    r->bufpos = 0;
-    r->mode = MODE_WRITE;
-}
-
-static void
-do_closesrch(struct reader *r)
-{
-    struct rs_cmd *cmd = r->buf;
-
-    ovdb_closesearch(cmd->handle);
-    free(r->buf);
-    r->buf = NULL;
-    r->bufpos = r->buflen = 0;
-    r->mode = MODE_READ;
-    r->currentsearch = NULL;
-}
-
-static void
-do_artinfo(struct reader *r)
-{
-    struct rs_cmd *cmd = r->buf;
-    struct rs_artinfo *reply;
-    char *group = (char *)(r->buf) + sizeof(struct rs_cmd);
-    TOKEN token;
-
-    /*syslog(LOG_DEBUG, "OVDB: rs: do_artinfo: '%s' %d", group, cmd->artlo);*/
-    if(ovdb_getartinfo(group, cmd->artlo, &token)) {
-       reply = xmalloc(sizeof(struct rs_artinfo));
-       reply->status = CMD_ARTINFO;
-       reply->token = token;
-       r->buflen = sizeof(struct rs_artinfo);
-    } else {
-       reply = xmalloc(sizeof(struct rs_artinfo));
-       reply->status = CMD_ARTINFO | RPLY_ERROR;
-       r->buflen = sizeof(struct rs_artinfo);
-    }
-    free(r->buf);
-    r->buf = reply;
-    r->bufpos = 0;
-    r->mode = MODE_WRITE;
-}
-
-
-static int
-process_cmd(struct reader *r)
-{
-    struct rs_cmd *cmd = r->buf;
-
-    if(r->state == STATE_READCMD) {
-       switch(cmd->what) {
-       case CMD_GROUPSTATS:
-       case CMD_OPENSRCH:
-       case CMD_ARTINFO:
-           r->state = STATE_READGROUP;
-           if(cmd->grouplen == 0) {
-               /* shoudn't happen... */
-               r->mode = MODE_CLOSED;
-               close(r->fd);
-               free(r->buf);
-               r->buf = NULL;
-               return 0;
-           }
-           r->buflen += cmd->grouplen;
-            r->buf = xrealloc(r->buf, r->buflen);
-           return 1;
-       }
-    }
-
-    switch(cmd->what) {
-    case CMD_GROUPSTATS:
-       ((char *)r->buf)[r->buflen - 1] = 0;    /* make sure group is null-terminated */
-       do_groupstats(r);
-       break;
-    case CMD_OPENSRCH:
-       ((char *)r->buf)[r->buflen - 1] = 0;
-       do_opensrch(r);
-       break;
-    case CMD_SRCH:
-       do_srch(r);
-       break;
-    case CMD_CLOSESRCH:
-       do_closesrch(r);
-       break;
-    case CMD_ARTINFO:
-       ((char *)r->buf)[r->buflen - 1] = 0;
-       do_artinfo(r);
-       break;
-    default:
-       r->mode = MODE_CLOSED;
-       close(r->fd);
-       free(r->buf);
-       r->buf = NULL;
-       break;
-    }
-
-    return 0;
-}
-
-static void
-handle_read(struct reader *r)
-{
-    int n;
-    r->lastactive = now;
-
-    if(r->buf == NULL) {
-       r->state = STATE_READCMD;
-       r->buf = xmalloc(sizeof(struct rs_cmd));
-       r->buflen = sizeof(struct rs_cmd);
-       r->bufpos = 0;
-    }
-again:
-    n = read(r->fd, (char *)(r->buf) + r->bufpos, r->buflen - r->bufpos);
-    if(n <= 0) {
-       if(n < 0 && (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK))
-           return;
-       r->mode = MODE_CLOSED;
-       close(r->fd);
-       free(r->buf);
-       r->buf = NULL;
-    }
-    r->bufpos += n;
-
-    if(r->bufpos >= r->buflen)
-       if(process_cmd(r))
-           goto again;
-}
-
-static void
-handle_write(struct reader *r)
-{
-    int n;
-    r->lastactive = now;
-
-    if(r->buf == NULL) /* shouldn't happen */
-       return;
-
-    n = write(r->fd, (char *)(r->buf) + r->bufpos, r->buflen - r->bufpos);
-    if(n <= 0) {
-       if(n < 0 && (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK))
-           return;
-       r->mode = MODE_CLOSED;
-       close(r->fd);
-       free(r->buf);
-       r->buf = NULL;
-    }
-    r->bufpos += n;
-
-    if(r->bufpos >= r->buflen) {
-       free(r->buf);
-       r->buf = NULL;
-       r->bufpos = r->buflen = 0;
-       r->mode = MODE_READ;
-    }
-}
-
-static void
-newclient(int fd)
-{
-    struct reader *r;
-    int i;
-
-    nonblocking(fd, 1);
-
-    if(numreaders >= readertablen) {
-       readertablen += 50;
-        readertab = xrealloc(readertab, readertablen * sizeof(struct reader));
-        for(i = numreaders; i < readertablen; i++) {
-           readertab[i].mode = MODE_CLOSED;
-           readertab[i].buf = NULL;
-       }
-    }
-
-    r = &(readertab[numreaders]);
-    numreaders++;
-
-    r->fd = fd;
-    r->mode = MODE_WRITE;
-    r->buflen = sizeof(OVDB_SERVER_BANNER);
-    r->bufpos = 0;
-    r->buf = xstrdup(OVDB_SERVER_BANNER);
-    r->lastactive = now;
-    r->currentsearch = NULL;
-
-    handle_write(r);
-}
-
-static void
-delclient(int which)
-{
-    int i;
-    struct reader *r = &(readertab[which]);
-
-    if(r->mode != MODE_CLOSED)
-       close(r->fd);
-
-    if(r->buf != NULL) {
-       free(r->buf);
-    }
-    if(r->currentsearch != NULL) {
-       ovdb_closesearch(r->currentsearch);
-       r->currentsearch = NULL;
-    }
-
-    /* numreaders will get decremented by the calling function */
-    for(i = which; i < numreaders-1; i++)
-       readertab[i] = readertab[i+1];
-
-    readertab[i].mode = MODE_CLOSED;
-    readertab[i].buf = NULL;
-}
-
-static pid_t
-serverproc(int me)
-{
-    fd_set rdset, wrset;
-    int i, ret, count, lastfd, lastnumreaders;
-    socklen_t salen;
-    struct sockaddr_in sa;
-    struct timeval tv;
-    pid_t pid;
-
-    pid = fork();
-    if (pid != 0)
-       return pid;
-
-    if (!ovdb_open(OV_READ|OVDB_SERVER))
-        die("cannot open overview");
-    xsignal_norestart(SIGINT, sigfunc);
-    xsignal_norestart(SIGTERM, sigfunc);
-    xsignal_norestart(SIGHUP, sigfunc);
-    xsignal_norestart(SIGUSR1, childsig);
-    xsignal(SIGPIPE, SIG_IGN);
-
-    numreaders = lastnumreaders = 0;
-    if(ovdb_conf.maxrsconn) {
-       readertablen = ovdb_conf.maxrsconn;
-    } else {
-       readertablen = 50;
-    }
-    readertab = xmalloc(readertablen * sizeof(struct reader));
-    for(i = 0; i < readertablen; i++) {
-       readertab[i].mode = MODE_CLOSED;
-       readertab[i].buf = NULL;
-    }
-
-    setproctitle("0 clients");
-
-    /* main loop */
-    while(!signalled) {
-       FD_ZERO(&rdset);
-       FD_ZERO(&wrset);
-       lastfd = 0;
-       if(wholistens == me) {
-           if(!ovdb_conf.maxrsconn || numreaders < ovdb_conf.maxrsconn) {
-               FD_SET(listensock, &rdset);
-               lastfd = listensock;
-                setproctitle("%d client%s *", numreaders,
-                             numreaders == 1 ? "" : "s");
-           } else {
-               wholistens = -1;
-               kill(parent, SIGUSR1);
-           }
-        }
-
-       for(i = 0; i < numreaders; i++) {
-           switch(readertab[i].mode) {
-           case MODE_READ:
-               FD_SET(readertab[i].fd, &rdset);
-               break;
-           case MODE_WRITE:
-               FD_SET(readertab[i].fd, &wrset);
-               break;
-           default:
-               continue;
-           }
-           if(readertab[i].fd > lastfd)
-               lastfd = readertab[i].fd;
-       }
-       tv.tv_usec = 0;
-       tv.tv_sec = SELECT_TIMEOUT;
-       count = select(lastfd + 1, &rdset, &wrset, NULL, &tv);
-
-       if(signalled)
-           break;
-       if(count <= 0)
-           continue;
-
-       now = time(NULL);
-
-       if(FD_ISSET(listensock, &rdset)) {
-           if(!ovdb_conf.maxrsconn || numreaders < ovdb_conf.maxrsconn) {
-               salen = sizeof(sa);
-               ret = accept(listensock, (struct sockaddr *)&sa, &salen);
-               if(ret >= 0) {
-                   newclient(ret);
-                   wholistens = -1;
-                   children[me].num = numreaders;
-                   kill(parent, SIGUSR1);
-               }
-           }
-       }
-
-       for(i = 0; i < numreaders; i++) {
-           switch(readertab[i].mode) {
-           case MODE_READ:
-               if(FD_ISSET(readertab[i].fd, &rdset))
-                   handle_read(&(readertab[i]));
-               break;
-           case MODE_WRITE:
-               if(FD_ISSET(readertab[i].fd, &wrset))
-                   handle_write(&(readertab[i]));
-               break;
-           }
-       }
-
-       for(i = 0; i < numreaders; i++) {
-           if(readertab[i].mode == MODE_CLOSED
-                 || readertab[i].lastactive + CLIENT_TIMEOUT < now) {
-               delclient(i);
-               numreaders--;
-               i--;
-           }
-       }
-       if(children[me].num != numreaders) {
-           children[me].num = numreaders;
-           kill(parent, SIGUSR1);
-        }
-       if(numreaders != lastnumreaders) {
-           lastnumreaders = numreaders;
-            setproctitle("%d client%s", numreaders,
-                         numreaders == 1 ? "" : "s");
-       }
-    }
-
-    ovdb_close();
-    exit(0);
-}
-
-static int
-reap(void)
-{
-    int i, cs;
-    pid_t c;
-
-    while((c = waitpid(-1, &cs, WNOHANG)) > 0) {
-       for(i = 0; i < ovdb_conf.numrsprocs; i++) {
-           if(c == children[i].pid) {
-               if(children[i].started + 30 > time(NULL))
-                   return 1;
-
-               children[i].num = 0;
-
-               if(wholistens == i)
-                   wholistens = -1;
-
-               if((children[i].pid = serverproc(i)) == -1)
-                   return 1;
-
-               children[i].started = time(NULL);
-               break;
-           }
-       }
-    }
-    if(wholistens == -1)
-       parentsig(SIGUSR1);
-    return 0;
-}
-
-#ifndef MAP_ANON
-#ifdef MAP_ANONYMOUS
-#define MAP_ANON MAP_ANONYMOUS
-#endif
-#endif
-
-static void *
-sharemem(size_t len)
-{
-#ifdef MAP_ANON
-    return mmap(0, len, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0);
-#else
-    int fd = open("/dev/zero", O_RDWR, 0);
-    char *ptr = mmap(0, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
-    close(fd);
-    return ptr;
-#endif
-}
-
-int
-main(int argc, char *argv[])
-{
-    int i, ret;
-    socklen_t salen;
-    char *path, *pidfile;
-#ifdef HAVE_UNIX_DOMAIN_SOCKETS
-    struct sockaddr_un sa;
-#else
-    struct sockaddr_in sa;
-#endif
-    struct timeval tv;
-    fd_set rdset;
-
-    setproctitle_init(argc, argv);
-
-    openlog("ovdb_server", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
-    message_program_name = "ovdb_server";
-
-    if(argc != 2 || strcmp(argv[1], SPACES))
-        die("should be started by ovdb_init");
-    message_handlers_warn(1, message_log_syslog_err);
-    message_handlers_die(1, message_log_syslog_err);
-
-    if (!innconf_read(NULL))
-       exit(1);
-
-    if(strcmp(innconf->ovmethod, "ovdb"))
-        die("ovmethod not set to ovdb in inn.conf");
-
-    read_ovdb_conf();
-
-#ifdef HAVE_UNIX_DOMAIN_SOCKETS
-    listensock = socket(AF_UNIX, SOCK_STREAM, 0);
-#else
-    listensock = socket(AF_INET, SOCK_STREAM, 0);
-#endif
-    if(listensock < 0)
-        sysdie("cannot create socket");
-
-    nonblocking(listensock, 1);
-
-#ifdef HAVE_UNIX_DOMAIN_SOCKETS
-    sa.sun_family = AF_UNIX;
-    path = concatpath(innconf->pathrun, OVDB_SERVER_SOCKET);
-    strlcpy(sa.sun_path, path, sizeof(sa.sun_path));
-    unlink(sa.sun_path);
-    free(path);
-    ret = bind(listensock, (struct sockaddr *)&sa, sizeof sa);
-#else
-    sa.sin_family = AF_INET;
-    sa.sin_port = htons(OVDB_SERVER_PORT);
-    sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-    
-    ret = bind(listensock, (struct sockaddr *)&sa, sizeof sa);
-
-    if(ret != 0 && errno == EADDRNOTAVAIL) {
-       sa.sin_family = AF_INET;
-       sa.sin_port = htons(OVDB_SERVER_PORT);
-       sa.sin_addr.s_addr = INADDR_ANY;
-       ret = bind(listensock, (struct sockaddr *)&sa, sizeof sa);
-    }
-#endif
-
-    if(ret != 0)
-        sysdie("cannot bind socket");
-    if(listen(listensock, MAXLISTEN) < 0)
-        sysdie("cannot listen on socket");
-
-    pidfile = concatpath(innconf->pathrun, OVDB_SERVER_PIDFILE);
-    if(putpid(pidfile))
-        exit(1);
-
-    xsignal_norestart(SIGINT, sigfunc);
-    xsignal_norestart(SIGTERM, sigfunc);
-    xsignal_norestart(SIGHUP, sigfunc);
-
-    xsignal_norestart(SIGUSR1, parentsig);
-    xsignal_norestart(SIGCHLD, childsig);
-    parent = getpid();
-
-    children = sharemem(sizeof(struct child) * (ovdb_conf.numrsprocs+1));
-
-    if(children == NULL)
-        sysdie("cannot mmap shared memory");
-    for(i = 0; i < ovdb_conf.numrsprocs+1; i++) {
-       children[i].pid = -1;
-       children[i].num = 0;
-    }
-
-    for(i = 0; i < ovdb_conf.numrsprocs; i++) {
-       if((children[i].pid = serverproc(i)) == -1) {
-           for(i--; i >= 0; i--)
-               kill(children[i].pid, SIGTERM);
-           exit(1);
-       }
-       children[i].started = time(NULL);
-       sleep(1);
-    }
-
-    while(!signalled) {
-       if(reap())
-           break;
-
-       if(wholistens == -2) {
-           FD_ZERO(&rdset);
-           FD_SET(listensock, &rdset);
-           tv.tv_usec = 0;
-           tv.tv_sec = SELECT_TIMEOUT;
-           ret = select(listensock+1, &rdset, NULL, NULL, &tv);
-
-           if(ret == 1 && wholistens == -2) {
-               salen = sizeof(sa);
-               ret = accept(listensock, (struct sockaddr *)&sa, &salen);
-               if(ret >= 0)
-                  close(ret);
-           }
-       } else {
-           pause();
-       }
-    }
-
-    for(i = 0; i < ovdb_conf.numrsprocs; i++)
-       if(children[i].pid != -1)
-           kill(children[i].pid, SIGTERM);
-
-    while(wait(&ret) > 0)
-       ;
-
-    unlink(pidfile);
-
-    exit(0);
-}
-
-
-#endif /* USE_BERKELEY_DB */