/* Check if the format at default_format_path has changed from the beginning * of the update */ bool on_new_format(void) { int res = -1; int err; char *ret_str; res = get_value_from_path(&ret_str, DEFAULT_FORMAT_PATH, false); if (res != 0) { // could not detect current format return false; } err = strtoi_err(ret_str, NULL, &res); free_string(&ret_str); if (err != 0) { return false; } /* is_compatible_format returns true if the argument matches the * format_string, which was read at the beginning of the update. Return the * opposite of is_compatible_format to indicate when the new format is * different from the one we started on. */ return !is_compatible_format(res); }
int get_current_version(char *path_prefix) { char line[LINE_MAX]; FILE *file; int v = -1; int err; char *buildstamp; char *src, *dest; string_or_die(&buildstamp, "%s/usr/lib/os-release", path_prefix); file = fopen(buildstamp, "rm"); if (!file) { free_string(&buildstamp); string_or_die(&buildstamp, "%s/etc/os-release", path_prefix); file = fopen(buildstamp, "rm"); if (!file) { free_string(&buildstamp); return v; } } while (!feof(file)) { line[0] = 0; if (fgets(line, LINE_MAX, file) == NULL) { break; } if (strncmp(line, "VERSION_ID=", 11) == 0) { src = &line[11]; /* Drop quotes and newline in value */ dest = src; while (*src) { if (*src == '\'' || *src == '"' || *src == '\n') { ++src; } else { *dest = *src; ++dest; ++src; } } *dest = 0; err = strtoi_err(&line[11], &v); if (err != 0) { v = -1; } break; } } free_string(&buildstamp); fclose(file); return v; }
/* this function attempts to download the latest server version string file from * the preferred server to a memory buffer, returning either a negative integer * error code or >= 0 representing the server version * * if v_url is non-NULL the version at v_url is fetched. If v_url is NULL the * global version_url is used and the cached version may be used instead of * attempting to download the version string again. If v_url is the empty string * the global version_url is used and the cached version is ignored. */ int get_latest_version(char *v_url) { #define MAX_VERSION_CHARS 10 #define MAX_VERSION_STR_SIZE 11 char *url = NULL; int ret = 0; int err; char version_str[MAX_VERSION_STR_SIZE]; struct curl_file_data tmp_version = { MAX_VERSION_STR_SIZE, 0, version_str }; static int cached_version = -1; if (cached_version > 0 && v_url == NULL) { return cached_version; } if (v_url == NULL || strcmp(v_url, "") == 0) { v_url = version_url; } string_or_die(&url, "%s/version/format%s/latest", v_url, format_string); ret = swupd_curl_get_file_memory(url, &tmp_version); if (ret) { goto out; } else { tmp_version.data[tmp_version.len] = '\0'; err = strtoi_err(tmp_version.data, &ret); if (err != 0) { ret = -1; } } out: free_string(&url); cached_version = ret; return ret; }
int read_mix_version_file(char *filename, char *path_prefix) { char line[LINE_MAX]; FILE *file; int v = -1; int err; char *buildstamp; string_or_die(&buildstamp, "%s%s", path_prefix, filename); file = fopen(buildstamp, "rm"); if (!file) { free_string(&buildstamp); return v; } while (!feof(file)) { line[0] = 0; if (fgets(line, LINE_MAX, file) == NULL) { break; } /* Drop newline in value */ char *c = strchr(line, '\n'); if (c) { *c = '\0'; } err = strtoi_err(line, &v); if (err != 0) { v = -1; } } free_string(&buildstamp); fclose(file); return v; }
static bool parse_options(int argc, char **argv) { int opt; int err; while ((opt = getopt_long(argc, argv, "hu:c:v:P:p:F:s:t:mlbinIdS:C:", prog_opts, NULL)) != -1) { switch (opt) { case '?': case 'h': print_help(argv[0]); exit(0); case 'u': if (!optarg) { fprintf(stderr, "error: invalid --url argument\n\n"); goto err; } set_version_url(optarg); set_content_url(optarg); break; case 'c': if (!optarg) { fprintf(stderr, "Invalid --contenturl argument\n\n"); goto err; } set_content_url(optarg); break; case 'v': if (!optarg) { fprintf(stderr, "Invalid --versionurl argument\n\n"); goto err; } set_version_url(optarg); break; case 'P': if (sscanf(optarg, "%ld", &update_server_port) != 1) { fprintf(stderr, "Invalid --port argument\n\n"); goto err; } break; case 'p': /* default empty path_prefix verifies the running OS */ if (!optarg || !set_path_prefix(optarg)) { fprintf(stderr, "Invalid --path argument\n\n"); goto err; } break; case 's': if (!optarg || (strcmp(optarg, "b") && (strcmp(optarg, "o")))) { fprintf(stderr, "Invalid --scope argument. Must be 'b' or 'o'\n\n"); goto err; } if (!strcmp(optarg, "b")) { scope = 'b'; } else if (!strcmp(optarg, "o")) { scope = 'o'; } break; case 't': err = strtoi_err(optarg, NULL, &num_results); if (err != 0) { fprintf(stderr, "Invalid --top argument\n\n"); goto err; } break; case 'm': csv_format = true; break; case 'F': if (!optarg || !set_format_string(optarg)) { fprintf(stderr, "Invalid --format argument\n\n"); goto err; } break; case 'S': if (!optarg || !set_state_dir(optarg)) { fprintf(stderr, "Invalid --statedir argument\n\n"); goto err; } break; case 'l': if (search_type != '0') { fprintf(stderr, "Error, cannot specify multiple search types " "(-l and -b are mutually exclusive)\n"); goto err; } search_type = 'l'; break; case 'i': init = true; break; case 'n': sigcheck = false; break; case 'I': timecheck = false; break; case 'b': if (search_type != '0') { fprintf(stderr, "Error, cannot specify multiple search types " "(-l and -b are mutually exclusive)\n"); goto err; } search_type = 'b'; break; case 'd': display_files = true; break; case 'C': if (!optarg) { fprintf(stderr, "Invalid --certpath argument\n\n"); goto err; } set_cert_path(optarg); break; default: fprintf(stderr, "Error: unrecognized option: -'%c',\n\n", opt); goto err; } } if ((optind == argc) && (!init) && (!display_files)) { fprintf(stderr, "Error: Search term missing\n\n"); print_help(argv[0]); return false; } if ((optind == argc - 1) && (display_files)) { fprintf(stderr, "Error: Cannot supply a search term and -d, --display-files together\n"); return false; } search_string = argv[optind]; if (optind + 1 < argc) { fprintf(stderr, "Error, only 1 search term supported at a time\n"); return false; } return true; err: print_help(argv[0]); return false; }