blob: a9ecfd58b95ca556de737904469f284e187b61e0 [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
10#include <getopt.h>
Matt Kraai83788da2002-03-20 17:38:37 +000011
Denis Vlasenkob6adbf12007-05-26 19:00:18 +000012#include "libbb.h"
Matt Kraai83788da2002-03-20 17:38:37 +000013
Denis Vlasenko9b49a5e2007-10-11 10:05:36 +000014int losetup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
Denis Vlasenko27ee7ba2006-09-22 14:53:41 +000015int losetup_main(int argc, char **argv)
Matt Kraai83788da2002-03-20 17:38:37 +000016{
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000017 char dev[] = LOOP_NAME"0";
Denis Vlasenko67b23e62006-10-03 21:00:06 +000018 unsigned opt;
Denis Vlasenko27ee7ba2006-09-22 14:53:41 +000019 char *opt_o;
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000020 char *s;
Denis Vlasenko13858992006-10-08 12:49:22 +000021 unsigned long long offset = 0;
Matt Kraai83788da2002-03-20 17:38:37 +000022
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000023 /* max 2 args, all opts are mutially exclusive */
24 opt_complementary = "?2:d--of:o--df:f-do";
25 opt = getopt32(argv, "do:f", &opt_o);
Denis Vlasenko27ee7ba2006-09-22 14:53:41 +000026 argc -= optind;
27 argv += optind;
Matt Kraai83788da2002-03-20 17:38:37 +000028
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000029 if (opt == 0x2) // -o
30 offset = xatoull(opt_o);
31
32 if (opt == 0x4 && argc) // -f does not take any argument
Denis Vlasenko956a5692006-09-27 14:51:27 +000033 bb_show_usage();
Denis Vlasenko27ee7ba2006-09-22 14:53:41 +000034
35 if (opt == 0x1) { // -d
36 /* detach takes exactly one argument */
37 if (argc != 1)
38 bb_show_usage();
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000039 if (del_loop(argv[0]))
40 bb_perror_nomsg_and_die();
41 return EXIT_SUCCESS;
Denis Vlasenko27ee7ba2006-09-22 14:53:41 +000042 }
43
Denis Vlasenko27ee7ba2006-09-22 14:53:41 +000044 if (argc == 2) {
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000045 /* -o or no option */
Denis Vlasenko27ee7ba2006-09-22 14:53:41 +000046 if (set_loop(&argv[0], argv[1], offset) < 0)
47 bb_perror_nomsg_and_die();
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000048 return EXIT_SUCCESS;
49 }
50
51 if (argc == 1) {
52 /* -o or no option */
53 s = query_loop(argv[0]);
Denis Vlasenkoc34d3552007-04-19 00:09:34 +000054 if (!s)
55 bb_perror_nomsg_and_die();
Denis Vlasenko27ee7ba2006-09-22 14:53:41 +000056 printf("%s: %s\n", argv[0], s);
Denis Vlasenkoc34d3552007-04-19 00:09:34 +000057 if (ENABLE_FEATURE_CLEAN_UP)
58 free(s);
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000059 return EXIT_SUCCESS;
60 }
61
62 /* -o, -f or no option */
63 while (1) {
64 s = query_loop(dev);
65 if (!s) {
66 if (opt == 0x4) {
Denis Vlasenkofeb7ae72007-10-01 12:05:12 +000067 puts(dev);
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000068 return EXIT_SUCCESS;
Denis Vlasenko956a5692006-09-27 14:51:27 +000069 }
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000070 } else {
71 if (opt != 0x4)
72 printf("%s: %s\n", dev, s);
73 if (ENABLE_FEATURE_CLEAN_UP)
74 free(s);
Denis Vlasenko956a5692006-09-27 14:51:27 +000075 }
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000076
77 if (++dev[sizeof(dev) - 2] > '9')
78 break;
Denis Vlasenko956a5692006-09-27 14:51:27 +000079 }
Tim Rikerc1ef7bd2006-01-25 00:08:53 +000080 return EXIT_SUCCESS;
Matt Kraai83788da2002-03-20 17:38:37 +000081}