|
|
|
/*
|
|
|
|
* info_fbsd.cpp is part of the KDE program kcminfo. This displays
|
|
|
|
* various information about the system (hopefully a FreeBSD system)
|
|
|
|
* it's running on.
|
|
|
|
*
|
|
|
|
* All of the devinfo bits were blatantly stolen from the devinfo utility
|
|
|
|
* provided with FreeBSD 5.0 (and later). No gross hacks were harmed
|
|
|
|
* during the creation of info_fbsd.cpp. Thanks Mike.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define INFO_CPU_AVAILABLE
|
|
|
|
#define INFO_IRQ_AVAILABLE
|
|
|
|
#define INFO_DMA_AVAILABLE
|
|
|
|
#define INFO_PCI_AVAILABLE
|
|
|
|
#define INFO_IOPORTS_AVAILABLE
|
|
|
|
#define INFO_SOUND_AVAILABLE
|
|
|
|
#define INFO_DEVICES_AVAILABLE
|
|
|
|
#define INFO_SCSI_AVAILABLE
|
|
|
|
#define INFO_PARTITIONS_AVAILABLE
|
|
|
|
#define INFO_XSERVER_AVAILABLE
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* all following functions should return TRUE, when the Information
|
|
|
|
* was filled into the lBox-Widget. Returning FALSE indicates that
|
|
|
|
* information was not available.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include <config.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/sysctl.h>
|
|
|
|
|
|
|
|
//#if __FreeBSD_version >= 500042
|
|
|
|
// #define we should have devinfo.h
|
|
|
|
//#else
|
|
|
|
// #define we probably don't have devinfo.h
|
|
|
|
//#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_DEVINFO_H
|
|
|
|
extern "C" {
|
|
|
|
#include <devinfo.h>
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
#include <fstab.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <tqdict.h>
|
|
|
|
#include <tqfile.h>
|
|
|
|
#include <tqptrlist.h>
|
|
|
|
#include <tqstring.h>
|
|
|
|
#include <tqtextstream.h>
|
|
|
|
|
|
|
|
class Device {
|
|
|
|
public:
|
|
|
|
Device (TQString n=TQString::null, TQString d=TQString::null)
|
|
|
|
{name=n; description=d;}
|
|
|
|
TQString name, description;
|
|
|
|
};
|
|
|
|
|
|
|
|
void ProcessChildren(TQString name);
|
|
|
|
TQString GetController(const TQString &line);
|
|
|
|
Device *GetDevice(const TQString &line);
|
|
|
|
|
|
|
|
#ifdef HAVE_DEVINFO_H
|
|
|
|
extern "C" {
|
|
|
|
int print_irq(struct devinfo_rman *rman, void *arg);
|
|
|
|
int print_dma(struct devinfo_rman *rman, void *arg);
|
|
|
|
int print_ioports(struct devinfo_rman *rman, void *arg);
|
|
|
|
int print_resource(struct devinfo_res *res, void *arg);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
bool GetInfo_CPU (TQListView *lBox)
|
|
|
|
{
|
|
|
|
// Modified 13 July 2000 for SMP by Brad Hughes - bhughes@trolltech.com
|
|
|
|
|
|
|
|
int ncpu;
|
|
|
|
size_t len;
|
|
|
|
|
|
|
|
len = sizeof(ncpu);
|
|
|
|
sysctlbyname("hw.ncpu", &ncpu, &len, NULL, 0);
|
|
|
|
|
|
|
|
TQString cpustring;
|
|
|
|
for (int i = ncpu; i > 0; i--) {
|
|
|
|
/* Stuff for sysctl */
|
|
|
|
char *buf;
|
|
|
|
int i_buf;
|
|
|
|
|
|
|
|
// get the processor model
|
|
|
|
sysctlbyname("hw.model", NULL, &len, NULL, 0);
|
|
|
|
buf = new char[len];
|
|
|
|
sysctlbyname("hw.model", buf, &len, NULL, 0);
|
|
|
|
|
|
|
|
// get the TSC speed if we can
|
|
|
|
len = sizeof(i_buf);
|
|
|
|
if (sysctlbyname("machdep.tsc_freq", &i_buf, &len, NULL, 0) != -1) {
|
|
|
|
cpustring = i18n("CPU %1: %2, %3 MHz").arg(i).arg(buf).arg(i_buf/1000000);
|
|
|
|
} else {
|
|
|
|
cpustring = i18n("CPU %1: %2, unknown speed").arg(i).arg(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Put everything in the listbox */
|
|
|
|
new TQListViewItem(lBox, cpustring);
|
|
|
|
|
|
|
|
/* Clean up after ourselves, this time I mean it ;-) */
|
|
|
|
delete buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GetInfo_IRQ (TQListView *lbox)
|
|
|
|
{
|
|
|
|
#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;
|
|
|
|
devinfo_foreach_rman(print_irq, lbox);
|
|
|
|
return true;
|
|
|
|
#else
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GetInfo_DMA (TQListView *lbox)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_DEVINFO_H
|
|
|
|
/* Oh neat, current now has a neat little utility called devinfo */
|
|
|
|
if (devinfo_init())
|
|
|
|
return false;
|
|
|
|
devinfo_foreach_rman(print_dma, lbox);
|
|
|
|
return true;
|
|
|
|
#else
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GetInfo_IO_Ports (TQListView *lbox)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_DEVINFO_H
|
|
|
|
/* Oh neat, current now has a neat little utility called devinfo */
|
|
|
|
if (devinfo_init())
|
|
|
|
return false;
|
|
|
|
devinfo_foreach_rman(print_ioports, lbox);
|
|
|
|
return true;
|
|
|
|
#else
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GetInfo_Sound (TQListView *lbox)
|
|
|
|
{
|
|
|
|
TQFile *sndstat = new TQFile("/dev/sndstat");
|
|
|
|
TQTextStream *t;
|
|
|
|
TQString s;
|
|
|
|
TQListViewItem *olditem = 0;
|
|
|
|
|
|
|
|
if (!sndstat->exists() || !sndstat->open(IO_ReadOnly)) {
|
|
|
|
|
|
|
|
s = i18n("Your sound system could not be queried. /dev/sndstat does not exist or is not readable.");
|
|
|
|
olditem = new TQListViewItem(lbox, olditem, s);
|
|
|
|
} else {
|
|
|
|
t = new TQTextStream(sndstat);
|
|
|
|
while (!(s=t->readLine()).isNull()) {
|
|
|
|
olditem = new TQListViewItem(lbox, olditem, s);
|
|
|
|
}
|
|
|
|
|
|
|
|
delete t;
|
|
|
|
sndstat->close();
|
|
|
|
}
|
|
|
|
|
|
|
|
delete sndstat;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GetInfo_SCSI (TQListView *lbox)
|
|
|
|
{
|
|
|
|
FILE *pipe;
|
|
|
|
TQFile *camcontrol = new TQFile("/sbin/camcontrol");
|
|
|
|
TQTextStream *t;
|
|
|
|
TQString s;
|
|
|
|
TQListViewItem *olditem = 0;
|
|
|
|
|
|
|
|
if (!camcontrol->exists()) {
|
|
|
|
s = i18n ("SCSI subsystem could not be queried: /sbin/camcontrol could not be found");
|
|
|
|
olditem = new TQListViewItem(lbox, olditem, s);
|
|
|
|
} 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");
|
|
|
|
olditem = new TQListViewItem(lbox, olditem, s);
|
|
|
|
} 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 TQTextStream(pipe, IO_ReadOnly);
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
s = t->readLine();
|
|
|
|
if ( s.isEmpty() )
|
|
|
|
break;
|
|
|
|
olditem = new TQListViewItem(lbox, olditem, s);
|
|
|
|
}
|
|
|
|
|
|
|
|
delete t;
|
|
|
|
pclose(pipe);
|
|
|
|
}
|
|
|
|
|
|
|
|
delete camcontrol;
|
|
|
|
|
|
|
|
if (!lbox->childCount())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GetInfo_PCI (TQListView *lbox)
|
|
|
|
{
|
|
|
|
FILE *pipe;
|
|
|
|
TQFile *pcicontrol;
|
|
|
|
TQString s, cmd;
|
|
|
|
TQListViewItem *olditem = 0;
|
|
|
|
|
|
|
|
pcicontrol = new TQFile("/usr/sbin/pciconf");
|
|
|
|
|
|
|
|
if (!pcicontrol->exists()) {
|
|
|
|
delete pcicontrol;
|
|
|
|
pcicontrol = new TQFile("/usr/X11R6/bin/scanpci");
|
|
|
|
if (!pcicontrol->exists()) {
|
|
|
|
delete pcicontrol;
|
|
|
|
pcicontrol = new TQFile("/usr/X11R6/bin/pcitweak");
|
|
|
|
if (!pcicontrol->exists()) {
|
|
|
|
TQString s;
|
|
|
|
s = i18n("Could not find any programs with which to query your system's PCI information");
|
|
|
|
(void) new TQListViewItem(lbox, 0, s);
|
|
|
|
delete pcicontrol;
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
cmd = "/usr/X11R6/bin/pcitweak -l 2>&1";
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
cmd = "/usr/X11R6/bin/scanpci";
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
cmd = "/usr/sbin/pciconf -l -v 2>&1";
|
|
|
|
}
|
|
|
|
delete pcicontrol;
|
|
|
|
|
|
|
|
if ((pipe = popen(cmd.latin1(), "r")) == NULL) {
|
|
|
|
s = i18n ("PCI subsystem could not be queried: %1 could not be executed").arg(cmd);
|
|
|
|
olditem = new TQListViewItem(lbox, olditem, s);
|
|
|
|
} 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 */
|
|
|
|
|
|
|
|
pclose(pipe);
|
|
|
|
GetInfo_ReadfromPipe(lbox, cmd.latin1(), true);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!lbox->childCount()) {
|
|
|
|
s = i18n("The PCI subsystem could not be queried, this may need root privileges.");
|
|
|
|
olditem = new TQListViewItem(lbox, olditem, s);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GetInfo_Partitions (TQListView *lbox)
|
|
|
|
{
|
|
|
|
struct fstab *fstab_ent;
|
|
|
|
|
|
|
|
if (setfsent() != 1) /* Try to open fstab */ {
|
|
|
|
int s_err = errno;
|
|
|
|
TQString s;
|
|
|
|
s = i18n("Could not check filesystem info: ");
|
|
|
|
s += strerror(s_err);
|
|
|
|
(void)new TQListViewItem(lbox, 0, s);
|
|
|
|
} else {
|
|
|
|
lbox->addColumn(i18n("Device"));
|
|
|
|
lbox->addColumn(i18n("Mount Point"));
|
|
|
|
lbox->addColumn(i18n("FS Type"));
|
|
|
|
lbox->addColumn(i18n("Mount Options"));
|
|
|
|
|
|
|
|
while ((fstab_ent=getfsent())!=NULL) {
|
|
|
|
new TQListViewItem(lbox, fstab_ent->fs_spec,
|
|
|
|
fstab_ent->fs_file, fstab_ent->fs_vfstype,
|
|
|
|
fstab_ent->fs_mntops);
|
|
|
|
}
|
|
|
|
|
|
|
|
lbox->setSorting(0);
|
|
|
|
lbox->header()->setClickEnabled(true);
|
|
|
|
|
|
|
|
endfsent(); /* Close fstab */
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GetInfo_XServer_and_Video (TQListView *lBox)
|
|
|
|
{
|
|
|
|
return GetInfo_XServer_Generic( lBox );
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GetInfo_Devices (TQListView *lbox)
|
|
|
|
{
|
|
|
|
TQFile *f = new TQFile("/var/run/dmesg.boot");
|
|
|
|
if (f->open(IO_ReadOnly)) {
|
|
|
|
TQTextStream qts(f);
|
|
|
|
TQDict<TQListViewItem> lv_items;
|
|
|
|
Device *dev;
|
|
|
|
TQString line, controller;
|
|
|
|
lbox->setRootIsDecorated(true);
|
|
|
|
lbox->addColumn("Device");
|
|
|
|
lbox->addColumn("Description");
|
|
|
|
while ( !(line=qts.readLine()).isNull() ) {
|
|
|
|
controller = GetController(line);
|
|
|
|
if (controller.isNull())
|
|
|
|
continue;
|
|
|
|
dev=GetDevice(line);
|
|
|
|
if (!dev)
|
|
|
|
continue;
|
|
|
|
// Ewww assuing motherboard is the only toplevel controller is rather gross
|
|
|
|
if (controller == "motherboard") {
|
|
|
|
if (!lv_items[dev->name]) {
|
|
|
|
lv_items.insert(dev->name, new TQListViewItem(lbox, dev->name, dev->description) );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
TQListViewItem *parent=lv_items[controller];
|
|
|
|
if (parent && !lv_items[dev->name]) {
|
|
|
|
lv_items.insert(dev->name, new TQListViewItem(parent, dev->name, dev->description) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString GetController(const TQString &line)
|
|
|
|
{
|
|
|
|
if ( ( (line.startsWith("ad")) || (line.startsWith("afd")) || (line.startsWith("acd")) ) && (line.tqfind(":") < 6) ) {
|
|
|
|
TQString controller = line;
|
|
|
|
controller.remove(0, controller.tqfind(" at ")+4);
|
|
|
|
if (controller.tqfind("-slave") != -1) {
|
|
|
|
controller.remove(controller.tqfind("-slave"), controller.length());
|
|
|
|
} else if (controller.tqfind("-master") != -1) {
|
|
|
|
controller.remove(controller.tqfind("-master"), controller.length());
|
|
|
|
} else
|
|
|
|
controller=TQString::null;
|
|
|
|
if (!controller.isNull())
|
|
|
|
return controller;
|
|
|
|
}
|
|
|
|
if (line.tqfind(" on ") != -1) {
|
|
|
|
TQString controller;
|
|
|
|
controller = line;
|
|
|
|
controller.remove(0, controller.tqfind(" on ")+4);
|
|
|
|
if (controller.tqfind(" ") != -1)
|
|
|
|
controller.remove(controller.tqfind(" "), controller.length());
|
|
|
|
return controller;
|
|
|
|
}
|
|
|
|
return TQString::null;
|
|
|
|
}
|
|
|
|
|
|
|
|
Device *GetDevice(const TQString &line)
|
|
|
|
{
|
|
|
|
Device *dev;
|
|
|
|
int colon = line.tqfind(":");
|
|
|
|
if (colon == -1)
|
|
|
|
return 0;
|
|
|
|
dev = new Device;
|
|
|
|
dev->name = line.mid(0, colon);
|
|
|
|
dev->description = line.mid(line.tqfind("<")+1, line.length());
|
|
|
|
dev->description.remove(dev->description.tqfind(">"), dev->description.length());
|
|
|
|
return dev;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef HAVE_DEVINFO_H
|
|
|
|
|
|
|
|
int print_irq(struct devinfo_rman *rman, void *arg)
|
|
|
|
{
|
|
|
|
TQListView *lbox = (TQListView *)arg;
|
|
|
|
if (strcmp(rman->dm_desc, "Interrupt request lines")==0) {
|
|
|
|
(void)new TQListViewItem(lbox, 0, rman->dm_desc);
|
|
|
|
devinfo_foreach_rman_resource(rman, print_resource, arg);
|
|
|
|
}
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int print_dma(struct devinfo_rman *rman, void *arg)
|
|
|
|
{
|
|
|
|
TQListView *lbox = (TQListView *)arg;
|
|
|
|
if (strcmp(rman->dm_desc, "DMA request lines")==0) {
|
|
|
|
(void)new TQListViewItem(lbox, lbox->lastItem(), rman->dm_desc);
|
|
|
|
devinfo_foreach_rman_resource(rman, print_resource, arg);
|
|
|
|
}
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int print_ioports(struct devinfo_rman *rman, void *arg)
|
|
|
|
{
|
|
|
|
TQListView *lbox = (TQListView *)arg;
|
|
|
|
|
|
|
|
if (strcmp(rman->dm_desc, "I/O ports")==0) {
|
|
|
|
(void)new TQListViewItem(lbox, lbox->lastItem(), rman->dm_desc);
|
|
|
|
devinfo_foreach_rman_resource(rman, print_resource, arg);
|
|
|
|
}
|
|
|
|
else if (strcmp(rman->dm_desc, "I/O memory addresses")==0) {
|
|
|
|
(void)new TQListViewItem(lbox, lbox->lastItem(), rman->dm_desc);
|
|
|
|
devinfo_foreach_rman_resource(rman, print_resource, arg);
|
|
|
|
}
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int print_resource(struct devinfo_res *res, void *arg)
|
|
|
|
{
|
|
|
|
struct devinfo_dev *dev;
|
|
|
|
struct devinfo_rman *rman;
|
|
|
|
int hexmode;
|
|
|
|
|
|
|
|
TQListView *lbox;
|
|
|
|
|
|
|
|
lbox = (TQListView *)arg;
|
|
|
|
|
|
|
|
TQString s, tmp;
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
(void)new TQListViewItem(lbox, lbox->lastItem(), s);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|