# include <arpa/inet.h>
#endif
+#ifdef HAVE_SYS_CAPABILITY_H
+# include <sys/capability.h>
+#endif
+
#ifdef HAVE_LIBKSTAT
extern kstat_ctl_t *kc;
#endif
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;
+ }
+
+ memcpy(ptr, sep, sep_len);
- assert (buffer[buffer_size - 1] == 0);
- return ((int) strlen (buffer));
+ 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)
return (0);
} /* int parse_values */
+int parse_value_file (char const *path, value_t *ret_value, int ds_type)
+{
+ char buffer[256];
+
+ if (read_file_contents (path, buffer, sizeof (buffer)) < 0)
+ return errno;
+
+ 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)
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)
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)
#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)
sfree (array[i]);
sfree (array);
} /* }}} void strarray_free */
+
+#ifdef HAVE_SYS_CAPABILITY_H
+int check_capability (int capability) /* {{{ */
+{
+#ifdef _LINUX_CAPABILITY_VERSION_3
+ 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.");
+ return (0);
+#endif /* _LINUX_CAPABILITY_VERSION_3 */
+} /* }}} int check_capability */
+#endif /* HAVE_SYS_CAPABILITY_H */