use snprintf, strdup, ... where possible to make for safer operation -- Martin Pelikan
[rrdtool.git] / src / rrd_xport.c
index c4173e4..ebe72aa 100644 (file)
@@ -18,7 +18,6 @@
 #include <fcntl.h>
 #endif
 
-
 int       rrd_xport(
     int,
     char **,
@@ -40,7 +39,20 @@ int       rrd_xport_fn(
     rrd_value_t **,
     int);
 
+/* helper function for buffer handling */
+typedef struct stringbuffer_t {
+  size_t allocated;
+  size_t len;
+  unsigned char* data;
+  FILE *file;
+} stringbuffer_t;
+int addToBuffer(stringbuffer_t *,char*,size_t);
+void escapeJSON(char*,size_t);
 
+int rrd_graph_xport(image_desc_t *);
+int rrd_xport_format_xmljson(int,stringbuffer_t *,image_desc_t*,time_t, time_t, unsigned long, unsigned long, char**, rrd_value_t*);
+int rrd_xport_format_sv(char,stringbuffer_t *,image_desc_t*,time_t, time_t, unsigned long, unsigned long, char**, rrd_value_t*);
+int rrd_xport_format_addprints(int,stringbuffer_t *,image_desc_t *);
 
 int rrd_xport(
     int argc,
@@ -79,6 +91,9 @@ int rrd_xport(
     rrd_parsetime("end-24h", &start_tv);
     rrd_parsetime("now", &end_tv);
 
+    int enumds=0;
+    int json=0;
+
     while (1) {
         int       option_index = 0;
         int       opt;
@@ -93,6 +108,10 @@ int rrd_xport(
             im.step = atoi(optarg);
             break;
         case 262:
+           enumds=1;
+            break;
+        case 263:
+           json=1;
             break;
         case 's':
             if ((parsetime_error = rrd_parsetime(optarg, &start_tv))) {
@@ -179,6 +198,18 @@ int rrd_xport(
         return -1;
     }
 
+    /* and create the export */
+    if (!xsize) {
+      int flags=0;
+      if (json) { flags|=1; }
+      if (enumds) { flags|=4; }
+      stringbuffer_t buffer={0,0,NULL,stdout};
+      rrd_xport_format_xmljson(flags,&buffer,&im, 
+                              *start, *end, *step,
+                              *col_cnt, *legend_v,
+                              *data);
+    }
+
     im_free(&im);
     return 0;
 }
@@ -277,10 +308,9 @@ int rrd_xport_fn(
             *step_list_ptr = im->gdes[im->gdes[i].vidx].step;
             /* printf("%s:%lu\n",im->gdes[i].legend,*step_list_ptr); */
             step_list_ptr++;
+
             /* reserve room for one legend entry */
-            /* is FMT_LEG_LEN + 5 the correct size? */
-            if ((legend_list[j] =
-                (char*)malloc(sizeof(char) * (FMT_LEG_LEN + 5))) == NULL) {
+            if ((legend_list[j] = strdup(im->gdes[i].legend)) == NULL) {
                 free(ref_list);
                 *data = NULL;
                 while (--j > -1)
@@ -291,11 +321,9 @@ int rrd_xport_fn(
                 return (-1);
             }
 
-            if (im->gdes[i].legend)
-                /* omit bounds check, should have the same size */
-                strcpy(legend_list[j++], im->gdes[i].legend);
-            else
-                legend_list[j++][0] = '\0';
+            if (im->gdes[i].legend == 0)
+                legend_list[j][0] = '\0';
+            ++j;
        }
     }
     *step_list_ptr=0;    
@@ -341,21 +369,6 @@ int rrd_xport_fn(
 
 }
 
-/* helper function for buffer handling */
-typedef struct stringbuffer_t {
-  size_t allocated;
-  size_t len;
-  unsigned char* data;
-  FILE *file;
-} stringbuffer_t;
-int addToBuffer(stringbuffer_t *,char*,size_t);
-void escapeJSON(char*,size_t);
-
-int rrd_graph_xport(image_desc_t *);
-int rrd_xport_format_xmljson(int,stringbuffer_t *,image_desc_t*,time_t, time_t, unsigned long, unsigned long, char**, rrd_value_t*);
-int rrd_xport_format_sv(char,stringbuffer_t *,image_desc_t*,time_t, time_t, unsigned long, unsigned long, char**, rrd_value_t*);
-int rrd_xport_format_addprints(int,stringbuffer_t *,image_desc_t *);
-
 int rrd_graph_xport(image_desc_t *im) {
   /* prepare the data for processing */
   unsigned long col_cnt=0;
@@ -366,6 +379,18 @@ int rrd_graph_xport(image_desc_t *im) {
   rrd_value_t *data=NULL;
   /* initialize buffer */
   stringbuffer_t buffer={0,0,NULL,NULL}; 
+
+  /* check if we have a supported ggraph format */
+  switch (im->graph_type) {
+    /* allow the following to pass */
+  case GTYPE_TIME:
+  case GTYPE_XY:
+    break;
+  default:
+    rrd_set_error("Not supported graph type");
+    return -1;
+  }
+
   /* if we write a file, then open it */
   if (strlen(im->graphfile)) {
     buffer.file=fopen(im->graphfile,"w");
@@ -690,9 +715,11 @@ int rrd_xport_format_xmljson(int flags,stringbuffer_t *buffer,image_desc_t *im,t
   if (rrd_xport_format_addprints(json,buffer,im)) {return -1;}
 
   /* if we have got a trailing , then kill it */
-  if (buffer->data[buffer->len-2]==',') { 
-    buffer->data[buffer->len-2]=buffer->data[buffer->len-1];
-    buffer->len--;
+  if (buffer->data) {
+    if (buffer->data[buffer->len-2]==',') { 
+      buffer->data[buffer->len-2]=buffer->data[buffer->len-1];
+      buffer->len--;
+    }
   }
 
   /* end meta */