/* * 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.find(":") < 6) ) { TQString 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=TQString::null; if (!controller.isNull()) return controller; } if (line.find(" on ") != -1) { TQString controller; controller = line; controller.remove(0, controller.find(" on ")+4); if (controller.find(" ") != -1) controller.remove(controller.find(" "), controller.length()); return controller; } return TQString::null; } Device *GetDevice(const TQString &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) { 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