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

📄 ne_locks.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 2 页
字号:
static int parse_depth(const char *depth){    if (strcasecmp(depth, "infinity") == 0) {	return NE_DEPTH_INFINITE;    } else if (isdigit(depth[0])) {	return atoi(depth);    } else {	return -1;    }}static long parse_timeout(const char *timeout){    if (strcasecmp(timeout, "infinite") == 0) {	return NE_TIMEOUT_INFINITE;    } else if (strncasecmp(timeout, "Second-", 7) == 0) {	long to = strtol(timeout+7, NULL, 10);	if (to == LONG_MIN || to == LONG_MAX)	    return NE_TIMEOUT_INVALID;	return to;    } else {	return NE_TIMEOUT_INVALID;    }}static void discover_results(void *userdata, const char *href,			     const ne_prop_result_set *set){    struct discover_ctx *ctx = userdata;    struct ne_lock *lock = ne_propset_private(set);    const ne_status *status = ne_propset_status(set, &lock_props[0]);    /* Require at least that the lock has a token. */    if (lock->token) {	if (status && status->klass != 2) {	    ctx->results(ctx->userdata, NULL, lock->uri.path, status);	} else {	    ctx->results(ctx->userdata, lock, lock->uri.path, NULL);	}    }    else if (status) {	ctx->results(ctx->userdata, NULL, href, status);    }	    ne_lock_destroy(lock);    NE_DEBUG(NE_DBG_LOCKS, "End of response for %s\n", href);}static int end_element_common(struct ne_lock *l, int state, const char *cdata){    switch (state) {     case ELM_write:	l->type = ne_locktype_write;	break;    case ELM_exclusive:	l->scope = ne_lockscope_exclusive;	break;    case ELM_shared:	l->scope = ne_lockscope_shared;	break;    case ELM_depth:	NE_DEBUG(NE_DBG_LOCKS, "Got depth: %s\n", cdata);	l->depth = parse_depth(cdata);	if (l->depth == -1) {	    return -1;	}	break;    case ELM_timeout:	NE_DEBUG(NE_DBG_LOCKS, "Got timeout: %s\n", cdata);	l->timeout = parse_timeout(cdata);	if (l->timeout == NE_TIMEOUT_INVALID) {	    return -1;	}	break;    case ELM_owner:	l->owner = strdup(cdata);	break;    case ELM_href:	l->token = strdup(cdata);	break;    }    return 0;}/* End-element handler for lock discovery PROPFIND response */static int end_element_ldisc(void *userdata, int state,                              const char *nspace, const char *name){    struct ne_lock *lock = ne_propfind_current_private(userdata);    struct discover_ctx *ctx = userdata;    return end_element_common(lock, state, ctx->cdata->data);}static inline int can_accept(int parent, int id){    return (parent == NE_XML_STATEROOT && id == ELM_prop) ||        (parent == ELM_prop && id == ELM_lockdiscovery) ||        (parent == ELM_lockdiscovery && id == ELM_activelock) ||        (parent == ELM_activelock &&          (id == ELM_lockscope || id == ELM_locktype ||          id == ELM_depth || id == ELM_owner ||          id == ELM_timeout || id == ELM_locktoken)) ||        (parent == ELM_lockscope &&         (id == ELM_exclusive || id == ELM_shared)) ||        (parent == ELM_locktype && id == ELM_write) ||        (parent == ELM_locktoken && id == ELM_href);}static int ld_startelm(void *userdata, int parent,                       const char *nspace, const char *name,		       const char **atts){    struct discover_ctx *ctx = userdata;    int id = ne_xml_mapid(element_map, NE_XML_MAPLEN(element_map),                          nspace, name);        ne_buffer_clear(ctx->cdata);        if (can_accept(parent, id))        return id;    else        return NE_XML_DECLINE;}    #define MAX_CDATA (256)static int lk_cdata(void *userdata, int state,                    const char *cdata, size_t len){    struct lock_ctx *ctx = userdata;    if (ctx->cdata->used + len < MAX_CDATA)        ne_buffer_append(ctx->cdata, cdata, len);        return 0;}static int ld_cdata(void *userdata, int state,                    const char *cdata, size_t len){    struct discover_ctx *ctx = userdata;    if (ctx->cdata->used + len < MAX_CDATA)        ne_buffer_append(ctx->cdata, cdata, len);        return 0;}static int lk_startelm(void *userdata, int parent,                       const char *nspace, const char *name,		       const char **atts){    struct lock_ctx *ctx = userdata;    int id;    id = ne_xml_mapid(element_map, NE_XML_MAPLEN(element_map), nspace, name);    NE_DEBUG(NE_DBG_LOCKS, "lk_startelm: %s => %d\n", name, id);    /* Lock-Token header is a MUST requirement: if the token     * is not known, bail out. */    if (id == 0 || ctx->token == NULL)	return NE_XML_DECLINE;    /* TODO: only accept 'prop' as root for LOCK response */    if (!can_accept(parent, id))        return NE_XML_DECLINE;    if (id == ELM_activelock && !ctx->found) {	/* a new activelock */	ne_lock_free(&ctx->active);	memset(&ctx->active, 0, sizeof ctx->active);    }    ne_buffer_clear(ctx->cdata);    return id;}/* End-element handler for LOCK response */static int lk_endelm(void *userdata, int state,                     const char *nspace, const char *name){    struct lock_ctx *ctx = userdata;    if (ctx->found)	return 0;    if (end_element_common(&ctx->active, state, ctx->cdata->data))	return -1;    if (state == ELM_activelock) {	if (ctx->active.token && strcmp(ctx->active.token, ctx->token) == 0) {	    ctx->found = 1;	}    }    return 0;}static void *ld_create(void *userdata, const char *href){    struct discover_ctx *ctx = userdata;    struct ne_lock *lk = ne_lock_create();    if (ne_uri_parse(href, &lk->uri) != 0) {	ne_lock_destroy(lk);	return NULL;    }        if (!lk->uri.host)	ne_fill_server_uri(ctx->session, &lk->uri);    return lk;}/* Discover all locks on URI */int ne_lock_discover(ne_session *sess, const char *uri, 		     ne_lock_result callback, void *userdata){    ne_propfind_handler *handler;    struct discover_ctx ctx = {0};    int ret;        ctx.results = callback;    ctx.userdata = userdata;    ctx.session = sess;    ctx.cdata = ne_buffer_create();    handler = ne_propfind_create(sess, uri, NE_DEPTH_ZERO);    ne_propfind_set_private(handler, ld_create, &ctx);        ne_xml_push_handler(ne_propfind_get_parser(handler),                         ld_startelm, ld_cdata, end_element_ldisc, handler);        ret = ne_propfind_named(handler, lock_props, discover_results, &ctx);        ne_buffer_destroy(ctx.cdata);    ne_propfind_destroy(handler);    return ret;}static void add_timeout_header(ne_request *req, long timeout){    if (timeout == NE_TIMEOUT_INFINITE) {	ne_add_request_header(req, "Timeout", "Infinite");    }     else if (timeout != NE_TIMEOUT_INVALID && timeout > 0) {	ne_print_request_header(req, "Timeout", "Second-%ld", timeout);    }    /* just ignore it if timeout == 0 or invalid. */}/* Parse a Lock-Token response header. */static void get_ltoken_hdr(void *ud, const char *value){    struct lock_ctx *ctx = ud;        if (value[0] == '<') value++;    ctx->token = ne_strdup(value);    ne_shave(ctx->token, ">");}int ne_lock(ne_session *sess, struct ne_lock *lock) {    ne_request *req = ne_request_create(sess, "LOCK", lock->uri.path);    ne_buffer *body = ne_buffer_create();    ne_xml_parser *parser = ne_xml_create();    int ret, parse_failed;    struct lock_ctx ctx;    memset(&ctx, 0, sizeof ctx);    ctx.cdata = ne_buffer_create();        ne_xml_push_handler(parser, lk_startelm, lk_cdata, lk_endelm, &ctx);        /* Create the body */    ne_buffer_concat(body, "<?xml version=\"1.0\" encoding=\"utf-8\"?>" EOL		    "<lockinfo xmlns='DAV:'>" EOL " <lockscope>",		    lock->scope==ne_lockscope_exclusive?		    "<exclusive/>":"<shared/>",		    "</lockscope>" EOL		    "<locktype><write/></locktype>", NULL);    if (lock->owner) {	ne_buffer_concat(body, "<owner>", lock->owner, "</owner>" EOL, NULL);    }    ne_buffer_zappend(body, "</lockinfo>" EOL);    ne_set_request_body_buffer(req, body->data, ne_buffer_size(body));    ne_add_response_body_reader(req, ne_accept_2xx, 				ne_xml_parse_v, parser);    ne_add_request_header(req, "Content-Type", NE_XML_MEDIA_TYPE);    ne_add_depth_header(req, lock->depth);    add_timeout_header(req, lock->timeout);        ne_add_response_header_handler(req, "Lock-Token", get_ltoken_hdr, &ctx);    /* TODO:      * By 2518, we need this only if we are creating a lock-null resource.     * Since we don't KNOW whether the lock we're given is a lock-null     * or not, we cover our bases.     */    ne_lock_using_parent(req, lock->uri.path);    /* This one is clearer from 2518 sec 8.10.4. */    ne_lock_using_resource(req, lock->uri.path, lock->depth);    ret = ne_request_dispatch(req);    ne_buffer_destroy(body);    ne_buffer_destroy(ctx.cdata);    parse_failed = !ne_xml_valid(parser);        if (ret == NE_OK && ne_get_status(req)->klass == 2) {	if (ctx.token == NULL) {	    ret = NE_ERROR;	    ne_set_error(sess, _("No Lock-Token header given"));	}	else if (parse_failed) {	    ret = NE_ERROR;	    ne_set_error(sess, "%s", ne_xml_get_error(parser));	}	else if (ne_get_status(req)->code == 207) {	    ret = NE_ERROR;	    /* TODO: set the error string appropriately */	}	else if (ctx.found) {	    /* it worked: copy over real lock details if given. */	    NE_FREE(lock->token);	    lock->token = ctx.token;	    ctx.token = NULL;	    if (ctx.active.timeout != NE_TIMEOUT_INVALID)		lock->timeout = ctx.active.timeout;	    lock->scope = ctx.active.scope;	    lock->type = ctx.active.type;	    if (ctx.active.depth >= 0)		lock->depth = ctx.active.depth;	    if (ctx.active.owner) {		NE_FREE(lock->owner);		lock->owner = ctx.active.owner;		ctx.active.owner = NULL;	    }	} else {	    ret = NE_ERROR;	    ne_set_error(sess, _("Response missing activelock for %s"), 			 ctx.token);	}    } else {	ret = NE_ERROR;    }    if (ctx.token)	ne_free(ctx.token);    ne_lock_free(&ctx.active);    ne_request_destroy(req);    ne_xml_destroy(parser);    return ret;}int ne_lock_refresh(ne_session *sess, struct ne_lock *lock){    ne_request *req = ne_request_create(sess, "LOCK", lock->uri.path);    ne_xml_parser *parser = ne_xml_create();    int ret, parse_failed;    /* Handle the response and update *lock appropriately. */    ne_xml_push_handler(parser, lk_startelm, NULL, lk_endelm, lock);        ne_add_response_body_reader(req, ne_accept_2xx, 				ne_xml_parse_v, parser);    /* Probably don't need to submit any other lock-tokens for this     * resource? If it's an exclusive lock, then there can be no other     * locks covering the resource. If it's a shared lock, then this     * lock (which is being refreshed) is sufficient to modify the     * resource state? */    ne_print_request_header(req, "If", "(<%s>)", lock->token);    add_timeout_header(req, lock->timeout);    ret = ne_request_dispatch(req);    parse_failed = !ne_xml_valid(parser);        if (ret == NE_OK && ne_get_status(req)->klass == 2) {	if (parse_failed) {	    ret = NE_ERROR;	    ne_set_error(sess, "%s", ne_xml_get_error(parser));	}	else if (ne_get_status(req)->code == 207) {	    ret = NE_ERROR;	    /* TODO: set the error string appropriately */	}    } else {	ret = NE_ERROR;    }    ne_request_destroy(req);    ne_xml_destroy(parser);    return ret;}

⌨️ 快捷键说明

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