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