Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 284957 | Differences between
and this patch

Collapse All | Expand All

(-)klibc-1.5.15/usr/utils/Kbuild_orig (-1 / +3 lines)
Lines 4-10 Link Here
4
4
5
progs := chroot dd mkdir mkfifo mknod mount pivot_root umount
5
progs := chroot dd mkdir mkfifo mknod mount pivot_root umount
6
progs += true false sleep ln nuke minips cat
6
progs += true false sleep ln nuke minips cat
7
progs += uname halt kill readlink cpio sync dmesg
7
progs += uname halt kill readlink cpio sync dmesg losetup
8
8
9
static-y := $(addprefix static/, $(progs))
9
static-y := $(addprefix static/, $(progs))
10
shared-y := $(addprefix shared/, $(progs))
10
shared-y := $(addprefix shared/, $(progs))
Lines 54-59 Link Here
54
shared/cpio-y       := cpio.o
54
shared/cpio-y       := cpio.o
55
static/sync-y       := sync.o
55
static/sync-y       := sync.o
56
shared/sync-y       := sync.o
56
shared/sync-y       := sync.o
57
static/losetup-y    := losetup.o
58
shared/losetup-y    := losetup.o
57
59
58
# Additionally linked targets
60
# Additionally linked targets
59
always := static/reboot static/poweroff shared/reboot shared/poweroff
61
always := static/reboot static/poweroff shared/reboot shared/poweroff
(-)klibc-1.5/usr/utils/losetup.c (+485 lines)
Added Link Here
1
/* Originally from Ted's losetup.c */
2
3
#define LOOPMAJOR	7
4
5
/*
6
 * losetup.c - setup and control loop devices
7
 */
