#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <errno.h>
#include <err.h>
#include <syd.h>
#define PORT 65432
#define BUFFER_SIZE 1024
int main()
{
int server_fd, new_socket;
struct sockaddr_in address;
int r, opt = 1;
int addrlen = sizeof(address);
char buffer[BUFFER_SIZE] = {0};
bool should_quit = false;
char *sh = realpath("/bin/busybox", NULL);
if (!sh) {
err(1, "Failed to determine real path to /bin/busybox");
}
if ((r = syd_check()) != 0) {
errno = -r;
err(1, "Not running under syd");
}
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
err(1, "socket failed");
}
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt,
sizeof(opt))) {
err(1, "setsockopt");
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
address.sin_port = htons(PORT);
if ((r = syd_allow_net_bind_add("LOOPBACK!65432")) != 0) {
errno = -r;
err(1, "Failed to allow LOOPBACK!65432");
}
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
err(1, "bind failed");
}
if ((r = syd_allow_net_bind_del("LOOPBACK!65432")) != 0) {
errno = -r;
err(1, "Failed to allow LOOPBACK!65432");
}
if ((r = syd_allow_exec_add(sh)) != 0) {
errno = -r;
err(1, "Failed to allow %s for exec", sh);
}
if ((r = syd_allow_stat_add(sh)) != 0) {
errno = -r;
err(1, "Failed to allow %s for stat", sh);
}
if ((r = syd_lock(LOCK_ON)) != 0) {
errno = -r;
err(1, "Failed to lock syd");
}
if (listen(server_fd, 3) < 0) {
err(1, "listen");
}
for (;;) {
printf("*** Waiting for a connection...\n");
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t *)&addrlen)) < 0) {
err(1, "accept");
}
printf("*** Connection established\n");
ssize_t read_bytes;
while ((read_bytes = read(new_socket, buffer, BUFFER_SIZE - 1)) > 0) {
buffer[read_bytes] = '\0';
if (strncmp(buffer, "QUIT", 4) == 0) {
printf("Received 'QUIT', exiting.\n");
should_quit = 1; break;
}
FILE *fp;
char command_output[BUFFER_SIZE];
char command[BUFFER_SIZE + 10];
snprintf(command, sizeof(command), "/bin/busybox sh -c \"%s\" 2>&1", buffer);
fp = popen(command, "r");
if (fp == NULL) {
printf("Failed to run command\n");
continue;
}
while (fgets(command_output, sizeof(command_output), fp) != NULL) {
write(new_socket, command_output, strlen(command_output));
}
pclose(fp);
memset(buffer, 0, BUFFER_SIZE); }
if (read_bytes < 0) {
err(1, "read");
}
close(new_socket);
printf("Connection closed\n");
if (should_quit) {
break; }
}
printf("*** Shutting down server.\n");
close(server_fd);
return 0;
}