librazor/util.c
author Kristian H?gsberg <krh@redhat.com>
Fri Jun 20 18:26:46 2008 -0400 (2008-06-20)
changeset 250 ce5402017488
child 300 455eaa569767
permissions -rw-r--r--
Add getter to return system set for a razor_root.
rhughes@241
     1
#include <limits.h>
rhughes@241
     2
#include <string.h>
rhughes@241
     3
#include <sys/stat.h>
rhughes@241
     4
#include <stdlib.h>
rhughes@241
     5
#include <stdio.h>
rhughes@241
     6
#include <stdint.h>
rhughes@241
     7
#include <unistd.h>
rhughes@241
     8
rhughes@241
     9
#include "razor-internal.h"
rhughes@241
    10
rhughes@241
    11
int
rhughes@241
    12
razor_create_dir(const char *root, const char *path)
rhughes@241
    13
{
rhughes@241
    14
	char buffer[PATH_MAX], *p;
rhughes@241
    15
	const char *slash, *next;
rhughes@241
    16
	struct stat buf;
rhughes@241
    17
rhughes@241
    18
	/* Create all sub-directories in dir. We know root exists and
rhughes@241
    19
	 * is a dir, root does not end in a '/', and path has a
rhughes@241
    20
	 * leading '/'. */
rhughes@241
    21
rhughes@241
    22
	strcpy(buffer, root);
rhughes@241
    23
	p = buffer + strlen(buffer);
rhughes@241
    24
	slash = path;
rhughes@241
    25
	for (slash = path; *slash != '\0'; slash = next) {
rhughes@241
    26
		next = strchr(slash + 1, '/');
rhughes@241
    27
		if (next == NULL)
rhughes@241
    28
			break;
rhughes@241
    29
rhughes@241
    30
		memcpy(p, slash, next - slash);
rhughes@241
    31
		p += next - slash;
rhughes@241
    32
		*p = '\0';
rhughes@241
    33
rhughes@241
    34
		if (stat(buffer, &buf) == 0) {
rhughes@241
    35
			if (!S_ISDIR(buf.st_mode)) {
rhughes@241
    36
				fprintf(stderr,
rhughes@241
    37
					"%s exists but is not a directory\n",
rhughes@241
    38
					buffer);
rhughes@241
    39
				return -1;
rhughes@241
    40
			}
rhughes@241
    41
		} else if (mkdir(buffer, 0777) < 0) {
rhughes@241
    42
			fprintf(stderr, "failed to make directory %s: %m\n",
rhughes@241
    43
				buffer);
rhughes@241
    44
			return -1;
rhughes@241
    45
		}
rhughes@241
    46
rhughes@241
    47
		/* FIXME: What to do about permissions for dirs we
rhughes@241
    48
		 * have to create but are not in the cpio archive? */
rhughes@241
    49
	}
rhughes@241
    50
rhughes@241
    51
	return 0;
rhughes@241
    52
}
rhughes@241
    53
rhughes@241
    54
int
rhughes@241
    55
razor_write(int fd, const void *data, size_t size)
rhughes@241
    56
{
rhughes@241
    57
	size_t rest;
rhughes@241
    58
	ssize_t written;
rhughes@241
    59
	const unsigned char *p;
rhughes@241
    60
rhughes@241
    61
	rest = size;
rhughes@241
    62
	p = data;
rhughes@241
    63
	while (rest > 0) {
rhughes@241
    64
		written = write(fd, p, rest);
rhughes@241
    65
		if (written < 0) {
rhughes@241
    66
			fprintf(stderr, "write error: %m\n");
rhughes@241
    67
			return -1;
rhughes@241
    68
		}
rhughes@241
    69
		rest -= written;
rhughes@241
    70
		p += written;
rhughes@241
    71
	}
rhughes@241
    72
rhughes@241
    73
	return 0;
rhughes@241
    74
}
rhughes@241
    75
rhughes@241
    76
struct qsort_context {
rhughes@241
    77
	size_t size;
rhughes@241
    78
	razor_compare_with_data_func_t compare;
rhughes@241
    79
	void *data;
rhughes@241
    80
};
rhughes@241
    81
rhughes@241
    82
static void
rhughes@241
    83
