]> git.ipfire.org Git - ipfire-2.x.git/blob - src/hwinfo/src/hd/klog.c
HWInfo wieder eingefuegt, da mit kudzu zu viele Segmentation Faults liefert.
[ipfire-2.x.git] / src / hwinfo / src / hd / klog.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <sys/klog.h>
5
6 #include "hd.h"
7 #include "hd_int.h"
8 #include "klog.h"
9
10 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
11 * kernel log info
12 *
13 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
14 */
15
16 static int str_ok(str_list_t *sl);
17 static int str_list_cmp(str_list_t *sl1, str_list_t *sl2);
18
19
20 /*
21 * Check if a string starts with '<[0-9]>'.
22 */
23 int str_ok(str_list_t *sl)
24 {
25 return sl->str[0] == '<' && sl->str[2] == '>' && sl->str[1] >= '0' && sl->str[1] <= '9';
26 }
27
28 /*
29 * Check if sl1 is idential to sl2; sl1 may be shorter as sl2.
30 *
31 * Returns 0/1 if they are equal/not equal. If sl1 is NULL, 0 is returned.
32 */
33 int str_list_cmp(str_list_t *sl1, str_list_t *sl2)
34 {
35 for(; sl1; sl1 = sl1->next, sl2 = sl2->next) {
36 if(!sl2 || strcmp(sl1->str, sl2->str)) return 1;
37 }
38
39 return 0;
40 }
41
42 /*
43 * Read kernel log info. Combine with /var/log/boot.msg.
44 */
45 void read_klog(hd_data_t *hd_data)
46 {
47 char buf[0x2000 + 1], *s;
48 int i, j, len, n;
49 str_list_t *sl, *sl1, *sl2, *sl_last, **ssl, *sl_next;
50
51 /* some clean-up */
52 hd_data->klog = free_str_list(hd_data->klog);
53
54 sl1 = read_file(KLOG_BOOT, 0, 0);
55 sl2 = NULL;
56
57 /*
58 * remove non-canonical lines (not starting with <[0-9]>) at the start and
59 * at the end
60 */
61
62 /* note: the implementations assumes that at least *one* line is ok */
63 for(sl_last = NULL, sl = sl1; sl; sl = (sl_last = sl)->next) {
64 if(str_ok(sl)) {
65 if(sl_last) {
66 sl_last->next = NULL;
67 free_str_list(sl1);
68 sl1 = sl;
69 }
70 break;
71 }
72 }
73
74 for(sl_last = NULL, sl = sl1; sl; sl = (sl_last = sl)->next) {
75 if(!str_ok(sl)) {
76 if(sl_last) {
77 sl_last->next = NULL;
78 free_str_list(sl);
79 }
80 break;
81 }
82 }
83
84 n = klogctl(3, buf, sizeof buf - 1);
85 if(n <= 0) {
86 hd_data->klog = sl1;
87 return;
88 }
89
90 if(n > (int) sizeof buf - 1) n = sizeof buf - 1;
91 buf[n] = 0;
92 for(i = j = 0; i < n; i++) {
93 if(buf[i] == '\n') {
94 len = i - j + 1;
95 s = new_mem(len + 1);
96 memcpy(s, buf + j, len);
97 add_str_list(&sl2, s);
98 s = free_mem(s);
99 j = i + 1;
100 }
101 }
102
103 /* the 1st line may be incomplete */
104 if(sl2 && !str_ok(sl2)) {
105 sl_next = sl2->next;
106 sl2->next = NULL;
107 free_str_list(sl2);
108 sl2 = sl_next;
109 }
110
111 if(!sl1) {
112 hd_data->klog = sl2;
113 return;
114 }
115
116 if(sl1 && !sl2) {
117 hd_data->klog = sl1;
118 return;
119 }
120
121 /* now, try to join sl1 & sl2 */
122 for(sl_last = NULL, sl = sl1; sl; sl = (sl_last = sl)->next) {
123 if(!str_list_cmp(sl, sl2)) {
124 free_str_list(sl);
125 if(sl_last)
126 sl_last->next = NULL;
127 else
128 sl1 = NULL;
129 break;
130 }
131 }
132
133 /* append sl2 to sl1 */
134 for(ssl = &sl1; *ssl; ssl = &(*ssl)->next);
135 *ssl = sl2;
136
137 hd_data->klog = sl1;
138 }
139
140
141 /*
142 * Add some klog data to the global log.
143 */
144 void dump_klog(hd_data_t *hd_data)
145 {
146 str_list_t *sl;
147
148 ADD2LOG("----- kernel log -----\n");
149 for(sl = hd_data->klog; sl; sl = sl->next) {
150 ADD2LOG(" %s", sl->str);
151 }
152 ADD2LOG("----- kernel log end -----\n");
153 }