You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1418 lines
59 KiB
Rust
1418 lines
59 KiB
Rust
#![allow(dead_code, mutable_transmutes, non_camel_case_types, non_snake_case,
|
|
non_upper_case_globals, unused_assignments, unused_mut)]
|
|
#![register_tool(c2rust)]
|
|
#![feature(const_raw_ptr_to_usize_cast, extern_types, main, register_tool)]
|
|
extern "C" {
|
|
pub type _IO_wide_data;
|
|
pub type _IO_codecvt;
|
|
pub type _IO_marker;
|
|
#[no_mangle]
|
|
fn waitpid(__pid: __pid_t, __stat_loc: *mut libc::c_int,
|
|
__options: libc::c_int) -> __pid_t;
|
|
#[no_mangle]
|
|
fn socket(__domain: libc::c_int, __type: libc::c_int,
|
|
__protocol: libc::c_int) -> libc::c_int;
|
|
#[no_mangle]
|
|
fn connect(__fd: libc::c_int, __addr: *const sockaddr, __len: socklen_t)
|
|
-> libc::c_int;
|
|
#[no_mangle]
|
|
fn getaddrinfo(__name: *const libc::c_char,
|
|
__service: *const libc::c_char, __req: *const addrinfo,
|
|
__pai: *mut *mut addrinfo) -> libc::c_int;
|
|
#[no_mangle]
|
|
fn freeaddrinfo(__ai: *mut addrinfo);
|
|
#[no_mangle]
|
|
fn open(__file: *const libc::c_char, __oflag: libc::c_int, _: ...)
|
|
-> libc::c_int;
|
|
#[no_mangle]
|
|
fn close(__fd: libc::c_int) -> libc::c_int;
|
|
#[no_mangle]
|
|
fn read(__fd: libc::c_int, __buf: *mut libc::c_void, __nbytes: size_t)
|
|
-> ssize_t;
|
|
#[no_mangle]
|
|
fn write(__fd: libc::c_int, __buf: *const libc::c_void, __n: size_t)
|
|
-> ssize_t;
|
|
#[no_mangle]
|
|
fn sleep(__seconds: libc::c_uint) -> libc::c_uint;
|
|
#[no_mangle]
|
|
fn execvp(__file: *const libc::c_char, __argv: *const *mut libc::c_char)
|
|
-> libc::c_int;
|
|
#[no_mangle]
|
|
fn execlp(__file: *const libc::c_char, __arg: *const libc::c_char, _: ...)
|
|
-> libc::c_int;
|
|
#[no_mangle]
|
|
fn fork() -> __pid_t;
|
|
#[no_mangle]
|
|
fn unlink(__name: *const libc::c_char) -> libc::c_int;
|
|
#[no_mangle]
|
|
fn __errno_location() -> *mut libc::c_int;
|
|
#[no_mangle]
|
|
static mut stdout: *mut FILE;
|
|
#[no_mangle]
|
|
static mut stderr: *mut FILE;
|
|
#[no_mangle]
|
|
fn fclose(__stream: *mut FILE) -> libc::c_int;
|
|
#[no_mangle]
|
|
fn fflush(__stream: *mut FILE) -> libc::c_int;
|
|
#[no_mangle]
|
|
fn fopen(_: *const libc::c_char, _: *const libc::c_char) -> *mut FILE;
|
|
#[no_mangle]
|
|
fn fprintf(_: *mut FILE, _: *const libc::c_char, _: ...) -> libc::c_int;
|
|
#[no_mangle]
|
|
fn printf(_: *const libc::c_char, _: ...) -> libc::c_int;
|
|
#[no_mangle]
|
|
fn snprintf(_: *mut libc::c_char, _: libc::c_ulong,
|
|
_: *const libc::c_char, _: ...) -> libc::c_int;
|
|
#[no_mangle]
|
|
fn fgetc(__stream: *mut FILE) -> libc::c_int;
|
|
#[no_mangle]
|
|
fn fputs(__s: *const libc::c_char, __stream: *mut FILE) -> libc::c_int;
|
|
#[no_mangle]
|
|
fn puts(__s: *const libc::c_char) -> libc::c_int;
|
|
#[no_mangle]
|
|
fn calloc(_: libc::c_ulong, _: libc::c_ulong) -> *mut libc::c_void;
|
|
#[no_mangle]
|
|
fn free(__ptr: *mut libc::c_void);
|
|
#[no_mangle]
|
|
fn exit(_: libc::c_int) -> !;
|
|
#[no_mangle]
|
|
fn getenv(__name: *const libc::c_char) -> *mut libc::c_char;
|
|
#[no_mangle]
|
|
fn mkstemp(__template: *mut libc::c_char) -> libc::c_int;
|
|
#[no_mangle]
|
|
fn memset(_: *mut libc::c_void, _: libc::c_int, _: libc::c_ulong)
|
|
-> *mut libc::c_void;
|
|
#[no_mangle]
|
|
fn strcpy(_: *mut libc::c_char, _: *const libc::c_char)
|
|
-> *mut libc::c_char;
|
|
#[no_mangle]
|
|
fn strcmp(_: *const libc::c_char, _: *const libc::c_char) -> libc::c_int;
|
|
#[no_mangle]
|
|
fn strncmp(_: *const libc::c_char, _: *const libc::c_char,
|
|
_: libc::c_ulong) -> libc::c_int;
|
|
#[no_mangle]
|
|
fn strdup(_: *const libc::c_char) -> *mut libc::c_char;
|
|
#[no_mangle]
|
|
fn strrchr(_: *const libc::c_char, _: libc::c_int) -> *mut libc::c_char;
|
|
#[no_mangle]
|
|
fn strcasecmp(_: *const libc::c_char, _: *const libc::c_char)
|
|
-> libc::c_int;
|
|
#[no_mangle]
|
|
fn strlen(_: *const libc::c_char) -> libc::c_ulong;
|
|
#[no_mangle]
|
|
fn strerror(_: libc::c_int) -> *mut libc::c_char;
|
|
}
|
|
pub type __off_t = libc::c_long;
|
|
pub type __off64_t = libc::c_long;
|
|
pub type __pid_t = libc::c_int;
|
|
pub type __ssize_t = libc::c_long;
|
|
pub type __socklen_t = libc::c_uint;
|
|
pub type pid_t = __pid_t;
|
|
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,
|
|
}
|
|
#[derive(Copy, Clone)]
|
|
#[repr(C)]
|
|
pub struct _IO_FILE {
|
|
pub _flags: libc::c_int,
|
|
pub _IO_read_ptr: *mut libc::c_char,
|
|
pub _IO_read_end: *mut libc::c_char,
|
|
pub _IO_read_base: *mut libc::c_char,
|
|
pub _IO_write_base: *mut libc::c_char,
|
|
pub _IO_write_ptr: *mut libc::c_char,
|
|
pub _IO_write_end: *mut libc::c_char,
|
|
pub _IO_buf_base: *mut libc::c_char,
|
|
pub _IO_buf_end: *mut libc::c_char,
|
|
pub _IO_save_base: *mut libc::c_char,
|
|
pub _IO_backup_base: *mut libc::c_char,
|
|
pub _IO_save_end: *mut libc::c_char,
|
|
pub _markers: *mut _IO_marker,
|
|
pub _chain: *mut _IO_FILE,
|
|
pub _fileno: libc::c_int,
|
|
pub _flags2: libc::c_int,
|
|
pub _old_offset: __off_t,
|
|
pub _cur_column: libc::c_ushort,
|
|
pub _vtable_offset: libc::c_schar,
|
|
pub _shortbuf: [libc::c_char; 1],
|
|
pub _lock: *mut libc::c_void,
|
|
pub _offset: __off64_t,
|
|
pub _codecvt: *mut _IO_codecvt,
|
|
pub _wide_data: *mut _IO_wide_data,
|
|
pub _freeres_list: *mut _IO_FILE,
|
|
pub _freeres_buf: *mut libc::c_void,
|
|
pub __pad5: size_t,
|
|
pub _mode: libc::c_int,
|
|
pub _unused2: [libc::c_char; 20],
|
|
}
|
|
pub type _IO_lock_t = ();
|
|
pub type FILE = _IO_FILE;
|
|
#[derive(Copy, Clone)]
|
|
#[repr(C)]
|
|
pub struct link_s {
|
|
pub next: *mut link_t,
|
|
pub which: libc::c_char,
|
|
pub key: libc::c_short,
|
|
pub host: *mut libc::c_char,
|
|
pub port: *mut libc::c_char,
|
|
pub selector: *mut libc::c_char,
|
|
}
|
|
/* structs */
|
|
pub type link_t = link_s;
|
|
#[derive(Copy, Clone)]
|
|
#[repr(C)]
|
|
pub struct config_s {
|
|
pub start_uri: [libc::c_char; 512],
|
|
pub cmd_text: [libc::c_char; 512],
|
|
pub cmd_image: [libc::c_char; 512],
|
|
pub cmd_browser: [libc::c_char; 512],
|
|
pub cmd_player: [libc::c_char; 512],
|
|
pub color_prompt: [libc::c_char; 512],
|
|
pub color_selector: [libc::c_char; 512],
|
|
pub verbose: [libc::c_char; 512],
|
|
}
|
|
pub type config_t = config_s;
|
|
#[no_mangle]
|
|
pub static mut tmpfilename: [libc::c_char; 256] = [0; 256];
|
|
#[no_mangle]
|
|
pub static mut links: *mut link_t = 0 as *const link_t as *mut link_t;
|
|
#[no_mangle]
|
|
pub static mut history: *mut link_t = 0 as *const link_t as *mut link_t;
|
|
#[no_mangle]
|
|
pub static mut link_key: libc::c_int = 0;
|
|
#[no_mangle]
|
|
pub static mut current_host: [libc::c_char; 512] = [0; 512];
|
|
#[no_mangle]
|
|
pub static mut current_port: [libc::c_char; 64] = [0; 64];
|
|
#[no_mangle]
|
|
pub static mut current_selector: [libc::c_char; 1024] = [0; 1024];
|
|
#[no_mangle]
|
|
pub static mut parsed_host: [libc::c_char; 512] = [0; 512];
|
|
#[no_mangle]
|
|
pub static mut parsed_port: [libc::c_char; 64] = [0; 64];
|
|
#[no_mangle]
|
|
pub static mut parsed_selector: [libc::c_char; 1024] = [0; 1024];
|
|
#[no_mangle]
|
|
pub static mut bookmarks: [[libc::c_char; 512]; 20] = [[0; 512]; 20];
|
|
#[no_mangle]
|
|
pub static mut config: config_t =
|
|
config_t{start_uri: [0; 512],
|
|
cmd_text: [0; 512],
|
|
cmd_image: [0; 512],
|
|
cmd_browser: [0; 512],
|
|
cmd_player: [0; 512],
|
|
color_prompt: [0; 512],
|
|
color_selector: [0; 512],
|
|
verbose: [0; 512],};
|
|
/* implementation */
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn usage() {
|
|
fputs(b"usage: cgo [-v] [-H] [gopher URI]\n\x00" as *const u8 as
|
|
*const libc::c_char, stderr);
|
|
exit(0 as libc::c_int);
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn banner(mut f: *mut FILE) {
|
|
fputs(b"cgo 0.6.1 Copyright (c) 2020 Sebastian Steinhauer\n\x00" as
|
|
*const u8 as *const libc::c_char, f);
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn check_option_true(mut option: *const libc::c_char)
|
|
-> libc::c_int {
|
|
return (strcasecmp(option,
|
|
b"false\x00" as *const u8 as *const libc::c_char) != 0
|
|
&&
|
|
strcasecmp(option,
|
|
b"off\x00" as *const u8 as *const libc::c_char) !=
|
|
0) as libc::c_int;
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn parse_config_line(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) <
|
|
(::std::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 =
|
|
&mut *config.start_uri.as_mut_ptr().offset(0 as libc::c_int as
|
|
isize) as
|
|
*mut libc::c_char
|
|
} else if strcmp(token.as_mut_ptr(),
|
|
b"cmd_text\x00" as *const u8 as *const libc::c_char) == 0
|
|
{
|
|
value =
|
|
&mut *config.cmd_text.as_mut_ptr().offset(0 as libc::c_int as
|
|
isize) as
|
|
*mut libc::c_char
|
|
} else if strcmp(token.as_mut_ptr(),
|
|
b"cmd_browser\x00" as *const u8 as *const libc::c_char)
|
|
== 0 {
|
|
value =
|
|
&mut *config.cmd_browser.as_mut_ptr().offset(0 as libc::c_int as
|
|
isize) as
|
|
*mut libc::c_char
|
|
} else if strcmp(token.as_mut_ptr(),
|
|
b"cmd_image\x00" as *const u8 as *const libc::c_char) ==
|
|
0 {
|
|
value =
|
|
&mut *config.cmd_image.as_mut_ptr().offset(0 as libc::c_int as
|
|
isize) as
|
|
*mut libc::c_char
|
|
} else if strcmp(token.as_mut_ptr(),
|
|
b"cmd_player\x00" as *const u8 as *const libc::c_char) ==
|
|
0 {
|
|
value =
|
|
&mut *config.cmd_player.as_mut_ptr().offset(0 as libc::c_int as
|
|
isize) as
|
|
*mut libc::c_char
|
|
} else if strcmp(token.as_mut_ptr(),
|
|
b"color_prompt\x00" as *const u8 as *const libc::c_char)
|
|
== 0 {
|
|
value =
|
|
&mut *config.color_prompt.as_mut_ptr().offset(0 as libc::c_int as
|
|
isize) as
|
|
*mut libc::c_char
|
|
} else if strcmp(token.as_mut_ptr(),
|
|
b"color_selector\x00" as *const u8 as
|
|
*const libc::c_char) == 0 {
|
|
value =
|
|
&mut *config.color_selector.as_mut_ptr().offset(0 as libc::c_int
|
|
as isize) as
|
|
*mut libc::c_char
|
|
} else if strcmp(token.as_mut_ptr(),
|
|
b"verbose\x00" as *const u8 as *const libc::c_char) == 0
|
|
{
|
|
value =
|
|
&mut *config.verbose.as_mut_ptr().offset(0 as libc::c_int as
|
|
isize) as
|
|
*mut libc::c_char
|
|
} else {
|
|
j = 0 as libc::c_int;
|
|
while j < 20 as libc::c_int {
|
|
snprintf(bkey.as_mut_ptr(),
|
|
::std::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 =
|
|
&mut *(*bookmarks.as_mut_ptr().offset(j as
|
|
isize)).as_mut_ptr().offset(0
|
|
as
|
|
libc::c_int
|
|
as
|
|
isize)
|
|
as *mut libc::c_char;
|
|
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
|
|
}
|
|
i += 1;
|
|
*value.offset(i as isize) = 0 as libc::c_int as libc::c_char;
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn load_config(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,
|
|
::std::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 => { parse_config_line(line.as_mut_ptr()); fclose(fp); return }
|
|
13 => { ch = fgetc(fp) }
|
|
10 => {
|
|
parse_config_line(line.as_mut_ptr());
|
|
memset(line.as_mut_ptr() as *mut libc::c_void,
|
|
0 as libc::c_int,
|
|
::std::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) <
|
|
(::std::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)
|
|
}
|
|
}
|
|
};
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn init_config() {
|
|
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 */
|
|
snprintf(config.start_uri.as_mut_ptr(),
|
|
::std::mem::size_of::<[libc::c_char; 512]>() as libc::c_ulong,
|
|
b"gopher://gopher.floodgap.com:70\x00" as *const u8 as
|
|
*const libc::c_char);
|
|
snprintf(config.cmd_text.as_mut_ptr(),
|
|
::std::mem::size_of::<[libc::c_char; 512]>() as libc::c_ulong,
|
|
b"%s\x00" as *const u8 as *const libc::c_char,
|
|
b"less\x00" as *const u8 as *const libc::c_char);
|
|
snprintf(config.cmd_image.as_mut_ptr(),
|
|
::std::mem::size_of::<[libc::c_char; 512]>() as libc::c_ulong,
|
|
b"%s\x00" as *const u8 as *const libc::c_char,
|
|
b"display\x00" as *const u8 as *const libc::c_char);
|
|
snprintf(config.cmd_browser.as_mut_ptr(),
|
|
::std::mem::size_of::<[libc::c_char; 512]>() as libc::c_ulong,
|
|
b"%s\x00" as *const u8 as *const libc::c_char,
|
|
b"firefox\x00" as *const u8 as *const libc::c_char);
|
|
snprintf(config.cmd_player.as_mut_ptr(),
|
|
::std::mem::size_of::<[libc::c_char; 512]>() as libc::c_ulong,
|
|
b"%s\x00" as *const u8 as *const libc::c_char,
|
|
b"mplayer\x00" as *const u8 as *const libc::c_char);
|
|
snprintf(config.color_prompt.as_mut_ptr(),
|
|
::std::mem::size_of::<[libc::c_char; 512]>() as libc::c_ulong,
|
|
b"%s\x00" as *const u8 as *const libc::c_char,
|
|
b"1;34\x00" as *const u8 as *const libc::c_char);
|
|
snprintf(config.color_selector.as_mut_ptr(),
|
|
::std::mem::size_of::<[libc::c_char; 512]>() as libc::c_ulong,
|
|
b"%s\x00" as *const u8 as *const libc::c_char,
|
|
b"1;32\x00" as *const u8 as *const libc::c_char);
|
|
snprintf(config.verbose.as_mut_ptr(),
|
|
::std::mem::size_of::<[libc::c_char; 512]>() as libc::c_ulong,
|
|
b"%s\x00" as *const u8 as *const libc::c_char,
|
|
b"true\x00" as *const u8 as *const libc::c_char);
|
|
i = 0 as libc::c_int;
|
|
while i < 20 as libc::c_int {
|
|
bookmarks[i as usize][0 as libc::c_int as usize] =
|
|
0 as libc::c_int as libc::c_char;
|
|
i += 1
|
|
}
|
|
/* read configs */
|
|
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(),
|
|
::std::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);
|
|
load_config(filename.as_mut_ptr());
|
|
};
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn dial(mut host: *const libc::c_char,
|
|
mut port: *const libc::c_char,
|
|
mut selector: *const libc::c_char)
|
|
-> libc::c_int {
|
|
let mut hints: addrinfo =
|
|
addrinfo{ai_flags: 0,
|
|
ai_family: 0,
|
|
ai_socktype: 0,
|
|
ai_protocol: 0,
|
|
ai_addrlen: 0,
|
|
ai_addr: 0 as *mut sockaddr,
|
|
ai_canonname: 0 as *mut libc::c_char,
|
|
ai_next: 0 as *mut addrinfo,};
|
|
let mut res: *mut addrinfo = 0 as *mut addrinfo;
|
|
let mut r: *mut addrinfo = 0 as *mut addrinfo;
|
|
let mut srv: libc::c_int = -(1 as libc::c_int);
|
|
let mut l: libc::c_int = 0;
|
|
let mut request: [libc::c_char; 512] = [0; 512];
|
|
memset(&mut hints as *mut addrinfo as *mut libc::c_void, 0 as libc::c_int,
|
|
::std::mem::size_of::<addrinfo>() as libc::c_ulong);
|
|
hints.ai_family = 0 as libc::c_int;
|
|
hints.ai_socktype = SOCK_STREAM as libc::c_int;
|
|
if getaddrinfo(host, port, &mut hints, &mut res) != 0 as libc::c_int {
|
|
fprintf(stderr,
|
|
b"error: cannot resolve hostname \'%s:%s\': %s\n\x00" as
|
|
*const u8 as *const libc::c_char, host, port,
|
|
strerror(*__errno_location()));
|
|
return -(1 as libc::c_int)
|
|
}
|
|
r = res;
|
|
while !r.is_null() {
|
|
srv = socket((*r).ai_family, (*r).ai_socktype, (*r).ai_protocol);
|
|
if !(srv == -(1 as libc::c_int)) {
|
|
if connect(srv, (*r).ai_addr, (*r).ai_addrlen) == 0 as libc::c_int
|
|
{
|
|
break ;
|
|
}
|
|
close(srv);
|
|
}
|
|
r = (*r).ai_next
|
|
}
|
|
freeaddrinfo(res);
|
|
if r.is_null() {
|
|
fprintf(stderr,
|
|
b"error: cannot connect to host \'%s:%s\'\n\x00" as *const u8
|
|
as *const libc::c_char, host, port);
|
|
return -(1 as libc::c_int)
|
|
}
|
|
snprintf(request.as_mut_ptr(),
|
|
::std::mem::size_of::<[libc::c_char; 512]>() as libc::c_ulong,
|
|
b"%s\r\n\x00" as *const u8 as *const libc::c_char, selector);
|
|
l = strlen(request.as_mut_ptr()) as libc::c_int;
|
|
if write(srv, request.as_mut_ptr() as *const libc::c_void, l as size_t) !=
|
|
l as libc::c_long {
|
|
fprintf(stderr,
|
|
b"error: cannot complete request\n\x00" as *const u8 as
|
|
*const libc::c_char);
|
|
close(srv);
|
|
return -(1 as libc::c_int)
|
|
}
|
|
return srv;
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" 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,
|
|
::std::mem::size_of::<libc::c_char>() as libc::c_ulong) as
|
|
libc::c_ulong !=
|
|
::std::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;
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn download_file(mut host: *const libc::c_char,
|
|
mut port: *const libc::c_char,
|
|
mut selector: *const libc::c_char,
|
|
mut fd: libc::c_int) -> libc::c_int {
|
|
let mut srvfd: libc::c_int = 0;
|
|
let mut len: libc::c_int = 0;
|
|
let mut total: libc::c_ulong = 0 as libc::c_int as libc::c_ulong;
|
|
let mut buffer: [libc::c_char; 4096] = [0; 4096];
|
|
if check_option_true(config.verbose.as_mut_ptr()) != 0 {
|
|
printf(b"downloading [%s]...\r\x00" as *const u8 as
|
|
*const libc::c_char, selector);
|
|
}
|
|
srvfd = dial(host, port, selector);
|
|
if srvfd == -(1 as libc::c_int) {
|
|
printf(b"\x1b[2Kerror: downloading [%s] failed\n\x00" as *const u8 as
|
|
*const libc::c_char, selector);
|
|
close(fd);
|
|
return 0 as libc::c_int
|
|
}
|
|
loop {
|
|
len =
|
|
read(srvfd, buffer.as_mut_ptr() as *mut libc::c_void,
|
|
::std::mem::size_of::<[libc::c_char; 4096]>() as
|
|
libc::c_ulong) as libc::c_int;
|
|
if !(len > 0 as libc::c_int) { break ; }
|
|
write(fd, buffer.as_mut_ptr() as *const libc::c_void, len as size_t);
|
|
total = total.wrapping_add(len as libc::c_ulong);
|
|
if check_option_true(config.verbose.as_mut_ptr()) != 0 {
|
|
printf(b"downloading [%s] (%ld kb)...\r\x00" as *const u8 as
|
|
*const libc::c_char, selector,
|
|
total.wrapping_div(1024 as libc::c_int as libc::c_ulong));
|
|
}
|
|
}
|
|
close(fd);
|
|
close(srvfd);
|
|
if check_option_true(config.verbose.as_mut_ptr()) != 0 {
|
|
printf(b"\x1b[2Kdownloading [%s] complete\n\x00" as *const u8 as
|
|
*const libc::c_char, selector);
|
|
}
|
|
return 1 as libc::c_int;
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn download_temp(mut host: *const libc::c_char,
|
|
mut port: *const libc::c_char,
|
|
mut selector: *const libc::c_char)
|
|
-> libc::c_int {
|
|
let mut tmpfd: libc::c_int = 0;
|
|
strcpy(tmpfilename.as_mut_ptr(),
|
|
b"/tmp/cgoXXXXXX\x00" as *const u8 as *const libc::c_char);
|
|
tmpfd = mkstemp(tmpfilename.as_mut_ptr());
|
|
if tmpfd == -(1 as libc::c_int) {
|
|
fputs(b"error: unable to create tmp file\n\x00" as *const u8 as
|
|
*const libc::c_char, stderr);
|
|
return 0 as libc::c_int
|
|
}
|
|
if download_file(host, port, selector, tmpfd) == 0 {
|
|
unlink(tmpfilename.as_mut_ptr());
|
|
return 0 as libc::c_int
|
|
}
|
|
return 1 as libc::c_int;
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn make_key(mut c1: libc::c_char, mut c2: libc::c_char,
|
|
mut c3: libc::c_char) -> libc::c_int {
|
|
if c1 == 0 || c2 == 0 { return -(1 as libc::c_int) }
|
|
if c3 == 0 {
|
|
return (c1 as libc::c_int - 'a' as i32) *
|
|
('z' as i32 - 'a' as i32 + 1 as libc::c_int) +
|
|
(c2 as libc::c_int - 'a' as i32)
|
|
} else {
|
|
return (c1 as libc::c_int - 'a' as i32 + 1 as libc::c_int) *
|
|
('z' as i32 - 'a' as i32 + 1 as libc::c_int) *
|
|
('z' as i32 - 'a' as i32 + 1 as libc::c_int) +
|
|
(c2 as libc::c_int - 'a' as i32) *
|
|
('z' as i32 - 'a' as i32 + 1 as libc::c_int) +
|
|
(c3 as libc::c_int - 'a' as i32)
|
|
};
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn make_key_str(mut key: libc::c_int,
|
|
mut c1: *mut libc::c_char,
|
|
mut c2: *mut libc::c_char,
|
|
mut c3: *mut libc::c_char) {
|
|
if key <
|
|
('z' as i32 - 'a' as i32 + 1 as libc::c_int) *
|
|
('z' as i32 - 'a' as i32 + 1 as libc::c_int) {
|
|
*c1 =
|
|
('a' as i32 + key / ('z' as i32 - 'a' as i32 + 1 as libc::c_int))
|
|
as libc::c_char;
|
|
*c2 =
|
|
('a' as i32 + key % ('z' as i32 - 'a' as i32 + 1 as libc::c_int))
|
|
as libc::c_char;
|
|
*c3 = 0 as libc::c_int as libc::c_char
|
|
} else {
|
|
*c1 =
|
|
('a' as i32 +
|
|
key /
|
|
(('z' as i32 - 'a' as i32 + 1 as libc::c_int) *
|
|
('z' as i32 - 'a' as i32 + 1 as libc::c_int)) -
|
|
1 as libc::c_int) as libc::c_char;
|
|
*c2 =
|
|
('a' as i32 +
|
|
key / ('z' as i32 - 'a' as i32 + 1 as libc::c_int) %
|
|
('z' as i32 - 'a' as i32 + 1 as libc::c_int)) as
|
|
libc::c_char;
|
|
*c3 =
|
|
('a' as i32 + key % ('z' as i32 - 'a' as i32 + 1 as libc::c_int))
|
|
as libc::c_char
|
|
};
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn add_link(mut which: libc::c_char,
|
|
mut name: *const libc::c_char,
|
|
mut host: *const libc::c_char,
|
|
mut port: *const libc::c_char,
|
|
mut selector: *const libc::c_char) {
|
|
let mut link: *mut link_t = 0 as *mut link_t;
|
|
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() { return }
|
|
link =
|
|
calloc(1 as libc::c_int as libc::c_ulong,
|
|
::std::mem::size_of::<link_t>() as libc::c_ulong) as
|
|
*mut link_t;
|
|
(*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_t
|
|
} else { (*link).next = links }
|
|
links = link;
|
|
let fresh4 = link_key;
|
|
link_key = link_key + 1;
|
|
make_key_str(fresh4, &mut a, &mut b, &mut c);
|
|
printf(b"\x1b[%sm%c%c%c\x1b[0m \x1b[1m%s\x1b[0m\n\x00" as *const u8 as
|
|
*const libc::c_char, config.color_selector.as_mut_ptr(),
|
|
a as libc::c_int, b as libc::c_int, c as libc::c_int, name);
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn clear_links() {
|
|
let mut link: *mut link_t = 0 as *mut link_t;
|
|
let mut next: *mut link_t = 0 as *mut link_t;
|
|
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_t;
|
|
link_key = 0 as libc::c_int;
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn add_history() {
|
|
let mut link: *mut link_t = 0 as *mut link_t;
|
|
link =
|
|
calloc(1 as libc::c_int as libc::c_ulong,
|
|
::std::mem::size_of::<link_t>() as libc::c_ulong) as
|
|
*mut link_t;
|
|
(*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_t
|
|
} else { (*link).next = history }
|
|
history = link;
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn handle_directory_line(mut line: *mut libc::c_char) {
|
|
let mut i: libc::c_int = 0;
|
|
let mut lp: *mut libc::c_char = 0 as *mut libc::c_char;
|
|
let mut last: *mut libc::c_char = 0 as *mut libc::c_char;
|
|
let mut fields: [*mut libc::c_char; 4] = [0 as *mut libc::c_char; 4];
|
|
/* tokenize */
|
|
i = 0 as libc::c_int;
|
|
while i < 4 as libc::c_int {
|
|
fields[i as usize] = 0 as *mut libc::c_char;
|
|
i += 1
|
|
}
|
|
last = &mut *line.offset(1 as libc::c_int as isize) as *mut libc::c_char;
|
|
lp = last;
|
|
i = 0 as libc::c_int;
|
|
while i < 4 as libc::c_int {
|
|
if *lp as libc::c_int == '\t' as i32 ||
|
|
*lp as libc::c_int == '\u{0}' as i32 {
|
|
fields[i as usize] = last;
|
|
last = lp.offset(1 as libc::c_int as isize);
|
|
if *lp as libc::c_int == '\u{0}' as i32 { break ; }
|
|
*lp = '\u{0}' as i32 as libc::c_char;
|
|
i += 1
|
|
}
|
|
lp = lp.offset(1)
|
|
}
|
|
/* determine listing type */
|
|
match *line.offset(0 as libc::c_int as isize) as libc::c_int {
|
|
105 | 51 => {
|
|
printf(b" %s\n\x00" as *const u8 as *const libc::c_char,
|
|
fields[0 as libc::c_int as usize]);
|
|
}
|
|
46 => {
|
|
/* some gopher servers use this */
|
|
puts(b"\x00" as *const u8 as *const 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]);
|
|
}
|
|
_ => {
|
|
printf(b"miss [%c]: %s\n\x00" as *const u8 as *const libc::c_char,
|
|
*line.offset(0 as libc::c_int as isize) as libc::c_int,
|
|
fields[0 as libc::c_int as usize]);
|
|
}
|
|
};
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn is_valid_directory_entry(mut line:
|
|
*const libc::c_char)
|
|
-> libc::c_int {
|
|
match *line.offset(0 as libc::c_int as isize) as libc::c_int {
|
|
105 | 51 | 46 | 48 | 49 | 53 | 55 | 56 | 57 | 103 | 73 | 112 | 104 |
|
|
115 => {
|
|
/* some gopher servers use this */
|
|
return 1 as libc::c_int
|
|
}
|
|
_ => { return 0 as libc::c_int }
|
|
};
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn view_directory(mut host: *const libc::c_char,
|
|
mut port: *const libc::c_char,
|
|
mut selector: *const libc::c_char,
|
|
mut make_current: libc::c_int) {
|
|
let mut is_dir: libc::c_int = 0;
|
|
let mut srvfd: libc::c_int = 0;
|
|
let mut i: libc::c_int = 0;
|
|
let mut head_read: libc::c_int = 0;
|
|
let mut line: [libc::c_char; 1024] = [0; 1024];
|
|
let mut head: [[libc::c_char; 1024]; 5] = [[0; 1024]; 5];
|
|
srvfd = dial(host, port, selector);
|
|
if srvfd != -(1 as libc::c_int) {
|
|
/* only adapt current prompt when successful */
|
|
/* make history entry */
|
|
if make_current != 0 { add_history(); }
|
|
/* don't overwrite the current_* things... */
|
|
if host != current_host.as_mut_ptr() as *const libc::c_char {
|
|
snprintf(current_host.as_mut_ptr(),
|
|
::std::mem::size_of::<[libc::c_char; 512]>() as
|
|
libc::c_ulong,
|
|
b"%s\x00" as *const u8 as *const libc::c_char,
|
|
host); /* clear links *AFTER* dialing out!! */
|
|
} /* quit if not successful */
|
|
if port != current_port.as_mut_ptr() as *const libc::c_char {
|
|
snprintf(current_port.as_mut_ptr(),
|
|
::std::mem::size_of::<[libc::c_char; 64]>() as
|
|
libc::c_ulong,
|
|
b"%s\x00" as *const u8 as *const libc::c_char, port);
|
|
}
|
|
if selector != current_selector.as_mut_ptr() as *const libc::c_char {
|
|
snprintf(current_selector.as_mut_ptr(),
|
|
::std::mem::size_of::<[libc::c_char; 1024]>() as
|
|
libc::c_ulong,
|
|
b"%s\x00" as *const u8 as *const libc::c_char, selector);
|
|
}
|
|
}
|
|
clear_links();
|
|
if srvfd == -(1 as libc::c_int) { return }
|
|
head_read = 0 as libc::c_int;
|
|
is_dir = 1 as libc::c_int;
|
|
while head_read < 5 as libc::c_int &&
|
|
read_line(srvfd, line.as_mut_ptr(),
|
|
::std::mem::size_of::<[libc::c_char; 1024]>() as
|
|
libc::c_ulong) != 0 {
|
|
strcpy(head[head_read as usize].as_mut_ptr(), line.as_mut_ptr());
|
|
if is_valid_directory_entry(head[head_read as usize].as_mut_ptr()) ==
|
|
0 {
|
|
is_dir = 0 as libc::c_int;
|
|
break ;
|
|
} else { head_read += 1 }
|
|
}
|
|
if is_dir == 0 {
|
|
puts(b"error: Not a directory.\x00" as *const u8 as
|
|
*const libc::c_char);
|
|
close(srvfd);
|
|
return
|
|
}
|
|
i = 0 as libc::c_int;
|
|
while i < head_read {
|
|
handle_directory_line(head[i as usize].as_mut_ptr());
|
|
i += 1
|
|
}
|
|
while read_line(srvfd, line.as_mut_ptr(),
|
|
::std::mem::size_of::<[libc::c_char; 1024]>() as
|
|
libc::c_ulong) != 0 {
|
|
handle_directory_line(line.as_mut_ptr());
|
|
}
|
|
close(srvfd);
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn view_file(mut cmd: *const libc::c_char,
|
|
mut host: *const libc::c_char,
|
|
mut port: *const libc::c_char,
|
|
mut selector: *const libc::c_char) {
|
|
let mut pid: pid_t = 0;
|
|
let mut status: libc::c_int = 0;
|
|
let mut i: libc::c_int = 0;
|
|
let mut j: libc::c_int = 0;
|
|
let mut buffer: [libc::c_char; 1024] = [0; 1024];
|
|
let mut argv: [*mut libc::c_char; 32] = [0 as *mut libc::c_char; 32];
|
|
let mut p: *mut libc::c_char = 0 as *mut libc::c_char;
|
|
if check_option_true(config.verbose.as_mut_ptr()) != 0 {
|
|
printf(b"h(%s) p(%s) s(%s)\n\x00" as *const u8 as *const libc::c_char,
|
|
host, port, selector);
|
|
}
|
|
if download_temp(host, port, selector) == 0 { return }
|
|
/* parsed command line string */
|
|
argv[0 as libc::c_int as usize] =
|
|
&mut *buffer.as_mut_ptr().offset(0 as libc::c_int as isize) as
|
|
*mut libc::c_char;
|
|
p = cmd as *mut libc::c_char;
|
|
i = 0 as libc::c_int;
|
|
j = 1 as libc::c_int;
|
|
while *p as libc::c_int != 0 &&
|
|
(i as libc::c_ulong) <
|
|
(::std::mem::size_of::<[libc::c_char; 1024]>() as
|
|
libc::c_ulong).wrapping_sub(1 as libc::c_int as
|
|
libc::c_ulong) &&
|
|
j < 30 as libc::c_int {
|
|
if *p as libc::c_int == ' ' as i32 || *p as libc::c_int == '\t' as i32
|
|
{
|
|
let fresh5 = i;
|
|
i = i + 1;
|
|
buffer[fresh5 as usize] = 0 as libc::c_int as libc::c_char;
|
|
let fresh6 = j;
|
|
j = j + 1;
|
|
argv[fresh6 as usize] =
|
|
&mut *buffer.as_mut_ptr().offset(i as isize) as
|
|
*mut libc::c_char;
|
|
while *p as libc::c_int == ' ' as i32 ||
|
|
*p as libc::c_int == '\t' as i32 {
|
|
p = p.offset(1)
|
|
}
|
|
} else {
|
|
let fresh7 = p;
|
|
p = p.offset(1);
|
|
let fresh8 = i;
|
|
i = i + 1;
|
|
buffer[fresh8 as usize] = *fresh7
|
|
}
|
|
}
|
|
buffer[i as usize] = 0 as libc::c_int as libc::c_char;
|
|
let fresh9 = j;
|
|
j = j + 1;
|
|
argv[fresh9 as usize] = tmpfilename.as_mut_ptr();
|
|
argv[j as usize] = 0 as *mut libc::c_char;
|
|
/* fork and execute */
|
|
if check_option_true(config.verbose.as_mut_ptr()) != 0 {
|
|
printf(b"executing: %s %s\n\x00" as *const u8 as *const libc::c_char,
|
|
cmd,
|
|
tmpfilename.as_mut_ptr()); /* to wait for browsers etc. that return immediatly */
|
|
}
|
|
pid = fork();
|
|
if pid == 0 as libc::c_int {
|
|
if execvp(argv[0 as libc::c_int as usize],
|
|
argv.as_mut_ptr() as *const *mut libc::c_char) ==
|
|
-(1 as libc::c_int) {
|
|
puts(b"error: execvp() failed!\x00" as *const u8 as
|
|
*const libc::c_char);
|
|
}
|
|
} else if pid == -(1 as libc::c_int) {
|
|
puts(b"error: fork() failed\x00" as *const u8 as *const libc::c_char);
|
|
}
|
|
sleep(1 as libc::c_int as libc::c_uint);
|
|
waitpid(pid, &mut status, 0 as libc::c_int);
|
|
unlink(tmpfilename.as_mut_ptr());
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn view_telnet(mut host: *const libc::c_char,
|
|
mut port: *const libc::c_char) {
|
|
let mut pid: pid_t = 0;
|
|
let mut status: libc::c_int = 0;
|
|
printf(b"executing: %s %s %s\n\x00" as *const u8 as *const libc::c_char,
|
|
b"telnet\x00" as *const u8 as *const libc::c_char, host, port);
|
|
pid = fork();
|
|
if pid == 0 as libc::c_int {
|
|
if execlp(b"telnet\x00" as *const u8 as *const libc::c_char,
|
|
b"telnet\x00" as *const u8 as *const libc::c_char, host,
|
|
port, 0 as *mut libc::c_void) == -(1 as libc::c_int) {
|
|
puts(b"error: execlp() failed!\x00" as *const u8 as
|
|
*const libc::c_char);
|
|
}
|
|
} else if pid == -(1 as libc::c_int) {
|
|
puts(b"error: fork() failed!\x00" as *const u8 as
|
|
*const libc::c_char);
|
|
}
|
|
waitpid(pid, &mut status, 0 as libc::c_int);
|
|
puts(b"(done)\x00" as *const u8 as *const libc::c_char);
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn view_download(mut host: *const libc::c_char,
|
|
mut port: *const libc::c_char,
|
|
mut selector: *const libc::c_char) {
|
|
let mut fd: libc::c_int = 0;
|
|
let mut filename: [libc::c_char; 1024] = [0; 1024];
|
|
let mut line: [libc::c_char; 1024] = [0; 1024];
|
|
snprintf(filename.as_mut_ptr(),
|
|
::std::mem::size_of::<[libc::c_char; 1024]>() as libc::c_ulong,
|
|
b"%s\x00" as *const u8 as *const libc::c_char,
|
|
strrchr(selector, '/' as i32).offset(1 as libc::c_int as isize));
|
|
printf(b"enter filename for download [%s]: \x00" as *const u8 as
|
|
*const libc::c_char, filename.as_mut_ptr());
|
|
fflush(stdout);
|
|
if read_line(0 as libc::c_int, line.as_mut_ptr(),
|
|
::std::mem::size_of::<[libc::c_char; 1024]>() as
|
|
libc::c_ulong) == 0 {
|
|
puts(b"download aborted\x00" as *const u8 as *const libc::c_char);
|
|
return
|
|
}
|
|
if strlen(line.as_mut_ptr()) > 0 as libc::c_int as libc::c_ulong {
|
|
strcpy(filename.as_mut_ptr(), line.as_mut_ptr());
|
|
}
|
|
fd =
|
|
open(filename.as_mut_ptr(), 0o100 as libc::c_int | 0o1 as libc::c_int,
|
|
0o400 as libc::c_int | 0o200 as libc::c_int);
|
|
if fd == -(1 as libc::c_int) {
|
|
printf(b"error: unable to create file [%s]: %s\n\x00" as *const u8 as
|
|
*const libc::c_char, filename.as_mut_ptr(),
|
|
strerror(*__errno_location()));
|
|
return
|
|
}
|
|
if download_file(host, port, selector, fd) == 0 {
|
|
printf(b"error: unable to download [%s]\n\x00" as *const u8 as
|
|
*const libc::c_char, selector);
|
|
unlink(filename.as_mut_ptr());
|
|
return
|
|
};
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn view_search(mut host: *const libc::c_char,
|
|
mut port: *const libc::c_char,
|
|
mut selector: *const libc::c_char) {
|
|
let mut search_selector: [libc::c_char; 1024] = [0; 1024];
|
|
let mut line: [libc::c_char; 1024] = [0; 1024];
|
|
printf(b"enter search string: \x00" as *const u8 as *const libc::c_char);
|
|
fflush(stdout);
|
|
if read_line(0 as libc::c_int, line.as_mut_ptr(),
|
|
::std::mem::size_of::<[libc::c_char; 1024]>() as
|
|
libc::c_ulong) == 0 {
|
|
puts(b"search aborted\x00" as *const u8 as *const libc::c_char);
|
|
return
|
|
}
|
|
snprintf(search_selector.as_mut_ptr(),
|
|
::std::mem::size_of::<[libc::c_char; 1024]>() as libc::c_ulong,
|
|
b"%s\t%s\x00" as *const u8 as *const libc::c_char, selector,
|
|
line.as_mut_ptr());
|
|
view_directory(host, port, search_selector.as_mut_ptr(),
|
|
1 as libc::c_int);
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn view_history(mut key: libc::c_int) {
|
|
let mut history_key: libc::c_int = 0 as 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_t = 0 as *mut link_t;
|
|
if history.is_null() {
|
|
puts(b"(empty history)\x00" as *const u8 as *const libc::c_char);
|
|
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() {
|
|
let fresh10 = history_key;
|
|
history_key = history_key + 1;
|
|
make_key_str(fresh10, &mut a, &mut b, &mut c);
|
|
printf(b"\x1b[%sm%c%c%c\x1b[0m \x1b[1m%s:%s/1%s\x1b[0m\n\x00" as
|
|
*const u8 as *const libc::c_char,
|
|
b"1;32\x00" as *const u8 as *const libc::c_char,
|
|
a as libc::c_int, b as libc::c_int, c as libc::c_int,
|
|
(*link).host, (*link).port, (*link).selector);
|
|
link = (*link).next
|
|
}
|
|
} else {
|
|
/* traverse history list */
|
|
link = history;
|
|
while !link.is_null() {
|
|
if history_key == key {
|
|
view_directory((*link).host, (*link).port, (*link).selector,
|
|
0 as libc::c_int);
|
|
return
|
|
}
|
|
link = (*link).next;
|
|
history_key += 1
|
|
}
|
|
puts(b"history item not found\x00" as *const u8 as
|
|
*const libc::c_char);
|
|
};
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn view_bookmarks(mut key: libc::c_int) {
|
|
let mut i: libc::c_int = 0;
|
|
let mut a: libc::c_char = 0;
|
|
let mut b: libc::c_char = 0;
|
|
let mut c: libc::c_char = 0;
|
|
if key < 0 as libc::c_int {
|
|
puts(b"(bookmarks)\x00" as *const u8 as *const libc::c_char);
|
|
i = 0 as libc::c_int;
|
|
while i < 20 as libc::c_int {
|
|
if bookmarks[i as usize][0 as libc::c_int as usize] != 0 {
|
|
make_key_str(i, &mut a, &mut b, &mut c);
|
|
printf(b"\x1b[%sm%c%c%c\x1b[0m \x1b[1m%s\x1b[0m\n\x00" as
|
|
*const u8 as *const libc::c_char,
|
|
b"1;32\x00" as *const u8 as *const libc::c_char,
|
|
a as libc::c_int, b as libc::c_int, c as libc::c_int,
|
|
&mut *(*bookmarks.as_mut_ptr().offset(i as
|
|
isize)).as_mut_ptr().offset(0
|
|
as
|
|
libc::c_int
|
|
as
|
|
isize)
|
|
as *mut libc::c_char);
|
|
}
|
|
i += 1
|
|
}
|
|
} else {
|
|
i = 0 as libc::c_int;
|
|
while i < 20 as libc::c_int {
|
|
if bookmarks[i as usize][0 as libc::c_int as usize] as libc::c_int
|
|
!= 0 && i == key {
|
|
if parse_uri(&mut *(*bookmarks.as_mut_ptr().offset(i as
|
|
isize)).as_mut_ptr().offset(0
|
|
as
|
|
libc::c_int
|
|
as
|
|
isize))
|
|
!= 0 {
|
|
view_directory(parsed_host.as_mut_ptr(),
|
|
parsed_port.as_mut_ptr(),
|
|
parsed_selector.as_mut_ptr(),
|
|
0 as libc::c_int);
|
|
} else {
|
|
printf(b"invalid gopher URI: %s\x00" as *const u8 as
|
|
*const libc::c_char,
|
|
&mut *(*bookmarks.as_mut_ptr().offset(i as
|
|
isize)).as_mut_ptr().offset(0
|
|
as
|
|
libc::c_int
|
|
as
|
|
isize)
|
|
as *mut libc::c_char);
|
|
}
|
|
return
|
|
}
|
|
i += 1
|
|
}
|
|
};
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn pop_history() {
|
|
let mut next: *mut link_t = 0 as *mut link_t;
|
|
if history.is_null() {
|
|
puts(b"(empty history)\x00" as *const u8 as *const libc::c_char);
|
|
return
|
|
}
|
|
/* 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;
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn follow_link(mut key: libc::c_int) -> libc::c_int {
|
|
let mut link: *mut link_t = 0 as *mut link_t;
|
|
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 => {
|
|
view_file(&mut *config.cmd_text.as_mut_ptr().offset(0 as
|
|
libc::c_int
|
|
as
|
|
isize),
|
|
(*link).host, (*link).port, (*link).selector);
|
|
}
|
|
49 => {
|
|
view_directory((*link).host, (*link).port,
|
|
(*link).selector, 1 as libc::c_int);
|
|
}
|
|
55 => {
|
|
view_search((*link).host, (*link).port, (*link).selector);
|
|
}
|
|
53 | 57 => {
|
|
view_download((*link).host, (*link).port,
|
|
(*link).selector);
|
|
}
|
|
56 => { view_telnet((*link).host, (*link).port); }
|
|
103 | 73 | 112 => {
|
|
view_file(&mut *config.cmd_image.as_mut_ptr().offset(0 as
|
|
libc::c_int
|
|
as
|
|
isize),
|
|
(*link).host, (*link).port, (*link).selector);
|
|
}
|
|
104 => {
|
|
view_file(&mut *config.cmd_browser.as_mut_ptr().offset(0
|
|
as
|
|
libc::c_int
|
|
as
|
|
isize),
|
|
(*link).host, (*link).port, (*link).selector);
|
|
}
|
|
115 => {
|
|
view_file(&mut *config.cmd_player.as_mut_ptr().offset(0 as
|
|
libc::c_int
|
|
as
|
|
isize),
|
|
(*link).host, (*link).port, (*link).selector);
|
|
}
|
|
_ => {
|
|
printf(b"missing handler [%c]\n\x00" as *const u8 as
|
|
*const libc::c_char,
|
|
(*link).which as libc::c_int);
|
|
}
|
|
}
|
|
return 1 as libc::c_int
|
|
}
|
|
/* return the array is broken after view! */
|
|
}
|
|
return 0 as libc::c_int;
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn download_link(mut key: libc::c_int) {
|
|
let mut link: *mut link_t = 0 as *mut link_t;
|
|
link = links;
|
|
while !link.is_null() {
|
|
if (*link).key as libc::c_int != key {
|
|
link = (*link).next
|
|
} else {
|
|
view_download((*link).host, (*link).port, (*link).selector);
|
|
return
|
|
}
|
|
}
|
|
puts(b"link not found\x00" as *const u8 as *const libc::c_char);
|
|
}
|
|
/* function prototypes */
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn parse_uri(mut uri: *const libc::c_char)
|
|
-> libc::c_int {
|
|
let mut i: libc::c_int = 0;
|
|
/* strip gopher:// */
|
|
if strncmp(uri, b"gopher://\x00" as *const u8 as *const libc::c_char,
|
|
9 as libc::c_int as libc::c_ulong) == 0 {
|
|
uri = uri.offset(9 as libc::c_int as isize)
|
|
}
|
|
/* parse host */
|
|
i = 0 as libc::c_int;
|
|
while *uri as libc::c_int != 0 && *uri as libc::c_int != ':' as i32 &&
|
|
*uri as libc::c_int != '/' as i32 {
|
|
if *uri as libc::c_int != ' ' as i32 &&
|
|
(i as libc::c_ulong) <
|
|
(::std::mem::size_of::<[libc::c_char; 512]>() as
|
|
libc::c_ulong).wrapping_sub(1 as libc::c_int as
|
|
libc::c_ulong) {
|
|
let fresh11 = i;
|
|
i = i + 1;
|
|
parsed_host[fresh11 as usize] = *uri
|
|
}
|
|
uri = uri.offset(1)
|
|
}
|
|
if i > 0 as libc::c_int {
|
|
parsed_host[i as usize] = 0 as libc::c_int as libc::c_char
|
|
} else { return 0 as libc::c_int }
|
|
/* parse port */
|
|
if *uri as libc::c_int == ':' as i32 {
|
|
uri = uri.offset(1);
|
|
i = 0 as libc::c_int;
|
|
while *uri as libc::c_int != 0 && *uri as libc::c_int != '/' as i32 {
|
|
if *uri as libc::c_int != ' ' as i32 &&
|
|
(i as libc::c_ulong) <
|
|
(::std::mem::size_of::<[libc::c_char; 64]>() as
|
|
libc::c_ulong).wrapping_sub(1 as libc::c_int as
|
|
libc::c_ulong) {
|
|
let fresh12 = i;
|
|
i = i + 1;
|
|
parsed_port[fresh12 as usize] = *uri
|
|
}
|
|
uri = uri.offset(1)
|
|
}
|
|
parsed_port[i as usize] = 0 as libc::c_int as libc::c_char
|
|
} else {
|
|
snprintf(parsed_port.as_mut_ptr(),
|
|
::std::mem::size_of::<[libc::c_char; 64]>() as libc::c_ulong,
|
|
b"%d\x00" as *const u8 as *const libc::c_char,
|
|
70 as libc::c_int);
|
|
}
|
|
/* parse selector (ignore slash and selector type) */
|
|
if *uri != 0 { uri = uri.offset(1) }
|
|
if *uri != 0 { uri = uri.offset(1) }
|
|
i = 0 as libc::c_int;
|
|
while *uri as libc::c_int != 0 &&
|
|
(i as libc::c_ulong) <
|
|
(::std::mem::size_of::<[libc::c_char; 1024]>() as
|
|
libc::c_ulong).wrapping_sub(1 as libc::c_int as
|
|
libc::c_ulong) {
|
|
parsed_selector[i as usize] = *uri;
|
|
uri = uri.offset(1);
|
|
i += 1
|
|
}
|
|
parsed_selector[i as usize] = '\u{0}' as i32 as libc::c_char;
|
|
return 1 as libc::c_int;
|
|
}
|
|
unsafe fn main_0(mut argc: libc::c_int, mut argv: *mut *mut libc::c_char)
|
|
-> libc::c_int {
|
|
let mut i: libc::c_int = 0;
|
|
let mut line: [libc::c_char; 1024] = [0; 1024];
|
|
let mut uri: *mut libc::c_char = 0 as *mut libc::c_char;
|
|
/* copy defaults */
|
|
init_config();
|
|
uri =
|
|
&mut *config.start_uri.as_mut_ptr().offset(0 as libc::c_int as isize)
|
|
as *mut libc::c_char;
|
|
/* parse command line */
|
|
i = 1 as libc::c_int;
|
|
while i < argc {
|
|
if *(*argv.offset(i as isize)).offset(0 as libc::c_int as isize) as
|
|
libc::c_int == '-' as i32 {
|
|
match *(*argv.offset(i as
|
|
isize)).offset(1 as libc::c_int as isize)
|
|
as libc::c_int {
|
|
72 => { usage(); }
|
|
118 => { banner(stdout); exit(0 as libc::c_int); }
|
|
_ => { usage(); }
|
|
}
|
|
} else { uri = *argv.offset(i as isize) }
|
|
i += 1
|
|
}
|
|
/* parse uri */
|
|
if parse_uri(uri) == 0 {
|
|
banner(stderr);
|
|
fprintf(stderr,
|
|
b"invalid gopher URI: %s\x00" as *const u8 as
|
|
*const libc::c_char, *argv.offset(i as isize));
|
|
exit(1 as libc::c_int);
|
|
}
|
|
/* main loop */
|
|
view_directory(parsed_host.as_mut_ptr(), parsed_port.as_mut_ptr(),
|
|
parsed_selector.as_mut_ptr(),
|
|
0 as libc::c_int); /* to display the prompt */
|
|
loop {
|
|
printf(b"\x1b[%sm%s:%s%s\x1b[0m \x00" as *const u8 as
|
|
*const libc::c_char, config.color_prompt.as_mut_ptr(),
|
|
current_host.as_mut_ptr(), current_port.as_mut_ptr(),
|
|
current_selector.as_mut_ptr());
|
|
fflush(stdout);
|
|
if read_line(0 as libc::c_int, line.as_mut_ptr(),
|
|
::std::mem::size_of::<[libc::c_char; 1024]>() as
|
|
libc::c_ulong) == 0 {
|
|
puts(b"QUIT\x00" as *const u8 as *const libc::c_char);
|
|
return 0 as libc::c_int
|
|
}
|
|
i = strlen(line.as_mut_ptr()) as libc::c_int;
|
|
match line[0 as libc::c_int as usize] as libc::c_int {
|
|
63 => {
|
|
puts(b"? - 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\x00"
|
|
as *const u8 as *const libc::c_char);
|
|
}
|
|
60 => { pop_history(); }
|
|
42 => {
|
|
view_directory(current_host.as_mut_ptr(),
|
|
current_port.as_mut_ptr(),
|
|
current_selector.as_mut_ptr(),
|
|
0 as libc::c_int);
|
|
}
|
|
46 => {
|
|
download_link(make_key(line[1 as libc::c_int as usize],
|
|
line[2 as libc::c_int as usize],
|
|
line[3 as libc::c_int as usize]));
|
|
}
|
|
72 => {
|
|
if i == 1 as libc::c_int || i == 3 as libc::c_int ||
|
|
i == 4 as libc::c_int {
|
|
view_history(make_key(line[1 as libc::c_int as usize],
|
|
line[2 as libc::c_int as usize],
|
|
line[3 as libc::c_int as usize]));
|
|
}
|
|
}
|
|
71 => {
|
|
if parse_uri(&mut *line.as_mut_ptr().offset(1 as libc::c_int
|
|
as isize)) !=
|
|
0 {
|
|
view_directory(parsed_host.as_mut_ptr(),
|
|
parsed_port.as_mut_ptr(),
|
|
parsed_selector.as_mut_ptr(),
|
|
1 as libc::c_int);
|
|
} else {
|
|
puts(b"invalid gopher URI\x00" as *const u8 as
|
|
*const libc::c_char);
|
|
}
|
|
}
|
|
66 => {
|
|
if i == 1 as libc::c_int || i == 3 as libc::c_int ||
|
|
i == 4 as libc::c_int {
|
|
view_bookmarks(make_key(line[1 as libc::c_int as usize],
|
|
line[2 as libc::c_int as usize],
|
|
line[3 as libc::c_int as usize]));
|
|
}
|
|
}
|
|
_ => {
|
|
follow_link(make_key(line[0 as libc::c_int as usize],
|
|
line[1 as libc::c_int as usize],
|
|
line[2 as libc::c_int as usize]));
|
|
}
|
|
}
|
|
};
|
|
/* never get's here but stops cc complaining */
|
|
}
|
|
#[main]
|
|
pub fn main() {
|
|
let mut args: Vec<*mut libc::c_char> = Vec::new();
|
|
for arg in ::std::env::args() {
|
|
args.push(::std::ffi::CString::new(arg).expect("Failed to convert argument into CString.").into_raw());
|
|
};
|
|
args.push(::std::ptr::null_mut());
|
|
unsafe {
|
|
::std::process::exit(main_0((args.len() - 1) as libc::c_int,
|
|
args.as_mut_ptr() as
|
|
*mut *mut libc::c_char) as i32)
|
|
}
|
|
}
|