diff --git a/src/main.rs b/src/main.rs index eb52a4e..f95a8ae 100644 --- a/src/main.rs +++ b/src/main.rs @@ -210,12 +210,12 @@ pub type _IO_lock_t = (); pub type FILE = _IO_FILE; /* structs */ -#[derive(Copy, Clone)] +#[derive(Clone)] pub struct Link { - pub next: *mut Link, - pub which: libc::c_char, + pub next: Option>, + pub which: Option, pub key: libc::c_short, - pub host: *mut libc::c_char, + pub host: String, pub port: *mut libc::c_char, pub selector: *mut libc::c_char, } @@ -232,8 +232,8 @@ pub struct Config { } pub static mut tmpfilename: [libc::c_char; 256] = [0; 256]; -pub static mut links: *mut Link = 0 as *const Link as *mut Link; -pub static mut history: *mut Link = 0 as *const Link as *mut Link; +pub static mut links: Option> = None; +pub static mut history: Option> = None; pub static mut link_key: libc::c_int = 0; pub static mut current_host: [libc::c_char; 512] = [0; 512]; pub static mut current_port: [libc::c_char; 64] = [0; 64]; @@ -472,7 +472,7 @@ pub unsafe extern "C" fn init_config() { }; } pub unsafe extern "C" fn dial( - mut host: *const libc::c_char, + mut host: &str, mut port: *const libc::c_char, mut selector: *const libc::c_char, ) -> libc::c_int { @@ -706,35 +706,31 @@ pub unsafe extern "C" fn make_key_str( as libc::c_char }; } -pub unsafe extern "C" fn add_link( +pub unsafe fn add_link( mut which: libc::c_char, mut name: *const libc::c_char, - mut host: *const libc::c_char, + mut host: String, mut port: *const libc::c_char, mut selector: *const libc::c_char, ) { - let mut link: *mut Link = 0 as *mut Link; let mut a: libc::c_char = 0 as libc::c_int as libc::c_char; let mut b: libc::c_char = 0 as libc::c_int as libc::c_char; let mut c: libc::c_char = 0 as libc::c_int as libc::c_char; - if host.is_null() || port.is_null() || selector.is_null() { + if host.is_empty() || port.is_null() || selector.is_null() { return; } - link = calloc( - 1 as libc::c_int as libc::c_ulong, - mem::size_of::() as libc::c_ulong, - ) as *mut Link; - (*link).which = which; - (*link).key = link_key as libc::c_short; - (*link).host = strdup(host); - (*link).port = strdup(port); - (*link).selector = strdup(selector); - if links.is_null() { - (*link).next = 0 as *mut Link - } else { - (*link).next = links - } - links = link; + let mut link = Link { + which: Some(which as u8 as char), + key: link_key as libc::c_short, + host: host, + port: strdup(port), + selector: strdup(selector), + next: if links.is_none() { + None + } else { links.clone() } + }; + + links = Some(Box::new(link)); let fresh4 = link_key; link_key = link_key + 1; make_key_str(fresh4, &mut a, &mut b, &mut c); @@ -749,37 +745,23 @@ pub unsafe extern "C" fn add_link( ); } pub unsafe extern "C" fn clear_links() { - let mut link: *mut Link = 0 as *mut Link; - let mut next: *mut Link = 0 as *mut Link; - link = links; - while !link.is_null() { - next = (*link).next; - free((*link).host as *mut libc::c_void); - free((*link).port as *mut libc::c_void); - free((*link).selector as *mut libc::c_void); - free(link as *mut libc::c_void); - link = next - } - links = 0 as *mut Link; + links = None; link_key = 0 as libc::c_int; } pub unsafe extern "C" fn add_history() { - let mut link: *mut Link = 0 as *mut Link; - link = calloc( - 1 as libc::c_int as libc::c_ulong, - mem::size_of::() as libc::c_ulong, - ) as *mut Link; - (*link).host = strdup(current_host.as_mut_ptr()); - (*link).port = strdup(current_port.as_mut_ptr()); - (*link).selector = strdup(current_selector.as_mut_ptr()); - (*link).which = 0 as libc::c_int as libc::c_char; - (*link).key = 0 as libc::c_int as libc::c_short; - if history.is_null() { - (*link).next = 0 as *mut Link - } else { - (*link).next = history - } - history = link; + let mut link: Link = Link { + which: None, + key: 0 as libc::c_int as libc::c_short, + host: CString::new(current_host.iter().take_while(|x| **x != 0).map(|x| *x as u8).collect::>()).unwrap().into_string().unwrap(), + port: strdup(current_port.as_mut_ptr()), + selector: strdup(current_selector.as_mut_ptr()), + next: if history.is_none() { + None + } else { + history.clone() + } + }; + history = Some(Box::new(link)); } pub unsafe extern "C" fn handle_directory_line(mut line: *mut libc::c_char) { let mut i: libc::c_int = 0; @@ -822,10 +804,10 @@ pub unsafe extern "C" fn handle_directory_line(mut line: *mut libc::c_char) { 48 | 49 | 53 | 55 | 56 | 57 | 103 | 73 | 112 | 104 | 115 => { add_link( *line.offset(0 as libc::c_int as isize), - fields[0 as libc::c_int as usize], - fields[2 as libc::c_int as usize], - fields[3 as libc::c_int as usize], - fields[1 as libc::c_int as usize], + fields[0], + CString::from_raw(fields[2]).into_string().unwrap(), + fields[3], + fields[1], ); } _ => { @@ -849,7 +831,7 @@ pub unsafe extern "C" fn is_valid_directory_entry( }; } pub unsafe extern "C" fn view_directory( - mut host: *const libc::c_char, + mut host: String, mut port: *const libc::c_char, mut selector: *const libc::c_char, mut make_current: libc::c_int, @@ -936,7 +918,7 @@ pub unsafe extern "C" fn view_directory( } pub unsafe extern "C" fn view_file( mut cmd: *const libc::c_char, - mut host: *const libc::c_char, + mut host: &str, mut port: *const libc::c_char, mut selector: *const libc::c_char, ) { @@ -1019,7 +1001,7 @@ pub unsafe extern "C" fn view_file( unlink(tmpfilename.as_mut_ptr()); } pub unsafe extern "C" fn view_telnet( - mut host: *const libc::c_char, + mut host: &str, mut port: *const libc::c_char, ) { let mut pid: pid_t = 0; @@ -1049,7 +1031,7 @@ pub unsafe extern "C" fn view_telnet( puts(b"(done)\x00" as *const u8 as *const libc::c_char); } pub unsafe extern "C" fn view_download( - mut host: *const libc::c_char, + mut host: &str, mut port: *const libc::c_char, mut selector: *const libc::c_char, ) { @@ -1102,7 +1084,7 @@ pub unsafe extern "C" fn view_download( }; } pub unsafe extern "C" fn view_search( - mut host: *const libc::c_char, + mut host: &str, mut port: *const libc::c_char, mut selector: *const libc::c_char, ) { @@ -1132,15 +1114,15 @@ pub unsafe extern "C" fn view_history(mut key: libc::c_int) { let mut a: libc::c_char = 0; let mut b: libc::c_char = 0; let mut c: libc::c_char = 0; - let mut link: *mut Link = 0 as *mut Link; - if history.is_null() { - puts(b"(empty history)\x00" as *const u8 as *const libc::c_char); + let mut link: Option> = None; + if history.is_none() { + println!("(empty history)"); return; } if key < 0 as libc::c_int { puts(b"(history)\x00" as *const u8 as *const libc::c_char); - link = history; - while !link.is_null() { + link = history.clone(); + while let Some(l) = link { let fresh10 = history_key; history_key = history_key + 1; make_key_str(fresh10, &mut a, &mut b, &mut c); @@ -1151,29 +1133,29 @@ pub unsafe extern "C" fn view_history(mut key: libc::c_int) { a as libc::c_int, b as libc::c_int, c as libc::c_int, - (*link).host, - (*link).port, - (*link).selector, + (*l).host, + (*l).port, + (*l).selector, ); - link = (*link).next + link = (*l).next } } else { /* traverse history list */ - link = history; - while !link.is_null() { + link = history.clone(); + while let Some(l) = link { if history_key == key { view_directory( - (*link).host, - (*link).port, - (*link).selector, + (*l).host, + (*l).port, + (*l).selector, 0 as libc::c_int, ); return; } - link = (*link).next; + link = (*l).next; history_key += 1 } - puts(b"history item not found\x00" as *const u8 as *const libc::c_char); + println!("history item not found"); }; } pub unsafe extern "C" fn view_bookmarks(mut key: libc::c_int) { @@ -1214,7 +1196,7 @@ pub unsafe extern "C" fn view_bookmarks(mut key: libc::c_int) { ) != 0 { view_directory( - parsed_host.as_mut_ptr(), + CString::from_raw(parsed_host).into_string().unwrap(), parsed_port.as_mut_ptr(), parsed_selector.as_mut_ptr(), 0 as libc::c_int, @@ -1233,96 +1215,91 @@ pub unsafe extern "C" fn view_bookmarks(mut key: libc::c_int) { } }; } -pub unsafe extern "C" fn pop_history() { - let mut next: *mut Link = 0 as *mut Link; - if history.is_null() { - puts(b"(empty history)\x00" as *const u8 as *const libc::c_char); - return; +pub fn pop_history() { + match unsafe { &history } { + None => println!("(empty history)"), + Some(h) => { + /* reload page from history (and don't count as history) */ + unsafe { view_directory( + (*h).host, + (*h).port, + (*h).selector, + 0 as libc::c_int, + ); } + /* history is history... :) */ + unsafe { history = h.next.clone(); } + }, } - /* reload page from history (and don't count as history) */ - view_directory( - (*history).host, - (*history).port, - (*history).selector, - 0 as libc::c_int, - ); - /* history is history... :) */ - next = (*history).next; - free((*history).host as *mut libc::c_void); - free((*history).port as *mut libc::c_void); - free((*history).selector as *mut libc::c_void); - free(history as *mut libc::c_void); - history = next; } pub unsafe extern "C" fn follow_link(mut key: libc::c_int) -> libc::c_int { - let mut link: *mut Link = 0 as *mut Link; - link = links; - while !link.is_null() { - if (*link).key as libc::c_int != key { - link = (*link).next - } else { - match (*link).which as libc::c_int { - 48 => { + let mut link: Option> = links.clone(); + + while let Some(ref l) = link { + if (*l).key as libc::c_int != key { + link = (*l).next.clone() + } else if let Some(w) = (*l).which { + match w { + '0' => { view_file( CString::new(config.cmd_text.clone()) .unwrap() .into_raw(), - (*link).host, - (*link).port, - (*link).selector, + (*l).host, + (*l).port, + (*l).selector, ); } - 49 => { + '1' => { view_directory( - (*link).host, - (*link).port, - (*link).selector, + (*l).host, + (*l).port, + (*l).selector, 1 as libc::c_int, ); } - 55 => { - view_search((*link).host, (*link).port, (*link).selector); + '7' => { + view_search((*l).host, (*l).port, (*l).selector); } - 53 | 57 => { - view_download((*link).host, (*link).port, (*link).selector); + '5' | '9' => { + view_download((*l).host, (*l).port, (*l).selector); } - 56 => { - view_telnet((*link).host, (*link).port); + '8' => { + view_telnet((*l).host, (*l).port); } - 103 | 73 | 112 => { + 'f' | 'I' | 'p' => { view_file( CString::new(config.cmd_image.clone()) .unwrap() .into_raw(), - (*link).host, - (*link).port, - (*link).selector, + (*l).host, + (*l).port, + (*l).selector, ); } - 104 => { + 'h' => { view_file( CString::new(config.cmd_browser.clone()) .unwrap() .into_raw(), - (*link).host, - (*link).port, - (*link).selector, + (*l).host, + (*l).port, + (*l).selector, ); } - 115 => { + 's' => { view_file( CString::new(config.cmd_player.clone()) .unwrap() .into_raw(), - (*link).host, - (*link).port, - (*link).selector, + (*l).host, + (*l).port, + (*l).selector, ); } _ => { printf( b"missing handler [%c]\n\x00" as *const u8 as *const libc::c_char, - (*link).which as libc::c_int, + w as u8 as libc::c_int, ); } } @@ -1333,17 +1310,16 @@ pub unsafe extern "C" fn follow_link(mut key: libc::c_int) -> libc::c_int { return 0 as libc::c_int; } pub unsafe extern "C" fn download_link(mut key: libc::c_int) { - let mut link: *mut Link = 0 as *mut Link; - link = links; - while !link.is_null() { - if (*link).key as libc::c_int != key { - link = (*link).next + let mut link: Option> = links.clone(); + while let Some(l) = link { + if (*l).key as libc::c_int != key { + link = (*l).next } else { - view_download((*link).host, (*link).port, (*link).selector); + view_download((*l).host, (*l).port, (*l).selector); return; } } - puts(b"link not found\x00" as *const u8 as *const libc::c_char); + println!("link not found"); } /* function prototypes */ pub unsafe extern "C" fn parse_uri(mut uri: *const libc::c_char) -> libc::c_int {