librazor/util.c
changeset 248 057933050c42
child 300 455eaa569767
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/librazor/util.c	Fri Jun 20 15:10:34 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 +}