librazor/util.c
author Kristian H?gsberg <krh@redhat.com>
Tue Jul 08 22:57:34 2008 -0400 (2008-07-08)
changeset 317 019a53b65271
parent 241 c3eb520e2219
child 322 66c281524c98
permissions -rw-r--r--
Convert main.c to use razor_root for most cases.

With this we change the default repo location to /var/lib/razor, but let the env
variable RAZOR_ROOT override it.
richard@300
     1
/*
richard@300
     2
 * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
richard@300
     3
 * Copyright (C) 2008  Red Hat, Inc
richard@300
     4
 *
richard@300
     5
 * This program is free software; you can redistribute it and/or modify
richard@300
     6
 * it under the terms of the GNU General Public License as published by
richard@300
     7
 * the Free Software Foundation; either version 2 of the License, or
richard@300
     8
 * (at your option) any later version.
richard@300
     9
 *
richard@300
    10
 * This program is distributed in the hope that it will be useful,
richard@300
    11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
richard@300
    12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
richard@300
    13
 * GNU General Public License for more details.
richard@300
    14
 *
richard@300
    15
 * You should have received a copy of the GNU General Public License along
richard@300
    16
 * with this program; if not, write to the Free Software Foundation, Inc.,
richard@300
    17
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
richard@300
    18
 */
richard@300
    19
rhughes@241
    20
#include <limits.h>
rhughes@241
    21
#include <string.h>
rhughes@241
    22
#include <sys/stat.h>
rhughes@241
    23
#include <stdlib.h>
rhughes@241
    24
#include <stdio.h>
rhughes@241
    25
#include <stdint.h>
rhughes@241
    26
#include <unistd.h>
rhughes@241
    27
rhughes@241
    28
#include "razor-internal.h"
rhughes@241
    29
rhughes@241
    30
int
rhughes@241
    31
razor_create_dir(const char *root, const char *path)
rhughes@241
    32
{
rhughes@241
    33
	char buffer[PATH_MAX], *p;
rhughes@241
    34
	const char *slash, *next;
rhughes@241
    35
	struct stat buf;
rhughes@241
    36
rhughes@241
    37
	/* Create all sub-directories in dir. We know root exists and
rhughes@241
    38
	 * is a dir, root does not end in a '/', and path has a
rhughes@241
    39
	 * leading '/'. */
rhughes@241
    40
rhughes@241
    41
	strcpy(buffer, root);
rhughes@241
    42
	p = buffer + strlen(buffer);
rhughes@241
    43
	slash = path;
rhughes@241
    44
	for (slash = path; *slash != '\0'; slash = next) {
rhughes@241
    45
		next = strchr(slash + 1, '/');
rhughes@241
    46
		if (next == NULL)
rhughes@241
    47
			break;
rhughes@241
    48
rhughes@241
    49
		memcpy(p, slash, next - slash);
rhughes@241
    50
		p += next - slash;
rhughes@241
    51
		*p = '\0';
rhughes@241
    52
rhughes@241
    53
		if (stat(buffer, &buf) == 0) {
rhughes@241
    54
			if (!S_ISDIR(buf.st_mode)) {
rhughes@241
    55
				fprintf(stderr,
rhughes@241
    56
					"%s exists but is not a directory\n",
rhughes@241
    57
					buffer);
rhughes@241
    58
				return -1;
rhughes@241
    59
			}
rhughes@241
    60
		} else if (mkdir(buffer, 0777) < 0) {
rhughes@241
    61
			fprintf(stderr, "failed to make directory %s: %m\n",
rhughes@241
    62
				buffer);
rhughes@241
    63
			return -1;
rhughes@241
    64
		}
rhughes@241
    65
rhughes@241
    66
		/* FIXME: What to do about permissions for dirs we
rhughes@241
    67
		 * have to create but are not in the cpio archive? */
rhughes@241
    68
	}
rhughes@241
    69
rhughes@241
    70
	return 0;
rhughes@241
    71
}
rhughes@241
    72
rhughes@241
    73
int
rhughes@241
    74
razor_write(int fd, const void *data, size_t size)
rhughes@241
    75
{
rhughes@241
    76
	size_t rest;
rhughes@241
    77
	ssize_t written;
rhughes@241
    78
	const unsigned char *p;
rhughes@241
    79
rhughes@241
    80
	rest = size;
rhughes@241
    81
	p = data;
rhughes@241
    82
	while (rest > 0) {
rhughes@241
    83
		written = write(fd, p, rest);
rhughes@241
    84
		if (written < 0) {
rhughes@241
    85
			fprintf(stderr, "write error: %m\n");
rhughes@241
    86
			return -1;
rhughes@241
    87
		}
rhughes@241
    88
		rest -= written;
rhughes@241
    89
		p += written;
rhughes@241
    90
	}
rhughes@241
    91
rhughes@241
    92
	return 0;
rhughes@241
    93
}
rhughes@241
    94
