/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
** DAV extension module for Apache 2.0.*
**  - Property database handling (repository-independent)
**
** NOTES:
**
**   PROPERTY DATABASE
**
**   This version assumes that there is a per-resource database provider
**   to record properties. The database provider decides how and where to
**   store these databases.
**
**   The DBM keys for the properties have the following form:
**
**     namespace ":" propname
**
**   For example: 5:author
**
**   The namespace provides an integer index into the namespace table
**   (see below). propname is simply the property name, without a namespace
**   prefix.
**
**   A special case exists for properties that had a prefix starting with
**   "xml". The XML Specification reserves these for future use. mod_dav
**   stores and retrieves them unchanged. The keys for these properties
**   have the form:
**
**     ":" propname
**
**   The propname will contain the prefix and the property name. For
**   example, a key might be ":xmlfoo:name"
**
**   The ":name" style will also be used for properties that do not
**   exist within a namespace.
**
**   The DBM values consist of two null-terminated strings, appended
**   together (the null-terms are retained and stored in the database).
**   The first string is the xml:lang value for the property. An empty
**   string signifies that a lang value was not in context for the value.
**   The second string is the property value itself.
**
**
**   NAMESPACE TABLE
**
**   The namespace table is an array that lists each of the namespaces
**   that are in use by the properties in the given propdb. Each entry
**   in the array is a simple URI.
**
**   For example: http://www.foo.bar/standards/props/
**
**   The prefix used for the property is stripped and the URI for it
**   is entered into the namespace table. Also, any namespaces used
**   within the property value will be entered into the table (and
**   stripped from the child elements).
**
**   The namespaces are stored in the DBM database under the "METADATA" key.
**
**
**   STRIPPING NAMESPACES
**
**   Within the property values, the namespace declarations (xmlns...)
**   are stripped. Each element and attribute will have its prefix removed
**   and a new prefix inserted.
**
**   This must be done so that we can return multiple properties in a
**   PROPFIND which may have (originally) used conflicting prefixes. For
**   that case, we must bind all property value elements to new namespace
**   values.
**
**   This implies that clients must NOT be sensitive to the namespace
**   prefix used for their properties. It WILL change when the properties
**   are returned (we return them as "ns<index>", e.g. "ns5"). Also, the
**   property value can contain ONLY XML elements and CDATA. PI and comment
**   elements will be stripped. CDATA whitespace will be preserved, but
**   whitespace within element tags will be altered. Attribute ordering
**   may be altered. Element and CDATA ordering will be preserved.
**
**
**   ATTRIBUTES ON PROPERTY NAME ELEMENTS
**
**   When getting/setting properties, the XML used looks like:
**
**     <prop>
**       <propname1>value</propname1>
**       <propname2>value</propname1>
**     </prop>
**
**   This implementation (mod_dav) DOES NOT save any attributes that are
**   associated with the <propname1> element. The property value is deemed
**   to be only the contents ("value" in the above example).
**
**   We do store the xml:lang value (if any) that applies to the context
**   of the <propname1> element. Whether the xml:lang attribute is on
**   <propname1> itself, or from a higher level element, we will store it
**   with the property value.
**
**
**   VERSIONING
**
**   The DBM db contains a key named "METADATA" that holds database-level
**   information, such as the namespace table. The record also contains the
**   db's version number as the very first 16-bit value. This first number
**   is actually stored as two single bytes: the first byte is a "major"
**   version number. The second byte is a "minor" number.
**
**   If the major number is not what mod_dav expects, then the db is closed
**   immediately and an error is returned. A minor number change is
**   acceptable -- it is presumed that old/new dav_props.c can deal with
**   the database format. For example, a newer dav_props might update the
**   minor value and append information to the end of the metadata record
**   (which would be ignored by previous versions).
**
**
** ISSUES:
**
**   At the moment, for the dav_get_allprops() and dav_get_props() functions,
**   we must return a set of xmlns: declarations for ALL known namespaces
**   in the file. There isn't a way to filter this because we don't know
**   which are going to be used or not. Examining property names is not
**   sufficient because the property values could use entirely different
**   namespaces.
**
**   ==> we must devise a scheme where we can "garbage collect" the namespace
**       entries from the property database.
*/

#include "apr.h"
#include "apr_strings.h"

#define APR_WANT_STDIO
#define APR_WANT_BYTEFUNC
#include "apr_want.h"

#include "mod_dav.h"

#include "http_log.h"
#include "http_request.h"

