1
0
mirror of https://github.com/moparisthebest/hexchat synced 2024-11-24 02:02:19 -05:00

Unify sysinfo plugins and add osx support

This does remove the net* commands from the
Unix version that may return at a later date
with OSX and Windows support.

This commit also makes numerious other changes
such as code cleanup, reformatting, etc.

Closes #829
This commit is contained in:
TingPing 2015-02-14 13:35:02 -05:00
parent 363321dc33
commit 5e3355a6c3
28 changed files with 1681 additions and 2232 deletions

1
.gitignore vendored
View File

@ -2,6 +2,7 @@
# Unix generated files # Unix generated files
.deps/ .deps/
.libs/ .libs/
.dirstamp
Makefile Makefile
Makefile.in Makefile.in
aclocal.m4 aclocal.m4

View File

@ -40,6 +40,7 @@ AH_VERBATIM([PREFIX],[#undef PREFIX])
AH_VERBATIM([HEXCHATLIBDIR],[#undef HEXCHATLIBDIR]) AH_VERBATIM([HEXCHATLIBDIR],[#undef HEXCHATLIBDIR])
AH_VERBATIM([HEXCHATSHAREDIR],[#undef HEXCHATSHAREDIR]) AH_VERBATIM([HEXCHATSHAREDIR],[#undef HEXCHATSHAREDIR])
AH_VERBATIM([USE_LIBPROXY],[#undef USE_LIBPROXY]) AH_VERBATIM([USE_LIBPROXY],[#undef USE_LIBPROXY])
AH_VERBATIM([HAVE_LIBPCI],[#undef HAVE_LIBPCI])
AH_VERBATIM([HAVE_ISO_CODES],[#undef HAVE_ISO_CODES]) AH_VERBATIM([HAVE_ISO_CODES],[#undef HAVE_ISO_CODES])
AH_VERBATIM([HAVE_GTK_MAC],[#undef HAVE_GTK_MAC]) AH_VERBATIM([HAVE_GTK_MAC],[#undef HAVE_GTK_MAC])
AH_VERBATIM([USE_LIBNOTIFY],[#undef USE_LIBNOTIFY]) AH_VERBATIM([USE_LIBNOTIFY],[#undef USE_LIBNOTIFY])
@ -73,9 +74,12 @@ else
fi fi
platform_win32=no platform_win32=no
platform_osx=no
case $host_os in case $host_os in
*mingw*|*cygwin*|*msys*) *mingw*|*cygwin*|*msys*)
platform_win32=yes;; platform_win32=yes;;
darwin*)
platform_osx=yes;;
*);; *);;
esac esac
@ -492,7 +496,14 @@ if test "$sysinfo" != "no"; then
AC_MSG_CHECKING(for plugin interface used by SysInfo) AC_MSG_CHECKING(for plugin interface used by SysInfo)
if test "$plugin" = yes; then if test "$plugin" = yes; then
AC_MSG_RESULT([yes]) AC_MSG_RESULT([yes])
PKG_CHECK_MODULES(LIBPCI, libpci >= 3.0.0, [sysinfo=yes], [sysinfo=no]) if test "$platform_osx" = yes; then
sysinfo=yes
else
PKG_CHECK_MODULES(LIBPCI, libpci >= 3.0.0, [
sysinfo=yes
AC_DEFINE(HAVE_LIBPCI)
], [sysinfo=no])
fi
else else
AC_MSG_RESULT([plugins are disabled, use the --enable-plugin option for SysInfo]) AC_MSG_RESULT([plugins are disabled, use the --enable-plugin option for SysInfo])
sysinfo=no sysinfo=no
@ -600,6 +611,7 @@ AM_CONDITIONAL(USE_DBUS, test "x$dbus" = "xyes")
AM_CONDITIONAL(HAVE_ISO_CODES, test "x$isocodes" = "xyes") AM_CONDITIONAL(HAVE_ISO_CODES, test "x$isocodes" = "xyes")
AM_CONDITIONAL(HAVE_GTK_MAC, test "x$_gdk_tgt" = xquartz) AM_CONDITIONAL(HAVE_GTK_MAC, test "x$_gdk_tgt" = xquartz)
AM_CONDITIONAL(WITH_TM, test "x$theme_manager" != "xno") AM_CONDITIONAL(WITH_TM, test "x$theme_manager" != "xno")
AM_CONDITIONAL(PLATFORM_OSX, test "x$platform_osx" == "xyes")
dnl ********************************************************************* dnl *********************************************************************
dnl ** GCC FLAGS ******************************************************** dnl ** GCC FLAGS ********************************************************

View File

@ -1,7 +1,17 @@
libdir = $(hexchatlibdir) libdir = $(hexchatlibdir)
sources = sysinfo.c format.c shared/df.c
if PLATFORM_OSX
sources += osx/backend.m
else
sources += unix/backend.c unix/match.c unix/parse.c unix/pci.c
endif
EXTRA_DIST = osx unix win32 shared format.h sysinfo.h sysinfo-backend.h
lib_LTLIBRARIES = sysinfo.la lib_LTLIBRARIES = sysinfo.la
sysinfo_la_SOURCES = match.c parse.c pci.c xsys.c sysinfo_la_SOURCES = $(sources)
sysinfo_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module sysinfo_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module
sysinfo_la_LIBADD = $(LIBPCI_LIBS) $(GLIB_LIBS) sysinfo_la_LIBADD = $(LIBPCI_LIBS) $(GLIB_LIBS)
sysinfo_la_CFLAGS = $(LIBPCI_CFLAGS) $(GLIB_CFLAGS) -I$(srcdir)/../../src/common AM_CPPFLAGS = $(LIBPCI_CFLAGS) $(GLIB_CFLAGS) -I$(top_srcdir)/src/common -I$(srcdir)/shared

95
plugins/sysinfo/format.c Normal file
View File

@ -0,0 +1,95 @@
/*
* SysInfo - sysinfo plugin for HexChat
* Copyright (c) 2015 Patrick Griffis.
*
* 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 St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <glib.h>
char *
sysinfo_format_uptime (gint64 uptime)
{
char buffer[128];
int weeks;
int days;
int hours;
int minutes;
int seconds;
seconds = uptime%60;
minutes = (uptime/60)%60;
hours = (uptime/3600)%24;
days = (uptime/86400)%7;
weeks = uptime/604800;
if (minutes != 0 || hours != 0 || days != 0 || weeks != 0)
{
if (hours != 0 || days != 0 || weeks != 0)
{
if (days !=0 || weeks != 0)
{
if (weeks != 0)
g_snprintf (buffer, sizeof(buffer), "%dw %dd %dh %dm %ds", weeks, days, hours, minutes, seconds);
else
g_snprintf (buffer, sizeof(buffer), "%dd %dh %dm %ds", days, hours, minutes, seconds);
}
else
{
g_snprintf (buffer, sizeof(buffer), "%dh %dm %ds", hours, minutes, seconds);
}
}
else
{
g_snprintf (buffer, sizeof(buffer), "%dm %ds", minutes, seconds);
}
}
return g_strdup (buffer);
}
char *
sysinfo_format_memory (guint64 totalmem, guint64 freemem)
{
char *total_fmt, *free_fmt, *ret;
total_fmt = g_format_size_full (totalmem, G_FORMAT_SIZE_IEC_UNITS);
free_fmt = g_format_size_full (freemem, G_FORMAT_SIZE_IEC_UNITS);
ret = g_strdup_printf ("%s Total (%s Free)", total_fmt, free_fmt);
g_free (total_fmt);
g_free (free_fmt);
return ret;
}
char *
sysinfo_format_disk (guint64 total, guint64 free)
{
char *total_fmt, *free_fmt, *used_fmt, *ret;
GFormatSizeFlags format_flags = G_FORMAT_SIZE_DEFAULT;
#ifdef WIN32 /* Windows uses IEC size (with SI format) */
format_flags = G_FORMAT_SIZE_IEC_UNITS;
#endif
total_fmt = g_format_size_full (total, format_flags);
free_fmt = g_format_size_full (free, format_flags);
used_fmt = g_format_size_full (total - free, format_flags);
ret = g_strdup_printf ("%s / %s (%s Free)", used_fmt, total_fmt, free_fmt);
g_free (total_fmt);
g_free (free_fmt);
g_free (used_fmt);
return ret;
}

28
plugins/sysinfo/format.h Normal file
View File

@ -0,0 +1,28 @@
/*
* SysInfo - sysinfo plugin for HexChat
* Copyright (c) 2015 Patrick Griffis.
*
* 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 St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef FORMAT_H
#define FORMAT_H
char *sysinfo_format_uptime(gint64 uptime);
char *sysinfo_format_memory(guint64 totalmem, guint64 freemem);
char *sysinfo_format_disk(guint64 total, guint64 free);
#endif

View File

@ -1,228 +0,0 @@
/*
* match.c - matching functions for X-Sys
* Copyright (C) 2005, 2006, 2007 Tony Vroon
*
* 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 St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <glib.h>
#include "xsys.h"
float percentage(unsigned long long *free, unsigned long long *total)
{
unsigned long long result = (*free) * (unsigned long long)1000 / (*total);
return result / 10.0;
}
char *pretty_freespace(const char *desc, unsigned long long *free_k, unsigned long long *total_k)
{
char *quantities[] = { "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB", 0 };
char *result, **quantity;
double free_space, total_space;
free_space = *free_k;
total_space = *total_k;
result = g_new(char, bsize);
if (total_space == 0)
{
g_snprintf(result, bsize, "%s: none", desc);
return result;
}
quantity = quantities;
while (total_space > 1023 && *(quantity + 1))
{
quantity++;
free_space = free_space / 1024;
total_space = total_space / 1024;
}
if (sysinfo_get_percent () != 0)
g_snprintf(result, bsize, "%s: %.1f%s, %.1f%% free",
desc, total_space, *quantity,
percentage(free_k, total_k));
else
g_snprintf(result, bsize, "%s: %.1f%s/%.1f%s free",
desc, free_space, *quantity, total_space, *quantity);
return result;
}
void remove_leading_whitespace(char *buffer)
{
char *p;
if (buffer == NULL)
return;
for (p = buffer; *p && isspace (*p); p++)
;
memmove (buffer, p, strlen (p) + 1);
}
char *decruft_filename(char *buffer)
{
char *match, *match_end;
while ((match = strstr(buffer, "%20")))
{
match_end = match + 3;
*match++ = ' ';
while (*match_end)
*match++ = *match_end++;
*match = 0;
}
return buffer;
}
void find_match_char(char *buffer, char *match, char *result)
{
char *position;
remove_leading_whitespace(buffer);
if(strstr(buffer, match) == strstr(buffer, buffer))
{
position = strpbrk(buffer, delims);
if (position != NULL) {
position += 1;
strcpy(result, position);
position = strstr(result, "\n");
*(position) = '\0';
remove_leading_whitespace(result);
}
else
strcpy(result, "\0");
}
}
void find_match_double(char *buffer, char *match, double *result)
{
char *position;
remove_leading_whitespace(buffer);
if(strstr(buffer, match) == strstr(buffer, buffer))
{
position = strpbrk(buffer, delims);
if (position != NULL) {
position += 1;
*result = strtod(position, NULL);
}
else
*result = 0;
}
}
void find_match_double_hex(char *buffer, char *match, double *result)
{
char *position;
remove_leading_whitespace(buffer);
if(strstr(buffer, match) == strstr(buffer, buffer))
{
position = strpbrk(buffer, delims);
if (position != NULL) {
memcpy(position,"0x",2);
*result = strtod(position,NULL);
}
else
*result = 0;
}
}
void find_match_int(char *buffer, char *match, unsigned int *result)
{
char *position;
remove_leading_whitespace(buffer);
if(strstr(buffer, match) == strstr(buffer, buffer))
{
position = strpbrk(buffer, delims);
if (position != NULL) {
position += 1;
*result = atoi(position);
}
else
*result = 0;
}
}
void find_match_ll(char *buffer, char *match, unsigned long long *result)
{
char *position;
remove_leading_whitespace(buffer);
if(strstr(buffer, match) == strstr(buffer, buffer))
{
position = strpbrk(buffer, delims);
if (position != NULL) {
position += 1;
*result = strtoll(position, NULL, 10);
}
else
*result = 0;
}
}
void format_output(const char *arg, char *string, char *format)
{
char *pos1, *pos2, buffer[bsize];
pos1 = &format[0];
strncpy(buffer, string, bsize);
string[0] = '\0';
while((pos2 = strstr(pos1, "%")) != NULL)
{
strncat(string, pos1, (size_t)(pos2-pos1));
if(*(pos2+1) == '1')
strcat(string, arg);
else if(*(pos2+1) == '2')
strcat(string, buffer);
else if(*(pos2+1) == 'C' || *(pos2+1) == 'c')
strcat(string, "\003");
else if(*(pos2+1) == 'B' || *(pos2+1) == 'b')
strcat(string, "\002");
else if(*(pos2+1) == 'R' || *(pos2+1) == 'r')
strcat(string, "\026");
else if(*(pos2+1) == 'O' || *(pos2+1) == 'o')
strcat(string, "\017");
else if(*(pos2+1) == 'U' || *(pos2+1) == 'u')
strcat(string, "\037");
else if(*(pos2+1) == '%')
strcat(string, "%");
pos1=pos2+2;
}
strcat(string, pos1);
}
void flat_format_output(const char *arg, char *string, char *format)
{
char *pos1, *pos2, buffer[bsize];
pos1 = &format[0];
strncpy(buffer, string, bsize);
string[0] = '\0';
while((pos2 = strstr(pos1, "%")) != NULL)
{
strncat(string, pos1, (size_t)(pos2-pos1));
if(*(pos2+1) == '1')
strcat(string, arg);
else if(*(pos2+1) == '2')
strcat(string, buffer);
else if(*(pos2+1) == '%')
strcat(string, "%");
pos1=pos2+2;
}
strcat(string, pos1);
}

View File

@ -0,0 +1,263 @@
/*
* SysInfo - sysinfo plugin for HexChat
* Copyright (c) 2015 Patrick Griffis.
*
* 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 St, Fifth Floor, Boston, MA 02110-1301, USA
*/
/*
* Some snippets based upon Textual's System Profiler plugin.
* https://github.com/Codeux-Software/Textual
*/
#import <Cocoa/Cocoa.h>
#include <sys/sysctl.h>
#include <mach/mach.h>
#include <mach/mach_host.h>
#include <mach/host_info.h>
#include <mach/mach_vm.h>
#include <glib.h>
#include "format.h"
#include "df.h"
static char *
get_os (void)
{
NSDictionary *systemversion = [NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"];
NSString *build = [systemversion objectForKey:@"ProductBuildVersion"];
if (!build)
return NULL;
NSString *version = [systemversion objectForKey:@"ProductUserVisibleVersion"];
if (!version)
{
[build release];
return NULL;
}
NSDictionary *profiler = [NSDictionary dictionaryWithContentsOfFile:[@"~/Library/Preferences/com.apple.SystemProfiler.plist" stringByExpandingTildeInPath]];
NSDictionary *names = [profiler objectForKey:@"OS Names"];
NSString *os_name = nil;
for (NSString *name in names)
{
if ([name hasPrefix:build])
{
os_name = [names objectForKey:name];
break;
}
}
[build release];
if (!os_name)
{
[version release];
return NULL;
}
char *ret = g_strdup_printf ("%s %s", [os_name UTF8String], [version UTF8String]);
[version release];
return ret;
}
static char *
get_os_fallback (void)
{
NSProcessInfo *info = [NSProcessInfo processInfo];
NSOperatingSystemVersion version = [info operatingSystemVersion];
return g_strdup_printf ("OS X %ld.%ld.%ld", version.majorVersion, version.minorVersion, version.patchVersion);
}
char *
sysinfo_backend_get_os(void)
{
static char *os_str = NULL;
if (!os_str)
{
os_str = get_os();
if (!os_str)
os_str = get_os_fallback();
}
return g_strdup (os_str);
}
char *
sysinfo_backend_get_disk(void)
{
gint64 total, free_space;
if (xs_parse_df (&total, &free_space))
{
return NULL;
}
return sysinfo_format_disk (total, free_space);
}
static guint64
get_free_memory (void)
{
mach_msg_type_number_t infoCount = (sizeof(vm_statistics_data_t) / sizeof(natural_t));
vm_size_t pagesize;
vm_statistics_data_t vm_stat;
host_page_size(mach_host_self(), &pagesize);
if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vm_stat, &infoCount) == KERN_SUCCESS)
return ((vm_stat.inactive_count + vm_stat.free_count) * pagesize);
return 0;
}
char *
sysinfo_backend_get_memory(void)
{
NSProcessInfo *info = [NSProcessInfo processInfo];
guint64 totalmem, freemem;
totalmem = [info physicalMemory];
if ((freemem = get_free_memory()) == 0)
return NULL;
return sysinfo_format_memory (totalmem, freemem);
}
char *
sysinfo_backend_get_cpu(void)
{
guint64 cpu_clock_uint = 0;
double cpu_clock;
char cpu_string[256];
gsize len;
gboolean giga = FALSE;
len = sizeof(cpu_string);
if (sysctlbyname ("machdep.cpu.brand_string", cpu_string, &len, NULL, 0) != 0)
return NULL;
cpu_string[sizeof(cpu_string) - 1] = '\0';
len = sizeof(cpu_clock_uint);
if (sysctlbyname("hw.cpufrequency", &cpu_clock_uint, &len, NULL, 0) < 0)
return NULL;
cpu_clock = cpu_clock_uint / 1000000;
if (cpu_clock > 1000)
{
cpu_clock /= 1000;
giga = TRUE;
}
if (giga)
return g_strdup_printf ("%s (%.2fGHz)", cpu_string, cpu_clock);
else
return g_strdup_printf ("%s (%.0fMHz)", cpu_string, cpu_clock);
}
static char *
get_gpu(void)
{
CFMutableDictionaryRef pciDevices = IOServiceMatching("IOPCIDevice");
io_iterator_t entry_iterator, serviceObject;
if (IOServiceGetMatchingServices(kIOMasterPortDefault, pciDevices, &entry_iterator) != kIOReturnSuccess)
return NULL;
GString *gpu_list = g_string_new(NULL);
while ((serviceObject = IOIteratorNext(entry_iterator)))
{
CFMutableDictionaryRef serviceDictionary;
kern_return_t status = IORegistryEntryCreateCFProperties(serviceObject, &serviceDictionary,
kCFAllocatorDefault, kNilOptions);
if (status != kIOReturnSuccess)
{
IOObjectRelease(serviceObject);
continue;
}
const void *class = CFDictionaryGetValue(serviceDictionary, @"class-code");
if (!class || *(guint32*)CFDataGetBytePtr(class) != 0x30000) /* DISPLAY_VGA */
{
CFRelease(serviceDictionary);
continue;
}
const void *model = CFDictionaryGetValue(serviceDictionary, @"model");
if (model)
{
if (CFGetTypeID(model) == CFDataGetTypeID() && CFDataGetLength(model) > 1)
{
if (gpu_list->len != 0)
g_string_append (gpu_list, ", ");
g_string_append_len (gpu_list, (const char*)CFDataGetBytePtr(model), CFDataGetLength(model) - 1);
}
}
CFRelease(serviceDictionary);
}
if (gpu_list->len == 0)
{
g_string_free (gpu_list, TRUE);
return NULL;
}
/* The string may contain nul-chars we must replace */
int i;
for (i = 0; i < gpu_list->len; i++)
{
if (gpu_list->str[i] == '\0')
gpu_list->str[i] = ' ';
}
return g_string_free (gpu_list, FALSE);
}
char *
sysinfo_backend_get_gpu(void)
{
static char *gpu_str = NULL;
if (!gpu_str)
gpu_str = get_gpu();
return g_strdup (gpu_str);
}
char *
sysinfo_backend_get_sound(void)
{
return NULL;
}
char *
sysinfo_backend_get_uptime(void)
{
NSProcessInfo *info = [NSProcessInfo processInfo];
double uptime = [info systemUptime];
return sysinfo_format_uptime ((gint64)uptime);
}
char *
sysinfo_backend_get_network(void)
{
return NULL;
}

View File

@ -0,0 +1,53 @@
/*
* 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 St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <glib.h>
#include "sysinfo.h"
int xs_parse_df(gint64 *out_total, gint64 *out_free)
{
FILE *pipe;
char buffer[bsize];
pipe = popen("df -k -l -P", "r");
if(pipe==NULL)
return 1;
*out_total = *out_free = 0;
while(fgets(buffer, bsize, pipe) != NULL)
{
long long int avail, total;
/* Filesystem 1024-blocks Used Available Capacity Mounted-on */
if (sscanf (buffer, "%*s %lld %*lld %lld %*s %*s", &total, &avail) == 2)
{
*out_total += total;
*out_free += avail;
}
}
/* Convert to bytes */
*out_total *= 1000;
*out_free *= 1000;
pclose(pipe);
return 0;
}

View File

@ -0,0 +1,23 @@
/*
* 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 St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef SYSINFO_SHARED_H
#define SYSINFO_SHARED_H
int xs_parse_df(gint64 *total_bytes, gint64 *free_bytes);
#endif

View File

@ -0,0 +1,33 @@
/*
* SysInfo - sysinfo plugin for HexChat
* Copyright (c) 2015 Patrick Griffis.
*
* 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 St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef SYSINFO_BACKEND_H
#define SYSINFO_BACKEND_H
char *sysinfo_backend_get_os(void);
char *sysinfo_backend_get_disk(void);
char *sysinfo_backend_get_memory(void);
char *sysinfo_backend_get_cpu(void);
char *sysinfo_backend_get_gpu(void);
char *sysinfo_backend_get_sound(void);
char *sysinfo_backend_get_uptime(void);
char *sysinfo_backend_get_network(void);
#endif

View File

@ -1,567 +1,277 @@
/* HexChat /*
* Copyright (c) 2011-2012 Berke Viktor. * SysInfo - sysinfo plugin for HexChat
* Copyright (c) 2012 Berke Viktor.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * xsys.c - main functions for X-Sys 2
* of this software and associated documentation files (the "Software"), to deal * by mikeshoup
* in the Software without restriction, including without limitation the rights * Copyright (C) 2003, 2004, 2005 Michael Shoup
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * Copyright (C) 2005, 2006, 2007 Tony Vroon
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * This program is free software; you can redistribute it and/or modify
* all copies or substantial portions of the Software. * 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.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * This program is distributed in the hope that it will be useful,
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * GNU General Public License for more details.
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * You should have received a copy of the GNU General Public License
* THE SOFTWARE. * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include <stdio.h> #include "config.h"
#include <windows.h>
#include <wbemidl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h> #include <glib.h>
#include "hexchat-plugin.h" #include "hexchat-plugin.h"
#include "sysinfo-backend.h"
#include "sysinfo.h"
static hexchat_plugin *ph; /* plugin handle */ #define _(x) hexchat_gettext(ph,x)
#define DEFAULT_ANNOUNCE TRUE
static char name[] = "SysInfo"; static hexchat_plugin *ph;
static char name[] = "Sysinfo";
static char desc[] = "Display info about your hardware and OS"; static char desc[] = "Display info about your hardware and OS";
static char version[] = "1.1"; static char version[] = "1.0";
static char helptext[] = "USAGE: /SYSINFO - Sends info about your hardware and OS to current channel."; static char sysinfo_help[] = "SysInfo Usage:\n /SYSINFO [-e|-o] [CLIENT|OS|CPU|RAM|DISK|VGA|SOUND|ETHERNET|UPTIME], print various details about your system or print a summary without arguments\n /SYSINFO SET <variable>\n";
/* Cache the info for subsequent invocations of /SYSINFO */ typedef struct
static int cpu_arch = 0;
static char *os_name = NULL;
static char *cpu_info = NULL;
static char *vga_name = NULL;
static int command_callback (char *word[], char *word_eol[], void *user_data);
typedef enum
{ {
QUERY_WMI_OS, const char *name; /* Lower case name used for prefs */
QUERY_WMI_CPU, const char *title; /* Used for the end formatting */
QUERY_WMI_VGA, char *(*callback) (void);
QUERY_WMI_HDD, gboolean def; /* Hide by default? */
} QueryWmiType; } hwinfo;
void print_info (void); static char *
int get_cpu_arch (void); get_client (void)
char *query_wmi (QueryWmiType mode); {
char *read_os_name (IWbemClassObject *object); return g_strdup_printf ("HexChat %s", hexchat_get_info(ph, "version"));
char *read_cpu_info (IWbemClassObject *object); }
char *read_vga_name (IWbemClassObject *object);
guint64 hdd_capacity; static hwinfo hwinfos[] = {
guint64 hdd_free_space; {"client", "Client", get_client},
char *read_hdd_info (IWbemClassObject *object); {"os", "OS", sysinfo_backend_get_os},
{"cpu", "CPU", sysinfo_backend_get_cpu},
{"memory", "Memory", sysinfo_backend_get_memory},
{"storage", "Storage", sysinfo_backend_get_disk},
{"vga", "VGA", sysinfo_backend_get_gpu},
{"sound", "Sound", sysinfo_backend_get_sound, TRUE},
{"ethernet", "Ethernet", sysinfo_backend_get_network, TRUE},
{"uptime", "Uptime", sysinfo_backend_get_uptime},
{NULL, NULL},
};
char *get_memory_info (void); static gboolean sysinfo_get_bool_pref (const char *pref, gboolean def);
char *bstr_to_utf8 (BSTR bstr);
guint64 variant_to_uint64 (VARIANT *variant);
int hexchat_plugin_init (hexchat_plugin *plugin_handle, char **plugin_name, char **plugin_desc, char **plugin_version, char *arg) static gboolean
should_show_info (hwinfo info)
{
char hide_pref[32];
g_snprintf (hide_pref, sizeof(hide_pref), "hide_%s", info.name);
return !sysinfo_get_bool_pref (hide_pref, info.def);
}
static void
print_summary (gboolean announce)
{
char **strings = g_new0 (char*, G_N_ELEMENTS(hwinfos));
int i, x;
char *output;
for (i = 0, x = 0; hwinfos[i].name != NULL; i++)
{
if (should_show_info (hwinfos[i]))
{
char *str = hwinfos[i].callback();
if (str)
{
strings[x++] = g_strdup_printf ("\002%s\002: %s", hwinfos[i].title, str);
g_free (str);
}
}
}
output = g_strjoinv (" \002\342\200\242\002 ", strings);
hexchat_commandf (ph, "%s %s", announce ? "SAY" : "ECHO", output);
g_strfreev (strings);
g_free (output);
}
static void
print_info (char *info, gboolean announce)
{
int i;
for (i = 0; hwinfos[i].name != NULL; i++)
{
if (!g_ascii_strcasecmp (info, hwinfos[i].name))
{
char *str = hwinfos[i].callback();
if (str)
{
hexchat_commandf (ph, "%s \002%s\002: %s", announce ? "SAY" : "ECHO",
hwinfos[i].title, str);
g_free (str);
}
else
hexchat_print (ph, _("Sysinfo: Failed to get info. Either not supported or error."));
return;
}
}
hexchat_print (ph, _("Sysinfo: No info by that name\n"));
}
/*
* Simple wrapper for backend specific options.
* Ensure dest >= 512.
*/
int
sysinfo_get_str_pref (const char *pref, char *dest)
{
return hexchat_pluginpref_get_str (ph, pref, dest);
}
static gboolean
sysinfo_get_bool_pref (const char *pref, gboolean def)
{
int value = hexchat_pluginpref_get_int (ph, pref);
if (value != -1)
return value;
return def;
}
static void
sysinfo_set_pref_real (const char *pref, char *value, gboolean def)
{
if (value && value[0])
{
guint64 i = g_ascii_strtoull (value, NULL, 0);
hexchat_pluginpref_set_int (ph, pref, i != 0);
hexchat_printf (ph, _("Sysinfo: %s is set to: %d\n"), pref, i != 0);
}
else
{
hexchat_printf (ph, _("Sysinfo: %s is set to: %d\n"), pref,
sysinfo_get_bool_pref(pref, def));
}
}
static void
sysinfo_set_pref (char *key, char *value)
{
if (!key || !key[0])
{
hexchat_print (ph, _("Sysinfo: Valid settings are: announce and hide_* for each piece of information. e.g. hide_os. Without a value it will show current (or default) setting.\n"));
return;
}
if (!strcmp (key, "announce"))
{
sysinfo_set_pref_real (key, value, DEFAULT_ANNOUNCE);
return;
}
#ifdef HAVE_LIBPCI
else if (!strcmp (key, "pciids"))
{
if (value && value[0])
{
hexchat_pluginpref_set_str (ph, "pciids", value);
hexchat_printf (ph, _("Sysinfo: pciids is set to: %s\n"), value);
}
else
{
char buf[512];
if (hexchat_pluginpref_get_str (ph, "pciids", buf) == 0)
strcpy (buf, DEFAULT_PCIIDS);
hexchat_printf (ph, _("Sysinfo: pciids is set to: %s\n"), buf);
}
return;
}
#endif
else if (g_str_has_prefix (key, "hide_"))
{
int i;
for (i = 0; hwinfos[i].name != NULL; i++)
{
if (!strcmp (key + 5, hwinfos[i].name))
{
sysinfo_set_pref_real (key, value, hwinfos[i].def);
return;
}
}
}
hexchat_print (ph, _("Sysinfo: Invalid variable name\n"));
}
static int
sysinfo_cb (char *word[], char *word_eol[], void *userdata)
{
gboolean announce = sysinfo_get_bool_pref("announce", DEFAULT_ANNOUNCE);
int offset = 0, channel_type;
char *cmd;
/* Allow overriding global announce setting */
if (!strcmp ("-e", word[2]))
{
announce = FALSE;
offset++;
}
else if (!strcmp ("-o", word[2]))
{
announce = TRUE;
offset++;
}
/* Cannot send to server tab */
channel_type = hexchat_list_int (ph, NULL, "type");
if (channel_type != 2 /* SESS_CHANNEL */ && channel_type != 3 /* SESS_DIALOG */)
announce = FALSE;
cmd = word[2+offset];
if (!g_ascii_strcasecmp ("SET", cmd))
sysinfo_set_pref (word[3+offset], word_eol[4+offset]);
else if (!cmd || !cmd[0])
print_summary (announce);
else
print_info (cmd, announce);
return HEXCHAT_EAT_ALL;
}
int
hexchat_plugin_init (hexchat_plugin *plugin_handle, char **plugin_name, char **plugin_desc, char **plugin_version, char *arg)
{ {
ph = plugin_handle; ph = plugin_handle;
*plugin_name = name; *plugin_name = name;
*plugin_desc = desc; *plugin_desc = desc;
*plugin_version = version; *plugin_version = version;
hexchat_hook_command (ph, "SYSINFO", HEXCHAT_PRI_NORM, command_callback, helptext, NULL); hexchat_hook_command (ph, "SYSINFO", HEXCHAT_PRI_NORM, sysinfo_cb, sysinfo_help, NULL);
hexchat_command (ph, "MENU -ishare\\system.png ADD \"Window/Send System Info\" \"SYSINFO\"");
hexchat_printf (ph, "%s plugin loaded\n", name);
hexchat_command (ph, "MENU ADD \"Window/Send System Info\" \"SYSINFO\"");
hexchat_printf (ph, _("%s plugin loaded\n"), name);
return 1; return 1;
} }
int hexchat_plugin_deinit (void) int
hexchat_plugin_deinit (void)
{ {
g_free (os_name);
g_free (cpu_info);
g_free (vga_name);
hexchat_command (ph, "MENU DEL \"Window/Display System Info\""); hexchat_command (ph, "MENU DEL \"Window/Display System Info\"");
hexchat_printf (ph, "%s plugin unloaded\n", name); hexchat_printf (ph, _("%s plugin unloaded\n"), name);
return 1; return 1;
} }
static int command_callback (char *word[], char *word_eol[], void *user_data)
{
print_info ();
return HEXCHAT_EAT_HEXCHAT;
}
static void print_info (void)
{
char *memory_info;
char *hdd_info;
int channel_type;
#ifdef _WIN64
const char *build_arch = "x64";
#else
const char *build_arch = "x86";
#endif
/* Load information if not already loaded */
if (cpu_arch == 0)
{
cpu_arch = get_cpu_arch ();
}
if (os_name == NULL)
{
os_name = query_wmi (QUERY_WMI_OS);
if (os_name == NULL)
{
hexchat_printf (ph, "%s - Error while getting OS info.\n", name);
os_name = g_strdup ("Unknown");
}
}
if (cpu_info == NULL)
{
cpu_info = query_wmi (QUERY_WMI_CPU);
if (cpu_info == NULL)
{
hexchat_printf (ph, "%s - Error while getting CPU info.\n", name);
cpu_info = g_strdup ("Unknown");
}
}
if (vga_name == NULL)
{
vga_name = query_wmi (QUERY_WMI_VGA);
if (vga_name == NULL)
{
hexchat_printf (ph, "%s - Error while getting VGA info.\n", name);
vga_name = g_strdup ("Unknown");
}
}
/* Memory information is always loaded dynamically since it includes the current amount of free memory */
memory_info = get_memory_info ();
if (memory_info == NULL)
{
hexchat_printf (ph, "%s - Error while getting memory info.\n", name);
memory_info = g_strdup ("Unknown");
}
/* HDD information is always loaded dynamically since it includes the current amount of free space */
hdd_capacity = 0;
hdd_free_space = 0;
hdd_info = query_wmi (QUERY_WMI_HDD);
if (hdd_info == NULL)
{
hexchat_printf (ph, "%s - Error while getting disk info.\n", name);
hdd_info = g_strdup ("Unknown");
}
else
{
gfloat total_gb = hdd_capacity / 1000.f / 1000.f / 1000.f;
gfloat used_gb = (hdd_capacity - hdd_free_space) / 1000.f / 1000.f / 1000.f;
gfloat free_gb = hdd_free_space / 1000.f / 1000.f / 1000.f;
hdd_info = g_strdup_printf ("%.2f GB / %.2f GB (%.2f GB Free)", used_gb, total_gb, free_gb);
}
channel_type = hexchat_list_int (ph, NULL, "type");
if (channel_type == 2 /* SESS_CHANNEL */ || channel_type == 3 /* SESS_DIALOG */)
{
hexchat_commandf (
ph,
"ME ** SysInfo ** Client: HexChat %s (%s) ** OS: %s (x%d) ** CPU: %s ** RAM: %s ** VGA: %s ** HDD: %s ** Uptime: %.2f Hours **",
hexchat_get_info (ph, "version"), build_arch,
os_name, cpu_arch,
cpu_info,
memory_info,
vga_name,
hdd_info,
(float) GetTickCount64 () / 1000 / 60 / 60);
}
else
{
hexchat_printf (ph, " * Client: HexChat %s (%s)\n", hexchat_get_info (ph, "version"), build_arch);
hexchat_printf (ph, " * OS: %s (x%d)\n", os_name, cpu_arch);
hexchat_printf (ph, " * CPU: %s\n", cpu_info);
hexchat_printf (ph, " * RAM: %s\n", memory_info);
hexchat_printf (ph, " * VGA: %s\n", vga_name);
hexchat_printf (ph, " * HDD: %s\n", hdd_info);
hexchat_printf (ph, " * Uptime: %.2f Hours\n", (float) GetTickCount64 () / 1000 / 60 / 60);
}
g_free (memory_info);
}
static int get_cpu_arch (void)
{
SYSTEM_INFO si;
GetNativeSystemInfo (&si);
if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
{
return 64;
}
else
{
return 86;
}
}
/* http://msdn.microsoft.com/en-us/site/aa390423 */
static char *query_wmi (QueryWmiType type)
{
GString *result = NULL;
HRESULT hr;
IWbemLocator *locator = NULL;
BSTR namespaceName = NULL;
BSTR queryLanguageName = NULL;
BSTR query = NULL;
IWbemServices *namespace = NULL;
IUnknown *namespaceUnknown = NULL;
IEnumWbemClassObject *enumerator = NULL;
int i;
gboolean atleast_one_appended = FALSE;
hr = CoCreateInstance (&CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, &IID_IWbemLocator, (LPVOID *) &locator);
if (FAILED (hr))
{
goto exit;
}
namespaceName = SysAllocString (L"root\\CIMV2");
hr = locator->lpVtbl->ConnectServer (locator, namespaceName, NULL, NULL, NULL, 0, NULL, NULL, &namespace);
if (FAILED (hr))
{
goto release_locator;
}
hr = namespace->lpVtbl->QueryInterface (namespace, &IID_IUnknown, &namespaceUnknown);
if (FAILED (hr))
{
goto release_namespace;
}
hr = CoSetProxyBlanket (namespaceUnknown, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
if (FAILED (hr))
{
goto release_namespaceUnknown;
}
queryLanguageName = SysAllocString (L"WQL");
switch (type)
{
case QUERY_WMI_OS:
query = SysAllocString (L"SELECT Caption FROM Win32_OperatingSystem");
break;
case QUERY_WMI_CPU:
query = SysAllocString (L"SELECT Name, MaxClockSpeed FROM Win32_Processor");
break;
case QUERY_WMI_VGA:
query = SysAllocString (L"SELECT Name FROM Win32_VideoController");
break;
case QUERY_WMI_HDD:
query = SysAllocString (L"SELECT Name, Capacity, FreeSpace FROM Win32_Volume");
break;
default:
goto release_queryLanguageName;
}
hr = namespace->lpVtbl->ExecQuery (namespace, queryLanguageName, query, WBEM_FLAG_FORWARD_ONLY, NULL, &enumerator);
if (FAILED (hr))
{
goto release_query;
}
result = g_string_new ("");
for (i = 0;; i++)
{
ULONG numReturned = 0;
IWbemClassObject *object;
char *line;
hr = enumerator->lpVtbl->Next (enumerator, WBEM_INFINITE, 1, &object, &numReturned);
if (FAILED (hr) || numReturned == 0)
{
break;
}
switch (type)
{
case QUERY_WMI_OS:
line = read_os_name (object);
break;
case QUERY_WMI_CPU:
line = read_cpu_info (object);
break;
case QUERY_WMI_VGA:
line = read_vga_name (object);
break;
case QUERY_WMI_HDD:
line = read_hdd_info (object);
break;
default:
break;
}
object->lpVtbl->Release (object);
if (line != NULL)
{
if (atleast_one_appended)
{
g_string_append (result, ", ");
}
g_string_append (result, line);
g_free (line);
atleast_one_appended = TRUE;
}
}
enumerator->lpVtbl->Release (enumerator);
release_query:
SysFreeString (query);
release_queryLanguageName:
SysFreeString (queryLanguageName);
release_namespaceUnknown:
namespaceUnknown->lpVtbl->Release (namespaceUnknown);
release_namespace:
namespace->lpVtbl->Release (namespace);
release_locator:
locator->lpVtbl->Release (locator);
SysFreeString (namespaceName);
exit:
if (result == NULL)
{
return NULL;
}
return g_string_free (result, FALSE);
}
static char *read_os_name (IWbemClassObject *object)
{
HRESULT hr;
VARIANT caption_variant;
char *caption_utf8;
hr = object->lpVtbl->Get (object, L"Caption", 0, &caption_variant, NULL, NULL);
if (FAILED (hr))
{
return NULL;
}
caption_utf8 = bstr_to_utf8 (caption_variant.bstrVal);
VariantClear(&caption_variant);
if (caption_utf8 == NULL)
{
return NULL;
}
g_strchomp (caption_utf8);
return caption_utf8;
}
static char *read_cpu_info (IWbemClassObject *object)
{
HRESULT hr;
VARIANT name_variant;
char *name_utf8;
VARIANT max_clock_speed_variant;
guint cpu_freq_mhz;
char *result;
hr = object->lpVtbl->Get (object, L"Name", 0, &name_variant, NULL, NULL);
if (FAILED (hr))
{
return NULL;
}
name_utf8 = bstr_to_utf8 (name_variant.bstrVal);
VariantClear (&name_variant);
if (name_utf8 == NULL)
{
return NULL;
}
hr = object->lpVtbl->Get (object, L"MaxClockSpeed", 0, &max_clock_speed_variant, NULL, NULL);
if (FAILED (hr))
{
g_free (name_utf8);
return NULL;
}
cpu_freq_mhz = max_clock_speed_variant.uintVal;
VariantClear (&max_clock_speed_variant);
if (cpu_freq_mhz > 1000)
{
result = g_strdup_printf ("%s (%.2f GHz)", name_utf8, cpu_freq_mhz / 1000.f);
}
else
{
result = g_strdup_printf ("%s (%" G_GUINT32_FORMAT " MHz)", name_utf8, cpu_freq_mhz);
}
g_free (name_utf8);
return result;
}
static char *read_vga_name (IWbemClassObject *object)
{
HRESULT hr;
VARIANT name_variant;
char *name_utf8;
hr = object->lpVtbl->Get (object, L"Name", 0, &name_variant, NULL, NULL);
if (FAILED (hr))
{
return NULL;
}
name_utf8 = bstr_to_utf8 (name_variant.bstrVal);
VariantClear (&name_variant);
if (name_utf8 == NULL)
{
return NULL;
}
return name_utf8;
}
static char *read_hdd_info (IWbemClassObject *object)
{
HRESULT hr;
VARIANT name_variant;
BSTR name_bstr;
gsize name_len;
VARIANT capacity_variant;
guint64 capacity;
VARIANT free_space_variant;
guint64 free_space;
hr = object->lpVtbl->Get (object, L"Name", 0, &name_variant, NULL, NULL);
if (FAILED (hr))
{
return NULL;
}
name_bstr = name_variant.bstrVal;
name_len = SysStringLen (name_variant.bstrVal);
if (name_len >= 4 && name_bstr[0] == L'\\' && name_bstr[1] == L'\\' && name_bstr[2] == L'?' && name_bstr[3] == L'\\')
{
// This is not a named volume. Skip it.
VariantClear (&name_variant);
return NULL;
}
VariantClear (&name_variant);
hr = object->lpVtbl->Get (object, L"Capacity", 0, &capacity_variant, NULL, NULL);
if (FAILED (hr))
{
return NULL;
}
capacity = variant_to_uint64 (&capacity_variant);
VariantClear (&capacity_variant);
if (capacity == 0)
{
return NULL;
}
hr = object->lpVtbl->Get (object, L"FreeSpace", 0, &free_space_variant, NULL, NULL);
if (FAILED (hr))
{
return NULL;
}
free_space = variant_to_uint64 (&free_space_variant);
VariantClear (&free_space_variant);
if (free_space == 0)
{
return NULL;
}
hdd_capacity += capacity;
hdd_free_space += free_space;
return NULL;
}
static char *get_memory_info (void)
{
MEMORYSTATUSEX meminfo = { 0 };
meminfo.dwLength = sizeof (meminfo);
if (!GlobalMemoryStatusEx (&meminfo))
{
return NULL;
}
return g_strdup_printf ("%" G_GUINT64_FORMAT " MB Total (%" G_GUINT64_FORMAT " MB Free)", meminfo.ullTotalPhys / 1024 / 1024, meminfo.ullAvailPhys / 1024 / 1024);
}
static char *bstr_to_utf8 (BSTR bstr)
{
return g_utf16_to_utf8 (bstr, SysStringLen (bstr), NULL, NULL, NULL);
}
static guint64 variant_to_uint64 (VARIANT *variant)
{
switch (V_VT (variant))
{
case VT_UI8:
return variant->ullVal;
case VT_BSTR:
return wcstoull (variant->bstrVal, NULL, 10);
default:
return 0;
}
}

View File

@ -1,7 +1,6 @@
/* /*
* xsys.h - X-Sys general parameters header * SysInfo - sysinfo plugin for HexChat
* Copyright (C) 2005 Gustavo Zacarias * Copyright (c) 2015 Patrick Griffis.
* Copyright (C) 2006, 2007 Tony Vroon
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -19,14 +18,12 @@
*/ */
#ifndef _XSYS_H_ #ifndef SYSINFO_H
#define _XSYS_H_ #define SYSINFO_H
#define bsize 1024 #define bsize 1024
#define delims ":=" #define DEFAULT_PCIIDS "/usr/share/hwdata/pci.ids"
int sysinfo_get_percent (); int sysinfo_get_str_pref (const char *name, char *dest);
void sysinfo_get_pciids (char *dest);
void sysinfo_print_error (const char* msg);
#endif #endif

View File

@ -31,7 +31,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SYSINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SYSINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\src\common;$(DepsRoot)\include;$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\src\common;$(DepsRoot)\include;$(Glib);$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType> <TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
</ClCompile> </ClCompile>
<Link> <Link>
@ -44,7 +44,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <ClCompile>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;SYSINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;SYSINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\src\common;$(DepsRoot)\include;$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\src\common;$(DepsRoot)\include;$(Glib);$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType> <TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
</ClCompile> </ClCompile>
<Link> <Link>
@ -58,7 +58,14 @@
<None Include="sysinfo.def" /> <None Include="sysinfo.def" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="format.c" />
<ClCompile Include="sysinfo.c" /> <ClCompile Include="sysinfo.c" />
<ClCompile Include="win32\backend.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="format.h" />
<ClInclude Include="sysinfo-backend.h" />
<ClInclude Include="sysinfo.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project> </Project>

View File

@ -9,6 +9,9 @@
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter> </Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{c873eb6b-aca6-434d-8ec9-199838b80838}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="sysinfo.def"> <None Include="sysinfo.def">
@ -19,5 +22,22 @@
<ClCompile Include="sysinfo.c"> <ClCompile Include="sysinfo.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="win32\backend.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="format.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="sysinfo.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="sysinfo-backend.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="format.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -0,0 +1,170 @@
/*
* SysInfo - sysinfo plugin for HexChat
* Copyright (c) 2015 Patrick Griffis.
*
* 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 St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <glib.h>
#include "parse.h"
#include "match.h"
#include "sysinfo.h"
#include "format.h"
#include "df.h"
char *sysinfo_backend_get_os(void)
{
char name[bsize];
if (xs_parse_distro (name) != 0)
{
return NULL;
}
return g_strdup(name);
}
char *sysinfo_backend_get_disk(void)
{
gint64 total, free;
if (xs_parse_df (&total, &free))
{
return NULL;
}
return sysinfo_format_disk (total, free);
}
char *sysinfo_backend_get_memory(void)
{
unsigned long long mem_total;
unsigned long long mem_free;
unsigned long long swap_total;
unsigned long long swap_free;
char *swap_fmt = NULL, *mem_fmt, *ret;
if (xs_parse_meminfo (&mem_total, &mem_free, 0) == 1)
{
return NULL;
}
if (xs_parse_meminfo (&swap_total, &swap_free, 1) != 1)
{
swap_fmt = sysinfo_format_memory (swap_total, swap_free);
}
mem_fmt = sysinfo_format_memory (mem_total, mem_free);
if (swap_fmt)
{
ret = g_strdup_printf ("Physical: %s Swap: %s", mem_fmt, swap_fmt);
g_free (mem_fmt);
g_free (swap_fmt);
}
else
ret = mem_fmt;
return ret;
}
char *sysinfo_backend_get_cpu(void)
{
char model[bsize];
char vendor[bsize];
char buffer[bsize];
double freq;
int giga = 0;
if (xs_parse_cpu (model, vendor, &freq) != 0)
{
return NULL;
}
if (freq > 1000)
{
freq /= 1000;
giga = 1;
}
if (giga)
{
g_snprintf (buffer, bsize, "%s (%.2fGHz)", model, freq);
}
else
{
g_snprintf (buffer, bsize, "%s (%.0fMHz)", model, freq);
}
return g_strdup (buffer);
}
char *sysinfo_backend_get_gpu(void)
{
char vid_card[bsize];
char agp_bridge[bsize];
char buffer[bsize];
int ret;
if ((ret = xs_parse_video (vid_card)) != 0)
{
return NULL;
}
if (xs_parse_agpbridge (agp_bridge) != 0)
{
g_snprintf (buffer, bsize, "%s", vid_card);
}
else
{
g_snprintf (buffer, bsize, "%s @ %s", vid_card, agp_bridge);
}
return g_strdup (buffer);
}
char *sysinfo_backend_get_sound(void)
{
char sound[bsize];
if (xs_parse_sound (sound) != 0)
{
return NULL;
}
return g_strdup (sound);
}
char *sysinfo_backend_get_uptime(void)
{
guint64 uptime;
if ((uptime = xs_parse_uptime ()) == 0)
{
return NULL;
}
return sysinfo_format_uptime (uptime);
}
char *sysinfo_backend_get_network(void)
{
char ethernet_card[bsize];
if (xs_parse_ether (ethernet_card))
{
g_strlcpy (ethernet_card, "None found", bsize);
}
return g_strdup (ethernet_card);
}

View File

@ -0,0 +1,98 @@
/*
* match.c - matching functions for X-Sys
* Copyright (C) 2005, 2006, 2007 Tony Vroon
*
* 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 St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include "sysinfo.h"
#define delims ":="
void find_match_char(char *buffer, char *match, char *result)
{
char *position;
g_strchug(buffer);
if(strstr(buffer, match) == strstr(buffer, buffer))
{
position = strpbrk(buffer, delims);
if (position != NULL)
{
position += 1;
strcpy(result, position);
position = strstr(result, "\n");
*(position) = '\0';
g_strchug(result);
}
else
strcpy(result, "\0");
}
}
void find_match_double(char *buffer, char *match, double *result)
{
char *position;
g_strchug(buffer);
if(strstr(buffer, match) == strstr(buffer, buffer))
{
position = strpbrk(buffer, delims);
if (position != NULL)
{
position += 1;
*result = strtod(position, NULL);
}
else
*result = 0;
}
}
void find_match_double_hex(char *buffer, char *match, double *result)
{
char *position;
g_strchug(buffer);
if(strstr(buffer, match) == strstr(buffer, buffer))
{
position = strpbrk(buffer, delims);
if (position != NULL)
{
memcpy(position,"0x",2);
*result = strtod(position,NULL);
}
else
*result = 0;
}
}
void find_match_ll(char *buffer, char *match, unsigned long long *result)
{
char *position;
g_strchug(buffer);
if(strstr(buffer, match) == strstr(buffer, buffer))
{
position = strpbrk(buffer, delims);
if (position != NULL)
{
position += 1;
*result = strtoll(position, NULL, 10);
}
else
*result = 0;
}
}

View File

@ -23,13 +23,7 @@
void find_match_char(char *buffer, char *match, char *result); void find_match_char(char *buffer, char *match, char *result);
void find_match_double(char *buffer, char *match, double *result); void find_match_double(char *buffer, char *match, double *result);
void find_match_double_hex(char *buffer, char *match, double *result); void find_match_double_hex(char *buffer, char *match, double *result);
void find_match_int(char *buffer, char *match, unsigned int *result);
void find_match_ll(char *buffer, char *match, unsigned long long *result); void find_match_ll(char *buffer, char *match, unsigned long long *result);
void format_output(const char *arg, char *string, char *format);
void flat_format_output(const char *arg, char *string, char *format);
float percentage(unsigned long long *free, unsigned long long *total);
char *pretty_freespace(const char *desc, unsigned long long *free_k, unsigned long long *total_k);
void remove_leading_whitespace(char *buffer); void remove_leading_whitespace(char *buffer);
char *decruft_filename(char *buffer);
#endif #endif

View File

@ -23,20 +23,19 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <sys/utsname.h>
#include <unistd.h>
#include <time.h>
#include <dirent.h>
#include <sys/types.h>
#include <pci/header.h> #include <pci/header.h>
#include <glib.h> #include <glib.h>
#ifdef __sparc__
#include <dirent.h>
#endif
#include "pci.h" #include "pci.h"
#include "match.h" #include "match.h"
#include "xsys.h"
#include "parse.h" #include "parse.h"
#include "sysinfo.h"
int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned int *count) int xs_parse_cpu(char *model, char *vendor, double *freq)
{ {
#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || defined(__alpha__) || defined(__ia64__) || defined(__parisc__) || defined(__sparc__) #if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || defined(__alpha__) || defined(__ia64__) || defined(__parisc__) || defined(__sparc__)
char buffer[bsize]; char buffer[bsize];
@ -48,19 +47,13 @@ int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned
if(fp == NULL) if(fp == NULL)
return 1; return 1;
*count = 0;
strcpy(cache,"unknown\0");
#if defined(__i386__) || defined(__x86_64__) #if defined(__i386__) || defined(__x86_64__)
while(fgets(buffer, bsize, fp) != NULL) while(fgets(buffer, bsize, fp) != NULL)
{ {
find_match_char(buffer, "model name", model); find_match_char(buffer, "model name", model);
find_match_char(buffer, "vendor_id", vendor); find_match_char(buffer, "vendor_id", vendor);
find_match_double(buffer, "cpu MHz", freq); find_match_double(buffer, "cpu MHz", freq);
find_match_char(buffer, "cache size", cache);
find_match_int(buffer, "processor", count);
} }
*count = *count + 1;
#endif #endif
#ifdef __powerpc__ #ifdef __powerpc__
while(fgets(buffer, bsize, fp) != NULL) while(fgets(buffer, bsize, fp) != NULL)
@ -68,10 +61,7 @@ int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned
find_match_char(buffer, "cpu", model); find_match_char(buffer, "cpu", model);
find_match_char(buffer, "machine", vendor); find_match_char(buffer, "machine", vendor);
find_match_double(buffer, "clock", freq); find_match_double(buffer, "clock", freq);
find_match_char(buffer, "L2 cache", cache);
find_match_int(buffer, "processor", count);
} }
*count = *count + 1;
pos = strstr(model, ","); pos = strstr(model, ",");
if (pos != NULL) *pos = '\0'; if (pos != NULL) *pos = '\0';
#endif #endif
@ -81,8 +71,6 @@ int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned
find_match_char(buffer, "cpu model", model); find_match_char(buffer, "cpu model", model);
find_match_char(buffer, "system type", vendor); find_match_char(buffer, "system type", vendor);
find_match_double(buffer, "cycle frequency [Hz]", freq); find_match_double(buffer, "cycle frequency [Hz]", freq);
find_match_char(buffer, "L2 cache", cache);
find_match_int(buffer, "cpus detected", count);
} }
*freq = *freq / 1000000; *freq = *freq / 1000000;
#endif #endif
@ -92,20 +80,15 @@ int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned
find_match_char(buffer, "model", model); find_match_char(buffer, "model", model);
find_match_char(buffer, "vendor", vendor); find_match_char(buffer, "vendor", vendor);
find_match_double(buffer, "cpu MHz", freq); find_match_double(buffer, "cpu MHz", freq);
find_match_int(buffer, "processor", count);
} }
*count = *count + 1;
#endif #endif
#ifdef __parisc__ #ifdef __parisc__
while(fgets(buffer, bsize, fp) != NULL) while(fgets(buffer, bsize, fp) != NULL)
{ {
find_match_char(buffer, "cpu ", model); find_match_char(buffer, "cpu ", model);
find_match_char(buffer, "cpu family", vendor); find_match_char(buffer, "cpu family", vendor);
find_match_char(buffer, "D-cache", cache);
find_match_double(buffer, "cpu MHz", freq); find_match_double(buffer, "cpu MHz", freq);
find_match_int(buffer, "processor", count);
} }
*count = *count + 1;
#endif #endif
#ifdef __sparc__ #ifdef __sparc__
DIR *dir; DIR *dir;
@ -115,22 +98,8 @@ int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned
{ {
find_match_char(buffer, "cpu ", model); find_match_char(buffer, "cpu ", model);
find_match_char(buffer, "type ", vendor); find_match_char(buffer, "type ", vendor);
find_match_int(buffer, "ncpus active", count);
find_match_double_hex(buffer, "Cpu0ClkTck", freq); find_match_double_hex(buffer, "Cpu0ClkTck", freq);
} }
/* Cache is tricky, only implemented for sparc64 */
if ((dir = opendir("/proc/openprom")) != NULL)
while ((entry = readdir(dir)) != NULL)
if (strncmp(entry->d_name,"SUNW,UltraSPARC",15) == 0)
{
g_snprintf(buffer,bsize,"/proc/openprom/%s/ecache-size",entry->d_name);
fp2 = fopen(buffer, "r");
if (fp2 == NULL) break;
fscanf(fp2,"%16s",cache);
fclose(fp2);
sprintf(buffer,"0x%s",cache);
sprintf(cache,"%0.0f KB",strtod(buffer,NULL)/1024);
}
*freq = *freq / 1000000; *freq = *freq / 1000000;
#endif #endif
fclose(fp); fclose(fp);
@ -138,43 +107,20 @@ int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned
return 0; return 0;
} }
int xs_parse_uptime(int *weeks, int *days, int *hours, int *minutes, int *seconds) guint64 xs_parse_uptime(void)
{ {
char buffer[bsize]; char buffer[bsize];
long long uptime = 0; guint64 uptime = 0;
FILE *fp = fopen("/proc/uptime", "r"); FILE *fp = fopen("/proc/uptime", "r");
if(fp == NULL) if(fp == NULL)
return 1; return 0;
if(fgets(buffer, bsize, fp) != NULL) if(fgets(buffer, bsize, fp) != NULL)
uptime = strtol(buffer, NULL, 0); uptime = strtol(buffer, NULL, 0);
*seconds = uptime%60;
*minutes = (uptime/60)%60;
*hours = (uptime/3600)%24;
*days = (uptime/86400)%7;
*weeks = uptime/604800;
fclose(fp); fclose(fp);
return 0; return uptime;
}
int xs_parse_os(char *user, char *host, char *kernel)
{
struct utsname osinfo;
char hostn[bsize], *usern = getenv("USER");
if(uname(&osinfo)<0)
return 1;
if(gethostname(hostn, bsize)<0)
return 1;
strncpy(user, usern, bsize);
strcpy(host, hostn);
g_snprintf(kernel, bsize, "%s %s %s", osinfo.sysname, osinfo.release, osinfo.machine);
return 0;
} }
int xs_parse_sound(char *snd_card) int xs_parse_sound(char *snd_card)
@ -183,7 +129,8 @@ int xs_parse_sound(char *snd_card)
u16 class = PCI_CLASS_MULTIMEDIA_AUDIO; u16 class = PCI_CLASS_MULTIMEDIA_AUDIO;
FILE *fp = NULL; FILE *fp = NULL;
if((fp = fopen("/proc/asound/cards", "r"))== NULL) { if((fp = fopen("/proc/asound/cards", "r"))== NULL)
{
if (pci_find_by_class(&class, vendor, device) == 0) if (pci_find_by_class(&class, vendor, device) == 0)
{ {
pci_find_fullname(snd_card, vendor, device); pci_find_fullname(snd_card, vendor, device);
@ -251,98 +198,6 @@ int xs_parse_agpbridge(char *agp_bridge)
return 0; return 0;
} }
int xs_parse_netdev(const char *device, unsigned long long *bytes_recv, unsigned long long *bytes_sent)
{
FILE *fp;
char buffer[bsize], *pos;
int i;
fp=fopen("/proc/net/dev", "r");
if(fp==NULL)
return 1;
while(fgets(buffer, bsize, fp) != NULL)
{
for(i=0; isspace(buffer[i]); i++);
if(strncmp(device, &buffer[i], strlen(device)) == 0) break;
}
fclose(fp);
pos = strstr(buffer, ":");
pos++;
*bytes_recv = g_ascii_strtoull (pos, &pos, 0);
for(i=0;i<7;i++) g_ascii_strtoull (pos, &pos, 0);
*bytes_sent = g_ascii_strtoull (pos, NULL, 0);
return 0;
}
int xs_parse_df(const char *mount_point, char *result)
{
FILE *pipe;
char buffer[bsize], *pos;
unsigned long long total_k=0, free_k=0;
int i=0;
pipe = popen("df -k -l -P", "r");
if(pipe==NULL)
return 1;
while(fgets(buffer, bsize, pipe) != NULL)
{
/* Skip over pseudo-filesystems and description line */
if(isalpha(buffer[0]))
continue;
for(pos=buffer; !isspace(*pos); pos++);
for(;isspace(*pos);pos++);
if(mount_point == NULL)
{
total_k += g_ascii_strtoull (pos, &pos, 0);
g_ascii_strtoull(pos, &pos, 0);
free_k += g_ascii_strtoull (pos, &pos, 0);
continue;
}
total_k = g_ascii_strtoull (pos, &pos, 0);
g_ascii_strtoull(pos, &pos, 0);
free_k = g_ascii_strtoull (pos, &pos, 0);
g_ascii_strtoull (pos, &pos, 0);
for(;isspace(*pos);pos++);
for(;*pos!='/';pos++);
for(i=0;*(buffer+i)!='\n';i++);
*(buffer+i)='\0';
if(strncasecmp(mount_point, "ALL", 3)==0)
{
char *tmp_buf = pretty_freespace(pos, &free_k, &total_k);
strcat(tmp_buf, " | ");
strcat(result, tmp_buf);
g_free(tmp_buf);
}
else if(strncmp(mount_point, pos, strlen(mount_point)) == 0)
{
char *tmp_buf = pretty_freespace(mount_point, &free_k, &total_k);
strncpy(result, tmp_buf, bsize);
g_free(tmp_buf);
break;
}
else g_snprintf(result, bsize, "Mount point %s not found!", mount_point);
}
if(mount_point != NULL && strncasecmp(mount_point, "ALL", 3)==0)
*(result+strlen(result)-3) = '\0';
if(mount_point == NULL)
{
char *tmp_buf = pretty_freespace("Total", &free_k, &total_k);
strncpy(result, tmp_buf, bsize);
g_free(tmp_buf);
}
pclose(pipe);
return 0;
}
int xs_parse_meminfo(unsigned long long *mem_tot, unsigned long long *mem_free, int swap) int xs_parse_meminfo(unsigned long long *mem_tot, unsigned long long *mem_free, int swap)
{ {
FILE *fp; FILE *fp;
@ -369,10 +224,15 @@ int xs_parse_meminfo(unsigned long long *mem_tot, unsigned long long *mem_free,
find_match_ll(buffer, "SwapFree:", mem_free); find_match_ll(buffer, "SwapFree:", mem_free);
} }
} }
if (!swap) { if (!swap)
{
*mem_free = freemem + buffers + cache; *mem_free = freemem + buffers + cache;
} }
fclose(fp); fclose(fp);
/* Convert to bytes */
*mem_free *= 1000;
*mem_tot *= 1000;
return 0; return 0;
} }
@ -429,10 +289,12 @@ int xs_parse_distro(char *name)
} }
else else
g_snprintf(buffer, bsize, "Unknown Distro"); g_snprintf(buffer, bsize, "Unknown Distro");
if(fp != NULL) fclose(fp); if(fp != NULL)
fclose(fp);
pos=strchr(buffer, '\n'); pos=strchr(buffer, '\n');
if(pos != NULL) *pos = '\0'; if(pos != NULL)
*pos = '\0';
strcpy(name, buffer); strcpy(name, buffer);
return 0; return 0;
} }

View File

@ -23,12 +23,9 @@
#ifndef _PARSE_H_ #ifndef _PARSE_H_
#define _PARSE_H_ #define _PARSE_H_
int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned int *count); int xs_parse_cpu(char *model, char *vendor, double *freq);
int xs_parse_uptime(int *weeks, int *days, int *hours, int *minutes, int *seconds); guint64 xs_parse_uptime(void);
int xs_parse_os(char *user, char *host, char *kernel);
int xs_parse_sound(char *snd_card); int xs_parse_sound(char *snd_card);
int xs_parse_netdev(const char *device, unsigned long long *bytes_recv, unsigned long long *bytes_sent);
int xs_parse_df(const char *mount_point, char *string);
int xs_parse_meminfo(unsigned long long *mem_tot, unsigned long long *mem_free, int swap); int xs_parse_meminfo(unsigned long long *mem_tot, unsigned long long *mem_free, int swap);
int xs_parse_video(char *vid_card); int xs_parse_video(char *vid_card);
int xs_parse_agpbridge(char *agp_bridge); int xs_parse_agpbridge(char *agp_bridge);

