/*
 * DREADERD/CANCEL.C
 *
 * 	Implement pre-cancel cache via shared memory segment.  The cache only
 *	applies to cancels that are received prior to the article being
 *	received.
 *
 * (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 InitCancelCache(void);
Prototype void EnterCancelCache(const char *msgid);
Prototype int FindCancelCache(const char *msgid);

#define C_HSIZE		16384
#define C_HMASK		(C_HSIZE-1)

hash_t *CCacheAry = NULL;

void 
InitCancelCache(void)
{
#if USE_CANCEL_SHM
    int sid = shmget(IPC_PRIVATE, C_HSIZE * sizeof(hash_t), SHM_R|SHM_W);
    struct shmid_ds ds;

    if (sid < 0) {
	logit(LOG_WARNING, "InitCancelCache cannot allocate sysv shared memory");
    } else {
	CCacheAry = (hash_t *)shmat(sid, NULL, SHM_R|SHM_W);
	if (shmctl(sid, IPC_STAT, &ds) < 0 || shmctl(sid, IPC_RMID, &ds) < 0) {
	    logit(LOG_CRIT, "sysv shmctl stat/rmid failed");
	    exit(1);
	}
	if (CCacheAry == (hash_t *)-1) {
	    CCacheAry = NULL;
	    logit(LOG_CRIT, "sysv shared memory map failed");
	    exit(1);
	}
	if (CCacheAry)
	    bzero(CCacheAry, C_HSIZE * sizeof(hash_t));
    }
#endif
}

void 
EnterCancelCache(const char *msgid)
{
    if (CCacheAry) {
	hash_t hv = hhash(msgid);
	int hi = ((hv.h1 ^ hv.h2) & 0x7FFFFFFF) % C_HSIZE;

	CCacheAry[hi] = hv;
    }
}

int 
FindCancelCache(const char *msgid)
{
    if (CCacheAry) {
	hash_t hv = hhash(msgid);
	hash_t *hp;
	int hi = ((hv.h1 ^ hv.h2) & 0x7FFFFFFF) % C_HSIZE;

	hp = &CCacheAry[hi];
	if (hv.h1 == hp->h1 && hv.h2 == hp->h2)
	    return(0);
    }
    return(-1);
}



syntax highlighted by Code2HTML, v. 0.9.1