 Clean up info_fbsd.cpp.
 Use libpci for pci access if possible - on FreeBSD it requires root
 privileges (rw access to /dev/pci), therefore leave old method
 as a fallback.
 Improve GetInfo_ReadfromPipe function to use Qt types, pass program name
 and its parameters as separate arguments.

--- /dev/null
+++ cmake/modules/FindBSDDevinfo.cmake
@@ -0,0 +1,15 @@
+# Find FreeBSD devinfo library
+# Once done this will define
+#
+#  BSDDEVINFO_FOUND - system has devinfo
+#  BSDDEVINFO_INCLUDE_DIR - devinfo include directory
+#  BSDDEVINFO_LIBRARY - devinfo library
+
+find_path(BSDDEVINFO_INCLUDE_DIR devinfo.h)
+
+find_library(BSDDEVINFO_LIBRARY NAMES devinfo)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(BSDDEVINFO DEFAULT_MSG BSDDEVINFO_LIBRARY BSDDEVINFO_INCLUDE_DIR)
+
+mark_as_advanced(BSDDEVINFO_INCLUDE_DIR BSDDEVINFO_LIBRARY)
--- kinfocenter/Modules/base/CMakeLists.txt
+++ kinfocenter/Modules/base/CMakeLists.txt
@@ -1,6 +1,7 @@
 # TODO: HAVE_LIBDEVINFO_H (for Solaris 7 and later)
 #   to be set if both -ldevinfo and libdevinfo.h exist
 
-check_include_files(devinfo.h HAVE_DEVINFO_H)       # info_fbsd.cpp
+macro_optional_find_package(BSDDevinfo) # info_fbsd.cpp
+macro_bool_to_01(BSDDEVINFO_FOUND HAVE_DEVINFO_H)
 
 configure_file (../base/config-infocenter.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-infocenter.h )
--- kinfocenter/Modules/base/info_fbsd.cpp.orig	2014-11-06 22:36:58.000000000 +0000
+++ kinfocenter/Modules/base/info_fbsd.cpp	2015-02-20 22:40:53.380666149 +0000
@@ -15,8 +15,6 @@
  */
 
 #include "config-infocenter.h" // HAVE_DEVINFO_H
-#include <sys/types.h>
-#include <sys/sysctl.h>
 
 #ifdef HAVE_DEVINFO_H
 extern "C" {
@@ -24,13 +22,16 @@
 }
 #endif
 
-#include <string.h>
+#ifdef HAVE_PCIUTILS
+#include "kpci.h"
+#endif
 
-#include <QMap>
 #include <QFileInfo>
-
+#include <QStringList>
 #include <QTextStream>
 
+#include <KGlobalSettings>
+
 void ProcessChildren(QString name);
 
 #ifdef HAVE_DEVINFO_H
