OSDN Git Service

ChangeLog, Makefile.in, base_device.c, base_device.tst, fsck.c, fsck.h:
[android-x86/external-e2fsprogs.git] / misc / base_device.c
1 /*
2  * base_device.c
3  *
4  * Return the "base device" given a particular device; this is used to
5  * assure that we only fsck one partition on a particular drive at any
6  * one time.  Otherwise, the disk heads will be seeking all over the
7  * place.  If the base device can not be determined, return NULL.
8  * 
9  * The base_device() function returns an allocated string which must
10  * be freed.
11  * 
12  * Written by Theodore Ts'o, <tytso@mit.edu>
13  * 
14  * Copyright (C) 2000 Theodore Ts'o.
15  *
16  * %Begin-Header%
17  * This file may be redistributed under the terms of the GNU Public
18  * License.
19  * %End-Header%
20  */
21 #include <stdio.h>
22 #if HAVE_UNISTD_H
23 #include <unistd.h>
24 #endif
25 #if HAVE_STDLIB_H
26 #include <stdlib.h>
27 #endif
28 #include <ctype.h>
29 #include <string.h>
30
31 #include "fsck.h"
32
33 /*
34  * Required for the uber-silly devfs /dev/ide/host1/bus2/target3/lun3
35  * pathames.
36  */
37 static const char *devfs_hier[] = {
38         "host", "bus", "target", "lun", 0
39 };
40
41 char *base_device(char *device)
42 {
43         char *str, *cp;
44         const char **hier, *disk;
45         int len;
46
47         str = malloc(strlen(device)+1);
48         if (!str)
49                 return NULL;
50         strcpy(str, device);
51         cp = str;
52
53         /* Skip over /dev/; if it's not present, give up. */
54         if (strncmp(cp, "/dev/", 5) != 0)
55                 goto errout;
56         cp += 5;
57
58         /* Skip over /dev/dsk/... */
59         if (strncmp(cp, "dsk/", 4) == 0)
60                 cp += 4;
61         
62         /*
63          * For md devices, we treat them all as if they were all
64          * on one disk, since we don't know how to parallelize them.
65          */
66         if (cp[0] == 'm' && cp[1] == 'd') {
67                 *(cp+2) = 0;
68                 return str;
69         }
70
71         /* Now let's handle /dev/hd* and /dev/sd* devices.... */
72         if ((cp[0] == 'h' || cp[0] == 's') && (cp[1] == 'd')) {
73                 cp += 2;
74                 /* If there's a single number after /dev/hd, skip it */
75                 if (isdigit(*cp))
76                         cp++;
77                 /* What follows must be an alpha char, or give up */
78                 if (!isalpha(*cp))
79                         goto errout;
80                 *(cp + 1) = 0;
81                 return str;
82         }
83
84         /* Now let's handle devfs (ugh) names */
85         len = 0;
86         if (strncmp(cp, "ide/", 4) == 0)
87                 len = 4;
88         if (strncmp(cp, "scsi/", 5) == 0)
89                 len = 5;
90         if (len) {
91                 cp += len;
92                 /*
93                  * Now we proceed down the expected devfs hierarchy.
94                  * i.e., .../host1/bus2/target3/lun4/...
95                  * If we don't find the expected token, followed by
96                  * some number of digits at each level, abort.
97                  */
98                 for (hier = devfs_hier; *hier; hier++) {
99                         len = strlen(*hier);
100                         if (strncmp(cp, *hier, len) != 0)
101                                 goto errout;
102                         cp += len;
103                         while (*cp != '/' && *cp != 0) {
104                                 if (!isdigit(*cp))
105                                         goto errout;
106                                 cp++;
107                         }
108                         cp++;
109                 }
110                 *(cp - 1) = 0;
111                 return str;
112         }
113
114         /* Now handle devfs /dev/disc or /dev/disk names */
115         disk = 0;
116         if (strncmp(cp, "discs/", 6) == 0)
117                 disk = "disc";
118         else if (strncmp(cp, "disks/", 6) == 0)
119                 disk = "disk";
120         if (disk) {
121                 cp += 6;
122                 if (strncmp(cp, disk, 4) != 0)
123                         goto errout;
124                 cp += 4;
125                 while (*cp != '/' && *cp != 0) {
126                         if (!isdigit(*cp))
127                                 goto errout;
128                         cp++;
129                 }
130                 *cp = 0;
131                 return str;
132         }
133
134 errout:
135         free(str);
136         return NULL;
137 }
138
139 #ifdef DEBUG
140
141 main(int argc, char** argv)
142 {
143         const char *base;
144         char  buf[256], *cp;
145
146         while (1) {
147                 if (fgets(buf, sizeof(buf), stdin) == NULL)
148                         break;
149                 cp = strchr(buf, '\n');
150                 if (cp)
151                         *cp = 0;
152                 cp = strchr(buf, '\t');
153                 if (cp)
154                         *cp = 0;
155                 base = base_device(buf);
156                 printf("%s\t%s\n", buf, base ? base : "NONE");
157         }
158         exit(0);
159 }
160
161 #endif