1 --- e2fsprogs-1.19/misc/get_device_by_label.c.mountlabel Mon Feb 7 19:47:54 2000
2 +++ e2fsprogs-1.19/misc/get_device_by_label.c Wed Aug 9 13:01:21 2000
6 * Taken from aeb's mount, 990619
7 + * Updated from aeb's mount, 20000725
15 -#include "nls-enable.h"
16 #include "get_device_by_label.h"
18 #define PROC_PARTITIONS "/proc/partitions"
21 #define ext2magic(s) ((unsigned int) s.s_magic[0] + (((unsigned int) s.s_magic[1]) << 8))
35 - return ((procpt = fopen(PROC_PARTITIONS, "r")) != NULL);
43 - static char ptname[100];
45 - while (fgets(line, sizeof(line), procpt)) {
46 - if (sscanf (line, " %d %d %d %[^\n]\n", &ma, &mi, &sz, ptname) != 4)
49 - /* skip extended partitions (heuristic: size 1) */
53 - /* skip entire disk (minor 0, 64, ... on ide; 0, 16, ... on sd) */
54 - /* heuristic: partition name ends in a digit */
55 - for(s = ptname; *s; s++);
64 +static struct uuidCache_s {
65 + struct uuidCache_s *next;
71 /* for now, only ext2 is supported */
73 -has_right_label(const char *device, int n, const void *label) {
74 +get_label_uuid(const char *device, char **label, char *uuid) {
76 /* start with a test for ext2, taken from mount_guess_fstype */
77 + /* should merge these later */
79 struct ext2_super_block e2sb;
81 fd = open(device, O_RDONLY);
86 if (lseek(fd, 1024, SEEK_SET) != 1024
87 || read(fd, (char *) &e2sb, sizeof(e2sb)) != sizeof(e2sb)
88 || (ext2magic(e2sb) != EXT2_SUPER_MAGIC)) {
96 /* superblock is ext2 - now what is its label? */
98 - return (memcmp(e2sb.s_uuid, label, 16) == 0);
100 - return (strncmp(e2sb.s_volume_name,
101 - (const char *) label, 16) == 0);
102 + memcpy(uuid, e2sb.s_uuid, sizeof(e2sb.s_uuid));
103 + *label = strdup(e2sb.s_volume_name);
109 -get_spec_by_x(int n, const void *t) {
112 +uuidcache_addentry(char *device, char *label, char *uuid) {
113 + struct uuidCache_s *last;
116 + last = uuidCache = malloc(sizeof(*uuidCache));
118 + for (last = uuidCache; last->next; last = last->next) ;
119 + last->next = malloc(sizeof(*uuidCache));
123 + last->device = device;
124 + last->label = label;
125 + memcpy(last->uuid, uuid, sizeof(last->uuid));
129 +uuidcache_init(void) {
133 + static char ptname[100];
135 + char uuid[16], *label;
145 - while((pt = procptnext()) != NULL) {
146 - /* Note: this is a heuristic only - there is no reason
147 - why these devices should live in /dev.
148 - Perhaps this directory should be specifiable by option.
149 - One might for example have /devlabel with links to /dev
150 - for the devices that may be accessed in this way.
151 - (This is useful, if the cdrom on /dev/hdc must not
154 - sprintf(device, "%s/%s", DEVLABELDIR, pt);
155 - if (has_right_label(device, n, t)) {
157 - return strdup(device);
158 + procpt = fopen(PROC_PARTITIONS, "r");
162 + for (firstPass = 1; firstPass >= 0; firstPass--) {
163 + fseek(procpt, 0, SEEK_SET);
165 + while (fgets(line, sizeof(line), procpt)) {
166 + if (sscanf (line, " %d %d %d %[^\n ]",
167 + &ma, &mi, &sz, ptname) != 4)
170 + /* skip extended partitions (heuristic: size 1) */
174 + /* look only at md devices on first pass */
175 + handleOnFirst = !strncmp(ptname, "md", 2);
176 + if (firstPass != handleOnFirst)
179 + /* skip entire disk (minor 0, 64, ... on ide;
180 + 0, 16, ... on sd) */
181 + /* heuristic: partition name ends in a digit */
183 + for(s = ptname; *s; s++);
184 + if (isdigit(s[-1])) {
186 + * Note: this is a heuristic only - there is no reason
187 + * why these devices should live in /dev.
188 + * Perhaps this directory should be specifiable by option.
189 + * One might for example have /devlabel with links to /dev
190 + * for the devices that may be accessed in this way.
191 + * (This is useful, if the cdrom on /dev/hdc must not
194 + sprintf(device, "%s/%s", DEVLABELDIR, ptname);
195 + if (!get_label_uuid(device, &label, uuid))
196 + uuidcache_addentry(strdup(device), label, uuid);
208 +get_spec_by_x(int n, const char *t) {
209 + struct uuidCache_s *uc;
217 + if (!memcmp(t, uc->uuid, sizeof(uc->uuid)))
218 + return strdup(uc->device);
221 + if (!strcmp(t, uc->label))
222 + return strdup(uc->device);
231 -static unsigned char
240 -get_spec_by_uuid(const char *s0) {
241 - unsigned char uuid[16];
242 +get_spec_by_uuid(const char *s) {
245 - const char *s = s0;
247 if (strlen(s) != 36 ||
248 s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-')
249 @@ -156,11 +198,26 @@
250 return get_spec_by_x(UUID, uuid);
253 - fprintf(stderr, _("WARNING: %s: bad UUID"), s0);
255 + fprintf(stderr, ("WARNING: bad UUID"));
256 + return NULL; /* just for gcc */
260 get_spec_by_volume_label(const char *s) {
261 return get_spec_by_x(VOL, s);
265 +get_volume_label_by_spec(const char *spec) {
266 + struct uuidCache_s *uc;
272 + if (!strcmp(spec, uc->device))