8
9
#include <stdio.h>
10
#include <string.h>
11
#include <ctype.h>
12
#include <fcntl.h>
13
#include <errno.h>
14
#include <stdlib.h>
15
#include <unistd.h>
16
#include <sys/ioctl.h>
17
#include <sys/stat.h>
18
#include <sys/mman.h>
19
#include <sys/sysmacros.h>
20
#include <string.h>
21
22
#include "loop.h"
23
24
extern int verbose;
25
extern char *progname;
26
extern char *xstrdup (const char *s);	/* not: #include "sundries.h" */
27
extern void error (const char *fmt, ...);	/* idem */
28
29
/* caller guarantees n > 0 */
30
void
31
xstrncpy(char *dest, const char *src, size_t n) {
32
        strncpy(dest, src, n-1);
33
        dest[n-1] = 0;
34
}
35
36
37
static int
38
loop_info64_to_old(const struct loop_info64 *info64, struct loop_info *info)
39
{
40
        memset(info, 0, sizeof(*info));
41
        info->lo_number = info64->lo_number;
42
        info->lo_device = info64->lo_device;
43
        info->lo_inode = info64->lo_inode;
44
        info->lo_rdevice = info64->lo_rdevice;
45
        info->lo_offset = info64->lo_offset;
46
        info->lo_encrypt_type = info64->lo_encrypt_type;
47
        info->lo_encrypt_key_size = info64->lo_encrypt_key_size;
48
        info->lo_flags = info64->lo_flags;
49
        info->lo_init[0] = info64->lo_init[0];
50
        info->lo_init[1] = info64->lo_init[1];
51
        if (info->lo_encrypt_type == LO_CRYPT_CRYPTOAPI)
52
                memcpy(info->lo_name, info64->lo_crypt_name, LO_NAME_SIZE);
53
        else
54
                memcpy(info->lo_name, info64->lo_file_name, LO_NAME_SIZE);
55
        memcpy(info->lo_encrypt_key, info64->lo_encrypt_key, LO_KEY_SIZE);
56
57
        /* error in case values were truncated */
58
        if (info->lo_device != info64->lo_device ||
59
            info->lo_rdevice != info64->lo_rdevice ||
60
            info->lo_inode != info64->lo_inode ||
61
            info->lo_offset != info64->lo_offset)
62
                return -EOVERFLOW;
63
64
        return 0;
65
}
66
67
68
static int
69
show_loop(char *device) {
70
	struct loop_info loopinfo;
71
	struct loop_info64 loopinfo64;
72
	int fd, errsv;
73
74
	if ((fd = open(device, O_RDONLY)) < 0) {
75
		int errsv = errno;
76
		fprintf(stderr, "loop: can't open device %s: %s\n",
77
			device, strerror (errsv));
78
		return 2;
79
	}
80
81
	if (ioctl(fd, LOOP_GET_STATUS64, &loopinfo64) == 0) {
82
83
		loopinfo64.lo_file_name[LO_NAME_SIZE-2] = '*';
84
		loopinfo64.lo_file_name[LO_NAME_SIZE-1] = 0;
85
		loopinfo64.lo_crypt_name[LO_NAME_SIZE-1] = 0;
86
87
		printf("%s: [%04llx]:%llu (%s)",
88
		       device, loopinfo64.lo_device, loopinfo64.lo_inode,
89
		       loopinfo64.lo_file_name);
90
91
		if (loopinfo64.lo_offset)
92
			printf(", offset %lld", loopinfo64.lo_offset);
93
94
		if (loopinfo64.lo_sizelimit)
95
			printf(", sizelimit %lld", loopinfo64.lo_sizelimit);
96
97
		if (loopinfo64.lo_encrypt_type ||
98
		    loopinfo64.lo_crypt_name[0]) {
99
			char *e = loopinfo64.lo_crypt_name;
100
101
			if (*e == 0 && loopinfo64.lo_encrypt_type == 1)
102
				e = "XOR";
103
			printf(", encryption %s (type %d)",
104
			       e, loopinfo64.lo_encrypt_type);
105
		}
106
		printf("\n");
107
		close (fd);
108
		return 0;
109
	}
110
111
	if (ioctl(fd, LOOP_GET_STATUS, &loopinfo) == 0) {
112
		printf ("%s: [%04x]:%ld (%s)",
113
			device, loopinfo.lo_device, loopinfo.lo_inode,
114
			loopinfo.lo_name);
115
116
		if (loopinfo.lo_offset)
117
			printf(", offset %d", loopinfo.lo_offset);
118
119
		if (loopinfo.lo_encrypt_type)
120
			printf(", encryption type %d\n",
121
			       loopinfo.lo_encrypt_type);
122
123
		printf("\n");
124
		close (fd);
125
		return 0;
126
	}
127
128
	errsv = errno;
129
	fprintf(stderr, "loop: can't get info on device %s: %s\n",
130
		device, strerror (errsv));
131
	close (fd);
132
	return 1;
133
}
134
135
int
136
is_loop_device (const char *device) {
137
	struct stat statbuf;
138
139
	return (stat(device, &statbuf) == 0 &&
140
		S_ISBLK(statbuf.st_mode) &&
141
		major(statbuf.st_rdev) == LOOPMAJOR);
142
}
143
144
#define SIZE(a) (sizeof(a)/sizeof(a[0]))
145
146
char *
147
find_unused_loop_device (void) {
148
	/* Just creating a device, say in /tmp, is probably a bad idea -
149
	   people might have problems with backup or so.
150
	   So, we just try /dev/loop[0-7]. */
151
	char dev[20];
152
	char *loop_formats[] = { "/dev/loop%d", "/dev/loop/%d" };
153
	int i, j, fd, somedev = 0, someloop = 0, permission = 0;
154
	struct stat statbuf;
155
	struct loop_info loopinfo;
156
157
	for (j = 0; j < SIZE(loop_formats); j++) {
158
	    for(i = 0; i < 256; i++) {
159
		sprintf(dev, loop_formats[j], i);
160
		if (stat (dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) {
161
			somedev++;
162
			fd = open (dev, O_RDONLY);
163
			if (fd >= 0) {
164
				if(ioctl (fd, LOOP_GET_STATUS, &loopinfo) == 0)
165
					someloop++;		/* in use */
166
				else if (errno == ENXIO) {
167
					close (fd);
168
					return xstrdup(dev);/* probably free */
169
				}
170
				close (fd);
171
			} else if (errno == EACCES)
172
				permission++;
173
174
			continue;/* continue trying as long as devices exist */
175
		}
176
		break;
177
	    }
178
	}
179
180
	if (!somedev)
181
		error("%s: could not find any device /dev/loop#", progname);
182
	else if (!someloop && permission)
183
		error("%s: no permission to look at /dev/loop#", progname);
184
	else if (!someloop)
185
		error(
186
		    "%s: Could not find any loop device. Maybe this kernel "
187
		    "does not know\n"
188
		    "       about the loop device? (If so, recompile or "
189
		    "`modprobe loop'.)", progname);
190
	else
191
		error("%s: could not find any free loop device", progname);
192
	return 0;
193
}
194
195
/*
196
 * A function to read the passphrase either from the terminal or from
197
 * an open file descriptor.
198
 */
199
static char *
200
xgetpass(int pfd, const char *prompt) {
201
	char *pass;
202
	int buflen, i;
203
204
	pass = NULL;
205
	buflen = 0;
206
	for (i=0; ; i++) {
207
		if (i >= buflen-1) {
208
				/* we're running out of space in the buffer.
209
				 * Make it bigger: */
210
			char *tmppass = pass;
211
			buflen += 128;
212
			pass = realloc(tmppass, buflen);
213
			if (pass == NULL) {
214
				/* realloc failed. Stop reading. */
215
				error("Out of memory while reading passphrase");
216
				pass = tmppass; /* the old buffer hasn't changed */
217
				break;
218
			}
219
		}
220
		if (read(pfd, pass+i, 1) != 1 ||
221
		    pass[i] == '\n' || pass[i] == 0)
222
			break;
223
	}
224
225
	if (pass == NULL)
226
		return "";
227
228
	pass[i] = 0;
229
	return pass;
230
}
231
232
static int
233
digits_only(const char *s) {
234
	while (*s)
235
		if (!isdigit(*s++))
236
			return 0;
237
	return 1;
238
}
239
240
int
241
set_loop(const char *device, const char *file, unsigned long long offset,
242
	 const char *encryption, int pfd, int *loopro) {
243
	struct loop_info64 loopinfo64;
244
	int fd, ffd, mode, i;
245
	char *pass;
246
247
	mode = (*loopro ? O_RDONLY : O_RDWR);
248
	if ((ffd = open(file, mode)) < 0) {
249
		if (!*loopro && errno == EROFS)
250
			ffd = open(file, mode = O_RDONLY);
251
		if (ffd < 0) {
252
			perror(file);
253
			return 1;
254
		}
255
	}
256
	if ((fd = open(device, mode)) < 0) {
257
		perror (device);
258
		return 1;
259
	}
260
	*loopro = (mode == O_RDONLY);
261
262
	memset(&loopinfo64, 0, sizeof(loopinfo64));
263
264
	xstrncpy(loopinfo64.lo_file_name, file, LO_NAME_SIZE);
265
266
	if (encryption && *encryption) {
267
		if (digits_only(encryption)) {
268
			loopinfo64.lo_encrypt_type = atoi(encryption);
269
		} else {
270
			loopinfo64.lo_encrypt_type = LO_CRYPT_CRYPTOAPI;
271
			snprintf(loopinfo64.lo_crypt_name, LO_NAME_SIZE,
272
				 "%s", encryption);
273
		}
274
	}
275
276
	loopinfo64.lo_offset = offset;
277
278
279
	switch (loopinfo64.lo_encrypt_type) {
280
	case LO_CRYPT_NONE:
281
		loopinfo64.lo_encrypt_key_size = 0;
282
		break;
283
	case LO_CRYPT_XOR:
284
		pass = xgetpass(pfd, "Password: ");
285
		goto gotpass;
286
	default:
287
		pass = xgetpass(pfd, "Password: ");
288
	gotpass:
289
		memset(loopinfo64.lo_encrypt_key, 0, LO_KEY_SIZE);
290
		xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
291
		memset(pass, 0, strlen(pass));
292
		loopinfo64.lo_encrypt_key_size = LO_KEY_SIZE;
293
	}
294
295
	if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
296
		perror("ioctl: LOOP_SET_FD");
297
		return 1;
298
	}
299
	close (ffd);
300
301
	i = ioctl(fd, LOOP_SET_STATUS64, &loopinfo64);
302
	if (i) {
303
		struct loop_info loopinfo;
304
		int errsv = errno;
305
306
		i = loop_info64_to_old(&loopinfo64, &loopinfo);
307
		if (i) {
308
			errno = errsv;
309
			perror("ioctl: LOOP_SET_STATUS64");
310
		} else {
311
			i = ioctl(fd, LOOP_SET_STATUS, &loopinfo);
312
			if (i)
313
				perror("ioctl: LOOP_SET_STATUS");
314
		}
315
		memset(&loopinfo, 0, sizeof(loopinfo));
316
	}
317
	memset(&loopinfo64, 0, sizeof(loopinfo64));
318
319
	if (i) {
320
		ioctl (fd, LOOP_CLR_FD, 0);
321
		close (fd);
322
		return 1;
323
	}
324
	close (fd);
325
326
	if (verbose > 1)
327
		printf("set_loop(%s,%s,%llu): success\n",
328
		       device, file, offset);
329
	return 0;
330
}
331
332
int
333
del_loop (const char *device) {
334
	int fd;
335
336
	if ((fd = open (device, O_RDONLY)) < 0) {
337
		int errsv = errno;
338
		fprintf(stderr, "loop: can't delete device %s: %s\n",
339
			device, strerror (errsv));
340
		return 1;
341
	}
342
	if (ioctl (fd, LOOP_CLR_FD, 0) < 0) {
343
		perror ("ioctl: LOOP_CLR_FD");
344
		return 1;
345
	}
346
	close (fd);
347
	if (verbose > 1)
348
		printf("del_loop(%s): success\n", device);
349
	return 0;
350
}
351
352
353
#include <getopt.h>
354
#include <stdarg.h>
355
356
int verbose = 0;
357
char *progname;
358
359
static void
360
usage(void) {
361
	fprintf(stderr, "usage:\n\
362
  %s loop_device                                       # give info\n\
363
  %s -d loop_device                                    # delete\n\
364
  %s -f                                                # find unused\n\
365
  %s [-e encryption] [-o offset] {-f|loop_device} file # setup\n",
366
		progname, progname, progname, progname);
367
	exit(1);
368
}
369
370
char *
371
xstrdup (const char *s) {
372
	char *t;
373
374
	if (s == NULL)
375
		return NULL;
376
377
	t = strdup (s);
378
379
	if (t == NULL) {
380
		fprintf(stderr, "not enough memory");
381
		exit(1);
382
	}
383
384
	return t;
385
}
386
387
void
388
error (const char *fmt, ...) {
389
	va_list args;
390
391
	va_start (args, fmt);
392
	vfprintf (stderr, fmt, args);
393
	va_end (args);
394
	fprintf (stderr, "\n");
395
}
396
397
int
398
main(int argc, char **argv) {
399
	char *p, *offset, *encryption, *passfd, *device, *file;
400
	int delete, find, c;
401
	int res = 0;
402
	int ro = 0;
403
	int pfd = -1;
404
	unsigned long long off;
405
406
407
	delete = find = 0;
408
	off = 0;
409
	offset = encryption = passfd = NULL;
410
411
	progname = argv[0];
412
	if ((p = strrchr(progname, '/')) != NULL)
413
		progname = p+1;
414
415
	while ((c = getopt(argc, argv, "de:E:fo:p:v")) != -1) {
416
		switch (c) {
417
		case 'd':
418
			delete = 1;
419
			break;
420
		case 'E':
421
		case 'e':
422
			encryption = optarg;
423
			break;
424
		case 'f':
425
			find = 1;
426
			break;
427
		case 'o':
428
			offset = optarg;
429
			break;
430
		case 'p':
431
			passfd = optarg;
432
			break;
433
		case 'v':
434
			verbose = 1;
435
			break;
436
		default:
437
			usage();
438
		}
439
	}
440
441
	if (argc == 1) {
442
		usage();
443
	} else if (delete) {
444
		if (argc != optind+1 || encryption || offset || find)
445
			usage();
446
	} else if (find) {
447
		if (argc < optind || argc > optind+1)
448
			usage();
449
	} else {
450
		if (argc < optind+1 || argc > optind+2)
451
			usage();
452
	}
453
454
	if (find) {
455
		device = find_unused_loop_device();
456
		if (device == NULL)
457
			return -1;
458
		if (verbose)
459
			printf("Loop device is %s\n", device);
460
		if (argc == optind) {
461
			printf("%s\n", device);
462
			return 0;
463
		}
464
		file = argv[optind];
465
	} else {
466
		device = argv[optind];
467
		if (argc == optind+1)
468
			file = NULL;
469
		else
470
			file = argv[optind+1];
471
	}
472
473
	if (delete)
474
		res = del_loop(device);
475
	else if (file == NULL)
476
		res = show_loop(device);
477
	else {
478
		if (offset && sscanf(offset, "%llu", &off) != 1)
479
			usage();
480
		if (passfd && sscanf(passfd, "%d", &pfd) != 1)
481
			usage();
482
		res = set_loop(device, file, off, encryption, pfd, &ro);
483
	}
484
	return res;
485
}
(-)klibc-1.5/usr/utils/loop.h (+51 lines)
Added Link Here
1
#define LO_CRYPT_NONE	0
2
#define LO_CRYPT_XOR	1
3
#define LO_CRYPT_DES	2
4
#define LO_CRYPT_CRYPTOAPI 18
5
6
#define LOOP_SET_FD		0x4C00
7
#define LOOP_CLR_FD		0x4C01
8
#define LOOP_SET_STATUS		0x4C02
9
#define LOOP_GET_STATUS		0x4C03
10
#define LOOP_SET_STATUS64	0x4C04
11
#define LOOP_GET_STATUS64	0x4C05
12
13
#define LO_NAME_SIZE	64
14
#define LO_KEY_SIZE	32
15
16
#include "my_dev_t.h"
17
18
struct loop_info {
19
	int		lo_number;
20
	my_dev_t	lo_device;
21
	unsigned long	lo_inode;
22
	my_dev_t	lo_rdevice;
23
	int		lo_offset;
24
	int		lo_encrypt_type;
25
	int		lo_encrypt_key_size;
26
	int		lo_flags;
27
	char		lo_name[LO_NAME_SIZE];
28
	unsigned char	lo_encrypt_key[LO_KEY_SIZE];
29
	unsigned long	lo_init[2];
30
	char		reserved[4];
31
};
32
33
/*
34
 * Where to get __u8, __u32, __u64? Let us use unsigned char/int/long long
35
 * and get punished when someone comes with 128-bit long longs.
36
 */
