diff options
Diffstat (limited to '')
-rw-r--r-- | updater/Android.mk | 71 | ||||
-rw-r--r-- | updater/blockimg.cpp | 46 | ||||
-rw-r--r-- | updater/install.cpp | 206 | ||||
-rw-r--r-- | updater/install.h | 4 | ||||
-rw-r--r-- | updater/updater.cpp | 3 | ||||
-rw-r--r-- | updater/updater.h | 4 |
6 files changed, 97 insertions, 237 deletions
diff --git a/updater/Android.mk b/updater/Android.mk index d7aa613e9..e4d73a45a 100644 --- a/updater/Android.mk +++ b/updater/Android.mk @@ -14,49 +14,58 @@ LOCAL_PATH := $(call my-dir) -updater_src_files := \ - install.cpp \ - blockimg.cpp \ - updater.cpp - -# -# Build a statically-linked binary to include in OTA packages -# +# updater (static executable) +# =============================== +# Build a statically-linked binary to include in OTA packages. include $(CLEAR_VARS) -# Build only in eng, so we don't end up with a copy of this in /system -# on user builds. (TODO: find a better way to build device binaries -# needed only for OTA packages.) -LOCAL_MODULE_TAGS := eng +updater_src_files := \ + install.cpp \ + blockimg.cpp \ + updater.cpp LOCAL_CLANG := true - LOCAL_SRC_FILES := $(updater_src_files) -LOCAL_STATIC_LIBRARIES += libfec libfec_rs libext4_utils_static libsquashfs_utils libcrypto_static +LOCAL_STATIC_LIBRARIES += \ + $(TARGET_RECOVERY_UPDATER_LIBS) \ + $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS) \ + libfec \ + libfec_rs \ + libext4_utils_static \ + libsquashfs_utils \ + libcrypto_utils \ + libcrypto \ + libapplypatch \ + libotafault \ + libedify \ + libminzip \ + libmounts \ + libz \ + libbz \ + libcutils \ + liblog \ + libselinux \ + libbase \ + liblog + +tune2fs_static_libraries := \ + libext2_com_err \ + libext2_blkid \ + libext2_quota \ + libext2_uuid_static \ + libext2_e2p \ + libext2fs + +LOCAL_STATIC_LIBRARIES += \ + libtune2fs \ + $(tune2fs_static_libraries) -ifeq ($(TARGET_USERIMAGES_USE_EXT4), true) -LOCAL_CFLAGS += -DUSE_EXT4 LOCAL_CFLAGS += -Wno-unused-parameter LOCAL_C_INCLUDES += system/extras/ext4_utils LOCAL_STATIC_LIBRARIES += \ libsparse_static \ libz -endif - -LOCAL_STATIC_LIBRARIES += $(TARGET_RECOVERY_UPDATER_LIBS) $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS) -LOCAL_STATIC_LIBRARIES += libapplypatch libbase libotafault libedify libmtdutils libminzip libz -LOCAL_STATIC_LIBRARIES += libbz -LOCAL_STATIC_LIBRARIES += libcutils liblog libc -LOCAL_STATIC_LIBRARIES += libselinux -tune2fs_static_libraries := \ - libext2_com_err \ - libext2_blkid \ - libext2_quota \ - libext2_uuid_static \ - libext2_e2p \ - libext2fs -LOCAL_STATIC_LIBRARIES += libtune2fs $(tune2fs_static_libraries) LOCAL_C_INCLUDES += external/e2fsprogs/misc LOCAL_C_INCLUDES += $(LOCAL_PATH)/.. diff --git a/updater/blockimg.cpp b/updater/blockimg.cpp index a80180a9a..0caa1acbd 100644 --- a/updater/blockimg.cpp +++ b/updater/blockimg.cpp @@ -40,6 +40,7 @@ #include <android-base/parseint.h> #include <android-base/strings.h> +#include <android-base/unique_fd.h> #include "applypatch/applypatch.h" #include "edify/expr.h" @@ -49,7 +50,6 @@ #include "minzip/Hash.h" #include "ota_io.h" #include "print_sha1.h" -#include "unique_fd.h" #include "updater.h" #define BLOCKSIZE 4096 @@ -151,6 +151,10 @@ static int read_all(int fd, uint8_t* data, size_t size) { failure_type = kFreadFailure; fprintf(stderr, "read failed: %s\n", strerror(errno)); return -1; + } else if (r == 0) { + failure_type = kFreadFailure; + fprintf(stderr, "read reached unexpected EOF.\n"); + return -1; } so_far += r; } @@ -213,7 +217,7 @@ static void allocate(size_t size, std::vector<uint8_t>& buffer) { } struct RangeSinkState { - RangeSinkState(RangeSet& rs) : tgt(rs) { }; + explicit RangeSinkState(RangeSet& rs) : tgt(rs) { }; int fd; const RangeSet& tgt; @@ -398,7 +402,7 @@ struct CommandParameters { std::string stashbase; bool canwrite; int createdstash; - int fd; + android::base::unique_fd fd; bool foundwrites; bool isunresumable; int version; @@ -608,9 +612,7 @@ static int LoadStash(CommandParameters& params, const std::string& base, const s return -1; } - int fd = TEMP_FAILURE_RETRY(open(fn.c_str(), O_RDONLY)); - unique_fd fd_holder(fd); - + android::base::unique_fd fd(TEMP_FAILURE_RETRY(ota_open(fn.c_str(), O_RDONLY))); if (fd == -1) { fprintf(stderr, "open \"%s\" failed: %s\n", fn.c_str(), strerror(errno)); return -1; @@ -665,9 +667,9 @@ static int WriteStash(const std::string& base, const std::string& id, int blocks fprintf(stderr, " writing %d blocks to %s\n", blocks, cn.c_str()); - int fd = TEMP_FAILURE_RETRY(open(fn.c_str(), O_WRONLY | O_CREAT | O_TRUNC, STASH_FILE_MODE)); - unique_fd fd_holder(fd); - + android::base::unique_fd fd(TEMP_FAILURE_RETRY(ota_open(fn.c_str(), + O_WRONLY | O_CREAT | O_TRUNC, + STASH_FILE_MODE))); if (fd == -1) { fprintf(stderr, "failed to create \"%s\": %s\n", fn.c_str(), strerror(errno)); return -1; @@ -690,9 +692,8 @@ static int WriteStash(const std::string& base, const std::string& id, int blocks } std::string dname = GetStashFileName(base, "", ""); - int dfd = TEMP_FAILURE_RETRY(open(dname.c_str(), O_RDONLY | O_DIRECTORY)); - unique_fd dfd_holder(dfd); - + android::base::unique_fd dfd(TEMP_FAILURE_RETRY(ota_open(dname.c_str(), + O_RDONLY | O_DIRECTORY))); if (dfd == -1) { failure_type = kFileOpenFailure; fprintf(stderr, "failed to open \"%s\" failed: %s\n", dname.c_str(), strerror(errno)); @@ -980,8 +981,8 @@ static int LoadSrcTgtVersion3(CommandParameters& params, RangeSet& tgt, size_t& tgthash = params.tokens[params.cpos++]; } - if (LoadSrcTgtVersion2(params, tgt, src_blocks, params.buffer, params.fd, params.stashbase, - &overlap) == -1) { + if (LoadSrcTgtVersion2(params, tgt, src_blocks, params.buffer, params.fd, + params.stashbase, &overlap) == -1) { return -1; } @@ -1382,8 +1383,7 @@ static unsigned int HashString(const char *s) { static Value* PerformBlockImageUpdate(const char* name, State* state, int /* argc */, Expr* argv[], const Command* commands, size_t cmdcount, bool dryrun) { - CommandParameters params; - memset(¶ms, 0, sizeof(params)); + CommandParameters params = {}; params.canwrite = !dryrun; fprintf(stderr, "performing %s\n", dryrun ? "verification" : "update"); @@ -1452,9 +1452,7 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, int /* arg return StringValue(strdup("")); } - params.fd = TEMP_FAILURE_RETRY(open(blockdev_filename->data, O_RDWR)); - unique_fd fd_holder(params.fd); - + params.fd.reset(TEMP_FAILURE_RETRY(ota_open(blockdev_filename->data, O_RDWR))); if (params.fd == -1) { fprintf(stderr, "open \"%s\" failed: %s\n", blockdev_filename->data, strerror(errno)); return StringValue(strdup("")); @@ -1613,7 +1611,7 @@ pbiudone: failure_type = kFsyncFailure; fprintf(stderr, "fsync failed: %s\n", strerror(errno)); } - // params.fd will be automatically closed because of the fd_holder above. + // params.fd will be automatically closed because it's a unique_fd. // Only delete the stash if the update cannot be resumed, or it's // a verification run and we created the stash. @@ -1739,9 +1737,8 @@ Value* RangeSha1Fn(const char* name, State* state, int /* argc */, Expr* argv[]) return StringValue(strdup("")); } - int fd = open(blockdev_filename->data, O_RDWR); - unique_fd fd_holder(fd); - if (fd < 0) { + android::base::unique_fd fd(ota_open(blockdev_filename->data, O_RDWR)); + if (fd == -1) { ErrorAbort(state, kFileOpenFailure, "open \"%s\" failed: %s", blockdev_filename->data, strerror(errno)); return StringValue(strdup("")); @@ -1795,8 +1792,7 @@ Value* CheckFirstBlockFn(const char* name, State* state, int argc, Expr* argv[]) return StringValue(strdup("")); } - int fd = open(arg_filename->data, O_RDONLY); - unique_fd fd_holder(fd); + android::base::unique_fd fd(ota_open(arg_filename->data, O_RDONLY)); if (fd == -1) { ErrorAbort(state, kFileOpenFailure, "open \"%s\" failed: %s", arg_filename->data, strerror(errno)); diff --git a/updater/install.cpp b/updater/install.cpp index 005f9f97d..4c4886d51 100644 --- a/updater/install.cpp +++ b/updater/install.cpp @@ -27,7 +27,6 @@ #include <unistd.h> #include <fcntl.h> #include <time.h> -#include <selinux/selinux.h> #include <ftw.h> #include <sys/capability.h> #include <sys/xattr.h> @@ -40,6 +39,8 @@ #include <android-base/parseint.h> #include <android-base/strings.h> #include <android-base/stringprintf.h> +#include <selinux/label.h> +#include <selinux/selinux.h> #include "bootloader.h" #include "applypatch/applypatch.h" @@ -49,18 +50,15 @@ #include "edify/expr.h" #include "error_code.h" #include "minzip/DirUtil.h" -#include "mtdutils/mounts.h" -#include "mtdutils/mtdutils.h" +#include "mounts.h" #include "openssl/sha.h" #include "ota_io.h" #include "updater.h" #include "install.h" #include "tune2fs.h" -#ifdef USE_EXT4 #include "make_ext4fs.h" #include "wipe.h" -#endif // Send over the buffer to recovery though the command pipe. static void uiPrint(State* state, const std::string& buffer) { @@ -82,8 +80,7 @@ static void uiPrint(State* state, const std::string& buffer) { fprintf(stderr, "%s", buffer.c_str()); } -__attribute__((__format__(printf, 2, 3))) __nonnull((2)) -void uiPrintf(State* state, const char* format, ...) { +void uiPrintf(State* _Nonnull state, const char* _Nonnull format, ...) { std::string error_msg; va_list ap; @@ -109,7 +106,6 @@ char* PrintSha1(const uint8_t* digest) { // mount(fs_type, partition_type, location, mount_point) // -// fs_type="yaffs2" partition_type="MTD" location=partition // fs_type="ext4" partition_type="EMMC" location=device Value* MountFn(const char* name, State* state, int argc, Expr* argv[]) { char* result = NULL; @@ -171,33 +167,14 @@ Value* MountFn(const char* name, State* state, int argc, Expr* argv[]) { } } - if (strcmp(partition_type, "MTD") == 0) { - mtd_scan_partitions(); - const MtdPartition* mtd; - mtd = mtd_find_partition_by_name(location); - if (mtd == NULL) { - uiPrintf(state, "%s: no mtd partition named \"%s\"\n", - name, location); - result = strdup(""); - goto done; - } - if (mtd_mount_partition(mtd, mount_point, fs_type, 0 /* rw */) != 0) { - uiPrintf(state, "mtd mount of %s failed: %s\n", - location, strerror(errno)); - result = strdup(""); - goto done; - } - result = mount_point; + if (mount(location, mount_point, fs_type, + MS_NOATIME | MS_NODEV | MS_NODIRATIME, + has_mount_options ? mount_options : "") < 0) { + uiPrintf(state, "%s: failed to mount %s at %s: %s\n", + name, location, mount_point, strerror(errno)); + result = strdup(""); } else { - if (mount(location, mount_point, fs_type, - MS_NOATIME | MS_NODEV | MS_NODIRATIME, - has_mount_options ? mount_options : "") < 0) { - uiPrintf(state, "%s: failed to mount %s at %s: %s\n", - name, location, mount_point, strerror(errno)); - result = strdup(""); - } else { - result = mount_point; - } + result = mount_point; } done: @@ -227,7 +204,7 @@ Value* IsMountedFn(const char* name, State* state, int argc, Expr* argv[]) { scan_mounted_volumes(); { - const MountedVolume* vol = find_mounted_volume_by_mount_point(mount_point); + MountedVolume* vol = find_mounted_volume_by_mount_point(mount_point); if (vol == NULL) { result = strdup(""); } else { @@ -257,7 +234,7 @@ Value* UnmountFn(const char* name, State* state, int argc, Expr* argv[]) { scan_mounted_volumes(); { - const MountedVolume* vol = find_mounted_volume_by_mount_point(mount_point); + MountedVolume* vol = find_mounted_volume_by_mount_point(mount_point); if (vol == NULL) { uiPrintf(state, "unmount of %s failed; no such volume\n", mount_point); result = strdup(""); @@ -293,7 +270,6 @@ static int exec_cmd(const char* path, char* const argv[]) { // format(fs_type, partition_type, location, fs_size, mount_point) // -// fs_type="yaffs2" partition_type="MTD" location=partition fs_size=<bytes> mount_point=<location> // fs_type="ext4" partition_type="EMMC" location=device fs_size=<bytes> mount_point=<location> // fs_type="f2fs" partition_type="EMMC" location=device fs_size=<bytes> mount_point=<location> // if fs_size == 0, then make fs uses the entire partition. @@ -334,35 +310,7 @@ Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) { goto done; } - if (strcmp(partition_type, "MTD") == 0) { - mtd_scan_partitions(); - const MtdPartition* mtd = mtd_find_partition_by_name(location); - if (mtd == NULL) { - printf("%s: no mtd partition named \"%s\"", - name, location); - result = strdup(""); - goto done; - } - MtdWriteContext* ctx = mtd_write_partition(mtd); - if (ctx == NULL) { - printf("%s: can't write \"%s\"", name, location); - result = strdup(""); - goto done; - } - if (mtd_erase_blocks(ctx, -1) == -1) { - mtd_write_close(ctx); - printf("%s: failed to erase \"%s\"", name, location); - result = strdup(""); - goto done; - } - if (mtd_write_close(ctx) != 0) { - printf("%s: failed to close \"%s\"", name, location); - result = strdup(""); - goto done; - } - result = location; -#ifdef USE_EXT4 - } else if (strcmp(fs_type, "ext4") == 0) { + if (strcmp(fs_type, "ext4") == 0) { int status = make_ext4fs(location, atoll(fs_size), mount_point, sehandle); if (status != 0) { printf("%s: make_ext4fs failed (%d) on %s", @@ -389,7 +337,6 @@ Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) { goto done; } result = location; -#endif } else { printf("%s: unsupported fs_type \"%s\" partition_type \"%s\"", name, fs_type, partition_type); @@ -561,7 +508,7 @@ Value* PackageExtractFileFn(const char* name, State* state, } { - int fd = TEMP_FAILURE_RETRY(ota_open(dest_path, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, + int fd = TEMP_FAILURE_RETRY(ota_open(dest_path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)); if (fd == -1) { printf("%s: can't open %s for write: %s\n", name, dest_path, strerror(errno)); @@ -604,8 +551,8 @@ Value* PackageExtractFileFn(const char* name, State* state, v->size = mzGetZipEntryUncompLen(entry); v->data = reinterpret_cast<char*>(malloc(v->size)); if (v->data == NULL) { - printf("%s: failed to allocate %ld bytes for %s\n", - name, (long)v->size, zip_path); + printf("%s: failed to allocate %zd bytes for %s\n", + name, v->size, zip_path); goto done1; } @@ -998,13 +945,13 @@ Value* FileGetPropFn(const char* name, State* state, int argc, Expr* argv[]) { buffer = reinterpret_cast<char*>(malloc(st.st_size+1)); if (buffer == NULL) { - ErrorAbort(state, kFileGetPropFailure, "%s: failed to alloc %lld bytes", name, - (long long)st.st_size+1); + ErrorAbort(state, kFileGetPropFailure, "%s: failed to alloc %zu bytes", name, + static_cast<size_t>(st.st_size+1)); goto done; } FILE* f; - f = fopen(filename, "rb"); + f = ota_fopen(filename, "rb"); if (f == NULL) { ErrorAbort(state, kFileOpenFailure, "%s: failed to open %s: %s", name, filename, strerror(errno)); @@ -1012,14 +959,14 @@ Value* FileGetPropFn(const char* name, State* state, int argc, Expr* argv[]) { } if (ota_fread(buffer, 1, st.st_size, f) != static_cast<size_t>(st.st_size)) { - ErrorAbort(state, kFreadFailure, "%s: failed to read %lld bytes from %s", - name, (long long)st.st_size+1, filename); - fclose(f); + ErrorAbort(state, kFreadFailure, "%s: failed to read %zu bytes from %s", + name, static_cast<size_t>(st.st_size), filename); + ota_fclose(f); goto done; } buffer[st.st_size] = '\0'; - fclose(f); + ota_fclose(f); char* line; line = strtok(buffer, "\n"); @@ -1066,98 +1013,6 @@ Value* FileGetPropFn(const char* name, State* state, int argc, Expr* argv[]) { return StringValue(result); } -// write_raw_image(filename_or_blob, partition) -Value* WriteRawImageFn(const char* name, State* state, int argc, Expr* argv[]) { - char* result = NULL; - - Value* partition_value; - Value* contents; - if (ReadValueArgs(state, argv, 2, &contents, &partition_value) < 0) { - return NULL; - } - - char* partition = NULL; - if (partition_value->type != VAL_STRING) { - ErrorAbort(state, kArgsParsingFailure, "partition argument to %s must be string", name); - goto done; - } - partition = partition_value->data; - if (strlen(partition) == 0) { - ErrorAbort(state, kArgsParsingFailure, "partition argument to %s can't be empty", name); - goto done; - } - if (contents->type == VAL_STRING && strlen((char*) contents->data) == 0) { - ErrorAbort(state, kArgsParsingFailure, "file argument to %s can't be empty", name); - goto done; - } - - mtd_scan_partitions(); - const MtdPartition* mtd; - mtd = mtd_find_partition_by_name(partition); - if (mtd == NULL) { - printf("%s: no mtd partition named \"%s\"\n", name, partition); - result = strdup(""); - goto done; - } - - MtdWriteContext* ctx; - ctx = mtd_write_partition(mtd); - if (ctx == NULL) { - printf("%s: can't write mtd partition \"%s\"\n", - name, partition); - result = strdup(""); - goto done; - } - - bool success; - - if (contents->type == VAL_STRING) { - // we're given a filename as the contents - char* filename = contents->data; - FILE* f = ota_fopen(filename, "rb"); - if (f == NULL) { - printf("%s: can't open %s: %s\n", name, filename, strerror(errno)); - result = strdup(""); - goto done; - } - - success = true; - char* buffer = reinterpret_cast<char*>(malloc(BUFSIZ)); - int read; - while (success && (read = ota_fread(buffer, 1, BUFSIZ, f)) > 0) { - int wrote = mtd_write_data(ctx, buffer, read); - success = success && (wrote == read); - } - free(buffer); - ota_fclose(f); - } else { - // we're given a blob as the contents - ssize_t wrote = mtd_write_data(ctx, contents->data, contents->size); - success = (wrote == contents->size); - } - if (!success) { - printf("mtd_write_data to %s failed: %s\n", - partition, strerror(errno)); - } - - if (mtd_erase_blocks(ctx, -1) == -1) { - printf("%s: error erasing blocks of %s\n", name, partition); - } - if (mtd_write_close(ctx) != 0) { - printf("%s: error closing write of %s\n", name, partition); - } - - printf("%s %s partition\n", - success ? "wrote" : "failed to write", partition); - - result = success ? partition : strdup(""); - -done: - if (result != partition) FreeValue(partition_value); - FreeValue(contents); - return StringValue(result); -} - // apply_patch_space(bytes) Value* ApplyPatchSpaceFn(const char* name, State* state, int argc, Expr* argv[]) { @@ -1450,10 +1305,10 @@ Value* RebootNowFn(const char* name, State* state, int argc, Expr* argv[]) { // zero out the 'command' field of the bootloader message. memset(buffer, 0, sizeof(((struct bootloader_message*)0)->command)); - FILE* f = fopen(filename, "r+b"); + FILE* f = ota_fopen(filename, "r+b"); fseek(f, offsetof(struct bootloader_message, command), SEEK_SET); ota_fwrite(buffer, sizeof(((struct bootloader_message*)0)->command), 1, f); - fclose(f); + ota_fclose(f); free(filename); strcpy(buffer, "reboot,"); @@ -1492,7 +1347,7 @@ Value* SetStageFn(const char* name, State* state, int argc, Expr* argv[]) { // bootloader message that the main recovery uses to save its // arguments in case of the device restarting midway through // package installation. - FILE* f = fopen(filename, "r+b"); + FILE* f = ota_fopen(filename, "r+b"); fseek(f, offsetof(struct bootloader_message, stage), SEEK_SET); int to_write = strlen(stagestr)+1; int max_size = sizeof(((struct bootloader_message*)0)->stage); @@ -1501,7 +1356,7 @@ Value* SetStageFn(const char* name, State* state, int argc, Expr* argv[]) { stagestr[max_size-1] = 0; } ota_fwrite(stagestr, to_write, 1, f); - fclose(f); + ota_fclose(f); free(stagestr); return StringValue(filename); @@ -1518,10 +1373,10 @@ Value* GetStageFn(const char* name, State* state, int argc, Expr* argv[]) { if (ReadArgs(state, argv, 1, &filename) < 0) return NULL; char buffer[sizeof(((struct bootloader_message*)0)->stage)]; - FILE* f = fopen(filename, "rb"); + FILE* f = ota_fopen(filename, "rb"); fseek(f, offsetof(struct bootloader_message, stage), SEEK_SET); ota_fread(buffer, sizeof(buffer), 1, f); - fclose(f); + ota_fclose(f); buffer[sizeof(buffer)-1] = '\0'; return StringValue(strdup(buffer)); @@ -1616,7 +1471,6 @@ void RegisterInstallFunctions() { RegisterFunction("getprop", GetPropFn); RegisterFunction("file_getprop", FileGetPropFn); - RegisterFunction("write_raw_image", WriteRawImageFn); RegisterFunction("apply_patch", ApplyPatchFn); RegisterFunction("apply_patch_check", ApplyPatchCheckFn); diff --git a/updater/install.h b/updater/install.h index 70e343404..b3b8a4dd5 100644 --- a/updater/install.h +++ b/updater/install.h @@ -20,8 +20,8 @@ void RegisterInstallFunctions(); // uiPrintf function prints msg to screen as well as logs -void uiPrintf(State* state, const char* format, ...); +void uiPrintf(State* _Nonnull state, const char* _Nonnull format, ...) __attribute__((__format__(printf, 2, 3))); -static int make_parents(char* name); +static int make_parents(char* _Nonnull name); #endif diff --git a/updater/updater.cpp b/updater/updater.cpp index e956dd557..c222cee0d 100644 --- a/updater/updater.cpp +++ b/updater/updater.cpp @@ -27,6 +27,9 @@ #include "minzip/SysUtil.h" #include "config.h" +#include <selinux/label.h> +#include <selinux/selinux.h> + // Generated by the makefile, this function defines the // RegisterDeviceExtensions() function, which calls all the // registration functions for device-specific extensions. diff --git a/updater/updater.h b/updater/updater.h index d1dfdd05e..d3a09b93d 100644 --- a/updater/updater.h +++ b/updater/updater.h @@ -20,9 +20,6 @@ #include <stdio.h> #include "minzip/Zip.h" -#include <selinux/selinux.h> -#include <selinux/label.h> - typedef struct { FILE* cmd_pipe; ZipArchive* package_zip; @@ -32,6 +29,7 @@ typedef struct { size_t package_zip_len; } UpdaterInfo; +struct selabel_handle; extern struct selabel_handle *sehandle; #endif |