/* * miniudev - implement a small udev that can run at bootup * Copyright Frank Sorenson 2005 * * Permission is hereby granted to copy, modify and redistribute this code * in terms of the GNU Library General Public License, Version 2 or later, * at your option. * */ #include #include #include #include #include #include #include #include #include #define DEV_PATH "/dev" #define DEV_MODE 0700 int get_device_info(const char *path, int *major, int *minor) { char buf[512]; int fd; int ret; char *chr; char got_colon = 0; int tempval = 0; sprintf(buf, "%s/dev", path); fd = open(buf, O_RDONLY); ret = read(fd, buf, 1024); buf[ret - 1] = '\0'; if (ret == 0) return -1; close(fd); chr = buf; while (*chr != '\0') { if (*chr == ':') { *major = tempval; tempval = 0; got_colon ++; } else { tempval *= 10; tempval += (*chr - '0'); } chr ++; } *minor = tempval; return 0; } int make_device(const char *path, int type) { char buf[512]; const char *device_name; int major; int minor; int ret; int local_errno; device_name = path; while (*device_name != '\0') device_name ++; while ((*(device_name - 1) != '/') && (device_name > path)) { device_name --; } get_device_info(path, &major, &minor); printf("%s: %d %d\n", device_name, major, minor); sprintf(buf, "%s/%s", DEV_PATH, device_name); ret = mknod(buf, DEV_MODE | type, makedev(major, minor)); if (ret != 0) { local_errno = errno; printf("Could not create device node %s: error %d\n", buf, local_errno); } return 0; } char cmp(const char *s1, const char *s2) { int n = 0; while (s1[n] == s2[n]) { if (s1[n] == '\0') return 1; n++; } return 0; } int find_dev(const char *path, int type) { DIR *dir; struct dirent *entry; char temp_path[512]; int local_errno; dir = opendir(path); if (dir == NULL) { printf("Could not open path %s: error %d\n", path, local_errno); exit(-1); } do { entry = readdir(dir); if (entry == NULL) break; if (cmp(entry->d_name, ".")) continue; if (cmp(entry->d_name, "..")) continue; if (entry->d_type == DT_DIR) { sprintf(temp_path, "%s/%s", path, entry->d_name); find_dev(temp_path, type); } if (cmp(entry->d_name, "dev")) { make_device(path, type); } } while (entry != NULL); closedir(dir); return 0; } int main(int argc, char *argv[]) { find_dev("/sys/block", S_IFBLK); find_dev("/sys/class", S_IFCHR); return 0; }