37
struct loop_info64 {
38
	unsigned long long	lo_device;
39
	unsigned long long	lo_inode;
40
	unsigned long long	lo_rdevice;
41
	unsigned long long	lo_offset;
42
	unsigned long long	lo_sizelimit; /* bytes, 0 == max available */
43
	unsigned int		lo_number;
44
	unsigned int		lo_encrypt_type;
45
	unsigned int		lo_encrypt_key_size;
46
	unsigned int		lo_flags;
47
	unsigned char		lo_file_name[LO_NAME_SIZE];
48
	unsigned char		lo_crypt_name[LO_NAME_SIZE];
49
	unsigned char		lo_encrypt_key[LO_KEY_SIZE];
50
	unsigned long long	lo_init[2];
51
};
(-)klibc-1.5/usr/utils/my_dev_t.h (+20 lines)
Added Link Here
1
/* silliness to get dev_t defined as the kernel defines it */
2
/* glibc uses a different dev_t */
3
4
#include <linux/posix_types.h>
5
#include <linux/version.h>
6
7
#ifndef KERNEL_VERSION
8
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
9
#endif
10
11
#if LINUX_VERSION_CODE < KERNEL_VERSION(1,3,78)
12
/* for i386 - alpha uses unsigned int */
13
#define my_dev_t unsigned short
14
#else
15
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68)
16
#define my_dev_t __kernel_dev_t
17
#else
18
#define my_dev_t __kernel_old_dev_t
19
#endif
20
#endif

Return to bug 284957