Annotation of embedaddon/php/ext/dba/dba_db4.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
                      5:    | Copyright (c) 1997-2012 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: Marcus Boerger <helly@php.net>                              |
                     16:    |          Sascha Schumann <sascha@schumann.cx>                        |
                     17:    +----------------------------------------------------------------------+
                     18:  */
                     19: 
                     20: /* $Id: dba_db4.c 321634 2012-01-01 13:15:04Z felipe $ */
                     21: 
                     22: #ifdef HAVE_CONFIG_H
                     23: #include "config.h"
                     24: #endif
                     25: 
                     26: #include "php.h"
                     27: 
                     28: #if DBA_DB4
                     29: #include "php_db4.h"
                     30: #include <sys/stat.h>
                     31: 
                     32: #include <string.h>
                     33: #ifdef DB4_INCLUDE_FILE
                     34: #include DB4_INCLUDE_FILE
                     35: #else
                     36: #include <db.h>
                     37: #endif
                     38: 
                     39: static void php_dba_db4_errcall_fcn(
                     40: #if (DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3))
                     41:        const DB_ENV *dbenv, 
                     42: #endif
                     43:        const char *errpfx, const char *msg)
                     44: {
                     45:        TSRMLS_FETCH();
                     46: 
                     47: #if (DB_VERSION_MAJOR == 5 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 8))
                     48: /* Bug 51086, Berkeley DB 4.8.26 */
                     49: /* This code suppresses a BDB 4.8+ error message, thus keeping PHP test compatibility */
                     50:        {
                     51:                char *function = get_active_function_name(TSRMLS_C);
                     52:                if (function && (!strcmp(function,"dba_popen") || !strcmp(function,"dba_open"))
                     53:                        && (!strncmp(msg, "fop_read_meta", sizeof("fop_read_meta")-1)
                     54:                                || !strncmp(msg, "BDB0004 fop_read_meta", sizeof("BDB0004 fop_read_meta")-1))) {
                     55:                        return;
                     56:                }
                     57:        }
                     58: #endif
                     59: 
                     60:        php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s%s", errpfx?errpfx:"", msg);
                     61: }
                     62: 
                     63: #define DB4_DATA dba_db4_data *dba = info->dbf
                     64: #define DB4_GKEY \
                     65:        DBT gkey; \
                     66:        memset(&gkey, 0, sizeof(gkey)); \
                     67:        gkey.data = (char *) key; gkey.size = keylen
                     68: 
                     69: typedef struct {
                     70:        DB *dbp;
                     71:        DBC *cursor;
                     72: } dba_db4_data;
                     73: 
                     74: DBA_OPEN_FUNC(db4)
                     75: {
                     76:        DB *dbp = NULL;
                     77:        DBTYPE type;
                     78:        int gmode = 0, err;
                     79:        int filemode = 0644;
                     80:        struct stat check_stat;
                     81:        int s = VCWD_STAT(info->path, &check_stat);
                     82: 
                     83: #if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR <= 7)  /* Bug 51086 */
                     84:        if (!s && !check_stat.st_size) {
                     85:                info->mode = DBA_TRUNC; /* force truncate */
                     86:        }
                     87: 
                     88:        type = info->mode == DBA_READER ? DB_UNKNOWN :
                     89:                info->mode == DBA_TRUNC ? DB_BTREE :
                     90:                s ? DB_BTREE : DB_UNKNOWN;
                     91:          
                     92:        gmode = info->mode == DBA_READER ? DB_RDONLY :
                     93:                (info->mode == DBA_CREAT && s) ? DB_CREATE : 
                     94:                (info->mode == DBA_CREAT && !s) ? 0 :
                     95:                info->mode == DBA_WRITER ? 0         : 
                     96:                info->mode == DBA_TRUNC ? DB_CREATE | DB_TRUNCATE : -1;
                     97: #else
                     98:        if (!s && !check_stat.st_size) {
                     99:                info->mode = DBA_CREAT; /* force creation */
                    100:        }
                    101: 
                    102:        type = info->mode == DBA_READER ? DB_UNKNOWN :
                    103:                (info->mode == DBA_TRUNC || info->mode == DBA_CREAT) ? DB_BTREE :
                    104:                s ? DB_BTREE : DB_UNKNOWN;
                    105:          
                    106:        gmode = info->mode == DBA_READER ? DB_RDONLY :
                    107:                info->mode == DBA_CREAT ? DB_CREATE : 
                    108:                info->mode == DBA_WRITER ? 0         : 
                    109:                info->mode == DBA_TRUNC ? DB_CREATE | DB_TRUNCATE : -1;
                    110: #endif
                    111: 
                    112:        if (gmode == -1) {
                    113:                return FAILURE; /* not possible */
                    114:        }
                    115: 
                    116:        if (info->flags & DBA_PERSISTENT) {
                    117:                gmode |= DB_THREAD;
                    118:        }
                    119: 
                    120:        if (info->argc > 0) {
                    121:                convert_to_long_ex(info->argv[0]);
                    122:                filemode = Z_LVAL_PP(info->argv[0]);
                    123:        }
                    124: 
                    125:        if ((err=db_create(&dbp, NULL, 0)) == 0) {
                    126:            dbp->set_errcall(dbp, php_dba_db4_errcall_fcn);
                    127:            if (
                    128: #if (DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1))
                    129:                        (err=dbp->open(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) {
                    130: #else
                    131:                        (err=dbp->open(dbp, info->path, NULL, type, gmode, filemode)) == 0) {
                    132: #endif
                    133:                        dba_db4_data *data;
                    134: 
                    135:                        data = pemalloc(sizeof(*data), info->flags&DBA_PERSISTENT);
                    136:                        data->dbp = dbp;
                    137:                        data->cursor = NULL;
                    138:                        info->dbf = data;
                    139:                
                    140:                        return SUCCESS;
                    141:                } else {
                    142:                        dbp->close(dbp, 0);
                    143:                        *error = db_strerror(err);
                    144:                }
                    145:        } else {
                    146:                *error = db_strerror(err);
                    147:        }
                    148: 
                    149:        return FAILURE;
                    150: }
                    151: 
                    152: DBA_CLOSE_FUNC(db4)
                    153: {
                    154:        DB4_DATA;
                    155:        
                    156:        if (dba->cursor) dba->cursor->c_close(dba->cursor);
                    157:        dba->dbp->close(dba->dbp, 0);
                    158:        pefree(dba, info->flags&DBA_PERSISTENT);
                    159: }
                    160: 
                    161: DBA_FETCH_FUNC(db4)
                    162: {
                    163:        DBT gval;
                    164:        char *new = NULL;
                    165:        DB4_DATA;
                    166:        DB4_GKEY;
                    167:        
                    168:        memset(&gval, 0, sizeof(gval));
                    169:        if (info->flags & DBA_PERSISTENT) {
                    170:                gval.flags |= DB_DBT_MALLOC;
                    171:        }
                    172:        if (!dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) {
                    173:                if (newlen) *newlen = gval.size;
                    174:                new = estrndup(gval.data, gval.size);
                    175:                if (info->flags & DBA_PERSISTENT) {
                    176:                        free(gval.data);
                    177:                }
                    178:        }
                    179:        return new;
                    180: }
                    181: 
                    182: DBA_UPDATE_FUNC(db4)
                    183: {
                    184:        DBT gval;
                    185:        DB4_DATA;
                    186:        DB4_GKEY;
                    187:        
                    188:        memset(&gval, 0, sizeof(gval));
                    189:        gval.data = (char *) val;
                    190:        gval.size = vallen;
                    191: 
                    192:        if (!dba->dbp->put(dba->dbp, NULL, &gkey, &gval, 
                    193:                                mode == 1 ? DB_NOOVERWRITE : 0)) {
                    194:                return SUCCESS;
                    195:        }
                    196:        return FAILURE;
                    197: }
                    198: 
                    199: DBA_EXISTS_FUNC(db4)
                    200: {
                    201:        DBT gval;
                    202:        DB4_DATA;
                    203:        DB4_GKEY;
                    204:        
                    205:        memset(&gval, 0, sizeof(gval));
                    206:        
                    207:        if (info->flags & DBA_PERSISTENT) {
                    208:                gval.flags |= DB_DBT_MALLOC;
                    209:        }
                    210: 
                    211:        if (!dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) {
                    212:                if (info->flags & DBA_PERSISTENT) {
                    213:                        free(gval.data);
                    214:                }
                    215:                return SUCCESS;
                    216:        }
                    217:        return FAILURE;
                    218: }
                    219: 
                    220: DBA_DELETE_FUNC(db4)
                    221: {
                    222:        DB4_DATA;
                    223:        DB4_GKEY;
                    224: 
                    225:        return dba->dbp->del(dba->dbp, NULL, &gkey, 0) ? FAILURE : SUCCESS;
                    226: }
                    227: 
                    228: DBA_FIRSTKEY_FUNC(db4)
                    229: {
                    230:        DB4_DATA;
                    231: 
                    232:        if (dba->cursor) {
                    233:                dba->cursor->c_close(dba->cursor);
                    234:        }
                    235: 
                    236:        dba->cursor = NULL;
                    237:        if (dba->dbp->cursor(dba->dbp, NULL, &dba->cursor, 0) != 0) {
                    238:                return NULL;
                    239:        }
                    240: 
                    241:        /* we should introduce something like PARAM_PASSTHRU... */
                    242:        return dba_nextkey_db4(info, newlen TSRMLS_CC);
                    243: }
                    244: 
                    245: DBA_NEXTKEY_FUNC(db4)
                    246: {
                    247:        DB4_DATA;
                    248:        DBT gkey, gval;
                    249:        char *nkey = NULL;
                    250:        
                    251:        memset(&gkey, 0, sizeof(gkey));
                    252:        memset(&gval, 0, sizeof(gval));
                    253: 
                    254:        if (info->flags & DBA_PERSISTENT) {
                    255:                gkey.flags |= DB_DBT_MALLOC;
                    256:                gval.flags |= DB_DBT_MALLOC;
                    257:        }
                    258:        if (dba->cursor && dba->cursor->c_get(dba->cursor, &gkey, &gval, DB_NEXT) == 0) {
                    259:                if (gkey.data) {
                    260:                        nkey = estrndup(gkey.data, gkey.size);
                    261:                        if (newlen) *newlen = gkey.size;
                    262:                }
                    263:                if (info->flags & DBA_PERSISTENT) {
                    264:                        if (gkey.data) {
                    265:                                free(gkey.data);
                    266:                        }
                    267:                        if (gval.data) {
                    268:                                free(gval.data);
                    269:                        }
                    270:                }
                    271:        }
                    272: 
                    273:        return nkey;
                    274: }
                    275: 
                    276: DBA_OPTIMIZE_FUNC(db4)
                    277: {
                    278:        return SUCCESS;
                    279: }
                    280: 
                    281: DBA_SYNC_FUNC(db4)
                    282: {
                    283:        DB4_DATA;
                    284: 
                    285:        return dba->dbp->sync(dba->dbp, 0) ? FAILURE : SUCCESS;
                    286: }
                    287: 
                    288: DBA_INFO_FUNC(db4)
                    289: {
                    290:        return estrdup(DB_VERSION_STRING);
                    291: }
                    292: 
                    293: #endif
                    294: 
                    295: /*
                    296:  * Local variables:
                    297:  * tab-width: 4
                    298:  * c-basic-offset: 4
                    299:  * End:
                    300:  * vim600: sw=4 ts=4 fdm=marker
                    301:  * vim<600: sw=4 ts=4
                    302:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>