/*
** There is some rough support for writable DAV:getcontenttype and
** DAV:getcontentlanguage properties. If this #define is (1), then
** this support is disabled.
**
** We are disabling it because of a lack of support in GET and PUT
** operations. For GET, it would be "expensive" to look for a propdb,
** open it, and attempt to extract the Content-Type and Content-Language
** values for the response.
** (Handling the PUT would not be difficult, though)
*/
#define DAV_DISABLE_WRITABLE_PROPS     1

#define DAV_EMPTY_VALUE                "\0"    /* TWO null terms */

struct dav_propdb {
    apr_pool_t *p;                /* the pool we should use */
    request_rec *r;               /* the request record */

    const dav_resource *resource; /* the target resource */

    int deferred;                 /* open of db has been deferred */
    dav_db *db;                   /* underlying database containing props */

    apr_array_header_t *ns_xlate; /* translation of an elem->ns to URI */
    dav_namespace_map *mapping;   /* namespace mapping */

    dav_lockdb *lockdb;           /* the lock database */

    dav_buffer wb_lock;           /* work buffer for lockdiscovery property */

    /* if we ever run a GET subreq, it will be stored here */
    request_rec *subreq;

    /* hooks we should use for processing (based on the target resource) */
    const dav_hooks_db *db_hooks;
};

/* NOTE: dav_core_props[] and the following enum must stay in sync. */
/* ### move these into a "core" liveprop provider? */
static const char * const dav_core_props[] =
{
    "getcontenttype",
    "getcontentlanguage",
    "lockdiscovery",
    "supportedlock",

    NULL        /* sentinel */
};
enum {
    DAV_PROPID_CORE_getcontenttype = DAV_PROPID_CORE,
    DAV_PROPID_CORE_getcontentlanguage,
    DAV_PROPID_CORE_lockdiscovery,
    DAV_PROPID_CORE_supportedlock,

    DAV_PROPID_CORE_UNKNOWN
};

/*
** This structure is used to track information needed for a rollback.
*/
typedef struct dav_rollback_item {
    /* select one of the two rollback context structures based on the
       value of dav_prop_ctx.is_liveprop */
    dav_deadprop_rollback *deadprop;
    dav_liveprop_rollback *liveprop;

} dav_rollback_item;


static int dav_find_liveprop_provider(dav_propdb *propdb,
                                      const char *ns_uri,
                                      const char *propname,
                                      const dav_hooks_liveprop **provider)
{
    int propid;

    *provider = NULL;

    if (ns_uri == NULL) {
        /* policy: liveprop providers cannot define no-namespace properties */
        return DAV_PROPID_CORE_UNKNOWN;
    }

    /* check liveprop providers first, so they can define core properties */
    propid = dav_run_find_liveprop(propdb->resource, ns_uri, propname,
                                   provider);
    if (propid != 0) {
        return propid;
    }

    /* check for core property */
    if (strcmp(ns_uri, "DAV:") == 0) {
        const char * const *p = dav_core_props;

        for (propid = DAV_PROPID_CORE; *p != NULL; ++p, ++propid)
            if (strcmp(propname, *p) == 0) {
                return propid;
            }
    }

    /* no provider for this property */
    return DAV_PROPID_CORE_UNKNOWN;
}

static void dav_find_liveprop(dav_propdb *propdb, apr_xml_elem *elem)
{
    const char *ns_uri;
    dav_elem_private *priv = elem->priv;
    const dav_hooks_liveprop *hooks;


    if (elem->ns == APR_XML_NS_NONE)
        ns_uri = NULL;
    else if (elem->ns == APR_XML_NS_DAV_ID)
        ns_uri = "DAV:";
    else
        ns_uri = APR_XML_GET_URI_ITEM(propdb->ns_xlate, elem->ns);

    priv->propid = dav_find_liveprop_provider(propdb, ns_uri, elem->name,
                                              &hooks);

    /* ### this test seems redundant... */
    if (priv->propid != DAV_PROPID_CORE_UNKNOWN) {
        priv->provider = hooks;
    }
}

