From 7de6c1d06199e2dc00ed6b147542ce75a33bc0fe Mon Sep 17 00:00:00 2001 From: Brenden Matthews Date: Wed, 24 Sep 2008 06:59:45 +0000 Subject: [PATCH] * Introduced (buggy) support for IMAP IDLE * Added support for MOC (the console audio player) (thanks henux) * Added scroll step patch (thanks asto) git-svn-id: https://conky.svn.sourceforge.net/svnroot/conky/trunk/conky1@1252 7f574dfc-610e-0410-a909-a81674777703 --- AUTHORS | 6 + ChangeLog | 5 + README | 165 ++++++++++++++++--------- configure.ac.in | 14 +++ doc/conky.1 | 48 +++++++- doc/variables.xml | 103 +++++++++++++++- src/Makefile.am | 7 ++ src/common.c | 17 +++ src/conky.c | 298 ++++++++++++++++++++++++++++++++++++++------- src/conky.h | 13 +- src/timed_thread.c | 2 +- 11 files changed, 570 insertions(+), 108 deletions(-) diff --git a/AUTHORS b/AUTHORS index 3e766b1a..9f97a2b3 100644 --- a/AUTHORS +++ b/AUTHORS @@ -115,6 +115,9 @@ Gwenhael LE MOINE Hannu Saransaari Main code +Henri Häkkinen + MOC support + hinokind support negative values in human_readable() @@ -305,6 +308,9 @@ Toni Spets hifi Linux wifi code RSS code (created with Mikko Sysikaski) +Tris + Scroll step patch + tyir MPD features patch 1319461 diff --git a/ChangeLog b/ChangeLog index edf02ca1..2335773e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ # $Id$ +2008-09-24 + * Introduced (buggy) support for IMAP IDLE + * Added support for MOC (the console audio player) (thanks henux) + * Added scroll step patch (thanks asto) + 2008-09-11 * Maybe fix missing include bug (http://bugs.gentoo.org/show_bug.cgi?id=235233) diff --git a/README b/README index 58f7f4fc..a8f10199 100644 --- a/README +++ b/README @@ -1076,6 +1076,50 @@ conky(1) conky(1) Percentage of memory in use + 1mmoc_state0m + Current state of MOC; playing, stopped etc. + + + 1mmoc_file0m + File name of the current MOC song + + + 1mmoc_title0m + Title of the current MOC song + + + 1mmoc_artist0m + Artist of the current MOC song + + + 1mmoc_song0m + The current song name being played in MOC. + + + 1mmoc_album0m + Album of the current MOC song + + + 1mmoc_totaltime0m + Total length of the current MOC song + + + 1mmoc_timeleft0m + Time left in the current MOC song + + + 1mmoc_curtime0m + Current time of the current MOC song + + + 1mmoc_bitrate0m + Bitrate in the current MOC song + + + 1mmoc_rate0m + Rate of the current MOC song + + 1mmonitor0m Number of the monitor on which conky is running @@ -1239,16 +1283,17 @@ conky(1) conky(1) Running processes (not sleeping), requires Linux 2.6 - 1mscroll length text0m - Scroll ’text’ showing ’length’ number of characters at the same - time. The text may also contain variables. If a var creates out‐ - put on multiple lines then the lines are placed behind each oth‐ - er separated with a ’|’-sign. Do NOT use vars that change colors - or otherwise affect the design inside a scrolling text. If you - want spaces between the start and the end of ’text’, place them - at the end of ’text’ not at the front ("foobar" and " foobar" - can both generate "barfoo" but "foobar " will keep the spaces - like this "bar foo"). + 1mscroll length (step) text0m + Scroll ’text’ by ’step’ characters showing ’length’ number of + characters at the same time. The text may also contain vari‐ + ables. ’step’ is optional and defaults to 1 if not set. If a var + creates output on multiple lines then the lines are placed be‐ + hind each other separated with a ’|’-sign. Do NOT use vars that + change colors or otherwise affect the design inside a scrolling + text. If you want spaces between the start and the end of + ’text’, place them at the end of ’text’ not at the front ("foo‐ + bar" and " foobar" can both generate "barfoo" but "foobar " will + keep the spaces like this "bar foo"). 1mshadecolor (color)0m @@ -1256,35 +1301,35 @@ conky(1) conky(1) 1msmapi (ARGS)0m - when using smapi, display contents of the /sys/devices/plat‐ - form/smapi directory. ARGS are either ’(FILENAME)’ or ’bat (IN‐ - DEX) (FILENAME)’ to display the corresponding files’ content. - This is a very raw method of accessing the smapi values. When + when using smapi, display contents of the /sys/devices/plat‐ + form/smapi directory. ARGS are either ’(FILENAME)’ or ’bat (IN‐ + DEX) (FILENAME)’ to display the corresponding files’ content. + This is a very raw method of accessing the smapi values. When available, better use one of the smapi_* variables instead. 1msmapi_bat_bar (INDEX),(height),(width)0m - when using smapi, display the remaining capacity of the battery + when using smapi, display the remaining capacity of the battery with index INDEX as a bar. 1msmapi_bat_perc (INDEX)0m - when using smapi, display the remaining capacity in percent of - the battery with index INDEX. This is a separate variable be‐ + when using smapi, display the remaining capacity in percent of + the battery with index INDEX. This is a separate variable be‐ cause it supports the ’use_spacer’ configuration option. 1msmapi_bat_power INDEX0m - when using smapi, display the current power of the battery with - index INDEX in watt. This is a separate variable because the - original read out value is being converted from mW. The sign of - the output reflects charging (positive) or discharging (nega‐ + when using smapi, display the current power of the battery with + index INDEX in watt. This is a separate variable because the + original read out value is being converted from mW. The sign of + the output reflects charging (positive) or discharging (nega‐ tive) state. 1msmapi_bat_temp INDEX0m when using smapi, display the current temperature of the battery - with index INDEX in degree Celsius. This is a separate variable + with index INDEX in degree Celsius. This is a separate variable because the original read out value is being converted from mil‐ li degree Celsius. @@ -1329,36 +1374,36 @@ conky(1) conky(1) The connection index provides you with access to each connection in the port monitor. The monitor will return information for in‐ dex values from 0 to n-1 connections. Values higher than n-1 are - simply ignored. For the "count" item, the connection index must + simply ignored. For the "count" item, the connection index must be omitted. It is required for all other items. Examples: - 1m${tcp_portmon 6881 6999 count} 22m- displays the number of connec‐ + 1m${tcp_portmon 6881 6999 count} 22m- displays the number of connec‐ tions in the bittorrent port range - 1m${tcp_portmon 22 22 rip 0} 22m- displays the remote host ip of the + 1m${tcp_portmon 22 22 rip 0} 22m- displays the remote host ip of the first sshd connection - 1m${tcp_portmon 22 22 rip 9} 22m- displays the remote host ip of the + 1m${tcp_portmon 22 22 rip 9} 22m- displays the remote host ip of the tenth sshd connection 1m${tcp_portmon 1 1024 rhost 0} 22m- displays the remote host name of the first connection on a privileged port 1m${tcp_portmon 1 1024 rport 4} 22m- displays the remote host port of the fifth connection on a privileged port - 1m${tcp_portmon 1 65535 lservice 14} 22m- displays the local service + 1m${tcp_portmon 1 65535 lservice 14} 22m- displays the local service name of the fifteenth connection in the range of all ports Note that port monitor variables which share the same port range actually refer to the same monitor, so many references to a sin‐ gle port range for different items and different indexes all use - the same monitor internally. In other words, the program avoids + the same monitor internally. In other words, the program avoids creating redundant monitors. 1mtexeci interval command0m - Runs a command at an interval inside a thread and displays the - output. Same as $execi, except the command is run inside a - thread. Use this if you have a slow script to keep Conky updat‐ - ing. You should make the interval slightly longer then the time - it takes your script to execute. For example, if you have a - script that take 5 seconds to execute, you should make the in‐ + Runs a command at an interval inside a thread and displays the + output. Same as $execi, except the command is run inside a + thread. Use this if you have a slow script to keep Conky updat‐ + ing. You should make the interval slightly longer then the time + it takes your script to execute. For example, if you have a + script that take 5 seconds to execute, you should make the in‐ terval at least 6 seconds. See also $execi. @@ -1367,8 +1412,8 @@ conky(1) conky(1) 1mrss url delay_in_minutes action item_num0m - Download and parse RSS feeds. Action may be one of the follow‐ - ing: feed_title, item_title (with num par), item_desc (with num + Download and parse RSS feeds. Action may be one of the follow‐ + ing: feed_title, item_title (with num par), item_desc (with num par) and item_titles. @@ -1383,7 +1428,7 @@ conky(1) conky(1) 1mtime (format)0m - Local time, see man strftime to get more information about for‐ + Local time, see man strftime to get more information about for‐ mat @@ -1392,23 +1437,23 @@ conky(1) conky(1) 1mtztime (timezone) (format)0m - Local time for specified timezone, see man strftime to get more - information about format. The timezone argument is specified in - similar fashion as TZ environment variable. For hints, look in + Local time for specified timezone, see man strftime to get more + information about format. The timezone argument is specified in + similar fashion as TZ environment variable. For hints, look in /usr/share/zoneinfo. e.g. US/Pacific, Europe/Zurich, etc. 1mtotaldown net0m - Total download, overflows at 4 GB on Linux with 32-bit arch and + Total download, overflows at 4 GB on Linux with 32-bit arch and there doesn’t seem to be a way to know how many times it has al‐ ready done that before conky has started. 1mtop type, num0m - This takes arguments in the form:top (name) (number) Basically, - processes are ranked from highest to lowest in terms of cpu us‐ - age, which is what (num) represents. The types are: "name", - "pid", "cpu", "mem", "mem_res", "mem_vsize", and "time". There + This takes arguments in the form:top (name) (number) Basically, + processes are ranked from highest to lowest in terms of cpu us‐ + age, which is what (num) represents. The types are: "name", + "pid", "cpu", "mem", "mem_res", "mem_vsize", and "time". There can be a max of 10 processes listed. @@ -1432,11 +1477,11 @@ conky(1) conky(1) Upload speed in KiB with one decimal - 1mupspeedgraph normal|log net (height),(width) (gradient colour 1) (gra‐0m + 1mupspeedgraph normal|log net (height),(width) (gradient colour 1) (gra‐0m 1mdient colour 2) (scale)0m - Upload speed graph, colours defined in hex, minus the #. If - scale is non-zero, it becomes the scale for the graph. Uses a - logarithmic scale (to see small numbers) when you use "log" in‐ + Upload speed graph, colours defined in hex, minus the #. If + scale is non-zero, it becomes the scale for the graph. Uses a + logarithmic scale (to see small numbers) when you use "log" in‐ stead of "normal". @@ -1464,12 +1509,12 @@ conky(1) conky(1) 1mvoffset (pixels)0m - Change vertical offset by N pixels. Negative values will cause + Change vertical offset by N pixels. Negative values will cause text to overlap. See also $offset. 1mvoltage_mv (n)0m - Returns CPU #n’s voltage in mV. CPUs are counted from 1. If + Returns CPU #n’s voltage in mV. CPUs are counted from 1. If omitted, the parameter defaults to 1. @@ -1588,7 +1633,7 @@ conky(1) conky(1) 1meve api_userid api_key character_id0m - Fetches your currently training skill from the Eve Online API + Fetches your currently training skill from the Eve Online API servers (http://www.eve-online.com/) and displays the skill along with the remaining training time. @@ -1607,13 +1652,13 @@ conky(1) conky(1) 1mBUGS0m Drawing to root or some other desktop window directly doesn’t work with all window managers. Especially doesn’t work well with Gnome and it has - been reported that it doesn’t work with KDE either. Nautilus can be - disabled from drawing to desktop with program gconf-editor. Uncheck - show_desktop in /apps/nautilus/preferences/. There is -w switch in - Conky to set some specific window id. You might find xwininfo -tree - useful to find the window to draw to. You can also use -o argument + been reported that it doesn’t work with KDE either. Nautilus can be + disabled from drawing to desktop with program gconf-editor. Uncheck + show_desktop in /apps/nautilus/preferences/. There is -w switch in + Conky to set some specific window id. You might find xwininfo -tree + useful to find the window to draw to. You can also use -o argument which makes Conky to create its own window. If you do try running Conky - in its own window, be sure to read up on the own_window_type settings + in its own window, be sure to read up on the own_window_type settings and experiment. 1mSEE ALSO0m @@ -1624,11 +1669,11 @@ conky(1) conky(1) #conky on irc.freenode.net 1mCOPYING0m - Copyright (c) 2005-2008 Brenden Matthews, Philip Kovacs, et. al. Any + Copyright (c) 2005-2008 Brenden Matthews, Philip Kovacs, et. al. Any original torsmo code is licensed under the BSD license (see LICENSE.BSD for a copy). All code written since the fork of torsmo is licensed un‐ der the GPL (see LICENSE.GPL for a copy), except where noted different‐ - ly (such as in portmon code, timed thread code, and audacious code + ly (such as in portmon code, timed thread code, and audacious code which are LGPL, and prss which is an MIT-style license). 1mAUTHORS0m diff --git a/configure.ac.in b/configure.ac.in index 445d8783..56b21d61 100644 --- a/configure.ac.in +++ b/configure.ac.in @@ -203,6 +203,19 @@ if test x$want_mpd = xyes; then AC_DEFINE(MPD, 1, [Define if you want MPD support]) fi +dnl +dnl MOC +dnl + +AC_ARG_ENABLE([moc], + AC_HELP_STRING([--disable-moc], [disable if you do not want MOC support @<:@default=yes@:>@]), + [want_moc="$enableval"], [want_moc=yes]) + +AM_CONDITIONAL(BUILD_MOC, test x$want_moc = xyes) +if test x$want_moc = xyes; then + AC_DEFINE(MOC, 1, [Define if you want MOC support]) +fi + dnl dnl XMMS2 dnl @@ -680,6 +693,7 @@ $PACKAGE $VERSION configured successfully: Audacious: $want_audacious BMPx: $want_bmpx MPD: $want_mpd + MOC: $want_moc XMMS2: $want_xmms2 * General: diff --git a/doc/conky.1 b/doc/conky.1 index 89b883d0..2581bae8 100644 --- a/doc/conky.1 +++ b/doc/conky.1 @@ -908,6 +908,50 @@ Total amount of memory \fB\*(T<\fBmemperc\fR\*(T>\fR Percentage of memory in use +.TP +\fB\*(T<\fBmoc_state\fR\*(T>\fR +Current state of MOC; playing, stopped etc. + +.TP +\fB\*(T<\fBmoc_file\fR\*(T>\fR +File name of the current MOC song + +.TP +\fB\*(T<\fBmoc_title\fR\*(T>\fR +Title of the current MOC song + +.TP +\fB\*(T<\fBmoc_artist\fR\*(T>\fR +Artist of the current MOC song + +.TP +\fB\*(T<\fBmoc_song\fR\*(T>\fR +The current song name being played in MOC. + +.TP +\fB\*(T<\fBmoc_album\fR\*(T>\fR +Album of the current MOC song + +.TP +\fB\*(T<\fBmoc_totaltime\fR\*(T>\fR +Total length of the current MOC song + +.TP +\fB\*(T<\fBmoc_timeleft\fR\*(T>\fR +Time left in the current MOC song + +.TP +\fB\*(T<\fBmoc_curtime\fR\*(T>\fR +Current time of the current MOC song + +.TP +\fB\*(T<\fBmoc_bitrate\fR\*(T>\fR +Bitrate in the current MOC song + +.TP +\fB\*(T<\fBmoc_rate\fR\*(T>\fR +Rate of the current MOC song + .TP \fB\*(T<\fBmonitor\fR\*(T>\fR Number of the monitor on which conky is running @@ -1067,8 +1111,8 @@ Total processes (sleeping and running) Running processes (not sleeping), requires Linux 2.6 .TP -\fB\*(T<\fBscroll\fR\*(T>\fR \*(T<\fBlength text\fR\*(T> -Scroll 'text' showing 'length' number of characters at the same time. The text may also contain variables. If a var creates output on multiple lines then the lines are placed behind each other separated with a '|'-sign. Do NOT use vars that change colors or otherwise affect the design inside a scrolling text. If you want spaces between the start and the end of 'text', place them at the end of 'text' not at the front ("foobar" and " foobar" can both generate "barfoo" but "foobar " will keep the spaces like this "bar foo"). +\fB\*(T<\fBscroll\fR\*(T>\fR \*(T<\fBlength (step) text\fR\*(T> +Scroll 'text' by 'step' characters showing 'length' number of characters at the same time. The text may also contain variables. 'step' is optional and defaults to 1 if not set. If a var creates output on multiple lines then the lines are placed behind each other separated with a '|'-sign. Do NOT use vars that change colors or otherwise affect the design inside a scrolling text. If you want spaces between the start and the end of 'text', place them at the end of 'text' not at the front ("foobar" and " foobar" can both generate "barfoo" but "foobar " will keep the spaces like this "bar foo"). .TP \fB\*(T<\fBshadecolor\fR\*(T>\fR \*(T<\fB(color)\fR\*(T> diff --git a/doc/variables.xml b/doc/variables.xml index d8df26e8..81c194d4 100644 --- a/doc/variables.xml +++ b/doc/variables.xml @@ -1248,6 +1248,105 @@ + + + + + + Current state of MOC; playing, stopped etc. + + + + + + + + + File name of the current MOC song + + + + + + + + + Title of the current MOC song + + + + + + + + + Artist of the current MOC song + + + + + + + + + The current song name being played in MOC. + + + + + + + + + Album of the current MOC song + + + + + + + + + Total length of the current MOC song + + + + + + + + + Time left in the current MOC song + + + + + + + + + Current time of the current MOC song + + + + + + + + + Bitrate in the current MOC song + + + + + + + + + Rate of the current MOC song + + + @@ -1583,10 +1682,10 @@ - + - Scroll 'text' showing 'length' number of characters at the same time. The text may also contain variables. If a var creates output on multiple lines then the lines are placed behind each other separated with a '|'-sign. Do NOT use vars that change colors or otherwise affect the design inside a scrolling text. If you want spaces between the start and the end of 'text', place them at the end of 'text' not at the front ("foobar" and " foobar" can both generate "barfoo" but "foobar " will keep the spaces like this "bar foo"). + Scroll 'text' by 'step' characters showing 'length' number of characters at the same time. The text may also contain variables. 'step' is optional and defaults to 1 if not set. If a var creates output on multiple lines then the lines are placed behind each other separated with a '|'-sign. Do NOT use vars that change colors or otherwise affect the design inside a scrolling text. If you want spaces between the start and the end of 'text', place them at the end of 'text' not at the front ("foobar" and " foobar" can both generate "barfoo" but "foobar " will keep the spaces like this "bar foo"). diff --git a/src/Makefile.am b/src/Makefile.am index b1d9bc30..fdd03bf1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -40,6 +40,10 @@ if BUILD_MPD mpd = mpd.c libmpdclient.c endif +if BUILD_MOC +moc = moc.c +endif + if BUILD_XMMS2 xmms2 = xmms2.c endif @@ -109,6 +113,7 @@ conky_SOURCES = \ mail.c \ mixer.c \ $(mpd) \ + $(moc) \ $(netbsd) \ $(openbsd) \ $(port_monitors) \ @@ -146,6 +151,8 @@ EXTRA_DIST = \ rss.h \ mail.h \ mixer.h \ + moc.h \ + moc.c \ mpd.c \ mpd.h \ netbsd.c \ diff --git a/src/common.c b/src/common.c index 78edc5ad..4c31ee3d 100644 --- a/src/common.c +++ b/src/common.c @@ -330,6 +330,23 @@ void update_stuff(void) } #endif +#ifdef MOC + if (NEED(INFO_MOC)) { + if (!info.moc.timed_thread) { + init_moc(&info.moc); + info.moc.timed_thread = timed_thread_create(&update_moc, + (void *) &info.moc, info.music_player_interval * 100000); + if (!info.moc.timed_thread) { + ERR("Failed to create MOC timed thread"); + } + timed_thread_register(info.moc.timed_thread, &info.moc.timed_thread); + if (timed_thread_run(info.moc.timed_thread)) { + ERR("Failed to run MOC timed thread"); + } + } + } +#endif + #ifdef XMMS2 if (NEED(INFO_XMMS2)) { update_xmms2(); diff --git a/src/conky.c b/src/conky.c index 471e81a2..d26395d2 100644 --- a/src/conky.c +++ b/src/conky.c @@ -70,8 +70,9 @@ #define MAX_IF_BLOCK_DEPTH 5 #define MAX_TAIL_LINES 100 -/* #define SIGNAL_BLOCKING */ -#undef SIGNAL_BLOCKING +#define SIGNAL_BLOCKING +//#undef SIGNAL_BLOCKING +sigset_t oldmask; static void print_version(void) __attribute__((noreturn)); @@ -103,6 +104,9 @@ static void print_version(void) #ifdef MPD " * mpd\n" #endif /* MPD */ +#ifdef MOC + " * moc\n" +#endif /* MOC */ #ifdef XMMS2 " * xmms2\n" #endif /* XMMS2 */ @@ -138,6 +142,7 @@ static void print_version(void) static const char *suffixes[] = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "" }; + #ifdef X11 /* text size */ @@ -1313,6 +1318,19 @@ enum text_object_type { OBJ_mpd_file, OBJ_mpd_percent, OBJ_mpd_smart, +#endif +#ifdef MOC + OBJ_moc_state, + OBJ_moc_file, + OBJ_moc_title, + OBJ_moc_artist, + OBJ_moc_song, + OBJ_moc_album, + OBJ_moc_totaltime, + OBJ_moc_timeleft, + OBJ_moc_curtime, + OBJ_moc_bitrate, + OBJ_moc_rate, #endif OBJ_music_player_interval, #ifdef XMMS2 @@ -1511,6 +1529,7 @@ struct text_object { struct { char *text; unsigned int show; + unsigned int step; unsigned int start; } scroll; @@ -1635,14 +1654,15 @@ void *imap_thread(void *arg) char sendbuf[MAXDATASIZE]; char *reply; unsigned int fail = 0; - unsigned int old_unseen = UINT_MAX; - unsigned int old_messages = UINT_MAX; + unsigned long old_unseen = ULONG_MAX; + unsigned long old_messages = ULONG_MAX; struct stat stat_buf; struct hostent he, *he_res = 0; int he_errno; char hostbuff[2048]; struct sockaddr_in their_addr; // connector's address information struct mail_s *mail = (struct mail_s *)arg; + int has_idle = 0; #ifdef HAVE_GETHOSTBYNAME_R if (gethostbyname_r(mail->host, &he, hostbuff, sizeof(hostbuff), &he_res, &he_errno)) { // get the host info @@ -1736,6 +1756,10 @@ void *imap_thread(void *arg) fail++; break; } + if (strstr(recvbuf, " IDLE ") != NULL) { + has_idle = 1; + } + strncpy(sendbuf, "a2 STATUS ", MAXDATASIZE); strncat(sendbuf, mail->folder, MAXDATASIZE - strlen(sendbuf) - 1); strncat(sendbuf, " (MESSAGES UNSEEN)\r\n", @@ -1763,6 +1787,7 @@ void *imap_thread(void *arg) fail++; break; } + // now we get the data reply = strstr(recvbuf, " (MESSAGES "); reply += 2; @@ -1777,30 +1802,6 @@ void *imap_thread(void *arg) &mail->unseen); timed_thread_unlock(mail->p_timed_thread); } - strncpy(sendbuf, "a3 logout\r\n", MAXDATASIZE); - if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) { - perror("send a3"); - fail++; - break; - } - timeout.tv_sec = 60; // 60 second timeout i guess - timeout.tv_usec = 0; - FD_ZERO(&fdset); - FD_SET(sockfd, &fdset); - res = select(sockfd + 1, &fdset, NULL, NULL, &timeout); - if (res > 0) { - if ((numbytes = recv(sockfd, recvbuf, MAXDATASIZE - 1, 0)) == -1) { - perror("recv a3"); - fail++; - break; - } - } - recvbuf[numbytes] = '\0'; - if (strstr(recvbuf, "a3 OK") == NULL) { - ERR("IMAP logout failed: %s", recvbuf); - fail++; - break; - } if (strlen(mail->command) > 1 && (mail->unseen > old_unseen || (mail->messages > old_messages && mail->unseen > 0))) { // new mail goodie @@ -1811,6 +1812,147 @@ void *imap_thread(void *arg) fail = 0; old_unseen = mail->unseen; old_messages = mail->messages; + + if (has_idle) { + strncpy(sendbuf, "a4 SELECT ", MAXDATASIZE); + strncat(sendbuf, mail->folder, MAXDATASIZE - strlen(sendbuf) - 1); + strncat(sendbuf, "\r\n", MAXDATASIZE - strlen(sendbuf) - 1); + if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) { + perror("send a4"); + fail++; + break; + } + timeout.tv_sec = 60; // 60 second timeout i guess + timeout.tv_usec = 0; + FD_ZERO(&fdset); + FD_SET(sockfd, &fdset); + res = select(sockfd + 1, &fdset, NULL, NULL, &timeout); + if (res > 0) { + if ((numbytes = recv(sockfd, recvbuf, MAXDATASIZE - 1, 0)) == -1) { + perror("recv a4"); + fail++; + break; + } + } + recvbuf[numbytes] = '\0'; + if (strstr(recvbuf, "a4 OK") == NULL) { + ERR("IMAP status failed: %s", recvbuf); + fail++; + break; + } + + strncpy(sendbuf, "a5 IDLE\r\n", MAXDATASIZE); + if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) { + perror("send a5"); + fail++; + break; + } + timeout.tv_sec = 60; // 60 second timeout i guess + timeout.tv_usec = 0; + FD_ZERO(&fdset); + FD_SET(sockfd, &fdset); + res = select(sockfd + 1, &fdset, NULL, NULL, &timeout); + if (res > 0) { + if ((numbytes = recv(sockfd, recvbuf, MAXDATASIZE - 1, 0)) == -1) { + perror("recv a5"); + fail++; + break; + } + } + recvbuf[numbytes] = '\0'; + if (strstr(recvbuf, "+ idling") == NULL) { + ERR("IMAP status failed: %s", recvbuf); + fail++; + break; + } + recvbuf[0] = '\0'; + + while (1) { + FD_ZERO(&fdset); + FD_SET(sockfd, &fdset); + if (timed_thread_test(mail->p_timed_thread)) { + break; + } + res = pselect(sockfd + 1, &fdset, NULL, NULL, NULL, &oldmask); + if (res == -1 && errno == EINTR) { + timed_thread_exit(mail->p_timed_thread); + } else if (res > 0) { + if ((numbytes = recv(sockfd, recvbuf, MAXDATASIZE - 1, 0)) == -1) { + perror("recv idling"); + fail++; + printf("fail\n"); + break; + } + } else { + break; + } + recvbuf[numbytes] = '\0'; + if (strlen(recvbuf) > 2) { + unsigned long messages, unseen; + char *buf = recvbuf; + buf = strstr(buf, "EXISTS"); + if (buf) { + // back up until we reach '*' + while (buf >= recvbuf && buf[0] != '*') { + buf--; + } + if (sscanf(buf, "* %lu EXISTS\r\n", &messages) == 1) { + timed_thread_lock(mail->p_timed_thread); + mail->messages = messages; + timed_thread_unlock(mail->p_timed_thread); + } + } + buf = strstr(buf, "RECENT"); + if (buf) { + // back up until we reach '*' + while (buf >= recvbuf && buf[0] != '*') { + buf--; + } + if (sscanf(buf, "* %lu RECENT\r\n", &unseen) == 1) { + timed_thread_lock(mail->p_timed_thread); + mail->unseen = unseen; + timed_thread_unlock(mail->p_timed_thread); + } + } + } + if (strlen(mail->command) > 1 && (mail->unseen > old_unseen + || (mail->messages > old_messages && mail->unseen > 0))) { + // new mail goodie + if (system(mail->command) == -1) { + perror("system()"); + } + } + fail = 0; + old_unseen = mail->unseen; + old_messages = mail->messages; + + } + } else { + strncpy(sendbuf, "a3 logout\r\n", MAXDATASIZE); + if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) { + perror("send a3"); + fail++; + break; + } + timeout.tv_sec = 60; // 60 second timeout i guess + timeout.tv_usec = 0; + FD_ZERO(&fdset); + FD_SET(sockfd, &fdset); + res = select(sockfd + 1, &fdset, NULL, NULL, &timeout); + if (res > 0) { + if ((numbytes = recv(sockfd, recvbuf, MAXDATASIZE - 1, 0)) == -1) { + perror("recv a3"); + fail++; + break; + } + } + recvbuf[numbytes] = '\0'; + if (strstr(recvbuf, "a3 OK") == NULL) { + ERR("IMAP logout failed: %s", recvbuf); + fail++; + break; + } + } } while (0); if ((fstat(sockfd, &stat_buf) == 0) && S_ISSOCK(stat_buf.st_mode)) { /* if a valid socket, close it */ @@ -1832,7 +1974,7 @@ void *pop3_thread(void *arg) char sendbuf[MAXDATASIZE]; char *reply; unsigned int fail = 0; - unsigned int old_unseen = UINT_MAX; + unsigned long old_unseen = ULONG_MAX; struct stat stat_buf; struct hostent he, *he_res = 0; int he_errno; @@ -2391,6 +2533,21 @@ static void free_text_objects(struct text_object_list *text_object_list, char fu free_mpd_vars(&info.mpd); } break; +#endif +#ifdef MOC + case OBJ_moc_state: + case OBJ_moc_file: + case OBJ_moc_title: + case OBJ_moc_artist: + case OBJ_moc_song: + case OBJ_moc_album: + case OBJ_moc_totaltime: + case OBJ_moc_timeleft: + case OBJ_moc_curtime: + case OBJ_moc_bitrate: + case OBJ_moc_rate: + free_moc(&info.moc); + break; #endif case OBJ_scroll: free(obj->data.scroll.text); @@ -3828,6 +3985,19 @@ static struct text_object *construct_text_object(const char *s, obj->data.i = 0; } #endif /* MPD */ +#ifdef MOC + END OBJ_THREAD(moc_state, INFO_MOC) + END OBJ_THREAD(moc_file, INFO_MOC) + END OBJ_THREAD(moc_title, INFO_MOC) + END OBJ_THREAD(moc_artist, INFO_MOC) + END OBJ_THREAD(moc_song, INFO_MOC) + END OBJ_THREAD(moc_album, INFO_MOC) + END OBJ_THREAD(moc_totaltime, INFO_MOC) + END OBJ_THREAD(moc_timeleft, INFO_MOC) + END OBJ_THREAD(moc_curtime, INFO_MOC) + END OBJ_THREAD(moc_bitrate, INFO_MOC) + END OBJ_THREAD(moc_rate, INFO_MOC) +#endif /* MOC */ #ifdef XMMS2 END OBJ(xmms2_artist, INFO_XMMS2) END OBJ(xmms2_album, INFO_XMMS2) @@ -4030,11 +4200,12 @@ static struct text_object *construct_text_object(const char *s, END OBJ(scroll, 0) int n; - if (arg && sscanf(arg, "%u %n", &obj->data.scroll.show, &n) > 0) { + obj->data.scroll.step = 1; + if (arg && sscanf(arg, "%u %u %n", &obj->data.scroll.show, &obj->data.scroll.step, &n) > 0) { obj->data.scroll.text = strndup(arg + n, text_buffer_size); obj->data.scroll.start = 0; } else { - CRIT_ERR("scroll needs arguments: "); + CRIT_ERR("scroll needs arguments: [] "); } #ifdef NVIDIA END OBJ(nvidia, 0) @@ -5771,6 +5942,41 @@ static void generate_text_internal(char *p, int p_max_size, } #endif +#ifdef MOC + OBJ(moc_state) { + snprintf(p, p_max_size, "%s", (cur->moc.state ? cur->moc.state : "??")); + } + OBJ(moc_file) { + snprintf(p, p_max_size, "%s", (cur->moc.file ? cur->moc.file : "no file")); + } + OBJ(moc_title) { + snprintf(p, p_max_size, "%s", (cur->moc.title ? cur->moc.title : "no title")); + } + OBJ(moc_artist) { + snprintf(p, p_max_size, "%s", (cur->moc.artist ? cur->moc.artist : "no artist")); + } + OBJ(moc_song) { + snprintf(p, p_max_size, "%s", (cur->moc.song ? cur->moc.song : "no song")); + } + OBJ(moc_album) { + snprintf(p, p_max_size, "%s", (cur->moc.album ? cur->moc.album : "no album")); + } + OBJ(moc_totaltime) { + snprintf(p, p_max_size, "%s", (cur->moc.totaltime ? cur->moc.totaltime : "0:00")); + } + OBJ(moc_timeleft) { + snprintf(p, p_max_size, "%s", (cur->moc.timeleft ? cur->moc.timeleft : "0:00")); + } + OBJ(moc_curtime) { + snprintf(p, p_max_size, "%s", (cur->moc.curtime ? cur->moc.curtime : "0:00")); + } + OBJ(moc_bitrate) { + snprintf(p, p_max_size, "%s", (cur->moc.bitrate ? cur->moc.bitrate : "0Kbps")); + } + OBJ(moc_rate) { + snprintf(p, p_max_size, "%s", (cur->moc.rate ? cur->moc.rate : "0KHz")); + } +#endif /* MOC */ #ifdef XMMS2 OBJ(xmms2_artist) { snprintf(p, p_max_size, "%s", cur->xmms2.artist); @@ -6300,6 +6506,10 @@ head: unsigned int j; char *tmp; parse_conky_vars(obj->data.scroll.text, p, cur); + + if (strlen(p) <= obj->data.scroll.show) { + break; + } #define LINESEPARATOR '|' //place all the lines behind each other with LINESEPARATOR between them for(j = 0; p[j] != 0; j++) { @@ -6322,8 +6532,8 @@ head: p[obj->data.scroll.show] = 0; } //next time, scroll a place more or reset scrolling if we are at the end - obj->data.scroll.start++; - if(obj->data.scroll.start == j){ + obj->data.scroll.start += obj->data.scroll.step; + if(obj->data.scroll.start >= j){ obj->data.scroll.start = 0; } } @@ -7359,7 +7569,7 @@ static void update_text(void) static void main_loop(void) { #ifdef SIGNAL_BLOCKING - sigset_t newmask, oldmask; + sigset_t newmask; #endif double t; #ifdef X11 @@ -7751,6 +7961,10 @@ void reload_config(void) } #endif +#ifdef MOC + free_moc(&info.moc); +#endif + #ifdef X11 free_fonts(); #endif /* X11 */ @@ -7799,6 +8013,7 @@ void reload_config(void) memset(text_buffer, 0, max_user_text); update_text(); } + sigemptyset(&oldmask); } void clean_up(void) @@ -7958,6 +8173,9 @@ static void set_default_configurations(void) info.mpd.name = NULL; info.mpd.file = NULL; #endif +#ifdef MOC + init_moc(&info.moc); +#endif #ifdef XMMS2 info.xmms2.artist = NULL; info.xmms2.album = NULL; @@ -8794,6 +9012,7 @@ int main(int argc, char **argv) g_signal_pending = 0; memset(&info, 0, sizeof(info)); + clear_net_stats(); #ifdef TCP_PORT_MONITOR tcp_port_monitor_args.max_port_monitor_connections = @@ -9084,16 +9303,13 @@ int main(int argc, char **argv) act.sa_flags |= SA_RESTART; #endif - if (sigaction(SIGINT, &act, &oact) < 0 - || sigaction(SIGUSR1, &act, &oact) < 0 - || sigaction(SIGHUP,&act,&oact) < 0 - || sigaction(SIGTERM, &act, &oact) < 0) { + if ( sigaction(SIGINT, &act, &oact) < 0 + || sigaction(SIGUSR1, &act, &oact) < 0 + || sigaction(SIGHUP, &act, &oact) < 0 + || sigaction(SIGTERM, &act, &oact) < 0) { ERR("error setting signal handler: %s", strerror(errno)); } - /* *************** * - * MAIN CONKY LOOP * - * *************** */ main_loop(); #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) diff --git a/src/conky.h b/src/conky.h index 3e390e48..8b38a94f 100644 --- a/src/conky.h +++ b/src/conky.h @@ -178,6 +178,10 @@ struct mail_s { // for imap and pop3 #include "mpd.h" #endif +#ifdef MOC +#include "moc.h" +#endif + #ifdef XMMS2 #include "xmms2.h" #endif @@ -273,8 +277,10 @@ enum { #ifdef X11 INFO_X11 = 29, #endif - INFO_DNS = 30 - + INFO_DNS = 30, +#ifdef MOC + INFO_MOC = 31 +#endif }; /* get_battery_stuff() item selector */ @@ -325,6 +331,9 @@ struct information { #ifdef MPD struct mpd_s mpd; #endif +#ifdef MOC + struct moc_s moc; +#endif #ifdef XMMS2 struct xmms2_s xmms2; int xmms2_conn_state; diff --git a/src/timed_thread.c b/src/timed_thread.c index 4819a5e7..678d0ab2 100644 --- a/src/timed_thread.c +++ b/src/timed_thread.c @@ -46,7 +46,7 @@ struct _timed_thread { void *(*start_routine)(void *); /* thread function to run */ void *arg; /* thread function argument */ struct timespec interval_time; /* interval_usecs as a struct timespec */ - struct timespec wait_time; /* absolute future time next timed_thread_test will wait until */ + struct timespec wait_time; /* absolute future time next timed_thread_test will wait until */ }; /* linked list of created threads */