1.1 --- a/librazor/root.c Tue Sep 09 15:27:12 2014 +0100
1.2 +++ b/librazor/root.c Mon Jul 11 16:12:45 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,7 +25,6 @@
1.13 #include <stdio.h>
1.14 #include <string.h>
1.15 #include <errno.h>
1.16 -#include <sys/stat.h>
1.17 #include <dirent.h>
1.18 #include <unistd.h>
1.19 #include <fcntl.h>
1.20 @@ -59,102 +58,130 @@
1.21 */
1.22 static const char system_lock_filename[] = "system-next.rzdb";
1.23 #ifdef MSWIN_API
1.24 -#define RAZOR_DATABASE_PATH NULL
1.25 +#define RAZOR_DATABASE_URI NULL
1.26 #else
1.27 -#define RAZOR_DATABASE_PATH "/var/lib/razor"
1.28 +/*
1.29 + * The non-MSWIN default is a relative-ref and thus affected by the root
1.30 + */
1.31 +#define RAZOR_DATABASE_URI "var/lib/razor"
1.32 #endif
1.33 -static char *razor_database_path = RAZOR_DATABASE_PATH;
1.34 -static int razor_database_path_alloced = FALSE;
1.35 +static char *razor_database_uri = RAZOR_DATABASE_URI;
1.36 +static int razor_database_uri_alloced = FALSE;
1.37
1.38 struct razor_root {
1.39 struct razor_set *system;
1.40 - char *path;
1.41 + char *uri;
1.42 };
1.43
1.44 static void
1.45 razor_root_init(void)
1.46 {
1.47 #ifdef MSWIN_API
1.48 - static char database_path[MAX_PATH];
1.49 - if (!razor_database_path) {
1.50 + /*
1.51 + * The MSWIN default is an absolute-URI and thus unaffected by the root
1.52 + */
1.53 + char database_path[MAX_PATH];
1.54 + if (!razor_database_uri) {
1.55 SHGetFolderPath(NULL,
1.56 CSIDL_COMMON_APPDATA | CSIDL_FLAG_DONT_VERIFY, NULL, 0,
1.57 database_path);
1.58 strcat(database_path, "\\Razor");
1.59 - razor_database_path = database_path;
1.60 - razor_database_path_alloced = FALSE;
1.61 + razor_database_uri = razor_path_to_uri(database_path);
1.62 + razor_database_uri_alloced = TRUE;
1.63 }
1.64 #endif
1.65 }
1.66
1.67 -RAZOR_EXPORT const char *
1.68 -razor_get_database_path()
1.69 +RAZOR_EXPORT const char *razor_get_database_uri(void)
1.70 {
1.71 razor_root_init();
1.72 -
1.73 - return razor_database_path;
1.74 + return razor_database_uri;
1.75 }
1.76
1.77 RAZOR_EXPORT void
1.78 -razor_set_database_path(const char *database_path)
1.79 +razor_set_database_uri(const char *database_uri)
1.80 {
1.81 - if (razor_database_path_alloced)
1.82 - free(razor_database_path);
1.83 + if (razor_database_uri_alloced)
1.84 + free(razor_database_uri);
1.85
1.86 - if (database_path) {
1.87 - razor_database_path = strdup(database_path);
1.88 - razor_database_path_alloced = TRUE;
1.89 + if (database_uri) {
1.90 + razor_database_uri = strdup(database_uri);
1.91 + razor_database_uri_alloced = TRUE;
1.92 } else {
1.93 - razor_database_path = RAZOR_DATABASE_PATH;
1.94 - razor_database_path_alloced = FALSE;
1.95 + razor_database_uri = RAZOR_DATABASE_URI;
1.96 + razor_database_uri_alloced = FALSE;
1.97 }
1.98 }
1.99
1.100 +char *razor_resolve_database_file(const char *root_uri, const char *filename,
1.101 + struct razor_error **error)
1.102 +{
1.103 + char *s, *uri;
1.104 +
1.105 + razor_root_init();
1.106 +
1.107 + s = razor_concat(razor_database_uri, "/", filename, NULL);
1.108 +
1.109 + uri = razor_resolve_uri_root(root_uri, s, -1, error);
1.110 +
1.111 + free(s);
1.112 +
1.113 + return uri;
1.114 +}
1.115 +
1.116 RAZOR_EXPORT int
1.117 -razor_root_create(const char *root, struct razor_error **error)
1.118 +razor_root_create(const char *root_uri, struct razor_error **error)
1.119 {
1.120 - int retval;
1.121 - struct stat buf;
1.122 + int retval, is_within_root, is_directory;
1.123 struct razor_set *set;
1.124 struct razor_atomic *atomic;
1.125 - char *file, *path;
1.126 + struct razor_error *tmp_err = NULL;
1.127 + char *uri;
1.128
1.129 - assert (root != NULL);
1.130 + uri = razor_resolve_database_file(root_uri, system_repo_filename,
1.131 + error);
1.132
1.133 - razor_root_init();
1.134 - if (root[0] == '\0') {
1.135 - /* root is file system root */
1.136 - } else if (stat(root, &buf) < 0) {
1.137 - if (mkdir(root, 0777) < 0) {
1.138 - razor_set_error(error, RAZOR_POSIX_ERROR, errno, root,
1.139 + if (!uri)
1.140 + return -1;
1.141 +
1.142 + if (razor_uri_is_directory(uri, NULL) >= 0) {
1.143 + razor_set_error(error, RAZOR_GENERAL_ERROR,
1.144 + RAZOR_GENERAL_ERROR_DATABASE_EXISTS, NULL,
1.145 + "A razor install root is already initialized");
1.146 + free(uri);
1.147 + return -1;
1.148 + }
1.149 +
1.150 + is_within_root = root_uri && strchr(root_uri, '/') &&
1.151 + str_has_prefix(uri, root_uri);
1.152 +
1.153 + atomic = razor_atomic_open("Create initial package set");
1.154 +
1.155 + if (is_within_root) {
1.156 + is_directory = razor_uri_is_directory(root_uri, NULL);
1.157 +
1.158 + if (!is_directory) {
1.159 + razor_set_error(error, RAZOR_POSIX_ERROR, ENOTDIR,
1.160 + root_uri, "Not a directory");
1.161 + return -1;
1.162 + } else if (is_directory < 0 &&
1.163 + razor_uri_mkdir(root_uri, 0777, &tmp_err) < 0) {
1.164 + razor_set_error(error,
1.165 + razor_error_get_domain(tmp_err),
1.166 + razor_error_get_code(tmp_err),
1.167 + root_uri,
1.168 "Could not create install root");
1.169 return -1;
1.170 }
1.171 - } else if (!S_ISDIR(buf.st_mode)) {
1.172 - razor_set_error(error, RAZOR_POSIX_ERROR, ENOTDIR, root,
1.173 - "Not a directory");
1.174 - return -1;
1.175 - }
1.176
1.177 - file = razor_concat(razor_database_path, "/", system_repo_filename,
1.178 - NULL);
1.179 - path = razor_path_add_root(file, root);
1.180 - retval = !stat(path, &buf);
1.181 - if (retval) {
1.182 - razor_set_error(error, RAZOR_GENERAL_ERROR,
1.183 - RAZOR_GENERAL_ERROR_DATABASE_EXISTS, NULL,
1.184 - "A razor install root is already initialized");
1.185 - free(path);
1.186 - free(file);
1.187 - return retval;
1.188 - }
1.189 + razor_atomic_make_dirs(atomic, root_uri,
1.190 + uri + strlen(root_uri));
1.191 + } else
1.192 + razor_atomic_make_dirs(atomic, "", uri);
1.193
1.194 - atomic = razor_atomic_open("Create initial package set");
1.195 - razor_atomic_make_dirs(atomic, root, file);
1.196 set = razor_set_create();
1.197 - razor_set_write(set, atomic, path, RAZOR_SECTION_ALL);
1.198 - free(path);
1.199 - free(file);
1.200 + razor_set_write(set, atomic, uri, RAZOR_SECTION_ALL);
1.201 + free(uri);
1.202 retval = razor_atomic_commit(atomic);
1.203 if (retval)
1.204 razor_propagate_error(error,
1.205 @@ -167,17 +194,21 @@
1.206 }
1.207
1.208 RAZOR_EXPORT struct razor_root *
1.209 -razor_root_open(const char *root, struct razor_error **error)
1.210 +razor_root_open(const char *root_uri, struct razor_error **error)
1.211 {
1.212 struct razor_root *image;
1.213 - char *s, *lock_path;
1.214 + char *lock_uri;
1.215 int r;
1.216
1.217 - assert (root != NULL);
1.218 + lock_uri = razor_resolve_database_file(root_uri, system_lock_filename,
1.219 + error);
1.220
1.221 - razor_root_init();
1.222 + if (!lock_uri)
1.223 + return NULL;
1.224 +
1.225 image = malloc(sizeof *image);
1.226 if (image == NULL) {
1.227 + free(lock_uri);
1.228 razor_set_error(error, RAZOR_POSIX_ERROR, ENOMEM, NULL,
1.229 "Not enough memory");
1.230 return NULL;
1.231 @@ -186,35 +217,37 @@
1.232 image->system = razor_set_create_without_root();
1.233 if (image->system == NULL) {
1.234 free(image);
1.235 + free(lock_uri);
1.236 razor_set_error(error, RAZOR_POSIX_ERROR, ENOMEM, NULL,
1.237 "Not enough memory");
1.238 return NULL;
1.239 }
1.240
1.241 - s = razor_concat(razor_database_path, "/", system_lock_filename, NULL);
1.242 - lock_path = razor_path_add_root(s, root);
1.243 - free(s);
1.244 + r = razor_set_acquire_lock(image->system, lock_uri, 1);
1.245
1.246 - r = razor_set_aquire_lock(image->system, lock_path, 1);
1.247 -
1.248 - free(lock_path);
1.249 + free(lock_uri);
1.250
1.251 if (r < 0) {
1.252 razor_set_error(error, RAZOR_GENERAL_ERROR,
1.253 RAZOR_GENERAL_ERROR_DATABASE_LOCKED, NULL,
1.254 - "Failed to aquire exclusive system lock");
1.255 + "Failed to acquire exclusive system lock");
1.256 razor_set_unref(image->system);
1.257 free(image);
1.258 return NULL;
1.259 }
1.260
1.261 - s = razor_concat(razor_database_path, "/", system_repo_filename, NULL);
1.262 - image->path = razor_path_add_root(s, root);
1.263 - free(s);
1.264 + image->uri = razor_resolve_database_file(root_uri, system_repo_filename,
1.265 + error);
1.266
1.267 - if (razor_set_bind_sections(image->system, image->path,
1.268 + if (!image->uri) {
1.269 + razor_set_unref(image->system);
1.270 + free(image);
1.271 + return NULL;
1.272 + }
1.273 +
1.274 + if (razor_set_bind_sections(image->system, image->uri,
1.275 RAZOR_SET_PRIVATE, error)) {
1.276 - free(image->path);
1.277 + free(image->uri);
1.278 razor_set_unref(image->system);
1.279 free(image);
1.280 return NULL;
1.281 @@ -224,46 +257,47 @@
1.282 }
1.283
1.284 RAZOR_EXPORT struct razor_set *
1.285 -razor_root_open_read_only(const char *root, struct razor_error **error)
1.286 +razor_root_open_read_only(const char *root_uri, struct razor_error **error)
1.287 {
1.288 - char *s, *path;
1.289 + int r;
1.290 + char *uri;
1.291 struct razor_set *set;
1.292
1.293 - assert (root != NULL);
1.294 + uri = razor_resolve_database_file(root_uri, system_lock_filename,
1.295 + error);
1.296
1.297 - razor_root_init();
1.298 + if (!uri)
1.299 + return NULL;
1.300 +
1.301 set = razor_set_create_without_root();
1.302 if (set == NULL) {
1.303 + free(uri);
1.304 razor_set_error(error, RAZOR_POSIX_ERROR, ENOMEM, NULL,
1.305 "Not enough memory");
1.306 return NULL;
1.307 }
1.308
1.309 - s = razor_concat(razor_database_path, "/", system_lock_filename, NULL);
1.310 - path = razor_path_add_root(s, root);
1.311 - free(s);
1.312 + r = razor_set_acquire_lock(set, uri, 0);
1.313
1.314 - if (razor_set_aquire_lock(set, path, 0) < 0) {
1.315 + free(uri);
1.316 +
1.317 + if (r < 0) {
1.318 razor_set_error(error, RAZOR_GENERAL_ERROR,
1.319 RAZOR_GENERAL_ERROR_DATABASE_LOCKED, NULL,
1.320 - "Failed to aquire non-exclusive system lock");
1.321 - free(path);
1.322 + "Failed to acquire non-exclusive system lock");
1.323 razor_set_unref(set);
1.324 return NULL;
1.325 }
1.326
1.327 - free(path);
1.328 + uri = razor_resolve_database_file(root_uri, system_repo_filename,
1.329 + error);
1.330
1.331 - s = razor_concat(razor_database_path, "/", system_repo_filename, NULL);
1.332 - path = razor_path_add_root(s, root);
1.333 - free(s);
1.334 -
1.335 - if (razor_set_bind_sections(set, path, 0, error)) {
1.336 + if (!uri || razor_set_bind_sections(set, uri, 0, error)) {
1.337 razor_set_unref(set);
1.338 set = NULL;
1.339 }
1.340
1.341 - free(path);
1.342 + free(uri);
1.343
1.344 return set;
1.345 }
1.346 @@ -282,7 +316,7 @@
1.347 assert (root != NULL);
1.348
1.349 razor_set_unref(root->system);
1.350 - free(root->path);
1.351 + free(root->uri);
1.352 free(root);
1.353
1.354 return 0;
1.355 @@ -297,7 +331,7 @@
1.356 assert (root != NULL);
1.357 assert (next != NULL);
1.358
1.359 - handle = razor_atomic_create_file(atomic, root->path,
1.360 + handle = razor_atomic_create_file(atomic, root->uri,
1.361 S_IRWXU | S_IRWXG | S_IRWXO);
1.362 if (handle < 0)
1.363 return handle;