1use std::os::unix::net::{UnixListener, UnixStream};
4use std::io::{Read, Write};
5use std::process::Command;
6use serde_json::Value;
7use rand::{thread_rng, Rng};
8use rand::distributions::Alphanumeric;
9
10use crate::error::{GuiError, Result};
11
12pub fn generate_random_address() -> String {
14 thread_rng()
15 .sample_iter(&Alphanumeric)
16 .take(50)
17 .map(char::from)
18 .collect()
19}
20
21pub fn bind_abstract_socket(name: &str) -> Result<UnixListener> {
23 unsafe {
24 use std::os::unix::io::FromRawFd;
25
26 let fd = libc::socket(libc::AF_UNIX, libc::SOCK_STREAM, 0);
27 if fd < 0 {
28 return Err(GuiError::Io(std::io::Error::last_os_error()));
29 }
30
31 let mut addr_bytes = vec![0u8];
32 addr_bytes.extend_from_slice(name.as_bytes());
33
34 let mut addr: libc::sockaddr_un = std::mem::zeroed();
35 addr.sun_family = libc::AF_UNIX as u16;
36 for (i, &byte) in addr_bytes.iter().enumerate() {
37 addr.sun_path[i] = byte as _;
38 }
39
40 let addr_len = (std::mem::size_of::<libc::sa_family_t>() + addr_bytes.len()) as libc::socklen_t;
41
42 if libc::bind(fd, &addr as *const _ as *const libc::sockaddr, addr_len) < 0 {
43 libc::close(fd);
44 return Err(GuiError::SocketBind(format!("bind failed for {}", name)));
45 }
46
47 if libc::listen(fd, 1) < 0 {
48 libc::close(fd);
49 return Err(GuiError::SocketBind(format!("listen failed for {}", name)));
50 }
51
52 Ok(UnixListener::from_raw_fd(fd))
53 }
54}
55
56pub fn send_message(stream: &mut UnixStream, msg: &Value) -> Result<()> {
58 let json_bytes = msg.to_string().into_bytes();
59 stream.write_all(&(json_bytes.len() as u32).to_be_bytes())?;
60 stream.write_all(&json_bytes)?;
61 stream.flush()?;
62 Ok(())
63}
64
65pub fn read_message(stream: &mut UnixStream) -> Result<Value> {
67 let mut len_buf = [0u8; 4];
68 stream.read_exact(&mut len_buf)?;
69 let len = u32::from_be_bytes(len_buf) as usize;
70
71 let mut buf = vec![0u8; len];
72 stream.read_exact(&mut buf)?;
73
74 let value = serde_json::from_slice(&buf)?;
75 Ok(value)
76}
77
78pub fn send_and_read(stream: &mut UnixStream, msg: &Value) -> Result<Value> {
80 eprintln!("[DEBUG] send_and_read: sending...");
81 send_message(stream, msg)?;
82 eprintln!("[DEBUG] send_and_read: reading response...");
83 let response = read_message(stream)?;
84 eprintln!("[DEBUG] send_and_read: got response!");
85 Ok(response)
86}
87
88pub struct Connection {
90 pub main_stream: UnixStream,
91 pub event_stream: UnixStream,
92}
93
94impl Connection {
95 pub fn new() -> Result<Self> {
97 eprintln!("[DEBUG] Generating addresses...");
98 let addr_main = generate_random_address();
99 let addr_event = generate_random_address();
100
101 eprintln!("[DEBUG] Binding sockets...");
102 let main_listener = bind_abstract_socket(&addr_main)?;
103 let event_listener = bind_abstract_socket(&addr_event)?;
104
105 eprintln!("[DEBUG] Sending broadcast...");
106 let output = Command::new("termux-am")
108 .args(&[
109 "broadcast",
110 "-n",
111 "com.termux.gui/.GUIReceiver",
112 "--es",
113 "mainSocket",
114 &addr_main,
115 "--es",
116 "eventSocket",
117 &addr_event,
118 ])
119 .output();
120
121 match output {
122 Ok(out) if !out.status.success() => {
123 eprintln!("[DEBUG] termux-am failed, trying am...");
124 Command::new("am")
125 .args(&[
126 "broadcast",
127 "-n",
128 "com.termux.gui/.GUIReceiver",
129 "--es",
130 "mainSocket",
131 &addr_main,
132 "--es",
133 "eventSocket",
134 &addr_event,
135 ])
136 .output()
137 .map_err(|_| GuiError::ConnectionFailed)?;
138 }
139 Err(_) => {
140 eprintln!("[DEBUG] termux-am not found, trying am...");
141 Command::new("am")
142 .args(&[
143 "broadcast",
144 "-n",
145 "com.termux.gui/.GUIReceiver",
146 "--es",
147 "mainSocket",
148 &addr_main,
149 "--es",
150 "eventSocket",
151 &addr_event,
152 ])
153 .output()
154 .map_err(|_| GuiError::ConnectionFailed)?;
155 }
156 _ => {}
157 }
158
159 eprintln!("[DEBUG] Accepting connections...");
160 let (mut main_stream, _) = main_listener.accept()?;
161 let (event_stream, _) = event_listener.accept()?;
162
163 eprintln!("[DEBUG] Handshake...");
164 main_stream.write_all(&[0x01])?;
166 main_stream.read_exact(&mut [0u8; 1])?;
167
168 eprintln!("[DEBUG] Connection established!");
169 Ok(Connection {
170 main_stream,
171 event_stream,
172 })
173 }
174
175 pub fn send(&mut self, msg: &Value) -> Result<()> {
177 send_message(&mut self.main_stream, msg)
178 }
179
180 pub fn send_read(&mut self, msg: &Value) -> Result<Value> {
182 send_and_read(&mut self.main_stream, msg)
183 }
184
185 pub fn event_stream(&mut self) -> &mut UnixStream {
187 &mut self.event_stream
188 }
189}