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>
42 #include "razor-internal.h"
48 #define RAZOR_ASCII_ISALPHA(c) \
49 ((c) >= 'A' && (c) <= 'Z' || (c) >= 'a' && (c) <= 'z')
51 /* Required by gnulib on non-libc platforms */
52 char *program_name = "librazor";
54 static int allow_all_root_names = 0;
57 * Primarily intended for testing named roots under UNIX platforms.
59 RAZOR_EXPORT void razor_disable_root_name_checks(int disable)
61 allow_all_root_names = disable;
64 static int razor_valid_root_name(const char *name)
66 if (allow_all_root_names)
67 return !strchr(name,'/');
70 return RAZOR_ASCII_ISALPHA(name[0]) && name[1] == ':' &&
73 return name[0] == '\0';
78 razor_create_dir(const char *root, const char *path)
80 char buffer[PATH_MAX], *p;
81 const char *slash, *next;
84 /* Create all sub-directories in dir. We know root exists and
85 * is a dir, root does not end in a '/', and path either has a
86 * leading '/' or (on MS-Windows only) root is the empty string
87 * and path starts with drive (eg., "c:/windows"). */
90 p = buffer + strlen(buffer);
92 for (slash = path; *slash != '\0'; slash = next) {
93 next = strchr(slash + 1, '/');
97 memcpy(p, slash, next - slash);
101 if (razor_valid_root_name(buffer))
104 if (stat(buffer, &buf) == 0) {
105 if (!S_ISDIR(buf.st_mode)) {
107 "%s exists but is not a directory\n",
111 } else if (mkdir(buffer, 0777) < 0) {
112 fprintf(stderr, "failed to make directory %s: %s\n",
113 buffer, strerror(errno));
117 /* FIXME: What to do about permissions for dirs we
118 * have to create but are not in the cpio archive? */
125 razor_write(int fd, const void *data, size_t size)
129 const unsigned char *p;
134 written = write(fd, p, rest);
136 perror("write error");
147 razor_file_get_contents(const char *filename, size_t *length)
157 fd = open(filename, O_RDONLY | O_BINARY);
161 if (fstat(fd, &st) < 0) {
166 *length = st.st_size;
168 addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
170 addr = malloc(st.st_size);
173 while(nb < st.st_size) {
174 res = read(fd, addr + nb, st.st_size - nb);
187 if (addr == MAP_FAILED)
195 razor_file_free_contents(void *addr, size_t length)
198 return munmap(addr, length);
205 struct qsort_context {
207 razor_compare_with_data_func_t compare;
212 qsort_swap(void *p1, void *p2, size_t size)
216 memcpy(buffer, p1, size);
217 memcpy(p1, p2, size);
218 memcpy(p2, buffer, size);
222 __qsort_with_data(void *base, size_t nelem, uint32_t *map,
223 struct qsort_context *ctx)
225 void *p, *start, *end, *pivot;
226 uint32_t *mp, *mstart, *mend, tmp;
227 int left, right, result;
228 size_t size = ctx->size;
232 end = base + nelem * size;
236 pivot = base + (rand() % nelem) * size;
239 result = ctx->compare(p, pivot, ctx->data);
241 qsort_swap(p, start, size);
251 } else if (result == 0) {
257 qsort_swap(p, end, size);
266 left = (start - base) / size;
267 right = (base + nelem * size - end) / size;
269 __qsort_with_data(base, left, map, ctx);
271 __qsort_with_data(end, right, mend, ctx);
275 razor_qsort_with_data(void *base, size_t nelem, size_t size,
276 razor_compare_with_data_func_t compare, void *data)
278 struct qsort_context ctx;
286 ctx.compare = compare;
289 map = malloc(nelem * sizeof (uint32_t));
290 for (i = 0; i < nelem; i++)
293 __qsort_with_data(base, nelem, map, &ctx);
298 void environment_init(struct environment *env)
301 array_init(&env->string_pool);
302 array_init(&env->vars);
305 void environment_add_variable(struct environment *env,
306 const char *variable, const char *value)
310 assert(!env->is_set);
312 s = array_add(&env->string_pool,
313 strlen(variable) + strlen(value) + 2);
314 sprintf(s, "%s=%s", variable, value);
315 r = array_add(&env->vars, sizeof *r);
316 *r = s - (char *)env->string_pool.data;
319 void environment_set(struct environment *env)
326 count = env->vars.size / sizeof(uint32_t);
327 r = (uint32_t *)env->vars.data;
328 for (i = 0; i < count; i++) {
329 s = env->string_pool.data + *r++;
337 void environment_unset(struct environment *env)
344 count = env->vars.size / sizeof(uint32_t);
345 r = (uint32_t *)env->vars.data;
346 for (i = 0; i < count; i++) {
347 s = env->string_pool.data + *r++;
348 t = strchr(s, '=') + 1;
359 void environment_release(struct environment *env)
361 environment_unset(env);
362 array_release(&env->string_pool);
363 array_release(&env->vars);