X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fdaemon%2Fcommon.c;h=53c1f08ac5aa87c362844a8189e703e96a699b77;hb=f701e685eab83f37ecc6501d7dbe4eb941a454bb;hp=5386739fbc372e96638ac55c79a91e8ca3af3ca9;hpb=216c6246b73645ac093de15b87aedc9abc6ebc80;p=collectd.git diff --git a/src/daemon/common.c b/src/daemon/common.c index 5386739f..53c1f08a 100644 --- a/src/daemon/common.c +++ b/src/daemon/common.c @@ -49,6 +49,8 @@ #include #include +#include + #if HAVE_NETINET_IN_H # include #endif @@ -270,9 +272,23 @@ ssize_t swrite (int fd, const void *buf, size_t count) const char *ptr; size_t nleft; ssize_t status; + struct pollfd pfd; ptr = (const char *) buf; nleft = count; + + /* checking for closed peer connection */ + pfd.fd = fd; + pfd.events = POLLIN | POLLHUP; + pfd.revents = 0; + if (poll(&pfd, 1, 0) > 0) { + char buffer[32]; + if (recv(fd, buffer, sizeof(buffer), MSG_PEEK | MSG_DONTWAIT) == 0) { + // if recv returns zero (even though poll() said there is data to be read), + // that means the connection has been closed + return -1; + } + } while (nleft > 0) { @@ -312,44 +328,51 @@ int strsplit (char *string, char **fields, size_t size) return ((int) i); } -int strjoin (char *dst, size_t dst_len, +int strjoin (char *buffer, size_t buffer_size, char **fields, size_t fields_num, const char *sep) { - size_t field_len; + size_t avail; + char *ptr; size_t sep_len; - int i; - - memset (dst, '\0', dst_len); + size_t i; - if (fields_num <= 0) + if ((buffer_size < 1) || (fields_num <= 0)) return (-1); + memset (buffer, 0, buffer_size); + ptr = buffer; + avail = buffer_size - 1; + sep_len = 0; if (sep != NULL) sep_len = strlen (sep); - for (i = 0; i < (int)fields_num; i++) + for (i = 0; i < fields_num; i++) { + size_t field_len; + if ((i > 0) && (sep_len > 0)) { - if (dst_len <= sep_len) + if (avail < sep_len) return (-1); - strncat (dst, sep, dst_len); - dst_len -= sep_len; + memcpy (ptr, sep, sep_len); + ptr += sep_len; + avail -= sep_len; } field_len = strlen (fields[i]); - - if (dst_len <= field_len) + if (avail < field_len) return (-1); - strncat (dst, fields[i], dst_len); - dst_len -= field_len; + memcpy (ptr, fields[i], field_len); + ptr += field_len; + avail -= field_len; } - return (strlen (dst)); + assert (buffer[buffer_size - 1] == 0); + return (strlen (buffer)); } int strsubstitute (char *str, char c_from, char c_to) @@ -373,6 +396,60 @@ int strsubstitute (char *str, char c_from, char c_to) return (ret); } /* int strsubstitute */ +int escape_string (char *buffer, size_t buffer_size) +{ + char *temp; + size_t i; + size_t j; + + /* Check if we need to escape at all first */ + temp = strpbrk (buffer, " \t\"\\"); + if (temp == NULL) + return (0); + + if (buffer_size < 3) + return (EINVAL); + + temp = (char *) malloc (buffer_size); + if (temp == NULL) + return (ENOMEM); + memset (temp, 0, buffer_size); + + temp[0] = '"'; + j = 1; + + for (i = 0; i < buffer_size; i++) + { + if (buffer[i] == 0) + { + break; + } + else if ((buffer[i] == '"') || (buffer[i] == '\\')) + { + if (j > (buffer_size - 4)) + break; + temp[j] = '\\'; + temp[j + 1] = buffer[i]; + j += 2; + } + else + { + if (j > (buffer_size - 3)) + break; + temp[j] = buffer[i]; + j++; + } + } + + assert ((j + 1) < buffer_size); + temp[j] = '"'; + temp[j + 1] = 0; + + sstrncpy (buffer, temp, buffer_size); + sfree (temp); + return (0); +} /* int escape_string */ + int strunescape (char *buf, size_t buf_len) { size_t i; @@ -421,8 +498,8 @@ size_t strstripnewline (char *buffer) if ((buffer[buffer_len - 1] != '\n') && (buffer[buffer_len - 1] != '\r')) break; - buffer[buffer_len] = 0; buffer_len--; + buffer[buffer_len] = 0; } return (buffer_len); @@ -453,7 +530,7 @@ int escape_slashes (char *buffer, size_t buffer_size) buffer_len--; } - for (i = 0; i < buffer_len - 1; i++) + for (i = 0; i < buffer_len; i++) { if (buffer[i] == '/') buffer[i] = '_'; @@ -914,18 +991,17 @@ int format_values (char *ret, size_t ret_len, /* {{{ */ for (i = 0; i < ds->ds_num; i++) { if (ds->ds[i].type == DS_TYPE_GAUGE) - BUFFER_ADD (":%f", vl->values[i].gauge); + BUFFER_ADD (":"GAUGE_FORMAT, vl->values[i].gauge); else if (store_rates) { if (rates == NULL) rates = uc_get_rate (ds, vl); if (rates == NULL) { - WARNING ("format_values: " - "uc_get_rate failed."); + WARNING ("format_values: uc_get_rate failed."); return (-1); } - BUFFER_ADD (":%g", rates[i]); + BUFFER_ADD (":"GAUGE_FORMAT, rates[i]); } else if (ds->ds[i].type == DS_TYPE_COUNTER) BUFFER_ADD (":%llu", vl->values[i].counter); @@ -935,7 +1011,7 @@ int format_values (char *ret, size_t ret_len, /* {{{ */ BUFFER_ADD (":%"PRIu64, vl->values[i].absolute); else { - ERROR ("format_values plugin: Unknown data source type: %i", + ERROR ("format_values: Unknown data source type: %i", ds->ds[i].type); sfree (rates); return (-1);