chiark / gitweb /
build argv[] for builtin commands
[elogind.git] / udev / udev-builtin-blkid.c
1 /*
2  * probe disks for filesystems and partitions
3  *
4  * Copyright (C) 2011 Kay Sievers <kay.sievers@vrfy.org>
5  * Copyright (C) 2011 Karel Zak <kzak@redhat.com>
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdarg.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <sys/stat.h>
29 #include <blkid/blkid.h>
30
31 #include "udev.h"
32
33 static void print_property(const char *name, const char *value)
34 {
35         char enc[265], safe[256];
36         size_t namelen = strlen(name);
37
38         enc[0] = '\0';
39         safe[0] = '\0';
40
41         if (!strcmp(name, "TYPE") || !strcmp(name, "VERSION")) {
42                 blkid_encode_string(value, enc, sizeof(enc));
43                 printf("ID_FS_%s=%s\n", name, enc);
44
45         } else if (!strcmp(name, "UUID") ||
46                  !strcmp(name, "LABEL") ||
47                  !strcmp(name, "UUID_SUB")) {
48
49                 blkid_safe_string(value, safe, sizeof(safe));
50                 printf("ID_FS_%s=%s\n", name, safe);
51
52                 blkid_encode_string(value, enc, sizeof(enc));
53                 printf("ID_FS_%s_ENC=%s\n", name, enc);
54
55         } else if (!strcmp(name, "PTTYPE")) {
56                 printf("ID_PART_TABLE_TYPE=%s\n", value);
57
58         } else if (!strcmp(name, "PART_ENTRY_NAME") ||
59                   !strcmp(name, "PART_ENTRY_TYPE")) {
60
61                 blkid_encode_string(value, enc, sizeof(enc));
62                 printf("ID_%s=%s\n", name, enc);
63
64         } else if (!strncmp(name, "PART_ENTRY_", 11))
65                 printf("ID_%s=%s\n", name, value);
66
67         else if (namelen >= 15 && (
68                    !strcmp(name + (namelen - 12), "_SECTOR_SIZE") ||
69                    !strcmp(name + (namelen - 8), "_IO_SIZE") ||
70                    !strcmp(name, "ALIGNMENT_OFFSET")))
71                         printf("ID_IOLIMIT_%s=%s\n", name, value);
72         else
73                 printf("ID_FS_%s=%s\n", name, value);
74 }
75
76 static int probe_superblocks(blkid_probe pr)
77 {
78         struct stat st;
79         int rc;
80
81         if (fstat(blkid_probe_get_fd(pr), &st))
82                 return -1;
83
84         blkid_probe_enable_partitions(pr, 1);
85
86         if (!S_ISCHR(st.st_mode) && blkid_probe_get_size(pr) <= 1024 * 1440 &&
87             blkid_probe_is_wholedisk(pr)) {
88                 /*
89                  * check if the small disk is partitioned, if yes then
90                  * don't probe for filesystems.
91                  */
92                 blkid_probe_enable_superblocks(pr, 0);
93
94                 rc = blkid_do_fullprobe(pr);
95                 if (rc < 0)
96                         return rc;      /* -1 = error, 1 = nothing, 0 = succes */
97
98                 if (blkid_probe_lookup_value(pr, "PTTYPE", NULL, NULL) == 0)
99                         return 0;       /* partition table detected */
100         }
101
102         blkid_probe_set_partitions_flags(pr, BLKID_PARTS_ENTRY_DETAILS);
103         blkid_probe_enable_superblocks(pr, 1);
104
105         return blkid_do_safeprobe(pr);
106 }
107
108 static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool test)
109 {
110         char *device = "/dev/sda3";
111         int64_t offset = 0;
112         //int noraid = 0;
113         int fd = -1;
114         blkid_probe pr;
115         const char *data;
116         const char *name;
117         int nvals;
118         int i;
119         size_t len;
120         int err = 0;
121
122         //FIXME: read offset, read noraid
123
124         pr = blkid_new_probe();
125         if (!pr) {
126                 err = -ENOMEM;
127                 return EXIT_FAILURE;
128         }
129
130         blkid_probe_set_superblocks_flags(pr,
131                 BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID |
132                 BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE |
133                 BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION);
134
135         fd = open(device, O_RDONLY|O_CLOEXEC);
136         if (fd < 0) {
137                 fprintf(stderr, "error: %s: %m\n", device);
138                 goto out;
139         }
140
141         err = blkid_probe_set_device(pr, fd, offset, 0);
142         if (err < 0)
143                 goto out;
144
145         err = probe_superblocks(pr);
146         if (err < 0)
147                 goto out;
148
149         nvals = blkid_probe_numof_values(pr);
150         for (i = 0; i < nvals; i++) {
151                 if (blkid_probe_get_value(pr, i, &name, &data, &len))
152                         continue;
153                 len = strnlen((char *) data, len);
154                 print_property(name, (char *) data);
155         }
156
157         blkid_free_probe(pr);
158 out:
159         if (fd > 0)
160                 close(fd);
161         if (err < 0)
162                 return EXIT_FAILURE;
163         return EXIT_SUCCESS;
164 }
165
166 const struct udev_builtin udev_builtin_blkid = {
167         .name = "blkid",
168         .cmd = builtin_blkid,
169         .help = "filesystem and partition probing",
170         .run_once = true,
171 };