Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » Developing U++ » UppHub » [SysInfo - Improvement - Koldo] Better way to find distribution version & more
Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41093 is a reply to message #41091] Wed, 30 October 2013 23:15 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3355
Registered: August 2008
Senior Veteran
Smile Anyway, now it is like this:

static double GetCpuTemperatureHWMON() {
	double sumTemps = 0.;
	int count = 0;
	for (FindFile ff("/sys/class/hwmon/hwmon0/device/*input"); ff; ff.Next()) {
		if (!ff.IsHidden()) {
			String temp = LoadFile_Safe(ff.GetPath());
			if (!temp.IsEmpty()) {
				sumTemps += double(StrInt(temp))/1000.;
				count++;
			}
		}
	}
	if (count == 0)
		return Null;
	return sumTemps/count;
}


Best regards
Iñaki
Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41109 is a reply to message #41093] Thu, 31 October 2013 17:01 Go to previous messageGo to next message
Klugier is currently offline  Klugier
Messages: 1075
Registered: September 2012
Location: Poland, Kraków
Senior Contributor
Hello Koldo,

Alternative paths, can be done in this way:

static double GetCpuTemperatureHWMON()
{
	FindFile ff;
	double sumTemps = 0.0;
	int count       = 0;
	
	String path = "/sys/class/hwmon/";
	
	if (ff.Search(AppendFileName(path, "device"))) {
		path += ff.GetName() + "/";
	}
	else {
		String tempPath;
		for (ff.Search(AppendFileName(path, "hwmon*")); ff; ff.Next()) {
			FindFile hwmonFF;
		
			tempPath = path;
			tempPath += ff.GetName() + "/";
			if (hwmonFF.Search(AppendFileName(tempPath, "device"))) {
				tempPath += hwmonFF.GetName() + "/";
			}
		
			if (hwmonFF.Search(AppendFileName(tempPath, "*input"))) {
				if (!hwmonFF.IsDirectory()) {
					path = tempPath;
					break;
				}
			}
		}
		if (!tempPath.IsEmpty() && tempPath != path)
			path = tempPath;
	}
	
	for (ff.Search(AppendFileName(path, "*input")); ff; ff.Next()) {
		if (!ff.IsHidden()) {
			String temp = LoadFile_Safe(ff.GetPath());
			if (!temp.IsEmpty()) {
				sumTemps += static_cast <double> ((StrInt(temp))) / 1000.0;
				count++;
			}
		}
	}
	if (count == 0)
		return Null;
	return sumTemps / count;
}


* Additional changes:
- change casting method to more safer.
- changed "0." to "0.0" (Are you sure that 0. is more readable than 0.0???)

* TODO:
- create function static String "findHWMONInputFilesPath()" - ALTERNATIVE METHOD

Sincerely,
Klugier


U++ - one framework to rule them all.

[Updated on: Thu, 31 October 2013 19:01]

Report message to a moderator

Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41121 is a reply to message #41109] Fri, 01 November 2013 22:51 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3355
Registered: August 2008
Senior Veteran
Hello all

To get CPU temperature is more complicated than expected, and more difficult than checking folders.

So it is necessary to install either acpi or lm-sensors packages. There is no problem with the licenses because now the libraries are not used.

GetCpuTemperature() has been adapted to this and documentation has been updated.


Best regards
Iñaki
Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41122 is a reply to message #41121] Fri, 01 November 2013 23:37 Go to previous messageGo to next message
Klugier is currently offline  Klugier
Messages: 1075
Registered: September 2012
Location: Poland, Kraków
Senior Contributor
Hello Koldo,

Using sensors command is the easiest solution and safe solution, but not efficient one. Calling external program always associated with the overhead time. In addition we can check where are input files only once per program to optimize the algorithm.

Quote:


To get CPU temperature is more complicated than expected, and more difficult than checking folders.



I am almost sure that we can do this in above way (Open sources projects like "Conky" do this in simillar way).

Sincerely,
Klugier


U++ - one framework to rule them all.

