Beispiel #1
0
int main(int argc, char**argv)
#endif
{
#if defined WIN32
#ifndef _DEBUG
	CreateMutexA(0, FALSE, "Local\\Domoticz"); 
	if(GetLastError() == ERROR_ALREADY_EXISTS) { 
		MessageBox(HWND_DESKTOP,"Another instance of Domoticz is already running!","Domoticz",MB_OK);
		return 1; 
	}
#endif //_DEBUG
	bool bStartWebBrowser = true;
	RedirectIOToConsole();
#endif //WIN32

	szStartupFolder = "";
	szWWWFolder = "";
	szWebRoot = "";
	
	CCmdLine cmdLine;

	// parse argc,argv 
#if defined WIN32
	cmdLine.SplitLine(__argc, __argv);
#else
	cmdLine.SplitLine(argc, argv);
	//ignore pipe errors
	signal(SIGPIPE, SIG_IGN);
#endif

	if (cmdLine.HasSwitch("-log"))
	{
		if (cmdLine.GetArgumentCount("-log") != 1)
		{
			_log.Log(LOG_ERROR, "Please specify an output log file");
			return 1;
		}
		logfile = cmdLine.GetSafeArgument("-log", 0, "domoticz.log");
		_log.SetOutputFile(logfile.c_str());
	}
	if (cmdLine.HasSwitch("-loglevel"))
	{
		if (cmdLine.GetArgumentCount("-loglevel") != 1)
		{
			_log.Log(LOG_ERROR, "Please specify logfile output level (0=All, 1=Status+Error, 2=Error)");
			return 1;
		}
		int Level = atoi(cmdLine.GetSafeArgument("-loglevel", 0, "").c_str());
		_log.SetVerboseLevel((_eLogFileVerboseLevel)Level);
	}
	if (cmdLine.HasSwitch("-notimestamps"))
	{
		_log.EnableLogTimestamps(false);
	}

	if (cmdLine.HasSwitch("-approot"))
	{
		if (cmdLine.GetArgumentCount("-approot") != 1)
		{
			_log.Log(LOG_ERROR, "Please specify a APP root path");
			return 1;
		}
		std::string szroot = cmdLine.GetSafeArgument("-approot", 0, "");
		if (szroot.size() != 0)
			szStartupFolder = szroot;
	}

	if (szStartupFolder == "")
	{
#if !defined WIN32
		char szStartupPath[255];
		getExecutablePathName((char*)&szStartupPath,255);
		szStartupFolder=szStartupPath;
		if (szStartupFolder.find_last_of('/')!=std::string::npos)
			szStartupFolder=szStartupFolder.substr(0,szStartupFolder.find_last_of('/')+1);
#else
#ifndef _DEBUG
		char szStartupPath[255];
		char * p;
		GetModuleFileName(NULL, szStartupPath, sizeof(szStartupPath));
		p = szStartupPath + strlen(szStartupPath);

		while (p >= szStartupPath && *p != '\\')
			p--;

		if (++p >= szStartupPath)
			*p = 0;
		szStartupFolder=szStartupPath;
		size_t start_pos = szStartupFolder.find("\\Release\\");
		if(start_pos != std::string::npos) {
			szStartupFolder.replace(start_pos, 9, "\\domoticz\\");
			_log.Log(LOG_STATUS,"%s",szStartupFolder.c_str());
		}
#endif
#endif
	}
	GetAppVersion();
	_log.Log(LOG_STATUS, "Domoticz V%s (c)2012-%d GizMoCuz", szAppVersion.c_str(), ActYear);
	_log.Log(LOG_STATUS, "Build Hash: %s, Date: %s", szAppHash.c_str(), szAppDate.c_str());

#if !defined WIN32
	//Check if we are running on a RaspberryPi
	std::string sLine = "";
	std::ifstream infile;

#if defined(__FreeBSD__)
	infile.open("/compat/linux/proc/cpuinfo");
#else
	infile.open("/proc/cpuinfo");
#endif
	if (infile.is_open())
	{
		while (!infile.eof())
		{
			getline(infile, sLine);
			if (
				(sLine.find("BCM2708")!=std::string::npos)||
				(sLine.find("BCM2709")!=std::string::npos)
				)
			{
				//Core temperature of BCM2835 SoC
				_log.Log(LOG_STATUS,"System: Raspberry Pi");
				szInternalTemperatureCommand="/opt/vc/bin/vcgencmd measure_temp";
				bHasInternalTemperature=true;
				break;
			}
		}
		infile.close();
	}
	if (!bHasInternalTemperature)
	{
		if (file_exist("/sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/temp1_input"))
		{
			_log.Log(LOG_STATUS,"System: Cubieboard/Cubietruck");
			szInternalTemperatureCommand="cat /sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/temp1_input | awk '{ printf (\"temp=%0.2f\\n\",$1/1000); }'";
			bHasInternalTemperature = true;
		}
		else if (file_exist("/sys/devices/virtual/thermal/thermal_zone0/temp"))
		{
			//_log.Log(LOG_STATUS,"System: ODroid");
			szInternalTemperatureCommand="cat /sys/devices/virtual/thermal/thermal_zone0/temp | awk '{ if ($1 < 100) printf(\"temp=%d\\n\",$1); else printf (\"temp=%0.2f\\n\",$1/1000); }'";
			bHasInternalTemperature = true;
		}
	}
	if (file_exist("/sys/class/power_supply/ac/voltage_now"))
	{
		szInternalVoltageCommand = "cat /sys/class/power_supply/ac/voltage_now | awk '{ printf (\"volt=%0.2f\\n\",$1/1000000); }'";
		bHasInternalVoltage = true;
	}
	if (file_exist("/sys/class/power_supply/ac/current_now"))
	{
		szInternalCurrentCommand = "cat /sys/class/power_supply/ac/current_now | awk '{ printf (\"curr=%0.2f\\n\",$1/1000000); }'";
		bHasInternalCurrent = true;
	}
	_log.Log(LOG_STATUS,"Startup Path: %s", szStartupFolder.c_str());
#endif

	szWWWFolder = szStartupFolder + "www";

	if ((cmdLine.HasSwitch("-h")) || (cmdLine.HasSwitch("--help")) || (cmdLine.HasSwitch("/?")))
	{
		_log.Log(LOG_NORM, szHelp);
		return 0;
	}

	szUserDataFolder=szStartupFolder;
	if (cmdLine.HasSwitch("-userdata"))
	{
		if (cmdLine.GetArgumentCount("-userdata") != 1)
		{
			_log.Log(LOG_ERROR, "Please specify a path for user data to be stored");
			return 1;
		}
		std::string szroot = cmdLine.GetSafeArgument("-userdata", 0, "");
		if (szroot.size() != 0)
			szUserDataFolder = szroot;
	}

	if (cmdLine.HasSwitch("-startupdelay"))
	{
		if (cmdLine.GetArgumentCount("-startupdelay") != 1)
		{
			_log.Log(LOG_ERROR, "Please specify a startupdelay");
			return 1;
		}
		int DelaySeconds = atoi(cmdLine.GetSafeArgument("-startupdelay", 0, "").c_str());
		_log.Log(LOG_STATUS, "Startup delay... waiting %d seconds...", DelaySeconds);
		sleep_seconds(DelaySeconds);
	}

	http::server::server_settings webserver_settings;
	if (cmdLine.HasSwitch("-wwwbind"))
	{
		if (cmdLine.GetArgumentCount("-wwwbind") != 1)
		{
			_log.Log(LOG_ERROR, "Please specify an address");
			return 1;
		}
		webserver_settings.listening_address = cmdLine.GetSafeArgument("-wwwbind", 0, "0.0.0.0");
	}

	if (cmdLine.HasSwitch("-www"))
	{
		if (cmdLine.GetArgumentCount("-www") != 1)
		{
			_log.Log(LOG_ERROR, "Please specify a port");
			return 1;
		}
		std::string wwwport = cmdLine.GetSafeArgument("-www", 0, "");
		webserver_settings.listening_port = wwwport;
	}

	if (cmdLine.HasSwitch("-php_cgi_path"))
	{
		if (cmdLine.GetArgumentCount("-php_cgi_path") != 1)
		{
			_log.Log(LOG_ERROR, "Please specify the path to the php-cgi command");
			return 1;
		}
		webserver_settings.php_cgi_path = cmdLine.GetSafeArgument("-php_cgi_path", 0, "");
	}
	if (cmdLine.HasSwitch("-wwwroot"))
	{
		if (cmdLine.GetArgumentCount("-wwwroot") != 1)
		{
			_log.Log(LOG_ERROR, "Please specify a WWW root path");
			return 1;
		}
		std::string szroot = cmdLine.GetSafeArgument("-wwwroot", 0, "");
		if (szroot.size() != 0)
			szWWWFolder = szroot;
	}
	webserver_settings.www_root = szWWWFolder;
	m_mainworker.SetWebserverSettings(webserver_settings);
#ifdef WWW_ENABLE_SSL
	http::server::ssl_server_settings secure_webserver_settings;
	if (cmdLine.HasSwitch("-sslwww"))
	{
		if (cmdLine.GetArgumentCount("-sslwww") != 1)
		{
			_log.Log(LOG_ERROR, "Please specify a port");
			return 1;
		}
		std::string wwwport = cmdLine.GetSafeArgument("-sslwww", 0, "");
		secure_webserver_settings.listening_port = wwwport;
	}
	if (!webserver_settings.listening_address.empty()) {
		// Secure listening address has to be equal
		secure_webserver_settings.listening_address = webserver_settings.listening_address;
	}
	if (cmdLine.HasSwitch("-sslcert"))
	{
		if (cmdLine.GetArgumentCount("-sslcert") != 1)
		{
			_log.Log(LOG_ERROR, "Please specify a file path for your server certificate file");
			return 1;
		}
		secure_webserver_settings.cert_file_path = cmdLine.GetSafeArgument("-sslcert", 0, "");
	}
	if (cmdLine.HasSwitch("-sslpass"))
	{
		if (cmdLine.GetArgumentCount("-sslpass") != 1)
		{
			_log.Log(LOG_ERROR, "Please specify a passphrase to access to your server private key in certificate file");
			return 1;
		}
		secure_webserver_settings.private_key_pass_phrase = cmdLine.GetSafeArgument("-sslpass", 0, "");
	}
	if (cmdLine.HasSwitch("-sslmethod"))
	{
		if (cmdLine.GetArgumentCount("-sslmethod") != 1)
		{
			_log.Log(LOG_ERROR, "Please specify a SSL method");
			return 1;
		}
		secure_webserver_settings.ssl_method = cmdLine.GetSafeArgument("-sslmethod", 0, "");
	}
	if (cmdLine.HasSwitch("-ssloptions"))
	{
		if (cmdLine.GetArgumentCount("-ssloptions") != 1)
		{
			_log.Log(LOG_ERROR, "Please specify SSL options");
			return 1;
		}
		secure_webserver_settings.options = cmdLine.GetSafeArgument("-ssloptions", 0, "");
	}
	if (cmdLine.HasSwitch("-ssldhparam"))
	{
		if (cmdLine.GetArgumentCount("-ssldhparam") != 1)
		{
			_log.Log(LOG_ERROR, "Please specify a file path for the SSL DH parameters file");
			return 1;
		}
		secure_webserver_settings.tmp_dh_file_path = cmdLine.GetSafeArgument("-ssldhparam", 0, "");
	}
	if (cmdLine.HasSwitch("-php_cgi_path"))
	{
		if (cmdLine.GetArgumentCount("-php_cgi_path") != 1)
		{
			_log.Log(LOG_ERROR, "Please specify the path to the php-cgi command");
			return 1;
		}
		secure_webserver_settings.php_cgi_path = cmdLine.GetSafeArgument("-php_cgi_path", 0, "");
	}
	secure_webserver_settings.www_root = szWWWFolder;
	m_mainworker.SetSecureWebserverSettings(secure_webserver_settings);
#endif
	if (cmdLine.HasSwitch("-nowwwpwd"))
	{
		m_mainworker.m_bIgnoreUsernamePassword = true;
	}
	if (cmdLine.HasSwitch("-nocache"))
	{
		g_bDontCacheWWW = true;
	}
	std::string dbasefile = szUserDataFolder + "domoticz.db";
#ifdef WIN32
#ifndef _DEBUG
	if (!IsUserAnAdmin())
	{
		char szPath[MAX_PATH];
		HRESULT hr = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, 0, szPath);
		if (SUCCEEDED(hr))
		{
			std::string sPath = szPath;
			sPath += "\\Domoticz";

			DWORD dwAttr = GetFileAttributes(sPath.c_str());
			BOOL bDirExists = (dwAttr != 0xffffffff && (dwAttr & FILE_ATTRIBUTE_DIRECTORY));
			if (!bDirExists)
			{
				BOOL bRet = CreateDirectory(sPath.c_str(), NULL);
				if (bRet == FALSE) {
					MessageBox(0, "Error creating Domoticz directory in program data folder (%ProgramData%)!!", "Error:", MB_OK);
				}
			}
			sPath += "\\domoticz.db";
			dbasefile = sPath;
		}
	}
