driver.c

Go to the documentation of this file.
00001 
00018 #include <sys/types.h>
00019 #include <sys/stat.h>
00020 #include <stdlib.h>
00021 #include <stdio.h>
00022 #include <grass/gis.h>
00023 #include <grass/dbmi.h>
00024 #include "procs.h"
00025 #define DB_DRIVER_C
00026 #include "dbstubs.h"
00027 
00028 extern char *getenv();
00029 
00038 int db_driver(int argc, char *argv[])
00039 {
00040     int stat;
00041     int procnum;
00042     int i;
00043     int rfd, wfd;
00044     FILE *send, *recv;
00045     char *modestr;
00046 
00047     /* Read and set environment variables, see dbmi_client/start.c */
00048     if ((modestr = getenv("GRASS_DB_DRIVER_GISRC_MODE"))) {
00049         int mode;
00050 
00051         mode = atoi(modestr);
00052 
00053         if (mode == G_GISRC_MODE_MEMORY) {
00054             G_set_gisrc_mode(G_GISRC_MODE_MEMORY);
00055             G__setenv("DEBUG", getenv("DEBUG"));
00056             G__setenv("GISDBASE", getenv("GISDBASE"));
00057             G__setenv("LOCATION_NAME", getenv("LOCATION_NAME"));
00058             G__setenv("MAPSET", getenv("MAPSET"));
00059             G_debug(3, "Driver GISDBASE set to '%s'", G_getenv("GISDBASE"));
00060         }
00061     }
00062 
00063 #ifdef __MINGW32__
00064     /* TODO: */
00065     /* We should close everything except stdin, stdout but _fcloseall()
00066      * closes open streams not file descriptors. _getmaxstdio too big number.
00067      * 
00068      * Because the pipes were created just before this driver was started 
00069      * the file descriptors should not be above a closed descriptor
00070      * until it was run from a multithread application and some descriptors 
00071      * were closed in the mean time. 
00072      * Also Windows documentation does not say that new file descriptor is 
00073      * the lowest available.
00074      */
00075 
00076     {
00077         int err_count = 0;
00078         int cfd = 3;
00079 
00080         while (1) {
00081             if (close(cfd) == -1)
00082                 err_count++;
00083 
00084             /* no good reason for 10 */
00085             if (err_count > 10)
00086                 break;
00087 
00088             cfd++;
00089         }
00090     }
00091 #endif
00092 
00093     send = stdout;
00094     recv = stdin;
00095 
00096     /* THIS CODE IS FOR DEBUGGING WITH CODECENTER */
00097 
00098 /**********************************************/
00099     if (argc == 3) {
00100         rfd = wfd = -1;
00101         sscanf(argv[1], "%d", &rfd);
00102         sscanf(argv[2], "%d", &wfd);
00103         send = fdopen(wfd, "w");
00104         if (send == NULL) {
00105             db_syserror(argv[1]);
00106             exit(1);
00107         }
00108         recv = fdopen(rfd, "r");
00109         if (recv == NULL) {
00110             db_syserror(argv[2]);
00111             exit(1);
00112         }
00113     }
00114 
00115 /**********************************************/
00116 
00117     db_clear_error();
00118     db_auto_print_errors(0);
00119     db_auto_print_protocol_errors(1);
00120     db__init_driver_state();
00121 
00122 #ifndef USE_BUFFERED_IO
00123     setbuf(recv, NULL);
00124     setbuf(send, NULL);
00125 #endif
00126     db__set_protocol_fds(send, recv);
00127 
00128     if (db_driver_init(argc, argv) == DB_OK)
00129         db__send_success();
00130     else {
00131         db__send_failure();
00132         exit(1);
00133     }
00134 
00135     stat = DB_OK;
00136     /* get the procedure number */
00137     while (db__recv_procnum(&procnum) == DB_OK) {
00138 #ifdef __MINGW32__
00139         if (procnum == DB_PROC_SHUTDOWN_DRIVER) {
00140             db__send_procedure_ok(procnum);
00141             break;
00142         }
00143 #endif
00144         db_clear_error();
00145 
00146         /* find this procedure */
00147         for (i = 0; procedure[i].routine; i++)
00148             if (procedure[i].procnum == procnum)
00149                 break;
00150 
00151         /* if found, call it */
00152         if (procedure[i].routine) {
00153             if ((stat = db__send_procedure_ok(procnum)) != DB_OK)
00154                 break;          /* while loop */
00155             if ((stat = (*procedure[i].routine) ()) != DB_OK)
00156                 break;
00157         }
00158         else if ((stat =
00159                   db__send_procedure_not_implemented(procnum)) != DB_OK)
00160             break;
00161     }
00162 
00163     db_driver_finish();
00164 
00165     exit(stat == DB_OK ? 0 : 1);
00166 }