indent all the rest of the code, and add some typedefs to indent.pro
[rrdtool.git] / bindings / tcl / tclrrd.c
index 11d25df..a58a6c2 100644 (file)
 #   define CONST84
 #endif
 
-extern int Tclrrd_Init(Tcl_Interp *interp);
-extern int Tclrrd_SafeInit(Tcl_Interp *interp);
+extern int Tclrrd_Init(
+    Tcl_Interp *interp);
+extern int Tclrrd_SafeInit(
+    Tcl_Interp *interp);
 
 
 /*
@@ -37,147 +39,165 @@ extern int Tclrrd_SafeInit(Tcl_Interp *interp);
  * Hence, we need to do some preparation before
  * calling the rrd library functions.
  */
-static char ** getopt_init(int argc, CONST84 char *argv[])
+static char **getopt_init(
+    int argc,
+    CONST84 char *argv[])
 {
-    char **argv2;
-    int i;
-    
+    char    **argv2;
+    int       i;
+
     argv2 = calloc(argc, sizeof(char *));
     for (i = 0; i < argc; i++) {
-       argv2[i] = strdup(argv[i]);
+        argv2[i] = strdup(argv[i]);
     }
     return argv2;
 }
 
-static void getopt_cleanup(int argc, char **argv2)
+static void getopt_cleanup(
+    int argc,
+    char **argv2)
 {
-    int i;
-    
+    int       i;
+
     for (i = 0; i < argc; i++) {
-       if (argv2[i] != NULL) {
-           free(argv2[i]);
-       }
+        if (argv2[i] != NULL) {
+            free(argv2[i]);
+        }
     }
     free(argv2);
 }
 
-static void getopt_free_element(argv2, argn)
-    char *argv2[];
-    int  argn;
+static void getopt_free_element(
+    argv2,
+    argn)
+    char     *argv2[];
+    int argn;
 {
     if (argv2[argn] != NULL) {
-       free(argv2[argn]);
-       argv2[argn] = NULL;
+        free(argv2[argn]);
+        argv2[argn] = NULL;
     }
 }
 
-static void getopt_squieeze(argc, argv2)
-    int  *argc;
-    char *argv2[];
+static void getopt_squieeze(
+    argc,
+    argv2)
+    int      *argc;
+    char     *argv2[];
 {
-    int i, null_i = 0, argc_tmp = *argc;
+    int       i, null_i = 0, argc_tmp = *argc;
 
     for (i = 0; i < argc_tmp; i++) {
-       if (argv2[i] == NULL) {
-           (*argc)--;
-       } else {
-           argv2[null_i++] = argv2[i];
-       }
+        if (argv2[i] == NULL) {
+            (*argc)--;
+        } else {
+            argv2[null_i++] = argv2[i];
+        }
     }
 }
 
 
 
 /* Thread-safe version */
