]>
Commit | Line | Data |
---|---|---|
93afd047 MT |
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 | } |