1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/librazor/util.c Fri Jun 20 22:27:07 2008 -0400
1.3 @@ -0,0 +1,167 @@
1.4 +#include <limits.h>
1.5 +#include <string.h>
1.6 +#include <sys/stat.h>
1.7 +#include <stdlib.h>
1.8 +#include <stdio.h>
1.9 +#include <stdint.h>
1.10 +#include <unistd.h>
1.11 +
1.12 +#include "razor-internal.h"
1.13 +
1.14 +int
1.15 +razor_create_dir(const char *root, const char *path)
1.16 +{
1.17 + char buffer[PATH_MAX], *p;
1.18 + const char *slash, *next;
1.19 + struct stat buf;
1.20 +
1.21 + /* Create all sub-directories in dir. We know root exists and
1.22 + * is a dir, root does not end in a '/', and path has a
1.23 + * leading '/'. */
1.24 +
1.25 + strcpy(buffer, root);
1.26 + p = buffer + strlen(buffer);
1.27 + slash = path;
1.28 + for (slash = path; *slash != '\0'; slash = next) {
1.29 + next = strchr(slash + 1, '/');
1.30 + if (next == NULL)
1.31 + break;
1.32 +
1.33 + memcpy(p, slash, next - slash);
1.34 + p += next - slash;
1.35 + *p = '\0';
1.36 +
1.37 + if (stat(buffer, &buf) == 0) {
1.38 + if (!S_ISDIR(buf.st_mode)) {
1.39 + fprintf(stderr,
1.40 + "%s exists but is not a directory\n",
1.41 + buffer);
1.42 + return -1;
1.43 + }
1.44 + } else if (mkdir(buffer, 0777) < 0) {
1.45 + fprintf(stderr, "failed to make directory %s: %m\n",
1.46 + buffer);
1.47 + return -1;
1.48 + }
1.49 +
1.50 + /* FIXME: What to do about permissions for dirs we
1.51 + * have to create but are not in the cpio archive? */
1.52 + }
1.53 +
1.54 + return 0;
1.55 +}
1.56 +
1.57 +int
1.58 +razor_write(int fd, const void *data, size_t size)
1.59 +{
1.60 + size_t rest;
1.61 + ssize_t written;
1.62 + const unsigned char *p;
1.63 +
1.64 + rest = size;
1.65 + p = data;
1.66 + while (rest > 0) {
1.67 + written = write(fd, p, rest);
1.68 + if (written < 0) {
1.69 + fprintf(stderr, "write error: %m\n");
1.70 + return -1;
1.71 + }
1.72 + rest -= written;
1.73 + p += written;
1.74 + }
1.75 +
1.76 + return 0;
1.77 +}
1.78 +
1.79 +struct qsort_context {
1.80 + size_t size;
1.81 + razor_compare_with_data_func_t compare;
1.82 + void *data;
1.83 +};
1.84 +
1.85 +static void
1.86 +qsort_swap(void *p1, void *p2, size_t size)
1.87 +{
1.88 + char buffer[size];
1.89 +
1.90 + memcpy(buffer, p1, size);
1.91 + memcpy(p1, p2, size);
1.92 + memcpy(p2, buffer, size);
1.93 +}
1.94 +
1.95 +static void
1.96 +__qsort_with_data(void *base, size_t nelem, uint32_t *map,
1.97 + struct qsort_context *ctx)
1.98 +{
1.99 + void *p, *start, *end, *pivot;
1.100 + uint32_t *mp, *mstart, *mend, tmp;
1.101 + int left, right, result;
1.102 + size_t size = ctx->size;
1.103 +
1.104 + p = base;
1.105 + start = base;
1.106 + end = base + nelem * size;
1.107 + mp = map;
1.108 + mstart = map;
1.109 + mend = map + nelem;
1.110 + pivot = base + (random() % nelem) * size;
1.111 +
1.112 + while (p < end) {
1.113 + result = ctx->compare(p, pivot, ctx->data);
1.114 + if (result < 0) {
1.115 + qsort_swap(p, start, size);
1.116 + tmp = *mp;
1.117 + *mp = *mstart;
1.118 + *mstart = tmp;
1.119 + if (start == pivot)
1.120 + pivot = p;
1.121 + start += size;
1.122 + mstart++;
1.123 + p += size;
1.124 + mp++;
1.125 + } else if (result == 0) {
1.126 + p += size;
1.127 + mp++;
1.128 + } else {
1.129 + end -= size;
1.130 + mend--;
1.131 + qsort_swap(p, end, size);
1.132 + tmp = *mp;
1.133 + *mp = *mend;
1.134 + *mend = tmp;
1.135 + if (end == pivot)
1.136 + pivot = p;
1.137 + }
1.138 + }
1.139 +
1.140 + left = (start - base) / size;
1.141 + right = (base + nelem * size - end) / size;
1.142 + if (left > 1)
1.143 + __qsort_with_data(base, left, map, ctx);
1.144 + if (right > 1)
1.145 + __qsort_with_data(end, right, mend, ctx);
1.146 +}
1.147 +
1.148 +uint32_t *
1.149 +razor_qsort_with_data(void *base, size_t nelem, size_t size,
1.150 + razor_compare_with_data_func_t compare, void *data)
1.151 +{
1.152 + struct qsort_context ctx;
1.153 + uint32_t *map;
1.154 + int i;
1.155 +
1.156 + if (nelem == 0)
1.157 + return NULL;
1.158 +
1.159 + ctx.size = size;
1.160 + ctx.compare = compare;
1.161 + ctx.data = data;
1.162 +
1.163 + map = malloc(nelem * sizeof (uint32_t));
1.164 + for (i = 0; i < nelem; i++)
1.165 + map[i] = i;
1.166 +
1.167 + __qsort_with_data(base, nelem, map, &ctx);
1.168 +
1.169 + return map;
1.170 +}