/*
 * squid_db: Squid external acl helper for matching against DB databases
 *
 * Copyright (C) 2010 Alan Mizrahi <alan at mizrahi dot com dot ve>
 *
 * 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 2 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
 * GNU General Public License for more details.
 *
 * 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, USA.
 */

#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
#include <db.h>
#include <signal.h>

#define PROGNAME "squid_db"

DB **db = NULL;
int dbNum = 0;
char **dbFiles = NULL;

/* Loads databases from specified files
 * This is called at program startup and when SIGHUP is received
 */
void openDatabases() {
	int i;

	if (db) {
		for(i = 0; i < dbNum; i++) {
			db[i]->close(db[i], 0);
		}
	}
	if (db == NULL) {
		if (!(db = malloc(dbNum * sizeof(DB *)))) {
			perror("malloc");
			exit(1);
		}
	}
	for (i = 0; i < dbNum; i++) {
		if (db_create(&db[i], NULL, 0)) {
			fprintf(stderr, "%s: Error creating db environment: %s\n", PROGNAME, strerror(errno));
			exit(1);
		}
		if (db[i]->open(db[i], NULL, dbFiles[i], NULL, DB_HASH, DB_RDONLY, S_IRUSR)) {
			fprintf(stderr, "%s: Error opening %s: %s\n", PROGNAME, dbFiles[i], strerror(errno));
			exit(1);
		}
	}
}

int main(int argc, char **argv) {
	char dest[256];
	DBT key;
	int i;

	if (argc <= 1) {
		fprintf(stderr, "Usage: %s db_file [...]\n", PROGNAME);
		exit(1);
	}
	dbNum = argc - 1;
	dbFiles = argv + 1;
	
	openDatabases();
	signal(SIGHUP, openDatabases);

	memset(&key, 0, sizeof(key));
	key.data = dest;

	while (fgets(dest, sizeof(dest), stdin)) {
		key.size = strlen(dest) - 1;
		
		int found = -1;
		for (i = 0; i < dbNum; i++) {
			if (db[i]->exists(db[i], NULL, &key, 0) != DB_NOTFOUND) {
				found = i;
				break;
			}
			
		}
		/* check if host is in a db and return appropriate result to squid */
		if (found == -1)
			puts("OK");
		else
			printf("ERR log=%s\n", dbFiles[i]);
	}
	exit(0);
}