#endif
#endif

	if (cmdLine.HasSwitch("-dbase"))
	{
		if (cmdLine.GetArgumentCount("-dbase") != 1)
		{
			_log.Log(LOG_ERROR, "Please specify a Database Name");
			return 1;
		}
		dbasefile = cmdLine.GetSafeArgument("-dbase", 0, "domoticz.db");
	}
	m_sql.SetDatabaseName(dbasefile);

	if (cmdLine.HasSwitch("-webroot"))
	{
		if (cmdLine.GetArgumentCount("-webroot") != 1)
		{
			_log.Log(LOG_ERROR, "Please specify a web root path");
			return 1;
		}
		std::string szroot = cmdLine.GetSafeArgument("-webroot", 0, "");
		if (szroot.size() != 0)
			szWebRoot = szroot;
	}

	if (cmdLine.HasSwitch("-verbose"))
	{
		if (cmdLine.GetArgumentCount("-verbose") != 1)
		{
			_log.Log(LOG_ERROR, "Please specify a verbose level");
			return 1;
		}
		int Level = atoi(cmdLine.GetSafeArgument("-verbose", 0, "").c_str());
		m_mainworker.SetVerboseLevel((eVerboseLevel)Level);
	}
#if defined WIN32
	if (cmdLine.HasSwitch("-nobrowser"))
	{
		bStartWebBrowser = false;
	}
	//Init WinSock
	WSADATA data;
	WORD version;

	version = (MAKEWORD(2, 2));
	int ret = WSAStartup(version, &data);
	if (ret != 0)
	{
		ret = WSAGetLastError();

		if (ret == WSANOTINITIALISED)
		{
			_log.Log(LOG_ERROR, "Error: Winsock could not be initialized!");
		}
	}
	CoInitializeEx(0, COINIT_MULTITHREADED);
	CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
