Back to index

avfs  1.0.1
Classes | Defines | Typedefs | Enumerations | Functions
dav_locks.h File Reference
#include "http_request.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  dav_lock

Defines

#define DAV_TIMEOUT_INFINITE   -1
#define DAV_TIMEOUT_INVALID   -2

Typedefs

typedef struct dav_lock_session_s
typedef void(* dav_lock_walkfunc )(struct dav_lock *lock, void *userdata)
typedef void(* dav_lock_result )(void *userdata, const struct dav_lock *lock, const char *uri, const http_status *status)

Enumerations

enum  dav_lock_scope { dav_lockscope_exclusive, dav_lockscope_shared }
enum  dav_lock_type { dav_locktype_write }

Functions

dav_lock_session * dav_lock_register (http_session *sess)
void dav_lock_unregister (dav_lock_session *sess)
void dav_lock_add (dav_lock_session *sess, struct dav_lock *lock)
void dav_lock_remove (dav_lock_session *sess, struct dav_lock *lock)
int dav_lock_iterate (dav_lock_session *sess, dav_lock_walkfunc func, void *userdata)
int dav_lock (http_session *sess, struct dav_lock *lock)
int dav_unlock (http_session *sess, struct dav_lock *lock)
struct dav_lockdav_lock_find (dav_lock_session *sess, const char *uri)
struct dav_lockdav_lock_copy (const struct dav_lock *lock)
void dav_lock_free (struct dav_lock *lock)
int dav_lock_discover (http_session *sess, const char *uri, dav_lock_result result, void *userdata)
void dav_lock_using_resource (http_req *req, const char *uri, int depth)
void dav_lock_using_parent (http_req *req, const char *uri)

Class Documentation

struct dav_lock

Definition at line 40 of file dav_locks.h.

Class Members
int depth
char * uri

Define Documentation

#define DAV_TIMEOUT_INFINITE   -1

Definition at line 52 of file dav_locks.h.

#define DAV_TIMEOUT_INVALID   -2

Definition at line 53 of file dav_locks.h.


Typedef Documentation

typedef void(* dav_lock_result)(void *userdata, const struct dav_lock *lock, const char *uri, const http_status *status)

Definition at line 110 of file dav_locks.h.

typedef struct dav_lock_session_s

Definition at line 55 of file dav_locks.h.

typedef void(* dav_lock_walkfunc)(struct dav_lock *lock, void *userdata)

Definition at line 84 of file dav_locks.h.


Enumeration Type Documentation

Enumerator:
dav_lockscope_exclusive 
dav_lockscope_shared 

Definition at line 28 of file dav_locks.h.

Enumerator:
dav_locktype_write 

Definition at line 33 of file dav_locks.h.


Function Documentation

int dav_lock ( http_session *  sess,
struct dav_lock lock 
)

Definition at line 545 of file dav_locks.c.

{
    http_req *req = http_request_create(sess, "LOCK", lock->uri);
    sbuffer body = sbuffer_create();
    hip_xml_parser *parser = hip_xml_create();
    int ret, parse_failed;

    hip_xml_push_handler(parser, lock_elms, check_context, 
                      NULL, end_element_lock, lock);
    
    /* Create the body */
    sbuffer_concat(body, "<?xml version=\"1.0\" encoding=\"utf-8\"?>" EOL
                  "<lockinfo xmlns='DAV:'>" EOL " <lockscope>",
                  lock->scope==dav_lockscope_exclusive?
                  "<exclusive/>":"<shared/>",
                  "</lockscope>" EOL
                  "<locktype><write/></locktype>", NULL);

    if (lock->owner) {
       sbuffer_concat(body, "<owner>", lock->owner, "</owner>" EOL, NULL);
    }
    sbuffer_zappend(body, "</lockinfo>" EOL);

    http_set_request_body_buffer(req, sbuffer_data(body));
    http_add_response_body_reader(req, http_accept_2xx, 
                              hip_xml_parse_v, parser);
    http_add_request_header(req, "Content-Type", "text/xml");
    dav_add_depth_header(req, lock->depth);

    /* 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.
     */
    dav_lock_using_parent(req, lock->uri);
    /* This one is clearer from 2518 sec 8.10.4. */
    dav_lock_using_resource(req, lock->uri, lock->depth);

    ret = http_request_dispatch(req);

    sbuffer_destroy(body);
    parse_failed = !hip_xml_valid(parser);
    
    if (ret == HTTP_OK && http_get_status(req)->klass == 2) {
       if (parse_failed) {
           ret = HTTP_ERROR;
           http_set_error(sess, hip_xml_get_error(parser));
       }
       else if (http_get_status(req)->code == 207) {
           ret = HTTP_ERROR;
           /* TODO: set the error string appropriately */
       }
    } else {
       ret = HTTP_ERROR;
    }

    http_request_destroy(req);
    hip_xml_destroy(parser);

    /* TODO: free the list */
    return ret;
}

Here is the call graph for this function:

void dav_lock_add ( dav_lock_session *  sess,
struct dav_lock lock 
)

Definition at line 295 of file dav_locks.c.

{
    if (sess->locks != NULL) {
       sess->locks->prev = lock;
    }
    lock->prev = NULL;
    lock->next = sess->locks;
    sess->locks = lock;
}
struct dav_lock* dav_lock_copy ( const struct dav_lock lock) [read]

Definition at line 317 of file dav_locks.c.

{
    struct dav_lock *ret = ne_calloc(sizeof *ret);

    ret->uri = ne_strdup(lock->uri);
    ret->depth = lock->depth;
    ret->type = lock->type;
    ret->scope = lock->scope;
    ret->token = ne_strdup(lock->token);
    ret->owner = ne_strdup(lock->owner);
    ret->timeout = lock->timeout;

    return ret;
}
int dav_lock_discover ( http_session *  sess,
const char *  uri,
dav_lock_result  result,
void *  userdata 
)