[Updated on: Fri, 01 November 2013 23:45]

Report message to a moderator

Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41125 is a reply to message #41122] Sat, 02 November 2013 22:26 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3355
Registered: August 2008
Senior Veteran
Hello Klugier

IMHO calling external programs is a solution very used in open source projects, SysInfo included. For example it permits GPL code to be called from any program.

In the other side, I do not consider that registering CPU temperature requires a super fast response.

acpi and lm-sensors are well respect solutions, and there are so many different devices that it seems difficult to support them.


Best regards
Iñaki
Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41126 is a reply to message #41125] Sun, 03 November 2013 01:09 Go to previous messageGo to next message
Klugier is currently offline  Klugier
Messages: 1075
Registered: September 2012
Location: Poland, Kraków
Senior Contributor
Thank you for your answer Koldo. I fully understand your position and I agree with most of theses. If I have any ideas about SysInfo package I will posted about it on the forum.

Sincerely,
Klugier


U++ - one framework to rule them all.
Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #43154 is a reply to message #41091] Tue, 20 May 2014 12:59 Go to previous messageGo to next message
kasome is currently offline  kasome
Messages: 78
Registered: July 2008
Location: Taiwan
Member
Hello Koldo,

There is a bug in upp\bazaar\SysInfo\SysInfo.cpp

Here is the original code
Array<NetAdapter> GetAdapterInfo()
{
	Array<NetAdapter> res;
	Index<String> macs;
	
	int sck = socket(PF_INET, SOCK_DGRAM, 0);
	if(sck < 0)
		return res;
	
	int bufSize = 4096;
	struct ifconf ifc =	{ 0	};
	byte buf[bufSize];
	for(int iTry = 0; iTry < 4; iTry++) {
		ifc.ifc_len = bufSize;
		ifc.ifc_buf = (__caddr_t)buf;
 
		if (ioctl(sck, SIOCGIFCONF, &ifc) < 0) {
			close(sck);
			return res;
		}
		
		if(ifc.ifc_len != bufSize)
			break;

		bufSize *= 2;
		if(iTry >= 3) {
			close(sck);
			return res;
		}
	}
		
	int nIfaces = ifc.ifc_len / sizeof(struct ifreq);
	struct ifreq *iface = ifc.ifc_req;
	for(int iIface = 0; iIface < nIfaces; iIface++) {
		String MAC;
		
#ifdef SIOCGIFHWADDR
		if(ioctl(sck, SIOCGIFHWADDR, iface) < 0) 
			continue;
		
		MAC = Format("%02x:%02x:%02x:%02x:%02x:%02x",
						(byte)iface->ifr_hwaddr.sa_data[0],
						(byte)iface->ifr_hwaddr.sa_data[1],
						(byte)iface->ifr_hwaddr.sa_data[2],
						(byte)iface->ifr_hwaddr.sa_data[3],
						(byte)iface->ifr_hwaddr.sa_data[4],
						(byte)iface->ifr_hwaddr.sa_data[5]
		);

#elif SIOCGENADDR
		if (ioctl(sck, SIOCGENADDR, iface) < 0) 
			continue;
		
		MAC = Format("%02x:%02x:%02x:%02x:%02x:%02x",
						(byte)iface->ifr_enaddr[0],
						(byte)iface->ifr_enaddr[1],
						(byte)iface->ifr_enaddr[2],
						(byte)iface->ifr_enaddr[3],
						(byte)iface->ifr_enaddr[4],
						(byte)iface->ifr_enaddr[5]
		);

#elif __MACH__ || __NetBSD__ || __OpenBSD__ || __FreeBSD__
		int mib[6];
		mib[0] = CTL_NET;
		mib[1] = AF_ROUTE;
		mib[2] = 0;
		mib[3] = AF_LINK;
		mib[4] = NET_RT_IFLIST;
		mib[5] = if_nametoindex(iface->ifr_name);
		if (mib[5] == 0)	// nameless interface ? skip
			continue;

		int len = 0;
		if (sysctl(mib, 6, NULL, (size_t*)&len, NULL, 0) != 0) 
			continue;	// sysctl error, just leave MAC empty

		char macbuf[len];
		if (!macbuf) 	// can't allocat buffer, skip this MAC
			continue;
		
		if (sysctl(mib, 6, macbuf, (size_t*)&len, NULL, 0) != 0) 
			continue;

		struct if_msghdr *ifm = (struct if_msghdr *)macbuf;
		struct sockaddr_dl *sdl = (struct sockaddr_dl *)(ifm + 1);
		byte ptr[] = (byte **)LLADDR(sdl);

		MAC = Format("%02x:%02x:%02x:%02x:%02x:%02x", 
					ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);

#else
#error OS Distribution Not Recognized
#endif

		if(MAC == "00:00:00:00:00:00")
			MAC.Clear();

		if(!MAC.IsEmpty() && macs.Find(MAC) >= 0)
			continue;
		macs.Add(MAC);

		NetAdapter &adapter = res.Add();
		
		adapter.mac = MAC;
		
		adapter.fullname = iface->ifr_name;
		
		// set interface type from name
		if(adapter.fullname.StartsWith("eth"))
			adapter.type = "ETHERNET";
		else if(adapter.fullname.StartsWith("lo"))
			adapter.type = "SOFTWARE_LOOPBACK";
		else if(adapter.fullname.StartsWith("ppp"))
			adapter.type = "MODEM";		
		else if(adapter.fullname.StartsWith("hci"))
			adapter.type = "BLUETOOTH";
		else if(adapter.fullname.StartsWith("tr"))
			adapter.type = "TOKENRING";
		else if(adapter.fullname.StartsWith("vbox") || adapter.fullname.StartsWith("wifi") ||
				adapter.fullname.StartsWith("ath"))
			adapter.type = "VIRTUALBOX";
		else if(adapter.fullname.StartsWith("wlan"))
			adapter.type = "IEEE80211";
		else if(adapter.fullname.StartsWith("vmnet"))			
			adapter.type = "VMWARE";
		else
			adapter.type = "OTHER";
		
		adapter.description = adapter.fullname;
		
		if (!ioctl(sck, SIOCGIFADDR, iface))
			continue;
        
        adapter.ip4 = inet_ntoa(((struct sockaddr_in *)&(iface->ifr_addr))->sin_addr);  
		
		iface++;
	}
	close(sck);

	return res;
}


