#include "alloc.h"
#include "stralloc.h"
#include "open.h"
#include "cdb.h"
#include "case.h"
#include "mfrules.h"
/* return -9: problems reading cdb */
/* return -1: key matches; data not */
/* return 0: no key */
/* return 1: key matches without data */
/* return 2: key and data match */
stralloc key = {0};
static struct cdb c;
static int mffind(char *mf)
{
char *x;
char *data;
unsigned int datalen;
int plus = 0;
int dlen;
int len;
int mflen;
int delta;
switch(cdb_find(&c,key.s,key.len)) {
case -1: return -9;
case 0: return 0;
}
datalen = cdb_datalen(&c);
data = alloc(datalen);
if (!data) return -9;
if (!datalen) return 1;
mflen = str_len(mf);
if (cdb_read(&c,data,datalen,cdb_datapos(&c)) == -1) {
alloc_free(data);
return -9;
}
x = data; dlen = datalen - 1; /* trailing separator */
while (dlen > 0) {
plus = byte_rchr(data,dlen,'+');
x = data + plus + 1;
len = dlen - plus;
delta = (mflen > len) ? mflen - len : 0;
if (!byte_diff(x,len,mf + delta)) { alloc_free(data); return 2; }
dlen = plus - 1;
}
alloc_free(data);
return -1;
}
int mfsearch(char *ip,char *host,char *info,char *mf)
{
int r;
if (info) {
if (!stralloc_copys(&key,info)) return -9;
r = mffind(mf);
if (r < -1 || r > 0) return r;
if (!stralloc_cats(&key,"@")) return -9;
if (!stralloc_cats(&key,ip)) return -9;
r = mffind(mf);
if (r < -1 || r > 0) return r;
if (host) {
if (!stralloc_copys(&key,info)) return -9;
if (!stralloc_cats(&key,"@=")) return -9;
if (!stralloc_cats(&key,host)) return -9;
r = mffind(mf);
if (r < -1 || r > 0) return r;
}
}
if (!stralloc_copys(&key,ip)) return -9;
r = mffind(mf);
if (r < -1 || r > 0) return r;
if (host) {
if (!stralloc_copys(&key,"=")) return -9;
if (!stralloc_cats(&key,host)) return -9;
r = mffind(mf);
if (r < -1 || r > 0) return r;
}
if (!stralloc_copys(&key,ip)) return -9;
while (key.len > 0) {
if (ip[key.len - 1] == '.') {
r = mffind(mf);
if (r < -1 || r > 0) return r;
}
--key.len;
}
if (host) {
while (*host) {
if (*host == '.') {
if (!stralloc_copys(&key,"=")) return -9;
if (!stralloc_cats(&key,host)) return -9;
r = mffind(mf);
if (r < -1 || r > 0) return r;
}
++host;
}
if (!stralloc_copys(&key,"=")) return -9;
r = mffind(mf);
if (r < -1 || r > 0) return r;
}
key.len = 0;
/* return mffind(mf); */
return -1;
}
int mfrules(int fd,char *ip,char *host,char *info,char *mf)
{
int r;
cdb_init(&c,fd);
case_lowers(mf);
r = mfsearch(ip,host,info,mf);
cdb_free(&c);
return r;
}
syntax highlighted by Code2HTML, v. 0.9.1