]> git.ipfire.org Git - thirdparty/util-linux.git/blobdiff - misc-utils/blkid.c
libblkid: check status for the current CDROM slot
[thirdparty/util-linux.git] / misc-utils / blkid.c
index a472d06c45ebdf41797243bd827138264a2bbdf5..88a90578b030b1658860ed5fedadeefd3a3c11da 100644 (file)
@@ -34,7 +34,6 @@
 
 #include "ismounted.h"
 
-#define STRTOXX_EXIT_CODE      BLKID_EXIT_OTHER        /* strtoxx_or_err() */
 #include "strutils.h"
 #define OPTUTILS_EXIT_CODE     BLKID_EXIT_OTHER        /* exclusive_option() */
 #include "optutils.h"
@@ -43,6 +42,8 @@
 
 #include "nls.h"
 #include "ttyutils.h"
+
+#define XALLOC_EXIT_CODE    BLKID_EXIT_OTHER    /* x.*alloc(), xstrndup() */
 #include "xalloc.h"
 
 struct blkid_control {
@@ -57,54 +58,49 @@ struct blkid_control {
                lowprobe:1,
                lowprobe_superblocks:1,
                lowprobe_topology:1,
+               no_part_details:1,
                raw_chars:1;
 };
 
-static void print_version(FILE *out)
-{
-       fprintf(out, _("%s from %s  (libblkid %s, %s)\n"),
-               program_invocation_short_name, PACKAGE_STRING,
-               LIBBLKID_VERSION, LIBBLKID_DATE);
-}
-
-static void usage(int error)
+static void __attribute__((__noreturn__)) usage(void)
 {
-       FILE *out = error ? stderr : stdout;
+       FILE *out = stdout;
 
        fputs(USAGE_HEADER, out);
-       fprintf(out, _( " %s -L <label> | -U <uuid>\n\n"), program_invocation_short_name);
-       fprintf(out, _( " %s [-c <file>] [-ghlLv] [-o <format>] [-s <tag>] \n"
-                       "       [-t <token>] [<dev> ...]\n\n"), program_invocation_short_name);
-       fprintf(out, _( " %s -p [-s <tag>] [-O <offset>] [-S <size>] \n"
-                       "       [-o <format>] <dev> ...\n\n"), program_invocation_short_name);
-       fprintf(out, _( " %s -i [-s <tag>] [-o <format>] <dev> ...\n"), program_invocation_short_name);
+       fprintf(out, _( " %s --label <label> | --uuid <uuid>\n\n"), program_invocation_short_name);
+       fprintf(out, _( " %s [--cache-file <file>] [-ghlLv] [--output <format>] [--match-tag <tag>] \n"
+                       "       [--match-token <token>] [<dev> ...]\n\n"), program_invocation_short_name);
+       fprintf(out, _( " %s -p [--match-tag <tag>] [--offset <offset>] [--size <size>] \n"
+                       "       [--output <format>] <dev> ...\n\n"), program_invocation_short_name);
+       fprintf(out, _( " %s -i [--match-tag <tag>] [--output <format>] <dev> ...\n"), program_invocation_short_name);
        fputs(USAGE_OPTIONS, out);
-       fputs(_(        " -c <file>   read from <file> instead of reading from the default\n"
-                       "               cache file (-c /dev/null means no cache)\n"), out);
-       fputs(_(        " -d          don't encode non-printing characters\n"), out);
-       fputs(_(        " -h          print this usage message and exit\n"), out);
-       fputs(_(        " -g          garbage collect the blkid cache\n"), out);
-       fputs(_(        " -o <format> output format; can be one of:\n"
-                       "               value, device, export or full; (default: full)\n"), out);
-       fputs(_(        " -k          list all known filesystems/RAIDs and exit\n"), out);
-       fputs(_(        " -s <tag>    show specified tag(s) (default show all tags)\n"), out);
-       fputs(_(        " -t <token>  find device with a specific token (NAME=value pair)\n"), out);
-       fputs(_(        " -l          look up only first device with token specified by -t\n"), out);
-       fputs(_(        " -L <label>  convert LABEL to device name\n"), out);
-       fputs(_(        " -U <uuid>   convert UUID to device name\n"), out);
-       fputs(_(        " -V          print version and exit\n"), out);
-       fputs(_(        " <dev>       specify device(s) to probe (default: all devices)\n"), out);
+       fputs(_(        " -c, --cache-file <file>    read from <file> instead of reading from the default\n"
+                       "                              cache file (-c /dev/null means no cache)\n"), out);
+       fputs(_(        " -d, --no-encoding          don't encode non-printing characters\n"), out);
+       fputs(_(        " -g, --garbage-collect      garbage collect the blkid cache\n"), out);
+       fputs(_(        " -o, --output <format>      output format; can be one of:\n"
+                       "                              value, device, export or full; (default: full)\n"), out);
+       fputs(_(        " -k, --list-filesystems     list all known filesystems/RAIDs and exit\n"), out);
+       fputs(_(        " -s, --match-tag <tag>      show specified tag(s) (default show all tags)\n"), out);
+       fputs(_(        " -t, --match-token <token>  find device with a specific token (NAME=value pair)\n"), out);
+       fputs(_(        " -l, --list-one             look up only first device with token specified by -t\n"), out);
+       fputs(_(        " -L, --label <label>        convert LABEL to device name\n"), out);
+       fputs(_(        " -U, --uuid <uuid>          convert UUID to device name\n"), out);
+       fputs(_(        " <dev>                      specify device(s) to probe (default: all devices)\n"), out);
        fputs(          "\n", out);
        fputs(_(        "Low-level probing options:\n"), out);
-       fputs(_(        " -p          low-level superblocks probing (bypass cache)\n"), out);
-       fputs(_(        " -i          gather information about I/O limits\n"), out);
-       fputs(_(        " -S <size>   overwrite device size\n"), out);
-       fputs(_(        " -O <offset> probe at the given offset\n"), out);
-       fputs(_(        " -u <list>   filter by \"usage\" (e.g. -u filesystem,raid)\n"), out);
-       fputs(_(        " -n <list>   filter by filesystem type (e.g. -n vfat,ext3)\n"), out);
-
-       fprintf(out, USAGE_MAN_TAIL("blkid(8)"));
-       exit(error);
+       fputs(_(        " -p, --probe                low-level superblocks probing (bypass cache)\n"), out);
+       fputs(_(        " -i, --info                 gather information about I/O limits\n"), out);
+       fputs(_(        " -S, --size <size>          overwrite device size\n"), out);
+       fputs(_(        " -O, --offset <offset>      probe at the given offset\n"), out);
+       fputs(_(        " -u, --usages <list>        filter by \"usage\" (e.g. -u filesystem,raid)\n"), out);
+       fputs(_(        " -n, --match-types <list>   filter by filesystem type (e.g. -n vfat,ext3)\n"), out);
+       fputs(_(        " -D, --no-part-details      don't print info from partition table\n"), out);
+
+       fputs(USAGE_SEPARATOR, out);
+       printf(USAGE_HELP_OPTIONS(28));
+       printf(USAGE_MAN_TAIL("blkid(8)"));
+       exit(EXIT_SUCCESS);
 }
 
 /*
@@ -229,13 +225,18 @@ static void pretty_print_dev(blkid_dev dev)
        mtpt[0] = 0;
        retval = check_mount_point(devname, &mount_flags, mtpt, sizeof(mtpt));
        if (retval == 0) {
+               const char *msg = NULL;
+
                if (mount_flags & MF_MOUNTED) {
                        if (!mtpt[0])
-                               strcpy(mtpt, _("(mounted, mtpt unknown)"));
+                               msg = _("(mounted, mtpt unknown)");
                } else if (mount_flags & MF_BUSY)
-                       strcpy(mtpt, _("(in use)"));
+                       msg = _("(in use)");
                else
-                       strcpy(mtpt, _("(not mounted)"));
+                       msg = _("(not mounted)");
+
+               if (msg)
+                       xstrncpy(mtpt, msg, sizeof(mtpt));
        }
 
        pretty_print_line(devname, fs_type, label, mtpt, uuid);
@@ -253,7 +254,7 @@ static void print_udev_format(const char *name, const char *value)
                printf("ID_FS_%s=%s\n", name, enc);
 
        } else if (!strcmp(name, "UUID") ||
-                !strcmp(name, "LABEL") ||
+                !strncmp(name, "LABEL", 5) ||
                 !strcmp(name, "UUID_SUB")) {
 
                blkid_safe_string(value, safe, sizeof(safe));
@@ -443,7 +444,7 @@ done:
        return rc;
 }
 
-static int lowprobe_superblocks(blkid_probe pr)
+static int lowprobe_superblocks(blkid_probe pr, struct blkid_control *ctl)
 {
        struct stat st;
        int rc, fd = blkid_probe_get_fd(pr);
@@ -469,7 +470,8 @@ static int lowprobe_superblocks(blkid_probe pr)
                        return 0;       /* partition table detected */
        }
 
