void swupd_deinit(void) { terminate_signature(); swupd_curl_deinit(); free_globals(); v_lockfile(); dump_file_descriptor_leaks(); }
static int bundle_rm() { char *filename = NULL; int ret = 0; struct stat statb; if (!init_globals()) { free_globals(); return -1; } init_log_stdout(); verbose = 1; if (asprintf(&filename, "%s/%s", BUNDLES_DIR, bundle) <= 0) { log_stdout("ERROR: allocating memory, exiting now\n\n"); abort(); } if (stat(filename, &statb) == -1) { log_stdout("bundle %s does not seem to be installed, exiting now\n\n", filename); ret = EXIT_FAILURE; goto out; } if (S_ISREG(statb.st_mode)) { if (unlink(filename) != 0) { log_stdout("ERROR: cannot remove bundle file, exiting now %s\n\n", filename); ret = EXIT_FAILURE; goto out; } } else { log_stdout("ERROR: bundle definition file %s is corrupted, exiting now", filename); ret = EXIT_FAILURE; goto out; } verbose = 0; ret = verify_fix(VERIFY_PICKY); out: free_globals(); free(filename); free(bundle); return ret; }
RTcmix::~RTcmix() { #ifndef MAXMSP run_status = RT_SHUTDOWN; waitForMainLoop(); #endif free_globals(); }
int initialize_globals() { // Get the android data directory. if (get_path_from_env(&android_data_dir, "ANDROID_DATA") < 0) { return -1; } // Get the android app directory. if (copy_and_append(&android_app_dir, &android_data_dir, APP_SUBDIR) < 0) { return -1; } // Get the android protected app directory. if (copy_and_append(&android_app_private_dir, &android_data_dir, PRIVATE_APP_SUBDIR) < 0) { return -1; } // Get the android app native library directory. if (copy_and_append(&android_app_lib_dir, &android_data_dir, APP_LIB_SUBDIR) < 0) { return -1; } // Get the sd-card ASEC mount point. if (get_path_from_env(&android_asec_dir, "ASEC_MOUNTPOINT") < 0) { return -1; } // Get the android media directory. if (copy_and_append(&android_media_dir, &android_data_dir, MEDIA_SUBDIR) < 0) { return -1; } // Take note of the system and vendor directories. android_system_dirs.count = 2; android_system_dirs.dirs = calloc(android_system_dirs.count, sizeof(dir_rec_t)); if (android_system_dirs.dirs == NULL) { ALOGE("Couldn't allocate array for dirs; aborting\n"); return -1; } // system if (get_path_from_env(&android_system_dirs.dirs[0], "ANDROID_ROOT") < 0) { free_globals(); return -1; } // append "app/" to dirs[0] char *system_app_path = build_string2(android_system_dirs.dirs[0].path, APP_SUBDIR); android_system_dirs.dirs[0].path = system_app_path; android_system_dirs.dirs[0].len = strlen(system_app_path); // vendor // TODO replace this with an environment variable (doesn't exist yet) android_system_dirs.dirs[1].path = "/vendor/app/"; android_system_dirs.dirs[1].len = strlen(android_system_dirs.dirs[1].path); return 0; }
int update_main(int argc, char **argv) { int ret = 0; copyright_header("software update"); if (!parse_options(argc, argv)) { free_globals(); return EXIT_FAILURE; } if (cmd_line_status) { print_versions(); } else { ret = main_update(); } free_globals(); return ret; }
RTcmix::~RTcmix() { run_status = RT_SHUTDOWN; waitForMainLoop(); // This calls close() free_globals(); #ifdef EMBEDDED destroy_parser(); // clean up symbols, etc #endif }
void swupd_deinit(int lock_fd) { terminate_signature(); swupd_curl_cleanup(); free_subscriptions(); free_globals(); v_lockfile(lock_fd); dump_file_descriptor_leaks(); }
int search_main(int argc, char **argv) { int ret = 0; int lock_fd = 0; struct manifest *MoM = NULL; if (!parse_options(argc, argv)) { return EXIT_FAILURE; } ret = swupd_init(&lock_fd); if (ret != 0) { printf("Failed swupd initialization, exiting now.\n"); goto clean_exit; } if (!check_network()) { printf("Error: Network issue, unable to proceed with update\n"); ret = EXIT_FAILURE; goto clean_exit; } if (!init) { printf("Searching for '%s'\n\n", search_string); } ret = download_manifests(&MoM); if (ret != 0) { printf("Error: Failed to download manifests\n"); goto clean_exit; } if (init) { printf("Successfully retreived manifests. Exiting\n"); ret = 0; goto clean_exit; } /* Arbitrary upper limit to ensure we aren't getting handed garbage */ if (!display_files && ((strlen(search_string) <= 0) || (strlen(search_string) > NAME_MAX))) { printf("Error - search string invalid\n"); ret = EXIT_FAILURE; goto clean_exit; } do_search(MoM, search_type, search_string); clean_exit: free_manifest(MoM); free_globals(); swupd_curl_cleanup(); v_lockfile(lock_fd); return ret; }
static int bundle_add() { char *filename = NULL; int f = -1; int ret = 0; if (!init_globals()) { free_globals(); return -1; } init_log_stdout(); verbose = 1; if (asprintf(&filename, "%s/%s", BUNDLES_DIR, bundle) <= 0) { log_stdout("Error: allocating memory, exiting now\n\n"); abort(); } f = open(filename, O_WRONLY | O_CREAT | O_NONBLOCK | O_NOCTTY, MODE_RW_O); if (f < 0) { log_stdout("cannot create bundle file %s exiting now\n\n", filename); ret = EXIT_FAILURE; goto out; } close(f); log_stdout("bundle %s added, trying to install it now\n", filename); verbose = 0; ret = verify_fix(VERIFY_NOPICKY); out: free_globals(); free(filename); free(bundle); return ret; }
static int clean_init(void) { int ret = 0; check_root(); if (!init_globals()) { return SWUPD_INIT_GLOBALS_FAILED; } if (p_lockfile() < 0) { free_globals(); return SWUPD_LOCK_FILE_FAILED; } return ret; }
int main(int argc, char **argv) { struct slp_client *client; int count = 0; time_t now, last; lslpMsg msg_list; if(FALSE == get_options(argc, argv)) { usage(); } else { if(scopes == NULL) scopes = strdup("DEFAULT"); if(test == TRUE) { return test_srv_reg(type, url, attrs, scopes); } if(NULL != (client = create_slp_client(addr, iface, port, "DSA", scopes, should_listen, dir_agent))) { now = (last = time(NULL)); if( addr != NULL && inet_addr(addr) == inet_addr("127.0.0.1") ) count = client->srv_reg_local(client, url, attrs, type, scopes, life); else count = client->srv_reg_all(client, url, attrs, type, scopes, life); while(should_listen == TRUE) { _LSLP_SLEEP(10); client->service_listener(client, 0, &msg_list); now = time(NULL); if((now - last) > (life - 1)) { count = client->srv_reg_local(client, url, attrs, type, scopes, life); last = time(NULL); } } destroy_slp_client(client); } printf("srvreg: registered %s with %d SLP agents.\n", type, count); } free_globals(); return(1); }
int info_main(int UNUSED_PARAM argc, char UNUSED_PARAM **argv) { int current_version; copyright_header("info"); if (!init_globals()) { return EINIT_GLOBALS; } current_version = get_current_version(path_prefix); printf("Installed version: %d\n", current_version); printf("Version URL: %s\n", version_url); printf("Content URL: %s\n", content_url); free_globals(); return 0; }
/* Bundle install one ore more bundles passed in bundles * param as a null terminated array of strings */ int install_bundles_frontend(char **bundles) { int lock_fd; int ret = 0; int current_version; struct list *bundles_list = NULL; struct manifest *mom; /* initialize swupd and get current version from OS */ ret = swupd_init(&lock_fd); if (ret != 0) { printf("Failed updater initialization, exiting now.\n"); return ret; } current_version = read_version_from_subvol_file(path_prefix); swupd_curl_set_current_version(current_version); ret = load_manifests(current_version, current_version, "MoM", NULL, &mom); if (ret != 0) { printf("Cannot load official manifest MoM for version %i\n", current_version); ret = EMOM_NOTFOUND; goto clean_and_exit; } for (; *bundles; ++bundles) { bundles_list = list_prepend_data(bundles_list, *bundles); } ret = install_bundles(bundles_list, current_version, mom); list_free_list(bundles_list); free_manifest(mom); clean_and_exit: swupd_curl_cleanup(); v_lockfile(lock_fd); dump_file_descriptor_leaks(); free_globals(); return ret; }
int spai (matrix *A, matrix **spai_mat, FILE *messages_arg, /* file for warning messages */ double epsilon_arg, /* tolerance */ int nbsteps_arg, /* max number of "improvement" steps per line */ int max_arg, /* max dimensions of I, q, etc. */ int maxnew_arg, /* max number of new entries per step */ int cache_size_arg, /* one of (1,2,3,4,5,6) indicting size of cache */ /* cache_size == 0 indicates no caching */ int verbose_arg, int spar_arg, int lower_diag_arg, int upper_diag_arg, double tau_arg) { matrix *M; int col,ierr; int cache_sizes[6]; /* Only create resplot for the numprocs=1 case. */ if (debug && (A->numprocs == 1)) { resplot_fptr = fopen("resplot","w"); fprintf(resplot_fptr, "ep=%5.5lf ns=%d mn=%d bs=%d\n", epsilon_arg,nbsteps_arg,maxnew_arg,A->bs); fprintf(resplot_fptr,"\n"); fprintf(resplot_fptr,"scol: scalar column number\n"); fprintf(resplot_fptr,"srn: scalar resnorm\n"); fprintf(resplot_fptr,"bcol: block column number\n"); fprintf(resplot_fptr,"brn: block resnorm\n"); fprintf(resplot_fptr,"* indicates epsilon not attained\n"); fprintf(resplot_fptr,"\n"); fprintf(resplot_fptr," scol srn bcol brn\n"); } start_col = 0; num_bad_cols = 0; cache_sizes[0] = 101; cache_sizes[1] = 503; cache_sizes[2] = 2503; cache_sizes[3] = 12503; cache_sizes[4] = 62501; cache_sizes[5] = 104743; if (verbose_arg && !A->myid) { if (spar_arg == 0) printf("\n\nComputing SPAI: epsilon = %f\n",epsilon_arg); else if (spar_arg == 1) printf("\n\nComputing SPAI: tau = %f\n",tau_arg); else if (spar_arg == 2) printf("\n\nComputing SPAI: # diagonals = %d\n", lower_diag_arg+upper_diag_arg+1); fflush(stdout); } epsilon = epsilon_arg; message = messages_arg; maxnew = maxnew_arg; max_dim = max_arg; /* Determine maximum number of scalar nonzeros for any column of M */ if (spar_arg == 0) { nbsteps = nbsteps_arg; maxapi = A->max_block_size * (1 + maxnew*nbsteps); } else if(spar_arg == 1) { nbsteps = A->maxnz; maxapi = A->max_block_size * (1 + nbsteps); } else { nbsteps = lower_diag_arg+upper_diag_arg+1; maxapi = A->max_block_size * (1 + nbsteps); } allocate_globals(A); #ifdef MPI MPI_Barrier(A->comm); #endif if ((cache_size_arg < 0) || (cache_size_arg > 6)) { fprintf(stderr,"illegal cache size in spai\n"); exit(1); } if (cache_size_arg > 0) ht = init_hash_table(cache_sizes[cache_size_arg-1]); M = clone_matrix(A); ndone = 0; Im_done = 0; all_done = 0; next_line = 0; /* Timing of SPAI starts here. In a "real production" code everything before this could be static. */ if (verbose_arg) start_timer(ident_spai); if ((ierr = precompute_column_square_inverses(A)) != 0) return ierr; #ifdef MPI MPI_Barrier(A->comm); #endif for (;;) { col = grab_Mline(A, M, A->comm); if (debug && col >= 0) { fprintf(fptr_dbg,"col=%d of %d\n",col,A->n); fflush(fptr_dbg); } if (col < 0 ) break; if ((ierr = spai_line(A,col,spar_arg,lower_diag_arg,upper_diag_arg,tau_arg,M)) != 0) return ierr; } #ifdef MPI say_Im_done(A,M); do { com_server(A,M); } while (! all_done); MPI_Barrier(A->comm); #endif #ifdef MPI MPI_Barrier(A->comm); #endif if (verbose_arg) { stop_timer(ident_spai); report_times(ident_spai,"spai",0,A->comm); } free_globals(nbsteps); free_hash_table(ht); if (resplot_fptr) fclose(resplot_fptr); *spai_mat = M; return 0; }
int main(int argc, char **argv) { #ifdef PEGASUS_ENABLE_IPV6 struct in6_addr ip6_loop = PEGASUS_IPV6_LOOPBACK_INIT; struct in6_addr ip6_addr; #endif struct slp_client *client; lslpMsg responses, *temp; if (FALSE == get_options(argc, argv)) { usage(); } else { if (scopes == NULL) { scopes = strdup("DEFAULT"); } if (test == TRUE) { return test_query(type, predicate, scopes); } if(NULL != (client = create_slp_client( addr, _interface, port, "DSA", scopes, FALSE, dir_agent, type))) { if (slp_is_loop_back_addr(addr)) { client->local_srv_req(client, type, predicate, scopes); } else if (converge) { client->_convergence = converge ; client->converge_srv_req(client, type, predicate, scopes); } else { if (!addr) { client->converge_srv_req(client, type, predicate, scopes); } else { #ifdef PEGASUS_ENABLE_IPV6 SOCKADDR_IN6 ip6; #endif SOCKADDR_IN ip4; void *target = 0; if (slp_is_valid_ip4_addr(addr)) { ip4.sin_port = htons(port); ip4.sin_family = AF_INET; ip4.sin_addr.s_addr = inet_addr(addr); target = &ip4; } #ifdef PEGASUS_ENABLE_IPV6 else { memset(&ip6, 0, sizeof(ip6)); ip6.sin6_port = htons(port); ip6.sin6_family = AF_INET6; slp_pton(AF_INET6, addr, &ip6.sin6_addr); target = &ip6; } #endif if(target) { client->unicast_srv_req( client, type, predicate, scopes, (SOCKADDR*)target); } } } responses.isHead = TRUE; responses.next = responses.prev = &responses; client->get_response(client, &responses); while (! _LSLP_IS_EMPTY(&responses)) { temp = responses.next; if (temp->type == srvRply) { if (parsable == TRUE) { lslp_print_srv_rply_parse(temp, fs, rs); } else { lslp_print_srv_rply(temp); } } _LSLP_UNLINK(temp); lslpDestroySLPMsg(temp, LSLP_DESTRUCTOR_DYNAMIC); } destroy_slp_client(client); } } free_globals(); return 1; }
/* Bundle install one ore more bundles passed in bundles * param as a null terminated array of strings */ int install_bundles(char **bundles) { int lock_fd; int ret = 0; int current_version; struct manifest *mom; struct list *iter; struct sub *sub; struct file *file; /* step 1: initialize swupd and get current version from OS */ if (!init_globals()) { return EINIT_GLOBALS; } ret = swupd_init(&lock_fd); if (ret != 0) { printf("Failed updater initialization, exiting now.\n"); return ret; } current_version = read_version_from_subvol_file(path_prefix); swupd_curl_set_current_version(current_version); /* first of all, make sure STATE_DIR is there, recreate if necessary*/ ret = create_required_dirs(); if (ret != 0) { printf("State directory %s cannot be recreated, aborting installation\n", STATE_DIR); goto clean_and_exit; } ret = load_manifests(current_version, current_version, "MoM", NULL, &mom); if (ret != 0) { printf("Cannot load official manifest MoM for version %i\n", current_version); ret = EMOM_NOTFOUND; goto clean_and_exit; } /* step 2: check bundle args are valid if so populate subs struct */ int i; for (i = 0; *bundles; ++bundles) { if (is_tracked_bundle(*bundles)) { printf("%s bundle already installed, skipping it\n", *bundles); continue; } if (!manifest_has_component(mom, *bundles)) { printf("%s bundle name is invalid, skipping it...\n", *bundles); continue; } if (component_subscribed(*bundles)) { continue; } create_and_append_subscription(*bundles); i++; printf("Added bundle %s for installation\n", *bundles); } if (i == 0) { printf("There are no pending bundles to install, exiting now\n"); ret = EBUNDLE_INSTALL; goto clean_manifest_and_exit; } subscription_versions_from_MoM(mom, 0); recurse_manifest(mom, NULL); consolidate_submanifests(mom); /* step 3: download neccessary packs */ ret = rm_staging_dir_contents("download"); printf("Downloading required packs...\n"); ret = download_subscribed_packs(0, current_version, true); if (ret != 0) { printf("pack downloads failed, cannot proceed with the installation, exiting.\n"); goto clean_subs_and_exit; } /* step 4: Install all bundle(s) files into the fs */ printf("Installing bundle(s) files...\n"); iter = list_head(mom->files); while (iter) { file = iter->data; iter = iter->next; if (file->is_deleted || file->do_not_update || ignore(file)) { continue; } ret = do_staging(file); if (ret == 0) { rename_staged_file_to_final(file); } } sync(); /* step 5: create bundle(s) subscription entries to track them * * Strictly speaking each manifest has an entry to write its own bundle filename * and thus tracking automagically, here just making sure. */ iter = list_head(subs); while (iter) { sub = iter->data; iter = iter->next; printf("Tracking %s bundle on the system\n", sub->component); ret = track_bundle_in_system(sub->component); if (ret != 0) { printf("Cannot track %s bundle on the system\n", sub->component); } } /* Run any scripts that are needed to complete update */ run_scripts(); ret = 0; printf("Bundle(s) installation done.\n"); clean_subs_and_exit: free_subscriptions(); clean_manifest_and_exit: free_manifest(mom); clean_and_exit: swupd_curl_cleanup(); v_lockfile(lock_fd); dump_file_descriptor_leaks(); free_globals(); return ret; }
int main(int argc, char **argv) { struct slp_client *client; lslpMsg responses, *temp; if (FALSE == get_options(argc, argv)) { usage(); return 0; } else { if (scopes == NULL) scopes = strdup("DEFAULT"); if (NULL != (client = create_slp_client( addr, _interface, port, "DSA", scopes, FALSE, dir_agent, 0))) { if (slp_is_loop_back_addr(addr)) { client->local_attr_req(client, url, scopes, tags); } else if (converge) { client->_convergence = converge ; client->converge_attr_req(client, url, scopes, tags); } else { if (!addr) { client->converge_attr_req(client, url, scopes, tags); } else { #ifdef PEGASUS_ENABLE_IPV6 SOCKADDR_IN6 ip6; #endif SOCKADDR_IN ip4; void *target = 0; if (slp_is_valid_ip4_addr(addr)) { ip4.sin_port = htons(port); ip4.sin_family = AF_INET; ip4.sin_addr.s_addr = inet_addr(addr); target = &ip4; } #ifdef PEGASUS_ENABLE_IPV6 else { memset(&ip6, 0, sizeof(ip6)); ip6.sin6_port = htons(port); ip6.sin6_family = AF_INET6; slp_pton(AF_INET6, addr, &ip6.sin6_addr); target = &ip6; } #endif if(target) { client->unicast_attr_req( client, url, scopes, tags, (SOCKADDR*)target); } } } responses.isHead = TRUE; responses.next = responses.prev = &responses; client->get_response(client, &responses); while ( ! _LSLP_IS_EMPTY(&responses) ) { temp = responses.next; if (temp->type == attrRep) { if(parsable == TRUE && temp->msg.attrRep.attrListLen > 0) { lslp_print_attr_rply_parse(temp, fs, rs); } else { if( temp->msg.attrRep.attrListLen > 0) { printf("Attr. Reply for %s\n", url); lslp_print_attr_rply(temp); } } }/* if we got an attr rply */ _LSLP_UNLINK(temp); lslpDestroySLPMsg(temp, LSLP_DESTRUCTOR_DYNAMIC); } /* while traversing response list */ destroy_slp_client(client); } /* client successfully created */ } free_globals(); return 1 ; }
static void clean_deinit(void) { free_globals(); v_lockfile(); }
int main_update() { int current_version = -1, server_version = -1; struct manifest *current_manifest = NULL, *server_manifest = NULL; struct list *updates = NULL; int ret; int lock_fd; int retries = 0; int timeout = 10; srand(time(NULL)); ret = swupd_init(&lock_fd); if (ret != 0) { /* being here means we already close log by a previously caught error */ printf("Updater failed to initialize, exiting now.\n"); return ret; } if (!check_network()) { printf("Error: Network issue, unable to proceed with update\n"); ret = EXIT_FAILURE; goto clean_curl; } printf("Update started.\n"); read_subscriptions_alt(); if (!signature_initialize(UPDATE_CA_CERTS_PATH "/" SIGNATURE_CA_CERT)) { goto clean_curl; } /* Step 1: get versions */ ret = check_versions(¤t_version, &server_version, path_prefix); if (ret < 0) { goto clean_curl; } if (server_version <= current_version) { printf("Version on server (%i) is not newer than system version (%i)\n", server_version, current_version); ret = EXIT_SUCCESS; goto clean_curl; } printf("Preparing to update from %i to %i\n", current_version, server_version); /* Step 2: housekeeping */ if (rm_staging_dir_contents("download")) { goto clean_curl; } load_current_manifests: /* Step 3: setup manifests */ /* get the from/to MoM manifests */ printf("Querying current manifest.\n"); ret = load_manifests(current_version, current_version, "MoM", NULL, ¤t_manifest); if (ret) { /* TODO: possibly remove this as not getting a "from" manifest is not fatal * - we just don't apply deltas */ if (retries < MAX_TRIES) { increment_retries(&retries, &timeout); printf("Retry #%d downloading from/to MoM Manifests\n", retries); goto load_current_manifests; } printf("Failure retrieving manifest from server\n"); goto clean_exit; } /* Reset the retries and timeout for subsequent download calls */ retries = 0; timeout = 10; load_server_manifests: printf("Querying server manifest.\n"); ret = load_manifests(current_version, server_version, "MoM", NULL, &server_manifest); if (ret) { if (retries < MAX_TRIES) { increment_retries(&retries, &timeout); printf("Retry #%d downloading server Manifests\n", retries); goto load_server_manifests; } printf("Failure retrieving manifest from server\n"); goto clean_exit; } if (current_manifest == NULL || server_manifest == NULL) { printf("Unable to load manifest after retrying (config or network problem?)\n"); goto clean_exit; } retries = 0; timeout = 10; ret = add_included_manifests(server_manifest); if (ret) { goto clean_exit; } subscription_versions_from_MoM(current_manifest, 1); subscription_versions_from_MoM(server_manifest, 0); link_submanifests(current_manifest, server_manifest); /* updating subscribed manifests is done as part of recurse_manifest */ /* read the current collective of manifests that we are subscribed to */ current_manifest->submanifests = recurse_manifest(current_manifest, NULL); if (!current_manifest->submanifests) { printf("Cannot load current MoM sub-manifests, (%s), exiting\n", strerror(errno)); goto clean_exit; } /* consolidate the current collective manifests down into one in memory */ current_manifest->files = files_from_bundles(current_manifest->submanifests); current_manifest->files = consolidate_files(current_manifest->files); /* read the new collective of manifests that we are subscribed to */ server_manifest->submanifests = recurse_manifest(server_manifest, NULL); if (!server_manifest->submanifests) { printf("Error: Cannot load server MoM sub-manifests, (%s), exiting\n", strerror(errno)); goto clean_exit; } /* consolidate the new collective manifests down into one in memory */ server_manifest->files = files_from_bundles(server_manifest->submanifests); server_manifest->files = consolidate_files(server_manifest->files); /* prepare for an update process based on comparing two in memory manifests */ link_manifests(current_manifest, server_manifest); #if 0 debug_write_manifest(current_manifest, "debug_manifest_current.txt"); debug_write_manifest(server_manifest, "debug_manifest_server.txt"); #endif /* Step 4: check disk state before attempting update */ run_preupdate_scripts(server_manifest); download_packs: /* Step 5: get the packs and untar */ ret = download_subscribed_packs(false); if (ret) { // packs don't always exist, tolerate that but not ENONET if (retries < MAX_TRIES) { increment_retries(&retries, &timeout); printf("Retry #%d downloading packs\n", retries); goto download_packs; } printf("No network, or server unavailable for pack downloads\n"); goto clean_exit; } /* Step 6: some more housekeeping */ /* TODO: consider trying to do less sorting of manifests */ updates = create_update_list(current_manifest, server_manifest); link_renames(updates, current_manifest); /* TODO: Have special lists for candidate and renames */ print_statistics(current_version, server_version); /* Step 7: apply the update */ ret = update_loop(updates, server_manifest); if (ret == 0) { ret = update_device_latest_version(server_version); printf("Update was applied.\n"); } delete_motd(); /* Run any scripts that are needed to complete update */ run_scripts(); clean_exit: list_free_list(updates); free_manifest(current_manifest); free_manifest(server_manifest); clean_curl: signature_terminate(); swupd_curl_cleanup(); free_subscriptions(); free_globals(); v_lockfile(lock_fd); dump_file_descriptor_leaks(); if ((current_version < server_version) && (ret == 0)) { printf("Update successful. System updated from version %d to version %d\n", current_version, server_version); } else if (ret == 0) { printf("Update complete. System already up-to-date at version %d\n", current_version); } return ret; }