diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2005-06-04 17:25:18 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2005-06-04 17:25:18 +0000 |
commit | 6edbc8f983af5fa40ae0f1b6a34b5f22d6c668ce (patch) | |
tree | e5b4b0f1d5b1bcc446051beffe7b0eba8b8d45cb | |
parent | d75711ebcc2cbf726a7430241319caf9bc3ca3a6 (diff) | |
download | mailfromd-6edbc8f983af5fa40ae0f1b6a34b5f22d6c668ce.tar.gz mailfromd-6edbc8f983af5fa40ae0f1b6a34b5f22d6c668ce.tar.bz2 |
Added to the repository
git-svn-id: file:///svnroot/mailfromd/trunk@21 7a8a7f39-df28-0410-adc6-e0d955640f24
-rw-r--r-- | src/mu_dbm.c | 503 | ||||
-rw-r--r-- | src/mu_dbm.h | 79 | ||||
-rw-r--r-- | src/strtok_r.c | 66 |
3 files changed, 648 insertions, 0 deletions
diff --git a/src/mu_dbm.c b/src/mu_dbm.c new file mode 100644 index 00000000..8045111c --- /dev/null +++ b/src/mu_dbm.c @@ -0,0 +1,503 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + + GNU Mailutils 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. + + GNU Mailutils 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 GNU Mailutils; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301 USA */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif +#include <errno.h> +#include <mailutils/errno.h> +#include <mu_dbm.h> + +int +mu_fcheck_perm (int fd, int mode) +{ + struct stat st; + + if (fstat (fd, &st) == -1) + { + if (errno == ENOENT) + return 0; + else + return 1; + } + if ((st.st_mode & 0777) != mode) + { + errno = MU_ERR_UNSAFE_PERMS; + return 1; + } + return 0; +} + +int +mu_check_perm (const char *name, int mode) +{ + struct stat st; + + if (mode == 0) + return 0; + if (stat (name, &st) == -1) + { + if (errno == ENOENT) + return 0; + else + return 1; + } + if ((st.st_mode & 0777) != mode) + { + errno = MU_ERR_UNSAFE_PERMS; + return 1; + } + return 0; +} + +#if defined(WITH_GDBM) + +#define DB_SUFFIX ".db" + +int +mu_dbm_stat (char *name, struct stat *sb) +{ + int rc; + char *pfname = malloc (strlen (name) + sizeof DB_SUFFIX); + if (!pfname) + return ENOMEM; + strcat (strcpy (pfname, name), DB_SUFFIX); + rc = stat (pfname, sb); + free (pfname); + return rc; +} + +int +mu_dbm_open (char *name, DBM_FILE *db, int flags, int mode) +{ + int f; + char *pfname; + + pfname = malloc (strlen (name) + sizeof DB_SUFFIX); + if (!pfname) + return -1; + + strcat (strcpy (pfname, name), DB_SUFFIX); + if (mu_check_perm (pfname, mode)) + { + free (pfname); + return -1; + } + + switch (flags) + { + case MU_STREAM_CREAT: + f = GDBM_NEWDB; + break; + case MU_STREAM_READ: + f = GDBM_READER; + break; + case MU_STREAM_RDWR: + f = GDBM_WRCREAT; + break; + default: + free (pfname); + errno = EINVAL; + return 1; + } + *db = gdbm_open(pfname, 512, f, mode, NULL); + free (pfname); + return *db == NULL; +} + +int +mu_dbm_close (DBM_FILE db) +{ + gdbm_close(db); + return 0; +} + +int +mu_dbm_fetch (DBM_FILE db, DBM_DATUM key, DBM_DATUM *ret) +{ + *ret = gdbm_fetch(db, key); + return ret->dptr == NULL; +} + +int +mu_dbm_delete (DBM_FILE db, DBM_DATUM key) +{ + return gdbm_delete (db, key); +} + +int +mu_dbm_insert (DBM_FILE db, DBM_DATUM key, DBM_DATUM contents, int replace) +{ + return gdbm_store(db, key, contents, + replace ? GDBM_REPLACE : GDBM_INSERT); +} + +DBM_DATUM +mu_dbm_firstkey (DBM_FILE db) +{ + return gdbm_firstkey (db); +} + +DBM_DATUM +mu_dbm_nextkey (DBM_FILE db, DBM_DATUM key) +{ + return gdbm_nextkey (db, key); +} + +#elif defined(WITH_BDB2) + +#define DB_SUFFIX ".db" + +int +mu_dbm_stat (char *name, struct stat *sb) +{ + int rc; + char *pfname = xmalloc (strlen (name) + sizeof DB_SUFFIX); + strcat (strcpy (pfname, name), DB_SUFFIX); + rc = stat (pfname, sb); + free (pfname); + return rc; +} + +int +mu_dbm_open (char *name, DBM_FILE *dbm, int flags, int mode) +{ + int f, rc; + DB *db; + char *pfname; + + pfname = xmalloc (strlen (name) + sizeof DB_SUFFIX); + strcat (strcpy (pfname, name), DB_SUFFIX); + if (mu_check_perm (pfname, mode)) + { + free (pfname); + return -1; + } + + switch (flags) + { + case MU_STREAM_CREAT: + f = DB_CREATE|DB_TRUNCATE; + break; + case MU_STREAM_READ: + f = DB_RDONLY; + break; + case MU_STREAM_RDWR: + f = DB_CREATE; + break; + default: + free (pfname); + errno = EINVAL; + return -1; + } + + rc = db_open (pfname, DB_HASH, f, mode, NULL, NULL, &db); + free (pfname); + if (rc) + return -1; + + *dbm = malloc (sizeof **dbm); + if (!*dbm) + { + db->close (db, 0); + errno = ENOMEM; + return -1; + } + (*dbm)->db = db; + (*dbm)->dbc = NULL; + return 0; +} + +int +mu_dbm_close (DBM_FILE db) +{ + db->db->close (db->db, 0); + free (db); + return 0; +} + +int +mu_dbm_fetch (DBM_FILE db, DBM_DATUM key, DBM_DATUM *ret) +{ + return db->db->get (db->db, NULL, &key, ret, 0); +} + +int +mu_dbm_delete (DBM_FILE db, DBM_DATUM key) +{ + return db->db->del (db->db, NULL, &key, 0); +} + +int +mu_dbm_insert (DBM_FILE db, DBM_DATUM key, DBM_DATUM contents, int replace) +{ + /*FIXME: replace unused*/ + return db->db->put (db->db, NULL, &key, &contents, 0); +} + +DBM_DATUM +mu_dbm_firstkey (DBM_FILE db) +{ + DBT key, data; + int ret; + + memset(&key, 0, sizeof key); + memset(&data, 0, sizeof data); + + if (!db->dbc) + { + if (db->db->cursor(db->db, NULL, &db->dbc BDB2_CURSOR_LASTARG) != 0) + return key; + } + + if ((ret = db->dbc->c_get(db->dbc, &key, &data, DB_FIRST)) != 0) + { + key.data = NULL; + key.size = 0; + if (ret == DB_NOTFOUND) + errno = MU_ERR_NOENT; + else + errno = ret; + } + return key; +} + +DBM_DATUM +mu_dbm_nextkey (DBM_FILE db, DBM_DATUM pkey /*unused*/) +{ + DBT key, data; + int ret; + + memset(&key, 0, sizeof key); + memset(&data, 0, sizeof data); + + if (!db->dbc) + return key; + + if ((ret = db->dbc->c_get(db->dbc, &key, &data, DB_NEXT)) != 0) + { + key.data = NULL; + key.size = 0; + if (ret == DB_NOTFOUND) + errno = MU_ERR_NOENT; + else + errno = ret; + } + return key; +} + +#elif defined(WITH_NDBM) + +#define DB_SUFFIX ".pag" + +int +mu_dbm_stat (char *name, struct stat *sb) +{ + int rc; + char *pfname = xmalloc (strlen (name) + sizeof DB_SUFFIX); + strcat (strcpy (pfname, name), DB_SUFFIX); + rc = stat (pfname, sb); + free (pfname); + return rc; +} + +int +mu_dbm_open (char *name, DBM_FILE *db, int flags, int mode) +{ + int f; + + switch (flags) + { + case MU_STREAM_CREAT: + f = O_CREAT|O_TRUNC|O_RDWR; + break; + case MU_STREAM_READ: + f = O_RDONLY; + break; + case MU_STREAM_RDWR: + f = O_CREAT|O_RDWR; + break; + default: + errno = EINVAL; + return -1; + } + *db = dbm_open (name, f, mode); + if (!*db) + return -1; + + if (mu_fcheck_perm (dbm_dirfno (*db), mode) + || mu_fcheck_perm (dbm_pagfno (*db), mode)) + { + dbm_close (*db); + return 1; + } + + return 0; +} + +int +mu_dbm_close (DBM_FILE db) +{ + dbm_close(db); + return 0; +} + +int +mu_dbm_fetch (DBM_FILE db, DBM_DATUM key, DBM_DATUM *ret) +{ + *ret = dbm_fetch(db, key); + return ret->dptr == NULL; +} + +int +mu_dbm_delete (DBM_FILE db, DBM_DATUM key) +{ + return dbm_delete (db, key); +} + +int +mu_dbm_insert (DBM_FILE db, DBM_DATUM key, DBM_DATUM contents, int replace) +{ + return dbm_store(db, key, contents, replace ? DBM_REPLACE : DBM_INSERT); +} + +DBM_DATUM +mu_dbm_firstkey (DBM_FILE db) +{ + return dbm_firstkey (db); +} + +DBM_DATUM +mu_dbm_nextkey (DBM_FILE db, DBM_DATUM key) +{ + return dbm_nextkey (db, key); +} + +#elif defined(WITH_OLD_DBM) + +#define DB_SUFFIX ".pag" + +int +mu_dbm_stat (char *name, struct stat *sb) +{ + int rc; + char *pfname = xmalloc (strlen (name) + sizeof DB_SUFFIX); + strcat (strcpy (pfname, name), DB_SUFFIX); + rc = stat (pfname, sb); + free (pfname); + return rc; +} + +/*ARGSUSED*/ +int +mu_dbm_open (char *name, DBM_FILE *db, int flags, int mode) +{ + int f; + + switch (flags) + { + case MU_STREAM_CREAT: + f = O_CREAT|O_TRUNC|O_RDWR; + break; + case MU_STREAM_READ: + f = O_RDONLY; + break; + case MU_STREAM_RDWR: + f = O_CREAT|O_RDWR; + break; + default: + return -1; + } + + if (f & O_CREAT) + { + char *p; + int fd; + + p = xmalloc(strlen(name)+5); + strcat(strcpy(p, name), ".pag"); + fd = open(p, f, mode); + free(p); + if (fd < 0) + return -1; + close(fd); + + p = xmalloc(strlen(name)+5); + strcat(strcpy(p, name), ".dir"); + fd = open(p, f, mode); + free(p); + if (fd < 0) + return -1; + close(fd); + } + + return dbminit(name); +} + +/*ARGSUSED*/ +int +mu_dbm_close (DBM_FILE db) +{ + dbmclose(); + return 0; +} + +/*ARGSUSED*/ +int +mu_dbm_fetch (DBM_FILE db, DBM_DATUM key, DBM_DATUM *ret) +{ + *ret = fetch(key); + return ret->dptr == NULL; +} + +int +mu_dbm_delete (DBM_FILE db, DBM_DATUM key) +{ + return delete (key); +} + +int +mu_dbm_insert (DBM_FILE db, DBM_DATUM key, DBM_DATUM contents, int replace) +{ + return store(key, contents); +} + +DBM_DATUM +mu_dbm_firstkey (DBM_FILE db) +{ + return firstkey (); +} + +DBM_DATUM +mu_dbm_nextkey (DBM_FILE db, DBM_DATUM key) +{ + return nextkey (key); +} + +#endif + diff --git a/src/mu_dbm.h b/src/mu_dbm.h new file mode 100644 index 00000000..2be98191 --- /dev/null +++ b/src/mu_dbm.h @@ -0,0 +1,79 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + + GNU Mailutils 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. + + GNU Mailutils 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 GNU Mailutils; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301 USA */ + +#include <mailutils/stream.h> + +#if defined(WITH_GDBM) + +#include <gdbm.h> +#define USE_DBM +typedef GDBM_FILE DBM_FILE; +typedef datum DBM_DATUM; +#define MU_DATUM_SIZE(d) d.dsize +#define MU_DATUM_PTR(d) d.dptr + +#elif defined(WITH_BDB2) + +#include <db.h> +#define USE_DBM + +struct db2_file +{ + DB *db; + DBC *dbc; +}; + +typedef struct db2_file *DBM_FILE; +typedef DBT DBM_DATUM; +#define MU_DATUM_SIZE(d) d.size +#define MU_DATUM_PTR(d) d.data + +#elif defined(WITH_NDBM) + +#include <ndbm.h> +#define USE_DBM +typedef DBM *DBM_FILE; +typedef datum DBM_DATUM; +#define MU_DATUM_SIZE(d) d.dsize +#define MU_DATUM_PTR(d) d.dptr + +#elif defined(WITH_OLD_DBM) + +#include <dbm.h> +#define USE_DBM +typedef int DBM_FILE; +typedef datum DBM_DATUM; +#define MU_DATUM_SIZE(d) d.dsize +#define MU_DATUM_PTR(d) d.dptr + +#endif + +#ifdef USE_DBM +struct stat; +int mu_dbm_stat (char *name, struct stat *sb); +int mu_dbm_open __P((char *name, DBM_FILE *db, int flags, int mode)); +int mu_dbm_close __P((DBM_FILE db)); +int mu_dbm_fetch __P((DBM_FILE db, DBM_DATUM key, DBM_DATUM *ret)); +int mu_dbm_insert __P((DBM_FILE db, DBM_DATUM key, DBM_DATUM contents, int replace)); +int mu_dbm_delete (DBM_FILE db, DBM_DATUM key); +DBM_DATUM mu_dbm_firstkey __P((DBM_FILE db)); +DBM_DATUM mu_dbm_nextkey __P((DBM_FILE db, DBM_DATUM key)); +#endif + +int mu_fcheck_perm __P((int fd, int mode)); +int mu_check_perm __P((const char *name, int mode)); diff --git a/src/strtok_r.c b/src/strtok_r.c new file mode 100644 index 00000000..cd9eed38 --- /dev/null +++ b/src/strtok_r.c @@ -0,0 +1,66 @@ +/* Reentrant string tokenizer. Generic version. + Copyright (C) 1991, 1996, 1997, 1998, 1999, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <string.h> + +/* Parse S into tokens separated by characters in DELIM. + If S is NULL, the saved pointer in SAVE_PTR is used as + the next starting point. For example: + char s[] = "-abc-=-def"; + char *sp; + x = strtok_r(s, "-", &sp); // x = "abc", sp = "=-def" + x = strtok_r(NULL, "-=", &sp); // x = "def", sp = NULL + x = strtok_r(NULL, "=", &sp); // x = NULL + // s = "abc\0-def\0" +*/ +char * +strtok_r (s, delim, save_ptr) + char *s; + const char *delim; + char **save_ptr; +{ + char *token; + + if (s == NULL) + s = *save_ptr; + + /* Scan leading delimiters. */ + s += strspn (s, delim); + if (*s == '\0') + { + *save_ptr = s; + return NULL; + } + + /* Find the end of the token. */ + token = s; + s = strpbrk (token, delim); + if (s == NULL) + /* This token finishes the string. */ + /* *save_ptr = __rawmemchr (token, '\0'); */ + *save_ptr = token + strlen (token); + else + { + /* Terminate the token and make *SAVE_PTR point past it. */ + *s = '\0'; + *save_ptr = s + 1; + } + return token; +} +/* weak_alias (__strtok_r, strtok_r) */ |