dav/sync.c

changeset 47
fbbbeed4ba8f
parent 46
0542668d0f26
child 48
08d5544c92fb
equal deleted inserted replaced
46:0542668d0f26 47:fbbbeed4ba8f
77 77
78 int ret = EXIT_FAILURE; 78 int ret = EXIT_FAILURE;
79 if(!strcmp(cmd, "pull")) { 79 if(!strcmp(cmd, "pull")) {
80 ret = cmd_pull(args); 80 ret = cmd_pull(args);
81 } else if(!strcmp(cmd, "push")) { 81 } else if(!strcmp(cmd, "push")) {
82 ret = cmd_pull(args); 82 ret = cmd_push(args);
83 } else if(!strcmp(cmd, "sync")) { 83 } else if(!strcmp(cmd, "sync")) {
84 ret = cmd_sync(args); 84 ret = cmd_sync(args);
85 } 85 }
86 86
87 return ret; 87 return ret;
150 } 150 }
151 res = res->next; 151 res = res->next;
152 } 152 }
153 } 153 }
154 154
155 // TODO: cleanup
156
155 // store db 157 // store db
156 158 if(store_db(db, dir->database)) {
159 fprintf(stderr, "Cannot store sync db\n");
160 return -1;
161 }
157 162
158 return 0; 163 return 0;
159 } 164 }
160 165
161 int sync_get_resource(SyncDirectory *dir, DavResource *res, UcxMap *db) { 166 int sync_get_resource(SyncDirectory *dir, DavResource *res, UcxMap *db) {
184 return -1; 189 return -1;
185 } 190 }
186 printf("get %s\n", res->path); 191 printf("get %s\n", res->path);
187 if(dav_get_content(res, out, (dav_write_func)fwrite)) { 192 if(dav_get_content(res, out, (dav_write_func)fwrite)) {
188 ret = -1; 193 ret = -1;
189 } else {
190 if(local) {
191 if(local->etag) {
192 free(local->etag);
193 }
194 local->etag = etag;
195 }
196 } 194 }
197 fclose(out); 195 fclose(out);
196
197 if(ret == 0) {
198 // get file informations for db update
199 struct stat s;
200 if(stat(local_path, &s)) {
201 fprintf(stderr, "stat failed: %s\n", local_path);
202 ret = -1;
203 }
204
205 if(!local) {
206 local = calloc(1, sizeof(LocalResource));
207 local->path = strdup(res->path);
208 ucx_map_cstr_put(db, local->path, local);
209 }
210
211 if(local->etag) {
212 free(local->etag);
213 }
214 local->etag = etag;
215 local->last_modified = s.st_mtim.tv_sec;
216 local->size = s.st_size;
217 }
198 } 218 }
199 219
200 free(local_path); 220 free(local_path);
201 return ret; 221 return ret;
202 } 222 }
203 223
204 int cmd_push(CmdArgs *a) { 224 int cmd_push(CmdArgs *a) {
225 if(a->argc != 1) {
226 fprintf(stderr, "Too %s arguments\n", a->argc < 1 ? "few" : "many");
227 return -1;
228 }
229
230 SyncDirectory *dir = scfg_get_dir(a->argv[0]);
231 if(!dir) {
232 fprintf(stderr, "Unknown sync dir: %s\n", a->argv[0]);
233 return -1;
234 }
235
236 Repository *repo = get_repository(sstr(dir->repository));
237 if(!repo) {
238 fprintf(stderr, "Unkown repository %s\n", dir->name);
239 return -1;
240 }
241
242 UcxMap *db = load_db(dir->database);
243 if(!db) {
244 fprintf(stderr, "Cannot load database file: %s\n", dir->database);
245 return -1;
246 }
247
248 DavSession *sn = dav_session_new_auth(
249 ctx,
250 repo->url,
251 repo->user,
252 repo->password);
253 dav_session_set_flags(sn, get_repository_flags(repo));
254 sn->key = dav_context_get_key(ctx, repo->default_key);
255
256 UcxList *resources = local_scan(dir, db);
257 UCX_FOREACH(elm, resources) {
258 char *path = elm->data;
259 printf("put: %s\n", path);
260 DavResource *res = dav_resource_new(sn, path);
261 sync_put_resource(dir, res, db);
262 dav_resource_free(res);
263 free(path);
264 }
265 ucx_list_free(resources);
266
267 // store db
268 if(store_db(db, dir->database)) {
269 fprintf(stderr, "Cannot store sync db\n");
270 return -1;
271 }
272
205 return 0; 273 return 0;
206 } 274 }
275
276 UcxList* local_scan(SyncDirectory *dir, UcxMap *db) {
277 UcxList *resources = NULL;
278
279 char *path = strdup("/");
280 UcxList *stack = ucx_list_prepend(NULL, path);
281 while(stack) {
282 // get a directory path from the stack and read all entries
283 // if an entry is a directory, put it on the stack
284 // otherwise compare the metadata with the db content
285
286 char *p = stack->data;
287 stack = ucx_list_remove(stack, stack);
288 char *local_path = util_concat_path(dir->path, p);
289 DIR *local_dir = opendir(local_path);
290
291 if(!local_dir) {
292 fprintf(stderr, "Cannot open directory %s\n", local_path);
293 } else {
294 long namemax = namemax = pathconf(path, _PC_NAME_MAX);
295 if(namemax == 0) {
296 namemax = 255;
297 }
298 struct dirent *ent = malloc(sizeof(struct dirent) + namemax + 1);
299 struct dirent *res = NULL;
300 while(!readdir_r(local_dir, ent, &res) && res) {
301 if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
302 continue;
303 }
304
305 char *new_path = util_concat_path(p, ent->d_name);
306 char *file_path = util_concat_path(dir->path, new_path);
307 struct stat s;
308 if(stat(file_path, &s)) {
309 fprintf(stderr, "Cannot stat file %s\n", file_path);
310 free(new_path);
311 free(file_path);
312 continue;
313 }
314 free(file_path);
315
316 if(S_ISDIR(s.st_mode)) {
317 stack = ucx_list_prepend(stack, new_path);
318 } else {
319 LocalResource *res = ucx_map_cstr_get(db, new_path);
320 if(res) {
321 // the file is already in the database
322 // compare length and lastmodified date
323
324 if(res->last_modified == s.st_mtim.tv_sec
325 && res->size == s.st_size)
326 {
327 // skip this file
328 free(new_path);
329 } else {
330 // add file to list
331 resources = ucx_list_append(
332 resources,
333 new_path);
334
335 // update db entries
336 res->size = s.st_size;
337 res->last_modified = s.st_mtim.tv_sec;
338 }
339 } else {
340 // add file to list
341 LocalResource *res = calloc(1, sizeof(LocalResource));
342 res->path = strdup(new_path);
343 res->etag = NULL;
344 res->last_modified = s.st_mtim.tv_sec;
345 res->size = s.st_size;
346 ucx_map_cstr_put(db, res->path, res);
347 resources = ucx_list_append(resources, new_path);
348 }
349 }
350 }
351 closedir(local_dir);
352 free(ent);
353 }
354 free(local_path);
355 free(p);
356 }
357
358 return resources;
359 }
360
361 int sync_put_resource(SyncDirectory *dir, DavResource *res, UcxMap *db) {
362 char *local_path = util_concat_path(dir->path, res->path);
363 FILE *in = fopen(local_path, "r");
364 if(!in) {
365 fprintf(stderr, "Cannot open file %s\n", local_path);
366 free(local_path);
367 return -1;
368 }
369 free(local_path);
370
371 dav_set_content(res, in, (dav_read_func)fread);
372
373 int ret = -1;
374 for(;;) {
375 if(dav_create(res)) {
376 break;
377 }
378 if(dav_store(res)) {
379 break;
380 }
381 if(dav_load(res)) {
382 break;
383 }
384 ret = 0;
385 break;
386 }
387
388 if(ret == 0) {
389 LocalResource *local_res = ucx_map_cstr_get(db, res->path);
390 if(local_res->etag) {
391 free(local_res->etag);
392 }
393 char *etag = dav_get_property(res, "D:getetag");
394 if(etag) {
395 local_res->etag = strdup(dav_get_property(res, "D:getetag"));
396 } else {
397 local_res->etag = NULL;
398 }
399 }
400
401 fclose(in);
402
403 return 0;
404 }
405
406
207 407
208 int cmd_sync(CmdArgs *a) { 408 int cmd_sync(CmdArgs *a) {
209 return 0; 409 return 0;
210 } 410 }
211 411

mercurial