#include #include #include #include #include #include #include #include #include #include #include #include "config.h" #include #include #define buf_size 2048 /* chat-loop / main.c. sends text to vrchat using osc. Copyright (C) 2026 iceyrazor This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ static volatile sig_atomic_t keepRunning = true; // handle Ctrl+C static void sigintHandler(int x) { keepRunning = false; } // execute command and put output into ret_buf buffer int execlb(const char* cmd, char* buffer, size_t buffer_size) { int link[2]; pid_t pid; int status; if (pipe(link) == -1) exit(-5); if ((pid = fork()) == -1) exit(-5); if (pid == 0) { dup2(link[1], STDOUT_FILENO); close(link[0]); close(link[1]); execl("/bin/sh", "sh", "-c", cmd, (char*)0); _exit(127); } else { close(link[1]); int nbytes = read(link[0], buffer, buffer_size - 1); buffer[nbytes] = '\0'; waitpid(pid,&status,0); close(link[0]); return status; } } int main() { char wbuffer[2048] = {0}; // declare a 2Kb buffer to read packet data into int port = 9000; struct sockaddr_in servaddr; int socketfd = socket(AF_INET, SOCK_DGRAM, 0); if (socketfd < 0) { perror("ERROR:"); return -1; } servaddr.sin_family = AF_INET; // IPv4 servaddr.sin_port = htons(port); // Server port servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // Server IP // register the SIGINT handler (Ctrl+C) signal(SIGINT, sigintHandler); char dist[2048] = {0}; int status=execlb("uname -r", dist, sizeof dist); if (status != 0){ fprintf(stderr,"ERROR WITH execlb %d", status); exit(1); } dist[strcspn(dist,"\n")] = '\0'; char comb_string[2048] = {0}; char song_title[2048] = {0}; size_t i = 0; while (keepRunning) { int song_status=execlb("src/title.sh", song_title, sizeof song_title); if (song_status != 0){ fprintf(stderr,"ERROR WITH execlb %d", status); exit(1); } snprintf(comb_string, sizeof comb_string, "%s\nLinux %s\n%s\n%s", title, dist, arr[i], song_title); uint32_t len = tosc_writeMessage(wbuffer, sizeof(wbuffer), "/chatbox/input", "sTF", comb_string); sendto(socketfd, wbuffer, len, MSG_CONFIRM, (const struct sockaddr*)&servaddr, sizeof(servaddr)); sleep(3); i = (i + 1) % (sizeof arr / sizeof arr[0]); } // remove till end if you dont care about sending a clear to chat box when stopping the program. usleep(900000); // if 2 messages are sent to quickly. this one doesnt send. so this seems like a good delay on my machine. comment out if you dont care uint32_t len = tosc_writeMessage(wbuffer, sizeof(wbuffer), "/chatbox/input", "sTF", ""); sendto(socketfd, wbuffer, len, MSG_CONFIRM, (const struct sockaddr*)&servaddr, sizeof(servaddr)); // end return 0; }