librazor/root.c
author J. Ali Harlow <ali@juiblex.co.uk>
Sat Aug 23 11:13:48 2014 +0100 (2014-08-23)
changeset 440 48204dea0b9f
parent 425 0c8bdd8dc942
child 441 cf499fd51df7
permissions -rw-r--r--
Remove INTLLIBS from librazor_la_LIBADD.

This partially reverts 611c84a3f4b4538a65d186050608c17adbf17770.
It's not clear what motivated the initial inclusion of INTLLIBS
here since the net effect is only seen in librazor.la and not
in razor.pc and librazor.la is not normally packaged. Certainly
neither the static nor the dynamic versions of librazor currently
use libintl. At best this would cause the linker to search a
static libintl for undefined symbols without finding any; at worse
it causes a static build of plover using librazor.la to fail if
no static version of libintl is installed.
     1 /*
     2  * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
     3  * Copyright (C) 2008  Red Hat, Inc
     4  * Copyright (C) 2009, 2011, 2012  J. Ali Harlow <ali@juiblex.co.uk>
     5  *
     6  * This program is free software; you can redistribute it and/or modify
     7  * it under the terms of the GNU General Public License as published by
     8  * the Free Software Foundation; either version 2 of the License, or
     9  * (at your option) any later version.
    10  *
    11  * This program is distributed in the hope that it will be useful,
    12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  * GNU General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License along
    17  * with this program; if not, write to the Free Software Foundation, Inc.,
    18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    19  */
    20 
    21 #include "config.h"
    22 
    23 #include <stdlib.h>
    24 #include <stdint.h>
    25 #include <stdio.h>
    26 #include <string.h>
    27 #include <sys/stat.h>
    28 #include <dirent.h>
    29 #include <unistd.h>
    30 #include <fcntl.h>
    31 #include <limits.h>
    32 #include <assert.h>
    33 #ifdef MSWIN_API
    34 #include <shlobj.h>
    35 #endif
    36 
    37 #include "razor.h"
    38 #include "razor-internal.h"
    39 
    40 #ifndef O_BINARY
    41 #define O_BINARY	0
    42 #endif
    43 
    44 static const char system_repo_filename[] = "system.rzdb";
    45 /*
    46  * system_lock_filename is chosen to be the same as the pre v0.3
    47  * next_repo_filename. This means that once a system has been
    48  * updated by a v0.3+ copy of razor all pre v0.3 versions of razor
    49  * will see the system as permenantly locked.
    50  */
    51 static const char system_lock_filename[] = "system-next.rzdb";
    52 #ifdef MSWIN_API
    53 #define RAZOR_ROOT_PATH	NULL
    54 #else
    55 #define RAZOR_ROOT_PATH	"/var/lib/razor"
    56 #endif
    57 static const char *razor_root_path = RAZOR_ROOT_PATH;
    58 
    59 struct razor_root {
    60 	struct razor_set *system;
    61 	char *path;
    62 };
    63 
    64 static void
    65 razor_root_init(void)
    66 {
    67 #ifdef MSWIN_API
    68 	static char root_path[MAX_PATH];
    69 	if (!razor_root_path) {
    70 		SHGetFolderPath(NULL,
    71 			CSIDL_COMMON_APPDATA | CSIDL_FLAG_DONT_VERIFY, NULL, 0,
    72 			root_path);
    73 		strcat(root_path, "\\Razor");
    74 		razor_root_path = root_path;
    75 	}
    76 #endif
    77 }
    78 
    79 RAZOR_EXPORT int
    80 razor_root_create(const char *root, struct razor_error **error)
    81 {
    82 	int retval;
    83 	struct stat buf;
    84 	struct razor_set *set;
    85 	struct razor_atomic *atomic;
    86 	char *file, *path;
    87 
    88 	assert (root != NULL);
    89 
    90 	razor_root_init();
    91 	if (root[0] == '\0') {
    92 		/* root is file system root */
    93 	} else if (stat(root, &buf) < 0) {
    94 		if (mkdir(root, 0777) < 0) {
    95 			razor_set_error(error, root,
    96 					"Could not create install root");
    97 			return -1;
    98 		}
    99 	} else if (!S_ISDIR(buf.st_mode)) {
   100 		razor_set_error(error, root, "Not a directory");
   101 		return -1;
   102 	}
   103 
   104 	file = razor_concat(razor_root_path, "/", system_repo_filename, NULL);
   105 	path = razor_concat(root, file, NULL);
   106 	retval = !stat(path, &buf);
   107 	if (retval) {
   108 		razor_set_error(error, NULL,
   109 				"A razor install root is already initialized");
   110 		free(path);
   111 		free(file);
   112 		return retval;
   113 	}
   114 
   115 	atomic = razor_atomic_open("Create initial package set");
   116 	razor_atomic_make_dirs(atomic, root, file);
   117 	set = razor_set_create();
   118 	razor_set_write(set, atomic, path, RAZOR_SECTION_ALL);
   119 	free(path);
   120 	free(file);
   121 	retval = razor_atomic_commit(atomic);
   122 	if (retval)
   123 		razor_propagate_error(error,
   124 				      razor_atomic_get_error(atomic),
   125 				      "Could not write initial package set");
   126 	razor_set_unref(set);
   127 	razor_atomic_destroy(atomic);
   128 
   129 	return retval;
   130 }
   131 
   132 RAZOR_EXPORT struct razor_root *
   133 razor_root_open(const char *root, struct razor_error **error)
   134 {
   135 	struct razor_root *image;
   136 	char *lock_path;
   137 	int r;
   138 
   139 	assert (root != NULL);
   140 
   141 	razor_root_init();
   142 	image = malloc(sizeof *image);
   143 	if (image == NULL) {
   144 		razor_set_error(error, NULL, "Not enough memory");
   145 		return NULL;
   146 	}
   147 
   148 	image->system = razor_set_create_without_root();
   149 	if (image->system == NULL) {
   150 		free(image);
   151 		razor_set_error(error, NULL, "Not enough memory");
   152 		return NULL;
   153 	}
   154 
   155 	lock_path = razor_concat(root, razor_root_path, "/",
   156 				 system_lock_filename, NULL);
   157 
   158 	r = razor_set_aquire_lock(image->system, lock_path, 1);
   159 
   160 	free(lock_path);
   161 
   162 	if (r < 0) {
   163 		razor_set_error(error, NULL,
   164 				"Failed to aquire exclusive system lock");
   165 		razor_set_unref(image->system);
   166 		free(image);
   167 		return NULL;
   168 	}
   169 
   170 	image->path = razor_concat(root, razor_root_path, "/",
   171 				   system_repo_filename, NULL);
   172 
   173 	if (razor_set_bind_sections(image->system, image->path,
   174 				    RAZOR_SET_PRIVATE, error)) {
   175 		free(image->path);
   176 		razor_set_unref(image->system);
   177 		free(image);
   178 		return NULL;
   179 	}
   180 
   181 	return image;
   182 }
   183 
   184 RAZOR_EXPORT struct razor_set *
   185 razor_root_open_read_only(const char *root, struct razor_error **error)
   186 {
   187 	char *path;
   188 	struct razor_set *set;
   189 
   190 	assert (root != NULL);
   191 
   192 	razor_root_init();
   193 	set = razor_set_create_without_root();
   194 	if (set == NULL) {
   195 		razor_set_error(error, NULL, "Not enough memory");
   196 		return NULL;
   197 	}
   198 
   199 	path = razor_concat(root, razor_root_path, "/", system_lock_filename,
   200 			    NULL);
   201 	if (razor_set_aquire_lock(set, path, 0) < 0) {
   202 		razor_set_error(error, NULL,
   203 				"Failed to aquire non-exclusive system lock");
   204 		free(path);
   205 		razor_set_unref(set);
   206 		return NULL;
   207 	}
   208 
   209 	free(path);
   210 	path = razor_concat(root, razor_root_path, "/", system_repo_filename,
   211 			    NULL);
   212 
   213 	if (razor_set_bind_sections(set, path, 0, error)) {
   214 		razor_set_unref(set);
   215 		set = NULL;
   216 	}
   217 
   218 	free(path);
   219 
   220 	return set;
   221 }
   222 
   223 RAZOR_EXPORT struct razor_set *
   224 razor_root_get_system_set(struct razor_root *root)
   225 {
   226 	assert (root != NULL);
   227 
   228 	return root->system;
   229 }
   230 
   231 RAZOR_EXPORT int
   232 razor_root_close(struct razor_root *root)
   233 {
   234 	assert (root != NULL);
   235 
   236 	razor_set_unref(root->system);
   237 	free(root->path);
   238 	free(root);
   239 
   240 	return 0;
   241 }
   242 
   243 RAZOR_EXPORT int
   244 razor_root_update(struct razor_root *root, struct razor_set *next,
   245 		  struct razor_atomic *atomic)
   246 {
   247 	int handle, retval;
   248 
   249 	assert (root != NULL);
   250 	assert (next != NULL);
   251 
   252 	handle = razor_atomic_create_file(atomic, root->path,
   253 					  S_IRWXU | S_IRWXG | S_IRWXO);
   254 	if (handle < 0)
   255 		return handle;
   256 
   257 	razor_set_write_to_handle(next, atomic, handle, RAZOR_SECTION_ALL);
   258 
   259 	retval = razor_atomic_close(atomic, handle);
   260 
   261 	if (!retval) {
   262 		razor_set_unref(root->system);
   263 		root->system = razor_set_ref(next);
   264 	}
   265 
   266 	return retval;
   267 }