refactor: safe logging macros

This commit is contained in:
dignifiedquire
2019-05-30 12:24:01 +02:00
parent f607dd3073
commit 37cfcae42f
7 changed files with 123 additions and 209 deletions

View File

@@ -1523,7 +1523,7 @@ unsafe fn moz_autoconfigure_starttag_cb(
} }
fn read_autoconf_file(context: &Context, url: *const libc::c_char) -> *mut libc::c_char { fn read_autoconf_file(context: &Context, url: *const libc::c_char) -> *mut libc::c_char {
info!(context, 0, "Testing %s ...", url); info!(context, 0, "Testing {} ...", to_string(url));
match reqwest::Client::new() match reqwest::Client::new()
.get(to_str(url)) .get(to_str(url))

View File

@@ -94,16 +94,14 @@ macro_rules! info {
($ctx:expr, $data1:expr, $msg:expr) => { ($ctx:expr, $data1:expr, $msg:expr) => {
info!($ctx, $data1, $msg,) info!($ctx, $data1, $msg,)
}; };
($ctx:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => { ($ctx:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => {{
let formatted = format!($msg, $($args),*);
let formatted_c = crate::dc_tools::to_cstring(formatted);
unsafe { unsafe {
dc_log_info( ($ctx.cb)($ctx, crate::constants::Event::INFO, $data1 as uintptr_t,
$ctx, crate::dc_tools::dc_strdup(formatted_c.as_ptr()) as uintptr_t)
$data1,
std::ffi::CString::new($msg).unwrap().as_ptr(),
$($args),*
)
} }
}; }};
} }
#[macro_export] #[macro_export]
@@ -112,13 +110,11 @@ macro_rules! warn {
warn!($ctx, $data1, $msg,) warn!($ctx, $data1, $msg,)
}; };
($ctx:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => { ($ctx:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => {
let formatted = format!($msg, $($args),*);
let formatted_c = crate::dc_tools::to_cstring(formatted);
unsafe { unsafe {
dc_log_warning( ($ctx.cb)($ctx, crate::constants::Event::WARNING, $data1 as libc::uintptr_t,
$ctx, crate::dc_tools::dc_strdup(formatted_c.as_ptr()) as libc::uintptr_t)
$data1,
std::ffi::CString::new($msg).unwrap().as_ptr(),
$($args),*
)
} }
}; };
} }
@@ -129,13 +125,11 @@ macro_rules! error {
error!($ctx, $data1, $msg,) error!($ctx, $data1, $msg,)
}; };
($ctx:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => { ($ctx:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => {
let formatted = format!($msg, $($args),*);
let formatted_c = crate::dc_tools::to_cstring(formatted);
unsafe { unsafe {
dc_log_error( ($ctx.cb)($ctx, crate::constants::Event::ERROR, $data1 as uintptr_t,
$ctx, crate::dc_tools::dc_strdup(formatted_c.as_ptr()) as uintptr_t)
$data1,
std::ffi::CString::new($msg).unwrap().as_ptr(),
$($args),*
)
} }
}; };
} }
@@ -146,14 +140,11 @@ macro_rules! log_event {
log_event!($ctx, $data1, $msg,) log_event!($ctx, $data1, $msg,)
}; };
($ctx:expr, $event:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => { ($ctx:expr, $event:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => {
let formatted = format!($msg, $($args),*);
let formatted_c = crate::dc_tools::to_cstring(formatted);
unsafe { unsafe {
dc_log_event( ($ctx.cb)($ctx, $event, $data1 as uintptr_t,
$ctx, crate::dc_tools::dc_strdup(formatted_c.as_ptr()) as uintptr_t)
$event,
$data1,
std::ffi::CString::new($msg).unwrap().as_ptr(),
$($args),*
)
} }
}; };
} }

View File

