1 /* Originally from Ted's losetup.c */
3 * losetup.c - setup and control loop devices
12 #include <sys/ioctl.h>
15 #include <sys/sysmacros.h>
25 #include "pathnames.h"
29 static int is_associated(int dev, struct stat *file, unsigned long long offset, int isoff);
32 loop_info64_to_old(const struct loop_info64 *info64, struct loop_info *info)
34 memset(info, 0, sizeof(*info));
35 info->lo_number = info64->lo_number;
36 info->lo_device = info64->lo_device;
37 info->lo_inode = info64->lo_inode;
38 info->lo_rdevice = info64->lo_rdevice;
39 info->lo_offset = info64->lo_offset;
40 info->lo_encrypt_type = info64->lo_encrypt_type;
41 info->lo_encrypt_key_size = info64->lo_encrypt_key_size;
42 info->lo_flags = info64->lo_flags;
43 info->lo_init[0] = info64->lo_init[0];
44 info->lo_init[1] = info64->lo_init[1];
45 if (info->lo_encrypt_type == LO_CRYPT_CRYPTOAPI)
46 memcpy(info->lo_name, info64->lo_crypt_name, LO_NAME_SIZE);
48 memcpy(info->lo_name, info64->lo_file_name, LO_NAME_SIZE);
49 memcpy(info->lo_encrypt_key, info64->lo_encrypt_key, LO_KEY_SIZE);
51 /* error in case values were truncated */
52 if (info->lo_device != info64->lo_device ||
53 info->lo_rdevice != info64->lo_rdevice ||
54 info->lo_inode != info64->lo_inode ||
55 info->lo_offset < 0 ||
56 (uint64_t) info->lo_offset != info64->lo_offset)
63 #define NLOOPS_DEFAULT 8 /* /dev/loop[0-7] */
66 int flag; /* scanning options */
67 FILE *proc; /* /proc/partitions */
68 int ncur; /* current position */
69 int *minors; /* ary of minor numbers (when scan whole /dev) */
70 int nminors; /* number of items in *minors */
71 char name[128]; /* device name */
72 int ct_perm; /* count permission problems */
73 int ct_succ; /* count number of successfully
77 #define LLFLG_USEDONLY (1 << 1) /* return used devices only */
78 #define LLFLG_FREEONLY (1 << 2) /* return non-used devices */
79 #define LLFLG_DONE (1 << 3) /* all is done */
80 #define LLFLG_PROCFS (1 << 4) /* try to found used devices in /proc/partitions */
81 #define LLFLG_SUBDIR (1 << 5) /* /dev/loop/N */
82 #define LLFLG_DFLT (1 << 6) /* directly try to check default loops */
84 /* TODO: move to lib/sysfs.c */
85 static char *loopfile_from_sysfs(const char *device)
89 char buf[PATH_MAX], *res = NULL;
91 if (stat(device, &st) || !S_ISBLK(st.st_mode))
94 snprintf(buf, sizeof(buf), _PATH_SYS_DEVBLOCK "/%d:%d/loop/backing_file",
95 major(st.st_rdev), minor(st.st_rdev));
101 if (fgets(buf, sizeof(buf), f)) {
102 size_t sz = strlen(buf);
113 char *loopdev_get_loopfile(const char *device)
115 char *res = loopfile_from_sysfs(device);
119 struct loop_info64 lo64;
122 if ((fd = open(device, O_RDONLY)) < 0)
125 if (ioctl(fd, LOOP_GET_STATUS64, &lo64) == 0) {
126 lo64.lo_file_name[LO_NAME_SIZE-2] = '*';
127 lo64.lo_file_name[LO_NAME_SIZE-1] = 0;
128 res = xstrdup((char *) lo64.lo_file_name);
130 } else if (ioctl(fd, LOOP_GET_STATUS, &lo) == 0) {
131 lo.lo_name[LO_NAME_SIZE-2] = '*';
132 lo.lo_name[LO_NAME_SIZE-1] = 0;
133 res = xstrdup((char *) lo.lo_name);
141 is_loop_device (const char *device) {
144 return (stat(device, &st) == 0 &&
145 S_ISBLK(st.st_mode) &&
146 major(st.st_rdev) == LOOPMAJOR);
155 if (ioctl (fd, LOOP_GET_STATUS, &li) < 0 && errno == ENXIO)
161 is_loopfd_autoclear(int fd)
164 struct loop_info64 lo64;
166 if (ioctl(fd, LOOP_GET_STATUS64, &lo64) == 0) {
167 if (lo64.lo_flags & LO_FLAGS_AUTOCLEAR)
170 } else if (ioctl(fd, LOOP_GET_STATUS, &lo) == 0) {
171 if (lo.lo_flags & LO_FLAGS_AUTOCLEAR)
178 is_loop_autoclear(const char *device)
182 if ((fd = open(device, O_RDONLY)) < 0)
184 rc = is_loopfd_autoclear(fd);
191 looplist_open(struct looplist *ll, int flag)
195 memset(ll, 0, sizeof(*ll));
199 if (stat(_PATH_DEV, &st) == -1 || (!S_ISDIR(st.st_mode)))
200 return -1; /* /dev doesn't exist */
202 if (stat(_PATH_DEV_LOOP, &st) == 0 && S_ISDIR(st.st_mode))
203 ll->flag |= LLFLG_SUBDIR; /* /dev/loop/ exists */
205 if ((ll->flag & LLFLG_USEDONLY) &&
206 stat(_PATH_PROC_PARTITIONS, &st) == 0)
207 ll->flag |= LLFLG_PROCFS; /* try /proc/partitions */
209 ll->flag |= LLFLG_DFLT; /* required! */
214 looplist_close(struct looplist *ll)
222 ll->flag |= LLFLG_DONE;
226 looplist_open_dev(struct looplist *ll, int lnum)
232 /* create a full device path */
233 snprintf(ll->name, sizeof(ll->name),
234 ll->flag & LLFLG_SUBDIR ?
235 _PATH_DEV_LOOP "/%d" :
239 fd = open(ll->name, O_RDONLY);
245 if (fstat(fd, &st) == -1)
247 if (!S_ISBLK(st.st_mode) || major(st.st_rdev) != LOOPMAJOR)
252 /* check if the device is wanted */
253 if (!(ll->flag & (LLFLG_USEDONLY | LLFLG_FREEONLY)))
256 used = is_loop_used(fd);
258 if ((ll->flag & LLFLG_USEDONLY) && used)
260 if ((ll->flag & LLFLG_FREEONLY) && !used)
267 /* returns <N> from "loop<N>" */
269 name2minor(int hasprefix, const char *name)
275 if (strncmp(name, "loop", 4))
279 n = strtol(name, &end, 10);
280 if (end && end != name && *end == '\0' && n >= 0)
286 cmpnum(const void *p1, const void *p2)
288 return (*(int *) p1 > *(int *) p2) - (*(int *) p1 < *(int *) p2);
292 * The classic scandir() is more expensive and less portable.
293 * We needn't full loop device names -- minor numbers (loop<N>)
297 loop_scandir(const char *dirname, int **ary, int hasprefix)
301 int n, count = 0, arylen = 0;
303 if (!dirname || !ary)
305 dir = opendir(dirname);
311 while((d = readdir(dir))) {
312 if (d->d_type != DT_BLK && d->d_type != DT_UNKNOWN && d->d_type != DT_LNK)
314 n = name2minor(hasprefix, d->d_name);
315 if (n == -1 || n < NLOOPS_DEFAULT)
317 if (count + 1 > arylen) {
322 tmp = realloc(*ary, arylen * sizeof(int));
332 qsort(*ary, count, sizeof(int), cmpnum);
339 looplist_next(struct looplist *ll)
343 if (ll->flag & LLFLG_DONE)
346 /* A) Look for used loop devices in /proc/partitions ("losetup -a" only)
348 if (ll->flag & LLFLG_PROCFS) {
352 ll->proc = fopen(_PATH_PROC_PARTITIONS, "r");
354 while (ll->proc && fgets(buf, sizeof(buf), ll->proc)) {
356 unsigned long long sz;
359 if (sscanf(buf, " %d %d %llu %128[^\n ]",
360 &m, &n, &sz, name) != 4)
364 /* unfortunately, real minor numbers needn't to match
365 * loop<N> device name. We have to follow device name.
367 n = name2minor(1, name);
368 fd = looplist_open_dev(ll, n);
376 /* B) Classic way, try first eight loop devices (default number
377 * of loop devices). This is enough for 99% of all cases.
379 if (ll->flag & LLFLG_DFLT) {
380 for (++ll->ncur; ll->ncur < NLOOPS_DEFAULT; ll->ncur++) {
381 fd = looplist_open_dev(ll, ll->ncur);
385 ll->flag &= ~LLFLG_DFLT;
388 /* C) the worst possibility, scan all /dev or /dev/loop
391 ll->nminors = (ll->flag & LLFLG_SUBDIR) ?
392 loop_scandir(_PATH_DEV_LOOP, &ll->minors, 0) :
393 loop_scandir(_PATH_DEV, &ll->minors, 1);
396 for (++ll->ncur; ll->ncur < ll->nminors; ll->ncur++) {
397 fd = looplist_open_dev(ll, ll->minors[ll->ncur]);
407 /* Find loop device associated with given @filename. Used for unmounting loop
408 * device specified by associated backing file.
410 * returns: 1 no such device/error
411 * 2 more than one loop device associated with @filename
412 * 0 exactly one loop device associated with @filename
413 * (@loopdev points to string containing full device name)
416 find_loopdev_by_backing_file(const char *filename, char **loopdev)
419 struct stat filestat;
421 int devs_n = 0; /* number of loop devices found */
422 char* devname = NULL;
424 if (stat(filename, &filestat) == -1) {
429 if (looplist_open(&ll, LLFLG_USEDONLY) == -1) {
430 error(_("%s: /dev directory does not exist."), progname);
434 while((devs_n < 2) && (fd = looplist_next(&ll)) != -1) {
435 if (is_associated(fd, &filestat, 0, 0) == 1) {
437 devname = xstrdup(ll.name);
446 return 0; /* exactly one loopdev */
449 return devs_n ? 2 : 1; /* more loopdevs or error */
455 set_capacity(const char *device)
458 int fd = open(device, O_RDONLY);
463 if (ioctl(fd, LOOP_SET_CAPACITY) != 0)
469 fprintf(stderr, _("loop: can't set capacity on device %s: %s\n"),
470 device, strerror (errsv));
477 show_loop_fd(int fd, char *device) {
478 struct loop_info loopinfo;
479 struct loop_info64 loopinfo64;
482 if (ioctl(fd, LOOP_GET_STATUS64, &loopinfo64) == 0) {
486 loopinfo64.lo_file_name[LO_NAME_SIZE-2] = '*';
487 loopinfo64.lo_file_name[LO_NAME_SIZE-1] = 0;
488 loopinfo64.lo_crypt_name[LO_NAME_SIZE-1] = 0;
490 /* ioctl has limited buffer for backing file name, since
491 * kernel 2.6.37 the filename is available in sysfs too
493 if (strlen((char *) loopinfo64.lo_file_name) == LO_NAME_SIZE - 1)
494 lofile = loopfile_from_sysfs(device);
496 lofile = (char *) loopinfo64.lo_file_name;
498 printf("%s: [%04" PRIx64 "]:%" PRIu64 " (%s)",
499 device, loopinfo64.lo_device, loopinfo64.lo_inode,
502 if (lofile != (char *) loopinfo64.lo_file_name)
505 if (loopinfo64.lo_offset)
506 printf(_(", offset %" PRIu64 ), loopinfo64.lo_offset);
508 if (loopinfo64.lo_sizelimit)
509 printf(_(", sizelimit %" PRIu64 ), loopinfo64.lo_sizelimit);
511 if (loopinfo64.lo_encrypt_type ||
512 loopinfo64.lo_crypt_name[0]) {
513 char *e = (char *)loopinfo64.lo_crypt_name;
515 if (*e == 0 && loopinfo64.lo_encrypt_type == 1)
517 printf(_(", encryption %s (type %" PRIu32 ")"),
518 e, loopinfo64.lo_encrypt_type);
524 if (ioctl(fd, LOOP_GET_STATUS, &loopinfo) == 0) {
525 printf ("%s: [%04x]:%ld (%s)",
526 device, (unsigned int)loopinfo.lo_device, loopinfo.lo_inode,
529 if (loopinfo.lo_offset)
530 printf(_(", offset %d"), loopinfo.lo_offset);
532 if (loopinfo.lo_encrypt_type)
533 printf(_(", encryption type %d\n"),
534 loopinfo.lo_encrypt_type);
541 fprintf(stderr, _("loop: can't get info on device %s: %s\n"),
542 device, strerror (errsv));
547 show_loop(char *device) {
550 if ((fd = open(device, O_RDONLY)) < 0) {
552 fprintf(stderr, _("loop: can't open device %s: %s\n"),
553 device, strerror (errsv));
556 ret = show_loop_fd(fd, device);
563 show_used_loop_devices (void) {
567 if (looplist_open(&ll, LLFLG_USEDONLY) == -1) {
568 error(_("%s: /dev directory does not exist."), progname);
572 while((fd = looplist_next(&ll)) != -1) {
573 show_loop_fd(fd, ll.name);
578 if (!ll.ct_succ && ll.ct_perm) {
579 error(_("%s: no permission to look at /dev/loop%s<N>"), progname,
580 (ll.flag & LLFLG_SUBDIR) ? "/" : "");
586 /* list all associated loop devices */
588 show_associated_loop_devices(char *filename, unsigned long long offset, int isoff)
591 struct stat filestat;
594 if (stat(filename, &filestat) == -1) {
599 if (looplist_open(&ll, LLFLG_USEDONLY) == -1) {
600 error(_("%s: /dev directory does not exist."), progname);
604 while((fd = looplist_next(&ll)) != -1) {
605 if (is_associated(fd, &filestat, offset, isoff) == 1)
606 show_loop_fd(fd, ll.name);
617 /* check if the loopfile is already associated with the same given
620 * returns: 0 unused / error
621 * 1 loop device already used
624 is_associated(int dev, struct stat *file, unsigned long long offset, int isoff)
626 struct loop_info64 linfo64;
627 struct loop_info64 linfo;
630 if (ioctl(dev, LOOP_GET_STATUS64, &linfo64) == 0) {
631 if (file->st_dev == linfo64.lo_device &&
632 file->st_ino == linfo64.lo_inode &&
633 (isoff == 0 || offset == linfo64.lo_offset))
636 } else if (ioctl(dev, LOOP_GET_STATUS, &linfo) == 0) {
637 if (file->st_dev == linfo.lo_device &&
638 file->st_ino == linfo.lo_inode &&
639 (isoff == 0 || offset == linfo.lo_offset))
646 /* check if the loop file is already used with the same given
647 * parameters. We check for device no, inode and offset.
648 * returns: associated devname or NULL
651 loopfile_used (const char *filename, unsigned long long offset) {
653 char *devname = NULL;
654 struct stat filestat;
657 if (stat(filename, &filestat) == -1) {
662 if (looplist_open(&ll, LLFLG_USEDONLY) == -1) {
663 error(_("%s: /dev directory does not exist."), progname);
667 while((fd = looplist_next(&ll)) != -1) {
668 int res = is_associated(fd, &filestat, offset, 1);
671 devname = xstrdup(ll.name);
681 loopfile_used_with(char *devname, const char *filename, unsigned long long offset)
686 if (!is_loop_device(devname))
689 if (stat(filename, &statbuf) == -1)
692 fd = open(devname, O_RDONLY);
696 ret = is_associated(fd, &statbuf, offset, 1);
702 find_unused_loop_device (void) {
704 char *devname = NULL;
707 if (looplist_open(&ll, LLFLG_FREEONLY) == -1) {
708 error(_("%s: /dev directory does not exist."), progname);
712 if ((fd = looplist_next(&ll)) != -1) {
714 devname = xstrdup(ll.name);
720 if (!ll.ct_succ && ll.ct_perm)
721 error(_("%s: no permission to look at /dev/loop%s<N>"), progname,
722 (ll.flag & LLFLG_SUBDIR) ? "/" : "");
724 error(_("%s: could not find any free loop device"), progname);
727 "%s: Could not find any loop device. Maybe this kernel "
729 " about the loop device? (If so, recompile or "
730 "`modprobe loop'.)"), progname);
735 * A function to read the passphrase either from the terminal or from
736 * an open file descriptor.
739 xgetpass(int pfd, const char *prompt) {
743 if (pfd < 0) /* terminal */
744 return getpass(prompt);
750 /* we're running out of space in the buffer.
752 char *tmppass = pass;
754 pass = realloc(tmppass, buflen);
756 /* realloc failed. Stop reading. */
757 error(_("Out of memory while reading passphrase"));
758 pass = tmppass; /* the old buffer hasn't changed */
762 if (read(pfd, pass+i, 1) != 1 ||
763 pass[i] == '\n' || pass[i] == 0)
775 digits_only(const char *s) {
789 set_loop(const char *device, const char *file, unsigned long long offset,
790 unsigned long long sizelimit, const char *encryption, int pfd, int *options) {
791 struct loop_info64 loopinfo64;
792 int fd, ffd, mode, i;
797 char *xdev = loopfile_used(file, offset);
800 printf(_("warning: %s is already associated with %s\n"),
806 mode = (*options & SETLOOP_RDONLY) ? O_RDONLY : O_RDWR;
807 if ((ffd = open(file, mode)) < 0) {
808 if (!(*options & SETLOOP_RDONLY) &&
809 (errno == EROFS || errno == EACCES))
810 ffd = open(file, mode = O_RDONLY);
816 printf(_("warning: %s: is write-protected, using read-only.\n"),
818 *options |= SETLOOP_RDONLY;
820 if ((fd = open(device, mode)) < 0) {
825 memset(&loopinfo64, 0, sizeof(loopinfo64));
827 if (!(filename = canonicalize(file)))
828 filename = (char *) file;
829 xstrncpy((char *)loopinfo64.lo_file_name, filename, LO_NAME_SIZE);
831 if (encryption && *encryption) {
832 if (digits_only(encryption)) {
833 loopinfo64.lo_encrypt_type = atoi(encryption);
835 loopinfo64.lo_encrypt_type = LO_CRYPT_CRYPTOAPI;
836 snprintf((char *)loopinfo64.lo_crypt_name, LO_NAME_SIZE,
841 loopinfo64.lo_offset = offset;
842 loopinfo64.lo_sizelimit = sizelimit;
846 * Oh-oh, sensitive data coming up. Better lock into memory to prevent
847 * passwd etc being swapped out and left somewhere on disk.
849 if (loopinfo64.lo_encrypt_type != LO_CRYPT_NONE) {
850 if(mlockall(MCL_CURRENT | MCL_FUTURE)) {
852 fprintf(stderr, _("Couldn't lock into memory, exiting.\n"));
858 switch (loopinfo64.lo_encrypt_type) {
860 loopinfo64.lo_encrypt_key_size = 0;
863 pass = getpass(_("Password: "));
866 pass = xgetpass(pfd, _("Password: "));
868 memset(loopinfo64.lo_encrypt_key, 0, LO_KEY_SIZE);
869 xstrncpy((char *)loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
870 memset(pass, 0, strlen(pass));
871 loopinfo64.lo_encrypt_key_size = LO_KEY_SIZE;
874 if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
877 if (errno == EBUSY) {
879 printf(_("ioctl LOOP_SET_FD failed: %s\n"),
883 perror("ioctl: LOOP_SET_FD");
887 if (file != filename)
893 if (*options & SETLOOP_AUTOCLEAR)
894 loopinfo64.lo_flags = LO_FLAGS_AUTOCLEAR;
896 i = ioctl(fd, LOOP_SET_STATUS64, &loopinfo64);
898 struct loop_info loopinfo;
901 i = loop_info64_to_old(&loopinfo64, &loopinfo);
904 *options &= ~SETLOOP_AUTOCLEAR;
905 perror("ioctl: LOOP_SET_STATUS64");
907 i = ioctl(fd, LOOP_SET_STATUS, &loopinfo);
909 perror("ioctl: LOOP_SET_STATUS");
911 memset(&loopinfo, 0, sizeof(loopinfo));
914 if ((*options & SETLOOP_AUTOCLEAR) && !is_loopfd_autoclear(fd))
915 /* kernel doesn't support loop auto-destruction */
916 *options &= ~SETLOOP_AUTOCLEAR;
918 memset(&loopinfo64, 0, sizeof(loopinfo64));
921 ioctl (fd, LOOP_CLR_FD, 0);
923 if (file != filename)
929 * HACK: here we're leaking a file descriptor,
930 * but mount is a short-lived process anyway.
932 if (!(*options & SETLOOP_AUTOCLEAR))
936 printf(_("set_loop(%s,%s,%llu,%llu): success\n"),
937 device, filename, offset, sizelimit);
938 if (file != filename)
944 del_loop (const char *device) {
947 if ((fd = open (device, O_RDONLY)) < 0) {
951 if (ioctl (fd, LOOP_CLR_FD, 0) < 0) {
957 printf(_("del_loop(%s): success\n"), device);
961 fprintf(stderr, _("loop: can't delete device %s: %s\n"),
962 device, strerror(errsv));
968 #else /* no LOOP_SET_FD defined */
972 _("This mount was compiled without loop support. "
973 "Please recompile.\n"));
977 set_loop(const char *device, const char *file, unsigned long long offset,
978 unsigned long long sizelimit, const char *encryption, int pfd, int *loopro,
979 int keysz, int hash_pass) {
985 del_loop (const char *device) {
991 find_unused_loop_device (void) {
997 find_loopdev_by_backing_file(const char *filename, char **loopdev)
1003 #endif /* !LOOP_SET_FD */
1015 fputs(_("\nUsage:\n"), out);
1017 _(" %1$s loop_device give info\n"
1018 " %1$s -a | --all list all used\n"
1019 " %1$s -d | --detach <loopdev> [<loopdev> ...] delete\n"
1020 " %1$s -f | --find find unused\n"
1021 " %1$s -c | --set-capacity <loopdev> resize\n"
1022 " %1$s -j | --associated <file> [-o <num>] list all associated with <file>\n"
1023 " %1$s [options] {-f|--find|loopdev} <file> setup\n"),
1026 fputs(_("\nOptions:\n"), out);
1027 fputs(_(" -e, --encryption <type> enable data encryption with specified <name/num>\n"
1028 " -h, --help this help\n"
1029 " -o, --offset <num> start at offset <num> into file\n"
1030 " --sizelimit <num> loop limited to only <num> bytes of the file\n"
1031 " -p, --pass-fd <num> read passphrase from file descriptor <num>\n"
1032 " -r, --read-only setup read-only loop device\n"
1033 " --show print device name (with -f <file>)\n"
1034 " -v, --verbose verbose mode\n\n"), out);
1036 exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
1040 main(int argc, char **argv) {
1041 char *p, *offset, *sizelimit, *encryption, *passfd, *device, *file, *assoc;
1042 int delete, find, c, all, capacity;
1047 uintmax_t off = 0, slimit = 0;
1049 static const struct option longopts[] = {
1050 { "all", 0, 0, 'a' },
1051 { "set-capacity", 0, 0, 'c' },
1052 { "detach", 0, 0, 'd' },
1053 { "encryption", 1, 0, 'e' },
1054 { "find", 0, 0, 'f' },
1055 { "help", 0, 0, 'h' },
1056 { "associated", 1, 0, 'j' },
1057 { "offset", 1, 0, 'o' },
1058 { "sizelimit", 1, 0, 128 },
1059 { "pass-fd", 1, 0, 'p' },
1060 { "read-only", 0, 0, 'r' },
1061 { "show", 0, 0, 's' },
1062 { "verbose", 0, 0, 'v' },
1066 setlocale(LC_ALL, "");
1067 bindtextdomain(PACKAGE, LOCALEDIR);
1068 textdomain(PACKAGE);
1070 capacity = delete = find = all = 0;
1071 assoc = offset = sizelimit = encryption = passfd = NULL;
1074 if ((p = strrchr(progname, '/')) != NULL)
1077 while ((c = getopt_long(argc, argv, "acde:E:fhj:o:p:rsv",
1078 longopts, NULL)) != -1) {
1094 encryption = optarg;
1118 case 128: /* --sizelimit */
1129 } else if (delete) {
1130 if (argc < optind+1 || encryption || offset || sizelimit ||
1131 capacity || find || all || showdev || assoc || ro)
1134 if (capacity || all || assoc || argc < optind || argc > optind+1)
1137 /* only -v is allowed */
1138 if ((argc == 3 && verbose == 0) || argc > 3)
1141 if (capacity || encryption || showdev || passfd || ro)
1143 } else if (capacity) {
1144 if (argc != optind + 1 || encryption || offset || sizelimit ||
1148 if (argc < optind+1 || argc > optind+2)
1152 if (offset && strtosize(offset, &off)) {
1153 error(_("%s: invalid offset '%s' specified"), progname, offset);
1156 if (sizelimit && strtosize(sizelimit, &slimit)) {
1157 error(_("%s: invalid sizelimit '%s' specified"),
1158 progname, sizelimit);
1163 return show_used_loop_devices();
1165 return show_associated_loop_devices(assoc, off, offset ? 1 : 0);
1167 device = find_unused_loop_device();
1170 if (argc == optind) {
1172 printf(_("Loop device is %s\n"), device);
1173 printf("%s\n", device);
1176 file = argv[optind];
1177 } else if (!delete) {
1178 device = argv[optind];
1179 if (argc == optind+1)
1182 file = argv[optind+1];
1186 while (optind < argc)
1187 res += del_loop(argv[optind++]);
1188 } else if (capacity) {
1189 res = set_capacity(device);
1190 } else if (file == NULL)
1191 res = show_loop(device);
1193 if (passfd && sscanf(passfd, "%d", &pfd) != 1)
1196 res = set_loop(device, file, off, slimit, encryption, pfd, &ro);
1197 if (res == 2 && find) {
1199 printf(_("stolen loop=%s...trying again\n"),
1202 if (!(device = find_unused_loop_device()))
1205 } while (find && res == 2);
1209 error(_("%s: %s: device is busy"), progname, device);
1210 else if (res == 0) {
1212 printf(_("Loop device is %s\n"), device);
1213 if (showdev && find)
1214 printf("%s\n", device);
1221 #else /* LOOP_SET_FD not defined */
1224 main(int argc, char **argv) {
1226 _("No loop support was available at compile time. "
1227 "Please recompile.\n"));
1230 #endif /* !LOOP_SET_FD*/