- Include stdlib.h and cos.h.
[chise/concord.git] / concord-bdb.c
1 /* Copyright (C) 2003, 2004, 2005, 2006, 2013 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 #include "sysdep.h"
25 #include "concord.h"
26 #include "concord-bdb.h"
27
28 DB*
29 CONCORD_BDB_open (const char* db_dir,
30                   const char* genre,
31                   const char* key_type,
32                   const char* name,
33                   DBTYPE real_subtype,
34                   u_int32_t accessmask, int modemask)
35 {
36   DB* dbase;
37   int status;
38   int len, name_len, i;
39   int size;
40   char *db_file_name, *sp;
41   struct stat statbuf;
42
43   status = db_create (&dbase, NULL, 0);
44   if (status)
45     return NULL;
46
47   if ( (accessmask & DB_CREATE) && stat (db_dir, &statbuf) )
48     mkdir (db_dir, modemask);
49
50   len = strlen (db_dir);
51   name_len = strlen (name);
52   size = len + strlen (genre) + strlen (key_type) + name_len * 3 + 5;
53   db_file_name = alloca (size);
54   strcpy (db_file_name, db_dir);
55   if (db_file_name[len - 1] != '/')
56     {
57       db_file_name[len++] = '/';
58       db_file_name[len] = '\0';
59     }
60
61   strcat (db_file_name, genre);
62   if ( (accessmask & DB_CREATE) && stat (db_file_name, &statbuf) )
63     mkdir (db_file_name, modemask);
64   strcat (db_file_name, "/");
65
66   strcat (db_file_name, key_type);
67   if ( (accessmask & DB_CREATE) && stat (db_file_name, &statbuf) )
68     mkdir (db_file_name, modemask);
69   strcat (db_file_name, "/");
70
71   /* strcat (db_file_name, name); */
72   sp = &db_file_name[strlen (db_file_name)];
73   for (i = 0; i < name_len; i++)
74     {
75       int c = name[i];
76
77       if ( /* (c == '/') || (c == '%') */
78           strchr ("%/\\:*?\"<>|", c) != NULL )
79         {
80           sprintf (sp, "%%%02X", c);
81           sp += 3;
82         }
83       else
84         *sp++ = c;
85     }
86   *sp = '\0';
87 #if DB_VERSION_MAJOR < 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 1)
88   status = dbase->open (dbase, db_file_name, NULL,
89                         real_subtype, accessmask, modemask);
90 #else /* DB_VERSION >= 4.1 */
91   status = dbase->open (dbase, NULL, db_file_name, NULL,
92                         real_subtype,
93                         accessmask /* | DB_AUTO_COMMIT */, modemask);
94 #endif /* DB_VERSION < 4.1 */
95   if (status)
96     {
97       dbase->close (dbase, 0);
98       return NULL;
99     }
100   return dbase;
101 }
102
103 int
104 CONCORD_BDB_close (DB* db)
105 {
106   if (db)
107     {
108       db->sync  (db, 0);
109       db->close (db, 0);
110     }
111   return 0;
112 }
113
114 int
115 CONCORD_BDB_get (DB* db, const char* key, DBT* valdatum)
116 {
117   DBT keydatum;
118   int status = 0;
119
120   /* DB Version 2 requires DBT's to be zeroed before use. */
121   xzero (keydatum);
122   xzero (*valdatum);
123
124   keydatum.data = (char*)key;
125   keydatum.size = strlen (key);
126
127   status = db->get (db, NULL, &keydatum, valdatum, 0);
128   return status;
129 }
130
131 int
132 CONCORD_BDB_put (DB* db, const char* key, unsigned char* value)
133 {
134   DBT keydatum, valdatum;
135   int status = 0;
136
137   /* DB Version 2 requires DBT's to be zeroed before use. */
138   xzero (keydatum);
139   xzero (valdatum);
140
141   keydatum.data = (char*)key;
142   keydatum.size = strlen (key);
143
144   valdatum.data = value;
145   valdatum.size = strlen ((char*)value);
146
147   status = db->put (db, NULL, &keydatum, &valdatum, 0);
148   return status;
149 }