1From b76e3c578f1e9f582e9c28f50d82b1f569602075 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Michal=20Such=C3=A1nek?= <hramrach@gmail.com>
3Date: Fri, 5 Jan 2024 15:31:48 +0100
4Subject: [PATCH] Constify argv, fix warnings. (#1242)
5
6* Fix perl warnings
7
8 - cast POPs to void to avoid unused value warning
9 - declare functions that don't set RETVAL as returning void
10
11Signed-off-by: Michal Suchanek <msuchanek@suse.de>
12
13* Constify argv
14
15rrd has no business modifying the string pointed to by passed agrv, and
16as far as gcc can see it does indeed not modify them because it compiles
17with const argv.
18
19This fixes warnings when passing const strings into rrd, and avoids the
20need to duplicate all strings in the tcl bindings.
21
22This fixes warnings like these:
23[    3s] prog/sensord/rrd.c: In function 'rrdInit':
24[    3s] prog/sensord/rrd.c:302:40: warning: cast discards 'const' qualifier from pointer target type [-Wcast-qual]
25[    3s]   302 |                 ret = rrd_create(argc, (char**) argv);
26[    3s]       |                                        ^
27[    3s] prog/sensord/rrd.c: In function 'rrdUpdate':
28[    3s] prog/sensord/rrd.c:458:42: warning: cast discards 'const' qualifier from pointer target type [-Wcast-qual]
29[    3s]   458 |                 if ((ret = rrd_update(3, (char **) /* WEAK */ argv))) {
30[    3s]       |                                          ^
31
32Signed-off-by: Michal Suchanek <msuchanek@suse.de>
33
34* tcl: Do not duplicate const strings
35
36---------
37
38Signed-off-by: Michal Suchanek <msuchanek@suse.de>
39Upstream-Status: Backport [https://github.com/oetiker/rrdtool-1.x/commit/b76e3c578f1e9f582e9c28f50d82b1f569602075]
40---
41 CHANGES                         |  3 ++
42 bindings/lua/rrdlua.c           | 25 +++++-----
43 bindings/perl-shared/RRDs.xs    | 36 +++++++-------
44 bindings/python/rrdtoolmodule.c | 38 +++++++--------
45 bindings/ruby/main.c            | 10 ++--
46 bindings/tcl/tclrrd.c           | 84 ++++++++-------------------------
47 src/optparse.c                  | 14 +++---
48 src/optparse.h                  |  6 +--
49 src/rrd.h                       | 38 +++++++--------
50 src/rrd_cgi.c                   | 24 +++++-----
51 src/rrd_create.c                |  2 +-
52 src/rrd_daemon.c                | 12 ++---
53 src/rrd_dump.c                  |  4 +-
54 src/rrd_fetch.c                 |  2 +-
55 src/rrd_first.c                 |  2 +-
56 src/rrd_flushcached.c           |  2 +-
57 src/rrd_graph.c                 |  6 +--
58 src/rrd_graph.h                 |  4 +-
59 src/rrd_graph_helper.c          |  2 +-
60 src/rrd_info.c                  |  2 +-
61 src/rrd_last.c                  |  2 +-
62 src/rrd_lastupdate.c            |  2 +-
63 src/rrd_list.c                  |  6 +--
64 src/rrd_modify.c                |  2 +-
65 src/rrd_modify.h                |  2 +-
66 src/rrd_resize.c                |  4 +-
67 src/rrd_restore.c               |  2 +-
68 src/rrd_tool.c                  | 26 +++++-----
69 src/rrd_tune.c                  |  2 +-
70 src/rrd_update.c                |  4 +-
71 src/rrd_xport.c                 |  2 +-
72 src/rrdupdate.c                 |  7 +--
73 32 files changed, 168 insertions(+), 209 deletions(-)
74
75diff --git a/bindings/lua/rrdlua.c b/bindings/lua/rrdlua.c
76index d1a700641..2095c3b5b 100644
77--- a/bindings/lua/rrdlua.c
78+++ b/bindings/lua/rrdlua.c
79@@ -37,8 +37,8 @@
80 extern void rrd_freemem(void *mem);
81
82 extern int luaopen_rrd (lua_State * L);
83-typedef int (*RRD_FUNCTION)(int, char **);
84-typedef rrd_info_t *(RRD_FUNCTION_V)(int, char **);
85+typedef int (*RRD_FUNCTION)(int, const char **);
86+typedef rrd_info_t *(RRD_FUNCTION_V)(int, const char **);
87
88 /**********************************************************/
89
90@@ -49,9 +49,9 @@ static void reset_rrd_state(void)
91     rrd_clear_error();
92 }
93
94-static char **make_argv(const char *cmd, lua_State * L)
95+static const char **make_argv(const char *cmd, lua_State * L)
96 {
97-  char **argv;
98+  const char **argv;
99   int i;
100   int argc = lua_gettop(L) + 1;
101
102@@ -60,13 +60,12 @@ static char **make_argv(const char *cmd, lua_State * L)
103     luaL_error(L, "Can't allocate memory for arguments array", cmd);
104
105   /* fprintf(stderr, "Args:\n"); */
106-  argv[0] = (char *) cmd; /* Dummy arg. Cast to (char *) because rrd */
107-                          /* functions don't expect (const * char)   */
108+  argv[0] = cmd;
109   /* fprintf(stderr, "%s\n", argv[0]); */
110   for (i=1; i<argc; i++) {
111     /* accepts string or number */
112     if (lua_isstring(L, i) || lua_isnumber(L, i)) {
113-      if (!(argv[i] = (char *) lua_tostring (L, i))) {
114+      if (!(argv[i] = lua_tostring (L, i))) {
115         /* raise an error and never return */
116         luaL_error(L, "%s - error duplicating string area for arg #%d",
117                    cmd, i);
118@@ -84,7 +83,7 @@ static char **make_argv(const char *cmd, lua_State * L)
119 static int
120 rrd_common_call (lua_State *L, const char *cmd, RRD_FUNCTION rrd_function)
121 {
122-  char **argv;
123+  const char **argv;
124   int argc = lua_gettop(L) + 1;
125
126   argv = make_argv(cmd, L);
127@@ -99,7 +98,7 @@ rrd_common_call (lua_State *L, const char *cmd, RRD_FUNCTION rrd_function)
128 static int
129 lua_rrd_infocall(lua_State *L, const char *cmd, RRD_FUNCTION_V rrd_function)
130 {
131-  char **argv;
132+  const char **argv;
133   rrd_info_t *p, *data;
134   int argc = lua_gettop(L) + 1;
135
136@@ -197,7 +196,7 @@ static int
137 lua_rrd_fetch (lua_State * L)
138 {
139   int argc = lua_gettop(L) + 1;
140-  char **argv = make_argv("fetch", L);
141+  const char **argv = make_argv("fetch", L);
142   unsigned long i, j, step, ds_cnt;
143   rrd_value_t *data, *p;
144   char    **names;
145@@ -246,7 +245,7 @@ lua_rrd_first (lua_State * L)
146 {
147   time_t first;
148   int argc = lua_gettop(L) + 1;
149-  char **argv = make_argv("first", L);
150+  const char **argv = make_argv("first", L);
151   reset_rrd_state();
152   first = rrd_first(argc, argv);
153   free(argv);
154@@ -260,7 +259,7 @@ lua_rrd_last (lua_State * L)
155 {
156   time_t last;
157   int argc = lua_gettop(L) + 1;
158-  char **argv = make_argv("last", L);
159+  const char **argv = make_argv("last", L);
160   reset_rrd_state();
161   last = rrd_last(argc, argv);
162   free(argv);
163@@ -275,7 +274,7 @@ static int
164 lua_rrd_graph (lua_State * L)
165 {
166   int argc = lua_gettop(L) + 1;
167-  char **argv = make_argv("last", L);
168+  const char **argv = make_argv("last", L);
169   char **calcpr;
170   int i, xsize, ysize;
171   double ymin, ymax;
172diff --git a/bindings/perl-shared/RRDs.xs b/bindings/perl-shared/RRDs.xs
173index e233b5835..edce76ec4 100644
174--- a/bindings/perl-shared/RRDs.xs
175+++ b/bindings/perl-shared/RRDs.xs
176@@ -44,11 +44,11 @@ extern "C" {
177 		    strcpy(argv[i+1],handle); \
178  	        } \
179 		rrd_clear_error();\
180-		RETVAL=name(items+1,argv); \
181+		RETVAL = name(items + 1, (const char **)argv); \
182 		for (i=0; i < items; i++) {\
183-		    free(argv[i+1]);\
184+		    free((void *)argv[i+1]);\
185 		} \
186-		free(argv);\
187+		free((void *)argv);\
188 		\
189 		if (rrd_test_error()) XSRETURN_UNDEF;
190
191@@ -67,11 +67,11 @@ extern "C" {
192 		    strcpy(argv[i+1],handle); \
193  	        } \
194                 rrd_clear_error(); \
195-                data=name(items+1, argv); \
196+                data = name(items + 1, (const char **)argv); \
197                 for (i=0; i < items; i++) { \
198-		    free(argv[i+1]); \
199+		    free((void *)argv[i+1]); \
200 		} \
201-		free(argv); \
202+		free((void *)argv); \
203                 if (rrd_test_error()) XSRETURN_UNDEF; \
204                 hash = newHV(); \
205    	        save=data; \
206@@ -175,7 +175,7 @@ static int rrd_fetch_cb_wrapper(
207     /* Check the eval first */
208     if (SvTRUE(ERRSV)) {
209         rrd_set_error("perl callback failed: %s",SvPV_nolen(ERRSV));
210-        POPs; /* there is undef on top of the stack when there is an error
211+        (void)POPs; /* there is undef on top of the stack when there is an error
212                  and call_sv was initiated with G_EVAL|G_SCALER */
213         goto error_out;
214     }
215@@ -383,7 +383,7 @@ rrd_tune(...)
216
217 #ifdef HAVE_RRD_GRAPH
218
219-SV *
220+void
221 rrd_graph(...)
222 	PROTOTYPE: @
223 	PREINIT:
224@@ -404,7 +404,7 @@ rrd_graph(...)
225 		    strcpy(argv[i+1],handle);
226  	        }
227 		rrd_clear_error();
228-		rrd_graph(items+1,argv,&calcpr,&xsize,&ysize,NULL,&ymin,&ymax);
229+		rrd_graph(items+1,(const char **)argv,&calcpr,&xsize,&ysize,NULL,&ymin,&ymax);
230 		for (i=0; i < items; i++) {
231 		    free(argv[i+1]);
232 		}
233@@ -433,7 +433,7 @@ rrd_graph(...)
234
235 #endif /* HAVE_RRD_GRAPH */
236
237-SV *
238+void
239 rrd_fetch(...)
240 	PROTOTYPE: @
241 	PREINIT:
242@@ -455,7 +455,7 @@ rrd_fetch(...)
243 		    strcpy(argv[i+1],handle);
244  	        }
245 		rrd_clear_error();
246-		rrd_fetch(items+1,argv,&start,&end,&step,&ds_cnt,&ds_namv,&data);
247+		rrd_fetch(items+1,(const char **)argv,&start,&end,&step,&ds_cnt,&ds_namv,&data);
248 		for (i=0; i < items; i++) {
249 		    free(argv[i+1]);
250 		}
251@@ -486,7 +486,7 @@ rrd_fetch(...)
252 		PUSHs(sv_2mortal(newRV_noinc((SV*)names)));
253 		PUSHs(sv_2mortal(newRV_noinc((SV*)retar)));
254
255-SV *
256+void
257 rrd_fetch_cb_register(cb)
258     SV * cb
259     CODE:
260@@ -496,7 +496,7 @@ rrd_fetch_cb_register(cb)
261             SvSetSV(rrd_fetch_cb_svptr,cb);
262         rrd_fetch_cb_register(rrd_fetch_cb_wrapper);
263
264-SV *
265+void
266 rrd_times(start, end)
267 	  char *start
268 	  char *end
269@@ -521,7 +521,7 @@ rrd_times(start, end)
270 		PUSHs(sv_2mortal(newSVuv(start_tmp)));
271 		PUSHs(sv_2mortal(newSVuv(end_tmp)));
272
273-int
274+void
275 rrd_xport(...)
276 	PROTOTYPE: @
277 	PREINIT:
278@@ -543,7 +543,7 @@ rrd_xport(...)
279 		    strcpy(argv[i+1],handle);
280  	        }
281 		rrd_clear_error();
282-		rrd_xport(items+1,argv,&xsize,&start,&end,&step,&col_cnt,&legend_v,&data);
283+		rrd_xport(items+1,(const char **)argv,&xsize,&start,&end,&step,&col_cnt,&legend_v,&data);
284 		for (i=0; i < items; i++) {
285 		    free(argv[i+1]);
286 		}
287@@ -657,7 +657,7 @@ rrd_flushcached(...)
288 	OUTPUT:
289 		RETVAL
290
291-SV*
292+void
293 rrd_list(...)
294 	PROTOTYPE: @
295 	PREINIT:
296@@ -667,7 +667,7 @@ rrd_list(...)
297                 char **argv;
298 		AV *list;
299 	PPCODE:
300-		argv = (char **) malloc((items+1)*sizeof(char *));
301+		argv = malloc((items+1)*sizeof(char *));
302 		argv[0] = "dummy";
303
304 		for (i = 0; i < items; i++) {
305@@ -681,7 +681,7 @@ rrd_list(...)
306
307                 rrd_clear_error();
308
309-		data = rrd_list(items+1, argv);
310+		data = rrd_list(items+1, (const char **)argv);
311
312                 for (i=0; i < items; i++) {
313 		    free(argv[i+1]);
314diff --git a/bindings/python/rrdtoolmodule.c b/bindings/python/rrdtoolmodule.c
315index 1ab463584..f255e65bc 100644
316--- a/bindings/python/rrdtoolmodule.c
317+++ b/bindings/python/rrdtoolmodule.c
318@@ -123,7 +123,7 @@ PyRRD_String_FromCF(enum cf_en cf)
319  * @return Zero if the function succeeds, otherwise -1
320  */
321 static int
322-convert_args(char *command, PyObject *args, char ***rrdtool_argv, int *rrdtool_argc)
323+convert_args(char *command, PyObject *args, const char ***rrdtool_argv, int *rrdtool_argc)
324 {
325     PyObject *o, *lo;
326     int i, j, args_count, argv_count, element_count;
327@@ -145,7 +145,7 @@ convert_args(char *command, PyObject *args, char ***rrdtool_argv, int *rrdtool_a
328         }
329     }
330
331-    *rrdtool_argv = PyMem_New(char *, element_count + 1);
332+    *rrdtool_argv = PyMem_New(const char *, element_count + 1);
333
334     if (*rrdtool_argv == NULL)
335         return -1;
336@@ -186,7 +186,7 @@ convert_args(char *command, PyObject *args, char ***rrdtool_argv, int *rrdtool_a
337  * Destroy argument vector.
338  */
339 static void
340-destroy_args(char ***rrdtool_argv)
341+destroy_args(const char ***rrdtool_argv)
342 {
343     PyMem_Del(*rrdtool_argv);
344     *rrdtool_argv = NULL;
345@@ -267,7 +267,7 @@ static char _rrdtool_create__doc__[] = "Create a new Round Robin Database.\n\n\
346 static PyObject *
347 _rrdtool_create(PyObject *Py_UNUSED(self), PyObject *args)
348 {
349-    char **rrdtool_argv = NULL;
350+    const char **rrdtool_argv = NULL;
351     int    rrdtool_argc = 0;
352     PyObject *ret;
353     int status;
354@@ -306,7 +306,7 @@ static char _rrdtool_dump__doc__[] = "Dump an RRD to XML.\n\n\
355 static PyObject *
356 _rrdtool_dump(PyObject *Py_UNUSED(self), PyObject *args)
357 {
358-    char **rrdtool_argv = NULL;
359+    const char **rrdtool_argv = NULL;
360     int    rrdtool_argc = 0;
361     PyObject *ret;
362     int status;
363@@ -345,7 +345,7 @@ static char _rrdtool_update__doc__[] = "Store a new set of values into\
364 static PyObject *
365 _rrdtool_update(PyObject *Py_UNUSED(self), PyObject *args)
366 {
367-    char **rrdtool_argv = NULL;
368+    const char **rrdtool_argv = NULL;
369     int    rrdtool_argc = 0;
370     PyObject *ret;
371     int status;
372@@ -378,7 +378,7 @@ static char _rrdtool_updatev__doc__[] = "Store a new set of values into "\
373 static PyObject *
374 _rrdtool_updatev(PyObject *Py_UNUSED(self), PyObject *args)
375 {
376-    char **rrdtool_argv = NULL;
377+    const char **rrdtool_argv = NULL;
378     int    rrdtool_argc = 0;
379     PyObject *ret;
380     rrd_info_t *data;
381@@ -419,7 +419,7 @@ static char _rrdtool_fetch__doc__[] = "Fetch data from an RRD.\n\n\
382 static PyObject *
383 _rrdtool_fetch(PyObject *Py_UNUSED(self), PyObject *args)
384 {
385-    char **rrdtool_argv = NULL;
386+    const char **rrdtool_argv = NULL;
387     int    rrdtool_argc = 0;
388     PyObject *ret, *range_tup, *dsnam_tup, *data_list, *t;
389     rrd_value_t *data, *datai, dv;
390@@ -497,7 +497,7 @@ static char _rrdtool_flushcached__doc__[] = "Flush RRD files from memory.\n\n\
391 static PyObject *
392 _rrdtool_flushcached(PyObject *Py_UNUSED(self), PyObject *args)
393 {
394-    char **rrdtool_argv = NULL;
395+    const char **rrdtool_argv = NULL;
396     int    rrdtool_argc = 0;
397     PyObject *ret;
398     int status;
399@@ -592,7 +592,7 @@ static char _rrdtool_graph__doc__[] = "Create a graph based on one or more " \
400 static PyObject *
401 _rrdtool_graph(PyObject *Py_UNUSED(self), PyObject *args)
402 {
403-    char **rrdtool_argv = NULL;
404+    const char **rrdtool_argv = NULL;
405     int    rrdtool_argc = 0;
406     PyObject *ret;
407     int xsize, ysize, i, status;
408@@ -650,7 +650,7 @@ static char _rrdtool_graphv__doc__[] = "Create a graph based on one or more " \
409 static PyObject *
410 _rrdtool_graphv(PyObject *Py_UNUSED(self), PyObject *args)
411 {
412-    char **rrdtool_argv = NULL;
413+    const char **rrdtool_argv = NULL;
414     int    rrdtool_argc = 0;
415     PyObject *ret;
416     rrd_info_t *data;
417@@ -695,7 +695,7 @@ static char _rrdtool_xport__doc__[] = "Dictionary representation of data " \
418 static PyObject *
419 _rrdtool_xport(PyObject *Py_UNUSED(self), PyObject *args)
420 {
421-    char **rrdtool_argv = NULL;
422+    const char **rrdtool_argv = NULL;
423     int    rrdtool_argc = 0;
424     PyObject *ret;
425     int xsize, status;
426@@ -793,7 +793,7 @@ static char _rrdtool_list__doc__[] = "List RRDs in storage.\n\n" \
427 static PyObject *
428 _rrdtool_list(PyObject *Py_UNUSED(self), PyObject *args)
429 {
430-    char **rrdtool_argv = NULL;
431+    const char **rrdtool_argv = NULL;
432     int    rrdtool_argc = 0;
433     PyObject *ret, *str;
434     char *data, *ptr, *end;
435@@ -855,7 +855,7 @@ static char _rrdtool_tune__doc__[] = "Modify some basic properties of a " \
436 static PyObject *
437 _rrdtool_tune(PyObject *Py_UNUSED(self), PyObject *args)
438 {
439-    char **rrdtool_argv = NULL;
440+    const char **rrdtool_argv = NULL;
441     int    rrdtool_argc = 0;
442     PyObject *ret;
443     int status;
444@@ -893,7 +893,7 @@ static char _rrdtool_first__doc__[] = "Get the first UNIX timestamp of the "\
445 static PyObject *
446 _rrdtool_first(PyObject *Py_UNUSED(self), PyObject *args)
447 {
448-    char **rrdtool_argv = NULL;
449+    const char **rrdtool_argv = NULL;
450     int    rrdtool_argc = 0;
451     PyObject *ret;
452     int ts;
453@@ -928,7 +928,7 @@ static char _rrdtool_last__doc__[] = "Get the UNIX timestamp of the most "\
454 static PyObject *
455 _rrdtool_last(PyObject *Py_UNUSED(self), PyObject *args)
456 {
457-    char **rrdtool_argv = NULL;
458+    const char **rrdtool_argv = NULL;
459     int    rrdtool_argc = 0;
460     PyObject *ret;
461     int ts;
462@@ -965,7 +965,7 @@ static char _rrdtool_resize__doc__[] = "Modify the number of rows in a "\
463 static PyObject *
464 _rrdtool_resize(PyObject *Py_UNUSED(self), PyObject *args)
465 {
466-    char **rrdtool_argv = NULL;
467+    const char **rrdtool_argv = NULL;
468     int    rrdtool_argc = 0;
469     PyObject *ret;
470     int status;
471@@ -1003,7 +1003,7 @@ static char _rrdtool_info__doc__[] = "Extract header information from an "\
472 static PyObject *
473 _rrdtool_info(PyObject *Py_UNUSED(self), PyObject *args)
474 {
475-    char **rrdtool_argv = NULL;
476+    const char **rrdtool_argv = NULL;
477     int    rrdtool_argc = 0;
478     PyObject *ret;
479     rrd_info_t *data;
480@@ -1040,7 +1040,7 @@ static char _rrdtool_lastupdate__doc__[] = "Returns datetime and value stored "\
481 static PyObject *
482 _rrdtool_lastupdate(PyObject *Py_UNUSED(self), PyObject *args)
483 {
484-    char **rrdtool_argv = NULL;
485+    const char **rrdtool_argv = NULL;
486     int    rrdtool_argc = 0;
487     PyObject *ret, *ds_dict, *lastupd;
488     int status;
489diff --git a/bindings/ruby/main.c b/bindings/ruby/main.c
490index e4cc6443d..a036b7fb8 100644
491--- a/bindings/ruby/main.c
492+++ b/bindings/ruby/main.c
493@@ -9,7 +9,7 @@
494
495 typedef struct string_arr_t {
496     int       len;
497-    char    **strings;
498+    const char    **strings;
499 } string_arr;
500
501 VALUE     mRRD;
502@@ -18,12 +18,12 @@ VALUE     rb_eRRDError;
503 typedef int (
504     *RRDFUNC) (
505     int argc,
506-    char **argv);
507+    const char **argv);
508
509 typedef rrd_info_t *(
510     *RRDINFOFUNC) (
511     int argc,
512-    char **argv);
513+    const char **argv);
514
515 #define RRD_CHECK_ERROR  \
516     if (rrd_test_error()) \
517@@ -72,10 +72,10 @@ void string_arr_delete(
518
519     /* skip dummy first entry */
520     for (i = 1; i < a.len; i++) {
521-        free(a.strings[i]);
522+        free((void *)a.strings[i]);
523     }
524
525-    free(a.strings);
526+    free((void *)a.strings);
527 }
528
529 void reset_rrd_state(
530diff --git a/bindings/tcl/tclrrd.c b/bindings/tcl/tclrrd.c
531index 2927d9251..58a4cef68 100644
532--- a/bindings/tcl/tclrrd.c
533+++ b/bindings/tcl/tclrrd.c
534@@ -22,6 +22,7 @@
535 #include <stdlib.h>
536 #include "../../src/rrd_tool.h"
537 #include "../../src/rrd_format.h"
538+#include "../../src/unused.h"
539
540 /* support pre-8.4 tcl */
541
542@@ -41,47 +42,39 @@ extern int Tclrrd_SafeInit(
543  * Hence, we need to do some preparation before
544  * calling the rrd library functions.
545  */
546-static char **getopt_init(
547+static const char **getopt_init(
548     int argc,
549     CONST84 char *argv[])
550 {
551-    char    **argv2;
552+    const char    **argv2;
553     int       i;
554
555     argv2 = calloc(argc, sizeof(char *));
556     for (i = 0; i < argc; i++) {
557-        argv2[i] = strdup(argv[i]);
558+        argv2[i] = argv[i];
559     }
560     return argv2;
561 }
562
563 static void getopt_cleanup(
564-    int argc,
565-    char **argv2)
566+    int UNUSED(argc),
567+    const char **argv2)
568 {
569-    int       i;
570-
571-    for (i = 0; i < argc; i++) {
572-        if (argv2[i] != NULL) {
573-            free(argv2[i]);
574-        }
575-    }
576-    free(argv2);
577+    free((void *)argv2);
578 }
579
580 static void getopt_free_element(
581-    char *argv2[],
582+    const char *argv2[],
583     int argn)
584 {
585     if (argv2[argn] != NULL) {
586-        free(argv2[argn]);
587         argv2[argn] = NULL;
588     }
589 }
590
591 static void getopt_squieeze(
592     int *argc,
593-    char *argv2[])
594+    const char *argv2[])
595 {
596     int       i, null_i = 0, argc_tmp = *argc;
597
598@@ -104,7 +97,7 @@ static int Rrd_Create(
599     CONST84 char *argv[])
600 {
601     int       argv_i;
602-    char    **argv2;
603+    const char    **argv2;
604     char     *parsetime_error = NULL;
605     time_t    last_up = time(NULL) - 10;
606     long int  long_tmp;
607@@ -295,7 +288,7 @@ static int Rrd_Flushcached(
608         return TCL_ERROR;
609     }
610
611-    rrd_flushcached(argc, (char**)argv);
612+    rrd_flushcached(argc, argv);
613
614     if (rrd_test_error()) {
615         Tcl_AppendResult(interp, "RRD Error: ",
616@@ -380,7 +373,7 @@ static int Rrd_Update(
617     CONST84 char *argv[])
618 {
619     int       argv_i;
620-    char    **argv2, *template = NULL;
621+    const char    **argv2, *template = NULL;
622
623     argv2 = getopt_init(argc, argv);
624
625@@ -391,16 +384,10 @@ static int Rrd_Update(
626                 Tcl_AppendResult(interp, "RRD Error: option '",
627                                  argv2[argv_i - 1], "' needs an argument",
628                                  (char *) NULL);
629-                if (template != NULL) {
630-                    free(template);
631-                }
632                 getopt_cleanup(argc, argv2);
633                 return TCL_ERROR;
634             }
635-            if (template != NULL) {
636-                free(template);
637-            }
638-            template = strdup(argv2[argv_i]);
639+            template = argv2[argv_i];
640             getopt_free_element(argv2, argv_i - 1);
641             getopt_free_element(argv2, argv_i);
642         } else if (!strcmp(argv2[argv_i], "--")) {
643@@ -409,9 +396,6 @@ static int Rrd_Update(
644         } else if (argv2[argv_i][0] == '-') {
645             Tcl_AppendResult(interp, "RRD Error: unknown option '",
646                              argv2[argv_i], "'", (char *) NULL);
647-            if (template != NULL) {
648-                free(template);
649-            }
650             getopt_cleanup(argc, argv2);
651             return TCL_ERROR;
652         }
653@@ -422,18 +406,12 @@ static int Rrd_Update(
654     if (argc < 2) {
655         Tcl_AppendResult(interp, "RRD Error: needs rrd filename",
656                          (char *) NULL);
657-        if (template != NULL) {
658-            free(template);
659-        }
660         getopt_cleanup(argc, argv2);
661         return TCL_ERROR;
662     }
663
664     rrd_update_r(argv2[1], template, argc - 2, (const char **)argv2 + 2);
665
666-    if (template != NULL) {
667-        free(template);
668-    }
669     getopt_cleanup(argc, argv2);
670
671     if (rrd_test_error()) {
672@@ -454,7 +432,6 @@ static int Rrd_Info(
673 {
674     int status = TCL_OK;
675     rrd_info_t *data;
676-    char **argv2;
677
678     /* TODO: support for rrdcached */
679     if (argc != 2) {
680@@ -463,9 +440,7 @@ static int Rrd_Info(
681         return TCL_ERROR;
682     }
683
684-    argv2 = getopt_init(argc, argv);
685-
686-    data = rrd_info_r(argv2[1]);
687+    data = rrd_info_r(argv[1]);
688
689     if (data) {
690 	Tcl_SetObjResult(interp, convert_info(data));
691@@ -477,7 +452,6 @@ static int Rrd_Info(
692 	status = TCL_ERROR;
693     }
694
695-    getopt_cleanup(argc, argv2);
696     return status;
697 }
698
699@@ -488,7 +462,6 @@ static int Rrd_Lastupdate(
700     CONST84 char *argv[])
701 {
702     time_t    last_update;
703-    char    **argv2;
704     char    **ds_namv;
705     char    **last_ds;
706     char      s[30];
707@@ -502,8 +475,7 @@ static int Rrd_Lastupdate(
708         return TCL_ERROR;
709     }
710
711-    argv2 = getopt_init(argc, argv);
712-    if (rrd_lastupdate_r(argv2[1], &last_update,
713+    if (rrd_lastupdate_r(argv[1], &last_update,
714                        &ds_cnt, &ds_namv, &last_ds) == 0) {
715         listPtr = Tcl_GetObjResult(interp);
716         for (i = 0; i < ds_cnt; i++) {
717@@ -527,7 +499,6 @@ static int Rrd_Lastupdate(
718             free(ds_namv);
719         }
720     }
721-    getopt_cleanup(argc, argv2);
722     return TCL_OK;
723 }
724
725@@ -543,10 +514,8 @@ static int Rrd_Fetch(
726     char    **ds_namv;
727     Tcl_Obj  *listPtr;
728     char      s[30];
729-    char    **argv2;
730
731-    argv2 = getopt_init(argc, argv);
732-    if (rrd_fetch(argc, argv2, &start, &end, &step,
733+    if (rrd_fetch(argc, argv, &start, &end, &step,
734                   &ds_cnt, &ds_namv, &data) != -1) {
735         datai = data;
736         listPtr = Tcl_GetObjResult(interp);
737@@ -562,7 +531,6 @@ static int Rrd_Fetch(
738         free(ds_namv);
739         free(data);
740     }
741-    getopt_cleanup(argc, argv2);
742
743     if (rrd_test_error()) {
744         Tcl_AppendResult(interp, "RRD Error: ",
745@@ -590,7 +558,7 @@ static int Rrd_Graph(
746     int       rc, xsize, ysize;
747     double    ymin, ymax;
748     char      dimensions[50];
749-    char    **argv2;
750+    const char    **argv2;
751     CONST84 char *save;
752
753     /*
754@@ -692,11 +660,7 @@ static int Rrd_Tune(
755     int argc,
756     CONST84 char *argv[])
757 {
758-    char    **argv2;
759-
760-    argv2 = getopt_init(argc, argv);
761-    rrd_tune(argc, argv2);
762-    getopt_cleanup(argc, argv2);
763+    rrd_tune(argc, argv);
764
765     if (rrd_test_error()) {
766         Tcl_AppendResult(interp, "RRD Error: ",
767@@ -716,11 +680,7 @@ static int Rrd_Resize(
768     int argc,
769     CONST84 char *argv[])
770 {
771-    char    **argv2;
772-
773-    argv2 = getopt_init(argc, argv);
774-    rrd_resize(argc, argv2);
775-    getopt_cleanup(argc, argv2);
776+    rrd_resize(argc, argv);
777
778     if (rrd_test_error()) {
779         Tcl_AppendResult(interp, "RRD Error: ",
780@@ -740,11 +700,7 @@ static int Rrd_Restore(
781     int argc,
782     CONST84 char *argv[])
783 {
784-    char    **argv2;
785-
786-    argv2 = getopt_init(argc, argv);
787-    rrd_restore(argc, argv2);
788-    getopt_cleanup(argc, argv2);
789+    rrd_restore(argc, argv);
790
791     if (rrd_test_error()) {
792         Tcl_AppendResult(interp, "RRD Error: ",
793diff --git a/src/optparse.c b/src/optparse.c
794index 9040ba8b2..79a3efe11 100644
795--- a/src/optparse.c
796+++ b/src/optparse.c
797@@ -10,7 +10,7 @@
798 #define options_argv(i) \
799     ((i) < options->argc ? options->argv[i] : NULL)
800
801-void optparse_init(struct optparse *options, int argc, char **argv)
802+void optparse_init(struct optparse *options, int argc, const char **argv)
803 {
804     options->argv = argv;
805     options->argc = argc;
806@@ -42,7 +42,7 @@ is_longopt(const char *arg)
807 static void
808 permute(struct optparse *options, int index)
809 {
810-    char *nonoption = options->argv[index];
811+    const char *nonoption = options->argv[index];
812     for (int i = index; i < options->optind - 1; i++)
813         options->argv[i] = options->argv[i + 1];
814     options->argv[options->optind - 1] = nonoption;
815@@ -67,7 +67,7 @@ int optparse(struct optparse *options, const char *optstring)
816     options->errmsg[0] = '\0';
817     options->optopt = 0;
818     options->optarg = NULL;
819-    char *option = options_argv(options->optind);
820+    const char *option = options_argv(options->optind);
821     if (option == NULL) {
822         return -1;
823     } else if (is_dashdash(option)) {
824@@ -88,7 +88,7 @@ int optparse(struct optparse *options, const char *optstring)
825     option += options->subopt + 1;
826     options->optopt = option[0];
827     int type = argtype(optstring, option[0]);
828-    char *next = options_argv(options->optind + 1);
829+    const char *next = options_argv(options->optind + 1);
830     switch (type) {
831     case -1:
832         opterror(options, "invalid option -- '%c'", option[0]);
833@@ -128,10 +128,10 @@ int optparse(struct optparse *options, const char *optstring)
834     return 0;
835 }
836
837-char *optparse_arg(struct optparse *options)
838+const char *optparse_arg(struct optparse *options)
839 {
840     options->subopt = 0;
841-    char *option = options->argv[options->optind];
842+    const char *option = options->argv[options->optind];
843     if (option != NULL)
844         options->optind++;
845     return option;
846@@ -222,7 +222,7 @@ optparse_long(struct optparse *options,
847               int *longindex)
848 {
849 //    printf("%i < %i\n",options->optind,options->argc);
850-    char *option = options_argv(options->optind);
851+    const char *option = options_argv(options->optind);
852     if (option == NULL) {
853         return -1;
854     } else if (is_dashdash(option)) {
855diff --git a/src/optparse.h b/src/optparse.h
856index c4b0ec19c..7a0bb3885 100644
857--- a/src/optparse.h
858+++ b/src/optparse.h
859@@ -44,7 +44,7 @@
860  */
861
862 struct optparse {
863-    char **argv;
864+    const char **argv;
865     int argc;
866     int permute;
867     int optind;
868@@ -65,7 +65,7 @@ struct optparse_long {
869 /**
870  * Initializes the parser state.
871  */
872-void optparse_init(struct optparse *options, int argc, char **argv);
873+void optparse_init(struct optparse *options, int argc, const char **argv);
874
875 /**
876  * Read the next option in the argv array.
877@@ -98,6 +98,6 @@ optparse_long(struct optparse *options,
878  * subcommand returned by optparse_arg(). This function allows you to
879  * ignore the value of optind.
880  */
881-char *optparse_arg(struct optparse *options);
882+const char *optparse_arg(struct optparse *options);
883
884 #endif
885diff --git a/src/rrd.h b/src/rrd.h
886index 184887ccc..b40f9a449 100644
887--- a/src/rrd.h
888+++ b/src/rrd.h
889@@ -155,10 +155,10 @@ extern    "C" {
890 /* main function blocks */
891     int       rrd_create(
892     int,
893-    char **);
894+    const char **);
895     rrd_info_t *rrd_info(
896     int,
897-    char **);
898+    const char **);
899     rrd_info_t *rrd_info_push(
900     rrd_info_t *,
901     char *,
902@@ -170,19 +170,19 @@ extern    "C" {
903     rrd_info_t *);
904     char     *rrd_list(
905     int,
906-    char **);
907+    const char **);
908     char     *rrd_list_r(
909     int,
910-    char *dirname);
911+    const char *dirname);
912     int       rrd_update(
913     int,
914-    char **);
915+    const char **);
916     rrd_info_t *rrd_update_v(
917     int,
918-    char **);
919+    const char **);
920     int       rrd_graph(
921     int,
922-    char **,
923+    const char **,
924     char ***,
925     int *,
926     int *,
927@@ -191,11 +191,11 @@ extern    "C" {
928     double *);
929     rrd_info_t *rrd_graph_v(
930     int,
931-    char **);
932+    const char **);
933
934     int       rrd_fetch(
935     int,
936-    char **,
937+    const char **,
938     time_t *,
939     time_t *,
940     unsigned long *,
941@@ -204,32 +204,32 @@ extern    "C" {
942     rrd_value_t **);
943     int       rrd_restore(
944     int,
945-    char **);
946+    const char **);
947     int       rrd_dump(
948     int,
949-    char **);
950+    const char **);
951     int       rrd_tune(
952     int,
953-    char **);
954+    const char **);
955     time_t    rrd_last(
956     int,
957-    char **);
958+    const char **);
959     int       rrd_lastupdate(
960     int argc,
961-    char **argv);
962+    const char **argv);
963     time_t    rrd_first(
964     int,
965-    char **);
966+    const char **);
967     int       rrd_resize(
968     int,
969-    char **);
970+    const char **);
971     char     *rrd_strversion(
972     void);
973     double    rrd_version(
974     void);
975     int       rrd_xport(
976     int,
977-    char **,
978+    const char **,
979     int *,
980     time_t *,
981     time_t *,
982@@ -239,7 +239,7 @@ extern    "C" {
983     rrd_value_t **);
984     int       rrd_flushcached(
985     int argc,
986-    char **argv);
987+    const char **argv);
988
989     void      rrd_freemem(
990     void *mem);
991@@ -323,7 +323,7 @@ extern    "C" {
992     const char **argv);
993     int       rrd_dump_opt_r(
994     const char *filename,
995-    char *outname,
996+    const char *outname,
997     int opt_noheader);
998     int       rrd_dump_r(
999     const char *filename,
1000diff --git a/src/rrd_cgi.c b/src/rrd_cgi.c
1001index b82c310db..14a4f511a 100644
1002--- a/src/rrd_cgi.c
1003+++ b/src/rrd_cgi.c
1004@@ -102,7 +102,7 @@ static char *rrdstrip(
1005 static char *scanargs(
1006     char *line,
1007     int *argc,
1008-    char ***args);
1009+    const char ***args);
1010
1011 /* format at-time specified times using strftime */
1012 static char *printstrftime(
1013@@ -317,7 +317,7 @@ static const char *putvar(
1014 }
1015
1016 /* expand those RRD:* directives that can be used recursively */
1017-static char *rrd_expand_vars(
1018+static const char *rrd_expand_vars(
1019     char *buffer)
1020 {
1021     int       i;
1022@@ -434,7 +434,7 @@ static int readfile(
1023
1024 int main(
1025     int argc,
1026-    char *argv[])
1027+    const char *argv[])
1028 {
1029     char     *buffer;
1030     long      i;
1031@@ -926,7 +926,7 @@ static char *drawgraph(
1032     }
1033     calfree();
1034     if (rrd_graph
1035-        (argc + 1, (char **) args - 1, &calcpr, &xsize, &ysize, NULL, &ymin,
1036+        (argc + 1, args - 1, &calcpr, &xsize, &ysize, NULL, &ymin,
1037          &ymax) != -1) {
1038         return stralloc(calcpr[0]);
1039     } else {
1040@@ -973,7 +973,7 @@ static char *printtimelast(
1041         /* not raising argc in step with args - 1 since the last argument
1042            will be used below for strftime  */
1043
1044-        last = rrd_last(argc, (char **) args - 1);
1045+        last = rrd_last(argc, args - 1);
1046         if (rrd_test_error()) {
1047             char      err[4096];
1048
1049@@ -1027,7 +1027,7 @@ static char *printtimenow(
1050 static char *scanargs(
1051     char *line,
1052     int *argument_count,
1053-    char ***arguments)
1054+    const char ***arguments)
1055 {
1056     char     *getP;     /* read cursor */
1057     char     *putP;     /* write cursor */
1058@@ -1039,8 +1039,8 @@ static char *scanargs(
1059
1060     /* local array of arguments while parsing */
1061     int       argc = 1;
1062-    char    **argv;
1063-    char    **argv_tmp; /* temp variable for realloc() */
1064+    const char    **argv;
1065+    const char    **argv_tmp; /* temp variable for realloc() */
1066
1067 #ifdef DEBUG_PARSER
1068     printf("<-- scanargs(%s) -->\n", line);
1069@@ -1051,7 +1051,7 @@ static char *scanargs(
1070
1071     /* create initial argument array of char pointers */
1072     argsz = 32;
1073-    argv = (char **) malloc(argsz * sizeof(char *));
1074+    argv = malloc(argsz * sizeof(char *));
1075     if (!argv) {
1076         return NULL;
1077     }
1078@@ -1146,7 +1146,7 @@ static char *scanargs(
1079         if (argc == argsz - 2) {
1080             /* resize argument array */
1081             argsz *= 2;
1082-            argv_tmp = (char **) rrd_realloc(argv, argsz * sizeof(char *));
1083+            argv_tmp = rrd_realloc(argv, argsz * sizeof(char *));
1084             if (*argv_tmp == NULL) {
1085                 return NULL;
1086             }
1087@@ -1213,7 +1213,7 @@ static int parse(
1088     /* the name of the vairable ... */
1089     char     *val;
1090     long      valln;
1091-    char    **args;
1092+    const char    **args;
1093     char     *end;
1094     long      end_offset;
1095     int       argc;
1096@@ -1264,7 +1264,7 @@ static int parse(
1097         /* make sure we do not shrink the mallocd block */
1098         size_t    newbufsize = i + strlen(end) + valln + 1;
1099
1100-        *buf = (char *) rrd_realloc(*buf, newbufsize);
1101+        *buf = rrd_realloc(*buf, newbufsize);
1102
1103         if (*buf == NULL) {
1104             perror("Realoc buf:");
1105diff --git a/src/rrd_create.c b/src/rrd_create.c
1106index f9bad0866..919b4195a 100644
1107--- a/src/rrd_create.c
1108+++ b/src/rrd_create.c
1109@@ -76,7 +76,7 @@ static void parseGENERIC_DS(
1110
1111 int rrd_create(
1112     int argc,
1113-    char **argv)
1114+    const char **argv)
1115 {
1116     struct optparse_long longopts[] = {
1117         {"start", 'b', OPTPARSE_REQUIRED},
1118diff --git a/src/rrd_daemon.c b/src/rrd_daemon.c
1119index 751798aa1..21c38a11d 100644
1120--- a/src/rrd_daemon.c
1121+++ b/src/rrd_daemon.c
1122@@ -1877,7 +1877,7 @@ static int handle_request_tune(
1123     HANDLER_PROTO)
1124 {                       /* {{{ */
1125     int       status;
1126-    char**    argv = NULL;
1127+    const char**    argv = NULL;
1128     int       argc, argc_tmp;
1129     char*     i;
1130     int       rc;
1131@@ -1916,7 +1916,7 @@ static int handle_request_tune(
1132         goto done;
1133     }
1134
1135-    if ((argv = (char **) malloc(argc * sizeof(char*))) == NULL) {
1136+    if ((argv = malloc(argc * sizeof(char*))) == NULL) {
1137         rc = send_response(sock, RESP_ERR, "%s\n", rrd_strerror(ENOMEM));
1138         goto done;
1139     }
1140@@ -1927,7 +1927,7 @@ static int handle_request_tune(
1141         argc_tmp += 1;
1142     }
1143
1144-    status = rrd_tune_r(file, argc, (const char **)argv);
1145+    status = rrd_tune_r(file, argc, argv);
1146     if (status != 0) {
1147         rc = send_response(sock, RESP_ERR, "Got error %s\n", rrd_get_error());
1148         goto done;
1149@@ -1935,7 +1935,7 @@ static int handle_request_tune(
1150     rc = send_response(sock, RESP_OK, "Success\n");
1151     done:
1152     free(file);
1153-    free(argv);
1154+    free((void *)argv);
1155     return rc;
1156 }
1157
1158@@ -4505,7 +4505,7 @@ static int cleanup(
1159
1160 static int read_options(
1161     int argc,
1162-    char **argv)
1163+    const char **argv)
1164 {                       /* {{{ */
1165     struct optparse_long longopts[] = {
1166         {NULL, 'a', OPTPARSE_REQUIRED},
1167@@ -5050,7 +5050,7 @@ static int read_options(
1168
1169 int main(
1170     int argc,
1171-    char **argv)
1172+    const char **argv)
1173 {
1174     int       status;
1175
1176diff --git a/src/rrd_dump.c b/src/rrd_dump.c
1177index a4490d594..c58e0ee4a 100644
1178--- a/src/rrd_dump.c
1179+++ b/src/rrd_dump.c
1180@@ -497,7 +497,7 @@ static size_t rrd_dump_opt_cb_fileout(
1181
1182 int rrd_dump_opt_r(
1183     const char *filename,
1184-    char *outname,
1185+    const char *outname,
1186     int opt_noheader)
1187 {
1188     FILE     *out_file;
1189@@ -543,7 +543,7 @@ int rrd_dump_r(
1190
1191 int rrd_dump(
1192     int argc,
1193-    char **argv)
1194+    const char **argv)
1195 {
1196     int       opt;
1197     struct optparse_long longopts[] = {
1198diff --git a/src/rrd_fetch.c b/src/rrd_fetch.c
1199index c739bfc45..54780f19b 100644
1200--- a/src/rrd_fetch.c
1201+++ b/src/rrd_fetch.c
1202@@ -61,7 +61,7 @@
1203
1204 int rrd_fetch(
1205     int argc,
1206-    char **argv,
1207+    const char **argv,
1208     time_t *start,
1209     time_t *end,        /* which time frame do you want ?
1210                          * will be changed to represent reality */
1211diff --git a/src/rrd_first.c b/src/rrd_first.c
1212index a696c5c38..f3dde5404 100644
1213--- a/src/rrd_first.c
1214+++ b/src/rrd_first.c
1215@@ -13,7 +13,7 @@
1216
1217 time_t rrd_first(
1218     int argc,
1219-    char **argv)
1220+    const char **argv)
1221 {
1222     struct optparse_long longopts[] = {
1223         {"rraindex", 129, OPTPARSE_REQUIRED},
1224diff --git a/src/rrd_flushcached.c b/src/rrd_flushcached.c
1225index 090bca749..3bf6cd29d 100644
1226--- a/src/rrd_flushcached.c
1227+++ b/src/rrd_flushcached.c
1228@@ -22,7 +22,7 @@
1229 #include "rrd_tool.h"
1230 #include "rrd_client.h"
1231
1232-int rrd_flushcached (int argc, char **argv)
1233+int rrd_flushcached (int argc, const char **argv)
1234 {
1235     struct optparse_long longopts[] = {
1236         {"daemon", 'd', OPTPARSE_REQUIRED},
1237diff --git a/src/rrd_graph.c b/src/rrd_graph.c
1238index b32d45085..46511e9a3 100644
1239--- a/src/rrd_graph.c
1240+++ b/src/rrd_graph.c
1241@@ -4607,7 +4607,7 @@ int scan_for_col(
1242 /* Now just a wrapper around rrd_graph_v */
1243 int rrd_graph(
1244     int argc,
1245-    char **argv,
1246+    const char **argv,
1247     char ***prdata,
1248     int *xsize,
1249     int *ysize,
1250@@ -4690,7 +4690,7 @@ int rrd_graph(
1251
1252 rrd_info_t *rrd_graph_v(
1253     int argc,
1254-    char **argv)
1255+    const char **argv)
1256 {
1257     image_desc_t im;
1258     rrd_info_t *grinfo;
1259@@ -4953,7 +4953,7 @@ void rrd_graph_init(
1260
1261 void rrd_graph_options(
1262     int argc,
1263-    char *argv[],
1264+    const char **argv,
1265     struct optparse *poptions,
1266     image_desc_t *im)
1267 {
1268diff --git a/src/rrd_graph.h b/src/rrd_graph.h
1269index 4df32ec66..083cf3800 100644
1270--- a/src/rrd_graph.h
1271+++ b/src/rrd_graph.h
1272@@ -473,12 +473,12 @@ void      time_clean(
1273
1274 void      rrd_graph_options(
1275     int,
1276-    char **,
1277+    const char **,
1278     struct optparse *,
1279     image_desc_t *);
1280 void      rrd_graph_script(
1281     int,
1282-    char **,
1283+    const char **,
1284     image_desc_t *const,
1285     int);
1286 int       rrd_graph_color(
1287diff --git a/src/rrd_graph_helper.c b/src/rrd_graph_helper.c
1288index 99cdefa65..ba90e1a6c 100644
1289--- a/src/rrd_graph_helper.c
1290+++ b/src/rrd_graph_helper.c
1291@@ -1952,7 +1952,7 @@ static int parse_xport(
1292
1293 void rrd_graph_script(
1294     int argc,
1295-    char *argv[],
1296+    const char **argv,
1297     image_desc_t *const im,
1298     int optno)
1299 {
1300diff --git a/src/rrd_info.c b/src/rrd_info.c
1301index c0c6f68c7..eb0d4e4de 100644
1302--- a/src/rrd_info.c
1303+++ b/src/rrd_info.c
1304@@ -82,7 +82,7 @@ rrd_info_t
1305
1306 rrd_info_t *rrd_info(
1307     int argc,
1308-    char **argv)
1309+    const char **argv)
1310 {
1311     struct optparse_long longopts[] = {
1312         {"daemon", 'd', OPTPARSE_REQUIRED},
1313diff --git a/src/rrd_last.c b/src/rrd_last.c
1314index 026a1e828..1aae72512 100644
1315--- a/src/rrd_last.c
1316+++ b/src/rrd_last.c
1317@@ -11,7 +11,7 @@
1318
1319 time_t rrd_last(
1320     int argc,
1321-    char **argv)
1322+    const char **argv)
1323 {
1324     char *opt_daemon = NULL;
1325     time_t lastupdate;
1326diff --git a/src/rrd_lastupdate.c b/src/rrd_lastupdate.c
1327index ab30dcf67..4f7f4770e 100644
1328--- a/src/rrd_lastupdate.c
1329+++ b/src/rrd_lastupdate.c
1330@@ -14,7 +14,7 @@
1331 #include "rrd_client.h"
1332 #include <stdarg.h>
1333
1334-int rrd_lastupdate (int argc, char **argv)
1335+int rrd_lastupdate (int argc, const char **argv)
1336 {
1337     struct optparse_long longopts[] = {
1338         {"daemon", 'd', OPTPARSE_REQUIRED},
1339diff --git a/src/rrd_list.c b/src/rrd_list.c
1340index e743b9b7d..6e96220ea 100644
1341--- a/src/rrd_list.c
1342+++ b/src/rrd_list.c
1343@@ -37,7 +37,7 @@ static char *move_past_prefix(const char *prefix, const char *string)
1344 	return (char *)&(string[index]);
1345 }
1346
1347-static char *rrd_list_rec(int recursive, char *root, char *dirname)
1348+static char *rrd_list_rec(int recursive, const char *root, const char *dirname)
1349 {
1350 #define SANE_ASPRINTF2(_dest_str, _format, ...)				\
1351 	if (asprintf(&_dest_str, _format, __VA_ARGS__) == -1) {		\
1352@@ -138,7 +138,7 @@ static char *rrd_list_rec(int recursive, char *root, char *dirname)
1353 	return out;
1354 }
1355
1356-char *rrd_list_r(int recursive, char *dirname)
1357+char *rrd_list_r(int recursive, const char *dirname)
1358 {
1359 #define SANE_ASPRINTF(_dest_str, _format, ...)				\
1360 	if (asprintf(&_dest_str, _format, __VA_ARGS__) == -1) {		\
1361@@ -240,7 +240,7 @@ char *rrd_list_r(int recursive, char *dirname)
1362 	return rrd_list_rec(recursive, dirname, dirname);
1363 }
1364
1365-char *rrd_list(int argc, char **argv)
1366+char *rrd_list(int argc, const char **argv)
1367 {
1368 	char *opt_daemon = NULL;
1369 	int status;
1370diff --git a/src/rrd_modify.c b/src/rrd_modify.c
1371index a2b07f640..70ac9e77f 100644
1372--- a/src/rrd_modify.c
1373+++ b/src/rrd_modify.c
1374@@ -1297,7 +1297,7 @@ static int add_rras(const rrd_t *in, rrd_t *out, const int *ds_map,
1375 }
1376
1377 int handle_modify(const rrd_t *in, const char *outfilename,
1378-		  int argc, char **argv, int optidx,
1379+		  int argc, const char **argv, int optidx,
1380 		  int newstep) {
1381     // parse add/remove options
1382     int rc = -1;
1383diff --git a/src/rrd_modify.h b/src/rrd_modify.h
1384index 52d8789be..64a39926e 100644
1385--- a/src/rrd_modify.h
1386+++ b/src/rrd_modify.h
1387@@ -28,7 +28,7 @@ typedef struct {
1388 } rra_mod_op_t;
1389
1390 int handle_modify(const rrd_t *in, const char *outfilename,
1391-		  int argc, char **argv, int optind,
1392+		  int argc, const char **argv, int optind,
1393 		  int newstep);
1394
1395 typedef union {
1396diff --git a/src/rrd_resize.c b/src/rrd_resize.c
1397index fb75d81ff..742e6d141 100644
1398--- a/src/rrd_resize.c
1399+++ b/src/rrd_resize.c
1400@@ -12,9 +12,9 @@
1401
1402 int rrd_resize(
1403     int argc,
1404-    char **argv)
1405+    const char **argv)
1406 {
1407-    char     *infilename, outfilename[11] = "resize.rrd";
1408+    const char     *infilename, outfilename[11] = "resize.rrd";
1409     rrd_t     rrdold, rrdnew;
1410     rrd_value_t buffer;
1411     int       version;
1412diff --git a/src/rrd_restore.c b/src/rrd_restore.c
1413index 85d481e0c..ebef5efe8 100644
1414--- a/src/rrd_restore.c
1415+++ b/src/rrd_restore.c
1416@@ -1378,7 +1378,7 @@ int write_file(
1417
1418 int rrd_restore(
1419     int argc,
1420-    char **argv)
1421+    const char **argv)
1422 {
1423     struct optparse_long longopts[] = {
1424         {"range-check", 'r', OPTPARSE_NONE},
1425diff --git a/src/rrd_tool.c b/src/rrd_tool.c
1426index cc6119d9a..56321ee1a 100644
1427--- a/src/rrd_tool.c
1428+++ b/src/rrd_tool.c
1429@@ -22,16 +22,16 @@
1430
1431
1432 static void PrintUsage(
1433-    char *cmd);
1434+    const char *cmd);
1435 static int CountArgs(
1436     char *aLine);
1437 static int CreateArgs(
1438+    const char *,
1439     char *,
1440-    char *,
1441-    char **);
1442+    const char **);
1443 static int HandleInputLine(
1444     int,
1445-    char **,
1446+    const char **,
1447     FILE *);
1448 int       RemoteMode = 0;
1449 int       ChangeRoot = 0;
1450@@ -42,7 +42,7 @@ int       ChangeRoot = 0;
1451
1452
1453 static void PrintUsage(
1454-    char *cmd)
1455+    const char *cmd)
1456 {
1457
1458     const char *help_main =
1459@@ -443,11 +443,11 @@ static char *fgetslong(
1460
1461 int main(
1462     int argc,
1463-    char *argv[])
1464+    const char *argv[])
1465 {
1466-    char    **myargv;
1467+    const char    **myargv;
1468     char     *aLine;
1469-    char     *firstdir = "";
1470+    const char     *firstdir = "";
1471
1472 #ifdef MUST_DISABLE_SIGFPE
1473     signal(SIGFPE, SIG_IGN);
1474@@ -526,7 +526,7 @@ int main(
1475                 printf("ERROR: not enough arguments\n");
1476                 continue;
1477             }
1478-            if ((myargv = (char **) malloc((argc + 1) *
1479+            if ((myargv = malloc((argc + 1) *
1480                                            sizeof(char *))) == NULL) {
1481                 perror("malloc");
1482                 exit(1);
1483@@ -572,7 +572,7 @@ int main(
1484    resolving them portably is not really simple. */
1485 static int HandleInputLine(
1486     int argc,
1487-    char **argv,
1488+    const char **argv,
1489     FILE * out)
1490 {
1491 #if defined(HAVE_OPENDIR) && defined (HAVE_READDIR)
1492@@ -887,12 +887,12 @@ static int CountArgs(
1493  * CreateArgs - take a string (aLine) and tokenize
1494  */
1495 static int CreateArgs(
1496-    char *pName,
1497+    const char *pName,
1498     char *aLine,
1499-    char **argv)
1500+    const char **argv)
1501 {
1502     char     *getP, *putP;
1503-    char    **pargv = argv;
1504+    const char    **pargv = argv;
1505     char      Quote = 0;
1506     int       inArg = 0;
1507     int       len;
1508diff --git a/src/rrd_tune.c b/src/rrd_tune.c
1509index 198817f37..dd3f3f7cb 100644
1510--- a/src/rrd_tune.c
1511+++ b/src/rrd_tune.c
1512@@ -71,7 +71,7 @@ static int set_hwsmootharg(
1513
1514 int rrd_tune(
1515     int argc,
1516-    char **argv)
1517+    const char **argv)
1518 {
1519     char      *opt_daemon = NULL;
1520     const char *in_filename = NULL;
1521diff --git a/src/rrd_update.c b/src/rrd_update.c
1522index fbbe2820a..bb9a0602c 100644
1523--- a/src/rrd_update.c
1524+++ b/src/rrd_update.c
1525@@ -299,7 +299,7 @@ static void initialize_time(
1526
1527 rrd_info_t *rrd_update_v(
1528     int argc,
1529-    char **argv)
1530+    const char **argv)
1531 {
1532     struct optparse_long longopts[] = {
1533         {"template",          't', OPTPARSE_REQUIRED},
1534@@ -674,7 +674,7 @@ static int rrd_template_update(const char *filename,  /* {{{ */
1535
1536 int rrd_update(
1537     int argc,
1538-    char **argv)
1539+    const char **argv)
1540 {
1541     struct optparse_long longopts[] = {
1542         {"template",          't', OPTPARSE_REQUIRED},
1543diff --git a/src/rrd_xport.c b/src/rrd_xport.c
1544index d15d33dd9..93c02f926 100644
1545--- a/src/rrd_xport.c
1546+++ b/src/rrd_xport.c
1547@@ -73,7 +73,7 @@ static int rrd_xport_format_addprints(
1548
1549 int rrd_xport(
1550     int argc,
1551-    char **argv,
1552+    const char **argv,
1553     int UNUSED(*xsize),
1554     time_t *start,
1555     time_t *end,        /* which time frame do you want ?
1556diff --git a/src/rrdupdate.c b/src/rrdupdate.c
1557index cbbf48cc1..e368516c8 100644
1558--- a/src/rrdupdate.c
1559+++ b/src/rrdupdate.c
1560@@ -20,19 +20,20 @@ int main(
1561     int argc,
1562     char **argv)
1563 {
1564+    const char **cargv = (const char **)argv;
1565     char *name=basename(argv[0]);
1566     rrd_info_t *info;
1567
1568     if (!strcmp(name, "rrdcreate")) {
1569-        rrd_create(argc, argv);
1570+        rrd_create(argc, cargv);
1571     }
1572     else if (!strcmp(name, "rrdinfo")) {
1573-         info=rrd_info(argc, argv);
1574+         info=rrd_info(argc, cargv);
1575          rrd_info_print(info);
1576          rrd_info_free(info);
1577     }
1578     else {
1579-        rrd_update(argc, argv);
1580+        rrd_update(argc, cargv);
1581     }
1582
1583     if (rrd_test_error()) {
1584