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

View File

@@ -1,7 +1,6 @@
/* $Id$ */ /* $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 * 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 * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
* USA. * USA. */
*
*/
#ifndef AUDACIOUS_H #ifndef AUDACIOUS_H
#define AUDACIOUS_H #define AUDACIOUS_H
enum _audacious_items { enum _audacious_items {
AUDACIOUS_STATUS=0, AUDACIOUS_STATUS = 0,
AUDACIOUS_TITLE, AUDACIOUS_TITLE,
AUDACIOUS_LENGTH, AUDACIOUS_LENGTH,
AUDACIOUS_LENGTH_SECONDS, 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 * Any original torsmo code is licensed under the BSD license
* *
@@ -7,7 +6,8 @@
* *
* Please see COPYING for details * 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. * All rights reserved.
* *
* This program is free software: you can redistribute it and/or modify * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
* $Id$ * $Id$ */
*/
#include <bmp/dbus.hh> #include <bmp/dbus.hh>
#include <dbus/dbus-glib.h> #include <dbus/dbus-glib.h>
@@ -33,7 +32,8 @@
#include "conky.h" #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 DBusGConnection *bus;
static DBusGProxy *remote_object; static DBusGProxy *remote_object;
@@ -57,10 +57,8 @@ void update_bmpx()
goto fail; goto fail;
} }
remote_object = dbus_g_proxy_new_for_name(bus, remote_object = dbus_g_proxy_new_for_name(bus, BMP_DBUS_SERVICE,
BMP_DBUS_SERVICE, BMP_DBUS_PATH, BMP_DBUS_INTERFACE);
BMP_DBUS_PATH,
BMP_DBUS_INTERFACE);
if (!remote_object) { if (!remote_object) {
ERR("BMPx error 2: %s\n", error->message); ERR("BMPx error 2: %s\n", error->message);
goto fail; goto fail;
@@ -71,19 +69,15 @@ void update_bmpx()
if (connected == 1) { if (connected == 1) {
if (dbus_g_proxy_call(remote_object, "GetCurrentTrack", &error, if (dbus_g_proxy_call(remote_object, "GetCurrentTrack", &error,
G_TYPE_INVALID, G_TYPE_INVALID, G_TYPE_INT, &current_track, G_TYPE_INVALID)) {
G_TYPE_INT, &current_track, G_TYPE_INVALID)) {
} else { } else {
ERR("BMPx error 3: %s\n", error->message); ERR("BMPx error 3: %s\n", error->message);
goto fail; goto fail;
} }
if (dbus_g_proxy_call(remote_object, "GetMetadataForListItem", &error, if (dbus_g_proxy_call(remote_object, "GetMetadataForListItem", &error,
G_TYPE_INT, G_TYPE_INT, current_track, G_TYPE_INVALID,
current_track, DBUS_TYPE_G_STRING_VALUE_HASHTABLE, &metadata,
G_TYPE_INVALID,
DBUS_TYPE_G_STRING_VALUE_HASHTABLE,
&metadata,
G_TYPE_INVALID)) { G_TYPE_INVALID)) {
if (current_info->bmpx.title) { if (current_info->bmpx.title) {
free(current_info->bmpx.title); free(current_info->bmpx.title);
@@ -97,12 +91,18 @@ void update_bmpx()
free(current_info->bmpx.album); free(current_info->bmpx.album);
current_info->bmpx.album = 0; current_info->bmpx.album = 0;
} }
current_info->bmpx.title = g_value_dup_string(g_hash_table_lookup(metadata, "title")); current_info->bmpx.title =
current_info->bmpx.artist = g_value_dup_string(g_hash_table_lookup(metadata, "artist")); g_value_dup_string(g_hash_table_lookup(metadata, "title"));
current_info->bmpx.album = g_value_dup_string(g_hash_table_lookup(metadata, "album")); current_info->bmpx.artist =
current_info->bmpx.bitrate = g_value_get_int(g_hash_table_lookup(metadata, "bitrate")); g_value_dup_string(g_hash_table_lookup(metadata, "artist"));
current_info->bmpx.track = g_value_get_int(g_hash_table_lookup(metadata, "track-number")); current_info->bmpx.album =
current_info->bmpx.uri = g_value_get_string(g_hash_table_lookup(metadata, "location")); 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 { } else {
ERR("BMPx error 4: %s\n", error->message); ERR("BMPx error 4: %s\n", error->message);
goto fail; goto fail;
@@ -111,8 +111,9 @@ void update_bmpx()
g_hash_table_destroy(metadata); g_hash_table_destroy(metadata);
} else { } else {
fail: fail:
if (error) if (error) {
g_error_free(error); g_error_free(error);
}
if (current_info->bmpx.title) { if (current_info->bmpx.title) {
g_free(current_info->bmpx.title); g_free(current_info->bmpx.title);
current_info->bmpx.title = 0; 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 * Any original torsmo code is licensed under the BSD license
* *
@@ -8,7 +7,8 @@
* Please see COPYING for details * Please see COPYING for details
* *
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen * 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. * All rights reserved.
* *
* This program is free software: you can redistribute it and/or modify * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
* $Id$ * $Id$ */
*/
#include "conky.h" #include "conky.h"
#include <stdio.h> #include <stdio.h>
@@ -45,6 +44,7 @@ void update_uname()
double get_time() double get_time()
{ {
struct timeval tv; struct timeval tv;
gettimeofday(&tv, 0); gettimeofday(&tv, 0);
return tv.tv_sec + (tv.tv_usec / 1000000.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 *open_file(const char *file, int *reported)
{ {
FILE *fp = fopen(file, "r"); FILE *fp = fopen(file, "r");
if (!fp) { if (!fp) {
if (!reported || *reported == 0) { if (!reported || *reported == 0) {
ERR("can't open %s: %s", file, strerror(errno)); ERR("can't open %s: %s", file, strerror(errno));
if (reported) if (reported) {
*reported = 1; *reported = 1;
} }
}
return 0; return 0;
} }
@@ -78,30 +80,33 @@ void variable_substitute(const char *s, char *dest, unsigned int n)
if (*s == '{') { if (*s == '{') {
s++; s++;
a = s; a = s;
while (*s && *s != '}') while (*s && *s != '}') {
s++; s++;
}
} else { } else {
a = s; a = s;
while (*s && (isalnum((int) *s) while (*s && (isalnum((int) *s) || *s == '_')) {
|| *s == '_'))
s++; s++;
} }
}
/* copy variable to buffer and look it up */ /* copy variable to buffer and look it up */
len = (s - a > 255) ? 255 : (s - a); len = (s - a > 255) ? 255 : (s - a);
strncpy(buf, a, len); strncpy(buf, a, len);
buf[len] = '\0'; buf[len] = '\0';
if (*s == '}') if (*s == '}') {
s++; s++;
}
var = getenv(buf); var = getenv(buf);
if (var) { if (var) {
/* add var to dest */ /* add var to dest */
len = strlen(var); len = strlen(var);
if (len >= n) if (len >= n) {
len = n - 1; len = n - 1;
}
strncpy(dest, var, len); strncpy(dest, var, len);
dest += len; dest += len;
n -= len; n -= len;
@@ -125,14 +130,16 @@ struct net_stat *get_net_stat(const char *dev)
{ {
unsigned int i; unsigned int i;
if (!dev) if (!dev) {
return 0; return 0;
}
/* find interface stat */ /* find interface stat */
for (i = 0; i < 16; i++) { 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]; return &netstats[i];
} }
}
/* wasn't found? add it */ /* wasn't found? add it */
if (i == 16) { if (i == 16) {
@@ -148,51 +155,53 @@ struct net_stat *get_net_stat(const char *dev)
return 0; 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) void format_seconds(char *buf, unsigned int n, long t)
{ {
if (t >= 24 * 60 * 60) /* hours necessary when there are days? */ if (t >= 24 * 60 * 60) { /* hours necessary when there are days? */
snprintf(buf, n, "%ldd %ldh %ldm", t / 60 / 60 / 24, snprintf(buf, n, "%ldd %ldh %ldm", t / 60 / 60 / 24, (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,
(t / 60) % 60); (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); snprintf(buf, n, "%ldm %lds", t / 60, t % 60);
}
} }
void format_seconds_short(char *buf, unsigned int n, long t) void format_seconds_short(char *buf, unsigned int n, long t)
{ {
if (t >= 24 * 60 * 60) if (t >= 24 * 60 * 60) {
snprintf(buf, n, "%ldd %ldh", t / 60 / 60 / 24, snprintf(buf, n, "%ldd %ldh", t / 60 / 60 / 24, (t / 60 / 60) % 24);
(t / 60 / 60) % 24); } else if (t >= 60 * 60) {
else if (t >= 60 * 60) snprintf(buf, n, "%ldh %ldm", (t / 60 / 60) % 24, (t / 60) % 60);
snprintf(buf, n, "%ldh %ldm", (t / 60 / 60) % 24, } else {
(t / 60) % 60);
else
snprintf(buf, n, "%ldm", t / 60); snprintf(buf, n, "%ldm", t / 60);
}
} }
static double last_meminfo_update; static double last_meminfo_update;
static double last_fs_update; static double last_fs_update;
unsigned long long need_mask; unsigned long long need_mask;
#define NEED(a) ((need_mask & (1 << a)) && ((info.mask & (1 << a)) == 0)) #define NEED(a) ((need_mask & (1 << a)) && ((info.mask & (1 << a)) == 0))
void update_stuff() void update_stuff()
{ {
unsigned int i; unsigned int i;
info.mask = 0; info.mask = 0;
if (no_buffers) if (no_buffers) {
need_mask |= 1 << INFO_BUFFERS; need_mask |= 1 << INFO_BUFFERS;
}
/* clear speeds and up status in case device was removed and doesn't get /* clear speeds and up status in case device was removed and doesn't get
updated */ * updated */
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
if (netstats[i].dev) { if (netstats[i].dev) {
@@ -204,66 +213,77 @@ void update_stuff()
prepare_update(); prepare_update();
if (NEED(INFO_UPTIME)) if (NEED(INFO_UPTIME)) {
update_uptime(); update_uptime();
}
if (NEED(INFO_PROCS)) if (NEED(INFO_PROCS)) {
update_total_processes(); update_total_processes();
}
if (NEED(INFO_RUN_PROCS)) if (NEED(INFO_RUN_PROCS)) {
update_running_processes(); update_running_processes();
}
if (NEED(INFO_CPU)) if (NEED(INFO_CPU)) {
update_cpu_usage(); update_cpu_usage();
}
if (NEED(INFO_NET)) if (NEED(INFO_NET)) {
update_net_stats(); update_net_stats();
}
if (NEED(INFO_DISKIO)) if (NEED(INFO_DISKIO)) {
update_diskio(); update_diskio();
}
#if defined(__linux__) #if defined(__linux__)
if (NEED(INFO_I8K)) if (NEED(INFO_I8K)) {
update_i8k(); update_i8k();
}
#endif /* __linux__ */ #endif /* __linux__ */
#ifdef MPD #ifdef MPD
if (NEED(INFO_MPD)) { if (NEED(INFO_MPD)) {
if (!mpd_timed_thread) { if (!mpd_timed_thread) {
init_mpd_stats(&info); init_mpd_stats(&info);
mpd_timed_thread = mpd_timed_thread = timed_thread_create((void *) update_mpd,
timed_thread_create((void*)update_mpd, (void*) NULL, info.music_player_interval * 1000000); (void *) NULL, info.music_player_interval * 1000000);
if (!mpd_timed_thread) { if (!mpd_timed_thread) {
ERR("Failed to create MPD timed thread"); ERR("Failed to create MPD timed thread");
} }
timed_thread_register(mpd_timed_thread, &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"); ERR("Failed to run MPD timed thread");
} }
} }
}
#endif #endif
#ifdef XMMS2 #ifdef XMMS2
if (NEED(INFO_XMMS2)) if (NEED(INFO_XMMS2)) {
update_xmms2(); update_xmms2();
}
#endif #endif
#ifdef AUDACIOUS #ifdef AUDACIOUS
if (NEED(INFO_AUDACIOUS)) if (NEED(INFO_AUDACIOUS)) {
update_audacious(); update_audacious();
}
#endif #endif
#ifdef BMPX #ifdef BMPX
if (NEED(INFO_BMPX)) if (NEED(INFO_BMPX)) {
update_bmpx(); update_bmpx();
}
#endif #endif
if (NEED(INFO_LOADAVG)) if (NEED(INFO_LOADAVG)) {
update_load_average(); update_load_average();
}
if ((NEED(INFO_MEM) || NEED(INFO_BUFFERS) || NEED(INFO_TOP))
if ((NEED(INFO_MEM) || NEED(INFO_BUFFERS) || NEED(INFO_TOP)) && && current_update_time - last_meminfo_update > 6.9) {
current_update_time - last_meminfo_update > 6.9) {
update_meminfo(); update_meminfo();
if (no_buffers) { if (no_buffers) {
info.mem -= info.bufmem; info.mem -= info.bufmem;
@@ -271,8 +291,9 @@ void update_stuff()
last_meminfo_update = current_update_time; last_meminfo_update = current_update_time;
} }
if (NEED(INFO_TOP)) if (NEED(INFO_TOP)) {
update_top(); update_top();
}
/* update_fs_stat() won't do anything if there aren't fs -things */ /* 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) { 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; last_fs_update = current_update_time;
} }
#ifdef TCP_PORT_MONITOR #ifdef TCP_PORT_MONITOR
if (NEED(INFO_TCP_PORT_MONITOR)) if (NEED(INFO_TCP_PORT_MONITOR)) {
update_tcp_port_monitor_collection( info.p_tcp_port_monitor_collection ); update_tcp_port_monitor_collection(info.p_tcp_port_monitor_collection);
}
#endif #endif
if (NEED(INFO_ENTROPY)) if (NEED(INFO_ENTROPY)) {
update_entropy(); update_entropy();
}
} }
int round_to_int(float f) 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 * Any original torsmo code is licensed under the BSD license
* *
@@ -8,7 +7,8 @@
* Please see COPYING for details * Please see COPYING for details
* *
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen * 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. * All rights reserved.
* *
* This program is free software: you can redistribute it and/or modify * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
* $Id$ * $Id$ */
*/
#ifndef _conky_h_ #ifndef _conky_h_
#define _conky_h_ #define _conky_h_
@@ -32,6 +31,7 @@
#if defined(HAS_MCHECK_H) #if defined(HAS_MCHECK_H)
#include <mcheck.h> #include <mcheck.h>
#endif /* HAS_MCHECK_H */ #endif /* HAS_MCHECK_H */
#include "config.h" #include "config.h"
#include <sys/utsname.h> #include <sys/utsname.h>
#include <stdio.h> #include <stdio.h>
@@ -41,15 +41,15 @@
#include <langinfo.h> #include <langinfo.h>
#include <wchar.h> #include <wchar.h>
#include <sys/param.h> #include <sys/param.h>
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/ucred.h> #include <sys/ucred.h>
#include <fcntl.h> #include <fcntl.h>
#include <kvm.h> #include <kvm.h>
#endif /* __FreeBSD__ */ #if (defined(i386) || defined(__i386__))
#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) && (defined(i386) || defined(__i386__))
#include <machine/apm_bios.h> #include <machine/apm_bios.h>
#endif /* i386 || __i386__ */
#endif /* __FreeBSD__ */ #endif /* __FreeBSD__ */
#if defined(__OpenBSD__) #if defined(__OpenBSD__)
@@ -91,12 +91,11 @@ extern unsigned int text_buffer_size;
#include <sys/socket.h> #include <sys/socket.h>
#define ERR(s, varargs...) \ #define ERR(s, varargs...) fprintf(stderr, "Conky: " s "\n", ##varargs)
fprintf(stderr, "Conky: " s "\n", ##varargs)
/* critical error */ /* critical error */
#define CRIT_ERR(s, varargs...) \ #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 { struct i8k_struct {
char *version; char *version;
@@ -160,10 +159,10 @@ struct mail_s { // for imap and pop3
char secure; char secure;
} mail; } mail;
/*struct cpu_stat { /* struct cpu_stat {
unsigned int user, nice, system, idle, iowait, irq, softirq; unsigned int user, nice, system, idle, iowait, irq, softirq;
int cpu_avg_samples; int cpu_avg_samples;
};*/ }; */
#ifdef MPD #ifdef MPD
struct mpd_s { struct mpd_s {
@@ -191,15 +190,15 @@ struct mpd_s {
#ifdef XMMS2 #ifdef XMMS2
struct xmms2_s { struct xmms2_s {
char* artist; char *artist;
char* album; char *album;
char* title; char *title;
char* genre; char *genre;
char* comment; char *comment;
char* decoder; char *decoder;
char* transport; char *transport;
char* url; char *url;
char* date; char *date;
int tracknr; int tracknr;
int bitrate; int bitrate;
unsigned int id; unsigned int id;
@@ -208,7 +207,7 @@ struct xmms2_s {
float size; float size;
float progress; float progress;
char* status; char *status;
}; };
#endif #endif
@@ -283,7 +282,6 @@ enum {
#endif #endif
}; };
/* get_battery_stuff() item selector */ /* get_battery_stuff() item selector */
enum { enum {
BATTERY_STATUS, BATTERY_STATUS,
@@ -324,7 +322,7 @@ struct information {
float loadavg[3]; float loadavg[3];
struct mail_s* mail; struct mail_s *mail;
int mail_running; int mail_running;
#ifdef MPD #ifdef MPD
struct mpd_s mpd; struct mpd_s mpd;
@@ -348,7 +346,7 @@ struct information {
struct process *first_process; struct process *first_process;
unsigned long looped; unsigned long looped;
#ifdef TCP_PORT_MONITOR #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 #endif
struct entropy_s entropy; struct entropy_s entropy;
double music_player_interval; double music_player_interval;
@@ -357,17 +355,20 @@ struct information {
}; };
enum { enum {
KFLAG_IS_LONGSTAT = 0x01, /* set to true if kernel uses "long" format for /proc/stats */ /* 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_IS_LONGSTAT = 0x01,
/* KFLAG_NEXT_ONE=0x04 bits 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 available for future use */ /* 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_SETON(a) info.kflags |= a
#define KFLAG_SETOFF(a) info.kflags &= (~a) #define KFLAG_SETOFF(a) info.kflags &= (~a)
#define KFLAG_FLIP(a) info.kflags ^= a #define KFLAG_FLIP(a) info.kflags ^= a
#define KFLAG_ISSET(a) info.kflags & a #define KFLAG_ISSET(a) info.kflags & a
int out_to_console; int out_to_console;
int top_cpu; int top_cpu;
@@ -412,11 +413,13 @@ enum _window_hints {
HINT_SKIP_TASKBAR, HINT_SKIP_TASKBAR,
HINT_SKIP_PAGER 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 #endif
struct conky_window { struct conky_window {
Window root,window,desktop; Window root, window, desktop;
Drawable drawable; Drawable drawable;
GC gc; GC gc;
#ifdef HAVE_XDBE #ifdef HAVE_XDBE
@@ -442,7 +445,6 @@ struct conky_window {
extern int use_xdbe; extern int use_xdbe;
#endif #endif
#ifdef XFT #ifdef XFT
extern int use_xft; extern int use_xft;
#endif #endif
@@ -457,8 +459,8 @@ extern int workarea[4];
extern struct conky_window window; extern struct conky_window window;
void init_X11(); void init_X11();
void init_window(int use_own_window, int width, int height, int set_trans, int back_colour, void init_window(int use_own_window, int width, int height, int set_trans,
char **argv, int argc); int back_colour, char **argv, int argc);
void create_gc(); void create_gc();
void set_transparent_background(Window win); void set_transparent_background(Window win);
long get_x11_color(const char *); long get_x11_color(const char *);
@@ -508,31 +510,31 @@ void update_cpu_usage(void);
void update_total_processes(void); void update_total_processes(void);
void update_running_processes(void); void update_running_processes(void);
void update_i8k(void); void update_i8k(void);
char get_freq( char *, size_t, char *, int, unsigned int ); char get_freq(char *, size_t, char *, int, unsigned int);
void get_freq_dynamic( char *, size_t, char *, int ); void get_freq_dynamic(char *, size_t, char *, int);
char get_voltage(char *, size_t, char *, int, unsigned int ); /* ptarjan */ char get_voltage(char *, size_t, char *, int, unsigned int); /* ptarjan */
void update_load_average(); void update_load_average();
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,
#define open_i2c_sensor(dev,type,n,div,devtype) \ int *div, char *devtype);
open_sysfs_sensor("/sys/bus/i2c/devices/",dev,type,n,div,devtype)
#define open_platform_sensor(dev,type,n,div,devtype) \ #define open_i2c_sensor(dev, type, n, div, devtype) \
open_sysfs_sensor("/sys/bus/platform/devices/",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) \
#define open_hwmon_sensor(dev,type,n,div,devtype) \ open_sysfs_sensor("/sys/bus/platform/devices/", dev, type, n, div, devtype)
open_sysfs_sensor("/sys/class/hwmon/",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); double get_sysfs_info(int *fd, int arg, char *devtype, char *type);
void get_adt746x_cpu( char *, size_t ); void get_adt746x_cpu(char *, size_t);
void get_adt746x_fan( char *, size_t ); void get_adt746x_fan(char *, size_t);
unsigned int get_diskio(void); unsigned int get_diskio(void);
int open_acpi_temperature(const char *name); int open_acpi_temperature(const char *name);
double get_acpi_temperature(int fd); double get_acpi_temperature(int fd);
void get_acpi_ac_adapter( char *, size_t ); void get_acpi_ac_adapter(char *, size_t);
void get_acpi_fan( char *, size_t ); void get_acpi_fan(char *, size_t);
void get_battery_stuff(char *buf, unsigned int n, const char *bat, int item); 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(const char *bat);
int get_battery_perct_bar(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; struct obsd_sensors_struct obsd_sensors;
#endif /* __OpenBSD__ */ #endif /* __OpenBSD__ */
enum { PB_BATT_STATUS, PB_BATT_PERCENT, PB_BATT_TIME };
enum { PB_BATT_STATUS, PB_BATT_PERCENT, PB_BATT_TIME}; void get_powerbook_batt_info(char *, size_t, int);
void get_powerbook_batt_info(char*, size_t, int);
struct process { struct process {
struct process *next; struct process *next;
@@ -625,7 +626,8 @@ void update_mail_count();
kvm_t *kd; kvm_t *kd;
#endif #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__ #ifdef __OpenBSD__
typedef struct apm_power_info *apm_info_t; typedef struct apm_power_info *apm_info_t;
#endif #endif
@@ -655,7 +657,7 @@ char *get_hddtemp_info(char *dev, char *addr, int port, char *unit);
/* in rss.c */ /* in rss.c */
#ifdef RSS #ifdef RSS
PRSS* get_rss_info(char *uri, int delay); PRSS *get_rss_info(char *uri, int delay);
void init_rss_info(); void init_rss_info();
void free_rss_info(); void free_rss_info();
#endif /* RSS */ #endif /* RSS */
@@ -663,5 +665,3 @@ void free_rss_info();
/* in linux.c */ /* in linux.c */
#endif #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 * Any original torsmo code is licensed under the BSD license
* *
@@ -8,7 +7,8 @@
* Please see COPYING for details * Please see COPYING for details
* *
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen * 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. * All rights reserved.
* *
* This program is free software: you can redistribute it and/or modify * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
* $Id$ * $Id$ */
*/
#include "conky.h" #include "conky.h"
#include <unistd.h> #include <unistd.h>
@@ -52,40 +51,48 @@
static struct fs_stat fs_stats_[MAX_FS_STATS]; static struct fs_stat fs_stats_[MAX_FS_STATS];
struct fs_stat *fs_stats = 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() void update_fs_stats()
{ {
unsigned i; 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]); update_fs_stat(&fs_stats[i]);
}
}
} }
void clear_fs_stats() void clear_fs_stats()
{ {
unsigned i; 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); 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 *prepare_fs_stat(const char *s)
{ {
struct fs_stat* new = 0; struct fs_stat *new = 0;
unsigned i; unsigned i;
/* lookup existing or get new */ /* lookup existing or get new */
for(i=0; i<MAX_FS_STATS; ++i) { for (i = 0; i < MAX_FS_STATS; ++i) {
if(fs_stats[i].path) { if (fs_stats[i].path) {
if(strcmp(fs_stats[i].path, s) == 0) if (strcmp(fs_stats[i].path, s) == 0) {
return &fs_stats[i]; return &fs_stats[i];
} else }
} else {
new = &fs_stats[i]; new = &fs_stats[i];
} }
}
/* new path */ /* new path */
if(!new) { if (!new) {
ERR("too many fs stats"); ERR("too many fs stats");
return 0; return 0;
} }
@@ -94,14 +101,14 @@ struct fs_stat *prepare_fs_stat(const char *s)
return new; return new;
} }
static static void update_fs_stat(struct fs_stat *fs)
void update_fs_stat(struct fs_stat* fs)
{ {
struct statfs s; 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; fs->size = (long long) s.f_blocks * s.f_bsize;
/* bfree (root) or bavail (non-roots) ? */ /* 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; fs->free = (long long) s.f_bfree * s.f_bsize;
} else { } else {
fs->size = 0; 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 * Any original torsmo code is licensed under the BSD license
* *
@@ -8,7 +7,8 @@
* Please see COPYING for details * Please see COPYING for details
* *
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen * 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. * All rights reserved.
* *
* This program is free software: you can redistribute it and/or modify * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
* $Id$ * $Id$ */
*/
#include "conky.h" #include "conky.h"
#include <errno.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); ret = sscanf(arg, "%31s %63s %d", buf1, buf2, &n);
if (ret < 1) if (ret < 1) {
return -1; return -1;
}
*dev = strdup(buf1); *dev = strdup(buf1);
if (ret >= 2) if (ret >= 2) {
*addr = strdup(buf2); *addr = strdup(buf2);
else } else {
*addr = strdup("127.0.0.1"); *addr = strdup("127.0.0.1");
}
if (ret == 3) if (ret == 3) {
*port = n; *port = n;
else } else {
*port = PORT; *port = PORT;
}
return 0; 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_family = AF_INET;
addr.sin_port = htons(port); 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); 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"); perror("connect");
goto out; goto out;
} }
@@ -102,29 +105,30 @@ char *get_hddtemp_info(char *dev, char *hostaddr, int port, char *unit)
FD_ZERO(&rfds); FD_ZERO(&rfds);
FD_SET(sockfd, &rfds); FD_SET(sockfd, &rfds);
/* We're going to wait up to a quarter a second to see whether /* We're going to wait up to a quarter a second to see whether there's
* there's any data available. Polling with timeout set to 0 * any data available. Polling with timeout set to 0 doesn't seem to work
* doesn't seem to work with hddtemp. */ * with hddtemp. */
tv.tv_sec = 0; tv.tv_sec = 0;
tv.tv_usec = 250000; tv.tv_usec = 250000;
i = select(sockfd+1, &rfds, NULL, NULL, &tv); i = select(sockfd + 1, &rfds, NULL, NULL, &tv);
if (i == -1) if (i == -1) {
{ if (errno == EINTR) { /* silently ignore interrupted system call */
if (errno == EINTR) /* silently ignore interrupted system call */
goto out; goto out;
else } else {
perror("select"); perror("select");
} }
}
/* No data available */ /* No data available */
if (i <= 0) if (i <= 0) {
goto out; goto out;
}
p = buf; p = buf;
len = 0; len = 0;
do { do {
i = recv(sockfd, p, BUFLEN - (p-buf), 0); i = recv(sockfd, p, BUFLEN - (p - buf), 0);
if (i < 0) { if (i < 0) {
perror("recv"); perror("recv");
goto out; 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. */ /* The first character read is the separator. */
sep = buf[0]; sep = buf[0];
p = buf+1; p = buf + 1;
while (*p) { while (*p) {
if (!strncmp(p, dev, devlen)) { if (!strncmp(p, dev, devlen)) {
p += devlen + 1; p += devlen + 1;
p = strchr(p, sep); p = strchr(p, sep);
if (!p) if (!p) {
goto out; goto out;
}
p++; p++;
out = p; out = p;
p = strchr(p, sep); p = strchr(p, sep);
if (!p) if (!p) {
goto out; goto out;
}
*p = '\0'; *p = '\0';
p++; p++;
*unit = *p; *unit = *p;
@@ -167,13 +173,14 @@ char *get_hddtemp_info(char *dev, char *hostaddr, int port, char *unit)
} else { } else {
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++) {
p = strchr(p, sep); p = strchr(p, sep);
if (!p) if (!p) {
goto out; goto out;
}
p++; p++;
} }
} }
} }
out: close(sockfd); out:
close(sockfd);
return r; return r;
} }

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@@ -1,7 +1,6 @@
/* $Id$ */ /* $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 * 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 * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
* USA. * USA. */
*
*/
#ifndef LIBTCP_PORTMON_H #ifndef LIBTCP_PORTMON_H
#define LIBTCP_PORTMON_H #define LIBTCP_PORTMON_H
@@ -40,7 +37,8 @@
#include <glib.h> #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_CONNECTION_HASH_KEY_SIZE 28
#define TCP_PORT_MONITOR_HASH_KEY_SIZE 12 #define TCP_PORT_MONITOR_HASH_KEY_SIZE 12
@@ -54,7 +52,7 @@
/* The inventory of peekable items within the port monitor. */ /* The inventory of peekable items within the port monitor. */
enum tcp_port_monitor_peekables { enum tcp_port_monitor_peekables {
COUNT=0, COUNT = 0,
REMOTEIP, REMOTEIP,
REMOTEHOST, REMOTEHOST,
REMOTEPORT, REMOTEPORT,
@@ -72,7 +70,8 @@ enum tcp_port_monitor_peekables {
* are not seen again in subsequent update cycles. * are not seen again in subsequent update cycles.
* ------------------------------------------------------------------------ */ * ------------------------------------------------------------------------ */
typedef struct _tcp_connection_t { 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_addr_t local_addr;
in_port_t local_port; in_port_t local_port;
in_addr_t remote_addr; in_addr_t remote_addr;
@@ -84,98 +83,99 @@ typedef struct _tcp_connection_t {
* Copy a connection * Copy a connection
* *
* Returns 0 on success, -1 otherwise * Returns 0 on success, -1 otherwise
* ----------------------------------*/ * ---------------------------------- */
int copy_tcp_connection( int copy_tcp_connection(tcp_connection_t *p_dest_connection,
tcp_connection_t * /* p_dest_connection */, const tcp_connection_t *p_source_connection);
const tcp_connection_t * /* p_source_connection */
);
/* ------------------------------------------------------------------------ /* -------------------------------------------------------------------
* A tcp connection node/list * A tcp connection node/list
* *
* Connections within each monitor are stored in a double-linked list. * Connections within each monitor are stored in a double-linked list.
* ------------------------------------------------------------------------ */ * ------------------------------------------------------------------- */
typedef struct _tcp_connection_node_t { typedef struct _tcp_connection_node_t {
tcp_connection_t connection; tcp_connection_t connection;
struct _tcp_connection_node_t * p_prev; struct _tcp_connection_node_t *p_prev;
struct _tcp_connection_node_t * p_next; struct _tcp_connection_node_t *p_next;
} tcp_connection_node_t; } tcp_connection_node_t;
typedef struct _tcp_connection_list_t { typedef struct _tcp_connection_list_t {
tcp_connection_node_t * p_head; tcp_connection_node_t *p_head;
tcp_connection_node_t * p_tail; tcp_connection_node_t *p_tail;
} tcp_connection_list_t; } tcp_connection_list_t;
/* -------------- /* --------------
* A port monitor * A port monitor
* -------------- */ * -------------- */
typedef struct _tcp_port_monitor_t { typedef struct _tcp_port_monitor_t {
gchar key[TCP_PORT_MONITOR_HASH_KEY_SIZE]; /* monitor's key in collection hash */ /* monitor's key in collection hash */
in_port_t port_range_begin; /* start of monitor port range */ gchar key[TCP_PORT_MONITOR_HASH_KEY_SIZE];
in_port_t port_range_end; /* begin = end to monitor a single port */ /* start of monitor port range */
tcp_connection_list_t connection_list; /* list of connections for this monitor */ in_port_t port_range_begin;
GHashTable *hash; /* hash table of pointers into connection list */ /* begin = end to monitor a single port */
tcp_connection_t **p_peek; /* array of connection pointers for O(1) peeking */ in_port_t port_range_end;
unsigned int max_port_monitor_connections; /* max number of connections */ /* 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; } tcp_port_monitor_t;
/* ------------------------ /* ------------------------
* A port monitor node/list * A port monitor node/list
* ------------------------ */ * ------------------------ */
typedef struct _tcp_port_monitor_node_t { 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; struct _tcp_port_monitor_node_t *p_next;
} tcp_port_monitor_node_t; } tcp_port_monitor_node_t;
typedef struct __tcp_port_monitor_list_t { typedef struct __tcp_port_monitor_list_t {
tcp_port_monitor_node_t * p_head; tcp_port_monitor_node_t *p_head;
tcp_port_monitor_node_t * p_tail; tcp_port_monitor_node_t *p_tail;
} tcp_port_monitor_list_t; } tcp_port_monitor_list_t;
/* --------------------------------------- /* ---------------------------------------
* A port monitor utility function typedef * 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 * Port monitor utility functions implementing
* ---------------------------------------------------------------------------*/ * tcp_port_monitor_function_ptr_t
void destroy_tcp_port_monitor( * ------------------------------------------- */
tcp_port_monitor_t * /* p_monitor */, void destroy_tcp_port_monitor(tcp_port_monitor_t *p_monitor,
void * /* p_void (use NULL for this function) */ void *p_void /* (use NULL for this function) */);
);
void age_tcp_port_monitor( void age_tcp_port_monitor(tcp_port_monitor_t *p_monitor,
tcp_port_monitor_t * /* p_monitor */, void *p_void /* (use NULL for this function) */);
void * /* p_void (use NULL for this function) */
);
void rebuild_tcp_port_monitor_peek_table( void rebuild_tcp_port_monitor_peek_table(tcp_port_monitor_t *p_monitor,
tcp_port_monitor_t * /* p_monitor */, void *p_void /* (use NULL for this function) */);
void * /* p_void (use NULL for this function) */
);
void show_connection_to_tcp_port_monitor( void show_connection_to_tcp_port_monitor(tcp_port_monitor_t *p_monitor,
tcp_port_monitor_t * /* p_monitor */, void *p_connection /* (client should cast) */);
void * /* p_connection (client should cast) */
);
/* ----------------------------- /* -----------------------------
* A tcp port monitor collection * A tcp port monitor collection
* -----------------------------*/ * ----------------------------- */
typedef struct _tcp_port_monitor_collection_t { typedef struct _tcp_port_monitor_collection_t {
tcp_port_monitor_list_t monitor_list; /* list of monitors for this collection */ /* list of monitors for this collection */
GHashTable *hash; /* hash table of pointers into collection's monitor list */ tcp_port_monitor_list_t monitor_list;
/* hash table of pointers into collection's monitor list */
GHashTable *hash;
} tcp_port_monitor_collection_t; } 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( void for_each_tcp_port_monitor_in_collection(
tcp_port_monitor_collection_t * /* p_collection */, tcp_port_monitor_collection_t *p_collection,
tcp_port_monitor_function_ptr_t /* p_function */, tcp_port_monitor_function_ptr_t p_function,
void * /* p_function_args (for user arguments) */ void *p_function_args /* (for user arguments) */);
);
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
* CLIENT INTERFACE * CLIENT INTERFACE
@@ -185,62 +185,57 @@ void for_each_tcp_port_monitor_in_collection(
/* struct to hold monitor creation arguments */ /* struct to hold monitor creation arguments */
typedef struct _tcp_port_monitor_args_t { 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; } tcp_port_monitor_args_t;
/* ---------------------------------- /* ----------------------------------
* Client operations on port monitors * Client operations on port monitors
* ---------------------------------- */ * ---------------------------------- */
/* Clients should first try to "find_tcp_port_monitor" before creating one /* Clients should first try to "find_tcp_port_monitor" before creating one,
so that there are no redundant monitors. */ * so that there are no redundant monitors. */
tcp_port_monitor_t * create_tcp_port_monitor( tcp_port_monitor_t *create_tcp_port_monitor(in_port_t port_range_begin,
in_port_t /* port_range_begin */, in_port_t port_range_end, tcp_port_monitor_args_t *p_creation_args);
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. /* Clients use this function to get connection data from
The requested monitor value is copied into a client-supplied char buffer. * the indicated port monitor.
Returns 0 on success, -1 otherwise. */ * The requested monitor value is copied into a client-supplied char buffer.
int peek_tcp_port_monitor( * Returns 0 on success, -1 otherwise. */
const tcp_port_monitor_t * /* p_monitor */, int peek_tcp_port_monitor(const tcp_port_monitor_t *p_monitor,
int /* item, ( item of interest, from tcp_port_monitor_peekables enum ) */, /* (item of interest, from tcp_port_monitor_peekables enum) */
int /* connection_index, ( 0 to number of connections in monitor - 1 )*/, int item,
char * /* p_buffer, buffer to receive requested value */, /* (0 to number of connections in monitor - 1) */
size_t /* buffer_size, size of p_buffer */ int connection_index,
); /* buffer to receive requested value */
char *p_buffer,
/* size of p_buffer */
size_t buffer_size);
/* -------------------------------- /* --------------------------------
* Client operations on collections * Client operations on collections
* -------------------------------- */ * -------------------------------- */
/* Create a monitor collection. Do this one first. */ /* 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( 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 */ /* Updates the tcp statitics for all monitors within a collection */
void update_tcp_port_monitor_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. /* 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( int insert_tcp_port_monitor_into_collection(
tcp_port_monitor_collection_t * /* p_collection */, tcp_port_monitor_collection_t *p_collection, tcp_port_monitor_t *p_monitor);
tcp_port_monitor_t * /* p_monitor */
);
/* Clients need a way to find monitors */ /* Clients need a way to find monitors */
tcp_port_monitor_t * find_tcp_port_monitor( tcp_port_monitor_t *find_tcp_port_monitor(
const tcp_port_monitor_collection_t * /* p_collection */, const tcp_port_monitor_collection_t *p_collection,
in_port_t /* port_range_begin */, in_port_t port_range_begin, in_port_t port_range_end);
in_port_t /* port_range_end */
);
#endif #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 * Any original torsmo code is licensed under the BSD license
* *
@@ -8,7 +7,8 @@
* Please see COPYING for details * Please see COPYING for details
* *
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen * 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. * All rights reserved.
* *
* This program is free software: you can redistribute it and/or modify * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
* $Id$ * $Id$ */
*/
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/time.h> #include <sys/time.h>
@@ -42,22 +41,24 @@ void update_mail_count(struct local_mail_s *mail)
{ {
struct stat buf; struct stat buf;
if (mail == NULL) if (mail == NULL) {
return; return;
}
/* TODO: use that fine file modification notify on Linux 2.4 */ /* TODO: use that fine file modification notify on Linux 2.4 */
/* don't check mail so often (9.5s is minimum interval) */ /* 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; return;
else } else {
mail->last_update = current_update_time; mail->last_update = current_update_time;
}
if (stat(mail->box, &buf)) { if (stat(mail->box, &buf)) {
static int rep; static int rep;
if (!rep) { if (!rep) {
ERR("can't stat %s: %s", mail->box, ERR("can't stat %s: %s", mail->box, strerror(errno));
strerror(errno));
rep = 1; rep = 1;
} }
return; return;
@@ -70,9 +71,7 @@ void update_mail_count(struct local_mail_s *mail)
struct dirent *dirent; struct dirent *dirent;
mail->mail_count = mail->new_mail_count = 0; mail->mail_count = mail->new_mail_count = 0;
dirname = dirname = (char *) malloc(sizeof(char) * (strlen(mail->box) + 5));
(char *) malloc(sizeof(char) *
(strlen(mail->box) + 5));
if (!dirname) { if (!dirname) {
ERR("malloc"); ERR("malloc");
return; return;
@@ -135,43 +134,46 @@ void update_mail_count(struct local_mail_s *mail)
mail->new_mail_count = mail->mail_count = 0; mail->new_mail_count = mail->mail_count = 0;
fp = open_file(mail->box, &rep); fp = open_file(mail->box, &rep);
if (!fp) if (!fp) {
return; return;
}
/* NOTE: adds mail as new if there isn't Status-field at all */ /* NOTE: adds mail as new if there isn't Status-field at all */
while (!feof(fp)) { while (!feof(fp)) {
char buf[128]; char buf[128];
if (fgets(buf, 128, fp) == NULL)
if (fgets(buf, 128, fp) == NULL) {
break; break;
}
if (strncmp(buf, "From ", 5) == 0) { if (strncmp(buf, "From ", 5) == 0) {
/* ignore MAILER-DAEMON */ /* ignore MAILER-DAEMON */
if (strncmp(buf + 5, "MAILER-DAEMON ", 14) if (strncmp(buf + 5, "MAILER-DAEMON ", 14) != 0) {
!= 0) {
mail->mail_count++; mail->mail_count++;
if (reading_status) if (reading_status) {
mail->new_mail_count++; mail->new_mail_count++;
else } else {
reading_status = 1; reading_status = 1;
} }
}
} else { } else {
if (reading_status if (reading_status
&& strncmp(buf, "X-Mozilla-Status:", && strncmp(buf, "X-Mozilla-Status:", 17) == 0) {
17) == 0) {
/* check that mail isn't already read */ /* check that mail isn't already read */
if (strchr(buf + 21, '0')) if (strchr(buf + 21, '0')) {
mail->new_mail_count++; mail->new_mail_count++;
}
reading_status = 0; reading_status = 0;
continue; continue;
} }
if (reading_status if (reading_status && strncmp(buf, "Status:", 7) == 0) {
&& strncmp(buf, "Status:", 7) == 0) {
/* check that mail isn't already read */ /* check that mail isn't already read */
if (strchr(buf + 7, 'R') == NULL) if (strchr(buf + 7, 'R') == NULL) {
mail->new_mail_count++; mail->new_mail_count++;
}
reading_status = 0; reading_status = 0;
continue; continue;
@@ -179,14 +181,16 @@ void update_mail_count(struct local_mail_s *mail)
} }
/* skip until \n */ /* skip until \n */
while (strchr(buf, '\n') == NULL && !feof(fp)) while (strchr(buf, '\n') == NULL && !feof(fp)) {
fgets(buf, 128, fp); fgets(buf, 128, fp);
} }
}
fclose(fp); fclose(fp);
if (reading_status) if (reading_status) {
mail->new_mail_count++; mail->new_mail_count++;
}
mail->last_mtime = buf.st_mtime; 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 * Any original torsmo code is licensed under the BSD license
* *
@@ -8,7 +7,8 @@
* Please see COPYING for details * Please see COPYING for details
* *
* Copyright (c) 2006 Marco Candrian <mac@calmar.ws> * 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. * All rights reserved.
* *
* This program is free software: you can redistribute it and/or modify * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
* $Id$ * $Id$ */
*/
#include "conky.h" #include "conky.h"
#include <sys/stat.h> #include <sys/stat.h>
@@ -57,23 +56,20 @@ static int subject_width;
static int print_mails; static int print_mails;
static int time_delay; 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 is the maximum output in chars
* TEXT_BUFFER_SIZE actually something like a allowed size * TEXT_BUFFER_SIZE actually something like a allowed size for things in the
* for things in the config, below 'TEXT'. Or what is more probably * config, below 'TEXT'. Or what is more probably max_user_text.
* max_user_text. Anyway, I used TEXT_BUFFER_SIZE for not 'output' things here * Anyway, I used TEXT_BUFFER_SIZE for not 'output' things here
* -- calmar * -- calmar
* *
* To clarify, TEXT_BUFFER_SIZE is used for buffers of fixed size, and * 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 used for buffers which can change in size.
* text_buffer_size is just defined as TEXT_BUFFER_SIZE to start, * text_buffer_size is just defined as TEXT_BUFFER_SIZE to start, so it's okay
* so its okay for most things, however if something is allocated * for most things, however if something is allocated with text_buffer_size and
* with text_buffer_size and then text_buffer_size changes but * then text_buffer_size changes but the array doesn't, you might have some
* the array doesn't, you might have some issues if you are using * issues if you are using text_buffer_size to determine the size of the array.
* text_buffer_size to determine the size of the array. * -- brenden */
* -- brenden
*/
static char mbox_mail_spool[TEXT_BUFFER_SIZE]; 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) { if (!args_ok || force_rescan) {
char *substr = strstr(args, "-n"); char *substr = strstr(args, "-n");
if (substr) { if (substr) {
if (sscanf(substr, "-n %i", &print_mails) != 1) { if (sscanf(substr, "-n %i", &print_mails) != 1) {
print_mails = PRINT_MAILS; print_mails = PRINT_MAILS;
@@ -101,8 +98,9 @@ void mbox_scan(char *args, char *output, size_t max_len)
} else { } else {
print_mails = PRINT_MAILS; print_mails = PRINT_MAILS;
} }
if (print_mails < 1) if (print_mails < 1) {
print_mails = 1; print_mails = 1;
}
substr = strstr(args, "-t"); substr = strstr(args, "-t");
if (substr) { if (substr) {
@@ -134,12 +132,14 @@ void mbox_scan(char *args, char *output, size_t max_len)
if (args[strlen(args) - 1] == '"') { if (args[strlen(args) - 1] == '"') {
strncpy(mbox_mail_spool, args, TEXT_BUFFER_SIZE); strncpy(mbox_mail_spool, args, TEXT_BUFFER_SIZE);
char *start = strchr(mbox_mail_spool, '"') + 1; 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); strncpy(mbox_mail_spool, start, TEXT_BUFFER_SIZE);
} else { } else {
char *copy_args = strdup(args); char *copy_args = strdup(args);
char *tmp = strtok(copy_args, " "); char *tmp = strtok(copy_args, " ");
char *start = tmp; char *start = tmp;
while (tmp) { while (tmp) {
tmp = strtok(NULL, " "); tmp = strtok(NULL, " ");
if (tmp) { if (tmp) {
@@ -150,7 +150,9 @@ void mbox_scan(char *args, char *output, size_t max_len)
free(copy_args); free(copy_args);
} }
if (strlen(mbox_mail_spool) < 1) { 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 */ /* 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 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; return;
}
last_update = current_update_time; 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 */ /* 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; return;
} }
last_ctime = statbuf.st_ctime; last_ctime = statbuf.st_ctime;
last_mtime = statbuf.st_mtime; 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; struct ring_list *curr = 0, *prev = 0, *startlist = 0;
for (i = 0; i < print_mails; i++) { for (i = 0; i < print_mails; i++) {
curr = (struct ring_list *)malloc(sizeof(struct ring_list)); curr = (struct ring_list *) malloc(sizeof(struct ring_list));
curr->from = (char *)malloc(sizeof(char[from_width + 1])); curr->from = (char *) malloc(sizeof(char[from_width + 1]));
curr->subject = (char *)malloc(sizeof(char[subject_width + 1])); curr->subject = (char *) malloc(sizeof(char[subject_width + 1]));
curr->from[0] = '\0'; curr->from[0] = '\0';
curr->subject[0] = '\0'; curr->subject[0] = '\0';
if (i == 0) if (i == 0) {
startlist = curr; startlist = curr;
}
if (i > 0) { if (i > 0) {
curr->previous = prev; curr->previous = prev;
prev->next = curr; prev->next = curr;
@@ -216,17 +222,20 @@ void mbox_scan(char *args, char *output, size_t max_len)
return; 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)) { while (!feof(fp)) {
if (fgets(buf, text_buffer_size, fp) == NULL) if (fgets(buf, text_buffer_size, fp) == NULL) {
break; break;
}
if (strncmp(buf, "From ", 5) == 0) { if (strncmp(buf, "From ", 5) == 0) {
curr = curr->next; curr = curr->next;
/* skip until \n */ /* skip until \n */
while (strchr(buf, '\n') == NULL && !feof(fp)) while (strchr(buf, '\n') == NULL && !feof(fp)) {
fgets(buf, text_buffer_size, fp); fgets(buf, text_buffer_size, fp);
}
flag = 0; /* in the headers now */ flag = 0; /* in the headers now */
continue; 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 */ /* beyond the headers now (empty line), skip until \n */
/* then search for new mail ("From ") */ /* 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); fgets(buf, text_buffer_size, fp);
}
flag = 1; /* in the body now */ flag = 1; /* in the body now */
continue; continue;
} }
@@ -253,10 +263,12 @@ void mbox_scan(char *args, char *output, size_t max_len)
flag = 1; /* search for next From */ flag = 1; /* search for next From */
curr->subject[0] = '\0'; curr->subject[0] = '\0';
curr->from[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 */ /* Skip until \n */
while (strchr(buf, '\n') == NULL && !feof(fp)) while (strchr(buf, '\n') == NULL && !feof(fp)) {
fgets(buf, text_buffer_size, fp); fgets(buf, text_buffer_size, fp);
}
continue; continue;
} }
@@ -272,12 +284,14 @@ void mbox_scan(char *args, char *output, size_t max_len)
continue; 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'; curr->from[i] = '\0';
/* skip until \n */ /* skip until \n */
while (strchr(buf, '\n') == NULL && !feof(fp)) while (strchr(buf, '\n') == NULL && !feof(fp)) {
fgets(buf, text_buffer_size, fp); fgets(buf, text_buffer_size, fp);
}
break; break;
} }
@@ -294,8 +308,9 @@ void mbox_scan(char *args, char *output, size_t max_len)
if (i >= from_width) { if (i >= from_width) {
curr->from[i] = '\0'; curr->from[i] = '\0';
/* skip until \n */ /* skip until \n */
while (strchr(buf, '\n') == NULL && !feof(fp)) while (strchr(buf, '\n') == NULL && !feof(fp)) {
fgets(buf, text_buffer_size, fp); fgets(buf, text_buffer_size, fp);
}
break; break;
} }
@@ -323,8 +338,9 @@ void mbox_scan(char *args, char *output, size_t max_len)
curr->subject[i] = '\0'; curr->subject[i] = '\0';
/* skip until \n */ /* skip until \n */
while (strchr(buf, '\n') == NULL && !feof(fp)) while (strchr(buf, '\n') == NULL && !feof(fp)) {
fgets(buf, text_buffer_size, fp); fgets(buf, text_buffer_size, fp);
}
break; break;
} }
@@ -332,22 +348,23 @@ void mbox_scan(char *args, char *output, size_t max_len)
curr->subject[i++] = buf[u++]; curr->subject[i++] = buf[u++];
} }
} }
} }
fclose(fp); fclose(fp);
output[0] = '\0'; output[0] = '\0';
struct ring_list *tmp; struct ring_list *tmp;
i = print_mails; i = print_mails;
while (i) { while (i) {
if (curr->from[0] != '\0') { if (curr->from[0] != '\0') {
if (i != print_mails) { 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 */ } 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 { } else {
snprintf(buf, text_buffer_size, "\n"); 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 * Any original torsmo code is licensed under the BSD license
* *
@@ -8,7 +7,8 @@
* Please see COPYING for details * Please see COPYING for details
* *
* Copyright (c) 2006 Marco Candrian <mac@calmar.ws> * 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. * All rights reserved.
* *
* This program is free software: you can redistribute it and/or modify * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
* $Id$ * $Id$ */
*/
#ifndef _MBOXSCAN_H_ #ifndef _MBOXSCAN_H_
#define _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 * Any original torsmo code is licensed under the BSD license
* *
@@ -8,7 +7,8 @@
* Please see COPYING for details * Please see COPYING for details
* *
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen * 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. * All rights reserved.
* *
* This program is free software: you can redistribute it and/or modify * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
* $Id$ * $Id$ */
*/
#include <sys/ioctl.h> #include <sys/ioctl.h>
@@ -54,15 +53,15 @@ int mixer_init(const char *name)
{ {
unsigned int i; unsigned int i;
if (name == 0 || name[0] == '\0') if (name == 0 || name[0] == '\0') {
name = "vol"; name = "vol";
}
/* open mixer */ /* open mixer */
if (mixer_fd <= 0) { if (mixer_fd <= 0) {
mixer_fd = open(MIXER_DEV, O_RDONLY); mixer_fd = open(MIXER_DEV, O_RDONLY);
if (mixer_fd == -1) { if (mixer_fd == -1) {
ERR("can't open %s: %s", MIXER_DEV, ERR("can't open %s: %s", MIXER_DEV, strerror(errno));
strerror(errno));
return -1; return -1;
} }
} }
@@ -82,8 +81,9 @@ static int mixer_get(int i)
int val = -1; int val = -1;
if (ioctl(mixer_fd, MIXER_READ(i), &val) == -1) { if (ioctl(mixer_fd, MIXER_READ(i), &val) == -1) {
if (!rep) if (!rep) {
ERR("mixer ioctl: %s", strerror(errno)); ERR("mixer ioctl: %s", strerror(errno));
}
rep = 1; rep = 1;
return 0; return 0;
} }
@@ -95,6 +95,7 @@ static int mixer_get(int i)
int mixer_get_avg(int i) int mixer_get_avg(int i)
{ {
int v = mixer_get(i); int v = mixer_get(i);
return ((v >> 8) + (v & 0xFF)) / 2; 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 * Any original torsmo code is licensed under the BSD license
* *
@@ -7,7 +6,8 @@
* *
* Please see COPYING for details * 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. * All rights reserved.
* *
* This program is free software: you can redistribute it and/or modify * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
* $Id$ * $Id$ */
*/
#include "conky.h" #include "conky.h"
#include <stdio.h> #include <stdio.h>
@@ -32,42 +31,52 @@
#include "libmpdclient.h" #include "libmpdclient.h"
timed_thread *mpd_timed_thread = NULL; timed_thread *mpd_timed_thread = NULL;
void clear_mpd_stats(struct information *current_info); void clear_mpd_stats(struct information *current_info);
void init_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); 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); 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); 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); 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); 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); 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); 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); 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); current_info->mpd.file = malloc(TEXT_BUFFER_SIZE);
}
clear_mpd_stats(current_info); clear_mpd_stats(current_info);
} }
void clear_mpd_stats(struct information *current_info) void clear_mpd_stats(struct information *current_info)
{ {
*current_info->mpd.name=0; *current_info->mpd.name = 0;
*current_info->mpd.file=0; *current_info->mpd.file = 0;
*current_info->mpd.artist=0; *current_info->mpd.artist = 0;
*current_info->mpd.album=0; *current_info->mpd.album = 0;
*current_info->mpd.title=0; *current_info->mpd.title = 0;
*current_info->mpd.random=0; *current_info->mpd.random = 0;
*current_info->mpd.repeat=0; *current_info->mpd.repeat = 0;
*current_info->mpd.track=0; *current_info->mpd.track = 0;
*current_info->mpd.status=0; *current_info->mpd.status = 0;
current_info->mpd.bitrate = 0; current_info->mpd.bitrate = 0;
current_info->mpd.progress = 0; current_info->mpd.progress = 0;
current_info->mpd.elapsed = 0; current_info->mpd.elapsed = 0;
@@ -77,9 +86,11 @@ void clear_mpd_stats(struct information *current_info)
void *update_mpd(void) void *update_mpd(void)
{ {
struct information *current_info = &info; struct information *current_info = &info;
while (1) { while (1) {
if (!current_info->conn) { 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) { if (strlen(current_info->mpd.password) > 1) {
mpd_sendPasswordCommand(current_info->conn, mpd_sendPasswordCommand(current_info->conn,
@@ -90,67 +101,74 @@ void *update_mpd(void)
timed_thread_lock(mpd_timed_thread); timed_thread_lock(mpd_timed_thread);
if (current_info->conn->error || current_info->conn == NULL) { 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); mpd_closeConnection(current_info->conn);
current_info->conn = 0; current_info->conn = 0;
clear_mpd_stats(current_info); 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); 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; continue;
} }
mpd_Status *status; mpd_Status *status;
mpd_InfoEntity *entity; mpd_InfoEntity *entity;
mpd_sendStatusCommand(current_info->conn); mpd_sendStatusCommand(current_info->conn);
if ((status = mpd_getStatus(current_info->conn)) == NULL) { 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); mpd_closeConnection(current_info->conn);
current_info->conn = 0; current_info->conn = 0;
clear_mpd_stats(current_info); 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); 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; continue;
} }
mpd_finishCommand(current_info->conn); mpd_finishCommand(current_info->conn);
if (current_info->conn->error) { 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); mpd_closeConnection(current_info->conn);
current_info->conn = 0; current_info->conn = 0;
timed_thread_unlock(mpd_timed_thread); 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; continue;
} }
current_info->mpd.volume = status->volume; current_info->mpd.volume = status->volume;
//if (status->error) /* if (status->error) {
//printf("error: %s\n", status->error); printf("error: %s\n", status->error);
} */
if (status->state == MPD_STATUS_STATE_PLAY) { if (status->state == MPD_STATUS_STATE_PLAY) {
strncpy(current_info->mpd.status, "Playing", strncpy(current_info->mpd.status, "Playing", TEXT_BUFFER_SIZE - 1);
TEXT_BUFFER_SIZE - 1);
} }
if (status->state == MPD_STATUS_STATE_STOP) { if (status->state == MPD_STATUS_STATE_STOP) {
clear_mpd_stats(current_info); clear_mpd_stats(current_info);
strncpy(current_info->mpd.status, "Stopped", strncpy(current_info->mpd.status, "Stopped", TEXT_BUFFER_SIZE - 1);
TEXT_BUFFER_SIZE - 1);
} }
if (status->state == MPD_STATUS_STATE_PAUSE) { if (status->state == MPD_STATUS_STATE_PAUSE) {
strncpy(current_info->mpd.status, "Paused", strncpy(current_info->mpd.status, "Paused", TEXT_BUFFER_SIZE - 1);
TEXT_BUFFER_SIZE - 1);
} }
if (status->state == MPD_STATUS_STATE_UNKNOWN) { if (status->state == MPD_STATUS_STATE_UNKNOWN) {
clear_mpd_stats(current_info); clear_mpd_stats(current_info);
*current_info->mpd.status=0; *current_info->mpd.status = 0;
} }
if (status->state == MPD_STATUS_STATE_PLAY || if (status->state == MPD_STATUS_STATE_PLAY
status->state == MPD_STATUS_STATE_PAUSE) { || status->state == MPD_STATUS_STATE_PAUSE) {
current_info->mpd.bitrate = status->bitRate; current_info->mpd.bitrate = status->bitRate;
current_info->mpd.progress = current_info->mpd.progress = (float) status->elapsedTime /
(float) status->elapsedTime / status->totalTime; status->totalTime;
current_info->mpd.elapsed = status->elapsedTime; current_info->mpd.elapsed = status->elapsedTime;
current_info->mpd.length = status->totalTime; current_info->mpd.length = status->totalTime;
if (status->random == 0) { if (status->random == 0) {
@@ -158,29 +176,32 @@ void *update_mpd(void)
} else if (status->random == 1) { } else if (status->random == 1) {
strcpy(current_info->mpd.random, "On"); strcpy(current_info->mpd.random, "On");
} else { } else {
*current_info->mpd.random=0; *current_info->mpd.random = 0;
} }
if (status->repeat == 0) { if (status->repeat == 0) {
strcpy(current_info->mpd.repeat, "Off"); strcpy(current_info->mpd.repeat, "Off");
} else if (status->repeat == 1) { } else if (status->repeat == 1) {
strcpy(current_info->mpd.repeat, "On"); strcpy(current_info->mpd.repeat, "On");
} else { } else {
*current_info->mpd.repeat=0; *current_info->mpd.repeat = 0;
} }
} }
if (current_info->conn->error) { 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); mpd_closeConnection(current_info->conn);
current_info->conn = 0; current_info->conn = 0;
timed_thread_unlock(mpd_timed_thread); 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; continue;
} }
mpd_sendCurrentSongCommand(current_info->conn); mpd_sendCurrentSongCommand(current_info->conn);
while ((entity = mpd_getNextInfoEntity(current_info->conn))) { while ((entity = mpd_getNextInfoEntity(current_info->conn))) {
mpd_Song *song = entity->info.song; mpd_Song *song = entity->info.song;
if (entity->type != MPD_INFO_ENTITY_TYPE_SONG) { if (entity->type != MPD_INFO_ENTITY_TYPE_SONG) {
mpd_freeInfoEntity(entity); mpd_freeInfoEntity(entity);
continue; continue;
@@ -190,37 +211,37 @@ void *update_mpd(void)
strncpy(current_info->mpd.artist, song->artist, strncpy(current_info->mpd.artist, song->artist,
TEXT_BUFFER_SIZE - 1); TEXT_BUFFER_SIZE - 1);
} else { } else {
*current_info->mpd.artist=0; *current_info->mpd.artist = 0;
} }
if (song->album) { if (song->album) {
strncpy(current_info->mpd.album, song->album, strncpy(current_info->mpd.album, song->album,
TEXT_BUFFER_SIZE - 1); TEXT_BUFFER_SIZE - 1);
} else { } else {
*current_info->mpd.album=0; *current_info->mpd.album = 0;
} }
if (song->title) { if (song->title) {
strncpy(current_info->mpd.title, song->title, strncpy(current_info->mpd.title, song->title,
TEXT_BUFFER_SIZE - 1); TEXT_BUFFER_SIZE - 1);
} else { } else {
*current_info->mpd.title=0; *current_info->mpd.title = 0;
} }
if (song->track) { if (song->track) {
strncpy(current_info->mpd.track, song->track, strncpy(current_info->mpd.track, song->track,
TEXT_BUFFER_SIZE - 1); TEXT_BUFFER_SIZE - 1);
} else { } else {
*current_info->mpd.track=0; *current_info->mpd.track = 0;
} }
if (song->name) { if (song->name) {
strncpy(current_info->mpd.name, song->name, strncpy(current_info->mpd.name, song->name,
TEXT_BUFFER_SIZE - 1); TEXT_BUFFER_SIZE - 1);
} else { } else {
*current_info->mpd.name=0; *current_info->mpd.name = 0;
} }
if (song->file) { if (song->file) {
strncpy(current_info->mpd.file, strncpy(current_info->mpd.file, song->file,
song->file, TEXT_BUFFER_SIZE - 1); TEXT_BUFFER_SIZE - 1);
} else { } else {
*current_info->mpd.file=0; *current_info->mpd.file = 0;
} }
if (entity != NULL) { if (entity != NULL) {
mpd_freeInfoEntity(entity); mpd_freeInfoEntity(entity);
@@ -233,29 +254,35 @@ void *update_mpd(void)
} }
mpd_finishCommand(current_info->conn); mpd_finishCommand(current_info->conn);
if (current_info->conn->error) { 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); mpd_closeConnection(current_info->conn);
current_info->conn = 0; current_info->conn = 0;
timed_thread_unlock(mpd_timed_thread); 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; continue;
} }
timed_thread_unlock(mpd_timed_thread); timed_thread_unlock(mpd_timed_thread);
if (current_info->conn->error) { 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); mpd_closeConnection(current_info->conn);
current_info->conn = 0; 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; continue;
} }
mpd_freeStatus(status); mpd_freeStatus(status);
/* if (current_info->conn) { /* if (current_info->conn) {
mpd_closeConnection(current_info->conn); mpd_closeConnection(current_info->conn);
current_info->conn = 0; 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; continue;
} }
return 0; 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 * Any original torsmo code is licensed under the BSD license
* *
@@ -8,7 +7,8 @@
* Please see COPYING for details * Please see COPYING for details
* *
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen * 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. * All rights reserved.
* *
* This program is free software: you can redistribute it and/or modify * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
* $Id$ * $Id$ */
*/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -57,7 +56,6 @@
#include "conky.h" #include "conky.h"
static kvm_t *kd = NULL; static kvm_t *kd = NULL;
int kd_init = 0, nkd_init = 0; int kd_init = 0, nkd_init = 0;
u_int32_t sensvalue; u_int32_t sensvalue;
@@ -65,12 +63,13 @@ char errbuf[_POSIX2_LINE_MAX];
static int init_kvm(void) static int init_kvm(void)
{ {
if (kd_init) if (kd_init) {
return 0; return 0;
}
kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf); kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf);
if (kd == NULL) { if (kd == NULL) {
(void) warnx("cannot kvm_openfiles: %s", errbuf); warnx("cannot kvm_openfiles: %s", errbuf);
return -1; return -1;
} }
kd_init = 1; kd_init = 1;
@@ -88,25 +87,24 @@ static int swapmode(int *retavail, int *retfree)
n = swapctl(SWAP_NSWAP, 0, 0); n = swapctl(SWAP_NSWAP, 0, 0);
if (n < 1) { if (n < 1) {
(void) warn("could not get swap information"); warn("could not get swap information");
return 0; return 0;
} }
sep = (struct swapent *) malloc(n * (sizeof(*sep))); sep = (struct swapent *) malloc(n * (sizeof(*sep)));
if (sep == NULL) { if (sep == NULL) {
(void) warn("memory allocation failed"); warn("memory allocation failed");
return 0; return 0;
} }
if (swapctl(SWAP_STATS, (void *) sep, n) < n) { if (swapctl(SWAP_STATS, (void *) sep, n) < n) {
(void) warn("could not get swap stats"); warn("could not get swap stats");
return 0; return 0;
} }
for (; n > 0; n--) { for (; n > 0; n--) {
*retavail += (int) dbtob(sep[n - 1].se_nblks); *retavail += (int) dbtob(sep[n - 1].se_nblks);
*retfree += *retfree += (int) dbtob(sep[n - 1].se_nblks - sep[n - 1].se_inuse);
(int) dbtob(sep[n - 1].se_nblks - sep[n - 1].se_inuse);
} }
*retavail = (int) (*retavail / 1024); *retavail = (int) (*retavail / 1024);
*retfree = (int) (*retfree / 1024); *retfree = (int) (*retfree / 1024);
@@ -114,7 +112,6 @@ static int swapmode(int *retavail, int *retfree)
return 1; return 1;
} }
void prepare_update() void prepare_update()
{ {
} }
@@ -128,10 +125,10 @@ void update_uptime()
if ((sysctl(mib, 2, &boottime, &size, NULL, 0) != -1) if ((sysctl(mib, 2, &boottime, &size, NULL, 0) != -1)
&& (boottime.tv_sec != 0)) { && (boottime.tv_sec != 0)) {
(void) time(&now); time(&now);
info.uptime = now - boottime.tv_sec; info.uptime = now - boottime.tv_sec;
} else { } else {
(void) warn("could not get uptime"); warn("could not get uptime");
info.uptime = 0; info.uptime = 0;
} }
} }
@@ -154,7 +151,6 @@ void update_meminfo()
info.memmax = info.mem = 0; info.memmax = info.mem = 0;
info.swapmax = info.swap = 0; info.swapmax = info.swap = 0;
if (sysctl(mib, 2, &uvmexp, &size, NULL, 0) < 0) { if (sysctl(mib, 2, &uvmexp, &size, NULL, 0) < 0) {
warn("could not get memory info"); warn("could not get memory info");
return; return;
@@ -165,8 +161,7 @@ void update_meminfo()
inactive_pages = uvmexp.inactive; inactive_pages = uvmexp.inactive;
info.memmax = (total_pages * pagesize) >> 10; info.memmax = (total_pages * pagesize) >> 10;
info.mem = info.mem = ((total_pages - free_pages - inactive_pages) * pagesize) >> 10;
((total_pages - free_pages - inactive_pages) * pagesize) >> 10;
if (swapmode(&swap_avail, &swap_free) >= 0) { if (swapmode(&swap_avail, &swap_free) >= 0) {
info.swapmax = swap_avail; info.swapmax = swap_avail;
@@ -182,36 +177,36 @@ void update_net_stats()
struct ifnet_head ifhead; /* interfaces are in a tail queue */ struct ifnet_head ifhead; /* interfaces are in a tail queue */
u_long ifnetaddr; u_long ifnetaddr;
static struct nlist namelist[] = { static struct nlist namelist[] = {
{"_ifnet"}, { "_ifnet" },
{NULL}, { NULL }
}; };
static kvm_t *nkd; static kvm_t *nkd;
if (!nkd_init) { if (!nkd_init) {
nkd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf); nkd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
if (nkd == NULL) { if (nkd == NULL) {
(void) warnx("cannot kvm_openfiles: %s", errbuf); warnx("cannot kvm_openfiles: %s", errbuf);
(void) warnx("maybe you need to setgid kmem this program?");
warnx
("maybe you need to setgid kmem this program?");
return; return;
} else if (kvm_nlist(nkd, namelist) != 0) { } else if (kvm_nlist(nkd, namelist) != 0) {
(void) warn("cannot kvm_nlist"); warn("cannot kvm_nlist");
return; return;
} else } else {
nkd_init = 1; nkd_init = 1;
} }
}
if (kvm_read(nkd, (u_long) namelist[0].n_value, (void *) &ifhead, if (kvm_read(nkd, (u_long) namelist[0].n_value, (void *) &ifhead,
sizeof(ifhead)) < 0) { sizeof(ifhead)) < 0) {
(void) warn("cannot kvm_read"); warn("cannot kvm_read");
return; return;
} }
/* get delta */ /* get delta */
delta = current_update_time - last_update_time; delta = current_update_time - last_update_time;
if (delta <= 0.0001) if (delta <= 0.0001) {
return; return;
}
for (i = 0, ifnetaddr = (u_long) ifhead.tqh_first; for (i = 0, ifnetaddr = (u_long) ifhead.tqh_first;
ifnet.if_list.tqe_next && i < 16; ifnet.if_list.tqe_next && i < 16;
@@ -220,29 +215,27 @@ void update_net_stats()
struct net_stat *ns; struct net_stat *ns;
long long last_recv, last_trans; long long last_recv, last_trans;
(void) kvm_read(nkd, (u_long) ifnetaddr, (void *) &ifnet, kvm_read(nkd, (u_long) ifnetaddr, (void *) &ifnet, sizeof(ifnet));
sizeof(ifnet));
ns = get_net_stat(ifnet.if_xname); ns = get_net_stat(ifnet.if_xname);
ns->up = 1; ns->up = 1;
last_recv = ns->recv; last_recv = ns->recv;
last_trans = ns->trans; last_trans = ns->trans;
if (ifnet.if_ibytes < ns->last_read_recv) if (ifnet.if_ibytes < ns->last_read_recv) {
ns->recv += ns->recv += ((long long) 4294967295U - ns->last_read_recv) +
((long long) 4294967295U - ifnet.if_ibytes;
ns->last_read_recv) + ifnet.if_ibytes; } else {
else
ns->recv += (ifnet.if_ibytes - ns->last_read_recv); ns->recv += (ifnet.if_ibytes - ns->last_read_recv);
}
ns->last_read_recv = ifnet.if_ibytes; ns->last_read_recv = ifnet.if_ibytes;
if (ifnet.if_obytes < ns->last_read_trans) if (ifnet.if_obytes < ns->last_read_trans) {
ns->trans += ns->trans += ((long long) 4294967295U - ns->last_read_trans) +
((long long) 4294967295U - ifnet.if_obytes;
ns->last_read_trans) + ifnet.if_obytes; } else {
else ns->trans += (ifnet.if_obytes - ns->last_read_trans);
ns->trans += }
(ifnet.if_obytes - ns->last_read_trans);
ns->last_read_trans = ifnet.if_obytes; ns->last_read_trans = ifnet.if_obytes;
@@ -264,11 +257,12 @@ void update_total_processes()
info.procs = 0; info.procs = 0;
if (init_kvm() < 0) if (init_kvm() < 0) {
return; return;
else } else {
kvm_getproc2(kd, KERN_PROC_ALL, 0, kvm_getproc2(kd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2),
sizeof(struct kinfo_proc2), &n_processes); &n_processes);
}
info.procs = n_processes; info.procs = n_processes;
} }
@@ -281,16 +275,18 @@ void update_running_processes()
info.run_procs = 0; info.run_procs = 0;
if (init_kvm() < 0) if (init_kvm() < 0) {
return; return;
else { } else {
p = kvm_getproc2(kd, KERN_PROC_ALL, 0, p = kvm_getproc2(kd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2),
sizeof(struct kinfo_proc2), &n_processes); &n_processes);
for (i = 0; i < n_processes; i++) for (i = 0; i < n_processes; i++) {
if (p[i].p_stat == LSRUN || p[i].p_stat == LSIDL || if (p[i].p_stat == LSRUN || p[i].p_stat == LSIDL
p[i].p_stat == LSONPROC) || p[i].p_stat == LSONPROC) {
cnt++; cnt++;
} }
}
}
info.run_procs = cnt; info.run_procs = cnt;
} }
@@ -313,9 +309,9 @@ void update_cpu_usage()
info.cpu_usage = 0; info.cpu_usage = 0;
if (sysctlbyname("kern.cp_time", &cp_time, &len, NULL, 0) < 0) if (sysctlbyname("kern.cp_time", &cp_time, &len, NULL, 0) < 0) {
(void) warn("cannot get kern.cp_time"); warn("cannot get kern.cp_time");
}
fresh.load[0] = cp_time[CP_USER]; fresh.load[0] = cp_time[CP_USER];
fresh.load[1] = cp_time[CP_NICE]; fresh.load[1] = cp_time[CP_NICE];
@@ -324,19 +320,17 @@ void update_cpu_usage()
fresh.load[4] = cp_time[CP_IDLE]; fresh.load[4] = cp_time[CP_IDLE];
used = fresh.load[0] + fresh.load[1] + fresh.load[2]; used = fresh.load[0] + fresh.load[1] + fresh.load[2];
total = total = fresh.load[0] + fresh.load[1] + fresh.load[2] + fresh.load[3];
fresh.load[0] + fresh.load[1] + fresh.load[2] + fresh.load[3];
if ((total - oldtotal) != 0) if ((total - oldtotal) != 0) {
info.cpu_usage = info.cpu_usage = ((double) (used - oldused)) /
((double) (used - oldused)) / (double) (total - (double) (total - oldtotal);
oldtotal); } else {
else
info.cpu_usage = 0; info.cpu_usage = 0;
}
oldused = used; oldused = used;
oldtotal = total; oldtotal = total;
} }
double get_sysfs_info(int *fd, int div, char *devtype) 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() void update_load_average()
{ {
double v[3]; double v[3];
getloadavg(v, 3); getloadavg(v, 3);
info.loadavg[0] = (float) v[0]; 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 int open_sysfs_sensor(const char *dir, const char *dev, const char *type, int n,
open_sysfs_sensor(const char *dir, const char *dev, const char *type, int n, int *div, char *devtype) int *div, char *devtype)
{ {
return -1; return -1;
} }
@@ -374,29 +369,27 @@ int open_acpi_temperature(const char *name)
return -1; 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; return;
}
/* not implemented */ /* not implemented */
memset(p_client_buffer,0,client_buffer_size); memset(p_client_buffer, 0, client_buffer_size);
return;
} }
/*char *get_acpi_fan()*/ /* char *get_acpi_fan() */
void get_acpi_fan( char * p_client_buffer, size_t client_buffer_size ) 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; return;
}
/* not implemented */ /* not implemented */
memset(p_client_buffer,0,client_buffer_size); memset(p_client_buffer, 0, client_buffer_size);
return;
} }
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 * Any original torsmo code is licensed under the BSD license
* *
@@ -8,7 +7,8 @@
* Please see COPYING for details * Please see COPYING for details
* *
* Copyright (c) 2007 Toni Spets * 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. * All rights reserved.
* *
* This program is free software: you can redistribute it and/or modify * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
* $Id$ * $Id$ */
*/
#include <sys/dkstat.h> #include <sys/dkstat.h>
#include <sys/param.h> #include <sys/param.h>
@@ -79,39 +78,42 @@ int init_sensors = 0;
static int kvm_init() static int kvm_init()
{ {
if(init_kvm) if (init_kvm) {
return 1; return 1;
}
kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, NULL); kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, NULL);
if(kd == NULL) if (kd == NULL) {
ERR("error opening kvm"); ERR("error opening kvm");
else init_kvm = 1; } else {
init_kvm = 1;
}
return 1; return 1;
} }
/* note: swapmode taken from 'top' source */ /* note: swapmode taken from 'top' source */
/* /* swapmode is rewritten by Tobias Weingartner <weingart@openbsd.org>
* swapmode is rewritten by Tobias Weingartner <weingart@openbsd.org> * to be based on the new swapctl(2) system call. */
* to be based on the new swapctl(2) system call. static int swapmode(int *used, int *total)
*/
static int
swapmode(int *used, int *total)
{ {
struct swapent *swdev; struct swapent *swdev;
int nswap, rnswap, i; int nswap, rnswap, i;
nswap = swapctl(SWAP_NSWAP, 0, 0); nswap = swapctl(SWAP_NSWAP, 0, 0);
if (nswap == 0) if (nswap == 0) {
return 0; return 0;
}
swdev = malloc(nswap * sizeof(*swdev)); swdev = malloc(nswap * sizeof(*swdev));
if (swdev == NULL) if (swdev == NULL) {
return 0; return 0;
}
rnswap = swapctl(SWAP_STATS, swdev, nswap); rnswap = swapctl(SWAP_STATS, swdev, nswap);
if (rnswap == -1) if (rnswap == -1) {
return 0; return 0;
}
/* if rnswap != nswap, then what? */ /* if rnswap != nswap, then what? */
@@ -133,16 +135,15 @@ int check_mount(char *s)
return 0; return 0;
} }
void void update_uptime()
update_uptime()
{ {
int mib[2] = { CTL_KERN, KERN_BOOTTIME }; int mib[2] = { CTL_KERN, KERN_BOOTTIME };
struct timeval boottime; struct timeval boottime;
time_t now; time_t now;
size_t size = sizeof (boottime); size_t size = sizeof(boottime);
if ((sysctl(mib, 2, &boottime, &size, NULL, 0) != -1) && if ((sysctl(mib, 2, &boottime, &size, NULL, 0) != -1)
(boottime.tv_sec != 0)) { && (boottime.tv_sec != 0)) {
time(&now); time(&now);
info.uptime = now - boottime.tv_sec; info.uptime = now - boottime.tv_sec;
} else { } else {
@@ -151,10 +152,9 @@ update_uptime()
} }
} }
void void update_meminfo()
update_meminfo()
{ {
static int mib[2] = {CTL_VM, VM_METER}; static int mib[2] = { CTL_VM, VM_METER };
struct vmtotal vmtotal; struct vmtotal vmtotal;
size_t size; size_t size;
int pagesize, pageshift, swap_avail, swap_used; int pagesize, pageshift, swap_avail, swap_used;
@@ -188,8 +188,7 @@ update_meminfo()
} }
} }
void void update_net_stats()
update_net_stats()
{ {
struct net_stat *ns; struct net_stat *ns;
double delta; double delta;
@@ -197,14 +196,15 @@ update_net_stats()
struct ifaddrs *ifap, *ifa; struct ifaddrs *ifap, *ifa;
struct if_data *ifd; struct if_data *ifd;
/* get delta */ /* get delta */
delta = current_update_time - last_update_time; delta = current_update_time - last_update_time;
if (delta <= 0.0001) if (delta <= 0.0001) {
return; return;
}
if (getifaddrs(&ifap) < 0) if (getifaddrs(&ifap) < 0) {
return; return;
}
for (ifa = ifap; ifa; ifa = ifa->ifa_next) { for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
ns = get_net_stat((const char *) ifa->ifa_name); ns = get_net_stat((const char *) ifa->ifa_name);
@@ -216,35 +216,36 @@ update_net_stats()
last_recv = ns->recv; last_recv = ns->recv;
last_trans = ns->trans; last_trans = ns->trans;
if (ifa->ifa_addr->sa_family != AF_LINK) if (ifa->ifa_addr->sa_family != AF_LINK) {
continue; continue;
}
for (iftmp = ifa->ifa_next; iftmp != NULL && for (iftmp = ifa->ifa_next;
strcmp(ifa->ifa_name, iftmp->ifa_name) == 0; iftmp != NULL && strcmp(ifa->ifa_name, iftmp->ifa_name) == 0;
iftmp = iftmp->ifa_next) iftmp = iftmp->ifa_next) {
if (iftmp->ifa_addr->sa_family == AF_INET) if (iftmp->ifa_addr->sa_family == AF_INET) {
memcpy(&(ns->addr), iftmp->ifa_addr, memcpy(&(ns->addr), iftmp->ifa_addr,
iftmp->ifa_addr->sa_len); iftmp->ifa_addr->sa_len);
}
}
ifd = (struct if_data *) ifa->ifa_data; ifd = (struct if_data *) ifa->ifa_data;
r = ifd->ifi_ibytes; r = ifd->ifi_ibytes;
t = ifd->ifi_obytes; t = ifd->ifi_obytes;
if (r < ns->last_read_recv) if (r < ns->last_read_recv) {
ns->recv += ns->recv += ((long long) 4294967295U - ns->last_read_recv) + r;
((long long) 4294967295U - } else {
ns->last_read_recv) + r;
else
ns->recv += (r - ns->last_read_recv); ns->recv += (r - ns->last_read_recv);
}
ns->last_read_recv = r; ns->last_read_recv = r;
if (t < ns->last_read_trans) if (t < ns->last_read_trans) {
ns->trans += ns->trans += (long long) 4294967295U - ns->last_read_trans + t;
((long long) 4294967295U - } else {
ns->last_read_trans) + t;
else
ns->trans += (t - ns->last_read_trans); ns->trans += (t - ns->last_read_trans);
}
ns->last_read_trans = t; ns->last_read_trans = t;
@@ -259,8 +260,7 @@ update_net_stats()
freeifaddrs(ifap); freeifaddrs(ifap);
} }
void void update_total_processes()
update_total_processes()
{ {
int n_processes; int n_processes;
@@ -270,8 +270,7 @@ update_total_processes()
info.procs = n_processes; info.procs = n_processes;
} }
void void update_running_processes()
update_running_processes()
{ {
struct kinfo_proc2 *p; struct kinfo_proc2 *p;
int n_processes; int n_processes;
@@ -279,11 +278,13 @@ update_running_processes()
kvm_init(); kvm_init();
int max_size = sizeof(struct kinfo_proc2); int max_size = sizeof(struct kinfo_proc2);
p = kvm_getproc2(kd, KERN_PROC_ALL, 0, max_size, &n_processes); p = kvm_getproc2(kd, KERN_PROC_ALL, 0, max_size, &n_processes);
for (i = 0; i < n_processes; i++) { for (i = 0; i < n_processes; i++) {
if (p[i].p_stat == SRUN) if (p[i].p_stat == SRUN) {
cnt++; cnt++;
} }
}
info.run_procs = cnt; info.run_procs = cnt;
} }
@@ -300,44 +301,47 @@ struct cpu_load_struct fresh = { {0, 0, 0, 0, 0} };
long cpu_used, oldtotal, oldused; long cpu_used, oldtotal, oldused;
#else #else
#include <assert.h> #include <assert.h>
int64_t* fresh = NULL; int64_t *fresh = NULL;
/* XXX is 8 enough? - What's the constant for MAXCPU?*/
/* allocate this with malloc would be better*/ /* XXX is 8 enough? - What's the constant for MAXCPU? */
/* allocate this with malloc would be better */
int64_t oldtotal[8], oldused[8]; int64_t oldtotal[8], oldused[8];
#endif #endif
void void get_cpu_count()
get_cpu_count()
{ {
int cpu_count = 1; /* default to 1 cpu */ int cpu_count = 1; /* default to 1 cpu */
#ifndef OLDCPU #ifndef OLDCPU
int mib[2] = { CTL_HW, HW_NCPU }; int mib[2] = { CTL_HW, HW_NCPU };
size_t len = sizeof(cpu_count); 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"); ERR("error getting cpu count, defaulting to 1");
}
#endif #endif
info.cpu_count = cpu_count; info.cpu_count = cpu_count;
info.cpu_usage = malloc(info.cpu_count * sizeof (float)); info.cpu_usage = malloc(info.cpu_count * sizeof(float));
if (info.cpu_usage == NULL) if (info.cpu_usage == NULL) {
CRIT_ERR("malloc"); CRIT_ERR("malloc");
}
#ifndef OLDCPU #ifndef OLDCPU
assert(fresh == NULL); /* XXX Is this leaking memory?*/ assert(fresh == NULL); /* XXX Is this leaking memory? */
/* XXX Where shall I free this?*/ /* XXX Where shall I free this? */
if (NULL == (fresh = calloc(cpu_count, sizeof(int64_t) * CPUSTATES))) if (NULL == (fresh = calloc(cpu_count, sizeof(int64_t) * CPUSTATES))) {
CRIT_ERR("calloc"); CRIT_ERR("calloc");
}
#endif #endif
} }
void void update_cpu_usage()
update_cpu_usage()
{ {
#ifdef OLDCPU #ifdef OLDCPU
int mib[2] = { CTL_KERN, KERN_CPTIME }; int mib[2] = { CTL_KERN, KERN_CPTIME };
long used, total; long used, total;
long cp_time[CPUSTATES]; long cp_time[CPUSTATES];
size_t len = sizeof (cp_time); size_t len = sizeof(cp_time);
#else #else
size_t size; size_t size;
unsigned int i; unsigned int i;
@@ -361,8 +365,7 @@ update_cpu_usage()
fresh.load[4] = cp_time[CP_IDLE]; fresh.load[4] = cp_time[CP_IDLE];
used = fresh.load[0] + fresh.load[1] + fresh.load[2]; used = fresh.load[0] + fresh.load[1] + fresh.load[2];
total = total = fresh.load[0] + fresh.load[1] + fresh.load[2] + fresh.load[3];
fresh.load[0] + fresh.load[1] + fresh.load[2] + fresh.load[3];
if ((total - oldtotal) != 0) { if ((total - oldtotal) != 0) {
info.cpu_usage[0] = ((double) (used - oldused)) / info.cpu_usage[0] = ((double) (used - oldused)) /
@@ -377,23 +380,27 @@ update_cpu_usage()
if (info.cpu_count > 1) { if (info.cpu_count > 1) {
size = CPUSTATES * sizeof(int64_t); size = CPUSTATES * sizeof(int64_t);
for (i = 0; i < info.cpu_count; i++) { for (i = 0; i < info.cpu_count; i++) {
int cp_time_mib[] = {CTL_KERN, KERN_CPTIME2, i}; int cp_time_mib[] = { CTL_KERN, KERN_CPTIME2, i };
if (sysctl(cp_time_mib, 3, &(fresh[i * CPUSTATES]), &size, NULL, 0) < 0) if (sysctl(cp_time_mib, 3, &(fresh[i * CPUSTATES]), &size, NULL, 0)
< 0) {
ERR("sysctl kern.cp_time2 failed"); ERR("sysctl kern.cp_time2 failed");
} }
}
} else { } else {
int cp_time_mib[] = {CTL_KERN, KERN_CPTIME}; int cp_time_mib[] = { CTL_KERN, KERN_CPTIME };
long cp_time_tmp[CPUSTATES]; long cp_time_tmp[CPUSTATES];
size = sizeof(cp_time_tmp); 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"); 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++) { for (i = 0; i < info.cpu_count; i++) {
int64_t used, total; int64_t used, total;
int at = i * CPUSTATES; int at = i * CPUSTATES;
@@ -414,10 +421,10 @@ update_cpu_usage()
#endif #endif
} }
void void update_load_average()
update_load_average()
{ {
double v[3]; double v[3];
getloadavg(v, 3); getloadavg(v, 3);
info.loadavg[0] = (float) v[0]; 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 }; int sensor_cnt, dev, numt, mib[5] = { CTL_HW, HW_SENSORS, 0, 0, 0 };
struct sensor sensor; struct sensor sensor;
struct sensordev sensordev; struct sensordev sensordev;
size_t slen,sdlen; size_t slen, sdlen;
enum sensor_type type; enum sensor_type type;
slen = sizeof(sensor); slen = sizeof(sensor);
@@ -443,34 +450,38 @@ void update_obsd_sensors()
/* for (dev = 0; dev < MAXSENSORDEVICES; dev++) { */ /* for (dev = 0; dev < MAXSENSORDEVICES; dev++) { */
mib[2] = dev; mib[2] = dev;
if(sysctl(mib, 3, &sensordev, &sdlen, NULL, 0) == -1) { if (sysctl(mib, 3, &sensordev, &sdlen, NULL, 0) == -1) {
if (errno != ENOENT) if (errno != ENOENT) {
warn("sysctl"); warn("sysctl");
}
return; return;
//continue; // continue;
} }
for (type = 0; type < SENSOR_MAX_TYPES; type++) { for (type = 0; type < SENSOR_MAX_TYPES; type++) {
mib[3] = type; mib[3] = type;
for (numt = 0; numt < sensordev.maxnumt[type]; numt++) { for (numt = 0; numt < sensordev.maxnumt[type]; numt++) {
mib[4] = numt; mib[4] = numt;
if (sysctl(mib, 5, &sensor, &slen, NULL, 0) if (sysctl(mib, 5, &sensor, &slen, NULL, 0) == -1) {
== -1) { if (errno != ENOENT) {
if (errno != ENOENT)
warn("sysctl"); warn("sysctl");
}
continue; continue;
} }
if (sensor.flags & SENSOR_FINVALID) if (sensor.flags & SENSOR_FINVALID) {
continue; continue;
}
switch (type) { switch (type) {
case SENSOR_TEMP: 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; break;
case SENSOR_FANRPM: case SENSOR_FANRPM:
obsd_sensors.fan[dev][sensor.numt] = sensor.value; obsd_sensors.fan[dev][sensor.numt] = sensor.value;
break; break;
case SENSOR_VOLTS_DC: 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; break;
default: default:
break; break;
@@ -488,11 +499,13 @@ void update_obsd_sensors()
void get_obsd_vendor(char *buf, size_t client_buffer_size) void get_obsd_vendor(char *buf, size_t client_buffer_size)
{ {
int mib[2]; int mib[2];
mib[0] = CTL_HW; mib[0] = CTL_HW;
mib[1] = HW_VENDOR; mib[1] = HW_VENDOR;
char vendor[64]; char vendor[64];
size_t size = sizeof(vendor); 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"); ERR("error reading vendor");
snprintf(buf, client_buffer_size, "unknown"); snprintf(buf, client_buffer_size, "unknown");
} else { } 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) void get_obsd_product(char *buf, size_t client_buffer_size)
{ {
int mib[2]; int mib[2];
mib[0] = CTL_HW; mib[0] = CTL_HW;
mib[1] = HW_PRODUCT; mib[1] = HW_PRODUCT;
char product[64]; char product[64];
size_t size = sizeof(product); 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"); ERR("error reading product");
snprintf(buf, client_buffer_size, "unknown"); snprintf(buf, client_buffer_size, "unknown");
} else { } 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 */ /* rdtsc() and get_freq_dynamic() copied from linux.c */
#if defined(__i386) || defined(__x86_64) #if defined(__i386) || defined(__x86_64)
__inline__ unsigned long long int __inline__ unsigned long long int rdtsc()
rdtsc()
{ {
unsigned long long int x; unsigned long long int x;
__asm__ volatile(".byte 0x0f, 0x31":"=A" (x)); __asm__ volatile(".byte 0x0f, 0x31":"=A" (x));
return (x); return x;
} }
#endif #endif
/* return system frequency in MHz (use divisor=1) or GHz (use divisor=1000) */ /* return system frequency in MHz (use divisor=1) or GHz (use divisor=1000) */
void void get_freq_dynamic(char *p_client_buffer, size_t client_buffer_size,
get_freq_dynamic(char *p_client_buffer, size_t client_buffer_size,
char *p_format, int divisor) char *p_format, int divisor)
{ {
#if defined(__i386) || defined(__x86_64) #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 long long cycles[2]; /* gotta be 64 bit */
unsigned int microseconds; /* total time taken */ unsigned int microseconds; /* total time taken */
memset(&tz, 0, sizeof (tz)); memset(&tz, 0, sizeof(tz));
/* get this function in cached memory */ /* get this function in cached memory */
gettimeofday(&tvstart, &tz); 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); (tvstop.tv_usec - tvstart.tv_usec);
snprintf(p_client_buffer, client_buffer_size, p_format, snprintf(p_client_buffer, client_buffer_size, p_format,
(float)((cycles[1] - cycles[0]) / microseconds) / divisor); (float) ((cycles[1] - cycles[0]) / microseconds) / divisor);
#else #else
get_freq(p_client_buffer, client_buffer_size, p_format, divisor, 1); get_freq(p_client_buffer, client_buffer_size, p_format, divisor, 1);
#endif #endif
} }
/*void*/ /* void */
char char get_freq(char *p_client_buffer, size_t client_buffer_size, char *p_format,
get_freq(char *p_client_buffer, size_t client_buffer_size, int divisor, unsigned int cpu)
char *p_format, int divisor, unsigned int cpu)
{ {
int freq = cpu; int freq = cpu;
int mib[2] = { CTL_HW, HW_CPUSPEED }; int mib[2] = { CTL_HW, HW_CPUSPEED };
if (!p_client_buffer || client_buffer_size <= 0 || if (!p_client_buffer || client_buffer_size <= 0 || !p_format
!p_format || divisor <= 0) || divisor <= 0) {
return 0; return 0;
}
size_t size = sizeof(freq); size_t size = sizeof(freq);
if(sysctl(mib, 2, &freq, &size, NULL, 0) == 0)
snprintf(p_client_buffer, client_buffer_size, if (sysctl(mib, 2, &freq, &size, NULL, 0) == 0) {
p_format, (float)freq/divisor); snprintf(p_client_buffer, client_buffer_size, p_format,
else (float) freq / divisor);
} else {
snprintf(p_client_buffer, client_buffer_size, p_format, 0.0f); snprintf(p_client_buffer, client_buffer_size, p_format, 0.0f);
}
return 1; return 1;
} }
void void update_top()
update_top()
{ {
proc_find_top(info.cpu, info.memu); proc_find_top(info.cpu, info.memu);
} }
#if 0 #if 0
/* deprecated, will rewrite this soon in update_net_stats() -hifi */ /* deprecated, will rewrite this soon in update_net_stats() -hifi */
void void update_wifi_stats()
update_wifi_stats()
{ {
struct net_stat * ns; struct net_stat *ns;
struct ifaddrs *ifap, *ifa; struct ifaddrs *ifap, *ifa;
struct ifmediareq ifmr; struct ifmediareq ifmr;
struct ieee80211_nodereq nr; struct ieee80211_nodereq nr;
struct ieee80211_bssid bssid; struct ieee80211_bssid bssid;
int s,ibssid; int s, ibssid;
/* /* Get iface table */
* Get iface table if (getifaddrs(&ifap) < 0) {
*/
if (getifaddrs(&ifap) < 0)
return; return;
}
for (ifa = ifap; ifa; ifa = ifa->ifa_next) { for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
ns = get_net_stat((const char *) ifa->ifa_name); ns = get_net_stat((const char *) ifa->ifa_name);
@@ -614,15 +627,14 @@ update_wifi_stats()
/* Get media type */ /* Get media type */
bzero(&ifmr, sizeof(ifmr)); bzero(&ifmr, sizeof(ifmr));
strlcpy(ifmr.ifm_name, ifa->ifa_name, IFNAMSIZ); 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; goto cleanup;
}
/* /* We can monitor only wireless interfaces
* We can monitor only wireless interfaces * which are not in hostap mode */
* which not in hostap mode if ((ifmr.ifm_active & IFM_IEEE80211)
*/ && !(ifmr.ifm_active & IFM_IEEE80211_HOSTAP)) {
if ((ifmr.ifm_active & IFM_IEEE80211) &&
!(ifmr.ifm_active & IFM_IEEE80211_HOSTAP)) {
/* Get wi status */ /* Get wi status */
memset(&bssid, 0, sizeof(bssid)); memset(&bssid, 0, sizeof(bssid));
@@ -633,51 +645,50 @@ update_wifi_stats()
bcopy(bssid.i_bssid, &nr.nr_macaddr, sizeof(nr.nr_macaddr)); bcopy(bssid.i_bssid, &nr.nr_macaddr, sizeof(nr.nr_macaddr));
strlcpy(nr.nr_ifname, ifa->ifa_name, sizeof(nr.nr_ifname)); 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; ns->linkstatus = nr.nr_rssi;
} }
}
cleanup: cleanup:
close(s); close(s);
} }
} }
#endif #endif
void void update_diskio()
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 int comparecpu(const void *a, const void *b)
comparecpu(const void *a, const void *b)
{ {
if (((struct process *)a)->amount > ((struct process *)b)->amount) if (((struct process *) a)->amount > ((struct process *) b)->amount) {
return (-1); return -1;
}
if (((struct process *)a)->amount < ((struct process *)b)->amount) if (((struct process *) a)->amount < ((struct process *) b)->amount) {
return (1); return 1;
}
return (0); return 0;
} }
int int comparemem(const void *a, const void *b)
comparemem(const void *a, const void *b)
{ {
if (((struct process *)a)->totalmem > ((struct process *)b)->totalmem) if (((struct process *) a)->totalmem > ((struct process *) b)->totalmem) {
return (-1); return -1;
}
if (((struct process *)a)->totalmem < ((struct process *)b)->totalmem) if (((struct process *) a)->totalmem < ((struct process *) b)->totalmem) {
return (1); return 1;
}
return (0); return 0;
} }
inline void inline void proc_find_top(struct process **cpu, struct process **mem)
proc_find_top(struct process **cpu, struct process **mem)
{ {
struct kinfo_proc2 *p; struct kinfo_proc2 *p;
int n_processes; int n_processes;
@@ -692,32 +703,32 @@ proc_find_top(struct process **cpu, struct process **mem)
mib[0] = CTL_HW; mib[0] = CTL_HW;
mib[1] = HW_USERMEM; mib[1] = HW_USERMEM;
size_t size = sizeof(total_pages); 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"); ERR("error reading nmempages");
}
int max_size = sizeof(struct kinfo_proc2); 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++) { for (i = 0; i < n_processes; i++) {
if (!((p[i].p_flag & P_SYSTEM)) && if (!((p[i].p_flag & P_SYSTEM)) && p[i].p_comm != NULL) {
p[i].p_comm != NULL) {
processes[j].pid = p[i].p_pid; processes[j].pid = p[i].p_pid;
processes[j].name = strdup(p[i].p_comm); processes[j].name = strdup(p[i].p_comm);
processes[j].amount = 100.0 * processes[j].amount = 100.0 * p[i].p_pctcpu / FSCALE;
p[i].p_pctcpu / FSCALE; processes[j].totalmem = (float) (p[i].p_vm_rssize * pagesize /
processes[j].totalmem = (float)(p[i].p_vm_rssize * pagesize / (float) total_pages) * 100.0;
(float)total_pages) * 100.0;
j++; j++;
} }
} }
qsort(processes, j - 1, sizeof (struct process), comparemem); qsort(processes, j - 1, sizeof(struct process), comparemem);
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
struct process *tmp, *ttmp; struct process *tmp, *ttmp;
tmp = malloc(sizeof (struct process)); tmp = malloc(sizeof(struct process));
tmp->pid = processes[i].pid; tmp->pid = processes[i].pid;
tmp->amount = processes[i].amount; tmp->amount = processes[i].amount;
tmp->totalmem = processes[i].totalmem; 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++) { for (i = 0; i < 10; i++) {
struct process *tmp, *ttmp; struct process *tmp, *ttmp;
tmp = malloc(sizeof (struct process)); tmp = malloc(sizeof(struct process));
tmp->pid = processes[i].pid; tmp->pid = processes[i].pid;
tmp->amount = processes[i].amount; tmp->amount = processes[i].amount;
tmp->totalmem = processes[i].totalmem; 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); free(processes);
} }
@@ -757,93 +770,91 @@ proc_find_top(struct process **cpu, struct process **mem)
#define APMDEV "/dev/apm" #define APMDEV "/dev/apm"
#define APM_UNKNOWN 255 #define APM_UNKNOWN 255
int int apm_getinfo(int fd, apm_info_t aip)
apm_getinfo(int fd, apm_info_t aip)
{ {
if (ioctl(fd, APM_IOC_GETPOWER, aip) == -1) if (ioctl(fd, APM_IOC_GETPOWER, aip) == -1) {
return (-1); return -1;
}
return (0); return 0;
} }
char char *get_apm_adapter()
*get_apm_adapter()
{ {
int fd; int fd;
struct apm_power_info info; struct apm_power_info info;
char *out; char *out;
out = (char *)calloc(16, sizeof (char)); out = (char *) calloc(16, sizeof(char));
fd = open(APMDEV, O_RDONLY); fd = open(APMDEV, O_RDONLY);
if (fd < 0) { if (fd < 0) {
strncpy(out, "ERR", 16); strncpy(out, "ERR", 16);
return (out); return out;
} }
if (apm_getinfo(fd, &info) != 0) { if (apm_getinfo(fd, &info) != 0) {
close(fd); close(fd);
strncpy(out, "ERR", 16); strncpy(out, "ERR", 16);
return (out); return out;
} }
close(fd); close(fd);
switch (info.ac_state) { switch (info.ac_state) {
case APM_AC_OFF: case APM_AC_OFF:
strncpy(out, "off-line", 16); strncpy(out, "off-line", 16);
return (out); return out;
break; break;
case APM_AC_ON: case APM_AC_ON:
if (info.battery_state == APM_BATT_CHARGING) { if (info.battery_state == APM_BATT_CHARGING) {
strncpy(out, "charging", 16); strncpy(out, "charging", 16);
return (out); return out;
} else { } else {
strncpy(out, "on-line", 16); strncpy(out, "on-line", 16);
return (out); return out;
} }
break; break;
default: default:
strncpy(out, "unknown", 16); strncpy(out, "unknown", 16);
return (out); return out;
break; break;
} }
} }
char char *get_apm_battery_life()
*get_apm_battery_life()
{ {
int fd; int fd;
u_int batt_life; u_int batt_life;
struct apm_power_info info; struct apm_power_info info;
char *out; char *out;
out = (char *)calloc(16, sizeof (char)); out = (char *) calloc(16, sizeof(char));
fd = open(APMDEV, O_RDONLY); fd = open(APMDEV, O_RDONLY);
if (fd < 0) { if (fd < 0) {
strncpy(out, "ERR", 16); strncpy(out, "ERR", 16);
return (out); return out;
} }
if (apm_getinfo(fd, &info) != 0) { if (apm_getinfo(fd, &info) != 0) {
close(fd); close(fd);
strncpy(out, "ERR", 16); strncpy(out, "ERR", 16);
return (out); return out;
} }
close(fd); close(fd);
batt_life = info.battery_life; batt_life = info.battery_life;
if (batt_life <= 100) { if (batt_life <= 100) {
snprintf(out, 16, "%d%%", batt_life); snprintf(out, 16, "%d%%", batt_life);
return (out); return out;
} else } else {
strncpy(out, "ERR", 16); strncpy(out, "ERR", 16);
}
return (out); return out;
} }
char char *get_apm_battery_time()
*get_apm_battery_time()
{ {
int fd; int fd;
int batt_time; int batt_time;
@@ -851,50 +862,45 @@ char
struct apm_power_info info; struct apm_power_info info;
char *out; char *out;
out = (char *)calloc(16, sizeof (char)); out = (char *) calloc(16, sizeof(char));
fd = open(APMDEV, O_RDONLY); fd = open(APMDEV, O_RDONLY);
if (fd < 0) { if (fd < 0) {
strncpy(out, "ERR", 16); strncpy(out, "ERR", 16);
return (out); return out;
} }
if (apm_getinfo(fd, &info) != 0) { if (apm_getinfo(fd, &info) != 0) {
close(fd); close(fd);
strncpy(out, "ERR", 16); strncpy(out, "ERR", 16);
return (out); return out;
} }
close(fd); close(fd);
batt_time = info.minutes_left; batt_time = info.minutes_left;
if (batt_time == -1) if (batt_time == -1) {
strncpy(out, "unknown", 16); strncpy(out, "unknown", 16);
else { } else {
h = batt_time / 60; h = batt_time / 60;
m = batt_time % 60; m = batt_time % 60;
snprintf(out, 16, "%2d:%02d", h, m); snprintf(out, 16, "%2d:%02d", h, m);
} }
return (out); return out;
} }
#endif #endif
/* empty stubs so conky links */ /* empty stubs so conky links */
void void prepare_update()
prepare_update()
{ {
return;
} }
void update_entropy (void) void update_entropy(void)
{ {
return;
} }
void void free_all_processes(void)
free_all_processes(void)
{ {
return;
} }

View File

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

View File

@@ -1,5 +1,4 @@
/* /* $Id$
* $Id$
* *
* Copyright (c) 2007 Mikko Sysikaski <mikko.sysikaski@gmail.com> * Copyright (c) 2007 Mikko Sysikaski <mikko.sysikaski@gmail.com>
* Toni Spets <toni.spets@gmail.com> * Toni Spets <toni.spets@gmail.com>
@@ -14,8 +13,7 @@
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * 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 #ifndef PRSS_H
#define PRSS_H #define PRSS_H
@@ -23,45 +21,45 @@
#include <libxml/parser.h> #include <libxml/parser.h>
typedef struct PRSS_Item_ { typedef struct PRSS_Item_ {
char* title; char *title;
char* link; char *link;
char* description; char *description;
char* category; char *category;
char* pubdate; char *pubdate;
char* guid; char *guid;
} PRSS_Item; } PRSS_Item;
typedef struct PRSS_ { typedef struct PRSS_ {
xmlDocPtr _data; xmlDocPtr _data;
char* version; char *version;
char* title; char *title;
char* link; char *link;
char* description; char *description;
char* language; char *language;
char* generator; char *generator;
char* managingeditor; char *managingeditor;
char* webmaster; char *webmaster;
char* docs; char *docs;
char* lastbuilddate; char *lastbuilddate;
char* pubdate; char *pubdate;
char* copyright; char *copyright;
char* ttl; char *ttl;
PRSS_Item* items; PRSS_Item *items;
int item_count; int item_count;
} PRSS; } PRSS;
/* Functions for parsing RSS-data */ /* Functions for parsing RSS-data */
PRSS* prss_parse_data(const char *xml_data); PRSS *prss_parse_data(const char *xml_data);
PRSS* prss_parse_file(const char *xml_file); PRSS *prss_parse_file(const char *xml_file);
// Works wrong currently when called from application! /* // Works wrong currently when called from application!
//PRSS* prss_parse_doc(xmlDocPtr doc); PRSS *prss_parse_doc(xmlDocPtr doc); */
/* Frees the PRSS-stucture returned by prss_parse_*. /* Frees the PRSS-stucture returned by prss_parse_*.
* The memory area pointed by data becomes invalid * The memory area pointed by data becomes invalid
* after call to this function. */ * 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 * Any original torsmo code is licensed under the BSD license
* *
@@ -8,7 +7,8 @@
* Please see COPYING for details * Please see COPYING for details
* *
* Copyright (c) 2007 Toni Spets * 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. * All rights reserved.
* *
* This program is free software: you can redistribute it and/or modify * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
* $Id$ * $Id$ */
*/
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -44,21 +43,20 @@ struct MemoryStruct {
}; };
typedef struct feed_ { typedef struct feed_ {
char* uri; char *uri;
int last_update; int last_update;
PRSS* data; PRSS *data;
} feed; } feed;
int num_feeds = 0; int num_feeds = 0;
feed feeds[MAX_FEEDS]; feed feeds[MAX_FEEDS];
size_t size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
{ {
size_t realsize = size * nmemb; 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) { if (mem->memory) {
memcpy(&(mem->memory[mem->size]), ptr, realsize); memcpy(&(mem->memory[mem->size]), ptr, realsize);
mem->size += realsize; mem->size += realsize;
@@ -67,21 +65,22 @@ WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
return realsize; return realsize;
} }
int rss_delay(int *wait, int delay) int rss_delay(int *wait, int delay)
{ {
time_t now = time(NULL); time_t now = time(NULL);
// make it minutes // make it minutes
if(delay < 1) delay = 1; if (delay < 1) {
delay = 1;
}
delay *= 60; delay *= 60;
if(!*wait) { if (!*wait) {
*wait = now + delay; *wait = now + delay;
return 1; return 1;
} }
if(now >= *wait + delay) { if (now >= *wait + delay) {
*wait = now + delay; *wait = now + delay;
return 1; return 1;
} }
@@ -92,7 +91,8 @@ int rss_delay(int *wait, int delay)
void init_rss_info() void init_rss_info()
{ {
int i; int i;
for(i = 0; i < MAX_FEEDS; i++) {
for (i = 0; i < MAX_FEEDS; i++) {
feeds[i].uri = NULL; feeds[i].uri = NULL;
feeds[i].data = NULL; feeds[i].data = NULL;
feeds[i].last_update = 0; feeds[i].last_update = 0;
@@ -102,18 +102,22 @@ void init_rss_info()
void free_rss_info() void free_rss_info()
{ {
int i; 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); free(feeds[i].uri);
}
}
} }
PRSS* PRSS *get_rss_info(char *uri, int delay)
get_rss_info(char *uri, int delay)
{ {
CURL *curl = NULL; CURL *curl = NULL;
CURLcode res; CURLcode res;
// curl temps // curl temps
struct MemoryStruct chunk; struct MemoryStruct chunk;
chunk.memory = NULL; chunk.memory = NULL;
chunk.size = 0; chunk.size = 0;
@@ -125,16 +129,19 @@ get_rss_info(char *uri, int delay)
int i; int i;
// first seek for the uri in list // first seek for the uri in list
for(i = 0; i < num_feeds; i++) { for (i = 0; i < num_feeds; i++) {
if(feeds[i].uri != NULL) if (feeds[i].uri != NULL) {
if(!strcmp(feeds[i].uri, uri)) { if (!strcmp(feeds[i].uri, uri)) {
curfeed = &feeds[i]; curfeed = &feeds[i];
break; break;
} }
} }
}
if(!curfeed) { // new feed if (!curfeed) { // new feed
if(num_feeds == MAX_FEEDS-1) return NULL; if (num_feeds == MAX_FEEDS - 1) {
return NULL;
}
curfeed = &feeds[num_feeds]; curfeed = &feeds[num_feeds];
curfeed->uri = strdup(uri); curfeed->uri = strdup(uri);
num_feeds++; num_feeds++;
@@ -143,28 +150,30 @@ get_rss_info(char *uri, int delay)
last_update = &curfeed->last_update; last_update = &curfeed->last_update;
curdata = curfeed->data; curdata = curfeed->data;
if(!rss_delay(last_update, delay)) if (!rss_delay(last_update, delay)) {
return curdata; // wait for delay to pass return curdata; // wait for delay to pass
}
if(curdata != NULL) { if (curdata != NULL) {
prss_free(curdata); // clean up old data prss_free(curdata); // clean up old data
curdata = NULL; curdata = NULL;
} }
curl = curl_easy_init(); curl = curl_easy_init();
if(curl) { if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, uri); curl_easy_setopt(curl, CURLOPT_URL, uri);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); 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"); curl_easy_setopt(curl, CURLOPT_USERAGENT, "conky-rss/1.0");
res = curl_easy_perform(curl); res = curl_easy_perform(curl);
if(chunk.size) { if (chunk.size) {
curdata = prss_parse_data(chunk.memory); curdata = prss_parse_data(chunk.memory);
free(chunk.memory); free(chunk.memory);
} else } else {
ERR("No data from server"); ERR("No data from server");
}
curl_easy_cleanup(curl); 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 * Any original torsmo code is licensed under the BSD license
* *
@@ -7,7 +6,8 @@
* *
* Please see COPYING for details * 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. * All rights reserved.
* *
* This program is free software: you can redistribute it and/or modify * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
* $Id$ * $Id$ */
*/
/* doesn't work, feel free to finish this */ /* doesn't work, feel free to finish this */
#include "conky.h" #include "conky.h"
@@ -62,12 +61,10 @@ double get_uptime()
if (ksp != NULL) { if (ksp != NULL) {
if (kstat_read(kstat, ksp, NULL) >= 0) { if (kstat_read(kstat, ksp, NULL) >= 0) {
kstat_named_t *knp; kstat_named_t *knp;
knp =
(kstat_named_t *) kstat_data_lookup(ksp, knp = (kstat_named_t *) kstat_data_lookup(ksp, "boot_time");
"boot_time");
if (knp != NULL) { if (knp != NULL) {
return get_time() - return get_time() - (double) knp->value.ui32;
(double) knp->value.ui32;
} }
} }
} }

View File

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

View File

@@ -1,7 +1,6 @@
/* $Id$ */ /* $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 * 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 * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
* USA. * USA. */
*
*/
#ifndef _TIMED_THREAD_H_ #ifndef _TIMED_THREAD_H_
#define _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 */ /* opaque structure for clients */
typedef struct _timed_thread timed_thread; typedef struct _timed_thread timed_thread;
/* create a timed thread (object creation only) */ /* 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) */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* waits required interval for termination signal
int timed_thread_test (timed_thread* p_timed_thread); * returns 1 if received,
* 0 otherwise */
int timed_thread_test(timed_thread *p_timed_thread);
/* exit a 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() */ /* register a timed thread for future destruction via
int timed_thread_register (timed_thread* p_timed_thread, timed_thread** addr_of_p_timed_thread); * 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 */ /* destroy all registered timed threads */
void timed_thread_destroy_registered_threads (void); void timed_thread_destroy_registered_threads(void);
#endif /* #ifdef _TIMED_THREAD_H_ */ #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 * 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>, * Copyright (c) 2005 Adi Zaimi, Dan Piponi <dan@tanelorn.demon.co.uk>,
* Dave Clark <clarkd@skynet.ca> * 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. * All rights reserved.
* *
* This program is free software: you can redistribute it and/or modify * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
* $Id$ * $Id$ */
*/
#include "top.h" #include "top.h"
@@ -38,11 +37,10 @@ struct process *get_first_process()
return first_process; return first_process;
} }
void free_all_processes() void free_all_processes()
{ {
struct process *next = NULL, *pr = first_process; struct process *next = NULL, *pr = first_process;
while (pr) { while (pr) {
next = pr->next; next = pr->next;
if (pr->name) { if (pr->name) {
@@ -57,33 +55,32 @@ void free_all_processes()
static struct process *find_process(pid_t pid) static struct process *find_process(pid_t pid)
{ {
struct process *p = first_process; struct process *p = first_process;
while (p) { while (p) {
if (p->pid == pid) if (p->pid == pid) {
return p; return p;
}
p = p->next; p = p->next;
} }
return 0; 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) static struct process *new_process(int p)
{ {
struct process *process; struct process *process;
process = (struct process*)malloc(sizeof(struct process)); process = (struct process *) malloc(sizeof(struct process));
// clean up memory first // clean up memory first
memset(process, 0, sizeof(struct process)); memset(process, 0, sizeof(struct process));
/* /* Do stitching necessary for doubly linked list */
* Do stitching necessary for doubly linked list
*/
process->name = 0; process->name = 0;
process->previous = 0; process->previous = 0;
process->next = first_process; process->next = first_process;
if (process->next) if (process->next) {
process->next->previous = process; process->next->previous = process;
}
first_process = process; first_process = process;
process->pid = p; process->pid = p;
@@ -92,37 +89,25 @@ static struct process *new_process(int p)
process->previous_kernel_time = ULONG_MAX; process->previous_kernel_time = ULONG_MAX;
process->counted = 1; process->counted = 1;
/* process_find_name(process); */ /* process_find_name(process); */
return process; return process;
} }
/******************************************/ /******************************************
/* Functions */ * Functions *
/******************************************/ ******************************************/
static int process_parse_stat(struct process *); /******************************************
static int update_process_table(void); * Extract information from /proc *
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);
/* These are the guts that extract information out of /proc.
/******************************************/ * Anyone hoping to port wmtop should look here first. */
/* Extract information from /proc */
/******************************************/
/*
* 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) static int process_parse_stat(struct process *process)
{ {
struct information *cur; struct information *cur;
cur = &info; cur = &info;
char line[BUFFER_LEN] = { 0 }, filename[BUFFER_LEN], procname[BUFFER_LEN]; char line[BUFFER_LEN] = { 0 }, filename[BUFFER_LEN], procname[BUFFER_LEN];
int ps; int ps;
@@ -134,50 +119,42 @@ static int process_parse_stat(struct process *process)
int endl; int endl;
int nice_val; int nice_val;
snprintf(filename, sizeof(filename), PROCFS_TEMPLATE, snprintf(filename, sizeof(filename), PROCFS_TEMPLATE, process->pid);
process->pid);
ps = open(filename, O_RDONLY); ps = open(filename, O_RDONLY);
if (ps < 0) if (ps < 0) {
/* /* The process must have finished in the last few jiffies! */
* The process must have finished in the last few jiffies!
*/
return 1; return 1;
}
/* /* Mark process as up-to-date. */
* Mark process as up-to-date.
*/
process->time_stamp = g_time; process->time_stamp = g_time;
rc = read(ps, line, sizeof(line)); rc = read(ps, line, sizeof(line));
close(ps); close(ps);
if (rc < 0) if (rc < 0) {
return 1; return 1;
}
/* /* Extract cpu times from data in /proc filesystem */
* 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,
rc = sscanf(line, &process->kernel_time, &nice_val, &process->vsize, &process->rss);
"%*s %s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %lu %lu %*s %*s %*s %d %*s %*s %*s %d %d", if (rc < 5) {
procname, &process->user_time, &process->kernel_time,
&nice_val, &process->vsize, &process->rss);
if (rc < 5)
return 1; 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; r = procname + 1;
/* remove any "kdeinit: " */ /* remove any "kdeinit: " */
if (r == strstr(r, "kdeinit")) { if (r == strstr(r, "kdeinit")) {
snprintf(filename, sizeof(filename), snprintf(filename, sizeof(filename), PROCFS_CMDLINE_TEMPLATE,
PROCFS_CMDLINE_TEMPLATE, process->pid); process->pid);
ps = open(filename, O_RDONLY); ps = open(filename, O_RDONLY);
if (ps < 0) if (ps < 0) {
/* /* The process must have finished in the last few jiffies! */
* The process must have finished in the last few jiffies!
*/
return 1; return 1;
}
endl = read(ps, line, sizeof(line)); endl = read(ps, line, sizeof(line));
close(ps); close(ps);
@@ -185,20 +162,23 @@ static int process_parse_stat(struct process *process)
/* null terminate the input */ /* null terminate the input */
line[endl] = 0; line[endl] = 0;
/* account for "kdeinit: " */ /* account for "kdeinit: " */
if ((char *) line == strstr(line, "kdeinit: ")) if ((char *) line == strstr(line, "kdeinit: ")) {
r = ((char *) line) + 9; r = ((char *) line) + 9;
else } else {
r = (char *) line; r = (char *) line;
}
q = deparenthesised_name; q = deparenthesised_name;
/* stop at space */ /* stop at space */
while (*r && *r != ' ') while (*r && *r != ' ') {
*q++ = *r++; *q++ = *r++;
}
*q = 0; *q = 0;
} else { } else {
q = deparenthesised_name; q = deparenthesised_name;
while (*r && *r != ')') while (*r && *r != ')') {
*q++ = *r++; *q++ = *r++;
}
*q = 0; *q = 0;
} }
@@ -208,17 +188,18 @@ static int process_parse_stat(struct process *process)
process->name = strdup(deparenthesised_name); process->name = strdup(deparenthesised_name);
process->rss *= getpagesize(); process->rss *= getpagesize();
if (!cur->memmax) if (!cur->memmax) {
update_total_processes(); update_total_processes();
}
process->total_cpu_time = process->user_time + process->kernel_time; process->total_cpu_time = process->user_time + process->kernel_time;
process->totalmem = (float)(((float) process->rss / cur->memmax) / 10); process->totalmem = (float) (((float) process->rss / cur->memmax) / 10);
if (process->previous_user_time == ULONG_MAX) if (process->previous_user_time == ULONG_MAX) {
process->previous_user_time = process->user_time; 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; process->previous_kernel_time = process->kernel_time;
}
/* store the difference of the user_time */ /* store the difference of the user_time */
user_time = process->user_time - process->previous_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->user_time = user_time;
process->kernel_time = kernel_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; return 0;
} }
/******************************************/ /******************************************
/* Update process table */ * Update process table *
/******************************************/ ******************************************/
static int update_process_table() static int update_process_table()
{ {
DIR *dir; DIR *dir;
struct dirent *entry; struct dirent *entry;
if (!(dir = opendir("/proc"))) if (!(dir = opendir("/proc"))) {
return 1; return 1;
}
++g_time; ++g_time;
/* /* Get list of processes from /proc directory */
* Get list of processes from /proc directory
*/
while ((entry = readdir(dir))) { while ((entry = readdir(dir))) {
pid_t pid; pid_t pid;
if (!entry) { if (!entry) {
/* /* Problem reading list of processes */
* Problem reading list of processes
*/
closedir(dir); closedir(dir);
return 1; return 1;
} }
if (sscanf(entry->d_name, "%d", &pid) > 0) { if (sscanf(entry->d_name, "%d", &pid) > 0) {
struct process *p; struct process *p;
p = find_process(pid); p = find_process(pid);
if (!p) if (!p) {
p = new_process(pid); p = new_process(pid);
}
/* compute each process cpu usage */ /* compute each process cpu usage */
calculate_cpu(p); calculate_cpu(p);
@@ -280,64 +285,9 @@ static int update_process_table()
return 0; return 0;
} }
/******************************************/ /******************************************
/* Get process structure for process pid */ * Destroy and remove a process *
/******************************************/ ******************************************/
/*
* 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 */
/******************************************/
static void delete_process(struct process *p) static void delete_process(struct process *p)
{ {
@@ -366,9 +316,33 @@ static void delete_process(struct process *p)
free(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_SHORTPROC "%*s %llu %llu %llu %llu"
#define TMPL_LONGPROC "%*s %llu %llu %llu %llu %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 irq = 0;
unsigned long long softirq = 0; unsigned long long softirq = 0;
unsigned long long steal = 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); ps = open("/proc/stat", O_RDONLY);
rc = read(ps, line, sizeof(line)); rc = read(ps, line, sizeof(line));
close(ps); close(ps);
if (rc < 0) if (rc < 0) {
return 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; total = cpu + nice + system + idle + iowait + irq + softirq + steal;
t = total - previous_total; t = total - previous_total;
@@ -404,102 +381,112 @@ static unsigned long long calc_cpu_total()
return t; return t;
} }
/******************************************/ /******************************************
/* Calculate each processes cpu */ * Calculate each processes cpu *
/******************************************/ ******************************************/
inline static void calc_cpu_each(unsigned long long total) inline static void calc_cpu_each(unsigned long long total)
{ {
struct process *p = first_process; struct process *p = first_process;
while (p) { while (p) {
p->amount = p->amount = 100.0 * (cpu_separate ? info.cpu_count : 1) *
100.0 * (cpu_separate ? info.cpu_count : 1) * (p->user_time + p->kernel_time) / (float)total; (p->user_time + p->kernel_time) / (float) total;
p = p->next; p = p->next;
} }
} }
/******************************************/ /******************************************
/* Find the top processes */ * Find the top processes *
/******************************************/ ******************************************/
/* /* free a sp_process structure */
* free a sp_process structure void free_sp(struct sorted_process *sp)
*/ {
void free_sp(struct sorted_process * sp) {
free(sp); free(sp);
} }
/* /* create a new sp_process structure */
* create a new sp_process structure struct sorted_process *malloc_sp(struct process *proc)
*/ {
struct sorted_process * malloc_sp(struct process * proc) { struct sorted_process *sp;
struct sorted_process * sp;
sp = malloc(sizeof(struct sorted_process)); sp = malloc(sizeof(struct sorted_process));
sp->greater = NULL; sp->greater = NULL;
sp->less = NULL; sp->less = NULL;
sp->proc = proc; sp->proc = proc;
return(sp); return sp;
} }
/* /* cpu comparison function for insert_sp_element */
* cpu comparison function for insert_sp_element int compare_cpu(struct process *a, struct process *b)
*/ {
int compare_cpu(struct process *a, struct process *b) { if (a->amount < b->amount) {
if (a->amount < b->amount) return 1; return 1;
} else if (a->amount > b->amount) {
return -1;
} else {
return 0; return 0;
}
} }
/* /* mem comparison function for insert_sp_element */
* mem comparison function for insert_sp_element int compare_mem(struct process *a, struct process *b)
*/ {
int compare_mem(struct process *a, struct process *b) { if (a->totalmem < b->totalmem) {
if (a->totalmem < b->totalmem) return 1; return 1;
} else if (a->totalmem > b->totalmem) {
return -1;
} else {
return 0; return 0;
}
} }
/* /* insert this process into the list in a sorted fashion,
* insert this process into the list in a sorted fashion, * or destroy it if it doesn't fit on the list */
* 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 insert_sp_element( int max_elements, int compare_funct(struct process *, struct process *))
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; int did_insert = 0, x = 0;
if (*p_sp_head == NULL) { if (*p_sp_head == NULL) {
*p_sp_head = sp_cur; *p_sp_head = sp_cur;
*p_sp_tail = 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++) { for (sp_readthru = *p_sp_head, x = 0;
if (compare_funct(sp_readthru->proc, sp_cur->proc) && !did_insert) { sp_readthru != NULL && x < max_elements;
/* sp_cur is bigger than sp_readthru so insert it before sp_readthru */ sp_readthru = sp_readthru->less, x++) {
sp_cur->less=sp_readthru; 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) { 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 { } 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_cur->greater = sp_readthru->greater;
} }
sp_readthru->greater=sp_cur; sp_readthru->greater = sp_cur;
did_insert = ++x; /* element was inserted, so increase the counter */ /* element was inserted, so increase the counter */
did_insert = ++x;
} }
} }
if (x < max_elements && sp_readthru == NULL && !did_insert) { 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 */ /* sp_cur is the smallest element and list isn't full,
(*p_sp_tail)->less=sp_cur; * so insert at the end */
sp_cur->greater=*p_sp_tail; (*p_sp_tail)->less = sp_cur;
sp_cur->greater = *p_sp_tail;
*p_sp_tail = sp_cur; *p_sp_tail = sp_cur;
did_insert=x; did_insert = x;
} else if (x >= max_elements) { } 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; sp_destroy = *p_sp_tail;
*p_sp_tail = sp_destroy->greater; *p_sp_tail = sp_destroy->greater;
(*p_sp_tail)->less = NULL; (*p_sp_tail)->less = NULL;
@@ -512,26 +499,25 @@ int insert_sp_element(
return did_insert; return did_insert;
} }
/* /* copy the procs in the sorted list to the array, and destroy the list */
* 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)
*/
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; int x;
sp_cur = sp_head; 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; ar[x] = sp_cur->proc;
sp_tmp = sp_cur; sp_tmp = sp_cur;
sp_cur= sp_cur->less; sp_cur = sp_cur->less;
free_sp(sp_tmp); free_sp(sp_tmp);
} }
} }
/* ****************************************************************** */ /* ****************************************************************** *
/* Get a sorted list of the top cpu hogs and top mem hogs. */ * 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]. */ * Results are stored in the cpu,mem arrays in decreasing order[0-9]. *
/* ****************************************************************** */ * ****************************************************************** */
inline void process_find_top(struct process **cpu, struct process **mem) 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; struct process *cur_proc = NULL;
unsigned long long total = 0; 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 */ total = calc_cpu_total(); /* calculate the total of the processor */
update_process_table(); /* update the table with process list */ 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; cur_proc = first_process;
while (cur_proc !=NULL) { while (cur_proc != NULL) {
if (top_cpu) { if (top_cpu) {
spc_cur = malloc_sp(cur_proc); 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) { if (top_mem) {
spm_cur = malloc_sp(cur_proc); 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; cur_proc = cur_proc->next;
} }
sp_acopy(spc_head, cpu, MAX_SP); sp_acopy(spc_head, cpu, MAX_SP);
sp_acopy(spm_head, mem, 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 * 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>, * Copyright (c) 2005 Adi Zaimi, Dan Piponi <dan@tanelorn.demon.co.uk>,
* Dave Clark <clarkd@skynet.ca> * 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. * All rights reserved.
* *
* This program is free software: you can redistribute it and/or modify * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
* $Id$ * $Id$ */
*/
/* /* Ensure there's an operating system defined.
* Ensure there's an operating system defined. There is *no* default
* because every OS has it's own way of revealing CPU/memory usage.
* compile with gcc -DOS ... * 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" #include "conky.h"
#define CPU_THRESHHOLD 0 /* threshhold for the cpu diff to appear */ #define CPU_THRESHHOLD 0 /* threshhold for the cpu diff to appear */
@@ -62,28 +60,28 @@
#include <regex.h> #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 BUFFER_LEN 1024
#define PROCFS_TEMPLATE "/proc/%d/stat" #define PROCFS_TEMPLATE "/proc/%d/stat"
#define PROCFS_TEMPLATE_MEM "/proc/%d/statm" #define PROCFS_TEMPLATE_MEM "/proc/%d/statm"
#define PROCFS_CMDLINE_TEMPLATE "/proc/%d/cmdline" #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; extern int cpu_separate;
/******************************************/ /******************************************
/* Process class */ * Process class *
/******************************************/ ******************************************/
struct sorted_process { struct sorted_process {
struct sorted_process *greater; struct sorted_process *greater;
@@ -91,7 +89,5 @@ struct sorted_process {
struct process *proc; struct process *proc;
}; };
/* /* Pointer to head of process list */
* Pointer to head of process list
*/
void process_find_top(struct process **, struct process **); 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 * Any original torsmo code is licensed under the BSD license
* *
@@ -8,7 +7,8 @@
* Please see COPYING for details * Please see COPYING for details
* *
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen * 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. * All rights reserved.
* *
* This program is free software: you can redistribute it and/or modify * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
* $Id$ * $Id$ */
*/
#include "conky.h" #include "conky.h"
@@ -67,8 +66,9 @@ static Window find_subwindow(Window win, int w, int h);
/* X11 initializer */ /* X11 initializer */
void init_X11() void init_X11()
{ {
if ((display = XOpenDisplay(0)) == NULL) if ((display = XOpenDisplay(0)) == NULL) {
CRIT_ERR("can't open display: %s", XDisplayName(0)); CRIT_ERR("can't open display: %s", XDisplayName(0));
}
screen = DefaultScreen(display); screen = DefaultScreen(display);
display_width = DisplayWidth(display, screen); display_width = DisplayWidth(display, screen);
@@ -92,17 +92,15 @@ static void update_workarea()
workarea[3] = display_height; workarea[3] = display_height;
/* get current desktop */ /* get current desktop */
if (XGetWindowProperty(display, root, ATOM(_NET_CURRENT_DESKTOP), if (XGetWindowProperty(display, root, ATOM(_NET_CURRENT_DESKTOP), 0, 1,
0, 1, False, XA_CARDINAL, &type, &format, False, XA_CARDINAL, &type, &format, &nitems, &bytes, &buf)
&nitems, &bytes, &buf) == Success == Success && type == XA_CARDINAL && nitems > 0) {
&& type == XA_CARDINAL && nitems > 0) {
//Currently unused // Currently unused
/* long desktop = * (long *) buf; */ /* long desktop = *(long *) buf; */
XFree(buf); XFree(buf);
buf = 0; buf = 0;
} }
if (buf) { if (buf) {
@@ -111,8 +109,10 @@ static void update_workarea()
} }
} }
/* Find root window and desktop window. Return desktop window on success, /* Find root window and desktop window.
* and set root and desktop byref return values. Return 0 on failure. */ * 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) static Window find_desktop_window(Window *p_root, Window *p_desktop)
{ {
Atom type; Atom type;
@@ -124,25 +124,26 @@ static Window find_desktop_window(Window *p_root, Window *p_desktop)
Window troot, parent, *children; Window troot, parent, *children;
unsigned char *buf = NULL; unsigned char *buf = NULL;
if (!p_root || !p_desktop) if (!p_root || !p_desktop) {
return(0); return 0;
}
/* some window managers set __SWM_VROOT to some child of root window */ /* some window managers set __SWM_VROOT to some child of root window */
XQueryTree(display, root, &troot, &parent, &children, &n); XQueryTree(display, root, &troot, &parent, &children, &n);
for (i = 0; i < (int) n; i++) { for (i = 0; i < (int) n; i++) {
if (XGetWindowProperty if (XGetWindowProperty(display, children[i], ATOM(__SWM_VROOT), 0, 1,
(display, children[i], ATOM(__SWM_VROOT), 0, 1, False, False, XA_WINDOW, &type, &format, &nitems, &bytes, &buf)
XA_WINDOW, &type, &format, &nitems, &bytes, == Success && type == XA_WINDOW) {
&buf) == Success && type == XA_WINDOW) {
win = *(Window *) buf; win = *(Window *) buf;
XFree(buf); XFree(buf);
XFree(children); XFree(children);
fprintf(stderr, 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); fflush(stderr);
*p_root=win; *p_root = win;
*p_desktop=win; *p_desktop = win;
return win; return win;
} }
@@ -165,16 +166,18 @@ static Window find_desktop_window(Window *p_root, Window *p_desktop)
buf = 0; buf = 0;
} }
if (win != root) if (win != root) {
fprintf(stderr, fprintf(stderr,
"Conky: desktop window (%lx) is subwindow of root window (%lx)\n",win,root); "Conky: desktop window (%lx) is subwindow of root window (%lx)\n",
else win, root);
fprintf(stderr, "Conky: desktop window (%lx) is root window\n",win); } else {
fprintf(stderr, "Conky: desktop window (%lx) is root window\n", win);
}
fflush(stderr); fflush(stderr);
*p_root=root; *p_root = root;
*p_desktop=win; *p_desktop = win;
return 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) inline void set_transparent_background(Window win)
{ {
static int colour_set = -1; static int colour_set = -1;
if (set_transparent) { if (set_transparent) {
Window parent = win; Window parent = win;
unsigned int i; unsigned int i;
for (i = 0; i < 50 && parent != RootWindow(display, screen); i++) { for (i = 0; i < 50 && parent != RootWindow(display, screen); i++) {
Window r, *children; Window r, *children;
unsigned int n; unsigned int n;
@@ -198,15 +203,15 @@ inline void set_transparent_background(Window win)
} else if (colour_set != background_colour) { } else if (colour_set != background_colour) {
XSetWindowBackground(display, win, background_colour); XSetWindowBackground(display, win, background_colour);
colour_set = 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, void init_window(int own_window, int w, int h, int set_trans, int back_colour,
char **argv, int argc) char **argv, int argc)
{ {
/* There seems to be some problems with setting transparent background (on /* There seems to be some problems with setting transparent background
* fluxbox this time). It doesn't happen always and I don't know why it * (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. */ * happens but I bet the bug is somewhere here. */
set_transparent = set_trans; set_transparent = set_trans;
background_colour = back_colour; 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 #ifdef OWN_WINDOW
if (own_window) { if (own_window) {
if ( !find_desktop_window( &window.root, &window.desktop ) ) if (!find_desktop_window(&window.root, &window.desktop)) {
return; return;
}
if (window.type == TYPE_OVERRIDE) { if (window.type == TYPE_OVERRIDE) {
/* /* An override_redirect True window.
An override_redirect True window. No WM hints or button processing needed. * No WM hints or button processing needed. */
*/ XSetWindowAttributes attrs = { ParentRelative, 0L, 0, 0L, 0, 0,
XSetWindowAttributes attrs = { Always, 0L, 0L, False, StructureNotifyMask | ExposureMask, 0L,
ParentRelative,0L,0,0L,0,0,Always,0L,0L,False, True, 0, 0 };
StructureNotifyMask|ExposureMask,
0L,
True,
0,0 };
/* Parent is desktop window (which might be a child of root) */ /* Parent is desktop window (which might be a child of root) */
window.window = XCreateWindow(display, window.window = XCreateWindow(display, window.desktop, window.x,
window.desktop, window.y, w, h, 0, CopyFromParent, InputOutput, CopyFromParent,
window.x, window.y, w, h, 0, CWBackPixel | CWOverrideRedirect, &attrs);
CopyFromParent,
InputOutput,
CopyFromParent,
CWBackPixel|CWOverrideRedirect,
&attrs);
XLowerWindow(display, window.window); 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 */
} /* A window managed by the window manager.
* Process hints and buttons. */
else { /* window.type != TYPE_OVERRIDE */ 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; XClassHint classHint;
XWMHints wmHint; XWMHints wmHint;
Atom xa; Atom xa;
/* Parent is root window so WM can take control */ /* Parent is root window so WM can take control */
window.window = XCreateWindow(display, window.window = XCreateWindow(display, window.root, window.x,
window.root, window.y, w, h, 0, CopyFromParent, InputOutput, CopyFromParent,
window.x, window.y, w, h, 0, CWBackPixel | CWOverrideRedirect, &attrs);
CopyFromParent,
InputOutput,
CopyFromParent,
CWBackPixel|CWOverrideRedirect,
&attrs);
classHint.res_name = window.class_name; classHint.res_name = window.class_name;
classHint.res_class = classHint.res_name; classHint.res_class = classHint.res_name;
wmHint.flags = InputHint | StateHint; wmHint.flags = InputHint | StateHint;
/* allow decorated windows to be given input focus by WM */ /* 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; wmHint.initial_state = NormalState;
XmbSetWMProperties (display, window.window, window.title, NULL, XmbSetWMProperties(display, window.window, window.title, NULL, argv,
argv, argc, argc, NULL, &wmHint, &classHint);
NULL, &wmHint, &classHint);
/* Sets an empty WM_PROTOCOLS property */ /* Sets an empty WM_PROTOCOLS property */
XSetWMProtocols(display,window.window,NULL,0); XSetWMProtocols(display, window.window, NULL, 0);
/* Set window type */ /* Set window type */
if ( (xa = ATOM(_NET_WM_WINDOW_TYPE)) != None ) if ((xa = ATOM(_NET_WM_WINDOW_TYPE)) != None) {
{
Atom prop; Atom prop;
switch(window.type) {
switch (window.type) {
case TYPE_DESKTOP: case TYPE_DESKTOP:
{
prop = ATOM(_NET_WM_WINDOW_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; break;
case TYPE_NORMAL: case TYPE_NORMAL:
default: default:
{
prop = ATOM(_NET_WM_WINDOW_TYPE_NORMAL); 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; break;
} }
XChangeProperty(display, window.window, xa, XChangeProperty(display, window.window, xa, XA_ATOM, 32,
XA_ATOM, 32, PropModeReplace, (unsigned char *) &prop, 1);
PropModeReplace,
(unsigned char *) &prop, 1);
} }
/* Set desired hints */ /* Set desired hints */
/* Window decorations */ /* Window decorations */
if (TEST_HINT(window.hints,HINT_UNDECORATED)) { if (TEST_HINT(window.hints, HINT_UNDECORATED)) {
/*fprintf(stderr, "Conky: hint - undecorated\n"); fflush(stderr);*/ /* fprintf(stderr, "Conky: hint - undecorated\n");
fflush(stderr); */
xa = ATOM(_MOTIF_WM_HINTS); xa = ATOM(_MOTIF_WM_HINTS);
if (xa != None) { if (xa != None) {
long prop[5] = { 2, 0, 0, 0, 0 }; long prop[5] = { 2, 0, 0, 0, 0 };
XChangeProperty(display, window.window, xa, XChangeProperty(display, window.window, xa, xa, 32,
xa, 32, PropModeReplace, PropModeReplace, (unsigned char *) prop, 5);
(unsigned char *) prop, 5);
} }
} }
/* Below other windows */ /* Below other windows */
if (TEST_HINT(window.hints,HINT_BELOW)) { if (TEST_HINT(window.hints, HINT_BELOW)) {
/*fprintf(stderr, "Conky: hint - below\n"); fflush(stderr); */ /* fprintf(stderr, "Conky: hint - below\n");
fflush(stderr); */
xa = ATOM(_WIN_LAYER); xa = ATOM(_WIN_LAYER);
if (xa != None) { if (xa != None) {
long prop = 0; long prop = 0;
XChangeProperty(display, window.window, xa,
XA_CARDINAL, 32, XChangeProperty(display, window.window, xa, XA_CARDINAL, 32,
PropModeAppend, PropModeAppend, (unsigned char *) &prop, 1);
(unsigned char *) &prop, 1);
} }
xa = ATOM(_NET_WM_STATE); xa = ATOM(_NET_WM_STATE);
if (xa != None) { if (xa != None) {
Atom xa_prop = ATOM(_NET_WM_STATE_BELOW); Atom xa_prop = ATOM(_NET_WM_STATE_BELOW);
XChangeProperty(display, window.window, xa,
XA_ATOM, 32, XChangeProperty(display, window.window, xa, XA_ATOM, 32,
PropModeAppend, PropModeAppend, (unsigned char *) &xa_prop, 1);
(unsigned char *) &xa_prop,
1);
} }
} }
/* Above other windows */ /* Above other windows */
if (TEST_HINT(window.hints,HINT_ABOVE)) { if (TEST_HINT(window.hints, HINT_ABOVE)) {
/*fprintf(stderr, "Conky: hint - above\n"); fflush(stderr);*/ /* fprintf(stderr, "Conky: hint - above\n");
fflush(stderr); */
xa = ATOM(_WIN_LAYER); xa = ATOM(_WIN_LAYER);
if (xa != None) { if (xa != None) {
long prop = 6; long prop = 6;
XChangeProperty(display, window.window, xa,
XA_CARDINAL, 32, XChangeProperty(display, window.window, xa, XA_CARDINAL, 32,
PropModeAppend, PropModeAppend, (unsigned char *) &prop, 1);
(unsigned char *) &prop, 1);
} }
xa = ATOM(_NET_WM_STATE); xa = ATOM(_NET_WM_STATE);
if (xa != None) { if (xa != None) {
Atom xa_prop = ATOM(_NET_WM_STATE_ABOVE); Atom xa_prop = ATOM(_NET_WM_STATE_ABOVE);
XChangeProperty(display, window.window, xa,
XA_ATOM, 32, XChangeProperty(display, window.window, xa, XA_ATOM, 32,
PropModeAppend, PropModeAppend, (unsigned char *) &xa_prop, 1);
(unsigned char *) &xa_prop,
1);
} }
} }
/* Sticky */ /* Sticky */
if (TEST_HINT(window.hints,HINT_STICKY)) { if (TEST_HINT(window.hints, HINT_STICKY)) {
/*fprintf(stderr, "Conky: hint - sticky\n"); fflush(stderr); */ /* fprintf(stderr, "Conky: hint - sticky\n");
fflush(stderr); */
xa = ATOM(_NET_WM_DESKTOP); xa = ATOM(_NET_WM_DESKTOP);
if (xa != None) { if (xa != None) {
CARD32 xa_prop = 0xFFFFFFFF; CARD32 xa_prop = 0xFFFFFFFF;
XChangeProperty(display, window.window, xa,
XA_CARDINAL, 32, XChangeProperty(display, window.window, xa, XA_CARDINAL, 32,
PropModeAppend, PropModeAppend, (unsigned char *) &xa_prop, 1);
(unsigned char *) &xa_prop,
1);
} }
xa = ATOM(_NET_WM_STATE); xa = ATOM(_NET_WM_STATE);
if (xa != None) { if (xa != None) {
Atom xa_prop = ATOM(_NET_WM_STATE_STICKY); Atom xa_prop = ATOM(_NET_WM_STATE_STICKY);
XChangeProperty(display, window.window, xa,
XA_ATOM, 32, XChangeProperty(display, window.window, xa, XA_ATOM, 32,
PropModeAppend, PropModeAppend, (unsigned char *) &xa_prop, 1);
(unsigned char *) &xa_prop,
1);
} }
} }
/* Skip taskbar */ /* Skip taskbar */
if (TEST_HINT(window.hints,HINT_SKIP_TASKBAR)) { if (TEST_HINT(window.hints, HINT_SKIP_TASKBAR)) {
/*fprintf(stderr, "Conky: hint - skip_taskbar\n"); fflush(stderr);*/ /* fprintf(stderr, "Conky: hint - skip_taskbar\n");
fflush(stderr); */
xa = ATOM(_NET_WM_STATE); xa = ATOM(_NET_WM_STATE);
if (xa != None) { if (xa != None) {
Atom xa_prop = ATOM(_NET_WM_STATE_SKIP_TASKBAR); Atom xa_prop = ATOM(_NET_WM_STATE_SKIP_TASKBAR);
XChangeProperty(display, window.window, xa,
XA_ATOM, 32, XChangeProperty(display, window.window, xa, XA_ATOM, 32,
PropModeAppend, PropModeAppend, (unsigned char *) &xa_prop, 1);
(unsigned char *) &xa_prop,
1);
} }
} }
/* Skip pager */ /* Skip pager */
if (TEST_HINT(window.hints,HINT_SKIP_PAGER)) { if (TEST_HINT(window.hints, HINT_SKIP_PAGER)) {
/*fprintf(stderr, "Conky: hint - skip_pager\n"); fflush(stderr);*/ /* fprintf(stderr, "Conky: hint - skip_pager\n");
fflush(stderr); */
xa = ATOM(_NET_WM_STATE); xa = ATOM(_NET_WM_STATE);
if (xa != None) { if (xa != None) {
Atom xa_prop = ATOM(_NET_WM_STATE_SKIP_PAGER); 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 */ } /* 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); fflush(stderr);
XMapWindow(display, window.window); XMapWindow(display, window.window);
} else /* if (own_window) { */ } else /* if (own_window) { */
#endif #endif
/* root / desktop window */ /* root / desktop window */
{ {
XWindowAttributes attrs; XWindowAttributes attrs;
if (!window.window) if (!window.window) {
window.window = find_desktop_window( &window.root, &window.desktop ); window.window = find_desktop_window(&window.root, &window.desktop);
}
if (XGetWindowAttributes(display, window.window, &attrs)) { if (XGetWindowAttributes(display, window.window, &attrs)) {
window.width = attrs.width; 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 #ifdef HAVE_XDBE
if (use_xdbe) { if (use_xdbe) {
int major, minor; int major, minor;
if (!XdbeQueryExtension(display, &major, &minor)) { if (!XdbeQueryExtension(display, &major, &minor)) {
use_xdbe = 0; use_xdbe = 0;
} else { } else {
window.back_buffer = window.back_buffer = XdbeAllocateBackBufferName(display,
XdbeAllocateBackBufferName(display, window.window, XdbeBackground);
window.window,
XdbeBackground);
if (window.back_buffer != None) { if (window.back_buffer != None) {
window.drawable = window.back_buffer; window.drawable = window.back_buffer;
fprintf(stderr, fprintf(stderr, "Conky: drawing to double buffer\n");
"Conky: drawing to double buffer\n"); } else {
} else
use_xdbe = 0; use_xdbe = 0;
} }
if (!use_xdbe) }
if (!use_xdbe) {
ERR("failed to set up double buffer"); ERR("failed to set up double buffer");
} }
if (!use_xdbe) }
if (!use_xdbe) {
fprintf(stderr, "Conky: drawing to single buffer\n"); fprintf(stderr, "Conky: drawing to single buffer\n");
}
#endif #endif
XFlush(display); 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 #ifdef OWN_WINDOW
/*if (own_window) { /* if (own_window) {
set_transparent_background(window.window); set_transparent_background(window.window);
XClearWindow(display, window.window); XClearWindow(display, window.window);
}*/ } */
#endif #endif
XSelectInput(display, window.window, ExposureMask
#ifdef OWN_WINDOW #ifdef OWN_WINDOW
| (own_window XSelectInput(display, window.window, ExposureMask |
? (StructureNotifyMask | PropertyChangeMask | (own_window ? (StructureNotifyMask | PropertyChangeMask |
ButtonPressMask | ButtonReleaseMask) : 0) ButtonPressMask | ButtonReleaseMask) : 0));
#else
XSelectInput(display, window.window, ExposureMask);
#endif #endif
);
} }
static Window find_subwindow(Window win, int w, int h) 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++) { for (j = 0; j < n; j++) {
XWindowAttributes attrs; XWindowAttributes attrs;
if (XGetWindowAttributes if (XGetWindowAttributes(display, children[j], &attrs)) {
(display, children[j], &attrs)) { /* Window must be mapped and same size as display or
/* Window must be mapped and same size as display or work space */ * work space */
if (attrs.map_state != 0 && if (attrs.map_state != 0 && ((attrs.width == display_width
((attrs.width == display_width
&& attrs.height == display_height) && attrs.height == display_height)
|| (attrs.width == w || (attrs.width == w && attrs.height == h))) {
&& attrs.height == h))) {
win = children[j]; win = children[j];
break; break;
} }
@@ -529,9 +501,10 @@ static Window find_subwindow(Window win, int w, int h)
} }
XFree(children); XFree(children);
if (j == n) if (j == n) {
break; break;
} }
}
return win; return win;
} }
@@ -539,24 +512,25 @@ static Window find_subwindow(Window win, int w, int h)
long get_x11_color(const char *name) long get_x11_color(const char *name)
{ {
XColor color; XColor color;
color.pixel = 0; color.pixel = 0;
if (!XParseColor if (!XParseColor(display, DefaultColormap(display, screen), name, &color)) {
(display, DefaultColormap(display, screen), name, &color)) {
/* lets check if it's a hex colour with the # missing in front /* 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]; char newname[64];
newname[0] = '#'; newname[0] = '#';
strncpy(&newname[1], name, 62); strncpy(&newname[1], name, 62);
/* now lets try again */ /* 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); ERR("can't parse X color '%s'", name);
return 0xFF00FF; return 0xFF00FF;
} }
} }
if (!XAllocColor if (!XAllocColor(display, DefaultColormap(display, screen), &color)) {
(display, DefaultColormap(display, screen), &color))
ERR("can't allocate X color '%s'", name); ERR("can't allocate X color '%s'", name);
}
return (long) color.pixel; return (long) color.pixel;
} }
@@ -564,6 +538,7 @@ long get_x11_color(const char *name)
void create_gc() void create_gc()
{ {
XGCValues values; XGCValues values;
values.graphics_exposures = 0; values.graphics_exposures = 0;
values.function = GXcopy; values.function = GXcopy;
window.gc = XCreateGC(display, window.drawable, 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 * Any original torsmo code is licensed under the BSD license
* *
@@ -7,7 +6,8 @@
* *
* Please see COPYING for details * 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. * All rights reserved.
* *
* This program is free software: you can redistribute it and/or modify * 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 * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
* $Id$ * $Id$ */
*/
#include "conky.h" #include "conky.h"
#include <stdio.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); xmms_alloc(ptr);
ptr->xmms2.status[0] = '\0'; ptr->xmms2.status[0] = '\0';
ptr->xmms2.artist[0] = '\0'; ptr->xmms2.artist[0] = '\0';
@@ -107,6 +107,7 @@ static void xmms_clear(struct information *ptr) {
void connection_lost(void *p) void connection_lost(void *p)
{ {
struct information *ptr = p; struct information *ptr = p;
ptr->xmms2_conn_state = CONN_NO; ptr->xmms2_conn_state = CONN_NO;
xmms_clear(ptr); xmms_clear(ptr);
@@ -124,132 +125,134 @@ void handle_curent_id(xmmsc_result_t *res, void *p)
uint current_id; uint current_id;
struct information *ptr = p; struct information *ptr = p;
if ( xmmsc_result_get_uint( res, &current_id ) ) { if (xmmsc_result_get_uint(res, &current_id)) {
xmmsc_result_t *res2; xmmsc_result_t *res2;
res2 = xmmsc_medialib_get_info(ptr->xmms2_conn, current_id); res2 = xmmsc_medialib_get_info(ptr->xmms2_conn, current_id);
xmmsc_result_wait( res2 ); xmmsc_result_wait(res2);
xmms_clear(ptr); xmms_clear(ptr);
ptr->xmms2.id = current_id; ptr->xmms2.id = current_id;
char *temp; 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); strncpy(ptr->xmms2.artist, temp, TEXT_BUFFER_SIZE - 1);
} else { } else {
strncpy(ptr->xmms2.artist, "[Unknown]", TEXT_BUFFER_SIZE - 1); strncpy(ptr->xmms2.artist, "[Unknown]", TEXT_BUFFER_SIZE - 1);
} }
xmmsc_result_get_dict_entry_string(res2, "title", &temp);
xmmsc_result_get_dict_entry_string( res2, "title", &temp ); if (temp != NULL) {
if ( temp != NULL ) {
strncpy(ptr->xmms2.title, temp, TEXT_BUFFER_SIZE - 1); strncpy(ptr->xmms2.title, temp, TEXT_BUFFER_SIZE - 1);
} else { } else {
strncpy(ptr->xmms2.title, "[Unknown]", TEXT_BUFFER_SIZE - 1); strncpy(ptr->xmms2.title, "[Unknown]", TEXT_BUFFER_SIZE - 1);
} }
xmmsc_result_get_dict_entry_string( res2, "album", &temp ); xmmsc_result_get_dict_entry_string(res2, "album", &temp);
if ( temp != NULL ) { if (temp != NULL) {
strncpy(ptr->xmms2.album, temp, TEXT_BUFFER_SIZE - 1); strncpy(ptr->xmms2.album, temp, TEXT_BUFFER_SIZE - 1);
} else { } else {
strncpy(ptr->xmms2.album, "[Unknown]", TEXT_BUFFER_SIZE - 1); strncpy(ptr->xmms2.album, "[Unknown]", TEXT_BUFFER_SIZE - 1);
} }
xmmsc_result_get_dict_entry_string(res2, "genre", &temp);
xmmsc_result_get_dict_entry_string( res2, "genre", &temp ); if (temp != NULL) {
if ( temp != NULL ) {
strncpy(ptr->xmms2.genre, temp, TEXT_BUFFER_SIZE - 1); strncpy(ptr->xmms2.genre, temp, TEXT_BUFFER_SIZE - 1);
} else { } else {
strncpy(ptr->xmms2.genre, "[Unknown]", TEXT_BUFFER_SIZE - 1); strncpy(ptr->xmms2.genre, "[Unknown]", TEXT_BUFFER_SIZE - 1);
} }
xmmsc_result_get_dict_entry_string(res2, "comment", &temp);
xmmsc_result_get_dict_entry_string( res2, "comment", &temp ); if (temp != NULL) {
if ( temp != NULL ) {
strncpy(ptr->xmms2.comment, temp, TEXT_BUFFER_SIZE - 1); strncpy(ptr->xmms2.comment, temp, TEXT_BUFFER_SIZE - 1);
} else { } else {
strncpy(ptr->xmms2.comment, "", TEXT_BUFFER_SIZE - 1); strncpy(ptr->xmms2.comment, "", TEXT_BUFFER_SIZE - 1);
} }
xmmsc_result_get_dict_entry_string(res2, "decoder", &temp);
xmmsc_result_get_dict_entry_string( res2, "decoder", &temp ); if (temp != NULL) {
if ( temp != NULL ) {
strncpy(ptr->xmms2.decoder, temp, TEXT_BUFFER_SIZE - 1); strncpy(ptr->xmms2.decoder, temp, TEXT_BUFFER_SIZE - 1);
} else { } else {
strncpy(ptr->xmms2.decoder, "[Unknown]", TEXT_BUFFER_SIZE - 1); strncpy(ptr->xmms2.decoder, "[Unknown]", TEXT_BUFFER_SIZE - 1);
} }
xmmsc_result_get_dict_entry_string(res2, "transport", &temp);
xmmsc_result_get_dict_entry_string( res2, "transport", &temp ); if (temp != NULL) {
if ( temp != NULL ) {
strncpy(ptr->xmms2.transport, temp, TEXT_BUFFER_SIZE - 1); strncpy(ptr->xmms2.transport, temp, TEXT_BUFFER_SIZE - 1);
} else { } else {
strncpy(ptr->xmms2.transport, "[Unknown]", TEXT_BUFFER_SIZE - 1); strncpy(ptr->xmms2.transport, "[Unknown]", TEXT_BUFFER_SIZE - 1);
} }
xmmsc_result_get_dict_entry_string(res2, "url", &temp);
xmmsc_result_get_dict_entry_string( res2, "url", &temp ); if (temp != NULL) {
if ( temp != NULL ) {
strncpy(ptr->xmms2.url, temp, TEXT_BUFFER_SIZE - 1); strncpy(ptr->xmms2.url, temp, TEXT_BUFFER_SIZE - 1);
} else { } else {
strncpy(ptr->xmms2.url, "[Unknown]", TEXT_BUFFER_SIZE - 1); strncpy(ptr->xmms2.url, "[Unknown]", TEXT_BUFFER_SIZE - 1);
} }
xmmsc_result_get_dict_entry_string(res2, "date", &temp);
xmmsc_result_get_dict_entry_string( res2, "date", &temp ); if (temp != NULL) {
if ( temp != NULL ) {
strncpy(ptr->xmms2.date, temp, TEXT_BUFFER_SIZE - 1); strncpy(ptr->xmms2.date, temp, TEXT_BUFFER_SIZE - 1);
} else { } else {
strncpy(ptr->xmms2.date, "????", TEXT_BUFFER_SIZE - 1); strncpy(ptr->xmms2.date, "????", TEXT_BUFFER_SIZE - 1);
} }
int itemp; int itemp;
xmmsc_result_get_dict_entry_int( res2, "tracknr", &itemp );
xmmsc_result_get_dict_entry_int(res2, "tracknr", &itemp);
ptr->xmms2.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; 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; ptr->xmms2.bitrate = itemp / 1000;
xmmsc_result_get_dict_entry_int( res2, "size", &itemp ); xmmsc_result_get_dict_entry_int(res2, "size", &itemp);
ptr->xmms2.size = (float)itemp / 1048576; 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; struct information *ptr = p;
xmmsc_result_t * res2; xmmsc_result_t *res2;
uint play_time; uint play_time;
if ( xmmsc_result_iserror( res ) ) if (xmmsc_result_iserror(res)) {
return; return;
}
if ( !xmmsc_result_get_uint( res, &play_time ) ) if (!xmmsc_result_get_uint(res, &play_time)) {
return; return;
}
res2 = xmmsc_result_restart( res ); res2 = xmmsc_result_restart(res);
xmmsc_result_unref( res2 ); xmmsc_result_unref(res2);
ptr->xmms2.elapsed = play_time; ptr->xmms2.elapsed = play_time;
ptr->xmms2.progress = (float) play_time / ptr->xmms2.duration; 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; struct information *ptr = p;
uint pb_state = 0; uint pb_state = 0;
if ( xmmsc_result_iserror( res ) )
return;
if ( !xmmsc_result_get_uint( res, &pb_state ) ) if (xmmsc_result_iserror(res)) {
return; return;
}
if (!xmmsc_result_get_uint(res, &pb_state)) {
return;
}
switch (pb_state) { switch (pb_state) {
case XMMS_PLAYBACK_STATUS_PLAY: case XMMS_PLAYBACK_STATUS_PLAY:
@@ -266,20 +269,21 @@ void handle_playback_state_change(xmmsc_result_t *res, void *p) {
} }
} }
void update_xmms2()
void update_xmms2() { {
struct information * current_info = &info; struct information *current_info = &info;
/* initialize connection */ /* initialize connection */
if ( current_info->xmms2_conn_state == CONN_INIT ) { if (current_info->xmms2_conn_state == CONN_INIT) {
if ( current_info->xmms2_conn == NULL ) { if (current_info->xmms2_conn == NULL) {
current_info->xmms2_conn = xmmsc_init( "conky" ); current_info->xmms2_conn = xmmsc_init("conky");
} }
/* did init fail? */ /* did init fail? */
if ( current_info->xmms2_conn == NULL ) { if (current_info->xmms2_conn == NULL) {
fprintf(stderr,"Conky: xmms2 init failed. %s\n", xmmsc_get_last_error ( current_info->xmms2_conn )); fprintf(stderr, "Conky: xmms2 init failed. %s\n",
xmmsc_get_last_error(current_info->xmms2_conn));
fflush(stderr); fflush(stderr);
return; return;
} }
@@ -298,69 +302,79 @@ void update_xmms2() {
current_info->xmms2.size = 0; current_info->xmms2.size = 0;
current_info->xmms2.progress = 0; current_info->xmms2.progress = 0;
/* fprintf(stderr,"Conky: xmms2 init ok.\n"); /* fprintf(stderr, "Conky: xmms2 init ok.\n");
fflush(stderr); */ fflush(stderr); */
} }
/* connect */ /* connect */
if ( current_info->xmms2_conn_state == CONN_NO ) { if (current_info->xmms2_conn_state == CONN_NO) {
char *path = getenv ( "XMMS_PATH" ); char *path = getenv("XMMS_PATH");
if ( !xmmsc_connect( current_info->xmms2_conn, path ) ) {
fprintf(stderr,"Conky: xmms2 connection failed. %s\n", if (!xmmsc_connect(current_info->xmms2_conn, path)) {
xmmsc_get_last_error ( current_info->xmms2_conn )); fprintf(stderr, "Conky: xmms2 connection failed. %s\n",
xmmsc_get_last_error(current_info->xmms2_conn));
fflush(stderr); fflush(stderr);
current_info->xmms2_conn_state = CONN_NO; current_info->xmms2_conn_state = CONN_NO;
return; return;
} }
/* set callbacks */ /* set callbacks */
xmmsc_disconnect_callback_set( current_info->xmms2_conn, connection_lost, current_info ); xmmsc_disconnect_callback_set(current_info->xmms2_conn, connection_lost,
XMMS_CALLBACK_SET( current_info->xmms2_conn, xmmsc_playback_current_id, handle_curent_id, current_info ); 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_playback_current_id,
XMMS_CALLBACK_SET( current_info->xmms2_conn, xmmsc_signal_playback_playtime, handle_playtime, current_info ); handle_curent_id, current_info);
XMMS_CALLBACK_SET( current_info->xmms2_conn, xmmsc_broadcast_playback_status, handle_playback_state_change, 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 */ /* get playback status, it wont be broadcasted untill it chages */
xmmsc_result_t * res = xmmsc_playback_status( current_info->xmms2_conn ); xmmsc_result_t *res = xmmsc_playback_status(current_info->xmms2_conn);
xmmsc_result_wait ( res );
xmmsc_result_wait(res);
unsigned int pb_state; unsigned int pb_state;
xmmsc_result_get_uint( res, &pb_state ); xmmsc_result_get_uint(res, &pb_state);
switch (pb_state) { switch (pb_state) {
case XMMS_PLAYBACK_STATUS_PLAY: case XMMS_PLAYBACK_STATUS_PLAY:
strncpy(current_info->xmms2.status, strncpy(current_info->xmms2.status, "Playing",
"Playing", TEXT_BUFFER_SIZE - 1 ); TEXT_BUFFER_SIZE - 1);
break; break;
case XMMS_PLAYBACK_STATUS_PAUSE: case XMMS_PLAYBACK_STATUS_PAUSE:
strncpy( current_info->xmms2.status, strncpy(current_info->xmms2.status, "Paused",
"Paused", TEXT_BUFFER_SIZE - 1 ); TEXT_BUFFER_SIZE - 1);
break; break;
case XMMS_PLAYBACK_STATUS_STOP: case XMMS_PLAYBACK_STATUS_STOP:
strncpy( current_info->xmms2.status, strncpy(current_info->xmms2.status, "Stopped",
"Stopped", TEXT_BUFFER_SIZE - 1 ); TEXT_BUFFER_SIZE - 1);
break; break;
default: default:
strncpy( current_info->xmms2.status, strncpy(current_info->xmms2.status, "Unknown",
"Unknown", TEXT_BUFFER_SIZE - 1 ); TEXT_BUFFER_SIZE - 1);
} }
xmmsc_result_unref ( res ); xmmsc_result_unref(res);
/* everything seems to be ok */ /* everything seems to be ok */
current_info->xmms2_conn_state = CONN_OK; current_info->xmms2_conn_state = CONN_OK;
/* fprintf(stderr,"Conky: xmms2 connected.\n"); /* fprintf(stderr, "Conky: xmms2 connected.\n");
fflush(stderr); */ fflush(stderr); */
} }
/* handle callbacks */ /* handle callbacks */
if ( current_info->xmms2_conn_state == CONN_OK ) { if (current_info->xmms2_conn_state == CONN_OK) {
struct timeval tmout; struct timeval tmout;
tmout.tv_sec = 0; tmout.tv_sec = 0;
tmout.tv_usec = 100; 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); xmmsc_io_in_handle(current_info->xmms2_conn);
if (xmmsc_io_want_out(current_info->xmms2_conn)) { if (xmmsc_io_want_out(current_info->xmms2_conn)) {