VulpesOS/tundra/probes/beatles-control-client.c
2026-10-22 20:42:26 +02:00

63 lines
2.1 KiB
C

/* SPDX-License-Identifier: MPL-2.0 */
/* Unprivileged one-request relay. The root broker still validates every command. */
#define _POSIX_C_SOURCE 200809L
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#define REQUEST_LIMIT 8192
#define RESPONSE_LIMIT 65536
static int write_all(int fd, const char *data, size_t size) {
while (size) {
ssize_t count=write(fd,data,size);
if (count<0 && errno==EINTR) continue;
if (count<=0) return -1;
data+=count;size-=(size_t)count;
}
return 0;
}
int main(int argc,char **argv) {
const char *path;
if (argc!=2) return 2;
if (!strcmp(argv[1],"--radio")) path="/work/phone-control.sock";
else if (!strcmp(argv[1],"--wifi")) path="/work/wifi-control.sock";
else return 2;
signal(SIGPIPE,SIG_IGN);
/* Bound the whole exchange, including a truncated stdin or an unresponsive broker. */
alarm(40);
char request[REQUEST_LIMIT+1];size_t used=0;
for (;;) {
ssize_t count=read(STDIN_FILENO,request+used,sizeof(request)-used);
if (count<0 && errno==EINTR) continue;
if (count<0) return 1;
if (!count) break;
used+=(size_t)count;
if (used>REQUEST_LIMIT) return 2;
}
if (!used || memchr(request,'\n',used) || memchr(request,'\r',used)) return 2;
int fd=socket(AF_UNIX,SOCK_STREAM,0);
if (fd<0) return 1;
struct sockaddr_un address={.sun_family=AF_UNIX};
memcpy(address.sun_path,path,strlen(path)+1);
if (connect(fd,(struct sockaddr *)&address,sizeof(address)) ||
write_all(fd,request,used) || write_all(fd,"\n",1)) {close(fd);return 1;}
char response[RESPONSE_LIMIT+1];used=0;
for (;;) {
ssize_t count=read(fd,response+used,sizeof(response)-used);
if (count<0 && errno==EINTR) continue;
if (count<=0) {close(fd);return 1;}
used+=(size_t)count;
if (used>RESPONSE_LIMIT) {close(fd);return 1;}
char *end=memchr(response,'\n',used);
if (end) {
int result=write_all(STDOUT_FILENO,response,(size_t)(end-response)+1);
close(fd);return result?1:0;
}
}
}