/* is the live property read/write? */
static int dav_rw_liveprop(dav_propdb *propdb, dav_elem_private *priv)
{
    int propid = priv->propid;

    /*
    ** Check the liveprop provider (if this is a provider-defined prop)
    */
    if (priv->provider != NULL) {
        return (*priv->provider->is_writable)(propdb->resource, propid);
    }

    /* these are defined as read-only */
    if (propid == DAV_PROPID_CORE_lockdiscovery
#if DAV_DISABLE_WRITABLE_PROPS
        || propid == DAV_PROPID_CORE_getcontenttype
        || propid == DAV_PROPID_CORE_getcontentlanguage
#endif
        || propid == DAV_PROPID_CORE_supportedlock
        ) {

        return 0;
    }

    /* these are defined as read/write */
    if (propid == DAV_PROPID_CORE_getcontenttype
        || propid == DAV_PROPID_CORE_getcontentlanguage
        || propid == DAV_PROPID_CORE_UNKNOWN) {

        return 1;
    }

    /*
    ** We don't recognize the property, so it must be dead (and writable)
    */
    return 1;
}

/* do a sub-request to fetch properties for the target resource's URI. */
static void dav_do_prop_subreq(dav_propdb *propdb)
{
    /* need to escape the uri that's in the resource struct because during
     * the property walker it's not encoded. */
    const char *e_uri = ap_escape_uri(propdb->resource->pool,
                                      propdb->resource->uri);

    /* perform a "GET" on the resource's URI (note that the resource
       may not correspond to the current request!). */
    propdb->subreq = ap_sub_req_lookup_uri(e_uri, propdb->r, NULL);
}

static dav_error * dav_insert_coreprop(dav_propdb *propdb,
                                       int propid, const char *name,
                                       dav_prop_insert what,
                                       apr_text_header *phdr,
                                       dav_prop_insert *inserted)
{
    const char *value = NULL;
    dav_error *err;

    *inserted = DAV_PROP_INSERT_NOTDEF;

    /* fast-path the common case */
    if (propid == DAV_PROPID_CORE_UNKNOWN)
        return NULL;

    switch (propid) {

    case DAV_PROPID_CORE_lockdiscovery:
        if (propdb->lockdb != NULL) {
            dav_lock *locks;

            if ((err = dav_lock_query(propdb->lockdb, propdb->resource,
                                      &locks)) != NULL) {
                return dav_push_error(propdb->p, err->status, 0,
                                      "DAV:lockdiscovery could not be "
                                      "determined due to a problem fetching "
                                      "the locks for this resource.",
                                      err);
            }

            /* fast-path the no-locks case */
            if (locks == NULL) {
                value = "";
            }
            else {
                /*
                ** This may modify the buffer. value may point to
                ** wb_lock.pbuf or a string constant.
                */
                value = dav_lock_get_activelock(propdb->r, locks,
                                                &propdb->wb_lock);

                /* make a copy to isolate it from changes to wb_lock */
                value = apr_pstrdup(propdb->p, propdb->wb_lock.buf);
            }
        }
        break;

    case DAV_PROPID_CORE_supportedlock:
        if (propdb->lockdb != NULL) {
            value = (*propdb->lockdb->hooks->get_supportedlock)(propdb->resource);
        }
        break;

    case DAV_PROPID_CORE_getcontenttype:
        if (propdb->subreq == NULL) {
            dav_do_prop_subreq(propdb);
        }
        if (propdb->subreq->content_type != NULL) {
            value = propdb->subreq->content_type;
        }
        break;

    case DAV_PROPID_CORE_getcontentlanguage:
    {
        const char *lang;

        if (propdb->subreq == NULL) {
            dav_do_prop_subreq(propdb);
        }
        if ((lang = apr_table_get(propdb->subreq->headers_out,
                                 "Content-Language")) != NULL) {
            value = lang;
        }
        break;
    }

    default:
        /* fall through to interpret as a dead property */
        break;
    }

    /* if something was supplied, then insert it */
    if (value != NULL) {
        const char *s;

        if (what == DAV_PROP_INSERT_SUPPORTED) {
            /* use D: prefix to refer to the DAV: namespace URI,
             * and let the namespace attribute default to "DAV:"
             */
            s = apr_psprintf(propdb->p,
                            "<D:supported-live-property D:name=\"%s\"/>" DEBUG_CR,
                            name);
        }
        else if (what == DAV_PROP_INSERT_VALUE && *value != '\0') {
            /* use D: prefix to refer to the DAV: namespace URI */
            s = apr_psprintf(propdb->p, "<D:%s>%s</D:%s>" DEBUG_CR,
                            name, value, name);
        }
        else {
            /* use D: prefix to refer to the DAV: namespace URI */
            s = apr_psprintf(propdb->p, "<D:%s/>" DEBUG_CR, name);
        }
        apr_text_append(propdb->p, phdr, s);

        *inserted = what;
    }

    return NULL;
}

