Reformatted all code

git-svn-id: https://conky.svn.sourceforge.net/svnroot/conky/trunk/conky1@1007 7f574dfc-610e-0410-a909-a81674777703
This commit is contained in:
Kevin Lyles
2008-02-20 20:30:45 +00:00
parent 3cf1a29768
commit 3d26a4880e
51 changed files with 9342 additions and 8872 deletions

View File

@@ -1,7 +1,6 @@
/* $Id$ */
/*
* audacious.c: conky support for audacious music player
/* audacious.c: conky support for audacious music player
*
* Copyright (C) 2005-2007 Philip Kovacs pkovacs@users.sourceforge.net
*
@@ -18,9 +17,7 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
* USA.
*
*/
* USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -36,16 +33,26 @@
#include <audacious/dbus.h>
#else
#include <audacious/beepctrl.h>
#define audacious_remote_is_running(x) xmms_remote_is_running(x)
#define audacious_remote_is_paused(x) xmms_remote_is_paused(x)
#define audacious_remote_is_playing(x) xmms_remote_is_playing(x)
#define audacious_remote_get_playlist_pos(x) xmms_remote_get_playlist_pos(x)
#define audacious_remote_get_playlist_title(x,y) xmms_remote_get_playlist_title(x,y)
#define audacious_remote_get_playlist_time(x,y) xmms_remote_get_playlist_time(x,y)
#define audacious_remote_get_output_time(x) xmms_remote_get_output_time(x)
#define audacious_remote_get_info(w,x,y,z) xmms_remote_get_info(w,x,y,z)
#define audacious_remote_get_playlist_file(x,y) xmms_remote_get_playlist_file(x,y)
#define audacious_remote_get_playlist_length(x) xmms_remote_get_playlist_length(x)
#define audacious_remote_is_running(x) \
xmms_remote_is_running(x)
#define audacious_remote_is_paused(x) \
xmms_remote_is_paused(x)
#define audacious_remote_is_playing(x) \
xmms_remote_is_playing(x)
#define audacious_remote_get_playlist_pos(x) \
xmms_remote_get_playlist_pos(x)
#define audacious_remote_get_playlist_title(x, y) \
xmms_remote_get_playlist_title(x, y)
#define audacious_remote_get_playlist_time(x, y) \
xmms_remote_get_playlist_time(x, y)
#define audacious_remote_get_output_time(x) \
xmms_remote_get_output_time(x)
#define audacious_remote_get_info(w, x, y, z) \
xmms_remote_get_info(w, x, y, z)
#define audacious_remote_get_playlist_file(x, y) \
xmms_remote_get_playlist_file(x, y)
#define audacious_remote_get_playlist_length(x) \
xmms_remote_get_playlist_length(x)
#endif
#include "config.h"
@@ -61,49 +68,54 @@ static audacious_t audacious_items;
* ----------------------------------------- */
void update_audacious(void)
{
/*
The worker thread is updating audacious_items array asynchronously to the main
conky thread. We merely copy the audacious_items array into the main thread's
info structure when the main thread's update cycle fires.
*/
if (!info.audacious.p_timed_thread)
/* The worker thread is updating audacious_items array asynchronously
* to the main conky thread.
* We merely copy the audacious_items array into the main thread's info
* structure when the main thread's update cycle fires. */
if (!info.audacious.p_timed_thread) {
return;
}
timed_thread_lock (info.audacious.p_timed_thread);
memcpy(&info.audacious.items,audacious_items,sizeof(audacious_items));
timed_thread_unlock (info.audacious.p_timed_thread);
timed_thread_lock(info.audacious.p_timed_thread);
memcpy(&info.audacious.items, audacious_items, sizeof(audacious_items));
timed_thread_unlock(info.audacious.p_timed_thread);
}
/* ------------------------------------------------------------
/* ---------------------------------------------------------
* Create a worker thread for audacious media player status.
*
* Returns 0 on success, -1 on error.
* ------------------------------------------------------------*/
* --------------------------------------------------------- */
int create_audacious_thread(void)
{
if (!info.audacious.p_timed_thread)
if (!info.audacious.p_timed_thread) {
info.audacious.p_timed_thread =
timed_thread_create (audacious_thread_func, NULL, info.music_player_interval * 1000000);
timed_thread_create(audacious_thread_func, NULL,
info.music_player_interval * 1000000);
}
if (!info.audacious.p_timed_thread || timed_thread_run (info.audacious.p_timed_thread))
return (-1);
if (!info.audacious.p_timed_thread
|| timed_thread_run(info.audacious.p_timed_thread)) {
return -1;
}
return 0;
}
/* ------------------------------------------------
/* ---------------------------------------
* Destroy audacious player status thread.
*
* Returns 0 on success, -1 on error.
* ------------------------------------------------ */
* --------------------------------------- */
int destroy_audacious_thread(void)
{
/* Is a worker is thread running? If not, no error. */
if (!info.audacious.p_timed_thread)
return(0);
if (!info.audacious.p_timed_thread) {
return 0;
}
timed_thread_destroy (info.audacious.p_timed_thread, &info.audacious.p_timed_thread);
timed_thread_destroy(info.audacious.p_timed_thread,
&info.audacious.p_timed_thread);
return 0;
}
@@ -114,9 +126,9 @@ int destroy_audacious_thread(void)
void *audacious_thread_func(void *pvoid)
{
static audacious_t items;
gint playpos,frames,length;
gint rate,freq,chans;
gchar *psong,*pfilename;
gint playpos, frames, length;
gint rate, freq, chans;
gchar *psong, *pfilename;
#ifndef AUDACIOUS_LEGACY
DBusGProxy *session = NULL;
@@ -125,112 +137,117 @@ void *audacious_thread_func(void *pvoid)
gint session;
#endif
pvoid=(void *)pvoid; /* avoid warning */
session=0;
psong=NULL;
pfilename=NULL;
pvoid = (void *) pvoid; /* avoid warning */
session = 0;
psong = NULL;
pfilename = NULL;
#ifndef AUDACIOUS_LEGACY
g_type_init ();
connection = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
g_type_init();
connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
if (!connection) {
CRIT_ERR ("unable to establish dbus connection");
CRIT_ERR("unable to establish dbus connection");
}
session = dbus_g_proxy_new_for_name (connection,
AUDACIOUS_DBUS_SERVICE,
AUDACIOUS_DBUS_PATH,
AUDACIOUS_DBUS_INTERFACE);
session = dbus_g_proxy_new_for_name(connection, AUDACIOUS_DBUS_SERVICE,
AUDACIOUS_DBUS_PATH, AUDACIOUS_DBUS_INTERFACE);
if (!session) {
CRIT_ERR ("unable to create dbus proxy");
CRIT_ERR("unable to create dbus proxy");
}
#endif /* AUDACIOUS_LEGACY */
/* Loop until the main thread resets the runnable signal. */
while (1) {
if (!audacious_remote_is_running (session))
{
memset(&items,0,sizeof(items));
strcpy(items[AUDACIOUS_STATUS],"Not running");
if (!audacious_remote_is_running(session)) {
memset(&items, 0, sizeof(items));
strcpy(items[AUDACIOUS_STATUS], "Not running");
goto bottom;
}
/* Player status */
if (audacious_remote_is_paused (session))
strcpy(items[AUDACIOUS_STATUS],"Paused");
else if (audacious_remote_is_playing (session))
strcpy(items[AUDACIOUS_STATUS],"Playing");
else
strcpy(items[AUDACIOUS_STATUS],"Stopped");
if (audacious_remote_is_paused(session)) {
strcpy(items[AUDACIOUS_STATUS], "Paused");
} else if (audacious_remote_is_playing(session)) {
strcpy(items[AUDACIOUS_STATUS], "Playing");
} else {
strcpy(items[AUDACIOUS_STATUS], "Stopped");
}
/* Current song title */
playpos = audacious_remote_get_playlist_pos (session);
psong = audacious_remote_get_playlist_title (session, playpos);
if (psong)
{
strncpy(items[AUDACIOUS_TITLE],psong,sizeof(items[AUDACIOUS_TITLE])-1);
g_free (psong);
psong=NULL;
playpos = audacious_remote_get_playlist_pos(session);
psong = audacious_remote_get_playlist_title(session, playpos);
if (psong) {
strncpy(items[AUDACIOUS_TITLE], psong,
sizeof(items[AUDACIOUS_TITLE]) - 1);
g_free(psong);
psong = NULL;
}
/* Current song length as MM:SS */
frames = audacious_remote_get_playlist_time (session,playpos);
frames = audacious_remote_get_playlist_time(session, playpos);
length = frames / 1000;
snprintf(items[AUDACIOUS_LENGTH],sizeof(items[AUDACIOUS_LENGTH])-1, "%d:%.2d", length / 60, length % 60);
/* Current song length in seconds */
snprintf(items[AUDACIOUS_LENGTH_SECONDS],sizeof(items[AUDACIOUS_LENGTH_SECONDS])-1, "%d", length);
/* Current song position as MM:SS */
frames = audacious_remote_get_output_time (session);
length = frames / 1000;
snprintf(items[AUDACIOUS_POSITION],sizeof(items[AUDACIOUS_POSITION])-1,
snprintf(items[AUDACIOUS_LENGTH], sizeof(items[AUDACIOUS_LENGTH]) - 1,
"%d:%.2d", length / 60, length % 60);
/* Current song length in seconds */
snprintf(items[AUDACIOUS_LENGTH_SECONDS],
sizeof(items[AUDACIOUS_LENGTH_SECONDS]) - 1, "%d", length);
/* Current song position as MM:SS */
frames = audacious_remote_get_output_time(session);
length = frames / 1000;
snprintf(items[AUDACIOUS_POSITION],
sizeof(items[AUDACIOUS_POSITION]) - 1, "%d:%.2d", length / 60,
length % 60);
/* Current song position in seconds */
snprintf(items[AUDACIOUS_POSITION_SECONDS],sizeof(items[AUDACIOUS_POSITION_SECONDS])-1, "%d", length);
snprintf(items[AUDACIOUS_POSITION_SECONDS],
sizeof(items[AUDACIOUS_POSITION_SECONDS]) - 1, "%d", length);
/* Current song bitrate */
audacious_remote_get_info (session, &rate, &freq, &chans);
snprintf(items[AUDACIOUS_BITRATE],sizeof(items[AUDACIOUS_BITRATE])-1, "%d", rate);
audacious_remote_get_info(session, &rate, &freq, &chans);
snprintf(items[AUDACIOUS_BITRATE], sizeof(items[AUDACIOUS_BITRATE]) - 1,
"%d", rate);
/* Current song frequency */
snprintf(items[AUDACIOUS_FREQUENCY],sizeof(items[AUDACIOUS_FREQUENCY])-1, "%d", freq);
snprintf(items[AUDACIOUS_FREQUENCY],
sizeof(items[AUDACIOUS_FREQUENCY]) - 1, "%d", freq);
/* Current song channels */
snprintf(items[AUDACIOUS_CHANNELS],sizeof(items[AUDACIOUS_CHANNELS])-1, "%d", chans);
snprintf(items[AUDACIOUS_CHANNELS],
sizeof(items[AUDACIOUS_CHANNELS]) - 1, "%d", chans);
/* Current song filename */
pfilename = audacious_remote_get_playlist_file (session,playpos);
if (pfilename)
{
strncpy(items[AUDACIOUS_FILENAME],pfilename,sizeof(items[AUDACIOUS_FILENAME])-1);
g_free (pfilename);
pfilename=NULL;
pfilename = audacious_remote_get_playlist_file(session, playpos);
if (pfilename) {
strncpy(items[AUDACIOUS_FILENAME], pfilename,
sizeof(items[AUDACIOUS_FILENAME]) - 1);
g_free(pfilename);
pfilename = NULL;
}
/* Length of the Playlist (number of songs) */
length = audacious_remote_get_playlist_length (session);
snprintf(items[AUDACIOUS_PLAYLIST_LENGTH],sizeof(items[AUDACIOUS_PLAYLIST_LENGTH])-1, "%d", length);
length = audacious_remote_get_playlist_length(session);
snprintf(items[AUDACIOUS_PLAYLIST_LENGTH],
sizeof(items[AUDACIOUS_PLAYLIST_LENGTH]) - 1, "%d", length);
/* Playlist position (index of song) */
snprintf(items[AUDACIOUS_PLAYLIST_POSITION],sizeof(items[AUDACIOUS_PLAYLIST_POSITION])-1,
"%d", playpos+1);
snprintf(items[AUDACIOUS_PLAYLIST_POSITION],
sizeof(items[AUDACIOUS_PLAYLIST_POSITION]) - 1, "%d", playpos + 1);
bottom:
/* Deliver the refreshed items array to audacious_items. */
timed_thread_lock (info.audacious.p_timed_thread);
memcpy(&audacious_items,items,sizeof(items));
timed_thread_unlock (info.audacious.p_timed_thread);
timed_thread_lock(info.audacious.p_timed_thread);
memcpy(&audacious_items, items, sizeof(items));
timed_thread_unlock(info.audacious.p_timed_thread);
if (timed_thread_test (info.audacious.p_timed_thread)) {
if (timed_thread_test(info.audacious.p_timed_thread)) {
#ifndef AUDACIOUS_LEGACY
/* release reference to dbus proxy */
g_object_unref (session);
g_object_unref(session);
#endif
timed_thread_exit (info.audacious.p_timed_thread);
timed_thread_exit(info.audacious.p_timed_thread);
}
}
}

View File

@@ -1,7 +1,6 @@
/* $Id$ */
/*
* audacious.h: conky support for audacious music player
/* audacious.h: conky support for audacious music player
*
* Copyright (C) 2005-2007 Philip Kovacs pkovacs@users.sourceforge.net
*
@@ -18,15 +17,13 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
* USA.
*
*/
* USA. */
#ifndef AUDACIOUS_H
#define AUDACIOUS_H
enum _audacious_items {
AUDACIOUS_STATUS=0,
AUDACIOUS_STATUS = 0,
AUDACIOUS_TITLE,
AUDACIOUS_LENGTH,
AUDACIOUS_LENGTH_SECONDS,

View File

@@ -1,5 +1,4 @@
/*
* Conky, a system monitor, based on torsmo
/* Conky, a system monitor, based on torsmo
*
* Any original torsmo code is licensed under the BSD license
*
@@ -7,7 +6,8 @@
*
* Please see COPYING for details
*
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
@@ -22,8 +22,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*/
* $Id$ */
#include <bmp/dbus.hh>
#include <dbus/dbus-glib.h>
@@ -33,7 +32,8 @@
#include "conky.h"
#define DBUS_TYPE_G_STRING_VALUE_HASHTABLE (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
#define DBUS_TYPE_G_STRING_VALUE_HASHTABLE \
(dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
static DBusGConnection *bus;
static DBusGProxy *remote_object;
@@ -57,10 +57,8 @@ void update_bmpx()
goto fail;
}
remote_object = dbus_g_proxy_new_for_name(bus,
BMP_DBUS_SERVICE,
BMP_DBUS_PATH,
BMP_DBUS_INTERFACE);
remote_object = dbus_g_proxy_new_for_name(bus, BMP_DBUS_SERVICE,
BMP_DBUS_PATH, BMP_DBUS_INTERFACE);
if (!remote_object) {
ERR("BMPx error 2: %s\n", error->message);
goto fail;
@@ -71,19 +69,15 @@ void update_bmpx()
if (connected == 1) {
if (dbus_g_proxy_call(remote_object, "GetCurrentTrack", &error,
G_TYPE_INVALID,
G_TYPE_INT, &current_track, G_TYPE_INVALID)) {
G_TYPE_INVALID, G_TYPE_INT, &current_track, G_TYPE_INVALID)) {
} else {
ERR("BMPx error 3: %s\n", error->message);
goto fail;
}
if (dbus_g_proxy_call(remote_object, "GetMetadataForListItem", &error,
G_TYPE_INT,
current_track,
G_TYPE_INVALID,
DBUS_TYPE_G_STRING_VALUE_HASHTABLE,
&metadata,
G_TYPE_INT, current_track, G_TYPE_INVALID,
DBUS_TYPE_G_STRING_VALUE_HASHTABLE, &metadata,
G_TYPE_INVALID)) {
if (current_info->bmpx.title) {
free(current_info->bmpx.title);
@@ -97,12 +91,18 @@ void update_bmpx()
free(current_info->bmpx.album);
current_info->bmpx.album = 0;
}
current_info->bmpx.title = g_value_dup_string(g_hash_table_lookup(metadata, "title"));
current_info->bmpx.artist = g_value_dup_string(g_hash_table_lookup(metadata, "artist"));
current_info->bmpx.album = g_value_dup_string(g_hash_table_lookup(metadata, "album"));
current_info->bmpx.bitrate = g_value_get_int(g_hash_table_lookup(metadata, "bitrate"));
current_info->bmpx.track = g_value_get_int(g_hash_table_lookup(metadata, "track-number"));
current_info->bmpx.uri = g_value_get_string(g_hash_table_lookup(metadata, "location"));
current_info->bmpx.title =
g_value_dup_string(g_hash_table_lookup(metadata, "title"));
current_info->bmpx.artist =
g_value_dup_string(g_hash_table_lookup(metadata, "artist"));
current_info->bmpx.album =
g_value_dup_string(g_hash_table_lookup(metadata, "album"));
current_info->bmpx.bitrate =
g_value_get_int(g_hash_table_lookup(metadata, "bitrate"));
current_info->bmpx.track =
g_value_get_int(g_hash_table_lookup(metadata, "track-number"));
current_info->bmpx.uri =
g_value_get_string(g_hash_table_lookup(metadata, "location"));
} else {
ERR("BMPx error 4: %s\n", error->message);
goto fail;
@@ -111,8 +111,9 @@ void update_bmpx()
g_hash_table_destroy(metadata);
} else {
fail:
if (error)
if (error) {
g_error_free(error);
}
if (current_info->bmpx.title) {
g_free(current_info->bmpx.title);
current_info->bmpx.title = 0;

View File

@@ -1,5 +1,4 @@
/*
* Conky, a system monitor, based on torsmo
/* Conky, a system monitor, based on torsmo
*
* Any original torsmo code is licensed under the BSD license
*
@@ -8,7 +7,8 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*/
* $Id$ */
#include "conky.h"
#include <stdio.h>
@@ -45,6 +44,7 @@ void update_uname()
double get_time()
{
struct timeval tv;
gettimeofday(&tv, 0);
return tv.tv_sec + (tv.tv_usec / 1000000.0);
}
@@ -52,12 +52,14 @@ double get_time()
FILE *open_file(const char *file, int *reported)
{
FILE *fp = fopen(file, "r");
if (!fp) {
if (!reported || *reported == 0) {
ERR("can't open %s: %s", file, strerror(errno));
if (reported)
if (reported) {
*reported = 1;
}
}
return 0;
}
@@ -78,30 +80,33 @@ void variable_substitute(const char *s, char *dest, unsigned int n)
if (*s == '{') {
s++;
a = s;
while (*s && *s != '}')
while (*s && *s != '}') {
s++;
}
} else {
a = s;
while (*s && (isalnum((int) *s)
|| *s == '_'))
while (*s && (isalnum((int) *s) || *s == '_')) {
s++;
}
}
/* copy variable to buffer and look it up */
len = (s - a > 255) ? 255 : (s - a);
strncpy(buf, a, len);
buf[len] = '\0';
if (*s == '}')
if (*s == '}') {
s++;
}
var = getenv(buf);
if (var) {
/* add var to dest */
len = strlen(var);
if (len >= n)
if (len >= n) {
len = n - 1;
}
strncpy(dest, var, len);
dest += len;
n -= len;
@@ -125,14 +130,16 @@ struct net_stat *get_net_stat(const char *dev)
{
unsigned int i;
if (!dev)
if (!dev) {
return 0;
}
/* find interface stat */
for (i = 0; i < 16; i++) {
if (netstats[i].dev && strcmp(netstats[i].dev, dev) == 0)
if (netstats[i].dev && strcmp(netstats[i].dev, dev) == 0) {
return &netstats[i];
}
}
/* wasn't found? add it */
if (i == 16) {
@@ -148,51 +155,53 @@ struct net_stat *get_net_stat(const char *dev)
return 0;
}
void clear_net_stats (void)
void clear_net_stats(void)
{
memset (netstats, 0, sizeof(netstats));
memset(netstats, 0, sizeof(netstats));
}
void format_seconds(char *buf, unsigned int n, long t)
{
if (t >= 24 * 60 * 60) /* hours necessary when there are days? */
snprintf(buf, n, "%ldd %ldh %ldm", t / 60 / 60 / 24,
(t / 60 / 60) % 24, (t / 60) % 60);
else if (t >= 60 * 60)
snprintf(buf, n, "%ldh %ldm", (t / 60 / 60) % 24,
if (t >= 24 * 60 * 60) { /* hours necessary when there are days? */
snprintf(buf, n, "%ldd %ldh %ldm", t / 60 / 60 / 24, (t / 60 / 60) % 24,
(t / 60) % 60);
else
} else if (t >= 60 * 60) {
snprintf(buf, n, "%ldh %ldm", (t / 60 / 60) % 24, (t / 60) % 60);
} else {
snprintf(buf, n, "%ldm %lds", t / 60, t % 60);
}
}
void format_seconds_short(char *buf, unsigned int n, long t)
{
if (t >= 24 * 60 * 60)
snprintf(buf, n, "%ldd %ldh", t / 60 / 60 / 24,
(t / 60 / 60) % 24);
else if (t >= 60 * 60)
snprintf(buf, n, "%ldh %ldm", (t / 60 / 60) % 24,
(t / 60) % 60);
else
if (t >= 24 * 60 * 60) {
snprintf(buf, n, "%ldd %ldh", t / 60 / 60 / 24, (t / 60 / 60) % 24);
} else if (t >= 60 * 60) {
snprintf(buf, n, "%ldh %ldm", (t / 60 / 60) % 24, (t / 60) % 60);
} else {
snprintf(buf, n, "%ldm", t / 60);
}
}
static double last_meminfo_update;
static double last_fs_update;
unsigned long long need_mask;
#define NEED(a) ((need_mask & (1 << a)) && ((info.mask & (1 << a)) == 0))
void update_stuff()
{
unsigned int i;
info.mask = 0;
if (no_buffers)
if (no_buffers) {
need_mask |= 1 << INFO_BUFFERS;
}
/* clear speeds and up status in case device was removed and doesn't get
updated */
* updated */
for (i = 0; i < 16; i++) {
if (netstats[i].dev) {
@@ -204,66 +213,77 @@ void update_stuff()
prepare_update();
if (NEED(INFO_UPTIME))
if (NEED(INFO_UPTIME)) {
update_uptime();
}
if (NEED(INFO_PROCS))
if (NEED(INFO_PROCS)) {
update_total_processes();
}
if (NEED(INFO_RUN_PROCS))
if (NEED(INFO_RUN_PROCS)) {
update_running_processes();
}
if (NEED(INFO_CPU))
if (NEED(INFO_CPU)) {
update_cpu_usage();
}
if (NEED(INFO_NET))
if (NEED(INFO_NET)) {
update_net_stats();
}
if (NEED(INFO_DISKIO))
if (NEED(INFO_DISKIO)) {
update_diskio();
}
#if defined(__linux__)
if (NEED(INFO_I8K))
if (NEED(INFO_I8K)) {
update_i8k();
}
#endif /* __linux__ */
#ifdef MPD
if (NEED(INFO_MPD)) {
if (!mpd_timed_thread) {
init_mpd_stats(&info);
mpd_timed_thread =
timed_thread_create((void*)update_mpd, (void*) NULL, info.music_player_interval * 1000000);
mpd_timed_thread = timed_thread_create((void *) update_mpd,
(void *) NULL, info.music_player_interval * 1000000);
if (!mpd_timed_thread) {
ERR("Failed to create MPD timed thread");
}
timed_thread_register(mpd_timed_thread, &mpd_timed_thread);
if (timed_thread_run (mpd_timed_thread))
if (timed_thread_run(mpd_timed_thread)) {
ERR("Failed to run MPD timed thread");
}
}
}
#endif
#ifdef XMMS2
if (NEED(INFO_XMMS2))
if (NEED(INFO_XMMS2)) {
update_xmms2();
}
#endif
#ifdef AUDACIOUS
if (NEED(INFO_AUDACIOUS))
if (NEED(INFO_AUDACIOUS)) {
update_audacious();
}
#endif
#ifdef BMPX
if (NEED(INFO_BMPX))
if (NEED(INFO_BMPX)) {
update_bmpx();
}
#endif
if (NEED(INFO_LOADAVG))
if (NEED(INFO_LOADAVG)) {
update_load_average();
}
if ((NEED(INFO_MEM) || NEED(INFO_BUFFERS) || NEED(INFO_TOP)) &&
current_update_time - last_meminfo_update > 6.9) {
if ((NEED(INFO_MEM) || NEED(INFO_BUFFERS) || NEED(INFO_TOP))
&& current_update_time - last_meminfo_update > 6.9) {
update_meminfo();
if (no_buffers) {
info.mem -= info.bufmem;
@@ -271,8 +291,9 @@ void update_stuff()
last_meminfo_update = current_update_time;
}
if (NEED(INFO_TOP))
if (NEED(INFO_TOP)) {
update_top();
}
/* update_fs_stat() won't do anything if there aren't fs -things */
if (NEED(INFO_FS) && current_update_time - last_fs_update > 12.9) {
@@ -280,11 +301,13 @@ void update_stuff()
last_fs_update = current_update_time;
}
#ifdef TCP_PORT_MONITOR
if (NEED(INFO_TCP_PORT_MONITOR))
update_tcp_port_monitor_collection( info.p_tcp_port_monitor_collection );
if (NEED(INFO_TCP_PORT_MONITOR)) {
update_tcp_port_monitor_collection(info.p_tcp_port_monitor_collection);
}
#endif
if (NEED(INFO_ENTROPY))
if (NEED(INFO_ENTROPY)) {
update_entropy();
}
}
int round_to_int(float f)

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,4 @@
/*
* Conky, a system monitor, based on torsmo
/* Conky, a system monitor, based on torsmo
*
* Any original torsmo code is licensed under the BSD license
*
@@ -8,7 +7,8 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*/
* $Id$ */
#ifndef _conky_h_
#define _conky_h_
@@ -32,6 +31,7 @@
#if defined(HAS_MCHECK_H)
#include <mcheck.h>
#endif /* HAS_MCHECK_H */
#include "config.h"
#include <sys/utsname.h>
#include <stdio.h>
@@ -41,15 +41,15 @@
#include <langinfo.h>
#include <wchar.h>
#include <sys/param.h>
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <sys/mount.h>
#include <sys/ucred.h>
#include <fcntl.h>
#include <kvm.h>
#endif /* __FreeBSD__ */
#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) && (defined(i386) || defined(__i386__))
#if (defined(i386) || defined(__i386__))
#include <machine/apm_bios.h>
#endif /* i386 || __i386__ */
#endif /* __FreeBSD__ */
#if defined(__OpenBSD__)
@@ -91,12 +91,11 @@ extern unsigned int text_buffer_size;
#include <sys/socket.h>
#define ERR(s, varargs...) \
fprintf(stderr, "Conky: " s "\n", ##varargs)
#define ERR(s, varargs...) fprintf(stderr, "Conky: " s "\n", ##varargs)
/* critical error */
#define CRIT_ERR(s, varargs...) \
{ fprintf(stderr, "Conky: " s "\n", ##varargs); exit(EXIT_FAILURE); }
{ fprintf(stderr, "Conky: " s "\n", ##varargs); exit(EXIT_FAILURE); }
struct i8k_struct {
char *version;
@@ -160,10 +159,10 @@ struct mail_s { // for imap and pop3
char secure;
} mail;
/*struct cpu_stat {
/* struct cpu_stat {
unsigned int user, nice, system, idle, iowait, irq, softirq;
int cpu_avg_samples;
};*/
}; */
#ifdef MPD
struct mpd_s {
@@ -191,15 +190,15 @@ struct mpd_s {
#ifdef XMMS2
struct xmms2_s {
char* artist;
char* album;
char* title;
char* genre;
char* comment;
char* decoder;
char* transport;
char* url;
char* date;
char *artist;
char *album;
char *title;
char *genre;
char *comment;
char *decoder;
char *transport;
char *url;
char *date;
int tracknr;
int bitrate;
unsigned int id;
@@ -208,7 +207,7 @@ struct xmms2_s {
float size;
float progress;
char* status;
char *status;
};
#endif
@@ -283,7 +282,6 @@ enum {
#endif
};
/* get_battery_stuff() item selector */
enum {
BATTERY_STATUS,
@@ -324,7 +322,7 @@ struct information {
float loadavg[3];
struct mail_s* mail;
struct mail_s *mail;
int mail_running;
#ifdef MPD
struct mpd_s mpd;
@@ -348,7 +346,7 @@ struct information {
struct process *first_process;
unsigned long looped;
#ifdef TCP_PORT_MONITOR
tcp_port_monitor_collection_t * p_tcp_port_monitor_collection;
tcp_port_monitor_collection_t *p_tcp_port_monitor_collection;
#endif
struct entropy_s entropy;
double music_player_interval;
@@ -357,17 +355,20 @@ struct information {
};
enum {
KFLAG_IS_LONGSTAT = 0x01, /* set to true if kernel uses "long" format for /proc/stats */
KFLAG_PROC_IS_THREADS=0x02 /* set to true if kernel shows # of threads for the proc value in sysinfo() call */
/* KFLAG_NEXT_ONE=0x04 bits 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 available for future use */
};
/* set to true if kernel uses "long" format for /proc/stats */
KFLAG_IS_LONGSTAT = 0x01,
/* set to true if kernel shows # of threads for the proc value
* in sysinfo() call */
KFLAG_PROC_IS_THREADS = 0x02
/* bits 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 available for future use */
/* KFLAG_NEXT_ONE = 0x04 */
};
#define KFLAG_SETON(a) info.kflags |= a
#define KFLAG_SETOFF(a) info.kflags &= (~a)
#define KFLAG_FLIP(a) info.kflags ^= a
#define KFLAG_ISSET(a) info.kflags & a
int out_to_console;
int top_cpu;
@@ -412,11 +413,13 @@ enum _window_hints {
HINT_SKIP_TASKBAR,
HINT_SKIP_PAGER
};
#define SET_HINT(mask,hint) (mask |= (1<<hint))
#define TEST_HINT(mask,hint) (mask & (1<<hint))
#define SET_HINT(mask, hint) (mask |= (1 << hint))
#define TEST_HINT(mask, hint) (mask & (1 << hint))
#endif
struct conky_window {
Window root,window,desktop;
Window root, window, desktop;
Drawable drawable;
GC gc;
#ifdef HAVE_XDBE
@@ -442,7 +445,6 @@ struct conky_window {
extern int use_xdbe;
#endif
#ifdef XFT
extern int use_xft;
#endif
@@ -457,8 +459,8 @@ extern int workarea[4];
extern struct conky_window window;
void init_X11();
void init_window(int use_own_window, int width, int height, int set_trans, int back_colour,
char **argv, int argc);
void init_window(int use_own_window, int width, int height, int set_trans,
int back_colour, char **argv, int argc);
void create_gc();
void set_transparent_background(Window win);
long get_x11_color(const char *);
@@ -508,31 +510,31 @@ void update_cpu_usage(void);
void update_total_processes(void);
void update_running_processes(void);
void update_i8k(void);
char get_freq( char *, size_t, char *, int, unsigned int );
void get_freq_dynamic( char *, size_t, char *, int );
char get_voltage(char *, size_t, char *, int, unsigned int ); /* ptarjan */
char get_freq(char *, size_t, char *, int, unsigned int);
void get_freq_dynamic(char *, size_t, char *, int);
char get_voltage(char *, size_t, char *, int, unsigned int); /* ptarjan */
void update_load_average();
int open_sysfs_sensor(const char *dir, const char *dev, const char *type, int n, int *div, char *devtype);
#define open_i2c_sensor(dev,type,n,div,devtype) \
open_sysfs_sensor("/sys/bus/i2c/devices/",dev,type,n,div,devtype)
int open_sysfs_sensor(const char *dir, const char *dev, const char *type, int n,
int *div, char *devtype);
#define open_platform_sensor(dev,type,n,div,devtype) \
open_sysfs_sensor("/sys/bus/platform/devices/",dev,type,n,div,devtype)
#define open_hwmon_sensor(dev,type,n,div,devtype) \
open_sysfs_sensor("/sys/class/hwmon/",dev,type,n,div,devtype); \
#define open_i2c_sensor(dev, type, n, div, devtype) \
open_sysfs_sensor("/sys/bus/i2c/devices/", dev, type, n, div, devtype)
#define open_platform_sensor(dev, type, n, div, devtype) \
open_sysfs_sensor("/sys/bus/platform/devices/", dev, type, n, div, devtype)
#define open_hwmon_sensor(dev, type, n, div, devtype) \
open_sysfs_sensor("/sys/class/hwmon/", dev, type, n, div, devtype)
double get_sysfs_info(int *fd, int arg, char *devtype, char *type);
void get_adt746x_cpu( char *, size_t );
void get_adt746x_fan( char *, size_t );
void get_adt746x_cpu(char *, size_t);
void get_adt746x_fan(char *, size_t);
unsigned int get_diskio(void);
int open_acpi_temperature(const char *name);
double get_acpi_temperature(int fd);
void get_acpi_ac_adapter( char *, size_t );
void get_acpi_fan( char *, size_t );
void get_acpi_ac_adapter(char *, size_t);
void get_acpi_fan(char *, size_t);
void get_battery_stuff(char *buf, unsigned int n, const char *bat, int item);
int get_battery_perct(const char *bat);
int get_battery_perct_bar(const char *bat);
@@ -563,9 +565,8 @@ struct obsd_sensors_struct {
struct obsd_sensors_struct obsd_sensors;
#endif /* __OpenBSD__ */
enum { PB_BATT_STATUS, PB_BATT_PERCENT, PB_BATT_TIME};
void get_powerbook_batt_info(char*, size_t, int);
enum { PB_BATT_STATUS, PB_BATT_PERCENT, PB_BATT_TIME };
void get_powerbook_batt_info(char *, size_t, int);
struct process {
struct process *next;
@@ -625,7 +626,8 @@ void update_mail_count();
kvm_t *kd;
#endif
#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__)) && (defined(i386) || defined(__i386__))
#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) \
|| defined(__OpenBSD__)) && (defined(i386) || defined(__i386__))
#ifdef __OpenBSD__
typedef struct apm_power_info *apm_info_t;
#endif
@@ -655,7 +657,7 @@ char *get_hddtemp_info(char *dev, char *addr, int port, char *unit);
/* in rss.c */
#ifdef RSS
PRSS* get_rss_info(char *uri, int delay);
PRSS *get_rss_info(char *uri, int delay);
void init_rss_info();
void free_rss_info();
#endif /* RSS */
@@ -663,5 +665,3 @@ void free_rss_info();
/* in linux.c */
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,4 @@
/*
* Conky, a system monitor, based on torsmo
/* Conky, a system monitor, based on torsmo
*
* Any original torsmo code is licensed under the BSD license
*
@@ -8,7 +7,8 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*/
* $Id$ */
#include "conky.h"
#include <unistd.h>
@@ -52,40 +51,48 @@
static struct fs_stat fs_stats_[MAX_FS_STATS];
struct fs_stat *fs_stats = fs_stats_;
static void update_fs_stat(struct fs_stat* fs);
static void update_fs_stat(struct fs_stat *fs);
void update_fs_stats()
{
unsigned i;
for(i=0; i<MAX_FS_STATS; ++i)
if(fs_stats[i].path)
for (i = 0; i < MAX_FS_STATS; ++i) {
if (fs_stats[i].path) {
update_fs_stat(&fs_stats[i]);
}
}
}
void clear_fs_stats()
{
unsigned i;
for(i=0; i<MAX_FS_STATS; ++i)
if(fs_stats[i].path) {
for (i = 0; i < MAX_FS_STATS; ++i) {
if (fs_stats[i].path) {
free(fs_stats[i].path);
fs_stats[i].path = 0;
fs_stats[i].path = NULL;
}
}
}
struct fs_stat *prepare_fs_stat(const char *s)
{
struct fs_stat* new = 0;
struct fs_stat *new = 0;
unsigned i;
/* lookup existing or get new */
for(i=0; i<MAX_FS_STATS; ++i) {
if(fs_stats[i].path) {
if(strcmp(fs_stats[i].path, s) == 0)
for (i = 0; i < MAX_FS_STATS; ++i) {
if (fs_stats[i].path) {
if (strcmp(fs_stats[i].path, s) == 0) {
return &fs_stats[i];
} else
}
} else {
new = &fs_stats[i];
}
}
/* new path */
if(!new) {
if (!new) {
ERR("too many fs stats");
return 0;
}
@@ -94,14 +101,14 @@ struct fs_stat *prepare_fs_stat(const char *s)
return new;
}
static
void update_fs_stat(struct fs_stat* fs)
static void update_fs_stat(struct fs_stat *fs)
{
struct statfs s;
if(statfs(fs->path, &s) == 0) {
if (statfs(fs->path, &s) == 0) {
fs->size = (long long) s.f_blocks * s.f_bsize;
/* bfree (root) or bavail (non-roots) ? */
fs->avail = (long long) s.f_bavail* s.f_bsize;
fs->avail = (long long) s.f_bavail * s.f_bsize;
fs->free = (long long) s.f_bfree * s.f_bsize;
} else {
fs->size = 0;

View File

@@ -1,5 +1,4 @@
/*
* Conky, a system monitor, based on torsmo
/* Conky, a system monitor, based on torsmo
*
* Any original torsmo code is licensed under the BSD license
*
@@ -8,7 +7,8 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*/
* $Id$ */
#include "conky.h"
#include <errno.h>
@@ -50,19 +49,22 @@ int scan_hddtemp(const char *arg, char **dev, char **addr, int *port)
ret = sscanf(arg, "%31s %63s %d", buf1, buf2, &n);
if (ret < 1)
if (ret < 1) {
return -1;
}
*dev = strdup(buf1);
if (ret >= 2)
if (ret >= 2) {
*addr = strdup(buf2);
else
} else {
*addr = strdup("127.0.0.1");
}
if (ret == 3)
if (ret == 3) {
*port = n;
else
} else {
*port = PORT;
}
return 0;
}
@@ -91,10 +93,11 @@ char *get_hddtemp_info(char *dev, char *hostaddr, int port, char *unit)
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr = *((struct in_addr *)he->h_addr);
addr.sin_addr = *((struct in_addr *) he->h_addr);
memset(&(addr.sin_zero), 0, 8);
if (connect(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) == -1) {
if (connect(sockfd, (struct sockaddr *) &addr,
sizeof(struct sockaddr)) == -1) {
perror("connect");
goto out;
}
@@ -102,29 +105,30 @@ char *get_hddtemp_info(char *dev, char *hostaddr, int port, char *unit)
FD_ZERO(&rfds);
FD_SET(sockfd, &rfds);
/* We're going to wait up to a quarter a second to see whether
* there's any data available. Polling with timeout set to 0
* doesn't seem to work with hddtemp. */
/* We're going to wait up to a quarter a second to see whether there's
* any data available. Polling with timeout set to 0 doesn't seem to work
* with hddtemp. */
tv.tv_sec = 0;
tv.tv_usec = 250000;
i = select(sockfd+1, &rfds, NULL, NULL, &tv);
if (i == -1)
{
if (errno == EINTR) /* silently ignore interrupted system call */
i = select(sockfd + 1, &rfds, NULL, NULL, &tv);
if (i == -1) {
if (errno == EINTR) { /* silently ignore interrupted system call */
goto out;
else
} else {
perror("select");
}
}
/* No data available */
if (i <= 0)
if (i <= 0) {
goto out;
}
p = buf;
len = 0;
do {
i = recv(sockfd, p, BUFLEN - (p-buf), 0);
i = recv(sockfd, p, BUFLEN - (p - buf), 0);
if (i < 0) {
perror("recv");
goto out;
@@ -141,19 +145,21 @@ char *get_hddtemp_info(char *dev, char *hostaddr, int port, char *unit)
/* The first character read is the separator. */
sep = buf[0];
p = buf+1;
p = buf + 1;
while (*p) {
if (!strncmp(p, dev, devlen)) {
p += devlen + 1;
p = strchr(p, sep);
if (!p)
if (!p) {
goto out;
}
p++;
out = p;
p = strchr(p, sep);
if (!p)
if (!p) {
goto out;
}
*p = '\0';
p++;
*unit = *p;
@@ -167,13 +173,14 @@ char *get_hddtemp_info(char *dev, char *hostaddr, int port, char *unit)
} else {
for (i = 0; i < 5; i++) {
p = strchr(p, sep);
if (!p)
if (!p) {
goto out;
}
p++;
}
}
}
out: close(sockfd);
out:
close(sockfd);
return r;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,34 +1,33 @@
/* libmpdclient
(c)2003-2006 by Warren Dukes (warren.dukes@gmail.com)
This project's homepage is: http://www.musicpd.org
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the Music Player Daemon nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
* (c)2003-2006 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of the Music Player Daemon nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#ifndef LIBMPDCLIENT_H
#define LIBMPDCLIENT_H
@@ -71,12 +70,7 @@
#define MPD_ACK_ERROR_PLAYER_SYNC 55
#define MPD_ACK_ERROR_EXIST 56
#ifdef __cplusplus
extern "C" {
#endif
typedef enum mpd_TagItems
{
typedef enum mpd_TagItems {
MPD_TAG_ITEM_ARTIST,
MPD_TAG_ITEM_ALBUM,
MPD_TAG_ITEM_TITLE,
@@ -93,60 +87,56 @@ typedef enum mpd_TagItems
MPD_TAG_NUM_OF_ITEM_TYPES
} mpd_TagItems;
extern char * mpdTagItemKeys[MPD_TAG_NUM_OF_ITEM_TYPES];
extern char *mpdTagItemKeys[MPD_TAG_NUM_OF_ITEM_TYPES];
/* internal stuff don't touch this struct */
typedef struct _mpd_ReturnElement {
char * name;
char * value;
char *name;
char *value;
} mpd_ReturnElement;
/* mpd_Connection
* holds info about connection to mpd
* use error, and errorStr to detect errors
*/
* use error, and errorStr to detect errors */
typedef struct _mpd_Connection {
/* use this to check the version of mpd */
int version[3];
/* IMPORTANT, you want to get the error messages from here */
char errorStr[MPD_ERRORSTR_MAX_LENGTH+1];
char errorStr[MPD_ERRORSTR_MAX_LENGTH + 1];
int errorCode;
int errorAt;
/* this will be set to MPD_ERROR_* if there is an error, 0 if not */
int error;
/* DON'T TOUCH any of the rest of this stuff */
int sock;
char buffer[MPD_BUFFER_MAX_LENGTH+1];
char buffer[MPD_BUFFER_MAX_LENGTH + 1];
int buflen;
int bufstart;
int doneProcessing;
int listOks;
int doneListOk;
int commandList;
mpd_ReturnElement * returnElement;
mpd_ReturnElement *returnElement;
struct timeval timeout;
char *request;
} mpd_Connection;
/* mpd_newConnection
* use this to open a new connection
* you should use mpd_closeConnection, when your done with the connection,
* you should use mpd_closeConnection when you're done with the connection,
* even if an error has occurred
* _timeout_ is the connection timeout period in seconds
*/
mpd_Connection * mpd_newConnection(const char * host, int port, float timeout);
* _timeout_ is the connection timeout period in seconds */
mpd_Connection *mpd_newConnection(const char *host, int port, float timeout);
void mpd_setConnectionTimeout(mpd_Connection * connection, float timeout);
void mpd_setConnectionTimeout(mpd_Connection *connection, float timeout);
/* mpd_closeConnection
* use this to close a connection and free'ing subsequent memory
*/
void mpd_closeConnection(mpd_Connection * connection);
* use this to close a connection and free subsequent memory */
void mpd_closeConnection(mpd_Connection *connection);
/* mpd_clearError
* clears error
*/
void mpd_clearError(mpd_Connection * connection);
* clears error */
void mpd_clearError(mpd_Connection *connection);
/* STATUS STUFF */
@@ -156,12 +146,11 @@ void mpd_clearError(mpd_Connection * connection);
#define MPD_STATUS_STATE_PLAY 2
#define MPD_STATUS_STATE_PAUSE 3
/* us this with status.volume to determine if mpd has volume support */
/* use this with status.volume to determine if mpd has volume support */
#define MPD_STATUS_NO_VOLUME -1
/* mpd_Status
* holds info return from status command
*/
* holds info return from status command */
typedef struct mpd_Status {
/* 0-100, or MPD_STATUS_NO_VOLUME when there is no volume support */
int volume;
@@ -177,16 +166,13 @@ typedef struct mpd_Status {
int state;
/* crossfade setting in seconds */
int crossfade;
/* if a song is currently selected (always the case when state is
* PLAY or PAUSE), this is the position of the currently
* playing song in the playlist, beginning with 0
*/
/* if a song is currently selected (always the case when state is PLAY
* or PAUSE), this is the position of the currently playing song in the
* playlist, beginning with 0 */
int song;
/* Song ID of the currently selected song */
int songid;
/* time in seconds that have elapsed in the currently playing/paused
* song
*/
/* time in seconds that have elapsed in the currently playing/paused song */
int elapsedTime;
/* length in seconds of the currently playing/paused song */
int totalTime;
@@ -201,21 +187,19 @@ typedef struct mpd_Status {
/* 1 if mpd is updating, 0 otherwise */
int updatingDb;
/* error */
char * error;
char *error;
} mpd_Status;
void mpd_sendStatusCommand(mpd_Connection * connection);
void mpd_sendStatusCommand(mpd_Connection *connection);
/* mpd_getStatus
* returns status info, be sure to free it with mpd_freeStatus()
* call this after mpd_sendStatusCommand()
*/
mpd_Status * mpd_getStatus(mpd_Connection * connection);
* call this after mpd_sendStatusCommand() */
mpd_Status *mpd_getStatus(mpd_Connection *connection);
/* mpd_freeStatus
* free's status info malloc'd and returned by mpd_getStatus
*/
void mpd_freeStatus(mpd_Status * status);
* free's status info malloc'd and returned by mpd_getStatus */
void mpd_freeStatus(mpd_Status *status);
typedef struct _mpd_Stats {
int numberOfArtists;
@@ -232,15 +216,15 @@ typedef struct _mpd_SearchStats {
unsigned long playTime;
} mpd_SearchStats;
void mpd_sendStatsCommand(mpd_Connection * connection);
void mpd_sendStatsCommand(mpd_Connection *connection);
mpd_Stats * mpd_getStats(mpd_Connection * connection);
mpd_Stats *mpd_getStats(mpd_Connection *connection);
void mpd_freeStats(mpd_Stats * stats);
void mpd_freeStats(mpd_Stats *stats);
mpd_SearchStats * mpd_getSearchStats(mpd_Connection * connection);
mpd_SearchStats *mpd_getSearchStats(mpd_Connection *connection);
void mpd_freeSearchStats(mpd_SearchStats * stats);
void mpd_freeSearchStats(mpd_SearchStats *stats);
/* SONG STUFF */
@@ -249,22 +233,21 @@ void mpd_freeSearchStats(mpd_SearchStats * stats);
#define MPD_SONG_NO_ID -1
/* mpd_Song
* for storing song info returned by mpd
*/
* for storing song info returned by mpd */
typedef struct _mpd_Song {
/* filename of song */
char * file;
char *file;
/* artist, maybe NULL if there is no tag */
char * artist;
char *artist;
/* title, maybe NULL if there is no tag */
char * title;
char *title;
/* album, maybe NULL if there is no tag */
char * album;
char *album;
/* track, maybe NULL if there is no tag */
char * track;
/* name, maybe NULL if there is no tag; it's the name of the current
* song, f.e. the icyName of the stream */
char * name;
char *track;
/* name, maybe NULL if there is no tag; it's the name of the current song,
* f.e. the icyName of the stream */
char *name;
/* date */
char *date;
@@ -282,8 +265,8 @@ typedef struct _mpd_Song {
/* length of song in seconds, check that it is not MPD_SONG_NO_TIME */
int time;
/* if plchanges/playlistinfo/playlistid used, is the position of the
* song in the playlist */
/* if plchanges/playlistinfo/playlistid used, is the position of the song
* in the playlist */
int pos;
/* song id for a song in the playlist */
int id;
@@ -292,338 +275,317 @@ typedef struct _mpd_Song {
/* mpd_newSong
* use to allocate memory for a new mpd_Song
* file, artist, etc all initialized to NULL
* if your going to assign values to file, artist, etc
* be sure to malloc or strdup the memory
* if you're going to assign values to file, artist, etc., be sure to
* malloc or strdup the memory
* use mpd_freeSong to free the memory for the mpd_Song, it will also
* free memory for file, artist, etc, so don't do it yourself
*/
mpd_Song * mpd_newSong(void);
* free memory for file, artist, etc, so don't do it yourself */
mpd_Song *mpd_newSong(void);
/* mpd_freeSong
* use to free memory allocated by mpd_newSong
* also it will free memory pointed to by file, artist, etc, so be careful
*/
void mpd_freeSong(mpd_Song * song);
* also it will free memory pointed to by file, artist, etc, so be careful */
void mpd_freeSong(mpd_Song *song);
/* mpd_songDup
* works like strDup, but for a mpd_Song
*/
mpd_Song * mpd_songDup(mpd_Song * song);
* works like strDup, but for a mpd_Song */
mpd_Song *mpd_songDup(mpd_Song *song);
/* DIRECTORY STUFF */
/* mpd_Directory
* used to store info fro directory (right now that just the path)
*/
* used to store info from directory (right now just the path) */
typedef struct _mpd_Directory {
char * path;
char *path;
} mpd_Directory;
/* mpd_newDirectory
* allocates memory for a new directory
* use mpd_freeDirectory to free this memory
*/
mpd_Directory * mpd_newDirectory(void);
* use mpd_freeDirectory to free this memory */
mpd_Directory *mpd_newDirectory(void);
/* mpd_freeDirectory
* used to free memory allocated with mpd_newDirectory, and it frees
* path of mpd_Directory, so be careful
*/
void mpd_freeDirectory(mpd_Directory * directory);
* path of mpd_Directory, so be careful */
void mpd_freeDirectory(mpd_Directory *directory);
/* mpd_directoryDup
* works like strdup, but for mpd_Directory
*/
mpd_Directory * mpd_directoryDup(mpd_Directory * directory);
* works like strdup, but for mpd_Directory */
mpd_Directory *mpd_directoryDup(mpd_Directory *directory);
/* PLAYLISTFILE STUFF */
/* mpd_PlaylistFile
* stores info about playlist file returned by lsinfo
*/
* stores info about playlist file returned by lsinfo */
typedef struct _mpd_PlaylistFile {
char * path;
char *path;
} mpd_PlaylistFile;
/* mpd_newPlaylistFile
* allocates memory for new mpd_PlaylistFile, path is set to NULL
* free this memory with mpd_freePlaylistFile
*/
mpd_PlaylistFile * mpd_newPlaylistFile(void);
* free this memory with mpd_freePlaylistFile */
mpd_PlaylistFile *mpd_newPlaylistFile(void);
/* mpd_freePlaylist
* free memory allocated for freePlaylistFile, will also free
* path, so be careful
*/
void mpd_freePlaylistFile(mpd_PlaylistFile * playlist);
* free memory allocated for freePlaylistFile
* will also free path, so be careful */
void mpd_freePlaylistFile(mpd_PlaylistFile *playlist);
/* mpd_playlistFileDup
* works like strdup, but for mpd_PlaylistFile
*/
mpd_PlaylistFile * mpd_playlistFileDup(mpd_PlaylistFile * playlist);
* works like strdup, but for mpd_PlaylistFile */
mpd_PlaylistFile *mpd_playlistFileDup(mpd_PlaylistFile *playlist);
/* INFO ENTITY STUFF */
/* the type of entity returned from one of the commands that generates info
* use in conjunction with mpd_InfoEntity.type
*/
* use in conjunction with mpd_InfoEntity.type */
#define MPD_INFO_ENTITY_TYPE_DIRECTORY 0
#define MPD_INFO_ENTITY_TYPE_SONG 1
#define MPD_INFO_ENTITY_TYPE_PLAYLISTFILE 2
/* mpd_InfoEntity
* stores info on stuff returned info commands
*/
* stores info on stuff returned info commands */
typedef struct mpd_InfoEntity {
/* the type of entity, use with MPD_INFO_ENTITY_TYPE_* to determine
* what this entity is (song, directory, etc...)
*/
* what this entity is (song, directory, etc...) */
int type;
/* the actual data you want, mpd_Song, mpd_Directory, etc */
union {
mpd_Directory * directory;
mpd_Song * song;
mpd_PlaylistFile * playlistFile;
mpd_Directory *directory;
mpd_Song *song;
mpd_PlaylistFile *playlistFile;
} info;
} mpd_InfoEntity;
mpd_InfoEntity * mpd_newInfoEntity(void);
mpd_InfoEntity *mpd_newInfoEntity(void);
void mpd_freeInfoEntity(mpd_InfoEntity * entity);
void mpd_freeInfoEntity(mpd_InfoEntity *entity);
/* INFO COMMANDS AND STUFF */
/* use this function to loop over after calling Info/Listall functions */
mpd_InfoEntity * mpd_getNextInfoEntity(mpd_Connection * connection);
mpd_InfoEntity *mpd_getNextInfoEntity(mpd_Connection *connection);
/* fetches the currently seeletect song (the song referenced by status->song
* and status->songid*/
void mpd_sendCurrentSongCommand(mpd_Connection * connection);
/* fetches the currently selected song (the song referenced by status->song
* and status->songid */
void mpd_sendCurrentSongCommand(mpd_Connection *connection);
/* songNum of -1, means to display the whole list */
void mpd_sendPlaylistInfoCommand(mpd_Connection * connection, int songNum);
void mpd_sendPlaylistInfoCommand(mpd_Connection *connection, int songNum);
/* songId of -1, means to display the whole list */
void mpd_sendPlaylistIdCommand(mpd_Connection * connection, int songId);
void mpd_sendPlaylistIdCommand(mpd_Connection *connection, int songId);
/* use this to get the changes in the playlist since version _playlist_ */
void mpd_sendPlChangesCommand(mpd_Connection * connection, long long playlist);
void mpd_sendPlChangesCommand(mpd_Connection *connection, long long playlist);
/**
* @param connection: A valid and connected mpd_Connection.
* @param playlist: The playlist version you want the diff with.
*
* A more bandwidth efficient version of the mpd_sendPlChangesCommand.
* It only returns the pos+id of the changes song.
*/
void mpd_sendPlChangesPosIdCommand(mpd_Connection * connection, long long playlist);
* It only returns the pos+id of the changes song. */
void mpd_sendPlChangesPosIdCommand(mpd_Connection *connection,
long long playlist);
/* recursivel fetches all songs/dir/playlists in "dir* (no metadata is
* returned) */
void mpd_sendListallCommand(mpd_Connection * connection, const char * dir);
/* recursively fetches all songs/dir/playlists in "dir*
* (no metadata is returned) */
void mpd_sendListallCommand(mpd_Connection *connection, const char *dir);
/* same as sendListallCommand, but also metadata is returned */
void mpd_sendListallInfoCommand(mpd_Connection * connection, const char * dir);
void mpd_sendListallInfoCommand(mpd_Connection *connection, const char *dir);
/* non-recursive version of ListallInfo */
void mpd_sendLsInfoCommand(mpd_Connection * connection, const char * dir);
void mpd_sendLsInfoCommand(mpd_Connection *connection, const char *dir);
#define MPD_TABLE_ARTIST MPD_TAG_ITEM_ARTIST
#define MPD_TABLE_ALBUM MPD_TAG_ITEM_ALBUM
#define MPD_TABLE_TITLE MPD_TAG_ITEM_TITLE
#define MPD_TABLE_FILENAME MPD_TAG_ITEM_FILENAME
void mpd_sendSearchCommand(mpd_Connection * connection, int table,
const char * str);
void mpd_sendSearchCommand(mpd_Connection *connection, int table,
const char *str);
void mpd_sendFindCommand(mpd_Connection * connection, int table,
const char * str);
void mpd_sendFindCommand(mpd_Connection *connection, int table,
const char *str);
/* LIST TAG COMMANDS */
/* use this function fetch next artist entry, be sure to free the returned
* string. NULL means there are no more. Best used with sendListArtists
*/
char * mpd_getNextArtist(mpd_Connection * connection);
/* use this function fetch next artist entry, be sure to free the
* returned string.
* NULL means there are no more.
* Best used with sendListArtists */
char *mpd_getNextArtist(mpd_Connection *connection);
char * mpd_getNextAlbum(mpd_Connection * connection);
char *mpd_getNextAlbum(mpd_Connection *connection);
char * mpd_getNextTag(mpd_Connection *connection, int type);
char *mpd_getNextTag(mpd_Connection *connection, int type);
/* list artist or albums by artist, arg1 should be set to the artist if
* listing albums by a artist, otherwise NULL for listing all artists or albums
*/
void mpd_sendListCommand(mpd_Connection * connection, int table,
const char * arg1);
/* list artist or albums by artist
* arg1 should be set to the artist if listing albums by a artist
* otherwise NULL for listing all artists or albums */
void mpd_sendListCommand(mpd_Connection *connection, int table,
const char *arg1);
/* SIMPLE COMMANDS */
void mpd_sendAddCommand(mpd_Connection * connection, const char * file);
void mpd_sendAddCommand(mpd_Connection *connection, const char *file);
int mpd_sendAddIdCommand(mpd_Connection *connection, const char *file);
void mpd_sendDeleteCommand(mpd_Connection * connection, int songNum);
void mpd_sendDeleteCommand(mpd_Connection *connection, int songNum);
void mpd_sendDeleteIdCommand(mpd_Connection * connection, int songNum);
void mpd_sendDeleteIdCommand(mpd_Connection *connection, int songNum);
void mpd_sendSaveCommand(mpd_Connection * connection, const char * name);
void mpd_sendSaveCommand(mpd_Connection *connection, const char *name);
void mpd_sendLoadCommand(mpd_Connection * connection, const char * name);
void mpd_sendLoadCommand(mpd_Connection *connection, const char *name);
void mpd_sendRmCommand(mpd_Connection * connection, const char * name);
void mpd_sendRmCommand(mpd_Connection *connection, const char *name);
void mpd_sendRenameCommand(mpd_Connection *connection, const char *from,
const char *to);
void mpd_sendShuffleCommand(mpd_Connection * connection);
void mpd_sendShuffleCommand(mpd_Connection *connection);
void mpd_sendClearCommand(mpd_Connection * connection);
void mpd_sendClearCommand(mpd_Connection *connection);
/* use this to start playing at the beginning, useful when in random mode */
#define MPD_PLAY_AT_BEGINNING -1
void mpd_sendPlayCommand(mpd_Connection * connection, int songNum);
void mpd_sendPlayCommand(mpd_Connection *connection, int songNum);
void mpd_sendPlayIdCommand(mpd_Connection * connection, int songNum);
void mpd_sendPlayIdCommand(mpd_Connection *connection, int songNum);
void mpd_sendStopCommand(mpd_Connection * connection);
void mpd_sendStopCommand(mpd_Connection *connection);
void mpd_sendPauseCommand(mpd_Connection * connection, int pauseMode);
void mpd_sendPauseCommand(mpd_Connection *connection, int pauseMode);
void mpd_sendNextCommand(mpd_Connection * connection);
void mpd_sendNextCommand(mpd_Connection *connection);
void mpd_sendPrevCommand(mpd_Connection * connection);
void mpd_sendPrevCommand(mpd_Connection *connection);
void mpd_sendMoveCommand(mpd_Connection * connection, int from, int to);
void mpd_sendMoveCommand(mpd_Connection *connection, int from, int to);
void mpd_sendMoveIdCommand(mpd_Connection * connection, int from, int to);
void mpd_sendMoveIdCommand(mpd_Connection *connection, int from, int to);
void mpd_sendSwapCommand(mpd_Connection * connection, int song1, int song2);
void mpd_sendSwapCommand(mpd_Connection *connection, int song1, int song2);
void mpd_sendSwapIdCommand(mpd_Connection * connection, int song1, int song2);
void mpd_sendSwapIdCommand(mpd_Connection *connection, int song1, int song2);
void mpd_sendSeekCommand(mpd_Connection * connection, int song, int time);
void mpd_sendSeekCommand(mpd_Connection *connection, int song, int time);
void mpd_sendSeekIdCommand(mpd_Connection * connection, int song, int time);
void mpd_sendSeekIdCommand(mpd_Connection *connection, int song, int time);
void mpd_sendRepeatCommand(mpd_Connection * connection, int repeatMode);
void mpd_sendRepeatCommand(mpd_Connection *connection, int repeatMode);
void mpd_sendRandomCommand(mpd_Connection * connection, int randomMode);
void mpd_sendRandomCommand(mpd_Connection *connection, int randomMode);
void mpd_sendSetvolCommand(mpd_Connection * connection, int volumeChange);
void mpd_sendSetvolCommand(mpd_Connection *connection, int volumeChange);
/* WARNING: don't use volume command, its depreacted */
void mpd_sendVolumeCommand(mpd_Connection * connection, int volumeChange);
void mpd_sendVolumeCommand(mpd_Connection *connection, int volumeChange);
void mpd_sendCrossfadeCommand(mpd_Connection * connection, int seconds);
void mpd_sendCrossfadeCommand(mpd_Connection *connection, int seconds);
void mpd_sendUpdateCommand(mpd_Connection * connection, char * path);
void mpd_sendUpdateCommand(mpd_Connection *connection, char *path);
/* returns the update job id, call this after a update command*/
int mpd_getUpdateId(mpd_Connection * connection);
/* returns the update job id, call this after a update command */
int mpd_getUpdateId(mpd_Connection *connection);
void mpd_sendPasswordCommand(mpd_Connection * connection, const char * pass);
void mpd_sendPasswordCommand(mpd_Connection *connection, const char *pass);
/* after executing a command, when your done with it to get its status
* (you want to check connection->error for an error)
*/
void mpd_finishCommand(mpd_Connection * connection);
/* after executing a command, when you're done with it to get its status
* (you want to check connection->error for an error) */
void mpd_finishCommand(mpd_Connection *connection);
/* command list stuff, use this to do things like add files very quickly */
void mpd_sendCommandListBegin(mpd_Connection * connection);
void mpd_sendCommandListBegin(mpd_Connection *connection);
void mpd_sendCommandListOkBegin(mpd_Connection * connection);
void mpd_sendCommandListOkBegin(mpd_Connection *connection);
void mpd_sendCommandListEnd(mpd_Connection * connection);
void mpd_sendCommandListEnd(mpd_Connection *connection);
/* advance to the next listOk
* returns 0 if advanced to the next list_OK,
* returns -1 if it advanced to an OK or ACK */
int mpd_nextListOkCommand(mpd_Connection * connection);
int mpd_nextListOkCommand(mpd_Connection *connection);
typedef struct _mpd_OutputEntity {
int id;
char * name;
char *name;
int enabled;
} mpd_OutputEntity;
void mpd_sendOutputsCommand(mpd_Connection * connection);
void mpd_sendOutputsCommand(mpd_Connection *connection);
mpd_OutputEntity * mpd_getNextOutput(mpd_Connection * connection);
mpd_OutputEntity *mpd_getNextOutput(mpd_Connection *connection);
void mpd_sendEnableOutputCommand(mpd_Connection * connection, int outputId);
void mpd_sendEnableOutputCommand(mpd_Connection *connection, int outputId);
void mpd_sendDisableOutputCommand(mpd_Connection * connection, int outputId);
void mpd_sendDisableOutputCommand(mpd_Connection *connection, int outputId);
void mpd_freeOutputElement(mpd_OutputEntity * output);
void mpd_freeOutputElement(mpd_OutputEntity *output);
/**
* @param connection a #mpd_Connection
*
* Queries mpd for the allowed commands
*/
void mpd_sendCommandsCommand(mpd_Connection * connection);
* Queries mpd for the allowed commands */
void mpd_sendCommandsCommand(mpd_Connection *connection);
/**
* @param connection a #mpd_Connection
*
* Queries mpd for the not allowed commands
*/
void mpd_sendNotCommandsCommand(mpd_Connection * connection);
* Queries mpd for the not allowed commands */
void mpd_sendNotCommandsCommand(mpd_Connection *connection);
/**
* @param connection a #mpd_Connection
*
* returns the next supported command.
*
* @returns a string, needs to be free'ed
*/
* @returns a string, needs to be freed */
char *mpd_getNextCommand(mpd_Connection *connection);
void mpd_sendUrlHandlersCommand(mpd_Connection * connection);
void mpd_sendUrlHandlersCommand(mpd_Connection *connection);
char *mpd_getNextHandler(mpd_Connection * connection);
char *mpd_getNextHandler(mpd_Connection *connection);
void mpd_sendTagTypesCommand(mpd_Connection * connection);
void mpd_sendTagTypesCommand(mpd_Connection *connection);
char *mpd_getNextTagType(mpd_Connection * connection);
char *mpd_getNextTagType(mpd_Connection *connection);
/**
* @param connection a MpdConnection
* @param path the path to the playlist.
*
* List the content, with full metadata, of a stored playlist.
*
*/
* List the content, with full metadata, of a stored playlist. */
void mpd_sendListPlaylistInfoCommand(mpd_Connection *connection, char *path);
/**
* @param connection a MpdConnection
* @param path the path to the playlist.
*
* List the content of a stored playlist.
*
*/
* List the content of a stored playlist. */
void mpd_sendListPlaylistCommand(mpd_Connection *connection, char *path);
/**
* @param connection a #mpd_Connection
* @param exact if to match exact
*
* starts a search, use mpd_addConstraintSearch to add
* a constraint to the search, and mpd_commitSearch to do the actual search
*/
* starts a search
* use mpd_addConstraintSearch to add a constraint to the search
* use mpd_commitSearch to do the actual search */
void mpd_startSearch(mpd_Connection *connection, int exact);
/**
* @param connection a #mpd_Connection
* @param type
* @param name
*/
void mpd_addConstraintSearch(mpd_Connection *connection, int type, const char *name);
* @param name */
void mpd_addConstraintSearch(mpd_Connection *connection, int type,
const char *name);
/**
* @param connection a #mpd_Connection
*/
* @param connection a #mpd_Connection */
void mpd_commitSearch(mpd_Connection *connection);
/**
@@ -643,10 +605,10 @@ void mpd_commitSearch(mpd_Connection *connection);
* mpd_commitSearch(connection);
* @endcode
*
* mpd_startSearch will return a list of songs (and you need mpd_getNextInfoEntity)
* this one will return a list of only one field (the one specified with type) and you need
* mpd_getNextTag to get the results
*/
* mpd_startSearch will return a list of songs
* (and you need mpd_getNextInfoEntity)
* this will return a list of only one field (the one specified with type)
* you need mpd_getNextTag to get the results */
void mpd_startFieldSearch(mpd_Connection *connection, int type);
void mpd_startPlaylistSearch(mpd_Connection *connection, int exact);
@@ -655,16 +617,13 @@ void mpd_startStatsSearch(mpd_Connection *connection);
void mpd_sendPlaylistClearCommand(mpd_Connection *connection, char *path);
void mpd_sendPlaylistAddCommand(mpd_Connection *connection,
char *playlist, char *path);
void mpd_sendPlaylistAddCommand(mpd_Connection *connection, char *playlist,
char *path);
void mpd_sendPlaylistMoveCommand(mpd_Connection *connection,
char *playlist, int from, int to);
void mpd_sendPlaylistMoveCommand(mpd_Connection *connection, char *playlist,
int from, int to);
void mpd_sendPlaylistDeleteCommand(mpd_Connection *connection,
char *playlist, int pos);
#ifdef __cplusplus
}
#endif
void mpd_sendPlaylistDeleteCommand(mpd_Connection *connection, char *playlist,
int pos);
#endif

View File

@@ -1,7 +1,6 @@
/* $Id$ */
/*
* libtcp-portmon.c: tcp port monitoring library.
/* libtcp-portmon.c: tcp port monitoring library.
*
* Copyright (C) 2005-2007 Philip Kovacs pkovacs@users.sourceforge.net
*
@@ -18,9 +17,7 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
* USA.
*
*/
* USA. */
#include <glib/gprintf.h>
#include "libtcp-portmon.h"
@@ -33,20 +30,20 @@
* functions. Use the "Client interface" functions defined at bottom.
* ------------------------------------------------------------------- */
/* ----------------------------------
/* -----------------------------------
* Copy a tcp_connection_t
*
* Returns 0 on success, -1 otherwise.
* ----------------------------------*/
int copy_tcp_connection(
tcp_connection_t * p_dest_connection,
const tcp_connection_t * p_source_connection
)
* ----------------------------------- */
int copy_tcp_connection(tcp_connection_t *p_dest_connection,
const tcp_connection_t *p_source_connection)
{
if ( !p_dest_connection || !p_source_connection )
return (-1);
if (!p_dest_connection || !p_source_connection) {
return -1;
}
g_strlcpy (p_dest_connection->key, p_source_connection->key, sizeof(p_dest_connection->key));
g_strlcpy(p_dest_connection->key, p_source_connection->key,
sizeof(p_dest_connection->key));
p_dest_connection->local_addr = p_source_connection->local_addr;
p_dest_connection->local_port = p_source_connection->local_port;
p_dest_connection->remote_addr = p_source_connection->remote_addr;
@@ -56,46 +53,41 @@ int copy_tcp_connection(
return 0;
}
/* ---------------------------------------------------------------------------
* Port monitor utility functions implementing tcp_port_monitor_function_ptr_t
* ---------------------------------------------------------------------------*/
void destroy_tcp_port_monitor(
tcp_port_monitor_t * p_monitor,
void * p_void
)
/* -------------------------------------------
* Port monitor utility functions implementing
* tcp_port_monitor_function_ptr_t
* ------------------------------------------- */
void destroy_tcp_port_monitor(tcp_port_monitor_t *p_monitor, void *p_void)
{
tcp_connection_node_t *p_node, *p_temp;
if ( !p_monitor || p_void ) /* p_void should be NULL in this context */
if (!p_monitor || p_void) { /* p_void should be NULL in this context */
return;
}
/* destroy the monitor's peek array */
free( p_monitor->p_peek );
free(p_monitor->p_peek);
/* destroy the monitor's connection list */
for ( p_node=p_monitor->connection_list.p_head; p_node!=NULL; )
{
for (p_node = p_monitor->connection_list.p_head; p_node != NULL; ) {
/* p_temp is for the next iteration */
p_temp = p_node->p_next;
free( p_node );
free(p_node);
p_node = p_temp;
}
/* destroy the monitor's hash */
g_hash_table_destroy (p_monitor->hash);
p_monitor->hash=NULL;
g_hash_table_destroy(p_monitor->hash);
p_monitor->hash = NULL;
/* destroy the monitor */
free( p_monitor );
p_monitor=NULL;
free(p_monitor);
p_monitor = NULL;
}
void age_tcp_port_monitor(
tcp_port_monitor_t * p_monitor,
void * p_void
)
void age_tcp_port_monitor(tcp_port_monitor_t *p_monitor, void *p_void)
{
/* Run through the monitor's connections and decrement the age variable.
* If the age goes negative, we remove the connection from the monitor.
@@ -104,15 +96,16 @@ void age_tcp_port_monitor(
tcp_connection_node_t *p_node, *p_temp;
tcp_connection_t *p_conn;
if ( !p_monitor || p_void ) /* p_void should be NULL in this context */
if (!p_monitor || p_void) { /* p_void should be NULL in this context */
return;
}
if ( !p_monitor->p_peek )
if (!p_monitor->p_peek) {
return;
}
for ( p_node = p_monitor->connection_list.p_head; p_node; )
{
if ( --p_node->connection.age >= 0 ) {
for (p_node = p_monitor->connection_list.p_head; p_node; ) {
if (--p_node->connection.age >= 0) {
p_node = p_node->p_next;
continue;
}
@@ -120,114 +113,126 @@ void age_tcp_port_monitor(
/* connection on p_node is old. remove connection from the hash. */
p_conn = &p_node->connection;
#ifdef HASH_DEBUG
fprintf (stderr, "monitor hash removal of connection [%s]", p_conn->key);
if ( !g_hash_table_remove (p_monitor->hash, (gconstpointer)p_conn->key) ) {
fprintf (stderr, " - ERROR NOT FOUND\n");
fprintf(stderr, "monitor hash removal of connection [%s]", p_conn->key);
if (!g_hash_table_remove(p_monitor->hash,
(gconstpointer) p_conn->key)) {
fprintf(stderr, " - ERROR NOT FOUND\n");
return;
}
fprintf (stderr, " - OK\n");
fprintf(stderr, " - OK\n");
#else
if ( !g_hash_table_remove (p_monitor->hash, (gconstpointer)p_conn->key) )
if (!g_hash_table_remove(p_monitor->hash,
(gconstpointer) p_conn->key)) {
return;
}
#endif
/* splice p_node out of the connection_list */
if ( p_node->p_prev != NULL )
if (p_node->p_prev != NULL) {
p_node->p_prev->p_next = p_node->p_next;
if ( p_node->p_next != NULL )
}
if (p_node->p_next != NULL) {
p_node->p_next->p_prev = p_node->p_prev;
}
/* correct the list head and tail if necessary */
if ( p_monitor->connection_list.p_head == p_node )
if (p_monitor->connection_list.p_head == p_node) {
p_monitor->connection_list.p_head = p_node->p_next;
if ( p_monitor->connection_list.p_tail == p_node )
}
if (p_monitor->connection_list.p_tail == p_node) {
p_monitor->connection_list.p_tail = p_node->p_prev;
}
/* p_temp is for the next iteration */
p_temp = p_node->p_next;
/* destroy the node */
free( p_node );
free(p_node);
p_node = p_temp;
}
}
void rebuild_tcp_port_monitor_peek_table(
tcp_port_monitor_t * p_monitor,
void * p_void
)
void rebuild_tcp_port_monitor_peek_table(tcp_port_monitor_t *p_monitor,
void *p_void)
{
/* Run through the monitor's connections and rebuild the peek table
* of connection pointers. This is done so peeking into the monitor
* can be done in O(1) time instead of O(n) time for each peek. */
/* Run through the monitor's connections and rebuild the peek table of
* connection pointers. This is done so peeking into the monitor can be
* done in O(1) time instead of O(n) time for each peek. */
tcp_connection_node_t *p_node;
int i = 0;
if ( !p_monitor || p_void ) /* p_void should be NULL in this context */
if (!p_monitor || p_void) { /* p_void should be NULL in this context */
return;
/* zero out the peek array */
memset( p_monitor->p_peek, 0, p_monitor->max_port_monitor_connections * sizeof(tcp_connection_t *) );
for ( p_node=p_monitor->connection_list.p_head; p_node!=NULL; p_node=p_node->p_next, i++ )
{
p_monitor->p_peek[i] = &p_node->connection;
}
/* zero out the peek array */
memset(p_monitor->p_peek, 0, p_monitor->max_port_monitor_connections *
sizeof(tcp_connection_t *));
for (p_node = p_monitor->connection_list.p_head; p_node != NULL;
p_node = p_node->p_next, i++) {
p_monitor->p_peek[i] = &p_node->connection;
}
}
void show_connection_to_tcp_port_monitor(
tcp_port_monitor_t * p_monitor,
void * p_void
)
void show_connection_to_tcp_port_monitor(tcp_port_monitor_t *p_monitor,
void *p_void)
{
/* The monitor gets to look at each connection to see if it falls within
* the monitor's port range of interest. Connections of interest are first
* looked up in the hash to see if they are already there. If they are, we
* reset the age of the connection so it is not deleted. If the connection
* is not in the hash, we add it, but only if we haven't exceeded the maximum
* connection limit for the monitor. The function takes O(1) time. */
* is not in the hash, we add it, but only if we haven't exceeded the
* maximum connection limit for the monitor.
* The function takes O(1) time. */
tcp_connection_node_t *p_node;
tcp_connection_t *p_connection, *p_conn_hash;
if ( !p_monitor || !p_void )
if (!p_monitor || !p_void) {
return;
}
/* This p_connection is on caller's stack and not the heap. If we are interested,
* we will create a copy of the connection (on the heap) and add it to our list. */
p_connection = (tcp_connection_t *)p_void;
/* This p_connection is on caller's stack and not the heap.
* If we are interested, we will create a copy of the connection
* (on the heap) and add it to our list. */
p_connection = (tcp_connection_t *) p_void;
/* inspect the local port number of the connection to see if we're interested. */
if ( (p_monitor->port_range_begin <= p_connection->local_port) &&
(p_connection->local_port <= p_monitor->port_range_end) )
{
/* inspect the local port number of the connection to see if we're
* interested. */
if ((p_monitor->port_range_begin <= p_connection->local_port)
&& (p_connection->local_port <= p_monitor->port_range_end)) {
/* the connection is in the range of the monitor. */
/* first check the hash to see if the connection is already there. */
if ( (p_conn_hash = g_hash_table_lookup (p_monitor->hash, (gconstpointer)p_connection->key)) )
{
if ((p_conn_hash = g_hash_table_lookup(p_monitor->hash,
(gconstpointer) p_connection->key))) {
/* it's already in the hash. reset the age of the connection. */
p_conn_hash->age = TCP_CONNECTION_STARTING_AGE;
return;
}
/* Connection is not yet in the hash. Add it if max_connections not exceeded. */
if (g_hash_table_size (p_monitor->hash) >= p_monitor->max_port_monitor_connections)
/* Connection is not yet in the hash.
* Add it if max_connections not exceeded. */
if (g_hash_table_size(p_monitor->hash)
>= p_monitor->max_port_monitor_connections) {
return;
}
/* create a new connection node */
if ( (p_node = (tcp_connection_node_t *) calloc(1, sizeof(tcp_connection_node_t))) == NULL )
if ((p_node = (tcp_connection_node_t *)
calloc(1, sizeof(tcp_connection_node_t))) == NULL) {
return;
}
/* copy the connection data */
if ( copy_tcp_connection( &p_node->connection, p_connection ) != 0 )
{
/* error copying the connection data. deallocate p_node to avoid leaks and return. */
free( p_node );
if (copy_tcp_connection(&p_node->connection, p_connection) != 0) {
/* error copying the connection data. deallocate p_node to
* avoid leaks and return. */
free(p_node);
return;
}
@@ -236,21 +241,19 @@ void show_connection_to_tcp_port_monitor(
/* insert it into the monitor's hash table */
#ifdef HASH_DEBUG
fprintf (stderr, "monitor hash insert of connection [%s]\n", p_node->connection.key);
fprintf(stderr, "monitor hash insert of connection [%s]\n",
p_node->connection.key);
#endif
g_hash_table_insert( p_monitor->hash,
(gpointer)p_node->connection.key,
(gpointer)&p_node->connection);
g_hash_table_insert(p_monitor->hash,
(gpointer) p_node->connection.key, (gpointer) &p_node->connection);
/* append the node to the monitor's connection list */
if ( p_monitor->connection_list.p_tail == NULL ) /* assume p_head is NULL too */
{
if (p_monitor->connection_list.p_tail == NULL) {
/* assume p_head is NULL too */
p_monitor->connection_list.p_head = p_node;
p_monitor->connection_list.p_tail = p_node;
p_node->p_prev = NULL;
}
else
{
} else {
p_monitor->connection_list.p_tail->p_next = p_node;
p_node->p_prev = p_monitor->connection_list.p_tail;
p_monitor->connection_list.p_tail = p_node;
@@ -258,34 +261,30 @@ void show_connection_to_tcp_port_monitor(
}
}
/* ---------------------------------------------------------------------------------------
* Apply a tcp_port_monitor_function_ptr_t function to each port monitor in the collection.
* ---------------------------------------------------------------------------------------*/
/* ------------------------------------------------------------------------
* Apply a tcp_port_monitor_function_ptr_t function to each port monitor in
* the collection.
* ------------------------------------------------------------------------ */
void for_each_tcp_port_monitor_in_collection(
tcp_port_monitor_collection_t * p_collection,
tcp_port_monitor_function_ptr_t p_function,
void * p_function_args
)
tcp_port_monitor_collection_t *p_collection,
tcp_port_monitor_function_ptr_t p_function, void *p_function_args)
{
tcp_port_monitor_node_t * p_current_node, * p_next_node;
tcp_port_monitor_node_t *p_current_node, *p_next_node;
if ( !p_collection || !p_function )
if (!p_collection || !p_function) {
return;
}
/* for each monitor in the collection */
for ( p_current_node = p_collection->monitor_list.p_head; p_current_node != NULL; )
{
for (p_current_node = p_collection->monitor_list.p_head;
p_current_node != NULL; p_current_node = p_next_node) {
p_next_node = p_current_node->p_next; /* do this first! */
if ( p_current_node->p_monitor )
{
if (p_current_node->p_monitor) {
/* apply the function with the given arguments */
(*p_function)( p_current_node->p_monitor, p_function_args );
p_function(p_current_node->p_monitor, p_function_args);
}
p_current_node = p_next_node;
}
}
/* ----------------------------------------------------------------------
@@ -299,40 +298,40 @@ void for_each_tcp_port_monitor_in_collection(
* ---------------------------------- */
/* Clients should first try to "find_tcp_port_monitor" before creating one
so that there are no redundant monitors. */
tcp_port_monitor_t * create_tcp_port_monitor(
in_port_t port_range_begin,
in_port_t port_range_end,
tcp_port_monitor_args_t * p_creation_args
)
* so that there are no redundant monitors. */
tcp_port_monitor_t *create_tcp_port_monitor(in_port_t port_range_begin,
in_port_t port_range_end, tcp_port_monitor_args_t *p_creation_args)
{
tcp_port_monitor_t * p_monitor;
tcp_port_monitor_t *p_monitor;
/* create the monitor */
p_monitor = (tcp_port_monitor_t *) calloc(1, sizeof(tcp_port_monitor_t) );
if ( !p_monitor )
p_monitor = (tcp_port_monitor_t *) calloc(1, sizeof(tcp_port_monitor_t));
if (!p_monitor) {
return NULL;
}
p_monitor->max_port_monitor_connections = p_creation_args->max_port_monitor_connections;
p_monitor->max_port_monitor_connections =
p_creation_args->max_port_monitor_connections;
/* build the monitor key for the collection hash */
g_sprintf (p_monitor->key, ":%04X :%04X", port_range_begin, port_range_end);
g_sprintf(p_monitor->key, ":%04X :%04X", port_range_begin, port_range_end);
/* create the monitor's connection hash */
if ( (p_monitor->hash = g_hash_table_new (g_str_hash, g_str_equal)) == NULL)
{
/* we failed to create the hash, so destroy the monitor completely so we don't leak */
destroy_tcp_port_monitor(p_monitor,NULL);
if ((p_monitor->hash = g_hash_table_new(g_str_hash, g_str_equal)) == NULL) {
/* we failed to create the hash, so destroy the monitor completely
* so we don't leak */
destroy_tcp_port_monitor(p_monitor, NULL);
return NULL;
}
/* create the monitor's peek array */
if ( (p_monitor->p_peek = (tcp_connection_t **) calloc (p_monitor->max_port_monitor_connections,
sizeof(tcp_connection_t *))) == NULL )
{
/* we failed to create the peek array, so destroy the monitor completely, again, so we don't leak */
destroy_tcp_port_monitor(p_monitor,NULL);
return NULL ;
if ((p_monitor->p_peek = (tcp_connection_t **)
calloc(p_monitor->max_port_monitor_connections,
sizeof(tcp_connection_t *))) == NULL) {
/* we failed to create the peek array,
* so destroy the monitor completely, again, so we don't leak */
destroy_tcp_port_monitor(p_monitor, NULL);
return NULL;
}
p_monitor->port_range_begin = port_range_begin;
@@ -344,117 +343,124 @@ tcp_port_monitor_t * create_tcp_port_monitor(
return p_monitor;
}
/* Clients use this function to get connection data from the indicated port monitor.
The requested monitor value is copied into a client-supplied char buffer.
Returns 0 on success, -1 otherwise. */
int peek_tcp_port_monitor(
const tcp_port_monitor_t * p_monitor,
int item,
int connection_index,
char * p_buffer,
size_t buffer_size
)
/* Clients use this function to get connection data from the indicated
* port monitor.
* The requested monitor value is copied into a client-supplied char buffer.
* Returns 0 on success, -1 otherwise. */
int peek_tcp_port_monitor(const tcp_port_monitor_t *p_monitor, int item,
int connection_index, char *p_buffer, size_t buffer_size)
{
struct hostent *p_hostent;
struct servent *p_servent;
struct in_addr net;
if ( !p_monitor || !p_buffer || connection_index < 0 )
return(-1);
if (!p_monitor || !p_buffer || connection_index < 0) {
return -1;
}
memset(p_buffer, 0, buffer_size);
memset(&net, 0, sizeof(net));
/* if the connection index is out of range, we simply return with no error
/* if the connection index is out of range, we simply return with no error,
* having first cleared the client-supplied buffer. */
if ( (item!=COUNT) && (connection_index > (int)g_hash_table_size (p_monitor->hash) - 1) )
return(0);
if ((item != COUNT) && (connection_index
> (int) g_hash_table_size(p_monitor->hash) - 1)) {
return 0;
}
switch (item) {
case COUNT:
snprintf( p_buffer, buffer_size, "%d" , g_hash_table_size (p_monitor->hash) );
snprintf(p_buffer, buffer_size, "%d",
g_hash_table_size(p_monitor->hash));
break;
case REMOTEIP:
net.s_addr = p_monitor->p_peek[ connection_index ]->remote_addr;
snprintf( p_buffer, buffer_size, "%s", inet_ntoa( net ) );
net.s_addr = p_monitor->p_peek[connection_index]->remote_addr;
snprintf(p_buffer, buffer_size, "%s", inet_ntoa(net));
break;
case REMOTEHOST:
p_hostent = gethostbyaddr( (const void *)&p_monitor->p_peek[ connection_index ]->remote_addr,
p_hostent = gethostbyaddr((const void *)
&p_monitor->p_peek[connection_index]->remote_addr,
sizeof(in_addr_t), AF_INET);
/* if no host name found, just use ip address. */
if ( !p_hostent || !p_hostent->h_name )
{
net.s_addr = p_monitor->p_peek[ connection_index ]->remote_addr;
snprintf( p_buffer, buffer_size, "%s", inet_ntoa( net ) );
if (!p_hostent || !p_hostent->h_name) {
net.s_addr = p_monitor->p_peek[connection_index]->remote_addr;
snprintf(p_buffer, buffer_size, "%s", inet_ntoa(net));
break;
}
snprintf( p_buffer, buffer_size, "%s", p_hostent->h_name );
snprintf(p_buffer, buffer_size, "%s", p_hostent->h_name);
break;
case REMOTEPORT:
snprintf( p_buffer, buffer_size, "%d", p_monitor->p_peek[ connection_index ]->remote_port );
snprintf(p_buffer, buffer_size, "%d",
p_monitor->p_peek[connection_index]->remote_port);
break;
case REMOTESERVICE:
p_servent = getservbyport( htons(p_monitor->p_peek[ connection_index ]->remote_port ), "tcp" );
/* if no service name found for the port, just use the port number. */
if ( !p_servent || !p_servent->s_name ) {
snprintf( p_buffer, buffer_size, "%d", p_monitor->p_peek[ connection_index ]->remote_port );
p_servent = getservbyport(
htons(p_monitor->p_peek[connection_index]->remote_port), "tcp");
/* if no service name found for the port,
* just use the port number. */
if (!p_servent || !p_servent->s_name) {
snprintf(p_buffer, buffer_size, "%d",
p_monitor->p_peek[connection_index]->remote_port);
} else {
snprintf( p_buffer, buffer_size, "%s", p_servent->s_name );
snprintf(p_buffer, buffer_size, "%s", p_servent->s_name);
}
break;
case LOCALIP:
net.s_addr = p_monitor->p_peek[ connection_index ]->local_addr;
snprintf( p_buffer, buffer_size, "%s", inet_ntoa( net ) );
net.s_addr = p_monitor->p_peek[connection_index]->local_addr;
snprintf(p_buffer, buffer_size, "%s", inet_ntoa(net));
break;
case LOCALHOST:
p_hostent = gethostbyaddr( (const void *)&p_monitor->p_peek[ connection_index ]->local_addr,
p_hostent = gethostbyaddr((const void *)
&p_monitor->p_peek[connection_index]->local_addr,
sizeof(in_addr_t), AF_INET);
/* if no host name found, just use ip address. */
if ( !p_hostent || !p_hostent->h_name )
{
net.s_addr = p_monitor->p_peek[ connection_index ]->local_addr;
snprintf( p_buffer, buffer_size, "%s", inet_ntoa( net ) );
if (!p_hostent || !p_hostent->h_name) {
net.s_addr = p_monitor->p_peek[connection_index]->local_addr;
snprintf(p_buffer, buffer_size, "%s", inet_ntoa(net));
break;
}
snprintf( p_buffer, buffer_size, "%s", p_hostent->h_name );
snprintf(p_buffer, buffer_size, "%s", p_hostent->h_name);
break;
case LOCALPORT:
snprintf( p_buffer, buffer_size, "%d", p_monitor->p_peek[ connection_index ]->local_port );
snprintf(p_buffer, buffer_size, "%d",
p_monitor->p_peek[connection_index]->local_port);
break;
case LOCALSERVICE:
p_servent = getservbyport( htons(p_monitor->p_peek[ connection_index ]->local_port ), "tcp" );
/* if no service name found for the port, just use the port number. */
if ( !p_servent || !p_servent->s_name )
{
snprintf( p_buffer, buffer_size, "%d", p_monitor->p_peek[ connection_index ]->local_port );
p_servent = getservbyport(
htons(p_monitor->p_peek[connection_index]->local_port), "tcp");
/* if no service name found for the port,
* just use the port number. */
if (!p_servent || !p_servent->s_name) {
snprintf(p_buffer, buffer_size, "%d",
p_monitor->p_peek[connection_index]->local_port);
break;
}
snprintf( p_buffer, buffer_size, "%s", p_servent->s_name );
snprintf(p_buffer, buffer_size, "%s", p_servent->s_name);
break;
default:
return(-1);
return -1;
}
return(0);
return 0;
}
/* --------------------------------
@@ -462,18 +468,21 @@ int peek_tcp_port_monitor(
* -------------------------------- */
/* Create a monitor collection. Do this one first. */
tcp_port_monitor_collection_t * create_tcp_port_monitor_collection (void)
tcp_port_monitor_collection_t *create_tcp_port_monitor_collection(void)
{
tcp_port_monitor_collection_t * p_collection;
tcp_port_monitor_collection_t *p_collection;
p_collection = (tcp_port_monitor_collection_t *) calloc( 1, sizeof( tcp_port_monitor_collection_t ) );
if ( !p_collection )
p_collection = (tcp_port_monitor_collection_t *)
calloc(1, sizeof(tcp_port_monitor_collection_t));
if (!p_collection) {
return NULL;
}
/* create the collection's monitor hash */
if ( (p_collection->hash = g_hash_table_new (g_str_hash, g_str_equal)) == NULL)
{
/* we failed to create the hash, so destroy the monitor completely so we don't leak */
if ((p_collection->hash = g_hash_table_new(g_str_hash, g_str_equal))
== NULL) {
/* we failed to create the hash,
* so destroy the monitor completely so we don't leak */
destroy_tcp_port_monitor_collection(p_collection);
return NULL;
}
@@ -484,118 +493,113 @@ tcp_port_monitor_collection_t * create_tcp_port_monitor_collection (void)
return p_collection;
}
/* Destroy the monitor collection (and the monitors inside). Do this one last. */
/* Destroy the monitor collection (and the monitors inside).
* Do this one last. */
void destroy_tcp_port_monitor_collection(
tcp_port_monitor_collection_t * p_collection
)
tcp_port_monitor_collection_t *p_collection)
{
tcp_port_monitor_node_t * p_current_node, * p_next_node;
tcp_port_monitor_node_t *p_current_node, *p_next_node;
if ( !p_collection )
if (!p_collection) {
return;
}
/* destroy the monitors */
for_each_tcp_port_monitor_in_collection(
p_collection,
&destroy_tcp_port_monitor,
NULL
);
for_each_tcp_port_monitor_in_collection(p_collection,
&destroy_tcp_port_monitor, NULL);
/* next destroy the empty monitor nodes */
for ( p_current_node = p_collection->monitor_list.p_head; p_current_node != NULL; )
{
for (p_current_node = p_collection->monitor_list.p_head;
p_current_node != NULL; p_current_node = p_next_node) {
p_next_node = p_current_node->p_next; /* do this first! */
free( p_current_node );
p_current_node = p_next_node;
free(p_current_node);
}
/* destroy the collection's hash */
g_hash_table_destroy (p_collection->hash);
g_hash_table_destroy(p_collection->hash);
p_collection->hash = NULL;
free( p_collection );
p_collection=NULL;
free(p_collection);
p_collection = NULL;
}
/* Updates the tcp statistics for all monitors within a collection */
void update_tcp_port_monitor_collection(
tcp_port_monitor_collection_t * p_collection
)
tcp_port_monitor_collection_t *p_collection)
{
FILE *fp;
char buf[256];
tcp_connection_t conn;
unsigned long inode,uid,state;
unsigned long inode, uid, state;
if ( !p_collection )
if (!p_collection) {
return;
}
/* age the connections in all port monitors. */
for_each_tcp_port_monitor_in_collection(
p_collection,
&age_tcp_port_monitor,
NULL
);
for_each_tcp_port_monitor_in_collection(p_collection,
&age_tcp_port_monitor, NULL);
/* read tcp data from /proc/net/tcp */
if ( ( fp = fopen("/proc/net/tcp", "r" ) ) == NULL )
if ((fp = fopen("/proc/net/tcp", "r")) == NULL) {
return;
}
/* ignore field name line */
fgets(buf, 255, fp);
/* read all tcp connections */
while (fgets (buf, sizeof (buf), fp) != NULL) {
while (fgets(buf, sizeof(buf), fp) != NULL) {
if ( sscanf (buf, "%*d: %x:%hx %x:%hx %lx %*x:%*x %*x:%*x %*x %lu %*d %lu",
(unsigned int *)&conn.local_addr, &conn.local_port,
(unsigned int *)&conn.remote_addr, &conn.remote_port,
(unsigned long *)&state, (unsigned long *)&uid, (unsigned long *)&inode) != 7 )
if (sscanf(buf,
"%*d: %x:%hx %x:%hx %lx %*x:%*x %*x:%*x %*x %lu %*d %lu",
(unsigned int *) &conn.local_addr, &conn.local_port,
(unsigned int *) &conn.remote_addr, &conn.remote_port,
(unsigned long *) &state, (unsigned long *) &uid,
(unsigned long *) &inode) != 7) {
fprintf(stderr, "/proc/net/tcp: bad file format\n");
}
fprintf( stderr, "/proc/net/tcp: bad file format\n" );
if ((inode == 0) || (state != TCP_ESTABLISHED)) continue;
if ((inode == 0) || (state != TCP_ESTABLISHED)) {
continue;
}
/* build hash key */
g_sprintf (conn.key, "%08X:%04X %08X:%04X",
conn.local_addr, conn.local_port,
conn.remote_addr, conn.remote_port);
g_sprintf(conn.key, "%08X:%04X %08X:%04X", conn.local_addr,
conn.local_port, conn.remote_addr, conn.remote_port);
/* show the connection to each port monitor. */
for_each_tcp_port_monitor_in_collection(
p_collection,
&show_connection_to_tcp_port_monitor,
(void *) &conn
);
for_each_tcp_port_monitor_in_collection(p_collection,
&show_connection_to_tcp_port_monitor, (void *) &conn);
}
fclose(fp);
/* rebuild the connection peek tables of all monitors so clients can peek in O(1) time */
for_each_tcp_port_monitor_in_collection(
p_collection,
&rebuild_tcp_port_monitor_peek_table,
NULL
);
/* rebuild the connection peek tables of all monitors
* so clients can peek in O(1) time */
for_each_tcp_port_monitor_in_collection(p_collection,
&rebuild_tcp_port_monitor_peek_table, NULL);
}
/* After clients create a monitor, use this to add it to the collection.
Returns 0 on success, -1 otherwise. */
* Returns 0 on success, -1 otherwise. */
int insert_tcp_port_monitor_into_collection(
tcp_port_monitor_collection_t * p_collection,
tcp_port_monitor_t * p_monitor
)
tcp_port_monitor_collection_t *p_collection,
tcp_port_monitor_t *p_monitor)
{
tcp_port_monitor_node_t * p_node;
tcp_port_monitor_node_t *p_node;
if ( !p_collection || !p_monitor )
return (-1);
if (!p_collection || !p_monitor) {
return -1;
}
/* create a container node for this monitor */
p_node = (tcp_port_monitor_node_t *) calloc( 1, sizeof(tcp_port_monitor_node_t) );
if ( !p_node )
return (-1);
p_node = (tcp_port_monitor_node_t *)
calloc(1, sizeof(tcp_port_monitor_node_t));
if (!p_node) {
return -1;
}
/* populate the node */
p_node->p_monitor = p_monitor;
@@ -603,18 +607,19 @@ int insert_tcp_port_monitor_into_collection(
/* add a pointer to this monitor to the collection's hash */
#ifdef HASH_DEBUG
fprintf (stderr, "collection hash insert of monitor [%s]\n", p_monitor->key);
fprintf(stderr, "collection hash insert of monitor [%s]\n", p_monitor->key);
#endif
g_hash_table_insert (p_collection->hash, (gpointer)p_monitor->key, (gpointer)p_monitor);
g_hash_table_insert(p_collection->hash, (gpointer) p_monitor->key,
(gpointer) p_monitor);
/* tail of the container gets this node */
if ( !p_collection->monitor_list.p_tail )
if (!p_collection->monitor_list.p_tail) {
p_collection->monitor_list.p_tail = p_node;
else
{
} else {
/* p_next of the tail better be NULL */
if ( p_collection->monitor_list.p_tail->p_next != NULL )
return (-1);
if (p_collection->monitor_list.p_tail->p_next != NULL) {
return -1;
}
/* splice node onto tail */
p_collection->monitor_list.p_tail->p_next = p_node;
@@ -622,27 +627,27 @@ int insert_tcp_port_monitor_into_collection(
}
/* if this was the first element added */
if ( !p_collection->monitor_list.p_head )
if (!p_collection->monitor_list.p_head) {
p_collection->monitor_list.p_head = p_collection->monitor_list.p_tail;
}
return 0;
}
/* Clients need a way to find monitors */
tcp_port_monitor_t * find_tcp_port_monitor(
const tcp_port_monitor_collection_t * p_collection,
in_port_t port_range_begin,
in_port_t port_range_end
)
tcp_port_monitor_t *find_tcp_port_monitor(
const tcp_port_monitor_collection_t *p_collection,
in_port_t port_range_begin, in_port_t port_range_end)
{
tcp_port_monitor_t *p_monitor;
gchar key[12];
if ( !p_collection )
if (!p_collection) {
return NULL;
}
/* is monitor in hash? */
g_sprintf (key, ":%04X :%04X", port_range_begin, port_range_end);
p_monitor = g_hash_table_lookup( p_collection->hash, (gconstpointer)key);
return (p_monitor);
g_sprintf(key, ":%04X :%04X", port_range_begin, port_range_end);
p_monitor = g_hash_table_lookup(p_collection->hash, (gconstpointer) key);
return p_monitor;
}

View File

@@ -1,7 +1,6 @@
/* $Id$ */
/*
* libtcp-portmon.h: tcp port monitoring library.
/* libtcp-portmon.h: tcp port monitoring library.
*
* Copyright (C) 2005-2007 Philip Kovacs pkovacs@users.sourceforge.net
*
@@ -18,9 +17,7 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
* USA.
*
*/
* USA. */
#ifndef LIBTCP_PORTMON_H
#define LIBTCP_PORTMON_H
@@ -40,7 +37,8 @@
#include <glib.h>
#define TCP_CONNECTION_STARTING_AGE 1 /* connection deleted if unseen again after this # of refreshes */
/* connection deleted if unseen again after this # of refreshes */
#define TCP_CONNECTION_STARTING_AGE 1
#define TCP_CONNECTION_HASH_KEY_SIZE 28
#define TCP_PORT_MONITOR_HASH_KEY_SIZE 12
@@ -54,7 +52,7 @@
/* The inventory of peekable items within the port monitor. */
enum tcp_port_monitor_peekables {
COUNT=0,
COUNT = 0,
REMOTEIP,
REMOTEHOST,
REMOTEPORT,
@@ -72,7 +70,8 @@ enum tcp_port_monitor_peekables {
* are not seen again in subsequent update cycles.
* ------------------------------------------------------------------------ */
typedef struct _tcp_connection_t {
gchar key[TCP_CONNECTION_HASH_KEY_SIZE]; /* connection's key in monitor hash */
/* connection's key in monitor hash */
gchar key[TCP_CONNECTION_HASH_KEY_SIZE];
in_addr_t local_addr;
in_port_t local_port;
in_addr_t remote_addr;
@@ -84,98 +83,99 @@ typedef struct _tcp_connection_t {
* Copy a connection
*
* Returns 0 on success, -1 otherwise
* ----------------------------------*/
int copy_tcp_connection(
tcp_connection_t * /* p_dest_connection */,
const tcp_connection_t * /* p_source_connection */
);
* ---------------------------------- */
int copy_tcp_connection(tcp_connection_t *p_dest_connection,
const tcp_connection_t *p_source_connection);
/* ------------------------------------------------------------------------
/* -------------------------------------------------------------------
* A tcp connection node/list
*
* Connections within each monitor are stored in a double-linked list.
* ------------------------------------------------------------------------ */
* ------------------------------------------------------------------- */
typedef struct _tcp_connection_node_t {
tcp_connection_t connection;
struct _tcp_connection_node_t * p_prev;
struct _tcp_connection_node_t * p_next;
struct _tcp_connection_node_t *p_prev;
struct _tcp_connection_node_t *p_next;
} tcp_connection_node_t;
typedef struct _tcp_connection_list_t {
tcp_connection_node_t * p_head;
tcp_connection_node_t * p_tail;
tcp_connection_node_t *p_head;
tcp_connection_node_t *p_tail;
} tcp_connection_list_t;
/* --------------
* A port monitor
* -------------- */
typedef struct _tcp_port_monitor_t {
gchar key[TCP_PORT_MONITOR_HASH_KEY_SIZE]; /* monitor's key in collection hash */
in_port_t port_range_begin; /* start of monitor port range */
in_port_t port_range_end; /* begin = end to monitor a single port */
tcp_connection_list_t connection_list; /* list of connections for this monitor */
GHashTable *hash; /* hash table of pointers into connection list */
tcp_connection_t **p_peek; /* array of connection pointers for O(1) peeking */
unsigned int max_port_monitor_connections; /* max number of connections */
/* monitor's key in collection hash */
gchar key[TCP_PORT_MONITOR_HASH_KEY_SIZE];
/* start of monitor port range */
in_port_t port_range_begin;
/* begin = end to monitor a single port */
in_port_t port_range_end;
/* list of connections for this monitor */
tcp_connection_list_t connection_list;
/* hash table of pointers into connection list */
GHashTable *hash;
/* array of connection pointers for O(1) peeking */
tcp_connection_t **p_peek;
/* max number of connections */
unsigned int max_port_monitor_connections;
} tcp_port_monitor_t;
/* ------------------------
* A port monitor node/list
* ------------------------ */
typedef struct _tcp_port_monitor_node_t {
tcp_port_monitor_t * p_monitor;
tcp_port_monitor_t *p_monitor;
struct _tcp_port_monitor_node_t *p_next;
} tcp_port_monitor_node_t;
typedef struct __tcp_port_monitor_list_t {
tcp_port_monitor_node_t * p_head;
tcp_port_monitor_node_t * p_tail;
tcp_port_monitor_node_t *p_head;
tcp_port_monitor_node_t *p_tail;
} tcp_port_monitor_list_t;
/* ---------------------------------------
* A port monitor utility function typedef
* ---------------------------------------*/
typedef void (*tcp_port_monitor_function_ptr_t)( tcp_port_monitor_t * /* p_monitor */, void * /* p_void */ );
* --------------------------------------- */
typedef void (*tcp_port_monitor_function_ptr_t)(tcp_port_monitor_t *p_monitor,
void *p_void);
/* ---------------------------------------------------------------------------
* Port monitor utility functions implementing tcp_port_monitor_function_ptr_t
* ---------------------------------------------------------------------------*/
void destroy_tcp_port_monitor(
tcp_port_monitor_t * /* p_monitor */,
void * /* p_void (use NULL for this function) */
);
/* -------------------------------------------
* Port monitor utility functions implementing
* tcp_port_monitor_function_ptr_t
* ------------------------------------------- */
void destroy_tcp_port_monitor(tcp_port_monitor_t *p_monitor,
void *p_void /* (use NULL for this function) */);
void age_tcp_port_monitor(
tcp_port_monitor_t * /* p_monitor */,
void * /* p_void (use NULL for this function) */
);
void age_tcp_port_monitor(tcp_port_monitor_t *p_monitor,
void *p_void /* (use NULL for this function) */);
void rebuild_tcp_port_monitor_peek_table(
tcp_port_monitor_t * /* p_monitor */,
void * /* p_void (use NULL for this function) */
);
void rebuild_tcp_port_monitor_peek_table(tcp_port_monitor_t *p_monitor,
void *p_void /* (use NULL for this function) */);
void show_connection_to_tcp_port_monitor(
tcp_port_monitor_t * /* p_monitor */,
void * /* p_connection (client should cast) */
);
void show_connection_to_tcp_port_monitor(tcp_port_monitor_t *p_monitor,
void *p_connection /* (client should cast) */);
/* -----------------------------
* A tcp port monitor collection
* -----------------------------*/
* ----------------------------- */
typedef struct _tcp_port_monitor_collection_t {
tcp_port_monitor_list_t monitor_list; /* list of monitors for this collection */
GHashTable *hash; /* hash table of pointers into collection's monitor list */
/* list of monitors for this collection */
tcp_port_monitor_list_t monitor_list;
/* hash table of pointers into collection's monitor list */
GHashTable *hash;
} tcp_port_monitor_collection_t;
/* ---------------------------------------------------------------------------------------
* Apply a tcp_port_monitor_function_ptr_t function to each port monitor in the collection.
* ---------------------------------------------------------------------------------------*/
/* --------------------------------------------------------
* Apply a tcp_port_monitor_function_ptr_t function to each
* port monitor in the collection.
* -------------------------------------------------------- */
void for_each_tcp_port_monitor_in_collection(
tcp_port_monitor_collection_t * /* p_collection */,
tcp_port_monitor_function_ptr_t /* p_function */,
void * /* p_function_args (for user arguments) */
);
tcp_port_monitor_collection_t *p_collection,
tcp_port_monitor_function_ptr_t p_function,
void *p_function_args /* (for user arguments) */);
/* ----------------------------------------------------------------------
* CLIENT INTERFACE
@@ -185,62 +185,57 @@ void for_each_tcp_port_monitor_in_collection(
/* struct to hold monitor creation arguments */
typedef struct _tcp_port_monitor_args_t {
int max_port_monitor_connections; /* monitor supports tracking at most this many connections */
/* monitor supports tracking at most this many connections */
int max_port_monitor_connections;
} tcp_port_monitor_args_t;
/* ----------------------------------
* Client operations on port monitors
* ---------------------------------- */
/* Clients should first try to "find_tcp_port_monitor" before creating one
so that there are no redundant monitors. */
tcp_port_monitor_t * create_tcp_port_monitor(
in_port_t /* port_range_begin */,
in_port_t /* port_range_end */,
tcp_port_monitor_args_t * /* p_creation_args */
);
/* Clients should first try to "find_tcp_port_monitor" before creating one,
* so that there are no redundant monitors. */
tcp_port_monitor_t *create_tcp_port_monitor(in_port_t port_range_begin,
in_port_t port_range_end, tcp_port_monitor_args_t *p_creation_args);
/* Clients use this function to get connection data from the indicated port monitor.
The requested monitor value is copied into a client-supplied char buffer.
Returns 0 on success, -1 otherwise. */
int peek_tcp_port_monitor(
const tcp_port_monitor_t * /* p_monitor */,
int /* item, ( item of interest, from tcp_port_monitor_peekables enum ) */,
int /* connection_index, ( 0 to number of connections in monitor - 1 )*/,
char * /* p_buffer, buffer to receive requested value */,
size_t /* buffer_size, size of p_buffer */
);
/* Clients use this function to get connection data from
* the indicated port monitor.
* The requested monitor value is copied into a client-supplied char buffer.
* Returns 0 on success, -1 otherwise. */
int peek_tcp_port_monitor(const tcp_port_monitor_t *p_monitor,
/* (item of interest, from tcp_port_monitor_peekables enum) */
int item,
/* (0 to number of connections in monitor - 1) */
int connection_index,
/* buffer to receive requested value */
char *p_buffer,
/* size of p_buffer */
size_t buffer_size);
/* --------------------------------
* Client operations on collections
* -------------------------------- */
/* Create a monitor collection. Do this one first. */
tcp_port_monitor_collection_t * create_tcp_port_monitor_collection (void);
tcp_port_monitor_collection_t *create_tcp_port_monitor_collection(void);
/* Destroy the monitor collection (and everything it contains). Do this one last. */
/* Destroy the monitor collection (and everything it contains).
* Do this one last. */
void destroy_tcp_port_monitor_collection(
tcp_port_monitor_collection_t * /* p_collection */
);
tcp_port_monitor_collection_t *p_collection);
/* Updates the tcp statitics for all monitors within a collection */
void update_tcp_port_monitor_collection(
tcp_port_monitor_collection_t * /* p_collection */
);
tcp_port_monitor_collection_t *p_collection);
/* After clients create a monitor, use this to add it to the collection.
Returns 0 on success, -1 otherwise. */
* Returns 0 on success, -1 otherwise. */
int insert_tcp_port_monitor_into_collection(
tcp_port_monitor_collection_t * /* p_collection */,
tcp_port_monitor_t * /* p_monitor */
);
tcp_port_monitor_collection_t *p_collection, tcp_port_monitor_t *p_monitor);
/* Clients need a way to find monitors */
tcp_port_monitor_t * find_tcp_port_monitor(
const tcp_port_monitor_collection_t * /* p_collection */,
in_port_t /* port_range_begin */,
in_port_t /* port_range_end */
);
tcp_port_monitor_t *find_tcp_port_monitor(
const tcp_port_monitor_collection_t *p_collection,
in_port_t port_range_begin, in_port_t port_range_end);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,4 @@
/*
* Conky, a system monitor, based on torsmo
/* Conky, a system monitor, based on torsmo
*
* Any original torsmo code is licensed under the BSD license
*
@@ -8,7 +7,8 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*/
* $Id$ */
#include <sys/stat.h>
#include <sys/time.h>
@@ -42,22 +41,24 @@ void update_mail_count(struct local_mail_s *mail)
{
struct stat buf;
if (mail == NULL)
if (mail == NULL) {
return;
}
/* TODO: use that fine file modification notify on Linux 2.4 */
/* don't check mail so often (9.5s is minimum interval) */
if (current_update_time - mail->last_update < 9.5)
if (current_update_time - mail->last_update < 9.5) {
return;
else
} else {
mail->last_update = current_update_time;
}
if (stat(mail->box, &buf)) {
static int rep;
if (!rep) {
ERR("can't stat %s: %s", mail->box,
strerror(errno));
ERR("can't stat %s: %s", mail->box, strerror(errno));
rep = 1;
}
return;
@@ -70,9 +71,7 @@ void update_mail_count(struct local_mail_s *mail)
struct dirent *dirent;
mail->mail_count = mail->new_mail_count = 0;
dirname =
(char *) malloc(sizeof(char) *
(strlen(mail->box) + 5));
dirname = (char *) malloc(sizeof(char) * (strlen(mail->box) + 5));
if (!dirname) {
ERR("malloc");
return;
@@ -135,43 +134,46 @@ void update_mail_count(struct local_mail_s *mail)
mail->new_mail_count = mail->mail_count = 0;
fp = open_file(mail->box, &rep);
if (!fp)
if (!fp) {
return;
}
/* NOTE: adds mail as new if there isn't Status-field at all */
while (!feof(fp)) {
char buf[128];
if (fgets(buf, 128, fp) == NULL)
if (fgets(buf, 128, fp) == NULL) {
break;
}
if (strncmp(buf, "From ", 5) == 0) {
/* ignore MAILER-DAEMON */
if (strncmp(buf + 5, "MAILER-DAEMON ", 14)
!= 0) {
if (strncmp(buf + 5, "MAILER-DAEMON ", 14) != 0) {
mail->mail_count++;
if (reading_status)
if (reading_status) {
mail->new_mail_count++;
else
} else {
reading_status = 1;
}
}
} else {
if (reading_status
&& strncmp(buf, "X-Mozilla-Status:",
17) == 0) {
&& strncmp(buf, "X-Mozilla-Status:", 17) == 0) {
/* check that mail isn't already read */
if (strchr(buf + 21, '0'))
if (strchr(buf + 21, '0')) {
mail->new_mail_count++;
}
reading_status = 0;
continue;
}
if (reading_status
&& strncmp(buf, "Status:", 7) == 0) {
if (reading_status && strncmp(buf, "Status:", 7) == 0) {
/* check that mail isn't already read */
if (strchr(buf + 7, 'R') == NULL)
if (strchr(buf + 7, 'R') == NULL) {
mail->new_mail_count++;
}
reading_status = 0;
continue;
@@ -179,14 +181,16 @@ void update_mail_count(struct local_mail_s *mail)
}
/* skip until \n */
while (strchr(buf, '\n') == NULL && !feof(fp))
while (strchr(buf, '\n') == NULL && !feof(fp)) {
fgets(buf, 128, fp);
}
}
fclose(fp);
if (reading_status)
if (reading_status) {
mail->new_mail_count++;
}
mail->last_mtime = buf.st_mtime;
}

View File

@@ -1,5 +1,4 @@
/*
* Conky, a system monitor, based on torsmo
/* Conky, a system monitor, based on torsmo
*
* Any original torsmo code is licensed under the BSD license
*
@@ -8,7 +7,8 @@
* Please see COPYING for details
*
* Copyright (c) 2006 Marco Candrian <mac@calmar.ws>
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*/
* $Id$ */
#include "conky.h"
#include <sys/stat.h>
@@ -57,23 +56,20 @@ static int subject_width;
static int print_mails;
static int time_delay;
/*
* I don't know what to use: TEXT_BUFFER_SIZE or text_buffer_size
/* I don't know what to use: TEXT_BUFFER_SIZE or text_buffer_size
* text_buffer_size is the maximum output in chars
* TEXT_BUFFER_SIZE actually something like a allowed size
* for things in the config, below 'TEXT'. Or what is more probably
* max_user_text. Anyway, I used TEXT_BUFFER_SIZE for not 'output' things here
* TEXT_BUFFER_SIZE actually something like a allowed size for things in the
* config, below 'TEXT'. Or what is more probably max_user_text.
* Anyway, I used TEXT_BUFFER_SIZE for not 'output' things here
* -- calmar
*
* To clarify, TEXT_BUFFER_SIZE is used for buffers of fixed size, and
* text_buffer_size is used for buffers which can change in size.
* text_buffer_size is just defined as TEXT_BUFFER_SIZE to start,
* so its okay for most things, however if something is allocated
* with text_buffer_size and then text_buffer_size changes but
* the array doesn't, you might have some issues if you are using
* text_buffer_size to determine the size of the array.
* -- brenden
*/
* text_buffer_size is just defined as TEXT_BUFFER_SIZE to start, so it's okay
* for most things, however if something is allocated with text_buffer_size and
* then text_buffer_size changes but the array doesn't, you might have some
* issues if you are using text_buffer_size to determine the size of the array.
* -- brenden */
static char mbox_mail_spool[TEXT_BUFFER_SIZE];
@@ -94,6 +90,7 @@ void mbox_scan(char *args, char *output, size_t max_len)
if (!args_ok || force_rescan) {
char *substr = strstr(args, "-n");
if (substr) {
if (sscanf(substr, "-n %i", &print_mails) != 1) {
print_mails = PRINT_MAILS;
@@ -101,8 +98,9 @@ void mbox_scan(char *args, char *output, size_t max_len)
} else {
print_mails = PRINT_MAILS;
}
if (print_mails < 1)
if (print_mails < 1) {
print_mails = 1;
}
substr = strstr(args, "-t");
if (substr) {
@@ -134,12 +132,14 @@ void mbox_scan(char *args, char *output, size_t max_len)
if (args[strlen(args) - 1] == '"') {
strncpy(mbox_mail_spool, args, TEXT_BUFFER_SIZE);
char *start = strchr(mbox_mail_spool, '"') + 1;
start[(long)(strrchr(mbox_mail_spool, '"') - start)] = '\0';
start[(long) (strrchr(mbox_mail_spool, '"') - start)] = '\0';
strncpy(mbox_mail_spool, start, TEXT_BUFFER_SIZE);
} else {
char *copy_args = strdup(args);
char *tmp = strtok(copy_args, " ");
char *start = tmp;
while (tmp) {
tmp = strtok(NULL, " ");
if (tmp) {
@@ -150,7 +150,9 @@ void mbox_scan(char *args, char *output, size_t max_len)
free(copy_args);
}
if (strlen(mbox_mail_spool) < 1) {
CRIT_ERR("Usage: ${mboxscan [-n <number of messages to print>] [-fw <from width>] [-sw <subject width>] [-t <delay in sec> mbox]}");
CRIT_ERR("Usage: ${mboxscan [-n <number of messages to print>] "
"[-fw <from width>] [-sw <subject width>] "
"[-t <delay in sec> mbox]}");
}
/* allowing $MAIL in the config */
@@ -165,8 +167,9 @@ void mbox_scan(char *args, char *output, size_t max_len)
}
/* if time_delay not yet reached, then return */
if (current_update_time - last_update < time_delay && !force_rescan)
if (current_update_time - last_update < time_delay && !force_rescan) {
return;
}
last_update = current_update_time;
@@ -178,25 +181,28 @@ void mbox_scan(char *args, char *output, size_t max_len)
}
/* modification time has not changed, so skip scanning the box */
if (statbuf.st_ctime == last_ctime && statbuf.st_mtime == last_mtime && !force_rescan) {
if (statbuf.st_ctime == last_ctime && statbuf.st_mtime == last_mtime
&& !force_rescan) {
return;
}
last_ctime = statbuf.st_ctime;
last_mtime = statbuf.st_mtime;
/* build up double-linked ring-list to hold data, while scanning down * the mbox */
/* build up double-linked ring-list to hold data, while scanning down the
* mbox */
struct ring_list *curr = 0, *prev = 0, *startlist = 0;
for (i = 0; i < print_mails; i++) {
curr = (struct ring_list *)malloc(sizeof(struct ring_list));
curr->from = (char *)malloc(sizeof(char[from_width + 1]));
curr->subject = (char *)malloc(sizeof(char[subject_width + 1]));
curr = (struct ring_list *) malloc(sizeof(struct ring_list));
curr->from = (char *) malloc(sizeof(char[from_width + 1]));
curr->subject = (char *) malloc(sizeof(char[subject_width + 1]));
curr->from[0] = '\0';
curr->subject[0] = '\0';
if (i == 0)
if (i == 0) {
startlist = curr;
}
if (i > 0) {
curr->previous = prev;
prev->next = curr;
@@ -216,17 +222,20 @@ void mbox_scan(char *args, char *output, size_t max_len)
return;
}
flag = 1; /* first find a "From " to set it to 0 for header-sarchings */
/* first find a "From " to set it to 0 for header-sarchings */
flag = 1;
while (!feof(fp)) {
if (fgets(buf, text_buffer_size, fp) == NULL)
if (fgets(buf, text_buffer_size, fp) == NULL) {
break;
}
if (strncmp(buf, "From ", 5) == 0) {
curr = curr->next;
/* skip until \n */
while (strchr(buf, '\n') == NULL && !feof(fp))
while (strchr(buf, '\n') == NULL && !feof(fp)) {
fgets(buf, text_buffer_size, fp);
}
flag = 0; /* in the headers now */
continue;
@@ -240,8 +249,9 @@ void mbox_scan(char *args, char *output, size_t max_len)
/* beyond the headers now (empty line), skip until \n */
/* then search for new mail ("From ") */
while (strchr(buf, '\n') == NULL && !feof(fp))
while (strchr(buf, '\n') == NULL && !feof(fp)) {
fgets(buf, text_buffer_size, fp);
}
flag = 1; /* in the body now */
continue;
}
@@ -253,10 +263,12 @@ void mbox_scan(char *args, char *output, size_t max_len)
flag = 1; /* search for next From */
curr->subject[0] = '\0';
curr->from[0] = '\0';
curr = curr->previous; /* (will get current again on new * 'From ' finding) */
/* (will get current again on new 'From ' finding) */
curr = curr->previous;
/* Skip until \n */
while (strchr(buf, '\n') == NULL && !feof(fp))
while (strchr(buf, '\n') == NULL && !feof(fp)) {
fgets(buf, text_buffer_size, fp);
}
continue;
}
@@ -272,12 +284,14 @@ void mbox_scan(char *args, char *output, size_t max_len)
continue;
}
if (buf[u] == '<' && i > 1) { /* some are: From: * <foo@bar.com> */
/* some are: From: <foo@bar.com> */
if (buf[u] == '<' && i > 1) {
curr->from[i] = '\0';
/* skip until \n */
while (strchr(buf, '\n') == NULL && !feof(fp))
while (strchr(buf, '\n') == NULL && !feof(fp)) {
fgets(buf, text_buffer_size, fp);
}
break;
}
@@ -294,8 +308,9 @@ void mbox_scan(char *args, char *output, size_t max_len)
if (i >= from_width) {
curr->from[i] = '\0';
/* skip until \n */
while (strchr(buf, '\n') == NULL && !feof(fp))
while (strchr(buf, '\n') == NULL && !feof(fp)) {
fgets(buf, text_buffer_size, fp);
}
break;
}
@@ -323,8 +338,9 @@ void mbox_scan(char *args, char *output, size_t max_len)
curr->subject[i] = '\0';
/* skip until \n */
while (strchr(buf, '\n') == NULL && !feof(fp))
while (strchr(buf, '\n') == NULL && !feof(fp)) {
fgets(buf, text_buffer_size, fp);
}
break;
}
@@ -332,22 +348,23 @@ void mbox_scan(char *args, char *output, size_t max_len)
curr->subject[i++] = buf[u++];
}
}
}
fclose(fp);
output[0] = '\0';
struct ring_list *tmp;
i = print_mails;
while (i) {
if (curr->from[0] != '\0') {
if (i != print_mails) {
snprintf(buf, text_buffer_size, "\nF: %-*s S: %-*s", from_width, curr->from, subject_width, curr->subject);
snprintf(buf, text_buffer_size, "\nF: %-*s S: %-*s", from_width,
curr->from, subject_width, curr->subject);
} else { /* first time - no \n in front */
snprintf(buf, text_buffer_size, "F: %-*s S: %-*s", from_width, curr->from, subject_width, curr->subject);
snprintf(buf, text_buffer_size, "F: %-*s S: %-*s", from_width,
curr->from, subject_width, curr->subject);
}
} else {
snprintf(buf, text_buffer_size, "\n");
}

View File

@@ -1,5 +1,4 @@
/*
* Conky, a system monitor, based on torsmo
/* Conky, a system monitor, based on torsmo
*
* Any original torsmo code is licensed under the BSD license
*
@@ -8,7 +7,8 @@
* Please see COPYING for details
*
* Copyright (c) 2006 Marco Candrian <mac@calmar.ws>
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*/
* $Id$ */
#ifndef _MBOXSCAN_H_
#define _MBOXSCAN_H_

View File

@@ -1,5 +1,4 @@
/*
* Conky, a system monitor, based on torsmo
/* Conky, a system monitor, based on torsmo
*
* Any original torsmo code is licensed under the BSD license
*
@@ -8,7 +7,8 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*/
* $Id$ */
#include <sys/ioctl.h>
@@ -54,15 +53,15 @@ int mixer_init(const char *name)
{
unsigned int i;
if (name == 0 || name[0] == '\0')
if (name == 0 || name[0] == '\0') {
name = "vol";
}
/* open mixer */
if (mixer_fd <= 0) {
mixer_fd = open(MIXER_DEV, O_RDONLY);
if (mixer_fd == -1) {
ERR("can't open %s: %s", MIXER_DEV,
strerror(errno));
ERR("can't open %s: %s", MIXER_DEV, strerror(errno));
return -1;
}
}
@@ -82,8 +81,9 @@ static int mixer_get(int i)
int val = -1;
if (ioctl(mixer_fd, MIXER_READ(i), &val) == -1) {
if (!rep)
if (!rep) {
ERR("mixer ioctl: %s", strerror(errno));
}
rep = 1;
return 0;
}
@@ -95,6 +95,7 @@ static int mixer_get(int i)
int mixer_get_avg(int i)
{
int v = mixer_get(i);
return ((v >> 8) + (v & 0xFF)) / 2;
}

155
src/mpd.c
View File

@@ -1,5 +1,4 @@
/*
* Conky, a system monitor, based on torsmo
/* Conky, a system monitor, based on torsmo
*
* Any original torsmo code is licensed under the BSD license
*
@@ -7,7 +6,8 @@
*
* Please see COPYING for details
*
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
@@ -22,8 +22,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*/
* $Id$ */
#include "conky.h"
#include <stdio.h>
@@ -32,42 +31,52 @@
#include "libmpdclient.h"
timed_thread *mpd_timed_thread = NULL;
void clear_mpd_stats(struct information *current_info);
void init_mpd_stats(struct information *current_info)
{
if (current_info->mpd.artist == NULL)
if (current_info->mpd.artist == NULL) {
current_info->mpd.artist = malloc(TEXT_BUFFER_SIZE);
if (current_info->mpd.album == NULL)
}
if (current_info->mpd.album == NULL) {
current_info->mpd.album = malloc(TEXT_BUFFER_SIZE);
if (current_info->mpd.title == NULL)
}
if (current_info->mpd.title == NULL) {
current_info->mpd.title = malloc(TEXT_BUFFER_SIZE);
if (current_info->mpd.random == NULL)
}
if (current_info->mpd.random == NULL) {
current_info->mpd.random = malloc(TEXT_BUFFER_SIZE);
if (current_info->mpd.repeat == NULL)
}
if (current_info->mpd.repeat == NULL) {
current_info->mpd.repeat = malloc(TEXT_BUFFER_SIZE);
if (current_info->mpd.track == NULL)
}
if (current_info->mpd.track == NULL) {
current_info->mpd.track = malloc(TEXT_BUFFER_SIZE);
if (current_info->mpd.status == NULL)
}
if (current_info->mpd.status == NULL) {
current_info->mpd.status = malloc(TEXT_BUFFER_SIZE);
if (current_info->mpd.name == NULL)
}
if (current_info->mpd.name == NULL) {
current_info->mpd.name = malloc(TEXT_BUFFER_SIZE);
if (current_info->mpd.file == NULL)
}
if (current_info->mpd.file == NULL) {
current_info->mpd.file = malloc(TEXT_BUFFER_SIZE);
}
clear_mpd_stats(current_info);
}
void clear_mpd_stats(struct information *current_info)
{
*current_info->mpd.name=0;
*current_info->mpd.file=0;
*current_info->mpd.artist=0;
*current_info->mpd.album=0;
*current_info->mpd.title=0;
*current_info->mpd.random=0;
*current_info->mpd.repeat=0;
*current_info->mpd.track=0;
*current_info->mpd.status=0;
*current_info->mpd.name = 0;
*current_info->mpd.file = 0;
*current_info->mpd.artist = 0;
*current_info->mpd.album = 0;
*current_info->mpd.title = 0;
*current_info->mpd.random = 0;
*current_info->mpd.repeat = 0;
*current_info->mpd.track = 0;
*current_info->mpd.status = 0;
current_info->mpd.bitrate = 0;
current_info->mpd.progress = 0;
current_info->mpd.elapsed = 0;
@@ -77,9 +86,11 @@ void clear_mpd_stats(struct information *current_info)
void *update_mpd(void)
{
struct information *current_info = &info;
while (1) {
if (!current_info->conn) {
current_info->conn = mpd_newConnection(current_info->mpd.host, current_info->mpd.port, 10);
current_info->conn = mpd_newConnection(current_info->mpd.host,
current_info->mpd.port, 10);
}
if (strlen(current_info->mpd.password) > 1) {
mpd_sendPasswordCommand(current_info->conn,
@@ -90,67 +101,74 @@ void *update_mpd(void)
timed_thread_lock(mpd_timed_thread);
if (current_info->conn->error || current_info->conn == NULL) {
//ERR("%MPD error: s\n", current_info->conn->errorStr);
// ERR("%MPD error: s\n", current_info->conn->errorStr);
mpd_closeConnection(current_info->conn);
current_info->conn = 0;
clear_mpd_stats(current_info);
strncpy(current_info->mpd.status, "MPD not responding", TEXT_BUFFER_SIZE - 1);
strncpy(current_info->mpd.status, "MPD not responding",
TEXT_BUFFER_SIZE - 1);
timed_thread_unlock(mpd_timed_thread);
if (timed_thread_test(mpd_timed_thread)) timed_thread_exit(mpd_timed_thread);
if (timed_thread_test(mpd_timed_thread)) {
timed_thread_exit(mpd_timed_thread);
}
continue;
}
mpd_Status *status;
mpd_InfoEntity *entity;
mpd_sendStatusCommand(current_info->conn);
if ((status = mpd_getStatus(current_info->conn)) == NULL) {
//ERR("MPD error: %s\n", current_info->conn->errorStr);
// ERR("MPD error: %s\n", current_info->conn->errorStr);
mpd_closeConnection(current_info->conn);
current_info->conn = 0;
clear_mpd_stats(current_info);
strncpy(current_info->mpd.status, "MPD not responding", TEXT_BUFFER_SIZE - 1);
strncpy(current_info->mpd.status, "MPD not responding",
TEXT_BUFFER_SIZE - 1);
timed_thread_unlock(mpd_timed_thread);
if (timed_thread_test(mpd_timed_thread)) timed_thread_exit(mpd_timed_thread);
if (timed_thread_test(mpd_timed_thread)) {
timed_thread_exit(mpd_timed_thread);
}
continue;
}
mpd_finishCommand(current_info->conn);
if (current_info->conn->error) {
//fprintf(stderr, "%s\n", current_info->conn->errorStr);
// fprintf(stderr, "%s\n", current_info->conn->errorStr);
mpd_closeConnection(current_info->conn);
current_info->conn = 0;
timed_thread_unlock(mpd_timed_thread);
if (timed_thread_test(mpd_timed_thread)) timed_thread_exit(mpd_timed_thread);
if (timed_thread_test(mpd_timed_thread)) {
timed_thread_exit(mpd_timed_thread);
}
continue;
}
current_info->mpd.volume = status->volume;
//if (status->error)
//printf("error: %s\n", status->error);
/* if (status->error) {
printf("error: %s\n", status->error);
} */
if (status->state == MPD_STATUS_STATE_PLAY) {
strncpy(current_info->mpd.status, "Playing",
TEXT_BUFFER_SIZE - 1);
strncpy(current_info->mpd.status, "Playing", TEXT_BUFFER_SIZE - 1);
}
if (status->state == MPD_STATUS_STATE_STOP) {
clear_mpd_stats(current_info);
strncpy(current_info->mpd.status, "Stopped",
TEXT_BUFFER_SIZE - 1);
strncpy(current_info->mpd.status, "Stopped", TEXT_BUFFER_SIZE - 1);
}
if (status->state == MPD_STATUS_STATE_PAUSE) {
strncpy(current_info->mpd.status, "Paused",
TEXT_BUFFER_SIZE - 1);
strncpy(current_info->mpd.status, "Paused", TEXT_BUFFER_SIZE - 1);
}
if (status->state == MPD_STATUS_STATE_UNKNOWN) {
clear_mpd_stats(current_info);
*current_info->mpd.status=0;
*current_info->mpd.status = 0;
}
if (status->state == MPD_STATUS_STATE_PLAY ||
status->state == MPD_STATUS_STATE_PAUSE) {
if (status->state == MPD_STATUS_STATE_PLAY
|| status->state == MPD_STATUS_STATE_PAUSE) {
current_info->mpd.bitrate = status->bitRate;
current_info->mpd.progress =
(float) status->elapsedTime / status->totalTime;
current_info->mpd.progress = (float) status->elapsedTime /
status->totalTime;
current_info->mpd.elapsed = status->elapsedTime;
current_info->mpd.length = status->totalTime;
if (status->random == 0) {
@@ -158,29 +176,32 @@ void *update_mpd(void)
} else if (status->random == 1) {
strcpy(current_info->mpd.random, "On");
} else {
*current_info->mpd.random=0;
*current_info->mpd.random = 0;
}
if (status->repeat == 0) {
strcpy(current_info->mpd.repeat, "Off");
} else if (status->repeat == 1) {
strcpy(current_info->mpd.repeat, "On");
} else {
*current_info->mpd.repeat=0;
*current_info->mpd.repeat = 0;
}
}
if (current_info->conn->error) {
//fprintf(stderr, "%s\n", current_info->conn->errorStr);
// fprintf(stderr, "%s\n", current_info->conn->errorStr);
mpd_closeConnection(current_info->conn);
current_info->conn = 0;
timed_thread_unlock(mpd_timed_thread);
if (timed_thread_test(mpd_timed_thread)) timed_thread_exit(mpd_timed_thread);
if (timed_thread_test(mpd_timed_thread)) {
timed_thread_exit(mpd_timed_thread);
}
continue;
}
mpd_sendCurrentSongCommand(current_info->conn);
while ((entity = mpd_getNextInfoEntity(current_info->conn))) {
mpd_Song *song = entity->info.song;
if (entity->type != MPD_INFO_ENTITY_TYPE_SONG) {
mpd_freeInfoEntity(entity);
continue;
@@ -190,37 +211,37 @@ void *update_mpd(void)
strncpy(current_info->mpd.artist, song->artist,
TEXT_BUFFER_SIZE - 1);
} else {
*current_info->mpd.artist=0;
*current_info->mpd.artist = 0;
}
if (song->album) {
strncpy(current_info->mpd.album, song->album,
TEXT_BUFFER_SIZE - 1);
} else {
*current_info->mpd.album=0;
*current_info->mpd.album = 0;
}
if (song->title) {
strncpy(current_info->mpd.title, song->title,
TEXT_BUFFER_SIZE - 1);
} else {
*current_info->mpd.title=0;
*current_info->mpd.title = 0;
}
if (song->track) {
strncpy(current_info->mpd.track, song->track,
TEXT_BUFFER_SIZE - 1);
} else {
*current_info->mpd.track=0;
*current_info->mpd.track = 0;
}
if (song->name) {
strncpy(current_info->mpd.name, song->name,
TEXT_BUFFER_SIZE - 1);
} else {
*current_info->mpd.name=0;
*current_info->mpd.name = 0;
}
if (song->file) {
strncpy(current_info->mpd.file,
song->file, TEXT_BUFFER_SIZE - 1);
strncpy(current_info->mpd.file, song->file,
TEXT_BUFFER_SIZE - 1);
} else {
*current_info->mpd.file=0;
*current_info->mpd.file = 0;
}
if (entity != NULL) {
mpd_freeInfoEntity(entity);
@@ -233,29 +254,35 @@ void *update_mpd(void)
}
mpd_finishCommand(current_info->conn);
if (current_info->conn->error) {
//fprintf(stderr, "%s\n", current_info->conn->errorStr);
// fprintf(stderr, "%s\n", current_info->conn->errorStr);
mpd_closeConnection(current_info->conn);
current_info->conn = 0;
timed_thread_unlock(mpd_timed_thread);
if (timed_thread_test(mpd_timed_thread)) timed_thread_exit(mpd_timed_thread);
if (timed_thread_test(mpd_timed_thread)) {
timed_thread_exit(mpd_timed_thread);
}
continue;
}
timed_thread_unlock(mpd_timed_thread);
if (current_info->conn->error) {
//fprintf(stderr, "%s\n", current_info->conn->errorStr);
// fprintf(stderr, "%s\n", current_info->conn->errorStr);
mpd_closeConnection(current_info->conn);
current_info->conn = 0;
if (timed_thread_test(mpd_timed_thread)) timed_thread_exit(mpd_timed_thread);
if (timed_thread_test(mpd_timed_thread)) {
timed_thread_exit(mpd_timed_thread);
}
continue;
}
mpd_freeStatus(status);
/* if (current_info->conn) {
/* if (current_info->conn) {
mpd_closeConnection(current_info->conn);
current_info->conn = 0;
}*/
if (timed_thread_test(mpd_timed_thread)) timed_thread_exit(mpd_timed_thread);
} */
if (timed_thread_test(mpd_timed_thread)) {
timed_thread_exit(mpd_timed_thread);
}
continue;
}
return 0;

View File

@@ -1,5 +1,4 @@
/*
* Conky, a system monitor, based on torsmo
/* Conky, a system monitor, based on torsmo
*
* Any original torsmo code is licensed under the BSD license
*
@@ -8,7 +7,8 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*/
* $Id$ */
#include <stdio.h>
#include <stdlib.h>
@@ -57,7 +56,6 @@
#include "conky.h"
static kvm_t *kd = NULL;
int kd_init = 0, nkd_init = 0;
u_int32_t sensvalue;
@@ -65,12 +63,13 @@ char errbuf[_POSIX2_LINE_MAX];
static int init_kvm(void)
{
if (kd_init)
if (kd_init) {
return 0;
}
kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf);
if (kd == NULL) {
(void) warnx("cannot kvm_openfiles: %s", errbuf);
warnx("cannot kvm_openfiles: %s", errbuf);
return -1;
}
kd_init = 1;
@@ -88,25 +87,24 @@ static int swapmode(int *retavail, int *retfree)
n = swapctl(SWAP_NSWAP, 0, 0);
if (n < 1) {
(void) warn("could not get swap information");
warn("could not get swap information");
return 0;
}
sep = (struct swapent *) malloc(n * (sizeof(*sep)));
if (sep == NULL) {
(void) warn("memory allocation failed");
warn("memory allocation failed");
return 0;
}
if (swapctl(SWAP_STATS, (void *) sep, n) < n) {
(void) warn("could not get swap stats");
warn("could not get swap stats");
return 0;
}
for (; n > 0; n--) {
*retavail += (int) dbtob(sep[n - 1].se_nblks);
*retfree +=
(int) dbtob(sep[n - 1].se_nblks - sep[n - 1].se_inuse);
*retfree += (int) dbtob(sep[n - 1].se_nblks - sep[n - 1].se_inuse);
}
*retavail = (int) (*retavail / 1024);
*retfree = (int) (*retfree / 1024);
@@ -114,7 +112,6 @@ static int swapmode(int *retavail, int *retfree)
return 1;
}
void prepare_update()
{
}
@@ -128,10 +125,10 @@ void update_uptime()
if ((sysctl(mib, 2, &boottime, &size, NULL, 0) != -1)
&& (boottime.tv_sec != 0)) {
(void) time(&now);
time(&now);
info.uptime = now - boottime.tv_sec;
} else {
(void) warn("could not get uptime");
warn("could not get uptime");
info.uptime = 0;
}
}
@@ -154,7 +151,6 @@ void update_meminfo()
info.memmax = info.mem = 0;
info.swapmax = info.swap = 0;
if (sysctl(mib, 2, &uvmexp, &size, NULL, 0) < 0) {
warn("could not get memory info");
return;
@@ -165,8 +161,7 @@ void update_meminfo()
inactive_pages = uvmexp.inactive;
info.memmax = (total_pages * pagesize) >> 10;
info.mem =
((total_pages - free_pages - inactive_pages) * pagesize) >> 10;
info.mem = ((total_pages - free_pages - inactive_pages) * pagesize) >> 10;
if (swapmode(&swap_avail, &swap_free) >= 0) {
info.swapmax = swap_avail;
@@ -182,36 +177,36 @@ void update_net_stats()
struct ifnet_head ifhead; /* interfaces are in a tail queue */
u_long ifnetaddr;
static struct nlist namelist[] = {
{"_ifnet"},
{NULL},
{ "_ifnet" },
{ NULL }
};
static kvm_t *nkd;
if (!nkd_init) {
nkd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
if (nkd == NULL) {
(void) warnx("cannot kvm_openfiles: %s", errbuf);
(void)
warnx
("maybe you need to setgid kmem this program?");
warnx("cannot kvm_openfiles: %s", errbuf);
warnx("maybe you need to setgid kmem this program?");
return;
} else if (kvm_nlist(nkd, namelist) != 0) {
(void) warn("cannot kvm_nlist");
warn("cannot kvm_nlist");
return;
} else
} else {
nkd_init = 1;
}
}
if (kvm_read(nkd, (u_long) namelist[0].n_value, (void *) &ifhead,
sizeof(ifhead)) < 0) {
(void) warn("cannot kvm_read");
warn("cannot kvm_read");
return;
}
/* get delta */
delta = current_update_time - last_update_time;
if (delta <= 0.0001)
if (delta <= 0.0001) {
return;
}
for (i = 0, ifnetaddr = (u_long) ifhead.tqh_first;
ifnet.if_list.tqe_next && i < 16;
@@ -220,29 +215,27 @@ void update_net_stats()
struct net_stat *ns;
long long last_recv, last_trans;
(void) kvm_read(nkd, (u_long) ifnetaddr, (void *) &ifnet,
sizeof(ifnet));
kvm_read(nkd, (u_long) ifnetaddr, (void *) &ifnet, sizeof(ifnet));
ns = get_net_stat(ifnet.if_xname);
ns->up = 1;
last_recv = ns->recv;
last_trans = ns->trans;
if (ifnet.if_ibytes < ns->last_read_recv)
ns->recv +=
((long long) 4294967295U -
ns->last_read_recv) + ifnet.if_ibytes;
else
if (ifnet.if_ibytes < ns->last_read_recv) {
ns->recv += ((long long) 4294967295U - ns->last_read_recv) +
ifnet.if_ibytes;
} else {
ns->recv += (ifnet.if_ibytes - ns->last_read_recv);
}
ns->last_read_recv = ifnet.if_ibytes;
if (ifnet.if_obytes < ns->last_read_trans)
ns->trans +=
((long long) 4294967295U -
ns->last_read_trans) + ifnet.if_obytes;
else
ns->trans +=
(ifnet.if_obytes - ns->last_read_trans);
if (ifnet.if_obytes < ns->last_read_trans) {
ns->trans += ((long long) 4294967295U - ns->last_read_trans) +
ifnet.if_obytes;
} else {
ns->trans += (ifnet.if_obytes - ns->last_read_trans);
}
ns->last_read_trans = ifnet.if_obytes;
@@ -264,11 +257,12 @@ void update_total_processes()
info.procs = 0;
if (init_kvm() < 0)
if (init_kvm() < 0) {
return;
else
kvm_getproc2(kd, KERN_PROC_ALL, 0,
sizeof(struct kinfo_proc2), &n_processes);
} else {
kvm_getproc2(kd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2),
&n_processes);
}
info.procs = n_processes;
}
@@ -281,16 +275,18 @@ void update_running_processes()
info.run_procs = 0;
if (init_kvm() < 0)
if (init_kvm() < 0) {
return;
else {
p = kvm_getproc2(kd, KERN_PROC_ALL, 0,
sizeof(struct kinfo_proc2), &n_processes);
for (i = 0; i < n_processes; i++)
if (p[i].p_stat == LSRUN || p[i].p_stat == LSIDL ||
p[i].p_stat == LSONPROC)
} else {
p = kvm_getproc2(kd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2),
&n_processes);
for (i = 0; i < n_processes; i++) {
if (p[i].p_stat == LSRUN || p[i].p_stat == LSIDL
|| p[i].p_stat == LSONPROC) {
cnt++;
}
}
}
info.run_procs = cnt;
}
@@ -313,9 +309,9 @@ void update_cpu_usage()
info.cpu_usage = 0;
if (sysctlbyname("kern.cp_time", &cp_time, &len, NULL, 0) < 0)
(void) warn("cannot get kern.cp_time");
if (sysctlbyname("kern.cp_time", &cp_time, &len, NULL, 0) < 0) {
warn("cannot get kern.cp_time");
}
fresh.load[0] = cp_time[CP_USER];
fresh.load[1] = cp_time[CP_NICE];
@@ -324,19 +320,17 @@ void update_cpu_usage()
fresh.load[4] = cp_time[CP_IDLE];
used = fresh.load[0] + fresh.load[1] + fresh.load[2];
total =
fresh.load[0] + fresh.load[1] + fresh.load[2] + fresh.load[3];
total = fresh.load[0] + fresh.load[1] + fresh.load[2] + fresh.load[3];
if ((total - oldtotal) != 0)
info.cpu_usage =
((double) (used - oldused)) / (double) (total -
oldtotal);
else
if ((total - oldtotal) != 0) {
info.cpu_usage = ((double) (used - oldused)) /
(double) (total - oldtotal);
} else {
info.cpu_usage = 0;
}
oldused = used;
oldtotal = total;
}
double get_sysfs_info(int *fd, int div, char *devtype)
@@ -347,6 +341,7 @@ double get_sysfs_info(int *fd, int div, char *devtype)
void update_load_average()
{
double v[3];
getloadavg(v, 3);
info.loadavg[0] = (float) v[0];
@@ -363,8 +358,8 @@ void get_battery_stuff(char *buf, unsigned int n, const char *bat, int item)
{
}
int
open_sysfs_sensor(const char *dir, const char *dev, const char *type, int n, int *div, char *devtype)
int open_sysfs_sensor(const char *dir, const char *dev, const char *type, int n,
int *div, char *devtype)
{
return -1;
}
@@ -374,29 +369,27 @@ int open_acpi_temperature(const char *name)
return -1;
}
void get_acpi_ac_adapter( char * p_client_buffer, size_t client_buffer_size )
void get_acpi_ac_adapter(char *p_client_buffer, size_t client_buffer_size)
{
if ( !p_client_buffer || client_buffer_size <= 0 )
if (!p_client_buffer || client_buffer_size <= 0) {
return;
}
/* not implemented */
memset(p_client_buffer,0,client_buffer_size);
return;
memset(p_client_buffer, 0, client_buffer_size);
}
/*char *get_acpi_fan()*/
void get_acpi_fan( char * p_client_buffer, size_t client_buffer_size )
/* char *get_acpi_fan() */
void get_acpi_fan(char *p_client_buffer, size_t client_buffer_size)
{
if ( !p_client_buffer || client_buffer_size <= 0 )
if (!p_client_buffer || client_buffer_size <= 0) {
return;
}
/* not implemented */
memset(p_client_buffer,0,client_buffer_size);
return;
memset(p_client_buffer, 0, client_buffer_size);
}
void update_entropy (void)
void update_entropy(void)
{
}

View File

@@ -1,5 +1,4 @@
/*
* Conky, a system monitor, based on torsmo
/* Conky, a system monitor, based on torsmo
*
* Any original torsmo code is licensed under the BSD license
*
@@ -8,7 +7,8 @@
* Please see COPYING for details
*
* Copyright (c) 2007 Toni Spets
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*/
* $Id$ */
#include <sys/dkstat.h>
#include <sys/param.h>
@@ -79,39 +78,42 @@ int init_sensors = 0;
static int kvm_init()
{
if(init_kvm)
if (init_kvm) {
return 1;
}
kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, NULL);
if(kd == NULL)
if (kd == NULL) {
ERR("error opening kvm");
else init_kvm = 1;
} else {
init_kvm = 1;
}
return 1;
}
/* note: swapmode taken from 'top' source */
/*
* swapmode is rewritten by Tobias Weingartner <weingart@openbsd.org>
* to be based on the new swapctl(2) system call.
*/
static int
swapmode(int *used, int *total)
/* swapmode is rewritten by Tobias Weingartner <weingart@openbsd.org>
* to be based on the new swapctl(2) system call. */
static int swapmode(int *used, int *total)
{
struct swapent *swdev;
int nswap, rnswap, i;
nswap = swapctl(SWAP_NSWAP, 0, 0);
if (nswap == 0)
if (nswap == 0) {
return 0;
}
swdev = malloc(nswap * sizeof(*swdev));
if (swdev == NULL)
if (swdev == NULL) {
return 0;
}
rnswap = swapctl(SWAP_STATS, swdev, nswap);
if (rnswap == -1)
if (rnswap == -1) {
return 0;
}
/* if rnswap != nswap, then what? */
@@ -133,16 +135,15 @@ int check_mount(char *s)
return 0;
}
void
update_uptime()
void update_uptime()
{
int mib[2] = { CTL_KERN, KERN_BOOTTIME };
struct timeval boottime;
time_t now;
size_t size = sizeof (boottime);
size_t size = sizeof(boottime);
if ((sysctl(mib, 2, &boottime, &size, NULL, 0) != -1) &&
(boottime.tv_sec != 0)) {
if ((sysctl(mib, 2, &boottime, &size, NULL, 0) != -1)
&& (boottime.tv_sec != 0)) {
time(&now);
info.uptime = now - boottime.tv_sec;
} else {
@@ -151,10 +152,9 @@ update_uptime()
}
}
void
update_meminfo()
void update_meminfo()
{
static int mib[2] = {CTL_VM, VM_METER};
static int mib[2] = { CTL_VM, VM_METER };
struct vmtotal vmtotal;
size_t size;
int pagesize, pageshift, swap_avail, swap_used;
@@ -188,8 +188,7 @@ update_meminfo()
}
}
void
update_net_stats()
void update_net_stats()
{
struct net_stat *ns;
double delta;
@@ -197,14 +196,15 @@ update_net_stats()
struct ifaddrs *ifap, *ifa;
struct if_data *ifd;
/* get delta */
delta = current_update_time - last_update_time;
if (delta <= 0.0001)
if (delta <= 0.0001) {
return;
}
if (getifaddrs(&ifap) < 0)
if (getifaddrs(&ifap) < 0) {
return;
}
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
ns = get_net_stat((const char *) ifa->ifa_name);
@@ -216,35 +216,36 @@ update_net_stats()
last_recv = ns->recv;
last_trans = ns->trans;
if (ifa->ifa_addr->sa_family != AF_LINK)
if (ifa->ifa_addr->sa_family != AF_LINK) {
continue;
}
for (iftmp = ifa->ifa_next; iftmp != NULL &&
strcmp(ifa->ifa_name, iftmp->ifa_name) == 0;
iftmp = iftmp->ifa_next)
if (iftmp->ifa_addr->sa_family == AF_INET)
for (iftmp = ifa->ifa_next;
iftmp != NULL && strcmp(ifa->ifa_name, iftmp->ifa_name) == 0;
iftmp = iftmp->ifa_next) {
if (iftmp->ifa_addr->sa_family == AF_INET) {
memcpy(&(ns->addr), iftmp->ifa_addr,
iftmp->ifa_addr->sa_len);
}
}
ifd = (struct if_data *) ifa->ifa_data;
r = ifd->ifi_ibytes;
t = ifd->ifi_obytes;
if (r < ns->last_read_recv)
ns->recv +=
((long long) 4294967295U -
ns->last_read_recv) + r;
else
if (r < ns->last_read_recv) {
ns->recv += ((long long) 4294967295U - ns->last_read_recv) + r;
} else {
ns->recv += (r - ns->last_read_recv);
}
ns->last_read_recv = r;
if (t < ns->last_read_trans)
ns->trans +=
((long long) 4294967295U -
ns->last_read_trans) + t;
else
if (t < ns->last_read_trans) {
ns->trans += (long long) 4294967295U - ns->last_read_trans + t;
} else {
ns->trans += (t - ns->last_read_trans);
}
ns->last_read_trans = t;
@@ -259,8 +260,7 @@ update_net_stats()
freeifaddrs(ifap);
}
void
update_total_processes()
void update_total_processes()
{
int n_processes;
@@ -270,8 +270,7 @@ update_total_processes()
info.procs = n_processes;
}
void
update_running_processes()
void update_running_processes()
{
struct kinfo_proc2 *p;
int n_processes;
@@ -279,11 +278,13 @@ update_running_processes()
kvm_init();
int max_size = sizeof(struct kinfo_proc2);
p = kvm_getproc2(kd, KERN_PROC_ALL, 0, max_size, &n_processes);
for (i = 0; i < n_processes; i++) {
if (p[i].p_stat == SRUN)
if (p[i].p_stat == SRUN) {
cnt++;
}
}
info.run_procs = cnt;
}
@@ -300,44 +301,47 @@ struct cpu_load_struct fresh = { {0, 0, 0, 0, 0} };
long cpu_used, oldtotal, oldused;
#else
#include <assert.h>
int64_t* fresh = NULL;
/* XXX is 8 enough? - What's the constant for MAXCPU?*/
/* allocate this with malloc would be better*/
int64_t *fresh = NULL;
/* XXX is 8 enough? - What's the constant for MAXCPU? */
/* allocate this with malloc would be better */
int64_t oldtotal[8], oldused[8];
#endif
void
get_cpu_count()
void get_cpu_count()
{
int cpu_count = 1; /* default to 1 cpu */
#ifndef OLDCPU
int mib[2] = { CTL_HW, HW_NCPU };
size_t len = sizeof(cpu_count);
if(sysctl(mib, 2, &cpu_count, &len, NULL, 0) != 0)
if (sysctl(mib, 2, &cpu_count, &len, NULL, 0) != 0) {
ERR("error getting cpu count, defaulting to 1");
}
#endif
info.cpu_count = cpu_count;
info.cpu_usage = malloc(info.cpu_count * sizeof (float));
if (info.cpu_usage == NULL)
info.cpu_usage = malloc(info.cpu_count * sizeof(float));
if (info.cpu_usage == NULL) {
CRIT_ERR("malloc");
}
#ifndef OLDCPU
assert(fresh == NULL); /* XXX Is this leaking memory?*/
/* XXX Where shall I free this?*/
if (NULL == (fresh = calloc(cpu_count, sizeof(int64_t) * CPUSTATES)))
assert(fresh == NULL); /* XXX Is this leaking memory? */
/* XXX Where shall I free this? */
if (NULL == (fresh = calloc(cpu_count, sizeof(int64_t) * CPUSTATES))) {
CRIT_ERR("calloc");
}
#endif
}
void
update_cpu_usage()
void update_cpu_usage()
{
#ifdef OLDCPU
int mib[2] = { CTL_KERN, KERN_CPTIME };
long used, total;
long cp_time[CPUSTATES];
size_t len = sizeof (cp_time);
size_t len = sizeof(cp_time);
#else
size_t size;
unsigned int i;
@@ -361,8 +365,7 @@ update_cpu_usage()
fresh.load[4] = cp_time[CP_IDLE];
used = fresh.load[0] + fresh.load[1] + fresh.load[2];
total =
fresh.load[0] + fresh.load[1] + fresh.load[2] + fresh.load[3];
total = fresh.load[0] + fresh.load[1] + fresh.load[2] + fresh.load[3];
if ((total - oldtotal) != 0) {
info.cpu_usage[0] = ((double) (used - oldused)) /
@@ -377,23 +380,27 @@ update_cpu_usage()
if (info.cpu_count > 1) {
size = CPUSTATES * sizeof(int64_t);
for (i = 0; i < info.cpu_count; i++) {
int cp_time_mib[] = {CTL_KERN, KERN_CPTIME2, i};
if (sysctl(cp_time_mib, 3, &(fresh[i * CPUSTATES]), &size, NULL, 0) < 0)
int cp_time_mib[] = { CTL_KERN, KERN_CPTIME2, i };
if (sysctl(cp_time_mib, 3, &(fresh[i * CPUSTATES]), &size, NULL, 0)
< 0) {
ERR("sysctl kern.cp_time2 failed");
}
}
} else {
int cp_time_mib[] = {CTL_KERN, KERN_CPTIME};
int cp_time_mib[] = { CTL_KERN, KERN_CPTIME };
long cp_time_tmp[CPUSTATES];
size = sizeof(cp_time_tmp);
if (sysctl(cp_time_mib, 2, cp_time_tmp, &size, NULL, 0) < 0)
if (sysctl(cp_time_mib, 2, cp_time_tmp, &size, NULL, 0) < 0) {
ERR("sysctl kern.cp_time failed");
for (i = 0; i < CPUSTATES; i++)
fresh[i] = (int64_t)cp_time_tmp[i];
}
/* XXX Do sg with this int64_t => long => double ? float hell.*/
for (i = 0; i < CPUSTATES; i++) {
fresh[i] = (int64_t) cp_time_tmp[i];
}
}
/* XXX Do sg with this int64_t => long => double ? float hell. */
for (i = 0; i < info.cpu_count; i++) {
int64_t used, total;
int at = i * CPUSTATES;
@@ -414,10 +421,10 @@ update_cpu_usage()
#endif
}
void
update_load_average()
void update_load_average()
{
double v[3];
getloadavg(v, 3);
info.loadavg[0] = (float) v[0];
@@ -431,7 +438,7 @@ void update_obsd_sensors()
int sensor_cnt, dev, numt, mib[5] = { CTL_HW, HW_SENSORS, 0, 0, 0 };
struct sensor sensor;
struct sensordev sensordev;
size_t slen,sdlen;
size_t slen, sdlen;
enum sensor_type type;
slen = sizeof(sensor);
@@ -443,34 +450,38 @@ void update_obsd_sensors()
/* for (dev = 0; dev < MAXSENSORDEVICES; dev++) { */
mib[2] = dev;
if(sysctl(mib, 3, &sensordev, &sdlen, NULL, 0) == -1) {
if (errno != ENOENT)
if (sysctl(mib, 3, &sensordev, &sdlen, NULL, 0) == -1) {
if (errno != ENOENT) {
warn("sysctl");
}
return;
//continue;
// continue;
}
for (type = 0; type < SENSOR_MAX_TYPES; type++) {
mib[3] = type;
for (numt = 0; numt < sensordev.maxnumt[type]; numt++) {
mib[4] = numt;
if (sysctl(mib, 5, &sensor, &slen, NULL, 0)
== -1) {
if (errno != ENOENT)
if (sysctl(mib, 5, &sensor, &slen, NULL, 0) == -1) {
if (errno != ENOENT) {
warn("sysctl");
}
continue;
}
if (sensor.flags & SENSOR_FINVALID)
if (sensor.flags & SENSOR_FINVALID) {
continue;
}
switch (type) {
case SENSOR_TEMP:
obsd_sensors.temp[dev][sensor.numt] = (sensor.value - 273150000) / 1000000.0;
obsd_sensors.temp[dev][sensor.numt] =
(sensor.value - 273150000) / 1000000.0;
break;
case SENSOR_FANRPM:
obsd_sensors.fan[dev][sensor.numt] = sensor.value;
break;
case SENSOR_VOLTS_DC:
obsd_sensors.volt[dev][sensor.numt] = sensor.value/1000000.0;
obsd_sensors.volt[dev][sensor.numt] =
sensor.value / 1000000.0;
break;
default:
break;
@@ -488,11 +499,13 @@ void update_obsd_sensors()
void get_obsd_vendor(char *buf, size_t client_buffer_size)
{
int mib[2];
mib[0] = CTL_HW;
mib[1] = HW_VENDOR;
char vendor[64];
size_t size = sizeof(vendor);
if(sysctl(mib, 2, vendor, &size, NULL, 0) == -1) {
if (sysctl(mib, 2, vendor, &size, NULL, 0) == -1) {
ERR("error reading vendor");
snprintf(buf, client_buffer_size, "unknown");
} else {
@@ -504,11 +517,13 @@ void get_obsd_vendor(char *buf, size_t client_buffer_size)
void get_obsd_product(char *buf, size_t client_buffer_size)
{
int mib[2];
mib[0] = CTL_HW;
mib[1] = HW_PRODUCT;
char product[64];
size_t size = sizeof(product);
if(sysctl(mib, 2, product, &size, NULL, 0) == -1) {
if (sysctl(mib, 2, product, &size, NULL, 0) == -1) {
ERR("error reading product");
snprintf(buf, client_buffer_size, "unknown");
} else {
@@ -519,18 +534,17 @@ void get_obsd_product(char *buf, size_t client_buffer_size)
/* rdtsc() and get_freq_dynamic() copied from linux.c */
#if defined(__i386) || defined(__x86_64)
__inline__ unsigned long long int
rdtsc()
__inline__ unsigned long long int rdtsc()
{
unsigned long long int x;
__asm__ volatile(".byte 0x0f, 0x31":"=A" (x));
return (x);
return x;
}
#endif
/* return system frequency in MHz (use divisor=1) or GHz (use divisor=1000) */
void
get_freq_dynamic(char *p_client_buffer, size_t client_buffer_size,
void get_freq_dynamic(char *p_client_buffer, size_t client_buffer_size,
char *p_format, int divisor)
{
#if defined(__i386) || defined(__x86_64)
@@ -539,7 +553,7 @@ get_freq_dynamic(char *p_client_buffer, size_t client_buffer_size,
unsigned long long cycles[2]; /* gotta be 64 bit */
unsigned int microseconds; /* total time taken */
memset(&tz, 0, sizeof (tz));
memset(&tz, 0, sizeof(tz));
/* get this function in cached memory */
gettimeofday(&tvstart, &tz);
@@ -554,57 +568,56 @@ get_freq_dynamic(char *p_client_buffer, size_t client_buffer_size,
(tvstop.tv_usec - tvstart.tv_usec);
snprintf(p_client_buffer, client_buffer_size, p_format,
(float)((cycles[1] - cycles[0]) / microseconds) / divisor);
(float) ((cycles[1] - cycles[0]) / microseconds) / divisor);
#else
get_freq(p_client_buffer, client_buffer_size, p_format, divisor, 1);
#endif
}
/*void*/
char
get_freq(char *p_client_buffer, size_t client_buffer_size,
char *p_format, int divisor, unsigned int cpu)
/* void */
char get_freq(char *p_client_buffer, size_t client_buffer_size, char *p_format,
int divisor, unsigned int cpu)
{
int freq = cpu;
int mib[2] = { CTL_HW, HW_CPUSPEED };
if (!p_client_buffer || client_buffer_size <= 0 ||
!p_format || divisor <= 0)
if (!p_client_buffer || client_buffer_size <= 0 || !p_format
|| divisor <= 0) {
return 0;
}
size_t size = sizeof(freq);
if(sysctl(mib, 2, &freq, &size, NULL, 0) == 0)
snprintf(p_client_buffer, client_buffer_size,
p_format, (float)freq/divisor);
else
if (sysctl(mib, 2, &freq, &size, NULL, 0) == 0) {
snprintf(p_client_buffer, client_buffer_size, p_format,
(float) freq / divisor);
} else {
snprintf(p_client_buffer, client_buffer_size, p_format, 0.0f);
}
return 1;
}
void
update_top()
void update_top()
{
proc_find_top(info.cpu, info.memu);
}
#if 0
/* deprecated, will rewrite this soon in update_net_stats() -hifi */
void
update_wifi_stats()
void update_wifi_stats()
{
struct net_stat * ns;
struct net_stat *ns;
struct ifaddrs *ifap, *ifa;
struct ifmediareq ifmr;
struct ieee80211_nodereq nr;
struct ieee80211_bssid bssid;
int s,ibssid;
int s, ibssid;
/*
* Get iface table
*/
if (getifaddrs(&ifap) < 0)
/* Get iface table */
if (getifaddrs(&ifap) < 0) {
return;
}
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
ns = get_net_stat((const char *) ifa->ifa_name);
@@ -614,15 +627,14 @@ update_wifi_stats()
/* Get media type */
bzero(&ifmr, sizeof(ifmr));
strlcpy(ifmr.ifm_name, ifa->ifa_name, IFNAMSIZ);
if (ioctl(s, SIOCGIFMEDIA, (caddr_t) &ifmr) < 0)
if (ioctl(s, SIOCGIFMEDIA, (caddr_t) &ifmr) < 0) {
goto cleanup;
}
/*
* We can monitor only wireless interfaces
* which not in hostap mode
*/
if ((ifmr.ifm_active & IFM_IEEE80211) &&
!(ifmr.ifm_active & IFM_IEEE80211_HOSTAP)) {
/* We can monitor only wireless interfaces
* which are not in hostap mode */
if ((ifmr.ifm_active & IFM_IEEE80211)
&& !(ifmr.ifm_active & IFM_IEEE80211_HOSTAP)) {
/* Get wi status */
memset(&bssid, 0, sizeof(bssid));
@@ -633,51 +645,50 @@ update_wifi_stats()
bcopy(bssid.i_bssid, &nr.nr_macaddr, sizeof(nr.nr_macaddr));
strlcpy(nr.nr_ifname, ifa->ifa_name, sizeof(nr.nr_ifname));
if (ioctl(s, SIOCG80211NODE, &nr) == 0 && nr.nr_rssi)
if (ioctl(s, SIOCG80211NODE, &nr) == 0 && nr.nr_rssi) {
ns->linkstatus = nr.nr_rssi;
}
}
cleanup:
close(s);
}
}
#endif
void
update_diskio()
void update_diskio()
{
return; /* XXX implement? hifi: not sure how */
return; /* XXX: implement? hifi: not sure how */
}
/*
* While topless is obviously better, top is also not bad.
*/
/* While topless is obviously better, top is also not bad. */
int
comparecpu(const void *a, const void *b)
int comparecpu(const void *a, const void *b)
{
if (((struct process *)a)->amount > ((struct process *)b)->amount)
return (-1);
if (((struct process *) a)->amount > ((struct process *) b)->amount) {
return -1;
}
if (((struct process *)a)->amount < ((struct process *)b)->amount)
return (1);
if (((struct process *) a)->amount < ((struct process *) b)->amount) {
return 1;
}
return (0);
return 0;
}
int
comparemem(const void *a, const void *b)
int comparemem(const void *a, const void *b)
{
if (((struct process *)a)->totalmem > ((struct process *)b)->totalmem)
return (-1);
if (((struct process *) a)->totalmem > ((struct process *) b)->totalmem) {
return -1;
}
if (((struct process *)a)->totalmem < ((struct process *)b)->totalmem)
return (1);
if (((struct process *) a)->totalmem < ((struct process *) b)->totalmem) {
return 1;
}
return (0);
return 0;
}
inline void
proc_find_top(struct process **cpu, struct process **mem)
inline void proc_find_top(struct process **cpu, struct process **mem)
{
struct kinfo_proc2 *p;
int n_processes;
@@ -692,32 +703,32 @@ proc_find_top(struct process **cpu, struct process **mem)
mib[0] = CTL_HW;
mib[1] = HW_USERMEM;
size_t size = sizeof(total_pages);
if(sysctl(mib, 2, &total_pages, &size, NULL, 0) == -1)
if (sysctl(mib, 2, &total_pages, &size, NULL, 0) == -1) {
ERR("error reading nmempages");
}
int max_size = sizeof(struct kinfo_proc2);
p = kvm_getproc2(kd, KERN_PROC_ALL, 0, max_size, &n_processes);
processes = malloc(n_processes * sizeof (struct process));
p = kvm_getproc2(kd, KERN_PROC_ALL, 0, max_size, &n_processes);
processes = malloc(n_processes * sizeof(struct process));
for (i = 0; i < n_processes; i++) {
if (!((p[i].p_flag & P_SYSTEM)) &&
p[i].p_comm != NULL) {
if (!((p[i].p_flag & P_SYSTEM)) && p[i].p_comm != NULL) {
processes[j].pid = p[i].p_pid;
processes[j].name = strdup(p[i].p_comm);
processes[j].amount = 100.0 *
p[i].p_pctcpu / FSCALE;
processes[j].totalmem = (float)(p[i].p_vm_rssize * pagesize /
(float)total_pages) * 100.0;
processes[j].amount = 100.0 * p[i].p_pctcpu / FSCALE;
processes[j].totalmem = (float) (p[i].p_vm_rssize * pagesize /
(float) total_pages) * 100.0;
j++;
}
}
qsort(processes, j - 1, sizeof (struct process), comparemem);
qsort(processes, j - 1, sizeof(struct process), comparemem);
for (i = 0; i < 10; i++) {
struct process *tmp, *ttmp;
tmp = malloc(sizeof (struct process));
tmp = malloc(sizeof(struct process));
tmp->pid = processes[i].pid;
tmp->amount = processes[i].amount;
tmp->totalmem = processes[i].totalmem;
@@ -731,11 +742,11 @@ proc_find_top(struct process **cpu, struct process **mem)
}
}
qsort(processes, j - 1, sizeof (struct process), comparecpu);
qsort(processes, j - 1, sizeof(struct process), comparecpu);
for (i = 0; i < 10; i++) {
struct process *tmp, *ttmp;
tmp = malloc(sizeof (struct process));
tmp = malloc(sizeof(struct process));
tmp->pid = processes[i].pid;
tmp->amount = processes[i].amount;
tmp->totalmem = processes[i].totalmem;
@@ -749,7 +760,9 @@ proc_find_top(struct process **cpu, struct process **mem)
}
}
for (i = 0; i < j; free(processes[i++].name));
for (i = 0; i < j; i++) {
free(processes[i].name);
}
free(processes);
}
@@ -757,93 +770,91 @@ proc_find_top(struct process **cpu, struct process **mem)
#define APMDEV "/dev/apm"
#define APM_UNKNOWN 255
int
apm_getinfo(int fd, apm_info_t aip)
int apm_getinfo(int fd, apm_info_t aip)
{
if (ioctl(fd, APM_IOC_GETPOWER, aip) == -1)
return (-1);
if (ioctl(fd, APM_IOC_GETPOWER, aip) == -1) {
return -1;
}
return (0);
return 0;
}
char
*get_apm_adapter()
char *get_apm_adapter()
{
int fd;
struct apm_power_info info;
char *out;
out = (char *)calloc(16, sizeof (char));
out = (char *) calloc(16, sizeof(char));
fd = open(APMDEV, O_RDONLY);
if (fd < 0) {
strncpy(out, "ERR", 16);
return (out);
return out;
}
if (apm_getinfo(fd, &info) != 0) {
close(fd);
strncpy(out, "ERR", 16);
return (out);
return out;
}
close(fd);
switch (info.ac_state) {
case APM_AC_OFF:
strncpy(out, "off-line", 16);
return (out);
return out;
break;
case APM_AC_ON:
if (info.battery_state == APM_BATT_CHARGING) {
strncpy(out, "charging", 16);
return (out);
return out;
} else {
strncpy(out, "on-line", 16);
return (out);
return out;
}
break;
default:
strncpy(out, "unknown", 16);
return (out);
return out;
break;
}
}
char
*get_apm_battery_life()
char *get_apm_battery_life()
{
int fd;
u_int batt_life;
struct apm_power_info info;
char *out;
out = (char *)calloc(16, sizeof (char));
out = (char *) calloc(16, sizeof(char));
fd = open(APMDEV, O_RDONLY);
if (fd < 0) {
strncpy(out, "ERR", 16);
return (out);
return out;
}
if (apm_getinfo(fd, &info) != 0) {
close(fd);
strncpy(out, "ERR", 16);
return (out);
return out;
}
close(fd);
batt_life = info.battery_life;
if (batt_life <= 100) {
snprintf(out, 16, "%d%%", batt_life);
return (out);
} else
return out;
} else {
strncpy(out, "ERR", 16);
}
return (out);
return out;
}
char
*get_apm_battery_time()
char *get_apm_battery_time()
{
int fd;
int batt_time;
@@ -851,50 +862,45 @@ char
struct apm_power_info info;
char *out;
out = (char *)calloc(16, sizeof (char));
out = (char *) calloc(16, sizeof(char));
fd = open(APMDEV, O_RDONLY);
if (fd < 0) {
strncpy(out, "ERR", 16);
return (out);
return out;
}
if (apm_getinfo(fd, &info) != 0) {
close(fd);
strncpy(out, "ERR", 16);
return (out);
return out;
}
close(fd);
batt_time = info.minutes_left;
if (batt_time == -1)
if (batt_time == -1) {
strncpy(out, "unknown", 16);
else {
} else {
h = batt_time / 60;
m = batt_time % 60;
snprintf(out, 16, "%2d:%02d", h, m);
}
return (out);
return out;
}
#endif
/* empty stubs so conky links */
void
prepare_update()
void prepare_update()
{
return;
}
void update_entropy (void)
void update_entropy(void)
{
return;
}
void
free_all_processes(void)
void free_all_processes(void)
{
return;
}

View File

@@ -1,5 +1,4 @@
/*
* $Id$
/* $Id$
*
* Copyright (c) 2007 Mikko Sysikaski <mikko.sysikaski@gmail.com>
* Toni Spets <toni.spets@gmail.com>
@@ -14,8 +13,7 @@
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <libxml/parser.h>
#include <libxml/tree.h>
@@ -29,144 +27,165 @@
#define PARSE_OPTIONS 0
#endif
PRSS* prss_parse_doc(xmlDocPtr doc);
PRSS *prss_parse_doc(xmlDocPtr doc);
PRSS* prss_parse_data(const char* xml_data)
PRSS *prss_parse_data(const char *xml_data)
{
xmlDocPtr doc = xmlReadMemory(xml_data, strlen(xml_data), "", NULL, PARSE_OPTIONS);
if (!doc)
xmlDocPtr doc = xmlReadMemory(xml_data, strlen(xml_data), "", NULL,
PARSE_OPTIONS);
if (!doc) {
return NULL;
}
return prss_parse_doc(doc);
}
PRSS* prss_parse_file(const char* xml_file)
PRSS *prss_parse_file(const char *xml_file)
{
xmlDocPtr doc = xmlReadFile(xml_file, NULL, PARSE_OPTIONS);
if (!doc)
if (!doc) {
return NULL;
}
return prss_parse_doc(doc);
}
void prss_free(PRSS* data)
void prss_free(PRSS *data)
{
if (!data)
if (!data) {
return;
}
xmlFreeDoc(data->_data);
free(data->version);
free(data->items);
free(data);
}
static inline void prss_null(PRSS* p)
static inline void prss_null(PRSS *p)
{
memset(p, 0, sizeof(PRSS));
}
static inline void prss_null_item(PRSS_Item* i)
static inline void prss_null_item(PRSS_Item *i)
{
memset(i, 0, sizeof(PRSS_Item));
}
static inline void read_item(PRSS_Item* res, xmlNodePtr data)
static inline void read_item(PRSS_Item *res, xmlNodePtr data)
{
prss_null_item(res);
res->title = res->link = res->description = NULL;
for(; data; data = data->next) {
if (data->type != XML_ELEMENT_NODE)
for (; data; data = data->next) {
if (data->type != XML_ELEMENT_NODE) {
continue;
}
xmlNodePtr child = data->children;
if (!child)
continue;
if (!strcasecmp((char*)data->name, "title")) {
res->title = (char*)child->content;
} else if (!strcasecmp((char*)data->name, "link")) {
res->link = (char*)child->content;
} else if (!strcasecmp((char*)data->name, "description")) {
res->description = (char*)child->content;
} else if (!strcasecmp((char*)data->name, "category")) {
res->category = (char*)child->content;
} else if (!strcasecmp((char*)data->name, "pubDate")) {
res->pubdate = (char*)child->content;
} else if (!strcasecmp((char*)data->name, "guid")) {
res->guid = (char*)child->content;
if (!child) {
continue;
}
if (!strcasecmp((char *) data->name, "title")) {
res->title = (char *) child->content;
} else if (!strcasecmp((char *) data->name, "link")) {
res->link = (char *) child->content;
} else if (!strcasecmp((char *) data->name, "description")) {
res->description = (char *) child->content;
} else if (!strcasecmp((char *) data->name, "category")) {
res->category = (char *) child->content;
} else if (!strcasecmp((char *) data->name, "pubDate")) {
res->pubdate = (char *) child->content;
} else if (!strcasecmp((char *) data->name, "guid")) {
res->guid = (char *) child->content;
}
}
}
static inline void read_element(PRSS* res, xmlNodePtr n)
static inline void read_element(PRSS *res, xmlNodePtr n)
{
if (n->type != XML_ELEMENT_NODE)
if (n->type != XML_ELEMENT_NODE) {
return;
}
xmlNodePtr child = n->children;
if (!child)
return;
if (!strcasecmp((char*)n->name, "title")) {
res->title = (char*)child->content;
} else if (!strcasecmp((char*)n->name, "link")) {
res->link = (char*)child->content;
} else if (!strcasecmp((char*)n->name, "description")) {
res->description = (char*)child->content;
} else if (!strcasecmp((char*)n->name, "language")) {
res->language = (char*)child->content;
} else if (!strcasecmp((char*)n->name, "pubDate")) {
res->pubdate = (char*)child->content;
} else if (!strcasecmp((char*)n->name, "lastBuildDate")) {
res->lastbuilddate = (char*)child->content;
} else if (!strcasecmp((char*)n->name, "generator")) {
res->generator = (char*)child->content;
} else if (!strcasecmp((char*)n->name, "docs")) {
res->docs = (char*)child->content;
} else if (!strcasecmp((char*)n->name, "managingEditor")) {
res->managingeditor = (char*)child->content;
} else if (!strcasecmp((char*)n->name, "webMaster")) {
res->webmaster = (char*)child->content;
} else if (!strcasecmp((char*)n->name, "copyright")) {
res->copyright = (char*)child->content;
} else if (!strcasecmp((char*)n->name, "ttl")) {
res->ttl = (char*)child->content;
} else if (!strcasecmp((char*)n->name, "item")) {
if (!child) {
return;
}
if (!strcasecmp((char *) n->name, "title")) {
res->title = (char *) child->content;
} else if (!strcasecmp((char *) n->name, "link")) {
res->link = (char *) child->content;
} else if (!strcasecmp((char *) n->name, "description")) {
res->description = (char *) child->content;
} else if (!strcasecmp((char *) n->name, "language")) {
res->language = (char *) child->content;
} else if (!strcasecmp((char *) n->name, "pubDate")) {
res->pubdate = (char *) child->content;
} else if (!strcasecmp((char *) n->name, "lastBuildDate")) {
res->lastbuilddate = (char *) child->content;
} else if (!strcasecmp((char *) n->name, "generator")) {
res->generator = (char *) child->content;
} else if (!strcasecmp((char *) n->name, "docs")) {
res->docs = (char *) child->content;
} else if (!strcasecmp((char *) n->name, "managingEditor")) {
res->managingeditor = (char *) child->content;
} else if (!strcasecmp((char *) n->name, "webMaster")) {
res->webmaster = (char *) child->content;
} else if (!strcasecmp((char *) n->name, "copyright")) {
res->copyright = (char *) child->content;
} else if (!strcasecmp((char *) n->name, "ttl")) {
res->ttl = (char *) child->content;
} else if (!strcasecmp((char *) n->name, "item")) {
read_item(&res->items[res->item_count++], n->children);
}
}
static inline int parse_rss_2_0(PRSS* res, xmlNodePtr root)
static inline int parse_rss_2_0(PRSS *res, xmlNodePtr root)
{
xmlNodePtr channel = root->children;
while(channel
&& (channel->type!=XML_ELEMENT_NODE
|| strcmp((char*)channel->name, "channel")))
while (channel && (channel->type != XML_ELEMENT_NODE
|| strcmp((char *) channel->name, "channel"))) {
channel = channel->next;
if (!channel)
}
if (!channel) {
return 0;
}
int items = 0;
xmlNodePtr n;
for(n = channel->children; n; n = n->next)
if (n->type==XML_ELEMENT_NODE && !strcmp((char*)n->name, "item"))
for (n = channel->children; n; n = n->next) {
if (n->type == XML_ELEMENT_NODE && !strcmp((char *) n->name, "item")) {
++items;
}
}
res->version = strdup("2.0");
res->items = malloc(items*sizeof(PRSS_Item));
res->items = malloc(items * sizeof(PRSS_Item));
res->item_count = 0;
for(n = channel->children; n; n = n->next) {
for (n = channel->children; n; n = n->next) {
read_element(res, n);
}
return 1;
}
static inline int parse_rss_1_0(PRSS* res, xmlNodePtr root)
static inline int parse_rss_1_0(PRSS *res, xmlNodePtr root)
{
int items = 0;
xmlNodePtr n;
for(n = root->children; n; n = n->next) {
if (n->type==XML_ELEMENT_NODE) {
if (!strcmp((char*)n->name, "item"))
for (n = root->children; n; n = n->next) {
if (n->type == XML_ELEMENT_NODE) {
if (!strcmp((char *) n->name, "item")) {
++items;
else if (!strcmp((char*)n->name, "channel")) {
} else if (!strcmp((char *) n->name, "channel")) {
xmlNodePtr i;
for(i = n->children; i; i = i->next) {
for (i = n->children; i; i = i->next) {
read_element(res, i);
}
}
@@ -174,33 +193,36 @@ static inline int parse_rss_1_0(PRSS* res, xmlNodePtr root)
}
res->version = strdup("1.0");
res->items = malloc(items*sizeof(PRSS_Item));
res->items = malloc(items * sizeof(PRSS_Item));
res->item_count = 0;
for(n = root->children; n; n = n->next) {
if (n->type==XML_ELEMENT_NODE && !strcmp((char*)n->name, "item"))
for (n = root->children; n; n = n->next) {
if (n->type == XML_ELEMENT_NODE && !strcmp((char *) n->name, "item")) {
read_item(&res->items[res->item_count++], n->children);
}
}
return 1;
}
static inline int parse_rss_0_9x(PRSS* res, xmlNodePtr root)
static inline int parse_rss_0_9x(PRSS *res, xmlNodePtr root)
{
// almost same...
return parse_rss_2_0(res, root);
}
PRSS* prss_parse_doc(xmlDocPtr doc)
PRSS *prss_parse_doc(xmlDocPtr doc)
{
// FIXME: doc shouldn't be freed after failure when called explicitly from program!
/* FIXME: doc shouldn't be freed after failure when called explicitly from
* program! */
xmlNodePtr root = xmlDocGetRootElement(doc);
PRSS* result = malloc(sizeof(PRSS));
PRSS *result = malloc(sizeof(PRSS));
prss_null(result);
result->_data = doc;
do {
if (root->type == XML_ELEMENT_NODE) {
if (!strcmp((char*)root->name, "RDF")) {
if (!strcmp((char *) root->name, "RDF")) {
// RSS 1.0 document
if (!parse_rss_1_0(result, root)) {
free(result);
@@ -208,7 +230,7 @@ PRSS* prss_parse_doc(xmlDocPtr doc)
return NULL;
}
return result;
} else if (!strcmp((char*)root->name, "rss")) {
} else if (!strcmp((char *) root->name, "rss")) {
// RSS 2.0 or <1.0 document
if (!parse_rss_2_0(result, root)) {
free(result);
@@ -219,7 +241,7 @@ PRSS* prss_parse_doc(xmlDocPtr doc)
}
}
root = root->next;
} while(root);
} while (root);
free(result);
return NULL;
}

View File

@@ -1,5 +1,4 @@
/*
* $Id$
/* $Id$
*
* Copyright (c) 2007 Mikko Sysikaski <mikko.sysikaski@gmail.com>
* Toni Spets <toni.spets@gmail.com>
@@ -14,8 +13,7 @@
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#ifndef PRSS_H
#define PRSS_H
@@ -23,45 +21,45 @@
#include <libxml/parser.h>
typedef struct PRSS_Item_ {
char* title;
char* link;
char* description;
char* category;
char* pubdate;
char* guid;
char *title;
char *link;
char *description;
char *category;
char *pubdate;
char *guid;
} PRSS_Item;
typedef struct PRSS_ {
xmlDocPtr _data;
char* version;
char *version;
char* title;
char* link;
char* description;
char* language;
char* generator;
char* managingeditor;
char* webmaster;
char* docs;
char* lastbuilddate;
char* pubdate;
char* copyright;
char* ttl;
char *title;
char *link;
char *description;
char *language;
char *generator;
char *managingeditor;
char *webmaster;
char *docs;
char *lastbuilddate;
char *pubdate;
char *copyright;
char *ttl;
PRSS_Item* items;
PRSS_Item *items;
int item_count;
} PRSS;
/* Functions for parsing RSS-data */
PRSS* prss_parse_data(const char *xml_data);
PRSS* prss_parse_file(const char *xml_file);
PRSS *prss_parse_data(const char *xml_data);
PRSS *prss_parse_file(const char *xml_file);
// Works wrong currently when called from application!
//PRSS* prss_parse_doc(xmlDocPtr doc);
/* // Works wrong currently when called from application!
PRSS *prss_parse_doc(xmlDocPtr doc); */
/* Frees the PRSS-stucture returned by prss_parse_*.
* The memory area pointed by data becomes invalid
* after call to this function. */
void prss_free(PRSS* data);
void prss_free(PRSS *data);
#endif // PRSS_H
#endif /* PRSS_H */

View File

@@ -1,5 +1,4 @@
/*
* Conky, a system monitor, based on torsmo
/* Conky, a system monitor, based on torsmo
*
* Any original torsmo code is licensed under the BSD license
*
@@ -8,7 +7,8 @@
* Please see COPYING for details
*
* Copyright (c) 2007 Toni Spets
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*/
* $Id$ */
#include <stdio.h>
#include <string.h>
@@ -44,21 +43,20 @@ struct MemoryStruct {
};
typedef struct feed_ {
char* uri;
char *uri;
int last_update;
PRSS* data;
PRSS *data;
} feed;
int num_feeds = 0;
feed feeds[MAX_FEEDS];
size_t
WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
{
size_t realsize = size * nmemb;
struct MemoryStruct *mem = (struct MemoryStruct *)data;
struct MemoryStruct *mem = (struct MemoryStruct *) data;
mem->memory = (char *)realloc(mem->memory, mem->size + realsize + 1);
mem->memory = (char *) realloc(mem->memory, mem->size + realsize + 1);
if (mem->memory) {
memcpy(&(mem->memory[mem->size]), ptr, realsize);
mem->size += realsize;
@@ -67,21 +65,22 @@ WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
return realsize;
}
int rss_delay(int *wait, int delay)
{
time_t now = time(NULL);
// make it minutes
if(delay < 1) delay = 1;
if (delay < 1) {
delay = 1;
}
delay *= 60;
if(!*wait) {
if (!*wait) {
*wait = now + delay;
return 1;
}
if(now >= *wait + delay) {
if (now >= *wait + delay) {
*wait = now + delay;
return 1;
}
@@ -92,7 +91,8 @@ int rss_delay(int *wait, int delay)
void init_rss_info()
{
int i;
for(i = 0; i < MAX_FEEDS; i++) {
for (i = 0; i < MAX_FEEDS; i++) {
feeds[i].uri = NULL;
feeds[i].data = NULL;
feeds[i].last_update = 0;
@@ -102,18 +102,22 @@ void init_rss_info()
void free_rss_info()
{
int i;
for(i = 0; i < num_feeds; i++)
if(feeds[i].uri != NULL)
for (i = 0; i < num_feeds; i++) {
if (feeds[i].uri != NULL) {
free(feeds[i].uri);
}
}
}
PRSS*
get_rss_info(char *uri, int delay)
PRSS *get_rss_info(char *uri, int delay)
{
CURL *curl = NULL;
CURLcode res;
// curl temps
struct MemoryStruct chunk;
chunk.memory = NULL;
chunk.size = 0;
@@ -125,16 +129,19 @@ get_rss_info(char *uri, int delay)
int i;
// first seek for the uri in list
for(i = 0; i < num_feeds; i++) {
if(feeds[i].uri != NULL)
if(!strcmp(feeds[i].uri, uri)) {
for (i = 0; i < num_feeds; i++) {
if (feeds[i].uri != NULL) {
if (!strcmp(feeds[i].uri, uri)) {
curfeed = &feeds[i];
break;
}
}
}
if(!curfeed) { // new feed
if(num_feeds == MAX_FEEDS-1) return NULL;
if (!curfeed) { // new feed
if (num_feeds == MAX_FEEDS - 1) {
return NULL;
}
curfeed = &feeds[num_feeds];
curfeed->uri = strdup(uri);
num_feeds++;
@@ -143,28 +150,30 @@ get_rss_info(char *uri, int delay)
last_update = &curfeed->last_update;
curdata = curfeed->data;
if(!rss_delay(last_update, delay))
if (!rss_delay(last_update, delay)) {
return curdata; // wait for delay to pass
}
if(curdata != NULL) {
if (curdata != NULL) {
prss_free(curdata); // clean up old data
curdata = NULL;
}
curl = curl_easy_init();
if(curl) {
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, uri);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &chunk);
curl_easy_setopt(curl, CURLOPT_USERAGENT, "conky-rss/1.0");
res = curl_easy_perform(curl);
if(chunk.size) {
if (chunk.size) {
curdata = prss_parse_data(chunk.memory);
free(chunk.memory);
} else
} else {
ERR("No data from server");
}
curl_easy_cleanup(curl);
}

View File

@@ -1,5 +1,4 @@
/*
* Conky, a system monitor, based on torsmo
/* Conky, a system monitor, based on torsmo
*
* Any original torsmo code is licensed under the BSD license
*
@@ -7,7 +6,8 @@
*
* Please see COPYING for details
*
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
@@ -22,8 +22,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*/
* $Id$ */
/* doesn't work, feel free to finish this */
#include "conky.h"
@@ -62,12 +61,10 @@ double get_uptime()
if (ksp != NULL) {
if (kstat_read(kstat, ksp, NULL) >= 0) {
kstat_named_t *knp;
knp =
(kstat_named_t *) kstat_data_lookup(ksp,
"boot_time");
knp = (kstat_named_t *) kstat_data_lookup(ksp, "boot_time");
if (knp != NULL) {
return get_time() -
(double) knp->value.ui32;
return get_time() - (double) knp->value.ui32;
}
}
}

View File

@@ -1,7 +1,6 @@
/* $Id$ */
/*
* timed_thread.c: Abstraction layer for timed threads
/* timed_thread.c: Abstraction layer for timed threads
*
* Copyright (C) 2006-2007 Philip Kovacs pkovacs@users.sourceforge.net
*
@@ -18,9 +17,7 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
* USA.
*
*/
* USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -39,24 +36,22 @@
/* Abstraction layer for timed threads */
static int now (struct timespec *);
static int now(struct timespec *);
/* private */
struct _timed_thread
{
struct _timed_thread {
pthread_t thread; /* thread itself */
pthread_attr_t thread_attr; /* thread attributes */
pthread_mutex_t cs_mutex; /* critical section mutex */
pthread_mutex_t runnable_mutex; /* only for the runnable_cond */
pthread_cond_t runnable_cond; /* signalled to stop the thread */
void *(*start_routine)(void*); /* thread function to run */
void *(*start_routine)(void *); /* thread function to run */
void *arg; /* thread function argument */
struct timespec interval_time; /* interval_usecs as a struct timespec */
};
/* linked list of created threads */
typedef struct _timed_thread_list
{
typedef struct _timed_thread_list {
timed_thread *p_timed_thread;
timed_thread **addr_of_p_timed_thread;
struct _timed_thread_list *next;
@@ -65,18 +60,21 @@ typedef struct _timed_thread_list
static timed_thread_list *p_timed_thread_list_head = NULL;
static timed_thread_list *p_timed_thread_list_tail = NULL;
static int now (struct timespec *abstime)
static int now(struct timespec *abstime)
{
if (!abstime)
return (-1);
if (!abstime) {
return -1;
}
#ifdef HAVE_CLOCK_GETTIME
return clock_gettime (CLOCK_REALTIME, abstime);
return clock_gettime(CLOCK_REALTIME, abstime);
#else
/* fallback to gettimeofday () */
struct timeval tv;
if (gettimeofday (&tv, NULL) != 0)
return (-1);
if (gettimeofday(&tv, NULL) != 0) {
return -1;
}
abstime->tv_sec = tv.tv_sec;
abstime->tv_nsec = tv.tv_usec * 1000;
@@ -84,183 +82,184 @@ static int now (struct timespec *abstime)
#endif
}
/* create a timed thread (object creation only) */
timed_thread*
timed_thread_create (void *(*start_routine)(void*), void *arg, unsigned int interval_usecs)
timed_thread *timed_thread_create(void *start_routine(void *), void *arg,
unsigned int interval_usecs)
{
timed_thread *p_timed_thread;
assert (start_routine != NULL);
assert (interval_usecs >= MINIMUM_INTERVAL_USECS);
assert(start_routine != NULL);
assert(interval_usecs >= MINIMUM_INTERVAL_USECS);
if ((p_timed_thread = calloc (sizeof(timed_thread), 1)) == 0)
if ((p_timed_thread = calloc(sizeof(timed_thread), 1)) == 0) {
return NULL;
}
/* init attributes, e.g. joinable thread */
pthread_attr_init (&p_timed_thread->thread_attr);
pthread_attr_setdetachstate (&p_timed_thread->thread_attr, PTHREAD_CREATE_JOINABLE);
pthread_attr_init(&p_timed_thread->thread_attr);
pthread_attr_setdetachstate(&p_timed_thread->thread_attr,
PTHREAD_CREATE_JOINABLE);
/* init mutexes */
pthread_mutex_init (&p_timed_thread->cs_mutex, NULL);
pthread_mutex_init (&p_timed_thread->runnable_mutex, NULL);
pthread_mutex_init(&p_timed_thread->cs_mutex, NULL);
pthread_mutex_init(&p_timed_thread->runnable_mutex, NULL);
/* init cond */
pthread_cond_init (&p_timed_thread->runnable_cond, NULL);
pthread_cond_init(&p_timed_thread->runnable_cond, NULL);
p_timed_thread->start_routine = start_routine;
p_timed_thread->arg = arg;
/* seconds portion of the microseconds interval */
p_timed_thread->interval_time.tv_sec = (time_t)(interval_usecs / 1000000);
p_timed_thread->interval_time.tv_sec = (time_t) (interval_usecs / 1000000);
/* remaining microseconds convert to nanoseconds */
p_timed_thread->interval_time.tv_nsec = (long)((interval_usecs % 1000000) * 1000);
p_timed_thread->interval_time.tv_nsec =
(long) ((interval_usecs % 1000000) * 1000);
/*
printf ("interval_time.tv_sec = %li, .tv_nsec = %li\n",
/* printf("interval_time.tv_sec = %li, .tv_nsec = %li\n",
p_timed_thread->interval_time.tv_sec,
p_timed_thread->interval_time.tv_nsec);
*/
p_timed_thread->interval_time.tv_nsec); */
return p_timed_thread;
}
/* run a timed thread (drop the thread and run it) */
int
timed_thread_run (timed_thread* p_timed_thread)
int timed_thread_run(timed_thread *p_timed_thread)
{
return pthread_create (&p_timed_thread->thread, &p_timed_thread->thread_attr,
return pthread_create(&p_timed_thread->thread, &p_timed_thread->thread_attr,
p_timed_thread->start_routine, p_timed_thread->arg);
}
/* destroy a timed thread.
* optional addr_of_p_timed_thread to set callers pointer to NULL as a convenience. */
void
timed_thread_destroy (timed_thread* p_timed_thread, timed_thread** addr_of_p_timed_thread)
* optional addr_of_p_timed_thread to set callers pointer to NULL as a
* convenience. */
void timed_thread_destroy(timed_thread *p_timed_thread,
timed_thread **addr_of_p_timed_thread)
{
assert (p_timed_thread != NULL);
assert ((addr_of_p_timed_thread == NULL) || (*addr_of_p_timed_thread == p_timed_thread));
assert(p_timed_thread != NULL);
assert((addr_of_p_timed_thread == NULL)
|| (*addr_of_p_timed_thread == p_timed_thread));
/* signal thread to stop */
pthread_mutex_lock (&p_timed_thread->runnable_mutex);
pthread_cond_signal (&p_timed_thread->runnable_cond);
pthread_mutex_unlock (&p_timed_thread->runnable_mutex);
pthread_mutex_lock(&p_timed_thread->runnable_mutex);
pthread_cond_signal(&p_timed_thread->runnable_cond);
pthread_mutex_unlock(&p_timed_thread->runnable_mutex);
/* join the terminating thread */
if (p_timed_thread->thread)
pthread_join (p_timed_thread->thread, NULL);
if (p_timed_thread->thread) {
pthread_join(p_timed_thread->thread, NULL);
}
/* clean up */
pthread_attr_destroy (&p_timed_thread->thread_attr);
pthread_mutex_destroy (&p_timed_thread->cs_mutex);
pthread_mutex_destroy (&p_timed_thread->runnable_mutex);
pthread_cond_destroy (&p_timed_thread->runnable_cond);
pthread_attr_destroy(&p_timed_thread->thread_attr);
pthread_mutex_destroy(&p_timed_thread->cs_mutex);
pthread_mutex_destroy(&p_timed_thread->runnable_mutex);
pthread_cond_destroy(&p_timed_thread->runnable_cond);
free (p_timed_thread);
if (addr_of_p_timed_thread)
free(p_timed_thread);
if (addr_of_p_timed_thread) {
*addr_of_p_timed_thread = NULL;
}
}
/* lock a timed thread for critical section activity */
int
timed_thread_lock (timed_thread* p_timed_thread)
int timed_thread_lock(timed_thread *p_timed_thread)
{
assert (p_timed_thread != NULL);
assert(p_timed_thread != NULL);
return pthread_mutex_lock (&p_timed_thread->cs_mutex);
return pthread_mutex_lock(&p_timed_thread->cs_mutex);
}
/* unlock a timed thread after critical section activity */
int
timed_thread_unlock (timed_thread* p_timed_thread)
int timed_thread_unlock(timed_thread *p_timed_thread)
{
assert (p_timed_thread != NULL);
assert(p_timed_thread != NULL);
return pthread_mutex_unlock (&p_timed_thread->cs_mutex);
return pthread_mutex_unlock(&p_timed_thread->cs_mutex);
}
/* thread waits interval_usecs for runnable_cond to be signaled. returns 1 if signaled,
* -1 on error, and 0 otherwise. caller should call timed_thread_exit() on any non-zero
* return value. */
int
timed_thread_test (timed_thread* p_timed_thread)
/* thread waits interval_usecs for runnable_cond to be signaled.
* returns 1 if signaled, -1 on error, and 0 otherwise.
* caller should call timed_thread_exit() on any non-zero return value. */
int timed_thread_test(timed_thread *p_timed_thread)
{
struct timespec wait_time;
int rc;
assert (p_timed_thread != NULL);
assert(p_timed_thread != NULL);
if (now (&wait_time)) return (-1);
/*printf ("PRE:wait_time.tv_secs = %li, .tv_nsecs = %li\n", wait_time.tv_sec, wait_time.tv_nsec);*/
if (now(&wait_time)) {
return -1;
}
/* printf("PRE:wait_time.tv_secs = %li, .tv_nsecs = %li\n",
wait_time.tv_sec, wait_time.tv_nsec); */
/* add in the wait interval */
if (1000000000-wait_time.tv_nsec <= p_timed_thread->interval_time.tv_nsec)
{
if (1000000000 - wait_time.tv_nsec
<= p_timed_thread->interval_time.tv_nsec) {
/* perform nsec->sec carry operation */
wait_time.tv_sec += p_timed_thread->interval_time.tv_sec + 1;
wait_time.tv_nsec -= 1000000000-p_timed_thread->interval_time.tv_nsec;
/*printf ("001:wait_time.tv_secs = %li, .tv_nsecs = %li\n", wait_time.tv_sec, wait_time.tv_nsec);*/
}
else
{
wait_time.tv_nsec -= 1000000000 - p_timed_thread->interval_time.tv_nsec;
/* printf("001:wait_time.tv_secs = %li, .tv_nsecs = %li\n",
wait_time.tv_sec, wait_time.tv_nsec); */
} else {
/* no carry needed, just add respective components */
wait_time.tv_sec += p_timed_thread->interval_time.tv_sec;
wait_time.tv_nsec += p_timed_thread->interval_time.tv_nsec;
/*printf ("002:wait_time.tv_secs = %li, .tv_nsecs = %li\n", wait_time.tv_sec, wait_time.tv_nsec);*/
/* printf("002:wait_time.tv_secs = %li, .tv_nsecs = %li\n",
wait_time.tv_sec, wait_time.tv_nsec); */
}
/* acquire runnable_cond mutex */
if (pthread_mutex_lock (&p_timed_thread->runnable_mutex))
return (-1); /* could not acquire runnable_cond mutex, so tell caller to exit thread */
if (pthread_mutex_lock(&p_timed_thread->runnable_mutex)) {
/* could not acquire runnable_cond mutex,
* so tell caller to exit thread */
return -1;
}
/* release mutex and wait until future time for runnable_cond to signal */
rc = pthread_cond_timedwait (&p_timed_thread->runnable_cond,
&p_timed_thread->runnable_mutex,
&wait_time);
rc = pthread_cond_timedwait(&p_timed_thread->runnable_cond,
&p_timed_thread->runnable_mutex, &wait_time);
/* mutex re-acquired, so release it */
pthread_mutex_unlock (&p_timed_thread->runnable_mutex);
pthread_mutex_unlock(&p_timed_thread->runnable_mutex);
if (rc==0)
return 1; /* runnable_cond was signaled, so tell caller to exit thread */
if (rc == 0) {
/* runnable_cond was signaled, so tell caller to exit thread */
return 1;
}
/* tell caller not to exit yet */
return 0;
}
/* exit a timed thread */
void
timed_thread_exit (timed_thread* p_timed_thread)
void timed_thread_exit(timed_thread *p_timed_thread)
{
assert (p_timed_thread != NULL);
assert(p_timed_thread != NULL);
pthread_exit (NULL);
pthread_exit(NULL);
}
/* register a timed thread for future destruction via timed_thread_destroy_registered_threads() */
int
timed_thread_register (timed_thread* p_timed_thread, timed_thread** addr_of_p_timed_thread)
/* register a timed thread for future destruction via
* timed_thread_destroy_registered_threads() */
int timed_thread_register(timed_thread *p_timed_thread,
timed_thread **addr_of_p_timed_thread)
{
timed_thread_node *p_node;
assert ((addr_of_p_timed_thread == NULL) || (*addr_of_p_timed_thread == p_timed_thread));
assert((addr_of_p_timed_thread == NULL)
|| (*addr_of_p_timed_thread == p_timed_thread));
if ((p_node = calloc (sizeof (timed_thread_node), 1)) == 0)
if ((p_node = calloc(sizeof(timed_thread_node), 1)) == 0) {
return 0;
}
p_node->p_timed_thread = p_timed_thread;
p_node->addr_of_p_timed_thread = addr_of_p_timed_thread;
p_node->next = NULL;
if (!p_timed_thread_list_tail)
{
if (!p_timed_thread_list_tail) {
/* first node of empty list */
p_timed_thread_list_tail = p_node;
p_timed_thread_list_head = p_node;
}
else
{
} else {
/* add node to tail of non-empty list */
p_timed_thread_list_tail->next = p_node;
p_timed_thread_list_tail = p_node;
@@ -269,24 +268,19 @@ timed_thread_register (timed_thread* p_timed_thread, timed_thread** addr_of_p_ti
return 0;
}
/* destroy all registered timed threads */
void
timed_thread_destroy_registered_threads (void)
void timed_thread_destroy_registered_threads(void)
{
timed_thread_node *p_node, *p_next;
for (p_node=p_timed_thread_list_head;
p_node;
p_node=p_next)
{
for (p_node = p_timed_thread_list_head; p_node; p_node = p_next) {
p_next = p_node->next;
timed_thread_destroy (p_node->p_timed_thread, p_node->addr_of_p_timed_thread);
free (p_node);
timed_thread_destroy(p_node->p_timed_thread,
p_node->addr_of_p_timed_thread);
free(p_node);
p_node = NULL;
}
p_timed_thread_list_head = NULL;
p_timed_thread_list_tail = NULL;
}

View File

@@ -1,7 +1,6 @@
/* $Id$ */
/*
* timed_thread.h: Abstraction layer for timed threads
/* timed_thread.h: Abstraction layer for timed threads
*
* Copyright (C) 2006-2007 Philip Kovacs pkovacs@users.sourceforge.net
*
@@ -18,43 +17,48 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
* USA.
*
*/
* USA. */
#ifndef _TIMED_THREAD_H_
#define _TIMED_THREAD_H_
#define MINIMUM_INTERVAL_USECS 10000 /* 10000 microseconds = 10 ms = 0.01 sec */
/* 10000 microseconds = 10 ms = 0.01 sec */
#define MINIMUM_INTERVAL_USECS 10000
/* opaque structure for clients */
typedef struct _timed_thread timed_thread;
/* create a timed thread (object creation only) */
timed_thread* timed_thread_create (void *(*start_routine)(void*), void *arg, unsigned int interval_usecs);
timed_thread *timed_thread_create(void *start_routine(void *), void *arg,
unsigned int interval_usecs);
/* run a timed thread (drop the thread and run it) */
int timed_thread_run (timed_thread* p_timed_thread);
int timed_thread_run(timed_thread *p_timed_thread);
/* destroy a timed thread */
void timed_thread_destroy (timed_thread* p_timed_thread, timed_thread** addr_of_p_timed_thread);
void timed_thread_destroy(timed_thread *p_timed_thread,
timed_thread **addr_of_p_timed_thread);
/* lock a timed thread for critical section activity */
int timed_thread_lock (timed_thread* p_timed_thread);
int timed_thread_lock(timed_thread *p_timed_thread);
/* unlock a timed thread after critical section activity */
int timed_thread_unlock (timed_thread* p_timed_thread);
int timed_thread_unlock(timed_thread *p_timed_thread);
/* waits required interval for termination signal and returns 1 if got it, 0 otherwise */
int timed_thread_test (timed_thread* p_timed_thread);
/* waits required interval for termination signal
* returns 1 if received,
* 0 otherwise */
int timed_thread_test(timed_thread *p_timed_thread);
/* exit a timed thread */
void timed_thread_exit (timed_thread* p_timed_thread);
void timed_thread_exit(timed_thread *p_timed_thread);
/* register a timed thread for future destruction via timed_thread_destroy_registered_threads() */
int timed_thread_register (timed_thread* p_timed_thread, timed_thread** addr_of_p_timed_thread);
/* register a timed thread for future destruction via
* timed_thread_destroy_registered_threads() */
int timed_thread_register(timed_thread *p_timed_thread,
timed_thread **addr_of_p_timed_thread);
/* destroy all registered timed threads */
void timed_thread_destroy_registered_threads (void);
void timed_thread_destroy_registered_threads(void);
#endif /* #ifdef _TIMED_THREAD_H_ */

427
src/top.c
View File

@@ -1,5 +1,4 @@
/*
* Conky, a system monitor, based on torsmo
/* Conky, a system monitor, based on torsmo
*
* Any original torsmo code is licensed under the BSD license
*
@@ -9,7 +8,8 @@
*
* Copyright (c) 2005 Adi Zaimi, Dan Piponi <dan@tanelorn.demon.co.uk>,
* Dave Clark <clarkd@skynet.ca>
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
@@ -24,8 +24,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*/
* $Id$ */
#include "top.h"
@@ -38,11 +37,10 @@ struct process *get_first_process()
return first_process;
}
void free_all_processes()
{
struct process *next = NULL, *pr = first_process;
while (pr) {
next = pr->next;
if (pr->name) {
@@ -57,33 +55,32 @@ void free_all_processes()
static struct process *find_process(pid_t pid)
{
struct process *p = first_process;
while (p) {
if (p->pid == pid)
if (p->pid == pid) {
return p;
}
p = p->next;
}
return 0;
}
/*
* Create a new process object and insert it into the process list
*/
/* Create a new process object and insert it into the process list */
static struct process *new_process(int p)
{
struct process *process;
process = (struct process*)malloc(sizeof(struct process));
process = (struct process *) malloc(sizeof(struct process));
// clean up memory first
memset(process, 0, sizeof(struct process));
/*
* Do stitching necessary for doubly linked list
*/
/* Do stitching necessary for doubly linked list */
process->name = 0;
process->previous = 0;
process->next = first_process;
if (process->next)
if (process->next) {
process->next->previous = process;
}
first_process = process;
process->pid = p;
@@ -92,37 +89,25 @@ static struct process *new_process(int p)
process->previous_kernel_time = ULONG_MAX;
process->counted = 1;
/* process_find_name(process); */
return process;
}
/******************************************/
/* Functions */
/******************************************/
/******************************************
* Functions *
******************************************/
static int process_parse_stat(struct process *);
static int update_process_table(void);
static int calculate_cpu(struct process *);
static void process_cleanup(void);
static void delete_process(struct process *);
/*inline void draw_processes(void);*/
static unsigned long long calc_cpu_total(void);
static void calc_cpu_each(unsigned long long);
/******************************************
* Extract information from /proc *
******************************************/
/******************************************/
/* Extract information from /proc */
/******************************************/
/*
* These are the guts that extract information out of /proc.
* Anyone hoping to port wmtop should look here first.
*/
/* These are the guts that extract information out of /proc.
* Anyone hoping to port wmtop should look here first. */
static int process_parse_stat(struct process *process)
{
struct information *cur;
cur = &info;
char line[BUFFER_LEN] = { 0 }, filename[BUFFER_LEN], procname[BUFFER_LEN];
int ps;
@@ -134,50 +119,42 @@ static int process_parse_stat(struct process *process)
int endl;
int nice_val;
snprintf(filename, sizeof(filename), PROCFS_TEMPLATE,
process->pid);
snprintf(filename, sizeof(filename), PROCFS_TEMPLATE, process->pid);
ps = open(filename, O_RDONLY);
if (ps < 0)
/*
* The process must have finished in the last few jiffies!
*/
if (ps < 0) {
/* The process must have finished in the last few jiffies! */
return 1;
}
/*
* Mark process as up-to-date.
*/
/* Mark process as up-to-date. */
process->time_stamp = g_time;
rc = read(ps, line, sizeof(line));
close(ps);
if (rc < 0)
if (rc < 0) {
return 1;
}
/*
* Extract cpu times from data in /proc filesystem
*/
rc = sscanf(line,
"%*s %s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %lu %lu %*s %*s %*s %d %*s %*s %*s %d %d",
procname, &process->user_time, &process->kernel_time,
&nice_val, &process->vsize, &process->rss);
if (rc < 5)
/* Extract cpu times from data in /proc filesystem */
rc = sscanf(line, "%*s %s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %lu "
"%lu %*s %*s %*s %d %*s %*s %*s %d %d", procname, &process->user_time,
&process->kernel_time, &nice_val, &process->vsize, &process->rss);
if (rc < 5) {
return 1;
/*
* Remove parentheses from the process name stored in /proc/ under Linux...
*/
}
/* Remove parentheses from the process name stored in /proc/ under Linux */
r = procname + 1;
/* remove any "kdeinit: " */
if (r == strstr(r, "kdeinit")) {
snprintf(filename, sizeof(filename),
PROCFS_CMDLINE_TEMPLATE, process->pid);
snprintf(filename, sizeof(filename), PROCFS_CMDLINE_TEMPLATE,
process->pid);
ps = open(filename, O_RDONLY);
if (ps < 0)
/*
* The process must have finished in the last few jiffies!
*/
if (ps < 0) {
/* The process must have finished in the last few jiffies! */
return 1;
}
endl = read(ps, line, sizeof(line));
close(ps);
@@ -185,20 +162,23 @@ static int process_parse_stat(struct process *process)
/* null terminate the input */
line[endl] = 0;
/* account for "kdeinit: " */
if ((char *) line == strstr(line, "kdeinit: "))
if ((char *) line == strstr(line, "kdeinit: ")) {
r = ((char *) line) + 9;
else
} else {
r = (char *) line;
}
q = deparenthesised_name;
/* stop at space */
while (*r && *r != ' ')
while (*r && *r != ' ') {
*q++ = *r++;
}
*q = 0;
} else {
q = deparenthesised_name;
while (*r && *r != ')')
while (*r && *r != ')') {
*q++ = *r++;
}
*q = 0;
}
@@ -208,17 +188,18 @@ static int process_parse_stat(struct process *process)
process->name = strdup(deparenthesised_name);
process->rss *= getpagesize();
if (!cur->memmax)
if (!cur->memmax) {
update_total_processes();
}
process->total_cpu_time = process->user_time + process->kernel_time;
process->totalmem = (float)(((float) process->rss / cur->memmax) / 10);
if (process->previous_user_time == ULONG_MAX)
process->totalmem = (float) (((float) process->rss / cur->memmax) / 10);
if (process->previous_user_time == ULONG_MAX) {
process->previous_user_time = process->user_time;
if (process->previous_kernel_time == ULONG_MAX)
}
if (process->previous_kernel_time == ULONG_MAX) {
process->previous_kernel_time = process->kernel_time;
}
/* store the difference of the user_time */
user_time = process->user_time - process->previous_user_time;
@@ -232,43 +213,67 @@ static int process_parse_stat(struct process *process)
process->user_time = user_time;
process->kernel_time = kernel_time;
return 0;
}
/******************************************
* Get process structure for process pid *
******************************************/
/* This function seems to hog all of the CPU time.
* I can't figure out why - it doesn't do much. */
static int calculate_cpu(struct process *process)
{
int rc;
/* compute each process cpu usage by reading /proc/<proc#>/stat */
rc = process_parse_stat(process);
if (rc)
return 1;
/* rc = process_parse_statm(process); if (rc) return 1; */
/*
* Check name against the exclusion list
*/
/* if (process->counted && exclusion_expression &&
* !regexec(exclusion_expression, process->name, 0, 0, 0))
* process->counted = 0; */
return 0;
}
/******************************************/
/* Update process table */
/******************************************/
/******************************************
* Update process table *
******************************************/
static int update_process_table()
{
DIR *dir;
struct dirent *entry;
if (!(dir = opendir("/proc")))
if (!(dir = opendir("/proc"))) {
return 1;
}
++g_time;
/*
* Get list of processes from /proc directory
*/
/* Get list of processes from /proc directory */
while ((entry = readdir(dir))) {
pid_t pid;
if (!entry) {
/*
* Problem reading list of processes
*/
/* Problem reading list of processes */
closedir(dir);
return 1;
}
if (sscanf(entry->d_name, "%d", &pid) > 0) {
struct process *p;
p = find_process(pid);
if (!p)
if (!p) {
p = new_process(pid);
}
/* compute each process cpu usage */
calculate_cpu(p);
@@ -280,64 +285,9 @@ static int update_process_table()
return 0;
}
/******************************************/
/* Get process structure for process pid */
/******************************************/
/*
* This function seems to hog all of the CPU time. I can't figure out why - it
* doesn't do much.
*/
static int calculate_cpu(struct process *process)
{
int rc;
/* compute each process cpu usage by reading /proc/<proc#>/stat */
rc = process_parse_stat(process);
if (rc)
return 1;
/*rc = process_parse_statm(process);
if (rc)
return 1; */
/*
* Check name against the exclusion list
*/
/* if (process->counted && exclusion_expression
&& !regexec(exclusion_expression, process->name, 0, 0, 0))
process->counted = 0;
*/
return 0;
}
/******************************************/
/* Strip dead process entries */
/******************************************/
static void process_cleanup()
{
struct process *p = first_process;
while (p) {
struct process *current = p;
#if defined(PARANOID)
assert(p->id == 0x0badfeed);
#endif /* defined(PARANOID) */
p = p->next;
/*
* Delete processes that have died
*/
if (current->time_stamp != g_time)
delete_process(current);
}
}
/******************************************/
/* Destroy and remove a process */
/******************************************/
/******************************************
* Destroy and remove a process *
******************************************/
static void delete_process(struct process *p)
{
@@ -366,9 +316,33 @@ static void delete_process(struct process *p)
free(p);
}
/******************************************/
/* Calculate cpu total */
/******************************************/
/******************************************
* Strip dead process entries *
******************************************/
static void process_cleanup()
{
struct process *p = first_process;
while (p) {
struct process *current = p;
#if defined(PARANOID)
assert(p->id == 0x0badfeed);
#endif /* defined(PARANOID) */
p = p->next;
/* Delete processes that have died */
if (current->time_stamp != g_time) {
delete_process(current);
}
}
}
/******************************************
* Calculate cpu total *
******************************************/
#define TMPL_SHORTPROC "%*s %llu %llu %llu %llu"
#define TMPL_LONGPROC "%*s %llu %llu %llu %llu %llu %llu %llu %llu"
@@ -387,15 +361,18 @@ static unsigned long long calc_cpu_total()
unsigned long long irq = 0;
unsigned long long softirq = 0;
unsigned long long steal = 0;
char * template = KFLAG_ISSET(KFLAG_IS_LONGSTAT) ? TMPL_LONGPROC : TMPL_SHORTPROC;
char *template =
KFLAG_ISSET(KFLAG_IS_LONGSTAT) ? TMPL_LONGPROC : TMPL_SHORTPROC;
ps = open("/proc/stat", O_RDONLY);
rc = read(ps, line, sizeof(line));
close(ps);
if (rc < 0)
if (rc < 0) {
return 0;
}
sscanf(line, template, &cpu, &nice, &system, &idle, &iowait, &irq, &softirq, &steal);
sscanf(line, template, &cpu, &nice, &system, &idle, &iowait, &irq,
&softirq, &steal);
total = cpu + nice + system + idle + iowait + irq + softirq + steal;
t = total - previous_total;
@@ -404,102 +381,112 @@ static unsigned long long calc_cpu_total()
return t;
}
/******************************************/
/* Calculate each processes cpu */
/******************************************/
/******************************************
* Calculate each processes cpu *
******************************************/
inline static void calc_cpu_each(unsigned long long total)
{
struct process *p = first_process;
while (p) {
p->amount =
100.0 * (cpu_separate ? info.cpu_count : 1) * (p->user_time + p->kernel_time) / (float)total;
p->amount = 100.0 * (cpu_separate ? info.cpu_count : 1) *
(p->user_time + p->kernel_time) / (float) total;
p = p->next;
}
}
/******************************************/
/* Find the top processes */
/******************************************/
/******************************************
* Find the top processes *
******************************************/
/*
* free a sp_process structure
*/
void free_sp(struct sorted_process * sp) {
/* free a sp_process structure */
void free_sp(struct sorted_process *sp)
{
free(sp);
}
/*
* create a new sp_process structure
*/
struct sorted_process * malloc_sp(struct process * proc) {
struct sorted_process * sp;
/* create a new sp_process structure */
struct sorted_process *malloc_sp(struct process *proc)
{
struct sorted_process *sp;
sp = malloc(sizeof(struct sorted_process));
sp->greater = NULL;
sp->less = NULL;
sp->proc = proc;
return(sp);
return sp;
}
/*
* cpu comparison function for insert_sp_element
*/
int compare_cpu(struct process *a, struct process *b) {
if (a->amount < b->amount) return 1;
/* cpu comparison function for insert_sp_element */
int compare_cpu(struct process *a, struct process *b)
{
if (a->amount < b->amount) {
return 1;
} else if (a->amount > b->amount) {
return -1;
} else {
return 0;
}
}
/*
* mem comparison function for insert_sp_element
*/
int compare_mem(struct process *a, struct process *b) {
if (a->totalmem < b->totalmem) return 1;
/* mem comparison function for insert_sp_element */
int compare_mem(struct process *a, struct process *b)
{
if (a->totalmem < b->totalmem) {
return 1;
} else if (a->totalmem > b->totalmem) {
return -1;
} else {
return 0;
}
}
/*
* insert this process into the list in a sorted fashion,
* or destroy it if it doesn't fit on the list
*/
int insert_sp_element(
struct sorted_process * sp_cur
, struct sorted_process ** p_sp_head
, struct sorted_process ** p_sp_tail
, int max_elements
, int (*compare_funct) (struct process *, struct process *)
) {
/* insert this process into the list in a sorted fashion,
* or destroy it if it doesn't fit on the list */
int insert_sp_element(struct sorted_process *sp_cur,
struct sorted_process **p_sp_head, struct sorted_process **p_sp_tail,
int max_elements, int compare_funct(struct process *, struct process *))
{
struct sorted_process * sp_readthru=NULL, * sp_destroy=NULL;
struct sorted_process *sp_readthru = NULL, *sp_destroy = NULL;
int did_insert = 0, x = 0;
if (*p_sp_head == NULL) {
*p_sp_head = sp_cur;
*p_sp_tail = sp_cur;
return(1);
return 1;
}
for(sp_readthru=*p_sp_head, x=0; sp_readthru != NULL && x < max_elements; sp_readthru=sp_readthru->less, x++) {
if (compare_funct(sp_readthru->proc, sp_cur->proc) && !did_insert) {
/* sp_cur is bigger than sp_readthru so insert it before sp_readthru */
sp_cur->less=sp_readthru;
for (sp_readthru = *p_sp_head, x = 0;
sp_readthru != NULL && x < max_elements;
sp_readthru = sp_readthru->less, x++) {
if (compare_funct(sp_readthru->proc, sp_cur->proc) > 0 && !did_insert) {
/* sp_cur is bigger than sp_readthru
* so insert it before sp_readthru */
sp_cur->less = sp_readthru;
if (sp_readthru == *p_sp_head) {
*p_sp_head = sp_cur; /* insert as the new head of the list */
/* insert as the new head of the list */
*p_sp_head = sp_cur;
} else {
sp_readthru->greater->less = sp_cur; /* insert inside the list */
/* insert inside the list */
sp_readthru->greater->less = sp_cur;
sp_cur->greater = sp_readthru->greater;
}
sp_readthru->greater=sp_cur;
did_insert = ++x; /* element was inserted, so increase the counter */
sp_readthru->greater = sp_cur;
/* element was inserted, so increase the counter */
did_insert = ++x;
}
}
if (x < max_elements && sp_readthru == NULL && !did_insert) {
/* sp_cur is the smallest element and list isn't full, so insert at the end */
(*p_sp_tail)->less=sp_cur;
sp_cur->greater=*p_sp_tail;
/* sp_cur is the smallest element and list isn't full,
* so insert at the end */
(*p_sp_tail)->less = sp_cur;
sp_cur->greater = *p_sp_tail;
*p_sp_tail = sp_cur;
did_insert=x;
did_insert = x;
} else if (x >= max_elements) {
/* we inserted an element and now the list is too big by one. Destroy the smallest element */
/* We inserted an element and now the list is too big by one.
* Destroy the smallest element */
sp_destroy = *p_sp_tail;
*p_sp_tail = sp_destroy->greater;
(*p_sp_tail)->less = NULL;
@@ -512,26 +499,25 @@ int insert_sp_element(
return did_insert;
}
/*
* copy the procs in the sorted list to the array, and destroy the list
*/
void sp_acopy(struct sorted_process *sp_head, struct process ** ar, int max_size)
/* copy the procs in the sorted list to the array, and destroy the list */
void sp_acopy(struct sorted_process *sp_head, struct process **ar, int max_size)
{
struct sorted_process * sp_cur, * sp_tmp;
struct sorted_process *sp_cur, *sp_tmp;
int x;
sp_cur = sp_head;
for (x=0; x < max_size && sp_cur != NULL; x++) {
for (x = 0; x < max_size && sp_cur != NULL; x++) {
ar[x] = sp_cur->proc;
sp_tmp = sp_cur;
sp_cur= sp_cur->less;
sp_cur = sp_cur->less;
free_sp(sp_tmp);
}
}
/* ****************************************************************** */
/* Get a sorted list of the top cpu hogs and top mem hogs. */
/* Results are stored in the cpu,mem arrays in decreasing order[0-9]. */
/* ****************************************************************** */
/* ****************************************************************** *
* Get a sorted list of the top cpu hogs and top mem hogs. *
* Results are stored in the cpu,mem arrays in decreasing order[0-9]. *
* ****************************************************************** */
inline void process_find_top(struct process **cpu, struct process **mem)
{
@@ -540,7 +526,9 @@ inline void process_find_top(struct process **cpu, struct process **mem)
struct process *cur_proc = NULL;
unsigned long long total = 0;
if (!top_cpu && !top_mem) return;
if (!top_cpu && !top_mem) {
return;
}
total = calc_cpu_total(); /* calculate the total of the processor */
update_process_table(); /* update the table with process list */
@@ -549,18 +537,19 @@ inline void process_find_top(struct process **cpu, struct process **mem)
cur_proc = first_process;
while (cur_proc !=NULL) {
while (cur_proc != NULL) {
if (top_cpu) {
spc_cur = malloc_sp(cur_proc);
insert_sp_element(spc_cur, &spc_head, &spc_tail, MAX_SP, &compare_cpu);
insert_sp_element(spc_cur, &spc_head, &spc_tail, MAX_SP,
&compare_cpu);
}
if (top_mem) {
spm_cur = malloc_sp(cur_proc);
insert_sp_element(spm_cur, &spm_head, &spm_tail, MAX_SP, &compare_mem);
insert_sp_element(spm_cur, &spm_head, &spm_tail, MAX_SP,
&compare_mem);
}
cur_proc = cur_proc->next;
}
sp_acopy(spc_head, cpu, MAX_SP);
sp_acopy(spm_head, mem, MAX_SP);
}

View File

@@ -1,5 +1,4 @@
/*
* Conky, a system monitor, based on torsmo
/* Conky, a system monitor, based on torsmo
*
* Any original torsmo code is licensed under the BSD license
*
@@ -9,7 +8,8 @@
*
* Copyright (c) 2005 Adi Zaimi, Dan Piponi <dan@tanelorn.demon.co.uk>,
* Dave Clark <clarkd@skynet.ca>
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
@@ -24,18 +24,16 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*/
* $Id$ */
/*
* Ensure there's an operating system defined. There is *no* default
* because every OS has it's own way of revealing CPU/memory usage.
/* Ensure there's an operating system defined.
* compile with gcc -DOS ...
*/
* There is *no* default because every OS has it's own way of revealing
* CPU/memory usage. */
/******************************************/
/* Includes */
/******************************************/
/******************************************
* Includes *
******************************************/
#include "conky.h"
#define CPU_THRESHHOLD 0 /* threshhold for the cpu diff to appear */
@@ -62,28 +60,28 @@
#include <regex.h>
/******************************************/
/* Defines */
/******************************************/
/******************************************
* Defines *
******************************************/
/*
* XXX: I shouldn't really use this BUFFER_LEN variable but scanf is so
* lame and it'll take me a while to write a replacement.
*/
/* XXX: I shouldn't really use this BUFFER_LEN variable but scanf is so lame
* and it'll take me a while to write a replacement. */
#define BUFFER_LEN 1024
#define PROCFS_TEMPLATE "/proc/%d/stat"
#define PROCFS_TEMPLATE_MEM "/proc/%d/statm"
#define PROCFS_CMDLINE_TEMPLATE "/proc/%d/cmdline"
#define MAX_SP 10 //number of elements to sort
#define MAX_SP 10 // number of elements to sort
/******************************************
* Globals *
******************************************/
extern int cpu_separate;
/******************************************/
/* Process class */
/******************************************/
/******************************************
* Process class *
******************************************/
struct sorted_process {
struct sorted_process *greater;
@@ -91,7 +89,5 @@ struct sorted_process {
struct process *proc;
};
/*
* Pointer to head of process list
*/
/* Pointer to head of process list */
void process_find_top(struct process **, struct process **);

343
src/x11.c
View File

@@ -1,5 +1,4 @@
/*
* Conky, a system monitor, based on torsmo
/* Conky, a system monitor, based on torsmo
*
* Any original torsmo code is licensed under the BSD license
*
@@ -8,7 +7,8 @@
* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
@@ -23,8 +23,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*/
* $Id$ */
#include "conky.h"
@@ -67,8 +66,9 @@ static Window find_subwindow(Window win, int w, int h);
/* X11 initializer */
void init_X11()
{
if ((display = XOpenDisplay(0)) == NULL)
if ((display = XOpenDisplay(0)) == NULL) {
CRIT_ERR("can't open display: %s", XDisplayName(0));
}
screen = DefaultScreen(display);
display_width = DisplayWidth(display, screen);
@@ -92,17 +92,15 @@ static void update_workarea()
workarea[3] = display_height;
/* get current desktop */
if (XGetWindowProperty(display, root, ATOM(_NET_CURRENT_DESKTOP),
0, 1, False, XA_CARDINAL, &type, &format,
&nitems, &bytes, &buf) == Success
&& type == XA_CARDINAL && nitems > 0) {
if (XGetWindowProperty(display, root, ATOM(_NET_CURRENT_DESKTOP), 0, 1,
False, XA_CARDINAL, &type, &format, &nitems, &bytes, &buf)
== Success && type == XA_CARDINAL && nitems > 0) {
//Currently unused
/* long desktop = * (long *) buf; */
// Currently unused
/* long desktop = *(long *) buf; */
XFree(buf);
buf = 0;
}
if (buf) {
@@ -111,8 +109,10 @@ static void update_workarea()
}
}
/* Find root window and desktop window. Return desktop window on success,
* and set root and desktop byref return values. Return 0 on failure. */
/* Find root window and desktop window.
* Return desktop window on success,
* and set root and desktop byref return values.
* Return 0 on failure. */
static Window find_desktop_window(Window *p_root, Window *p_desktop)
{
Atom type;
@@ -124,25 +124,26 @@ static Window find_desktop_window(Window *p_root, Window *p_desktop)
Window troot, parent, *children;
unsigned char *buf = NULL;
if (!p_root || !p_desktop)
return(0);
if (!p_root || !p_desktop) {
return 0;
}
/* some window managers set __SWM_VROOT to some child of root window */
XQueryTree(display, root, &troot, &parent, &children, &n);
for (i = 0; i < (int) n; i++) {
if (XGetWindowProperty
(display, children[i], ATOM(__SWM_VROOT), 0, 1, False,
XA_WINDOW, &type, &format, &nitems, &bytes,
&buf) == Success && type == XA_WINDOW) {
if (XGetWindowProperty(display, children[i], ATOM(__SWM_VROOT), 0, 1,
False, XA_WINDOW, &type, &format, &nitems, &bytes, &buf)
== Success && type == XA_WINDOW) {
win = *(Window *) buf;
XFree(buf);
XFree(children);
fprintf(stderr,
"Conky: desktop window (%lx) found from __SWM_VROOT property\n", win);
"Conky: desktop window (%lx) found from __SWM_VROOT property\n",
win);
fflush(stderr);
*p_root=win;
*p_desktop=win;
*p_root = win;
*p_desktop = win;
return win;
}
@@ -165,16 +166,18 @@ static Window find_desktop_window(Window *p_root, Window *p_desktop)
buf = 0;
}
if (win != root)
if (win != root) {
fprintf(stderr,
"Conky: desktop window (%lx) is subwindow of root window (%lx)\n",win,root);
else
fprintf(stderr, "Conky: desktop window (%lx) is root window\n",win);
"Conky: desktop window (%lx) is subwindow of root window (%lx)\n",
win, root);
} else {
fprintf(stderr, "Conky: desktop window (%lx) is root window\n", win);
}
fflush(stderr);
*p_root=root;
*p_desktop=win;
*p_root = root;
*p_desktop = win;
return win;
}
@@ -183,9 +186,11 @@ static Window find_desktop_window(Window *p_root, Window *p_desktop)
inline void set_transparent_background(Window win)
{
static int colour_set = -1;
if (set_transparent) {
Window parent = win;
unsigned int i;
for (i = 0; i < 50 && parent != RootWindow(display, screen); i++) {
Window r, *children;
unsigned int n;
@@ -198,15 +203,15 @@ inline void set_transparent_background(Window win)
} else if (colour_set != background_colour) {
XSetWindowBackground(display, win, background_colour);
colour_set = background_colour;
}
//XClearWindow(display, win); not sure why this was here
}
// XClearWindow(display, win); not sure why this was here
}
void init_window(int own_window, int w, int h, int set_trans, int back_colour,
char **argv, int argc)
{
/* There seems to be some problems with setting transparent background (on
* fluxbox this time). It doesn't happen always and I don't know why it
/* There seems to be some problems with setting transparent background
* (on fluxbox this time). It doesn't happen always and I don't know why it
* happens but I bet the bug is somewhere here. */
set_transparent = set_trans;
background_colour = back_colour;
@@ -214,237 +219,204 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour,
#ifdef OWN_WINDOW
if (own_window) {
if ( !find_desktop_window( &window.root, &window.desktop ) )
if (!find_desktop_window(&window.root, &window.desktop)) {
return;
}
if (window.type == TYPE_OVERRIDE) {
/*
An override_redirect True window. No WM hints or button processing needed.
*/
XSetWindowAttributes attrs = {
ParentRelative,0L,0,0L,0,0,Always,0L,0L,False,
StructureNotifyMask|ExposureMask,
0L,
True,
0,0 };
/* An override_redirect True window.
* No WM hints or button processing needed. */
XSetWindowAttributes attrs = { ParentRelative, 0L, 0, 0L, 0, 0,
Always, 0L, 0L, False, StructureNotifyMask | ExposureMask, 0L,
True, 0, 0 };
/* Parent is desktop window (which might be a child of root) */
window.window = XCreateWindow(display,
window.desktop,
window.x, window.y, w, h, 0,
CopyFromParent,
InputOutput,
CopyFromParent,
CWBackPixel|CWOverrideRedirect,
&attrs);
window.window = XCreateWindow(display, window.desktop, window.x,
window.y, w, h, 0, CopyFromParent, InputOutput, CopyFromParent,
CWBackPixel | CWOverrideRedirect, &attrs);
XLowerWindow(display, window.window);
fprintf(stderr, "Conky: window type - override\n"); fflush(stderr);
fprintf(stderr, "Conky: window type - override\n");
fflush(stderr);
} else { /* window.type != TYPE_OVERRIDE */
}
else { /* window.type != TYPE_OVERRIDE */
/*
A window managed by the window manager. Process hints and buttons.
*/
XSetWindowAttributes attrs = {
ParentRelative,0L,0,0L,0,0,Always,0L,0L,False,
StructureNotifyMask|ExposureMask|ButtonPressMask|ButtonReleaseMask,
0L,
False,
0,0 };
/* A window managed by the window manager.
* Process hints and buttons. */
XSetWindowAttributes attrs = { ParentRelative, 0L, 0, 0L, 0, 0,
Always, 0L, 0L, False, StructureNotifyMask | ExposureMask |
ButtonPressMask | ButtonReleaseMask, 0L, False, 0, 0 };
XClassHint classHint;
XWMHints wmHint;
Atom xa;
/* Parent is root window so WM can take control */
window.window = XCreateWindow(display,
window.root,
window.x, window.y, w, h, 0,
CopyFromParent,
InputOutput,
CopyFromParent,
CWBackPixel|CWOverrideRedirect,
&attrs);
window.window = XCreateWindow(display, window.root, window.x,
window.y, w, h, 0, CopyFromParent, InputOutput, CopyFromParent,
CWBackPixel | CWOverrideRedirect, &attrs);
classHint.res_name = window.class_name;
classHint.res_class = classHint.res_name;
wmHint.flags = InputHint | StateHint;
/* allow decorated windows to be given input focus by WM */
wmHint.input = TEST_HINT(window.hints,HINT_UNDECORATED) ? False : True;
wmHint.input =
TEST_HINT(window.hints, HINT_UNDECORATED) ? False : True;
wmHint.initial_state = NormalState;
XmbSetWMProperties (display, window.window, window.title, NULL,
argv, argc,
NULL, &wmHint, &classHint);
XmbSetWMProperties(display, window.window, window.title, NULL, argv,
argc, NULL, &wmHint, &classHint);
/* Sets an empty WM_PROTOCOLS property */
XSetWMProtocols(display,window.window,NULL,0);
XSetWMProtocols(display, window.window, NULL, 0);
/* Set window type */
if ( (xa = ATOM(_NET_WM_WINDOW_TYPE)) != None )
{
if ((xa = ATOM(_NET_WM_WINDOW_TYPE)) != None) {
Atom prop;
switch(window.type) {
switch (window.type) {
case TYPE_DESKTOP:
{
prop = ATOM(_NET_WM_WINDOW_TYPE_DESKTOP);
fprintf(stderr, "Conky: window type - desktop\n"); fflush(stderr);
}
fprintf(stderr, "Conky: window type - desktop\n");
fflush(stderr);
break;
case TYPE_NORMAL:
default:
{
prop = ATOM(_NET_WM_WINDOW_TYPE_NORMAL);
fprintf(stderr, "Conky: window type - normal\n"); fflush(stderr);
}
fprintf(stderr, "Conky: window type - normal\n");
fflush(stderr);
break;
}
XChangeProperty(display, window.window, xa,
XA_ATOM, 32,
PropModeReplace,
(unsigned char *) &prop, 1);
XChangeProperty(display, window.window, xa, XA_ATOM, 32,
PropModeReplace, (unsigned char *) &prop, 1);
}
/* Set desired hints */
/* Window decorations */
if (TEST_HINT(window.hints,HINT_UNDECORATED)) {
/*fprintf(stderr, "Conky: hint - undecorated\n"); fflush(stderr);*/
if (TEST_HINT(window.hints, HINT_UNDECORATED)) {
/* fprintf(stderr, "Conky: hint - undecorated\n");
fflush(stderr); */
xa = ATOM(_MOTIF_WM_HINTS);
if (xa != None) {
long prop[5] = { 2, 0, 0, 0, 0 };
XChangeProperty(display, window.window, xa,
xa, 32, PropModeReplace,
(unsigned char *) prop, 5);
XChangeProperty(display, window.window, xa, xa, 32,
PropModeReplace, (unsigned char *) prop, 5);
}
}
/* Below other windows */
if (TEST_HINT(window.hints,HINT_BELOW)) {
/*fprintf(stderr, "Conky: hint - below\n"); fflush(stderr); */
if (TEST_HINT(window.hints, HINT_BELOW)) {
/* fprintf(stderr, "Conky: hint - below\n");
fflush(stderr); */
xa = ATOM(_WIN_LAYER);
if (xa != None) {
long prop = 0;
XChangeProperty(display, window.window, xa,
XA_CARDINAL, 32,
PropModeAppend,
(unsigned char *) &prop, 1);
XChangeProperty(display, window.window, xa, XA_CARDINAL, 32,
PropModeAppend, (unsigned char *) &prop, 1);
}
xa = ATOM(_NET_WM_STATE);
if (xa != None) {
Atom xa_prop = ATOM(_NET_WM_STATE_BELOW);
XChangeProperty(display, window.window, xa,
XA_ATOM, 32,
PropModeAppend,
(unsigned char *) &xa_prop,
1);
XChangeProperty(display, window.window, xa, XA_ATOM, 32,
PropModeAppend, (unsigned char *) &xa_prop, 1);
}
}
/* Above other windows */
if (TEST_HINT(window.hints,HINT_ABOVE)) {
/*fprintf(stderr, "Conky: hint - above\n"); fflush(stderr);*/
if (TEST_HINT(window.hints, HINT_ABOVE)) {
/* fprintf(stderr, "Conky: hint - above\n");
fflush(stderr); */
xa = ATOM(_WIN_LAYER);
if (xa != None) {
long prop = 6;
XChangeProperty(display, window.window, xa,
XA_CARDINAL, 32,
PropModeAppend,
(unsigned char *) &prop, 1);
XChangeProperty(display, window.window, xa, XA_CARDINAL, 32,
PropModeAppend, (unsigned char *) &prop, 1);
}
xa = ATOM(_NET_WM_STATE);
if (xa != None) {
Atom xa_prop = ATOM(_NET_WM_STATE_ABOVE);
XChangeProperty(display, window.window, xa,
XA_ATOM, 32,
PropModeAppend,
(unsigned char *) &xa_prop,
1);
XChangeProperty(display, window.window, xa, XA_ATOM, 32,
PropModeAppend, (unsigned char *) &xa_prop, 1);
}
}
/* Sticky */
if (TEST_HINT(window.hints,HINT_STICKY)) {
/*fprintf(stderr, "Conky: hint - sticky\n"); fflush(stderr); */
if (TEST_HINT(window.hints, HINT_STICKY)) {
/* fprintf(stderr, "Conky: hint - sticky\n");
fflush(stderr); */
xa = ATOM(_NET_WM_DESKTOP);
if (xa != None) {
CARD32 xa_prop = 0xFFFFFFFF;
XChangeProperty(display, window.window, xa,
XA_CARDINAL, 32,
PropModeAppend,
(unsigned char *) &xa_prop,
1);
XChangeProperty(display, window.window, xa, XA_CARDINAL, 32,
PropModeAppend, (unsigned char *) &xa_prop, 1);
}
xa = ATOM(_NET_WM_STATE);
if (xa != None) {
Atom xa_prop = ATOM(_NET_WM_STATE_STICKY);
XChangeProperty(display, window.window, xa,
XA_ATOM, 32,
PropModeAppend,
(unsigned char *) &xa_prop,
1);
XChangeProperty(display, window.window, xa, XA_ATOM, 32,
PropModeAppend, (unsigned char *) &xa_prop, 1);
}
}
/* Skip taskbar */
if (TEST_HINT(window.hints,HINT_SKIP_TASKBAR)) {
/*fprintf(stderr, "Conky: hint - skip_taskbar\n"); fflush(stderr);*/
if (TEST_HINT(window.hints, HINT_SKIP_TASKBAR)) {
/* fprintf(stderr, "Conky: hint - skip_taskbar\n");
fflush(stderr); */
xa = ATOM(_NET_WM_STATE);
if (xa != None) {
Atom xa_prop = ATOM(_NET_WM_STATE_SKIP_TASKBAR);
XChangeProperty(display, window.window, xa,
XA_ATOM, 32,
PropModeAppend,
(unsigned char *) &xa_prop,
1);
XChangeProperty(display, window.window, xa, XA_ATOM, 32,
PropModeAppend, (unsigned char *) &xa_prop, 1);
}
}
/* Skip pager */
if (TEST_HINT(window.hints,HINT_SKIP_PAGER)) {
/*fprintf(stderr, "Conky: hint - skip_pager\n"); fflush(stderr);*/
if (TEST_HINT(window.hints, HINT_SKIP_PAGER)) {
/* fprintf(stderr, "Conky: hint - skip_pager\n");
fflush(stderr); */
xa = ATOM(_NET_WM_STATE);
if (xa != None) {
Atom xa_prop = ATOM(_NET_WM_STATE_SKIP_PAGER);
XChangeProperty(display, window.window, xa,
XA_ATOM, 32,
PropModeAppend,
(unsigned char *) &xa_prop,
1);
}
}
XChangeProperty(display, window.window, xa, XA_ATOM, 32,
PropModeAppend, (unsigned char *) &xa_prop, 1);
}
}
} /* else { window.type != TYPE_OVERRIDE */
fprintf(stderr, "Conky: drawing to created window (%lx)\n", window.window);
fprintf(stderr, "Conky: drawing to created window (%lx)\n",
window.window);
fflush(stderr);
XMapWindow(display, window.window);
} else /* if (own_window) { */
#endif
/* root / desktop window */
{
XWindowAttributes attrs;
if (!window.window)
window.window = find_desktop_window( &window.root, &window.desktop );
if (!window.window) {
window.window = find_desktop_window(&window.root, &window.desktop);
}
if (XGetWindowAttributes(display, window.window, &attrs)) {
window.width = attrs.width;
@@ -460,44 +432,46 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour,
#ifdef HAVE_XDBE
if (use_xdbe) {
int major, minor;
if (!XdbeQueryExtension(display, &major, &minor)) {
use_xdbe = 0;
} else {
window.back_buffer =
XdbeAllocateBackBufferName(display,
window.window,
XdbeBackground);
window.back_buffer = XdbeAllocateBackBufferName(display,
window.window, XdbeBackground);
if (window.back_buffer != None) {
window.drawable = window.back_buffer;
fprintf(stderr,
"Conky: drawing to double buffer\n");
} else
fprintf(stderr, "Conky: drawing to double buffer\n");
} else {
use_xdbe = 0;
}
if (!use_xdbe)
}
if (!use_xdbe) {
ERR("failed to set up double buffer");
}
if (!use_xdbe)
}
if (!use_xdbe) {
fprintf(stderr, "Conky: drawing to single buffer\n");
}
#endif
XFlush(display);
/*set_transparent_background(window.window); must be done after double buffer stuff? */
/* set_transparent_background(window.window);
* must be done after double buffer stuff? */
#ifdef OWN_WINDOW
/*if (own_window) {
/* if (own_window) {
set_transparent_background(window.window);
XClearWindow(display, window.window);
}*/
} */
#endif
XSelectInput(display, window.window, ExposureMask
#ifdef OWN_WINDOW
| (own_window
? (StructureNotifyMask | PropertyChangeMask |
ButtonPressMask | ButtonReleaseMask) : 0)
XSelectInput(display, window.window, ExposureMask |
(own_window ? (StructureNotifyMask | PropertyChangeMask |
ButtonPressMask | ButtonReleaseMask) : 0));
#else
XSelectInput(display, window.window, ExposureMask);
#endif
);
}
static Window find_subwindow(Window win, int w, int h)
@@ -514,14 +488,12 @@ static Window find_subwindow(Window win, int w, int h)
for (j = 0; j < n; j++) {
XWindowAttributes attrs;
if (XGetWindowAttributes
(display, children[j], &attrs)) {
/* Window must be mapped and same size as display or work space */
if (attrs.map_state != 0 &&
((attrs.width == display_width
if (XGetWindowAttributes(display, children[j], &attrs)) {
/* Window must be mapped and same size as display or
* work space */
if (attrs.map_state != 0 && ((attrs.width == display_width
&& attrs.height == display_height)
|| (attrs.width == w
&& attrs.height == h))) {
|| (attrs.width == w && attrs.height == h))) {
win = children[j];
break;
}
@@ -529,9 +501,10 @@ static Window find_subwindow(Window win, int w, int h)
}
XFree(children);
if (j == n)
if (j == n) {
break;
}
}
return win;
}
@@ -539,24 +512,25 @@ static Window find_subwindow(Window win, int w, int h)
long get_x11_color(const char *name)
{
XColor color;
color.pixel = 0;
if (!XParseColor
(display, DefaultColormap(display, screen), name, &color)) {
if (!XParseColor(display, DefaultColormap(display, screen), name, &color)) {
/* lets check if it's a hex colour with the # missing in front
* if yes, then do something about it
*/
* if yes, then do something about it */
char newname[64];
newname[0] = '#';
strncpy(&newname[1], name, 62);
/* now lets try again */
if (!XParseColor(display, DefaultColormap(display, screen), &newname[0], &color)) {
if (!XParseColor(display, DefaultColormap(display, screen), &newname[0],
&color)) {
ERR("can't parse X color '%s'", name);
return 0xFF00FF;
}
}
if (!XAllocColor
(display, DefaultColormap(display, screen), &color))
if (!XAllocColor(display, DefaultColormap(display, screen), &color)) {
ERR("can't allocate X color '%s'", name);
}
return (long) color.pixel;
}
@@ -564,6 +538,7 @@ long get_x11_color(const char *name)
void create_gc()
{
XGCValues values;
values.graphics_exposures = 0;
values.function = GXcopy;
window.gc = XCreateGC(display, window.drawable,

View File

@@ -1,5 +1,4 @@
/*
* Conky, a system monitor, based on torsmo
/* Conky, a system monitor, based on torsmo
*
* Any original torsmo code is licensed under the BSD license
*
@@ -7,7 +6,8 @@
*
* Please see COPYING for details
*
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
* Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
@@ -22,8 +22,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*/
* $Id$ */
#include "conky.h"
#include <stdio.h>
@@ -90,7 +89,8 @@ static void xmms_alloc(struct information *ptr)
}
}
static void xmms_clear(struct information *ptr) {
static void xmms_clear(struct information *ptr)
{
xmms_alloc(ptr);
ptr->xmms2.status[0] = '\0';
ptr->xmms2.artist[0] = '\0';
@@ -107,6 +107,7 @@ static void xmms_clear(struct information *ptr) {
void connection_lost(void *p)
{
struct information *ptr = p;
ptr->xmms2_conn_state = CONN_NO;
xmms_clear(ptr);
@@ -124,132 +125,134 @@ void handle_curent_id(xmmsc_result_t *res, void *p)
uint current_id;
struct information *ptr = p;
if ( xmmsc_result_get_uint( res, &current_id ) ) {
if (xmmsc_result_get_uint(res, &current_id)) {
xmmsc_result_t *res2;
res2 = xmmsc_medialib_get_info(ptr->xmms2_conn, current_id);
xmmsc_result_wait( res2 );
xmmsc_result_wait(res2);
xmms_clear(ptr);
ptr->xmms2.id = current_id;
char *temp;
xmmsc_result_get_dict_entry_string( res2, "artist", &temp );
if ( temp != NULL ) {
xmmsc_result_get_dict_entry_string(res2, "artist", &temp);
if (temp != NULL) {
strncpy(ptr->xmms2.artist, temp, TEXT_BUFFER_SIZE - 1);
} else {
strncpy(ptr->xmms2.artist, "[Unknown]", TEXT_BUFFER_SIZE - 1);
}
xmmsc_result_get_dict_entry_string( res2, "title", &temp );
if ( temp != NULL ) {
xmmsc_result_get_dict_entry_string(res2, "title", &temp);
if (temp != NULL) {
strncpy(ptr->xmms2.title, temp, TEXT_BUFFER_SIZE - 1);
} else {
strncpy(ptr->xmms2.title, "[Unknown]", TEXT_BUFFER_SIZE - 1);
}
xmmsc_result_get_dict_entry_string( res2, "album", &temp );
if ( temp != NULL ) {
xmmsc_result_get_dict_entry_string(res2, "album", &temp);
if (temp != NULL) {
strncpy(ptr->xmms2.album, temp, TEXT_BUFFER_SIZE - 1);
} else {
strncpy(ptr->xmms2.album, "[Unknown]", TEXT_BUFFER_SIZE - 1);
}
xmmsc_result_get_dict_entry_string( res2, "genre", &temp );
if ( temp != NULL ) {
xmmsc_result_get_dict_entry_string(res2, "genre", &temp);
if (temp != NULL) {
strncpy(ptr->xmms2.genre, temp, TEXT_BUFFER_SIZE - 1);
} else {
strncpy(ptr->xmms2.genre, "[Unknown]", TEXT_BUFFER_SIZE - 1);
}
xmmsc_result_get_dict_entry_string( res2, "comment", &temp );
if ( temp != NULL ) {
xmmsc_result_get_dict_entry_string(res2, "comment", &temp);
if (temp != NULL) {
strncpy(ptr->xmms2.comment, temp, TEXT_BUFFER_SIZE - 1);
} else {
strncpy(ptr->xmms2.comment, "", TEXT_BUFFER_SIZE - 1);
}
xmmsc_result_get_dict_entry_string( res2, "decoder", &temp );
if ( temp != NULL ) {
xmmsc_result_get_dict_entry_string(res2, "decoder", &temp);
if (temp != NULL) {
strncpy(ptr->xmms2.decoder, temp, TEXT_BUFFER_SIZE - 1);
} else {
strncpy(ptr->xmms2.decoder, "[Unknown]", TEXT_BUFFER_SIZE - 1);
}
xmmsc_result_get_dict_entry_string( res2, "transport", &temp );
if ( temp != NULL ) {
xmmsc_result_get_dict_entry_string(res2, "transport", &temp);
if (temp != NULL) {
strncpy(ptr->xmms2.transport, temp, TEXT_BUFFER_SIZE - 1);
} else {
strncpy(ptr->xmms2.transport, "[Unknown]", TEXT_BUFFER_SIZE - 1);
}
xmmsc_result_get_dict_entry_string( res2, "url", &temp );
if ( temp != NULL ) {
xmmsc_result_get_dict_entry_string(res2, "url", &temp);
if (temp != NULL) {
strncpy(ptr->xmms2.url, temp, TEXT_BUFFER_SIZE - 1);
} else {
strncpy(ptr->xmms2.url, "[Unknown]", TEXT_BUFFER_SIZE - 1);
}
xmmsc_result_get_dict_entry_string( res2, "date", &temp );
if ( temp != NULL ) {
xmmsc_result_get_dict_entry_string(res2, "date", &temp);
if (temp != NULL) {
strncpy(ptr->xmms2.date, temp, TEXT_BUFFER_SIZE - 1);
} else {
strncpy(ptr->xmms2.date, "????", TEXT_BUFFER_SIZE - 1);
}
int itemp;
xmmsc_result_get_dict_entry_int( res2, "tracknr", &itemp );
xmmsc_result_get_dict_entry_int(res2, "tracknr", &itemp);
ptr->xmms2.tracknr = itemp;
xmmsc_result_get_dict_entry_int( res2, "duration", &itemp );
xmmsc_result_get_dict_entry_int(res2, "duration", &itemp);
ptr->xmms2.duration = itemp;
xmmsc_result_get_dict_entry_int( res2, "bitrate", &itemp );
xmmsc_result_get_dict_entry_int(res2, "bitrate", &itemp);
ptr->xmms2.bitrate = itemp / 1000;
xmmsc_result_get_dict_entry_int( res2, "size", &itemp );
ptr->xmms2.size = (float)itemp / 1048576;
xmmsc_result_get_dict_entry_int(res2, "size", &itemp);
ptr->xmms2.size = (float) itemp / 1048576;
xmmsc_result_unref( res2 );
xmmsc_result_unref(res2);
}
}
void handle_playtime(xmmsc_result_t *res, void *p) {
void handle_playtime(xmmsc_result_t *res, void *p)
{
struct information *ptr = p;
xmmsc_result_t * res2;
xmmsc_result_t *res2;
uint play_time;
if ( xmmsc_result_iserror( res ) )
if (xmmsc_result_iserror(res)) {
return;
}
if ( !xmmsc_result_get_uint( res, &play_time ) )
if (!xmmsc_result_get_uint(res, &play_time)) {
return;
}
res2 = xmmsc_result_restart( res );
xmmsc_result_unref( res2 );
res2 = xmmsc_result_restart(res);
xmmsc_result_unref(res2);
ptr->xmms2.elapsed = play_time;
ptr->xmms2.progress = (float) play_time / ptr->xmms2.duration;
}
void handle_playback_state_change(xmmsc_result_t *res, void *p) {
void handle_playback_state_change(xmmsc_result_t *res, void *p)
{
struct information *ptr = p;
uint pb_state = 0;
if ( xmmsc_result_iserror( res ) )
return;
if ( !xmmsc_result_get_uint( res, &pb_state ) )
if (xmmsc_result_iserror(res)) {
return;
}
if (!xmmsc_result_get_uint(res, &pb_state)) {
return;
}
switch (pb_state) {
case XMMS_PLAYBACK_STATUS_PLAY:
@@ -266,20 +269,21 @@ void handle_playback_state_change(xmmsc_result_t *res, void *p) {
}
}
void update_xmms2() {
struct information * current_info = &info;
void update_xmms2()
{
struct information *current_info = &info;
/* initialize connection */
if ( current_info->xmms2_conn_state == CONN_INIT ) {
if (current_info->xmms2_conn_state == CONN_INIT) {
if ( current_info->xmms2_conn == NULL ) {
current_info->xmms2_conn = xmmsc_init( "conky" );
if (current_info->xmms2_conn == NULL) {
current_info->xmms2_conn = xmmsc_init("conky");
}
/* did init fail? */
if ( current_info->xmms2_conn == NULL ) {
fprintf(stderr,"Conky: xmms2 init failed. %s\n", xmmsc_get_last_error ( current_info->xmms2_conn ));
if (current_info->xmms2_conn == NULL) {
fprintf(stderr, "Conky: xmms2 init failed. %s\n",
xmmsc_get_last_error(current_info->xmms2_conn));
fflush(stderr);
return;
}
@@ -298,69 +302,79 @@ void update_xmms2() {
current_info->xmms2.size = 0;
current_info->xmms2.progress = 0;
/* fprintf(stderr,"Conky: xmms2 init ok.\n");
/* fprintf(stderr, "Conky: xmms2 init ok.\n");
fflush(stderr); */
}
/* connect */
if ( current_info->xmms2_conn_state == CONN_NO ) {
if (current_info->xmms2_conn_state == CONN_NO) {
char *path = getenv ( "XMMS_PATH" );
if ( !xmmsc_connect( current_info->xmms2_conn, path ) ) {
fprintf(stderr,"Conky: xmms2 connection failed. %s\n",
xmmsc_get_last_error ( current_info->xmms2_conn ));
char *path = getenv("XMMS_PATH");
if (!xmmsc_connect(current_info->xmms2_conn, path)) {
fprintf(stderr, "Conky: xmms2 connection failed. %s\n",
xmmsc_get_last_error(current_info->xmms2_conn));
fflush(stderr);
current_info->xmms2_conn_state = CONN_NO;
return;
}
/* set callbacks */
xmmsc_disconnect_callback_set( current_info->xmms2_conn, connection_lost, current_info );
XMMS_CALLBACK_SET( current_info->xmms2_conn, xmmsc_playback_current_id, handle_curent_id, current_info );
XMMS_CALLBACK_SET( current_info->xmms2_conn, xmmsc_broadcast_playback_current_id, handle_curent_id, current_info );
XMMS_CALLBACK_SET( current_info->xmms2_conn, xmmsc_signal_playback_playtime, handle_playtime, current_info );
XMMS_CALLBACK_SET( current_info->xmms2_conn, xmmsc_broadcast_playback_status, handle_playback_state_change, current_info );
xmmsc_disconnect_callback_set(current_info->xmms2_conn, connection_lost,
current_info);
XMMS_CALLBACK_SET(current_info->xmms2_conn, xmmsc_playback_current_id,
handle_curent_id, current_info);
XMMS_CALLBACK_SET(current_info->xmms2_conn,
xmmsc_broadcast_playback_current_id, handle_curent_id,
current_info);
XMMS_CALLBACK_SET(current_info->xmms2_conn,
xmmsc_signal_playback_playtime, handle_playtime, current_info);
XMMS_CALLBACK_SET(current_info->xmms2_conn,
xmmsc_broadcast_playback_status, handle_playback_state_change,
current_info);
/* get playback status, it wont be broadcasted untill it chages */
xmmsc_result_t * res = xmmsc_playback_status( current_info->xmms2_conn );
xmmsc_result_wait ( res );
xmmsc_result_t *res = xmmsc_playback_status(current_info->xmms2_conn);
xmmsc_result_wait(res);
unsigned int pb_state;
xmmsc_result_get_uint( res, &pb_state );
xmmsc_result_get_uint(res, &pb_state);
switch (pb_state) {
case XMMS_PLAYBACK_STATUS_PLAY:
strncpy(current_info->xmms2.status,
"Playing", TEXT_BUFFER_SIZE - 1 );
strncpy(current_info->xmms2.status, "Playing",
TEXT_BUFFER_SIZE - 1);
break;
case XMMS_PLAYBACK_STATUS_PAUSE:
strncpy( current_info->xmms2.status,
"Paused", TEXT_BUFFER_SIZE - 1 );
strncpy(current_info->xmms2.status, "Paused",
TEXT_BUFFER_SIZE - 1);
break;
case XMMS_PLAYBACK_STATUS_STOP:
strncpy( current_info->xmms2.status,
"Stopped", TEXT_BUFFER_SIZE - 1 );
strncpy(current_info->xmms2.status, "Stopped",
TEXT_BUFFER_SIZE - 1);
break;
default:
strncpy( current_info->xmms2.status,
"Unknown", TEXT_BUFFER_SIZE - 1 );
strncpy(current_info->xmms2.status, "Unknown",
TEXT_BUFFER_SIZE - 1);
}
xmmsc_result_unref ( res );
xmmsc_result_unref(res);
/* everything seems to be ok */
current_info->xmms2_conn_state = CONN_OK;
/* fprintf(stderr,"Conky: xmms2 connected.\n");
/* fprintf(stderr, "Conky: xmms2 connected.\n");
fflush(stderr); */
}
/* handle callbacks */
if ( current_info->xmms2_conn_state == CONN_OK ) {
if (current_info->xmms2_conn_state == CONN_OK) {
struct timeval tmout;
tmout.tv_sec = 0;
tmout.tv_usec = 100;
select( current_info->xmms2_fd + 1, &current_info->xmms2_fdset, NULL, NULL, &tmout );
select(current_info->xmms2_fd + 1, &current_info->xmms2_fdset, NULL,
NULL, &tmout);
xmmsc_io_in_handle(current_info->xmms2_conn);
if (xmmsc_io_want_out(current_info->xmms2_conn)) {