#![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::() 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::() as libc::c_ulong) as libc::c_ulong != ::std::mem::size_of::() 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::() 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::() 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) } }