# HG changeset patch # User Olaf Wintermann # Date 1458327276 -3600 # Node ID 7b73058d782e8c4959cb69d3808ca637254e6b7c # Parent e22c29b7ee2f40d37a9158ee2d9e091ad5e6a8e3 fixed some memory leaks in dav-sync pull diff -r e22c29b7ee2f -r 7b73058d782e dav/config.c --- a/dav/config.c Fri Mar 18 15:08:30 2016 +0100 +++ b/dav/config.c Fri Mar 18 19:54:36 2016 +0100 @@ -147,6 +147,9 @@ if(repo->user) { free(repo->user); } + if(repo->cert) { + free(repo->cert); + } free(repo); } ucx_map_free(repos); diff -r e22c29b7ee2f -r 7b73058d782e dav/db.c --- a/dav/db.c Fri Mar 18 15:08:30 2016 +0100 +++ b/dav/db.c Fri Mar 18 19:54:36 2016 +0100 @@ -325,3 +325,27 @@ xmlFreeTextWriter(writer); return 0; } + +void destroy_db(SyncDatabase *db) { + ucx_map_free_content(db->resources, (ucx_destructor)local_resource_free); + ucx_map_free_content(db->conflict, (ucx_destructor)local_resource_free); + ucx_map_free(db->resources); + ucx_map_free(db->conflict); + free(db); +} + +void local_resource_free(LocalResource *res) { + if(!res) { + return; + } + if(res->name) { + free(res->name); + } + if(res->path) { + free(res->path); + } + if(res->etag) { + free(res->etag); + } + free(res); +} diff -r e22c29b7ee2f -r 7b73058d782e dav/db.h --- a/dav/db.h Fri Mar 18 15:08:30 2016 +0100 +++ b/dav/db.h Fri Mar 18 19:54:36 2016 +0100 @@ -53,12 +53,14 @@ struct SyncDatabase { UcxMap *resources; - //UcxMap *remove; UcxMap *conflict; }; SyncDatabase* load_db(char *name); int store_db(SyncDatabase *db, char *name); +void destroy_db(SyncDatabase *db); + +void local_resource_free(LocalResource *res); LocalResource* process_resource(xmlTextReaderPtr reader); LocalResource* process_conflict(xmlTextReaderPtr reader); diff -r e22c29b7ee2f -r 7b73058d782e dav/scfg.c --- a/dav/scfg.c Fri Mar 18 15:08:30 2016 +0100 +++ b/dav/scfg.c Fri Mar 18 19:54:36 2016 +0100 @@ -79,12 +79,14 @@ perror("Cannot load sync.xml"); } } + free(file); return 0; } xmlDoc *doc = xmlReadFile(file, NULL, 0); if(!doc) { fprintf(stderr, "Broken configuration file\n"); + free(file); return -1; } @@ -104,7 +106,7 @@ } xmlFreeDoc(doc); - + free(file); return ret; } diff -r e22c29b7ee2f -r 7b73058d782e dav/sopt.c --- a/dav/sopt.c Fri Mar 18 15:08:30 2016 +0100 +++ b/dav/sopt.c Fri Mar 18 19:54:36 2016 +0100 @@ -30,7 +30,7 @@ #include #include -#include "optparser.h" +#include "sopt.h" void cmd_args_free(CmdArgs *args) { if(args) { diff -r e22c29b7ee2f -r 7b73058d782e dav/sopt.h --- a/dav/sopt.h Fri Mar 18 15:08:30 2016 +0100 +++ b/dav/sopt.h Fri Mar 18 19:54:36 2016 +0100 @@ -41,6 +41,7 @@ int argc; } CmdArgs; +void cmd_args_free(CmdArgs *args); CmdArgs* cmd_parse_args(int argc, char **argv); char* cmd_getoption(CmdArgs *arg, char *name); diff -r e22c29b7ee2f -r 7b73058d782e dav/sync.c --- a/dav/sync.c Fri Mar 18 15:08:30 2016 +0100 +++ b/dav/sync.c Fri Mar 18 19:54:36 2016 +0100 @@ -90,6 +90,8 @@ memcpy(ctx->https_proxy, get_https_proxy(), sizeof(Proxy)); if(load_sync_config()) { + cmd_args_free(args); + dav_context_destroy(ctx); return EXIT_FAILURE; } } @@ -113,6 +115,10 @@ } // TODO: cleanup sync config (don't forget to call regfree for regex) + cmd_args_free(args); + dav_context_destroy(ctx); + + free_config(); return ret; } @@ -208,6 +214,7 @@ SyncDatabase *db = load_db(dir->database); if(!db) { fprintf(stderr, "Cannot load database file: %s\n", dir->database); + destroy_db(db); return -1; } remove_deleted_conflicts(dir, db); @@ -217,6 +224,7 @@ new_url = util_concat_path(repo->url, dir->collection); } DavSession *sn = create_session(ctx, repo, new_url ? new_url : repo->url); + ucx_mempool_reg_destr(sn->mp, db, (ucx_destructor)destroy_db); if(new_url) { free(new_url); } @@ -400,6 +408,7 @@ } if(!strcmp(e.ptr, local->etag)) { // resource is already up-to-date on the client + free(local_path); return 0; } } @@ -491,7 +500,7 @@ free(local->etag); } // set metadata from stat - local->etag = etag; + local->etag = strdup(etag); local->last_modified = s.st_mtime; local->size = s.st_size; } else { @@ -695,6 +704,7 @@ new_url = util_concat_path(repo->url, dir->collection); } DavSession *sn = create_session(ctx, repo, new_url ? new_url : repo->url); + ucx_mempool_reg_destr(sn->mp, db, (ucx_destructor)destroy_db); if(new_url) { free(new_url); } @@ -743,6 +753,7 @@ if(res_isconflict(db, local_res)) { printf("skip: %s\n", local_res->path); sync_skipped++; + local_resource_free(local_res); continue; } @@ -766,6 +777,7 @@ if(cdt && remote_resource_is_changed(sn, dir, db, local_res)) { printf("conflict: %s\n", local_res->path); sync_skipped++; + local_resource_free(local_res); continue; } @@ -783,7 +795,10 @@ // remove every locally available resource from db->resource // the remaining elements are all deleted files ucx_map_cstr_put(lclres, local_res->path, local_res); - ucx_map_cstr_remove(db->resources, local_res->path); // TODO: element leaked + LocalResource *lr = ucx_map_cstr_remove(db->resources, local_res->path); + if(lr) { + local_resource_free(lr); + } } } ucx_list_free(resources); @@ -824,6 +839,7 @@ // cleanup dav_session_destroy(sn); + ucx_list_free(resources); // content is already freed // Report if(ret == 0) { @@ -1194,6 +1210,8 @@ for(int i=0;iconflict, dc[i]); } + + free(dc); } int cmd_resolve_conflicts(CmdArgs *a) { @@ -1214,6 +1232,8 @@ return -1; } + int ret = 0; + // remove conflicts int num_conflict = db->conflict->count; //TODO: ucx_map_free_content(db->conflict, destr); @@ -1223,14 +1243,17 @@ if(store_db(db, dir->database)) { fprintf(stderr, "Cannot store sync db\n"); fprintf(stderr, "Abort\n"); - return -1; // TODO: don't return here + ret = -1; } + destroy_db(db); // Report - char *str_conflict = num_conflict == 1 ? "conflict" : "conflicts"; - printf("Result: %d %s resolved\n", num_conflict, str_conflict); + if(ret == 0) { + char *str_conflict = num_conflict == 1 ? "conflict" : "conflicts"; + printf("Result: %d %s resolved\n", num_conflict, str_conflict); + } - return 0; + return ret; } int cmd_delete_conflicts(CmdArgs *a) { @@ -1254,6 +1277,8 @@ int num_del = 0; int num_err = 0; + int ret = 0; + // delete all conflict files UcxMapIterator i = ucx_map_iterator(db->conflict); LocalResource *res; @@ -1277,17 +1302,20 @@ if(store_db(db, dir->database)) { fprintf(stderr, "Cannot store sync db\n"); fprintf(stderr, "Abort\n"); - return -1; // TODO: don't return here + ret = -1; } + destroy_db(db); // Report - char *str_delete = num_del == 1 ? "file" : "files"; - char *str_error = num_err == 1 ? "error" : "errors"; - printf("Result: %d conflict %s deleted, %d %s\n", - num_del, str_delete, - num_err, str_error); + if(ret == 0) { + char *str_delete = num_del == 1 ? "file" : "files"; + char *str_error = num_err == 1 ? "error" : "errors"; + printf("Result: %d conflict %s deleted, %d %s\n", + num_del, str_delete, + num_err, str_error); + } - return 0; + return ret; } diff -r e22c29b7ee2f -r 7b73058d782e libidav/resource.c --- a/libidav/resource.c Fri Mar 18 15:08:30 2016 +0100 +++ b/libidav/resource.c Fri Mar 18 19:54:36 2016 +0100 @@ -953,14 +953,18 @@ //printf("%.*s\n\n", request->size, request->space); //printf("%.*s\n\n", response->size, response->space); + ucx_buffer_free(request); + long status = 0; curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status); if(ret == CURLE_OK && (status >= 200 && status < 300)) { LockDiscovery lock; if(parse_lock_response(sn, response, &lock)) { sn->error = DAV_ERROR; + ucx_buffer_free(response); return -1; } + ucx_buffer_free(response); DavLock *l = dav_create_lock(sn, lock.locktoken, lock.timeout); free(lock.locktoken); @@ -983,6 +987,7 @@ } } else { dav_session_set_error(sn, ret, status); + ucx_buffer_free(response); return -1; } } diff -r e22c29b7ee2f -r 7b73058d782e libidav/session.c --- a/libidav/session.c Fri Mar 18 15:08:30 2016 +0100 +++ b/libidav/session.c Fri Mar 18 19:54:36 2016 +0100 @@ -57,7 +57,7 @@ sstr_t url = sstrdup_a(sn->mp->allocator, sstr(base_url)); sn->base_url = url.ptr; } else { - char *url_str = malloc(url.length + 2); + char *url_str = ucx_mempool_malloc(sn->mp, url.length + 2); memcpy(url_str, base_url, url.length); url_str[url.length] = '/'; url_str[url.length + 1] = '\0';