-static int
-Rrd_Create(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[])
+static int Rrd_Create(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int argc,
+    CONST84 char *argv[])
 {
-    int                                argv_i;
-    char                       **argv2;
-    char                       *parsetime_error = NULL;
-    time_t                     last_up = time(NULL) - 10;
-    long int                   long_tmp;
-    unsigned long int          pdp_step = 300;
-    struct rrd_time_value      last_up_tv;
+    int       argv_i;
+    char    **argv2;
+    char     *parsetime_error = NULL;
+    time_t    last_up = time(NULL) - 10;
+    long int  long_tmp;
+    unsigned long int pdp_step = 300;
+    struct rrd_time_value last_up_tv;
 
     argv2 = getopt_init(argc, argv);
 
     for (argv_i = 1; argv_i < argc; argv_i++) {
-       if (!strcmp(argv2[argv_i], "--start") || !strcmp(argv2[argv_i], "-b")) {
-           if (argv_i++>=argc) {
-               Tcl_AppendResult(interp, "RRD Error: option '",
-                                argv2[argv_i - 1], "' needs an argument", (char *) NULL);
-               getopt_cleanup(argc, argv2);
-               return TCL_ERROR;
-           }
-           if ((parsetime_error = parsetime(argv2[argv_i], &last_up_tv))) {
-               Tcl_AppendResult(interp, "RRD Error: invalid time format: '",
-                                argv2[argv_i], "'", (char *) NULL);
-               getopt_cleanup(argc, argv2);
-               return TCL_ERROR;
-           }
-           if (last_up_tv.type == RELATIVE_TO_END_TIME ||
-               last_up_tv.type == RELATIVE_TO_START_TIME) {
-               Tcl_AppendResult(interp, "RRD Error: specifying time relative to the 'start' ",
-                                "or 'end' makes no sense here", (char *) NULL);
-               getopt_cleanup(argc, argv2);
-               return TCL_ERROR;
-           }
-           last_up = mktime(&last_up_tv.tm) + last_up_tv.offset;
-           if (last_up < 3600*24*365*10) {
-               Tcl_AppendResult(interp, "RRD Error: the first entry to the RRD should be after 1980",
-                                (char *) NULL);
-               getopt_cleanup(argc, argv2);
-               return TCL_ERROR;
-           }
-           getopt_free_element(argv2, argv_i - 1);
-           getopt_free_element(argv2, argv_i);
-       } else if (!strcmp(argv2[argv_i], "--step") || !strcmp(argv2[argv_i], "-s")) {
-           if (argv_i++>=argc) {
-               Tcl_AppendResult(interp, "RRD Error: option '",
-                                argv2[argv_i - 1], "' needs an argument", (char *) NULL);
-               getopt_cleanup(argc, argv2);
-               return TCL_ERROR;
-           }
-           long_tmp = atol(argv2[argv_i]);
-           if (long_tmp < 1) {
-               Tcl_AppendResult(interp, "RRD Error: step size should be no less than one second",
-                                (char *) NULL);
-               getopt_cleanup(argc, argv2);
-               return TCL_ERROR;
-           }
-           pdp_step = long_tmp;
-           getopt_free_element(argv2, argv_i - 1);
-           getopt_free_element(argv2, argv_i);
-       } else if (!strcmp(argv2[argv_i], "--")) {
-           getopt_free_element(argv2, argv_i);
-           break;
-       } else if (argv2[argv_i][0]=='-') {
-           Tcl_AppendResult(interp, "RRD Error: unknown option '",
-                            argv2[argv_i], "'", (char *) NULL);
-           getopt_cleanup(argc, argv2);
-           return TCL_ERROR;
-       }
+        if (!strcmp(argv2[argv_i], "--start") || !strcmp(argv2[argv_i], "-b")) {
+            if (argv_i++ >= argc) {
+                Tcl_AppendResult(interp, "RRD Error: option '",
+                                 argv2[argv_i - 1], "' needs an argument",
+                                 (char *) NULL);
+                getopt_cleanup(argc, argv2);
+                return TCL_ERROR;
+            }
+            if ((parsetime_error = parsetime(argv2[argv_i], &last_up_tv))) {
+                Tcl_AppendResult(interp, "RRD Error: invalid time format: '",
+                                 argv2[argv_i], "'", (char *) NULL);
+                getopt_cleanup(argc, argv2);
+                return TCL_ERROR;
+            }
+            if (last_up_tv.type == RELATIVE_TO_END_TIME ||
+                last_up_tv.type == RELATIVE_TO_START_TIME) {
+                Tcl_AppendResult(interp,
+                                 "RRD Error: specifying time relative to the 'start' ",
+                                 "or 'end' makes no sense here",
+                                 (char *) NULL);
+                getopt_cleanup(argc, argv2);
+                return TCL_ERROR;
+            }
+            last_up = mktime(&last_up_tv.tm) +last_up_tv.offset;
+            if (last_up < 3600 * 24 * 365 * 10) {
+                Tcl_AppendResult(interp,
+                                 "RRD Error: the first entry to the RRD should be after 1980",
+                                 (char *) NULL);
+                getopt_cleanup(argc, argv2);
+                return TCL_ERROR;
+            }
+            getopt_free_element(argv2, argv_i - 1);
+            getopt_free_element(argv2, argv_i);
+        } else if (!strcmp(argv2[argv_i], "--step")
+                   || !strcmp(argv2[argv_i], "-s")) {
+            if (argv_i++ >= argc) {
+                Tcl_AppendResult(interp, "RRD Error: option '",
+                                 argv2[argv_i - 1], "' needs an argument",
+                                 (char *) NULL);
+                getopt_cleanup(argc, argv2);
+                return TCL_ERROR;
+            }
+            long_tmp = atol(argv2[argv_i]);
+            if (long_tmp < 1) {
+                Tcl_AppendResult(interp,
+                                 "RRD Error: step size should be no less than one second",
+                                 (char *) NULL);
+                getopt_cleanup(argc, argv2);
+                return TCL_ERROR;
+            }
+            pdp_step = long_tmp;
+            getopt_free_element(argv2, argv_i - 1);
+            getopt_free_element(argv2, argv_i);
+        } else if (!strcmp(argv2[argv_i], "--")) {
+            getopt_free_element(argv2, argv_i);
+            break;
+        } else if (argv2[argv_i][0] == '-') {
+            Tcl_AppendResult(interp, "RRD Error: unknown option '",
+                             argv2[argv_i], "'", (char *) NULL);
+            getopt_cleanup(argc, argv2);
+            return TCL_ERROR;
+        }
     }
 
     getopt_squieeze(&argc, argv2);
 
     if (argc < 2) {
-       Tcl_AppendResult(interp, "RRD Error: needs rrd filename",
-                        (char *) NULL);
-       getopt_cleanup(argc, argv2);
-       return TCL_ERROR;
+        Tcl_AppendResult(interp, "RRD Error: needs rrd filename",
+                         (char *) NULL);
+        getopt_cleanup(argc, argv2);
+        return TCL_ERROR;
     }
 
     rrd_create_r(argv2[1], pdp_step, last_up, argc - 2, argv2 + 2);
 
     getopt_cleanup(argc, argv2);
-    
+
     if (rrd_test_error()) {
-       Tcl_AppendResult(interp, "RRD Error: ",
-                        rrd_get_error(), (char *) NULL);
+        Tcl_AppendResult(interp, "RRD Error: ",
+                         rrd_get_error(), (char *) NULL);
         rrd_clear_error();
-       return TCL_ERROR;
+        return TCL_ERROR;
     }
 
     return TCL_OK;
@@ -186,13 +206,16 @@ Rrd_Create(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *ar
 
 
 /* Thread-safe version */
-static int
-Rrd_Dump(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[])
+static int Rrd_Dump(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int argc,
+    CONST84 char *argv[])
 {
     if (argc < 2) {
-       Tcl_AppendResult(interp, "RRD Error: needs rrd filename",
-                        (char *) NULL);
-       return TCL_ERROR;
+        Tcl_AppendResult(interp, "RRD Error: needs rrd filename",
+                         (char *) NULL);
+        return TCL_ERROR;
     }
 
     rrd_dump_r(argv[1], NULL);
@@ -200,10 +223,10 @@ Rrd_Dump(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv
     /* NOTE: rrd_dump() writes to stdout. No interaction with TCL. */
 
     if (rrd_test_error()) {
-       Tcl_AppendResult(interp, "RRD Error: ",
-                        rrd_get_error(), (char *) NULL);
+        Tcl_AppendResult(interp, "RRD Error: ",
+                         rrd_get_error(), (char *) NULL);
         rrd_clear_error();
-       return TCL_ERROR;
+        return TCL_ERROR;
     }
 
     return TCL_OK;
@@ -212,24 +235,27 @@ Rrd_Dump(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv
 
 
 /* Thread-safe version */
-static int
-Rrd_Last(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[])
+static int Rrd_Last(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int argc,
+    CONST84 char *argv[])
 {
-    time_t t;
-    
+    time_t    t;
+
     if (argc < 2) {
-       Tcl_AppendResult(interp, "RRD Error: needs rrd filename",
-                        (char *) NULL);
-       return TCL_ERROR;
+        Tcl_AppendResult(interp, "RRD Error: needs rrd filename",
+                         (char *) NULL);
+        return TCL_ERROR;
     }
 
     t = rrd_last_r(argv[1]);
 
     if (rrd_test_error()) {
-       Tcl_AppendResult(interp, "RRD Error: ",
-                        rrd_get_error(), (char *) NULL);
+        Tcl_AppendResult(interp, "RRD Error: ",
+                         rrd_get_error(), (char *) NULL);
         rrd_clear_error();
-       return TCL_ERROR;
+        return TCL_ERROR;
     }
 
     Tcl_SetIntObj(Tcl_GetObjResult(interp), t);
@@ -240,147 +266,159 @@ Rrd_Last(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv
 
 
 /* Thread-safe version */
-static int
-Rrd_Update(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[])
+static int Rrd_Update(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int argc,
+    CONST84 char *argv[])
 {
-    int                argv_i;
-    char       **argv2, *template = NULL;
-    
+    int       argv_i;
+    char    **argv2, *template = NULL;
+
     argv2 = getopt_init(argc, argv);
 
     for (argv_i = 1; argv_i < argc; argv_i++) {
-       if (!strcmp(argv2[argv_i], "--template") || !strcmp(argv2[argv_i], "-t")) {
-           if (argv_i++>=argc) {
-               Tcl_AppendResult(interp, "RRD Error: option '",
-                                argv2[argv_i - 1], "' needs an argument", (char *) NULL);
-               if (template != NULL) {
-                   free(template);
-               }
-               getopt_cleanup(argc, argv2);
-               return TCL_ERROR;
-           }
-           if (template != NULL) {
-               free(template);
-           }
-           template = strdup(argv2[argv_i]);
-           getopt_free_element(argv2, argv_i - 1);
-           getopt_free_element(argv2, argv_i);
-       } else if (!strcmp(argv2[argv_i], "--")) {
-           getopt_free_element(argv2, argv_i);
-           break;
-       } else if (argv2[argv_i][0]=='-') {
-           Tcl_AppendResult(interp, "RRD Error: unknown option '",
-                            argv2[argv_i], "'", (char *) NULL);
-           if (template != NULL) {
-               free(template);
-           }
-           getopt_cleanup(argc, argv2);
-           return TCL_ERROR;
-       }
+        if (!strcmp(argv2[argv_i], "--template")
+            || !strcmp(argv2[argv_i], "-t")) {
+            if (argv_i++ >= argc) {
+                Tcl_AppendResult(interp, "RRD Error: option '",
+                                 argv2[argv_i - 1], "' needs an argument",
+                                 (char *) NULL);
+                if (template != NULL) {
+                    free(template);
+                }
+                getopt_cleanup(argc, argv2);
+                return TCL_ERROR;
+            }
+            if (template != NULL) {
+                free(template);
+            }
+            template = strdup(argv2[argv_i]);
+            getopt_free_element(argv2, argv_i - 1);
+            getopt_free_element(argv2, argv_i);
+        } else if (!strcmp(argv2[argv_i], "--")) {
+            getopt_free_element(argv2, argv_i);
+            break;
+        } else if (argv2[argv_i][0] == '-') {
+            Tcl_AppendResult(interp, "RRD Error: unknown option '",
+                             argv2[argv_i], "'", (char *) NULL);
+            if (template != NULL) {
+                free(template);
+            }
+            getopt_cleanup(argc, argv2);
+            return TCL_ERROR;
+        }
     }
 
     getopt_squieeze(&argc, argv2);
 
     if (argc < 2) {
-       Tcl_AppendResult(interp, "RRD Error: needs rrd filename",
-                        (char *) NULL);
-       if (template != NULL) {
-           free(template);
-       }
-       getopt_cleanup(argc, argv2);
-       return TCL_ERROR;
+        Tcl_AppendResult(interp, "RRD Error: needs rrd filename",
+                         (char *) NULL);
+        if (template != NULL) {
+            free(template);
+        }
+        getopt_cleanup(argc, argv2);
+        return TCL_ERROR;
     }
 
     rrd_update_r(argv2[1], template, argc - 2, argv2 + 2);
 
     if (template != NULL) {
-       free(template);
+        free(template);
     }
     getopt_cleanup(argc, argv2);
 
     if (rrd_test_error()) {
-       Tcl_AppendResult(interp, "RRD Error: ",
-                        rrd_get_error(), (char *) NULL);
+        Tcl_AppendResult(interp, "RRD Error: ",
+                         rrd_get_error(), (char *) NULL);
         rrd_clear_error();
-       return TCL_ERROR;
+        return TCL_ERROR;
     }
 
     return TCL_OK;
 }
 
-static int
-Rrd_Lastupdate(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[])
+static int Rrd_Lastupdate(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int argc,
+    CONST84 char *argv[])
 {
-   time_t last_update;
-   char **argv2;
-   char **ds_namv;
-   char **last_ds;
-   char s[30];
-   Tcl_Obj *listPtr;
-   unsigned long ds_cnt, i;
-
-   argv2 = getopt_init(argc, argv);
-   if (rrd_lastupdate(argc-1, argv2, &last_update,
-       &ds_cnt, &ds_namv, &last_ds) == 0) {
-          listPtr = Tcl_GetObjResult(interp);
-           for (i=0; i<ds_cnt; i++) {
-              sprintf(s, " %28s", ds_namv[i]);
-              Tcl_ListObjAppendElement(interp, listPtr,
-                      Tcl_NewStringObj(s, -1));
-           sprintf(s, "\n\n%10lu:", last_update);
-              Tcl_ListObjAppendElement(interp, listPtr,
-                      Tcl_NewStringObj(s, -1));
-           for (i=0; i<ds_cnt; i++) {
-               sprintf(s, " %s", last_ds[i]);
-              Tcl_ListObjAppendElement(interp, listPtr,
-                      Tcl_NewStringObj(s, -1));
-               free(last_ds[i]);
-               free(ds_namv[i]);
-           }
-           sprintf(s, "\n");
-          Tcl_ListObjAppendElement(interp, listPtr,
-                   Tcl_NewStringObj(s, -1));
-           free(last_ds);
-           free(ds_namv);
-          }
+    time_t    last_update;
+    char    **argv2;
+    char    **ds_namv;
+    char    **last_ds;
+    char      s[30];
+    Tcl_Obj  *listPtr;
+    unsigned long ds_cnt, i;
+
+    argv2 = getopt_init(argc, argv);
+    if (rrd_lastupdate(argc - 1, argv2, &last_update,
+                       &ds_cnt, &ds_namv, &last_ds) == 0) {
+        listPtr = Tcl_GetObjResult(interp);
+        for (i = 0; i < ds_cnt; i++) {
+            sprintf(s, " %28s", ds_namv[i]);
+            Tcl_ListObjAppendElement(interp, listPtr,
+                                     Tcl_NewStringObj(s, -1));
+            sprintf(s, "\n\n%10lu:", last_update);
+            Tcl_ListObjAppendElement(interp, listPtr,
+                                     Tcl_NewStringObj(s, -1));
+            for (i = 0; i < ds_cnt; i++) {
+                sprintf(s, " %s", last_ds[i]);
+                Tcl_ListObjAppendElement(interp, listPtr,
+                                         Tcl_NewStringObj(s, -1));
+                free(last_ds[i]);
+                free(ds_namv[i]);
+            }
+            sprintf(s, "\n");
+            Tcl_ListObjAppendElement(interp, listPtr,
+                                     Tcl_NewStringObj(s, -1));
+            free(last_ds);
+            free(ds_namv);
+        }
     }
     return TCL_OK;
 }
 
-static int
-Rrd_Fetch(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[])
+static int Rrd_Fetch(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int argc,
+    CONST84 char *argv[])
 {
-    time_t start, end, j;
+    time_t    start, end, j;
     unsigned long step, ds_cnt, i, ii;
     rrd_value_t *data, *datai;
-    char **ds_namv;
-    Tcl_Obj *listPtr;
-    char s[30];
-    char **argv2;
-    
+    char    **ds_namv;
+    Tcl_Obj  *listPtr;
+    char      s[30];
+    char    **argv2;
+
     argv2 = getopt_init(argc, argv);
     if (rrd_fetch(argc, argv2, &start, &end, &step,
-                 &ds_cnt, &ds_namv, &data) != -1) {
+                  &ds_cnt, &ds_namv, &data) != -1) {
         datai = data;
         listPtr = Tcl_GetObjResult(interp);
         for (j = start; j <= end; j += step) {
             for (ii = 0; ii < ds_cnt; ii++) {
-               sprintf(s, "%.2f", *(datai++));
+                sprintf(s, "%.2f", *(datai++));
                 Tcl_ListObjAppendElement(interp, listPtr,
-                                        Tcl_NewStringObj(s, -1));
+                                         Tcl_NewStringObj(s, -1));
             }
         }
-        for (i=0; i<ds_cnt; i++) free(ds_namv[i]);
+        for (i = 0; i < ds_cnt; i++)
+            free(ds_namv[i]);
         free(ds_namv);
         free(data);
     }
     getopt_cleanup(argc, argv2);
 
     if (rrd_test_error()) {
-       Tcl_AppendResult(interp, "RRD Error: ",
-                        rrd_get_error(), (char *) NULL);
+        Tcl_AppendResult(interp, "RRD Error: ",
+                         rrd_get_error(), (char *) NULL);
         rrd_clear_error();
-       return TCL_ERROR;
+        return TCL_ERROR;
     }
 
     return TCL_OK;
@@ -388,102 +426,109 @@ Rrd_Fetch(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *arg
 
 
 
-static int
-Rrd_Graph(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[])
+static int Rrd_Graph(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int argc,
+    CONST84 char *argv[])
 {
     Tcl_Channel channel;
-    int mode, fd2;
+    int       mode, fd2;
     ClientData fd1;
-    FILE *stream = NULL;
-    char **calcpr = NULL;
-    int rc, xsize, ysize;
-    double ymin, ymax;
-    char dimensions[50];
-    char **argv2;
+    FILE     *stream = NULL;
+    char    **calcpr = NULL;
+    int       rc, xsize, ysize;
+    double    ymin, ymax;
+    char      dimensions[50];
+    char    **argv2;
     CONST84 char *save;
-    
+
     /*
      * If the "filename" is a Tcl fileID, then arrange for rrd_graph() to write to
      * that file descriptor.  Will this work with windoze?  I have no idea.
      */
     if ((channel = Tcl_GetChannel(interp, argv[1], &mode)) != NULL) {
-       /*
-        * It >is< a Tcl fileID
-        */
-       if (!(mode & TCL_WRITABLE)) {
-           Tcl_AppendResult(interp, "channel \"", argv[1],
-               "\" wasn't opened for writing", (char *) NULL);
-           return TCL_ERROR;
-       }
-       /*
-        * Must flush channel to make sure any buffered data is written before
-        * rrd_graph() writes to the stream
-        */
-       if (Tcl_Flush(channel) != TCL_OK) {
-           Tcl_AppendResult(interp, "flush failed for \"", argv[1], "\": ",
-               strerror(Tcl_GetErrno()), (char *) NULL);
-           return TCL_ERROR;
-       }
-       if (Tcl_GetChannelHandle(channel, TCL_WRITABLE, &fd1) != TCL_OK) {
-           Tcl_AppendResult(interp, "cannot get file descriptor associated with \"",
-               argv[1], "\"", (char *) NULL);
-           return TCL_ERROR;
-       }
-       /*
-        * Must dup() file descriptor so we can fclose(stream), otherwise the fclose()
-        * would close Tcl's file descriptor
-        */
-       if ((fd2 = dup((int)fd1)) == -1) {
-           Tcl_AppendResult(interp, "dup() failed for file descriptor associated with \"",
-               argv[1], "\": ", strerror(errno), (char *) NULL);
-           return TCL_ERROR;
-       }
-       /*
-        * rrd_graph() wants a FILE*
-        */
-       if ((stream = fdopen(fd2, "wb")) == NULL) {
-           Tcl_AppendResult(interp, "fdopen() failed for file descriptor associated with \"",
-               argv[1], "\": ", strerror(errno), (char *) NULL);
-           close(fd2);         /* plug potential file descriptor leak */
-           return TCL_ERROR;
-       }
-
-       save = argv[1];
-       argv[1] = "-";
-       argv2 = getopt_init(argc, argv);
-       argv[1] = save;
+        /*
+         * It >is< a Tcl fileID
+         */
+        if (!(mode & TCL_WRITABLE)) {
+            Tcl_AppendResult(interp, "channel \"", argv[1],
+                             "\" wasn't opened for writing", (char *) NULL);
+            return TCL_ERROR;
+        }
+        /*
+         * Must flush channel to make sure any buffered data is written before
+         * rrd_graph() writes to the stream
+         */
+        if (Tcl_Flush(channel) != TCL_OK) {
+            Tcl_AppendResult(interp, "flush failed for \"", argv[1], "\": ",
+                             strerror(Tcl_GetErrno()), (char *) NULL);
+            return TCL_ERROR;
+        }
+        if (Tcl_GetChannelHandle(channel, TCL_WRITABLE, &fd1) != TCL_OK) {
+            Tcl_AppendResult(interp,
+                             "cannot get file descriptor associated with \"",
+                             argv[1], "\"", (char *) NULL);
+            return TCL_ERROR;
+        }
+        /*
+         * Must dup() file descriptor so we can fclose(stream), otherwise the fclose()
+         * would close Tcl's file descriptor
+         */
+        if ((fd2 = dup((int) fd1)) == -1) {
+            Tcl_AppendResult(interp,
+                             "dup() failed for file descriptor associated with \"",
+                             argv[1], "\": ", strerror(errno), (char *) NULL);
+            return TCL_ERROR;
+        }
+        /*
+         * rrd_graph() wants a FILE*
+         */
+        if ((stream = fdopen(fd2, "wb")) == NULL) {
+            Tcl_AppendResult(interp,
+                             "fdopen() failed for file descriptor associated with \"",
+                             argv[1], "\": ", strerror(errno), (char *) NULL);
+            close(fd2); /* plug potential file descriptor leak */
+            return TCL_ERROR;
+        }
+
+        save = argv[1];
+        argv[1] = "-";
+        argv2 = getopt_init(argc, argv);
+        argv[1] = save;
     } else {
-       Tcl_ResetResult(interp);        /* clear error from Tcl_GetChannel() */
-       argv2 = getopt_init(argc, argv);
+        Tcl_ResetResult(interp);    /* clear error from Tcl_GetChannel() */
+        argv2 = getopt_init(argc, argv);
     }
 
-    rc = rrd_graph(argc, argv2, &calcpr, &xsize, &ysize, stream, &ymin, &ymax);
+    rc = rrd_graph(argc, argv2, &calcpr, &xsize, &ysize, stream, &ymin,
+                   &ymax);
     getopt_cleanup(argc, argv2);
 
     if (stream != NULL)
-       fclose(stream);         /* plug potential malloc & file descriptor leak */
+        fclose(stream); /* plug potential malloc & file descriptor leak */
 
     if (rc != -1) {
         sprintf(dimensions, "%d %d", xsize, ysize);
         Tcl_AppendResult(interp, dimensions, (char *) NULL);
         if (calcpr) {
 #if 0
-           int i;
-           
-            for(i = 0; calcpr[i]; i++){
+            int       i;
+
+            for (i = 0; calcpr[i]; i++) {
                 printf("%s\n", calcpr[i]);
                 free(calcpr[i]);
-            } 
+            }
 #endif
             free(calcpr);
         }
     }
 
     if (rrd_test_error()) {
-       Tcl_AppendResult(interp, "RRD Error: ",
-                        rrd_get_error(), (char *) NULL);
+        Tcl_AppendResult(interp, "RRD Error: ",
+                         rrd_get_error(), (char *) NULL);
         rrd_clear_error();
-       return TCL_ERROR;
+        return TCL_ERROR;
     }
 
     return TCL_OK;
@@ -491,20 +536,23 @@ Rrd_Graph(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *arg
 
 
 
-static int
-Rrd_Tune(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[])
+static int Rrd_Tune(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int argc,
+    CONST84 char *argv[])
 {
-    char **argv2;
-    
+    char    **argv2;
+
     argv2 = getopt_init(argc, argv);
     rrd_tune(argc, argv2);
     getopt_cleanup(argc, argv2);
 
     if (rrd_test_error()) {
-       Tcl_AppendResult(interp, "RRD Error: ",
-                        rrd_get_error(), (char *) NULL);
+        Tcl_AppendResult(interp, "RRD Error: ",
+                         rrd_get_error(), (char *) NULL);
         rrd_clear_error();
-       return TCL_ERROR;
+        return TCL_ERROR;
     }
 
     return TCL_OK;
@@ -512,20 +560,23 @@ Rrd_Tune(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv
 
 
 
-static int
-Rrd_Resize(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[])
+static int Rrd_Resize(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int argc,
+    CONST84 char *argv[])
 {
-    char **argv2;
-    
+    char    **argv2;
+
     argv2 = getopt_init(argc, argv);
     rrd_resize(argc, argv2);
     getopt_cleanup(argc, argv2);
 
     if (rrd_test_error()) {
-       Tcl_AppendResult(interp, "RRD Error: ",
-                        rrd_get_error(), (char *) NULL);
+        Tcl_AppendResult(interp, "RRD Error: ",
+                         rrd_get_error(), (char *) NULL);
         rrd_clear_error();
-       return TCL_ERROR;
+        return TCL_ERROR;
     }
 
     return TCL_OK;
@@ -533,20 +584,23 @@ Rrd_Resize(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *ar
 
 
 
-static int
-Rrd_Restore(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[])
+static int Rrd_Restore(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int argc,
+    CONST84 char *argv[])
 {
-    char **argv2;
-    
+    char    **argv2;
+
     argv2 = getopt_init(argc, argv);
     rrd_restore(argc, argv2);
     getopt_cleanup(argc, argv2);
 
     if (rrd_test_error()) {
-       Tcl_AppendResult(interp, "RRD Error: ",
-                        rrd_get_error(), (char *) NULL);
+        Tcl_AppendResult(interp, "RRD Error: ",
+                         rrd_get_error(), (char *) NULL);
         rrd_clear_error();
-       return TCL_ERROR;
+        return TCL_ERROR;
     }
 
     return TCL_OK;
@@ -559,39 +613,40 @@ Rrd_Restore(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *a
  */
 
 typedef struct {
-    char *name;                        /* Name of the command. */
-    Tcl_CmdProc *proc;         /* Procedure for command. */
-    int hide;                  /* Hide if safe interpreter */
+    char     *name;     /* Name of the command. */
+    Tcl_CmdProc *proc;  /* Procedure for command. */
+    int       hide;     /* Hide if safe interpreter */
 } CmdInfo;
 
 static CmdInfo rrdCmds[] = {
-    { "Rrd::create",    Rrd_Create,     1 }, /* Thread-safe version */
-    { "Rrd::dump",      Rrd_Dump,       0 }, /* Thread-safe version */
-    { "Rrd::last",      Rrd_Last,       0 }, /* Thread-safe version */
-    { "Rrd::lastupdate", Rrd_Lastupdate, 0 }, /* Thread-safe version */
-    { "Rrd::update",    Rrd_Update,     1 }, /* Thread-safe version */
-    { "Rrd::fetch",     Rrd_Fetch,      0 },
-    { "Rrd::graph",     Rrd_Graph,      1 }, /* Due to RRD's API, a safe
-                                               interpreter cannot create
-                                               a graph since it writes to
-                                               a filename supplied by the
-                                               caller */
-    { "Rrd::tune",      Rrd_Tune,       1 },
-    { "Rrd::resize",    Rrd_Resize,     1 },
-    { "Rrd::restore",   Rrd_Restore,    1 },
-    { (char *) NULL,   (Tcl_CmdProc *)  NULL, 0        }
+    {"Rrd::create", Rrd_Create, 1}, /* Thread-safe version */
+    {"Rrd::dump", Rrd_Dump, 0}, /* Thread-safe version */
+    {"Rrd::last", Rrd_Last, 0}, /* Thread-safe version */
+    {"Rrd::lastupdate", Rrd_Lastupdate, 0}, /* Thread-safe version */
+    {"Rrd::update", Rrd_Update, 1}, /* Thread-safe version */
+    {"Rrd::fetch", Rrd_Fetch, 0},
+    {"Rrd::graph", Rrd_Graph, 1},   /* Due to RRD's API, a safe
+                                       interpreter cannot create
+                                       a graph since it writes to
+                                       a filename supplied by the
+                                       caller */
+    {"Rrd::tune", Rrd_Tune, 1},
+    {"Rrd::resize", Rrd_Resize, 1},
+    {"Rrd::restore", Rrd_Restore, 1},
+    {(char *) NULL, (Tcl_CmdProc *) NULL, 0}
 };
 
 
 
-static int
-init(Tcl_Interp *interp, int safe)
-{ 
-    CmdInfo *cmdInfoPtr;
+static int init(
+    Tcl_Interp *interp,
+    int safe)
+{
+    CmdInfo  *cmdInfoPtr;
     Tcl_CmdInfo info;
 
-    if ( Tcl_InitStubs(interp,TCL_VERSION,0) == NULL )
-       return TCL_ERROR;
+    if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL)
+        return TCL_ERROR;
 
     if (Tcl_PkgRequire(interp, "Tcl", TCL_VERSION, 1) == NULL) {
         return TCL_ERROR;
@@ -604,65 +659,65 @@ init(Tcl_Interp *interp, int safe)
     Tcl_SetVar2(interp, "rrd", "version", VERSION, TCL_GLOBAL_ONLY);
 
     for (cmdInfoPtr = rrdCmds; cmdInfoPtr->name != NULL; cmdInfoPtr++) {
-       /*
-        * Check if the command already exists and return an error
-        * to ensure we detect name clashes while loading the Rrd
-        * extension.
-        */
-       if (Tcl_GetCommandInfo(interp, cmdInfoPtr->name, &info)) {
-           Tcl_AppendResult(interp, "command \"", cmdInfoPtr->name,
-                            "\" already exists", (char *) NULL);
-           return TCL_ERROR;
-       }
-       if (safe && cmdInfoPtr->hide) {
+        /*
+         * Check if the command already exists and return an error
+         * to ensure we detect name clashes while loading the Rrd
+         * extension.
+         */
+        if (Tcl_GetCommandInfo(interp, cmdInfoPtr->name, &info)) {
+            Tcl_AppendResult(interp, "command \"", cmdInfoPtr->name,
+                             "\" already exists", (char *) NULL);
+            return TCL_ERROR;
+        }
+        if (safe && cmdInfoPtr->hide) {
 #if 0
-           /*
-            * Turns out the one cannot hide a command in a namespace
-            * due to a limitation of Tcl, one can only hide global
-            * commands.  Thus, if we created the commands without
-            * the Rrd:: namespace in a safe interpreter, then the
-            * "unsafe" commands could be hidden -- which would allow
-            * an owning interpreter either un-hiding them or doing
-            * an "interp invokehidden".  If the Rrd:: namespace is
-            * used, then it's still possible for the owning interpreter
-            * to fake out the missing commands:
-            *
-            *   # Make all Rrd::* commands available in master interperter
-            *   package require Rrd
-            *   set safe [interp create -safe]
-            *   # Make safe Rrd::* commands available in safe interperter
-            *   interp invokehidden $safe -global load ./tclrrd1.2.11.so
-            *   # Provide the safe interpreter with the missing commands
-            *   $safe alias Rrd::update do_update $safe
-            *   proc do_update {which_interp $args} {
-            *     # Do some checking maybe...
-            *       :
-            *     return [eval Rrd::update $args]
-            *   }
-            *
-            * Our solution for now is to just not create the "unsafe"
-            * commands in a safe interpreter.
-            */
-           if (Tcl_HideCommand(interp, cmdInfoPtr->name, cmdInfoPtr->name) != TCL_OK)
-               return TCL_ERROR;
+            /*
+             * Turns out the one cannot hide a command in a namespace
+             * due to a limitation of Tcl, one can only hide global
+             * commands.  Thus, if we created the commands without
+             * the Rrd:: namespace in a safe interpreter, then the
+             * "unsafe" commands could be hidden -- which would allow
+             * an owning interpreter either un-hiding them or doing
+             * an "interp invokehidden".  If the Rrd:: namespace is
+             * used, then it's still possible for the owning interpreter
+             * to fake out the missing commands:
+             *
+             *   # Make all Rrd::* commands available in master interperter
+             *   package require Rrd
+             *   set safe [interp create -safe]
+             *   # Make safe Rrd::* commands available in safe interperter
+             *   interp invokehidden $safe -global load ./tclrrd1.2.11.so
+             *   # Provide the safe interpreter with the missing commands
+             *   $safe alias Rrd::update do_update $safe
+             *   proc do_update {which_interp $args} {
+             *     # Do some checking maybe...
+             *       :
+             *     return [eval Rrd::update $args]
+             *   }
+             *
+             * Our solution for now is to just not create the "unsafe"
+             * commands in a safe interpreter.
+             */
+            if (Tcl_HideCommand(interp, cmdInfoPtr->name, cmdInfoPtr->name) !=
+                TCL_OK)
+                return TCL_ERROR;
 #endif
-       }
-       else
-           Tcl_CreateCommand(interp, cmdInfoPtr->name, cmdInfoPtr->proc,
-                         (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
+        } else
+            Tcl_CreateCommand(interp, cmdInfoPtr->name, cmdInfoPtr->proc,
+                              (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
     }
 
     if (Tcl_PkgProvide(interp, "Rrd", VERSION) != TCL_OK) {
-       return TCL_ERROR;
+        return TCL_ERROR;
     }
 
     return TCL_OK;
 }
 
-int
-Tclrrd_Init(Tcl_Interp *interp)
-{ 
-  return init(interp, 0);
+int Tclrrd_Init(
+    Tcl_Interp *interp)
+{
+    return init(interp, 0);
 }
 
 /*
@@ -670,8 +725,8 @@ Tclrrd_Init(Tcl_Interp *interp)
  * Using rrdtool in a safe interpreter has very limited functionality.  It's
  * tempting to just return TCL_ERROR and forget about it.
  */
-int
-Tclrrd_SafeInit(Tcl_Interp *interp)
-{ 
-  return init(interp, 1);
+int Tclrrd_SafeInit(
+    Tcl_Interp *interp)
+{
+    return init(interp, 1);
 }