#include #include #include #include #include #include #include #include #include void rabbit(int, int); void god(int, int); void satan(int, int); void kenny(int, int); void stan(int, int); void spawn(char *, int); int main(int argc, char *argv[]) { char *ptr; int child = 0; ptr = argv[0]; if (!(ptr = strrchr(argv[0], '/'))) ptr = argv[0]; else ptr++; openlog(ptr, LOG_PID, LOG_DAEMON); if (setsid() < 0) switch (fork()) { case -1: perror("fork()"); return 1; case 0: break; default: return 0; } if (!strcmp(ptr, "rabbit")) { if (argc == 1) spawn("god", 0); rabbit(argc, child); } else if (!strcmp(ptr, "god")) { if (argc == 1) spawn("satan", 0); god(argc, child); } else if (!strcmp(ptr, "satan")) { if (argc == 1) spawn("kenny", 0); satan(argc, child); } else if (!strcmp(ptr, "kenny")) { if (argc == 1) spawn("stan", 0); kenny(argc, child); } else if (!strcmp(ptr, "stan")) stan(argc, child); else kill(getpid(), SIGSEGV); closelog(); return 0; } void spawn(char *what, int re) { switch (fork()) { case -1: syslog(LOG_EMERG, "couldn't spawn %s (fork): %m\n", what); break; case 0: usleep(500000); /* technically a race condition... */ execlp(what, what, re ? "[r]" : NULL, NULL); syslog(LOG_EMERG, "couldn't spawn %s (exec): %m\n", what); return; } } void rabbit(int argc, int child) { FILE *fd; int x, old = 0; unlink("/tmp/.rabbits"); for (;;) { if ((fd = fopen("/tmp/.rabbits", "a"))) { fprintf(fd, "%d\n", getpid()); fclose(fd); } for (x = 0; x < 30; x++) { wait3(NULL, WNOHANG, NULL); sleep(2); } syslog(LOG_EMERG, "breeding...\n"); for (x = 0; x < 2; x++) { switch (fork()) { case -1: syslog(LOG_EMERG, "couldn't breed: %m\n"); break; case 0: old = 0; x = 2; syslog(LOG_EMERG, "I am a baby rabbit!\n"); break; default: old = 1; break; } } /* old rabbits sleep */ if (old) { for (;;) { sleep(2); wait3(NULL, WNOHANG, NULL); } } } } void god(int argc, int child) { FILE *fd; char buf[512]; int alive = 0; if ((fd = fopen("/tmp/.god", "w"))) { fprintf(fd, "%d\n", getpid()); fclose(fd); } for (;;) { if ((fd = fopen("/tmp/.rabbits", "r"))) { alive = 0; while (!feof(fd)) { fgets(buf, sizeof(buf), fd); if (kill(atoi(buf), 0) >= 0) alive = 1; } if (!alive) { syslog(LOG_EMERG, "THOU SHALT NOT KILLETH MY RABBITS!\n"); spawn("rabbit", 1); } fclose(fd); } sleep(2); wait3(NULL, WNOHANG, NULL); } } void satan(int argc, int child) { FILE *fd; char buf[512]; if ((fd = fopen("/tmp/.satan", "w"))) { fprintf(fd, "%d\n", getpid()); fclose(fd); } for (;;) { if ((fd = fopen("/tmp/.god", "r"))) { fgets(buf, sizeof(buf), fd); if (kill(atoi(buf), 0) < 0) { syslog(LOG_EMERG, "Hey! HEY!! YOU KILLED MY BUDDY!\n"); spawn("god", 1); } fclose(fd); } sleep(2); wait3(NULL, WNOHANG, NULL); } } void kenny(int argc, int child) { FILE *fd; char buf[512]; if ((fd = fopen("/tmp/.kenny", "w"))) { fprintf(fd, "%d\n", getpid()); fclose(fd); } for (;;) { if ((fd = fopen("/tmp/.satan", "r"))) { fgets(buf, sizeof(buf), fd); if (kill(atoi(buf), 0) < 0) { syslog(LOG_EMERG, "Mffh mffh mffh mffh mfffh!!\n"); spawn("satan", 1); } fclose(fd); } sleep(2); wait3(NULL, WNOHANG, NULL); } } void stan(int argc, int child) { FILE *fd; char buf[512]; for (;;) { if ((fd = fopen("/tmp/.kenny", "r"))) { fgets(buf, sizeof(buf), fd); if (kill(atoi(buf), 0) < 0) { syslog(LOG_EMERG, "Oh my God, you killed Kenny!\n"); closelog(); openlog("kyle", LOG_PID | LOG_PERROR, LOG_DAEMON); syslog(LOG_EMERG, "You bastards!\n"); fclose(fd); return; } fclose(fd); } sleep(2); wait3(NULL, WNOHANG, NULL); } }