#define SHORTSTAT_TEMPL "%*s %llu %llu %llu"
#define LONGSTAT_TEMPL "%*s %llu %llu %llu "
-#ifdef HAVE_LIBDEXTER
-/* need the procraw service from the libdexter dxt-sysinfo plugin */
-#include <dxt-sysinfo/procraw-public.h>
-#define PROCRAW_SERVICE_UUID "ce975a10-0e52-458a-a4b9-253734760436"
-/* timed sampler that delivers the procraw data */
-static DexterTimedSampler *procraw_sampler = NULL;
-/* procraw structure used as /proc surrogate */
-static DxtSysinfoProcrawData procraw_data;
-/* data selector mask for the service */
-gint procraw_mask;
-#endif
-
static int show_nice_processes;
/* this flags tells the linux routines to use the /proc system
info.mask |= (1 << INFO_ENTROPY);
}
-
-#ifdef HAVE_LIBDEXTER
-FILE *open_file(const char *file, int *reported)
-{
- /* this version of open_file() is the hook that ties the client/server code
- * into conky. if conky wants to open a /proc file that the server is feeding
- * us, we do not return an ordinary file stream pointer to the local /proc
- * filesystem. instead, we return a string stream pointer to the proc surrogate,
- * so conky parses remote data as if it were local.
- */
- FILE *fp;
-
- if ((strcmp (file,"/proc/cpuinfo")==0) && (procraw_mask & PROCRAW_CPUINFO))
- {
- if (!procraw_sampler)
- return NULL;
- fp = fmemopen (procraw_data.cpuinfo, procraw_data.cpuinfo_sz, "r");
- }
- else if ((strcmp (file,"/proc/loadavg")==0) && (procraw_mask & PROCRAW_LOADAVG))
- {
- if (!procraw_sampler)
- return NULL;
- fp = fmemopen (procraw_data.loadavg, procraw_data.loadavg_sz, "r");
- }
- else if ((strcmp (file,"/proc/meminfo")==0) && (procraw_mask & PROCRAW_MEMINFO))
- {
- if (!procraw_sampler)
- return NULL;
- fp = fmemopen (procraw_data.meminfo, procraw_data.meminfo_sz, "r");
- }
- else if ((strcmp (file,"/proc/stat")==0) && (procraw_mask & PROCRAW_STAT))
- {
- if (!procraw_sampler)
- return NULL;
- fp = fmemopen (procraw_data.stat, procraw_data.stat_sz, "r");
- }
- else if ((strcmp (file,"/proc/uptime")==0) && (procraw_mask & PROCRAW_UPTIME))
- {
- if (!procraw_sampler)
- return NULL;
- fp = fmemopen (procraw_data.uptime, procraw_data.uptime_sz, "r");
- }
- else if ((strcmp (file,"/proc/net/dev")==0) && (procraw_mask & PROCRAW_NET_DEV))
- {
- if (!procraw_sampler)
- return NULL;
- fp = fmemopen (procraw_data.net_dev, procraw_data.net_dev_sz, "r");
- }
- else if ((strcmp (file,"/proc/diskstats")==0) && (procraw_mask & PROCRAW_DISKSTATS))
- {
- if (!procraw_sampler)
- return NULL;
- fp = fmemopen (procraw_data.diskstats, procraw_data.diskstats_sz, "r");
- }
- else
- {
- fp = fopen(file, "r");
- }
-
- if (!fp)
- {
- if (!reported || *reported == 0)
- {
- ERR("can't open %s: %s", file, strerror(errno));
- if (reported)
- *reported = 1;
- }
- return 0;
- }
- return fp;
-}
-
-void sampler_data_callback (gpointer sampler, gpointer sampler_data)
-{
- /* callback runs in a thread */
- if (!sampler)
- return;
-
- if (sampler_data)
- {
- FILE *out;
- char *p;
- unsigned int i;
- DxtSysinfoProcrawData *data = (DxtSysinfoProcrawData *)sampler_data;
-
- /* use GNU string streams and stdio locking to exchange data with main thread. */
-
- /* update /proc/cpuinfo surrogate */
- for (;data->cpuinfo;)
- {
- if (!(out = open_memstream (&procraw_data.cpuinfo, &procraw_data.cpuinfo_sz)))
- break;
-
- flockfile (out);
- if (procraw_data.cpuinfo)
- {
- free (procraw_data.cpuinfo); procraw_data.cpuinfo=NULL;
- }
- for (p=data->cpuinfo, i=0; i<data->cpuinfo_sz; i++, p++)
- {
- /* we have the FILE lock so use faster putc_unlocked() */
- if (fputc_unlocked (*p, out) == EOF)
- break;
- }
- fclose (out);
- funlockfile (out);
- break;
- }
-
- /* update /proc/loadavg surrogate */
- for (;data->loadavg;)
- {
- if (!(out = open_memstream (&procraw_data.loadavg, &procraw_data.loadavg_sz)))
- break;
-
- flockfile (out);
- if (procraw_data.loadavg)
- {
- free (procraw_data.loadavg); procraw_data.loadavg=NULL;
- }
- for (p=data->loadavg, i=0; i<data->loadavg_sz; i++, p++)
- {
- /* we have the FILE lock so use faster putc_unlocked() */
- if (fputc_unlocked (*p, out) == EOF)
- break;
- }
- fclose (out);
- funlockfile (out);
- break;
- }
-
- /* update /proc/meminfo surrogate */
- for (;data->meminfo;)
- {
- if (!(out = open_memstream (&procraw_data.meminfo, &procraw_data.meminfo_sz)))
- break;
-
- flockfile (out);
- if (procraw_data.meminfo)
- {
- free (procraw_data.meminfo); procraw_data.meminfo=NULL;
- }
- for (p=data->meminfo, i=0; i<data->meminfo_sz; i++, p++)
- {
- /* we have the FILE lock so use faster putc_unlocked() */
- if (fputc_unlocked (*p, out) == EOF)
- break;
- }
- fclose (out);
- funlockfile (out);
- break;
- }
-
- /* update /proc/stat surrogate */
- for (;data->stat;)
- {
- if (!(out = open_memstream (&procraw_data.stat, &procraw_data.stat_sz)))
- break;
-
- flockfile (out);
- if (procraw_data.stat)
- {
- free (procraw_data.stat); procraw_data.stat=NULL;
- }
- for (p=data->stat, i=0; i<data->stat_sz; i++, p++)
- {
- /* we have the FILE lock so use faster putc_unlocked() */
- if (fputc_unlocked (*p, out) == EOF)
- break;
- }
- fclose (out);
- funlockfile (out);
- break;
- }
-
- /* update /proc/uptime surrogate */
- for (;data->uptime;)
- {
- if (!(out = open_memstream (&procraw_data.uptime, &procraw_data.uptime_sz)))
- break;
-
- flockfile (out);
- if (procraw_data.uptime)
- {
- free (procraw_data.uptime); procraw_data.uptime=NULL;
- }
- for (p=data->uptime, i=0; i<data->uptime_sz; i++, p++)
- {
- /* we have the FILE lock so use faster putc_unlocked() */
- if (fputc_unlocked (*p, out) == EOF)
- break;
- }
- fclose (out);
- funlockfile (out);
- break;
- }
-
- /* update /proc/net/dev surrogate */
- for (;data->net_dev;)
- {
- if (!(out = open_memstream (&procraw_data.net_dev, &procraw_data.net_dev_sz)))
- break;
-
- flockfile (out);
- if (procraw_data.net_dev)
- {
- free (procraw_data.net_dev); procraw_data.net_dev=NULL;
- }
- for (p=data->net_dev, i=0; i<data->net_dev_sz; i++, p++)
- {
- /* we have the FILE lock so use faster putc_unlocked() */
- if (fputc_unlocked (*p, out) == EOF)
- break;
- }
- fclose (out);
- funlockfile (out);
- break;
- }
-
- /* update /proc/diskstats surrogate */
- for (;data->diskstats;)
- {
- if (!(out = open_memstream (&procraw_data.diskstats, &procraw_data.diskstats_sz)))
- break;
-
- flockfile (out);
- if (procraw_data.diskstats)
- {
- free (procraw_data.diskstats); procraw_data.diskstats=NULL;
- }
- for (p=data->diskstats, i=0; i<data->diskstats_sz; i++, p++)
- {
- /* we have the FILE lock so use faster putc_unlocked() */
- if (fputc_unlocked (*p, out) == EOF)
- break;
- }
- fclose (out);
- funlockfile (out);
- break;
- }
-
- /* record data packet arrival time */
- g_mutex_lock (packet_mutex);
-#ifdef HAVE_CLOCK_GETTIME
- clock_gettime (CLOCK_REALTIME, &packet_arrival_time);
-#else
- {
- /* fallback to gettimeofday () */
- struct timeval tv;
- if (gettimeofday (&tv, NULL) == 0)
- {
- packet_arrival_time.tv_sec = tv.tv_sec;
- packet_arrival_time.tv_nsec = tv.tv_usec * 1000;
- }
- }
-#endif
- g_mutex_unlock (packet_mutex);
-#ifdef DEBUG
- fprintf(stderr, "Conky: data packet arrived\n");
-#endif
-
- } /* if (sampler_data) ... */
-}
-
-/* return 0 on success, -1 on failure */
-int dexter_client_init (void)
-{
- /* init libdexter for linux-specific client-side activity */
-
- DexterServiceBroker *broker;
- DexterPluginServiceGroup *service_group;
- DexterPluginService *procraw_service;
- DexterSamplerDataCallback *callbacks;
- GError *error = NULL;
-
- /* create a service broker so we can query the server for its services */
- if (!(broker = dexter_service_broker_new (info.dexter.channel)))
- {
- ERR ("unable to create service broker");
- return (-1);
- }
-
- /* fetch the services from the server */
- service_group = dexter_service_broker_get_services (broker, DEXTER_SERVICE_SAMPLER, &error);
- if (error)
- {
- ERR("%s", error->message);
- g_clear_error (&error);
- dexter_service_broker_free (broker);
- return (-1);
- }
-
- /* dont need service broker any more */
- dexter_service_broker_free (broker);
- broker=NULL;
-
- /* find the procraw service */
- procraw_service=NULL;
- if (!dexterplugin_service_group_find_uuid (&procraw_service, service_group, PROCRAW_SERVICE_UUID))
- {
- ERR ("server doesn't offer the procraw service: (%s)", PROCRAW_SERVICE_UUID);
- dexterplugin_service_group_free (service_group);
- return (-1);
- }
-
- /* create null-terminated callback list with one callback on it */
- callbacks = g_new0 (DexterSamplerDataCallback, 2);
- callbacks[0] = sampler_data_callback;
-
- /* create the procraw timed sampler, timed to match conky's update_interval */
- procraw_sampler = dexter_timedsampler_new (procraw_service, update_interval*1000 /* millsecs */,
- callbacks, info.dexter.channel, &error);
- if (error)
- {
- ERR("%s", error->message);
- g_clear_error (&error);
- dexterplugin_service_group_free (service_group);
- return (-1);
- }
-
- /* free callbacks as libdexter makes internal copy */
- g_free (callbacks);
- callbacks=NULL;
-
- /* initialize the timed sampler */
- procraw_mask = 0;
- if (need_mask & (1 << INFO_FREQ))
- procraw_mask |= PROCRAW_CPUINFO;
- if (need_mask & (1 << INFO_LOADAVG))
- procraw_mask |= PROCRAW_LOADAVG;
- if ((need_mask & (1 << INFO_MEM)) || (need_mask & (1 << INFO_BUFFERS)))
- procraw_mask |= PROCRAW_MEMINFO;
- if ((need_mask & (1 << INFO_CPU)) || (need_mask & (1 << INFO_PROCS)) ||
- (need_mask & (1 << INFO_RUN_PROCS)) || (need_mask & (1 << INFO_FREQ )))
- procraw_mask |= PROCRAW_STAT;
- if (need_mask & (1 << INFO_UPTIME))
- procraw_mask |= PROCRAW_UPTIME;
- if (need_mask & (1 << INFO_NET))
- procraw_mask |= PROCRAW_NET_DEV;
- if (need_mask & (1 << INFO_DISKIO))
- procraw_mask |= PROCRAW_DISKSTATS;
-
- dexter_timedsampler_initialize (procraw_sampler, &procraw_mask, NULL, &error);
- if (error)
- {
- ERR("%s", error->message);
- g_clear_error (&error);
- dexter_timedsampler_free (procraw_sampler, NULL);
- dexterplugin_service_group_free (service_group);
- return (-1);
- }
-
- /* start the timed sampler and begin receiving updates from server */
- dexter_timedsampler_start (procraw_sampler, &error);
- if (error)
- {
- ERR("%s", error->message);
- g_clear_error (&error);
- dexter_timedsampler_free (procraw_sampler, NULL);
- dexterplugin_service_group_free (service_group);
- return (-1);
- }
-
- dexterplugin_service_group_free (service_group);
-
- /* so far, so good. tell the linux routines to read /proc,
- * even if other api's are available. */
- prefer_proc = 1;
-
- return 0;
-}
-
-/* return 0 on success, -1 on failure */
-int dexter_client_exit (void)
-{
- /* de-init libdexter for linux-specific client-side activity */
-
- if (procraw_sampler)
- {
- dexter_timedsampler_stop (procraw_sampler, NULL);
- dexter_timedsampler_free (procraw_sampler, NULL);
- procraw_sampler=NULL;
- }
-
- /* free left-over sampler data. ok to do this without thread sync because
- * this function runs in the same thread that conky issues open_file(). */
- if (procraw_data.cpuinfo)
- {
- free (procraw_data.cpuinfo); procraw_data.cpuinfo=NULL;
- }
- if (procraw_data.loadavg)
- {
- free (procraw_data.loadavg); procraw_data.loadavg=NULL;
- }
- if (procraw_data.meminfo)
- {
- free (procraw_data.meminfo); procraw_data.meminfo=NULL;
- }
- if (procraw_data.stat)
- {
- free (procraw_data.stat); procraw_data.stat=NULL;
- }
- if (procraw_data.uptime)
- {
- free (procraw_data.uptime); procraw_data.uptime=NULL;
- }
- if (procraw_data.net_dev)
- {
- free (procraw_data.net_dev); procraw_data.net_dev=NULL;
- }
- if (procraw_data.diskstats)
- {
- free (procraw_data.diskstats); procraw_data.diskstats=NULL;
- }
-
- info.uptime=0.0;
- info.procs=0;
- info.mem = info.memmax = info.swap = info.swapmax = info.bufmem = info.buffers = info.cached = 0;
- info.run_procs=0;
- if (info.cpu_usage)
- {
- memset(info.cpu_usage, 0, info.cpu_count * sizeof (float));
- }
- clear_net_stats ();
- diskio_value=0;
- return 0;
-}
-#endif