Mercurial > hg > toybox
comparison toys/mdev.c @ 577:2a757e592ff7
Remove strndupa() gnu-ism at Georgi's suggestion, and adjust mdev to compile with new dirtree. (No idea if it works, this command was never finished and needs a lot more work.)
author | Rob Landley <rob@landley.net> |
---|---|
date | Wed, 09 May 2012 06:39:01 -0500 |
parents | d51be130fda2 |
children | 4877cff01b25 |
comparison
equal
deleted
inserted
replaced
576:4058eacd4fbc | 577:2a757e592ff7 |
---|---|
48 // Try to read major/minor string | 48 // Try to read major/minor string |
49 | 49 |
50 temp = strrchr(path, '/'); | 50 temp = strrchr(path, '/'); |
51 fd = open(path, O_RDONLY); | 51 fd = open(path, O_RDONLY); |
52 *temp=0; | 52 *temp=0; |
53 temp++; | 53 temp = toybuf; |
54 len = read(fd, temp, 64); | 54 len = read(fd, temp, 64); |
55 close(fd); | 55 close(fd); |
56 if (len<1) return; | 56 if (len<1) return; |
57 temp[len] = 0; | 57 temp[len] = 0; |
58 | 58 |
93 end2<end && !isspace(*end2) && *end2!='#'; end2++); | 93 end2<end && !isspace(*end2) && *end2!='#'; end2++); |
94 switch(field) { | 94 switch(field) { |
95 // Regex to match this device | 95 // Regex to match this device |
96 case 3: | 96 case 3: |
97 { | 97 { |
98 char *regex = strndupa(pos, end2-pos); | 98 char *regex = strndup(pos, end2-pos); |
99 regex_t match; | 99 regex_t match; |
100 regmatch_t off; | 100 regmatch_t off; |
101 int result; | 101 int result; |
102 | 102 |
103 // Is this it? | 103 // Is this it? |
104 xregcomp(&match, regex, REG_EXTENDED); | 104 xregcomp(&match, regex, REG_EXTENDED); |
105 result=regexec(&match, device_name, 1, &off, 0); | 105 result=regexec(&match, device_name, 1, &off, 0); |
106 regfree(&match); | 106 regfree(&match); |
107 free(regex); | |
107 | 108 |
108 // If not this device, skip rest of line | 109 // If not this device, skip rest of line |
109 if (result || off.rm_so | 110 if (result || off.rm_so |
110 || off.rm_eo!=strlen(device_name)) | 111 || off.rm_eo!=strlen(device_name)) |
111 goto end_line; | 112 goto end_line; |
123 | 124 |
124 // Parse UID | 125 // Parse UID |
125 uid = strtoul(pos,&s2,10); | 126 uid = strtoul(pos,&s2,10); |
126 if (s!=s2) { | 127 if (s!=s2) { |
127 struct passwd *pass; | 128 struct passwd *pass; |
128 pass = getpwnam(strndupa(pos, s-pos)); | 129 char *str = strndup(pos, s-pos); |
130 pass = getpwnam(str); | |
131 free(str); | |
129 if (!pass) goto end_line; | 132 if (!pass) goto end_line; |
130 uid = pass->pw_uid; | 133 uid = pass->pw_uid; |
131 } | 134 } |
132 s++; | 135 s++; |
133 // parse GID | 136 // parse GID |
134 gid = strtoul(s,&s2,10); | 137 gid = strtoul(s,&s2,10); |
135 if (end2!=s2) { | 138 if (end2!=s2) { |
136 struct group *grp; | 139 struct group *grp; |
137 grp = getgrnam(strndupa(s, end2-s)); | 140 char *str = strndup(s, end2-s); |
141 grp = getgrnam(str); | |
142 free(str); | |
138 if (!grp) goto end_line; | 143 if (!grp) goto end_line; |
139 gid = grp->gr_gid; | 144 gid = grp->gr_gid; |
140 } | 145 } |
141 break; | 146 break; |
142 } | 147 } |
166 | 171 |
167 sprintf(temp, "/dev/%s", device_name); | 172 sprintf(temp, "/dev/%s", device_name); |
168 if (mknod(temp, mode | type, makedev(major, minor)) && errno != EEXIST) | 173 if (mknod(temp, mode | type, makedev(major, minor)) && errno != EEXIST) |
169 perror_exit("mknod %s failed", temp); | 174 perror_exit("mknod %s failed", temp); |
170 | 175 |
171 // Dear gcc: shut up about ignoring the return value here. If it doesn't | |
172 // work, what exactly are we supposed to do about it? | |
173 if (CFG_MDEV_CONF) mode=chown(temp, uid, gid); | 176 if (CFG_MDEV_CONF) mode=chown(temp, uid, gid); |
174 } | 177 } |
175 | 178 |
176 static int callback(char *path, struct dirtree *node) | 179 static int callback(struct dirtree *node) |
177 { | 180 { |
178 // Entries in /sys/class/block aren't char devices, so skip 'em. (We'll | 181 // Entries in /sys/class/block aren't char devices, so skip 'em. (We'll |
179 // get block devices out of /sys/block.) | 182 // get block devices out of /sys/block.) |
180 if(!strcmp(node->name, "block")) return 1; | 183 if(!strcmp(node->name, "block")) return DIRTREE_NOSAVE|DIRTREE_NORECURSE; |
181 | 184 |
182 // Does this directory have a "dev" entry in it? | 185 // Does this directory have a "dev" entry in it? |
186 // This is path based because the hotplug callbacks are | |
183 if (S_ISDIR(node->st.st_mode) || S_ISLNK(node->st.st_mode)) { | 187 if (S_ISDIR(node->st.st_mode) || S_ISLNK(node->st.st_mode)) { |
184 char *dest = path+strlen(path); | 188 int len=4; |
185 strcpy(dest, "/dev"); | 189 char *dev = dirtree_path(node, &len); |
186 if (!access(path, R_OK)) make_device(path); | 190 strcpy(dev+len, "/dev"); |
187 *dest = 0; | 191 if (!access(dev, R_OK)) make_device(dev); |
192 free(dev); | |
188 } | 193 } |
189 | 194 |
190 // Circa 2.6.25 the entries more than 2 deep are all either redundant | 195 // Circa 2.6.25 the entries more than 2 deep are all either redundant |
191 // (mouse#, event#) or unnamed (every usb_* entry is called "device"). | 196 // (mouse#, event#) or unnamed (every usb_* entry is called "device"). |
192 return node->depth>1; | 197 if (node->parent && node->parent->parent) |
198 return DIRTREE_NOSAVE|DIRTREE_NORECURSE; | |
199 return DIRTREE_NOSAVE; | |
193 } | 200 } |
194 | 201 |
195 void mdev_main(void) | 202 void mdev_main(void) |
196 { | 203 { |
197 // Handle -s | 204 // Handle -s |
198 | 205 |
199 if (toys.optflags) { | 206 if (toys.optflags) { |
200 xchdir("/sys/class"); | 207 dirtree_read("/sys/class", callback); |
201 strcpy(toybuf, "/sys/class"); | 208 dirtree_read("/sys/block", callback); |
202 dirtree_read(toybuf, NULL, callback); | |
203 strcpy(toybuf+5, "block"); | |
204 dirtree_read(toybuf, NULL, callback); | |
205 } | 209 } |
206 // if (toys.optflags) { | |
207 // strcpy(toybuf, "/sys/block"); | |
208 // find_dev(toybuf); | |
209 // strcpy(toybuf, "/sys/class"); | |
210 // find_dev(toybuf); | |
211 // return; | |
212 // } | |
213 | 210 |
214 // hotplug support goes here | 211 // hotplug support goes here |
215 } | 212 } |