#endif
#ifndef WIN32
	if (cmdLine.HasSwitch("-daemon"))
	{
		g_bRunAsDaemon = true;
	}

	std::string daemonname = DAEMON_NAME;
	if (cmdLine.HasSwitch("-daemonname"))
	{
		daemonname = cmdLine.GetSafeArgument("-daemonname", 0, DAEMON_NAME);
	}

	std::string pidfile = PID_FILE;
	if (cmdLine.HasSwitch("-pidfile"))
	{
		pidfile = cmdLine.GetSafeArgument("-pidfile", 0, PID_FILE);
	}

	if (cmdLine.HasSwitch("-syslog"))
	{
		g_bUseSyslog = true;
		logfacname = cmdLine.GetSafeArgument("-syslog", 0, "");
		if ( logfacname.length() == 0 ) 
		{
			logfacname = "user";
		}
	}

	if ((g_bRunAsDaemon)||(g_bUseSyslog))
	{
		int idx, logfacility = 0;

		for ( idx = 0; idx < sizeof(facilities)/sizeof(facilities[0]); idx++ ) 
		{
			if (strcmp(facilities[idx].facname, logfacname.c_str()) == 0) 
			{
				logfacility = facilities[idx].facvalue;
				break;
			}
		} 
		if ( logfacility == 0 ) 
		{
			_log.Log(LOG_ERROR, "%s is an unknown syslog facility", logfacname.c_str());
			return 1;
		}

		// _log.Log(LOG_STATUS, "syslog to %s (%x)", logfacname.c_str(), logfacility);
		setlogmask(LOG_UPTO(LOG_INFO));
		openlog(daemonname.c_str(), LOG_CONS | LOG_PERROR, logfacility);

		syslog(LOG_INFO, "Domoticz is starting up....");
	}

	if (g_bRunAsDaemon)
	{
		/* Deamonize */
		daemonize(szStartupFolder.c_str(), pidfile.c_str());
	}
	if ((g_bRunAsDaemon) || (g_bUseSyslog))
	{
		syslog(LOG_INFO, "Domoticz running...");
	}