static dav_error * dav_insert_liveprop(dav_propdb *propdb,
                                       const apr_xml_elem *elem,
                                       dav_prop_insert what,
                                       apr_text_header *phdr,
                                       dav_prop_insert *inserted)
{
    dav_elem_private *priv = elem->priv;

    *inserted = DAV_PROP_INSERT_NOTDEF;

    if (priv->provider == NULL) {
        /* this is a "core" property that we define */
        return dav_insert_coreprop(propdb, priv->propid, elem->name,
                                   what, phdr, inserted);
    }

    /* ask the provider (that defined this prop) to insert the prop */
    *inserted = (*priv->provider->insert_prop)(propdb->resource, priv->propid,
                                               what, phdr);

    return NULL;
}

static void dav_output_prop_name(apr_pool_t *pool,
                                 const dav_prop_name *name,
                                 dav_xmlns_info *xi,
                                 apr_text_header *phdr)
{
    const char *s;

    if (*name->ns == '\0')
        s = apr_psprintf(pool, "<%s/>" DEBUG_CR, name->name);
    else {
        const char *prefix = dav_xmlns_add_uri(xi, name->ns);

        s = apr_psprintf(pool, "<%s:%s/>" DEBUG_CR, prefix, name->name);
    }

    apr_text_append(pool, phdr, s);
}

static void dav_insert_xmlns(apr_pool_t *p, const char *pre_prefix, long ns,
                             const char *ns_uri, apr_text_header *phdr)
{
    const char *s;

    s = apr_psprintf(p, " xmlns:%s%ld=\"%s\"", pre_prefix, ns, ns_uri);
    apr_text_append(p, phdr, s);
}

static dav_error *dav_really_open_db(dav_propdb *propdb, int ro)
{
    dav_error *err;

    /* we're trying to open the db; turn off the 'deferred' flag */
    propdb->deferred = 0;

    /* ask the DB provider to open the thing */
    err = (*propdb->db_hooks->open)(propdb->p, propdb->resource, ro,
                                    &propdb->db);
    if (err != NULL) {
        return dav_push_error(propdb->p, HTTP_INTERNAL_SERVER_ERROR,
                              DAV_ERR_PROP_OPENING,
                              "Could not open the property database.",
                              err);
    }

    /*
    ** NOTE: propdb->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.
    */

    return NULL;
}

DAV_DECLARE(dav_error *)dav_open_propdb(request_rec *r, dav_lockdb *lockdb,
                                        const dav_resource *resource,
                                        int ro,
                                        apr_array_header_t * ns_xlate,
                                        dav_propdb **p_propdb)
{
    dav_propdb *propdb = apr_pcalloc(r->pool, sizeof(*propdb));

    *p_propdb = NULL;

#if DAV_DEBUG
    if (resource->uri == NULL) {
        return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0, 0,
                             "INTERNAL DESIGN ERROR: resource must define "
                             "its URI.");
    }
#endif

    propdb->r = r;
    apr_pool_create(&propdb->p, r->pool);
    propdb->resource = resource;
    propdb->ns_xlate = ns_xlate;

    propdb->db_hooks = DAV_GET_HOOKS_PROPDB(r);

    propdb->lockdb = lockdb;

    /* always defer actual open, to avoid expense of accessing db
     * when only live properties are involved
     */
    propdb->deferred = 1;

    /* ### what to do about closing the propdb on server failure? */

    *p_propdb = propdb;
    return NULL;
}

DAV_DECLARE(void) dav_close_propdb(dav_propdb *propdb)
{
    if (propdb->db != NULL) {
        (*propdb->db_hooks->close)(propdb->db);
    }

    /* Currently, mod_dav's pool usage doesn't allow clearing this pool. */
#if 0
    apr_pool_destroy(propdb->p);
#endif
}

