1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
/* $Id: overchan.c 6135 2003-01-19 01:15:40Z rra $
**
** Parse input to add to news overview database.
*/
#include "config.h"
#include "clibrary.h"
#include "portable/time.h"
#include <errno.h>
#include <syslog.h>
#include <sys/stat.h>
#include "inn/innconf.h"
#include "inn/messages.h"
#include "inn/qio.h"
#include "libinn.h"
#include "ov.h"
#include "paths.h"
unsigned int NumArts;
unsigned int StartTime;
unsigned int TotOvTime;
/*
* Timer function (lifted from innd/timer.c).
* This function is designed to report the number of milliseconds since
* the first invocation. I wanted better resolution than time(), and
* something easier to work with than gettimeofday()'s struct timeval's.
*/
static unsigned gettime(void)
{
static int init = 0;
static struct timeval start_tv;
struct timeval tv;
if (! init) {
gettimeofday(&start_tv, NULL);
init++;
}
gettimeofday(&tv, NULL);
return((tv.tv_sec - start_tv.tv_sec) * 1000 + (tv.tv_usec - start_tv.tv_usec) / 1000);
}
/*
** Process the input. Data comes from innd in the form:
** @token@ data
*/
#define TEXT_TOKEN_LEN (2*sizeof(TOKEN)+2)
static void ProcessIncoming(QIOSTATE *qp)
{
char *Data;
char *p;
TOKEN token;
unsigned int starttime, endtime;
time_t Time, Expires;
for ( ; ; ) {
/* Read the first line of data. */
if ((Data = QIOread(qp)) == NULL) {
if (QIOtoolong(qp)) {
warn("line too long");
continue;
}
break;
}
if (Data[0] != '@' || strlen(Data) < TEXT_TOKEN_LEN+2
|| Data[TEXT_TOKEN_LEN-1] != '@' || Data[TEXT_TOKEN_LEN] != ' ') {
warn("malformed token %s", Data);
continue;
}
token = TextToToken(Data);
Data += TEXT_TOKEN_LEN+1; /* skip over token and space */
for (p = Data; !ISWHITE(*p) ;p++) ;
*p++ = '\0';
Time = (time_t)atol(Data);
for (Data = p; !ISWHITE(*p) ;p++) ;
*p++ = '\0';
Expires = (time_t)atol(Data);
Data = p;
NumArts++;
starttime = gettime();
if (OVadd(token, Data, strlen(Data), Time, Expires) == OVADDFAILED)
syswarn("cannot write overview %s", Data);
endtime = gettime();
TotOvTime += endtime - starttime;
}
QIOclose(qp);
}
int main(int ac, char *av[])
{
QIOSTATE *qp;
unsigned int now;
/* First thing, set up our identity. */
message_program_name = "overchan";
/* Log warnings and fatal errors to syslog unless we were given command
line arguments, since we're probably running under innd. */
if (ac == 0) {
openlog("overchan", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
message_handlers_warn(1, message_log_syslog_err);
message_handlers_die(1, message_log_syslog_err);
message_handlers_notice(1, message_log_syslog_notice);
}
/* Set defaults. */
if (!innconf_read(NULL))
exit(1);
umask(NEWSUMASK);
if (innconf->enableoverview && !innconf->useoverchan)
warn("overchan is running while innd is creating overview data (you"
" can ignore this message if you are running makehistory -F)");
ac -= 1;
av += 1;
if (!OVopen(OV_WRITE))
die("cannot open overview");
StartTime = gettime();
if (ac == 0)
ProcessIncoming(QIOfdopen(STDIN_FILENO));
else {
for ( ; *av; av++)
if (strcmp(*av, "-") == 0)
ProcessIncoming(QIOfdopen(STDIN_FILENO));
else if ((qp = QIOopen(*av)) == NULL)
syswarn("cannot open %s", *av);
else
ProcessIncoming(qp);
}
OVclose();
now = gettime();
notice("timings %u arts %u of %u ms", NumArts, TotOvTime, now - StartTime);
exit(0);
/* NOTREACHED */
}
|