mirror of https://github.com/nealey/irc-bot
add remove action to infobot
This commit is contained in:
parent
b993629d88
commit
b48152c085
20
cdb.c
20
cdb.c
|
@ -40,7 +40,9 @@ read_u32le(FILE *f)
|
||||||
{
|
{
|
||||||
uint8_t d[4];
|
uint8_t d[4];
|
||||||
|
|
||||||
fread(d, 4, 1, f);
|
if (0 == fread(d, 4, 1, f)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return ((d[0] << 0) |
|
return ((d[0] << 0) |
|
||||||
(d[1] << 8) |
|
(d[1] << 8) |
|
||||||
(d[2] << 16) |
|
(d[2] << 16) |
|
||||||
|
@ -80,24 +82,26 @@ cdb_dump(struct cdb_ctx *ctx,
|
||||||
// Find out where to stop reading
|
// Find out where to stop reading
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
fseek(ctx->f, 0, SEEK_SET);
|
||||||
ctx->hash_len = 0;
|
ctx->hash_len = 0;
|
||||||
ctx->hash_pos = 0xffffffff;
|
ctx->hash_pos = 0xffffffff;
|
||||||
for (i = 0; i < 256; i += 1) {
|
for (i = 0; i < 256; i += 1) {
|
||||||
uint32_t p;
|
uint32_t p;
|
||||||
|
|
||||||
fseek(ctx->f, i * 8, SEEK_SET);
|
|
||||||
p = read_u32le(ctx->f);
|
p = read_u32le(ctx->f);
|
||||||
|
read_u32le(ctx->f);
|
||||||
if (p < ctx->hash_pos) {
|
if (p < ctx->hash_pos) {
|
||||||
ctx->hash_pos = p;
|
ctx->hash_pos = p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fseek(ctx->f, 256 * 8, SEEK_SET);
|
|
||||||
} else {
|
|
||||||
long where = ftell(ctx->f);
|
|
||||||
|
|
||||||
if (where >= ctx->hash_pos) {
|
ctx->entry = 256 * 8;
|
||||||
return EOF;
|
fseek(ctx->f, ctx->entry, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stop if we've reached the end
|
||||||
|
if (ctx->entry >= ctx->hash_pos) {
|
||||||
|
return EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the two buffers
|
// Read the two buffers
|
||||||
|
@ -107,6 +111,8 @@ cdb_dump(struct cdb_ctx *ctx,
|
||||||
|
|
||||||
*keylen = read_buf(ctx->f, klen, key, *keylen);
|
*keylen = read_buf(ctx->f, klen, key, *keylen);
|
||||||
*vallen = read_buf(ctx->f, vlen, val, *vallen);
|
*vallen = read_buf(ctx->f, vlen, val, *vallen);
|
||||||
|
|
||||||
|
ctx->entry += 4 + 4 + klen + vlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h> // XXX: remove if malloc() is gone
|
#include <stdlib.h> // XXX: remove if malloc() is gone
|
||||||
#include "cdbmake.h"
|
#include "cdbmake.h"
|
||||||
|
#include "dump.h"
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
hash(char *s, size_t len)
|
hash(char *s, size_t len)
|
||||||
|
@ -36,7 +37,8 @@ cdbmake_init(struct cdbmake_ctx *ctx, FILE *f)
|
||||||
ctx->nrecords[i] = 0;
|
ctx->nrecords[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fseek(f, 256 * 8, SEEK_SET);
|
ctx->where = 256 * 8;
|
||||||
|
fseek(f, ctx->where, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -44,7 +46,6 @@ cdbmake_add(struct cdbmake_ctx *ctx,
|
||||||
char *key, size_t keylen,
|
char *key, size_t keylen,
|
||||||
char *val, size_t vallen)
|
char *val, size_t vallen)
|
||||||
{
|
{
|
||||||
long where = ftell(ctx->f);
|
|
||||||
uint32_t hashval = hash(key, keylen);
|
uint32_t hashval = hash(key, keylen);
|
||||||
int idx = hashval % 256;
|
int idx = hashval % 256;
|
||||||
uint32_t n = ctx->nrecords[idx];
|
uint32_t n = ctx->nrecords[idx];
|
||||||
|
@ -57,13 +58,15 @@ cdbmake_add(struct cdbmake_ctx *ctx,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ctx->records[idx][n].hashval = hashval;
|
ctx->records[idx][n].hashval = hashval;
|
||||||
ctx->records[idx][n].offset = (uint32_t)where;
|
ctx->records[idx][n].offset = (uint32_t)ctx->where;
|
||||||
|
|
||||||
// Write it out
|
// Write it out
|
||||||
write_u32le(ctx->f, keylen);
|
write_u32le(ctx->f, keylen);
|
||||||
write_u32le(ctx->f, vallen);
|
write_u32le(ctx->f, vallen);
|
||||||
fwrite(key, 1, keylen, ctx->f);
|
fwrite(key, 1, keylen, ctx->f);
|
||||||
fwrite(val, 1, vallen, ctx->f);
|
fwrite(val, 1, vallen, ctx->f);
|
||||||
|
|
||||||
|
ctx->where += 4 + 4 + keylen + vallen;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -15,6 +15,7 @@ struct cdbmake_ctx {
|
||||||
FILE *f;
|
FILE *f;
|
||||||
struct cdbmake_record *records[256];
|
struct cdbmake_record *records[256];
|
||||||
uint32_t nrecords[256];
|
uint32_t nrecords[256];
|
||||||
|
long where;
|
||||||
};
|
};
|
||||||
|
|
||||||
void cdbmake_init(struct cdbmake_ctx *ctx, FILE *f);
|
void cdbmake_init(struct cdbmake_ctx *ctx, FILE *f);
|
||||||
|
|
1
dump.h
1
dump.h
|
@ -11,6 +11,7 @@
|
||||||
#endif
|
#endif
|
||||||
#define DUMP() DUMPf("")
|
#define DUMP() DUMPf("")
|
||||||
#define DUMP_d(v) DUMPf("%s = %d", #v, v)
|
#define DUMP_d(v) DUMPf("%s = %d", #v, v)
|
||||||
|
#define DUMP_l(v) DUMPf("%s = %ld", #v, v)
|
||||||
#define DUMP_x(v) DUMPf("%s = 0x%x", #v, v)
|
#define DUMP_x(v) DUMPf("%s = 0x%x", #v, v)
|
||||||
#define DUMP_s(v) DUMPf("%s = %s", #v, v)
|
#define DUMP_s(v) DUMPf("%s = %s", #v, v)
|
||||||
#define DUMP_c(v) DUMPf("%s = '%c' (0x%02x)", #v, v, v)
|
#define DUMP_c(v) DUMPf("%s = '%c' (0x%02x)", #v, v, v)
|
||||||
|
|
127
infobot.c
127
infobot.c
|
@ -3,25 +3,13 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <fnmatch.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sysexits.h>
|
#include <sysexits.h>
|
||||||
#include "cdb.h"
|
#include "cdb.h"
|
||||||
#include "cdbmake.h"
|
#include "cdbmake.h"
|
||||||
|
#include "dump.h"
|
||||||
/* Some things I use for debugging */
|
|
||||||
#ifdef NODUMP
|
|
||||||
# define DUMPf(fmt, args...)
|
|
||||||
#else
|
|
||||||
# define DUMPf(fmt, args...) fprintf(stderr, "%s:%s:%d " fmt "\n", __FILE__, __FUNCTION__, __LINE__, ##args)
|
|
||||||
#endif
|
|
||||||
#define DUMP() DUMPf("")
|
|
||||||
#define DUMP_u(v) DUMPf("%s = %u", #v, v)
|
|
||||||
#define DUMP_d(v) DUMPf("%s = %d", #v, v)
|
|
||||||
#define DUMP_x(v) DUMPf("%s = 0x%x", #v, v)
|
|
||||||
#define DUMP_s(v) DUMPf("%s = %s", #v, v)
|
|
||||||
#define DUMP_c(v) DUMPf("%s = %c", #v, v)
|
|
||||||
#define DUMP_p(v) DUMPf("%s = %p", #v, v)
|
|
||||||
|
|
||||||
int
|
int
|
||||||
usage()
|
usage()
|
||||||
|
@ -115,6 +103,45 @@ list(char *filename, char *key)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
setup_copy(char *infn, struct cdb_ctx *inc, FILE **inf,
|
||||||
|
char **outfn, struct cdbmake_ctx *outc, FILE **outf)
|
||||||
|
{
|
||||||
|
static char tmpfn[8192];
|
||||||
|
|
||||||
|
*inf = fopen(infn, "rb");
|
||||||
|
if (! *inf) {
|
||||||
|
perror("Opening database");
|
||||||
|
return EX_NOINPUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(tmpfn, sizeof(tmpfn), "%s.%d", infn, getpid());
|
||||||
|
*outf = fopen(tmpfn, "wb");
|
||||||
|
if (! *outf) {
|
||||||
|
perror("Creating temporary database");
|
||||||
|
return EX_CANTCREAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
cdb_init(inc, *inf);
|
||||||
|
cdbmake_init(outc, *outf);
|
||||||
|
|
||||||
|
*outfn = strdup(tmpfn);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
finish_copy(char *infn, struct cdb_ctx *inc, FILE **inf,
|
||||||
|
char *outfn, struct cdbmake_ctx *outc, FILE **outf)
|
||||||
|
{
|
||||||
|
cdbmake_finalize(outc);
|
||||||
|
fclose(*outf);
|
||||||
|
fclose(*inf);
|
||||||
|
|
||||||
|
rename(outfn, infn);
|
||||||
|
free(outfn);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
add(char *filename, char *key, char *val)
|
add(char *filename, char *key, char *val)
|
||||||
{
|
{
|
||||||
|
@ -122,26 +149,14 @@ add(char *filename, char *key, char *val)
|
||||||
struct cdbmake_ctx outc;
|
struct cdbmake_ctx outc;
|
||||||
FILE *inf;
|
FILE *inf;
|
||||||
FILE *outf;
|
FILE *outf;
|
||||||
char tmpfn[8192];
|
char *outfn;
|
||||||
|
int ret;
|
||||||
|
|
||||||
// Open input file
|
ret = setup_copy(filename, &inc, &inf, &outfn, &outc, &outf);
|
||||||
inf = fopen(filename, "rb");
|
if (ret) {
|
||||||
if (! inf) {
|
return ret;
|
||||||
perror("Opening database");
|
|
||||||
return EX_NOINPUT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create temporary output file
|
|
||||||
snprintf(tmpfn, sizeof(tmpfn), "%s.%d", filename, getpid());
|
|
||||||
outf = fopen(tmpfn, "wb");
|
|
||||||
if (! outf) {
|
|
||||||
perror("Creating temporary database");
|
|
||||||
return EX_CANTCREAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
cdb_init(&inc, inf);
|
|
||||||
cdbmake_init(&outc, outf);
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
char key[8192];
|
char key[8192];
|
||||||
char val[8192];
|
char val[8192];
|
||||||
|
@ -154,15 +169,52 @@ add(char *filename, char *key, char *val)
|
||||||
cdbmake_add(&outc, key, keylen, val, vallen);
|
cdbmake_add(&outc, key, keylen, val, vallen);
|
||||||
}
|
}
|
||||||
cdbmake_add(&outc, key, strlen(key), val, strlen(val));
|
cdbmake_add(&outc, key, strlen(key), val, strlen(val));
|
||||||
cdbmake_finalize(&outc);
|
|
||||||
|
|
||||||
fclose(outf);
|
finish_copy(filename, &inc, &inf, outfn, &outc, &outf);
|
||||||
fclose(inf);
|
|
||||||
rename(tmpfn, filename);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
del(char *filename, char *key, char *glob)
|
||||||
|
{
|
||||||
|
size_t keylen = strlen(key);
|
||||||
|
struct cdb_ctx inc;
|
||||||
|
struct cdbmake_ctx outc;
|
||||||
|
FILE *inf;
|
||||||
|
FILE *outf;
|
||||||
|
char *outfn;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = setup_copy(filename, &inc, &inf, &outfn, &outc, &outf);
|
||||||
|
if (ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
char k[8192];
|
||||||
|
char v[8192];
|
||||||
|
size_t klen = sizeof(k);
|
||||||
|
size_t vlen = sizeof(v) - 1;
|
||||||
|
|
||||||
|
if (EOF == cdb_dump(&inc, k, &klen, v, &vlen)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
v[vlen] = '\0';
|
||||||
|
if ((klen == keylen) &&
|
||||||
|
(0 == memcmp(k, key, klen)) &&
|
||||||
|
(0 == fnmatch(glob, v, 0))) {
|
||||||
|
// Skip if it matches
|
||||||
|
} else {
|
||||||
|
cdbmake_add(&outc, k, klen, v, vlen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
finish_copy(filename, &inc, &inf, outfn, &outc, &outf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
enum action {
|
enum action {
|
||||||
ACT_ONE,
|
ACT_ONE,
|
||||||
|
@ -223,9 +275,8 @@ main(int argc, char *argv[])
|
||||||
return list(filename, key);
|
return list(filename, key);
|
||||||
case ACT_ADD:
|
case ACT_ADD:
|
||||||
return add(filename, key, val);
|
return add(filename, key, val);
|
||||||
default:
|
case ACT_DEL:
|
||||||
fprintf(stderr, "Not yet implemented, chump %s.\n", val);
|
return del(filename, key, val);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue