|
|
@ -1,5 +1,3 @@
|
|
|
|
#![feature(main)]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern crate tempfile;
|
|
|
|
extern crate tempfile;
|
|
|
|
extern crate simple_input;
|
|
|
|
extern crate simple_input;
|
|
|
|
|
|
|
|
|
|
|
@ -80,7 +78,7 @@ impl BrowserState {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsafe fn parse_config_line(&mut self, line: &str) {
|
|
|
|
fn parse_config_line(&mut self, line: &str) {
|
|
|
|
let trimmed_line = line.trim_start();
|
|
|
|
let trimmed_line = line.trim_start();
|
|
|
|
|
|
|
|
|
|
|
|
let words = trimmed_line.split_whitespace().take(2).collect::<Vec<_>>();
|
|
|
|
let words = trimmed_line.split_whitespace().take(2).collect::<Vec<_>>();
|
|
|
@ -101,7 +99,7 @@ impl BrowserState {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub unsafe fn load_config<P: AsRef<Path>>(&mut self, filename: P) {
|
|
|
|
pub fn load_config<P: AsRef<Path>>(&mut self, filename: P) {
|
|
|
|
let file = match File::open(filename) {
|
|
|
|
let file = match File::open(filename) {
|
|
|
|
Ok(f) => BufReader::new(f),
|
|
|
|
Ok(f) => BufReader::new(f),
|
|
|
|
Err(_) => {
|
|
|
|
Err(_) => {
|
|
|
@ -114,7 +112,7 @@ impl BrowserState {
|
|
|
|
.for_each(|line| self.parse_config_line(&line))
|
|
|
|
.for_each(|line| self.parse_config_line(&line))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub unsafe fn init_config(&mut self) {
|
|
|
|
pub fn init_config(&mut self) {
|
|
|
|
/* read configs */
|
|
|
|
/* read configs */
|
|
|
|
self.load_config("/etc/cgorc"); /* ignore incomplete selectors */
|
|
|
|
self.load_config("/etc/cgorc"); /* ignore incomplete selectors */
|
|
|
|
if let Some(dir) = env::home_dir() {
|
|
|
|
if let Some(dir) = env::home_dir() {
|
|
|
@ -122,7 +120,7 @@ impl BrowserState {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub unsafe fn download_file(
|
|
|
|
pub fn download_file(
|
|
|
|
&mut self,
|
|
|
|
&mut self,
|
|
|
|
host: &str,
|
|
|
|
host: &str,
|
|
|
|
port: u16,
|
|
|
|
port: u16,
|
|
|
@ -152,7 +150,7 @@ impl BrowserState {
|
|
|
|
true
|
|
|
|
true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub unsafe fn download_temp(
|
|
|
|
pub fn download_temp(
|
|
|
|
&mut self,
|
|
|
|
&mut self,
|
|
|
|
host: &str,
|
|
|
|
host: &str,
|
|
|
|
port: u16,
|
|
|
|
port: u16,
|
|
|
@ -173,7 +171,7 @@ impl BrowserState {
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub unsafe fn add_link(
|
|
|
|
pub fn add_link(
|
|
|
|
&mut self,
|
|
|
|
&mut self,
|
|
|
|
which: char,
|
|
|
|
which: char,
|
|
|
|
name: String,
|
|
|
|
name: String,
|
|
|
@ -203,12 +201,12 @@ impl BrowserState {
|
|
|
|
println!("{}{}{} {}", a, b, c, name);
|
|
|
|
println!("{}{}{} {}", a, b, c, name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub unsafe fn clear_links(&mut self) {
|
|
|
|
pub fn clear_links(&mut self) {
|
|
|
|
self.links = None;
|
|
|
|
self.links = None;
|
|
|
|
self.link_key = 0;
|
|
|
|
self.link_key = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub unsafe fn add_history(&mut self) {
|
|
|
|
pub fn add_history(&mut self) {
|
|
|
|
let link: Link = Link {
|
|
|
|
let link: Link = Link {
|
|
|
|
which: None,
|
|
|
|
which: None,
|
|
|
|
key: 0,
|
|
|
|
key: 0,
|
|
|
@ -220,7 +218,7 @@ impl BrowserState {
|
|
|
|
self.history = Some(Box::new(link));
|
|
|
|
self.history = Some(Box::new(link));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub unsafe fn handle_directory_line(&mut self, line: &str) {
|
|
|
|
pub fn handle_directory_line(&mut self, line: &str) {
|
|
|
|
let fields = {
|
|
|
|
let fields = {
|
|
|
|
let mut v = line[1..].split('\t').collect::<Vec<_>>();
|
|
|
|
let mut v = line[1..].split('\t').collect::<Vec<_>>();
|
|
|
|
v.retain(|x| !x.is_empty());
|
|
|
|
v.retain(|x| !x.is_empty());
|
|
|
@ -270,7 +268,7 @@ impl BrowserState {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub unsafe fn view_directory(
|
|
|
|
pub fn view_directory(
|
|
|
|
&mut self,
|
|
|
|
&mut self,
|
|
|
|
host: &str,
|
|
|
|
host: &str,
|
|
|
|
port: u16,
|
|
|
|
port: u16,
|
|
|
@ -318,7 +316,7 @@ impl BrowserState {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub unsafe fn view_file(
|
|
|
|
pub fn view_file(
|
|
|
|
&mut self,
|
|
|
|
&mut self,
|
|
|
|
cmd: &str,
|
|
|
|
cmd: &str,
|
|
|
|
host: &str,
|
|
|
|
host: &str,
|
|
|
@ -349,7 +347,7 @@ impl BrowserState {
|
|
|
|
fs::remove_file(&self.tmpfilename).expect("failed to delete temp file");
|
|
|
|
fs::remove_file(&self.tmpfilename).expect("failed to delete temp file");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub unsafe fn view_download(
|
|
|
|
pub fn view_download(
|
|
|
|
&mut self,
|
|
|
|
&mut self,
|
|
|
|
host: &str,
|
|
|
|
host: &str,
|
|
|
|
port: u16,
|
|
|
|
port: u16,
|
|
|
@ -384,7 +382,7 @@ impl BrowserState {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub unsafe fn view_search(
|
|
|
|
pub fn view_search(
|
|
|
|
&mut self,
|
|
|
|
&mut self,
|
|
|
|
host: &str,
|
|
|
|
host: &str,
|
|
|
|
port: u16,
|
|
|
|
port: u16,
|
|
|
@ -400,7 +398,7 @@ impl BrowserState {
|
|
|
|
self.view_directory(host, port, &search_selector, true);
|
|
|
|
self.view_directory(host, port, &search_selector, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub unsafe fn view_history(&mut self, key: Option<usize>) {
|
|
|
|
pub fn view_history(&mut self, key: Option<usize>) {
|
|
|
|
let mut history_key: usize = 0;
|
|
|
|
let mut history_key: usize = 0;
|
|
|
|
let mut a: char = '\0';
|
|
|
|
let mut a: char = '\0';
|
|
|
|
let mut b: char = '\0';
|
|
|
|
let mut b: char = '\0';
|
|
|
@ -440,7 +438,7 @@ impl BrowserState {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub unsafe fn view_bookmarks(&mut self, key: Option<usize>) {
|
|
|
|
pub fn view_bookmarks(&mut self, key: Option<usize>) {
|
|
|
|
let mut a: char = '\0';
|
|
|
|
let mut a: char = '\0';
|
|
|
|
let mut b: char = '\0';
|
|
|
|
let mut b: char = '\0';
|
|
|
|
let mut c: char = '\0';
|
|
|
|
let mut c: char = '\0';
|
|
|
@ -474,21 +472,19 @@ impl BrowserState {
|
|
|
|
None => println!("(empty history)"),
|
|
|
|
None => println!("(empty history)"),
|
|
|
|
Some(h) => {
|
|
|
|
Some(h) => {
|
|
|
|
/* reload page from history (and don't count as history) */
|
|
|
|
/* reload page from history (and don't count as history) */
|
|
|
|
unsafe {
|
|
|
|
|
|
|
|
self.view_directory(
|
|
|
|
self.view_directory(
|
|
|
|
&(*h).host,
|
|
|
|
&(*h).host,
|
|
|
|
(*h).port,
|
|
|
|
(*h).port,
|
|
|
|
&(*h).selector,
|
|
|
|
&(*h).selector,
|
|
|
|
false,
|
|
|
|
false,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* history is history... :) */
|
|
|
|
/* history is history... :) */
|
|
|
|
self.history = h.next.clone();
|
|
|
|
self.history = h.next.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub unsafe fn follow_link(&mut self, key: usize) -> bool {
|
|
|
|
pub fn follow_link(&mut self, key: usize) -> bool {
|
|
|
|
let mut link: Option<Box<Link>> = self.links.clone();
|
|
|
|
let mut link: Option<Box<Link>> = self.links.clone();
|
|
|
|
|
|
|
|
|
|
|
|
while let Some(ref l) = link {
|
|
|
|
while let Some(ref l) = link {
|
|
|
@ -556,7 +552,7 @@ impl BrowserState {
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub unsafe fn download_link(&mut self, key: usize) {
|
|
|
|
pub fn download_link(&mut self, key: usize) {
|
|
|
|
let mut link: Option<Box<Link>> = self.links.clone();
|
|
|
|
let mut link: Option<Box<Link>> = self.links.clone();
|
|
|
|
while let Some(l) = link {
|
|
|
|
while let Some(l) = link {
|
|
|
|
if (*l).key != key {
|
|
|
|
if (*l).key != key {
|
|
|
@ -570,7 +566,7 @@ impl BrowserState {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* function prototypes */
|
|
|
|
/* function prototypes */
|
|
|
|
pub unsafe fn parse_uri(&mut self, uri: &str) -> bool {
|
|
|
|
pub fn parse_uri(&mut self, uri: &str) -> bool {
|
|
|
|
let mut tmp: &str = &uri[..];
|
|
|
|
let mut tmp: &str = &uri[..];
|
|
|
|
/* strip gopher:// */
|
|
|
|
/* strip gopher:// */
|
|
|
|
if uri.starts_with("gopher://") {
|
|
|
|
if uri.starts_with("gopher://") {
|
|
|
@ -613,7 +609,7 @@ impl BrowserState {
|
|
|
|
true
|
|
|
|
true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub unsafe fn init(&mut self, argc: usize, argv: Vec<String>) -> i32 {
|
|
|
|
pub fn init(&mut self, argc: usize, argv: Vec<String>) -> i32 {
|
|
|
|
let mut i: usize = 1;
|
|
|
|
let mut i: usize = 1;
|
|
|
|
/* copy defaults */
|
|
|
|
/* copy defaults */
|
|
|
|
self.init_config();
|
|
|
|
self.init_config();
|
|
|
@ -738,7 +734,7 @@ pub fn banner(to_error: bool) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub unsafe fn dial(
|
|
|
|
pub fn dial(
|
|
|
|
host: &str,
|
|
|
|
host: &str,
|
|
|
|
port: u16,
|
|
|
|
port: u16,
|
|
|
|
selector: &str,
|
|
|
|
selector: &str,
|
|
|
@ -759,7 +755,7 @@ pub unsafe fn dial(
|
|
|
|
Some(stream)
|
|
|
|
Some(stream)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub unsafe fn make_key(c1: char, c2: char, c3: char) -> Option<usize> {
|
|
|
|
pub fn make_key(c1: char, c2: char, c3: char) -> Option<usize> {
|
|
|
|
if c1 == '\0' || c2 == '\0' {
|
|
|
|
if c1 == '\0' || c2 == '\0' {
|
|
|
|
return None;
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -778,7 +774,7 @@ pub unsafe fn make_key(c1: char, c2: char, c3: char) -> Option<usize> {
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pub unsafe fn make_key_str(
|
|
|
|
pub fn make_key_str(
|
|
|
|
key: usize,
|
|
|
|
key: usize,
|
|
|
|
c1: &mut char,
|
|
|
|
c1: &mut char,
|
|
|
|
c2: &mut char,
|
|
|
|
c2: &mut char,
|
|
|
@ -807,7 +803,7 @@ pub unsafe fn make_key_str(
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub unsafe fn is_valid_directory_entry(kind: char) -> bool {
|
|
|
|
pub fn is_valid_directory_entry(kind: char) -> bool {
|
|
|
|
match kind {
|
|
|
|
match kind {
|
|
|
|
'i' | '3' | '.' | '0' | '1' | '5' | '7' | '8' | '9' | 'g' | 'I' | 'p' | 'h'
|
|
|
|
'i' | '3' | '.' | '0' | '1' | '5' | '7' | '8' | '9' | 'g' | 'I' | 'p' | 'h'
|
|
|
|
| 's' => true,
|
|
|
|
| 's' => true,
|
|
|
@ -815,7 +811,7 @@ pub unsafe fn is_valid_directory_entry(kind: char) -> bool {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub unsafe fn view_telnet(host: &str, port: u16) {
|
|
|
|
pub fn view_telnet(host: &str, port: u16) {
|
|
|
|
println!("executing: telnet {} {}", host, port);
|
|
|
|
println!("executing: telnet {} {}", host, port);
|
|
|
|
|
|
|
|
|
|
|
|
// TODO check stdio
|
|
|
|
// TODO check stdio
|
|
|
@ -829,9 +825,8 @@ pub unsafe fn view_telnet(host: &str, port: u16) {
|
|
|
|
println!("(done)");
|
|
|
|
println!("(done)");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[main]
|
|
|
|
fn main() {
|
|
|
|
pub fn main() {
|
|
|
|
|
|
|
|
let mut state = BrowserState::new();
|
|
|
|
let mut state = BrowserState::new();
|
|
|
|
let args: Vec<String> = env::args().collect();
|
|
|
|
let args: Vec<String> = env::args().collect();
|
|
|
|
unsafe { exit(state.init(args.len() - 1, args) as i32) }
|
|
|
|
exit(state.init(args.len() - 1, args) as i32)
|
|
|
|
}
|
|
|
|
}
|
|
|
|