summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 38c3864)
raw | patch | inline | side by side (parent: 38c3864)
author | oetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa> | |
Sat, 12 Nov 2005 23:10:48 +0000 (23:10 +0000) | ||
committer | oetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa> | |
Sat, 12 Nov 2005 23:10:48 +0000 (23:10 +0000) |
required anymore ... -- D. Walsh <buildsmart at daleenterprise.com>
* check if we have to include malloc/malloc.h to make malloc work ... -- tobi
git-svn-id: svn://svn.oetiker.ch/rrdtool/branches/1.2/program@708 a5681a0c-68f1-0310-ab6d-d61299d08faa
* check if we have to include malloc/malloc.h to make malloc work ... -- tobi
git-svn-id: svn://svn.oetiker.ch/rrdtool/branches/1.2/program@708 a5681a0c-68f1-0310-ab6d-d61299d08faa
configure.ac | patch | blob | history | |
doc/rrdbuild.pod | patch | blob | history | |
src/Makefile.am | patch | blob | history | |
src/rrd_cgi.c | patch | blob | history |
diff --git a/configure.ac b/configure.ac
index e2d5c6af5f646870fd4263678095093dfab85d88..9f59bb70de160544e9c0d3a8a54b92abe53663c0 100644 (file)
--- a/configure.ac
+++ b/configure.ac
# define rrd_realloc(a,b) realloc((a), (b))
#endif
+#if NEED_MALLOC_MALLOC_H
+# include <malloc/malloc.h>
+#endif
+
#if HAVE_MATH_H
# include <math.h>
#endif
AC_FULL_IEEE
+AC_LANG_PUSH(C)
+dnl see if we have to include malloc/malloc.h
+AC_MSG_CHECKING([do we need malloc/malloc.h])
+AC_LINK_IFELSE(
+ AC_LANG_PROGRAM(
+ [[#include <stdlib.h>]],
+ [[malloc(1)]]
+ ),
+ [ AC_MSG_RESULT([nope, works out of the box]) ],
+ [ AC_LINK_IFELSE(
+ AC_LANG_PROGRAM(
+ [[#include <stdlib.h>
+ #include <malloc/malloc.h>]],
+ [[malloc(1)]]
+ ),
+ [AC_DEFINE(NEED_MALLOC_MALLOC_H)
+ AC_MSG_RESULT([yes we do])],
+ [AC_MSG_ERROR([Can't figure how to compile malloc])]
+ )
+ ]
+)
+AC_LANG_POP(C)
+
dnl How the vertical axis label is printed
AC_ARG_VAR(RRDGRAPH_YLEGEND_ANGLE,
[Vertical label angle: 90.0 (default) or 270.0])
EX_CHECK_ALL(png, png_access_version_number, png.h, libpng, 1.2.8, http://prdownloads.sourceforge.net/libpng/, "")
EX_CHECK_ALL(freetype, FT_Init_FreeType, ft2build.h, freetype2, 2.1.9, http://prdownloads.sourceforge.net/freetype/, /usr/include/freetype2)
-save_LIBS=${LIBS}
-save_CPPFLAGS=${CPPFLAGS}
-save_LDFLAGS=${LDFLAGS}
-
-if test $enable_rrdcgi != no; then
-EX_CHECK_ALL(cgi, cgiInit, cgi.h, cgilib, 0.5, http://www.infodrom.org/projects/cgilib, "")
-fi
-
-CGI_LIBS=${LIBS}
-CGI_CPPFLAGS=${CPPFLAGS}
-CGI_LDFLAGS=${LDFLAGS}
-
-AC_SUBST(CGI_LIBS)
-AC_SUBST(CGI_CPPFLAGS)
-AC_SUBST(CGI_LDFLAGS)
-
-LIBS=${save_LIBS}
-CPPFLAGS=${save_CPPFLAGS}
-LDFLAGS=${save_LDFLAGS}
-
if test "$EX_CHECK_ALL_ERR" = "YES"; then
AC_MSG_ERROR([Please fix the library issues listed above and try again.])
fi
diff --git a/doc/rrdbuild.pod b/doc/rrdbuild.pod
index 0c872beabf2bbd3c74ae246e96f258ad1878aeb6..b2dfba2e60f2d3929d0a28899526910298c06b27 100644 (file)
--- a/doc/rrdbuild.pod
+++ b/doc/rrdbuild.pod
=over
-=item Building cgilib
-
- cd $BUILD_DIR
- wget http://people.ee.ethz.ch/oetiker/webtools/rrdtool/pub/libs/cgilib-0.5.tar.gz
- tar zxf cgilib-0.5.tar.gz
- cd cgilib-0.5
-
-If you are on Mac OSX you want to fix a little header problem here by doing
-
- touch malloc.h
-
-and now you are ready to build
-
- make CC=gcc CFLAGS="-O3 -fPIC -I."
- mkdir -p $BUILD_DIR/lb/include
- cp *.h $BUILD_DIR/lb/include
- mkdir -p $BUILD_DIR/lb/lib
- cp libcgi* $BUILD_DIR/lb/lib
-
=item Building zlib
cd $BUILD_DIR
ranlib $BUILD_DIR/lb/lib/*.a
-Note for OpenBSD users: It seems that libcgi fails to build properly on some
-of these systems. Run F<ar rc libcgi.a cgi.o cookies.o> to get a propper
-library if you find that libcgi.a is only a few bytes in size.
-
This time you tell configure where it should be looking for libraries and
include files. This is done via environment variables. Depending on the
shell you are running, the syntax for setting environment variables is
diff --git a/src/Makefile.am b/src/Makefile.am
index 6bee6b71b0109a24128c4e1a60e83a814d6ac075..d029600014807b035b51263a100efc4498b0170d 100644 (file)
--- a/src/Makefile.am
+++ b/src/Makefile.am
fontsdir = $(datadir)/rrdtool/fonts
fonts_DATA = DejaVuSansMono-Roman.ttf
-#INCLUDES = $(CGI_INCLUDES) $(FREETYPE_INCLUDES) $(ART_INCLUDES) \
+#INCLUDES = $(FREETYPE_INCLUDES) $(ART_INCLUDES) \
# $(PNG_INCLUDES) $(ZLIB_INCLUDES)
RRD_DEFAULT_FONT=@RRD_DEFAULT_FONT@
AM_CPPFLAGS = -DRRD_DEFAULT_FONT=\"$(RRD_DEFAULT_FONT)\" -DNUMVERS=@NUMVERS@
#librrd_private_la_LDFLAGS = -static
bin_PROGRAMS = rrdtool rrdupdate
+
if BUILD_RRDCGI
bin_PROGRAMS += rrdcgi
endif
rrdcgi_SOURCES = rrd_cgi.c
rrdcgi_LDADD = librrd.la
-rrdcgi_CPPFLAGS = $(AM_CPPFLAGS) @CGI_CPPFLAGS@
-rrdcgi_LDFLAGS = @CGI_LDFLAGS@ @CGI_LIBS@
rrdupdate_SOURCES =
rrdupdate_LDADD = rrdupdate.o librrd.la
diff --git a/src/rrd_cgi.c b/src/rrd_cgi.c
index 2daa5a5f13ad1f9b3ecd39b393001d6c3a5eeb42..17a6b16b97f64919957f0221cbcc6ce9b3fee094 100644 (file)
--- a/src/rrd_cgi.c
+++ b/src/rrd_cgi.c
*****************************************************************************/
#include "rrd_tool.h"
-#include <cgi.h>
-#include <time.h>
#define MEMBLK 1024
/*#define DEBUG_PARSER
#define DEBUG_VARS*/
-/* global variable for libcgi */
-s_cgi *cgiArg;
+typedef struct var_s {
+ char *name, *value;
+} s_var;
+
+typedef struct cgi_s {
+ s_var **vars;
+} s_cgi;
/* in arg[0] find tags beginning with arg[1] call arg[2] on them
and replace by result of arg[2] call */
/* return a pointer to newly allocated copy of this string */
char *stralloc(const char *);
+/* global variable for rrdcgi */
+s_cgi *rrdcgiArg;
+
+/* rrdcgiHeader
+ *
+ * Prints a valid CGI Header (Content-type...) etc.
+ */
+void rrdcgiHeader(void);
+
+/* rrdcgiDecodeString
+ * decode html escapes
+ */
+
+char *rrdcgiDecodeString(char *text);
+
+/* rrdcgiDebug
+ *
+ * Set/unsets debugging
+ */
+void rrdcgiDebug(int level, int where);
+
+/* rrdcgiInit
+ *
+ * Reads in variables set via POST or stdin.
+ */
+s_cgi *rrdcgiInit (void);
+
+/* rrdcgiGetValue
+ *
+ * Returns the value of the specified variable or NULL if it's empty
+ * or doesn't exist.
+ */
+char *rrdcgiGetValue (s_cgi *parms, const char *name);
+
+/* rrdcgiFreeList
+ *
+ * Frees a list as returned by rrdcgiGetVariables()
+ */
+void rrdcgiFreeList (char **list);
+
+/* rrdcgiFree
+ *
+ * Frees the internal data structures
+ */
+void rrdcgiFree (s_cgi *parms);
+
+/* rrdcgiReadVariables()
+ *
+ * Read from stdin if no string is provided via CGI. Variables that
+ * doesn't have a value associated with it doesn't get stored.
+ */
+s_var **rrdcgiReadVariables(void);
+
+
+int rrdcgiDebugLevel = 0;
+int rrdcgiDebugStderr = 1;
+char *rrdcgiHeaderString = NULL;
+char *rrdcgiType = NULL;
/* rrd interface to the variable functions {put,get}var() */
char* rrdgetvar(long argc, const char **args);
}
if (!filter) {
- cgiDebug(0,0);
- cgiArg = cgiInit();
+ rrdcgiDebug(0,0);
+ rrdcgiArg = rrdcgiInit();
server_url = getenv("SERVER_URL");
}
char* cgigetq(long argc, const char **args){
if (argc>= 1){
- char *buf = rrdstrip(cgiGetValue(cgiArg,args[0]));
+ char *buf = rrdstrip(rrdcgiGetValue(rrdcgiArg,args[0]));
char *buf2;
char *c,*d;
int qc=0;
return stralloc("[ERROR: not enough arguments for RRD::CV::PATH]");
}
- buf = rrdstrip(cgiGetValue(cgiArg, args[0]));
+ buf = rrdstrip(rrdcgiGetValue(rrdcgiArg, args[0]));
if (!buf)
{
return NULL;
char* cgiget(long argc, const char **args){
if (argc>= 1)
- return rrdstrip(cgiGetValue(cgiArg,args[0]));
+ return rrdstrip(rrdcgiGetValue(rrdcgiArg,args[0]));
else
return stralloc("[ERROR: not enough arguments for RRD::CV]");
}
strftime(buf,sizeof(buf),"%a, %d %b %Y %H:%M:%S GMT",tmptime);
return(buf);
}
+
+void rrdcgiHeader(void)
+{
+ if (rrdcgiType)
+ printf ("Content-type: %s\n", rrdcgiType);
+ else
+ printf ("Content-type: text/html\n");
+ if (rrdcgiHeaderString)
+ printf ("%s", rrdcgiHeaderString);
+ printf ("\n");
+}
+
+void rrdcgiDebug(int level, int where)
+{
+ if (level > 0)
+ rrdcgiDebugLevel = level;
+ else
+ rrdcgiDebugLevel = 0;
+ if (where)
+ rrdcgiDebugStderr = 0;
+ else
+ rrdcgiDebugStderr = 1;
+}
+
+char *rrdcgiDecodeString(char *text)
+{
+ char *cp, *xp;
+
+ for (cp=text,xp=text; *cp; cp++) {
+ if (*cp == '%') {
+ if (strchr("0123456789ABCDEFabcdef", *(cp+1))
+ && strchr("0123456789ABCDEFabcdef", *(cp+2))) {
+ if (islower(*(cp+1)))
+ *(cp+1) = toupper(*(cp+1));
+ if (islower(*(cp+2)))
+ *(cp+2) = toupper(*(cp+2));
+ *(xp) = (*(cp+1) >= 'A' ? *(cp+1) - 'A' + 10 : *(cp+1) - '0' ) * 16
+ + (*(cp+2) >= 'A' ? *(cp+2) - 'A' + 10 : *(cp+2) - '0');
+ xp++;cp+=2;
+ }
+ } else {
+ *(xp++) = *cp;
+ }
+ }
+ memset(xp, 0, cp-xp);
+ return text;
+}
+
+/* rrdcgiReadVariables()
+ *
+ * Read from stdin if no string is provided via CGI. Variables that
+ * doesn't have a value associated with it doesn't get stored.
+ */
+s_var **rrdcgiReadVariables(void)
+{
+ int length;
+ char *line = NULL;
+ int numargs;
+ char *cp, *ip, *esp, *sptr;
+ s_var **result;
+ int i, k, len;
+ char tmp[101];
+
+ cp = getenv("REQUEST_METHOD");
+ ip = getenv("CONTENT_LENGTH");
+
+ if (cp && !strcmp(cp, "POST")) {
+ if (ip) {
+ length = atoi(ip);
+ if ((line = (char *)malloc (length+2)) == NULL)
+ return NULL;
+ fgets(line, length+1, stdin);
+ } else
+ return NULL;
+ } else if (cp && !strcmp(cp, "GET")) {
+ esp = getenv("QUERY_STRING");
+ if (esp && strlen(esp)) {
+ if ((line = (char *)malloc (strlen(esp)+2)) == NULL)
+ return NULL;
+ sprintf (line, "%s", esp);
+ } else
+ return NULL;
+ } else {
+ length = 0;
+ printf ("(offline mode: enter name=value pairs on standard input)\n");
+ memset (tmp, 0, sizeof(tmp));
+ while((cp = fgets (tmp, 100, stdin)) != NULL) {
+ if (strlen(tmp)) {
+ if (tmp[strlen(tmp)-1] == '\n')
+ tmp[strlen(tmp)-1] = '&';
+ if (length) {
+ length += strlen(tmp);
+ len = (length+1) * sizeof(char);
+ if ((line = (char *)realloc (line, len)) == NULL)
+ return NULL;
+ strcat (line, tmp);
+ } else {
+ length = strlen(tmp);
+ len = (length+1) * sizeof(char);
+ if ((line = (char *)malloc (len)) == NULL)
+ return NULL;
+ memset (line, 0, len);
+ strcpy (line, tmp);
+ }
+ }
+ memset (tmp, 0, sizeof(tmp));
+ }
+ if (!line)
+ return NULL;
+ if (line[strlen(line)-1] == '&')
+ line[strlen(line)-1] = '\0';
+ }
+
+ /*
+ * From now on all cgi variables are stored in the variable line
+ * and look like foo=bar&foobar=barfoo&foofoo=
+ */
+
+ if (rrdcgiDebugLevel > 0) {
+ if (rrdcgiDebugStderr)
+ fprintf (stderr, "Received cgi input: %s\n", line);
+ else
+ printf ("<b>Received cgi input</b><br>\n<pre>\n--\n%s\n--\n</pre>\n\n", line);
+ }
+
+ for (cp=line; *cp; cp++)
+ if (*cp == '+')
+ *cp = ' ';
+
+ if (strlen(line)) {
+ for (numargs=1,cp=line; *cp; cp++)
+ if (*cp == '&') numargs++;
+ } else
+ numargs = 0;
+ if (rrdcgiDebugLevel > 0) {
+ if (rrdcgiDebugStderr)
+ fprintf (stderr, "%d cgi variables found.\n", numargs);
+ else
+ printf ("%d cgi variables found.<br>\n", numargs);
+ }
+
+ len = (numargs+1) * sizeof(s_var *);
+ if ((result = (s_var **)malloc (len)) == NULL)
+ return NULL;
+ memset (result, 0, len);
+
+ cp = line;
+ i=0;
+ while (*cp) {
+ if ((ip = (char *)strchr(cp, '&')) != NULL) {
+ *ip = '\0';
+ }else
+ ip = cp + strlen(cp);
+
+ if ((esp=(char *)strchr(cp, '=')) == NULL) {
+ cp = ++ip;
+ continue;
+ }
+
+ if (!strlen(esp)) {
+ cp = ++ip;
+ continue;
+ }
+
+ if (i<numargs) {
+
+ /* try to find out if there's already such a variable */
+ for (k=0; k<i && (strncmp (result[k]->name,cp, esp-cp) || !(strlen (result[k]->name) == esp-cp)); k++);
+
+ if (k == i) { /* No such variable yet */
+ if ((result[i] = (s_var *)malloc(sizeof(s_var))) == NULL)
+ return NULL;
+ if ((result[i]->name = (char *)malloc((esp-cp+1) * sizeof(char))) == NULL)
+ return NULL;
+ memset (result[i]->name, 0, esp-cp+1);
+ strncpy(result[i]->name, cp, esp-cp);
+ cp = ++esp;
+ if ((result[i]->value = (char *)malloc((ip-esp+1) * sizeof(char))) == NULL)
+ return NULL;
+ memset (result[i]->value, 0, ip-esp+1);
+ strncpy(result[i]->value, cp, ip-esp);
+ result[i]->value = rrdcgiDecodeString(result[i]->value);
+ if (rrdcgiDebugLevel) {
+ if (rrdcgiDebugStderr)
+ fprintf (stderr, "%s: %s\n", result[i]->name, result[i]->value);
+ else
+ printf ("<h3>Variable %s</h3>\n<pre>\n%s\n</pre>\n\n", result[i]->name, result[i]->value);
+ }
+ i++;
+ } else { /* There is already such a name, suppose a mutiple field */
+ cp = ++esp;
+ len = (strlen(result[k]->value)+(ip-esp)+2) * sizeof (char);
+ if ((sptr = (char *)malloc(len)) == NULL)
+ return NULL;
+ memset (sptr, 0, len);
+ sprintf (sptr, "%s\n", result[k]->value);
+ strncat(sptr, cp, ip-esp);
+ free(result[k]->value);
+ result[k]->value = rrdcgiDecodeString (sptr);
+ }
+ }
+ cp = ++ip;
+ }
+ return result;
+}
+
+/* rrdcgiInit()
+ *
+ * Read from stdin if no string is provided via CGI. Variables that
+ * doesn't have a value associated with it doesn't get stored.
+ */
+s_cgi *rrdcgiInit(void)
+{
+ s_cgi *res;
+ s_var **vars;
+
+ vars = rrdcgiReadVariables();
+
+ if (!vars)
+ return NULL;
+
+ if ((res = (s_cgi *)malloc (sizeof (s_cgi))) == NULL)
+ return NULL;
+ res->vars = vars;
+
+ return res;
+}
+
+char *rrdcgiGetValue(s_cgi *parms, const char *name)
+{
+ int i;
+
+ if (!parms || !parms->vars)
+ return NULL;
+ for (i=0;parms->vars[i]; i++)
+ if (!strcmp(name,parms->vars[i]->name)) {
+ if (rrdcgiDebugLevel > 0) {
+ if (rrdcgiDebugStderr)
+ fprintf (stderr, "%s found as %s\n", name, parms->vars[i]->value);
+ else
+ printf ("%s found as %s<br>\n", name, parms->vars[i]->value);
+ }
+ return parms->vars[i]->value;
+ }
+ if (rrdcgiDebugLevel) {
+ if (rrdcgiDebugStderr)
+ fprintf (stderr, "%s not found\n", name);
+ else
+ printf ("%s not found<br>\n", name);
+ }
+ return NULL;
+}
+
+void rrdcgiFreeList (char **list)
+{
+ int i;
+
+ for (i=0; list[i] != NULL; i++)
+ free (list[i]);
+ free (list);
+}
+
+void rrdcgiFree (s_cgi *parms)
+{
+ int i;
+
+ if (!parms)
+ return;
+ if (parms->vars) {
+ for (i=0;parms->vars[i]; i++) {
+ if (parms->vars[i]->name)
+ free (parms->vars[i]->name);
+ if (parms->vars[i]->value)
+ free (parms->vars[i]->value);
+ free (parms->vars[i]);
+ }
+ free (parms->vars);
+ }
+ free (parms);
+
+ if (rrdcgiHeaderString) {
+ free (rrdcgiHeaderString);
+ rrdcgiHeaderString = NULL;
+ }
+ if (rrdcgiType) {
+ free (rrdcgiType);
+ rrdcgiType = NULL;
+ }
+}
+