diff --git a/ClientCommand.cpp b/ClientCommand.cpp index 4359ffd2..113e974b 100644 --- a/ClientCommand.cpp +++ b/ClientCommand.cpp @@ -236,6 +236,15 @@ void CClient::UserCommand(const CString& sLine) { usleep(100000); // Sleep for 10ms to attempt to allow the previous Broadcast() to go through to all users throw CException(CException::EX_Shutdown); + } else if (m_pUser->IsAdmin() && sCommand.CaseCmp("RESTART") == 0) { + CString sMessage = sLine.Token(1, true); + + if (sMessage.empty()) { + sMessage = "ZNC is being restarted NOW!!"; + } + + CZNC::Get().Broadcast(sMessage); + throw CException(CException::EX_Restart); } else if (sCommand.CaseCmp("JUMP") == 0 || sCommand.CaseCmp("CONNECT") == 0) { if (m_pUser) { @@ -1171,6 +1180,11 @@ void CClient::HelpUser() { Table.SetCell("Command", "Shutdown"); Table.SetCell("Arguments", "[message]"); Table.SetCell("Description", "Shutdown znc completely"); + + Table.AddRow(); + Table.SetCell("Command", "Restart"); + Table.SetCell("Arguments", "[message]"); + Table.SetCell("Description", "Restarts znc"); } if (Table.size()) { diff --git a/Utils.h b/Utils.h index 8b0c4d37..54a61eab 100644 --- a/Utils.h +++ b/Utils.h @@ -183,7 +183,8 @@ private: class CException { public: typedef enum { - EX_Shutdown + EX_Shutdown, + EX_Restart } EType; CException(EType e) { diff --git a/main.cpp b/main.cpp index 59a6ee05..5e25a309 100644 --- a/main.cpp +++ b/main.cpp @@ -260,10 +260,22 @@ int main(int argc, char** argv) { try { iRet = pZNC->Loop(); } catch (CException e) { - // EX_Shutdown is thrown to exit switch (e.GetType()) { case CException::EX_Shutdown: iRet = 0; + break; + case CException::EX_Restart: { + // strdup() because GCC is stupid + char *args[] = { + strdup(argv[0]), + strdup("--datadir"), + strdup(pZNC->GetZNCPath().c_str()), + strdup(pZNC->GetConfigFile().c_str()), + NULL + }; + execvp(args[0], args); + CUtils::PrintError("Unable to restart znc [" + CString(strerror(errno)) + "]"); + } /* Fall through */ default: iRet = 1; }