]> git.ipfire.org Git - thirdparty/util-linux.git/blobdiff - sys-utils/losetup.c
mount: losetup: remove obsolete encryption support
[thirdparty/util-linux.git] / sys-utils / losetup.c
index 35c1c919d58a9fb5202143979b845578c7065ea8..38ccc7d08459e4ea3636537cd4093988cfe90911 100644 (file)
@@ -18,6 +18,8 @@
 #include "nls.h"
 #include "strutils.h"
 #include "loopdev.h"
+#include "closestream.h"
+#include "optutils.h"
 
 enum {
        A_CREATE = 1,           /* setup a new device */
@@ -31,45 +33,6 @@ enum {
 
 static int verbose;
 
-/*
- * A function to read the passphrase either from the terminal or from
- * an open file descriptor.
- */
-static char *xgetpass(int pfd, const char *prompt)
-{
-       char *pass;
-       int buflen, i;
-
-        if (pfd < 0) /* terminal */
-               return getpass(prompt);
-
-       pass = NULL;
-       buflen = 0;
-       for (i=0; ; i++) {
-               if (i >= buflen-1) {
-                               /* we're running out of space in the buffer.
-                                * Make it bigger: */
-                       char *tmppass = pass;
-                       buflen += 128;
-                       pass = realloc(tmppass, buflen);
-                       if (pass == NULL) {
-                               /* realloc failed. Stop reading. */
-                               warn(_("Out of memory while reading passphrase"));
-                               pass = tmppass; /* the old buffer hasn't changed */
-                               break;
-                       }
-               }
-               if (read(pfd, pass+i, 1) != 1 ||
-                   pass[i] == '\n' || pass[i] == 0)
-                       break;
-       }
-
-       if (pass == NULL)
-               return "";
-
-       pass[i] = 0;
-       return pass;
-}
 
 static int printf_loopdev(struct loopdev_cxt *lc)
 {
@@ -77,7 +40,7 @@ static int printf_loopdev(struct loopdev_cxt *lc)
        dev_t dev = 0;
        ino_t ino = 0;
        char *fname = NULL;
-       int type;
+       uint32_t type;
 
        fname = loopcxt_get_backing_file(lc);
        if (!fname)
@@ -104,7 +67,7 @@ static int printf_loopdev(struct loopdev_cxt *lc)
        }
 
        printf("%s: [%04d]:%" PRIu64 " (%s)",
-               loopcxt_get_device(lc), dev, ino, fname);
+               loopcxt_get_device(lc), (int) dev, ino, fname);
 
        if (loopcxt_get_offset(lc, &x) == 0 && x)
                        printf(_(", offset %ju"), x);
@@ -118,7 +81,7 @@ static int printf_loopdev(struct loopdev_cxt *lc)
                if ((!e || !*e) && type == 1)
                        e = "XOR";
                if (e && *e)
-                       printf(_(", encryption %s (type %ju)"), e, type);
+                       printf(_(", encryption %s (type %u)"), e, type);
        }
        printf("\n");
        return 0;
@@ -151,7 +114,7 @@ static int set_capacity(struct loopdev_cxt *lc)
        int fd = loopcxt_get_fd(lc);
 
        if (fd < 0)
-               warn(_("%s: open failed"), loopcxt_get_device(lc));
+               warn(_("cannot open %s"), loopcxt_get_device(lc));
        else if (ioctl(fd, LOOP_SET_CAPACITY) != 0)
                warnx(_("%s: set capacity failed"), loopcxt_get_device(lc));
        else
@@ -202,10 +165,9 @@ static void usage(FILE *out)
                " -j, --associated <file>       list all devices associated with <file>\n"), out);
        fputs(USAGE_SEPARATOR, out);
 