Here is the fixed code
Array<NetAdapter> GetAdapterInfo()
{
	Array<NetAdapter> res;
	Index<String> macs;
	
	int sck = socket(PF_INET, SOCK_DGRAM, 0);
	if(sck < 0)
		return res;
	
	int bufSize = 4096;
	struct ifconf ifc =	{ 0	};
	byte buf[bufSize];
	for(int iTry = 0; iTry < 4; iTry++) {
		ifc.ifc_len = bufSize;
		ifc.ifc_buf = (__caddr_t)buf;
 
		if (ioctl(sck, SIOCGIFCONF, &ifc) < 0) {
			close(sck);
			return res;
		}
		
		if(ifc.ifc_len != bufSize)
			break;

		bufSize *= 2;
		if(iTry >= 3) {
			close(sck);
			return res;
		}
	}
		
	int nIfaces = ifc.ifc_len / sizeof(struct ifreq);
	struct ifreq *iface = ifc.ifc_req;
	for(int iIface = 0; iIface < nIfaces; iIface++) {
		String MAC;
		
#ifdef SIOCGIFHWADDR
		if(ioctl(sck, SIOCGIFHWADDR, iface) < 0) 
			continue;
		
		MAC = Format("%02x:%02x:%02x:%02x:%02x:%02x",
						(byte)iface->ifr_hwaddr.sa_data[0],
						(byte)iface->ifr_hwaddr.sa_data[1],
						(byte)iface->ifr_hwaddr.sa_data[2],
						(byte)iface->ifr_hwaddr.sa_data[3],
						(byte)iface->ifr_hwaddr.sa_data[4],
						(byte)iface->ifr_hwaddr.sa_data[5]
		);

#elif SIOCGENADDR
		if (ioctl(sck, SIOCGENADDR, iface) < 0) 
			continue;
		
		MAC = Format("%02x:%02x:%02x:%02x:%02x:%02x",
						(byte)iface->ifr_enaddr[0],
						(byte)iface->ifr_enaddr[1],
						(byte)iface->ifr_enaddr[2],
						(byte)iface->ifr_enaddr[3],
						(byte)iface->ifr_enaddr[4],
						(byte)iface->ifr_enaddr[5]
		);

#elif __MACH__ || __NetBSD__ || __OpenBSD__ || __FreeBSD__
		int mib[6];
		mib[0] = CTL_NET;
		mib[1] = AF_ROUTE;
		mib[2] = 0;
		mib[3] = AF_LINK;
		mib[4] = NET_RT_IFLIST;
		mib[5] = if_nametoindex(iface->ifr_name);
		if (mib[5] == 0)	// nameless interface ? skip
			continue;

		int len = 0;
		if (sysctl(mib, 6, NULL, (size_t*)&len, NULL, 0) != 0) 
			continue;	// sysctl error, just leave MAC empty

		char macbuf[len];
		if (!macbuf) 	// can't allocat buffer, skip this MAC
			continue;
		
		if (sysctl(mib, 6, macbuf, (size_t*)&len, NULL, 0) != 0) 
			continue;

		struct if_msghdr *ifm = (struct if_msghdr *)macbuf;
		struct sockaddr_dl *sdl = (struct sockaddr_dl *)(ifm + 1);
		byte ptr[] = (byte **)LLADDR(sdl);

		MAC = Format("%02x:%02x:%02x:%02x:%02x:%02x", 
					ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);

#else
#error OS Distribution Not Recognized
#endif

		if(MAC == "00:00:00:00:00:00")
			MAC.Clear();

		if(!MAC.IsEmpty() && macs.Find(MAC) >= 0)
			continue;
		macs.Add(MAC);

		NetAdapter &adapter = res.Add();
		
		adapter.mac = MAC;
		
		adapter.fullname = iface->ifr_name;
		
		// set interface type from name
		if(adapter.fullname.StartsWith("eth"))
			adapter.type = "ETHERNET";
		else if(adapter.fullname.StartsWith("lo"))
			adapter.type = "SOFTWARE_LOOPBACK";
		else if(adapter.fullname.StartsWith("ppp"))
			adapter.type = "MODEM";		
		else if(adapter.fullname.StartsWith("hci"))
			adapter.type = "BLUETOOTH";
		else if(adapter.fullname.StartsWith("tr"))
			adapter.type = "TOKENRING";
		else if(adapter.fullname.StartsWith("vbox") || adapter.fullname.StartsWith("wifi") ||
				adapter.fullname.StartsWith("ath"))
			adapter.type = "VIRTUALBOX";
		else if(adapter.fullname.StartsWith("wlan"))
			adapter.type = "IEEE80211";
		else if(adapter.fullname.StartsWith("vmnet"))			
			adapter.type = "VMWARE";
		else
			adapter.type = "OTHER";
		
		adapter.description = adapter.fullname;

if (ioctl(sck, SIOCGIFADDR, iface) < 0) {
iface++;
continue;
}

        
        adapter.ip4 = inet_ntoa(((struct sockaddr_in *)&(iface->ifr_addr))->sin_addr);  
		
		iface++;
	}
	close(sck);

	return res;
}


