U++ framework
Do not panic. Ask here before giving up.

Home » Developing U++ » UppHub » [SysInfo - Improvement - Koldo] Better way to find distribution version & more
[SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #40951] Sun, 13 October 2013 00:11 Go to next message
Klugier is currently offline  Klugier
Messages: 1117
Registered: September 2012
Location: Poland, Kraków
Senior Contributor
Hello Koldo,

I found a better way to find distribution version. I have replace function "GetOsInfo_CheckLsb" to "GetOsInfoCheckRelease".

static bool GetOsInfoCheckRelease(String &distro, String &distVersion) {
	StringParse release;
	for (FindFile ff(AppendFileName("/etc/", "*-release")); ff; ff.Next())
		release += LoadFile_Safe(ff.GetPath());
	
	if (release.IsEmpty())
		return false;
	if (!release.GoAfter("DISTRIB_ID="))
		return false;				
	distro = release.GetText();
	if (distro.IsEmpty())
		return false;
	
	release.GoAfter_Init("VERSION=");
	distVersion = release.GetText();

	return true;
}


I enclose full source file with additional changes (SysInfo/os.cpp).

P.S.
Are you sure about this assignation "distro = ubuntu" or "distro=fedora" (Shouldn't it be "Ubuntu" or "Fedora")? BTW, my version uses big letter notation.

Sincerely,
Klugier
  • Attachment: os.cpp
    (Size: 14.29KB, Downloaded 656 times)


U++ - one framework to rule them all.
Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #40953 is a reply to message #40951] Sun, 13 October 2013 00:38 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3458
Registered: August 2008
Senior Veteran
Hello Klugier

Thank you for your work. Smile

You have changed:
- /etc/lsb-release with /etc/*-release
- DISTRIB_RELEASE= with VERSION=

Please send me the distros that you have tested.

About the lowercase, I think it is more standard to use "ubuntu" than "Ubuntu" and I hate the uppercases like "UBUNTU".


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

Following two lines of code are tricky:
for (FindFile ff(AppendFileName("/etc/", "*-release")); ff; ff.Next())
	release += LoadFile_Safe(ff.GetPath());

This means, that find all files, that have "release" chain in their names. File "lsb-release" dosen't contain full version information, so we need to scan other files with "release" in their names.

************************************************************ ************************************************************ **

Here is the output (Ubuntu 13.04):
DISTRIB_VERSION=13.04
VERSION=13.04, Raring Ringtail

VERSION can be replaced with VERSION_ID (And even DISTRIB_VERSION to ID):
VERSION_ID=13.04
ID=ubuntu
************************************************************ ************************************************************ **

You can type following command in your terminal: "cat /etc/*-release":
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=13.04
DISTRIB_CODENAME=raring
DISTRIB_DESCRIPTION="Ubuntu 13.04"
NAME="Ubuntu"
VERSION="13.04, Raring Ringtail"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 13.04"
VERSION_ID="13.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"


Personally, I think we can add more information about distribution to SysInfo.
************************************************************ ************************************************************ **

P.S.
I uploaded old file (It doesn't compile!!!).
*I enclose newer version with lowercase fix.

Sincerely,
Klugier
  • Attachment: os.cpp
    (Size: 14.31KB, Downloaded 712 times)


U++ - one framework to rule them all.

[Updated on: Sun, 13 October 2013 13:06]

Report message to a moderator

Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #40955 is a reply to message #40954] Sun, 13 October 2013 01:58 Go to previous messageGo to next message
Klugier is currently offline  Klugier
Messages: 1117
Registered: September 2012
Location: Poland, Kraków
Senior Contributor
Here is the final version of the function:
static bool GetOsInfoCheckRelease(String &distro, String &distVersion) 
{
	StringParse release;
	for (FindFile ff(AppendFileName("/etc/", "*-release")); ff; ff.Next())
		release += LoadFile_Safe(ff.GetPath());
	
	if (release.IsEmpty())
		return false;
	if (!release.GoAfter("DISTRIB_ID="))
		return false;	
	distro = ToLower(release.GetText());
	
	if (distro.IsEmpty())
		return false;
	
	release.GoAfter_Init("DISTRIB_RELEASE=");
	distVersion = release.GetText();

	return true;
}


I don't want to change current functionality, so i decided to stay with old qualifiers. In the future we can get more informations about distribution (with my extension). It is up to you.

P.S.
Moreover, you can change LoadFile_Safe function (Functions4U) to:
String LoadFile_Safe(const String& fileName);


insted of:

String LoadFile_Safe(String fileName);




U++ - one framework to rule them all.

[Updated on: Sun, 13 October 2013 13:06]

Report message to a moderator

Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #40956 is a reply to message #40955] Sun, 13 October 2013 16:40 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3458
Registered: August 2008
Senior Veteran
Hello Klugier

I have included

	for (FindFile ff("/etc/*-release"); ff; ff.Next())
		release += LoadFile_Safe(ff.GetPath());	
because it does not hurt.

However you have to imagine that this function has to work with many different distros, not only Ubuntu. You can see SysInfo testing here: http://www.ultimatepp.org/srcimp$SysInfo$SysInfo$en-us.html




Best regards
Iñaki
Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41001 is a reply to message #40956] Fri, 18 October 2013 22:32 Go to previous messageGo to next message
Klugier is currently offline  Klugier
Messages: 1117
Registered: September 2012
Location: Poland, Kraków
Senior Contributor
Hello Koldo,

Did you forget to add reference in LoadFile_Safe function? In my opinion declaration of this function should look like:

String LoadFile_Safe(const String& fileName);


* Negligible change which can increase memory performance of yours packages (Including SysInfo Razz)

Sincerely,
Klugier


U++ - one framework to rule them all.
Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41002 is a reply to message #41001] Sat, 19 October 2013 00:37 Go to previous messageGo to next message
Klugier is currently offline  Klugier
Messages: 1117
Registered: September 2012
Location: Poland, Kraków
Senior Contributor
Hello Koldo,

Moreover, I wrote better handling for measuring cpu temperature on GNU/Linux (POSIX?). Now, SysInfo should use "hwmon" when "acpi" fails. Let's look at code:
static double GetCpuTemperatureViaAcpi() 
{
	FindFile ff;
	if(ff.Search("/proc/acpi/thermal_zone/*")) {
		do {
			if (ff.IsDirectory()) {
				String name = ff.GetName();
				if (name != "." && name != "..") {
					StringParse str = LoadFile_Safe(AppendFileName(AppendFileName("/proc/acpi/thermal_zone", name), "temperature"));			
					str.GoAfter("temperature:");
					return str.GetDouble();
				}
			}
		} while(ff.Next());
	}
	
	return Null;
}

static double GetCpuTemperatureViaHwmon() 
{
	Vector <double> temps;
	for (FindFile ff(AppendFileName("/sys/class/hwmon/hwmon0/device", "*input")); ff; ff.Next()) {
		if (!ff.IsHidden()) {
			String temp = LoadFile_Safe(ff.GetPath());
			if (!temp.IsEmpty())
				temps.Add((double)StrInt(temp) / 1000.0);
		}
	}
	
	double sumTemps = 0.0;
	for (int i = 0; i < temps.GetCount(); i++)
		sumTemps += temps[i];
	
	if (!temps.IsEmpty())
		return sumTemps / (double)temps.GetCount();
	else
		return Null;
}

double GetCpuTemperature() 
{
	double temp = Null;
	
	if (temp == (double)Null) temp = GetCpuTemperatureViaAcpi();
	if (temp == (double)Null) temp = GetCpuTemperatureViaHwmon();
	
	return temp;
}


* in this case "static" means that function should be use only in file where it was declared.

P.S.
Toomorow, I will enclose source file with above improvement.

Sincerely,
Klugier


U++ - one framework to rule them all.

[Updated on: Sat, 19 October 2013 00:50]

Report message to a moderator

Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41007 is a reply to message #41002] Sat, 19 October 2013 22:29 Go to previous messageGo to next message
Klugier is currently offline  Klugier
Messages: 1117
Registered: September 2012
Location: Poland, Kraków
Senior Contributor
Hello Koldo,

BTW, I noticed that LoadFile_Safe function is really useful for system files (like hwmon files). What is not good in Core package is that LoadFile dosen't provides such functionality. I tried loading hwmon files using LoadFile function, but in this case it dosen't work. I think we should discuss transfer LoadFile_Safe (LoadFileSafe? or LoadSystemFile?) function to Ultimate++ mainstream package (Core). What do you think guys?

Sincerely,
Klugier


U++ - one framework to rule them all.
Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41009 is a reply to message #41007] Sun, 20 October 2013 10:00 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3458
Registered: August 2008
Senior Veteran
Hello Klugier

LoadSystemFile() could be a good name.

These files (many in Linux) cannot be opened by LoadFile because it is not possible to know their size in advance, they are like pipes.


Best regards
Iñaki
Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41010 is a reply to message #41002] Sun, 20 October 2013 10:04 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3458
Registered: August 2008
Senior Veteran
Hello Klugier

It seems good.

For me to check it, could you tell me some distros where acpi is not used and Hwmon is used?


Best regards
Iñaki
Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41014 is a reply to message #41002] Sun, 20 October 2013 12:36 Go to previous messageGo to next message
Zbych is currently offline  Zbych
Messages: 332
Registered: July 2009
Senior Member
klugier wrote on Sat, 19 October 2013 00:37


static double GetCpuTemperatureViaHwmon()
{
Vector <double> temps;
for (FindFile ff(AppendFileName("/sys/class/hwmon/hwmon0/device", "*input")); ff; ff.Next()) {



Unfortunately it will not work on all systems. I checked some computers in my office:
1. intel, ubuntu 12.04, kernel 3.2, temperature location: /sys/class/hwmon/hwmon0/temp1_input (no device sub-dir)
2. intel, ubuntu 12.04, kernel 3.8, temperature location: /sys/devices/platform/coretemp.0/temp*_input
3. AMD, ubuntu 12.04, kernel 3.2, temperature location: /sys/class/hwmon/hwmon0/device/temp1_input

Maybe we should check libsensors to find out how it locates cpu temperature files.
Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41030 is a reply to message #41014] Tue, 22 October 2013 16:24 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3458
Registered: August 2008
Senior Veteran
Hello Zbych

Following your advice I am checking it.


Best regards
Iñaki
Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41044 is a reply to message #41030] Wed, 23 October 2013 22:13 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3458
Registered: August 2008
Senior Veteran
Hello

There is a libsensors test in the beginning of SysInfo_demo_console.

Please run it and report the results (Do not forget to install libsensors before).

In my case they are:

LibSensors version: 3.3.2
Results:
Chip: acpitz-virtual-0
	temperature: temp1
		input(RM)	temp1_input = 47
		critical(RM)	temp1_crit = 104
Chip: coretemp-isa-0000
	temperature: Core 0
		input(RM)	temp2_input = 52
		max(RM)	temp2_max = 85
		critical(RM)	temp2_crit = 85
		crit alarm(R)	temp2_crit_alarm = 0
	temperature: Core 1
		input(RM)	temp3_input = 48
		max(RM)	temp3_max = 85
		critical(RM)	temp3_crit = 85
		crit alarm(R)	temp3_crit_alarm = 0


Best regards
Iñaki
Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41045 is a reply to message #41030] Wed, 23 October 2013 22:46 Go to previous messageGo to next message
Klugier is currently offline  Klugier
Messages: 1117
Registered: September 2012
Location: Poland, Kraków
Senior Contributor
Hello Koldo,

Koldo, please noticed that libsensor is GPL library. It means that all applications which are linking to SysInfo should also use GPL license. Only the latest version of libsensors use LGPL license. I do not think that people linking their programs with libsensors want to risk so much.

To use my trick with temperature you don't need to link with libsensors, beacuse I read only system file. In this way, you can also get more information about the computer sensors state. The main problem of this solution is how to find appropriate path on certain linux version.

More information about libsensors licence you can find on official site.

Sincerely,
Klugier


U++ - one framework to rule them all.

[Updated on: Thu, 24 October 2013 01:55]

Report message to a moderator

Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41076 is a reply to message #41045] Tue, 29 October 2013 18:52 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3458
Registered: August 2008
Senior Veteran
Oh! Although it is LGPL I think we can get the information by our means Smile.

libsensors is now removed from SysInfo.


Best regards
Iñaki

[Updated on: Tue, 29 October 2013 19:02]

Report message to a moderator

Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41078 is a reply to message #41076] Tue, 29 October 2013 22:19 Go to previous messageGo to next message
Klugier is currently offline  Klugier
Messages: 1117
Registered: September 2012
Location: Poland, Kraków
Senior Contributor
Hello Koldo,

Can you add also following if statement at the end of GetCpuTemperatureHWMON function? Dividing by zero can be painful. This situation can occur when hwmon subsystem does not exist!

	if (!temps.IsEmpty())
		return sumTemps / (double)temps.GetCount();
	else
		return Null;


P.S.
Now, I am looking for optimal path for hwmon.

Sincerley,
Klugier


U++ - one framework to rule them all.
Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41081 is a reply to message #41078] Wed, 30 October 2013 09:17 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3458
Registered: August 2008
Senior Veteran
Thank you Klugier

Quote:

Now, I am looking for optimal path for hwmon.

I was going to do this so thank you for relieving me of this duty.

About the division by zero, I think actual code avoids that possibility.


Best regards
Iñaki
Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41086 is a reply to message #41081] Wed, 30 October 2013 15:12 Go to previous messageGo to next message
Klugier is currently offline  Klugier
Messages: 1117
Registered: September 2012
Location: Poland, Kraków
Senior Contributor
Hello Koldo,

Quote:

About the division by zero, I think actual code avoids that possibility.


No it doesn't, cause
(double)temps.GetCount()
can return zero if input files don't exist!!!

Sincerely,
Klugier


U++ - one framework to rule them all.

[Updated on: Wed, 30 October 2013 15:12]

Report message to a moderator

Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41089 is a reply to message #41086] Wed, 30 October 2013 21:37 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3458
Registered: August 2008
Senior Veteran
Hello Klugier

I think there is a misunderstanding. See actual code:

static double GetCpuTemperatureHWMON() {
	Vector <double> temps;
	for (FindFile ff("/sys/class/hwmon/hwmon0/device/*input"); ff; ff.Next()) {
		if (!ff.IsHidden()) {
			String temp = LoadFile_Safe(ff.GetPath());
			if (!temp.IsEmpty())
				temps.Add((double)StrInt(temp) / 1000.0);
		}
	}
	if (temps.IsEmpty())
		return Null;
	double sumTemps = 0.;
	for (int i = 0; i < temps.GetCount(); i++)
		sumTemps += temps[i];
	
	return sumTemps/double(temps.GetCount());
}


Best regards
Iñaki
Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41091 is a reply to message #41089] Wed, 30 October 2013 22:16 Go to previous messageGo to next message
Klugier is currently offline  Klugier
Messages: 1117
Registered: September 2012
Location: Poland, Kraków
Senior Contributor
Hello Koldo,

Now, I see:
if (temps.IsEmpty())
   return Null;


I am sorry for the mess which i have made.

Sincerely,
Klugier


U++ - one framework to rule them all.

[Updated on: Wed, 30 October 2013 22:18]

Report message to a moderator

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: 3458
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: 1117
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: 3458
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: 1117
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: 3458
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: 1117
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: 3458
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: 3458
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: 1117
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: 3458
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: Sun Apr 26 01:52:51 GMT+2 2026

Total time taken to generate the page: 0.00862 seconds