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
|
/*
* LIB/SEQ.C - Sequence space control
*
* The sequence space is based on directories split into 10 minute
* segments. The main diablo process updates the sequence space by
* scanning /news/spool/news and creates a new directory every 10
* minutes.
*/
#include "defs.h"
Prototype void InitSeqSpace(void);
Prototype uint32 ExpireToSeq(uint16 exp);
Prototype void LoadSlotDir(time_t t);
typedef struct SeqSpace {
uint32 ss_Beg;
uint32 ss_End;
} SeqSpace;
SeqSpace *SSeq;
uint32 LSTime;
void
InitSeqSpace(void)
{
#if USE_SPAM_SHM
int sid = shmget(IPC_PRIVATE, sizeof(SeqSpace), SHM_R|SHM_W);
struct shmid_ds ds;
if (sid < 0) {
syslog(LOG_CRIT, "sysv shared memory alloc failed");
exit(1);
}
SSeq = (SeqSpace *)shmat(sid, NULL, SHM_R|SHM_W);
if (shmctl(sid, IPC_STAT, &ds) < 0 || shmctl(sid, IPC_RMID, &ds) < 0) {
syslog(LOG_CRIT, "sysv shmctl stat/rmid failed");
exit(1);
}
if (SSeq == (SeqSpace *)-1) {
SSeq = NULL;
syslog(LOG_CRIT, "sysv shared memory map failed");
exit(1);
}
bzero(SSeq, sizeof(SeqSpace));
#else
#error "lib/seq.c currently requires USE_SPAM_SHM to be set in lib/config.h or lib/vendor.h"
#endif
}
void
LoadSlotDir(time_t t)
{
uint32 gmt = t / 60;
gmt = gmt - gmt % 10;
if (LSTime == 0 || gmt != LSTime) {
char path[256];
/*
* create directory, fixup end sequence
*/
sprintf(path, "%s/D.%08x", SpoolHome, gmt);
mkdir(path, 0755);
LSTime = gmt;
SSeq->ss_End = gmt;
/*
* Scan the spool to obtain the beginning sequence
*/
{
DIR *dir;
if ((dir = opendir(SpoolHome)) != NULL) {
den_t *den;
uint32 beg = gmt;
while ((den = readdir(dir)) != NULL) {
int32 v;
if (den->d_name[0] != 'D' || den->d_name[1] != '.')
continue;
if (sscanf(den->d_name + 2, "%x", &v) == 1) {
if ((uint32)v < beg)
beg = (uint32)v;
}
}
closedir(dir);
SSeq->ss_Beg = beg;
/*syslog(LOG_INFO, "SeqSpace: %08x - %08x", SSeq->ss_Beg, SSeq->ss_End);*/
}
}
}
}
uint32
ExpireToSeq(uint16 exp)
{
uint32 slot;
if (DiabloExpire == EXPIRE_FEEDER) {
slot = SSeq->ss_End;
} else {
/* EXPIRE_READER */
slot = SSeq->ss_Beg + (SSeq->ss_End - SSeq->ss_Beg) * (uint32)exp / 100;
}
slot = slot - slot % 10; /* 10 minute boundries */
return(slot);
}
|