static void add_entry(dbDbmscap ** list, char *name, char *startup, char *comment) { dbDbmscap *head, *cur, *tail; /* add this entry to the head of a linked list */ tail = head = *list; while (tail && tail->next) tail = tail->next; *list = NULL; cur = (dbDbmscap *) db_malloc(sizeof(dbDbmscap)); if (cur == NULL) return; /* out of memory */ cur->next = NULL; /* copy each item to the dbmscap structure */ strcpy(cur->driverName, name); strcpy(cur->startup, startup); strcpy(cur->comment, comment); /* handle the first call (head == NULL) */ if (tail) tail->next = cur; else head = cur; *list = head; }
cursor *alloc_cursor(void) { cursor *c; /* allocate the cursor */ c = (cursor *) db_malloc(sizeof(cursor)); if (c == NULL) { append_error("Cannot allocate cursor."); return NULL; } c->res = NULL; /* tokenize it */ c->token = db_new_token(c); if (c->token < 0) { append_error("Cannot ad new token."); return NULL; } c->cols = NULL; c->ncols = 0; return c; }
/*! \brief Make a copy of string buffer Allocated string buffer should be freed by db_free(). \param s source string buffer \return allocated string buffer */ char *db_store(const char *s) { char *a; a = db_malloc(strlen(s) + 1); if (a) strcpy(a, s); return a; }
static const char *login_filename(void) { static char *file; if (!file) { file = (char *)db_malloc(GPATH_MAX); sprintf(file, "%s%cdblogin", G_config_path(), HOST_DIRSEP); } return file; }
/*! \brief Open select cursor \return DB_OK on success \return DB_FAILED on failure */ int db_d_open_select_cursor(void) { dbCursor *cursor; int stat; dbToken token; dbString select; int mode; /* get the arg(s) */ db_init_string(&select); DB_RECV_STRING(&select); DB_RECV_INT(&mode); /* create a cursor */ cursor = (dbCursor *) db_malloc(sizeof(dbCursor)); if (cursor == NULL) return db_get_error_code(); token = db_new_token((dbAddress) cursor); if (token < 0) return db_get_error_code(); db_init_cursor(cursor); /* call the procedure */ stat = db_driver_open_select_cursor(&select, cursor, mode); db_free_string(&select); /* send the return code */ if (stat != DB_OK) { DB_SEND_FAILURE(); return DB_OK; } DB_SEND_SUCCESS(); /* mark this as a readonly cursor */ db_set_cursor_type_readonly(cursor); /* add this cursor to the cursors managed by the driver state */ db__add_cursor_to_driver_state(cursor); /* results */ DB_SEND_TOKEN(&token); DB_SEND_INT(cursor->type); DB_SEND_INT(cursor->mode); DB_SEND_TABLE_DEFINITION(cursor->table); return DB_OK; }
cursor *alloc_cursor() { cursor *c; /* allocate the cursor */ c = (cursor *) db_malloc(sizeof(cursor)); if (c == NULL) { append_error("cannot alloc new cursor"); return c; } c->st = NULL; c->cols = NULL; /* tokenize it */ c->token = db_new_token(c); if (c->token < 0) { free_cursor(c); c = NULL; append_error("cannot tokenize new cursor\n"); } return c; }
static void add_entry(dbDbmscap ** list, char *name, char *startup, char *comment) { /* add an entry to the list, so that the list remains ordered (by driverName) */ dbDbmscap *head, *cur, *tail; cur = (dbDbmscap *) db_malloc(sizeof(dbDbmscap)); if (cur == NULL) { *list = NULL; return; /* out of memory */ } cur->next = NULL; /* copy each item to the dbmscap structure */ strcpy(cur->driverName, name); strcpy(cur->startup, startup); strcpy(cur->comment, comment); /* find the last entry that is less than cur */ tail = head = *list; while (tail && tail->next && cmp_entry(tail->next,cur)<0) tail = tail->next; /* handle the first call (head == NULL) */ if (tail && cmp_entry(tail,cur)<0) { /* insert right after tail */ cur->next = tail->next; tail->next = cur; } else { /* insert at first position */ cur->next = head; head = cur; } *list = head; }
/*! \brief Initialize a new dbDriver for db transaction. If <i>name</i> is NULL, the db name will be assigned connection.driverName. \param name driver name \return pointer to dbDriver structure \return NULL on error */ dbDriver *db_start_driver(const char *name) { dbDriver *driver; dbDbmscap *list, *cur; const char *startup; int p1[2], p2[2]; int pid; int stat; dbConnection connection; char ebuf[5]; /* Set some environment variables which are later read by driver. * This is necessary when application is running without GISRC file and all * gis variables are set by application. * Even if GISRC is set, application may change some variables during runtime, * if for example reads data from different gdatabase, location or mapset*/ /* setenv() is not portable, putenv() is POSIX, putenv() in glibc 2.0-2.1.1 doesn't conform to SUSv2, * G_putenv() as well, but that is what we want, makes a copy of string */ if (G_get_gisrc_mode() == G_GISRC_MODE_MEMORY) { G_debug(3, "G_GISRC_MODE_MEMORY\n"); sprintf(ebuf, "%d", G_GISRC_MODE_MEMORY); G_putenv("GRASS_DB_DRIVER_GISRC_MODE", ebuf); /* to tell driver that it must read variables */ if (G_getenv_nofatal("DEBUG")) { G_putenv("DEBUG", G_getenv_nofatal("DEBUG")); } else { G_putenv("DEBUG", "0"); } G_putenv("GISDBASE", G_getenv_nofatal("GISDBASE")); G_putenv("LOCATION_NAME", G_getenv_nofatal("LOCATION_NAME")); G_putenv("MAPSET", G_getenv_nofatal("MAPSET")); } else { /* Warning: GISRC_MODE_MEMORY _must_ be set to G_GISRC_MODE_FILE, because the module can be * run from an application which previously set environment variable to G_GISRC_MODE_MEMORY */ sprintf(ebuf, "%d", G_GISRC_MODE_FILE); G_putenv("GRASS_DB_DRIVER_GISRC_MODE", ebuf); } /* read the dbmscap file */ if (NULL == (list = db_read_dbmscap())) return (dbDriver *) NULL; /* if name is empty use connection.driverName, added by RB 4/2000 */ if (name == '\0') { db_get_connection(&connection); if (NULL == (name = connection.driverName)) return (dbDriver *) NULL; } /* find this system name */ for (cur = list; cur; cur = cur->next) if (strcmp(cur->driverName, name) == 0) break; if (cur == NULL) { char msg[256]; db_free_dbmscap(list); sprintf(msg, "%s: no such driver available", name); db_error(msg); return (dbDriver *) NULL; } /* allocate a driver structure */ driver = (dbDriver *) db_malloc(sizeof(dbDriver)); if (driver == NULL) { db_free_dbmscap(list); return (dbDriver *) NULL; } /* copy the relevant info from the dbmscap entry into the driver structure */ db_copy_dbmscap_entry(&driver->dbmscap, cur); startup = driver->dbmscap.startup; /* free the dbmscap list */ db_free_dbmscap(list); /* run the driver as a child process and create pipes to its stdin, stdout */ #ifdef __MINGW32__ #define pipe(fds) _pipe(fds, 250000, _O_BINARY | _O_NOINHERIT) #endif /* open the pipes */ if ((pipe(p1) < 0) || (pipe(p2) < 0)) { db_syserror("can't open any pipes"); return (dbDriver *) NULL; } close_on_exec(p1[READ]); close_on_exec(p1[WRITE]); close_on_exec(p2[READ]); close_on_exec(p2[WRITE]); pid = G_spawn_ex(startup, SF_BACKGROUND, SF_REDIRECT_DESCRIPTOR, 0, p1[READ], SF_CLOSE_DESCRIPTOR, p1[WRITE], SF_REDIRECT_DESCRIPTOR, 1, p2[WRITE], SF_CLOSE_DESCRIPTOR, p2[READ], startup, NULL); /* create a child */ if (pid < 0) { db_syserror("can't create fork"); return (dbDriver *) NULL; } close(p1[READ]); close(p2[WRITE]); /* record driver process id in driver struct */ driver->pid = pid; /* convert pipes to FILE* */ driver->send = fdopen(p1[WRITE], "wb"); driver->recv = fdopen(p2[READ], "rb"); /* most systems will have to use unbuffered io to get the send/recv to work */ #ifndef USE_BUFFERED_IO setbuf(driver->send, NULL); setbuf(driver->recv, NULL); #endif db__set_protocol_fds(driver->send, driver->recv); if (db__recv_return_code(&stat) != DB_OK || stat != DB_OK) driver = NULL; return driver; }