1 Index: klibc-1.5/usr/utils/losetup.c
2 ===================================================================
3 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
4 +++ klibc-1.5/usr/utils/losetup.c 2008-03-07 23:13:38.635692852 +0100
6 +/* Originally from Ted's losetup.c */
11 + * losetup.c - setup and control loop devices
21 +#include <sys/ioctl.h>
22 +#include <sys/stat.h>
23 +#include <sys/mman.h>
24 +#include <sys/sysmacros.h>
30 +extern char *progname;
31 +extern char *xstrdup (const char *s); /* not: #include "sundries.h" */
32 +extern void error (const char *fmt, ...); /* idem */
34 +/* caller guarantees n > 0 */
36 +xstrncpy(char *dest, const char *src, size_t n) {
37 + strncpy(dest, src, n-1);
43 +loop_info64_to_old(const struct loop_info64 *info64, struct loop_info *info)
45 + memset(info, 0, sizeof(*info));
46 + info->lo_number = info64->lo_number;
47 + info->lo_device = info64->lo_device;
48 + info->lo_inode = info64->lo_inode;
49 + info->lo_rdevice = info64->lo_rdevice;
50 + info->lo_offset = info64->lo_offset;
51 + info->lo_encrypt_type = info64->lo_encrypt_type;
52 + info->lo_encrypt_key_size = info64->lo_encrypt_key_size;
53 + info->lo_flags = info64->lo_flags;
54 + info->lo_init[0] = info64->lo_init[0];
55 + info->lo_init[1] = info64->lo_init[1];
56 + if (info->lo_encrypt_type == LO_CRYPT_CRYPTOAPI)
57 + memcpy(info->lo_name, info64->lo_crypt_name, LO_NAME_SIZE);
59 + memcpy(info->lo_name, info64->lo_file_name, LO_NAME_SIZE);
60 + memcpy(info->lo_encrypt_key, info64->lo_encrypt_key, LO_KEY_SIZE);
62 + /* error in case values were truncated */
63 + if (info->lo_device != info64->lo_device ||
64 + info->lo_rdevice != info64->lo_rdevice ||
65 + info->lo_inode != info64->lo_inode ||
66 + info->lo_offset != info64->lo_offset)
74 +show_loop(char *device) {
75 + struct loop_info loopinfo;
76 + struct loop_info64 loopinfo64;
79 + if ((fd = open(device, O_RDONLY)) < 0) {
81 + fprintf(stderr, "loop: can't open device %s: %s\n",
82 + device, strerror (errsv));
86 + if (ioctl(fd, LOOP_GET_STATUS64, &loopinfo64) == 0) {
88 + loopinfo64.lo_file_name[LO_NAME_SIZE-2] = '*';
89 + loopinfo64.lo_file_name[LO_NAME_SIZE-1] = 0;
90 + loopinfo64.lo_crypt_name[LO_NAME_SIZE-1] = 0;
92 + printf("%s: [%04llx]:%llu (%s)",
93 + device, loopinfo64.lo_device, loopinfo64.lo_inode,
94 + loopinfo64.lo_file_name);
96 + if (loopinfo64.lo_offset)
97 + printf(", offset %lld", loopinfo64.lo_offset);
99 + if (loopinfo64.lo_sizelimit)
100 + printf(", sizelimit %lld", loopinfo64.lo_sizelimit);
102 + if (loopinfo64.lo_encrypt_type ||
103 + loopinfo64.lo_crypt_name[0]) {
104 + char *e = loopinfo64.lo_crypt_name;
106 + if (*e == 0 && loopinfo64.lo_encrypt_type == 1)
108 + printf(", encryption %s (type %d)",
109 + e, loopinfo64.lo_encrypt_type);
116 + if (ioctl(fd, LOOP_GET_STATUS, &loopinfo) == 0) {
117 + printf ("%s: [%04x]:%ld (%s)",
118 + device, loopinfo.lo_device, loopinfo.lo_inode,
121 + if (loopinfo.lo_offset)
122 + printf(", offset %d", loopinfo.lo_offset);
124 + if (loopinfo.lo_encrypt_type)
125 + printf(", encryption type %d\n",
126 + loopinfo.lo_encrypt_type);
134 + fprintf(stderr, "loop: can't get info on device %s: %s\n",
135 + device, strerror (errsv));
141 +is_loop_device (const char *device) {
142 + struct stat statbuf;
144 + return (stat(device, &statbuf) == 0 &&
145 + S_ISBLK(statbuf.st_mode) &&
146 + major(statbuf.st_rdev) == LOOPMAJOR);
149 +#define SIZE(a) (sizeof(a)/sizeof(a[0]))
152 +find_unused_loop_device (void) {
153 + /* Just creating a device, say in /tmp, is probably a bad idea -
154 + people might have problems with backup or so.
155 + So, we just try /dev/loop[0-7]. */
157 + char *loop_formats[] = { "/dev/loop%d", "/dev/loop/%d" };
158 + int i, j, fd, somedev = 0, someloop = 0, permission = 0;
159 + struct stat statbuf;
160 + struct loop_info loopinfo;
162 + for (j = 0; j < SIZE(loop_formats); j++) {
163 + for(i = 0; i < 256; i++) {
164 + sprintf(dev, loop_formats[j], i);
165 + if (stat (dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) {
167 + fd = open (dev, O_RDONLY);
169 + if(ioctl (fd, LOOP_GET_STATUS, &loopinfo) == 0)
170 + someloop++; /* in use */
171 + else if (errno == ENXIO) {
173 + return xstrdup(dev);/* probably free */
176 + } else if (errno == EACCES)
179 + continue;/* continue trying as long as devices exist */
186 + error("%s: could not find any device /dev/loop#", progname);
187 + else if (!someloop && permission)
188 + error("%s: no permission to look at /dev/loop#", progname);
189 + else if (!someloop)
191 + "%s: Could not find any loop device. Maybe this kernel "
193 + " about the loop device? (If so, recompile or "
194 + "`modprobe loop'.)", progname);
196 + error("%s: could not find any free loop device", progname);
201 + * A function to read the passphrase either from the terminal or from
202 + * an open file descriptor.
205 +xgetpass(int pfd, const char *prompt) {
212 + if (i >= buflen-1) {
213 + /* we're running out of space in the buffer.
214 + * Make it bigger: */
215 + char *tmppass = pass;
217 + pass = realloc(tmppass, buflen);
218 + if (pass == NULL) {
219 + /* realloc failed. Stop reading. */
220 + error("Out of memory while reading passphrase");
221 + pass = tmppass; /* the old buffer hasn't changed */
225 + if (read(pfd, pass+i, 1) != 1 ||
226 + pass[i] == '\n' || pass[i] == 0)
238 +digits_only(const char *s) {
240 + if (!isdigit(*s++))
246 +set_loop(const char *device, const char *file, unsigned long long offset,
247 + const char *encryption, int pfd, int *loopro) {
248 + struct loop_info64 loopinfo64;
249 + int fd, ffd, mode, i;
252 + mode = (*loopro ? O_RDONLY : O_RDWR);
253 + if ((ffd = open(file, mode)) < 0) {
254 + if (!*loopro && errno == EROFS)
255 + ffd = open(file, mode = O_RDONLY);
261 + if ((fd = open(device, mode)) < 0) {
265 + *loopro = (mode == O_RDONLY);
267 + memset(&loopinfo64, 0, sizeof(loopinfo64));
269 + xstrncpy(loopinfo64.lo_file_name, file, LO_NAME_SIZE);
271 + if (encryption && *encryption) {
272 + if (digits_only(encryption)) {
273 + loopinfo64.lo_encrypt_type = atoi(encryption);
275 + loopinfo64.lo_encrypt_type = LO_CRYPT_CRYPTOAPI;
276 + snprintf(loopinfo64.lo_crypt_name, LO_NAME_SIZE,
281 + loopinfo64.lo_offset = offset;
284 + switch (loopinfo64.lo_encrypt_type) {
285 + case LO_CRYPT_NONE:
286 + loopinfo64.lo_encrypt_key_size = 0;
289 + pass = xgetpass(pfd, "Password: ");
292 + pass = xgetpass(pfd, "Password: ");
294 + memset(loopinfo64.lo_encrypt_key, 0, LO_KEY_SIZE);
295 + xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
296 + memset(pass, 0, strlen(pass));
297 + loopinfo64.lo_encrypt_key_size = LO_KEY_SIZE;
300 + if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
301 + perror("ioctl: LOOP_SET_FD");
306 + i = ioctl(fd, LOOP_SET_STATUS64, &loopinfo64);
308 + struct loop_info loopinfo;
311 + i = loop_info64_to_old(&loopinfo64, &loopinfo);
314 + perror("ioctl: LOOP_SET_STATUS64");
316 + i = ioctl(fd, LOOP_SET_STATUS, &loopinfo);
318 + perror("ioctl: LOOP_SET_STATUS");
320 + memset(&loopinfo, 0, sizeof(loopinfo));
322 + memset(&loopinfo64, 0, sizeof(loopinfo64));
325 + ioctl (fd, LOOP_CLR_FD, 0);
332 + printf("set_loop(%s,%s,%llu): success\n",
333 + device, file, offset);
338 +del_loop (const char *device) {
341 + if ((fd = open (device, O_RDONLY)) < 0) {
343 + fprintf(stderr, "loop: can't delete device %s: %s\n",
344 + device, strerror (errsv));
347 + if (ioctl (fd, LOOP_CLR_FD, 0) < 0) {
348 + perror ("ioctl: LOOP_CLR_FD");
353 + printf("del_loop(%s): success\n", device);
366 + fprintf(stderr, "usage:\n\
367 + %s loop_device # give info\n\
368 + %s -d loop_device # delete\n\
369 + %s -f # find unused\n\
370 + %s [-e encryption] [-o offset] {-f|loop_device} file # setup\n",
371 + progname, progname, progname, progname);
376 +xstrdup (const char *s) {
385 + fprintf(stderr, "not enough memory");
393 +error (const char *fmt, ...) {
396 + va_start (args, fmt);
397 + vfprintf (stderr, fmt, args);
399 + fprintf (stderr, "\n");
403 +main(int argc, char **argv) {
404 + char *p, *offset, *encryption, *passfd, *device, *file;
405 + int delete, find, c;
409 + unsigned long long off;
414 + offset = encryption = passfd = NULL;
416 + progname = argv[0];
417 + if ((p = strrchr(progname, '/')) != NULL)
420 + while ((c = getopt(argc, argv, "de:E:fo:p:v")) != -1) {
427 + encryption = optarg;
448 + } else if (delete) {
449 + if (argc != optind+1 || encryption || offset || find)
452 + if (argc < optind || argc > optind+1)
455 + if (argc < optind+1 || argc > optind+2)
460 + device = find_unused_loop_device();
461 + if (device == NULL)
464 + printf("Loop device is %s\n", device);
465 + if (argc == optind) {
466 + printf("%s\n", device);
469 + file = argv[optind];
471 + device = argv[optind];
472 + if (argc == optind+1)
475 + file = argv[optind+1];
479 + res = del_loop(device);
480 + else if (file == NULL)
481 + res = show_loop(device);
483 + if (offset && sscanf(offset, "%llu", &off) != 1)
485 + if (passfd && sscanf(passfd, "%d", &pfd) != 1)
487 + res = set_loop(device, file, off, encryption, pfd, &ro);
491 Index: klibc-1.5/usr/utils/loop.h
492 ===================================================================
493 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
494 +++ klibc-1.5/usr/utils/loop.h 2008-03-07 23:01:49.336694297 +0100
496 +#define LO_CRYPT_NONE 0
497 +#define LO_CRYPT_XOR 1
498 +#define LO_CRYPT_DES 2
499 +#define LO_CRYPT_CRYPTOAPI 18
501 +#define LOOP_SET_FD 0x4C00
502 +#define LOOP_CLR_FD 0x4C01
503 +#define LOOP_SET_STATUS 0x4C02
504 +#define LOOP_GET_STATUS 0x4C03
505 +#define LOOP_SET_STATUS64 0x4C04
506 +#define LOOP_GET_STATUS64 0x4C05
508 +#define LO_NAME_SIZE 64
509 +#define LO_KEY_SIZE 32
511 +#include "my_dev_t.h"
515 + my_dev_t lo_device;
516 + unsigned long lo_inode;
517 + my_dev_t lo_rdevice;
519 + int lo_encrypt_type;
520 + int lo_encrypt_key_size;
522 + char lo_name[LO_NAME_SIZE];
523 + unsigned char lo_encrypt_key[LO_KEY_SIZE];
524 + unsigned long lo_init[2];
529 + * Where to get __u8, __u32, __u64? Let us use unsigned char/int/long long
530 + * and get punished when someone comes with 128-bit long longs.
532 +struct loop_info64 {
533 + unsigned long long lo_device;
534 + unsigned long long lo_inode;
535 + unsigned long long lo_rdevice;
536 + unsigned long long lo_offset;
537 + unsigned long long lo_sizelimit; /* bytes, 0 == max available */
538 + unsigned int lo_number;
539 + unsigned int lo_encrypt_type;
540 + unsigned int lo_encrypt_key_size;
541 + unsigned int lo_flags;
542 + unsigned char lo_file_name[LO_NAME_SIZE];
543 + unsigned char lo_crypt_name[LO_NAME_SIZE];
544 + unsigned char lo_encrypt_key[LO_KEY_SIZE];
545 + unsigned long long lo_init[2];
547 Index: klibc-1.5/usr/utils/my_dev_t.h
548 ===================================================================
549 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
550 +++ klibc-1.5/usr/utils/my_dev_t.h 2008-03-07 23:03:45.148693283 +0100
552 +/* silliness to get dev_t defined as the kernel defines it */
553 +/* glibc uses a different dev_t */
555 +#include <linux/posix_types.h>
556 +#include <linux/version.h>
558 +#ifndef KERNEL_VERSION
559 +#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
562 +#if LINUX_VERSION_CODE < KERNEL_VERSION(1,3,78)
563 +/* for i386 - alpha uses unsigned int */
564 +#define my_dev_t unsigned short
566 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68)
567 +#define my_dev_t __kernel_dev_t
569 +#define my_dev_t __kernel_old_dev_t