diff options
Diffstat (limited to 'ksim/monitors')
103 files changed, 14906 insertions, 0 deletions
diff --git a/ksim/monitors/Makefile.am b/ksim/monitors/Makefile.am new file mode 100644 index 0000000..7e5c863 --- /dev/null +++ b/ksim/monitors/Makefile.am @@ -0,0 +1,9 @@ +if supports_i8k +i8k_SUBDIR = i8k +endif + +if include_ksim_monitors_snmp +SNMP_SUBDIR = snmp +endif + +SUBDIRS = filesystem net lm_sensors cpu disk $(i8k_SUBDIR) $(SNMP_SUBDIR) diff --git a/ksim/monitors/cpu/Makefile.am b/ksim/monitors/cpu/Makefile.am new file mode 100644 index 0000000..beaebd2 --- /dev/null +++ b/ksim/monitors/cpu/Makefile.am @@ -0,0 +1,16 @@ +kde_module_LTLIBRARIES = ksim_cpu.la +ksim_cpu_la_SOURCES = ksimcpu.cpp + +ksim_cpu_la_LIBADD = ../../library/libksimcore.la +ksim_cpu_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) + +EXTRA_DIST = cpu.desktop + +INCLUDES= -I$(top_srcdir)/ksim/library \ + $(all_includes) + +METASOURCES = AUTO +KDE_ICON = AUTO + +mon_DATA = cpu.desktop +mondir = $(kde_datadir)/ksim/monitors diff --git a/ksim/monitors/cpu/cpu.desktop b/ksim/monitors/cpu/cpu.desktop new file mode 100644 index 0000000..c8130ec --- /dev/null +++ b/ksim/monitors/cpu/cpu.desktop @@ -0,0 +1,94 @@ +[Desktop Entry] +Icon=ksim_cpu +Name=CPU +Name[af]=Sve +Name[ar]=وحدة المعالجة المركزية +Name[bg]=Процесори +Name[cs]=Procesor +Name[el]=KME +Name[eo]=Procezilo +Name[fa]=واحد پردازش مرکزی +Name[fr]=Processeur +Name[he]=מעבד +Name[hi]=सीपीयू +Name[hr]=Procesor +Name[is]=Örgjörvi +Name[kk]=Процессор +Name[mk]=Процесор +Name[pl]=procesor +Name[ru]=Процессор +Name[sk]=Procesor +Name[sl]=CPE +Name[sv]=Processor +Name[ta]= சிபியு +Name[tg]=ВПМ +Name[th]=ซีพียู +Name[tr]=İşlemci +Name[uk]=ЦП +Name[uz]=Protsessor +Name[uz@cyrillic]=Процессор +Name[wa]=Processeu +Comment=CPU Monitor Plugin +Comment[af]=Sve Monitor Inplak +Comment[ar]=ملحق مراقبة وحدة المعالجة المركزيّة +Comment[bg]=Мониторинг на процесора(ите) +Comment[bs]=Dodatak za nadzor CPUa +Comment[ca]=Monitor de CPU +Comment[cs]=Modul pro monitorování procesoru +Comment[cy]=Atodyn Monitro CPU +Comment[da]=CPU-overvågnings-plugin +Comment[de]=CPU-Nutzungsanzeige +Comment[el]=Πρόσθετο εποπτείας KME +Comment[eo]=Prozecilo-observila kromaĵo +Comment[es]=Extensión de monitorización de la CPU +Comment[et]=Protsessori monitooring +Comment[eu]=CPU Plugin Begiralea +Comment[fa]=وصلۀ نمایشگر واحد پردازش مرکزی +Comment[fi]=Suorittimentarkkailusovelma +Comment[fr]=Module de surveillance du processeur +Comment[ga]=Breiseán Monatóireachta LAP +Comment[he]=תוסף צג מעבד +Comment[hi]=सीपीयू मॉनीटर प्लगइन +Comment[hu]=CPU-figyelő bővítőmodul +Comment[is]=Örgjörva eftirlitsíforrit +Comment[it]=Plugin di controllo CPU +Comment[ja]=CPU モニタプラグイン +Comment[ka]= პროცესორის მონიტორის მოდული +Comment[kk]=Процессорды бақылау модулі +Comment[km]=កម្មវិធីជំនួយនៃកម្មវិធីត្រួតពិនិត្យថាស CPU Monitor +Comment[lt]=CPU stebėtojo priedas +Comment[mk]=Приклучок за следење на процесорот +Comment[ms]=Plug masuk Pemerhati CPU +Comment[nb]=Programtillegg for CPU-overvåkning +Comment[nds]=CPU-Kiekmoduul +Comment[ne]=CPU मोनिटर प्लगइन +Comment[nl]=CPU monitor-plugin +Comment[nn]=Programtillegg for CPU-overvaking +Comment[pa]=CPU ਨਿਗਰਾਨੀ ਪਲੱਗਿੰਨ +Comment[pl]=Stan procesora +Comment[pt]='Plugin' de monitorização do processador +Comment[pt_BR]=Plug-in de monitoramento da CPU +Comment[ro]=Modul monitorizare CPU +Comment[ru]=Монитор процессора +Comment[sk]=Modul pre monitorovanie CPU +Comment[sl]=Vstavek za opazovanje stanja CPE +Comment[sr]=Прикључак за надгледање CPU-а +Comment[sr@Latn]=Priključak za nadgledanje CPU-a +Comment[sv]=Insticksprogram för processoraktivitet +Comment[ta]= சிபியு கண்காணி சொருகுப்பொருள் +Comment[tg]=Модули Дидабони ВПМ +Comment[th]=ปลั๊กอินสอดส่องซีพียู +Comment[tr]=İşlemci İzleyici Eklentisi +Comment[uk]=Втулок датчика ЦП +Comment[uz]=Protsessorni nazorat qilish plagini +Comment[uz@cyrillic]=Процессорни назорат қилиш плагини +Comment[wa]=Tchôke-divins di corwaitaedje do CPU +Comment[xh]=Iplagi yangaphakathi ye Monitor CPU +Comment[zh_CN]=CPU 监视器插件 +Comment[zh_TW]=CPU 監視器外掛程式 +Comment[zu]=I-plugin Yomlawuli we-CPU +X-KSIM-VERSION=0.1 +X-KSIM-LIBRARY=cpu +X-KSIM-AUTHOR=Robbie Ward +X-KSIM-EMAIL=linuxphreak@gmx.co.uk +X-KSIM-COPYRIGHT=(C) 2001 Robbie Ward diff --git a/ksim/monitors/cpu/cr16-device-ksim_cpu.png b/ksim/monitors/cpu/cr16-device-ksim_cpu.png Binary files differnew file mode 100644 index 0000000..c9d8d08 --- /dev/null +++ b/ksim/monitors/cpu/cr16-device-ksim_cpu.png diff --git a/ksim/monitors/cpu/ksimcpu.cpp b/ksim/monitors/cpu/ksimcpu.cpp new file mode 100644 index 0000000..9e6d089 --- /dev/null +++ b/ksim/monitors/cpu/ksimcpu.cpp @@ -0,0 +1,514 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "ksimcpu.h" +#include "ksimcpu.moc" + +#include <qtextstream.h> +#include <qregexp.h> +#include <qlayout.h> +#include <qtimer.h> +#include <qfile.h> +#include <qgroupbox.h> +#include <qlabel.h> +#include <qglobal.h> +#include <qpushbutton.h> + +#include <klistview.h> +#include <kdebug.h> +#include <kaboutapplication.h> +#include <kaboutdata.h> +#include <klocale.h> +#include <kglobal.h> +#include <kconfig.h> +#include <kapplication.h> +#include <kinputdialog.h> + +#include <themetypes.h> + +#ifdef Q_OS_BSD4 +#include <sys/param.h> +#if defined(__DragonFly__) +#include <kinfo.h> +#include <err.h> +#include <sys/time.h> +#include <sys/resource.h> + +#elif defined Q_OS_FREEBSD +#if __FreeBSD_version < 500101 +#include <sys/dkstat.h> +#else +#include <sys/resource.h> +#endif +#else +#include <sys/dkstat.h> +#endif +#include <sys/sysctl.h> +#include <string.h> +#include <kvm.h> +#ifdef Q_OS_NETBSD +#include <sys/sched.h> +#endif +#endif + +#define CPU_NAME(cpu) "Cpu" + QString::number(cpu) + "_options" +#define CPU_SPEED 1000 + +KSIM_INIT_PLUGIN(CpuPlugin) + +CpuPlugin::CpuPlugin(const char *name) + : KSim::PluginObject(name) +{ + setConfigFileName(instanceName()); +} + +CpuPlugin::~CpuPlugin() +{ +} + +KSim::PluginView *CpuPlugin::createView(const char *className) +{ + return new CpuView(this, className); +} + +KSim::PluginPage *CpuPlugin::createConfigPage(const char *className) +{ + return new CpuConfig(this, className); +} + +void CpuPlugin::showAbout() +{ + QString version = kapp->aboutData()->version(); + + KAboutData aboutData(instanceName(), + I18N_NOOP("KSim CPU Plugin"), version.latin1(), + I18N_NOOP("A cpu monitor plugin for KSim"), + KAboutData::License_GPL, "(C) 2001 Robbie Ward"); + + aboutData.addAuthor("Robbie Ward", I18N_NOOP("Author"), + "linuxphreak@gmx.co.uk"); + + KAboutApplication(&aboutData).exec(); +} + +CpuView::CpuView(KSim::PluginObject *parent, const char *name) + : KSim::PluginView(parent, name) +{ +#ifdef Q_OS_LINUX + m_procStream = 0L; + if ((m_procFile = fopen("/proc/stat", "r"))) + m_procStream = new QTextStream(m_procFile, IO_ReadOnly); +#endif + + m_mainLayout = new QVBoxLayout(this); + QSpacerItem *item = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding); + m_mainLayout->addItem(item); + + m_firstTime = true; + + m_cpus = createList(); + addDisplay(); + + m_timer = new QTimer(this); + connect(m_timer, SIGNAL(timeout()), SLOT(updateView())); + m_timer->start(CPU_SPEED); + updateView(); +} + +CpuView::~CpuView() +{ +#ifdef Q_OS_LINUX + delete m_procStream; + + if (m_procFile) + fclose(m_procFile); +#endif + + cleanup(m_cpus); +} + +void CpuView::reparseConfig() +{ + CpuList cpus = createList(); + if (m_cpus != cpus) { + if (m_timer->isActive()) + m_timer->stop(); + + cleanup(m_cpus); + m_cpus = cpus; + addDisplay(); + m_timer->start(CPU_SPEED); + } +} + +void CpuView::updateView() +{ + if (m_cpus.isEmpty()) + return; + + CpuList::Iterator it; + for (it = m_cpus.begin(); it != m_cpus.end(); ++it) { + Cpu ¤t = (*it); + CpuData cpuData; + updateCpu(cpuData, current.number()); + + QString text = current.format(); + current.setData(cpuData); + cpuData -= current.oldData(); + int cpuDiff = 0; + int total = cpuData.sys + cpuData.user + cpuData.nice + cpuData.idle; + +// kdDebug(2003) << "name = " << cpuData.name << endl; +// kdDebug(2003) << "user = " << cpuData.user << endl; +// kdDebug(2003) << "nice = " << cpuData.nice << endl; +// kdDebug(2003) << "sys = " << cpuData.sys << endl; +// kdDebug(2003) << "idle = " << cpuData.idle << endl; + + if (!m_firstTime) { + if (text.find("%T") != -1) + cpuDiff = cpuData.sys + cpuData.user + cpuData.nice; + else if (text.find("%t") != -1) + cpuDiff = cpuData.sys + cpuData.user; + else if (text.find("%s") != -1) + cpuDiff = cpuData.sys; + else if (text.find("%u") != -1) + cpuDiff = cpuData.user; + else if (text.find("%n") != -1) + cpuDiff = cpuData.nice; + + cpuDiff *= 100; + + if ( total > 0 ) + cpuDiff /= total; + + if (cpuDiff > 100) + cpuDiff = 100; + } + + current.chart()->setText(i18n("%1%").arg(cpuDiff)); + current.chart()->setValue(cpuDiff, 0); + current.label()->setValue(cpuDiff); + } + + m_firstTime = false; +} + +void CpuView::updateCpu(CpuData &cpu, int cpuNumber) +{ +#ifdef Q_OS_LINUX + if (!m_procStream) + return; + + bool cpuFound = false; + QString output; + QString parser; + QString cpuString; + cpuString.setNum(cpuNumber).prepend("cpu"); + + // Parse the proc file + while (!m_procStream->atEnd()) { + parser = m_procStream->readLine(); + // remove all the entries apart from the line containing 'cpuString' + if (!cpuFound && parser.find(QRegExp(cpuString)) != -1) { + output = parser; + cpuFound = true; + } + } + + QStringList cpuList = QStringList::split(' ', output); + + if (!cpuList.isEmpty()) { + cpu.name = cpuList[0].stripWhiteSpace(); + cpu.user = cpuList[1].toULong(); + cpu.nice = cpuList[2].toULong(); + cpu.sys = cpuList[3].toULong(); + cpu.idle = cpuList[4].toULong(); + } + + fseek(m_procFile, 0L, SEEK_SET); +#endif + +#ifdef __DragonFly__ + struct kinfo_cputime cp_time; + if (kinfo_get_sched_cputime(&cp_time)) + err(1, "kinfo_get_sched_cputime"); + cpu.user = cp_time.cp_user; + cpu.nice = cp_time.cp_nice; + cpu.sys = cp_time.cp_sys; + cpu.idle = cp_time.cp_idle; +#elif defined(Q_OS_FREEBSD) +#warning "add support for SMP on FreeBSD" + Q_UNUSED(cpuNumber); + static int name2oid[2] = { 0, 3 }; + static int oidCpuTime[CTL_MAXNAME + 2]; + static size_t oidCpuTimeLen = sizeof(oidCpuTime); + long cpuTime[CPUSTATES]; + size_t cpuTimeLen = sizeof(cpuTime); + static char name[] = "kern.cp_time"; + static int initialized = 0; + + if (!initialized) { + if (sysctl(name2oid, 2, oidCpuTime, &oidCpuTimeLen, + name, strlen(name)) < 0) + return; + + oidCpuTimeLen /= sizeof(int); + initialized = 1; + } + + if (sysctl(oidCpuTime, oidCpuTimeLen, + cpuTime, &cpuTimeLen, 0, 0) < 0) + return; + + cpu.user = cpuTime[CP_USER]; + cpu.nice = cpuTime[CP_NICE]; + cpu.sys = cpuTime[CP_SYS]; + cpu.idle = cpuTime[CP_IDLE]; +#endif + +#if defined(Q_OS_NETBSD) +#define KERN_CPTIME KERN_CP_TIME +#endif +#if defined(Q_OS_OPENBSD) || defined(Q_OS_NETBSD) +//#warning "add support for SMP on OpenBSD and NetBSD" + int name2oid[2] = { CTL_KERN, KERN_CPTIME }; + long cpuTime[CPUSTATES]; + size_t cpuTimeLen = sizeof(cpuTime); + + if (sysctl(name2oid, 2, &cpuTime, &cpuTimeLen, + 0, 0) < 0) + return; + + cpu.user = cpuTime[CP_USER]; + cpu.nice = cpuTime[CP_NICE]; + cpu.sys = cpuTime[CP_SYS]; + cpu.idle = cpuTime[CP_IDLE]; +#endif +} + +CpuView::CpuList CpuView::createList() +{ + config()->setGroup("CpuPlugin"); + CpuList list; + + int number = 0; + QStringList cpus = config()->readListEntry("Cpus"); + QStringList::ConstIterator it; + for (it = cpus.begin(); it != cpus.end(); ++it) { + list.append(Cpu((*it), config()->readEntry(CPU_NAME(number), + "%T"), number)); + + ++number; + } + + return list; +} + +void CpuView::addDisplay() +{ + CpuList::Iterator it; + for (it = m_cpus.begin(); it != m_cpus.end(); ++it) { + KSim::Progress *progress = addLabel(); + KSim::Chart *chart = addChart(); + //KSim::Progress *progress = addLabel(); + + (*it).setDisplay(chart, progress); + } +} + +void CpuView::cleanup(CpuList &list) +{ + CpuList::Iterator it; + for (it = list.begin(); it != list.end(); ++it) + (*it).cleanup(); + + list.clear(); +} + +KSim::Chart *CpuView::addChart() +{ + KSim::Chart *chart = new KSim::Chart(false, 0, this); + chart->show(); + m_mainLayout->addWidget(chart); + + return chart; +} + +KSim::Progress *CpuView::addLabel() +{ + KSim::Progress *progress = new KSim::Progress(100, + KSim::Types::None, KSim::Progress::Panel, this); + + progress->show(); + m_mainLayout->addWidget(progress); + + return progress; +} + +CpuConfig::CpuConfig(KSim::PluginObject *parent, const char *name) + : KSim::PluginPage(parent, name) +{ + QVBoxLayout * mainLayout = new QVBoxLayout( this ); + mainLayout->setSpacing( 6 ); + + m_listView = new KListView(this); + m_listView->addColumn(i18n("Available CPUs")); + m_listView->addColumn(i18n("Chart Format")); + m_listView->setAllColumnsShowFocus(true); + m_listView->setSelectionMode(QListView::Single); + connect( m_listView, SIGNAL( doubleClicked( QListViewItem * ) ), + SLOT( modify( QListViewItem * ) ) ); + + mainLayout->addWidget( m_listView ); + + QHBoxLayout * layout = new QHBoxLayout; + layout->setSpacing( 6 ); + + QSpacerItem * spacer = new QSpacerItem( 20, 20, + QSizePolicy::Expanding, QSizePolicy::Minimum ); + layout->addItem(spacer); + + m_modify = new QPushButton( this ); + m_modify->setText( i18n( "Modify..." ) ); + connect( m_modify, SIGNAL( clicked() ), SLOT( modify() ) ); + layout->addWidget( m_modify ); + mainLayout->addLayout( layout ); + + m_legendBox = new QGroupBox(this); + m_legendBox->setColumnLayout(0, Qt::Vertical); + m_legendBox->setTitle(i18n("Chart Legend")); + m_legendBox->layout()->setSpacing(0); + m_legendBox->layout()->setMargin(0); + + m_legendLayout = new QVBoxLayout(m_legendBox->layout()); + m_legendLayout->setAlignment(Qt::AlignTop); + m_legendLayout->setSpacing(6); + m_legendLayout->setMargin(11); + + m_totalNiceLabel = new QLabel(i18n("%T - Total CPU time (sys + user + nice)"), m_legendBox); + m_legendLayout->addWidget(m_totalNiceLabel); + + m_totalLabel = new QLabel(i18n("%t - Total CPU time (sys + user)"), m_legendBox); + m_legendLayout->addWidget(m_totalLabel); + + m_sysLabel = new QLabel(i18n("%s - Total sys time"), m_legendBox); + m_legendLayout->addWidget(m_sysLabel); + + m_userLabel = new QLabel(i18n("%u - Total user time"), m_legendBox); + m_legendLayout->addWidget(m_userLabel); + + m_niceLabel = new QLabel(i18n("%n - Total nice time"), m_legendBox); + m_legendLayout->addWidget(m_niceLabel); + + mainLayout->addWidget( m_legendBox ); + + for (uint i = 0; i < addCpus(); ++i) + { + QCheckListItem *item = new QCheckListItem(m_listView, i18n("cpu %1").arg(i), QCheckListItem::CheckBox); + item->setText(1, "%T"); + } +} + +CpuConfig::~CpuConfig() +{ +} + +void CpuConfig::readConfig() +{ + config()->setGroup("CpuPlugin"); + QStringList enabledCpus(config()->readListEntry("Cpus")); + + int cpuNum = 0; + QStringList::ConstIterator it; + for (it = enabledCpus.begin(); it != enabledCpus.end(); ++it) { + if (QCheckListItem *item = + static_cast<QCheckListItem *>(m_listView->findItem((*it), 0))) { + item->setOn(true); + item->setText(1, config()->readEntry(CPU_NAME(cpuNum), "%T")); + } + ++cpuNum; + } +} + +void CpuConfig::saveConfig() +{ + config()->setGroup("CpuPlugin"); + + int cpuNum = 0; + QStringList enabledCpus; + for (QListViewItemIterator it(m_listView); it.current(); ++it) { + config()->writeEntry(CPU_NAME(cpuNum), it.current()->text(1)); + if (static_cast<QCheckListItem *>(it.current())->isOn()) + enabledCpus.append(it.current()->text(0)); + ++cpuNum; + } + + config()->writeEntry("Cpus", enabledCpus); +} + +uint CpuConfig::addCpus() +{ +#ifdef Q_OS_LINUX + QStringList output; + QString parser; + QFile file("/proc/stat"); + if (!file.open(IO_ReadOnly)) + return 0; + + // Parse the proc file + QTextStream procStream(&file); + while (!procStream.atEnd()) { + parser = procStream.readLine(); + if (QRegExp("cpu").search(parser, 0) != -1 + && QRegExp("cpu0").search(parser, 0) == -1) { + output.append(parser); + } + } + + return output.count(); +#endif + +#ifdef Q_OS_BSD4 + int mib[] = { CTL_HW, HW_NCPU }; // hw.ncpu + uint cpu; + size_t cpuLen = sizeof(cpu); + if (sysctl(mib, 2, &cpu, &cpuLen, NULL, 0) < 0) + return 0; + + return cpu; +#endif +} + +void CpuConfig::modify( QListViewItem * item ) +{ + if ( !item ) + return; + + bool ok = false; + QString text = KInputDialog::getText( i18n( "Modify CPU Format" ), i18n( "Chart format:" ), + item->text( 1 ), &ok, this ); + + if ( ok ) + item->setText( 1, text ); +} + +void CpuConfig::modify() +{ + modify( m_listView->selectedItem() ); +} diff --git a/ksim/monitors/cpu/ksimcpu.h b/ksim/monitors/cpu/ksimcpu.h new file mode 100644 index 0000000..b129ec0 --- /dev/null +++ b/ksim/monitors/cpu/ksimcpu.h @@ -0,0 +1,228 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KSIMCPU_H +#define KSIMCPU_H + +#include <pluginmodule.h> +#include <chart.h> +#include <progress.h> + +#include <stdio.h> + +class QPushButton; +class QTextStream; +class QVBoxLayout; +class QHBoxLayout; +class QCheckBox; +class QLabel; +class QGroupBox; +class QTimer; +class QListViewItem; +class KListView; + +class CpuPlugin : public KSim::PluginObject +{ + public: + CpuPlugin(const char *name); + ~CpuPlugin(); + + virtual KSim::PluginView *createView(const char *); + virtual KSim::PluginPage *createConfigPage(const char *); + + virtual void showAbout(); +}; + +class CpuView : public KSim::PluginView +{ + Q_OBJECT + public: + CpuView(KSim::PluginObject *parent, const char *name); + ~CpuView(); + + virtual void reparseConfig(); + + private slots: + void updateView(); + + private: + class CpuData + { + public: + CpuData() { user = nice = sys = idle = 0; } + + QString name; + unsigned long user; + unsigned long nice; + unsigned long sys; + unsigned long idle; + + CpuData &operator-=(const CpuData &rhs) + { + if (name != rhs.name) + return *this; + + user -= rhs.user; + nice -= rhs.nice; + sys -= rhs.sys; + idle -= rhs.idle; + return *this; + } + }; + + class Cpu + { + public: + Cpu() + { + m_num = 0; + m_chart = 0; + m_label = 0; + } + + Cpu(const QString &name, + const QString &format, + int number) + : m_name(name), + m_format(format), + m_num(number) + { + m_chart = 0; + m_label = 0; + } + + ~Cpu() + { + } + + bool operator==(const Cpu &rhs) const + { + return m_name == rhs.m_name && + m_format == rhs.m_format; + } + + bool operator!=(const Cpu &rhs) const + { + return !operator==(rhs); + } + + void cleanup() + { + delete m_chart; + delete m_label; + } + + void setData(const CpuData &data) + { + m_old = m_data; + m_data = data; + } + + const CpuData &oldData() const + { + return m_old; + } + + const QString &format() const + { + return m_format; + } + + int number() const + { + return m_num; + } + + void setDisplay(KSim::Chart *chart, KSim::Progress *label) + { + m_chart = chart; + m_label = label; + m_label->setText(m_name); + } + + KSim::Chart *chart() + { + return m_chart; + } + + KSim::Progress *label() + { + return m_label; + } + + private: + CpuData m_data; + CpuData m_old; + QString m_name; + QString m_format; + KSim::Chart *m_chart; + KSim::Progress *m_label; + int m_num; + }; + + typedef QValueList<Cpu> CpuList; + void updateCpu(CpuData &cpu, int cpuNumber); + CpuList createList(); + + void addDisplay(); + void cleanup(CpuList &); + + KSim::Chart *addChart(); + KSim::Progress *addLabel(); + + QTimer *m_timer; + QVBoxLayout *m_mainLayout; + bool m_firstTime; + CpuList m_cpus; + +#ifdef __linux__ + FILE *m_procFile; + QTextStream *m_procStream; +#endif +}; + +class CpuConfig : public KSim::PluginPage +{ + Q_OBJECT + public: + CpuConfig(KSim::PluginObject *parent, const char *name); + ~CpuConfig(); + + virtual void saveConfig(); + virtual void readConfig(); + + private slots: + void modify( QListViewItem * ); + void modify(); + + private: + uint addCpus(); + + KListView *m_listView; + QGroupBox *m_legendBox; + QLabel *m_totalNiceLabel; + QLabel *m_totalLabel; + QLabel *m_sysLabel; + QLabel *m_userLabel; + QLabel *m_niceLabel; + QVBoxLayout *m_legendLayout; + + QPushButton * m_modify; +}; +#endif diff --git a/ksim/monitors/disk/Makefile.am b/ksim/monitors/disk/Makefile.am new file mode 100644 index 0000000..ce9f79c --- /dev/null +++ b/ksim/monitors/disk/Makefile.am @@ -0,0 +1,15 @@ +kde_module_LTLIBRARIES = ksim_disk.la +ksim_disk_la_SOURCES = ksimdisk.cpp + +ksim_disk_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +ksim_disk_la_LIBADD = $(LIB_DEVSTAT) ../../library/libksimcore.la + +EXTRA_DIST = disk.desktop + +INCLUDES= -I$(top_srcdir)/ksim/library \ + $(all_includes) + +METASOURCES = AUTO + +mon_DATA = disk.desktop +mondir = $(kde_datadir)/ksim/monitors diff --git a/ksim/monitors/disk/configure.in.in b/ksim/monitors/disk/configure.in.in new file mode 100644 index 0000000..19b0e8f --- /dev/null +++ b/ksim/monitors/disk/configure.in.in @@ -0,0 +1,13 @@ +AC_CHECK_LIB(devstat, selectdevs, +[ + LIB_DEVSTAT="-ldevstat" +], +[ + AC_CHECK_LIB(devstat, devstat_selectdevs, + [ + LIB_DEVSTAT="-ldevstat" + ] + ) +]) + +AC_SUBST(LIB_DEVSTAT) diff --git a/ksim/monitors/disk/disk.desktop b/ksim/monitors/disk/disk.desktop new file mode 100644 index 0000000..f048878 --- /dev/null +++ b/ksim/monitors/disk/disk.desktop @@ -0,0 +1,106 @@ +[Desktop Entry] +Comment=Disk Monitor Plugin +Comment[af]=Disket Monitor Inplak +Comment[ar]=ملحق مراقبة القرص +Comment[bg]=Мониторинг на входно-изходите операции с диска +Comment[bs]=Dodatak za nadzor diska +Comment[ca]=Monitor de disc +Comment[cs]=Modul pro monitorování disku +Comment[cy]=Atodyn Monitro Disg +Comment[da]=Diskovervågnings-plugin +Comment[de]=Hilfsprogramm zur Festplattenüberwachung +Comment[el]=Πρόσθετο εποπτείας δίσκου +Comment[eo]=Disk-observa kromaĵo +Comment[es]=Extensión de monitorización de disco +Comment[et]=Ketta monitooring +Comment[eu]=Diskoaren Plugin Begiralea +Comment[fa]=وصلۀ نمایشگر دیسک +Comment[fi]=Levyntarkkailusovelma +Comment[fr]=Module de surveillance du disque +Comment[ga]=Breiseán Monatóireachta Diosca +Comment[he]=תוסף צג דיסק +Comment[hi]=डिस्क मॉनीटर प्लगइन +Comment[hu]=Lemezfigyelő bővítőmodul +Comment[is]=Disk eftirlitsforrit +Comment[it]=Plugin di controllo disco +Comment[ja]=ディスクモニタプラグイン +Comment[ka]= დისკის მონიტორის მოდული +Comment[kk]=Дискін бақылау модулі +Comment[km]=កម្មវិធីជំនួយនៃកម្មវិធីត្រួតពិនិត្យថាស +Comment[lt]=Disko stebėtojo priedas +Comment[mk]=Приклучок за следење на дискот +Comment[ms]=Plug masuk Pemerhati Monitor +Comment[nb]=Programtillegg for diskovervåkning +Comment[nds]=Fastplaat-Kiekmoduul +Comment[ne]=डिस्क मोनिटर प्लगइन +Comment[nl]=Disk monitor-plugin +Comment[nn]=Programtillegg for diskovervaking +Comment[pa]=ਡਿਸਕ ਨਿਗਰਾਨ ਪਲੱਗਿੰਨ +Comment[pl]=Stan dysku +Comment[pt]='Plugin' de Monitorização do Disco +Comment[pt_BR]=Plug-in de monitoramento do Disco +Comment[ro]=Modul monitorizare disc +Comment[ru]=Монитор дискового пространства +Comment[sk]=Modul pre monitorovanie disku +Comment[sl]=Vstavek za opazovanje diska +Comment[sr]=Прикључак за надгледање диска +Comment[sr@Latn]=Priključak za nadgledanje diska +Comment[sv]=Insticksprogram för diskövervakning +Comment[ta]= வட்டு கண்காணி சொருகுப்பொருள் +Comment[tg]=Модули Дидабони Диск +Comment[th]=ปลั๊กอินตรวจการทำงานดิสก์ +Comment[tr]=Disk İzleyici Eklentisi +Comment[uk]=Втулок датчика диску +Comment[uz]=Diskni nazorat qilish plagini +Comment[uz@cyrillic]=Дискни назорат қилиш плагини +Comment[wa]=Tchôke-divins di corwaitaedje del deure plake +Comment[xh]=Iplagi efakiweyo ye Monitor Yediski +Comment[zh_CN]=磁盘监视器插件 +Comment[zh_TW]=磁碟監視器外掛程式 +Comment[zu]=I-plugin Yomlawuli Wediski +Icon=hdd_mount +Name=Disk +Name[af]=Disket +Name[ar]=قرص +Name[bg]=Дискове +Name[br]=Pladenn +Name[ca]=Disc +Name[el]=Δίσκος +Name[eo]=Disko +Name[es]=Disco +Name[et]=Ketas +Name[eu]=Diskoa +Name[fa]=دیسک +Name[fi]=Levy +Name[ga]=Diosca +Name[he]=דיסק +Name[hi]=डिस्क +Name[hu]=Lemez +Name[is]=Diskur +Name[it]=Disco +Name[ja]=ディスク +Name[kk]=Дискі +Name[km]=ថាស +Name[lt]=Diskas +Name[lv]=Disks +Name[mk]=Диск +Name[ms]=Cakera +Name[nds]=Fastplaat +Name[ne]=डिस्क +Name[pa]=ਡਿਸਕ +Name[pl]=Dysk +Name[pt]=Disco +Name[pt_BR]=Disco +Name[ro]=Disc +Name[ru]=Диск +Name[sr]=Диск +Name[ta]=வட்டு +Name[tg]=Диск +Name[th]=ดิสก์ +Name[uk]=Диск +Name[uz@cyrillic]=Диск +Name[wa]=Deure plake +Name[xh]=Idiski +Name[zh_CN]=磁盘 +Name[zu]=Idiski +X-KSIM-LIBRARY=disk diff --git a/ksim/monitors/disk/ksimdisk.cpp b/ksim/monitors/disk/ksimdisk.cpp new file mode 100644 index 0000000..2fe3560 --- /dev/null +++ b/ksim/monitors/disk/ksimdisk.cpp @@ -0,0 +1,570 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "ksimdisk.h" +#include "ksimdisk.moc" + +#include <qtextstream.h> +#include <qregexp.h> +#include <qtimer.h> +#include <qlayout.h> +#include <qradiobutton.h> +#include <qvbuttongroup.h> +#include <qpushbutton.h> + +#include <kdebug.h> +#include <kaboutapplication.h> +#include <kaboutdata.h> +#include <klocale.h> +#include <kapplication.h> +#include <klistview.h> +#include <kinputdialog.h> +#include <kconfig.h> + +#include <chart.h> +#include <progress.h> +#include <themetypes.h> + +#if defined(__DragonFly__) +#include <sys/time.h> +#include <sys/param.h> +#include <sys/resource.h> +#include <devstat.h> +#include <stdlib.h> +#elif defined(Q_OS_FREEBSD) +#include <sys/param.h> +#if __FreeBSD_version < 500101 +#include <sys/dkstat.h> +#else +#include <sys/resource.h> +#endif +#include <devstat.h> +#include <stdlib.h> +#endif + +#ifdef Q_OS_LINUX +#include <linux/major.h> +#endif + +#include <iostream> + +#define DISK_SPEED 1000 + +KSIM_INIT_PLUGIN(DiskPlugin) + +DiskPlugin::DiskPlugin(const char *name) + : KSim::PluginObject(name) +{ + setConfigFileName(instanceName()); +} + +DiskPlugin::~DiskPlugin() +{ +} + +KSim::PluginView *DiskPlugin::createView(const char *className) +{ + return new DiskView(this, className); +} + +KSim::PluginPage *DiskPlugin::createConfigPage(const char *className) +{ + return new DiskConfig(this, className); +} + +void DiskPlugin::showAbout() +{ + QString version = kapp->aboutData()->version(); + + KAboutData aboutData(instanceName(), + I18N_NOOP("KSim Disk Plugin"), version.latin1(), + I18N_NOOP("A disk monitor plugin for KSim"), + KAboutData::License_GPL, "(C) 2001 Robbie Ward"); + + aboutData.addAuthor("Robbie Ward", I18N_NOOP("Author"), + "linuxphreak@gmx.co.uk"); + + KAboutApplication(&aboutData).exec(); +} + +DiskView::DiskView(KSim::PluginObject *parent, const char *name) + : KSim::PluginView(parent, name) +{ +#ifdef Q_OS_LINUX + m_bLinux24 = true; + m_procStream = 0L; + if ((m_procFile = fopen("/proc/stat", "r"))) + m_procStream = new QTextStream(m_procFile, IO_ReadOnly); +#endif + + config()->setGroup("DiskPlugin"); + m_list = config()->readListEntry("Disks", QStringList() << "complete"); + m_useSeperatly = config()->readBoolEntry("UseSeperatly", true); + + m_firstTime = 1; + m_addAll = false; + m_layout = new QVBoxLayout(this); + QSpacerItem *item = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding); + m_layout->addItem(item); + + init(); + + m_timer = new QTimer(this); + connect(m_timer, SIGNAL(timeout()), SLOT(updateDisplay())); + m_timer->start(DISK_SPEED); + updateDisplay(); +} + +DiskView::~DiskView() +{ +#ifdef Q_OS_LINUX + delete m_procStream; + + if (m_procFile) + fclose(m_procFile); +#endif +} + +void DiskView::reparseConfig() +{ + config()->setGroup("DiskPlugin"); + QStringList list = config()->readListEntry("Disks", QStringList() << "complete"); + m_useSeperatly = config()->readBoolEntry("UseSeperatly", true); + + if (list != m_list) { + m_list = list; + m_timer->stop(); + cleanup(); + + QPtrListIterator<DiskPair> it(m_diskList); + for (; it.current(); ++it) { + delete it.current()->first; + delete it.current()->second; + } + + m_diskList.clear(); + init(); + m_timer->start(DISK_SPEED); + updateDisplay(); + } +} + +DiskView::DiskData DiskView::findDiskData(const DiskList& diskList, QString diskName) +{ + if (diskName == "complete") + diskName = i18n("All Disks"); + + DiskView::DiskList::ConstIterator disk; + for (disk = diskList.begin(); disk != diskList.end(); ++disk) + if ((*disk).name == diskName) + return *disk; + + // Not found + DiskView::DiskData dummy; + dummy.name = "["+diskName+"]"; + return dummy; +} + +// Kind of messy code, dont ya think? +void DiskView::updateDisplay() +{ + DiskList diskList; + + updateData(diskList); + + if (m_addAll) + { + DiskData all; + all.name = i18n("All Disks"); + + for (DiskList::ConstIterator disk = diskList.begin(); + disk != diskList.end(); ++disk) + { + all += (*disk); + } + + diskList.prepend(all); + } + + // merge all the disks into one + QPtrListIterator<DiskPair> it(m_diskList); + for (int i = 0; it.current(); ++it, ++i) { + DiskData diskData = findDiskData(diskList, m_list[i]); + m_data[i].second = m_data[i].first; + m_data[i].first = diskData; + diskData -= m_data[i].second; + unsigned long diff = diskData.readBlocks + diskData.writeBlocks; + if (m_firstTime) + diff = diskData.readBlocks = diskData.writeBlocks = 0; + + if (m_useSeperatly) { + it.current()->first->setValue(diskData.readBlocks, diskData.writeBlocks); + it.current()->first->setText(i18n("in: %1k") + .arg(KGlobal::locale()->formatNumber((float)diskData.readBlocks / 1024.0, 1)), + i18n("out: %1k").arg(KGlobal::locale()->formatNumber((float)diskData.writeBlocks / 1024.0, 1))); + } + else { + it.current()->first->setValue(diff, 0); + it.current()->first->setText(i18n("%1k") + .arg(KGlobal::locale()->formatNumber((float)diff / 1024.0, 1))); + } + + it.current()->second->setMaxValue(it.current()->first->maxValue()); + it.current()->second->setText(diskData.name); + it.current()->second->setValue(diff); + } + + m_firstTime = 0; +} + +void DiskView::updateData(DiskList &disks) +{ +#ifdef Q_OS_LINUX + if (!m_procStream) + return; + + m_procStream->device()->reset(); + fseek(m_procFile, 0L, SEEK_SET); + + if (m_bLinux24) + { + // here we need a regexp to match something like: + // (3,0):(108911,48080,1713380,60831,1102644) + QRegExp regexp("\\([0-9]+,[0-9]+\\):\\([0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+\\)"); + QString content = m_procStream->read(); + if (content.find("disk_io") == -1) + { + m_bLinux24 = false; + + delete m_procStream; + m_procStream = 0; + fclose(m_procFile); + + if ((m_procFile = fopen("/proc/diskstats", "r"))) + m_procStream = new QTextStream(m_procFile, IO_ReadOnly); + + updateData(disks); + return; + } + int idx = 0; + while ((idx = regexp.search(content, idx)) != -1) + { + idx += regexp.matchedLength(); + QString diskStr = regexp.cap(0); + diskStr.replace(':', ','); + diskStr.replace(QRegExp("\\)?\\(?"), QString::null); + + QStringList list = QStringList::split(',', diskStr); + if (list.count() < 7) + continue; + + DiskData diskData; + diskData.major = list[0].toInt(); + diskData.minor = list[1].toInt(); + diskData.name = diskName( diskData.major, diskData.minor ); + diskData.total = list[2].toULong(); + diskData.readIO = list[3].toULong(); + diskData.readBlocks = list[4].toULong(); + diskData.writeIO = list[5].toULong(); + diskData.writeBlocks = list[6].toULong(); + disks.append(diskData); + } + } + else + { + // 3 0 hda 564142 160009 14123957 12369403 1052983 2801992 30905928 78981451 0 4531584 91518334 + // The 11 fields after the device name are defined as follows: + // Field 1 -- # of reads issued + // This is the total number of reads completed successfully. + // Field 2 -- # of reads merged, + // Reads and writes which are adjacent to each other may be merged for + // efficiency. Thus two 4K reads may become one 8K read before it is + // ultimately handed to the disk, and so it will be counted (and queued) + // as only one I/O. This field lets you know how often this was done. + // Field 3 -- # of sectors read + // This is the total number of sectors read successfully. + // Field 4 -- # of milliseconds spent reading + // This is the total number of milliseconds spent by all reads (as + // measured from __make_request() to end_that_request_last()). + // Field 5 -- # of writes completed + // This is the total number of writes completed successfully. + // Field 6 -- # of writes merged + // See field 2 + // Field 7 -- # of sectors written + // This is the total number of sectors written successfully. + // Field 8 -- # of milliseconds spent writing + // This is the total number of milliseconds spent by all writes (as + // measured from __make_request() to end_that_request_last()). + // Field 9 -- # of I/Os currently in progress + // The only field that should go to zero. Incremented as requests are + // given to appropriate request_queue_t and decremented as they finish. + // Field 10 -- # of milliseconds spent doing I/Os + // This field is increases so long as field 9 is nonzero. + // Field 11 -- weighted # of milliseconds spent doing I/Os + // This field is incremented at each I/O start, I/O completion, I/O + // merge, or read of these stats by the number of I/Os in progress + // (field 9) times the number of milliseconds spent doing I/O since the + // last update of this field. This can provide an easy measure of both + // I/O completion time and the backlog that may be accumulating. + QString content = m_procStream->read(); + QStringList lines = QStringList::split('\n', content); + + for(QStringList::ConstIterator it = lines.begin(); + it != lines.end(); ++it) + { + QString diskStr = (*it).simplifyWhiteSpace(); + QStringList list = QStringList::split(' ', diskStr); + if (list.count() < 14) + continue; + + DiskData diskData; + diskData.major = list[0].toInt(); + diskData.minor = list[1].toInt(); + diskData.name = list[2]; + diskData.readIO = 0; + diskData.readBlocks = list[3+2].toULong(); + diskData.writeIO = 0; + diskData.writeBlocks = list[7+2].toULong(); + diskData.total = diskData.readBlocks + diskData.writeBlocks; + disks.append(diskData); + } + } + +#endif + +#ifdef Q_OS_FREEBSD +#if defined(__DragonFly__) || __FreeBSD_version < 500107 +#define devstat_getdevs(fd, stats) getdevs(stats) +#define devstat_selectdevs selectdevs +#define bytes_read(dev) (dev).bytes_read +#define bytes_written(dev) (dev).bytes_written +#else +#define bytes_read(dev) (dev).bytes[DEVSTAT_READ] +#define bytes_written(dev) (dev).bytes[DEVSTAT_WRITE] +#endif + + statinfo diskStats; + bzero(&diskStats, sizeof(diskStats)); + diskStats.dinfo = (struct devinfo *)malloc(sizeof(struct devinfo)); + bzero(diskStats.dinfo, sizeof(struct devinfo)); + int deviceAmount; + int selected; + int selections; + long generation; + device_selection *deviceSelect = 0; + + if (devstat_getdevs(NULL, &diskStats) < 0) + return; + + deviceAmount = diskStats.dinfo->numdevs; + if (devstat_selectdevs(&deviceSelect, &selected, &selections, + &generation, diskStats.dinfo->generation, + diskStats.dinfo->devices, deviceAmount, + 0, 0, 0, 0, DS_SELECT_ONLY, 10, 1) < 0) + return; + + unsigned long readBlocks = 0, writeBlocks = 0, blockSize; + for (int i = 0; i < deviceAmount; ++i) { + int disk; + devstat device; + disk = deviceSelect[i].position; + device = diskStats.dinfo->devices[disk]; + blockSize = (device.block_size <= 0 ? 512 : device.block_size); + readBlocks = bytes_read(device) / blockSize; + writeBlocks = bytes_written(device) / blockSize; + + DiskData diskData; + diskData.name = device.device_name + + QString::number(device.unit_number); + diskData.major = device.device_number; + diskData.minor = 0; + diskData.total = readBlocks + writeBlocks; + diskData.readIO = 0; + diskData.readBlocks = readBlocks; + diskData.writeIO = 0; + diskData.writeBlocks = writeBlocks; + disks.append(diskData); + } + + free(deviceSelect); + free(diskStats.dinfo); +#endif +} + +QString DiskView::diskName( int major, int minor ) const +{ +#ifdef Q_OS_LINUX + QString returnValue; + switch ( major ) + { + case IDE0_MAJOR: + returnValue.prepend(QString::fromLatin1("hda")); + break; + case IDE1_MAJOR: + returnValue.prepend(QString::fromLatin1("hdc")); + break; + case IDE3_MAJOR: + returnValue.prepend(QString::fromLatin1("hde")); + break; + case SCSI_DISK0_MAJOR: + returnValue.prepend(QString::fromLatin1("sda")); + break; + case SCSI_GENERIC_MAJOR: + returnValue.prepend(QString::fromLatin1("sg0")); + break; + } + + returnValue.at(2) = returnValue.at(2).latin1() + minor; + return returnValue; +#else + Q_UNUSED(major); + Q_UNUSED(minor); + return 0; +#endif +} + +DiskView::DiskPair *DiskView::addDisk() +{ + KSim::Chart *chart = new KSim::Chart(false, 0, this); + chart->show(); + m_layout->addWidget(chart); + + KSim::Progress *progress = new KSim::Progress(0, KSim::Types::None, + KSim::Progress::Panel, this); + progress->show(); + m_layout->addWidget(progress); + + return new DiskPair(chart, progress); +} + +void DiskView::init() +{ + m_data.resize(m_list.size()); + + QStringList::ConstIterator it; + for (it = m_list.begin(); it != m_list.end(); ++it) { + if ((*it) == "complete") + m_addAll = true; + + m_diskList.append(addDisk()); + } +} + +void DiskView::cleanup() +{ + m_data.clear(); + m_addAll = false; +} + +DiskConfig::DiskConfig(KSim::PluginObject *parent, const char *name) + : KSim::PluginPage(parent, name) +{ + m_layout = new QVBoxLayout(this); + m_layout->setSpacing(6); + + m_listview = new KListView(this); + m_listview->addColumn(i18n("Disks")); + m_layout->addWidget(m_listview); + + QHBoxLayout *layout = new QHBoxLayout; + layout->setSpacing(6); + + QSpacerItem *spacer = new QSpacerItem(20, 20, + QSizePolicy::Expanding, QSizePolicy::Minimum); + layout->addItem(spacer); + + m_add = new QPushButton(this); + m_add->setText(i18n("Add...")); + connect(m_add, SIGNAL(clicked()), SLOT(addItem())); + layout->addWidget(m_add); + + m_remove = new QPushButton(this); + m_remove->setText(i18n("Remove")); + connect(m_remove, SIGNAL(clicked()), SLOT(removeItem())); + layout->addWidget(m_remove); + m_layout->addLayout(layout); + + m_buttonBox = new QVButtonGroup(i18n("Disk Styles"), this); + m_layout->addWidget(m_buttonBox); + + m_totalButton = new QRadioButton(m_buttonBox); + m_totalButton->setText(i18n("Display the read and write data as one")); + m_bothButton = new QRadioButton(m_buttonBox); + m_bothButton->setText(i18n("Display the read and write data" + "\nseparately as in/out data")); + + QSpacerItem *vSpacer = new QSpacerItem(20, 20, + QSizePolicy::Minimum, QSizePolicy::Expanding); + m_layout->addItem(vSpacer); +} + +DiskConfig::~DiskConfig() +{ +} + +void DiskConfig::readConfig() +{ + config()->setGroup("DiskPlugin"); + m_buttonBox->setButton(config()->readBoolEntry("UseSeperatly", true)); + QStringList list = config()->readListEntry("Disks"); + + QStringList::ConstIterator it; + for (it = list.begin(); it != list.end(); ++it) { + QString text = ((*it) == "complete" ? i18n("All Disks") : (*it)); + if (!m_listview->findItem(text, 0)) + new QListViewItem(m_listview, text); + } +} + +void DiskConfig::saveConfig() +{ + QStringList list; + for (QListViewItemIterator it(m_listview); it.current(); ++it) { + if (it.current()->text(0) == i18n("All Disks")) + list.append("complete"); + else + list.append(it.current()->text(0)); + } + + config()->setGroup("DiskPlugin"); + config()->writeEntry("UseSeperatly", (bool)m_buttonBox->id(m_buttonBox->selected())); + config()->writeEntry("Disks", list); +} + +void DiskConfig::addItem() +{ + bool ok = false; + QString text = KInputDialog::getText(i18n("Add Disk Device"), i18n("Disk name:"), + QString::null, &ok, this); + + if (text.startsWith("/dev/")) + text = text.mid(5); + + if (ok) + new QListViewItem(m_listview, text); +} + +void DiskConfig::removeItem() +{ + if (!m_listview->selectedItem()) + return; + + QListViewItem *item = m_listview->selectedItem(); + delete item; +} diff --git a/ksim/monitors/disk/ksimdisk.h b/ksim/monitors/disk/ksimdisk.h new file mode 100644 index 0000000..de4c8ba --- /dev/null +++ b/ksim/monitors/disk/ksimdisk.h @@ -0,0 +1,154 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KSIMDISK_H +#define KSIMDISK_H + +#include <qvaluelist.h> +#include <pluginmodule.h> +#include <stdio.h> +#include <qptrlist.h> +#include <qstringlist.h> +#include <qvaluevector.h> + +class QTextStream; +class QTimer; +class KListView; +class QVBoxLayout; +class QVButtonGroup; +class QRadioButton; +class QPushButton; +namespace KSim +{ + class Chart; + class Progress; +} + +class DiskPlugin : public KSim::PluginObject +{ + public: + DiskPlugin(const char *name); + ~DiskPlugin(); + + virtual KSim::PluginView *createView(const char *); + virtual KSim::PluginPage *createConfigPage(const char *); + + virtual void showAbout(); +}; + +class DiskView : public KSim::PluginView +{ + Q_OBJECT + public: + DiskView(KSim::PluginObject *parent, const char *name); + ~DiskView(); + + virtual void reparseConfig(); + + private slots: + void updateDisplay(); + + private: + class DiskData + { + public: + DiskData() + { + major = minor = readIO = readBlocks = + writeIO = writeBlocks = 0; + } + + DiskData &operator+=(const DiskData &rhs) + { + total += rhs.total; + readIO += rhs.readIO; + readBlocks += rhs.readBlocks; + writeIO += rhs.writeIO; + writeBlocks += rhs.writeBlocks; + return *this; + } + + DiskData &operator-=(const DiskData &rhs) + { + total -= rhs.total; + readIO -= rhs.readIO; + readBlocks -= rhs.readBlocks; + writeIO -= rhs.writeIO; + writeBlocks -= rhs.writeBlocks; + return *this; + } + + QString name; + int major; + int minor; + unsigned long total; + unsigned long readIO; + unsigned long readBlocks; + unsigned long writeIO; + unsigned long writeBlocks; + }; + + typedef QValueList<DiskData> DiskList; + typedef QPair<KSim::Chart *, KSim::Progress *> DiskPair; + + void updateData(DiskList &disks); + QString diskName( int, int ) const; + DiskPair *addDisk(); + DiskData findDiskData(const DiskList& diskList, QString diskName); + + void init(); + void cleanup(); + + QValueVector<QPair<DiskData, DiskData> > m_data; + QTimer *m_timer; + bool m_bLinux24; + FILE *m_procFile; + QTextStream *m_procStream; + QVBoxLayout *m_layout; + QPtrList<DiskPair> m_diskList; + int m_firstTime; + bool m_useSeperatly; + QStringList m_list; + bool m_addAll; +}; + +class DiskConfig : public KSim::PluginPage +{ + Q_OBJECT + public: + DiskConfig(KSim::PluginObject *parent, const char *name); + ~DiskConfig(); + + virtual void saveConfig(); + virtual void readConfig(); + + private slots: + void addItem(); + void removeItem(); + + private: + QVBoxLayout *m_layout; + KListView *m_listview; + QPushButton *m_add; + QPushButton *m_remove; + QVButtonGroup *m_buttonBox; + QRadioButton *m_totalButton; + QRadioButton *m_bothButton; +}; +#endif diff --git a/ksim/monitors/filesystem/DFree.desktop b/ksim/monitors/filesystem/DFree.desktop new file mode 100644 index 0000000..78ffdb1 --- /dev/null +++ b/ksim/monitors/filesystem/DFree.desktop @@ -0,0 +1,87 @@ +[Desktop Entry] +Icon=hdd_unmount +Name=DFree +Name[af]=Dfree +Name[bg]=Дялове +Name[ca]=Disc lliure +Name[cs]=Volný disk +Name[eo]=Diskuzo +Name[et]=Vaba kettaruum +Name[he]=מחיצות +Name[hi]=डी-फ्री +Name[it]=Disco libero +Name[kk]=Тіркеген бөлімдер +Name[ko]=디스크 사용량 +Name[ne]=डिफ्रि +Name[pt_BR]=Disco Livre +Name[ru]=Смонтированные разделы +Name[sk]=Voľný disk +Name[sv]=Ledigt diskutrymme +Name[ta]= Dபிரீ +Name[tg]=DОзод +Name[th]=พื้นที่ว่างของดิสก์ +Comment=Mounted Partitions Monitor +Comment[af]=Gekoppelde Partisies Monitor +Comment[ar]=مراقب الأقسام المضمومة +Comment[bg]=Мониторинг на монтираните дялове +Comment[bs]=Nadzor montiranih particija +Comment[ca]=Monitor de les particions muntades +Comment[cs]=Monitor připojených diskových oddílů +Comment[cy]=Monitr Rhaniadau Mowntiedig +Comment[da]=Overvågning af monterede partitioner +Comment[de]=Anzeige für eingebundene Laufwerke +Comment[el]=Επόπτης προσαρτημένων κατατμήσεων +Comment[eo]=Vidigilo por la kroĉitaj subdiskoj +Comment[es]=Monitor de particiones montadas +Comment[et]=Ühendatud partitsioonide monitooring +Comment[eu]=Muntatutako Partizioen Begiralea +Comment[fa]=نمایشگر افرازهای سوارشده +Comment[fi]=Liitettyjen osioiden valvonta +Comment[fr]=Surveillant des lecteurs montés +Comment[ga]=Monatóir Rannta Feistithe +Comment[he]=צג מחיצות מחוברות +Comment[hi]=माउन्टेड पार्टीशन्स मॉनीटर +Comment[hu]=Lemezcsatlakoztatás-figyelő +Comment[is]=Eftirlit með tengdum disksneiðum +Comment[it]=Controllo delle partizioni montate +Comment[ja]=マウントされたパーティションのモニタ +Comment[ka]= მონტირებული პარტიციების მონიტორი +Comment[kk]=Тіркеген бөлімдерді бақылау +Comment[km]=កម្មវិធីត្រួតពិនិត្យភាគដែលបានម៉ោន +Comment[lt]=Sumontuotų skirsnių stebėtojas +Comment[mk]=Монитор на монтираните партиции +Comment[ms]=Pemerhati Partisi yang telah Dilekapkan +Comment[nb]=Overvåkning av monterte partisjoner +Comment[nds]=Kieker för inhangte Partitschonen +Comment[ne]=माउन्ट गरिएको विभाजन मोनिटर +Comment[nl]=Monitor van aangekoppelde partities +Comment[nn]=Overvaking av monterte partisjonar +Comment[pa]=ਮਾਊਂਟ ਭਾਗ ਨਿਗਰਾਨ +Comment[pl]=Stan zamontowanych partycji +Comment[pt]=Monitor de Partições Montadas +Comment[pt_BR]=Monitor das Partições Montadas +Comment[ro]=Monitor partiţii montate +Comment[ru]=Монитор смонтированных разделов +Comment[sk]=Monitor pripojených diskových oddielov +Comment[sl]=Nadzornik priklopljenih razdelkov +Comment[sr]=Надгледање монтираних партиција +Comment[sr@Latn]=Nadgledanje montiranih particija +Comment[sv]=Övervakar monterade partitioner +Comment[ta]=ஏற்றப்பட்ட பகுக்கப்பட்ட கண்காணி +Comment[tg]=Дидабони Қисмҳои Насбшуда +Comment[th]=สอดส่องพาร์ติชันที่เมานท์ไว้แล้ว +Comment[tr]=Bağlanmış Disk Bölümü İzleyici +Comment[uk]=Монітор змонтованих розділів +Comment[uz]=Diskning ulangan qismlarini nazorat qilish plagini +Comment[uz@cyrillic]=Дискнинг уланган қисмларини назорат қилиш плагини +Comment[wa]=Corwaitoe des montêyès pårticions +Comment[xh]=Ulwahlulo Lonyuso lwe Monitor +Comment[zh_CN]=已挂载分区监视器 +Comment[zh_TW]=已掛載的分割區監視器 +Comment[zu]=Umlawuli Wezahlukaniso Ezinyukile +X-KSIM-VERSION=0.1 +X-KSIM-LIBRARY=filesystem +X-KSIM-PREFS=File System +X-KSIM-AUTHOR=Robbie Ward +X-KSIM-EMAIL=linuxphreak@gmx.co.uk +X-KSIM-COPYRIGHT=(C) 2001 Robbie Ward diff --git a/ksim/monitors/filesystem/Makefile.am b/ksim/monitors/filesystem/Makefile.am new file mode 100644 index 0000000..7da7012 --- /dev/null +++ b/ksim/monitors/filesystem/Makefile.am @@ -0,0 +1,16 @@ +kde_module_LTLIBRARIES = ksim_filesystem.la +ksim_filesystem_la_SOURCES = ksimfsystem.cpp fsystemconfig.cpp \ + fsystemiface.skel filesystemwidget.cpp filesystemstats.cpp + +ksim_filesystem_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +ksim_filesystem_la_LIBADD = ../../library/libksimcore.la + +EXTRA_DIST = DFree.desktop + +INCLUDES= -I$(top_srcdir)/ksim/library \ + $(all_includes) + +METASOURCES = AUTO + +mon_DATA = DFree.desktop +mondir = $(kde_datadir)/ksim/monitors diff --git a/ksim/monitors/filesystem/configure.in.in b/ksim/monitors/filesystem/configure.in.in new file mode 100644 index 0000000..8fd7a61 --- /dev/null +++ b/ksim/monitors/filesystem/configure.in.in @@ -0,0 +1,2 @@ +AC_CHECK_HEADERS(sys/mnttab.h mntent.h sys/statvfs.h sys/statfs.h sys/vfs.h sys/mount.h sys/ucred.h sys/loadavg.h) +AC_CHECK_FUNCS(statvfs) diff --git a/ksim/monitors/filesystem/filesystemstats.cpp b/ksim/monitors/filesystem/filesystemstats.cpp new file mode 100644 index 0000000..eeb5c62 --- /dev/null +++ b/ksim/monitors/filesystem/filesystemstats.cpp @@ -0,0 +1,224 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "filesystemstats.h" + +#include <qglobal.h> +#include <qfile.h> +#include <qstringlist.h> + +#include <kdebug.h> + +#include <config.h> + +#include <sys/types.h> +#include <sys/param.h> + +#if defined(HAVE_SYS_STATVFS_H) && !defined(__DragonFly__) +#include <sys/statvfs.h> +#elif defined( HAVE_SYS_STATFS_H ) +#include <sys/statfs.h> +#endif +#ifdef HAVE_SYS_VFS_H +#include <sys/vfs.h> +#endif +#ifdef HAVE_SYS_MOUNT_H +#include <sys/mount.h> +#endif +#ifdef HAVE_MNTENT_H +#include <mntent.h> +#ifdef _HPUX_SOURCE +#define _PATH_MOUNTED MNTTAB +#endif +#endif +#ifdef HAVE_SYS_UCRED_H +#include <sys/ucred.h> +#endif +#ifdef HAVE_SYS_MNTTAB_H +#include <sys/mnttab.h> +#undef HAVE_MNTENT_H +#define _PATH_MOUNTED MNTTAB +#endif + +#include <stdio.h> +#include <unistd.h> + +#if defined(HAVE_STATVFS) && !defined(__DragonFly__) +typedef struct statvfs ksim_statfs; +#define ksim_getfsstat getvfsstat +#elif defined( HAVE_STATFS ) || defined( Q_OS_FREEBSD ) +typedef struct statfs ksim_statfs; +#define ksim_getfsstat getfsstat +#else +typedef struct // fall back for (possibly) non-supported systems +{ + int f_blocks; + int f_bfree; +} ksim_statfs; +#endif + +int fsystemStats( const char * file, ksim_statfs & stats ) +{ +#if defined(HAVE_STATVFS) && !defined(__DragonFly__) + return statvfs( file, &stats ); +#elif defined( HAVE_STATFS ) || defined( Q_OS_FREEBSD ) + return statfs( file, &stats ); +#else // fall back for (possibly) non-supported systems + (void)file; + + stats.f_blocks = 0; + stats.f_bfree = 0; + return -1; +#endif +} + +#ifdef HAVE_SYS_MNTTAB_H +#define USE_MNTENT + +typedef struct +{ + const char * mnt_dir; + const char * mnt_fsname; + const char * mnt_type; +} ksim_mntent; + +FILE * setmntent( const char * mtab, const char * mode ) +{ + return fopen( mtab, mode ); +} + +int endmntent( FILE * file ) +{ + return fclose( file ); +} + +ksim_mntent * ksim_getmntent( FILE * file ) +{ + ksim_mntent * entry; + struct mnttab tab; + + if ( getmntent( file, &tab ) != 0 ) + return NULL; + + entry = new ksim_mntent; + entry->mnt_dir = tab.mnt_mountp; + entry->mnt_fsname = tab.mnt_special; + entry->mnt_type = tab.mnt_fstype; + return entry; +} + +#define delete_mntent( x ) delete x +#elif defined( HAVE_MNTENT_H ) +#define USE_MNTENT + +// Dummy setup +typedef struct mntent ksim_mntent; +ksim_mntent * ksim_getmntent( FILE * file ) +{ + return getmntent( file ); +} + +#define delete_mntent( x ) +#elif defined( HAVE_SYS_UCRED_H ) || defined( HAVE_SYS_MOUNT_H ) +#define USE_FSSTAT +#else +#define USE_FAILSAFE +#endif + +FilesystemStats::List FilesystemStats::readEntries() +{ + List list; + +#ifdef USE_MNTENT + FILE * fp = setmntent( _PATH_MOUNTED, "r" ); + ksim_mntent * point; + + while ( ( point = ksim_getmntent( fp ) ) != 0 ) + { + Entry entry; + entry.dir = point->mnt_dir; + entry.fsname = point->mnt_fsname; + entry.type = point->mnt_type; + list.append( entry ); + + delete_mntent( point ); + } + + endmntent( fp ); +#endif + +#ifdef USE_FSSTAT + ksim_statfs sfs[32]; + int fs_count; + if ( ( fs_count = ksim_getfsstat( sfs, sizeof( sfs ), 0 ) ) != -1 ) + { + for ( int i = 0; i < fs_count; i++ ) + { + Entry entry; + entry.dir = sfs[i].f_mntonname; + entry.fsname = sfs[i].f_mntfromname; + +#ifndef __osf__ + entry.type = sfs[i].f_fstypename; +#endif + + list.append( entry ); + } + } +#endif + +#ifdef USE_FAILSAFE + QFile file( QString::fromLatin1( _PATH_MOUNTED ) ); + + if ( !file.open( IO_ReadOnly ) ) + return list; + + QTextStream stream( &file ); + + while ( !stream.atEnd() ) + { + QStringList line = QStringList::split( " ", stream.readLine() ); + + Entry entry; + entry.dir = line[1].stripWhiteSpace(); + entry.fsname = line[0].stripWhiteSpace(); + entry.type = line[2].stripWhiteSpace(); + list.append( entry ); + } +#endif + + return list; +} + +bool FilesystemStats::readStats( const QString & mntPoint, int & totalBlocks, int & freeBlocks ) +{ + ksim_statfs sysStats; + if ( fsystemStats( QFile::encodeName( mntPoint ).data(), sysStats ) < 0 ) + { + kdError() << "While reading filesystem information for " << mntPoint << endl; + totalBlocks = 0; + freeBlocks = 0; + } + + totalBlocks = sysStats.f_blocks; + freeBlocks = sysStats.f_bfree; + + // Return true if our filesystem is statable + return totalBlocks > 0; +} diff --git a/ksim/monitors/filesystem/filesystemstats.h b/ksim/monitors/filesystem/filesystemstats.h new file mode 100644 index 0000000..3ea8f74 --- /dev/null +++ b/ksim/monitors/filesystem/filesystemstats.h @@ -0,0 +1,40 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef FILESYSTEMSTATS_H +#define FILESYSTEMSTATS_H + +#include <qstring.h> +#include <qvaluelist.h> + +namespace FilesystemStats +{ + struct Entry + { + QString dir; + QString fsname; + QString type; + }; + + typedef QValueList<Entry> List; + List readEntries(); + bool readStats( const QString &, int &, int & ); + +} +#endif diff --git a/ksim/monitors/filesystem/filesystemwidget.cpp b/ksim/monitors/filesystem/filesystemwidget.cpp new file mode 100644 index 0000000..0428ee3 --- /dev/null +++ b/ksim/monitors/filesystem/filesystemwidget.cpp @@ -0,0 +1,232 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "filesystemwidget.h" + +#include <pluginmodule.h> + +#include <qlayout.h> +#include <qpopupmenu.h> +#include <qregexp.h> +#include <qcursor.h> + +#include <kprocess.h> +#include <kmessagebox.h> +#include <klocale.h> +#include <kiconloader.h> +#include <kdebug.h> + +FilesystemWidget::Filesystem::Filesystem() +{ + m_display = 0; +} + +FilesystemWidget::Filesystem::Filesystem(KSim::Progress *display, + const QString &point) +{ + m_display = display; + m_mountPoint = point; +} + +FilesystemWidget::Filesystem::~Filesystem() +{ + delete m_display; +} + +KSim::Progress *FilesystemWidget::Filesystem::display() const +{ + return m_display; +} + +const QString &FilesystemWidget::Filesystem::mountPoint() const +{ + return m_mountPoint; +} + +const QString &FilesystemWidget::Filesystem::text() const +{ + return m_display->text(); +} + +int FilesystemWidget::Filesystem::value() const +{ + return m_display->value(); +} + +void FilesystemWidget::Filesystem::setText(const QString &text) +{ + if (!m_display) + return; + + m_display->setText(text); +} + +void FilesystemWidget::Filesystem::setValue(int value) +{ + if (!m_display) + return; + + m_display->setValue(value); +} + +FilesystemWidget::FilesystemWidget(QWidget *parent, const char *name) + : QWidget(parent, name) +{ + m_list.setAutoDelete(true); + m_layout = new QVBoxLayout(this); + m_process = 0; +} + +FilesystemWidget::~FilesystemWidget() +{ + delete m_process; +} + +void FilesystemWidget::append(int max, const QString &mountPoint) +{ + KSim::Progress *progress = new KSim::Progress(max, this); + progress->installEventFilter(this); + progress->show(); + m_layout->addWidget(progress); + + m_list.append(new Filesystem(progress, mountPoint)); +} + +void FilesystemWidget::setText(uint id, const QString &text) +{ + if (id > m_list.count()) + return; + + m_list.at(id)->setText(text); +} + +void FilesystemWidget::setValue(uint id, int value) +{ + if (id > m_list.count()) + return; + + m_list.at(id)->setValue(value); +} + +void FilesystemWidget::clear() +{ + m_list.clear(); +} + +bool FilesystemWidget::eventFilter(QObject *o, QEvent *e) +{ + if (!o->isA("KSim::Progress")) + return QWidget::eventFilter(o, e); + + KSim::Progress *progressBar = 0; + int i = 0; + QPtrListIterator<Filesystem> it(m_list); + Filesystem *filesystem; + while ((filesystem = it.current()) != 0) { + ++it; + + if (filesystem->display() == o) { + progressBar = filesystem->display(); + break; + } + + ++i; + } + + if (o == progressBar && e->type() == QEvent::MouseButtonPress) + { + switch(static_cast<QMouseEvent *>(e)->button()) { + case QMouseEvent::RightButton: + showMenu(i); + break; + default: + break; + case QMouseEvent::LeftButton: + if (parentWidget()->inherits("KSim::PluginView")) + static_cast<KSim::PluginView *>(parentWidget())->doCommand(); + break; + } + + return true; + } + + return QWidget::eventFilter(o, e); +} + +void FilesystemWidget::receivedStderr(KProcess *, char *buffer, int length) +{ + m_stderrString.setLatin1(buffer, length); +} + +void FilesystemWidget::processExited(KProcess *) +{ + delete m_process; + m_process = 0; + kdDebug(2003) << "Deleting KProcess pointer" << endl; + + if (m_stderrString.isEmpty()) + return; + + QStringList errorList = QStringList::split("\n", m_stderrString); + QString message = i18n("<qt>The following errors occurred:<ul>"); + + QStringList::Iterator it; + for (it = errorList.begin(); it != errorList.end(); ++it) { + message += QString::fromLatin1("<li>%1</li>") + .arg((*it).replace(QRegExp("[u]?mount: "), QString::null)); + } + + message += QString::fromLatin1("</ul></qt>"); + KMessageBox::sorry(0, message); +} + +void FilesystemWidget::createProcess(const QString &command, const QString &point) +{ + m_process = new KProcess(); + connect(m_process, + SIGNAL(receivedStderr(KProcess *, char *, int)), + SLOT(receivedStderr(KProcess *, char *, int))); + connect(m_process, + SIGNAL(processExited(KProcess *)), + SLOT(processExited(KProcess *))); + + (*m_process) << command << point; + void(m_process->start(KProcess::NotifyOnExit, KProcess::Stderr)); +} + +void FilesystemWidget::showMenu(uint id) +{ + if (id > m_list.count()) + return; + + QPopupMenu menu; + menu.insertItem(SmallIcon("hdd_mount"), i18n("&Mount Device"), 1); + menu.insertItem(SmallIcon("hdd_unmount"), i18n("&Unmount Device"), 2); + + switch (menu.exec(QCursor::pos())) { + case 1: + createProcess("mount", m_list.at(id)->mountPoint()); + break; + case 2: + createProcess("umount", m_list.at(id)->mountPoint()); + break; + } +} + +#include "filesystemwidget.moc" diff --git a/ksim/monitors/filesystem/filesystemwidget.h b/ksim/monitors/filesystem/filesystemwidget.h new file mode 100644 index 0000000..d169b9a --- /dev/null +++ b/ksim/monitors/filesystem/filesystemwidget.h @@ -0,0 +1,78 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef FSYSTEM_WIDGET_H +#define FSYSTEM_WIDGET_H + +#include <progress.h> + +#include <qptrlist.h> + +class KProcess; +class QVBoxLayout; + +class FilesystemWidget : public QWidget +{ + Q_OBJECT + public: + FilesystemWidget(QWidget *parent, const char *name); + ~FilesystemWidget(); + + void append(int, const QString &); + void setText(uint, const QString &); + void setValue(uint, int); + void clear(); + + protected: + bool eventFilter(QObject *, QEvent *); + + private slots: + void receivedStderr(KProcess *, char *, int); + void processExited(KProcess *); + + private: + class Filesystem + { + public: + Filesystem(); + Filesystem(KSim::Progress *, const QString &); + ~Filesystem(); + + KSim::Progress *display() const; + const QString &mountPoint() const; + const QString &text() const; + int value() const; + + void setText(const QString &); + void setValue(int); + + QString m_mountPoint; + KSim::Progress *m_display; + }; + + void createProcess(const QString &, const QString &); + void showMenu(uint); + + typedef QPtrList<Filesystem> ProgressList; + ProgressList m_list; + QVBoxLayout *m_layout; + KProcess *m_process; + QString m_stderrString; +}; +#endif diff --git a/ksim/monitors/filesystem/fsystemconfig.cpp b/ksim/monitors/filesystem/fsystemconfig.cpp new file mode 100644 index 0000000..9b07ee4 --- /dev/null +++ b/ksim/monitors/filesystem/fsystemconfig.cpp @@ -0,0 +1,184 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "fsystemconfig.h" +#include "fsystemconfig.moc" + +#include <kconfig.h> +#include <klocale.h> +#include <kiconloader.h> +#include <klistview.h> +#include <kapplication.h> +#include <knuminput.h> +#include <kdebug.h> + +#include <qcheckbox.h> +#include <qlayout.h> +#include <qtooltip.h> +#include <qlabel.h> +#include <qwhatsthis.h> + +class FSysViewItem : public QCheckListItem +{ + public: + FSysViewItem(QListView *parent, const QString &text1, + const QString &text2, const QString &text3) + : QCheckListItem(parent, text1, CheckBox) + { + setText(1, text2); + setText(2, text3); + } +}; + +FsystemConfig::FsystemConfig(KSim::PluginObject *parent, const char *name) + : KSim::PluginPage(parent, name) +{ + m_mainLayout = new QGridLayout(this); + m_mainLayout->setSpacing(6); + + m_availableMounts = new KListView(this); + m_availableMounts->addColumn(i18n("Mounted Partition")); + m_availableMounts->addColumn(i18n("Device")); + m_availableMounts->addColumn(i18n("Type")); + m_mainLayout->addMultiCellWidget(m_availableMounts, 0, 0, 0, 3); + + m_showPercentage = new QCheckBox(this); + m_showPercentage->setText(i18n("Show percentage")); + m_mainLayout->addMultiCellWidget(m_showPercentage, 1, 1, 0, 3); + + m_splitNames = new QCheckBox(this); + m_splitNames->setText(i18n("Display short mount point names")); + QWhatsThis::add(m_splitNames, i18n("This option shortens the text" + " to shrink down a mount point. E.G: a mount point /home/myuser" + " would become myuser.")); + m_mainLayout->addMultiCellWidget(m_splitNames, 2, 2, 0, 3); + + m_intervalLabel = new QLabel(this); + m_intervalLabel->setText( i18n("Update interval:")); + m_intervalLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, + QSizePolicy::Fixed)); + m_mainLayout->addMultiCellWidget(m_intervalLabel, 3, 3, 0, 0); + + m_updateTimer = new KIntSpinBox(this); + m_updateTimer->setValue(60); + QToolTip::add(m_updateTimer, i18n("0 means no update")); + m_mainLayout->addMultiCellWidget(m_updateTimer, 3, 3, 1, 1); + + QLabel *intervalLabel = new QLabel(this); + intervalLabel->setText(i18n("seconds")); + intervalLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, + QSizePolicy::Fixed)); + m_mainLayout->addMultiCellWidget(intervalLabel, 3, 3, 2, 2); + + m_entries = FilesystemStats::readEntries(); + getStats(); +} + +FsystemConfig::~FsystemConfig() +{ +} + +void FsystemConfig::readConfig() +{ + config()->setGroup("Fsystem"); + m_showPercentage->setChecked(config()->readBoolEntry("ShowPercentage", true)); + m_updateTimer->setValue(config()->readNumEntry("updateValue", 60)); + m_splitNames->setChecked(config()->readBoolEntry("ShortenEntries", false)); + + if (!m_availableMounts->childCount()) + return; + + QStringList list = config()->readListEntry("mountEntries"); + for (QListViewItemIterator it(m_availableMounts); it.current(); ++it) { + QString string = it.current()->text(0) + ":" + splitString(it.current()->text(0)); + static_cast<QCheckListItem *>(it.current())->setOn(list.contains(string) > 0); + } +} + +void FsystemConfig::saveConfig() +{ + config()->setGroup("Fsystem"); + config()->writeEntry("ShowPercentage", m_showPercentage->isChecked()); + config()->writeEntry("updateValue", m_updateTimer->value()); + config()->writeEntry("ShortenEntries", m_splitNames->isChecked()); + + QStringList list; + for (QListViewItemIterator it(m_availableMounts); it.current(); ++it) { + if (static_cast<QCheckListItem *>(it.current())->isOn()) + list.append(it.current()->text(0) + ":" + splitString(it.current()->text(0))); + } + + config()->writeEntry("mountEntries", list); +} + +void FsystemConfig::showEvent(QShowEvent *) +{ + // FIXME: Maybe this is the slow method of doing this? + // Eitherway, i need to find a way to only update the list + // if the amount of mounted partitions has changed + FilesystemStats::List entries = FilesystemStats::readEntries(); + if ( entries.count() == m_entries.count() ) + return; + + m_entries = entries; + + // Update the entries to take into account + // any mounted/unmounted filesystems + m_availableMounts->clear(); + getStats(); +} + +void FsystemConfig::getStats() +{ + int total = 0; + int free = 0; + + FilesystemStats::List::ConstIterator it; + for ( it = m_entries.begin(); it != m_entries.end(); ++it ) + { + if ( !FilesystemStats::readStats( ( *it ).dir, total, free ) ) + continue; + + if ( !m_availableMounts->findItem( ( *it ).dir, 0 ) ) + { + (void) new FSysViewItem( m_availableMounts, ( *it ).dir, + ( *it ).fsname, ( *it ).type ); + } + } + + if (!m_availableMounts->childCount()) + return; + + config()->setGroup("Fsystem"); + QStringList list = config()->readListEntry("mountEntries"); + for (QListViewItemIterator it(m_availableMounts); it.current(); ++it) { + QString string = it.current()->text(0) + ":" + splitString(it.current()->text(0)); + static_cast<QCheckListItem *>(it.current())->setOn(list.contains(string) > 0); + } +} + +QString FsystemConfig::splitString(const QString &string) const +{ + if (string == "/" || !m_splitNames->isChecked()) + return string; + + int location = string.findRev("/"); + QString newString(string); + return newString.remove(0, location + 1); +} diff --git a/ksim/monitors/filesystem/fsystemconfig.h b/ksim/monitors/filesystem/fsystemconfig.h new file mode 100644 index 0000000..353dcf8 --- /dev/null +++ b/ksim/monitors/filesystem/fsystemconfig.h @@ -0,0 +1,58 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef FSYSTEMCONFIG_H +#define FSYSTEMCONFIG_H + +#include <pluginmodule.h> +#include "filesystemstats.h" + +class KIntSpinBox; +class KListView; +class QGridLayout; +class QCheckBox; +class QLabel; +class QListBoxItem; + +class FsystemConfig : public KSim::PluginPage +{ + Q_OBJECT + public: + FsystemConfig(KSim::PluginObject *parent, const char *name); + ~FsystemConfig(); + + virtual void saveConfig(); + virtual void readConfig(); + + protected: + void showEvent(QShowEvent *); + + private: + void getStats(); + QString splitString(const QString &string) const; + + QCheckBox *m_showPercentage; + QCheckBox *m_splitNames; + QLabel *m_intervalLabel; + KIntSpinBox *m_updateTimer; + KListView *m_availableMounts; + QGridLayout *m_mainLayout; + FilesystemStats::List m_entries; +}; +#endif // FILESYSTEM_H diff --git a/ksim/monitors/filesystem/fsystemiface.h b/ksim/monitors/filesystem/fsystemiface.h new file mode 100644 index 0000000..d590776 --- /dev/null +++ b/ksim/monitors/filesystem/fsystemiface.h @@ -0,0 +1,32 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 - 2004 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef FSYSTEMIFACE_H +#define FSYSTEMIFACE_H + +#include <dcopobject.h> + +class FsystemIface : virtual public DCOPObject +{ + K_DCOP + k_dcop: + virtual int totalFreeSpace() const = 0; +}; + +#endif // FSYSTEMIFACE_H diff --git a/ksim/monitors/filesystem/ksimfsystem.cpp b/ksim/monitors/filesystem/ksimfsystem.cpp new file mode 100644 index 0000000..3303f6d --- /dev/null +++ b/ksim/monitors/filesystem/ksimfsystem.cpp @@ -0,0 +1,202 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * $Id$ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <config.h> + +#include <qlayout.h> +#include <qvaluelist.h> +#include <qtimer.h> +#include <qfile.h> +#include <qregexp.h> + +#include <kdebug.h> +#include <klocale.h> +#include <kaboutapplication.h> +#include <kaboutdata.h> +#include <kapplication.h> +#include <kconfig.h> + +#include "ksimfsystem.h" +#include "fsystemconfig.h" +#include "filesystemwidget.h" +#include "filesystemstats.h" +#include <themeloader.h> + +KSIM_INIT_PLUGIN(PluginModule) + +PluginModule::PluginModule(const char *name) + : KSim::PluginObject(name) +{ + setConfigFileName(instanceName()); +} + +PluginModule::~PluginModule() +{ +} + +KSim::PluginView *PluginModule::createView(const char *className) +{ + return new Fsystem(this, className); +} + +KSim::PluginPage *PluginModule::createConfigPage(const char *className) +{ + return new FsystemConfig(this, className); +} + +void PluginModule::showAbout() +{ + QString version = kapp->aboutData()->version(); + + KAboutData aboutData(instanceName(), + I18N_NOOP("KSim FileSystem Plugin"), version.latin1(), + I18N_NOOP("A filesystem plugin for KSim"), + KAboutData::License_GPL, "(C) 2001 Robbie Ward"); + + aboutData.addAuthor("Robbie Ward", I18N_NOOP("Author"), + "linuxphreak@gmx.co.uk"); + aboutData.addAuthor("Jason Katz-Brown", I18N_NOOP("Some Fixes"), + "jason@katzbrown.com"); + aboutData.addAuthor("Heitham Omar", I18N_NOOP("FreeBSD ports"), + "super_ice@ntlworld.com"); + + KAboutApplication(&aboutData).exec(); +} + +Fsystem::Fsystem(KSim::PluginObject *parent, const char *name) + : DCOPObject("fsystem"), + KSim::PluginView(parent, name) +{ + config()->setGroup("Fsystem"); + QVBoxLayout *vbLayout = new QVBoxLayout(this); + vbLayout->setAutoAdd(true); + + QSpacerItem *item = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding); + vbLayout->addItem(item); + + m_mountEntries = makeList(config()->readListEntry("mountEntries")); + m_showPercentage = config()->readBoolEntry("ShowPercentage", true); + + m_widget = new FilesystemWidget(this, "FilesystemWidget"); + + createFreeInfo(); + + m_updateTimer = new QTimer(this); + connect(m_updateTimer, SIGNAL(timeout()), SLOT(updateFS())); + m_updateTimer->start(config()->readNumEntry("updateValue", 60) * 1000); +} + +Fsystem::~Fsystem() +{ +} + +void Fsystem::reparseConfig() +{ + config()->setGroup("Fsystem"); + + m_showPercentage = config()->readBoolEntry("ShowPercentage", true); + MountEntryList mountEntries = makeList(config()->readListEntry("mountEntries")); + + if (m_mountEntries != mountEntries) { + m_widget->clear(); + m_mountEntries = mountEntries; + createFreeInfo(); + } + + updateFS(); +} + +int Fsystem::totalFreeSpace() const +{ + int totalSize, totalFree; + int totalFreeSpace = 0; + MountEntryList::ConstIterator it; + for (it = m_mountEntries.begin(); it != m_mountEntries.end(); ++it) { + if ( FilesystemStats::readStats( ( *it ).first, totalSize, totalFree ) ) + totalFreeSpace += totalFree; + } + + return totalFreeSpace; +} + +void Fsystem::createFreeInfo() +{ + int total, free; + int i = 0; + MountEntryList::ConstIterator it; + for (it = m_mountEntries.begin(); it != m_mountEntries.end(); ++it) { + // returns the total space and free space from *it + // (the current mounted partition) + if ( !FilesystemStats::readStats( ( *it ).first, total, free ) ) + continue; + + int percent = 0; + if( total != 0) + percent = ((total - free) * 100) / total; + m_widget->append(total, (*it).first); + m_widget->setValue(i, total - free); + if (m_showPercentage) + m_widget->setText(i, ((*it).second.isEmpty() ? (*it).first : (*it).second) + + " - " + QString::number(percent) + "%"); + else + m_widget->setText(i, ((*it).second.isEmpty() ? (*it).first : (*it).second)); + i++; + } +} + +void Fsystem::updateFS() +{ + int total, free; + int i = 0; + MountEntryList::ConstIterator it; + for (it = m_mountEntries.begin(); it != m_mountEntries.end(); ++it) { + // returns the total space and free space from *it + // (the current mounted partition) + if ( !FilesystemStats::readStats( ( *it ).first, total, free ) ) + continue; + + int percent = 0; + if( total != 0 ) + percent = ((total - free) * 100) / total; + m_widget->setValue(i, total - free); + if (m_showPercentage) + m_widget->setText(i, ((*it).second.isEmpty() ? (*it).first : (*it).second) + + " - " + QString::number(percent) + "%"); + else + m_widget->setText(i, ((*it).second.isEmpty() ? (*it).first : (*it).second)); + i++; + } +} + +Fsystem::MountEntryList Fsystem::makeList(const QStringList &list) const +{ + MountEntryList newList; + QStringList splitList; + QStringList::ConstIterator it; + for (it = list.begin(); it != list.end(); ++it) { + splitList = QStringList::split(":", (*it)); + newList.append(qMakePair(splitList[0], splitList[1])); + } + + return newList; +} + +#include "ksimfsystem.moc" diff --git a/ksim/monitors/filesystem/ksimfsystem.h b/ksim/monitors/filesystem/ksimfsystem.h new file mode 100644 index 0000000..c3d403f --- /dev/null +++ b/ksim/monitors/filesystem/ksimfsystem.h @@ -0,0 +1,76 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef FSYSTEM_H +#define FSYSTEM_H + +#include <pluginmodule.h> +#include "fsystemiface.h" + +class KPopupMenu; +class FilesystemWidget; +class QTimer; + +/** + * This class is the filesystem monitor plugin + * + * @author Robbie Ward <linuxphreak@gmx.co.uk> + * @version 0.1 + */ +class PluginModule : public KSim::PluginObject +{ + public: + PluginModule(const char *name); + ~PluginModule(); + + virtual KSim::PluginView *createView(const char *); + virtual KSim::PluginPage *createConfigPage(const char *); + + virtual void showAbout(); +}; + +class Fsystem : public KSim::PluginView, public FsystemIface +{ + Q_OBJECT + public: + /** + * construtor of Fsystem, calls all init functions to create the plugin. + */ + Fsystem(KSim::PluginObject *parent, const char *name); + ~Fsystem(); + + virtual void reparseConfig(); + int totalFreeSpace() const; + + public slots: + void createFreeInfo(); + + private slots: + void updateFS(); + + private: + typedef QValueList<QPair<QString, QString> > MountEntryList; + MountEntryList makeList(const QStringList &list) const; + + FilesystemWidget *m_widget; + QTimer *m_updateTimer; + MountEntryList m_mountEntries; + bool m_showPercentage; +}; +#endif diff --git a/ksim/monitors/i8k/Makefile.am b/ksim/monitors/i8k/Makefile.am new file mode 100644 index 0000000..d46a0d9 --- /dev/null +++ b/ksim/monitors/i8k/Makefile.am @@ -0,0 +1,15 @@ +kde_module_LTLIBRARIES = ksim_i8k.la +ksim_i8k_la_SOURCES = ksimi8k.cpp + +ksim_i8k_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +ksim_i8k_la_LIBADD = ../../library/libksimcore.la + +EXTRA_DIST = i8k.desktop + +INCLUDES= -I$(top_srcdir)/ksim/library \ + $(all_includes) + +METASOURCES = AUTO + +mon_DATA = i8k.desktop +mondir = $(kde_datadir)/ksim/monitors diff --git a/ksim/monitors/i8k/i8k.desktop b/ksim/monitors/i8k/i8k.desktop new file mode 100644 index 0000000..322fda3 --- /dev/null +++ b/ksim/monitors/i8k/i8k.desktop @@ -0,0 +1,62 @@ +[Desktop Entry] +Comment=Dell I8K Hardware Monitor Plugin +Comment[ar]=ملحق لمراقبة عتاد Dell I8K +Comment[bg]=Мониторинг на Dell I8K +Comment[bs]=Dell I8K dodatak za nadzor hardvera +Comment[ca]=Connector per a controlar el maquinari Dell I8K +Comment[cs]=Modul sledování hardwaru pro Dell I8K +Comment[cy]=Ategyn Arsylwydd Caledwedd Dell I8K +Comment[de]=Dell I8K Hardware Überwachungs-Plugin +Comment[el]=Πρόσθετο εποπτείας υλικού Dell I8K +Comment[es]=Extensión de monitorización de hardware para Dell I8K +Comment[et]=Dell I8K riistvara monitooringu plugin +Comment[eu]=Dell I8K Hardwarearen Plugin Begiralea +Comment[fa]=وصلۀ نمایشگر سختافزار Dell I8K +Comment[fi]=Dell I8K-laitteistomonitoriliitännäinen +Comment[fr]=Module de surveillance du Dell l8K +Comment[ga]=Breiseán Monatóireachta Cruaearraí Dell I8K +Comment[hi]=डेल I8K हार्डवेयर मॉनीटर प्लगइन +Comment[hu]=Dell I8K hardvermonitor bővítőmodul +Comment[is]=Íforrit til að fylgjast með Dell I8K vélbúnaði +Comment[it]=Plugin di controllo hardware Dell I8K +Comment[ja]=Dell I8K ハードウェアモニタプラグイン +Comment[ka]=Dell I8K მოწყობილობათა მონიტორის მოდული +Comment[kk]=Dell I8K жабдықтарын бақылау модулі +Comment[km]=កម្មវិធីជំនួយរបស់កម្មវិធីត្រួតពិនិត្យផ្នែករឹង Dell I8K +Comment[lt]=Dell I8K aparatinės įrangos stebėjimo priedas +Comment[mk]=Приклучок за следење на хардверот Dell I8K +Comment[ms]=Plug masuk Pemerhati Perkakasan Dell I8K +Comment[nb]=Programtillegg for overvåkning av maskinvare Dell I8K +Comment[nds]=Kiekmoduul för Dell I8K-Hardware +Comment[ne]=डेल I8K हार्डवेयर मोनिटर प्लगइन +Comment[nl]=Dell I8000 Hardware Monitor-plugin +Comment[nn]=Programtillegg for overvaking av Dell I8K-maskinvare +Comment[pa]=Dell I8K ਜੰਤਰ ਨਿਗਰਾਨ ਪਲੱਗਿੰਨ +Comment[pl]=Wtyczka monitorowania Dell I8K +Comment[pt]='Plugin' de monitorização de hardware para o Dell I8K +Comment[pt_BR]=Plug-in de monitoramento do Hardware Dell I8K +Comment[ro]=Modul monitorizare Dell I8K +Comment[ru]=Модуль монитора оборудования Dell I8K +Comment[sk]=Modul pre monitorovanie hardware Dell I8K +Comment[sl]=Vstavek za opazovanje strojne opreme Dell I8K +Comment[sr]=Прикључак за надгледање Dell-овог I8K хардвера +Comment[sr@Latn]=Priključak za nadgledanje Dell-ovog I8K hardvera +Comment[sv]=Insticksprogram för Dell I8K-övervakning +Comment[ta]=டெல்I8K வன்பொருள் கண்காணி சொருகுபொருள் +Comment[tg]=Модули Дидабони Сахтафзори Dell I8K +Comment[tr]=Dell I8K Donanım Monitör Plugini +Comment[uk]=Втулок датчика апаратного забезпечення Dell I8K +Comment[wa]=Tchôke-divins di corwaitaedje di l' éndjolreye pol Dell I8K +Comment[zh_CN]=Dell I8K 硬件邮件监视器插件 +Comment[zh_TW]=Dell I8K 硬體監視器外掛程式 +Icon=hdd_mount +Name=Dell I8K +Name[fr]=Dell l8K +Name[he]=Dell l8k +Name[hi]=डेल I8K +Name[nb]=Dell 18K +Name[ne]=डेल I8K +Name[sr]=Dell-ов I8K +Name[sr@Latn]=Dell-ov I8K +Name[ta]= டெல் I8K +X-KSIM-LIBRARY=i8k diff --git a/ksim/monitors/i8k/ksimi8k.cpp b/ksim/monitors/i8k/ksimi8k.cpp new file mode 100644 index 0000000..ff995b0 --- /dev/null +++ b/ksim/monitors/i8k/ksimi8k.cpp @@ -0,0 +1,257 @@ +/* Dell i8K Hardware Monitor Plug-in for KSim + * + * Copyright (C) 2003 Nadeem Hasan <nhasan@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "ksimi8k.h" + +#include <qlayout.h> +#include <qtimer.h> +#include <qfile.h> +#include <qtextstream.h> +#include <qregexp.h> +#include <qlabel.h> +#include <qcheckbox.h> + +#include <label.h> +#include <klocale.h> +#include <kapplication.h> +#include <kconfig.h> +#include <kaboutapplication.h> +#include <knuminput.h> +#include <kdebug.h> + +KSIM_INIT_PLUGIN(I8KPlugin); + +I8KPlugin::I8KPlugin(const char *name) + : KSim::PluginObject(name) +{ + setConfigFileName(instanceName()); +} + +I8KPlugin::~I8KPlugin() +{ +} + +KSim::PluginView *I8KPlugin::createView(const char *className) +{ + return new I8KView(this, className); +} + +KSim::PluginPage *I8KPlugin::createConfigPage(const char *className) +{ + return new I8KConfig(this, className); +} + +void I8KPlugin::showAbout() +{ + QString version = kapp->aboutData()->version(); + + KAboutData aboutData(instanceName(), + I18N_NOOP("KSim I8K Plugin"), version.latin1(), + I18N_NOOP("Dell I8K Hardware Monitor plugin"), + KAboutData::License_GPL, "(C) 2003 Nadeem Hasan"); + + aboutData.addAuthor("Nadeem Hasan", I18N_NOOP("Author"), + "nhasan@kde.org"); + + KAboutApplication(&aboutData).exec(); +} + +I8KView::I8KView(KSim::PluginObject *parent, const char *name) + : KSim::PluginView(parent, name), + m_timer( 0L ), m_procFile( 0L ), m_procStream( 0L ) +{ + initGUI(); + + m_timer = new QTimer( this ); + + m_reData = new QRegExp( "\\S+\\s+\\S+\\s+\\S+\\s+(\\d+)\\s+\\S+" + "\\s+\\S+\\s+(\\d+)\\s+(\\d+)\\s+\\S+\\s+\\S+" ); + + openStream(); + reparseConfig(); +} + +I8KView::~I8KView() +{ + closeStream(); + + delete m_timer; + delete m_reData; +} + +void I8KView::reparseConfig() +{ + config()->setGroup("I8KPlugin"); + + m_unit = config()->readEntry( "Unit", "C" ); + m_interval = config()->readNumEntry( "Interval", 5 ); + + if ( m_procStream ) + { + m_timer->stop(); + m_timer->start( m_interval*1000 ); + } + + updateView(); +} + +void I8KView::openStream() +{ + kdDebug( 2003 ) << "i8k: Trying /proc/i8k...." << endl; + + m_timer->stop(); + + if ( ( m_procFile = fopen( "/proc/i8k", "r" ) ) ) + { + m_procStream = new QTextIStream( m_procFile ); + disconnect( m_timer, 0, 0, 0 ); + connect( m_timer, SIGNAL( timeout() ), SLOT( updateView() ) ); + m_timer->start( m_interval*1000 ); + + kdDebug( 2003 ) << "i8k: Success" << endl; + } + else + { + // i8k module is not loaded. Try again after 30 secs. + disconnect( m_timer, 0, 0, 0 ); + connect( m_timer, SIGNAL( timeout() ), SLOT( openStream() ) ); + m_timer->start( 30*1000 ); + kdDebug( 2003 ) << "i8k: Failed...retry after 30 secs" << endl; + } +} + +void I8KView::closeStream() +{ + if ( m_procFile ) + fclose( m_procFile ); + + if ( m_procStream ) + delete m_procStream; + + m_procFile = 0L; + m_procStream = 0L; + m_timer->stop(); +} + +void I8KView::initGUI() +{ + QVBoxLayout *layout = new QVBoxLayout( this ); + + m_fan1Label = new KSim::Label( this ); + m_fan2Label = new KSim::Label( this ); + m_tempLabel = new KSim::Label( this ); + + layout->addWidget( m_fan1Label ); + layout->addWidget( m_fan2Label ); + layout->addWidget( m_tempLabel ); +} + +void I8KView::updateView() +{ + kdDebug( 2003 ) << "i8k: Updating..." << endl; + int cputemp=0, rightspeed=0, leftspeed=0; + + if ( m_procStream ) + { + fseek( m_procFile, 0L, SEEK_SET ); + + QString line = m_procStream->read(); + + if ( line.isEmpty() ) + { + // i8k module is no longer available, is it possible? + closeStream(); + openStream(); + return; + } + + if ( m_reData->search( line ) > -1 ) + { + QStringList matches = m_reData->capturedTexts(); + + cputemp = matches[ 1 ].toInt(); + leftspeed = matches[ 2 ].toInt(); + rightspeed = matches[ 3 ].toInt(); + + if ( m_unit == "F" ) + cputemp = ( cputemp*9/5 ) + 32; + } + } + + if ( rightspeed > 0 ) + m_fan1Label->setText( i18n( "Right fan: %1 RPM" ).arg( rightspeed ) ); + else + m_fan1Label->setText( i18n( "Right fan: Off" ) ); + + if ( leftspeed > 0 ) + m_fan2Label->setText( i18n( "Left fan: %1 RPM" ).arg( leftspeed ) ); + else + m_fan2Label->setText( i18n( "Left fan: Off" ) ); + + m_tempLabel->setText( i18n( "CPU temp: %1°%2" ).arg( cputemp ) + .arg( m_unit ) ); +} + +I8KConfig::I8KConfig(KSim::PluginObject *parent, const char *name) + : KSim::PluginPage(parent, name) +{ + m_unit = new QCheckBox( i18n( "Show temperature in Fahrenheit" ), + this ); + QLabel *label = new QLabel( i18n( "Update interval:" ), this ); + m_interval = new KIntNumInput( this ); + m_interval->setRange( 2, 60, 1, true ); + m_interval->setSuffix( i18n( " sec" ) ); + + QGridLayout *layout = new QGridLayout( this, 3, 2, 0, + KDialog::spacingHint() ); + + layout->addMultiCellWidget( m_unit, 0, 0, 0, 1 ); + layout->addWidget( label, 1, 0 ); + layout->addWidget( m_interval, 1, 1 ); + layout->setColStretch( 1, 1 ); + layout->setRowStretch( 2, 1 ); +} + +I8KConfig::~I8KConfig() +{ +} + +void I8KConfig::readConfig() +{ + config()->setGroup("I8KPlugin"); + + QString unit = config()->readEntry( "Unit", "C" ); + int interval = config()->readNumEntry( "Interval", 5 ); + + m_unit->setChecked( unit == "F" ); + m_interval->setValue( interval ); +} + +void I8KConfig::saveConfig() +{ + config()->setGroup("I8KPlugin"); + + config()->writeEntry( "Unit", m_unit->isChecked()? "F" : "C" ); + config()->writeEntry( "Interval", m_interval->value() ); +} + +#include "ksimi8k.moc" + +/* vim: et sw=2 ts=2 +*/ diff --git a/ksim/monitors/i8k/ksimi8k.h b/ksim/monitors/i8k/ksimi8k.h new file mode 100644 index 0000000..4357508 --- /dev/null +++ b/ksim/monitors/i8k/ksimi8k.h @@ -0,0 +1,102 @@ +/* Dell i8K Hardware Monitor Plug-in for KSim + * + * Copyright (C) 2003 Nadeem Hasan <nhasan@kde.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KSIMI8K_H +#define KSIMI8K_H + +#include <stdio.h> + +#include <pluginmodule.h> + +class QTimer; +class QTextIStream; +class QRegExp; +class QCheckBox; +class KIntNumInput; + +namespace KSim +{ + class Label; +} + +class I8KPlugin : public KSim::PluginObject +{ + public: + I8KPlugin(const char *name); + ~I8KPlugin(); + + virtual KSim::PluginView *createView(const char *); + virtual KSim::PluginPage *createConfigPage(const char *); + + virtual void showAbout(); +}; + +class I8KView : public KSim::PluginView +{ + Q_OBJECT + public: + I8KView(KSim::PluginObject *parent, const char *name); + ~I8KView(); + + virtual void reparseConfig(); + + protected: + + void initGUI(); + void closeStream(); + + protected slots: + + void openStream(); + void updateView(); + + private: + + QString m_unit; + int m_interval; + + KSim::Label *m_fan1Label, *m_fan2Label, *m_tempLabel; + QTimer *m_timer; + FILE *m_procFile; + QTextIStream *m_procStream; + QRegExp *m_reData; +}; + +class I8KConfig : public KSim::PluginPage +{ + Q_OBJECT + public: + I8KConfig(KSim::PluginObject *parent, const char *name); + ~I8KConfig(); + + virtual void saveConfig(); + virtual void readConfig(); + + private slots: + + private: + + QCheckBox *m_unit; + KIntNumInput *m_interval; +}; + +#endif // KSIMI8K_H + +/* vim: et sw=2 ts=2 +*/ diff --git a/ksim/monitors/lm_sensors/Lm_sensors.desktop b/ksim/monitors/lm_sensors/Lm_sensors.desktop new file mode 100644 index 0000000..d700e0d --- /dev/null +++ b/ksim/monitors/lm_sensors/Lm_sensors.desktop @@ -0,0 +1,84 @@ +[Desktop Entry] +Comment=Lm_sensors Status Monitor +Comment[ar]=مراقب حالة Lm_sensors +Comment[bg]=Мониторинг на Lm_sensors +Comment[bs]=Nadzor statusa lm_sensors +Comment[ca]=Monitor de l'estat de Lm_sensors +Comment[cs]=Monitor stavu lm_sensorů +Comment[cy]=Monitr Statws Lm_sensors +Comment[da]=Statusovervågning af lm_følere +Comment[de]=Statusanzeige für LM-Sensoren +Comment[el]=Επόπτης κατάστασης lm_sensors +Comment[eo]=Rigardilo por la stato de Lm-sentiloj +Comment[es]=Monitor de estado de los sensores Lm +Comment[et]=Lm_sensors olekute monitooring +Comment[eu]=Lm_sentsoreen Egoera Begiralea +Comment[fa]=Lm_نمایشگر وضعیت حسگرهای +Comment[fi]=Lm_sensors tilavalvonta +Comment[fr]=Indicateur d'état lm_sensors +Comment[ga]=Monatóir Stádais Lm_sensors +Comment[he]=צג מצב Lm_sensors +Comment[hi]=एलएम_सेंसर्स स्थिति मॉनीटर +Comment[hu]=Lm_sensors hardvermonitor +Comment[is]=Eftirlit með stöðu Lm_sensors +Comment[it]=Controllo di stato Lm_sensors +Comment[ja]=Lm センサーの状態モニタ +Comment[ka]=Lm_sensors სტატუსის მონიტორი +Comment[kk]=Lm_sensor сенсорларының күйін бақылау +Comment[km]=កម្មវិធីត្រួតពិនិត្យស្ថានភាព Lm_sensors +Comment[lt]=Lm_sensors būsenos stebėtojas +Comment[mk]=Монитор за статусот на Lm_sensors +Comment[ms]=Pemerhati Status Lm_sensors +Comment[nb]=Statusovervåkning av Lm_sensorer +Comment[nds]=LM_Sensors-Statuskieker +Comment[ne]=Lm_sensors स्थिति मोनिटर +Comment[nl]=Lm_sensors statusmonitor +Comment[nn]=Lm_sensors-statusovervaking +Comment[pa]=Lm_sensors ਹਾਲਤ ਨਿਗਰਾਨ +Comment[pl]=Stan Lm_sensors +Comment[pt]=Monitor de Estado do Lm_sensors +Comment[pt_BR]=Monitor de estado dos sensores do sistema +Comment[ro]=Monitor stare lm_sensors +Comment[ru]=Монитор состояния датчиков lm_sensors +Comment[sk]=Monitor stavu lm_sensors +Comment[sl]=Nadzornik stanja Lm_senzorji +Comment[sr]=Надгледање статуса lm-сензора +Comment[sr@Latn]=Nadgledanje statusa lm-senzora +Comment[sv]=Lm_sensors statusövervakare +Comment[ta]=Lm_உணர்கருவி நிலை கண்காணி +Comment[tg]=Дидабони Ҳолати Lm_sensors +Comment[th]=Lm_sensors - เครื่องมือสอดส่องสถานะ +Comment[tr]=Lm_sensors Durum İzleyici +Comment[uk]=Монітор стану Lm_sensors +Comment[zh_CN]=Lm_sensors 状态监视器 +Comment[zh_TW]=Lm_sensors 狀態監視器 +Comment[zu]=Umlawuli Wezinga we-Lm_sensors +Icon=memory +Name=Lm_sensors +Name[cs]=Lm_sensory +Name[da]=Lm_følere +Name[de]=LM-Sensoren +Name[eo]=Lm-sentiloj +Name[es]=Sensores Lm +Name[eu]=Lm_sentsoreak +Name[fa]=Lm_حسگرهای +Name[he]=חיישנים +Name[hi]=एलएम_सेंसर्स +Name[ja]=Lm センサー +Name[kk]=Lm_sensor сенсорлары +Name[ko]=Lm 센서 +Name[lv]=Lm_sensori +Name[nb]=Lm_sensorer +Name[nds]=LM-Sensoren +Name[ro]=Senzori LM +Name[ru]=Датчики lm_sensors +Name[sl]=Lm_senzorji +Name[sr]=Lm-сензори +Name[sr@Latn]=Lm-senzori +Name[ta]= Lm_சென்சார்ஸ் +X-KSIM-VERSION=0.1 +X-KSIM-LIBRARY=sensors +X-KSIM-PREFS=Sensors +X-KSIM-AUTHOR=Robbie Ward +X-KSIM-EMAIL=linuxphreak@gmx.co.uk +X-KSIM-COPYRIGHT=(C) 2001 Robbie Ward diff --git a/ksim/monitors/lm_sensors/Makefile.am b/ksim/monitors/lm_sensors/Makefile.am new file mode 100644 index 0000000..182e01c --- /dev/null +++ b/ksim/monitors/lm_sensors/Makefile.am @@ -0,0 +1,26 @@ +kde_module_LTLIBRARIES = ksim_sensors.la + +if include_nv +NVCTRL_LIB= NVCtrl.la +NVCtrl_la_SOURCES = NVCtrl.c +NVCtrl_la_LDFLAGS = -module $(all_libraries) $(KDE_PLUGIN) +endif + +noinst_LTLIBRARIES = $(NVCTRL_LIB) + +ksim_sensors_la_SOURCES = ksimsensors.cpp sensorsconfig.cpp \ + sensorbase.cpp ksimsensorsiface.skel + +ksim_sensors_la_LDFLAGS = $(all_libraries) -module -avoid-version +ksim_sensors_la_LIBADD = ../../library/libksimcore.la $(NVCTRL_LIB) + +EXTRA_DIST = Lm_sensors.desktop + +INCLUDES = -I$(top_srcdir)/ksim/library \ + -I$(top_srcdir)/ksim \ + $(all_includes) + +METASOURCES = AUTO + +mon_DATA = Lm_sensors.desktop +mondir = $(kde_datadir)/ksim/monitors diff --git a/ksim/monitors/lm_sensors/NVCtrl.c b/ksim/monitors/lm_sensors/NVCtrl.c new file mode 100644 index 0000000..6c61b8a --- /dev/null +++ b/ksim/monitors/lm_sensors/NVCtrl.c @@ -0,0 +1,357 @@ +/* + * Copyright (C) 2004 NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of Version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See Version 2 + * of the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + * + */ + +#define NEED_EVENTS +#define NEED_REPLIES +#include <X11/Xlibint.h> +#include <X11/Xutil.h> +#include <X11/extensions/Xext.h> +#include <X11/extensions/extutil.h> +#include "NVCtrlLib.h" +#include "nv_control.h" + + +static XExtensionInfo _nvctrl_ext_info_data; +static XExtensionInfo *nvctrl_ext_info = &_nvctrl_ext_info_data; +static const char *nvctrl_extension_name = NV_CONTROL_NAME; + +#define XNVCTRLCheckExtension(dpy,i,val) \ + XextCheckExtension (dpy, i, nvctrl_extension_name, val) +#define XNVCTRLSimpleCheckExtension(dpy,i) \ + XextSimpleCheckExtension (dpy, i, nvctrl_extension_name) + +static int close_display(); +static Bool wire_to_event(); +static const XExtensionHooks nvctrl_extension_hooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + close_display, /* close_display */ + wire_to_event, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; + +static XEXT_GENERATE_FIND_DISPLAY (find_display, nvctrl_ext_info, + nvctrl_extension_name, + &nvctrl_extension_hooks, + NV_CONTROL_EVENTS, NULL) + +static XEXT_GENERATE_CLOSE_DISPLAY (close_display, nvctrl_ext_info) + +Bool XNVCTRLQueryExtension ( + Display *dpy, + int *event_basep, + int *error_basep +){ + XExtDisplayInfo *info = find_display (dpy); + + if (XextHasExtension(info)) { + if (event_basep) *event_basep = info->codes->first_event; + if (error_basep) *error_basep = info->codes->first_error; + return True; + } else { + return False; + } +} + + +Bool XNVCTRLQueryVersion ( + Display *dpy, + int *major, + int *minor +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlQueryExtensionReply rep; + xnvCtrlQueryExtensionReq *req; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlQueryExtension, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryExtension; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + if (major) *major = rep.major; + if (minor) *minor = rep.minor; + UnlockDisplay (dpy); + SyncHandle (); + return True; +} + + +Bool XNVCTRLIsNvScreen ( + Display *dpy, + int screen +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlIsNvReply rep; + xnvCtrlIsNvReq *req; + Bool isnv; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlIsNv, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlIsNv; + req->screen = screen; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + isnv = rep.isnv; + UnlockDisplay (dpy); + SyncHandle (); + return isnv; +} + + +void XNVCTRLSetAttribute ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + int value +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlSetAttributeReq *req; + + XNVCTRLSimpleCheckExtension (dpy, info); + + LockDisplay (dpy); + GetReq (nvCtrlSetAttribute, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlSetAttribute; + req->screen = screen; + req->display_mask = display_mask; + req->attribute = attribute; + req->value = value; + UnlockDisplay (dpy); + SyncHandle (); +} + + +Bool XNVCTRLQueryAttribute ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + int *value +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlQueryAttributeReply rep; + xnvCtrlQueryAttributeReq *req; + Bool exists; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlQueryAttribute, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryAttribute; + req->screen = screen; + req->display_mask = display_mask; + req->attribute = attribute; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + if (value) *value = rep.value; + exists = rep.flags; + UnlockDisplay (dpy); + SyncHandle (); + return exists; +} + + +Bool XNVCTRLQueryStringAttribute ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + char **ptr +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlQueryStringAttributeReply rep; + xnvCtrlQueryStringAttributeReq *req; + Bool exists; + int length, numbytes, slop; + + if (!ptr) return False; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlQueryStringAttribute, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryStringAttribute; + req->screen = screen; + req->display_mask = display_mask; + req->attribute = attribute; + if (!_XReply (dpy, (xReply *) &rep, 0, False)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + length = rep.length; + numbytes = rep.n; + slop = numbytes & 3; + *ptr = (char *) Xmalloc(numbytes); + if (! *ptr) { + _XEatData(dpy, length); + UnlockDisplay (dpy); + SyncHandle (); + return False; + } else { + _XRead(dpy, (char *) *ptr, numbytes); + if (slop) _XEatData(dpy, 4-slop); + } + exists = rep.flags; + UnlockDisplay (dpy); + SyncHandle (); + return exists; +} + +Bool XNVCTRLQueryValidAttributeValues ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + NVCTRLAttributeValidValuesRec *values +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlQueryValidAttributeValuesReply rep; + xnvCtrlQueryValidAttributeValuesReq *req; + Bool exists; + + if (!values) return False; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlQueryValidAttributeValues, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryValidAttributeValues; + req->screen = screen; + req->display_mask = display_mask; + req->attribute = attribute; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + exists = rep.flags; + values->type = rep.attr_type; + if (rep.attr_type == ATTRIBUTE_TYPE_RANGE) { + values->u.range.min = rep.min; + values->u.range.max = rep.max; + } + if (rep.attr_type == ATTRIBUTE_TYPE_INT_BITS) { + values->u.bits.ints = rep.bits; + } + values->permissions = rep.perms; + UnlockDisplay (dpy); + SyncHandle (); + return exists; +} + +Bool XNVCtrlSelectNotify ( + Display *dpy, + int screen, + int type, + Bool onoff +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlSelectNotifyReq *req; + + if(!XextHasExtension (info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlSelectNotify, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlSelectNotify; + req->screen = screen; + req->notifyType = type; + req->onoff = onoff; + UnlockDisplay (dpy); + SyncHandle (); + + return True; +} + +static Bool wire_to_event (Display *dpy, XEvent *host, xEvent *wire) +{ + XExtDisplayInfo *info = find_display (dpy); + XNVCtrlEvent *re = (XNVCtrlEvent *) host; + xnvctrlEvent *event = (xnvctrlEvent *) wire; + + XNVCTRLCheckExtension (dpy, info, False); + + switch ((event->u.u.type & 0x7F) - info->codes->first_event) { + case ATTRIBUTE_CHANGED_EVENT: + re->attribute_changed.type = event->u.u.type & 0x7F; + re->attribute_changed.serial = + _XSetLastRequestRead(dpy, (xGenericReply*) event); + re->attribute_changed.send_event = ((event->u.u.type & 0x80) != 0); + re->attribute_changed.display = dpy; + re->attribute_changed.time = event->u.attribute_changed.time; + re->attribute_changed.screen = event->u.attribute_changed.screen; + re->attribute_changed.display_mask = + event->u.attribute_changed.display_mask; + re->attribute_changed.attribute = event->u.attribute_changed.attribute; + re->attribute_changed.value = event->u.attribute_changed.value; + break; + default: + return False; + } + + return True; +} + diff --git a/ksim/monitors/lm_sensors/NVCtrl.h b/ksim/monitors/lm_sensors/NVCtrl.h new file mode 100644 index 0000000..81c9432 --- /dev/null +++ b/ksim/monitors/lm_sensors/NVCtrl.h @@ -0,0 +1,807 @@ +/* + * Copyright (C) 2004 NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of Version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See Version 2 + * of the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + * + */ + +#ifndef __NVCTRL_H +#define __NVCTRL_H + +/**************************************************************************/ +/* + * Integer attributes; these are settable/gettable via + * XNVCTRLSetAttribute() and XNVCTRLQueryAttribute, respectively. + * Some attributes may only be read; some may require a display_mask + * argument. This information is encoded in the "permission" comment + * after each attribute #define, and can be queried at run time with + * XNVCTRLQueryValidAttributeValues(). + * + * Key to Integer Attribute "Permissions": + * + * R: The attribute is readable (in general, all attributes will be + * readable) + * + * W: The attribute is writable (attributes may not be writable for + * various reasons: they represent static system information, they + * can only be changed by changing an XF86Config option, etc). + * + * D: The attribute requires the display mask argument. The + * attributes NV_CTRL_CONNECTED_DISPLAYS and NV_CTRL_ENABLED_DISPLAYS + * will be a bitmask of what display devices are connected and what + * display devices are enabled for use in X, respectively. Each bit + * in the bitmask represents a display device; it is these bits which + * should be used as the display_mask when dealing with attributes + * designated with "D" below. For attributes that do not require the + * display mask, the argument is ignored. + */ + + +/**************************************************************************/ + + +/* + * NV_CTRL_FLATPANEL_SCALING - the current flatpanel scaling state; + * possible values are: + * + * 0: default (the driver will use whatever state is current) + * 1: native (the driver will use the panel's scaler, if possible) + * 2: scaled (the driver will use the GPU's scaler, if possible) + * 3: centered (the driver will center the image) + * 4: aspect scaled (scale with the GPU's scaler, but keep the aspect + * ratio correct) + */ + +#define NV_CTRL_FLATPANEL_SCALING 2 /* RWD */ +#define NV_CTRL_FLATPANEL_SCALING_DEFAULT 0 +#define NV_CTRL_FLATPANEL_SCALING_NATIVE 1 +#define NV_CTRL_FLATPANEL_SCALING_SCALED 2 +#define NV_CTRL_FLATPANEL_SCALING_CENTERED 3 +#define NV_CTRL_FLATPANEL_SCALING_ASPECT_SCALED 4 + + +/* + * NV_CTRL_FLATPANEL_DITHERING - the current flatpanel dithering + * state; possible values are: + * + * 0: default (the driver will decide when to dither) + * 1: enabled (the driver will always dither when possible) + * 2: disabled (the driver will never dither) + */ + +#define NV_CTRL_FLATPANEL_DITHERING 3 /* RWD */ +#define NV_CTRL_FLATPANEL_DITHERING_DEFAULT 0 +#define NV_CTRL_FLATPANEL_DITHERING_ENABLED 1 +#define NV_CTRL_FLATPANEL_DITHERING_DISABLED 2 + + +/* + * NV_CTRL_DIGITAL_VIBRANCE - sets the digital vibrance level for the + * specified display device. + */ + +#define NV_CTRL_DIGITAL_VIBRANCE 4 /* RWD */ + + +/* + * NV_CTRL_BUS_TYPE - returns the Bus type through which the GPU + * driving the specified X screen is connected to the computer. + */ + +#define NV_CTRL_BUS_TYPE 5 /* R-- */ +#define NV_CTRL_BUS_TYPE_AGP 0 +#define NV_CTRL_BUS_TYPE_PCI 1 +#define NV_CTRL_BUS_TYPE_PCI_EXPRESS 2 + + +/* + * NV_CTRL_VIDEO_RAM - returns the amount of video ram on the GPU + * driving the specified X screen. + */ + +#define NV_CTRL_VIDEO_RAM 6 /* R-- */ + + +/* + * NV_CTRL_IRQ - returns the interrupt request line used by the GPU + * driving the specified X screen. + */ + +#define NV_CTRL_IRQ 7 /* R-- */ + + +/* + * NV_CTRL_OPERATING_SYSTEM - returns the operating system on which + * the X server is running. + */ + +#define NV_CTRL_OPERATING_SYSTEM 8 /* R-- */ +#define NV_CTRL_OPERATING_SYSTEM_LINUX 0 +#define NV_CTRL_OPERATING_SYSTEM_FREEBSD 1 + + +/* + * NV_CTRL_SYNC_TO_VBLANK - enables sync to vblank for OpenGL clients. + * This setting is only applied to OpenGL clients that are started + * after this setting is applied. + */ + +#define NV_CTRL_SYNC_TO_VBLANK 9 /* RW- */ +#define NV_CTRL_SYNC_TO_VBLANK_OFF 0 +#define NV_CTRL_SYNC_TO_VBLANK_ON 1 + + +/* + * NV_CTRL_LOG_ANISO - enables anisotropic filtering for OpenGL + * clients; on some NVIDIA hardware, this can only be enabled or + * disabled; on other hardware different levels of anisotropic + * filtering can be specified. This setting is only applied to OpenGL + * clients that are started after this setting is applied. + */ + +#define NV_CTRL_LOG_ANISO 10 /* RW- */ + + +/* + * NV_CTRL_FSAA_MODE - the FSAA setting for OpenGL clients; possible + * FSAA modes: + * + * NV_CTRL_FSAA_MODE_2x "2x Bilinear Multisampling" + * NV_CTRL_FSAA_MODE_2x_5t "2x Quincunx Multisampling" + * NV_CTRL_FSAA_MODE_15x15 "1.5 x 1.5 Supersampling" + * NV_CTRL_FSAA_MODE_2x2 "2 x 2 Supersampling" + * NV_CTRL_FSAA_MODE_4x "4x Bilinear Multisampling" + * NV_CTRL_FSAA_MODE_4x_9t "4x Gaussian Multisampling" + * NV_CTRL_FSAA_MODE_8x "2x Bilinear Multisampling by 4x Supersampling" + * NV_CTRL_FSAA_MODE_16x "4x Bilinear Multisampling by 4x Supersampling" + * + * This setting is only applied to OpenGL clients that are started + * after this setting is applied. + */ + +#define NV_CTRL_FSAA_MODE 11 /* RW- */ +#define NV_CTRL_FSAA_MODE_NONE 0 +#define NV_CTRL_FSAA_MODE_2x 1 +#define NV_CTRL_FSAA_MODE_2x_5t 2 +#define NV_CTRL_FSAA_MODE_15x15 3 +#define NV_CTRL_FSAA_MODE_2x2 4 +#define NV_CTRL_FSAA_MODE_4x 5 +#define NV_CTRL_FSAA_MODE_4x_9t 6 +#define NV_CTRL_FSAA_MODE_8x 7 +#define NV_CTRL_FSAA_MODE_16x 8 + + +/* + * NV_CTRL_TEXTURE_SHARPEN - enables texture sharpening for OpenGL + * clients. This setting is only applied to OpenGL clients that are + * started after this setting is applied. + */ + +#define NV_CTRL_TEXTURE_SHARPEN 12 /* RW- */ +#define NV_CTRL_TEXTURE_SHARPEN_OFF 0 +#define NV_CTRL_TEXTURE_SHARPEN_ON 1 + + +/* + * NV_CTRL_UBB - returns whether UBB is enabled for the specified X + * screen. + */ + +#define NV_CTRL_UBB 13 /* R-- */ +#define NV_CTRL_UBB_OFF 0 +#define NV_CTRL_UBB_ON 1 + + +/* + * NV_CTRL_OVERLAY - returns whether the RGB overlay is enabled for + * the specified X screen. + */ + +#define NV_CTRL_OVERLAY 14 /* R-- */ +#define NV_CTRL_OVERLAY_OFF 0 +#define NV_CTRL_OVERLAY_ON 1 + + +/* + * NV_CTRL_STEREO - returns whether stereo (and what type) is enabled + * for the specified X screen. + */ + +#define NV_CTRL_STEREO 16 /* R-- */ +#define NV_CTRL_STEREO_OFF 0 +#define NV_CTRL_STEREO_DDC 1 +#define NV_CTRL_STEREO_BLUELINE 2 +#define NV_CTRL_STEREO_DIN 3 +#define NV_CTRL_STEREO_TWINVIEW 4 + + +/* + * NV_CTRL_EMULATE - controls OpenGL software emulation of future + * NVIDIA GPUs. + */ + +#define NV_CTRL_EMULATE 17 /* RW- */ +#define NV_CTRL_EMULATE_NONE 0 + + +/* + * NV_CTRL_TWINVIEW - returns whether TwinView is enabled for the + * specified X screen. + */ + +#define NV_CTRL_TWINVIEW 18 /* R-- */ +#define NV_CTRL_TWINVIEW_NOT_ENABLED 0 +#define NV_CTRL_TWINVIEW_ENABLED 1 + + +/* + * NV_CTRL_CONNECTED_DISPLAYS - returns a display mask indicating what + * display devices are connected to the GPU driving the specified X + * screen. + */ + +#define NV_CTRL_CONNECTED_DISPLAYS 19 /* R-- */ + + +/* + * NV_CTRL_ENABLED_DISPLAYS - returns a display mask indicating what + * display devices are enabled for use on the specified X screen. + */ + +#define NV_CTRL_ENABLED_DISPLAYS 20 /* R-- */ + +/**************************************************************************/ +/* + * Integer attributes specific to configuring FrameLock on boards that + * support it. + */ + + +/* + * NV_CTRL_FRAMELOCK - returns whether this X screen supports + * FrameLock. All of the other FrameLock attributes are only + * applicable if NV_CTRL_FRAMELOCK is _SUPPORTED. + */ + +#define NV_CTRL_FRAMELOCK 21 /* R-- */ +#define NV_CTRL_FRAMELOCK_NOT_SUPPORTED 0 +#define NV_CTRL_FRAMELOCK_SUPPORTED 1 + + +/* + * NV_CTRL_FRAMELOCK_MASTER - get/set whether this X screen is the + * FrameLock master for the entire sync group. Note that only one + * node in the sync group should be configured as the master. + */ + +#define NV_CTRL_FRAMELOCK_MASTER 22 /* RW- */ +#define NV_CTRL_FRAMELOCK_MASTER_FALSE 0 +#define NV_CTRL_FRAMELOCK_MASTER_TRUE 1 + + +/* + * NV_CTRL_FRAMELOCK_POLARITY - sync either to the rising edge of the + * framelock pulse, or both the rising and falling edges of the + * framelock pulse. + */ + +#define NV_CTRL_FRAMELOCK_POLARITY 23 /* RW- */ +#define NV_CTRL_FRAMELOCK_POLARITY_RISING_EDGE 0x1 +#define NV_CTRL_FRAMELOCK_POLARITY_BOTH_EDGES 0x3 + + +/* + * NV_CTRL_FRAMELOCK_SYNC_DELAY - delay between the framelock pulse + * and the GPU sync. This is an 11 bit value which is multipled by + * 7.81 to determine the sync delay in microseconds. + */ + +#define NV_CTRL_FRAMELOCK_SYNC_DELAY 24 /* RW- */ +#define NV_CTRL_FRAMELOCK_SYNC_DELAY_MAX 2047 +#define NV_CTRL_FRAMELOCK_SYNC_DELAY_FACTOR 7.81 + +/* + * NV_CTRL_FRAMELOCK_SYNC_INTERVAL - how many house sync pulses + * between the FrameLock sync generation (0 == sync every house sync); + * this only applies to the master when receiving house sync. + */ + +#define NV_CTRL_FRAMELOCK_SYNC_INTERVAL 25 /* RW- */ + + +/* + * NV_CTRL_FRAMELOCK_PORT0_STATUS - status of the rj45 port0. + */ + +#define NV_CTRL_FRAMELOCK_PORT0_STATUS 26 /* R-- */ +#define NV_CTRL_FRAMELOCK_PORT0_STATUS_INPUT 0 +#define NV_CTRL_FRAMELOCK_PORT0_STATUS_OUTPUT 1 + + +/* + * NV_CTRL_FRAMELOCK_PORT1_STATUS - status of the rj45 port1. + */ + +#define NV_CTRL_FRAMELOCK_PORT1_STATUS 27 /* R-- */ +#define NV_CTRL_FRAMELOCK_PORT1_STATUS_INPUT 0 +#define NV_CTRL_FRAMELOCK_PORT1_STATUS_OUTPUT 1 + + +/* + * NV_CTRL_FRAMELOCK_HOUSE_STATUS - status of the house input (the BNC + * connector). + */ + +#define NV_CTRL_FRAMELOCK_HOUSE_STATUS 28 /* R-- */ +#define NV_CTRL_FRAMELOCK_HOUSE_STATUS_NOT_DETECTED 0 +#define NV_CTRL_FRAMELOCK_HOUSE_STATUS_DETECTED 1 + + +/* + * NV_CTRL_FRAMELOCK_SYNC - enable/disable the syncing of the + * specified display devices to the FrameLock pulse. + */ + +#define NV_CTRL_FRAMELOCK_SYNC 29 /* RWD */ +#define NV_CTRL_FRAMELOCK_SYNC_DISABLE 0 +#define NV_CTRL_FRAMELOCK_SYNC_ENABLE 1 + + +/* + * NV_CTRL_FRAMELOCK_SYNC_READY - reports whether a slave FrameLock + * board is receiving sync (regardless of whether or not any display + * devices are using the sync). + */ + +#define NV_CTRL_FRAMELOCK_SYNC_READY 30 /* R-- */ +#define NV_CTRL_FRAMELOCK_SYNC_READY_FALSE 0 +#define NV_CTRL_FRAMELOCK_SYNC_READY_TRUE 1 + + +/* + * NV_CTRL_FRAMELOCK_STEREO_SYNC - this indicates that the GPU stereo + * signal is in sync with the framelock stereo signal. + */ + +#define NV_CTRL_FRAMELOCK_STEREO_SYNC 31 /* R-- */ +#define NV_CTRL_FRAMELOCK_STEREO_SYNC_FALSE 0 +#define NV_CTRL_FRAMELOCK_STEREO_SYNC_TRUE 1 + + +/* + * NV_CTRL_FRAMELOCK_TEST_SIGNAL - to test the connections in the sync + * group, tell the master to enable a test signal, then query port[01] + * status and sync_ready on all slaves. When done, tell the master to + * disable the test signal. Test signal should only be manipulated + * while NV_CTRL_FRAMELOCK_SYNC is enabled. + * + * The TEST_SIGNAL is also used to reset the Universal Frame Count (as + * returned by the glXQueryFrameCountNV() function in the + * GLX_NV_swap_group extension). Note: for best accuracy of the + * Universal Frame Count, it is recommended to toggle the TEST_SIGNAL + * on and off after enabling FrameLock. + */ + +#define NV_CTRL_FRAMELOCK_TEST_SIGNAL 32 /* RW- */ +#define NV_CTRL_FRAMELOCK_TEST_SIGNAL_DISABLE 0 +#define NV_CTRL_FRAMELOCK_TEST_SIGNAL_ENABLE 1 + + +/* + * NV_CTRL_FRAMELOCK_ETHERNET_DETECTED - The FrameLock boards are + * cabled together using regular cat5 cable, connecting to rj45 ports + * on the backplane of the card. There is some concern that users may + * think these are ethernet ports and connect them to a + * router/hub/etc. The hardware can detect this and will shut off to + * prevent damage (either to itself or to the router). + * NV_CTRL_FRAMELOCK_ETHERNET_DETECTED may be called to find out if + * ethernet is connected to one of the rj45 ports. An appropriate + * error message should then be displayed. The _PORT0 and PORT1 + * values may be or'ed together. + */ + +#define NV_CTRL_FRAMELOCK_ETHERNET_DETECTED 33 /* R-- */ +#define NV_CTRL_FRAMELOCK_ETHERNET_DETECTED_NONE 0 +#define NV_CTRL_FRAMELOCK_ETHERNET_DETECTED_PORT0 0x1 +#define NV_CTRL_FRAMELOCK_ETHERNET_DETECTED_PORT1 0x2 + + +/* + * NV_CTRL_FRAMELOCK_VIDEO_MODE - get/set the video mode of the house + * input. + */ + +#define NV_CTRL_FRAMELOCK_VIDEO_MODE 34 /* RW- */ +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_NONE 0 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_TTL 1 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_NTSCPALSECAM 2 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_HDTV 3 + +/* + * During FRAMELOCK bring-up, the above values were redefined to + * these: + */ + +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_COMPOSITE_AUTO 0 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_TTL 1 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_COMPOSITE_BI_LEVEL 2 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_COMPOSITE_TRI_LEVEL 3 + + +/* + * NV_CTRL_FRAMELOCK_SYNC_RATE - this is the refresh rate that the + * framelock board is sending to the GPU, in milliHz. + */ + +#define NV_CTRL_FRAMELOCK_SYNC_RATE 35 /* R-- */ + + + +/**************************************************************************/ + +/* + * NV_CTRL_FORCE_GENERIC_CPU - inhibit the use of CPU specific + * features such as MMX, SSE, or 3DNOW! for OpenGL clients; this + * option may result in performance loss, but may be useful in + * conjunction with software such as the Valgrind memory debugger. + * This setting is only applied to OpenGL clients that are started + * after this setting is applied. + */ + +#define NV_CTRL_FORCE_GENERIC_CPU 37 /* RW- */ +#define NV_CTRL_FORCE_GENERIC_CPU_DISABLE 0 +#define NV_CTRL_FORCE_GENERIC_CPU_ENABLE 1 + + +/* + * NV_CTRL_OPENGL_AA_LINE_GAMMA - for OpenGL clients, allow + * Gamma-corrected antialiased lines to consider variances in the + * color display capabilities of output devices when rendering smooth + * lines. Only available on recent Quadro GPUs. This setting is only + * applied to OpenGL clients that are started after this setting is + * applied. + */ + +#define NV_CTRL_OPENGL_AA_LINE_GAMMA 38 /* RW- */ +#define NV_CTRL_OPENGL_AA_LINE_GAMMA_DISABLE 0 +#define NV_CTRL_OPENGL_AA_LINE_GAMMA_ENABLE 1 + + +/* + * NV_CTRL_FRAMELOCK_TIMING - this is TRUE when the framelock board is + * receiving timing input. + */ + +#define NV_CTRL_FRAMELOCK_TIMING 39 /* RW- */ +#define NV_CTRL_FRAMELOCK_TIMING_FALSE 0 +#define NV_CTRL_FRAMELOCK_TIMING_TRUE 1 + +/* + * NV_CTRL_FLIPPING_ALLOWED - when TRUE, OpenGL will swap by flipping + * when possible; when FALSE, OpenGL will alway swap by blitting. XXX + * can this be enabled dynamically? + */ + +#define NV_CTRL_FLIPPING_ALLOWED 40 /* RW- */ +#define NV_CTRL_FLIPPING_ALLOWED_FALSE 0 +#define NV_CTRL_FLIPPING_ALLOWED_TRUE 1 + +/* + * NV_CTRL_ARCHITECTURE - returns the architecture on which the X server is + * running. + */ + +#define NV_CTRL_ARCHITECTURE 41 /* R-- */ +#define NV_CTRL_ARCHITECTURE_X86 0 +#define NV_CTRL_ARCHITECTURE_X86_64 1 +#define NV_CTRL_ARCHITECTURE_IA64 2 + + +/* + * NV_CTRL_TEXTURE_CLAMPING - texture clamping mode in OpenGL. By + * default, NVIDIA's OpenGL implementation uses CLAMP_TO_EDGE, which + * is not strictly conformant, but some applications rely on the + * non-conformant behavior, and not all GPUs support conformant + * texture clamping in hardware. _SPEC forces OpenGL texture clamping + * to be conformant, but may introduce slower performance on older + * GPUS, or incorrect texture clamping in certain applications. + */ + +#define NV_CTRL_TEXTURE_CLAMPING 42 /* RW- */ +#define NV_CTRL_TEXTURE_CLAMPING_EDGE 0 +#define NV_CTRL_TEXTURE_CLAMPING_SPEC 1 + + + +#define NV_CTRL_CURSOR_SHADOW 43 /* RW- */ +#define NV_CTRL_CURSOR_SHADOW_DISABLE 0 +#define NV_CTRL_CURSOR_SHADOW_ENABLE 1 + +#define NV_CTRL_CURSOR_SHADOW_ALPHA 44 /* RW- */ +#define NV_CTRL_CURSOR_SHADOW_RED 45 /* RW- */ +#define NV_CTRL_CURSOR_SHADOW_GREEN 46 /* RW- */ +#define NV_CTRL_CURSOR_SHADOW_BLUE 47 /* RW- */ + +#define NV_CTRL_CURSOR_SHADOW_X_OFFSET 48 /* RW- */ +#define NV_CTRL_CURSOR_SHADOW_Y_OFFSET 49 /* RW- */ + + + +/* + * When Application Control for FSAA is enabled, then what the + * application requests is used, and NV_CTRL_FSAA_MODE is ignored. If + * this is disabled, then any application setting is overridden with + * NV_CTRL_FSAA_MODE + */ + +#define NV_CTRL_FSAA_APPLICATION_CONTROLLED 50 /* RW- */ +#define NV_CTRL_FSAA_APPLICATION_CONTROLLED_ENABLED 1 +#define NV_CTRL_FSAA_APPLICATION_CONTROLLED_DISABLED 0 + + +/* + * When Application Control for LogAniso is enabled, then what the + * application requests is used, and NV_CTRL_LOG_ANISO is ignored. If + * this is disabled, then any application setting is overridden with + * NV_CTRL_LOG_ANISO + */ + +#define NV_CTRL_LOG_ANISO_APPLICATION_CONTROLLED 51 /* RW- */ +#define NV_CTRL_LOG_ANISO_APPLICATION_CONTROLLED_ENABLED 1 +#define NV_CTRL_LOG_ANISO_APPLICATION_CONTROLLED_DISABLED 0 + + +/* + * IMAGE_SHARPENING adjusts the sharpness of the display's image + * quality by amplifying high frequency content. Valid values will + * normally be in the range [0,32). Only available on GeForceFX or + * newer. + */ + +#define NV_CTRL_IMAGE_SHARPENING 52 /* RWD */ + + +/* + * NV_CTRL_TV_OVERSCAN adjusts the amount of overscan on the specified + * display device. + */ + +#define NV_CTRL_TV_OVERSCAN 53 /* RWD */ + + +/* + * NV_CTRL_TV_FLICKER_FILTER adjusts the amount of flicker filter on + * the specified display device. + */ + +#define NV_CTRL_TV_FLICKER_FILTER 54 /* RWD */ + + +/* + * NV_CTRL_TV_BRIGHTNESS adjusts the amount of brightness on the + * specified display device. + */ + +#define NV_CTRL_TV_BRIGHTNESS 55 /* RWD */ + + +/* + * NV_CTRL_TV_HUE adjusts the amount of hue on the specified display + * device. + */ + +#define NV_CTRL_TV_HUE 56 /* RWD */ + + +/* + * NV_CTRL_TV_CONTRAST adjusts the amount of contrast on the specified + * display device. + */ + +#define NV_CTRL_TV_CONTRAST 57 /* RWD */ + + +/* + * NV_CTRL_TV_SATURATION adjusts the amount of saturation on the + * specified display device. + */ + +#define NV_CTRL_TV_SATURATION 58 /* RWD */ + + +/* + * NV_CTRL_TV_RESET_SETTINGS - this write-only attribute can be used + * to request that all TV Settings be reset to their default values; + * typical usage would be that this attribute be sent, and then all + * the TV attributes be queried to retrieve their new values. + */ + +#define NV_CTRL_TV_RESET_SETTINGS 59 /* -WD */ + + +/* + * NV_CTRL_GPU_CORE_TEMPERATURE reports the current core temperature + * of the GPU driving the X screen. + */ + +#define NV_CTRL_GPU_CORE_TEMPERATURE 60 /* R-- */ + + +/* + * NV_CTRL_GPU_CORE_THRESHOLD reports the current GPU core slowdown + * threshold temperature, NV_CTRL_GPU_DEFAULT_CORE_THRESHOLD and + * NV_CTRL_GPU_MAX_CORE_THRESHOLD report the default and MAX core + * slowdown threshold temperatures. + * + * NV_CTRL_GPU_CORE_THRESHOLD reflects the temperature at which the + * GPU is throttled to prevent overheating. + */ + +#define NV_CTRL_GPU_CORE_THRESHOLD 61 /* R-- */ +#define NV_CTRL_GPU_DEFAULT_CORE_THRESHOLD 62 /* R-- */ +#define NV_CTRL_GPU_MAX_CORE_THRESHOLD 63 /* R-- */ + + +/* + * NV_CTRL_AMBIENT_TEMPERATURE reports the current temperature in the + * immediate neighbourhood of the GPU driving the X screen. + */ + +#define NV_CTRL_AMBIENT_TEMPERATURE 64 /* R-- */ + + +/* + * NV_CTRL_PBUFFER_SCANOUT_SUPPORTED - returns whether this X screen + * supports scanout of FP pbuffers; + * + * if this screen does not support PBUFFER_SCANOUT, then all other + * PBUFFER_SCANOUT attributes are unavailable. + */ + +#define NV_CTRL_PBUFFER_SCANOUT_SUPPORTED 65 /* R-- */ +#define NV_CTRL_PBUFFER_SCANOUT_FALSE 0 +#define NV_CTRL_PBUFFER_SCANOUT_TRUE 1 + +/* + * NV_CTRL_PBUFFER_SCANOUT_XID indicates the XID of the pbuffer used for + * scanout. + */ +#define NV_CTRL_PBUFFER_SCANOUT_XID 66 /* RW- */ + +#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_PBUFFER_SCANOUT_XID + +/**************************************************************************/ + +/* + * String Attributes: + */ + + +/* + * NV_CTRL_STRING_PRODUCT_NAME - the GPU product name on which the + * specified X screen is running. + */ + +#define NV_CTRL_STRING_PRODUCT_NAME 0 /* R-- */ + + +/* + * NV_CTRL_STRING_VBIOS_VERSION - the video bios version on the GPU on + * which the specified X screen is running. + */ + +#define NV_CTRL_STRING_VBIOS_VERSION 1 /* R-- */ + + +/* + * NV_CTRL_STRING_NVIDIA_DRIVER_VERSION - string representation of the + * NVIDIA driver version number for the NVIDIA X driver in use. + */ + +#define NV_CTRL_STRING_NVIDIA_DRIVER_VERSION 3 /* R-- */ + + +/* + * NV_CTRL_STRING_DISPLAY_DEVICE_NAME - name of the display device + * specified in the display_mask argument. + */ + +#define NV_CTRL_STRING_DISPLAY_DEVICE_NAME 4 /* R-D */ + + +/* + * NV_CTRL_STRING_TV_ENCODER_NAME - name of the TV encoder used by the + * specified display device; only valid if the display device is a TV. + */ + +#define NV_CTRL_STRING_TV_ENCODER_NAME 5 /* R-D */ + +#define NV_CTRL_STRING_LAST_ATTRIBUTE NV_CTRL_STRING_TV_ENCODER_NAME + + + +/**************************************************************************/ +/* + * CTRLAttributeValidValuesRec - + * + * structure and related defines used by + * XNVCTRLQueryValidAttributeValues() to describe the valid values of + * a particular attribute. The type field will be one of: + * + * ATTRIBUTE_TYPE_INTEGER : the attribute is an integer value; there + * is no fixed range of valid values. + * + * ATTRIBUTE_TYPE_BITMASK : the attribute is an integer value, + * interpretted as a bitmask. + * + * ATTRIBUTE_TYPE_BOOL : the attribute is a boolean, valid values are + * either 1 (on/true) or 0 (off/false). + * + * ATTRIBUTE_TYPE_RANGE : the attribute can have any integer value + * between NVCTRLAttributeValidValues.u.range.min and + * NVCTRLAttributeValidValues.u.range.max (inclusive). + * + * ATTRIBUTE_TYPE_INT_BITS : the attribute can only have certain + * integer values, indicated by which bits in + * NVCTRLAttributeValidValues.u.bits.ints are on (for example: if bit + * 0 is on, then 0 is a valid value; if bit 5 is on, then 5 is a valid + * value, etc). This is useful for attributes like NV_CTRL_FSAA_MODE, + * which can only have certain values, depending on GPU. + * + * + * The permissions field of NVCTRLAttributeValidValuesRec is a bitmask + * that may contain: + * + * ATTRIBUTE_TYPE_READ + * ATTRIBUTE_TYPE_WRITE + * ATTRIBUTE_TYPE_DISPLAY + * + * See 'Key to Integer Attribute "Permissions"' at the top of this + * file for a description of what these three permission bits mean. + */ + +#define ATTRIBUTE_TYPE_UNKNOWN 0 +#define ATTRIBUTE_TYPE_INTEGER 1 +#define ATTRIBUTE_TYPE_BITMASK 2 +#define ATTRIBUTE_TYPE_BOOL 3 +#define ATTRIBUTE_TYPE_RANGE 4 +#define ATTRIBUTE_TYPE_INT_BITS 5 + +#define ATTRIBUTE_TYPE_READ 0x1 +#define ATTRIBUTE_TYPE_WRITE 0x2 +#define ATTRIBUTE_TYPE_DISPLAY 0x4 + +typedef struct _NVCTRLAttributeValidValues { + int type; + union { + struct { + int min; + int max; + } range; + struct { + unsigned int ints; + } bits; + } u; + unsigned int permissions; +} NVCTRLAttributeValidValuesRec; + + + +#define ATTRIBUTE_CHANGED_EVENT 0 + + +#endif /* __NVCTRL_H */ diff --git a/ksim/monitors/lm_sensors/NVCtrlLib.h b/ksim/monitors/lm_sensors/NVCtrlLib.h new file mode 100644 index 0000000..8d9cec4 --- /dev/null +++ b/ksim/monitors/lm_sensors/NVCtrlLib.h @@ -0,0 +1,184 @@ +#ifndef __NVCTRLLIB_H +#define __NVCTRLLIB_H + +#include "NVCtrl.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * XNVCTRLQueryExtension - + * + * Returns True if the extension exists, returns False otherwise. + * event_basep and error_basep are the extension event and error + * bases. Currently, no extension specific errors or events are + * defined. + */ + +Bool XNVCTRLQueryExtension ( + Display *dpy, + int *event_basep, + int *error_basep +); + +/* + * XNVCTRLQueryVersion - + * + * Returns True if the extension exists, returns False otherwise. + * major and minor are the extension's major and minor version + * numbers. + */ + +Bool XNVCTRLQueryVersion ( + Display *dpy, + int *major, + int *minor +); + + +/* + * XNVCTRLIsNvScreen + * + * Returns True is the specified screen is controlled by the NVIDIA + * driver. Returns False otherwise. + */ + +Bool XNVCTRLIsNvScreen ( + Display *dpy, + int screen +); + +/* + * XNVCTRLSetAttribute - + * + * Sets the attribute to the given value. The attributes and their + * possible values are listed in NVCtrl.h. + * + * Not all attributes require the display_mask parameter; see + * NVCtrl.h for details. + * + * Possible errors: + * BadValue - The screen or attribute doesn't exist. + * BadMatch - The NVIDIA driver is not present on that screen. + */ + +void XNVCTRLSetAttribute ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + int value +); + +/* + * XNVCTRLQueryAttribute - + * + * Returns True if the attribute exists. Returns False otherwise. + * If XNVCTRLQueryAttribute returns True, value will contain the + * value of the specified attribute. + * + * Not all attributes require the display_mask parameter; see + * NVCtrl.h for details. + * + * Possible errors: + * BadValue - The screen doesn't exist. + * BadMatch - The NVIDIA driver is not present on that screen. + */ + + +Bool XNVCTRLQueryAttribute ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + int *value +); + +/* + * XNVCTRLQueryStringAttribute - + * + * Returns True if the attribute exists. Returns False otherwise. + * If XNVCTRLQueryStringAttribute returns True, *ptr will point to an + * allocated string containing the string attribute requested. It is + * the caller's responsibility to free the string when done. + * + * Possible errors: + * BadValue - The screen doesn't exist. + * BadMatch - The NVIDIA driver is not present on that screen. + * BadAlloc - Insufficient resources to fulfill the request. + */ + +Bool XNVCTRLQueryStringAttribute ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + char **ptr +); + +/* + * XNVCTRLQueryValidAttributeValues - + * + * Returns True if the attribute exists. Returns False otherwise. If + * XNVCTRLQueryValidAttributeValues returns True, values will indicate + * the valid values for the specified attribute; see the description + * of NVCTRLAttributeValidValues in NVCtrl.h. + */ + +Bool XNVCTRLQueryValidAttributeValues ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + NVCTRLAttributeValidValuesRec *values +); + +/* + * XNVCtrlSelectNotify - + * + * This enables/disables receiving of NV-CONTROL events. The type + * specifies the type of event to enable (currently, the only type is + * ATTRIBUTE_CHANGED_EVENT); onoff controls whether receiving this + * type of event should be enabled (True) or disabled (False). + * + * Returns True if successful, or False if the screen is not + * controlled by the NVIDIA driver. + */ + +Bool XNVCtrlSelectNotify ( + Display *dpy, + int screen, + int type, + Bool onoff +); + + + +/* + * XNVCtrlEvent structure + */ + +typedef struct { + int type; + unsigned long serial; + Bool send_event; /* always FALSE, we don't allow send_events */ + Display *display; + Time time; + int screen; + unsigned int display_mask; + unsigned int attribute; + int value; +} XNVCtrlAttributeChangedEvent; + +typedef union { + int type; + XNVCtrlAttributeChangedEvent attribute_changed; + long pad[24]; +} XNVCtrlEvent; + +#if defined(__cplusplus) +} +#endif + +#endif /* __NVCTRLLIB_H */ diff --git a/ksim/monitors/lm_sensors/ksimsensors.cpp b/ksim/monitors/lm_sensors/ksimsensors.cpp new file mode 100644 index 0000000..e63f5cf --- /dev/null +++ b/ksim/monitors/lm_sensors/ksimsensors.cpp @@ -0,0 +1,189 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "ksimsensors.h" +#include "ksimsensors.moc" + +#include <kdebug.h> +#include <kapplication.h> +#include <klocale.h> +#include <kaboutapplication.h> +#include <kaboutdata.h> +#include <kconfig.h> + +#include <qlayout.h> + +#include <label.h> +#include <themetypes.h> +#include "sensorsconfig.h" +#include "sensorbase.h" + +KSIM_INIT_PLUGIN(PluginModule) + +PluginModule::PluginModule(const char *name) + : KSim::PluginObject(name) +{ + setConfigFileName(instanceName()); +} + +PluginModule::~PluginModule() +{ +} + +KSim::PluginView *PluginModule::createView(const char *className) +{ + return new SensorsView(this, className); +} + +KSim::PluginPage *PluginModule::createConfigPage(const char *className) +{ + return new SensorsConfig(this, className); +} + +void PluginModule::showAbout() +{ + QString version = kapp->aboutData()->version(); + + KAboutData aboutData(instanceName(), + I18N_NOOP("KSim Sensors Plugin"), version.latin1(), + I18N_NOOP("An lm_sensors plugin for KSim"), + KAboutData::License_GPL, "(C) 2001 Robbie Ward"); + + aboutData.addAuthor("Robbie Ward", I18N_NOOP("Author"), + "linuxphreak@gmx.co.uk"); + + KAboutApplication(&aboutData).exec(); +} + +SensorsView::SensorsView(KSim::PluginObject *parent, const char *name) + : DCOPObject("sensors"), KSim::PluginView(parent, name) +{ + config()->setGroup("Sensors"); + (new QVBoxLayout(this))->setAutoAdd(true); + + connect(SensorBase::self(), SIGNAL(updateSensors(const SensorList &)), + this, SLOT(updateSensors(const SensorList &))); + + insertSensors(); +} + +SensorsView::~SensorsView() +{ +} + +void SensorsView::reparseConfig() +{ + config()->setGroup("Sensors"); + bool displayFahrenheit = config()->readBoolEntry("displayFahrenheit", false); + int updateVal = config()->readNumEntry("sensorUpdateValue", 5); + SensorBase::self()->setDisplayFahrenheit(displayFahrenheit); + SensorBase::self()->setUpdateSpeed(updateVal * 1000); + + QString label; + QStringList names; + SensorItemList sensorItemList; + const SensorList &list = SensorBase::self()->sensorsList(); + + SensorList::ConstIterator it; + for (it = list.begin(); it != list.end(); ++it) { + config()->setGroup("Sensors"); + label = (*it).sensorType() + "/" + (*it).sensorName(); + names = QStringList::split(':', config()->readEntry(label)); + if (names[0] == "1") + sensorItemList.append(SensorItem((*it).sensorId(), names[1])); + } + + if (sensorItemList == m_sensorItemList) + return; + + m_sensorItemList.clear(); + m_sensorItemList = sensorItemList; + insertSensors(false); +} + +void SensorsView::insertSensors(bool createList) +{ + const SensorList &list = SensorBase::self()->sensorsList(); + + if (createList) { + QString label; + QStringList names; + + config()->setGroup("Sensors"); + bool displayFahrenheit = config()->readBoolEntry("displayFahrenheit", false); + int updateVal = config()->readNumEntry("sensorUpdateValue", 5); + SensorBase::self()->setDisplayFahrenheit(displayFahrenheit); + SensorBase::self()->setUpdateSpeed(updateVal * 1000); + + SensorList::ConstIterator it; + for (it = list.begin(); it != list.end(); ++it) { + label = (*it).sensorType() + "/" + (*it).sensorName(); + names = QStringList::split(':', config()->readEntry(label)); + if (names[0] == "1") + m_sensorItemList.append(SensorItem((*it).sensorId(), names[1])); + } + } + + SensorItemList::Iterator item; + for (item = m_sensorItemList.begin(); item != m_sensorItemList.end(); ++item) + (*item).setLabel(new KSim::Label(KSim::Types::None, this)); + + updateSensors(list); +} + +void SensorsView::updateSensors(const SensorList &sensorList) +{ + if (sensorList.isEmpty() || m_sensorItemList.isEmpty()) + return; + + SensorList::ConstIterator it; + for (it = sensorList.begin(); it != sensorList.end(); ++it) { + SensorItemList::Iterator item; + for (item = m_sensorItemList.begin(); item != m_sensorItemList.end(); ++item) { + if ((*item).id == (*it).sensorId()) { + if (!(*item).label->isVisible()) + (*item).label->show(); + + (*item).label->setText((*item).name + ": " + + (*it).sensorValue() + (*it).sensorUnit()); + } + } + } +} + +QString SensorsView::sensorValue(const QString &sensor, + const QString &label1) +{ + const SensorList &list = SensorBase::self()->sensorsList(); + config()->setGroup("Sensors"); + QStringList names = QStringList::split(':', + config()->readEntry(sensor + "/" + label1)); + + if (names[0] == "0" || list.isEmpty()) + return i18n("Sensor specified not found."); + + SensorList::ConstIterator it; + for (it = list.begin(); it != list.end(); ++it) { + if (sensor == (*it).sensorType() && label1 == (*it).sensorName()) { + return names[1] + QString(": ") + (*it).sensorValue() + (*it).sensorUnit(); + } + } + + return i18n("Sensor specified not found."); +} diff --git a/ksim/monitors/lm_sensors/ksimsensors.h b/ksim/monitors/lm_sensors/ksimsensors.h new file mode 100644 index 0000000..8446931 --- /dev/null +++ b/ksim/monitors/lm_sensors/ksimsensors.h @@ -0,0 +1,91 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SENSORS_H +#define SENSORS_H + +#include <pluginmodule.h> +#include <label.h> +#include "ksimsensorsiface.h" + +class KConfig; +class SensorList; +class KInstance; + +/** + * This class is the lm_sensors monitor plugin + * + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ +class PluginModule : public KSim::PluginObject +{ + public: + PluginModule(const char *name); + ~PluginModule(); + + virtual KSim::PluginView *createView(const char *); + virtual KSim::PluginPage *createConfigPage(const char *); + + virtual void showAbout(); +}; + +class SensorsView : public KSim::PluginView, public KSimSensorsIface +{ + Q_OBJECT + public: + SensorsView(KSim::PluginObject *parent, const char *name); + ~SensorsView(); + + virtual void reparseConfig(); + virtual QString sensorValue(const QString &, const QString &); + + private slots: + void updateSensors(const SensorList &); + + private: + void insertSensors(bool createList = true); + + class SensorItem + { + public: + SensorItem() : id(-1), label(0) {} + SensorItem(int i, const QString &na) + : id(i), name(na), label(0) {} + ~SensorItem() { delete label; } + + bool operator==(const SensorItem &rhs) const + { + return (id == rhs.id && name == rhs.name); + } + + void setLabel(KSim::Label *lab) + { + delete label; + label = lab; + } + + int id; + QString name; + KSim::Label *label; + }; + + typedef QValueList<SensorItem> SensorItemList; + SensorItemList m_sensorItemList; +}; +#endif diff --git a/ksim/monitors/lm_sensors/ksimsensorsiface.h b/ksim/monitors/lm_sensors/ksimsensorsiface.h new file mode 100644 index 0000000..4bd50ce --- /dev/null +++ b/ksim/monitors/lm_sensors/ksimsensorsiface.h @@ -0,0 +1,33 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 - 2004 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KSIMSENSORSIFACE_H +#define KSIMSENSORSIFACE_H + +#include <dcopobject.h> + +class KSimSensorsIface : virtual public DCOPObject +{ + K_DCOP + k_dcop: + virtual QString sensorValue(const QString &sensorType, + const QString &sensorName) = 0; +}; + +#endif // KSIMSENSORSIFACE_H diff --git a/ksim/monitors/lm_sensors/nv_control.h b/ksim/monitors/lm_sensors/nv_control.h new file mode 100644 index 0000000..d94ee95 --- /dev/null +++ b/ksim/monitors/lm_sensors/nv_control.h @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2004 NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of Version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See Version 2 + * of the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + * + */ + +#ifndef __NVCONTROL_H +#define __NVCONTROL_H + +#define NV_CONTROL_ERRORS 0 +#define NV_CONTROL_EVENTS 1 +#define NV_CONTROL_NAME "NV-CONTROL" + +#define NV_CONTROL_MAJOR 1 +#define NV_CONTROL_MINOR 6 + +#define X_nvCtrlQueryExtension 0 +#define X_nvCtrlIsNv 1 +#define X_nvCtrlQueryAttribute 2 +#define X_nvCtrlSetAttribute 3 +#define X_nvCtrlQueryStringAttribute 4 +#define X_nvCtrlQueryValidAttributeValues 5 +#define X_nvCtrlSelectNotify 6 +#define X_nvCtrlLastRequest (X_nvCtrlSelectNotify + 1) + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; +} xnvCtrlQueryExtensionReq; +#define sz_xnvCtrlQueryExtensionReq 4 + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 padb1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 major B16; + CARD16 minor B16; + CARD32 padl4 B32; + CARD32 padl5 B32; + CARD32 padl6 B32; + CARD32 padl7 B32; + CARD32 padl8 B32; +} xnvCtrlQueryExtensionReply; +#define sz_xnvCtrlQueryExtensionReply 32 + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; +} xnvCtrlIsNvReq; +#define sz_xnvCtrlIsNvReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 padb1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 isnv B32; + CARD32 padl4 B32; + CARD32 padl5 B32; + CARD32 padl6 B32; + CARD32 padl7 B32; + CARD32 padl8 B32; +} xnvCtrlIsNvReply; +#define sz_xnvCtrlIsNvReply 32 + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; + CARD32 display_mask B32; + CARD32 attribute B32; +} xnvCtrlQueryAttributeReq; +#define sz_xnvCtrlQueryAttributeReq 16 + +typedef struct { + BYTE type; + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 flags B32; + INT32 value B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xnvCtrlQueryAttributeReply; +#define sz_xnvCtrlQueryAttributeReply 32 + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; + CARD32 display_mask B32; + CARD32 attribute B32; + INT32 value B32; +} xnvCtrlSetAttributeReq; +#define sz_xnvCtrlSetAttributeReq 20 + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; + CARD32 display_mask B32; + CARD32 attribute B32; +} xnvCtrlQueryStringAttributeReq; +#define sz_xnvCtrlQueryStringAttributeReq 16 + +/* + * CtrlQueryStringAttribute reply struct + * n indicates the length of the string. + */ +typedef struct { + BYTE type; + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 flags B32; + CARD32 n B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xnvCtrlQueryStringAttributeReply; +#define sz_xnvCtrlQueryStringAttributeReply 32 + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; + CARD32 display_mask B32; + CARD32 attribute B32; +} xnvCtrlQueryValidAttributeValuesReq; +#define sz_xnvCtrlQueryValidAttributeValuesReq 16 + +typedef struct { + BYTE type; + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 flags B32; + INT32 attr_type B32; + INT32 min B32; + INT32 max B32; + CARD32 bits B32; + CARD32 perms B32; +} xnvCtrlQueryValidAttributeValuesReply; +#define sz_xnvCtrlQueryValidAttributeValuesReply 32 + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; + CARD16 notifyType B16; + CARD16 onoff B16; +} xnvCtrlSelectNotifyReq; +#define sz_xnvCtrlSelectNotifyReq 12 + +typedef struct { + union { + struct { + BYTE type; + BYTE detail; + CARD16 sequenceNumber B16; + } u; + struct { + BYTE type; + BYTE detail; + CARD16 sequenceNumber B16; + Time time B32; + CARD32 screen B32; + CARD32 display_mask B32; + CARD32 attribute B32; + CARD32 value B32; + CARD32 pad0 B32; + CARD32 pad1 B32; + } attribute_changed; + } u; +} xnvctrlEvent; + + +#endif /* __NVCONTROL_H */ diff --git a/ksim/monitors/lm_sensors/sensorbase.cpp b/ksim/monitors/lm_sensors/sensorbase.cpp new file mode 100644 index 0000000..9ccb247 --- /dev/null +++ b/ksim/monitors/lm_sensors/sensorbase.cpp @@ -0,0 +1,254 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "sensorbase.h" +#include "sensorbase.moc" +#include <ksimconfig.h> + +#include <kdebug.h> +#include <klocale.h> +#include <qglobal.h> +#include <klibloader.h> +#include <kstandarddirs.h> +#include <kconfig.h> + +#include <qtimer.h> +#include <qfile.h> +#include <qregexp.h> + +#include <stdio.h> + +#include <X11/Xlib.h> + +#include "NVCtrl.h" +#include "NVCtrlLib.h" + +SensorBase *SensorBase::m_self = 0; +SensorBase *SensorBase::self() +{ + if (!m_self) { + m_self = new SensorBase; + qAddPostRoutine(cleanup); + } + + return m_self; +} + +SensorBase::SensorBase() : QObject() +{ + KSim::Config::config()->setGroup("Sensors"); + QCString sensorsName("libsensors.so"); + + QStringList sensorLocations = KSim::Config::config()->readListEntry("sensorLocations"); + + QStringList::ConstIterator it; + for (it = sensorLocations.begin(); it != sensorLocations.end(); ++it) { + if (QFile::exists((*it).local8Bit() + sensorsName)) { + m_libLocation = (*it).local8Bit() + sensorsName; + break; + } + } + + m_library = KLibLoader::self()->library(m_libLocation); + kdDebug(2003) << sensorsName << " location = " << m_libLocation << endl; + m_loaded = init(); + + { + int eventBase; + int errorBase; + m_hasNVControl = XNVCTRLQueryExtension(qt_xdisplay(), &eventBase, &errorBase) == True; + } + + m_updateTimer = new QTimer(this); + connect(m_updateTimer, SIGNAL(timeout()), SLOT(update())); +} + +SensorBase::~SensorBase() +{ + if (!m_libLocation.isNull()) { + if (m_cleanup) m_cleanup(); + KLibLoader::self()->unloadLibrary(m_libLocation); + } +} + +void SensorBase::setUpdateSpeed(uint speed) +{ + if (m_updateTimer->isActive()) + m_updateTimer->stop(); + + update(); // just to make sure the display is updated ASAP + + if (speed == 0) + return; + + m_updateTimer->start(speed); +} + +void SensorBase::update() +{ + if (!m_loaded) + return; + + m_sensorList.clear(); + const ChipName *chip; + int currentSensor = 0; + int sensor = 0; + + while ((chip = m_detectedChips(&sensor)) != NULL) { + int first = 0, second = 0; + const FeatureData *sFeature = 0; + while ((sFeature = m_allFeatures(*chip, &first, &second)) != NULL) { + if (sFeature->mapping == NoMapping) { + char *name; + double value; + m_label(*chip, sFeature->number, &name); + m_feature(*chip, sFeature->number, &value); + + float returnValue = formatValue(QString::fromUtf8(name), float(value)); + QString label = formatString(QString::fromUtf8(name), returnValue); + QString chipset = chipsetString(chip); + + m_sensorList.append(SensorInfo(currentSensor++, label, + QString::fromUtf8(name), QString::fromUtf8(chip->prefix), + chipset, sensorType(QString::fromLatin1(name)))); + } + } + } + + if (m_hasNVControl) { + int temp = 0; + if (XNVCTRLQueryAttribute(qt_xdisplay(), qt_xscreen(), 0 /* not used? */, NV_CTRL_GPU_CORE_TEMPERATURE, &temp)) { + QString name = QString::fromLatin1("GPU Temp"); + m_sensorList.append(SensorInfo(currentSensor++, QString::number(temp), + name, QString::null, QString::null, sensorType(name))); + } + + if (XNVCTRLQueryAttribute(qt_xdisplay(), qt_xscreen(), 0 /* not used? */, NV_CTRL_AMBIENT_TEMPERATURE, &temp)) { + QString name = QString::fromLatin1("GPU Ambient Temp"); + m_sensorList.append(SensorInfo(currentSensor++, QString::number(temp), + name, QString::null, QString::null, sensorType(name))); + } + + } + + emit updateSensors(m_sensorList); +} + +void SensorBase::cleanup() +{ + if (!m_self) + return; + + delete m_self; + m_self = 0; +} + +bool SensorBase::init() +{ + if (m_libLocation.isNull()) { + kdError() << "Unable to find libsensors.so" << endl; + return false; + } + + m_init = (Init)m_library->symbol("sensors_init"); + if (!m_init) + return false; + + m_error = (Error)m_library->symbol("sensors_strerror"); + if (!m_error) + return false; + + m_detectedChips = (GetDetectedChips *)m_library->symbol("sensors_get_detected_chips"); + m_allFeatures = (GetAllFeatures *)m_library->symbol("sensors_get_all_features"); + m_label = (Label)m_library->symbol("sensors_get_label"); + m_feature = (Feature)m_library->symbol("sensors_get_feature"); + + if (!m_detectedChips || !m_allFeatures || !m_label || !m_feature) + return false; + + m_cleanup = (Cleanup)m_library->symbol("sensors_cleanup"); + if (!m_cleanup) + return false; + + int res; + FILE *input; + + if ((input = fopen("/etc/sensors.conf", "r")) == 0) + return false; + + if ((res = m_init(input))) { + if (res == ProcError) { + kdError() << "There was an error reading the sensor information\n" + << "Make sure sensors.o and i2c-proc.o are loaded" << endl; + } + else { + kdError() << m_error(res) << endl; + } + + fclose(input); + return false; + } + + fclose(input); + + return true; +} + +QString SensorBase::sensorType(const QString &name) +{ + if (name.findRev("fan", -1, false) != -1) + return i18n("Rounds per minute", " RPM"); + + if (name.findRev("temp", -1, false) != -1) + if (SensorBase::fahrenheit()) + return QString::fromLatin1("F"); + else + return QString::fromLatin1("C"); + + if (name.findRev(QRegExp("[^\\+]?[^\\-]?V$")) != -1) + return i18n("Volt", "V"); + + return QString::null; +} + +QString SensorBase::chipsetString(const ChipName *c) +{ + QString data = QString::fromUtf8(c->prefix); + + if (c->bus == BusISA) + return QString().sprintf("%s-isa-%04x", data.utf8().data(), c->addr); + + return QString().sprintf("%s-i2c-%d-%02x", data.utf8().data(), c->bus, c->addr); +} + +float SensorBase::formatValue(const QString &label, float value) +{ + if (label.findRev("temp", -1, false) != -1) + return toFahrenheit(value); + + return value; +} + +QString SensorBase::formatString(const QString &label, float value) +{ + if (label.findRev("fan", -1, false) != -1) + return QString::number(value); + + return QString::number(value,'f',2); +} diff --git a/ksim/monitors/lm_sensors/sensorbase.h b/ksim/monitors/lm_sensors/sensorbase.h new file mode 100644 index 0000000..c819d48 --- /dev/null +++ b/ksim/monitors/lm_sensors/sensorbase.h @@ -0,0 +1,175 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SENSORBASE_H +#define SENSORBASE_H + +#include <qobject.h> +#include <qvaluelist.h> +#include <qcstring.h> + +class QTimer; +class KLibrary; + +class SensorInfo +{ + public: + SensorInfo() {} + SensorInfo(int id, + const QString &sensorValue, + const QString &sensorName, + const QString &sensorType, + const QString &chipsetName, + const QString &sensorUnit) + : m_id(id), m_sensor(sensorValue), + m_sensorName(sensorName), + m_sensorType(sensorType), + m_chipsetName(chipsetName), + m_sensorUnit(sensorUnit) {} + + /** + * @return the sensor Id + */ + int sensorId() const { return m_id; } + /** + * @return the current value, eg: 5000 + */ + const QString &sensorValue() const { return m_sensor; } + /** + * @return the sensor name, eg: temp1, fan2 + */ + const QString &sensorName() const { return m_sensorName; } + /** + * @return the sensor type name, eg: w83782d + */ + const QString &sensorType() const { return m_sensorType; } + /** + * @return the chipset name, eg: w83782d-i2c-0-2d + */ + const QString &chipsetName() const { return m_chipsetName; } + /** + * @return the unit name, eg: RPM, C or F if display fahrenheit is enabled + */ + const QString &sensorUnit() const { return m_sensorUnit; } + + private: + int m_id; + QString m_sensor; + QString m_sensorName; + QString m_sensorType; + QString m_chipsetName; + QString m_sensorUnit; +}; + +class SensorList : public QValueList<SensorInfo> +{ + public: + SensorList() {} + SensorList(const SensorList &sensorList) + : QValueList<SensorInfo>(sensorList) {} + SensorList(const QValueList<SensorInfo> &sensorList) + : QValueList<SensorInfo>(sensorList) {} + SensorList(const SensorInfo &sensor) { append(sensor); } +}; + +class SensorBase : public QObject +{ + Q_OBJECT + public: + static SensorBase *self(); + + const SensorList &sensorsList() const { return m_sensorList; } + bool fahrenheit() { return m_fahrenheit; } + + signals: + void updateSensors(const SensorList&); + + public slots: + void setUpdateSpeed(uint); + void setDisplayFahrenheit(bool fah) { m_fahrenheit = fah; } + + private slots: + void update(); + + protected: + SensorBase(); + ~SensorBase(); + + private: + SensorBase(const SensorBase &); + SensorBase &operator=(const SensorBase &); + + static void cleanup(); + struct ChipName + { + char *prefix; + int bus; + int addr; + char *busname; + }; + + struct FeatureData + { + int number; + const char *name; + int mapping; + int unused; + int mode; + }; + + enum { ProcError=4, NoMapping=-1, BusISA=-1 }; + typedef void (*Cleanup)(); + typedef int (*Init)(FILE *); + typedef const char *(*Error)(int); + typedef const ChipName *(GetDetectedChips)(int *); + typedef const FeatureData *(GetAllFeatures)(ChipName, int *, int *); + typedef int (*Label)(ChipName, int, char **); + typedef int (*Feature)(ChipName, int, double *); + + bool init(); + float toFahrenheit(float value); + QString sensorType(const QString &name); + QString chipsetString(const ChipName *c); + float formatValue(const QString &label, float value); + QString formatString(const QString &label, float value); + + SensorList m_sensorList; + QTimer *m_updateTimer; + KLibrary *m_library; + QCString m_libLocation; + bool m_loaded; + bool m_fahrenheit; + + bool m_hasNVControl; + + Init m_init; + Error m_error; + GetDetectedChips *m_detectedChips; + GetAllFeatures *m_allFeatures; + Label m_label; + Feature m_feature; + Cleanup m_cleanup; + static SensorBase *m_self; +}; + +inline float SensorBase::toFahrenheit(float value) +{ + return fahrenheit() ? (value * (9.0F / 5.0F) + 32.0F) : value; +} +#endif // SENSORBASE_H diff --git a/ksim/monitors/lm_sensors/sensorsconfig.cpp b/ksim/monitors/lm_sensors/sensorsconfig.cpp new file mode 100644 index 0000000..6e2b4b3 --- /dev/null +++ b/ksim/monitors/lm_sensors/sensorsconfig.cpp @@ -0,0 +1,241 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "sensorsconfig.h" +#include "sensorsconfig.moc" +#include "sensorbase.h" + +#include <klocale.h> +#include <kiconloader.h> +#include <klistview.h> +#include <knuminput.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kinputdialog.h> + +#include <qtimer.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qcheckbox.h> +#include <qcursor.h> +#include <qpopupmenu.h> +#include <qpushbutton.h> + +class SensorViewItem : public QCheckListItem +{ + public: + SensorViewItem(QListView *parent, const QString &text1, + const QString &text2, const QString &text3, + const QString &text4) + : QCheckListItem(parent, text1, CheckBox) + { + setText(1, text2); + setText(2, text3); + setText(3, text4); + } +}; + +SensorsConfig::SensorsConfig(KSim::PluginObject *parent, const char *name) + : KSim::PluginPage(parent, name) +{ + m_layout = new QGridLayout(this); + m_layout->setSpacing(6); + m_neverShown = true; + + m_sensorView = new KListView(this); + m_sensorView->addColumn(i18n("No.")); + m_sensorView->addColumn(i18n("Label")); + m_sensorView->addColumn(i18n("Sensors")); + m_sensorView->addColumn(i18n("Value")); + m_sensorView->setColumnWidth(0, 40); + m_sensorView->setColumnWidth(1, 60); + m_sensorView->setColumnWidth(2, 80); + m_sensorView->setAllColumnsShowFocus(true); + connect(m_sensorView, SIGNAL(contextMenu(KListView *, + QListViewItem *, const QPoint &)), this, SLOT(menu(KListView *, + QListViewItem *, const QPoint &))); + + connect( m_sensorView, SIGNAL( doubleClicked( QListViewItem * ) ), + SLOT( modify( QListViewItem * ) ) ); + + m_layout->addMultiCellWidget(m_sensorView, 1, 1, 0, 3); + + m_modify = new QPushButton( this ); + m_modify->setText( i18n( "Modify..." ) ); + connect( m_modify, SIGNAL( clicked() ), SLOT( modify() ) ); + m_layout->addMultiCellWidget( m_modify, 2, 2, 3, 3 ); + + m_fahrenBox = new QCheckBox(i18n("Display Fahrenheit"), this); + m_layout->addMultiCellWidget(m_fahrenBox, 3, 3, 0, 3); + + m_updateLabel = new QLabel(this); + m_updateLabel->setText(i18n("Update interval:")); + m_updateLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, + QSizePolicy::Fixed)); + m_layout->addMultiCellWidget(m_updateLabel, 4, 4, 0, 0); + + m_sensorSlider = new KIntSpinBox(this); + m_layout->addMultiCellWidget(m_sensorSlider, 4, 4, 1, 1); + + QLabel *intervalLabel = new QLabel(this); + intervalLabel->setText(i18n("seconds")); + intervalLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, + QSizePolicy::Fixed)); + m_layout->addMultiCellWidget(intervalLabel, 4, 4, 2, 2); +} + +SensorsConfig::~SensorsConfig() +{ +} + +void SensorsConfig::saveConfig() +{ + config()->setGroup("Sensors"); + config()->writeEntry("sensorUpdateValue", m_sensorSlider->value()); + config()->writeEntry("displayFahrenheit", m_fahrenBox->isChecked()); + + for (QListViewItemIterator it(m_sensorView); it.current(); ++it) { + config()->setGroup("Sensors"); + config()->writeEntry(it.current()->text(2), + QString::number(static_cast<QCheckListItem *>(it.current())->isOn()) + + ":" + it.current()->text(1)); + } +} + +void SensorsConfig::readConfig() +{ + config()->setGroup("Sensors"); + m_fahrenBox->setChecked(config()->readBoolEntry("displayFahrenheit", false)); + m_sensorSlider->setValue(config()->readNumEntry("sensorUpdateValue", 15)); + + QStringList names; + for (QListViewItemIterator it(m_sensorView); it.current(); ++it) { + config()->setGroup("Sensors"); + names = QStringList::split(":", config()->readEntry(it.current()->text(2), "0:")); + if (!names[1].isNull()) + it.current()->setText(1, names[1]); + static_cast<QCheckListItem *>(it.current())->setOn(names[0].toInt()); + } +} + +void SensorsConfig::menu(KListView *, QListViewItem *, const QPoint &) +{ + m_popupMenu = new QPopupMenu(this); + + m_popupMenu->insertItem(i18n("Select All"), 1); + m_popupMenu->insertItem(i18n("Unselect All"), 2); + m_popupMenu->insertItem(i18n("Invert Selection"), 3); + + switch (m_popupMenu->exec(QCursor::pos())) { + case 1: + selectAll(); + break; + case 2: + unSelectAll(); + break; + case 3: + invertSelect(); + break; + } + + delete m_popupMenu; +} + +void SensorsConfig::selectAll() +{ + for (QListViewItemIterator it(m_sensorView); it.current(); ++it) + static_cast<QCheckListItem *>(it.current())->setOn(true); +} + +void SensorsConfig::unSelectAll() +{ + for (QListViewItemIterator it(m_sensorView); it.current(); ++it) + static_cast<QCheckListItem *>(it.current())->setOn(false); +} + +void SensorsConfig::invertSelect() +{ + for (QListViewItemIterator it(m_sensorView); it.current(); ++it) { + QCheckListItem *item = static_cast<QCheckListItem *>(it.current()); + if (item->isOn()) + item->setOn(false); + else + item->setOn(true); + } +} + +void SensorsConfig::initSensors() +{ + const SensorList &sensorList = SensorBase::self()->sensorsList(); + + int i = 0; + QString label; + QStringList sensorInfo; + SensorList::ConstIterator it; + for (it = sensorList.begin(); it != sensorList.end(); ++it) { + label.sprintf("%02i", ++i); + (void) new SensorViewItem(m_sensorView, label, + (*it).sensorName(), (*it).sensorType() + "/" + (*it).sensorName(), + (*it).sensorValue() + (*it).sensorUnit()); + } + + QStringList names; + for (QListViewItemIterator it(m_sensorView); it.current(); ++it) { + config()->setGroup("Sensors"); + names = QStringList::split(":", config()->readEntry(it.current()->text(2), "0:")); + if (!names[1].isNull()) + it.current()->setText(1, names[1]); + static_cast<QCheckListItem *>(it.current())->setOn(names[0].toInt()); + } +} + +void SensorsConfig::modify( QListViewItem * item ) +{ + if ( !item ) + return; + + bool ok = false; + QString text = KInputDialog::getText( i18n( "Modify Sensor Label" ), i18n( "Sensor label:" ), + item->text( 1 ), &ok, this ); + + if ( ok ) + item->setText( 1, text ); +} + +void SensorsConfig::modify() +{ + modify( m_sensorView->selectedItem() ); +} + +void SensorsConfig::showEvent(QShowEvent *) +{ + if (m_neverShown) { + initSensors(); + m_neverShown = false; + } + else { + const SensorList &list = SensorBase::self()->sensorsList(); + SensorList::ConstIterator it; + for (it = list.begin(); it != list.end(); ++it) { + QListViewItem *item = m_sensorView->findItem((*it).sensorName(), 1); + if (item) + item->setText(3, (*it).sensorValue() + (*it).sensorUnit()); + } + } +} diff --git a/ksim/monitors/lm_sensors/sensorsconfig.h b/ksim/monitors/lm_sensors/sensorsconfig.h new file mode 100644 index 0000000..28d656e --- /dev/null +++ b/ksim/monitors/lm_sensors/sensorsconfig.h @@ -0,0 +1,69 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SENSORSIMPL_H +#define SENSORSIMPL_H + +#include <pluginmodule.h> + +class QPushButton; +class QCheckListItem; +class QGridLayout; +class QLabel; +class KListView; +class QListViewItem; +class QPopupMenu; +class KIntSpinBox; +class QCheckBox; +class QTimer; + +class SensorsConfig : public KSim::PluginPage +{ + Q_OBJECT + public: + SensorsConfig(KSim::PluginObject *parent, const char *name); + ~SensorsConfig(); + + void saveConfig(); + void readConfig(); + + private slots: + void menu(KListView *, QListViewItem *, const QPoint &); + void initSensors(); + void selectAll(); + void unSelectAll(); + void invertSelect(); + + void modify( QListViewItem * ); + void modify(); + + protected: + void showEvent(QShowEvent *); + + private: + bool m_neverShown; + QLabel *m_updateLabel; + KIntSpinBox *m_sensorSlider; + KListView *m_sensorView; + QCheckBox *m_fahrenBox; + QGridLayout *m_layout; + QPopupMenu *m_popupMenu; + QPushButton * m_modify; +}; +#endif diff --git a/ksim/monitors/mail/Makefile.am b/ksim/monitors/mail/Makefile.am new file mode 100644 index 0000000..bf89a1d --- /dev/null +++ b/ksim/monitors/mail/Makefile.am @@ -0,0 +1,15 @@ +kde_module_LTLIBRARIES = ksim_mail.la +ksim_mail_la_SOURCES = ksimmail.cpp + +ksim_mail_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +ksim_mail_la_LIBADD = $(LIB_KIO) ../../library/libksimcore.la + +EXTRA_DIST = mail.desktop + +INCLUDES= -I$(top_srcdir)/ksim/library \ + $(all_includes) + +METASOURCES = AUTO + +mon_DATA = mail.desktop +mondir = $(kde_datadir)/ksim/monitors diff --git a/ksim/monitors/mail/ksimmail.cpp b/ksim/monitors/mail/ksimmail.cpp new file mode 100644 index 0000000..6ca1142 --- /dev/null +++ b/ksim/monitors/mail/ksimmail.cpp @@ -0,0 +1,160 @@ +/* + Copyright (c) 2002 Malte Starostik <malte@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +// $Id$ + +#include <qbitmap.h> +#include <qlayout.h> +#include <qtimer.h> + +#include <kaboutapplication.h> +#include <kdebug.h> +#include <klocale.h> + +#include <label.h> +#include <themeloader.h> +#include <themetypes.h> + +#include "ksimmail.moc" + +KSIM_INIT_PLUGIN( MailPlugin ); + +MailPlugin::MailPlugin( const char* name ) + : KSim::PluginObject( name ) +{ + setConfigFileName(instanceName()); +} + +MailPlugin::~MailPlugin() +{ +} + +KSim::PluginView* MailPlugin::createView( const char* name ) +{ + return new MailView( this, name ); +} + +KSim::PluginPage* MailPlugin::createConfigPage( const char* name ) +{ + return new MailConfig( this, name ); +} + +void MailPlugin::showAbout() +{ + KAboutData about( instanceName(), + I18N_NOOP( "KSim Mail Plugin" ), "0.1", + I18N_NOOP( "A mail monitor plugin for KSim" ), + KAboutData::License_GPL, "(c) 2002 Malte Starostik" ); + about.addAuthor( "Malte Starostik", I18N_NOOP( "Author" ), "malte@kde.org" ); + + KAboutApplication( &about ).exec(); +} + +MailView::MailView( KSim::PluginObject* parent, const char* name ) + : KSim::PluginView( parent, name ) +{ + QVBoxLayout* layout = new QVBoxLayout( this ); + + MailLabel* label = new MailLabel( this ); + layout->addWidget( label, 0, AlignHCenter ); +} + +MailView::~MailView() +{ +} + +void MailView::reparseConfig() +{ +} + +void MailView::updateDisplay() +{ +} + +MailLabel::MailLabel( QWidget* parent ) + : KSim::Label( KSim::Types::Mail, parent ) +{ +// label->setPixmap( KSim::ThemeLoader::self().current().krellMail() ); + configureObject( false ); + QTimer* timer = new QTimer( this ); + connect( timer, SIGNAL( timeout() ), SLOT( animation() ) ); + timer->start( 100 ); +} + +MailLabel::~MailLabel() +{ +} + +void MailLabel::configureObject( bool repaint ) +{ + m_envelope.load( themeLoader().current().mailPixmap() ); + m_frames = themeLoader().current().mailFrames(); + m_delay = themeLoader().current().mailDelay(); + + if ( !m_frames ) m_frames = 18; + if ( !m_delay ) m_delay = 1; + + setPixmap( frame( m_envelope, 1 ) ); + + KSim::Label::configureObject( repaint ); +} + +void MailLabel::paintEvent( QPaintEvent* e ) +{ + KSim::Label::paintEvent( e ); +} + +void MailLabel::animation() +{ + static int f = 1; + setPixmap( frame( m_envelope, f ) ); + if ( f++ >= m_frames ) f = 1; +} + +QPixmap MailLabel::frame( const QPixmap& source, int number ) const +{ + QPixmap result( source.width(), source.height() / m_frames ); + bitBlt( &result, 0, 0, &source, 0, number * source.height() / m_frames ); + if ( source.mask() ) + { + QBitmap mask( result.size() ); + bitBlt( &mask, 0, 0, source.mask(), 0, number * source.height() / m_frames ); + result.setMask( mask ); + } + return result; +} + +MailConfig::MailConfig( KSim::PluginObject* parent, const char* name ) + : KSim::PluginPage( parent, name ) +{ +} + +MailConfig::~MailConfig() +{ +} + +void MailConfig::saveConfig() +{ +} + +void MailConfig::readConfig() +{ +} + +// vim: ts=4 sw=4 noet diff --git a/ksim/monitors/mail/ksimmail.h b/ksim/monitors/mail/ksimmail.h new file mode 100644 index 0000000..fd8790a --- /dev/null +++ b/ksim/monitors/mail/ksimmail.h @@ -0,0 +1,90 @@ +/* + Copyright (c) 2002 Malte Starostik <malte@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +// $Id$ + +#ifndef __ksimmail_h__ +#define __ksimmail_h__ + +#include <pluginmodule.h> + +class MailPlugin : public KSim::PluginObject +{ +public: + MailPlugin( const char* name ); + ~MailPlugin(); + + virtual KSim::PluginView* createView( const char* ); + virtual KSim::PluginPage* createConfigPage( const char* ); + + virtual void showAbout(); +}; + +class MailView : public KSim::PluginView +{ + Q_OBJECT +public: + MailView( KSim::PluginObject* parent, const char* name ); + ~MailView(); + + virtual void reparseConfig(); + +private slots: + void updateDisplay(); +}; + +class MailLabel : public KSim::Label +{ + Q_OBJECT +public: + MailLabel( QWidget* parent ); + virtual ~MailLabel(); + + virtual void configureObject( bool ); + +protected: + virtual void paintEvent( QPaintEvent* ); + +private slots: + void animation(); + +private: + QPixmap frame( const QPixmap& source, int number ) const; + +private: + QPixmap m_envelope; + QPixmap m_penguin; + int m_frames; + int m_delay; +}; + +class MailConfig : public KSim::PluginPage +{ + Q_OBJECT +public: + MailConfig( KSim::PluginObject* parent, const char* name ); + ~MailConfig(); + + virtual void saveConfig(); + virtual void readConfig(); +}; + +#endif + +// vim: ts=4 sw=4 noet diff --git a/ksim/monitors/mail/mail.desktop b/ksim/monitors/mail/mail.desktop new file mode 100644 index 0000000..f65ed27 --- /dev/null +++ b/ksim/monitors/mail/mail.desktop @@ -0,0 +1,119 @@ +[Desktop Entry] +Comment=Mail Monitor Plugin +Comment[af]=Pos Monitor Inplak +Comment[ar]=ملحق مراقبة البريد +Comment[bg]=Мониторинг на електронната поща +Comment[bs]=Dodatak za praćenje pošte +Comment[ca]=Monitor de correu +Comment[cs]=Modul pro monitorování pošty +Comment[cy]=Atodyn Monitro Post +Comment[da]=Postovervågnings-plugin +Comment[de]=Hilfsprogramm zur Mailüberwachung +Comment[el]=Πρόσθετο εποπτείας αλληλογραφίας +Comment[eo]=Disk-observa kromaĵo +Comment[es]=Extensión de monitorización de correo +Comment[et]=E-posti monitooring +Comment[eu]=Postaren Plugin Begiralea +Comment[fa]=وصلۀ نمایشگر نامه +Comment[fi]=Sähköpostin monitorointisovelma +Comment[fr]=Module de surveillance de boîtes aux lettres +Comment[ga]=Breiseán Monatóireachta Ríomhphoist +Comment[he]=תוסף צג דואר +Comment[hi]=डाक मॉनीटर प्लगइन +Comment[hu]=E-mail-figyelő bővítőmodul +Comment[is]=Pósteftirlitsforrit +Comment[it]=Plugin di controllo posta +Comment[ja]=メールモニタプラグイン +Comment[ka]= ფოსტის მონიტორის მოდული +Comment[kk]=Поштаны бақылау модулі +Comment[km]=កម្មវិធីជំនួយរបស់កម្មវិធីត្រួតពិនិត្យសំបុត្រ +Comment[lt]=Pašto stebėtojo priedas +Comment[mk]=Приклучок за следење на е-поштата +Comment[ms]=Plug masuk Pemerhati Mel +Comment[nb]=Programtillegg for E-postovervåking +Comment[nds]=Nettpost-Kiekmoduul +Comment[ne]=मेल मोनिटर प्लगइन +Comment[nl]=Mail monitor-plugin +Comment[nn]=Programtillegg for e-postovervaking +Comment[pa]=ਪੱਤਰ ਨਿਗਰਾਨ ਪਲੱਗਿੰਨ +Comment[pl]=Stan skrzynki pocztowej +Comment[pt]='Plugin' de Monitorização do Correio +Comment[pt_BR]=Plug-in de monitoramento de e-mail +Comment[ro]=Modul monitorizare e-mail +Comment[ru]=Монитор почты +Comment[sk]=Modul pre monitorovanie pošty +Comment[sl]=Vstavek za opazovanje pošte +Comment[sr]=Прикључак за надгледање поште +Comment[sr@Latn]=Priključak za nadgledanje pošte +Comment[sv]=Insticksprogram för e-postövervakning +Comment[ta]= அஞ்சல் கண்காணி சொருகுப்பொருள் +Comment[tg]=Модули Дидабони Пост +Comment[th]=ปลั๊กอินตรวจสอบจดหมาย +Comment[tr]=Posta İzleyici Eklentisi +Comment[uk]=Втулок датчика пошти +Comment[uz]=Xat-xabarni nazorat qilish plagini +Comment[uz@cyrillic]=Хат-хабарни назорат қилиш плагини +Comment[wa]=Tchôke-divins di corwaitaedje di l' emilaedje +Comment[xh]=Iplagi efakiweyo Monitor Yeposi +Comment[zh_CN]=邮件监视器插件 +Comment[zh_TW]=電子郵件監視器外掛程式 +Comment[zu]=I-plugin Yomlawuli Weposi +Icon=kmail +Name=Mail +Name[af]=Pos +Name[ar]=البريد +Name[bg]=Поща +Name[br]=Lizher +Name[ca]=Correu +Name[cs]=Pošta +Name[cy]=Post +Name[da]=Post +Name[el]=Αλληλογραφία +Name[eo]=Retpoŝto +Name[es]=Correo +Name[et]=Kirjad +Name[eu]=Posta +Name[fa]=نامه +Name[fi]=Sähköposti +Name[fr]=Courrier +Name[ga]=Ríomhphost +Name[he]=דואר +Name[hi]=डाक +Name[hr]=Pošta +Name[is]=Póstur +Name[it]=Posta +Name[ja]=メール +Name[ka]=ფოსტა +Name[kk]=Пошта +Name[km]=សំបុត្រ +Name[lt]=Paštas +Name[lv]=Pasts +Name[mk]=Е-пошта +Name[mt]=Imejl +Name[nb]=E-Post +Name[nds]=Nettpost +Name[ne]=मेल +Name[nn]=E-post +Name[pa]=ਪੱਤਰ +Name[pl]=Poczta +Name[pt]=E-mail +Name[pt_BR]=E-mail +Name[ru]=Почта +Name[sk]=Pošta +Name[sl]=Pošta +Name[sr]=Пошта +Name[sr@Latn]=Pošta +Name[sv]=E-post +Name[ta]= அஞ்சல் +Name[tg]=Пост +Name[th]=จดหมาย +Name[tr]=E-posta +Name[uk]=Пошта +Name[uz]=Xat-xabar +Name[uz@cyrillic]=Хат-хабар +Name[wa]=Emilaedje +Name[xh]=Iposi +Name[zh_CN]=邮件 +Name[zh_TW]=電子郵件 +Name[zu]=Iposi +X-KSIM-LIBRARY=mail diff --git a/ksim/monitors/net/Makefile.am b/ksim/monitors/net/Makefile.am new file mode 100644 index 0000000..291eb71 --- /dev/null +++ b/ksim/monitors/net/Makefile.am @@ -0,0 +1,14 @@ +kde_module_LTLIBRARIES = ksim_net.la +ksim_net_la_SOURCES = ksimnet.cpp netdialog.cpp netconfig.cpp + +ksim_net_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +ksim_net_la_LIBADD = ../../library/libksimcore.la $(LIB_KIO) + +EXTRA_DIST = Net.desktop + +INCLUDES= -I$(top_srcdir)/ksim/library $(all_includes) + +METASOURCES = AUTO + +mon_DATA = Net.desktop +mondir = $(kde_datadir)/ksim/monitors diff --git a/ksim/monitors/net/Net.desktop b/ksim/monitors/net/Net.desktop new file mode 100644 index 0000000..2fa6b87 --- /dev/null +++ b/ksim/monitors/net/Net.desktop @@ -0,0 +1,112 @@ +[Desktop Entry] +Comment=Net Status Monitor +Comment[ar]=مراقب حالة الشبكة +Comment[bg]=Мониторинг на мрежата +Comment[bs]=Nadzor statusa mreže +Comment[ca]=Monitor de l'estat de xarxa +Comment[cs]=Monitor stavu sítě +Comment[cy]=Monitr Statws Rhwyd +Comment[da]=Overvågning af netstatus +Comment[de]=Statusanzeige fürs Netzwerk +Comment[el]=Επόπτης κατάστασης δικτύου +Comment[eo]=Rigardilo por la retstato +Comment[es]=Monitor de estado de la red +Comment[et]=Võrgu oleku monitooring +Comment[eu]=Sarearen Egoera Begiralea +Comment[fa]=Net نمایشگر وضعیت +Comment[fi]=Verkon tilavalvonta +Comment[fr]=Indicateur d'état réseau +Comment[ga]=Monatóir Stádais an Ghréasáin +Comment[he]=צג מצב רשת +Comment[hi]=नेट स्थिति मॉनीटर +Comment[hu]=Hálózati állapotfigyelő +Comment[is]=Eftirlit með stöðu netsins +Comment[it]=Controllo dello stato della rete +Comment[ja]=ネットワーク状態モニタ +Comment[ka]=ქსელის სტატუსის სტატუსი +Comment[kk]=Желінің күйін бақылау +Comment[km]=កម្មវិធីត្រួតពិនិត្យស្ថានភាពបណ្តាញ +Comment[lt]=Net būsenos stebėtojas +Comment[mk]=Монитор за статусот на мрежата +Comment[ms]=Pemerhati Status Net +Comment[nb]=Overvåkning av nettstatus +Comment[nds]=Statuskieker för't Nettwark +Comment[ne]=सञ्जाल स्थिति मोनिटर +Comment[nl]=Netstatus-monitor +Comment[nn]=Overvaking av nettstatus +Comment[pa]=ਨੈੱਟ ਹਾਲਤ ਨਿਗਰਾਨ +Comment[pl]=Ruch w sieci +Comment[pt]=Monitor de Estado da Rede +Comment[pt_BR]=Monitor de estado da rede +Comment[ro]=Monitor stare reţea +Comment[ru]=Монитор сети +Comment[sk]=Monitor stavu siete +Comment[sl]=Nadzornik stanja mreže +Comment[sr]=Надгледање статуса мреже +Comment[sr@Latn]=Nadgledanje statusa mreže +Comment[sv]=Övervakar nätverkets status +Comment[ta]=வலை நிலை கண்காணி +Comment[tg]=Дидабони Ҳолати Шабака +Comment[th]=เครื่องมือสอดส่องสถานะของเน็ต +Comment[tr]=Ağ İçin Durum İzleyici +Comment[uk]=Монітор стану мережі +Comment[uz]=Tarmoqni nazorat qilish plagini +Comment[uz@cyrillic]=Тармоқни назорат қилиш плагини +Comment[wa]=Corwaitoe di l' estat del rantoele +Comment[zh_CN]=网络状态监视器 +Comment[zh_TW]=網路狀態監視器 +Comment[zu]=Umlawuli Wezinga Lenethi +Icon=network +Name=Net +Name[ar]=الشبكة +Name[bg]=Мрежа +Name[br]=Rouedad +Name[ca]=Xarxa +Name[cs]=Síť +Name[cy]=Rhwyd +Name[el]=Δίκτυο +Name[eo]=Reto +Name[es]=Red +Name[ga]=Gréasán +Name[he]=רשת +Name[hi]=नेट +Name[is]=Netið +Name[it]=Rete +Name[ja]=ネット +Name[kk]=Желі +Name[km]=បណ្តាញ +Name[lv]=Tīkls +Name[mk]=Мрежа +Name[nb]=Nett +Name[nds]=Nett +Name[ne]=सञ्जाल +Name[nn]=Nett +Name[pa]=ਨੈੱਟ +Name[pl]=Sieć +Name[pt]=Rede +Name[pt_BR]=Rede +Name[ro]=Reţea +Name[ru]=Сеть +Name[sk]=Sieť +Name[sl]=Mreža +Name[sr]=Мрежа +Name[sr@Latn]=Mreža +Name[sv]=Nätverk +Name[ta]= வலை +Name[tg]=Шабака +Name[th]=เน็ต +Name[tr]=ağ +Name[uk]=Мережа +Name[uz]=Tarmoq +Name[uz@cyrillic]=Тармоқ +Name[wa]=Rantoele +Name[xh]=Umnatha +Name[zh_CN]=网络 +Name[zh_TW]=網路 +Name[zu]=Inethi +X-KSIM-VERSION=0.1 +X-KSIM-LIBRARY=net +X-KSIM-COPYRIGHT=(C) 2001 Robbie Ward +X-KSIM-EMAIL=linuxphreak@gmx.co.uk +X-KSIM-PREFS=Network +X-KSIM-AUTHOR=Robbie Ward diff --git a/ksim/monitors/net/ksimnet.cpp b/ksim/monitors/net/ksimnet.cpp new file mode 100644 index 0000000..45f86c2 --- /dev/null +++ b/ksim/monitors/net/ksimnet.cpp @@ -0,0 +1,672 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <time.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/stat.h> + +#ifdef __FreeBSD__ +#include <sys/types.h> +#include <sys/sysctl.h> +#include <sys/socket.h> +#include <net/if.h> +#include <net/if_dl.h> +#include <net/route.h> + +static int mib[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 }; +#endif + +#include <qpushbutton.h> +#include <qtextstream.h> +#include <qfile.h> +#include <qdatetime.h> +#include <qlayout.h> +#include <qtimer.h> +#include <qregexp.h> +#include <qcursor.h> +#include <qpopupmenu.h> + +#include <kdebug.h> +#include <klocale.h> +#include <kaboutapplication.h> +#include <kaboutdata.h> +#include <ksimpleconfig.h> +#include <kglobal.h> +#include <krun.h> +#include <kapplication.h> +#include <kiconloader.h> + +#include "ksimnet.h" +#include "netconfig.h" +#include <themetypes.h> + +#define NET_UPDATE 1000 +#define LED_UPDATE 125 + +KSIM_INIT_PLUGIN(NetPlugin) + +NetPlugin::NetPlugin(const char *name) + : KSim::PluginObject(name) +{ + setConfigFileName(instanceName()); +} + +NetPlugin::~NetPlugin() +{ +} + +KSim::PluginView *NetPlugin::createView(const char *className) +{ + return new NetView(this, className); +} + +KSim::PluginPage *NetPlugin::createConfigPage(const char *className) +{ + return new NetConfig(this, className); +} + +void NetPlugin::showAbout() +{ + QString version = kapp->aboutData()->version(); + + KAboutData aboutData(instanceName(), + I18N_NOOP("KSim Net Plugin"), version.latin1(), + I18N_NOOP("A net plugin for KSim"), + KAboutData::License_GPL, "(C) 2001 Robbie Ward"); + + aboutData.addAuthor("Robbie Ward", I18N_NOOP("Author"), + "linuxphreak@gmx.co.uk"); + aboutData.addAuthor("Heitham Omar", I18N_NOOP("FreeBSD ports"), + "super_ice@ntlworld.com"); + + KAboutApplication(&aboutData).exec(); +} + +NetView::NetView(KSim::PluginObject *parent, const char *name) + : KSim::PluginView(parent, name) +{ +#ifdef __linux__ + m_procStream = 0L; + if ((m_procFile = fopen("/proc/net/dev", "r"))) + m_procStream = new QTextStream(m_procFile, IO_ReadOnly); +#endif +#ifdef __FreeBSD__ + m_buf = 0; + m_allocSize = 0; +#endif + + m_firstTime = true; + m_netLayout = new QVBoxLayout(this); + + m_networkList = createList(); + addDisplay(); + + m_netTimer = new QTimer(this); + connect(m_netTimer, SIGNAL(timeout()), SLOT(updateGraph())); + m_netTimer->start(NET_UPDATE); + + m_lightTimer = new QTimer(this); + connect(m_lightTimer, SIGNAL(timeout()), SLOT(updateLights())); + m_lightTimer->start(LED_UPDATE); + + updateGraph(); +} + +NetView::~NetView() +{ +#ifdef __linux__ + delete m_procStream; + + if (m_procFile) + fclose(m_procFile); +#endif + + cleanup(); +} + +void NetView::reparseConfig() +{ + Network::List networkList = createList(); + if ( networkList == m_networkList ) + return; + + m_netTimer->stop(); + m_lightTimer->stop(); + m_firstTime = true; + + cleanup(); + + m_networkList = networkList; + addDisplay(); + + m_netTimer->start(NET_UPDATE); + m_lightTimer->start(LED_UPDATE); +} + +void NetView::cleanup() +{ + Network::List::Iterator it; + for ( it = m_networkList.begin(); it != m_networkList.end(); ++it ) + { + ( *it ).cleanup(); + } + + m_networkList.clear(); +} + +void NetView::addDisplay() +{ + int i = 0; + + Network::List::Iterator it; + for ( it = m_networkList.begin(); it != m_networkList.end(); ++it ) + { + KSim::LedLabel *led = addLedLabel( ( *it ).name() ); + KSim::Label *label = ( ( *it ).showTimer() ? addLabel() : 0L ); + QPopupMenu * popup = ( ( *it ).commandsEnabled() ? + addPopupMenu( ( *it ).name(), i ) : 0L ); + KSim::Chart *chart = addChart(); + //KSim::LedLabel *led = addLedLabel( ( *it ).name() ); + //KSim::Label *label = ( ( *it ).showTimer() ? addLabel() : 0L ); + //QPopupMenu * popup = ( ( *it ).commandsEnabled() ? + //addPopupMenu( ( *it ).name(), i ) : 0L ); + + if ( ( *it ).commandsEnabled() ) + { + if ( chart ) + { + chart->installEventFilter( this ); + } + + if ( led ) + { + led->installEventFilter( this ); + } + + if ( label ) + { + label->installEventFilter( this ); + } + } + + ( *it ).setDisplay( chart, led, label, popup ); + ++i; + } +} + +// Run the connect command +void NetView::runConnectCommand( int value ) +{ + int i = 0; + Network::List::ConstIterator it; + for ( it = m_networkList.begin(); it != m_networkList.end(); ++it ) + { + if ( value == i ) + { + // I use KRun here as it provides startup notification + if ( !( *it ).connectCommand().isNull() ) + { + KRun::runCommand( ( *it ).connectCommand() ); + } + + break; + } + ++i; + } +} + +// Run the disconnect command +void NetView::runDisconnectCommand( int value ) +{ + int i = 0; + Network::List::ConstIterator it; + for ( it = m_networkList.begin(); it != m_networkList.end(); ++it ) + { + if ( value == i ) + { + // I use KRun here as it provides startup notification + if ( !( *it ).disconnectCommand().isNull() ) + { + KRun::runCommand( ( *it ).disconnectCommand() ); + } + + break; + } + + ++i; + } +} + +Network::List NetView::createList() const +{ + config()->setGroup( "Net" ); + int amount = config()->readNumEntry( "deviceAmount", 0 ); + + Network::List list; + for ( int i = 0; i < amount; ++i ) + { + if ( !config()->hasGroup( "device-" + QString::number( i ) ) ) + { + continue; + } + + config()->setGroup( "device-" + QString::number( i ) ); + + list.append( Network( config()->readEntry( "deviceName" ), + config()->readEntry( "deviceFormat" ), + config()->readBoolEntry( "showTimer" ), + config()->readBoolEntry( "commands" ), + config()->readEntry( "cCommand" ), + config()->readEntry("dCommand") ) ); + } + + qHeapSort( list ); + return list; +} + +void NetView::updateLights() +{ + Network::List::Iterator it; + for ( it = m_networkList.begin(); it != m_networkList.end(); ++it ) + { + if ( isOnline( ( *it ).name() ) ) + { + unsigned long receiveDiff = ( *it ).data().in - ( *it ).oldData().in; + unsigned long sendDiff = ( *it ).data().out - ( *it ).oldData().out; + unsigned long halfMax = ( *it ).maxValue() / 2; + + ( *it ).led()->setMaxValue( ( *it ).maxValue() / 1024 ); + ( *it ).led()->setValue( receiveDiff / 1024 ); + + if ( receiveDiff == 0 ) + { + ( *it ).led()->setOff( KSim::Led::First ); + } + else if ( ( receiveDiff / 1024 ) >= halfMax ) + { + ( *it ).led()->setOn( KSim::Led::First ); + } + else + { + ( *it ).led()->toggle( KSim::Led::First ); + } + + if ( sendDiff == 0 ) + { + ( *it ).led()->setOff( KSim::Led::Second ); + } + else if ( ( sendDiff / 1024 ) >= halfMax ) + { + ( *it ).led()->setOn( KSim::Led::Second ); + } + else + { + ( *it ).led()->toggle( KSim::Led::Second ); + } + } + else + { + ( *it ).led()->setMaxValue( 0 ); + ( *it ).led()->setValue( 0 ); + ( *it ).led()->setOff( KSim::Led::First ); + ( *it ).led()->setOff( KSim::Led::Second ); + } + } +} + +void NetView::updateGraph() +{ + int timer = 0; + int hours = 0; + int minutes = 0; + int seconds = 0; + + time_t start = 0; + struct stat st; + + QTime netTime; + QString timeDisplay; + QString pid( "/var/run/%1.pid" ); + QString newPid; + + Network::List::Iterator it; + for ( it = m_networkList.begin(); it != m_networkList.end(); ++it ) + { + if ( isOnline( ( *it ).name() ) ) + { + NetData data; + + if ( ( *it ).label() ) + { + timeDisplay = ( *it ).format(); + newPid = pid.arg( ( *it ).name() ); + + if ( QFile::exists( newPid ) && stat( QFile::encodeName( newPid ).data(), &st ) == 0 ) + { + start = st.st_mtime; + + timer = static_cast<int>( difftime( time( 0 ), start ) ); + hours = timer / 3600; + minutes = (timer - hours * 3600) / 60; + seconds = timer % 60; + if ( netTime.isValid( hours, minutes, seconds ) ) + netTime.setHMS( hours, minutes, seconds ); + } + + // Keep backwards compat for now + if ( timeDisplay.contains( '%' ) > 0 ) + timeDisplay.replace( '%', "" ); + + ( *it ).label()->setText( netTime.toString( timeDisplay ) ); + } + + netStatistics( ( *it ).name(), data ); + ( *it ).setData( data ); + + unsigned long receiveDiff = data.in - ( *it ).oldData().in; + unsigned long sendDiff = data.out - ( *it ).oldData().out; + + if ( m_firstTime ) + { + receiveDiff = sendDiff = 0; + } + + ( *it ).chart()->setValue( receiveDiff, sendDiff ); + ( *it ).setMaxValue( ( *it ).chart()->maxValue() ); + + QString receiveString = KGlobal::locale()->formatNumber( ( float ) receiveDiff / 1024.0, 1 ); + QString sendString = KGlobal::locale()->formatNumber( ( float ) sendDiff / 1024.0, 1 ); + + ( *it ).chart()->setText( i18n( "in: %1k" ).arg( receiveString ), + i18n( "out: %1k" ).arg( sendString ) ); + } + else + { + ( *it ).setData( NetData() ); + ( *it ).chart()->setValue( 0, 0 ); + + ( *it ).chart()->setText( i18n( "in: %1k" ).arg( KGlobal::locale()->formatNumber( 0.0, 1 ) ), + i18n( "out: %1k" ).arg( KGlobal::locale()->formatNumber( 0.0, 1 ) ) ); + + if ( ( *it ).label() ) + ( *it ).label()->setText( i18n( "offline" ) ); + } + } + + if ( m_firstTime ) + m_firstTime = false; +} + +KSim::Chart *NetView::addChart() +{ + KSim::Chart *chart = new KSim::Chart(false, 0, this); + m_netLayout->addWidget(chart); + chart->show(); + return chart; +} + +KSim::LedLabel *NetView::addLedLabel(const QString &device) +{ + KSim::LedLabel *ledLabel = new KSim::LedLabel(0, KSim::Types::Net, + device, this); + + ledLabel->show(); + m_netLayout->addWidget(ledLabel); + return ledLabel; +} + +KSim::Label *NetView::addLabel() +{ + KSim::Label *label = new KSim::Label(KSim::Types::None, this); + label->show(); + m_netLayout->addWidget(label); + return label; +} + +QPopupMenu *NetView::addPopupMenu(const QString &device, int value) +{ + QPopupMenu *popup = new QPopupMenu(this); + popup->insertItem(SmallIcon("network"), i18n("Connect"), this, + SLOT(runConnectCommand(int)), 0, 1); + popup->setItemParameter(1, value); + popup->insertItem(SmallIcon("network"), i18n("Disconnect"), this, + SLOT(runDisconnectCommand(int)), 0, 2); + popup->setItemParameter(2, value); + menu()->insertItem(device, popup, 100 + value); + return popup; +} + +void NetView::netStatistics(const QString &device, NetData &data) +{ +#ifdef __linux__ + if (m_procFile == 0) { + data.in = 0; + data.out = 0; + return; + } + + QString output; + QString parser; + // Parse the proc file + while (!m_procStream->atEnd()) { + parser = m_procStream->readLine(); + // remove all the entries apart from the line containing 'device' + if (parser.find(device) != -1) + output = parser; + } + + if (output.isEmpty()) { + data.in = 0; + data.out = 0; + return; + } + + // make sure our output doesn't contain "eth0:11210107" so we dont + // end up with netList[1] actually being netList[2] + output.replace(QRegExp(":"), " "); + QStringList netList = QStringList::split(' ', output); + + data.in = netList[1].toULong(); + data.out = netList[9].toULong(); + + fseek(m_procFile, 0L, SEEK_SET); +#endif + +#ifdef __FreeBSD__ + struct if_msghdr *ifm, *nextifm; + struct sockaddr_dl *sdl; + char *lim, *next; + size_t needed; + char s[32]; + + if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) + return; + + if (m_allocSize < needed) { + if (m_buf != NULL) + delete[] m_buf; + + m_buf = new char[needed]; + + if (m_buf == NULL) + return; + + m_allocSize = needed; + } + + if (sysctl(mib, 6, m_buf, &needed, NULL, 0) < 0) + return; + + lim = m_buf + needed; + + next = m_buf; + while (next < lim) { + ifm = (struct if_msghdr *)next; + if (ifm->ifm_type != RTM_IFINFO) + return; + + next += ifm->ifm_msglen; + + // get an interface with a network address + while (next < lim) { + nextifm = (struct if_msghdr *)next; + if (nextifm->ifm_type != RTM_NEWADDR) + break; + + next += nextifm->ifm_msglen; + } + + // if the interface is up + if (ifm->ifm_flags & IFF_UP) { + sdl = (struct sockaddr_dl *)(ifm + 1); + if (sdl->sdl_family != AF_LINK) + continue; + + strncpy(s, sdl->sdl_data, sdl->sdl_nlen); + s[sdl->sdl_nlen] = '\0'; + + if (strcmp(device.local8Bit().data(), s) == 0) { + data.in = ifm->ifm_data.ifi_ibytes; + data.out = ifm->ifm_data.ifi_obytes; + return; + } + } + } +#endif +} + +bool NetView::isOnline(const QString &device) +{ +#ifdef __linux__ + QFile file("/proc/net/route"); + if (!file.open(IO_ReadOnly)) + return -1; + + return (QTextStream(&file).read().find(device) != -1 ? true : false); +#endif + +#ifdef __FreeBSD__ + struct if_msghdr *ifm, *nextifm; + struct sockaddr_dl *sdl; + char *lim, *next; + size_t needed; + char s[32]; + + if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) + return false; + + if (m_allocSize < needed) { + if (m_buf != NULL) + delete[] m_buf; + + m_buf = new char[needed]; + + if (m_buf == NULL) + return false; + + m_allocSize = needed; + } + + if (sysctl(mib, 6, m_buf, &needed, NULL, 0) < 0) + return false; + + lim = m_buf + needed; + + next = m_buf; + while (next < lim) { + ifm = (struct if_msghdr *)next; + if (ifm->ifm_type != RTM_IFINFO) + return false; + + next += ifm->ifm_msglen; + + // get an interface with a network address + while (next < lim) { + nextifm = (struct if_msghdr *)next; + if (nextifm->ifm_type != RTM_NEWADDR) + break; + + next += nextifm->ifm_msglen; + } + + // if the interface is up + if (ifm->ifm_flags & IFF_UP) { + sdl = (struct sockaddr_dl *)(ifm + 1); + if (sdl->sdl_family != AF_LINK) + continue; + + strncpy(s, sdl->sdl_data, sdl->sdl_nlen); + s[sdl->sdl_nlen] = '\0'; + + if (strcmp(s, device.local8Bit().data()) == 0) + return true; + } + } + + return false; +#endif +} + +// EventFilter +bool NetView::eventFilter( QObject * o, QEvent * e ) +{ + // find out which interface we are + int i = 0; + Network::List::Iterator it; + for ( it = m_networkList.begin(); it != m_networkList.end(); ++it ) + { + if ( o == ( *it ).chart() || o == ( *it ).label() || o == ( *it ).led() ) + { + break; + } + + ++i; + } + + if ( e->type() == QEvent::MouseButtonPress ) + { + if ( static_cast<QMouseEvent *>( e )->button() == QMouseEvent::RightButton ) + { + showMenu(i); + } + + return true; + } + + return false; +} + +void NetView::showMenu(int i) { + + QPopupMenu menu; + menu.insertItem( SmallIcon("network"), i18n("Connect"), 1); + menu.insertItem( SmallIcon("network"), i18n("Disconnect"), 2); + switch (menu.exec(QCursor::pos())) { + case 1: + runConnectCommand(i); + break; + case 2: + runDisconnectCommand(i); + break; + } +} + + +#include "ksimnet.moc" diff --git a/ksim/monitors/net/ksimnet.h b/ksim/monitors/net/ksimnet.h new file mode 100644 index 0000000..bdb76e6 --- /dev/null +++ b/ksim/monitors/net/ksimnet.h @@ -0,0 +1,90 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KSIMNET_H +#define KSIMNET_H + +#include <pluginmodule.h> +#include "netdevices.h" +#include <stdio.h> + +class QTimer; +class QVBoxLayout; +class QTextStream; + +class NetPlugin : public KSim::PluginObject +{ + public: + NetPlugin(const char *name); + ~NetPlugin(); + + virtual KSim::PluginView *createView(const char *); + virtual KSim::PluginPage *createConfigPage(const char *); + + virtual void showAbout(); +}; + +class NetView : public KSim::PluginView +{ + Q_OBJECT + public: + NetView(KSim::PluginObject *parent, const char *name); + ~NetView(); + + virtual void reparseConfig(); + + private slots: + void cleanup(); + void updateLights(); + void updateGraph(); + void addDisplay(); + void runConnectCommand(int); + void runDisconnectCommand(int); + + protected: + bool eventFilter(QObject *, QEvent *); + + private: + Network::List createList() const; + + KSim::Chart *addChart(); + KSim::LedLabel *addLedLabel(const QString &device); + KSim::Label *addLabel(); + QPopupMenu *addPopupMenu(const QString &device, int value); + + void netStatistics(const QString &device, NetData &data); + bool isOnline(const QString &device); + + void showMenu(int i); + + bool m_firstTime; + Network::List m_networkList; + QTimer *m_netTimer; + QTimer *m_lightTimer; + QVBoxLayout *m_netLayout; +#ifdef __linux__ + FILE *m_procFile; + QTextStream *m_procStream; +#endif +#ifdef __FreeBSD__ + char *m_buf; + int m_allocSize; +#endif +}; +#endif diff --git a/ksim/monitors/net/netconfig.cpp b/ksim/monitors/net/netconfig.cpp new file mode 100644 index 0000000..ca424b3 --- /dev/null +++ b/ksim/monitors/net/netconfig.cpp @@ -0,0 +1,296 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <qpushbutton.h> +#include <qlayout.h> +#include <qcursor.h> + +#include <klistview.h> +#include <ksimpleconfig.h> +#include <klocale.h> +#include <kiconloader.h> +#include <kapplication.h> +#include <kpopupmenu.h> +#include <kdebug.h> +#include <kmessagebox.h> + +#include "netconfig.h" +#include "netconfig.moc" +#include "netdialog.h" + +NetConfig::NetConfig(KSim::PluginObject *parent, const char *name) + : KSim::PluginPage(parent, name) +{ + m_yes = i18n("yes"); + m_no = i18n("no"); + + QVBoxLayout *mainLayout = new QVBoxLayout(this); + mainLayout->setSpacing(6); + + usingBox = new KListView(this); + usingBox ->addColumn(i18n("Interface")); + usingBox ->addColumn(i18n("Timer")); + usingBox ->addColumn(i18n("Commands")); + usingBox->setAllColumnsShowFocus(true); + + connect(usingBox, SIGNAL(contextMenu(KListView *, + QListViewItem *, const QPoint &)), + SLOT(menu(KListView *, QListViewItem *, const QPoint &))); + connect(usingBox, SIGNAL(doubleClicked(QListViewItem *)), + SLOT(modifyItem(QListViewItem *))); + mainLayout->addWidget(usingBox); + + layout = new QHBoxLayout; + layout->setSpacing(6); + + QSpacerItem *spacer = new QSpacerItem(20, 20, + QSizePolicy::Expanding, QSizePolicy::Minimum); + layout->addItem(spacer); + + insertButton = new QPushButton(this); + insertButton->setText(i18n("Add...")); + connect(insertButton, SIGNAL(clicked()), SLOT(showNetDialog())); + layout->addWidget(insertButton); + + modifyButton = new QPushButton(this); + modifyButton->setText(i18n("Modify...")); + connect(modifyButton, SIGNAL(clicked()), SLOT(modifyCurrent())); + layout->addWidget(modifyButton); + + removeButton = new QPushButton(this); + removeButton->setText(i18n("Remove")); + connect(removeButton, SIGNAL(clicked()), SLOT(removeCurrent())); + layout->addWidget(removeButton); + + mainLayout->addLayout(layout); +} + +NetConfig::~NetConfig() +{ +} + +void NetConfig::saveConfig() +{ + qHeapSort( m_networkList); + + int i = 0; + Network::List::Iterator it; + for( it = m_networkList.begin(); it != m_networkList.end(); ++it ) + { + config()->setGroup( "device-" + QString::number( i ) ); + config()->writeEntry( "deviceName", ( *it ).name() ); + config()->writeEntry( "showTimer", ( *it ).showTimer() ); + config()->writeEntry( "deviceFormat", ( *it ).format() ); + config()->writeEntry( "commands", ( *it ).commandsEnabled() ); + config()->writeEntry( "cCommand", ( *it ).connectCommand() ); + config()->writeEntry( "dCommand", ( *it ).disconnectCommand() ); + i++; + } + + config()->setGroup( "Net" ); + config()->writeEntry( "deviceAmount", m_networkList.count() ); +} + +void NetConfig::readConfig() +{ + usingBox->clear(); + m_networkList.clear(); + + config()->setGroup( "Net" ); + int deviceAmount = config()->readNumEntry( "deviceAmount" ); + + for ( int i = 0; i < deviceAmount; ++i ) + { + if ( !config()->hasGroup( "device-" + QString::number( i ) ) ) + { + continue; + } + + config()->setGroup("device-" + QString::number(i)); + + m_networkList.append( Network( config()->readEntry( "deviceName" ), + config()->readEntry( "deviceFormat" ), + config()->readBoolEntry( "showTimer" ), + config()->readBoolEntry( "commands" ), + config()->readEntry( "cCommand" ), + config()->readEntry( "dCommand" ) ) ); + + (void) new QListViewItem( usingBox, + config()->readEntry( "deviceName" ), + boolToString( config()->readBoolEntry( "showTimer" ) ), + boolToString( config()->readBoolEntry( "commands" ) ) ); + } +} + +void NetConfig::menu(KListView *, QListViewItem *item, const QPoint &) +{ + aboutMenu = new QPopupMenu(this); + + if (item) { + aboutMenu->insertItem(i18n("&Add Net Device"), 3); + aboutMenu->insertItem(i18n("&Modify '%1'").arg(item->text(0)), 2); + aboutMenu->insertItem(i18n("&Remove '%1'").arg(item->text(0)), 1); + } + else { + aboutMenu->insertItem(i18n("&Add Net Device"), 3); + aboutMenu->insertItem(i18n("&Modify..."), 2); + aboutMenu->insertItem(i18n("&Remove..."), 1); + aboutMenu->setItemEnabled(1, false); + aboutMenu->setItemEnabled(2, false); + } + + switch (aboutMenu->exec(QCursor::pos())) { + case 1: + removeItem(item); + break; + case 2: + modifyItem(item); + break; + case 3: + showNetDialog(); + break; + } + + delete aboutMenu; +} + +void NetConfig::modifyItem(QListViewItem *item) +{ + if (!item) + return; + + netDialog = new NetDialog(this); + Network::List::Iterator it, netDevice; + for ( it = m_networkList.begin(); it != m_networkList.end(); ++it ) + { + if ( ( *it ).name() == item->text( 0 ) ) + { + netDevice = it; + netDialog->setDeviceName( ( *it ).name() ); + netDialog->setShowTimer( ( *it ).showTimer() ); + netDialog->setFormat( ( *it ).format() ); + netDialog->setShowCommands( ( *it ).commandsEnabled() ); + netDialog->setCCommand( ( *it ).connectCommand() ); + netDialog->setDCommand( ( *it ).disconnectCommand() ); + break; + } + } + + netDialog->exec(); + if ( netDialog->okClicked() ) + { + m_networkList.remove( netDevice ); + m_networkList.append( Network( netDialog->deviceName(), + netDialog->format(), + netDialog->timer(), + netDialog->commands(), + netDialog->cCommand(), + netDialog->dCommand() ) ); + + item->setText( 0, netDialog->deviceName() ); + item->setText( 1, boolToString( netDialog->timer() ) ); + item->setText( 2, boolToString( netDialog->commands() ) ); + } + + delete netDialog; +} + +void NetConfig::removeItem(QListViewItem *item) +{ + if (!item) + return; + + int result = KMessageBox::warningContinueCancel(0, i18n("Are you sure you " + "want to remove the net interface '%1'?").arg(item->text(0)), QString::null, KStdGuiItem::del()); + + if (result == KMessageBox::Cancel) + return; + + int i = 0; + Network::List::Iterator it; + for ( it = m_networkList.begin(); it != m_networkList.end(); ++it ) + { + if ( item->text( 0 ) == ( *it ).name() ) + { + m_networkList.remove( it ); + if ( config()->deleteGroup( "device-" + QString::number( i ) ) ) + kdDebug(2003) << "device-" << i << " was deleted" << endl; + + break; + } + i++; + } + + delete item; +} + +void NetConfig::removeCurrent() +{ + removeItem(usingBox->currentItem()); +} + +void NetConfig::modifyCurrent() +{ + modifyItem(usingBox->currentItem()); +} + +void NetConfig::showNetDialog() +{ + netDialog = new NetDialog(this, "netDialog"); + netDialog->exec(); + if (netDialog->okClicked()) + getStats(); + + delete netDialog; +} + +void NetConfig::getStats() +{ + Network::List::ConstIterator it; + for ( it = m_networkList.begin(); it != m_networkList.end(); ++it ) + { + if ( ( *it ).name() == netDialog->deviceName() ) + { + KMessageBox::sorry(0, i18n("You already have a network " + "interface by this name. Please select a different interface")); + + return; + } + } + + m_networkList.append( Network( netDialog->deviceName(), + netDialog->format(), + netDialog->timer(), + netDialog->commands(), + netDialog->cCommand(), + netDialog->dCommand() ) ); + + (void) new QListViewItem( usingBox, + netDialog->deviceName(), + boolToString( netDialog->timer() ), + boolToString( netDialog->commands() ) ); +} + +const QString &NetConfig::boolToString(bool value) const +{ + if (value) + return m_yes; + + return m_no; +} diff --git a/ksim/monitors/net/netconfig.h b/ksim/monitors/net/netconfig.h new file mode 100644 index 0000000..9ec5c8d --- /dev/null +++ b/ksim/monitors/net/netconfig.h @@ -0,0 +1,67 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef NETCONFIG_H +#define NETCONFIG_H + +#include <pluginmodule.h> +#include "netdevices.h" + +class NetDialog; +class QPopupMenu; +class QPushButton; +class KListView; +class QHBoxLayout; +class QListViewItem; + +class NetConfig : public KSim::PluginPage +{ + Q_OBJECT + public: + NetConfig(KSim::PluginObject *parent, const char *name); + virtual ~NetConfig(); + + virtual void saveConfig(); + virtual void readConfig(); + + private slots: + void menu(KListView *, QListViewItem *, const QPoint &); + void modifyItem(QListViewItem *); + void removeItem(QListViewItem *); + void removeCurrent(); + void modifyCurrent(); + void showNetDialog(); + void getStats(); + + private: + // Couldnt think of a better name for this :) + const QString &boolToString(bool) const; + + QHBoxLayout *layout; + QPushButton *insertButton; + QPushButton *removeButton; + QPushButton *modifyButton; + KListView *usingBox; + NetDialog *netDialog; + Network::List m_networkList; + QString m_yes; + QString m_no; + QPopupMenu *aboutMenu; +}; +#endif diff --git a/ksim/monitors/net/netdevices.h b/ksim/monitors/net/netdevices.h new file mode 100644 index 0000000..2a5a680 --- /dev/null +++ b/ksim/monitors/net/netdevices.h @@ -0,0 +1,218 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef NETDEVICES_H +#define NETDEVICES_H + +#include <chart.h> +#include <led.h> + +class NetData +{ + public: + NetData() : in(0), out(0) {} + NetData &operator=( const NetData & rhs ) + { + in = rhs.in; + out = rhs.out; + + return *this; + } + + unsigned long in; + unsigned long out; +}; + +class Network +{ + public: + typedef QValueList<Network> List; + + Network() + { + m_chart = 0; + m_led = 0; + m_label = 0; + m_popup = 0; + + m_max = 0; + } + + Network( const QString & name, + const QString & format, + bool timer, + bool commands, + const QString & cCommand, + const QString & dCommand ) + : m_name( name ), + m_format( format ), + m_timer( timer ), + m_commands( commands ), + m_cCommand( cCommand ), + m_dCommand( dCommand ) + { + m_chart = 0; + m_led = 0; + m_label = 0; + m_popup = 0; + + m_max = 0; + } + + bool operator==( const Network & rhs ) const + { + return m_name == rhs.m_name && + m_format == rhs.m_format && + m_timer == rhs.m_timer && + m_commands == rhs.m_commands && + m_cCommand == rhs.m_cCommand && + m_dCommand == rhs.m_dCommand; + } + + bool operator!=( const Network & rhs ) const + { + return !operator==(rhs); + } + + bool operator<( const Network & rhs ) const + { + return m_name < rhs.m_name; + } + + bool operator>( const Network & rhs ) const + { + return m_name > rhs.m_name; + } + + bool operator<=( const Network & rhs ) const + { + return !( *this > rhs ); + } + + void cleanup() + { + delete m_chart; + delete m_label; + delete m_led; + delete m_popup; + + m_chart = 0; + m_label = 0; + m_led = 0; + m_popup = 0; + } + + void setData( const NetData & data ) + { + m_old = m_data; + m_data = data; + } + + const NetData & data() const + { + return m_data; + } + + const NetData & oldData() const + { + return m_old; + } + + void setMaxValue( int max ) + { + m_max = max; + } + + int maxValue() const + { + return m_max; + } + + const QString & name() const + { + return m_name; + } + + bool showTimer() const + { + return m_timer; + } + + const QString & format() const + { + return m_format; + } + + bool commandsEnabled() const + { + return m_commands; + } + + const QString & connectCommand() const + { + return m_cCommand; + } + + const QString & disconnectCommand() const + { + return m_dCommand; + } + + void setDisplay( KSim::Chart * chart, KSim::LedLabel * led, + KSim::Label * label, QPopupMenu * popup ) + { + m_chart = chart; + m_led = led; + m_label = label; + m_popup = popup; + } + + KSim::Chart * chart() + { + return m_chart; + } + + KSim::LedLabel * led() + { + return m_led; + } + + KSim::Label * label() + { + return m_label; + } + + private: + NetData m_data; + NetData m_old; + QString m_name; + QString m_format; + bool m_timer; + bool m_commands; + QString m_cCommand; + QString m_dCommand; + + KSim::Chart * m_chart; + KSim::LedLabel * m_led; + KSim::Label * m_label; + QPopupMenu * m_popup; + + int m_max; +}; +#endif diff --git a/ksim/monitors/net/netdialog.cpp b/ksim/monitors/net/netdialog.cpp new file mode 100644 index 0000000..fe655d4 --- /dev/null +++ b/ksim/monitors/net/netdialog.cpp @@ -0,0 +1,328 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "netdialog.h" +#include "netdialog.moc" + +#include <qcheckbox.h> +#include <qgroupbox.h> +#include <qlabel.h> +#include <qpushbutton.h> +#include <qtabwidget.h> +#include <qwidget.h> +#include <qlayout.h> +#include <qfile.h> +#include <qregexp.h> + +#include <klocale.h> +#include <kcombobox.h> +#include <kdebug.h> +#include <klineedit.h> +#include <kapplication.h> +#include <kurlrequester.h> +#include <kstdguiitem.h> + +#ifdef __FreeBSD__ +#include <sys/types.h> +#include <sys/sysctl.h> +#include <sys/socket.h> +#include <net/if.h> +#include <net/if_dl.h> +#include <net/route.h> +#endif + +#include <string.h> + +NetDialog::NetDialog(QWidget *parent, const char *name) + : QTabDialog(parent, name, true) +{ + m_clicked = false; + setCaption(kapp->makeStdCaption(i18n("Network Interface"))); + + m_generalTab = new QWidget(this); + m_generalLayout = new QGridLayout(m_generalTab); + m_generalLayout->setSpacing(6); + m_generalLayout->setMargin(11); + + m_deviceLabel = new QLabel(m_generalTab); + m_deviceLabel->setText(i18n("Interface:")); + m_generalLayout->addMultiCellWidget(m_deviceLabel, 0, 0, 0, 0); + + m_deviceCombo = new KComboBox(true, m_generalTab); + m_deviceCombo->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, + QSizePolicy::Fixed)); + m_deviceCombo->setFocus(); + m_deviceCombo->setDuplicatesEnabled(false); + m_generalLayout->addMultiCellWidget(m_deviceCombo, 0, 0, 1, 1); + + QStringList output(createList()); + if (output.isEmpty()) { + m_deviceCombo->insertItem("ppp0"); + m_deviceCombo->insertItem("eth0"); + } + else + m_deviceCombo->insertStringList(output); + + QSpacerItem *deviceSpacer = new QSpacerItem(20, 20, + QSizePolicy::Expanding, QSizePolicy::Fixed); + m_generalLayout->addMultiCell(deviceSpacer, 0, 0, 2, 2); + + m_timerBox = new QGroupBox(m_generalTab); + m_timerBox->setTitle(i18n("Timer")); + m_timerBox->setColumnLayout(0, Qt::Vertical); + m_timerBox->layout()->setSpacing(0); + m_timerBox->layout()->setMargin(0); + m_timerBoxLayout = new QVBoxLayout(m_timerBox->layout()); + m_timerBoxLayout->setAlignment(Qt::AlignTop); + m_timerBoxLayout->setSpacing(6); + m_timerBoxLayout->setMargin(11); + + m_timerEdit = new KLineEdit(m_timerBox); + m_timerEdit->setText("hh:mm:ss"); + m_timerEdit->setEnabled(false); + + m_showTimer = new QCheckBox(m_timerBox); + m_showTimer->setText(i18n("Show timer")); + connect(m_showTimer, SIGNAL(toggled(bool)), + m_timerEdit, SLOT(setEnabled(bool))); + m_timerBoxLayout->addWidget(m_showTimer); + m_timerBoxLayout->addWidget(m_timerEdit); + + m_hFormat = new QLabel(m_timerBox); + m_hFormat->setText(i18n("hh - Total hours online")); + m_timerBoxLayout->addWidget(m_hFormat); + + m_mFormat = new QLabel(m_timerBox); + m_mFormat->setText(i18n("mm - Total minutes online")); + m_timerBoxLayout->addWidget(m_mFormat); + + m_sFormat = new QLabel(m_timerBox); + m_sFormat->setText(i18n("ss - Total seconds online")); + m_timerBoxLayout->addWidget(m_sFormat); + m_generalLayout->addMultiCellWidget(m_timerBox, 1, 1, 0, 2); + + QSpacerItem *spacer = new QSpacerItem(20, 20, + QSizePolicy::Minimum, QSizePolicy::Expanding); + m_generalLayout->addMultiCell(spacer, 2, 2, 0, 0); + addTab(m_generalTab, i18n("General")); + + m_commandTab = new QWidget(this); + m_commandLayout = new QGridLayout(m_commandTab); + m_commandLayout->setSpacing(6); + m_commandLayout->setMargin(11); + + m_enableCommands = new QCheckBox(m_commandTab); + m_enableCommands->setText(i18n("Enable connect/disconnect")); + m_commandLayout->addMultiCellWidget(m_enableCommands, 0, 0, 0, 2); + + m_cCommand = new QLabel(m_commandTab); + m_cCommand->setText(i18n("Connect command:")); + m_commandLayout->addMultiCellWidget(m_cCommand, 1, 1, 0, 0); + + m_connectRequester = new KURLRequester(m_commandTab); + m_connectRequester->setMinimumSize(145, 0); + m_connectRequester->setEnabled(false); + connect(m_enableCommands, SIGNAL(toggled(bool)), + m_connectRequester, SLOT(setEnabled(bool))); + m_commandLayout->addMultiCellWidget(m_connectRequester, 1, 1, 1, 2); + + m_dCommand = new QLabel(m_commandTab); + m_dCommand->setText(i18n("Disconnect command:")); + m_commandLayout->addMultiCellWidget(m_dCommand, 2, 2, 0, 0); + + m_disconnectRequester = new KURLRequester(m_commandTab); + m_disconnectRequester->setMinimumSize(145, 0); + m_disconnectRequester->setEnabled(false); + connect(m_enableCommands, SIGNAL(toggled(bool)), + m_disconnectRequester, SLOT(setEnabled(bool))); + m_commandLayout->addMultiCellWidget(m_disconnectRequester, 2, 2, 1, 2); + + QSpacerItem *commandSpacer = new QSpacerItem(20, 20, + QSizePolicy::Minimum, QSizePolicy::Expanding); + m_commandLayout->addItem(commandSpacer); + addTab(m_commandTab, i18n("Commands")); + + setOkButton(KStdGuiItem::ok().text()); + setCancelButton(KStdGuiItem::cancel().text()); + connect(this, SIGNAL(applyButtonPressed()), SLOT(sendClicked())); +} + +NetDialog::~NetDialog() +{ +} + +const QString NetDialog::deviceName() const +{ + return m_deviceCombo->currentText(); +} + +bool NetDialog::timer() +{ + return m_showTimer->isChecked(); +} + +const QString NetDialog::format() const +{ + return m_timerEdit->text(); +} + +bool NetDialog::commands() +{ + return m_enableCommands->isChecked(); +} + +const QString NetDialog::cCommand() const +{ + return m_connectRequester->url(); +} + +const QString NetDialog::dCommand() const +{ + return m_disconnectRequester->url(); +} + +void NetDialog::setDeviceName(const QString &text) +{ + m_deviceCombo->setCurrentItem(text, true); +} + +void NetDialog::setShowTimer(bool value) +{ + m_showTimer->setChecked(value); +} + +void NetDialog::setFormat(const QString &format) +{ + m_timerEdit->setText(format); +} + +void NetDialog::setShowCommands(bool value) +{ + m_enableCommands->setChecked(value); +} + +void NetDialog::setCCommand(const QString &text) +{ + m_connectRequester->setURL(text); +} + +void NetDialog::setDCommand(const QString &text) +{ + m_disconnectRequester->setURL(text); +} + +void NetDialog::sendClicked() +{ + m_clicked = true; + kdDebug(2003) << "ok was clicked" << endl; +} + +QStringList NetDialog::createList() const +{ +#ifdef __linux__ + QFile file("/proc/net/dev"); + if (!file.open(IO_ReadOnly)) + return QStringList(); + + QStringList output; + QTextStream textStream(&file); + while (!textStream.atEnd()) + output.append(textStream.readLine()); + + if (output.isEmpty()) + return QStringList(); + + output.pop_front(); + output.pop_front(); + + QStringList::Iterator it; + QStringList list; + for (it = output.begin(); it != output.end(); ++it) { + list = QStringList::split(' ', (*it)); + (*it) = list[0].stripWhiteSpace(); + (*it).truncate((*it).find(':')); + } + + return output; +#endif + +#ifdef __FreeBSD__ + QStringList output; + int mib[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 }; + char *buf = 0; + int alloc = 0; + struct if_msghdr *ifm, *nextifm; + struct sockaddr_dl *sdl; + char *lim, *next; + size_t needed; + char s[32]; + + if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) + return QStringList(); + + if (alloc < needed) { + buf = new char[needed]; + + if (buf == NULL) + return QStringList(); + + alloc = needed; + } + + if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) + return QStringList(); + + lim = buf + needed; + + next = buf; + while (next < lim) { + ifm = (struct if_msghdr *)next; + if (ifm->ifm_type != RTM_IFINFO) + return QStringList(); + + next += ifm->ifm_msglen; + + // get an interface with a network address + while (next < lim) { + nextifm = (struct if_msghdr *)next; + if (nextifm->ifm_type != RTM_NEWADDR) + break; + + next += nextifm->ifm_msglen; + } + + // if the interface is up + if (ifm->ifm_flags & IFF_UP) { + sdl = (struct sockaddr_dl *)(ifm + 1); + if (sdl->sdl_family != AF_LINK) + continue; + + strncpy(s, sdl->sdl_data, sdl->sdl_nlen); + s[sdl->sdl_nlen] = '\0'; + + output.append(s); + } + } + + if (buf) + delete[] buf; + + return output; +#endif +} diff --git a/ksim/monitors/net/netdialog.h b/ksim/monitors/net/netdialog.h new file mode 100644 index 0000000..b6d7801 --- /dev/null +++ b/ksim/monitors/net/netdialog.h @@ -0,0 +1,85 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef NETDIALOG_H +#define NETDIALOG_H + +#include <qtabdialog.h> + +class QVBoxLayout; +class QGridLayout; +class QCheckBox; +class QGroupBox; +class QLabel; +class QWidget; +class KComboBox; +class KLineEdit; +class KURLRequester; + +class NetDialog : public QTabDialog +{ + Q_OBJECT + public: + NetDialog(QWidget *parent, const char *name = 0); + ~NetDialog(); + + const QString deviceName() const; + bool timer(); + const QString format() const; + bool commands(); + const QString cCommand() const; + const QString dCommand() const; + bool okClicked() { return m_clicked; } + + public slots: + void setDeviceName(const QString &); + void setShowTimer(bool); + void setFormat(const QString &); + void setShowCommands(bool); + void setCCommand(const QString &); + void setDCommand(const QString &); + + private slots: + void sendClicked(); + + private: + QStringList createList() const; + + bool m_clicked; + QWidget *m_generalTab; + QLabel *m_deviceLabel; + KComboBox *m_deviceCombo; + QGroupBox *m_timerBox; + QCheckBox *m_showTimer; + KLineEdit *m_timerEdit; + QLabel *m_hFormat; + QLabel *m_mFormat; + QLabel *m_sFormat; + QWidget *m_commandTab; + QCheckBox *m_enableCommands; + QLabel *m_cCommand; + KURLRequester *m_connectRequester; + QLabel *m_dCommand; + KURLRequester *m_disconnectRequester; + + QGridLayout *m_generalLayout; + QVBoxLayout *m_timerBoxLayout; + QGridLayout *m_commandLayout; +}; +#endif // NETDIALOG_H diff --git a/ksim/monitors/snmp/Makefile.am b/ksim/monitors/snmp/Makefile.am new file mode 100644 index 0000000..0c922c9 --- /dev/null +++ b/ksim/monitors/snmp/Makefile.am @@ -0,0 +1,16 @@ +kde_module_LTLIBRARIES = ksim_snmp.la +ksim_snmp_la_SOURCES = plugin.cpp view.cpp configpage.cpp configwidget.ui snmp.cpp hostdialogbase.ui hostdialog.cpp value.cpp monitor.cpp \ + monitordialogbase.ui monitordialog.cpp labelmonitor.cpp chartmonitor.cpp \ + identifier.cpp monitorconfig.cpp hostconfig.cpp session.cpp probedialog.cpp snmplib.cpp \ + pdu.cpp proberesultdialogbase.ui proberesultdialog.cpp browsedialogbase.ui browsedialog.cpp \ + walker.cpp + +ksim_snmp_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +ksim_snmp_la_LIBADD = ../../library/libksimcore.la $(LIB_KIO) $(LIBSNMP) + +INCLUDES= -I$(top_srcdir)/ksim/library $(all_includes) + +METASOURCES = AUTO + +mon_DATA = Snmp.desktop +mondir = $(kde_datadir)/ksim/monitors diff --git a/ksim/monitors/snmp/Snmp.desktop b/ksim/monitors/snmp/Snmp.desktop new file mode 100644 index 0000000..b6ceb4c --- /dev/null +++ b/ksim/monitors/snmp/Snmp.desktop @@ -0,0 +1,70 @@ +[Desktop Entry] +Comment=Snmp Status Monitor +Comment[ar]=مراقب حالة Snmp +Comment[bg]=Мониторинг на Snmp +Comment[bs]=Nadzor SNMP statusa +Comment[ca]=Monitor d'estat snmp +Comment[cs]=Monitor stavu SNMP +Comment[cy]=Monitr Cyflwr Snmp +Comment[da]=Snmp statusovervågning +Comment[de]=Statusanzeige für SNMP +Comment[el]=Επόπτης κατάστασης snmp +Comment[eo]=Monitoro por la Snmp-stato +Comment[es]=Monitor de estado de Snmp +Comment[et]=Snmp oleku monitooring +Comment[eu]=Snmp Egoera Begiralea +Comment[fa]=نمایشگر وضعیت Snmp +Comment[fi]=SNPP-tilavalvoja +Comment[fr]=Indicateur d'état snmp +Comment[ga]=Monatóir Stádais SNMP +Comment[hi]=एसएनएमपी स्थिति मॉनीटर +Comment[hu]=Snmp állapotmonitor +Comment[is]=Snmp eftirlitstól +Comment[it]=Controllo di stato SNMP +Comment[ja]=Snmp ステータスモニタ +Comment[ka]=Snmp სტატუსის მონიტორი +Comment[kk]=SNMP күйін бақылау +Comment[km]=កម្មវិធីត្រួតពិនិត្យស្ថានភាព Snmp +Comment[lt]=Snmp būsenos stebėtojas +Comment[mk]=Монитор за статусот на Snmp +Comment[nb]=Overvåkning av status via SNMP +Comment[nds]=SNMP-Statuskieker +Comment[ne]=Snmp स्थिति मोनिटर +Comment[nl]=Snmp Statusbewaking +Comment[nn]=Overvaking av status via SNMP +Comment[pa]=Snmp ਹਾਲਤ ਨਿਗਰਾਨ +Comment[pl]=Monitor statusu Snmp +Comment[pt]=Monitor de Estado do SNMP +Comment[pt_BR]=Monitor de estado do SNMP +Comment[ro]=Monitor stare SNMP +Comment[ru]=Монитор состояния SNMP +Comment[sk]=Monitor stavu SNMP +Comment[sl]=Nadzornik stanja Snmp +Comment[sr]=Надгледање статуса Snmp-а +Comment[sr@Latn]=Nadgledanje statusa Snmp-a +Comment[sv]=Övervakar SNMP-status +Comment[ta]=Snmp நிலை கண்காணி +Comment[tg]=Дидабони Ҳолати Snmp +Comment[tr]=Snmp Durum Monitörü +Comment[uk]=Монітор стану мережі (snmp протокол) +Comment[wa]=Corwaitoe di l' estat snmp +Comment[zh_CN]=Snmp 状态监视器 +Comment[zh_TW]=Snmp 狀態監視器 +Icon=network +Name=Snmp +Name[cs]=SNMP +Name[de]=SNMP +Name[ga]=SNMP +Name[hi]=एसएनएमपी +Name[it]=SNMP +Name[kk]=SNMP +Name[nds]=SNMP +Name[ro]=SNMP +Name[sk]=SNMP +Name[sv]=SNMP +X-KSIM-VERSION=0.1 +X-KSIM-LIBRARY=snmp +X-KSIM-COPYRIGHT=(C) 2003 Simon Hausmann +X-KSIM-EMAIL=hausmann@kde.org +X-KSIM-PREFS=Snmp +X-KSIM-AUTHOR=Simon Hausmann diff --git a/ksim/monitors/snmp/browsedialog.cpp b/ksim/monitors/snmp/browsedialog.cpp new file mode 100644 index 0000000..d196ec8 --- /dev/null +++ b/ksim/monitors/snmp/browsedialog.cpp @@ -0,0 +1,147 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "browsedialog.h" + +#include <qlabel.h> + +#include <klistview.h> +#include <kguiitem.h> +#include <klocale.h> +#include <kpushbutton.h> +#include <klineedit.h> + +using namespace KSim::Snmp; + +BrowseDialog::BrowseDialog( const HostConfig &hostConfig, const QString ¤tOid, QWidget *parent, const char *name ) + : BrowseDialogBase( parent, name ), m_host( hostConfig ) +{ + stop->setGuiItem( KGuiItem( i18n( "&Stop" ), "stop" ) ); + + browserContents->setSorting( -1 ); + + selectedObject->setText( currentOid ); + + m_walker = 0; + + baseOids << "1.3.6.1.2" << "1.3.6.1.4"; + nextWalk(); +} + +QString BrowseDialog::selectedObjectIdentifier() const +{ + return selectedObject->text(); +} + +void BrowseDialog::stopAllWalks() +{ + baseOids.clear(); + stopWalker(); +} + +void BrowseDialog::insertBrowseItem( const Walker::Result &result ) +{ + if ( !result.success || + result.data.type() == Value::EndOfMIBView || + result.data.type() == Value::NoSuchInstance || + result.data.type() == Value::NoSuchObject ) { + + nextWalk(); + return; + } + + QListViewItem *i = new QListViewItem( browserContents, browserContents->lastItem(), result.identifierString, result.dataString ); + applyFilter( i ); +} + +void BrowseDialog::applyFilter() +{ + for ( QListViewItem *i = browserContents->firstChild(); + i; i = i->nextSibling() ) + applyFilter( i ); +} + +void BrowseDialog::nextWalk() +{ + stopWalker(); + + if ( baseOids.isEmpty() ) + return; + + QString baseOidString = baseOids.pop(); + Identifier id = Identifier::fromString( baseOidString ); + if ( id.isNull() ) + return; + startWalk( id ); +} + +void BrowseDialog::startWalk( const Identifier &startOid ) +{ + stopWalker(); + + m_walker = new Walker( m_host, startOid, this ); + connect( m_walker, SIGNAL( resultReady( const Walker::Result & ) ), + this, SLOT( insertBrowseItem( const Walker::Result & ) ) ); + connect( m_walker, SIGNAL( finished() ), + this, SLOT( nextWalk() ) ); + + stop->setEnabled( true ); +} + +void BrowseDialog::stopWalker() +{ + if ( !m_walker ) + return; + + disconnect( m_walker, SIGNAL( resultReady( const Walker::Result & ) ), + this, SLOT( insertBrowseItem( const Walker::Result & ) ) ); + disconnect( m_walker, SIGNAL( finished() ), + this, SLOT( nextWalk() ) ); + + m_walker->deleteLater(); + m_walker = 0; + + stop->setEnabled( false ); +} + +void BrowseDialog::objectSelected( QListViewItem *item ) +{ + selectedObject->setText( item->text( 0 ) ); +} + +void BrowseDialog::applyFilter( QListViewItem *item ) +{ + QString filterText = filter->text(); + + if ( filterText.isEmpty() ) { + item->setVisible( true ); + return; + } + + if ( item->text( 0 ).find( filterText, 0 /*index*/, false /*case sensitive*/ ) == -1 ) { + item->setVisible( false ); + return; + } + + item->setVisible( true ); +} + +#include "browsedialog.moc" +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/browsedialog.h b/ksim/monitors/snmp/browsedialog.h new file mode 100644 index 0000000..cb6466a --- /dev/null +++ b/ksim/monitors/snmp/browsedialog.h @@ -0,0 +1,71 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef BROWSEDIALOG_H +#define BROWSEDIALOG_H + +#include "browsedialogbase.h" + +#include "hostconfig.h" +#include "identifier.h" +#include "value.h" +#include "snmp.h" +#include "walker.h" + +#include <qvaluestack.h> + +namespace KSim +{ + +namespace Snmp +{ + +class BrowseDialog : public BrowseDialogBase +{ + Q_OBJECT +public: + BrowseDialog( const HostConfig &hostConfig, const QString ¤tOid, QWidget *parent, const char *name = 0 ); + + QString selectedObjectIdentifier() const; + +protected: + virtual void stopAllWalks(); + virtual void applyFilter(); + virtual void objectSelected( QListViewItem *item ); + +private slots: + void insertBrowseItem( const Walker::Result &browseResult ); + void nextWalk(); + +private: + void applyFilter( QListViewItem *item ); + void startWalk( const Identifier &startOid ); + void stopWalker(); + + HostConfig m_host; + Walker *m_walker; + QValueStack<QString> baseOids; +}; + +} +} + +#endif // BROWSEDIALOG_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/browsedialogbase.ui b/ksim/monitors/snmp/browsedialogbase.ui new file mode 100644 index 0000000..17459f8 --- /dev/null +++ b/ksim/monitors/snmp/browsedialogbase.ui @@ -0,0 +1,262 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>KSim::Snmp::BrowseDialogBase</class> +<widget class="KDialog"> + <property name="name"> + <cstring>MyDialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>650</width> + <height>532</height> + </rect> + </property> + <property name="caption"> + <string>Browse</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Filter:</string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>filter</cstring> + </property> + </widget> + <widget class="Line"> + <property name="name"> + <cstring>line1</cstring> + </property> + <property name="frameShape"> + <enum>VLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>stop</cstring> + </property> + <property name="text"> + <string>Stop</string> + </property> + </widget> + </hbox> + </widget> + <widget class="KListView" row="1" column="0"> + <column> + <property name="text"> + <string>Object</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Value</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>browserContents</cstring> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + </widget> + <widget class="QLayoutWidget" row="3" column="0"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget" row="2" column="0"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>blah</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Selected object:</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>selectedObject</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>textLabel1</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>71</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>MyDialog</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>MyDialog</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>stop</sender> + <signal>clicked()</signal> + <receiver>MyDialog</receiver> + <slot>stopAllWalks()</slot> + </connection> + <connection> + <sender>filter</sender> + <signal>textChanged(const QString&)</signal> + <receiver>MyDialog</receiver> + <slot>applyFilter()</slot> + </connection> + <connection> + <sender>browserContents</sender> + <signal>executed(QListViewItem*)</signal> + <receiver>MyDialog</receiver> + <slot>objectSelected(QListViewItem*)</slot> + </connection> +</connections> +<slots> + <slot access="protected">stopAllWalks()</slot> + <slot access="protected">applyFilter()</slot> + <slot access="protected">objectSelected(QListViewItem *)</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kdialog.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>klistview.h</includehint> +</includehints> +</UI> diff --git a/ksim/monitors/snmp/chartmonitor.cpp b/ksim/monitors/snmp/chartmonitor.cpp new file mode 100644 index 0000000..1a32086 --- /dev/null +++ b/ksim/monitors/snmp/chartmonitor.cpp @@ -0,0 +1,83 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#include "chartmonitor.h" + +#include <kio/global.h> + +using namespace KSim::Snmp; + +ChartMonitor::ChartMonitor( const MonitorConfig &config, QWidget *parent, const char *name ) + : KSim::Chart( true /* displayMeter */, 0, QString::null, parent, name ), + m_lastValue( 0 ), m_config( config ), m_firstSampleReceived( false ) +{ + setTitle( m_config.name ); + disableAutomaticUpdates(); +} + +void ChartMonitor::setData( const Value &data ) +{ + Q_UINT64 currentValue = convertToInt( data ); + + if ( data.isCounterType() ) { + int diff = currentValue - m_lastValue; + + if ( !m_firstSampleReceived ) { + diff = 0; + m_firstSampleReceived = true; + } + + m_lastValue = currentValue; + currentValue = diff; + } + + // move the graph and add the new sample then + updateDisplay(); + setValue( currentValue ); + if ( m_config.displayCurrentValueInline ) { + Q_UINT64 bytesPerSec = currentValue / ( m_config.refreshInterval.seconds + m_config.refreshInterval.minutes * 60 ); + setText( KIO::convertSize( bytesPerSec ), 0 ); + } +} + +Q_UINT64 ChartMonitor::convertToInt( const Value &data ) +{ + switch ( data.type() ) { + case Value::TimeTicks: + case Value::Int: return data.toInt(); + case Value::Gauge: + case Value::Counter: + case Value::UInt: return data.toUInt(); + case Value::Counter64: return data.toCounter64(); + case Value::Double: // ### not sure what to do here... + case Value::ByteArray: + case Value::Oid: // ### could treat this as a sort of hyperlink... hmm + case Value::IpAddress: + case Value::NoSuchObject: + case Value::NoSuchInstance: + case Value::EndOfMIBView: + case Value::Invalid: + case Value::Null: return 0; + } + return 0; +} + +#include "chartmonitor.moc" + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/chartmonitor.h b/ksim/monitors/snmp/chartmonitor.h new file mode 100644 index 0000000..30a58ad --- /dev/null +++ b/ksim/monitors/snmp/chartmonitor.h @@ -0,0 +1,54 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#ifndef CHARTMONITOR_H +#define CHARTMONITOR_H + +#include "chart.h" +#include "monitor.h" + +namespace KSim +{ + +namespace Snmp +{ + +class ChartMonitor : public KSim::Chart +{ + Q_OBJECT +public: + ChartMonitor( const MonitorConfig &config, QWidget *parent, const char *name = 0 ); + +public slots: + void setData( const Value &data ); + +private: + Q_UINT64 m_lastValue; + MonitorConfig m_config; + bool m_firstSampleReceived; + + static Q_UINT64 convertToInt( const Value &data ); +}; + +} + +} + +#endif // CHARTMONITOR_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/configpage.cpp b/ksim/monitors/snmp/configpage.cpp new file mode 100644 index 0000000..d15d606 --- /dev/null +++ b/ksim/monitors/snmp/configpage.cpp @@ -0,0 +1,313 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "configpage.h" +#include "plugin.h" + +#include "configwidget.h" +#include "hostdialog.h" +#include "monitordialog.h" + +#include <qlayout.h> +#include <qgroupbox.h> +#include <qpushbutton.h> + +#include <kconfig.h> +#include <klistview.h> +#include <kmessagebox.h> +#include <klocale.h> + +using namespace KSim::Snmp; + +static bool listViewHasSelection( QListView *lv ) +{ + for ( QListViewItem *i = lv->firstChild(); i; i = i->itemBelow() ) + if ( i->isSelected() ) + return true; + return false; +} + +ConfigPage::ConfigPage( Plugin *parent, const char *name ) + : KSim::PluginPage( parent, name ) +{ + ( new QVBoxLayout( this ) )->setAutoAdd( true ); + + m_page = new ConfigWidget( this ); + + connect( m_page->addHost, SIGNAL( clicked() ), + this, SLOT( addNewHost() ) ); + connect( m_page->modifyHost, SIGNAL( clicked() ), + this, SLOT( modifyHost() ) ); + connect( m_page->removeHost, SIGNAL( clicked() ), + this, SLOT( removeHost() ) ); + + connect( m_page->addMonitor, SIGNAL( clicked() ), + this, SLOT( addNewMonitor() ) ); + connect( m_page->modifyMonitor, SIGNAL( clicked() ), + this, SLOT( modifyMonitor() ) ); + connect( m_page->removeMonitor, SIGNAL( clicked() ), + this, SLOT( removeMonitor() ) ); + + connect( m_page->hosts, SIGNAL( selectionChanged() ), + this, SLOT( disableOrEnableSomeWidgets() ) ); + connect( m_page->monitors, SIGNAL( selectionChanged() ), + this, SLOT( disableOrEnableSomeWidgets() ) ); +} + +ConfigPage::~ConfigPage() +{ +} + +void ConfigPage::saveConfig() +{ + KConfig &cfg = *config(); + + // collect garbage + removeAllHostGroups(); + removeAllMonitorGroups(); + + QStringList hosts = m_hosts.save( cfg ); + QStringList monitors = m_monitors.save( cfg ); + + cfg.setGroup( "General" ); + cfg.writeEntry( "Hosts", hosts ); + cfg.writeEntry( "Monitors", monitors ); +} + +void ConfigPage::readConfig() +{ + KConfig &cfg = *config(); + + cfg.setGroup( "General" ); + QStringList hosts = cfg.readListEntry( "Hosts" ); + QStringList monitors = cfg.readListEntry( "Monitors" ); + + m_hosts.load( cfg, hosts ); + m_monitors.load( cfg, monitors, m_hosts ); + + fillGui(); +} + +void ConfigPage::addNewHost() +{ + HostDialog dlg( this ); + if ( dlg.exec() ) { + HostConfig src = dlg.settings(); + m_hosts.insert( src.name, src ); + + ( void )new HostItem( m_page->hosts, src ); + } + + disableOrEnableSomeWidgets(); +} + +void ConfigPage::modifyHost() +{ + HostItem *currentItem = dynamic_cast<HostItem *>( m_page->hosts->currentItem() ); + if ( !currentItem ) + return; + + HostConfigMap::Iterator hostIt = m_hosts.find( currentItem->text( 0 ) ); + if ( hostIt == m_hosts.end() ) + return; + + HostDialog dlg( *hostIt, this ); + if ( dlg.exec() ) { + HostConfig newHost = dlg.settings(); + + if ( newHost.name != hostIt.key() ) { + m_hosts.remove( hostIt ); + hostIt = m_hosts.insert( newHost.name, newHost ); + } else + *hostIt = newHost; + + currentItem->setFromHostConfig( newHost ); + } +} + +void ConfigPage::removeHost() +{ + HostItem *currentItem = dynamic_cast<HostItem *>( m_page->hosts->currentItem() ); + if ( !currentItem ) + return; + + HostConfigMap::Iterator hostIt = m_hosts.find( currentItem->text( 0 ) ); + if ( hostIt == m_hosts.end() ) + return; + + QStringList monitors = monitorsForHost( *hostIt ); + if ( !monitors.isEmpty() ) { + int answer = KMessageBox::warningContinueCancelList( + this, + i18n( "This host has the following monitor associated. Do you really want to delete this host entry?", + "This host has the following %n monitors associated. Do you really want to delete this host entry?", + monitors.count() ), + monitors, + i18n( "Delete Host Entry" ), + i18n( "Delete" ) ); + + if ( answer != KMessageBox::Continue ) + return; + + removeMonitors( monitors ); + } + + m_hosts.remove( hostIt ); + delete currentItem; + + disableOrEnableSomeWidgets(); +} + +void ConfigPage::addNewMonitor() +{ + MonitorDialog dlg( m_hosts, this ); + if ( dlg.exec() ) { + MonitorConfig monitor = dlg.monitorConfig(); + m_monitors.insert( monitor.name, monitor ); + + ( void )new MonitorItem( m_page->monitors, monitor ); + } +} + +void ConfigPage::modifyMonitor() +{ + MonitorItem *currentItem = dynamic_cast<MonitorItem *>( m_page->monitors->currentItem() ); + if ( !currentItem ) + return; + + MonitorConfigMap::Iterator monitorIt = m_monitors.find( currentItem->text( 0 ) ); + if ( monitorIt == m_monitors.end() ) + return; + + MonitorDialog dlg( *monitorIt, m_hosts, this ); + if ( dlg.exec() ) { + MonitorConfig newMonitor = dlg.monitorConfig(); + + if ( newMonitor.name != monitorIt.key() ) { + m_monitors.remove( monitorIt ); + monitorIt = m_monitors.insert( newMonitor.name, newMonitor ); + } else + *monitorIt = newMonitor; + + currentItem->setFromMonitor( newMonitor ); + } +} + +void ConfigPage::removeMonitor() +{ + MonitorItem *currentItem = dynamic_cast<MonitorItem *>( m_page->monitors->currentItem() ); + if ( !currentItem ) + return; + + MonitorConfigMap::Iterator monitorIt = m_monitors.find( currentItem->text( 0 ) ); + if ( monitorIt == m_monitors.end() ) + return; + + m_monitors.remove( monitorIt ); + delete currentItem; +} + +void ConfigPage::disableOrEnableSomeWidgets() +{ + bool hostSelected = listViewHasSelection( m_page->hosts ); + bool monitorSelected = listViewHasSelection( m_page->monitors ); + + m_page->modifyHost->setEnabled( hostSelected ); + m_page->removeHost->setEnabled( hostSelected ); + + m_page->modifyMonitor->setEnabled( monitorSelected ); + m_page->removeMonitor->setEnabled( monitorSelected ); + + m_page->monitorGroup->setEnabled( !m_hosts.isEmpty() ); +} + +void ConfigPage::removeMonitors( QStringList monitors ) +{ + for ( QStringList::ConstIterator it = monitors.begin(); + it != monitors.end(); ++it ) + m_monitors.remove( *it ); + + QListViewItem *item = m_page->monitors->firstChild(); + while ( item ) { + QListViewItem *nextItem = item->itemBelow(); + + for ( QStringList::Iterator it = monitors.begin(); + it != monitors.end(); ++it ) + if ( item->text( 0 ) == *it ) { + + monitors.remove( it ); + + delete item; + + break; + } + + item = nextItem; + } +} + +void ConfigPage::removeAllHostGroups() +{ + removeConfigGroups( "Host " ); +} + +void ConfigPage::removeAllMonitorGroups() +{ + removeConfigGroups( "Monitor " ); +} + +void ConfigPage::removeConfigGroups( const QString &prefix ) +{ + KConfig &cfg = *config(); + + QStringList groups = cfg.groupList(); + for ( QStringList::ConstIterator it = groups.begin(); it != groups.end(); ++it ) + if ( ( *it ).startsWith( prefix ) ) + cfg.deleteGroup( *it, true /* deep */ ); +} + +void ConfigPage::fillGui() +{ + m_page->hosts->clear(); + m_page->monitors->clear(); + + for ( HostConfigMap::ConstIterator it = m_hosts.begin(); it != m_hosts.end(); ++it ) + ( void )new HostItem( m_page->hosts, *it ); + + for ( MonitorConfigMap::ConstIterator it = m_monitors.begin(); it != m_monitors.end(); ++it ) + ( void )new MonitorItem( m_page->monitors, *it ); + + disableOrEnableSomeWidgets(); +} + +QStringList ConfigPage::monitorsForHost( const HostConfig &host ) const +{ + QStringList monitors; + + for ( MonitorConfigMap::ConstIterator it = m_monitors.begin(); + it != m_monitors.end(); ++it ) + if ( ( *it ).host == host ) + monitors << ( *it ).name; + + return monitors; +} + +#include "configpage.moc" +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/configpage.h b/ksim/monitors/snmp/configpage.h new file mode 100644 index 0000000..42c7579 --- /dev/null +++ b/ksim/monitors/snmp/configpage.h @@ -0,0 +1,120 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef CONFIGPAGE_H +#define CONFIGPAGE_H + +#include <pluginmodule.h> +#include <klistview.h> + +#include "monitorconfig.h" +#include "hostconfig.h" + +namespace KSim +{ + +namespace Snmp +{ + +class HostItem : public QListViewItem +{ +public: + HostItem( QListView *parent, const KSim::Snmp::HostConfig &src ) + : QListViewItem( parent, QString::null, QString::null, QString::null ) + { + setFromHostConfig( src ); + } + + HostItem( QListView *parent ) + : QListViewItem( parent, QString::null, QString::null, QString::null ) + {} + + void setFromHostConfig( const KSim::Snmp::HostConfig &src ) + { + setText( 0, src.name ); + setText( 1, QString::number( src.port ) ); + setText( 2, snmpVersionToString( src.version ) ); + } +}; + +class MonitorItem : public QListViewItem +{ +public: + MonitorItem( QListView *parent, const KSim::Snmp::MonitorConfig &monitor ) + : QListViewItem( parent, QString::null, QString::null, QString::null ) + { + setFromMonitor( monitor ); + } + + MonitorItem( QListView *parent ) + : QListViewItem( parent, QString::null, QString::null, QString::null ) + {} + + void setFromMonitor( const KSim::Snmp::MonitorConfig &monitor ) + { + setText( 0, monitor.name ); + setText( 1, monitorDisplayTypeToString( monitor.display ) ); + } +}; + +class ConfigWidget; +class Plugin; + +class ConfigPage : public KSim::PluginPage +{ + Q_OBJECT +public: + ConfigPage( Plugin *parent, const char *name ); + ~ConfigPage(); + + virtual void saveConfig(); + virtual void readConfig(); + +private slots: + void addNewHost(); + void modifyHost(); + void removeHost(); + void addNewMonitor(); + void modifyMonitor(); + void removeMonitor(); + + void disableOrEnableSomeWidgets(); + +private: + void removeMonitors( QStringList monitors ); + + void removeAllHostGroups(); + void removeAllMonitorGroups(); + void removeConfigGroups( const QString &prefix ); + void fillGui(); + + QStringList monitorsForHost( const HostConfig &host ) const; + + ConfigWidget *m_page; + KSim::Snmp::HostConfigMap m_hosts; + KSim::Snmp::MonitorConfigMap m_monitors; +}; + +} + +} + +#endif // CONFIGPAGE_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/configure.in.in b/ksim/monitors/snmp/configure.in.in new file mode 100644 index 0000000..2d266d7 --- /dev/null +++ b/ksim/monitors/snmp/configure.in.in @@ -0,0 +1,40 @@ +AC_ARG_WITH(snmp, + [AC_HELP_STRING(--with-snmp, + [enable support for SNMP @<:@default=check@:>@])], + [], with_snmp=check) + +enable_snmp=no +if test "x$with_snmp" != xno; then + KDE_CHECK_HEADER( net-snmp/library/snmp_api.h, + [ have_netsnmp_h=yes ], [ have_netsnmp_h=no ], + [ #include <net-snmp/net-snmp-config.h> + #include <net-snmp/types.h> + ] + ) + + if test "$have_netsnmp_h" = yes; then + KDE_CHECK_LIB( netsnmp, snmp_sess_init, [ + AC_SUBST( LIBSNMP, "-lnetsnmp" ) + enable_snmp=yes + ], [], [] ) + fi + + if test "$enable_snmp" != yes; then + AC_MSG_CHECKING([if libnetsnmp needs -lcrypto]) + + dnl use a different symbol to prevent autoconf from caching + KDE_CHECK_LIB( netsnmp, snmp_open, [ + AC_SUBST( LIBSNMP, "-lnetsnmp -lcrypto" ) + enable_snmp=yes + AC_MSG_RESULT(yes) + ], [ + AC_MSG_RESULT(no) + ], [-lcrypto] ) + fi + + if test "x$with_snmp" != xcheck && test "x$enable_snmp" != xyes; then + AC_MSG_ERROR([--with-snmp was given, but test for net-snmp failed]) + fi +fi + +AM_CONDITIONAL(include_ksim_monitors_snmp, test "x$enable_snmp" = xyes) diff --git a/ksim/monitors/snmp/configwidget.ui b/ksim/monitors/snmp/configwidget.ui new file mode 100644 index 0000000..c121184 --- /dev/null +++ b/ksim/monitors/snmp/configwidget.ui @@ -0,0 +1,215 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>KSim::Snmp::ConfigWidget</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ConfigWidget</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>740</width> + <height>597</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox"> + <property name="name"> + <cstring>hostGroup</cstring> + </property> + <property name="title"> + <string>SNMP Hosts</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton" row="1" column="3"> + <property name="name"> + <cstring>removeHost</cstring> + </property> + <property name="text"> + <string>Remove</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="2"> + <property name="name"> + <cstring>modifyHost</cstring> + </property> + <property name="text"> + <string>Modify...</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>addHost</cstring> + </property> + <property name="text"> + <string>Add...</string> + </property> + </widget> + <widget class="KListView" row="0" column="0" rowspan="1" colspan="4"> + <column> + <property name="text"> + <string>Host</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Port</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Version</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>hosts</cstring> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>141</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>monitorGroup</cstring> + </property> + <property name="title"> + <string>SNMP Monitors</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>addMonitor</cstring> + </property> + <property name="text"> + <string>Add...</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="2"> + <property name="name"> + <cstring>modifyMonitor</cstring> + </property> + <property name="text"> + <string>Modify...</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="3"> + <property name="name"> + <cstring>removeMonitor</cstring> + </property> + <property name="text"> + <string>Remove</string> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>121</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KListView" row="0" column="0" rowspan="1" colspan="4"> + <column> + <property name="text"> + <string>Name</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Type</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>monitors</cstring> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + </vbox> +</widget> +<tabstops> + <tabstop>hosts</tabstop> + <tabstop>addHost</tabstop> + <tabstop>modifyHost</tabstop> + <tabstop>removeHost</tabstop> + <tabstop>monitors</tabstop> + <tabstop>addMonitor</tabstop> + <tabstop>modifyMonitor</tabstop> + <tabstop>removeMonitor</tabstop> +</tabstops> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klistview.h</includehint> + <includehint>klistview.h</includehint> +</includehints> +</UI> diff --git a/ksim/monitors/snmp/hostconfig.cpp b/ksim/monitors/snmp/hostconfig.cpp new file mode 100644 index 0000000..1b96541 --- /dev/null +++ b/ksim/monitors/snmp/hostconfig.cpp @@ -0,0 +1,152 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "hostconfig.h" + +#include <kstringhandler.h> + +#include <netdb.h> + +using namespace KSim::Snmp; + +static int defaultSnmpPort() +{ + servent *ent = getservbyname( "snmp", 0 ); + if ( !ent ) + return 161; + return ent->s_port; +} + +bool HostConfig::load( KConfigBase &config ) +{ + name = config.readEntry( "Host" ); + if ( name.isEmpty() ) + return false; + + port = config.readNumEntry( "Port", defaultSnmpPort() ); + + bool ok = false; + version = stringToSnmpVersion( config.readEntry( "Version" ), &ok ); + if ( !ok ) + return false; + + if ( version != SnmpVersion3 ) { + community = config.readEntry( "Community" ); + return true; + } + + securityName = config.readEntry( "SecurityName" ); + + securityLevel = stringToSecurityLevel( config.readEntry( "SecurityLevel" ), &ok ); + if ( !ok ) + return false; + + if ( securityLevel == NoAuthPriv ) + return true; + + authentication.protocol = stringToAuthenticationProtocol( config.readEntry( "AuthType" ), &ok ); + if ( !ok ) + return false; + authentication.key = KStringHandler::obscure( config.readEntry( "AuthPassphrase" ) ); + + if ( securityLevel == AuthNoPriv ) + return true; + + privacy.protocol = stringToPrivacyProtocol( config.readEntry( "PrivType" ), &ok ); + if ( !ok ) + return false; + privacy.key = KStringHandler::obscure( config.readEntry( "PrivPassphrase" ) ); + + return true; +} + +void HostConfig::save( KConfigBase &config ) const +{ + if ( isNull() ) + return; + + config.writeEntry( "Host", name ); + if ( port != 0 ) + config.writeEntry( "Port", port ); + + config.writeEntry( "Version", snmpVersionToString( version ) ); + + if ( version != SnmpVersion3 ) { + writeIfNotEmpty( config, "Community", community ); + return; + } + + writeIfNotEmpty( config, "SecurityName", securityName ); + + config.writeEntry( "SecurityLevel", securityLevelToString( securityLevel ) ); + + if ( securityLevel == NoAuthPriv ) + return; + + writeIfNotEmpty( config, "AuthType", authenticationProtocolToString( authentication.protocol ) ); + writeIfNotEmpty( config, "AuthPassphrase", KStringHandler::obscure( authentication.key ) ); + + if ( securityLevel == AuthNoPriv ) + return; + + writeIfNotEmpty( config, "PrivType", privacyProtocolToString( privacy.protocol ) ); + writeIfNotEmpty( config, "PrivPassphrase", KStringHandler::obscure( privacy.key ) ); +} + +void HostConfig::writeIfNotEmpty( KConfigBase &config, const QString &name, const QString &value ) +{ + if ( value.isEmpty() ) + return; + + config.writeEntry( name, value ); +} + +void HostConfigMap::load( KConfigBase &config, const QStringList &hosts ) +{ + clear(); + + for ( QStringList::ConstIterator it = hosts.begin(); it != hosts.end(); ++it ) { + config.setGroup( "Host " + *it ); + + HostConfig src; + if ( !src.load( config ) ) + continue; + + insert( *it, src ); + } +} + +QStringList HostConfigMap::save( KConfigBase &config ) const +{ + QStringList hostList; + + for ( ConstIterator it = begin(); it != end(); ++it ) { + QString host = it.key(); + + hostList << host; + + config.setGroup( "Host " + host ); + ( *it ).save( config ); + } + + return hostList; +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/hostconfig.h b/ksim/monitors/snmp/hostconfig.h new file mode 100644 index 0000000..d19de9b --- /dev/null +++ b/ksim/monitors/snmp/hostconfig.h @@ -0,0 +1,86 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef HOSTCONFIG_H +#define HOSTCONFIG_H + +#include "snmp.h" + +namespace KSim +{ + +namespace Snmp +{ + +struct HostConfig +{ + HostConfig() {} + HostConfig( KConfigBase &config ) + { load( config ); } + + QString name; // hostname + ushort port; + + SnmpVersion version; + + QString community; + + QString securityName; + + SecurityLevel securityLevel; + + struct + { + AuthenticationProtocol protocol; + QString key; + } authentication; + struct + { + PrivacyProtocol protocol; + QString key; + } privacy; + + bool load( KConfigBase &config ); + void save( KConfigBase &config ) const; + + bool isNull() const { return name.isEmpty(); } + + bool operator==( const HostConfig &rhs ) const + { return name == rhs.name; } + +private: + static void writeIfNotEmpty( KConfigBase &config, const QString &name, const QString &value ); +}; + +struct HostConfigMap : public QMap< QString, HostConfig > +{ + HostConfigMap() {} + HostConfigMap( const QMap< QString, HostConfig > &rhs ) + : QMap< QString, HostConfig >( rhs ) {} + + void load( KConfigBase &config, const QStringList &hosts ); + QStringList save( KConfigBase &config ) const; +}; + +} +} + +#endif // HOSTCONFIG_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/hostdialog.cpp b/ksim/monitors/snmp/hostdialog.cpp new file mode 100644 index 0000000..a1ccdc3 --- /dev/null +++ b/ksim/monitors/snmp/hostdialog.cpp @@ -0,0 +1,193 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "hostdialog.h" +#include "probedialog.h" +#include "proberesultdialog.h" + +#include <qcombobox.h> +#include <qwidgetstack.h> +#include <klineedit.h> +#include <qlabel.h> +#include <qpushbutton.h> +#include <qspinbox.h> + +#include <klocale.h> +#include <kmessagebox.h> + +#include <assert.h> + +using namespace KSim::Snmp; + +HostDialog::HostDialog( QWidget *parent, const char *name ) + : HostDialogBase( parent, name ) +{ + init(); + port->setValue( 161 ); +} + +HostDialog::HostDialog( const HostConfig &src, QWidget *parent, const char *name ) + : HostDialogBase( parent, name ) +{ + init( src ); +} + +HostConfig HostDialog::settings() const +{ + HostConfig result; + + result.name = hostName->text(); + result.port = port->value(); + + result.version = stringToSnmpVersion( snmpVersion->currentText() ); + if ( result.version != SnmpVersion3 ) { + result.community = communityString->text(); + } + + result.securityName = securityName->text(); + + result.securityLevel = stringToSecurityLevel( securityLevel->currentText() ); + + if ( result.securityLevel == NoAuthPriv ) + return result; + + result.authentication.protocol = stringToAuthenticationProtocol( authenticationType->currentText() ); + result.authentication.key = authenticationPassphrase->text(); + + if ( result.securityLevel == AuthNoPriv ) + return result; + + result.privacy.protocol = stringToPrivacyProtocol( privacyType->currentText() ); + result.privacy.key = privacyPassphrase->text(); + + return result; +} + +void HostDialog::showSnmpAuthenticationDetailsForVersion( const QString &versionStr ) +{ + bool ok = false; + SnmpVersion version = stringToSnmpVersion( versionStr, &ok ); + assert( ok ); + + authenticationDetails->raiseWidget( version == SnmpVersion3 ? snmpV3Page : snmpV1Page ); +} + +void HostDialog::enableDisabledAuthenticationAndPrivacyElementsForSecurityLevel( const QString &levelStr ) +{ + bool ok = false; + SecurityLevel level = stringToSecurityLevel( levelStr, &ok ); + assert( ok ); + + bool enableAuthentication = level != NoAuthPriv; + bool enablePrivacy = level == AuthPriv; + + authenticationTypeLabel->setEnabled( enableAuthentication ); + authenticationType->setEnabled( enableAuthentication ); + authenticationPassphraseLabel->setEnabled( enableAuthentication ); + authenticationPassphrase->setEnabled( enableAuthentication ); + + privacyTypeLabel->setEnabled( enablePrivacy ); + privacyType->setEnabled( enablePrivacy ); + privacyPassphraseLabel->setEnabled( enablePrivacy ); + privacyPassphrase->setEnabled( enablePrivacy ); +} + +void HostDialog::checkValidity() +{ + bool enableOk = true; + bool ok = false; + SnmpVersion version = stringToSnmpVersion( snmpVersion->currentText(), &ok ); + assert( ok ); + + enableOk &= !hostName->text().isEmpty(); + + if ( version == SnmpVersion3 ) + enableOk &= !securityName->text().isEmpty(); + else + enableOk &= !communityString->text().isEmpty(); + + buttonOk->setEnabled( enableOk ); + testHostButton->setEnabled( enableOk ); +} + +void HostDialog::testHost() +{ + ProbeDialog dlg( settings(), this ); + if ( dlg.exec() ) { + ProbeDialog::ProbeResultList results = dlg.probeResults(); + + ProbeResultDialog resultDlg( settings(), results, this ); + resultDlg.exec(); + } +} + +void HostDialog::init( const HostConfig &src ) +{ + // hide these, there's nothing to choose right now. might be that + // net-snmp will support different privacy types in the future, but + // apparently not now. + privacyTypeLabel->hide(); + privacyType->hide(); + + snmpVersion->insertStringList( allSnmpVersions() ); + securityLevel->insertStringList( allSecurityLevels() ); + authenticationType->insertStringList( allAuthenticationProtocols() ); + privacyType->insertStringList( allPrivacyProtocols() ); + + if ( !src.isNull() ) + loadSettingsFromHostConfig( src ); + + showSnmpAuthenticationDetailsForVersion( snmpVersion->currentText() ); + enableDisabledAuthenticationAndPrivacyElementsForSecurityLevel( securityLevel->currentText() ); + checkValidity(); +} + +void HostDialog::loadSettingsFromHostConfig( const HostConfig &src ) +{ + hostName->setText( src.name ); + port->setValue( src.port ); + + snmpVersion->setCurrentItem( allSnmpVersions().findIndex( snmpVersionToString( src.version ) ) ); + + if ( src.version != SnmpVersion3 ) { + communityString->setText( src.community ); + return; + } + + securityName->setText( src.securityName ); + + securityLevel->setCurrentItem( allSecurityLevels().findIndex( securityLevelToString( src.securityLevel ) ) ); + + if ( src.securityLevel == NoAuthPriv ) + return; + + authenticationType->setCurrentItem( allAuthenticationProtocols().findIndex( authenticationProtocolToString( src.authentication.protocol ) ) ); + authenticationPassphrase->setText( src.authentication.key ); + + if ( src.securityLevel == AuthNoPriv ) + return; + + privacyType->setCurrentItem( allPrivacyProtocols().findIndex( privacyProtocolToString( src.privacy.protocol ) ) ); + privacyPassphrase->setText( src.privacy.key ); +} + +#include "hostdialog.moc" + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/hostdialog.h b/ksim/monitors/snmp/hostdialog.h new file mode 100644 index 0000000..e296b7b --- /dev/null +++ b/ksim/monitors/snmp/hostdialog.h @@ -0,0 +1,59 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef HOSTDIALOG_H +#define HOSTDIALOG_H + +#include "hostdialogbase.h" +#include "hostconfig.h" +#include "probedialog.h" + +namespace KSim +{ + +namespace Snmp +{ + +class HostDialog : public HostDialogBase +{ + Q_OBJECT +public: + HostDialog( QWidget *parent, const char *name = 0 ); + HostDialog( const HostConfig &src, QWidget *parent, const char *name = 0 ); + + HostConfig settings() const; + +private slots: + void showSnmpAuthenticationDetailsForVersion( const QString &versionStr ); + void enableDisabledAuthenticationAndPrivacyElementsForSecurityLevel( const QString &levelStr ); + void checkValidity(); + void testHost(); + +private: + void init( const HostConfig &src = HostConfig() ); + void loadSettingsFromHostConfig( const HostConfig &src ); +}; + +} + +} + +#endif // HOSTDIALOG_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/hostdialogbase.ui b/ksim/monitors/snmp/hostdialogbase.ui new file mode 100644 index 0000000..1ee9ee4 --- /dev/null +++ b/ksim/monitors/snmp/hostdialogbase.ui @@ -0,0 +1,526 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>KSim::Snmp::HostDialogBase</class> +<comment>Much thanks to Frerich for hints/advice on the GUI design</comment> +<author>Simon Hausmann</author> +<widget class="KDialog"> + <property name="name"> + <cstring>HostDialogBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>559</width> + <height>454</height> + </rect> + </property> + <property name="caption"> + <string>Configure Host</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <property name="text"> + <string>&Hostname:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>hostName</cstring> + </property> + </widget> + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>hostName</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="2"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>&Port:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>port</cstring> + </property> + </widget> + <widget class="QSpinBox" row="0" column="3"> + <property name="name"> + <cstring>port</cstring> + </property> + <property name="maxValue"> + <number>65535</number> + </property> + <property name="minValue"> + <number>1</number> + </property> + </widget> + <spacer row="0" column="4"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>91</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QButtonGroup" row="1" column="0" rowspan="1" colspan="5"> + <property name="name"> + <cstring>buttonGroup2</cstring> + </property> + <property name="title"> + <string>Authentication Details</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QWidgetStack" row="2" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>authenticationDetails</cstring> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>snmpV1Page</cstring> + </property> + <attribute name="id"> + <number>0</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel5</cstring> + </property> + <property name="text"> + <string>&Community String:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>communityString</cstring> + </property> + </widget> + <spacer row="1" column="1"> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>41</height> + </size> + </property> + </spacer> + <spacer row="0" column="2"> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>160</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>communityString</cstring> + </property> + <property name="echoMode"> + <enum>Password</enum> + </property> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>snmpV3Page</cstring> + </property> + <attribute name="id"> + <number>1</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel6</cstring> + </property> + <property name="text"> + <string>S&ecurity name:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>securityName</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel7</cstring> + </property> + <property name="text"> + <string>Security &level:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>securityLevel</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>authenticationTypeLabel</cstring> + </property> + <property name="text"> + <string>&Authentication type:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>authenticationType</cstring> + </property> + </widget> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>privacyTypeLabel</cstring> + </property> + <property name="text"> + <string>P&rivacy type:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>privacyType</cstring> + </property> + </widget> + <widget class="QLabel" row="5" column="0"> + <property name="name"> + <cstring>privacyPassphraseLabel</cstring> + </property> + <property name="text"> + <string>Priva&cy passphrase:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>privacyPassphrase</cstring> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>authenticationPassphraseLabel</cstring> + </property> + <property name="text"> + <string>Authentication &passphrase:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>authenticationPassphrase</cstring> + </property> + </widget> + <spacer row="3" column="2"> + <property name="name"> + <cstring>spacer5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>71</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>securityName</cstring> + </property> + </widget> + <widget class="QComboBox" row="4" column="1"> + <property name="name"> + <cstring>privacyType</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + </widget> + <widget class="KLineEdit" row="5" column="1"> + <property name="name"> + <cstring>privacyPassphrase</cstring> + </property> + <property name="echoMode"> + <enum>Password</enum> + </property> + </widget> + <widget class="QComboBox" row="1" column="1"> + <property name="name"> + <cstring>securityLevel</cstring> + </property> + </widget> + <widget class="QComboBox" row="2" column="1"> + <property name="name"> + <cstring>authenticationType</cstring> + </property> + </widget> + <widget class="KLineEdit" row="3" column="1"> + <property name="name"> + <cstring>authenticationPassphrase</cstring> + </property> + <property name="echoMode"> + <enum>Password</enum> + </property> + </widget> + <spacer row="6" column="1"> + <property name="name"> + <cstring>spacer7</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + </widget> + <widget class="Line" row="1" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>line3</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel2_2</cstring> + </property> + <property name="text"> + <string>&SNMP version:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>snmpVersion</cstring> + </property> + </widget> + <widget class="QComboBox" row="0" column="1"> + <property name="name"> + <cstring>snmpVersion</cstring> + </property> + </widget> + <spacer row="0" column="2"> + <property name="name"> + <cstring>spacer8</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>351</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="Line" row="2" column="0" rowspan="1" colspan="5"> + <property name="name"> + <cstring>line2</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="QLayoutWidget" row="3" column="0" rowspan="1" colspan="5"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>testHostButton</cstring> + </property> + <property name="text"> + <string>Test Host...</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>220</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>HostDialogBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>HostDialogBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>snmpVersion</sender> + <signal>activated(const QString&)</signal> + <receiver>HostDialogBase</receiver> + <slot>showSnmpAuthenticationDetailsForVersion(const QString&)</slot> + </connection> + <connection> + <sender>securityLevel</sender> + <signal>activated(const QString&)</signal> + <receiver>HostDialogBase</receiver> + <slot>enableDisabledAuthenticationAndPrivacyElementsForSecurityLevel(const QString&)</slot> + </connection> + <connection> + <sender>hostName</sender> + <signal>textChanged(const QString&)</signal> + <receiver>HostDialogBase</receiver> + <slot>checkValidity()</slot> + </connection> + <connection> + <sender>securityName</sender> + <signal>textChanged(const QString&)</signal> + <receiver>HostDialogBase</receiver> + <slot>checkValidity()</slot> + </connection> + <connection> + <sender>communityString</sender> + <signal>textChanged(const QString&)</signal> + <receiver>HostDialogBase</receiver> + <slot>checkValidity()</slot> + </connection> + <connection> + <sender>testHostButton</sender> + <signal>clicked()</signal> + <receiver>HostDialogBase</receiver> + <slot>testHost()</slot> + </connection> +</connections> +<tabstops> + <tabstop>hostName</tabstop> + <tabstop>port</tabstop> + <tabstop>snmpVersion</tabstop> + <tabstop>securityName</tabstop> + <tabstop>securityLevel</tabstop> + <tabstop>authenticationType</tabstop> + <tabstop>authenticationPassphrase</tabstop> + <tabstop>privacyType</tabstop> + <tabstop>privacyPassphrase</tabstop> + <tabstop>buttonOk</tabstop> + <tabstop>buttonCancel</tabstop> + <tabstop>communityString</tabstop> +</tabstops> +<slots> + <slot access="private">showSnmpAuthenticationDetailsForVersion(const QString &)</slot> + <slot>enableDisabledAuthenticationAndPrivacyElementsForSecurityLevel(const QString &)</slot> + <slot>checkValidity()</slot> + <slot access="protected">testHost()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kdialog.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> +</includehints> +</UI> diff --git a/ksim/monitors/snmp/identifier.cpp b/ksim/monitors/snmp/identifier.cpp new file mode 100644 index 0000000..25c188e --- /dev/null +++ b/ksim/monitors/snmp/identifier.cpp @@ -0,0 +1,129 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "identifier.h" +#include "snmp_p.h" +#include "snmplib.h" + +#include <assert.h> + +using namespace KSim::Snmp; + +Identifier::Data::Data( const oid *d, size_t length ) +{ + memcpy( data, d, length * sizeof( oid ) ); + this->length = length; +} + +Identifier::Identifier() + : d( new Data ) +{ +} + +Identifier::Identifier( Data *data ) + : d( data ) +{ + assert( d ); +} + +Identifier::Identifier( const Identifier &rhs ) + : d( new Data( *rhs.d ) ) +{ +} + +Identifier &Identifier::operator=( const Identifier &rhs ) +{ + if ( d == rhs.d ) + return *this; + + *d = *rhs.d; + + return *this; +} + +Identifier::~Identifier() +{ + delete d; +} + +Identifier Identifier::fromString( const QString &name, bool *ok ) +{ + Identifier res; + res.d->length = MAX_OID_LEN; + // if ( !get_node( name.ascii(), res.d->data, &res.d->length ) ) { + if ( name.isEmpty() || !SnmpLib::self()->snmp_parse_oid( name.ascii(), res.d->data, &res.d->length ) ) { + if ( ok ) + *ok = false; + return Identifier(); + } + + if ( ok ) + *ok = true; + + return res; +} + +QString Identifier::toString( PrintFlags flags ) const +{ + size_t buflen = 256; + size_t outlen = 0; + int overflow = 0; + + u_char *buf = ( u_char* )calloc( buflen, 1 ); + if ( !buf ) + return QString::null; + + int oldOutpuFormat = SnmpLib::self()->netsnmp_ds_get_int( NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT ); + SnmpLib::self()->netsnmp_ds_set_int( NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, + flags == PrintAscii ? NETSNMP_OID_OUTPUT_MODULE : NETSNMP_OID_OUTPUT_NUMERIC ); + + SnmpLib::self()->netsnmp_sprint_realloc_objid_tree( &buf, &buflen, &outlen, 1 /* alloc realloc */, + &overflow, d->data, d->length ); + + SnmpLib::self()->netsnmp_ds_set_int( NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, oldOutpuFormat ); + + if ( overflow ) { + free( buf ); + return QString::null; + } + + QString result = QString::fromAscii( ( char* )buf ); + + free( buf ); + + return result; +} + +bool Identifier::operator==( const Identifier &rhs ) const +{ + return SnmpLib::self()->netsnmp_oid_equals( d->data, d->length, rhs.d->data, rhs.d->length ) == 0; +} + +bool Identifier::operator<( const Identifier &rhs ) const +{ + return SnmpLib::self()->snmp_oid_compare( d->data, d->length, rhs.d->data, rhs.d->length ) < 0; +} + +bool Identifier::isNull() const +{ + return d->length == 0; +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/identifier.h b/ksim/monitors/snmp/identifier.h new file mode 100644 index 0000000..7da54dd --- /dev/null +++ b/ksim/monitors/snmp/identifier.h @@ -0,0 +1,72 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef IDENTIFIER_H +#define IDENTIFIER_H + +#include <qstring.h> +#include <qvaluelist.h> +#include <qmap.h> + +#include "value.h" + +namespace KSim +{ + +namespace Snmp +{ + +class Identifier +{ +public: + friend class PDU; + struct Data; + + enum PrintFlags { PrintAscii, PrintNumeric }; + + Identifier(); + Identifier( Data *data ); + Identifier( const Identifier &rhs ); + Identifier &operator=( const Identifier &rhs ); + ~Identifier(); + + static Identifier fromString( const QString &name, bool *ok = 0 ); + + QString toString( PrintFlags flags = PrintAscii ) const; + + bool isNull() const; + + bool operator==( const Identifier &rhs ) const; + bool operator!=( const Identifier &rhs ) const + { return !operator==( rhs ); } + bool operator<( const Identifier &rhs ) const; + +private: + Data *d; +}; + +typedef QValueList<Identifier> IdentifierList; +typedef QMap<Identifier, Value> ValueMap; + +} +} + +#endif // IDENTIFIER_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/labelmonitor.cpp b/ksim/monitors/snmp/labelmonitor.cpp new file mode 100644 index 0000000..24e48c7 --- /dev/null +++ b/ksim/monitors/snmp/labelmonitor.cpp @@ -0,0 +1,45 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "labelmonitor.h" + +using namespace KSim::Snmp; + +LabelMonitor::LabelMonitor( const MonitorConfig &config, QWidget *parent, const char *name ) + : KSim::Label( parent, name ), m_config( config ) +{ +} + +void LabelMonitor::setData( const Value &data ) +{ + QString dataString = data.toString( m_config.refreshInterval.minutes == 0 ? Value::TimeTicksWithSeconds : 0 ); + + if ( m_config.useCustomFormatString ) { + QString text = m_config.customFormatString; + text.replace( "%n", m_config.name ); + text.replace( "%s", dataString ); + setText( text ); + } else + setText( m_config.name + ": " + dataString ); +} + +#include "labelmonitor.moc" + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/labelmonitor.h b/ksim/monitors/snmp/labelmonitor.h new file mode 100644 index 0000000..3e92c69 --- /dev/null +++ b/ksim/monitors/snmp/labelmonitor.h @@ -0,0 +1,52 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef LABELMONITOR_H +#define LABELMONITOR_H + +#include "label.h" +#include "value.h" +#include "monitorconfig.h" + +namespace KSim +{ + +namespace Snmp +{ + +class LabelMonitor : public KSim::Label +{ + Q_OBJECT +public: + LabelMonitor( const MonitorConfig &config, QWidget *parent, const char *name = 0 ); + +public slots: + void setData( const Value &data ); + +private: + MonitorConfig m_config; +}; + +} + +} + +#endif // LABELMONITOR_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/monitor.cpp b/ksim/monitors/snmp/monitor.cpp new file mode 100644 index 0000000..7a97825 --- /dev/null +++ b/ksim/monitors/snmp/monitor.cpp @@ -0,0 +1,96 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "monitor.h" + +#include <qtimer.h> +#include <qapplication.h> + +using namespace KSim::Snmp; + +Monitor::Monitor( const HostConfig &host, const Identifier &oid, int refresh, QObject *parent, const char *name ) + : QObject( parent, name ), m_oid( oid ), m_session( host ) +{ + if ( refresh > 0 ) + m_timerId = startTimer( refresh ); + else + m_timerId = -1; + + QTimer::singleShot( 0, this, SLOT( performSnmpRequest() ) ); +} + +Monitor::~Monitor() +{ + if ( QThread::running() ) + QThread::wait(); +} + +void Monitor::run() +{ + AsyncSnmpQueryResult *result = new AsyncSnmpQueryResult; + + result->oid = m_oid; + result->success = performSyncSnmpRequest( result->data, &result->error ); + + QCustomEvent *ev = new QCustomEvent( QEvent::User, result ); + QApplication::postEvent( this, ev ); +} + +void Monitor::customEvent( QCustomEvent *ev ) +{ + if ( ev->type() != QEvent::User ) + return; + + AsyncSnmpQueryResult *result = reinterpret_cast<AsyncSnmpQueryResult *>( ev->data() ); + if ( result->success ) { + emit newData( result->data ); + emit newData( result->oid, result->data ); + } else { + emit error( result->error ); + emit error( result->oid, result->error ); + } + + delete result; +} + +void Monitor::timerEvent( QTimerEvent *ev ) +{ + if ( ev->timerId() != m_timerId ) + return; + + performSnmpRequest(); +} + +void Monitor::performSnmpRequest() +{ + if ( QThread::running() ) + return; + + start(); +} + +bool Monitor::performSyncSnmpRequest( Value &data, ErrorInfo *errorInfo ) +{ + return m_session.snmpGet( m_oid, data, errorInfo ); +} + +#include "monitor.moc" + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/monitor.h b/ksim/monitors/snmp/monitor.h new file mode 100644 index 0000000..cd3dedc --- /dev/null +++ b/ksim/monitors/snmp/monitor.h @@ -0,0 +1,77 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef MONITOR_H +#define MONITOR_H + +#include "monitorconfig.h" +#include "session.h" + +#include <qthread.h> + +namespace KSim +{ + +namespace Snmp +{ + +class Monitor : public QObject, public QThread +{ + Q_OBJECT +public: + Monitor( const HostConfig &host, const Identifier &oid, int refresh, QObject *parent = 0, const char *name = 0 ); + virtual ~Monitor(); + +signals: + void newData( const Value &data ); + void newData( const Identifier &oid, const Value &data ); + void error( const ErrorInfo &errorInfo ); + void error( const Identifier &oid, const ErrorInfo &errorInfo ); + +protected: + virtual void run(); + virtual void customEvent( QCustomEvent *ev ); + virtual void timerEvent( QTimerEvent *ev ); + +private slots: + void performSnmpRequest(); + bool performSyncSnmpRequest( Value &data, ErrorInfo *errorInfo = 0 ); + +private: + struct AsyncSnmpQueryResult + { + AsyncSnmpQueryResult() : success( false ) {} + Identifier oid; + Value data; + ErrorInfo error; + bool success; + }; + + const Identifier m_oid; + int m_timerId; + Session m_session; +}; + +} + +} + +#endif // MONITOR_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/monitorconfig.cpp b/ksim/monitors/snmp/monitorconfig.cpp new file mode 100644 index 0000000..6b3b27e --- /dev/null +++ b/ksim/monitors/snmp/monitorconfig.cpp @@ -0,0 +1,183 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "monitorconfig.h" +#include "labelmonitor.h" +#include "chartmonitor.h" + +#include <assert.h> + +using namespace KSim::Snmp; + +MonitorConfig::MonitorConfig() +{ + display = Label; + refreshInterval.minutes = refreshInterval.seconds = 0; + useCustomFormatString = false; + displayCurrentValueInline = false; +} + +bool MonitorConfig::load( KConfigBase &config, const HostConfigMap &hosts ) +{ + QString hostName = config.readEntry( "Host" ); + if ( hostName.isEmpty() ) + return false; + + HostConfigMap::ConstIterator hostIt = hosts.find( hostName ); + if ( hostIt == hosts.end() ) + return false; + + host = *hostIt; + + name = config.readEntry( "MonitorName" ); + if ( name.isEmpty() ) + return false; + + oid = config.readEntry( "ObjectIdentifier" ); + if ( Identifier::fromString( oid ).isNull() ) + return false; + + bool ok = false; + display = stringToMonitorDisplayType( config.readEntry( "DisplayType" ), &ok ); + if ( !ok ) + return false; + + refreshInterval.minutes = config.readUnsignedNumEntry( "RefreshIntervalMinutes" ); + refreshInterval.seconds = config.readUnsignedNumEntry( "RefreshIntervalSeconds" ); + + if ( refreshInterval.minutes == 0 && refreshInterval.seconds == 0 ) + return false; + + if ( display == Label ) { + useCustomFormatString = config.readBoolEntry( "UseCustomFormatString", useCustomFormatString ); + if ( useCustomFormatString ) + customFormatString = config.readEntry( "CustomFormatString" ); + } else + displayCurrentValueInline = config.readBoolEntry( "DisplayCurrentValueInline", displayCurrentValueInline ); + + return true; +} + +void MonitorConfig::save( KConfigBase &config ) const +{ + if ( isNull() ) + return; + + config.writeEntry( "Host", host.name ); + config.writeEntry( "MonitorName", name ); + config.writeEntry( "ObjectIdentifier", oid ); + config.writeEntry( "DisplayType", monitorDisplayTypeToString( display ) ); + config.writeEntry( "RefreshIntervalMinutes", refreshInterval.minutes ); + config.writeEntry( "RefreshIntervalSeconds", refreshInterval.seconds ); + if ( display == Label ) { + config.writeEntry( "UseCustomFormatString", useCustomFormatString ); + if ( useCustomFormatString ) + config.writeEntry( "CustomFormatString", customFormatString ); + } else + config.writeEntry( "DisplayCurrentValueInline", displayCurrentValueInline ); +} + +QWidget *MonitorConfig::createMonitorWidget( QWidget *parent, const char *name ) +{ + QWidget *w; + + int refresh = refreshInterval.seconds * 1000 + refreshInterval.minutes * 60 * 1000; + Identifier id = Identifier::fromString( oid ); + if ( id.isNull() ) + return 0; + + if ( display == Label ) + w = new LabelMonitor( *this, parent, name ); + else + w = new ChartMonitor( *this, parent, name ); + + Monitor *monitor = new Monitor( host, id, refresh, w ); + QObject::connect( monitor, SIGNAL( newData( const Value & ) ), + w, SLOT( setData( const Value & ) ) ); + return w; +} + +QString KSim::Snmp::monitorDisplayTypeToString( MonitorConfig::DisplayType type ) +{ + switch ( type ) + { + case MonitorConfig::Label: return QString::fromLatin1( "Label" ); + case MonitorConfig::Chart: return QString::fromLatin1( "Chart" ); + default: assert( false ); + }; + return QString::null; +} + +MonitorConfig::DisplayType KSim::Snmp::stringToMonitorDisplayType( QString string, bool *ok ) +{ + string = string.lower(); + if ( string == "chart" ) { + if ( ok ) + *ok = true; + return MonitorConfig::Chart; + } + if ( string == "label" ) { + if ( ok ) + *ok = true; + return MonitorConfig::Label; + } + if ( ok ) + *ok = false; + return MonitorConfig::Chart; +} + +QStringList KSim::Snmp::allDisplayTypes() +{ + // !!! keep order with enum + return QStringList() << "Label" << "Chart"; +} + +void MonitorConfigMap::load( KConfigBase &config, const QStringList &names, const HostConfigMap &hosts ) +{ + clear(); + + for ( QStringList::ConstIterator it = names.begin(); it != names.end(); ++it ) { + config.setGroup( "Monitor " + *it ); + + MonitorConfig monitor; + if ( !monitor.load( config, hosts ) ) + continue; + + insert( *it, monitor ); + } +} + +QStringList MonitorConfigMap::save( KConfigBase &config ) const +{ + QStringList names; + + for ( ConstIterator it = begin(); it != end(); ++it ) { + QString name = it.key(); + + names << name; + + config.setGroup( "Monitor " + name ); + ( *it ).save( config ); + } + + return names; +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/monitorconfig.h b/ksim/monitors/snmp/monitorconfig.h new file mode 100644 index 0000000..bbc8674 --- /dev/null +++ b/ksim/monitors/snmp/monitorconfig.h @@ -0,0 +1,84 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef MONITORCONFIG_H +#define MONITORCONFIG_H + +#include "hostconfig.h" + +namespace KSim +{ + +namespace Snmp +{ + +struct MonitorConfig +{ + enum DisplayType { Label = 0, Chart }; + + MonitorConfig(); + MonitorConfig( KConfigBase &config, const HostConfigMap &hosts ) + { load( config, hosts ); } + + bool load( KConfigBase &config, const HostConfigMap &hosts ); + void save( KConfigBase &config ) const; + + bool isNull() const { return name.isEmpty() || host.isNull(); } + + QWidget *createMonitorWidget( QWidget *parent, const char *name = 0 ); + + HostConfig host; + QString name; + QString oid; + struct + { + uint minutes; + uint seconds; + } refreshInterval; + DisplayType display; + + bool useCustomFormatString; + QString customFormatString; + + bool displayCurrentValueInline; +}; + +struct MonitorConfigMap : public QMap< QString, MonitorConfig > +{ + MonitorConfigMap() {} + MonitorConfigMap( const QMap< QString, MonitorConfig > &rhs ) + : QMap< QString, MonitorConfig >( rhs ) {} + + void load( KConfigBase &config, const QStringList &names, const HostConfigMap &hosts ); + QStringList save( KConfigBase &config ) const; +}; + +typedef QValueList<MonitorConfig> MonitorConfigList; + +QString monitorDisplayTypeToString( MonitorConfig::DisplayType type ); +MonitorConfig::DisplayType stringToMonitorDisplayType( QString string, bool *ok = 0 ); +QStringList allDisplayTypes(); + +} + +} + +#endif // MONITORCONFIG_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/monitordialog.cpp b/ksim/monitors/snmp/monitordialog.cpp new file mode 100644 index 0000000..615a1aa --- /dev/null +++ b/ksim/monitors/snmp/monitordialog.cpp @@ -0,0 +1,178 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "monitordialog.h" +#include "identifier.h" +#include "browsedialog.h" + +#include <qcombobox.h> +#include <qlineedit.h> +#include <qspinbox.h> +#include <qpushbutton.h> +#include <qradiobutton.h> +#include <qbuttongroup.h> +#include <qcheckbox.h> +#include <qlabel.h> + +#include <klocale.h> +#include <kpushbutton.h> + +#include <assert.h> + +using namespace KSim::Snmp; + +MonitorDialog::MonitorDialog( const HostConfigMap &hosts, QWidget *parent, const char *name ) + : MonitorDialogBase( parent, name ), m_hosts( hosts ) +{ + init(); +} + +MonitorDialog::MonitorDialog( const MonitorConfig &monitor, const HostConfigMap &hosts, QWidget *parent, const char *name ) + : MonitorDialogBase( parent, name ), m_hosts( hosts ) +{ + init( monitor ); +} + +MonitorConfig MonitorDialog::monitorConfig() const +{ + MonitorConfig result; + + result.host = currentHost(); + if ( result.host.isNull() ) + return MonitorConfig(); + + result.name = monitorName->text(); + if ( result.name.isEmpty() ) + return MonitorConfig(); + + result.oid = oid->text(); + if ( Identifier::fromString( result.oid ).isNull() ) + return MonitorConfig(); + + result.refreshInterval.minutes = updateIntervalMinutes->value(); + result.refreshInterval.seconds = updateIntervalSeconds->value(); + + result.display = stringToMonitorDisplayType( displayType->currentText() ); + + if ( result.display == MonitorConfig::Label ) { + result.useCustomFormatString = customFormatStringCheckBox->isChecked(); + if ( result.useCustomFormatString ) + result.customFormatString = customFormatString->text(); + } else + result.displayCurrentValueInline = displayCurrentValueInline->isChecked(); + + return result; +} + +void MonitorDialog::checkValues() +{ + bool currentDisplayTypeIsLabel = stringToMonitorDisplayType( displayType->currentText() ) == MonitorConfig::Label; + labelOptions->setEnabled( currentDisplayTypeIsLabel ); + chartOptions->setEnabled( !currentDisplayTypeIsLabel ); + + QString statusText; + + if ( monitorName->text().isEmpty() ) + statusText = i18n( "Please enter a name for this monitor" ); + + if ( statusText.isEmpty() && Identifier::fromString( oid->text() ).isNull() ) + statusText = i18n( "Please enter a valid name for the object identifier" ); + + if ( statusText.isEmpty() ) + statusText = " "; // a space to keep the height + + status->setText( statusText ); + + buttonOk->setEnabled( !monitorConfig().isNull() ); +} + +void MonitorDialog::testObject() +{ + // ### FIXME +} + +void MonitorDialog::browse() +{ + HostConfig host = currentHost(); + if ( host.isNull() ) + return; + + BrowseDialog dlg( host, oid->text(), this ); + if ( dlg.exec() ) + oid->setText( dlg.selectedObjectIdentifier() ); +} + +void MonitorDialog::init( const MonitorConfig &monitor ) +{ + customFormatString->setText( "%s" ); + + status->setText( " " ); + + host->clear(); + + QStringList allHosts; + for ( HostConfigMap::ConstIterator it = m_hosts.begin(); it != m_hosts.end(); ++it ) + allHosts << it.key(); + + host->insertStringList( allHosts ); + + displayType->clear(); + displayType->insertStringList( allDisplayTypes() ); + + if ( monitor.isNull() ) { + checkValues(); + return; + } + + monitorName->setText( monitor.name ); + + assert( allHosts.findIndex( monitor.host.name ) != -1 ); + + host->setCurrentItem( allHosts.findIndex( monitor.host.name ) ); + + oid->setText( monitor.oid ); + + updateIntervalMinutes->setValue( monitor.refreshInterval.minutes ); + updateIntervalSeconds->setValue( monitor.refreshInterval.seconds ); + + displayType->setCurrentItem( allDisplayTypes().findIndex( monitorDisplayTypeToString( monitor.display ) ) ); + + customFormatStringCheckBox->setChecked( monitor.useCustomFormatString ); + customFormatString->setEnabled( monitor.useCustomFormatString ); + + if ( monitor.useCustomFormatString ) + customFormatString->setText( monitor.customFormatString ); + + displayCurrentValueInline->setChecked( monitor.displayCurrentValueInline ); + + checkValues(); +} + +HostConfig MonitorDialog::currentHost() const +{ + HostConfigMap::ConstIterator hostIt = m_hosts.find( host->currentText() ); + if ( hostIt == m_hosts.end() ) + return HostConfig(); + + return *hostIt; +} + +#include "monitordialog.moc" +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/monitordialog.h b/ksim/monitors/snmp/monitordialog.h new file mode 100644 index 0000000..0f22d33 --- /dev/null +++ b/ksim/monitors/snmp/monitordialog.h @@ -0,0 +1,60 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef MONITORDIALOG_H +#define MONITORDIALOG_H + +#include "monitordialogbase.h" +#include "monitorconfig.h" + +namespace KSim +{ + +namespace Snmp +{ + +class MonitorDialog : public MonitorDialogBase +{ + Q_OBJECT +public: + MonitorDialog( const HostConfigMap &hosts, QWidget *parent, const char *name = 0 ); + MonitorDialog( const MonitorConfig &monitor, const HostConfigMap &hosts, QWidget *parent, const char *name = 0 ); + + MonitorConfig monitorConfig() const; + +protected: + virtual void checkValues(); + virtual void testObject(); + virtual void browse(); + +private: + void init( const MonitorConfig &monitor = MonitorConfig() ); + + HostConfig currentHost() const; + + HostConfigMap m_hosts; +}; + +} + +} + +#endif // MONITORDIALOG_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/monitordialogbase.ui b/ksim/monitors/snmp/monitordialogbase.ui new file mode 100644 index 0000000..13d6b06 --- /dev/null +++ b/ksim/monitors/snmp/monitordialogbase.ui @@ -0,0 +1,440 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>KSim::Snmp::MonitorDialogBase</class> +<widget class="KDialog"> + <property name="name"> + <cstring>MonitorDialogBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>725</width> + <height>597</height> + </rect> + </property> + <property name="caption"> + <string>Configure Monitor</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>textLabel5</cstring> + </property> + <property name="text"> + <string>Display type:</string> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>Update interval:</string> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Object identifier:</string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="text"> + <string>Name:</string> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel1_3</cstring> + </property> + <property name="text"> + <string>Host:</string> + </property> + </widget> + <widget class="QGroupBox" row="5" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>labelOptions</cstring> + </property> + <property name="title"> + <string>Options for Label</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox" row="0" column="0"> + <property name="name"> + <cstring>customFormatStringCheckBox</cstring> + </property> + <property name="text"> + <string>Use custom format string:</string> + </property> + </widget> + <widget class="QLineEdit" row="0" column="1"> + <property name="name"> + <cstring>customFormatString</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + <widget class="QLabel" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>textLabel1_4</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>The text in the edit box is what is displayed except that any occurrence of <b>%s</b> will be replaced with the snmp object value and any occurrence of <b>%n</b> will be replaced with the name of this monitor (see Name input field) .</string> + </property> + <property name="alignment"> + <set>WordBreak|AlignVCenter</set> + </property> + </widget> + </grid> + </widget> + <widget class="QLayoutWidget" row="3" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QSpinBox"> + <property name="name"> + <cstring>updateIntervalMinutes</cstring> + </property> + <property name="maxValue"> + <number>60</number> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel4</cstring> + </property> + <property name="text"> + <string>minutes</string> + </property> + </widget> + <widget class="QSpinBox"> + <property name="name"> + <cstring>updateIntervalSeconds</cstring> + </property> + <property name="maxValue"> + <number>59</number> + </property> + <property name="minValue"> + <number>1</number> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>seconds</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>141</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QLayoutWidget" row="4" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QComboBox"> + <item> + <property name="text"> + <string>Chart</string> + </property> + </item> + <item> + <property name="text"> + <string>Text Label</string> + </property> + </item> + <property name="name"> + <cstring>displayType</cstring> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>271</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <spacer row="0" column="2" rowspan="1" colspan="2"> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>244</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLineEdit" row="0" column="1"> + <property name="name"> + <cstring>monitorName</cstring> + </property> + </widget> + <spacer row="1" column="2" rowspan="1" colspan="2"> + <property name="name"> + <cstring>spacer5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>210</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QComboBox" row="1" column="1"> + <property name="name"> + <cstring>host</cstring> + </property> + </widget> + <widget class="QLayoutWidget" row="9" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="Line" row="8" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>line1</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="QLabel" row="7" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>status</cstring> + </property> + <property name="text"> + <string>blehStatus</string> + </property> + </widget> + <widget class="QGroupBox" row="6" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>chartOptions</cstring> + </property> + <property name="title"> + <string>Options for Chart</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>displayCurrentValueInline</cstring> + </property> + <property name="text"> + <string>Treat data as byte transfer rate and display the current value inline</string> + </property> + </widget> + </hbox> + </widget> + <widget class="KPushButton" row="2" column="3"> + <property name="name"> + <cstring>browseButton</cstring> + </property> + <property name="text"> + <string>Browse...</string> + </property> + </widget> + <widget class="QLineEdit" row="2" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>oid</cstring> + </property> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>MonitorDialogBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>MonitorDialogBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>monitorName</sender> + <signal>textChanged(const QString&)</signal> + <receiver>MonitorDialogBase</receiver> + <slot>checkValues()</slot> + </connection> + <connection> + <sender>oid</sender> + <signal>textChanged(const QString&)</signal> + <receiver>MonitorDialogBase</receiver> + <slot>checkValues()</slot> + </connection> + <connection> + <sender>displayType</sender> + <signal>activated(const QString&)</signal> + <receiver>MonitorDialogBase</receiver> + <slot>checkValues()</slot> + </connection> + <connection> + <sender>customFormatStringCheckBox</sender> + <signal>toggled(bool)</signal> + <receiver>customFormatString</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>browseButton</sender> + <signal>clicked()</signal> + <receiver>MonitorDialogBase</receiver> + <slot>browse()</slot> + </connection> +</connections> +<tabstops> + <tabstop>monitorName</tabstop> + <tabstop>host</tabstop> + <tabstop>oid</tabstop> + <tabstop>updateIntervalMinutes</tabstop> + <tabstop>updateIntervalSeconds</tabstop> + <tabstop>displayType</tabstop> + <tabstop>buttonOk</tabstop> + <tabstop>buttonCancel</tabstop> +</tabstops> +<slots> + <slot access="protected">checkValues()</slot> + <slot access="protected">browse()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kdialog.h</includehint> + <includehint>kpushbutton.h</includehint> +</includehints> +</UI> diff --git a/ksim/monitors/snmp/pdu.cpp b/ksim/monitors/snmp/pdu.cpp new file mode 100644 index 0000000..1619086 --- /dev/null +++ b/ksim/monitors/snmp/pdu.cpp @@ -0,0 +1,98 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "pdu.h" +#include "snmp_p.h" +#include "value_p.h" + +#include <algorithm> +#include <functional> + +#include <assert.h> + +using namespace KSim::Snmp; + +PDU::PDU() + : d( 0 ) +{ +} + +PDU::PDU( int requestType ) +{ + d = SnmpLib::self()->snmp_pdu_create( requestType ); +} + +PDU::~PDU() +{ + if ( d ) + SnmpLib::self()->snmp_free_pdu( d ); +} + +void PDU::addNullVariables( const IdentifierList &oids ) +{ + std::for_each( oids.begin(), oids.end(), + std::bind1st( std::mem_fun( &PDU::addNullVariable ), this ) ); +} + +void PDU::addNullVariable( Identifier oid ) +{ + assert( d ); + SnmpLib::self()->snmp_add_null_var( d, oid.d->data, oid.d->length ); +} + +netsnmp_pdu *PDU::release() +{ + netsnmp_pdu *res = d; + d = 0; + return res; +} + +bool PDU::hasError() const +{ + if ( !d ) + return false; + + return d->errstat != SNMP_ERR_NOERROR; +} + +int PDU::errorCode() const +{ + return d->errstat; +} + +ValueMap PDU::variables() const +{ + if ( !d ) + return ValueMap(); + + ValueMap result; + + for ( variable_list *var = d->variables; var; var = var->next_variable ) { + Identifier oid( new Identifier::Data( var->name, var->name_length ) ); + Value value( new ValueImpl( var ) ); + + result.insert( oid, value ); + } + + return result; +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/pdu.h b/ksim/monitors/snmp/pdu.h new file mode 100644 index 0000000..2e648d4 --- /dev/null +++ b/ksim/monitors/snmp/pdu.h @@ -0,0 +1,60 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef PDU_H +#define PDU_H + +#include "identifier.h" +#include "snmplib.h" + +namespace KSim +{ + +namespace Snmp +{ + +class PDU +{ +public: + PDU(); + PDU( int requestType ); + ~PDU(); + + void addNullVariables( const IdentifierList &oids ); + void addNullVariable( Identifier oid ); + + netsnmp_pdu **operator&() { return &d; } + + netsnmp_pdu *release(); + + bool hasError() const; + int errorCode() const; + + ValueMap variables() const; + +private: + netsnmp_pdu *d; +}; + +} +} + +#endif // PDU_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/plugin.cpp b/ksim/monitors/snmp/plugin.cpp new file mode 100644 index 0000000..90683a2 --- /dev/null +++ b/ksim/monitors/snmp/plugin.cpp @@ -0,0 +1,52 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "plugin.h" +#include "view.h" +#include "configpage.h" + +using namespace KSim::Snmp; + +KSIM_INIT_PLUGIN( Plugin ); + +Plugin::Plugin( const char *name ) + : KSim::PluginObject( name ) +{ +} + +Plugin::~Plugin() +{ +} + +KSim::PluginView *Plugin::createView( const char *name ) +{ + return new View( this, name ); +} + +KSim::PluginPage *Plugin::createConfigPage( const char *name ) +{ + return new ConfigPage( this, name ); +} + +void Plugin::showAbout() +{ +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/plugin.h b/ksim/monitors/snmp/plugin.h new file mode 100644 index 0000000..3e0fb66 --- /dev/null +++ b/ksim/monitors/snmp/plugin.h @@ -0,0 +1,49 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KSIM_PLUGIN_H +#define KSIM_PLUGIN_H + +#include <pluginmodule.h> + +namespace KSim +{ + +namespace Snmp +{ + +class Plugin : public KSim::PluginObject +{ +public: + Plugin( const char *name ); + ~Plugin(); + + virtual KSim::PluginView *createView( const char *name ); + virtual KSim::PluginPage *createConfigPage( const char *name ); + + virtual void showAbout(); +}; + +} + +} + +#endif // KSIM_PLUGIN_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/probedialog.cpp b/ksim/monitors/snmp/probedialog.cpp new file mode 100644 index 0000000..d45db6b --- /dev/null +++ b/ksim/monitors/snmp/probedialog.cpp @@ -0,0 +1,117 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "probedialog.h" +#include "monitor.h" + +#include <qtimer.h> + +#include <klocale.h> +#include <kdebug.h> + +using namespace KSim::Snmp; + +static const char * const probeIdentifiers[] = +{ + "system.sysDescr.0", + "system.sysName.0", + "system.sysUpTime.0", + "system.sysContact.0", + "system.sysObjectID.0", + ".1.3.6.1.2.1.25.1.1.0", + 0 +}; + +ProbeDialog::ProbeDialog( const HostConfig &hostConfig, QWidget *parent, const char *name ) + : KProgressDialog( parent, name, i18n( "SNMP Host Probe" ), QString::null, true /* modal */ ), + m_host( hostConfig ), m_currentMonitor( 0 ), m_canceled( false ) +{ + setLabel( i18n( "Probing for common object identifiers..." ) ); + + for ( uint i = 0; probeIdentifiers[ i ]; ++i ) { + Identifier id = Identifier::fromString( probeIdentifiers[ i ] ); + if ( !id.isNull() ) + m_probeOIDs << id; + } + + progressBar()->setTotalSteps( m_probeOIDs.count() ); + + setAutoClose( false ); + + nextProbe(); +} + +void ProbeDialog::done( int code ) +{ + if ( code == QDialog::Rejected && m_currentMonitor ) { + setLabel( "Probe aborted. Waiting for job to finish..." ); + m_canceled = true; + return; + } + KProgressDialog::done( code ); +} + +void ProbeDialog::probeOne() +{ + if ( m_probeOIDs.isEmpty() ) { + accept(); + return; + } + + Identifier oid = m_probeOIDs.pop(); + + delete m_currentMonitor; + m_currentMonitor = new Monitor( m_host, oid, 0 /* no refresh */, this ); + + connect( m_currentMonitor, SIGNAL( newData( const Identifier &, const Value & ) ), + this, SLOT( probeResult( const Identifier &, const Value & ) ) ); + connect( m_currentMonitor, SIGNAL( error( const Identifier &, const ErrorInfo & ) ), + this, SLOT( probeError( const Identifier &, const ErrorInfo & ) ) ); +} + +void ProbeDialog::probeResult( const Identifier &oid, const Value &value ) +{ + if ( !m_canceled ) + m_results << ProbeResult( oid, value ); + + nextProbe(); +} + +void ProbeDialog::probeError( const Identifier &oid, const ErrorInfo &errorInfo ) +{ + if ( !m_canceled ) + m_results << ProbeResult( oid, errorInfo ); + + nextProbe(); +} + +void ProbeDialog::nextProbe() +{ + progressBar()->setProgress( progressBar()->totalSteps() - m_probeOIDs.count() ); + + if ( m_canceled ) + KProgressDialog::done( QDialog::Rejected ); + else + QTimer::singleShot( 0, this, SLOT( probeOne() ) ); +} + +#include "probedialog.moc" + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/probedialog.h b/ksim/monitors/snmp/probedialog.h new file mode 100644 index 0000000..47a5fb0 --- /dev/null +++ b/ksim/monitors/snmp/probedialog.h @@ -0,0 +1,87 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef PROBEDIALOG_H +#define PROBEDIALOG_H + +#include <qvaluestack.h> + +#include <kprogress.h> + +#include "hostconfig.h" +#include "identifier.h" + +namespace KSim +{ + +namespace Snmp +{ + +class Monitor; + +class ProbeDialog : public KProgressDialog +{ + Q_OBJECT +public: + ProbeDialog( const HostConfig &hostConfig, QWidget *parent, const char *name = 0 ); + + struct ProbeResult + { + ProbeResult() : success( false ) {} + ProbeResult( const Identifier &_oid, const Value &_value ) + : oid( _oid ), value( _value ), success( true ) + {} + ProbeResult( const Identifier &_oid, const ErrorInfo &_errorInfo ) + : oid( _oid ), success( false ), errorInfo( _errorInfo ) + {} + + Identifier oid; + Value value; + bool success; + ErrorInfo errorInfo; + }; + typedef QValueList<ProbeResult> ProbeResultList; + + ProbeResultList probeResults() const { return m_results; } + +protected: + virtual void done( int code ); + +private slots: + void probeOne(); + void probeResult( const Identifier &oid, const Value &value ); + void probeError( const Identifier &oid, const ErrorInfo &errorInfo ); + +private: + void nextProbe(); + + HostConfig m_host; + QValueStack<Identifier> m_probeOIDs; + Monitor *m_currentMonitor; + + ProbeResultList m_results; + bool m_canceled; +}; + +} +} + +#endif // PROBEDIALOG_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/proberesultdialog.cpp b/ksim/monitors/snmp/proberesultdialog.cpp new file mode 100644 index 0000000..641f12e --- /dev/null +++ b/ksim/monitors/snmp/proberesultdialog.cpp @@ -0,0 +1,55 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "proberesultdialog.h" + +#include <qlabel.h> + +#include <klocale.h> +#include <klistview.h> + +using namespace KSim::Snmp; + +ProbeResultDialog::ProbeResultDialog( const HostConfig &hostConfig, const ProbeDialog::ProbeResultList &probeResults, + QWidget *parent, const char *name ) + : ProbeResultDialogBase( parent, name ) +{ + info->setText( i18n( "Results of scanning host %1:" ).arg( hostConfig.name ) ); + + for ( ProbeDialog::ProbeResultList::ConstIterator it = probeResults.begin(); + it != probeResults.end(); ++it ) + addResultItem( *it ); +} + +void ProbeResultDialog::addResultItem( const ProbeDialog::ProbeResult &result ) +{ + QListViewItem *item = new QListViewItem( probeResultView ); + + item->setText( 0, result.oid.toString() ); + + if ( result.success ) + item->setText( 1, result.value.toString( Value::TimeTicksWithSeconds ) ); + else + item->setText( 1, QString( "ERROR: " ) + result.errorInfo.errorMessage() ); +} + +#include "proberesultdialog.moc" + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/proberesultdialog.h b/ksim/monitors/snmp/proberesultdialog.h new file mode 100644 index 0000000..9ba3523 --- /dev/null +++ b/ksim/monitors/snmp/proberesultdialog.h @@ -0,0 +1,49 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef PROBERESULTDIALOG_H +#define PROBERESULTDIALOG_H + +#include "proberesultdialogbase.h" + +#include "probedialog.h" + +namespace KSim +{ + +namespace Snmp +{ + +class ProbeResultDialog : public ProbeResultDialogBase +{ + Q_OBJECT +public: + ProbeResultDialog( const HostConfig &hostConfig, const ProbeDialog::ProbeResultList &probeResults, + QWidget *parent, const char *name = 0 ); + +private: + void addResultItem( const ProbeDialog::ProbeResult &result ); +}; + +} + +} +#endif // PROBERESULTDIALOG_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/proberesultdialogbase.ui b/ksim/monitors/snmp/proberesultdialogbase.ui new file mode 100644 index 0000000..01b0c70 --- /dev/null +++ b/ksim/monitors/snmp/proberesultdialogbase.ui @@ -0,0 +1,124 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>KSim::Snmp::ProbeResultDialogBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>ProbeResultDialogBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>501</width> + <height>321</height> + </rect> + </property> + <property name="caption"> + <string>Probe Results</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>info</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="KListView"> + <column> + <property name="text"> + <string>Object</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Value</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>probeResultView</cstring> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>ProbeResultDialogBase</receiver> + <slot>accept()</slot> + </connection> +</connections> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klistview.h</includehint> +</includehints> +</UI> diff --git a/ksim/monitors/snmp/session.cpp b/ksim/monitors/snmp/session.cpp new file mode 100644 index 0000000..d7de283 --- /dev/null +++ b/ksim/monitors/snmp/session.cpp @@ -0,0 +1,283 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "session.h" +#include "snmp.h" +#include "snmp_p.h" +#include "snmplib.h" +#include "pdu.h" + +#include <assert.h> + +using namespace KSim::Snmp; + +// ### clean me up +struct Session::Data +{ + Data() : session( 0 ) {} + + netsnmp_session defaultSession; + netsnmp_session *session; + + bool initialized; + + HostConfig source; + + QCString host; + QCString community; + QCString securityName; + QCString authPassPhrase; + QCString privPassPhrase; +}; + +Session::Session( const HostConfig &source ) +{ + d = new Data; + d->initialized = false; + + d->source = source; + + // unicode madness + d->host = source.name.ascii(); + d->community = source.community.ascii(); + d->securityName = source.securityName.ascii(); + d->authPassPhrase = source.authentication.key.ascii(); + d->privPassPhrase = source.privacy.key.ascii(); + + SnmpLib::self()->snmp_sess_init( &d->defaultSession ); +} + +bool Session::snmpGetInternal( int getType, const IdentifierList &identifiers, ValueMap &variables, ErrorInfo *error ) +{ + if ( !d->initialized && !initialize( error ) ) + return false; + + bool result = false; + + if ( getType != SNMP_MSG_GETNEXT && d->session ) { + SnmpLib::self()->snmp_close( d->session ); + d->session = 0; + } + + if ( getType != SNMP_MSG_GETNEXT || + !d->session ) { + + if ( ( d->session = SnmpLib::self()->snmp_open( &d->defaultSession ) ) == 0 ) { + if ( error ) + *error = ErrorInfo( sessionErrorCode( d->defaultSession ) ); + return false; + } + } + + PDU request( getType ); + PDU response; + + request.addNullVariables( identifiers ); + + int status = SnmpLib::self()->snmp_synch_response( d->session, request.release(), &response ); + + if ( status == STAT_SUCCESS ) { + + if ( response.hasError() ) { + + if ( error ) + *error = ErrorInfo( response.errorCode() ); + + } else { + + variables = response.variables(); + result = true; + + if ( error ) + *error = ErrorInfo( ErrorInfo::NoError ); + } + + } else if ( status == STAT_TIMEOUT ) { + + if ( error ) + *error = ErrorInfo( ErrorInfo::ErrTimeout ); + + } else { + + if ( error ) + *error = ErrorInfo( sessionErrorCode( *d->session ) ); + + } + + if ( getType != SNMP_MSG_GETNEXT ) { + SnmpLib::self()->snmp_close( d->session ); + d->session = 0; + } + + return result; + +} + +bool Session::initialize( ErrorInfo *error ) +{ + if ( d->initialized ) { + if ( error ) + *error = ErrorInfo( ErrorInfo::NoError ); + return true; + } + + HostConfig &source = d->source; + + d->defaultSession.peername = d->host.data(); + + d->defaultSession.version = snmpVersionToSnmpLibConstant( source.version ); + + if ( source.version != SnmpVersion3 ) { + d->defaultSession.community = reinterpret_cast<u_char *>( d->community.data() ); + d->defaultSession.community_len = d->community.length(); + d->initialized = true; + return true; + } + + d->defaultSession.securityName = d->securityName.data(); + d->defaultSession.securityNameLen = d->securityName.length(); + + d->defaultSession.securityLevel = snmpSecurityLevelToSnmpLibConstant( source.securityLevel ); + + // ### clean me up + switch ( source.authentication.protocol ) { + case MD5Auth: { + d->defaultSession.securityAuthProto = usmHMACMD5AuthProtocol; + d->defaultSession.securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN; + break; + } + case SHA1Auth: { + d->defaultSession.securityAuthProto = usmHMACSHA1AuthProtocol; + d->defaultSession.securityAuthProtoLen = USM_AUTH_PROTO_SHA_LEN; + break; + } + default: assert( false ); + } + + d->defaultSession.securityAuthKeyLen = USM_AUTH_KU_LEN; + + int result; + if ( ( result = SnmpLib::self()->generate_Ku( d->defaultSession.securityAuthProto, d->defaultSession.securityAuthProtoLen, + reinterpret_cast<uchar *>( d->authPassPhrase.data() ), d->authPassPhrase.length(), + d->defaultSession.securityAuthKey, &d->defaultSession.securityAuthKeyLen ) ) + != SNMPERR_SUCCESS ) { + + if ( error ) + *error = ErrorInfo( result ); + + return false; + } + + switch ( source.privacy.protocol ) { + case DESPrivacy: { + d->defaultSession.securityPrivProto = usmDESPrivProtocol; + d->defaultSession.securityPrivProtoLen = USM_PRIV_PROTO_DES_LEN; + break; + } + default: assert( false ); + } + + d->defaultSession.securityPrivKeyLen = USM_PRIV_KU_LEN; + + if ( ( result = SnmpLib::self()->generate_Ku( d->defaultSession.securityAuthProto, d->defaultSession.securityAuthProtoLen, + reinterpret_cast<u_char *>( d->privPassPhrase.data() ), d->privPassPhrase.length(), + d->defaultSession.securityPrivKey, &d->defaultSession.securityPrivKeyLen ) ) + != SNMPERR_SUCCESS ) { + + if ( error ) + *error = ErrorInfo( result ); + + + return false; + } + + d->initialized = true; + return true; +} + +bool Session::snmpGet( const QString &identifier, Value &value, ErrorInfo *error ) +{ + bool ok = false; + Identifier oid = Identifier::fromString( identifier, &ok ); + if ( !ok ) { + if ( error ) + *error = ErrorInfo( ErrorInfo::ErrUnknownOID ); + return false; + } + + return snmpGet( oid, value, error ); +} + +bool Session::snmpGet( const Identifier &identifier, Value &value, ErrorInfo *error ) +{ + ValueMap vars; + IdentifierList ids; + + ids << identifier; + + if ( !snmpGet( ids, vars, error ) ) + return false; + + ValueMap::ConstIterator it = vars.find( identifier ); + if ( it == vars.end() ) { + if ( error ) + *error = ErrorInfo( ErrorInfo::ErrMissingVariables ); + return false; + } + + value = it.data(); + + return true; +} + +bool Session::snmpGet( const IdentifierList &identifiers, ValueMap &variables, ErrorInfo *error ) +{ + return snmpGetInternal( SNMP_MSG_GET, identifiers, variables, error ); +} + +bool Session::snmpGetNext( Identifier &identifier, Value &value, ErrorInfo *error ) +{ + ValueMap vars; + IdentifierList ids; + + ids << identifier; + + if ( !snmpGetInternal( SNMP_MSG_GETNEXT, ids, vars, error ) ) + return false; + + assert( vars.count() == 1 ); + + ValueMap::ConstIterator it = vars.begin(); + identifier = it.key(); + value = it.data(); + + return true; + +} + +Session::~Session() +{ + if ( d->session ) + SnmpLib::self()->snmp_close( d->session ); + delete d; +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/session.h b/ksim/monitors/snmp/session.h new file mode 100644 index 0000000..0d5cda3 --- /dev/null +++ b/ksim/monitors/snmp/session.h @@ -0,0 +1,64 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef SESSION_H +#define SESSION_H + +#include "hostconfig.h" +#include "value.h" +#include "identifier.h" + +namespace KSim +{ + +namespace Snmp +{ + +class Session +{ +public: + struct Data; + + Session( const HostConfig &snmpHostConfig ); + ~Session(); + + bool snmpGet( const QString &identifier, Value &value, ErrorInfo *error = 0 ); + bool snmpGet( const Identifier &identifier, Value &value, ErrorInfo *error = 0 ); + bool snmpGet( const IdentifierList &identifiers, ValueMap &variables, ErrorInfo *error = 0 ); + + bool snmpGetNext( Identifier &identifier, Value &value, ErrorInfo *error = 0 ); + +private: + Data *d; + + bool snmpGetInternal( int getType, const IdentifierList &identifiers, ValueMap &variables, ErrorInfo *error = 0 ); + + bool initialize( ErrorInfo *error ); + + Session( const Session & ); + Session &operator=( const Session & ); +}; + +} + +} + +#endif // SESSION_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/snmp.cpp b/ksim/monitors/snmp/snmp.cpp new file mode 100644 index 0000000..80fb073 --- /dev/null +++ b/ksim/monitors/snmp/snmp.cpp @@ -0,0 +1,320 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "snmp.h" +#include "snmp_p.h" +#include "snmplib.h" +#include "value_p.h" + +#include <qmutex.h> + +#include <assert.h> + +using namespace KSim::Snmp; + +static const struct EnumStringMapInfo +{ + const int enumValue; + const char *stringValue; + const char snmpLibConstant; +} snmpVersionStrings[ 4 ] = { + { SnmpVersion1, "1", SNMP_VERSION_1 }, + { SnmpVersion2c, "2c", SNMP_VERSION_2c }, + { SnmpVersion3, "3", SNMP_VERSION_3 }, + { 0, 0, 0 } +}, securityLevelStrings[ 4 ] = { + { NoAuthPriv, "NoAuthPriv", SNMP_SEC_LEVEL_NOAUTH }, + { AuthNoPriv, "AuthNoPriv", SNMP_SEC_LEVEL_AUTHNOPRIV }, + { AuthPriv, "AuthPriv", SNMP_SEC_LEVEL_AUTHPRIV }, + { 0, 0, 0 } +}, authenticationProtocolStrings[ 3 ] = { + { MD5Auth, "MD5", 0 }, + { SHA1Auth, "SHA1", 0 }, + { 0, 0, 0 } +}, privacyProtocolStrings[ 2 ] = { + { DESPrivacy, "DES", 0 }, + { 0, 0, 0 } +}; + +static QStringList allStrings( const EnumStringMapInfo *array ) +{ + QStringList result; + for ( uint i = 0; array[ i ].stringValue; ++i ) + result << QString::fromLatin1( array[ i ].stringValue ); + return result; +} + +static QString enumToString( const EnumStringMapInfo *array, int value ) +{ + for ( uint i = 0; array[ i ].stringValue; ++i ) + if ( array[ i ].enumValue == value ) + return QString::fromLatin1( array[ i ].stringValue ); + + assert( false ); + return QString::null; +} + +static int stringToEnum( const EnumStringMapInfo *array, QString string, bool *ok ) +{ + string = string.lower(); + uint i; + for ( i = 0; array[ i ].stringValue; ++i ) + if ( QString::fromLatin1( array[ i ].stringValue ).lower() == string ) { + if ( ok ) *ok = true; + return array[ i ].enumValue; + } + + if ( ok ) + *ok = false; + + // something.. + return array[ 0 ].enumValue; +} + +static int extractSnmpLibConstant( const EnumStringMapInfo *array, int enumValue ) +{ + for ( uint i = 0; array[ i ].stringValue; ++i ) + if ( array[ i ].enumValue == enumValue ) + return array[ i ].snmpLibConstant; + + assert( false ); + return 0; +} + +int KSim::Snmp::snmpVersionToSnmpLibConstant( SnmpVersion version ) +{ + return extractSnmpLibConstant( snmpVersionStrings, version ); +} + +int KSim::Snmp::snmpSecurityLevelToSnmpLibConstant( SecurityLevel secLevel ) +{ + return extractSnmpLibConstant( securityLevelStrings, secLevel ); +} + +QStringList KSim::Snmp::allSnmpVersions() +{ + return allStrings( snmpVersionStrings ); +} + +QString KSim::Snmp::snmpVersionToString( SnmpVersion version ) +{ + return enumToString( snmpVersionStrings, version ); +} + +SnmpVersion KSim::Snmp::stringToSnmpVersion( QString string, bool *ok ) +{ + return static_cast<SnmpVersion>( stringToEnum( snmpVersionStrings, string, ok ) ); +} + +QStringList KSim::Snmp::allSecurityLevels() +{ + return allStrings( securityLevelStrings ); +} + +QString KSim::Snmp::securityLevelToString( SecurityLevel level ) +{ + return enumToString( securityLevelStrings, level ); +} + +SecurityLevel KSim::Snmp::stringToSecurityLevel( QString string, bool *ok ) +{ + return static_cast<SecurityLevel>( stringToEnum( securityLevelStrings, string, ok ) ); +} + +QStringList KSim::Snmp::allAuthenticationProtocols() +{ + return allStrings( authenticationProtocolStrings ); +} + +QString KSim::Snmp::authenticationProtocolToString( AuthenticationProtocol proto ) +{ + return enumToString( authenticationProtocolStrings, proto ); +} + +AuthenticationProtocol KSim::Snmp::stringToAuthenticationProtocol( QString string, bool *ok ) +{ + return static_cast<AuthenticationProtocol>( stringToEnum( authenticationProtocolStrings, string, ok ) ); +} + +QStringList KSim::Snmp::allPrivacyProtocols() +{ + return allStrings( privacyProtocolStrings ); +} + +QString KSim::Snmp::privacyProtocolToString( PrivacyProtocol proto ) +{ + return enumToString( privacyProtocolStrings, proto ); +} + +PrivacyProtocol KSim::Snmp::stringToPrivacyProtocol( QString string, bool *ok ) +{ + return static_cast<PrivacyProtocol>( stringToEnum( privacyProtocolStrings, string, ok ) ); +} + +// I'm afraid of them changing the order in the error constants or the like, hence the +// slow list instead of a fast lookup table +static const struct ErrorMapInfo +{ + int errorCode; + ErrorInfo::ErrorType enumValue; +} errorMap[] = +{ + // API Errors + { SNMPERR_GENERR, ErrorInfo::ErrGeneric }, + { SNMPERR_BAD_LOCPORT, ErrorInfo::ErrInvalidLocalPort }, + { SNMPERR_BAD_ADDRESS, ErrorInfo::ErrUnknownHost }, + { SNMPERR_BAD_SESSION, ErrorInfo::ErrUnknownSession }, + { SNMPERR_TOO_LONG, ErrorInfo::ErrTooLong }, + { SNMPERR_NO_SOCKET, ErrorInfo::ErrNoSocket }, + { SNMPERR_V2_IN_V1, ErrorInfo::ErrCannotSendV2PDUOnV1Session }, + { SNMPERR_V1_IN_V2, ErrorInfo::ErrCannotSendV1PDUOnV2Session }, + { SNMPERR_BAD_REPEATERS, ErrorInfo::ErrBadValueForNonRepeaters }, + { SNMPERR_BAD_REPETITIONS, ErrorInfo::ErrBadValueForMaxRepetitions }, + { SNMPERR_BAD_ASN1_BUILD, ErrorInfo::ErrBuildingASN1Representation }, + { SNMPERR_BAD_SENDTO, ErrorInfo::ErrFailureInSendto }, + { SNMPERR_BAD_PARSE, ErrorInfo::ErrBadParseOfASN1Type }, + { SNMPERR_BAD_VERSION, ErrorInfo::ErrBadVersion }, + { SNMPERR_BAD_SRC_PARTY, ErrorInfo::ErrBadSourceParty }, + { SNMPERR_BAD_DST_PARTY, ErrorInfo::ErrBadDestinationParty }, + { SNMPERR_BAD_CONTEXT, ErrorInfo::ErrBadContext }, + { SNMPERR_BAD_COMMUNITY, ErrorInfo::ErrBadCommunity }, + { SNMPERR_NOAUTH_DESPRIV, ErrorInfo::ErrCannotSendNoAuthDesPriv }, + { SNMPERR_BAD_ACL, ErrorInfo::ErrBadACL }, + { SNMPERR_BAD_PARTY, ErrorInfo::ErrBadParty }, + { SNMPERR_ABORT, ErrorInfo::ErrSessionAbortFailure }, + { SNMPERR_UNKNOWN_PDU, ErrorInfo::ErrUnknownPDU }, + { SNMPERR_TIMEOUT, ErrorInfo::ErrTimeout }, + { SNMPERR_BAD_RECVFROM, ErrorInfo::ErrFailureInRecvfrom }, + { SNMPERR_BAD_ENG_ID, ErrorInfo::ErrUnableToDetermineContextEngineID }, + { SNMPERR_BAD_SEC_NAME, ErrorInfo::ErrNoSecurityName }, + { SNMPERR_BAD_SEC_LEVEL, ErrorInfo::ErrUnableToDetermineSecurityLevel }, + { SNMPERR_ASN_PARSE_ERR, ErrorInfo::ErrASN1ParseError }, + { SNMPERR_UNKNOWN_SEC_MODEL, ErrorInfo::ErrUnknownSecurityModel }, + { SNMPERR_INVALID_MSG, ErrorInfo::ErrInvalidMessage }, + { SNMPERR_UNKNOWN_ENG_ID, ErrorInfo::ErrUnknownEngineID }, + { SNMPERR_UNKNOWN_USER_NAME, ErrorInfo::ErrUnknownUserName }, + { SNMPERR_UNSUPPORTED_SEC_LEVEL, ErrorInfo::ErrUnsupportedSecurityLevel }, + { SNMPERR_AUTHENTICATION_FAILURE, ErrorInfo::ErrAuthenticationFailure }, + { SNMPERR_NOT_IN_TIME_WINDOW, ErrorInfo::ErrNotInTimeWindow }, + { SNMPERR_DECRYPTION_ERR, ErrorInfo::ErrDecryptionError }, + { SNMPERR_SC_GENERAL_FAILURE, ErrorInfo::ErrSCAPIGeneralFailure }, + { SNMPERR_SC_NOT_CONFIGURED, ErrorInfo::ErrSCAPISubSystemNotConfigured }, + { SNMPERR_KT_NOT_AVAILABLE, ErrorInfo::ErrNoKeyTools }, + { SNMPERR_UNKNOWN_REPORT, ErrorInfo::ErrUnknownReport }, + { SNMPERR_USM_GENERICERROR, ErrorInfo::ErrUSMGenericError }, + { SNMPERR_USM_UNKNOWNSECURITYNAME, ErrorInfo::ErrUSMUnknownSecurityName }, + { SNMPERR_USM_UNSUPPORTEDSECURITYLEVEL, ErrorInfo::ErrUSMUnsupportedSecurityLevel }, + { SNMPERR_USM_ENCRYPTIONERROR, ErrorInfo::ErrUSMEncryptionError }, + { SNMPERR_USM_AUTHENTICATIONFAILURE, ErrorInfo::ErrUSMAuthenticationFailure }, + { SNMPERR_USM_PARSEERROR, ErrorInfo::ErrUSMParseError }, + { SNMPERR_USM_UNKNOWNENGINEID, ErrorInfo::ErrUSMUnknownEngineID }, + { SNMPERR_USM_NOTINTIMEWINDOW, ErrorInfo::ErrUSMNotInTimeWindow }, + { SNMPERR_USM_DECRYPTIONERROR, ErrorInfo::ErrUSMDecryptionError }, + { SNMPERR_NOMIB, ErrorInfo::ErrMIBNotInitialized }, + { SNMPERR_RANGE, ErrorInfo::ErrValueOutOfRange }, + { SNMPERR_MAX_SUBID, ErrorInfo::ErrSubIdOutOfRange }, + { SNMPERR_BAD_SUBID, ErrorInfo::ErrBadSubIdInOID }, + { SNMPERR_LONG_OID, ErrorInfo::ErrOIDTooLong }, + { SNMPERR_BAD_NAME, ErrorInfo::ErrBadValueName }, + { SNMPERR_VALUE, ErrorInfo::ErrBadValueNotation }, + { SNMPERR_UNKNOWN_OBJID, ErrorInfo::ErrUnknownOID }, + { SNMPERR_NULL_PDU, ErrorInfo::ErrNullPDU }, + { SNMPERR_NO_VARS, ErrorInfo::ErrMissingVariables }, + { SNMPERR_VAR_TYPE, ErrorInfo::ErrBadVariableType }, + { SNMPERR_MALLOC, ErrorInfo::ErrOOM }, + { SNMPERR_KRB5, ErrorInfo::ErrKerberos }, + + // PDU response errors + { SNMP_ERR_TOOBIG, ErrorInfo::ErrResponseTooLarge }, + { SNMP_ERR_NOSUCHNAME, ErrorInfo::ErrNoSuchVariable }, + { SNMP_ERR_BADVALUE, ErrorInfo::ErrBadValue }, + { SNMP_ERR_READONLY, ErrorInfo::ErrReadOnly }, + { SNMP_ERR_GENERR, ErrorInfo::ErrGeneric }, + { SNMP_ERR_NOACCESS, ErrorInfo::ErrNoAccess }, + { SNMP_ERR_WRONGTYPE, ErrorInfo::ErrWrongType }, + { SNMP_ERR_WRONGLENGTH, ErrorInfo::ErrWrongLength }, + { SNMP_ERR_WRONGENCODING, ErrorInfo::ErrWrongEncoding }, + { SNMP_ERR_WRONGVALUE, ErrorInfo::ErrWrongValue }, + { SNMP_ERR_NOCREATION, ErrorInfo::ErrNoCreation }, + { SNMP_ERR_INCONSISTENTVALUE, ErrorInfo::ErrInconsistentValue }, + { SNMP_ERR_RESOURCEUNAVAILABLE, ErrorInfo::ErrResourceUnavailable }, + { SNMP_ERR_COMMITFAILED, ErrorInfo::ErrCommitFailed }, + { SNMP_ERR_UNDOFAILED, ErrorInfo::ErrUndoFailed }, + { SNMP_ERR_AUTHORIZATIONERROR, ErrorInfo::ErrAuthorizationFailed }, + { SNMP_ERR_NOTWRITABLE, ErrorInfo::ErrNotWritable }, + { SNMP_ERR_INCONSISTENTNAME, ErrorInfo::ErrInconsistentName }, + + { SNMPERR_SUCCESS, ErrorInfo::NoError } +}; + +ErrorInfo::ErrorType KSim::Snmp::convertSnmpLibErrorToErrorInfo( int error ) +{ + for ( uint i = 0; errorMap[ i ].errorCode != SNMPERR_SUCCESS; ++i ) + if ( errorMap[ i ].errorCode == error ) + return errorMap[ i ].enumValue; + return ErrorInfo::ErrUnknown; +} + +int KSim::Snmp::convertErrorInfoToSnmpLibError( ErrorInfo::ErrorType error ) +{ + for ( uint i = 0; errorMap[ i ].errorCode != SNMPERR_SUCCESS; ++i ) + if ( errorMap[ i ].enumValue == error ) + return errorMap[ i ].errorCode; + assert( false ); + return SNMPERR_SUCCESS; +} + +int KSim::Snmp::sessionErrorCode( netsnmp_session &session ) +{ + int errorCode = 0; + SnmpLib::self()->snmp_error( &session, 0, &errorCode, 0 ); + return errorCode; +} + +static QString messageForErrorCode( int errorCode ) +{ + if ( errorCode >= SNMPERR_MAX && errorCode <= SNMPERR_GENERR ) + return QString::fromLatin1( SnmpLib::self()->snmp_api_errstring( errorCode ) ); + if ( errorCode >= SNMP_ERR_NOERROR && errorCode <= MAX_SNMP_ERR ) + return QString::fromLatin1( SnmpLib::self()->snmp_errstring( errorCode ) ); + + return QString::null; +} + +ErrorInfo::ErrorInfo() +{ + m_errorCode = NoError; +} + +ErrorInfo::ErrorInfo( int internalErrorCode ) +{ + m_errorCode = convertSnmpLibErrorToErrorInfo( internalErrorCode ); + m_errorMessage = messageForErrorCode( internalErrorCode ); +} + +ErrorInfo::ErrorInfo( ErrorType error ) +{ + m_errorCode = error; + if ( error != NoError && error != ErrUnknown ) + m_errorMessage = messageForErrorCode( convertErrorInfoToSnmpLibError( error ) ); +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/snmp.h b/ksim/monitors/snmp/snmp.h new file mode 100644 index 0000000..4710c2d --- /dev/null +++ b/ksim/monitors/snmp/snmp.h @@ -0,0 +1,165 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KSIM_SNMP_H +#define KSIM_SNMP_H + +#include <kconfigbase.h> + +#include <qmap.h> + + +namespace KSim +{ + +namespace Snmp +{ + +enum SnmpVersion { SnmpVersion1, SnmpVersion2c, SnmpVersion3, SnmpLastVersion }; +QStringList allSnmpVersions(); +QString snmpVersionToString( SnmpVersion version ); +SnmpVersion stringToSnmpVersion( QString string, bool *ok = 0 ); + +enum SecurityLevel { NoAuthPriv, AuthNoPriv, AuthPriv, LastSecurityLevel }; +QStringList allSecurityLevels(); +QString securityLevelToString( SecurityLevel level ); +SecurityLevel stringToSecurityLevel( QString string, bool *ok = 0 ); + +enum AuthenticationProtocol { MD5Auth, SHA1Auth, LastAuthenticationProtocol }; +QStringList allAuthenticationProtocols(); +QString authenticationProtocolToString( AuthenticationProtocol proto ); +AuthenticationProtocol stringToAuthenticationProtocol( QString string, bool *ok = 0 ); + +enum PrivacyProtocol { DESPrivacy }; +QStringList allPrivacyProtocols(); +QString privacyProtocolToString( PrivacyProtocol proto ); +PrivacyProtocol stringToPrivacyProtocol( QString string, bool *ok = 0 ); + +class ErrorInfo +{ +public: + enum ErrorType { + NoError = 0, + ErrUnknown, // ... if we forgot a mapping of error codes + + // api errors + ErrGeneric, + ErrInvalidLocalPort, + ErrUnknownHost, + ErrUnknownSession, + ErrTooLong, + ErrNoSocket, + ErrCannotSendV2PDUOnV1Session, + ErrCannotSendV1PDUOnV2Session, + ErrBadValueForNonRepeaters, + ErrBadValueForMaxRepetitions, + ErrBuildingASN1Representation, + ErrFailureInSendto, + ErrBadParseOfASN1Type, + ErrBadVersion, + ErrBadSourceParty, + ErrBadDestinationParty, + ErrBadContext, + ErrBadCommunity, + ErrCannotSendNoAuthDesPriv, + ErrBadACL, + ErrBadParty, + ErrSessionAbortFailure, + ErrUnknownPDU, + ErrTimeout, + ErrFailureInRecvfrom, + ErrUnableToDetermineContextEngineID, + ErrNoSecurityName, + ErrUnableToDetermineSecurityLevel, + ErrASN1ParseError, + ErrUnknownSecurityModel, + ErrInvalidMessage, + ErrUnknownEngineID, + ErrUnknownUserName, + ErrUnsupportedSecurityLevel, + ErrAuthenticationFailure, + ErrNotInTimeWindow, + ErrDecryptionError, + ErrSCAPIGeneralFailure, + ErrSCAPISubSystemNotConfigured, + ErrNoKeyTools, + ErrUnknownReport, + ErrUSMGenericError, + ErrUSMUnknownSecurityName, + ErrUSMUnsupportedSecurityLevel, + ErrUSMEncryptionError, + ErrUSMAuthenticationFailure, + ErrUSMParseError, + ErrUSMUnknownEngineID, + ErrUSMNotInTimeWindow, + ErrUSMDecryptionError, + ErrMIBNotInitialized, + ErrValueOutOfRange, + ErrSubIdOutOfRange, + ErrBadSubIdInOID, + ErrOIDTooLong, + ErrBadValueName, + ErrBadValueNotation, + ErrUnknownOID, + ErrNullPDU, + ErrMissingVariables, + ErrBadVariableType, + ErrOOM, + ErrKerberos, + + // pdu response errors + + ErrResponseTooLarge, + ErrNoSuchVariable, + ErrBadValue, + ErrReadOnly, + ErrNoAccess, + ErrWrongType, + ErrWrongLength, + ErrWrongEncoding, + ErrWrongValue, + ErrNoCreation, + ErrInconsistentValue, + ErrResourceUnavailable, + ErrCommitFailed, + ErrUndoFailed, + ErrAuthorizationFailed, + ErrNotWritable, + ErrInconsistentName + }; + + ErrorInfo(); + ErrorInfo( int internalErrorCode ); + ErrorInfo( ErrorType error ); + + ErrorType errorCode() const { return m_errorCode; } + QString errorMessage() const { return m_errorMessage; } + +private: + ErrorType m_errorCode; + QString m_errorMessage; +}; + +} + +} + +#endif // KSIMSNMP_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/snmp_p.h b/ksim/monitors/snmp/snmp_p.h new file mode 100644 index 0000000..9d96868 --- /dev/null +++ b/ksim/monitors/snmp/snmp_p.h @@ -0,0 +1,59 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef SNMP_P_H +#define SNMP_P_H + +#define HAVE_STRLCPY 1 +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/net-snmp-includes.h> + +#include "snmp.h" +#include "identifier.h" + +namespace KSim +{ + +namespace Snmp +{ + +ErrorInfo::ErrorType convertSnmpLibErrorToErrorInfo( int error ); +int convertErrorInfoToSnmpLibError( ErrorInfo::ErrorType error ); + +int snmpVersionToSnmpLibConstant( SnmpVersion version ); +int snmpSecurityLevelToSnmpLibConstant( SecurityLevel secLevel ); + +int sessionErrorCode( netsnmp_session &session ); + +struct Identifier::Data +{ + Data() : length( 0 ) {} + Data( const oid *d, size_t length ); + + oid data[ MAX_OID_LEN ]; + size_t length; +}; + +} + +} + +#endif // SNMP_P_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/snmplib.cpp b/ksim/monitors/snmp/snmplib.cpp new file mode 100644 index 0000000..a063203 --- /dev/null +++ b/ksim/monitors/snmp/snmplib.cpp @@ -0,0 +1,151 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "snmplib.h" +#include "snmp_p.h" + +#include <kstaticdeleter.h> + +using namespace KSim::Snmp; + +SnmpLib *SnmpLib::s_self; + +::KStaticDeleter<KSim::Snmp::SnmpLib> sd; + +SnmpLib::SnmpLib() +{ + m_lockHelper = new ClassLocker<SnmpLib>( &m_guard, this ); + + init_snmp( "ksim" ); +} + +SnmpLib::~SnmpLib() +{ + delete m_lockHelper; +} + +ClassLocker<SnmpLib> &SnmpLib::self() +{ + if ( !s_self ) { + static QMutex singletonGuard; + + QMutexLocker locker( &singletonGuard ); + if ( !s_self ) + sd.setObject( s_self, new SnmpLib ); + } + return *s_self->m_lockHelper; +} + +oid *SnmpLib::snmp_parse_oid( const char *name, oid *oid, size_t *length ) +{ + return ::snmp_parse_oid( name, oid, length ); +} + +int SnmpLib::netsnmp_ds_set_int( int storeid, int which, int value ) +{ + return ::netsnmp_ds_set_int( storeid, which, value ); +} + +int SnmpLib::netsnmp_ds_get_int( int storeid, int which ) +{ + return ::netsnmp_ds_get_int( storeid, which ); +} + +struct tree *SnmpLib::netsnmp_sprint_realloc_objid_tree( u_char ** buf, + size_t * buf_len, + size_t * out_len, + int allow_realloc, + int *buf_overflow, + const oid * objid, + size_t objidlen ) +{ + return ::netsnmp_sprint_realloc_objid_tree( buf, buf_len, out_len, allow_realloc, buf_overflow, objid, objidlen ); +} + +int SnmpLib::netsnmp_oid_equals( const oid *firstOid, size_t firstOidLen, const oid *secondOid, size_t secondOidLen ) +{ + return ::netsnmp_oid_equals( firstOid, firstOidLen, secondOid, secondOidLen ); +} + +int SnmpLib::snmp_oid_compare( const oid *firstOid, size_t firstOidLen, const oid *secondOid, size_t secondOidLen ) +{ + return ::snmp_oid_compare( firstOid, firstOidLen, secondOid, secondOidLen ); +} + +void SnmpLib::snmp_error( netsnmp_session *session, int *p_errno, int *p_snmp_errno, char **p_str ) +{ + ::snmp_error( session, p_errno, p_snmp_errno, p_str ); +} + +const char *SnmpLib::snmp_api_errstring( int code ) +{ + return ::snmp_api_errstring( code ); +} + +const char *SnmpLib::snmp_errstring( int code ) +{ + return ::snmp_errstring( code ); +} + +netsnmp_pdu *SnmpLib::snmp_pdu_create( int pduType ) +{ + return ::snmp_pdu_create( pduType ); +} + +void SnmpLib::snmp_free_pdu( netsnmp_pdu *pdu ) +{ + ::snmp_free_pdu( pdu ); +} + +netsnmp_variable_list *SnmpLib::snmp_add_null_var( netsnmp_pdu *pdu, oid *var, size_t varlen ) +{ + return ::snmp_add_null_var( pdu, var, varlen ); +} + +void SnmpLib::snmp_sess_init( netsnmp_session *session ) +{ + ::snmp_sess_init( session ); +} + +netsnmp_session *SnmpLib::snmp_open( netsnmp_session *session ) +{ + return ::snmp_open( session ); +} + +int SnmpLib::snmp_close( netsnmp_session *session ) +{ + return ::snmp_close( session ); +} + +int SnmpLib::snmp_synch_response( netsnmp_session *session, netsnmp_pdu *pdu, + netsnmp_pdu **response ) +{ + return ::snmp_synch_response( session, pdu, response ); +} + +int SnmpLib::generate_Ku( const oid * hashtype, u_int hashtype_len, + u_char * P, size_t pplen, + u_char * Ku, size_t * kulen ) +{ + return ::generate_Ku( hashtype, hashtype_len, P, pplen, Ku, kulen ); +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/snmplib.h b/ksim/monitors/snmp/snmplib.h new file mode 100644 index 0000000..e8b14a4 --- /dev/null +++ b/ksim/monitors/snmp/snmplib.h @@ -0,0 +1,143 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef SNMPLIB_H +#define SNMPLIB_H + +// ### REMOVEME: move snmplib somewhere else +#define HAVE_STRLCPY 1 +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/net-snmp-includes.h> + +#include <qmutex.h> + +template <class> class KStaticDeleter; + +namespace KSim +{ + +namespace Snmp +{ + +template <class T> +class ClassLocker +{ +public: + ClassLocker( QMutex *guard, T *obj ) + : m_guard( guard ), m_obj( obj ) + {} + + struct ClassLockerHelper + { + ClassLockerHelper( QMutex *guard, T *obj ) + : m_guard( guard ), m_obj( obj ), m_locked( false ) + {} + + ~ClassLockerHelper() + { + if ( m_locked ) + m_guard->unlock(); + } + + T *operator->() + { + m_guard->lock(); + m_locked = true; + return m_obj; + } + + private: + QMutex *m_guard; + T *m_obj; + bool m_locked; + }; + + ClassLockerHelper operator->() + { + return ClassLockerHelper( m_guard, m_obj ); + } + +private: + ClassLocker( const ClassLocker & ); + ClassLocker &operator=( const ClassLocker & ); + + QMutex *m_guard; + T *m_obj; +}; + +class SnmpLib +{ + friend class KStaticDeleter<SnmpLib>; +public: + + static ClassLocker<SnmpLib> &self(); + + oid *snmp_parse_oid( const char *name, oid *oid, size_t *length ); + + int netsnmp_ds_set_int( int storeid, int which, int value ); + int netsnmp_ds_get_int( int storeid, int which ); + + struct tree *netsnmp_sprint_realloc_objid_tree( u_char ** buf, + size_t * buf_len, + size_t * out_len, + int allow_realloc, + int *buf_overflow, + const oid * objid, + size_t objidlen ); + + int netsnmp_oid_equals( const oid *firstOid, size_t firstOidLen, const oid *secondOid, size_t secondOidLen ); + int snmp_oid_compare( const oid *firstOid, size_t firstOidLen, const oid *secondOid, size_t secondOidLen ); + + void snmp_error( netsnmp_session *session, int *p_errno, int *p_snmp_errno, char **p_str ); + const char *snmp_api_errstring( int code ); + const char *snmp_errstring( int code ); + + netsnmp_pdu *snmp_pdu_create( int pduType ); + void snmp_free_pdu( netsnmp_pdu *pdu ); + netsnmp_variable_list *snmp_add_null_var( netsnmp_pdu *pdu, oid *var, size_t varlen ); + + void snmp_sess_init( netsnmp_session *session ); + netsnmp_session *snmp_open( netsnmp_session *session ); + int snmp_close( netsnmp_session *session ); + + int snmp_synch_response( netsnmp_session *session, netsnmp_pdu *pdu, + netsnmp_pdu **response ); + + int generate_Ku( const oid * hashtype, u_int hashtype_len, + u_char * P, size_t pplen, + u_char * Ku, size_t * kulen ); + +private: + SnmpLib(); + ~SnmpLib(); + + QMutex m_guard; + ClassLocker<SnmpLib> *m_lockHelper; + + static SnmpLib *s_self; +}; + +} +} + + +#endif // SNMPLIB_H +/* vim: et sw=4 ts=4 + */ + diff --git a/ksim/monitors/snmp/value.cpp b/ksim/monitors/snmp/value.cpp new file mode 100644 index 0000000..fe42a08 --- /dev/null +++ b/ksim/monitors/snmp/value.cpp @@ -0,0 +1,333 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "value.h" +#include "value_p.h" +#include "snmp_p.h" + +#include <qvariant.h> + +#include <klocale.h> + +#include <assert.h> + +using namespace KSim::Snmp; + +ValueImpl::ValueImpl( variable_list *var ) +{ + switch ( var->type ) { + case ASN_INTEGER: { + type = Value::Int; + data = QVariant( static_cast<int>( *var->val.integer ) ); + break; + } + case ASN_UINTEGER: { + type = Value::UInt; + data = QVariant( static_cast<uint>( *var->val.integer ) ); + break; + } + case ASN_OCTET_STR: { + type = Value::ByteArray; + QByteArray d; + d.setRawData( reinterpret_cast<char *>( var->val.string ), var->val_len ); + QByteArray copy = d; + copy.detach(); + d.resetRawData( reinterpret_cast<char *>( var->val.string ), var->val_len ); + data = QVariant( copy ); + break; + } + case ASN_NULL: { + type = Value::Null; + break; + } + case ASN_OBJECT_ID: { + type = Value::Oid; + oid = Identifier( new Identifier::Data( var->val.objid, var->val_len / sizeof( oid ) ) ); + break; + } + case ASN_IPADDRESS: { + type = Value::IpAddress; + addr = QHostAddress( static_cast<uint>( *var->val.integer ) ); + break; + } + case ASN_COUNTER: { + type = Value::Counter; + data = QVariant( static_cast<uint>( *var->val.integer ) ); + break; + } + case ASN_GAUGE: { + type = Value::Gauge; + data = QVariant( static_cast<uint>( *var->val.integer ) ); + break; + } + case ASN_COUNTER64: { + type = Value::Counter64; + ctr64 = ( ( ( Q_UINT64 )var->val.counter64->high ) << 32 ) | ( var->val.counter64->low ); + break; + } + case ASN_TIMETICKS: { + type = Value::TimeTicks; + data = QVariant( static_cast<int>( *var->val.integer ) ); + break; + } + case SNMP_NOSUCHOBJECT: { + type = Value::NoSuchObject; + break; + } + case SNMP_NOSUCHINSTANCE: { + type = Value::NoSuchInstance; + break; + } + case SNMP_ENDOFMIBVIEW: { + type = Value::EndOfMIBView; + break; + } +#if defined( OPAQUE_SPECIAL_TYPES ) + case ASN_OPAQUE_FLOAT: { + type = Value::Double; + data = QVariant( static_cast<float>( *var->val.floatVal ) ); + break; + } + case ASN_OPAQUE_DOUBLE: { + type = Value::Double; + data = QVariant( static_cast<float>( *var->val.doubleVal ) ); + break; + } +#endif + default: { + qDebug( "ValueImp: converting from %i to invalid", var->type ); + type = Value::Invalid; break; + } + } +} + +Value::Value() +{ + d = new ValueImpl; +} + +Value::Value( ValueImpl *impl ) + : d( impl ) +{ +} + +Value::Value( int val, Type type ) +{ + d = new ValueImpl; + + assert( type == Int || type == TimeTicks ); + + d->type = type; + d->data = QVariant( val ); +} + +Value::Value( uint val, Type type ) +{ + d = new ValueImpl; + + assert( type == UInt || type == Counter || type == Gauge ); + + d->type = type; + d->data = QVariant( val ); +} + +Value::Value( double val ) +{ + d = new ValueImpl; + d->type = Double; + d->data = QVariant( val ); +} + +Value::Value( const QByteArray &data ) +{ + d = new ValueImpl; + d->type = ByteArray; + d->data = QVariant( data ); +} + +Value::Value( const KSim::Snmp::Identifier &oid ) +{ + d = new ValueImpl; + d->type = Value::Oid; + d->oid = oid; +} + +Value::Value( const QHostAddress &address ) +{ + d = new ValueImpl; + d->type = IpAddress; + d->addr = address; +} + +Value::Value( Q_UINT64 counter ) +{ + d = new ValueImpl; + d->type = Counter64; + d->ctr64 = counter; +} + +Value::Value( const Value &rhs ) +{ + d = new ValueImpl( *rhs.d ); +} + +Value &Value::operator=( const Value &rhs ) +{ + if ( this == &rhs ) + return *this; + + delete d; + d = new ValueImpl( *rhs.d ); + + return *this; +} + +Value::~Value() +{ + delete d; +} + +Value::Type Value::type() const +{ + return d->type; +} + +int Value::toInt() const +{ + switch ( d->type ) { + case Int: + case TimeTicks: return d->data.toInt(); + case Invalid: qDebug( "cannot convert from invalid to int" ); + default: assert( false ); + } + assert( false ); + return -1; +} + +uint Value::toUInt() const +{ + switch ( d->type ) { + case UInt: + case Counter: + case Gauge: return d->data.toUInt(); + case Invalid: qDebug( "cannot convert from invalid to uint" ); + default: assert( false ); + } + assert( false ); + return 0; +} + +double Value::toDouble() const +{ + assert( d->type == Double ); + return d->data.toDouble(); +} + +const QByteArray Value::toByteArray() const +{ + assert( d->type == ByteArray ); + return d->data.toByteArray(); +} + +const Identifier Value::toOID() const +{ + assert( d->type == Oid ); + return d->oid; +} + +const QHostAddress Value::toIpAddress() const +{ + assert( d->type == IpAddress ); + return d->addr; +} + +uint Value::toCounter() const +{ + return toUInt(); +} + +uint Value::toGauge() const +{ + return toUInt(); +} + +int Value::toTimeTicks() const +{ + return toInt(); +} + +Q_UINT64 Value::toCounter64() const +{ + assert( d->type == Counter64 ); + return d->ctr64; +} + +QString Value::toString( int conversionFlags ) const +{ + switch ( type() ) { + case Value::Int: return QString::number( toInt() ); + case Value::Gauge: + case Value::Counter: + case Value::UInt: return QString::number( toUInt() ); + case Value::Double: return QString::number( toDouble() ); + case Value::Counter64: return QString::number( toCounter64() ); + case Value::ByteArray: return QString::fromAscii( toByteArray().data(), toByteArray().size() ); + case Value::IpAddress: return toIpAddress().toString(); + case Value::Oid: return toOID().toString(); + case Value::TimeTicks: return formatTimeTicks( toTimeTicks(), conversionFlags ); + // not using i18n here, because it may be called from within a worker thread, and I'm + // not sure it makes sense to translate it anyway + case Value::NoSuchObject: return QString::fromLatin1( "No Such Object" ); + case Value::NoSuchInstance: return QString::fromLatin1( "No Such Instance" ); + case Value::EndOfMIBView: return QString::fromLatin1( "End Of MIB View" ); + case Value::Invalid: + case Value::Null: return QString::null; + } + return QString::null; +} + +QString Value::formatTimeTicks( int ticks, int conversionFlags ) +{ + ticks /= 100; + + int days = ticks / ( 60 * 60 * 24 ); + ticks %= 60 * 60 * 24; + + int hours = ticks / ( 60 * 60 ); + ticks %= 60 * 60; + + int minutes = ticks / 60; + int seconds = ticks % 60; + + QString result; + + if ( days > 0 ) + result += QString::number( days ) + "d:"; + + result += QString::fromAscii( "%1h:%2m" ).arg( hours ).arg( minutes ); + + if ( conversionFlags & TimeTicksWithSeconds ) + result += ":" + QString::number( seconds ) + "s"; + + return result; +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/value.h b/ksim/monitors/snmp/value.h new file mode 100644 index 0000000..4ffdcbb --- /dev/null +++ b/ksim/monitors/snmp/value.h @@ -0,0 +1,106 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef VALUE_H +#define VALUE_H + +#include <qhostaddress.h> + +namespace KSim +{ + +namespace Snmp +{ + +class ValueImpl; + +class Identifier; + +struct ValueImpl; + +class Value +{ +public: + enum Type { + Invalid, + Int, + UInt, + Double, + ByteArray, + Null, + Oid, + IpAddress, + Counter, + Gauge, + TimeTicks, + Counter64, + NoSuchObject, + NoSuchInstance, + EndOfMIBView + }; + + enum StringConversionFlags { TimeTicksWithSeconds = 0x1 }; + + Value(); + + Value( ValueImpl *imp ); + + Value( int val, Type type ); + Value( uint val, Type type ); + Value( float val ); + Value( double val ); + Value( const QByteArray &data ); + Value( const Identifier &oid ); + Value( const QHostAddress &address ); + Value( Q_UINT64 counter ); + + Value( const Value &rhs ); + Value &operator=( const Value &rhs ); + ~Value(); + + Type type() const; + + bool isCounterType() const { return type() == Value::Counter || type() == Value::Counter64; } + + int toInt() const; + uint toUInt() const; + double toDouble() const; + const QByteArray toByteArray() const; + const Identifier toOID() const; + const QHostAddress toIpAddress() const; + uint toCounter() const; + uint toGauge() const; + int toTimeTicks() const; + Q_UINT64 toCounter64() const; + + QString toString( int conversionFlags = 0 ) const; + +private: + static QString formatTimeTicks( int ticks, int conversionFlags ); + + ValueImpl *d; +}; + +} + +} + +#endif // VALUE_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/value_p.h b/ksim/monitors/snmp/value_p.h new file mode 100644 index 0000000..8d61f59 --- /dev/null +++ b/ksim/monitors/snmp/value_p.h @@ -0,0 +1,63 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef VALUE_P_H +#define VALUE_P_H + +#define HAVE_STRLCPY 1 +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/net-snmp-includes.h> + +#include <qvariant.h> + +#include "identifier.h" + +namespace KSim +{ + +namespace Snmp +{ + +struct ValueImpl +{ + ValueImpl() + : type( Value::Invalid ) + {} + + ValueImpl( const ValueImpl &rhs ) + { + ( *this ) = rhs; + } + + ValueImpl( variable_list *var ); + + Value::Type type; + QVariant data; + Identifier oid; + QHostAddress addr; + Q_UINT64 ctr64; +}; + +} + +} + +#endif // VALUE_P_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/view.cpp b/ksim/monitors/snmp/view.cpp new file mode 100644 index 0000000..0a4b276 --- /dev/null +++ b/ksim/monitors/snmp/view.cpp @@ -0,0 +1,80 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "view.h" +#include "plugin.h" +#include "monitorconfig.h" + +#include <label.h> + +#include <qlayout.h> + +#include <kconfig.h> + +using namespace KSim::Snmp; + +View::View( Plugin *parent, const char *name ) + : KSim::PluginView( parent, name ) +{ + m_layout = new QVBoxLayout( this ); + + reparseConfig(); +} + +View::~View() +{ +} + +void View::reparseConfig() +{ + m_widgets.setAutoDelete( true ); + m_widgets.clear(); + m_widgets.setAutoDelete( false ); + + KConfig &cfg = *config(); + cfg.setGroup( "General" ); + QStringList allHosts = cfg.readListEntry( "Hosts" ); + QStringList monitors = cfg.readListEntry( "Monitors" ); + + HostConfigMap hosts; + hosts.load( cfg, allHosts ); + + MonitorConfigMap monitorConfigs; + monitorConfigs.load( cfg, monitors, hosts ); + + for ( MonitorConfigMap::ConstIterator it = monitorConfigs.begin(); + it != monitorConfigs.end(); ++it ) { + + MonitorConfig monitorConfig = *it; + + QWidget *w = monitorConfig.createMonitorWidget( this ); + if ( !w ) + continue; + + m_widgets.append( w ); + m_layout->addWidget( w ); + + w->show(); + } +} + +#include "view.moc" + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/view.h b/ksim/monitors/snmp/view.h new file mode 100644 index 0000000..f03a59c --- /dev/null +++ b/ksim/monitors/snmp/view.h @@ -0,0 +1,55 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef VIEW_H +#define VIEW_H + +#include <pluginmodule.h> + +class QBoxLayout; + +namespace KSim +{ + +namespace Snmp +{ + +class Plugin; + +class View : public KSim::PluginView +{ + Q_OBJECT +public: + View( Plugin *parent, const char *name ); + ~View(); + + virtual void reparseConfig(); + +private: + QPtrList<QWidget> m_widgets; + QBoxLayout *m_layout; +}; + +} + +} + +#endif // VIEW_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/walker.cpp b/ksim/monitors/snmp/walker.cpp new file mode 100644 index 0000000..593cd04 --- /dev/null +++ b/ksim/monitors/snmp/walker.cpp @@ -0,0 +1,121 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "walker.h" + +#include <qapplication.h> + +#include <functional> +#include <algorithm> + +using namespace KSim::Snmp; + +namespace +{ + template <class T> + struct Deleter : public std::unary_function<T, void> + { + void operator()( T arg ) + { delete arg; } + }; +} + +static const uint walkerRefresh = 0; + +Walker::Walker( const HostConfig &host, const Identifier &startOid, QObject *parent, const char *name ) + : QObject( parent, name ), m_stop( false ), m_oid( startOid ), m_session( host ) +{ + m_timerId = startTimer( walkerRefresh ); + start(); +} + +Walker::~Walker() +{ + m_stopGuard.lock(); + m_stop = true; + m_stopGuard.unlock(); + + if ( QThread::running() ) + QThread::wait(); + + std::for_each( m_results.begin(), m_results.end(), Deleter<Result *>() ); +} + +void Walker::run() +{ + while ( !m_stop ) { + Result *result = new Result; + + result->success = m_session.snmpGetNext( m_oid, result->data, &result->error ); + result->oid = m_oid; + + // do it here, because it sometimes is slow and can block for a bit + if ( result->success ) { + result->identifierString = result->oid.toString(); + result->dataString = result->data.toString(); + } + + m_stopGuard.lock(); + if ( !m_stop ) + m_stop = !result->success; + m_stopGuard.unlock(); + + m_resultGuard.lock(); + m_results << result; + m_resultGuard.unlock(); + } + + // cause finished signal to be emitted + QApplication::postEvent( this, new QCustomEvent( QEvent::User ) ); +} + +void Walker::timerEvent( QTimerEvent *ev ) +{ + if ( ev->timerId() != m_timerId ) + return; + + Result *result = 0; + + m_resultGuard.lock(); + if ( !m_results.isEmpty() ) { + result = m_results.first(); + m_results.remove( m_results.begin() ); + } + m_resultGuard.unlock(); + + if ( result ) { + emit resultReady( *result ); + + delete result; + } + + if ( !QThread::running() && !result ) { + killTimer( m_timerId ); + m_timerId = 0; + } +} + +void Walker::customEvent( QCustomEvent * ) +{ + emit finished(); +} + +#include "walker.moc" +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/walker.h b/ksim/monitors/snmp/walker.h new file mode 100644 index 0000000..e1b1ace --- /dev/null +++ b/ksim/monitors/snmp/walker.h @@ -0,0 +1,82 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef WALKER_H +#define WALKER_H + +#include <qthread.h> +#include <qobject.h> +#include <qmutex.h> +#include <qvaluelist.h> + +#include "session.h" + +namespace KSim +{ + +namespace Snmp +{ + +class Walker : public QObject, public QThread +{ + Q_OBJECT +public: + Walker( const HostConfig &host, const Identifier &startOid, QObject *parent, const char *name = 0 ); + virtual ~Walker(); + + struct Result + { + Result() : success( false ) {} + bool success; + Identifier oid; + QString identifierString; + Value data; + QString dataString; + ErrorInfo error; + }; + +signals: + void resultReady( const Walker::Result &result ); + void finished(); + +protected: + virtual void run(); + virtual void timerEvent( QTimerEvent *ev ); + virtual void customEvent( QCustomEvent *ev ); + +private: + typedef QValueList<Result *> ResultList; + + ResultList m_results; + QMutex m_resultGuard; + + bool m_stop; + QMutex m_stopGuard; + + Identifier m_oid; + int m_timerId; + Session m_session; +}; + +} +} + +#endif // WALKER_H +/* vim: et sw=4 ts=4 + */ |