root/ext/dba/dba_cdb.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. DBA_OPEN_FUNC
  2. DBA_CLOSE_FUNC
  3. DBA_FETCH_FUNC
  4. DBA_UPDATE_FUNC
  5. DBA_EXISTS_FUNC
  6. DBA_DELETE_FUNC
  7. cdb_file_lseek
  8. cdb_file_lseek
  9. DBA_FIRSTKEY_FUNC
  10. DBA_NEXTKEY_FUNC
  11. DBA_OPTIMIZE_FUNC
  12. DBA_SYNC_FUNC
  13. DBA_INFO_FUNC

   1 /*
   2    +----------------------------------------------------------------------+
   3    | PHP Version 7                                                        |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1997-2016 The PHP Group                                |
   6    +----------------------------------------------------------------------+
   7    | This source file is subject to version 3.01 of the PHP license,      |
   8    | that is bundled with this package in the file LICENSE, and is        |
   9    | available through the world-wide-web at the following url:           |
  10    | http://www.php.net/license/3_01.txt                                  |
  11    | If you did not receive a copy of the PHP license and are unable to   |
  12    | obtain it through the world-wide-web, please send a note to          |
  13    | license@php.net so we can mail you a copy immediately.               |
  14    +----------------------------------------------------------------------+
  15    | Authors: Sascha Schumann <sascha@schumann.cx>                        |
  16    |          Marcus Boerger <helly@php.net>                              |
  17    +----------------------------------------------------------------------+
  18  */
  19 
  20 /* $Id$ */
  21 
  22 #ifdef HAVE_CONFIG_H
  23 #include "config.h"
  24 #endif
  25 
  26 #include "php.h"
  27 
  28 #if DBA_CDB
  29 #include "php_cdb.h"
  30 
  31 #include <sys/types.h>
  32 #ifdef HAVE_UNISTD_H
  33 #include <unistd.h>
  34 #endif
  35 #include <fcntl.h>
  36 
  37 #if DBA_CDB_BUILTIN
  38 # include "libcdb/cdb.h"
  39 # include "libcdb/cdb_make.h"
  40 # include "libcdb/uint32.h"
  41 #else
  42 # ifdef CDB_INCLUDE_FILE
  43 #  include CDB_INCLUDE_FILE
  44 # endif
  45 #endif
  46 
  47 #define CDB_INFO \
  48         dba_cdb *cdb = (dba_cdb *) info->dbf
  49 
  50 typedef struct {
  51         struct cdb c;
  52 #if DBA_CDB_BUILTIN
  53         struct cdb_make m;
  54         php_stream *file;
  55         int make;
  56 #else
  57         int file;
  58 #endif
  59         uint32 eod; /* size of constant database */
  60         uint32 pos; /* current position for traversing */
  61 } dba_cdb;
  62 
  63 DBA_OPEN_FUNC(cdb)
  64 {
  65 #if DBA_CDB_BUILTIN
  66         php_stream* file = 0;
  67         int make;
  68 #else
  69         int file = 0;
  70 #endif
  71         dba_cdb *cdb;
  72         dba_info *pinfo = (dba_info *) info;
  73 
  74         switch (info->mode) {
  75                 case DBA_READER:
  76 #if DBA_CDB_BUILTIN
  77                         make = 0;
  78                         file = info->fp;
  79 #else
  80                         file = VCWD_OPEN(info->path, O_RDONLY);
  81                         if (file < 0) {
  82                                 *error = "Unable to open file";
  83                                 return FAILURE;
  84                         }
  85 #endif
  86                         break;
  87 #if DBA_CDB_BUILTIN
  88                 case DBA_TRUNC:
  89                         make = 1;
  90                         file = info->fp;
  91                         break;
  92                 case DBA_CREAT:
  93                 case DBA_WRITER:
  94                         *error = "Update operations are not supported";
  95                         return FAILURE; /* not supported */
  96 #endif
  97                 default:
  98                         *error = "Currently not supported";
  99                         return FAILURE;
 100         }
 101 
 102         cdb = pemalloc(sizeof(dba_cdb), info->flags&DBA_PERSISTENT);
 103         memset(cdb, 0, sizeof(dba_cdb));
 104 
 105 #if DBA_CDB_BUILTIN
 106         if (make) {
 107                 cdb_make_start(&cdb->m, file);
 108         } else {
 109                 cdb_init(&cdb->c, file);
 110         }
 111         cdb->make = make;
 112 #else
 113         cdb_init(&cdb->c, file);
 114 #endif
 115         cdb->file = file;
 116 
 117         pinfo->dbf = cdb;
 118         return SUCCESS;
 119 }
 120 
 121 DBA_CLOSE_FUNC(cdb)
 122 {
 123         CDB_INFO;
 124 
 125         /* cdb_free does not close associated file */
 126 #if DBA_CDB_BUILTIN
 127         if (cdb->make) {
 128                 cdb_make_finish(&cdb->m);
 129         } else {
 130                 cdb_free(&cdb->c);
 131         }
 132 #else
 133         cdb_free(&cdb->c);
 134         close(cdb->file);
 135 #endif
 136         pefree(cdb, info->flags&DBA_PERSISTENT);
 137 }
 138 
 139 #if DBA_CDB_BUILTIN
 140 # define php_cdb_read(cdb, buf, len, pos) cdb_read(cdb, buf, len, pos)
 141 # define php_cdb_findnext(cdb, key, len) cdb_findnext(cdb, key, len)
 142 # define php_cdb_find(cdb, key, len) cdb_find(cdb, key, len)
 143 #else
 144 # define php_cdb_read(cdb, buf, len, pos) cdb_read(cdb, buf, len, pos)
 145 # define php_cdb_findnext(cdb, key, len) cdb_findnext(cdb, key, len)
 146 # define php_cdb_find(cdb, key, len) cdb_find(cdb, key, len)
 147 #endif
 148 
 149 DBA_FETCH_FUNC(cdb)
 150 {
 151         CDB_INFO;
 152         unsigned int len;
 153         char *new_entry = NULL;
 154 
 155 #if DBA_CDB_BUILTIN
 156         if (cdb->make)
 157                 return NULL; /* database was opened writeonly */
 158 #endif
 159         if (php_cdb_find(&cdb->c, key, keylen) == 1) {
 160                 while(skip--) {
 161                         if (php_cdb_findnext(&cdb->c, key, keylen) != 1) {
 162                                 return NULL;
 163                         }
 164                 }
 165                 len = cdb_datalen(&cdb->c);
 166                 new_entry = safe_emalloc(len, 1, 1);
 167 
 168                 if (php_cdb_read(&cdb->c, new_entry, len, cdb_datapos(&cdb->c)) == -1) {
 169                         efree(new_entry);
 170                         return NULL;
 171                 }
 172                 new_entry[len] = 0;
 173                 if (newlen)
 174                         *newlen = len;
 175         }
 176 
 177         return new_entry;
 178 }
 179 
 180 DBA_UPDATE_FUNC(cdb)
 181 {
 182 #if DBA_CDB_BUILTIN
 183         CDB_INFO;
 184 
 185         if (!cdb->make)
 186                 return FAILURE; /* database was opened readonly */
 187         if (!mode)
 188                 return FAILURE; /* cdb_make dosn't know replace */
 189         if (cdb_make_add(&cdb->m, key, keylen, val, vallen) != -1)
 190                 return SUCCESS;
 191 #endif
 192         return FAILURE;
 193 }
 194 
 195 DBA_EXISTS_FUNC(cdb)
 196 {
 197         CDB_INFO;
 198 
 199 #if DBA_CDB_BUILTIN
 200         if (cdb->make)
 201                 return FAILURE; /* database was opened writeonly */
 202 #endif
 203         if (php_cdb_find(&cdb->c, key, keylen) == 1)
 204                 return SUCCESS;
 205         return FAILURE;
 206 }
 207 
 208 DBA_DELETE_FUNC(cdb)
 209 {
 210         return FAILURE; /* cdb doesn't support delete */
 211 }
 212 
 213 /* {{{ cdb_file_read */
 214 #if DBA_CDB_BUILTIN
 215 # define cdb_file_read(fildes, buf, size) php_stream_read(fildes, buf, size)
 216 #else
 217 # define cdb_file_read(fildes, buf, size) read(fildes, buf, size)
 218 #endif
 219 /* }}} */
 220 
 221 #define CREAD(n) do { \
 222         if (cdb_file_read(cdb->file, buf, n) < n) return NULL; \
 223 } while (0)
 224 
 225 /* {{{ cdb_file_lseek
 226  php_stream_seek does not return actual position */
 227 #if DBA_CDB_BUILTIN
 228 int cdb_file_lseek(php_stream *fp, off_t offset, int whence) {
 229         php_stream_seek(fp, offset, whence);
 230         return php_stream_tell(fp);
 231 }
 232 #else
 233 int cdb_file_lseek(int fd, off_t offset, int whence) {
 234         return lseek(fd, offset, whence);
 235 }
 236 #endif
 237 /* }}} */
 238 
 239 #define CSEEK(n) do { \
 240         if (n >= cdb->eod) return NULL; \
 241         if (cdb_file_lseek(cdb->file, (off_t)n, SEEK_SET) != (off_t) n) return NULL; \
 242 } while (0)
 243 
 244 
 245 DBA_FIRSTKEY_FUNC(cdb)
 246 {
 247         CDB_INFO;
 248         uint32 klen, dlen;
 249         char buf[8];
 250         char *key;
 251 
 252 #if DBA_CDB_BUILTIN
 253         if (cdb->make)
 254                 return NULL; /* database was opened writeonly */
 255 #endif
 256 
 257         cdb->eod = -1;
 258         CSEEK(0);
 259         CREAD(4);
 260 
 261         /* Total length of file in bytes */
 262         uint32_unpack(buf, &cdb->eod);
 263 
 264         CSEEK(2048);
 265         CREAD(8);
 266 
 267         /* The first four bytes contain the length of the key */
 268         uint32_unpack(buf, &klen);
 269         uint32_unpack(buf + 4, &dlen);
 270 
 271         key = safe_emalloc(klen, 1, 1);
 272         if (cdb_file_read(cdb->file, key, klen) < klen) {
 273                 efree(key);
 274                 key = NULL;
 275         } else {
 276                 key[klen] = '\0';
 277                 if (newlen) *newlen = klen;
 278         }
 279 
 280         /*       header + klenlen + dlenlen + klen + dlen */
 281         cdb->pos = 2048 + 4       + 4       + klen + dlen;
 282 
 283         return key;
 284 }
 285 
 286 DBA_NEXTKEY_FUNC(cdb)
 287 {
 288         CDB_INFO;
 289         uint32 klen, dlen;
 290         char buf[8];
 291         char *key;
 292 
 293 #if DBA_CDB_BUILTIN
 294         if (cdb->make)
 295                 return NULL; /* database was opened writeonly */
 296 #endif
 297 
 298         CSEEK(cdb->pos);
 299         CREAD(8);
 300         uint32_unpack(buf, &klen);
 301         uint32_unpack(buf + 4, &dlen);
 302 
 303         key = safe_emalloc(klen, 1, 1);
 304         if (cdb_file_read(cdb->file, key, klen) < klen) {
 305                 efree(key);
 306                 key = NULL;
 307         } else {
 308                 key[klen] = '\0';
 309                 if (newlen) *newlen = klen;
 310         }
 311 
 312         cdb->pos += 8 + klen + dlen;
 313 
 314         return key;
 315 }
 316 
 317 DBA_OPTIMIZE_FUNC(cdb)
 318 {
 319         return SUCCESS;
 320 }
 321 
 322 DBA_SYNC_FUNC(cdb)
 323 {
 324         /* this is read-only */
 325         return SUCCESS;
 326 }
 327 
 328 DBA_INFO_FUNC(cdb)
 329 {
 330 #if DBA_CDB_BUILTIN
 331         if (!strcmp(hnd->name, "cdb")) {
 332                 return estrdup(cdb_version());
 333         } else {
 334                 return estrdup(cdb_make_version());
 335         }
 336 #else
 337         return estrdup("External");
 338 #endif
 339 }
 340 
 341 #endif
 342 
 343 /*
 344  * Local variables:
 345  * tab-width: 4
 346  * c-basic-offset: 4
 347  * End:
 348  * vim600: sw=4 ts=4 fdm=marker
 349  * vim<600: sw=4 ts=4
 350  */

/* [<][>][^][v][top][bottom][index][help] */