#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "versioning.h"
#include "methods.h"
#include "utils.h"
#include "session.h"
static int basic_deltav_op(DavResource *res,
char *method) {
DavSession *sn = res->session;
CURL *handle = sn->handle;
util_set_url(sn, dav_resource_get_href(res));
DavLock *lock = dav_get_lock(res->session, res->path);
char *locktoken = lock ? lock->token :
NULL;
CURLcode ret = do_simple_request(sn, method, locktoken);
long status =
0;
curl_easy_getinfo (handle,
CURLINFO_RESPONSE_CODE, &status);
if(!(ret ==
CURLE_OK && (status >=
200 && status <
300))) {
dav_session_set_error(sn, ret, status);
return 1;
}
return 0;
}
int dav_versioncontrol(DavResource *res) {
return basic_deltav_op(res,
"VERSION-CONTROL");
}
int dav_checkout(DavResource *res) {
return basic_deltav_op(res,
"CHECKOUT");
}
int dav_checkin(DavResource *res) {
return basic_deltav_op(res,
"CHECKIN");
}
int dav_uncheckout(DavResource *res) {
return basic_deltav_op(res,
"UNCHECKOUT");
}
DavResource* dav_versiontree(DavResource *res,
char *properties) {
DavSession *sn = res->session;
util_set_url(sn, dav_resource_get_href(res));
CxList *proplist =
NULL;
if(properties) {
proplist = parse_properties_string(sn->context, cx_str(properties));
int add_vname =
1;
CxIterator i = cxListIterator(proplist);
cx_foreach(DavProperty *, p, i) {
if(!strcmp(p->ns->name,
"DAV:") && !strcmp(p->name,
"version-name")) {
add_vname =
0;
break;
}
}
if(add_vname) {
DavProperty p;
p.ns = dav_get_namespace(sn->context,
"D");
p.name = strdup(
"version-name");
p.value =
NULL;
cxListInsert(proplist,
0, &p);
}
}
CxBuffer *rqbuf = create_propfind_request(sn, proplist,
"version-tree",
1);
CxBuffer *rpbuf = cxBufferCreate(
NULL,
4096, cxDefaultAllocator,
CX_BUFFER_FREE_CONTENTS|
CX_BUFFER_AUTO_EXTEND);
CURLcode ret = do_report_request(sn, rqbuf, rpbuf);
long status =
0;
curl_easy_getinfo (sn->handle,
CURLINFO_RESPONSE_CODE, &status);
int error =
0;
DavResource *versions =
NULL;
if(ret ==
CURLE_OK && status ==
207) {
sn->error =
DAV_OK;
PropfindParser *parser = create_propfind_parser(rpbuf,
NULL);
if(parser) {
DavResource *list_end =
NULL;
ResponseTag response;
int r;
int snflags = sn->flags;
sn->flags =
0;
while((r = get_propfind_response(parser, &response)) !=
0) {
if(r == -
1) {
res->session->error =
DAV_ERROR;
error =
1;
break;
}
DavResource *v = response2resource(sn, &response,
NULL);
if(!versions) {
versions = v;
}
else {
list_end->next = v;
}
list_end = v;
cleanup_response(&response);
}
sn->flags = snflags;
destroy_propfind_parser(parser);
}
else {
sn->error =
DAV_ERROR;
error =
1;
}
}
else {
dav_session_set_error(sn, ret, status);
error =
1;
}
if(proplist) {
CxIterator i = cxListIterator(proplist);
cx_foreach(DavProperty*, p, i) {
free(p->name);
}
cxListDestroy(proplist);
}
if(error && versions) {
DavResource *cur = versions;
while(cur) {
DavResource *next = cur->next;
dav_resource_free(cur);
cur = next;
}
versions =
NULL;
}
return versions;
}