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 }