Hope that helps.
Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #43155 is a reply to message #43154] Tue, 20 May 2014 17:27 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3355
Registered: August 2008
Senior Veteran
Yes you are right. Thank you. Smile

Best regards
Iñaki
Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #43374 is a reply to message #43155] Mon, 14 July 2014 10:26 Go to previous messageGo to next message
kasome is currently offline  kasome
Messages: 78
Registered: July 2008
Location: Taiwan
Member
Hello Koldo,

There is a few memory leak in function GetWMIInfo of upp\bazaar\SysInfo\SysInfo.cpp

find

bool GetWMIInfo(String system, Array <String> &data, Array <Value> *ret[], String nameSpace = "root\\cimv2")

and modify

for (int col = 0; col < data.GetCount(); ++col) {
			VARIANT vProp;
			BSTR strClassProp = SysAllocString(data[col].ToWString());
	        hRes = pClassObject->Get(strClassProp, 0, &vProp, 0, 0);
	        if(hRes != S_OK){
		        pWbemServices->Release();
		        pIWbemLocator->Release(); 
		        pEnumerator->Release(); 
		        pClassObject->Release();   
		        CoUninitialize();
		        return false;
		    }
			SysFreeString(strClassProp);        
			ret[col]->Add(GetVARIANT(vProp));
			rt = true;
}