DAV_DECLARE(dav_get_props_result) dav_get_allprops(dav_propdb *propdb,
                                                   dav_prop_insert what)
{
    const dav_hooks_db *db_hooks = propdb->db_hooks;
    apr_text_header hdr = { 0 };
    apr_text_header hdr_ns = { 0 };
    dav_get_props_result result = { 0 };
    int found_contenttype = 0;
    int found_contentlang = 0;
    dav_prop_insert unused_inserted;

    /* if not just getting supported live properties,
     * scan all properties in the dead prop database
     */
    if (what != DAV_PROP_INSERT_SUPPORTED) {
        if (propdb->deferred) {
            /* ### what to do with db open error? */
            (void) dav_really_open_db(propdb, 1 /*ro*/);
        }

        /* initialize the result with some start tags... */
        apr_text_append(propdb->p, &hdr,
                        "<D:propstat>" DEBUG_CR
                        "<D:prop>" DEBUG_CR);

        /* if there ARE properties, then scan them */
        if (propdb->db != NULL) {
            dav_xmlns_info *xi = dav_xmlns_create(propdb->p);
            dav_prop_name name;
            dav_error *err;

            /* define (up front) any namespaces the db might need */
            (void) (*db_hooks->define_namespaces)(propdb->db, xi);

            /* get the first property name, beginning the scan */
            err = (*db_hooks->first_name)(propdb->db, &name);
            while (!err && name.ns) {

                /*
                ** We also look for <DAV:getcontenttype> and
                ** <DAV:getcontentlanguage>. If they are not stored as dead
                ** properties, then we need to perform a subrequest to get
                ** their values (if any).
                */
                if (*name.ns == 'D' && strcmp(name.ns, "DAV:") == 0
                    && *name.name == 'g') {
                    if (strcmp(name.name, "getcontenttype") == 0) {
                        found_contenttype = 1;
                    }
                    else if (strcmp(name.name, "getcontentlanguage") == 0) {
                        found_contentlang = 1;
                    }
                }

                if (what == DAV_PROP_INSERT_VALUE) {
                    int found;

                    if ((err = (*db_hooks->output_value)(propdb->db, &name,
                                                         xi, &hdr,
                                                         &found)) != NULL) {
                        /* ### anything better to do? */
                        /* ### probably should enter a 500 error */
                        goto next_key;
                    }
                    /* assert: found == 1 */
                }
                else {
                    /* the value was not requested, so just add an empty
                       tag specifying the property name. */
                    dav_output_prop_name(propdb->p, &name, xi, &hdr);
                }

              next_key:
                err = (*db_hooks->next_name)(propdb->db, &name);
            }

            /* all namespaces have been entered into xi. generate them into
               the output now. */
            dav_xmlns_generate(xi, &hdr_ns);

        } /* propdb->db != NULL */

        /* add namespaces for all the liveprop providers */
        dav_add_all_liveprop_xmlns(propdb->p, &hdr_ns);
    }

    /* ask the liveprop providers to insert their properties */
    dav_run_insert_all_liveprops(propdb->r, propdb->resource, what, &hdr);

    /* insert the standard properties */
    /* ### should be handling the return errors here */
    (void)dav_insert_coreprop(propdb,
                              DAV_PROPID_CORE_supportedlock, "supportedlock",
                              what, &hdr, &unused_inserted);
    (void)dav_insert_coreprop(propdb,
                              DAV_PROPID_CORE_lockdiscovery, "lockdiscovery",
                              what, &hdr, &unused_inserted);

    /* if we didn't find these, then do the whole subreq thing. */
    if (!found_contenttype) {
        /* ### should be handling the return error here */
        (void)dav_insert_coreprop(propdb,
                                  DAV_PROPID_CORE_getcontenttype,
                                  "getcontenttype",
                                  what, &hdr, &unused_inserted);
    }
    if (!found_contentlang) {
        /* ### should be handling the return error here */
        (void)dav_insert_coreprop(propdb,
                                  DAV_PROPID_CORE_getcontentlanguage,
                                  "getcontentlanguage",
                                  what, &hdr, &unused_inserted);
    }

    /* if not just reporting on supported live props,
     * terminate the result */
    if (what != DAV_PROP_INSERT_SUPPORTED) {
        apr_text_append(propdb->p, &hdr,
                        "</D:prop>" DEBUG_CR
                        "<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR
                        "</D:propstat>" DEBUG_CR);
    }

    result.propstats = hdr.first;
    result.xmlns = hdr_ns.first;
    return result;
}

