tmhd/tmhd.c
Slendi ed9c760920
Change trigger time.
Signed-off-by: Slendi <slendi@socopon.com>
2023-09-09 14:41:10 +03:00

161 lines
3.3 KiB
C

// Two Minutes Hate Daemon (tmhd) for Linux systems.
//
// Runs as a daemon. Everyday, at a programmed time, CPU goes to 100% and the
// computer starts hating processes running on the system.
#define HOUR 14
#define MINUTE 30
#define DELAY 5
#include <ctype.h>
#include <dirent.h>
#include <pthread.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/sysinfo.h>
#include <time.h>
#include <unistd.h>
#include <libnotify/notify.h>
#define MESSAGES_LEN 8
static char const *MESSAGES[MESSAGES_LEN] = {
"I fucking hate %s!",
"%s fucking sucks!",
"Down with %s!",
"Boo! Boo!",
"AAAAAAAAAAAAAAAAAAA",
"%s should cease to exist!",
"%s was programmed by a retard!",
"The pinacle of stupidity is %s!",
};
bool program_running = true;
bool hogging_cpu = false;
void *cpu_hog_thread(void *_)
{
while (program_running)
if (!hogging_cpu) usleep(0);
return NULL;
}
bool is_numeric(const char *str)
{
for (int i = 0; str[i] != '\0'; i++)
if (!isdigit(str[i])) return false;
return true;
}
bool has_slash(char *str)
{
for (char *ptr = str; *ptr != '\0'; ptr++)
if (*ptr == '/') return true;
return false;
}
char process_name_buf[256];
char *get_random_process_name()
{
DIR *dir;
struct dirent *entry;
dir = opendir("/proc");
if (dir == NULL) {
perror("opendir");
return NULL;
}
srand(time(NULL));
int num_proc = 0;
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR && is_numeric(entry->d_name)
&& atoi(entry->d_name) != 0) {
num_proc++;
}
}
closedir(dir);
dir = opendir("/proc");
if (dir == NULL) {
perror("opendir");
return NULL;
}
int random_index = rand() % num_proc;
int current_index = 0;
explicit_bzero(process_name_buf, sizeof(process_name_buf));
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR && is_numeric(entry->d_name)
&& atoi(entry->d_name) != 0) {
if (current_index == random_index) {
pid_t pid = atoi(entry->d_name);
char path[256];
snprintf(path, sizeof(path) - 1, "/proc/%d/status", pid);
FILE *fp = fopen(path, "r");
if (!fp) break;
fscanf(fp, "Name:\t%s\n", process_name_buf);
fclose(fp);
if (has_slash(process_name_buf)) {
closedir(dir);
return get_random_process_name();
}
break;
}
current_index++;
}
}
closedir(dir);
return process_name_buf;
}
void do_hate()
{
hogging_cpu = true;
NotifyNotification *n;
for (unsigned i = 0; i < 60 * 2 && program_running; i += DELAY) {
char hate_msg[256];
snprintf(hate_msg, sizeof(hate_msg), MESSAGES[rand() % MESSAGES_LEN],
get_random_process_name());
n = notify_notification_new("AAAAAAAAAAAAAAAAAAAAAAA", hate_msg, NULL);
notify_notification_show(n, NULL);
sleep(DELAY);
}
hogging_cpu = false;
}
void int_handler(int _)
{
program_running = false;
}
int main(void)
{
puts("Starting daemon.");
srand(time(NULL));
signal(SIGINT, int_handler);
signal(SIGTERM, int_handler);
pthread_t thread;
int procs = get_nprocs();
while (procs--)
pthread_create(&thread, NULL, cpu_hog_thread, NULL);
notify_init("tmhd");
while (program_running) {
time_t rawtime;
struct tm *timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
if (timeinfo->tm_hour == HOUR && timeinfo->tm_min == MINUTE) do_hate();
}
notify_uninit();
}