78 lines
2.0 KiB
C
78 lines
2.0 KiB
C
// gcc fastfetch_server.c -o fastfetch_server
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
|
|
#define BUFFER_SIZE 0x10000
|
|
|
|
void handle_client(int client_fd) {
|
|
char output[BUFFER_SIZE];
|
|
|
|
FILE *fp = popen("fastfetch --pipe false 2>/dev/null", "r");
|
|
size_t n = fp ? fread(output, 1, BUFFER_SIZE - 1, fp) : 0;
|
|
if (fp) pclose(fp);
|
|
output[n] = '\0';
|
|
|
|
dprintf(client_fd,
|
|
"HTTP/1.1 200 OK\r\n"
|
|
"Content-Type: text/plain\r\n"
|
|
"Content-Length: %zu\r\n"
|
|
"Connection: close\r\n"
|
|
"\r\n"
|
|
"%s",
|
|
n, output);
|
|
|
|
shutdown(client_fd, SHUT_WR);
|
|
|
|
char discard[1024];
|
|
while (recv(client_fd, discard, sizeof(discard), 0) > 0) {}
|
|
|
|
close(client_fd);
|
|
exit(0);
|
|
}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
const int port = argc > 1 ? atoi(argv[1]) : 80;
|
|
|
|
const int server_fd = socket(AF_INET6, SOCK_STREAM, 0);
|
|
if (server_fd < 0) return perror("socket"), 1;
|
|
|
|
int opt = 0;
|
|
setsockopt(server_fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt));
|
|
opt = 1;
|
|
setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
|
|
|
|
const struct sockaddr_in6 addr = {
|
|
.sin6_family = AF_INET6,
|
|
.sin6_addr = in6addr_any,
|
|
.sin6_port = htons(port)
|
|
};
|
|
|
|
if (bind(server_fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) return perror("bind"), 1;
|
|
if (listen(server_fd, 128) < 0) return perror("listen"), 1;
|
|
|
|
printf("listening on port %d\n", port);
|
|
|
|
for (;;) {
|
|
struct sockaddr_in6 client_addr;
|
|
socklen_t addrlen = sizeof(client_addr);
|
|
int client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &addrlen);
|
|
|
|
if (client_fd < 0) continue;
|
|
|
|
pid_t pid = fork();
|
|
if (pid == 0) {
|
|
close(server_fd);
|
|
handle_client(client_fd);
|
|
}
|
|
else if (pid > 0) {
|
|
close(client_fd);
|
|
}
|
|
else {
|
|
perror("fork");
|
|
close(client_fd);
|
|
}
|
|
}
|
|
} |