moved stuff
authorBrenden Matthews <brenden1@rty.ca>
Sun, 21 Aug 2005 22:10:54 +0000 (22:10 +0000)
committerBrenden Matthews <brenden1@rty.ca>
Sun, 21 Aug 2005 22:10:54 +0000 (22:10 +0000)
git-svn-id: https://conky.svn.sourceforge.net/svnroot/conky/trunk/conky@130 7f574dfc-610e-0410-a909-a81674777703

55 files changed:
Makefile.am
Makefile.in
cairo.c [deleted file]
common.c [deleted file]
configure.in
conky.c [deleted file]
conky.h [deleted file]
freebsd.c [deleted file]
fs.c [deleted file]
ftp.c [deleted file]
ftp.h [deleted file]
install-sh
libmpdclient.c [deleted file]
libmpdclient.h [deleted file]
linux.c [deleted file]
mail.c [deleted file]
mixer.c [deleted file]
mldonkey.c [deleted file]
mpd.c [deleted file]
netbsd.c [deleted file]
remotec.c [deleted file]
remotec.h [deleted file]
remoted.c [deleted file]
remoted.h [deleted file]
seti.c [deleted file]
solaris.c [deleted file]
src/cairo.c [new file with mode: 0644]
src/common.c [new file with mode: 0644]
src/config.h.in [new file with mode: 0644]
src/conky.c [new file with mode: 0644]
src/conky.h [new file with mode: 0644]
src/freebsd.c [new file with mode: 0644]
src/fs.c [new file with mode: 0644]
src/ftp.c [new file with mode: 0644]
src/ftp.h [new file with mode: 0644]
src/libmpdclient.c [new file with mode: 0644]
src/libmpdclient.h [new file with mode: 0644]
src/linux.c [new file with mode: 0644]
src/mail.c [new file with mode: 0644]
src/mixer.c [new file with mode: 0644]
src/mldonkey.c [new file with mode: 0644]
src/mpd.c [new file with mode: 0644]
src/netbsd.c [new file with mode: 0644]
src/remotec.c [new file with mode: 0644]
src/remotec.h [new file with mode: 0644]
src/remoted.c [new file with mode: 0644]
src/remoted.h [new file with mode: 0644]
src/seti.c [new file with mode: 0644]
src/solaris.c [new file with mode: 0644]
src/top.c [new file with mode: 0644]
src/top.h [new file with mode: 0644]
src/x11.c [new file with mode: 0644]
top.c [deleted file]
top.h [deleted file]
x11.c [deleted file]

index 335695e..46a6811 100644 (file)
@@ -1,56 +1,56 @@
 bin_PROGRAMS = conky
 
 if BUILD_SETI
-seti = seti.c
+seti = src/seti.c
 endif
 
 if BUILD_MPD
-mpd = mpd.c libmpdclient.c
+mpd = src/mpd.c src/libmpdclient.c
 endif
 
 if BUILD_LINUX
-linux = linux.c
+linux = src/linux.c
 endif
 
 if BUILD_SOLARIS
-solaris = solaris.c
+solaris = src/solaris.c
 endif
 
 if BUILD_FREEBSD
-freebsd = freebsd.c
+freebsd = src/freebsd.c
 endif
 
 if BUILD_NETBSD
-netbsd = netbsd.c
+netbsd = src/netbsd.c
 endif
 
 if BUILD_CAIRO
-cairo = cairo.c
+cairo = src/cairo.c
 endif
 
 if BUILD_MLDONKEY
-mldonkey = mldonkey.c
+mldonkey = src/mldonkey.c
 endif
 
 if BUILD_X11
-x11 = x11.c
+x11 = src/x11.c
 endif
 
-conky_SOURCES = common.c fs.c top.c $(linux) mail.c mixer.c $(seti) $(mpd) \
-       $(solaris) $(freebsd) $(netbsd) $(cairo) conky.c conky.h $(x11) \
-       $(mldonkey) remoted.c remoted.h remotec.c remotec.h
+conky_SOURCES = src/common.c src/fs.c src/top.c $(linux) src/mail.c src/mixer.c $(seti) $(mpd) \
+       $(solaris) $(freebsd) $(netbsd) $(cairo) src/conky.c src/conky.h $(x11) \
+       $(mldonkey) src/remoted.c src/remoted.h src/remotec.c src/remotec.h
 
 conky_LDFLAGS = $(X11_LIBS) $(XFT_LIBS) $(CAIRO_LIBS)
 
 conky_LDADD = $(METAR_LIBS)
 
-man_MANS = conky.1
+man_MANS = doc/conky.1
 
 LIBS = -lm -lpthread
 
 # conky.1 is in EXTRA_DIST in case that someone doesn't have help2man
-EXTRA_DIST = conkyrc.sample conky.1 conky.x \
+EXTRA_DIST = conkyrc.sample doc/conky.1 \
              app-admin/conky/conky-1.2.ebuild app-admin/conky/conky-1.9999.ebuild
 
-EXTRA_conky_SOURCES = seti.c linux.c solaris.c freebsd.c netbsd.c mpd.c libmpdclient.c \
-cairo.c libmpdclient.h top.h mldonkey.c ftp.c ftp.h x11.c
\ No newline at end of file
+EXTRA_conky_SOURCES = src/seti.c src/linux.c src/solaris.c src/freebsd.c src/netbsd.c src/mpd.c src/libmpdclient.c \
+src/cairo.c src/libmpdclient.h src/top.h src/mldonkey.c src/ftp.c src/ftp.h src/x11.c
index 70d1a98..593d5aa 100644 (file)
@@ -39,9 +39,9 @@ POST_UNINSTALL = :
 bin_PROGRAMS = conky$(EXEEXT)
 subdir = .
 DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
-       $(srcdir)/Makefile.in $(srcdir)/config.h.in \
-       $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
-       TODO depcomp install-sh missing mkinstalldirs
+       $(srcdir)/Makefile.in $(top_srcdir)/configure \
+       $(top_srcdir)/src/config.h.in AUTHORS COPYING ChangeLog \
+       INSTALL NEWS TODO depcomp install-sh missing mkinstalldirs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/configure.in
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
@@ -49,15 +49,16 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
  configure.lineno configure.status.lineno
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
-CONFIG_HEADER = config.h
+CONFIG_HEADER = $(top_builddir)/src/config.h
 CONFIG_CLEAN_FILES =
 am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"
 binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
 PROGRAMS = $(bin_PROGRAMS)
-am__conky_SOURCES_DIST = common.c fs.c top.c linux.c mail.c mixer.c \
-       seti.c mpd.c libmpdclient.c solaris.c freebsd.c netbsd.c \
-       cairo.c conky.c conky.h x11.c mldonkey.c remoted.c remoted.h \
-       remotec.c remotec.h
+am__conky_SOURCES_DIST = src/common.c src/fs.c src/top.c src/linux.c \
+       src/mail.c src/mixer.c src/seti.c src/mpd.c src/libmpdclient.c \
+       src/solaris.c src/freebsd.c src/netbsd.c src/cairo.c \
+       src/conky.c src/conky.h src/x11.c src/mldonkey.c src/remoted.c \
+       src/remoted.h src/remotec.c src/remotec.h
 @BUILD_LINUX_TRUE@am__objects_1 = linux.$(OBJEXT)
 @BUILD_SETI_TRUE@am__objects_2 = seti.$(OBJEXT)
 @BUILD_MPD_TRUE@am__objects_3 = mpd.$(OBJEXT) libmpdclient.$(OBJEXT)
@@ -75,7 +76,7 @@ am_conky_OBJECTS = common.$(OBJEXT) fs.$(OBJEXT) top.$(OBJEXT) \
        remoted.$(OBJEXT) remotec.$(OBJEXT)
 conky_OBJECTS = $(am_conky_OBJECTS)
 conky_DEPENDENCIES =
-DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -193,32 +194,31 @@ sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 sysconfdir = @sysconfdir@
 target_alias = @target_alias@
-@BUILD_SETI_TRUE@seti = seti.c
-@BUILD_MPD_TRUE@mpd = mpd.c libmpdclient.c
-@BUILD_LINUX_TRUE@linux = linux.c
-@BUILD_SOLARIS_TRUE@solaris = solaris.c
-@BUILD_FREEBSD_TRUE@freebsd = freebsd.c
-@BUILD_NETBSD_TRUE@netbsd = netbsd.c
-@BUILD_CAIRO_TRUE@cairo = cairo.c
-@BUILD_MLDONKEY_TRUE@mldonkey = mldonkey.c
-@BUILD_X11_TRUE@x11 = x11.c
-conky_SOURCES = common.c fs.c top.c $(linux) mail.c mixer.c $(seti) $(mpd) \
-       $(solaris) $(freebsd) $(netbsd) $(cairo) conky.c conky.h $(x11) \
-       $(mldonkey) remoted.c remoted.h remotec.c remotec.h
+@BUILD_SETI_TRUE@seti = src/seti.c
+@BUILD_MPD_TRUE@mpd = src/mpd.c src/libmpdclient.c
+@BUILD_LINUX_TRUE@linux = src/linux.c
+@BUILD_SOLARIS_TRUE@solaris = src/solaris.c
+@BUILD_FREEBSD_TRUE@freebsd = src/freebsd.c
+@BUILD_NETBSD_TRUE@netbsd = src/netbsd.c
+@BUILD_CAIRO_TRUE@cairo = src/cairo.c
+@BUILD_MLDONKEY_TRUE@mldonkey = src/mldonkey.c
+@BUILD_X11_TRUE@x11 = src/x11.c
+conky_SOURCES = src/common.c src/fs.c src/top.c $(linux) src/mail.c src/mixer.c $(seti) $(mpd) \
+       $(solaris) $(freebsd) $(netbsd) $(cairo) src/conky.c src/conky.h $(x11) \
+       $(mldonkey) src/remoted.c src/remoted.h src/remotec.c src/remotec.h
 
 conky_LDFLAGS = $(X11_LIBS) $(XFT_LIBS) $(CAIRO_LIBS)
 conky_LDADD = $(METAR_LIBS)
-man_MANS = conky.1
+man_MANS = doc/conky.1
 
 # conky.1 is in EXTRA_DIST in case that someone doesn't have help2man
-EXTRA_DIST = conkyrc.sample conky.1 conky.x \
+EXTRA_DIST = conkyrc.sample doc/conky.1 \
              app-admin/conky/conky-1.2.ebuild app-admin/conky/conky-1.9999.ebuild
 
-EXTRA_conky_SOURCES = seti.c linux.c solaris.c freebsd.c netbsd.c mpd.c libmpdclient.c \
-cairo.c libmpdclient.h top.h mldonkey.c ftp.c ftp.h x11.c
+EXTRA_conky_SOURCES = src/seti.c src/linux.c src/solaris.c src/freebsd.c src/netbsd.c src/mpd.c src/libmpdclient.c \
+src/cairo.c src/libmpdclient.h src/top.h src/mldonkey.c src/ftp.c src/ftp.h src/x11.c
 
-all: config.h
-       $(MAKE) $(AM_MAKEFLAGS) all-am
+all: all-am
 
 .SUFFIXES:
 .SUFFIXES: .c .o .obj
@@ -256,22 +256,22 @@ $(top_srcdir)/configure:  $(am__configure_deps)
 $(ACLOCAL_M4):  $(am__aclocal_m4_deps)
        cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
 
-config.h: stamp-h1
+src/config.h: src/stamp-h1
        @if test ! -f $@; then \
-         rm -f stamp-h1; \
-         $(MAKE) stamp-h1; \
+         rm -f src/stamp-h1; \
+         $(MAKE) src/stamp-h1; \
        else :; fi
 
-stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
-       @rm -f stamp-h1
-       cd $(top_builddir) && $(SHELL) ./config.status config.h
-$(srcdir)/config.h.in:  $(am__configure_deps) 
+src/stamp-h1: $(top_srcdir)/src/config.h.in $(top_builddir)/config.status
+       @rm -f src/stamp-h1
+       cd $(top_builddir) && $(SHELL) ./config.status src/config.h
+$(top_srcdir)/src/config.h.in:  $(am__configure_deps) 
        cd $(top_srcdir) && $(AUTOHEADER)
-       rm -f stamp-h1
+       rm -f src/stamp-h1
        touch $@
 
 distclean-hdr:
-       -rm -f config.h stamp-h1
+       -rm -f src/config.h src/stamp-h1
 install-binPROGRAMS: $(bin_PROGRAMS)
        @$(NORMAL_INSTALL)
        test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
@@ -338,6 +338,272 @@ distclean-compile:
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+common.o: src/common.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT common.o -MD -MP -MF "$(DEPDIR)/common.Tpo" -c -o common.o `test -f 'src/common.c' || echo '$(srcdir)/'`src/common.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/common.Tpo" "$(DEPDIR)/common.Po"; else rm -f "$(DEPDIR)/common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/common.c' object='common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o common.o `test -f 'src/common.c' || echo '$(srcdir)/'`src/common.c
+
+common.obj: src/common.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT common.obj -MD -MP -MF "$(DEPDIR)/common.Tpo" -c -o common.obj `if test -f 'src/common.c'; then $(CYGPATH_W) 'src/common.c'; else $(CYGPATH_W) '$(srcdir)/src/common.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/common.Tpo" "$(DEPDIR)/common.Po"; else rm -f "$(DEPDIR)/common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/common.c' object='common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o common.obj `if test -f 'src/common.c'; then $(CYGPATH_W) 'src/common.c'; else $(CYGPATH_W) '$(srcdir)/src/common.c'; fi`
+
+fs.o: src/fs.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fs.o -MD -MP -MF "$(DEPDIR)/fs.Tpo" -c -o fs.o `test -f 'src/fs.c' || echo '$(srcdir)/'`src/fs.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/fs.Tpo" "$(DEPDIR)/fs.Po"; else rm -f "$(DEPDIR)/fs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/fs.c' object='fs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fs.o `test -f 'src/fs.c' || echo '$(srcdir)/'`src/fs.c
+
+fs.obj: src/fs.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fs.obj -MD -MP -MF "$(DEPDIR)/fs.Tpo" -c -o fs.obj `if test -f 'src/fs.c'; then $(CYGPATH_W) 'src/fs.c'; else $(CYGPATH_W) '$(srcdir)/src/fs.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/fs.Tpo" "$(DEPDIR)/fs.Po"; else rm -f "$(DEPDIR)/fs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/fs.c' object='fs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fs.obj `if test -f 'src/fs.c'; then $(CYGPATH_W) 'src/fs.c'; else $(CYGPATH_W) '$(srcdir)/src/fs.c'; fi`
+
+top.o: src/top.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT top.o -MD -MP -MF "$(DEPDIR)/top.Tpo" -c -o top.o `test -f 'src/top.c' || echo '$(srcdir)/'`src/top.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/top.Tpo" "$(DEPDIR)/top.Po"; else rm -f "$(DEPDIR)/top.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/top.c' object='top.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o top.o `test -f 'src/top.c' || echo '$(srcdir)/'`src/top.c
+
+top.obj: src/top.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT top.obj -MD -MP -MF "$(DEPDIR)/top.Tpo" -c -o top.obj `if test -f 'src/top.c'; then $(CYGPATH_W) 'src/top.c'; else $(CYGPATH_W) '$(srcdir)/src/top.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/top.Tpo" "$(DEPDIR)/top.Po"; else rm -f "$(DEPDIR)/top.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/top.c' object='top.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o top.obj `if test -f 'src/top.c'; then $(CYGPATH_W) 'src/top.c'; else $(CYGPATH_W) '$(srcdir)/src/top.c'; fi`
+
+linux.o: src/linux.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT linux.o -MD -MP -MF "$(DEPDIR)/linux.Tpo" -c -o linux.o `test -f 'src/linux.c' || echo '$(srcdir)/'`src/linux.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/linux.Tpo" "$(DEPDIR)/linux.Po"; else rm -f "$(DEPDIR)/linux.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/linux.c' object='linux.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o linux.o `test -f 'src/linux.c' || echo '$(srcdir)/'`src/linux.c
+
+linux.obj: src/linux.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT linux.obj -MD -MP -MF "$(DEPDIR)/linux.Tpo" -c -o linux.obj `if test -f 'src/linux.c'; then $(CYGPATH_W) 'src/linux.c'; else $(CYGPATH_W) '$(srcdir)/src/linux.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/linux.Tpo" "$(DEPDIR)/linux.Po"; else rm -f "$(DEPDIR)/linux.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/linux.c' object='linux.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o linux.obj `if test -f 'src/linux.c'; then $(CYGPATH_W) 'src/linux.c'; else $(CYGPATH_W) '$(srcdir)/src/linux.c'; fi`
+
+mail.o: src/mail.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mail.o -MD -MP -MF "$(DEPDIR)/mail.Tpo" -c -o mail.o `test -f 'src/mail.c' || echo '$(srcdir)/'`src/mail.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/mail.Tpo" "$(DEPDIR)/mail.Po"; else rm -f "$(DEPDIR)/mail.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/mail.c' object='mail.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mail.o `test -f 'src/mail.c' || echo '$(srcdir)/'`src/mail.c
+
+mail.obj: src/mail.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mail.obj -MD -MP -MF "$(DEPDIR)/mail.Tpo" -c -o mail.obj `if test -f 'src/mail.c'; then $(CYGPATH_W) 'src/mail.c'; else $(CYGPATH_W) '$(srcdir)/src/mail.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/mail.Tpo" "$(DEPDIR)/mail.Po"; else rm -f "$(DEPDIR)/mail.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/mail.c' object='mail.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mail.obj `if test -f 'src/mail.c'; then $(CYGPATH_W) 'src/mail.c'; else $(CYGPATH_W) '$(srcdir)/src/mail.c'; fi`
+
+mixer.o: src/mixer.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mixer.o -MD -MP -MF "$(DEPDIR)/mixer.Tpo" -c -o mixer.o `test -f 'src/mixer.c' || echo '$(srcdir)/'`src/mixer.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/mixer.Tpo" "$(DEPDIR)/mixer.Po"; else rm -f "$(DEPDIR)/mixer.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/mixer.c' object='mixer.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mixer.o `test -f 'src/mixer.c' || echo '$(srcdir)/'`src/mixer.c
+
+mixer.obj: src/mixer.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mixer.obj -MD -MP -MF "$(DEPDIR)/mixer.Tpo" -c -o mixer.obj `if test -f 'src/mixer.c'; then $(CYGPATH_W) 'src/mixer.c'; else $(CYGPATH_W) '$(srcdir)/src/mixer.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/mixer.Tpo" "$(DEPDIR)/mixer.Po"; else rm -f "$(DEPDIR)/mixer.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/mixer.c' object='mixer.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mixer.obj `if test -f 'src/mixer.c'; then $(CYGPATH_W) 'src/mixer.c'; else $(CYGPATH_W) '$(srcdir)/src/mixer.c'; fi`
+
+seti.o: src/seti.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT seti.o -MD -MP -MF "$(DEPDIR)/seti.Tpo" -c -o seti.o `test -f 'src/seti.c' || echo '$(srcdir)/'`src/seti.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/seti.Tpo" "$(DEPDIR)/seti.Po"; else rm -f "$(DEPDIR)/seti.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/seti.c' object='seti.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o seti.o `test -f 'src/seti.c' || echo '$(srcdir)/'`src/seti.c
+
+seti.obj: src/seti.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT seti.obj -MD -MP -MF "$(DEPDIR)/seti.Tpo" -c -o seti.obj `if test -f 'src/seti.c'; then $(CYGPATH_W) 'src/seti.c'; else $(CYGPATH_W) '$(srcdir)/src/seti.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/seti.Tpo" "$(DEPDIR)/seti.Po"; else rm -f "$(DEPDIR)/seti.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/seti.c' object='seti.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o seti.obj `if test -f 'src/seti.c'; then $(CYGPATH_W) 'src/seti.c'; else $(CYGPATH_W) '$(srcdir)/src/seti.c'; fi`
+
+mpd.o: src/mpd.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mpd.o -MD -MP -MF "$(DEPDIR)/mpd.Tpo" -c -o mpd.o `test -f 'src/mpd.c' || echo '$(srcdir)/'`src/mpd.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/mpd.Tpo" "$(DEPDIR)/mpd.Po"; else rm -f "$(DEPDIR)/mpd.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/mpd.c' object='mpd.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mpd.o `test -f 'src/mpd.c' || echo '$(srcdir)/'`src/mpd.c
+
+mpd.obj: src/mpd.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mpd.obj -MD -MP -MF "$(DEPDIR)/mpd.Tpo" -c -o mpd.obj `if test -f 'src/mpd.c'; then $(CYGPATH_W) 'src/mpd.c'; else $(CYGPATH_W) '$(srcdir)/src/mpd.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/mpd.Tpo" "$(DEPDIR)/mpd.Po"; else rm -f "$(DEPDIR)/mpd.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/mpd.c' object='mpd.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mpd.obj `if test -f 'src/mpd.c'; then $(CYGPATH_W) 'src/mpd.c'; else $(CYGPATH_W) '$(srcdir)/src/mpd.c'; fi`
+
+libmpdclient.o: src/libmpdclient.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmpdclient.o -MD -MP -MF "$(DEPDIR)/libmpdclient.Tpo" -c -o libmpdclient.o `test -f 'src/libmpdclient.c' || echo '$(srcdir)/'`src/libmpdclient.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/libmpdclient.Tpo" "$(DEPDIR)/libmpdclient.Po"; else rm -f "$(DEPDIR)/libmpdclient.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/libmpdclient.c' object='libmpdclient.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmpdclient.o `test -f 'src/libmpdclient.c' || echo '$(srcdir)/'`src/libmpdclient.c
+
+libmpdclient.obj: src/libmpdclient.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmpdclient.obj -MD -MP -MF "$(DEPDIR)/libmpdclient.Tpo" -c -o libmpdclient.obj `if test -f 'src/libmpdclient.c'; then $(CYGPATH_W) 'src/libmpdclient.c'; else $(CYGPATH_W) '$(srcdir)/src/libmpdclient.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/libmpdclient.Tpo" "$(DEPDIR)/libmpdclient.Po"; else rm -f "$(DEPDIR)/libmpdclient.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/libmpdclient.c' object='libmpdclient.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmpdclient.obj `if test -f 'src/libmpdclient.c'; then $(CYGPATH_W) 'src/libmpdclient.c'; else $(CYGPATH_W) '$(srcdir)/src/libmpdclient.c'; fi`
+
+solaris.o: src/solaris.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT solaris.o -MD -MP -MF "$(DEPDIR)/solaris.Tpo" -c -o solaris.o `test -f 'src/solaris.c' || echo '$(srcdir)/'`src/solaris.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/solaris.Tpo" "$(DEPDIR)/solaris.Po"; else rm -f "$(DEPDIR)/solaris.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/solaris.c' object='solaris.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o solaris.o `test -f 'src/solaris.c' || echo '$(srcdir)/'`src/solaris.c
+
+solaris.obj: src/solaris.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT solaris.obj -MD -MP -MF "$(DEPDIR)/solaris.Tpo" -c -o solaris.obj `if test -f 'src/solaris.c'; then $(CYGPATH_W) 'src/solaris.c'; else $(CYGPATH_W) '$(srcdir)/src/solaris.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/solaris.Tpo" "$(DEPDIR)/solaris.Po"; else rm -f "$(DEPDIR)/solaris.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/solaris.c' object='solaris.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o solaris.obj `if test -f 'src/solaris.c'; then $(CYGPATH_W) 'src/solaris.c'; else $(CYGPATH_W) '$(srcdir)/src/solaris.c'; fi`
+
+freebsd.o: src/freebsd.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT freebsd.o -MD -MP -MF "$(DEPDIR)/freebsd.Tpo" -c -o freebsd.o `test -f 'src/freebsd.c' || echo '$(srcdir)/'`src/freebsd.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/freebsd.Tpo" "$(DEPDIR)/freebsd.Po"; else rm -f "$(DEPDIR)/freebsd.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/freebsd.c' object='freebsd.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o freebsd.o `test -f 'src/freebsd.c' || echo '$(srcdir)/'`src/freebsd.c
+
+freebsd.obj: src/freebsd.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT freebsd.obj -MD -MP -MF "$(DEPDIR)/freebsd.Tpo" -c -o freebsd.obj `if test -f 'src/freebsd.c'; then $(CYGPATH_W) 'src/freebsd.c'; else $(CYGPATH_W) '$(srcdir)/src/freebsd.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/freebsd.Tpo" "$(DEPDIR)/freebsd.Po"; else rm -f "$(DEPDIR)/freebsd.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/freebsd.c' object='freebsd.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o freebsd.obj `if test -f 'src/freebsd.c'; then $(CYGPATH_W) 'src/freebsd.c'; else $(CYGPATH_W) '$(srcdir)/src/freebsd.c'; fi`
+
+netbsd.o: src/netbsd.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT netbsd.o -MD -MP -MF "$(DEPDIR)/netbsd.Tpo" -c -o netbsd.o `test -f 'src/netbsd.c' || echo '$(srcdir)/'`src/netbsd.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/netbsd.Tpo" "$(DEPDIR)/netbsd.Po"; else rm -f "$(DEPDIR)/netbsd.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/netbsd.c' object='netbsd.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o netbsd.o `test -f 'src/netbsd.c' || echo '$(srcdir)/'`src/netbsd.c
+
+netbsd.obj: src/netbsd.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT netbsd.obj -MD -MP -MF "$(DEPDIR)/netbsd.Tpo" -c -o netbsd.obj `if test -f 'src/netbsd.c'; then $(CYGPATH_W) 'src/netbsd.c'; else $(CYGPATH_W) '$(srcdir)/src/netbsd.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/netbsd.Tpo" "$(DEPDIR)/netbsd.Po"; else rm -f "$(DEPDIR)/netbsd.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/netbsd.c' object='netbsd.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o netbsd.obj `if test -f 'src/netbsd.c'; then $(CYGPATH_W) 'src/netbsd.c'; else $(CYGPATH_W) '$(srcdir)/src/netbsd.c'; fi`
+
+cairo.o: src/cairo.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cairo.o -MD -MP -MF "$(DEPDIR)/cairo.Tpo" -c -o cairo.o `test -f 'src/cairo.c' || echo '$(srcdir)/'`src/cairo.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/cairo.Tpo" "$(DEPDIR)/cairo.Po"; else rm -f "$(DEPDIR)/cairo.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/cairo.c' object='cairo.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cairo.o `test -f 'src/cairo.c' || echo '$(srcdir)/'`src/cairo.c
+
+cairo.obj: src/cairo.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cairo.obj -MD -MP -MF "$(DEPDIR)/cairo.Tpo" -c -o cairo.obj `if test -f 'src/cairo.c'; then $(CYGPATH_W) 'src/cairo.c'; else $(CYGPATH_W) '$(srcdir)/src/cairo.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/cairo.Tpo" "$(DEPDIR)/cairo.Po"; else rm -f "$(DEPDIR)/cairo.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/cairo.c' object='cairo.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cairo.obj `if test -f 'src/cairo.c'; then $(CYGPATH_W) 'src/cairo.c'; else $(CYGPATH_W) '$(srcdir)/src/cairo.c'; fi`
+
+conky.o: src/conky.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT conky.o -MD -MP -MF "$(DEPDIR)/conky.Tpo" -c -o conky.o `test -f 'src/conky.c' || echo '$(srcdir)/'`src/conky.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/conky.Tpo" "$(DEPDIR)/conky.Po"; else rm -f "$(DEPDIR)/conky.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/conky.c' object='conky.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o conky.o `test -f 'src/conky.c' || echo '$(srcdir)/'`src/conky.c
+
+conky.obj: src/conky.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT conky.obj -MD -MP -MF "$(DEPDIR)/conky.Tpo" -c -o conky.obj `if test -f 'src/conky.c'; then $(CYGPATH_W) 'src/conky.c'; else $(CYGPATH_W) '$(srcdir)/src/conky.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/conky.Tpo" "$(DEPDIR)/conky.Po"; else rm -f "$(DEPDIR)/conky.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/conky.c' object='conky.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o conky.obj `if test -f 'src/conky.c'; then $(CYGPATH_W) 'src/conky.c'; else $(CYGPATH_W) '$(srcdir)/src/conky.c'; fi`
+
+x11.o: src/x11.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT x11.o -MD -MP -MF "$(DEPDIR)/x11.Tpo" -c -o x11.o `test -f 'src/x11.c' || echo '$(srcdir)/'`src/x11.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/x11.Tpo" "$(DEPDIR)/x11.Po"; else rm -f "$(DEPDIR)/x11.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/x11.c' object='x11.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o x11.o `test -f 'src/x11.c' || echo '$(srcdir)/'`src/x11.c
+
+x11.obj: src/x11.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT x11.obj -MD -MP -MF "$(DEPDIR)/x11.Tpo" -c -o x11.obj `if test -f 'src/x11.c'; then $(CYGPATH_W) 'src/x11.c'; else $(CYGPATH_W) '$(srcdir)/src/x11.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/x11.Tpo" "$(DEPDIR)/x11.Po"; else rm -f "$(DEPDIR)/x11.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/x11.c' object='x11.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o x11.obj `if test -f 'src/x11.c'; then $(CYGPATH_W) 'src/x11.c'; else $(CYGPATH_W) '$(srcdir)/src/x11.c'; fi`
+
+mldonkey.o: src/mldonkey.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mldonkey.o -MD -MP -MF "$(DEPDIR)/mldonkey.Tpo" -c -o mldonkey.o `test -f 'src/mldonkey.c' || echo '$(srcdir)/'`src/mldonkey.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/mldonkey.Tpo" "$(DEPDIR)/mldonkey.Po"; else rm -f "$(DEPDIR)/mldonkey.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/mldonkey.c' object='mldonkey.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mldonkey.o `test -f 'src/mldonkey.c' || echo '$(srcdir)/'`src/mldonkey.c
+
+mldonkey.obj: src/mldonkey.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mldonkey.obj -MD -MP -MF "$(DEPDIR)/mldonkey.Tpo" -c -o mldonkey.obj `if test -f 'src/mldonkey.c'; then $(CYGPATH_W) 'src/mldonkey.c'; else $(CYGPATH_W) '$(srcdir)/src/mldonkey.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/mldonkey.Tpo" "$(DEPDIR)/mldonkey.Po"; else rm -f "$(DEPDIR)/mldonkey.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/mldonkey.c' object='mldonkey.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mldonkey.obj `if test -f 'src/mldonkey.c'; then $(CYGPATH_W) 'src/mldonkey.c'; else $(CYGPATH_W) '$(srcdir)/src/mldonkey.c'; fi`
+
+remoted.o: src/remoted.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT remoted.o -MD -MP -MF "$(DEPDIR)/remoted.Tpo" -c -o remoted.o `test -f 'src/remoted.c' || echo '$(srcdir)/'`src/remoted.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/remoted.Tpo" "$(DEPDIR)/remoted.Po"; else rm -f "$(DEPDIR)/remoted.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/remoted.c' object='remoted.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o remoted.o `test -f 'src/remoted.c' || echo '$(srcdir)/'`src/remoted.c
+
+remoted.obj: src/remoted.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT remoted.obj -MD -MP -MF "$(DEPDIR)/remoted.Tpo" -c -o remoted.obj `if test -f 'src/remoted.c'; then $(CYGPATH_W) 'src/remoted.c'; else $(CYGPATH_W) '$(srcdir)/src/remoted.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/remoted.Tpo" "$(DEPDIR)/remoted.Po"; else rm -f "$(DEPDIR)/remoted.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/remoted.c' object='remoted.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o remoted.obj `if test -f 'src/remoted.c'; then $(CYGPATH_W) 'src/remoted.c'; else $(CYGPATH_W) '$(srcdir)/src/remoted.c'; fi`
+
+remotec.o: src/remotec.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT remotec.o -MD -MP -MF "$(DEPDIR)/remotec.Tpo" -c -o remotec.o `test -f 'src/remotec.c' || echo '$(srcdir)/'`src/remotec.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/remotec.Tpo" "$(DEPDIR)/remotec.Po"; else rm -f "$(DEPDIR)/remotec.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/remotec.c' object='remotec.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o remotec.o `test -f 'src/remotec.c' || echo '$(srcdir)/'`src/remotec.c
+
+remotec.obj: src/remotec.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT remotec.obj -MD -MP -MF "$(DEPDIR)/remotec.Tpo" -c -o remotec.obj `if test -f 'src/remotec.c'; then $(CYGPATH_W) 'src/remotec.c'; else $(CYGPATH_W) '$(srcdir)/src/remotec.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/remotec.Tpo" "$(DEPDIR)/remotec.Po"; else rm -f "$(DEPDIR)/remotec.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/remotec.c' object='remotec.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o remotec.obj `if test -f 'src/remotec.c'; then $(CYGPATH_W) 'src/remotec.c'; else $(CYGPATH_W) '$(srcdir)/src/remotec.c'; fi`
+
+ftp.o: src/ftp.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ftp.o -MD -MP -MF "$(DEPDIR)/ftp.Tpo" -c -o ftp.o `test -f 'src/ftp.c' || echo '$(srcdir)/'`src/ftp.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/ftp.Tpo" "$(DEPDIR)/ftp.Po"; else rm -f "$(DEPDIR)/ftp.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/ftp.c' object='ftp.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ftp.o `test -f 'src/ftp.c' || echo '$(srcdir)/'`src/ftp.c
+
+ftp.obj: src/ftp.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ftp.obj -MD -MP -MF "$(DEPDIR)/ftp.Tpo" -c -o ftp.obj `if test -f 'src/ftp.c'; then $(CYGPATH_W) 'src/ftp.c'; else $(CYGPATH_W) '$(srcdir)/src/ftp.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/ftp.Tpo" "$(DEPDIR)/ftp.Po"; else rm -f "$(DEPDIR)/ftp.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='src/ftp.c' object='ftp.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ftp.obj `if test -f 'src/ftp.c'; then $(CYGPATH_W) 'src/ftp.c'; else $(CYGPATH_W) '$(srcdir)/src/ftp.c'; fi`
 uninstall-info-am:
 install-man1: $(man1_MANS) $(man_MANS)
        @$(NORMAL_INSTALL)
@@ -395,11 +661,11 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        mkid -fID $$unique
 tags: TAGS
 
-TAGS:  $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
        here=`pwd`; \
-       list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
@@ -411,11 +677,11 @@ TAGS:  $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
            $$tags $$unique; \
        fi
 ctags: CTAGS
-CTAGS:  $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
        here=`pwd`; \
-       list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
@@ -436,7 +702,7 @@ distclean-tags:
 distdir: $(DISTFILES)
        $(am__remove_distdir)
        mkdir $(distdir)
-       $(mkdir_p) $(distdir)/app-admin/conky
+       $(mkdir_p) $(distdir)/app-admin/conky $(distdir)/doc $(distdir)/src
        @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
        list='$(DISTFILES)'; for file in $$list; do \
@@ -562,7 +828,7 @@ distcleancheck: distclean
               exit 1; } >&2
 check-am: all-am
 check: check-am
-all-am: Makefile $(PROGRAMS) $(MANS) config.h
+all-am: Makefile $(PROGRAMS) $(MANS)
 installdirs:
        for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \
          test -z "$$dir" || $(mkdir_p) "$$dir"; \
diff --git a/cairo.c b/cairo.c
deleted file mode 100644 (file)
index c2008aa..0000000
--- a/cairo.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-
-/* Small example demonstrating emulating knockout-groups as in PDF-1.4
- * using cairo_set_operator().
- *
- * Owen Taylor,
-
- * v0.1  30 November  2002
- * v0.2   1 December  2002 - typo fixes from Keith Packard
- * v0.3  17 April     2003 - Tracking changes in Xr, (Removal of Xr{Push,Pop}Group)
- * v0.4  29 September 2003 - Use cairo_rectangle rather than private rect_path
- *                          Use cairo_arc for oval_path
- * Keeping log of changes in ChangeLog/CVS now. (2003-11-19) Carl Worth
- */
-#include "conky.h"
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <cairo.h>
-#include <cairo-xlib.h>
-#include <math.h>
-#include <stdio.h>
-
-/* Fill the given area with checks in the standard style
- * for showing compositing effects.
- */
-static void fill_checks(cairo_t * cr, int x, int y, int width, int height)
-{
-       cairo_surface_t *check;
-       cairo_pattern_t *check_pattern;
-
-       cairo_save(cr);
-
-#define CHECK_SIZE 32
-
-       check =
-           cairo_surface_create_similar(cairo_current_target_surface(cr),
-                                        CAIRO_FORMAT_RGB24,
-                                        2 * CHECK_SIZE, 2 * CHECK_SIZE);
-       cairo_surface_set_repeat(check, 1);
-
-       /* Draw the check */
-       {
-               cairo_save(cr);
-
-               cairo_set_target_surface(cr, check);
-
-               cairo_set_operator(cr, CAIRO_OPERATOR_SRC);
-
-               cairo_set_rgb_color(cr, 0.4, 0.4, 0.4);
-
-               cairo_rectangle(cr, 0, 0, 2 * CHECK_SIZE, 2 * CHECK_SIZE);
-               cairo_fill(cr);
-
-               cairo_set_rgb_color(cr, 0.7, 0.7, 0.7);
-
-               cairo_rectangle(cr, x, y, CHECK_SIZE, CHECK_SIZE);
-               cairo_fill(cr);
-               cairo_rectangle(cr, x + CHECK_SIZE, y + CHECK_SIZE,
-                               CHECK_SIZE, CHECK_SIZE);
-               cairo_fill(cr);
-
-               cairo_restore(cr);
-       }
-
-       /* Fill the whole surface with the check */
-
-       check_pattern = cairo_pattern_create_for_surface(check);
-       cairo_set_pattern(cr, check_pattern);
-       cairo_rectangle(cr, 0, 0, width, height);
-       cairo_fill(cr);
-
-       cairo_pattern_destroy(check_pattern);
-       cairo_surface_destroy(check);
-
-       cairo_restore(cr);
-}
-
-static void draw_pee(cairo_t * cr, double xc, double yc)
-{
-       cairo_set_rgb_color(cr, 0, 0, 0);
-       cairo_show_text(cr, "Conky");
-}
-
-static void draw(cairo_t * cr, int width, int height)
-{
-       cairo_surface_t *overlay;
-
-       /* Fill the background */
-       double xc = width / 2.;
-       double yc = height / 2.;
-
-       overlay =
-           cairo_surface_create_similar(cairo_current_target_surface(cr),
-                                        CAIRO_FORMAT_ARGB32, width,
-                                        height);
-       if (overlay == NULL)
-               return;
-
-       fill_checks(cr, 0, 0, width, height);
-
-       cairo_save(cr);
-       cairo_set_target_surface(cr, overlay);
-
-       cairo_set_alpha(cr, 0.5);
-       cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
-       draw_pee(cr, xc, yc);
-
-       cairo_restore(cr);
-
-       cairo_show_surface(cr, overlay, width, height);
-
-       cairo_surface_destroy(overlay);
-}
-
-int do_it(void)
-{
-       Display *dpy;
-       int screen;
-       Window w;
-       Pixmap pixmap;
-       char *title = "cairo: Knockout Groups";
-       unsigned int quit_keycode;
-       int needs_redraw;
-       GC gc;
-       XWMHints *wmhints;
-       XSizeHints *normalhints;
-       XClassHint *classhint;
-
-       int width = 400;
-       int height = 400;
-
-       dpy = XOpenDisplay(NULL);
-       screen = DefaultScreen(dpy);
-
-       w = XCreateSimpleWindow(dpy, RootWindow(dpy, screen),
-                               0, 0, width, height, 0,
-                               BlackPixel(dpy, screen), WhitePixel(dpy,
-                                                                   screen));
-
-       normalhints = XAllocSizeHints();
-       normalhints->flags = 0;
-       normalhints->x = 0;
-       normalhints->y = 0;
-       normalhints->width = width;
-       normalhints->height = height;
-
-       classhint = XAllocClassHint();
-       classhint->res_name = "cairo-knockout";
-       classhint->res_class = "Cairo-knockout";
-
-       wmhints = XAllocWMHints();
-       wmhints->flags = InputHint;
-       wmhints->input = True;
-
-       XmbSetWMProperties(dpy, w, title, "cairo-knockout", 0, 0,
-                          normalhints, wmhints, classhint);
-       XFree(wmhints);
-       XFree(classhint);
-       XFree(normalhints);
-
-       pixmap =
-           XCreatePixmap(dpy, w, width, height,
-                         DefaultDepth(dpy, screen));
-       gc = XCreateGC(dpy, pixmap, 0, NULL);
-
-       quit_keycode = XKeysymToKeycode(dpy, XStringToKeysym("Q"));
-
-       XSelectInput(dpy, w,
-                    ExposureMask | StructureNotifyMask | ButtonPressMask |
-                    KeyPressMask);
-       XMapWindow(dpy, w);
-
-       needs_redraw = 1;
-
-       while (1) {
-               XEvent xev;
-
-               /* Only do the redraw if there are no events pending.  This
-                * avoids us getting behind doing several redraws for several
-                * consecutive resize events for example.
-                */
-               if (!XPending(dpy) && needs_redraw) {
-                       cairo_t *cr = cairo_create();
-
-                       cairo_set_target_drawable(cr, dpy, pixmap);
-
-                       draw(cr, width, height);
-
-                       cairo_destroy(cr);
-
-                       XCopyArea(dpy, pixmap, w, gc,
-                                 0, 0, width, height, 0, 0);
-
-                       needs_redraw = 0;
-               }
-
-               XNextEvent(dpy, &xev);
-
-               switch (xev.xany.type) {
-               case ButtonPress:
-                       /* A click on the canvas ends the program */
-                       goto DONE;
-               case KeyPress:
-                       if (xev.xkey.keycode == quit_keycode)
-                               goto DONE;
-                       break;
-               case ConfigureNotify:
-                       /* Note new size and create new pixmap. */
-                       width = xev.xconfigure.width;
-                       height = xev.xconfigure.height;
-                       XFreePixmap(dpy, pixmap);
-                       pixmap =
-                           XCreatePixmap(dpy, w, width, height,
-                                         DefaultDepth(dpy, screen));
-                       needs_redraw = 1;
-                       break;
-               case Expose:
-                       XCopyArea(dpy, pixmap, w, gc,
-                                 xev.xexpose.x, xev.xexpose.y,
-                                 xev.xexpose.width, xev.xexpose.height,
-                                 xev.xexpose.x, xev.xexpose.y);
-                       break;
-               }
-       }
-      DONE:
-
-       XFreeGC(dpy, gc);
-       XCloseDisplay(dpy);
-
-       return 0;
-}
diff --git a/common.c b/common.c
deleted file mode 100644 (file)
index f61d6b8..0000000
--- a/common.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Conky, a system monitor, based on torsmo
- *
- * This program is licensed under BSD license, read COPYING
- *
- *  $Id$
- */
-
-#include "conky.h"
-#include "remoted.h"
-#include "remotec.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-#include <sys/time.h>
-
-struct information info;
-
-void update_uname()
-{
-       uname(&info.uname_s);
-}
-
-double get_time()
-{
-       struct timeval tv;
-       gettimeofday(&tv, 0);
-       return tv.tv_sec + tv.tv_usec / 1000000.0;
-}
-
-FILE *open_file(const char *file, int *reported)
-{
-       FILE *fp = fopen(file, "r");
-       if (!fp) {
-               if (!reported || *reported == 0) {
-                       CRIT_ERR("can't open %s: %s", file, strerror(errno));
-                       if (reported)
-                               *reported = 1;
-               }
-               return 0;
-       }
-
-       return fp;
-}
-
-void variable_substitute(const char *s, char *dest, unsigned int n)
-{
-       while (*s && n > 1) {
-               if (*s == '$') {
-                       s++;
-                       if (*s != '$') {
-                               char buf[256];
-                               const char *a, *var;
-                               unsigned int len;
-
-                               /* variable is either $foo or ${foo} */
-                               if (*s == '{') {
-                                       s++;
-                                       a = s;
-                                       while (*s && *s != '}')
-                                               s++;
-                               } else {
-                                       a = s;
-                                       while (*s && (isalnum((int) *s)
-                                                     || *s == '_'))
-                                               s++;
-                               }
-
-                               /* copy variable to buffer and look it up */
-                               len = (s - a > 255) ? 255 : (s - a);
-                               strncpy(buf, a, len);
-                               buf[len] = '\0';
-
-                               if (*s == '}')
-                                       s++;
-
-                               var = getenv(buf);
-
-                               if (var) {
-                                       /* add var to dest */
-                                       len = strlen(var);
-                                       if (len >= n)
-                                               len = n - 1;
-                                       strncpy(dest, var, len);
-                                       dest += len;
-                                       n -= len;
-                               }
-                               continue;
-                       }
-               }
-
-               *dest++ = *s++;
-               n--;
-       }
-
-       *dest = '\0';
-}
-
-/* network interface stuff */
-
-static struct net_stat netstats[16];
-
-struct net_stat *get_net_stat(const char *dev)
-{
-       unsigned int i;
-
-       if (!dev)
-               return 0;
-
-       /* find interface stat */
-       for (i = 0; i < 16; i++) {
-               if (netstats[i].dev && strcmp(netstats[i].dev, dev) == 0)
-                       return &netstats[i];
-       }
-
-       /* wasn't found? add it */
-       if (i == 16) {
-               for (i = 0; i < 16; i++) {
-                       if (netstats[i].dev == 0) {
-                               netstats[i].dev = strdup(dev);
-                               return &netstats[i];
-                       }
-               }
-       }
-
-       CRIT_ERR("too many interfaces used (limit is 16)");
-       return 0;
-}
-
-void format_seconds(char *buf, unsigned int n, long t)
-{
-       if (t >= 24 * 60 * 60)  /* hours necessary when there are days? */
-               snprintf(buf, n, "%ldd %ldh %ldm", t / 60 / 60 / 24,
-                        (t / 60 / 60) % 24, (t / 60) % 60);
-       else if (t >= 60 * 60)
-               snprintf(buf, n, "%ldh %ldm", (t / 60 / 60) % 24,
-                        (t / 60) % 60);
-       else
-               snprintf(buf, n, "%ldm %lds", t / 60, t % 60);
-}
-
-void format_seconds_short(char *buf, unsigned int n, long t)
-{
-       if (t >= 24 * 60 * 60)
-               snprintf(buf, n, "%ldd %ldh", t / 60 / 60 / 24,
-                        (t / 60 / 60) % 24);
-       else if (t >= 60 * 60)
-               snprintf(buf, n, "%ldh %ldm", (t / 60 / 60) % 24,
-                        (t / 60) % 60);
-       else
-               snprintf(buf, n, "%ldm", t / 60);
-}
-
-static double last_meminfo_update;
-static double last_fs_update;
-
-unsigned long long need_mask;
-
-void update_stuff()
-{
-       unsigned int i;
-       info.mask = 0;
-
-       if (no_buffers)
-               need_mask |= 1 << INFO_BUFFERS;
-
-       /* clear speeds and up status in case device was removed and doesn't get
-        * updated */
-
-       for (i = 0; i < 16; i++) {
-               if (netstats[i].dev) {
-                       netstats[i].up = 0;
-                       netstats[i].recv_speed = 0.0;
-                       netstats[i].trans_speed = 0.0;
-               }
-       }
-
-       prepare_update();
-       /* client(); this is approximately where the client should be called */
-#define NEED(a) ((need_mask & (1 << a)) && ((info.mask & (1 << a)) == 0))
-
-       if (NEED(INFO_UPTIME))
-               update_uptime();
-
-       if (NEED(INFO_PROCS))
-               update_total_processes();
-
-       if (NEED(INFO_RUN_PROCS))
-               update_running_processes();
-
-       if (NEED(INFO_CPU))
-               update_cpu_usage();
-
-       if (NEED(INFO_NET))
-               update_net_stats();
-
-       if (NEED(INFO_WIFI))
-               update_wifi_stats();
-
-       if (NEED(INFO_MAIL))
-               update_mail_count();
-
-       if (NEED(INFO_TOP))
-               update_top();
-
-#ifdef MLDONKEY
-       if (NEED(INFO_MLDONKEY))
-               get_mldonkey_status(&mlconfig, &mlinfo);
-#endif
-
-#ifdef SETI
-       if (NEED(INFO_SETI))
-               update_seti();
-#endif
-
-#ifdef MPD
-       if (NEED(INFO_MPD))
-               update_mpd();
-#endif
-
-       if (NEED(INFO_LOADAVG))
-               update_load_average();
-
-       if ((NEED(INFO_MEM) || NEED(INFO_BUFFERS)) &&
-           current_update_time - last_meminfo_update > 6.9) {
-               update_meminfo();
-               if (no_buffers)
-                       info.mem -= info.bufmem;
-               last_meminfo_update = current_update_time;
-       }
-
-       /* 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) {
-               update_fs_stats();
-               last_fs_update = current_update_time;
-       }
-}
index 6424071..166e87f 100644 (file)
@@ -1,7 +1,7 @@
-AC_INIT(conky.c)
+AC_INIT(src/conky.c)
 
 AM_INIT_AUTOMAKE(conky, 1.3)
-AM_CONFIG_HEADER(config.h)
+AM_CONFIG_HEADER(src/config.h)
 
 uname=`uname`
 
diff --git a/conky.c b/conky.c
deleted file mode 100644 (file)
index a63ed1b..0000000
--- a/conky.c
+++ /dev/null
@@ -1,4337 +0,0 @@
-/*
- * Conky, a system monitor, based on torsmo
- *
- * This program is licensed under BSD license, read COPYING
- *
- *  $Id$
- */
-
-#include "conky.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <time.h>
-#include <locale.h>
-#include <signal.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <string.h>
-#include <limits.h>
-#if HAVE_DIRENT_H
-#include <dirent.h>
-#endif
-#include <sys/time.h>
-#ifdef X11
-#include <X11/Xutil.h>
-#endif /* X11 */
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#define CONFIG_FILE "$HOME/.conkyrc"
-#define MAIL_FILE "$MAIL"
-#define MAX_IF_BLOCK_DEPTH 5
-
-#ifdef X11
-
-/* alignments */
-enum alignment {
-       TOP_LEFT = 1,
-       TOP_RIGHT,
-       BOTTOM_LEFT,
-       BOTTOM_RIGHT,
-       NONE
-};
-
-
-/* for fonts */
-struct font_list {
-
-       char name[TEXT_BUFFER_SIZE];
-       int num;
-       XFontStruct *font;
-
-#ifdef XFT
-       XftFont *xftfont;
-       int font_alpha;
-#endif 
-
-};
-static int selected_font = 0;
-static int font_count = -1;
-struct font_list *fonts = NULL;
-
-#ifdef XFT
-
-#define font_height() use_xft ? (fonts[selected_font].xftfont->ascent + fonts[selected_font].xftfont->descent) : \
-(fonts[selected_font].font->max_bounds.ascent + fonts[selected_font].font->max_bounds.descent)
-#define font_ascent() use_xft ? fonts[selected_font].xftfont->ascent : fonts[selected_font].font->max_bounds.ascent
-#define font_descent() use_xft ? fonts[selected_font].xftfont->descent : fonts[selected_font].font->max_bounds.descent
-
-#else
-
-#define font_height() (fonts[selected_font].font->max_bounds.ascent + fonts[selected_font].font->max_bounds.descent)
-#define font_ascent() fonts[selected_font].font->max_bounds.ascent
-#define font_descent() fonts[selected_font].font->max_bounds.descent
-
-#endif
-
-#define MAX_FONTS 64 // hmm, no particular reason, just makes sense.
-
-
-static void set_font();
-
-
-int addfont(const char *data_in)
-{
-       if (font_count > MAX_FONTS) {
-               CRIT_ERR("you don't need that many fonts, sorry.");
-       }
-       font_count++;
-       if (font_count == 0) {
-               if (fonts != NULL) {
-                       free(fonts);
-               }
-               if ((fonts = (struct font_list*)malloc(sizeof(struct font_list))) == NULL) {
-                       CRIT_ERR("malloc");
-               }
-       }
-       fonts = realloc(fonts, (sizeof(struct font_list) * (font_count+1)));
-       if (fonts == NULL) {
-               CRIT_ERR("realloc in addfont");
-       }
-       if (strlen(data_in) < TEXT_BUFFER_SIZE) { // must account for null terminator
-               strncpy(fonts[font_count].name, data_in, TEXT_BUFFER_SIZE);
-#ifdef XFT
-               fonts[font_count].font_alpha = 0xffff;
-#endif
-       } else {
-               CRIT_ERR("Oops...looks like something overflowed in addfont().");
-       }
-       return font_count;
-}
-
-void set_first_font(const char *data_in)
-{
-       if (font_count < 0) {
-               if ((fonts = (struct font_list*)malloc(sizeof(struct font_list))) == NULL) {
-                       CRIT_ERR("malloc");
-               }
-               font_count++;
-       }
-       if (strlen(data_in) > 1) {
-               strncpy(fonts[0].name, data_in, TEXT_BUFFER_SIZE-1);
-#ifdef XFT
-               fonts[0].font_alpha = 0xffff;
-#endif
-       }
-}
-
-void free_fonts()
-{
-       int i;
-       for (i=0;i<=font_count;i++) {
-#ifdef XFT
-               if (use_xft) {
-                       XftFontClose(display, fonts[i].xftfont);
-               } else
-#endif
-               {
-                       XFreeFont(display, fonts[i].font);
-               }
-}
-       free(fonts);
-       fonts = NULL;
-       font_count = -1;
-       selected_font = 0;
-       set_first_font("6x10");
-}
-
-
-static void load_fonts()
-{
-       int i;
-       for (i=0;i<=font_count;i++) {
-#ifdef XFT
-       /* load Xft font */
-       if (use_xft) {
-       /*if (fonts[i].xftfont != NULL && selected_font == 0) {
-                       XftFontClose(display, fonts[i].xftfont);
-       }*/
-               if ((fonts[i].xftfont =
-                       XftFontOpenName(display, screen, fonts[i].name)) != NULL)
-                       continue;
-               
-               ERR("can't load Xft font '%s'", fonts[i].name);
-               if ((fonts[i].xftfont =
-                       XftFontOpenName(display, screen,
-                                       "courier-12")) != NULL)
-                       continue;
-               
-               ERR("can't load Xft font '%s'", "courier-12");
-               
-               if ((fonts[i].font = XLoadQueryFont(display, "fixed")) == NULL) {
-                       CRIT_ERR("can't load font '%s'", "fixed");
-               }
-               use_xft = 0;
-               
-               continue;
-       }
-#endif
-       /* load normal font */
-/*     if (fonts[i].font != NULL)
-               XFreeFont(display, fonts[i].font);*/
-       
-       if ((fonts[i].font = XLoadQueryFont(display, fonts[i].name)) == NULL) {
-               ERR("can't load font '%s'", fonts[i].name);
-               if ((fonts[i].font = XLoadQueryFont(display, "fixed")) == NULL) {
-                       CRIT_ERR("can't load font '%s'", "fixed");
-               }
-       }
-       }
-}
-
-#endif /* X11 */
-
-/* default config file */
-static char *current_config;
-
-/* set to 1 if you want all text to be in uppercase */
-static unsigned int stuff_in_upper_case;
-
-/* Update interval */
-static double update_interval;
-
-/* Run how many times? */
-static unsigned long total_run_times;
-
-/* fork? */
-static int fork_to_background;
-
-static int cpu_avg_samples, net_avg_samples;
-
-#ifdef X11
-
-/* Always on bottom */
-static int on_bottom;
-
-/* Position on the screen */
-static int text_alignment;
-static int gap_x, gap_y;
-
-/* border */
-static int draw_borders;
-static int stippled_borders;
-
-static int draw_shades, draw_outline;
-
-static int border_margin, border_width;
-
-static long default_fg_color, default_bg_color, default_out_color;
-
-/* create own window or draw stuff to root? */
-static int own_window = 0;
-
-#ifdef OWN_WINDOW
-/* fixed size/pos is set if wm/user changes them */
-static int fixed_size = 0, fixed_pos = 0;
-#endif
-
-static int minimum_width, minimum_height;
-
-/* UTF-8 */
-int utf8_mode = 0;
-
-#endif /* X11 */
-
-/* no buffers in used memory? */
-int no_buffers;
-
-/* pad percentages to decimals? */
-static int pad_percents = 0;
-
-/* Text that is shown */
-static char original_text[] =
-    "$nodename - $sysname $kernel on $machine\n"
-    "$hr\n"
-    "${color grey}Uptime:$color $uptime\n"
-    "${color grey}Frequency (in MHz):$color $freq\n"
-    "${color grey}Frequency (in Ghz):$color $freq_g\n"
-    "${color grey}RAM Usage:$color $mem/$memmax - $memperc% ${membar 4}\n"
-    "${color grey}Swap Usage:$color $swap/$swapmax - $swapperc% ${swapbar 4}\n"
-    "${color grey}CPU Usage:$color $cpu% ${cpubar 4}\n"
-    "${color grey}Processes:$color $processes  ${color grey}Running:$color $running_processes\n"
-    "$hr\n"
-    "${color grey}File systems:\n"
-    " / $color${fs_free /}/${fs_size /} ${fs_bar 6 /}\n"
-    "${color grey}Networking:\n"
-    " Up:$color ${upspeed eth0} k/s${color grey} - Down:$color ${downspeed eth0} k/s\n"
-    "${color grey}Temperatures:\n"
-    " CPU:$color ${i2c temp 1}°C${color grey} - MB:$color ${i2c temp 2}°C\n"
-    "$hr\n"
-#ifdef SETI
-    "${color grey}SETI@Home Statistics:\n"
-    "${color grey}Seti Unit Number:$color $seti_credit\n"
-    "${color grey}Seti Progress:$color $seti_prog% $seti_progbar\n"
-#endif
-#ifdef MPD
-    "${color grey}MPD: $mpd_status $mpd_artist - $mpd_title from $mpd_album at $mpd_vol\n"
-    "Bitrate: $mpd_bitrate\n" "Progress: $mpd_bar\n"
-#endif
-    "${color grey}Name         PID     CPU%    MEM%\n"
-    " ${color lightgrey} ${top name 1} ${top pid 1} ${top cpu 1} ${top mem 1}\n"
-    " ${color lightgrey} ${top name 2} ${top pid 2} ${top cpu 2} ${top mem 2}\n"
-    " ${color lightgrey} ${top name 3} ${top pid 3} ${top cpu 3} ${top mem 3}\n"
-    " ${color lightgrey} ${top name 4} ${top pid 4} ${top cpu 4} ${top mem 4}\n"
-    "${tail /var/log/Xorg.0.log 3}";
-
-static char *text = original_text;
-
-static int total_updates;
-
-/* if-blocks */
-static int blockdepth = 0;
-static int if_jumped = 0;
-static int blockstart[MAX_IF_BLOCK_DEPTH];
-
-int check_mount(char *s)
-{
-       int ret = 0;
-       FILE *mtab = fopen("/etc/mtab", "r");
-       if (mtab) {
-               char buf1[256], buf2[128];
-               while (fgets(buf1, 256, mtab)) {
-                       sscanf(buf1, "%*s %128s", buf2);
-                       if (!strcmp(s, buf2)) {
-                               ret = 1;
-                               break;
-                       }
-               }
-               fclose(mtab);
-       } else {
-               ERR("Could not open mtab");
-       }
-       return ret;
-}
-
-
-#ifdef X11
-static inline int calc_text_width(const char *s, unsigned int l)
-{
-#ifdef XFT
-       if (use_xft) {
-               XGlyphInfo gi;
-               if (utf8_mode) {
-                       XftTextExtentsUtf8(display, fonts[selected_font].xftfont, s, l, &gi);
-               } else {
-                       XftTextExtents8(display, fonts[selected_font].xftfont, s, l, &gi);
-               }
-               return gi.xOff;
-       } else
-#endif
-       {
-               return XTextWidth(fonts[selected_font].font, s, l);
-       }
-}
-#endif /* X11 */
-
-/* formatted text to render on screen, generated in generate_text(),
- * drawn in draw_stuff() */
-
-static char text_buffer[TEXT_BUFFER_SIZE * 4];
-
-/* special stuff in text_buffer */
-
-#define SPECIAL_CHAR '\x01'
-
-enum {
-       HORIZONTAL_LINE,
-       STIPPLED_HR,
-       BAR,
-       FG,
-       BG,
-       OUTLINE,
-       ALIGNR,
-       ALIGNC,
-       GRAPH,
-       OFFSET,
-       VOFFSET,
-       FONT,
-};
-
-static struct special_t {
-       int type;
-       short height;
-       short width;
-       long arg;
-       double *graph;
-       double graph_scale;
-       int graph_width;
-       int scaled;
-       short font_added;
-       unsigned long first_colour; // for graph gradient
-       unsigned long last_colour;
-} specials[128];
-
-static int special_count;
-#ifdef X11
-static int special_index;      /* used when drawing */
-#endif /* X11 */
-
-#define MAX_GRAPH_DEPTH 256    /* why 256? who knows. */
-
-static struct special_t *new_special(char *buf, int t)
-{
-       if (special_count >= 128)
-               CRIT_ERR("too many special things in text");
-
-       buf[0] = SPECIAL_CHAR;
-       buf[1] = '\0';
-       if (t == GRAPH && specials[special_count].graph == NULL) {
-               if (specials[special_count].width > 0
-                   && specials[special_count].width < MAX_GRAPH_DEPTH)
-                       specials[special_count].graph_width = specials[special_count].width - 3;        // subtract 3 for the box
-               else
-                       specials[special_count].graph_width =
-                           MAX_GRAPH_DEPTH;
-               specials[special_count].graph =
-                   calloc(specials[special_count].graph_width,
-                          sizeof(double));
-               specials[special_count].graph_scale = 100;
-       }
-       specials[special_count].type = t;
-       return &specials[special_count++];
-}
-
-typedef struct tailstring_list {
-       char data[TEXT_BUFFER_SIZE];
-       struct tailstring_list *next;
-       struct tailstring_list *first;
-} tailstring;
-
-void addtail(tailstring ** head, char *data_in)
-{
-       tailstring *tmp;
-       if ((tmp = malloc(sizeof(*tmp))) == NULL) {
-               CRIT_ERR("malloc");
-       }
-       if (*head == NULL) {
-               tmp->first = tmp;
-       } else {
-               tmp->first = (*head)->first;
-       }
-       strncpy(tmp->data, data_in, TEXT_BUFFER_SIZE);
-       tmp->next = *head;
-       *head = tmp;
-}
-
-void freetail(tailstring * head)
-{
-       tailstring *tmp;
-       while (head != NULL) {
-               tmp = head->next;
-               free(head);
-               head = tmp;
-       }
-}
-
-void freelasttail(tailstring * head)
-{
-       tailstring * tmp = head;
-       while(tmp != NULL) {
-               if (tmp->next == head->first) {
-                       tmp->next = NULL;
-                       break;
-               }
-               tmp = tmp->next;
-       }
-       free(head->first);
-       while(head != NULL && tmp != NULL) {
-               head->first = tmp;
-               head = head->next;
-       }
-}
-
-static void new_bar(char *buf, int w, int h, int usage)
-{
-       struct special_t *s = new_special(buf, BAR);
-       s->arg = (usage > 255) ? 255 : ((usage < 0) ? 0 : usage);
-       s->width = w;
-       s->height = h;
-}
-
-static const char *scan_bar(const char *args, int *w, int *h)
-{
-       *w = 0;                 /* zero width means all space that is available */
-       *h = 6;
-       /* bar's argument is either height or height,width */
-       if (args) {
-               int n = 0;
-               if (sscanf(args, "%d,%d %n", h, w, &n) <= 1)
-                       sscanf(args, "%d %n", h, &n);
-               args += n;
-       }
-
-       return args;
-}
-
-static char *scan_font(const char *args)
-{
-       if (args && sizeof(args) < 127) {
-               return strdup(args);
-       }
-       else {
-               ERR("font scan failed, lets hope it doesn't mess stuff up");
-       }
-       return NULL;
-}
-
-#ifdef X11
-static void new_font(char *buf, char * args) {
-       struct special_t *s = new_special(buf, FONT);
-       if (!s->font_added || strcmp(args, fonts[s->font_added].name)) {
-               int tmp = selected_font;
-               selected_font = s->font_added = addfont(args);
-               load_fonts();
-               set_font();
-               selected_font = tmp;
-       }
-}
-#endif
-
-inline void graph_append(struct special_t *graph, double f)
-{
-       int i;
-       if (graph->scaled) {
-               graph->graph_scale = 0;
-       }
-       graph->graph[graph->graph_width - 1] = f; /* add new data */
-       for (i = 0; i < graph->graph_width - 1; i++) { /* shift all the data by 1 */
-               graph->graph[i] = graph->graph[i + 1];
-               if (graph->scaled && graph->graph[i] > graph->graph_scale) {
-                       graph->graph_scale = graph->graph[i]; /* check if we need to update the scale */
-               }
-       }
-}
-
-static void new_graph(char *buf, int w, int h, unsigned int first_colour, unsigned int second_colour, double i, int scaled)
-{
-       struct special_t *s = new_special(buf, GRAPH);
-       s->width = w;
-       s->height = h;
-       s->first_colour = first_colour;
-       s->last_colour = second_colour;
-       s->scaled = scaled;
-       if (s->width) {
-               s->graph_width = s->width - 3;  // subtract 3 for rectangle around
-       }
-       if (scaled) {
-               s->graph_scale = 1;
-       } else {
-               s->graph_scale = 100;
-       }
-       graph_append(s, i);
-}
-
-static const char *scan_graph(const char *args, int *w, int *h, unsigned int *first_colour, unsigned int *last_colour)
-{
-       *w = 0;                 /* zero width means all space that is available */
-       *h = 25;
-       *first_colour = 0;
-       *last_colour = 0;
-       /* graph's argument is either height or height,width */
-       if (args) {
-               if (sscanf(args, "%*s %d,%d %x %x", h, w, first_colour, last_colour) < 4) {
-                       if (sscanf(args, "%d,%d %x %x", h, w, first_colour, last_colour) < 4) {
-                               *w = 0;
-                               *h = 25;                        
-                               if (sscanf(args, "%*s %x %x", first_colour, last_colour) < 3) {
-                               *w = 0;
-                               *h = 25;
-                               if (sscanf(args, "%x %x", first_colour, last_colour) < 2) {
-                                       *first_colour = 0;
-                                       *last_colour = 0;
-                                       if (sscanf(args, "%d,%d", h, w) < 2) {
-                                               *first_colour = 0;
-                                               *last_colour = 0;
-                                               sscanf(args, "%*s %d,%d", h, w);
-                                       }
-                               }
-                       }
-                       }
-               }
-       }
-
-       return args;
-}
-
-
-static inline void new_hr(char *buf, int a)
-{
-       new_special(buf, HORIZONTAL_LINE)->height = a;
-}
-
-static inline void new_stippled_hr(char *buf, int a, int b)
-{
-       struct special_t *s = new_special(buf, STIPPLED_HR);
-       s->height = b;
-       s->arg = a;
-}
-
-static inline void new_fg(char *buf, long c)
-{
-       new_special(buf, FG)->arg = c;
-}
-
-static inline void new_bg(char *buf, long c)
-{
-       new_special(buf, BG)->arg = c;
-}
-
-static inline void new_outline(char *buf, long c)
-{
-       new_special(buf, OUTLINE)->arg = c;
-}
-
-static inline void new_offset(char *buf, long c)
-{
-       new_special(buf, OFFSET)->arg = c;
-}
-
-static inline void new_voffset(char *buf, long c)
-{
-       new_special(buf, VOFFSET)->arg = c;
-}
-
-static inline void new_alignr(char *buf, long c)
-{
-       new_special(buf, ALIGNR)->arg = c;
-}
-
-static inline void new_alignc(char *buf, long c)
-{
-       new_special(buf, ALIGNC)->arg = c;
-}
-
-/* quite boring functions */
-
-static inline void for_each_line(char *b, void (*f) (char *))
-{
-       char *ps, *pe;
-
-       for (ps = b, pe = b; *pe; pe++) {
-               if (*pe == '\n') {
-                       *pe = '\0';
-                       f(ps);
-                       *pe = '\n';
-                       ps = pe + 1;
-               }
-       }
-
-       if (ps < pe)
-               f(ps);
-}
-
-static void convert_escapes(char *buf)
-{
-       char *p = buf, *s = buf;
-
-       while (*s) {
-               if (*s == '\\') {
-                       s++;
-                       if (*s == 'n')
-                               *p++ = '\n';
-                       else if (*s == '\\')
-                               *p++ = '\\';
-                       s++;
-               } else
-                       *p++ = *s++;
-       }
-       *p = '\0';
-}
-
-/* converts from bytes to human readable format (k, M, G, T) */
-static void human_readable(long long a, char *buf, int size)
-{
-       //Strange conditional due to possible overflows
-       if(a / 1024 / 1024 / 1024.0 > 1024.0){
-               snprintf(buf, size, "%.2fT", (a / 1024 / 1024) / 1024 / 1024.0);
-       }
-       else if (a >= 1024 * 1024 * 1024) {
-               snprintf(buf, size, "%.2fG", (a / 1024 / 1024) / 1024.0);
-       }
-       else if (a >= 1024 * 1024) {
-               double m = (a / 1024) / 1024.0;
-               if (m >= 100.0)
-                       snprintf(buf, size, "%.0fM", m);
-               else
-                       snprintf(buf, size, "%.1fM", m);
-       } else if (a >= 1024)
-               snprintf(buf, size, "%Ldk", a / (long long) 1024);
-       else
-               snprintf(buf, size, "%Ld", a);
-}
-
-/* text handling */
-
-enum text_object_type {
-       OBJ_acpiacadapter,
-       OBJ_adt746xcpu,
-       OBJ_adt746xfan,
-       OBJ_acpifan,
-       OBJ_addr,
-       OBJ_linkstatus,
-       OBJ_acpitemp,
-       OBJ_acpitempf,
-       OBJ_battery,
-       OBJ_buffers,
-       OBJ_cached,
-       OBJ_color,
-       OBJ_font,
-       OBJ_cpu,
-       OBJ_cpubar,
-       OBJ_cpugraph,
-       OBJ_downspeed,
-       OBJ_downspeedf,
-       OBJ_downspeedgraph,
-       OBJ_else,
-       OBJ_endif,
-       OBJ_exec,
-       OBJ_execi,
-       OBJ_execbar,
-       OBJ_execgraph,
-       OBJ_freq,
-       OBJ_freq_g,
-       OBJ_fs_bar,
-       OBJ_fs_bar_free,
-       OBJ_fs_free,
-       OBJ_fs_free_perc,
-       OBJ_fs_size,
-       OBJ_fs_used,
-       OBJ_fs_used_perc,
-       OBJ_hr,
-       OBJ_offset,
-       OBJ_voffset,
-       OBJ_alignr,
-       OBJ_alignc,
-       OBJ_i2c,
-       OBJ_if_existing,
-       OBJ_if_mounted,
-       OBJ_if_running,
-       OBJ_top,
-       OBJ_top_mem,
-       OBJ_tail,
-       OBJ_kernel,
-       OBJ_loadavg,
-       OBJ_machine,
-       OBJ_mails,
-       OBJ_mem,
-       OBJ_membar,
-       OBJ_memgraph,
-       OBJ_memmax,
-       OBJ_memperc,
-       OBJ_mixer,
-       OBJ_mixerl,
-       OBJ_mixerr,
-       OBJ_mixerbar,
-       OBJ_mixerlbar,
-       OBJ_mixerrbar,
-       OBJ_new_mails,
-       OBJ_nodename,
-       OBJ_pre_exec,
-#ifdef MLDONKEY
-       OBJ_ml_upload_counter,
-       OBJ_ml_download_counter,
-       OBJ_ml_nshared_files,
-       OBJ_ml_shared_counter,
-       OBJ_ml_tcp_upload_rate,
-       OBJ_ml_tcp_download_rate,
-       OBJ_ml_udp_upload_rate,
-       OBJ_ml_udp_download_rate,
-       OBJ_ml_ndownloaded_files,
-       OBJ_ml_ndownloading_files,
-#endif
-       OBJ_processes,
-       OBJ_running_processes,
-       OBJ_shadecolor,
-       OBJ_outlinecolor,
-       OBJ_stippled_hr,
-       OBJ_swap,
-       OBJ_swapbar,
-       OBJ_swapmax,
-       OBJ_swapperc,
-       OBJ_sysname,
-       OBJ_temp1,              /* i2c is used instead in these */
-       OBJ_temp2,
-       OBJ_text,
-       OBJ_time,
-       OBJ_utime,
-       OBJ_totaldown,
-       OBJ_totalup,
-       OBJ_updates,
-       OBJ_upspeed,
-       OBJ_upspeedf,
-       OBJ_upspeedgraph,
-       OBJ_uptime,
-       OBJ_uptime_short,
-#ifdef SETI
-       OBJ_seti_prog,
-       OBJ_seti_progbar,
-       OBJ_seti_credit,
-#endif
-#ifdef MPD
-       OBJ_mpd_title,
-       OBJ_mpd_artist,
-       OBJ_mpd_album,
-       OBJ_mpd_vol,
-       OBJ_mpd_bitrate,
-       OBJ_mpd_status,
-       OBJ_mpd_host,
-       OBJ_mpd_port,
-       OBJ_mpd_bar,
-       OBJ_mpd_elapsed,
-       OBJ_mpd_length,
-       OBJ_mpd_percent,
-#endif
-};
-
-struct text_object {
-       int type;
-       int a, b;
-       unsigned int c, d;
-       union {
-               char *s;        /* some string */
-               int i;          /* some integer */
-               long l;         /* some other integer */
-               struct net_stat *net;
-               struct fs_stat *fs;
-               unsigned char loadavg[3];
-
-               struct {
-                       struct fs_stat *fs;
-                       int w, h;
-               } fsbar;        /* 3 */
-
-               struct {
-                       int l;
-                       int w, h;
-               } mixerbar;     /* 3 */
-
-               struct {
-                       int fd;
-                       int arg;
-                       char devtype[256];
-                       char type[64];
-               } i2c;          /* 2 */
-               struct {
-                       int pos;
-                       char *s;
-               } ifblock;
-               struct {
-                       int num;
-                       int type;
-               } top;
-
-               struct {
-                       int wantedlines;
-                       int readlines;
-                       char *logfile;
-                       double last_update;
-                       float interval;
-                       char *buffer;
-               } tail;
-
-               struct {
-                       double last_update;
-                       float interval;
-                       char *cmd;
-                       char *buffer;
-               } execi;        /* 5 */
-
-               struct {
-                       int a, b;
-               } pair;         /* 2 */
-       } data;
-};
-
-static unsigned int text_object_count;
-static struct text_object *text_objects;
-
-/* new_text_object() allocates a new zeroed text_object */
-static struct text_object *new_text_object()
-{
-       text_object_count++;
-       text_objects = (struct text_object *) realloc(text_objects,
-                                                     sizeof(struct
-                                                            text_object) *
-                                                     text_object_count);
-       memset(&text_objects[text_object_count - 1], 0,
-              sizeof(struct text_object));
-
-       return &text_objects[text_object_count - 1];
-}
-
-static void free_text_objects()
-{
-       unsigned int i;
-
-       for (i = 0; i < text_object_count; i++) {
-               switch (text_objects[i].type) {
-               case OBJ_acpitemp:
-                       close(text_objects[i].data.i);
-                       break;
-               case OBJ_acpitempf:
-                       close(text_objects[i].data.i);
-                       break;
-               case OBJ_i2c:
-                       close(text_objects[i].data.i2c.fd);
-                       break;
-               case OBJ_time:
-               case OBJ_utime:
-               case OBJ_if_existing:
-               case OBJ_if_mounted:
-               case OBJ_if_running:
-                       free(text_objects[i].data.ifblock.s);
-                       break;
-               case OBJ_text:
-               case OBJ_exec:
-               case OBJ_execbar:
-               case OBJ_execgraph:
-#ifdef MPD
-               case OBJ_mpd_title:
-               case OBJ_mpd_artist:
-               case OBJ_mpd_album:
-               case OBJ_mpd_status:
-               case OBJ_mpd_host:
-#endif
-               case OBJ_pre_exec:
-               case OBJ_battery:
-                       free(text_objects[i].data.s);
-                       break;
-
-               case OBJ_execi:
-                       free(text_objects[i].data.execi.cmd);
-                       free(text_objects[i].data.execi.buffer);
-                       break;
-               }
-       }
-
-       free(text_objects);
-       text_objects = NULL;
-       text_object_count = 0;
-}
-
-void scan_mixer_bar(const char *arg, int *a, int *w, int *h)
-{
-       char buf1[64];
-       int n;
-
-       if (arg && sscanf(arg, "%63s %n", buf1, &n) >= 1) {
-               *a = mixer_init(buf1);
-               (void) scan_bar(arg + n, w, h);
-       } else {
-               *a = mixer_init(0);
-               (void) scan_bar(arg, w, h);
-       }
-}
-
-/* construct_text_object() creates a new text_object */
-static void construct_text_object(const char *s, const char *arg)
-{
-       struct text_object *obj = new_text_object();
-
-#define OBJ(a, n) if (strcmp(s, #a) == 0) { obj->type = OBJ_##a; need_mask |= (1 << n); {
-#define END ; } } else
-
-#ifdef X11     
-if (s[0] == '#') {
-               obj->type = OBJ_color;
-               obj->data.l = get_x11_color(s);
-       } else
-#endif /* X11 */
-       OBJ(acpitemp, 0) obj->data.i = open_acpi_temperature(arg);
-       END OBJ(acpitempf, 0) obj->data.i = open_acpi_temperature(arg);
-       END OBJ(acpiacadapter, 0)
-       END OBJ(freq, 0);
-       END OBJ(freq_g, 0);
-       END OBJ(acpifan, 0);
-       END OBJ(battery, 0);
-       char bat[64];
-       if (arg)
-               sscanf(arg, "%63s", bat);
-       else
-               strcpy(bat, "BAT0");
-       obj->data.s = strdup(bat);
-       END OBJ(buffers, INFO_BUFFERS)
-       END OBJ(cached, INFO_BUFFERS)
-       END OBJ(cpu, INFO_CPU)
-       END OBJ(cpubar, INFO_CPU)
-        (void) scan_bar(arg, &obj->data.pair.a, &obj->data.pair.b);
-       END OBJ(cpugraph, INFO_CPU)
-                       (void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d);
-       END OBJ(color, 0) 
-#ifdef X11
-                       obj->data.l = arg ? get_x11_color(arg) : default_fg_color;
-#endif /* X11 */
-       END
-                       OBJ(font, 0)
-                       obj->data.s = scan_font(arg);
-                       END
-                       OBJ(downspeed, INFO_NET) obj->data.net = get_net_stat(arg);
-       END OBJ(downspeedf, INFO_NET) obj->data.net = get_net_stat(arg);
-       END OBJ(downspeedgraph, INFO_NET)
-                       (void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d);
-       char buf[64];
-       sscanf(arg, "%63s %*i,%*i %*i", buf);
-       obj->data.net = get_net_stat(buf);
-       if (sscanf(arg, "%*s %d,%d %*d", &obj->b, &obj->a) <= 1) {
-               if (sscanf(arg, "%*s %d,%d", &obj->b, &obj->a) <= 1) {
-                       obj->a = 0;
-                       obj->b = 25;
-               }
-       }
-       END OBJ(
-                      else
-                      , 0)
-       if (blockdepth) {
-               text_objects[blockstart[blockdepth - 1] -
-                            1].data.ifblock.pos = text_object_count;
-               blockstart[blockdepth - 1] = text_object_count;
-               obj->data.ifblock.pos = text_object_count + 2;
-       } else {
-               ERR("$else: no matching $if_*");
-       }
-       END OBJ(endif, 0)
-       if (blockdepth) {
-               blockdepth--;
-               text_objects[blockstart[blockdepth] - 1].data.ifblock.pos =
-                   text_object_count;
-       } else {
-               ERR("$endif: no matching $if_*");
-       }
-       END
-#ifdef HAVE_POPEN
-           OBJ(exec, 0) obj->data.s = strdup(arg ? arg : "");
-       END OBJ(execbar, 0) obj->data.s = strdup(arg ? arg : "");
-       END OBJ(execgraph, 0) obj->data.s = strdup(arg ? arg : "");
-       END OBJ(execi, 0) unsigned int n;
-
-       if (!arg
-           || sscanf(arg, "%f %n", &obj->data.execi.interval, &n) <= 0) {
-               char buf[256];
-               ERR("${execi <interval> command}");
-               obj->type = OBJ_text;
-               snprintf(buf, 256, "${%s}", s);
-               obj->data.s = strdup(buf);
-       } else {
-               obj->data.execi.cmd = strdup(arg + n);
-               obj->data.execi.buffer =
-                   (char *) calloc(1, TEXT_BUFFER_SIZE);
-       }
-       END OBJ(pre_exec, 0) obj->type = OBJ_text;
-       if (arg) {
-               FILE *fp = popen(arg, "r");
-               unsigned int n;
-               char buf[2048];
-
-               n = fread(buf, 1, 2048, fp);
-               buf[n] = '\0';
-
-               if (n && buf[n - 1] == '\n')
-                       buf[n - 1] = '\0';
-
-               (void) pclose(fp);
-
-               obj->data.s = strdup(buf);
-       } else
-               obj->data.s = strdup("");
-       END
-#endif
-           OBJ(fs_bar, INFO_FS) obj->data.fsbar.h = 4;
-       arg = scan_bar(arg, &obj->data.fsbar.w, &obj->data.fsbar.h);
-       if (arg) {
-               while (isspace(*arg))
-                       arg++;
-               if (*arg == '\0')
-                       arg = "/";
-       } else
-               arg = "/";
-       obj->data.fsbar.fs = prepare_fs_stat(arg);
-       END OBJ(fs_bar_free, INFO_FS) obj->data.fsbar.h = 4;
-       if (arg) {
-               unsigned int n;
-               if (sscanf(arg, "%d %n", &obj->data.fsbar.h, &n) >= 1)
-                       arg += n;
-       } else
-               arg = "/";
-       obj->data.fsbar.fs = prepare_fs_stat(arg);
-       END OBJ(fs_free, INFO_FS) if (!arg)
-                arg = "/";
-       obj->data.fs = prepare_fs_stat(arg);
-       END OBJ(fs_used_perc, INFO_FS) if (!arg)
-                arg = "/";
-       obj->data.fs = prepare_fs_stat(arg);
-       END OBJ(fs_free_perc, INFO_FS) if (!arg)
-                arg = "/";
-       obj->data.fs = prepare_fs_stat(arg);
-       END OBJ(fs_size, INFO_FS) if (!arg)
-                arg = "/";
-       obj->data.fs = prepare_fs_stat(arg);
-       END OBJ(fs_used, INFO_FS) if (!arg)
-                arg = "/";
-       obj->data.fs = prepare_fs_stat(arg);
-       END OBJ(hr, 0) obj->data.i = arg ? atoi(arg) : 1;
-       END OBJ(offset, 0) obj->data.i = arg ? atoi(arg) : 1;
-       END OBJ(voffset, 0) obj->data.i = arg ? atoi(arg) : 1;
-       END OBJ(i2c, INFO_I2C) char buf1[64], buf2[64];
-       int n;
-
-       if (!arg) {
-               ERR("i2c needs arguments");
-               obj->type = OBJ_text;
-               obj->data.s = strdup("${i2c}");
-               return;
-       }
-
-       if (sscanf(arg, "%63s %63s %d", buf1, buf2, &n) != 3) {
-               /* if scanf couldn't read three values, read type and num and use
-                * default device */
-               sscanf(arg, "%63s %d", buf2, &n);
-               obj->data.i2c.fd =
-                   open_i2c_sensor(0, buf2, n, &obj->data.i2c.arg,
-                                   obj->data.i2c.devtype);
-               strcpy(obj->data.i2c.type, buf2);
-       } else {
-               obj->data.i2c.fd =
-                   open_i2c_sensor(buf1, buf2, n, &obj->data.i2c.arg,
-                                   obj->data.i2c.devtype);
-               strcpy(obj->data.i2c.type, buf2);
-       }
-
-       END OBJ(top, INFO_TOP)
-       char buf[64];
-       int n;
-       if (!arg) {
-               ERR("top needs arguments");
-               obj->type = OBJ_text;
-               obj->data.s = strdup("${top}");
-               return;
-       }
-       if (sscanf(arg, "%63s %i", buf, &n) == 2) {
-               if (strcmp(buf, "name") == 0) {
-                       obj->data.top.type = TOP_NAME;
-               } else if (strcmp(buf, "cpu") == 0) {
-                       obj->data.top.type = TOP_CPU;
-               } else if (strcmp(buf, "pid") == 0) {
-                       obj->data.top.type = TOP_PID;
-               } else if (strcmp(buf, "mem") == 0) {
-                       obj->data.top.type = TOP_MEM;
-               } else {
-                       ERR("invalid arg for top");
-                       return;
-               }
-               if (n < 1 || n > 10) {
-                       CRIT_ERR("invalid arg for top");
-                       return;
-               } else {
-                       obj->data.top.num = n - 1;
-                       top_cpu = 1;
-               }
-       } else {
-               ERR("invalid args given for top");
-               return;
-       }
-       END OBJ(top_mem, INFO_TOP)
-       char buf[64];
-       int n;
-       if (!arg) {
-               ERR("top_mem needs arguments");
-               obj->type = OBJ_text;
-               obj->data.s = strdup("${top_mem}");
-               return;
-       }
-       if (sscanf(arg, "%63s %i", buf, &n) == 2) {
-               if (strcmp(buf, "name") == 0) {
-                       obj->data.top.type = TOP_NAME;
-               } else if (strcmp(buf, "cpu") == 0) {
-                       obj->data.top.type = TOP_CPU;
-               } else if (strcmp(buf, "pid") == 0) {
-                       obj->data.top.type = TOP_PID;
-               } else if (strcmp(buf, "mem") == 0) {
-                       obj->data.top.type = TOP_MEM;
-               } else {
-                       ERR("invalid arg for top");
-                       return;
-               }
-               if (n < 1 || n > 10) {
-                       CRIT_ERR("invalid arg for top");
-                       return;
-               } else {
-                       obj->data.top.num = n - 1;
-                       top_mem = 1;
-               }
-       } else {
-               ERR("invalid args given for top");
-               return;
-       }
-       END OBJ(addr, INFO_NET) obj->data.net = get_net_stat(arg);
-       END OBJ(linkstatus, INFO_WIFI) obj->data.net = get_net_stat(arg);
-       END OBJ(tail, 0)
-       char buf[64];
-       int n1, n2;
-       if (!arg) {
-               ERR("tail needs arguments");
-               obj->type = OBJ_text;
-               obj->data.s = strdup("${tail}");
-               return;
-       }
-       if (sscanf(arg, "%63s %i %i", buf, &n1, &n2) == 2) {
-               if (n1 < 1 || n1 > 30) {
-                       CRIT_ERR("invalid arg for tail, number of lines must be between 1 and 30");
-                       return;
-               } else {
-                       FILE *fp;
-                       fp = fopen(buf, "rt");
-                       if (fp != NULL) {
-                               obj->data.tail.logfile =
-                                   malloc(TEXT_BUFFER_SIZE);
-                               strcpy(obj->data.tail.logfile, buf);
-                               obj->data.tail.wantedlines = n1 - 1;
-                               obj->data.tail.interval =
-                                   update_interval * 2;
-                               fclose(fp);
-                       } else {
-                               //fclose (fp);
-                               CRIT_ERR("tail logfile does not exist, or you do not have correct permissions");
-                       }
-               }
-       } else if (sscanf(arg, "%63s %i %i", buf, &n1, &n2) == 3) {
-               if (n1 < 1 || n1 > 30) {
-                       CRIT_ERR
-                           ("invalid arg for tail, number of lines must be between 1 and 30");
-                       return;
-               } else if (n2 < 1 || n2 < update_interval) {
-                       CRIT_ERR
-                           ("invalid arg for tail, interval must be greater than 0 and Conky's interval");
-                       return;
-               } else {
-                       FILE *fp;
-                       fp = fopen(buf, "rt");
-                       if (fp != NULL) {
-                               obj->data.tail.logfile =
-                                   malloc(TEXT_BUFFER_SIZE);
-                               strcpy(obj->data.tail.logfile, buf);
-                               obj->data.tail.wantedlines = n1 - 1;
-                               obj->data.tail.interval = n2;
-                               fclose(fp);
-                       } else {
-                               //fclose (fp);
-                               CRIT_ERR("tail logfile does not exist, or you do not have correct permissions");
-                       }
-               }
-       }
-
-       else {
-               ERR("invalid args given for tail");
-               return;
-       }
-       obj->data.tail.buffer = malloc(TEXT_BUFFER_SIZE * 6); /* asumming all else worked */
-       END OBJ(loadavg, INFO_LOADAVG) int a = 1, b = 2, c = 3, r = 3;
-       if (arg) {
-               r = sscanf(arg, "%d %d %d", &a, &b, &c);
-               if (r >= 3 && (c < 1 || c > 3))
-                       r--;
-               if (r >= 2 && (b < 1 || b > 3))
-                       r--, b = c;
-               if (r >= 1 && (a < 1 || a > 3))
-                       r--, a = b, b = c;
-       }
-       obj->data.loadavg[0] = (r >= 1) ? (unsigned char) a : 0;
-       obj->data.loadavg[1] = (r >= 2) ? (unsigned char) b : 0;
-       obj->data.loadavg[2] = (r >= 3) ? (unsigned char) c : 0;
-       END OBJ(if_existing, 0)
-       if (blockdepth >= MAX_IF_BLOCK_DEPTH) {
-               CRIT_ERR("MAX_IF_BLOCK_DEPTH exceeded");
-       }
-       if (!arg) {
-               ERR("if_existing needs an argument");
-               obj->data.ifblock.s = 0;
-       } else
-               obj->data.ifblock.s = strdup(arg);
-       blockstart[blockdepth] = text_object_count;
-       obj->data.ifblock.pos = text_object_count + 2;
-       blockdepth++;
-       END OBJ(if_mounted, 0)
-       if (blockdepth >= MAX_IF_BLOCK_DEPTH) {
-               CRIT_ERR("MAX_IF_BLOCK_DEPTH exceeded");
-       }
-       if (!arg) {
-               ERR("if_mounted needs an argument");
-               obj->data.ifblock.s = 0;
-       } else
-               obj->data.ifblock.s = strdup(arg);
-       blockstart[blockdepth] = text_object_count;
-       obj->data.ifblock.pos = text_object_count + 2;
-       blockdepth++;
-       END OBJ(if_running, 0)
-       if (blockdepth >= MAX_IF_BLOCK_DEPTH) {
-               CRIT_ERR("MAX_IF_BLOCK_DEPTH exceeded");
-       }
-       if (arg) {
-               char buf[256];
-               snprintf(buf, 256, "pidof %s >/dev/null", arg);
-               obj->data.ifblock.s = strdup(buf);
-       } else {
-               ERR("if_running needs an argument");
-               obj->data.ifblock.s = 0;
-       }
-       blockstart[blockdepth] = text_object_count;
-       obj->data.ifblock.pos = text_object_count + 2;
-       blockdepth++;
-       END OBJ(kernel, 0)
-       END OBJ(machine, 0)
-       END OBJ(mails, INFO_MAIL)
-       END OBJ(mem, INFO_MEM)
-       END OBJ(memmax, INFO_MEM)
-       END OBJ(memperc, INFO_MEM)
-       END OBJ(membar, INFO_MEM)
-        (void) scan_bar(arg, &obj->data.pair.a, &obj->data.pair.b);
-       END OBJ(memgraph, INFO_MEM)
-                       (void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d);
-       END OBJ(mixer, INFO_MIXER) obj->data.l = mixer_init(arg);
-       END OBJ(mixerl, INFO_MIXER) obj->data.l = mixer_init(arg);
-       END OBJ(mixerr, INFO_MIXER) obj->data.l = mixer_init(arg);
-       END OBJ(mixerbar, INFO_MIXER)
-           scan_mixer_bar(arg, &obj->data.mixerbar.l,
-                          &obj->data.mixerbar.w, &obj->data.mixerbar.h);
-       END OBJ(mixerlbar, INFO_MIXER)
-           scan_mixer_bar(arg, &obj->data.mixerbar.l,
-                          &obj->data.mixerbar.w, &obj->data.mixerbar.h);
-       END OBJ(mixerrbar, INFO_MIXER)
-           scan_mixer_bar(arg, &obj->data.mixerbar.l,
-                          &obj->data.mixerbar.w, &obj->data.mixerbar.h);
-       END
-#ifdef MLDONKEY
-           OBJ(ml_upload_counter, INFO_MLDONKEY)
-       END OBJ(ml_download_counter, INFO_MLDONKEY)
-       END OBJ(ml_nshared_files, INFO_MLDONKEY)
-       END OBJ(ml_shared_counter, INFO_MLDONKEY)
-       END OBJ(ml_tcp_upload_rate, INFO_MLDONKEY)
-       END OBJ(ml_tcp_download_rate, INFO_MLDONKEY)
-       END OBJ(ml_udp_upload_rate, INFO_MLDONKEY)
-       END OBJ(ml_udp_download_rate, INFO_MLDONKEY)
-       END OBJ(ml_ndownloaded_files, INFO_MLDONKEY)
-       END OBJ(ml_ndownloading_files, INFO_MLDONKEY) END
-#endif
-        OBJ(new_mails, INFO_MAIL)
-       END OBJ(nodename, 0)
-       END OBJ(processes, INFO_PROCS)
-       END OBJ(running_processes, INFO_RUN_PROCS)
-       END OBJ(shadecolor, 0)
-#ifdef X11
-           obj->data.l = arg ? get_x11_color(arg) : default_bg_color;
-#endif /* X11 */
-       END OBJ(outlinecolor, 0)
-#ifdef X11
-           obj->data.l = arg ? get_x11_color(arg) : default_out_color;
-#endif /* X11 */
-       END OBJ(stippled_hr, 0)
-#ifdef X11
-int a = stippled_borders, b = 1;
-       if (arg) {
-               if (sscanf(arg, "%d %d", &a, &b) != 2)
-                       sscanf(arg, "%d", &b);
-       }
-       if (a <= 0)
-               a = 1;
-       obj->data.pair.a = a;
-       obj->data.pair.b = b;
-#endif /* X11 */
-       END OBJ(swap, INFO_MEM)
-       END OBJ(swapmax, INFO_MEM)
-       END OBJ(swapperc, INFO_MEM)
-       END OBJ(swapbar, INFO_MEM)
-        (void) scan_bar(arg, &obj->data.pair.a, &obj->data.pair.b);
-       END OBJ(sysname, 0) END OBJ(temp1, INFO_I2C) obj->type = OBJ_i2c;
-       obj->data.i2c.fd =
-           open_i2c_sensor(0, "temp", 1, &obj->data.i2c.arg,
-                           obj->data.i2c.devtype);
-       END OBJ(temp2, INFO_I2C) obj->type = OBJ_i2c;
-       obj->data.i2c.fd =
-           open_i2c_sensor(0, "temp", 2, &obj->data.i2c.arg,
-                           obj->data.i2c.devtype);
-       END OBJ(time, 0) obj->data.s = strdup(arg ? arg : "%F %T");
-       END OBJ(utime, 0) obj->data.s = strdup(arg ? arg : "%F %T");
-       END OBJ(totaldown, INFO_NET) obj->data.net = get_net_stat(arg);
-       END OBJ(totalup, INFO_NET) obj->data.net = get_net_stat(arg);
-       END OBJ(updates, 0)
-       END OBJ(alignr, 0) obj->data.i = arg ? atoi(arg) : 0;
-       END OBJ(alignc, 0) obj->data.i = arg ? atoi(arg) : 0;
-       END OBJ(upspeed, INFO_NET) obj->data.net = get_net_stat(arg);
-       END OBJ(upspeedf, INFO_NET) obj->data.net = get_net_stat(arg);
-       END OBJ(upspeedgraph, INFO_NET)
-                       (void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d);
-       char buf[64];
-       sscanf(arg, "%63s %*i,%*i %*i", buf);
-       obj->data.net = get_net_stat(buf);
-       if (sscanf(arg, "%*s %d,%d %*d", &obj->b, &obj->a) <= 1) {
-               if (sscanf(arg, "%*s %d,%d", &obj->a, &obj->a) <= 1) {
-                       obj->a = 0;
-                       obj->b = 25;
-               }
-       }
-       END OBJ(uptime_short, INFO_UPTIME) END OBJ(uptime, INFO_UPTIME) END
-           OBJ(adt746xcpu, 0) END OBJ(adt746xfan, 0) END
-#ifdef SETI
-        OBJ(seti_prog, INFO_SETI) END OBJ(seti_progbar, INFO_SETI)
-        (void) scan_bar(arg, &obj->data.pair.a, &obj->data.pair.b);
-       END OBJ(seti_credit, INFO_SETI) END
-#endif
-#ifdef MPD
-        OBJ(mpd_artist, INFO_MPD)
-       END OBJ(mpd_title, INFO_MPD)
-       END OBJ(mpd_elapsed, INFO_MPD)
-       END OBJ(mpd_length, INFO_MPD)
-       END OBJ(mpd_percent, INFO_MPD)
-       END OBJ(mpd_album, INFO_MPD) END OBJ(mpd_vol,
-                                            INFO_MPD) END OBJ(mpd_bitrate,
-                                                              INFO_MPD)
-       END OBJ(mpd_status, INFO_MPD) END OBJ(mpd_bar, INFO_MPD)
-        (void) scan_bar(arg, &obj->data.pair.a, &obj->data.pair.b);
-       END
-#endif
-       {
-               char buf[256];
-               ERR("unknown variable %s", s);
-               obj->type = OBJ_text;
-               snprintf(buf, 256, "${%s}", s);
-               obj->data.s = strdup(buf);
-       }
-#undef OBJ
-}
-
-/* append_text() appends text to last text_object if it's text, if it isn't
- * it creates a new text_object */
-static void append_text(const char *s)
-{
-       struct text_object *obj;
-
-       if (s == NULL || *s == '\0')
-               return;
-
-       obj = text_object_count ? &text_objects[text_object_count - 1] : 0;
-
-       /* create a new text object? */
-       if (!obj || obj->type != OBJ_text) {
-               obj = new_text_object();
-               obj->type = OBJ_text;
-               obj->data.s = strdup(s);
-       } else {
-               /* append */
-               obj->data.s = (char *) realloc(obj->data.s,
-                                              strlen(obj->data.s) +
-                                              strlen(s) + 1);
-               strcat(obj->data.s, s);
-       }
-}
-
-static void extract_variable_text(const char *p)
-{
-       const char *s = p;
-
-       free_text_objects();
-
-       while (*p) {
-               if (*p == '$') {
-                       *(char *) p = '\0';
-                       append_text(s);
-                       *(char *) p = '$';
-                       p++;
-                       s = p;
-
-                       if (*p != '$') {
-                               char buf[256];
-                               const char *var;
-                               unsigned int len;
-
-                               /* variable is either $foo or ${foo} */
-                               if (*p == '{') {
-                                       p++;
-                                       s = p;
-                                       while (*p && *p != '}')
-                                               p++;
-                               } else {
-                                       s = p;
-                                       if (*p == '#')
-                                               p++;
-                                       while (*p && (isalnum((int) *p)
-                                                     || *p == '_'))
-                                               p++;
-                               }
-
-                               /* copy variable to buffer */
-                               len = (p - s > 255) ? 255 : (p - s);
-                               strncpy(buf, s, len);
-                               buf[len] = '\0';
-
-                               if (*p == '}')
-                                       p++;
-                               s = p;
-
-                               var = getenv(buf);
-
-                               /* if variable wasn't found from environment, use some special */
-                               if (!var) {
-                                       char *p;
-                                       char *arg = 0;
-
-                                       /* split arg */
-                                       if (strchr(buf, ' ')) {
-                                               arg = strchr(buf, ' ');
-                                               *arg = '\0';
-                                               arg++;
-                                               while (isspace((int) *arg))
-                                                       arg++;
-                                               if (!*arg)
-                                                       arg = 0;
-                                       }
-
-                                       /* lowercase variable name */
-                                       p = buf;
-                                       while (*p) {
-                                               *p = tolower(*p);
-                                               p++;
-                                       }
-
-                                       construct_text_object(buf, arg);
-                               }
-                               continue;
-                       } else
-                               append_text("$");
-               }
-
-               p++;
-       }
-       append_text(s);
-       if (blockdepth) {
-               ERR("one or more $endif's are missing");
-       }
-}
-
-double current_update_time, last_update_time;
-
-static void generate_text()
-{
-       unsigned int i, n;
-       struct information *cur = &info;
-       char *p;
-
-       special_count = 0;
-
-       /* update info */
-
-       current_update_time = get_time();
-
-       update_stuff(cur);
-
-       /* generate text */
-
-       n = TEXT_BUFFER_SIZE * 4 - 2;
-       p = text_buffer;
-
-       for (i = 0; i < text_object_count; i++) {
-               struct text_object *obj = &text_objects[i];
-
-#define OBJ(a) break; case OBJ_##a:
-
-               switch (obj->type) {
-               default:
-                       {
-                               ERR("not implemented obj type %d",
-                                   obj->type);
-                       }
-                       OBJ(acpitemp) {
-                               /* does anyone have decimals in acpi temperature? */
-                               if (!use_spacer)
-                                       snprintf(p, n, "%d", (int)
-                                                       get_acpi_temperature(obj->
-                                                                       data.
-                                                                       i));
-                               else
-                                       snprintf(p, 5, "%d    ", (int)
-                                                       get_acpi_temperature(obj->
-                                                                       data.
-                                                                       i));
-                       }
-                       OBJ(acpitempf) {
-                               /* does anyone have decimals in acpi temperature? */
-                               if (!use_spacer)
-                                       snprintf(p, n, "%d", (int)
-                                                       ((get_acpi_temperature(obj->
-                                                                       data.
-                                                                       i)+ 40) * 9.0 / 5 - 40));
-                               else
-                                       snprintf(p, 5, "%d    ", (int)
-                                                       ((get_acpi_temperature(obj->
-                                                                       data.
-                                                                       i)+ 40) * 9.0 / 5 - 40));
-                       }
-                       OBJ(freq) {
-                               snprintf(p, n, "%sMhz", get_freq());
-                       }
-                       OBJ(freq_g) {
-                               float ghz = (float)(atof(get_freq())/1000);
-                               //printf("%f\n", ghz);
-                               snprintf(p, n, "%'.2fGhz", ghz);
-                       }
-                       OBJ(adt746xcpu) {
-                               snprintf(p, n, "%s", get_adt746x_cpu());
-                       }
-                       OBJ(adt746xfan) {
-                               snprintf(p, n, "%s", get_adt746x_fan());
-                       }
-                       OBJ(acpifan) {
-                               snprintf(p, n, "%s", get_acpi_fan());
-                       }
-                       OBJ(acpiacadapter) {
-                               snprintf(p, n, "%s",
-                                        get_acpi_ac_adapter());
-                       }
-                       OBJ(battery) {
-                               get_battery_stuff(p, n, obj->data.s);
-                       }
-                       OBJ(buffers) {
-                               human_readable(cur->buffers * 1024, p,
-                                              255);
-                       }
-                       OBJ(cached) {
-                               human_readable(cur->cached * 1024, p, 255);
-                       }
-                       OBJ(cpu) {
-                               if (!use_spacer)
-                                       snprintf(p, n, "%*d", pad_percents,
-                                                (int) (cur->cpu_usage *
-                                                       100.0));
-                               else
-                                       snprintf(p, 4, "%*d    ",
-                                                pad_percents,
-                                                (int) (cur->cpu_usage *
-                                                       100.0));
-                       }
-                       OBJ(cpubar) {
-                               new_bar(p, obj->data.pair.a,
-                                       obj->data.pair.b,
-                                       (int) (cur->cpu_usage * 255.0));
-                       }
-                       OBJ(cpugraph) {
-                               new_graph(p, obj->a,
-                                         obj->b, obj->c, obj->d,
-                                         (unsigned int) (cur->cpu_usage *
-                                                         100), 0);
-                       }
-                       OBJ(color) {
-                               new_fg(p, obj->data.l);
-                       }
-#ifdef X11
-                       OBJ(font) {
-                               new_font(p, obj->data.s);
-                       }
-#endif /* X11 */
-                       OBJ(downspeed) {
-                               if (!use_spacer) {
-                                       snprintf(p, n, "%d",
-                                                (int) (obj->data.net->
-                                                       recv_speed /
-                                                       1024));
-                               } else
-                                       snprintf(p, 6, "%d     ",
-                                                (int) (obj->data.net->
-                                                       recv_speed /
-                                                       1024));
-                       }
-                       OBJ(downspeedf) {
-                               if (!use_spacer)
-                                       snprintf(p, n, "%.1f",
-                                                obj->data.net->
-                                                recv_speed / 1024.0);
-                               else
-                                       snprintf(p, 8, "%.1f       ",
-                                                obj->data.net->
-                                                recv_speed / 1024.0);
-                       }
-                       OBJ(downspeedgraph) {
-                               if (obj->data.net->recv_speed == 0)     // this is just to make the ugliness at start go away
-                                       obj->data.net->recv_speed = 0.01;
-                               new_graph(p, obj->a, obj->b, obj->c, obj->d,
-                                         (obj->data.net->recv_speed /
-                               1024.0), 1);
-                       }
-                       OBJ(
-                                  else
-                       ) {
-                               if (!if_jumped) {
-                                       i = obj->data.ifblock.pos - 2;
-                               } else {
-                                       if_jumped = 0;
-                               }
-                       }
-                       OBJ(endif) {
-                               if_jumped = 0;
-                       }
-#ifdef HAVE_POPEN
-                       OBJ(addr) {
-                               snprintf(p, n, "%u.%u.%u.%u",
-                                        obj->data.net->addr.
-                                        sa_data[2] & 255,
-                                        obj->data.net->addr.
-                                        sa_data[3] & 255,
-                                        obj->data.net->addr.
-                                        sa_data[4] & 255,
-                                        obj->data.net->addr.
-                                        sa_data[5] & 255);
-
-                       }
-                       OBJ(linkstatus) {
-                               snprintf(p, n, "%d",
-                                        obj->data.net->linkstatus);
-                       }
-
-                       OBJ(exec) {
-                               char *p2 = p;
-                               FILE *fp = popen(obj->data.s, "r");
-                               int n2 = fread(p, 1, n, fp);
-                               (void) pclose(fp);
-
-                               p[n2] = '\0';
-                               if (n2 && p[n2 - 1] == '\n')
-                                       p[n2 - 1] = '\0';
-
-                               while (*p2) {
-                                       if (*p2 == '\001')
-                                               *p2 = ' ';
-                                       p2++;
-                               }
-                       }
-                       OBJ(execbar) {
-                               char *p2 = p;
-                               FILE *fp = popen(obj->data.s, "r");
-                               int n2 = fread(p, 1, n, fp);
-                               (void) pclose(fp);
-
-                               p[n2] = '\0';
-                               if (n2 && p[n2 - 1] == '\n')
-                                       p[n2 - 1] = '\0';
-
-                               while (*p2) {
-                                       if (*p2 == '\001')
-                                               *p2 = ' ';
-                                       p2++;
-                               }
-                               double barnum;
-                               if (sscanf(p, "%lf", &barnum) == 0) {
-                                       ERR("reading execbar value failed (perhaps it's not the correct format?)");
-                               }
-                               if (barnum > 100 || barnum < 0) {
-                                       ERR("your execbar value is not between 0 and 100, therefore it will be ignored");
-                               } else {
-                                       barnum = barnum / 100.0;
-                                       new_bar(p, 0,
-                                               4, (int) (barnum * 255.0));
-                               }
-
-                       }
-                       OBJ(execgraph) {
-                               char *p2 = p;
-                               FILE *fp = popen(obj->data.s, "r");
-                               int n2 = fread(p, 1, n, fp);
-                               (void) pclose(fp);
-
-                               p[n2] = '\0';
-                               if (n2 && p[n2 - 1] == '\n')
-                                       p[n2 - 1] = '\0';
-
-                               while (*p2) {
-                                       if (*p2 == '\001')
-                                               *p2 = ' ';
-                                       p2++;
-                               }
-                               double barnum;
-                               if (sscanf(p, "%lf", &barnum) == 0) {
-                                       ERR("reading execgraph value failed (perhaps it's not the correct format?)");
-                               }
-                               if (barnum > 100 || barnum < 0) {
-                                       ERR("your execgraph value is not between 0 and 100, therefore it will be ignored");
-                               } else {
-                                       new_graph(p, 0,
-                                       25, obj->c, obj->d, (int) (barnum), 0);
-                               }
-
-                       }
-                       OBJ(execi) {
-                               if (current_update_time -
-                                   obj->data.execi.last_update <
-                                   obj->data.execi.interval) {
-                                       snprintf(p, n, "%s",
-                                                obj->data.execi.buffer);
-                               } else {
-                                       char *p2 = obj->data.execi.buffer;
-                                       FILE *fp =
-                                           popen(obj->data.execi.cmd,
-                                                 "r");
-                                       int n2 =
-                                           fread(p2, 1, TEXT_BUFFER_SIZE,
-                                                 fp);
-                                       (void) pclose(fp);
-
-                                       p2[n2] = '\0';
-                                       if (n2 && p2[n2 - 1] == '\n')
-                                               p2[n2 - 1] = '\0';
-
-                                       while (*p2) {
-                                               if (*p2 == '\001')
-                                                       *p2 = ' ';
-                                               p2++;
-                                       }
-
-                                       snprintf(p, n, "%s",
-                                                obj->data.execi.buffer);
-
-                                       obj->data.execi.last_update =
-                                           current_update_time;
-                               }
-                       }
-#endif
-                       OBJ(fs_bar) {
-                               if (obj->data.fs != NULL) {
-                                       if (obj->data.fs->size == 0)
-                                               new_bar(p,
-                                                       obj->data.fsbar.w,
-                                                       obj->data.fsbar.h,
-                                                       255);
-                                       else
-                                               new_bar(p,
-                                                       obj->data.fsbar.w,
-                                                       obj->data.fsbar.h,
-                                                       (int) (255 -
-                                                              obj->data.
-                                                              fsbar.fs->
-                                                              avail *
-                                                              255 /
-                                                              obj->data.
-                                                              fs->size));
-                               }
-                       }
-                       OBJ(fs_free) {
-                               if (obj->data.fs != NULL)
-                                       human_readable(obj->data.fs->avail,
-                                                      p, 255);
-                       }
-                       OBJ(fs_free_perc) {
-                               if (obj->data.fs != NULL) {
-                                       if (obj->data.fs->size)
-                                               snprintf(p, n, "%*d",
-                                                        pad_percents,
-                                                        (int) ((obj->data.
-                                                                fs->
-                                                                avail *
-                                                                100) /
-                                                               obj->data.
-                                                               fs->size));
-                                       else
-                                               snprintf(p, n, "0");
-                               }
-                       }
-                       OBJ(fs_size) {
-                               if (obj->data.fs != NULL)
-                                       human_readable(obj->data.fs->size,
-                                                      p, 255);
-                       }
-                       OBJ(fs_used) {
-                               if (obj->data.fs != NULL)
-                                       human_readable(obj->data.fs->size -
-                                                      obj->data.fs->avail,
-                                                      p, 255);
-                       }
-                       OBJ(fs_bar_free) {
-                               if (obj->data.fs != NULL) {
-                                       if (obj->data.fs->size == 0)
-                                               new_bar(p,
-                                                       obj->data.fsbar.w,
-                                                       obj->data.fsbar.h,
-                                                       255);
-                                       else
-                                               new_bar(p,
-                                                       obj->data.fsbar.w,
-                                                       obj->data.fsbar.h,
-                                                       (int) (obj->data.
-                                                              fsbar.fs->
-                                                              avail *
-                                                              255 /
-                                                              obj->data.
-                                                              fs->size));
-                               }
-                       }
-                       OBJ(fs_used_perc) {
-                               if (obj->data.fs != NULL) {
-                                       if (obj->data.fs->size)
-                                               snprintf(p, 4, "%d",
-                                                        100 - ((int)
-                                                               ((obj->
-                                                                 data.fs->
-                                                                 avail *
-                                                                 100) /
-                                                                obj->data.
-                                                                fs->
-                                                                size)));
-                                       else
-                                               snprintf(p, n, "0");
-                               }
-                       }
-                       OBJ(loadavg) {
-                               float *v = info.loadavg;
-
-                               if (obj->data.loadavg[2])
-                                       snprintf(p, n, "%.2f %.2f %.2f",
-                                                v[obj->data.loadavg[0] -
-                                                  1],
-                                                v[obj->data.loadavg[1] -
-                                                  1],
-                                                v[obj->data.loadavg[2] -
-                                                  1]);
-                               else if (obj->data.loadavg[1])
-                                       snprintf(p, n, "%.2f %.2f",
-                                                v[obj->data.loadavg[0] -
-                                                  1],
-                                                v[obj->data.loadavg[1] -
-                                                  1]);
-                               else if (obj->data.loadavg[0])
-                                       snprintf(p, n, "%.2f",
-                                                v[obj->data.loadavg[0] -
-                                                  1]);
-                       }
-                       OBJ(hr) {
-                               new_hr(p, obj->data.i);
-                       }
-                       OBJ(offset) {
-                               new_offset(p, obj->data.i);
-                       }
-                       OBJ(voffset) {
-                               new_voffset(p, obj->data.i);
-                       }
-                       OBJ(i2c) {
-                               double r;
-
-                               r = get_i2c_info(&obj->data.i2c.fd,
-                                                obj->data.i2c.arg,
-                                                obj->data.i2c.devtype,
-                                                obj->data.i2c.type);
-
-                               if (r >= 100.0 || r == 0)
-                                       snprintf(p, n, "%d", (int) r);
-                               else
-                                       snprintf(p, n, "%.1f", r);
-                       }
-                       OBJ(alignr) {
-                               new_alignr(p, obj->data.i);
-                       }
-                       OBJ(alignc) {
-                               new_alignc(p, obj->data.i);
-                       }
-                       OBJ(if_existing) {
-                               struct stat tmp;
-                               if ((obj->data.ifblock.s)
-                                   && (stat(obj->data.ifblock.s, &tmp) ==
-                                       -1)) {
-                                       i = obj->data.ifblock.pos - 2;
-                                       if_jumped = 1;
-                               } else
-                                       if_jumped = 0;
-                       }
-                       OBJ(if_mounted) {
-                               if ((obj->data.ifblock.s)
-                                   && (!check_mount(obj->data.ifblock.s))) {
-                                       i = obj->data.ifblock.pos - 2;
-                                       if_jumped = 1;
-                               } else
-                                       if_jumped = 0;
-                       }
-                       OBJ(if_running) {
-                               if ((obj->data.ifblock.s)
-                                   && system(obj->data.ifblock.s)) {
-                                       i = obj->data.ifblock.pos - 2;
-                                       if_jumped = 1;
-                               } else
-                                       if_jumped = 0;
-                       }
-                       OBJ(kernel) {
-                               snprintf(p, n, "%s", cur->uname_s.release);
-                       }
-                       OBJ(machine) {
-                               snprintf(p, n, "%s", cur->uname_s.machine);
-                       }
-
-                       /* memory stuff */
-                       OBJ(mem) {
-                               human_readable(cur->mem * 1024, p, 6);
-                       }
-                       OBJ(memmax) {
-                               human_readable(cur->memmax * 1024, p, 255);
-                       }
-                       OBJ(memperc) {
-                               if (cur->memmax) {
-                                       if (!use_spacer)
-                                               snprintf(p, n, "%*d",
-                                                        pad_percents,
-                                                        (cur->mem * 100) /
-                                                        (cur->memmax));
-                                       else
-                                               snprintf(p, 4, "%*d   ",
-                                                        pad_percents,
-                                                        (cur->mem * 100) /
-                                                        (cur->memmax));
-                               }
-                       }
-                       OBJ(membar) {
-                               new_bar(p, obj->data.pair.a,
-                                       obj->data.pair.b,
-                                       cur->memmax ? (cur->mem * 255) /
-                                       (cur->memmax) : 0);
-                       }
-
-                       OBJ(memgraph) {
-                               new_graph(p, obj->a,
-                               obj->b, obj->c, obj->d,
-                               cur->memmax ? (cur->mem * 100.0) /
-                                               (cur->memmax) : 0.0, 0);
-                       }
-                       /* mixer stuff */
-                       OBJ(mixer) {
-                               snprintf(p, n, "%d",
-                                        mixer_get_avg(obj->data.l));
-                       }
-                       OBJ(mixerl) {
-                               snprintf(p, n, "%d",
-                                        mixer_get_left(obj->data.l));
-                       }
-                       OBJ(mixerr) {
-                               snprintf(p, n, "%d",
-                                        mixer_get_right(obj->data.l));
-                       }
-                       OBJ(mixerbar) {
-                               new_bar(p, obj->data.mixerbar.w,
-                                       obj->data.mixerbar.h,
-                                       mixer_get_avg(obj->data.mixerbar.
-                                                     l) * 255 / 100);
-                       }
-                       OBJ(mixerlbar) {
-                               new_bar(p, obj->data.mixerbar.w,
-                                       obj->data.mixerbar.h,
-                                       mixer_get_left(obj->data.mixerbar.
-                                                      l) * 255 / 100);
-                       }
-                       OBJ(mixerrbar) {
-                               new_bar(p, obj->data.mixerbar.w,
-                                       obj->data.mixerbar.h,
-                                       mixer_get_right(obj->data.mixerbar.
-                                                       l) * 255 / 100);
-                       }
-
-                       /* mail stuff */
-                       OBJ(mails) {
-                               snprintf(p, n, "%d", cur->mail_count);
-                       }
-                       OBJ(new_mails) {
-                               snprintf(p, n, "%d", cur->new_mail_count);
-                       }
-#ifdef MLDONKEY
-                       OBJ(ml_upload_counter) {
-                               snprintf(p, n, "%lld",
-                                        mlinfo.upload_counter / 1048576);
-                       }
-                       OBJ(ml_download_counter) {
-                               snprintf(p, n, "%lld",
-                                        mlinfo.download_counter /
-                                        1048576);
-                       }
-                       OBJ(ml_nshared_files) {
-                               snprintf(p, n, "%i", mlinfo.nshared_files);
-                       }
-                       OBJ(ml_shared_counter) {
-                               snprintf(p, n, "%lld",
-                                        mlinfo.shared_counter / 1048576);
-                       }
-                       OBJ(ml_tcp_upload_rate) {
-                               snprintf(p, n, "%.2f",
-                                        (float) mlinfo.tcp_upload_rate /
-                                        1024);
-                       }
-                       OBJ(ml_tcp_download_rate) {
-                               snprintf(p, n, "%.2f",
-                                        (float) mlinfo.tcp_download_rate /
-                                        1024);
-                       }
-                       OBJ(ml_udp_upload_rate) {
-                               snprintf(p, n, "%.2f",
-                                        (float) mlinfo.udp_upload_rate /
-                                        1024);
-                       }
-                       OBJ(ml_udp_download_rate) {
-                               snprintf(p, n, "%.2f",
-                                        (float) mlinfo.udp_download_rate /
-                                        1024);
-                       }
-                       OBJ(ml_ndownloaded_files) {
-                               snprintf(p, n, "%i",
-                                        mlinfo.ndownloaded_files);
-                       }
-                       OBJ(ml_ndownloading_files) {
-                               snprintf(p, n, "%i",
-                                        mlinfo.ndownloading_files);
-                       }
-#endif
-
-                       OBJ(nodename) {
-                               snprintf(p, n, "%s",
-                                        cur->uname_s.nodename);
-                       }
-                       OBJ(outlinecolor) {
-                               new_outline(p, obj->data.l);
-                       }
-                       OBJ(processes) {
-                               if (!use_spacer)
-                                       snprintf(p, n, "%d", cur->procs);
-                               else
-                                       snprintf(p, 5, "%d    ",
-                                                cur->procs);
-                       }
-                       OBJ(running_processes) {
-                               if (!use_spacer)
-                                       snprintf(p, n, "%d",
-                                                cur->run_procs);
-                               else
-                                       snprintf(p, 3, "%d     ",
-                                                cur->run_procs);
-                       }
-                       OBJ(text) {
-                               snprintf(p, n, "%s", obj->data.s);
-                       }
-                       OBJ(shadecolor) {
-                               new_bg(p, obj->data.l);
-                       }
-                       OBJ(stippled_hr) {
-                               new_stippled_hr(p, obj->data.pair.a,
-                                               obj->data.pair.b);
-                       }
-                       OBJ(swap) {
-                               human_readable(cur->swap * 1024, p, 255);
-                       }
-                       OBJ(swapmax) {
-                               human_readable(cur->swapmax * 1024, p,
-                                              255);
-                       }
-                       OBJ(swapperc) {
-                               if (cur->swapmax == 0) {
-                                       strncpy(p, "No swap", 255);
-                               } else {
-                                       if (!use_spacer)
-                                               snprintf(p, 255, "%*u",
-                                                        pad_percents,
-                                                        (cur->swap *
-                                                         100) /
-                                                        cur->swapmax);
-                                       else
-                                               snprintf(p, 4, "%*u   ",
-                                                        pad_percents,
-                                                        (cur->swap *
-                                                         100) /
-                                                        cur->swapmax);
-                               }
-                       }
-                       OBJ(swapbar) {
-                               new_bar(p, obj->data.pair.a,
-                                       obj->data.pair.b,
-                                       cur->swapmax ? (cur->swap * 255) /
-                                       (cur->swapmax) : 0);
-                       }
-                       OBJ(sysname) {
-                               snprintf(p, n, "%s", cur->uname_s.sysname);
-                       }
-                       OBJ(time) {
-                               time_t t = time(NULL);
-                               struct tm *tm = localtime(&t);
-                               setlocale(LC_TIME, "");
-                               strftime(p, n, obj->data.s, tm);
-                       }
-                       OBJ(utime) {
-                               time_t t = time(NULL);
-                               struct tm *tm = gmtime(&t);
-                               strftime(p, n, obj->data.s, tm);
-                       }
-                       OBJ(totaldown) {
-                               human_readable(obj->data.net->recv, p,
-                                              255);
-                       }
-                       OBJ(totalup) {
-                               human_readable(obj->data.net->trans, p,
-                                              255);
-                       }
-                       OBJ(updates) {
-                               snprintf(p, n, "%d", total_updates);
-                       }
-                       OBJ(upspeed) {
-                               if (!use_spacer)
-                                       snprintf(p, n, "%d",
-                                                (int) (obj->data.net->
-                                                       trans_speed /
-                                                       1024));
-                               else
-                                       snprintf(p, 5, "%d     ",
-                                                (int) (obj->data.net->
-                                                       trans_speed /
-                                                       1024));
-                       }
-                       OBJ(upspeedf) {
-                               if (!use_spacer)
-                                       snprintf(p, n, "%.1f",
-                                                obj->data.net->
-                                                trans_speed / 1024.0);
-                               else
-                                       snprintf(p, 8, "%.1f       ",
-                                                obj->data.net->
-                                                trans_speed / 1024.0);
-                       }
-                       OBJ(upspeedgraph) {
-                               if (obj->data.net->trans_speed == 0)    // this is just to make the ugliness at start go away
-                                       obj->data.net->trans_speed = 0.01;
-                               new_graph(p, obj->a, obj->b, obj->c, obj->d,
-                                         (obj->data.net->trans_speed /
-                               1024.0), 1);
-                       }
-                       OBJ(uptime_short) {
-                               format_seconds_short(p, n,
-                                                    (int) cur->uptime);
-                       }
-                       OBJ(uptime) {
-                               format_seconds(p, n, (int) cur->uptime);
-                       }
-
-#ifdef SETI
-                       OBJ(seti_prog) {
-                               snprintf(p, n, "%.2f",
-                                        cur->seti_prog * 100.0f);
-                       }
-                       OBJ(seti_progbar) {
-                               new_bar(p, obj->data.pair.a,
-                                       obj->data.pair.b,
-                                       (int) (cur->seti_prog * 255.0f));
-                       }
-                       OBJ(seti_credit) {
-                               snprintf(p, n, "%.0f", cur->seti_credit);
-                       }
-#endif
-
-#ifdef MPD
-                       OBJ(mpd_title) {
-                               snprintf(p, n, "%s", cur->mpd.title);
-                       }
-                       OBJ(mpd_artist) {
-                               snprintf(p, n, "%s", cur->mpd.artist);
-                       }
-                       OBJ(mpd_album) {
-                               snprintf(p, n, "%s", cur->mpd.album);
-                       }
-                       OBJ(mpd_vol) {
-                               snprintf(p, n, "%i", cur->mpd.volume);
-                       }
-                       OBJ(mpd_bitrate) {
-                               snprintf(p, n, "%i", cur->mpd.bitrate);
-                       }
-                       OBJ(mpd_status) {
-                               snprintf(p, n, "%s", cur->mpd.status);
-                       }
-                       OBJ(mpd_elapsed) {
-                               int days = 0, hours = 0, minutes =
-                                   0, seconds = 0;
-                               int tmp = cur->mpd.elapsed;
-                               while (tmp >= 86400) {
-                                       tmp -= 86400;
-                                       days++;
-                               }
-                               while (tmp >= 3600) {
-                                       tmp -= 3600;
-                                       hours++;
-                               }
-                               while (tmp >= 60) {
-                                       tmp -= 60;
-                                       minutes++;
-                               }
-                               seconds = tmp;
-                               if (days > 0)
-                                       snprintf(p, n, "%i days %i:%i:%2i",
-                                                days, hours, minutes,
-                                                seconds);
-                               else if (days > 0)
-                                       snprintf(p, n, "%i:%i:%02i", hours,
-                                                minutes, seconds);
-                               else
-                                       snprintf(p, n, "%i:%02i", minutes,
-                                                seconds);
-                       }
-                       OBJ(mpd_length) {
-                               int days = 0, hours = 0, minutes =
-                                   0, seconds = 0;
-                               int tmp = cur->mpd.length;
-                               while (tmp >= 86400) {
-                                       tmp -= 86400;
-                                       days++;
-                               }
-                               while (tmp >= 3600) {
-                                       tmp -= 3600;
-                                       hours++;
-                               }
-                               while (tmp >= 60) {
-                                       tmp -= 60;
-                                       minutes++;
-                               }
-                               seconds = tmp;
-                               if (days > 0)
-                                       snprintf(p, n,
-                                                "%i days %i:%i:%02i",
-                                                days, hours, minutes,
-                                                seconds);
-                               else if (days > 0)
-                                       snprintf(p, n, "%i:%i:%02i", hours,
-                                                minutes, seconds);
-                               else
-                                       snprintf(p, n, "%i:%02i", minutes,
-                                                seconds);
-                       }
-                       OBJ(mpd_percent) {
-                               snprintf(p, n, "%2.0f",
-                                        cur->mpd.progress * 100);
-                       }
-                       OBJ(mpd_bar) {
-                               new_bar(p, obj->data.pair.a,
-                                       obj->data.pair.b,
-                                       (int) (cur->mpd.progress *
-                                              255.0f));
-                       }
-#endif
-                       OBJ(top) {
-                               if (obj->data.top.type == TOP_NAME
-                                   && obj->data.top.num >= 0
-                                   && obj->data.top.num < 10) {
-                                       // if we limit the buffer and add a bunch of space after, it stops the thing from
-                                       // moving other shit around, which is really fucking annoying
-                                       snprintf(p, 17,
-                                                "%s                              ",
-                                                cur->cpu[obj->data.top.
-                                                         num]->name);
-                               } else if (obj->data.top.type == TOP_CPU
-                                          && obj->data.top.num >= 0
-                                          && obj->data.top.num < 10) {
-                                       snprintf(p, 7, "%3.2f      ",
-                                                cur->cpu[obj->data.top.
-                                                         num]->amount);
-                               } else if (obj->data.top.type == TOP_PID
-                                          && obj->data.top.num >= 0
-                                          && obj->data.top.num < 10) {
-                                       snprintf(p, 8, "%i           ",
-                                                cur->cpu[obj->data.top.
-                                                         num]->pid);
-                               } else if (obj->data.top.type == TOP_MEM
-                                          && obj->data.top.num >= 0
-                                          && obj->data.top.num < 10) {
-                                       snprintf(p, 7, "%3.2f       ",
-                                                cur->cpu[obj->data.top.
-                                                         num]->totalmem);
-                               }
-                       }
-                       OBJ(top_mem) {
-                               if (obj->data.top.type == TOP_NAME
-                                   && obj->data.top.num >= 0
-                                   && obj->data.top.num < 10) {
-                                       // if we limit the buffer and add a bunch of space after, it stops the thing from
-                                       // moving other shit around, which is really fucking annoying
-                                       snprintf(p, 17,
-                                                "%s                              ",
-                                                cur->memu[obj->data.top.
-                                                          num]->name);
-                               } else if (obj->data.top.type == TOP_CPU
-                                          && obj->data.top.num >= 0
-                                          && obj->data.top.num < 10) {
-                                       snprintf(p, 7, "%3.2f      ",
-                                                cur->memu[obj->data.top.
-                                                          num]->amount);
-                               } else if (obj->data.top.type == TOP_PID
-                                          && obj->data.top.num >= 0
-                                          && obj->data.top.num < 10) {
-                                       snprintf(p, 8, "%i           ",
-                                                cur->memu[obj->data.top.
-                                                          num]->pid);
-                               } else if (obj->data.top.type == TOP_MEM
-                                          && obj->data.top.num >= 0
-                                          && obj->data.top.num < 10) {
-                                       snprintf(p, 7, "%3.2f       ",
-                                                cur->memu[obj->data.top.
-                                                          num]->totalmem);
-                               }
-                       }
-
-
-
-                       /*
-                        * I'm tired of everything being packed in
-                        * pee
-                        * poop
-                        */
-
-
-                       OBJ(tail) {
-                               if (current_update_time -obj->data.tail.last_update < obj->data.tail.interval) {
-                                       snprintf(p, n, "%s", obj->data.tail.buffer);
-                               } else {
-                                       obj->data.tail.last_update = current_update_time;
-                                       FILE *fp;
-                                       int i;
-                                       int added = 0;
-                                       tailstring *head = NULL;
-                                       tailstring *headtmp = NULL;
-                                       fp = fopen(obj->data.tail.logfile, "rt");
-                                       if (fp == NULL) {
-                                               ERR("tail logfile failed to open");
-                                       }
-                                       else {
-                                               obj->data.tail.readlines = 0;
-
-                                               while (fgets(obj->data.tail.buffer, TEXT_BUFFER_SIZE*4, fp) != NULL) {
-                                                       if (added >= 30) {
-                                                               freelasttail(head);
-                                                       }
-                                                       else {
-                                                               added++;
-                                                       }
-                                                       addtail(&head, obj->data.tail.buffer);
-                                                       obj->data.tail.readlines++;
-                                               }
-
-                                               fclose(fp);
-
-                                               if (obj->data.tail.readlines > 0) {
-                                                       for (i = 0;i < obj->data.tail.wantedlines + 1 && i < obj->data.tail.readlines; i++) {
-                                                               addtail(&headtmp, head->data);
-                                                               head = head->next;
-                                                       }
-                                                       strcpy(obj->data.tail.buffer, headtmp->data);
-                                                       headtmp = headtmp->next;
-                                                       for (i = 1;i < obj->data.tail.wantedlines + 1 && i < obj->data.tail.readlines; i++) {
-                                                               if (headtmp) {
-                                                                       strncat(obj->data.tail.buffer, headtmp->data, (TEXT_BUFFER_SIZE * 6 / obj->data.tail.wantedlines) - strlen(obj->data.tail.buffer)); /* without strlen() at the end this becomes a possible */
-                                                                       headtmp = headtmp->next;
-                                                               }
-                                                       }
-
-                                                       /* get rid of any ugly newlines at the end */
-                                                       if (obj->data.tail.buffer[strlen(obj->data.tail.buffer)-1] == '\n') {
-                                                               obj->data.tail.buffer[strlen(obj->data.tail.buffer)-1] = '\0';
-                                                       }
-                                                       snprintf(p, n, "%s", obj->data.tail.buffer);
-
-                                                       freetail(headtmp);
-                                               }
-                                               else {
-                                                       strcpy(obj->data.tail.buffer, "Logfile Empty");
-                                                       snprintf(p, n, "Logfile Empty");
-                                               }
-                                               freetail(head);
-                                       }
-                               }
-                       }
-
-
-
-                       break;
-               }
-
-               {
-                       unsigned int a = strlen(p);
-                       p += a;
-                       n -= a;
-               }
-       }
-
-       if (stuff_in_upper_case) {
-               char *p;
-
-               p = text_buffer;
-               while (*p) {
-                       *p = toupper(*p);
-                       p++;
-               }
-       }
-
-       last_update_time = current_update_time;
-       total_updates++;
-       //free(p);
-}
-
-#ifdef X11
-static void set_font()
-{
-#ifdef XFT
-       if (use_xft) {
-                       if (window.xftdraw != NULL)
-                               XftDrawDestroy(window.xftdraw);
-                       window.xftdraw = XftDrawCreate(display, window.drawable,
-                                       DefaultVisual(display,
-                                                       screen),
-                                       DefaultColormap(display,
-                                                       screen));
-               } else
-#endif
-{
-       XSetFont(display, window.gc, fonts[selected_font].font->fid);
-}
-}
-
-
-/*
- * text size
- */
-
-static int text_start_x, text_start_y; /* text start position in window */
-static int text_width, text_height;
-
-#endif /* X11 */
-
-static inline int get_string_width(const char *s)
-{
-#ifdef X11
-       return *s ? calc_text_width(s, strlen(s)) : 0;
-#else
-       return strlen(s);
-#endif /* X11 */
-}
-
-int fontchange = 0;
-
-#ifdef X11
-static void text_size_updater(char *s)
-{
-       int w = 0;
-       char *p;
-       int h = font_height();
-       /* get string widths and skip specials */
-       p = s;
-       while (*p) {
-               if (*p == SPECIAL_CHAR) {
-                       *p = '\0';
-                       w += get_string_width(s);
-                       *p = SPECIAL_CHAR;
-
-                       if (specials[special_index].type == BAR
-                           || specials[special_index].type == GRAPH) {
-                               w += specials[special_index].width;
-                               if (specials[special_index].height > h) {
-                                       h = specials[special_index].height;
-                                       h += font_ascent();
-                               }
-                       }
-                       
-                       else if (specials[special_index].type == OFFSET) {
-                               w += specials[special_index].arg + get_string_width("a"); /* filthy, but works */
-                       }
-                       else if (specials[special_index].type == VOFFSET) {
-                               h += specials[special_index].arg;
-                       }
-                       else if (specials[special_index].type == FONT) {
-                               fontchange = specials[special_index].font_added;
-                               selected_font = specials[special_index].font_added;
-                               h = font_height();
-                       }
-
-                       
-                       special_index++;
-                       s = p + 1;
-               }
-               p++;
-       }
-               w += get_string_width(s);
-       if (w > text_width)
-               text_width = w;
-
-       text_height += h;
-       if (fontchange) {
-               selected_font = 0;
-       }
-}
-#endif /* X11 */
-
-
-#ifdef X11
-static void update_text_area()
-{
-       int x, y;
-
-       /* update text size if it isn't fixed */
-#ifdef OWN_WINDOW
-       if (!fixed_size)
-#endif
-       {
-               text_width = minimum_width;
-               text_height = 0;
-               special_index = 0;
-               for_each_line(text_buffer, text_size_updater);
-               text_width += 1;
-               if (text_height < minimum_height)
-                       text_height = minimum_height;
-       }
-
-       /* get text position on workarea */
-       switch (text_alignment) {
-       case TOP_LEFT:
-               x = gap_x;
-               y = gap_y;
-               break;
-
-       case TOP_RIGHT:
-               x = workarea[2] - text_width - gap_x;
-               y = gap_y;
-               break;
-
-       default:
-       case BOTTOM_LEFT:
-               x = gap_x;
-               y = workarea[3] - text_height - gap_y;
-               break;
-
-       case BOTTOM_RIGHT:
-               x = workarea[2] - text_width - gap_x;
-               y = workarea[3] - text_height - gap_y;
-               break;
-       
-#ifdef OWN_WINDOW
-       case NONE: // Let the WM manage the window
-               x = window.x;
-               y = window.y;
-
-               fixed_pos  = 1;
-               fixed_size = 1;
-               break;
-#endif
-       }
-#ifdef OWN_WINDOW
-
-       if (own_window && !fixed_pos) {
-               x += workarea[0];
-               y += workarea[1];
-               text_start_x = border_margin + 1;
-               text_start_y = border_margin + 1;
-               window.x = x - border_margin - 1;
-               window.y = y - border_margin - 1;
-       } else
-#endif
-       {
-               /* If window size doesn't match to workarea's size, then window
-                * probably includes panels (gnome).
-                * Blah, doesn't work on KDE. */
-               if (workarea[2] != window.width
-                   || workarea[3] != window.height) {
-                       y += workarea[1];
-                       x += workarea[0];
-               }
-
-               text_start_x = x;
-               text_start_y = y;
-       }
-}
-
-/*
- * drawing stuff
- */
-
-static int cur_x, cur_y;       /* current x and y for drawing */
-static int draw_mode;          /* FG, BG or OUTLINE */
-static long current_color;
-
-static inline void set_foreground_color(long c)
-{
-       current_color = c;
-       XSetForeground(display, window.gc, c);
-}
-#endif /* X11 */
-
-static void draw_string(const char *s)
-{
-       if (s[0] == '\0')
-               return;
-       int i, i2, pos, width_of_s;
-       int max=0;
-       int added;
-       width_of_s = get_string_width(s);
-       if (out_to_console) {
-               printf("%s\n", s);
-       }
-       /* daemon_run(s);  the daemon can be called here, but we need to have a buffer in daemon_run() and we need to tell it when everything is ready to be sent */
-       strcpy(tmpstring1, s);
-       pos = 0;
-       added = 0;
-       char space[2];
-       snprintf(space, 2, " ");
-#ifdef X11
-       max = ((text_width - width_of_s) / get_string_width(space));
-#endif /* X11 */
-       /*
-        * This code looks for tabs in the text and coverts them to spaces.
-        * The trick is getting the correct number of spaces,
-        * and not going over the window's size without forcing
-        * the window larger.
-        */
-       for (i = 0; i < TEXT_BUFFER_SIZE; i++) {
-               if (tmpstring1[i] == '\t')      // 9 is ascii tab
-               {
-                       i2 = 0;
-                       for (i2 = 0;
-                            i2 < (8 - (1 + pos) % 8) && added <= max;
-                            i2++) {
-                               tmpstring2[pos + i2] = ' ';
-                               added++;
-                       }
-                       pos += i2;
-               } else {
-                       if (tmpstring1[i] != 9) {
-                               tmpstring2[pos] = tmpstring1[i];
-                               pos++;
-                       }
-               }
-       }
-       s = tmpstring2;
-#ifdef X11
-#ifdef XFT
-       if (use_xft) {
-               XColor c;
-               XftColor c2;
-               c.pixel = current_color;
-               XQueryColor(display, DefaultColormap(display, screen), &c);
-
-               c2.pixel = c.pixel;
-               c2.color.red = c.red;
-               c2.color.green = c.green;
-               c2.color.blue = c.blue;
-               c2.color.alpha = fonts[selected_font].font_alpha;
-               if (utf8_mode) {
-                       XftDrawStringUtf8(window.xftdraw, &c2, fonts[selected_font].xftfont,
-                                         cur_x, cur_y, (XftChar8 *) s,
-                                         strlen(s));
-               } else {
-                       XftDrawString8(window.xftdraw, &c2, fonts[selected_font].xftfont,
-                                      cur_x, cur_y, (XftChar8 *) s,
-                                      strlen(s));
-               }
-       } else
-#endif
-       {
-               XDrawString(display, window.drawable, window.gc,
-                           cur_x, cur_y, s, strlen(s));
-       }
-       cur_x += width_of_s;
-#endif /* X11 */
-       memcpy(tmpstring1, s, TEXT_BUFFER_SIZE);
-}
-
-long redmask, greenmask, bluemask;
-short colour_depth = 0;
-
-void set_up_gradient()
-{
-       colour_depth = DisplayPlanes(display, screen);
-       if (colour_depth != 24 && colour_depth != 16) {
-               ERR("using non-standard colour depth, gradients may look like a lolly-pop");
-       }
-       int i;
-       redmask = 0;
-       greenmask = 0;
-       bluemask = 0;
-       for(i = (colour_depth / 3)-1; i>=0; i--) {
-               redmask |= 1 << i;
-               greenmask |= 1 << i;
-               bluemask |= 1 << i;
-       }
-       if (colour_depth%3 == 1) {
-               greenmask |= 1 << (colour_depth / 3);
-       }
-       redmask = redmask << (2*colour_depth / 3 + colour_depth%3);
-       greenmask = greenmask << (colour_depth / 3);
-}
-
-inline unsigned long do_gradient(unsigned long first_colour, unsigned long last_colour) { /* this function returns the next colour between two colours for a gradient */
-       int tmp_color = 0;
-       int red1, green1, blue1; // first colour
-       int red2, green2, blue2; // second colour
-       int red3 = 0, green3 = 0, blue3 = 0; // difference
-       short redshift = (2*colour_depth / 3 + colour_depth%3);
-       short greenshift = (colour_depth / 3);
-       red1 = (first_colour & redmask) >> redshift;
-       green1 = (first_colour & greenmask) >> greenshift;
-       blue1 = first_colour & bluemask;
-       red2 = (last_colour & redmask) >> redshift;
-       green2 = (last_colour & greenmask) >> greenshift;
-       blue2 = last_colour & bluemask;
-       if (red1 > red2) {
-               red3 = -1;
-       }
-       if (red1 < red2) {
-               red3 = 1;
-       }
-       if (green1 > green2) {
-               green3 = -1;
-       }
-       if (green1 < green2) {
-               green3 = 1;
-       }
-       if (blue1 > blue2) {
-               blue3 = -1;
-       }
-       if (blue1 < blue2) {
-               blue3 = 1;
-       }
-       red1 += red3;
-       green1 += green3;
-       blue1 += blue3;
-       if (red1 < 0) {
-               red1 = 0;
-       }
-       if (green1 < 0) {
-               green1 = 0;
-       }
-       if (blue1 < 0) {
-               blue1 = 0;
-       }
-       if (red1 > bluemask) {
-               red1 = bluemask;
-       }
-       if (green1 > bluemask) {
-               green1 = bluemask;
-       }
-       if (blue1 > bluemask) {
-               blue1 = bluemask;
-       }
-       tmp_color = (red1 << redshift) | (green1 << greenshift) | blue1;
-       return tmp_color;
-}
-
-inline unsigned long gradient_max(unsigned long first_colour, unsigned long last_colour) { /* this function returns the max diff for a gradient */
-       if (colour_depth == 0) {
-               set_up_gradient();
-       }
-       int red1, green1, blue1; // first colour
-       int red2, green2, blue2; // second colour
-       long redshift = (2*colour_depth / 3 + colour_depth%3);
-       long greenshift = (colour_depth / 3);
-       int red3 = 0, green3 = 0, blue3 = 0; // difference
-       red1 = (first_colour & redmask) >> redshift;
-       green1 = (first_colour & greenmask) >> greenshift;
-       blue1 = first_colour & bluemask;
-       red2 = (last_colour & redmask) >> redshift;
-       green2 = (last_colour & greenmask) >> greenshift;
-       blue2 = last_colour & bluemask;
-       red3 = abs(red1 - red2);
-       green3 = abs(green1 - green2);
-       blue3 = abs(blue1 - blue2);
-       int max = red3;
-       if (green3 > max)
-               max = green3;
-       if (blue3 > max)
-               max = blue3;
-       return max;
-}
-
-static void draw_line(char *s)
-{
-#ifdef X11
-       char *p;
-       cur_x = text_start_x;
-       cur_y += font_ascent();
-       int cur_y_add = 0;
-       short font_h = font_height();
-
-       /* find specials and draw stuff */
-       p = s;
-       while (*p) {
-               if (*p == SPECIAL_CHAR) {
-                       int w = 0;
-
-                       /* draw string before special */
-                       *p = '\0';
-                       draw_string(s);
-                       *p = SPECIAL_CHAR;
-                       s = p + 1;
-
-                       /* draw special */
-                       switch (specials[special_index].type) {
-                       case HORIZONTAL_LINE:
-                               {
-                                       int h =
-                                           specials[special_index].height;
-                                       int mid = font_ascent() / 2;
-                                       w = text_start_x + text_width -
-                                           cur_x;
-
-                                       XSetLineAttributes(display,
-                                                          window.gc, h,
-                                                          LineSolid,
-                                                          CapButt,
-                                                          JoinMiter);
-                                       XDrawLine(display, window.drawable,
-                                                 window.gc, cur_x,
-                                                 cur_y - mid / 2,
-                                                 cur_x + w,
-                                                 cur_y - mid / 2);
-                               }
-                               break;
-
-                       case STIPPLED_HR:
-                               {
-                                       int h =
-                                           specials[special_index].height;
-                                       int s =
-                                           specials[special_index].arg;
-                                       int mid = font_ascent() / 2;
-                                       char ss[2] = { s, s };
-                                       w = text_start_x + text_width -
-                                           cur_x - 1;
-
-                                       XSetLineAttributes(display,
-                                                          window.gc, h,
-                                                          LineOnOffDash,
-                                                          CapButt,
-                                                          JoinMiter);
-                                       XSetDashes(display, window.gc, 0,
-                                                  ss, 2);
-                                       XDrawLine(display, window.drawable,
-                                                 window.gc, cur_x,
-                                                 cur_y - mid / 2,
-                                                 cur_x + w,
-                                                 cur_y - mid / 2);
-                               }
-                               break;
-
-                       case BAR:
-                               {
-                                       int h =
-                                           specials[special_index].height;
-                                       int bar_usage =
-                                           specials[special_index].arg;
-                                       int by =
-                                           cur_y - (font_ascent() +
-                                                    h) / 2 - 1;
-                                       w = specials[special_index].width;
-                                       if (w == 0)
-                                               w = text_start_x +
-                                                   text_width - cur_x - 1;
-                                       if (w < 0)
-                                               w = 0;
-
-                                       XSetLineAttributes(display,
-                                                          window.gc, 1,
-                                                          LineSolid,
-                                                          CapButt,
-                                                          JoinMiter);
-
-                                       XDrawRectangle(display,
-                                                      window.drawable,
-                                                      window.gc, cur_x,
-                                                      by, w, h);
-                                       XFillRectangle(display,
-                                                      window.drawable,
-                                                      window.gc, cur_x,
-                                                      by,
-                                                      w * bar_usage / 255,
-                                                      h);
-                                       if (specials[special_index].
-                                           height > cur_y_add
-                                           && specials[special_index].
-                                           height > font_h) {
-                                               cur_y_add =
-                                                   specials
-                                                   [special_index].height;
-                                       }
-                               }
-                               break;
-
-                       case GRAPH:
-                               {
-                                       int h =
-                                           specials[special_index].height;
-                                       int by;
-#ifdef XFT
-                                       if (use_xft) {
-                                           by = cur_y - (font_ascent() +
-                                                    h) / 2 - 1;
-                                       } else
-#endif
-                                       {
-                                               by = cur_y - (font_ascent()/2);
-                                       }
-                                       w = specials[special_index].width;
-                                       if (w == 0)
-                                               w = text_start_x + text_width - cur_x - 1;
-                                       if (w < 0)
-                                               w = 0;
-                                       XSetLineAttributes(display,
-                                                          window.gc, 1,
-                                                          LineSolid,
-                                                          CapButt,
-                                                          JoinMiter);
-                                       XDrawRectangle(display,
-                                                      window.drawable,
-                                                      window.gc, cur_x,
-                                                      by, w, h);
-                                       XSetLineAttributes(display,
-                                                          window.gc, 1,
-                                                          LineSolid,
-                                                          CapButt,
-                                                          JoinMiter);
-       int i;
-       int j = 0;
-       int gradient_size = 0;
-       float gradient_factor = 0;
-       float gradient_update = 0;
-       unsigned long tmpcolour = current_color;
-       if (specials[special_index].first_colour != specials[special_index].last_colour) {
-               tmpcolour = specials[special_index].first_colour;
-               gradient_size = gradient_max(specials[special_index].first_colour, specials[special_index].last_colour);
-               gradient_factor = (float)gradient_size / (w - 3);
-       }
-       for (i = 0; i < w - 3; i++) {
-               if (specials[special_index].first_colour != specials[special_index].last_colour) {
-                       XSetForeground(display, window.gc, tmpcolour);
-                       gradient_update += gradient_factor;
-                       while (gradient_update > 0) {
-                               tmpcolour = do_gradient(tmpcolour, specials[special_index].last_colour);
-                               gradient_update--;
-                       }
-               }
-               if (i / ((float) (w - 3) / (specials[special_index].graph_width)) > j) {
-                       j++;
-                                               }
-                                               XDrawLine(display,  window.drawable, window.gc, cur_x + i + 2, by + h, cur_x + i + 2, by + h - specials[special_index].graph[j] * (h - 1) / specials[special_index].graph_scale);       /* this is mugfugly, but it works */
-       }
-                                       if (specials[special_index].
-                                           height > cur_y_add
-                                           && specials[special_index].
-                                           height > font_h) {
-                                               cur_y_add =
-                                                   specials
-                                                   [special_index].height;
-                                       }
-                               }
-                               if (draw_mode == BG) {
-                                       set_foreground_color(default_bg_color);
-                               }
-                               else if (draw_mode == OUTLINE) {
-                                       set_foreground_color(default_out_color);
-                               } else {
-                                       set_foreground_color(default_fg_color);
-                               }
-                               break;
-                       
-                               case FONT:
-                               if (fontchange) {
-                                       cur_y -= font_ascent();
-                                       selected_font = specials[special_index].font_added;
-                                       cur_y += font_ascent();
-#ifdef XFT
-                                       if (!use_xft)
-#endif
-                                       {
-                                               set_font();
-                                       }
-                               }
-                               break;
-                       case FG:
-                               if (draw_mode == FG)
-                                       set_foreground_color(specials
-                                                            [special_index].
-                                                            arg);
-                               break;
-
-                       case BG:
-                               if (draw_mode == BG)
-                                       set_foreground_color(specials
-                                                            [special_index].
-                                                            arg);
-                               break;
-
-                       case OUTLINE:
-                               if (draw_mode == OUTLINE)
-                                       set_foreground_color(specials
-                                                            [special_index].
-                                                            arg);
-                               break;
-
-                               case OFFSET:
-                               {
-                                       w += specials[special_index].arg;
-                               }
-                               break;
-                               case VOFFSET:
-                               {
-                                       cur_y += specials[special_index].arg;
-                               }
-                               break;
-
-                       case ALIGNR:
-                               {
-                                       int pos_x = text_width + gap_x - get_string_width(p) /*- border_margin*2 - 1*/;
-                                       /*printf("pos_x %i text_start_x %i text_width %i cur_x %i get_string_width(p) %i gap_x %i specials[special_index].arg %i border_margin %i border_width %i\n", pos_x, text_start_x, text_width, cur_x, get_string_width(p), gap_x, specials[special_index].arg, border_margin, border_width);*/
-                                       if (pos_x > specials[special_index].arg && pos_x > cur_x) {
-                                       cur_x = pos_x - specials[special_index].arg;
-                               }
-                               }
-                               break;
-
-                       case ALIGNC:
-                               {
-                                       int pos_x = (text_width)/2 - get_string_width(p)/2 - (cur_x - text_start_x);
-                                       /*printf("pos_x %i text_start_x %i text_width %i cur_x %i get_string_width(p) %i gap_x %i specials[special_index].arg %i\n", pos_x, text_start_x, text_width, cur_x, get_string_width(p), gap_x, specials[special_index].arg);*/
-                                       if (pos_x >
-                                           specials[special_index].arg)
-                                               w = pos_x -
-                                                   specials
-                                                   [special_index].arg;
-                               }
-                               break;
-
-                       }
-
-                       cur_x += w;
-
-                       special_index++;
-               }
-
-               p++;
-       }
-#else
-       draw_string(s);
-#endif
-#ifdef X11
-       if (cur_y_add > 0) {
-               cur_y += cur_y_add;
-               cur_y -= font_descent();
-       }
-
-       draw_string(s);
-
-       cur_y += font_descent();
-       if (fontchange) {
-               selected_font = 0;
-       }
-#endif /* X11 */
-}
-
-static void draw_text()
-{
-#ifdef X11
-       cur_y = text_start_y;
-
-       /* draw borders */
-       if (draw_borders && border_width > 0) {
-               unsigned int b = (border_width + 1) / 2;
-
-               if (stippled_borders) {
-                       char ss[2] =
-                           { stippled_borders, stippled_borders };
-                       XSetLineAttributes(display, window.gc,
-                                          border_width, LineOnOffDash,
-                                          CapButt, JoinMiter);
-                       XSetDashes(display, window.gc, 0, ss, 2);
-               } else {
-                       XSetLineAttributes(display, window.gc,
-                                          border_width, LineSolid,
-                                          CapButt, JoinMiter);
-               }
-
-               XDrawRectangle(display, window.drawable, window.gc,
-                              text_start_x - border_margin + b,
-                              text_start_y - border_margin + b,
-                              text_width + border_margin * 2 - 1 - b * 2,
-                              text_height + border_margin * 2 - 1 -
-                              b * 2);
-       }
-
-       /* draw text */
-       special_index = 0;
-#endif /* X11 */
-       for_each_line(text_buffer, draw_line);
-}
-
-static void draw_stuff()
-{
-#ifdef X11
-       if (draw_shades && !draw_outline) {
-               text_start_x++;
-               text_start_y++;
-               set_foreground_color(default_bg_color);
-               draw_mode = BG;
-               draw_text();
-               text_start_x--;
-               text_start_y--;
-       }
-
-       if (draw_outline) {
-               int i, j;
-               for (i = -1; i < 2; i++)
-                       for (j = -1; j < 2; j++) {
-                               if (i == 0 && j == 0)
-                                       continue;
-                               text_start_x += i;
-                               text_start_y += j;
-                               set_foreground_color(default_out_color);
-                               draw_mode = OUTLINE;
-                               draw_text();
-                               text_start_x -= i;
-                               text_start_y -= j;
-                       }
-       }
-
-       set_foreground_color(default_fg_color);
-       draw_mode = FG;
-#endif /* X11 */
-       draw_text();
-#ifdef X11
-#ifdef XDBE
-       if (use_xdbe) {
-               XdbeSwapInfo swap;
-               swap.swap_window = window.window;
-               swap.swap_action = XdbeBackground;
-               XdbeSwapBuffers(display, &swap, 1);
-       }
-#endif
-#endif /* X11 */
-}
-#ifdef X11
-static void clear_text(int exposures)
-{
-#ifdef XDBE
-       if (use_xdbe)
-               return;         /* The swap action is XdbeBackground, which clears */
-#endif
-       /* there is some extra space for borders and outlines */
-       XClearArea(display, window.drawable,
-                  text_start_x - border_margin - 1,
-                  text_start_y - border_margin - 1,
-                  text_width + border_margin * 2 + 2,
-                  text_height + border_margin * 2 + 2,
-                  exposures ? True : 0);
-}
-#endif /* X11 */
-
-static int need_to_update;
-
-/* update_text() generates new text and clears old text area */
-static void update_text()
-{
-       generate_text();
-#ifdef X11
-       clear_text(1);
-#endif /* X11 */
-       need_to_update = 1;
-}
-
-static void main_loop()
-{
-#ifdef X11
-       Region region = XCreateRegion();
-#endif /* X11 */
-
-       info.looped = 0;
-       while (total_run_times == 0 || info.looped < total_run_times - 1) {
-               info.looped++;
-#ifdef X11
-               XFlush(display);
-
-               /* wait for X event or timeout */
-
-               if (!XPending(display)) {
-                       fd_set fdsr;
-                       struct timeval tv;
-                       int s;
-                       double t =
-                           update_interval - (get_time() -
-                                              last_update_time);
-
-                       if (t < 0)
-                               t = 0;
-
-                       tv.tv_sec = (long) t;
-                       tv.tv_usec = (long) (t * 1000000) % 1000000;
-                       FD_ZERO(&fdsr);
-                       FD_SET(ConnectionNumber(display), &fdsr);
-
-
-                       s = select(ConnectionNumber(display) + 1, &fdsr, 0,
-                                  0, &tv);
-#else
-                       usleep(update_interval*1000000); /* FIXME just sleep for the interval time if no X11 */
-#endif /* X11 */
-#ifdef X11
-                       if (s == -1) {
-                               if (errno != EINTR)
-                                       ERR("can't select(): %s",
-                                           strerror(errno));
-                       } else {
-                               /* timeout */
-                               if (s == 0)
-#endif /* X11 */
-                                       update_text();
-#ifdef X11
-                       }
-               }
-
-               if (need_to_update) {
-#ifdef OWN_WINDOW
-                       int wx = window.x, wy = window.y;
-#endif
-
-                       need_to_update = 0;
-
-                       update_text_area();
-
-#ifdef OWN_WINDOW
-                       if (own_window) {
-                               /* resize window if it isn't right size */
-                               if (!fixed_size &&
-                                   (text_width + border_margin * 2 !=
-                                    window.width
-                                    || text_height + border_margin * 2 !=
-                                    window.height)) {
-                                       window.width =
-                                           text_width +
-                                           border_margin * 2 + 1;
-                                       window.height =
-                                           text_height +
-                                           border_margin * 2 + 1;
-                                       XResizeWindow(display,
-                                                     window.window,
-                                                     window.width,
-                                                     window.height);
-                               }
-
-                               /* move window if it isn't in right position */
-                               if (!fixed_pos
-                                   && (window.x != wx
-                                       || window.y != wy)) {
-                                       XMoveWindow(display, window.window,
-                                                   window.x, window.y);
-                               }
-                       }
-#endif
-
-                       clear_text(1);
-
-#ifdef XDBE
-                       if (use_xdbe) {
-                               XRectangle r;
-                               r.x = text_start_x - border_margin;
-                               r.y = text_start_y - border_margin;
-                               r.width = text_width + border_margin * 2;
-                               r.height = text_height + border_margin * 2;
-                               XUnionRectWithRegion(&r, region, region);
-                       }
-#endif
-               }
-
-               /* handle X events */
-
-               while (XPending(display)) {
-                       XEvent ev;
-                       XNextEvent(display, &ev);
-
-                       switch (ev.type) {
-                       case Expose:
-                               {
-                                       XRectangle r;
-                                       r.x = ev.xexpose.x;
-                                       r.y = ev.xexpose.y;
-                                       r.width = ev.xexpose.width;
-                                       r.height = ev.xexpose.height;
-                                       XUnionRectWithRegion(&r, region,
-                                                            region);
-                               }
-                               break;
-
-#ifdef OWN_WINDOW
-                       case ReparentNotify:
-                               /* set background to ParentRelative for all parents */
-                               if (own_window)
-                                       set_transparent_background(window.
-                                                                  window);
-                               break;
-
-                       case ConfigureNotify:
-                               if (own_window) {
-                                       /* if window size isn't what expected, set fixed size */
-                                       if (ev.xconfigure.width !=
-                                           window.width
-                                           || ev.xconfigure.height !=
-                                           window.height) {
-                                               if (window.width != 0
-                                                   && window.height != 0)
-                                                       fixed_size = 1;
-
-                                               /* clear old stuff before screwing up size and pos */
-                                               clear_text(1);
-
-                                               {
-                                                       XWindowAttributes
-                                                           attrs;
-                                                       if (XGetWindowAttributes(display, window.window, &attrs)) {
-                                                               window.
-                                                                   width =
-                                                                   attrs.
-                                                                   width;
-                                                               window.
-                                                                   height
-                                                                   =
-                                                                   attrs.
-                                                                   height;
-                                                       }
-                                               }
-
-                                               text_width =
-                                                   window.width -
-                                                   border_margin * 2 - 1;
-                                               text_height =
-                                                   window.height -
-                                                   border_margin * 2 - 1;
-                                       }
-
-                                       /* if position isn't what expected, set fixed pos, total_updates
-                                        * avoids setting fixed_pos when window is set to weird locations
-                                        * when started */
-                                       if (total_updates >= 2
-                                           && !fixed_pos
-                                           && (window.x != ev.xconfigure.x
-                                               || window.y !=
-                                               ev.xconfigure.y)
-                                           && (ev.xconfigure.x != 0
-                                               || ev.xconfigure.y != 0)) {
-                                               fixed_pos = 1;
-                                       }
-                               }
-                               break;
-#endif
-
-                       default:
-                               break;
-                       }
-               }
-
-               /* XDBE doesn't seem to provide a way to clear the back buffer without
-                * interfering with the front buffer, other than passing XdbeBackground
-                * to XdbeSwapBuffers. That means that if we're using XDBE, we need to
-                * redraw the text even if it wasn't part of the exposed area. OTOH,
-                * if we're not going to call draw_stuff at all, then no swap happens
-                * and we can safely do nothing.
-                */
-
-               if (!XEmptyRegion(region)) {
-#ifdef XDBE
-                       if (use_xdbe) {
-                               XRectangle r;
-                               r.x = text_start_x - border_margin;
-                               r.y = text_start_y - border_margin;
-                               r.width = text_width + border_margin * 2;
-                               r.height = text_height + border_margin * 2;
-                               XUnionRectWithRegion(&r, region, region);
-                       }
-#endif
-                       XSetRegion(display, window.gc, region);
-#ifdef XFT
-                       if (use_xft)
-                               XftDrawSetClip(window.xftdraw, region);
-#endif
-#endif /* X11 */
-                       draw_stuff();
-#ifdef X11
-                       XDestroyRegion(region);
-                       region = XCreateRegion();
-               }
-#endif /* X11 */
-
-       }
-}
-
-static void load_config_file(const char *);
-
-/* signal handler that reloads config file */
-static void reload_handler(int a)
-{
-       ERR("Conky: received signal %d, reloading config\n", a);
-
-       if (current_config) {
-               clear_fs_stats();
-               load_config_file(current_config);
-#ifdef X11
-               load_fonts();
-               set_font();
-#endif /* X11 */
-               extract_variable_text(text);
-               free(text);
-               text = NULL;
-               update_text();
-       }
-}
-
-static void clean_up()
-{
-#ifdef X11
-#ifdef XDBE
-       if (use_xdbe)
-               XdbeDeallocateBackBufferName(display, window.back_buffer);
-#endif
-#ifdef OWN_WINDOW
-       if (own_window)
-               XDestroyWindow(display, window.window);
-       else
-#endif
-       {
-               XClearWindow(display, RootWindow(display, screen));
-               clear_text(1);
-               XFlush(display);
-       }
-
-       XFreeGC(display, window.gc);
-#endif /* X11 */
-
-
-       /* it is really pointless to free() memory at the end of program but ak|ra
-        * wants me to do this */
-
-       free_text_objects();
-
-       if (text != original_text)
-               free(text);
-
-       free(current_config);
-       free(current_mail_spool);
-#ifdef SETI
-       free(seti_dir);
-#endif
-}
-
-static void term_handler(int a)
-{
-       a = a;                  /* to get rid of warning */
-       clean_up();
-       exit(0);
-}
-
-static int string_to_bool(const char *s)
-{
-       if (!s)
-               return 1;
-       if (strcasecmp(s, "yes") == 0)
-               return 1;
-       if (strcasecmp(s, "true") == 0)
-               return 1;
-       if (strcasecmp(s, "1") == 0)
-               return 1;
-       return 0;
-}
-#ifdef X11
-static enum alignment string_to_alignment(const char *s)
-{
-       if (strcasecmp(s, "top_left") == 0)
-               return TOP_LEFT;
-       else if (strcasecmp(s, "top_right") == 0)
-               return TOP_RIGHT;
-       else if (strcasecmp(s, "bottom_left") == 0)
-               return BOTTOM_LEFT;
-       else if (strcasecmp(s, "bottom_right") == 0)
-               return BOTTOM_RIGHT;
-       else if (strcasecmp(s, "tl") == 0)
-               return TOP_LEFT;
-       else if (strcasecmp(s, "tr") == 0)
-               return TOP_RIGHT;
-       else if (strcasecmp(s, "bl") == 0)
-               return BOTTOM_LEFT;
-       else if (strcasecmp(s, "br") == 0)
-               return BOTTOM_RIGHT;
-       else if (strcasecmp(s, "none") == 0)
-               return NONE;
-       return TOP_LEFT;
-}
-#endif /* X11 */
-
-
-static void set_default_configurations(void)
-{
-       fork_to_background = 0;
-       total_run_times = 0;
-       info.cpu_avg_samples = 2;
-       info.net_avg_samples = 2;
-       info.memmax = 0;
-       top_cpu = 0;
-       top_mem = 0;
-#ifdef MPD
-       strcpy(info.mpd.host, "localhost");
-       info.mpd.port = 6600;
-       info.mpd.status = "Checking status...";
-#endif
-       use_spacer = 0;
-#ifdef X11
-       out_to_console = 0;
-#else
-       out_to_console = 1;
-#endif
-#ifdef X11
-       default_fg_color = WhitePixel(display, screen);
-       default_bg_color = BlackPixel(display, screen);
-       default_out_color = BlackPixel(display, screen);
-       draw_borders = 0;
-       draw_shades = 1;
-       draw_outline = 0;
-       set_first_font("6x10");
-       gap_x = 5;
-       gap_y = 5;
-       minimum_width = 5;
-       minimum_height = 5;
-#ifdef OWN_WINDOW
-       own_window = 0;
-#endif
-       stippled_borders = 0;
-       border_margin = 3;
-       border_width = 1;
-       text_alignment = BOTTOM_LEFT;
-       on_bottom = 1;
-#endif /* X11 */
-
-       free(current_mail_spool);
-       {
-               char buf[256];
-               variable_substitute(MAIL_FILE, buf, 256);
-               if (buf[0] != '\0')
-                       current_mail_spool = strdup(buf);
-       }
-
-       no_buffers = 1;
-       update_interval = 10.0;
-       stuff_in_upper_case = 0;
-#ifdef MLDONKEY
-       mlconfig.mldonkey_hostname = "127.0.0.1";
-       mlconfig.mldonkey_port = 4001;
-       mlconfig.mldonkey_login = NULL;
-       mlconfig.mldonkey_password = NULL;
-#endif
-}
-
-static void load_config_file(const char *f)
-{
-#define CONF_ERR ERR("%s: %d: config file error", f, line)
-       int line = 0;
-       FILE *fp;
-
-       set_default_configurations();
-
-       fp = open_file(f, 0);
-       if (!fp)
-               return;
-
-       while (!feof(fp)) {
-               char buf[256], *p, *p2, *name, *value;
-               line++;
-               if (fgets(buf, 256, fp) == NULL)
-                       break;
-
-               p = buf;
-
-               /* break at comment */
-               p2 = strchr(p, '#');
-               if (p2)
-                       *p2 = '\0';
-
-               /* skip spaces */
-               while (*p && isspace((int) *p))
-                       p++;
-               if (*p == '\0')
-                       continue;       /* empty line */
-
-               name = p;
-
-               /* skip name */
-               p2 = p;
-               while (*p2 && !isspace((int) *p2))
-                       p2++;
-               if (*p2 != '\0') {
-                       *p2 = '\0';     /* break at name's end */
-                       p2++;
-               }
-
-               /* get value */
-               if (*p2) {
-                       p = p2;
-                       while (*p && isspace((int) *p))
-                               p++;
-
-                       value = p;
-
-                       p2 = value + strlen(value);
-                       while (isspace((int) *(p2 - 1)))
-                               *--p2 = '\0';
-               } else {
-                       value = 0;
-               }
-
-#define CONF2(a) if (strcasecmp(name, a) == 0)
-#define CONF(a) else CONF2(a)
-#define CONF3(a,b) \
-else if (strcasecmp(name, a) == 0 || strcasecmp(name, a) == 0)
-
-
-#ifdef X11
-               CONF2("alignment") {
-       if (value) {
-               int a = string_to_alignment(value);
-               if (a <= 0)
-                       CONF_ERR;
-               else
-                       text_alignment = a;
-       } else
-               CONF_ERR;
-               }
-               CONF("on_bottom") {
-                       if(value)
-                               on_bottom = string_to_bool(value);
-                       else
-                               CONF_ERR;
-               }
-               CONF("background") {
-                       fork_to_background = string_to_bool(value);
-               }
-
-#else
-               CONF2("background") {
-       fork_to_background = string_to_bool(value);
-               }
-#endif /* X11 */
-#ifdef X11
-               CONF("border_margin") {
-                       if (value)
-                               border_margin = strtol(value, 0, 0);
-                       else
-                               CONF_ERR;
-               }
-               CONF("border_width") {
-                       if (value)
-                               border_width = strtol(value, 0, 0);
-                       else
-                               CONF_ERR;
-               }
-               CONF("default_color") {
-                       if (value)
-                               default_fg_color = get_x11_color(value);
-                       else
-                               CONF_ERR;
-               }
-               CONF3("default_shade_color", "default_shadecolor") {
-                       if (value)
-                               default_bg_color = get_x11_color(value);
-                       else
-                               CONF_ERR;
-               }
-               CONF3("default_outline_color", "default_outlinecolor") {
-                       if (value)
-                               default_out_color = get_x11_color(value);
-                       else
-                               CONF_ERR;
-               }
-#endif /* X11 */
-#ifdef MPD
-               CONF("mpd_host") {
-                       if (value)
-                               strcpy(info.mpd.host, value);
-                       else
-                               CONF_ERR;
-               }
-               CONF("mpd_port") {
-                       if (value) {
-                               info.mpd.port = strtol(value, 0, 0);
-                               if (info.mpd.port < 1
-                                   || info.mpd.port > 0xffff)
-                                       CONF_ERR;
-                       }
-               }
-#endif
-               CONF("cpu_avg_samples") {
-                       if (value) {
-                               cpu_avg_samples = strtol(value, 0, 0);
-                               if (cpu_avg_samples < 1
-                                   || cpu_avg_samples > 14)
-                                       CONF_ERR;
-                               else
-                                       info.
-                                           cpu_avg_samples
-                                           = cpu_avg_samples;
-                       } else
-                               CONF_ERR;
-               }
-               CONF("net_avg_samples") {
-                       if (value) {
-                               net_avg_samples = strtol(value, 0, 0);
-                               if (net_avg_samples < 1
-                                   || net_avg_samples > 14)
-                                       CONF_ERR;
-                               else
-                                       info.
-                                           net_avg_samples
-                                           = net_avg_samples;
-                       } else
-                               CONF_ERR;
-               }
-
-
-
-
-
-
-#ifdef XDBE
-               CONF("double_buffer") {
-       if (!own_window) {
-               use_xdbe = string_to_bool(value);
-       }
-               }
-#endif
-#ifdef X11
-               CONF("override_utf8_locale") {
-       utf8_mode = string_to_bool(value);
-               }
-
-               CONF("draw_borders") {
-                       draw_borders = string_to_bool(value);
-               }
-               CONF("draw_shades") {
-                       draw_shades = string_to_bool(value);
-               }
-               CONF("draw_outline") {
-                       draw_outline = string_to_bool(value);
-               }
-#endif /* X11 */
-               CONF("out_to_console") {
-                       out_to_console = string_to_bool(value);
-               }
-               CONF("use_spacer") {
-                       use_spacer = string_to_bool(value);
-               }
-#ifdef X11
-#ifdef XFT
-               CONF("use_xft") {
-                       use_xft = string_to_bool(value);
-               }
-               CONF("font") {
-                       if (!use_xft) {
-                               if (value) {
-                                       set_first_font(value);
-                               } else
-                                       CONF_ERR;
-                       }
-               }
-               CONF("xftalpha") {
-                       if (value && font_count >= 0)
-                               fonts[0].font_alpha = atof(value)
-                                   * 65535.0;
-                       else
-                               CONF_ERR;
-               }
-               CONF("xftfont") {
-#else
-               CONF("use_xft") {
-                       if (string_to_bool(value))
-                               ERR("Xft not enabled");
-               }
-               CONF("xftfont") {
-                       /* xftfont silently ignored when no Xft */
-               }
-               CONF("xftalpha") {
-                       /* xftalpha is silently ignored when no Xft */
-               }
-               CONF("font") {
-#endif
-                       if (value) {
-                               set_first_font(value);
-                       } else
-                               CONF_ERR;
-               }
-               CONF("gap_x") {
-                       if (value)
-                               gap_x = atoi(value);
-                       else
-                               CONF_ERR;
-               }
-               CONF("gap_y") {
-                       if (value)
-                               gap_y = atoi(value);
-                       else
-                               CONF_ERR;
-               }
-#endif /* X11 */
-               CONF("mail_spool") {
-                       if (value) {
-                               char buf[256];
-                               variable_substitute(value, buf, 256);
-
-                               if (buf[0]
-                                   != '\0') {
-                                       if (current_mail_spool)
-                                               free(current_mail_spool);
-                                       current_mail_spool = strdup(buf);
-                               }
-                       } else
-                               CONF_ERR;
-               }
-#ifdef X11
-               CONF("minimum_size") {
-                       if (value) {
-                               if (sscanf
-                                   (value, "%d %d", &minimum_width,
-                                    &minimum_height) != 2)
-                                       if (sscanf
-                                           (value, "%d",
-                                            &minimum_width) != 1)
-                                               CONF_ERR;
-                       } else
-                               CONF_ERR;
-               }
-#endif /* X11 */
-               CONF("no_buffers") {
-                       no_buffers = string_to_bool(value);
-               }
-#ifdef MLDONKEY
-               CONF("mldonkey_hostname") {
-                       if (value) {
-                               if (mlconfig.mldonkey_hostname != NULL) {
-                                       free(mlconfig.mldonkey_hostname);
-                               }
-                       mlconfig.mldonkey_hostname = strdup(value);
-                       }
-                       else
-                               CONF_ERR;
-               }
-               CONF("mldonkey_port") {
-                       if (value)
-                               mlconfig.mldonkey_port = atoi(value);
-                       else
-                               CONF_ERR;
-               }
-               CONF("mldonkey_login") {
-                       if (value) {
-                               if (mlconfig.mldonkey_login != NULL) {
-                                       free(mlconfig.mldonkey_login);
-                               }
-                               mlconfig.mldonkey_login = strdup(value);
-                       }
-                       else
-                               CONF_ERR;
-               }
-               CONF("mldonkey_password") {
-                       if (value) {
-                               if (mlconfig.mldonkey_password != NULL) {
-                                       free(mlconfig.mldonkey_password);
-                               }
-                               mlconfig.mldonkey_password = strdup(value);
-                       }
-                       else
-                               CONF_ERR;
-               }
-#endif
-               CONF("pad_percents") {
-       pad_percents = atoi(value);
-               }
-#ifdef X11
-#ifdef OWN_WINDOW
-               CONF("own_window") {
-                       own_window = string_to_bool(value);
-                       use_xdbe = 0;
-               }
-#endif
-               CONF("stippled_borders") {
-                       if (value)
-                               stippled_borders = strtol(value, 0, 0);
-                       else
-                               stippled_borders = 4;
-               }
-#endif /* X11 */
-               CONF("temp1") {
-                       ERR("temp1 configuration is obsolete, use ${i2c <i2c device here> temp 1}");
-               }
-               CONF("temp1") {
-                       ERR("temp2 configuration is obsolete, use ${i2c <i2c device here> temp 2}");
-               }
-               CONF("update_interval") {
-                       if (value)
-                               update_interval = strtod(value, 0);
-                       else
-                               CONF_ERR;
-               }
-               CONF("total_run_times") {
-                       if (value)
-                               total_run_times = strtod(value, 0);
-                       else
-                               CONF_ERR;
-               }
-               CONF("uppercase") {
-                       stuff_in_upper_case = string_to_bool(value);
-               }
-#ifdef SETI
-               CONF("seti_dir") {
-                       seti_dir = (char *)
-                           malloc(strlen(value)
-                                  + 1);
-                       strcpy(seti_dir, value);
-               }
-#endif
-               CONF("text") {
-                       if (text != original_text)
-                               free(text);
-
-                       text = (char *)
-                           malloc(1);
-                       text[0]
-                           = '\0';
-
-                       while (!feof(fp)) {
-                               unsigned
-                               int l = strlen(text);
-                               if (fgets(buf, 256, fp) == NULL)
-                                       break;
-                               text = (char *)
-                                   realloc(text, l + strlen(buf)
-                                           + 1);
-                               strcat(text, buf);
-
-                               if (strlen(text) > 1024 * 8)
-                                       break;
-                       }
-                       fclose(fp);
-                       return;
-               }
-               else
-               ERR("%s: %d: no such configuration: '%s'", f, line, name);
-
-#undef CONF
-#undef CONF2
-       }
-
-       fclose(fp);
-#undef CONF_ERR
-}
-
-                                                                                                                                                                                       /* : means that character before that takes an argument */
-static const char *getopt_string = "vVdt:f:u:i:hc:w:x:y:a:"
-#ifdef X11
-               "x:y:w:a:f:"
-#ifdef OWN_WINDOW
-    "o"
-#endif
-#ifdef XDBE
-    "b"
-#endif
-#endif /* X11 */
-    ;
-
-
-int main(int argc, char **argv)
-{
-       /* handle command line parameters that don't change configs */
-#ifdef X11
-       char *s;
-       char temp[10];
-       unsigned int x;
-
-       if (((s = getenv("LC_ALL")) && *s) || ((s = getenv("LC_CTYPE")) && 
-                    *s) || ((s = getenv("LANG")) && *s)) {
-               strcpy(temp, s);
-               for(x = 0; x < strlen(s) ; x++) {
-                       temp[x] = tolower(s[x]);
-               }
-               if (strstr(temp, "utf-8") || strstr(temp, "utf8")) {
-                       utf8_mode = 1;
-               }
-       }
-       if (!setlocale(LC_CTYPE, "")) {
-               ERR("Can't set the specified locale!\nCheck LANG, LC_CTYPE, LC_ALL.");
-               return 1;
-       }
-#endif /* X11 */
-       while (1) {
-               int c = getopt(argc,
-                              argv,
-                              getopt_string);
-               if (c == -1)
-                       break;
-
-               switch (c) {
-               case 'v':
-               case 'V':
-                       printf
-                           ("Conky " VERSION " compiled " __DATE__ "\n");
-                       return 0;
-
-               case 'c':
-                       /* if current_config is set to a strdup of CONFIG_FILE, free it (even
-                        * though free() does the NULL check itself;), then load optarg value */
-                       if (current_config)
-                               free(current_config);
-                       current_config = strdup(optarg);
-                       break;
-
-               case 'h':
-                       printf
-                                       ("Usage: %s [OPTION]...\n"
-                                       "Conky is a system monitor that renders text on desktop or to own transparent\n"
-                                       "window. Command line options will override configurations defined in config\n"
-                                       "file.\n"
-                                       "   -V            version\n"
-                                       "   -c FILE       config file to load instead of "
-                                       CONFIG_FILE
-                                       "\n"
-                                       "   -d            daemonize, fork to background\n"
-                                       "   -h            help\n"
-#ifdef X11
-                                       "   -a ALIGNMENT  text alignment on screen, {top,bottom}_{left,right}\n"
-                                       "   -f FONT       font to use\n"
-#ifdef OWN_WINDOW
-                                       "   -o            create own window to draw\n"
-#endif
-#ifdef XDBE
-                                       "   -b            double buffer (prevents flickering)\n"
-#endif
-                                       "   -w WIN_ID     window id to draw\n"
-                                       "   -x X          x position\n"
-                                       "   -y Y          y position\n"
-#endif /* X11 */
-                                       "   -t TEXT       text to render, remember single quotes, like -t '$uptime'\n"
-                                       "   -u SECS       update interval\n"
-                                       "   -i NUM        number of times to update Conky\n", argv[0]);
-                       return 0;
-#ifdef X11
-               case 'w':
-                       window.window = strtol(optarg, 0, 0);
-                       break;
-#endif /* X11 */
-
-               case '?':
-                       exit(EXIT_FAILURE);
-               }
-       }
-#ifdef X11
-       /* initalize X BEFORE we load config. (we need to so that 'screen' is set) */
-       init_X11();
-#endif /* X11 */
-
-       tmpstring1 = (char *)
-           malloc(TEXT_BUFFER_SIZE);
-       tmpstring2 = (char *)
-           malloc(TEXT_BUFFER_SIZE);
-
-       /* load current_config or CONFIG_FILE */
-
-#ifdef CONFIG_FILE
-       if (current_config == NULL) {
-               /* load default config file */
-               char buf[256];
-
-               variable_substitute(CONFIG_FILE, buf, 256);
-
-               if (buf[0] != '\0')
-                       current_config = strdup(buf);
-       }
-#endif
-
-       if (current_config != NULL)
-               load_config_file(current_config);
-       else
-               set_default_configurations();
-
-#ifdef MAIL_FILE
-       if (current_mail_spool == NULL) {
-               char buf[256];
-               variable_substitute(MAIL_FILE, buf, 256);
-
-               if (buf[0] != '\0')
-                       current_mail_spool = strdup(buf);
-       }
-#endif
-
-       /* handle other command line arguments */
-
-       optind = 0;
-
-       while (1) {
-               int c = getopt(argc,
-                              argv,
-                              getopt_string);
-               if (c == -1)
-                       break;
-
-               switch (c) {
-               case 'd':
-                       fork_to_background = 1;
-                       break;
-
-#ifdef X11
-                       case 'f':
-                       set_first_font(optarg);
-                       break;
-                       case 'a':
-                               text_alignment = string_to_alignment(optarg);
-                               break;
-
-#ifdef OWN_WINDOW
-               case 'o':
-                       own_window = 1;
-                       use_xdbe = 0;
-                       break;
-#endif
-#ifdef XDBE
-               case 'b':
-                       use_xdbe = 1;
-                       break;
-#endif
-#endif /* X11 */
-               case 't':
-                       if (text != original_text)
-                               free(text);
-                       text = strdup(optarg);
-                       convert_escapes(text);
-                       break;
-
-               case 'u':
-                       update_interval = strtod(optarg, 0);
-                       break;
-
-               case 'i':
-                       total_run_times = strtod(optarg, 0);
-                       break;
-#ifdef X11
-               case 'x':
-                       gap_x = atoi(optarg);
-                       break;
-
-               case 'y':
-                       gap_y = atoi(optarg);
-                       break;
-#endif /* X11 */
-
-               case '?':
-                       exit(EXIT_FAILURE);
-               }
-       }
-
-#ifdef X11
-       /* load font */
-       load_fonts();
-#endif /* X11 */
-
-       /* generate text and get initial size */
-       extract_variable_text(text);
-       if (text != original_text) {
-               free(text);
-       }
-       text = NULL;
-
-       update_uname();
-
-       generate_text();
-#ifdef X11
-       update_text_area();     /* to get initial size of the window */
-
-#if defined OWN_WINDOW
-       init_window
-           (own_window,
-            text_width + border_margin * 2 + 1,
-            text_height + border_margin * 2 + 1,
-            on_bottom, fixed_pos);
-#else
-       init_window
-               (own_window,
-                text_width + border_margin * 2 + 1,
-                text_height + border_margin * 2 + 1,
-                on_bottom);
-       
-#endif
-
-       update_text_area();     /* to position text/window on screen */
-#endif /* X11 */
-
-/*#ifdef CAIRO
-// why the fuck not?
-//do_it();
-#endif*/
-
-#ifdef X11
-#ifdef OWN_WINDOW
-       if (own_window && !fixed_pos)
-               XMoveWindow(display, window.window, window.x, window.y);
-#endif
-
-       create_gc();
-
-       set_font();
-       draw_stuff();
-#endif /* X11 */
-
-       /* fork */
-       if (fork_to_background) {
-               int ret = fork();
-               switch (ret) {
-               case -1:
-                       ERR("can't fork() to background: %s",
-                           strerror(errno));
-                       break;
-
-               case 0:
-                       break;
-
-               default:
-                       fprintf
-                           (stderr,
-                            "Conky: forked to background, pid is %d\n",
-                            ret);
-                       return 0;
-               }
-       }
-
-       /* set SIGUSR1, SIGINT and SIGTERM handlers */
-       {
-               struct
-               sigaction sa;
-
-               sa.sa_handler = reload_handler;
-               sigemptyset(&sa.sa_mask);
-               sa.sa_flags = SA_RESTART;
-               if (sigaction(SIGUSR1, &sa, NULL) != 0)
-                       ERR("can't set signal handler for SIGUSR1: %s",
-                           strerror(errno));
-
-               sa.sa_handler = term_handler;
-               sigemptyset(&sa.sa_mask);
-               sa.sa_flags = SA_RESTART;
-               if (sigaction(SIGINT, &sa, NULL) != 0)
-                       ERR("can't set signal handler for SIGINT: %s",
-                           strerror(errno));
-
-               sa.sa_handler = term_handler;
-               sigemptyset(&sa.sa_mask);
-               sa.sa_flags = SA_RESTART;
-               if (sigaction(SIGTERM, &sa, NULL) != 0)
-                       ERR("can't set signal handler for SIGTERM: %s",
-                           strerror(errno));
-       }
-       main_loop();
-       free(tmpstring1);
-       free(tmpstring2);
-       return 0;
-}
diff --git a/conky.h b/conky.h
deleted file mode 100644 (file)
index 9f832ce..0000000
--- a/conky.h
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * Conky, a system monitor, based on torsmo
- *
- * This program is licensed under BSD license, read COPYING
- *
- *  $Id$
- */
-
-#ifndef _conky_h_
-#define _conky_h_
-
-
-#include <mcheck.h>
-#include "config.h"
-#include <sys/utsname.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <locale.h>
-#include <langinfo.h>
-#include <wchar.h>
-
-#ifdef X11
-#if defined(HAVE_CAIRO_H) && defined(HAVE_CAIRO_XLIB_H) && defined(WANT_CAIRO)
-#define CAIRO
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <cairo.h>
-#include <cairo-xlib.h>
-#endif
-#endif /* X11 */
-
-#define TOP_CPU 1
-#define TOP_NAME 2
-#define TOP_PID 3
-#define TOP_MEM 4
-
-#define TEXT_BUFFER_SIZE 1024
-
-#include <sys/socket.h>
-
-#define ERR(s, varargs...) \
-fprintf(stderr, "Conky: " s "\n", ##varargs)
-
-/* critical error */
-#define CRIT_ERR(s, varargs...) \
-{ fprintf(stderr, "Conky: " s "\n", ##varargs);  exit(EXIT_FAILURE); }
-
-struct net_stat {
-       const char *dev;
-       int up;
-       long long last_read_recv, last_read_trans;
-       long long recv, trans;
-       double recv_speed, trans_speed;
-       struct sockaddr addr;
-       int linkstatus;
-       double net_rec[15], net_trans[15];
-};
-
-struct fs_stat {
-       int fd;
-       char *path;
-       long long size;
-       long long avail;
-};
-
-struct cpu_stat {
-       unsigned int user, nice, system, idle, iowait, irq, softirq;
-       int cpu_avg_samples;
-};
-
-#ifdef MPD
-struct mpd_s {
-       char *title;
-       char *artist;
-       char *album;
-       char *status;
-       int volume;
-       unsigned int port;
-       char host[128];
-       float progress;
-       int bitrate;
-       int length;
-       int elapsed;
-};
-#endif
-
-enum {
-       INFO_CPU = 0,
-       INFO_MAIL = 1,
-       INFO_MEM = 2,
-       INFO_NET = 3,
-#ifdef SETI
-       INFO_SETI = 4,
-#endif
-       INFO_PROCS = 5,
-       INFO_RUN_PROCS = 6,
-       INFO_UPTIME = 7,
-       INFO_BUFFERS = 8,
-       INFO_FS = 9,
-       INFO_I2C = 10,
-       INFO_MIXER = 11,
-       INFO_LOADAVG = 12,
-       INFO_UNAME = 13,
-       INFO_FREQ = 14,
-#ifdef MPD
-       INFO_MPD = 15,
-#endif
-       INFO_TOP = 16,
-#ifdef MLDONKEY
-       INFO_MLDONKEY = 18,
-#endif
-       INFO_WIFI = 19,
-};
-
-
-#ifdef MPD
-#include "libmpdclient.h"
-#endif
-
-struct information {
-       unsigned int mask;
-
-       struct utsname uname_s;
-
-       char freq[10];
-
-       double uptime;
-
-       /* memory information in kilobytes */
-       unsigned int mem, memmax, swap, swapmax;
-       unsigned int bufmem, buffers, cached;
-
-       unsigned int procs;
-       unsigned int run_procs;
-
-       float cpu_usage;
-       struct cpu_stat cpu_summed;
-       unsigned int cpu_count;
-       unsigned int cpu_avg_samples;
-
-       unsigned int net_avg_samples;
-
-       float loadavg[3];
-
-       int new_mail_count, mail_count;
-#ifdef SETI
-       float seti_prog;
-       float seti_credit;
-#endif
-#ifdef MPD
-       struct mpd_s mpd;
-       mpd_Connection *conn;
-#endif
-       struct process *cpu[10];
-       struct process *memu[10];
-       unsigned long looped;
-};
-
-int out_to_console;
-
-int top_cpu;
-int top_mem;
-
-int use_spacer;
-
-char *tmpstring1;
-char *tmpstring2;
-
-#ifdef X11
-/* in x11.c */
-
-#include <X11/Xlib.h>
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-
-#ifdef XFT
-#include <X11/Xft/Xft.h>
-#endif
-
-#if defined(HAVE_XDBE) && defined(DOUBLE_BUFFER)
-#define XDBE
-#include <X11/extensions/Xdbe.h>
-#endif
-
-#define ATOM(a) XInternAtom(display, #a, False)
-
-struct conky_window {
-       Window window;
-       Drawable drawable;
-       GC gc;
-#ifdef XDBE
-       XdbeBackBuffer back_buffer;
-#endif
-#ifdef XFT
-       XftDraw *xftdraw;
-#endif
-
-       int width;
-       int height;
-#ifdef OWN_WINDOW
-       int x;
-       int y;
-#endif
-};
-
-#ifdef XDBE
-extern int use_xdbe;
-#endif
-
-
-#ifdef XFT
-extern int use_xft;
-#endif
-
-extern Display *display;
-extern int display_width;
-extern int display_height;
-extern int screen;
-
-extern int workarea[4];
-
-extern struct conky_window window;
-
-void init_X11();
-#if defined OWN_WINDOW
-void init_window(int use_own_window, int width, int height, int on_bottom, int fixed_pos);
-#else
-void init_window(int use_own_window, int width, int height, int on_bottom);
-#endif
-void create_gc();
-void set_transparent_background(Window win);
-long get_x11_color(const char *);
-
-#endif /* X11 */
-
-/* in common.c */
-
-/* struct that has all info */
-struct information info;
-
-void update_uname();
-double get_time(void);
-FILE *open_file(const char *file, int *reported);
-void variable_substitute(const char *s, char *dest, unsigned int n);
-void format_seconds(char *buf, unsigned int n, long t);
-void format_seconds_short(char *buf, unsigned int n, long t);
-struct net_stat *get_net_stat(const char *dev);
-
-void update_stuff();
-
-#define SET_NEED(a) need_mask |= 1 << (a)
-extern unsigned long long need_mask;
-
-extern double current_update_time, last_update_time;
-
-extern int no_buffers;
-
-/* system dependant (in linux.c) */
-
-void prepare_update(void);
-void update_uptime(void);
-void update_meminfo(void);
-void update_net_stats(void);
-void update_wifi_stats(void);
-void update_cpu_usage(void);
-void update_total_processes(void);
-void update_running_processes(void);
-char *get_freq();
-void update_load_average();
-int open_i2c_sensor(const char *dev, const char *type, int n, int *div,
-                   char *devtype);
-double get_i2c_info(int *fd, int arg, char *devtype, char *type);
-
-char *get_adt746x_cpu(void);
-char *get_adt746x_fan(void);
-
-int open_acpi_temperature(const char *name);
-double get_acpi_temperature(int fd);
-char *get_acpi_ac_adapter(void);
-char *get_acpi_fan(void);
-void get_battery_stuff(char *buf, unsigned int n, const char *bat);
-
-struct process {
-       struct process *next;
-       struct process *previous;
-
-       pid_t pid;
-       char *name;
-       float amount;
-       unsigned int user_time;
-       unsigned int total;
-       unsigned int kernel_time;
-       unsigned int previous_user_time;
-       unsigned int previous_kernel_time;
-       unsigned int vsize;
-       unsigned int rss;
-       unsigned int time_stamp;
-       unsigned int counted;
-       unsigned int changed;
-       float totalmem;
-};
-
-void update_top();
-
-/* fs-stuff is possibly system dependant (in fs.c) */
-
-void update_fs_stats(void);
-struct fs_stat *prepare_fs_stat(const char *path);
-void clear_fs_stats(void);
-
-/* in mixer.c */
-
-int mixer_init(const char *);
-int mixer_get_avg(int);
-int mixer_get_left(int);
-int mixer_get_right(int);
-
-/* in mail.c */
-
-extern char *current_mail_spool;
-
-void update_mail_count();
-
-/* in seti.c */
-
-#ifdef SETI
-extern char *seti_dir;
-
-void update_seti();
-#endif
-
-/* in mpd.c */
-
-#ifdef MPD
-void update_mpd();
-#endif
-
-#ifdef MLDONKEY
-/* in mldonkey.c */
-typedef long long int64;
-/* The info necessary to connect to mldonkey. login and password can be NULL. */
-typedef struct mldonkey_config {
-       char *mldonkey_hostname;
-       int mldonkey_port;
-       char *mldonkey_login;
-       char *mldonkey_password;
-} mldonkey_config;
-
-/* The MLDonkey status returned */
-typedef struct mldonkey_info {
-       int64 upload_counter;
-       int64 download_counter;
-       int nshared_files;
-       int64 shared_counter;
-       int tcp_upload_rate;
-       int tcp_download_rate;
-       int udp_upload_rate;
-       int udp_download_rate;
-       int ndownloaded_files;
-       int ndownloading_files;
-       int nconnected_networks;
-       int connected_networks[1];
-} mldonkey_info;
-
-extern mldonkey_info mlinfo;
-extern mldonkey_config mlconfig;
-
-int get_mldonkey_status(mldonkey_config * config, mldonkey_info * info);
-#endif
-
-/* in linux.c */
-
-/* nothing to see here */
-
-/* in cairo.c */
-
-extern int do_it(void);
-
-#endif
diff --git a/freebsd.c b/freebsd.c
deleted file mode 100644 (file)
index 90e809d..0000000
--- a/freebsd.c
+++ /dev/null
@@ -1,451 +0,0 @@
-#include "conky.h"
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <kvm.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/sysctl.h>
-#include <sys/vmmeter.h>
-#include <sys/dkstat.h>
-#include <unistd.h>
-#include <sys/user.h>
-#include <sys/socket.h>
-#include <net/if.h>
-#include <net/if_mib.h>
-#include <sys/socket.h>
-#include <ifaddrs.h>
-
-#define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var))
-#define KELVTOC(x)      ((x - 2732) / 10.0)
-
-#if defined(i386) || defined(__i386__)
-static unsigned int get_timer();
-static unsigned int get_cpu_speed(void);
-static inline unsigned long long int rdtsc(void);
-
-/* cpu frequency detection code based on mplayer's one */
-
-static unsigned int get_timer()
-{
-       struct timeval tv;
-       struct timezone tz;
-       gettimeofday(&tv, &tz);
-
-       return (tv.tv_sec * 1000000 + tv.tv_usec);
-}
-
-static inline unsigned long long int rdtsc(void)
-{
-       unsigned long long int retval;
-       __asm __volatile("rdtsc":"=A"(retval)::"memory");
-       return retval;
-}
-
-static unsigned int get_cpu_speed(void)
-{
-       unsigned long long int tscstart, tscstop;
-       unsigned int start, stop;
-
-       tscstart = rdtsc();
-       start = get_timer();
-       usleep(50000);
-       stop = get_timer();
-       tscstop = rdtsc();
-
-       return ((tscstop - tscstart) / ((stop - start) / 1000.0));
-}
-#endif
-
-
-static int getsysctl(char *name, void *ptr, size_t len)
-{
-       size_t nlen = len;
-       if (sysctlbyname(name, ptr, &nlen, NULL, 0) == -1) {
-               return -1;
-       }
-
-       if (nlen != len) {
-               return -1;
-       }
-
-       return 0;
-}
-
-static kvm_t *kd = NULL;
-struct ifmibdata *data = NULL;
-size_t len = 0;
-
-
-static int swapmode(int *retavail, int *retfree)
-{
-       int n;
-       int pagesize = getpagesize();
-       struct kvm_swap swapary[1];
-       static int kd_init = 1;
-
-       if (kd_init) {
-               kd_init = 0;
-               if ((kd = kvm_open("/dev/null", "/dev/null", "/dev/null",
-                                  O_RDONLY, "kvm_open")) == NULL) {
-                       (void) fprintf(stderr, "Cannot read kvm.");
-                       return -1;
-               }
-       }
-
-       if (kd == NULL) {
-               return -1;
-       }
-
-       *retavail = 0;
-       *retfree = 0;
-
-#define CONVERT(v)      ((quad_t)(v) * pagesize / 1024)
-
-       n = kvm_getswapinfo(kd, swapary, 1, 0);
-       if (n < 0 || swapary[0].ksw_total == 0)
-               return (0);
-
-       *retavail = CONVERT(swapary[0].ksw_total);
-       *retfree = CONVERT(swapary[0].ksw_total - swapary[0].ksw_used);
-
-       n = (int) ((double) swapary[0].ksw_used * 100.0 /
-                  (double) swapary[0].ksw_total);
-
-       return n;
-}
-
-
-void prepare_update()
-{
-}
-
-/*double get_uptime() */
-void update_uptime()
-{
-       int mib[2] = { CTL_KERN, KERN_BOOTTIME };
-       struct timeval boottime;
-       time_t now;
-       size_t size = sizeof(boottime);
-
-       if ((sysctl(mib, 2, &boottime, &size, NULL, 0) != -1)
-           && (boottime.tv_sec != 0)) {
-               time(&now);
-               info.uptime = now - boottime.tv_sec;
-       } else {
-               (void) fprintf(stderr, "Could not get uptime\n");
-               info.uptime = 0;
-       }
-}
-
-
-void update_meminfo()
-{
-       int total_pages, inactive_pages, free_pages;
-       int swap_avail, swap_free;
-
-       int pagesize = getpagesize();
-
-       if (GETSYSCTL("vm.stats.vm.v_page_count", total_pages))
-               (void) fprintf(stderr,
-                              "Cannot read sysctl \"vm.stats.vm.v_page_count\"");
-
-       if (GETSYSCTL("vm.stats.vm.v_free_count", free_pages))
-               (void) fprintf(stderr,
-                              "Cannot read sysctl \"vm.stats.vm.v_free_count\"");
-
-       if (GETSYSCTL("vm.stats.vm.v_inactive_count", inactive_pages))
-               (void) fprintf(stderr,
-                              "Cannot read sysctl \"vm.stats.vm.v_inactive_count\"");
-
-       info.memmax = (total_pages * pagesize) >> 10;
-       info.mem =
-           ((total_pages - free_pages - inactive_pages) * pagesize) >> 10;
-
-
-       if ((swapmode(&swap_avail, &swap_free)) >= 0) {
-               info.swapmax = swap_avail;
-               info.swap = (swap_avail - swap_free);
-       } else {
-               info.swapmax = 0;
-               info.swap = 0;
-       }
-}
-
-void update_net_stats()
-{
-       struct net_stat *ns;
-       double delta;
-       long long r, t, last_recv, last_trans;
-       struct ifaddrs *ifap, *ifa;
-       struct if_data *ifd;
-
-
-       /* get delta */
-       delta = current_update_time - last_update_time;
-       if (delta <= 0.0001)
-               return;
-
-       if (getifaddrs(&ifap) < 0)
-               return;
-
-       for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
-               ns = get_net_stat((const char *) ifa->ifa_name);
-
-               if (ifa->ifa_flags & IFF_UP) {
-                       last_recv = ns->recv;
-                       last_trans = ns->trans;
-
-                       if (ifa->ifa_addr->sa_family != AF_LINK)
-                               continue;
-
-                       ifd = (struct if_data *) ifa->ifa_data;
-                       r = ifd->ifi_ibytes;
-                       t = ifd->ifi_obytes;
-
-                       if (r < ns->last_read_recv)
-                               ns->recv +=
-                                   ((long long) 4294967295U -
-                                    ns->last_read_recv) + r;
-                       else
-                               ns->recv += (r - ns->last_read_recv);
-
-                       ns->last_read_recv = r;
-
-                       if (t < ns->last_read_trans)
-                               ns->trans +=
-                                   ((long long) 4294967295U -
-                                    ns->last_read_trans) + t;
-                       else
-                               ns->trans += (t - ns->last_read_trans);
-
-                       ns->last_read_trans = t;
-
-
-                       /* calculate speeds */
-                       ns->recv_speed = (ns->recv - last_recv) / delta;
-                       ns->trans_speed = (ns->trans - last_trans) / delta;
-               }
-       }
-
-       freeifaddrs(ifap);
-}
-
-void update_total_processes()
-{
-       /* It's easier to use kvm here than sysctl */
-
-       int n_processes;
-       static int kd_init = 1;
-
-       if (kd_init) {
-               kd_init = 0;
-               if ((kd = kvm_open("/dev/null", "/dev/null", "/dev/null",
-                                  O_RDONLY, "kvm_open")) == NULL) {
-                       (void) fprintf(stderr, "Cannot read kvm.");
-                       return;
-               }
-       }
-
-
-       if (kd != NULL)
-               kvm_getprocs(kd, KERN_PROC_ALL, 0, &n_processes);
-       else
-               return;
-
-       info.procs = n_processes;
-}
-
-void update_running_processes()
-{
-       static int kd_init = 1;
-       struct kinfo_proc *p;
-       int n_processes;
-       int i, cnt = 0;
-
-       if (kd_init) {
-               kd_init = 0;
-               if ((kd =
-                    kvm_open("/dev/null", "/dev/null", "/dev/null",
-                             O_RDONLY, "kvm_open")) == NULL) {
-                       (void) fprintf(stderr, "Cannot read kvm.");
-               }
-       }
-
-       if (kd != NULL) {
-               p = kvm_getprocs(kd, KERN_PROC_ALL, 0, &n_processes);
-               for (i = 0; i < n_processes; i++) {
-#if __FreeBSD__ < 5
-                       if (p[i].kp_proc.p_stat == SRUN)
-#else
-                       if (p[i].ki_stat == SRUN)
-#endif
-                               cnt++;
-               }
-       } else
-               return;
-
-       info.run_procs = cnt;
-}
-
-struct cpu_load_struct {
-       unsigned long load[5];
-};
-
-struct cpu_load_struct fresh = { {0, 0, 0, 0, 0} };
-long cpu_used, oldtotal, oldused;
-
-void update_cpu_usage()
-{
-       long used, total;
-       long cp_time[CPUSTATES];
-       size_t len = sizeof(cp_time);
-
-       if (sysctlbyname("kern.cp_time", &cp_time, &len, NULL, 0) < 0) {
-               (void) fprintf(stderr, "Cannot get kern.cp_time");
-       }
-
-       fresh.load[0] = cp_time[CP_USER];
-       fresh.load[1] = cp_time[CP_NICE];
-       fresh.load[2] = cp_time[CP_SYS];
-       fresh.load[3] = cp_time[CP_IDLE];
-       fresh.load[4] = cp_time[CP_IDLE];
-
-       used = fresh.load[0] + fresh.load[1] + fresh.load[2];
-       total =
-           fresh.load[0] + fresh.load[1] + fresh.load[2] + fresh.load[3];
-
-       if ((total - oldtotal) != 0) {
-               info.cpu_usage =
-                   ((double) (used - oldused)) / (double) (total -
-                                                           oldtotal);
-       } else {
-               info.cpu_usage = 0;
-       }
-
-       oldused = used;
-       oldtotal = total;
-}
-
-double get_i2c_info(int *fd, int div, char *devtype)
-{
-       return 0;
-}
-
-void update_load_average()
-{
-       double v[3];
-       getloadavg(v, 3);
-
-       info.loadavg[0] = (float) v[0];
-       info.loadavg[1] = (float) v[1];
-       info.loadavg[2] = (float) v[2];
-}
-
-double get_acpi_temperature(int fd)
-{
-       int temp;
-
-       if (GETSYSCTL("hw.acpi.thermal.tz0.temperature", temp)) {
-               (void) fprintf(stderr,
-                              "Cannot read sysctl \"hw.acpi.thermal.tz0.temperature\"\n");
-               return 0.0;
-       }
-
-       return KELVTOC(temp);
-}
-
-void get_battery_stuff(char *buf, unsigned int n, const char *bat)
-{
-       int battime;
-
-       if (GETSYSCTL("hw.acpi.battery.time", battime))
-               (void) fprintf(stderr,
-                              "Cannot read sysctl \"hw.acpi.battery.time\"\n");
-
-       if (battime != -1)
-               snprintf(buf, n, "Discharging, remaining %d:%2.2d",
-                        battime / 60, battime % 60);
-       else
-               snprintf(buf, n, "Battery is charging");
-}
-
-int
-open_i2c_sensor(const char *dev, const char *type, int n, int *div,
-               char *devtype)
-{
-       return 0;
-}
-
-int open_acpi_temperature(const char *name)
-{
-       return 0;
-}
-
-char *get_acpi_ac_adapter(void)
-{
-       int state;
-       char *acstate = (char *) malloc(100);
-
-       if (GETSYSCTL("hw.acpi.acline", state)) {
-               (void) fprintf(stderr,
-                              "Cannot read sysctl \"hw.acpi.acline\"\n");
-               return "n\\a";
-       }
-
-
-       if (state)
-               strcpy(acstate, "Running on AC Power");
-       else
-               strcpy(acstate, "Running on battery");
-
-       return acstate;
-}
-
-char *get_acpi_fan()
-{
-       return "";
-}
-
-char *get_adt746x_cpu()
-{
-       return "";
-}
-
-char *get_adt746x_fan()
-{
-       return "";
-}
-
-char *get_freq()
-{
-#if defined(i386) || defined(__i386__)
-       int i;
-       char *cpuspeed;
-
-       if ((cpuspeed = (char *) malloc(16)) == NULL) {
-               CRIT_ERR("get_freq()");
-       }
-
-       i = 0;
-       if ((i = get_cpu_speed()) > 0) {
-               if (i < 1000000) {
-                       i += 50;        /* for rounding */
-                       snprintf(cpuspeed, 15, "%d.%d MHz", i / 1000,
-                                (i / 100) % 10);
-               } else {
-                       snprintf(cpuspeed, 15, "%d MHz", i / 1000);
-               }
-       } else {
-               cpuspeed = "";
-       }
-
-       return cpuspeed;
-#else
-       return "";
-#endif
-}
diff --git a/fs.c b/fs.c
deleted file mode 100644 (file)
index 9c019e8..0000000
--- a/fs.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Conky, a system monitor, based on torsmo
- *
- * This program is licensed under BSD license, read COPYING
- *
- *  $Id$
- */
-
-#include "conky.h"
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <fcntl.h>
-
-/* linux */
-#ifdef HAVE_SYS_STATFS_H
-#include <sys/statfs.h>
-#endif
-
-/* freebsd && netbsd */
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-#ifdef HAVE_SYS_MOUNT_H
-#include <sys/mount.h>
-#endif
-
-/* TODO: benchmark which is faster, fstatvfs() or pre-opened fd and
- * statvfs() (fstatvfs() would handle mounts I think...) */
-
-static struct fs_stat fs_stats_[64];
-struct fs_stat *fs_stats = fs_stats_;
-
-void update_fs_stats()
-{
-       unsigned int i;
-       struct statfs s;
-       for (i = 0; i < 16; i++) {
-               if (fs_stats[i].fd <= 0)
-                       break;
-
-               fstatfs(fs_stats[i].fd, &s);
-
-               fs_stats[i].size = (long long) s.f_blocks * s.f_bsize;
-               /* bfree (root) or bavail (non-roots) ? */
-               fs_stats[i].avail = (long long) s.f_bavail * s.f_bsize;
-       }
-}
-
-void clear_fs_stats()
-{
-       unsigned int i;
-       for (i = 0; i < 16; i++) {
-               if (fs_stats[i].fd) {
-                       close(fs_stats[i].fd);
-                       fs_stats[i].fd = -1;
-               }
-
-               if (fs_stats[i].path != NULL) {
-                       free(fs_stats[i].path);
-                       fs_stats[i].path = NULL;
-               }
-       }
-}
-
-struct fs_stat *prepare_fs_stat(const char *s)
-{
-       unsigned int i;
-
-       for (i = 0; i < 16; i++) {
-               struct fs_stat *fs = &fs_stats[i];
-
-               if (fs->path && strcmp(fs->path, s) == 0)
-                       return fs;
-
-               if (fs->fd <= 0) {
-                       /* when compiled with icc, it crashes when leaving function and open()
-                        * is used, I don't know why */
-
-                       /* this icc workaround didn't seem to work */
-#if 0
-                       {
-                               FILE *fp = fopen(s, "r");
-                               if (fp)
-                                       fs->fd = fileno(fp);
-                               else
-                                       fs->fd = -1;
-                       }
-#endif
-
-                       fs->fd = open(s, O_RDONLY);
-
-                       if (fs->fd <= 0) {      /* 0 isn't error but actually it is :) */
-                               ERR("open '%s': %s", s, strerror(errno));
-                               return 0;
-                       }
-
-                       fs->path = strdup(s);
-                       update_fs_stats();
-                       return fs;
-               }
-       }
-
-       ERR("too many fs stats");
-       return 0;
-}
diff --git a/ftp.c b/ftp.c
deleted file mode 100644 (file)
index 490fd20..0000000
--- a/ftp.c
+++ /dev/null
@@ -1,936 +0,0 @@
-/*
- * ftp.c: basic handling of an FTP command connection to check for
- *        directory availability. No transfer is needed.
- *
- *  Reference: RFC 959
- *
- *  $Id$
- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <resolv.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <netdb.h>
-#include <string.h>
-
-#include "ftp.h"
-
-/* #define DEBUG_FTP 1  */
-#ifdef STANDALONE
-#define DEBUG_FTP 1
-#endif
-
-static int ftpFd = -1;
-static struct sockaddr_in ftpAddr;
-static char hostname[100];
-static int ftpPassive = 1;
-static int dataFd = -1;
-
-#define FTP_COMMAND_OK          200
-#define FTP_SYNTAX_ERROR        500
-#define FTP_GET_PASSWD          331
-
-/*
- * Initialize the FTP handling.
- */
-
-void initFtp(void)
-{
-       gethostname(hostname, sizeof(hostname));
-}
-
-/*
- * Parsing of the server answer, we just extract the code.
- * return 0 for errors
- *     +XXX for last line of response
- *     -XXX for response to be continued
- */
-int parseFtpResponse(char *buf, int len)
-{
-       int val = 0;
-
-       if (len < 3)
-               return (-1);
-       if ((*buf >= '0') && (*buf <= '9'))
-               val = val * 10 + (*buf - '0');
-       else
-               return (0);
-       buf++;
-       if ((*buf >= '0') && (*buf <= '9'))
-               val = val * 10 + (*buf - '0');
-       else
-               return (0);
-       buf++;
-       if ((*buf >= '0') && (*buf <= '9'))
-               val = val * 10 + (*buf - '0');
-       else
-               return (0);
-       buf++;
-       if (*buf == '-')
-               return (-val);
-       return (val);
-}
-
-/*
- * Read the response from the FTP server after a command.
- * Returns the code number
- *
- */
-int readFtpResponse(char *buf, int size)
-{
-       char *ptr, *end;
-       int len;
-       int res = -1;
-
-       if (size <= 0)
-               return (-1);
-
-      get_more:
-       if ((len = recv(ftpFd, buf, size - 1, 0)) < 0) {
-               close(ftpFd);
-               ftpFd = -1;
-               ftpFd = -1;
-               return (-1);
-       }
-       if (len == 0) {
-               return (-1);
-       }
-
-       end = &buf[len];
-       *end = 0;
-#ifdef DEBUG_FTP
-       printf(buf);
-#endif
-       ptr = buf;
-       while (ptr < end) {
-               res = parseFtpResponse(ptr, end - ptr);
-               if (res > 0)
-                       break;
-               if (res == 0) {
-#ifdef DEBUG_FTP
-                       fprintf(stderr, "readFtpResponse failed: %s\n",
-                               ptr);
-#endif
-                       return (-1);
-               }
-               while ((ptr < end) && (*ptr != '\n'))
-                       ptr++;
-               if (ptr >= end) {
-#ifdef DEBUG_FTP
-                       fprintf(stderr,
-                               "readFtpResponse: unexpected end %s\n",
-                               buf);
-#endif
-                       return ((-res) / 100);
-               }
-               if (*ptr != '\r')
-                       ptr++;
-       }
-
-       if (res < 0)
-               goto get_more;
-
-#ifdef DEBUG_FTP
-       printf("Got %d\n", res);
-#endif
-       return (res / 100);
-}
-
-/*
- * Get the response from the FTP server after a command.
- * Returns the code number
- *
- */
-int getFtpResponse(void)
-{
-       char buf[16 * 1024 + 1];
-
-/**************
-    fd_set rfd;
-    struct timeval tv;
-    int res;
-
-    tv.tv_sec = 10;
-    tv.tv_usec = 0;
-    FD_ZERO(&rfd);
-    FD_SET(ftpFd, &rfd);
-    res = select(ftpFd + 1, &rfd, NULL, NULL, &tv);
-    if (res <= 0) return(res);
- **************/
-
-       return (readFtpResponse(buf, 16 * 1024));
-}
-
-/*
- * Check if there is a response from the FTP server after a command.
- * Returns the code number, or 0
- */
-int checkFtpResponse(void)
-{
-       char buf[1024 + 1];
-       fd_set rfd;
-       struct timeval tv;
-
-       tv.tv_sec = 0;
-       tv.tv_usec = 0;
-       FD_ZERO(&rfd);
-       FD_SET(ftpFd, &rfd);
-       switch (select(ftpFd + 1, &rfd, NULL, NULL, &tv)) {
-       case 0:
-               return (0);
-       case -1:
-#ifdef DEBUG_FTP
-               perror("select");
-#endif
-               return (-1);
-
-       }
-
-       return (readFtpResponse(buf, 1024));
-}
-
-/*
- * Send the user authentification
- */
-
-int sendUser(void)
-{
-       char buf[200];
-       int len;
-       int res;
-
-       len = snprintf(buf, sizeof(buf), "USER anonymous\r\n");
-#ifdef DEBUG_FTP
-       printf(buf);
-#endif
-       res = send(ftpFd, buf, len, 0);
-       if (res < 0)
-               return (res);
-       return (0);
-}
-
-/*
- * Send the password authentification
- */
-
-int sendPasswd(void)
-{
-       char buf[200];
-       int len;
-       int res;
-
-       len =
-           snprintf(buf, sizeof(buf), "PASS mirrorfind@%s\r\n", hostname);
-#ifdef DEBUG_FTP
-       printf(buf);
-#endif
-       res = send(ftpFd, buf, len, 0);
-       if (res < 0)
-               return (res);
-       return (0);
-}
-
-/*
- * Send a QUIT
- */
-
-int sendQuit(void)
-{
-       char buf[200];
-       int len;
-       int res;
-
-       len = snprintf(buf, sizeof(buf), "QUIT\r\n");
-#ifdef DEBUG_FTP
-       printf(buf);
-#endif
-       res = send(ftpFd, buf, len, 0);
-       return (0);
-}
-
-/*
- * Connecting to the server, port 21 by default.
- */
-
-int connectFtp(const char *server, int port)
-{
-       struct hostent *hp;
-       int res;
-
-       /*
-        * do the blocking DNS query.
-        */
-       hp = gethostbyname(server);
-       if (hp == NULL)
-               return (-1);
-
-       /*
-        * Prepare the socket
-        */
-       memset(&ftpAddr, 0, sizeof(ftpAddr));
-       ftpAddr.sin_family = AF_INET;
-       memcpy(&ftpAddr.sin_addr, hp->h_addr_list[0], hp->h_length);
-       if (port == 0)
-               port = 21;
-       ftpAddr.sin_port = htons(port);
-       ftpFd = socket(AF_INET, SOCK_STREAM, 0);
-       if (ftpFd < 0)
-               return (-1);
-
-       /*
-        * Do the connect.
-        */
-       if (connect(ftpFd, (struct sockaddr *) &ftpAddr,
-                   sizeof(struct sockaddr_in)) < 0) {
-               close(ftpFd);
-               ftpFd = -1;
-               ftpFd = -1;
-               return (-1);
-       }
-
-       /*
-        * Wait for the HELLO from the server.
-        */
-       res = getFtpResponse();
-       if (res != 2) {
-               close(ftpFd);
-               ftpFd = -1;
-               ftpFd = -1;
-               return (-1);
-       }
-
-       /*
-        * State diagram for the login operation on the FTP server
-        *
-        * Reference: RFC 959
-        *
-        *                       1
-        * +---+   USER    +---+------------->+---+
-        * | B |---------->| W | 2       ---->| E |
-        * +---+           +---+------  |  -->+---+
-        *                  | |       | | |
-        *                3 | | 4,5   | | |
-        *    --------------   -----  | | |
-        *   |                      | | | |
-        *   |                      | | | |
-        *   |                 ---------  |
-        *   |               1|     | |   |
-        *   V                |     | |   |
-        * +---+   PASS    +---+ 2  |  ------>+---+
-        * |   |---------->| W |------------->| S |
-        * +---+           +---+   ---------->+---+
-        *                  | |   | |     |
-        *                3 | |4,5| |     |
-        *    --------------   --------   |
-        *   |                    | |  |  |
-        *   |                    | |  |  |
-        *   |                 -----------
-        *   |             1,3|   | |  |
-        *   V                |  2| |  |
-        * +---+   ACCT    +---+--  |   ----->+---+
-        * |   |---------->| W | 4,5 -------->| F |
-        * +---+           +---+------------->+---+
-        */
-       res = sendUser();
-       if (res < 0) {
-               close(ftpFd);
-               ftpFd = -1;
-               ftpFd = -1;
-               return (-1);
-       }
-       res = getFtpResponse();
-       switch (res) {
-       case 2:
-               return (0);
-       case 3:
-               break;
-       case 1:
-       case 4:
-       case 5:
-       case -1:
-       default:
-               close(ftpFd);
-               ftpFd = -1;
-               ftpFd = -1;
-               return (-1);
-       }
-       res = sendPasswd();
-       if (res < 0) {
-               close(ftpFd);
-               ftpFd = -1;
-               ftpFd = -1;
-               return (-1);
-       }
-       res = getFtpResponse();
-       switch (res) {
-       case 2:
-               return (0);
-       case 3:
-               fprintf(stderr,
-                       "FTP server asking for ACCNT on anonymous\n");
-       case 1:
-       case 4:
-       case 5:
-       case -1:
-       default:
-               close(ftpFd);
-               ftpFd = -1;
-               ftpFd = -1;
-               return (-1);
-       }
-
-       return (0);
-}
-
-/*
- * Check an FTP directory on the server
- */
-
-int changeFtpDirectory(char *directory)
-{
-       char buf[400];
-       int len;
-       int res;
-
-       /*
-        * Expected response code for CWD:
-        *
-        * CWD
-        *     250
-        *     500, 501, 502, 421, 530, 550
-        */
-       len = snprintf(buf, sizeof(buf), "CWD %s\r\n", directory);
-#ifdef DEBUG_FTP
-       printf(buf);
-#endif
-       res = send(ftpFd, buf, len, 0);
-       if (res < 0)
-               return (res);
-       res = getFtpResponse();
-       if (res == 4) {
-               close(ftpFd);
-               ftpFd = -1;
-               ftpFd = -1;
-               return (-1);
-       }
-       if (res == 2)
-               return (1);
-       if (res == 5) {
-               return (0);
-       }
-       return (0);
-}
-
-/*
- * dataConnectFtp
- */
-int dataConnectFtp()
-{
-       char buf[200];
-       int len, i;
-       int res;
-       unsigned char ad[6], *cur, *adp, *portp;
-       unsigned int temp[6];
-       struct sockaddr_in dataAddr;
-       socklen_t dataAddrLen;
-
-       dataFd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-       if (dataFd < 0) {
-               fprintf(stderr,
-                       "dataConnectFtp: failed to create socket\n");
-       }
-       dataAddrLen = sizeof(dataAddr);
-       memset(&dataAddr, 0, dataAddrLen);
-       dataAddr.sin_family = AF_INET;
-
-       if (ftpPassive) {
-               len = snprintf(buf, sizeof(buf), "PASV\r\n");
-#ifdef DEBUG_FTP
-               printf(buf);
-#endif
-               res = send(ftpFd, buf, len, 0);
-               if (res < 0) {
-                       close(dataFd);
-                       dataFd = -1;
-                       return (res);
-               }
-               res = readFtpResponse(buf, sizeof(buf) - 1);
-               if (res != 2) {
-                       if (res == 5) {
-                               close(dataFd);
-                               dataFd = -1;
-                               return (-1);
-                       } else {
-                               /*
-                                * retry with an active connection
-                                */
-                               close(dataFd);
-                               dataFd = -1;
-                               ftpPassive = 0;
-                       }
-               }
-               cur = &buf[4];
-               while (((*cur < '0') || (*cur > '9')) && *cur != '\0')
-                       cur++;
-               if (sscanf
-                   (cur, "%d,%d,%d,%d,%d,%d", &temp[0], &temp[1],
-                    &temp[2], &temp[3], &temp[4], &temp[5]) != 6) {
-                       fprintf(stderr, "Invalid answer to PASV\n");
-                       close(dataFd);
-                       dataFd = -1;
-                       return (-1);
-               }
-               for (i = 0; i < 6; i++)
-                       ad[i] = (unsigned char) (temp[i] & 0xff);
-               memcpy(&dataAddr.sin_addr, &ad[0], 4);
-               memcpy(&dataAddr.sin_port, &ad[4], 2);
-               if (connect
-                   (dataFd, (struct sockaddr *) &dataAddr,
-                    dataAddrLen) < 0) {
-                       fprintf(stderr,
-                               "Failed to create a data connection\n");
-                       close(dataFd);
-                       dataFd = -1;
-                       return (-1);
-               }
-       } else {
-               getsockname(dataFd, (struct sockaddr *) &dataAddr,
-                           &dataAddrLen);
-               dataAddr.sin_port = 0;
-               if (bind
-                   (dataFd, (struct sockaddr *) &dataAddr,
-                    dataAddrLen) < 0) {
-                       fprintf(stderr, "Failed to bind a port\n");
-                       close(dataFd);
-                       dataFd = -1;
-                       return (-1);
-               }
-               getsockname(dataFd, (struct sockaddr *) &dataAddr,
-                           &dataAddrLen);
-
-               if (listen(dataFd, 1) < 0) {
-                       fprintf(stderr, "Could not listen on port %d\n",
-                               ntohs(dataAddr.sin_port));
-                       close(dataFd);
-                       dataFd = -1;
-                       return (-1);
-               }
-               adp = (unsigned char *) &dataAddr.sin_addr;
-               portp = (unsigned char *) &dataAddr.sin_port;
-               len =
-                   snprintf(buf, sizeof(buf),
-                            "PORT %d,%d,%d,%d,%d,%d\r\n", adp[0] & 0xff,
-                            adp[1] & 0xff, adp[2] & 0xff, adp[3] & 0xff,
-                            portp[0] & 0xff, portp[1] & 0xff);
-               buf[sizeof(buf) - 1] = 0;
-#ifdef DEBUG_FTP
-               printf(buf);
-#endif
-
-               res = send(ftpFd, buf, len, 0);
-               if (res < 0) {
-                       close(dataFd);
-                       dataFd = -1;
-                       return (res);
-               }
-               res = getFtpResponse();
-               if (res != 2) {
-                       close(dataFd);
-                       dataFd = -1;
-                       return (-1);
-               }
-       }
-       return (dataFd);
-
-}
-
-/*
- * dataConnectEndFtp
- */
-int dataConnectEndFtp()
-{
-       int res;
-
-       close(dataFd);
-       dataFd = -1;
-       res = getFtpResponse();
-       if (res != 2) {
-               close(dataFd);
-               dataFd = -1;
-               close(ftpFd);
-               ftpFd = -1;
-               return (-1);
-       }
-       return (0);
-}
-
-/*
- * parseListFtp
- */
-
-int parseListFtp(const char *list, ftpListCallback callback,
-                void *userData)
-{
-       const char *cur = list;
-       char filename[151];
-       char attrib[11];
-       char owner[11];
-       char group[11];
-       char month[4];
-       int year = 0;
-       int minute = 0;
-       int hour = 0;
-       int day = 0;
-       unsigned long size = 0;
-       int links = 0;
-       int i;
-
-       if (!strncmp(cur, "total", 5)) {
-               cur += 5;
-               while (*cur == ' ')
-                       cur++;
-               while ((*cur >= '0') && (*cur <= '9'))
-                       links = (links * 10) + (*cur++ - '0');
-               while ((*cur == ' ') || (*cur == '\n') || (*cur == '\r'))
-                       cur++;
-               return (cur - list);
-       } else if (*list == '+') {
-               return (0);
-       } else {
-               while ((*cur == ' ') || (*cur == '\n') || (*cur == '\r'))
-                       cur++;
-               if (*cur == 0)
-                       return (0);
-               i = 0;
-               while (*cur != ' ') {
-                       if (i < 10)
-                               attrib[i++] = *cur;
-                       cur++;
-                       if (*cur == 0)
-                               return (0);
-               }
-               attrib[10] = 0;
-               while (*cur == ' ')
-                       cur++;
-               if (*cur == 0)
-                       return (0);
-               while ((*cur >= '0') && (*cur <= '9'))
-                       links = (links * 10) + (*cur++ - '0');
-               while (*cur == ' ')
-                       cur++;
-               if (*cur == 0)
-                       return (0);
-               i = 0;
-               while (*cur != ' ') {
-                       if (i < 10)
-                               owner[i++] = *cur;
-                       cur++;
-                       if (*cur == 0)
-                               return (0);
-               }
-               owner[i] = 0;
-               while (*cur == ' ')
-                       cur++;
-               if (*cur == 0)
-                       return (0);
-               i = 0;
-               while (*cur != ' ') {
-                       if (i < 10)
-                               group[i++] = *cur;
-                       cur++;
-                       if (*cur == 0)
-                               return (0);
-               }
-               group[i] = 0;
-               while (*cur == ' ')
-                       cur++;
-               if (*cur == 0)
-                       return (0);
-               while ((*cur >= '0') && (*cur <= '9'))
-                       size = (size * 10) + (*cur++ - '0');
-               while (*cur == ' ')
-                       cur++;
-               if (*cur == 0)
-                       return (0);
-               i = 0;
-               while (*cur != ' ') {
-                       if (i < 3)
-                               month[i++] = *cur;
-                       cur++;
-                       if (*cur == 0)
-                               return (0);
-               }
-               month[i] = 0;
-               while (*cur == ' ')
-                       cur++;
-               if (*cur == 0)
-                       return (0);
-               while ((*cur >= '0') && (*cur <= '9'))
-                       day = (day * 10) + (*cur++ - '0');
-               while (*cur == ' ')
-                       cur++;
-               if (*cur == 0)
-                       return (0);
-               if ((cur[1] == 0) || (cur[2] == 0))
-                       return (0);
-               if ((cur[1] == ':') || (cur[2] == ':')) {
-                       while ((*cur >= '0') && (*cur <= '9'))
-                               hour = (hour * 10) + (*cur++ - '0');
-                       if (*cur == ':')
-                               cur++;
-                       while ((*cur >= '0') && (*cur <= '9'))
-                               minute = (minute * 10) + (*cur++ - '0');
-               } else {
-                       while ((*cur >= '0') && (*cur <= '9'))
-                               year = (year * 10) + (*cur++ - '0');
-               }
-               while (*cur == ' ')
-                       cur++;
-               if (*cur == 0)
-                       return (0);
-               i = 0;
-               while ((*cur != '\n') && (*cur != '\r')) {
-                       if (i < 150)
-                               filename[i++] = *cur;
-                       cur++;
-                       if (*cur == 0)
-                               return (0);
-               }
-               filename[i] = 0;
-               if ((*cur != '\n') && (*cur != '\r'))
-                       return (0);
-               while ((*cur == '\n') || (*cur == '\r'))
-                       cur++;
-       }
-       if (callback != NULL) {
-               callback(userData, filename, attrib, owner, group, size,
-                        links, year, month, day, minute);
-       }
-       return (cur - list);
-}
-
-/*
- * listFtp
- */
-int listFtp(ftpListCallback callback, void *userData)
-{
-       char buf[4096 + 1];
-       int len, res;
-       int index = 0, base;
-       fd_set rfd, efd;
-       struct timeval tv;
-
-       dataFd = dataConnectFtp();
-
-       len = snprintf(buf, sizeof(buf), "LIST -L\r\n");
-#ifdef DEBUG_FTP
-       printf(buf);
-#endif
-       res = send(ftpFd, buf, len, 0);
-       if (res < 0) {
-               close(dataFd);
-               dataFd = -1;
-               return (res);
-       }
-       res = readFtpResponse(buf, sizeof(buf) - 1);
-       if (res != 1) {
-               close(dataFd);
-               dataFd = -1;
-               return (-res);
-       }
-
-       do {
-               tv.tv_sec = 1;
-               tv.tv_usec = 0;
-               FD_ZERO(&rfd);
-               FD_SET(dataFd, &rfd);
-               FD_ZERO(&efd);
-               FD_SET(dataFd, &efd);
-               res = select(dataFd + 1, &rfd, NULL, &efd, &tv);
-               if (res < 0) {
-#ifdef DEBUG_FTP
-                       perror("select");
-#endif
-                       close(dataFd);
-                       dataFd = -1;
-                       return (-1);
-               }
-               if (res == 0) {
-                       res = checkFtpResponse();
-                       if (res < 0) {
-                               close(dataFd);
-                               dataFd = -1;
-                               dataFd = -1;
-                               return (-1);
-                       }
-                       if (res == 2) {
-                               close(dataFd);
-                               dataFd = -1;
-                               return (0);
-                       }
-
-                       continue;
-               }
-
-               if ((len =
-                    read(dataFd, &buf[index],
-                         sizeof(buf) - (index + 1))) < 0) {
-#ifdef DEBUG_FTP
-                       perror("read");
-#endif
-                       close(dataFd);
-                       dataFd = -1;
-                       dataFd = -1;
-                       return (-1);
-               }
-#ifdef DEBUG_FTP
-               write(1, &buf[index], len);
-#endif
-               index += len;
-               buf[index] = 0;
-               base = 0;
-               do {
-                       res = parseListFtp(&buf[base], callback, userData);
-                       base += res;
-               } while (res > 0);
-
-               memmove(&buf[0], &buf[base], index - base);
-               index -= base;
-       } while (len != 0);
-       dataConnectEndFtp();
-       return (0);
-}
-
-/*
- * getFtpSocket:
- */
-
-int getFtpSocket(const char *filename)
-{
-       char buf[300];
-       int res, len;
-       if (filename == NULL)
-               return (-1);
-       dataFd = dataConnectFtp();
-
-       len = snprintf(buf, sizeof(buf), "TYPE I\r\n");
-#ifdef DEBUG_FTP
-       printf(buf);
-#endif
-       res = send(ftpFd, buf, len, 0);
-       if (res < 0) {
-               close(dataFd);
-               dataFd = -1;
-               return (res);
-       }
-       res = readFtpResponse(buf, sizeof(buf) - 1);
-       if (res != 2) {
-               close(dataFd);
-               dataFd = -1;
-               return (-res);
-       }
-       len = snprintf(buf, sizeof(buf), "RETR %s\r\n", filename);
-#ifdef DEBUG_FTP
-       printf(buf);
-#endif
-       res = send(ftpFd, buf, len, 0);
-       if (res < 0) {
-               close(dataFd);
-               dataFd = -1;
-               return (res);
-       }
-       res = readFtpResponse(buf, sizeof(buf) - 1);
-       if (res != 1) {
-               close(dataFd);
-               dataFd = -1;
-               return (-res);
-       }
-       return (dataFd);
-}
-
-/*
- * closeFtpSocket
- */
-
-int closeFtpSocket()
-{
-       return (dataConnectEndFtp());
-}
-
-/*
- * listFtp
- */
-int getFtp(ftpDataCallback callback, void *userData, const char *filename)
-{
-       char buf[4096];
-       int len = 0, res;
-       fd_set rfd;
-       struct timeval tv;
-
-       if (filename == NULL)
-               return (-1);
-       if (callback == NULL)
-               return (-1);
-       if (getFtpSocket(filename) < 0)
-               return (-1);
-
-       do {
-               tv.tv_sec = 1;
-               tv.tv_usec = 0;
-               FD_ZERO(&rfd);
-               FD_SET(dataFd, &rfd);
-               res = select(dataFd + 1, &rfd, NULL, NULL, &tv);
-               if (res < 0) {
-#ifdef DEBUG_FTP
-                       perror("select");
-#endif
-                       close(dataFd);
-                       dataFd = -1;
-                       return (-1);
-               }
-               if (res == 0) {
-                       res = checkFtpResponse();
-                       if (res < 0) {
-                               close(dataFd);
-                               dataFd = -1;
-                               dataFd = -1;
-                               return (-1);
-                       }
-                       if (res == 2) {
-                               close(dataFd);
-                               dataFd = -1;
-                               return (0);
-                       }
-
-                       continue;
-               }
-               if ((len = read(dataFd, &buf, sizeof(buf))) < 0) {
-                       callback(userData, buf, len);
-                       close(dataFd);
-                       dataFd = -1;
-                       ftpFd = -1;
-                       return (-1);
-               }
-               callback(userData, buf, len);
-       } while (len != 0);
-
-       return (closeFtpSocket());
-}
-
-/*
- * Disconnect from the FTP server.
- */
-
-int disconnectFtp(void)
-{
-       if (ftpFd < 0)
-               return (-1);
-       sendQuit();
-       close(ftpFd);
-       ftpFd = -1;
-       ftpFd = -1;
-       return (0);
-}
diff --git a/ftp.h b/ftp.h
deleted file mode 100644 (file)
index b158eba..0000000
--- a/ftp.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * ftp.h: interface for basic handling of an FTP command connection
- *        to check for directory availability. No transfer is needed.
- *
- *  Reference: RFC 959
- *
- *  $Id$
- */
-
-#ifndef __MIRRORS_FTP_H__
-#define __MIRRORS_FTP_H__
-typedef void (*ftpListCallback) (void *userData,
-                                const char *filename, const char *attrib,
-                                const char *owner, const char *group,
-                                unsigned long size, int links, int year,
-                                const char *month, int day, int minute);
-
-typedef void (*ftpDataCallback) (void *userData,
-                                const char *data, int len);
-
-
-extern void initFtp(void);
-extern int connectFtp(const char *server, int port);
-extern int changeFtpDirectory(char *directory);
-extern int disconnectFtp(void);
-int getFtp(ftpDataCallback, void *, const char *);
-
-#endif                         /* __MIRRORS_FTP_H__ */
index e9de238..1a83534 100644 (file)
@@ -1,19 +1,38 @@
 #!/bin/sh
-#
 # install - install a program, script, or datafile
-# This comes from X11R5 (mit/util/scripts/install.sh).
+
+scriptversion=2005-02-02.21
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
 #
-# Copyright 1991 by the Massachusetts Institute of Technology
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
-# Permission to use, copy, modify, distribute, and sell this software and its
-# documentation for any purpose is hereby granted without fee, provided that
-# the above copyright notice appear in all copies and that both that
-# copyright notice and this permission notice appear in supporting
-# documentation, and that the name of M.I.T. not be used in advertising or
-# publicity pertaining to distribution of the software without specific,
-# written prior permission.  M.I.T. makes no representations about the
-# suitability of this software for any purpose.  It is provided "as is"
-# without express or implied warranty.
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
 #
 # Calling this script install-sh is preferred over install.sh, to prevent
 # `make' implicit rules from creating a file called install from it
 # from scratch.  It can only install one file at a time, a restriction
 # shared with many OS's install programs.
 
-
 # set DOITPROG to echo to test this script
 
 # Don't use :- since 4.3BSD and earlier shells don't like it.
 doit="${DOITPROG-}"
 
-
 # put in absolute paths if you don't have them in your path; or use env. vars.
 
 mvprog="${MVPROG-mv}"
@@ -41,211 +58,266 @@ stripprog="${STRIPPROG-strip}"
 rmprog="${RMPROG-rm}"
 mkdirprog="${MKDIRPROG-mkdir}"
 
-transformbasename=""
-transform_arg=""
-instcmd="$mvprog"
 chmodcmd="$chmodprog 0755"
-chowncmd=""
-chgrpcmd=""
-stripcmd=""
+chowncmd=
+chgrpcmd=
+stripcmd=
 rmcmd="$rmprog -f"
 mvcmd="$mvprog"
-src=""
-dst=""
-dir_arg=""
-
-while [ x"$1" != x ]; do
-    case $1 in
-       -c) instcmd="$cpprog"
-           shift
-           continue;;
-
-       -d) dir_arg=true
-           shift
-           continue;;
-
-       -m) chmodcmd="$chmodprog $2"
-           shift
-           shift
-           continue;;
-
-       -o) chowncmd="$chownprog $2"
-           shift
-           shift
-           continue;;
-
-       -g) chgrpcmd="$chgrpprog $2"
-           shift
-           shift
-           continue;;
-
-       -s) stripcmd="$stripprog"
-           shift
-           continue;;
-
-       -t=*) transformarg=`echo $1 | sed 's/-t=//'`
-           shift
-           continue;;
-
-       -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
-           shift
-           continue;;
-
-       *)  if [ x"$src" = x ]
-           then
-               src=$1
-           else
-               # this colon is to work around a 386BSD /bin/sh bug
-               :
-               dst=$1
-           fi
-           shift
-           continue;;
-    esac
-done
-
-if [ x"$src" = x ]
-then
-       echo "install:  no input file specified"
-       exit 1
-else
-       true
-fi
-
-if [ x"$dir_arg" != x ]; then
-       dst=$src
-       src=""
-       
-       if [ -d $dst ]; then
-               instcmd=:
-               chmodcmd=""
-       else
-               instcmd=mkdir
-       fi
-else
-
-# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
-# might cause directories to be created, which would be especially bad 
-# if $src (and thus $dsttmp) contains '*'.
-
-       if [ -f $src -o -d $src ]
-       then
-               true
-       else
-               echo "install:  $src does not exist"
-               exit 1
-       fi
-       
-       if [ x"$dst" = x ]
-       then
-               echo "install:  no destination specified"
-               exit 1
-       else
-               true
-       fi
-
-# If destination is a directory, append the input filename; if your system
-# does not like double slashes in filenames, you may need to add some logic
-
-       if [ -d $dst ]
-       then
-               dst="$dst"/`basename $src`
-       else
-               true
-       fi
-fi
-
-## this sed command emulates the dirname command
-dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
-
-# Make sure that the destination directory exists.
-#  this part is taken from Noah Friedman's mkinstalldirs script
-
-# Skip lots of stat calls in the usual case.
-if [ ! -d "$dstdir" ]; then
-defaultIFS='   
-'
-IFS="${IFS-${defaultIFS}}"
-
-oIFS="${IFS}"
-# Some sh's can't handle IFS=/ for some reason.
-IFS='%'
-set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
-IFS="${oIFS}"
-
-pathcomp=''
-
-while [ $# -ne 0 ] ; do
-       pathcomp="${pathcomp}${1}"
+src=
+dst=
+dir_arg=
+dstarg=
+no_target_directory=
+
+usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+-c         (ignored)
+-d         create directories instead of installing files.
+-g GROUP   $chgrpprog installed files to GROUP.
+-m MODE    $chmodprog installed files to MODE.
+-o USER    $chownprog installed files to USER.
+-s         $stripprog installed files.
+-t DIRECTORY  install into DIRECTORY.
+-T         report an error if DSTFILE is a directory.
+--help     display this help and exit.
+--version  display version info and exit.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+"
+
+while test -n "$1"; do
+  case $1 in
+    -c) shift
+        continue;;
+
+    -d) dir_arg=true
+        shift
+        continue;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+        shift
+        shift
+        continue;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) chmodcmd="$chmodprog $2"
+        shift
+        shift
+        continue;;
+
+    -o) chowncmd="$chownprog $2"
+        shift
+        shift
+        continue;;
+
+    -s) stripcmd=$stripprog
+        shift
+        continue;;
+
+    -t) dstarg=$2
        shift
+       shift
+       continue;;
 
-       if [ ! -d "${pathcomp}" ] ;
-        then
-               $mkdirprog "${pathcomp}"
-       else
-               true
-       fi
-
-       pathcomp="${pathcomp}/"
+    -T) no_target_directory=true
+       shift
+       continue;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    *)  # When -d is used, all remaining arguments are directories to create.
+       # When -t is used, the destination is already specified.
+       test -n "$dir_arg$dstarg" && break
+        # Otherwise, the last argument is the destination.  Remove it from $@.
+       for arg
+       do
+          if test -n "$dstarg"; then
+           # $@ is not empty: it contains at least $arg.
+           set fnord "$@" "$dstarg"
+           shift # fnord
+         fi
+         shift # arg
+         dstarg=$arg
+       done
+       break;;
+  esac
 done
-fi
-
-if [ x"$dir_arg" != x ]
-then
-       $doit $instcmd $dst &&
-
-       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
-       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
-       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
-       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
-else
-
-# If we're going to rename the final executable, determine the name now.
-
-       if [ x"$transformarg" = x ] 
-       then
-               dstfile=`basename $dst`
-       else
-               dstfile=`basename $dst $transformbasename | 
-                       sed $transformarg`$transformbasename
-       fi
-
-# don't allow the sed command to completely eliminate the filename
-
-       if [ x"$dstfile" = x ] 
-       then
-               dstfile=`basename $dst`
-       else
-               true
-       fi
-
-# Make a temp file name in the proper directory.
-
-       dsttmp=$dstdir/#inst.$$#
 
-# Move or copy the file name to the temp name
-
-       $doit $instcmd $src $dsttmp &&
-
-       trap "rm -f ${dsttmp}" 0 &&
-
-# and set any options; do chmod last to preserve setuid bits
-
-# If any of these fail, we abort the whole thing.  If we want to
-# ignore errors from any of these, just make sure not to ignore
-# errors from the above "$doit $instcmd $src $dsttmp" command.
-
-       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
-       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
-       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
-       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
-
-# Now rename the file to the real destination.
-
-       $doit $rmcmd -f $dstdir/$dstfile &&
-       $doit $mvcmd $dsttmp $dstdir/$dstfile 
+if test -z "$1"; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call `install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
 
-fi &&
+for src
+do
+  # Protect names starting with `-'.
+  case $src in
+    -*) src=./$src ;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    src=
+
+    if test -d "$dst"; then
+      mkdircmd=:
+      chmodcmd=
+    else
+      mkdircmd=$mkdirprog
+    fi
+  else
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dstarg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+
+    dst=$dstarg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst ;;
+    esac
 
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+       echo "$0: $dstarg: Is a directory" >&2
+       exit 1
+      fi
+      dst=$dst/`basename "$src"`
+    fi
+  fi
+
+  # This sed command emulates the dirname command.
+  dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
+
+  # Make sure that the destination directory exists.
+
+  # Skip lots of stat calls in the usual case.
+  if test ! -d "$dstdir"; then
+    defaultIFS='
+        '
+    IFS="${IFS-$defaultIFS}"
+
+    oIFS=$IFS
+    # Some sh's can't handle IFS=/ for some reason.
+    IFS='%'
+    set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+    shift
+    IFS=$oIFS
+
+    pathcomp=
+
+    while test $# -ne 0 ; do
+      pathcomp=$pathcomp$1
+      shift
+      if test ! -d "$pathcomp"; then
+        $mkdirprog "$pathcomp"
+       # mkdir can fail with a `File exist' error in case several
+       # install-sh are creating the directory concurrently.  This
+       # is OK.
+       test -d "$pathcomp" || exit
+      fi
+      pathcomp=$pathcomp/
+    done
+  fi
+
+  if test -n "$dir_arg"; then
+    $doit $mkdircmd "$dst" \
+      && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
+      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
+      && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
+      && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
+
+  else
+    dstfile=`basename "$dst"`
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+    trap '(exit $?); exit' 1 2 13 15
+
+    # Copy the file name to the temp name.
+    $doit $cpprog "$src" "$dsttmp" &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
+      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
+      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
+      && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
+
+    # Now rename the file to the real destination.
+    { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
+      || {
+          # The rename failed, perhaps because mv can't rename something else
+          # to itself, or perhaps because mv is so ancient that it does not
+          # support -f.
+
+          # Now remove or move aside any old file at destination location.
+          # We try this two ways since rm can't unlink itself on some
+          # systems and the destination file might be busy for other
+          # reasons.  In this case, the final cleanup might fail but the new
+          # file should still install successfully.
+          {
+            if test -f "$dstdir/$dstfile"; then
+              $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
+              || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
+              || {
+                echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+                (exit 1); exit 1
+              }
+            else
+              :
+            fi
+          } &&
+
+          # Now rename the file to the real destination.
+          $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+        }
+    }
+  fi || { (exit 1); exit 1; }
+done
 
-exit 0
+# The final little trick to "correctly" pass the exit status to the exit trap.
+{
+  (exit 0); exit 0
+}
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/libmpdclient.c b/libmpdclient.c
deleted file mode 100644 (file)
index d1b5604..0000000
+++ /dev/null
@@ -1,1517 +0,0 @@
-/* libmpdclient
-   (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu)
-   This project's homepage is: http://www.musicpd.org
-  
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions
-   are met:
-                                                                                
-   - Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-                                                                                
-   - Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-                                                                                
-   - Neither the name of the Music Player Daemon nor the names of its
-   contributors may be used to endorse or promote products derived from
-   this software without specific prior written permission.
-                                                                                
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
-   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-*/
-
-#include "libmpdclient.h"
-
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <sys/param.h>
-#include <string.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <fcntl.h>
-
-#ifndef MPD_NO_IPV6
-#ifdef AF_INET6
-#define MPD_HAVE_IPV6
-#endif
-#endif
-
-#define COMMAND_LIST   1
-#define COMMAND_LIST_OK        2
-
-#ifdef MPD_HAVE_IPV6
-int mpd_ipv6Supported()
-{
-       int s;
-       s = socket(AF_INET6, SOCK_STREAM, 0);
-       if (s == -1)
-               return 0;
-       close(s);
-       return 1;
-}
-#endif
-
-
-char *mpd_sanitizeArg(const char *arg)
-{
-       size_t i;
-       int count = 0;
-       char *ret;
-
-       for (i = 0; i < strlen(arg); i++) {
-               if (arg[i] == '"' || arg[i] == '\\')
-                       count++;
-       }
-
-       ret = malloc(strlen(arg) + count + 1);
-
-       count = 0;
-       for (i = 0; i < strlen(arg) + 1; i++) {
-               if (arg[i] == '"' || arg[i] == '\\') {
-                       ret[i + count] = '\\';
-                       count++;
-               }
-               ret[i + count] = arg[i];
-       }
-
-       return ret;
-}
-
-mpd_ReturnElement *mpd_newReturnElement(const char *name,
-                                       const char *value)
-{
-       mpd_ReturnElement *ret = malloc(sizeof(mpd_ReturnElement));
-
-       ret->name = strdup(name);
-       ret->value = strdup(value);
-
-       return ret;
-}
-
-void mpd_freeReturnElement(mpd_ReturnElement * re)
-{
-       free(re->name);
-       free(re->value);
-       free(re);
-}
-
-void mpd_setConnectionTimeout(mpd_Connection * connection, float timeout)
-{
-       connection->timeout.tv_sec = (int) timeout;
-       connection->timeout.tv_usec = (int) (timeout * 1e6 -
-                                            connection->timeout.tv_sec *
-                                            1000000 + 0.5);
-}
-
-mpd_Connection *mpd_newConnection(const char *host, int port,
-                                 float timeout)
-{
-       int err;
-       struct hostent *he;
-       struct sockaddr *dest;
-#ifdef HAVE_SOCKLEN_T
-       socklen_t destlen;
-#else
-       int destlen;
-#endif
-       struct sockaddr_in sin;
-       char *rt;
-       char *output;
-       mpd_Connection *connection = malloc(sizeof(mpd_Connection));
-       struct timeval tv;
-       fd_set fds;
-#ifdef MPD_HAVE_IPV6
-       struct sockaddr_in6 sin6;
-#endif
-       strcpy(connection->buffer, "");
-       connection->buflen = 0;
-       connection->bufstart = 0;
-       strcpy(connection->errorStr, "");
-       connection->error = 0;
-       connection->doneProcessing = 0;
-       connection->commandList = 0;
-       connection->listOks = 0;
-       connection->doneListOk = 0;
-       connection->returnElement = NULL;
-
-       if (!(he = gethostbyname(host))) {
-               snprintf(connection->errorStr, MPD_BUFFER_MAX_LENGTH,
-                        "host \"%s\" not found", host);
-               connection->error = MPD_ERROR_UNKHOST;
-               return connection;
-       }
-
-       memset(&sin, 0, sizeof(struct sockaddr_in));
-       /*dest.sin_family = he->h_addrtype; */
-       sin.sin_family = AF_INET;
-       sin.sin_port = htons(port);
-#ifdef MPD_HAVE_IPV6
-       memset(&sin6, 0, sizeof(struct sockaddr_in6));
-       sin6.sin6_family = AF_INET6;
-       sin6.sin6_port = htons(port);
-#endif
-       switch (he->h_addrtype) {
-       case AF_INET:
-               memcpy((char *) &sin.sin_addr.s_addr, (char *) he->h_addr,
-                      he->h_length);
-               dest = (struct sockaddr *) &sin;
-               destlen = sizeof(struct sockaddr_in);
-               break;
-#ifdef MPD_HAVE_IPV6
-       case AF_INET6:
-               if (!mpd_ipv6Supported()) {
-                       strcpy(connection->errorStr,
-                              "no IPv6 suuport but a "
-                              "IPv6 address found\n");
-                       connection->error = MPD_ERROR_SYSTEM;
-                       return connection;
-               }
-               memcpy((char *) &sin6.sin6_addr.s6_addr,
-                      (char *) he->h_addr, he->h_length);
-               dest = (struct sockaddr *) &sin6;
-               destlen = sizeof(struct sockaddr_in6);
-               break;
-#endif
-       default:
-               strcpy(connection->errorStr,
-                      "address type is not IPv4 or " "IPv6\n");
-               connection->error = MPD_ERROR_SYSTEM;
-               return connection;
-               break;
-       }
-
-       if ((connection->sock =
-            socket(dest->sa_family, SOCK_STREAM, 0)) < 0) {
-               strcpy(connection->errorStr, "problems creating socket");
-               connection->error = MPD_ERROR_SYSTEM;
-               return connection;
-       }
-
-       mpd_setConnectionTimeout(connection, timeout);
-
-       /* connect stuff */
-       {
-               int flags = fcntl(connection->sock, F_GETFL, 0);
-               fcntl(connection->sock, F_SETFL, flags | O_NONBLOCK);
-
-               if (connect(connection->sock, dest, destlen) < 0
-                   && errno != EINPROGRESS) {
-                       snprintf(connection->errorStr,
-                                MPD_BUFFER_MAX_LENGTH,
-                                "problems connecting to \"%s\" on port"
-                                " %i", host, port);
-                       connection->error = MPD_ERROR_CONNPORT;
-                       return connection;
-               }
-       }
-
-       while (!(rt = strstr(connection->buffer, "\n"))) {
-               tv.tv_sec = connection->timeout.tv_sec;
-               tv.tv_usec = connection->timeout.tv_usec;
-               FD_ZERO(&fds);
-               FD_SET(connection->sock, &fds);
-               if ((err =
-                    select(connection->sock + 1, &fds, NULL, NULL,
-                           &tv)) == 1) {
-                       int readed;
-                       readed = recv(connection->sock,
-                                     &(connection->
-                                       buffer[connection->buflen]),
-                                     MPD_BUFFER_MAX_LENGTH -
-                                     connection->buflen, 0);
-                       if (readed <= 0) {
-                               snprintf(connection->errorStr,
-                                        MPD_BUFFER_MAX_LENGTH,
-                                        "problems getting a response from"
-                                        " \"%s\" on port %i", host, port);
-                               connection->error = MPD_ERROR_NORESPONSE;
-                               return connection;
-                       }
-                       connection->buflen += readed;
-                       connection->buffer[connection->buflen] = '\0';
-                       tv.tv_sec = connection->timeout.tv_sec;
-                       tv.tv_usec = connection->timeout.tv_usec;
-               } else if (err < 0) {
-                       switch (errno) {
-                       case EINTR:
-                               continue;
-                       default:
-                               snprintf(connection->errorStr,
-                                        MPD_BUFFER_MAX_LENGTH,
-                                        "problems connecting to \"%s\" on port"
-                                        " %i", host, port);
-                               connection->error = MPD_ERROR_CONNPORT;
-                               return connection;
-                       }
-               } else {
-                       snprintf(connection->errorStr,
-                                MPD_BUFFER_MAX_LENGTH,
-                                "timeout in attempting to get a response from"
-                                " \"%s\" on port %i", host, port);
-                       connection->error = MPD_ERROR_NORESPONSE;
-                       return connection;
-               }
-       }
-
-       *rt = '\0';
-       output = strdup(connection->buffer);
-       strcpy(connection->buffer, rt + 1);
-       connection->buflen = strlen(connection->buffer);
-
-       if (strncmp
-           (output, MPD_WELCOME_MESSAGE, strlen(MPD_WELCOME_MESSAGE))) {
-               free(output);
-               snprintf(connection->errorStr, MPD_BUFFER_MAX_LENGTH,
-                        "mpd not running on port %i on host \"%s\"", port,
-                        host);
-               connection->error = MPD_ERROR_NOTMPD;
-               return connection;
-       }
-
-       {
-               char *test;
-               char *version[3];
-               char *tmp = &output[strlen(MPD_WELCOME_MESSAGE)];
-               char *search = ".";
-               int i;
-
-               for (i = 0; i < 3; i++) {
-                       char *tok;
-                       if (i == 3)
-                               search = " ";
-                       version[i] = strtok_r(tmp, search, &tok);
-                       if (!version[i]) {
-                               free(output);
-                               snprintf(connection->errorStr,
-                                        MPD_BUFFER_MAX_LENGTH,
-                                        "error parsing version number at "
-                                        "\"%s\"",
-                                        &output[strlen
-                                                (MPD_WELCOME_MESSAGE)]);
-                               connection->error = MPD_ERROR_NOTMPD;
-                               return connection;
-                       }
-                       connection->version[i] =
-                           strtol(version[i], &test, 10);
-                       if (version[i] == test || *test != '\0') {
-                               free(output);
-                               snprintf(connection->errorStr,
-                                        MPD_BUFFER_MAX_LENGTH,
-                                        "error parsing version number at "
-                                        "\"%s\"",
-                                        &output[strlen
-                                                (MPD_WELCOME_MESSAGE)]);
-                               connection->error = MPD_ERROR_NOTMPD;
-                               return connection;
-                       }
-                       tmp = NULL;
-               }
-       }
-
-       free(output);
-
-       connection->doneProcessing = 1;
-
-       return connection;
-}
-
-void mpd_clearError(mpd_Connection * connection)
-{
-       connection->error = 0;
-       connection->errorStr[0] = '\0';
-}
-
-void mpd_closeConnection(mpd_Connection * connection)
-{
-       close(connection->sock);
-       if (connection->returnElement)
-               free(connection->returnElement);
-       free(connection);
-}
-
-void mpd_executeCommand(mpd_Connection * connection, char *command)
-{
-       int ret;
-       struct timeval tv;
-       fd_set fds;
-       char *commandPtr = command;
-       int commandLen = strlen(command);
-
-       if (!connection->doneProcessing && !connection->commandList) {
-               strcpy(connection->errorStr,
-                      "not done processing current command");
-               connection->error = 1;
-               return;
-       }
-
-       mpd_clearError(connection);
-
-       FD_ZERO(&fds);
-       FD_SET(connection->sock, &fds);
-       tv.tv_sec = connection->timeout.tv_sec;
-       tv.tv_usec = connection->timeout.tv_usec;
-
-       while ((ret =
-               select(connection->sock + 1, NULL, &fds, NULL, &tv) == 1)
-              || (ret == -1 && errno == EINTR)) {
-               ret =
-                   send(connection->sock, commandPtr, commandLen,
-                        MSG_DONTWAIT);
-               if (ret <= 0) {
-                       if (ret == EAGAIN || ret == EINTR)
-                               continue;
-                       snprintf(connection->errorStr,
-                                MPD_BUFFER_MAX_LENGTH,
-                                "problems giving command \"%s\"",
-                                command);
-                       connection->error = MPD_ERROR_SENDING;
-                       return;
-               } else {
-                       commandPtr += ret;
-                       commandLen -= ret;
-               }
-
-               if (commandLen <= 0)
-                       break;
-       }
-
-       if (commandLen > 0) {
-               perror("");
-               snprintf(connection->errorStr, MPD_BUFFER_MAX_LENGTH,
-                        "timeout sending command \"%s\"", command);
-               connection->error = MPD_ERROR_TIMEOUT;
-               return;
-       }
-
-       if (!connection->commandList)
-               connection->doneProcessing = 0;
-       else if (connection->commandList == COMMAND_LIST_OK) {
-               connection->listOks++;
-       }
-}
-
-void mpd_getNextReturnElement(mpd_Connection * connection)
-{
-       char *output = NULL;
-       char *rt = NULL;
-       char *name = NULL;
-       char *value = NULL;
-       fd_set fds;
-       struct timeval tv;
-       char *tok = NULL;
-       int readed;
-       char *bufferCheck = NULL;
-       int err;
-
-       if (connection->returnElement)
-               mpd_freeReturnElement(connection->returnElement);
-       connection->returnElement = NULL;
-
-       if (connection->doneProcessing || (connection->listOks &&
-                                          connection->doneListOk)) {
-               strcpy(connection->errorStr,
-                      "already done processing current command");
-               connection->error = 1;
-               return;
-       }
-
-       bufferCheck = connection->buffer + connection->bufstart;
-       while (connection->bufstart >= connection->buflen ||
-              !(rt = strstr(bufferCheck, "\n"))) {
-               if (connection->buflen >= MPD_BUFFER_MAX_LENGTH) {
-                       memmove(connection->buffer,
-                               connection->buffer +
-                               connection->bufstart,
-                               connection->buflen - connection->bufstart +
-                               1);
-                       bufferCheck -= connection->bufstart;
-                       connection->buflen -= connection->bufstart;
-                       connection->bufstart = 0;
-               }
-               if (connection->buflen >= MPD_BUFFER_MAX_LENGTH) {
-                       strcpy(connection->errorStr, "buffer overrun");
-                       connection->error = MPD_ERROR_BUFFEROVERRUN;
-                       connection->doneProcessing = 1;
-                       connection->doneListOk = 0;
-                       return;
-               }
-               bufferCheck += connection->buflen - connection->bufstart;
-               tv.tv_sec = connection->timeout.tv_sec;
-               tv.tv_usec = connection->timeout.tv_usec;
-               FD_ZERO(&fds);
-               FD_SET(connection->sock, &fds);
-               if ((err =
-                    select(connection->sock + 1, &fds, NULL, NULL,
-                           &tv) == 1)) {
-                       readed =
-                           recv(connection->sock,
-                                connection->buffer + connection->buflen,
-                                MPD_BUFFER_MAX_LENGTH -
-                                connection->buflen, MSG_DONTWAIT);
-                       if (readed < 0
-                           && (errno == EAGAIN || errno == EINTR)) {
-                               continue;
-                       }
-                       if (readed <= 0) {
-                               strcpy(connection->errorStr,
-                                      "connection" " closed");
-                               connection->error = MPD_ERROR_CONNCLOSED;
-                               connection->doneProcessing = 1;
-                               connection->doneListOk = 0;
-                               return;
-                       }
-                       connection->buflen += readed;
-                       connection->buffer[connection->buflen] = '\0';
-               } else if (err < 0 && errno == EINTR)
-                       continue;
-               else {
-                       strcpy(connection->errorStr, "connection timeout");
-                       connection->error = MPD_ERROR_TIMEOUT;
-                       connection->doneProcessing = 1;
-                       connection->doneListOk = 0;
-                       return;
-               }
-       }
-
-       *rt = '\0';
-       output = connection->buffer + connection->bufstart;
-       connection->bufstart = rt - connection->buffer + 1;
-
-       if (strcmp(output, "OK") == 0) {
-               if (connection->listOks > 0) {
-                       strcpy(connection->errorStr,
-                              "expected more list_OK's");
-                       connection->error = 1;
-               }
-               connection->listOks = 0;
-               connection->doneProcessing = 1;
-               connection->doneListOk = 0;
-               return;
-       }
-
-       if (strcmp(output, "list_OK") == 0) {
-               if (!connection->listOks) {
-                       strcpy(connection->errorStr,
-                              "got an unexpected list_OK");
-                       connection->error = 1;
-               } else {
-                       connection->doneListOk = 1;
-                       connection->listOks--;
-               }
-               return;
-       }
-
-       if (strncmp(output, "ACK", strlen("ACK")) == 0) {
-               char *test;
-               char *needle;
-               int val;
-
-               strcpy(connection->errorStr, output);
-               connection->error = MPD_ERROR_ACK;
-               connection->errorCode = MPD_ACK_ERROR_UNK;
-               connection->errorAt = MPD_ERROR_AT_UNK;
-               connection->doneProcessing = 1;
-               connection->doneListOk = 0;
-
-               needle = strchr(output, '[');
-               if (!needle)
-                       return;
-               val = strtol(needle + 1, &test, 10);
-               if (*test != '@')
-                       return;
-               connection->errorCode = val;
-               val = strtol(test + 1, &test, 10);
-               if (*test != ']')
-                       return;
-               connection->errorAt = val;
-               return;
-       }
-
-       name = strtok_r(output, ":", &tok);
-       if (name && (value = strtok_r(NULL, "", &tok)) && value[0] == ' ') {
-               connection->returnElement =
-                   mpd_newReturnElement(name, &(value[1]));
-       } else {
-               if (!name || !value) {
-                       snprintf(connection->errorStr,
-                                MPD_BUFFER_MAX_LENGTH,
-                                "error parsing: %s", output);
-               } else {
-                       snprintf(connection->errorStr,
-                                MPD_BUFFER_MAX_LENGTH,
-                                "error parsing: %s:%s", name, value);
-               }
-               connection->errorStr[MPD_BUFFER_MAX_LENGTH] = '\0';
-               connection->error = 1;
-       }
-}
-
-void mpd_finishCommand(mpd_Connection * connection)
-{
-       while (!connection->doneProcessing) {
-               if (connection->doneListOk)
-                       connection->doneListOk = 0;
-               mpd_getNextReturnElement(connection);
-       }
-}
-
-void mpd_finishListOkCommand(mpd_Connection * connection)
-{
-       while (!connection->doneProcessing && connection->listOks &&
-              !connection->doneListOk) {
-               mpd_getNextReturnElement(connection);
-       }
-}
-
-int mpd_nextListOkCommand(mpd_Connection * connection)
-{
-       mpd_finishListOkCommand(connection);
-       if (!connection->doneProcessing)
-               connection->doneListOk = 0;
-       if (connection->listOks == 0 || connection->doneProcessing)
-               return -1;
-       return 0;
-}
-
-void mpd_sendStatusCommand(mpd_Connection * connection)
-{
-       mpd_executeCommand(connection, "status\n");
-}
-
-mpd_Status *mpd_getStatus(mpd_Connection * connection)
-{
-       mpd_Status *status;
-
-       /*mpd_executeCommand(connection,"status\n");
-
-          if(connection->error) return NULL; */
-
-       if (connection->doneProcessing || (connection->listOks &&
-                                          connection->doneListOk)) {
-               return NULL;
-       }
-
-       if (!connection->returnElement)
-               mpd_getNextReturnElement(connection);
-
-       status = malloc(sizeof(mpd_Status));
-       status->volume = -1;
-       status->repeat = 0;
-       status->random = 0;
-       status->playlist = -1;
-       status->playlistLength = -1;
-       status->state = -1;
-       status->song = 0;
-       status->elapsedTime = 0;
-       status->totalTime = 0;
-       status->bitRate = 0;
-       status->sampleRate = 0;
-       status->bits = 0;
-       status->channels = 0;
-       status->crossfade = -1;
-       status->error = NULL;
-       status->updatingDb = 0;
-
-       if (connection->error) {
-               free(status);
-               return NULL;
-       }
-       while (connection->returnElement) {
-               mpd_ReturnElement *re = connection->returnElement;
-               if (strcmp(re->name, "volume") == 0) {
-                       status->volume = atoi(re->value);
-               } else if (strcmp(re->name, "repeat") == 0) {
-                       status->repeat = atoi(re->value);
-               } else if (strcmp(re->name, "random") == 0) {
-                       status->random = atoi(re->value);
-               } else if (strcmp(re->name, "playlist") == 0) {
-                       status->playlist = strtol(re->value, NULL, 10);
-               } else if (strcmp(re->name, "playlistlength") == 0) {
-                       status->playlistLength = atoi(re->value);
-               } else if (strcmp(re->name, "bitrate") == 0) {
-                       status->bitRate = atoi(re->value);
-               } else if (strcmp(re->name, "state") == 0) {
-                       if (strcmp(re->value, "play") == 0) {
-                               status->state = MPD_STATUS_STATE_PLAY;
-                       } else if (strcmp(re->value, "stop") == 0) {
-                               status->state = MPD_STATUS_STATE_STOP;
-                       } else if (strcmp(re->value, "pause") == 0) {
-                               status->state = MPD_STATUS_STATE_PAUSE;
-                       } else {
-                               status->state = MPD_STATUS_STATE_UNKNOWN;
-                       }
-               } else if (strcmp(re->name, "song") == 0) {
-                       status->song = atoi(re->value);
-               } else if (strcmp(re->name, "songid") == 0) {
-                       status->songid = atoi(re->value);
-               } else if (strcmp(re->name, "time") == 0) {
-                       char *tok;
-                       char *copy;
-                       char *temp;
-                       copy = strdup(re->value);
-                       temp = strtok_r(copy, ":", &tok);
-                       if (temp) {
-                               status->elapsedTime = atoi(temp);
-                               temp = strtok_r(NULL, "", &tok);
-                               if (temp)
-                                       status->totalTime = atoi(temp);
-                       }
-                       free(copy);
-               } else if (strcmp(re->name, "error") == 0) {
-                       status->error = strdup(re->value);
-               } else if (strcmp(re->name, "xfade") == 0) {
-                       status->crossfade = atoi(re->value);
-               } else if (strcmp(re->name, "updating_db") == 0) {
-                       status->updatingDb = atoi(re->value);
-               } else if (strcmp(re->name, "audio") == 0) {
-                       char *tok;
-                       char *copy;
-                       char *temp;
-                       copy = strdup(re->value);
-                       temp = strtok_r(copy, ":", &tok);
-                       if (temp) {
-                               status->sampleRate = atoi(temp);
-                               temp = strtok_r(NULL, ":", &tok);
-                               if (temp) {
-                                       status->bits = atoi(temp);
-                                       temp = strtok_r(NULL, "", &tok);
-                                       if (temp)
-                                               status->channels =
-                                                   atoi(temp);
-                               }
-                       }
-                       free(copy);
-               }
-
-               mpd_getNextReturnElement(connection);
-               if (connection->error) {
-                       free(status);
-                       return NULL;
-               }
-       }
-
-       if (connection->error) {
-               free(status);
-               return NULL;
-       } else if (status->state < 0) {
-               strcpy(connection->errorStr, "state not found");
-               connection->error = 1;
-               free(status);
-               return NULL;
-       }
-
-       return status;
-}
-
-void mpd_freeStatus(mpd_Status * status)
-{
-       if (status->error)
-               free(status->error);
-       free(status);
-}
-
-void mpd_sendStatsCommand(mpd_Connection * connection)
-{
-       mpd_executeCommand(connection, "stats\n");
-}
-
-mpd_Stats *mpd_getStats(mpd_Connection * connection)
-{
-       mpd_Stats *stats;
-
-       /*mpd_executeCommand(connection,"stats\n");
-
-          if(connection->error) return NULL; */
-
-       if (connection->doneProcessing || (connection->listOks &&
-                                          connection->doneListOk)) {
-               return NULL;
-       }
-
-       if (!connection->returnElement)
-               mpd_getNextReturnElement(connection);
-
-       stats = malloc(sizeof(mpd_Stats));
-       stats->numberOfArtists = 0;
-       stats->numberOfAlbums = 0;
-       stats->numberOfSongs = 0;
-       stats->uptime = 0;
-       stats->dbUpdateTime = 0;
-       stats->playTime = 0;
-       stats->dbPlayTime = 0;
-
-       if (connection->error) {
-               free(stats);
-               return NULL;
-       }
-       while (connection->returnElement) {
-               mpd_ReturnElement *re = connection->returnElement;
-               if (strcmp(re->name, "artists") == 0) {
-                       stats->numberOfArtists = atoi(re->value);
-               } else if (strcmp(re->name, "albums") == 0) {
-                       stats->numberOfAlbums = atoi(re->value);
-               } else if (strcmp(re->name, "songs") == 0) {
-                       stats->numberOfSongs = atoi(re->value);
-               } else if (strcmp(re->name, "uptime") == 0) {
-                       stats->uptime = strtol(re->value, NULL, 10);
-               } else if (strcmp(re->name, "db_update") == 0) {
-                       stats->dbUpdateTime = strtol(re->value, NULL, 10);
-               } else if (strcmp(re->name, "playtime") == 0) {
-                       stats->playTime = strtol(re->value, NULL, 10);
-               } else if (strcmp(re->name, "db_playtime") == 0) {
-                       stats->dbPlayTime = strtol(re->value, NULL, 10);
-               }
-
-               mpd_getNextReturnElement(connection);
-               if (connection->error) {
-                       free(stats);
-                       return NULL;
-               }
-       }
-
-       if (connection->error) {
-               free(stats);
-               return NULL;
-       }
-
-       return stats;
-}
-
-void mpd_freeStats(mpd_Stats * stats)
-{
-       free(stats);
-}
-
-void mpd_initSong(mpd_Song * song)
-{
-       song->file = NULL;
-       song->artist = NULL;
-       song->album = NULL;
-       song->track = NULL;
-       song->title = NULL;
-       song->name = NULL;
-       song->time = MPD_SONG_NO_TIME;
-       song->pos = MPD_SONG_NO_NUM;
-       song->id = MPD_SONG_NO_ID;
-}
-
-void mpd_finishSong(mpd_Song * song)
-{
-       if (song->file)
-               free(song->file);
-       if (song->artist)
-               free(song->artist);
-       if (song->album)
-               free(song->album);
-       if (song->title)
-               free(song->title);
-       if (song->track)
-               free(song->track);
-       if (song->name)
-               free(song->name);
-}
-
-mpd_Song *mpd_newSong()
-{
-       mpd_Song *ret = malloc(sizeof(mpd_Song));
-
-       mpd_initSong(ret);
-
-       return ret;
-}
-
-void mpd_freeSong(mpd_Song * song)
-{
-       mpd_finishSong(song);
-       free(song);
-}
-
-mpd_Song *mpd_songDup(mpd_Song * song)
-{
-       mpd_Song *ret = mpd_newSong();
-
-       if (song->file)
-               ret->file = strdup(song->file);
-       if (song->artist)
-               ret->artist = strdup(song->artist);
-       if (song->album)
-               ret->album = strdup(song->album);
-       if (song->title)
-               ret->title = strdup(song->title);
-       if (song->track)
-               ret->track = strdup(song->track);
-       if (song->name)
-               ret->name = strdup(song->name);
-       ret->time = song->time;
-       ret->pos = song->pos;
-       ret->id = song->id;
-
-       return ret;
-}
-
-void mpd_initDirectory(mpd_Directory * directory)
-{
-       directory->path = NULL;
-}
-
-void mpd_finishDirectory(mpd_Directory * directory)
-{
-       if (directory->path)
-               free(directory->path);
-}
-
-mpd_Directory *mpd_newDirectory()
-{
-       mpd_Directory *directory = malloc(sizeof(mpd_Directory));;
-
-       mpd_initDirectory(directory);
-
-       return directory;
-}
-
-void mpd_freeDirectory(mpd_Directory * directory)
-{
-       mpd_finishDirectory(directory);
-
-       free(directory);
-}
-
-mpd_Directory *mpd_directoryDup(mpd_Directory * directory)
-{
-       mpd_Directory *ret = mpd_newDirectory();
-
-       if (directory->path)
-               ret->path = strdup(directory->path);
-
-       return ret;
-}
-
-void mpd_initPlaylistFile(mpd_PlaylistFile * playlist)
-{
-       playlist->path = NULL;
-}
-
-void mpd_finishPlaylistFile(mpd_PlaylistFile * playlist)
-{
-       if (playlist->path)
-               free(playlist->path);
-}
-
-mpd_PlaylistFile *mpd_newPlaylistFile()
-{
-       mpd_PlaylistFile *playlist = malloc(sizeof(mpd_PlaylistFile));
-
-       mpd_initPlaylistFile(playlist);
-
-       return playlist;
-}
-
-void mpd_freePlaylistFile(mpd_PlaylistFile * playlist)
-{
-       mpd_finishPlaylistFile(playlist);
-       free(playlist);
-}
-
-mpd_PlaylistFile *mpd_playlistFileDup(mpd_PlaylistFile * playlist)
-{
-       mpd_PlaylistFile *ret = mpd_newPlaylistFile();
-
-       if (playlist->path)
-               ret->path = strdup(playlist->path);
-
-       return ret;
-}
-
-void mpd_initInfoEntity(mpd_InfoEntity * entity)
-{
-       entity->info.directory = NULL;
-}
-
-void mpd_finishInfoEntity(mpd_InfoEntity * entity)
-{
-       if (entity->info.directory) {
-               if (entity->type == MPD_INFO_ENTITY_TYPE_DIRECTORY) {
-                       mpd_freeDirectory(entity->info.directory);
-               } else if (entity->type == MPD_INFO_ENTITY_TYPE_SONG) {
-                       mpd_freeSong(entity->info.song);
-               } else if (entity->type ==
-                          MPD_INFO_ENTITY_TYPE_PLAYLISTFILE) {
-                       mpd_freePlaylistFile(entity->info.playlistFile);
-               }
-       }
-}
-
-mpd_InfoEntity *mpd_newInfoEntity()
-{
-       mpd_InfoEntity *entity = malloc(sizeof(mpd_InfoEntity));
-
-       mpd_initInfoEntity(entity);
-
-       return entity;
-}
-
-void mpd_freeInfoEntity(mpd_InfoEntity * entity)
-{
-       mpd_finishInfoEntity(entity);
-       free(entity);
-}
-
-void mpd_sendInfoCommand(mpd_Connection * connection, char *command)
-{
-       mpd_executeCommand(connection, command);
-}
-
-mpd_InfoEntity *mpd_getNextInfoEntity(mpd_Connection * connection)
-{
-       mpd_InfoEntity *entity = NULL;
-
-       if (connection->doneProcessing || (connection->listOks &&
-                                          connection->doneListOk)) {
-               return NULL;
-       }
-
-       if (!connection->returnElement)
-               mpd_getNextReturnElement(connection);
-
-       if (connection->returnElement) {
-               if (strcmp(connection->returnElement->name, "file") == 0) {
-                       entity = mpd_newInfoEntity();
-                       entity->type = MPD_INFO_ENTITY_TYPE_SONG;
-                       entity->info.song = mpd_newSong();
-                       entity->info.song->file =
-                           strdup(connection->returnElement->value);
-               } else
-                   if (strcmp
-                       (connection->returnElement->name,
-                        "directory") == 0) {
-                       entity = mpd_newInfoEntity();
-                       entity->type = MPD_INFO_ENTITY_TYPE_DIRECTORY;
-                       entity->info.directory = mpd_newDirectory();
-                       entity->info.directory->path =
-                           strdup(connection->returnElement->value);
-               } else
-                   if (strcmp(connection->returnElement->name, "playlist")
-                       == 0) {
-                       entity = mpd_newInfoEntity();
-                       entity->type = MPD_INFO_ENTITY_TYPE_PLAYLISTFILE;
-                       entity->info.playlistFile = mpd_newPlaylistFile();
-                       entity->info.playlistFile->path =
-                           strdup(connection->returnElement->value);
-               } else {
-                       connection->error = 1;
-                       strcpy(connection->errorStr,
-                              "problem parsing song info");
-                       return NULL;
-               }
-       } else
-               return NULL;
-
-       mpd_getNextReturnElement(connection);
-       while (connection->returnElement) {
-               mpd_ReturnElement *re = connection->returnElement;
-
-               if (strcmp(re->name, "file") == 0)
-                       return entity;
-               else if (strcmp(re->name, "directory") == 0)
-                       return entity;
-               else if (strcmp(re->name, "playlist") == 0)
-                       return entity;
-
-               if (entity->type == MPD_INFO_ENTITY_TYPE_SONG
-                   && strlen(re->value)) {
-                       if (!entity->info.song->artist
-                           && strcmp(re->name, "Artist") == 0) {
-                               entity->info.song->artist =
-                                   strdup(re->value);
-                       } else if (!entity->info.song->album
-                                  && strcmp(re->name, "Album") == 0) {
-                               entity->info.song->album =
-                                   strdup(re->value);
-                       } else if (!entity->info.song->title
-                                  && strcmp(re->name, "Title") == 0) {
-                               entity->info.song->title =
-                                   strdup(re->value);
-                       } else if (!entity->info.song->track
-                                  && strcmp(re->name, "Track") == 0) {
-                               entity->info.song->track =
-                                   strdup(re->value);
-                       } else if (!entity->info.song->name
-                                  && strcmp(re->name, "Name") == 0) {
-                               entity->info.song->name =
-                                   strdup(re->value);
-                       } else if (entity->info.song->time ==
-                                  MPD_SONG_NO_TIME
-                                  && strcmp(re->name, "Time") == 0) {
-                               entity->info.song->time = atoi(re->value);
-                       } else if (entity->info.song->pos ==
-                                  MPD_SONG_NO_NUM
-                                  && strcmp(re->name, "Pos") == 0) {
-                               entity->info.song->pos = atoi(re->value);
-                       } else if (entity->info.song->id == MPD_SONG_NO_ID
-                                  && strcmp(re->name, "Id") == 0) {
-                               entity->info.song->id = atoi(re->value);
-                       }
-               } else if (entity->type == MPD_INFO_ENTITY_TYPE_DIRECTORY) {
-               } else if (entity->type ==
-                          MPD_INFO_ENTITY_TYPE_PLAYLISTFILE) {
-               }
-
-               mpd_getNextReturnElement(connection);
-       }
-
-       return entity;
-}
-
-char *mpd_getNextReturnElementNamed(mpd_Connection * connection,
-                                   const char *name)
-{
-       if (connection->doneProcessing || (connection->listOks &&
-                                          connection->doneListOk)) {
-               return NULL;
-       }
-
-       mpd_getNextReturnElement(connection);
-       while (connection->returnElement) {
-               mpd_ReturnElement *re = connection->returnElement;
-
-               if (strcmp(re->name, name) == 0)
-                       return strdup(re->value);
-               mpd_getNextReturnElement(connection);
-       }
-
-       return NULL;
-}
-
-char *mpd_getNextArtist(mpd_Connection * connection)
-{
-       return mpd_getNextReturnElementNamed(connection, "Artist");
-}
-
-char *mpd_getNextAlbum(mpd_Connection * connection)
-{
-       return mpd_getNextReturnElementNamed(connection, "Album");
-}
-
-void mpd_sendPlaylistInfoCommand(mpd_Connection * connection, int songPos)
-{
-       char *string = malloc(strlen("playlistinfo") + 25);
-       sprintf(string, "playlistinfo \"%i\"\n", songPos);
-       mpd_sendInfoCommand(connection, string);
-       free(string);
-}
-
-void mpd_sendPlaylistIdCommand(mpd_Connection * connection, int id)
-{
-       char *string = malloc(strlen("playlistid") + 25);
-       sprintf(string, "playlistid \"%i\"\n", id);
-       mpd_sendInfoCommand(connection, string);
-       free(string);
-}
-
-void
-mpd_sendPlChangesCommand(mpd_Connection * connection, long long playlist)
-{
-       char *string = malloc(strlen("plchanges") + 25);
-       sprintf(string, "plchanges \"%lld\"\n", playlist);
-       mpd_sendInfoCommand(connection, string);
-       free(string);
-}
-
-void mpd_sendListallCommand(mpd_Connection * connection, const char *dir)
-{
-       char *sDir = mpd_sanitizeArg(dir);
-       char *string = malloc(strlen("listall") + strlen(sDir) + 5);
-       sprintf(string, "listall \"%s\"\n", sDir);
-       mpd_sendInfoCommand(connection, string);
-       free(string);
-       free(sDir);
-}
-
-void
-mpd_sendListallInfoCommand(mpd_Connection * connection, const char *dir)
-{
-       char *sDir = mpd_sanitizeArg(dir);
-       char *string = malloc(strlen("listallinfo") + strlen(sDir) + 5);
-       sprintf(string, "listallinfo \"%s\"\n", sDir);
-       mpd_sendInfoCommand(connection, string);
-       free(string);
-       free(sDir);
-}
-
-void mpd_sendLsInfoCommand(mpd_Connection * connection, const char *dir)
-{
-       char *sDir = mpd_sanitizeArg(dir);
-       char *string = malloc(strlen("lsinfo") + strlen(sDir) + 5);
-       sprintf(string, "lsinfo \"%s\"\n", sDir);
-       mpd_sendInfoCommand(connection, string);
-       free(string);
-       free(sDir);
-}
-
-void mpd_sendCurrentSongCommand(mpd_Connection * connection)
-{
-       mpd_executeCommand(connection, "currentsong\n");
-}
-
-void
-mpd_sendSearchCommand(mpd_Connection * connection, int table,
-                     const char *str)
-{
-       char st[10];
-       char *string;
-       char *sanitStr = mpd_sanitizeArg(str);
-       if (table == MPD_TABLE_ARTIST)
-               strcpy(st, "artist");
-       else if (table == MPD_TABLE_ALBUM)
-               strcpy(st, "album");
-       else if (table == MPD_TABLE_TITLE)
-               strcpy(st, "title");
-       else if (table == MPD_TABLE_FILENAME)
-               strcpy(st, "filename");
-       else {
-               connection->error = 1;
-               strcpy(connection->errorStr, "unknown table for search");
-               return;
-       }
-       string =
-           malloc(strlen("search") + strlen(sanitStr) + strlen(st) + 6);
-       sprintf(string, "search %s \"%s\"\n", st, sanitStr);
-       mpd_sendInfoCommand(connection, string);
-       free(string);
-       free(sanitStr);
-}
-
-void
-mpd_sendFindCommand(mpd_Connection * connection, int table,
-                   const char *str)
-{
-       char st[10];
-       char *string;
-       char *sanitStr = mpd_sanitizeArg(str);
-       if (table == MPD_TABLE_ARTIST)
-               strcpy(st, "artist");
-       else if (table == MPD_TABLE_ALBUM)
-               strcpy(st, "album");
-       else if (table == MPD_TABLE_TITLE)
-               strcpy(st, "title");
-       else {
-               connection->error = 1;
-               strcpy(connection->errorStr, "unknown table for find");
-               return;
-       }
-       string =
-           malloc(strlen("find") + strlen(sanitStr) + strlen(st) + 6);
-       sprintf(string, "find %s \"%s\"\n", st, sanitStr);
-       mpd_sendInfoCommand(connection, string);
-       free(string);
-       free(sanitStr);
-}
-
-void
-mpd_sendListCommand(mpd_Connection * connection, int table,
-                   const char *arg1)
-{
-       char st[10];
-       char *string;
-       if (table == MPD_TABLE_ARTIST)
-               strcpy(st, "artist");
-       else if (table == MPD_TABLE_ALBUM)
-               strcpy(st, "album");
-       else {
-               connection->error = 1;
-               strcpy(connection->errorStr, "unknown table for list");
-               return;
-       }
-       if (arg1) {
-               char *sanitArg1 = mpd_sanitizeArg(arg1);
-               string =
-                   malloc(strlen("list") + strlen(sanitArg1) +
-                          strlen(st) + 6);
-               sprintf(string, "list %s \"%s\"\n", st, sanitArg1);
-               free(sanitArg1);
-       } else {
-               string = malloc(strlen("list") + strlen(st) + 3);
-               sprintf(string, "list %s\n", st);
-       }
-       mpd_sendInfoCommand(connection, string);
-       free(string);
-}
-
-void mpd_sendAddCommand(mpd_Connection * connection, const char *file)
-{
-       char *sFile = mpd_sanitizeArg(file);
-       char *string = malloc(strlen("add") + strlen(sFile) + 5);
-       sprintf(string, "add \"%s\"\n", sFile);
-       mpd_executeCommand(connection, string);
-       free(string);
-       free(sFile);
-}
-
-void mpd_sendDeleteCommand(mpd_Connection * connection, int songPos)
-{
-       char *string = malloc(strlen("delete") + 25);
-       sprintf(string, "delete \"%i\"\n", songPos);
-       mpd_sendInfoCommand(connection, string);
-       free(string);
-}
-
-void mpd_sendDeleteIdCommand(mpd_Connection * connection, int id)
-{
-       char *string = malloc(strlen("deleteid") + 25);
-       sprintf(string, "deleteid \"%i\"\n", id);
-       mpd_sendInfoCommand(connection, string);
-       free(string);
-}
-
-void mpd_sendSaveCommand(mpd_Connection * connection, const char *name)
-{
-       char *sName = mpd_sanitizeArg(name);
-       char *string = malloc(strlen("save") + strlen(sName) + 5);
-       sprintf(string, "save \"%s\"\n", sName);
-       mpd_executeCommand(connection, string);
-       free(string);
-       free(sName);
-}
-
-void mpd_sendLoadCommand(mpd_Connection * connection, const char *name)
-{
-       char *sName = mpd_sanitizeArg(name);
-       char *string = malloc(strlen("load") + strlen(sName) + 5);
-       sprintf(string, "load \"%s\"\n", sName);
-       mpd_executeCommand(connection, string);
-       free(string);
-       free(sName);
-}
-
-void mpd_sendRmCommand(mpd_Connection * connection, const char *name)
-{
-       char *sName = mpd_sanitizeArg(name);
-       char *string = malloc(strlen("rm") + strlen(sName) + 5);
-       sprintf(string, "rm \"%s\"\n", sName);
-       mpd_executeCommand(connection, string);
-       free(string);
-       free(sName);
-}
-
-void mpd_sendShuffleCommand(mpd_Connection * connection)
-{
-       mpd_executeCommand(connection, "shuffle\n");
-}
-
-void mpd_sendClearCommand(mpd_Connection * connection)
-{
-       mpd_executeCommand(connection, "clear\n");
-}
-
-void mpd_sendPlayCommand(mpd_Connection * connection, int songPos)
-{
-       char *string = malloc(strlen("play") + 25);
-       sprintf(string, "play \"%i\"\n", songPos);
-       mpd_sendInfoCommand(connection, string);
-       free(string);
-}
-
-void mpd_sendPlayIdCommand(mpd_Connection * connection, int id)
-{
-       char *string = malloc(strlen("playid") + 25);
-       sprintf(string, "playid \"%i\"\n", id);
-       mpd_sendInfoCommand(connection, string);
-       free(string);
-}
-
-void mpd_sendStopCommand(mpd_Connection * connection)
-{
-       mpd_executeCommand(connection, "stop\n");
-}
-
-void mpd_sendPauseCommand(mpd_Connection * connection, int pauseMode)
-{
-       char *string = malloc(strlen("pause") + 25);
-       sprintf(string, "pause \"%i\"\n", pauseMode);
-       mpd_executeCommand(connection, string);
-       free(string);
-}
-
-void mpd_sendNextCommand(mpd_Connection * connection)
-{
-       mpd_executeCommand(connection, "next\n");
-}
-
-void mpd_sendMoveCommand(mpd_Connection * connection, int from, int to)
-{
-       char *string = malloc(strlen("move") + 25);
-       sprintf(string, "move \"%i\" \"%i\"\n", from, to);
-       mpd_sendInfoCommand(connection, string);
-       free(string);
-}
-
-void mpd_sendMoveIdCommand(mpd_Connection * connection, int id, int to)
-{
-       char *string = malloc(strlen("moveid") + 25);
-       sprintf(string, "moveid \"%i\" \"%i\"\n", id, to);
-       mpd_sendInfoCommand(connection, string);
-       free(string);
-}
-
-void mpd_sendSwapCommand(mpd_Connection * connection, int song1, int song2)
-{
-       char *string = malloc(strlen("swap") + 25);
-       sprintf(string, "swap \"%i\" \"%i\"\n", song1, song2);
-       mpd_sendInfoCommand(connection, string);
-       free(string);
-}
-
-void mpd_sendSwapIdCommand(mpd_Connection * connection, int id1, int id2)
-{
-       char *string = malloc(strlen("swapid") + 25);
-       sprintf(string, "swapid \"%i\" \"%i\"\n", id1, id2);
-       mpd_sendInfoCommand(connection, string);
-       free(string);
-}
-
-void mpd_sendSeekCommand(mpd_Connection * connection, int song, int time)
-{
-       char *string = malloc(strlen("seek") + 25);
-       sprintf(string, "seek \"%i\" \"%i\"\n", song, time);
-       mpd_sendInfoCommand(connection, string);
-       free(string);
-}
-
-void mpd_sendSeekIdCommand(mpd_Connection * connection, int id, int time)
-{
-       char *string = malloc(strlen("seekid") + 25);
-       sprintf(string, "seekid \"%i\" \"%i\"\n", id, time);
-       mpd_sendInfoCommand(connection, string);
-       free(string);
-}
-
-void mpd_sendUpdateCommand(mpd_Connection * connection, char *path)
-{
-       char *sPath = mpd_sanitizeArg(path);
-       char *string = malloc(strlen("update") + strlen(sPath) + 5);
-       sprintf(string, "update \"%s\"\n", sPath);
-       mpd_sendInfoCommand(connection, string);
-       free(string);
-       free(sPath);
-}
-
-int mpd_getUpdateId(mpd_Connection * connection)
-{
-       char *jobid;
-       int ret = 0;
-
-       jobid = mpd_getNextReturnElementNamed(connection, "updating_db");
-       if (jobid) {
-               ret = atoi(jobid);
-               free(jobid);
-       }
-
-       return ret;
-}
-
-void mpd_sendPrevCommand(mpd_Connection * connection)
-{
-       mpd_executeCommand(connection, "previous\n");
-}
-
-void mpd_sendRepeatCommand(mpd_Connection * connection, int repeatMode)
-{
-       char *string = malloc(strlen("repeat") + 25);
-       sprintf(string, "repeat \"%i\"\n", repeatMode);
-       mpd_executeCommand(connection, string);
-       free(string);
-}
-
-void mpd_sendRandomCommand(mpd_Connection * connection, int randomMode)
-{
-       char *string = malloc(strlen("random") + 25);
-       sprintf(string, "random \"%i\"\n", randomMode);
-       mpd_executeCommand(connection, string);
-       free(string);
-}
-
-void mpd_sendSetvolCommand(mpd_Connection * connection, int volumeChange)
-{
-       char *string = malloc(strlen("setvol") + 25);
-       sprintf(string, "setvol \"%i\"\n", volumeChange);
-       mpd_executeCommand(connection, string);
-       free(string);
-}
-
-void mpd_sendVolumeCommand(mpd_Connection * connection, int volumeChange)
-{
-       char *string = malloc(strlen("volume") + 25);
-       sprintf(string, "volume \"%i\"\n", volumeChange);
-       mpd_executeCommand(connection, string);
-       free(string);
-}
-
-void mpd_sendCrossfadeCommand(mpd_Connection * connection, int seconds)
-{
-       char *string = malloc(strlen("crossfade") + 25);
-       sprintf(string, "crossfade \"%i\"\n", seconds);
-       mpd_executeCommand(connection, string);
-       free(string);
-}
-
-void mpd_sendPasswordCommand(mpd_Connection * connection, const char *pass)
-{
-       char *sPass = mpd_sanitizeArg(pass);
-       char *string = malloc(strlen("password") + strlen(sPass) + 5);
-       sprintf(string, "password \"%s\"\n", sPass);
-       mpd_executeCommand(connection, string);
-       free(string);
-       free(sPass);
-}
-
-void mpd_sendCommandListBegin(mpd_Connection * connection)
-{
-       if (connection->commandList) {
-               strcpy(connection->errorStr,
-                      "already in command list mode");
-               connection->error = 1;
-               return;
-       }
-       connection->commandList = COMMAND_LIST;
-       mpd_executeCommand(connection, "command_list_begin\n");
-}
-
-void mpd_sendCommandListOkBegin(mpd_Connection * connection)
-{
-       if (connection->commandList) {
-               strcpy(connection->errorStr,
-                      "already in command list mode");
-               connection->error = 1;
-               return;
-       }
-       connection->commandList = COMMAND_LIST_OK;
-       mpd_executeCommand(connection, "command_list_ok_begin\n");
-       connection->listOks = 0;
-}
-
-void mpd_sendCommandListEnd(mpd_Connection * connection)
-{
-       if (!connection->commandList) {
-               strcpy(connection->errorStr, "not in command list mode");
-               connection->error = 1;
-               return;
-       }
-       connection->commandList = 0;
-       mpd_executeCommand(connection, "command_list_end\n");
-}
diff --git a/libmpdclient.h b/libmpdclient.h
deleted file mode 100644 (file)
index 2b7669c..0000000
+++ /dev/null
@@ -1,509 +0,0 @@
-/* libmpdclient
-   (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu)
-   This project's homepage is: http://www.musicpd.org
-  
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions
-   are met:
-                                                                                
-   - Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-                                                                                
-   - Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-                                                                                
-   - Neither the name of the Music Player Daemon nor the names of its
-   contributors may be used to endorse or promote products derived from
-   this software without specific prior written permission.
-                                                                                
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
-   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-   
-   $Id$
-
-*/
-
-#ifndef LIBMPDCLIENT_H
-#define LIBMPDCLIENT_H
-
-#include <sys/time.h>
-
-#define MPD_BUFFER_MAX_LENGTH  50000
-#define MPD_WELCOME_MESSAGE    "OK MPD "
-
-#define MPD_ERROR_TIMEOUT      10      /* timeout trying to talk to mpd */
-#define MPD_ERROR_SYSTEM       11      /* system error */
-#define MPD_ERROR_UNKHOST      12      /* unknown host */
-#define MPD_ERROR_CONNPORT     13      /* problems connecting to port on host */
-#define MPD_ERROR_NOTMPD       14      /* mpd not running on port at host */
-#define MPD_ERROR_NORESPONSE   15      /* no response on attempting to connect */
-#define MPD_ERROR_SENDING      16      /* error sending command */
-#define MPD_ERROR_CONNCLOSED   17      /* connection closed by mpd */
-#define MPD_ERROR_ACK          18      /* ACK returned! */
-#define MPD_ERROR_BUFFEROVERRUN        19      /* Buffer was overrun! */
-
-#define MPD_ACK_ERROR_UNK      -1
-#define MPD_ERROR_AT_UNK       -1
-
-#define MPD_ACK_ERROR_NOT_LIST                 1
-#define MPD_ACK_ERROR_ARG                      2
-#define MPD_ACK_ERROR_PASSWORD                 3
-#define MPD_ACK_ERROR_PERMISSION               4
-#define MPD_ACK_ERROR_UNKNOWN_CMD              5
-
-#define MPD_ACK_ERROR_NO_EXIST                 50
-#define MPD_ACK_ERROR_PLAYLIST_MAX             51
-#define MPD_ACK_ERROR_SYSTEM                   52
-#define MPD_ACK_ERROR_PLAYLIST_LOAD            53
-#define MPD_ACK_ERROR_UPDATE_ALREADY           54
-#define MPD_ACK_ERROR_PLAYER_SYNC              55
-#define MPD_ACK_ERROR_EXIST                    56
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* internal stuff don't touch this struct */
-       typedef struct _mpd_ReturnElement {
-               char *name;
-               char *value;
-       } mpd_ReturnElement;
-
-/* mpd_Connection
- * holds info about connection to mpd
- * use error, and errorStr to detect errors
- */
-       typedef struct _mpd_Connection {
-               /* use this to check the version of mpd */
-               int version[3];
-               /* IMPORTANT, you want to get the error messages from here */
-               char errorStr[MPD_BUFFER_MAX_LENGTH + 1];
-               int errorCode;
-               int errorAt;
-               /* this will be set to MPD_ERROR_* if there is an error, 0 if not */
-               int error;
-               /* DON'T TOUCH any of the rest of this stuff */
-               int sock;
-               char buffer[MPD_BUFFER_MAX_LENGTH + 1];
-               int buflen;
-               int bufstart;
-               int doneProcessing;
-               int listOks;
-               int doneListOk;
-               int commandList;
-               mpd_ReturnElement *returnElement;
-               struct timeval timeout;
-       } mpd_Connection;
-
-/* mpd_newConnection
- * use this to open a new connection
- * you should use mpd_closeConnection, when your done with the connection,
- * even if an error has occurred
- * _timeout_ is the connection timeout period in seconds
- */
-       mpd_Connection *mpd_newConnection(const char *host, int port,
-                                         float timeout);
-
-       void mpd_setConnectionTimeout(mpd_Connection * connection,
-                                     float timeout);
-
-/* mpd_closeConnection
- * use this to close a connection and free'ing subsequent memory
- */
-       void mpd_closeConnection(mpd_Connection * connection);
-
-/* mpd_clearError
- * clears error
- */
-       void mpd_clearError(mpd_Connection * connection);
-
-/* STATUS STUFF */
-
-/* use these with status.state to determine what state the player is in */
-#define MPD_STATUS_STATE_UNKNOWN       0
-#define MPD_STATUS_STATE_STOP          1
-#define MPD_STATUS_STATE_PLAY          2
-#define MPD_STATUS_STATE_PAUSE         3
-
-/* us this with status.volume to determine if mpd has volume support */
-#define MPD_STATUS_NO_VOLUME           -1
-
-/* mpd_Status
- * holds info return from status command
- */
-       typedef struct mpd_Status {
-               /* 0-100, or MPD_STATUS_NO_VOLUME when there is no volume support */
-               int volume;
-               /* 1 if repeat is on, 0 otherwise */
-               int repeat;
-               /* 1 if random is on, 0 otherwise */
-               int random;
-               /* playlist length */
-               int playlistLength;
-               /* playlist, use this to determine when the playlist has changed */
-               long long playlist;
-               /* use with MPD_STATUS_STATE_* to determine state of player */
-               int state;
-               /* crossfade setting in seconds */
-               int crossfade;
-               /* if a song is currently selected (always the case when state is
-                * PLAY or PAUSE), this is the position of the currently
-                * playing song in the playlist, beginning with 0
-                */
-               int song;
-               /* Song ID of the currently selected song */
-               int songid;
-               /* time in seconds that have elapsed in the currently playing/paused
-                * song
-                */
-               int elapsedTime;
-               /* length in seconds of the currently playing/paused song */
-               int totalTime;
-               /* current bit rate in kbs */
-               int bitRate;
-               /* audio sample rate */
-               unsigned int sampleRate;
-               /* audio bits */
-               int bits;
-               /* audio channels */
-               int channels;
-               /* 1 if mpd is updating, 0 otherwise */
-               int updatingDb;
-               /* error */
-               char *error;
-       } mpd_Status;
-
-       void mpd_sendStatusCommand(mpd_Connection * connection);
-
-/* mpd_getStatus
- * returns status info, be sure to free it with mpd_freeStatus()
- * call this after mpd_sendStatusCommand()
- */
-       mpd_Status *mpd_getStatus(mpd_Connection * connection);
-
-/* mpd_freeStatus
- * free's status info malloc'd and returned by mpd_getStatus
- */
-       void mpd_freeStatus(mpd_Status * status);
-
-       typedef struct _mpd_Stats {
-               int numberOfArtists;
-               int numberOfAlbums;
-               int numberOfSongs;
-               unsigned long uptime;
-               unsigned long dbUpdateTime;
-               unsigned long playTime;
-               unsigned long dbPlayTime;
-       } mpd_Stats;
-
-       void mpd_sendStatsCommand(mpd_Connection * connection);
-
-       mpd_Stats *mpd_getStats(mpd_Connection * connection);
-
-       void mpd_freeStats(mpd_Stats * stats);
-
-/* SONG STUFF */
-
-#define MPD_SONG_NO_TIME       -1
-#define MPD_SONG_NO_NUM                -1
-#define MPD_SONG_NO_ID         -1
-
-/* mpd_Song
- * for storing song info returned by mpd
- */
-       typedef struct _mpd_Song {
-               /* filename of song */
-               char *file;
-               /* artist, maybe NULL if there is no tag */
-               char *artist;
-               /* title, maybe NULL if there is no tag */
-               char *title;
-               /* album, maybe NULL if there is no tag */
-               char *album;
-               /* track, maybe NULL if there is no tag */
-               char *track;
-               /* name, maybe NULL if there is no tag; it's the name of the current
-                * song, f.e. the icyName of the stream */
-               char *name;
-               /* length of song in seconds, check that it is not MPD_SONG_NO_TIME  */
-               int time;
-               /* if plchanges/playlistinfo/playlistid used, is the position of the 
-                * song in the playlist */
-               int pos;
-               /* song id for a song in the playlist */
-               int id;
-       } mpd_Song;
-
-/* mpd_newSong
- * use to allocate memory for a new mpd_Song
- * file, artist, etc all initialized to NULL
- * if your going to assign values to file, artist, etc
- * be sure to malloc or strdup the memory
- * use mpd_freeSong to free the memory for the mpd_Song, it will also
- * free memory for file, artist, etc, so don't do it yourself
- */
-       mpd_Song *mpd_newSong();
-
-/* mpd_freeSong
- * use to free memory allocated by mpd_newSong
- * also it will free memory pointed to by file, artist, etc, so be careful
- */
-       void mpd_freeSong(mpd_Song * song);
-
-/* mpd_songDup
- * works like strDup, but for a mpd_Song
- */
-       mpd_Song *mpd_songDup(mpd_Song * song);
-
-/* DIRECTORY STUFF */
-
-/* mpd_Directory
- * used to store info fro directory (right now that just the path)
- */
-       typedef struct _mpd_Directory {
-               char *path;
-       } mpd_Directory;
-
-/* mpd_newDirectory
- * allocates memory for a new directory
- * use mpd_freeDirectory to free this memory
- */
-       mpd_Directory *mpd_newDirectory();
-
-/* mpd_freeDirectory
- * used to free memory allocated with mpd_newDirectory, and it frees
- * path of mpd_Directory, so be careful
- */
-       void mpd_freeDirectory(mpd_Directory * directory);
-
-/* mpd_directoryDup
- * works like strdup, but for mpd_Directory
- */
-       mpd_Directory *mpd_directoryDup(mpd_Directory * directory);
-
-/* PLAYLISTFILE STUFF */
-
-/* mpd_PlaylistFile
- * stores info about playlist file returned by lsinfo
- */
-       typedef struct _mpd_PlaylistFile {
-               char *path;
-       } mpd_PlaylistFile;
-
-/* mpd_newPlaylistFile
- * allocates memory for new mpd_PlaylistFile, path is set to NULL
- * free this memory with mpd_freePlaylistFile
- */
-       mpd_PlaylistFile *mpd_newPlaylistFile();
-
-/* mpd_freePlaylist
- * free memory allocated for freePlaylistFile, will also free
- * path, so be careful
- */
-       void mpd_freePlaylistFile(mpd_PlaylistFile * playlist);
-
-/* mpd_playlistFileDup
- * works like strdup, but for mpd_PlaylistFile
- */
-       mpd_PlaylistFile *mpd_playlistFileDup(mpd_PlaylistFile * playlist);
-
-/* INFO ENTITY STUFF */
-
-/* the type of entity returned from one of the commands that generates info
- * use in conjunction with mpd_InfoEntity.type
- */
-#define MPD_INFO_ENTITY_TYPE_DIRECTORY         0
-#define MPD_INFO_ENTITY_TYPE_SONG              1
-#define MPD_INFO_ENTITY_TYPE_PLAYLISTFILE      2
-
-/* mpd_InfoEntity
- * stores info on stuff returned info commands
- */
-       typedef struct mpd_InfoEntity {
-               /* the type of entity, use with MPD_INFO_ENTITY_TYPE_* to determine
-                * what this entity is (song, directory, etc...)
-                */
-               int type;
-               /* the actual data you want, mpd_Song, mpd_Directory, etc */
-               union {
-                       mpd_Directory *directory;
-                       mpd_Song *song;
-                       mpd_PlaylistFile *playlistFile;
-               } info;
-       } mpd_InfoEntity;
-
-       mpd_InfoEntity *mpd_newInfoEntity();
-
-       void mpd_freeInfoEntity(mpd_InfoEntity * entity);
-
-/* INFO COMMANDS AND STUFF */
-
-/* use this function to loop over after calling Info/Listall functions */
-       mpd_InfoEntity *mpd_getNextInfoEntity(mpd_Connection * connection);
-
-/* fetches the currently seeletect song (the song referenced by status->song
- * and status->songid*/
-       void mpd_sendCurrentSongCommand(mpd_Connection * connection);
-
-/* songNum of -1, means to display the whole list */
-       void mpd_sendPlaylistInfoCommand(mpd_Connection * connection,
-                                        int songNum);
-
-/* use this to get the changes in the playlist since version _playlist_ */
-       void mpd_sendPlChangesCommand(mpd_Connection * connection,
-                                     long long playlist);
-
-/* recursivel fetches all songs/dir/playlists in "dir* (no metadata is 
- * returned) */
-       void mpd_sendListallCommand(mpd_Connection * connection,
-                                   const char *dir);
-
-/* same as sendListallCommand, but also metadata is returned */
-       void mpd_sendListallInfoCommand(mpd_Connection * connection,
-                                       const char *dir);
-
-/* non-recursive version of ListallInfo */
-       void mpd_sendLsInfoCommand(mpd_Connection * connection,
-                                  const char *dir);
-
-#define MPD_TABLE_ARTIST       0
-#define MPD_TABLE_ALBUM                1
-#define MPD_TABLE_TITLE                2
-#define MPD_TABLE_FILENAME     3
-
-       void mpd_sendSearchCommand(mpd_Connection * connection, int table,
-                                  const char *str);
-
-       void mpd_sendFindCommand(mpd_Connection * connection, int table,
-                                const char *str);
-
-/* LIST TAG COMMANDS */
-
-/* use this function fetch next artist entry, be sure to free the returned 
- * string.  NULL means there are no more.  Best used with sendListArtists
- */
-       char *mpd_getNextArtist(mpd_Connection * connection);
-
-       char *mpd_getNextAlbum(mpd_Connection * connection);
-
-/* list artist or albums by artist, arg1 should be set to the artist if
- * listing albums by a artist, otherwise NULL for listing all artists or albums
- */
-       void mpd_sendListCommand(mpd_Connection * connection, int table,
-                                const char *arg1);
-
-/* SIMPLE COMMANDS */
-
-       void mpd_sendAddCommand(mpd_Connection * connection,
-                               const char *file);
-
-       void mpd_sendDeleteCommand(mpd_Connection * connection,
-                                  int songNum);
-
-       void mpd_sendDeleteIdCommand(mpd_Connection * connection,
-                                    int songNum);
-
-       void mpd_sendSaveCommand(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_sendShuffleCommand(mpd_Connection * connection);
-
-       void mpd_sendClearCommand(mpd_Connection * connection);
-
-/* use this to start playing at the beginning, useful when in random mode */
-#define MPD_PLAY_AT_BEGINNING  -1
-
-       void mpd_sendPlayCommand(mpd_Connection * connection, int songNum);
-
-       void mpd_sendPlayIdCommand(mpd_Connection * connection,
-                                  int songNum);
-
-       void mpd_sendStopCommand(mpd_Connection * connection);
-
-       void mpd_sendPauseCommand(mpd_Connection * connection,
-                                 int pauseMode);
-
-       void mpd_sendNextCommand(mpd_Connection * connection);
-
-       void mpd_sendPrevCommand(mpd_Connection * connection);
-
-       void mpd_sendMoveCommand(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_sendSwapIdCommand(mpd_Connection * connection, int song1,
-                                  int song2);
-
-       void mpd_sendSeekCommand(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_sendRandomCommand(mpd_Connection * connection,
-                                  int randomMode);
-
-       void mpd_sendSetvolCommand(mpd_Connection * connection,
-                                  int volumeChange);
-
-/* WARNING: don't use volume command, its depreacted */
-       void mpd_sendVolumeCommand(mpd_Connection * connection,
-                                  int volumeChange);
-
-       void mpd_sendCrossfadeCommand(mpd_Connection * connection,
-                                     int seconds);
-
-       void mpd_sendUpdateCommand(mpd_Connection * connection,
-                                  char *path);
-
-/* returns the update job id, call this after a update command*/
-       int mpd_getUpdateId(mpd_Connection * connection);
-
-       void mpd_sendPasswordCommand(mpd_Connection * connection,
-                                    const char *pass);
-
-/* after executing a command, when your done with it to get its status
- * (you want to check connection->error for an error)
- */
-       void mpd_finishCommand(mpd_Connection * connection);
-
-/* command list stuff, use this to do things like add files very quickly */
-       void mpd_sendCommandListBegin(mpd_Connection * connection);
-
-       void mpd_sendCommandListOkBegin(mpd_Connection * connection);
-
-       void mpd_sendCommandListEnd(mpd_Connection * connection);
-
-/* advance to the next listOk 
- * returns 0 if advanced to the next list_OK,
- * returns -1 if it advanced to an OK or ACK */
-       int mpd_nextListOkCommand(mpd_Connection * connection);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/linux.c b/linux.c
deleted file mode 100644 (file)
index 561ca01..0000000
--- a/linux.c
+++ /dev/null
@@ -1,1067 +0,0 @@
-/* linux.c
- * Contains linux specific code
- *
- *  $Id$
- */
-
-
-#include "conky.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <dirent.h>
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-#include <sys/types.h>
-#include <sys/sysinfo.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-// #include <assert.h>
-#include <time.h>
-#include "top.h"
-
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <linux/sockios.h>
-#include <net/if.h>
-#include <math.h>
-
-
-static struct sysinfo s_info;
-
-static int show_nice_processes;
-
-void prepare_update()
-{
-}
-
-static void update_sysinfo()
-{
-       sysinfo(&s_info);
-
-       info.uptime = (double) s_info.uptime;
-
-       /* there was some problem with these */
-#if 0
-//      info.loadavg[0] = s_info.loads[0] / 100000.0f;
-       info.loadavg[1] = s_info.loads[1] / 100000.0f;
-       info.loadavg[2] = s_info.loads[2] / 100000.0f;
-       gkrelltop_process_find_top_three info.mask |= 1 << INFO_LOADAVG;
-#endif
-
-       info.procs = s_info.procs;
-
-       /* these aren't nice, no cache and should check kernel version for mem_unit */
-#if 0
-       info.memmax = s_info.totalram;
-       info.mem = s_info.totalram - s_info.freeram;
-       info.swapmax = s_info.totalswap;
-       info.swap = s_info.totalswap - s_info.swap;
-       info.mask |= 1 << INFO_MEM;
-#endif
-
-       info.mask |= (1 << INFO_UPTIME) | (1 << INFO_PROCS);
-}
-
-void update_uptime()
-{
-       /* prefers sysinfo() for uptime, I don't really know which one is better
-        * (=faster?) */
-#ifdef USE_PROC_UPTIME
-       static int rep;
-       FILE *fp = open_file("/proc/uptime", &rep);
-       if (!fp)
-               return 0;
-       fscanf(fp, "%lf", &info.uptime);
-       fclose(fp);
-
-       info.mask |= (1 << INFO_UPTIME);
-#else
-       update_sysinfo();
-#endif
-}
-
-/* these things are also in sysinfo except Buffers:, that's why I'm reading
-* them from proc */
-
-static FILE *meminfo_fp;
-
-void update_meminfo()
-{
-       static int rep;
-       /*  unsigned int a; */
-       char buf[256];
-
-       info.mem = info.memmax = info.swap = info.swapmax = info.bufmem =
-           info.buffers = info.cached = 0;
-
-       if (meminfo_fp == NULL)
-               meminfo_fp = open_file("/proc/meminfo", &rep);
-       else
-               fseek(meminfo_fp, 0, SEEK_SET);
-       if (meminfo_fp == NULL)
-               return;
-
-       while (!feof(meminfo_fp)) {
-               if (fgets(buf, 255, meminfo_fp) == NULL)
-                       break;
-
-               if (strncmp(buf, "MemTotal:", 9) == 0) {
-                       sscanf(buf, "%*s %u", &info.memmax);
-               } else if (strncmp(buf, "MemFree:", 8) == 0) {
-                       sscanf(buf, "%*s %u", &info.mem);
-               } else if (strncmp(buf, "SwapTotal:", 10) == 0) {
-                       sscanf(buf, "%*s %u", &info.swapmax);
-               } else if (strncmp(buf, "SwapFree:", 9) == 0) {
-                       sscanf(buf, "%*s %u", &info.swap);
-               } else if (strncmp(buf, "Buffers:", 8) == 0) {
-                       sscanf(buf, "%*s %u", &info.buffers);
-               } else if (strncmp(buf, "Cached:", 7) == 0) {
-                       sscanf(buf, "%*s %u", &info.cached);
-               }
-       }
-
-       info.mem = info.memmax - info.mem;
-       info.swap = info.swapmax - info.swap;
-
-       info.bufmem = info.cached + info.buffers;
-
-       info.mask |= (1 << INFO_MEM) | (1 << INFO_BUFFERS);
-}
-
-static FILE *net_dev_fp;
-static FILE *net_wireless_fp;
-
-inline void update_net_stats()
-{
-       static int rep;
-       // FIXME: arbitrary size chosen to keep code simple.
-       int i, i2;
-       unsigned int curtmp1, curtmp2;
-       unsigned int k;
-       struct ifconf conf;
-
-
-       char buf[256];
-       double delta;
-
-       /* get delta */
-       delta = current_update_time - last_update_time;
-       if (delta <= 0.0001)
-               return;
-
-       /* open file and ignore first two lines */
-       if (net_dev_fp == NULL)
-               net_dev_fp = open_file("/proc/net/dev", &rep);
-       else
-               fseek(net_dev_fp, 0, SEEK_SET);
-       if (!net_dev_fp)
-               return;
-
-       fgets(buf, 255, net_dev_fp);    /* garbage */
-       fgets(buf, 255, net_dev_fp);    /* garbage (field names) */
-
-       /* read each interface */
-       for (i2 = 0; i2 < 16; i2++) {
-               struct net_stat *ns;
-               char *s, *p;
-               long long r, t, last_recv, last_trans;
-
-               if (fgets(buf, 255, net_dev_fp) == NULL)
-                       break;
-               p = buf;
-               while (isspace((int) *p))
-                       p++;
-
-               s = p;
-
-               while (*p && *p != ':')
-                       p++;
-               if (*p == '\0')
-                       continue;
-               *p = '\0';
-               p++;
-
-               ns = get_net_stat(s);
-               ns->up = 1;
-               last_recv = ns->recv;
-               last_trans = ns->trans;
-
-               sscanf(p,
-                      /* bytes packets errs drop fifo frame compressed multicast|bytes ... */
-                      "%Ld  %*d     %*d  %*d  %*d  %*d   %*d        %*d       %Ld",
-                      &r, &t);
-
-               /* if recv or trans is less than last time, an overflow happened */
-
-               if (r < ns->last_read_recv)
-                       ns->recv +=
-                           ((long long) 4294967295U -
-                            ns->last_read_recv) + r;
-               else
-                       ns->recv += (r - ns->last_read_recv);
-               ns->last_read_recv = r;
-
-               if (t < ns->last_read_trans)
-                       ns->trans +=
-                           ((long long) 4294967295U -
-                            ns->last_read_trans) + t;
-               else
-                       ns->trans += (t - ns->last_read_trans);
-               ns->last_read_trans = t;
-
-               /*** ip addr patch ***/
-               i = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
-
-               conf.ifc_buf = malloc(sizeof(struct ifreq) * 16);
-
-               conf.ifc_len = sizeof(struct ifreq) * 16;
-
-               ioctl((long) i, SIOCGIFCONF, &conf);
-
-               for (k = 0; k < conf.ifc_len / sizeof(struct ifreq); k++) {
-                       struct net_stat *ns;
-                       ns = get_net_stat(((struct ifreq *) conf.
-                                          ifc_buf)[k].ifr_ifrn.ifrn_name);
-                       ns->addr =
-                           ((struct ifreq *) conf.ifc_buf)[k].ifr_ifru.
-                           ifru_addr;
-               }
-
-               close((long) i);
-
-               free(conf.ifc_buf);
-
-
-               /*** end ip addr patch ***/
-
-
-               /* calculate speeds */
-               ns->net_rec[0] = (ns->recv - last_recv) / delta;
-               ns->net_trans[0] = (ns->trans - last_trans) / delta;
-               curtmp1 = 0;
-               curtmp2 = 0;
-               // get an average
-               for (i = 0; (unsigned) i < info.net_avg_samples; i++) {
-                       curtmp1 += ns->net_rec[i];
-                       curtmp2 += ns->net_trans[i];
-               }
-               ns->recv_speed = curtmp1 / (double) info.net_avg_samples;
-               ns->trans_speed = curtmp2 / (double) info.net_avg_samples;
-               if (info.net_avg_samples > 1) {
-                       for (i = info.net_avg_samples; i > 1; i--) {
-                               ns->net_rec[i - 1] = ns->net_rec[i - 2];
-                               ns->net_trans[i - 1] =
-                                   ns->net_trans[i - 2];
-                       }
-               }
-
-
-
-       }
-
-       /* fclose(net_dev_fp); net_dev_fp = NULL; */
-}
-
-inline void update_wifi_stats()
-{
-       /** wireless stats patch by Bobby Beckmann **/
-       static int rep;
-       int i;
-       char buf[256];
-       /*open file and ignore first two lines       sorry, this code sucks ass right now, i'll clean it up later */
-       if (net_wireless_fp == NULL)
-               net_wireless_fp = open_file("/proc/net/wireless", &rep);
-       else
-               fseek(net_wireless_fp, 0, SEEK_SET);
-       if (net_wireless_fp == NULL)
-               return;
-
-       fgets(buf, 255, net_wireless_fp);       /* garbage */
-       fgets(buf, 255, net_wireless_fp);       /* garbage (field names) */
-
-       /* read each interface */
-       for (i = 0; i < 16; i++) {
-               struct net_stat *ns;
-               char *s, *p;
-               int l, m, n;
-
-               if (fgets(buf, 255, net_wireless_fp) == NULL)
-                       break;
-               p = buf;
-               while (isspace((int) *p))
-                       p++;
-
-               s = p;
-
-               while (*p && *p != ':')
-                       p++;
-               if (*p == '\0')
-                       continue;
-               *p = '\0';
-               p++;
-
-               ns = get_net_stat(s);
-
-               sscanf(p, "%*d   %d.  %d.  %d", &l, &m, &n);
-
-               ns->linkstatus = (int) (log(l) / log(92) * 100);
-       }
-
-       /*** end wireless patch ***/
-}
-
-int result;
-
-void update_total_processes()
-{
-       update_sysinfo();
-}
-
-static unsigned int cpu_user, cpu_system, cpu_nice;
-static double last_cpu_sum;
-static int clock_ticks;
-
-static FILE *stat_fp;
-
-inline static void update_stat()
-{
-       // FIXME: arbitrary size?
-       static double cpu_val[15];
-       static int rep;
-       char buf[256];
-       unsigned int i;
-       double curtmp;
-
-       if (stat_fp == NULL)
-               stat_fp = open_file("/proc/stat", &rep);
-       else
-               fseek(stat_fp, 0, SEEK_SET);
-       if (stat_fp == NULL)
-               return;
-
-       info.cpu_count = 0;
-
-       while (!feof(stat_fp)) {
-               if (fgets(buf, 255, stat_fp) == NULL)
-                       break;
-
-               if (strncmp(buf, "procs_running ", 14) == 0) {
-                       sscanf(buf, "%*s %d", &info.run_procs);
-                       info.mask |= (1 << INFO_RUN_PROCS);
-               } else if (strncmp(buf, "cpu ", 4) == 0) {
-                       sscanf(buf, "%*s %u %u %u", &cpu_user, &cpu_nice,
-                              &cpu_system);
-                       info.mask |= (1 << INFO_CPU);
-               } else if (strncmp(buf, "cpu", 3) == 0 && isdigit(buf[3])) {
-                       info.cpu_count++;
-               }
-       }
-
-       {
-               double delta;
-               delta = current_update_time - last_update_time;
-               if (delta <= 0.001)
-                       return;
-
-               if (clock_ticks == 0)
-                       clock_ticks = sysconf(_SC_CLK_TCK);
-               curtmp = 0;
-               cpu_val[0] =
-                   (cpu_user + cpu_nice + cpu_system -
-                    last_cpu_sum) / delta / (double) clock_ticks /
-                   info.cpu_count;
-               for (i = 0; i < info.cpu_avg_samples; i++)
-                       curtmp += cpu_val[i];
-               info.cpu_usage = curtmp / info.cpu_avg_samples;
-               last_cpu_sum = cpu_user + cpu_nice + cpu_system;
-               for (i = info.cpu_avg_samples; i > 1; i--)
-                       cpu_val[i - 1] = cpu_val[i - 2];
-
-       }
-
-// test code
-// this is for getting proc shit
-// pee pee
-// poo
-       //
-
-
-
-
-
-
-}
-
-void update_running_processes()
-{
-       update_stat();
-}
-
-void update_cpu_usage()
-{
-       update_stat();
-}
-
-void update_load_average()
-{
-#ifdef HAVE_GETLOADAVG
-       double v[3];
-       getloadavg(v, 3);
-       info.loadavg[0] = (float) v[0];
-       info.loadavg[1] = (float) v[1];
-       info.loadavg[2] = (float) v[2];
-#else
-       static int rep;
-       FILE *fp;
-
-       fp = open_file("/proc/loadavg", &rep);
-       if (!fp) {
-               v[0] = v[1] = v[2] = 0.0;
-               return;
-       }
-
-       fscanf(fp, "%f %f %f", &info.loadavg[0], &info.loadavg[1],
-              &info.loadavg[2]);
-
-       fclose(fp);
-#endif
-}
-
-
-static int no_dots(const struct dirent *d)
-{
-       if (d->d_name[0] == '.')
-               return 0;
-       return 1;
-}
-
-static int
-get_first_file_in_a_directory(const char *dir, char *s, int *rep)
-{
-       struct dirent **namelist;
-       int i, n;
-
-       n = scandir(dir, &namelist, no_dots, alphasort);
-       if (n < 0) {
-               if (!rep || !*rep) {
-                       ERR("scandir for %s: %s", dir, strerror(errno));
-                       if (rep)
-                               *rep = 1;
-               }
-               return 0;
-       } else {
-               if (n == 0)
-                       return 0;
-
-               strncpy(s, namelist[0]->d_name, 255);
-               s[255] = '\0';
-
-               for (i = 0; i < n; i++)
-                       free(namelist[i]);
-               free(namelist);
-
-               return 1;
-       }
-}
-
-#define I2C_DIR "/sys/bus/i2c/devices/"
-
-int
-open_i2c_sensor(const char *dev, const char *type, int n, int *div,
-               char *devtype)
-{
-       char path[256];
-       char buf[64];
-       int fd;
-       int divfd;
-
-       /* if i2c device is NULL or *, get first */
-       if (dev == NULL || strcmp(dev, "*") == 0) {
-               static int rep;
-               if (!get_first_file_in_a_directory(I2C_DIR, buf, &rep))
-                       return -1;
-               dev = buf;
-       }
-
-       /* change vol to in */
-       if (strcmp(type, "vol") == 0)
-               type = "in";
-
-       if (strcmp(type, "tempf") == 0) {
-               snprintf(path, 255, I2C_DIR "%s/%s%d_input", dev, "temp",
-                        n);
-       } else {
-               snprintf(path, 255, I2C_DIR "%s/%s%d_input", dev, type, n);
-       }
-       strcpy(devtype, path);
-
-       /* open file */
-       fd = open(path, O_RDONLY);
-       if (fd < 0) {
-               CRIT_ERR("can't open '%s': %s\nplease fix i2c or remove it from Conky", path, strerror(errno));
-       }
-
-       if (strcmp(type, "in") == 0 || strcmp(type, "temp") == 0
-           || strcmp(type, "tempf") == 0)
-               *div = 1;
-       else
-               *div = 0;
-       /* fan does not use *_div as a read divisor */
-       if (strcmp("fan", type) == 0)
-               return fd;
-
-       /* test if *_div file exist, open it and use it as divisor */
-       if (strcmp(type, "tempf") == 0) {
-               snprintf(path, 255, I2C_DIR "%s/%s%d_div", "one", "two",
-                        n);
-       } else {
-               snprintf(path, 255, I2C_DIR "%s/%s%d_div", dev, type, n);
-       }
-
-       divfd = open(path, O_RDONLY);
-       if (divfd > 0) {
-               /* read integer */
-               char divbuf[64];
-               unsigned int divn;
-               divn = read(divfd, divbuf, 63);
-               /* should read until n == 0 but I doubt that kernel will give these
-                * in multiple pieces. :) */
-               divbuf[divn] = '\0';
-               *div = atoi(divbuf);
-       }
-
-       close(divfd);
-
-       return fd;
-}
-
-double get_i2c_info(int *fd, int div, char *devtype, char *type)
-{
-       int val = 0;
-
-       if (*fd <= 0)
-               return 0;
-
-       lseek(*fd, 0, SEEK_SET);
-
-       /* read integer */
-       {
-               char buf[64];
-               unsigned int n;
-               n = read(*fd, buf, 63);
-               /* should read until n == 0 but I doubt that kernel will give these
-                * in multiple pieces. :) */
-               buf[n] = '\0';
-               val = atoi(buf);
-       }
-
-       close(*fd);
-       /* open file */
-       *fd = open(devtype, O_RDONLY);
-       if (*fd < 0)
-               ERR("can't open '%s': %s", devtype, strerror(errno));
-
-       /* My dirty hack for computing CPU value 
-        * Filedil, from forums.gentoo.org
-        */
-/*     if (strstr(devtype, "temp1_input") != NULL)
-       return -15.096+1.4893*(val / 1000.0); */
-
-
-       /* divide voltage and temperature by 1000 */
-       /* or if any other divisor is given, use that */
-       if (strcmp(type, "tempf") == 0) {
-               if (div > 1)
-                       return ((val / div + 40) * 9.0 / 5) - 40;
-               else if (div)
-                       return ((val / 1000.0 + 40) * 9.0 / 5) - 40;
-               else
-                       return ((val + 40) * 9.0 / 5) - 40;
-       } else {
-               if (div > 1)
-                       return val / div;
-               else if (div)
-                       return val / 1000.0;
-               else
-                       return val;
-       }
-}
-
-#define ADT746X_FAN "/sys/devices/temperatures/cpu_fan_speed"
-
-static char *adt746x_fan_state;
-
-char *get_adt746x_fan()
-{
-       static int rep;
-       FILE *fp;
-
-       if (adt746x_fan_state == NULL) {
-               adt746x_fan_state = (char *) malloc(100);
-               assert(adt746x_fan_state != NULL);
-       }
-
-       fp = open_file(ADT746X_FAN, &rep);
-       if (!fp) {
-               strcpy(adt746x_fan_state,
-                      "No fan found! Hey, you don't have one?");
-               return adt746x_fan_state;
-       }
-       fscanf(fp, "%s", adt746x_fan_state);
-       fclose(fp);
-
-       return adt746x_fan_state;
-}
-
-#define ADT746X_CPU "/sys/devices/temperatures/cpu_temperature"
-
-static char *adt746x_cpu_state;
-
-char *get_adt746x_cpu()
-{
-       static int rep;
-       FILE *fp;
-
-       if (adt746x_cpu_state == NULL) {
-               adt746x_cpu_state = (char *) malloc(100);
-               assert(adt746x_cpu_state != NULL);
-       }
-
-       fp = open_file(ADT746X_CPU, &rep);
-       fscanf(fp, "%2s", adt746x_cpu_state);
-       fclose(fp);
-
-       return adt746x_cpu_state;
-}
-
-/* Thanks to "Walt Nelson" <wnelsonjr@comcast.net> */
-
-/***********************************************************************/
-/*
- *  This file is part of x86info.
- *  (C) 2001 Dave Jones.
- *
- *  Licensed under the terms of the GNU GPL License version 2.
- *
- * Estimate CPU MHz routine by Andrea Arcangeli <andrea@suse.de>
- * Small changes by David Sterba <sterd9am@ss1000.ms.mff.cuni.cz>
- *
- */
-#if  defined(__i386) || defined(__x86_64)
-__inline__ unsigned long long int rdtsc()
-{
-       unsigned long long int x;
-       __asm__ volatile (".byte 0x0f, 0x31":"=A" (x));
-       return x;
-}
-static char *buffer = NULL;
-#else
-static char *frequency;
-#endif
-
-char *get_freq()
-{
-#if  defined(__i386) || defined(__x86_64)
-       if (buffer == NULL)
-               buffer = malloc(64);
-       struct timezone tz;
-       struct timeval tvstart, tvstop;
-       unsigned long long cycles[2];   /* gotta be 64 bit */
-       unsigned int microseconds;      /* total time taken */
-
-       memset(&tz, 0, sizeof(tz));
-
-       /* get this function in cached memory */
-       gettimeofday(&tvstart, &tz);
-       cycles[0] = rdtsc();
-       gettimeofday(&tvstart, &tz);
-
-       /* we don't trust that this is any specific length of time */
-       usleep(100);
-       cycles[1] = rdtsc();
-       gettimeofday(&tvstop, &tz);
-       microseconds = ((tvstop.tv_sec - tvstart.tv_sec) * 1000000) +
-           (tvstop.tv_usec - tvstart.tv_usec);
-
-       sprintf(buffer, "%lld", (cycles[1] - cycles[0]) / microseconds);
-
-       return buffer;
-#else
-       FILE *f;
-       char s[1000];
-       if (frequency == NULL) {
-               frequency = (char *) malloc(100);
-               assert(frequency != NULL);
-       }
-       //char frequency[10];
-       f = fopen("/proc/cpuinfo", "r");        //open the CPU information file
-       //if (!f)
-       //    return;
-       while (fgets(s, 1000, f) != NULL){      //read the file
-               if (strncmp(s, "clock", 5) == 0) {      //and search for the cpu mhz
-                       //printf("%s", strchr(s, ':')+2);
-               strcpy(frequency, strchr(s, ':') + 2);  //copy just the number
-               frequency[strlen(frequency) - 1] = '\0';        // strip \n
-               break;
-               }
-       }
-               fclose(f);
-               //printf("%s\n", frequency);
-               return frequency;
-#endif
-}
-
-
-#define ACPI_FAN_DIR "/proc/acpi/fan/"
-
-static char *acpi_fan_state;
-
-char *get_acpi_fan()
-{
-       static int rep;
-       char buf[256];
-       char buf2[256];
-       FILE *fp;
-
-       if (acpi_fan_state == NULL) {
-               acpi_fan_state = (char *) malloc(100);
-               assert(acpi_fan_state != NULL);
-       }
-
-       /* yeah, slow... :/ */
-       if (!get_first_file_in_a_directory(ACPI_FAN_DIR, buf, &rep))
-               return "no fans?";
-
-       snprintf(buf2, 256, "%s%s/state", ACPI_FAN_DIR, buf);
-
-       fp = open_file(buf2, &rep);
-       if (!fp) {
-               strcpy(acpi_fan_state, "can't open fan's state file");
-               return acpi_fan_state;
-       }
-       fscanf(fp, "%*s %99s", acpi_fan_state);
-
-       return acpi_fan_state;
-}
-
-#define ACPI_AC_ADAPTER_DIR "/proc/acpi/ac_adapter/"
-
-static char *acpi_ac_adapter_state;
-
-char *get_acpi_ac_adapter()
-{
-       static int rep;
-       char buf[256];
-       char buf2[256];
-       FILE *fp;
-
-       if (acpi_ac_adapter_state == NULL) {
-               acpi_ac_adapter_state = (char *) malloc(100);
-               assert(acpi_ac_adapter_state != NULL);
-       }
-
-       /* yeah, slow... :/ */
-       if (!get_first_file_in_a_directory(ACPI_AC_ADAPTER_DIR, buf, &rep))
-               return "no ac_adapters?";
-
-       snprintf(buf2, 256, "%s%s/state", ACPI_AC_ADAPTER_DIR, buf);
-
-       fp = open_file(buf2, &rep);
-       if (!fp) {
-               strcpy(acpi_ac_adapter_state,
-                      "No ac adapter found.... where is it?");
-               return acpi_ac_adapter_state;
-       }
-       fscanf(fp, "%*s %99s", acpi_ac_adapter_state);
-       fclose(fp);
-
-       return acpi_ac_adapter_state;
-}
-
-/*
-/proc/acpi/thermal_zone/THRM/cooling_mode
-cooling mode:            active
-/proc/acpi/thermal_zone/THRM/polling_frequency
-<polling disabled>
-/proc/acpi/thermal_zone/THRM/state
-state:                   ok
-/proc/acpi/thermal_zone/THRM/temperature
-temperature:             45 C
-/proc/acpi/thermal_zone/THRM/trip_points
-critical (S5):           73 C
-passive:                 73 C: tc1=4 tc2=3 tsp=40 devices=0xcdf6e6c0
-*/
-
-#define ACPI_THERMAL_DIR "/proc/acpi/thermal_zone/"
-#define ACPI_THERMAL_FORMAT "/proc/acpi/thermal_zone/%s/temperature"
-
-int open_acpi_temperature(const char *name)
-{
-       char path[256];
-       char buf[64];
-       int fd;
-
-       if (name == NULL || strcmp(name, "*") == 0) {
-               static int rep;
-               if (!get_first_file_in_a_directory
-                   (ACPI_THERMAL_DIR, buf, &rep))
-                       return -1;
-               name = buf;
-       }
-
-       snprintf(path, 255, ACPI_THERMAL_FORMAT, name);
-
-       fd = open(path, O_RDONLY);
-       if (fd < 0)
-               ERR("can't open '%s': %s", path, strerror(errno));
-
-       return fd;
-}
-
-static double last_acpi_temp;
-static double last_acpi_temp_time;
-
-double get_acpi_temperature(int fd)
-{
-       if (fd <= 0)
-               return 0;
-
-       /* don't update acpi temperature too often */
-       if (current_update_time - last_acpi_temp_time < 11.32) {
-               return last_acpi_temp;
-       }
-       last_acpi_temp_time = current_update_time;
-
-       /* seek to beginning */
-       lseek(fd, 0, SEEK_SET);
-
-       /* read */
-       {
-               char buf[256];
-               int n;
-               n = read(fd, buf, 255);
-               if (n < 0)
-                       ERR("can't read fd %d: %s", fd, strerror(errno));
-               else {
-                       buf[n] = '\0';
-                       sscanf(buf, "temperature: %lf", &last_acpi_temp);
-               }
-       }
-
-       return last_acpi_temp;
-}
-
-/*
-hipo@lepakko hipo $ cat /proc/acpi/battery/BAT1/info 
-present:                 yes
-design capacity:         4400 mAh
-last full capacity:      4064 mAh
-battery technology:      rechargeable
-design voltage:          14800 mV
-design capacity warning: 300 mAh
-design capacity low:     200 mAh
-capacity granularity 1:  32 mAh
-capacity granularity 2:  32 mAh
-model number:            02KT
-serial number:           16922
-battery type:            LION
-OEM info:                SANYO
-*/
-
-/*
-hipo@lepakko conky $ cat /proc/acpi/battery/BAT1/state
-present:                 yes
-capacity state:          ok
-charging state:          unknown
-present rate:            0 mA
-remaining capacity:      4064 mAh
-present voltage:         16608 mV
-*/
-
-/*
-2213<@jupet kellari ö> jupet@lagi-unstable:~$ cat /proc/apm 
-2213<@jupet kellari ö> 1.16 1.2 0x03 0x01 0xff 0x10 -1% -1 ?
-2213<@jupet kellari ö> (-1 ollee ei akkua kiinni, koska akku on pöydällä)
-2214<@jupet kellari ö> jupet@lagi-unstable:~$ cat /proc/apm 
-2214<@jupet kellari ö> 1.16 1.2 0x03 0x01 0x03 0x09 98% -1 ?
-
-2238<@jupet kellari ö> 1.16 1.2 0x03 0x00 0x00 0x01 100% -1 ? ilman verkkovirtaa
-2239<@jupet kellari ö> 1.16 1.2 0x03 0x01 0x00 0x01 99% -1 ? verkkovirralla
-
-2240<@jupet kellari ö> 1.16 1.2 0x03 0x01 0x03 0x09 100% -1 ? verkkovirralla ja monitori päällä
-2241<@jupet kellari ö> 1.16 1.2 0x03 0x00 0x00 0x01 99% -1 ? monitori päällä mutta ilman verkkovirtaa
-*/
-
-#define ACPI_BATTERY_BASE_PATH "/proc/acpi/battery"
-#define APM_PATH "/proc/apm"
-
-static FILE *acpi_bat_fp;
-static FILE *apm_bat_fp;
-
-static int acpi_last_full;
-
-static char last_battery_str[64];
-
-static double last_battery_time;
-
-void get_battery_stuff(char *buf, unsigned int n, const char *bat)
-{
-       static int rep, rep2;
-       char acpi_path[128];
-       snprintf(acpi_path, 127, ACPI_BATTERY_BASE_PATH "/%s/state", bat);
-
-       /* don't update battery too often */
-       if (current_update_time - last_battery_time < 29.5) {
-               snprintf(buf, n, "%s", last_battery_str);
-               return;
-       }
-       last_battery_time = current_update_time;
-
-       /* first try ACPI */
-
-       if (acpi_bat_fp == NULL && apm_bat_fp == NULL)
-               acpi_bat_fp = open_file(acpi_path, &rep);
-
-       if (acpi_bat_fp != NULL) {
-               int present_rate = -1;
-               int remaining_capacity = -1;
-               char charging_state[64];
-
-               /* read last full capacity if it's zero */
-               if (acpi_last_full == 0) {
-                       static int rep;
-                       char path[128];
-                       FILE *fp;
-                       snprintf(path, 127,
-                                ACPI_BATTERY_BASE_PATH "/%s/info", bat);
-                       fp = open_file(path, &rep);
-                       if (fp != NULL) {
-                               while (!feof(fp)) {
-                                       char b[256];
-                                       if (fgets(b, 256, fp) == NULL)
-                                               break;
-
-                                       if (sscanf
-                                           (b, "last full capacity: %d",
-                                            &acpi_last_full) != 0)
-                                               break;
-                               }
-
-                               fclose(fp);
-                       }
-               }
-
-               fseek(acpi_bat_fp, 0, SEEK_SET);
-
-               strcpy(charging_state, "unknown");
-
-               while (!feof(acpi_bat_fp)) {
-                       char buf[256];
-                       if (fgets(buf, 256, acpi_bat_fp) == NULL)
-                               break;
-
-                       /* let's just hope units are ok */
-                       if (buf[0] == 'c')
-                               sscanf(buf, "charging state: %63s",
-                                      charging_state);
-                       else if (buf[0] == 'p')
-                               sscanf(buf, "present rate: %d",
-                                      &present_rate);
-                       else if (buf[0] == 'r')
-                               sscanf(buf, "remaining capacity: %d",
-                                      &remaining_capacity);
-               }
-
-               /* charging */
-               if (strcmp(charging_state, "charging") == 0) {
-                       if (acpi_last_full != 0 && present_rate > 0) {
-                               strcpy(last_battery_str, "charging ");
-                               format_seconds(last_battery_str + 9,
-                                              63 - 9,
-                                              (acpi_last_full -
-                                               remaining_capacity) * 60 *
-                                              60 / present_rate);
-                       } else if (acpi_last_full != 0
-                                  && present_rate <= 0) {
-                               sprintf(last_battery_str, "charging %d%%",
-                                       remaining_capacity * 100 /
-                                       acpi_last_full);
-                       } else {
-                               strcpy(last_battery_str, "charging");
-                       }
-               }
-               /* discharging */
-               else if (strcmp(charging_state, "discharging") == 0) {
-                       if (present_rate > 0)
-                               format_seconds(last_battery_str, 63,
-                                              (remaining_capacity * 60 *
-                                               60) / present_rate);
-                       else
-                               sprintf(last_battery_str,
-                                       "discharging %d%%",
-                                       remaining_capacity * 100 /
-                                       acpi_last_full);
-               }
-               /* charged */
-               /* thanks to Lukas Zapletal <lzap@seznam.cz> */
-               else if (strcmp(charging_state, "charged") == 0) {
-                       if (acpi_last_full != 0
-                           && remaining_capacity != acpi_last_full)
-                               sprintf(last_battery_str, "charged %d%%",
-                                       remaining_capacity * 100 /
-                                       acpi_last_full);
-                       else
-                               strcpy(last_battery_str, "charged");
-               }
-               /* unknown, probably full / AC */
-               else {
-                       if (acpi_last_full != 0
-                           && remaining_capacity != acpi_last_full)
-                               sprintf(last_battery_str, "unknown %d%%",
-                                       remaining_capacity * 100 /
-                                       acpi_last_full);
-                       else
-                               strcpy(last_battery_str, "AC");
-               }
-       } else {
-               /* APM */
-               if (apm_bat_fp == NULL)
-                       apm_bat_fp = open_file(APM_PATH, &rep2);
-
-               if (apm_bat_fp != NULL) {
-                       int ac, status, flag, life;
-
-                       fscanf(apm_bat_fp,
-                              "%*s %*s %*x %x   %x       %x     %d%%",
-                              &ac, &status, &flag, &life);
-
-                       if (life == -1) {
-                               /* could check now that there is ac */
-                               snprintf(last_battery_str, 64, "AC");
-                       } else if (ac && life != 100) { /* could check that status==3 here? */
-                               snprintf(last_battery_str, 64,
-                                        "charging %d%%", life);
-                       } else {
-                               snprintf(last_battery_str, 64, "%d%%",
-                                        life);
-                       }
-
-                       /* it seemed to buffer it so file must be closed (or could use syscalls
-                        * directly but I don't feel like coding it now) */
-                       fclose(apm_bat_fp);
-                       apm_bat_fp = NULL;
-               }
-       }
-
-       snprintf(buf, n, "%s", last_battery_str);
-}
-
-void update_top()
-{
-       show_nice_processes = 1;
-       process_find_top(info.cpu, info.memu);
-}
diff --git a/mail.c b/mail.c
deleted file mode 100644 (file)
index baf7741..0000000
--- a/mail.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Conky, a system monitor, based on torsmo
- *
- * This program is licensed under BSD license, read COPYING
- *
- *  $Id$
- */
-
-#include "conky.h"
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-#include <dirent.h>
-
-char *current_mail_spool;
-
-static time_t last_mail_mtime;
-static double last_mail_update;
-
-void update_mail_count()
-{
-       struct stat buf;
-
-       if (current_mail_spool == NULL)
-               return;
-
-       /* TODO: use that fine file modification notify on Linux 2.4 */
-
-       /* don't check mail so often (9.5s is minimum interval) */
-       if (current_update_time - last_mail_update < 9.5)
-               return;
-       else
-               last_mail_update = current_update_time;
-
-       if (stat(current_mail_spool, &buf)) {
-               static int rep;
-               if (!rep) {
-                       ERR("can't stat %s: %s", current_mail_spool,
-                           strerror(errno));
-                       rep = 1;
-               }
-               return;
-       }
-#if HAVE_DIRENT_H
-       /* maildir format */
-       if (S_ISDIR(buf.st_mode)) {
-               DIR *dir;
-               char *dirname;
-               struct dirent *dirent;
-               info.mail_count = 0;
-               info.new_mail_count = 0;
-
-               dirname =
-                   (char *) malloc(sizeof(char) *
-                                   (strlen(current_mail_spool) + 5));
-               if (!dirname) {
-                       ERR("malloc");
-                       return;
-               }
-               strcpy(dirname, current_mail_spool);
-               strcat(dirname, "/");
-               /* checking the cur subdirectory */
-               strcat(dirname, "cur");
-
-               dir = opendir(dirname);
-               if (!dir) {
-                       ERR("cannot open directory");
-                       free(dirname);
-                       return;
-               }
-               dirent = readdir(dir);
-               while (dirent) {
-                       /* . and .. are skipped */
-                       if (dirent->d_name[0] != '.') {
-                               info.mail_count++;
-                       }
-                       dirent = readdir(dir);
-               }
-               closedir(dir);
-
-               dirname[strlen(dirname) - 3] = '\0';
-               strcat(dirname, "new");
-
-               dir = opendir(dirname);
-               if (!dir) {
-                       ERR("cannot open directory");
-                       free(dirname);
-                       return;
-               }
-               dirent = readdir(dir);
-               while (dirent) {
-                       /* . and .. are skipped */
-                       if (dirent->d_name[0] != '.') {
-                               info.new_mail_count++;
-                               info.mail_count++;
-                       }
-                       dirent = readdir(dir);
-               }
-               closedir(dir);
-
-               free(dirname);
-               return;
-       }
-#endif
-       /* mbox format */
-
-
-       if (buf.st_mtime != last_mail_mtime) {
-               /* yippee, modification time has changed, let's read mail count! */
-               static int rep;
-               FILE *fp;
-               int reading_status = 0;
-
-               /* could lock here but I don't think it's really worth it because
-                * this isn't going to write mail spool */
-
-               info.new_mail_count = 0;
-               info.mail_count = 0;
-
-               fp = open_file(current_mail_spool, &rep);
-               if (!fp)
-                       return;
-
-               /* NOTE: adds mail as new if there isn't Status-field at all */
-
-               while (!feof(fp)) {
-                       char buf[128];
-                       if (fgets(buf, 128, fp) == NULL)
-                               break;
-
-                       if (strncmp(buf, "From ", 5) == 0) {
-                               /* ignore MAILER-DAEMON */
-                               if (strncmp(buf + 5, "MAILER-DAEMON ", 14)
-                                   != 0) {
-                                       info.mail_count++;
-
-                                       if (reading_status)
-                                               info.new_mail_count++;
-                                       else
-                                               reading_status = 1;
-                               }
-                       } else {
-                               if (reading_status
-                                   && strncmp(buf, "X-Mozilla-Status:",
-                                              17) == 0) {
-                                       /* check that mail isn't already read */
-                                       if (strchr(buf + 21, '0'))
-                                               info.new_mail_count++;
-
-                                       reading_status = 0;
-                                       continue;
-                               }
-                               if (reading_status
-                                   && strncmp(buf, "Status:", 7) == 0) {
-                                       /* check that mail isn't already read */
-                                       if (strchr(buf + 7, 'R') == NULL)
-                                               info.new_mail_count++;
-
-                                       reading_status = 0;
-                                       continue;
-                               }
-                       }
-
-                       /* skip until \n */
-                       while (strchr(buf, '\n') == NULL && !feof(fp))
-                               fgets(buf, 128, fp);
-               }
-
-               fclose(fp);
-
-               if (reading_status)
-                       info.new_mail_count++;
-
-               last_mail_mtime = buf.st_mtime;
-       }
-}
diff --git a/mixer.c b/mixer.c
deleted file mode 100644 (file)
index 7b4ce24..0000000
--- a/mixer.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Conky, a system monitor, based on torsmo
- *
- * This program is licensed under BSD license, read COPYING
- *
- *  $Id$
- */
-
-#include "conky.h"
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-
-#ifdef HAVE_LINUX_SOUNDCARD_H
-#include <linux/soundcard.h>
-#else
-#include <sys/soundcard.h>
-#endif                         /* HAVE_LINUX_SOUNDCARD_H */
-
-#define MIXER_DEV "/dev/mixer"
-
-static int mixer_fd;
-static const char *devs[] = SOUND_DEVICE_NAMES;
-
-int mixer_init(const char *name)
-{
-       unsigned int i;
-
-       if (name == 0 || name[0] == '\0')
-               name = "vol";
-
-       /* open mixer */
-       if (mixer_fd <= 0) {
-               mixer_fd = open(MIXER_DEV, O_RDONLY);
-               if (mixer_fd == -1) {
-                       ERR("can't open %s: %s", MIXER_DEV,
-                           strerror(errno));
-                       return -1;
-               }
-       }
-
-       for (i = 0; i < sizeof(devs) / sizeof(const char *); i++) {
-               if (strcasecmp(devs[i], name) == 0) {
-                       return i;
-               }
-       }
-
-       return -1;
-}
-
-static int mixer_get(int i)
-{
-       static char rep = 0;
-       int val = -1;
-
-       if (ioctl(mixer_fd, MIXER_READ(i), &val) == -1) {
-               if (!rep)
-                       ERR("mixer ioctl: %s", strerror(errno));
-               rep = 1;
-               return 0;
-       }
-       rep = 0;
-
-       return val;
-}
-
-int mixer_get_avg(int i)
-{
-       int v = mixer_get(i);
-       return ((v >> 8) + (v & 0xFF)) / 2;
-}
-
-int mixer_get_left(int i)
-{
-       return mixer_get(i) >> 8;
-}
-
-int mixer_get_right(int i)
-{
-       return mixer_get(i) & 0xFF;
-}
diff --git a/mldonkey.c b/mldonkey.c
deleted file mode 100644 (file)
index 8f4381a..0000000
+++ /dev/null
@@ -1,456 +0,0 @@
-#include "conky.h"
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <netdb.h>
-#include <fcntl.h>
-#include <arpa/inet.h>
-
-
-int64 buf_to_int(char *buf, int pos, int size);
-void int_to_buf(int64 i, char *buf, int pos, int size);
-
-#define BUF16_TO_INT(buf, pos) buf_to_int((buf), (pos), 2)
-#define BUF32_TO_INT(buf, pos) buf_to_int((buf), (pos), 4)
-#define BUF64_TO_INT(buf, pos) buf_to_int((buf), (pos), 8)
-
-#define INT_TO_BUF16(i, buf, pos) int_to_buf((i), (buf), (pos), 2)
-#define INT_TO_BUF32(i, buf, pos) int_to_buf((i), (buf), (pos), 4)
-#define INT_TO_BUF64(i, buf, pos) int_to_buf((i), (buf), (pos), 8)
-
-mldonkey_info mlinfo;
-mldonkey_config mlconfig;
-
-/* Call this function to update the information about mldonkey.
- * Note that the function will not reconnect to mldonkey if the
- * pointer to the mldonkey_config has not changed. As it uses static
- * data, it cannot be used in a multithreaded env.
- * Returns 1 if connected and info filled, 0 if connected but not filled,
- * -1 otherwise. */
-
-enum to_gui {
-       CoreProtocol,           /* 0 */
-       Options_info,
-       RESERVED2,
-       DefineSearches,
-       Result_info,
-       Search_result,
-       Search_waiting,
-       File_info,
-       File_downloaded,
-       File_availability,
-       File_source,            /* 10 */
-       Server_busy,
-       Server_user,
-       Server_state,
-       Server_info,
-       Client_info,
-       Client_state,
-       Client_friend,
-       Client_file,
-       Console,
-       Network_info,           /* 20 */
-       User_info,
-       Room_info,
-       Room_message,
-       Room_add_user,
-       Client_stats,
-       Server_info_v2,
-       MessageFromClient,
-       ConnectedServers,
-       DownloadFiles,
-       DownloadedFiles,        /* 30 */
-       Room_info_v2,
-       Room_remove_user,
-       Shared_file_info,
-       Shared_file_upload,
-       Shared_file_unshared,
-       Add_section_option,
-       Client_stats_v2,
-       Add_plugin_option,
-       Client_stats_v3,
-       File_info_v2,           /* 40 */
-       DownloadFiles_v2,
-       DownloadedFiles_v2,
-       File_info_v3,
-       DownloadFiles_v3,
-       DownloadedFiles_v3,
-       File_downloaded_v2,
-       BadPassword,
-       Shared_file_info_v2,
-       Client_stats_v4,        /* 49 */
-};
-
-#define MLDONKEY_DISCONNECTED   0
-#define MLDONKEY_CONNECTING     1
-#define MLDONKEY_AUTHENTICATING 2
-#define MLDONKEY_CONNECTED      3
-
-#define MAX_MESSAGE_LEN 65000
-static int write_pos = 0;
-static char write_buf[MAX_MESSAGE_LEN];
-static char read_buf[MAX_MESSAGE_LEN];
-static int read_pos;
-static int mldonkey_sock = -1;
-static int mldonkey_state = MLDONKEY_DISCONNECTED;
-static mldonkey_config *old_config = NULL;
-
-/* int64 ------------------------------ */
-
-int64 buf_to_int(char *buf, int pos, int size)
-{
-       int i;
-       int64 res = 0;
-
-       for (i = 0; i < size; i++) {
-               res += (buf[pos + i] & 0xFF) << (8 * i);
-       }
-       return res;
-}
-
-void int_to_buf(int64 i, char *buf, int pos, int size)
-{
-       int j;
-
-       for (j = 0; j < size; j++) {
-               buf[pos + j] = (i & (-1)) >> (8 * j);
-       }
-}
-
-/* Write operations --------------------- */
-
-void init_message()
-{
-       write_pos = 0;
-}
-
-void write_int8(int code)
-{
-       write_buf[write_pos++] = code;
-}
-
-void write_opcode(int code)
-{
-       write_buf[write_pos++] = code;
-}
-
-void write_int16(int code)
-{
-       INT_TO_BUF16(code, write_buf, write_pos);
-       write_pos += 2;
-}
-
-void write_int32(int code)
-{
-       INT_TO_BUF32(code, write_buf, write_pos);
-       write_pos += 4;
-}
-
-void write_int64(int64 code)
-{
-       INT_TO_BUF64(code, write_buf, write_pos);
-       write_pos += 8;
-}
-
-void write_string(char *str)
-{
-       if (str == NULL) {
-               write_int16(0);
-       } else {
-               int len = strlen(str);
-               write_int16(len);
-               memcpy((void *) (write_buf + write_pos), (void *) str,
-                      (size_t) len);
-               write_pos += len;
-       }
-}
-
-
-int write_message(char *mtype)
-{
-       char header[4];
-
-       INT_TO_BUF32(write_pos, header, 0);
-       if (4 != write(mldonkey_sock, header, 4) ||
-           write_pos != write(mldonkey_sock, (void *) write_buf,
-                              (size_t) write_pos)) {
-               ERR("Error in transmitting %s\n", mtype);
-               write_pos = 0;
-
-               /* Immediatly close the connection */
-               close(mldonkey_sock);
-               mldonkey_state = MLDONKEY_DISCONNECTED;
-               mldonkey_sock = -1;
-               return -1;
-       } else {
-               write_pos = 0;
-               return 0;
-       }
-}
-
-
-/* Read operations ----------------------------*/
-
-int read_int8()
-{
-       return read_buf[read_pos++];
-}
-
-int read_int16()
-{
-       int i = BUF16_TO_INT(read_buf, read_pos);
-       read_pos += 2;
-       return i;
-}
-
-int read_int32()
-{
-       int i = BUF32_TO_INT(read_buf, read_pos);
-       read_pos += 4;
-       return i;
-}
-
-int64 read_int64()
-{
-       int64 i = BUF64_TO_INT(read_buf, read_pos);
-       read_pos += 8;
-       return i;
-}
-
-char *read_string()
-{
-       char *buf;
-       int len;
-
-       len = BUF16_TO_INT(read_buf, read_pos);
-       read_pos += 2;
-
-       buf = (char *) malloc((size_t) len + 1);
-       memmove(read_buf + read_pos, buf, len);
-       buf[len] = 0;
-       read_pos += len;
-
-       return buf;
-}
-
-/* protocol impl. ----------------------------- */
-
-void close_sock();
-
-/* This function returns the number of messages read, 0 if it blocks,
--1 on error. */
-int cut_messages(int reinit)
-{
-       int nread;
-       static int toread = 0;
-       static int pos = 0;
-
-       if (reinit) {
-               toread = 0;
-               pos = 0;
-               read_pos = 0;
-               return 0;
-       }
-
-       while (1) {
-               if (toread == 0) {
-                       nread =
-                           read(mldonkey_sock, read_buf + pos, 4 - pos);
-                       if (nread <= 0) {
-                               if (errno == EAGAIN) {
-                                       return 0;
-                               } else {
-                                       close_sock();
-                                       pos = 0;
-                                       toread = 0;
-                                       return -1;
-                               }
-                       }
-                       pos += nread;
-                       if (pos == 4) {
-                               toread = BUF32_TO_INT(read_buf, 0);
-                               pos = 0;
-                       }
-               } else {
-                       nread =
-                           read(mldonkey_sock, read_buf + pos,
-                                toread - pos);
-                       if (nread <= 0) {
-                               if (errno == EAGAIN)
-                                       return 0;
-                               else {
-                                       pos = 0;
-                                       toread = 0;
-                                       close_sock();
-                                       return -1;
-                               }
-                       }
-                       pos += nread;
-                       if (pos == toread) {
-                               /* We have one message !!! */
-                               int old_pos = pos;
-                               read_pos = 0;
-                               pos = 0;
-                               toread = 0;
-
-                               return old_pos;
-                       }
-               }
-       }
-}
-
-void close_sock()
-{
-       old_config = NULL;
-       if (mldonkey_sock >= 0)
-               close(mldonkey_sock);
-       mldonkey_sock = -1;
-       mldonkey_state = MLDONKEY_DISCONNECTED;
-       cut_messages(1);
-}
-
-int mldonkey_connect(mldonkey_config * config)
-{
-       if (config != old_config) {
-               struct sockaddr_in sa;
-               int retcode;
-               close_sock();
-
-
-               old_config = config;
-               /* resolve hostname */
-               memset(&sa, 0, sizeof(sa));
-
-               if (config->mldonkey_hostname == NULL)
-                       config->mldonkey_hostname = "127.0.0.1";
-               if (config->mldonkey_hostname[0] >= '0' &&
-                   config->mldonkey_hostname[0] <= '9') {
-#ifdef HAS_INET_ATON
-                       if (inet_aton
-                           (config->mldonkey_hostname, &sa.sin_addr) == 0)
-                               return -1;
-#else
-
-                       sa.sin_addr.s_addr =
-                           inet_addr(config->mldonkey_hostname);
-                       if (sa.sin_addr.s_addr == (unsigned int) -1)
-                               return -1;
-#endif
-
-               } else {
-                       struct hostent *hp;
-                       hp = gethostbyname(config->mldonkey_hostname);
-                       if (hp == (struct hostent *) NULL)
-                               return -1;
-                       sa.sin_addr.s_addr =
-                           (unsigned long) hp->h_addr_list[0];
-               }
-
-               sa.sin_port = htons(config->mldonkey_port);
-               sa.sin_family = AF_INET;
-
-               if ((mldonkey_sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
-                       ERR("Opening socket");
-                       close_sock();
-                       return -1;
-               }
-
-               if (connect
-                   (mldonkey_sock, (struct sockaddr *) &sa,
-                    sizeof(sa)) < 0) {
-                       if (errno != EAGAIN && errno != EINTR
-                           && errno != EINPROGRESS
-                           && errno != EWOULDBLOCK) {
-//        ERR("Connection failed");
-                               close_sock();
-                               return -1;
-                       }
-               }
-
-               retcode = fcntl(mldonkey_sock, F_GETFL, 0);
-               if (retcode == -1 ||
-                   fcntl(mldonkey_sock, F_SETFL,
-                         retcode | O_NONBLOCK) == -1) {
-                       return -1;
-               }
-
-
-               mldonkey_state = MLDONKEY_CONNECTING;
-               return 0;
-       }
-
-       return 0;
-}
-
-int mldonkey_can_read()
-{
-       return cut_messages(0);
-}
-
-int mldonkey_info_message(mldonkey_info * info)
-{
-       int opcode = read_int16();
-
-       switch (opcode) {
-
-       case CoreProtocol:
-               init_message();
-
-               write_int16(0); /* GUI protocol */
-               write_int32(10);        /* Version 10 ! */
-               write_message("GuiProtocol");
-
-               write_int16(47);        /* GUI protocol */
-
-               write_int16(1);
-               write_int32(1);
-               write_int8(1);
-               write_message("GuiExtensions");
-
-               init_message();
-               write_int16(5); /* Password */
-               write_string(old_config->mldonkey_password);
-               write_message("Password");
-
-               break;
-
-       case BadPassword:
-               ERR("Bad Password\n");
-               close_sock();
-               break;
-
-       case Client_stats:
-       case Client_stats_v2:
-       case Client_stats_v3:
-               ERR("Client stats format too old...\n");
-               break;
-
-       case Client_stats_v4:
-               mldonkey_state = MLDONKEY_CONNECTED;
-
-               info->upload_counter = read_int64();
-               info->download_counter = read_int64();
-               info->shared_counter = read_int64();
-               info->nshared_files = read_int32();
-               info->tcp_upload_rate = read_int32();
-               info->tcp_download_rate = read_int32();
-               info->udp_upload_rate = read_int32();
-               info->udp_download_rate = read_int32();
-               info->ndownloading_files = read_int32();
-               info->ndownloaded_files = read_int32();
-
-               break;
-       }
-
-       return 0;
-}
-
-int get_mldonkey_status(mldonkey_config * config, mldonkey_info * info)
-{
-       if (mldonkey_connect(config) >= 0) {
-               while (mldonkey_can_read() > 0) {
-                       mldonkey_info_message(info);
-               }
-       }
-       return mldonkey_state;
-}
diff --git a/mpd.c b/mpd.c
deleted file mode 100644 (file)
index c21ec01..0000000
--- a/mpd.c
+++ /dev/null
@@ -1,154 +0,0 @@
-#include "conky.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "libmpdclient.h"
-
-
-void update_mpd()
-{
-       struct information *current_info = &info;
-       current_info->conn =
-           mpd_newConnection(current_info->mpd.host,
-                             current_info->mpd.port, 10);
-       if (current_info->conn->error) {
-               //fprintf(stderr, "%s\n", current_info->conn->errorStr);
-               mpd_closeConnection(current_info->conn);
-               if (current_info->mpd.artist == NULL)
-                       current_info->mpd.artist =
-                           malloc(TEXT_BUFFER_SIZE);
-               if (current_info->mpd.album == NULL)
-                       current_info->mpd.album = malloc(TEXT_BUFFER_SIZE);
-               if (current_info->mpd.title == NULL)
-                       current_info->mpd.title = malloc(TEXT_BUFFER_SIZE);
-               strcpy(current_info->mpd.artist, "Unknown");
-               strcpy(current_info->mpd.album, "Unknown");
-               strcpy(current_info->mpd.title, "Unknown");
-               current_info->mpd.status = "MPD not responding";
-               current_info->mpd.bitrate = 0;
-               current_info->mpd.progress = 0;
-               current_info->mpd.elapsed = 0;
-               current_info->mpd.length = 0;
-               return;
-       }
-
-       mpd_Status *status;
-       mpd_InfoEntity *entity;
-       mpd_sendCommandListOkBegin(current_info->conn);
-       mpd_sendStatusCommand(current_info->conn);
-       mpd_sendCurrentSongCommand(current_info->conn);
-       mpd_sendCommandListEnd(current_info->conn);
-       if ((status = mpd_getStatus(current_info->conn)) == NULL) {
-               //fprintf(stderr, "%s\n", current_info->conn->errorStr);
-               mpd_closeConnection(current_info->conn);
-               if (current_info->mpd.artist == NULL)
-                       current_info->mpd.artist =
-                           malloc(TEXT_BUFFER_SIZE);
-               if (current_info->mpd.album == NULL)
-                       current_info->mpd.album = malloc(TEXT_BUFFER_SIZE);
-               if (current_info->mpd.title == NULL)
-                       current_info->mpd.title = malloc(TEXT_BUFFER_SIZE);
-               strcpy(current_info->mpd.artist, "Unknown");
-               strcpy(current_info->mpd.album, "Unknown");
-               strcpy(current_info->mpd.title, "Unknown");
-               current_info->mpd.status = "MPD not responding";
-               current_info->mpd.bitrate = 0;
-               current_info->mpd.progress = 0;
-               current_info->mpd.elapsed = 0;
-               current_info->mpd.length = 0;
-               return;
-       }
-       current_info->mpd.volume = status->volume;
-       //if (status->error)
-       //printf("error: %s\n", status->error);
-
-       if (status->state == MPD_STATUS_STATE_PLAY) {
-               current_info->mpd.status = "Playing";
-       }
-       if (status->state == MPD_STATUS_STATE_STOP) {
-               current_info->mpd.status = "Stopped";
-               current_info->mpd.bitrate = 0;
-               current_info->mpd.progress = 0;
-               current_info->mpd.elapsed = 0;
-               current_info->mpd.length = 0;
-       }
-       if (status->state == MPD_STATUS_STATE_PAUSE) {
-               current_info->mpd.status = "Paused";
-       }
-       if (status->state == MPD_STATUS_STATE_UNKNOWN) {
-               current_info->mpd.status = "Unknown";
-               current_info->mpd.bitrate = 0;
-               current_info->mpd.progress = 0;
-               current_info->mpd.elapsed = 0;
-               current_info->mpd.length = 0;
-       }
-       if (status->state == MPD_STATUS_STATE_PLAY ||
-           status->state == MPD_STATUS_STATE_PAUSE) {
-               current_info->mpd.bitrate = status->bitRate;
-               current_info->mpd.progress =
-                   (float) status->elapsedTime / status->totalTime;
-               current_info->mpd.elapsed = status->elapsedTime;
-               current_info->mpd.length = status->totalTime;
-       }
-
-
-       if (current_info->conn->error) {
-               //fprintf(stderr, "%s\n", current_info->conn->errorStr);
-               mpd_closeConnection(current_info->conn);
-               return;
-       }
-
-       mpd_nextListOkCommand(current_info->conn);
-
-       while ((entity = mpd_getNextInfoEntity(current_info->conn))) {
-               mpd_Song *song = entity->info.song;
-               if (entity->type != MPD_INFO_ENTITY_TYPE_SONG) {
-                       mpd_freeInfoEntity(entity);
-                       continue;
-               }
-
-               if (current_info->mpd.artist == NULL)
-                       current_info->mpd.artist =
-                           malloc(TEXT_BUFFER_SIZE);
-               if (current_info->mpd.album == NULL)
-                       current_info->mpd.album = malloc(TEXT_BUFFER_SIZE);
-               if (current_info->mpd.title == NULL)
-                       current_info->mpd.title = malloc(TEXT_BUFFER_SIZE);
-               if (song->artist) {
-                       strcpy(current_info->mpd.artist, song->artist);
-               } else {
-                       strcpy(current_info->mpd.artist, "Unknown");
-               }
-               if (song->album) {
-                       strcpy(current_info->mpd.album, song->album);
-               } else {
-                       strcpy(current_info->mpd.album, "Unknown");
-               }
-               if (song->title) {
-                       strcpy(current_info->mpd.title, song->title);
-               } else {
-                       strcpy(current_info->mpd.title, "Unknown");
-               }
-               if (entity != NULL) {
-                       mpd_freeInfoEntity(entity);
-               }
-       }
-       if (entity != NULL) {
-               mpd_freeInfoEntity(entity);
-       }
-
-       if (current_info->conn->error) {
-               //fprintf(stderr, "%s\n", current_info->conn->errorStr);
-               mpd_closeConnection(current_info->conn);
-               return;
-       }
-
-       mpd_finishCommand(current_info->conn);
-       if (current_info->conn->error) {
-               //fprintf(stderr, "%s\n", current_info->conn->errorStr);
-               mpd_closeConnection(current_info->conn);
-               return;
-       }
-       mpd_freeStatus(status);
-       mpd_closeConnection(current_info->conn);
-}
diff --git a/netbsd.c b/netbsd.c
deleted file mode 100644 (file)
index 6e4fcbf..0000000
--- a/netbsd.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/* NetBSD port */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <time.h>
-#include <unistd.h>
-#include <err.h>
-#include <limits.h>
-#include <paths.h>
-
-#include <kvm.h>
-#include <nlist.h>
-
-#include <sys/time.h>
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/user.h>
-#include <sys/socket.h>
-#include <sys/swap.h>
-#include <sys/sched.h>
-#include <sys/envsys.h>
-
-#include <net/if.h>
-
-#include <uvm/uvm_extern.h>
-
-#include <machine/param.h>
-
-#include "conky.h"
-
-
-static kvm_t *kd = NULL;
-int kd_init = 0, nkd_init = 0;
-u_int32_t sensvalue;
-char errbuf[_POSIX2_LINE_MAX];
-
-static int init_kvm(void)
-{
-       if (kd_init)
-               return 0;
-
-       kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf);
-       if (kd == NULL) {
-               (void) warnx("cannot kvm_openfiles: %s", errbuf);
-               return -1;
-       }
-       kd_init = 1;
-       return 0;
-}
-
-static int swapmode(int *retavail, int *retfree)
-{
-       int n;
-       struct swapent *sep;
-
-       *retavail = 0;
-       *retfree = 0;
-
-       n = swapctl(SWAP_NSWAP, 0, 0);
-
-       if (n < 1) {
-               (void) warn("could not get swap information");
-               return 0;
-       }
-
-       sep = (struct swapent *) malloc(n * (sizeof(*sep)));
-
-       if (sep == NULL) {
-               (void) warn("memory allocation failed");
-               return 0;
-       }
-
-       if (swapctl(SWAP_STATS, (void *) sep, n) < n) {
-               (void) warn("could not get swap stats");
-               return 0;
-       }
-       for (; n > 0; n--) {
-               *retavail += (int) dbtob(sep[n - 1].se_nblks);
-               *retfree +=
-                   (int) dbtob(sep[n - 1].se_nblks - sep[n - 1].se_inuse);
-       }
-       *retavail = (int) (*retavail / 1024);
-       *retfree = (int) (*retfree / 1024);
-
-       return 1;
-}
-
-
-void prepare_update()
-{
-}
-
-void update_uptime()
-{
-       int mib[2] = { CTL_KERN, KERN_BOOTTIME };
-       struct timeval boottime;
-       time_t now;
-       int size = sizeof(boottime);
-
-       if ((sysctl(mib, 2, &boottime, &size, NULL, 0) != -1)
-           && (boottime.tv_sec != 0)) {
-               (void) time(&now);
-               info.uptime = now - boottime.tv_sec;
-       } else {
-               (void) warn("could not get uptime");
-               info.uptime = 0;
-       }
-}
-
-
-void update_meminfo()
-{
-       int mib[] = { CTL_VM, VM_UVMEXP2 };
-       int total_pages, inactive_pages, free_pages;
-       int swap_avail, swap_free;
-       const int pagesize = getpagesize();
-       struct uvmexp_sysctl uvmexp;
-       size_t size = sizeof(uvmexp);
-
-       info.memmax = info.mem = 0;
-       info.swapmax = info.swap = 0;
-
-
-       if (sysctl(mib, 2, &uvmexp, &size, NULL, 0) < 0) {
-               warn("could not get memory info");
-               return;
-       }
-
-       total_pages = uvmexp.npages;
-       free_pages = uvmexp.free;
-       inactive_pages = uvmexp.inactive;
-
-       info.memmax = (total_pages * pagesize) >> 10;
-       info.mem =
-           ((total_pages - free_pages - inactive_pages) * pagesize) >> 10;
-
-       if (swapmode(&swap_avail, &swap_free) >= 0) {
-               info.swapmax = swap_avail;
-               info.swap = (swap_avail - swap_free);
-       }
-}
-
-void update_net_stats()
-{
-       int i;
-       double delta;
-       struct ifnet ifnet;
-       struct ifnet_head ifhead;       /* interfaces are in a tail queue */
-       u_long ifnetaddr;
-       static struct nlist namelist[] = {
-               {"_ifnet"},
-               {NULL},
-       };
-       static kvm_t *nkd;
-
-       if (!nkd_init) {
-               nkd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
-               if (nkd == NULL) {
-                       (void) warnx("cannot kvm_openfiles: %s", errbuf);
-                       (void)
-                           warnx
-                           ("maybe you need to setgid kmem this program?");
-                       return;
-               } else if (kvm_nlist(nkd, namelist) != 0) {
-                       (void) warn("cannot kvm_nlist");
-                       return;
-               } else
-                       nkd_init = 1;
-       }
-
-       if (kvm_read(nkd, (u_long) namelist[0].n_value, (void *) &ifhead,
-                    sizeof(ifhead)) < 0) {
-               (void) warn("cannot kvm_read");
-               return;
-       }
-
-       /* get delta */
-       delta = current_update_time - last_update_time;
-       if (delta <= 0.0001)
-               return;
-
-       for (i = 0, ifnetaddr = (u_long) ifhead.tqh_first;
-            ifnet.if_list.tqe_next && i < 16;
-            ifnetaddr = (u_long) ifnet.if_list.tqe_next, i++) {
-
-               struct net_stat *ns;
-               long long last_recv, last_trans;
-
-               (void) kvm_read(nkd, (u_long) ifnetaddr, (void *) &ifnet,
-                               sizeof(ifnet));
-               ns = get_net_stat(ifnet.if_xname);
-               ns->up = 1;
-               last_recv = ns->recv;
-               last_trans = ns->trans;
-
-               if (ifnet.if_ibytes < ns->last_read_recv)
-                       ns->recv +=
-                           ((long long) 4294967295U -
-                            ns->last_read_recv) + ifnet.if_ibytes;
-               else
-                       ns->recv += (ifnet.if_ibytes - ns->last_read_recv);
-
-               ns->last_read_recv = ifnet.if_ibytes;
-
-               if (ifnet.if_obytes < ns->last_read_trans)
-                       ns->trans +=
-                           ((long long) 4294967295U -
-                            ns->last_read_trans) + ifnet.if_obytes;
-               else
-                       ns->trans +=
-                           (ifnet.if_obytes - ns->last_read_trans);
-
-               ns->last_read_trans = ifnet.if_obytes;
-
-               ns->recv += (ifnet.if_ibytes - ns->last_read_recv);
-               ns->last_read_recv = ifnet.if_ibytes;
-               ns->trans += (ifnet.if_obytes - ns->last_read_trans);
-               ns->last_read_trans = ifnet.if_obytes;
-
-               ns->recv_speed = (ns->recv - last_recv) / delta;
-               ns->trans_speed = (ns->trans - last_trans) / delta;
-       }
-}
-
-void update_total_processes()
-{
-       /* It's easier to use kvm here than sysctl */
-
-       int n_processes;
-
-       info.procs = 0;
-
-       if (init_kvm() < 0)
-               return;
-       else
-               kvm_getproc2(kd, KERN_PROC_ALL, 0,
-                            sizeof(struct kinfo_proc2), &n_processes);
-
-       info.procs = n_processes;
-}
-
-void update_running_processes()
-{
-       struct kinfo_proc2 *p;
-       int n_processes;
-       int i, cnt = 0;
-
-       info.run_procs = 0;
-
-       if (init_kvm() < 0)
-               return;
-       else {
-               p = kvm_getproc2(kd, KERN_PROC_ALL, 0,
-                                sizeof(struct kinfo_proc2), &n_processes);
-               for (i = 0; i < n_processes; i++)
-                       if (p[i].p_stat == LSRUN || p[i].p_stat == LSIDL ||
-                           p[i].p_stat == LSONPROC)
-                               cnt++;
-       }
-
-       info.run_procs = cnt;
-}
-
-struct cpu_load_struct {
-       unsigned long load[5];
-};
-
-struct cpu_load_struct fresh = {
-       {0, 0, 0, 0, 0}
-};
-
-long cpu_used, oldtotal, oldused;
-
-void update_cpu_usage()
-{
-       long used, total;
-       static u_int64_t cp_time[CPUSTATES];
-       size_t len = sizeof(cp_time);
-
-       info.cpu_usage = 0;
-
-       if (sysctlbyname("kern.cp_time", &cp_time, &len, NULL, 0) < 0)
-               (void) warn("cannot get kern.cp_time");
-
-
-       fresh.load[0] = cp_time[CP_USER];
-       fresh.load[1] = cp_time[CP_NICE];
-       fresh.load[2] = cp_time[CP_SYS];
-       fresh.load[3] = cp_time[CP_IDLE];
-       fresh.load[4] = cp_time[CP_IDLE];
-
-       used = fresh.load[0] + fresh.load[1] + fresh.load[2];
-       total =
-           fresh.load[0] + fresh.load[1] + fresh.load[2] + fresh.load[3];
-
-       if ((total - oldtotal) != 0)
-               info.cpu_usage =
-                   ((double) (used - oldused)) / (double) (total -
-                                                           oldtotal);
-       else
-               info.cpu_usage = 0;
-
-       oldused = used;
-       oldtotal = total;
-
-}
-
-double get_i2c_info(int *fd, int div, char *devtype)
-{
-       return -1;
-}
-
-void update_load_average()
-{
-       double v[3];
-       getloadavg(v, 3);
-
-       info.loadavg[0] = (float) v[0];
-       info.loadavg[1] = (float) v[1];
-       info.loadavg[2] = (float) v[2];
-}
-
-double get_acpi_temperature(int fd)
-{
-       return -1;
-}
-
-void get_battery_stuff(char *buf, unsigned int n, const char *bat)
-{
-}
-
-int
-open_i2c_sensor(const char *dev, const char *type, int n, int *div,
-               char *devtype)
-{
-       return -1;
-}
-
-int open_acpi_temperature(const char *name)
-{
-       return -1;
-}
-
-char *get_acpi_ac_adapter(void)
-{
-       return "N/A";
-}
-
-char *get_acpi_fan()
-{
-       return "N/A";
-}
diff --git a/remotec.c b/remotec.c
deleted file mode 100644 (file)
index dbe5bf0..0000000
--- a/remotec.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Conky, a system monitor, based on torsmo
- *
- * This program is licensed under BSD license, read COPYING
- *
- *  $Id$
- */
- /*
- okay, nothing here right now.  thanks for coming out
- */
-
-#include "conky.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <netdb.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-
-#define PORT 3490 // the port client will be connecting to 
-
-#define MAXDATASIZE 100 // max number of bytes we can get at once 
-
-void client()
-{
-       int sockfd, numbytes;  
-       char buf[MAXDATASIZE];
-       struct hostent *he;
-       struct sockaddr_in their_addr; // connector's address information 
-       if ((he=gethostbyname("localhost")) == NULL) {  // get the host info 
-               perror("gethostbyname");
-               exit(1);
-       }
-
-       if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
-               perror("socket");
-               exit(1);
-       }
-
-       their_addr.sin_family = AF_INET;    // host byte order 
-       their_addr.sin_port = htons(PORT);  // short, network byte order 
-       their_addr.sin_addr = *((struct in_addr *)he->h_addr);
-       memset(&(their_addr.sin_zero), '\0', 8);  // zero the rest of the struct 
-
-       if (connect(sockfd, (struct sockaddr *)&their_addr,
-           sizeof(struct sockaddr)) == -1) {
-                   perror("connect");
-                   exit(1);
-           }
-
-           if ((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) {
-                   perror("recv");
-                   exit(1);
-           }
-
-           buf[numbytes] = '\0';
-
-           printf("Received: %s",buf);
-
-           close(sockfd);
-
-           return 0;
-}
diff --git a/remotec.h b/remotec.h
deleted file mode 100644 (file)
index 37ed44d..0000000
--- a/remotec.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Conky, a system monitor, based on torsmo
- *
- * This program is licensed under BSD license, read COPYING
- *
- *  $Id$
- */
-  /*
- okay, nothing here right now.  thanks for coming out
-  */
-
-void client();
diff --git a/remoted.c b/remoted.c
deleted file mode 100644 (file)
index b6136c4..0000000
--- a/remoted.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
-* Conky, a system monitor, based on torsmo
-*
-* This program is licensed under BSD license, read COPYING
-*
-*  $Id$
-*/
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/wait.h>
-#include <signal.h>
-
-static pthread_t daemon_thread;
-static int daemon_status = 0;
-static char *data;
-
-/* okay, heres how it will basically work.
-* when something connects, it will first send the conkyrc on the local (daemonized) server
-* after this, it will simply continue to send all the buffered text to the remote client
-* http://analyser.oli.tudelft.nl/beej/mirror/net/html/
-*  http://www.kegel.com/c10k.html
-*/
-
-#define MYPORT 3490    // the port users will be connecting to
-
-#define BACKLOG 10     // how many pending connections queue will hold
-
-void sigchld_handler(int s)
-{
-       while(wait(NULL) > 0);
-}
-
-void *daemon_loop()
-{
-       /* do something */
-
-
-
-       int sockfd, new_fd;  // listen on sock_fd, new connection on new_fd
-       struct sockaddr_in my_addr;    // my address information
-       struct sockaddr_in their_addr; // connector's address information
-       int sin_size;
-       struct sigaction sa;
-       int yes=1;
-
-       if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
-               perror("socket");
-               exit(1);
-       }
-
-       if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
-               perror("setsockopt");
-               exit(1);
-       }
-       
-       my_addr.sin_family = AF_INET;         // host byte order
-       my_addr.sin_port = htons(MYPORT);     // short, network byte order
-       my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
-       memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct
-
-       if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))
-                  == -1) {
-               perror("bind");
-               exit(1);
-                  }
-
-                  if (listen(sockfd, BACKLOG) == -1) {
-                          perror("listen");
-                          exit(1);
-                  }
-
-                  sa.sa_handler = sigchld_handler; // reap all dead processes
-                  sigemptyset(&sa.sa_mask);
-                  sa.sa_flags = SA_RESTART;
-                  if (sigaction(SIGCHLD, &sa, NULL) == -1) {
-                          perror("sigaction");
-                          exit(1);
-                  }
-
-                  while(1) {  // main accept() loop
-                          sin_size = sizeof(struct sockaddr_in);
-                          if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr,
-                               &sin_size)) == -1) {
-                                       perror("accept");
-                                       continue;
-                               }
-                               printf("server: got connection from %s\n",
-                                      inet_ntoa(their_addr.sin_addr));
-                               if (!fork()) { // this is the child process
-                                       close(sockfd); // child doesn't need the listener
-                                       if (send(new_fd, data, 14, 0) == -1)
-                                               perror("send");
-                                       close(new_fd);
-                                       exit(0);
-                               }
-                               close(new_fd);  // parent doesn't need this
-                  }
-
-                  return 0;
-}
-
-void daemon_run(const char *s)
-{
-       /* create thread, keep an eye on it */
-       data = s;
-       int iret;
-       if (!daemon_status) {
-               daemon_status = 1;
-               iret = pthread_create(&daemon_thread, NULL, daemon_loop, NULL);
-       } else if (daemon_status == 1) {
-               /* thread is still running, we'll just wait for it to finish for now */
-               pthread_join(daemon_thread, NULL);
-               daemon_status = 0;
-       } else {
-               /* something else */
-       }
-}
diff --git a/remoted.h b/remoted.h
deleted file mode 100644 (file)
index b198389..0000000
--- a/remoted.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Conky, a system monitor, based on torsmo
- *
- * This program is licensed under BSD license, read COPYING
- *
- *  $Id$
- */
-
-#include "conky.h"
-
-void daemon_run(const char *s);
diff --git a/seti.c b/seti.c
deleted file mode 100644 (file)
index 1c8a8d5..0000000
--- a/seti.c
+++ /dev/null
@@ -1,103 +0,0 @@
-#include "conky.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-char *seti_dir = NULL;
-
-//Need to code for BOINC, because the old SETI@Home does not use xml to store data.
-//Perhaps in the .conkyrc file there could be an option for BOINC or old SETI.
-
-/*static float seti_get_float (FILE *fp, const char *name)
-{
-  char buffer[80];
-  char *token;
-
-  while (!feof(fp) && !ferror (fp))
-  {
-    fgets(buffer, 80, fp);
-    token = strtok(buffer, ">");
-
-    if (strcmp(token, name) == 0)
-    {
-      token = strtok(NULL, "<");
-      if ( token != NULL )
-        return atof (token);
-      break;
-    }
-  }
-  return 0.0f;
-}*/
-
-float seti_get_data(FILE * fp, const char *name)
-{
-       char token[1000];
-       char buffer[1000];
-       float data;
-
-       while (fgets(token, 1000, fp) != NULL)  //read the file
-               if (strncmp(token, name, strlen(name)) == 0) {  //and search for the data in name
-                       strcpy(buffer, strchr(token, '=') + 1); //copy just the number
-                       break;
-               }
-       data = atof(buffer);
-       return data;
-}
-
-void update_seti()
-{
-       if (seti_dir == NULL)
-               return;
-
-       char filename[80];
-
-       struct information *current_info = &info;
-
-       current_info->seti_prog = current_info->seti_credit = 0.0f;
-
-       /* read total user credit */
-
-       /*FILE *fp = fopen(filename, "r");
-          if (!fp)
-          return;
-
-          seti_credit = seti_get_float(fp, "<user_total_credit");
-
-          fclose (fp); */
-
-       snprintf(filename, 80, "%s/user_info.sah", seti_dir);
-
-       FILE *fp = fopen(filename, "r");
-
-       if (!fp) {
-               return;
-       }
-
-       current_info->seti_credit = seti_get_data(fp, "nresults");
-
-       fclose(fp);
-
-       /* read current progress */
-
-       /*snprintf(filename, 80, "%s/slots/0/state.sah", seti_dir);
-          fp = fopen(filename, "r");
-          if (!fp)
-          return;
-
-          seti_prog = seti_get_float(fp, "<prog");
-
-          fclose (fp);
-
-          snprintf(filename, 80, "%s/slots/0/init_data.xml", seti_dir); */
-
-       snprintf(filename, 80, "%s/state.sah", seti_dir);
-
-       fp = fopen(filename, "r");
-       if (!fp)
-               return;
-
-       current_info->seti_prog = seti_get_data(fp, "prog");
-
-       fclose(fp);
-
-}
diff --git a/solaris.c b/solaris.c
deleted file mode 100644 (file)
index 3854336..0000000
--- a/solaris.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/* doesn't work, feel free to finish this */
-#include "conky.h"
-#include <kstat.h>
-
-static kstat_ctl_t *kstat;
-static int kstat_updated;
-
-static void update_kstat()
-{
-       if (kstat == NULL) {
-               kstat = kstat_open();
-               if (kstat == NULL) {
-                       ERR("can't open kstat: %s", strerror(errno));
-               }
-       }
-
-       if (kstat_chain_update(kstat) == -1) {
-               perror("kstat_chain_update");
-               return;
-       }
-}
-
-void prepare_update()
-{
-       kstat_updated = 0;
-}
-
-double get_uptime()
-{
-       kstat_t *ksp;
-
-       update_kstat();
-
-       ksp = kstat_lookup(kstat, "unix", -1, "system_misc");
-       if (ksp != NULL) {
-               if (kstat_read(kstat, ksp, NULL) >= 0) {
-                       kstat_named_t *knp;
-                       knp =
-                           (kstat_named_t *) kstat_data_lookup(ksp,
-                                                               "boot_time");
-                       if (knp != NULL) {
-                               return get_time() -
-                                   (double) knp->value.ui32;
-                       }
-               }
-       }
-}
-
-void update_meminfo()
-{
-       /* TODO */
-}
diff --git a/src/cairo.c b/src/cairo.c
new file mode 100644 (file)
index 0000000..c2008aa
--- /dev/null
@@ -0,0 +1,231 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* Small example demonstrating emulating knockout-groups as in PDF-1.4
+ * using cairo_set_operator().
+ *
+ * Owen Taylor,
+
+ * v0.1  30 November  2002
+ * v0.2   1 December  2002 - typo fixes from Keith Packard
+ * v0.3  17 April     2003 - Tracking changes in Xr, (Removal of Xr{Push,Pop}Group)
+ * v0.4  29 September 2003 - Use cairo_rectangle rather than private rect_path
+ *                          Use cairo_arc for oval_path
+ * Keeping log of changes in ChangeLog/CVS now. (2003-11-19) Carl Worth
+ */
+#include "conky.h"
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <cairo.h>
+#include <cairo-xlib.h>
+#include <math.h>
+#include <stdio.h>
+
+/* Fill the given area with checks in the standard style
+ * for showing compositing effects.
+ */
+static void fill_checks(cairo_t * cr, int x, int y, int width, int height)
+{
+       cairo_surface_t *check;
+       cairo_pattern_t *check_pattern;
+
+       cairo_save(cr);
+
+#define CHECK_SIZE 32
+
+       check =
+           cairo_surface_create_similar(cairo_current_target_surface(cr),
+                                        CAIRO_FORMAT_RGB24,
+                                        2 * CHECK_SIZE, 2 * CHECK_SIZE);
+       cairo_surface_set_repeat(check, 1);
+
+       /* Draw the check */
+       {
+               cairo_save(cr);
+
+               cairo_set_target_surface(cr, check);
+
+               cairo_set_operator(cr, CAIRO_OPERATOR_SRC);
+
+               cairo_set_rgb_color(cr, 0.4, 0.4, 0.4);
+
+               cairo_rectangle(cr, 0, 0, 2 * CHECK_SIZE, 2 * CHECK_SIZE);
+               cairo_fill(cr);
+
+               cairo_set_rgb_color(cr, 0.7, 0.7, 0.7);
+
+               cairo_rectangle(cr, x, y, CHECK_SIZE, CHECK_SIZE);
+               cairo_fill(cr);
+               cairo_rectangle(cr, x + CHECK_SIZE, y + CHECK_SIZE,
+                               CHECK_SIZE, CHECK_SIZE);
+               cairo_fill(cr);
+
+               cairo_restore(cr);
+       }
+
+       /* Fill the whole surface with the check */
+
+       check_pattern = cairo_pattern_create_for_surface(check);
+       cairo_set_pattern(cr, check_pattern);
+       cairo_rectangle(cr, 0, 0, width, height);
+       cairo_fill(cr);
+
+       cairo_pattern_destroy(check_pattern);
+       cairo_surface_destroy(check);
+
+       cairo_restore(cr);
+}
+
+static void draw_pee(cairo_t * cr, double xc, double yc)
+{
+       cairo_set_rgb_color(cr, 0, 0, 0);
+       cairo_show_text(cr, "Conky");
+}
+
+static void draw(cairo_t * cr, int width, int height)
+{
+       cairo_surface_t *overlay;
+
+       /* Fill the background */
+       double xc = width / 2.;
+       double yc = height / 2.;
+
+       overlay =
+           cairo_surface_create_similar(cairo_current_target_surface(cr),
+                                        CAIRO_FORMAT_ARGB32, width,
+                                        height);
+       if (overlay == NULL)
+               return;
+
+       fill_checks(cr, 0, 0, width, height);
+
+       cairo_save(cr);
+       cairo_set_target_surface(cr, overlay);
+
+       cairo_set_alpha(cr, 0.5);
+       cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
+       draw_pee(cr, xc, yc);
+
+       cairo_restore(cr);
+
+       cairo_show_surface(cr, overlay, width, height);
+
+       cairo_surface_destroy(overlay);
+}
+
+int do_it(void)
+{
+       Display *dpy;
+       int screen;
+       Window w;
+       Pixmap pixmap;
+       char *title = "cairo: Knockout Groups";
+       unsigned int quit_keycode;
+       int needs_redraw;
+       GC gc;
+       XWMHints *wmhints;
+       XSizeHints *normalhints;
+       XClassHint *classhint;
+
+       int width = 400;
+       int height = 400;
+
+       dpy = XOpenDisplay(NULL);
+       screen = DefaultScreen(dpy);
+
+       w = XCreateSimpleWindow(dpy, RootWindow(dpy, screen),
+                               0, 0, width, height, 0,
+                               BlackPixel(dpy, screen), WhitePixel(dpy,
+                                                                   screen));
+
+       normalhints = XAllocSizeHints();
+       normalhints->flags = 0;
+       normalhints->x = 0;
+       normalhints->y = 0;
+       normalhints->width = width;
+       normalhints->height = height;
+
+       classhint = XAllocClassHint();
+       classhint->res_name = "cairo-knockout";
+       classhint->res_class = "Cairo-knockout";
+
+       wmhints = XAllocWMHints();
+       wmhints->flags = InputHint;
+       wmhints->input = True;
+
+       XmbSetWMProperties(dpy, w, title, "cairo-knockout", 0, 0,
+                          normalhints, wmhints, classhint);
+       XFree(wmhints);
+       XFree(classhint);
+       XFree(normalhints);
+
+       pixmap =
+           XCreatePixmap(dpy, w, width, height,
+                         DefaultDepth(dpy, screen));
+       gc = XCreateGC(dpy, pixmap, 0, NULL);
+
+       quit_keycode = XKeysymToKeycode(dpy, XStringToKeysym("Q"));
+
+       XSelectInput(dpy, w,
+                    ExposureMask | StructureNotifyMask | ButtonPressMask |
+                    KeyPressMask);
+       XMapWindow(dpy, w);
+
+       needs_redraw = 1;
+
+       while (1) {
+               XEvent xev;
+
+               /* Only do the redraw if there are no events pending.  This
+                * avoids us getting behind doing several redraws for several
+                * consecutive resize events for example.
+                */
+               if (!XPending(dpy) && needs_redraw) {
+                       cairo_t *cr = cairo_create();
+
+                       cairo_set_target_drawable(cr, dpy, pixmap);
+
+                       draw(cr, width, height);
+
+                       cairo_destroy(cr);
+
+                       XCopyArea(dpy, pixmap, w, gc,
+                                 0, 0, width, height, 0, 0);
+
+                       needs_redraw = 0;
+               }
+
+               XNextEvent(dpy, &xev);
+
+               switch (xev.xany.type) {
+               case ButtonPress:
+                       /* A click on the canvas ends the program */
+                       goto DONE;
+               case KeyPress:
+                       if (xev.xkey.keycode == quit_keycode)
+                               goto DONE;
+                       break;
+               case ConfigureNotify:
+                       /* Note new size and create new pixmap. */
+                       width = xev.xconfigure.width;
+                       height = xev.xconfigure.height;
+                       XFreePixmap(dpy, pixmap);
+                       pixmap =
+                           XCreatePixmap(dpy, w, width, height,
+                                         DefaultDepth(dpy, screen));
+                       needs_redraw = 1;
+                       break;
+               case Expose:
+                       XCopyArea(dpy, pixmap, w, gc,
+                                 xev.xexpose.x, xev.xexpose.y,
+                                 xev.xexpose.width, xev.xexpose.height,
+                                 xev.xexpose.x, xev.xexpose.y);
+                       break;
+               }
+       }
+      DONE:
+
+       XFreeGC(dpy, gc);
+       XCloseDisplay(dpy);
+
+       return 0;
+}
diff --git a/src/common.c b/src/common.c
new file mode 100644 (file)
index 0000000..f61d6b8
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * Conky, a system monitor, based on torsmo
+ *
+ * This program is licensed under BSD license, read COPYING
+ *
+ *  $Id$
+ */
+
+#include "conky.h"
+#include "remoted.h"
+#include "remotec.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <sys/time.h>
+
+struct information info;
+
+void update_uname()
+{
+       uname(&info.uname_s);
+}
+
+double get_time()
+{
+       struct timeval tv;
+       gettimeofday(&tv, 0);
+       return tv.tv_sec + tv.tv_usec / 1000000.0;
+}
+
+FILE *open_file(const char *file, int *reported)
+{
+       FILE *fp = fopen(file, "r");
+       if (!fp) {
+               if (!reported || *reported == 0) {
+                       CRIT_ERR("can't open %s: %s", file, strerror(errno));
+                       if (reported)
+                               *reported = 1;
+               }
+               return 0;
+       }
+
+       return fp;
+}
+
+void variable_substitute(const char *s, char *dest, unsigned int n)
+{
+       while (*s && n > 1) {
+               if (*s == '$') {
+                       s++;
+                       if (*s != '$') {
+                               char buf[256];
+                               const char *a, *var;
+                               unsigned int len;
+
+                               /* variable is either $foo or ${foo} */
+                               if (*s == '{') {
+                                       s++;
+                                       a = s;
+                                       while (*s && *s != '}')
+                                               s++;
+                               } else {
+                                       a = s;
+                                       while (*s && (isalnum((int) *s)
+                                                     || *s == '_'))
+                                               s++;
+                               }
+
+                               /* copy variable to buffer and look it up */
+                               len = (s - a > 255) ? 255 : (s - a);
+                               strncpy(buf, a, len);
+                               buf[len] = '\0';
+
+                               if (*s == '}')
+                                       s++;
+
+                               var = getenv(buf);
+
+                               if (var) {
+                                       /* add var to dest */
+                                       len = strlen(var);
+                                       if (len >= n)
+                                               len = n - 1;
+                                       strncpy(dest, var, len);
+                                       dest += len;
+                                       n -= len;
+                               }
+                               continue;
+                       }
+               }
+
+               *dest++ = *s++;
+               n--;
+       }
+
+       *dest = '\0';
+}
+
+/* network interface stuff */
+
+static struct net_stat netstats[16];
+
+struct net_stat *get_net_stat(const char *dev)
+{
+       unsigned int i;
+
+       if (!dev)
+               return 0;
+
+       /* find interface stat */
+       for (i = 0; i < 16; i++) {
+               if (netstats[i].dev && strcmp(netstats[i].dev, dev) == 0)
+                       return &netstats[i];
+       }
+
+       /* wasn't found? add it */
+       if (i == 16) {
+               for (i = 0; i < 16; i++) {
+                       if (netstats[i].dev == 0) {
+                               netstats[i].dev = strdup(dev);
+                               return &netstats[i];
+                       }
+               }
+       }
+
+       CRIT_ERR("too many interfaces used (limit is 16)");
+       return 0;
+}
+
+void format_seconds(char *buf, unsigned int n, long t)
+{
+       if (t >= 24 * 60 * 60)  /* hours necessary when there are days? */
+               snprintf(buf, n, "%ldd %ldh %ldm", t / 60 / 60 / 24,
+                        (t / 60 / 60) % 24, (t / 60) % 60);
+       else if (t >= 60 * 60)
+               snprintf(buf, n, "%ldh %ldm", (t / 60 / 60) % 24,
+                        (t / 60) % 60);
+       else
+               snprintf(buf, n, "%ldm %lds", t / 60, t % 60);
+}
+
+void format_seconds_short(char *buf, unsigned int n, long t)
+{
+       if (t >= 24 * 60 * 60)
+               snprintf(buf, n, "%ldd %ldh", t / 60 / 60 / 24,
+                        (t / 60 / 60) % 24);
+       else if (t >= 60 * 60)
+               snprintf(buf, n, "%ldh %ldm", (t / 60 / 60) % 24,
+                        (t / 60) % 60);
+       else
+               snprintf(buf, n, "%ldm", t / 60);
+}
+
+static double last_meminfo_update;
+static double last_fs_update;
+
+unsigned long long need_mask;
+
+void update_stuff()
+{
+       unsigned int i;
+       info.mask = 0;
+
+       if (no_buffers)
+               need_mask |= 1 << INFO_BUFFERS;
+
+       /* clear speeds and up status in case device was removed and doesn't get
+        * updated */
+
+       for (i = 0; i < 16; i++) {
+               if (netstats[i].dev) {
+                       netstats[i].up = 0;
+                       netstats[i].recv_speed = 0.0;
+                       netstats[i].trans_speed = 0.0;
+               }
+       }
+
+       prepare_update();
+       /* client(); this is approximately where the client should be called */
+#define NEED(a) ((need_mask & (1 << a)) && ((info.mask & (1 << a)) == 0))
+
+       if (NEED(INFO_UPTIME))
+               update_uptime();
+
+       if (NEED(INFO_PROCS))
+               update_total_processes();
+
+       if (NEED(INFO_RUN_PROCS))
+               update_running_processes();
+
+       if (NEED(INFO_CPU))
+               update_cpu_usage();
+
+       if (NEED(INFO_NET))
+               update_net_stats();
+
+       if (NEED(INFO_WIFI))
+               update_wifi_stats();
+
+       if (NEED(INFO_MAIL))
+               update_mail_count();
+
+       if (NEED(INFO_TOP))
+               update_top();
+
+#ifdef MLDONKEY
+       if (NEED(INFO_MLDONKEY))
+               get_mldonkey_status(&mlconfig, &mlinfo);
+#endif
+
+#ifdef SETI
+       if (NEED(INFO_SETI))
+               update_seti();
+#endif
+
+#ifdef MPD
+       if (NEED(INFO_MPD))
+               update_mpd();
+#endif
+
+       if (NEED(INFO_LOADAVG))
+               update_load_average();
+
+       if ((NEED(INFO_MEM) || NEED(INFO_BUFFERS)) &&
+           current_update_time - last_meminfo_update > 6.9) {
+               update_meminfo();
+               if (no_buffers)
+                       info.mem -= info.bufmem;
+               last_meminfo_update = current_update_time;
+       }
+
+       /* 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) {
+               update_fs_stats();
+               last_fs_update = current_update_time;
+       }
+}
diff --git a/src/config.h.in b/src/config.h.in
new file mode 100644 (file)
index 0000000..c08ebec
--- /dev/null
@@ -0,0 +1,133 @@
+/* src/config.h.in.  Generated from configure.in by autoheader.  */
+
+/* Define if you are using Cairo */
+#undef CAIRO
+
+/* Define if you want support for the DBE extension */
+#undef DOUBLE_BUFFER
+
+/* Define to 1 if you have the <cairo.h> header file. */
+#undef HAVE_CAIRO_H
+
+/* Define to 1 if you have the <cairo-xlib.h> header file. */
+#undef HAVE_CAIRO_XLIB_H
+
+/* Define to 1 if you have the <dirent.h> header file. */
+#undef HAVE_DIRENT_H
+
+/* Define if you have getloadavg */
+#undef HAVE_GETLOADAVG
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define if you have kstat (Solaris) */
+#undef HAVE_KSTAT
+
+/* Define if you have libXext */
+#undef HAVE_LIBXEXT
+
+/* Define to 1 if you have the <linux/soundcard.h> header file. */
+#undef HAVE_LINUX_SOUNDCARD_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `popen' function. */
+#undef HAVE_POPEN
+
+/* Define to 1 if you have the <signal.h> header file. */
+#undef HAVE_SIGNAL_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have sysinfo (Linux) */
+#undef HAVE_SYSINFO
+
+/* Define to 1 if you have the <sys/mount.h> header file. */
+#undef HAVE_SYS_MOUNT_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define to 1 if you have the <sys/statfs.h> header file. */
+#undef HAVE_SYS_STATFS_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <sys/utsname.h> header file. */
+#undef HAVE_SYS_UTSNAME_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if you have X11 */
+#undef HAVE_X11
+
+/* Define to 1 if you have the <X11/extensions/Xdbe.h> header file. */
+#undef HAVE_X11_EXTENSIONS_XDBE_H
+
+/* Define to 1 if you have the <X11/Xlib.h> header file. */
+#undef HAVE_X11_XLIB_H
+
+/* Xdbe */
+#undef HAVE_XDBE
+
+/* Define if you want MLDonkey support */
+#undef MLDONKEY
+
+/* Define if you want MPD support */
+#undef MPD
+
+/* Define if you want support for window creating */
+#undef OWN_WINDOW
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define if you want to use /proc/uptime for uptime */
+#undef PROC_UPTIME
+
+/* Define if you want SETI at Home stats */
+#undef SETI
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Version number of package */
+#undef VERSION
+
+/* Define if you want to use X11 */
+#undef X11
+
+/* Define if you are using Xft */
+#undef XFT
diff --git a/src/conky.c b/src/conky.c
new file mode 100644 (file)
index 0000000..a63ed1b
--- /dev/null
@@ -0,0 +1,4337 @@
+/*
+ * Conky, a system monitor, based on torsmo
+ *
+ * This program is licensed under BSD license, read COPYING
+ *
+ *  $Id$
+ */
+
+#include "conky.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+#include <locale.h>
+#include <signal.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <string.h>
+#include <limits.h>
+#if HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#include <sys/time.h>
+#ifdef X11
+#include <X11/Xutil.h>
+#endif /* X11 */
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#define CONFIG_FILE "$HOME/.conkyrc"
+#define MAIL_FILE "$MAIL"
+#define MAX_IF_BLOCK_DEPTH 5
+
+#ifdef X11
+
+/* alignments */
+enum alignment {
+       TOP_LEFT = 1,
+       TOP_RIGHT,
+       BOTTOM_LEFT,
+       BOTTOM_RIGHT,
+       NONE
+};
+
+
+/* for fonts */
+struct font_list {
+
+       char name[TEXT_BUFFER_SIZE];
+       int num;
+       XFontStruct *font;
+
+#ifdef XFT
+       XftFont *xftfont;
+       int font_alpha;
+#endif 
+
+};
+static int selected_font = 0;
+static int font_count = -1;
+struct font_list *fonts = NULL;
+
+#ifdef XFT
+
+#define font_height() use_xft ? (fonts[selected_font].xftfont->ascent + fonts[selected_font].xftfont->descent) : \
+(fonts[selected_font].font->max_bounds.ascent + fonts[selected_font].font->max_bounds.descent)
+#define font_ascent() use_xft ? fonts[selected_font].xftfont->ascent : fonts[selected_font].font->max_bounds.ascent
+#define font_descent() use_xft ? fonts[selected_font].xftfont->descent : fonts[selected_font].font->max_bounds.descent
+
+#else
+
+#define font_height() (fonts[selected_font].font->max_bounds.ascent + fonts[selected_font].font->max_bounds.descent)
+#define font_ascent() fonts[selected_font].font->max_bounds.ascent
+#define font_descent() fonts[selected_font].font->max_bounds.descent
+
+#endif
+
+#define MAX_FONTS 64 // hmm, no particular reason, just makes sense.
+
+
+static void set_font();
+
+
+int addfont(const char *data_in)
+{
+       if (font_count > MAX_FONTS) {
+               CRIT_ERR("you don't need that many fonts, sorry.");
+       }
+       font_count++;
+       if (font_count == 0) {
+               if (fonts != NULL) {
+                       free(fonts);
+               }
+               if ((fonts = (struct font_list*)malloc(sizeof(struct font_list))) == NULL) {
+                       CRIT_ERR("malloc");
+               }
+       }
+       fonts = realloc(fonts, (sizeof(struct font_list) * (font_count+1)));
+       if (fonts == NULL) {
+               CRIT_ERR("realloc in addfont");
+       }
+       if (strlen(data_in) < TEXT_BUFFER_SIZE) { // must account for null terminator
+               strncpy(fonts[font_count].name, data_in, TEXT_BUFFER_SIZE);
+#ifdef XFT
+               fonts[font_count].font_alpha = 0xffff;
+#endif
+       } else {
+               CRIT_ERR("Oops...looks like something overflowed in addfont().");
+       }
+       return font_count;
+}
+
+void set_first_font(const char *data_in)
+{
+       if (font_count < 0) {
+               if ((fonts = (struct font_list*)malloc(sizeof(struct font_list))) == NULL) {
+                       CRIT_ERR("malloc");
+               }
+               font_count++;
+       }
+       if (strlen(data_in) > 1) {
+               strncpy(fonts[0].name, data_in, TEXT_BUFFER_SIZE-1);
+#ifdef XFT
+               fonts[0].font_alpha = 0xffff;
+#endif
+       }
+}
+
+void free_fonts()
+{
+       int i;
+       for (i=0;i<=font_count;i++) {
+#ifdef XFT
+               if (use_xft) {
+                       XftFontClose(display, fonts[i].xftfont);
+               } else
+#endif
+               {
+                       XFreeFont(display, fonts[i].font);
+               }
+}
+       free(fonts);
+       fonts = NULL;
+       font_count = -1;
+       selected_font = 0;
+       set_first_font("6x10");
+}
+
+
+static void load_fonts()
+{
+       int i;
+       for (i=0;i<=font_count;i++) {
+#ifdef XFT
+       /* load Xft font */
+       if (use_xft) {
+       /*if (fonts[i].xftfont != NULL && selected_font == 0) {
+                       XftFontClose(display, fonts[i].xftfont);
+       }*/
+               if ((fonts[i].xftfont =
+                       XftFontOpenName(display, screen, fonts[i].name)) != NULL)
+                       continue;
+               
+               ERR("can't load Xft font '%s'", fonts[i].name);
+               if ((fonts[i].xftfont =
+                       XftFontOpenName(display, screen,
+                                       "courier-12")) != NULL)
+                       continue;
+               
+               ERR("can't load Xft font '%s'", "courier-12");
+               
+               if ((fonts[i].font = XLoadQueryFont(display, "fixed")) == NULL) {
+                       CRIT_ERR("can't load font '%s'", "fixed");
+               }
+               use_xft = 0;
+               
+               continue;
+       }
+#endif
+       /* load normal font */
+/*     if (fonts[i].font != NULL)
+               XFreeFont(display, fonts[i].font);*/
+       
+       if ((fonts[i].font = XLoadQueryFont(display, fonts[i].name)) == NULL) {
+               ERR("can't load font '%s'", fonts[i].name);
+               if ((fonts[i].font = XLoadQueryFont(display, "fixed")) == NULL) {
+                       CRIT_ERR("can't load font '%s'", "fixed");
+               }
+       }
+       }
+}
+
+#endif /* X11 */
+
+/* default config file */
+static char *current_config;
+
+/* set to 1 if you want all text to be in uppercase */
+static unsigned int stuff_in_upper_case;
+
+/* Update interval */
+static double update_interval;
+
+/* Run how many times? */
+static unsigned long total_run_times;
+
+/* fork? */
+static int fork_to_background;
+
+static int cpu_avg_samples, net_avg_samples;
+
+#ifdef X11
+
+/* Always on bottom */
+static int on_bottom;
+
+/* Position on the screen */
+static int text_alignment;
+static int gap_x, gap_y;
+
+/* border */
+static int draw_borders;
+static int stippled_borders;
+
+static int draw_shades, draw_outline;
+
+static int border_margin, border_width;
+
+static long default_fg_color, default_bg_color, default_out_color;
+
+/* create own window or draw stuff to root? */
+static int own_window = 0;
+
+#ifdef OWN_WINDOW
+/* fixed size/pos is set if wm/user changes them */
+static int fixed_size = 0, fixed_pos = 0;
+#endif
+
+static int minimum_width, minimum_height;
+
+/* UTF-8 */
+int utf8_mode = 0;
+
+#endif /* X11 */
+
+/* no buffers in used memory? */
+int no_buffers;
+
+/* pad percentages to decimals? */
+static int pad_percents = 0;
+
+/* Text that is shown */
+static char original_text[] =
+    "$nodename - $sysname $kernel on $machine\n"
+    "$hr\n"
+    "${color grey}Uptime:$color $uptime\n"
+    "${color grey}Frequency (in MHz):$color $freq\n"
+    "${color grey}Frequency (in Ghz):$color $freq_g\n"
+    "${color grey}RAM Usage:$color $mem/$memmax - $memperc% ${membar 4}\n"
+    "${color grey}Swap Usage:$color $swap/$swapmax - $swapperc% ${swapbar 4}\n"
+    "${color grey}CPU Usage:$color $cpu% ${cpubar 4}\n"
+    "${color grey}Processes:$color $processes  ${color grey}Running:$color $running_processes\n"
+    "$hr\n"
+    "${color grey}File systems:\n"
+    " / $color${fs_free /}/${fs_size /} ${fs_bar 6 /}\n"
+    "${color grey}Networking:\n"
+    " Up:$color ${upspeed eth0} k/s${color grey} - Down:$color ${downspeed eth0} k/s\n"
+    "${color grey}Temperatures:\n"
+    " CPU:$color ${i2c temp 1}°C${color grey} - MB:$color ${i2c temp 2}°C\n"
+    "$hr\n"
+#ifdef SETI
+    "${color grey}SETI@Home Statistics:\n"
+    "${color grey}Seti Unit Number:$color $seti_credit\n"
+    "${color grey}Seti Progress:$color $seti_prog% $seti_progbar\n"
+#endif
+#ifdef MPD
+    "${color grey}MPD: $mpd_status $mpd_artist - $mpd_title from $mpd_album at $mpd_vol\n"
+    "Bitrate: $mpd_bitrate\n" "Progress: $mpd_bar\n"
+#endif
+    "${color grey}Name         PID     CPU%    MEM%\n"
+    " ${color lightgrey} ${top name 1} ${top pid 1} ${top cpu 1} ${top mem 1}\n"
+    " ${color lightgrey} ${top name 2} ${top pid 2} ${top cpu 2} ${top mem 2}\n"
+    " ${color lightgrey} ${top name 3} ${top pid 3} ${top cpu 3} ${top mem 3}\n"
+    " ${color lightgrey} ${top name 4} ${top pid 4} ${top cpu 4} ${top mem 4}\n"
+    "${tail /var/log/Xorg.0.log 3}";
+
+static char *text = original_text;
+
+static int total_updates;
+
+/* if-blocks */
+static int blockdepth = 0;
+static int if_jumped = 0;
+static int blockstart[MAX_IF_BLOCK_DEPTH];
+
+int check_mount(char *s)
+{
+       int ret = 0;
+       FILE *mtab = fopen("/etc/mtab", "r");
+       if (mtab) {
+               char buf1[256], buf2[128];
+               while (fgets(buf1, 256, mtab)) {
+                       sscanf(buf1, "%*s %128s", buf2);
+                       if (!strcmp(s, buf2)) {
+                               ret = 1;
+                               break;
+                       }
+               }
+               fclose(mtab);
+       } else {
+               ERR("Could not open mtab");
+       }
+       return ret;
+}
+
+
+#ifdef X11
+static inline int calc_text_width(const char *s, unsigned int l)
+{
+#ifdef XFT
+       if (use_xft) {
+               XGlyphInfo gi;
+               if (utf8_mode) {
+                       XftTextExtentsUtf8(display, fonts[selected_font].xftfont, s, l, &gi);
+               } else {
+                       XftTextExtents8(display, fonts[selected_font].xftfont, s, l, &gi);
+               }
+               return gi.xOff;
+       } else
+#endif
+       {
+               return XTextWidth(fonts[selected_font].font, s, l);
+       }
+}
+#endif /* X11 */
+
+/* formatted text to render on screen, generated in generate_text(),
+ * drawn in draw_stuff() */
+
+static char text_buffer[TEXT_BUFFER_SIZE * 4];
+
+/* special stuff in text_buffer */
+
+#define SPECIAL_CHAR '\x01'
+
+enum {
+       HORIZONTAL_LINE,
+       STIPPLED_HR,
+       BAR,
+       FG,
+       BG,
+       OUTLINE,
+       ALIGNR,
+       ALIGNC,
+       GRAPH,
+       OFFSET,
+       VOFFSET,
+       FONT,
+};
+
+static struct special_t {
+       int type;
+       short height;
+       short width;
+       long arg;
+       double *graph;
+       double graph_scale;
+       int graph_width;
+       int scaled;
+       short font_added;
+       unsigned long first_colour; // for graph gradient
+       unsigned long last_colour;
+} specials[128];
+
+static int special_count;
+#ifdef X11
+static int special_index;      /* used when drawing */
+#endif /* X11 */
+
+#define MAX_GRAPH_DEPTH 256    /* why 256? who knows. */
+
+static struct special_t *new_special(char *buf, int t)
+{
+       if (special_count >= 128)
+               CRIT_ERR("too many special things in text");
+
+       buf[0] = SPECIAL_CHAR;
+       buf[1] = '\0';
+       if (t == GRAPH && specials[special_count].graph == NULL) {
+               if (specials[special_count].width > 0
+                   && specials[special_count].width < MAX_GRAPH_DEPTH)
+                       specials[special_count].graph_width = specials[special_count].width - 3;        // subtract 3 for the box
+               else
+                       specials[special_count].graph_width =
+                           MAX_GRAPH_DEPTH;
+               specials[special_count].graph =
+                   calloc(specials[special_count].graph_width,
+                          sizeof(double));
+               specials[special_count].graph_scale = 100;
+       }
+       specials[special_count].type = t;
+       return &specials[special_count++];
+}
+
+typedef struct tailstring_list {
+       char data[TEXT_BUFFER_SIZE];
+       struct tailstring_list *next;
+       struct tailstring_list *first;
+} tailstring;
+
+void addtail(tailstring ** head, char *data_in)
+{
+       tailstring *tmp;
+       if ((tmp = malloc(sizeof(*tmp))) == NULL) {
+               CRIT_ERR("malloc");
+       }
+       if (*head == NULL) {
+               tmp->first = tmp;
+       } else {
+               tmp->first = (*head)->first;
+       }
+       strncpy(tmp->data, data_in, TEXT_BUFFER_SIZE);
+       tmp->next = *head;
+       *head = tmp;
+}
+
+void freetail(tailstring * head)
+{
+       tailstring *tmp;
+       while (head != NULL) {
+               tmp = head->next;
+               free(head);
+               head = tmp;
+       }
+}
+
+void freelasttail(tailstring * head)
+{
+       tailstring * tmp = head;
+       while(tmp != NULL) {
+               if (tmp->next == head->first) {
+                       tmp->next = NULL;
+                       break;
+               }
+               tmp = tmp->next;
+       }
+       free(head->first);
+       while(head != NULL && tmp != NULL) {
+               head->first = tmp;
+               head = head->next;
+       }
+}
+
+static void new_bar(char *buf, int w, int h, int usage)
+{
+       struct special_t *s = new_special(buf, BAR);
+       s->arg = (usage > 255) ? 255 : ((usage < 0) ? 0 : usage);
+       s->width = w;
+       s->height = h;
+}
+
+static const char *scan_bar(const char *args, int *w, int *h)
+{
+       *w = 0;                 /* zero width means all space that is available */
+       *h = 6;
+       /* bar's argument is either height or height,width */
+       if (args) {
+               int n = 0;
+               if (sscanf(args, "%d,%d %n", h, w, &n) <= 1)
+                       sscanf(args, "%d %n", h, &n);
+               args += n;
+       }
+
+       return args;
+}
+
+static char *scan_font(const char *args)
+{
+       if (args && sizeof(args) < 127) {
+               return strdup(args);
+       }
+       else {
+               ERR("font scan failed, lets hope it doesn't mess stuff up");
+       }
+       return NULL;
+}
+
+#ifdef X11
+static void new_font(char *buf, char * args) {
+       struct special_t *s = new_special(buf, FONT);
+       if (!s->font_added || strcmp(args, fonts[s->font_added].name)) {
+               int tmp = selected_font;
+               selected_font = s->font_added = addfont(args);
+               load_fonts();
+               set_font();
+               selected_font = tmp;
+       }
+}
+#endif
+
+inline void graph_append(struct special_t *graph, double f)
+{
+       int i;
+       if (graph->scaled) {
+               graph->graph_scale = 0;
+       }
+       graph->graph[graph->graph_width - 1] = f; /* add new data */
+       for (i = 0; i < graph->graph_width - 1; i++) { /* shift all the data by 1 */
+               graph->graph[i] = graph->graph[i + 1];
+               if (graph->scaled && graph->graph[i] > graph->graph_scale) {
+                       graph->graph_scale = graph->graph[i]; /* check if we need to update the scale */
+               }
+       }
+}
+
+static void new_graph(char *buf, int w, int h, unsigned int first_colour, unsigned int second_colour, double i, int scaled)
+{
+       struct special_t *s = new_special(buf, GRAPH);
+       s->width = w;
+       s->height = h;
+       s->first_colour = first_colour;
+       s->last_colour = second_colour;
+       s->scaled = scaled;
+       if (s->width) {
+               s->graph_width = s->width - 3;  // subtract 3 for rectangle around
+       }
+       if (scaled) {
+               s->graph_scale = 1;
+       } else {
+               s->graph_scale = 100;
+       }
+       graph_append(s, i);
+}
+
+static const char *scan_graph(const char *args, int *w, int *h, unsigned int *first_colour, unsigned int *last_colour)
+{
+       *w = 0;                 /* zero width means all space that is available */
+       *h = 25;
+       *first_colour = 0;
+       *last_colour = 0;
+       /* graph's argument is either height or height,width */
+       if (args) {
+               if (sscanf(args, "%*s %d,%d %x %x", h, w, first_colour, last_colour) < 4) {
+                       if (sscanf(args, "%d,%d %x %x", h, w, first_colour, last_colour) < 4) {
+                               *w = 0;
+                               *h = 25;                        
+                               if (sscanf(args, "%*s %x %x", first_colour, last_colour) < 3) {
+                               *w = 0;
+                               *h = 25;
+                               if (sscanf(args, "%x %x", first_colour, last_colour) < 2) {
+                                       *first_colour = 0;
+                                       *last_colour = 0;
+                                       if (sscanf(args, "%d,%d", h, w) < 2) {
+                                               *first_colour = 0;
+                                               *last_colour = 0;
+                                               sscanf(args, "%*s %d,%d", h, w);
+                                       }
+                               }
+                       }
+                       }
+               }
+       }
+
+       return args;
+}
+
+
+static inline void new_hr(char *buf, int a)
+{
+       new_special(buf, HORIZONTAL_LINE)->height = a;
+}
+
+static inline void new_stippled_hr(char *buf, int a, int b)
+{
+       struct special_t *s = new_special(buf, STIPPLED_HR);
+       s->height = b;
+       s->arg = a;
+}
+
+static inline void new_fg(char *buf, long c)
+{
+       new_special(buf, FG)->arg = c;
+}
+
+static inline void new_bg(char *buf, long c)
+{
+       new_special(buf, BG)->arg = c;
+}
+
+static inline void new_outline(char *buf, long c)
+{
+       new_special(buf, OUTLINE)->arg = c;
+}
+
+static inline void new_offset(char *buf, long c)
+{
+       new_special(buf, OFFSET)->arg = c;
+}
+
+static inline void new_voffset(char *buf, long c)
+{
+       new_special(buf, VOFFSET)->arg = c;
+}
+
+static inline void new_alignr(char *buf, long c)
+{
+       new_special(buf, ALIGNR)->arg = c;
+}
+
+static inline void new_alignc(char *buf, long c)
+{
+       new_special(buf, ALIGNC)->arg = c;
+}
+
+/* quite boring functions */
+
+static inline void for_each_line(char *b, void (*f) (char *))
+{
+       char *ps, *pe;
+
+       for (ps = b, pe = b; *pe; pe++) {
+               if (*pe == '\n') {
+                       *pe = '\0';
+                       f(ps);
+                       *pe = '\n';
+                       ps = pe + 1;
+               }
+       }
+
+       if (ps < pe)
+               f(ps);
+}
+
+static void convert_escapes(char *buf)
+{
+       char *p = buf, *s = buf;
+
+       while (*s) {
+               if (*s == '\\') {
+                       s++;
+                       if (*s == 'n')
+                               *p++ = '\n';
+                       else if (*s == '\\')
+                               *p++ = '\\';
+                       s++;
+               } else
+                       *p++ = *s++;
+       }
+       *p = '\0';
+}
+
+/* converts from bytes to human readable format (k, M, G, T) */
+static void human_readable(long long a, char *buf, int size)
+{
+       //Strange conditional due to possible overflows
+       if(a / 1024 / 1024 / 1024.0 > 1024.0){
+               snprintf(buf, size, "%.2fT", (a / 1024 / 1024) / 1024 / 1024.0);
+       }
+       else if (a >= 1024 * 1024 * 1024) {
+               snprintf(buf, size, "%.2fG", (a / 1024 / 1024) / 1024.0);
+       }
+       else if (a >= 1024 * 1024) {
+               double m = (a / 1024) / 1024.0;
+               if (m >= 100.0)
+                       snprintf(buf, size, "%.0fM", m);
+               else
+                       snprintf(buf, size, "%.1fM", m);
+       } else if (a >= 1024)
+               snprintf(buf, size, "%Ldk", a / (long long) 1024);
+       else
+               snprintf(buf, size, "%Ld", a);
+}
+
+/* text handling */
+
+enum text_object_type {
+       OBJ_acpiacadapter,
+       OBJ_adt746xcpu,
+       OBJ_adt746xfan,
+       OBJ_acpifan,
+       OBJ_addr,
+       OBJ_linkstatus,
+       OBJ_acpitemp,
+       OBJ_acpitempf,
+       OBJ_battery,
+       OBJ_buffers,
+       OBJ_cached,
+       OBJ_color,
+       OBJ_font,
+       OBJ_cpu,
+       OBJ_cpubar,
+       OBJ_cpugraph,
+       OBJ_downspeed,
+       OBJ_downspeedf,
+       OBJ_downspeedgraph,
+       OBJ_else,
+       OBJ_endif,
+       OBJ_exec,
+       OBJ_execi,
+       OBJ_execbar,
+       OBJ_execgraph,
+       OBJ_freq,
+       OBJ_freq_g,
+       OBJ_fs_bar,
+       OBJ_fs_bar_free,
+       OBJ_fs_free,
+       OBJ_fs_free_perc,
+       OBJ_fs_size,
+       OBJ_fs_used,
+       OBJ_fs_used_perc,
+       OBJ_hr,
+       OBJ_offset,
+       OBJ_voffset,
+       OBJ_alignr,
+       OBJ_alignc,
+       OBJ_i2c,
+       OBJ_if_existing,
+       OBJ_if_mounted,
+       OBJ_if_running,
+       OBJ_top,
+       OBJ_top_mem,
+       OBJ_tail,
+       OBJ_kernel,
+       OBJ_loadavg,
+       OBJ_machine,
+       OBJ_mails,
+       OBJ_mem,
+       OBJ_membar,
+       OBJ_memgraph,
+       OBJ_memmax,
+       OBJ_memperc,
+       OBJ_mixer,
+       OBJ_mixerl,
+       OBJ_mixerr,
+       OBJ_mixerbar,
+       OBJ_mixerlbar,
+       OBJ_mixerrbar,
+       OBJ_new_mails,
+       OBJ_nodename,
+       OBJ_pre_exec,
+#ifdef MLDONKEY
+       OBJ_ml_upload_counter,
+       OBJ_ml_download_counter,
+       OBJ_ml_nshared_files,
+       OBJ_ml_shared_counter,
+       OBJ_ml_tcp_upload_rate,
+       OBJ_ml_tcp_download_rate,
+       OBJ_ml_udp_upload_rate,
+       OBJ_ml_udp_download_rate,
+       OBJ_ml_ndownloaded_files,
+       OBJ_ml_ndownloading_files,
+#endif
+       OBJ_processes,
+       OBJ_running_processes,
+       OBJ_shadecolor,
+       OBJ_outlinecolor,
+       OBJ_stippled_hr,
+       OBJ_swap,
+       OBJ_swapbar,
+       OBJ_swapmax,
+       OBJ_swapperc,
+       OBJ_sysname,
+       OBJ_temp1,              /* i2c is used instead in these */
+       OBJ_temp2,
+       OBJ_text,
+       OBJ_time,
+       OBJ_utime,
+       OBJ_totaldown,
+       OBJ_totalup,
+       OBJ_updates,
+       OBJ_upspeed,
+       OBJ_upspeedf,
+       OBJ_upspeedgraph,
+       OBJ_uptime,
+       OBJ_uptime_short,
+#ifdef SETI
+       OBJ_seti_prog,
+       OBJ_seti_progbar,
+       OBJ_seti_credit,
+#endif
+#ifdef MPD
+       OBJ_mpd_title,
+       OBJ_mpd_artist,
+       OBJ_mpd_album,
+       OBJ_mpd_vol,
+       OBJ_mpd_bitrate,
+       OBJ_mpd_status,
+       OBJ_mpd_host,
+       OBJ_mpd_port,
+       OBJ_mpd_bar,
+       OBJ_mpd_elapsed,
+       OBJ_mpd_length,
+       OBJ_mpd_percent,
+#endif
+};
+
+struct text_object {
+       int type;
+       int a, b;
+       unsigned int c, d;
+       union {
+               char *s;        /* some string */
+               int i;          /* some integer */
+               long l;         /* some other integer */
+               struct net_stat *net;
+               struct fs_stat *fs;
+               unsigned char loadavg[3];
+
+               struct {
+                       struct fs_stat *fs;
+                       int w, h;
+               } fsbar;        /* 3 */
+
+               struct {
+                       int l;
+                       int w, h;
+               } mixerbar;     /* 3 */
+
+               struct {
+                       int fd;
+                       int arg;
+                       char devtype[256];
+                       char type[64];
+               } i2c;          /* 2 */
+               struct {
+                       int pos;
+                       char *s;
+               } ifblock;
+               struct {
+                       int num;
+                       int type;
+               } top;
+
+               struct {
+                       int wantedlines;
+                       int readlines;
+                       char *logfile;
+                       double last_update;
+                       float interval;
+                       char *buffer;
+               } tail;
+
+               struct {
+                       double last_update;
+                       float interval;
+                       char *cmd;
+                       char *buffer;
+               } execi;        /* 5 */
+
+               struct {
+                       int a, b;
+               } pair;         /* 2 */
+       } data;
+};
+
+static unsigned int text_object_count;
+static struct text_object *text_objects;
+
+/* new_text_object() allocates a new zeroed text_object */
+static struct text_object *new_text_object()
+{
+       text_object_count++;
+       text_objects = (struct text_object *) realloc(text_objects,
+                                                     sizeof(struct
+                                                            text_object) *
+                                                     text_object_count);
+       memset(&text_objects[text_object_count - 1], 0,
+              sizeof(struct text_object));
+
+       return &text_objects[text_object_count - 1];
+}
+
+static void free_text_objects()
+{
+       unsigned int i;
+
+       for (i = 0; i < text_object_count; i++) {
+               switch (text_objects[i].type) {
+               case OBJ_acpitemp:
+                       close(text_objects[i].data.i);
+                       break;
+               case OBJ_acpitempf:
+                       close(text_objects[i].data.i);
+                       break;
+               case OBJ_i2c:
+                       close(text_objects[i].data.i2c.fd);
+                       break;
+               case OBJ_time:
+               case OBJ_utime:
+               case OBJ_if_existing:
+               case OBJ_if_mounted:
+               case OBJ_if_running:
+                       free(text_objects[i].data.ifblock.s);
+                       break;
+               case OBJ_text:
+               case OBJ_exec:
+               case OBJ_execbar:
+               case OBJ_execgraph:
+#ifdef MPD
+               case OBJ_mpd_title:
+               case OBJ_mpd_artist:
+               case OBJ_mpd_album:
+               case OBJ_mpd_status:
+               case OBJ_mpd_host:
+#endif
+               case OBJ_pre_exec:
+               case OBJ_battery:
+                       free(text_objects[i].data.s);
+                       break;
+
+               case OBJ_execi:
+                       free(text_objects[i].data.execi.cmd);
+                       free(text_objects[i].data.execi.buffer);
+                       break;
+               }
+       }
+
+       free(text_objects);
+       text_objects = NULL;
+       text_object_count = 0;
+}
+
+void scan_mixer_bar(const char *arg, int *a, int *w, int *h)
+{
+       char buf1[64];
+       int n;
+
+       if (arg && sscanf(arg, "%63s %n", buf1, &n) >= 1) {
+               *a = mixer_init(buf1);
+               (void) scan_bar(arg + n, w, h);
+       } else {
+               *a = mixer_init(0);
+               (void) scan_bar(arg, w, h);
+       }
+}
+
+/* construct_text_object() creates a new text_object */
+static void construct_text_object(const char *s, const char *arg)
+{
+       struct text_object *obj = new_text_object();
+
+#define OBJ(a, n) if (strcmp(s, #a) == 0) { obj->type = OBJ_##a; need_mask |= (1 << n); {
+#define END ; } } else
+
+#ifdef X11     
+if (s[0] == '#') {
+               obj->type = OBJ_color;
+               obj->data.l = get_x11_color(s);
+       } else
+#endif /* X11 */
+       OBJ(acpitemp, 0) obj->data.i = open_acpi_temperature(arg);
+       END OBJ(acpitempf, 0) obj->data.i = open_acpi_temperature(arg);
+       END OBJ(acpiacadapter, 0)
+       END OBJ(freq, 0);
+       END OBJ(freq_g, 0);
+       END OBJ(acpifan, 0);
+       END OBJ(battery, 0);
+       char bat[64];
+       if (arg)
+               sscanf(arg, "%63s", bat);
+       else
+               strcpy(bat, "BAT0");
+       obj->data.s = strdup(bat);
+       END OBJ(buffers, INFO_BUFFERS)
+       END OBJ(cached, INFO_BUFFERS)
+       END OBJ(cpu, INFO_CPU)
+       END OBJ(cpubar, INFO_CPU)
+        (void) scan_bar(arg, &obj->data.pair.a, &obj->data.pair.b);
+       END OBJ(cpugraph, INFO_CPU)
+                       (void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d);
+       END OBJ(color, 0) 
+#ifdef X11
+                       obj->data.l = arg ? get_x11_color(arg) : default_fg_color;
+#endif /* X11 */
+       END
+                       OBJ(font, 0)
+                       obj->data.s = scan_font(arg);
+                       END
+                       OBJ(downspeed, INFO_NET) obj->data.net = get_net_stat(arg);
+       END OBJ(downspeedf, INFO_NET) obj->data.net = get_net_stat(arg);
+       END OBJ(downspeedgraph, INFO_NET)
+                       (void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d);
+       char buf[64];
+       sscanf(arg, "%63s %*i,%*i %*i", buf);
+       obj->data.net = get_net_stat(buf);
+       if (sscanf(arg, "%*s %d,%d %*d", &obj->b, &obj->a) <= 1) {
+               if (sscanf(arg, "%*s %d,%d", &obj->b, &obj->a) <= 1) {
+                       obj->a = 0;
+                       obj->b = 25;
+               }
+       }
+       END OBJ(
+                      else
+                      , 0)
+       if (blockdepth) {
+               text_objects[blockstart[blockdepth - 1] -
+                            1].data.ifblock.pos = text_object_count;
+               blockstart[blockdepth - 1] = text_object_count;
+               obj->data.ifblock.pos = text_object_count + 2;
+       } else {
+               ERR("$else: no matching $if_*");
+       }
+       END OBJ(endif, 0)
+       if (blockdepth) {
+               blockdepth--;
+               text_objects[blockstart[blockdepth] - 1].data.ifblock.pos =
+                   text_object_count;
+       } else {
+               ERR("$endif: no matching $if_*");
+       }
+       END
+#ifdef HAVE_POPEN
+           OBJ(exec, 0) obj->data.s = strdup(arg ? arg : "");
+       END OBJ(execbar, 0) obj->data.s = strdup(arg ? arg : "");
+       END OBJ(execgraph, 0) obj->data.s = strdup(arg ? arg : "");
+       END OBJ(execi, 0) unsigned int n;
+
+       if (!arg
+           || sscanf(arg, "%f %n", &obj->data.execi.interval, &n) <= 0) {
+               char buf[256];
+               ERR("${execi <interval> command}");
+               obj->type = OBJ_text;
+               snprintf(buf, 256, "${%s}", s);
+               obj->data.s = strdup(buf);
+       } else {
+               obj->data.execi.cmd = strdup(arg + n);
+               obj->data.execi.buffer =
+                   (char *) calloc(1, TEXT_BUFFER_SIZE);
+       }
+       END OBJ(pre_exec, 0) obj->type = OBJ_text;
+       if (arg) {
+               FILE *fp = popen(arg, "r");
+               unsigned int n;
+               char buf[2048];
+
+               n = fread(buf, 1, 2048, fp);
+               buf[n] = '\0';
+
+               if (n && buf[n - 1] == '\n')
+                       buf[n - 1] = '\0';
+
+               (void) pclose(fp);
+
+               obj->data.s = strdup(buf);
+       } else
+               obj->data.s = strdup("");
+       END
+#endif
+           OBJ(fs_bar, INFO_FS) obj->data.fsbar.h = 4;
+       arg = scan_bar(arg, &obj->data.fsbar.w, &obj->data.fsbar.h);
+       if (arg) {
+               while (isspace(*arg))
+                       arg++;
+               if (*arg == '\0')
+                       arg = "/";
+       } else
+               arg = "/";
+       obj->data.fsbar.fs = prepare_fs_stat(arg);
+       END OBJ(fs_bar_free, INFO_FS) obj->data.fsbar.h = 4;
+       if (arg) {
+               unsigned int n;
+               if (sscanf(arg, "%d %n", &obj->data.fsbar.h, &n) >= 1)
+                       arg += n;
+       } else
+               arg = "/";
+       obj->data.fsbar.fs = prepare_fs_stat(arg);
+       END OBJ(fs_free, INFO_FS) if (!arg)
+                arg = "/";
+       obj->data.fs = prepare_fs_stat(arg);
+       END OBJ(fs_used_perc, INFO_FS) if (!arg)
+                arg = "/";
+       obj->data.fs = prepare_fs_stat(arg);
+       END OBJ(fs_free_perc, INFO_FS) if (!arg)
+                arg = "/";
+       obj->data.fs = prepare_fs_stat(arg);
+       END OBJ(fs_size, INFO_FS) if (!arg)
+                arg = "/";
+       obj->data.fs = prepare_fs_stat(arg);
+       END OBJ(fs_used, INFO_FS) if (!arg)
+                arg = "/";
+       obj->data.fs = prepare_fs_stat(arg);
+       END OBJ(hr, 0) obj->data.i = arg ? atoi(arg) : 1;
+       END OBJ(offset, 0) obj->data.i = arg ? atoi(arg) : 1;
+       END OBJ(voffset, 0) obj->data.i = arg ? atoi(arg) : 1;
+       END OBJ(i2c, INFO_I2C) char buf1[64], buf2[64];
+       int n;
+
+       if (!arg) {
+               ERR("i2c needs arguments");
+               obj->type = OBJ_text;
+               obj->data.s = strdup("${i2c}");
+               return;
+       }
+
+       if (sscanf(arg, "%63s %63s %d", buf1, buf2, &n) != 3) {
+               /* if scanf couldn't read three values, read type and num and use
+                * default device */
+               sscanf(arg, "%63s %d", buf2, &n);
+               obj->data.i2c.fd =
+                   open_i2c_sensor(0, buf2, n, &obj->data.i2c.arg,
+                                   obj->data.i2c.devtype);
+               strcpy(obj->data.i2c.type, buf2);
+       } else {
+               obj->data.i2c.fd =
+                   open_i2c_sensor(buf1, buf2, n, &obj->data.i2c.arg,
+                                   obj->data.i2c.devtype);
+               strcpy(obj->data.i2c.type, buf2);
+       }
+
+       END OBJ(top, INFO_TOP)
+       char buf[64];
+       int n;
+       if (!arg) {
+               ERR("top needs arguments");
+               obj->type = OBJ_text;
+               obj->data.s = strdup("${top}");
+               return;
+       }
+       if (sscanf(arg, "%63s %i", buf, &n) == 2) {
+               if (strcmp(buf, "name") == 0) {
+                       obj->data.top.type = TOP_NAME;
+               } else if (strcmp(buf, "cpu") == 0) {
+                       obj->data.top.type = TOP_CPU;
+               } else if (strcmp(buf, "pid") == 0) {
+                       obj->data.top.type = TOP_PID;
+               } else if (strcmp(buf, "mem") == 0) {
+                       obj->data.top.type = TOP_MEM;
+               } else {
+                       ERR("invalid arg for top");
+                       return;
+               }
+               if (n < 1 || n > 10) {
+                       CRIT_ERR("invalid arg for top");
+                       return;
+               } else {
+                       obj->data.top.num = n - 1;
+                       top_cpu = 1;
+               }
+       } else {
+               ERR("invalid args given for top");
+               return;
+       }
+       END OBJ(top_mem, INFO_TOP)
+       char buf[64];
+       int n;
+       if (!arg) {
+               ERR("top_mem needs arguments");
+               obj->type = OBJ_text;
+               obj->data.s = strdup("${top_mem}");
+               return;
+       }
+       if (sscanf(arg, "%63s %i", buf, &n) == 2) {
+               if (strcmp(buf, "name") == 0) {
+                       obj->data.top.type = TOP_NAME;
+               } else if (strcmp(buf, "cpu") == 0) {
+                       obj->data.top.type = TOP_CPU;
+               } else if (strcmp(buf, "pid") == 0) {
+                       obj->data.top.type = TOP_PID;
+               } else if (strcmp(buf, "mem") == 0) {
+                       obj->data.top.type = TOP_MEM;
+               } else {
+                       ERR("invalid arg for top");
+                       return;
+               }
+               if (n < 1 || n > 10) {
+                       CRIT_ERR("invalid arg for top");
+                       return;
+               } else {
+                       obj->data.top.num = n - 1;
+                       top_mem = 1;
+               }
+       } else {
+               ERR("invalid args given for top");
+               return;
+       }
+       END OBJ(addr, INFO_NET) obj->data.net = get_net_stat(arg);
+       END OBJ(linkstatus, INFO_WIFI) obj->data.net = get_net_stat(arg);
+       END OBJ(tail, 0)
+       char buf[64];
+       int n1, n2;
+       if (!arg) {
+               ERR("tail needs arguments");
+               obj->type = OBJ_text;
+               obj->data.s = strdup("${tail}");
+               return;
+       }
+       if (sscanf(arg, "%63s %i %i", buf, &n1, &n2) == 2) {
+               if (n1 < 1 || n1 > 30) {
+                       CRIT_ERR("invalid arg for tail, number of lines must be between 1 and 30");
+                       return;
+               } else {
+                       FILE *fp;
+                       fp = fopen(buf, "rt");
+                       if (fp != NULL) {
+                               obj->data.tail.logfile =
+                                   malloc(TEXT_BUFFER_SIZE);
+                               strcpy(obj->data.tail.logfile, buf);
+                               obj->data.tail.wantedlines = n1 - 1;
+                               obj->data.tail.interval =
+                                   update_interval * 2;
+                               fclose(fp);
+                       } else {
+                               //fclose (fp);
+                               CRIT_ERR("tail logfile does not exist, or you do not have correct permissions");
+                       }
+               }
+       } else if (sscanf(arg, "%63s %i %i", buf, &n1, &n2) == 3) {
+               if (n1 < 1 || n1 > 30) {
+                       CRIT_ERR
+                           ("invalid arg for tail, number of lines must be between 1 and 30");
+                       return;
+               } else if (n2 < 1 || n2 < update_interval) {
+                       CRIT_ERR
+                           ("invalid arg for tail, interval must be greater than 0 and Conky's interval");
+                       return;
+               } else {
+                       FILE *fp;
+                       fp = fopen(buf, "rt");
+                       if (fp != NULL) {
+                               obj->data.tail.logfile =
+                                   malloc(TEXT_BUFFER_SIZE);
+                               strcpy(obj->data.tail.logfile, buf);
+                               obj->data.tail.wantedlines = n1 - 1;
+                               obj->data.tail.interval = n2;
+                               fclose(fp);
+                       } else {
+                               //fclose (fp);
+                               CRIT_ERR("tail logfile does not exist, or you do not have correct permissions");
+                       }
+               }
+       }
+
+       else {
+               ERR("invalid args given for tail");
+               return;
+       }
+       obj->data.tail.buffer = malloc(TEXT_BUFFER_SIZE * 6); /* asumming all else worked */
+       END OBJ(loadavg, INFO_LOADAVG) int a = 1, b = 2, c = 3, r = 3;
+       if (arg) {
+               r = sscanf(arg, "%d %d %d", &a, &b, &c);
+               if (r >= 3 && (c < 1 || c > 3))
+                       r--;
+               if (r >= 2 && (b < 1 || b > 3))
+                       r--, b = c;
+               if (r >= 1 && (a < 1 || a > 3))
+                       r--, a = b, b = c;
+       }
+       obj->data.loadavg[0] = (r >= 1) ? (unsigned char) a : 0;
+       obj->data.loadavg[1] = (r >= 2) ? (unsigned char) b : 0;
+       obj->data.loadavg[2] = (r >= 3) ? (unsigned char) c : 0;
+       END OBJ(if_existing, 0)
+       if (blockdepth >= MAX_IF_BLOCK_DEPTH) {
+               CRIT_ERR("MAX_IF_BLOCK_DEPTH exceeded");
+       }
+       if (!arg) {
+               ERR("if_existing needs an argument");
+               obj->data.ifblock.s = 0;
+       } else
+               obj->data.ifblock.s = strdup(arg);
+       blockstart[blockdepth] = text_object_count;
+       obj->data.ifblock.pos = text_object_count + 2;
+       blockdepth++;
+       END OBJ(if_mounted, 0)
+       if (blockdepth >= MAX_IF_BLOCK_DEPTH) {
+               CRIT_ERR("MAX_IF_BLOCK_DEPTH exceeded");
+       }
+       if (!arg) {
+               ERR("if_mounted needs an argument");
+               obj->data.ifblock.s = 0;
+       } else
+               obj->data.ifblock.s = strdup(arg);
+       blockstart[blockdepth] = text_object_count;
+       obj->data.ifblock.pos = text_object_count + 2;
+       blockdepth++;
+       END OBJ(if_running, 0)
+       if (blockdepth >= MAX_IF_BLOCK_DEPTH) {
+               CRIT_ERR("MAX_IF_BLOCK_DEPTH exceeded");
+       }
+       if (arg) {
+               char buf[256];
+               snprintf(buf, 256, "pidof %s >/dev/null", arg);
+               obj->data.ifblock.s = strdup(buf);
+       } else {
+               ERR("if_running needs an argument");
+               obj->data.ifblock.s = 0;
+       }
+       blockstart[blockdepth] = text_object_count;
+       obj->data.ifblock.pos = text_object_count + 2;
+       blockdepth++;
+       END OBJ(kernel, 0)
+       END OBJ(machine, 0)
+       END OBJ(mails, INFO_MAIL)
+       END OBJ(mem, INFO_MEM)
+       END OBJ(memmax, INFO_MEM)
+       END OBJ(memperc, INFO_MEM)
+       END OBJ(membar, INFO_MEM)
+        (void) scan_bar(arg, &obj->data.pair.a, &obj->data.pair.b);
+       END OBJ(memgraph, INFO_MEM)
+                       (void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d);
+       END OBJ(mixer, INFO_MIXER) obj->data.l = mixer_init(arg);
+       END OBJ(mixerl, INFO_MIXER) obj->data.l = mixer_init(arg);
+       END OBJ(mixerr, INFO_MIXER) obj->data.l = mixer_init(arg);
+       END OBJ(mixerbar, INFO_MIXER)
+           scan_mixer_bar(arg, &obj->data.mixerbar.l,
+                          &obj->data.mixerbar.w, &obj->data.mixerbar.h);
+       END OBJ(mixerlbar, INFO_MIXER)
+           scan_mixer_bar(arg, &obj->data.mixerbar.l,
+                          &obj->data.mixerbar.w, &obj->data.mixerbar.h);
+       END OBJ(mixerrbar, INFO_MIXER)
+           scan_mixer_bar(arg, &obj->data.mixerbar.l,
+                          &obj->data.mixerbar.w, &obj->data.mixerbar.h);
+       END
+#ifdef MLDONKEY
+           OBJ(ml_upload_counter, INFO_MLDONKEY)
+       END OBJ(ml_download_counter, INFO_MLDONKEY)
+       END OBJ(ml_nshared_files, INFO_MLDONKEY)
+       END OBJ(ml_shared_counter, INFO_MLDONKEY)
+       END OBJ(ml_tcp_upload_rate, INFO_MLDONKEY)
+       END OBJ(ml_tcp_download_rate, INFO_MLDONKEY)
+       END OBJ(ml_udp_upload_rate, INFO_MLDONKEY)
+       END OBJ(ml_udp_download_rate, INFO_MLDONKEY)
+       END OBJ(ml_ndownloaded_files, INFO_MLDONKEY)
+       END OBJ(ml_ndownloading_files, INFO_MLDONKEY) END
+#endif
+        OBJ(new_mails, INFO_MAIL)
+       END OBJ(nodename, 0)
+       END OBJ(processes, INFO_PROCS)
+       END OBJ(running_processes, INFO_RUN_PROCS)
+       END OBJ(shadecolor, 0)
+#ifdef X11
+           obj->data.l = arg ? get_x11_color(arg) : default_bg_color;
+#endif /* X11 */
+       END OBJ(outlinecolor, 0)
+#ifdef X11
+           obj->data.l = arg ? get_x11_color(arg) : default_out_color;
+#endif /* X11 */
+       END OBJ(stippled_hr, 0)
+#ifdef X11
+int a = stippled_borders, b = 1;
+       if (arg) {
+               if (sscanf(arg, "%d %d", &a, &b) != 2)
+                       sscanf(arg, "%d", &b);
+       }
+       if (a <= 0)
+               a = 1;
+       obj->data.pair.a = a;
+       obj->data.pair.b = b;
+#endif /* X11 */
+       END OBJ(swap, INFO_MEM)
+       END OBJ(swapmax, INFO_MEM)
+       END OBJ(swapperc, INFO_MEM)
+       END OBJ(swapbar, INFO_MEM)
+        (void) scan_bar(arg, &obj->data.pair.a, &obj->data.pair.b);
+       END OBJ(sysname, 0) END OBJ(temp1, INFO_I2C) obj->type = OBJ_i2c;
+       obj->data.i2c.fd =
+           open_i2c_sensor(0, "temp", 1, &obj->data.i2c.arg,
+                           obj->data.i2c.devtype);
+       END OBJ(temp2, INFO_I2C) obj->type = OBJ_i2c;
+       obj->data.i2c.fd =
+           open_i2c_sensor(0, "temp", 2, &obj->data.i2c.arg,
+                           obj->data.i2c.devtype);
+       END OBJ(time, 0) obj->data.s = strdup(arg ? arg : "%F %T");
+       END OBJ(utime, 0) obj->data.s = strdup(arg ? arg : "%F %T");
+       END OBJ(totaldown, INFO_NET) obj->data.net = get_net_stat(arg);
+       END OBJ(totalup, INFO_NET) obj->data.net = get_net_stat(arg);
+       END OBJ(updates, 0)
+       END OBJ(alignr, 0) obj->data.i = arg ? atoi(arg) : 0;
+       END OBJ(alignc, 0) obj->data.i = arg ? atoi(arg) : 0;
+       END OBJ(upspeed, INFO_NET) obj->data.net = get_net_stat(arg);
+       END OBJ(upspeedf, INFO_NET) obj->data.net = get_net_stat(arg);
+       END OBJ(upspeedgraph, INFO_NET)
+                       (void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d);
+       char buf[64];
+       sscanf(arg, "%63s %*i,%*i %*i", buf);
+       obj->data.net = get_net_stat(buf);
+       if (sscanf(arg, "%*s %d,%d %*d", &obj->b, &obj->a) <= 1) {
+               if (sscanf(arg, "%*s %d,%d", &obj->a, &obj->a) <= 1) {
+                       obj->a = 0;
+                       obj->b = 25;
+               }
+       }
+       END OBJ(uptime_short, INFO_UPTIME) END OBJ(uptime, INFO_UPTIME) END
+           OBJ(adt746xcpu, 0) END OBJ(adt746xfan, 0) END
+#ifdef SETI
+        OBJ(seti_prog, INFO_SETI) END OBJ(seti_progbar, INFO_SETI)
+        (void) scan_bar(arg, &obj->data.pair.a, &obj->data.pair.b);
+       END OBJ(seti_credit, INFO_SETI) END
+#endif
+#ifdef MPD
+        OBJ(mpd_artist, INFO_MPD)
+       END OBJ(mpd_title, INFO_MPD)
+       END OBJ(mpd_elapsed, INFO_MPD)
+       END OBJ(mpd_length, INFO_MPD)
+       END OBJ(mpd_percent, INFO_MPD)
+       END OBJ(mpd_album, INFO_MPD) END OBJ(mpd_vol,
+                                            INFO_MPD) END OBJ(mpd_bitrate,
+                                                              INFO_MPD)
+       END OBJ(mpd_status, INFO_MPD) END OBJ(mpd_bar, INFO_MPD)
+        (void) scan_bar(arg, &obj->data.pair.a, &obj->data.pair.b);
+       END
+#endif
+       {
+               char buf[256];
+               ERR("unknown variable %s", s);
+               obj->type = OBJ_text;
+               snprintf(buf, 256, "${%s}", s);
+               obj->data.s = strdup(buf);
+       }
+#undef OBJ
+}
+
+/* append_text() appends text to last text_object if it's text, if it isn't
+ * it creates a new text_object */
+static void append_text(const char *s)
+{
+       struct text_object *obj;
+
+       if (s == NULL || *s == '\0')
+               return;
+
+       obj = text_object_count ? &text_objects[text_object_count - 1] : 0;
+
+       /* create a new text object? */
+       if (!obj || obj->type != OBJ_text) {
+               obj = new_text_object();
+               obj->type = OBJ_text;
+               obj->data.s = strdup(s);
+       } else {
+               /* append */
+               obj->data.s = (char *) realloc(obj->data.s,
+                                              strlen(obj->data.s) +
+                                              strlen(s) + 1);
+               strcat(obj->data.s, s);
+       }
+}
+
+static void extract_variable_text(const char *p)
+{
+       const char *s = p;
+
+       free_text_objects();
+
+       while (*p) {
+               if (*p == '$') {
+                       *(char *) p = '\0';
+                       append_text(s);
+                       *(char *) p = '$';
+                       p++;
+                       s = p;
+
+                       if (*p != '$') {
+                               char buf[256];
+                               const char *var;
+                               unsigned int len;
+
+                               /* variable is either $foo or ${foo} */
+                               if (*p == '{') {
+                                       p++;
+                                       s = p;
+                                       while (*p && *p != '}')
+                                               p++;
+                               } else {
+                                       s = p;
+                                       if (*p == '#')
+                                               p++;
+                                       while (*p && (isalnum((int) *p)
+                                                     || *p == '_'))
+                                               p++;
+                               }
+
+                               /* copy variable to buffer */
+                               len = (p - s > 255) ? 255 : (p - s);
+                               strncpy(buf, s, len);
+                               buf[len] = '\0';
+
+                               if (*p == '}')
+                                       p++;
+                               s = p;
+
+                               var = getenv(buf);
+
+                               /* if variable wasn't found from environment, use some special */
+                               if (!var) {
+                                       char *p;
+                                       char *arg = 0;
+
+                                       /* split arg */
+                                       if (strchr(buf, ' ')) {
+                                               arg = strchr(buf, ' ');
+                                               *arg = '\0';
+                                               arg++;
+                                               while (isspace((int) *arg))
+                                                       arg++;
+                                               if (!*arg)
+                                                       arg = 0;
+                                       }
+
+                                       /* lowercase variable name */
+                                       p = buf;
+                                       while (*p) {
+                                               *p = tolower(*p);
+                                               p++;
+                                       }
+
+                                       construct_text_object(buf, arg);
+                               }
+                               continue;
+                       } else
+                               append_text("$");
+               }
+
+               p++;
+       }
+       append_text(s);
+       if (blockdepth) {
+               ERR("one or more $endif's are missing");
+       }
+}
+
+double current_update_time, last_update_time;
+
+static void generate_text()
+{
+       unsigned int i, n;
+       struct information *cur = &info;
+       char *p;
+
+       special_count = 0;
+
+       /* update info */
+
+       current_update_time = get_time();
+
+       update_stuff(cur);
+
+       /* generate text */
+
+       n = TEXT_BUFFER_SIZE * 4 - 2;
+       p = text_buffer;
+
+       for (i = 0; i < text_object_count; i++) {
+               struct text_object *obj = &text_objects[i];
+
+#define OBJ(a) break; case OBJ_##a:
+
+               switch (obj->type) {
+               default:
+                       {
+                               ERR("not implemented obj type %d",
+                                   obj->type);
+                       }
+                       OBJ(acpitemp) {
+                               /* does anyone have decimals in acpi temperature? */
+                               if (!use_spacer)
+                                       snprintf(p, n, "%d", (int)
+                                                       get_acpi_temperature(obj->
+                                                                       data.
+                                                                       i));
+                               else
+                                       snprintf(p, 5, "%d    ", (int)
+                                                       get_acpi_temperature(obj->
+                                                                       data.
+                                                                       i));
+                       }
+                       OBJ(acpitempf) {
+                               /* does anyone have decimals in acpi temperature? */
+                               if (!use_spacer)
+                                       snprintf(p, n, "%d", (int)
+                                                       ((get_acpi_temperature(obj->
+                                                                       data.
+                                                                       i)+ 40) * 9.0 / 5 - 40));
+                               else
+                                       snprintf(p, 5, "%d    ", (int)
+                                                       ((get_acpi_temperature(obj->
+                                                                       data.
+                                                                       i)+ 40) * 9.0 / 5 - 40));
+                       }
+                       OBJ(freq) {
+                               snprintf(p, n, "%sMhz", get_freq());
+                       }
+                       OBJ(freq_g) {
+                               float ghz = (float)(atof(get_freq())/1000);
+                               //printf("%f\n", ghz);
+                               snprintf(p, n, "%'.2fGhz", ghz);
+                       }
+                       OBJ(adt746xcpu) {
+                               snprintf(p, n, "%s", get_adt746x_cpu());
+                       }
+                       OBJ(adt746xfan) {
+                               snprintf(p, n, "%s", get_adt746x_fan());
+                       }
+                       OBJ(acpifan) {
+                               snprintf(p, n, "%s", get_acpi_fan());
+                       }
+                       OBJ(acpiacadapter) {
+                               snprintf(p, n, "%s",
+                                        get_acpi_ac_adapter());
+                       }
+                       OBJ(battery) {
+                               get_battery_stuff(p, n, obj->data.s);
+                       }
+                       OBJ(buffers) {
+                               human_readable(cur->buffers * 1024, p,
+                                              255);
+                       }
+                       OBJ(cached) {
+                               human_readable(cur->cached * 1024, p, 255);
+                       }
+                       OBJ(cpu) {
+                               if (!use_spacer)
+                                       snprintf(p, n, "%*d", pad_percents,
+                                                (int) (cur->cpu_usage *
+                                                       100.0));
+                               else
+                                       snprintf(p, 4, "%*d    ",
+                                                pad_percents,
+                                                (int) (cur->cpu_usage *
+                                                       100.0));
+                       }
+                       OBJ(cpubar) {
+                               new_bar(p, obj->data.pair.a,
+                                       obj->data.pair.b,
+                                       (int) (cur->cpu_usage * 255.0));
+                       }
+                       OBJ(cpugraph) {
+                               new_graph(p, obj->a,
+                                         obj->b, obj->c, obj->d,
+                                         (unsigned int) (cur->cpu_usage *
+                                                         100), 0);
+                       }
+                       OBJ(color) {
+                               new_fg(p, obj->data.l);
+                       }
+#ifdef X11
+                       OBJ(font) {
+                               new_font(p, obj->data.s);
+                       }
+#endif /* X11 */
+                       OBJ(downspeed) {
+                               if (!use_spacer) {
+                                       snprintf(p, n, "%d",
+                                                (int) (obj->data.net->
+                                                       recv_speed /
+                                                       1024));
+                               } else
+                                       snprintf(p, 6, "%d     ",
+                                                (int) (obj->data.net->
+                                                       recv_speed /
+                                                       1024));
+                       }
+                       OBJ(downspeedf) {
+                               if (!use_spacer)
+                                       snprintf(p, n, "%.1f",
+                                                obj->data.net->
+                                                recv_speed / 1024.0);
+                               else
+                                       snprintf(p, 8, "%.1f       ",
+                                                obj->data.net->
+                                                recv_speed / 1024.0);
+                       }
+                       OBJ(downspeedgraph) {
+                               if (obj->data.net->recv_speed == 0)     // this is just to make the ugliness at start go away
+                                       obj->data.net->recv_speed = 0.01;
+                               new_graph(p, obj->a, obj->b, obj->c, obj->d,
+                                         (obj->data.net->recv_speed /
+                               1024.0), 1);
+                       }
+                       OBJ(
+                                  else
+                       ) {
+                               if (!if_jumped) {
+                                       i = obj->data.ifblock.pos - 2;
+                               } else {
+                                       if_jumped = 0;
+                               }
+                       }
+                       OBJ(endif) {
+                               if_jumped = 0;
+                       }
+#ifdef HAVE_POPEN
+                       OBJ(addr) {
+                               snprintf(p, n, "%u.%u.%u.%u",
+                                        obj->data.net->addr.
+                                        sa_data[2] & 255,
+                                        obj->data.net->addr.
+                                        sa_data[3] & 255,
+                                        obj->data.net->addr.
+                                        sa_data[4] & 255,
+                                        obj->data.net->addr.
+                                        sa_data[5] & 255);
+
+                       }
+                       OBJ(linkstatus) {
+                               snprintf(p, n, "%d",
+                                        obj->data.net->linkstatus);
+                       }
+
+                       OBJ(exec) {
+                               char *p2 = p;
+                               FILE *fp = popen(obj->data.s, "r");
+                               int n2 = fread(p, 1, n, fp);
+                               (void) pclose(fp);
+
+                               p[n2] = '\0';
+                               if (n2 && p[n2 - 1] == '\n')
+                                       p[n2 - 1] = '\0';
+
+                               while (*p2) {
+                                       if (*p2 == '\001')
+                                               *p2 = ' ';
+                                       p2++;
+                               }
+                       }
+                       OBJ(execbar) {
+                               char *p2 = p;
+                               FILE *fp = popen(obj->data.s, "r");
+                               int n2 = fread(p, 1, n, fp);
+                               (void) pclose(fp);
+
+                               p[n2] = '\0';
+                               if (n2 && p[n2 - 1] == '\n')
+                                       p[n2 - 1] = '\0';
+
+                               while (*p2) {
+                                       if (*p2 == '\001')
+                                               *p2 = ' ';
+                                       p2++;
+                               }
+                               double barnum;
+                               if (sscanf(p, "%lf", &barnum) == 0) {
+                                       ERR("reading execbar value failed (perhaps it's not the correct format?)");
+                               }
+                               if (barnum > 100 || barnum < 0) {
+                                       ERR("your execbar value is not between 0 and 100, therefore it will be ignored");
+                               } else {
+                                       barnum = barnum / 100.0;
+                                       new_bar(p, 0,
+                                               4, (int) (barnum * 255.0));
+                               }
+
+                       }
+                       OBJ(execgraph) {
+                               char *p2 = p;
+                               FILE *fp = popen(obj->data.s, "r");
+                               int n2 = fread(p, 1, n, fp);
+                               (void) pclose(fp);
+
+                               p[n2] = '\0';
+                               if (n2 && p[n2 - 1] == '\n')
+                                       p[n2 - 1] = '\0';
+
+                               while (*p2) {
+                                       if (*p2 == '\001')
+                                               *p2 = ' ';
+                                       p2++;
+                               }
+                               double barnum;
+                               if (sscanf(p, "%lf", &barnum) == 0) {
+                                       ERR("reading execgraph value failed (perhaps it's not the correct format?)");
+                               }
+                               if (barnum > 100 || barnum < 0) {
+                                       ERR("your execgraph value is not between 0 and 100, therefore it will be ignored");
+                               } else {
+                                       new_graph(p, 0,
+                                       25, obj->c, obj->d, (int) (barnum), 0);
+                               }
+
+                       }
+                       OBJ(execi) {
+                               if (current_update_time -
+                                   obj->data.execi.last_update <
+                                   obj->data.execi.interval) {
+                                       snprintf(p, n, "%s",
+                                                obj->data.execi.buffer);
+                               } else {
+                                       char *p2 = obj->data.execi.buffer;
+                                       FILE *fp =
+                                           popen(obj->data.execi.cmd,
+                                                 "r");
+                                       int n2 =
+                                           fread(p2, 1, TEXT_BUFFER_SIZE,
+                                                 fp);
+                                       (void) pclose(fp);
+
+                                       p2[n2] = '\0';
+                                       if (n2 && p2[n2 - 1] == '\n')
+                                               p2[n2 - 1] = '\0';
+
+                                       while (*p2) {
+                                               if (*p2 == '\001')
+                                                       *p2 = ' ';
+                                               p2++;
+                                       }
+
+                                       snprintf(p, n, "%s",
+                                                obj->data.execi.buffer);
+
+                                       obj->data.execi.last_update =
+                                           current_update_time;
+                               }
+                       }
+#endif
+                       OBJ(fs_bar) {
+                               if (obj->data.fs != NULL) {
+                                       if (obj->data.fs->size == 0)
+                                               new_bar(p,
+                                                       obj->data.fsbar.w,
+                                                       obj->data.fsbar.h,
+                                                       255);
+                                       else
+                                               new_bar(p,
+                                                       obj->data.fsbar.w,
+                                                       obj->data.fsbar.h,
+                                                       (int) (255 -
+                                                              obj->data.
+                                                              fsbar.fs->
+                                                              avail *
+                                                              255 /
+                                                              obj->data.
+                                                              fs->size));
+                               }
+                       }
+                       OBJ(fs_free) {
+                               if (obj->data.fs != NULL)
+                                       human_readable(obj->data.fs->avail,
+                                                      p, 255);
+                       }
+                       OBJ(fs_free_perc) {
+                               if (obj->data.fs != NULL) {
+                                       if (obj->data.fs->size)
+                                               snprintf(p, n, "%*d",
+                                                        pad_percents,
+                                                        (int) ((obj->data.
+                                                                fs->
+                                                                avail *
+                                                                100) /
+                                                               obj->data.
+                                                               fs->size));
+                                       else
+                                               snprintf(p, n, "0");
+                               }
+                       }
+                       OBJ(fs_size) {
+                               if (obj->data.fs != NULL)
+                                       human_readable(obj->data.fs->size,
+                                                      p, 255);
+                       }
+                       OBJ(fs_used) {
+                               if (obj->data.fs != NULL)
+                                       human_readable(obj->data.fs->size -
+                                                      obj->data.fs->avail,
+                                                      p, 255);
+                       }
+                       OBJ(fs_bar_free) {
+                               if (obj->data.fs != NULL) {
+                                       if (obj->data.fs->size == 0)
+                                               new_bar(p,
+                                                       obj->data.fsbar.w,
+                                                       obj->data.fsbar.h,
+                                                       255);
+                                       else
+                                               new_bar(p,
+                                                       obj->data.fsbar.w,
+                                                       obj->data.fsbar.h,
+                                                       (int) (obj->data.
+                                                              fsbar.fs->
+                                                              avail *
+                                                              255 /
+                                                              obj->data.
+                                                              fs->size));
+                               }
+                       }
+                       OBJ(fs_used_perc) {
+                               if (obj->data.fs != NULL) {
+                                       if (obj->data.fs->size)
+                                               snprintf(p, 4, "%d",
+                                                        100 - ((int)
+                                                               ((obj->
+                                                                 data.fs->
+                                                                 avail *
+                                                                 100) /
+                                                                obj->data.
+                                                                fs->
+                                                                size)));
+                                       else
+                                               snprintf(p, n, "0");
+                               }
+                       }
+                       OBJ(loadavg) {
+                               float *v = info.loadavg;
+
+                               if (obj->data.loadavg[2])
+                                       snprintf(p, n, "%.2f %.2f %.2f",
+                                                v[obj->data.loadavg[0] -
+                                                  1],
+                                                v[obj->data.loadavg[1] -
+                                                  1],
+                                                v[obj->data.loadavg[2] -
+                                                  1]);
+                               else if (obj->data.loadavg[1])
+                                       snprintf(p, n, "%.2f %.2f",
+                                                v[obj->data.loadavg[0] -
+                                                  1],
+                                                v[obj->data.loadavg[1] -
+                                                  1]);
+                               else if (obj->data.loadavg[0])
+                                       snprintf(p, n, "%.2f",
+                                                v[obj->data.loadavg[0] -
+                                                  1]);
+                       }
+                       OBJ(hr) {
+                               new_hr(p, obj->data.i);
+                       }
+                       OBJ(offset) {
+                               new_offset(p, obj->data.i);
+                       }
+                       OBJ(voffset) {
+                               new_voffset(p, obj->data.i);
+                       }
+                       OBJ(i2c) {
+                               double r;
+
+                               r = get_i2c_info(&obj->data.i2c.fd,
+                                                obj->data.i2c.arg,
+                                                obj->data.i2c.devtype,
+                                                obj->data.i2c.type);
+
+                               if (r >= 100.0 || r == 0)
+                                       snprintf(p, n, "%d", (int) r);
+                               else
+                                       snprintf(p, n, "%.1f", r);
+                       }
+                       OBJ(alignr) {
+                               new_alignr(p, obj->data.i);
+                       }
+                       OBJ(alignc) {
+                               new_alignc(p, obj->data.i);
+                       }
+                       OBJ(if_existing) {
+                               struct stat tmp;
+                               if ((obj->data.ifblock.s)
+                                   && (stat(obj->data.ifblock.s, &tmp) ==
+                                       -1)) {
+                                       i = obj->data.ifblock.pos - 2;
+                                       if_jumped = 1;
+                               } else
+                                       if_jumped = 0;
+                       }
+                       OBJ(if_mounted) {
+                               if ((obj->data.ifblock.s)
+                                   && (!check_mount(obj->data.ifblock.s))) {
+                                       i = obj->data.ifblock.pos - 2;
+                                       if_jumped = 1;
+                               } else
+                                       if_jumped = 0;
+                       }
+                       OBJ(if_running) {
+                               if ((obj->data.ifblock.s)
+                                   && system(obj->data.ifblock.s)) {
+                                       i = obj->data.ifblock.pos - 2;
+                                       if_jumped = 1;
+                               } else
+                                       if_jumped = 0;
+                       }
+                       OBJ(kernel) {
+                               snprintf(p, n, "%s", cur->uname_s.release);
+                       }
+                       OBJ(machine) {
+                               snprintf(p, n, "%s", cur->uname_s.machine);
+                       }
+
+                       /* memory stuff */
+                       OBJ(mem) {
+                               human_readable(cur->mem * 1024, p, 6);
+                       }
+                       OBJ(memmax) {
+                               human_readable(cur->memmax * 1024, p, 255);
+                       }
+                       OBJ(memperc) {
+                               if (cur->memmax) {
+                                       if (!use_spacer)
+                                               snprintf(p, n, "%*d",
+                                                        pad_percents,
+                                                        (cur->mem * 100) /
+                                                        (cur->memmax));
+                                       else
+                                               snprintf(p, 4, "%*d   ",
+                                                        pad_percents,
+                                                        (cur->mem * 100) /
+                                                        (cur->memmax));
+                               }
+                       }
+                       OBJ(membar) {
+                               new_bar(p, obj->data.pair.a,
+                                       obj->data.pair.b,
+                                       cur->memmax ? (cur->mem * 255) /
+                                       (cur->memmax) : 0);
+                       }
+
+                       OBJ(memgraph) {
+                               new_graph(p, obj->a,
+                               obj->b, obj->c, obj->d,
+                               cur->memmax ? (cur->mem * 100.0) /
+                                               (cur->memmax) : 0.0, 0);
+                       }
+                       /* mixer stuff */
+                       OBJ(mixer) {
+                               snprintf(p, n, "%d",
+                                        mixer_get_avg(obj->data.l));
+                       }
+                       OBJ(mixerl) {
+                               snprintf(p, n, "%d",
+                                        mixer_get_left(obj->data.l));
+                       }
+                       OBJ(mixerr) {
+                               snprintf(p, n, "%d",
+                                        mixer_get_right(obj->data.l));
+                       }
+                       OBJ(mixerbar) {
+                               new_bar(p, obj->data.mixerbar.w,
+                                       obj->data.mixerbar.h,
+                                       mixer_get_avg(obj->data.mixerbar.
+                                                     l) * 255 / 100);
+                       }
+                       OBJ(mixerlbar) {
+                               new_bar(p, obj->data.mixerbar.w,
+                                       obj->data.mixerbar.h,
+                                       mixer_get_left(obj->data.mixerbar.
+                                                      l) * 255 / 100);
+                       }
+                       OBJ(mixerrbar) {
+                               new_bar(p, obj->data.mixerbar.w,
+                                       obj->data.mixerbar.h,
+                                       mixer_get_right(obj->data.mixerbar.
+                                                       l) * 255 / 100);
+                       }
+
+                       /* mail stuff */
+                       OBJ(mails) {
+                               snprintf(p, n, "%d", cur->mail_count);
+                       }
+                       OBJ(new_mails) {
+                               snprintf(p, n, "%d", cur->new_mail_count);
+                       }
+#ifdef MLDONKEY
+                       OBJ(ml_upload_counter) {
+                               snprintf(p, n, "%lld",
+                                        mlinfo.upload_counter / 1048576);
+                       }
+                       OBJ(ml_download_counter) {
+                               snprintf(p, n, "%lld",
+                                        mlinfo.download_counter /
+                                        1048576);
+                       }
+                       OBJ(ml_nshared_files) {
+                               snprintf(p, n, "%i", mlinfo.nshared_files);
+                       }
+                       OBJ(ml_shared_counter) {
+                               snprintf(p, n, "%lld",
+                                        mlinfo.shared_counter / 1048576);
+                       }
+                       OBJ(ml_tcp_upload_rate) {
+                               snprintf(p, n, "%.2f",
+                                        (float) mlinfo.tcp_upload_rate /
+                                        1024);
+                       }
+                       OBJ(ml_tcp_download_rate) {
+                               snprintf(p, n, "%.2f",
+                                        (float) mlinfo.tcp_download_rate /
+                                        1024);
+                       }
+                       OBJ(ml_udp_upload_rate) {
+                               snprintf(p, n, "%.2f",
+                                        (float) mlinfo.udp_upload_rate /
+                                        1024);
+                       }
+                       OBJ(ml_udp_download_rate) {
+                               snprintf(p, n, "%.2f",
+                                        (float) mlinfo.udp_download_rate /
+                                        1024);
+                       }
+                       OBJ(ml_ndownloaded_files) {
+                               snprintf(p, n, "%i",
+                                        mlinfo.ndownloaded_files);
+                       }
+                       OBJ(ml_ndownloading_files) {
+                               snprintf(p, n, "%i",
+                                        mlinfo.ndownloading_files);
+                       }
+#endif
+
+                       OBJ(nodename) {
+                               snprintf(p, n, "%s",
+                                        cur->uname_s.nodename);
+                       }
+                       OBJ(outlinecolor) {
+                               new_outline(p, obj->data.l);
+                       }
+                       OBJ(processes) {
+                               if (!use_spacer)
+                                       snprintf(p, n, "%d", cur->procs);
+                               else
+                                       snprintf(p, 5, "%d    ",
+                                                cur->procs);
+                       }
+                       OBJ(running_processes) {
+                               if (!use_spacer)
+                                       snprintf(p, n, "%d",
+                                                cur->run_procs);
+                               else
+                                       snprintf(p, 3, "%d     ",
+                                                cur->run_procs);
+                       }
+                       OBJ(text) {
+                               snprintf(p, n, "%s", obj->data.s);
+                       }
+                       OBJ(shadecolor) {
+                               new_bg(p, obj->data.l);
+                       }
+                       OBJ(stippled_hr) {
+                               new_stippled_hr(p, obj->data.pair.a,
+                                               obj->data.pair.b);
+                       }
+                       OBJ(swap) {
+                               human_readable(cur->swap * 1024, p, 255);
+                       }
+                       OBJ(swapmax) {
+                               human_readable(cur->swapmax * 1024, p,
+                                              255);
+                       }
+                       OBJ(swapperc) {
+                               if (cur->swapmax == 0) {
+                                       strncpy(p, "No swap", 255);
+                               } else {
+                                       if (!use_spacer)
+                                               snprintf(p, 255, "%*u",
+                                                        pad_percents,
+                                                        (cur->swap *
+                                                         100) /
+                                                        cur->swapmax);
+                                       else
+                                               snprintf(p, 4, "%*u   ",
+                                                        pad_percents,
+                                                        (cur->swap *
+                                                         100) /
+                                                        cur->swapmax);
+                               }
+                       }
+                       OBJ(swapbar) {
+                               new_bar(p, obj->data.pair.a,
+                                       obj->data.pair.b,
+                                       cur->swapmax ? (cur->swap * 255) /
+                                       (cur->swapmax) : 0);
+                       }
+                       OBJ(sysname) {
+                               snprintf(p, n, "%s", cur->uname_s.sysname);
+                       }
+                       OBJ(time) {
+                               time_t t = time(NULL);
+                               struct tm *tm = localtime(&t);
+                               setlocale(LC_TIME, "");
+                               strftime(p, n, obj->data.s, tm);
+                       }
+                       OBJ(utime) {
+                               time_t t = time(NULL);
+                               struct tm *tm = gmtime(&t);
+                               strftime(p, n, obj->data.s, tm);
+                       }
+                       OBJ(totaldown) {
+                               human_readable(obj->data.net->recv, p,
+                                              255);
+                       }
+                       OBJ(totalup) {
+                               human_readable(obj->data.net->trans, p,
+                                              255);
+                       }
+                       OBJ(updates) {
+                               snprintf(p, n, "%d", total_updates);
+                       }
+                       OBJ(upspeed) {
+                               if (!use_spacer)
+                                       snprintf(p, n, "%d",
+                                                (int) (obj->data.net->
+                                                       trans_speed /
+                                                       1024));
+                               else
+                                       snprintf(p, 5, "%d     ",
+                                                (int) (obj->data.net->
+                                                       trans_speed /
+                                                       1024));
+                       }
+                       OBJ(upspeedf) {
+                               if (!use_spacer)
+                                       snprintf(p, n, "%.1f",
+                                                obj->data.net->
+                                                trans_speed / 1024.0);
+                               else
+                                       snprintf(p, 8, "%.1f       ",
+                                                obj->data.net->
+                                                trans_speed / 1024.0);
+                       }
+                       OBJ(upspeedgraph) {
+                               if (obj->data.net->trans_speed == 0)    // this is just to make the ugliness at start go away
+                                       obj->data.net->trans_speed = 0.01;
+                               new_graph(p, obj->a, obj->b, obj->c, obj->d,
+                                         (obj->data.net->trans_speed /
+                               1024.0), 1);
+                       }
+                       OBJ(uptime_short) {
+                               format_seconds_short(p, n,
+                                                    (int) cur->uptime);
+                       }
+                       OBJ(uptime) {
+                               format_seconds(p, n, (int) cur->uptime);
+                       }
+
+#ifdef SETI
+                       OBJ(seti_prog) {
+                               snprintf(p, n, "%.2f",
+                                        cur->seti_prog * 100.0f);
+                       }
+                       OBJ(seti_progbar) {
+                               new_bar(p, obj->data.pair.a,
+                                       obj->data.pair.b,
+                                       (int) (cur->seti_prog * 255.0f));
+                       }
+                       OBJ(seti_credit) {
+                               snprintf(p, n, "%.0f", cur->seti_credit);
+                       }
+#endif
+
+#ifdef MPD
+                       OBJ(mpd_title) {
+                               snprintf(p, n, "%s", cur->mpd.title);
+                       }
+                       OBJ(mpd_artist) {
+                               snprintf(p, n, "%s", cur->mpd.artist);
+                       }
+                       OBJ(mpd_album) {
+                               snprintf(p, n, "%s", cur->mpd.album);
+                       }
+                       OBJ(mpd_vol) {
+                               snprintf(p, n, "%i", cur->mpd.volume);
+                       }
+                       OBJ(mpd_bitrate) {
+                               snprintf(p, n, "%i", cur->mpd.bitrate);
+                       }
+                       OBJ(mpd_status) {
+                               snprintf(p, n, "%s", cur->mpd.status);
+                       }
+                       OBJ(mpd_elapsed) {
+                               int days = 0, hours = 0, minutes =
+                                   0, seconds = 0;
+                               int tmp = cur->mpd.elapsed;
+                               while (tmp >= 86400) {
+                                       tmp -= 86400;
+                                       days++;
+                               }
+                               while (tmp >= 3600) {
+                                       tmp -= 3600;
+                                       hours++;
+                               }
+                               while (tmp >= 60) {
+                                       tmp -= 60;
+                                       minutes++;
+                               }
+                               seconds = tmp;
+                               if (days > 0)
+                                       snprintf(p, n, "%i days %i:%i:%2i",
+                                                days, hours, minutes,
+                                                seconds);
+                               else if (days > 0)
+                                       snprintf(p, n, "%i:%i:%02i", hours,
+                                                minutes, seconds);
+                               else
+                                       snprintf(p, n, "%i:%02i", minutes,
+                                                seconds);
+                       }
+                       OBJ(mpd_length) {
+                               int days = 0, hours = 0, minutes =
+                                   0, seconds = 0;
+                               int tmp = cur->mpd.length;
+                               while (tmp >= 86400) {
+                                       tmp -= 86400;
+                                       days++;
+                               }
+                               while (tmp >= 3600) {
+                                       tmp -= 3600;
+                                       hours++;
+                               }
+                               while (tmp >= 60) {
+                                       tmp -= 60;
+                                       minutes++;
+                               }
+                               seconds = tmp;
+                               if (days > 0)
+                                       snprintf(p, n,
+                                                "%i days %i:%i:%02i",
+                                                days, hours, minutes,
+                                                seconds);
+                               else if (days > 0)
+                                       snprintf(p, n, "%i:%i:%02i", hours,
+                                                minutes, seconds);
+                               else
+                                       snprintf(p, n, "%i:%02i", minutes,
+                                                seconds);
+                       }
+                       OBJ(mpd_percent) {
+                               snprintf(p, n, "%2.0f",
+                                        cur->mpd.progress * 100);
+                       }
+                       OBJ(mpd_bar) {
+                               new_bar(p, obj->data.pair.a,
+                                       obj->data.pair.b,
+                                       (int) (cur->mpd.progress *
+                                              255.0f));
+                       }
+#endif
+                       OBJ(top) {
+                               if (obj->data.top.type == TOP_NAME
+                                   && obj->data.top.num >= 0
+                                   && obj->data.top.num < 10) {
+                                       // if we limit the buffer and add a bunch of space after, it stops the thing from
+                                       // moving other shit around, which is really fucking annoying
+                                       snprintf(p, 17,
+                                                "%s                              ",
+                                                cur->cpu[obj->data.top.
+                                                         num]->name);
+                               } else if (obj->data.top.type == TOP_CPU
+                                          && obj->data.top.num >= 0
+                                          && obj->data.top.num < 10) {
+                                       snprintf(p, 7, "%3.2f      ",
+                                                cur->cpu[obj->data.top.
+                                                         num]->amount);
+                               } else if (obj->data.top.type == TOP_PID
+                                          && obj->data.top.num >= 0
+                                          && obj->data.top.num < 10) {
+                                       snprintf(p, 8, "%i           ",
+                                                cur->cpu[obj->data.top.
+                                                         num]->pid);
+                               } else if (obj->data.top.type == TOP_MEM
+                                          && obj->data.top.num >= 0
+                                          && obj->data.top.num < 10) {
+                                       snprintf(p, 7, "%3.2f       ",
+                                                cur->cpu[obj->data.top.
+                                                         num]->totalmem);
+                               }
+                       }
+                       OBJ(top_mem) {
+                               if (obj->data.top.type == TOP_NAME
+                                   && obj->data.top.num >= 0
+                                   && obj->data.top.num < 10) {
+                                       // if we limit the buffer and add a bunch of space after, it stops the thing from
+                                       // moving other shit around, which is really fucking annoying
+                                       snprintf(p, 17,
+                                                "%s                              ",
+                                                cur->memu[obj->data.top.
+                                                          num]->name);
+                               } else if (obj->data.top.type == TOP_CPU
+                                          && obj->data.top.num >= 0
+                                          && obj->data.top.num < 10) {
+                                       snprintf(p, 7, "%3.2f      ",
+                                                cur->memu[obj->data.top.
+                                                          num]->amount);
+                               } else if (obj->data.top.type == TOP_PID
+                                          && obj->data.top.num >= 0
+                                          && obj->data.top.num < 10) {
+                                       snprintf(p, 8, "%i           ",
+                                                cur->memu[obj->data.top.
+                                                          num]->pid);
+                               } else if (obj->data.top.type == TOP_MEM
+                                          && obj->data.top.num >= 0
+                                          && obj->data.top.num < 10) {
+                                       snprintf(p, 7, "%3.2f       ",
+                                                cur->memu[obj->data.top.
+                                                          num]->totalmem);
+                               }
+                       }
+
+
+
+                       /*
+                        * I'm tired of everything being packed in
+                        * pee
+                        * poop
+                        */
+
+
+                       OBJ(tail) {
+                               if (current_update_time -obj->data.tail.last_update < obj->data.tail.interval) {
+                                       snprintf(p, n, "%s", obj->data.tail.buffer);
+                               } else {
+                                       obj->data.tail.last_update = current_update_time;
+                                       FILE *fp;
+                                       int i;
+                                       int added = 0;
+                                       tailstring *head = NULL;
+                                       tailstring *headtmp = NULL;
+                                       fp = fopen(obj->data.tail.logfile, "rt");
+                                       if (fp == NULL) {
+                                               ERR("tail logfile failed to open");
+                                       }
+                                       else {
+                                               obj->data.tail.readlines = 0;
+
+                                               while (fgets(obj->data.tail.buffer, TEXT_BUFFER_SIZE*4, fp) != NULL) {
+                                                       if (added >= 30) {
+                                                               freelasttail(head);
+                                                       }
+                                                       else {
+                                                               added++;
+                                                       }
+                                                       addtail(&head, obj->data.tail.buffer);
+                                                       obj->data.tail.readlines++;
+                                               }
+
+                                               fclose(fp);
+
+                                               if (obj->data.tail.readlines > 0) {
+                                                       for (i = 0;i < obj->data.tail.wantedlines + 1 && i < obj->data.tail.readlines; i++) {
+                                                               addtail(&headtmp, head->data);
+                                                               head = head->next;
+                                                       }
+                                                       strcpy(obj->data.tail.buffer, headtmp->data);
+                                                       headtmp = headtmp->next;
+                                                       for (i = 1;i < obj->data.tail.wantedlines + 1 && i < obj->data.tail.readlines; i++) {
+                                                               if (headtmp) {
+                                                                       strncat(obj->data.tail.buffer, headtmp->data, (TEXT_BUFFER_SIZE * 6 / obj->data.tail.wantedlines) - strlen(obj->data.tail.buffer)); /* without strlen() at the end this becomes a possible */
+                                                                       headtmp = headtmp->next;
+                                                               }
+                                                       }
+
+                                                       /* get rid of any ugly newlines at the end */
+                                                       if (obj->data.tail.buffer[strlen(obj->data.tail.buffer)-1] == '\n') {
+                                                               obj->data.tail.buffer[strlen(obj->data.tail.buffer)-1] = '\0';
+                                                       }
+                                                       snprintf(p, n, "%s", obj->data.tail.buffer);
+
+                                                       freetail(headtmp);
+                                               }
+                                               else {
+                                                       strcpy(obj->data.tail.buffer, "Logfile Empty");
+                                                       snprintf(p, n, "Logfile Empty");
+                                               }
+                                               freetail(head);
+                                       }
+                               }
+                       }
+
+
+
+                       break;
+               }
+
+               {
+                       unsigned int a = strlen(p);
+                       p += a;
+                       n -= a;
+               }
+       }
+
+       if (stuff_in_upper_case) {
+               char *p;
+
+               p = text_buffer;
+               while (*p) {
+                       *p = toupper(*p);
+                       p++;
+               }
+       }
+
+       last_update_time = current_update_time;
+       total_updates++;
+       //free(p);
+}
+
+#ifdef X11
+static void set_font()
+{
+#ifdef XFT
+       if (use_xft) {
+                       if (window.xftdraw != NULL)
+                               XftDrawDestroy(window.xftdraw);
+                       window.xftdraw = XftDrawCreate(display, window.drawable,
+                                       DefaultVisual(display,
+                                                       screen),
+                                       DefaultColormap(display,
+                                                       screen));
+               } else
+#endif
+{
+       XSetFont(display, window.gc, fonts[selected_font].font->fid);
+}
+}
+
+
+/*
+ * text size
+ */
+
+static int text_start_x, text_start_y; /* text start position in window */
+static int text_width, text_height;
+
+#endif /* X11 */
+
+static inline int get_string_width(const char *s)
+{
+#ifdef X11
+       return *s ? calc_text_width(s, strlen(s)) : 0;
+#else
+       return strlen(s);
+#endif /* X11 */
+}
+
+int fontchange = 0;
+
+#ifdef X11
+static void text_size_updater(char *s)
+{
+       int w = 0;
+       char *p;
+       int h = font_height();
+       /* get string widths and skip specials */
+       p = s;
+       while (*p) {
+               if (*p == SPECIAL_CHAR) {
+                       *p = '\0';
+                       w += get_string_width(s);
+                       *p = SPECIAL_CHAR;
+
+                       if (specials[special_index].type == BAR
+                           || specials[special_index].type == GRAPH) {
+                               w += specials[special_index].width;
+                               if (specials[special_index].height > h) {
+                                       h = specials[special_index].height;
+                                       h += font_ascent();
+                               }
+                       }
+                       
+                       else if (specials[special_index].type == OFFSET) {
+                               w += specials[special_index].arg + get_string_width("a"); /* filthy, but works */
+                       }
+                       else if (specials[special_index].type == VOFFSET) {
+                               h += specials[special_index].arg;
+                       }
+                       else if (specials[special_index].type == FONT) {
+                               fontchange = specials[special_index].font_added;
+                               selected_font = specials[special_index].font_added;
+                               h = font_height();
+                       }
+
+                       
+                       special_index++;
+                       s = p + 1;
+               }
+               p++;
+       }
+               w += get_string_width(s);
+       if (w > text_width)
+               text_width = w;
+
+       text_height += h;
+       if (fontchange) {
+               selected_font = 0;
+       }
+}
+#endif /* X11 */
+
+
+#ifdef X11
+static void update_text_area()
+{
+       int x, y;
+
+       /* update text size if it isn't fixed */
+#ifdef OWN_WINDOW
+       if (!fixed_size)
+#endif
+       {
+               text_width = minimum_width;
+               text_height = 0;
+               special_index = 0;
+               for_each_line(text_buffer, text_size_updater);
+               text_width += 1;
+               if (text_height < minimum_height)
+                       text_height = minimum_height;
+       }
+
+       /* get text position on workarea */
+       switch (text_alignment) {
+       case TOP_LEFT:
+               x = gap_x;
+               y = gap_y;
+               break;
+
+       case TOP_RIGHT:
+               x = workarea[2] - text_width - gap_x;
+               y = gap_y;
+               break;
+
+       default:
+       case BOTTOM_LEFT:
+               x = gap_x;
+               y = workarea[3] - text_height - gap_y;
+               break;
+
+       case BOTTOM_RIGHT:
+               x = workarea[2] - text_width - gap_x;
+               y = workarea[3] - text_height - gap_y;
+               break;
+       
+#ifdef OWN_WINDOW
+       case NONE: // Let the WM manage the window
+               x = window.x;
+               y = window.y;
+
+               fixed_pos  = 1;
+               fixed_size = 1;
+               break;
+#endif
+       }
+#ifdef OWN_WINDOW
+
+       if (own_window && !fixed_pos) {
+               x += workarea[0];
+               y += workarea[1];
+               text_start_x = border_margin + 1;
+               text_start_y = border_margin + 1;
+               window.x = x - border_margin - 1;
+               window.y = y - border_margin - 1;
+       } else
+#endif
+       {
+               /* If window size doesn't match to workarea's size, then window
+                * probably includes panels (gnome).
+                * Blah, doesn't work on KDE. */
+               if (workarea[2] != window.width
+                   || workarea[3] != window.height) {
+                       y += workarea[1];
+                       x += workarea[0];
+               }
+
+               text_start_x = x;
+               text_start_y = y;
+       }
+}
+
+/*
+ * drawing stuff
+ */
+
+static int cur_x, cur_y;       /* current x and y for drawing */
+static int draw_mode;          /* FG, BG or OUTLINE */
+static long current_color;
+
+static inline void set_foreground_color(long c)
+{
+       current_color = c;
+       XSetForeground(display, window.gc, c);
+}
+#endif /* X11 */
+
+static void draw_string(const char *s)
+{
+       if (s[0] == '\0')
+               return;
+       int i, i2, pos, width_of_s;
+       int max=0;
+       int added;
+       width_of_s = get_string_width(s);
+       if (out_to_console) {
+               printf("%s\n", s);
+       }
+       /* daemon_run(s);  the daemon can be called here, but we need to have a buffer in daemon_run() and we need to tell it when everything is ready to be sent */
+       strcpy(tmpstring1, s);
+       pos = 0;
+       added = 0;
+       char space[2];
+       snprintf(space, 2, " ");
+#ifdef X11
+       max = ((text_width - width_of_s) / get_string_width(space));
+#endif /* X11 */
+       /*
+        * This code looks for tabs in the text and coverts them to spaces.
+        * The trick is getting the correct number of spaces,
+        * and not going over the window's size without forcing
+        * the window larger.
+        */
+       for (i = 0; i < TEXT_BUFFER_SIZE; i++) {
+               if (tmpstring1[i] == '\t')      // 9 is ascii tab
+               {
+                       i2 = 0;
+                       for (i2 = 0;
+                            i2 < (8 - (1 + pos) % 8) && added <= max;
+                            i2++) {
+                               tmpstring2[pos + i2] = ' ';
+                               added++;
+                       }
+                       pos += i2;
+               } else {
+                       if (tmpstring1[i] != 9) {
+                               tmpstring2[pos] = tmpstring1[i];
+                               pos++;
+                       }
+               }
+       }
+       s = tmpstring2;
+#ifdef X11
+#ifdef XFT
+       if (use_xft) {
+               XColor c;
+               XftColor c2;
+               c.pixel = current_color;
+               XQueryColor(display, DefaultColormap(display, screen), &c);
+
+               c2.pixel = c.pixel;
+               c2.color.red = c.red;
+               c2.color.green = c.green;
+               c2.color.blue = c.blue;
+               c2.color.alpha = fonts[selected_font].font_alpha;
+               if (utf8_mode) {
+                       XftDrawStringUtf8(window.xftdraw, &c2, fonts[selected_font].xftfont,
+                                         cur_x, cur_y, (XftChar8 *) s,
+                                         strlen(s));
+               } else {
+                       XftDrawString8(window.xftdraw, &c2, fonts[selected_font].xftfont,
+                                      cur_x, cur_y, (XftChar8 *) s,
+                                      strlen(s));
+               }
+       } else
+#endif
+       {
+               XDrawString(display, window.drawable, window.gc,
+                           cur_x, cur_y, s, strlen(s));
+       }
+       cur_x += width_of_s;
+#endif /* X11 */
+       memcpy(tmpstring1, s, TEXT_BUFFER_SIZE);
+}
+
+long redmask, greenmask, bluemask;
+short colour_depth = 0;
+
+void set_up_gradient()
+{
+       colour_depth = DisplayPlanes(display, screen);
+       if (colour_depth != 24 && colour_depth != 16) {
+               ERR("using non-standard colour depth, gradients may look like a lolly-pop");
+       }
+       int i;
+       redmask = 0;
+       greenmask = 0;
+       bluemask = 0;
+       for(i = (colour_depth / 3)-1; i>=0; i--) {
+               redmask |= 1 << i;
+               greenmask |= 1 << i;
+               bluemask |= 1 << i;
+       }
+       if (colour_depth%3 == 1) {
+               greenmask |= 1 << (colour_depth / 3);
+       }
+       redmask = redmask << (2*colour_depth / 3 + colour_depth%3);
+       greenmask = greenmask << (colour_depth / 3);
+}
+
+inline unsigned long do_gradient(unsigned long first_colour, unsigned long last_colour) { /* this function returns the next colour between two colours for a gradient */
+       int tmp_color = 0;
+       int red1, green1, blue1; // first colour
+       int red2, green2, blue2; // second colour
+       int red3 = 0, green3 = 0, blue3 = 0; // difference
+       short redshift = (2*colour_depth / 3 + colour_depth%3);
+       short greenshift = (colour_depth / 3);
+       red1 = (first_colour & redmask) >> redshift;
+       green1 = (first_colour & greenmask) >> greenshift;
+       blue1 = first_colour & bluemask;
+       red2 = (last_colour & redmask) >> redshift;
+       green2 = (last_colour & greenmask) >> greenshift;
+       blue2 = last_colour & bluemask;
+       if (red1 > red2) {
+               red3 = -1;
+       }
+       if (red1 < red2) {
+               red3 = 1;
+       }
+       if (green1 > green2) {
+               green3 = -1;
+       }
+       if (green1 < green2) {
+               green3 = 1;
+       }
+       if (blue1 > blue2) {
+               blue3 = -1;
+       }
+       if (blue1 < blue2) {
+               blue3 = 1;
+       }
+       red1 += red3;
+       green1 += green3;
+       blue1 += blue3;
+       if (red1 < 0) {
+               red1 = 0;
+       }
+       if (green1 < 0) {
+               green1 = 0;
+       }
+       if (blue1 < 0) {
+               blue1 = 0;
+       }
+       if (red1 > bluemask) {
+               red1 = bluemask;
+       }
+       if (green1 > bluemask) {
+               green1 = bluemask;
+       }
+       if (blue1 > bluemask) {
+               blue1 = bluemask;
+       }
+       tmp_color = (red1 << redshift) | (green1 << greenshift) | blue1;
+       return tmp_color;
+}
+
+inline unsigned long gradient_max(unsigned long first_colour, unsigned long last_colour) { /* this function returns the max diff for a gradient */
+       if (colour_depth == 0) {
+               set_up_gradient();
+       }
+       int red1, green1, blue1; // first colour
+       int red2, green2, blue2; // second colour
+       long redshift = (2*colour_depth / 3 + colour_depth%3);
+       long greenshift = (colour_depth / 3);
+       int red3 = 0, green3 = 0, blue3 = 0; // difference
+       red1 = (first_colour & redmask) >> redshift;
+       green1 = (first_colour & greenmask) >> greenshift;
+       blue1 = first_colour & bluemask;
+       red2 = (last_colour & redmask) >> redshift;
+       green2 = (last_colour & greenmask) >> greenshift;
+       blue2 = last_colour & bluemask;
+       red3 = abs(red1 - red2);
+       green3 = abs(green1 - green2);
+       blue3 = abs(blue1 - blue2);
+       int max = red3;
+       if (green3 > max)
+               max = green3;
+       if (blue3 > max)
+               max = blue3;
+       return max;
+}
+
+static void draw_line(char *s)
+{
+#ifdef X11
+       char *p;
+       cur_x = text_start_x;
+       cur_y += font_ascent();
+       int cur_y_add = 0;
+       short font_h = font_height();
+
+       /* find specials and draw stuff */
+       p = s;
+       while (*p) {
+               if (*p == SPECIAL_CHAR) {
+                       int w = 0;
+
+                       /* draw string before special */
+                       *p = '\0';
+                       draw_string(s);
+                       *p = SPECIAL_CHAR;
+                       s = p + 1;
+
+                       /* draw special */
+                       switch (specials[special_index].type) {
+                       case HORIZONTAL_LINE:
+                               {
+                                       int h =
+                                           specials[special_index].height;
+                                       int mid = font_ascent() / 2;
+                                       w = text_start_x + text_width -
+                                           cur_x;
+
+                                       XSetLineAttributes(display,
+                                                          window.gc, h,
+                                                          LineSolid,
+                                                          CapButt,
+                                                          JoinMiter);
+                                       XDrawLine(display, window.drawable,
+                                                 window.gc, cur_x,
+                                                 cur_y - mid / 2,
+                                                 cur_x + w,
+                                                 cur_y - mid / 2);
+                               }
+                               break;
+
+                       case STIPPLED_HR:
+                               {
+                                       int h =
+                                           specials[special_index].height;
+                                       int s =
+                                           specials[special_index].arg;
+                                       int mid = font_ascent() / 2;
+                                       char ss[2] = { s, s };
+                                       w = text_start_x + text_width -
+                                           cur_x - 1;
+
+                                       XSetLineAttributes(display,
+                                                          window.gc, h,
+                                                          LineOnOffDash,
+                                                          CapButt,
+                                                          JoinMiter);
+                                       XSetDashes(display, window.gc, 0,
+                                                  ss, 2);
+                                       XDrawLine(display, window.drawable,
+                                                 window.gc, cur_x,
+                                                 cur_y - mid / 2,
+                                                 cur_x + w,
+                                                 cur_y - mid / 2);
+                               }
+                               break;
+
+                       case BAR:
+                               {
+                                       int h =
+                                           specials[special_index].height;
+                                       int bar_usage =
+                                           specials[special_index].arg;
+                                       int by =
+                                           cur_y - (font_ascent() +
+                                                    h) / 2 - 1;
+                                       w = specials[special_index].width;
+                                       if (w == 0)
+                                               w = text_start_x +
+                                                   text_width - cur_x - 1;
+                                       if (w < 0)
+                                               w = 0;
+
+                                       XSetLineAttributes(display,
+                                                          window.gc, 1,
+                                                          LineSolid,
+                                                          CapButt,
+                                                          JoinMiter);
+
+                                       XDrawRectangle(display,
+                                                      window.drawable,
+                                                      window.gc, cur_x,
+                                                      by, w, h);
+                                       XFillRectangle(display,
+                                                      window.drawable,
+                                                      window.gc, cur_x,
+                                                      by,
+                                                      w * bar_usage / 255,
+                                                      h);
+                                       if (specials[special_index].
+                                           height > cur_y_add
+                                           && specials[special_index].
+                                           height > font_h) {
+                                               cur_y_add =
+                                                   specials
+                                                   [special_index].height;
+                                       }
+                               }
+                               break;
+
+                       case GRAPH:
+                               {
+                                       int h =
+                                           specials[special_index].height;
+                                       int by;
+#ifdef XFT
+                                       if (use_xft) {
+                                           by = cur_y - (font_ascent() +
+                                                    h) / 2 - 1;
+                                       } else
+#endif
+                                       {
+                                               by = cur_y - (font_ascent()/2);
+                                       }
+                                       w = specials[special_index].width;
+                                       if (w == 0)
+                                               w = text_start_x + text_width - cur_x - 1;
+                                       if (w < 0)
+                                               w = 0;
+                                       XSetLineAttributes(display,
+                                                          window.gc, 1,
+                                                          LineSolid,
+                                                          CapButt,
+                                                          JoinMiter);
+                                       XDrawRectangle(display,
+                                                      window.drawable,
+                                                      window.gc, cur_x,
+                                                      by, w, h);
+                                       XSetLineAttributes(display,
+                                                          window.gc, 1,
+                                                          LineSolid,
+                                                          CapButt,
+                                                          JoinMiter);
+       int i;
+       int j = 0;
+       int gradient_size = 0;
+       float gradient_factor = 0;
+       float gradient_update = 0;
+       unsigned long tmpcolour = current_color;
+       if (specials[special_index].first_colour != specials[special_index].last_colour) {
+               tmpcolour = specials[special_index].first_colour;
+               gradient_size = gradient_max(specials[special_index].first_colour, specials[special_index].last_colour);
+               gradient_factor = (float)gradient_size / (w - 3);
+       }
+       for (i = 0; i < w - 3; i++) {
+               if (specials[special_index].first_colour != specials[special_index].last_colour) {
+                       XSetForeground(display, window.gc, tmpcolour);
+                       gradient_update += gradient_factor;
+                       while (gradient_update > 0) {
+                               tmpcolour = do_gradient(tmpcolour, specials[special_index].last_colour);
+                               gradient_update--;
+                       }
+               }
+               if (i / ((float) (w - 3) / (specials[special_index].graph_width)) > j) {
+                       j++;
+                                               }
+                                               XDrawLine(display,  window.drawable, window.gc, cur_x + i + 2, by + h, cur_x + i + 2, by + h - specials[special_index].graph[j] * (h - 1) / specials[special_index].graph_scale);       /* this is mugfugly, but it works */
+       }
+                                       if (specials[special_index].
+                                           height > cur_y_add
+                                           && specials[special_index].
+                                           height > font_h) {
+                                               cur_y_add =
+                                                   specials
+                                                   [special_index].height;
+                                       }
+                               }
+                               if (draw_mode == BG) {
+                                       set_foreground_color(default_bg_color);
+                               }
+                               else if (draw_mode == OUTLINE) {
+                                       set_foreground_color(default_out_color);
+                               } else {
+                                       set_foreground_color(default_fg_color);
+                               }
+                               break;
+                       
+                               case FONT:
+                               if (fontchange) {
+                                       cur_y -= font_ascent();
+                                       selected_font = specials[special_index].font_added;
+                                       cur_y += font_ascent();
+#ifdef XFT
+                                       if (!use_xft)
+#endif
+                                       {
+                                               set_font();
+                                       }
+                               }
+                               break;
+                       case FG:
+                               if (draw_mode == FG)
+                                       set_foreground_color(specials
+                                                            [special_index].
+                                                            arg);
+                               break;
+
+                       case BG:
+                               if (draw_mode == BG)
+                                       set_foreground_color(specials
+                                                            [special_index].
+                                                            arg);
+                               break;
+
+                       case OUTLINE:
+                               if (draw_mode == OUTLINE)
+                                       set_foreground_color(specials
+                                                            [special_index].
+                                                            arg);
+                               break;
+
+                               case OFFSET:
+                               {
+                                       w += specials[special_index].arg;
+                               }
+                               break;
+                               case VOFFSET:
+                               {
+                                       cur_y += specials[special_index].arg;
+                               }
+                               break;
+
+                       case ALIGNR:
+                               {
+                                       int pos_x = text_width + gap_x - get_string_width(p) /*- border_margin*2 - 1*/;
+                                       /*printf("pos_x %i text_start_x %i text_width %i cur_x %i get_string_width(p) %i gap_x %i specials[special_index].arg %i border_margin %i border_width %i\n", pos_x, text_start_x, text_width, cur_x, get_string_width(p), gap_x, specials[special_index].arg, border_margin, border_width);*/
+                                       if (pos_x > specials[special_index].arg && pos_x > cur_x) {
+                                       cur_x = pos_x - specials[special_index].arg;
+                               }
+                               }
+                               break;
+
+                       case ALIGNC:
+                               {
+                                       int pos_x = (text_width)/2 - get_string_width(p)/2 - (cur_x - text_start_x);
+                                       /*printf("pos_x %i text_start_x %i text_width %i cur_x %i get_string_width(p) %i gap_x %i specials[special_index].arg %i\n", pos_x, text_start_x, text_width, cur_x, get_string_width(p), gap_x, specials[special_index].arg);*/
+                                       if (pos_x >
+                                           specials[special_index].arg)
+                                               w = pos_x -
+                                                   specials
+                                                   [special_index].arg;
+                               }
+                               break;
+
+                       }
+
+                       cur_x += w;
+
+                       special_index++;
+               }
+
+               p++;
+       }
+#else
+       draw_string(s);
+#endif
+#ifdef X11
+       if (cur_y_add > 0) {
+               cur_y += cur_y_add;
+               cur_y -= font_descent();
+       }
+
+       draw_string(s);
+
+       cur_y += font_descent();
+       if (fontchange) {
+               selected_font = 0;
+       }
+#endif /* X11 */
+}
+
+static void draw_text()
+{
+#ifdef X11
+       cur_y = text_start_y;
+
+       /* draw borders */
+       if (draw_borders && border_width > 0) {
+               unsigned int b = (border_width + 1) / 2;
+
+               if (stippled_borders) {
+                       char ss[2] =
+                           { stippled_borders, stippled_borders };
+                       XSetLineAttributes(display, window.gc,
+                                          border_width, LineOnOffDash,
+                                          CapButt, JoinMiter);
+                       XSetDashes(display, window.gc, 0, ss, 2);
+               } else {
+                       XSetLineAttributes(display, window.gc,
+                                          border_width, LineSolid,
+                                          CapButt, JoinMiter);
+               }
+
+               XDrawRectangle(display, window.drawable, window.gc,
+                              text_start_x - border_margin + b,
+                              text_start_y - border_margin + b,
+                              text_width + border_margin * 2 - 1 - b * 2,
+                              text_height + border_margin * 2 - 1 -
+                              b * 2);
+       }
+
+       /* draw text */
+       special_index = 0;
+#endif /* X11 */
+       for_each_line(text_buffer, draw_line);
+}
+
+static void draw_stuff()
+{
+#ifdef X11
+       if (draw_shades && !draw_outline) {
+               text_start_x++;
+               text_start_y++;
+               set_foreground_color(default_bg_color);
+               draw_mode = BG;
+               draw_text();
+               text_start_x--;
+               text_start_y--;
+       }
+
+       if (draw_outline) {
+               int i, j;
+               for (i = -1; i < 2; i++)
+                       for (j = -1; j < 2; j++) {
+                               if (i == 0 && j == 0)
+                                       continue;
+                               text_start_x += i;
+                               text_start_y += j;
+                               set_foreground_color(default_out_color);
+                               draw_mode = OUTLINE;
+                               draw_text();
+                               text_start_x -= i;
+                               text_start_y -= j;
+                       }
+       }
+
+       set_foreground_color(default_fg_color);
+       draw_mode = FG;
+#endif /* X11 */
+       draw_text();
+#ifdef X11
+#ifdef XDBE
+       if (use_xdbe) {
+               XdbeSwapInfo swap;
+               swap.swap_window = window.window;
+               swap.swap_action = XdbeBackground;
+               XdbeSwapBuffers(display, &swap, 1);
+       }
+#endif
+#endif /* X11 */
+}
+#ifdef X11
+static void clear_text(int exposures)
+{
+#ifdef XDBE
+       if (use_xdbe)
+               return;         /* The swap action is XdbeBackground, which clears */
+#endif
+       /* there is some extra space for borders and outlines */
+       XClearArea(display, window.drawable,
+                  text_start_x - border_margin - 1,
+                  text_start_y - border_margin - 1,
+                  text_width + border_margin * 2 + 2,
+                  text_height + border_margin * 2 + 2,
+                  exposures ? True : 0);
+}
+#endif /* X11 */
+
+static int need_to_update;
+
+/* update_text() generates new text and clears old text area */
+static void update_text()
+{
+       generate_text();
+#ifdef X11
+       clear_text(1);
+#endif /* X11 */
+       need_to_update = 1;
+}
+
+static void main_loop()
+{
+#ifdef X11
+       Region region = XCreateRegion();
+#endif /* X11 */
+
+       info.looped = 0;
+       while (total_run_times == 0 || info.looped < total_run_times - 1) {
+               info.looped++;
+#ifdef X11
+               XFlush(display);
+
+               /* wait for X event or timeout */
+
+               if (!XPending(display)) {
+                       fd_set fdsr;
+                       struct timeval tv;
+                       int s;
+                       double t =
+                           update_interval - (get_time() -
+                                              last_update_time);
+
+                       if (t < 0)
+                               t = 0;
+
+                       tv.tv_sec = (long) t;
+                       tv.tv_usec = (long) (t * 1000000) % 1000000;
+                       FD_ZERO(&fdsr);
+                       FD_SET(ConnectionNumber(display), &fdsr);
+
+
+                       s = select(ConnectionNumber(display) + 1, &fdsr, 0,
+                                  0, &tv);
+#else
+                       usleep(update_interval*1000000); /* FIXME just sleep for the interval time if no X11 */
+#endif /* X11 */
+#ifdef X11
+                       if (s == -1) {
+                               if (errno != EINTR)
+                                       ERR("can't select(): %s",
+                                           strerror(errno));
+                       } else {
+                               /* timeout */
+                               if (s == 0)
+#endif /* X11 */
+                                       update_text();
+#ifdef X11
+                       }
+               }
+
+               if (need_to_update) {
+#ifdef OWN_WINDOW
+                       int wx = window.x, wy = window.y;
+#endif
+
+                       need_to_update = 0;
+
+                       update_text_area();
+
+#ifdef OWN_WINDOW
+                       if (own_window) {
+                               /* resize window if it isn't right size */
+                               if (!fixed_size &&
+                                   (text_width + border_margin * 2 !=
+                                    window.width
+                                    || text_height + border_margin * 2 !=
+                                    window.height)) {
+                                       window.width =
+                                           text_width +
+                                           border_margin * 2 + 1;
+                                       window.height =
+                                           text_height +
+                                           border_margin * 2 + 1;
+                                       XResizeWindow(display,
+                                                     window.window,
+                                                     window.width,
+                                                     window.height);
+                               }
+
+                               /* move window if it isn't in right position */
+                               if (!fixed_pos
+                                   && (window.x != wx
+                                       || window.y != wy)) {
+                                       XMoveWindow(display, window.window,
+                                                   window.x, window.y);
+                               }
+                       }
+#endif
+
+                       clear_text(1);
+
+#ifdef XDBE
+                       if (use_xdbe) {
+                               XRectangle r;
+                               r.x = text_start_x - border_margin;
+                               r.y = text_start_y - border_margin;
+                               r.width = text_width + border_margin * 2;
+                               r.height = text_height + border_margin * 2;
+                               XUnionRectWithRegion(&r, region, region);
+                       }
+#endif
+               }
+
+               /* handle X events */
+
+               while (XPending(display)) {
+                       XEvent ev;
+                       XNextEvent(display, &ev);
+
+                       switch (ev.type) {
+                       case Expose:
+                               {
+                                       XRectangle r;
+                                       r.x = ev.xexpose.x;
+                                       r.y = ev.xexpose.y;
+                                       r.width = ev.xexpose.width;
+                                       r.height = ev.xexpose.height;
+                                       XUnionRectWithRegion(&r, region,
+                                                            region);
+                               }
+                               break;
+
+#ifdef OWN_WINDOW
+                       case ReparentNotify:
+                               /* set background to ParentRelative for all parents */
+                               if (own_window)
+                                       set_transparent_background(window.
+                                                                  window);
+                               break;
+
+                       case ConfigureNotify:
+                               if (own_window) {
+                                       /* if window size isn't what expected, set fixed size */
+                                       if (ev.xconfigure.width !=
+                                           window.width
+                                           || ev.xconfigure.height !=
+                                           window.height) {
+                                               if (window.width != 0
+                                                   && window.height != 0)
+                                                       fixed_size = 1;
+
+                                               /* clear old stuff before screwing up size and pos */
+                                               clear_text(1);
+
+                                               {
+                                                       XWindowAttributes
+                                                           attrs;
+                                                       if (XGetWindowAttributes(display, window.window, &attrs)) {
+                                                               window.
+                                                                   width =
+                                                                   attrs.
+                                                                   width;
+                                                               window.
+                                                                   height
+                                                                   =
+                                                                   attrs.
+                                                                   height;
+                                                       }
+                                               }
+
+                                               text_width =
+                                                   window.width -
+                                                   border_margin * 2 - 1;
+                                               text_height =
+                                                   window.height -
+                                                   border_margin * 2 - 1;
+                                       }
+
+                                       /* if position isn't what expected, set fixed pos, total_updates
+                                        * avoids setting fixed_pos when window is set to weird locations
+                                        * when started */
+                                       if (total_updates >= 2
+                                           && !fixed_pos
+                                           && (window.x != ev.xconfigure.x
+                                               || window.y !=
+                                               ev.xconfigure.y)
+                                           && (ev.xconfigure.x != 0
+                                               || ev.xconfigure.y != 0)) {
+                                               fixed_pos = 1;
+                                       }
+                               }
+                               break;
+#endif
+
+                       default:
+                               break;
+                       }
+               }
+
+               /* XDBE doesn't seem to provide a way to clear the back buffer without
+                * interfering with the front buffer, other than passing XdbeBackground
+                * to XdbeSwapBuffers. That means that if we're using XDBE, we need to
+                * redraw the text even if it wasn't part of the exposed area. OTOH,
+                * if we're not going to call draw_stuff at all, then no swap happens
+                * and we can safely do nothing.
+                */
+
+               if (!XEmptyRegion(region)) {
+#ifdef XDBE
+                       if (use_xdbe) {
+                               XRectangle r;
+                               r.x = text_start_x - border_margin;
+                               r.y = text_start_y - border_margin;
+                               r.width = text_width + border_margin * 2;
+                               r.height = text_height + border_margin * 2;
+                               XUnionRectWithRegion(&r, region, region);
+                       }
+#endif
+                       XSetRegion(display, window.gc, region);
+#ifdef XFT
+                       if (use_xft)
+                               XftDrawSetClip(window.xftdraw, region);
+#endif
+#endif /* X11 */
+                       draw_stuff();
+#ifdef X11
+                       XDestroyRegion(region);
+                       region = XCreateRegion();
+               }
+#endif /* X11 */
+
+       }
+}
+
+static void load_config_file(const char *);
+
+/* signal handler that reloads config file */
+static void reload_handler(int a)
+{
+       ERR("Conky: received signal %d, reloading config\n", a);
+
+       if (current_config) {
+               clear_fs_stats();
+               load_config_file(current_config);
+#ifdef X11
+               load_fonts();
+               set_font();
+#endif /* X11 */
+               extract_variable_text(text);
+               free(text);
+               text = NULL;
+               update_text();
+       }
+}
+
+static void clean_up()
+{
+#ifdef X11
+#ifdef XDBE
+       if (use_xdbe)
+               XdbeDeallocateBackBufferName(display, window.back_buffer);
+#endif
+#ifdef OWN_WINDOW
+       if (own_window)
+               XDestroyWindow(display, window.window);
+       else
+#endif
+       {
+               XClearWindow(display, RootWindow(display, screen));
+               clear_text(1);
+               XFlush(display);
+       }
+
+       XFreeGC(display, window.gc);
+#endif /* X11 */
+
+
+       /* it is really pointless to free() memory at the end of program but ak|ra
+        * wants me to do this */
+
+       free_text_objects();
+
+       if (text != original_text)
+               free(text);
+
+       free(current_config);
+       free(current_mail_spool);
+#ifdef SETI
+       free(seti_dir);
+#endif
+}
+
+static void term_handler(int a)
+{
+       a = a;                  /* to get rid of warning */
+       clean_up();
+       exit(0);
+}
+
+static int string_to_bool(const char *s)
+{
+       if (!s)
+               return 1;
+       if (strcasecmp(s, "yes") == 0)
+               return 1;
+       if (strcasecmp(s, "true") == 0)
+               return 1;
+       if (strcasecmp(s, "1") == 0)
+               return 1;
+       return 0;
+}
+#ifdef X11
+static enum alignment string_to_alignment(const char *s)
+{
+       if (strcasecmp(s, "top_left") == 0)
+               return TOP_LEFT;
+       else if (strcasecmp(s, "top_right") == 0)
+               return TOP_RIGHT;
+       else if (strcasecmp(s, "bottom_left") == 0)
+               return BOTTOM_LEFT;
+       else if (strcasecmp(s, "bottom_right") == 0)
+               return BOTTOM_RIGHT;
+       else if (strcasecmp(s, "tl") == 0)
+               return TOP_LEFT;
+       else if (strcasecmp(s, "tr") == 0)
+               return TOP_RIGHT;
+       else if (strcasecmp(s, "bl") == 0)
+               return BOTTOM_LEFT;
+       else if (strcasecmp(s, "br") == 0)
+               return BOTTOM_RIGHT;
+       else if (strcasecmp(s, "none") == 0)
+               return NONE;
+       return TOP_LEFT;
+}
+#endif /* X11 */
+
+
+static void set_default_configurations(void)
+{
+       fork_to_background = 0;
+       total_run_times = 0;
+       info.cpu_avg_samples = 2;
+       info.net_avg_samples = 2;
+       info.memmax = 0;
+       top_cpu = 0;
+       top_mem = 0;
+#ifdef MPD
+       strcpy(info.mpd.host, "localhost");
+       info.mpd.port = 6600;
+       info.mpd.status = "Checking status...";
+#endif
+       use_spacer = 0;
+#ifdef X11
+       out_to_console = 0;
+#else
+       out_to_console = 1;
+#endif
+#ifdef X11
+       default_fg_color = WhitePixel(display, screen);
+       default_bg_color = BlackPixel(display, screen);
+       default_out_color = BlackPixel(display, screen);
+       draw_borders = 0;
+       draw_shades = 1;
+       draw_outline = 0;
+       set_first_font("6x10");
+       gap_x = 5;
+       gap_y = 5;
+       minimum_width = 5;
+       minimum_height = 5;
+#ifdef OWN_WINDOW
+       own_window = 0;
+#endif
+       stippled_borders = 0;
+       border_margin = 3;
+       border_width = 1;
+       text_alignment = BOTTOM_LEFT;
+       on_bottom = 1;
+#endif /* X11 */
+
+       free(current_mail_spool);
+       {
+               char buf[256];
+               variable_substitute(MAIL_FILE, buf, 256);
+               if (buf[0] != '\0')
+                       current_mail_spool = strdup(buf);
+       }
+
+       no_buffers = 1;
+       update_interval = 10.0;
+       stuff_in_upper_case = 0;
+#ifdef MLDONKEY
+       mlconfig.mldonkey_hostname = "127.0.0.1";
+       mlconfig.mldonkey_port = 4001;
+       mlconfig.mldonkey_login = NULL;
+       mlconfig.mldonkey_password = NULL;
+#endif
+}
+
+static void load_config_file(const char *f)
+{
+#define CONF_ERR ERR("%s: %d: config file error", f, line)
+       int line = 0;
+       FILE *fp;
+
+       set_default_configurations();
+
+       fp = open_file(f, 0);
+       if (!fp)
+               return;
+
+       while (!feof(fp)) {
+               char buf[256], *p, *p2, *name, *value;
+               line++;
+               if (fgets(buf, 256, fp) == NULL)
+                       break;
+
+               p = buf;
+
+               /* break at comment */
+               p2 = strchr(p, '#');
+               if (p2)
+                       *p2 = '\0';
+
+               /* skip spaces */
+               while (*p && isspace((int) *p))
+                       p++;
+               if (*p == '\0')
+                       continue;       /* empty line */
+
+               name = p;
+
+               /* skip name */
+               p2 = p;
+               while (*p2 && !isspace((int) *p2))
+                       p2++;
+               if (*p2 != '\0') {
+                       *p2 = '\0';     /* break at name's end */
+                       p2++;
+               }
+
+               /* get value */
+               if (*p2) {
+                       p = p2;
+                       while (*p && isspace((int) *p))
+                               p++;
+
+                       value = p;
+
+                       p2 = value + strlen(value);
+                       while (isspace((int) *(p2 - 1)))
+                               *--p2 = '\0';
+               } else {
+                       value = 0;
+               }
+
+#define CONF2(a) if (strcasecmp(name, a) == 0)
+#define CONF(a) else CONF2(a)
+#define CONF3(a,b) \
+else if (strcasecmp(name, a) == 0 || strcasecmp(name, a) == 0)
+
+
+#ifdef X11
+               CONF2("alignment") {
+       if (value) {
+               int a = string_to_alignment(value);
+               if (a <= 0)
+                       CONF_ERR;
+               else
+                       text_alignment = a;
+       } else
+               CONF_ERR;
+               }
+               CONF("on_bottom") {
+                       if(value)
+                               on_bottom = string_to_bool(value);
+                       else
+                               CONF_ERR;
+               }
+               CONF("background") {
+                       fork_to_background = string_to_bool(value);
+               }
+
+#else
+               CONF2("background") {
+       fork_to_background = string_to_bool(value);
+               }
+#endif /* X11 */
+#ifdef X11
+               CONF("border_margin") {
+                       if (value)
+                               border_margin = strtol(value, 0, 0);
+                       else
+                               CONF_ERR;
+               }
+               CONF("border_width") {
+                       if (value)
+                               border_width = strtol(value, 0, 0);
+                       else
+                               CONF_ERR;
+               }
+               CONF("default_color") {
+                       if (value)
+                               default_fg_color = get_x11_color(value);
+                       else
+                               CONF_ERR;
+               }
+               CONF3("default_shade_color", "default_shadecolor") {
+                       if (value)
+                               default_bg_color = get_x11_color(value);
+                       else
+                               CONF_ERR;
+               }
+               CONF3("default_outline_color", "default_outlinecolor") {
+                       if (value)
+                               default_out_color = get_x11_color(value);
+                       else
+                               CONF_ERR;
+               }
+#endif /* X11 */
+#ifdef MPD
+               CONF("mpd_host") {
+                       if (value)
+                               strcpy(info.mpd.host, value);
+                       else
+                               CONF_ERR;
+               }
+               CONF("mpd_port") {
+                       if (value) {
+                               info.mpd.port = strtol(value, 0, 0);
+                               if (info.mpd.port < 1
+                                   || info.mpd.port > 0xffff)
+                                       CONF_ERR;
+                       }
+               }
+#endif
+               CONF("cpu_avg_samples") {
+                       if (value) {
+                               cpu_avg_samples = strtol(value, 0, 0);
+                               if (cpu_avg_samples < 1
+                                   || cpu_avg_samples > 14)
+                                       CONF_ERR;
+                               else
+                                       info.
+                                           cpu_avg_samples
+                                           = cpu_avg_samples;
+                       } else
+                               CONF_ERR;
+               }
+               CONF("net_avg_samples") {
+                       if (value) {
+                               net_avg_samples = strtol(value, 0, 0);
+                               if (net_avg_samples < 1
+                                   || net_avg_samples > 14)
+                                       CONF_ERR;
+                               else
+                                       info.
+                                           net_avg_samples
+                                           = net_avg_samples;
+                       } else
+                               CONF_ERR;
+               }
+
+
+
+
+
+
+#ifdef XDBE
+               CONF("double_buffer") {
+       if (!own_window) {
+               use_xdbe = string_to_bool(value);
+       }
+               }
+#endif
+#ifdef X11
+               CONF("override_utf8_locale") {
+       utf8_mode = string_to_bool(value);
+               }
+
+               CONF("draw_borders") {
+                       draw_borders = string_to_bool(value);
+               }
+               CONF("draw_shades") {
+                       draw_shades = string_to_bool(value);
+               }
+               CONF("draw_outline") {
+                       draw_outline = string_to_bool(value);
+               }
+#endif /* X11 */
+               CONF("out_to_console") {
+                       out_to_console = string_to_bool(value);
+               }
+               CONF("use_spacer") {
+                       use_spacer = string_to_bool(value);
+               }
+#ifdef X11
+#ifdef XFT
+               CONF("use_xft") {
+                       use_xft = string_to_bool(value);
+               }
+               CONF("font") {
+                       if (!use_xft) {
+                               if (value) {
+                                       set_first_font(value);
+                               } else
+                                       CONF_ERR;
+                       }
+               }
+               CONF("xftalpha") {
+                       if (value && font_count >= 0)
+                               fonts[0].font_alpha = atof(value)
+                                   * 65535.0;
+                       else
+                               CONF_ERR;
+               }
+               CONF("xftfont") {
+#else
+               CONF("use_xft") {
+                       if (string_to_bool(value))
+                               ERR("Xft not enabled");
+               }
+               CONF("xftfont") {
+                       /* xftfont silently ignored when no Xft */
+               }
+               CONF("xftalpha") {
+                       /* xftalpha is silently ignored when no Xft */
+               }
+               CONF("font") {
+#endif
+                       if (value) {
+                               set_first_font(value);
+                       } else
+                               CONF_ERR;
+               }
+               CONF("gap_x") {
+                       if (value)
+                               gap_x = atoi(value);
+                       else
+                               CONF_ERR;
+               }
+               CONF("gap_y") {
+                       if (value)
+                               gap_y = atoi(value);
+                       else
+                               CONF_ERR;
+               }
+#endif /* X11 */
+               CONF("mail_spool") {
+                       if (value) {
+                               char buf[256];
+                               variable_substitute(value, buf, 256);
+
+                               if (buf[0]
+                                   != '\0') {
+                                       if (current_mail_spool)
+                                               free(current_mail_spool);
+                                       current_mail_spool = strdup(buf);
+                               }
+                       } else
+                               CONF_ERR;
+               }
+#ifdef X11
+               CONF("minimum_size") {
+                       if (value) {
+                               if (sscanf
+                                   (value, "%d %d", &minimum_width,
+                                    &minimum_height) != 2)
+                                       if (sscanf
+                                           (value, "%d",
+                                            &minimum_width) != 1)
+                                               CONF_ERR;
+                       } else
+                               CONF_ERR;
+               }
+#endif /* X11 */
+               CONF("no_buffers") {
+                       no_buffers = string_to_bool(value);
+               }
+#ifdef MLDONKEY
+               CONF("mldonkey_hostname") {
+                       if (value) {
+                               if (mlconfig.mldonkey_hostname != NULL) {
+                                       free(mlconfig.mldonkey_hostname);
+                               }
+                       mlconfig.mldonkey_hostname = strdup(value);
+                       }
+                       else
+                               CONF_ERR;
+               }
+               CONF("mldonkey_port") {
+                       if (value)
+                               mlconfig.mldonkey_port = atoi(value);
+                       else
+                               CONF_ERR;
+               }
+               CONF("mldonkey_login") {
+                       if (value) {
+                               if (mlconfig.mldonkey_login != NULL) {
+                                       free(mlconfig.mldonkey_login);
+                               }
+                               mlconfig.mldonkey_login = strdup(value);
+                       }
+                       else
+                               CONF_ERR;
+               }
+               CONF("mldonkey_password") {
+                       if (value) {
+                               if (mlconfig.mldonkey_password != NULL) {
+                                       free(mlconfig.mldonkey_password);
+                               }
+                               mlconfig.mldonkey_password = strdup(value);
+                       }
+                       else
+                               CONF_ERR;
+               }
+#endif
+               CONF("pad_percents") {
+       pad_percents = atoi(value);
+               }
+#ifdef X11
+#ifdef OWN_WINDOW
+               CONF("own_window") {
+                       own_window = string_to_bool(value);
+                       use_xdbe = 0;
+               }
+#endif
+               CONF("stippled_borders") {
+                       if (value)
+                               stippled_borders = strtol(value, 0, 0);
+                       else
+                               stippled_borders = 4;
+               }
+#endif /* X11 */
+               CONF("temp1") {
+                       ERR("temp1 configuration is obsolete, use ${i2c <i2c device here> temp 1}");
+               }
+               CONF("temp1") {
+                       ERR("temp2 configuration is obsolete, use ${i2c <i2c device here> temp 2}");
+               }
+               CONF("update_interval") {
+                       if (value)
+                               update_interval = strtod(value, 0);
+                       else
+                               CONF_ERR;
+               }
+               CONF("total_run_times") {
+                       if (value)
+                               total_run_times = strtod(value, 0);
+                       else
+                               CONF_ERR;
+               }
+               CONF("uppercase") {
+                       stuff_in_upper_case = string_to_bool(value);
+               }
+#ifdef SETI
+               CONF("seti_dir") {
+                       seti_dir = (char *)
+                           malloc(strlen(value)
+                                  + 1);
+                       strcpy(seti_dir, value);
+               }
+#endif
+               CONF("text") {
+                       if (text != original_text)
+                               free(text);
+
+                       text = (char *)
+                           malloc(1);
+                       text[0]
+                           = '\0';
+
+                       while (!feof(fp)) {
+                               unsigned
+                               int l = strlen(text);
+                               if (fgets(buf, 256, fp) == NULL)
+                                       break;
+                               text = (char *)
+                                   realloc(text, l + strlen(buf)
+                                           + 1);
+                               strcat(text, buf);
+
+                               if (strlen(text) > 1024 * 8)
+                                       break;
+                       }
+                       fclose(fp);
+                       return;
+               }
+               else
+               ERR("%s: %d: no such configuration: '%s'", f, line, name);
+
+#undef CONF
+#undef CONF2
+       }
+
+       fclose(fp);
+#undef CONF_ERR
+}
+
+                                                                                                                                                                                       /* : means that character before that takes an argument */
+static const char *getopt_string = "vVdt:f:u:i:hc:w:x:y:a:"
+#ifdef X11
+               "x:y:w:a:f:"
+#ifdef OWN_WINDOW
+    "o"
+#endif
+#ifdef XDBE
+    "b"
+#endif
+#endif /* X11 */
+    ;
+
+
+int main(int argc, char **argv)
+{
+       /* handle command line parameters that don't change configs */
+#ifdef X11
+       char *s;
+       char temp[10];
+       unsigned int x;
+
+       if (((s = getenv("LC_ALL")) && *s) || ((s = getenv("LC_CTYPE")) && 
+                    *s) || ((s = getenv("LANG")) && *s)) {
+               strcpy(temp, s);
+               for(x = 0; x < strlen(s) ; x++) {
+                       temp[x] = tolower(s[x]);
+               }
+               if (strstr(temp, "utf-8") || strstr(temp, "utf8")) {
+                       utf8_mode = 1;
+               }
+       }
+       if (!setlocale(LC_CTYPE, "")) {
+               ERR("Can't set the specified locale!\nCheck LANG, LC_CTYPE, LC_ALL.");
+               return 1;
+       }
+#endif /* X11 */
+       while (1) {
+               int c = getopt(argc,
+                              argv,
+                              getopt_string);
+               if (c == -1)
+                       break;
+
+               switch (c) {
+               case 'v':
+               case 'V':
+                       printf
+                           ("Conky " VERSION " compiled " __DATE__ "\n");
+                       return 0;
+
+               case 'c':
+                       /* if current_config is set to a strdup of CONFIG_FILE, free it (even
+                        * though free() does the NULL check itself;), then load optarg value */
+                       if (current_config)
+                               free(current_config);
+                       current_config = strdup(optarg);
+                       break;
+
+               case 'h':
+                       printf
+                                       ("Usage: %s [OPTION]...\n"
+                                       "Conky is a system monitor that renders text on desktop or to own transparent\n"
+                                       "window. Command line options will override configurations defined in config\n"
+                                       "file.\n"
+                                       "   -V            version\n"
+                                       "   -c FILE       config file to load instead of "
+                                       CONFIG_FILE
+                                       "\n"
+                                       "   -d            daemonize, fork to background\n"
+                                       "   -h            help\n"
+#ifdef X11
+                                       "   -a ALIGNMENT  text alignment on screen, {top,bottom}_{left,right}\n"
+                                       "   -f FONT       font to use\n"
+#ifdef OWN_WINDOW
+                                       "   -o            create own window to draw\n"
+#endif
+#ifdef XDBE
+                                       "   -b            double buffer (prevents flickering)\n"
+#endif
+                                       "   -w WIN_ID     window id to draw\n"
+                                       "   -x X          x position\n"
+                                       "   -y Y          y position\n"
+#endif /* X11 */
+                                       "   -t TEXT       text to render, remember single quotes, like -t '$uptime'\n"
+                                       "   -u SECS       update interval\n"
+                                       "   -i NUM        number of times to update Conky\n", argv[0]);
+                       return 0;
+#ifdef X11
+               case 'w':
+                       window.window = strtol(optarg, 0, 0);
+                       break;
+#endif /* X11 */
+
+               case '?':
+                       exit(EXIT_FAILURE);
+               }
+       }
+#ifdef X11
+       /* initalize X BEFORE we load config. (we need to so that 'screen' is set) */
+       init_X11();
+#endif /* X11 */
+
+       tmpstring1 = (char *)
+           malloc(TEXT_BUFFER_SIZE);
+       tmpstring2 = (char *)
+           malloc(TEXT_BUFFER_SIZE);
+
+       /* load current_config or CONFIG_FILE */
+
+#ifdef CONFIG_FILE
+       if (current_config == NULL) {
+               /* load default config file */
+               char buf[256];
+
+               variable_substitute(CONFIG_FILE, buf, 256);
+
+               if (buf[0] != '\0')
+                       current_config = strdup(buf);
+       }
+#endif
+
+       if (current_config != NULL)
+               load_config_file(current_config);
+       else
+               set_default_configurations();
+
+#ifdef MAIL_FILE
+       if (current_mail_spool == NULL) {
+               char buf[256];
+               variable_substitute(MAIL_FILE, buf, 256);
+
+               if (buf[0] != '\0')
+                       current_mail_spool = strdup(buf);
+       }
+#endif
+
+       /* handle other command line arguments */
+
+       optind = 0;
+
+       while (1) {
+               int c = getopt(argc,
+                              argv,
+                              getopt_string);
+               if (c == -1)
+                       break;
+
+               switch (c) {
+               case 'd':
+                       fork_to_background = 1;
+                       break;
+
+#ifdef X11
+                       case 'f':
+                       set_first_font(optarg);
+                       break;
+                       case 'a':
+                               text_alignment = string_to_alignment(optarg);
+                               break;
+
+#ifdef OWN_WINDOW
+               case 'o':
+                       own_window = 1;
+                       use_xdbe = 0;
+                       break;
+#endif
+#ifdef XDBE
+               case 'b':
+                       use_xdbe = 1;
+                       break;
+#endif
+#endif /* X11 */
+               case 't':
+                       if (text != original_text)
+                               free(text);
+                       text = strdup(optarg);
+                       convert_escapes(text);
+                       break;
+
+               case 'u':
+                       update_interval = strtod(optarg, 0);
+                       break;
+
+               case 'i':
+                       total_run_times = strtod(optarg, 0);
+                       break;
+#ifdef X11
+               case 'x':
+                       gap_x = atoi(optarg);
+                       break;
+
+               case 'y':
+                       gap_y = atoi(optarg);
+                       break;
+#endif /* X11 */
+
+               case '?':
+                       exit(EXIT_FAILURE);
+               }
+       }
+
+#ifdef X11
+       /* load font */
+       load_fonts();
+#endif /* X11 */
+
+       /* generate text and get initial size */
+       extract_variable_text(text);
+       if (text != original_text) {
+               free(text);
+       }
+       text = NULL;
+
+       update_uname();
+
+       generate_text();
+#ifdef X11
+       update_text_area();     /* to get initial size of the window */
+
+#if defined OWN_WINDOW
+       init_window
+           (own_window,
+            text_width + border_margin * 2 + 1,
+            text_height + border_margin * 2 + 1,
+            on_bottom, fixed_pos);
+#else
+       init_window
+               (own_window,
+                text_width + border_margin * 2 + 1,
+                text_height + border_margin * 2 + 1,
+                on_bottom);
+       
+#endif
+
+       update_text_area();     /* to position text/window on screen */
+#endif /* X11 */
+
+/*#ifdef CAIRO
+// why the fuck not?
+//do_it();
+#endif*/
+
+#ifdef X11
+#ifdef OWN_WINDOW
+       if (own_window && !fixed_pos)
+               XMoveWindow(display, window.window, window.x, window.y);
+#endif
+
+       create_gc();
+
+       set_font();
+       draw_stuff();
+#endif /* X11 */
+
+       /* fork */
+       if (fork_to_background) {
+               int ret = fork();
+               switch (ret) {
+               case -1:
+                       ERR("can't fork() to background: %s",
+                           strerror(errno));
+                       break;
+
+               case 0:
+                       break;
+
+               default:
+                       fprintf
+                           (stderr,
+                            "Conky: forked to background, pid is %d\n",
+                            ret);
+                       return 0;
+               }
+       }
+
+       /* set SIGUSR1, SIGINT and SIGTERM handlers */
+       {
+               struct
+               sigaction sa;
+
+               sa.sa_handler = reload_handler;
+               sigemptyset(&sa.sa_mask);
+               sa.sa_flags = SA_RESTART;
+               if (sigaction(SIGUSR1, &sa, NULL) != 0)
+                       ERR("can't set signal handler for SIGUSR1: %s",
+                           strerror(errno));
+
+               sa.sa_handler = term_handler;
+               sigemptyset(&sa.sa_mask);
+               sa.sa_flags = SA_RESTART;
+               if (sigaction(SIGINT, &sa, NULL) != 0)
+                       ERR("can't set signal handler for SIGINT: %s",
+                           strerror(errno));
+
+               sa.sa_handler = term_handler;
+               sigemptyset(&sa.sa_mask);
+               sa.sa_flags = SA_RESTART;
+               if (sigaction(SIGTERM, &sa, NULL) != 0)
+                       ERR("can't set signal handler for SIGTERM: %s",
+                           strerror(errno));
+       }
+       main_loop();
+       free(tmpstring1);
+       free(tmpstring2);
+       return 0;
+}
diff --git a/src/conky.h b/src/conky.h
new file mode 100644 (file)
index 0000000..9f832ce
--- /dev/null
@@ -0,0 +1,379 @@
+/*
+ * Conky, a system monitor, based on torsmo
+ *
+ * This program is licensed under BSD license, read COPYING
+ *
+ *  $Id$
+ */
+
+#ifndef _conky_h_
+#define _conky_h_
+
+
+#include <mcheck.h>
+#include "config.h"
+#include <sys/utsname.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <locale.h>
+#include <langinfo.h>
+#include <wchar.h>
+
+#ifdef X11
+#if defined(HAVE_CAIRO_H) && defined(HAVE_CAIRO_XLIB_H) && defined(WANT_CAIRO)
+#define CAIRO
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <cairo.h>
+#include <cairo-xlib.h>
+#endif
+#endif /* X11 */
+
+#define TOP_CPU 1
+#define TOP_NAME 2
+#define TOP_PID 3
+#define TOP_MEM 4
+
+#define TEXT_BUFFER_SIZE 1024
+
+#include <sys/socket.h>
+
+#define ERR(s, varargs...) \
+fprintf(stderr, "Conky: " s "\n", ##varargs)
+
+/* critical error */
+#define CRIT_ERR(s, varargs...) \
+{ fprintf(stderr, "Conky: " s "\n", ##varargs);  exit(EXIT_FAILURE); }
+
+struct net_stat {
+       const char *dev;
+       int up;
+       long long last_read_recv, last_read_trans;
+       long long recv, trans;
+       double recv_speed, trans_speed;
+       struct sockaddr addr;
+       int linkstatus;
+       double net_rec[15], net_trans[15];
+};
+
+struct fs_stat {
+       int fd;
+       char *path;
+       long long size;
+       long long avail;
+};
+
+struct cpu_stat {
+       unsigned int user, nice, system, idle, iowait, irq, softirq;
+       int cpu_avg_samples;
+};
+
+#ifdef MPD
+struct mpd_s {
+       char *title;
+       char *artist;
+       char *album;
+       char *status;
+       int volume;
+       unsigned int port;
+       char host[128];
+       float progress;
+       int bitrate;
+       int length;
+       int elapsed;
+};
+#endif
+
+enum {
+       INFO_CPU = 0,
+       INFO_MAIL = 1,
+       INFO_MEM = 2,
+       INFO_NET = 3,
+#ifdef SETI
+       INFO_SETI = 4,
+#endif
+       INFO_PROCS = 5,
+       INFO_RUN_PROCS = 6,
+       INFO_UPTIME = 7,
+       INFO_BUFFERS = 8,
+       INFO_FS = 9,
+       INFO_I2C = 10,
+       INFO_MIXER = 11,
+       INFO_LOADAVG = 12,
+       INFO_UNAME = 13,
+       INFO_FREQ = 14,
+#ifdef MPD
+       INFO_MPD = 15,
+#endif
+       INFO_TOP = 16,
+#ifdef MLDONKEY
+       INFO_MLDONKEY = 18,
+#endif
+       INFO_WIFI = 19,
+};
+
+
+#ifdef MPD
+#include "libmpdclient.h"
+#endif
+
+struct information {
+       unsigned int mask;
+
+       struct utsname uname_s;
+
+       char freq[10];
+
+       double uptime;
+
+       /* memory information in kilobytes */
+       unsigned int mem, memmax, swap, swapmax;
+       unsigned int bufmem, buffers, cached;
+
+       unsigned int procs;
+       unsigned int run_procs;
+
+       float cpu_usage;
+       struct cpu_stat cpu_summed;
+       unsigned int cpu_count;
+       unsigned int cpu_avg_samples;
+
+       unsigned int net_avg_samples;
+
+       float loadavg[3];
+
+       int new_mail_count, mail_count;
+#ifdef SETI
+       float seti_prog;
+       float seti_credit;
+#endif
+#ifdef MPD
+       struct mpd_s mpd;
+       mpd_Connection *conn;
+#endif
+       struct process *cpu[10];
+       struct process *memu[10];
+       unsigned long looped;
+};
+
+int out_to_console;
+
+int top_cpu;
+int top_mem;
+
+int use_spacer;
+
+char *tmpstring1;
+char *tmpstring2;
+
+#ifdef X11
+/* in x11.c */
+
+#include <X11/Xlib.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
+#ifdef XFT
+#include <X11/Xft/Xft.h>
+#endif
+
+#if defined(HAVE_XDBE) && defined(DOUBLE_BUFFER)
+#define XDBE
+#include <X11/extensions/Xdbe.h>
+#endif
+
+#define ATOM(a) XInternAtom(display, #a, False)
+
+struct conky_window {
+       Window window;
+       Drawable drawable;
+       GC gc;
+#ifdef XDBE
+       XdbeBackBuffer back_buffer;
+#endif
+#ifdef XFT
+       XftDraw *xftdraw;
+#endif
+
+       int width;
+       int height;
+#ifdef OWN_WINDOW
+       int x;
+       int y;
+#endif
+};
+
+#ifdef XDBE
+extern int use_xdbe;
+#endif
+
+
+#ifdef XFT
+extern int use_xft;
+#endif
+
+extern Display *display;
+extern int display_width;
+extern int display_height;
+extern int screen;
+
+extern int workarea[4];
+
+extern struct conky_window window;
+
+void init_X11();
+#if defined OWN_WINDOW
+void init_window(int use_own_window, int width, int height, int on_bottom, int fixed_pos);
+#else
+void init_window(int use_own_window, int width, int height, int on_bottom);
+#endif
+void create_gc();
+void set_transparent_background(Window win);
+long get_x11_color(const char *);
+
+#endif /* X11 */
+
+/* in common.c */
+
+/* struct that has all info */
+struct information info;
+
+void update_uname();
+double get_time(void);
+FILE *open_file(const char *file, int *reported);
+void variable_substitute(const char *s, char *dest, unsigned int n);
+void format_seconds(char *buf, unsigned int n, long t);
+void format_seconds_short(char *buf, unsigned int n, long t);
+struct net_stat *get_net_stat(const char *dev);
+
+void update_stuff();
+
+#define SET_NEED(a) need_mask |= 1 << (a)
+extern unsigned long long need_mask;
+
+extern double current_update_time, last_update_time;
+
+extern int no_buffers;
+
+/* system dependant (in linux.c) */
+
+void prepare_update(void);
+void update_uptime(void);
+void update_meminfo(void);
+void update_net_stats(void);
+void update_wifi_stats(void);
+void update_cpu_usage(void);
+void update_total_processes(void);
+void update_running_processes(void);
+char *get_freq();
+void update_load_average();
+int open_i2c_sensor(const char *dev, const char *type, int n, int *div,
+                   char *devtype);
+double get_i2c_info(int *fd, int arg, char *devtype, char *type);
+
+char *get_adt746x_cpu(void);
+char *get_adt746x_fan(void);
+
+int open_acpi_temperature(const char *name);
+double get_acpi_temperature(int fd);
+char *get_acpi_ac_adapter(void);
+char *get_acpi_fan(void);
+void get_battery_stuff(char *buf, unsigned int n, const char *bat);
+
+struct process {
+       struct process *next;
+       struct process *previous;
+
+       pid_t pid;
+       char *name;
+       float amount;
+       unsigned int user_time;
+       unsigned int total;
+       unsigned int kernel_time;
+       unsigned int previous_user_time;
+       unsigned int previous_kernel_time;
+       unsigned int vsize;
+       unsigned int rss;
+       unsigned int time_stamp;
+       unsigned int counted;
+       unsigned int changed;
+       float totalmem;
+};
+
+void update_top();
+
+/* fs-stuff is possibly system dependant (in fs.c) */
+
+void update_fs_stats(void);
+struct fs_stat *prepare_fs_stat(const char *path);
+void clear_fs_stats(void);
+
+/* in mixer.c */
+
+int mixer_init(const char *);
+int mixer_get_avg(int);
+int mixer_get_left(int);
+int mixer_get_right(int);
+
+/* in mail.c */
+
+extern char *current_mail_spool;
+
+void update_mail_count();
+
+/* in seti.c */
+
+#ifdef SETI
+extern char *seti_dir;
+
+void update_seti();
+#endif
+
+/* in mpd.c */
+
+#ifdef MPD
+void update_mpd();
+#endif
+
+#ifdef MLDONKEY
+/* in mldonkey.c */
+typedef long long int64;
+/* The info necessary to connect to mldonkey. login and password can be NULL. */
+typedef struct mldonkey_config {
+       char *mldonkey_hostname;
+       int mldonkey_port;
+       char *mldonkey_login;
+       char *mldonkey_password;
+} mldonkey_config;
+
+/* The MLDonkey status returned */
+typedef struct mldonkey_info {
+       int64 upload_counter;
+       int64 download_counter;
+       int nshared_files;
+       int64 shared_counter;
+       int tcp_upload_rate;
+       int tcp_download_rate;
+       int udp_upload_rate;
+       int udp_download_rate;
+       int ndownloaded_files;
+       int ndownloading_files;
+       int nconnected_networks;
+       int connected_networks[1];
+} mldonkey_info;
+
+extern mldonkey_info mlinfo;
+extern mldonkey_config mlconfig;
+
+int get_mldonkey_status(mldonkey_config * config, mldonkey_info * info);
+#endif
+
+/* in linux.c */
+
+/* nothing to see here */
+
+/* in cairo.c */
+
+extern int do_it(void);
+
+#endif
diff --git a/src/freebsd.c b/src/freebsd.c
new file mode 100644 (file)
index 0000000..90e809d
--- /dev/null
@@ -0,0 +1,451 @@
+#include "conky.h"
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <kvm.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/sysctl.h>
+#include <sys/vmmeter.h>
+#include <sys/dkstat.h>
+#include <unistd.h>
+#include <sys/user.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/if_mib.h>
+#include <sys/socket.h>
+#include <ifaddrs.h>
+
+#define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var))
+#define KELVTOC(x)      ((x - 2732) / 10.0)
+
+#if defined(i386) || defined(__i386__)
+static unsigned int get_timer();
+static unsigned int get_cpu_speed(void);
+static inline unsigned long long int rdtsc(void);
+
+/* cpu frequency detection code based on mplayer's one */
+
+static unsigned int get_timer()
+{
+       struct timeval tv;
+       struct timezone tz;
+       gettimeofday(&tv, &tz);
+
+       return (tv.tv_sec * 1000000 + tv.tv_usec);
+}
+
+static inline unsigned long long int rdtsc(void)
+{
+       unsigned long long int retval;
+       __asm __volatile("rdtsc":"=A"(retval)::"memory");
+       return retval;
+}
+
+static unsigned int get_cpu_speed(void)
+{
+       unsigned long long int tscstart, tscstop;
+       unsigned int start, stop;
+
+       tscstart = rdtsc();
+       start = get_timer();
+       usleep(50000);
+       stop = get_timer();
+       tscstop = rdtsc();
+
+       return ((tscstop - tscstart) / ((stop - start) / 1000.0));
+}
+#endif
+
+
+static int getsysctl(char *name, void *ptr, size_t len)
+{
+       size_t nlen = len;
+       if (sysctlbyname(name, ptr, &nlen, NULL, 0) == -1) {
+               return -1;
+       }
+
+       if (nlen != len) {
+               return -1;
+       }
+
+       return 0;
+}
+
+static kvm_t *kd = NULL;
+struct ifmibdata *data = NULL;
+size_t len = 0;
+
+
+static int swapmode(int *retavail, int *retfree)
+{
+       int n;
+       int pagesize = getpagesize();
+       struct kvm_swap swapary[1];
+       static int kd_init = 1;
+
+       if (kd_init) {
+               kd_init = 0;
+               if ((kd = kvm_open("/dev/null", "/dev/null", "/dev/null",
+                                  O_RDONLY, "kvm_open")) == NULL) {
+                       (void) fprintf(stderr, "Cannot read kvm.");
+                       return -1;
+               }
+       }
+
+       if (kd == NULL) {
+               return -1;
+       }
+
+       *retavail = 0;
+       *retfree = 0;
+
+#define CONVERT(v)      ((quad_t)(v) * pagesize / 1024)
+
+       n = kvm_getswapinfo(kd, swapary, 1, 0);
+       if (n < 0 || swapary[0].ksw_total == 0)
+               return (0);
+
+       *retavail = CONVERT(swapary[0].ksw_total);
+       *retfree = CONVERT(swapary[0].ksw_total - swapary[0].ksw_used);
+
+       n = (int) ((double) swapary[0].ksw_used * 100.0 /
+                  (double) swapary[0].ksw_total);
+
+       return n;
+}
+
+
+void prepare_update()
+{
+}
+
+/*double get_uptime() */
+void update_uptime()
+{
+       int mib[2] = { CTL_KERN, KERN_BOOTTIME };
+       struct timeval boottime;
+       time_t now;
+       size_t size = sizeof(boottime);
+
+       if ((sysctl(mib, 2, &boottime, &size, NULL, 0) != -1)
+           && (boottime.tv_sec != 0)) {
+               time(&now);
+               info.uptime = now - boottime.tv_sec;
+       } else {
+               (void) fprintf(stderr, "Could not get uptime\n");
+               info.uptime = 0;
+       }
+}
+
+
+void update_meminfo()
+{
+       int total_pages, inactive_pages, free_pages;
+       int swap_avail, swap_free;
+
+       int pagesize = getpagesize();
+
+       if (GETSYSCTL("vm.stats.vm.v_page_count", total_pages))
+               (void) fprintf(stderr,
+                              "Cannot read sysctl \"vm.stats.vm.v_page_count\"");
+
+       if (GETSYSCTL("vm.stats.vm.v_free_count", free_pages))
+               (void) fprintf(stderr,
+                              "Cannot read sysctl \"vm.stats.vm.v_free_count\"");
+
+       if (GETSYSCTL("vm.stats.vm.v_inactive_count", inactive_pages))
+               (void) fprintf(stderr,
+                              "Cannot read sysctl \"vm.stats.vm.v_inactive_count\"");
+
+       info.memmax = (total_pages * pagesize) >> 10;
+       info.mem =
+           ((total_pages - free_pages - inactive_pages) * pagesize) >> 10;
+
+
+       if ((swapmode(&swap_avail, &swap_free)) >= 0) {
+               info.swapmax = swap_avail;
+               info.swap = (swap_avail - swap_free);
+       } else {
+               info.swapmax = 0;
+               info.swap = 0;
+       }
+}
+
+void update_net_stats()
+{
+       struct net_stat *ns;
+       double delta;
+       long long r, t, last_recv, last_trans;
+       struct ifaddrs *ifap, *ifa;
+       struct if_data *ifd;
+
+
+       /* get delta */
+       delta = current_update_time - last_update_time;
+       if (delta <= 0.0001)
+               return;
+
+       if (getifaddrs(&ifap) < 0)
+               return;
+
+       for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+               ns = get_net_stat((const char *) ifa->ifa_name);
+
+               if (ifa->ifa_flags & IFF_UP) {
+                       last_recv = ns->recv;
+                       last_trans = ns->trans;
+
+                       if (ifa->ifa_addr->sa_family != AF_LINK)
+                               continue;
+
+                       ifd = (struct if_data *) ifa->ifa_data;
+                       r = ifd->ifi_ibytes;
+                       t = ifd->ifi_obytes;
+
+                       if (r < ns->last_read_recv)
+                               ns->recv +=
+                                   ((long long) 4294967295U -
+                                    ns->last_read_recv) + r;
+                       else
+                               ns->recv += (r - ns->last_read_recv);
+
+                       ns->last_read_recv = r;
+
+                       if (t < ns->last_read_trans)
+                               ns->trans +=
+                                   ((long long) 4294967295U -
+                                    ns->last_read_trans) + t;
+                       else
+                               ns->trans += (t - ns->last_read_trans);
+
+                       ns->last_read_trans = t;
+
+
+                       /* calculate speeds */
+                       ns->recv_speed = (ns->recv - last_recv) / delta;
+                       ns->trans_speed = (ns->trans - last_trans) / delta;
+               }
+       }
+
+       freeifaddrs(ifap);
+}
+
+void update_total_processes()
+{
+       /* It's easier to use kvm here than sysctl */
+
+       int n_processes;
+       static int kd_init = 1;
+
+       if (kd_init) {
+               kd_init = 0;
+               if ((kd = kvm_open("/dev/null", "/dev/null", "/dev/null",
+                                  O_RDONLY, "kvm_open")) == NULL) {
+                       (void) fprintf(stderr, "Cannot read kvm.");
+                       return;
+               }
+       }
+
+
+       if (kd != NULL)
+               kvm_getprocs(kd, KERN_PROC_ALL, 0, &n_processes);
+       else
+               return;
+
+       info.procs = n_processes;
+}
+
+void update_running_processes()
+{
+       static int kd_init = 1;
+       struct kinfo_proc *p;
+       int n_processes;
+       int i, cnt = 0;
+
+       if (kd_init) {
+               kd_init = 0;
+               if ((kd =
+                    kvm_open("/dev/null", "/dev/null", "/dev/null",
+                             O_RDONLY, "kvm_open")) == NULL) {
+                       (void) fprintf(stderr, "Cannot read kvm.");
+               }
+       }
+
+       if (kd != NULL) {
+               p = kvm_getprocs(kd, KERN_PROC_ALL, 0, &n_processes);
+               for (i = 0; i < n_processes; i++) {
+#if __FreeBSD__ < 5
+                       if (p[i].kp_proc.p_stat == SRUN)
+#else
+                       if (p[i].ki_stat == SRUN)
+#endif
+                               cnt++;
+               }
+       } else
+               return;
+
+       info.run_procs = cnt;
+}
+
+struct cpu_load_struct {
+       unsigned long load[5];
+};
+
+struct cpu_load_struct fresh = { {0, 0, 0, 0, 0} };
+long cpu_used, oldtotal, oldused;
+
+void update_cpu_usage()
+{
+       long used, total;
+       long cp_time[CPUSTATES];
+       size_t len = sizeof(cp_time);
+
+       if (sysctlbyname("kern.cp_time", &cp_time, &len, NULL, 0) < 0) {
+               (void) fprintf(stderr, "Cannot get kern.cp_time");
+       }
+
+       fresh.load[0] = cp_time[CP_USER];
+       fresh.load[1] = cp_time[CP_NICE];
+       fresh.load[2] = cp_time[CP_SYS];
+       fresh.load[3] = cp_time[CP_IDLE];
+       fresh.load[4] = cp_time[CP_IDLE];
+
+       used = fresh.load[0] + fresh.load[1] + fresh.load[2];
+       total =
+           fresh.load[0] + fresh.load[1] + fresh.load[2] + fresh.load[3];
+
+       if ((total - oldtotal) != 0) {
+               info.cpu_usage =
+                   ((double) (used - oldused)) / (double) (total -
+                                                           oldtotal);
+       } else {
+               info.cpu_usage = 0;
+       }
+
+       oldused = used;
+       oldtotal = total;
+}
+
+double get_i2c_info(int *fd, int div, char *devtype)
+{
+       return 0;
+}
+
+void update_load_average()
+{
+       double v[3];
+       getloadavg(v, 3);
+
+       info.loadavg[0] = (float) v[0];
+       info.loadavg[1] = (float) v[1];
+       info.loadavg[2] = (float) v[2];
+}
+
+double get_acpi_temperature(int fd)
+{
+       int temp;
+
+       if (GETSYSCTL("hw.acpi.thermal.tz0.temperature", temp)) {
+               (void) fprintf(stderr,
+                              "Cannot read sysctl \"hw.acpi.thermal.tz0.temperature\"\n");
+               return 0.0;
+       }
+
+       return KELVTOC(temp);
+}
+
+void get_battery_stuff(char *buf, unsigned int n, const char *bat)
+{
+       int battime;
+
+       if (GETSYSCTL("hw.acpi.battery.time", battime))
+               (void) fprintf(stderr,
+                              "Cannot read sysctl \"hw.acpi.battery.time\"\n");
+
+       if (battime != -1)
+               snprintf(buf, n, "Discharging, remaining %d:%2.2d",
+                        battime / 60, battime % 60);
+       else
+               snprintf(buf, n, "Battery is charging");
+}
+
+int
+open_i2c_sensor(const char *dev, const char *type, int n, int *div,
+               char *devtype)
+{
+       return 0;
+}
+
+int open_acpi_temperature(const char *name)
+{
+       return 0;
+}
+
+char *get_acpi_ac_adapter(void)
+{
+       int state;
+       char *acstate = (char *) malloc(100);
+
+       if (GETSYSCTL("hw.acpi.acline", state)) {
+               (void) fprintf(stderr,
+                              "Cannot read sysctl \"hw.acpi.acline\"\n");
+               return "n\\a";
+       }
+
+
+       if (state)
+               strcpy(acstate, "Running on AC Power");
+       else
+               strcpy(acstate, "Running on battery");
+
+       return acstate;
+}
+
+char *get_acpi_fan()
+{
+       return "";
+}
+
+char *get_adt746x_cpu()
+{
+       return "";
+}
+
+char *get_adt746x_fan()
+{
+       return "";
+}
+
+char *get_freq()
+{
+#if defined(i386) || defined(__i386__)
+       int i;
+       char *cpuspeed;
+
+       if ((cpuspeed = (char *) malloc(16)) == NULL) {
+               CRIT_ERR("get_freq()");
+       }
+
+       i = 0;
+       if ((i = get_cpu_speed()) > 0) {
+               if (i < 1000000) {
+                       i += 50;        /* for rounding */
+                       snprintf(cpuspeed, 15, "%d.%d MHz", i / 1000,
+                                (i / 100) % 10);
+               } else {
+                       snprintf(cpuspeed, 15, "%d MHz", i / 1000);
+               }
+       } else {
+               cpuspeed = "";
+       }
+
+       return cpuspeed;
+#else
+       return "";
+#endif
+}
diff --git a/src/fs.c b/src/fs.c
new file mode 100644 (file)
index 0000000..9c019e8
--- /dev/null
+++ b/src/fs.c
@@ -0,0 +1,108 @@
+/*
+ * Conky, a system monitor, based on torsmo
+ *
+ * This program is licensed under BSD license, read COPYING
+ *
+ *  $Id$
+ */
+
+#include "conky.h"
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+/* linux */
+#ifdef HAVE_SYS_STATFS_H
+#include <sys/statfs.h>
+#endif
+
+/* freebsd && netbsd */
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
+
+/* TODO: benchmark which is faster, fstatvfs() or pre-opened fd and
+ * statvfs() (fstatvfs() would handle mounts I think...) */
+
+static struct fs_stat fs_stats_[64];
+struct fs_stat *fs_stats = fs_stats_;
+
+void update_fs_stats()
+{
+       unsigned int i;
+       struct statfs s;
+       for (i = 0; i < 16; i++) {
+               if (fs_stats[i].fd <= 0)
+                       break;
+
+               fstatfs(fs_stats[i].fd, &s);
+
+               fs_stats[i].size = (long long) s.f_blocks * s.f_bsize;
+               /* bfree (root) or bavail (non-roots) ? */
+               fs_stats[i].avail = (long long) s.f_bavail * s.f_bsize;
+       }
+}
+
+void clear_fs_stats()
+{
+       unsigned int i;
+       for (i = 0; i < 16; i++) {
+               if (fs_stats[i].fd) {
+                       close(fs_stats[i].fd);
+                       fs_stats[i].fd = -1;
+               }
+
+               if (fs_stats[i].path != NULL) {
+                       free(fs_stats[i].path);
+                       fs_stats[i].path = NULL;
+               }
+       }
+}
+
+struct fs_stat *prepare_fs_stat(const char *s)
+{
+       unsigned int i;
+
+       for (i = 0; i < 16; i++) {
+               struct fs_stat *fs = &fs_stats[i];
+
+               if (fs->path && strcmp(fs->path, s) == 0)
+                       return fs;
+
+               if (fs->fd <= 0) {
+                       /* when compiled with icc, it crashes when leaving function and open()
+                        * is used, I don't know why */
+
+                       /* this icc workaround didn't seem to work */
+#if 0
+                       {
+                               FILE *fp = fopen(s, "r");
+                               if (fp)
+                                       fs->fd = fileno(fp);
+                               else
+                                       fs->fd = -1;
+                       }
+#endif
+
+                       fs->fd = open(s, O_RDONLY);
+
+                       if (fs->fd <= 0) {      /* 0 isn't error but actually it is :) */
+                               ERR("open '%s': %s", s, strerror(errno));
+                               return 0;
+                       }
+
+                       fs->path = strdup(s);
+                       update_fs_stats();
+                       return fs;
+               }
+       }
+
+       ERR("too many fs stats");
+       return 0;
+}
diff --git a/src/ftp.c b/src/ftp.c
new file mode 100644 (file)
index 0000000..490fd20
--- /dev/null
+++ b/src/ftp.c
@@ -0,0 +1,936 @@
+/*
+ * ftp.c: basic handling of an FTP command connection to check for
+ *        directory availability. No transfer is needed.
+ *
+ *  Reference: RFC 959
+ *
+ *  $Id$
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <string.h>
+
+#include "ftp.h"
+
+/* #define DEBUG_FTP 1  */
+#ifdef STANDALONE
+#define DEBUG_FTP 1
+#endif
+
+static int ftpFd = -1;
+static struct sockaddr_in ftpAddr;
+static char hostname[100];
+static int ftpPassive = 1;
+static int dataFd = -1;
+
+#define FTP_COMMAND_OK          200
+#define FTP_SYNTAX_ERROR        500
+#define FTP_GET_PASSWD          331
+
+/*
+ * Initialize the FTP handling.
+ */
+
+void initFtp(void)
+{
+       gethostname(hostname, sizeof(hostname));
+}
+
+/*
+ * Parsing of the server answer, we just extract the code.
+ * return 0 for errors
+ *     +XXX for last line of response
+ *     -XXX for response to be continued
+ */
+int parseFtpResponse(char *buf, int len)
+{
+       int val = 0;
+
+       if (len < 3)
+               return (-1);
+       if ((*buf >= '0') && (*buf <= '9'))
+               val = val * 10 + (*buf - '0');
+       else
+               return (0);
+       buf++;
+       if ((*buf >= '0') && (*buf <= '9'))
+               val = val * 10 + (*buf - '0');
+       else
+               return (0);
+       buf++;
+       if ((*buf >= '0') && (*buf <= '9'))
+               val = val * 10 + (*buf - '0');
+       else
+               return (0);
+       buf++;
+       if (*buf == '-')
+               return (-val);
+       return (val);
+}
+
+/*
+ * Read the response from the FTP server after a command.
+ * Returns the code number
+ *
+ */
+int readFtpResponse(char *buf, int size)
+{
+       char *ptr, *end;
+       int len;
+       int res = -1;
+
+       if (size <= 0)
+               return (-1);
+
+      get_more:
+       if ((len = recv(ftpFd, buf, size - 1, 0)) < 0) {
+               close(ftpFd);
+               ftpFd = -1;
+               ftpFd = -1;
+               return (-1);
+       }
+       if (len == 0) {
+               return (-1);
+       }
+
+       end = &buf[len];
+       *end = 0;
+#ifdef DEBUG_FTP
+       printf(buf);
+#endif
+       ptr = buf;
+       while (ptr < end) {
+               res = parseFtpResponse(ptr, end - ptr);
+               if (res > 0)
+                       break;
+               if (res == 0) {
+#ifdef DEBUG_FTP
+                       fprintf(stderr, "readFtpResponse failed: %s\n",
+                               ptr);
+#endif
+                       return (-1);
+               }
+               while ((ptr < end) && (*ptr != '\n'))
+                       ptr++;
+               if (ptr >= end) {
+#ifdef DEBUG_FTP
+                       fprintf(stderr,
+                               "readFtpResponse: unexpected end %s\n",
+                               buf);
+#endif
+                       return ((-res) / 100);
+               }
+               if (*ptr != '\r')
+                       ptr++;
+       }
+
+       if (res < 0)
+               goto get_more;
+
+#ifdef DEBUG_FTP
+       printf("Got %d\n", res);
+#endif
+       return (res / 100);
+}
+
+/*
+ * Get the response from the FTP server after a command.
+ * Returns the code number
+ *
+ */
+int getFtpResponse(void)
+{
+       char buf[16 * 1024 + 1];
+
+/**************
+    fd_set rfd;
+    struct timeval tv;
+    int res;
+
+    tv.tv_sec = 10;
+    tv.tv_usec = 0;
+    FD_ZERO(&rfd);
+    FD_SET(ftpFd, &rfd);
+    res = select(ftpFd + 1, &rfd, NULL, NULL, &tv);
+    if (res <= 0) return(res);
+ **************/
+
+       return (readFtpResponse(buf, 16 * 1024));
+}
+
+/*
+ * Check if there is a response from the FTP server after a command.
+ * Returns the code number, or 0
+ */
+int checkFtpResponse(void)
+{
+       char buf[1024 + 1];
+       fd_set rfd;
+       struct timeval tv;
+
+       tv.tv_sec = 0;
+       tv.tv_usec = 0;
+       FD_ZERO(&rfd);
+       FD_SET(ftpFd, &rfd);
+       switch (select(ftpFd + 1, &rfd, NULL, NULL, &tv)) {
+       case 0:
+               return (0);
+       case -1:
+#ifdef DEBUG_FTP
+               perror("select");
+#endif
+               return (-1);
+
+       }
+
+       return (readFtpResponse(buf, 1024));
+}
+
+/*
+ * Send the user authentification
+ */
+
+int sendUser(void)
+{
+       char buf[200];
+       int len;
+       int res;
+
+       len = snprintf(buf, sizeof(buf), "USER anonymous\r\n");
+#ifdef DEBUG_FTP
+       printf(buf);
+#endif
+       res = send(ftpFd, buf, len, 0);
+       if (res < 0)
+               return (res);
+       return (0);
+}
+
+/*
+ * Send the password authentification
+ */
+
+int sendPasswd(void)
+{
+       char buf[200];
+       int len;
+       int res;
+
+       len =
+           snprintf(buf, sizeof(buf), "PASS mirrorfind@%s\r\n", hostname);
+#ifdef DEBUG_FTP
+       printf(buf);
+#endif
+       res = send(ftpFd, buf, len, 0);
+       if (res < 0)
+               return (res);
+       return (0);
+}
+
+/*
+ * Send a QUIT
+ */
+
+int sendQuit(void)
+{
+       char buf[200];
+       int len;
+       int res;
+
+       len = snprintf(buf, sizeof(buf), "QUIT\r\n");
+#ifdef DEBUG_FTP
+       printf(buf);
+#endif
+       res = send(ftpFd, buf, len, 0);
+       return (0);
+}
+
+/*
+ * Connecting to the server, port 21 by default.
+ */
+
+int connectFtp(const char *server, int port)
+{
+       struct hostent *hp;
+       int res;
+
+       /*
+        * do the blocking DNS query.
+        */
+       hp = gethostbyname(server);
+       if (hp == NULL)
+               return (-1);
+
+       /*
+        * Prepare the socket
+        */
+       memset(&ftpAddr, 0, sizeof(ftpAddr));
+       ftpAddr.sin_family = AF_INET;
+       memcpy(&ftpAddr.sin_addr, hp->h_addr_list[0], hp->h_length);
+       if (port == 0)
+               port = 21;
+       ftpAddr.sin_port = htons(port);
+       ftpFd = socket(AF_INET, SOCK_STREAM, 0);
+       if (ftpFd < 0)
+               return (-1);
+
+       /*
+        * Do the connect.
+        */
+       if (connect(ftpFd, (struct sockaddr *) &ftpAddr,
+                   sizeof(struct sockaddr_in)) < 0) {
+               close(ftpFd);
+               ftpFd = -1;
+               ftpFd = -1;
+               return (-1);
+       }
+
+       /*
+        * Wait for the HELLO from the server.
+        */
+       res = getFtpResponse();
+       if (res != 2) {
+               close(ftpFd);
+               ftpFd = -1;
+               ftpFd = -1;
+               return (-1);
+       }
+
+       /*
+        * State diagram for the login operation on the FTP server
+        *
+        * Reference: RFC 959
+        *
+        *                       1
+        * +---+   USER    +---+------------->+---+
+        * | B |---------->| W | 2       ---->| E |
+        * +---+           +---+------  |  -->+---+
+        *                  | |       | | |
+        *                3 | | 4,5   | | |
+        *    --------------   -----  | | |
+        *   |                      | | | |
+        *   |                      | | | |
+        *   |                 ---------  |
+        *   |               1|     | |   |
+        *   V                |     | |   |
+        * +---+   PASS    +---+ 2  |  ------>+---+
+        * |   |---------->| W |------------->| S |
+        * +---+           +---+   ---------->+---+
+        *                  | |   | |     |
+        *                3 | |4,5| |     |
+        *    --------------   --------   |
+        *   |                    | |  |  |
+        *   |                    | |  |  |
+        *   |                 -----------
+        *   |             1,3|   | |  |
+        *   V                |  2| |  |
+        * +---+   ACCT    +---+--  |   ----->+---+
+        * |   |---------->| W | 4,5 -------->| F |
+        * +---+           +---+------------->+---+
+        */
+       res = sendUser();
+       if (res < 0) {
+               close(ftpFd);
+               ftpFd = -1;
+               ftpFd = -1;
+               return (-1);
+       }
+       res = getFtpResponse();
+       switch (res) {
+       case 2:
+               return (0);
+       case 3:
+               break;
+       case 1:
+       case 4:
+       case 5:
+       case -1:
+       default:
+               close(ftpFd);
+               ftpFd = -1;
+               ftpFd = -1;
+               return (-1);
+       }
+       res = sendPasswd();
+       if (res < 0) {
+               close(ftpFd);
+               ftpFd = -1;
+               ftpFd = -1;
+               return (-1);
+       }
+       res = getFtpResponse();
+       switch (res) {
+       case 2:
+               return (0);
+       case 3:
+               fprintf(stderr,
+                       "FTP server asking for ACCNT on anonymous\n");
+       case 1:
+       case 4:
+       case 5:
+       case -1:
+       default:
+               close(ftpFd);
+               ftpFd = -1;
+               ftpFd = -1;
+               return (-1);
+       }
+
+       return (0);
+}
+
+/*
+ * Check an FTP directory on the server
+ */
+
+int changeFtpDirectory(char *directory)
+{
+       char buf[400];
+       int len;
+       int res;
+
+       /*
+        * Expected response code for CWD:
+        *
+        * CWD
+        *     250
+        *     500, 501, 502, 421, 530, 550
+        */
+       len = snprintf(buf, sizeof(buf), "CWD %s\r\n", directory);
+#ifdef DEBUG_FTP
+       printf(buf);
+#endif
+       res = send(ftpFd, buf, len, 0);
+       if (res < 0)
+               return (res);
+       res = getFtpResponse();
+       if (res == 4) {
+               close(ftpFd);
+               ftpFd = -1;
+               ftpFd = -1;
+               return (-1);
+       }
+       if (res == 2)
+               return (1);
+       if (res == 5) {
+               return (0);
+       }
+       return (0);
+}
+
+/*
+ * dataConnectFtp
+ */
+int dataConnectFtp()
+{
+       char buf[200];
+       int len, i;
+       int res;
+       unsigned char ad[6], *cur, *adp, *portp;
+       unsigned int temp[6];
+       struct sockaddr_in dataAddr;
+       socklen_t dataAddrLen;
+
+       dataFd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+       if (dataFd < 0) {
+               fprintf(stderr,
+                       "dataConnectFtp: failed to create socket\n");
+       }
+       dataAddrLen = sizeof(dataAddr);
+       memset(&dataAddr, 0, dataAddrLen);
+       dataAddr.sin_family = AF_INET;
+
+       if (ftpPassive) {
+               len = snprintf(buf, sizeof(buf), "PASV\r\n");
+#ifdef DEBUG_FTP
+               printf(buf);
+#endif
+               res = send(ftpFd, buf, len, 0);
+               if (res < 0) {
+                       close(dataFd);
+                       dataFd = -1;
+                       return (res);
+               }
+               res = readFtpResponse(buf, sizeof(buf) - 1);
+               if (res != 2) {
+                       if (res == 5) {
+                               close(dataFd);
+                               dataFd = -1;
+                               return (-1);
+                       } else {
+                               /*
+                                * retry with an active connection
+                                */
+                               close(dataFd);
+                               dataFd = -1;
+                               ftpPassive = 0;
+                       }
+               }
+               cur = &buf[4];
+               while (((*cur < '0') || (*cur > '9')) && *cur != '\0')
+                       cur++;
+               if (sscanf
+                   (cur, "%d,%d,%d,%d,%d,%d", &temp[0], &temp[1],
+                    &temp[2], &temp[3], &temp[4], &temp[5]) != 6) {
+                       fprintf(stderr, "Invalid answer to PASV\n");
+                       close(dataFd);
+                       dataFd = -1;
+                       return (-1);
+               }
+               for (i = 0; i < 6; i++)
+                       ad[i] = (unsigned char) (temp[i] & 0xff);
+               memcpy(&dataAddr.sin_addr, &ad[0], 4);
+               memcpy(&dataAddr.sin_port, &ad[4], 2);
+               if (connect
+                   (dataFd, (struct sockaddr *) &dataAddr,
+                    dataAddrLen) < 0) {
+                       fprintf(stderr,
+                               "Failed to create a data connection\n");
+                       close(dataFd);
+                       dataFd = -1;
+                       return (-1);
+               }
+       } else {
+               getsockname(dataFd, (struct sockaddr *) &dataAddr,
+                           &dataAddrLen);
+               dataAddr.sin_port = 0;
+               if (bind
+                   (dataFd, (struct sockaddr *) &dataAddr,
+                    dataAddrLen) < 0) {
+                       fprintf(stderr, "Failed to bind a port\n");
+                       close(dataFd);
+                       dataFd = -1;
+                       return (-1);
+               }
+               getsockname(dataFd, (struct sockaddr *) &dataAddr,
+                           &dataAddrLen);
+
+               if (listen(dataFd, 1) < 0) {
+                       fprintf(stderr, "Could not listen on port %d\n",
+                               ntohs(dataAddr.sin_port));
+                       close(dataFd);
+                       dataFd = -1;
+                       return (-1);
+               }
+               adp = (unsigned char *) &dataAddr.sin_addr;
+               portp = (unsigned char *) &dataAddr.sin_port;
+               len =
+                   snprintf(buf, sizeof(buf),
+                            "PORT %d,%d,%d,%d,%d,%d\r\n", adp[0] & 0xff,
+                            adp[1] & 0xff, adp[2] & 0xff, adp[3] & 0xff,
+                            portp[0] & 0xff, portp[1] & 0xff);
+               buf[sizeof(buf) - 1] = 0;
+#ifdef DEBUG_FTP
+               printf(buf);
+#endif
+
+               res = send(ftpFd, buf, len, 0);
+               if (res < 0) {
+                       close(dataFd);
+                       dataFd = -1;
+                       return (res);
+               }
+               res = getFtpResponse();
+               if (res != 2) {
+                       close(dataFd);
+                       dataFd = -1;
+                       return (-1);
+               }
+       }
+       return (dataFd);
+
+}
+
+/*
+ * dataConnectEndFtp
+ */
+int dataConnectEndFtp()
+{
+       int res;
+
+       close(dataFd);
+       dataFd = -1;
+       res = getFtpResponse();
+       if (res != 2) {
+               close(dataFd);
+               dataFd = -1;
+               close(ftpFd);
+               ftpFd = -1;
+               return (-1);
+       }
+       return (0);
+}
+
+/*
+ * parseListFtp
+ */
+
+int parseListFtp(const char *list, ftpListCallback callback,
+                void *userData)
+{
+       const char *cur = list;
+       char filename[151];
+       char attrib[11];
+       char owner[11];
+       char group[11];
+       char month[4];
+       int year = 0;
+       int minute = 0;
+       int hour = 0;
+       int day = 0;
+       unsigned long size = 0;
+       int links = 0;
+       int i;
+
+       if (!strncmp(cur, "total", 5)) {
+               cur += 5;
+               while (*cur == ' ')
+                       cur++;
+               while ((*cur >= '0') && (*cur <= '9'))
+                       links = (links * 10) + (*cur++ - '0');
+               while ((*cur == ' ') || (*cur == '\n') || (*cur == '\r'))
+                       cur++;
+               return (cur - list);
+       } else if (*list == '+') {
+               return (0);
+       } else {
+               while ((*cur == ' ') || (*cur == '\n') || (*cur == '\r'))
+                       cur++;
+               if (*cur == 0)
+                       return (0);
+               i = 0;
+               while (*cur != ' ') {
+                       if (i < 10)
+                               attrib[i++] = *cur;
+                       cur++;
+                       if (*cur == 0)
+                               return (0);
+               }
+               attrib[10] = 0;
+               while (*cur == ' ')
+                       cur++;
+               if (*cur == 0)
+                       return (0);
+               while ((*cur >= '0') && (*cur <= '9'))
+                       links = (links * 10) + (*cur++ - '0');
+               while (*cur == ' ')
+                       cur++;
+               if (*cur == 0)
+                       return (0);
+               i = 0;
+               while (*cur != ' ') {
+                       if (i < 10)
+                               owner[i++] = *cur;
+                       cur++;
+                       if (*cur == 0)
+                               return (0);
+               }
+               owner[i] = 0;
+               while (*cur == ' ')
+                       cur++;
+               if (*cur == 0)
+                       return (0);
+               i = 0;
+               while (*cur != ' ') {
+                       if (i < 10)
+                               group[i++] = *cur;
+                       cur++;
+                       if (*cur == 0)
+                               return (0);
+               }
+               group[i] = 0;
+               while (*cur == ' ')
+                       cur++;
+               if (*cur == 0)
+                       return (0);
+               while ((*cur >= '0') && (*cur <= '9'))
+                       size = (size * 10) + (*cur++ - '0');
+               while (*cur == ' ')
+                       cur++;
+               if (*cur == 0)
+                       return (0);
+               i = 0;
+               while (*cur != ' ') {
+                       if (i < 3)
+                               month[i++] = *cur;
+                       cur++;
+                       if (*cur == 0)
+                               return (0);
+               }
+               month[i] = 0;
+               while (*cur == ' ')
+                       cur++;
+               if (*cur == 0)
+                       return (0);
+               while ((*cur >= '0') && (*cur <= '9'))
+                       day = (day * 10) + (*cur++ - '0');
+               while (*cur == ' ')
+                       cur++;
+               if (*cur == 0)
+                       return (0);
+               if ((cur[1] == 0) || (cur[2] == 0))
+                       return (0);
+               if ((cur[1] == ':') || (cur[2] == ':')) {
+                       while ((*cur >= '0') && (*cur <= '9'))
+                               hour = (hour * 10) + (*cur++ - '0');
+                       if (*cur == ':')
+                               cur++;
+                       while ((*cur >= '0') && (*cur <= '9'))
+                               minute = (minute * 10) + (*cur++ - '0');
+               } else {
+                       while ((*cur >= '0') && (*cur <= '9'))
+                               year = (year * 10) + (*cur++ - '0');
+               }
+               while (*cur == ' ')
+                       cur++;
+               if (*cur == 0)
+                       return (0);
+               i = 0;
+               while ((*cur != '\n') && (*cur != '\r')) {
+                       if (i < 150)
+                               filename[i++] = *cur;
+                       cur++;
+                       if (*cur == 0)
+                               return (0);
+               }
+               filename[i] = 0;
+               if ((*cur != '\n') && (*cur != '\r'))
+                       return (0);
+               while ((*cur == '\n') || (*cur == '\r'))
+                       cur++;
+       }
+       if (callback != NULL) {
+               callback(userData, filename, attrib, owner, group, size,
+                        links, year, month, day, minute);
+       }
+       return (cur - list);
+}
+
+/*
+ * listFtp
+ */
+int listFtp(ftpListCallback callback, void *userData)
+{
+       char buf[4096 + 1];
+       int len, res;
+       int index = 0, base;
+       fd_set rfd, efd;
+       struct timeval tv;
+
+       dataFd = dataConnectFtp();
+
+       len = snprintf(buf, sizeof(buf), "LIST -L\r\n");
+#ifdef DEBUG_FTP
+       printf(buf);
+#endif
+       res = send(ftpFd, buf, len, 0);
+       if (res < 0) {
+               close(dataFd);
+               dataFd = -1;
+               return (res);
+       }
+       res = readFtpResponse(buf, sizeof(buf) - 1);
+       if (res != 1) {
+               close(dataFd);
+               dataFd = -1;
+               return (-res);
+       }
+
+       do {
+               tv.tv_sec = 1;
+               tv.tv_usec = 0;
+               FD_ZERO(&rfd);
+               FD_SET(dataFd, &rfd);
+               FD_ZERO(&efd);
+               FD_SET(dataFd, &efd);
+               res = select(dataFd + 1, &rfd, NULL, &efd, &tv);
+               if (res < 0) {
+#ifdef DEBUG_FTP
+                       perror("select");
+#endif
+                       close(dataFd);
+                       dataFd = -1;
+                       return (-1);
+               }
+               if (res == 0) {
+                       res = checkFtpResponse();
+                       if (res < 0) {
+                               close(dataFd);
+                               dataFd = -1;
+                               dataFd = -1;
+                               return (-1);
+                       }
+                       if (res == 2) {
+                               close(dataFd);
+                               dataFd = -1;
+                               return (0);
+                       }
+
+                       continue;
+               }
+
+               if ((len =
+                    read(dataFd, &buf[index],
+                         sizeof(buf) - (index + 1))) < 0) {
+#ifdef DEBUG_FTP
+                       perror("read");
+#endif
+                       close(dataFd);
+                       dataFd = -1;
+                       dataFd = -1;
+                       return (-1);
+               }
+#ifdef DEBUG_FTP
+               write(1, &buf[index], len);
+#endif
+               index += len;
+               buf[index] = 0;
+               base = 0;
+               do {
+                       res = parseListFtp(&buf[base], callback, userData);
+                       base += res;
+               } while (res > 0);
+
+               memmove(&buf[0], &buf[base], index - base);
+               index -= base;
+       } while (len != 0);
+       dataConnectEndFtp();
+       return (0);
+}
+
+/*
+ * getFtpSocket:
+ */
+
+int getFtpSocket(const char *filename)
+{
+       char buf[300];
+       int res, len;
+       if (filename == NULL)
+               return (-1);
+       dataFd = dataConnectFtp();
+
+       len = snprintf(buf, sizeof(buf), "TYPE I\r\n");
+#ifdef DEBUG_FTP
+       printf(buf);
+#endif
+       res = send(ftpFd, buf, len, 0);
+       if (res < 0) {
+               close(dataFd);
+               dataFd = -1;
+               return (res);
+       }
+       res = readFtpResponse(buf, sizeof(buf) - 1);
+       if (res != 2) {
+               close(dataFd);
+               dataFd = -1;
+               return (-res);
+       }
+       len = snprintf(buf, sizeof(buf), "RETR %s\r\n", filename);
+#ifdef DEBUG_FTP
+       printf(buf);
+#endif
+       res = send(ftpFd, buf, len, 0);
+       if (res < 0) {
+               close(dataFd);
+               dataFd = -1;
+               return (res);
+       }
+       res = readFtpResponse(buf, sizeof(buf) - 1);
+       if (res != 1) {
+               close(dataFd);
+               dataFd = -1;
+               return (-res);
+       }
+       return (dataFd);
+}
+
+/*
+ * closeFtpSocket
+ */
+
+int closeFtpSocket()
+{
+       return (dataConnectEndFtp());
+}
+
+/*
+ * listFtp
+ */
+int getFtp(ftpDataCallback callback, void *userData, const char *filename)
+{
+       char buf[4096];
+       int len = 0, res;
+       fd_set rfd;
+       struct timeval tv;
+
+       if (filename == NULL)
+               return (-1);
+       if (callback == NULL)
+               return (-1);
+       if (getFtpSocket(filename) < 0)
+               return (-1);
+
+       do {
+               tv.tv_sec = 1;
+               tv.tv_usec = 0;
+               FD_ZERO(&rfd);
+               FD_SET(dataFd, &rfd);
+               res = select(dataFd + 1, &rfd, NULL, NULL, &tv);
+               if (res < 0) {
+#ifdef DEBUG_FTP
+                       perror("select");
+#endif
+                       close(dataFd);
+                       dataFd = -1;
+                       return (-1);
+               }
+               if (res == 0) {
+                       res = checkFtpResponse();
+                       if (res < 0) {
+                               close(dataFd);
+                               dataFd = -1;
+                               dataFd = -1;
+                               return (-1);
+                       }
+                       if (res == 2) {
+                               close(dataFd);
+                               dataFd = -1;
+                               return (0);
+                       }
+
+                       continue;
+               }
+               if ((len = read(dataFd, &buf, sizeof(buf))) < 0) {
+                       callback(userData, buf, len);
+                       close(dataFd);
+                       dataFd = -1;
+                       ftpFd = -1;
+                       return (-1);
+               }
+               callback(userData, buf, len);
+       } while (len != 0);
+
+       return (closeFtpSocket());
+}
+
+/*
+ * Disconnect from the FTP server.
+ */
+
+int disconnectFtp(void)
+{
+       if (ftpFd < 0)
+               return (-1);
+       sendQuit();
+       close(ftpFd);
+       ftpFd = -1;
+       ftpFd = -1;
+       return (0);
+}
diff --git a/src/ftp.h b/src/ftp.h
new file mode 100644 (file)
index 0000000..b158eba
--- /dev/null
+++ b/src/ftp.h
@@ -0,0 +1,28 @@
+/*
+ * ftp.h: interface for basic handling of an FTP command connection
+ *        to check for directory availability. No transfer is needed.
+ *
+ *  Reference: RFC 959
+ *
+ *  $Id$
+ */
+
+#ifndef __MIRRORS_FTP_H__
+#define __MIRRORS_FTP_H__
+typedef void (*ftpListCallback) (void *userData,
+                                const char *filename, const char *attrib,
+                                const char *owner, const char *group,
+                                unsigned long size, int links, int year,
+                                const char *month, int day, int minute);
+
+typedef void (*ftpDataCallback) (void *userData,
+                                const char *data, int len);
+
+
+extern void initFtp(void);
+extern int connectFtp(const char *server, int port);
+extern int changeFtpDirectory(char *directory);
+extern int disconnectFtp(void);
+int getFtp(ftpDataCallback, void *, const char *);
+
+#endif                         /* __MIRRORS_FTP_H__ */
diff --git a/src/libmpdclient.c b/src/libmpdclient.c
new file mode 100644 (file)
index 0000000..d1b5604
--- /dev/null
@@ -0,0 +1,1517 @@
+/* libmpdclient
+   (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu)
+   This project's homepage is: http://www.musicpd.org
+  
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+                                                                                
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+                                                                                
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+                                                                                
+   - Neither the name of the Music Player Daemon nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+                                                                                
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#include "libmpdclient.h"
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <sys/param.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
+#ifndef MPD_NO_IPV6
+#ifdef AF_INET6
+#define MPD_HAVE_IPV6
+#endif
+#endif
+
+#define COMMAND_LIST   1
+#define COMMAND_LIST_OK        2
+
+#ifdef MPD_HAVE_IPV6
+int mpd_ipv6Supported()
+{
+       int s;
+       s = socket(AF_INET6, SOCK_STREAM, 0);
+       if (s == -1)
+               return 0;
+       close(s);
+       return 1;
+}
+#endif
+
+
+char *mpd_sanitizeArg(const char *arg)
+{
+       size_t i;
+       int count = 0;
+       char *ret;
+
+       for (i = 0; i < strlen(arg); i++) {
+               if (arg[i] == '"' || arg[i] == '\\')
+                       count++;
+       }
+
+       ret = malloc(strlen(arg) + count + 1);
+
+       count = 0;
+       for (i = 0; i < strlen(arg) + 1; i++) {
+               if (arg[i] == '"' || arg[i] == '\\') {
+                       ret[i + count] = '\\';
+                       count++;
+               }
+               ret[i + count] = arg[i];
+       }
+
+       return ret;
+}
+
+mpd_ReturnElement *mpd_newReturnElement(const char *name,
+                                       const char *value)
+{
+       mpd_ReturnElement *ret = malloc(sizeof(mpd_ReturnElement));
+
+       ret->name = strdup(name);
+       ret->value = strdup(value);
+
+       return ret;
+}
+
+void mpd_freeReturnElement(mpd_ReturnElement * re)
+{
+       free(re->name);
+       free(re->value);
+       free(re);
+}
+
+void mpd_setConnectionTimeout(mpd_Connection * connection, float timeout)
+{
+       connection->timeout.tv_sec = (int) timeout;
+       connection->timeout.tv_usec = (int) (timeout * 1e6 -
+                                            connection->timeout.tv_sec *
+                                            1000000 + 0.5);
+}
+
+mpd_Connection *mpd_newConnection(const char *host, int port,
+                                 float timeout)
+{
+       int err;
+       struct hostent *he;
+       struct sockaddr *dest;
+#ifdef HAVE_SOCKLEN_T
+       socklen_t destlen;
+#else
+       int destlen;
+#endif
+       struct sockaddr_in sin;
+       char *rt;
+       char *output;
+       mpd_Connection *connection = malloc(sizeof(mpd_Connection));
+       struct timeval tv;
+       fd_set fds;
+#ifdef MPD_HAVE_IPV6
+       struct sockaddr_in6 sin6;
+#endif
+       strcpy(connection->buffer, "");
+       connection->buflen = 0;
+       connection->bufstart = 0;
+       strcpy(connection->errorStr, "");
+       connection->error = 0;
+       connection->doneProcessing = 0;
+       connection->commandList = 0;
+       connection->listOks = 0;
+       connection->doneListOk = 0;
+       connection->returnElement = NULL;
+
+       if (!(he = gethostbyname(host))) {
+               snprintf(connection->errorStr, MPD_BUFFER_MAX_LENGTH,
+                        "host \"%s\" not found", host);
+               connection->error = MPD_ERROR_UNKHOST;
+               return connection;
+       }
+
+       memset(&sin, 0, sizeof(struct sockaddr_in));
+       /*dest.sin_family = he->h_addrtype; */
+       sin.sin_family = AF_INET;
+       sin.sin_port = htons(port);
+#ifdef MPD_HAVE_IPV6
+       memset(&sin6, 0, sizeof(struct sockaddr_in6));
+       sin6.sin6_family = AF_INET6;
+       sin6.sin6_port = htons(port);
+#endif
+       switch (he->h_addrtype) {
+       case AF_INET:
+               memcpy((char *) &sin.sin_addr.s_addr, (char *) he->h_addr,
+                      he->h_length);
+               dest = (struct sockaddr *) &sin;
+               destlen = sizeof(struct sockaddr_in);
+               break;
+#ifdef MPD_HAVE_IPV6
+       case AF_INET6:
+               if (!mpd_ipv6Supported()) {
+                       strcpy(connection->errorStr,
+                              "no IPv6 suuport but a "
+                              "IPv6 address found\n");
+                       connection->error = MPD_ERROR_SYSTEM;
+                       return connection;
+               }
+               memcpy((char *) &sin6.sin6_addr.s6_addr,
+                      (char *) he->h_addr, he->h_length);
+               dest = (struct sockaddr *) &sin6;
+               destlen = sizeof(struct sockaddr_in6);
+               break;
+#endif
+       default:
+               strcpy(connection->errorStr,
+                      "address type is not IPv4 or " "IPv6\n");
+               connection->error = MPD_ERROR_SYSTEM;
+               return connection;
+               break;
+       }
+
+       if ((connection->sock =
+            socket(dest->sa_family, SOCK_STREAM, 0)) < 0) {
+               strcpy(connection->errorStr, "problems creating socket");
+               connection->error = MPD_ERROR_SYSTEM;
+               return connection;
+       }
+
+       mpd_setConnectionTimeout(connection, timeout);
+
+       /* connect stuff */
+       {
+               int flags = fcntl(connection->sock, F_GETFL, 0);
+               fcntl(connection->sock, F_SETFL, flags | O_NONBLOCK);
+
+               if (connect(connection->sock, dest, destlen) < 0
+                   && errno != EINPROGRESS) {
+                       snprintf(connection->errorStr,
+                                MPD_BUFFER_MAX_LENGTH,
+                                "problems connecting to \"%s\" on port"
+                                " %i", host, port);
+                       connection->error = MPD_ERROR_CONNPORT;
+                       return connection;
+               }
+       }
+
+       while (!(rt = strstr(connection->buffer, "\n"))) {
+               tv.tv_sec = connection->timeout.tv_sec;
+               tv.tv_usec = connection->timeout.tv_usec;
+               FD_ZERO(&fds);
+               FD_SET(connection->sock, &fds);
+               if ((err =
+                    select(connection->sock + 1, &fds, NULL, NULL,
+                           &tv)) == 1) {
+                       int readed;
+                       readed = recv(connection->sock,
+                                     &(connection->
+                                       buffer[connection->buflen]),
+                                     MPD_BUFFER_MAX_LENGTH -
+                                     connection->buflen, 0);
+                       if (readed <= 0) {
+                               snprintf(connection->errorStr,
+                                        MPD_BUFFER_MAX_LENGTH,
+                                        "problems getting a response from"
+                                        " \"%s\" on port %i", host, port);
+                               connection->error = MPD_ERROR_NORESPONSE;
+                               return connection;
+                       }
+                       connection->buflen += readed;
+                       connection->buffer[connection->buflen] = '\0';
+                       tv.tv_sec = connection->timeout.tv_sec;
+                       tv.tv_usec = connection->timeout.tv_usec;
+               } else if (err < 0) {
+                       switch (errno) {
+                       case EINTR:
+                               continue;
+                       default:
+                               snprintf(connection->errorStr,
+                                        MPD_BUFFER_MAX_LENGTH,
+                                        "problems connecting to \"%s\" on port"
+                                        " %i", host, port);
+                               connection->error = MPD_ERROR_CONNPORT;
+                               return connection;
+                       }
+               } else {
+                       snprintf(connection->errorStr,
+                                MPD_BUFFER_MAX_LENGTH,
+                                "timeout in attempting to get a response from"
+                                " \"%s\" on port %i", host, port);
+                       connection->error = MPD_ERROR_NORESPONSE;
+                       return connection;
+               }
+       }
+
+       *rt = '\0';
+       output = strdup(connection->buffer);
+       strcpy(connection->buffer, rt + 1);
+       connection->buflen = strlen(connection->buffer);
+
+       if (strncmp
+           (output, MPD_WELCOME_MESSAGE, strlen(MPD_WELCOME_MESSAGE))) {
+               free(output);
+               snprintf(connection->errorStr, MPD_BUFFER_MAX_LENGTH,
+                        "mpd not running on port %i on host \"%s\"", port,
+                        host);
+               connection->error = MPD_ERROR_NOTMPD;
+               return connection;
+       }
+
+       {
+               char *test;
+               char *version[3];
+               char *tmp = &output[strlen(MPD_WELCOME_MESSAGE)];
+               char *search = ".";
+               int i;
+
+               for (i = 0; i < 3; i++) {
+                       char *tok;
+                       if (i == 3)
+                               search = " ";
+                       version[i] = strtok_r(tmp, search, &tok);
+                       if (!version[i]) {
+                               free(output);
+                               snprintf(connection->errorStr,
+                                        MPD_BUFFER_MAX_LENGTH,
+                                        "error parsing version number at "
+                                        "\"%s\"",
+                                        &output[strlen
+                                                (MPD_WELCOME_MESSAGE)]);
+                               connection->error = MPD_ERROR_NOTMPD;
+                               return connection;
+                       }
+                       connection->version[i] =
+                           strtol(version[i], &test, 10);
+                       if (version[i] == test || *test != '\0') {
+                               free(output);
+                               snprintf(connection->errorStr,
+                                        MPD_BUFFER_MAX_LENGTH,
+                                        "error parsing version number at "
+                                        "\"%s\"",
+                                        &output[strlen
+                                                (MPD_WELCOME_MESSAGE)]);
+                               connection->error = MPD_ERROR_NOTMPD;
+                               return connection;
+                       }
+                       tmp = NULL;
+               }
+       }
+
+       free(output);
+
+       connection->doneProcessing = 1;
+
+       return connection;
+}
+
+void mpd_clearError(mpd_Connection * connection)
+{
+       connection->error = 0;
+       connection->errorStr[0] = '\0';
+}
+
+void mpd_closeConnection(mpd_Connection * connection)
+{
+       close(connection->sock);
+       if (connection->returnElement)
+               free(connection->returnElement);
+       free(connection);
+}
+
+void mpd_executeCommand(mpd_Connection * connection, char *command)
+{
+       int ret;
+       struct timeval tv;
+       fd_set fds;
+       char *commandPtr = command;
+       int commandLen = strlen(command);
+
+       if (!connection->doneProcessing && !connection->commandList) {
+               strcpy(connection->errorStr,
+                      "not done processing current command");
+               connection->error = 1;
+               return;
+       }
+
+       mpd_clearError(connection);
+
+       FD_ZERO(&fds);
+       FD_SET(connection->sock, &fds);
+       tv.tv_sec = connection->timeout.tv_sec;
+       tv.tv_usec = connection->timeout.tv_usec;
+
+       while ((ret =
+               select(connection->sock + 1, NULL, &fds, NULL, &tv) == 1)
+              || (ret == -1 && errno == EINTR)) {
+               ret =
+                   send(connection->sock, commandPtr, commandLen,
+                        MSG_DONTWAIT);
+               if (ret <= 0) {
+                       if (ret == EAGAIN || ret == EINTR)
+                               continue;
+                       snprintf(connection->errorStr,
+                                MPD_BUFFER_MAX_LENGTH,
+                                "problems giving command \"%s\"",
+                                command);
+                       connection->error = MPD_ERROR_SENDING;
+                       return;
+               } else {
+                       commandPtr += ret;
+                       commandLen -= ret;
+               }
+
+               if (commandLen <= 0)
+                       break;
+       }
+
+       if (commandLen > 0) {
+               perror("");
+               snprintf(connection->errorStr, MPD_BUFFER_MAX_LENGTH,
+                        "timeout sending command \"%s\"", command);
+               connection->error = MPD_ERROR_TIMEOUT;
+               return;
+       }
+
+       if (!connection->commandList)
+               connection->doneProcessing = 0;
+       else if (connection->commandList == COMMAND_LIST_OK) {
+               connection->listOks++;
+       }
+}
+
+void mpd_getNextReturnElement(mpd_Connection * connection)
+{
+       char *output = NULL;
+       char *rt = NULL;
+       char *name = NULL;
+       char *value = NULL;
+       fd_set fds;
+       struct timeval tv;
+       char *tok = NULL;
+       int readed;
+       char *bufferCheck = NULL;
+       int err;
+
+       if (connection->returnElement)
+               mpd_freeReturnElement(connection->returnElement);
+       connection->returnElement = NULL;
+
+       if (connection->doneProcessing || (connection->listOks &&
+                                          connection->doneListOk)) {
+               strcpy(connection->errorStr,
+                      "already done processing current command");
+               connection->error = 1;
+               return;
+       }
+
+       bufferCheck = connection->buffer + connection->bufstart;
+       while (connection->bufstart >= connection->buflen ||
+              !(rt = strstr(bufferCheck, "\n"))) {
+               if (connection->buflen >= MPD_BUFFER_MAX_LENGTH) {
+                       memmove(connection->buffer,
+                               connection->buffer +
+                               connection->bufstart,
+                               connection->buflen - connection->bufstart +
+                               1);
+                       bufferCheck -= connection->bufstart;
+                       connection->buflen -= connection->bufstart;
+                       connection->bufstart = 0;
+               }
+               if (connection->buflen >= MPD_BUFFER_MAX_LENGTH) {
+                       strcpy(connection->errorStr, "buffer overrun");
+                       connection->error = MPD_ERROR_BUFFEROVERRUN;
+                       connection->doneProcessing = 1;
+                       connection->doneListOk = 0;
+                       return;
+               }
+               bufferCheck += connection->buflen - connection->bufstart;
+               tv.tv_sec = connection->timeout.tv_sec;
+               tv.tv_usec = connection->timeout.tv_usec;
+               FD_ZERO(&fds);
+               FD_SET(connection->sock, &fds);
+               if ((err =
+                    select(connection->sock + 1, &fds, NULL, NULL,
+                           &tv) == 1)) {
+                       readed =
+                           recv(connection->sock,
+                                connection->buffer + connection->buflen,
+                                MPD_BUFFER_MAX_LENGTH -
+                                connection->buflen, MSG_DONTWAIT);
+                       if (readed < 0
+                           && (errno == EAGAIN || errno == EINTR)) {
+                               continue;
+                       }
+                       if (readed <= 0) {
+                               strcpy(connection->errorStr,
+                                      "connection" " closed");
+                               connection->error = MPD_ERROR_CONNCLOSED;
+                               connection->doneProcessing = 1;
+                               connection->doneListOk = 0;
+                               return;
+                       }
+                       connection->buflen += readed;
+                       connection->buffer[connection->buflen] = '\0';
+               } else if (err < 0 && errno == EINTR)
+                       continue;
+               else {
+                       strcpy(connection->errorStr, "connection timeout");
+                       connection->error = MPD_ERROR_TIMEOUT;
+                       connection->doneProcessing = 1;
+                       connection->doneListOk = 0;
+                       return;
+               }
+       }
+
+       *rt = '\0';
+       output = connection->buffer + connection->bufstart;
+       connection->bufstart = rt - connection->buffer + 1;
+
+       if (strcmp(output, "OK") == 0) {
+               if (connection->listOks > 0) {
+                       strcpy(connection->errorStr,
+                              "expected more list_OK's");
+                       connection->error = 1;
+               }
+               connection->listOks = 0;
+               connection->doneProcessing = 1;
+               connection->doneListOk = 0;
+               return;
+       }
+
+       if (strcmp(output, "list_OK") == 0) {
+               if (!connection->listOks) {
+                       strcpy(connection->errorStr,
+                              "got an unexpected list_OK");
+                       connection->error = 1;
+               } else {
+                       connection->doneListOk = 1;
+                       connection->listOks--;
+               }
+               return;
+       }
+
+       if (strncmp(output, "ACK", strlen("ACK")) == 0) {
+               char *test;
+               char *needle;
+               int val;
+
+               strcpy(connection->errorStr, output);
+               connection->error = MPD_ERROR_ACK;
+               connection->errorCode = MPD_ACK_ERROR_UNK;
+               connection->errorAt = MPD_ERROR_AT_UNK;
+               connection->doneProcessing = 1;
+               connection->doneListOk = 0;
+
+               needle = strchr(output, '[');
+               if (!needle)
+                       return;
+               val = strtol(needle + 1, &test, 10);
+               if (*test != '@')
+                       return;
+               connection->errorCode = val;
+               val = strtol(test + 1, &test, 10);
+               if (*test != ']')
+                       return;
+               connection->errorAt = val;
+               return;
+       }
+
+       name = strtok_r(output, ":", &tok);
+       if (name && (value = strtok_r(NULL, "", &tok)) && value[0] == ' ') {
+               connection->returnElement =
+                   mpd_newReturnElement(name, &(value[1]));
+       } else {
+               if (!name || !value) {
+                       snprintf(connection->errorStr,
+                                MPD_BUFFER_MAX_LENGTH,
+                                "error parsing: %s", output);
+               } else {
+                       snprintf(connection->errorStr,
+                                MPD_BUFFER_MAX_LENGTH,
+                                "error parsing: %s:%s", name, value);
+               }
+               connection->errorStr[MPD_BUFFER_MAX_LENGTH] = '\0';
+               connection->error = 1;
+       }
+}
+
+void mpd_finishCommand(mpd_Connection * connection)
+{
+       while (!connection->doneProcessing) {
+               if (connection->doneListOk)
+                       connection->doneListOk = 0;
+               mpd_getNextReturnElement(connection);
+       }
+}
+
+void mpd_finishListOkCommand(mpd_Connection * connection)
+{
+       while (!connection->doneProcessing && connection->listOks &&
+              !connection->doneListOk) {
+               mpd_getNextReturnElement(connection);
+       }
+}
+
+int mpd_nextListOkCommand(mpd_Connection * connection)
+{
+       mpd_finishListOkCommand(connection);
+       if (!connection->doneProcessing)
+               connection->doneListOk = 0;
+       if (connection->listOks == 0 || connection->doneProcessing)
+               return -1;
+       return 0;
+}
+
+void mpd_sendStatusCommand(mpd_Connection * connection)
+{
+       mpd_executeCommand(connection, "status\n");
+}
+
+mpd_Status *mpd_getStatus(mpd_Connection * connection)
+{
+       mpd_Status *status;
+
+       /*mpd_executeCommand(connection,"status\n");
+
+          if(connection->error) return NULL; */
+
+       if (connection->doneProcessing || (connection->listOks &&
+                                          connection->doneListOk)) {
+               return NULL;
+       }
+
+       if (!connection->returnElement)
+               mpd_getNextReturnElement(connection);
+
+       status = malloc(sizeof(mpd_Status));
+       status->volume = -1;
+       status->repeat = 0;
+       status->random = 0;
+       status->playlist = -1;
+       status->playlistLength = -1;
+       status->state = -1;
+       status->song = 0;
+       status->elapsedTime = 0;
+       status->totalTime = 0;
+       status->bitRate = 0;
+       status->sampleRate = 0;
+       status->bits = 0;
+       status->channels = 0;
+       status->crossfade = -1;
+       status->error = NULL;
+       status->updatingDb = 0;
+
+       if (connection->error) {
+               free(status);
+               return NULL;
+       }
+       while (connection->returnElement) {
+               mpd_ReturnElement *re = connection->returnElement;
+               if (strcmp(re->name, "volume") == 0) {
+                       status->volume = atoi(re->value);
+               } else if (strcmp(re->name, "repeat") == 0) {
+                       status->repeat = atoi(re->value);
+               } else if (strcmp(re->name, "random") == 0) {
+                       status->random = atoi(re->value);
+               } else if (strcmp(re->name, "playlist") == 0) {
+                       status->playlist = strtol(re->value, NULL, 10);
+               } else if (strcmp(re->name, "playlistlength") == 0) {
+                       status->playlistLength = atoi(re->value);
+               } else if (strcmp(re->name, "bitrate") == 0) {
+                       status->bitRate = atoi(re->value);
+               } else if (strcmp(re->name, "state") == 0) {
+                       if (strcmp(re->value, "play") == 0) {
+                               status->state = MPD_STATUS_STATE_PLAY;
+                       } else if (strcmp(re->value, "stop") == 0) {
+                               status->state = MPD_STATUS_STATE_STOP;
+                       } else if (strcmp(re->value, "pause") == 0) {
+                               status->state = MPD_STATUS_STATE_PAUSE;
+                       } else {
+                               status->state = MPD_STATUS_STATE_UNKNOWN;
+                       }
+               } else if (strcmp(re->name, "song") == 0) {
+                       status->song = atoi(re->value);
+               } else if (strcmp(re->name, "songid") == 0) {
+                       status->songid = atoi(re->value);
+               } else if (strcmp(re->name, "time") == 0) {
+                       char *tok;
+                       char *copy;
+                       char *temp;
+                       copy = strdup(re->value);
+                       temp = strtok_r(copy, ":", &tok);
+                       if (temp) {
+                               status->elapsedTime = atoi(temp);
+                               temp = strtok_r(NULL, "", &tok);
+                               if (temp)
+                                       status->totalTime = atoi(temp);
+                       }
+                       free(copy);
+               } else if (strcmp(re->name, "error") == 0) {
+                       status->error = strdup(re->value);
+               } else if (strcmp(re->name, "xfade") == 0) {
+                       status->crossfade = atoi(re->value);
+               } else if (strcmp(re->name, "updating_db") == 0) {
+                       status->updatingDb = atoi(re->value);
+               } else if (strcmp(re->name, "audio") == 0) {
+                       char *tok;
+                       char *copy;
+                       char *temp;
+                       copy = strdup(re->value);
+                       temp = strtok_r(copy, ":", &tok);
+                       if (temp) {
+                               status->sampleRate = atoi(temp);
+                               temp = strtok_r(NULL, ":", &tok);
+                               if (temp) {
+                                       status->bits = atoi(temp);
+                                       temp = strtok_r(NULL, "", &tok);
+                                       if (temp)
+                                               status->channels =
+                                                   atoi(temp);
+                               }
+                       }
+                       free(copy);
+               }
+
+               mpd_getNextReturnElement(connection);
+               if (connection->error) {
+                       free(status);
+                       return NULL;
+               }
+       }
+
+       if (connection->error) {
+               free(status);
+               return NULL;
+       } else if (status->state < 0) {
+               strcpy(connection->errorStr, "state not found");
+               connection->error = 1;
+               free(status);
+               return NULL;
+       }
+
+       return status;
+}
+
+void mpd_freeStatus(mpd_Status * status)
+{
+       if (status->error)
+               free(status->error);
+       free(status);
+}
+
+void mpd_sendStatsCommand(mpd_Connection * connection)
+{
+       mpd_executeCommand(connection, "stats\n");
+}
+
+mpd_Stats *mpd_getStats(mpd_Connection * connection)
+{
+       mpd_Stats *stats;
+
+       /*mpd_executeCommand(connection,"stats\n");
+
+          if(connection->error) return NULL; */
+
+       if (connection->doneProcessing || (connection->listOks &&
+                                          connection->doneListOk)) {
+               return NULL;
+       }
+
+       if (!connection->returnElement)
+               mpd_getNextReturnElement(connection);
+
+       stats = malloc(sizeof(mpd_Stats));
+       stats->numberOfArtists = 0;
+       stats->numberOfAlbums = 0;
+       stats->numberOfSongs = 0;
+       stats->uptime = 0;
+       stats->dbUpdateTime = 0;
+       stats->playTime = 0;
+       stats->dbPlayTime = 0;
+
+       if (connection->error) {
+               free(stats);
+               return NULL;
+       }
+       while (connection->returnElement) {
+               mpd_ReturnElement *re = connection->returnElement;
+               if (strcmp(re->name, "artists") == 0) {
+                       stats->numberOfArtists = atoi(re->value);
+               } else if (strcmp(re->name, "albums") == 0) {
+                       stats->numberOfAlbums = atoi(re->value);
+               } else if (strcmp(re->name, "songs") == 0) {
+                       stats->numberOfSongs = atoi(re->value);
+               } else if (strcmp(re->name, "uptime") == 0) {
+                       stats->uptime = strtol(re->value, NULL, 10);
+               } else if (strcmp(re->name, "db_update") == 0) {
+                       stats->dbUpdateTime = strtol(re->value, NULL, 10);
+               } else if (strcmp(re->name, "playtime") == 0) {
+                       stats->playTime = strtol(re->value, NULL, 10);
+               } else if (strcmp(re->name, "db_playtime") == 0) {
+                       stats->dbPlayTime = strtol(re->value, NULL, 10);
+               }
+
+               mpd_getNextReturnElement(connection);
+               if (connection->error) {
+                       free(stats);
+                       return NULL;
+               }
+       }
+
+       if (connection->error) {
+               free(stats);
+               return NULL;
+       }
+
+       return stats;
+}
+
+void mpd_freeStats(mpd_Stats * stats)
+{
+       free(stats);
+}
+
+void mpd_initSong(mpd_Song * song)
+{
+       song->file = NULL;
+       song->artist = NULL;
+       song->album = NULL;
+       song->track = NULL;
+       song->title = NULL;
+       song->name = NULL;
+       song->time = MPD_SONG_NO_TIME;
+       song->pos = MPD_SONG_NO_NUM;
+       song->id = MPD_SONG_NO_ID;
+}
+
+void mpd_finishSong(mpd_Song * song)
+{
+       if (song->file)
+               free(song->file);
+       if (song->artist)
+               free(song->artist);
+       if (song->album)
+               free(song->album);
+       if (song->title)
+               free(song->title);
+       if (song->track)
+               free(song->track);
+       if (song->name)
+               free(song->name);
+}
+
+mpd_Song *mpd_newSong()
+{
+       mpd_Song *ret = malloc(sizeof(mpd_Song));
+
+       mpd_initSong(ret);
+
+       return ret;
+}
+
+void mpd_freeSong(mpd_Song * song)
+{
+       mpd_finishSong(song);
+       free(song);
+}
+
+mpd_Song *mpd_songDup(mpd_Song * song)
+{
+       mpd_Song *ret = mpd_newSong();
+
+       if (song->file)
+               ret->file = strdup(song->file);
+       if (song->artist)
+               ret->artist = strdup(song->artist);
+       if (song->album)
+               ret->album = strdup(song->album);
+       if (song->title)
+               ret->title = strdup(song->title);
+       if (song->track)
+               ret->track = strdup(song->track);
+       if (song->name)
+               ret->name = strdup(song->name);
+       ret->time = song->time;
+       ret->pos = song->pos;
+       ret->id = song->id;
+
+       return ret;
+}
+
+void mpd_initDirectory(mpd_Directory * directory)
+{
+       directory->path = NULL;
+}
+
+void mpd_finishDirectory(mpd_Directory * directory)
+{
+       if (directory->path)
+               free(directory->path);
+}
+
+mpd_Directory *mpd_newDirectory()
+{
+       mpd_Directory *directory = malloc(sizeof(mpd_Directory));;
+
+       mpd_initDirectory(directory);
+
+       return directory;
+}
+
+void mpd_freeDirectory(mpd_Directory * directory)
+{
+       mpd_finishDirectory(directory);
+
+       free(directory);
+}
+
+mpd_Directory *mpd_directoryDup(mpd_Directory * directory)
+{
+       mpd_Directory *ret = mpd_newDirectory();
+
+       if (directory->path)
+               ret->path = strdup(directory->path);
+
+       return ret;
+}
+
+void mpd_initPlaylistFile(mpd_PlaylistFile * playlist)
+{
+       playlist->path = NULL;
+}
+
+void mpd_finishPlaylistFile(mpd_PlaylistFile * playlist)
+{
+       if (playlist->path)
+               free(playlist->path);
+}
+
+mpd_PlaylistFile *mpd_newPlaylistFile()
+{
+       mpd_PlaylistFile *playlist = malloc(sizeof(mpd_PlaylistFile));
+
+       mpd_initPlaylistFile(playlist);
+
+       return playlist;
+}
+
+void mpd_freePlaylistFile(mpd_PlaylistFile * playlist)
+{
+       mpd_finishPlaylistFile(playlist);
+       free(playlist);
+}
+
+mpd_PlaylistFile *mpd_playlistFileDup(mpd_PlaylistFile * playlist)
+{
+       mpd_PlaylistFile *ret = mpd_newPlaylistFile();
+
+       if (playlist->path)
+               ret->path = strdup(playlist->path);
+
+       return ret;
+}
+
+void mpd_initInfoEntity(mpd_InfoEntity * entity)
+{
+       entity->info.directory = NULL;
+}
+
+void mpd_finishInfoEntity(mpd_InfoEntity * entity)
+{
+       if (entity->info.directory) {
+               if (entity->type == MPD_INFO_ENTITY_TYPE_DIRECTORY) {
+                       mpd_freeDirectory(entity->info.directory);
+               } else if (entity->type == MPD_INFO_ENTITY_TYPE_SONG) {
+                       mpd_freeSong(entity->info.song);
+               } else if (entity->type ==
+                          MPD_INFO_ENTITY_TYPE_PLAYLISTFILE) {
+                       mpd_freePlaylistFile(entity->info.playlistFile);
+               }
+       }
+}
+
+mpd_InfoEntity *mpd_newInfoEntity()
+{
+       mpd_InfoEntity *entity = malloc(sizeof(mpd_InfoEntity));
+
+       mpd_initInfoEntity(entity);
+
+       return entity;
+}
+
+void mpd_freeInfoEntity(mpd_InfoEntity * entity)
+{
+       mpd_finishInfoEntity(entity);
+       free(entity);
+}
+
+void mpd_sendInfoCommand(mpd_Connection * connection, char *command)
+{
+       mpd_executeCommand(connection, command);
+}
+
+mpd_InfoEntity *mpd_getNextInfoEntity(mpd_Connection * connection)
+{
+       mpd_InfoEntity *entity = NULL;
+
+       if (connection->doneProcessing || (connection->listOks &&
+                                          connection->doneListOk)) {
+               return NULL;
+       }
+
+       if (!connection->returnElement)
+               mpd_getNextReturnElement(connection);
+
+       if (connection->returnElement) {
+               if (strcmp(connection->returnElement->name, "file") == 0) {
+                       entity = mpd_newInfoEntity();
+                       entity->type = MPD_INFO_ENTITY_TYPE_SONG;
+                       entity->info.song = mpd_newSong();
+                       entity->info.song->file =
+                           strdup(connection->returnElement->value);
+               } else
+                   if (strcmp
+                       (connection->returnElement->name,
+                        "directory") == 0) {
+                       entity = mpd_newInfoEntity();
+                       entity->type = MPD_INFO_ENTITY_TYPE_DIRECTORY;
+                       entity->info.directory = mpd_newDirectory();
+                       entity->info.directory->path =
+                           strdup(connection->returnElement->value);
+               } else
+                   if (strcmp(connection->returnElement->name, "playlist")
+                       == 0) {
+                       entity = mpd_newInfoEntity();
+                       entity->type = MPD_INFO_ENTITY_TYPE_PLAYLISTFILE;
+                       entity->info.playlistFile = mpd_newPlaylistFile();
+                       entity->info.playlistFile->path =
+                           strdup(connection->returnElement->value);
+               } else {
+                       connection->error = 1;
+                       strcpy(connection->errorStr,
+                              "problem parsing song info");
+                       return NULL;
+               }
+       } else
+               return NULL;
+
+       mpd_getNextReturnElement(connection);
+       while (connection->returnElement) {
+               mpd_ReturnElement *re = connection->returnElement;
+
+               if (strcmp(re->name, "file") == 0)
+                       return entity;
+               else if (strcmp(re->name, "directory") == 0)
+                       return entity;
+               else if (strcmp(re->name, "playlist") == 0)
+                       return entity;
+
+               if (entity->type == MPD_INFO_ENTITY_TYPE_SONG
+                   && strlen(re->value)) {
+                       if (!entity->info.song->artist
+                           && strcmp(re->name, "Artist") == 0) {
+                               entity->info.song->artist =
+                                   strdup(re->value);
+                       } else if (!entity->info.song->album
+                                  && strcmp(re->name, "Album") == 0) {
+                               entity->info.song->album =
+                                   strdup(re->value);
+                       } else if (!entity->info.song->title
+                                  && strcmp(re->name, "Title") == 0) {
+                               entity->info.song->title =
+                                   strdup(re->value);
+                       } else if (!entity->info.song->track
+                                  && strcmp(re->name, "Track") == 0) {
+                               entity->info.song->track =
+                                   strdup(re->value);
+                       } else if (!entity->info.song->name
+                                  && strcmp(re->name, "Name") == 0) {
+                               entity->info.song->name =
+                                   strdup(re->value);
+                       } else if (entity->info.song->time ==
+                                  MPD_SONG_NO_TIME
+                                  && strcmp(re->name, "Time") == 0) {
+                               entity->info.song->time = atoi(re->value);
+                       } else if (entity->info.song->pos ==
+                                  MPD_SONG_NO_NUM
+                                  && strcmp(re->name, "Pos") == 0) {
+                               entity->info.song->pos = atoi(re->value);
+                       } else if (entity->info.song->id == MPD_SONG_NO_ID
+                                  && strcmp(re->name, "Id") == 0) {
+                               entity->info.song->id = atoi(re->value);
+                       }
+               } else if (entity->type == MPD_INFO_ENTITY_TYPE_DIRECTORY) {
+               } else if (entity->type ==
+                          MPD_INFO_ENTITY_TYPE_PLAYLISTFILE) {
+               }
+
+               mpd_getNextReturnElement(connection);
+       }
+
+       return entity;
+}
+
+char *mpd_getNextReturnElementNamed(mpd_Connection * connection,
+                                   const char *name)
+{
+       if (connection->doneProcessing || (connection->listOks &&
+                                          connection->doneListOk)) {
+               return NULL;
+       }
+
+       mpd_getNextReturnElement(connection);
+       while (connection->returnElement) {
+               mpd_ReturnElement *re = connection->returnElement;
+
+               if (strcmp(re->name, name) == 0)
+                       return strdup(re->value);
+               mpd_getNextReturnElement(connection);
+       }
+
+       return NULL;
+}
+
+char *mpd_getNextArtist(mpd_Connection * connection)
+{
+       return mpd_getNextReturnElementNamed(connection, "Artist");
+}
+
+char *mpd_getNextAlbum(mpd_Connection * connection)
+{
+       return mpd_getNextReturnElementNamed(connection, "Album");
+}
+
+void mpd_sendPlaylistInfoCommand(mpd_Connection * connection, int songPos)
+{
+       char *string = malloc(strlen("playlistinfo") + 25);
+       sprintf(string, "playlistinfo \"%i\"\n", songPos);
+       mpd_sendInfoCommand(connection, string);
+       free(string);
+}
+
+void mpd_sendPlaylistIdCommand(mpd_Connection * connection, int id)
+{
+       char *string = malloc(strlen("playlistid") + 25);
+       sprintf(string, "playlistid \"%i\"\n", id);
+       mpd_sendInfoCommand(connection, string);
+       free(string);
+}
+
+void
+mpd_sendPlChangesCommand(mpd_Connection * connection, long long playlist)
+{
+       char *string = malloc(strlen("plchanges") + 25);
+       sprintf(string, "plchanges \"%lld\"\n", playlist);
+       mpd_sendInfoCommand(connection, string);
+       free(string);
+}
+
+void mpd_sendListallCommand(mpd_Connection * connection, const char *dir)
+{
+       char *sDir = mpd_sanitizeArg(dir);
+       char *string = malloc(strlen("listall") + strlen(sDir) + 5);
+       sprintf(string, "listall \"%s\"\n", sDir);
+       mpd_sendInfoCommand(connection, string);
+       free(string);
+       free(sDir);
+}
+
+void
+mpd_sendListallInfoCommand(mpd_Connection * connection, const char *dir)
+{
+       char *sDir = mpd_sanitizeArg(dir);
+       char *string = malloc(strlen("listallinfo") + strlen(sDir) + 5);
+       sprintf(string, "listallinfo \"%s\"\n", sDir);
+       mpd_sendInfoCommand(connection, string);
+       free(string);
+       free(sDir);
+}
+
+void mpd_sendLsInfoCommand(mpd_Connection * connection, const char *dir)
+{
+       char *sDir = mpd_sanitizeArg(dir);
+       char *string = malloc(strlen("lsinfo") + strlen(sDir) + 5);
+       sprintf(string, "lsinfo \"%s\"\n", sDir);
+       mpd_sendInfoCommand(connection, string);
+       free(string);
+       free(sDir);
+}
+
+void mpd_sendCurrentSongCommand(mpd_Connection * connection)
+{
+       mpd_executeCommand(connection, "currentsong\n");
+}
+
+void
+mpd_sendSearchCommand(mpd_Connection * connection, int table,
+                     const char *str)
+{
+       char st[10];
+       char *string;
+       char *sanitStr = mpd_sanitizeArg(str);
+       if (table == MPD_TABLE_ARTIST)
+               strcpy(st, "artist");
+       else if (table == MPD_TABLE_ALBUM)
+               strcpy(st, "album");
+       else if (table == MPD_TABLE_TITLE)
+               strcpy(st, "title");
+       else if (table == MPD_TABLE_FILENAME)
+               strcpy(st, "filename");
+       else {
+               connection->error = 1;
+               strcpy(connection->errorStr, "unknown table for search");
+               return;
+       }
+       string =
+           malloc(strlen("search") + strlen(sanitStr) + strlen(st) + 6);
+       sprintf(string, "search %s \"%s\"\n", st, sanitStr);
+       mpd_sendInfoCommand(connection, string);
+       free(string);
+       free(sanitStr);
+}
+
+void
+mpd_sendFindCommand(mpd_Connection * connection, int table,
+                   const char *str)
+{
+       char st[10];
+       char *string;
+       char *sanitStr = mpd_sanitizeArg(str);
+       if (table == MPD_TABLE_ARTIST)
+               strcpy(st, "artist");
+       else if (table == MPD_TABLE_ALBUM)
+               strcpy(st, "album");
+       else if (table == MPD_TABLE_TITLE)
+               strcpy(st, "title");
+       else {
+               connection->error = 1;
+               strcpy(connection->errorStr, "unknown table for find");
+               return;
+       }
+       string =
+           malloc(strlen("find") + strlen(sanitStr) + strlen(st) + 6);
+       sprintf(string, "find %s \"%s\"\n", st, sanitStr);
+       mpd_sendInfoCommand(connection, string);
+       free(string);
+       free(sanitStr);
+}
+
+void
+mpd_sendListCommand(mpd_Connection * connection, int table,
+                   const char *arg1)
+{
+       char st[10];
+       char *string;
+       if (table == MPD_TABLE_ARTIST)
+               strcpy(st, "artist");
+       else if (table == MPD_TABLE_ALBUM)
+               strcpy(st, "album");
+       else {
+               connection->error = 1;
+               strcpy(connection->errorStr, "unknown table for list");
+               return;
+       }
+       if (arg1) {
+               char *sanitArg1 = mpd_sanitizeArg(arg1);
+               string =
+                   malloc(strlen("list") + strlen(sanitArg1) +
+                          strlen(st) + 6);
+               sprintf(string, "list %s \"%s\"\n", st, sanitArg1);
+               free(sanitArg1);
+       } else {
+               string = malloc(strlen("list") + strlen(st) + 3);
+               sprintf(string, "list %s\n", st);
+       }
+       mpd_sendInfoCommand(connection, string);
+       free(string);
+}
+
+void mpd_sendAddCommand(mpd_Connection * connection, const char *file)
+{
+       char *sFile = mpd_sanitizeArg(file);
+       char *string = malloc(strlen("add") + strlen(sFile) + 5);
+       sprintf(string, "add \"%s\"\n", sFile);
+       mpd_executeCommand(connection, string);
+       free(string);
+       free(sFile);
+}
+
+void mpd_sendDeleteCommand(mpd_Connection * connection, int songPos)
+{
+       char *string = malloc(strlen("delete") + 25);
+       sprintf(string, "delete \"%i\"\n", songPos);
+       mpd_sendInfoCommand(connection, string);
+       free(string);
+}
+
+void mpd_sendDeleteIdCommand(mpd_Connection * connection, int id)
+{
+       char *string = malloc(strlen("deleteid") + 25);
+       sprintf(string, "deleteid \"%i\"\n", id);
+       mpd_sendInfoCommand(connection, string);
+       free(string);
+}
+
+void mpd_sendSaveCommand(mpd_Connection * connection, const char *name)
+{
+       char *sName = mpd_sanitizeArg(name);
+       char *string = malloc(strlen("save") + strlen(sName) + 5);
+       sprintf(string, "save \"%s\"\n", sName);
+       mpd_executeCommand(connection, string);
+       free(string);
+       free(sName);
+}
+
+void mpd_sendLoadCommand(mpd_Connection * connection, const char *name)
+{
+       char *sName = mpd_sanitizeArg(name);
+       char *string = malloc(strlen("load") + strlen(sName) + 5);
+       sprintf(string, "load \"%s\"\n", sName);
+       mpd_executeCommand(connection, string);
+       free(string);
+       free(sName);
+}
+
+void mpd_sendRmCommand(mpd_Connection * connection, const char *name)
+{
+       char *sName = mpd_sanitizeArg(name);
+       char *string = malloc(strlen("rm") + strlen(sName) + 5);
+       sprintf(string, "rm \"%s\"\n", sName);
+       mpd_executeCommand(connection, string);
+       free(string);
+       free(sName);
+}
+
+void mpd_sendShuffleCommand(mpd_Connection * connection)
+{
+       mpd_executeCommand(connection, "shuffle\n");
+}
+
+void mpd_sendClearCommand(mpd_Connection * connection)
+{
+       mpd_executeCommand(connection, "clear\n");
+}
+
+void mpd_sendPlayCommand(mpd_Connection * connection, int songPos)
+{
+       char *string = malloc(strlen("play") + 25);
+       sprintf(string, "play \"%i\"\n", songPos);
+       mpd_sendInfoCommand(connection, string);
+       free(string);
+}
+
+void mpd_sendPlayIdCommand(mpd_Connection * connection, int id)
+{
+       char *string = malloc(strlen("playid") + 25);
+       sprintf(string, "playid \"%i\"\n", id);
+       mpd_sendInfoCommand(connection, string);
+       free(string);
+}
+
+void mpd_sendStopCommand(mpd_Connection * connection)
+{
+       mpd_executeCommand(connection, "stop\n");
+}
+
+void mpd_sendPauseCommand(mpd_Connection * connection, int pauseMode)
+{
+       char *string = malloc(strlen("pause") + 25);
+       sprintf(string, "pause \"%i\"\n", pauseMode);
+       mpd_executeCommand(connection, string);
+       free(string);
+}
+
+void mpd_sendNextCommand(mpd_Connection * connection)
+{
+       mpd_executeCommand(connection, "next\n");
+}
+
+void mpd_sendMoveCommand(mpd_Connection * connection, int from, int to)
+{
+       char *string = malloc(strlen("move") + 25);
+       sprintf(string, "move \"%i\" \"%i\"\n", from, to);
+       mpd_sendInfoCommand(connection, string);
+       free(string);
+}
+
+void mpd_sendMoveIdCommand(mpd_Connection * connection, int id, int to)
+{
+       char *string = malloc(strlen("moveid") + 25);
+       sprintf(string, "moveid \"%i\" \"%i\"\n", id, to);
+       mpd_sendInfoCommand(connection, string);
+       free(string);
+}
+
+void mpd_sendSwapCommand(mpd_Connection * connection, int song1, int song2)
+{
+       char *string = malloc(strlen("swap") + 25);
+       sprintf(string, "swap \"%i\" \"%i\"\n", song1, song2);
+       mpd_sendInfoCommand(connection, string);
+       free(string);
+}
+
+void mpd_sendSwapIdCommand(mpd_Connection * connection, int id1, int id2)
+{
+       char *string = malloc(strlen("swapid") + 25);
+       sprintf(string, "swapid \"%i\" \"%i\"\n", id1, id2);
+       mpd_sendInfoCommand(connection, string);
+       free(string);
+}
+
+void mpd_sendSeekCommand(mpd_Connection * connection, int song, int time)
+{
+       char *string = malloc(strlen("seek") + 25);
+       sprintf(string, "seek \"%i\" \"%i\"\n", song, time);
+       mpd_sendInfoCommand(connection, string);
+       free(string);
+}
+
+void mpd_sendSeekIdCommand(mpd_Connection * connection, int id, int time)
+{
+       char *string = malloc(strlen("seekid") + 25);
+       sprintf(string, "seekid \"%i\" \"%i\"\n", id, time);
+       mpd_sendInfoCommand(connection, string);
+       free(string);
+}
+
+void mpd_sendUpdateCommand(mpd_Connection * connection, char *path)
+{
+       char *sPath = mpd_sanitizeArg(path);
+       char *string = malloc(strlen("update") + strlen(sPath) + 5);
+       sprintf(string, "update \"%s\"\n", sPath);
+       mpd_sendInfoCommand(connection, string);
+       free(string);
+       free(sPath);
+}
+
+int mpd_getUpdateId(mpd_Connection * connection)
+{
+       char *jobid;
+       int ret = 0;
+
+       jobid = mpd_getNextReturnElementNamed(connection, "updating_db");
+       if (jobid) {
+               ret = atoi(jobid);
+               free(jobid);
+       }
+
+       return ret;
+}
+
+void mpd_sendPrevCommand(mpd_Connection * connection)
+{
+       mpd_executeCommand(connection, "previous\n");
+}
+
+void mpd_sendRepeatCommand(mpd_Connection * connection, int repeatMode)
+{
+       char *string = malloc(strlen("repeat") + 25);
+       sprintf(string, "repeat \"%i\"\n", repeatMode);
+       mpd_executeCommand(connection, string);
+       free(string);
+}
+
+void mpd_sendRandomCommand(mpd_Connection * connection, int randomMode)
+{
+       char *string = malloc(strlen("random") + 25);
+       sprintf(string, "random \"%i\"\n", randomMode);
+       mpd_executeCommand(connection, string);
+       free(string);
+}
+
+void mpd_sendSetvolCommand(mpd_Connection * connection, int volumeChange)
+{
+       char *string = malloc(strlen("setvol") + 25);
+       sprintf(string, "setvol \"%i\"\n", volumeChange);
+       mpd_executeCommand(connection, string);
+       free(string);
+}
+
+void mpd_sendVolumeCommand(mpd_Connection * connection, int volumeChange)
+{
+       char *string = malloc(strlen("volume") + 25);
+       sprintf(string, "volume \"%i\"\n", volumeChange);
+       mpd_executeCommand(connection, string);
+       free(string);
+}
+
+void mpd_sendCrossfadeCommand(mpd_Connection * connection, int seconds)
+{
+       char *string = malloc(strlen("crossfade") + 25);
+       sprintf(string, "crossfade \"%i\"\n", seconds);
+       mpd_executeCommand(connection, string);
+       free(string);
+}
+
+void mpd_sendPasswordCommand(mpd_Connection * connection, const char *pass)
+{
+       char *sPass = mpd_sanitizeArg(pass);
+       char *string = malloc(strlen("password") + strlen(sPass) + 5);
+       sprintf(string, "password \"%s\"\n", sPass);
+       mpd_executeCommand(connection, string);
+       free(string);
+       free(sPass);
+}
+
+void mpd_sendCommandListBegin(mpd_Connection * connection)
+{
+       if (connection->commandList) {
+               strcpy(connection->errorStr,
+                      "already in command list mode");
+               connection->error = 1;
+               return;
+       }
+       connection->commandList = COMMAND_LIST;
+       mpd_executeCommand(connection, "command_list_begin\n");
+}
+
+void mpd_sendCommandListOkBegin(mpd_Connection * connection)
+{
+       if (connection->commandList) {
+               strcpy(connection->errorStr,
+                      "already in command list mode");
+               connection->error = 1;
+               return;
+       }
+       connection->commandList = COMMAND_LIST_OK;
+       mpd_executeCommand(connection, "command_list_ok_begin\n");
+       connection->listOks = 0;
+}
+
+void mpd_sendCommandListEnd(mpd_Connection * connection)
+{
+       if (!connection->commandList) {
+               strcpy(connection->errorStr, "not in command list mode");
+               connection->error = 1;
+               return;
+       }
+       connection->commandList = 0;
+       mpd_executeCommand(connection, "command_list_end\n");
+}
diff --git a/src/libmpdclient.h b/src/libmpdclient.h
new file mode 100644 (file)
index 0000000..2b7669c
--- /dev/null
@@ -0,0 +1,509 @@
+/* libmpdclient
+   (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu)
+   This project's homepage is: http://www.musicpd.org
+  
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+                                                                                
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+                                                                                
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+                                                                                
+   - Neither the name of the Music Player Daemon nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+                                                                                
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+   
+   $Id$
+
+*/
+
+#ifndef LIBMPDCLIENT_H
+#define LIBMPDCLIENT_H
+
+#include <sys/time.h>
+
+#define MPD_BUFFER_MAX_LENGTH  50000
+#define MPD_WELCOME_MESSAGE    "OK MPD "
+
+#define MPD_ERROR_TIMEOUT      10      /* timeout trying to talk to mpd */
+#define MPD_ERROR_SYSTEM       11      /* system error */
+#define MPD_ERROR_UNKHOST      12      /* unknown host */
+#define MPD_ERROR_CONNPORT     13      /* problems connecting to port on host */
+#define MPD_ERROR_NOTMPD       14      /* mpd not running on port at host */
+#define MPD_ERROR_NORESPONSE   15      /* no response on attempting to connect */
+#define MPD_ERROR_SENDING      16      /* error sending command */
+#define MPD_ERROR_CONNCLOSED   17      /* connection closed by mpd */
+#define MPD_ERROR_ACK          18      /* ACK returned! */
+#define MPD_ERROR_BUFFEROVERRUN        19      /* Buffer was overrun! */
+
+#define MPD_ACK_ERROR_UNK      -1
+#define MPD_ERROR_AT_UNK       -1
+
+#define MPD_ACK_ERROR_NOT_LIST                 1
+#define MPD_ACK_ERROR_ARG                      2
+#define MPD_ACK_ERROR_PASSWORD                 3
+#define MPD_ACK_ERROR_PERMISSION               4
+#define MPD_ACK_ERROR_UNKNOWN_CMD              5
+
+#define MPD_ACK_ERROR_NO_EXIST                 50
+#define MPD_ACK_ERROR_PLAYLIST_MAX             51
+#define MPD_ACK_ERROR_SYSTEM                   52
+#define MPD_ACK_ERROR_PLAYLIST_LOAD            53
+#define MPD_ACK_ERROR_UPDATE_ALREADY           54
+#define MPD_ACK_ERROR_PLAYER_SYNC              55
+#define MPD_ACK_ERROR_EXIST                    56
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* internal stuff don't touch this struct */
+       typedef struct _mpd_ReturnElement {
+               char *name;
+               char *value;
+       } mpd_ReturnElement;
+
+/* mpd_Connection
+ * holds info about connection to mpd
+ * use error, and errorStr to detect errors
+ */
+       typedef struct _mpd_Connection {
+               /* use this to check the version of mpd */
+               int version[3];
+               /* IMPORTANT, you want to get the error messages from here */
+               char errorStr[MPD_BUFFER_MAX_LENGTH + 1];
+               int errorCode;
+               int errorAt;
+               /* this will be set to MPD_ERROR_* if there is an error, 0 if not */
+               int error;
+               /* DON'T TOUCH any of the rest of this stuff */
+               int sock;
+               char buffer[MPD_BUFFER_MAX_LENGTH + 1];
+               int buflen;
+               int bufstart;
+               int doneProcessing;
+               int listOks;
+               int doneListOk;
+               int commandList;
+               mpd_ReturnElement *returnElement;
+               struct timeval timeout;
+       } mpd_Connection;
+
+/* mpd_newConnection
+ * use this to open a new connection
+ * you should use mpd_closeConnection, when your done with the connection,
+ * even if an error has occurred
+ * _timeout_ is the connection timeout period in seconds
+ */
+       mpd_Connection *mpd_newConnection(const char *host, int port,
+                                         float timeout);
+
+       void mpd_setConnectionTimeout(mpd_Connection * connection,
+                                     float timeout);
+
+/* mpd_closeConnection
+ * use this to close a connection and free'ing subsequent memory
+ */
+       void mpd_closeConnection(mpd_Connection * connection);
+
+/* mpd_clearError
+ * clears error
+ */
+       void mpd_clearError(mpd_Connection * connection);
+
+/* STATUS STUFF */
+
+/* use these with status.state to determine what state the player is in */
+#define MPD_STATUS_STATE_UNKNOWN       0
+#define MPD_STATUS_STATE_STOP          1
+#define MPD_STATUS_STATE_PLAY          2
+#define MPD_STATUS_STATE_PAUSE         3
+
+/* us this with status.volume to determine if mpd has volume support */
+#define MPD_STATUS_NO_VOLUME           -1
+
+/* mpd_Status
+ * holds info return from status command
+ */
+       typedef struct mpd_Status {
+               /* 0-100, or MPD_STATUS_NO_VOLUME when there is no volume support */
+               int volume;
+               /* 1 if repeat is on, 0 otherwise */
+               int repeat;
+               /* 1 if random is on, 0 otherwise */
+               int random;
+               /* playlist length */
+               int playlistLength;
+               /* playlist, use this to determine when the playlist has changed */
+               long long playlist;
+               /* use with MPD_STATUS_STATE_* to determine state of player */
+               int state;
+               /* crossfade setting in seconds */
+               int crossfade;
+               /* if a song is currently selected (always the case when state is
+                * PLAY or PAUSE), this is the position of the currently
+                * playing song in the playlist, beginning with 0
+                */
+               int song;
+               /* Song ID of the currently selected song */
+               int songid;
+               /* time in seconds that have elapsed in the currently playing/paused
+                * song
+                */
+               int elapsedTime;
+               /* length in seconds of the currently playing/paused song */
+               int totalTime;
+               /* current bit rate in kbs */
+               int bitRate;
+               /* audio sample rate */
+               unsigned int sampleRate;
+               /* audio bits */
+               int bits;
+               /* audio channels */
+               int channels;
+               /* 1 if mpd is updating, 0 otherwise */
+               int updatingDb;
+               /* error */
+               char *error;
+       } mpd_Status;
+
+       void mpd_sendStatusCommand(mpd_Connection * connection);
+
+/* mpd_getStatus
+ * returns status info, be sure to free it with mpd_freeStatus()
+ * call this after mpd_sendStatusCommand()
+ */
+       mpd_Status *mpd_getStatus(mpd_Connection * connection);
+
+/* mpd_freeStatus
+ * free's status info malloc'd and returned by mpd_getStatus
+ */
+       void mpd_freeStatus(mpd_Status * status);
+
+       typedef struct _mpd_Stats {
+               int numberOfArtists;
+               int numberOfAlbums;
+               int numberOfSongs;
+               unsigned long uptime;
+               unsigned long dbUpdateTime;
+               unsigned long playTime;
+               unsigned long dbPlayTime;
+       } mpd_Stats;
+
+       void mpd_sendStatsCommand(mpd_Connection * connection);
+
+       mpd_Stats *mpd_getStats(mpd_Connection * connection);
+
+       void mpd_freeStats(mpd_Stats * stats);
+
+/* SONG STUFF */
+
+#define MPD_SONG_NO_TIME       -1
+#define MPD_SONG_NO_NUM                -1
+#define MPD_SONG_NO_ID         -1
+
+/* mpd_Song
+ * for storing song info returned by mpd
+ */
+       typedef struct _mpd_Song {
+               /* filename of song */
+               char *file;
+               /* artist, maybe NULL if there is no tag */
+               char *artist;
+               /* title, maybe NULL if there is no tag */
+               char *title;
+               /* album, maybe NULL if there is no tag */
+               char *album;
+               /* track, maybe NULL if there is no tag */
+               char *track;
+               /* name, maybe NULL if there is no tag; it's the name of the current
+                * song, f.e. the icyName of the stream */
+               char *name;
+               /* length of song in seconds, check that it is not MPD_SONG_NO_TIME  */
+               int time;
+               /* if plchanges/playlistinfo/playlistid used, is the position of the 
+                * song in the playlist */
+               int pos;
+               /* song id for a song in the playlist */
+               int id;
+       } mpd_Song;
+
+/* mpd_newSong
+ * use to allocate memory for a new mpd_Song
+ * file, artist, etc all initialized to NULL
+ * if your going to assign values to file, artist, etc
+ * be sure to malloc or strdup the memory
+ * use mpd_freeSong to free the memory for the mpd_Song, it will also
+ * free memory for file, artist, etc, so don't do it yourself
+ */
+       mpd_Song *mpd_newSong();
+
+/* mpd_freeSong
+ * use to free memory allocated by mpd_newSong
+ * also it will free memory pointed to by file, artist, etc, so be careful
+ */
+       void mpd_freeSong(mpd_Song * song);
+
+/* mpd_songDup
+ * works like strDup, but for a mpd_Song
+ */
+       mpd_Song *mpd_songDup(mpd_Song * song);
+
+/* DIRECTORY STUFF */
+
+/* mpd_Directory
+ * used to store info fro directory (right now that just the path)
+ */
+       typedef struct _mpd_Directory {
+               char *path;
+       } mpd_Directory;
+
+/* mpd_newDirectory
+ * allocates memory for a new directory
+ * use mpd_freeDirectory to free this memory
+ */
+       mpd_Directory *mpd_newDirectory();
+
+/* mpd_freeDirectory
+ * used to free memory allocated with mpd_newDirectory, and it frees
+ * path of mpd_Directory, so be careful
+ */
+       void mpd_freeDirectory(mpd_Directory * directory);
+
+/* mpd_directoryDup
+ * works like strdup, but for mpd_Directory
+ */
+       mpd_Directory *mpd_directoryDup(mpd_Directory * directory);
+
+/* PLAYLISTFILE STUFF */
+
+/* mpd_PlaylistFile
+ * stores info about playlist file returned by lsinfo
+ */
+       typedef struct _mpd_PlaylistFile {
+               char *path;
+       } mpd_PlaylistFile;
+
+/* mpd_newPlaylistFile
+ * allocates memory for new mpd_PlaylistFile, path is set to NULL
+ * free this memory with mpd_freePlaylistFile
+ */
+       mpd_PlaylistFile *mpd_newPlaylistFile();
+
+/* mpd_freePlaylist
+ * free memory allocated for freePlaylistFile, will also free
+ * path, so be careful
+ */
+       void mpd_freePlaylistFile(mpd_PlaylistFile * playlist);
+
+/* mpd_playlistFileDup
+ * works like strdup, but for mpd_PlaylistFile
+ */
+       mpd_PlaylistFile *mpd_playlistFileDup(mpd_PlaylistFile * playlist);
+
+/* INFO ENTITY STUFF */
+
+/* the type of entity returned from one of the commands that generates info
+ * use in conjunction with mpd_InfoEntity.type
+ */
+#define MPD_INFO_ENTITY_TYPE_DIRECTORY         0
+#define MPD_INFO_ENTITY_TYPE_SONG              1
+#define MPD_INFO_ENTITY_TYPE_PLAYLISTFILE      2
+
+/* mpd_InfoEntity
+ * stores info on stuff returned info commands
+ */
+       typedef struct mpd_InfoEntity {
+               /* the type of entity, use with MPD_INFO_ENTITY_TYPE_* to determine
+                * what this entity is (song, directory, etc...)
+                */
+               int type;
+               /* the actual data you want, mpd_Song, mpd_Directory, etc */
+               union {
+                       mpd_Directory *directory;
+                       mpd_Song *song;
+                       mpd_PlaylistFile *playlistFile;
+               } info;
+       } mpd_InfoEntity;
+
+       mpd_InfoEntity *mpd_newInfoEntity();
+
+       void mpd_freeInfoEntity(mpd_InfoEntity * entity);
+
+/* INFO COMMANDS AND STUFF */
+
+/* use this function to loop over after calling Info/Listall functions */
+       mpd_InfoEntity *mpd_getNextInfoEntity(mpd_Connection * connection);
+
+/* fetches the currently seeletect song (the song referenced by status->song
+ * and status->songid*/
+       void mpd_sendCurrentSongCommand(mpd_Connection * connection);
+
+/* songNum of -1, means to display the whole list */
+       void mpd_sendPlaylistInfoCommand(mpd_Connection * connection,
+                                        int songNum);
+
+/* use this to get the changes in the playlist since version _playlist_ */
+       void mpd_sendPlChangesCommand(mpd_Connection * connection,
+                                     long long playlist);
+
+/* recursivel fetches all songs/dir/playlists in "dir* (no metadata is 
+ * returned) */
+       void mpd_sendListallCommand(mpd_Connection * connection,
+                                   const char *dir);
+
+/* same as sendListallCommand, but also metadata is returned */
+       void mpd_sendListallInfoCommand(mpd_Connection * connection,
+                                       const char *dir);
+
+/* non-recursive version of ListallInfo */
+       void mpd_sendLsInfoCommand(mpd_Connection * connection,
+                                  const char *dir);
+
+#define MPD_TABLE_ARTIST       0
+#define MPD_TABLE_ALBUM                1
+#define MPD_TABLE_TITLE                2
+#define MPD_TABLE_FILENAME     3
+
+       void mpd_sendSearchCommand(mpd_Connection * connection, int table,
+                                  const char *str);
+
+       void mpd_sendFindCommand(mpd_Connection * connection, int table,
+                                const char *str);
+
+/* LIST TAG COMMANDS */
+
+/* use this function fetch next artist entry, be sure to free the returned 
+ * string.  NULL means there are no more.  Best used with sendListArtists
+ */
+       char *mpd_getNextArtist(mpd_Connection * connection);
+
+       char *mpd_getNextAlbum(mpd_Connection * connection);
+
+/* list artist or albums by artist, arg1 should be set to the artist if
+ * listing albums by a artist, otherwise NULL for listing all artists or albums
+ */
+       void mpd_sendListCommand(mpd_Connection * connection, int table,
+                                const char *arg1);
+
+/* SIMPLE COMMANDS */
+
+       void mpd_sendAddCommand(mpd_Connection * connection,
+                               const char *file);
+
+       void mpd_sendDeleteCommand(mpd_Connection * connection,
+                                  int songNum);
+
+       void mpd_sendDeleteIdCommand(mpd_Connection * connection,
+                                    int songNum);
+
+       void mpd_sendSaveCommand(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_sendShuffleCommand(mpd_Connection * connection);
+
+       void mpd_sendClearCommand(mpd_Connection * connection);
+
+/* use this to start playing at the beginning, useful when in random mode */
+#define MPD_PLAY_AT_BEGINNING  -1
+
+       void mpd_sendPlayCommand(mpd_Connection * connection, int songNum);
+
+       void mpd_sendPlayIdCommand(mpd_Connection * connection,
+                                  int songNum);
+
+       void mpd_sendStopCommand(mpd_Connection * connection);
+
+       void mpd_sendPauseCommand(mpd_Connection * connection,
+                                 int pauseMode);
+
+       void mpd_sendNextCommand(mpd_Connection * connection);
+
+       void mpd_sendPrevCommand(mpd_Connection * connection);
+
+       void mpd_sendMoveCommand(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_sendSwapIdCommand(mpd_Connection * connection, int song1,
+                                  int song2);
+
+       void mpd_sendSeekCommand(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_sendRandomCommand(mpd_Connection * connection,
+                                  int randomMode);
+
+       void mpd_sendSetvolCommand(mpd_Connection * connection,
+                                  int volumeChange);
+
+/* WARNING: don't use volume command, its depreacted */
+       void mpd_sendVolumeCommand(mpd_Connection * connection,
+                                  int volumeChange);
+
+       void mpd_sendCrossfadeCommand(mpd_Connection * connection,
+                                     int seconds);
+
+       void mpd_sendUpdateCommand(mpd_Connection * connection,
+                                  char *path);
+
+/* returns the update job id, call this after a update command*/
+       int mpd_getUpdateId(mpd_Connection * connection);
+
+       void mpd_sendPasswordCommand(mpd_Connection * connection,
+                                    const char *pass);
+
+/* after executing a command, when your done with it to get its status
+ * (you want to check connection->error for an error)
+ */
+       void mpd_finishCommand(mpd_Connection * connection);
+
+/* command list stuff, use this to do things like add files very quickly */
+       void mpd_sendCommandListBegin(mpd_Connection * connection);
+
+       void mpd_sendCommandListOkBegin(mpd_Connection * connection);
+
+       void mpd_sendCommandListEnd(mpd_Connection * connection);
+
+/* advance to the next listOk 
+ * returns 0 if advanced to the next list_OK,
+ * returns -1 if it advanced to an OK or ACK */
+       int mpd_nextListOkCommand(mpd_Connection * connection);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/linux.c b/src/linux.c
new file mode 100644 (file)
index 0000000..561ca01
--- /dev/null
@@ -0,0 +1,1067 @@
+/* linux.c
+ * Contains linux specific code
+ *
+ *  $Id$
+ */
+
+
+#include "conky.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/sysinfo.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+// #include <assert.h>
+#include <time.h>
+#include "top.h"
+
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <linux/sockios.h>
+#include <net/if.h>
+#include <math.h>
+
+
+static struct sysinfo s_info;
+
+static int show_nice_processes;
+
+void prepare_update()
+{
+}
+
+static void update_sysinfo()
+{
+       sysinfo(&s_info);
+
+       info.uptime = (double) s_info.uptime;
+
+       /* there was some problem with these */
+#if 0
+//      info.loadavg[0] = s_info.loads[0] / 100000.0f;
+       info.loadavg[1] = s_info.loads[1] / 100000.0f;
+       info.loadavg[2] = s_info.loads[2] / 100000.0f;
+       gkrelltop_process_find_top_three info.mask |= 1 << INFO_LOADAVG;
+#endif
+
+       info.procs = s_info.procs;
+
+       /* these aren't nice, no cache and should check kernel version for mem_unit */
+#if 0
+       info.memmax = s_info.totalram;
+       info.mem = s_info.totalram - s_info.freeram;
+       info.swapmax = s_info.totalswap;
+       info.swap = s_info.totalswap - s_info.swap;
+       info.mask |= 1 << INFO_MEM;
+#endif
+
+       info.mask |= (1 << INFO_UPTIME) | (1 << INFO_PROCS);
+}
+
+void update_uptime()
+{
+       /* prefers sysinfo() for uptime, I don't really know which one is better
+        * (=faster?) */
+#ifdef USE_PROC_UPTIME
+       static int rep;
+       FILE *fp = open_file("/proc/uptime", &rep);
+       if (!fp)
+               return 0;
+       fscanf(fp, "%lf", &info.uptime);
+       fclose(fp);
+
+       info.mask |= (1 << INFO_UPTIME);
+#else
+       update_sysinfo();
+#endif
+}
+
+/* these things are also in sysinfo except Buffers:, that's why I'm reading
+* them from proc */
+
+static FILE *meminfo_fp;
+
+void update_meminfo()
+{
+       static int rep;
+       /*  unsigned int a; */
+       char buf[256];
+
+       info.mem = info.memmax = info.swap = info.swapmax = info.bufmem =
+           info.buffers = info.cached = 0;
+
+       if (meminfo_fp == NULL)
+               meminfo_fp = open_file("/proc/meminfo", &rep);
+       else
+               fseek(meminfo_fp, 0, SEEK_SET);
+       if (meminfo_fp == NULL)
+               return;
+
+       while (!feof(meminfo_fp)) {
+               if (fgets(buf, 255, meminfo_fp) == NULL)
+                       break;
+
+               if (strncmp(buf, "MemTotal:", 9) == 0) {
+                       sscanf(buf, "%*s %u", &info.memmax);
+               } else if (strncmp(buf, "MemFree:", 8) == 0) {
+                       sscanf(buf, "%*s %u", &info.mem);
+               } else if (strncmp(buf, "SwapTotal:", 10) == 0) {
+                       sscanf(buf, "%*s %u", &info.swapmax);
+               } else if (strncmp(buf, "SwapFree:", 9) == 0) {
+                       sscanf(buf, "%*s %u", &info.swap);
+               } else if (strncmp(buf, "Buffers:", 8) == 0) {
+                       sscanf(buf, "%*s %u", &info.buffers);
+               } else if (strncmp(buf, "Cached:", 7) == 0) {
+                       sscanf(buf, "%*s %u", &info.cached);
+               }
+       }
+
+       info.mem = info.memmax - info.mem;
+       info.swap = info.swapmax - info.swap;
+
+       info.bufmem = info.cached + info.buffers;
+
+       info.mask |= (1 << INFO_MEM) | (1 << INFO_BUFFERS);
+}
+
+static FILE *net_dev_fp;
+static FILE *net_wireless_fp;
+
+inline void update_net_stats()
+{
+       static int rep;
+       // FIXME: arbitrary size chosen to keep code simple.
+       int i, i2;
+       unsigned int curtmp1, curtmp2;
+       unsigned int k;
+       struct ifconf conf;
+
+
+       char buf[256];
+       double delta;
+
+       /* get delta */
+       delta = current_update_time - last_update_time;
+       if (delta <= 0.0001)
+               return;
+
+       /* open file and ignore first two lines */
+       if (net_dev_fp == NULL)
+               net_dev_fp = open_file("/proc/net/dev", &rep);
+       else
+               fseek(net_dev_fp, 0, SEEK_SET);
+       if (!net_dev_fp)
+               return;
+
+       fgets(buf, 255, net_dev_fp);    /* garbage */
+       fgets(buf, 255, net_dev_fp);    /* garbage (field names) */
+
+       /* read each interface */
+       for (i2 = 0; i2 < 16; i2++) {
+               struct net_stat *ns;
+               char *s, *p;
+               long long r, t, last_recv, last_trans;
+
+               if (fgets(buf, 255, net_dev_fp) == NULL)
+                       break;
+               p = buf;
+               while (isspace((int) *p))
+                       p++;
+
+               s = p;
+
+               while (*p && *p != ':')
+                       p++;
+               if (*p == '\0')
+                       continue;
+               *p = '\0';
+               p++;
+
+               ns = get_net_stat(s);
+               ns->up = 1;
+               last_recv = ns->recv;
+               last_trans = ns->trans;
+
+               sscanf(p,
+                      /* bytes packets errs drop fifo frame compressed multicast|bytes ... */
+                      "%Ld  %*d     %*d  %*d  %*d  %*d   %*d        %*d       %Ld",
+                      &r, &t);
+
+               /* if recv or trans is less than last time, an overflow happened */
+
+               if (r < ns->last_read_recv)
+                       ns->recv +=
+                           ((long long) 4294967295U -
+                            ns->last_read_recv) + r;
+               else
+                       ns->recv += (r - ns->last_read_recv);
+               ns->last_read_recv = r;
+
+               if (t < ns->last_read_trans)
+                       ns->trans +=
+                           ((long long) 4294967295U -
+                            ns->last_read_trans) + t;
+               else
+                       ns->trans += (t - ns->last_read_trans);
+               ns->last_read_trans = t;
+
+               /*** ip addr patch ***/
+               i = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
+
+               conf.ifc_buf = malloc(sizeof(struct ifreq) * 16);
+
+               conf.ifc_len = sizeof(struct ifreq) * 16;
+
+               ioctl((long) i, SIOCGIFCONF, &conf);
+
+               for (k = 0; k < conf.ifc_len / sizeof(struct ifreq); k++) {
+                       struct net_stat *ns;
+                       ns = get_net_stat(((struct ifreq *) conf.
+                                          ifc_buf)[k].ifr_ifrn.ifrn_name);
+                       ns->addr =
+                           ((struct ifreq *) conf.ifc_buf)[k].ifr_ifru.
+                           ifru_addr;
+               }
+
+               close((long) i);
+
+               free(conf.ifc_buf);
+
+
+               /*** end ip addr patch ***/
+
+
+               /* calculate speeds */
+               ns->net_rec[0] = (ns->recv - last_recv) / delta;
+               ns->net_trans[0] = (ns->trans - last_trans) / delta;
+               curtmp1 = 0;
+               curtmp2 = 0;
+               // get an average
+               for (i = 0; (unsigned) i < info.net_avg_samples; i++) {
+                       curtmp1 += ns->net_rec[i];
+                       curtmp2 += ns->net_trans[i];
+               }
+               ns->recv_speed = curtmp1 / (double) info.net_avg_samples;
+               ns->trans_speed = curtmp2 / (double) info.net_avg_samples;
+               if (info.net_avg_samples > 1) {
+                       for (i = info.net_avg_samples; i > 1; i--) {
+                               ns->net_rec[i - 1] = ns->net_rec[i - 2];
+                               ns->net_trans[i - 1] =
+                                   ns->net_trans[i - 2];
+                       }
+               }
+
+
+
+       }
+
+       /* fclose(net_dev_fp); net_dev_fp = NULL; */
+}
+
+inline void update_wifi_stats()
+{
+       /** wireless stats patch by Bobby Beckmann **/
+       static int rep;
+       int i;
+       char buf[256];
+       /*open file and ignore first two lines       sorry, this code sucks ass right now, i'll clean it up later */
+       if (net_wireless_fp == NULL)
+               net_wireless_fp = open_file("/proc/net/wireless", &rep);
+       else
+               fseek(net_wireless_fp, 0, SEEK_SET);
+       if (net_wireless_fp == NULL)
+               return;
+
+       fgets(buf, 255, net_wireless_fp);       /* garbage */
+       fgets(buf, 255, net_wireless_fp);       /* garbage (field names) */
+
+       /* read each interface */
+       for (i = 0; i < 16; i++) {
+               struct net_stat *ns;
+               char *s, *p;
+               int l, m, n;
+
+               if (fgets(buf, 255, net_wireless_fp) == NULL)
+                       break;
+               p = buf;
+               while (isspace((int) *p))
+                       p++;
+
+               s = p;
+
+               while (*p && *p != ':')
+                       p++;
+               if (*p == '\0')
+                       continue;
+               *p = '\0';
+               p++;
+
+               ns = get_net_stat(s);
+
+               sscanf(p, "%*d   %d.  %d.  %d", &l, &m, &n);
+
+               ns->linkstatus = (int) (log(l) / log(92) * 100);
+       }
+
+       /*** end wireless patch ***/
+}
+
+int result;
+
+void update_total_processes()
+{
+       update_sysinfo();
+}
+
+static unsigned int cpu_user, cpu_system, cpu_nice;
+static double last_cpu_sum;
+static int clock_ticks;
+
+static FILE *stat_fp;
+
+inline static void update_stat()
+{
+       // FIXME: arbitrary size?
+       static double cpu_val[15];
+       static int rep;
+       char buf[256];
+       unsigned int i;
+       double curtmp;
+
+       if (stat_fp == NULL)
+               stat_fp = open_file("/proc/stat", &rep);
+       else
+               fseek(stat_fp, 0, SEEK_SET);
+       if (stat_fp == NULL)
+               return;
+
+       info.cpu_count = 0;
+
+       while (!feof(stat_fp)) {
+               if (fgets(buf, 255, stat_fp) == NULL)
+                       break;
+
+               if (strncmp(buf, "procs_running ", 14) == 0) {
+                       sscanf(buf, "%*s %d", &info.run_procs);
+                       info.mask |= (1 << INFO_RUN_PROCS);
+               } else if (strncmp(buf, "cpu ", 4) == 0) {
+                       sscanf(buf, "%*s %u %u %u", &cpu_user, &cpu_nice,
+                              &cpu_system);
+                       info.mask |= (1 << INFO_CPU);
+               } else if (strncmp(buf, "cpu", 3) == 0 && isdigit(buf[3])) {
+                       info.cpu_count++;
+               }
+       }
+
+       {
+               double delta;
+               delta = current_update_time - last_update_time;
+               if (delta <= 0.001)
+                       return;
+
+               if (clock_ticks == 0)
+                       clock_ticks = sysconf(_SC_CLK_TCK);
+               curtmp = 0;
+               cpu_val[0] =
+                   (cpu_user + cpu_nice + cpu_system -
+                    last_cpu_sum) / delta / (double) clock_ticks /
+                   info.cpu_count;
+               for (i = 0; i < info.cpu_avg_samples; i++)
+                       curtmp += cpu_val[i];
+               info.cpu_usage = curtmp / info.cpu_avg_samples;
+               last_cpu_sum = cpu_user + cpu_nice + cpu_system;
+               for (i = info.cpu_avg_samples; i > 1; i--)
+                       cpu_val[i - 1] = cpu_val[i - 2];
+
+       }
+
+// test code
+// this is for getting proc shit
+// pee pee
+// poo
+       //
+
+
+
+
+
+
+}
+
+void update_running_processes()
+{
+       update_stat();
+}
+
+void update_cpu_usage()
+{
+       update_stat();
+}
+
+void update_load_average()
+{
+#ifdef HAVE_GETLOADAVG
+       double v[3];
+       getloadavg(v, 3);
+       info.loadavg[0] = (float) v[0];
+       info.loadavg[1] = (float) v[1];
+       info.loadavg[2] = (float) v[2];
+#else
+       static int rep;
+       FILE *fp;
+
+       fp = open_file("/proc/loadavg", &rep);
+       if (!fp) {
+               v[0] = v[1] = v[2] = 0.0;
+               return;
+       }
+
+       fscanf(fp, "%f %f %f", &info.loadavg[0], &info.loadavg[1],
+              &info.loadavg[2]);
+
+       fclose(fp);
+#endif
+}
+
+
+static int no_dots(const struct dirent *d)
+{
+       if (d->d_name[0] == '.')
+               return 0;
+       return 1;
+}
+
+static int
+get_first_file_in_a_directory(const char *dir, char *s, int *rep)
+{
+       struct dirent **namelist;
+       int i, n;
+
+       n = scandir(dir, &namelist, no_dots, alphasort);
+       if (n < 0) {
+               if (!rep || !*rep) {
+                       ERR("scandir for %s: %s", dir, strerror(errno));
+                       if (rep)
+                               *rep = 1;
+               }
+               return 0;
+       } else {
+               if (n == 0)
+                       return 0;
+
+               strncpy(s, namelist[0]->d_name, 255);
+               s[255] = '\0';
+
+               for (i = 0; i < n; i++)
+                       free(namelist[i]);
+               free(namelist);
+
+               return 1;
+       }
+}
+
+#define I2C_DIR "/sys/bus/i2c/devices/"
+
+int
+open_i2c_sensor(const char *dev, const char *type, int n, int *div,
+               char *devtype)
+{
+       char path[256];
+       char buf[64];
+       int fd;
+       int divfd;
+
+       /* if i2c device is NULL or *, get first */
+       if (dev == NULL || strcmp(dev, "*") == 0) {
+               static int rep;
+               if (!get_first_file_in_a_directory(I2C_DIR, buf, &rep))
+                       return -1;
+               dev = buf;
+       }
+
+       /* change vol to in */
+       if (strcmp(type, "vol") == 0)
+               type = "in";
+
+       if (strcmp(type, "tempf") == 0) {
+               snprintf(path, 255, I2C_DIR "%s/%s%d_input", dev, "temp",
+                        n);
+       } else {
+               snprintf(path, 255, I2C_DIR "%s/%s%d_input", dev, type, n);
+       }
+       strcpy(devtype, path);
+
+       /* open file */
+       fd = open(path, O_RDONLY);
+       if (fd < 0) {
+               CRIT_ERR("can't open '%s': %s\nplease fix i2c or remove it from Conky", path, strerror(errno));
+       }
+
+       if (strcmp(type, "in") == 0 || strcmp(type, "temp") == 0
+           || strcmp(type, "tempf") == 0)
+               *div = 1;
+       else
+               *div = 0;
+       /* fan does not use *_div as a read divisor */
+       if (strcmp("fan", type) == 0)
+               return fd;
+
+       /* test if *_div file exist, open it and use it as divisor */
+       if (strcmp(type, "tempf") == 0) {
+               snprintf(path, 255, I2C_DIR "%s/%s%d_div", "one", "two",
+                        n);
+       } else {
+               snprintf(path, 255, I2C_DIR "%s/%s%d_div", dev, type, n);
+       }
+
+       divfd = open(path, O_RDONLY);
+       if (divfd > 0) {
+               /* read integer */
+               char divbuf[64];
+               unsigned int divn;
+               divn = read(divfd, divbuf, 63);
+               /* should read until n == 0 but I doubt that kernel will give these
+                * in multiple pieces. :) */
+               divbuf[divn] = '\0';
+               *div = atoi(divbuf);
+       }
+
+       close(divfd);
+
+       return fd;
+}
+
+double get_i2c_info(int *fd, int div, char *devtype, char *type)
+{
+       int val = 0;
+
+       if (*fd <= 0)
+               return 0;
+
+       lseek(*fd, 0, SEEK_SET);
+
+       /* read integer */
+       {
+               char buf[64];
+               unsigned int n;
+               n = read(*fd, buf, 63);
+               /* should read until n == 0 but I doubt that kernel will give these
+                * in multiple pieces. :) */
+               buf[n] = '\0';
+               val = atoi(buf);
+       }
+
+       close(*fd);
+       /* open file */
+       *fd = open(devtype, O_RDONLY);
+       if (*fd < 0)
+               ERR("can't open '%s': %s", devtype, strerror(errno));
+
+       /* My dirty hack for computing CPU value 
+        * Filedil, from forums.gentoo.org
+        */
+/*     if (strstr(devtype, "temp1_input") != NULL)
+       return -15.096+1.4893*(val / 1000.0); */
+
+
+       /* divide voltage and temperature by 1000 */
+       /* or if any other divisor is given, use that */
+       if (strcmp(type, "tempf") == 0) {
+               if (div > 1)
+                       return ((val / div + 40) * 9.0 / 5) - 40;
+               else if (div)
+                       return ((val / 1000.0 + 40) * 9.0 / 5) - 40;
+               else
+                       return ((val + 40) * 9.0 / 5) - 40;
+       } else {
+               if (div > 1)
+                       return val / div;
+               else if (div)
+                       return val / 1000.0;
+               else
+                       return val;
+       }
+}
+
+#define ADT746X_FAN "/sys/devices/temperatures/cpu_fan_speed"
+
+static char *adt746x_fan_state;
+
+char *get_adt746x_fan()
+{
+       static int rep;
+       FILE *fp;
+
+       if (adt746x_fan_state == NULL) {
+               adt746x_fan_state = (char *) malloc(100);
+               assert(adt746x_fan_state != NULL);
+       }
+
+       fp = open_file(ADT746X_FAN, &rep);
+       if (!fp) {
+               strcpy(adt746x_fan_state,
+                      "No fan found! Hey, you don't have one?");
+               return adt746x_fan_state;
+       }
+       fscanf(fp, "%s", adt746x_fan_state);
+       fclose(fp);
+
+       return adt746x_fan_state;
+}
+
+#define ADT746X_CPU "/sys/devices/temperatures/cpu_temperature"
+
+static char *adt746x_cpu_state;
+
+char *get_adt746x_cpu()
+{
+       static int rep;
+       FILE *fp;
+
+       if (adt746x_cpu_state == NULL) {
+               adt746x_cpu_state = (char *) malloc(100);
+               assert(adt746x_cpu_state != NULL);
+       }
+
+       fp = open_file(ADT746X_CPU, &rep);
+       fscanf(fp, "%2s", adt746x_cpu_state);
+       fclose(fp);
+
+       return adt746x_cpu_state;
+}
+
+/* Thanks to "Walt Nelson" <wnelsonjr@comcast.net> */
+
+/***********************************************************************/
+/*
+ *  This file is part of x86info.
+ *  (C) 2001 Dave Jones.
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *
+ * Estimate CPU MHz routine by Andrea Arcangeli <andrea@suse.de>
+ * Small changes by David Sterba <sterd9am@ss1000.ms.mff.cuni.cz>
+ *
+ */
+#if  defined(__i386) || defined(__x86_64)
+__inline__ unsigned long long int rdtsc()
+{
+       unsigned long long int x;
+       __asm__ volatile (".byte 0x0f, 0x31":"=A" (x));
+       return x;
+}
+static char *buffer = NULL;
+#else
+static char *frequency;
+#endif
+
+char *get_freq()
+{
+#if  defined(__i386) || defined(__x86_64)
+       if (buffer == NULL)
+               buffer = malloc(64);
+       struct timezone tz;
+       struct timeval tvstart, tvstop;
+       unsigned long long cycles[2];   /* gotta be 64 bit */
+       unsigned int microseconds;      /* total time taken */
+
+       memset(&tz, 0, sizeof(tz));
+
+       /* get this function in cached memory */
+       gettimeofday(&tvstart, &tz);
+       cycles[0] = rdtsc();
+       gettimeofday(&tvstart, &tz);
+
+       /* we don't trust that this is any specific length of time */
+       usleep(100);
+       cycles[1] = rdtsc();
+       gettimeofday(&tvstop, &tz);
+       microseconds = ((tvstop.tv_sec - tvstart.tv_sec) * 1000000) +
+           (tvstop.tv_usec - tvstart.tv_usec);
+
+       sprintf(buffer, "%lld", (cycles[1] - cycles[0]) / microseconds);
+
+       return buffer;
+#else
+       FILE *f;
+       char s[1000];
+       if (frequency == NULL) {
+               frequency = (char *) malloc(100);
+               assert(frequency != NULL);
+       }
+       //char frequency[10];
+       f = fopen("/proc/cpuinfo", "r");        //open the CPU information file
+       //if (!f)
+       //    return;
+       while (fgets(s, 1000, f) != NULL){      //read the file
+               if (strncmp(s, "clock", 5) == 0) {      //and search for the cpu mhz
+                       //printf("%s", strchr(s, ':')+2);
+               strcpy(frequency, strchr(s, ':') + 2);  //copy just the number
+               frequency[strlen(frequency) - 1] = '\0';        // strip \n
+               break;
+               }
+       }
+               fclose(f);
+               //printf("%s\n", frequency);
+               return frequency;
+#endif
+}
+
+
+#define ACPI_FAN_DIR "/proc/acpi/fan/"
+
+static char *acpi_fan_state;
+
+char *get_acpi_fan()
+{
+       static int rep;
+       char buf[256];
+       char buf2[256];
+       FILE *fp;
+
+       if (acpi_fan_state == NULL) {
+               acpi_fan_state = (char *) malloc(100);
+               assert(acpi_fan_state != NULL);
+       }
+
+       /* yeah, slow... :/ */
+       if (!get_first_file_in_a_directory(ACPI_FAN_DIR, buf, &rep))
+               return "no fans?";
+
+       snprintf(buf2, 256, "%s%s/state", ACPI_FAN_DIR, buf);
+
+       fp = open_file(buf2, &rep);
+       if (!fp) {
+               strcpy(acpi_fan_state, "can't open fan's state file");
+               return acpi_fan_state;
+       }
+       fscanf(fp, "%*s %99s", acpi_fan_state);
+
+       return acpi_fan_state;
+}
+
+#define ACPI_AC_ADAPTER_DIR "/proc/acpi/ac_adapter/"
+
+static char *acpi_ac_adapter_state;
+
+char *get_acpi_ac_adapter()
+{
+       static int rep;
+       char buf[256];
+       char buf2[256];
+       FILE *fp;
+
+       if (acpi_ac_adapter_state == NULL) {
+               acpi_ac_adapter_state = (char *) malloc(100);
+               assert(acpi_ac_adapter_state != NULL);
+       }
+
+       /* yeah, slow... :/ */
+       if (!get_first_file_in_a_directory(ACPI_AC_ADAPTER_DIR, buf, &rep))
+               return "no ac_adapters?";
+
+       snprintf(buf2, 256, "%s%s/state", ACPI_AC_ADAPTER_DIR, buf);
+
+       fp = open_file(buf2, &rep);
+       if (!fp) {
+               strcpy(acpi_ac_adapter_state,
+                      "No ac adapter found.... where is it?");
+               return acpi_ac_adapter_state;
+       }
+       fscanf(fp, "%*s %99s", acpi_ac_adapter_state);
+       fclose(fp);
+
+       return acpi_ac_adapter_state;
+}
+
+/*
+/proc/acpi/thermal_zone/THRM/cooling_mode
+cooling mode:            active
+/proc/acpi/thermal_zone/THRM/polling_frequency
+<polling disabled>
+/proc/acpi/thermal_zone/THRM/state
+state:                   ok
+/proc/acpi/thermal_zone/THRM/temperature
+temperature:             45 C
+/proc/acpi/thermal_zone/THRM/trip_points
+critical (S5):           73 C
+passive:                 73 C: tc1=4 tc2=3 tsp=40 devices=0xcdf6e6c0
+*/
+
+#define ACPI_THERMAL_DIR "/proc/acpi/thermal_zone/"
+#define ACPI_THERMAL_FORMAT "/proc/acpi/thermal_zone/%s/temperature"
+
+int open_acpi_temperature(const char *name)
+{
+       char path[256];
+       char buf[64];
+       int fd;
+
+       if (name == NULL || strcmp(name, "*") == 0) {
+               static int rep;
+               if (!get_first_file_in_a_directory
+                   (ACPI_THERMAL_DIR, buf, &rep))
+                       return -1;
+               name = buf;
+       }
+
+       snprintf(path, 255, ACPI_THERMAL_FORMAT, name);
+
+       fd = open(path, O_RDONLY);
+       if (fd < 0)
+               ERR("can't open '%s': %s", path, strerror(errno));
+
+       return fd;
+}
+
+static double last_acpi_temp;
+static double last_acpi_temp_time;
+
+double get_acpi_temperature(int fd)
+{
+       if (fd <= 0)
+               return 0;
+
+       /* don't update acpi temperature too often */
+       if (current_update_time - last_acpi_temp_time < 11.32) {
+               return last_acpi_temp;
+       }
+       last_acpi_temp_time = current_update_time;
+
+       /* seek to beginning */
+       lseek(fd, 0, SEEK_SET);
+
+       /* read */
+       {
+               char buf[256];
+               int n;
+               n = read(fd, buf, 255);
+               if (n < 0)
+                       ERR("can't read fd %d: %s", fd, strerror(errno));
+               else {
+                       buf[n] = '\0';
+                       sscanf(buf, "temperature: %lf", &last_acpi_temp);
+               }
+       }
+
+       return last_acpi_temp;
+}
+
+/*
+hipo@lepakko hipo $ cat /proc/acpi/battery/BAT1/info 
+present:                 yes
+design capacity:         4400 mAh
+last full capacity:      4064 mAh
+battery technology:      rechargeable
+design voltage:          14800 mV
+design capacity warning: 300 mAh
+design capacity low:     200 mAh
+capacity granularity 1:  32 mAh
+capacity granularity 2:  32 mAh
+model number:            02KT
+serial number:           16922
+battery type:            LION
+OEM info:                SANYO
+*/
+
+/*
+hipo@lepakko conky $ cat /proc/acpi/battery/BAT1/state
+present:                 yes
+capacity state:          ok
+charging state:          unknown
+present rate:            0 mA
+remaining capacity:      4064 mAh
+present voltage:         16608 mV
+*/
+
+/*
+2213<@jupet kellari ö> jupet@lagi-unstable:~$ cat /proc/apm 
+2213<@jupet kellari ö> 1.16 1.2 0x03 0x01 0xff 0x10 -1% -1 ?
+2213<@jupet kellari ö> (-1 ollee ei akkua kiinni, koska akku on pöydällä)
+2214<@jupet kellari ö> jupet@lagi-unstable:~$ cat /proc/apm 
+2214<@jupet kellari ö> 1.16 1.2 0x03 0x01 0x03 0x09 98% -1 ?
+
+2238<@jupet kellari ö> 1.16 1.2 0x03 0x00 0x00 0x01 100% -1 ? ilman verkkovirtaa
+2239<@jupet kellari ö> 1.16 1.2 0x03 0x01 0x00 0x01 99% -1 ? verkkovirralla
+
+2240<@jupet kellari ö> 1.16 1.2 0x03 0x01 0x03 0x09 100% -1 ? verkkovirralla ja monitori päällä
+2241<@jupet kellari ö> 1.16 1.2 0x03 0x00 0x00 0x01 99% -1 ? monitori päällä mutta ilman verkkovirtaa
+*/
+
+#define ACPI_BATTERY_BASE_PATH "/proc/acpi/battery"
+#define APM_PATH "/proc/apm"
+
+static FILE *acpi_bat_fp;
+static FILE *apm_bat_fp;
+
+static int acpi_last_full;
+
+static char last_battery_str[64];
+
+static double last_battery_time;
+
+void get_battery_stuff(char *buf, unsigned int n, const char *bat)
+{
+       static int rep, rep2;
+       char acpi_path[128];
+       snprintf(acpi_path, 127, ACPI_BATTERY_BASE_PATH "/%s/state", bat);
+
+       /* don't update battery too often */
+       if (current_update_time - last_battery_time < 29.5) {
+               snprintf(buf, n, "%s", last_battery_str);
+               return;
+       }
+       last_battery_time = current_update_time;
+
+       /* first try ACPI */
+
+       if (acpi_bat_fp == NULL && apm_bat_fp == NULL)
+               acpi_bat_fp = open_file(acpi_path, &rep);
+
+       if (acpi_bat_fp != NULL) {
+               int present_rate = -1;
+               int remaining_capacity = -1;
+               char charging_state[64];
+
+               /* read last full capacity if it's zero */
+               if (acpi_last_full == 0) {
+                       static int rep;
+                       char path[128];
+                       FILE *fp;
+                       snprintf(path, 127,
+                                ACPI_BATTERY_BASE_PATH "/%s/info", bat);
+                       fp = open_file(path, &rep);
+                       if (fp != NULL) {
+                               while (!feof(fp)) {
+                                       char b[256];
+                                       if (fgets(b, 256, fp) == NULL)
+                                               break;
+
+                                       if (sscanf
+                                           (b, "last full capacity: %d",
+                                            &acpi_last_full) != 0)
+                                               break;
+                               }
+
+                               fclose(fp);
+                       }
+               }
+
+               fseek(acpi_bat_fp, 0, SEEK_SET);
+
+               strcpy(charging_state, "unknown");
+
+               while (!feof(acpi_bat_fp)) {
+                       char buf[256];
+                       if (fgets(buf, 256, acpi_bat_fp) == NULL)
+                               break;
+
+                       /* let's just hope units are ok */
+                       if (buf[0] == 'c')
+                               sscanf(buf, "charging state: %63s",
+                                      charging_state);
+                       else if (buf[0] == 'p')
+                               sscanf(buf, "present rate: %d",
+                                      &present_rate);
+                       else if (buf[0] == 'r')
+                               sscanf(buf, "remaining capacity: %d",
+                                      &remaining_capacity);
+               }
+
+               /* charging */
+               if (strcmp(charging_state, "charging") == 0) {
+                       if (acpi_last_full != 0 && present_rate > 0) {
+                               strcpy(last_battery_str, "charging ");
+                               format_seconds(last_battery_str + 9,
+                                              63 - 9,
+                                              (acpi_last_full -
+                                               remaining_capacity) * 60 *
+                                              60 / present_rate);
+                       } else if (acpi_last_full != 0
+                                  && present_rate <= 0) {
+                               sprintf(last_battery_str, "charging %d%%",
+                                       remaining_capacity * 100 /
+                                       acpi_last_full);
+                       } else {
+                               strcpy(last_battery_str, "charging");
+                       }
+               }
+               /* discharging */
+               else if (strcmp(charging_state, "discharging") == 0) {
+                       if (present_rate > 0)
+                               format_seconds(last_battery_str, 63,
+                                              (remaining_capacity * 60 *
+                                               60) / present_rate);
+                       else
+                               sprintf(last_battery_str,
+                                       "discharging %d%%",
+                                       remaining_capacity * 100 /
+                                       acpi_last_full);
+               }
+               /* charged */
+               /* thanks to Lukas Zapletal <lzap@seznam.cz> */
+               else if (strcmp(charging_state, "charged") == 0) {
+                       if (acpi_last_full != 0
+                           && remaining_capacity != acpi_last_full)
+                               sprintf(last_battery_str, "charged %d%%",
+                                       remaining_capacity * 100 /
+                                       acpi_last_full);
+                       else
+                               strcpy(last_battery_str, "charged");
+               }
+               /* unknown, probably full / AC */
+               else {
+                       if (acpi_last_full != 0
+                           && remaining_capacity != acpi_last_full)
+                               sprintf(last_battery_str, "unknown %d%%",
+                                       remaining_capacity * 100 /
+                                       acpi_last_full);
+                       else
+                               strcpy(last_battery_str, "AC");
+               }
+       } else {
+               /* APM */
+               if (apm_bat_fp == NULL)
+                       apm_bat_fp = open_file(APM_PATH, &rep2);
+
+               if (apm_bat_fp != NULL) {
+                       int ac, status, flag, life;
+
+                       fscanf(apm_bat_fp,
+                              "%*s %*s %*x %x   %x       %x     %d%%",
+                              &ac, &status, &flag, &life);
+
+                       if (life == -1) {
+                               /* could check now that there is ac */
+                               snprintf(last_battery_str, 64, "AC");
+                       } else if (ac && life != 100) { /* could check that status==3 here? */
+                               snprintf(last_battery_str, 64,
+                                        "charging %d%%", life);
+                       } else {
+                               snprintf(last_battery_str, 64, "%d%%",
+                                        life);
+                       }
+
+                       /* it seemed to buffer it so file must be closed (or could use syscalls
+                        * directly but I don't feel like coding it now) */
+                       fclose(apm_bat_fp);
+                       apm_bat_fp = NULL;
+               }
+       }
+
+       snprintf(buf, n, "%s", last_battery_str);
+}
+
+void update_top()
+{
+       show_nice_processes = 1;
+       process_find_top(info.cpu, info.memu);
+}
diff --git a/src/mail.c b/src/mail.c
new file mode 100644 (file)
index 0000000..baf7741
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * Conky, a system monitor, based on torsmo
+ *
+ * This program is licensed under BSD license, read COPYING
+ *
+ *  $Id$
+ */
+
+#include "conky.h"
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <dirent.h>
+
+char *current_mail_spool;
+
+static time_t last_mail_mtime;
+static double last_mail_update;
+
+void update_mail_count()
+{
+       struct stat buf;
+
+       if (current_mail_spool == NULL)
+               return;
+
+       /* TODO: use that fine file modification notify on Linux 2.4 */
+
+       /* don't check mail so often (9.5s is minimum interval) */
+       if (current_update_time - last_mail_update < 9.5)
+               return;
+       else
+               last_mail_update = current_update_time;
+
+       if (stat(current_mail_spool, &buf)) {
+               static int rep;
+               if (!rep) {
+                       ERR("can't stat %s: %s", current_mail_spool,
+                           strerror(errno));
+                       rep = 1;
+               }
+               return;
+       }
+#if HAVE_DIRENT_H
+       /* maildir format */
+       if (S_ISDIR(buf.st_mode)) {
+               DIR *dir;
+               char *dirname;
+               struct dirent *dirent;
+               info.mail_count = 0;
+               info.new_mail_count = 0;
+
+               dirname =
+                   (char *) malloc(sizeof(char) *
+                                   (strlen(current_mail_spool) + 5));
+               if (!dirname) {
+                       ERR("malloc");
+                       return;
+               }
+               strcpy(dirname, current_mail_spool);
+               strcat(dirname, "/");
+               /* checking the cur subdirectory */
+               strcat(dirname, "cur");
+
+               dir = opendir(dirname);
+               if (!dir) {
+                       ERR("cannot open directory");
+                       free(dirname);
+                       return;
+               }
+               dirent = readdir(dir);
+               while (dirent) {
+                       /* . and .. are skipped */
+                       if (dirent->d_name[0] != '.') {
+                               info.mail_count++;
+                       }
+                       dirent = readdir(dir);
+               }
+               closedir(dir);
+
+               dirname[strlen(dirname) - 3] = '\0';
+               strcat(dirname, "new");
+
+               dir = opendir(dirname);
+               if (!dir) {
+                       ERR("cannot open directory");
+                       free(dirname);
+                       return;
+               }
+               dirent = readdir(dir);
+               while (dirent) {
+                       /* . and .. are skipped */
+                       if (dirent->d_name[0] != '.') {
+                               info.new_mail_count++;
+                               info.mail_count++;
+                       }
+                       dirent = readdir(dir);
+               }
+               closedir(dir);
+
+               free(dirname);
+               return;
+       }
+#endif
+       /* mbox format */
+
+
+       if (buf.st_mtime != last_mail_mtime) {
+               /* yippee, modification time has changed, let's read mail count! */
+               static int rep;
+               FILE *fp;
+               int reading_status = 0;
+
+               /* could lock here but I don't think it's really worth it because
+                * this isn't going to write mail spool */
+
+               info.new_mail_count = 0;
+               info.mail_count = 0;
+
+               fp = open_file(current_mail_spool, &rep);
+               if (!fp)
+                       return;
+
+               /* NOTE: adds mail as new if there isn't Status-field at all */
+
+               while (!feof(fp)) {
+                       char buf[128];
+                       if (fgets(buf, 128, fp) == NULL)
+                               break;
+
+                       if (strncmp(buf, "From ", 5) == 0) {
+                               /* ignore MAILER-DAEMON */
+                               if (strncmp(buf + 5, "MAILER-DAEMON ", 14)
+                                   != 0) {
+                                       info.mail_count++;
+
+                                       if (reading_status)
+                                               info.new_mail_count++;
+                                       else
+                                               reading_status = 1;
+                               }
+                       } else {
+                               if (reading_status
+                                   && strncmp(buf, "X-Mozilla-Status:",
+                                              17) == 0) {
+                                       /* check that mail isn't already read */
+                                       if (strchr(buf + 21, '0'))
+                                               info.new_mail_count++;
+
+                                       reading_status = 0;
+                                       continue;
+                               }
+                               if (reading_status
+                                   && strncmp(buf, "Status:", 7) == 0) {
+                                       /* check that mail isn't already read */
+                                       if (strchr(buf + 7, 'R') == NULL)
+                                               info.new_mail_count++;
+
+                                       reading_status = 0;
+                                       continue;
+                               }
+                       }
+
+                       /* skip until \n */
+                       while (strchr(buf, '\n') == NULL && !feof(fp))
+                               fgets(buf, 128, fp);
+               }
+
+               fclose(fp);
+
+               if (reading_status)
+                       info.new_mail_count++;
+
+               last_mail_mtime = buf.st_mtime;
+       }
+}
diff --git a/src/mixer.c b/src/mixer.c
new file mode 100644 (file)
index 0000000..7b4ce24
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Conky, a system monitor, based on torsmo
+ *
+ * This program is licensed under BSD license, read COPYING
+ *
+ *  $Id$
+ */
+
+#include "conky.h"
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#ifdef HAVE_LINUX_SOUNDCARD_H
+#include <linux/soundcard.h>
+#else
+#include <sys/soundcard.h>
+#endif                         /* HAVE_LINUX_SOUNDCARD_H */
+
+#define MIXER_DEV "/dev/mixer"
+
+static int mixer_fd;
+static const char *devs[] = SOUND_DEVICE_NAMES;
+
+int mixer_init(const char *name)
+{
+       unsigned int i;
+
+       if (name == 0 || name[0] == '\0')
+               name = "vol";
+
+       /* open mixer */
+       if (mixer_fd <= 0) {
+               mixer_fd = open(MIXER_DEV, O_RDONLY);
+               if (mixer_fd == -1) {
+                       ERR("can't open %s: %s", MIXER_DEV,
+                           strerror(errno));
+                       return -1;
+               }
+       }
+
+       for (i = 0; i < sizeof(devs) / sizeof(const char *); i++) {
+               if (strcasecmp(devs[i], name) == 0) {
+                       return i;
+               }
+       }
+
+       return -1;
+}
+
+static int mixer_get(int i)
+{
+       static char rep = 0;
+       int val = -1;
+
+       if (ioctl(mixer_fd, MIXER_READ(i), &val) == -1) {
+               if (!rep)
+                       ERR("mixer ioctl: %s", strerror(errno));
+               rep = 1;
+               return 0;
+       }
+       rep = 0;
+
+       return val;
+}
+
+int mixer_get_avg(int i)
+{
+       int v = mixer_get(i);
+       return ((v >> 8) + (v & 0xFF)) / 2;
+}
+
+int mixer_get_left(int i)
+{
+       return mixer_get(i) >> 8;
+}
+
+int mixer_get_right(int i)
+{
+       return mixer_get(i) & 0xFF;
+}
diff --git a/src/mldonkey.c b/src/mldonkey.c
new file mode 100644 (file)
index 0000000..8f4381a
--- /dev/null
@@ -0,0 +1,456 @@
+#include "conky.h"
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <arpa/inet.h>
+
+
+int64 buf_to_int(char *buf, int pos, int size);
+void int_to_buf(int64 i, char *buf, int pos, int size);
+
+#define BUF16_TO_INT(buf, pos) buf_to_int((buf), (pos), 2)
+#define BUF32_TO_INT(buf, pos) buf_to_int((buf), (pos), 4)
+#define BUF64_TO_INT(buf, pos) buf_to_int((buf), (pos), 8)
+
+#define INT_TO_BUF16(i, buf, pos) int_to_buf((i), (buf), (pos), 2)
+#define INT_TO_BUF32(i, buf, pos) int_to_buf((i), (buf), (pos), 4)
+#define INT_TO_BUF64(i, buf, pos) int_to_buf((i), (buf), (pos), 8)
+
+mldonkey_info mlinfo;
+mldonkey_config mlconfig;
+
+/* Call this function to update the information about mldonkey.
+ * Note that the function will not reconnect to mldonkey if the
+ * pointer to the mldonkey_config has not changed. As it uses static
+ * data, it cannot be used in a multithreaded env.
+ * Returns 1 if connected and info filled, 0 if connected but not filled,
+ * -1 otherwise. */
+
+enum to_gui {
+       CoreProtocol,           /* 0 */
+       Options_info,
+       RESERVED2,
+       DefineSearches,
+       Result_info,
+       Search_result,
+       Search_waiting,
+       File_info,
+       File_downloaded,
+       File_availability,
+       File_source,            /* 10 */
+       Server_busy,
+       Server_user,
+       Server_state,
+       Server_info,
+       Client_info,
+       Client_state,
+       Client_friend,
+       Client_file,
+       Console,
+       Network_info,           /* 20 */
+       User_info,
+       Room_info,
+       Room_message,
+       Room_add_user,
+       Client_stats,
+       Server_info_v2,
+       MessageFromClient,
+       ConnectedServers,
+       DownloadFiles,
+       DownloadedFiles,        /* 30 */
+       Room_info_v2,
+       Room_remove_user,
+       Shared_file_info,
+       Shared_file_upload,
+       Shared_file_unshared,
+       Add_section_option,
+       Client_stats_v2,
+       Add_plugin_option,
+       Client_stats_v3,
+       File_info_v2,           /* 40 */
+       DownloadFiles_v2,
+       DownloadedFiles_v2,
+       File_info_v3,
+       DownloadFiles_v3,
+       DownloadedFiles_v3,
+       File_downloaded_v2,
+       BadPassword,
+       Shared_file_info_v2,
+       Client_stats_v4,        /* 49 */
+};
+
+#define MLDONKEY_DISCONNECTED   0
+#define MLDONKEY_CONNECTING     1
+#define MLDONKEY_AUTHENTICATING 2
+#define MLDONKEY_CONNECTED      3
+
+#define MAX_MESSAGE_LEN 65000
+static int write_pos = 0;
+static char write_buf[MAX_MESSAGE_LEN];
+static char read_buf[MAX_MESSAGE_LEN];
+static int read_pos;
+static int mldonkey_sock = -1;
+static int mldonkey_state = MLDONKEY_DISCONNECTED;
+static mldonkey_config *old_config = NULL;
+
+/* int64 ------------------------------ */
+
+int64 buf_to_int(char *buf, int pos, int size)
+{
+       int i;
+       int64 res = 0;
+
+       for (i = 0; i < size; i++) {
+               res += (buf[pos + i] & 0xFF) << (8 * i);
+       }
+       return res;
+}
+
+void int_to_buf(int64 i, char *buf, int pos, int size)
+{
+       int j;
+
+       for (j = 0; j < size; j++) {
+               buf[pos + j] = (i & (-1)) >> (8 * j);
+       }
+}
+
+/* Write operations --------------------- */
+
+void init_message()
+{
+       write_pos = 0;
+}
+
+void write_int8(int code)
+{
+       write_buf[write_pos++] = code;
+}
+
+void write_opcode(int code)
+{
+       write_buf[write_pos++] = code;
+}
+
+void write_int16(int code)
+{
+       INT_TO_BUF16(code, write_buf, write_pos);
+       write_pos += 2;
+}
+
+void write_int32(int code)
+{
+       INT_TO_BUF32(code, write_buf, write_pos);
+       write_pos += 4;
+}
+
+void write_int64(int64 code)
+{
+       INT_TO_BUF64(code, write_buf, write_pos);
+       write_pos += 8;
+}
+
+void write_string(char *str)
+{
+       if (str == NULL) {
+               write_int16(0);
+       } else {
+               int len = strlen(str);
+               write_int16(len);
+               memcpy((void *) (write_buf + write_pos), (void *) str,
+                      (size_t) len);
+               write_pos += len;
+       }
+}
+
+
+int write_message(char *mtype)
+{
+       char header[4];
+
+       INT_TO_BUF32(write_pos, header, 0);
+       if (4 != write(mldonkey_sock, header, 4) ||
+           write_pos != write(mldonkey_sock, (void *) write_buf,
+                              (size_t) write_pos)) {
+               ERR("Error in transmitting %s\n", mtype);
+               write_pos = 0;
+
+               /* Immediatly close the connection */
+               close(mldonkey_sock);
+               mldonkey_state = MLDONKEY_DISCONNECTED;
+               mldonkey_sock = -1;
+               return -1;
+       } else {
+               write_pos = 0;
+               return 0;
+       }
+}
+
+
+/* Read operations ----------------------------*/
+
+int read_int8()
+{
+       return read_buf[read_pos++];
+}
+
+int read_int16()
+{
+       int i = BUF16_TO_INT(read_buf, read_pos);
+       read_pos += 2;
+       return i;
+}
+
+int read_int32()
+{
+       int i = BUF32_TO_INT(read_buf, read_pos);
+       read_pos += 4;
+       return i;
+}
+
+int64 read_int64()
+{
+       int64 i = BUF64_TO_INT(read_buf, read_pos);
+       read_pos += 8;
+       return i;
+}
+
+char *read_string()
+{
+       char *buf;
+       int len;
+
+       len = BUF16_TO_INT(read_buf, read_pos);
+       read_pos += 2;
+
+       buf = (char *) malloc((size_t) len + 1);
+       memmove(read_buf + read_pos, buf, len);
+       buf[len] = 0;
+       read_pos += len;
+
+       return buf;
+}
+
+/* protocol impl. ----------------------------- */
+
+void close_sock();
+
+/* This function returns the number of messages read, 0 if it blocks,
+-1 on error. */
+int cut_messages(int reinit)
+{
+       int nread;
+       static int toread = 0;
+       static int pos = 0;
+
+       if (reinit) {
+               toread = 0;
+               pos = 0;
+               read_pos = 0;
+               return 0;
+       }
+
+       while (1) {
+               if (toread == 0) {
+                       nread =
+                           read(mldonkey_sock, read_buf + pos, 4 - pos);
+                       if (nread <= 0) {
+                               if (errno == EAGAIN) {
+                                       return 0;
+                               } else {
+                                       close_sock();
+                                       pos = 0;
+                                       toread = 0;
+                                       return -1;
+                               }
+                       }
+                       pos += nread;
+                       if (pos == 4) {
+                               toread = BUF32_TO_INT(read_buf, 0);
+                               pos = 0;
+                       }
+               } else {
+                       nread =
+                           read(mldonkey_sock, read_buf + pos,
+                                toread - pos);
+                       if (nread <= 0) {
+                               if (errno == EAGAIN)
+                                       return 0;
+                               else {
+                                       pos = 0;
+                                       toread = 0;
+                                       close_sock();
+                                       return -1;
+                               }
+                       }
+                       pos += nread;
+                       if (pos == toread) {
+                               /* We have one message !!! */
+                               int old_pos = pos;
+                               read_pos = 0;
+                               pos = 0;
+                               toread = 0;
+
+                               return old_pos;
+                       }
+               }
+       }
+}
+
+void close_sock()
+{
+       old_config = NULL;
+       if (mldonkey_sock >= 0)
+               close(mldonkey_sock);
+       mldonkey_sock = -1;
+       mldonkey_state = MLDONKEY_DISCONNECTED;
+       cut_messages(1);
+}
+
+int mldonkey_connect(mldonkey_config * config)
+{
+       if (config != old_config) {
+               struct sockaddr_in sa;
+               int retcode;
+               close_sock();
+
+
+               old_config = config;
+               /* resolve hostname */
+               memset(&sa, 0, sizeof(sa));
+
+               if (config->mldonkey_hostname == NULL)
+                       config->mldonkey_hostname = "127.0.0.1";
+               if (config->mldonkey_hostname[0] >= '0' &&
+                   config->mldonkey_hostname[0] <= '9') {
+#ifdef HAS_INET_ATON
+                       if (inet_aton
+                           (config->mldonkey_hostname, &sa.sin_addr) == 0)
+                               return -1;
+#else
+
+                       sa.sin_addr.s_addr =
+                           inet_addr(config->mldonkey_hostname);
+                       if (sa.sin_addr.s_addr == (unsigned int) -1)
+                               return -1;
+#endif
+
+               } else {
+                       struct hostent *hp;
+                       hp = gethostbyname(config->mldonkey_hostname);
+                       if (hp == (struct hostent *) NULL)
+                               return -1;
+                       sa.sin_addr.s_addr =
+                           (unsigned long) hp->h_addr_list[0];
+               }
+
+               sa.sin_port = htons(config->mldonkey_port);
+               sa.sin_family = AF_INET;
+
+               if ((mldonkey_sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
+                       ERR("Opening socket");
+                       close_sock();
+                       return -1;
+               }
+
+               if (connect
+                   (mldonkey_sock, (struct sockaddr *) &sa,
+                    sizeof(sa)) < 0) {
+                       if (errno != EAGAIN && errno != EINTR
+                           && errno != EINPROGRESS
+                           && errno != EWOULDBLOCK) {
+//        ERR("Connection failed");
+                               close_sock();
+                               return -1;
+                       }
+               }
+
+               retcode = fcntl(mldonkey_sock, F_GETFL, 0);
+               if (retcode == -1 ||
+                   fcntl(mldonkey_sock, F_SETFL,
+                         retcode | O_NONBLOCK) == -1) {
+                       return -1;
+               }
+
+
+               mldonkey_state = MLDONKEY_CONNECTING;
+               return 0;
+       }
+
+       return 0;
+}
+
+int mldonkey_can_read()
+{
+       return cut_messages(0);
+}
+
+int mldonkey_info_message(mldonkey_info * info)
+{
+       int opcode = read_int16();
+
+       switch (opcode) {
+
+       case CoreProtocol:
+               init_message();
+
+               write_int16(0); /* GUI protocol */
+               write_int32(10);        /* Version 10 ! */
+               write_message("GuiProtocol");
+
+               write_int16(47);        /* GUI protocol */
+
+               write_int16(1);
+               write_int32(1);
+               write_int8(1);
+               write_message("GuiExtensions");
+
+               init_message();
+               write_int16(5); /* Password */
+               write_string(old_config->mldonkey_password);
+               write_message("Password");
+
+               break;
+
+       case BadPassword:
+               ERR("Bad Password\n");
+               close_sock();
+               break;
+
+       case Client_stats:
+       case Client_stats_v2:
+       case Client_stats_v3:
+               ERR("Client stats format too old...\n");
+               break;
+
+       case Client_stats_v4:
+               mldonkey_state = MLDONKEY_CONNECTED;
+
+               info->upload_counter = read_int64();
+               info->download_counter = read_int64();
+               info->shared_counter = read_int64();
+               info->nshared_files = read_int32();
+               info->tcp_upload_rate = read_int32();
+               info->tcp_download_rate = read_int32();
+               info->udp_upload_rate = read_int32();
+               info->udp_download_rate = read_int32();
+               info->ndownloading_files = read_int32();
+               info->ndownloaded_files = read_int32();
+
+               break;
+       }
+
+       return 0;
+}
+
+int get_mldonkey_status(mldonkey_config * config, mldonkey_info * info)
+{
+       if (mldonkey_connect(config) >= 0) {
+               while (mldonkey_can_read() > 0) {
+                       mldonkey_info_message(info);
+               }
+       }
+       return mldonkey_state;
+}
diff --git a/src/mpd.c b/src/mpd.c
new file mode 100644 (file)
index 0000000..c21ec01
--- /dev/null
+++ b/src/mpd.c
@@ -0,0 +1,154 @@
+#include "conky.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "libmpdclient.h"
+
+
+void update_mpd()
+{
+       struct information *current_info = &info;
+       current_info->conn =
+           mpd_newConnection(current_info->mpd.host,
+                             current_info->mpd.port, 10);
+       if (current_info->conn->error) {
+               //fprintf(stderr, "%s\n", current_info->conn->errorStr);
+               mpd_closeConnection(current_info->conn);
+               if (current_info->mpd.artist == NULL)
+                       current_info->mpd.artist =
+                           malloc(TEXT_BUFFER_SIZE);
+               if (current_info->mpd.album == NULL)
+                       current_info->mpd.album = malloc(TEXT_BUFFER_SIZE);
+               if (current_info->mpd.title == NULL)
+                       current_info->mpd.title = malloc(TEXT_BUFFER_SIZE);
+               strcpy(current_info->mpd.artist, "Unknown");
+               strcpy(current_info->mpd.album, "Unknown");
+               strcpy(current_info->mpd.title, "Unknown");
+               current_info->mpd.status = "MPD not responding";
+               current_info->mpd.bitrate = 0;
+               current_info->mpd.progress = 0;
+               current_info->mpd.elapsed = 0;
+               current_info->mpd.length = 0;
+               return;
+       }
+
+       mpd_Status *status;
+       mpd_InfoEntity *entity;
+       mpd_sendCommandListOkBegin(current_info->conn);
+       mpd_sendStatusCommand(current_info->conn);
+       mpd_sendCurrentSongCommand(current_info->conn);
+       mpd_sendCommandListEnd(current_info->conn);
+       if ((status = mpd_getStatus(current_info->conn)) == NULL) {
+               //fprintf(stderr, "%s\n", current_info->conn->errorStr);
+               mpd_closeConnection(current_info->conn);
+               if (current_info->mpd.artist == NULL)
+                       current_info->mpd.artist =
+                           malloc(TEXT_BUFFER_SIZE);
+               if (current_info->mpd.album == NULL)
+                       current_info->mpd.album = malloc(TEXT_BUFFER_SIZE);
+               if (current_info->mpd.title == NULL)
+                       current_info->mpd.title = malloc(TEXT_BUFFER_SIZE);
+               strcpy(current_info->mpd.artist, "Unknown");
+               strcpy(current_info->mpd.album, "Unknown");
+               strcpy(current_info->mpd.title, "Unknown");
+               current_info->mpd.status = "MPD not responding";
+               current_info->mpd.bitrate = 0;
+               current_info->mpd.progress = 0;
+               current_info->mpd.elapsed = 0;
+               current_info->mpd.length = 0;
+               return;
+       }
+       current_info->mpd.volume = status->volume;
+       //if (status->error)
+       //printf("error: %s\n", status->error);
+
+       if (status->state == MPD_STATUS_STATE_PLAY) {
+               current_info->mpd.status = "Playing";
+       }
+       if (status->state == MPD_STATUS_STATE_STOP) {
+               current_info->mpd.status = "Stopped";
+               current_info->mpd.bitrate = 0;
+               current_info->mpd.progress = 0;
+               current_info->mpd.elapsed = 0;
+               current_info->mpd.length = 0;
+       }
+       if (status->state == MPD_STATUS_STATE_PAUSE) {
+               current_info->mpd.status = "Paused";
+       }
+       if (status->state == MPD_STATUS_STATE_UNKNOWN) {
+               current_info->mpd.status = "Unknown";
+               current_info->mpd.bitrate = 0;
+               current_info->mpd.progress = 0;
+               current_info->mpd.elapsed = 0;
+               current_info->mpd.length = 0;
+       }
+       if (status->state == MPD_STATUS_STATE_PLAY ||
+           status->state == MPD_STATUS_STATE_PAUSE) {
+               current_info->mpd.bitrate = status->bitRate;
+               current_info->mpd.progress =
+                   (float) status->elapsedTime / status->totalTime;
+               current_info->mpd.elapsed = status->elapsedTime;
+               current_info->mpd.length = status->totalTime;
+       }
+
+
+       if (current_info->conn->error) {
+               //fprintf(stderr, "%s\n", current_info->conn->errorStr);
+               mpd_closeConnection(current_info->conn);
+               return;
+       }
+
+       mpd_nextListOkCommand(current_info->conn);
+
+       while ((entity = mpd_getNextInfoEntity(current_info->conn))) {
+               mpd_Song *song = entity->info.song;
+               if (entity->type != MPD_INFO_ENTITY_TYPE_SONG) {
+                       mpd_freeInfoEntity(entity);
+                       continue;
+               }
+
+               if (current_info->mpd.artist == NULL)
+                       current_info->mpd.artist =
+                           malloc(TEXT_BUFFER_SIZE);
+               if (current_info->mpd.album == NULL)
+                       current_info->mpd.album = malloc(TEXT_BUFFER_SIZE);
+               if (current_info->mpd.title == NULL)
+                       current_info->mpd.title = malloc(TEXT_BUFFER_SIZE);
+               if (song->artist) {
+                       strcpy(current_info->mpd.artist, song->artist);
+               } else {
+                       strcpy(current_info->mpd.artist, "Unknown");
+               }
+               if (song->album) {
+                       strcpy(current_info->mpd.album, song->album);
+               } else {
+                       strcpy(current_info->mpd.album, "Unknown");
+               }
+               if (song->title) {
+                       strcpy(current_info->mpd.title, song->title);
+               } else {
+                       strcpy(current_info->mpd.title, "Unknown");
+               }
+               if (entity != NULL) {
+                       mpd_freeInfoEntity(entity);
+               }
+       }
+       if (entity != NULL) {
+               mpd_freeInfoEntity(entity);
+       }
+
+       if (current_info->conn->error) {
+               //fprintf(stderr, "%s\n", current_info->conn->errorStr);
+               mpd_closeConnection(current_info->conn);
+               return;
+       }
+
+       mpd_finishCommand(current_info->conn);
+       if (current_info->conn->error) {
+               //fprintf(stderr, "%s\n", current_info->conn->errorStr);
+               mpd_closeConnection(current_info->conn);
+               return;
+       }
+       mpd_freeStatus(status);
+       mpd_closeConnection(current_info->conn);
+}
diff --git a/src/netbsd.c b/src/netbsd.c
new file mode 100644 (file)
index 0000000..6e4fcbf
--- /dev/null
@@ -0,0 +1,356 @@
+/* NetBSD port */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+#include <err.h>
+#include <limits.h>
+#include <paths.h>
+
+#include <kvm.h>
+#include <nlist.h>
+
+#include <sys/time.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/user.h>
+#include <sys/socket.h>
+#include <sys/swap.h>
+#include <sys/sched.h>
+#include <sys/envsys.h>
+
+#include <net/if.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <machine/param.h>
+
+#include "conky.h"
+
+
+static kvm_t *kd = NULL;
+int kd_init = 0, nkd_init = 0;
+u_int32_t sensvalue;
+char errbuf[_POSIX2_LINE_MAX];
+
+static int init_kvm(void)
+{
+       if (kd_init)
+               return 0;
+
+       kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf);
+       if (kd == NULL) {
+               (void) warnx("cannot kvm_openfiles: %s", errbuf);
+               return -1;
+       }
+       kd_init = 1;
+       return 0;
+}
+
+static int swapmode(int *retavail, int *retfree)
+{
+       int n;
+       struct swapent *sep;
+
+       *retavail = 0;
+       *retfree = 0;
+
+       n = swapctl(SWAP_NSWAP, 0, 0);
+
+       if (n < 1) {
+               (void) warn("could not get swap information");
+               return 0;
+       }
+
+       sep = (struct swapent *) malloc(n * (sizeof(*sep)));
+
+       if (sep == NULL) {
+               (void) warn("memory allocation failed");
+               return 0;
+       }
+
+       if (swapctl(SWAP_STATS, (void *) sep, n) < n) {
+               (void) warn("could not get swap stats");
+               return 0;
+       }
+       for (; n > 0; n--) {
+               *retavail += (int) dbtob(sep[n - 1].se_nblks);
+               *retfree +=
+                   (int) dbtob(sep[n - 1].se_nblks - sep[n - 1].se_inuse);
+       }
+       *retavail = (int) (*retavail / 1024);
+       *retfree = (int) (*retfree / 1024);
+
+       return 1;
+}
+
+
+void prepare_update()
+{
+}
+
+void update_uptime()
+{
+       int mib[2] = { CTL_KERN, KERN_BOOTTIME };
+       struct timeval boottime;
+       time_t now;
+       int size = sizeof(boottime);
+
+       if ((sysctl(mib, 2, &boottime, &size, NULL, 0) != -1)
+           && (boottime.tv_sec != 0)) {
+               (void) time(&now);
+               info.uptime = now - boottime.tv_sec;
+       } else {
+               (void) warn("could not get uptime");
+               info.uptime = 0;
+       }
+}
+
+
+void update_meminfo()
+{
+       int mib[] = { CTL_VM, VM_UVMEXP2 };
+       int total_pages, inactive_pages, free_pages;
+       int swap_avail, swap_free;
+       const int pagesize = getpagesize();
+       struct uvmexp_sysctl uvmexp;
+       size_t size = sizeof(uvmexp);
+
+       info.memmax = info.mem = 0;
+       info.swapmax = info.swap = 0;
+
+
+       if (sysctl(mib, 2, &uvmexp, &size, NULL, 0) < 0) {
+               warn("could not get memory info");
+               return;
+       }
+
+       total_pages = uvmexp.npages;
+       free_pages = uvmexp.free;
+       inactive_pages = uvmexp.inactive;
+
+       info.memmax = (total_pages * pagesize) >> 10;
+       info.mem =
+           ((total_pages - free_pages - inactive_pages) * pagesize) >> 10;
+
+       if (swapmode(&swap_avail, &swap_free) >= 0) {
+               info.swapmax = swap_avail;
+               info.swap = (swap_avail - swap_free);
+       }
+}
+
+void update_net_stats()
+{
+       int i;
+       double delta;
+       struct ifnet ifnet;
+       struct ifnet_head ifhead;       /* interfaces are in a tail queue */
+       u_long ifnetaddr;
+       static struct nlist namelist[] = {
+               {"_ifnet"},
+               {NULL},
+       };
+       static kvm_t *nkd;
+
+       if (!nkd_init) {
+               nkd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
+               if (nkd == NULL) {
+                       (void) warnx("cannot kvm_openfiles: %s", errbuf);
+                       (void)
+                           warnx
+                           ("maybe you need to setgid kmem this program?");
+                       return;
+               } else if (kvm_nlist(nkd, namelist) != 0) {
+                       (void) warn("cannot kvm_nlist");
+                       return;
+               } else
+                       nkd_init = 1;
+       }
+
+       if (kvm_read(nkd, (u_long) namelist[0].n_value, (void *) &ifhead,
+                    sizeof(ifhead)) < 0) {
+               (void) warn("cannot kvm_read");
+               return;
+       }
+
+       /* get delta */
+       delta = current_update_time - last_update_time;
+       if (delta <= 0.0001)
+               return;
+
+       for (i = 0, ifnetaddr = (u_long) ifhead.tqh_first;
+            ifnet.if_list.tqe_next && i < 16;
+            ifnetaddr = (u_long) ifnet.if_list.tqe_next, i++) {
+
+               struct net_stat *ns;
+               long long last_recv, last_trans;
+
+               (void) kvm_read(nkd, (u_long) ifnetaddr, (void *) &ifnet,
+                               sizeof(ifnet));
+               ns = get_net_stat(ifnet.if_xname);
+               ns->up = 1;
+               last_recv = ns->recv;
+               last_trans = ns->trans;
+
+               if (ifnet.if_ibytes < ns->last_read_recv)
+                       ns->recv +=
+                           ((long long) 4294967295U -
+                            ns->last_read_recv) + ifnet.if_ibytes;
+               else
+                       ns->recv += (ifnet.if_ibytes - ns->last_read_recv);
+
+               ns->last_read_recv = ifnet.if_ibytes;
+
+               if (ifnet.if_obytes < ns->last_read_trans)
+                       ns->trans +=
+                           ((long long) 4294967295U -
+                            ns->last_read_trans) + ifnet.if_obytes;
+               else
+                       ns->trans +=
+                           (ifnet.if_obytes - ns->last_read_trans);
+
+               ns->last_read_trans = ifnet.if_obytes;
+
+               ns->recv += (ifnet.if_ibytes - ns->last_read_recv);
+               ns->last_read_recv = ifnet.if_ibytes;
+               ns->trans += (ifnet.if_obytes - ns->last_read_trans);
+               ns->last_read_trans = ifnet.if_obytes;
+
+               ns->recv_speed = (ns->recv - last_recv) / delta;
+               ns->trans_speed = (ns->trans - last_trans) / delta;
+       }
+}
+
+void update_total_processes()
+{
+       /* It's easier to use kvm here than sysctl */
+
+       int n_processes;
+
+       info.procs = 0;
+
+       if (init_kvm() < 0)
+               return;
+       else
+               kvm_getproc2(kd, KERN_PROC_ALL, 0,
+                            sizeof(struct kinfo_proc2), &n_processes);
+
+       info.procs = n_processes;
+}
+
+void update_running_processes()
+{
+       struct kinfo_proc2 *p;
+       int n_processes;
+       int i, cnt = 0;
+
+       info.run_procs = 0;
+
+       if (init_kvm() < 0)
+               return;
+       else {
+               p = kvm_getproc2(kd, KERN_PROC_ALL, 0,
+                                sizeof(struct kinfo_proc2), &n_processes);
+               for (i = 0; i < n_processes; i++)
+                       if (p[i].p_stat == LSRUN || p[i].p_stat == LSIDL ||
+                           p[i].p_stat == LSONPROC)
+                               cnt++;
+       }
+
+       info.run_procs = cnt;
+}
+
+struct cpu_load_struct {
+       unsigned long load[5];
+};
+
+struct cpu_load_struct fresh = {
+       {0, 0, 0, 0, 0}
+};
+
+long cpu_used, oldtotal, oldused;
+
+void update_cpu_usage()
+{
+       long used, total;
+       static u_int64_t cp_time[CPUSTATES];
+       size_t len = sizeof(cp_time);
+
+       info.cpu_usage = 0;
+
+       if (sysctlbyname("kern.cp_time", &cp_time, &len, NULL, 0) < 0)
+               (void) warn("cannot get kern.cp_time");
+
+
+       fresh.load[0] = cp_time[CP_USER];
+       fresh.load[1] = cp_time[CP_NICE];
+       fresh.load[2] = cp_time[CP_SYS];
+       fresh.load[3] = cp_time[CP_IDLE];
+       fresh.load[4] = cp_time[CP_IDLE];
+
+       used = fresh.load[0] + fresh.load[1] + fresh.load[2];
+       total =
+           fresh.load[0] + fresh.load[1] + fresh.load[2] + fresh.load[3];
+
+       if ((total - oldtotal) != 0)
+               info.cpu_usage =
+                   ((double) (used - oldused)) / (double) (total -
+                                                           oldtotal);
+       else
+               info.cpu_usage = 0;
+
+       oldused = used;
+       oldtotal = total;
+
+}
+
+double get_i2c_info(int *fd, int div, char *devtype)
+{
+       return -1;
+}
+
+void update_load_average()
+{
+       double v[3];
+       getloadavg(v, 3);
+
+       info.loadavg[0] = (float) v[0];
+       info.loadavg[1] = (float) v[1];
+       info.loadavg[2] = (float) v[2];
+}
+
+double get_acpi_temperature(int fd)
+{
+       return -1;
+}
+
+void get_battery_stuff(char *buf, unsigned int n, const char *bat)
+{
+}
+
+int
+open_i2c_sensor(const char *dev, const char *type, int n, int *div,
+               char *devtype)
+{
+       return -1;
+}
+
+int open_acpi_temperature(const char *name)
+{
+       return -1;
+}
+
+char *get_acpi_ac_adapter(void)
+{
+       return "N/A";
+}
+
+char *get_acpi_fan()
+{
+       return "N/A";
+}
diff --git a/src/remotec.c b/src/remotec.c
new file mode 100644 (file)
index 0000000..dbe5bf0
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Conky, a system monitor, based on torsmo
+ *
+ * This program is licensed under BSD license, read COPYING
+ *
+ *  $Id$
+ */
+ /*
+ okay, nothing here right now.  thanks for coming out
+ */
+
+#include "conky.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+
+#define PORT 3490 // the port client will be connecting to 
+
+#define MAXDATASIZE 100 // max number of bytes we can get at once 
+
+void client()
+{
+       int sockfd, numbytes;  
+       char buf[MAXDATASIZE];
+       struct hostent *he;
+       struct sockaddr_in their_addr; // connector's address information 
+       if ((he=gethostbyname("localhost")) == NULL) {  // get the host info 
+               perror("gethostbyname");
+               exit(1);
+       }
+
+       if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
+               perror("socket");
+               exit(1);
+       }
+
+       their_addr.sin_family = AF_INET;    // host byte order 
+       their_addr.sin_port = htons(PORT);  // short, network byte order 
+       their_addr.sin_addr = *((struct in_addr *)he->h_addr);
+       memset(&(their_addr.sin_zero), '\0', 8);  // zero the rest of the struct 
+
+       if (connect(sockfd, (struct sockaddr *)&their_addr,
+           sizeof(struct sockaddr)) == -1) {
+                   perror("connect");
+                   exit(1);
+           }
+
+           if ((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) {
+                   perror("recv");
+                   exit(1);
+           }
+
+           buf[numbytes] = '\0';
+
+           printf("Received: %s",buf);
+
+           close(sockfd);
+
+           return 0;
+}
diff --git a/src/remotec.h b/src/remotec.h
new file mode 100644 (file)
index 0000000..37ed44d
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Conky, a system monitor, based on torsmo
+ *
+ * This program is licensed under BSD license, read COPYING
+ *
+ *  $Id$
+ */
+  /*
+ okay, nothing here right now.  thanks for coming out
+  */
+
+void client();
diff --git a/src/remoted.c b/src/remoted.c
new file mode 100644 (file)
index 0000000..b6136c4
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+* Conky, a system monitor, based on torsmo
+*
+* This program is licensed under BSD license, read COPYING
+*
+*  $Id$
+*/
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/wait.h>
+#include <signal.h>
+
+static pthread_t daemon_thread;
+static int daemon_status = 0;
+static char *data;
+
+/* okay, heres how it will basically work.
+* when something connects, it will first send the conkyrc on the local (daemonized) server
+* after this, it will simply continue to send all the buffered text to the remote client
+* http://analyser.oli.tudelft.nl/beej/mirror/net/html/
+*  http://www.kegel.com/c10k.html
+*/
+
+#define MYPORT 3490    // the port users will be connecting to
+
+#define BACKLOG 10     // how many pending connections queue will hold
+
+void sigchld_handler(int s)
+{
+       while(wait(NULL) > 0);
+}
+
+void *daemon_loop()
+{
+       /* do something */
+
+
+
+       int sockfd, new_fd;  // listen on sock_fd, new connection on new_fd
+       struct sockaddr_in my_addr;    // my address information
+       struct sockaddr_in their_addr; // connector's address information
+       int sin_size;
+       struct sigaction sa;
+       int yes=1;
+
+       if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
+               perror("socket");
+               exit(1);
+       }
+
+       if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
+               perror("setsockopt");
+               exit(1);
+       }
+       
+       my_addr.sin_family = AF_INET;         // host byte order
+       my_addr.sin_port = htons(MYPORT);     // short, network byte order
+       my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
+       memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct
+
+       if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))
+                  == -1) {
+               perror("bind");
+               exit(1);
+                  }
+
+                  if (listen(sockfd, BACKLOG) == -1) {
+                          perror("listen");
+                          exit(1);
+                  }
+
+                  sa.sa_handler = sigchld_handler; // reap all dead processes
+                  sigemptyset(&sa.sa_mask);
+                  sa.sa_flags = SA_RESTART;
+                  if (sigaction(SIGCHLD, &sa, NULL) == -1) {
+                          perror("sigaction");
+                          exit(1);
+                  }
+
+                  while(1) {  // main accept() loop
+                          sin_size = sizeof(struct sockaddr_in);
+                          if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr,
+                               &sin_size)) == -1) {
+                                       perror("accept");
+                                       continue;
+                               }
+                               printf("server: got connection from %s\n",
+                                      inet_ntoa(their_addr.sin_addr));
+                               if (!fork()) { // this is the child process
+                                       close(sockfd); // child doesn't need the listener
+                                       if (send(new_fd, data, 14, 0) == -1)
+                                               perror("send");
+                                       close(new_fd);
+                                       exit(0);
+                               }
+                               close(new_fd);  // parent doesn't need this
+                  }
+
+                  return 0;
+}
+
+void daemon_run(const char *s)
+{
+       /* create thread, keep an eye on it */
+       data = s;
+       int iret;
+       if (!daemon_status) {
+               daemon_status = 1;
+               iret = pthread_create(&daemon_thread, NULL, daemon_loop, NULL);
+       } else if (daemon_status == 1) {
+               /* thread is still running, we'll just wait for it to finish for now */
+               pthread_join(daemon_thread, NULL);
+               daemon_status = 0;
+       } else {
+               /* something else */
+       }
+}
diff --git a/src/remoted.h b/src/remoted.h
new file mode 100644 (file)
index 0000000..b198389
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ * Conky, a system monitor, based on torsmo
+ *
+ * This program is licensed under BSD license, read COPYING
+ *
+ *  $Id$
+ */
+
+#include "conky.h"
+
+void daemon_run(const char *s);
diff --git a/src/seti.c b/src/seti.c
new file mode 100644 (file)
index 0000000..1c8a8d5
--- /dev/null
@@ -0,0 +1,103 @@
+#include "conky.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+char *seti_dir = NULL;
+
+//Need to code for BOINC, because the old SETI@Home does not use xml to store data.
+//Perhaps in the .conkyrc file there could be an option for BOINC or old SETI.
+
+/*static float seti_get_float (FILE *fp, const char *name)
+{
+  char buffer[80];
+  char *token;
+
+  while (!feof(fp) && !ferror (fp))
+  {
+    fgets(buffer, 80, fp);
+    token = strtok(buffer, ">");
+
+    if (strcmp(token, name) == 0)
+    {
+      token = strtok(NULL, "<");
+      if ( token != NULL )
+        return atof (token);
+      break;
+    }
+  }
+  return 0.0f;
+}*/
+
+float seti_get_data(FILE * fp, const char *name)
+{
+       char token[1000];
+       char buffer[1000];
+       float data;
+
+       while (fgets(token, 1000, fp) != NULL)  //read the file
+               if (strncmp(token, name, strlen(name)) == 0) {  //and search for the data in name
+                       strcpy(buffer, strchr(token, '=') + 1); //copy just the number
+                       break;
+               }
+       data = atof(buffer);
+       return data;
+}
+
+void update_seti()
+{
+       if (seti_dir == NULL)
+               return;
+
+       char filename[80];
+
+       struct information *current_info = &info;
+
+       current_info->seti_prog = current_info->seti_credit = 0.0f;
+
+       /* read total user credit */
+
+       /*FILE *fp = fopen(filename, "r");
+          if (!fp)
+          return;
+
+          seti_credit = seti_get_float(fp, "<user_total_credit");
+
+          fclose (fp); */
+
+       snprintf(filename, 80, "%s/user_info.sah", seti_dir);
+
+       FILE *fp = fopen(filename, "r");
+
+       if (!fp) {
+               return;
+       }
+
+       current_info->seti_credit = seti_get_data(fp, "nresults");
+
+       fclose(fp);
+
+       /* read current progress */
+
+       /*snprintf(filename, 80, "%s/slots/0/state.sah", seti_dir);
+          fp = fopen(filename, "r");
+          if (!fp)
+          return;
+
+          seti_prog = seti_get_float(fp, "<prog");
+
+          fclose (fp);
+
+          snprintf(filename, 80, "%s/slots/0/init_data.xml", seti_dir); */
+
+       snprintf(filename, 80, "%s/state.sah", seti_dir);
+
+       fp = fopen(filename, "r");
+       if (!fp)
+               return;
+
+       current_info->seti_prog = seti_get_data(fp, "prog");
+
+       fclose(fp);
+
+}
diff --git a/src/solaris.c b/src/solaris.c
new file mode 100644 (file)
index 0000000..3854336
--- /dev/null
@@ -0,0 +1,52 @@
+/* doesn't work, feel free to finish this */
+#include "conky.h"
+#include <kstat.h>
+
+static kstat_ctl_t *kstat;
+static int kstat_updated;
+
+static void update_kstat()
+{
+       if (kstat == NULL) {
+               kstat = kstat_open();
+               if (kstat == NULL) {
+                       ERR("can't open kstat: %s", strerror(errno));
+               }
+       }
+
+       if (kstat_chain_update(kstat) == -1) {
+               perror("kstat_chain_update");
+               return;
+       }
+}
+
+void prepare_update()
+{
+       kstat_updated = 0;
+}
+
+double get_uptime()
+{
+       kstat_t *ksp;
+
+       update_kstat();
+
+       ksp = kstat_lookup(kstat, "unix", -1, "system_misc");
+       if (ksp != NULL) {
+               if (kstat_read(kstat, ksp, NULL) >= 0) {
+                       kstat_named_t *knp;
+                       knp =
+                           (kstat_named_t *) kstat_data_lookup(ksp,
+                                                               "boot_time");
+                       if (knp != NULL) {
+                               return get_time() -
+                                   (double) knp->value.ui32;
+                       }
+               }
+       }
+}
+
+void update_meminfo()
+{
+       /* TODO */
+}
diff --git a/src/top.c b/src/top.c
new file mode 100644 (file)
index 0000000..511e3b5
--- /dev/null
+++ b/src/top.c
@@ -0,0 +1,514 @@
+/*
+ * Conky, a system monitor, based on torsmo
+ *
+ * This program is licensed under BSD license, read COPYING
+ *
+ *  $Id$
+ */
+
+#include "top.h"
+
+static regex_t *exclusion_expression = 0;
+static unsigned int g_time = 0;
+static int previous_total = 0;
+static struct process *first_process = 0;
+
+static struct process *find_process(pid_t pid)
+{
+       struct process *p = first_process;
+       while (p) {
+               if (p->pid == pid)
+                       return p;
+               p = p->next;
+       }
+       return 0;
+}
+
+/*
+* Create a new process object and insert it into the process list
+*/
+static struct process *new_process(int p)
+{
+       struct process *process;
+       process = malloc(sizeof(struct process));
+
+       /*
+        * Do stitching necessary for doubly linked list
+        */
+       process->name = 0;
+       process->previous = 0;
+       process->next = first_process;
+       if (process->next)
+               process->next->previous = process;
+       first_process = process;
+
+       process->pid = p;
+       process->time_stamp = 0;
+       process->previous_user_time = INT_MAX;
+       process->previous_kernel_time = INT_MAX;
+       process->counted = 1;
+
+       /*    process_find_name(process); */
+
+       return process;
+}
+
+/******************************************/
+/* Functions                              */
+/******************************************/
+
+static int process_parse_stat(struct process *);
+static int update_process_table(void);
+static int calculate_cpu(struct process *);
+static void process_cleanup(void);
+static void delete_process(struct process *);
+/*inline void draw_processes(void);*/
+static int calc_cpu_total(void);
+static void calc_cpu_each(int);
+
+
+/******************************************/
+/* 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)
+{
+       struct information *cur;
+       cur = &info;
+       char line[BUFFER_LEN], filename[BUFFER_LEN], procname[BUFFER_LEN];
+       int ps;
+       int user_time, kernel_time;
+       int rc;
+       char *r, *q;
+       char deparenthesised_name[BUFFER_LEN];
+       int endl;
+       int nice_val;
+
+       snprintf(filename, sizeof(filename), PROCFS_TEMPLATE,
+                process->pid);
+
+       ps = open(filename, O_RDONLY);
+       if (ps < 0)
+               /*
+                * The process must have finished in the last few jiffies!
+                */
+               return 1;
+
+       /*
+        * Mark process as up-to-date.
+        */
+       process->time_stamp = g_time;
+
+       rc = read(ps, line, sizeof(line));
+       close(ps);
+       if (rc < 0)
+               return 1;
+
+       /*
+        * Extract cpu times from data in /proc filesystem
+        */
+       rc = sscanf(line,
+                   "%*s %s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %d %d %*s %*s %*s %d %*s %*s %*s %d %d",
+                   procname, &process->user_time, &process->kernel_time,
+                   &nice_val, &process->vsize, &process->rss);
+       if (rc < 5)
+               return 1;
+       /*
+        * Remove parentheses from the process name stored in /proc/ under Linux...
+        */
+       r = procname + 1;
+       /* remove any "kdeinit: " */
+       if (r == strstr(r, "kdeinit")) {
+               snprintf(filename, sizeof(filename),
+                        PROCFS_CMDLINE_TEMPLATE, process->pid);
+
+               ps = open(filename, O_RDONLY);
+               if (ps < 0)
+                       /*
+                        * The process must have finished in the last few jiffies!
+                        */
+                       return 1;
+
+               endl = read(ps, line, sizeof(line));
+               close(ps);
+
+               /* null terminate the input */
+               line[endl] = 0;
+               /* account for "kdeinit: " */
+               if ((char *) line == strstr(line, "kdeinit: "))
+                       r = ((char *) line) + 9;
+               else
+                       r = (char *) line;
+
+               q = deparenthesised_name;
+               /* stop at space */
+               while (*r && *r != ' ')
+                       *q++ = *r++;
+               *q = 0;
+       } else {
+               q = deparenthesised_name;
+               while (*r && *r != ')')
+                       *q++ = *r++;
+               *q = 0;
+       }
+
+       if (process->name)
+               free(process->name);
+       process->name = strdup(deparenthesised_name);
+       process->rss *= getpagesize();
+
+       if (!cur->memmax)
+               update_total_processes();
+
+       process->totalmem = ((float) process->rss / cur->memmax) / 10;
+
+       if (process->previous_user_time == INT_MAX)
+               process->previous_user_time = process->user_time;
+       if (process->previous_kernel_time == INT_MAX)
+               process->previous_kernel_time = process->kernel_time;
+
+       /* store the difference of the user_time */
+       user_time = process->user_time - process->previous_user_time;
+       kernel_time = process->kernel_time - process->previous_kernel_time;
+
+       /* backup the process->user_time for next time around */
+       process->previous_user_time = process->user_time;
+       process->previous_kernel_time = process->kernel_time;
+
+       /* store only the difference of the user_time here... */
+       process->user_time = user_time;
+       process->kernel_time = kernel_time;
+
+
+       return 0;
+}
+
+/******************************************/
+/* Update process table                   */
+/******************************************/
+
+static int update_process_table()
+{
+       DIR *dir;
+       struct dirent *entry;
+
+       if (!(dir = opendir("/proc")))
+               return 1;
+
+       ++g_time;
+
+       /*
+        * Get list of processes from /proc directory
+        */
+       while ((entry = readdir(dir))) {
+               pid_t pid;
+
+               if (!entry) {
+                       /*
+                        * Problem reading list of processes
+                        */
+                       closedir(dir);
+                       return 1;
+               }
+
+               if (sscanf(entry->d_name, "%d", &pid) > 0) {
+                       struct process *p;
+                       p = find_process(pid);
+                       if (!p)
+                               p = new_process(pid);
+
+                       /* compute each process cpu usage */
+                       calculate_cpu(p);
+               }
+       }
+
+       closedir(dir);
+
+       return 0;
+}
+
+/******************************************/
+/* Get process structure for process pid  */
+/******************************************/
+
+/*
+* This function seems to hog all of the CPU time. I can't figure out why - it
+* doesn't do much.
+*/
+static int calculate_cpu(struct process *process)
+{
+       int rc;
+
+       /* compute each process cpu usage by reading /proc/<proc#>/stat */
+       rc = process_parse_stat(process);
+       if (rc)
+               return 1;
+       /*rc = process_parse_statm(process);
+          if (rc)
+          return 1; */
+
+       /*
+        * Check name against the exclusion list
+        */
+       if (process->counted && exclusion_expression
+           && !regexec(exclusion_expression, process->name, 0, 0, 0))
+               process->counted = 0;
+
+       return 0;
+}
+
+/******************************************/
+/* Strip dead process entries             */
+/******************************************/
+
+static void process_cleanup()
+{
+
+       struct process *p = first_process;
+       while (p) {
+               struct process *current = p;
+
+#if defined(PARANOID)
+               assert(p->id == 0x0badfeed);
+#endif                         /* defined(PARANOID) */
+
+               p = p->next;
+               /*
+                * Delete processes that have died
+                */
+               if (current->time_stamp != g_time)
+                       delete_process(current);
+       }
+}
+
+/******************************************/
+/* Destroy and remove a process           */
+/******************************************/
+
+static void delete_process(struct process *p)
+{
+#if defined(PARANOID)
+       assert(p->id == 0x0badfeed);
+
+       /*
+        * Ensure that deleted processes aren't reused.
+        */
+       p->id = 0x007babe;
+#endif                         /* defined(PARANOID) */
+
+       /*
+        * Maintain doubly linked list.
+        */
+       if (p->next)
+               p->next->previous = p->previous;
+       if (p->previous)
+               p->previous->next = p->next;
+       else
+               first_process = p->next;
+
+       if (p->name)
+               free(p->name);
+       free(p);
+}
+
+/******************************************/
+/* Calculate cpu total                    */
+/******************************************/
+
+static int calc_cpu_total()
+{
+       int total, t;
+       int rc;
+       int ps;
+       char line[BUFFER_LEN];
+       int cpu, nice, system, idle;
+
+       ps = open("/proc/stat", O_RDONLY);
+       rc = read(ps, line, sizeof(line));
+       close(ps);
+       if (rc < 0)
+               return 0;
+       sscanf(line, "%*s %d %d %d %d", &cpu, &nice, &system, &idle);
+       total = cpu + nice + system + idle;
+
+       t = total - previous_total;
+       previous_total = total;
+
+       if (t < 0)
+               t = 0;
+
+       return t;
+}
+
+/******************************************/
+/* Calculate each processes cpu           */
+/******************************************/
+
+inline static void calc_cpu_each(int total)
+{
+       struct process *p = first_process;
+       while (p) {
+               /*p->amount = total ?
+                  (100.0 * (float) (p->user_time + p->kernel_time) /
+                  total) : 0; */
+               p->amount =
+                   (100.0 * (p->user_time + p->kernel_time) / total);
+
+/*             if (p->amount > 100)
+               p->amount = 0;*/
+               p = p->next;
+       }
+}
+
+/******************************************/
+/* Find the top processes                 */
+/******************************************/
+
+/*
+* Result is stored in decreasing order in best[0-9].
+*/
+#define MAX_TOP_SIZE 400 /* this is plenty big */
+static struct process **sorttmp;
+static size_t sorttmp_size = 10;
+
+inline void process_find_top(struct process **cpu, struct process **mem)
+{
+       struct process *pr;
+       if (sorttmp == NULL) {
+               sorttmp = malloc(sizeof(struct process) * sorttmp_size);
+               assert(sorttmp != NULL);
+       }
+       int total;
+       unsigned int i, max;
+
+       total = calc_cpu_total();       /* calculate the total of the processor */
+
+       update_process_table(); /* update the table with process list */
+       calc_cpu_each(total);   /* and then the percentage for each task */
+       process_cleanup();      /* cleanup list from exited processes */
+
+       /*
+        * this is really ugly,
+        * not to mention probably not too efficient.
+        * the main problem is that there could be any number of processes,
+        * however we have to use a fixed size for the "best" array.
+        * right now i can't think of a better way to do this,
+        * although i'm sure there is one.
+        * Perhaps just using a linked list would be more effecient?
+        * I'm too fucking lazy to do that right now.
+        */
+       if (top_cpu) {
+               pr = first_process;
+               i = 0;
+               while (pr) {
+                       if (i < sorttmp_size && pr->counted) {
+                               sorttmp[i] = pr;
+                               i++;
+                       } else if (i == sorttmp_size && pr->counted && sorttmp_size < MAX_TOP_SIZE) {
+                               sorttmp_size++;
+                               sorttmp =
+                                   realloc(sorttmp,
+                                           sizeof(struct process) *
+                                           sorttmp_size);
+                               sorttmp[i] = pr;
+                               i++;
+                       }
+                       pr = pr->next;
+               }
+               if (i + 1 < sorttmp_size) {
+                       sorttmp_size--;
+                       sorttmp =
+                           realloc(sorttmp,
+                                   sizeof(struct process) * sorttmp_size);
+               }
+               max = i;
+               for (i = 0; i < max - 1; i++) {
+                       while (sorttmp[i + 1]->amount > sorttmp[i]->amount) {
+                               pr = sorttmp[i];
+                               sorttmp[i] = sorttmp[i + 1];
+                               sorttmp[i + 1] = pr;
+                               if (i > 0)
+                                       i--;
+                               else
+                                       break;
+                       }
+
+               }
+               for (i = max; i > 1; i--);
+               {
+                       while (sorttmp[i]->amount > sorttmp[i - 1]->amount) {
+                               pr = sorttmp[i];
+                               sorttmp[i] = sorttmp[i - 1];
+                               sorttmp[i - 1] = pr;
+                               if (i < max)
+                                       i++;
+                               else
+                                       break;
+                       }
+               }
+               for (i = 0; i < 10; i++) {
+                       cpu[i] = sorttmp[i];
+
+               }
+       }
+       if (top_mem) {
+               pr = first_process;
+               i = 0;
+               while (pr) {
+                       if (i < sorttmp_size && pr->counted) {
+                               sorttmp[i] = pr;
+                               i++;
+                       } else if (i == sorttmp_size && pr->counted && sorttmp_size < MAX_TOP_SIZE) {
+                               sorttmp_size++;
+                               sorttmp =
+                                   realloc(sorttmp,
+                                           sizeof(struct process) *
+                                           sorttmp_size);
+                               sorttmp[i] = pr;
+                               i++;
+                       }
+                       pr = pr->next;
+               }
+               if (i + 1 < sorttmp_size) {
+                       sorttmp_size--;
+                       sorttmp =
+                           realloc(sorttmp,
+                                   sizeof(struct process) * sorttmp_size);
+               }
+               max = i;
+               for (i = 0; i < max - 1; i++) {
+                       while (sorttmp[i + 1]->totalmem >
+                              sorttmp[i]->totalmem) {
+                               pr = sorttmp[i];
+                               sorttmp[i] = sorttmp[i + 1];
+                               sorttmp[i + 1] = pr;
+                               if (i > 0)
+                                       i--;
+                               else
+                                       break;
+                       }
+
+               }
+               for (i = max; i > 1; i--);
+               {
+                       while (sorttmp[i]->totalmem >
+                              sorttmp[i - 1]->totalmem) {
+                               pr = sorttmp[i];
+                               sorttmp[i] = sorttmp[i - 1];
+                               sorttmp[i - 1] = pr;
+                               if (i < max)
+                                       i++;
+                               else
+                                       break;
+                       }
+               }
+               for (i = 0; i < 10; i++) {
+                       mem[i] = sorttmp[i];
+
+               }
+       }
+}
diff --git a/src/top.h b/src/top.h
new file mode 100644 (file)
index 0000000..18f899e
--- /dev/null
+++ b/src/top.h
@@ -0,0 +1,86 @@
+/*
+ * top.c a slightly modified wmtop.c -- copied from the WindowMaker and gkrelltop
+ * 
+ * Modified by Brenden Matthews
+ *
+ * Modified by Adi Zaimi
+ *
+ * Derived by Dan Piponi dan@tanelorn.demon.co.uk
+ * http://www.tanelorn.demon.co.uk
+ * http://wmtop.sourceforge.net 
+ * from code originally contained in wmsysmon by Dave Clark 
+(clarkd@skynet.ca)
+ * This software is licensed through the GNU General Public License.
+ *  $Id$
+ */
+
+/*
+ * Ensure there's an operating system defined. There is *no* default
+ * because every OS has it's own way of revealing CPU/memory usage.
+ * compile with gcc -DOS ...
+ */
+
+/******************************************/
+/* Includes                               */
+/******************************************/
+
+#include "conky.h"
+#define CPU_THRESHHOLD   0     /* threshhold for the cpu diff to appear */
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <dirent.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <math.h>
+#include <assert.h>
+#include <limits.h>
+#include <errno.h>
+#include <signal.h>
+
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+
+#include <regex.h>
+
+/******************************************/
+/* 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.
+ */
+#define BUFFER_LEN 1024
+
+#define PROCFS_TEMPLATE "/proc/%d/stat"
+#define PROCFS_TEMPLATE_MEM "/proc/%d/statm"
+#define PROCFS_CMDLINE_TEMPLATE "/proc/%d/cmdline"
+
+
+/******************************************/
+/* Globals                                */
+/******************************************/
+
+
+
+
+
+
+
+/******************************************/
+/* Process class                          */
+/******************************************/
+
+/*
+ * Pointer to head of process list
+ */
+void process_find_top(struct process **, struct process **);
diff --git a/src/x11.c b/src/x11.c
new file mode 100644 (file)
index 0000000..e0b6d9e
--- /dev/null
+++ b/src/x11.c
@@ -0,0 +1,358 @@
+/*
+ * Conky, a system monitor, based on torsmo
+ *
+ * This program is licensed under BSD license, read COPYING
+ *
+ *  $Id$
+ */
+
+#include "conky.h"
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/Xutil.h>
+#ifdef XFT
+#include <X11/Xft/Xft.h>
+#endif
+
+#ifdef XDBE
+int use_xdbe;
+#endif
+
+#ifdef XFT
+int use_xft = 0;
+#endif
+
+/* some basic X11 stuff */
+Display *display;
+int display_width;
+int display_height;
+int screen;
+
+/* workarea from _NET_WORKAREA, this is where window / text is aligned */
+int workarea[4];
+
+/* Window stuff */
+struct conky_window window;
+
+/* local prototypes */
+static void update_workarea();
+static Window find_window_to_draw();
+static Window find_subwindow(Window win, int w, int h);
+
+/* X11 initializer */
+void init_X11()
+{
+       if ((display = XOpenDisplay(0)) == NULL)
+               CRIT_ERR("can't open display: %s", XDisplayName(0));
+
+       screen = DefaultScreen(display);
+       display_width = DisplayWidth(display, screen);
+       display_height = DisplayHeight(display, screen);
+
+       update_workarea();
+}
+
+static void update_workarea()
+{
+       Window root = RootWindow(display, screen);
+       unsigned long nitems, bytes;
+       unsigned char *buf = NULL;
+       Atom type;
+       int format;
+
+       /* default work area is display */
+       workarea[0] = 0;
+       workarea[1] = 0;
+       workarea[2] = display_width;
+       workarea[3] = display_height;
+
+       /* get current desktop */
+       if (XGetWindowProperty(display, root, ATOM(_NET_CURRENT_DESKTOP),
+                              0, 1, False, XA_CARDINAL, &type, &format,
+                              &nitems, &bytes, &buf) == Success
+           && type == XA_CARDINAL && nitems > 0) {
+
+               //Currently unused 
+               /*  long desktop = * (long *) buf; */
+
+               XFree(buf);
+               buf = 0;
+
+       }
+
+       if (buf) {
+               XFree(buf);
+               buf = 0;
+       }
+}
+
+static Window find_window_to_draw()
+{
+       Atom type;
+       int format, i;
+       unsigned long nitems, bytes;
+       unsigned int n;
+       Window root = RootWindow(display, screen);
+       Window win = root;
+       Window troot, parent, *children;
+       unsigned char *buf = NULL;
+
+       /* some window managers set __SWM_VROOT to some child of root window */
+
+       XQueryTree(display, root, &troot, &parent, &children, &n);
+       for (i = 0; i < (int) n; i++) {
+               if (XGetWindowProperty
+                   (display, children[i], ATOM(__SWM_VROOT), 0, 1, False,
+                    XA_WINDOW, &type, &format, &nitems, &bytes,
+                    &buf) == Success && type == XA_WINDOW) {
+                       win = *(Window *) buf;
+                       XFree(buf);
+                       XFree(children);
+                       fprintf(stderr,
+                               "Conky: drawing to window from __SWM_VROOT property\n");
+                       return win;
+               }
+
+               if (buf) {
+                       XFree(buf);
+                       buf = 0;
+               }
+       }
+       XFree(children);
+
+       /* get subwindows from root */
+       win = find_subwindow(root, -1, -1);
+
+       update_workarea();
+
+       win = find_subwindow(win, workarea[2], workarea[3]);
+
+       if (buf) {
+               XFree(buf);
+               buf = 0;
+       }
+
+       if (win != root)
+               fprintf(stderr,
+                       "Conky: drawing to subwindow of root window (%lx)\n",
+                       win);
+       else
+               fprintf(stderr, "Conky: drawing to root window\n");
+
+       return win;
+}
+
+/* sets background to ParentRelative for the Window and all parents */
+void set_transparent_background(Window win)
+{
+       Window parent = win;
+       unsigned int i;
+       for (i = 0; i < 16 && parent != RootWindow(display, screen); i++) {
+               Window r, *children;
+               unsigned int n;
+
+               XSetWindowBackgroundPixmap(display, parent,
+                                          ParentRelative);
+
+               XQueryTree(display, parent, &r, &parent, &children, &n);
+               XFree(children);
+       }
+       XClearWindow(display, win);
+}
+
+#if defined OWN_WINDOW
+void init_window(int own_window, int w, int h, int l, int fixed_pos)
+#else
+void init_window(int own_window, int w, int h, int l)
+#endif
+{
+       /* There seems to be some problems with setting transparent background (on
+        * fluxbox this time). It doesn't happen always and I don't know why it
+        * happens but I bet the bug is somewhere here. */
+#ifdef OWN_WINDOW
+       if (own_window) {
+               /* looks like root pixmap isn't needed for anything */
+               {
+                       XSetWindowAttributes attrs;
+                       XClassHint class_hints;
+
+                       /* just test color
+                       attrs.background_pixel = get_x11_color("green");
+                       */
+
+                       window.window = XCreateWindow(display, RootWindow(display, screen), window.x, window.y, w, h, 0, CopyFromParent,        /* depth */
+                                                     CopyFromParent,   /* class */
+                                                     CopyFromParent,   /* visual */
+                                                     CWBackPixel, &attrs);
+
+                       class_hints.res_class = "conky";
+                       class_hints.res_name = "conky";
+                       XSetClassHint(display, window.window,
+                                     &class_hints);
+
+                       set_transparent_background(window.window);
+
+                       XStoreName(display, window.window, "conky");
+
+                       XClearWindow(display, window.window);
+
+                       if (!fixed_pos)
+                               XMoveWindow(display, window.window, window.x,
+                                           window.y);
+               }
+
+               {
+                       /* turn off decorations */
+                       Atom a =
+                           XInternAtom(display, "_MOTIF_WM_HINTS", True);
+                       if (a != None) {
+                               long prop[5] = { 2, 0, 0, 0, 0 };
+                               XChangeProperty(display, window.window, a,
+                                               a, 32, PropModeReplace,
+                                               (unsigned char *) prop, 5);
+                       }
+
+                       /* set window sticky (to all desktops) */
+                       a = XInternAtom(display, "_NET_WM_DESKTOP", True);
+                       if (a != None) {
+                               long prop = 0xFFFFFFFF;
+                               XChangeProperty(display, window.window, a,
+                                               XA_CARDINAL, 32,
+                                               PropModeReplace,
+                                               (unsigned char *) &prop,
+                                               1);
+                       }
+                       if(l) {
+                       /* make sure the layer is on the bottom */
+         a = XInternAtom(display, "_WIN_LAYER", True);
+         if (a != None) {
+            long prop = 0;
+            XChangeProperty(display, window.window, a,
+            XA_CARDINAL, 32,
+            PropModeReplace,
+            (unsigned char *) &prop, 1);
+         }
+                       }
+               }
+
+               XMapWindow(display, window.window);
+       } else
+#endif
+               /* root / desktop window */
+       {
+               XWindowAttributes attrs;
+
+               if (!window.window)
+                       window.window = find_window_to_draw();
+
+               if (XGetWindowAttributes(display, window.window, &attrs)) {
+                       window.width = attrs.width;
+                       window.height = attrs.height;
+               }
+       }
+
+       /* Drawable is same as window. This may be changed by double buffering. */
+       window.drawable = window.window;
+
+#ifdef XDBE
+       if (use_xdbe) {
+               int major, minor;
+               if (!XdbeQueryExtension(display, &major, &minor)) {
+                       use_xdbe = 0;
+               } else {
+                       window.back_buffer =
+                           XdbeAllocateBackBufferName(display,
+                                                      window.window,
+                                                      XdbeBackground);
+                       if (window.back_buffer != None) {
+                               window.drawable = window.back_buffer;
+                               fprintf(stderr,
+                                       "Conky: drawing to double buffer\n");
+                       } else
+                               use_xdbe = 0;
+               }
+               if (!use_xdbe)
+                       ERR("failed to set up double buffer");
+       }
+       if (!use_xdbe)
+               fprintf(stderr, "Conky: drawing to single buffer\n");
+#endif
+
+       XFlush(display);
+
+       /* set_transparent_background() must be done after double buffer stuff? */
+#ifdef OWN_WINDOW
+       if (own_window) {
+               set_transparent_background(window.window);
+               XClearWindow(display, window.window);
+       }
+#endif
+
+       XSelectInput(display, window.window, ExposureMask
+#ifdef OWN_WINDOW
+                    | (own_window
+                       ? (StructureNotifyMask | PropertyChangeMask) : 0)
+#endif
+           );
+}
+
+static Window find_subwindow(Window win, int w, int h)
+{
+       unsigned int i, j;
+       Window troot, parent, *children;
+       unsigned int n;
+
+       /* search subwindows with same size as display or work area */
+
+       for (i = 0; i < 10; i++) {
+               XQueryTree(display, win, &troot, &parent, &children, &n);
+
+               for (j = 0; j < n; j++) {
+                       XWindowAttributes attrs;
+
+                       if (XGetWindowAttributes
+                           (display, children[j], &attrs)) {
+                               /* Window must be mapped and same size as display or work space */
+                               if (attrs.map_state != 0 &&
+                                   ((attrs.width == display_width
+                                     && attrs.height == display_height)
+                                    || (attrs.width == w
+                                        && attrs.height == h))) {
+                                       win = children[j];
+                                       break;
+                               }
+                       }
+               }
+
+               XFree(children);
+               if (j == n)
+                       break;
+       }
+
+       return win;
+}
+
+long get_x11_color(const char *name)
+{
+       XColor color;
+       color.pixel = 0;
+       if (!XParseColor
+           (display, DefaultColormap(display, screen), name, &color)) {
+               ERR("can't parse X color '%s'", name);
+               return 0xFF00FF;
+       }
+       if (!XAllocColor
+           (display, DefaultColormap(display, screen), &color))
+               ERR("can't allocate X color '%s'", name);
+
+       return (long) color.pixel;
+}
+
+void create_gc()
+{
+       XGCValues values;
+       values.graphics_exposures = 0;
+       values.function = GXcopy;
+       window.gc = XCreateGC(display, window.drawable,
+                             GCFunction | GCGraphicsExposures, &values);
+}
diff --git a/top.c b/top.c
deleted file mode 100644 (file)
index 511e3b5..0000000
--- a/top.c
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- * Conky, a system monitor, based on torsmo
- *
- * This program is licensed under BSD license, read COPYING
- *
- *  $Id$
- */
-
-#include "top.h"
-
-static regex_t *exclusion_expression = 0;
-static unsigned int g_time = 0;
-static int previous_total = 0;
-static struct process *first_process = 0;
-
-static struct process *find_process(pid_t pid)
-{
-       struct process *p = first_process;
-       while (p) {
-               if (p->pid == pid)
-                       return p;
-               p = p->next;
-       }
-       return 0;
-}
-
-/*
-* Create a new process object and insert it into the process list
-*/
-static struct process *new_process(int p)
-{
-       struct process *process;
-       process = malloc(sizeof(struct process));
-
-       /*
-        * Do stitching necessary for doubly linked list
-        */
-       process->name = 0;
-       process->previous = 0;
-       process->next = first_process;
-       if (process->next)
-               process->next->previous = process;
-       first_process = process;
-
-       process->pid = p;
-       process->time_stamp = 0;
-       process->previous_user_time = INT_MAX;
-       process->previous_kernel_time = INT_MAX;
-       process->counted = 1;
-
-       /*    process_find_name(process); */
-
-       return process;
-}
-
-/******************************************/
-/* Functions                              */
-/******************************************/
-
-static int process_parse_stat(struct process *);
-static int update_process_table(void);
-static int calculate_cpu(struct process *);
-static void process_cleanup(void);
-static void delete_process(struct process *);
-/*inline void draw_processes(void);*/
-static int calc_cpu_total(void);
-static void calc_cpu_each(int);
-
-
-/******************************************/
-/* 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)
-{
-       struct information *cur;
-       cur = &info;
-       char line[BUFFER_LEN], filename[BUFFER_LEN], procname[BUFFER_LEN];
-       int ps;
-       int user_time, kernel_time;
-       int rc;
-       char *r, *q;
-       char deparenthesised_name[BUFFER_LEN];
-       int endl;
-       int nice_val;
-
-       snprintf(filename, sizeof(filename), PROCFS_TEMPLATE,
-                process->pid);
-
-       ps = open(filename, O_RDONLY);
-       if (ps < 0)
-               /*
-                * The process must have finished in the last few jiffies!
-                */
-               return 1;
-
-       /*
-        * Mark process as up-to-date.
-        */
-       process->time_stamp = g_time;
-
-       rc = read(ps, line, sizeof(line));
-       close(ps);
-       if (rc < 0)
-               return 1;
-
-       /*
-        * Extract cpu times from data in /proc filesystem
-        */
-       rc = sscanf(line,
-                   "%*s %s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %d %d %*s %*s %*s %d %*s %*s %*s %d %d",
-                   procname, &process->user_time, &process->kernel_time,
-                   &nice_val, &process->vsize, &process->rss);
-       if (rc < 5)
-               return 1;
-       /*
-        * Remove parentheses from the process name stored in /proc/ under Linux...
-        */
-       r = procname + 1;
-       /* remove any "kdeinit: " */
-       if (r == strstr(r, "kdeinit")) {
-               snprintf(filename, sizeof(filename),
-                        PROCFS_CMDLINE_TEMPLATE, process->pid);
-
-               ps = open(filename, O_RDONLY);
-               if (ps < 0)
-                       /*
-                        * The process must have finished in the last few jiffies!
-                        */
-                       return 1;
-
-               endl = read(ps, line, sizeof(line));
-               close(ps);
-
-               /* null terminate the input */
-               line[endl] = 0;
-               /* account for "kdeinit: " */
-               if ((char *) line == strstr(line, "kdeinit: "))
-                       r = ((char *) line) + 9;
-               else
-                       r = (char *) line;
-
-               q = deparenthesised_name;
-               /* stop at space */
-               while (*r && *r != ' ')
-                       *q++ = *r++;
-               *q = 0;
-       } else {
-               q = deparenthesised_name;
-               while (*r && *r != ')')
-                       *q++ = *r++;
-               *q = 0;
-       }
-
-       if (process->name)
-               free(process->name);
-       process->name = strdup(deparenthesised_name);
-       process->rss *= getpagesize();
-
-       if (!cur->memmax)
-               update_total_processes();
-
-       process->totalmem = ((float) process->rss / cur->memmax) / 10;
-
-       if (process->previous_user_time == INT_MAX)
-               process->previous_user_time = process->user_time;
-       if (process->previous_kernel_time == INT_MAX)
-               process->previous_kernel_time = process->kernel_time;
-
-       /* store the difference of the user_time */
-       user_time = process->user_time - process->previous_user_time;
-       kernel_time = process->kernel_time - process->previous_kernel_time;
-
-       /* backup the process->user_time for next time around */
-       process->previous_user_time = process->user_time;
-       process->previous_kernel_time = process->kernel_time;
-
-       /* store only the difference of the user_time here... */
-       process->user_time = user_time;
-       process->kernel_time = kernel_time;
-
-
-       return 0;
-}
-
-/******************************************/
-/* Update process table                   */
-/******************************************/
-
-static int update_process_table()
-{
-       DIR *dir;
-       struct dirent *entry;
-
-       if (!(dir = opendir("/proc")))
-               return 1;
-
-       ++g_time;
-
-       /*
-        * Get list of processes from /proc directory
-        */
-       while ((entry = readdir(dir))) {
-               pid_t pid;
-
-               if (!entry) {
-                       /*
-                        * Problem reading list of processes
-                        */
-                       closedir(dir);
-                       return 1;
-               }
-
-               if (sscanf(entry->d_name, "%d", &pid) > 0) {
-                       struct process *p;
-                       p = find_process(pid);
-                       if (!p)
-                               p = new_process(pid);
-
-                       /* compute each process cpu usage */
-                       calculate_cpu(p);
-               }
-       }
-
-       closedir(dir);
-
-       return 0;
-}
-
-/******************************************/
-/* Get process structure for process pid  */
-/******************************************/
-
-/*
-* This function seems to hog all of the CPU time. I can't figure out why - it
-* doesn't do much.
-*/
-static int calculate_cpu(struct process *process)
-{
-       int rc;
-
-       /* compute each process cpu usage by reading /proc/<proc#>/stat */
-       rc = process_parse_stat(process);
-       if (rc)
-               return 1;
-       /*rc = process_parse_statm(process);
-          if (rc)
-          return 1; */
-
-       /*
-        * Check name against the exclusion list
-        */
-       if (process->counted && exclusion_expression
-           && !regexec(exclusion_expression, process->name, 0, 0, 0))
-               process->counted = 0;
-
-       return 0;
-}
-
-/******************************************/
-/* Strip dead process entries             */
-/******************************************/
-
-static void process_cleanup()
-{
-
-       struct process *p = first_process;
-       while (p) {
-               struct process *current = p;
-
-#if defined(PARANOID)
-               assert(p->id == 0x0badfeed);
-#endif                         /* defined(PARANOID) */
-
-               p = p->next;
-               /*
-                * Delete processes that have died
-                */
-               if (current->time_stamp != g_time)
-                       delete_process(current);
-       }
-}
-
-/******************************************/
-/* Destroy and remove a process           */
-/******************************************/
-
-static void delete_process(struct process *p)
-{
-#if defined(PARANOID)
-       assert(p->id == 0x0badfeed);
-
-       /*
-        * Ensure that deleted processes aren't reused.
-        */
-       p->id = 0x007babe;
-#endif                         /* defined(PARANOID) */
-
-       /*
-        * Maintain doubly linked list.
-        */
-       if (p->next)
-               p->next->previous = p->previous;
-       if (p->previous)
-               p->previous->next = p->next;
-       else
-               first_process = p->next;
-
-       if (p->name)
-               free(p->name);
-       free(p);
-}
-
-/******************************************/
-/* Calculate cpu total                    */
-/******************************************/
-
-static int calc_cpu_total()
-{
-       int total, t;
-       int rc;
-       int ps;
-       char line[BUFFER_LEN];
-       int cpu, nice, system, idle;
-
-       ps = open("/proc/stat", O_RDONLY);
-       rc = read(ps, line, sizeof(line));
-       close(ps);
-       if (rc < 0)
-               return 0;
-       sscanf(line, "%*s %d %d %d %d", &cpu, &nice, &system, &idle);
-       total = cpu + nice + system + idle;
-
-       t = total - previous_total;
-       previous_total = total;
-
-       if (t < 0)
-               t = 0;
-
-       return t;
-}
-
-/******************************************/
-/* Calculate each processes cpu           */
-/******************************************/
-
-inline static void calc_cpu_each(int total)
-{
-       struct process *p = first_process;
-       while (p) {
-               /*p->amount = total ?
-                  (100.0 * (float) (p->user_time + p->kernel_time) /
-                  total) : 0; */
-               p->amount =
-                   (100.0 * (p->user_time + p->kernel_time) / total);
-
-/*             if (p->amount > 100)
-               p->amount = 0;*/
-               p = p->next;
-       }
-}
-
-/******************************************/
-/* Find the top processes                 */
-/******************************************/
-
-/*
-* Result is stored in decreasing order in best[0-9].
-*/
-#define MAX_TOP_SIZE 400 /* this is plenty big */
-static struct process **sorttmp;
-static size_t sorttmp_size = 10;
-
-inline void process_find_top(struct process **cpu, struct process **mem)
-{
-       struct process *pr;
-       if (sorttmp == NULL) {
-               sorttmp = malloc(sizeof(struct process) * sorttmp_size);
-               assert(sorttmp != NULL);
-       }
-       int total;
-       unsigned int i, max;
-
-       total = calc_cpu_total();       /* calculate the total of the processor */
-
-       update_process_table(); /* update the table with process list */
-       calc_cpu_each(total);   /* and then the percentage for each task */
-       process_cleanup();      /* cleanup list from exited processes */
-
-       /*
-        * this is really ugly,
-        * not to mention probably not too efficient.
-        * the main problem is that there could be any number of processes,
-        * however we have to use a fixed size for the "best" array.
-        * right now i can't think of a better way to do this,
-        * although i'm sure there is one.
-        * Perhaps just using a linked list would be more effecient?
-        * I'm too fucking lazy to do that right now.
-        */
-       if (top_cpu) {
-               pr = first_process;
-               i = 0;
-               while (pr) {
-                       if (i < sorttmp_size && pr->counted) {
-                               sorttmp[i] = pr;
-                               i++;
-                       } else if (i == sorttmp_size && pr->counted && sorttmp_size < MAX_TOP_SIZE) {
-                               sorttmp_size++;
-                               sorttmp =
-                                   realloc(sorttmp,
-                                           sizeof(struct process) *
-                                           sorttmp_size);
-                               sorttmp[i] = pr;
-                               i++;
-                       }
-                       pr = pr->next;
-               }
-               if (i + 1 < sorttmp_size) {
-                       sorttmp_size--;
-                       sorttmp =
-                           realloc(sorttmp,
-                                   sizeof(struct process) * sorttmp_size);
-               }
-               max = i;
-               for (i = 0; i < max - 1; i++) {
-                       while (sorttmp[i + 1]->amount > sorttmp[i]->amount) {
-                               pr = sorttmp[i];
-                               sorttmp[i] = sorttmp[i + 1];
-                               sorttmp[i + 1] = pr;
-                               if (i > 0)
-                                       i--;
-                               else
-                                       break;
-                       }
-
-               }
-               for (i = max; i > 1; i--);
-               {
-                       while (sorttmp[i]->amount > sorttmp[i - 1]->amount) {
-                               pr = sorttmp[i];
-                               sorttmp[i] = sorttmp[i - 1];
-                               sorttmp[i - 1] = pr;
-                               if (i < max)
-                                       i++;
-                               else
-                                       break;
-                       }
-               }
-               for (i = 0; i < 10; i++) {
-                       cpu[i] = sorttmp[i];
-
-               }
-       }
-       if (top_mem) {
-               pr = first_process;
-               i = 0;
-               while (pr) {
-                       if (i < sorttmp_size && pr->counted) {
-                               sorttmp[i] = pr;
-                               i++;
-                       } else if (i == sorttmp_size && pr->counted && sorttmp_size < MAX_TOP_SIZE) {
-                               sorttmp_size++;
-                               sorttmp =
-                                   realloc(sorttmp,
-                                           sizeof(struct process) *
-                                           sorttmp_size);
-                               sorttmp[i] = pr;
-                               i++;
-                       }
-                       pr = pr->next;
-               }
-               if (i + 1 < sorttmp_size) {
-                       sorttmp_size--;
-                       sorttmp =
-                           realloc(sorttmp,
-                                   sizeof(struct process) * sorttmp_size);
-               }
-               max = i;
-               for (i = 0; i < max - 1; i++) {
-                       while (sorttmp[i + 1]->totalmem >
-                              sorttmp[i]->totalmem) {
-                               pr = sorttmp[i];
-                               sorttmp[i] = sorttmp[i + 1];
-                               sorttmp[i + 1] = pr;
-                               if (i > 0)
-                                       i--;
-                               else
-                                       break;
-                       }
-
-               }
-               for (i = max; i > 1; i--);
-               {
-                       while (sorttmp[i]->totalmem >
-                              sorttmp[i - 1]->totalmem) {
-                               pr = sorttmp[i];
-                               sorttmp[i] = sorttmp[i - 1];
-                               sorttmp[i - 1] = pr;
-                               if (i < max)
-                                       i++;
-                               else
-                                       break;
-                       }
-               }
-               for (i = 0; i < 10; i++) {
-                       mem[i] = sorttmp[i];
-
-               }
-       }
-}
diff --git a/top.h b/top.h
deleted file mode 100644 (file)
index 18f899e..0000000
--- a/top.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * top.c a slightly modified wmtop.c -- copied from the WindowMaker and gkrelltop
- * 
- * Modified by Brenden Matthews
- *
- * Modified by Adi Zaimi
- *
- * Derived by Dan Piponi dan@tanelorn.demon.co.uk
- * http://www.tanelorn.demon.co.uk
- * http://wmtop.sourceforge.net 
- * from code originally contained in wmsysmon by Dave Clark 
-(clarkd@skynet.ca)
- * This software is licensed through the GNU General Public License.
- *  $Id$
- */
-
-/*
- * Ensure there's an operating system defined. There is *no* default
- * because every OS has it's own way of revealing CPU/memory usage.
- * compile with gcc -DOS ...
- */
-
-/******************************************/
-/* Includes                               */
-/******************************************/
-
-#include "conky.h"
-#define CPU_THRESHHOLD   0     /* threshhold for the cpu diff to appear */
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <dirent.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <math.h>
-#include <assert.h>
-#include <limits.h>
-#include <errno.h>
-#include <signal.h>
-
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-
-#include <regex.h>
-
-/******************************************/
-/* 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.
- */
-#define BUFFER_LEN 1024
-
-#define PROCFS_TEMPLATE "/proc/%d/stat"
-#define PROCFS_TEMPLATE_MEM "/proc/%d/statm"
-#define PROCFS_CMDLINE_TEMPLATE "/proc/%d/cmdline"
-
-
-/******************************************/
-/* Globals                                */
-/******************************************/
-
-
-
-
-
-
-
-/******************************************/
-/* Process class                          */
-/******************************************/
-
-/*
- * Pointer to head of process list
- */
-void process_find_top(struct process **, struct process **);
diff --git a/x11.c b/x11.c
deleted file mode 100644 (file)
index e0b6d9e..0000000
--- a/x11.c
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * Conky, a system monitor, based on torsmo
- *
- * This program is licensed under BSD license, read COPYING
- *
- *  $Id$
- */
-
-#include "conky.h"
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/Xutil.h>
-#ifdef XFT
-#include <X11/Xft/Xft.h>
-#endif
-
-#ifdef XDBE
-int use_xdbe;
-#endif
-
-#ifdef XFT
-int use_xft = 0;
-#endif
-
-/* some basic X11 stuff */
-Display *display;
-int display_width;
-int display_height;
-int screen;
-
-/* workarea from _NET_WORKAREA, this is where window / text is aligned */
-int workarea[4];
-
-/* Window stuff */
-struct conky_window window;
-
-/* local prototypes */
-static void update_workarea();
-static Window find_window_to_draw();
-static Window find_subwindow(Window win, int w, int h);
-
-/* X11 initializer */
-void init_X11()
-{
-       if ((display = XOpenDisplay(0)) == NULL)
-               CRIT_ERR("can't open display: %s", XDisplayName(0));
-
-       screen = DefaultScreen(display);
-       display_width = DisplayWidth(display, screen);
-       display_height = DisplayHeight(display, screen);
-
-       update_workarea();
-}
-
-static void update_workarea()
-{
-       Window root = RootWindow(display, screen);
-       unsigned long nitems, bytes;
-       unsigned char *buf = NULL;
-       Atom type;
-       int format;
-
-       /* default work area is display */
-       workarea[0] = 0;
-       workarea[1] = 0;
-       workarea[2] = display_width;
-       workarea[3] = display_height;
-
-       /* get current desktop */
-       if (XGetWindowProperty(display, root, ATOM(_NET_CURRENT_DESKTOP),
-                              0, 1, False, XA_CARDINAL, &type, &format,
-                              &nitems, &bytes, &buf) == Success
-           && type == XA_CARDINAL && nitems > 0) {
-
-               //Currently unused 
-               /*  long desktop = * (long *) buf; */
-
-               XFree(buf);
-               buf = 0;
-
-       }
-
-       if (buf) {
-               XFree(buf);
-               buf = 0;
-       }
-}
-
-static Window find_window_to_draw()
-{
-       Atom type;
-       int format, i;
-       unsigned long nitems, bytes;
-       unsigned int n;
-       Window root = RootWindow(display, screen);
-       Window win = root;
-       Window troot, parent, *children;
-       unsigned char *buf = NULL;
-
-       /* some window managers set __SWM_VROOT to some child of root window */
-
-       XQueryTree(display, root, &troot, &parent, &children, &n);
-       for (i = 0; i < (int) n; i++) {
-               if (XGetWindowProperty
-                   (display, children[i], ATOM(__SWM_VROOT), 0, 1, False,
-                    XA_WINDOW, &type, &format, &nitems, &bytes,
-                    &buf) == Success && type == XA_WINDOW) {
-                       win = *(Window *) buf;
-                       XFree(buf);
-                       XFree(children);
-                       fprintf(stderr,
-                               "Conky: drawing to window from __SWM_VROOT property\n");
-                       return win;
-               }
-
-               if (buf) {
-                       XFree(buf);
-                       buf = 0;
-               }
-       }
-       XFree(children);
-
-       /* get subwindows from root */
-       win = find_subwindow(root, -1, -1);
-
-       update_workarea();
-
-       win = find_subwindow(win, workarea[2], workarea[3]);
-
-       if (buf) {
-               XFree(buf);
-               buf = 0;
-       }
-
-       if (win != root)
-               fprintf(stderr,
-                       "Conky: drawing to subwindow of root window (%lx)\n",
-                       win);
-       else
-               fprintf(stderr, "Conky: drawing to root window\n");
-
-       return win;
-}
-
-/* sets background to ParentRelative for the Window and all parents */
-void set_transparent_background(Window win)
-{
-       Window parent = win;
-       unsigned int i;
-       for (i = 0; i < 16 && parent != RootWindow(display, screen); i++) {
-               Window r, *children;
-               unsigned int n;
-
-               XSetWindowBackgroundPixmap(display, parent,
-                                          ParentRelative);
-
-               XQueryTree(display, parent, &r, &parent, &children, &n);
-               XFree(children);
-       }
-       XClearWindow(display, win);
-}
-
-#if defined OWN_WINDOW
-void init_window(int own_window, int w, int h, int l, int fixed_pos)
-#else
-void init_window(int own_window, int w, int h, int l)
-#endif
-{
-       /* There seems to be some problems with setting transparent background (on
-        * fluxbox this time). It doesn't happen always and I don't know why it
-        * happens but I bet the bug is somewhere here. */
-#ifdef OWN_WINDOW
-       if (own_window) {
-               /* looks like root pixmap isn't needed for anything */
-               {
-                       XSetWindowAttributes attrs;
-                       XClassHint class_hints;
-
-                       /* just test color
-                       attrs.background_pixel = get_x11_color("green");
-                       */
-
-                       window.window = XCreateWindow(display, RootWindow(display, screen), window.x, window.y, w, h, 0, CopyFromParent,        /* depth */
-                                                     CopyFromParent,   /* class */
-                                                     CopyFromParent,   /* visual */
-                                                     CWBackPixel, &attrs);
-
-                       class_hints.res_class = "conky";
-                       class_hints.res_name = "conky";
-                       XSetClassHint(display, window.window,
-                                     &class_hints);
-
-                       set_transparent_background(window.window);
-
-                       XStoreName(display, window.window, "conky");
-
-                       XClearWindow(display, window.window);
-
-                       if (!fixed_pos)
-                               XMoveWindow(display, window.window, window.x,
-                                           window.y);
-               }
-
-               {
-                       /* turn off decorations */
-                       Atom a =
-                           XInternAtom(display, "_MOTIF_WM_HINTS", True);
-                       if (a != None) {
-                               long prop[5] = { 2, 0, 0, 0, 0 };
-                               XChangeProperty(display, window.window, a,
-                                               a, 32, PropModeReplace,
-                                               (unsigned char *) prop, 5);
-                       }
-
-                       /* set window sticky (to all desktops) */
-                       a = XInternAtom(display, "_NET_WM_DESKTOP", True);
-                       if (a != None) {
-                               long prop = 0xFFFFFFFF;
-                               XChangeProperty(display, window.window, a,
-                                               XA_CARDINAL, 32,
-                                               PropModeReplace,
-                                               (unsigned char *) &prop,
-                                               1);
-                       }
-                       if(l) {
-                       /* make sure the layer is on the bottom */
-         a = XInternAtom(display, "_WIN_LAYER", True);
-         if (a != None) {
-            long prop = 0;
-            XChangeProperty(display, window.window, a,
-            XA_CARDINAL, 32,
-            PropModeReplace,
-            (unsigned char *) &prop, 1);
-         }
-                       }
-               }
-
-               XMapWindow(display, window.window);
-       } else
-#endif
-               /* root / desktop window */
-       {
-               XWindowAttributes attrs;
-
-               if (!window.window)
-                       window.window = find_window_to_draw();
-
-               if (XGetWindowAttributes(display, window.window, &attrs)) {
-                       window.width = attrs.width;
-                       window.height = attrs.height;
-               }
-       }
-
-       /* Drawable is same as window. This may be changed by double buffering. */
-       window.drawable = window.window;
-
-#ifdef XDBE
-       if (use_xdbe) {
-               int major, minor;
-               if (!XdbeQueryExtension(display, &major, &minor)) {
-                       use_xdbe = 0;
-               } else {
-                       window.back_buffer =
-                           XdbeAllocateBackBufferName(display,
-                                                      window.window,
-                                                      XdbeBackground);
-                       if (window.back_buffer != None) {
-                               window.drawable = window.back_buffer;
-                               fprintf(stderr,
-                                       "Conky: drawing to double buffer\n");
-                       } else
-                               use_xdbe = 0;
-               }
-               if (!use_xdbe)
-                       ERR("failed to set up double buffer");
-       }
-       if (!use_xdbe)
-               fprintf(stderr, "Conky: drawing to single buffer\n");
-#endif
-
-       XFlush(display);
-
-       /* set_transparent_background() must be done after double buffer stuff? */
-#ifdef OWN_WINDOW
-       if (own_window) {
-               set_transparent_background(window.window);
-               XClearWindow(display, window.window);
-       }
-#endif
-
-       XSelectInput(display, window.window, ExposureMask
-#ifdef OWN_WINDOW
-                    | (own_window
-                       ? (StructureNotifyMask | PropertyChangeMask) : 0)
-#endif
-           );
-}
-
-static Window find_subwindow(Window win, int w, int h)
-{
-       unsigned int i, j;
-       Window troot, parent, *children;
-       unsigned int n;
-
-       /* search subwindows with same size as display or work area */
-
-       for (i = 0; i < 10; i++) {
-               XQueryTree(display, win, &troot, &parent, &children, &n);
-
-               for (j = 0; j < n; j++) {
-                       XWindowAttributes attrs;
-
-                       if (XGetWindowAttributes
-                           (display, children[j], &attrs)) {
-                               /* Window must be mapped and same size as display or work space */
-                               if (attrs.map_state != 0 &&
-                                   ((attrs.width == display_width
-                                     && attrs.height == display_height)
-                                    || (attrs.width == w
-                                        && attrs.height == h))) {
-                                       win = children[j];
-                                       break;
-                               }
-                       }
-               }
-
-               XFree(children);
-               if (j == n)
-                       break;
-       }
-
-       return win;
-}
-
-long get_x11_color(const char *name)
-{
-       XColor color;
-       color.pixel = 0;
-       if (!XParseColor
-           (display, DefaultColormap(display, screen), name, &color)) {
-               ERR("can't parse X color '%s'", name);
-               return 0xFF00FF;
-       }
-       if (!XAllocColor
-           (display, DefaultColormap(display, screen), &color))
-               ERR("can't allocate X color '%s'", name);
-
-       return (long) color.pixel;
-}
-
-void create_gc()
-{
-       XGCValues values;
-       values.graphics_exposures = 0;
-       values.function = GXcopy;
-       window.gc = XCreateGC(display, window.drawable,
-                             GCFunction | GCGraphicsExposures, &values);
-}