diff -r b8638c3c7eee -r 6ba4c0f3c9d1 librazor/rpm.c --- a/librazor/rpm.c Wed Oct 22 12:09:47 2014 +0100 +++ b/librazor/rpm.c Tue Jul 05 09:40:01 2016 +0100 @@ -1,7 +1,7 @@ /* * Copyright (C) 2008 Kristian Høgsberg * Copyright (C) 2008 Red Hat, Inc - * Copyright (C) 2009, 2011, 2012, 2014 J. Ali Harlow + * Copyright (C) 2009, 2011, 2012, 2014, 2016 J. Ali Harlow * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,13 +25,10 @@ #include #include #include -#include -#include #if HAVE_SYS_WAIT_H #include #endif #include -#include #include #if MSWIN_API #include /* For ntohl() */ @@ -620,7 +617,7 @@ } RAZOR_EXPORT struct razor_rpm * -razor_rpm_open(const char *filename, struct razor_error **error) +razor_rpm_open(const char *uri, struct razor_error **error) { struct rpm_lead *lead; struct razor_rpm *rpm; @@ -628,7 +625,7 @@ unsigned int count, i, nindex, hsize; const char *name, *prefix; - assert (filename != NULL); + assert (uri != NULL); rpm = zalloc(sizeof *rpm); if (rpm == NULL) { @@ -638,7 +635,7 @@ } memset(rpm, 0, sizeof *rpm); - rpm->map = razor_file_get_contents(filename, &rpm->size, 0, error); + rpm->map = razor_uri_get_contents(uri, &rpm->size, 0, error); if (!rpm->map) { free(rpm); return NULL; @@ -646,11 +643,11 @@ lead = rpm->map; if (rpm->size < RPM_LEAD_SIZE || - strncmp(lead->magic,RPM_LEAD_MAGIC,4) || lead->major != 3) { + strncmp((char *)lead->magic,RPM_LEAD_MAGIC,4) || lead->major != 3) { razor_rpm_close(rpm); razor_set_error(error, RAZOR_GENERAL_ERROR, RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED, - filename, "Not a recognized RPM format file"); + uri, "Not a recognized RPM format file"); return NULL; } @@ -682,8 +679,7 @@ razor_rpm_close(rpm); razor_set_error(error, RAZOR_GENERAL_ERROR, RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED, - filename, - "Old filenames not supported"); + uri, "Old filenames not supported"); return NULL; } } @@ -704,8 +700,7 @@ razor_rpm_close(rpm); razor_set_error(error, RAZOR_GENERAL_ERROR, RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED, - filename, - "Default prefix not supported"); + uri, "Default prefix not supported"); return NULL; } } @@ -748,7 +743,7 @@ #define RESERVED 0xE0 /* bits 5..7: reserved */ struct installer { - const char *root; + const char *root_uri; struct razor_rpm *rpm; struct razor_atomic *atomic; z_stream stream; @@ -808,13 +803,47 @@ static int create_path(struct installer *installer, const char *path, unsigned int mode) { - char *s, *buffer; - int h, ret; + const char *s, *relative; + char *uri, *buffer; + int h, ret, is_within_root; + struct razor_error *tmp_error = NULL; - if (razor_atomic_make_dirs(installer->atomic, installer->root, path)) + uri = razor_path_to_uri(path); + + if (str_has_prefix(uri, "file:///")) + relative = uri + 8; + else if (str_has_prefix(uri, "file:/")) + relative = uri + 6; + else if (str_has_prefix(uri, "file:")) + relative = uri + 5; + else if (str_has_prefix(uri, "/")) + relative = uri + 1; + else + relative = uri; + + buffer = razor_resolve_uri_root(installer->root_uri, relative, 1, + &tmp_error); + + if (!buffer) { + razor_atomic_propagate_error(installer->atomic, tmp_error, + NULL); + free(uri); return -1; + } - buffer = razor_concat(installer->root, path, NULL); + is_within_root = installer->root_uri && + str_has_prefix(buffer, installer->root_uri); + + if (is_within_root) + ret = razor_atomic_make_dirs(installer->atomic, + installer->root_uri, relative); + else + ret = razor_atomic_make_dirs(installer->atomic, "", buffer); + + free(uri); + + if (ret) + return ret; switch (mode >> 12) { case REG: @@ -831,7 +860,8 @@ installer->length)) return -1; } - return razor_atomic_close(installer->atomic, h); + ret = razor_atomic_close(installer->atomic, h); + break; case XDIR: ret = razor_atomic_create_dir(installer->atomic, buffer, mode); free(buffer); @@ -842,16 +872,17 @@ return -1; if (installer->length >= sizeof installer->buffer) { razor_atomic_abort(installer->atomic, - RAZOR_GENERAL_ERROR, - RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED, - "Link target too long"); + RAZOR_GENERAL_ERROR, + RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED, + "Link target too long"); return -1; } installer->buffer[installer->length] = '\0'; ret = razor_atomic_create_symlink(installer->atomic, - (const char *)installer->buffer, buffer); + (const char *)installer->buffer, + buffer); free(buffer); - return ret; + break; #else s = "Symbolic links"; goto unsupported; @@ -861,9 +892,9 @@ unsupported: free(buffer); buffer = razor_concat(s, " are not supported on this platform", - NULL); + NULL); razor_atomic_abort(installer->atomic, RAZOR_GENERAL_ERROR, - RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED, buffer); + RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED, buffer); free(buffer); return -1; case CDEV: @@ -878,9 +909,12 @@ default: free(buffer); razor_atomic_abort(installer->atomic, RAZOR_GENERAL_ERROR, - RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED, "Unknown file type"); + RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED, + "Unknown file type"); return -1; } + + return ret; } static int chroot_push(const char *root) @@ -912,12 +946,14 @@ } static int -run_script_lua(const char *root, unsigned int script_tag, const char *script, - int arg1) +run_script_lua(const char *root_uri, unsigned int script_tag, + const char *script, int arg1, struct razor_error **error) { int root_fd, retval; + const char *name; #if HAVE_LUA - const char *name; + char *root; +#endif switch(script_tag) { case RPMTAG_PREIN: @@ -936,12 +972,19 @@ name = "script"; break; } - root_fd = chroot_push(root); + +#if HAVE_LUA + root = razor_path_from_uri(root_uri, error); + if (!root) + return -1; + root_fd = root ? chroot_push(root) : -1; retval = run_lua_script(root_fd < 0 ? root : NULL, name, script, -1, arg1); + free(root); chroot_pop(root_fd); #else /* HAVE_LUA */ - fprintf(stderr, "lua not available to run script\n"); + razor_set_error(error, RAZOR_GENERAL_ERROR, RAZOR_GENERAL_ERROR_FAILED, + name, "lua not available to run script"); retval = -1; #endif /* HAVE_LUA */ @@ -949,12 +992,12 @@ } static int -run_script_external(const char *root, const char *program, const char *script, - int arg1) +run_script_external(const char *root_uri, const char *program, + const char *script, int arg1, struct razor_error **error) { int root_fd, retval; FILE *fp; - char buf[32], *command; + char buf[32], *command, *root; if (program == NULL) { #if MSWIN_API @@ -971,7 +1014,11 @@ #endif } + root = razor_path_from_uri(root_uri, error); + if (!root) + return -1; root_fd = chroot_push(root); + free(root); if (arg1 >= 0) { sprintf(buf, "%d", arg1); command = malloc(strlen(program) + strlen(buf) + 2); @@ -982,10 +1029,11 @@ free(command); if (!fp) { - perror(program); + razor_set_error_posix(error, program); retval = -1; } else if (script && fwrite(script, strlen(script), 1, fp) != 1) { - perror("failed to write script to program"); + razor_set_error_posix(error, + "failed to write script to program"); retval = -1; } else retval = 0; @@ -998,8 +1046,8 @@ } static int -run_script(struct installer *installer, - unsigned int program_tag, unsigned int script_tag, int arg1) +run_script(struct installer *installer, unsigned int program_tag, + unsigned int script_tag, int arg1, struct razor_error **error) { int i, retval; struct razor_rpm *rpm = installer->rpm; @@ -1024,11 +1072,11 @@ } if (program && strcmp(program, "") == 0) - retval = run_script_lua(installer->root, script_tag, script, - arg1); + retval = run_script_lua(installer->root_uri, script_tag, + script, arg1, error); else - retval = run_script_external(installer->root, program, script, - arg1); + retval = run_script_external(installer->root_uri, program, + script, arg1, error); if (rpm->relocations) { environment_unset(&env); @@ -1040,7 +1088,8 @@ int razor_run_script(const char *root, enum razor_property_flags script, - const char *program, const char *body, int arg1) + const char *program, const char *body, int arg1, + struct razor_error **error) { int retval; unsigned int script_tag; @@ -1071,10 +1120,10 @@ script_tag = 0; break; } - retval = run_script_lua(root, script_tag, body, arg1); + retval = run_script_lua(root, script_tag, body, arg1, error); } else - retval = run_script_external(root, program, body, arg1); + retval = run_script_external(root, program, body, arg1, error); return retval; } @@ -1164,30 +1213,38 @@ RAZOR_EXPORT int razor_rpm_install(struct razor_rpm *rpm, struct razor_atomic *atomic, - const char *root, int install_count, + const char *root_uri, int install_count, enum razor_stage_type stage) { struct installer installer; struct cpio_file_header *header; - struct stat buf; unsigned int mode; const char *path; size_t filesize; char *s; - int retval = 0, code; + int retval = 0, domain, code; + struct razor_error *tmp_error = NULL; assert (rpm != NULL); - assert (root != NULL); + assert (root_uri != NULL); installer.rpm = rpm; - installer.root = root; + installer.root_uri = root_uri; installer.atomic = atomic; /* FIXME: Only do this before a transaction, not per rpm. */ - if (*root && ((retval = stat(root, &buf)) || !S_ISDIR(buf.st_mode))) { - code = retval ? errno : ENOTDIR; - s = razor_concat(root, ": Directory does not exist", NULL); - razor_atomic_abort(atomic, RAZOR_POSIX_ERROR, code, s); + if (*root_uri && razor_uri_is_directory(root_uri, &tmp_error) <= 0) { + if (tmp_error) { + domain = razor_error_get_domain(tmp_error); + code = razor_error_get_code(tmp_error); + razor_error_free(tmp_error); + tmp_error = NULL; + } else { + domain = RAZOR_POSIX_ERROR; + code = ENOTDIR; + } + s = razor_concat(root_uri, ": Directory does not exist", NULL); + razor_atomic_abort(atomic, domain, code, s); free(s); return -1; } @@ -1195,9 +1252,14 @@ if (rpm->relocations) razor_relocations_set_rpm(rpm->relocations, rpm); - if (stage & RAZOR_STAGE_SCRIPTS_PRE) + if (stage & RAZOR_STAGE_SCRIPTS_PRE) { retval = run_script(&installer, RPMTAG_PREINPROG, RPMTAG_PREIN, - install_count); + install_count, &tmp_error); + if (retval) { + razor_atomic_propagate_error(atomic, tmp_error, NULL); + tmp_error = NULL; + } + } if (!retval && (stage & RAZOR_STAGE_FILES)) { if (installer_init(&installer)) @@ -1244,9 +1306,14 @@ retval = razor_atomic_in_error_state(atomic); } - if (!retval && (stage & RAZOR_STAGE_SCRIPTS_POST)) + if (!retval && (stage & RAZOR_STAGE_SCRIPTS_POST)) { retval = run_script(&installer, RPMTAG_POSTINPROG, - RPMTAG_POSTIN, install_count); + RPMTAG_POSTIN, install_count, &tmp_error); + if (retval) { + razor_atomic_propagate_error(atomic, tmp_error, NULL); + tmp_error = NULL; + } + } return retval; } @@ -1260,7 +1327,7 @@ free(rpm->dirs); free(rpm->prefixes); - err = razor_file_free_contents(rpm->map, rpm->size); + err = razor_uri_free_contents(rpm->map, rpm->size); free(rpm->evr); free(rpm);