#include "stdinclude.h" #include "common.h" #include "command.h" #include "ficsmain.h" #include "network.h" #include "playerdb.h" #include "shutdown.h" #include "utils.h" PRIVATE int shutdownTime = 0; PRIVATE int lastTimeLeft; PRIVATE int shutdownStartTime; PRIVATE char downer[1024]; PRIVATE char reason[1024]; PUBLIC void output_shut_mess() { time_t shuttime = time(NULL); fprintf(stderr, "FICS: Shutting down at %s\n", strltime(&shuttime)); } PUBLIC 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 t = time(0); int p1; int timeLeft; int crossing = 0; 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(); } } PUBLIC int check_and_print_shutdown(int p) /* Tells a user if they is to be a shutdown */ /* returns 0 if there is not to be one, 1 if there is to be one */ /* for whenshut command */ { int timeLeft; int t = time(0); if (!shutdownTime) return 0; /* no shut down */ 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; } /* * shutdown * * Usage: shutdown [now,cancel,time] * * This command shutsdown 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); strcpy(downer, parray[p].name); shutdownStartTime = time(0); 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) strcpy (reason,param[1].val.string); 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 %d minutes and %d seconds. ****\n", shutdownTime / 60, 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) { int p1; if (shutdownTime && (shutdownTime <= secs)) { /* Server is already shutting down, I'll let it go */ return 0; } strcpy(downer, "Automatic"); shutdownTime = secs; shutdownStartTime = time(0); for (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 %d minutes and %d seconds. ****\n\n", shutdownTime / 60, 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) { int result = check_and_print_shutdown(p); if (result == 0) { pprintf (p,"No shutdown currently in progress\n"); } return COM_OK; }