to

for (int col = 0; col < data.GetCount(); ++col) {
			VARIANT vProp;

VariantInit( &vProp );
BSTR strClassProp = SysAllocString(data[col].ToWString());
	        hRes = pClassObject->Get(strClassProp, 0, &vProp, 0, 0);
	        if(hRes != S_OK){
		        pWbemServices->Release();
		        pIWbemLocator->Release(); 
		        pEnumerator->Release(); 
		        pClassObject->Release();   
		        CoUninitialize();
		        return false;
		    }
			SysFreeString(strClassProp);        
			ret[col]->Add(GetVARIANT(vProp));

VariantClear( &vProp );
rt = true;
}
Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #43375 is a reply to message #43374] Mon, 14 July 2014 10:33 Go to previous messageGo to next message
kasome is currently offline  kasome
Messages: 78
Registered: July 2008
Location: Taiwan
Member
About the functiion Shutdown in linux platform,

is there missing sync() function call when action == "shutdown" or action == "reboot" >

#ifdef PLATFORM_POSIX
bool Shutdown(String action)
{
	if (action == "logoff") {
		kill(1, SIGTSTP);
		sync();
		signal(SIGTERM, SIG_IGN);
		setpgrp();
		kill(-1, SIGTERM);
		sleep(1);
		kill(-1, SIGHUP); //* Force PPPD's down, too *
		sleep(1);
		kill(-1, SIGKILL);
		sync();
		sleep(1);
	} else if (action == "shutdown") {

sync();
sleep(1);

#if __GNU_LIBRARY__ > 5
		reboot(0xCDEF0123);
#else
		reboot(0xfee1dead, 672274793, 0xCDEF0123);
#endif
	} else if (action == "reboot") {		// LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2

sync();
sleep(1);

#if __GNU_LIBRARY__ > 5
		reboot(0x01234567);
#else
		reboot(0xfee1dead, 672274793, 0x01234567);
#endif
	} 
	exit(0);
	return true; 
}
#endif
Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #43379 is a reply to message #43375] Tue, 15 July 2014 12:05 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3355
Registered: August 2008
Senior Veteran
All included. Thank you!

Best regards
Iñaki
Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #43386 is a reply to message #43379] Sat, 19 July 2014 20:48 Go to previous messageGo to next message
Klugier is currently offline  Klugier
Messages: 1075
Registered: September 2012
Location: Poland, Kraków
Senior Contributor
Hello Koldo,

You should also replace C api function "exit(int)" by new U++ dedicated function "Exit(int code = 1)". This is maybe not important, but it makes your package more uppful Smile

Sincerely,
Klugier


U++ - one framework to rule them all.
Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #43387 is a reply to message #43386] Mon, 21 July 2014 10:13 Go to previous message
koldo is currently offline  koldo
Messages: 3355
Registered: August 2008
Senior Veteran
Thank you. An additional advantage is to avoid memory leaks because of the exit().

Best regards
Iñaki
Previous Topic: Problem with FileBrowser
Next Topic: AES for sqlite database
Goto Forum:
  


Current Time: Thu Mar 28 22:07:20 CET 2024

Total time taken to generate the page: 0.01771 seconds