]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/hwinfo/src/hd/sys.c
Kleiner netter neuer Versuch.
[people/teissler/ipfire-2.x.git] / src / hwinfo / src / hd / sys.c
1 #define _GNU_SOURCE /* we want memmem() */
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <unistd.h>
6 #include <signal.h>
7 #include <ctype.h>
8
9 #include <sys/types.h>
10 #include <sys/wait.h>
11
12 #include "hd.h"
13 #include "hd_int.h"
14 #include "sys.h"
15
16 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
17 * general system info
18 *
19 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
20 */
21
22 #if defined(__i386__)
23 static void sigsegv_handler(int signum);
24 static void chk_vmware(hd_data_t *hd_data, sys_info_t *st);
25 #endif
26
27 #if defined(__i386__) || defined(__x86_64__)
28 static int is_txt(char c);
29 static int is_decimal(char c);
30 static int txt_len(char *s);
31 static int decimal_len(char *s);
32 static int chk_vaio(hd_data_t *hd_data, sys_info_t *st);
33 #ifdef UCLIBC
34 void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen);
35 #endif
36 #endif
37
38 void hd_scan_sys(hd_data_t *hd_data)
39 {
40 hd_t *hd;
41 sys_info_t *st;
42 #if defined(__PPC__) || defined(__sparc__)
43 char buf0[80], *s, *t;
44 str_list_t *sl;
45 #endif
46
47 if(!hd_probe_feature(hd_data, pr_sys)) return;
48
49 hd_data->module = mod_sys;
50
51 /* some clean-up */
52 remove_hd_entries(hd_data);
53
54 PROGRESS(1, 0, "cpu");
55
56 hd = add_hd_entry(hd_data, __LINE__, 0);
57 hd->base_class.id = bc_internal;
58 hd->sub_class.id = sc_int_sys;
59 hd->detail = new_mem(sizeof *hd->detail);
60 hd->detail->type = hd_detail_sys;
61 hd->detail->sys.data = st = new_mem(sizeof *st);
62
63 if(!hd_data->cpu) {
64 hd_data->cpu = read_file(PROC_CPUINFO, 0, 0);
65 }
66
67 #ifdef __PPC__
68 for(sl = hd_data->cpu; sl; sl = sl->next) {
69 if(sscanf(sl->str, "motherboard : %79[^\n]", buf0) == 1) {
70 if((s = strstr(buf0, "MacRISC"))) {
71 for(t = s + sizeof "MacRISC" - 1; isalnum(*t); t++);
72 *t = 0;
73 st->system_type = new_str(s);
74 hd_data->flags.no_parport = 1;
75 }
76 }
77 if(sscanf(sl->str, "machine : %79[^\n]", buf0) == 1) {
78 if(strstr(buf0, "PReP")) {
79 st->system_type = new_str("PReP");
80 }
81 else if(strstr(buf0, "CHRP")) {
82 st->system_type = new_str(/* is_64 ? "CHRP64" : */ "CHRP");
83 }
84 else if(strstr(buf0, "iSeries")) {
85 st->system_type = new_str("iSeries");
86 hd_data->flags.iseries = 1;
87 }
88 if(strstr(buf0, "PowerBook2,")) {
89 st->model = new_str("iBook");
90 }
91 else if(strstr(buf0, "PowerBook")) {
92 st->model = new_str("PowerBook");
93 }
94 }
95 if(sscanf(sl->str, "pmac-generation : %79[^\n]", buf0) == 1) {
96 st->generation = new_str(buf0);
97 }
98 }
99 #endif /* __PPC__ */
100
101 #ifdef __sparc__
102 for(sl = hd_data->cpu; sl; sl = sl->next) {
103 if(sscanf(sl->str, "type : %79[^\n]", buf0) == 1) {
104 st->system_type = new_str(buf0);
105 }
106 }
107 #endif
108
109 #if defined(__i386__) || defined(__x86_64__)
110 chk_vaio(hd_data, st);
111 #endif
112
113 #if defined(__i386__)
114 chk_vmware(hd_data, st);
115 #endif
116
117 if(st->vendor) hd->vendor.name = new_str(st->vendor);
118 if(st->model) hd->device.name = new_str(st->model);
119 if(st->serial) hd->serial = new_str(st->serial);
120 }
121
122 #if defined(__i386__)
123 void sigsegv_handler(int signum) { exit(77); }
124
125 void chk_vmware(hd_data_t *hd_data, sys_info_t *st)
126 {
127 static int is_vmware = -1;
128 int child, status;
129
130 /* do the check only once */
131 if(is_vmware < 0) {
132
133 child = fork();
134
135 if(child == 0) {
136 signal(SIGSEGV, sigsegv_handler);
137
138 asm(
139 "push %ebx\n"
140 "\tpush %edx\n"
141 "\tpush %eax\n"
142 "\tpush %ecx\n"
143 "\tmov $0x564d5868,%eax\n"
144 "\tmov $0xa,%ecx\n"
145 "\tmov $0x5658,%edx\n"
146 "\tin (%dx),%eax\n"
147 "\tpop %ecx\n"
148 "\tpop %eax\n"
149 "\tpop %edx\n"
150 "\tpop %ebx\n"
151 );
152
153 _exit(66);
154 }
155 else {
156 if(waitpid(child, &status, 0) == child) {
157 status = WEXITSTATUS(status);
158 if(status == 66) is_vmware = 1;
159 if(status == 77) is_vmware = 0;
160 }
161 }
162
163 ADD2LOG(" vmware check: %d\n", is_vmware);
164 }
165
166 if(is_vmware == 1) {
167 st->model = new_str("VMWare");
168 }
169
170 hd_data->in_vmware = is_vmware;
171 }
172
173 #endif /* __i386__ */
174
175
176 #if defined(__i386__) || defined(__x86_64__)
177 int is_txt(char c)
178 {
179 if(c < ' ' || c == 0x7f) return 0;
180
181 return 1;
182 }
183
184 int is_decimal(char c)
185 {
186 if(c < '0' || c > '9') return 0;
187
188 return 1;
189 }
190
191 int txt_len(char *s)
192 {
193 int i;
194
195 for(i = 0; i < 0x100; i++) {
196 if(!is_txt(s[i])) break;
197 }
198
199 return i;
200 }
201
202 int decimal_len(char *s)
203 {
204 int i;
205
206 for(i = 0; i < 0x100; i++) {
207 if(!is_decimal(s[i])) break;
208 }
209
210 return i;
211 }
212
213 int chk_vaio(hd_data_t *hd_data, sys_info_t *st)
214 {
215 int i;
216 unsigned char *data, *s, *s0, *s1;
217
218 if(!hd_data->bios_rom.data) return 0;
219
220 data = hd_data->bios_rom.data + 0xe8000 - hd_data->bios_rom.start;
221
222 if(!(s = memmem(data, 0x10000, "Sony Corp", sizeof "Sony Corp" - 1))) return 0;
223
224 if((i = txt_len(s))) st->vendor = canon_str(s, i);
225 s += i;
226
227 if(!(s = memmem(s, 0x1000, "PCG-", sizeof "PCG-" - 1))) return 0;
228
229 if((i = txt_len(s))) {
230 st->model = canon_str(s, i);
231 }
232 s += i;
233
234 ADD2LOG(" vaio: %s\n", st->model);
235
236 for(i = 0; i < 0x1000; i++) {
237 if(is_decimal(s[i]) && txt_len(s + i) >= 10 && decimal_len(s + i) >= 5) {
238 st->serial = canon_str(s + i, txt_len(s + i));
239 break;
240 }
241 }
242
243 if(st->model) {
244 s0 = strrchr(st->model, '(');
245 s1 = strrchr(st->model, ')');
246
247 if(s0 && s1 && s1 - s0 >= 3 && s1[1] == 0) {
248 st->lang = canon_str(s0 + 1, s1 - s0 - 1);
249 for(s = st->lang; *s; s++) {
250 if(*s >= 'A' && *s <= 'Z') *s += 'a' - 'A';
251 }
252 if(!strcmp(st->lang, "uc")) strcpy(st->lang, "en");
253 *s0 = 0; /* cut the model entry */
254 }
255 }
256
257 return st->model ? 1 : 0;
258 }
259 #endif /* __i386__ || __x86_64__ */
260