summaryrefslogtreecommitdiff
path: root/app-metrics/collectd/files/collectd-5.12.0-nut-c99.patch
blob: 0935eed070e9a2aa20f4a28adff56f7cabbb42f1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
https://github.com/collectd/collectd/commit/d409ffa2a64cac3fc2abe2bb86ec3a80cb34d0a6

From d409ffa2a64cac3fc2abe2bb86ec3a80cb34d0a6 Mon Sep 17 00:00:00 2001
From: Jim Klimov <jimklimov+nut@gmail.com>
Date: Wed, 31 Aug 2022 11:40:01 +0200
Subject: [PATCH] configure.ac, src/nut.c: detect int types required by NUT API
 we build against

Either use the stricter int types required by NUT headers since v2.8.0 release,
or the relaxed (arch-dependent) types required by older NUT releases - depending
on which NUT API version the collectd is building against at the moment.

Inspired by discussion at https://github.com/networkupstools/nut/issues/1638
--- a/configure.ac
+++ b/configure.ac
@@ -5881,6 +5881,106 @@ if test "x$with_libupsclient" = "xyes"; then
   CPPFLAGS="$SAVE_CPPFLAGS"
 fi
 
+if test "x$with_libupsclient" = "xyes"; then
+  dnl The m4 script logic below is modelled after NUT_FUNC_GETNAMEINFO_ARGTYPES
+  dnl further originating in curl autoconf scripts or beyond. See there for an
+  dnl example of general-case logic to handle matching of numerous possible
+  dnl data types for each argument in supported API variants.
+  dnl Note: techically compiler complains here not about int types themselves,
+  dnl but about pointers to such data. We know "out of band" that e.g. NUT
+  dnl change to "size_t" happened at once for all arguments in the API, so
+  dnl simplify the handling here and now with that assumption.
+  AC_LANG_PUSH([C])
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  SAVE_LDFLAGS="$LDFLAGS"
+  SAVE_CFLAGS="$CFLAGS"
+  CPPFLAGS="$CPPFLAGS $with_libupsclient_cflags"
+  LDFLAGS="$LDFLAGS $with_libupsclient_libs"
+  CFLAGS="$CFLAGS $with_libupsclient_cflags"
+  if test "x$GCC" = "xyes"; then
+    CFLAGS="$CFLAGS -Wall -Werror"
+  fi
+
+  dnl upscli_splitname() *is* there forever (2007 or older)
+  dnl but int types e.g. "port" changed in NUT 2.8.0
+  dnl Also this is the UPSCONN_t::port field type:
+  AC_CACHE_CHECK([int type of port argument for NUT upscli_splitname],
+    [collectd_cv_func_upscli_splitname_args], [
+     collectd_cv_func_upscli_splitname_args="unknown"
+     for port_arg in 'uint16_t' 'int' ; do
+        AC_COMPILE_IFELSE([
+            AC_LANG_PROGRAM([
+#include <upsclient.h>
+/* int upscli_splitname(const char *buf, char **upsname, char **hostname, <port_arg> *port); */
+            ],[
+const char *origname = "ups@localhost:3493";
+$port_arg port=0;
+char *hostname;
+char *upsname;
+int res = upscli_splitname(origname, &upsname, &hostname, &port);
+return(res);
+            ])
+        ],[
+            collectd_cv_func_upscli_splitname_args="$port_arg"
+            break
+        ])
+     done
+    ])
+
+  AS_IF([test x"$collectd_cv_func_upscli_splitname_args" = xunknown],
+    [AC_MSG_WARN([Can not find proper port type for upscli_splitname()])
+     with_libupsclient="no (required data types for NUT API were not detected)"],
+    [AC_DEFINE_UNQUOTED(NUT_PORT_TYPE, $collectd_cv_func_upscli_splitname_args,
+        [Define to the integer type for TCP/IP ports used by NUT API we build against])
+    ])
+
+
+  AC_CACHE_CHECK([int type of length/numbering arguments for NUT upscli_list_next],
+    [collectd_cv_func_upscli_list_next_args], [
+     collectd_cv_func_upscli_list_next_args="unknown"
+     for size_arg in 'size_t' 'unsigned int' 'int' ; do
+        AC_COMPILE_IFELSE([
+            AC_LANG_PROGRAM([
+#include <upsclient.h>
+/* int upscli_list_next(UPSCONN_t *ups, <size_arg> numq, const char **query, <size_arg> *numa, char ***answer); */
+
+#if HAVE_UPSCONN_T
+typedef UPSCONN_t collectd_upsconn_t;
+#elif HAVE_UPSCONN
+typedef UPSCONN collectd_upsconn_t;
+#else
+#error "Unable to determine the UPS connection type."
+#endif
+            ],[
+$size_arg query_num=0;
+$size_arg answer_num=0;
+const char * query;
+char** answer;
+collectd_upsconn_t ups;
+int res = upscli_list_next(&ups, query_num, &query, &answer_num, &answer);
+return(res);
+            ])
+        ],[
+            collectd_cv_func_upscli_list_next_args="$size_arg"
+            break
+        ])
+     done
+    ])
+
+  AS_IF([test x"$collectd_cv_func_upscli_list_next_args" = xunknown],
+    [AC_MSG_WARN([Can not find proper type for array sizes and string lengths used by upscli_list_next()])
+     with_libupsclient="no (required data types for NUT API were not detected)"],
+    [AC_DEFINE_UNQUOTED(NUT_SIZE_TYPE, $collectd_cv_func_upscli_list_next_args,
+        [Define to the integer type for array sizes and string lengths used by NUT API we build against])
+    ])
+
+
+  CPPFLAGS="$SAVE_CPPFLAGS"
+  LDFLAGS="$SAVE_LDFLAGS"
+  CFLAGS="$SAVE_CFLAGS"
+  AC_LANG_POP([C])
+fi
+
 if test "x$with_libupsclient" = "xyes"; then
   BUILD_WITH_LIBUPSCLIENT_CFLAGS="$with_libupsclient_cflags"
   BUILD_WITH_LIBUPSCLIENT_LIBS="$with_libupsclient_libs"
--- a/src/nut.c
+++ b/src/nut.c
@@ -46,7 +46,7 @@ struct nut_ups_s {
   collectd_upsconn_t *conn;
   char *upsname;
   char *hostname;
-  int port;
+  NUT_PORT_TYPE port;
   nut_ups_t *next;
 };
 
@@ -250,7 +250,7 @@ static int nut_read(user_data_t *user_data) {
   const char *query[3] = {"VAR", ups->upsname, NULL};
   unsigned int query_num = 2;
   char **answer;
-  unsigned int answer_num;
+  NUT_SIZE_TYPE answer_num;
   int status;
 
   /* (Re-)Connect if we have no connection */