blob: 3873be399b37b296e2cfe89f02965bb0dbf209e2 [file] [log] [blame]
"Robert P. J. Day"63fc1a92006-07-02 19:47:05 +00001/* vi: set sw=4 ts=4: */
Matt Kraai83788da2002-03-20 17:38:37 +00002/*
3 * Mini losetup implementation for busybox
4 *
5 * Copyright (C) 2002 Matt Kraai.
6 *
Bernhard Reutner-Fischer4a1865c2006-01-13 18:11:59 +00007 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
Matt Kraai83788da2002-03-20 17:38:37 +00008 */
9
Denis Vlasenkob6adbf12007-05-26 19:00:18 +000010#include "libbb.h"
Matt Kraai83788da2002-03-20 17:38:37 +000011
Denis Vlasenko9b49a5e2007-10-11 10:05:36 +000012int losetup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
Denys Vlasenko92510142010-05-19 00:39:17 +020013int losetup_main(int argc UNUSED_PARAM, char **argv)
Matt Kraai83788da2002-03-20 17:38:37 +000014{
Denis Vlasenko67b23e62006-10-03 21:00:06 +000015 unsigned opt;
Denys Vlasenko92510142010-05-19 00:39:17 +020016 int n;
Denis Vlasenko27ee7ba2006-09-22 14:53:41 +000017 char *opt_o;
Denis Vlasenko13858992006-10-08 12:49:22 +000018 unsigned long long offset = 0;
Denys Vlasenko92510142010-05-19 00:39:17 +020019 enum {
20 OPT_d = (1 << 0),
21 OPT_o = (1 << 1),
22 OPT_f = (1 << 2),
23 };
Matt Kraai83788da2002-03-20 17:38:37 +000024
Bernhard Reutner-Fischer1d4cd602008-07-21 15:29:36 +000025 /* max 2 args, all opts are mutually exclusive */
Pascal Bellardb82b34e2010-06-07 01:16:45 +020026 opt_complementary = "?2:d--of:o--df:f--do";
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000027 opt = getopt32(argv, "do:f", &opt_o);
Denis Vlasenko27ee7ba2006-09-22 14:53:41 +000028 argv += optind;
Matt Kraai83788da2002-03-20 17:38:37 +000029
Denys Vlasenko92510142010-05-19 00:39:17 +020030 if (opt == OPT_o)
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000031 offset = xatoull(opt_o);
32
Denys Vlasenko92510142010-05-19 00:39:17 +020033 if (opt == OPT_d) {
34 /* -d BLOCKDEV */
35 if (!argv[0] || argv[1])
Denis Vlasenko27ee7ba2006-09-22 14:53:41 +000036 bb_show_usage();
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000037 if (del_loop(argv[0]))
Denis Vlasenko94e33652007-12-22 15:44:23 +000038 bb_simple_perror_msg_and_die(argv[0]);
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000039 return EXIT_SUCCESS;
Denis Vlasenko27ee7ba2006-09-22 14:53:41 +000040 }
41
Denys Vlasenko92510142010-05-19 00:39:17 +020042 if (argv[0]) {
43 char *s;
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000044
Denys Vlasenko92510142010-05-19 00:39:17 +020045 if (opt == OPT_f) /* -f should not have arguments */
46 bb_show_usage();
47
48 if (argv[1]) {
49 /* [-o OFS] BLOCKDEV FILE */
50 if (set_loop(&argv[0], argv[1], offset) < 0)
51 bb_simple_perror_msg_and_die(argv[0]);
52 return EXIT_SUCCESS;
53 }
54 /* [-o OFS] BLOCKDEV */
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000055 s = query_loop(argv[0]);
Denis Vlasenkoc34d3552007-04-19 00:09:34 +000056 if (!s)
Denis Vlasenko94e33652007-12-22 15:44:23 +000057 bb_simple_perror_msg_and_die(argv[0]);
Denis Vlasenko27ee7ba2006-09-22 14:53:41 +000058 printf("%s: %s\n", argv[0], s);
Denis Vlasenkoc34d3552007-04-19 00:09:34 +000059 if (ENABLE_FEATURE_CLEAN_UP)
60 free(s);
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000061 return EXIT_SUCCESS;
62 }
63
Denys Vlasenko92510142010-05-19 00:39:17 +020064 /* [-o OFS|-f] with no params */
65 n = 0;
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000066 while (1) {
Denys Vlasenko92510142010-05-19 00:39:17 +020067 char *s;
Lauri Kasanen7c1b2b52010-07-04 00:04:03 +020068 char dev[LOOP_NAMESIZE];
Denys Vlasenko92510142010-05-19 00:39:17 +020069
Lauri Kasanen7c1b2b52010-07-04 00:04:03 +020070 sprintf(dev, LOOP_FORMAT, n);
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000071 s = query_loop(dev);
Denys Vlasenko92510142010-05-19 00:39:17 +020072 n++;
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000073 if (!s) {
Denys Vlasenko92510142010-05-19 00:39:17 +020074 if (n > 9 && errno && errno != ENXIO)
75 return EXIT_SUCCESS;
76 if (opt == OPT_f) {
Denis Vlasenkofeb7ae72007-10-01 12:05:12 +000077 puts(dev);
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000078 return EXIT_SUCCESS;
Denis Vlasenko956a5692006-09-27 14:51:27 +000079 }
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000080 } else {
Denys Vlasenko92510142010-05-19 00:39:17 +020081 if (opt != OPT_f)
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000082 printf("%s: %s\n", dev, s);
83 if (ENABLE_FEATURE_CLEAN_UP)
84 free(s);
Denis Vlasenko956a5692006-09-27 14:51:27 +000085 }
86 }
Tim Rikerc1ef7bd2006-01-25 00:08:53 +000087 return EXIT_SUCCESS;
Matt Kraai83788da2002-03-20 17:38:37 +000088}