diff --git a/Listener.h b/Listener.h index f5eaa340..dbd357c5 100644 --- a/Listener.h +++ b/Listener.h @@ -43,6 +43,10 @@ public: EAcceptType GetAcceptType() const { return m_eAcceptType; } // !Getters + // It doesn't make sense to change any of the settings after Listen() + // except this one, so don't add other setters! + void SetAcceptType(EAcceptType eType) { m_eAcceptType = eType; } + bool Listen(); void ResetRealListener(); diff --git a/modules/webadmin.cpp b/modules/webadmin.cpp index 1090d5b3..80f948a4 100644 --- a/modules/webadmin.cpp +++ b/modules/webadmin.cpp @@ -38,6 +38,80 @@ public: } virtual bool OnLoad(const CString& sArgStr, CString& sMessage) { + if (sArgStr.empty()) + return true; + + // We don't accept any arguments, but for backwards + // compatibility we have to do some magic here. + sMessage = "Arguments converted to new syntax"; + + bool bSSL = false; + bool bIPv6 = false; + bool bShareIRCPorts = true; + unsigned short uPort = 8080; + CString sArgs(sArgStr); + CString sPort; + CString sListenHost; + + while (sArgs.Left(1) == "-") { + CString sOpt = sArgs.Token(0); + sArgs = sArgs.Token(1, true); + + if (sOpt.Equals("-IPV6")) { + bIPv6 = true; + } else if (sOpt.Equals("-IPV4")) { + bIPv6 = false; + } else if (sOpt.Equals("-noircport")) { + bShareIRCPorts = false; + } else { + // Uhm... Unknown option? Let's just ignore all + // arguments, older versions would have returned + // an error and denied loading + return true; + } + } + + // No arguments left: Only port sharing + if (sArgs.empty() && bShareIRCPorts) + return true; + + if (sArgs.find(" ") != CString::npos) { + sListenHost = sArgs.Token(0); + sPort = sArgs.Token(1, true); + } else { + sPort = sArgs; + } + + if (sPort.Left(1) == "+") { + sPort.TrimLeft("+"); + bSSL = true; + } + + if (!sPort.empty()) { + uPort = sPort.ToUShort(); + } + + if (!bShareIRCPorts) { + // Make all existing listeners IRC-only + const vector& vListeners = CZNC::Get().GetListeners(); + vector::const_iterator it; + for (it = vListeners.begin(); it != vListeners.end(); ++it) { + (*it)->SetAcceptType(CListener::ACCEPT_IRC); + } + } + + // Now turn that into a listener instance + CListener *pListener = new CListener(uPort, sListenHost, bSSL, + (!bIPv6 ? ADDR_IPV4ONLY : ADDR_ALL), + (bShareIRCPorts ? CListener::ACCEPT_ALL : CListener::ACCEPT_HTTP)); + + if (!pListener->Listen()) { + sMessage = "Failed to add backwards-compatible listener"; + return false; + } + CZNC::Get().AddListener(pListener); + + SetArgs(""); return true; }