DAV_DECLARE(dav_get_props_result) dav_get_props(dav_propdb *propdb,
                                                apr_xml_doc *doc)
{
    const dav_hooks_db *db_hooks = propdb->db_hooks;
    apr_xml_elem *elem = dav_find_child(doc->root, "prop");
    apr_text_header hdr_good = { 0 };
    apr_text_header hdr_bad = { 0 };
    apr_text_header hdr_ns = { 0 };
    int have_good = 0;
    dav_get_props_result result = { 0 };
    char *marks_liveprop;
    dav_xmlns_info *xi;
    int xi_filled = 0;

    /* ### NOTE: we should pass in TWO buffers -- one for keys, one for
       the marks */

    /* we will ALWAYS provide a "good" result, even if it is EMPTY */
    apr_text_append(propdb->p, &hdr_good,
                   "<D:propstat>" DEBUG_CR
                   "<D:prop>" DEBUG_CR);

    /* ### the marks should be in a buffer! */
    /* allocate zeroed-memory for the marks. These marks indicate which
       liveprop namespaces we've generated into the output xmlns buffer */

    /* same for the liveprops */
    marks_liveprop = apr_pcalloc(propdb->p, dav_get_liveprop_ns_count() + 1);

    xi = dav_xmlns_create(propdb->p);

    for (elem = elem->first_child; elem; elem = elem->next) {
        dav_elem_private *priv;
        dav_error *err;
        dav_prop_insert inserted;
        dav_prop_name name;

        /*
        ** First try live property providers; if they don't handle
        ** the property, then try looking it up in the propdb.
        */

        if (elem->priv == NULL) {
            elem->priv = apr_pcalloc(propdb->p, sizeof(*priv));
        }
        priv = elem->priv;

        /* cache the propid; dav_get_props() could be called many times */
        if (priv->propid == 0)
            dav_find_liveprop(propdb, elem);

        if (priv->propid != DAV_PROPID_CORE_UNKNOWN) {

            /* insert the property. returns 1 if an insertion was done. */
            if ((err = dav_insert_liveprop(propdb, elem, DAV_PROP_INSERT_VALUE,
                                           &hdr_good, &inserted)) != NULL) {
                /* ### need to propagate the error to the caller... */
                /* ### skip it for now, as if nothing was inserted */
            }
            if (inserted == DAV_PROP_INSERT_VALUE) {
                have_good = 1;

                /*
                ** Add the liveprop's namespace URIs. Note that provider==NULL
                ** for core properties.
                */
                if (priv->provider != NULL) {
                    const char * const * scan_ns_uri;

                    for (scan_ns_uri = priv->provider->namespace_uris;
                         *scan_ns_uri != NULL;
                         ++scan_ns_uri) {
                        long ns;

                        ns = dav_get_liveprop_ns_index(*scan_ns_uri);
                        if (marks_liveprop[ns])
                            continue;
                        marks_liveprop[ns] = 1;

                        dav_insert_xmlns(propdb->p, "lp", ns, *scan_ns_uri,
                                         &hdr_ns);
                    }
                }

                /* property added. move on to the next property. */
                continue;
            }
            else if (inserted == DAV_PROP_INSERT_NOTDEF) {
                /* nothing to do. fall thru to allow property to be handled
                   as a dead property */
            }
#if DAV_DEBUG
            else {
#if 0
                /* ### need to change signature to return an error */
                return dav_new_error(propdb->p, HTTP_INTERNAL_SERVER_ERROR, 0,
                                     0,
                                     "INTERNAL DESIGN ERROR: insert_liveprop "
                                     "did not insert what was asked for.");
#endif
            }
#endif
        }

        /* The property wasn't a live property, so look in the dead property
           database. */

        /* make sure propdb is really open */
        if (propdb->deferred) {
            /* ### what to do with db open error? */
            (void) dav_really_open_db(propdb, 1 /*ro*/);
        }

        if (elem->ns == APR_XML_NS_NONE)
            name.ns = "";
        else
            name.ns = APR_XML_GET_URI_ITEM(propdb->ns_xlate, elem->ns);
        name.name = elem->name;

        /* only bother to look if a database exists */
        if (propdb->db != NULL) {
            int found;

            if ((err = (*db_hooks->output_value)(propdb->db, &name,
                                                 xi, &hdr_good,
                                                 &found)) != NULL) {
                /* ### what to do? continue doesn't seem right... */
                continue;
            }

            if (found) {
                have_good = 1;

                /* if we haven't added the db's namespaces, then do so... */
                if (!xi_filled) {
                    (void) (*db_hooks->define_namespaces)(propdb->db, xi);
                    xi_filled = 1;
                }
                continue;
            }
        }

        /* not found as a live OR dead property. add a record to the "bad"
           propstats */

        /* make sure we've started our "bad" propstat */
        if (hdr_bad.first == NULL) {
            apr_text_append(propdb->p, &hdr_bad,
                            "<D:propstat>" DEBUG_CR
                            "<D:prop>" DEBUG_CR);
        }

        /* output this property's name (into the bad propstats) */
        dav_output_prop_name(propdb->p, &name, xi, &hdr_bad);
    }

    apr_text_append(propdb->p, &hdr_good,
                    "</D:prop>" DEBUG_CR
                    "<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR
                    "</D:propstat>" DEBUG_CR);

    /* default to start with the good */
    result.propstats = hdr_good.first;

    /* we may not have any "bad" results */
    if (hdr_bad.first != NULL) {
        /* "close" the bad propstat */
        apr_text_append(propdb->p, &hdr_bad,
                        "</D:prop>" DEBUG_CR
                        "<D:status>HTTP/1.1 404 Not Found</D:status>" DEBUG_CR
                        "</D:propstat>" DEBUG_CR);

        /* if there are no good props, then just return the bad */
        if (!have_good) {
            result.propstats = hdr_bad.first;
        }
        else {
            /* hook the bad propstat to the end of the good one */
            hdr_good.last->next = hdr_bad.first;
        }
    }

    /* add in all the various namespaces, and return them */
    dav_xmlns_generate(xi, &hdr_ns);
    result.xmlns = hdr_ns.first;

    return result;
}

