CZNC::CZNC() { if (!InitCsocket()) { CUtils::PrintError("Could not initialize Csocket!"); exit(-1); } m_pModules = new CModules(); m_uiConnectDelay = 5; m_uiAnonIPLimit = 10; m_uBytesRead = 0; m_uBytesWritten = 0; m_uiMaxBufferSize = 500; m_pConnectQueueTimer = NULL; m_eConfigState = ECONFIG_NOTHING; m_TimeStarted = time(NULL); m_sConnectThrottle.SetTTL(30000); m_pLockFile = NULL; m_bProtectWebSessions = true; }
int main(int argc, char** argv) { CString sConfig; CString sDataDir = ""; seedPRNG(); // Win32 doesn't support shell escape codes, so we do this. CUtils::SetStdoutIsTTY(false); CString sConsoleTitle = "ZNC " + CZNC::GetVersion(); SetConsoleTitle(sConsoleTitle.c_str()); // register Ctrl handler if (SetConsoleCtrlHandler((PHANDLER_ROUTINE)ConsoleCtrlHandler, TRUE) == NULL) { CUtils::PrintMessage("Couldn't register console Ctrl handler function!"); } // this prevents open()/read() and friends from stripping \r // from files... simply adding _O_BINARY to the modes doesn't seem // to be enough for some reason... // if we don't do this, Template.cpp will break // because it uses string.size() for file pos // calculations. _set_fmode(_O_BINARY); #ifdef HAVE_LIBSSL CRYPTO_malloc_init(); #endif // make sure the stuff in ZNC.dll matches this exe's version... bad crashes otherwise. if(CZNC::GetCoreVersion() != MODVERSION) { CUtils::PrintError("The version number in ZNC.dll doesn't match. Aborting."); return 1; } // process command line arguments int iArg, iOptIndex = -1; bool bMakeConf = false; bool bMakePass = false; bool bAllowRoot = false; #ifdef HAVE_LIBSSL bool bMakePem = false; while ((iArg = getopt_long(argc, argv, "hvcspd:D", g_LongOpts, &iOptIndex)) != -1) { #else while ((iArg = getopt_long(argc, argv, "hvcsd:D", g_LongOpts, &iOptIndex)) != -1) { #endif /* HAVE_LIBSSL */ switch (iArg) { case 'h': GenerateHelp(argv[0]); return 0; case 'v': cout << CZNC::GetTag() << endl; return 0; case 'c': bMakeConf = true; break; case 's': bMakePass = true; break; #ifdef HAVE_LIBSSL case 'p': bMakePem = true; break; #endif /* HAVE_LIBSSL */ case 'd': sDataDir = CString(optarg); break; case 'D': CUtils::SetDebug(true); break; case '?': default: GenerateHelp(argv[0]); return 1; } } if (optind < argc) { sConfig = argv[optind]; } if (!InitCsocket()) { CUtils::PrintError("Failed to initialize Csocket!"); exit(-1); } CZNC* pZNC = &CZNC::Get(); pZNC->InitDirs(((argc) ? argv[0] : ""), sDataDir); #ifdef HAVE_LIBSSL if (bMakePem) { pZNC->WritePemFile(); delete pZNC; return 0; } #endif /* HAVE_LIBSSL */ if (bMakePass) { CString sSalt; CString sHash = CUtils::GetSaltedHashPass(sSalt); CUtils::PrintMessage("Use this in the <User> section of your config:"); CUtils::PrintMessage("Pass = "******"#" + sHash + "#" + sSalt + "#"); delete pZNC; return 0; } #ifndef RUN_FROM_SOURCE if (CFile::Exists(pZNC->GetCurPath() + "/znc-uninstalled.pc")) { CUtils::PrintError("It looks like you are running znc without installing it first."); CUtils::PrintError("Recompile with --enable-run-from-source if you intend to do that."); } #endif if (bMakeConf) { if (!pZNC->WriteNewConfig(sConfig)) { delete pZNC; return 0; } /* Fall through to normal bootup */ } if (!pZNC->ParseConfig(sConfig)) { if(argc < 2) { CUtils::PrintMessage("\n"); CUtils::PrintMessage("Press any key to continue..."); _getch(); } else { CUtils::PrintError("Unrecoverable config error."); } delete pZNC; return 1; } if (!pZNC->OnBoot()) { CUtils::PrintError("Exiting due to module boot errors."); delete pZNC; return 1; } // removed: checks for isRoot, bForeground, forking and signal handlers int iRet = 0; CUtils::PrintMessage("\n\n***************************************************"); CUtils::PrintMessage("** ZNC is now running. Do not close this window. **"); CUtils::PrintMessage("***************************************************\n\n"); try { pZNC->Loop(&g_bMainLoop); CUtils::PrintMessage("Terminating ..."); } catch (CException e) { switch (e.GetType()) { case CException::EX_Shutdown: iRet = 0; CUtils::PrintMessage("************** Shutting down ZNC... **************"); break; case CException::EX_Restart: { // strdup() because GCC is stupid char *args[] = { strdup(argv[0]), strdup("--datadir"), strdup(pZNC->GetZNCPath().c_str()), NULL, NULL, NULL, NULL, NULL }; int pos = 3; if (CUtils::Debug()) args[pos++] = strdup("--debug"); #if 0 else if (bForeground) args[pos++] = strdup("--foreground"); if (!CUtils::StdoutIsTTY()) args[pos++] = strdup("--no-color"); if (bAllowRoot) args[pos++] = strdup("--allow-root"); #endif args[pos++] = strdup(pZNC->GetConfigFile().c_str()); // The above code adds 4 entries to args tops // which means the array should be big enough CUtils::PrintMessage("************** Restarting ZNC... **************"); delete pZNC; /* stuff screws up real bad if we don't close all sockets etc. */ pZNC = NULL; execvp(args[0], args); CUtils::PrintError("Unable to restart znc [" + CString(strerror(errno)) + "]"); } /* Fall through */ default: iRet = 1; } } delete pZNC; #ifdef _DEBUG ::_getch(); #endif return iRet; }