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