X-Git-Url: https://git.octo.it/?p=collectd.git;a=blobdiff_plain;f=src%2Fdaemon%2Fcommon.c;h=ec5c7ababee0473c006cd90206afe6d1d2b42188;hp=2be2e8e57c31d175189f0287ca0b9e4acbe8c37d;hb=11c8a760c2d354b2f4637bdb297efb253bfaa519;hpb=6cb7fdcc48e913ee293f27a6f16a3acc0c1bab05 diff --git a/src/daemon/common.c b/src/daemon/common.c index 2be2e8e5..ec5c7aba 100644 --- a/src/daemon/common.c +++ b/src/daemon/common.c @@ -271,8 +271,10 @@ ssize_t swrite(int fd, const void *buf, size_t count) { ptr = (const char *)buf; nleft = count; - if (fd < 0) - return (-1); + if (fd < 0) { + errno = EINVAL; + return errno; + } /* checking for closed peer connection */ pfd.fd = fd; @@ -281,10 +283,9 @@ ssize_t swrite(int fd, const void *buf, size_t count) { 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; + /* if recv returns zero (even though poll() said there is data to be + * read), that means the connection has been closed */ + return errno ? errno : -1; } } @@ -295,7 +296,7 @@ ssize_t swrite(int fd, const void *buf, size_t count) { continue; if (status < 0) - return (status); + return errno ? errno : status; nleft = nleft - ((size_t)status); ptr = ptr + ((size_t)status); @@ -325,44 +326,58 @@ int strsplit(char *string, char **fields, size_t size) { int strjoin(char *buffer, size_t buffer_size, char **fields, size_t fields_num, const char *sep) { - size_t avail; - char *ptr; - size_t sep_len; + size_t avail = 0; + char *ptr = buffer; + size_t sep_len = 0; - if ((buffer_size < 1) || (fields_num == 0)) - return (-1); + size_t buffer_req = 0; + + if (((fields_num != 0) && (fields == NULL)) || + ((buffer_size != 0) && (buffer == NULL))) + return (-EINVAL); + + if (buffer != NULL) + buffer[0] = 0; - memset(buffer, 0, buffer_size); - ptr = buffer; - avail = buffer_size - 1; + if (buffer_size != 0) + avail = buffer_size - 1; - sep_len = 0; if (sep != NULL) sep_len = strlen(sep); for (size_t i = 0; i < fields_num; i++) { - size_t field_len; + size_t field_len = strlen(fields[i]); - if ((i > 0) && (sep_len > 0)) { - if (avail < sep_len) - return (-1); + if (i != 0) + buffer_req += sep_len; + buffer_req += field_len; + + if ((i != 0) && (sep_len > 0)) { + if (sep_len >= avail) { + /* prevent subsequent iterations from writing to the + * buffer. */ + avail = 0; + continue; + } memcpy(ptr, sep, sep_len); + ptr += sep_len; avail -= sep_len; } - field_len = strlen(fields[i]); - if (avail < field_len) - return (-1); + if (field_len > avail) + field_len = avail; memcpy(ptr, fields[i], field_len); ptr += field_len; + avail -= field_len; + if (ptr != NULL) + *ptr = 0; } - assert(buffer[buffer_size - 1] == 0); - return ((int)strlen(buffer)); + return (int)buffer_req; } int escape_string(char *buffer, size_t buffer_size) { @@ -916,7 +931,7 @@ int format_values(char *ret, size_t ret_len, /* {{{ */ int parse_identifier(char *str, char **ret_host, char **ret_plugin, char **ret_plugin_instance, char **ret_type, - char **ret_type_instance) { + char **ret_type_instance, char *default_host) { char *hostname = NULL; char *plugin = NULL; char *plugin_instance = NULL; @@ -934,10 +949,17 @@ int parse_identifier(char *str, char **ret_host, char **ret_plugin, plugin++; type = strchr(plugin, '/'); - if (type == NULL) - return (-1); - *type = '\0'; - type++; + if (type == NULL) { + if (default_host == NULL) + return (-1); + /* else: no host specified; use default */ + type = plugin; + plugin = hostname; + hostname = default_host; + } else { + *type = '\0'; + type++; + } plugin_instance = strchr(plugin, '-'); if (plugin_instance != NULL) { @@ -975,7 +997,8 @@ int parse_identifier_vl(const char *str, value_list_t *vl) /* {{{ */ sstrncpy(str_copy, str, sizeof(str_copy)); status = parse_identifier(str_copy, &host, &plugin, &plugin_instance, &type, - &type_instance); + &type_instance, + /* default_host = */ NULL); if (status != 0) return (status); @@ -1102,6 +1125,26 @@ int parse_values(char *buffer, value_list_t *vl, const data_set_t *ds) { return (0); } /* int parse_values */ +int parse_value_file(char const *path, value_t *ret_value, int ds_type) { + FILE *fh; + char buffer[256]; + + fh = fopen(path, "r"); + if (fh == NULL) + return (-1); + + if (fgets(buffer, sizeof(buffer), fh) == NULL) { + fclose(fh); + return (-1); + } + + fclose(fh); + + strstripnewline(buffer); + + return parse_value(buffer, ret_value, ds_type); +} /* int parse_value_file */ + #if !HAVE_GETPWNAM_R int getpwnam_r(const char *name, struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp) { @@ -1422,18 +1465,16 @@ void set_sock_opts(int sockfd) /* {{{ */ int status; int socktype; - socklen_t socklen = sizeof(socklen_t); - int so_keepalive = 1; - - status = getsockopt(sockfd, SOL_SOCKET, SO_TYPE, &socktype, &socklen); + status = getsockopt(sockfd, SOL_SOCKET, SO_TYPE, &socktype, + &(socklen_t){sizeof(socktype)}); if (status != 0) { WARNING("set_sock_opts: failed to determine socket type"); return; } if (socktype == SOCK_STREAM) { - status = setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &so_keepalive, - sizeof(so_keepalive)); + status = + setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &(int){1}, sizeof(int)); if (status != 0) WARNING("set_sock_opts: failed to set socket keepalive flag");