krh@91: #include krh@91: #include krh@91: #include krh@91: #include krh@91: #include krh@186: #include krh@91: #include krh@91: danw@136: #include "razor-internal.h" danw@136: krh@91: int krh@91: razor_create_dir(const char *root, const char *path) krh@91: { krh@91: char buffer[PATH_MAX], *p; krh@91: const char *slash, *next; krh@91: struct stat buf; krh@91: krh@91: /* Create all sub-directories in dir and then create name. We krh@91: * know root exists and is a dir, root does not end in a '/', krh@91: * and path has a leading '/'. */ krh@91: krh@91: strcpy(buffer, root); krh@91: p = buffer + strlen(buffer); krh@91: slash = path; krh@149: for (slash = path; *slash != '\0'; slash = next) { krh@91: next = strchr(slash + 1, '/'); krh@149: if (next == NULL) krh@149: next = slash + strlen(slash); krh@149: krh@91: memcpy(p, slash, next - slash); krh@91: p += next - slash; krh@91: *p = '\0'; krh@91: krh@91: if (stat(buffer, &buf) == 0) { krh@91: if (!S_ISDIR(buf.st_mode)) { krh@91: fprintf(stderr, krh@91: "%s exists but is not a directory\n", krh@91: buffer); krh@91: return -1; krh@91: } krh@91: } else if (mkdir(buffer, 0777) < 0) { krh@91: fprintf(stderr, "failed to make directory %s: %m\n", krh@91: buffer); krh@91: return -1; krh@91: } krh@91: krh@91: /* FIXME: What to do about permissions for dirs we krh@91: * have to create but are not in the cpio archive? */ krh@91: } krh@91: krh@91: return 0; krh@91: } krh@91: krh@91: int krh@91: razor_write(int fd, const void *data, size_t size) krh@91: { krh@91: size_t rest; krh@91: ssize_t written; krh@91: const unsigned char *p; krh@91: krh@91: rest = size; krh@91: p = data; krh@91: while (rest > 0) { krh@91: written = write(fd, p, rest); krh@91: if (written < 0) { krh@91: fprintf(stderr, "write error: %m\n"); krh@91: return -1; krh@91: } krh@91: rest -= written; krh@91: p += written; krh@91: } krh@91: krh@91: return 0; krh@91: } krh@186: krh@186: struct qsort_context { krh@186: size_t size; krh@186: razor_compare_with_data_func_t compare; krh@186: void *data; krh@186: }; krh@186: krh@186: static void krh@186: qsort_swap(void *p1, void *p2, size_t size) krh@186: { krh@186: char buffer[size]; krh@186: krh@186: memcpy(buffer, p1, size); krh@186: memcpy(p1, p2, size); krh@186: memcpy(p2, buffer, size); krh@186: } krh@186: krh@186: static void krh@186: __qsort_with_data(void *base, size_t nelem, uint32_t *map, krh@186: struct qsort_context *ctx) krh@186: { krh@186: void *p, *start, *end, *pivot; krh@186: uint32_t *mp, *mstart, *mend, tmp; krh@186: int left, right, result; krh@186: size_t size = ctx->size; krh@186: krh@186: p = base; krh@186: start = base; krh@186: end = base + nelem * size; krh@186: mp = map; krh@186: mstart = map; krh@186: mend = map + nelem; krh@186: pivot = base + (random() % nelem) * size; krh@186: krh@186: while (p < end) { krh@186: result = ctx->compare(p, pivot, ctx->data); krh@186: if (result < 0) { krh@186: qsort_swap(p, start, size); krh@186: tmp = *mp; krh@186: *mp = *mstart; krh@186: *mstart = tmp; krh@186: if (start == pivot) krh@186: pivot = p; krh@186: start += size; krh@186: mstart++; krh@186: p += size; krh@186: mp++; krh@186: } else if (result == 0) { krh@186: p += size; krh@186: mp++; krh@186: } else { krh@186: end -= size; krh@186: mend--; krh@186: qsort_swap(p, end, size); krh@186: tmp = *mp; krh@186: *mp = *mend; krh@186: *mend = tmp; krh@186: if (end == pivot) krh@186: pivot = p; krh@186: } krh@186: } krh@186: krh@186: left = (start - base) / size; krh@186: right = (base + nelem * size - end) / size; krh@186: if (left > 1) krh@186: __qsort_with_data(base, left, map, ctx); krh@186: if (right > 1) krh@186: __qsort_with_data(end, right, mend, ctx); krh@186: } krh@186: krh@186: uint32_t * krh@186: razor_qsort_with_data(void *base, size_t nelem, size_t size, krh@186: razor_compare_with_data_func_t compare, void *data) krh@186: { krh@186: struct qsort_context ctx; krh@186: uint32_t *map; krh@186: int i; krh@186: krh@186: if (nelem == 0) krh@186: return NULL; krh@186: krh@186: ctx.size = size; krh@186: ctx.compare = compare; krh@186: ctx.data = data; krh@186: krh@186: map = malloc(nelem * sizeof (uint32_t)); krh@186: for (i = 0; i < nelem; i++) krh@186: map[i] = i; krh@186: krh@186: __qsort_with_data(base, nelem, map, &ctx); krh@186: krh@186: return map; krh@186: }