/*
* DREADERD/MAIN.C - diablo newsreader
*
* This is the startup for the dreaderd daemon.
*
* The diablo newsreader requires one or remote diablo news boxes to
* obtain articles from, but keeps track of article assignments to groups
* and overview information locally.
*
* Operationally, dreaderd runs as a standalone multi-forking,
* multi-threaded daemon. It forks X resolvers and Y readers. Each
* reader can support N connections (NxY total connections) and maintains
* its own links to one or more news servers (diablo, INN, whatever).
* Overview information is utilized and articles are accessed by
* message-id.
*
* The diablo newsreader is also able to accept header-only feeds from
* one or more diablo servers via 'mode headfeed'. Processing of these
* feeds is not multi-threaded, only processing of newsreader functions is
* multithreaded. The diablo newsreader does not operate with a dhistory
* file. If taking a feed from several sources you must also run the
* diablo server on the same box and use that to feed the dreaderd system,
* though the diablo server need not store any articles itself.
*
* (c)Copyright 1998, Matthew Dillon, All Rights Reserved. Refer to
* the COPYRIGHT file in the base directory of this distribution
* for specific rights granted.
*/
#include "defs.h"
Prototype void RTStatusOpen(const char *fileName, int slotBase, int numSlots);
Prototype void RTStatusBase(int slot, const char *ctl, ...);
Prototype void RTStatusUpdate(int slot, const char *ctl, ...);
#define RTLINESIZE 140
int RTSFd = -1;
int RTSlotBase;
int RTBaseLen;
void
RTStatusOpen(const char *fileName, int slotBase, int numSlots)
{
/*
* Each process needs its own copy of RTSFd so the seek
* position is not shared.
*/
if (RTSFd >= 0) {
close(RTSFd);
RTSFd = open(fileName, O_RDWR, 0644);
} else {
RTSFd = open(fileName, O_RDWR|O_CREAT|O_TRUNC, 0644);
}
RTSlotBase = slotBase;
if (RTSFd >= 0) {
int i;
lseek(RTSFd, slotBase * RTLINESIZE, 0);
for (i = 0; i < numSlots; ++i) {
RTStatusBase(i, "");
}
}
}
void
RTStatusBase(int slot, const char *ctl, ...)
{
va_list va;
char buf[RTLINESIZE];
if (slot >= 0 && RTSFd >= 0) {
sprintf(buf, "%05d %04d %010u ", (int)getpid(), slot + RTSlotBase, time(NULL));
/*
* WARNING! snprintf() may not understand full printf semantics,
* see lib/snprintf.c
*/
va_start(va, ctl);
vsnprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ctl, va);
va_end(va);
RTBaseLen = strlen(buf);
if (RTBaseLen > RTLINESIZE/2)
RTBaseLen = RTLINESIZE/2;
memset(buf + RTBaseLen, ' ', RTLINESIZE - RTBaseLen);
buf[RTLINESIZE-1] = '\n';
lseek(RTSFd, (RTSlotBase + slot) * RTLINESIZE, 0);
write(RTSFd, buf, RTLINESIZE);
}
}
void
RTStatusUpdate(int slot, const char *ctl, ...)
{
int ulineSize = RTLINESIZE - RTBaseLen;
va_list va;
char buf[RTLINESIZE];
if (slot >= 0 && RTSFd >= 0) {
int len;
buf[0] = ' ';
va_start(va, ctl);
vsnprintf(buf + 1, ulineSize - 1, ctl, va);
va_end(va);
len = strlen(buf);
memset(buf + len, ' ', ulineSize - len);
buf[ulineSize-1] = '\n';
lseek(RTSFd, (RTSlotBase + slot) * RTLINESIZE + RTBaseLen, 0);
write(RTSFd, buf, ulineSize);
}
}
syntax highlighted by Code2HTML, v. 0.9.1