|
|
|
@ -22,7 +22,7 @@ use std::time::Duration;
|
|
|
|
|
use std::ffi::{CStr, CString};
|
|
|
|
|
use std::fs::{self, File};
|
|
|
|
|
use std::mem;
|
|
|
|
|
use std::io::{Write};
|
|
|
|
|
use std::io::{Write, BufReader, BufRead};
|
|
|
|
|
|
|
|
|
|
use simple_input::input;
|
|
|
|
|
use tempfile::NamedTempFile;
|
|
|
|
@ -249,7 +249,7 @@ pub struct BrowserState {
|
|
|
|
|
pub parsed_host: String,
|
|
|
|
|
pub parsed_port: usize,
|
|
|
|
|
pub parsed_selector: String,
|
|
|
|
|
pub bookmarks: [[u8; 512]; 20],
|
|
|
|
|
pub bookmarks: Vec<String>,
|
|
|
|
|
pub config: Config,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -266,7 +266,7 @@ impl BrowserState {
|
|
|
|
|
parsed_host: String::new(),
|
|
|
|
|
parsed_port: 0,
|
|
|
|
|
parsed_selector: String::new(),
|
|
|
|
|
bookmarks: [[0; 512]; 20],
|
|
|
|
|
bookmarks: Vec::new(),
|
|
|
|
|
config: Config {
|
|
|
|
|
start_uri: String::from("gopher://gopher.floodgap.com:70"),
|
|
|
|
|
cmd_text: String::from("less"),
|
|
|
|
@ -280,198 +280,45 @@ impl BrowserState {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsafe fn parse_config_line(&mut self, mut line: *const libc::c_char) {
|
|
|
|
|
let mut token: [libc::c_char; 1024] = [0; 1024];
|
|
|
|
|
let mut bkey: [libc::c_char; 128] = [0; 128];
|
|
|
|
|
let mut value: *mut libc::c_char = 0 as *mut libc::c_char;
|
|
|
|
|
let mut i: libc::c_int = 0;
|
|
|
|
|
let mut j: libc::c_int = 0;
|
|
|
|
|
while *line as libc::c_int == ' ' as i32 || *line as libc::c_int == '\t' as i32 {
|
|
|
|
|
line = line.offset(1)
|
|
|
|
|
}
|
|
|
|
|
i = 0 as libc::c_int;
|
|
|
|
|
while *line as libc::c_int != 0
|
|
|
|
|
&& *line as libc::c_int != ' ' as i32
|
|
|
|
|
&& *line as libc::c_int != '\t' as i32
|
|
|
|
|
{
|
|
|
|
|
if (i as libc::c_ulong)
|
|
|
|
|
< (mem::size_of::<[libc::c_char; 1024]>() as libc::c_ulong)
|
|
|
|
|
.wrapping_sub(1 as libc::c_int as libc::c_ulong)
|
|
|
|
|
{
|
|
|
|
|
let fresh0 = i;
|
|
|
|
|
i = i + 1;
|
|
|
|
|
token[fresh0 as usize] = *line
|
|
|
|
|
}
|
|
|
|
|
line = line.offset(1)
|
|
|
|
|
}
|
|
|
|
|
token[i as usize] = 0 as libc::c_int as libc::c_char;
|
|
|
|
|
if strcmp(
|
|
|
|
|
token.as_mut_ptr(),
|
|
|
|
|
b"start_uri\x00" as *const u8 as *const libc::c_char,
|
|
|
|
|
) == 0
|
|
|
|
|
{
|
|
|
|
|
value = CString::new(self.config.start_uri.clone()).unwrap().into_raw();
|
|
|
|
|
} else if strcmp(
|
|
|
|
|
token.as_mut_ptr(),
|
|
|
|
|
b"cmd_text\x00" as *const u8 as *const libc::c_char,
|
|
|
|
|
) == 0
|
|
|
|
|
{
|
|
|
|
|
value = CString::new(self.config.cmd_text.clone()).unwrap().into_raw();
|
|
|
|
|
} else if strcmp(
|
|
|
|
|
token.as_mut_ptr(),
|
|
|
|
|
b"cmd_browser\x00" as *const u8 as *const libc::c_char,
|
|
|
|
|
) == 0
|
|
|
|
|
{
|
|
|
|
|
value = CString::new(self.config.cmd_browser.clone()).unwrap().into_raw();
|
|
|
|
|
} else if strcmp(
|
|
|
|
|
token.as_mut_ptr(),
|
|
|
|
|
b"cmd_image\x00" as *const u8 as *const libc::c_char,
|
|
|
|
|
) == 0
|
|
|
|
|
{
|
|
|
|
|
value = CString::new(self.config.cmd_image.clone()).unwrap().into_raw();
|
|
|
|
|
} else if strcmp(
|
|
|
|
|
token.as_mut_ptr(),
|
|
|
|
|
b"cmd_player\x00" as *const u8 as *const libc::c_char,
|
|
|
|
|
) == 0
|
|
|
|
|
{
|
|
|
|
|
value = CString::new(self.config.cmd_player.clone()).unwrap().into_raw();
|
|
|
|
|
} else if strcmp(
|
|
|
|
|
token.as_mut_ptr(),
|
|
|
|
|
b"color_prompt\x00" as *const u8 as *const libc::c_char,
|
|
|
|
|
) == 0
|
|
|
|
|
{
|
|
|
|
|
value = CString::new(self.config.color_prompt.clone()).unwrap().into_raw();
|
|
|
|
|
} else if strcmp(
|
|
|
|
|
token.as_mut_ptr(),
|
|
|
|
|
b"color_selector\x00" as *const u8 as *const libc::c_char,
|
|
|
|
|
) == 0
|
|
|
|
|
{
|
|
|
|
|
value = CString::new(self.config.color_selector.clone()).unwrap().into_raw();
|
|
|
|
|
} else if strcmp(
|
|
|
|
|
token.as_mut_ptr(),
|
|
|
|
|
b"verbose\x00" as *const u8 as *const libc::c_char,
|
|
|
|
|
) == 0
|
|
|
|
|
{
|
|
|
|
|
value = CString::new(self.config.verbose.clone()).unwrap().into_raw();
|
|
|
|
|
} else {
|
|
|
|
|
j = 0 as libc::c_int;
|
|
|
|
|
while j < 20 as libc::c_int {
|
|
|
|
|
snprintf(
|
|
|
|
|
bkey.as_mut_ptr(),
|
|
|
|
|
mem::size_of::<[libc::c_char; 128]>() as libc::c_ulong,
|
|
|
|
|
b"bookmark%d\x00" as *const u8 as *const libc::c_char,
|
|
|
|
|
j + 1 as libc::c_int,
|
|
|
|
|
);
|
|
|
|
|
if strcmp(token.as_mut_ptr(), bkey.as_mut_ptr()) == 0 {
|
|
|
|
|
value = CString::new(self.bookmarks[j as usize]).unwrap().into_raw();
|
|
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
j += 1
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if value.is_null() {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
while *line as libc::c_int == ' ' as i32 || *line as libc::c_int == '\t' as i32 {
|
|
|
|
|
line = line.offset(1)
|
|
|
|
|
}
|
|
|
|
|
i = 0 as libc::c_int;
|
|
|
|
|
while *line != 0 {
|
|
|
|
|
if i < 512 as libc::c_int - 1 as libc::c_int {
|
|
|
|
|
let fresh1 = i;
|
|
|
|
|
i = i + 1;
|
|
|
|
|
*value.offset(fresh1 as isize) = *line
|
|
|
|
|
}
|
|
|
|
|
line = line.offset(1)
|
|
|
|
|
}
|
|
|
|
|
i -= 1;
|
|
|
|
|
while i > 0 as libc::c_int
|
|
|
|
|
&& (*value.offset(i as isize) as libc::c_int == ' ' as i32
|
|
|
|
|
|| *value.offset(i as isize) as libc::c_int == '\t' as i32)
|
|
|
|
|
{
|
|
|
|
|
i -= 1
|
|
|
|
|
unsafe fn parse_config_line(&mut self, line: &str) {
|
|
|
|
|
let trimmed_line = line.trim_start();
|
|
|
|
|
|
|
|
|
|
let words = trimmed_line.split_whitespace().take(2).collect::<Vec<_>>();
|
|
|
|
|
match words[0] {
|
|
|
|
|
"start_uri" => self.config.start_uri = words[1].to_string(),
|
|
|
|
|
"cmd_text" => self.config.cmd_text = words[1].to_string(),
|
|
|
|
|
"cmd_browser" => self.config.cmd_browser = words[1].to_string(),
|
|
|
|
|
"cmd_image" => self.config.cmd_image = words[1].to_string(),
|
|
|
|
|
"cmd_player" => self.config.cmd_player = words[1].to_string(),
|
|
|
|
|
"color_prompt" => self.config.color_prompt = words[1].to_string(),
|
|
|
|
|
"color_selector" => self.config.color_selector = words[1].to_string(),
|
|
|
|
|
"verbose" => self.config.verbose = words[1].to_string(),
|
|
|
|
|
x if x.starts_with("bookmark") => self.bookmarks.push(words[1].to_string()),
|
|
|
|
|
x => {
|
|
|
|
|
eprintln!("invalid key in config: {}", x);
|
|
|
|
|
exit(1)
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
i += 1;
|
|
|
|
|
*value.offset(i as isize) = 0 as libc::c_int as libc::c_char;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub unsafe fn load_config(&mut self, mut filename: *const libc::c_char) {
|
|
|
|
|
let mut fp: *mut FILE = 0 as *mut FILE;
|
|
|
|
|
let mut ch: libc::c_int = 0;
|
|
|
|
|
let mut i: libc::c_int = 0;
|
|
|
|
|
let mut line: [libc::c_char; 1024] = [0; 1024];
|
|
|
|
|
fp = fopen(filename, b"r\x00" as *const u8 as *const libc::c_char);
|
|
|
|
|
if fp.is_null() {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
memset(
|
|
|
|
|
line.as_mut_ptr() as *mut libc::c_void,
|
|
|
|
|
0 as libc::c_int,
|
|
|
|
|
mem::size_of::<[libc::c_char; 1024]>() as libc::c_ulong,
|
|
|
|
|
);
|
|
|
|
|
i = 0 as libc::c_int;
|
|
|
|
|
ch = fgetc(fp);
|
|
|
|
|
loop {
|
|
|
|
|
match ch {
|
|
|
|
|
35 =>
|
|
|
|
|
while ch != '\n' as i32 && ch != -(1 as libc::c_int) {
|
|
|
|
|
ch = fgetc(fp)
|
|
|
|
|
},
|
|
|
|
|
-1 => {
|
|
|
|
|
self.parse_config_line(line.as_mut_ptr());
|
|
|
|
|
fclose(fp);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
13 => ch = fgetc(fp),
|
|
|
|
|
10 => {
|
|
|
|
|
self.parse_config_line(line.as_mut_ptr());
|
|
|
|
|
memset(
|
|
|
|
|
line.as_mut_ptr() as *mut libc::c_void,
|
|
|
|
|
0 as libc::c_int,
|
|
|
|
|
mem::size_of::<[libc::c_char; 1024]>() as libc::c_ulong,
|
|
|
|
|
);
|
|
|
|
|
i = 0 as libc::c_int;
|
|
|
|
|
ch = fgetc(fp)
|
|
|
|
|
}
|
|
|
|
|
_ => {
|
|
|
|
|
if (i as libc::c_ulong)
|
|
|
|
|
< (mem::size_of::<[libc::c_char; 1024]>() as libc::c_ulong)
|
|
|
|
|
.wrapping_sub(1 as libc::c_int as libc::c_ulong)
|
|
|
|
|
{
|
|
|
|
|
let fresh2 = i;
|
|
|
|
|
i = i + 1;
|
|
|
|
|
line[fresh2 as usize] = ch as libc::c_char
|
|
|
|
|
}
|
|
|
|
|
ch = fgetc(fp)
|
|
|
|
|
}
|
|
|
|
|
pub unsafe fn load_config<P: AsRef<Path>>(&mut self, filename: P) {
|
|
|
|
|
let mut file = match File::open(filename) {
|
|
|
|
|
Ok(f) => BufReader::new(f),
|
|
|
|
|
Err(_) => {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
file.lines().filter_map(|x| x.ok()).filter(|x| !x.starts_with('#')).for_each(|line| {
|
|
|
|
|
self.parse_config_line(&line)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub unsafe fn init_config(&mut self) {
|
|
|
|
|
let mut filename: [libc::c_char; 1024] = [0; 1024];
|
|
|
|
|
let mut home: *const libc::c_char = 0 as *const libc::c_char;
|
|
|
|
|
let mut i: libc::c_int = 0;
|
|
|
|
|
/* copy defaults */
|
|
|
|
|
i = 0 as libc::c_int;
|
|
|
|
|
while i < 20 as libc::c_int {
|
|
|
|
|
self.bookmarks[i as usize][0 as libc::c_int as usize] = 0;
|
|
|
|
|
i += 1
|
|
|
|
|
}
|
|
|
|
|
/* read configs */
|
|
|
|
|
self.load_config(b"/etc/cgorc\x00" as *const u8 as *const libc::c_char); /* ignore incomplete selectors */
|
|
|
|
|
home = getenv(b"HOME\x00" as *const u8 as *const libc::c_char); /* not needed for history...just clear them */
|
|
|
|
|
if !home.is_null() {
|
|
|
|
|
snprintf(
|
|
|
|
|
filename.as_mut_ptr(),
|
|
|
|
|
mem::size_of::<[libc::c_char; 1024]>() as libc::c_ulong,
|
|
|
|
|
b"%s%s\x00" as *const u8 as *const libc::c_char,
|
|
|
|
|
home,
|
|
|
|
|
b"/.cgorc\x00" as *const u8 as *const libc::c_char,
|
|
|
|
|
);
|
|
|
|
|
self.load_config(filename.as_mut_ptr());
|
|
|
|
|
};
|
|
|
|
|
self.load_config("/etc/cgorc"); /* ignore incomplete selectors */
|
|
|
|
|
if let Some(dir) = env::home_dir() {
|
|
|
|
|
self.load_config(dir.join(".cgorc"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub unsafe fn download_file(
|
|
|
|
@ -958,44 +805,20 @@ impl BrowserState {
|
|
|
|
|
if key.is_none() {
|
|
|
|
|
println!("(bookmarks)");
|
|
|
|
|
i = 0;
|
|
|
|
|
while i < 20 {
|
|
|
|
|
if self.bookmarks[i as usize][0] != 0 {
|
|
|
|
|
make_key_str(i, &mut a, &mut b, &mut c);
|
|
|
|
|
println!(
|
|
|
|
|
"{}{}{} {}",
|
|
|
|
|
a,
|
|
|
|
|
b,
|
|
|
|
|
c,
|
|
|
|
|
CString::new(
|
|
|
|
|
self.bookmarks[i as usize]
|
|
|
|
|
.iter()
|
|
|
|
|
.take_while(|x| **x != 0)
|
|
|
|
|
.cloned()
|
|
|
|
|
.collect::<Vec<_>>()
|
|
|
|
|
)
|
|
|
|
|
.unwrap()
|
|
|
|
|
.into_string()
|
|
|
|
|
.unwrap()
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
i += 1
|
|
|
|
|
for bookmark in &self.bookmarks {
|
|
|
|
|
make_key_str(i, &mut a, &mut b, &mut c);
|
|
|
|
|
println!(
|
|
|
|
|
"{}{}{} {}",
|
|
|
|
|
a,
|
|
|
|
|
b,
|
|
|
|
|
c,
|
|
|
|
|
bookmark
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
} else if let Some(key) = key {
|
|
|
|
|
i = 0;
|
|
|
|
|
while i < 20 {
|
|
|
|
|
if self.bookmarks[i][0] != 0 && i == key {
|
|
|
|
|
if self.parse_uri(
|
|
|
|
|
CString::new(
|
|
|
|
|
self.bookmarks[i]
|
|
|
|
|
.iter()
|
|
|
|
|
.take_while(|x| **x != 0)
|
|
|
|
|
.cloned()
|
|
|
|
|
.collect::<Vec<_>>(),
|
|
|
|
|
)
|
|
|
|
|
.unwrap()
|
|
|
|
|
.into_string()
|
|
|
|
|
.unwrap(),
|
|
|
|
|
) {
|
|
|
|
|
for (i, bookmark) in self.bookmarks.clone().iter().enumerate() {
|
|
|
|
|
if i == key {
|
|
|
|
|
if self.parse_uri(bookmark) {
|
|
|
|
|
self.view_directory(
|
|
|
|
|
&self.parsed_host.clone(),
|
|
|
|
|
self.parsed_port.clone(),
|
|
|
|
@ -1005,21 +828,11 @@ impl BrowserState {
|
|
|
|
|
} else {
|
|
|
|
|
println!(
|
|
|
|
|
"invalid gopher URI: {}",
|
|
|
|
|
CString::new(
|
|
|
|
|
self.bookmarks[i]
|
|
|
|
|
.iter()
|
|
|
|
|
.take_while(|x| **x != 0)
|
|
|
|
|
.cloned()
|
|
|
|
|
.collect::<Vec<_>>()
|
|
|
|
|
)
|
|
|
|
|
.unwrap()
|
|
|
|
|
.into_string()
|
|
|
|
|
.unwrap()
|
|
|
|
|
bookmark,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
i += 1
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
@ -1133,7 +946,7 @@ impl BrowserState {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* function prototypes */
|
|
|
|
|
pub unsafe fn parse_uri(&mut self, mut uri: String) -> bool {
|
|
|
|
|
pub unsafe fn parse_uri(&mut self, uri: &str) -> bool {
|
|
|
|
|
let mut tmp: &str = &uri[..];
|
|
|
|
|
/* strip gopher:// */
|
|
|
|
|
if uri.starts_with("gopher://") {
|
|
|
|
@ -1205,7 +1018,7 @@ impl BrowserState {
|
|
|
|
|
i += 1
|
|
|
|
|
}
|
|
|
|
|
/* parse uri */
|
|
|
|
|
if !self.parse_uri(uri) {
|
|
|
|
|
if !self.parse_uri(&uri) {
|
|
|
|
|
banner(false);
|
|
|
|
|
eprintln!("invalid gopher URI: {}", argv[i],);
|
|
|
|
|
exit(1);
|
|
|
|
@ -1285,7 +1098,7 @@ impl BrowserState {
|
|
|
|
|
},
|
|
|
|
|
71 => {
|
|
|
|
|
if self.parse_uri(
|
|
|
|
|
CString::from_raw(
|
|
|
|
|
&CString::from_raw(
|
|
|
|
|
&mut *line.as_mut_ptr().offset(1 as libc::c_int as isize)
|
|
|
|
|
as *mut u8 as *mut i8,
|
|
|
|
|
)
|
|
|
|
|