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:
217
src/audacious.c
217
src/audacious.c
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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,
|
||||||
|
49
src/bmpx.c
49
src/bmpx.c
@@ -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, ¤t_track, G_TYPE_INVALID)) {
|
||||||
G_TYPE_INT, ¤t_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;
|
||||||
|
125
src/common.c
125
src/common.c
@@ -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)
|
||||||
|
3816
src/conky.c
3816
src/conky.c
File diff suppressed because it is too large
Load Diff
118
src/conky.h
118
src/conky.h
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
581
src/freebsd.c
581
src/freebsd.c
File diff suppressed because it is too large
Load Diff
49
src/fs.c
49
src/fs.c
@@ -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;
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1585
src/libmpdclient.c
1585
src/libmpdclient.c
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
1216
src/linux.c
1216
src/linux.c
File diff suppressed because it is too large
Load Diff
58
src/mail.c
58
src/mail.c
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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");
|
||||||
}
|
}
|
||||||
|
@@ -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_
|
||||||
|
19
src/mixer.c
19
src/mixer.c
@@ -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
155
src/mpd.c
@@ -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;
|
||||||
|
151
src/netbsd.c
151
src/netbsd.c
@@ -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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
400
src/openbsd.c
400
src/openbsd.c
@@ -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;
|
|
||||||
}
|
}
|
||||||
|
192
src/prss.c
192
src/prss.c
@@ -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;
|
||||||
}
|
}
|
||||||
|
58
src/prss.h
58
src/prss.h
@@ -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 */
|
||||||
|
71
src/rss.c
71
src/rss.c
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
427
src/top.c
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
50
src/top.h
50
src/top.h
@@ -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
343
src/x11.c
@@ -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,
|
||||||
|
184
src/xmms2.c
184
src/xmms2.c
@@ -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, ¤t_id ) ) {
|
if (xmmsc_result_get_uint(res, ¤t_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, ¤t_info->xmms2_fdset, NULL, NULL, &tmout );
|
select(current_info->xmms2_fd + 1, ¤t_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)) {
|
||||||
|
Reference in New Issue
Block a user