-       blkid_probe_set_partitions_flags(pr, BLKID_PARTS_ENTRY_DETAILS);
+       if (!ctl->no_part_details)
+               blkid_probe_set_partitions_flags(pr, BLKID_PARTS_ENTRY_DETAILS);
        blkid_probe_enable_superblocks(pr, 1);
 
        return blkid_do_safeprobe(pr);
@@ -497,18 +499,22 @@ static int lowprobe_device(blkid_probe pr, const char *devname,
        int rc = 0;
        static int first = 1;
 
-       fd = open(devname, O_RDONLY|O_CLOEXEC);
+       fd = open(devname, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
        if (fd < 0) {
                warn(_("error: %s"), devname);
                return BLKID_EXIT_NOTFOUND;
        }
-       if (blkid_probe_set_device(pr, fd, ctl->offset, ctl->size))
+       errno = 0;
+       if (blkid_probe_set_device(pr, fd, ctl->offset, ctl->size)) {
+               if (errno)
+                       warn(_("error: %s"), devname);
                goto done;
+       }
 
        if (ctl->lowprobe_topology)
                rc = lowprobe_topology(pr);
        if (rc >= 0 && ctl->lowprobe_superblocks)
-               rc = lowprobe_superblocks(pr);
+               rc = lowprobe_superblocks(pr, ctl);
        if (rc < 0)
                goto done;
 
@@ -529,8 +535,8 @@ static int lowprobe_device(blkid_probe pr, const char *devname,
                        continue;
                if (ctl->show[0] && !has_item(ctl, name))
                        continue;
-               len = strnlen((char *) data, len);
-               print_value(ctl, num++, devname, (char *) data, name, len);
+               len = strnlen(data, len);
+               print_value(ctl, num++, devname, data, name, len);
        }
 
        if (first)
@@ -657,6 +663,29 @@ int main(int argc, char **argv)
        unsigned int i;
        int c;
 
+       static const struct option longopts[] = {
+               { "cache-file",       required_argument, NULL, 'c' },
+               { "no-encoding",      no_argument,       NULL, 'd' },
+               { "no-part-details",  no_argument,       NULL, 'D' },
+               { "garbage-collect",  no_argument,       NULL, 'g' },
+               { "output",           required_argument, NULL, 'o' },
+               { "list-filesystems", no_argument,       NULL, 'k' },
+               { "match-tag",        required_argument, NULL, 's' },
+               { "match-token",      required_argument, NULL, 't' },
+               { "list-one",         no_argument,       NULL, 'l' },
+               { "label",            required_argument, NULL, 'L' },
+               { "uuid",             required_argument, NULL, 'U' },
+               { "probe",            no_argument,       NULL, 'p' },
+               { "info",             no_argument,       NULL, 'i' },
+               { "size",             required_argument, NULL, 'S' },
+               { "offset",           required_argument, NULL, 'O' },
+               { "usages",           required_argument, NULL, 'u' },
+               { "match-types",      required_argument, NULL, 'n' },
+               { "version",          no_argument,       NULL, 'V' },
+               { "help",             no_argument,       NULL, 'h' },
+               { NULL, 0, NULL, 0 }
+       };
+
        static const ul_excl_t excl[] = {       /* rows and cols in ASCII order */
                { 'n','u' },
                { 0 }
@@ -666,10 +695,12 @@ int main(int argc, char **argv)
        setlocale(LC_ALL, "");
        bindtextdomain(PACKAGE, LOCALEDIR);
        textdomain(PACKAGE);
-       atexit(close_stdout);
+       close_stdout_atexit();
 
-       while ((c = getopt (argc, argv,
-                           "c:df:ghilL:n:ko:O:ps:S:t:u:U:w:Vv")) != EOF) {
+       strutils_set_exitcode(BLKID_EXIT_OTHER);
+
+       while ((c = getopt_long (argc, argv,
+                           "c:DdghilL:n:ko:O:ps:S:t:u:U:w:Vv", longopts, NULL)) != -1) {
 
                err_exclusive_options(c, NULL, excl, excl_st);
 
@@ -680,6 +711,9 @@ int main(int argc, char **argv)
                case 'd':
                        ctl.raw_chars = 1;
                        break;
+               case 'D':
+                       ctl.no_part_details = 1;
+                       break;
                case 'L':
                        ctl.eval = 1;
                        search_value = xstrdup(optarg);
@@ -739,7 +773,7 @@ int main(int argc, char **argv)
                case 's':
                        if (numtag + 1 >= sizeof(ctl.show) / sizeof(*ctl.show)) {
                                warnx(_("Too many tags specified"));
-                               errtryh(err);
+                               errtryhelp(err);
                        }
                        ctl.show[numtag++] = optarg;
                        break;
@@ -750,27 +784,30 @@ int main(int argc, char **argv)
                        if (search_type) {
                                warnx(_("Can only search for "
                                        "one NAME=value pair"));
-                               errtryh(err);
+                               errtryhelp(err);
                        }
                        if (blkid_parse_tag_string(optarg,
                                                   &search_type,
                                                   &search_value)) {
                                warnx(_("-t needs NAME=value pair"));
-                               errtryh(err);
+                               errtryhelp(err);
                        }
                        break;
                case 'V':
                case 'v':
-                       print_version(stdout);
+                       fprintf(stdout, _("%s from %s  (libblkid %s, %s)\n"),
+                               program_invocation_short_name, PACKAGE_STRING,
+                               LIBBLKID_VERSION, LIBBLKID_DATE);
+                       err = 0;
                        goto exit;
                case 'w':
                        /* ignore - backward compatibility */
                        break;
                case 'h':
-                       usage(0);
+                       usage();
                        break;
                default:
-                       errtryh(EXIT_FAILURE);
+                       errtryhelp(EXIT_FAILURE);
                }
        }