View File

@ -23,11 +23,10 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <unistd.h>
#include <pci/pci.h> #include <pci/pci.h>
#include <glib.h> #include <glib.h>
#include "xsys.h" #include "sysinfo.h"
static struct pci_filter filter; /* Device filter */ static struct pci_filter filter; /* Device filter */
static struct pci_access *pacc; static struct pci_access *pacc;
@ -53,7 +52,8 @@ static struct device *scan_device(struct pci_dev *p)
d->dev = p; d->dev = p;
if (!pci_read_block(p, 0, d->config, how_much)) if (!pci_read_block(p, 0, d->config, how_much))
exit(1); exit(1);
if (how_much < 128 && (d->config[PCI_HEADER_TYPE] & 0x7f) == PCI_HEADER_TYPE_CARDBUS) { if (how_much < 128 && (d->config[PCI_HEADER_TYPE] & 0x7f) == PCI_HEADER_TYPE_CARDBUS)
{
/* For cardbus bridges, we need to fetch 64 bytes more to get the full standard header... */ /* For cardbus bridges, we need to fetch 64 bytes more to get the full standard header... */
if (!pci_read_block(p, 64, d->config+64, 64)) if (!pci_read_block(p, 64, d->config+64, 64))
exit(1); exit(1);
@ -72,11 +72,14 @@ static void scan_devices(void)
pci_scan_bus(pacc); pci_scan_bus(pacc);
for(p=pacc->devices; p; p=p->next) for(p=pacc->devices; p; p=p->next)
if ((d = scan_device(p))) { {
if ((d = scan_device(p)))
{
d->next = first_dev; d->next = first_dev;
first_dev = d; first_dev = d;
} }
} }
}
static u16 get_conf_word(struct device *d, unsigned int pos) static u16 get_conf_word(struct device *d, unsigned int pos)
{ {
@ -94,10 +97,12 @@ int pci_find_by_class(u16 *class, char *vendor, char *device)
pci_init(pacc); pci_init(pacc);
scan_devices(); scan_devices();
for(d=first_dev; d; d=d->next) { for(d=first_dev; d; d=d->next)
{
p = d->dev; p = d->dev;
/* Acquire vendor & device ID if the class matches */ /* Acquire vendor & device ID if the class matches */
if(get_conf_word(d, PCI_CLASS_DEVICE) == *class) { if(get_conf_word(d, PCI_CLASS_DEVICE) == *class)
{
nomatch = 0; nomatch = 0;
g_snprintf(vendor,7,"%04x",p->vendor_id); g_snprintf(vendor,7,"%04x",p->vendor_id);
g_snprintf(device,7,"%04x",p->device_id); g_snprintf(device,7,"%04x",p->device_id);
@ -118,17 +123,21 @@ void pci_find_fullname(char *fullname, char *vendor, char *device)
int cardfound = 0; int cardfound = 0;
FILE *fp; FILE *fp;
sysinfo_get_pciids (buffer); if (!sysinfo_get_str_pref ("pciids", buffer))
fp = fopen (buffer, "r"); strcpy (buffer, DEFAULT_PCIIDS);
if(fp == NULL) { fp = fopen (buffer, "r");
if(fp == NULL)
{
g_snprintf(fullname, bsize, "%s:%s", vendor, device); g_snprintf(fullname, bsize, "%s:%s", vendor, device);
sysinfo_print_error ("pci.ids file not found! You might want to adjust your pciids setting with /SYSINFO SET pciids (you can query its current value with /SYSINFO LIST).\n"); //sysinfo_print_error ("pci.ids file not found! You might want to adjust your pciids setting with /SYSINFO SET pciids (you can query its current value with /SYSINFO LIST).\n");
return; return;
} }
while(fgets(buffer, bsize, fp) != NULL) { while(fgets(buffer, bsize, fp) != NULL)
if (!isspace(buffer[0]) && strstr(buffer, vendor) != NULL) { {
if (!isspace(buffer[0]) && strstr(buffer, vendor) != NULL)
{
position = strstr(buffer, vendor); position = strstr(buffer, vendor);
position += 6; position += 6;
strncpy(vendorname, position, bsize/2); strncpy(vendorname, position, bsize/2);
@ -137,8 +146,10 @@ void pci_find_fullname(char *fullname, char *vendor, char *device)
break; break;
} }
} }
while(fgets(buffer, bsize, fp) != NULL) { while(fgets(buffer, bsize, fp) != NULL)
if(strstr(buffer, device) != NULL) { {
if(strstr(buffer, device) != NULL)
{
position = strstr(buffer, device); position = strstr(buffer, device);
position += 6; position += 6;
strncpy(devicename, position, bsize/2); strncpy(devicename, position, bsize/2);

View File

@ -0,0 +1,493 @@
/* HexChat
* Copyright (c) 2011-2012 Berke Viktor.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdio.h>
#include <windows.h>
#include <wbemidl.h>
#include <glib.h>
#include "../format.h"
/* Cache the info for subsequent invocations of /SYSINFO */
static int cpu_arch = 0;
static char *os_name = NULL;
static char *cpu_info = NULL;
static char *vga_name = NULL;
static int command_callback (char *word[], char *word_eol[], void *user_data);
typedef enum
{
QUERY_WMI_OS,
QUERY_WMI_CPU,
QUERY_WMI_VGA,
QUERY_WMI_HDD,
} QueryWmiType;
void print_info (void);
int get_cpu_arch (void);
char *query_wmi (QueryWmiType mode);
char *read_os_name (IWbemClassObject *object);
char *read_cpu_info (IWbemClassObject *object);
char *read_vga_name (IWbemClassObject *object);
guint64 hdd_capacity;
guint64 hdd_free_space;
char *read_hdd_info (IWbemClassObject *object);
char *get_memory_info (void);
char *bstr_to_utf8 (BSTR bstr);
guint64 variant_to_uint64 (VARIANT *variant);
char *
sysinfo_backend_get_sound (void)
{
return NULL;
}
char *
sysinfo_backend_get_network (void)
{
return NULL;
}
char *
sysinfo_backend_get_uptime (void)
{
return sysinfo_format_uptime (GetTickCount64 () / 1000);
}
char *
sysinfo_backend_get_disk (void)
{
char *hdd_info;
/* HDD information is always loaded dynamically since it includes the current amount of free space */
hdd_capacity = 0;
hdd_free_space = 0;
hdd_info = query_wmi (QUERY_WMI_HDD);
if (hdd_info)
return sysinfo_format_disk (hdd_capacity, hdd_free_space);
return NULL;
}
char *
sysinfo_backend_get_cpu (void)
{
if (cpu_info == NULL)
cpu_info = query_wmi (QUERY_WMI_CPU);
return g_strdup (cpu_info);
}
char *
sysinfo_backend_get_memory (void)
{
/* Memory information is always loaded dynamically since it includes the current amount of free memory */
return get_memory_info ();
}
char *
sysinfo_backend_get_gpu (void)
{
if (vga_name == NULL)
vga_name = query_wmi (QUERY_WMI_VGA);
return g_strdup (vga_name);
}
char *
sysinfo_backend_get_os (void)
{
if (os_name == NULL)
os_name = query_wmi (QUERY_WMI_OS);
if (cpu_arch == 0)
cpu_arch = get_cpu_arch ();
return g_strdup_printf ("%s (x%d)", os_name, cpu_arch);
}
static int get_cpu_arch (void)
{
SYSTEM_INFO si;
GetNativeSystemInfo (&si);
if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
{
return 64;
}
else
{
return 86;
}
}
/* http://msdn.microsoft.com/en-us/site/aa390423 */
static char *query_wmi (QueryWmiType type)
{
GString *result = NULL;
HRESULT hr;
IWbemLocator *locator = NULL;
BSTR namespaceName = NULL;
BSTR queryLanguageName = NULL;
BSTR query = NULL;
IWbemServices *namespace = NULL;
IUnknown *namespaceUnknown = NULL;
IEnumWbemClassObject *enumerator = NULL;
int i;
gboolean atleast_one_appended = FALSE;
hr = CoCreateInstance (&CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, &IID_IWbemLocator, (LPVOID *) &locator);
if (FAILED (hr))
{
goto exit;
}
namespaceName = SysAllocString (L"root\\CIMV2");
hr = locator->lpVtbl->ConnectServer (locator, namespaceName, NULL, NULL, NULL, 0, NULL, NULL, &namespace);
if (FAILED (hr))
{
goto release_locator;
}
hr = namespace->lpVtbl->QueryInterface (namespace, &IID_IUnknown, &namespaceUnknown);
if (FAILED (hr))
{
goto release_namespace;
}
hr = CoSetProxyBlanket (namespaceUnknown, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
if (FAILED (hr))
{
goto release_namespaceUnknown;
}
queryLanguageName = SysAllocString (L"WQL");
switch (type)
{
case QUERY_WMI_OS:
query = SysAllocString (L"SELECT Caption FROM Win32_OperatingSystem");
break;
case QUERY_WMI_CPU:
query = SysAllocString (L"SELECT Name, MaxClockSpeed FROM Win32_Processor");
break;
case QUERY_WMI_VGA:
query = SysAllocString (L"SELECT Name FROM Win32_VideoController");
break;
case QUERY_WMI_HDD:
query = SysAllocString (L"SELECT Name, Capacity, FreeSpace FROM Win32_Volume");
break;
default:
goto release_queryLanguageName;
}
hr = namespace->lpVtbl->ExecQuery (namespace, queryLanguageName, query, WBEM_FLAG_FORWARD_ONLY, NULL, &enumerator);
if (FAILED (hr))
{
goto release_query;
}
result = g_string_new ("");
for (i = 0;; i++)
{
ULONG numReturned = 0;
IWbemClassObject *object;
char *line;
hr = enumerator->lpVtbl->Next (enumerator, WBEM_INFINITE, 1, &object, &numReturned);
if (FAILED (hr) || numReturned == 0)
{
break;
}
switch (type)
{
case QUERY_WMI_OS:
line = read_os_name (object);
break;
case QUERY_WMI_CPU:
line = read_cpu_info (object);
break;
case QUERY_WMI_VGA:
line = read_vga_name (object);
break;
case QUERY_WMI_HDD:
line = read_hdd_info (object);
break;
default:
break;
}
object->lpVtbl->Release (object);
if (line != NULL)
{
if (atleast_one_appended)
{
g_string_append (result, ", ");
}
g_string_append (result, line);
g_free (line);
atleast_one_appended = TRUE;
}
}
enumerator->lpVtbl->Release (enumerator);
release_query:
SysFreeString (query);
release_queryLanguageName:
SysFreeString (queryLanguageName);
release_namespaceUnknown:
namespaceUnknown->lpVtbl->Release (namespaceUnknown);
release_namespace:
namespace->lpVtbl->Release (namespace);
release_locator:
locator->lpVtbl->Release (locator);
SysFreeString (namespaceName);
exit:
if (result == NULL)
{
return NULL;
}
return g_string_free (result, FALSE);
}
static char *read_os_name (IWbemClassObject *object)
{
HRESULT hr;
VARIANT caption_variant;
char *caption_utf8;
hr = object->lpVtbl->Get (object, L"Caption", 0, &caption_variant, NULL, NULL);
if (FAILED (hr))
{
return NULL;
}
caption_utf8 = bstr_to_utf8 (caption_variant.bstrVal);
VariantClear(&caption_variant);
if (caption_utf8 == NULL)
{
return NULL;
}
g_strchomp (caption_utf8);
return caption_utf8;
}
static char *read_cpu_info (IWbemClassObject *object)
{
HRESULT hr;
VARIANT name_variant;
char *name_utf8;
VARIANT max_clock_speed_variant;
guint cpu_freq_mhz;
char *result;
hr = object->lpVtbl->Get (object, L"Name", 0, &name_variant, NULL, NULL);
if (FAILED (hr))
{
return NULL;
}
name_utf8 = bstr_to_utf8 (name_variant.bstrVal);
VariantClear (&name_variant);
if (name_utf8 == NULL)
{
return NULL;
}
hr = object->lpVtbl->Get (object, L"MaxClockSpeed", 0, &max_clock_speed_variant, NULL, NULL);
if (FAILED (hr))
{
g_free (name_utf8);
return NULL;
}
cpu_freq_mhz = max_clock_speed_variant.uintVal;
VariantClear (&max_clock_speed_variant);
if (cpu_freq_mhz > 1000)
{
result = g_strdup_printf ("%s (%.2fGHz)", name_utf8, cpu_freq_mhz / 1000.f);
}
else
{
result = g_strdup_printf ("%s (%" G_GUINT32_FORMAT "MHz)", name_utf8, cpu_freq_mhz);
}
g_free (name_utf8);
return result;
}
static char *read_vga_name (IWbemClassObject *object)
{
HRESULT hr;
VARIANT name_variant;
char *name_utf8;
hr = object->lpVtbl->Get (object, L"Name", 0, &name_variant, NULL, NULL);
if (FAILED (hr))
{
return NULL;
}
name_utf8 = bstr_to_utf8 (name_variant.bstrVal);
VariantClear (&name_variant);
if (name_utf8 == NULL)
{
return NULL;
}
return name_utf8;
}
static char *read_hdd_info (IWbemClassObject *object)
{
HRESULT hr;
VARIANT name_variant;
BSTR name_bstr;
gsize name_len;
VARIANT capacity_variant;
guint64 capacity;
VARIANT free_space_variant;
guint64 free_space;
hr = object->lpVtbl->Get (object, L"Name", 0, &name_variant, NULL, NULL);
if (FAILED (hr))
{
return NULL;
}
name_bstr = name_variant.bstrVal;
name_len = SysStringLen (name_variant.bstrVal);
if (name_len >= 4 && name_bstr[0] == L'\\' && name_bstr[1] == L'\\' && name_bstr[2] == L'?' && name_bstr[3] == L'\\')
{
// This is not a named volume. Skip it.
VariantClear (&name_variant);
return NULL;
}
VariantClear (&name_variant);
hr = object->lpVtbl->Get (object, L"Capacity", 0, &capacity_variant, NULL, NULL);
if (FAILED (hr))
{
return NULL;
}
capacity = variant_to_uint64 (&capacity_variant);
VariantClear (&capacity_variant);
if (capacity == 0)
{
return NULL;
}
hr = object->lpVtbl->Get (object, L"FreeSpace", 0, &free_space_variant, NULL, NULL);
if (FAILED (hr))
{
return NULL;
}
free_space = variant_to_uint64 (&free_space_variant);
VariantClear (&free_space_variant);
if (free_space == 0)
{
return NULL;
}
hdd_capacity += capacity;
hdd_free_space += free_space;
return NULL;
}
static char *get_memory_info (void)
{
MEMORYSTATUSEX meminfo = { 0 };
meminfo.dwLength = sizeof (meminfo);
if (!GlobalMemoryStatusEx (&meminfo))
{
return NULL;
}
return sysinfo_format_memory (meminfo.ullTotalPhys, meminfo.ullAvailPhys);
}
static char *bstr_to_utf8 (BSTR bstr)
{
return g_utf16_to_utf8 (bstr, SysStringLen (bstr), NULL, NULL, NULL);
}
static guint64 variant_to_uint64 (VARIANT *variant)
{
switch (V_VT (variant))
{
case VT_UI8:
return variant->ullVal;
case VT_BSTR:
return wcstoull (variant->bstrVal, NULL, 10);
default:
return 0;
}
}

View File

@ -1,116 +0,0 @@
v2.2.0
* (Thomas Cort) Report L2 cache info for Alpha CPUs
* (Tony Vroon) Drop XMMS, port audacious features to D-Bus, make dependency mandatory
* (Tony Vroon) Use pretty_freespace for memory & swap reporting as well as disk space
* (Tony Vroon) Make pretty_freespace report none if total_size is 0, thanks to Emopig <andrew@nelless.net> for the report
* (Tony Vroon) Make pretty_freespace aware of terabytes, petabytes, exabytes, zettabytes & yottabytes
* (Tony Vroon) Remove xchatdirfs workaround
v2.1.0
Removals & pending removal:
* (Tony Vroon) Remove support for BMP, it is an abandoned project. Suggested upgrade path: audacious
* (Tony Vroon) Remove /uname & /euname; the OS part of sysinfo displays similar info without requiring a process pipe
* (Tony Vroon) Added a note that the xchatdirfs workaround is due for removal as X-Chat Gnome has fixed the bug
Bugfixes:
* (Tony Vroon) Actually show the vendor that we retrieve in cpuinfo
* (Tony Vroon) Display Gentoo Linux as stable or ~arch, the baselayout version doesn't really interest anyone
* (Tony Vroon) Match framework: Make remove_leading_whitespace actually work
* (Tony Vroon) Match framework: Do not assume that a delimiter is always followed by a space
Code improvements:
* (Tony Vroon) PCI framework: We were requesting more info then we actually return to the caller
* (Tony Vroon) Match framework: Consolidate delimiters in a single define & use 1 strpbrk instead of 2 strstr's
* (Tony Vroon) Display the machine string instead of the pmac-generation as vendor info for PPC machines
New features
* (Tony Vroon) Show memory capacity in gigabytes instead of in megabytes when appropriate
* (Tony Vroon) Cut cpu name at comma (so overly long other info such as "altivec supported" is no longer displayed)
* (Tony Vroon) Now Playing: Report time played as well as the song length
* (Tony Vroon) Now Playing: Support reporting as an action; configurable at runtime
* (Tony Vroon) Check LSB release data, prefer above all others; based on a code sample submitted by Thomas Winwood
v2.0.9
* (Tony Vroon) Protect the matching framework against spurious matches (bug reported by Harm Geerts)
* (Tony Vroon) Unexporting unnecessary symbols for PCI framework
* (Tony Vroon) Deal with incompatible header changes in pciutils
* (Tony Vroon) Begin implementing hardware monitoring support, not yet activated
* (Tony Vroon) Add support for Audacious, a BMP fork
v2.0.8
* (Tony Vroon) Make XMMS interface actually work, thanks to a patch from Morten Cools
* (Tony Vroon) Use percentages for df information as well
* (Gustavo Zacarias) Add support for Sparc architecture, cache size detection on sparc64 only
* (Gustavo Zacarias) Consolidate buffer sizes into a single define
v2.0.7
* (Tony Vroon) Have df parser ignore pseudo-filesystems; deal with other locales more gracefully
* (Tony Vroon) Change default formatstring not to use mIRC color codes
* (Tony Vroon) Add fallback to ~/.xchat2 for xchat-gnome which does not report xchatdirfs properly
* (Tony Vroon) Revert to beepctrl.h style calls as infopipe is too unreliable
v2.0.6
* (Tony Vroon) Rewrote PCI framework, no longer depends on sysfs, kernel 2.4 and lower will work now
* (Tony Vroon) Made percentages configurable, can be set at runtime (feature request by Halcy0n)
* (Tony Vroon) Abstract out all pointer voodoo from xsys.c
* (Tony Vroon) Do not return XCHAT_EAT_NONE, causes spurious "unknown command" errors
* (Tony Vroon) Deal more gracefully with a missing soundcard or unknown linux distribution
* (Tony Vroon) Add error handling to the matching framework
v2.0.5
* (Tony Vroon) Added support for parisc/hppa & ia64 architectures
* (Tony Vroon) Proper report of L2 cache as "unknown" instead of showing bits of unitialized memory
* (Tony Vroon) Upped PCI parser yield for ppc64 architecture, has high bus number for AGP card
* (Tony Vroon) Use percentages in memory/swap information
v2.0.4
* (Tony Vroon) /sound uses ALSA if possible, PCI now fallback (false positives reported with PCI code)
* (Tony Vroon) Remove 0 prefix from first ALSA card; 1: and up will be shown for extra cards
* (Tony Vroon) Matching code rewritten and separated out from other code
* (Tony Vroon) Use new matching framework where possible
* (Tony Vroon) Added support for Alpha architecture, thanks to Bert (bert@ev6.net)
v2.0.3
* (Tony Vroon) Fix buttons, XMMS -> NP
* (Tony Vroon) PCI functions separated out from other code; fully rewritten
* (Tony Vroon) Use new PCI framework for sound detection; ALSA is now fallback
* (Tony Vroon) Implement /ether
* (Tony Vroon) /video now reports video card @ AGP bridge; resolution info dropped
v2.0.2
* (Tony Vroon) XMMS/BMP: Delete XMMS/BMP detection; it just got obsoleted by a BMP bugfix
* (Tony Vroon) XMMS/BMP: Change to /np & /enp as commands (np -> now playing)
* (Tony Vroon) Allow customization of now_playing with /playing
* (Tony Vroon) Separate out the length field for now_playing
* (Tony Vroon) Better configuration file handling
* (Tony Vroon) Set homepage to http://dev.gentoo.org/~chainsaw/xsys
* (Tony Vroon) Make channel buttons optional, not everyone appreciates them
* (Tony Vroon) Fix cpuinfo parsing on x86_64, a necessary define was missing
v2.0.1
* (Tony Vroon) XMMS/BMP: Report "stream" if song length is -1
* (Tony Vroon) XMMS/BMP: Determine whether XMMS or BMP is playing
* (Tony Vroon) Better errorhandling if pci.ids parsing fails; at least mention raw PCI ID of card
* (Tony Vroon) Remove AGP from video card messages; we detect plain PCI cards too
* (Tony Vroon) Fix Debian release detector
v2.0.0
* (mikeshoup) Clean up of code for 2.0.0 release
* (Tony Vroon) Added PowerPC /proc/cpuinfo support
* (Tony Vroon) Changed LSPCI to SYSFS
v1.9.3
* (mikeshoup) Introduced distro function
* (mikeshoup, Tony Vroon's suggestion) Removed bitrate from /XMMS
v1.9.2
* 2005/01/14 (mikeshoup) Put in the userlist buttons
* 2005/01/10 (mikeshoup) Added XMMS/BMP Support
v1.9.1
* 2004/12/20 (mikeshoup) Added a dynamic formatting scheme
* 2004/12/19 (mikeshoup) Changed some commands
* 2004/12/18 (mikeshoup) Reintroducted /VIDEO
v1.9.0
* 2004/12/17 (mikeshoup) Initial Release

View File

@ -1,15 +0,0 @@
INSTALLATION
============
Installation is straightforward. You need Audacious 1.4 or higher and D-Bus.
Open up the Makefile, check to make sure PCIIDS points to your pci.ids file.
(Symptom if you get it wrong: raw PCI ID's (XXXX:XXXX) emitted by /VIDEO and friends).
Run: make
Run: make install
Voila!
NOTES:
`make install' copies the compiled library (something like xsys-v.v.v.so) to
$HOME/.xchat2/xsys-plugin.so for autoloading. If $HOME/.xchat2/xsys-plugin.so
exists, it is removed first.

View File

@ -1,38 +0,0 @@
#### SET THIS VALUE TO THE LOCATION OF THE `pci.ids` file ####
PCIIDS = /usr/share/misc/pci.ids
#### UNCOMMENT THIS IF YOU WANT THE BUTTONS ####
#BUTTON = -Dbuttonbar
#### SHOULD NOT NEED TO EDIT BELOW THIS LINE ####
VER_MAJOR = 2
VER_MINOR = 2
VER_PATCH = 0
CC = gcc
CFLAGS += -O2 -Wall -fPIC
CFLAGS += -DVER_MINOR=$(VER_MINOR) -DVER_MAJOR=$(VER_MAJOR) -DVER_PATCH=$(VER_PATCH) \
-DVER_STRING=\"$(VER_MAJOR).$(VER_MINOR).$(VER_PATCH)\" -DPCIIDS=\"$(PCIIDS)\" $(BUTTON)
LDFLAGS = $(CFLAGS) -shared
LIBRARY = xsys-$(VER_MAJOR).$(VER_MINOR).$(VER_PATCH).so
OBJECTS = xsys.o parse.o pci.o match.o hwmon.o
ALL : $(LIBRARY)
$(LIBRARY) : $(OBJECTS)
$(CC) $(LDFLAGS) -o $(LIBRARY) $(OBJECTS) -lpci
xsys.o : xsys.c
parse.o : parse.c
pci.o : pci.c
match.o : match.c
hwmon.o : hwmon.c
.PHONY : clean
clean :
rm -rf *.o *.so *~
.PHONY : install
install : $(LIBRARY)
rm -f $(HOME)/.xchat2/xsys-plugin.so
cp ./$(LIBRARY) $(HOME)/.xchat2/xsys-plugin.so

View File

@ -1,105 +0,0 @@
X-Sys README
============
What is X-Sys?
X-Sys is a plugin for X-Chat that allows you to display your current system statistics in
a channel, private conversation or just in an echo to yourself for testing purposes.
It is supported on Linux, running on various architectures. Right now x86, ppc, ppc64, sparc,
sparc64 and alpha are supported, with parisc and ia64 implemented but awaiting testing.
---------------
Who wrote this?
X-Sys is originally a Mike Shoup creation, from the very first alpha releases to the open-source
version 1 releases. But then, things stalled. For a few months (more like a year almost)
Mike didn't work on X-Sys. The last version that had been written was 1.0.5.
The website was gone, and I (Tony) couldn't find Mike. So, I took over and improved it to my liking.
It turned out that Mike was still around, though, he contacted me and started development again,
now called version 2, a complete rewrite. Various 1.9 betas came out that I contributed patches to,
and starting with version 2.0.0 I'm maintaining xchat-xsys again, this time with Mike's blessing.
---------------
What do I need?
- X-Chat (regular or Gnome version)
- Audacious 1.4 or higher
- D-Bus (for communication with Audacious)
- a working toolchain (compiler, binutils, etc).
------------------------------------------------
What if I get errors about u8 not being defined?
Sorry to hear that, it appears your linux distribution neglected to install essential headers on your
system. On Debian & Ubuntu, apt-get install pciutils-dev should make it happy.
========
COMMANDS
X-Sys 2 has the following implemented commands:
/XSYS & /EXSYS - Output current version, either to channel or echoed on screen.
/CPUINFO & /ECPUINFO - Echoes or says current cpu statistics
/SYSUPTIME & /ESYSUPTIME - Echoes or says current uptime
/OSINFO & /EOSINFO - Echoes or says various OS statistics
/SOUND & /ESOUND - Echoes or says the current sound card, as determined by ALSA
/NETDATA & /ENETDATA - Echoes or says total amount transferred through a network
interface. Use like: `/netdata eth0' (where eth0 is a network interface)
/NETSTREAM & /ENETSTREAM - Echoes or says amount of bandwidth being used.
Use like: `/netstream eth0' (where eth0 is a network interface)
/DISKINFO & /EDISKINFO - Echoes or says free space on partitions. The DISK command has a
few arguments as follows:
ALL - Displays every partitions
/mount - Displays free space for that specific mount point
No arguments just displays total free space
/MEMINFO & /EMEMINFO - Echoes or says memory information.
/VIDEO & /EVIDEO - Echoes or says the current video card on the PCI bus
/ETHER & /EETHER - Echoes or says the current network card on the PCI bus
/DISTRO & /EDISTRO - Echoes or says which distro you're running
If this doesn't work for your distro, look for a *-release file or similar in /etc
E-mail this to chainsaw@gentoo.org
and the big one:
/SYSINFO & /ESYSINFO - Complete system information!
Two output control commands:
/XSYS2FORMAT , No arguments, it will print just the current formatting string.
It will take any arguments to it as the formatting string.
The formatting string can consist of any letter/numbers, and is used to format
the output. The following special symbols can be used:
%B : Bold
%Cnn : Foreground Color, where nn is a number corresponding to a mIRC color
%Cnn,nn : Foreground,Background Color
%R : Reverse Foreground/Background Colors
%O : Reset Color and Format (thats an 'oh' not a 'zero (0)')
%C : Reset Color
%U : Underline
/PLAYING will either print or allow you to set the text for /np.
The default is now_playing, but you can set this to whatever text you prefer.
/PERCENTAGES will allow you to set whether to use percentages in plugin output or not.
Percentages are enabled by default. Use a zero value to disable, and a non-zero value
to enable. If unsure, use 1.
/NP & /ENP - Reports what's currently playing in Audacious.
====
BUGS
(none known)
E-mail me your bug reports at chainsaw@gentoo.org
Please include the following information:
- what architecture you are using (amd64, ia64, parisc, ppc, ppc64, sparc, sparc64 or x86)
- what linux distribution you are using (Gentoo 2007.1, Fedora Core 8, etc)
- what compiler you have used to compile X-Sys, i.e. gcc (GCC) 4.1.2 (Gentoo 4.1.2)
- what version of X-Sys you are using
=======
Thanks!
Remember, everything here is:
(C) 2003, 2004, 2005 by Michael Shoup
(C) 2005, 2006, 2007 by Tony Vroon
All Rights Reserved.
Visit http://dev.gentoo.org/~chainsaw/xsys/ for release information.
Feel free to e-mail me for feature requests, or see if I'm online on irc.freenode.net

View File

@ -1,927 +0,0 @@
/*
* SysInfo - sysinfo plugin for HexChat
* Copyright (c) 2012 Berke Viktor.
*
* xsys.c - main functions for X-Sys 2
* by mikeshoup
* Copyright (C) 2003, 2004, 2005 Michael Shoup
* Copyright (C) 2005, 2006, 2007 Tony Vroon
*
* 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 St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include "hexchat-plugin.h"
#include "parse.h"
#include "match.h"
#include "xsys.h"
#define DEFAULT_FORMAT "%B%1:%B %2 **"
#define DEFAULT_PERCENT 1
#define DEFAULT_ANNOUNCE 1
#define DEFAULT_PCIIDS "/usr/share/hwdata/pci.ids"
static hexchat_plugin *ph; /* plugin handle */
static int error_printed = 0; /* semaphore, make sure not to print the same error more than once during one execution */
static char name[] = "SysInfo";
static char desc[] = "Display info about your hardware and OS";
static char version[] = "3.0";
static char sysinfo_help[] = "SysInfo Usage:\n /SYSINFO [-e|-o] [OS|DISTRO|CPU|RAM|DISK|VGA|SOUND|ETHERNET|UPTIME], print various details about your system or print a summary without arguments\n /SYSINFO LIST, print current settings\n /SYSINFO SET <variable>, update given setting\n /SYSINFO RESET, reset settings to defaults\n /NETDATA <iface>, show transmitted data on given interface\n /NETSTREAM <iface>, show current bandwidth on given interface\n";
void
sysinfo_get_pciids (char* dest)
{
hexchat_pluginpref_get_str (ph, "pciids", dest);
}
int
sysinfo_get_percent ()
{
return hexchat_pluginpref_get_int (ph, "percent");
}
int
sysinfo_get_announce ()
{
return hexchat_pluginpref_get_int (ph, "announce");
}
void
sysinfo_print_error (const char* msg)
{
if (!error_printed)
{
hexchat_printf (ph, "%s\t%s", name, msg);
}
error_printed++;
}
static int
print_summary (int announce, char* format)
{
char sysinfo[bsize];
char buffer[bsize];
char cpu_model[bsize];
char cpu_cache[bsize];
char cpu_vendor[bsize];
char os_host[bsize];
char os_user[bsize];
char os_kernel[bsize];
char *free_space;
unsigned long long mem_total;
unsigned long long mem_free;
unsigned int count;
double cpu_freq;
int giga = 0;
int weeks;
int days;
int hours;
int minutes;
int seconds;
sysinfo[0] = '\0';
g_snprintf (buffer, bsize, "%s", hexchat_get_info (ph, "version"));
format_output ("HexChat", buffer, format);
strcat (sysinfo, "\017 ");
strncat (sysinfo, buffer, bsize - strlen (sysinfo));
/* BEGIN OS PARSING */
if (xs_parse_os (os_user, os_host, os_kernel) != 0)
{
hexchat_printf (ph, "%s\tERROR in parse_os()", name);
return HEXCHAT_EAT_ALL;
}
g_snprintf (buffer, bsize, "%s", os_kernel);
format_output ("OS", buffer, format);
strcat (sysinfo, "\017 ");
strncat (sysinfo, buffer, bsize - strlen (sysinfo));
/* BEGIN DISTRO PARSING */
if (xs_parse_distro (buffer) != 0)
{
strncpy (buffer, "Unknown", bsize);
}
format_output ("Distro", buffer, format);
strcat (sysinfo, "\017 ");
strncat (sysinfo, buffer, bsize - strlen (sysinfo));
/* BEGIN CPU PARSING */
if (xs_parse_cpu (cpu_model, cpu_vendor, &cpu_freq, cpu_cache, &count) != 0)
{
hexchat_printf (ph, "%s\tERROR in parse_cpu()", name);
return HEXCHAT_EAT_ALL;
}
if (cpu_freq > 1000)
{
cpu_freq /= 1000;
giga = 1;
}
if (giga)
{
g_snprintf (buffer, bsize, "%u x %s (%s) @ %.2fGHz", count, cpu_model, cpu_vendor, cpu_freq);
}
else
{
g_snprintf (buffer, bsize, "%u x %s (%s) @ %.0fMHz", count, cpu_model, cpu_vendor, cpu_freq);
}
format_output ("CPU", buffer, format);
strcat (sysinfo, "\017 ");
strncat (sysinfo, buffer, bsize - strlen (sysinfo));
/* BEGIN MEMORY PARSING */
if (xs_parse_meminfo (&mem_total, &mem_free, 0) == 1)
{
hexchat_printf (ph, "%s\tERROR in parse_meminfo!", name);
return HEXCHAT_EAT_ALL;
}
free_space = pretty_freespace ("Physical", &mem_free, &mem_total);
g_snprintf (buffer, bsize, "%s", free_space);
g_free (free_space);
format_output ("RAM", buffer, format);
strcat (sysinfo, "\017 ");
strncat (sysinfo, buffer, bsize - strlen (sysinfo));
/* BEGIN DISK PARSING */
if (xs_parse_df (NULL, buffer))
{
hexchat_printf (ph, "%s\tERROR in parse_df", name);
return HEXCHAT_EAT_ALL;
}
format_output ("Disk", buffer, format);
strcat (sysinfo, "\017 ");
strncat (sysinfo, buffer, bsize - strlen (buffer));
/* BEGIN VIDEO PARSING */
if (xs_parse_video (buffer))
{
hexchat_printf (ph, "%s\tERROR in parse_video", name);
return HEXCHAT_EAT_ALL;
}
format_output ("VGA", buffer, format);
strcat (sysinfo, "\017 ");
strncat (sysinfo, buffer, bsize - strlen (buffer));
/* BEGIN SOUND PARSING */
if (xs_parse_sound (buffer))
{
strncpy (buffer, "Not present", bsize);
}
format_output ("Sound", buffer, format);
strcat (sysinfo, "\017 ");
strncat (sysinfo, buffer, bsize - strlen (buffer));
/* BEGIN ETHERNET PARSING */
if (xs_parse_ether (buffer))
{
strncpy (buffer, "None found", bsize);
}
format_output ("Ethernet", buffer, format);
strcat (sysinfo, "\017 ");
strncat (sysinfo, buffer, bsize - strlen (buffer));
/* BEGIN UPTIME PARSING */
if (xs_parse_uptime (&weeks, &days, &hours, &minutes, &seconds))
{
hexchat_printf (ph, "%s\tERROR in parse_uptime()", name);
return HEXCHAT_EAT_ALL;
}
if (minutes != 0 || hours != 0 || days != 0 || weeks != 0)
{
if (hours != 0 || days != 0 || weeks != 0)
{
if (days !=0 || weeks != 0)
{
if (weeks != 0)
{
g_snprintf (buffer, bsize, "%dw %dd %dh %dm %ds", weeks, days, hours, minutes, seconds);
}
else
{
g_snprintf (buffer, bsize, "%dd %dh %dm %ds", days, hours, minutes, seconds);
}
}
else
{
g_snprintf (buffer, bsize, "%dh %dm %ds", hours, minutes, seconds);
}
}
else
{
g_snprintf (buffer, bsize, "%dm %ds", minutes, seconds);
}
}
format_output ("Uptime", buffer, format);
strcat (sysinfo, "\017 ");
strncat (sysinfo, buffer, bsize - strlen (buffer));
if (announce)
{
hexchat_commandf (ph, "SAY %s", sysinfo);
}
else
{
hexchat_printf (ph, "%s", sysinfo);
}
return HEXCHAT_EAT_ALL;
}
static int
print_os (int announce, char* format)
{
char buffer[bsize];
char user[bsize];
char host[bsize];
char kernel[bsize];
if (xs_parse_os (user, host, kernel) != 0)
{
hexchat_printf (ph, "%s\tERROR in parse_os()", name);
return HEXCHAT_EAT_ALL;
}
g_snprintf (buffer, bsize, "%s@%s, %s", user, host, kernel);
format_output ("OS", buffer, format);
if (announce)
{
hexchat_commandf (ph, "SAY %s", buffer);
}
else
{
hexchat_printf (ph, "%s", buffer);
}
return HEXCHAT_EAT_ALL;
}
static int
print_distro (int announce, char* format)
{
char name[bsize];
if (xs_parse_distro (name) != 0)
{
hexchat_printf (ph, "%s\tERROR in parse_distro()!", name);
return HEXCHAT_EAT_ALL;
}
format_output("Distro", name, format);
if (announce)
{
hexchat_commandf (ph, "SAY %s", name);
}
else
{
hexchat_printf (ph, "%s", name);
}
return HEXCHAT_EAT_ALL;
}
static int
print_cpu (int announce, char* format)
{
char model[bsize];
char vendor[bsize];
char cache[bsize];
char buffer[bsize];
unsigned int count;
double freq;
int giga = 0;
if (xs_parse_cpu (model, vendor, &freq, cache, &count) != 0)
{
hexchat_printf (ph, "%s\tERROR in parse_cpu()", name);
return HEXCHAT_EAT_ALL;
}
if (freq > 1000)
{
freq /= 1000;
giga = 1;
}
if (giga)
{
g_snprintf (buffer, bsize, "%u x %s (%s) @ %.2fGHz w/ %s L2 Cache", count, model, vendor, freq, cache);
}
else
{
g_snprintf (buffer, bsize, "%u x %s (%s) @ %.0fMHz w/ %s L2 Cache", count, model, vendor, freq, cache);
}
format_output ("CPU", buffer, format);
if (announce)
{
hexchat_commandf (ph, "SAY %s", buffer);
}
else
{
hexchat_printf (ph, "%s", buffer);
}
return HEXCHAT_EAT_ALL;
}
static int
print_ram (int announce, char* format)
{
unsigned long long mem_total;
unsigned long long mem_free;
unsigned long long swap_total;
unsigned long long swap_free;
char string[bsize];
if (xs_parse_meminfo (&mem_total, &mem_free, 0) == 1)
{
hexchat_printf (ph, "%s\tERROR in parse_meminfo!", name);
return HEXCHAT_EAT_ALL;
}
if (xs_parse_meminfo (&swap_total, &swap_free, 1) == 1)
{
hexchat_printf (ph, "%s\tERROR in parse_meminfo!", name);
return HEXCHAT_EAT_ALL;
}
g_snprintf (string, bsize, "%s - %s", pretty_freespace ("Physical", &mem_free, &mem_total), pretty_freespace ("Swap", &swap_free, &swap_total));
format_output ("RAM", string, format);
if (announce)
{
hexchat_commandf (ph, "SAY %s", string);
}
else
{
hexchat_printf (ph, "%s", string);
}
return HEXCHAT_EAT_ALL;
}
static int
print_disk (int announce, char* format)
{
char string[bsize] = {0,};
#if 0
if (*word == '\0')
{
if (xs_parse_df (NULL, string))
{
hexchat_printf (ph, "ERROR in parse_df");
return HEXCHAT_EAT_ALL;
}
}
else
{
if (xs_parse_df (*word, string))
{
hexchat_printf (ph, "ERROR in parse_df");
return HEXCHAT_EAT_ALL;
}
}
#endif
if (xs_parse_df (NULL, string))
{
hexchat_printf (ph, "%s\tERROR in parse_df", name);
return HEXCHAT_EAT_ALL;
}
format_output ("Disk", string, format);
if (announce)
{
hexchat_commandf (ph, "SAY %s", string);
}
else
{
hexchat_printf (ph, "%s", string);
}
return HEXCHAT_EAT_ALL;
}
static int
print_vga (int announce, char* format)
{
char vid_card[bsize];
char agp_bridge[bsize];
char buffer[bsize];
int ret;
if ((ret = xs_parse_video (vid_card)) != 0)
{
hexchat_printf (ph, "%s\tERROR in parse_video! %d", name, ret);
return HEXCHAT_EAT_ALL;
}
if (xs_parse_agpbridge (agp_bridge) != 0)
{
g_snprintf (buffer, bsize, "%s", vid_card);
}
else
{
g_snprintf (buffer, bsize, "%s @ %s", vid_card, agp_bridge);
}
format_output ("VGA", buffer, format);
if (announce)
{
hexchat_commandf (ph, "SAY %s", buffer);
}
else
{
hexchat_printf (ph, "%s", buffer);
}
return HEXCHAT_EAT_ALL;
}
static int
print_sound (int announce, char* format)
{
char sound[bsize];
if (xs_parse_sound (sound) != 0)
{
hexchat_printf (ph, "%s\tERROR in parse_asound()!", name);
return HEXCHAT_EAT_ALL;
}
format_output ("Sound", sound, format);
if (announce)
{
hexchat_commandf (ph, "SAY %s", sound);
}
else
{
hexchat_printf (ph, "%s", sound);
}
return HEXCHAT_EAT_ALL;
}
static int
print_ethernet (int announce, char* format)
{
char ethernet_card[bsize];
if (xs_parse_ether (ethernet_card))
{
strncpy (ethernet_card, "None found", bsize);
}
format_output ("Ethernet", ethernet_card, format);
if (announce)
{
hexchat_commandf (ph, "SAY %s", ethernet_card);
}
else
{
hexchat_printf (ph, "%s", ethernet_card);
}
return HEXCHAT_EAT_ALL;
}
static int
print_uptime (int announce, char* format)
{
char buffer[bsize];
int weeks;
int days;
int hours;
int minutes;
int seconds;
if (xs_parse_uptime (&weeks, &days, &hours, &minutes, &seconds))
{
hexchat_printf (ph, "%s\tERROR in parse_uptime()", name);
return HEXCHAT_EAT_ALL;
}
if (minutes != 0 || hours != 0 || days != 0 || weeks != 0)
{
if (hours != 0 || days != 0 || weeks != 0)
{
if (days !=0 || weeks != 0)
{
if (weeks != 0)
{
g_snprintf (buffer, bsize, "%dw %dd %dh %dm %ds", weeks, days, hours, minutes, seconds);
}
else
{
g_snprintf (buffer, bsize, "%dd %dh %dm %ds", days, hours, minutes, seconds);
}
}
else
{
g_snprintf (buffer, bsize, "%dh %dm %ds", hours, minutes, seconds);
}
}
else
{
g_snprintf (buffer, bsize, "%dm %ds", minutes, seconds);
}
}
format_output ("Uptime", buffer, format);
if (announce)
{
hexchat_commandf (ph, "SAY %s", buffer);
}
else
{
hexchat_printf (ph, "%s", buffer);
}
return HEXCHAT_EAT_ALL;
}
static int
netdata_cb (char *word[], char *word_eol[], void *userdata)
{
char netdata[bsize];
char format[bsize];
unsigned long long bytes_recv;
unsigned long long bytes_sent;
if (*word[2] == '\0')
{
hexchat_printf (ph, "%s\tYou must specify a network device (e.g. /NETDATA eth0)!", name);
return HEXCHAT_EAT_ALL;
}
if (xs_parse_netdev (word[2], &bytes_recv, &bytes_sent) != 0)
{
hexchat_printf (ph, "%s\tERROR in parse_netdev", name);
return HEXCHAT_EAT_ALL;
}
bytes_recv /= 1024;
bytes_sent /= 1024;
g_snprintf (netdata, bsize, "%s: %.1f MB Received, %.1f MB Sent", word[2], (double)bytes_recv/1024.0, (double)bytes_sent/1024.0);
hexchat_pluginpref_get_str (ph, "format", format);
format_output ("Netdata", netdata, format);
if (hexchat_list_int (ph, NULL, "type") >= 2)
{
hexchat_commandf (ph, "SAY %s", netdata);
}
else
{
hexchat_printf (ph, "%s", netdata);
}
return HEXCHAT_EAT_ALL;
}
static int
netstream_cb (char *word[], char *word_eol[], void *userdata)
{
char netstream[bsize];
char mag_r[5];
char mag_s[5];
char format[bsize];
unsigned long long bytes_recv;
unsigned long long bytes_sent;
unsigned long long bytes_recv_p;
unsigned long long bytes_sent_p;
struct timespec ts = {1, 0};
if (*word[2] == '\0')
{
hexchat_printf (ph, "%s\tYou must specify a network device (e.g. /NETSTREAM eth0)!", name);
return HEXCHAT_EAT_ALL;
}
if (xs_parse_netdev(word[2], &bytes_recv, &bytes_sent) != 0)
{
hexchat_printf (ph, "%s\tERROR in parse_netdev", name);
return HEXCHAT_EAT_ALL;
}
while (nanosleep (&ts, &ts) < 0);
if (xs_parse_netdev(word[2], &bytes_recv_p, &bytes_sent_p) != 0)
{
hexchat_printf (ph, "%s\tERROR in parse_netdev", name);
return HEXCHAT_EAT_ALL;
}
bytes_recv = (bytes_recv_p - bytes_recv);
bytes_sent = (bytes_sent_p - bytes_sent);
if (bytes_recv > 1024)
{
bytes_recv /= 1024;
g_snprintf (mag_r, 5, "KB/s");
}
else
{
g_snprintf (mag_r, 5, "B/s");
}
if (bytes_sent > 1024)
{
bytes_sent /= 1024;
g_snprintf (mag_s, 5, "KB/s");
}
else
{
g_snprintf (mag_s, 5, "B/s");
}
g_snprintf (netstream, bsize, "%s: Receiving %llu %s, Sending %llu %s", word[2], bytes_recv, mag_r, bytes_sent, mag_s);
hexchat_pluginpref_get_str (ph, "format", format);
format_output ("Netstream", netstream, format);
if (hexchat_list_int (ph, NULL, "type") >= 2)
{
hexchat_commandf (ph, "SAY %s", netstream);
}
else
{
hexchat_printf (ph, "%s", netstream);
}
return HEXCHAT_EAT_ALL;
}
static void
list_settings ()
{
char list[512];
char buffer[512];
char* token;
hexchat_pluginpref_list (ph, list);
hexchat_printf (ph, "%s\tCurrent Settings:", name);
token = strtok (list, ",");
while (token != NULL)
{
hexchat_pluginpref_get_str (ph, token, buffer);
hexchat_printf (ph, "%s\t%s: %s\n", name, token, buffer);
token = strtok (NULL, ",");
}
}
static void
reset_settings ()
{
hexchat_pluginpref_set_str (ph, "pciids", DEFAULT_PCIIDS);
hexchat_pluginpref_set_str (ph, "format", DEFAULT_FORMAT);
hexchat_pluginpref_set_int (ph, "percent", DEFAULT_PERCENT);
hexchat_pluginpref_set_int (ph, "announce", DEFAULT_ANNOUNCE);
}
static int
sysinfo_cb (char *word[], char *word_eol[], void *userdata)
{
error_printed = 0;
int announce = sysinfo_get_announce ();
int offset = 0;
int buffer;
char format[bsize];
if (!hexchat_pluginpref_get_str (ph, "format", format))
{
hexchat_printf (ph, "%s\tError reading config file!", name);
return HEXCHAT_EAT_ALL;
}
/* Cannot send to server tab */
if (hexchat_list_int (ph, NULL, "type") == 1)
{
announce = 0;
}
/* Allow overriding global announce setting */
if (!strcmp ("-e", word[2]))
{
announce = 0;
offset++;
}
else if (!strcmp ("-o", word[2]))
{
announce = 1;
offset++;
}
if (!g_ascii_strcasecmp ("HELP", word[2+offset]))
{
hexchat_printf (ph, "%s", sysinfo_help);
return HEXCHAT_EAT_ALL;
}
else if (!g_ascii_strcasecmp ("LIST", word[2+offset]))
{
list_settings ();
return HEXCHAT_EAT_ALL;
}
else if (!g_ascii_strcasecmp ("SET", word[2+offset]))
{
if (!g_ascii_strcasecmp ("", word_eol[4+offset]))
{
hexchat_printf (ph, "%s\tEnter a value!\n", name);
return HEXCHAT_EAT_ALL;
}
if (!g_ascii_strcasecmp ("format", word[3+offset]))
{
hexchat_pluginpref_set_str (ph, "format", word_eol[4+offset]);
hexchat_printf (ph, "%s\tformat is set to: %s\n", name, word_eol[4+offset]);
}
else if (!g_ascii_strcasecmp ("percent", word[3+offset]))
{
buffer = atoi (word[4+offset]); /* don't use word_eol, numbers must not contain spaces */
if (buffer > 0 && buffer < INT_MAX)
{
hexchat_pluginpref_set_int (ph, "percent", buffer);
hexchat_printf (ph, "%s\tpercent is set to: %d\n", name, buffer);
}
else
{
hexchat_printf (ph, "%s\tInvalid input!\n", name);
}
}
else if (!g_ascii_strcasecmp ("announce", word[3+offset]))
{
buffer = atoi (word[4+offset]); /* don't use word_eol, numbers must not contain spaces */
if (buffer > 0)
{
hexchat_pluginpref_set_int (ph, "announce", 1);
hexchat_printf (ph, "%s\tannounce is set to: On\n", name);
}
else
{
hexchat_pluginpref_set_int (ph, "announce", 0);
hexchat_printf (ph, "%s\tannounce is set to: Off\n", name);
}
}
else if (!g_ascii_strcasecmp ("pciids", word[3+offset]))
{
hexchat_pluginpref_set_str (ph, "pciids", word_eol[4+offset]);
hexchat_printf (ph, "%s\tpciids is set to: %s\n", name, word_eol[4+offset]);
}
else
{
hexchat_printf (ph, "%s\tInvalid variable name! Use 'pciids', 'format' or 'percent'!\n", name);
return HEXCHAT_EAT_ALL;
}
return HEXCHAT_EAT_ALL;
}
else if (!g_ascii_strcasecmp ("RESET", word[2+offset]))
{
reset_settings ();
hexchat_printf (ph, "%s\tSettings have been restored to defaults.\n", name);
return HEXCHAT_EAT_ALL;
}
else if (!g_ascii_strcasecmp ("OS", word[2+offset]))
{
print_os (announce, format);
return HEXCHAT_EAT_ALL;
}
else if (!g_ascii_strcasecmp ("DISTRO", word[2+offset]))
{
print_distro (announce, format);
return HEXCHAT_EAT_ALL;
}
else if (!g_ascii_strcasecmp ("CPU", word[2+offset]))
{
print_cpu (announce, format);
return HEXCHAT_EAT_ALL;
}
else if (!g_ascii_strcasecmp ("RAM", word[2+offset]))
{
print_ram (announce, format);
return HEXCHAT_EAT_ALL;
}
else if (!g_ascii_strcasecmp ("DISK", word[2+offset]))
{
print_disk (announce, format);
return HEXCHAT_EAT_ALL;
}
else if (!g_ascii_strcasecmp ("VGA", word[2+offset]))
{
print_vga (announce, format);
return HEXCHAT_EAT_ALL;
}
else if (!g_ascii_strcasecmp ("SOUND", word[2+offset]))
{
print_sound (announce, format);
return HEXCHAT_EAT_ALL;
}
else if (!g_ascii_strcasecmp ("ETHERNET", word[2+offset]))
{
print_ethernet (announce, format);
return HEXCHAT_EAT_ALL;
}
else if (!g_ascii_strcasecmp ("UPTIME", word[2+offset]))
{
print_uptime (announce, format);
return HEXCHAT_EAT_ALL;
}
else if (!g_ascii_strcasecmp ("", word[2+offset]))
{
print_summary (announce, format);
return HEXCHAT_EAT_ALL;
}
else
{
hexchat_printf (ph, "%s", sysinfo_help);
return HEXCHAT_EAT_ALL;
}
}
int
hexchat_plugin_init (hexchat_plugin *plugin_handle, char **plugin_name, char **plugin_desc, char **plugin_version, char *arg)
{
char buffer[bsize];
ph = plugin_handle;
*plugin_name = name;
*plugin_desc = desc;
*plugin_version = version;
hexchat_hook_command (ph, "SYSINFO", HEXCHAT_PRI_NORM, sysinfo_cb, sysinfo_help, NULL);
hexchat_hook_command (ph, "NETDATA", HEXCHAT_PRI_NORM, netdata_cb, NULL, NULL);
hexchat_hook_command (ph, "NETSTREAM", HEXCHAT_PRI_NORM, netstream_cb, NULL, NULL);
/* this is required for the very first run */
if (hexchat_pluginpref_get_str (ph, "pciids", buffer) == 0)
{
hexchat_pluginpref_set_str (ph, "pciids", DEFAULT_PCIIDS);
}
if (hexchat_pluginpref_get_str (ph, "format", buffer) == 0)
{
hexchat_pluginpref_set_str (ph, "format", DEFAULT_FORMAT);
}
if (hexchat_pluginpref_get_int (ph, "percent") == -1)
{
hexchat_pluginpref_set_int (ph, "percent", DEFAULT_PERCENT);
}
if (hexchat_pluginpref_get_int (ph, "announce") == -1)
{
hexchat_pluginpref_set_int (ph, "announce", DEFAULT_ANNOUNCE);
}
hexchat_command (ph, "MENU ADD \"Window/Send System Info\" \"SYSINFO\"");
hexchat_printf (ph, "%s plugin loaded\n", name);
return 1;
}
int
hexchat_plugin_deinit (void)
{
hexchat_command (ph, "MENU DEL \"Window/Display System Info\"");
hexchat_printf (ph, "%s plugin unloaded\n", name);
return 1;
}

View File

@ -43,3 +43,4 @@ src/fe-gtk/textgui.c
src/fe-gtk/urlgrab.c src/fe-gtk/urlgrab.c
src/fe-gtk/userlistgui.c src/fe-gtk/userlistgui.c
src/fe-text/fe-text.c src/fe-text/fe-text.c
plugins/sysinfo/sysinfo.c