/* * Copyright (c) 1999 Hideki Sakurada * * 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, 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. */ #include #include #include #include #include #include #include #include #include "config.h" #include "err.h" #include "dic.h" #include "dic_cdb.h" struct dic *dic_cdb_open(struct dic *d, char *path) { struct dic_cdb_internal *internal; if ((internal = malloc(sizeof(struct dic_cdb_internal))) == NULL) { err(LOG_ERR, "dic_cdb_open(%s): %s\n", path, strerror(errno)); exit(1); } if ((internal->fd = open(path, O_RDONLY, 0)) < 0) { err(LOG_ERR, "dic_cdb_open(%s): %s\n", path, strerror(errno)); exit(1); } d->internal = (void *)internal; d->search = dic_cdb_search; d->close = dic_cdb_close; return d; } char *dic_cdb_search(struct dic *d, char *key, int keylen) { unsigned int dlen; int fd = ((struct dic_cdb_internal *)(d->internal))->fd; char *buf = d->buf; switch(cdb_seek(fd, key, keylen, &dlen)) { case -1: /* error */ err(LOG_ERR, "cdb_search: error in cdb_seek\n"); exit(1); case 1: /* found */ if (dlen < DIC_BUFSIZE) { /* ensure terminator '\0' is writable */ if (read(fd, buf, dlen) != dlen) { err(LOG_ERR, "cdb_search: %s\n", strerror(errno)); exit(1); } buf[dlen] = '\0'; return buf; } else { err(LOG_WARNING, "cdb_search: too long entry for \"%.*s\"\n", keylen, key); return NULL; } case 0: /* notfound */ return NULL; } /* must be bug */ err(LOG_ERR, "cdb_search: invalid return from cdb_seek\n"); exit(1); } int dic_cdb_close(struct dic *d) { struct dic_cdb_internal *internal = (struct dic_cdb_internal *)(d->internal); close(internal->fd); free(internal); free(d); return 0; }