rhughes@241
    95
struct qsort_context {
rhughes@241
    96
	size_t size;
rhughes@241
    97
	razor_compare_with_data_func_t compare;
rhughes@241
    98
	void *data;
rhughes@241
    99
};
rhughes@241
   100
rhughes@241
   101
static void
rhughes@241
   102
qsort_swap(void *p1, void *p2, size_t size)
rhughes@241
   103
{
rhughes@241
   104
	char buffer[size];
rhughes@241
   105
rhughes@241
   106
	memcpy(buffer, p1, size);
rhughes@241
   107
	memcpy(p1, p2, size);
rhughes@241
   108
	memcpy(p2, buffer, size);
rhughes@241
   109
}
rhughes@241
   110
rhughes@241
   111
static void
rhughes@241
   112
__qsort_with_data(void *base, size_t nelem, uint32_t *map,
rhughes@241
   113
		  struct qsort_context *ctx)
rhughes@241
   114
{
rhughes@241
   115
	void *p, *start, *end, *pivot;
rhughes@241
   116
	uint32_t *mp, *mstart, *mend, tmp;
rhughes@241
   117
	int left, right, result;
rhughes@241
   118
	size_t size = ctx->size;
rhughes@241
   119
rhughes@241
   120
	p = base;
rhughes@241
   121
	start = base;
rhughes@241
   122
	end = base + nelem * size;
rhughes@241
   123
	mp = map;
rhughes@241
   124
	mstart = map;
rhughes@241
   125
	mend = map + nelem;
rhughes@241
   126
	pivot = base + (random() % nelem) * size;
rhughes@241
   127
rhughes@241
   128
	while (p < end) {
rhughes@241
   129
		result = ctx->compare(p, pivot, ctx->data);
rhughes@241
   130
		if (result < 0) {
rhughes@241
   131
			qsort_swap(p, start, size);
rhughes@241
   132
			tmp = *mp;
rhughes@241
   133
			*mp = *mstart;
rhughes@241
   134
			*mstart = tmp;
rhughes@241
   135
			if (start == pivot)
rhughes@241
   136
				pivot = p;
rhughes@241
   137
			start += size;
rhughes@241
   138
			mstart++;
rhughes@241
   139
			p += size;
rhughes@241
   140
			mp++;
rhughes@241
   141
		} else if (result == 0) {
rhughes@241
   142
			p += size;
rhughes@241
   143
			mp++;
rhughes@241
   144
		} else {
rhughes@241
   145
 			end -= size;
rhughes@241
   146
			mend--;
rhughes@241
   147
			qsort_swap(p, end, size);
rhughes@241
   148
			tmp = *mp;
rhughes@241
   149
			*mp = *mend;
rhughes@241
   150
			*mend = tmp;
rhughes@241
   151
			if (end == pivot)
rhughes@241
   152
				pivot = p;
rhughes@241
   153
		}
rhughes@241
   154
	}
rhughes@241
   155
rhughes@241
   156
	left = (start - base) / size;
rhughes@241
   157
	right = (base + nelem * size - end) / size;
rhughes@241
   158
	if (left > 1)
rhughes@241
   159
		__qsort_with_data(base, left, map, ctx);
rhughes@241
   160
	if (right > 1)
rhughes@241
   161
		__qsort_with_data(end, right, mend, ctx);
rhughes@241
   162
}
rhughes@241
   163
rhughes@241
   164
uint32_t *
rhughes@241
   165
razor_qsort_with_data(void *base, size_t nelem, size_t size,
rhughes@241
   166
		      razor_compare_with_data_func_t compare, void *data)
rhughes@241
   167
{
rhughes@241
   168
	struct qsort_context ctx;
rhughes@241
   169
	uint32_t *map;
rhughes@241
   170
	int i;
rhughes@241
   171
rhughes@241
   172
	if (nelem == 0)
rhughes@241
   173
		return NULL;
rhughes@241
   174
rhughes@241
   175
	ctx.size = size;
rhughes@241
   176
	ctx.compare = compare;
rhughes@241
   177
	ctx.data = data;
rhughes@241
   178
rhughes@241
   179
	map = malloc(nelem * sizeof (uint32_t));
rhughes@241
   180
	for (i = 0; i < nelem; i++)
rhughes@241
   181
		map[i] = i;
rhughes@241
   182
rhughes@241
   183
	__qsort_with_data(base, nelem, map, &ctx);
rhughes@241
   184
rhughes@241
   185
	return map;
rhughes@241
   186
}