File: | initd/mkdev.c |
Warning: | line 126, column 2 Address of stack memory associated with local variable 'pattern' is still referred to by the global variable 'patterns' upon returning to the caller. This will be a dangling reference |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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_SOURCE1 | |||
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_MAX4096]; | |||
35 | static char buf2[PATH_MAX4096]; | |||
36 | static unsigned int mode = 0600; | |||
37 | ||||
38 | static bool_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 true1; | |||
45 | ||||
46 | return false0; | |||
47 | } | |||
48 | ||||
49 | static void make_dev(const char *path, bool_Bool block, int major, int minor) | |||
50 | { | |||
51 | unsigned int oldumask = umask(0); | |||
52 | unsigned int _mode = mode | (block ? S_IFBLK0060000 : S_IFCHR0020000); | |||
53 | ||||
54 | DEBUG(4, "Creating %s device %s(%d,%d)\n",do { if (debug >= 4) { ulog(5, "Creating %s device %s(%d,%d)\n" , block ? "block" : "character", path, major, minor); } } while (0) | |||
55 | block ? "block" : "character",do { if (debug >= 4) { ulog(5, "Creating %s device %s(%d,%d)\n" , block ? "block" : "character", path, major, minor); } } while (0) | |||
56 | path, major, minor)do { if (debug >= 4) { ulog(5, "Creating %s device %s(%d,%d)\n" , block ? "block" : "character", path, major, minor); } } while (0); | |||
57 | ||||
58 | mknod(path, _mode, makedev(major, minor)gnu_dev_makedev (major, minor)); | |||
59 | umask(oldumask); | |||
60 | } | |||
61 | ||||
62 | static void find_devs(bool_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((void*)0)) { | |||
74 | char *c; | |||
75 | int major = 0, minor = 0; | |||
76 | int len; | |||
77 | ||||
78 | if (dp->d_type != DT_LNKDT_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)); | |||
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(true1); | |||
124 | find_devs(false0); | |||
125 | free(pattern); | |||
126 | return chdir("/"); | |||
| ||||
127 | } |