]> git.pld-linux.org Git - packages/e2fsprogs.git/blob - e2fsprogs-mountlabel.patch
patch from rawhie.
[packages/e2fsprogs.git] / e2fsprogs-mountlabel.patch
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
3 @@ -7,6 +7,7 @@
4   * License.
5   *
6   * Taken from aeb's mount, 990619
7 + * Updated from aeb's mount, 20000725
8   */
9  
10  #include <stdio.h>
11 @@ -14,7 +15,6 @@
12  #include <ctype.h>
13  #include <fcntl.h>
14  #include <unistd.h>
15 -#include "nls-enable.h"
16  #include "get_device_by_label.h"
17  
18  #define PROC_PARTITIONS "/proc/partitions"
19 @@ -30,104 +30,147 @@
20  };
21  #define ext2magic(s)    ((unsigned int) s.s_magic[0] + (((unsigned int) s.s_magic[1]) << 8))
22  
23 -
24 -static FILE *procpt;
25 -
26 -static void
27 -procptclose(void) {
28 -    if (procpt)
29 -        fclose (procpt);
30 -    procpt = 0;
31 -}
32 -
33 -static int
34 -procptopen(void) {
35 -    return ((procpt = fopen(PROC_PARTITIONS, "r")) != NULL);
36 -}
37 -
38 -static char *
39 -procptnext(void) {
40 -   char line[100];
41 -   char *s;
42 -   int ma, mi, sz;
43 -   static char ptname[100];
44 -
45 -   while (fgets(line, sizeof(line), procpt)) {
46 -      if (sscanf (line, " %d %d %d %[^\n]\n", &ma, &mi, &sz, ptname) != 4)
47 -             continue;
48 -
49 -      /* skip extended partitions (heuristic: size 1) */
50 -      if (sz == 1)
51 -             continue;
52 -
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++);
56 -      if (isdigit(s[-1]))
57 -             return ptname;
58 -   }
59 -   return 0;
60 -}
61 -
62 -#define UUID   1
63 -#define VOL    2
64 +static struct uuidCache_s {
65 +       struct uuidCache_s *next;
66 +       char uuid[16];
67 +       char *label;
68 +       char *device;
69 +} *uuidCache = NULL;
70  
71  /* for now, only ext2 is supported */
72  static int
73 -has_right_label(const char *device, int n, const void *label) {
74 +get_label_uuid(const char *device, char **label, char *uuid) {
75  
76         /* start with a test for ext2, taken from mount_guess_fstype */
77 +       /* should merge these later */
78         int fd;
79         struct ext2_super_block e2sb;
80  
81         fd = open(device, O_RDONLY);
82         if (fd < 0)
83 -               return 0;
84 +               return 1;
85  
86         if (lseek(fd, 1024, SEEK_SET) != 1024
87             || read(fd, (char *) &e2sb, sizeof(e2sb)) != sizeof(e2sb)
88             || (ext2magic(e2sb) != EXT2_SUPER_MAGIC)) {
89                 close(fd);
90 -               return 0;
91 +               return 1;
92         }
93  
94         close(fd);
95  
96         /* superblock is ext2 - now what is its label? */
97 -       if (n == UUID)
98 -               return (memcmp(e2sb.s_uuid, label, 16) == 0);
99 -       else
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);
104 +
105 +       return 0;
106  }
107  
108 -static char *
109 -get_spec_by_x(int n, const void *t) {
110 -       char *pt;
111 +static void
112 +uuidcache_addentry(char *device, char *label, char *uuid) {
113 +       struct uuidCache_s *last;
114 +
115 +       if (!uuidCache) {
116 +               last = uuidCache = malloc(sizeof(*uuidCache));
117 +       } else {
118 +               for (last = uuidCache; last->next; last = last->next) ;
119 +               last->next = malloc(sizeof(*uuidCache));
120 +               last = last->next;
121 +       }
122 +       last->next = NULL;
123 +       last->device = device;
124 +       last->label = label;
125 +       memcpy(last->uuid, uuid, sizeof(last->uuid));
126 +}
127 +
128 +static void
129 +uuidcache_init(void) {
130 +       char line[100];
131 +       char *s;
132 +       int ma, mi, sz;
133 +       static char ptname[100];
134 +       FILE *procpt;
135 +       char uuid[16], *label;
136         char device[110];
137 +       int firstPass;
138 +       int handleOnFirst;
139 +
140 +       if (uuidCache)
141 +               return;
142  
143 -       if(!procptopen())
144 -               return NULL;
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
152 -                  be accessed.)
153 -               */
154 -               sprintf(device, "%s/%s", DEVLABELDIR, pt);
155 -               if (has_right_label(device, n, t)) {
156 -                       procptclose();
157 -                       return strdup(device);
158 +       procpt = fopen(PROC_PARTITIONS, "r");
159 +       if (!procpt)
160 +               return;
161 +
162 +       for (firstPass = 1; firstPass >= 0; firstPass--) {
163 +           fseek(procpt, 0, SEEK_SET);
164 +
165 +           while (fgets(line, sizeof(line), procpt)) {
166 +               if (sscanf (line, " %d %d %d %[^\n ]",
167 +                           &ma, &mi, &sz, ptname) != 4)
168 +                       continue;
169 +
170 +               /* skip extended partitions (heuristic: size 1) */
171 +               if (sz == 1)
172 +                       continue;
173 +
174 +               /* look only at md devices on first pass */
175 +               handleOnFirst = !strncmp(ptname, "md", 2);
176 +               if (firstPass != handleOnFirst)
177 +                       continue;
178 +
179 +               /* skip entire disk (minor 0, 64, ... on ide;
180 +                  0, 16, ... on sd) */
181 +               /* heuristic: partition name ends in a digit */
182 +
183 +               for(s = ptname; *s; s++);
184 +               if (isdigit(s[-1])) {
185 +               /*
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
192 +                * be accessed.)
193 +                */
194 +                       sprintf(device, "%s/%s", DEVLABELDIR, ptname);
195 +                       if (!get_label_uuid(device, &label, uuid))
196 +                               uuidcache_addentry(strdup(device), label, uuid);
197                 }
198 +           }
199 +       }
200 +
201 +       fclose(procpt);
202 +}
203 +
204 +#define UUID   1
205 +#define VOL    2
206 +
207 +static char *
208 +get_spec_by_x(int n, const char *t) {
209 +       struct uuidCache_s *uc;
210 +
211 +       uuidcache_init();
212 +       uc = uuidCache;
213 +
214 +       while(uc) {
215 +               switch (n) {
216 +               case UUID:
217 +                       if (!memcmp(t, uc->uuid, sizeof(uc->uuid)))
218 +                               return strdup(uc->device);
219 +                       break;
220 +               case VOL:
221 +                       if (!strcmp(t, uc->label))
222 +                               return strdup(uc->device);
223 +                       break;
224 +               }
225 +               uc = uc->next;
226         }
227 -       procptclose();
228         return NULL;
229  }
230  
231 -static unsigned char
232 +static u_char
233  fromhex(char c) {
234         if (isdigit(c))
235                 return (c - '0');
236 @@ -138,10 +181,9 @@
237  }
238  
239  char *
240 -get_spec_by_uuid(const char *s0) {
241 -       unsigned char uuid[16];
242 +get_spec_by_uuid(const char *s) {
243 +       u_char uuid[16];
244         int i;
245 -       const char *s = s0;
246  
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);
251  
252   bad_uuid:
253 -       fprintf(stderr, _("WARNING: %s: bad UUID"), s0);
254 -       return NULL;
255 +       fprintf(stderr, ("WARNING: bad UUID"));
256 +       return NULL;            /* just for gcc */
257  }
258  
259  char *
260  get_spec_by_volume_label(const char *s) {
261         return get_spec_by_x(VOL, s);
262 +}
263 +
264 +const char *
265 +get_volume_label_by_spec(const char *spec) {
266 +        struct uuidCache_s *uc;
267 +
268 +        uuidcache_init();
269 +        uc = uuidCache;
270 +
271 +       while(uc) {
272 +               if (!strcmp(spec, uc->device))
273 +                       return uc->label;
274 +               uc = uc->next;
275 +       }
276 +       return NULL;
277  }
This page took 0.105741 seconds and 3 git commands to generate.