relibc/header/fmtmsg/
mod.rs1use crate::{
9 byte_literal::ByteLiteral,
10 header::{
11 fcntl::{O_WRONLY, open},
12 pthread::{PTHREAD_CANCEL_DISABLE, pthread_setcancelstate},
13 stdio::dprintf,
14 stdlib::getenv,
15 string::strchr,
16 unistd::close,
17 },
18 platform::types::{c_char, c_int, c_long},
19};
20
21pub const MM_HARD: c_int = 1;
25pub const MM_SOFT: c_int = 2;
27pub const MM_FIRM: c_int = 4;
29
30pub const MM_APPL: c_int = 8;
32pub const MM_UTIL: c_int = 16;
34pub const MM_OPSYS: c_int = 32;
36
37pub const MM_RECOVER: c_int = 64;
39pub const MM_NRECOV: c_int = 128;
41
42pub const MM_PRINT: c_long = 256;
44pub const MM_CONSOLE: c_long = 512;
46
47pub const MM_NULLMC: c_long = 0;
49
50pub const MM_HALT: c_int = 1;
52pub const MM_ERROR: c_int = 2;
54pub const MM_WARNING: c_int = 3;
56pub const MM_INFO: c_int = 4;
58pub const MM_NOSEV: c_int = 0;
60
61pub const MM_OK: c_int = 0;
63pub const MM_NOTOK: c_int = -1;
65pub const MM_NOMSG: c_int = 1;
67pub const MM_NOCON: c_int = 4;
69
70pub const MM_NULLSEV: c_int = 0;
72
73unsafe fn strcolcmp(mut lstr: *const c_char, mut bstr: *const c_char) -> c_int {
75 unsafe {
76 while *lstr != 0 && *bstr != 0 && (*lstr == *bstr) {
78 lstr = lstr.add(1);
79 bstr = bstr.add(1);
80 }
81 if *lstr != 0 || (*bstr != 0 && *bstr != ByteLiteral::cast_cchar(b':')) {
82 1
83 } else {
84 0
85 }
86 }
87}
88
89#[unsafe(no_mangle)]
91pub unsafe extern "C" fn fmtmsg(
92 classification: c_long,
93 label: *const c_char,
94 severity: c_int,
95 text: *const c_char,
96 action: *const c_char,
97 tag: *const c_char,
98) -> c_int {
99 let mut ret: c_int = 0;
100 let mut verb: c_int = 0;
101 let mut i: usize;
102 let consolefd: c_int;
103 let mut cs: c_int = 0;
104 unsafe {
105 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &raw mut cs);
106 }
107 let mut cmsg = unsafe { getenv(c"MSGVERB".as_ptr()) };
108 let errstring: *const c_char = match severity {
109 MM_HALT => c"HALT: ".as_ptr(),
110 MM_ERROR => c"ERROR: ".as_ptr(),
111 MM_WARNING => c"WARNING: ".as_ptr(),
112 MM_INFO => c"INFO: ".as_ptr(),
113 _ => MM_NULLSEV as _, };
115 let msgs: [*const c_char; 6] = [
116 c"label".as_ptr(),
117 c"severity".as_ptr(),
118 c"text".as_ptr(),
119 c"action".as_ptr(),
120 c"tag".as_ptr(),
121 core::ptr::null(),
122 ];
123 if (classification & MM_CONSOLE) != 0 {
124 unsafe {
126 consolefd = open(c"/dev/console".as_ptr(), O_WRONLY);
127 if consolefd < 0 {
128 ret = MM_NOCON;
129 } else {
130 #[rustfmt::skip]
131 let status = dprintf(
132 consolefd,
133 c"%s%s%s%s%s%s%s%s\n".as_ptr(),
134 if !label.is_null() {label } else { c"".as_ptr()},
135 if !label.is_null() {c": ".as_ptr()} else { c"".as_ptr() },
136 if severity != 0 { errstring } else { c"".as_ptr()},
137 if !text.is_null() { text } else { c"".as_ptr() },
138 if !action.is_null() {c"\nTO FIX: ".as_ptr()} else { c"".as_ptr()},
139 if !action.is_null() {action} else {c"".as_ptr()},
140 if !action.is_null() {c" ".as_ptr()} else { c"".as_ptr()},
141 if !tag.is_null() { tag } else { c"".as_ptr() },
142 );
143 if status < 1 {
144 ret = MM_NOCON;
145 }
146 close(consolefd);
147 }
148 }
149 }
150 if (classification & MM_PRINT) != 0 {
151 unsafe {
152 while !cmsg.is_null() && *cmsg != 0 {
153 i = 0;
154 loop {
155 if msgs[i].is_null() {
156 break;
157 }
158 if strcolcmp(msgs[i], cmsg) == 0 {
159 break;
160 }
161 i += 1;
162 }
163 if msgs[i].is_null() {
164 verb = 0xFF;
166 break;
167 } else {
168 verb |= 1 << i;
169 cmsg = strchr(cmsg, b':'.into());
170 if !cmsg.is_null() {
171 cmsg = cmsg.add(1);
172 }
173 }
174 }
175 if verb == 0 {
176 verb = 0xFF;
177 }
178 #[rustfmt::skip]
179 let status = dprintf(2,c"%s%s%s%s%s%s%s%s\n".as_ptr(),
180 if (verb & 1 != 0) && !label.is_null() { label } else { c"".as_ptr() },
181 if (verb & 1 != 0) && !label.is_null() { c": ".as_ptr() } else { c"".as_ptr() },
182 if (verb & 2 != 0) && severity != 0 { errstring } else { c"".as_ptr() },
183 if (verb & 4 != 0) && !text.is_null() { text } else { c"".as_ptr() },
184 if (verb & 8 != 0) && !action.is_null() { c"\nTO FIX: ".as_ptr() } else { c"".as_ptr() },
185 if (verb & 8 != 0) && !action.is_null() { action } else { c"".as_ptr() },
186 if (verb & 8 != 0) && !action.is_null() { c" ".as_ptr() } else { c"".as_ptr() },
187 if (verb & 16 != 0) && !tag.is_null() { tag } else { c"".as_ptr() },
188 );
189 if status < 1 {
190 ret |= MM_NOMSG;
191 }
192 }
193 }
194 if ret & (MM_NOCON | MM_NOMSG) == (MM_NOCON | MM_NOMSG) {
195 ret = MM_NOTOK;
196 }
197 unsafe {
198 pthread_setcancelstate(cs, 0 as _);
199 }
200 ret
201}