1.1 --- a/librazor/rpm.c Wed Oct 22 12:09:47 2014 +0100
1.2 +++ b/librazor/rpm.c Mon Jul 04 10:48:18 2016 +0100
1.3 @@ -1,7 +1,7 @@
1.4 /*
1.5 * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
1.6 * Copyright (C) 2008 Red Hat, Inc
1.7 - * Copyright (C) 2009, 2011, 2012, 2014 J. Ali Harlow <ali@juiblex.co.uk>
1.8 + * Copyright (C) 2009, 2011, 2012, 2014, 2016 J. Ali Harlow <ali@juiblex.co.uk>
1.9 *
1.10 * This program is free software; you can redistribute it and/or modify
1.11 * it under the terms of the GNU General Public License as published by
1.12 @@ -25,13 +25,10 @@
1.13 #include <stdlib.h>
1.14 #include <string.h>
1.15 #include <errno.h>
1.16 -#include <sys/stat.h>
1.17 -#include <sys/types.h>
1.18 #if HAVE_SYS_WAIT_H
1.19 #include <sys/wait.h>
1.20 #endif
1.21 #include <fcntl.h>
1.22 -#include <dirent.h>
1.23 #include <unistd.h>
1.24 #if MSWIN_API
1.25 #include <winsock2.h> /* For ntohl() */
1.26 @@ -620,7 +617,7 @@
1.27 }
1.28
1.29 RAZOR_EXPORT struct razor_rpm *
1.30 -razor_rpm_open(const char *filename, struct razor_error **error)
1.31 +razor_rpm_open(const char *uri, struct razor_error **error)
1.32 {
1.33 struct rpm_lead *lead;
1.34 struct razor_rpm *rpm;
1.35 @@ -628,7 +625,7 @@
1.36 unsigned int count, i, nindex, hsize;
1.37 const char *name, *prefix;
1.38
1.39 - assert (filename != NULL);
1.40 + assert (uri != NULL);
1.41
1.42 rpm = zalloc(sizeof *rpm);
1.43 if (rpm == NULL) {
1.44 @@ -638,7 +635,7 @@
1.45 }
1.46 memset(rpm, 0, sizeof *rpm);
1.47
1.48 - rpm->map = razor_file_get_contents(filename, &rpm->size, 0, error);
1.49 + rpm->map = razor_uri_get_contents(uri, &rpm->size, 0, error);
1.50 if (!rpm->map) {
1.51 free(rpm);
1.52 return NULL;
1.53 @@ -646,11 +643,11 @@
1.54
1.55 lead = rpm->map;
1.56 if (rpm->size < RPM_LEAD_SIZE ||
1.57 - strncmp(lead->magic,RPM_LEAD_MAGIC,4) || lead->major != 3) {
1.58 + strncmp((char *)lead->magic,RPM_LEAD_MAGIC,4) || lead->major != 3) {
1.59 razor_rpm_close(rpm);
1.60 razor_set_error(error, RAZOR_GENERAL_ERROR,
1.61 RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED,
1.62 - filename, "Not a recognized RPM format file");
1.63 + uri, "Not a recognized RPM format file");
1.64 return NULL;
1.65 }
1.66
1.67 @@ -682,8 +679,7 @@
1.68 razor_rpm_close(rpm);
1.69 razor_set_error(error, RAZOR_GENERAL_ERROR,
1.70 RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED,
1.71 - filename,
1.72 - "Old filenames not supported");
1.73 + uri, "Old filenames not supported");
1.74 return NULL;
1.75 }
1.76 }
1.77 @@ -704,8 +700,7 @@
1.78 razor_rpm_close(rpm);
1.79 razor_set_error(error, RAZOR_GENERAL_ERROR,
1.80 RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED,
1.81 - filename,
1.82 - "Default prefix not supported");
1.83 + uri, "Default prefix not supported");
1.84 return NULL;
1.85 }
1.86 }
1.87 @@ -748,7 +743,7 @@
1.88 #define RESERVED 0xE0 /* bits 5..7: reserved */
1.89
1.90 struct installer {
1.91 - const char *root;
1.92 + const char *root_uri;
1.93 struct razor_rpm *rpm;
1.94 struct razor_atomic *atomic;
1.95 z_stream stream;
1.96 @@ -808,13 +803,47 @@
1.97 static int
1.98 create_path(struct installer *installer, const char *path, unsigned int mode)
1.99 {
1.100 - char *s, *buffer;
1.101 - int h, ret;
1.102 + const char *s, *relative;
1.103 + char *uri, *buffer;
1.104 + int h, ret, is_within_root;
1.105 + struct razor_error *tmp_error = NULL;
1.106
1.107 - if (razor_atomic_make_dirs(installer->atomic, installer->root, path))
1.108 + uri = razor_path_to_uri(path);
1.109 +
1.110 + if (str_has_prefix(uri, "file:///"))
1.111 + relative = uri + 8;
1.112 + else if (str_has_prefix(uri, "file:/"))
1.113 + relative = uri + 6;
1.114 + else if (str_has_prefix(uri, "file:"))
1.115 + relative = uri + 5;
1.116 + else if (str_has_prefix(uri, "/"))
1.117 + relative = uri + 1;
1.118 + else
1.119 + relative = uri;
1.120 +
1.121 + buffer = razor_resolve_uri_root(installer->root_uri, relative, 1,
1.122 + &tmp_error);
1.123 +
1.124 + if (!buffer) {
1.125 + razor_atomic_propagate_error(installer->atomic, tmp_error,
1.126 + NULL);
1.127 + free(uri);
1.128 return -1;
1.129 + }
1.130
1.131 - buffer = razor_concat(installer->root, path, NULL);
1.132 + is_within_root = installer->root_uri &&
1.133 + str_has_prefix(buffer, installer->root_uri);
1.134 +
1.135 + if (is_within_root)
1.136 + ret = razor_atomic_make_dirs(installer->atomic,
1.137 + installer->root_uri, relative);
1.138 + else
1.139 + ret = razor_atomic_make_dirs(installer->atomic, "", buffer);
1.140 +
1.141 + free(uri);
1.142 +
1.143 + if (ret)
1.144 + return ret;
1.145
1.146 switch (mode >> 12) {
1.147 case REG:
1.148 @@ -831,7 +860,8 @@
1.149 installer->length))
1.150 return -1;
1.151 }
1.152 - return razor_atomic_close(installer->atomic, h);
1.153 + ret = razor_atomic_close(installer->atomic, h);
1.154 + break;
1.155 case XDIR:
1.156 ret = razor_atomic_create_dir(installer->atomic, buffer, mode);
1.157 free(buffer);
1.158 @@ -842,16 +872,17 @@
1.159 return -1;
1.160 if (installer->length >= sizeof installer->buffer) {
1.161 razor_atomic_abort(installer->atomic,
1.162 - RAZOR_GENERAL_ERROR,
1.163 - RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED,
1.164 - "Link target too long");
1.165 + RAZOR_GENERAL_ERROR,
1.166 + RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED,
1.167 + "Link target too long");
1.168 return -1;
1.169 }
1.170 installer->buffer[installer->length] = '\0';
1.171 ret = razor_atomic_create_symlink(installer->atomic,
1.172 - (const char *)installer->buffer, buffer);
1.173 + (const char *)installer->buffer,
1.174 + buffer);
1.175 free(buffer);
1.176 - return ret;
1.177 + break;
1.178 #else
1.179 s = "Symbolic links";
1.180 goto unsupported;
1.181 @@ -861,9 +892,9 @@
1.182 unsupported:
1.183 free(buffer);
1.184 buffer = razor_concat(s, " are not supported on this platform",
1.185 - NULL);
1.186 + NULL);
1.187 razor_atomic_abort(installer->atomic, RAZOR_GENERAL_ERROR,
1.188 - RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED, buffer);
1.189 + RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED, buffer);
1.190 free(buffer);
1.191 return -1;
1.192 case CDEV:
1.193 @@ -878,9 +909,12 @@
1.194 default:
1.195 free(buffer);
1.196 razor_atomic_abort(installer->atomic, RAZOR_GENERAL_ERROR,
1.197 - RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED, "Unknown file type");
1.198 + RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED,
1.199 + "Unknown file type");
1.200 return -1;
1.201 }
1.202 +
1.203 + return ret;
1.204 }
1.205
1.206 static int chroot_push(const char *root)
1.207 @@ -912,12 +946,14 @@
1.208 }
1.209
1.210 static int
1.211 -run_script_lua(const char *root, unsigned int script_tag, const char *script,
1.212 - int arg1)
1.213 +run_script_lua(const char *root_uri, unsigned int script_tag,
1.214 + const char *script, int arg1, struct razor_error **error)
1.215 {
1.216 int root_fd, retval;
1.217 + const char *name;
1.218 #if HAVE_LUA
1.219 - const char *name;
1.220 + char *root;
1.221 +#endif
1.222
1.223 switch(script_tag) {
1.224 case RPMTAG_PREIN:
1.225 @@ -936,12 +972,19 @@
1.226 name = "script";
1.227 break;
1.228 }
1.229 - root_fd = chroot_push(root);
1.230 +
1.231 +#if HAVE_LUA
1.232 + root = razor_path_from_uri(root_uri, error);
1.233 + if (!root)
1.234 + return -1;
1.235 + root_fd = root ? chroot_push(root) : -1;
1.236 retval = run_lua_script(root_fd < 0 ? root : NULL, name, script, -1,
1.237 arg1);
1.238 + free(root);
1.239 chroot_pop(root_fd);
1.240 #else /* HAVE_LUA */
1.241 - fprintf(stderr, "lua not available to run script\n");
1.242 + razor_set_error(error, RAZOR_GENERAL_ERROR, RAZOR_GENERAL_ERROR_FAILED,
1.243 + name, "lua not available to run script");
1.244 retval = -1;
1.245 #endif /* HAVE_LUA */
1.246
1.247 @@ -949,12 +992,12 @@
1.248 }
1.249
1.250 static int
1.251 -run_script_external(const char *root, const char *program, const char *script,
1.252 - int arg1)
1.253 +run_script_external(const char *root_uri, const char *program,
1.254 + const char *script, int arg1, struct razor_error **error)
1.255 {
1.256 int root_fd, retval;
1.257 FILE *fp;
1.258 - char buf[32], *command;
1.259 + char buf[32], *command, *root;
1.260
1.261 if (program == NULL) {
1.262 #if MSWIN_API
1.263 @@ -971,7 +1014,11 @@
1.264 #endif
1.265 }
1.266
1.267 + root = razor_path_from_uri(root_uri, error);
1.268 + if (!root)
1.269 + return -1;
1.270 root_fd = chroot_push(root);
1.271 + free(root);
1.272 if (arg1 >= 0) {
1.273 sprintf(buf, "%d", arg1);
1.274 command = malloc(strlen(program) + strlen(buf) + 2);
1.275 @@ -982,10 +1029,11 @@
1.276 free(command);
1.277
1.278 if (!fp) {
1.279 - perror(program);
1.280 + razor_set_error_posix(error, program);
1.281 retval = -1;
1.282 } else if (script && fwrite(script, strlen(script), 1, fp) != 1) {
1.283 - perror("failed to write script to program");
1.284 + razor_set_error_posix(error,
1.285 + "failed to write script to program");
1.286 retval = -1;
1.287 } else
1.288 retval = 0;
1.289 @@ -998,8 +1046,8 @@
1.290 }
1.291
1.292 static int
1.293 -run_script(struct installer *installer,
1.294 - unsigned int program_tag, unsigned int script_tag, int arg1)
1.295 +run_script(struct installer *installer, unsigned int program_tag,
1.296 + unsigned int script_tag, int arg1, struct razor_error **error)
1.297 {
1.298 int i, retval;
1.299 struct razor_rpm *rpm = installer->rpm;
1.300 @@ -1024,11 +1072,11 @@
1.301 }
1.302
1.303 if (program && strcmp(program, "<lua>") == 0)
1.304 - retval = run_script_lua(installer->root, script_tag, script,
1.305 - arg1);
1.306 + retval = run_script_lua(installer->root_uri, script_tag,
1.307 + script, arg1, error);
1.308 else
1.309 - retval = run_script_external(installer->root, program, script,
1.310 - arg1);
1.311 + retval = run_script_external(installer->root_uri, program,
1.312 + script, arg1, error);
1.313
1.314 if (rpm->relocations) {
1.315 environment_unset(&env);
1.316 @@ -1040,7 +1088,8 @@
1.317
1.318 int
1.319 razor_run_script(const char *root, enum razor_property_flags script,
1.320 - const char *program, const char *body, int arg1)
1.321 + const char *program, const char *body, int arg1,
1.322 + struct razor_error **error)
1.323 {
1.324 int retval;
1.325 unsigned int script_tag;
1.326 @@ -1071,10 +1120,10 @@
1.327 script_tag = 0;
1.328 break;
1.329 }
1.330 - retval = run_script_lua(root, script_tag, body, arg1);
1.331 + retval = run_script_lua(root, script_tag, body, arg1, error);
1.332 }
1.333 else
1.334 - retval = run_script_external(root, program, body, arg1);
1.335 + retval = run_script_external(root, program, body, arg1, error);
1.336
1.337 return retval;
1.338 }
1.339 @@ -1164,30 +1213,38 @@
1.340
1.341 RAZOR_EXPORT int
1.342 razor_rpm_install(struct razor_rpm *rpm, struct razor_atomic *atomic,
1.343 - const char *root, int install_count,
1.344 + const char *root_uri, int install_count,
1.345 enum razor_stage_type stage)
1.346 {
1.347 struct installer installer;
1.348 struct cpio_file_header *header;
1.349 - struct stat buf;
1.350 unsigned int mode;
1.351 const char *path;
1.352 size_t filesize;
1.353 char *s;
1.354 - int retval = 0, code;
1.355 + int retval = 0, domain, code;
1.356 + struct razor_error *tmp_error = NULL;
1.357
1.358 assert (rpm != NULL);
1.359 - assert (root != NULL);
1.360 + assert (root_uri != NULL);
1.361
1.362 installer.rpm = rpm;
1.363 - installer.root = root;
1.364 + installer.root_uri = root_uri;
1.365 installer.atomic = atomic;
1.366
1.367 /* FIXME: Only do this before a transaction, not per rpm. */
1.368 - if (*root && ((retval = stat(root, &buf)) || !S_ISDIR(buf.st_mode))) {
1.369 - code = retval ? errno : ENOTDIR;
1.370 - s = razor_concat(root, ": Directory does not exist", NULL);
1.371 - razor_atomic_abort(atomic, RAZOR_POSIX_ERROR, code, s);
1.372 + if (*root_uri && razor_uri_is_directory(root_uri, &tmp_error) <= 0) {
1.373 + if (tmp_error) {
1.374 + domain = razor_error_get_domain(tmp_error);
1.375 + code = razor_error_get_code(tmp_error);
1.376 + razor_error_free(tmp_error);
1.377 + tmp_error = NULL;
1.378 + } else {
1.379 + domain = RAZOR_POSIX_ERROR;
1.380 + code = ENOTDIR;
1.381 + }
1.382 + s = razor_concat(root_uri, ": Directory does not exist", NULL);
1.383 + razor_atomic_abort(atomic, domain, code, s);
1.384 free(s);
1.385 return -1;
1.386 }
1.387 @@ -1195,9 +1252,14 @@
1.388 if (rpm->relocations)
1.389 razor_relocations_set_rpm(rpm->relocations, rpm);
1.390
1.391 - if (stage & RAZOR_STAGE_SCRIPTS_PRE)
1.392 + if (stage & RAZOR_STAGE_SCRIPTS_PRE) {
1.393 retval = run_script(&installer, RPMTAG_PREINPROG, RPMTAG_PREIN,
1.394 - install_count);
1.395 + install_count, &tmp_error);
1.396 + if (retval) {
1.397 + razor_atomic_propagate_error(atomic, tmp_error, NULL);
1.398 + tmp_error = NULL;
1.399 + }
1.400 + }
1.401
1.402 if (!retval && (stage & RAZOR_STAGE_FILES)) {
1.403 if (installer_init(&installer))
1.404 @@ -1244,9 +1306,14 @@
1.405 retval = razor_atomic_in_error_state(atomic);
1.406 }
1.407
1.408 - if (!retval && (stage & RAZOR_STAGE_SCRIPTS_POST))
1.409 + if (!retval && (stage & RAZOR_STAGE_SCRIPTS_POST)) {
1.410 retval = run_script(&installer, RPMTAG_POSTINPROG,
1.411 - RPMTAG_POSTIN, install_count);
1.412 + RPMTAG_POSTIN, install_count, &tmp_error);
1.413 + if (retval) {
1.414 + razor_atomic_propagate_error(atomic, tmp_error, NULL);
1.415 + tmp_error = NULL;
1.416 + }
1.417 + }
1.418
1.419 return retval;
1.420 }
1.421 @@ -1260,7 +1327,7 @@
1.422
1.423 free(rpm->dirs);
1.424 free(rpm->prefixes);
1.425 - err = razor_file_free_contents(rpm->map, rpm->size);
1.426 + err = razor_uri_free_contents(rpm->map, rpm->size);
1.427 free(rpm->evr);
1.428 free(rpm);
1.429