src/server/webdav/xattrbackend.c

changeset 482
b02da778362e
parent 481
31affbf33911
child 483
f69d88f86b9c
equal deleted inserted replaced
481:31affbf33911 482:b02da778362e
135 WebdavResource *resource, 135 WebdavResource *resource,
136 struct stat *s) 136 struct stat *s)
137 { 137 {
138 Session *sn = request->sn; 138 Session *sn = request->sn;
139 Request *rq = request->rq; 139 Request *rq = request->rq;
140 CxAllocator *a = pool_allocator(sn->pool);
140 141
141 WebdavXAttrBackend *xdav = request->dav->instance; 142 WebdavXAttrBackend *xdav = request->dav->instance;
142 WebdavXAttrRepository *repo = xdav->repo; 143 WebdavXAttrRepository *repo = xdav->repo;
143 XAttrPropfind *xprop = request->userdata; 144 XAttrPropfind *xprop = request->userdata;
144 145
146 // get resource path
145 const char *path; 147 const char *path;
146 char *path_dp = NULL; 148 char *path_dp = NULL;
147 if(!parent) { 149 if(!parent) {
148 // use base path 150 // use base path
149 path = xprop->base_path; 151 path = xprop->base_path;
173 (libxattr_free_func)pool_free, 175 (libxattr_free_func)pool_free,
174 path, 176 path,
175 repo->xattr_name, 177 repo->xattr_name,
176 &xattr_data_len); 178 &xattr_data_len);
177 179
178 if(xattr_data) { 180 if(!xattr_data) {
179 181 // no properties for this resource
180 } 182 return 0;
181 183 }
182 184
183 return 0; 185 CxMap *pmap = webdav_xattr_parse_data(a, xattr_data, xattr_data_len, path);
186 pool_free(sn->pool, xattr_data);
187 if(!pmap) {
188 return 1;
189 }
190
191 int err;
192 if(request->allprop || request->propname) {
193 err = webdav_xattr_propfind_allprop(request, resource, a, pmap);
194 } else {
195 err = webdav_xattr_propfind_get_requested_properties(request, resource, a, pmap);
196 }
197
198 return err;
184 } 199 }
185 200
186 int webdav_xattr_propfind_finish(WebdavPropfindRequest *rq) { 201 int webdav_xattr_propfind_finish(WebdavPropfindRequest *rq) {
187 return 0; 202 return 0;
188 } 203 }
204
205 // helper functions for propfind_do
206
207 int webdav_xattr_propfind_get_requested_properties(
208 WebdavPropfindRequest *request,
209 WebdavResource *resource,
210 CxAllocator *a,
211 CxMap *pmap)
212 {
213 WebdavPListIterator i = webdav_plist_iterator(&request->properties);
214 WebdavPList *cur;
215 while(webdav_plist_iterator_next(&i, &cur)) {
216 WebdavProperty *reqprop = cur->property;
217
218 CxHashKey key = webdav_property_key_a(
219 a,
220 (const char*)reqprop->namespace->href,
221 (const char*)reqprop->name);
222 if(!key.data.str) {
223 return 1;
224 }
225
226 WebdavProperty *prop = cxMapGet(pmap, key);
227 if(prop) {
228 if(resource->addproperty(resource, prop, 200)) {
229 return 1;
230 }
231 }
232 }
233
234 return 0;
235 }
236
237 int webdav_xattr_propfind_allprop(
238 WebdavPropfindRequest *request,
239 WebdavResource *resource,
240 CxAllocator *a,
241 CxMap *pmap)
242 {
243 CxIterator i = cxMapIteratorValues(pmap);
244 cx_foreach(WebdavProperty*, prop, i) {
245 if(request->propname) {
246 prop->vtype = WS_VALUE_NO_TYPE;
247 }
248 if(resource->addproperty(resource, prop, 200)) {
249 return 1;
250 }
251 }
252 return 0;
253 }
254
255
189 256
190 int webdav_xattr_proppatch_do( 257 int webdav_xattr_proppatch_do(
191 WebdavProppatchRequest *request, 258 WebdavProppatchRequest *request,
192 WebdavResource *response, 259 WebdavResource *response,
193 VFSFile *file, 260 VFSFile *file,
198 Request *rq = request->rq; 265 Request *rq = request->rq;
199 CxAllocator *a = pool_allocator(sn->pool); 266 CxAllocator *a = pool_allocator(sn->pool);
200 267
201 WebdavXAttrBackend *xdav = request->dav->instance; 268 WebdavXAttrBackend *xdav = request->dav->instance;
202 WebdavXAttrRepository *repo = xdav->repo; 269 WebdavXAttrRepository *repo = xdav->repo;
270
271 char *path = pblock_findkeyval(pb_key_path, rq->vars);
272
273 // How xattr proppatch works:
274 // 1. get existing property data from the file's xattr
275 // 2. do set/remove operations to the existing data
276 // 3. write new property data to the xattr (webdav_xattr_proppatch_finish)
277
278 // TODO: proppatch file lock (in-process userspace lock)
203 279
204 XAttrProppatch *xprop = pool_malloc(sn->pool, sizeof(XAttrProppatch)); 280 XAttrProppatch *xprop = pool_malloc(sn->pool, sizeof(XAttrProppatch));
205 if(!xprop) { 281 if(!xprop) {
206 return 1; 282 return 1;
207 } 283 }
208 request->userdata = xprop; 284 request->userdata = xprop;
209
210 char *path = pblock_findkeyval(pb_key_path, rq->vars);
211 285
212 // get existing property data 286 // get existing property data
213 ssize_t xattr_data_len = 0; 287 ssize_t xattr_data_len = 0;
214 char *xattr_data = xattr_get_alloc( 288 char *xattr_data = xattr_get_alloc(
215 sn->pool, 289 sn->pool,
220 &xattr_data_len); 294 &xattr_data_len);
221 295
222 CxMap *pmap; 296 CxMap *pmap;
223 if(xattr_data) { 297 if(xattr_data) {
224 pmap = webdav_xattr_parse_data(a, xattr_data, xattr_data_len, path); 298 pmap = webdav_xattr_parse_data(a, xattr_data, xattr_data_len, path);
299 pool_free(sn->pool, xattr_data);
225 } else { 300 } else {
226 // empty map 301 // empty map
227 pmap = cxHashMapCreate(a, request->setcount + 8); 302 pmap = cxHashMapCreate(a, request->setcount + 8);
228 } 303 }
229 if(!pmap) { 304 if(!pmap) {
230 return 1; 305 return 1;
231 } 306 }
307 xprop->properties = pmap;
232 308
233 // remove properties 309 // remove properties
234 WebdavPListIterator i = webdav_plist_iterator(removeInOut); 310 WebdavPListIterator i = webdav_plist_iterator(removeInOut);
235 WebdavPList *cur; 311 WebdavPList *cur;
236 while(webdav_plist_iterator_next(&i, &cur)) { 312 while(webdav_plist_iterator_next(&i, &cur)) {
274 } 350 }
275 351
276 webdav_plist_iterator_remove_current(&i); 352 webdav_plist_iterator_remove_current(&i);
277 } 353 }
278 354
279 //printf("\n\n%.*s\n\n", (int)buf.size, buf.space); 355 return 0;
280 //fflush(stdout);
281
282 int ret = 0;
283 cxmutstr new_data = webdav_xattr_serialze_map(a, pmap);
284 if(new_data.ptr) {
285 xattr_set(path, repo->xattr_name, new_data.ptr, new_data.length);
286 } else {
287 cxMapDestroy(pmap);
288 ret = 1;
289 }
290
291 return ret;
292 } 356 }
293 357
294 int webdav_xattr_proppatch_finish( 358 int webdav_xattr_proppatch_finish(
295 WebdavProppatchRequest *request, 359 WebdavProppatchRequest *request,
296 WebdavResource *response, 360 WebdavResource *response,
297 VFSFile *file, 361 VFSFile *file,
298 WSBool commit) 362 WSBool commit)
299 { 363 {
364 Session *sn = request->sn;
365 Request *rq = request->rq;
366 CxAllocator *a = pool_allocator(sn->pool);
367
368 WebdavXAttrBackend *xdav = request->dav->instance;
369 WebdavXAttrRepository *repo = xdav->repo;
370
371 XAttrProppatch *xprop = request->userdata;
372
373 char *path = pblock_findkeyval(pb_key_path, rq->vars);
374
375 int ret = 0;
376 if(commit) {
377 cxmutstr new_data = webdav_xattr_serialze_map(a, xprop->properties);
378 if(new_data.ptr) {
379 if(xattr_set(path, repo->xattr_name, new_data.ptr, new_data.length)) {
380 ret = 1;
381 }
382 } else {
383 ret = 1;
384 }
385 }
386
300 return 0; 387 return 0;
301 } 388 }
302 389
303 390
304 /* ----------------------- properties xattr data ----------------------- */ 391 /* ----------------------- properties xattr data ----------------------- */

mercurial