@@ -5,7 +5,6 @@ use std::time::{Duration, SystemTime};
use crate::constants::*; use crate::constants::*;
use crate::context::Context; use crate::context::Context;
use crate::dc_log::*;
use crate::dc_loginparam::*; use crate::dc_loginparam::*;
use crate::dc_sqlite3::*; use crate::dc_sqlite3::*;
use crate::dc_tools::{to_str, to_string}; use crate::dc_tools::{to_str, to_string};
@@ -441,10 +440,10 @@ impl Imap {
context, context,
Event::ERROR_NETWORK, Event::ERROR_NETWORK,
0, 0,
format!( "Could not connect to IMAP-server {}:{}. ({})",
"Could not connect to IMAP-server {}:{}. ({})", imap_server,
imap_server, imap_port, err imap_port,
), err
); );
return 0; return 0;
@@ -459,13 +458,7 @@ impl Imap {
1 1
} }
Err((err, _)) => { Err((err, _)) => {
log_event!( log_event!(context, Event::ERROR_NETWORK, 0, "Cannot login ({})", err);
context,
Event::ERROR_NETWORK,
0,
format!("Cannot login ({})", err),
);
self.unsetup_handle(context); self.unsetup_handle(context);
0 0
@@ -560,9 +553,8 @@ impl Imap {
s += c; s += c;
s s
}); });
let caps_list_c = std::ffi::CString::new(caps_list).unwrap();
info!(context, 0, "IMAP-capabilities:%s", caps_list_c.as_ptr()); info!(context, 0, "IMAP-capabilities:{}", caps_list);
let mut config = self.config.write().unwrap(); let mut config = self.config.write().unwrap();
config.can_idle = can_idle; config.can_idle = can_idle;
@@ -641,12 +633,7 @@ impl Imap {
// deselect existing folder, if needed (it's also done implicitly by SELECT, however, without EXPUNGE then) // deselect existing folder, if needed (it's also done implicitly by SELECT, however, without EXPUNGE then)
if self.config.read().unwrap().selected_folder_needs_expunge { if self.config.read().unwrap().selected_folder_needs_expunge {
if let Some(ref folder) = self.config.read().unwrap().selected_folder { if let Some(ref folder) = self.config.read().unwrap().selected_folder {
info!( info!(context, 0, "Expunge messages in \"{}\".", folder);
context,
0,
"Expunge messages in \"%s\".",
CString::new(folder.to_owned()).unwrap().as_ptr()
);
// A CLOSE-SELECT is considerably faster than an EXPUNGE-SELECT, see // A CLOSE-SELECT is considerably faster than an EXPUNGE-SELECT, see
// https://tools.ietf.org/html/rfc3501#section-6.4.2 // https://tools.ietf.org/html/rfc3501#section-6.4.2
@@ -677,7 +664,9 @@ impl Imap {
info!( info!(
context, context,
0, 0,
format!("Cannot select folder: {}; {:?}.", folder.as_ref(), err) "Cannot select folder: {}; {:?}.",
folder.as_ref(),
err
); );
let mut config = self.config.write().unwrap(); let mut config = self.config.write().unwrap();
@@ -721,8 +710,8 @@ impl Imap {
info!( info!(
context, context,
0, 0,
"Cannot fetch from \"%s\" - not connected.", "Cannot fetch from \"{}\" - not connected.",
CString::new(folder.as_ref().to_owned()).unwrap().as_ptr(), folder.as_ref()
); );
return 0; return 0;
@@ -732,8 +721,8 @@ impl Imap {
info!( info!(
context, context,
0, 0,
"Cannot select folder \"%s\" for fetching.", "Cannot select folder \"{}\" for fetching.",
CString::new(folder.as_ref().to_owned()).unwrap().as_ptr(), folder.as_ref()
); );
return 0; return 0;
@@ -749,8 +738,8 @@ impl Imap {
error!( error!(
context, context,
0, 0,
"Cannot get UIDVALIDITY for folder \"%s\".", "Cannot get UIDVALIDITY for folder \"{}\".",
CString::new(folder.as_ref().to_owned()).unwrap().as_ptr(), folder.as_ref(),
); );
return 0; return 0;
@@ -760,12 +749,7 @@ impl Imap {
// first time this folder is selected or UIDVALIDITY has changed, init lastseenuid and save it to config // first time this folder is selected or UIDVALIDITY has changed, init lastseenuid and save it to config
if mailbox.exists == 0 { if mailbox.exists == 0 {
info!( info!(context, 0, "Folder \"{}\" is empty.", folder.as_ref());
context,
0,
"Folder \"%s\" is empty.",
CString::new(folder.as_ref().to_owned()).unwrap().as_ptr()
);
// set lastseenuid=0 for empty folders. // set lastseenuid=0 for empty folders.
// id we do not do this here, we'll miss the first message // id we do not do this here, we'll miss the first message
@@ -780,15 +764,13 @@ impl Imap {
let set = format!("{}", mailbox.exists); let set = format!("{}", mailbox.exists);
match session.fetch(set, PREFETCH_FLAGS) { match session.fetch(set, PREFETCH_FLAGS) {
Ok(list) => list, Ok(list) => list,
Err(err) => { Err(_err) => {
self.config.write().unwrap().should_reconnect = true; self.config.write().unwrap().should_reconnect = true;
eprintln!("fetch error: {:?}", err);
info!( info!(
context, context,
0, 0,
"No result returned for folder \"%s\".", "No result returned for folder \"{}\".",
CString::new(folder.as_ref().to_owned()).unwrap().as_ptr() folder.as_ref()
); );
return 0; return 0;
@@ -810,10 +792,10 @@ impl Imap {
info!( info!(
context, context,
0, 0,
"lastseenuid initialized to %i for %s@%i", "lastseenuid initialized to {} for {}@{}",
last_seen_uid as libc::c_int, last_seen_uid,
CString::new(folder.as_ref().to_owned()).unwrap().as_ptr(), folder.as_ref(),
uid_validity as libc::c_int uid_validity,
); );
} }
@@ -858,9 +840,9 @@ impl Imap {
info!( info!(
context, context,
0, 0,
"Read error for message %s from \"%s\", trying over later.", "Read error for message {} from \"{}\", trying over later.",
message_id_c.as_ptr(), message_id,
folder_c.as_ptr() folder.as_ref()
); );
read_errors += 1; read_errors += 1;
@@ -870,9 +852,9 @@ impl Imap {
info!( info!(
context, context,
0, 0,
"Skipping message %s from \"%s\" by precheck.", "Skipping message {} from \"{}\" by precheck.",
message_id_c.as_ptr(), message_id,
folder_c.as_ptr() folder.as_ref(),
); );
} }
if cur_uid > new_last_seen_uid { if cur_uid > new_last_seen_uid {
@@ -891,18 +873,18 @@ impl Imap {
warn!( warn!(
context, context,
0, 0,
"%i mails read from \"%s\" with %i errors.", "{} mails read from \"{}\" with {} errors.",
read_cnt as libc::c_int, read_cnt,
CString::new(folder.as_ref().to_owned()).unwrap().as_ptr(), folder.as_ref(),
read_errors as libc::c_int, read_errors
); );
} else { } else {
info!( info!(
context, context,
0, 0,
"%i mails read from \"%s\".", "{} mails read from \"{}\".",
read_cnt as libc::c_int, read_cnt,
CString::new(folder.as_ref().to_owned()).unwrap().as_ptr() folder.as_ref()
); );
} }
@@ -953,13 +935,11 @@ impl Imap {
warn!( warn!(
context, context,
0, 0,
format!( "Error on fetching message #{} from folder \"{}\"; retry={}; error={}.",
"Error on fetching message #%i from folder \"%s\"; retry=%i; error={}.", server_uid,
err folder.as_ref(),
), self.should_reconnect(),
server_uid as libc::c_int, err
CString::new(folder.as_ref().to_owned()).unwrap().as_ptr(),
self.should_reconnect() as libc::c_int,
); );
if self.should_reconnect() { if self.should_reconnect() {
@@ -978,9 +958,9 @@ impl Imap {
warn!( warn!(
context, context,
0, 0,
"Message #%i does not exist in folder \"%s\".", "Message #{} does not exist in folder \"{}\".",
server_uid as libc::c_int, server_uid,
CString::new(folder.as_ref().to_owned()).unwrap().as_ptr(), folder.as_ref()
); );
} else { } else {
let msg = &msgs[0]; let msg = &msgs[0];
@@ -1089,11 +1069,7 @@ impl Imap {
self.config.write().unwrap().should_reconnect = true; self.config.write().unwrap().should_reconnect = true;
} }
_ => { _ => {
warn!( warn!(context, 0, "IMAP-IDLE returns unknown value: {}", err);
context,
0,
format!("IMAP-IDLE returns unknown value: {:?}", err)
);
} }
}, },
}; };
@@ -1204,12 +1180,10 @@ impl Imap {
info!( info!(
context, context,
0, 0,
"Skip moving message; message %s/%i is already in %s...", "Skip moving message; message {}/{} is already in {}...",
CString::new(folder.as_ref().to_owned()).unwrap().as_ptr(), folder.as_ref(),
uid as libc::c_int, uid,
CString::new(dest_folder.as_ref().to_owned()) dest_folder.as_ref()
.unwrap()
.as_ptr()
); );
res = DC_ALREADY_DONE; res = DC_ALREADY_DONE;
@@ -1217,20 +1191,18 @@ impl Imap {
info!( info!(
context, context,
0, 0,
"Moving message %s/%i to %s...", "Moving message {}/{} to {}...",
CString::new(folder.as_ref().to_owned()).unwrap().as_ptr(), folder.as_ref(),
uid as libc::c_int, uid,
CString::new(dest_folder.as_ref().to_owned()) dest_folder.as_ref()
.unwrap()
.as_ptr()
); );
if self.select_folder(context, Some(folder.as_ref())) == 0 { if self.select_folder(context, Some(folder.as_ref())) == 0 {
warn!( warn!(
context, context,
0, 0,
"Cannot select folder %s for moving message.", "Cannot select folder {} for moving message.",
CString::new(folder.as_ref().to_owned()).unwrap().as_ptr(), folder.as_ref()
); );
} else { } else {
let moved = if let Some(ref mut session) = self.session.lock().unwrap().0 { let moved = if let Some(ref mut session) = self.session.lock().unwrap().0 {
@@ -1240,16 +1212,14 @@ impl Imap {
true true
} }
Err(err) => { Err(err) => {
eprintln!("move error: {:?}", err);
info!( info!(
context, context,
0, 0,
"Cannot move message, fallback to COPY/DELETE %s/%i to %s...", "Cannot move message, fallback to COPY/DELETE {}/{} to {}: {}",
CString::new(folder.as_ref().to_owned()).unwrap().as_ptr(), folder.as_ref(),
uid as libc::c_int, uid,
CString::new(dest_folder.as_ref().to_owned()) dest_folder.as_ref(),
.unwrap() err
.as_ptr()
); );
false false
@@ -1326,22 +1296,20 @@ impl Imap {
if uid == 0 { if uid == 0 {
res = DC_FAILED res = DC_FAILED
} else if self.is_connected() { } else if self.is_connected() {
let folder_c = CString::new(folder.as_ref().to_owned()).unwrap();
info!( info!(
context, context,
0, 0,
"Marking message %s/%i as seen...", "Marking message {}/{} as seen...",
folder_c.as_ptr(), folder.as_ref(),
uid as libc::c_int uid,
); );
if self.select_folder(context, Some(folder)) == 0 { if self.select_folder(context, Some(folder.as_ref())) == 0 {
warn!( warn!(
context, context,
0, 0,
"Cannot select folder %s for setting SEEN flag.", "Cannot select folder {} for setting SEEN flag.",
folder_c.as_ptr(), folder.as_ref(),
); );
} else if self.add_flag(uid, "\\Seen") == 0 { } else if self.add_flag(uid, "\\Seen") == 0 {
warn!(context, 0, "Cannot mark message as seen.",); warn!(context, 0, "Cannot mark message as seen.",);
@@ -1369,21 +1337,20 @@ impl Imap {
if uid == 0 { if uid == 0 {
res = DC_FAILED; res = DC_FAILED;
} else if self.is_connected() { } else if self.is_connected() {
let folder_c = CString::new(folder.as_ref().to_owned()).unwrap();
info!( info!(
context, context,
0, 0,
"Marking message %s/%i as $MDNSent...", "Marking message {}/{} as $MDNSent...",
folder_c.as_ptr(), folder.as_ref(),
uid as libc::c_int uid,
); );
if self.select_folder(context, Some(folder)) == 0 { if self.select_folder(context, Some(folder.as_ref())) == 0 {
warn!( warn!(
context, context,
0, 0,
"Cannot select folder %s for setting $MDNSent flag.", "Cannot select folder {} for setting $MDNSent flag.",
folder_c.as_ptr(), folder.as_ref()
); );
} else { } else {
// Check if the folder can handle the `$MDNSent` flag (see RFC 3503). If so, and not // Check if the folder can handle the `$MDNSent` flag (see RFC 3503). If so, and not
@@ -1447,13 +1414,11 @@ impl Imap {
res res
}; };
let msg = if res == DC_SUCCESS { if res == DC_SUCCESS {
"$MDNSent just set and MDN will be sent." info!(context, 0, "$MDNSent just set and MDN will be sent.");
} else { } else {
"$MDNSent already set and MDN already sent." info!(context, 0, "$MDNSent already set and MDN already sent.");
}; }
info!(context, 0, msg);
} }
} else { } else {
res = DC_SUCCESS; res = DC_SUCCESS;
@@ -1491,22 +1456,18 @@ impl Imap {
info!( info!(
context, context,
0, 0,
format!( "Marking message \"{}\", {}/{} for deletion...",
"Marking message \"{}\", {}/{} for deletion...", message_id.as_ref(),
message_id.as_ref(), folder.as_ref(),
folder.as_ref(), server_uid,
server_uid,
)
); );
if self.select_folder(context, Some(&folder)) == 0 { if self.select_folder(context, Some(&folder)) == 0 {
warn!( warn!(
context, context,
0, 0,
format!( "Cannot select folder {} for deleting message.",
"Cannot select folder {} for deleting message.", folder.as_ref()
folder.as_ref()
)
); );
} else { } else {
let set = format!("{}", server_uid); let set = format!("{}", server_uid);
@@ -1526,12 +1487,10 @@ impl Imap {
warn!( warn!(
context, context,
0, 0,
format!( "Cannot delete on IMAP, {}/{} does not match {}.",
"Cannot delete on IMAP, {}/{} does not match {}.", folder.as_ref(),
folder.as_ref(), server_uid,
server_uid, message_id.as_ref(),
message_id.as_ref(),
)
); );
*server_uid = 0; *server_uid = 0;
} }
@@ -1542,11 +1501,9 @@ impl Imap {
warn!( warn!(
context, context,
0, 0,
format!( "Cannot delete on IMAP, {}/{} not found.",
"Cannot delete on IMAP, {}/{} not found.", folder.as_ref(),
folder.as_ref(), server_uid,
server_uid,
)
); );
*server_uid = 0; *server_uid = 0;
} }
@@ -1594,12 +1551,7 @@ impl Imap {
}); });
if mvbox_folder.is_none() && 0 != (flags as usize & DC_CREATE_MVBOX) { if mvbox_folder.is_none() && 0 != (flags as usize & DC_CREATE_MVBOX) {
info!( info!(context, 0, "Creating MVBOX-folder \"DeltaChat\"...",);
context,
0,
"Creating MVBOX-folder \"%s\"...",
b"DeltaChat\x00" as *const u8 as *const libc::c_char
);
if let Some(ref mut session) = self.session.lock().unwrap().0 { if let Some(ref mut session) = self.session.lock().unwrap().0 {
match session.create("DeltaChat") { match session.create("DeltaChat") {

View File

@@ -10,7 +10,6 @@ use pgp::types::{KeyTrait, SecretKeyTrait};
use crate::constants::*; use crate::constants::*;
use crate::context::Context; use crate::context::Context;
use crate::dc_log::*;
use crate::dc_sqlite3::*; use crate::dc_sqlite3::*;
use crate::dc_tools::*; use crate::dc_tools::*;
use crate::types::*; use crate::types::*;
@@ -281,7 +280,7 @@ impl Key {
strlen(file_content), strlen(file_content),
) )
} { } {
error!(context, 0, "Cannot write key to %s", file); error!(context, 0, "Cannot write key to {}", to_string(file));
false false
} else { } else {
true true

View File

@@ -5,7 +5,6 @@ use percent_encoding::{utf8_percent_encode, DEFAULT_ENCODE_SET};
use serde::Deserialize; use serde::Deserialize;
use crate::context::Context; use crate::context::Context;
use crate::dc_log::*;
use crate::dc_sqlite3::*; use crate::dc_sqlite3::*;
use crate::dc_tools::*; use crate::dc_tools::*;
use crate::types::*; use crate::types::*;
@@ -125,8 +124,7 @@ pub fn dc_get_oauth2_access_token(
if response.is_err() { if response.is_err() {
warn!( warn!(
context, context,
0, 0, "Error calling OAuth2 at {}: {:?}", token_url, response
format!("Error calling OAuth2 at {}: {:?}", token_url, response)
); );
return None; return None;
} }
@@ -135,11 +133,9 @@ pub fn dc_get_oauth2_access_token(
warn!( warn!(
context, context,
0, 0,
format!( "Error calling OAuth2 at {}: {:?}",
"Error calling OAuth2 at {}: {:?}", token_url,
token_url, response.status()
response.status()
)
); );
return None; return None;
} }
@@ -148,11 +144,7 @@ pub fn dc_get_oauth2_access_token(
if parsed.is_err() { if parsed.is_err() {
warn!( warn!(
context, context,
0, 0, "Failed to parse OAuth2 JSON response from {}: error: {:?}", token_url, parsed
format!(
"Failed to parse OAuth2 JSON response from {}: error: {:?}",
token_url, parsed
)
); );
return None; return None;
} }
@@ -251,11 +243,7 @@ impl Oauth2 {
// } // }
let response = reqwest::Client::new().get(&userinfo_url).send(); let response = reqwest::Client::new().get(&userinfo_url).send();
if response.is_err() { if response.is_err() {
warn!( warn!(context, 0, "Error getting userinfo: {:?}", response);
context,
0,
format!("Error getting userinfo: {:?}", response)
);
return None; return None;
} }
let mut response = response.unwrap(); let mut response = response.unwrap();
@@ -263,7 +251,8 @@ impl Oauth2 {
warn!( warn!(
context, context,
0, 0,
format!("Error getting userinfo: {:?}", response.status()) "Error getting userinfo: {:?}",
response.status()
); );
return None; return None;
} }
@@ -272,8 +261,7 @@ impl Oauth2 {
if parsed.is_err() { if parsed.is_err() {
warn!( warn!(
context, context,
0, 0, "Failed to parse userinfo JSON response: {:?}", parsed
format!("Failed to parse userinfo JSON response: {:?}", parsed)
); );
return None; return None;
} }

View File

@@ -1,4 +1,4 @@
use std::ffi::{CStr, CString}; use std::ffi::CStr;
use lettre::smtp::client::net::*; use lettre::smtp::client::net::*;
use lettre::*; use lettre::*;
@@ -10,7 +10,6 @@ use crate::dc_log::*;
use crate::dc_loginparam::*; use crate::dc_loginparam::*;
use crate::dc_tools::*; use crate::dc_tools::*;
use crate::oauth2::*; use crate::oauth2::*;
use crate::x::*;
pub struct Smtp { pub struct Smtp {
transport: Option<lettre::smtp::SmtpTransport>, transport: Option<lettre::smtp::SmtpTransport>,
@@ -141,11 +140,7 @@ impl Smtp {
1 1
} }
Err(err) => { Err(err) => {
warn!( warn!(context, 0, "SMTP: failed to establish connection {:?}", err);
context,
0,
format!("SMTP: failed to establish connection {:?}", err)
);
0 0
} }
} }
@@ -180,11 +175,7 @@ impl Smtp {
1 1
} }
Err(err) => { Err(err) => {
let error_msg = format!("SMTP failed to send message: {:?}", err); warn!(context, 0, "SMTP failed to send message: {}", err);
let msg = CString::new(error_msg).unwrap();
self.error = unsafe { strdup(msg.as_ptr()) };
warn!(context, 0, "%s", msg,);
0 0
} }

View File

@@ -43,13 +43,6 @@ extern "C" {
unsafe extern "C" fn(_: *const libc::c_void, _: *const libc::c_void) -> libc::c_int, unsafe extern "C" fn(_: *const libc::c_void, _: *const libc::c_void) -> libc::c_int,
>, >,
); );
pub fn pow(_: libc::c_double, _: libc::c_double) -> libc::c_double;
pub fn strftime(
_: *mut libc::c_char,
_: size_t,
_: *const libc::c_char,
_: *const libc::tm,
) -> size_t;
pub fn atol(_: *const libc::c_char) -> libc::c_long; pub fn atol(_: *const libc::c_char) -> libc::c_long;
pub fn vsnprintf( pub fn vsnprintf(
_: *mut libc::c_char, _: *mut libc::c_char,