X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fdaemon%2Fcommon.c;h=c80abcbee65cb1e95a8ef14dc065d7082f83c4c2;hb=8c5927c52f4eefebaad3a6ecadc253ee9007ebb5;hp=765619160cbcda31cba551e13f2be4eba66e0b56;hpb=448627953cde2f7b3b138f53f4f2c62f0d48b726;p=collectd.git diff --git a/src/daemon/common.c b/src/daemon/common.c index 76561916..c80abcbe 100644 --- a/src/daemon/common.c +++ b/src/daemon/common.c @@ -68,6 +68,11 @@ extern kstat_ctl_t *kc; #endif +/* AIX doesn't have MSG_DONTWAIT */ +#ifndef MSG_DONTWAIT +# define MSG_DONTWAIT MSG_NONBLOCK +#endif + #if !HAVE_GETPWNAM_R static pthread_mutex_t getpwnam_r_lock = PTHREAD_MUTEX_INITIALIZER; #endif @@ -334,50 +339,60 @@ int strsplit (char *string, char **fields, size_t size) return ((int) i); } -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; +int strjoin(char *buffer, size_t buffer_size, char **fields, size_t fields_num, + const char *sep) { + 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; - memset (buffer, 0, buffer_size); - ptr = buffer; - avail = buffer_size - 1; + if (((fields_num != 0) && (fields == NULL)) || + ((buffer_size != 0) && (buffer == NULL))) + return (-EINVAL); - sep_len = 0; - if (sep != NULL) - sep_len = strlen (sep); + if (buffer != NULL) + buffer[0] = 0; - for (size_t i = 0; i < fields_num; i++) - { - size_t field_len; + if (buffer_size != 0) + avail = buffer_size - 1; - if ((i > 0) && (sep_len > 0)) - { - if (avail < sep_len) - return (-1); + if (sep != NULL) + sep_len = strlen(sep); - memcpy (ptr, sep, sep_len); - ptr += sep_len; - avail -= sep_len; - } + for (size_t i = 0; i < fields_num; i++) { + size_t field_len = strlen(fields[i]); - field_len = strlen (fields[i]); - if (avail < field_len) - return (-1); + if (i != 0) + buffer_req += sep_len; + buffer_req += field_len; - memcpy (ptr, fields[i], field_len); - ptr += field_len; - avail -= field_len; - } + if ((i != 0) && (sep_len > 0)) { + if (sep_len >= avail) { + /* prevent subsequent iterations from writing to the + * buffer. */ + avail = 0; + continue; + } - assert (buffer[buffer_size - 1] == 0); - return ((int) strlen (buffer)); + memcpy(ptr, sep, sep_len); + + ptr += sep_len; + avail -= sep_len; + } + + if (field_len > avail) + field_len = avail; + + memcpy(ptr, fields[i], field_len); + ptr += field_len; + + avail -= field_len; + if (ptr != NULL) + *ptr = 0; + } + + return (int)buffer_req; } int escape_string (char *buffer, size_t buffer_size) @@ -1124,7 +1139,7 @@ int parse_value (const char *value_orig, value_t *ret_value, int ds_type) } if (value == endptr) { - ERROR ("parse_value: Failed to parse string as %s: %s.", + ERROR ("parse_value: Failed to parse string as %s: \"%s\".", DS_TYPE_TO_STRING (ds_type), value); sfree (value); return -1; @@ -1199,6 +1214,28 @@ 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) @@ -1572,8 +1609,6 @@ void set_sock_opts (int sockfd) /* {{{ */ socklen_t socklen = sizeof (socklen_t); int so_keepalive = 1; - int tcp_keepidle = ((CDTIME_T_TO_MS(plugin_get_interval()) - 1) / 100 + 1); - int tcp_keepintvl = ((CDTIME_T_TO_MS(plugin_get_interval()) - 1) / 1000 + 1); status = getsockopt (sockfd, SOL_SOCKET, SO_TYPE, &socktype, &socklen); if (status != 0) @@ -1590,6 +1625,7 @@ void set_sock_opts (int sockfd) /* {{{ */ WARNING ("set_sock_opts: failed to set socket keepalive flag"); #ifdef TCP_KEEPIDLE + int tcp_keepidle = ((CDTIME_T_TO_MS(plugin_get_interval()) - 1) / 100 + 1); status = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, &tcp_keepidle, sizeof (tcp_keepidle)); if (status != 0) @@ -1597,6 +1633,7 @@ void set_sock_opts (int sockfd) /* {{{ */ #endif #ifdef TCP_KEEPINTVL + int tcp_keepintvl = ((CDTIME_T_TO_MS(plugin_get_interval()) - 1) / 1000 + 1); status = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, &tcp_keepintvl, sizeof (tcp_keepintvl)); if (status != 0) @@ -1677,23 +1714,43 @@ void strarray_free (char **array, size_t array_len) /* {{{ */ int check_capability (int capability) /* {{{ */ { #ifdef _LINUX_CAPABILITY_VERSION_3 - struct __user_cap_header_struct cap_header_data; - cap_user_header_t cap_header = &cap_header_data; - struct __user_cap_data_struct cap_data_data; - cap_user_data_t cap_data = &cap_data_data; + cap_user_header_t cap_header = calloc(1, sizeof (*cap_header)); + if (cap_header == NULL) + { + ERROR("check_capability: calloc failed"); + return (-1); + } + + cap_user_data_t cap_data = calloc(1, sizeof (*cap_data)); + if (cap_data == NULL) + { + ERROR("check_capability: calloc failed"); + sfree(cap_header); + return (-1); + } cap_header->pid = getpid(); cap_header->version = _LINUX_CAPABILITY_VERSION; if (capget(cap_header, cap_data) < 0) { ERROR("check_capability: capget failed"); + sfree(cap_header); + sfree(cap_data); return (-1); } if ((cap_data->effective & (1 << capability)) == 0) + { + sfree(cap_header); + sfree(cap_data); return (-1); + } else + { + sfree(cap_header); + sfree(cap_data); return (0); + } #else WARNING ("check_capability: unsupported capability implementation. " "Some plugin(s) may require elevated privileges to work properly.");