Print this page
*** NO COMMENTS ***

@@ -62,11 +62,11 @@
 #include <aes/aes_impl.h>
 #include <des/des_impl.h>
 #include <blowfish/blowfish_impl.h>
 
 static const char USAGE[] =
-        "Usage: %s -a file [ device ] "
+        "Usage: %s [-r] -a file [ device ] "
         " [-c aes-128-cbc|aes-192-cbc|aes-256-cbc|des3-cbc|blowfish-cbc]"
         " [-e] [-k keyfile] [-T [token]:[manuf]:[serial]:key]\n"
         "       %s -d file | device\n"
         "       %s -C [gzip|gzip-6|gzip-9|lzma] [-s segment_size] file\n"
         "       %s -U file\n"

@@ -362,14 +362,16 @@
  * Add a device association. If devicename is NULL, let the driver
  * pick a device.
  */
 static void
 add_mapping(int lfd, const char *devicename, const char *filename,
-    mech_alias_t *cipher, const char *rkey, size_t rksz)
+    mech_alias_t *cipher, const char *rkey, size_t rksz, boolean_t rdonly)
 {
         struct lofi_ioctl li;
 
+        li.li_readonly = rdonly;
+
         li.li_crypto_enabled = B_FALSE;
         if (cipher != NULL) {
                 /* set up encryption for mapped file */
                 li.li_crypto_enabled = B_TRUE;
                 (void) strlcpy(li.li_cipher, cipher->name,

@@ -495,11 +497,11 @@
 {
         struct lofi_ioctl li;
         int     minor;
         int     maxminor;
         char    path[MAXPATHLEN];
-        char    options[MAXPATHLEN];
+        char    options[MAXPATHLEN] = { 0 };
 
         li.li_minor = 0;
         if (ioctl(fd, LOFI_GET_MAXMINOR, &li) == -1) {
                 die("ioctl");
         }

@@ -515,20 +517,33 @@
                         warn("ioctl");
                         break;
                 }
                 (void) snprintf(path, sizeof (path), "/dev/%s/%d",
                     LOFI_BLOCK_NAME, minor);
+
+                options[0] = '\0';
+
                 /*
                  * Encrypted lofi and compressed lofi are mutually exclusive.
                  */
                 if (li.li_crypto_enabled)
                         (void) snprintf(options, sizeof (options),
                             gettext("Encrypted"));
                 else if (li.li_algorithm[0] != '\0')
                         (void) snprintf(options, sizeof (options),
                             gettext("Compressed(%s)"), li.li_algorithm);
-                else
+                if (li.li_readonly) {
+                        if (strlen(options) != 0) {
+                                (void) strlcat(options, ",", sizeof (options));
+                                (void) strlcat(options, "Readonly",
+                                    sizeof (options));
+                        } else {
+                                (void) snprintf(options, sizeof (options),
+                                    gettext("Readonly"));
+                        }
+                }
+                if (strlen(options) == 0)
                         (void) snprintf(options, sizeof (options), "-");
 
                 (void) printf(FORMAT, path, li.li_filename, options);
         }
 }

@@ -1787,10 +1802,11 @@
         static char *lofictl = "/dev/" LOFI_CTL_NAME;
         boolean_t force = B_FALSE;
         const char *pname;
         boolean_t errflag = B_FALSE;
         boolean_t addflag = B_FALSE;
+        boolean_t rdflag = B_FALSE;
         boolean_t deleteflag = B_FALSE;
         boolean_t ephflag = B_FALSE;
         boolean_t compressflag = B_FALSE;
         boolean_t uncompressflag = B_FALSE;
         /* the next two work together for -c, -k, -T, -e options only */

@@ -1806,11 +1822,11 @@
         pname = getpname(argv[0]);
 
         (void) setlocale(LC_ALL, "");
         (void) textdomain(TEXT_DOMAIN);
 
-        while ((c = getopt(argc, argv, "a:c:Cd:efk:o:s:T:U")) != EOF) {
+        while ((c = getopt(argc, argv, "a:c:Cd:efk:o:rs:T:U")) != EOF) {
                 switch (c) {
                 case 'a':
                         addflag = B_TRUE;
                         if ((filename = realpath(optarg, realfilename)) == NULL)
                                 die("%s", optarg);

@@ -1861,10 +1877,13 @@
                 case 'k':
                         keyfile = optarg;
                         need_crypto = B_TRUE;
                         cipher_only = B_FALSE;  /* need to unset cipher_only */
                         break;
+                case 'r':
+                        rdflag = B_TRUE;
+                        break;
                 case 's':
                         segsize = convert_to_num(optarg);
                         if (segsize < DEV_BSIZE || !ISP2(segsize))
                                 die(gettext("segment size %s is invalid "
                                     "or not a multiple of minimum block "

@@ -1891,10 +1910,11 @@
         }
 
         /* Check for mutually exclusive combinations of options */
         if (errflag ||
             (addflag && deleteflag) ||
+            (rdflag && !addflag) ||
             (!addflag && need_crypto) ||
             ((compressflag || uncompressflag) && (addflag || deleteflag)))
                 usage(pname);
 
         /* ephemeral key, and key from either file or token are incompatible */

@@ -2007,11 +2027,12 @@
 
         /*
          * Now to the real work.
          */
         if (addflag)
-                add_mapping(lfd, devicename, filename, cipher, rkey, rksz);
+                add_mapping(lfd, devicename, filename, cipher, rkey, rksz,
+                    rdflag);
         else if (compressflag)
                 lofi_compress(&lfd, filename, compress_index, segsize);
         else if (uncompressflag)
                 lofi_uncompress(lfd, filename);
         else if (deleteflag)