Example #1
0
void swupd_deinit(void)
{
	terminate_signature();
	swupd_curl_deinit();
	free_globals();
	v_lockfile();
	dump_file_descriptor_leaks();
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #5
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;
}
Example #6
0
RTcmix::~RTcmix()
{
	run_status = RT_SHUTDOWN;
	waitForMainLoop();	// This calls close()
	free_globals();
#ifdef EMBEDDED
	destroy_parser();	// clean up symbols, etc
#endif
}
Example #7
0
void swupd_deinit(int lock_fd)
{
	terminate_signature();
	swupd_curl_cleanup();
	free_subscriptions();
	free_globals();
	v_lockfile(lock_fd);
	dump_file_descriptor_leaks();
}
Example #8
0
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;
}
Example #9
0
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;
}
Example #10
0
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;
}
Example #11
0
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);
}
Example #12
0
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;
}
Example #13
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;
}
Example #14
0
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;

}
Example #15
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;
}
Example #16
0
/* 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;
}
Example #17
0
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 ;
}
Example #18
0
static void clean_deinit(void)
{
	free_globals();
	v_lockfile();
}
Example #19
0
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(&current_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, &current_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;
}