diff --git a/AUTHORS b/AUTHORS index be68f0ef..8abe69a1 100644 --- a/AUTHORS +++ b/AUTHORS @@ -19,6 +19,9 @@ affinity akash battery_percent and battery_bar +Aseem Mohanty + if_up patch + Ben Kibbey $tail fifo patch multiple mailbox patch @@ -169,7 +172,7 @@ killfire Lassi Selander XMMS2 patch - XMMS2 fixes patch + XMMS2 fixes Lauri Hakkarainen Some translating, web and other stuff @@ -203,6 +206,9 @@ nathanj439 Nikos Ntarmos FreeBSD total memory patch +norsetto + fix SIGUSR1/SIGHUP segfault + Pascal Eberhard graph and bar fix for right alignment @@ -286,6 +292,9 @@ Warren Dukes warudemaru rss and vsize for top +wedge + battery time fix for 2.6.24 + William DiPlacido Frequency from /proc/cpuinfo Some other SETI stuff diff --git a/ChangeLog b/ChangeLog index 25325038..d75048b9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ # $Id$ +2008-04-10 + * Getting rid of goto usage throughout code. + * Fix bug due to usage of gethostbyname() in threads (which is not + reentrant) by using gethostbyname_r() when available. + * Added patch for battery_time problem on 2.6.24 (thanks wedge). + * Added patch to fix broken xmms2 stuff (thanks sleipner). + * Added patch to fix SIGHUP/SIGUSR1 segfault (thanks norsetto). + * Added patch to improve $if_up (thanks Aseem). + 2008-04-02 * Added patch to use mail_spool correctly (thanks Kapil) * Replacing strdup() with strndup() throughout diff --git a/configure.ac.in b/configure.ac.in index f4f2f4f7..3acb0fd7 100644 --- a/configure.ac.in +++ b/configure.ac.in @@ -470,7 +470,7 @@ dnl dnl Some functions dnl -AC_CHECK_FUNCS([calloc malloc free popen sysinfo getloadavg memrchr strndup]) +AC_CHECK_FUNCS([calloc malloc free popen sysinfo getloadavg memrchr strndup gethostbyname_r]) AC_SEARCH_LIBS(clock_gettime, [rt], [AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [Define if you have clock_gettime()])], [AC_CHECK_FUNCS([gettimeofday], [], [AC_MSG_ERROR([gettimeofday() not available!])])], []) diff --git a/src/audacious.c b/src/audacious.c index 4f2cdfb4..1014e2aa 100644 --- a/src/audacious.c +++ b/src/audacious.c @@ -153,7 +153,7 @@ void *audacious_thread_func(void *pvoid) CRIT_ERR("unable to establish dbus connection"); } session = dbus_g_proxy_new_for_name(connection, AUDACIOUS_DBUS_SERVICE, - AUDACIOUS_DBUS_PATH, AUDACIOUS_DBUS_INTERFACE); + AUDACIOUS_DBUS_PATH, AUDACIOUS_DBUS_INTERFACE); if (!session) { CRIT_ERR("unable to create dbus proxy"); } @@ -162,85 +162,84 @@ void *audacious_thread_func(void *pvoid) /* Loop until the main thread resets the runnable signal. */ while (1) { - if (!audacious_remote_is_running(session)) { - memset(&items, 0, sizeof(items)); - strcpy(items[AUDACIOUS_STATUS], "Not running"); - goto bottom; - } + do { + if (!audacious_remote_is_running(session)) { + memset(&items, 0, sizeof(items)); + strcpy(items[AUDACIOUS_STATUS], "Not running"); + break; + } - /* Player status */ - if (audacious_remote_is_paused(session)) { - strcpy(items[AUDACIOUS_STATUS], "Paused"); - } else if (audacious_remote_is_playing(session)) { - strcpy(items[AUDACIOUS_STATUS], "Playing"); - } else { - strcpy(items[AUDACIOUS_STATUS], "Stopped"); - } + /* Player status */ + if (audacious_remote_is_paused(session)) { + strcpy(items[AUDACIOUS_STATUS], "Paused"); + } else if (audacious_remote_is_playing(session)) { + strcpy(items[AUDACIOUS_STATUS], "Playing"); + } else { + strcpy(items[AUDACIOUS_STATUS], "Stopped"); + } - /* Current song title */ - playpos = audacious_remote_get_playlist_pos(session); - psong = audacious_remote_get_playlist_title(session, playpos); - if (psong) { - strncpy(items[AUDACIOUS_TITLE], psong, - sizeof(items[AUDACIOUS_TITLE]) - 1); - g_free(psong); - psong = NULL; - } + /* Current song title */ + playpos = audacious_remote_get_playlist_pos(session); + psong = audacious_remote_get_playlist_title(session, playpos); + if (psong) { + strncpy(items[AUDACIOUS_TITLE], psong, + sizeof(items[AUDACIOUS_TITLE]) - 1); + g_free(psong); + psong = NULL; + } - /* Current song length as MM:SS */ - frames = audacious_remote_get_playlist_time(session, playpos); - length = frames / 1000; - snprintf(items[AUDACIOUS_LENGTH], sizeof(items[AUDACIOUS_LENGTH]) - 1, - "%d:%.2d", length / 60, length % 60); + /* Current song length as MM:SS */ + frames = audacious_remote_get_playlist_time(session, playpos); + length = frames / 1000; + snprintf(items[AUDACIOUS_LENGTH], sizeof(items[AUDACIOUS_LENGTH]) - 1, + "%d:%.2d", length / 60, length % 60); - /* Current song length in seconds */ - snprintf(items[AUDACIOUS_LENGTH_SECONDS], - sizeof(items[AUDACIOUS_LENGTH_SECONDS]) - 1, "%d", length); + /* Current song length in seconds */ + snprintf(items[AUDACIOUS_LENGTH_SECONDS], + sizeof(items[AUDACIOUS_LENGTH_SECONDS]) - 1, "%d", length); - /* Current song position as MM:SS */ - frames = audacious_remote_get_output_time(session); - length = frames / 1000; - snprintf(items[AUDACIOUS_POSITION], - sizeof(items[AUDACIOUS_POSITION]) - 1, "%d:%.2d", length / 60, - length % 60); + /* Current song position as MM:SS */ + frames = audacious_remote_get_output_time(session); + length = frames / 1000; + snprintf(items[AUDACIOUS_POSITION], + sizeof(items[AUDACIOUS_POSITION]) - 1, "%d:%.2d", length / 60, + length % 60); - /* Current song position in seconds */ - snprintf(items[AUDACIOUS_POSITION_SECONDS], - sizeof(items[AUDACIOUS_POSITION_SECONDS]) - 1, "%d", length); + /* Current song position in seconds */ + snprintf(items[AUDACIOUS_POSITION_SECONDS], + sizeof(items[AUDACIOUS_POSITION_SECONDS]) - 1, "%d", length); - /* Current song bitrate */ - audacious_remote_get_info(session, &rate, &freq, &chans); - snprintf(items[AUDACIOUS_BITRATE], sizeof(items[AUDACIOUS_BITRATE]) - 1, - "%d", rate); + /* Current song bitrate */ + audacious_remote_get_info(session, &rate, &freq, &chans); + snprintf(items[AUDACIOUS_BITRATE], sizeof(items[AUDACIOUS_BITRATE]) - 1, + "%d", rate); - /* Current song frequency */ - snprintf(items[AUDACIOUS_FREQUENCY], - sizeof(items[AUDACIOUS_FREQUENCY]) - 1, "%d", freq); + /* Current song frequency */ + snprintf(items[AUDACIOUS_FREQUENCY], + sizeof(items[AUDACIOUS_FREQUENCY]) - 1, "%d", freq); - /* Current song channels */ - snprintf(items[AUDACIOUS_CHANNELS], - sizeof(items[AUDACIOUS_CHANNELS]) - 1, "%d", chans); + /* Current song channels */ + snprintf(items[AUDACIOUS_CHANNELS], + sizeof(items[AUDACIOUS_CHANNELS]) - 1, "%d", chans); - /* Current song filename */ - pfilename = audacious_remote_get_playlist_file(session, playpos); - if (pfilename) { - strncpy(items[AUDACIOUS_FILENAME], pfilename, - sizeof(items[AUDACIOUS_FILENAME]) - 1); - g_free(pfilename); - pfilename = NULL; - } + /* Current song filename */ + pfilename = audacious_remote_get_playlist_file(session, playpos); + if (pfilename) { + strncpy(items[AUDACIOUS_FILENAME], pfilename, + sizeof(items[AUDACIOUS_FILENAME]) - 1); + g_free(pfilename); + pfilename = NULL; + } - /* Length of the Playlist (number of songs) */ - length = audacious_remote_get_playlist_length(session); - snprintf(items[AUDACIOUS_PLAYLIST_LENGTH], - sizeof(items[AUDACIOUS_PLAYLIST_LENGTH]) - 1, "%d", length); - - /* Playlist position (index of song) */ - snprintf(items[AUDACIOUS_PLAYLIST_POSITION], - sizeof(items[AUDACIOUS_PLAYLIST_POSITION]) - 1, "%d", playpos + 1); - -bottom: + /* Length of the Playlist (number of songs) */ + length = audacious_remote_get_playlist_length(session); + snprintf(items[AUDACIOUS_PLAYLIST_LENGTH], + sizeof(items[AUDACIOUS_PLAYLIST_LENGTH]) - 1, "%d", length); + /* Playlist position (index of song) */ + snprintf(items[AUDACIOUS_PLAYLIST_POSITION], + sizeof(items[AUDACIOUS_PLAYLIST_POSITION]) - 1, "%d", playpos + 1); + } while (0); /* Deliver the refreshed items array to audacious_items. */ timed_thread_lock(info.audacious.p_timed_thread); memcpy(&audacious_items, items, sizeof(items)); diff --git a/src/bmpx.c b/src/bmpx.c index ebb79027..31d52377 100644 --- a/src/bmpx.c +++ b/src/bmpx.c @@ -40,6 +40,8 @@ static DBusGProxy *remote_object; static int connected = 0; static char *unknown = "unknown"; +void fail(GError *error); + void update_bmpx() { GError *error = NULL; @@ -54,14 +56,16 @@ void update_bmpx() bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); if (bus == NULL) { ERR("BMPx error 1: %s\n", error->message); - goto fail; + fail(error); + return; } remote_object = dbus_g_proxy_new_for_name(bus, BMP_DBUS_SERVICE, - BMP_DBUS_PATH, BMP_DBUS_INTERFACE); + BMP_DBUS_PATH, BMP_DBUS_INTERFACE); if (!remote_object) { ERR("BMPx error 2: %s\n", error->message); - goto fail; + fail(error); + return; } connected = 1; @@ -69,16 +73,17 @@ void update_bmpx() if (connected == 1) { if (dbus_g_proxy_call(remote_object, "GetCurrentTrack", &error, - G_TYPE_INVALID, G_TYPE_INT, ¤t_track, G_TYPE_INVALID)) { + G_TYPE_INVALID, G_TYPE_INT, ¤t_track, G_TYPE_INVALID)) { } else { ERR("BMPx error 3: %s\n", error->message); - goto fail; + fail(error); + return; } if (dbus_g_proxy_call(remote_object, "GetMetadataForListItem", &error, - G_TYPE_INT, current_track, G_TYPE_INVALID, - DBUS_TYPE_G_STRING_VALUE_HASHTABLE, &metadata, - G_TYPE_INVALID)) { + G_TYPE_INT, current_track, G_TYPE_INVALID, + DBUS_TYPE_G_STRING_VALUE_HASHTABLE, &metadata, + G_TYPE_INVALID)) { if (current_info->bmpx.title) { free(current_info->bmpx.title); current_info->bmpx.title = 0; @@ -105,31 +110,36 @@ void update_bmpx() g_value_get_string(g_hash_table_lookup(metadata, "location")); } else { ERR("BMPx error 4: %s\n", error->message); - goto fail; + fail(error); + return; } g_hash_table_destroy(metadata); } else { -fail: - if (error) { - g_error_free(error); - } - if (current_info->bmpx.title) { - g_free(current_info->bmpx.title); - current_info->bmpx.title = 0; - } - if (current_info->bmpx.artist) { - g_free(current_info->bmpx.artist); - current_info->bmpx.artist = 0; - } - if (current_info->bmpx.album) { - g_free(current_info->bmpx.album); - current_info->bmpx.album = 0; - } - current_info->bmpx.title = unknown; - current_info->bmpx.artist = unknown; - current_info->bmpx.album = unknown; - current_info->bmpx.bitrate = 0; - current_info->bmpx.track = 0; + fail(error); } } + +void fail(GError *error) +{ + if (error) { + g_error_free(error); + } + if (current_info->bmpx.title) { + g_free(current_info->bmpx.title); + current_info->bmpx.title = 0; + } + if (current_info->bmpx.artist) { + g_free(current_info->bmpx.artist); + current_info->bmpx.artist = 0; + } + if (current_info->bmpx.album) { + g_free(current_info->bmpx.album); + current_info->bmpx.album = 0; + } + current_info->bmpx.title = unknown; + current_info->bmpx.artist = unknown; + current_info->bmpx.album = unknown; + current_info->bmpx.bitrate = 0; + current_info->bmpx.track = 0; +} diff --git a/src/common.c b/src/common.c index 240de431..59dfd777 100644 --- a/src/common.c +++ b/src/common.c @@ -203,8 +203,9 @@ void update_dns_data(void) if ((fp = fopen("/etc/resolv.conf", "r")) == NULL) return; while(!feof(fp)) { - if (fgets(line, 255, fp) == NULL) - goto OUT; + if (fgets(line, 255, fp) == NULL) { + break; + } if (!strncmp(line, "nameserver ", 11)) { line[strlen(line) - 1] = '\0'; // remove trailing newline data->nscount++; @@ -212,7 +213,6 @@ void update_dns_data(void) data->ns_list[data->nscount - 1] = strndup(line + 11, text_buffer_size); } } -OUT: fclose(fp); } diff --git a/src/conky.c b/src/conky.c index 2e726a57..5052f762 100644 --- a/src/conky.c +++ b/src/conky.c @@ -1555,14 +1555,23 @@ void *imap_thread(void *arg) unsigned int old_unseen = UINT_MAX; unsigned int old_messages = UINT_MAX; struct stat stat_buf; - struct hostent *he; + 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; - if ((he = gethostbyname(mail->host)) == NULL) { // get the host info +#ifdef HAVE_GETHOSTBYNAME_R + if (gethostbyname_r(mail->host, &he, hostbuff, sizeof(hostbuff), &he_res, &he_errno)) { // get the host info + ERR("IMAP gethostbyname_r: %s", hstrerror(h_errno)); + exit(1); + } +#else /* HAVE_GETHOSTBYNAME_R */ + if ((he_res = gethostbyname(mail->host)) == NULL) { // get the host info herror("gethostbyname"); exit(1); } +#endif /* HAVE_GETHOSTBYNAME_R */ while (fail < 5) { struct timeval timeout; int res; @@ -1570,155 +1579,156 @@ void *imap_thread(void *arg) if (fail > 0) { ERR("Trying IMAP connection again for %s@%s (try %i/5)", - mail->user, mail->host, fail + 1); - } - if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { - perror("socket"); - fail++; - goto next_iteration; + mail->user, mail->host, fail + 1); } + do { + if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { + perror("socket"); + fail++; + break; + } - // host byte order - their_addr.sin_family = AF_INET; - // short, network byte order - their_addr.sin_port = htons(mail->port); - their_addr.sin_addr = *((struct in_addr *) he->h_addr); - // zero the rest of the struct - memset(&(their_addr.sin_zero), '\0', 8); + // host byte order + their_addr.sin_family = AF_INET; + // short, network byte order + their_addr.sin_port = htons(mail->port); + their_addr.sin_addr = *((struct in_addr *) he_res->h_addr); + // zero the rest of the struct + memset(&(their_addr.sin_zero), '\0', 8); - if (connect(sockfd, (struct sockaddr *) &their_addr, - sizeof(struct sockaddr)) == -1) { - perror("connect"); - fail++; - goto next_iteration; - } + if (connect(sockfd, (struct sockaddr *) &their_addr, + sizeof(struct sockaddr)) == -1) { + perror("connect"); + 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"); + 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"); + fail++; + break; + } + } else { + ERR("IMAP connection failed: timeout"); fail++; - goto next_iteration; + break; } - } else { - ERR("IMAP connection failed: timeout"); - fail++; - goto next_iteration; - } - recvbuf[numbytes] = '\0'; - if (strstr(recvbuf, "* OK") != recvbuf) { - ERR("IMAP connection failed, probably not an IMAP server"); - fail++; - goto next_iteration; - } - strncpy(sendbuf, "a1 login ", MAXDATASIZE); - strncat(sendbuf, mail->user, MAXDATASIZE - strlen(sendbuf) - 1); - strncat(sendbuf, " ", MAXDATASIZE - strlen(sendbuf) - 1); - strncat(sendbuf, mail->pass, MAXDATASIZE - strlen(sendbuf) - 1); - strncat(sendbuf, "\r\n", MAXDATASIZE - strlen(sendbuf) - 1); - if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) { - perror("send a1"); - fail++; - goto next_iteration; - } - 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 a1"); + recvbuf[numbytes] = '\0'; + if (strstr(recvbuf, "* OK") != recvbuf) { + ERR("IMAP connection failed, probably not an IMAP server"); fail++; - goto next_iteration; + break; } - } - recvbuf[numbytes] = '\0'; - if (strstr(recvbuf, "a1 OK") == NULL) { - ERR("IMAP server login failed: %s", recvbuf); - fail++; - goto next_iteration; - } - strncpy(sendbuf, "a2 STATUS ", MAXDATASIZE); - strncat(sendbuf, mail->folder, MAXDATASIZE - strlen(sendbuf) - 1); - strncat(sendbuf, " (MESSAGES UNSEEN)\r\n", - MAXDATASIZE - strlen(sendbuf) - 1); - if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) { - perror("send a2"); - fail++; - goto next_iteration; - } - 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 a2"); + strncpy(sendbuf, "a1 login ", MAXDATASIZE); + strncat(sendbuf, mail->user, MAXDATASIZE - strlen(sendbuf) - 1); + strncat(sendbuf, " ", MAXDATASIZE - strlen(sendbuf) - 1); + strncat(sendbuf, mail->pass, MAXDATASIZE - strlen(sendbuf) - 1); + strncat(sendbuf, "\r\n", MAXDATASIZE - strlen(sendbuf) - 1); + if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) { + perror("send a1"); fail++; - goto next_iteration; + break; } - } - recvbuf[numbytes] = '\0'; - if (strstr(recvbuf, "a2 OK") == NULL) { - ERR("IMAP status failed: %s", recvbuf); - fail++; - goto next_iteration; - } - // now we get the data - reply = strstr(recvbuf, " (MESSAGES "); - reply += 2; - *strchr(reply, ')') = '\0'; - if (reply == NULL) { - ERR("Error parsing IMAP response: %s", recvbuf); - fail++; - goto next_iteration; - } else { - timed_thread_lock(mail->p_timed_thread); - sscanf(reply, "MESSAGES %lu UNSEEN %lu", &mail->messages, - &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++; - goto next_iteration; - } - 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"); + 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 a1"); + fail++; + break; + } + } + recvbuf[numbytes] = '\0'; + if (strstr(recvbuf, "a1 OK") == NULL) { + ERR("IMAP server login failed: %s", recvbuf); fail++; - goto next_iteration; + break; } - } - recvbuf[numbytes] = '\0'; - if (strstr(recvbuf, "a3 OK") == NULL) { - ERR("IMAP logout failed: %s", recvbuf); - fail++; - goto next_iteration; - } - 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()"); + strncpy(sendbuf, "a2 STATUS ", MAXDATASIZE); + strncat(sendbuf, mail->folder, MAXDATASIZE - strlen(sendbuf) - 1); + strncat(sendbuf, " (MESSAGES UNSEEN)\r\n", + MAXDATASIZE - strlen(sendbuf) - 1); + if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) { + perror("send a2"); + fail++; + break; } - } - fail = 0; - old_unseen = mail->unseen; - old_messages = mail->messages; -next_iteration: + 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 a2"); + fail++; + break; + } + } + recvbuf[numbytes] = '\0'; + if (strstr(recvbuf, "a2 OK") == NULL) { + ERR("IMAP status failed: %s", recvbuf); + fail++; + break; + } + // now we get the data + reply = strstr(recvbuf, " (MESSAGES "); + reply += 2; + *strchr(reply, ')') = '\0'; + if (reply == NULL) { + ERR("Error parsing IMAP response: %s", recvbuf); + fail++; + break; + } else { + timed_thread_lock(mail->p_timed_thread); + sscanf(reply, "MESSAGES %lu UNSEEN %lu", &mail->messages, + &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 + if (system(mail->command) == -1) { + perror("system()"); + } + } + fail = 0; + old_unseen = mail->unseen; + old_messages = mail->messages; + } while (0); if ((fstat(sockfd, &stat_buf) == 0) && S_ISSOCK(stat_buf.st_mode)) { /* if a valid socket, close it */ close(sockfd); @@ -1741,14 +1751,23 @@ void *pop3_thread(void *arg) int fail = 0; unsigned int old_unseen = UINT_MAX; struct stat stat_buf; - struct hostent *he; + 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; - if ((he = gethostbyname(mail->host)) == NULL) { // get the host info +#ifdef HAVE_GETHOSTBYNAME_R + if (gethostbyname_r(mail->host, &he, hostbuff, sizeof(hostbuff), &he_res, &he_errno)) { // get the host info + ERR("POP3 gethostbyname_r: %s", hstrerror(h_errno)); + exit(1); + } +#else /* HAVE_GETHOSTBYNAME_R */ + if ((he_res = gethostbyname(mail->host)) == NULL) { // get the host info herror("gethostbyname"); exit(1); } +#endif /* HAVE_GETHOSTBYNAME_R */ while (fail < 5) { struct timeval timeout; int res; @@ -1756,171 +1775,172 @@ void *pop3_thread(void *arg) if (fail > 0) { ERR("Trying POP3 connection again for %s@%s (try %i/5)", - mail->user, mail->host, fail + 1); - } - if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { - perror("socket"); - fail++; - goto next_iteration; + mail->user, mail->host, fail + 1); } + do { + if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { + perror("socket"); + fail++; + break; + } - // host byte order - their_addr.sin_family = AF_INET; - // short, network byte order - their_addr.sin_port = htons(mail->port); - their_addr.sin_addr = *((struct in_addr *) he->h_addr); - // zero the rest of the struct - memset(&(their_addr.sin_zero), '\0', 8); + // host byte order + their_addr.sin_family = AF_INET; + // short, network byte order + their_addr.sin_port = htons(mail->port); + their_addr.sin_addr = *((struct in_addr *) he_res->h_addr); + // zero the rest of the struct + memset(&(their_addr.sin_zero), '\0', 8); - if (connect(sockfd, (struct sockaddr *) &their_addr, - sizeof(struct sockaddr)) == -1) { - perror("connect"); - fail++; - goto next_iteration; - } + if (connect(sockfd, (struct sockaddr *) &their_addr, + sizeof(struct sockaddr)) == -1) { + perror("connect"); + 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"); + 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"); + fail++; + break; + } + } else { + ERR("POP3 connection failed: timeout\n"); fail++; - goto next_iteration; + break; } - } else { - ERR("POP3 connection failed: timeout\n"); - fail++; - goto next_iteration; - } - recvbuf[numbytes] = '\0'; - if (strstr(recvbuf, "+OK ") != recvbuf) { - ERR("POP3 connection failed, probably not a POP3 server"); - fail++; - goto next_iteration; - } - strncpy(sendbuf, "USER ", MAXDATASIZE); - strncat(sendbuf, mail->user, MAXDATASIZE - strlen(sendbuf) - 1); - strncat(sendbuf, "\r\n", MAXDATASIZE - strlen(sendbuf) - 1); - if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) { - perror("send USER"); - fail++; - goto next_iteration; - } - 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 USER"); + recvbuf[numbytes] = '\0'; + if (strstr(recvbuf, "+OK ") != recvbuf) { + ERR("POP3 connection failed, probably not a POP3 server"); fail++; - goto next_iteration; + break; } - } - recvbuf[numbytes] = '\0'; - if (strstr(recvbuf, "+OK ") == NULL) { - ERR("POP3 server login failed: %s", recvbuf); - fail++; - goto next_iteration; - } - strncpy(sendbuf, "PASS ", MAXDATASIZE); - strncat(sendbuf, mail->pass, MAXDATASIZE - strlen(sendbuf) - 1); - strncat(sendbuf, "\r\n", MAXDATASIZE - strlen(sendbuf) - 1); - if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) { - perror("send PASS"); - fail++; - goto next_iteration; - } - 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 PASS"); + strncpy(sendbuf, "USER ", MAXDATASIZE); + strncat(sendbuf, mail->user, MAXDATASIZE - strlen(sendbuf) - 1); + strncat(sendbuf, "\r\n", MAXDATASIZE - strlen(sendbuf) - 1); + if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) { + perror("send USER"); fail++; - goto next_iteration; + break; } - } - recvbuf[numbytes] = '\0'; - if (strstr(recvbuf, "+OK ") == NULL) { - ERR("POP3 server login failed: %s", recvbuf); - fail++; - goto next_iteration; - } - strncpy(sendbuf, "STAT\r\n", MAXDATASIZE); - if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) { - perror("send STAT"); - fail++; - goto next_iteration; - } - 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 STAT"); + 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 USER"); + fail++; + break; + } + } + recvbuf[numbytes] = '\0'; + if (strstr(recvbuf, "+OK ") == NULL) { + ERR("POP3 server login failed: %s", recvbuf); fail++; - goto next_iteration; + break; } - } - recvbuf[numbytes] = '\0'; - if (strstr(recvbuf, "+OK ") == NULL) { - ERR("POP3 status failed: %s", recvbuf); - fail++; - goto next_iteration; - } - // now we get the data - reply = recvbuf + 4; - if (reply == NULL) { - ERR("Error parsing POP3 response: %s", recvbuf); - fail++; - goto next_iteration; - } else { - timed_thread_lock(mail->p_timed_thread); - sscanf(reply, "%lu %lu", &mail->unseen, &mail->used); - timed_thread_unlock(mail->p_timed_thread); - } - strncpy(sendbuf, "QUIT\r\n", MAXDATASIZE); - if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) { - perror("send QUIT"); - fail++; - goto next_iteration; - } - 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 QUIT"); + strncpy(sendbuf, "PASS ", MAXDATASIZE); + strncat(sendbuf, mail->pass, MAXDATASIZE - strlen(sendbuf) - 1); + strncat(sendbuf, "\r\n", MAXDATASIZE - strlen(sendbuf) - 1); + if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) { + perror("send PASS"); fail++; - goto next_iteration; + break; } - } - recvbuf[numbytes] = '\0'; - if (strstr(recvbuf, "+OK") == NULL) { - ERR("POP3 logout failed: %s", recvbuf); - fail++; - goto next_iteration; - } - if (strlen(mail->command) > 1 && mail->unseen > old_unseen) { - // new mail goodie - if (system(mail->command) == -1) { - perror("system()"); + 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 PASS"); + fail++; + break; + } } - } - fail = 0; - old_unseen = mail->unseen; -next_iteration: + recvbuf[numbytes] = '\0'; + if (strstr(recvbuf, "+OK ") == NULL) { + ERR("POP3 server login failed: %s", recvbuf); + fail++; + break; + } + strncpy(sendbuf, "STAT\r\n", MAXDATASIZE); + if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) { + perror("send STAT"); + 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 STAT"); + fail++; + break; + } + } + recvbuf[numbytes] = '\0'; + if (strstr(recvbuf, "+OK ") == NULL) { + ERR("POP3 status failed: %s", recvbuf); + fail++; + break; + } + // now we get the data + reply = recvbuf + 4; + if (reply == NULL) { + ERR("Error parsing POP3 response: %s", recvbuf); + fail++; + break; + } else { + timed_thread_lock(mail->p_timed_thread); + sscanf(reply, "%lu %lu", &mail->unseen, &mail->used); + timed_thread_unlock(mail->p_timed_thread); + } + strncpy(sendbuf, "QUIT\r\n", MAXDATASIZE); + if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) { + perror("send QUIT"); + 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 QUIT"); + fail++; + break; + } + } + recvbuf[numbytes] = '\0'; + if (strstr(recvbuf, "+OK") == NULL) { + ERR("POP3 logout failed: %s", recvbuf); + fail++; + break; + } + if (strlen(mail->command) > 1 && mail->unseen > old_unseen) { + // new mail goodie + if (system(mail->command) == -1) { + perror("system()"); + } + } + fail = 0; + old_unseen = mail->unseen; + } while (0); if ((fstat(sockfd, &stat_buf) == 0) && S_ISSOCK(stat_buf.st_mode)) { /* if a valid socket, close it */ close(sockfd); @@ -6027,7 +6047,6 @@ static void generate_text_internal(char *p, int p_max_size, } /* if cur_upd_time >= */ // parse_conky_vars(obj->data.tail.buffer, p, cur); } - head: OBJ(head) { if (current_update_time - obj->data.tail.last_update @@ -7515,8 +7534,6 @@ void reload_config(void) #ifdef X11 free_fonts(); - load_fonts(); - set_font(); #endif /* X11 */ #ifdef TCP_PORT_MONITOR @@ -7534,6 +7551,8 @@ void reload_config(void) } #ifdef X11 + load_fonts(); + set_font(); // clear the window first XClearWindow(display, RootWindow(display, screen)); diff --git a/src/diskio.c b/src/diskio.c index a4105ac2..8796f0a8 100644 --- a/src/diskio.c +++ b/src/diskio.c @@ -30,6 +30,20 @@ #include "conky.h" #include #include +/* The following ifdefs were adapted from gkrellm */ +#include + +#if !defined(MD_MAJOR) +#define MD_MAJOR 9 +#endif + +#if !defined(LVM_BLK_MAJOR) +#define LVM_BLK_MAJOR 58 +#endif + +#if !defined(NBD_MAJOR) +#define NBD_MAJOR 43 +#endif static struct diskio_stat diskio_stats_[MAX_DISKIO_STATS]; struct diskio_stat *diskio_stats = diskio_stats_; @@ -112,3 +126,107 @@ struct diskio_stat *prepare_diskio_stat(const char *s) new->last_write = UINT_MAX; return new; } + +void update_diskio(void) +{ + static unsigned int last = UINT_MAX; + static unsigned int last_read = UINT_MAX; + static unsigned int last_write = UINT_MAX; + FILE *fp; + static int rep = 0; + + char buf[512], devbuf[64]; + int i; + unsigned int major, minor; + unsigned int current = 0; + unsigned int current_read = 0; + unsigned int current_write = 0; + unsigned int reads, writes = 0; + int col_count = 0; + int tot, tot_read, tot_write; + + if (!(fp = open_file("/proc/diskstats", &rep))) { + diskio_value = 0; + return; + } + + /* read reads and writes from all disks (minor = 0), including cd-roms + * and floppies, and sum them up */ + while (!feof(fp)) { + fgets(buf, 512, fp); + col_count = sscanf(buf, "%u %u %s %*u %*u %u %*u %*u %*u %u", &major, + &minor, devbuf, &reads, &writes); + /* ignore subdevices (they have only 3 matching entries in their line) + * and virtual devices (LVM, network block devices, RAM disks, Loopback) + * + * XXX: ignore devices which are part of a SW RAID (MD_MAJOR) */ + if (col_count == 5 && major != LVM_BLK_MAJOR && major != NBD_MAJOR + && major != RAMDISK_MAJOR && major != LOOP_MAJOR) { + current += reads + writes; + current_read += reads; + current_write += writes; + } else { + col_count = sscanf(buf, "%u %u %s %*u %u %*u %u", + &major, &minor, devbuf, &reads, &writes); + if (col_count != 5) { + continue; + } + } + for (i = 0; i < MAX_DISKIO_STATS; i++) { + if (diskio_stats[i].dev && + strncmp(devbuf, diskio_stats[i].dev, text_buffer_size) == 0) { + diskio_stats[i].current = + (reads + writes - diskio_stats[i].last) / 2; + diskio_stats[i].current_read = + (reads - diskio_stats[i].last_read) / 2; + diskio_stats[i].current_write = + (writes - diskio_stats[i].last_write) / 2; + if (reads + writes < diskio_stats[i].last) { + diskio_stats[i].current = 0; + } + if (reads < diskio_stats[i].last_read) { + diskio_stats[i].current_read = 0; + diskio_stats[i].current = diskio_stats[i].current_write; + } + if (writes < diskio_stats[i].last_write) { + diskio_stats[i].current_write = 0; + diskio_stats[i].current = diskio_stats[i].current_read; + } + diskio_stats[i].last = reads + writes; + diskio_stats[i].last_read = reads; + diskio_stats[i].last_write = writes; + } + } + } + + /* since the values in /proc/diststats are absolute, we have to substract + * our last reading. The numbers stand for "sectors read", and we therefore + * have to divide by two to get KB */ + tot = ((double) (current - last) / 2); + tot_read = ((double) (current_read - last_read) / 2); + tot_write = ((double) (current_write - last_write) / 2); + + if (last_read > current_read) { + tot_read = 0; + } + if (last_write > current_write) { + tot_write = 0; + } + + if (last > current) { + /* we hit this either if it's the very first time we run this, or + * when /proc/diskstats overflows; while 0 is not correct, it's at + * least not way off */ + tot = 0; + } + last = current; + last_read = current_read; + last_write = current_write; + + diskio_value = tot; + diskio_read_value = tot_read; + diskio_write_value = tot_write; + + fclose(fp); +} + diff --git a/src/freebsd.c b/src/freebsd.c index 5f0e380c..63d25a72 100644 --- a/src/freebsd.c +++ b/src/freebsd.c @@ -607,7 +607,8 @@ void update_wifi_stats() bzero(&ifmr, sizeof(ifmr)); strlcpy(ifmr.ifm_name, ifa->ifa_name, IFNAMSIZ); if (ioctl(s, SIOCGIFMEDIA, (caddr_t) &ifmr) < 0) { - goto cleanup; + close(s); + return; } /* We can monitor only wireless interfaces diff --git a/src/hddtemp.c b/src/hddtemp.c index c1216f5b..c7e10cbe 100644 --- a/src/hddtemp.c +++ b/src/hddtemp.c @@ -77,7 +77,9 @@ int scan_hddtemp(const char *arg, char **dev, char **addr, int *port) char *get_hddtemp_info(char *dev, char *hostaddr, int port, char *unit) { int sockfd = 0; - struct hostent *he; + struct hostent he, *he_res = 0; + int he_errno; + char hostbuff[2048]; struct sockaddr_in addr; struct timeval tv; fd_set rfds; @@ -90,102 +92,110 @@ char *get_hddtemp_info(char *dev, char *hostaddr, int port, char *unit) return NULL; } - he = gethostbyname(hostaddr); - if (!he) { - perror("gethostbyname"); - goto out; - } - - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr = *((struct in_addr *) he->h_addr); - memset(&(addr.sin_zero), 0, 8); - - if (connect(sockfd, (struct sockaddr *) &addr, - sizeof(struct sockaddr)) == -1) { - perror("connect"); - goto out; - } - - FD_ZERO(&rfds); - FD_SET(sockfd, &rfds); - - /* We're going to wait up to a quarter a second to see whether there's - * any data available. Polling with timeout set to 0 doesn't seem to work - * with hddtemp. */ - tv.tv_sec = 0; - tv.tv_usec = 250000; - - i = select(sockfd + 1, &rfds, NULL, NULL, &tv); - if (i == -1) { - if (errno == EINTR) { /* silently ignore interrupted system call */ - goto out; - } else { - perror("select"); - } - } - - /* No data available */ - if (i <= 0) { - goto out; - } - - p = buf; - len = 0; do { - i = recv(sockfd, p, BUFLEN - (p - buf), 0); - if (i < 0) { - perror("recv"); - goto out; +#ifdef HAVE_GETHOSTBYNAME_R + if (gethostbyname_r(hostaddr, &he, hostbuff, sizeof(hostbuff), &he_res, &he_errno)) { // get the host info + ERR("hddtemp gethostbyname_r: %s", hstrerror(h_errno)); + break; } - len += i; - p += i; - } while (i > 0 && p < buf + BUFLEN - 1); +#else /* HAVE_GETHOSTBYNAME_R */ + he_res = gethostbyname(hostaddr); + if (!he_res) { + perror("gethostbyname"); + break; + } +#endif /* HAVE_GETHOSTBYNAME_R */ - if (len < 2) { - goto out; - } + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr = *((struct in_addr *) he_res->h_addr); + memset(&(addr.sin_zero), 0, 8); - buf[len] = 0; + if (connect(sockfd, (struct sockaddr *) &addr, + sizeof(struct sockaddr)) == -1) { + perror("connect"); + break; + } - /* The first character read is the separator. */ - sep = buf[0]; - p = buf + 1; + FD_ZERO(&rfds); + FD_SET(sockfd, &rfds); - while (*p) { - if (!strncmp(p, dev, devlen)) { - p += devlen + 1; - p = strchr(p, sep); - if (!p) { - goto out; - } - p++; - out = p; - p = strchr(p, sep); - if (!p) { - goto out; - } - *p = '\0'; - p++; - *unit = *p; - if (!strncmp(out, "NA", 2)) { - strcpy(buf, "N/A"); - r = buf; + /* We're going to wait up to a quarter a second to see whether there's + * any data available. Polling with timeout set to 0 doesn't seem to work + * with hddtemp. */ + tv.tv_sec = 0; + tv.tv_usec = 250000; + + i = select(sockfd + 1, &rfds, NULL, NULL, &tv); + if (i == -1) { + if (errno == EINTR) { /* silently ignore interrupted system call */ + break; } else { - r = out; + perror("select"); } - goto out; - } else { - for (i = 0; i < 5; i++) { + } + + /* No data available */ + if (i <= 0) { + break; + } + + p = buf; + len = 0; + do { + i = recv(sockfd, p, BUFLEN - (p - buf), 0); + if (i < 0) { + perror("recv"); + break; + } + len += i; + p += i; + } while (i > 0 && p < buf + BUFLEN - 1); + + if (len < 2) { + break; + } + + buf[len] = 0; + + /* The first character read is the separator. */ + sep = buf[0]; + p = buf + 1; + + while (*p) { + if (!strncmp(p, dev, devlen)) { + p += devlen + 1; p = strchr(p, sep); if (!p) { - goto out; + break; } p++; + out = p; + p = strchr(p, sep); + if (!p) { + break; + } + *p = '\0'; + p++; + *unit = *p; + if (!strncmp(out, "NA", 2)) { + strcpy(buf, "N/A"); + r = buf; + } else { + r = out; + } + break; + } else { + for (i = 0; i < 5; i++) { + p = strchr(p, sep); + if (!p) { + break; + } + p++; + } } } - } -out: + } while (0); close(sockfd); return r; } diff --git a/src/libmpdclient.c b/src/libmpdclient.c index d66b3ab8..9539b9f1 100644 --- a/src/libmpdclient.c +++ b/src/libmpdclient.c @@ -195,27 +195,38 @@ static int mpd_connect(mpd_Connection *connection, const char *host, int port, static int mpd_connect(mpd_Connection *connection, const char *host, int port, float timeout) { - struct hostent *he; + struct hostent he, *he_res = 0; + int he_errno; + char hostbuff[2048]; struct sockaddr *dest; int destlen; struct sockaddr_in sin; - if (!(he = gethostbyname(host))) { +#ifdef HAVE_GETHOSTBYNAME_R + if (gethostbyname_r(rhost, &he, hostbuff, sizeof(hostbuff), &he_res, &he_errno)) { // get the host info + snprintf(connection->errorStr, MPD_ERRORSTR_MAX_LENGTH, + "%s ('%s')", hstrerror(h_errno), host); + connection->error = MPD_ERROR_UNKHOST; + return -1; + } +#else /* HAVE_GETHOSTBYNAME_R */ + if (!(he_res = gethostbyname(host))) { snprintf(connection->errorStr, MPD_ERRORSTR_MAX_LENGTH, "host \"%s\" not found", host); connection->error = MPD_ERROR_UNKHOST; return -1; } +#endif /* HAVE_GETHOSTBYNAME_R */ memset(&sin, 0, sizeof(struct sockaddr_in)); - /* dest.sin_family = he->h_addrtype; */ + /* dest.sin_family = he_res->h_addrtype; */ sin.sin_family = AF_INET; sin.sin_port = htons(port); - switch (he->h_addrtype) { + switch (he_res->h_addrtype) { case AF_INET: - memcpy((char *) &sin.sin_addr.s_addr, (char *) he->h_addr, - he->h_length); + memcpy((char *) &sin.sin_addr.s_addr, (char *) he_res->h_addr, + he_res->h_length); dest = (struct sockaddr *) &sin; destlen = sizeof(struct sockaddr_in); break; diff --git a/src/linux.c b/src/linux.c index c41841d0..6aea4c9a 100644 --- a/src/linux.c +++ b/src/linux.c @@ -212,23 +212,61 @@ char *get_ioscheduler(char *disk) int interface_up(const char *dev) { - int fd; - struct ifreq ifr; + int fd, dnl, ifnl, nl; + unsigned int k; + struct ifconf conf; + struct sockaddr addr; + char *ifdev; - if((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { + dnl = strlen(dev); + if((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) { CRIT_ERR("could not create sockfd"); return 0; } - strncpy(ifr.ifr_name, dev, IFNAMSIZ); - if(ioctl(fd, SIOCGIFFLAGS, &ifr)) { - /* if device does not exist, treat like not up */ + + /* allocate memory for interface request */ + if((conf.ifc_buf = calloc(16, sizeof(struct ifreq))) == NULL) { + CRIT_ERR("could not allocate memory for interface query"); + return 0; + } + conf.ifc_len = sizeof(struct ifreq) * 16; + + /* send a conf query ioctl to device to enumerate all interfaces */ + if(ioctl(fd, SIOCGIFCONF, &conf)) { + /* if device does not exist, treat like not up - fail fast */ if (errno != ENODEV) perror("SIOCGIFFLAGS"); } else { - close(fd); - return (ifr.ifr_flags & IFF_UP); + /* for all enumerated interface devices ... */ + for (k = 0; k < conf.ifc_len / sizeof(struct ifreq); k++) { + /* end of buffer - break out */ + if (!(((struct ifreq *) conf.ifc_buf) + k)) + break; + /* get interface device name */ + ifdev = ((struct ifreq *) conf.ifc_buf)[k].ifr_ifrn.ifrn_name; + ifnl = strlen(ifdev); + nl = dnl > ifnl ? ifnl : dnl; + /* if it does not match our specified device - move on */ + if (strncmp(dev, ifdev, nl) != 0) { + continue; + } + /* get associated address on device */ + addr = ((struct ifreq *) conf.ifc_buf)[k].ifr_ifru.ifru_addr; + /* if ip is 0.0.0.0 it is not up */ + if((addr.sa_data[2] & 255) == 0 && + (addr.sa_data[3] & 255) == 0 && + (addr.sa_data[4] & 255) == 0 && + (addr.sa_data[5] & 255) == 0) { + break; + } + /* otherwise we are good */ + close(fd); + return 1; + } } + /* cleanup */ close(fd); + free(conf.ifc_buf); return 0; } @@ -258,34 +296,34 @@ void update_gateway_info(void) if ((fp = fopen("/proc/net/route", "r")) == NULL) { perror("fopen()"); - goto FAIL; + info.gw_info.iface = info.gw_info.ip = strndup("failed", text_buffer_size); + return; } if (fscanf(fp, "%*[^\n]\n") == EOF) { perror("fscanf()"); - goto CLOSE_FAIL; + fclose(fp); + info.gw_info.iface = info.gw_info.ip = strndup("failed", text_buffer_size); + return; } while (!feof(fp)) { // Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT if(fscanf(fp, "%63s %lx %lx %x %hd %hd %hd %lx %hd %hd %hd\n", - iface, &dest, &gate, &flags, &ref, &use, - &metric, &mask, &mtu, &win, &irtt) != 11) { + iface, &dest, &gate, &flags, &ref, &use, + &metric, &mask, &mtu, &win, &irtt) != 11) { perror("fscanf()"); - goto CLOSE_FAIL; + fclose(fp); + info.gw_info.iface = info.gw_info.ip = strndup("failed", text_buffer_size); + return; } if (flags & RTF_GATEWAY && dest == 0 && mask == 0) { gw_info->count++; SAVE_SET_STRING(gw_info->iface, iface) - ina.s_addr = gate; + ina.s_addr = gate; SAVE_SET_STRING(gw_info->ip, inet_ntoa(ina)) } } fclose(fp); return; -CLOSE_FAIL: - fclose(fp); -FAIL: - info.gw_info.iface = info.gw_info.ip = strndup("failed", text_buffer_size); - return; } inline void update_net_stats(void) @@ -1520,6 +1558,8 @@ int get_battery_idx(const char *bat) return idx; } +void set_return_value(char *buffer, unsigned int n, int item, int idx); + void get_battery_stuff(char *buffer, unsigned int n, const char *bat, int item) { static int idx, rep = 0, rep2 = 0; @@ -1535,7 +1575,8 @@ void get_battery_stuff(char *buffer, unsigned int n, const char *bat, int item) /* don't update battery too often */ if (current_update_time - last_battery_time[idx] < 29.5) { - goto set_return_value; + set_return_value(buffer, n, item, idx); + return; } last_battery_time[idx] = current_update_time; @@ -1630,7 +1671,7 @@ void get_battery_stuff(char *buffer, unsigned int n, const char *bat, int item) (int) (((float) remaining_capacity / acpi_last_full[idx]) * 100 )); /* e.g. 1h 12m */ format_seconds(last_battery_time_str[idx], sizeof(last_battery_time_str[idx])-1, - (long) (((float)(acpi_last_full[idx] - remaining_capacity) / present_rate) * 3600)); + (long) (((float) remaining_capacity / present_rate) * 3600)); } else if (present_rate == 0) { /* Thanks to Nexox for this one */ snprintf(last_battery_str[idx], sizeof(last_battery_str[idx])-1, "full"); snprintf(last_battery_time_str[idx], @@ -1823,8 +1864,11 @@ void get_battery_stuff(char *buffer, unsigned int n, const char *bat, int item) apm_bat_fp[idx] = NULL; } } + set_return_value(buffer, n, item, idx); +} -set_return_value: +void set_return_value(char *buffer, unsigned int n, int item, int idx) +{ switch (item) { case BATTERY_STATUS: snprintf(buffer, n, "%s", last_battery_str[idx]); @@ -2072,124 +2116,6 @@ void update_top(void) info.first_process = get_first_process(); } -/* The following ifdefs were adapted from gkrellm */ -#include - -#if !defined(MD_MAJOR) -#define MD_MAJOR 9 -#endif - -#if !defined(LVM_BLK_MAJOR) -#define LVM_BLK_MAJOR 58 -#endif - -#if !defined(NBD_MAJOR) -#define NBD_MAJOR 43 -#endif - -void update_diskio(void) -{ - static unsigned int last = UINT_MAX; - static unsigned int last_read = UINT_MAX; - static unsigned int last_write = UINT_MAX; - FILE *fp; - static int rep = 0; - - char buf[512], devbuf[64]; - int i; - unsigned int major, minor; - unsigned int current = 0; - unsigned int current_read = 0; - unsigned int current_write = 0; - unsigned int reads, writes = 0; - int col_count = 0; - int tot, tot_read, tot_write; - - if (!(fp = open_file("/proc/diskstats", &rep))) { - diskio_value = 0; - return; - } - - /* read reads and writes from all disks (minor = 0), including cd-roms - * and floppies, and sum them up */ - while (!feof(fp)) { - fgets(buf, 512, fp); - col_count = sscanf(buf, "%u %u %s %*u %*u %u %*u %*u %*u %u", &major, - &minor, devbuf, &reads, &writes); - /* ignore subdevices (they have only 3 matching entries in their line) - * and virtual devices (LVM, network block devices, RAM disks, Loopback) - * - * XXX: ignore devices which are part of a SW RAID (MD_MAJOR) */ - if (col_count == 5 && major != LVM_BLK_MAJOR && major != NBD_MAJOR - && major != RAMDISK_MAJOR && major != LOOP_MAJOR) { - current += reads + writes; - current_read += reads; - current_write += writes; - } else { - col_count = sscanf(buf, "%u %u %s %*u %u %*u %u", - &major, &minor, devbuf, &reads, &writes); - if (col_count != 5) { - continue; - } - } - for (i = 0; i < MAX_DISKIO_STATS; i++) { - if (diskio_stats[i].dev && - strncmp(devbuf, diskio_stats[i].dev, text_buffer_size) == 0) { - diskio_stats[i].current = - (reads + writes - diskio_stats[i].last) / 2; - diskio_stats[i].current_read = - (reads - diskio_stats[i].last_read) / 2; - diskio_stats[i].current_write = - (writes - diskio_stats[i].last_write) / 2; - if (reads + writes < diskio_stats[i].last) { - diskio_stats[i].current = 0; - } - if (reads < diskio_stats[i].last_read) { - diskio_stats[i].current_read = 0; - diskio_stats[i].current = diskio_stats[i].current_write; - } - if (writes < diskio_stats[i].last_write) { - diskio_stats[i].current_write = 0; - diskio_stats[i].current = diskio_stats[i].current_read; - } - diskio_stats[i].last = reads + writes; - diskio_stats[i].last_read = reads; - diskio_stats[i].last_write = writes; - } - } - } - - /* since the values in /proc/diststats are absolute, we have to substract - * our last reading. The numbers stand for "sectors read", and we therefore - * have to divide by two to get KB */ - tot = ((double) (current - last) / 2); - tot_read = ((double) (current_read - last_read) / 2); - tot_write = ((double) (current_write - last_write) / 2); - - if (last_read > current_read) { - tot_read = 0; - } - if (last_write > current_write) { - tot_write = 0; - } - - if (last > current) { - /* we hit this either if it's the very first time we run this, or - * when /proc/diskstats overflows; while 0 is not correct, it's at - * least not way off */ - tot = 0; - } - last = current; - last_read = current_read; - last_write = current_write; - - diskio_value = tot; - diskio_read_value = tot_read; - diskio_write_value = tot_write; - - fclose(fp); -} - /* Here come the IBM ACPI-specific things. For reference, see * http://ibm-acpi.sourceforge.net/README * If IBM ACPI is installed, /proc/acpi/ibm contains the following files: diff --git a/src/openbsd.c b/src/openbsd.c index 2655992e..1a87e874 100644 --- a/src/openbsd.c +++ b/src/openbsd.c @@ -628,7 +628,8 @@ void update_wifi_stats() bzero(&ifmr, sizeof(ifmr)); strlcpy(ifmr.ifm_name, ifa->ifa_name, IFNAMSIZ); if (ioctl(s, SIOCGIFMEDIA, (caddr_t) &ifmr) < 0) { - goto cleanup; + close(s); + return; } /* We can monitor only wireless interfaces diff --git a/src/xmms2.c b/src/xmms2.c index 63786cc4..42d7dea0 100644 --- a/src/xmms2.c +++ b/src/xmms2.c @@ -39,42 +39,42 @@ static void xmms_alloc(struct information *ptr) { if (ptr->xmms2.status == NULL) { - ptr->xmms2.status = malloc(TEXT_BUFFER_SIZE); + ptr->xmms2.status = malloc(text_buffer_size); ptr->xmms2.status[0] = '\0'; } if (ptr->xmms2.artist == NULL) { - ptr->xmms2.artist = malloc(TEXT_BUFFER_SIZE); + ptr->xmms2.artist = malloc(text_buffer_size); ptr->xmms2.artist[0] = '\0'; } if (ptr->xmms2.album == NULL) { - ptr->xmms2.album = malloc(TEXT_BUFFER_SIZE); + ptr->xmms2.album = malloc(text_buffer_size); ptr->xmms2.album[0] = '\0'; } if (ptr->xmms2.title == NULL) { - ptr->xmms2.title = malloc(TEXT_BUFFER_SIZE); + ptr->xmms2.title = malloc(text_buffer_size); ptr->xmms2.title[0] = '\0'; } if (ptr->xmms2.genre == NULL) { - ptr->xmms2.genre = malloc(TEXT_BUFFER_SIZE); + ptr->xmms2.genre = malloc(text_buffer_size); ptr->xmms2.genre[0] = '\0'; } if (ptr->xmms2.comment == NULL) { - ptr->xmms2.comment = malloc(TEXT_BUFFER_SIZE); + ptr->xmms2.comment = malloc(text_buffer_size); ptr->xmms2.comment[0] = '\0'; } if (ptr->xmms2.url == NULL) { - ptr->xmms2.url = malloc(TEXT_BUFFER_SIZE); + ptr->xmms2.url = malloc(text_buffer_size); ptr->xmms2.url[0] = '\0'; } if (ptr->xmms2.date == NULL) { - ptr->xmms2.date = malloc(TEXT_BUFFER_SIZE); + ptr->xmms2.date = malloc(text_buffer_size); ptr->xmms2.date[0] = '\0'; } } @@ -132,52 +132,52 @@ void handle_curent_id(xmmsc_result_t *res, void *p) xmmsc_result_get_dict_entry_string(res2, "artist", &temp); if (temp != NULL) { - strncpy(ptr->xmms2.artist, temp, TEXT_BUFFER_SIZE - 1); + strncpy(ptr->xmms2.artist, temp, text_buffer_size - 1); } else { - strncpy(ptr->xmms2.artist, "[Unknown]", TEXT_BUFFER_SIZE - 1); + strncpy(ptr->xmms2.artist, "[Unknown]", text_buffer_size - 1); } xmmsc_result_get_dict_entry_string(res2, "title", &temp); if (temp != NULL) { - strncpy(ptr->xmms2.title, temp, TEXT_BUFFER_SIZE - 1); + strncpy(ptr->xmms2.title, temp, text_buffer_size - 1); } else { - strncpy(ptr->xmms2.title, "[Unknown]", TEXT_BUFFER_SIZE - 1); + strncpy(ptr->xmms2.title, "[Unknown]", text_buffer_size - 1); } xmmsc_result_get_dict_entry_string(res2, "album", &temp); if (temp != NULL) { - strncpy(ptr->xmms2.album, temp, TEXT_BUFFER_SIZE - 1); + strncpy(ptr->xmms2.album, temp, text_buffer_size - 1); } else { - strncpy(ptr->xmms2.album, "[Unknown]", TEXT_BUFFER_SIZE - 1); + strncpy(ptr->xmms2.album, "[Unknown]", text_buffer_size - 1); } xmmsc_result_get_dict_entry_string(res2, "genre", &temp); if (temp != NULL) { - strncpy(ptr->xmms2.genre, temp, TEXT_BUFFER_SIZE - 1); + strncpy(ptr->xmms2.genre, temp, text_buffer_size - 1); } else { - strncpy(ptr->xmms2.genre, "[Unknown]", TEXT_BUFFER_SIZE - 1); + strncpy(ptr->xmms2.genre, "[Unknown]", text_buffer_size - 1); } xmmsc_result_get_dict_entry_string(res2, "comment", &temp); if (temp != NULL) { - strncpy(ptr->xmms2.comment, temp, TEXT_BUFFER_SIZE - 1); + strncpy(ptr->xmms2.comment, temp, text_buffer_size - 1); } else { - strncpy(ptr->xmms2.comment, "", TEXT_BUFFER_SIZE - 1); + strncpy(ptr->xmms2.comment, "", text_buffer_size - 1); } xmmsc_result_get_dict_entry_string(res2, "url", &temp); if (temp != NULL) { - strncpy(ptr->xmms2.url, temp, TEXT_BUFFER_SIZE - 1); + strncpy(ptr->xmms2.url, temp, text_buffer_size - 1); } else { - strncpy(ptr->xmms2.url, "[Unknown]", TEXT_BUFFER_SIZE - 1); + strncpy(ptr->xmms2.url, "[Unknown]", text_buffer_size - 1); } xmmsc_result_get_dict_entry_string(res2, "date", &temp); if (temp != NULL) { - strncpy(ptr->xmms2.date, temp, TEXT_BUFFER_SIZE - 1); + strncpy(ptr->xmms2.date, temp, text_buffer_size - 1); } else { - strncpy(ptr->xmms2.date, "????", TEXT_BUFFER_SIZE - 1); + strncpy(ptr->xmms2.date, "????", text_buffer_size - 1); } int itemp; @@ -237,16 +237,16 @@ void handle_playback_state_change(xmmsc_result_t *res, void *p) switch (pb_state) { case XMMS_PLAYBACK_STATUS_PLAY: - strncpy(ptr->xmms2.status, "Playing", TEXT_BUFFER_SIZE - 1); + strncpy(ptr->xmms2.status, "Playing", text_buffer_size - 1); break; case XMMS_PLAYBACK_STATUS_PAUSE: - strncpy(ptr->xmms2.status, "Paused", TEXT_BUFFER_SIZE - 1); + strncpy(ptr->xmms2.status, "Paused", text_buffer_size - 1); break; case XMMS_PLAYBACK_STATUS_STOP: - strncpy(ptr->xmms2.status, "Stopped", TEXT_BUFFER_SIZE - 1); + strncpy(ptr->xmms2.status, "Stopped", text_buffer_size - 1); break; default: - strncpy(ptr->xmms2.status, "Unknown", TEXT_BUFFER_SIZE - 1); + strncpy(ptr->xmms2.status, "Unknown", text_buffer_size - 1); } } @@ -254,7 +254,7 @@ void handle_playlist_loaded(xmmsc_result_t *res, void *p) { struct information *ptr = p; if (ptr->xmms2.playlist == NULL) { - ptr->xmms2.playlist = malloc(TEXT_BUFFER_SIZE); + ptr->xmms2.playlist = malloc(text_buffer_size); ptr->xmms2.playlist[0] = '\0'; }