You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
458 lines
12 KiB
458 lines
12 KiB
15 years ago
|
/*
|
||
|
* 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 <qdict.h>
|
||
|
#include <qfile.h>
|
||
|
#include <qptrlist.h>
|
||
|
#include <qstring.h>
|
||
|
#include <qtextstream.h>
|
||
|
|
||
|
class Device {
|
||
|
public:
|
||
|
Device (QString n=QString::null, QString d=QString::null)
|
||
|
{name=n; description=d;}
|
||
|
QString name, description;
|
||
|
};
|
||
|
|
||
|
void ProcessChildren(QString name);
|
||
|
QString GetController(const QString &line);
|
||
|
Device *GetDevice(const QString &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 (QListView *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);
|
||
|
|
||
|
QString 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 QListViewItem(lBox, cpustring);
|
||
|
|
||
|
/* Clean up after ourselves, this time I mean it ;-) */
|
||
|
delete buf;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool GetInfo_IRQ (QListView *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 (QListView *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 (QListView *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 (QListView *lbox)
|
||
|
{
|
||
|
QFile *sndstat = new QFile("/dev/sndstat");
|
||
|
QTextStream *t;
|
||
|
QString s;
|
||
|
QListViewItem *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 QListViewItem(lbox, olditem, s);
|
||
|
} else {
|
||
|
t = new QTextStream(sndstat);
|
||
|
while (!(s=t->readLine()).isNull()) {
|
||
|
olditem = new QListViewItem(lbox, olditem, s);
|
||
|
}
|
||
|
|
||
|
delete t;
|
||
|
sndstat->close();
|
||
|
}
|
||
|
|
||
|
delete sndstat;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool GetInfo_SCSI (QListView *lbox)
|
||
|
{
|
||
|
FILE *pipe;
|
||
|
QFile *camcontrol = new QFile("/sbin/camcontrol");
|
||
|
QTextStream *t;
|
||
|
QString s;
|
||
|
QListViewItem *olditem = 0;
|
||
|
|
||
|
if (!camcontrol->exists()) {
|
||
|
s = i18n ("SCSI subsystem could not be queried: /sbin/camcontrol could not be found");
|
||
|
olditem = new QListViewItem(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 QListViewItem(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 QTextStream(pipe, IO_ReadOnly);
|
||
|
|
||
|
while (true) {
|
||
|
s = t->readLine();
|
||
|
if ( s.isEmpty() )
|
||
|
break;
|
||
|
olditem = new QListViewItem(lbox, olditem, s);
|
||
|
}
|
||
|
|
||
|
delete t;
|
||
|
pclose(pipe);
|
||
|
}
|
||
|
|
||
|
delete camcontrol;
|
||
|
|
||
|
if (!lbox->childCount())
|
||
|
return false;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool GetInfo_PCI (QListView *lbox)
|
||
|
{
|
||
|
FILE *pipe;
|
||
|
QFile *pcicontrol;
|
||
|
QString s, cmd;
|
||
|
QListViewItem *olditem = 0;
|
||
|
|
||
|
pcicontrol = new QFile("/usr/sbin/pciconf");
|
||
|
|
||
|
if (!pcicontrol->exists()) {
|
||
|
delete pcicontrol;
|
||
|
pcicontrol = new QFile("/usr/X11R6/bin/scanpci");
|
||
|
if (!pcicontrol->exists()) {
|
||
|
delete pcicontrol;
|
||
|
pcicontrol = new QFile("/usr/X11R6/bin/pcitweak");
|
||
|
if (!pcicontrol->exists()) {
|
||
|
QString s;
|
||
|
s = i18n("Could not find any programs with which to query your system's PCI information");
|
||
|
(void) new QListViewItem(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 QListViewItem(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 QListViewItem(lbox, olditem, s);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool GetInfo_Partitions (QListView *lbox)
|
||
|
{
|
||
|
struct fstab *fstab_ent;
|
||
|
|
||
|
if (setfsent() != 1) /* Try to open fstab */ {
|
||
|
int s_err = errno;
|
||
|
QString s;
|
||
|
s = i18n("Could not check filesystem info: ");
|
||
|
s += strerror(s_err);
|
||
|
(void)new QListViewItem(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 QListViewItem(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 (QListView *lBox)
|
||
|
{
|
||
|
return GetInfo_XServer_Generic( lBox );
|
||
|
}
|
||
|
|
||
|
bool GetInfo_Devices (QListView *lbox)
|
||
|
{
|
||
|
QFile *f = new QFile("/var/run/dmesg.boot");
|
||
|
if (f->open(IO_ReadOnly)) {
|
||
|
QTextStream qts(f);
|
||
|
QDict<QListViewItem> lv_items;
|
||
|
Device *dev;
|
||
|
QString 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 QListViewItem(lbox, dev->name, dev->description) );
|
||
|
}
|
||
|
} else {
|
||
|
QListViewItem *parent=lv_items[controller];
|
||
|
if (parent && !lv_items[dev->name]) {
|
||
|
lv_items.insert(dev->name, new QListViewItem(parent, dev->name, dev->description) );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
QString GetController(const QString &line)
|
||
|
{
|
||
|
if ( ( (line.startsWith("ad")) || (line.startsWith("afd")) || (line.startsWith("acd")) ) && (line.find(":") < 6) ) {
|
||
|
QString controller = line;
|
||
|
controller.remove(0, controller.find(" at ")+4);
|
||
|
if (controller.find("-slave") != -1) {
|
||
|
controller.remove(controller.find("-slave"), controller.length());
|
||
|
} else if (controller.find("-master") != -1) {
|
||
|
controller.remove(controller.find("-master"), controller.length());
|
||
|
} else
|
||
|
controller=QString::null;
|
||
|
if (!controller.isNull())
|
||
|
return controller;
|
||
|
}
|
||
|
if (line.find(" on ") != -1) {
|
||
|
QString controller;
|
||
|
controller = line;
|
||
|
controller.remove(0, controller.find(" on ")+4);
|
||
|
if (controller.find(" ") != -1)
|
||
|
controller.remove(controller.find(" "), controller.length());
|
||
|
return controller;
|
||
|
}
|
||
|
return QString::null;
|
||
|
}
|
||
|
|
||
|
Device *GetDevice(const QString &line)
|
||
|
{
|
||
|
Device *dev;
|
||
|
int colon = line.find(":");
|
||
|
if (colon == -1)
|
||
|
return 0;
|
||
|
dev = new Device;
|
||
|
dev->name = line.mid(0, colon);
|
||
|
dev->description = line.mid(line.find("<")+1, line.length());
|
||
|
dev->description.remove(dev->description.find(">"), dev->description.length());
|
||
|
return dev;
|
||
|
}
|
||
|
|
||
|
#ifdef HAVE_DEVINFO_H
|
||
|
|
||
|
int print_irq(struct devinfo_rman *rman, void *arg)
|
||
|
{
|
||
|
QListView *lbox = (QListView *)arg;
|
||
|
if (strcmp(rman->dm_desc, "Interrupt request lines")==0) {
|
||
|
(void)new QListViewItem(lbox, 0, rman->dm_desc);
|
||
|
devinfo_foreach_rman_resource(rman, print_resource, arg);
|
||
|
}
|
||
|
return(0);
|
||
|
}
|
||
|
|
||
|
int print_dma(struct devinfo_rman *rman, void *arg)
|
||
|
{
|
||
|
QListView *lbox = (QListView *)arg;
|
||
|
if (strcmp(rman->dm_desc, "DMA request lines")==0) {
|
||
|
(void)new QListViewItem(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)
|
||
|
{
|
||
|
QListView *lbox = (QListView *)arg;
|
||
|
|
||
|
if (strcmp(rman->dm_desc, "I/O ports")==0) {
|
||
|
(void)new QListViewItem(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 QListViewItem(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;
|
||
|
|
||
|
QListView *lbox;
|
||
|
|
||
|
lbox = (QListView *)arg;
|
||
|
|
||
|
QString 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 QListViewItem(lbox, lbox->lastItem(), s);
|
||
|
return(0);
|
||
|
}
|
||
|
|
||
|
#endif
|