DAV_DECLARE(void) dav_get_liveprop_supported(dav_propdb *propdb,
                                             const char *ns_uri,
                                             const char *propname,
                                             apr_text_header *body)
{
    int propid;
    const dav_hooks_liveprop *hooks;

    propid = dav_find_liveprop_provider(propdb, ns_uri, propname, &hooks);

    if (propid != DAV_PROPID_CORE_UNKNOWN) {
        if (hooks == NULL) {
            /* this is a "core" property that we define */
            dav_prop_insert unused_inserted;
            dav_insert_coreprop(propdb, propid, propname,
                                DAV_PROP_INSERT_SUPPORTED, body, &unused_inserted);
        }
        else {
            (*hooks->insert_prop)(propdb->resource, propid,
                                  DAV_PROP_INSERT_SUPPORTED, body);
        }
    }
}

DAV_DECLARE_NONSTD(void) dav_prop_validate(dav_prop_ctx *ctx)
{
    dav_propdb *propdb = ctx->propdb;
    apr_xml_elem *prop = ctx->prop;
    dav_elem_private *priv;

    priv = ctx->prop->priv = apr_pcalloc(propdb->p, sizeof(*priv));

    /*
    ** Check to see if this is a live property, and fill the fields
    ** in the XML elem, as appropriate.
    **
    ** Verify that the property is read/write. If not, then it cannot
    ** be SET or DELETEd.
    */
    if (priv->propid == 0) {
        dav_find_liveprop(propdb, prop);

        /* it's a liveprop if a provider was found */
        /* ### actually the "core" props should really be liveprops, but
           ### there is no "provider" for those and the r/w props are
           ### treated as dead props anyhow */
        ctx->is_liveprop = priv->provider != NULL;
    }

    if (!dav_rw_liveprop(propdb, priv)) {
        ctx->err = dav_new_error(propdb->p, HTTP_CONFLICT,
                                 DAV_ERR_PROP_READONLY, 0,
                                 "Property is read-only.");
        return;
    }

    if (ctx->is_liveprop) {
        int defer_to_dead = 0;

        ctx->err = (*priv->provider->patch_validate)(propdb->resource,
                                                     prop, ctx->operation,
                                                     &ctx->liveprop_ctx,
                                                     &defer_to_dead);
        if (ctx->err != NULL || !defer_to_dead)
            return;

        /* clear is_liveprop -- act as a dead prop now */
        ctx->is_liveprop = 0;
    }

    /*
    ** The property is supposed to be stored into the dead-property
    ** database. Make sure the thing is truly open (and writable).
    */
    if (propdb->deferred
        && (ctx->err = dav_really_open_db(propdb, 0 /* ro */)) != NULL) {
        return;
    }

    /*
    ** There should be an open, writable database in here!
    **
    ** Note: the database would be NULL if it was opened readonly and it
    **       did not exist.
    */
    if (propdb->db == NULL) {
        ctx->err = dav_new_error(propdb->p, HTTP_INTERNAL_SERVER_ERROR,
                                 DAV_ERR_PROP_NO_DATABASE, 0,
                                 "Attempted to set/remove a property "
                                 "without a valid, open, read/write "
                                 "property database.");
        return;
    }

    if (ctx->operation == DAV_PROP_OP_SET) {
        /*
        ** Prep the element => propdb namespace index mapping, inserting
        ** namespace URIs into the propdb that don't exist.
        */
        (void) (*propdb->db_hooks->map_namespaces)(propdb->db,
                                                   propdb->ns_xlate,
                                                   &propdb->mapping);
    }
    else if (ctx->operation == DAV_PROP_OP_DELETE) {
        /*
        ** There are no checks to perform here. If a property exists, then
        ** we will delete it. If it does not exist, then it does not matter
        ** (see S12.13.1).
        **
        ** Note that if a property does not exist, that does not rule out
        ** that a SET will occur during this PROPPATCH (thusly creating it).
        */
    }
}