#endif

	if (!g_bRunAsDaemon)
	{
		signal(SIGINT, signal_handler);
		signal(SIGTERM, signal_handler);
	}

	if (!m_mainworker.Start())
	{
		return 1;
	}
	m_StartTime = time(NULL);

	/* now, lets get into an infinite loop of doing nothing. */
#if defined WIN32
#ifndef _DEBUG
	RedirectIOToConsole();	//hide console
#endif
	InitWindowsHelper(hInstance, hPrevInstance, nShowCmd, m_mainworker.GetWebserverAddress(), atoi(m_mainworker.GetWebserverPort().c_str()), bStartWebBrowser);
	MSG Msg;
	while (!g_bStopApplication)
	{
		if (PeekMessage(&Msg, NULL, 0, 0, PM_NOREMOVE))
		{
			if (GetMessage(&Msg, NULL, 0, 0) > 0)
			{
				TranslateMessage(&Msg);
				DispatchMessage(&Msg);
			}
		}
		else
			sleep_milliseconds(100);
	}
	TrayMessage(NIM_DELETE, NULL);
#else
	while ( !g_bStopApplication )
	{
		sleep_seconds(1);
	}
#endif
	_log.Log(LOG_STATUS, "Closing application!...");
	fflush(stdout);
	_log.Log(LOG_STATUS, "Stopping worker...");
	try
	{
		m_mainworker.Stop();
	}
	catch (...)
	{

	}
#ifndef WIN32
	if (g_bRunAsDaemon)
	{
		syslog(LOG_INFO, "Domoticz stopped...");
		daemonShutdown();

		// Delete PID file
		remove(pidfile.c_str());
	}
#else
	// Release WinSock
	WSACleanup();
	CoUninitialize();
#endif
	return 0;
}