@@ -44,13 +45,12 @@
 
 bool GetInfo_IRQ(QTreeWidget* tree) {
 #ifdef HAVE_DEVINFO_H
-	/* systat lists the interrupts assigned to devices as well as how many were
-	 generated.  Parsing its output however is about as fun as a sandpaper
-	 enema.  The best idea would probably be to rip out the guts of systat.
-	 Too bad it's not very well commented */
-	/* Oh neat, current now has a neat little utility called devinfo */
 	if (devinfo_init())
-	return false;
+		return false;
+
+	QStringList headers;
+	headers << i18n("IRQ") << i18n("Used By");
+	tree->setHeaderLabels(headers);
 	devinfo_foreach_rman(print_irq, tree);
 	return true;
 #else
@@ -60,9 +60,13 @@
 
 bool GetInfo_DMA(QTreeWidget* tree) {
 #ifdef HAVE_DEVINFO_H
-	/* Oh neat, current now has a neat little utility called devinfo */
 	if (devinfo_init())
-	return false;
+		return false;
+
+	QStringList headers;
+	headers << i18n("DMA-Channel") << i18n("Used By");
+	tree->setHeaderLabels(headers);
+
 	devinfo_foreach_rman(print_dma, tree);
 	return true;
 #else
@@ -72,9 +76,12 @@
 
 bool GetInfo_IO_Ports(QTreeWidget* tree) {
 #ifdef HAVE_DEVINFO_H
-	/* Oh neat, current now has a neat little utility called devinfo */
 	if (devinfo_init())
-	return false;
+		return false;
+
+	QStringList headers;
+	headers << i18n("I/O-Range") << i18n("Used By");
+	tree->setHeaderLabels(headers);
 	devinfo_foreach_rman(print_ioports, tree);
 	return true;
 #else
@@ -83,50 +90,28 @@
 }
 
 bool GetInfo_SCSI(QTreeWidget* tree) {
-	FILE *pipe;
-	QTextStream *t;
-	QString s;
-
 	if (!QFileInfo(QLatin1String("/sbin/camcontrol")).exists()) {
-		s = i18n("SCSI subsystem could not be queried: /sbin/camcontrol could not be found");
 		QStringList list;
-		list << s;
+		list << i18n("SCSI subsystem could not be queried: /sbin/camcontrol could not be found");
 		new QTreeWidgetItem(tree, list);
-	} else if ((pipe = popen("/sbin/camcontrol devlist 2>&1", "r")) == NULL) {
-		s = i18n("SCSI subsystem could not be queried: /sbin/camcontrol could not be executed");
-		QStringList list;
-		list << s;
-		new QTreeWidgetItem(tree, list);
-	} else {
-
-		/* This prints out a list of all the scsi devies, perhaps eventually we could
-		 parse it as opposed to schlepping it into a listbox */
-
-		t = new QTextStream(pipe, QIODevice::ReadOnly);
-
-		while (true) {
-			s = t->readLine();
-			if (s.isEmpty() )
-				break;
-			QStringList list;
-			list << s;
-			new QTreeWidgetItem(tree, list);
-		}
-
-		delete t;
-		pclose(pipe);
 	}
+	if (GetInfo_ReadfromPipe(tree, "/sbin/camcontrol", QStringList() << "devlist", true))
+		return true;
 
-	if (!tree->topLevelItemCount())
-		return false;
-
-	return true;
+	return false;
 }
 
 bool GetInfo_PCI(QTreeWidget* tree) {
-	FILE *pipe;
-	QString s, cmd;
-	QTreeWidgetItem *olditem= NULL;
+#ifdef HAVE_PCIUTILS
+// libpci exits immediately if /dev/pci can't be open in rw mode
+	QFile pcidev("/dev/pci");
+	if (pcidev.open(QIODevice::ReadWrite)) {
+		pcidev.close();
+		if ( GetInfo_PCIUtils(tree)) {
+			return true;
+		}
+	}
+#endif //HAVE_PCIUTILS
 
 	const QStringList headers(i18nc("@title:column Column name for PCI information", "Information"));
 	tree->setHeaderLabels(headers);
@@ -136,40 +121,11 @@
 		list << i18n("Could not find any programs with which to query your system's PCI information");
 		new QTreeWidgetItem(tree, list);
 		return true;
-	} else {
-		cmd = "/usr/sbin/pciconf -l -v 2>&1";
-	}
-
-	// TODO: GetInfo_ReadfromPipe should be improved so that we could pass the program name and its
-	//       arguments to it and remove most of the code below.
-	if ((pipe = popen(cmd.toLatin1(), "r")) == NULL) {
-		QStringList list;
-		list << i18n("PCI subsystem could not be queried: %1 could not be executed", cmd);
-		olditem = new QTreeWidgetItem(olditem, list);
-	} else {
-		/* This prints out a list of all the pci devies, perhaps eventually we could
-		 parse it as opposed to schlepping it into a listbox */
-		QTextStream outputStream(pipe, QIODevice::ReadOnly);
-
-		while (!outputStream.atEnd()) {
-			s = outputStream.readLine();
-			if (s.isEmpty() )
-				break;
-			const QStringList list(s);
-			new QTreeWidgetItem(tree, list);
-		}
-
-		pclose(pipe);
 	}
-
-	if (!tree->topLevelItemCount()) {
-		QString str = i18n("The PCI subsystem could not be queried, this may need root privileges.");
-		olditem = new QTreeWidgetItem(tree, olditem);
-		olditem->setText(0, str);
+	if (GetInfo_ReadfromPipe(tree, "/usr/sbin/pciconf", QStringList() << "-l" << "-v", true))
 		return true;
-	}
 
-	return true;
+	return false;
 }
 
 bool GetInfo_XServer_and_Video(QTreeWidget* tree) {
@@ -179,12 +135,7 @@
 #ifdef HAVE_DEVINFO_H
 
 int print_irq(struct devinfo_rman *rman, void *arg) {
-	QTreeWidget* tree = (QTreeWidget *)arg;
 	if (strcmp(rman->dm_desc, "Interrupt request lines")==0) {
-
-		QStringList list;
-		list << rman->dm_desc;
-		new QTreeWidgetItem(tree, list);
 		devinfo_foreach_rman_resource(rman, print_resource, arg);
 	}
 	return 0;
@@ -192,11 +143,7 @@
 
 int print_dma(struct devinfo_rman *rman, void *arg)
 {
-	QTreeWidget* tree = (QTreeWidget *)arg;
 	if (strcmp(rman->dm_desc, "DMA request lines")==0) {
-		QStringList list;
-		list << rman->dm_desc;
-		new QTreeWidgetItem(tree, list);
 		devinfo_foreach_rman_resource(rman, print_resource, arg);
 	}
 	return(0);
@@ -230,29 +177,25 @@
 	int hexmode;
 
 	QTreeWidget* tree = (QTreeWidget*) arg;
+	tree->setFont(KGlobalSettings::fixedFont());
+	QStringList list;
 
-	QString s, tmp;
+	QString s;
+	QTextStream result(&s);
 
 	rman = devinfo_handle_to_rman(res->dr_rman);
 	hexmode = (rman->dm_size > 100) || (rman->dm_size == 0);
-	tmp.sprintf(hexmode ? "0x%lx" : "%lu", res->dr_start);
-	s += tmp;
-	if (res->dr_size > 1) {
-		tmp.sprintf(hexmode ? "-0x%lx" : "-%lu",
-				res->dr_start + res->dr_size - 1);
-		s += tmp;
-	}
+	if (hexmode)
+		result << showbase << hex;
+	result << res->dr_start;
+	if (res->dr_size > 1)
+		result << "-" << res->dr_start + res->dr_size - 1;
+	list << s;
 
 	dev = devinfo_handle_to_device(res->dr_device);
-	if ((dev != NULL) && (dev->dd_name[0] != 0)) {
-		tmp.sprintf(" (%s)", dev->dd_name);
-	} else {
-		tmp.sprintf(" ----");
-	}
-	s += tmp;
+	if ((dev != NULL) && (dev->dd_name[0] != 0))
+		list << QString(dev->dd_name);
 
-	QStringList list;
-	list << s;
 	new QTreeWidgetItem(tree, list);
 
 	return 0;
--- kinfocenter/Modules/info/CMakeLists.txt
+++ kinfocenter/Modules/info/CMakeLists.txt
@@ -13,6 +13,9 @@ set(kcm_info_PART_SRCS main.cpp info.cpp ../base/os_current.cpp )
 kde4_add_plugin(kcm_info ${kcm_info_PART_SRCS})
 
 target_link_libraries(kcm_info  ${KDE4_KDEUI_LIBS} ${QT_QTGUI_LIBRARY} ${X11_X11_LIB})
+if(BSDDEVINFO_FOUND)
+	target_link_libraries(kcm_info ${BSDDEVINFO_LIBRARY})
+endif(BSDDEVINFO_FOUND)
 
 install(TARGETS kcm_info  DESTINATION ${PLUGIN_INSTALL_DIR} )
 
--- kinfocenter/Modules/base/info_hpux.cpp
+++ kinfocenter/Modules/base/info_hpux.cpp
@@ -30,6 +30,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include <stdlib.h>
 #include <QFile>
 #include <QFontMetrics>
+#include <QStringList>
 #include <QTextStream>
 
 #	define INFO_PCI			""	// Please, who know it ????
@@ -178,14 +179,14 @@ bool GetInfo_PCI(QTreeWidget* tree) {
 }
 
 bool GetInfo_IO_Ports(QListView *lBox) {
-	if (GetInfo_ReadfromPipe(lBox, INFO_IOPORTS_1, false))
+	if (GetInfo_ReadfromPipe(lBox, INFO_IOPORTS_1, QStringList(), false))
 		return true;
 	else
-		return GetInfo_ReadfromPipe(lBox, INFO_IOPORTS_2, false);
+		return GetInfo_ReadfromPipe(lBox, INFO_IOPORTS_2, QStringList(), false);
 }
 
 bool GetInfo_SCSI(QListView *lBox) {
-	return GetInfo_ReadfromPipe(lBox, INFO_DEVICES, false);
+	return GetInfo_ReadfromPipe(lBox, INFO_DEVICES, QStringList(), false);
 }
 /* Parts taken from fsusage.c from the Midnight Commander (mc)
 
--- kinfocenter/Modules/base/info_linux.cpp
+++ kinfocenter/Modules/base/info_linux.cpp
@@ -33,6 +33,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include <QRegExp>
 #include <QFile>
 #include <QHeaderView>
+#include <QStringList>
 
 #include <klocale.h>
 #include <kiconloader.h>
@@ -140,9 +141,12 @@ bool GetInfo_PCI(QTreeWidget* tree) {
 	tree->setSortingEnabled(false);
 
 	/* try to get the output of the lspci package first */
-	if ((num = GetInfo_ReadfromPipe(tree, "lspci -v", true)) || (num = GetInfo_ReadfromPipe(tree, "/sbin/lspci -v", true)) || (num = GetInfo_ReadfromPipe(tree, "/usr/sbin/lspci -v", true)) || (num = GetInfo_ReadfromPipe(tree, "/usr/local/sbin/lspci -v", true)) || (num = GetInfo_ReadfromPipe(tree,
-			"/usr/bin/lspci -v", true)))
-		return num;
+	QStringList lspci;
+	lspci << "lspci" << "/sbin/lspci" << "/usr/sbin/lspci" << "/usr/local/sbin/lspci" << "/usr/bin/lspci";
+	QString p;
+	foreach(p, lspci)
+		if (num = GetInfo_ReadfromPipe(tree, p, QStringList() << "-v", true))
+			return num;
 
 	/* if lspci failed, read the contents of /proc/pci */
 	return GetInfo_ReadfromFile(tree, INFO_PCI, 0);
--- kinfocenter/Modules/base/os_base.h
+++ kinfocenter/Modules/base/os_base.h
@@ -320,12 +320,12 @@ static bool GetInfo_XServer_Generic(QTreeWidget *lBox) {
 }
 
 /* Helper-function to read output from an external program */
-static int GetInfo_ReadfromPipe(QTreeWidget* tree, const char *FileName, bool WithEmptyLines = true) {
+static int GetInfo_ReadfromPipe(QTreeWidget* tree, const QString &program, const QStringList &arguments, bool WithEmptyLines = true) {
 	QProcess proc;
 	QTreeWidgetItem* olditem= NULL;
 	QString s;
 
-	proc.start(FileName, QIODevice::ReadOnly);
+	proc.start(program, arguments, QIODevice::ReadOnly);
 	if (!proc.waitForFinished()) {
 		// Process hanged or did not start
 		return 0;
