1 /* 2 * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org> 3 * Copyright (C) 2013 John Crispin <blogic@openwrt.org> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU Lesser General Public License version 2.1 7 * as published by the Free Software Foundation 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 */ 14 15 #define _DEFAULT_SOURCE 16 17 #include <sys/stat.h> 18 #include <sys/types.h> 19 #include <sys/sysmacros.h> 20 21 #include <stdio.h> 22 #include <string.h> 23 #include <stdlib.h> 24 #include <unistd.h> 25 #include <stdbool.h> 26 #include <dirent.h> 27 #include <limits.h> 28 #include <fnmatch.h> 29 30 #include "init.h" 31 32 static char **patterns; 33 static int n_patterns; 34 static char buf[PATH_MAX]; 35 static char buf2[PATH_MAX]; 36 static unsigned int mode = 0600; 37 38 static bool find_pattern(const char *name) 39 { 40 int i; 41 42 for (i = 0; i < n_patterns; i++) 43 if (!fnmatch(patterns[i], name, 0)) 44 return true; 45 46 return false; 47 } 48 49 static void make_dev(const char *path, bool block, int major, int minor) 50 { 51 unsigned int oldumask = umask(0); 52 unsigned int _mode = mode | (block ? S_IFBLK : S_IFCHR); 53 54 DEBUG(4, "Creating %s device %s(%d,%d)\n", 55 block ? "block" : "character", 56 path, major, minor); 57 58 mknod(path, _mode, makedev(major, minor)); 59 umask(oldumask); 60 } 61 62 static void find_devs(bool block) 63 { 64 char *path = block ? "/sys/dev/block" : "/sys/dev/char"; 65 struct dirent *dp; 66 DIR *dir; 67 68 dir = opendir(path); 69 if (!dir) 70 return; 71 72 path = buf2 + sprintf(buf2, "%s/", path); 73 while ((dp = readdir(dir)) != NULL) { 74 char *c; 75 int major = 0, minor = 0; 76 int len; 77 78 if (dp->d_type != DT_LNK) 79 continue; 80 81 if (sscanf(dp->d_name, "%d:%d", &major, &minor) != 2) 82 continue; 83 84 strcpy(path, dp->d_name); 85 len = readlink(buf2, buf, sizeof(buf) - 1); 86 if (len <= 0) 87 continue; 88 89 buf[len] = 0; 90 if (!find_pattern(buf)) 91 continue; 92 93 c = strrchr(buf, '/'); 94 if (!c) 95 continue; 96 97 c++; 98 make_dev(c, block, major, minor); 99 } 100 closedir(dir); 101 } 102 103 static char *add_pattern(const char *name) 104 { 105 char *str = malloc(strlen(name) + 2); 106 107 str[0] = '*'; 108 strcpy(str + 1, name); 109 return str; 110 } 111 112 int mkdev(const char *name, int _mode) 113 { 114 char *pattern; 115 116 if (chdir("/dev")) 117 return 1; 118 119 pattern = add_pattern(name); 120 patterns = &pattern; 121 mode = _mode; 122 n_patterns = 1; 123 find_devs(true); 124 find_devs(false); 125 free(pattern); 126 return chdir("/"); 127 } 128
This page was automatically generated by LXR 0.3.1. • OpenWrt