Files
swupd-client/include/swupd.h
T
Matthew Johnson de9c2c4dd8 Make some small improvements to new swupd search
Remove some of the magic numbers, add some comments, fix some code
style, remove an unnecessary string duplication, free dynamically
allocated memory in response to feedback on PR #387.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2018-02-21 17:45:28 -08:00

421 lines
14 KiB
C

#ifndef __INCLUDE_GUARD_SWUPD_H
#define __INCLUDE_GUARD_SWUPD_H
#include <curl/curl.h>
#include <dirent.h>
#include <limits.h>
#include <regex.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/queue.h>
#include "list.h"
#include "swupd-error.h"
#ifdef __cplusplus
extern "C" {
#endif
/* WARNING: keep SWUPD_VERSION_INCR in sync with server definition */
#define SWUPD_VERSION_INCR 10
#define SWUPD_VERSION_IS_DEVEL(v) (((v) % SWUPD_VERSION_INCR) == 8)
#define SWUPD_VERSION_IS_RESVD(v) (((v) % SWUPD_VERSION_INCR) == 9)
#ifndef LINE_MAX
#define LINE_MAX _POSIX2_LINE_MAX
#endif
#define PATH_MAXLEN 4096
#define CURRENT_OS_VERSION -1
#define BUNDLE_NAME_MAXLEN 256
#define UNUSED_PARAM __attribute__((__unused__))
#define MAX_TRIES 3
#define SWUPD_HASH_DIRNAME "DIRECTORY"
#define SWUPD_DEFAULTS "/usr/share/defaults/swupd/"
#define MIX_DIR "/usr/share/mix/"
#define MIX_STATE_DIR MIX_DIR "update/www/"
#define MIX_CERT MIX_DIR "Swupd_Root.pem"
#define MIX_BUNDLES_DIR MIX_STATE_DIR "mix-bundles/"
#define MIXED_FILE SWUPD_DEFAULTS "mixed"
#define DEFAULT_VERSION_URL_PATH "/usr/share/defaults/swupd/versionurl"
#define DEFAULT_CONTENT_URL_PATH "/usr/share/defaults/swupd/contenturl"
#define DEFAULT_FORMAT_PATH "/usr/share/defaults/swupd/format"
#define DEFAULT_CONTENTURL "https://cdn.download.clearlinux.org/update/"
struct sub {
/* name of bundle/component/subscription */
char *component;
/* version meanings:
* non-zero -> version has been read from MoM
* -1 -> error, local bundle do not match any bundle on MoM */
int version;
/* oldversion: set to 0 by calloc(), possibly overridden by MoM read */
int oldversion;
};
struct manifest {
int version;
int manifest_version;
uint64_t filecount;
uint64_t contentsize;
struct list *files;
struct list *manifests; /* struct file for possible manifests */
struct list *submanifests; /* struct manifest for subscribed manifests */
struct list *includes; /* manifest names included in manifest */
char *component;
unsigned int is_mix : 1;
};
struct version_container {
size_t offset;
char *version;
};
struct header;
extern bool allow_mix_collisions;
extern bool verbose_time;
extern bool force;
extern bool migrate;
extern bool sigcheck;
extern bool timecheck;
extern int verbose;
extern int update_count;
extern int update_skip;
extern bool update_complete;
extern bool need_update_boot;
extern bool need_update_bootloader;
extern bool need_systemd_reexec;
extern struct list *post_update_actions;
struct update_stat {
uint64_t st_mode;
uint64_t st_uid;
uint64_t st_gid;
uint64_t st_rdev;
uint64_t st_size;
};
#define DIGEST_LEN_SHA256 64
/* +1 for null termination */
#define SWUPD_HASH_LEN (DIGEST_LEN_SHA256 + 1)
struct file {
char *filename;
char hash[SWUPD_HASH_LEN];
bool use_xattrs;
int last_change;
struct update_stat stat;
unsigned int is_dir : 1;
unsigned int is_file : 1;
unsigned int is_link : 1;
unsigned int is_deleted : 1;
unsigned int is_ghosted : 1;
unsigned int is_tracked : 1;
unsigned int is_manifest : 1;
unsigned int is_config : 1;
unsigned int is_state : 1;
unsigned int is_boot : 1;
unsigned int is_rename : 1;
unsigned int is_orphan : 1;
unsigned int is_mix : 1;
unsigned int do_not_update : 1;
struct file *peer; /* same file in another manifest */
struct file *deltapeer; /* the file to do the binary delta against; often same as "peer" except in rename cases */
struct header *header;
char *staging; /* output name used during download & staging */
CURL *curl; /* curl handle if downloading */
FILE *fh; /* file written into during downloading */
};
struct filerecord {
char *filename;
bool dir;
bool in_manifest;
};
struct time {
struct timespec procstart;
struct timespec procstop;
struct timespec rawstart;
struct timespec rawstop;
const char *name;
bool complete;
TAILQ_ENTRY(time)
times;
};
typedef TAILQ_HEAD(timelist, time) timelist;
extern bool download_only;
extern bool verify_esp_only;
extern bool have_manifest_diskspace;
extern bool have_network;
extern bool verify_bundles_only;
extern bool ignore_config;
extern bool ignore_state;
extern bool ignore_orphans;
extern bool no_scripts;
extern bool no_boot_update;
extern char *format_string;
extern char *path_prefix;
extern bool set_format_string(char *userinput);
extern bool init_globals(void);
extern void free_globals(void);
extern void save_cmd(char **argv);
extern char *swupd_cmd;
extern char *bundle_to_add;
extern struct timeval start_time;
extern char *state_dir;
extern char *version_url;
extern char *content_url;
extern char *cert_path;
extern long update_server_port;
extern char *default_format_path;
extern bool set_path_prefix(char *path);
extern int set_content_url(char *url);
extern int set_version_url(char *url);
extern void set_cert_path(char *path);
extern bool set_state_dir(char *path);
extern void check_root(void);
extern void clean_curl_multi_queue(void);
extern void increment_retries(int *retries, int *timeout);
extern int main_update(void);
extern int add_included_manifests(struct manifest *mom, int current, struct list **subs);
extern int main_verify(int current_version);
extern int walk_tree(struct manifest *, const char *, bool, const regex_t *);
extern int get_latest_version(void);
extern void read_versions(int *current_version, int *server_version, char *path_prefix);
extern int check_versions(int *current_version, int *server_version, char *path_prefix);
extern int get_current_version(char *path_prefix);
extern bool ignore(struct file *file);
extern void apply_heuristics(struct file *file);
extern int file_sort_filename(const void *a, const void *b);
extern int file_sort_filename_reverse(const void *a, const void *b);
extern struct manifest *load_mom(int version, bool latest, bool mix_exists);
extern struct manifest *load_manifest(int current, int version, struct file *file, struct manifest *mom, bool header_only);
extern struct manifest *load_manifest_full(int version, bool mix);
extern struct list *create_update_list(struct manifest *current, struct manifest *server);
extern void link_manifests(struct manifest *m1, struct manifest *m2);
extern void link_submanifests(struct manifest *m1, struct manifest *m2, struct list *subs1, struct list *subs2, bool server);
extern void free_manifest(struct manifest *manifest);
extern void remove_manifest_files(char *filename, int version, char *hash);
extern void grabtime_start(timelist *list, const char *name);
extern void grabtime_stop(timelist *list);
extern void print_time_stats(timelist *list);
extern int get_value_from_path(char **contents, const char *path, bool is_abs_path);
extern int get_version_from_path(const char *abs_path);
extern timelist init_timelist(void);
extern int extract_to(const char *tarfile, const char *outputdir);
static inline int bsearch_file_helper(const void *A, const void *B)
{
struct file *key = (struct file *)A;
struct file *elem = (*(struct file **)B);
return strcmp(key->filename, elem->filename);
}
extern int swupd_stats[];
static inline void account_new_file(void)
{
swupd_stats[0]++;
}
static inline void account_deleted_file(void)
{
swupd_stats[1]++;
}
static inline void account_changed_file(void)
{
swupd_stats[2]++;
};
static inline void account_new_bundle(void)
{
swupd_stats[3]++;
};
static inline void account_deleted_bundle(void)
{
swupd_stats[4]++;
};
static inline void account_changed_bundle(void)
{
swupd_stats[5]++;
};
static inline void account_delta_hit(void)
{
swupd_stats[6]++;
};
static inline void account_delta_miss(void)
{
swupd_stats[7]++;
};
extern void print_statistics(int version1, int version2);
extern int download_subscribed_packs(struct list *subs, struct manifest *mom, bool required, bool resume_ok);
extern void try_delta(struct file *file);
extern void full_download(struct file *file);
extern int start_full_download(bool pipelining);
extern struct list *end_full_download(void);
extern int untar_full_download(void *data);
extern int do_staging(struct file *file, struct manifest *manifest);
extern int rename_all_files_to_final(struct list *updates);
extern int rename_staged_file_to_final(struct file *file);
extern int update_device_latest_version(int version);
extern int swupd_curl_init(void);
extern void swupd_curl_cleanup(void);
extern int swupd_curl_check_network(void);
extern void swupd_curl_set_current_version(int v);
extern void swupd_curl_set_requested_version(int v);
extern double swupd_query_url_content_size(char *url);
extern CURLcode swupd_download_file_start(struct file *file);
extern CURLcode swupd_download_file_complete(CURLcode curl_ret, struct file *file);
extern int swupd_curl_get_file(const char *url, char *filename, struct file *file,
struct version_container *tmp_version, bool resume_ok);
#define SWUPD_CURL_LOW_SPEED_LIMIT 1
#define SWUPD_CURL_CONNECT_TIMEOUT 30
#define SWUPD_CURL_RCV_TIMEOUT 120
extern CURLcode swupd_curl_set_basic_options(CURL *curl, const char *url);
extern void free_subscriptions(struct list **subs);
extern void read_subscriptions(struct list **subs);
extern int component_subscribed(struct list *subs, char *component);
extern void set_subscription_versions(struct manifest *latest, struct manifest *current, struct list **subs);
extern void hash_assign(char *src, char *dest);
extern bool hash_equal(char *hash1, char *hash2);
extern bool hash_is_zeros(char *hash);
extern int compute_hash_lazy(struct file *file, char *filename);
extern int compute_hash(struct file *file, char *filename) __attribute__((warn_unused_result));
/* manifest.c */
extern struct list *recurse_manifest(struct manifest *manifest, struct list *subs, const char *component, bool server);
extern struct list *consolidate_files(struct list *files);
extern void debug_write_manifest(struct manifest *manifest, char *filename);
extern void populate_file_struct(struct file *file, char *filename);
extern bool verify_file(struct file *file, char *filename);
extern int verify_bundle_hash(struct manifest *manifest, struct file *bundle);
extern void unlink_all_staged_content(struct file *file);
extern void link_renames(struct list *newfiles, struct manifest *from_manifest);
extern void dump_file_descriptor_leaks(void);
extern int rm_staging_dir_contents(const char *rel_path);
extern void dump_file_info(struct file *file);
void free_file_data(void *data);
void free_manifest_data(void *data);
void remove_files_in_manifest_from_fs(struct manifest *m);
void deduplicate_files_from_manifest(struct manifest **m1, struct manifest *m2);
extern struct file *search_bundle_in_manifest(struct manifest *manifest, const char *bundlename);
extern struct file *search_file_in_manifest(struct manifest *manifest, const char *filename);
extern char *mounted_dirs;
extern char *mk_full_filename(const char *prefix, const char *path);
extern bool is_directory_mounted(const char *filename);
extern bool is_under_mounted_directory(const char *filename);
extern void run_scripts(bool block);
extern void run_preupdate_scripts(struct manifest *manifest);
/* lock.c */
int p_lockfile(void);
void v_lockfile(int fd);
/* helpers.c */
extern int swupd_rm(const char *path);
extern int rm_bundle_file(const char *bundle);
extern void print_manifest_files(struct manifest *m);
extern void swupd_deinit(int lock_fd, struct list **subs);
extern int swupd_init(int *lock_fd);
extern void copyright_header(const char *name);
extern void string_or_die(char **strp, const char *fmt, ...);
extern void free_string(char **s);
void update_motd(int new_release);
void delete_motd(void);
extern int get_dirfd_path(const char *fullname);
extern int verify_fix_path(char *targetpath, struct manifest *manifest);
extern struct list *files_from_bundles(struct list *bundles);
extern bool version_files_consistent(void);
extern bool string_in_list(char *string_to_check, struct list *list_to_check);
extern void print_progress(unsigned int count, unsigned int max);
extern bool is_compatible_format(int format_num);
extern bool is_current_version(int version);
extern bool on_new_format(void);
/* subscription.c */
struct list *free_list_file(struct list *item);
struct list *free_bundle(struct list *item);
extern void create_and_append_subscription(struct list **subs, const char *component);
/* bundle.c */
extern bool is_tracked_bundle(const char *bundle_name);
extern int remove_bundle(const char *bundle_name);
extern int show_bundle_reqd_by(const char *bundle_name, bool server);
extern int show_included_bundles(char *bundle_name);
extern void required_by(struct list **list, const char *bundle_name, struct manifest *mom, int rl);
extern int list_installable_bundles();
extern int install_bundles_frontend(char **bundles);
extern int add_subscriptions(struct list *bundles, struct list **subs, int current_version, struct manifest *mom, bool find_all, int recursion);
int list_local_bundles();
/* telemetry.c */
typedef enum telem_prio_t {
TELEMETRY_DEBG = 1,
TELEMETRY_INFO,
TELEMETRY_WARN,
TELEMETRY_CRIT
} telem_prio_t;
extern void telemetry(telem_prio_t level, const char *class, const char *fmt, ...);
extern struct file **manifest_files_to_array(struct manifest *manifest);
extern int enforce_compliant_manifest(struct file **a, struct file **b, int searchsize, int size);
extern void free_manifest_array(struct file **array);
extern bool system_on_mix(void);
extern bool check_mix_exists(void);
extern void check_mix_versions(int *current_version, int *server_version, char *path_prefix);
extern int read_mix_version_file(char *filename, char *path_prefix);
/* some disk sizes constants for the various features:
* ...consider adding build automation to catch at build time
* if the build's artifacts are larger than these thresholds */
#define MANIFEST_REQUIRED_SIZE (1024 * 1024 * 100) /* 100M */
#define FREE_MARGIN 10 /* 10% */
/****************************************************************/
#ifdef __cplusplus
}
#endif
#endif