Fix a bug causing libtool versioning to be ignored.
This bug meant that razor 0.1 was recorded as interface 0 rather
than the intended interface 1. razor 0.2 will use interface 1.
2 * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
3 * Copyright (C) 2008 Red Hat, Inc
4 * Copyright (C) 2009 J. Ali Harlow <ali@juiblex.co.uk>
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.
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.
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.
25 #include <sys/types.h>
43 #include "razor-internal.h"
49 #define RAZOR_ASCII_ISALPHA(c) \
50 ((c) >= 'A' && (c) <= 'Z' || (c) >= 'a' && (c) <= 'z')
52 /* Required by gnulib on non-libc platforms */
53 char *program_name = "librazor";
55 static int allow_all_root_names = 0;
58 * Primarily intended for testing named roots under UNIX platforms.
60 RAZOR_EXPORT void razor_disable_root_name_checks(int disable)
62 allow_all_root_names = disable;
65 static int razor_valid_root_name(const char *name)
67 if (allow_all_root_names)
68 return !strchr(name,'/');
71 return RAZOR_ASCII_ISALPHA(name[0]) && name[1] == ':' &&
74 return name[0] == '\0';
79 razor_create_dir(const char *root, const char *path)
81 char buffer[PATH_MAX], *p;
82 const char *slash, *next;
85 /* Create all sub-directories in dir. We know root exists and
86 * is a dir, root does not end in a '/', and path either has a
87 * leading '/' or (on MS-Windows only) root is the empty string
88 * and path starts with drive (eg., "c:/windows"). */
91 p = buffer + strlen(buffer);
93 for (slash = path; *slash != '\0'; slash = next) {
94 next = strchr(slash + 1, '/');
98 memcpy(p, slash, next - slash);
102 if (razor_valid_root_name(buffer))
105 if (stat(buffer, &buf) == 0) {
106 if (!S_ISDIR(buf.st_mode)) {
108 "%s exists but is not a directory\n",
112 } else if (mkdir(buffer, 0777) < 0) {
113 fprintf(stderr, "failed to make directory %s: %s\n",
114 buffer, strerror(errno));
118 /* FIXME: What to do about permissions for dirs we
119 * have to create but are not in the cpio archive? */
126 razor_remove(const char *path)
131 if (DeleteFile(path))
134 err = GetLastError();
135 if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND)
138 if (SetFileAttributes(path, FILE_ATTRIBUTE_NORMAL) && DeleteFile(path))
141 if (RemoveDirectory(path) || GetLastError() == ERROR_DIR_NOT_EMPTY)
145 * It would be tempting to use:
146 * MoveFileEx(path, NULL, MOVEFILE_DELAY_UNTIL_REBOOT)
147 * but unless we can guarantee that the system will be rebooted
148 * before we (or some other application) write another file with the
149 * same path, this is likely to cause more problems than it solves.
152 /* Use remove() as a fallback so that errno is set appropriately */
159 razor_write(int fd, const void *data, size_t size)
163 const unsigned char *p;
168 written = write(fd, p, rest);
170 perror("write error");
181 razor_file_get_contents(const char *filename, size_t *length)
191 fd = open(filename, O_RDONLY | O_BINARY);
195 if (fstat(fd, &st) < 0) {
200 *length = st.st_size;
202 addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
204 addr = malloc(st.st_size);
207 while(nb < st.st_size) {
208 res = read(fd, addr + nb, st.st_size - nb);
221 if (addr == MAP_FAILED)
229 razor_file_free_contents(void *addr, size_t length)
232 return munmap(addr, length);
239 struct qsort_context {
241 razor_compare_with_data_func_t compare;
246 qsort_swap(void *p1, void *p2, size_t size)
250 memcpy(buffer, p1, size);
251 memcpy(p1, p2, size);
252 memcpy(p2, buffer, size);
256 __qsort_with_data(void *base, size_t nelem, uint32_t *map,
257 struct qsort_context *ctx)
259 void *p, *start, *end, *pivot;
260 uint32_t *mp, *mstart, *mend, tmp;
261 int left, right, result;
262 size_t size = ctx->size;
266 end = base + nelem * size;
270 pivot = base + (rand() % nelem) * size;
273 result = ctx->compare(p, pivot, ctx->data);
275 qsort_swap(p, start, size);
285 } else if (result == 0) {
291 qsort_swap(p, end, size);
300 left = (start - base) / size;
301 right = (base + nelem * size - end) / size;
303 __qsort_with_data(base, left, map, ctx);
305 __qsort_with_data(end, right, mend, ctx);
309 razor_qsort_with_data(void *base, size_t nelem, size_t size,
310 razor_compare_with_data_func_t compare, void *data)
312 struct qsort_context ctx;
320 ctx.compare = compare;
323 map = malloc(nelem * sizeof (uint32_t));
324 for (i = 0; i < nelem; i++)
327 __qsort_with_data(base, nelem, map, &ctx);
332 void environment_init(struct environment *env)
335 array_init(&env->string_pool);
336 array_init(&env->vars);
339 void environment_add_variable(struct environment *env,
340 const char *variable, const char *value)
344 assert(!env->is_set);
346 s = array_add(&env->string_pool,
347 strlen(variable) + strlen(value) + 2);
348 sprintf(s, "%s=%s", variable, value);
349 r = array_add(&env->vars, sizeof *r);
350 *r = s - (char *)env->string_pool.data;
353 void environment_set(struct environment *env)
360 count = env->vars.size / sizeof(uint32_t);
361 r = (uint32_t *)env->vars.data;
362 for (i = 0; i < count; i++) {
363 s = env->string_pool.data + *r++;
371 void environment_unset(struct environment *env)
378 count = env->vars.size / sizeof(uint32_t);
379 r = (uint32_t *)env->vars.data;
380 for (i = 0; i < count; i++) {
381 s = env->string_pool.data + *r++;
382 t = strchr(s, '=') + 1;
393 void environment_release(struct environment *env)
395 environment_unset(env);
396 array_release(&env->string_pool);
397 array_release(&env->vars);