diff options
Diffstat (limited to 'FICS/shutdown.c')
-rw-r--r-- | FICS/shutdown.c | 311 |
1 files changed, 311 insertions, 0 deletions
diff --git a/FICS/shutdown.c b/FICS/shutdown.c new file mode 100644 index 0000000..6e765ed --- /dev/null +++ b/FICS/shutdown.c @@ -0,0 +1,311 @@ +/* + * Revised by maxxe <maxxe@rpblc.net>, + * 18 Dec 2023. + */ + +#include "stdinclude.h" +#include "common.h" + +#include "command.h" +#include "network.h" +#include "playerdb.h" +#include "shutdown.h" +#include "utils.h" + +#if __linux__ +#include <bsd/string.h> +#endif + +PRIVATE char downer[1024]; +PRIVATE char reason[1024]; + +PRIVATE time_t lastTimeLeft; +PRIVATE time_t shutdownStartTime; +PRIVATE time_t shutdownTime = 0; + +PUBLIC void +output_shut_mess(void) +{ + time_t shuttime = time(NULL); + + fprintf(stderr, "FICS: Shutting down at %s\n", strltime(&shuttime)); +} + +PUBLIC __dead void +ShutDown(void) +{ + time_t shuttime = time(NULL); + + for (int p1 = 0; p1 < p_num; p1++) { + if (parray[p1].status != PLAYER_PROMPT) + continue; + + pprintf(p1, "\n\n **** Server shutdown ordered by %s. " + "****\n", downer); + + if (reason[0] != '\0') { + pprintf(p1, "\n **** We are going down because: " + "%s. ****\n", reason); + } + } + + TerminateCleanup(); + fprintf(stderr, "FICS: Shut down ordered at %s by %s.\n", + strltime(&shuttime), downer); + output_shut_mess(); + net_close(); + exit(0); +} + +PUBLIC void +ShutHeartBeat(void) +{ + int crossing = 0; + int p1; + int timeLeft; + time_t t = time(NULL); + + if (!shutdownTime) + return; + if (!lastTimeLeft) + lastTimeLeft = shutdownTime; + + timeLeft = shutdownTime - (t - shutdownStartTime); + + if (lastTimeLeft > 3600 && timeLeft <= 3600) + crossing = 1; + if (lastTimeLeft > 2400 && timeLeft <= 2400) + crossing = 1; + if (lastTimeLeft > 1200 && timeLeft <= 1200) + crossing = 1; + if (lastTimeLeft > 600 && timeLeft <= 600) + crossing = 1; + if (lastTimeLeft > 300 && timeLeft <= 300) + crossing = 1; + if (lastTimeLeft > 120 && timeLeft <= 120) + crossing = 1; + if (lastTimeLeft > 60 && timeLeft <= 60) + crossing = 1; + if (lastTimeLeft > 10 && timeLeft <= 10) + crossing = 1; + + if (crossing) { + fprintf(stderr, "FICS: **** Server going down in %d minutes " + "and %d seconds. ****\n\n", + (timeLeft / 60), + timeLeft - ((timeLeft / 60) * 60)); + + if (reason[0] != '\0') { + fprintf(stderr,"FICS: We are going down because: %s.\n", + reason); + } + + for (p1 = 0; p1 < p_num; p1++) { + if (parray[p1].status != PLAYER_PROMPT) + continue; + + pprintf(p1, "\n\n **** Server going down in %d " + "minutes and %d seconds. ****\n", + (timeLeft / 60), + timeLeft - ((timeLeft / 60) * 60)); + + if (reason[0] != '\0') { + pprintf_prompt(p1, "\n **** We are going " + "down because: %s. ****\n", reason); + } else + pprintf_prompt(p1, "\n"); + } + } + + lastTimeLeft = timeLeft; + + if (timeLeft <= 0) + ShutDown(); +} + +/* + * Tells a user about a shutdown. Returns 1 if there is to be one, and + * 0 otherwise. (For 'whenshut' command.) + */ +PUBLIC int +check_and_print_shutdown(int p) +{ + int timeLeft; + time_t t = time(NULL); + + if (!shutdownTime) + return 0; // no shutdown + + timeLeft = shutdownTime - (t - shutdownStartTime); + + pprintf(p, "\n **** Server going down in %d minutes and %d seconds. " + "****\n", + (timeLeft / 60), + timeLeft - ((timeLeft / 60) * 60)); + + if (reason[0] != '\0') { + pprintf(p, "\n **** We are going down because: %s. ****\n", + reason); + } + return 1; +} + + +/* + * Usage: shutdown [now,cancel,time] + * + * This command shuts down the server. If the parameter is omitted or + * is 'now' then the server is immediately halted cleanly. If a time + * is given then a countdown commences and the server is halted when + * time is up. If 'cancel' is given then the countdown is stopped. + */ +PUBLIC int +com_shutdown(int p, param_list param) +{ + char *ptr; + int p1, secs; + + ASSERT(parray[p].adminLevel >= ADMIN_ADMIN); + strlcpy(downer, parray[p].name, sizeof downer); + shutdownStartTime = time(NULL); + + if (shutdownTime) { // Cancel any pending shutdowns + for (p1 = 0; p1 < p_num; p1++) { + if (parray[p1].status != PLAYER_PROMPT) + continue; + pprintf(p1, "\n\n **** Server shutdown canceled by " + "%s. ****\n", downer); + } + + shutdownTime = 0; + + if (param[0].type == TYPE_NULL) + return COM_OK; + } + + /* + * Work out how soon to shut down + */ + if (param[0].type == TYPE_NULL) { + shutdownTime = 300; + } else { + if (!strcmp(param[0].val.word, "now")) { + shutdownTime = 0; + } else if (!strcmp(param[0].val.word, "die")) { + fprintf(stderr,"%s salutes FICS and presses the " + "self-destruct button.\n", parray[p].name); + output_shut_mess(); + abort(); + } else if (!strcmp(param[0].val.word, "cancel")) { + return COM_OK; + } else { + ptr = param[0].val.word; + shutdownTime = secs = 0; + p1 = 2; + + while (*ptr) { + switch (*ptr) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + secs = (secs * 10 + *ptr - '0'); + break; + case ':': + if (p1--) { + shutdownTime = (shutdownTime * + 60 + secs); + secs = 0; + break; + } + default: + shutdownTime = 0; + pprintf(p, "I don't know what you mean " + "by %s\n", param[0].val.word); + return COM_OK; + } + + ptr++; + } + + shutdownTime = (shutdownTime * 60 + secs); + } + } + + if (shutdownTime <= 0) + ShutDown(); + if (param[1].type == TYPE_STRING) + strlcpy(reason, param[1].val.string, sizeof reason); + else + reason[0] = '\0'; // No reason - perhaps admin is in a + // bad mood? :) + + for (p1 = 0; p1 < p_num; p1++) { + if (parray[p1].status != PLAYER_PROMPT) + continue; + + pprintf(p1, "\n\n **** Server shutdown ordered by %s. " + "****\n", downer); + + if (reason[0] != '\0') { + pprintf(p1, " **** We are going down because: " + "%s. ****\n", reason); + } + + pprintf(p1, " **** Server going down in %ld minutes and %ld " + "seconds. ****\n", + (long int)(shutdownTime / 60), + (long int)(shutdownTime % 60)); + if (p != p1) // fix double prompt - DAV + pprintf_prompt(p1, "\n"); + else + pprintf(p1, "\n"); + } + + lastTimeLeft = 0; + return COM_OK; +} + +PUBLIC int +server_shutdown(int secs, char *why) +{ + if (shutdownTime && shutdownTime <= secs) { + /* + * Server is already shutting down + */ + return 0; + } + + strlcpy(downer, "Automatic", sizeof downer); + shutdownTime = secs; + shutdownStartTime = time(NULL); + + for (int p1 = 0; p1 < p_num; p1++) { + if (parray[p1].status != PLAYER_PROMPT) + continue; + pprintf(p1, "\n\n **** Automatic Server shutdown. ****\n"); + pprintf(p1, "%s\n", why); + pprintf_prompt(p1, " **** Server going down in %ld minutes " + "and %ld seconds. ****\n\n", + (long int)(shutdownTime / 60), + (long int)(shutdownTime - ((shutdownTime / 60) * 60))); + } + + fprintf(stderr, "FICS: **** Automatic Server shutdown. ****\n"); + fprintf(stderr, "FICS: %s\n", why); + return 0; +} + +PUBLIC int +com_whenshut(int p, param_list param) +{ + if (check_and_print_shutdown(p) == 0) + pprintf(p, "No shutdown currently in progress\n"); + return COM_OK; +} |