diff -r 0a5e583393e1 -r 7c6d932f291f librazor/root.c --- a/librazor/root.c Tue Sep 09 15:27:12 2014 +0100 +++ b/librazor/root.c Mon Jul 11 13:54:54 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,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -59,102 +58,130 @@ */ static const char system_lock_filename[] = "system-next.rzdb"; #ifdef MSWIN_API -#define RAZOR_DATABASE_PATH NULL +#define RAZOR_DATABASE_URI NULL #else -#define RAZOR_DATABASE_PATH "/var/lib/razor" +/* + * The non-MSWIN default is a relative-ref and thus affected by the root + */ +#define RAZOR_DATABASE_URI "var/lib/razor" #endif -static char *razor_database_path = RAZOR_DATABASE_PATH; -static int razor_database_path_alloced = FALSE; +static char *razor_database_uri = RAZOR_DATABASE_URI; +static int razor_database_uri_alloced = FALSE; struct razor_root { struct razor_set *system; - char *path; + char *uri; }; static void razor_root_init(void) { #ifdef MSWIN_API - static char database_path[MAX_PATH]; - if (!razor_database_path) { + /* + * The MSWIN default is an absolute-URI and thus unaffected by the root + */ + char database_path[MAX_PATH]; + if (!razor_database_uri) { SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA | CSIDL_FLAG_DONT_VERIFY, NULL, 0, database_path); strcat(database_path, "\\Razor"); - razor_database_path = database_path; - razor_database_path_alloced = FALSE; + razor_database_uri = razor_path_to_uri(database_path); + razor_database_uri_alloced = TRUE; } #endif } -RAZOR_EXPORT const char * -razor_get_database_path() +RAZOR_EXPORT const char *razor_get_database_uri(void) { razor_root_init(); - - return razor_database_path; + return razor_database_uri; } RAZOR_EXPORT void -razor_set_database_path(const char *database_path) +razor_set_database_uri(const char *database_uri) { - if (razor_database_path_alloced) - free(razor_database_path); + if (razor_database_uri_alloced) + free(razor_database_uri); - if (database_path) { - razor_database_path = strdup(database_path); - razor_database_path_alloced = TRUE; + if (database_uri) { + razor_database_uri = strdup(database_uri); + razor_database_uri_alloced = TRUE; } else { - razor_database_path = RAZOR_DATABASE_PATH; - razor_database_path_alloced = FALSE; + razor_database_uri = RAZOR_DATABASE_URI; + razor_database_uri_alloced = FALSE; } } +char *razor_resolve_database_file(const char *root_uri, const char *filename, + struct razor_error **error) +{ + char *s, *uri; + + razor_root_init(); + + s = razor_concat(razor_database_uri, "/", filename, NULL); + + uri = razor_resolve_uri_root(root_uri, s, -1, error); + + free(s); + + return uri; +} + RAZOR_EXPORT int -razor_root_create(const char *root, struct razor_error **error) +razor_root_create(const char *root_uri, struct razor_error **error) { - int retval; - struct stat buf; + int retval, is_within_root, is_directory; struct razor_set *set; struct razor_atomic *atomic; - char *file, *path; + struct razor_error *tmp_err = NULL; + char *uri; - assert (root != NULL); + uri = razor_resolve_database_file(root_uri, system_repo_filename, + error); - razor_root_init(); - if (root[0] == '\0') { - /* root is file system root */ - } else if (stat(root, &buf) < 0) { - if (mkdir(root, 0777) < 0) { - razor_set_error(error, RAZOR_POSIX_ERROR, errno, root, + if (!uri) + return -1; + + if (razor_uri_is_directory(uri, NULL) >= 0) { + razor_set_error(error, RAZOR_GENERAL_ERROR, + RAZOR_GENERAL_ERROR_DATABASE_EXISTS, NULL, + "A razor install root is already initialized"); + free(uri); + return -1; + } + + is_within_root = root_uri && strchr(root_uri, '/') && + str_has_prefix(uri, root_uri); + + atomic = razor_atomic_open("Create initial package set"); + + if (is_within_root) { + is_directory = razor_uri_is_directory(root_uri, NULL); + + if (!is_directory) { + razor_set_error(error, RAZOR_POSIX_ERROR, ENOTDIR, + root_uri, "Not a directory"); + return -1; + } else if (is_directory < 0 && + razor_uri_mkdir(root_uri, 0777, &tmp_err) < 0) { + razor_set_error(error, + razor_error_get_domain(tmp_err), + razor_error_get_code(tmp_err), + root_uri, "Could not create install root"); return -1; } - } else if (!S_ISDIR(buf.st_mode)) { - razor_set_error(error, RAZOR_POSIX_ERROR, ENOTDIR, root, - "Not a directory"); - return -1; - } - file = razor_concat(razor_database_path, "/", system_repo_filename, - NULL); - path = razor_path_add_root(file, root); - retval = !stat(path, &buf); - if (retval) { - razor_set_error(error, RAZOR_GENERAL_ERROR, - RAZOR_GENERAL_ERROR_DATABASE_EXISTS, NULL, - "A razor install root is already initialized"); - free(path); - free(file); - return retval; - } + razor_atomic_make_dirs(atomic, root_uri, + uri + strlen(root_uri)); + } else + razor_atomic_make_dirs(atomic, "", uri); - atomic = razor_atomic_open("Create initial package set"); - razor_atomic_make_dirs(atomic, root, file); set = razor_set_create(); - razor_set_write(set, atomic, path, RAZOR_SECTION_ALL); - free(path); - free(file); + razor_set_write(set, atomic, uri, RAZOR_SECTION_ALL); + free(uri); retval = razor_atomic_commit(atomic); if (retval) razor_propagate_error(error, @@ -167,17 +194,21 @@ } RAZOR_EXPORT struct razor_root * -razor_root_open(const char *root, struct razor_error **error) +razor_root_open(const char *root_uri, struct razor_error **error) { struct razor_root *image; - char *s, *lock_path; + char *lock_uri; int r; - assert (root != NULL); + lock_uri = razor_resolve_database_file(root_uri, system_lock_filename, + error); - razor_root_init(); + if (!lock_uri) + return NULL; + image = malloc(sizeof *image); if (image == NULL) { + free(lock_uri); razor_set_error(error, RAZOR_POSIX_ERROR, ENOMEM, NULL, "Not enough memory"); return NULL; @@ -186,35 +217,37 @@ image->system = razor_set_create_without_root(); if (image->system == NULL) { free(image); + free(lock_uri); razor_set_error(error, RAZOR_POSIX_ERROR, ENOMEM, NULL, "Not enough memory"); return NULL; } - s = razor_concat(razor_database_path, "/", system_lock_filename, NULL); - lock_path = razor_path_add_root(s, root); - free(s); + r = razor_set_acquire_lock(image->system, lock_uri, 1); - r = razor_set_aquire_lock(image->system, lock_path, 1); - - free(lock_path); + free(lock_uri); if (r < 0) { razor_set_error(error, RAZOR_GENERAL_ERROR, RAZOR_GENERAL_ERROR_DATABASE_LOCKED, NULL, - "Failed to aquire exclusive system lock"); + "Failed to acquire exclusive system lock"); razor_set_unref(image->system); free(image); return NULL; } - s = razor_concat(razor_database_path, "/", system_repo_filename, NULL); - image->path = razor_path_add_root(s, root); - free(s); + image->uri = razor_resolve_database_file(root_uri, system_repo_filename, + error); - if (razor_set_bind_sections(image->system, image->path, + if (!image->uri) { + razor_set_unref(image->system); + free(image); + return NULL; + } + + if (razor_set_bind_sections(image->system, image->uri, RAZOR_SET_PRIVATE, error)) { - free(image->path); + free(image->uri); razor_set_unref(image->system); free(image); return NULL; @@ -224,46 +257,47 @@ } RAZOR_EXPORT struct razor_set * -razor_root_open_read_only(const char *root, struct razor_error **error) +razor_root_open_read_only(const char *root_uri, struct razor_error **error) { - char *s, *path; + int r; + char *uri; struct razor_set *set; - assert (root != NULL); + uri = razor_resolve_database_file(root_uri, system_lock_filename, + error); - razor_root_init(); + if (!uri) + return NULL; + set = razor_set_create_without_root(); if (set == NULL) { + free(uri); razor_set_error(error, RAZOR_POSIX_ERROR, ENOMEM, NULL, "Not enough memory"); return NULL; } - s = razor_concat(razor_database_path, "/", system_lock_filename, NULL); - path = razor_path_add_root(s, root); - free(s); + r = razor_set_acquire_lock(set, uri, 0); - if (razor_set_aquire_lock(set, path, 0) < 0) { + free(uri); + + if (r < 0) { razor_set_error(error, RAZOR_GENERAL_ERROR, RAZOR_GENERAL_ERROR_DATABASE_LOCKED, NULL, - "Failed to aquire non-exclusive system lock"); - free(path); + "Failed to acquire non-exclusive system lock"); razor_set_unref(set); return NULL; } - free(path); + uri = razor_resolve_database_file(root_uri, system_repo_filename, + error); - s = razor_concat(razor_database_path, "/", system_repo_filename, NULL); - path = razor_path_add_root(s, root); - free(s); - - if (razor_set_bind_sections(set, path, 0, error)) { + if (!uri || razor_set_bind_sections(set, uri, 0, error)) { razor_set_unref(set); set = NULL; } - free(path); + free(uri); return set; } @@ -282,7 +316,7 @@ assert (root != NULL); razor_set_unref(root->system); - free(root->path); + free(root->uri); free(root); return 0; @@ -297,7 +331,7 @@ assert (root != NULL); assert (next != NULL); - handle = razor_atomic_create_file(atomic, root->path, + handle = razor_atomic_create_file(atomic, root->uri, S_IRWXU | S_IRWXG | S_IRWXO); if (handle < 0) return handle;