-       fputs(_(" -e, --encryption <type>       enable encryption with specified <name/num>\n"
-               " -o, --offset <num>            start at offset <num> into file\n"
+       fputs(_(" -o, --offset <num>            start at offset <num> into file\n"
                "     --sizelimit <num>         device limited to <num> bytes of the file\n"
-               " -p, --pass-fd <num>           read passphrase from file descriptor <num>\n"
+               " -P, --partscan                create partitioned loop device\n"
                " -r, --read-only               setup read-only loop device\n"
                "     --show                    print device name after setup (with -f)\n"
                " -v, --verbose                 verbose mode\n"), out);
@@ -219,11 +181,31 @@ static void usage(FILE *out)
        exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
 }
 
+static void warn_size(const char *filename, uint64_t size)
+{
+       struct stat st;
+
+       if (!size) {
+               if (stat(filename, &st))
+                       return;
+               size = st.st_size;
+       }
+
+       if (size < 512)
+               warnx(_("%s: warning: file smaller than 512 bytes, the loop device "
+                       "maybe be useless or invisible for system tools."),
+                       filename);
+       else if (size % 512)
+               warnx(_("%s: warning: file does not fit into a 512-byte sector "
+                       "the end of the file will be ignored."),
+                       filename);
+}
+
 int main(int argc, char **argv)
 {
        struct loopdev_cxt lc;
-       int act = 0, flags = 0, passfd = -1, c;
-       char *file = NULL, *encryption = NULL;
+       int act = 0, flags = 0, c;
+       char *file = NULL;
        uint64_t offset = 0, sizelimit = 0;
        int res = 0, showdev = 0, lo_flags = 0;
 
@@ -243,6 +225,7 @@ int main(int argc, char **argv)
                { "offset", 1, 0, 'o' },
                { "sizelimit", 1, 0, OPT_SIZELIMIT },
                { "pass-fd", 1, 0, 'p' },
+               { "partscan", 0, 0, 'P' },
                { "read-only", 0, 0, 'r' },
                { "show", 0, 0, OPT_SHOW },
                { "verbose", 0, 0, 'v' },
@@ -250,20 +233,26 @@ int main(int argc, char **argv)
                { NULL, 0, 0, 0 }
        };
 
+       static const ul_excl_t excl[] = {       /* rows and cols in ASCII order */
+               { 'D','a','c','d','f','j' },
+               { 0 }
+       };
+       int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT;
+
        setlocale(LC_ALL, "");
        bindtextdomain(PACKAGE, LOCALEDIR);
        textdomain(PACKAGE);
+       atexit(close_stdout);
+
+       if (loopcxt_init(&lc, 0))
+               err(EXIT_FAILURE, _("failed to initialize loopcxt"));
 
-       loopcxt_init(&lc, 0);
        loopcxt_enable_debug(&lc, getenv("LOOPDEV_DEBUG") ? TRUE : FALSE);
 
-       while ((c = getopt_long(argc, argv, "ac:d:De:E:fhj:o:p:rvV",
+       while ((c = getopt_long(argc, argv, "ac:d:De:E:fhj:o:p:PrvV",
                                longopts, NULL)) != -1) {
 
-               if (act && strchr("acdDfj", c))
-                       errx(EXIT_FAILURE,
-                               _("the options %s are mutually exclusive"),
-                               "--{all,associated,set-capacity,detach,detach-all,find}");
+               err_exclusive_options(c, longopts, excl, excl_st);
 
                switch (c) {
                case 'a':
@@ -271,21 +260,25 @@ int main(int argc, char **argv)
                        break;
                case 'c':
                        act = A_SET_CAPACITY;
-                       loopcxt_set_device(&lc, optarg);
+                       if (loopcxt_set_device(&lc, optarg))
+                               err(EXIT_FAILURE, _("%s: failed to use device"),
+                                               optarg);
                        break;
                case 'r':
                        lo_flags |= LO_FLAGS_READ_ONLY;
                        break;
                case 'd':
                        act = A_DELETE;
-                       loopcxt_set_device(&lc, optarg);
+                       if (loopcxt_set_device(&lc, optarg))
+                               err(EXIT_FAILURE, _("%s: failed to use device"),
+                                               optarg);
                        break;
                case 'D':
                        act = A_DELETE_ALL;
                        break;
                case 'E':
                case 'e':
-                       encryption = optarg;
+                       errx(EXIT_FAILURE, _("encryption not supported, use cryptsetup(8) instead"));
                        break;
                case 'f':
                        act = A_FIND_FREE;
@@ -298,14 +291,14 @@ int main(int argc, char **argv)
                        file = optarg;
                        break;
                case 'o':
-                       if (strtosize(optarg, &offset))
-                               errx(EXIT_FAILURE,
-                                    _("invalid offset '%s' specified"), optarg);
+                       offset = strtosize_or_err(optarg, _("failed to parse offset"));
                        flags |= LOOPDEV_FL_OFFSET;
                        break;
                case 'p':
-                       passfd = strtol_or_err(optarg,
-                                       _("invalid passphrase file descriptor"));
+                        warn(_("--pass-fd is no longer supported"));
+                       break;
+               case 'P':
+                       lo_flags |= LO_FLAGS_PARTSCAN;
                        break;
                case OPT_SHOW:
                        showdev = 1;
@@ -317,9 +310,7 @@ int main(int argc, char **argv)
                        printf(UTIL_LINUX_VERSION);
                        return EXIT_SUCCESS;
                case OPT_SIZELIMIT:                     /* --sizelimit */
-                       if (strtosize(optarg, &sizelimit))
-                               errx(EXIT_FAILURE,
-                                    _("invalid size '%s' specified"), optarg);
+                       sizelimit = strtosize_or_err(optarg, _("failed to parse size"));
                        flags |= LOOPDEV_FL_SIZELIMIT;
                         break;
                default:
@@ -342,7 +333,10 @@ int main(int argc, char **argv)
                 * losetup <device>
                 */
                act = A_SHOW_ONE;
-               loopcxt_set_device(&lc, argv[optind++]);
+               if (loopcxt_set_device(&lc, argv[optind]))
+                       err(EXIT_FAILURE, _("%s: failed to use device"),
+                                       argv[optind]);
+               optind++;
        }
        if (!act) {
                /*
@@ -352,7 +346,10 @@ int main(int argc, char **argv)
 
                if (optind >= argc)
                        errx(EXIT_FAILURE, _("no loop device specified"));
-               loopcxt_set_device(&lc, argv[optind++]);
+               if (loopcxt_set_device(&lc, argv[optind]))
+                       err(EXIT_FAILURE, _("%s: failed to use device"),
+                                       argv[optind]);
+               optind++;
 
                if (optind >= argc)
                        errx(EXIT_FAILURE, _("no file specified"));
@@ -360,10 +357,10 @@ int main(int argc, char **argv)
        }
 
        if (act != A_CREATE &&
-           (encryption || sizelimit || passfd != -1 || lo_flags || showdev))
+           (sizelimit || lo_flags || showdev))
                errx(EXIT_FAILURE,
                        _("the options %s are allowed to loop device setup only"),
-                       "--{encryption,sizelimit,pass-fd,read-only,show}");
+                       "--{sizelimit,read-only,show}");
 
        if ((flags & LOOPDEV_FL_OFFSET) &&
            act != A_CREATE && (act != A_SHOW || !file))
@@ -372,16 +369,8 @@ int main(int argc, char **argv)
        switch (act) {
        case A_CREATE:
        {
-               char *pass = NULL;
                int hasdev = loopcxt_has_device(&lc);
 
-               if (encryption) {
-#ifdef MCL_FUTURE
-                       if(mlockall(MCL_CURRENT | MCL_FUTURE))
-                               err(EXIT_FAILURE, _("couldn't lock into memory"));
-#endif
-                       pass = xgetpass(passfd, _("Password: "));
-               }
                do {
                        /* Note that loopcxt_{find_unused,set_device}() resets
                         * loopcxt struct.
@@ -390,12 +379,10 @@ int main(int argc, char **argv)
                                warnx(_("not found unused device"));
                                break;
                        }
-                       if (encryption && pass)
-                               loopcxt_set_encryption(&lc, encryption, pass);
                        if (flags & LOOPDEV_FL_OFFSET)
                                loopcxt_set_offset(&lc, offset);
                        if (flags & LOOPDEV_FL_SIZELIMIT)
-                               loopcxt_set_offset(&lc, sizelimit);
+                               loopcxt_set_sizelimit(&lc, sizelimit);
                        if (lo_flags)
                                loopcxt_set_flags(&lc, lo_flags);
                        if ((res = loopcxt_set_backing_file(&lc, file))) {
@@ -407,21 +394,27 @@ int main(int argc, char **argv)
                        if (res == 0)
                                break;                  /* success */
                        if (errno != EBUSY) {
-                               warn(_("failed to setup loop device"));
+                               warn(_("%s: failed to setup loop device"),
+                                       hasdev && loopcxt_get_fd(&lc) < 0 ?
+                                           loopcxt_get_device(&lc) : file);
                                break;
                        }
                } while (hasdev == 0);
 
-               free(pass);
-
-               if (showdev && res == 0)
-                       printf("%s\n", loopcxt_get_device(&lc));
+               if (res == 0) {
+                       if (showdev)
+                               printf("%s\n", loopcxt_get_device(&lc));
+                       warn_size(file, sizelimit);
+               }
                break;
        }
        case A_DELETE:
                res = delete_loop(&lc);
                while (optind < argc) {
-                       loopcxt_set_device(&lc, argv[optind++]);
+                       if (loopcxt_set_device(&lc, argv[optind]))
+                               warn(_("%s: failed to use device"),
+                                               argv[optind]);
+                       optind++;
                        res += delete_loop(&lc);
                }
                break;