]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - mount/lomount.c
1 /* Taken from Ted's losetup.c - Mitch <m.dsouza@mrc-apu.cam.ac.uk> */
2 /* Added vfs mount options - aeb - 960223 */
3 /* Removed lomount - aeb - 960224 */
5 #define PROC_DEVICES "/proc/devices"
8 * losetup.c - setup and control loop devices
18 #include <sys/ioctl.h>
21 #if defined(__GLIBC__)
24 #include "sundries.h" /* for xstrdup */
29 struct crypt_type_struct
{
32 } crypt_type_tbl
[] = {
33 { LO_CRYPT_NONE
, "no" },
34 { LO_CRYPT_NONE
, "none" },
35 { LO_CRYPT_XOR
, "xor" },
36 { LO_CRYPT_DES
, "DES" },
41 crypt_type (const char *name
)
46 for (i
= 0; crypt_type_tbl
[i
].id
!= -1; i
++)
47 if (!strcasecmp (name
, crypt_type_tbl
[i
].name
))
48 return crypt_type_tbl
[i
].id
;
58 for (i
= 0; crypt_type_tbl
[i
].id
!= -1; i
++)
59 if (id
== crypt_type_tbl
[i
].id
)
60 return crypt_type_tbl
[i
].name
;
65 show_loop (char *device
)
67 struct loop_info loopinfo
;
70 if ((fd
= open (device
, O_RDONLY
)) < 0) {
71 fprintf(stderr
, "loop: can't open device %s: %s\n",
72 device
, strerror (errno
));
75 if (ioctl (fd
, LOOP_GET_STATUS
, &loopinfo
) < 0) {
76 fprintf(stderr
, "loop: can't get info on device %s: %s\n",
77 device
, strerror (errno
));
81 printf ("%s: [%04x]:%ld (%s) offset %d, %s encryption\n",
82 device
, loopinfo
.lo_device
, loopinfo
.lo_inode
,
83 loopinfo
.lo_name
, loopinfo
.lo_offset
,
84 crypt_name (loopinfo
.lo_encrypt_type
));
90 find_unused_loop_device (void)
92 /* Just creating a device, say in /tmp, is probably a bad idea -
93 people might have problems with backup or so.
94 So, we just try /dev/loop[0-7]. */
96 int i
, fd
, somedev
= 0, someloop
= 0, loop_known
= 0;
98 struct loop_info loopinfo
;
101 for(i
= 0; i
< 256; i
++) {
102 sprintf(dev
, "/dev/loop%d", i
);
103 if (stat (dev
, &statbuf
) == 0 && S_ISBLK(statbuf
.st_mode
)) {
105 fd
= open (dev
, O_RDONLY
);
107 if(ioctl (fd
, LOOP_GET_STATUS
, &loopinfo
) == 0)
108 someloop
++; /* in use */
109 else if (errno
== ENXIO
) {
111 return xstrdup(dev
); /* probably free */
115 continue; /* continue trying as long as devices exist */
121 /* Nothing found. Why not? */
122 if ((procdev
= fopen(PROC_DEVICES
, "r")) != NULL
) {
124 while (fgets (line
, sizeof(line
), procdev
))
125 if (strstr (line
, " loop\n")) {
135 error("mount: could not find any device /dev/loop#");
139 "mount: Could not find any loop device.\n"
140 " Maybe /dev/loop# has a wrong major number?\n");
141 else if (loop_known
== -1)
143 "mount: Could not find any loop device, and, according to %s,\n"
144 " this kernel does not know about the loop device.\n"
145 " (If so, then recompile or `insmod loop.o'.)\n", PROC_DEVICES
);
148 "mount: Could not find any loop device. Maybe this kernel does not know\n"
149 " about the loop device (then recompile or `insmod loop.o'), or\n"
150 " maybe /dev/loop# has the wrong major number?\n");
152 error("mount: could not find any free loop device");
157 set_loop (const char *device
, const char *file
, int offset
,
158 const char *encryption
, int *loopro
)
160 struct loop_info loopinfo
;
161 int fd
, ffd
, mode
, i
;
164 mode
= (*loopro
? O_RDONLY
: O_RDWR
);
165 if ((ffd
= open (file
, mode
)) < 0) {
166 if (!*loopro
&& errno
== EROFS
)
167 ffd
= open (file
, mode
= O_RDONLY
);
173 if ((fd
= open (device
, mode
)) < 0) {
177 *loopro
= (mode
== O_RDONLY
);
178 memset (&loopinfo
, 0, sizeof (loopinfo
));
179 strncpy (loopinfo
.lo_name
, file
, LO_NAME_SIZE
);
180 loopinfo
.lo_name
[LO_NAME_SIZE
- 1] = 0;
181 if (encryption
&& (loopinfo
.lo_encrypt_type
= crypt_type (encryption
))
183 fprintf (stderr
, "Unsupported encryption type %s", encryption
);
186 loopinfo
.lo_offset
= offset
;
187 switch (loopinfo
.lo_encrypt_type
) {
189 loopinfo
.lo_encrypt_key_size
= 0;
192 pass
= getpass ("Password: ");
193 strncpy (loopinfo
.lo_encrypt_key
, pass
, LO_KEY_SIZE
);
194 loopinfo
.lo_encrypt_key
[LO_KEY_SIZE
- 1] = 0;
195 loopinfo
.lo_encrypt_key_size
= strlen (loopinfo
.lo_encrypt_key
);
198 pass
= getpass ("Password: ");
199 strncpy (loopinfo
.lo_encrypt_key
, pass
, 8);
200 loopinfo
.lo_encrypt_key
[8] = 0;
201 loopinfo
.lo_encrypt_key_size
= 8;
202 pass
= getpass ("Init (up to 16 hex digits): ");
203 for (i
= 0; i
< 16 && pass
[i
]; i
++)
204 if (isxdigit (pass
[i
]))
205 loopinfo
.lo_init
[i
>> 3] |= (pass
[i
] > '9' ?
206 (islower (pass
[i
]) ? toupper (pass
[i
]) :
207 pass
[i
]) - 'A' + 10 : pass
[i
] - '0') << (i
& 7) * 4;
209 fprintf (stderr
, "Non-hex digit '%c'.\n", pass
[i
]);
215 "Don't know how to get key for encryption system %d\n",
216 loopinfo
.lo_encrypt_type
);
219 if (ioctl (fd
, LOOP_SET_FD
, ffd
) < 0) {
220 perror ("ioctl: LOOP_SET_FD");
223 if (ioctl (fd
, LOOP_SET_STATUS
, &loopinfo
) < 0) {
224 (void) ioctl (fd
, LOOP_CLR_FD
, 0);
225 perror ("ioctl: LOOP_SET_STATUS");
231 printf("set_loop(%s,%s,%d): success\n", device
, file
, offset
);
236 del_loop (const char *device
)
240 if ((fd
= open (device
, O_RDONLY
)) < 0) {
241 fprintf(stderr
, "loop: can't delete device %s: %s\n",
242 device
, strerror (errno
));
245 if (ioctl (fd
, LOOP_CLR_FD
, 0) < 0) {
246 perror ("ioctl: LOOP_CLR_FD");
251 printf("del_loop(%s): success\n", device
);
255 #else /* no LOOP_SET_FD defined */
259 "This mount was compiled without loop support. Please recompile.\n");
263 set_loop (const char *device
, const char *file
, int offset
,
264 const char *encryption
, int *loopro
) {
270 del_loop (const char *device
) {
276 find_unused_loop_device (void) {