1 /*************************************************************************************************
2  * The skeleton database library working as a directory database
3  *                                                               Copyright (C) 2006-2010 FAL Labs
4  * This file is part of Tokyo Tyrant.
5  * Tokyo Tyrant is free software; you can redistribute it and/or modify it under the terms of
6  * the GNU Lesser General Public License as published by the Free Software Foundation; either
7  * version 2.1 of the License or any later version.  Tokyo Tyrant is distributed in the hope
8  * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
10  * License for more details.
11  * You should have received a copy of the GNU Lesser General Public License along with Tokyo
12  * Tyrant; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
13  * Boston, MA 02111-1307 USA.
14  *************************************************************************************************/
15 
16 
17 #include <tcutil.h>
18 #include <tcadb.h>
19 #include <stdlib.h>
20 #include <stdbool.h>
21 #include <stdint.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25 #include <pthread.h>
26 
27 
28 typedef struct {                         /* type of structure for a directory database */
29   char *name;                            /* name of the directory */
30 } TCDDB;
31 
32 
33 /* private funciton prototypes */
34 static TCDDB *tcddbnew(void);
35 static void tcddbdel(TCDDB *ddb);
36 static bool tcddbopen(TCDDB *ddb, const char *name);
37 static bool tcddbclose(TCDDB *ddb);
38 static bool tcddbput(TCDDB *ddb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
39 static bool tcddbout(TCDDB *ddb, const void *kbuf, int ksiz);
40 static void *tcddbget(TCDDB *ddb, const void *kbuf, int ksiz, int *sp);
41 static char *makepath(TCDDB *ddb, const void *kbuf, int ksiz);
42 
43 
44 
45 /*************************************************************************************************
46  * API
47  *************************************************************************************************/
48 
49 
initialize(ADBSKEL * skel)50 bool initialize(ADBSKEL *skel){
51   skel->opq = tcddbnew();
52   skel->del = (void (*)(void *))tcddbdel;
53   skel->open = (bool (*)(void *, const char *))tcddbopen;
54   skel->close = (bool (*)(void *))tcddbclose;
55   skel->put = (bool (*)(void *, const void *, int, const void *, int))tcddbput;
56   skel->out = (bool (*)(void *, const void *, int))tcddbout;
57   skel->get = (void *(*)(void *, const void *, int, int *))tcddbget;
58   return true;
59 }
60 
61 
62 
63 /*************************************************************************************************
64  * private features
65  *************************************************************************************************/
66 
67 
tcddbnew(void)68 static TCDDB *tcddbnew(void){
69   TCDDB *ddb = tcmalloc(sizeof(*ddb));
70   ddb->name = NULL;
71   return ddb;
72 }
73 
74 
tcddbdel(TCDDB * ddb)75 static void tcddbdel(TCDDB *ddb){
76   if(ddb->name) tcddbclose(ddb);
77   tcfree(ddb);
78 }
79 
80 
tcddbopen(TCDDB * ddb,const char * name)81 static bool tcddbopen(TCDDB *ddb, const char *name){
82   if(ddb->name) return false;
83   struct stat sbuf;
84   if(stat(name, &sbuf) == 0){
85     if(!S_ISDIR(sbuf.st_mode)) return false;
86   } else {
87     if(mkdir(name, 0755) != 0) return false;
88   }
89   ddb->name = tcstrdup(name);
90   return true;
91 }
92 
93 
tcddbclose(TCDDB * ddb)94 static bool tcddbclose(TCDDB *ddb){
95   if(!ddb->name) return false;
96   tcfree(ddb->name);
97   ddb->name = NULL;
98   return true;
99 }
100 
101 
tcddbput(TCDDB * ddb,const void * kbuf,int ksiz,const void * vbuf,int vsiz)102 static bool tcddbput(TCDDB *ddb, const void *kbuf, int ksiz, const void *vbuf, int vsiz){
103   if(!ddb->name) return false;
104   bool err = false;
105   char *path = makepath(ddb, kbuf, ksiz);
106   if(!tcwritefile(path, vbuf, vsiz)) err = true;
107   tcfree(path);
108   return !err;
109 }
110 
111 
tcddbout(TCDDB * ddb,const void * kbuf,int ksiz)112 static bool tcddbout(TCDDB *ddb, const void *kbuf, int ksiz){
113   if(!ddb->name) return false;
114   bool err = false;
115   char *path = makepath(ddb, kbuf, ksiz);
116   if(unlink(path) != 0) err = true;
117   tcfree(path);
118   return !err;
119 }
120 
121 
tcddbget(TCDDB * ddb,const void * kbuf,int ksiz,int * sp)122 static void *tcddbget(TCDDB *ddb, const void *kbuf, int ksiz, int *sp){
123   if(!ddb->name) return false;
124   void *vbuf;
125   char *path = makepath(ddb, kbuf, ksiz);
126   vbuf = tcreadfile(path, -1, sp);
127   tcfree(path);
128   return vbuf;
129 }
130 
131 
makepath(TCDDB * ddb,const void * kbuf,int ksiz)132 static char *makepath(TCDDB *ddb, const void *kbuf, int ksiz){
133   char *uenc = tcurlencode(kbuf, ksiz);
134   char *path = tcsprintf("%s/%s", ddb->name, uenc);
135   tcfree(uenc);
136   return path;
137 }
138 
139 
140 
141 // END OF FILE
142