1919
2020extern crate core;
2121
22+ use std:: path:: PathBuf ;
2223use anyhow:: Result ;
24+ use intercept:: reporter:: { Reporter , TcpReporter } ;
2325
2426fn main ( ) -> Result < ( ) > {
25- Ok ( ( ) )
27+ // Find out what is the executable name the execution was started with
28+ let executable = std:: env:: args ( ) . next ( ) . unwrap ( ) ;
29+ // Read the PATH variable and find the next executable with the same name
30+ let real_executable = std:: env:: var ( "PATH" ) ?
31+ . split ( ':' )
32+ . map ( |dir| std:: path:: Path :: new ( dir) . join ( & executable) )
33+ . filter ( |path| path. exists ( ) )
34+ . nth ( 1 )
35+ . ok_or_else ( || anyhow:: anyhow!( "Cannot find the real executable" ) ) ?;
36+ // TODO: ^ This is a very naive way to find the real executable.
37+ // Make sure we don't call ourselves.
38+
39+ // Report the execution with the real executable
40+ report_execution ( & real_executable) ;
41+
42+ // Execute the real executable with the same arguments
43+ let status = std:: process:: Command :: new ( real_executable)
44+ . args ( std:: env:: args ( ) . skip ( 1 ) )
45+ . status ( ) ?;
46+ // Return the status code
47+ std:: process:: exit ( status. code ( ) . unwrap_or ( 1 ) ) ;
48+ }
49+
50+ // TODO: Current error handling is very basic, it just panics on any error.
51+ // More sophisticated error handling can be: logging the error and return.
52+ fn report_execution ( path_buf : & PathBuf ) {
53+ // Get the reporter address from the environment
54+ let reporter_address = std:: env:: var ( INTERCEPT_REPORTER_ADDRESS )
55+ . expect ( format ! ( "${} is not set" , INTERCEPT_REPORTER_ADDRESS ) . as_str ( ) ) ;
56+ // Create a new reporter
57+ let reporter = TcpReporter :: new ( reporter_address)
58+ . expect ( "Cannot create reporter" ) ;
59+
60+ // Report the execution
61+ let execution = intercept:: Event :: Started {
62+ pid : intercept:: ProcessId ( std:: process:: id ( ) as u32 ) ,
63+ ppid : intercept:: ProcessId ( std:: os:: unix:: process:: parent_id ( ) as u32 ) , // FIXME: This is Unix specific
64+ execution : intercept:: Execution {
65+ executable : path_buf. clone ( ) ,
66+ arguments : std:: env:: args ( ) . collect ( ) ,
67+ working_dir : std:: env:: current_dir ( ) . expect ( "Cannot get current directory" ) ,
68+ environment : std:: env:: vars ( ) . collect ( ) ,
69+ } ,
70+ } ;
71+ reporter. report ( execution)
72+ . expect ( "Cannot report execution" ) ;
2673}
74+
75+ // declare a const string for the INTERCEPT_REPORTER_ADDRESS environment name
76+ const INTERCEPT_REPORTER_ADDRESS : & str = "INTERCEPT_REPORTER_ADDRESS" ;
0 commit comments