mirror of
https://github.com/jrbrtsn/ban2fail
synced 2024-06-16 11:58:01 +00:00
213 lines
5.6 KiB
C
213 lines
5.6 KiB
C
/***************************************************************************
|
|
* Copyright (C) 2019 by John D. Robertson *
|
|
* john@rrci.com *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 3 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
|
***************************************************************************/
|
|
#define _GNU_SOURCE
|
|
#include <assert.h>
|
|
|
|
#include "ez_libdb.h"
|
|
#include "ez_libc.h"
|
|
#include "ez_libz.h"
|
|
#include "obsvTpl.h"
|
|
|
|
/* Make sure we don't have padding at the end of this struct */
|
|
#pragma pack(push,2)
|
|
struct obsv {
|
|
z_off_t pos; /* position in the file */
|
|
uint16_t len; /* length of string to retrieve */
|
|
};
|
|
#pragma pack(pop)
|
|
|
|
ObsvTpl*
|
|
ObsvTpl_constructor(ObsvTpl *self, LOGFILE *lf, const char *addr)
|
|
/*****************************************************************
|
|
* prepare for use.
|
|
*/
|
|
{
|
|
memset(self, 0, sizeof(*self));
|
|
|
|
strncpy(self->addr, addr, sizeof(self->addr)-1);
|
|
self->lf= lf;
|
|
DS_constructor(&self->stack, sizeof(struct obsv), 10000);
|
|
return self;
|
|
}
|
|
|
|
int
|
|
ObsvTpl_sinit(ObsvTpl *self, LOGFILE *lf, const char *addr)
|
|
/********************************************************
|
|
* Initialize or reset a static instance
|
|
*/
|
|
{
|
|
if(self->lf) {
|
|
memset(self->addr, 0, sizeof(self->addr));
|
|
strncpy(self->addr, addr, sizeof(self->addr)-1);
|
|
self->lf= lf;
|
|
DS_reset(&self->stack);
|
|
} else {
|
|
ObsvTpl_constructor(self, lf, addr);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void*
|
|
ObsvTpl_destructor(ObsvTpl *self)
|
|
/*****************************************************************
|
|
* Free resources
|
|
*/
|
|
{
|
|
|
|
DS_destructor(&self->stack);
|
|
|
|
return self;
|
|
}
|
|
|
|
int
|
|
ObsvTpl_addObsv(ObsvTpl *self, z_off_t pos, unsigned len)
|
|
/*****************************************************************
|
|
* Add an observation to this report object.
|
|
*/
|
|
{
|
|
struct obsv obs;
|
|
obs.pos= pos;
|
|
obs.len= len;
|
|
DS_push(&self->stack, &obs);
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
ObsvTpl_db_put(ObsvTpl *self, DB *db)
|
|
/*****************************************************************
|
|
* Write our contents into the database.
|
|
*/
|
|
{
|
|
int rtn= -1;
|
|
|
|
DBT key= {
|
|
.data= self->addr,
|
|
.size= strlen(self->addr)
|
|
},
|
|
data= {
|
|
.data= DS_ptr(&self->stack),
|
|
.size= DS_numItems(&self->stack) * sizeof(struct obsv)
|
|
};
|
|
|
|
/* Write data to database */
|
|
ez_db_put(db, NULL, &key, &data, 0);
|
|
|
|
rtn= 0;
|
|
abort:
|
|
return rtn;
|
|
}
|
|
|
|
int
|
|
ObsvTpl_db_get(ObsvTpl *self, DB *db)
|
|
/********************************************************
|
|
* Fetch our content from a database.
|
|
*/
|
|
{
|
|
int rtn= -1;
|
|
|
|
DBT key= {
|
|
.data= self->addr,
|
|
.size= strlen(self->addr)
|
|
},
|
|
data;
|
|
|
|
memset(&data, 0, sizeof(data));
|
|
|
|
/* Read from the database */
|
|
int rc= ez_db_get(db, NULL, &key, &data, 0);
|
|
if(DB_NOTFOUND == rc) return rc;
|
|
|
|
/* Now put all obsv's in place */
|
|
DS_reset(&self->stack);
|
|
|
|
/* Compute number of items we fetched */
|
|
unsigned nItems= data.size / sizeof(struct obsv);
|
|
|
|
/* Load them into the stack */
|
|
for(unsigned i= 0; i < nItems; ++i) {
|
|
struct obsv *src= (struct obsv*)data.data + i;
|
|
DS_push(&self->stack, src);
|
|
}
|
|
|
|
rtn= 0;
|
|
abort:
|
|
return rtn;
|
|
}
|
|
|
|
static int obsv_print(struct obsv *self, FILE *fh)
|
|
/********************************************************
|
|
* Print observation to fh
|
|
*/
|
|
{
|
|
ez_fprintf(fh, "\tpos= %lu, len= %hu\n", (long unsigned)self->pos, self->len);
|
|
return 0;
|
|
}
|
|
|
|
|
|
int
|
|
ObsvTpl_print(ObsvTpl *self, FILE *fh)
|
|
/********************************************************
|
|
* Print a human readable representation of *self.
|
|
*/
|
|
{
|
|
ez_fprintf(fh, "ObsvTpl %s {\n", self->addr);
|
|
|
|
DS_visitAllEntries(&self->stack, (int(*)(void*,void*))obsv_print, fh);
|
|
ez_fprintf(fh, "}\n");
|
|
return 0;
|
|
}
|
|
|
|
struct infoTuple {
|
|
gzFile fh;
|
|
AddrRPT *ar;
|
|
LOGFILE *lf;
|
|
};
|
|
|
|
static int
|
|
obsv_load_AddrRPT(struct obsv *self, struct infoTuple *it)
|
|
/********************************************************
|
|
* load specific observation into it->ar.
|
|
*/
|
|
{
|
|
static char lbuf[1024];
|
|
assert(self->len < sizeof(lbuf));
|
|
unsigned len= MIN(self->len, sizeof(lbuf)-1);
|
|
|
|
/* Put null terminator in place */
|
|
lbuf[len]= '\0';
|
|
|
|
ez_gzseek(it->fh, self->pos, SEEK_SET);
|
|
ez_gzread(it->fh, lbuf, len);
|
|
AddrRPT_addLine(it->ar, it->lf, lbuf);
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
ObsvTpl_put_AddrRPT(ObsvTpl *self, gzFile fh, AddrRPT *ar)
|
|
/********************************************************
|
|
* Place contents of self into ar.
|
|
*/
|
|
{
|
|
struct infoTuple it= {.fh= fh, .ar= ar, .lf= self->lf};
|
|
DS_visitAllEntries(&self->stack, (int(*)(void*,void*))obsv_load_AddrRPT, &it);
|
|
return 0;
|
|
}
|
|
|