📄 apr_dbm.c
字号:
static apr_status_t set_error(apr_dbm_t *dbm, apr_status_t dbm_said){ apr_status_t rv = APR_SUCCESS; /* ### ignore whatever the DBM said (dbm_said); ask it explicitly */#if APU_USE_SDBM if ((dbm->errcode = sdbm_error(dbm->file)) == 0) { dbm->errmsg = NULL; } else { dbm->errmsg = "I/O error occurred."; rv = APR_EGENERAL; /* ### need something better */ } /* captured it. clear it now. */ sdbm_clearerr(dbm->file);#elif APU_USE_GDBM if ((dbm->errcode = gdbm_errno) == GDBM_NO_ERROR) { dbm->errmsg = NULL; } else { dbm->errmsg = gdbm_strerror(gdbm_errno); rv = APR_EGENERAL; /* ### need something better */ } /* captured it. clear it now. */ gdbm_errno = GDBM_NO_ERROR;#elif APU_USE_DB if (dbm_said == APR_SUCCESS) { dbm->errcode = 0; dbm->errmsg = NULL; } else { /* ### need to fix. dberr was tossed in db2s(). */ /* ### use db_strerror() */ dbm->errcode = 1; dbm->errmsg = "DB error occurred."; rv = APR_EGENERAL; }#else#error set_error has not been coded for this database type#endif return rv;}APU_DECLARE(apr_status_t) apr_dbm_open(apr_dbm_t **pdb, const char *pathname, int mode, apr_pool_t *pool){ real_file_t file; int dbmode; *pdb = NULL; switch (mode) { case APR_DBM_READONLY: dbmode = APR_DBM_DBMODE_RO; break; case APR_DBM_READWRITE: dbmode = APR_DBM_DBMODE_RW; break; case APR_DBM_RWCREATE: dbmode = APR_DBM_DBMODE_RWCREATE; break; default: return APR_EINVAL; }#if APU_USE_SDBM { apr_status_t rv; rv = sdbm_open(&file, pathname, dbmode, APR_OS_DEFAULT, pool); if (rv != APR_SUCCESS) return rv; }#elif APU_USE_GDBM { /* Note: stupid cast to get rid of "const" on the pathname */ file = gdbm_open((char *) pathname, 0, dbmode, POSIX_FILEMODE, NULL); if (file == NULL) return APR_EGENERAL; /* ### need a better error */ }#elif APU_USE_DB { int dberr;#if DB_VER == 3 if ((dberr = db_create(&file.bdb, NULL, 0)) == 0) { if ((dberr = (*file.bdb->open)(file.bdb, pathname, NULL, DB_HASH, dbmode, POSIX_FILEMODE)) != 0) { /* close the DB handler */ (void) (*file.bdb->close)(file.bdb, 0); } } file.curs = NULL;#elif DB_VER == 2 dberr = db_open(pathname, DB_HASH, dbmode, POSIX_FILEMODE, NULL, NULL, &file.bdb); file.curs = NULL;#else file.bdb = dbopen(pathname, dbmode, POSIX_FILEMODE, DB_HASH, NULL); if (file.bdb == NULL) return APR_EGENERAL; /* ### need a better error */ dberr = 0;#endif if (dberr != 0) return db2s(dberr); }#else#error apr_dbm_open has not been coded for this database type#endif /* switch on database types */ /* we have an open database... return it */ *pdb = apr_pcalloc(pool, sizeof(**pdb)); (*pdb)->pool = pool; (*pdb)->file = file; /* ### register a cleanup to close the DBM? */ return APR_SUCCESS;}APU_DECLARE(void) apr_dbm_close(apr_dbm_t *dbm){ APR_DBM_CLOSE(dbm->file);}APU_DECLARE(apr_status_t) apr_dbm_fetch(apr_dbm_t *dbm, apr_datum_t key, apr_datum_t *pvalue){ apr_status_t rv; cvt_datum_t ckey; result_datum_t rd; CONVERT_DATUM(ckey, &key); rv = APR_DBM_FETCH(dbm->file, ckey, rd); RETURN_DATUM(pvalue, rd); REGISTER_CLEANUP(dbm, pvalue); /* store the error info into DBM, and return a status code. Also, note that *pvalue should have been cleared on error. */ return set_error(dbm, rv);}APU_DECLARE(apr_status_t) apr_dbm_store(apr_dbm_t *dbm, apr_datum_t key, apr_datum_t value){ apr_status_t rv; cvt_datum_t ckey; cvt_datum_t cvalue; CONVERT_DATUM(ckey, &key); CONVERT_DATUM(cvalue, &value); rv = APR_DBM_STORE(dbm->file, ckey, cvalue); /* store any error info into DBM, and return a status code. */ return set_error(dbm, rv);}APU_DECLARE(apr_status_t) apr_dbm_delete(apr_dbm_t *dbm, apr_datum_t key){ apr_status_t rv; cvt_datum_t ckey; CONVERT_DATUM(ckey, &key); rv = APR_DBM_DELETE(dbm->file, ckey); /* store any error info into DBM, and return a status code. */ return set_error(dbm, rv);}APU_DECLARE(int) apr_dbm_exists(apr_dbm_t *dbm, apr_datum_t key){ int exists; cvt_datum_t ckey; CONVERT_DATUM(ckey, &key);#if APU_USE_SDBM { sdbm_datum value = sdbm_fetch(dbm->file, *ckey); sdbm_clearerr(dbm->file); /* don't need the error */ exists = value.dptr != NULL; }#elif APU_USE_GDBM exists = gdbm_exists(dbm->file, *ckey) != 0;#elif APU_USE_DB { DBT data; int dberr = do_fetch(dbm->file.bdb, ckey, data); /* DB returns DB_NOTFOUND if it doesn't exist. but we want to say that *any* error means it doesn't exist. */ exists = dberr == 0; }#else#error apr_dbm_exists has not been coded for this database type#endif return exists;}APU_DECLARE(apr_status_t) apr_dbm_firstkey(apr_dbm_t *dbm, apr_datum_t *pkey){ apr_status_t rv; result_datum_t rd; rv = APR_DBM_FIRSTKEY(dbm->file, rd); RETURN_DATUM(pkey, rd); REGISTER_CLEANUP(dbm, pkey); /* store any error info into DBM, and return a status code. */ return set_error(dbm, rv);}APU_DECLARE(apr_status_t) apr_dbm_nextkey(apr_dbm_t *dbm, apr_datum_t *pkey){ apr_status_t rv; cvt_datum_t ckey; result_datum_t rd; CONVERT_DATUM(ckey, pkey); rv = APR_DBM_NEXTKEY(dbm->file, ckey, rd); RETURN_DATUM(pkey, rd); REGISTER_CLEANUP(dbm, pkey); /* store any error info into DBM, and return a status code. */ return set_error(dbm, APR_SUCCESS);}APU_DECLARE(void) apr_dbm_freedatum(apr_dbm_t *dbm, apr_datum_t data){#ifdef NEEDS_CLEANUP (void) apr_pool_cleanup_run(dbm->pool, data.dptr, datum_cleanup);#else APR_DBM_FREEDPTR(data.dptr);#endif}APU_DECLARE(char *) apr_dbm_geterror(apr_dbm_t *dbm, int *errcode, char *errbuf, apr_size_t errbufsize){ if (errcode != NULL) *errcode = dbm->errcode; /* assert: errbufsize > 0 */ if (dbm->errmsg == NULL) *errbuf = '\0'; else (void) apr_cpystrn(errbuf, dbm->errmsg, errbufsize); return errbuf;}APU_DECLARE(void) apr_dbm_get_usednames(apr_pool_t *p, const char *pathname, const char **used1, const char **used2){#if APU_USE_SDBM char *work; *used1 = apr_pstrcat(p, pathname, SDBM_DIRFEXT, NULL); *used2 = work = apr_pstrdup(p, *used1); /* we know the extension is 4 characters */ memcpy(&work[strlen(work) - 4], SDBM_PAGFEXT, 4);#elif APU_USE_GDBM || APU_USE_DB *used1 = apr_pstrdup(p, pathname); *used2 = NULL;#else#error apr_dbm_get_usednames has not been coded for this database type#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -