(CONCORD_BDB_open): Use <char*> instead of <unsigned char*> for
[chise/concord.git] / concord-bdb.c
1 /* Copyright (C) 2003,2004,2005,2006 MORIOKA Tomohiko
2    This file is part of the CONCORD Library.
3
4    The CONCORD Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8
9    The CONCORD Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13
14    You should have received a copy of the GNU Lesser General Public
15    License along with the CONCORD Library; if not, write to the Free
16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307 USA.  */
18
19 #include <stdlib.h>
20 #include <string.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <unistd.h>
24 #ifdef HAVE_CONFIG_H
25 #  include "config.h"
26 #endif
27 #include "sysdep.h"
28 #include "concord.h"
29 #include "concord-bdb.h"
30
31 DB*
32 CONCORD_BDB_open (const char* db_dir,
33                   const char* genre,
34                   const char* key_type,
35                   const char* name,
36                   DBTYPE real_subtype,
37                   u_int32_t accessmask, int modemask)
38 {
39   DB* dbase;
40   int status;
41   int len, name_len, i;
42   int size;
43   char *db_file_name, *sp;
44   struct stat statbuf;
45
46   status = db_create (&dbase, NULL, 0);
47   if (status)
48     return NULL;
49
50   if ( (accessmask & DB_CREATE) && stat (db_dir, &statbuf) )
51     mkdir (db_dir, modemask);
52
53   len = strlen (db_dir);
54   name_len = strlen (name);
55   size = len + strlen (genre) + strlen (key_type) + name_len * 3 + 5;
56   db_file_name = alloca (size);
57   strcpy (db_file_name, db_dir);
58   if (db_file_name[len - 1] != '/')
59     {
60       db_file_name[len++] = '/';
61       db_file_name[len] = '\0';
62     }
63
64   strcat (db_file_name, genre);
65   if ( (accessmask & DB_CREATE) && stat (db_file_name, &statbuf) )
66     mkdir (db_file_name, modemask);
67   strcat (db_file_name, "/");
68
69   strcat (db_file_name, key_type);
70   if ( (accessmask & DB_CREATE) && stat (db_file_name, &statbuf) )
71     mkdir (db_file_name, modemask);
72   strcat (db_file_name, "/");
73
74   /* strcat (db_file_name, name); */
75   sp = &db_file_name[strlen (db_file_name)];
76   for (i = 0; i < name_len; i++)
77     {
78       int c = name[i];
79
80       if ( /* (c == '/') || (c == '%') */
81           strchr ("%/\\:*?\"<>|", c) != NULL )
82         {
83           sprintf (sp, "%%%02X", c);
84           sp += 3;
85         }
86       else
87         *sp++ = c;
88     }
89   *sp = '\0';
90 #if DB_VERSION_MAJOR < 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 1)
91   status = dbase->open (dbase, db_file_name, NULL,
92                         real_subtype, accessmask, modemask);
93 #else /* DB_VERSION >= 4.1 */
94   status = dbase->open (dbase, NULL, db_file_name, NULL,
95                         real_subtype,
96                         accessmask /* | DB_AUTO_COMMIT */, modemask);
97 #endif /* DB_VERSION < 4.1 */
98   if (status)
99     {
100       dbase->close (dbase, 0);
101       return NULL;
102     }
103   return dbase;
104 }
105
106 int
107 CONCORD_BDB_close (DB* db)
108 {
109   if (db)
110     {
111       db->sync  (db, 0);
112       db->close (db, 0);
113     }
114   return 0;
115 }
116
117 int
118 CONCORD_BDB_get (DB* db, const char* key, DBT* valdatum)
119 {
120   DBT keydatum;
121   int status = 0;
122
123   /* DB Version 2 requires DBT's to be zeroed before use. */
124   xzero (keydatum);
125   xzero (*valdatum);
126
127   keydatum.data = (char*)key;
128   keydatum.size = strlen (key);
129
130   status = db->get (db, NULL, &keydatum, valdatum, 0);
131   return status;
132 }
133
134 int
135 CONCORD_BDB_put (DB* db, const char* key, unsigned char* value)
136 {
137   DBT keydatum, valdatum;
138   int status = 0;
139
140   /* DB Version 2 requires DBT's to be zeroed before use. */
141   xzero (keydatum);
142   xzero (valdatum);
143
144   keydatum.data = (char*)key;
145   keydatum.size = strlen (key);
146
147   valdatum.data = value;
148   valdatum.size = strlen ((char*)value);
149
150   status = db->put (db, NULL, &keydatum, &valdatum, 0);
151   return status;
152 }