| 
 | 
 | 
 
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 #41109 is a reply to message #41093] | 
			Thu, 31 October 2013 17:01    | 
		 
		
			
				
				
				  | 
					
						  
						Klugier
						 Messages: 1106 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 #41122 is a reply to message #41121] | 
			Fri, 01 November 2013 23:37    | 
		 
		
			
				
				
				  | 
					
						  
						Klugier
						 Messages: 1106 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 #43154 is a reply to message #41091] | 
			Tue, 20 May 2014 12:59    | 
		 
		
			
				
				
				
					
						  
						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 #43374 is a reply to message #43155] | 
			Mon, 14 July 2014 10:26    | 
		 
		
			
				
				
				
					
						  
						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 ); 
			
		
		
		
 |  
	| 
		
	 | 
 
 
 |  
	
		
		
			| 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    | 
		 
		
			
				
				
				
					
						  
						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  
		
		
		
 |  
	| 
		
	 | 
 
 
 |  
	| 
		
 |  
	| 
		
 |  
	| 
		
 |   
Goto Forum:
 
 Current Time: Tue Nov 04 02:42:41 CET 2025 
 Total time taken to generate the page: 0.05958 seconds 
 |   
 |  
  |