qsort_swap(void *p1, void *p2, size_t size)
rhughes@241
    84
{
rhughes@241
    85
	char buffer[size];
rhughes@241
    86
rhughes@241
    87
	memcpy(buffer, p1, size);
rhughes@241
    88
	memcpy(p1, p2, size);
rhughes@241
    89
	memcpy(p2, buffer, size);
rhughes@241
    90
}
rhughes@241
    91
rhughes@241
    92
static void
rhughes@241
    93
__qsort_with_data(void *base, size_t nelem, uint32_t *map,
rhughes@241
    94
		  struct qsort_context *ctx)
rhughes@241
    95
{
rhughes@241
    96
	void *p, *start, *end, *pivot;
rhughes@241
    97
	uint32_t *mp, *mstart, *mend, tmp;
rhughes@241
    98
	int left, right, result;
rhughes@241
    99
	size_t size = ctx->size;
rhughes@241
   100
rhughes@241
   101
	p = base;
rhughes@241
   102
	start = base;
rhughes@241
   103
	end = base + nelem * size;
rhughes@241
   104
	mp = map;
rhughes@241
   105
	mstart = map;
rhughes@241
   106
	mend = map + nelem;
rhughes@241
   107
	pivot = base + (random() % nelem) * size;
rhughes@241
   108
rhughes@241
   109
	while (p < end) {
rhughes@241
   110
		result = ctx->compare(p, pivot, ctx->data);
rhughes@241
   111
		if (result < 0) {
rhughes@241
   112
			qsort_swap(p, start, size);
rhughes@241
   113
			tmp = *mp;
rhughes@241
   114
			*mp = *mstart;
rhughes@241
   115
			*mstart = tmp;
rhughes@241
   116
			if (start == pivot)
rhughes@241
   117
				pivot = p;
rhughes@241
   118
			start += size;
rhughes@241
   119
			mstart++;
rhughes@241
   120
			p += size;
rhughes@241
   121
			mp++;
rhughes@241
   122
		} else if (result == 0) {
rhughes@241
   123
			p += size;
rhughes@241
   124
			mp++;
rhughes@241
   125
		} else {
rhughes@241
   126
 			end -= size;
rhughes@241
   127
			mend--;
rhughes@241
   128
			qsort_swap(p, end, size);
rhughes@241
   129
			tmp = *mp;
rhughes@241
   130
			*mp = *mend;
rhughes@241
   131
			*mend = tmp;
rhughes@241
   132
			if (end == pivot)
rhughes@241
   133
				pivot = p;
rhughes@241
   134
		}
rhughes@241
   135
	}
rhughes@241
   136
rhughes@241
   137
	left = (start - base) / size;
rhughes@241
   138
	right = (base + nelem * size - end) / size;
rhughes@241
   139
	if (left > 1)
rhughes@241
   140
		__qsort_with_data(base, left, map, ctx);
rhughes@241
   141
	if (right > 1)
rhughes@241
   142
		__qsort_with_data(end, right, mend, ctx);
rhughes@241
   143
}
rhughes@241
   144
rhughes@241
   145
uint32_t *
rhughes@241
   146
razor_qsort_with_data(void *base, size_t nelem, size_t size,
rhughes@241
   147
		      razor_compare_with_data_func_t compare, void *data)
rhughes@241
   148
{
rhughes@241
   149
	struct qsort_context ctx;
rhughes@241
   150
	uint32_t *map;
rhughes@241
   151
	int i;
rhughes@241
   152
rhughes@241
   153
	if (nelem == 0)
rhughes@241
   154
		return NULL;
rhughes@241
   155
rhughes@241
   156
	ctx.size = size;
rhughes@241
   157
	ctx.compare = compare;
rhughes@241
   158
	ctx.data = data;
rhughes@241
   159
rhughes@241
   160
	map = malloc(nelem * sizeof (uint32_t));
rhughes@241
   161
	for (i = 0; i < nelem; i++)
rhughes@241
   162
		map[i] = i;
rhughes@241
   163
rhughes@241
   164
	__qsort_with_data(base, nelem, map, &ctx);
rhughes@241
   165
rhughes@241
   166
	return map;
rhughes@241
   167
}