⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbm.c

📁 linux网络服务器工具
💻 C
📖 第 1 页 / 共 2 页
字号:
    dav_db *db;    dav_error *err;    apr_datum_t key;    apr_datum_t value = { 0 };    *pdb = NULL;    /*    ** Return if an error occurred, or there is no database.    **    ** NOTE: db could be NULL if we attempted to open a readonly    **       database that doesn't exist. If we require read/write    **       access, then a database was created and opened.    */    if ((err = dav_dbm_open(pool, resource, ro, &db)) != NULL        || db == NULL)        return err;    db->uri_index = apr_hash_make(pool);    key.dptr = DAV_GDBM_NS_KEY;    key.dsize = DAV_GDBM_NS_KEY_LEN;    if ((err = dav_dbm_fetch(db, key, &value)) != NULL) {        /* ### push a higher-level description? */        return err;    }    if (value.dptr == NULL) {        dav_propdb_metadata m = {            DAV_DBVSN_MAJOR, DAV_DBVSN_MINOR, 0        };        /*        ** If there is no METADATA key, then the database may be        ** from versions 0.9.0 .. 0.9.4 (which would be incompatible).        ** These can be identified by the presence of an NS_TABLE entry.        */        key.dptr = "NS_TABLE";        key.dsize = 8;        if (dav_dbm_exists(db, key)) {            dav_dbm_close(db);            /* call it a major version error */            return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR,                                 DAV_ERR_PROP_BAD_MAJOR,                                 "Prop database has the wrong major "                                 "version number and cannot be used.");        }        /* initialize a new metadata structure */        dav_set_bufsize(pool, &db->ns_table, sizeof(m));        memcpy(db->ns_table.buf, &m, sizeof(m));    }    else {        dav_propdb_metadata m;        long ns;        const char *uri;        dav_set_bufsize(pool, &db->ns_table, value.dsize);        memcpy(db->ns_table.buf, value.dptr, value.dsize);        memcpy(&m, value.dptr, sizeof(m));        if (m.major != DAV_DBVSN_MAJOR) {            dav_dbm_close(db);            return dav_new_error(pool, HTTP_INTERNAL_SERVER_ERROR,                                 DAV_ERR_PROP_BAD_MAJOR,                                 "Prop database has the wrong major "                                 "version number and cannot be used.");        }        db->version = m.minor;        db->ns_count = ntohs(m.ns_count);        dav_dbm_freedatum(db, value);        /* create db->uri_index */        for (ns = 0, uri = db->ns_table.buf + sizeof(dav_propdb_metadata);             ns++ < db->ns_count;             uri += strlen(uri) + 1) {            /* we must copy the key, in case ns_table.buf moves */            apr_hash_set(db->uri_index,                         apr_pstrdup(pool, uri), APR_HASH_KEY_STRING,                         (void *)ns);        }    }    *pdb = db;    return NULL;}static void dav_propdb_close(dav_db *db){    if (db->ns_table_dirty) {        dav_propdb_metadata m;        apr_datum_t key;        apr_datum_t value;        dav_error *err;        key.dptr = DAV_GDBM_NS_KEY;        key.dsize = DAV_GDBM_NS_KEY_LEN;        value.dptr = db->ns_table.buf;        value.dsize = db->ns_table.cur_len;        /* fill in the metadata that we store into the prop db. */        m.major = DAV_DBVSN_MAJOR;        m.minor = db->version;          /* ### keep current minor version? */        m.ns_count = htons(db->ns_count);        memcpy(db->ns_table.buf, &m, sizeof(m));        err = dav_dbm_store(db, key, value);        /* ### what to do with the error? */    }    dav_dbm_close(db);}static dav_error * dav_propdb_define_namespaces(dav_db *db, dav_xmlns_info *xi){    int ns;    const char *uri = db->ns_table.buf + sizeof(dav_propdb_metadata);    /* within the prop values, we use "ns%d" for prefixes... register them */    for (ns = 0; ns < db->ns_count; ++ns, uri += strlen(uri) + 1) {        /* Empty URIs signify the empty namespace. These do not get a           namespace prefix. when we generate the value, we will simply           leave off the prefix, which is defined by mod_dav to be the           empty namespace. */        if (*uri == '\0')            continue;        /* ns_table.buf can move, so copy its value (we want the values to           last as long as the provided dav_xmlns_info). */        dav_xmlns_add(xi,                      apr_psprintf(xi->pool, "ns%d", ns),                      apr_pstrdup(xi->pool, uri));    }    return NULL;}static dav_error * dav_propdb_output_value(dav_db *db,                                           const dav_prop_name *name,                                           dav_xmlns_info *xi,                                           apr_text_header *phdr,                                           int *found){    apr_datum_t key = dav_build_key(db, name);    apr_datum_t value;    dav_error *err;    if ((err = dav_dbm_fetch(db, key, &value)) != NULL)        return err;    if (value.dptr == NULL) {        *found = 0;        return NULL;    }    *found = 1;    dav_append_prop(db->pool, key.dptr, value.dptr, phdr);    dav_dbm_freedatum(db, value);    return NULL;}static dav_error * dav_propdb_map_namespaces(    dav_db *db,    const apr_array_header_t *namespaces,    dav_namespace_map **mapping){    dav_namespace_map *m = apr_palloc(db->pool, sizeof(*m));    int i;    int *pmap;    const char **puri;    /*    ** Iterate over the provided namespaces. If a namespace already appears    ** in our internal map of URI -> ns_id, then store that in the map. If    ** we don't know the namespace yet, then add it to the map and to our    ** table of known namespaces.    */    m->ns_map = pmap = apr_palloc(db->pool, namespaces->nelts * sizeof(*pmap));    for (i = namespaces->nelts, puri = (const char **)namespaces->elts;         i-- > 0;         ++puri, ++pmap) {        const char *uri = *puri;        apr_size_t uri_len = strlen(uri);        long ns_id = (long)apr_hash_get(db->uri_index, uri, uri_len);        if (ns_id == 0) {            dav_check_bufsize(db->pool, &db->ns_table, uri_len + 1);            memcpy(db->ns_table.buf + db->ns_table.cur_len, uri, uri_len + 1);            db->ns_table.cur_len += uri_len + 1;            /* copy the uri in case the passed-in namespaces changes in               some way. */            apr_hash_set(db->uri_index, apr_pstrdup(db->pool, uri), uri_len,                         (void *)((long)(db->ns_count + 1)));            db->ns_table_dirty = 1;            *pmap = db->ns_count++;        }        else {            *pmap = ns_id - 1;        }    }    *mapping = m;    return NULL;}static dav_error * dav_propdb_store(dav_db *db, const dav_prop_name *name,                                    const apr_xml_elem *elem,                                    dav_namespace_map *mapping){    apr_datum_t key = dav_build_key(db, name);    apr_datum_t value;    /* Note: mapping->ns_map was set up in dav_propdb_map_namespaces() */    /* ### use a db- subpool for these values? clear on exit? */    /* quote all the values in the element */    /* ### be nice to do this without affecting the element itself */    /* ### of course, the cast indicates Badness is occurring here */    apr_xml_quote_elem(db->pool, (apr_xml_elem *)elem);    /* generate a text blob for the xml:lang plus the contents */    apr_xml_to_text(db->pool, elem, APR_XML_X2T_LANG_INNER, NULL,                    mapping->ns_map,                    (const char **)&value.dptr, &value.dsize);    return dav_dbm_store(db, key, value);}static dav_error * dav_propdb_remove(dav_db *db, const dav_prop_name *name){    apr_datum_t key = dav_build_key(db, name);    return dav_dbm_delete(db, key);}static int dav_propdb_exists(dav_db *db, const dav_prop_name *name){    apr_datum_t key = dav_build_key(db, name);    return dav_dbm_exists(db, key);}static const char *dav_get_ns_table_uri(dav_db *db, int ns_id){    const char *p = db->ns_table.buf + sizeof(dav_propdb_metadata);    while (ns_id--)        p += strlen(p) + 1;    return p;}static void dav_set_name(dav_db *db, dav_prop_name *pname){    const char *s = db->iter.dptr;    if (s == NULL) {        pname->ns = pname->name = NULL;    }    else if (*s == ':') {        pname->ns = "";        pname->name = s + 1;    }    else {        int id = atoi(s);        pname->ns = dav_get_ns_table_uri(db, id);        if (s[1] == ':') {            pname->name = s + 2;        }        else {            pname->name = ap_strchr_c(s + 2, ':') + 1;        }    }}static dav_error * dav_propdb_next_name(dav_db *db, dav_prop_name *pname){    dav_error *err;    /* free the previous key. note: if the loop is aborted, then the DBM       will toss the key (via pool cleanup) */    if (db->iter.dptr != NULL)        dav_dbm_freedatum(db, db->iter);    if ((err = dav_dbm_nextkey(db, &db->iter)) != NULL)        return err;    /* skip past the METADATA key */    if (db->iter.dptr != NULL && *db->iter.dptr == 'M')        return dav_propdb_next_name(db, pname);    dav_set_name(db, pname);    return NULL;}static dav_error * dav_propdb_first_name(dav_db *db, dav_prop_name *pname){    dav_error *err;    if ((err = dav_dbm_firstkey(db, &db->iter)) != NULL)        return err;    /* skip past the METADATA key */    if (db->iter.dptr != NULL && *db->iter.dptr == 'M')        return dav_propdb_next_name(db, pname);    dav_set_name(db, pname);    return NULL;}static dav_error * dav_propdb_get_rollback(dav_db *db,                                           const dav_prop_name *name,                                           dav_deadprop_rollback **prollback){    dav_deadprop_rollback *rb = apr_pcalloc(db->pool, sizeof(*rb));    apr_datum_t key;    apr_datum_t value;    dav_error *err;    key = dav_build_key(db, name);    rb->key.dptr = apr_pstrdup(db->pool, key.dptr);    rb->key.dsize = key.dsize;    if ((err = dav_dbm_fetch(db, key, &value)) != NULL)        return err;    if (value.dptr != NULL) {        rb->value.dptr = apr_pmemdup(db->pool, value.dptr, value.dsize);        rb->value.dsize = value.dsize;    }    *prollback = rb;    return NULL;}static dav_error * dav_propdb_apply_rollback(dav_db *db,                                             dav_deadprop_rollback *rollback){    if (rollback->value.dptr == NULL) {        /* don't fail if the thing isn't really there. */        (void) dav_dbm_delete(db, rollback->key);        return NULL;    }    return dav_dbm_store(db, rollback->key, rollback->value);}const dav_hooks_db dav_hooks_db_dbm ={    dav_propdb_open,    dav_propdb_close,    dav_propdb_define_namespaces,    dav_propdb_output_value,    dav_propdb_map_namespaces,    dav_propdb_store,    dav_propdb_remove,    dav_propdb_exists,    dav_propdb_first_name,    dav_propdb_next_name,    dav_propdb_get_rollback,    dav_propdb_apply_rollback,    NULL /* ctx */};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -