From 5e3355a6c348b511c7b7a1f6dc89185726d566c5 Mon Sep 17 00:00:00 2001 From: TingPing Date: Sat, 14 Feb 2015 13:35:02 -0500 Subject: [PATCH] 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 --- .gitignore | 1 + configure.ac | 14 +- plugins/sysinfo/Makefile.am | 14 +- plugins/sysinfo/format.c | 95 +++ plugins/sysinfo/format.h | 28 + plugins/sysinfo/match.c | 228 ------ plugins/sysinfo/osx/backend.m | 263 +++++++ plugins/sysinfo/shared/df.c | 53 ++ plugins/sysinfo/shared/df.h | 23 + plugins/sysinfo/sysinfo-backend.h | 33 + plugins/sysinfo/sysinfo.c | 780 +++++++------------- plugins/sysinfo/{xsys.h => sysinfo.h} | 15 +- plugins/sysinfo/sysinfo.vcxproj | 11 +- plugins/sysinfo/sysinfo.vcxproj.filters | 20 + plugins/sysinfo/unix/backend.c | 170 +++++ plugins/sysinfo/unix/match.c | 98 +++ plugins/sysinfo/{ => unix}/match.h | 6 - plugins/sysinfo/{ => unix}/parse.c | 222 ++---- plugins/sysinfo/{ => unix}/parse.h | 7 +- plugins/sysinfo/{ => unix}/pci.c | 137 ++-- plugins/sysinfo/{ => unix}/pci.h | 0 plugins/sysinfo/win32/backend.c | 493 +++++++++++++ plugins/sysinfo/xsys-changelog | 116 --- plugins/sysinfo/xsys-install | 15 - plugins/sysinfo/xsys-makefile | 38 - plugins/sysinfo/xsys-readme | 105 --- plugins/sysinfo/xsys.c | 927 ------------------------ po/POTFILES.in | 1 + 28 files changed, 1681 insertions(+), 2232 deletions(-) create mode 100644 plugins/sysinfo/format.c create mode 100644 plugins/sysinfo/format.h delete mode 100644 plugins/sysinfo/match.c create mode 100644 plugins/sysinfo/osx/backend.m create mode 100644 plugins/sysinfo/shared/df.c create mode 100644 plugins/sysinfo/shared/df.h create mode 100644 plugins/sysinfo/sysinfo-backend.h rename plugins/sysinfo/{xsys.h => sysinfo.h} (72%) create mode 100644 plugins/sysinfo/unix/backend.c create mode 100644 plugins/sysinfo/unix/match.c rename plugins/sysinfo/{ => unix}/match.h (73%) rename plugins/sysinfo/{ => unix}/parse.c (60%) rename plugins/sysinfo/{ => unix}/parse.h (75%) rename plugins/sysinfo/{ => unix}/pci.c (50%) rename plugins/sysinfo/{ => unix}/pci.h (100%) create mode 100644 plugins/sysinfo/win32/backend.c delete mode 100644 plugins/sysinfo/xsys-changelog delete mode 100644 plugins/sysinfo/xsys-install delete mode 100644 plugins/sysinfo/xsys-makefile delete mode 100644 plugins/sysinfo/xsys-readme delete mode 100644 plugins/sysinfo/xsys.c diff --git a/.gitignore b/.gitignore index 7b4fcb28..63675ee5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ # Unix generated files .deps/ .libs/ +.dirstamp Makefile Makefile.in aclocal.m4 diff --git a/configure.ac b/configure.ac index d53bf295..ea7f16e4 100644 --- a/configure.ac +++ b/configure.ac @@ -40,6 +40,7 @@ AH_VERBATIM([PREFIX],[#undef PREFIX]) AH_VERBATIM([HEXCHATLIBDIR],[#undef HEXCHATLIBDIR]) AH_VERBATIM([HEXCHATSHAREDIR],[#undef HEXCHATSHAREDIR]) 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_GTK_MAC],[#undef HAVE_GTK_MAC]) AH_VERBATIM([USE_LIBNOTIFY],[#undef USE_LIBNOTIFY]) @@ -73,9 +74,12 @@ else fi platform_win32=no +platform_osx=no case $host_os in *mingw*|*cygwin*|*msys*) platform_win32=yes;; + darwin*) + platform_osx=yes;; *);; esac @@ -492,7 +496,14 @@ if test "$sysinfo" != "no"; then AC_MSG_CHECKING(for plugin interface used by SysInfo) if test "$plugin" = yes; then 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 AC_MSG_RESULT([plugins are disabled, use the --enable-plugin option for SysInfo]) 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_GTK_MAC, test "x$_gdk_tgt" = xquartz) AM_CONDITIONAL(WITH_TM, test "x$theme_manager" != "xno") +AM_CONDITIONAL(PLATFORM_OSX, test "x$platform_osx" == "xyes") dnl ********************************************************************* dnl ** GCC FLAGS ******************************************************** diff --git a/plugins/sysinfo/Makefile.am b/plugins/sysinfo/Makefile.am index 4ac9c016..bd44a19d 100644 --- a/plugins/sysinfo/Makefile.am +++ b/plugins/sysinfo/Makefile.am @@ -1,7 +1,17 @@ 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 -sysinfo_la_SOURCES = match.c parse.c pci.c xsys.c +sysinfo_la_SOURCES = $(sources) sysinfo_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module 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 diff --git a/plugins/sysinfo/format.c b/plugins/sysinfo/format.c new file mode 100644 index 00000000..f0b0effd --- /dev/null +++ b/plugins/sysinfo/format.c @@ -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 + +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; +} diff --git a/plugins/sysinfo/format.h b/plugins/sysinfo/format.h new file mode 100644 index 00000000..5fe209be --- /dev/null +++ b/plugins/sysinfo/format.h @@ -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 diff --git a/plugins/sysinfo/match.c b/plugins/sysinfo/match.c deleted file mode 100644 index cfd66e37..00000000 --- a/plugins/sysinfo/match.c +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#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); -} diff --git a/plugins/sysinfo/osx/backend.m b/plugins/sysinfo/osx/backend.m new file mode 100644 index 00000000..450a557a --- /dev/null +++ b/plugins/sysinfo/osx/backend.m @@ -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 + +#include +#include +#include +#include +#include + +#include + +#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; +} diff --git a/plugins/sysinfo/shared/df.c b/plugins/sysinfo/shared/df.c new file mode 100644 index 00000000..2ef75689 --- /dev/null +++ b/plugins/sysinfo/shared/df.c @@ -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 +#include +#include +#include + +#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; +} diff --git a/plugins/sysinfo/shared/df.h b/plugins/sysinfo/shared/df.h new file mode 100644 index 00000000..5f7f3296 --- /dev/null +++ b/plugins/sysinfo/shared/df.h @@ -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 diff --git a/plugins/sysinfo/sysinfo-backend.h b/plugins/sysinfo/sysinfo-backend.h new file mode 100644 index 00000000..c69a0853 --- /dev/null +++ b/plugins/sysinfo/sysinfo-backend.h @@ -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 diff --git a/plugins/sysinfo/sysinfo.c b/plugins/sysinfo/sysinfo.c index c243de42..10c9d796 100644 --- a/plugins/sysinfo/sysinfo.c +++ b/plugins/sysinfo/sysinfo.c @@ -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 - * 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: + * xsys.c - main functions for X-Sys 2 + * by mikeshoup + * Copyright (C) 2003, 2004, 2005 Michael Shoup + * Copyright (C) 2005, 2006, 2007 Tony Vroon * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. + * 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. * - * 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. + * 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 -#include -#include +#include "config.h" +#include +#include +#include #include #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 version[] = "1.1"; -static char helptext[] = "USAGE: /SYSINFO - Sends info about your hardware and OS to current channel."; +static char version[] = "1.0"; +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 \n"; -/* 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 +typedef struct { - QUERY_WMI_OS, - QUERY_WMI_CPU, - QUERY_WMI_VGA, - QUERY_WMI_HDD, -} QueryWmiType; + const char *name; /* Lower case name used for prefs */ + const char *title; /* Used for the end formatting */ + char *(*callback) (void); + gboolean def; /* Hide by default? */ +} hwinfo; -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); +static char * +get_client (void) +{ + return g_strdup_printf ("HexChat %s", hexchat_get_info(ph, "version")); +} -guint64 hdd_capacity; -guint64 hdd_free_space; -char *read_hdd_info (IWbemClassObject *object); +static hwinfo hwinfos[] = { + {"client", "Client", get_client}, + {"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); -char *bstr_to_utf8 (BSTR bstr); -guint64 variant_to_uint64 (VARIANT *variant); +static gboolean sysinfo_get_bool_pref (const char *pref, gboolean def); -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; - *plugin_name = name; *plugin_desc = desc; *plugin_version = version; - hexchat_hook_command (ph, "SYSINFO", HEXCHAT_PRI_NORM, command_callback, helptext, NULL); - hexchat_command (ph, "MENU -ishare\\system.png ADD \"Window/Send System Info\" \"SYSINFO\""); - - hexchat_printf (ph, "%s plugin loaded\n", name); + hexchat_hook_command (ph, "SYSINFO", HEXCHAT_PRI_NORM, sysinfo_cb, sysinfo_help, NULL); + 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) +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_printf (ph, "%s plugin unloaded\n", name); - + hexchat_printf (ph, _("%s plugin unloaded\n"), name); 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; - } -} diff --git a/plugins/sysinfo/xsys.h b/plugins/sysinfo/sysinfo.h similarity index 72% rename from plugins/sysinfo/xsys.h rename to plugins/sysinfo/sysinfo.h index 4daf8545..cfde8408 100644 --- a/plugins/sysinfo/xsys.h +++ b/plugins/sysinfo/sysinfo.h @@ -1,7 +1,6 @@ /* - * xsys.h - X-Sys general parameters header - * Copyright (C) 2005 Gustavo Zacarias - * Copyright (C) 2006, 2007 Tony Vroon + * 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 @@ -19,14 +18,12 @@ */ -#ifndef _XSYS_H_ -#define _XSYS_H_ +#ifndef SYSINFO_H +#define SYSINFO_H #define bsize 1024 -#define delims ":=" +#define DEFAULT_PCIIDS "/usr/share/hwdata/pci.ids" -int sysinfo_get_percent (); -void sysinfo_get_pciids (char *dest); -void sysinfo_print_error (const char* msg); +int sysinfo_get_str_pref (const char *name, char *dest); #endif diff --git a/plugins/sysinfo/sysinfo.vcxproj b/plugins/sysinfo/sysinfo.vcxproj index fe3530e7..3d429295 100644 --- a/plugins/sysinfo/sysinfo.vcxproj +++ b/plugins/sysinfo/sysinfo.vcxproj @@ -31,7 +31,7 @@ WIN32;NDEBUG;_WINDOWS;_USRDLL;SYSINFO_EXPORTS;%(PreprocessorDefinitions) - ..\..\src\common;$(DepsRoot)\include;$(Glib);$(Gtk);%(AdditionalIncludeDirectories) + ..\..\src\common;$(DepsRoot)\include;$(Glib);$(HexChatLib);%(AdditionalIncludeDirectories) false @@ -44,7 +44,7 @@ WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;SYSINFO_EXPORTS;%(PreprocessorDefinitions) - ..\..\src\common;$(DepsRoot)\include;$(Glib);$(Gtk);%(AdditionalIncludeDirectories) + ..\..\src\common;$(DepsRoot)\include;$(Glib);$(HexChatLib);%(AdditionalIncludeDirectories) false @@ -58,7 +58,14 @@ + + + + + + + diff --git a/plugins/sysinfo/sysinfo.vcxproj.filters b/plugins/sysinfo/sysinfo.vcxproj.filters index 04831e5f..aa173bb5 100644 --- a/plugins/sysinfo/sysinfo.vcxproj.filters +++ b/plugins/sysinfo/sysinfo.vcxproj.filters @@ -9,6 +9,9 @@ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + {c873eb6b-aca6-434d-8ec9-199838b80838} + @@ -19,5 +22,22 @@ Source Files + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + \ No newline at end of file diff --git a/plugins/sysinfo/unix/backend.c b/plugins/sysinfo/unix/backend.c new file mode 100644 index 00000000..76a6f70f --- /dev/null +++ b/plugins/sysinfo/unix/backend.c @@ -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 +#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); +} diff --git a/plugins/sysinfo/unix/match.c b/plugins/sysinfo/unix/match.c new file mode 100644 index 00000000..2ef51f3f --- /dev/null +++ b/plugins/sysinfo/unix/match.c @@ -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 +#include +#include +#include +#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; + } +} + diff --git a/plugins/sysinfo/match.h b/plugins/sysinfo/unix/match.h similarity index 73% rename from plugins/sysinfo/match.h rename to plugins/sysinfo/unix/match.h index 61811e4a..16999fa2 100644 --- a/plugins/sysinfo/match.h +++ b/plugins/sysinfo/unix/match.h @@ -23,13 +23,7 @@ void find_match_char(char *buffer, char *match, char *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_int(char *buffer, char *match, unsigned int *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); -char *decruft_filename(char *buffer); #endif diff --git a/plugins/sysinfo/parse.c b/plugins/sysinfo/unix/parse.c similarity index 60% rename from plugins/sysinfo/parse.c rename to plugins/sysinfo/unix/parse.c index 3b210022..9f03533d 100644 --- a/plugins/sysinfo/parse.c +++ b/plugins/sysinfo/unix/parse.c @@ -23,20 +23,19 @@ #include #include #include -#include -#include -#include -#include -#include #include #include +#ifdef __sparc__ +#include +#endif + #include "pci.h" #include "match.h" -#include "xsys.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__) char buffer[bsize]; @@ -47,9 +46,6 @@ int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned FILE *fp = fopen("/proc/cpuinfo", "r"); if(fp == NULL) return 1; - - *count = 0; - strcpy(cache,"unknown\0"); #if defined(__i386__) || defined(__x86_64__) while(fgets(buffer, bsize, fp) != NULL) @@ -57,10 +53,7 @@ int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned find_match_char(buffer, "model name", model); find_match_char(buffer, "vendor_id", vendor); find_match_double(buffer, "cpu MHz", freq); - find_match_char(buffer, "cache size", cache); - find_match_int(buffer, "processor", count); } - *count = *count + 1; #endif #ifdef __powerpc__ 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, "machine", vendor); 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, ","); if (pos != NULL) *pos = '\0'; #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, "system type", vendor); 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; #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, "vendor", vendor); find_match_double(buffer, "cpu MHz", freq); - find_match_int(buffer, "processor", count); } - *count = *count + 1; #endif #ifdef __parisc__ while(fgets(buffer, bsize, fp) != NULL) { find_match_char(buffer, "cpu ", model); find_match_char(buffer, "cpu family", vendor); - find_match_char(buffer, "D-cache", cache); find_match_double(buffer, "cpu MHz", freq); - find_match_int(buffer, "processor", count); } - *count = *count + 1; #endif #ifdef __sparc__ 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, "type ", vendor); - find_match_int(buffer, "ncpus active", count); 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; #endif fclose(fp); @@ -138,43 +107,20 @@ int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned return 0; } -int xs_parse_uptime(int *weeks, int *days, int *hours, int *minutes, int *seconds) +guint64 xs_parse_uptime(void) { char buffer[bsize]; - long long uptime = 0; + guint64 uptime = 0; FILE *fp = fopen("/proc/uptime", "r"); if(fp == NULL) - return 1; + return 0; if(fgets(buffer, bsize, fp) != NULL) 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); - return 0; -} - -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; + return uptime; } int xs_parse_sound(char *snd_card) @@ -183,12 +129,13 @@ int xs_parse_sound(char *snd_card) u16 class = PCI_CLASS_MULTIMEDIA_AUDIO; 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) - { - pci_find_fullname(snd_card, vendor, device); - return 0; - } + { + pci_find_fullname(snd_card, vendor, device); + return 0; + } else return 1; } @@ -251,129 +198,42 @@ int xs_parse_agpbridge(char *agp_bridge) 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) { FILE *fp; - char buffer[bsize]; + char buffer[bsize]; unsigned long long freemem = 0, buffers = 0, cache = 0; - *mem_tot = 0; - *mem_free = 0; + *mem_tot = 0; + *mem_free = 0; - if((fp = fopen("/proc/meminfo", "r")) == NULL) - return 1; + if((fp = fopen("/proc/meminfo", "r")) == NULL) + return 1; - while(fgets(buffer, bsize, fp) != NULL) - { - if(!swap) - { + while(fgets(buffer, bsize, fp) != NULL) + { + if(!swap) + { find_match_ll(buffer, "MemTotal:", mem_tot); find_match_ll(buffer, "MemFree:", &freemem); find_match_ll(buffer, "Buffers:", &buffers); find_match_ll(buffer, "Cached:", &cache); - } - else - { + } + else + { find_match_ll(buffer, "SwapTotal:", mem_tot); find_match_ll(buffer, "SwapFree:", mem_free); - } - } - if (!swap) { + } + } + if (!swap) + { *mem_free = freemem + buffers + cache; } - fclose(fp); - return 0; + fclose(fp); + + /* Convert to bytes */ + *mem_free *= 1000; + *mem_tot *= 1000; + return 0; } int xs_parse_distro(char *name) @@ -429,10 +289,12 @@ int xs_parse_distro(char *name) } else g_snprintf(buffer, bsize, "Unknown Distro"); - if(fp != NULL) fclose(fp); + if(fp != NULL) + fclose(fp); pos=strchr(buffer, '\n'); - if(pos != NULL) *pos = '\0'; + if(pos != NULL) + *pos = '\0'; strcpy(name, buffer); return 0; } diff --git a/plugins/sysinfo/parse.h b/plugins/sysinfo/unix/parse.h similarity index 75% rename from plugins/sysinfo/parse.h rename to plugins/sysinfo/unix/parse.h index 600793de..89f1299c 100644 --- a/plugins/sysinfo/parse.h +++ b/plugins/sysinfo/unix/parse.h @@ -23,12 +23,9 @@ #ifndef _PARSE_H_ #define _PARSE_H_ -int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned int *count); -int xs_parse_uptime(int *weeks, int *days, int *hours, int *minutes, int *seconds); -int xs_parse_os(char *user, char *host, char *kernel); +int xs_parse_cpu(char *model, char *vendor, double *freq); +guint64 xs_parse_uptime(void); 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_video(char *vid_card); int xs_parse_agpbridge(char *agp_bridge); diff --git a/plugins/sysinfo/pci.c b/plugins/sysinfo/unix/pci.c similarity index 50% rename from plugins/sysinfo/pci.c rename to plugins/sysinfo/unix/pci.c index bda4888b..71b085fe 100644 --- a/plugins/sysinfo/pci.c +++ b/plugins/sysinfo/unix/pci.c @@ -23,64 +23,67 @@ #include #include #include -#include #include #include -#include "xsys.h" +#include "sysinfo.h" static struct pci_filter filter; /* Device filter */ static struct pci_access *pacc; int bus, dev, func; /* Location of the card */ struct device { - struct device *next; - struct pci_dev *dev; - unsigned int config_cnt; - u8 config[256]; + struct device *next; + struct pci_dev *dev; + unsigned int config_cnt; + u8 config[256]; }; static struct device *first_dev; static struct device *scan_device(struct pci_dev *p) { - int how_much = 64; - struct device *d; + int how_much = 64; + struct device *d; - if (!pci_filter_match(&filter, p)) - return NULL; - d = g_new0 (struct device, 1); - d->dev = p; - if (!pci_read_block(p, 0, d->config, how_much)) - exit(1); - 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... */ - if (!pci_read_block(p, 64, d->config+64, 64)) - exit(1); - how_much = 128; - } - d->config_cnt = how_much; - pci_setup_cache(p, d->config, d->config_cnt); - pci_fill_info(p, PCI_FILL_IDENT); - return d; + if (!pci_filter_match(&filter, p)) + return NULL; + d = g_new0 (struct device, 1); + d->dev = p; + if (!pci_read_block(p, 0, d->config, how_much)) + exit(1); + 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... */ + if (!pci_read_block(p, 64, d->config+64, 64)) + exit(1); + how_much = 128; + } + d->config_cnt = how_much; + pci_setup_cache(p, d->config, d->config_cnt); + pci_fill_info(p, PCI_FILL_IDENT); + return d; } static void scan_devices(void) { - struct device *d; - struct pci_dev *p; + struct device *d; + struct pci_dev *p; - pci_scan_bus(pacc); - for(p=pacc->devices; p; p=p->next) - if ((d = scan_device(p))) { - d->next = first_dev; - first_dev = d; - } + pci_scan_bus(pacc); + for(p=pacc->devices; p; p=p->next) + { + if ((d = scan_device(p))) + { + d->next = first_dev; + first_dev = d; + } + } } static u16 get_conf_word(struct device *d, unsigned int pos) { - return d->config[pos] | (d->config[pos+1] << 8); + return d->config[pos] | (d->config[pos+1] << 8); } int pci_find_by_class(u16 *class, char *vendor, char *device) @@ -94,19 +97,21 @@ int pci_find_by_class(u16 *class, char *vendor, char *device) pci_init(pacc); scan_devices(); - for(d=first_dev; d; d=d->next) { - p = d->dev; - /* Acquire vendor & device ID if the class matches */ - if(get_conf_word(d, PCI_CLASS_DEVICE) == *class) { - nomatch = 0; + for(d=first_dev; d; d=d->next) + { + p = d->dev; + /* Acquire vendor & device ID if the class matches */ + if(get_conf_word(d, PCI_CLASS_DEVICE) == *class) + { + nomatch = 0; g_snprintf(vendor,7,"%04x",p->vendor_id); g_snprintf(device,7,"%04x",p->device_id); - break; - } - } + break; + } + } - pci_cleanup(pacc); - return nomatch; + pci_cleanup(pacc); + return nomatch; } void pci_find_fullname(char *fullname, char *vendor, char *device) @@ -117,38 +122,44 @@ void pci_find_fullname(char *fullname, char *vendor, char *device) char *position; int cardfound = 0; FILE *fp; + + if (!sysinfo_get_str_pref ("pciids", buffer)) + strcpy (buffer, DEFAULT_PCIIDS); - sysinfo_get_pciids (buffer); fp = fopen (buffer, "r"); - - if(fp == NULL) { + if(fp == NULL) + { 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; } - while(fgets(buffer, bsize, fp) != NULL) { - if (!isspace(buffer[0]) && strstr(buffer, vendor) != NULL) { - position = strstr(buffer, vendor); - position += 6; - strncpy(vendorname, position, bsize/2); - position = strstr(vendorname, "\n"); - *(position) = '\0'; + while(fgets(buffer, bsize, fp) != NULL) + { + if (!isspace(buffer[0]) && strstr(buffer, vendor) != NULL) + { + position = strstr(buffer, vendor); + position += 6; + strncpy(vendorname, position, bsize/2); + position = strstr(vendorname, "\n"); + *(position) = '\0'; break; - } + } } - while(fgets(buffer, bsize, fp) != NULL) { - if(strstr(buffer, device) != NULL) { - position = strstr(buffer, device); - position += 6; - strncpy(devicename, position, bsize/2); + while(fgets(buffer, bsize, fp) != NULL) + { + if(strstr(buffer, device) != NULL) + { + position = strstr(buffer, device); + position += 6; + strncpy(devicename, position, bsize/2); position = strstr(devicename, " ("); if (position == NULL) - position = strstr(devicename, "\n"); - *(position) = '\0'; + position = strstr(devicename, "\n"); + *(position) = '\0'; cardfound = 1; break; - } + } } if (cardfound == 1) g_snprintf(fullname, bsize, "%s %s", vendorname, devicename); diff --git a/plugins/sysinfo/pci.h b/plugins/sysinfo/unix/pci.h similarity index 100% rename from plugins/sysinfo/pci.h rename to plugins/sysinfo/unix/pci.h diff --git a/plugins/sysinfo/win32/backend.c b/plugins/sysinfo/win32/backend.c new file mode 100644 index 00000000..26779961 --- /dev/null +++ b/plugins/sysinfo/win32/backend.c @@ -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 +#include +#include + +#include + +#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; + } +} diff --git a/plugins/sysinfo/xsys-changelog b/plugins/sysinfo/xsys-changelog deleted file mode 100644 index 9ea20727..00000000 --- a/plugins/sysinfo/xsys-changelog +++ /dev/null @@ -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 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 diff --git a/plugins/sysinfo/xsys-install b/plugins/sysinfo/xsys-install deleted file mode 100644 index 8f148569..00000000 --- a/plugins/sysinfo/xsys-install +++ /dev/null @@ -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. diff --git a/plugins/sysinfo/xsys-makefile b/plugins/sysinfo/xsys-makefile deleted file mode 100644 index 8b51a53d..00000000 --- a/plugins/sysinfo/xsys-makefile +++ /dev/null @@ -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 - diff --git a/plugins/sysinfo/xsys-readme b/plugins/sysinfo/xsys-readme deleted file mode 100644 index 6226e725..00000000 --- a/plugins/sysinfo/xsys-readme +++ /dev/null @@ -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 diff --git a/plugins/sysinfo/xsys.c b/plugins/sysinfo/xsys.c deleted file mode 100644 index be38b379..00000000 --- a/plugins/sysinfo/xsys.c +++ /dev/null @@ -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 -#include -#include -#include - -#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 , update given setting\n /SYSINFO RESET, reset settings to defaults\n /NETDATA , show transmitted data on given interface\n /NETSTREAM , 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; -} diff --git a/po/POTFILES.in b/po/POTFILES.in index b274cda9..ee756b00 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -43,3 +43,4 @@ src/fe-gtk/textgui.c src/fe-gtk/urlgrab.c src/fe-gtk/userlistgui.c src/fe-text/fe-text.c +plugins/sysinfo/sysinfo.c