2 * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
3 * Copyright (C) 2008 Red Hat, Inc
4 * Copyright (C) 2009, 2011, 2012, 2014 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>
37 #include <sys/utsname.h>
45 #include "razor-internal.h"
51 /* Required by gnulib on non-libc platforms */
52 char *program_name = "librazor";
66 #define OPEN_FILE_USED (1U<<0)
67 #define OPEN_FILE_MMAPPED (1U<<1)
75 struct array open_files = { 0, };
76 #endif /* HAVE_SYS_MMAN_H */
79 razor_file_get_contents(const char *filename, size_t *length, int private,
80 struct razor_error **error)
88 struct open_file *of, *ofend;
91 fd = open(filename, O_RDONLY | O_BINARY);
93 razor_set_error_posix(error, filename);
97 if (fstat(fd, &st) < 0) {
98 razor_set_error_posix(error, filename);
103 *length = st.st_size;
106 ofend = open_files.data + open_files.size;
107 for (of = open_files.data; of < ofend; of++)
108 if (!(of->flags & OPEN_FILE_USED))
111 of = array_add(&open_files, sizeof *of);
116 addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
117 if (addr == MAP_FAILED)
120 of->flags = OPEN_FILE_USED | OPEN_FILE_MMAPPED;
122 #endif /* HAVE_SYS_MMAN_H */
124 addr = malloc(st.st_size);
127 of->flags = OPEN_FILE_USED;
130 while(nb < st.st_size) {
131 res = read(fd, addr + nb, st.st_size - nb);
133 razor_set_error_posix(error, filename);
141 razor_set_error(error, RAZOR_POSIX_ERROR, ENOMEM, NULL,
142 "Not enough memory");
148 of->length = st.st_size;
154 int razor_file_free_contents(void *addr, size_t length)
158 struct open_file *of, *ofend;
160 ofend = open_files.data + open_files.size;
161 for (of = open_files.data; of < ofend; of++)
162 if ((of->flags & OPEN_FILE_USED) && of->addr == addr)
169 mmapped = of->flags & OPEN_FILE_MMAPPED;
170 of->flags &= ~OPEN_FILE_USED;
172 for (of = open_files.data; of < ofend; of++)
173 if (of->flags & OPEN_FILE_USED)
177 array_release(&open_files);
178 array_init(&open_files);
182 return munmap(addr, length);
189 struct qsort_context {
191 razor_compare_with_data_func_t compare;
196 qsort_swap(void *p1, void *p2, size_t size)
201 memcpy(buffer, p1, size);
202 memcpy(p1, p2, size);
203 memcpy(p2, buffer, size);
208 __qsort_with_data(void *base, size_t nelem, uint32_t *map,
209 struct qsort_context *ctx)
211 void *p, *start, *end, *pivot;
212 uint32_t *mp, *mstart, *mend, tmp;
213 int left, right, result;
214 size_t size = ctx->size;
218 end = base + nelem * size;
222 pivot = base + (rand() % nelem) * size;
225 result = ctx->compare(p, pivot, ctx->data);
227 qsort_swap(p, start, size);
237 } else if (result == 0) {
243 qsort_swap(p, end, size);
252 left = (start - base) / size;
253 right = (base + nelem * size - end) / size;
255 __qsort_with_data(base, left, map, ctx);
257 __qsort_with_data(end, right, mend, ctx);
261 razor_qsort_with_data(void *base, size_t nelem, size_t size,
262 razor_compare_with_data_func_t compare, void *data)
264 struct qsort_context ctx;
272 ctx.compare = compare;
275 map = malloc(nelem * sizeof (uint32_t));
276 for (i = 0; i < nelem; i++)
279 __qsort_with_data(base, nelem, map, &ctx);
284 void environment_init(struct environment *env)
287 array_init(&env->string_pool);
288 array_init(&env->vars);
291 void environment_add_variable(struct environment *env,
292 const char *variable, const char *value)
296 assert(!env->is_set);
298 s = array_add(&env->string_pool,
299 strlen(variable) + strlen(value) + 2);
300 sprintf(s, "%s=%s", variable, value);
301 r = array_add(&env->vars, sizeof *r);
302 *r = s - (char *)env->string_pool.data;
305 void environment_set(struct environment *env)
315 count = env->vars.size / sizeof(uint32_t);
316 r = (uint32_t *)env->vars.data;
317 for (i = 0; i < count; i++) {
318 s = env->string_pool.data + *r++;
333 void environment_unset(struct environment *env)
340 count = env->vars.size / sizeof(uint32_t);
341 r = (uint32_t *)env->vars.data;
342 for (i = 0; i < count; i++) {
343 s = env->string_pool.data + *r++;
363 void environment_release(struct environment *env)
365 environment_unset(env);
366 array_release(&env->string_pool);
367 array_release(&env->vars);
370 RAZOR_EXPORT char *razor_concat(const char *s, ...)
380 while((string = va_arg(args, const char *)))
381 len += strlen(string);
385 concat = malloc(len + 1);
393 memcpy(concat, s, len);
395 while((string = va_arg(args, const char *))) {
396 len = strlen(string);
397 memcpy(concat + n, string, len);
408 RAZOR_EXPORT const char *razor_system_arch(void)
413 GetNativeSystemInfo(&si);
414 switch(si.wProcessorArchitecture)
416 case PROCESSOR_ARCHITECTURE_INTEL:
418 case PROCESSOR_ARCHITECTURE_AMD64:
424 static struct utsname un;
435 char *razor_utf16_to_utf8(const wchar_t *utf16, int len)
443 n = WideCharToMultiByte(CP_UTF8, 0, utf16, len, NULL, 0, NULL, NULL);
447 (void)WideCharToMultiByte(CP_UTF8, 0, utf16, len, utf8, n, NULL, NULL);
454 wchar_t *razor_utf8_to_utf16(const char *utf8, int len)
460 utf16 = calloc(1, sizeof(wchar_t));
464 n = MultiByteToWideChar(CP_UTF8, 0, utf8, len, NULL, 0);
467 utf16 = malloc(n * sizeof(wchar_t));
468 (void)MultiByteToWideChar(CP_UTF8, 0, utf8, len, utf16, n);
475 #endif /* MSWIN_API */