Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #3
0
/*!
  \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;
}
Exemple #4
0
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;
}
Exemple #5
0
/*!
  \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;
}
Exemple #6
0
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;
}
Exemple #7
0
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;
}
Exemple #8
0
/*!
  \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;
}