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
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) \
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)
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) \
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
$(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)"
@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)
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 | \
$$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 | \
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 \
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"; \
+++ /dev/null
-/* -*- 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;
-}
+++ /dev/null
-/*
- * 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;
- }
-}
-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`
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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
+++ /dev/null
-#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
-}
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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);
-}
+++ /dev/null
-/*
- * 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__ */
#!/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}"
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:
+++ /dev/null
-/* 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");
-}
+++ /dev/null
-/* 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
+++ /dev/null
-/* 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);
-}
+++ /dev/null
-/*
- * 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;
- }
-}
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-#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;
-}
+++ /dev/null
-#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);
-}
+++ /dev/null
-/* 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";
-}
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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();
+++ /dev/null
-/*
-* 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 */
- }
-}
+++ /dev/null
-/*
- * 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);
+++ /dev/null
-#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);
-
-}
+++ /dev/null
-/* 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 */
-}
--- /dev/null
+/* -*- 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;
+}
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/* 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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+#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
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/* 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");
+}
--- /dev/null
+/* 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
--- /dev/null
+/* 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);
+}
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+#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;
+}
--- /dev/null
+#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);
+}
--- /dev/null
+/* 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";
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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();
--- /dev/null
+/*
+* 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 */
+ }
+}
--- /dev/null
+/*
+ * 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);
--- /dev/null
+#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);
+
+}
--- /dev/null
+/* 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 */
+}
--- /dev/null
+/*
+ * 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];
+
+ }
+ }
+}
--- /dev/null
+/*
+ * 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 **);
--- /dev/null
+/*
+ * 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);
+}
+++ /dev/null
-/*
- * 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];
-
- }
- }
-}
+++ /dev/null
-/*
- * 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 **);
+++ /dev/null
-/*
- * 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);
-}