X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?p=ossec-hids.git;a=blobdiff_plain;f=src%2Fanalysisd%2Fcdb%2Fcdb_make.c;fp=src%2Fanalysisd%2Fcdb%2Fcdb_make.c;h=eb5fe27b3decf318c60d67702d3edd444212a0bd;hp=bbfdfbc1eafb43ab515fecc2432ea7a0da8858fe;hb=3f728675941dc69d4e544d3a880a56240a6e394a;hpb=927951d1c1ad45ba9e7325f07d996154a91c911b diff --git a/src/analysisd/cdb/cdb_make.c b/src/analysisd/cdb/cdb_make.c index bbfdfbc..eb5fe27 100644 --- a/src/analysisd/cdb/cdb_make.c +++ b/src/analysisd/cdb/cdb_make.c @@ -1,4 +1,4 @@ -/* Public domain. */ +/* Public domain */ /* Adapted from DJB's original cdb-0.75 package */ #include @@ -10,171 +10,221 @@ #include "cdb_make.h" #include "uint32.h" -static int cdb_make_write(struct cdb_make *c, char *buf, uint32 sz) { - fwrite(buf, sz, 1, c->fp); - return ferror(c->fp); -} -int cdb_make_start(struct cdb_make *c, FILE * f) +static int cdb_make_write(struct cdb_make *c, char *buf, uint32 sz) { - c->head = 0; - c->split = 0; - c->hash = 0; - c->numentries = 0; - c->fp = f; - c->pos = sizeof c->final; - if (fseek(f,c->pos,SEEK_SET) == -1) { - perror("fseek failed"); - return -1; - } - return ftell(c->fp); + fwrite(buf, sz, 1, c->fp); + return ferror(c->fp); } -static int posplus(struct cdb_make *c,uint32 len) +int cdb_make_start(struct cdb_make *c, FILE *f) { - uint32 newpos = c->pos + len; - if (newpos < len) { errno = ENOMEM; return -1; } - c->pos = newpos; - return 0; + c->head = 0; + c->split = 0; + c->hash = 0; + c->numentries = 0; + c->fp = f; + c->pos = sizeof c->final; + if (fseek(f, c->pos, SEEK_SET) == -1) { + perror("fseek failed"); + return -1; + } + return ftell(c->fp); } -int cdb_make_addend(struct cdb_make *c,unsigned int keylen,unsigned int datalen,uint32 h) +static int posplus(struct cdb_make *c, uint32 len) { - struct cdb_hplist *head; - - head = c->head; - if (!head || (head->num >= CDB_HPLIST)) { - head = (struct cdb_hplist *) malloc(sizeof(struct cdb_hplist)); - if (!head) return -1; - head->num = 0; - head->next = c->head; - c->head = head; - } - head->hp[head->num].h = h; - head->hp[head->num].p = c->pos; - ++head->num; - ++c->numentries; - if (posplus(c,8) == -1) return -1; - if (posplus(c,keylen) == -1) return -1; - if (posplus(c,datalen) == -1) return -1; - return 0; + uint32 newpos = c->pos + len; + if (newpos < len) { + errno = ENOMEM; + return -1; + } + c->pos = newpos; + return 0; } -int cdb_make_addbegin(struct cdb_make *c,unsigned int keylen,unsigned int datalen) +int cdb_make_addend(struct cdb_make *c, unsigned int keylen, unsigned int datalen, uint32 h) { - char buf[8]; + struct cdb_hplist *head; + + head = c->head; + if (!head || (head->num >= CDB_HPLIST)) { + head = (struct cdb_hplist *) malloc(sizeof(struct cdb_hplist)); + if (!head) { + return -1; + } + head->num = 0; + head->next = c->head; + c->head = head; + } + head->hp[head->num].h = h; + head->hp[head->num].p = c->pos; + ++head->num; + ++c->numentries; + if (posplus(c, 8) == -1) { + return -1; + } + if (posplus(c, keylen) == -1) { + return -1; + } + if (posplus(c, datalen) == -1) { + return -1; + } + return 0; +} - if (keylen > 0xffffffff) { errno = ENOMEM; return -1; } - if (datalen > 0xffffffff) { errno = ENOMEM; return -1; } +int cdb_make_addbegin(struct cdb_make *c, unsigned int keylen, unsigned int datalen) +{ + char buf[8]; - uint32_pack(buf,keylen); - uint32_pack(buf + 4,datalen); - if (cdb_make_write(c,buf,8) != 0) return -1; - /* if (buffer_putalign(&c->b,buf,8) == -1) return -1; */ - return 0; + /*if (keylen > 0xffffffff) { + errno = ENOMEM; + return -1; + } + if (datalen > 0xffffffff) { + errno = ENOMEM; + return -1; + }*/ + + uint32_pack(buf, keylen); + uint32_pack(buf + 4, datalen); + if (cdb_make_write(c, buf, 8) != 0) { + return -1; + } + /* if (buffer_putalign(&c->b,buf,8) == -1) return -1; */ + return 0; } -int cdb_make_add(struct cdb_make *c,char *key,unsigned int keylen,char *data,unsigned int datalen) +int cdb_make_add(struct cdb_make *c, char *key, unsigned int keylen, char *data, unsigned int datalen) { - if (cdb_make_addbegin(c,keylen,datalen) == -1) return -1; - if (cdb_make_write(c,key,keylen) != 0) return -1; - if (cdb_make_write(c,data,datalen) != 0) return -1; - /* if (buffer_putalign(&c->b,key,keylen) == -1) return -1; */ - /* if (buffer_putalign(&c->b,data,datalen) == -1) return -1; */ - return cdb_make_addend(c,keylen,datalen,cdb_hash(key,keylen)); + if (cdb_make_addbegin(c, keylen, datalen) == -1) { + return -1; + } + if (cdb_make_write(c, key, keylen) != 0) { + return -1; + } + if (cdb_make_write(c, data, datalen) != 0) { + return -1; + } + /* if (buffer_putalign(&c->b,key,keylen) == -1) return -1; */ + /* if (buffer_putalign(&c->b,data,datalen) == -1) return -1; */ + return cdb_make_addend(c, keylen, datalen, cdb_hash(key, keylen)); } int cdb_make_finish(struct cdb_make *c) { - char buf[8]; - int i; - uint32 len; - uint32 u; - uint32 memsize; - uint32 count; - uint32 where; - struct cdb_hplist *x; - struct cdb_hp *hp; - - for (i = 0;i < 256;++i) - c->count[i] = 0; - - for (x = c->head;x;x = x->next) { - i = x->num; - while (i--) - ++c->count[255 & x->hp[i].h]; - } - - memsize = 1; - for (i = 0;i < 256;++i) { - u = c->count[i] * 2; - if (u > memsize) - memsize = u; - } - - memsize += c->numentries; /* no overflow possible up to now */ - u = (uint32) 0 - (uint32) 1; - u /= sizeof(struct cdb_hp); - if (memsize > u) { errno = ENOMEM; return -1; } - - c->split = (struct cdb_hp *) malloc(memsize * sizeof(struct cdb_hp)); - if (!c->split) return -1; - - c->hash = c->split + c->numentries; - - u = 0; - for (i = 0;i < 256;++i) { - u += c->count[i]; /* bounded by numentries, so no overflow */ - c->start[i] = u; - } - - for (x = c->head;x;x = x->next) { - i = x->num; - while (i--) - c->split[--c->start[255 & x->hp[i].h]] = x->hp[i]; - } - - for (i = 0;i < 256;++i) { - count = c->count[i]; - - len = count + count; /* no overflow possible */ - uint32_pack(c->final + 8 * i,c->pos); - uint32_pack(c->final + 8 * i + 4,len); - - for (u = 0;u < len;++u) - c->hash[u].h = c->hash[u].p = 0; - - hp = c->split + c->start[i]; - for (u = 0;u < count;++u) { - where = (hp->h >> 8) % len; - while (c->hash[where].p) - if (++where == len) - where = 0; - c->hash[where] = *hp++; - } - - for (u = 0;u < len;++u) { - uint32_pack(buf,c->hash[u].h); - uint32_pack(buf + 4,c->hash[u].p); - if (cdb_make_write(c,buf,8) != 0) return -1; - /* if (buffer_putalign(&c->b,buf,8) == -1) return -1; */ - if (posplus(c,8) == -1) return -1; - } - } - - if (c->split) free(c->split); - - for (x = c->head;x;c->head = x) { - x = x->next; - free(c->head); - } - - if (fflush(c->fp) != 0) return -1; - /* if (buffer_flush(&c->b) == -1) return -1; */ - rewind(c->fp); - if (ftell(c->fp) != 0) return -1; - /* if (seek_begin(c->fd) == -1) return -1; */ - if (cdb_make_write(c,c->final,sizeof c->final) != 0) return -1; - return fflush(c->fp); - /* return buffer_putflush(&c->b,c->final,sizeof c->final); */ + char buf[8]; + int i; + uint32 len; + uint32 u; + uint32 memsize; + uint32 count; + uint32 where; + struct cdb_hplist *x; + struct cdb_hp *hp; + + for (i = 0; i < 256; ++i) { + c->count[i] = 0; + } + + for (x = c->head; x; x = x->next) { + i = x->num; + while (i--) { + ++c->count[255 & x->hp[i].h]; + } + } + + memsize = 1; + for (i = 0; i < 256; ++i) { + u = c->count[i] * 2; + if (u > memsize) { + memsize = u; + } + } + + memsize += c->numentries; /* no overflow possible up to now */ + u = (uint32) 0 - (uint32) 1; + u /= sizeof(struct cdb_hp); + if (memsize > u) { + errno = ENOMEM; + return -1; + } + + c->split = (struct cdb_hp *) malloc(memsize * sizeof(struct cdb_hp)); + if (!c->split) { + return -1; + } + + c->hash = c->split + c->numentries; + + u = 0; + for (i = 0; i < 256; ++i) { + u += c->count[i]; /* bounded by numentries, so no overflow */ + c->start[i] = u; + } + + for (x = c->head; x; x = x->next) { + i = x->num; + while (i--) { + c->split[--c->start[255 & x->hp[i].h]] = x->hp[i]; + } + } + + for (i = 0; i < 256; ++i) { + count = c->count[i]; + + len = count + count; /* no overflow possible */ + uint32_pack(c->final + 8 * i, c->pos); + uint32_pack(c->final + 8 * i + 4, len); + + for (u = 0; u < len; ++u) { + c->hash[u].h = c->hash[u].p = 0; + } + + hp = c->split + c->start[i]; + for (u = 0; u < count; ++u) { + where = (hp->h >> 8) % len; + while (c->hash[where].p) + if (++where == len) { + where = 0; + } + c->hash[where] = *hp++; + } + + for (u = 0; u < len; ++u) { + uint32_pack(buf, c->hash[u].h); + uint32_pack(buf + 4, c->hash[u].p); + if (cdb_make_write(c, buf, 8) != 0) { + return -1; + } + /* if (buffer_putalign(&c->b,buf,8) == -1) return -1; */ + if (posplus(c, 8) == -1) { + return -1; + } + } + } + + if (c->split) { + free(c->split); + } + + for (x = c->head; x; c->head = x) { + x = x->next; + free(c->head); + } + + if (fflush(c->fp) != 0) { + return -1; + } + /* if (buffer_flush(&c->b) == -1) return -1; */ + rewind(c->fp); + if (ftell(c->fp) != 0) { + return -1; + } + /* if (seek_begin(c->fd) == -1) return -1; */ + if (cdb_make_write(c, c->final, sizeof c->final) != 0) { + return -1; + } + return fflush(c->fp); + /* return buffer_putflush(&c->b,c->final,sizeof c->final); */ }