changes - bmf - bmf (Bayesian Mail Filter) 0.9.4 fork + patches | |
git clone git://git.codemadness.org/bmf | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit e805a804b42a190f0b06d8c495fd0f29011b1329 | |
parent 4857ceba2cfedeafd8971a8e6e3db4ce2ea7f1b6 | |
Author: Hiltjo Posthuma <[email protected]> | |
Date: Sat, 22 Sep 2018 17:57:54 +0200 | |
changes | |
- remove -i option: reading from file. | |
- remove -f format option and db formats. | |
- initial pledge(2) support. | |
- remove bmfconv. only text "database" is supported. | |
Diffstat: | |
A .gitignore | 4 ++++ | |
A Makefile | 45 +++++++++++++++++++++++++++++… | |
D Makefile.in | 81 ------------------------------ | |
M bmf.1 | 13 +------------ | |
M bmf.c | 37 ++++++-----------------------… | |
D bmfconv.1 | 81 ------------------------------ | |
D bmfconv.c | 169 -----------------------------… | |
M config.h | 2 ++ | |
D configure | 354 -----------------------------… | |
M dbdb.c | 614 -----------------------------… | |
M dbdb.h | 48 -----------------------------… | |
M dbh.c | 7 ------- | |
M dbh.h | 4 +--- | |
D dbmysql.c | 545 -----------------------------… | |
D dbmysql.h | 60 -----------------------------… | |
15 files changed, 60 insertions(+), 2004 deletions(-) | |
--- | |
diff --git a/.gitignore b/.gitignore | |
@@ -0,0 +1,4 @@ | |
+*.o | |
+*.core | |
+bmf | |
+bmfconv | |
diff --git a/Makefile b/Makefile | |
@@ -0,0 +1,45 @@ | |
+# Makefile for bmf | |
+ | |
+BINDIR=/usr/bin | |
+MANDIR=/usr/share/man | |
+ | |
+VERSION=0.9.4 | |
+ | |
+CFLAGS+=-DNDEBUG -D_UNIX -D_BSD=40 -Wall | |
+LDFLAGS+= | |
+SYSLIBS= | |
+ | |
+all: bmf | |
+ | |
+bmf: bmf.o filt.o dbdb.o dbtext.o dbh.o lex.o vec.o str.o dbg.o | |
+ $(CC) -o $@ bmf.o filt.o dbdb.o dbtext.o dbh.o lex.o vec.o str.o dbg.o… | |
+ | |
+bmf.o: bmf.c | |
+ $(CC) $(CFLAGS) -DPACKAGE=\"bmf\" -DVERSION=\"$(VERSION)\" -c $< | |
+ | |
+install: checkroot bmf bmf.1 | |
+ [ -d $(DESTDIR)$(BINDIR) ] || mkdir -p $(DESTDIR)$(BINDIR) | |
+ [ -d $(DESTDIR)$(MANDIR)/man1 ] || mkdir -p $(DESTDIR)$(MANDIR)/man1 | |
+ cp bmf $(DESTDIR)$(BINDIR) | |
+ cp bmf.1 $(DESTDIR)$(MANDIR)/man1 | |
+ | |
+uninstall: checkroot | |
+ rm -f $(DESTDIR)$(BINDIR)/bmf | |
+ rm -f $(DESTDIR)$(MANDIR)/man1/bmf.1 | |
+ | |
+clean: | |
+ rm -f core *.o bmf | |
+ | |
+distclean: clean | |
+ rm -f Makefile | |
+ | |
+dist: tarball | |
+ | |
+tarball: distclean | |
+ (cd ..; \ | |
+ cp -ar bmf bmf-$(VERSION); \ | |
+ tar czvf bmf-$(VERSION).tar.gz `find bmf-$(VERSION) -type f | egrep -… | |
+ rm -rf bmf-$(VERSION); \ | |
+ cd $(PWD)) | |
+ | |
+checkroot: | |
diff --git a/Makefile.in b/Makefile.in | |
@@ -1,81 +0,0 @@ | |
-# Makefile for bmf | |
- | |
-BINDIR=/usr/bin | |
-MANDIR=/usr/share/man | |
- | |
-VERSION=0.9.4 | |
- | |
-CC=@CC@ | |
-CFLAGS=@CFLAGS@ | |
-LDFLAGS=@LDFLAGS@ | |
-SYSLIBS=@SYSLIBS@ | |
- | |
-# For creating rpm packages | |
-RPMROOT=/usr/src/rpm | |
-RPM = rpm | |
-RPMFLAGS = -ba | |
-ARCH=`arch|sed 's/i[4-9]86/i386/'` | |
- | |
-all: bmf bmfconv | |
- | |
-bmf: bmf.o filt.o dbmysql.o dbdb.o dbtext.o dbh.o lex.o vec.o str.o dbg.o | |
- $(CC) -o $@ bmf.o filt.o dbmysql.o dbdb.o dbtext.o dbh.o lex.o vec.o s… | |
- | |
-bmf.o: bmf.c | |
- $(CC) $(CFLAGS) -DPACKAGE=\"bmf\" -DVERSION=\"$(VERSION)\" -c $< | |
- | |
-bmfconv: bmfconv.o dbmysql.o dbdb.o dbtext.o dbh.o vec.o str.o dbg.o | |
- $(CC) -o $@ bmfconv.o dbmysql.o dbdb.o dbtext.o dbh.o vec.o str.o dbg.… | |
- | |
-bmfconv.o: bmfconv.c | |
- $(CC) $(CFLAGS) -DPACKAGE=\"bmfconv\" -DVERSION=\"$(VERSION)\" -c $< | |
- | |
-install: checkroot bmf bmf.1 bmfconv bmfconv.1 | |
- [ -d $(DESTDIR)$(BINDIR) ] || mkdir -p $(DESTDIR)$(BINDIR) | |
- [ -d $(DESTDIR)$(MANDIR)/man1 ] || mkdir -p $(DESTDIR)$(MANDIR)/man1 | |
- cp bmf $(DESTDIR)$(BINDIR) | |
- cp bmf.1 $(DESTDIR)$(MANDIR)/man1 | |
- cp bmfconv $(DESTDIR)$(BINDIR) | |
- cp bmfconv.1 $(DESTDIR)$(MANDIR)/man1 | |
- | |
-uninstall: checkroot | |
- rm -f $(DESTDIR)$(BINDIR)/bmf | |
- rm -f $(DESTDIR)$(MANDIR)/man1/bmf.1 | |
- rm -f $(DESTDIR)$(BINDIR)/bmfconv | |
- rm -f $(DESTDIR)$(MANDIR)/man1/bmfconv.1 | |
- | |
-clean: | |
- rm -f core *.o bmf bmfconv | |
- | |
-distclean: clean | |
- rm -f Makefile | |
- | |
-dist: tarball rpmpkg debpkg | |
- | |
-tarball: distclean | |
- (cd ..; \ | |
- cp -ar bmf bmf-$(VERSION); \ | |
- tar czvf bmf-$(VERSION).tar.gz `find bmf-$(VERSION) -type f | egrep -… | |
- rm -rf bmf-$(VERSION); \ | |
- cd $(PWD)) | |
- | |
-debpkg: checkroot | |
- debian/rules binary | |
- rm -rf debian/tmp | |
- | |
-rpmpkg: checkroot | |
- (mkdir -p $(RPMROOT); \ | |
- mkdir -p $(RPMROOT)/SOURCES; \ | |
- mkdir -p $(RPMROOT)/SPECS; \ | |
- mkdir -p $(RPMROOT)/RPMS; \ | |
- mkdir -p $(RPMROOT)/SRPMS; \ | |
- cp ../bmf-$(VERSION).tar.gz $(RPMROOT)/SOURCES; \ | |
- cat bmf.spec.in | sed 's/VERSION/$(VERSION)/' > $(RPMROOT)/SPECS/bmf.… | |
- cd $(RPMROOT)/SPECS; \ | |
- $(RPM) $(RPMFLAGS) bmf.spec; \ | |
- cp $(RPMROOT)/RPMS/$(ARCH)/bmf-$(VERSION)-*.rpm $(PWD)/..; \ | |
- cp $(RPMROOT)/SRPMS/bmf-$(VERSION)-*.src.rpm $(PWD)/..; \ | |
- cd $(PWD)) | |
- | |
-checkroot: | |
- [ "`whoami`" = root ] || (echo Need root; exit 1) | |
diff --git a/bmf.1 b/bmf.1 | |
@@ -23,7 +23,7 @@ bmf \- efficient Bayesian mail filter | |
.SH "SYNOPSIS" | |
.nf | |
-\fBbmf\fR [-t] [-n] [-s] [-N] [-S] [-f fmt] [-d db] [-i file] [-k n] [-m type]… | |
+\fBbmf\fR [-t] [-n] [-s] [-N] [-S] [-d db] [-k n] [-m type] [-p] | |
[-v] [-V] [-h] | |
.fi | |
@@ -62,9 +62,6 @@ Without command-line options, bmf processes the input, regist… | |
\fB-d db\fR Specify database or directory for loading and saving word lists. T… | |
.PP | |
-\fB-i file\fR Use file for input instead of stdin. | |
- | |
-.PP | |
\fB-k n\fR Specify the number of extrema (keepers) to use in the Bayes calcula… | |
.PP | |
@@ -119,14 +116,6 @@ List of good tokens for text mode. | |
\fI~/.bmf/spamlist.txt\fR | |
List of bad tokens for text mode. | |
-.TP | |
-\fI~/.bmf/goodlist.db\fR | |
-List of good tokens for libdb mode. | |
- | |
-.TP | |
-\fI~/.bmf/spamlist.db\fR | |
-List of bad tokens for libdb mode. | |
- | |
.SH "BUGS" | |
.PP | |
diff --git a/bmf.c b/bmf.c | |
@@ -72,7 +72,7 @@ static void version( void ) | |
int main( int argc, char** argv ) | |
{ | |
int ch; | |
- dbfmt_t dbfmt = db_db; | |
+ dbfmt_t dbfmt = db_text; | |
char* dbname = NULL; | |
bool_t rdonly; | |
@@ -93,17 +93,14 @@ int main( int argc, char** argv ) | |
int fd = STDIN_FILENO; | |
char* infile = NULL; | |
+ if (pledge("stdio rpath wpath cpath tmppath", NULL) == -1) | |
+ err(1, "pledge"); | |
+ | |
srand(time(NULL)); | |
atexit( dump_alloc_heap ); | |
-#ifdef HAVE_LIBDB | |
- dbfmt = db_db; | |
-#else | |
- dbfmt = db_text; | |
-#endif | |
- | |
stats.keepers = DEF_KEEPERS; | |
- while( (ch = getopt( argc, argv, "NSVd:f:i:hk:m:npstv" )) != EOF ) | |
+ while( (ch = getopt( argc, argv, "NSVd:hk:m:npstv" )) != EOF ) | |
{ | |
switch( ch ) | |
{ | |
@@ -120,31 +117,9 @@ int main( int argc, char** argv ) | |
free( dbname ); | |
dbname = strdup( optarg ); | |
break; | |
- case 'f': | |
- if( strcasecmp( optarg, "text" ) == 0 ) | |
- { | |
- dbfmt = db_text; | |
- } | |
- else if( strcasecmp( optarg, "db" ) == 0 ) | |
- { | |
- dbfmt = db_db; | |
- } | |
- else if( strcasecmp( optarg, "mysql" ) == 0 ) | |
- { | |
- dbfmt = db_mysql; | |
- } | |
- else | |
- { | |
- usage(); | |
- } | |
- break; | |
case 'h': | |
usage(); | |
break; /* notreached */ | |
- case 'i': | |
- free( infile ); | |
- infile = strdup( optarg ); | |
- break; | |
case 'k': | |
stats.keepers = atoi( optarg ); | |
break; | |
@@ -173,6 +148,8 @@ int main( int argc, char** argv ) | |
break; | |
case 't': | |
mode = mode_test; | |
+ if (pledge("stdio rpath", NULL) == -1) | |
+ err(1, "pledge"); | |
break; | |
case 'v': | |
g_verbose++; | |
diff --git a/bmfconv.1 b/bmfconv.1 | |
@@ -1,81 +0,0 @@ | |
-.\"Generated by db2man.xsl. Don't modify this, modify the source. | |
-.de Sh \" Subsection | |
-.br | |
-.if t .Sp | |
-.ne 5 | |
-.PP | |
-\fB\\$1\fR | |
-.PP | |
-.. | |
-.de Sp \" Vertical space (when we can't use .PP) | |
-.if t .sp .5v | |
-.if n .sp | |
-.. | |
-.de Ip \" List item | |
-.br | |
-.ie \\n(.$>=3 .ne \\$3 | |
-.el .ne 3 | |
-.IP "\\$1" \\$2 | |
-.. | |
-.TH "BMFCONV" 1 "" "" "" | |
-.SH NAME | |
-bmfconv \- Database converter for bmf | |
-.SH "SYNOPSIS" | |
- | |
-.nf | |
-\fBbmfconv\fR [-f fmt] [-d db] [-e] [-i] [-v] [-h] | |
-.fi | |
- | |
-.SH "DESCRIPTION" | |
- | |
-.PP | |
-bmfconv converts bmf token databases between the supported formats. It can imp… | |
- | |
-.PP | |
-PLEASE NOTE that the text files used in import and export operations are read … | |
- | |
-.SH "OPTIONS" | |
- | |
-.PP | |
-\fB-f fmt\fR Specify database format. Supported formats are "db" for libdb and… | |
- | |
-.PP | |
-\fB-d db\fR Specify database name. | |
- | |
-.PP | |
-\fB-e\fR Export the database to text files. | |
- | |
-.PP | |
-\fB-i\fR Import the database from text files. | |
- | |
-.PP | |
-\fB-v\fR Display version information. | |
- | |
-.PP | |
-\fB-h\fR Display usage information. | |
- | |
-.SH "RETURN VALUES" | |
- | |
-.PP | |
-0 if conversion succeeds, nonzero if conversion fails. | |
- | |
-.SH "FILES" | |
- | |
-.TP | |
-\fIgoodlist.txt\fR | |
-Text file for import or export of good tokens. | |
- | |
-.TP | |
-\fIspamlist.txt\fR | |
-Text file for import or export of spam tokens. | |
- | |
-.SH "BUGS" | |
- | |
-.PP | |
-Should be more robust. | |
- | |
-.SH "AUTHOR" | |
- | |
-.PP | |
-Tom Marshall <[email protected]>. bmfconv is a part of the bmf package. | |
- | |
diff --git a/bmfconv.c b/bmfconv.c | |
@@ -1,169 +0,0 @@ | |
-/* $Id: bmfconv.c,v 1.9 2002/10/20 18:19:17 tommy Exp $ */ | |
- | |
-/* | |
- * Copyright (c) 2002 Tom Marshall <[email protected]> | |
- * | |
- * This program is free software. It may be distributed under the terms | |
- * in the file LICENSE, found in the top level of the distribution. | |
- * | |
- * bmfconv.c: bmf database converter | |
- */ | |
- | |
-#include "config.h" | |
-#include "dbg.h" | |
-#include "str.h" | |
-#include "vec.h" | |
-#include "dbh.h" | |
- | |
-typedef enum | |
-{ | |
- none, | |
- db2text, | |
- text2db | |
-} dir_t; | |
- | |
-static void usage( void ) | |
-{ | |
- printf( "\n" | |
- "Usage: " PACKAGE " [options]\n" | |
- "\t-f fmt\tSpecify database format (db|mysql).\n" | |
- "\t-d db\tSpecify database or directory name.\n" | |
- "\t-e\tExport to text files goodlist.txt and spamlist.txt.\n" | |
- "\t-i\tImport from text files goodlist.txt and spamlist.txt.\n" | |
- "\t-v\tShow version information and exit\n" | |
- "\t-h\tShow this message and exit\n" | |
- "\n" ); | |
- exit( 2 ); | |
-} | |
- | |
-static void version( void ) | |
-{ | |
- printf( "\n" | |
- PACKAGE " version " VERSION " - a Bayesian mail filter\n" | |
- "Copyright (c) 2002 Tom Marshall\n" | |
- "\n" | |
- PACKAGE " comes with ABSOLUTELY NO WARRANTY.\n" | |
- "This is free software. You are welcome to redistribute it under … | |
- "of the GNU General Public License. See the file LICENSE in the s… | |
- "distribution, or visit http://www.gnu.org/licenses/gpl.html\n" | |
- "\n" ); | |
- exit( 2 ); | |
-} | |
- | |
-int main( int argc, char** argv ) | |
-{ | |
- int ch; | |
- dbfmt_t dbfmt = db_db; | |
- char* dbname = NULL; | |
- bool_t rdonly; | |
- | |
- dbh_t* pdb; | |
- dbt_t* ptable; | |
- dir_t dir = none; | |
- | |
- while( (ch = getopt( argc, argv, "d:ef:ihv" )) != EOF ) | |
- { | |
- switch( ch ) | |
- { | |
- case 'd': | |
- free( dbname ); | |
- dbname = strdup( optarg ); | |
- break; | |
- case 'e': | |
- dir = db2text; | |
- break; | |
- case 'f': | |
- if( strcasecmp( optarg, "db" ) == 0 ) | |
- { | |
- dbfmt = db_db; | |
- } | |
- else if( strcasecmp( optarg, "mysql" ) == 0 ) | |
- { | |
- dbfmt = db_mysql; | |
- } | |
- else | |
- { | |
- usage(); | |
- } | |
- break; | |
- case 'h': | |
- usage(); | |
- break; /* notreached */ | |
- case 'i': | |
- dir = text2db; | |
- break; | |
- case 'v': | |
- version(); | |
- break; /* notreached */ | |
- default: | |
- usage(); | |
- } | |
- } | |
- if( dir == none ) | |
- { | |
- usage(); | |
- } | |
- | |
- pdb = dbh_open( dbfmt, "localhost", dbname, DB_USER, DB_PASS ); | |
- if( pdb == NULL ) | |
- { | |
- fprintf( stderr, "cannot open database\n" ); | |
- exit( 1 ); | |
- } | |
- rdonly = (dir == db2text ? true : false); | |
- | |
- ptable = pdb->opentable( pdb, "spamlist", rdonly ); | |
- if( ptable == NULL ) | |
- { | |
- fprintf( stderr, "cannot open spamlist\n" ); | |
- exit( 1 ); | |
- } | |
- if( dir == db2text ) | |
- { | |
- if( !ptable->export( ptable, "spamlist.txt" ) ) | |
- { | |
- fprintf( stderr, "cannot export spamlist\n" ); | |
- exit( 1 ); | |
- } | |
- } | |
- else | |
- { | |
- if( !ptable->import( ptable, "spamlist.txt" ) ) | |
- { | |
- fprintf( stderr, "cannot import spamlist\n" ); | |
- exit( 1 ); | |
- } | |
- } | |
- ptable->close( ptable ); | |
- free( ptable ); | |
- | |
- ptable = pdb->opentable( pdb, "goodlist", rdonly ); | |
- if( ptable == NULL ) | |
- { | |
- fprintf( stderr, "cannot open goodlist\n" ); | |
- exit( 1 ); | |
- } | |
- if( dir == db2text ) | |
- { | |
- if( !ptable->export( ptable, "goodlist.txt" ) ) | |
- { | |
- fprintf( stderr, "cannot export goodlist\n" ); | |
- exit( 1 ); | |
- } | |
- } | |
- else | |
- { | |
- if( !ptable->import( ptable, "goodlist.txt" ) ) | |
- { | |
- fprintf( stderr, "cannot import goodlist\n" ); | |
- exit( 1 ); | |
- } | |
- } | |
- ptable->close( ptable ); | |
- free( ptable ); | |
- | |
- pdb->close( pdb ); | |
- free( pdb ); | |
- | |
- return 0; | |
-} | |
diff --git a/config.h b/config.h | |
@@ -10,6 +10,8 @@ | |
#ifndef _CONFIG_H | |
#define _CONFIG_H | |
+#include <err.h> | |
+ | |
/************************************** | |
* Standard headers | |
*/ | |
diff --git a/configure b/configure | |
@@ -1,354 +0,0 @@ | |
-#!/bin/sh | |
- | |
-echo "" | |
- | |
-# defaults | |
-DEBUG=no | |
-with_libdb=test | |
-with_mysql=test | |
- | |
-# parse options | |
-# --with/--without parsing copied from autoconf's output | |
-while [ $# -gt 0 ]; do | |
- case $1 in | |
- --with-*) | |
- ac_option=$1 | |
- ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` | |
- ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` | |
- # Reject names that are not valid shell variable names. | |
- expr "x$ac_package" : ".*[^A-Za-z0-9_-]" >/dev/null && | |
- { echo "error: invalid package name: $ac_package"; exit 1; } | |
- ac_package=`echo $ac_package | sed 's/-/_/g'` | |
- case $ac_option in | |
- *=*) | |
- ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` | |
- ;; | |
- *) | |
- ac_optarg=yes | |
- ;; | |
- esac | |
- eval "with_$ac_package='$ac_optarg'" | |
- ;; | |
- --without-*) | |
- ac_option=$1 | |
- ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` | |
- ac_package=`expr "x$ac_option" : 'x-*without-\([^=]*\)'` | |
- # Reject names that are not valid shell variable names. | |
- expr "x$ac_package" : ".*[^A-Za-z0-9_-]" >/dev/null && | |
- { echo "error: invalid package name: $ac_package"; exit 1; } | |
- ac_package=`echo $ac_package | sed 's/-/_/g'` | |
- eval "with_$ac_package=no" | |
- ;; | |
- --debug=yes|--debug|-d) | |
- echo "Debug mode enabled." | |
- with_debug=yes | |
- ;; | |
- --debug=no) | |
- echo "Debug mode disabled." | |
- with_debug=no | |
- ;; | |
- --help|-help|-h) | |
- echo "usage: $0 [ options ]" | |
- echo "available options:" | |
- echo " --debug=yes (or -d) Enable debugging support." | |
- echo " --debug=no Disable debugging support." | |
- echo " --with-package Enable support for package in default lo… | |
- echo " --with-package=path Enable support for package installed in … | |
- echo " --without-package Disable support for package." | |
- echo " --help (or -h) Show this message." | |
- echo "" | |
- echo "relevant packages:" | |
- echo " libdb = BerkeleyDB" | |
- echo " mysql = MySQL database" | |
- exit 1 | |
- ;; | |
- *) | |
- echo "Unknown option '$1', try -h for help" | |
- exit 1 | |
- ;; | |
- esac | |
- shift | |
-done | |
- | |
-echo "Examining system setup..." | |
- | |
-# Some known configs: | |
-# | |
-# uname -s uname -r uname -m uname -p | |
-# ======== =========== ======== ======== | |
-# SunOS 5.6 sun4u sparc | |
-# Linux 2.2.17 i686 unknown | |
-# FreeBSD 4.1-RELEASE i386 i386 | |
- | |
-UNAME_S=`uname -s` | |
-UNAME_R=`uname -r` | |
- | |
-case "$UNAME_S" in | |
- Linux) | |
- if [ "$with_debug" = "yes" ]; then | |
- CCDBG="-g" | |
- LDDBG="-g" | |
- else | |
- CCDBG="-DNDEBUG" | |
- LDDBG="" | |
- fi | |
- CC=gcc | |
- CFLAGS="$CCDBG -D_UNIX -D_LINUX -Wall" | |
- CXX=g++ | |
- CXXFLAGS=${CFLAGS} | |
- AR=ar | |
- ARFLAGS="-rc" | |
- LD=gcc | |
- LDFLAGS="$LDDBG" | |
- SYSLIBS="" | |
- LIBDB_LIB="-ldb" | |
- MYSQL_LIB="-lmysqlclient" | |
- ;; | |
- FreeBSD) | |
- case "$UNAME_R" in | |
- 2.*) | |
- OSVER=20 | |
- ;; | |
- 3.*) | |
- OSVER=30 | |
- ;; | |
- 4.*) | |
- OSVER=40 | |
- ;; | |
- *) | |
- # Assume 5.0 + | |
- OSVER=50 | |
- ;; | |
- esac | |
- if [ "$with_debug" = "yes" ]; then | |
- CCDBG="-g" | |
- LDDBG="-g" | |
- else | |
- CCDBG="-DNDEBUG" | |
- LDDBG="" | |
- fi | |
- CC=gcc | |
- CFLAGS="$CCDBG -D_UNIX -D_BSD=$OSVER -Wall" | |
- CXX=g++ | |
- CXXFLAGS=${CFLAGS} | |
- AR=ar | |
- ARFLAGS="-rc" | |
- LD=gcc | |
- LDFLAGS="$LDDBG" | |
- SYSLIBS="" | |
- LIBDB_LIB="" | |
- MYSQL_LIB="-lmysqlclient" | |
- ;; | |
- OpenBSD) | |
- # I'm guessing OpenBSD looks mostly like FreeBSD 4.x | |
- OSVER=40 | |
- if [ "$with_debug" = "yes" ]; then | |
- CCDBG="-g" | |
- LDDBG="-g" | |
- else | |
- CCDBG="-DNDEBUG" | |
- LDDBG="" | |
- fi | |
- CC=gcc | |
- CFLAGS="$CCDBG -D_UNIX -D_BSD=$OSVER -Wall" | |
- CXX=g++ | |
- CXXFLAGS=${CFLAGS} | |
- AR=ar | |
- ARFLAGS="-rc" | |
- LD=gcc | |
- LDFLAGS="$LDDBG" | |
- SYSLIBS="" | |
- LIBDB_LIB="" | |
- MYSQL_LIB="-lmysqlclient" | |
- ;; | |
- Darwin) | |
- # I'm guessing Darwin looks mostly like FreeBSD 4.x | |
- OSVER=40 | |
- if [ "$with_debug" = "yes" ]; then | |
- CCDBG="-g" | |
- LDDBG="-g" | |
- else | |
- CCDBG="-DNDEBUG" | |
- LDDBG="" | |
- fi | |
- CC=cc | |
- CFLAGS="$CCDBG -D_UNIX -D_BSD=$OSVER -DNOLOCK -Wall" | |
- CXX=c++ | |
- CXXFLAGS=${CFLAGS} | |
- AR=ar | |
- ARFLAGS="-rc" | |
- LD=cc | |
- LDFLAGS="$LDDBG" | |
- SYSLIBS="" | |
- LIBDB_LIB="" | |
- MYSQL_LIB="-lmysqlclient" | |
- ;; | |
- SunOS) | |
- case "$UNAME_R" in | |
- 5.6) | |
- OSVER=56 | |
- ;; | |
- 5.7) | |
- OSVER=57 | |
- ;; | |
- 5.8) | |
- OSVER=58 | |
- ;; | |
- *) | |
- # Assume 9.0+ | |
- OSVER=59 | |
- ;; | |
- esac | |
- # Prefer gcc to the native cc here because I haven't tested with the | |
- # native compiler yet. | |
- type gcc >/dev/null 2>&1 | |
- if [ $? -eq 0 ]; then | |
- if [ "$with_debug" = "yes" ]; then | |
- CCDBG="-g" | |
- LDDBG="-g" | |
- else | |
- CCDBG="-DNDEBUG" | |
- LDDBG="" | |
- fi | |
- CC=gcc | |
- CFLAGS="$CCDBG -D_UNIX -D_SOLARIS=$OSVER -Wall" | |
- CXX=g++ | |
- CXXFLAGS=${CFLAGS} | |
- LD=gcc | |
- LDFLAGS="$LDDBG" | |
- else | |
- if [ "$with_debug" = "yes" ]; then | |
- CCDBG="-g" | |
- LDDBG="-g" | |
- else | |
- CCDBG="-DNDEBUG" | |
- LDDBG="" | |
- fi | |
- CC=cc | |
- CFLAGS="-DNDEBUG -D_UNIX -D_SOLARIS=$OSVER" | |
- CXX=c++ | |
- CXXFLAGS=${CFLAGS} | |
- LD=ld | |
- LDFLAGS="" | |
- fi | |
- AR=ar | |
- ARFLAGS="-rc" | |
- SYSLIBS="" | |
- LIBDB_LIB="-ldb" | |
- MYSQL_LIB="-lmysqlclient" | |
- ;; | |
- OSF1) | |
- if [ "$with_debug" = "yes" ]; then | |
- CCDBG="-g2" | |
- LDDBG="-g2" | |
- else | |
- CCDBG="-DNDEBUG" | |
- LDDBG="" | |
- fi | |
- CC=cc | |
- CFLAGS="$CCDBG -D_UNIX -D_OSF" | |
- CXX=cxx | |
- CXXFLAGS="-noexceptions ${CFLAGS}" | |
- AR=ar | |
- ARFLAGS="-rc" | |
- LD=ld | |
- LDFLAGS="" | |
- SYSLIBS="-lm" | |
- LIBDB_LIB="-ldb" | |
- MYSQL_LIB="-lmysqlclient" | |
- ;; | |
- *) | |
- if [ "$with_debug" = "yes" ]; then | |
- CCDBG="-g" | |
- LDDBG="-g" | |
- else | |
- CCDBG="-DNDEBUG" | |
- LDDBG="" | |
- fi | |
- CC=cc | |
- CFLAGS="$CCDBG -DNDEBUG -D_UNIX" | |
- CXX=c++ | |
- CXXFLAGS=${CFLAGS} | |
- AR=ar | |
- ARFLAGS="-rc" | |
- LD=ld | |
- LDFLAGS="$LDDBG" | |
- SYSLIBS="" | |
- LIBDB_LIB="-ldb" | |
- MYSQL_LIB="-lmysqlclient" | |
- ;; | |
-esac | |
- | |
-echo -n "Looking for compiler... " | |
-type $CC >/dev/null 2>&1 | |
-if [ $? -ne 0 ]; then | |
- echo "compiler '$CC' not found!" | |
- exit 1 | |
-else | |
- echo "$CC is executable." | |
-fi | |
- | |
-echo -n "Checking for BerkeleyDB... " | |
-if [ "$with_libdb" = "test" ]; then | |
- if [ -e /usr/local/BerkeleyDB.4.1/include/db.h ]; then | |
- with_libdb=/usr/local/BerkeleyDB.4.1 | |
- LIBDB_LIB="-ldb" | |
- elif [ -e /usr/include/db.h -o \ | |
- -e /usr/local/include/db.h ]; then | |
- with_libdb=yes | |
- else | |
- with_libdb=no | |
- fi | |
-fi | |
-if [ "$with_libdb" = "no" ]; then | |
- echo "disabled." | |
-else | |
- if [ "$with_libdb" != "yes" ]; then | |
- CFLAGS="$CFLAGS -I$with_libdb/include" | |
- LDFLAGS="$LDFLAGS -L$with_libdb/lib" | |
- fi | |
- CFLAGS="$CFLAGS -DHAVE_LIBDB" | |
- LDFLAGS="$LDFLAGS $LIBDB_LIB" | |
- echo "enabled." | |
-fi | |
- | |
-echo -n "Checking for MySQL... " | |
-if [ "$with_mysql" = "test" ]; then | |
- type mysql_config >/dev/null 2>&1 | |
- if [ $? -eq 0 ]; then | |
- with_mysql=yes | |
- CFLAGS="$CFLAGS `mysql_config --cflags`" | |
- LDFLAGS="$LDFLAGS `mysql_config --libs`" | |
- # mysql_config will add -lmysqlclient, don't add it twice | |
- MYSQL_LIB="" | |
- else | |
- with_mysql=no | |
- fi | |
-fi | |
-if [ "$with_mysql" = "no" ]; then | |
- echo "disabled." | |
-else | |
- if [ "$with_mysql" != "yes" ]; then | |
- CFLAGS="$CFLAGS -I$with_mysql/include" | |
- LDFLAGS="$LDFLAGS -L$with_mysql/lib" | |
- fi | |
- CFLAGS="$CFLAGS -DHAVE_MYSQL" | |
- LDFLAGS="$LDFLAGS $MYSQL_LIB" | |
- echo "enabled." | |
-fi | |
- | |
-for D in .; do | |
- cat $D/Makefile.in | sed "s%@CC@%${CC}%g | |
- s%@CXX@%${CXX}%g | |
- s%@AR@%${AR}%g | |
- s%@LD@%${LD}%g | |
- s%@CFLAGS@%${CFLAGS}%g | |
- s%@CXXFLAGS@%${CXXFLAGS}%g | |
- s%@ARFLAGS@%${ARFLAGS}%g | |
- s%@LDFLAGS@%${LDFLAGS}%g | |
- s%@SYSLIBS@%${SYSLIBS}%" > $D/Makefile || exit 1 | |
-done | |
- | |
-echo "Configuration successful." | |
-echo "Now run 'make all' and 'make install'." | |
-echo "" | |
diff --git a/dbdb.c b/dbdb.c | |
@@ -18,625 +18,11 @@ | |
#include "dbh.h" | |
#include "dbdb.h" | |
-#ifdef HAVE_LIBDB | |
- | |
-#define DBT_init( pdbt ) memset( pdbt, 0, sizeof(DBT) ) | |
- | |
-#if !defined(DB_VERSION_MAJOR) /* v1 */ | |
-#define dbx_get(dbp,kp,vp) dbp->get( dbp, kp, vp, 0 ) | |
-#define dbx_put(dbp,kp,vp) dbp->put( dbp, kp, vp, 0 ) | |
-#define dbx_fd(dbp,fd) fd = dbp->fd( dbp ) | |
-#else /* v2+ */ | |
-#define dbx_get(dbp,kp,vp) dbp->get( dbp, NULL, kp, vp, 0 ) | |
-#define dbx_put(dbp,kp,vp) dbp->put( dbp, NULL, kp, vp, 0 ) | |
-#define dbx_fd(dbp,fd) dbp->fd( dbp, &fd ) | |
-#endif /* DB_VERSION_MAJOR */ | |
- | |
-#if !defined(DB_VERSION_MAJOR) /* v1 */ | |
-typedef DB DBC; /* no separate cursor type */ | |
-#define dbx_createcursor(dbp,dbcp) ((dbcp = dbp) ? 0 : -1) | |
-#define dbx_destroycursor(dbcp) (dbcp = NULL) | |
-#define dbx_first(dbcp,kp,vp) dbcp->seq(dbcp,kp,vp,R_FIRST) | |
-#define dbx_next(dbcp,kp,vp) dbcp->seq(dbcp,kp,vp,R_NEXT) | |
-#define dbx_prev(dbcp,kp,vp) dbcp->seq(dbcp,kp,vp,R_PREV) | |
-#define dbx_last(dbcp,kp,vp) dbcp->seq(dbcp,kp,vp,R_LAST) | |
-#elif DB_VERSION_MAJOR == 2 | |
-#define dbx_createcursor(dbp,dbcp) dbp->cursor(dbp,NULL,&csrp) | |
-#define dbx_destroycursor(dbcp) dbcp->c_close(dbcp) | |
-#define dbx_first(dbcp,kp,vp) dbcp->c_get(dbcp,kp,vp,DB_FIRST) | |
-#define dbx_next(dbcp,kp,vp) dbcp->c_get(dbcp,kp,vp,DB_NEXT) | |
-#define dbx_prev(dbcp,kp,vp) dbcp->c_get(dbcp,kp,vp,DB_PREV) | |
-#define dbx_last(dbcp,kp,vp) dbcp->c_get(dbcp,kp,vp,DB_LAST) | |
-#else /* v3+ */ | |
-#define dbx_createcursor(dbp,dbcp) dbp->cursor(dbp,NULL,&csrp,0) | |
-#define dbx_destroycursor(dbcp) dbcp->c_close(dbcp) | |
-#define dbx_first(dbcp,kp,vp) dbcp->c_get(dbcp,kp,vp,DB_FIRST) | |
-#define dbx_next(dbcp,kp,vp) dbcp->c_get(dbcp,kp,vp,DB_NEXT) | |
-#define dbx_prev(dbcp,kp,vp) dbcp->c_get(dbcp,kp,vp,DB_PREV) | |
-#define dbx_last(dbcp,kp,vp) dbcp->c_get(dbcp,kp,vp,DB_LAST) | |
-#endif /* DB_VERSION_MAJOR */ | |
- | |
-static void char2DBT( DBT* pdbt, char* p ) | |
-{ | |
- pdbt->data = p; | |
- pdbt->size = strlen(p); | |
-} | |
- | |
-static void uint2DBT( DBT* pdbt, uint* p ) | |
-{ | |
- pdbt->data = p; | |
- pdbt->size = sizeof(uint); | |
-} | |
- | |
-static uint DBT2uint( DBT* pdbt ) | |
-{ | |
- uint n; | |
- memcpy( &n, pdbt->data, sizeof(n) ); | |
- return n; | |
-} | |
- | |
-dbh_t* dbdb_db_open( cpchar dbhost, cpchar dbname, cpchar dbuser, cpchar dbpas… | |
-{ | |
- dbhdb_t* pthis; | |
- | |
- uint dirlen; | |
- cpchar phome; | |
- struct stat st; | |
- | |
- pthis = (dbhdb_t*)malloc( sizeof(dbhdb_t) ); | |
- if( pthis == NULL ) | |
- { | |
- goto bail; | |
- } | |
- pthis->close = dbdb_db_close; | |
- pthis->opentable = dbdb_db_opentable; | |
- if( dbname != NULL && *dbname != '\0' ) | |
- { | |
- dirlen = strlen( dbname ); | |
- pthis->dir = strdup( dbname ); | |
- if( pthis->dir[dirlen-1] == '/' ) | |
- { | |
- pthis->dir[dirlen-1] = '\0'; | |
- } | |
- } | |
- else | |
- { | |
- phome = getenv( "HOME" ); | |
- if( phome == NULL || *phome == '\0' ) | |
- { | |
- phome = "."; | |
- } | |
- pthis->dir = (char*)malloc( strlen(phome)+5+1 ); | |
- if( pthis->dir == NULL ) | |
- { | |
- goto bail; | |
- } | |
- sprintf( pthis->dir, "%s/.bmf", phome ); | |
- } | |
- | |
- /* ensure config directory exists */ | |
- if( stat( pthis->dir, &st ) != 0 ) | |
- { | |
- if( errno == ENOENT ) | |
- { | |
- if( mkdir( pthis->dir, S_IRUSR|S_IWUSR|S_IXUSR ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
- } | |
- else | |
- { | |
- goto bail; | |
- } | |
- } | |
- else | |
- { | |
- if( !S_ISDIR( st.st_mode ) ) | |
- { | |
- goto bail; | |
- } | |
- } | |
- | |
-#if !defined(DB_VERSION_MAJOR) || DB_VERSION_MAJOR < 3 | |
- /* no initialization */ | |
-#else /* DB_VERSION_MAJOR >= 3 */ | |
- if( db_env_create( &pthis->envp, 0 ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
- if( pthis->envp->open( pthis->envp, pthis->dir, DB_INIT_LOCK|DB_INIT_MPOOL… | |
- { | |
- goto bail; | |
- } | |
-#endif /* DB_VERSION_MAJOR */ | |
- | |
- return (dbh_t*)pthis; | |
- | |
-bail: | |
- free( pthis ); | |
- return NULL; | |
-} | |
- | |
-bool_t dbdb_db_close( dbhdb_t* pthis ) | |
-{ | |
-#if !defined(DB_VERSION_MAJOR) || DB_VERSION_MAJOR < 3 | |
- /* no cleanup */ | |
-#else /* DB_VERSION_MAJOR >= 3 */ | |
- pthis->envp->close( pthis->envp, 0 ); | |
-#endif /* DB_VERSION_MAJOR */ | |
- | |
- free( pthis->dir ); | |
- pthis->dir = NULL; | |
- | |
- return true; | |
-} | |
- | |
-dbt_t* dbdb_db_opentable( dbhdb_t* pthis, cpchar table, bool_t rdonly ) | |
-{ | |
- dbtdb_t* ptable; | |
- DB* dbp; | |
- DBT key; | |
- DBT val; | |
- | |
- char szpath[PATH_MAX]; | |
- | |
- ptable = (dbtdb_t*)malloc( sizeof(dbtdb_t) ); | |
- if( ptable == NULL ) | |
- { | |
- return NULL; | |
- } | |
- ptable->close = dbdb_table_close; | |
- ptable->mergeclose = dbdb_table_mergeclose; | |
- ptable->unmergeclose = dbdb_table_unmergeclose; | |
- ptable->import = dbdb_table_import; | |
- ptable->export = dbdb_table_export; | |
- ptable->getmsgcount = dbdb_table_getmsgcount; | |
- ptable->getcount = dbdb_table_getcount; | |
- ptable->dbp = NULL; | |
- | |
- sprintf( szpath, "%s/%s.db", pthis->dir, table ); | |
-#if !defined(DB_VERSION_MAJOR) | |
- if( (dbp = dbopen( szpath, O_CREAT|O_RDWR, 0644, DB_BTREE, NULL)) == NULL ) | |
- { | |
- goto bail; | |
- } | |
-#elif DB_VERSION_MAJOR == 2 | |
- if( db_open( szpath, DB_BTREE, DB_CREATE, 0644, NULL, NULL, &dbp ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
-#elif (DB_VERSION_MAJOR == 3) || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR ==… | |
- ptable->envp = pthis->envp; | |
- if( db_create( &dbp, NULL, 0 ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
- if( dbp->open( dbp, szpath, NULL, DB_BTREE, DB_CREATE, 0644 ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
-#else /* v4.1+ */ | |
- ptable->envp = pthis->envp; | |
- if( db_create( &dbp, NULL, 0 ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
- if( dbp->open( dbp, NULL, szpath, NULL, DB_BTREE, DB_CREATE, 0644 ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
-#endif /* DB_VERSION_MAJOR */ | |
- ptable->dbp = dbp; | |
- | |
- DBT_init( &key ); | |
- DBT_init( &val ); | |
- ptable->nmsgs = 0; | |
- char2DBT( &key, MSGCOUNT_KEY ); | |
- if( dbx_get( dbp, &key, &val ) == 0 ) | |
- { | |
- ptable->nmsgs = DBT2uint( &val ); | |
- } | |
- | |
- return (dbt_t*)ptable; | |
- | |
-bail: | |
- free( ptable ); | |
- return NULL; | |
-} | |
- | |
-static bool_t dbdb_table_lock( dbtdb_t* pthis ) | |
-{ | |
-#ifndef NOLOCK | |
- struct flock lock; | |
- int fd; | |
- | |
- dbx_fd( pthis->dbp, fd ); | |
- memset( &lock, 0, sizeof(lock) ); | |
- lock.l_type = F_WRLCK; | |
- lock.l_start = 0; | |
- lock.l_whence = SEEK_SET; | |
- lock.l_len = 0; | |
- if( fcntl( fd, F_SETLKW, &lock ) != 0 ) | |
- { | |
- return false; | |
- } | |
-#endif /* ndef NOLOCK */ | |
- return true; | |
-} | |
- | |
-static bool_t dbdb_table_unlock( dbtdb_t* pthis ) | |
-{ | |
-#ifndef NOLOCK | |
- struct flock lock; | |
- int fd; | |
- | |
- dbx_fd( pthis->dbp, fd ); | |
- memset( &lock, 0, sizeof(lock) ); | |
- lock.l_type = F_UNLCK; | |
- lock.l_start = 0; | |
- lock.l_whence = SEEK_SET; | |
- lock.l_len = 0; | |
- if( fcntl( fd, F_SETLK, &lock ) != 0 ) | |
- { | |
- return false; | |
- } | |
-#endif /* ndef NOLOCK */ | |
- return true; | |
-} | |
- | |
-bool_t dbdb_table_close( dbtdb_t* pthis ) | |
-{ | |
- DB* dbp = pthis->dbp; | |
- | |
- if( dbp != NULL ) | |
- { | |
-#if !defined(DB_VERSION_MAJOR) /* v1 */ | |
- dbp->close( dbp ); | |
-#else /* v2+ */ | |
- dbp->close( dbp, 0 ); | |
-#endif /* DB_VERSION_MAJOR */ | |
- pthis->dbp = NULL; | |
- } | |
- | |
- return true; | |
-} | |
- | |
-bool_t dbdb_table_mergeclose( dbtdb_t* pthis, vec_t* pmsg ) | |
-{ | |
- DB* dbp = pthis->dbp; | |
- DBT key; | |
- DBT val; | |
- | |
- char szword[MAXWORDLEN+1]; | |
- uint count; | |
- veciter_t msgiter; | |
- str_t* pmsgstr; | |
- | |
- if( pthis->dbp == NULL ) | |
- { | |
- return false; | |
- } | |
- | |
- if( !dbdb_table_lock( pthis ) ) | |
- { | |
- return false; | |
- } | |
- | |
- pthis->nmsgs++; | |
- | |
- DBT_init( &key ); | |
- DBT_init( &val ); | |
- | |
- char2DBT( &key, MSGCOUNT_KEY ); | |
- uint2DBT( &val, &pthis->nmsgs ); | |
- dbx_put( dbp, &key, &val ); | |
- | |
- vec_first( pmsg, &msgiter ); | |
- pmsgstr = veciter_get( &msgiter ); | |
- | |
- while( pmsgstr != NULL ) | |
- { | |
- assert( pmsgstr->len <= MAXWORDLEN ); | |
- strncpylwr( szword, pmsgstr->p, pmsgstr->len ); | |
- szword[pmsgstr->len] = '\0'; | |
- count = db_getnewcount( &msgiter ); | |
- | |
- char2DBT( &key, szword ); | |
- if( dbx_get( dbp, &key, &val ) == 0 ) | |
- { | |
- count += DBT2uint( &val ); | |
- } | |
- char2DBT( &key, szword ); | |
- uint2DBT( &val, &count ); | |
- if( dbx_put( dbp, &key, &val ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
- | |
- veciter_next( &msgiter ); | |
- pmsgstr = veciter_get( &msgiter ); | |
- } | |
- | |
- veciter_destroy( &msgiter ); | |
- dbdb_table_unlock( pthis ); | |
- return dbdb_table_close( pthis ); | |
- | |
-bail: | |
- return false; | |
-} | |
- | |
-bool_t dbdb_table_unmergeclose( dbtdb_t* pthis, vec_t* pmsg ) | |
-{ | |
- DB* dbp = pthis->dbp; | |
- DBT key; | |
- DBT val; | |
- | |
- char szword[MAXWORDLEN+1]; | |
- uint count; | |
- veciter_t msgiter; | |
- str_t* pmsgstr; | |
- | |
- if( pthis->dbp == NULL ) | |
- { | |
- return false; | |
- } | |
- | |
- if( pthis->nmsgs > 0 ) | |
- { | |
- pthis->nmsgs--; | |
- } | |
- | |
- if( !dbdb_table_lock( pthis ) ) | |
- { | |
- return false; | |
- } | |
- | |
- DBT_init( &key ); | |
- DBT_init( &val ); | |
- | |
- char2DBT( &key, MSGCOUNT_KEY ); | |
- uint2DBT( &val, &pthis->nmsgs ); | |
- dbx_put( dbp, &key, &val ); | |
- | |
- vec_first( pmsg, &msgiter ); | |
- pmsgstr = veciter_get( &msgiter ); | |
- | |
- while( pmsgstr != NULL ) | |
- { | |
- assert( pmsgstr->len <= MAXWORDLEN ); | |
- strncpylwr( szword, pmsgstr->p, pmsgstr->len ); | |
- szword[pmsgstr->len] = '\0'; | |
- count = db_getnewcount( &msgiter ); | |
- | |
- char2DBT( &key, szword ); | |
- if( dbx_get( dbp, &key, &val ) == 0 ) | |
- { | |
- uint n = DBT2uint( &val ); | |
- n = (n > count) ? (n - count) : 0; | |
- char2DBT( &key, szword ); | |
- uint2DBT( &val, &n ); | |
- if( dbx_put( dbp, &key, &val ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
- } | |
- | |
- veciter_next( &msgiter ); | |
- pmsgstr = veciter_get( &msgiter ); | |
- } | |
- | |
- veciter_destroy( &msgiter ); | |
- dbdb_table_unlock( pthis ); | |
- return dbdb_table_close( pthis ); | |
- | |
-bail: | |
- return false; | |
-} | |
- | |
-bool_t dbdb_table_import( dbtdb_t* pthis, cpchar filename ) | |
-{ | |
- DB* dbp = pthis->dbp; | |
- int fd; | |
- struct stat st; | |
- char* pbuf; | |
- char* pbegin; | |
- char* pend; | |
- rec_t r; | |
- DBT key; | |
- DBT val; | |
- char szword[MAXWORDLEN+1]; | |
- | |
- if( pthis->dbp == NULL ) | |
- { | |
- return false; | |
- } | |
- if( (fd = open( filename, O_RDONLY, 0644 )) < 0 ) | |
- { | |
- return false; | |
- } | |
- if( fstat( fd, &st ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
- if( st.st_size == 0 ) | |
- { | |
- goto bail; | |
- } | |
- pbuf = (char*)malloc( st.st_size ); | |
- if( pbuf == NULL ) | |
- { | |
- goto bail; | |
- } | |
- if( read( fd, pbuf, st.st_size ) != st.st_size ) | |
- { | |
- goto bail; | |
- } | |
- | |
- DBT_init( &key ); | |
- DBT_init( &val ); | |
- | |
- if( sscanf( pbuf, BOGOFILTER_HEADER, &pthis->nmsgs ) != 1 ) | |
- { | |
- goto bail; | |
- } | |
- pbegin = pbuf; | |
- while( *pbegin != '\n' ) pbegin++; | |
- pbegin++; | |
- | |
- char2DBT( &key, MSGCOUNT_KEY ); | |
- uint2DBT( &val, &pthis->nmsgs ); | |
- if( dbx_put( dbp, &key, &val ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
- | |
- while( pbegin < pbuf + st.st_size ) | |
- { | |
- pend = pbegin; | |
- r.w.p = pbegin; | |
- r.w.len = 0; | |
- r.n = 0; | |
- | |
- while( *pend != '\n' ) | |
- { | |
- if( pend >= pbuf + st.st_size ) | |
- { | |
- goto bail; | |
- } | |
- *pend = tolower(*pend); | |
- if( *pend == ' ' ) | |
- { | |
- r.w.len = (pend-pbegin); | |
- r.n = strtol( pend+1, NULL, 10 ); | |
- } | |
- pend++; | |
- } | |
- if( pend > pbegin && *pbegin != '#' && *pbegin != ';' ) | |
- { | |
- if( r.w.len == 0 || r.w.len > MAXWORDLEN ) | |
- { | |
- fprintf( stderr, "dbh_loadfile: bad file format\n" ); | |
- goto bail; | |
- } | |
- strncpylwr( szword, r.w.p, r.w.len ); | |
- szword[r.w.len] = '\0'; | |
- char2DBT( &key, szword ); | |
- uint2DBT( &val, &r.n ); | |
- if( dbx_put( dbp, &key, &val ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
- } | |
- pbegin = pend+1; | |
- } | |
- | |
- free( pbuf ); | |
- close( fd ); | |
- | |
- return true; | |
- | |
-bail: | |
- return false; | |
-} | |
- | |
-bool_t dbdb_table_export( dbtdb_t* pthis, cpchar filename ) | |
-{ | |
- DB* dbp = pthis->dbp; | |
- int fd; | |
- char iobuf[IOBUFSIZE]; | |
- char* p; | |
- | |
- DBC* csrp; | |
- int rc; | |
- DBT key; | |
- DBT val; | |
- | |
- if( (fd = open( filename, O_CREAT|O_WRONLY|O_TRUNC, 0644 )) < 0 ) | |
- { | |
- goto bail; | |
- } | |
- if( dbx_createcursor( dbp, csrp ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
- | |
- DBT_init( &key ); | |
- DBT_init( &val ); | |
- | |
- p = iobuf; | |
- p += sprintf( p, BOGOFILTER_HEADER, pthis->nmsgs ); | |
- | |
- rc = dbx_first( csrp, &key, &val ); | |
- while( rc == 0 ) | |
- { | |
- assert( key.data != NULL && key.size <= MAXWORDLEN ); | |
- assert( val.data != NULL && val.size == sizeof(uint) ); | |
- if( key.size != MSGCOUNT_KEY_LEN || | |
- memcmp( key.data, MSGCOUNT_KEY, MSGCOUNT_KEY_LEN ) != 0 ) | |
- { | |
- memcpy( p, key.data, key.size ); p += key.size; | |
- *p++ = ' '; | |
- p += sprintf( p, "%u\n", DBT2uint(&val) ); | |
- if( p+TEXTDB_MAXLINELEN > (iobuf+1) ) | |
- { | |
- write( fd, iobuf, p-iobuf ); | |
- p = iobuf; | |
- } | |
- } | |
- rc = dbx_next( csrp, &key, &val ); | |
- } | |
- dbx_destroycursor( csrp ); | |
- if( p != iobuf ) | |
- { | |
- write( fd, iobuf, p-iobuf ); | |
- } | |
- close( fd ); | |
- return true; | |
- | |
-bail: | |
- return false; | |
-} | |
- | |
-uint dbdb_table_getmsgcount( dbtdb_t* pthis ) | |
-{ | |
- return pthis->nmsgs; | |
-} | |
- | |
-uint dbdb_table_getcount( dbtdb_t* pthis, str_t* pword ) | |
-{ | |
- DB* dbp = pthis->dbp; | |
- DBT key; | |
- DBT val; | |
- | |
- char szword[MAXWORDLEN+1]; | |
- uint count = 0; | |
- | |
- assert( pword->len <= MAXWORDLEN ); | |
- strncpylwr( szword, pword->p, pword->len ); | |
- szword[pword->len] = '\0'; | |
- count = 0; | |
- | |
- DBT_init( &key ); | |
- DBT_init( &val ); | |
- | |
- char2DBT( &key, szword ); | |
- if( dbx_get( dbp, &key, &val ) == 0 ) | |
- { | |
- count = DBT2uint( &val ); | |
- } | |
- | |
- return count; | |
-} | |
- | |
-#else /* def HAVE_LIBDB */ | |
- | |
dbh_t* dbdb_db_open( cpchar dbhost, cpchar dbname, cpchar dbuser, cpchar dbpas… | |
{ | |
return NULL; | |
} | |
-#endif /* def HAVE_LIBDB */ | |
- | |
#ifdef UNIT_TEST | |
int main( int argc, char** argv ) | |
{ | |
diff --git a/dbdb.h b/dbdb.h | |
@@ -10,52 +10,4 @@ | |
#ifndef _DBDB_H | |
#define _DBDB_H | |
-#ifdef HAVE_LIBDB | |
- | |
-#include <db.h> | |
- | |
-typedef struct _dbtdb dbtdb_t; | |
-struct _dbtdb | |
-{ | |
- bool_t (*close)(dbtdb_t*); | |
- bool_t (*mergeclose)(dbtdb_t*,vec_t*); | |
- bool_t (*unmergeclose)(dbtdb_t*,vec_t*); | |
- bool_t (*import)(dbtdb_t*,cpchar); | |
- bool_t (*export)(dbtdb_t*,cpchar); | |
- uint (*getmsgcount)(dbtdb_t*); | |
- uint (*getcount)(dbtdb_t*,str_t*); | |
- | |
- DB* dbp; /* db handle */ | |
-#if defined(DB_VERSION_MAJOR) && DB_VERSION_MAJOR >= 3 | |
- DB_ENV* envp; /* we don't own this */ | |
-#endif /* DB_VERSION_MAJOR */ | |
- uint nmsgs; /* number of messages in table (cached) */ | |
-}; | |
- | |
-typedef struct _dbhdb dbhdb_t; | |
-struct _dbhdb | |
-{ | |
- bool_t (*close)(dbhdb_t*); | |
- dbt_t* (*opentable)(dbhdb_t*,cpchar,bool_t); | |
- | |
- char* dir; /* directory for db files */ | |
-#if defined(DB_VERSION_MAJOR) && DB_VERSION_MAJOR >= 3 | |
- DB_ENV* envp; /* db environment */ | |
-#endif /* DB_VERSION_MAJOR */ | |
-}; | |
- | |
-dbh_t* dbdb_db_open( cpchar dbhost, cpchar dbname, cpchar dbuser, cpchar dbpa… | |
-bool_t dbdb_db_close( dbhdb_t* pthis ); | |
-dbt_t* dbdb_db_opentable( dbhdb_t* pthis, cpchar table, bool_t rdonly ); | |
- | |
-bool_t dbdb_table_close( dbtdb_t* pthis ); | |
-bool_t dbdb_table_mergeclose( dbtdb_t* pthis, vec_t* pmsg ); | |
-bool_t dbdb_table_unmergeclose( dbtdb_t* pthis, vec_t* pmsg ); | |
-bool_t dbdb_table_import( dbtdb_t* pthis, cpchar filename ); | |
-bool_t dbdb_table_export( dbtdb_t* pthis, cpchar filename ); | |
-uint dbdb_table_getmsgcount( dbtdb_t* pthis ); | |
-uint dbdb_table_getcount( dbtdb_t* pthis, str_t* pword ); | |
- | |
-#endif /* def HAVE_LIBDB */ | |
- | |
#endif /* ndef _DBDB_H */ | |
diff --git a/dbh.c b/dbh.c | |
@@ -18,7 +18,6 @@ | |
#include "dbh.h" | |
#include "dbtext.h" | |
#include "dbdb.h" | |
-#include "dbmysql.h" | |
/* | |
* get count for new (incoming) word. there may be duplicate entries for the | |
@@ -60,12 +59,6 @@ dbh_t* dbh_open( dbfmt_t dbfmt, cpchar dbhost, cpchar dbname… | |
case db_text: | |
pdb = (dbh_t*)dbtext_db_open( dbhost, dbname, dbuser, dbpass ); | |
break; | |
- case db_db: | |
- pdb = (dbh_t*)dbdb_db_open( dbhost, dbname, dbuser, dbpass ); | |
- break; | |
- case db_mysql: | |
- pdb = (dbh_t*) dbmysql_db_open( dbhost, dbname, dbuser, dbpass ); | |
- break; | |
default: | |
assert(false); | |
} | |
diff --git a/dbh.h b/dbh.h | |
@@ -13,9 +13,7 @@ | |
/* database formats */ | |
typedef enum | |
{ | |
- db_text, /* flat text */ | |
- db_db, /* libdb */ | |
- db_mysql /* mysql */ | |
+ db_text /* flat text */ | |
} dbfmt_t; | |
/* record/field structure */ | |
diff --git a/dbmysql.c b/dbmysql.c | |
@@ -1,545 +0,0 @@ | |
-/* $Id: dbmysql.c,v 1.9 2002/10/14 07:09:51 tommy Exp $ */ | |
- | |
-/* | |
- * Copyright (c) 2002 Tom Marshall <[email protected]> | |
- * | |
- * This program is free software. It may be distributed under the terms | |
- * in the file LICENSE, found in the top level of the distribution. | |
- * | |
- * dbmysql.c: mysql database handler | |
- */ | |
- | |
-#include "config.h" | |
-#include "dbg.h" | |
-#include "str.h" | |
-#include "lex.h" | |
-#include "vec.h" | |
- | |
-#include "dbh.h" | |
-#include "dbmysql.h" | |
- | |
-#ifdef HAVE_MYSQL | |
- | |
-#define MAXQUERY 256 | |
- | |
-static MYSQL* g_mysql = NULL; | |
- | |
-static void sql_escape( char* d, const char* s ) | |
-{ | |
- while( *s != '\0' ) | |
- { | |
- if( *s == '\'' ) | |
- { | |
- *d++ = '\''; | |
- } | |
- *d++ = tolower(*s++); | |
- } | |
-} | |
- | |
-dbh_t* dbmysql_db_open( cpchar dbhost, cpchar dbname, cpchar dbuser, cpchar db… | |
-{ | |
- dbhmysql_t* pthis; | |
- | |
- if( g_mysql == NULL ) | |
- { | |
- g_mysql = mysql_init( NULL ); | |
- if( g_mysql == NULL ) | |
- { | |
- return NULL; | |
- } | |
- } | |
- | |
- pthis = (dbhmysql_t*)malloc( sizeof(dbhmysql_t) ); | |
- if( pthis == NULL ) | |
- { | |
- perror( "malloc()" ); | |
- goto bail; | |
- } | |
- pthis->close = dbmysql_db_close; | |
- pthis->opentable = dbmysql_db_opentable; | |
- | |
- pthis->dbh = mysql_real_connect( g_mysql, dbhost, dbuser, dbpass, dbname, … | |
- if( pthis->dbh == NULL ) | |
- { | |
- goto bail; | |
- } | |
- | |
- | |
- return (dbh_t*)pthis; | |
- | |
-bail: | |
- fprintf( stderr, "cannot open mysql database '%s': %s\n", dbname, mysql_er… | |
- free( pthis ); | |
- return NULL; | |
-} | |
- | |
-bool_t dbmysql_db_close( dbhmysql_t* pthis ) | |
-{ | |
- if( pthis->dbh != NULL ) | |
- { | |
- mysql_close( pthis->dbh ); | |
- pthis->dbh = NULL; | |
- } | |
- return true; | |
-} | |
- | |
-dbt_t* dbmysql_db_opentable( dbhmysql_t* pthis, cpchar table, bool_t rdonly ) | |
-{ | |
- dbtmysql_t* ptable; | |
- | |
- char query[MAXQUERY]; | |
- MYSQL_RES* res; | |
- MYSQL_ROW row; | |
- | |
- ptable = (dbtmysql_t*)malloc( sizeof(dbtmysql_t) ); | |
- if( ptable == NULL ) | |
- { | |
- return NULL; | |
- } | |
- ptable->close = dbmysql_table_close; | |
- ptable->mergeclose = dbmysql_table_mergeclose; | |
- ptable->unmergeclose = dbmysql_table_unmergeclose; | |
- ptable->import = dbmysql_table_import; | |
- ptable->export = dbmysql_table_export; | |
- ptable->getmsgcount = dbmysql_table_getmsgcount; | |
- ptable->getcount = dbmysql_table_getcount; | |
- ptable->pdb = pthis; | |
- ptable->table = strdup( table ); | |
- ptable->nmsgs = 0; | |
- | |
- sprintf( query, "SELECT count FROM %s WHERE name='%s'", | |
- table, MSGCOUNT_KEY ); | |
- if( mysql_query( pthis->dbh, query ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
- if( (res = mysql_store_result( pthis->dbh )) == NULL ) | |
- { | |
- goto bail; | |
- } | |
- while( (row = mysql_fetch_row( res )) ) | |
- { | |
- ptable->nmsgs = atoi( row[0] ); | |
- } | |
- | |
- return (dbt_t*)ptable; | |
- | |
-bail: | |
- free( ptable->table ); | |
- free( ptable ); | |
- return NULL; | |
-} | |
- | |
-bool_t dbmysql_table_close( dbtmysql_t* pthis ) | |
-{ | |
- if( pthis->pdb != NULL ) | |
- { | |
- free( pthis->table ); | |
- pthis->table = NULL; | |
- pthis->pdb = NULL; | |
- } | |
- return true; | |
-} | |
- | |
-bool_t dbmysql_table_mergeclose( dbtmysql_t* pthis, vec_t* pmsg ) | |
-{ | |
- char szword[MAXWORDLEN+1]; | |
- char szsqlword[MAXWORDLEN*2+1]; | |
- veciter_t msgiter; | |
- str_t* pmsgstr; | |
- | |
- char query[MAXQUERY]; | |
- uint count; | |
- | |
- if( pthis->pdb == NULL || pthis->pdb->dbh == NULL ) | |
- { | |
- assert( false ); | |
- return false; | |
- } | |
- | |
- pthis->nmsgs++; | |
- | |
- sprintf( query, "UPDATE %s SET count=%u WHERE name='%s'", | |
- pthis->table, pthis->nmsgs, MSGCOUNT_KEY ); | |
- if( mysql_query( pthis->pdb->dbh, query ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
- if( mysql_affected_rows( pthis->pdb->dbh ) == 0 ) | |
- { | |
- sprintf( query, "INSERT INTO %s ( name, count ) VALUES ( '%s', %u )", | |
- pthis->table, MSGCOUNT_KEY, pthis->nmsgs ); | |
- mysql_query( pthis->pdb->dbh, query ); | |
- } | |
- | |
- vec_first( pmsg, &msgiter ); | |
- pmsgstr = veciter_get( &msgiter ); | |
- | |
- while( pmsgstr != NULL ) | |
- { | |
- assert( pmsgstr->len <= MAXWORDLEN ); | |
- strncpylwr( szword, pmsgstr->p, pmsgstr->len ); | |
- szword[pmsgstr->len] = '\0'; | |
- sql_escape( szsqlword, szword ); | |
- count = db_getnewcount( &msgiter ); | |
- | |
- sprintf( query, "UPDATE %s SET count=count+%u WHERE name='%s'", | |
- pthis->table, count, szsqlword ); | |
- if( mysql_query( pthis->pdb->dbh, query ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
- if( mysql_affected_rows( pthis->pdb->dbh ) == 0 ) | |
- { | |
- sprintf( query, "INSERT INTO %s ( name, count ) VALUES ( '%s', %u … | |
- pthis->table, szsqlword, count ); | |
- if( mysql_query( pthis->pdb->dbh, query ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
- if( mysql_affected_rows( pthis->pdb->dbh ) == 0 ) | |
- { | |
- goto bail; | |
- } | |
- } | |
- | |
- veciter_next( &msgiter ); | |
- pmsgstr = veciter_get( &msgiter ); | |
- } | |
- | |
- veciter_destroy( &msgiter ); | |
- return dbmysql_table_close( pthis ); | |
- | |
-bail: | |
- return false; | |
-} | |
- | |
-bool_t dbmysql_table_unmergeclose( dbtmysql_t* pthis, vec_t* pmsg ) | |
-{ | |
- char szword[MAXWORDLEN+1]; | |
- char szsqlword[MAXWORDLEN*2+1]; | |
- veciter_t msgiter; | |
- str_t* pmsgstr; | |
- | |
- char query[MAXQUERY]; | |
- uint count; | |
- | |
- if( pthis->pdb == NULL || pthis->pdb->dbh == NULL ) | |
- { | |
- assert( false ); | |
- return false; | |
- } | |
- | |
- if( pthis->nmsgs > 0 ) | |
- { | |
- pthis->nmsgs--; | |
- } | |
- | |
- sprintf( query, "UPDATE %s SET count=%u WHERE name='%s'", | |
- pthis->table, pthis->nmsgs, MSGCOUNT_KEY ); | |
- if( mysql_query( pthis->pdb->dbh, query ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
- if( mysql_affected_rows( pthis->pdb->dbh ) == 0 ) | |
- { | |
- sprintf( query, "INSERT INTO %s ( name, count ) VALUES ( '%s', %u )", | |
- pthis->table, MSGCOUNT_KEY, pthis->nmsgs ); | |
- mysql_query( pthis->pdb->dbh, query ); | |
- } | |
- | |
- vec_first( pmsg, &msgiter ); | |
- pmsgstr = veciter_get( &msgiter ); | |
- | |
- while( pmsgstr != NULL ) | |
- { | |
- assert( pmsgstr->len <= MAXWORDLEN ); | |
- strncpylwr( szword, pmsgstr->p, pmsgstr->len ); | |
- szword[pmsgstr->len] = '\0'; | |
- sql_escape( szsqlword, szword ); | |
- count = db_getnewcount( &msgiter ); | |
- | |
- sprintf( query, "UPDATE %s SET count=GREATEST(0,count-%u) WHERE name='… | |
- pthis->table, count, szsqlword ); | |
- if( mysql_query( pthis->pdb->dbh, query ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
- if( mysql_affected_rows( pthis->pdb->dbh ) == 0 ) | |
- { | |
- /* this should not happen, so write with count=0 */ | |
- sprintf( query, "INSERT INTO %s ( name, count ) VALUES ( '%s', 0 )… | |
- pthis->table, szsqlword ); | |
- if( mysql_query( pthis->pdb->dbh, query ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
- if( mysql_affected_rows( pthis->pdb->dbh ) == 0 ) | |
- { | |
- goto bail; | |
- } | |
- } | |
- | |
- veciter_next( &msgiter ); | |
- pmsgstr = veciter_get( &msgiter ); | |
- } | |
- | |
- veciter_destroy( &msgiter ); | |
- return dbmysql_table_close( pthis ); | |
- | |
-bail: | |
- return false; | |
-} | |
- | |
-bool_t dbmysql_table_import( dbtmysql_t* pthis, cpchar filename ) | |
-{ | |
- int fd; | |
- struct stat st; | |
- char* pbuf; | |
- char* pbegin; | |
- char* pend; | |
- rec_t r; | |
- char szword[MAXWORDLEN+1]; | |
- char szsqlword[MAXWORDLEN*2+1]; | |
- char query[MAXQUERY]; | |
- | |
- if( pthis->pdb == NULL || pthis->pdb->dbh == NULL ) | |
- { | |
- return false; | |
- } | |
- if( (fd = open( filename, O_RDONLY, 0644 )) < 0 ) | |
- { | |
- return false; | |
- } | |
- if( fstat( fd, &st ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
- if( st.st_size == 0 ) | |
- { | |
- goto bail; | |
- } | |
- pbuf = (char*)malloc( st.st_size ); | |
- if( pbuf == NULL ) | |
- { | |
- goto bail; | |
- } | |
- if( read( fd, pbuf, st.st_size ) != st.st_size ) | |
- { | |
- goto bail; | |
- } | |
- | |
- if( sscanf( pbuf, BOGOFILTER_HEADER, &pthis->nmsgs ) != 1 ) | |
- { | |
- goto bail; | |
- } | |
- pbegin = pbuf; | |
- while( *pbegin != '\n' ) pbegin++; | |
- pbegin++; | |
- | |
- sprintf( query, "INSERT INTO %s ( name, count ) VALUES ( '%s', %u )", | |
- pthis->table, MSGCOUNT_KEY, pthis->nmsgs ); | |
- mysql_query( pthis->pdb->dbh, query ); | |
- if( mysql_affected_rows( pthis->pdb->dbh ) == 0 ) | |
- { | |
- goto bail; | |
- } | |
- | |
- while( pbegin < pbuf + st.st_size ) | |
- { | |
- pend = pbegin; | |
- r.w.p = pbegin; | |
- r.w.len = 0; | |
- r.n = 0; | |
- | |
- while( *pend != '\n' ) | |
- { | |
- if( pend >= pbuf + st.st_size ) | |
- { | |
- goto bail; | |
- } | |
- *pend = tolower(*pend); | |
- if( *pend == ' ' ) | |
- { | |
- r.w.len = (pend-pbegin); | |
- r.n = strtol( pend+1, NULL, 10 ); | |
- } | |
- pend++; | |
- } | |
- if( pend > pbegin && *pbegin != '#' && *pbegin != ';' ) | |
- { | |
- if( r.w.len == 0 || r.w.len > MAXWORDLEN ) | |
- { | |
- fprintf( stderr, "dbh_loadfile: bad file format\n" ); | |
- goto bail; | |
- } | |
- strncpylwr( szword, r.w.p, r.w.len ); | |
- szword[r.w.len] = '\0'; | |
- sql_escape( szsqlword, szword ); | |
- | |
- sprintf( query, "INSERT INTO %s ( name, count ) VALUES ( '%s', %u … | |
- pthis->table, szsqlword, r.n ); | |
- if( mysql_query( pthis->pdb->dbh, query ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
- if( mysql_affected_rows( pthis->pdb->dbh ) == 0 ) | |
- { | |
- goto bail; | |
- } | |
- } | |
- pbegin = pend+1; | |
- } | |
- | |
- return true; | |
- | |
-bail: | |
- return false; | |
-} | |
- | |
-bool_t dbmysql_table_export( dbtmysql_t* pthis, cpchar filename ) | |
-{ | |
- int fd; | |
- char iobuf[IOBUFSIZE]; | |
- char* p; | |
- | |
- char query[MAXQUERY]; | |
- MYSQL_RES* res; | |
- MYSQL_ROW row; | |
- | |
- if( (fd = open( filename, O_CREAT|O_WRONLY|O_TRUNC, 0644 )) < 0 ) | |
- { | |
- return false; | |
- } | |
- | |
- p += sprintf( p, BOGOFILTER_HEADER, pthis->nmsgs ); | |
- | |
- sprintf( query, "SELECT name, count FROM %s", | |
- pthis->table ); | |
- if( mysql_query( pthis->pdb->dbh, query ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
- if( mysql_affected_rows( pthis->pdb->dbh ) == 0 ) | |
- { | |
- goto bail; | |
- } | |
- | |
- while( (row = mysql_fetch_row( res )) ) | |
- { | |
- if( strcmp( row[0], MSGCOUNT_KEY ) == 0 ) | |
- { | |
- continue; | |
- } | |
- | |
- p += sprintf( p, "%s %s\n", row[0], row[1] ); | |
- if( p+TEXTDB_MAXLINELEN > (iobuf+1) ) | |
- { | |
- write( fd, iobuf, p-iobuf ); | |
- p = iobuf; | |
- } | |
- } | |
- if( p != iobuf ) | |
- { | |
- write( fd, iobuf, p-iobuf ); | |
- } | |
- close( fd ); | |
- | |
- return true; | |
- | |
-bail: | |
- return false; | |
-} | |
- | |
-uint dbmysql_table_getmsgcount( dbtmysql_t* pthis ) | |
-{ | |
- return pthis->nmsgs; | |
-} | |
- | |
-uint dbmysql_table_getcount( dbtmysql_t* pthis, str_t* pword ) | |
-{ | |
- uint count = 0; | |
- char szword[MAXWORDLEN+1]; | |
- char szsqlword[MAXWORDLEN*2+1]; | |
- | |
- char query[MAXQUERY]; | |
- MYSQL_RES* res; | |
- MYSQL_ROW row; | |
- | |
- assert( pword->len <= MAXWORDLEN ); | |
- strncpylwr( szword, pword->p, pword->len ); | |
- szword[pword->len] = '\0'; | |
- sql_escape( szsqlword, szword ); | |
- sprintf( query, "SELECT count FROM %s WHERE name='%s'", | |
- pthis->table, szsqlword ); | |
- if( mysql_query( pthis->pdb->dbh, query ) != 0 ) | |
- { | |
- goto bail; | |
- } | |
- if( (res = mysql_store_result( pthis->pdb->dbh )) == NULL ) | |
- { | |
- goto bail; | |
- } | |
- while( (row = mysql_fetch_row( res )) ) | |
- { | |
- count = atoi( row[0] ); | |
- } | |
- | |
-bail: | |
- return count; | |
-} | |
- | |
-#else /* def HAVE_MYSQL */ | |
- | |
-dbh_t* dbmysql_db_open( cpchar dbhost, cpchar dbname, cpchar dbuser, cpchar db… | |
-{ | |
- return NULL; | |
-} | |
- | |
-#endif /* def HAVE_MYSQL */ | |
- | |
-#ifdef UNIT_TEST | |
-int main( int argc, char** argv ) | |
-{ | |
- dbh_t* pdb; | |
- veciter_t iter; | |
- str_t* pstr; | |
- uint n; | |
- | |
- if( argc != 2 ) | |
- { | |
- fprintf( stderr, "usage: %s <file>\n", argv[0] ); | |
- return 1; | |
- } | |
- | |
- for( n = 0; n < 100; n++ ) | |
- { | |
- pdb = dbh_open( "testlist", true ); | |
- | |
- vec_first( &db, &iter ); | |
- while( (pstr = veciter_get( &iter )) != NULL ) | |
- { | |
- char buf[MAXWORDLEN+32]; | |
- char* p; | |
- if( pstr->len > 200 ) | |
- { | |
- fprintf( stderr, "str too long: %u chars\n", pstr->len ); | |
- break; | |
- } | |
- p = buf; | |
- strcpy( buf, "str: " ); | |
- p += 6; | |
- memcpy( p, pstr->p, pstr->len ); | |
- p += pstr->len; | |
- sprintf( p, " %u", pstr->count ); | |
- puts( buf ); | |
- | |
- veciter_next( &iter ); | |
- } | |
- | |
- dbh_close( &db ); | |
- } | |
- | |
- return 0; | |
-} | |
-#endif /* def UNIT_TEST */ | |
diff --git a/dbmysql.h b/dbmysql.h | |
@@ -1,60 +0,0 @@ | |
-/* $Id: dbmysql.h,v 1.4 2002/10/06 06:46:53 tommy Exp $ */ | |
- | |
-/* | |
- * Copyright (c) 2002 Tom Marshall <[email protected]> | |
- * | |
- * This program is free software. It may be distributed under the terms | |
- * in the file LICENSE, found in the top level of the distribution. | |
- */ | |
- | |
-#ifndef _DBMYSQL_H | |
-#define _DBMYSQL_H | |
- | |
-#ifdef HAVE_MYSQL | |
- | |
-#include "mysql.h" | |
- | |
-typedef struct _dbtmysql dbtmysql_t; | |
-struct _dbtmysql | |
-{ | |
- bool_t (*close)(dbtmysql_t*); | |
- bool_t (*mergeclose)(dbtmysql_t*,vec_t*); | |
- bool_t (*unmergeclose)(dbtmysql_t*,vec_t*); | |
- bool_t (*import)(dbtmysql_t*,cpchar); | |
- bool_t (*export)(dbtmysql_t*,cpchar); | |
- uint (*getmsgcount)(dbtmysql_t*); | |
- uint (*getcount)(dbtmysql_t*,str_t*); | |
- | |
- struct _dbhmysql* pdb; | |
- char* table; /* table name */ | |
- uint nmsgs; /* number of messages in table (cached) */ | |
-}; | |
- | |
-typedef struct _dbhmysql dbhmysql_t; | |
-struct _dbhmysql | |
-{ | |
- bool_t (*close)(dbhmysql_t*); | |
- dbt_t* (*opentable)(dbhmysql_t*,cpchar,bool_t); | |
- | |
- MYSQL* dbh; /* database handle, if currently open */ | |
-}; | |
- | |
-dbh_t* dbmysql_db_open( cpchar dbhost, cpchar dbname, cpchar dbuser, cpchar d… | |
-bool_t dbmysql_db_close( dbhmysql_t* pthis ); | |
-dbt_t* dbmysql_db_opentable( dbhmysql_t* pthis, cpchar table, bool_t rdonly ); | |
- | |
-bool_t dbmysql_table_close( dbtmysql_t* pthis ); | |
-bool_t dbmysql_table_mergeclose( dbtmysql_t* pthis, vec_t* pmsg ); | |
-bool_t dbmysql_table_unmergeclose( dbtmysql_t* pthis, vec_t* pmsg ); | |
-bool_t dbmysql_table_import( dbtmysql_t* pthis, cpchar filename ); | |
-bool_t dbmysql_table_export( dbtmysql_t* pthis, cpchar filename ); | |
-uint dbmysql_table_getmsgcount( dbtmysql_t* pthis ); | |
-uint dbmysql_table_getcount( dbtmysql_t* pthis, str_t* pword ); | |
- | |
-#else /* def HAVE_MYSQL */ | |
- | |
-dbh_t* dbmysql_db_open( cpchar dbhost, cpchar dbname, cpchar dbuser, cpchar d… | |
- | |
-#endif /* def HAVE_MYSQL */ | |
- | |
-#endif /* ndef _DBMYSQL_H */ |