char/avril
(wip) why'd you have to go and make things so complicaaaaated?
git clone https://git.t4t.associates/char/avril
f4a0f5b
main
1use std:: convert:: Infallible ; 2use std:: io; 3use std:: sync:: Arc ; 4 5use avril_caps::{ Capabilities , PathTarget }; 6use avril_core:: Op ; 7 8use avril_host:: io:: response; 9 10type Info =( u32 , String , String , String , String , Vec < String >); 11 12fn denied ( error : String ) -> io:: Error { 13 io:: Error :: new ( io:: ErrorKind :: PermissionDenied , error. to_string ()) 14} 15 16fn cwd ( caps : & Capabilities ) -> io:: Result < String > { 17let current = std:: env:: current_dir () ?; 18let target =PathTarget :: resolve ( & current) ?; 19 caps. check_read ( & target) 20. map_err ( |error|denied ( error. to_string ())) ?; 21 target 22. as_path () 23. to_str () 24. map ( str:: to_owned) 25. ok_or_else ( || io:: Error :: new ( io:: ErrorKind :: InvalidInput , "cwd is not UTF-8" )) 26} 27 28fn sys < T >( caps : & Capabilities , name : & str , value : fn () -> io:: Result < T >) -> io:: Result < T > { 29 caps. check_sys ( name) 30. map_err ( |error|denied ( error. to_string ())) ?; 31value () 32} 33 34pub fn ops ( caps : Arc < Capabilities >, args : Vec < String >) ->Vec < Op > { 35let info: Info =( 36 std:: process:: id (), 37 std:: env:: consts:: OS . to_owned (), 38 std:: env:: consts:: ARCH . to_owned (), 39env! ( "CARGO_PKG_VERSION" ). to_owned (), 40 avril_core:: v8:: V8 :: get_version (). to_owned (), 41 args, 42); 43vec! [ 44Op :: new ( "op_process_cwd" , { 45let caps = caps. clone (); 46move |(): () |Ok ::< _ , Infallible >( response ( cwd ( & caps))) 47}), 48Op :: new ( "op_sys_hostname" , { 49let caps = caps. clone (); 50move |(): () |Ok ::< _ , Infallible >( response ( sys ( & caps, "hostname" , hostname))) 51}), 52Op :: new ( "op_sys_os_release" , { 53let caps = caps. clone (); 54move |(): () |Ok ::< _ , Infallible >( response ( sys ( & caps, "osRelease" , os_release))) 55}), 56Op :: new ( "op_sys_uptime" , { 57let caps = caps. clone (); 58move |(): () |Ok ::< _ , Infallible >( response ( sys ( & caps, "uptime" , uptime))) 59}), 60Op :: new ( "op_sys_loadavg" , { 61let caps = caps. clone (); 62move |(): () |Ok ::< _ , Infallible >( response ( sys ( & caps, "loadavg" , loadavg))) 63}), 64Op :: new ( "op_runtime_info" , move |(): () |{ 65Ok ::< _ , Infallible >( info. clone ()) 66}), 67] 68} 69 70# [ cfg ( unix )] 71fn text ( bytes : & [ libc:: c_char ]) -> io:: Result < String > { 72let end = bytes 73. iter () 74. position ( |byte|* byte ==0 ) 75. unwrap_or ( bytes. len ()); 76let bytes: Vec < u8 > = bytes[ ..end]. iter (). map ( |byte|* byteas u8 ). collect (); 77String :: from_utf8 ( bytes) 78. map_err ( |_| io:: Error :: new ( io:: ErrorKind :: InvalidData , "System string is not UTF-8" )) 79} 80 81# [ cfg ( unix )] 82fn hostname () -> io:: Result < String > { 83let mut buffer =[ 0 as libc:: c_char ; 256 ]; 84if unsafe { libc:: gethostname ( buffer. as_mut_ptr (), buffer. len ()) } !=0 { 85return Err ( io:: Error :: last_os_error ()); 86} 87text ( & buffer) 88} 89 90# [ cfg ( unix )] 91fn os_release () -> io:: Result < String > { 92let mut name: libc:: utsname =unsafe { std:: mem:: zeroed () }; 93if unsafe { libc:: uname ( & mut name) } !=0 { 94return Err ( io:: Error :: last_os_error ()); 95} 96text ( & name. release ) 97} 98 99# [ cfg ( target_os = "linux" )] 100fn uptime () -> io:: Result < f64 > { 101let mut info: libc:: sysinfo =unsafe { std:: mem:: zeroed () }; 102if unsafe { libc:: sysinfo ( & mut info) } !=0 { 103return Err ( io:: Error :: last_os_error ()); 104} 105Ok ( info. uptime as f64 ) 106} 107 108# [ cfg ( target_os = "macos" )] 109fn uptime () -> io:: Result < f64 > { 110let mut boot: libc:: timeval =unsafe { std:: mem:: zeroed () }; 111let mut size = std:: mem:: size_of ::< libc:: timeval >(); 112if unsafe { 113 libc:: sysctlbyname ( 114c"kern.boottime" . as_ptr (), 115( & raw mut boot). cast (), 116& mut size, 117 std:: ptr:: null_mut (), 1180 , 119) 120} !=0 121{ 122return Err ( io:: Error :: last_os_error ()); 123} 124let now = std:: time:: SystemTime :: now () 125. duration_since ( std:: time:: UNIX_EPOCH ) 126. map_err ( io:: Error :: other) ?; 127Ok ( now. as_secs_f64 () - boot. tv_sec as f64 ) 128} 129 130# [ cfg ( all ( unix , not ( any ( target_os = "linux" , target_os = "macos" ))))] 131fn uptime () -> io:: Result < f64 > { 132Err ( io:: Error :: new ( 133 io:: ErrorKind :: Unsupported , 134"uptime is not supported on this platform" , 135)) 136} 137 138# [ cfg ( unix )] 139fn loadavg () -> io:: Result <[ f64 ; 3 ]> { 140let mut samples =[ 0.0 ; 3 ]; 141if unsafe { libc:: getloadavg ( samples. as_mut_ptr (), 3 ) } !=3 { 142return Err ( io:: Error :: last_os_error ()); 143} 144Ok ( samples) 145} 146 147# [ cfg ( windows )] 148fn hostname () -> io:: Result < String > { 149use windows_sys:: Win32 :: System :: SystemInformation ::{ 150ComputerNamePhysicalDnsHostname , GetComputerNameExW , 151}; 152let mut buffer =[ 0u16 ; 256 ]; 153let mut size = buffer. len () as u32 ; 154if unsafe { 155GetComputerNameExW ( 156ComputerNamePhysicalDnsHostname , 157 buffer. as_mut_ptr (), 158& mut size, 159) 160} ==0 161{ 162return Err ( io:: Error :: last_os_error ()); 163} 164String :: from_utf16 ( & buffer[ ..sizeas usize ]) 165. map_err ( |_| io:: Error :: new ( io:: ErrorKind :: InvalidData , "Hostname is not UTF-16" )) 166} 167 168// windows-sys does not expose RtlGetVersion under Win32, and GetVersionExW 169// reports the compatibility version rather than the real one. 170# [ cfg ( windows )] 171# [ link ( name = "ntdll" )] 172unsafe extern "system" { 173fn RtlGetVersion ( 174version : * mut windows_sys:: Win32 :: System :: SystemInformation :: OSVERSIONINFOW , 175) ->i32 ; 176} 177 178# [ cfg ( windows )] 179fn os_release () -> io:: Result < String > { 180use windows_sys:: Win32 :: System :: SystemInformation :: OSVERSIONINFOW ; 181let mut version =OSVERSIONINFOW { 182dwOSVersionInfoSize : std:: mem:: size_of ::< OSVERSIONINFOW >() as u32 , 183 ..Default :: default () 184}; 185if unsafe { RtlGetVersion ( & mut version) } !=0 { 186return Err ( io:: Error :: other ( "RtlGetVersion failed" )); 187} 188Ok ( format! ( 189"{}.{}.{}" , 190 version. dwMajorVersion , version. dwMinorVersion , version. dwBuildNumber 191)) 192} 193 194# [ cfg ( windows )] 195fn uptime () -> io:: Result < f64 > { 196use windows_sys:: Win32 :: System :: SystemInformation :: GetTickCount64 ; 197Ok ( unsafe { GetTickCount64 () } as f64 /1000.0 ) 198} 199 200# [ cfg ( windows )] 201fn loadavg () -> io:: Result <[ f64 ; 3 ]> { 202Ok ([ 0.0 , 0.0 , 0.0 ]) 203} 204 205# [ cfg ( not ( any ( unix , windows )))] 206fn hostname () -> io:: Result < String > { 207Err ( io:: Error :: new ( 208 io:: ErrorKind :: Unsupported , 209"hostname is not supported on this platform" , 210)) 211} 212 213# [ cfg ( not ( any ( unix , windows )))] 214fn os_release () -> io:: Result < String > { 215Err ( io:: Error :: new ( 216 io:: ErrorKind :: Unsupported , 217"osRelease is not supported on this platform" , 218)) 219} 220 221# [ cfg ( not ( any ( unix , windows )))] 222fn uptime () -> io:: Result < f64 > { 223Err ( io:: Error :: new ( 224 io:: ErrorKind :: Unsupported , 225"uptime is not supported on this platform" , 226)) 227} 228 229# [ cfg ( not ( any ( unix , windows )))] 230fn loadavg () -> io:: Result <[ f64 ; 3 ]> { 231Err ( io:: Error :: new ( 232 io:: ErrorKind :: Unsupported , 233"loadavg is not supported on this platform" , 234)) 235}