blob: 62a1a7363fbb8cdfffb39b56b76abd9207edc21c [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;
Denis Vlasenko27ee7ba2006-09-22 14:53:41 +000013int losetup_main(int argc, char **argv)
Matt Kraai83788da2002-03-20 17:38:37 +000014{
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000015 char dev[] = LOOP_NAME"0";
Denis Vlasenko67b23e62006-10-03 21:00:06 +000016 unsigned opt;
Denis Vlasenko27ee7ba2006-09-22 14:53:41 +000017 char *opt_o;
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000018 char *s;
Denis Vlasenko13858992006-10-08 12:49:22 +000019 unsigned long long offset = 0;
Matt Kraai83788da2002-03-20 17:38:37 +000020
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000021 /* max 2 args, all opts are mutially exclusive */
22 opt_complementary = "?2:d--of:o--df:f-do";
23 opt = getopt32(argv, "do:f", &opt_o);
Denis Vlasenko27ee7ba2006-09-22 14:53:41 +000024 argc -= optind;
25 argv += optind;
Matt Kraai83788da2002-03-20 17:38:37 +000026
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000027 if (opt == 0x2) // -o
28 offset = xatoull(opt_o);
29
30 if (opt == 0x4 && argc) // -f does not take any argument
Denis Vlasenko956a5692006-09-27 14:51:27 +000031 bb_show_usage();
Denis Vlasenko27ee7ba2006-09-22 14:53:41 +000032
33 if (opt == 0x1) { // -d
34 /* detach takes exactly one argument */
35 if (argc != 1)
36 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
Denis Vlasenko27ee7ba2006-09-22 14:53:41 +000042 if (argc == 2) {
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000043 /* -o or no option */
Denis Vlasenko27ee7ba2006-09-22 14:53:41 +000044 if (set_loop(&argv[0], argv[1], offset) < 0)
Denis Vlasenko94e33652007-12-22 15:44:23 +000045 bb_simple_perror_msg_and_die(argv[0]);
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000046 return EXIT_SUCCESS;
47 }
48
49 if (argc == 1) {
50 /* -o or no option */
51 s = query_loop(argv[0]);
Denis Vlasenkoc34d3552007-04-19 00:09:34 +000052 if (!s)
Denis Vlasenko94e33652007-12-22 15:44:23 +000053 bb_simple_perror_msg_and_die(argv[0]);
Denis Vlasenko27ee7ba2006-09-22 14:53:41 +000054 printf("%s: %s\n", argv[0], s);
Denis Vlasenkoc34d3552007-04-19 00:09:34 +000055 if (ENABLE_FEATURE_CLEAN_UP)
56 free(s);
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000057 return EXIT_SUCCESS;
58 }
59
60 /* -o, -f or no option */
61 while (1) {
62 s = query_loop(dev);
63 if (!s) {
64 if (opt == 0x4) {
Denis Vlasenkofeb7ae72007-10-01 12:05:12 +000065 puts(dev);
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000066 return EXIT_SUCCESS;
Denis Vlasenko956a5692006-09-27 14:51:27 +000067 }
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000068 } else {
69 if (opt != 0x4)
70 printf("%s: %s\n", dev, s);
71 if (ENABLE_FEATURE_CLEAN_UP)
72 free(s);
Denis Vlasenko956a5692006-09-27 14:51:27 +000073 }
Denis Vlasenko7ae209c2007-09-26 17:54:18 +000074
75 if (++dev[sizeof(dev) - 2] > '9')
76 break;
Denis Vlasenko956a5692006-09-27 14:51:27 +000077 }
Tim Rikerc1ef7bd2006-01-25 00:08:53 +000078 return EXIT_SUCCESS;
Matt Kraai83788da2002-03-20 17:38:37 +000079}