int Disconnected (Stream) { struct UserInfo * user = NULL; ChatCIRCUIT * conn; int n; char Msg[255]; int len; struct _EXCEPTION_POINTERS exinfo; for (n = 0; n <= NumberofChatStreams-1; n++) { conn=&ChatConnections[n]; if (Stream == conn->BPQStream) { if (conn->Active == FALSE) { return 0; } ChatClearQueue(conn); conn->Active = FALSE; RefreshMainWindow(); if (conn->Flags & CHATMODE) { if (conn->Flags & CHATLINK) { len=sprintf_s(Msg, sizeof(Msg), "Chat Node %s Disconnected", conn->u.link->call); WriteLogLine(conn, '|',Msg, len, LOG_CHAT); __try {link_drop(conn);} My__except_Routine("link_drop"); } else { len=sprintf_s(Msg, sizeof(Msg), "Chat User %s Disconnected", conn->Callsign); WriteLogLine(conn, '|',Msg, len, LOG_CHAT); __try { logout(conn); } #define EXCEPTMSG "logout" #include "StdExcept.c" } } conn->Flags = 0; conn->u.link = NULL; conn->UserPointer = NULL; return 0; }
void Logger::WriteLogLine(std::string LogLine) { WriteLogLine(LogLine, false); }
void ParseMemBus(void) { /*This function handles EVERYTHING passed to us via membus. It's truly vast.*/ #define BusDataIs(x) !strncmp(x, BusData, strlen(x)) char BusData[MEMBUS_MSGSIZE]; if (!BusRunning) return; if (!MemBus_Read(BusData, true)) { return; } /*If we got a signal over the membus.*/ if (BusDataIs(MEMBUS_CODE_RESET)) { if (ReloadConfig()) { MemBus_Write(MEMBUS_CODE_ACKNOWLEDGED " " MEMBUS_CODE_RESET, true); } else { MemBus_Write(MEMBUS_CODE_FAILURE " " MEMBUS_CODE_RESET, true); } } else if (BusDataIs(MEMBUS_CODE_OBJSTART) || BusDataIs(MEMBUS_CODE_OBJSTOP)) { unsigned LOffset = strlen((BusDataIs(MEMBUS_CODE_OBJSTART) ? MEMBUS_CODE_OBJSTART " " : MEMBUS_CODE_OBJSTOP " ")); char *TWorker = BusData + LOffset; ObjTable *CurObj = LookupObjectInTable(TWorker); char TmpBuf[MEMBUS_MSGSIZE], *MCode = MEMBUS_CODE_FAILURE; ReturnCode DidWork; if (LOffset >= strlen(BusData) || BusData[LOffset] == ' ') { /*No argument?*/ snprintf(TmpBuf, sizeof TmpBuf, "%s %s", MEMBUS_CODE_BADPARAM, BusData); MemBus_Write(TmpBuf, true); return; } if (CurObj) { /*If we ask to start a HaltCmdOnly command, run the stop command instead, because that's all that we use.*/ DidWork = ProcessConfigObject(CurObj, (BusDataIs(MEMBUS_CODE_OBJSTART) && !CurObj->Opts.HaltCmdOnly), false); snprintf(TmpBuf, sizeof TmpBuf, "Manual %s of object %s %s%s", (BusDataIs(MEMBUS_CODE_OBJSTART) ? "start" : "stop"), CurObj->ObjectID, (DidWork ? "succeeded" : "failed"), ((DidWork == WARNING) ? " with a warning" : "")); WriteLogLine(TmpBuf, true); } else { DidWork = FAILURE; } switch (DidWork) { case SUCCESS: MCode = MEMBUS_CODE_ACKNOWLEDGED; break; case WARNING: MCode = MEMBUS_CODE_WARNING; break; case FAILURE: MCode = MEMBUS_CODE_FAILURE; break; } snprintf(TmpBuf, sizeof TmpBuf, "%s %s %s", MCode, (BusDataIs(MEMBUS_CODE_OBJSTART) ? MEMBUS_CODE_OBJSTART : MEMBUS_CODE_OBJSTOP), TWorker); MemBus_Write(TmpBuf, true); } else if (BusDataIs(MEMBUS_CODE_CFMERGE) || BusDataIs(MEMBUS_CODE_CFUMERGE)) { const char *const MainCode = BusDataIs(MEMBUS_CODE_CFMERGE) ? MEMBUS_CODE_CFMERGE : MEMBUS_CODE_CFUMERGE; const char *MemBusReturnCode = NULL; const int LOffset = strlen(MainCode) + (sizeof " " - 1); const char *Filename = BusData + LOffset; switch (BusDataIs(MEMBUS_CODE_CFMERGE) ? MergeImportLine(Filename) : UnmergeImportLine(Filename)) { case SUCCESS: MemBusReturnCode = MEMBUS_CODE_ACKNOWLEDGED; break; case WARNING: MemBusReturnCode = MEMBUS_CODE_WARNING; break; default: MemBusReturnCode = MEMBUS_CODE_FAILURE; break; } char OutBuf[MEMBUS_MSGSIZE]; snprintf(OutBuf, sizeof OutBuf, "%s %s %s", MemBusReturnCode, MainCode, Filename); MemBus_Write(OutBuf, true); } else if (BusDataIs(MEMBUS_CODE_LSOBJS)) { /*Done for mostly third party stuff.*/ int Inc = 0; char OutBuf[MEMBUS_MSGSIZE]; unsigned char *BinWorker = (void*)OutBuf; ObjTable *Worker = ObjectTable; unsigned TPID = 0; const unsigned Length = strlen(MEMBUS_CODE_LSOBJS " " MEMBUS_LSOBJS_VERSION) + 1; for (; Worker->Next; Worker = Worker->Next) { const struct _RLTree *RLWorker = Worker->ObjectRunlevels; if (strlen(BusData) > strlen(MEMBUS_CODE_LSOBJS) && strcmp(BusData + strlen(MEMBUS_CODE_LSOBJS " "), Worker->ObjectID) != 0) { /*Allow for getting status of just one object.*/ continue; } if (!Worker->Opts.HasPIDFile || !(TPID = ReadPIDFile(Worker))) { TPID = Worker->ObjectPID; } /*We need a version for this protocol, because relevant options can change with updates. * Not all options are here, because some are not really useful.*/ strncpy(OutBuf, MEMBUS_CODE_LSOBJS " " MEMBUS_LSOBJS_VERSION, Length); BinWorker = (unsigned char*)OutBuf + Length; *BinWorker++ = (Worker->Started && !Worker->Opts.HaltCmdOnly); *BinWorker++ = ObjectProcessRunning(Worker); *BinWorker++ = Worker->Enabled; *BinWorker++ = Worker->TermSignal; *BinWorker++ = Worker->ReloadCommandSignal; memcpy(BinWorker, &Worker->UserID, sizeof(int)); memcpy((BinWorker += sizeof(int)), &Worker->GroupID, sizeof(int)); memcpy((BinWorker += sizeof(int)), &Worker->Opts.StopMode, sizeof(enum _StopMode)); memcpy((BinWorker += sizeof(enum _StopMode)), &TPID, sizeof(int)); memcpy((BinWorker += sizeof(int)), &Worker->StartedSince, sizeof(int)); memcpy(BinWorker + sizeof(int), &Worker->Opts.StopTimeout, sizeof(int)); MemBus_BinWrite(OutBuf, MEMBUS_MSGSIZE, true); snprintf(OutBuf, sizeof OutBuf, "%s %s", Worker->ObjectID, Worker->ObjectDescription); MemBus_Write(OutBuf, true); *OutBuf = '\0'; BinWorker = (void*)OutBuf; /*Write it over binary now.*/ if (Worker->Opts.RawDescription) *BinWorker++ = COPT_RAWDESCRIPTION; if (Worker->Opts.HaltCmdOnly) *BinWorker++ = COPT_HALTONLY; if (Worker->Opts.Persistent) *BinWorker++ = COPT_PERSISTENT; #ifndef NOMMU if (Worker->Opts.Fork) *BinWorker++ = COPT_FORK; if (Worker->Opts.ForkScanOnce) *BinWorker++ = COPT_FORKSCANONCE; #endif /*NOMMU*/ if (Worker->Opts.IsService) *BinWorker++ = COPT_SERVICE; if (Worker->Opts.AutoRestart) *BinWorker++ = COPT_AUTORESTART; if (Worker->Opts.ForceShell) *BinWorker++ = COPT_FORCESHELL; if (Worker->Opts.NoStopWait) *BinWorker++ = COPT_NOSTOPWAIT; if (Worker->Opts.Exec) *BinWorker++ = COPT_EXEC; if (Worker->Opts.PivotRoot) *BinWorker++ = COPT_PIVOTROOT; if (Worker->Opts.RunOnce) *BinWorker++ = COPT_RUNONCE; if (Worker->Opts.NoTrack) *BinWorker++ = COPT_NOTRACK; if (Worker->Opts.StartFailIsCritical) *BinWorker++ = COPT_STARTFAILCRITICAL; if (Worker->Opts.StopFailIsCritical) *BinWorker++ = COPT_STOPFAILCRITICAL; *BinWorker = 0; MemBus_BinWrite(OutBuf, MEMBUS_MSGSIZE, true); /*Now onto exit status mapping.*/ snprintf(OutBuf, sizeof OutBuf, MEMBUS_CODE_LSOBJS " MXS"); BinWorker = (void*)(OutBuf + sizeof MEMBUS_CODE_LSOBJS " MXS" + 1); for (Inc = 0; Worker->ExitStatuses[Inc].Value != 3 && Inc < sizeof Worker->ExitStatuses / sizeof Worker->ExitStatuses[0]; ++Inc) { /*Found one.*/ *BinWorker++ = Worker->ExitStatuses[Inc].Value; *BinWorker++ = Worker->ExitStatuses[Inc].ExitStatus; } BinWorker = (void*)(OutBuf + sizeof MEMBUS_CODE_LSOBJS " MXS"); *BinWorker = Inc; MemBus_BinWrite(OutBuf, MEMBUS_MSGSIZE, true); /**We know we're going to the runlevels now because we only send this one chunk before we ever do.**/ if (RLWorker) { for (; RLWorker->Next; RLWorker = RLWorker->Next) { /*Send all runlevels.*/ snprintf(OutBuf, sizeof OutBuf, "%s %s %s %s", MEMBUS_CODE_LSOBJS, MEMBUS_LSOBJS_VERSION, Worker->ObjectID, RLWorker->RL); MemBus_Write(OutBuf, true); } } } /*This says we are done.*/ MemBus_Write(MEMBUS_CODE_ACKNOWLEDGED " " MEMBUS_CODE_LSOBJS, true); return; } else if (BusDataIs(MEMBUS_CODE_GETRL)) { char TmpBuf[MEMBUS_MSGSIZE]; snprintf(TmpBuf, sizeof TmpBuf, MEMBUS_CODE_GETRL " %s", CurRunlevel); MemBus_Write(TmpBuf, true); } else if (BusDataIs(MEMBUS_CODE_OBJENABLE) || BusDataIs(MEMBUS_CODE_OBJDISABLE)) { Bool EnablingThis = (BusDataIs(MEMBUS_CODE_OBJENABLE) ? true : false); unsigned LOffset = strlen(EnablingThis ? MEMBUS_CODE_OBJENABLE " " : MEMBUS_CODE_OBJDISABLE " "); char *OurSignal = EnablingThis ? MEMBUS_CODE_OBJENABLE : MEMBUS_CODE_OBJDISABLE; char *TWorker = BusData + LOffset; ObjTable *CurObj = LookupObjectInTable(TWorker); char TmpBuf[MEMBUS_MSGSIZE]; ReturnCode DidWork = FAILURE; if (LOffset >= strlen(BusData) || BusData[LOffset] == ' ') { /*No argument?*/ snprintf(TmpBuf, sizeof TmpBuf, "%s %s", MEMBUS_CODE_BADPARAM, BusData); MemBus_Write(TmpBuf, true); return; } if (!CurObj) { snprintf(TmpBuf, sizeof TmpBuf, "%s %s %s", MEMBUS_CODE_FAILURE, OurSignal, TWorker); MemBus_Write(TmpBuf, true); return; } CurObj->Enabled = (EnablingThis ? true : false); DidWork = EditConfigValue(CurObj->ConfigFile, TWorker, "ObjectEnabled", EnablingThis ? "true" : "false"); switch (DidWork) { case SUCCESS: snprintf(TmpBuf, sizeof TmpBuf, "%s %s", MEMBUS_CODE_ACKNOWLEDGED, BusData); break; case WARNING: snprintf(TmpBuf, sizeof TmpBuf, "%s %s", MEMBUS_CODE_WARNING, BusData); break; case FAILURE: snprintf(TmpBuf, sizeof TmpBuf, "%s %s", MEMBUS_CODE_FAILURE, BusData); break; default: snprintf(TmpBuf, sizeof TmpBuf, "%s %s", MEMBUS_CODE_FAILURE, BusData); break; } MemBus_Write(TmpBuf, true); } else if (BusDataIs(MEMBUS_CODE_RUNLEVEL)) { unsigned LOffset = strlen(MEMBUS_CODE_RUNLEVEL " "); char *TWorker = BusData + LOffset; char TmpBuf[MEMBUS_MSGSIZE]; if (LOffset >= strlen(BusData) || BusData[LOffset] == ' ') { /*No argument?*/ snprintf(TmpBuf, sizeof TmpBuf, "%s %s", MEMBUS_CODE_BADPARAM, BusData); MemBus_Write(TmpBuf, true); return; } if (ObjRL_ValidRunlevel(TWorker)) { /*Tell them everything is OK, because we don't want to wait the whole time for the runlevel to start up.*/ snprintf(TmpBuf, sizeof TmpBuf, "%s %s %s", MEMBUS_CODE_ACKNOWLEDGED, MEMBUS_CODE_RUNLEVEL, TWorker); MemBus_Write(TmpBuf, true); } else { snprintf(TmpBuf, sizeof TmpBuf, "%s %s %s", MEMBUS_CODE_FAILURE, MEMBUS_CODE_RUNLEVEL, TWorker); MemBus_Write(TmpBuf, true); return; } snprintf(TmpBuf, sizeof TmpBuf, CONSOLE_COLOR_CYAN "Changing runlevel to \"%s\"...\n" CONSOLE_ENDCOLOR, TWorker); WriteLogLine(TmpBuf, true); printf("%s", TmpBuf); if (!SwitchRunlevels(TWorker)) /*Switch to it.*/ { char TmpBuf[1024]; snprintf(TmpBuf, sizeof TmpBuf, "Failed to switch to runlevel \"%s\".", TWorker); SpitError(TmpBuf); WriteLogLine(TmpBuf, true); } else { snprintf(TmpBuf, sizeof TmpBuf, CONSOLE_COLOR_GREEN "Switched to runlevel \"%s\"." CONSOLE_ENDCOLOR, TWorker); puts(TmpBuf); WriteLogLine(TmpBuf, true); } } else if (BusDataIs(MEMBUS_CODE_OBJRLS)) { char *Worker = NULL; char ObjectID[MAX_DESCRIPT_SIZE], SpecRunlevel[MAX_DESCRIPT_SIZE]; enum ObjRLS { OBJRLS_CHECK, OBJRLS_ADD, OBJRLS_DEL } Mode; int LOffset = 0, Inc = 0; char OutBuf[MEMBUS_MSGSIZE] = { '\0' }; ObjTable *CurObj = NULL; char *RunlevelText = NULL; unsigned RequiredRLTLength = 0; struct _RLTree *RLWorker = NULL; if (BusDataIs(MEMBUS_CODE_OBJRLS_CHECK)) LOffset = sizeof MEMBUS_CODE_OBJRLS_CHECK " " - 1, Mode = OBJRLS_CHECK; else if (BusDataIs(MEMBUS_CODE_OBJRLS_ADD)) LOffset = sizeof MEMBUS_CODE_OBJRLS_ADD " " - 1, Mode = OBJRLS_ADD; else if (BusDataIs(MEMBUS_CODE_OBJRLS_DEL)) LOffset = sizeof MEMBUS_CODE_OBJRLS_DEL " " - 1, Mode = OBJRLS_DEL; else return; Worker = BusData + LOffset; for (; Worker[Inc] != ' ' && Worker[Inc] != '\0' && Inc < sizeof ObjectID - 1; ++Inc) { /*Get the object ID.*/ ObjectID[Inc] = Worker[Inc]; } ObjectID[Inc] = '\0'; if ((Worker += Inc) == '\0') { /*Malformed.*/ snprintf(OutBuf, sizeof OutBuf, "%s %s", MEMBUS_CODE_BADPARAM, BusData); MemBus_Write(OutBuf, true); return; } ++Worker; /*Past the space.*/ for (Inc = 0; Worker[Inc] != '\0' && Inc < sizeof SpecRunlevel - 1; ++Inc) { /*Get the runlevel.*/ SpecRunlevel[Inc] = Worker[Inc]; } SpecRunlevel[Inc] = '\0'; if (!(CurObj = LookupObjectInTable(ObjectID))) { /*Object sent to us doesn't exist.*/ snprintf(OutBuf, sizeof OutBuf, "%s %s", MEMBUS_CODE_FAILURE, BusData); MemBus_Write(OutBuf, true); return; } /*Now process the commands.*/ switch (Mode) { case OBJRLS_CHECK: snprintf(OutBuf, sizeof OutBuf, MEMBUS_CODE_OBJRLS_CHECK " %s %s %d", ObjectID, SpecRunlevel, ObjRL_CheckRunlevel(SpecRunlevel, CurObj, true)); MemBus_Write(OutBuf, true); return; case OBJRLS_ADD: /*Add the runlevel in memory.*/ if (!ObjRL_CheckRunlevel(SpecRunlevel, CurObj, false)) { ObjRL_AddRunlevel(SpecRunlevel, CurObj); } else { snprintf(OutBuf, sizeof OutBuf, MEMBUS_CODE_FAILURE " %s", BusData); MemBus_Write(OutBuf, true); } break; case OBJRLS_DEL: if (!ObjRL_DelRunlevel(SpecRunlevel, CurObj)) { snprintf(OutBuf, sizeof OutBuf, "%s %s", MEMBUS_CODE_FAILURE, BusData); MemBus_Write(OutBuf, true); return; } break; default: break; } /*File editing. We already returned if we were just checking, so I won't handle that here.*/ if (CurObj->ObjectRunlevels) { for (RLWorker = CurObj->ObjectRunlevels; RLWorker->Next; RLWorker = RLWorker->Next) { RequiredRLTLength += strlen(RLWorker->RL) + 2; } ++RequiredRLTLength; /*For the null terminator.*/ *(RunlevelText = malloc(RequiredRLTLength)) = '\0'; /*I'm only going to say this once. * This is a Linux program. In Linux programs, most of the time, even if something is wrong, * malloc will NEVER return NULL. I will not dirty up my code with a hundred thousand * checks for a value that will never come to pass.*/ for (RLWorker = CurObj->ObjectRunlevels; RLWorker->Next; RLWorker = RLWorker->Next) { strncat(RunlevelText, RLWorker->RL, RequiredRLTLength - 1); strncat(RunlevelText, " ", 1); } /*Get rid of the space at the end.*/ RunlevelText[strlen(RunlevelText) - 1] = '\0'; } if (Mode == OBJRLS_ADD) { if (!EditConfigValue(CurObj->ConfigFile, CurObj->ObjectID, "ObjectRunlevels", RunlevelText)) { const int Length = MAX_LINE_SIZE + strlen(RunlevelText); char *TrickyBuf = malloc(Length); /*Special trick to attempt to add the ObjectRunlevels attribute.*/ snprintf(TrickyBuf, Length, "%s\n\tObjectRunlevels=%s", CurObj->Enabled ? "true" : "false", RunlevelText); if (!EditConfigValue(CurObj->ConfigFile, CurObj->ObjectID, "ObjectEnabled", TrickyBuf)) { /*Darn, we can't even do it the sneaky way!*/ free(TrickyBuf); free(RunlevelText); snprintf(OutBuf, sizeof OutBuf, MEMBUS_CODE_FAILURE " %s", BusData); MemBus_Write(OutBuf, true); return; } free(TrickyBuf); } } else { /*OBJRLS_DEL*/ /*Delete the line.*/ if (!EditConfigValue(CurObj->ConfigFile, CurObj->ObjectID, "ObjectRunlevels", CurObj->ObjectRunlevels ? RunlevelText : NULL)) { /*If we pass NULL to EditConfigValue(), it means we want to DELETE that line.*/ if (RunlevelText) free(RunlevelText); snprintf(OutBuf, sizeof OutBuf, MEMBUS_CODE_FAILURE " %s", BusData); MemBus_Write(OutBuf, true); return; } } if (RunlevelText) free(RunlevelText), RunlevelText = NULL; snprintf(OutBuf, sizeof OutBuf, MEMBUS_CODE_ACKNOWLEDGED " %s", BusData); MemBus_Write(OutBuf, true); return; } /*Power functions that close everything first.*/ else if (BusDataIs(MEMBUS_CODE_HALT) || BusDataIs(MEMBUS_CODE_POWEROFF) || BusDataIs(MEMBUS_CODE_REBOOT)) { unsigned LOffset = 0, Signal = OSCTL_REBOOT; char *TWorker = NULL, *MSig = NULL; char TmpBuf[MEMBUS_MSGSIZE]; if (BusDataIs(MEMBUS_CODE_HALT)) { LOffset = strlen(MEMBUS_CODE_HALT " "); Signal = OSCTL_HALT; MSig = MEMBUS_CODE_HALT; } else if (BusDataIs(MEMBUS_CODE_POWEROFF)) { LOffset = strlen(MEMBUS_CODE_POWEROFF " "); Signal = OSCTL_POWEROFF; MSig = MEMBUS_CODE_POWEROFF; } else if (BusDataIs(MEMBUS_CODE_REBOOT)) { LOffset = strlen(MEMBUS_CODE_REBOOT " "); Signal = OSCTL_REBOOT; MSig = MEMBUS_CODE_REBOOT; } TWorker = BusData + LOffset; if (LOffset >= strlen(BusData) || BusData[LOffset] == ' ') { /*No argument? Just do the action.*/ snprintf(TmpBuf, sizeof TmpBuf, "%s %s", MEMBUS_CODE_ACKNOWLEDGED, MSig); MemBus_Write(TmpBuf, true); while (!MemBus_Read(TmpBuf, true)) usleep(100); /*Wait to be told they received it.*/ LaunchShutdown(Signal); return; } if (strchr(TWorker, ':') && strchr(TWorker, '/')) { char MsgBuf[MAX_LINE_SIZE]; const char *HType = NULL; Bool H; Bool M; Bool S; if (HaltParams.HaltMode != -1) {/*Don't let us schedule two shutdowns.*/ snprintf(TmpBuf, sizeof TmpBuf, "%s %s", MEMBUS_CODE_FAILURE, BusData); MemBus_Write(TmpBuf, true); return; } if (sscanf(TWorker, "%u:%u:%u %u/%u/%u", &HaltParams.TargetHour, &HaltParams.TargetMin, &HaltParams.TargetSec, &HaltParams.TargetMonth, &HaltParams.TargetDay, &HaltParams.TargetYear) != 6) { SpitError("Invalid time signature for HALT/REBOOT/POWEROFF over membus.\n" "Please report to Epoch. This is probably a bug."); snprintf(TmpBuf, sizeof TmpBuf, "%s %s", MEMBUS_CODE_BADPARAM, BusData); MemBus_Write(TmpBuf, true); return; } H = HaltParams.TargetHour >= 10; M = HaltParams.TargetMin >= 10; S = HaltParams.TargetSec >= 10; ++HaltParams.JobID; HaltParams.HaltMode = Signal; snprintf(TmpBuf, sizeof TmpBuf, "%s %s", MEMBUS_CODE_ACKNOWLEDGED, BusData); MemBus_Write(TmpBuf, true); if (Signal == OSCTL_HALT) HType = "halt"; else if (Signal == OSCTL_POWEROFF) HType = "poweroff"; else if (Signal == OSCTL_REBOOT) HType = "reboot"; snprintf(MsgBuf, sizeof MsgBuf, "System is going down for %s at %s%u:%s%u:%s%u %u/%u/%u!", HType, H?"":"0", HaltParams.TargetHour, M?"":"0", HaltParams.TargetMin, S?"":"0", HaltParams.TargetSec, HaltParams.TargetMonth, HaltParams.TargetDay, HaltParams.TargetYear); EmulWall(MsgBuf, false); return; } else { SpitError("Time signature doesn't even contain a semicolon and a slash!\n" "This is probably a bug, please report to Epoch."); snprintf(TmpBuf, sizeof TmpBuf, "%s %s", MEMBUS_CODE_BADPARAM, BusData); MemBus_Write(TmpBuf, true); return; } } else if (BusDataIs(MEMBUS_CODE_ABORTHALT)) { char MsgBuf[MAX_LINE_SIZE]; const Bool H = HaltParams.TargetHour >= 10; const Bool M = HaltParams.TargetMin >= 10; const Bool S = HaltParams.TargetSec >= 10; if (HaltParams.HaltMode != -1) { HaltParams.HaltMode = -1; /*-1 does the real cancellation.*/ } else { /*Nothing scheduled?*/ MemBus_Write(MEMBUS_CODE_FAILURE " " MEMBUS_CODE_ABORTHALT, true); return; } snprintf(MsgBuf, sizeof MsgBuf, "%s %s%u:%s%u:%s%u %u/%u/%u %s", "The shutdown scheduled for", H?"":"0", HaltParams.TargetHour, M?"":"0", HaltParams.TargetMin, S?"":"0", HaltParams.TargetSec, HaltParams.TargetMonth, HaltParams.TargetDay, HaltParams.TargetYear, "has been aborted."); EmulWall(MsgBuf, false); MemBus_Write(MEMBUS_CODE_ACKNOWLEDGED " " MEMBUS_CODE_ABORTHALT, true); return; } /*Ctrl-Alt-Del control.*/ else if (BusDataIs(MEMBUS_CODE_CADOFF)) { if (!reboot(OSCTL_DISABLE_CTRLALTDEL)) { MemBus_Write(MEMBUS_CODE_ACKNOWLEDGED " " MEMBUS_CODE_CADOFF, true); } else { MemBus_Write(MEMBUS_CODE_FAILURE " " MEMBUS_CODE_CADOFF, true); } } else if (BusDataIs(MEMBUS_CODE_CADON)) { if (!reboot(OSCTL_ENABLE_CTRLALTDEL)) { MemBus_Write(MEMBUS_CODE_ACKNOWLEDGED " " MEMBUS_CODE_CADON, true); } else { MemBus_Write(MEMBUS_CODE_FAILURE " " MEMBUS_CODE_CADON, true); } } else if (BusDataIs(MEMBUS_CODE_SENDPID)) { char TmpBuf[MEMBUS_MSGSIZE]; unsigned LOffset = strlen(MEMBUS_CODE_SENDPID " "); const char *TWorker = BusData + LOffset; const ObjTable *TmpObj = NULL; if (LOffset >= strlen(BusData) || BusData[LOffset] == ' ') { /*No argument?*/ snprintf(TmpBuf, sizeof TmpBuf, "%s %s", MEMBUS_CODE_BADPARAM, BusData); MemBus_Write(TmpBuf, true); return; } if (!(TmpObj = LookupObjectInTable(TWorker)) || !TmpObj->Started) { /*Bad argument?*/ snprintf(TmpBuf, sizeof TmpBuf, "%s %s", MEMBUS_CODE_FAILURE, BusData); MemBus_Write(TmpBuf, true); return; } snprintf(TmpBuf, sizeof TmpBuf, "%s %s %u", MEMBUS_CODE_SENDPID, TWorker, (TmpObj->Opts.HasPIDFile ? ReadPIDFile(TmpObj) : TmpObj->ObjectPID)); MemBus_Write(TmpBuf, true); } else if (BusDataIs(MEMBUS_CODE_KILLOBJ) || BusDataIs(MEMBUS_CODE_OBJRELOAD)) { char TmpBuf[MEMBUS_MSGSIZE]; unsigned LOffset = (BusDataIs(MEMBUS_CODE_KILLOBJ) ? strlen(MEMBUS_CODE_KILLOBJ " ") : strlen(MEMBUS_CODE_OBJRELOAD " ")); const char *TWorker = BusData + LOffset; ObjTable *TmpObj = NULL; if (LOffset >= strlen(BusData) || BusData[LOffset] == ' ') { /*No argument?*/ snprintf(TmpBuf, sizeof TmpBuf, "%s %s", MEMBUS_CODE_BADPARAM, BusData); MemBus_Write(TmpBuf, true); return; } if (!(TmpObj = LookupObjectInTable(TWorker)) || !TmpObj->Started) { /*Bad argument?*/ snprintf(TmpBuf, sizeof TmpBuf, "%s %s", MEMBUS_CODE_FAILURE, BusData); MemBus_Write(TmpBuf, true); return; } if (BusDataIs(MEMBUS_CODE_KILLOBJ)) { /*Attempt to send SIGKILL to the PID.*/ if (!TmpObj->ObjectPID || kill((TmpObj->Opts.HasPIDFile ? ReadPIDFile(TmpObj) : TmpObj->ObjectPID), SIGKILL) != 0) { snprintf(TmpBuf, sizeof TmpBuf, "%s %s", MEMBUS_CODE_FAILURE, BusData); } else { snprintf(TmpBuf, sizeof TmpBuf, "%s %s", MEMBUS_CODE_ACKNOWLEDGED, BusData); TmpObj->Started = false; /*Mark it as stopped now that it's dead.*/ TmpObj->ObjectPID = 0; /*Erase the PID.*/ TmpObj->StartedSince = 0; } MemBus_Write(TmpBuf, true); } else { ReturnCode RV = SUCCESS; const char *MCode = MEMBUS_CODE_ACKNOWLEDGED, *RMsg = NULL; char LogOut[MAX_LINE_SIZE]; if (TmpObj->ObjectReloadCommand == NULL && TmpObj->ReloadCommandSignal == 0) { snprintf(TmpBuf, sizeof TmpBuf, "%s %s", MEMBUS_CODE_FAILURE, BusData); MemBus_Write(TmpBuf, true); return; } RV = ProcessReloadCommand(TmpObj, false); switch (RV) { case SUCCESS: MCode = MEMBUS_CODE_ACKNOWLEDGED; RMsg = "succeeded"; break; case WARNING: MCode = MEMBUS_CODE_WARNING; RMsg = "succeeded with a warning"; break; case FAILURE: MCode = MEMBUS_CODE_FAILURE; RMsg = "failed"; break; default: break; } snprintf(TmpBuf, sizeof TmpBuf, "%s %s", MCode, BusData); MemBus_Write(TmpBuf, true); snprintf(LogOut, MAX_LINE_SIZE, "Reload of object %s %s.", TWorker, RMsg); WriteLogLine(LogOut, true); } } else if (BusDataIs(MEMBUS_CODE_RXD)) { /*Restart Epoch from disk, but saves object states and whatnot. * Done mainly so we can unmount the filesystem after someone updates /sbin/epoch.*/ /**We set this so when we come back we'll know if we are doing a regular reexec.**/ setenv("EPOCHRXDMEMBUS", "1", true); ReexecuteEpoch(); } /*Something we don't understand. Send BADPARAM.*/ else { char TmpBuf[MEMBUS_MSGSIZE]; snprintf(TmpBuf, sizeof TmpBuf, "%s %s", MEMBUS_CODE_BADPARAM, BusData); MemBus_Write(TmpBuf, true); } }
int Connected(Stream) { int n; ChatCIRCUIT * conn; struct UserInfo * user = NULL; char callsign[10]; int port, paclen, maxframe, l4window; char ConnectedMsg[] = "*** CONNECTED "; char Msg[100]; LINK *link; KNOWNNODE *node; for (n = 0; n < NumberofChatStreams; n++) { conn = &ChatConnections[n]; if (Stream == conn->BPQStream) { if (conn->Active) { // Probably an outgoing connect if (conn->rtcflags == p_linkini) { conn->paclen = 236; nprintf(conn, "c %s\r", conn->u.link->call); return 0; } } memset(conn, 0, sizeof(ChatCIRCUIT)); // Clear everything conn->Active = TRUE; conn->BPQStream = Stream; conn->Secure_Session = GetConnectionInfo(Stream, callsign, &port, &conn->SessType, &paclen, &maxframe, &l4window); conn->paclen = paclen; strlop(callsign, ' '); // Remove trailing spaces memcpy(conn->Callsign, callsign, 10); strlop(callsign, '-'); // Remove any SSID user = zalloc(sizeof(struct UserInfo)); strcpy(user->Call, callsign); conn->UserPointer = user; n=sprintf_s(Msg, sizeof(Msg), "Incoming Connect from %s", user->Call); // Send SID and Prompt WriteLogLine(conn, '|',Msg, n, LOG_CHAT); conn->Flags |= CHATMODE; nodeprintf(conn, ChatSID, Ver[0], Ver[1], Ver[2], Ver[3]); // See if from a defined node for (link = link_hd; link; link = link->next) { if (matchi(conn->Callsign, link->call)) { conn->rtcflags = p_linkwait; return 0; // Wait for *RTL } } // See if from a previously known node node = knownnode_find(conn->Callsign); if (node) { // A node is trying to link, but we don't have it defined - close Logprintf(LOG_CHAT, conn, '!', "Node %s connected, but is not defined as a Node - closing", conn->Callsign); nodeprintf(conn, "Node %s does not have %s defined as a node to link to - closing.\r", OurNode, conn->Callsign); ChatFlush(conn); Sleep(500); Disconnect(conn->BPQStream); return 0; } if (user->Name[0] == 0) { char * Name = lookupuser(user->Call); if (Name) { if (strlen(Name) > 17) Name[17] = 0; strcpy(user->Name, Name); free(Name); } else { conn->Flags |= GETTINGUSER; nputs(conn, NewUserPrompt); return TRUE; } } SendWelcomeMsg(Stream, conn, user); RefreshMainWindow(); ChatFlush(conn); return 0; } } return 0; }