-
Notifications
You must be signed in to change notification settings - Fork 1
/
devices.c
129 lines (111 loc) · 2.45 KB
/
devices.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
* Routines for parsing /proc/devices for use by the ioctl fuzzer.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <linux/kdev_t.h>
#include "log.h"
static struct {
int major;
int minor;
char *name;
} *block_devs, *char_devs, *misc_devs;
static size_t bldevs, chrdevs, miscdevs;
static void parse_proc_devices(void)
{
FILE *fp;
char *name, *line = NULL;
size_t n = 0;
int block, major;
void *new;
fp = fopen("/proc/devices", "r");
if (!fp)
return;
block = 0;
while (getline(&line, &n, fp) >= 0) {
if (strcmp("Block devices:\n", line) == 0)
block = 1;
else if (sscanf(line, "%d %as", &major, &name) == 2) {
if (block) {
new = realloc(block_devs, (bldevs+1)*sizeof(*block_devs));
if (!new) {
free(name);
continue;
}
block_devs = new;
block_devs[bldevs].major = major;
block_devs[bldevs].minor = 0;
block_devs[bldevs].name = name;
bldevs++;
} else {
new = realloc(char_devs, (chrdevs+1)*sizeof(*char_devs));
if (!new) {
free(name);
continue;
}
char_devs = new;
char_devs[chrdevs].major = major;
char_devs[chrdevs].minor = 0;
char_devs[chrdevs].name = name;
chrdevs++;
}
}
}
fclose(fp);
free(line);
}
static void parse_proc_misc(void)
{
FILE *fp;
char *name;
int minor;
void *new;
fp = fopen("/proc/misc", "r");
if (!fp)
return;
while (fscanf(fp, "%d %as", &minor, &name) == 2) {
new = realloc(misc_devs, (miscdevs+1)*sizeof(*misc_devs));
if (!new) {
free(name);
continue;
}
misc_devs = new;
misc_devs[miscdevs].major = 0;
misc_devs[miscdevs].minor = minor;
misc_devs[miscdevs].name = name;
miscdevs++;
}
fclose(fp);
}
void parse_devices(void)
{
parse_proc_devices();
parse_proc_misc();
output(2, "Parsed %zu char devices, %zu block devices, %zu misc devices.\n",
chrdevs, bldevs, miscdevs);
}
const char *map_dev(dev_t st_rdev, mode_t st_mode)
{
int major, minor;
size_t i, j;
major = MAJOR(st_rdev);
minor = MINOR(st_rdev);
if (S_ISCHR(st_mode))
for (i=0; i < chrdevs; ++i)
if (char_devs[i].major == major) {
if (strcmp(char_devs[i].name, "misc") == 0) {
for (j=0; j < miscdevs; ++j)
if (misc_devs[j].minor == minor)
return misc_devs[j].name;
} else
return char_devs[i].name;
}
else if (S_ISBLK(st_mode))
for (i=0; i < bldevs; ++i)
if (block_devs[i].major == major)
return block_devs[i].name;
return NULL;
}