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;
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;
}
}
continue;
if (status < 0)
- return (status);
+ return errno ? errno : status;
nleft = nleft - ((size_t)status);
ptr = ptr + ((size_t)status);
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) {
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;
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) {
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);
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) {
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");
#if HAVE_CAPABILITY
int check_capability(int arg) /* {{{ */
{
- cap_value_t cap = (cap_value_t)arg;
+ cap_value_t cap_value = (cap_value_t)arg;
+ cap_t cap;
+ cap_flag_value_t cap_flag_value;
- if (!CAP_IS_SUPPORTED(cap))
+ if (!CAP_IS_SUPPORTED(cap_value))
return (-1);
- int have_cap = cap_get_bound(cap);
- if (have_cap != 1)
+ if (!(cap = cap_get_proc())) {
+ ERROR("check_capability: cap_get_proc failed.");
return (-1);
+ }
- return (0);
+ if (cap_get_flag(cap, cap_value, CAP_EFFECTIVE, &cap_flag_value) < 0) {
+ ERROR("check_capability: cap_get_flag failed.");
+ cap_free(cap);
+ return (-1);
+ }
+ cap_free(cap);
+
+ return (cap_flag_value != CAP_SET);
} /* }}} int check_capability */
#else
int check_capability(__attribute__((unused)) int arg) /* {{{ */