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

📄 ne_props.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    WebDAV property manipulation   Copyright (C) 2000-2004, Joe Orton <joe@manyfish.co.uk>   This library is free software; you can redistribute it and/or   modify it under the terms of the GNU Library General Public   License as published by the Free Software Foundation; either   version 2 of the License, or (at your option) any later version.      This library is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   Library General Public License for more details.   You should have received a copy of the GNU Library General Public   License along with this library; if not, write to the Free   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,   MA 02111-1307, USA*/#include "config.h"#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#ifdef HAVE_STRING_H#include <string.h>#endif#include "ne_alloc.h"#include "ne_xml.h"#include "ne_props.h"#include "ne_basic.h"#include "ne_locks.h"/* don't store flat props with a value > 10K */#define MAX_FLATPROP_LEN (102400)struct ne_propfind_handler_s {    ne_session *sess;    ne_request *request;    int has_props; /* whether we've already written some		    * props to the body. */    ne_buffer *body;        ne_207_parser *parser207;    ne_xml_parser *parser;    /* Callback to create the private structure. */    ne_props_create_complex private_creator;    void *private_userdata;        /* Current propset, or NULL if none being processed. */    ne_prop_result_set *current;    ne_buffer *value; /* current flat property value */    int depth; /* nesting depth within a flat property */    ne_props_result callback;    void *userdata;};#define ELM_flatprop (NE_207_STATE_TOP - 1)/* We build up the results of one 'response' element in memory. */struct prop {    char *name, *nspace, *value, *lang;    /* Store a ne_propname here too, for convienience.  pname.name =     * name, pname.nspace = nspace, but they are const'ed in pname. */    ne_propname pname;};#define NSPACE(x) ((x) ? (x) : "")struct propstat {    struct prop *props;    int numprops;    ne_status status;};/* Results set. */struct ne_prop_result_set_s {    struct propstat *pstats;    int numpstats;    void *private;    char *href;};static int startelm(void *userdata, int state, const char *name, const char *nspace,	 const char **atts);static int endelm(void *userdata, int state, const char *name, const char *nspace);/* Handle character data; flat property value. */static int chardata(void *userdata, int state, const char *data, size_t len){    ne_propfind_handler *hdl = userdata;    if (state == ELM_flatprop && hdl->value->length < MAX_FLATPROP_LEN)        ne_buffer_append(hdl->value, data, len);    return 0;}ne_xml_parser *ne_propfind_get_parser(ne_propfind_handler *handler){    return handler->parser;}ne_request *ne_propfind_get_request(ne_propfind_handler *handler){    return handler->request;}static int propfind(ne_propfind_handler *handler, 		    ne_props_result results, void *userdata){    int ret;    ne_request *req = handler->request;    /* Register the flat property handler to catch any properties      * which the user isn't handling as 'complex'. */    ne_xml_push_handler(handler->parser, startelm, chardata, endelm, handler);    handler->callback = results;    handler->userdata = userdata;    ne_set_request_body_buffer(req, handler->body->data,			       ne_buffer_size(handler->body));    ne_add_request_header(req, "Content-Type", NE_XML_MEDIA_TYPE);        ne_add_response_body_reader(req, ne_accept_207, ne_xml_parse_v, 				  handler->parser);    ret = ne_request_dispatch(req);    if (ret == NE_OK && ne_get_status(req)->klass != 2) {	ret = NE_ERROR;    } else if (!ne_xml_valid(handler->parser)) {	ne_set_error(handler->sess, "%s", ne_xml_get_error(handler->parser));	ret = NE_ERROR;    }    return ret;}static void set_body(ne_propfind_handler *hdl, const ne_propname *names){    ne_buffer *body = hdl->body;    int n;        if (!hdl->has_props) {	ne_buffer_zappend(body, "<prop>" EOL);	hdl->has_props = 1;    }    for (n = 0; names[n].name != NULL; n++) {	ne_buffer_concat(body, "<", names[n].name, " xmlns=\"", 			 NSPACE(names[n].nspace), "\"/>" EOL, NULL);    }}int ne_propfind_allprop(ne_propfind_handler *handler, 			 ne_props_result results, void *userdata){    ne_buffer_zappend(handler->body, "<allprop/></propfind>" EOL);    return propfind(handler, results, userdata);}int ne_propfind_named(ne_propfind_handler *handler, const ne_propname *props,		       ne_props_result results, void *userdata){    set_body(handler, props);    ne_buffer_zappend(handler->body, "</prop></propfind>" EOL);    return propfind(handler, results, userdata);}/* The easy one... PROPPATCH */int ne_proppatch(ne_session *sess, const char *uri, 		 const ne_proppatch_operation *items){    ne_request *req = ne_request_create(sess, "PROPPATCH", uri);    ne_buffer *body = ne_buffer_create();    int n, ret;        /* Create the request body */    ne_buffer_zappend(body, "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" EOL		     "<D:propertyupdate xmlns:D=\"DAV:\">");    for (n = 0; items[n].name != NULL; n++) {	const char *elm = (items[n].type == ne_propset) ? "set" : "remove";	/* <set><prop><prop-name>value</prop-name></prop></set> */	ne_buffer_concat(body, "<D:", elm, "><D:prop>"			 "<", items[n].name->name, NULL);		if (items[n].name->nspace) {	    ne_buffer_concat(body, " xmlns=\"", items[n].name->nspace, "\"", NULL);	}	if (items[n].type == ne_propset) {	    ne_buffer_concat(body, ">", items[n].value, NULL);	} else {	    ne_buffer_append(body, ">", 1);	}	ne_buffer_concat(body, "</", items[n].name->name, "></D:prop></D:", elm, ">"			 EOL, NULL);    }	    ne_buffer_zappend(body, "</D:propertyupdate>" EOL);    ne_set_request_body_buffer(req, body->data, ne_buffer_size(body));    ne_add_request_header(req, "Content-Type", NE_XML_MEDIA_TYPE);    #ifdef USE_DAV_LOCKS    ne_lock_using_resource(req, uri, NE_DEPTH_ZERO);#endif    ret = ne_simple_request(sess, req);        ne_buffer_destroy(body);    return ret;}/* Compare two property names. */static int pnamecmp(const ne_propname *pn1, const ne_propname *pn2){    if (pn1->nspace == NULL && pn2->nspace != NULL) {	return 1;    } else if (pn1->nspace != NULL && pn2->nspace == NULL) {	return -1;    } else if (pn1->nspace == NULL) {	return strcmp(pn1->name, pn2->name);    } else {	return (strcmp(pn1->nspace, pn2->nspace) ||		strcmp(pn1->name, pn2->name));    }}/* Find property in 'set' with name 'pname'.  If found, set pstat_ret * to the containing propstat, likewise prop_ret, and returns zero. * If not found, returns non-zero.  */static int findprop(const ne_prop_result_set *set, const ne_propname *pname,		    struct propstat **pstat_ret, struct prop **prop_ret){        int ps, p;    for (ps = 0; ps < set->numpstats; ps++) {	for (p = 0; p < set->pstats[ps].numprops; p++) {	    struct prop *prop = &set->pstats[ps].props[p];	    if (pnamecmp(&prop->pname, pname) == 0) {		if (pstat_ret != NULL)		    *pstat_ret = &set->pstats[ps];		if (prop_ret != NULL)		    *prop_ret = prop;		return 0;	    }	}    }    return -1;}const char *ne_propset_value(const ne_prop_result_set *set,			      const ne_propname *pname){    struct prop *prop;        if (findprop(set, pname, NULL, &prop)) {	return NULL;    } else {	return prop->value;    }}const char *ne_propset_lang(const ne_prop_result_set *set,			     const ne_propname *pname){    struct prop *prop;    if (findprop(set, pname, NULL, &prop)) {	return NULL;    } else {	return prop->lang;    }}void *ne_propfind_current_private(ne_propfind_handler *handler){    return handler->current ? handler->current->private : NULL;}void *ne_propset_private(const ne_prop_result_set *set){    return set->private;}int ne_propset_iterate(const ne_prop_result_set *set,			ne_propset_iterator iterator, void *userdata){

⌨️ 快捷键说明

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