Definition at line 521 of file dav_locks.c.

{
    dav_propfind_handler *handler;
    struct discover_ctx ctx = {0};
    int ret;
    
    ctx.results = callback;
    ctx.userdata = userdata;

    handler = dav_propfind_create(sess, uri, DAV_DEPTH_ZERO);

    dav_propfind_set_complex(handler, lock_props, create_private, NULL);
    
    hip_xml_push_handler(dav_propfind_get_parser(handler), lock_elms, 
                      check_context, NULL, end_element_ldisc, handler);
    
    ret = dav_propfind_named(handler, discover_results, &ctx);
    
    dav_propfind_destroy(handler);

    return ret;
}

Here is the call graph for this function:

struct dav_lock* dav_lock_find ( dav_lock_session *  sess,
const char *  uri 
) [read]

Definition at line 203 of file dav_locks.c.

{
    struct dav_lock *cur;
    for (cur = sess->locks; cur != NULL; cur = cur->next) {
       if (uri_compare(uri, cur->uri) == 0) 
           return cur;
    }
    return NULL;
}
void dav_lock_free ( struct dav_lock lock)

Definition at line 332 of file dav_locks.c.

{
    HTTP_FREE(lock->uri);
    HTTP_FREE(lock->owner);
    HTTP_FREE(lock->token);
    free(lock);
}
int dav_lock_iterate ( dav_lock_session *  sess,
dav_lock_walkfunc  func,
void *  userdata 
)

Definition at line 237 of file dav_locks.c.

{
    struct dav_lock *lock;
    int count = 0;

    for (lock = sess->locks; lock != NULL; lock = lock->next) {
       if (func != NULL) {
           (*func)(lock, userdata);
       }
       count++;
    }
    
    return count;
}
dav_lock_session* dav_lock_register ( http_session *  sess)

Definition at line 168 of file dav_locks.c.

{
    dav_lock_session *locksess = ne_calloc(sizeof *locksess);

    /* Register the hooks */
    http_add_hooks(sess, &lock_hooks, locksess);
    
    return locksess;
}
void dav_lock_remove ( dav_lock_session *  sess,
struct dav_lock lock 
)

Definition at line 305 of file dav_locks.c.

{
    if (lock->prev != NULL) {
       lock->prev->next = lock->next;
    } else {
       sess->locks = lock->next;
    }
    if (lock->next != NULL) {
       lock->next->prev = lock->prev;
    }
}
void dav_lock_unregister ( dav_lock_session *  sess)

Definition at line 178 of file dav_locks.c.

{
    /* FIXME: free the lock list */
    free(sess);
}
void dav_lock_using_parent ( http_req *  req,
const char *  uri 
)

Definition at line 213 of file dav_locks.c.

{
    struct request_locks *rl = http_get_hook_private(req, HOOK_ID);
    char *parent;

    if (rl == NULL)
       return;       

    parent = uri_parent(uri);

    if (parent != NULL) {
       struct dav_lock *lock;
       /* Find any locks on the parent resource.
        * FIXME: should check for depth-infinity locks too. */
       lock = dav_lock_find(rl->session, parent);
       if (lock) {
           DEBUG(DEBUG_LOCKS, "Locked parent, %s on %s\n", lock->token, 
                lock->uri);
           submit_lock(rl, lock, uri);
       }
       free(parent);
    }
}

Here is the call graph for this function:

void dav_lock_using_resource ( http_req *  req,
const char *  uri,
int  depth 
)

Definition at line 253 of file dav_locks.c.

{
    /* Grab the private cookie for this request */
    struct request_locks *rl = http_get_hook_private(req, HOOK_ID);
    struct dav_lock *lock; /* all the known locks */
    int match;

    if (rl == NULL)
       return;       

    /* Iterate over the list of session locks to see if any of
     * them apply to this resource */
    for (lock = rl->session->locks; lock != NULL; lock = lock->next) {
       
       match = 0;
       
       if (depth == DAV_DEPTH_INFINITE && uri_childof(uri, lock->uri)) {
           /* Case 1: this is a depth-infinity request which will 
            * modify a lock somewhere inside the collection. */
           DEBUG(DEBUG_LOCKS, "Has child: %s\n", lock->token);
           match = 1;
       } 
       else if (uri_compare(uri, lock->uri) == 0) {
           /* Case 2: this request is directly on a locked resource */
           DEBUG(DEBUG_LOCKS, "Has direct lock: %s\n", lock->token);
           match = 1;
       }
       else if (lock->depth == DAV_DEPTH_INFINITE && 
               uri_childof(lock->uri, uri)) {
           /* Case 3: there is a higher-up infinite-depth lock which
            * covers the resource that this request will modify. */
           DEBUG(DEBUG_LOCKS, "Is child of: %s\n", lock->token);
           match = 1;
       }
       
       if (match) {
           submit_lock(rl, lock, uri);
       }
    }

}

Here is the call graph for this function:

int dav_unlock ( http_session *  sess,
struct dav_lock lock 
)

Definition at line 340 of file dav_locks.c.

{
    http_req *req = http_request_create(sess, "UNLOCK", lock->uri);
    int ret;
    
    http_print_request_header(req, "Lock-Token", "<%s>", lock->token);
    
    /* TODO: need this or not?
     * it definitely goes away when lock-null resources go away */
    dav_lock_using_parent(req, lock->uri);

    ret = http_request_dispatch(req);
    
    if (ret == HTTP_OK && http_get_status(req)->klass == 2) {
       ret = HTTP_OK;    
    } else {
       ret = HTTP_ERROR;
    }

    http_request_destroy(req);
    
    return ret;
}