DAV_DECLARE_NONSTD(void) dav_prop_exec(dav_prop_ctx *ctx)
{
    dav_propdb *propdb = ctx->propdb;
    dav_error *err = NULL;
    dav_elem_private *priv = ctx->prop->priv;

    ctx->rollback = apr_pcalloc(propdb->p, sizeof(*ctx->rollback));

    if (ctx->is_liveprop) {
        err = (*priv->provider->patch_exec)(propdb->resource,
                                            ctx->prop, ctx->operation,
                                            ctx->liveprop_ctx,
                                            &ctx->rollback->liveprop);
    }
    else {
        dav_prop_name name;

        if (ctx->prop->ns == APR_XML_NS_NONE)
            name.ns = "";
        else
            name.ns = APR_XML_GET_URI_ITEM(propdb->ns_xlate, ctx->prop->ns);
        name.name = ctx->prop->name;

        /* save the old value so that we can do a rollback. */
        if ((err = (*propdb->db_hooks
                    ->get_rollback)(propdb->db, &name,
                                    &ctx->rollback->deadprop)) != NULL)
            goto error;

        if (ctx->operation == DAV_PROP_OP_SET) {

            /* Note: propdb->mapping was set in dav_prop_validate() */
            err = (*propdb->db_hooks->store)(propdb->db, &name, ctx->prop,
                                             propdb->mapping);

            /*
            ** If an error occurred, then assume that we didn't change the
            ** value. Remove the rollback item so that we don't try to set
            ** its value during the rollback.
            */
            /* ### euh... where is the removal? */
        }
        else if (ctx->operation == DAV_PROP_OP_DELETE) {

            /*
            ** Delete the property. Ignore errors -- the property is there, or
            ** we are deleting it for a second time.
            */
            /* ### but what about other errors? */
            (void) (*propdb->db_hooks->remove)(propdb->db, &name);
        }
    }

  error:
    /* push a more specific error here */
    if (err != NULL) {
        /*
        ** Use HTTP_INTERNAL_SERVER_ERROR because we shouldn't have seen
        ** any errors at this point.
        */
        ctx->err = dav_push_error(propdb->p, HTTP_INTERNAL_SERVER_ERROR,
                                  DAV_ERR_PROP_EXEC,
                                  "Could not execute PROPPATCH.", err);
    }
}

DAV_DECLARE_NONSTD(void) dav_prop_commit(dav_prop_ctx *ctx)
{
    dav_elem_private *priv = ctx->prop->priv;

    /*
    ** Note that a commit implies ctx->err is NULL. The caller should assume
    ** a status of HTTP_OK for this case.
    */

    if (ctx->is_liveprop) {
        (*priv->provider->patch_commit)(ctx->propdb->resource,
                                        ctx->operation,
                                        ctx->liveprop_ctx,
                                        ctx->rollback->liveprop);
    }
}

DAV_DECLARE_NONSTD(void) dav_prop_rollback(dav_prop_ctx *ctx)
{
    dav_error *err = NULL;
    dav_elem_private *priv = ctx->prop->priv;

    /* do nothing if there is no rollback information. */
    if (ctx->rollback == NULL)
        return;

    /*
    ** ### if we have an error, and a rollback occurs, then the namespace
    ** ### mods should not happen at all. Basically, the namespace management
    ** ### is simply a bitch.
    */

    if (ctx->is_liveprop) {
        err = (*priv->provider->patch_rollback)(ctx->propdb->resource,
                                                ctx->operation,
                                                ctx->liveprop_ctx,
                                                ctx->rollback->liveprop);
    }
    else {
        err = (*ctx->propdb->db_hooks
               ->apply_rollback)(ctx->propdb->db, ctx->rollback->deadprop);
    }

    if (err != NULL) {
        if (ctx->err == NULL)
            ctx->err = err;
        else {
            dav_error *scan = err;

            /* hook previous errors at the end of the rollback error */
            while (scan->prev != NULL)
                scan = scan->prev;
            scan->prev = ctx->err;
            ctx->err = err;
        }
    }
}
