@ -19,56 +19,13 @@ use std::path::Path;
use std ::process ::{ exit , Command } ;
use std ::thread ::sleep ;
use std ::time ::Duration ;
use std ::ffi ::{ CStr , CString } ;
use std ::fs ::{ self , File } ;
use std ::mem ;
use std ::io ::{ Write , BufReader , BufRead , Read , self } ;
use std ::net ::TcpStream ;
use simple_input ::input ;
use tempfile ::NamedTempFile ;
extern "C" {
#[ no_mangle ]
fn read ( __fd : libc ::c_int , __buf : * mut libc ::c_void , __nbytes : size_t ) -> ssize_t ;
#[ no_mangle ]
fn strlen ( _ : * const libc ::c_char ) -> libc ::c_ulong ;
}
pub type __ssize_t = libc ::c_long ;
pub type __socklen_t = libc ::c_uint ;
pub type ssize_t = __ssize_t ;
pub type size_t = libc ::c_ulong ;
pub type socklen_t = __socklen_t ;
pub type __socket_type = libc ::c_uint ;
pub const SOCK_NONBLOCK : __socket_type = 2048 ;
pub const SOCK_CLOEXEC : __socket_type = 524288 ;
pub const SOCK_PACKET : __socket_type = 10 ;
pub const SOCK_DCCP : __socket_type = 6 ;
pub const SOCK_SEQPACKET : __socket_type = 5 ;
pub const SOCK_RDM : __socket_type = 4 ;
pub const SOCK_RAW : __socket_type = 3 ;
pub const SOCK_DGRAM : __socket_type = 2 ;
pub const SOCK_STREAM : __socket_type = 1 ;
pub type sa_family_t = libc ::c_ushort ;
#[ derive(Copy, Clone) ]
#[ repr(C) ]
pub struct sockaddr {
pub sa_family : sa_family_t ,
pub sa_data : [ libc ::c_char ; 14 ] ,
}
#[ derive(Copy, Clone) ]
#[ repr(C) ]
pub struct addrinfo {
pub ai_flags : libc ::c_int ,
pub ai_family : libc ::c_int ,
pub ai_socktype : libc ::c_int ,
pub ai_protocol : libc ::c_int ,
pub ai_addrlen : socklen_t ,
pub ai_addr : * mut sockaddr ,
pub ai_canonname : * mut libc ::c_char ,
pub ai_next : * mut addrinfo ,
}
/* structs */
#[ derive(Clone, Debug) ]
pub struct Link {
@ -359,14 +316,14 @@ impl BrowserState {
}
for line in buffer . lines ( ) {
if ! is_valid_directory_entry ( line . chars ( ) . next ( ) . unwrap_or ( '\0' ) ) {
println! (
"error: not a directory: [{}] {}" ,
line . chars ( ) . next ( ) . unwrap_or ( '\0' ) ,
line . chars ( ) . skip ( 1 ) . collect :: < String > ( )
) ;
return ;
}
// if !is_valid_directory_entry(line.chars().next().unwrap_or('\0')) {
// println!(
// "error: not a directory: [{}] {}",
// line.chars().next().unwrap_or('\0'),
// line.chars().skip(1).collect::<String>()
// );
// return;
// }
self . handle_directory_line ( line ) ;
}
@ -671,7 +628,6 @@ impl BrowserState {
pub unsafe fn init ( & mut self , mut argc : usize , mut argv : Vec < String > ) -> libc ::c_int {
let mut i : usize = 0 ;
let mut line : [ u8 ; 1024 ] = [ 0 ; 1024 ] ;
let mut uri : String = String ::new ( ) ;
/* copy defaults */
self . init_config ( ) ;
@ -712,28 +668,19 @@ impl BrowserState {
) ; /* to display the prompt */
loop {
// todo color prompt
println !(
let line = input ( & format !(
"{}:{}{} " ,
self . current_host , self . current_port , & self . current_selector
) ;
if read_line (
0 as libc ::c_int ,
line . as_mut_ptr ( ) as * mut i8 ,
mem ::size_of ::< [ libc ::c_char ; 1024 ] > ( ) as libc ::c_ulong ,
) = = 0
{
println! ( "QUIT" ) ;
return 0 as libc ::c_int ;
}
i = strlen ( line . as_mut_ptr ( ) as * mut i8 ) as usize ;
match line [ 0 as libc ::c_int as usize ] as libc ::c_int {
63 = > {
) ) ;
match line . chars ( ) . next ( ) {
Some ( '?' ) = > {
println! ( "? - help\n* - reload directory\n< - go back in history\n.[LINK] - download the given link\nH - show history\nH[LINK] - jump to the specified history item\nG[URI] - jump to the given gopher URI\nB - show bookmarks\nB[LINK] - jump to the specified bookmark item\nC^d - quit" ) ;
}
60 = > {
Some ( '<' ) = > {
self . pop_history ( ) ;
}
42 = > {
Some ( '*' ) = > {
self . view_directory (
& self . current_host . clone ( ) ,
self . current_port ,
@ -741,29 +688,25 @@ impl BrowserState {
0 as libc ::c_int ,
) ;
}
46 = > {
Some ( '.' ) = > {
self . download_link (
make_key ( line [ 1 ] as char , line [ 2 ] as char , line [ 3 ] as char )
make_key (
line . chars ( ) . next ( ) . unwrap ( ) ,
line . chars ( ) . skip ( 1 ) . next ( ) . unwrap_or ( '\0' ) ,
line . chars ( ) . skip ( 2 ) . next ( ) . unwrap_or ( '\0' ) )
. unwrap_or ( 0 ) ,
) ;
}
72 = >
Some ( 'H' ) = >
if i = = 1 | | i = = 3 | | i = = 4 {
self . view_history ( make_key (
line [1 ] as char ,
line [2 ] as char ,
line [3 ] as char ,
line .chars ( ) . next ( ) . unwrap ( ) ,
line .chars ( ) . skip ( 1 ) . next ( ) . unwrap_or ( '\0' ) ,
line .chars ( ) . skip ( 2 ) . next ( ) . unwrap_or ( '\0' ) ,
) ) ;
} ,
71 = > {
if self . parse_uri (
& CString ::from_raw (
& mut * line . as_mut_ptr ( ) . offset ( 1 as libc ::c_int as isize )
as * mut u8 as * mut i8 ,
)
. into_string ( )
. unwrap ( ) ,
) {
Some ( 'G' ) = > {
if self . parse_uri ( & line [ 1 .. ] ) {
self . view_directory (
& self . parsed_host . clone ( ) ,
self . parsed_port . clone ( ) ,
@ -774,17 +717,20 @@ impl BrowserState {
println! ( "invalid gopher URI" ) ;
}
}
66 = >
Some ( 'B' ) = >
if i = = 1 | | i = = 3 | | i = = 4 {
self . view_bookmarks ( make_key (
line [1 ] as char ,
line [2 ] as char ,
line [3 ] as char ,
line .chars ( ) . next ( ) . unwrap ( ) ,
line .chars ( ) . skip ( 1 ) . next ( ) . unwrap_or ( '\0' ) ,
line .chars ( ) . skip ( 2 ) . next ( ) . unwrap_or ( '\0' ) ,
) ) ;
} ,
_ = > {
self . follow_link (
make_key ( line [ 0 ] as char , line [ 1 ] as char , line [ 2 ] as char )
make_key (
line . chars ( ) . next ( ) . unwrap ( ) ,
line . chars ( ) . skip ( 1 ) . next ( ) . unwrap_or ( '\0' ) ,
line . chars ( ) . skip ( 2 ) . next ( ) . unwrap_or ( '\0' ) )
. unwrap_or ( 0 ) ,
) ;
}
@ -821,44 +767,13 @@ pub unsafe fn dial(
} ;
if let Err ( e ) = writeln! ( stream , "{}" , selector ) {
eprintln! ( "failed to send request to server ") ;
eprintln! ( "failed to send request to server : {} ", e ) ;
return None ;
} ;
Some ( stream )
}
pub unsafe fn read_line (
mut fd : libc ::c_int ,
mut buf : * mut libc ::c_char ,
mut buf_len : size_t ,
) -> libc ::c_int {
let mut i : size_t = 0 as libc ::c_int as size_t ;
let mut c : libc ::c_char = 0 as libc ::c_int as libc ::c_char ;
loop {
if read (
fd ,
& mut c as * mut libc ::c_char as * mut libc ::c_void ,
mem ::size_of ::< libc ::c_char > ( ) as libc ::c_ulong ,
) as libc ::c_ulong
! = mem ::size_of ::< libc ::c_char > ( ) as libc ::c_ulong
{
return 0 as libc ::c_int ;
}
if c as libc ::c_int ! = '\r' as i32 {
let fresh3 = i ;
i = i . wrapping_add ( 1 ) ;
* buf . offset ( fresh3 as isize ) = c
}
if ! ( c as libc ::c_int ! = '\n' as i32 & & i < buf_len ) {
break ;
}
}
* buf . offset ( i . wrapping_sub ( 1 as libc ::c_int as libc ::c_ulong ) as isize ) =
'\u{0}' as i32 as libc ::c_char ;
return 1 as libc ::c_int ;
}
pub unsafe fn make_key ( mut c1 : char , mut c2 : char , mut c3 : char ) -> Option < usize > {
if c1 = = '\0' | | c2 = = '\0' {
return None ;