/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- dbeng_config_read
- dbeng_config_get_tmp_path
- dbeng_config_get_log
- dbeng_config_is_session
- dbeng_config_is_catalog
- dbeng_config_get_session
- dbeng_config_get_catalog
- dbeng_config_get_log_flag
- dbeng_config_get_session_flag
- dbeng_config_get_catalog_flag
- dbeng_config_get_replicate_flag
- dbeng_config_get_version
- dbeng_config_set_tmp_path
- dbeng_config_set_log
- dbeng_config_set_session
- dbeng_config_set_catalog
- dbeng_config_set_log_flag
- dbeng_config_set_session_flag
- dbeng_config_set_catalog_flag
- dbeng_config_set_replicate_flag
- dbeng_config_valid_tmp_path
- dbeng_config_valid_session
- dbeng_config_valid_catalog
/* DBENG (Bbuuzzb) configuration module. This module reads the
settings in the DBENG config file (DBENG_CONFIG_FILE).
This module also provides the 'get' and 'set' low level
access functions. Used in single user database applications
and the database server.
Rick Smereka, Copyright (C) 1998-2004.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, get a copy via the Internet at
http://gnu.org/copyleft/gpl.html or write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
You can contact the author via email at rsmereka@future-lab.com
The DBENG config file is a normal ASCII file that can
contain the following settings:
tmp_path path
log file
session_table file
catalog file
'tmp_path' specifies the complete path to use for
DBENG temporary files. If not specified, the
path used will be 'DBENG_DEFAULT_TMP_PATH'.
'log' is the path and file name of the
DBENG error log. If not specified, the file
used will be 'DBENG_DEFAULT_LOG'.
'session_table' is the path and file name of
the system session table. If not specified,
the file used will be 'DBENG_DEFAULT_SESSION_TABLE'.
'catalog' is the path and file name of the
system catalog. If not specified, the file
used will be 'DBENG_DEFAULT_CATALOG'.
The session table is only used with
the c/s version. It is currently used by 'dbsrv'.
All data on the configuration lines after the
required parameters and all lines not containing
a valid keyword will be ignored.
Original QNX version, Dec/98, Rick Smereka
Ported to 32bit Windows under CodeWarrior V4.
Jan/99, Rick Smereka
Moved global configuration data from 'dbeng.c' into
this module. Also moved 'get' functions and wrote
'set' functions. Wrote 'valid' functions.
Ported to HP-UX under GNU C 2.8.1.
Feb/99, Rick Smereka
Added session table and catalog functions and put
them on conditional compile only with the multiuser
define. Changed 'error_log' to 'log'. Added on/off
switches for the log, session table and catalog
along with 'get' and 'set' functions.
Mar/99, Rick Smereka
Added support for obtaining the Bbuuzzb version ID.
Apr/99, Rick Smereka
Ported to Red Hat Linux 5.2, Jul/99, Rick Smereka
Added include of 'flsocket.h'. Mar/2000, Rick Smereka
Added include of 'dbeng.h'. Feb/2001, Rick Smereka
Changed 'session_flag' and 'catalog_flag' default values
to 'FALSE'. Jun/2001, Rick Smereka
Changed function 'dbeng_config_is_systable' to detect temporary
tables. Oct/2001, Rick Smereka
Added member 'replicate_flag' to configuration structure. Added
functions 'dbeng_config_get_replicate_flag' and
'dbeng_config_set_replicate_flag'. Jan/2002, Rick Smereka
Added function 'dbeng_config_is_session' and deleted the
function 'dbeng_is_systable'. System tables are now
recognized by the 'is_systable' flag in the 'dbeng_table'
structure. Feb/2002, Rick Smereka
Added function 'dbeng_config_is_catalog'. Jun/2002,
Rick Smereka
Changed function 'dbeng_config_set_session_flag' to flush
the session table by calling 'dbeng_session_flush_all' when
the session flag is set high. Jul/2002, Rick Smereka
Ported to Debian Linux. Nov/2002, Rick Smereka
Changed 'dbeng_config' structure to always contain catalog
information and enabled config catalog functions
in both single user apps and the database server. Nov/2003,
Rick Smereka
Modified 'dbeng_config_read' to automatically enable the catalog
in single user mode if a catalog table was supplied in the config
file. Feb/2004, Rick Smereka
Changed all logging calls from 'sys_log' to 'logman'.
Changed function 'dbeng_config_set_log' so that it no longer
attempts to validate the path/file name of the log.
Changed function 'dbeng_config_set_log_flag' so that it
activates or de-activates logging.
Added include of 'appinit.h'.
Removed private function 'dbeng_config_valid_log'.
Mar/2004, Rick Smereka */
#include "stdhead.h"
#include "dbeng.h"
#include "dbmess.h"
#include "dblocal.h"
#include "dbengcfg.h"
#include "dbengver.h"
#include "dbiocode.h"
#ifndef OS_DOS
#include "appinit.h"
#endif
/* global configuration data */
struct
{
char *tmp_path;
char *log;
int log_flag;
char *catalog;
int catalog_flag;
#ifdef MULTIUSER
char *session_table;
int session_flag;
int replicate_flag;
} dbeng_config = {(char *)NULL, (char *)NULL, FALSE, (char *)NULL, FALSE,
(char *)NULL, FALSE, FALSE};
#else
} dbeng_config = {(char *)NULL, (char *)NULL, FALSE, (char *)NULL, FALSE};
#endif
/* private functions */
static int dbeng_config_valid_tmp_path(char *);
static int dbeng_config_valid_catalog(char *);
#ifdef MULTIUSER
static int dbeng_config_valid_session(char *);
#endif
int dbeng_config_read(char *fname)
{
/* Read and parse the DBENG config file 'fname'.
Upon successful completion, the global configuration
data will be loaded from the file. Note that missing
data will be filled in from default data as defined
in 'dbengcfg.h'. Function returns a 'dbeng' code. */
FILE *in;
char *line, *word, *ucase_word;
char mname[25];
int nwords;
int ret;
strcpy(mname, "dbeng_config_read");
logman("%s:enter", mname);
/* attempt to open config file, if not found, attempt
to load compiled defaults and exit */
if ((in = fopen(fname, "r")) == (FILE *)NULL)
{
if ((ret = dbeng_config_set_tmp_path(DBENG_DEFAULT_TMP_PATH)) !=
DBENG_OK)
{
dbeng_io_code_log(mname,
"exit:bad ret from dbeng_config_set_tmp_path",
ret);
return(ret);
}
if ((ret = dbeng_config_set_log(DBENG_DEFAULT_LOG)) !=
DBENG_OK)
{
dbeng_io_code_log(mname,
"exit:bad ret from dbeng_config_set_log", ret);
return(ret);
}
#ifdef MULTIUSER
if ((ret = dbeng_config_set_session(DBENG_DEFAULT_SESSION))
!= DBENG_OK)
{
dbeng_io_code_log(mname,
"exit:bad ret from dbeng_config_set_session_table",
ret);
return(ret);
}
#endif
if ((ret = dbeng_config_set_catalog(DBENG_DEFAULT_CATALOG)) != DBENG_OK)
{
dbeng_io_code_log(mname,
"exit:bad ret from dbeng_config_set_catalog",
ret);
return(ret);
}
dbeng_io_code_log(mname, "exit:no config file, loaded defaults",
DBENG_CONFIG_UNABLE_TO_OPEN);
return(DBENG_CONFIG_UNABLE_TO_OPEN);
}
/* alloc line buffer */
if ((line = (char *)malloc(BUFSIZE)) == (char *)NULL)
{
fclose(in);
dbeng_io_code_log(mname, "alloc fail[line]", DBENG_MEMORY_FAIL);
return(DBENG_MEMORY_FAIL);
}
/* get first record/line */
get_rec(in, line);
while(!feof(in))
{
/* number of command words on line */
nwords = command_words(line);
/* must have at least two command words per record */
if (nwords < 2)
{
free(line);
fclose(in);
dbeng_io_code_log(mname, "exit:missing parameter",
DBENG_CONFIG_PARAMETER_MISSING);
return(DBENG_CONFIG_PARAMETER_MISSING);
}
/* create word string by dynamically copying and
set length to zero */
word = initstring(line);
word[0] = EOS;
/* get first command word on line */
if (!command_word(line, word, 1))
{
free(word);
free(line);
fclose(in);
dbeng_io_code_log(mname, "exit:command_word[1] fail",
DBENG_INTERNAL_ERROR);
return(DBENG_INTERNAL_ERROR);
}
/* make another copy and convert it to upper case */
ucase_word = initstring(word);
ucase_word[0] = EOS;
ucase(word, ucase_word);
/* is it the 'tmp_path' keyword? */
if (!strcmp(ucase_word, "TMP_PATH"))
{
word[0] = EOS;
/* get second command word */
if (!command_word(line, word, 2))
{
free(word);
free(line);
free(ucase_word);
fclose(in);
dbeng_io_code_log(mname, "exit:command_word[2,tmp_path] fail",
DBENG_INTERNAL_ERROR);
return(DBENG_INTERNAL_ERROR);
}
/* set path */
if ((ret = dbeng_config_set_tmp_path(word)) != DBENG_OK)
{
free(word);
free(line);
free(ucase_word);
fclose(in);
dbeng_io_code_log(mname, "exit:bad ret dbeng_config_set_tmp_path",
ret);
return(ret);
}
}
/* is it the 'log' keyword? */
if (!strcmp(ucase_word, "LOG"))
{
word[0] = EOS;
if (!command_word(line, word, 2))
{
free(word);
free(line);
free(ucase_word);
fclose(in);
dbeng_io_code_log(mname, "exit:command_word[2,log] fail",
DBENG_INTERNAL_ERROR);
return(DBENG_INTERNAL_ERROR);
}
/* set log name */
if ((ret = dbeng_config_set_log(word)) != DBENG_OK)
{
free(word);
free(line);
free(ucase_word);
fclose(in);
dbeng_io_code_log(mname, "exit:bad ret dbeng_config_set_log", ret);
return(ret);
}
}
#ifdef MULTIUSER
/* is it the 'session_table' keyword?
which is valid only for the database
server */
if (!strcmp(ucase_word, "SESSION_TABLE"))
{
word[0] = EOS;
if (!command_word(line, word, 2))
{
free(word);
free(line);
free(ucase_word);
fclose(in);
dbeng_io_code_log(mname, "exit:command_word[2,session_table] fail",
DBENG_INTERNAL_ERROR);
return(DBENG_INTERNAL_ERROR);
}
if ((ret = dbeng_config_set_session(word)) != DBENG_OK)
{
free(word);
free(line);
free(ucase_word);
fclose(in);
dbeng_io_code_log(mname,
"exit:bad ret dbeng_config_set_session",
ret);
return(ret);
}
}
#endif
// is it the 'catalog' keyword?
if (!strcmp(ucase_word, "CATALOG"))
{
word[0] = EOS;
if (!command_word(line, word, 2))
{
free(word);
free(line);
free(ucase_word);
fclose(in);
dbeng_io_code_log(mname, "exit:command_word[2,catalog] fail",
DBENG_INTERNAL_ERROR);
return(DBENG_INTERNAL_ERROR);
}
/* set error log path/name */
if ((ret = dbeng_config_set_catalog(word)) != DBENG_OK)
{
free(word);
free(line);
free(ucase_word);
fclose(in);
dbeng_io_code_log(mname, "exit:bad ret dbeng_config_set_catalog",
ret);
return(ret);
}
}
// dealloc temp vars
free(word);
free(ucase_word);
// get next record
get_rec(in, line);
}
fclose(in);
free(line);
/* handle defaults in the case of missing data */
if (dbeng_config.tmp_path == (char *)NULL)
if ((ret = dbeng_config_set_tmp_path(DBENG_DEFAULT_TMP_PATH)) !=
DBENG_OK)
{
dbeng_io_code_log(mname, "exit:bad ret dbeng_config_set_tmp_path",
ret);
return(ret);
}
if (dbeng_config.log == (char *)NULL)
if ((ret = dbeng_config_set_log(DBENG_DEFAULT_LOG)) !=
DBENG_OK)
{
dbeng_io_code_log(mname, "exit:bad ret dbeng_config_set_log",
ret);
return(ret);
}
#ifdef MULTIUSER
if (dbeng_config.session_table == (char *)NULL)
if ((ret = dbeng_config_set_session(DBENG_DEFAULT_SESSION))
!= DBENG_OK)
{
dbeng_io_code_log(mname, "exit:bad ret dbeng_config_set_session",
ret);
return(ret);
}
/* we set the default if no catalog given for the database
server, single user apps will have no default if no
catalog is given */
if (dbeng_config.catalog == (char *)NULL)
if ((ret = dbeng_config_set_catalog(DBENG_DEFAULT_CATALOG))
!= DBENG_OK)
{
dbeng_io_code_log(mname, "exit:bad ret dbeng_config_set_catalog",
ret);
return(ret);
}
#else
/* single user apps have the catalog enabled if it was
supplied in the config file */
if (dbeng_config.catalog != (char *)NULL)
if ((ret = dbeng_config_set_catalog_flag(TRUE)) != DBENG_OK)
{
dbeng_io_code_log(mname, "exit:bad rc from "
"dbeng_config_set_catalog_flag", ret);
return(ret);
}
#endif
dbeng_io_code_log(mname, "normal exit", DBENG_OK);
return(DBENG_OK);
}
int dbeng_config_get_tmp_path(char *path)
{
/* Load the global 'dbeng_config.tmp_path' into 'path' which
must already be allocated to sufficient size.
Function returns 'DBENG_OK' upon success,
an engine i/o code otherwise. */
char mname[30];
strcpy(mname, "dbeng_config_get_tmp_path");
logman("%s:enter", mname);
if (path == (char *)NULL)
{
dbeng_io_code_log(mname, "exit:[path]null", DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
/* if global tmp path has not been loaded, it is an error */
if (dbeng_config.tmp_path == (char *)NULL)
{
dbeng_io_code_log(mname, "exit:tmp path not loaded",
DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
strcpy(path, dbeng_config.tmp_path);
dbeng_io_code_log(mname, "normal exit", DBENG_OK);
return(DBENG_OK);
}
int dbeng_config_get_log(char *slog)
{
/* Load the global 'dbeng_config.log' into 'slog'
which must already be allocated to sufficient size.
Function returns 'DBENG_OK' upon success,
an engine i/o code otherwise. */
char mname[25];
strcpy(mname, "dbeng_config_get_log");
logman("%s:enter", mname);
if (slog == (char *)NULL)
{
dbeng_io_code_log(mname, "exit:[slog]null", DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
/* if log name has not been loaded, it is an error */
if (dbeng_config.log == (char *)NULL)
{
dbeng_io_code_log(mname, "exit:log not loaded", DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
strcpy(slog, dbeng_config.log);
dbeng_io_code_log(mname, "normal exit", DBENG_OK);
return(DBENG_OK);
}
#ifdef MULTIUSER
int dbeng_config_is_session(char *fname)
{
/* Determine whether 'fname' is the session table. Function
returns 'TRUE' if the session table was found, 'FALSE'
otherwise. */
char mname[] = "dbeng_config_is_session", ses_table[128];
int session_flag;
if (fname == (char *)NULL || !strlen(fname))
{
logman("%s:exit[FALSE]:null or empty[fname]", mname);
return(FALSE);
}
logman("%s:enter:fname=%s,l=%d", mname, fname, strlen(fname));
(void)dbeng_config_get_session_flag(&session_flag);
/* if session table is not active, cannot be the session table
even if the name matches */
if (!session_flag)
{
logman("%s:exit[FALSE]:session table not active", mname);
return(FALSE);
}
(void)dbeng_config_get_session(ses_table);
if (!strcmp(fname, ses_table))
{
logman("%s:exit[TRUE]:matches session table", mname);
return(TRUE);
}
logman("%s:exit[FALSE]:no match", mname);
return(FALSE);
}
#endif
int dbeng_config_is_catalog(char *fname)
{
/* Determine whether 'fname' is the catalog. Function
returns 'TRUE' if the catalog was found, 'FALSE'
otherwise. */
char mname[] = "dbeng_config_is_catalog", cat[128];
int catalog_flag;
if (fname == (char *)NULL || !strlen(fname))
{
logman("%s:exit[FALSE]:null or empty[fname]", mname);
return(FALSE);
}
logman("%s:enter:fname=%s,l=%d", mname, fname, strlen(fname));
(void)dbeng_config_get_catalog_flag(&catalog_flag);
cat[0] = EOS;
/* if catalog is not active, cannot be the catalog
even if the name matches */
if (!catalog_flag)
{
logman("%s:exit[FALSE]:catalog not active", mname);
return(FALSE);
}
(void)dbeng_config_get_catalog(cat);
if (!strcmp(fname, cat))
{
logman("%s:exit[TRUE]:matches catalog", mname);
return(TRUE);
}
logman("%s:exit[FALSE]:no match", mname);
return(FALSE);
}
#ifdef MULTIUSER
int dbeng_config_get_session(char *ses_table)
{
/* Load the global 'dbeng_config.session_table' into 'ses_table'
which must already be allocated to sufficient size.
Function returns 'DBENG_OK' upon success,
an engine i/o code otherwise. */
char mname[35];
strcpy(mname, "dbeng_config_get_session");
logman("%s:enter", mname);
if (ses_table == (char *)NULL)
{
dbeng_io_code_log(mname, "exit:[ses_table]null", DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
/* if session table path/name has not been loaded, it is an error */
if (dbeng_config.session_table == (char *)NULL)
{
dbeng_io_code_log(mname, "exit:session table not loaded",
DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
strcpy(ses_table, dbeng_config.session_table);
dbeng_io_code_log(mname, "normal exit", DBENG_OK);
return(DBENG_OK);
}
#endif
int dbeng_config_get_catalog(char *cat)
{
/* Load the global 'dbeng_config.catalog' into 'cat'
which must already be allocated to sufficient size.
Function returns 'DBENG_OK' upon success,
an engine i/o code otherwise. */
char mname[30];
strcpy(mname, "dbeng_config_get_catalog");
logman("%s:enter", mname);
if (cat == (char *)NULL)
{
dbeng_io_code_log(mname, "exit:[cat]null", DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
// if catalog path/name has not been loaded, catalog is not in use
if (dbeng_config.catalog == (char *)NULL)
{
dbeng_io_code_log(mname, "exit:catalog not loaded",
DBENG_NO_CATALOG);
return(DBENG_NO_CATALOG);
}
strcpy(cat, dbeng_config.catalog);
dbeng_io_code_log(mname, "normal exit", DBENG_OK);
return(DBENG_OK);
}
int dbeng_config_get_log_flag(int *flag)
{
/* Get the value of 'dbeng_config.log_flag' and load
the value into 'flag'. Function returns 'DBENG_OK'
upon success, an engine i/o code otherwise. */
char mname[30];
strcpy(mname, "dbeng_config_get_log_flag");
logman("%s:enter", mname);
if (flag == (int *)NULL)
{
dbeng_io_code_log(mname, "exit:[flag] is null", DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
*flag = dbeng_config.log_flag;
dbeng_io_code_log(mname, "normal exit", DBENG_OK);
return(DBENG_OK);
}
#ifdef MULTIUSER
int dbeng_config_get_session_flag(int *flag)
{
/* Get the value of 'dbeng_config.session_flag' and load
the value into 'flag'. Function returns 'DBENG_OK'
upon success, an engine i/o code otherwise. */
char mname[] = "dbeng_config_get_session_flag";
logman("%s:enter", mname);
if (flag == (int *)NULL)
{
dbeng_io_code_log(mname, "exit:[flag] is null", DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
*flag = dbeng_config.session_flag;
logman("%s:normal exit[0],flag=%d", mname, *flag);
return(DBENG_OK);
}
#endif
int dbeng_config_get_catalog_flag(int *flag)
{
/* Get the value of 'dbeng_config.catalog_flag' and load
the value into 'flag'. Function returns 'DBENG_OK'
upon success, an engine i/o code otherwise. */
char mname[35];
strcpy(mname, "dbeng_config_get_catalog_flag");
logman("%s:enter", mname);
if (flag == (int *)NULL)
{
dbeng_io_code_log(mname, "exit:[flag] is null", DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
*flag = dbeng_config.catalog_flag;
logman("%s:normal exit[0],flag=%d", mname, *flag);
return(DBENG_OK);
}
#ifdef MULTIUSER
int dbeng_config_get_replicate_flag(int *flag)
{
/* Get the value of 'dbeng_config.replicate_flag' and load
the value into 'flag'. Function returns 'DBENG_OK'
upon success, an engine i/o code otherwise. */
char mname[] = "dbeng_config_get_replicate_flag";
logman("%s:enter", mname);
if (flag == (int *)NULL)
{
dbeng_io_code_log(mname, "exit:[flag] is null", DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
*flag = dbeng_config.replicate_flag;
logman("%s:normal exit[0],flag=%d", mname, *flag);
return(DBENG_OK);
}
#endif
int dbeng_config_get_version(char *ver)
{
/* Get the 'dbeng' version ID string. Function returns
'DBENG_OK' upon success with the version ID
loaded into 'ver' which must already be allocated
to sufficient size. Function returns a 'dbeng'
i/o code otherwise. */
char mname[] = "dbeng_config_get_version";
logman("%s:enter", mname);
if (ver == (char *)NULL)
{
dbeng_io_code_log(mname, "exit:[ver]is null", DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
strcpy(ver, DBENG_VERSION);
dbeng_io_code_log(mname, "normal exit", DBENG_OK);
return(DBENG_OK);
}
int dbeng_config_set_tmp_path(char *path)
{
/* Load 'dbeng_config.tmp_path' with data from 'path'.
'dbeng_config.tmp_path' is dynamically allocated.
Function returns a 'dbeng' i/o code. */
char mname[] = "dbeng_config_set_tmp_path";
int len;
int ret;
logman("%s:enter", mname);
if (path == (char *)NULL)
{
dbeng_io_code_log(mname, "exit:[path]null", DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
len = strlen(path);
if (!len)
{
dbeng_io_code_log(mname, "exit:[path]empty", DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
if (len >= DBENG_PATH_LIMIT)
{
dbeng_io_code_log(mname, "exit:[path]too large",
DBENG_CONFIG_TMP_PATH_SIZE);
return(DBENG_CONFIG_TMP_PATH_SIZE);
}
if ((ret = dbeng_config_valid_tmp_path(path)) != DBENG_OK)
{
dbeng_io_code_log(mname, "exit:bad ret dbeng_config_valid_tmp_path",
ret);
return(ret);
}
if (dbeng_config.tmp_path != (char *)NULL)
free(dbeng_config.tmp_path);
if ((dbeng_config.tmp_path = (char *)malloc(len + 1)) == (char *)NULL)
{
dbeng_io_code_log(mname, "exit:alloc fail[dbeng_config.tmp_path]",
DBENG_MEMORY_FAIL);
return(DBENG_MEMORY_FAIL);
}
strcpy(dbeng_config.tmp_path, path);
dbeng_io_code_log(mname, "normal exit", DBENG_OK);
return(DBENG_OK);
}
int dbeng_config_set_log(char *slog)
{
/* Load 'dbeng_config.log' with data from 'slog'.
'dbeng_config.log' is dynamically allocated.
Function returns a 'dbeng' i/o code. */
char mname[] = "dbeng_config_set_log";
int len;
logman("%s:enter", mname);
if (slog == (char *)NULL)
{
dbeng_io_code_log(mname, "exit:[slog]null", DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
len = strlen(slog);
if (!len)
{
dbeng_io_code_log(mname, "exit:[slog]empty", DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
if (len >= DBENG_PATH_LIMIT)
{
dbeng_io_code_log(mname, "exit:[slog]too large",
DBENG_CONFIG_LOG_SIZE);
return(DBENG_CONFIG_LOG_SIZE);
}
if (dbeng_config.log != (char *)NULL)
free(dbeng_config.log);
if ((dbeng_config.log = (char *)malloc(len + 1)) == (char *)NULL)
{
dbeng_io_code_log(mname, "exit:alloc fail[dbeng_config.log]",
DBENG_MEMORY_FAIL);
return(DBENG_MEMORY_FAIL);
}
strcpy(dbeng_config.log, slog);
dbeng_io_code_log(mname, "normal exit", DBENG_OK);
return(DBENG_OK);
}
#ifdef MULTIUSER
int dbeng_config_set_session(char *ses_table)
{
/* Load 'dbeng_config.session_table' with data from 'ses_table'.
'dbeng_config.session_table' is dynamically allocated.
If the file does not already exist, an attempt will be
made to create it. Function returns a 'dbeng' i/o code. */
char mname[35];
int len;
int ret;
strcpy(mname, "dbeng_config_set_session");
logman("%s:enter", mname);
if (ses_table == (char *)NULL)
{
dbeng_io_code_log(mname, "exit:[ses_table]null", DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
len = strlen(ses_table);
if (!len)
{
dbeng_io_code_log(mname, "exit:[ses_table]empty",
DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
if (len >= DBENG_PATH_LIMIT)
{
dbeng_io_code_log(mname, "exit:[slog]too large",
DBENG_CONFIG_SESSION_TABLE_SIZE);
return(DBENG_CONFIG_SESSION_TABLE_SIZE);
}
/* attempt to create the file if it does not exist */
if (!exist(ses_table))
if (!zcreate(ses_table))
{
dbeng_io_code_log(mname, "exit:cannot create session table",
DBENG_CANNOT_CREATE_TABLE);
return(DBENG_CANNOT_CREATE_TABLE);
}
if ((ret = dbeng_config_valid_session(ses_table)) != DBENG_OK)
{
dbeng_io_code_log(mname, "exit:bad ret dbeng_config_valid_session", ret);
return(ret);
}
if (dbeng_config.session_table != (char *)NULL)
free(dbeng_config.session_table);
if ((dbeng_config.session_table = (char *)malloc(len + 1)) == (char *)NULL)
{
dbeng_io_code_log(mname, "exit:alloc fail[dbeng_config.session_table]",
DBENG_MEMORY_FAIL);
return(DBENG_MEMORY_FAIL);
}
strcpy(dbeng_config.session_table, ses_table);
dbeng_io_code_log(mname, "normal exit", DBENG_OK);
return(DBENG_OK);
}
#endif
int dbeng_config_set_catalog(char *cat)
{
/* Load 'dbeng_config.catalog' with data from 'cat'.
'dbeng_config.catalog' is dynamically allocated.
The catalog file must exist. Function returns a
'dbeng' i/o code. */
char mname[30];
int len;
int ret;
strcpy(mname, "dbeng_config_set_catalog");
logman("%s:enter", mname);
if (cat == (char *)NULL)
{
dbeng_io_code_log(mname, "exit:[cat]null", DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
len = strlen(cat);
if (!len)
{
dbeng_io_code_log(mname, "exit:[cat]empty", DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
if (len >= DBENG_PATH_LIMIT)
{
dbeng_io_code_log(mname, "exit:[cat]too large",
DBENG_CONFIG_INVALID_CATALOG);
return(DBENG_CONFIG_INVALID_CATALOG);
}
if ((ret = dbeng_config_valid_catalog(cat)) != DBENG_OK)
{
dbeng_io_code_log(mname, "exit:bad ret dbeng_config_valid_catalog",
ret);
return(ret);
}
if (dbeng_config.catalog != (char *)NULL)
free(dbeng_config.catalog);
if ((dbeng_config.catalog = (char *)malloc(len + 1)) == (char *)NULL)
{
dbeng_io_code_log(mname, "exit:alloc fail[dbeng_config.catalog]",
DBENG_MEMORY_FAIL);
return(DBENG_MEMORY_FAIL);
}
strcpy(dbeng_config.catalog, cat);
dbeng_io_code_log(mname, "normal exit", DBENG_OK);
return(DBENG_OK);
}
int dbeng_config_set_log_flag(int flag)
{
/* Set 'dbeng_config.log_flag' to the value of
'flag' which must be zero or one and activate
or de-activate logging. Function
returns 'DBENG_OK' upon success, an
engine i/o code otherwise. */
char mname[] = "dbeng_config_set_log_flag";
char *ap;
logman("%s:enter", mname);
if (flag != TRUE && flag != FALSE)
{
dbeng_io_code_log(mname, "exit:[flag]not 0 or 1", DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
if (flag)
{
if ((ap = (char *)malloc(DBENG_PATH_LIMIT)) == (char *)NULL)
{
dbeng_io_code_log(mname, "exit:alloc fail[ap]", DBENG_MEMORY_FAIL);
return(DBENG_MEMORY_FAIL);
}
#ifndef OS_DOS
if (!appinit_get_name(ap))
{
free(ap);
dbeng_io_code_log(mname, "exit:bad rc[FALSE] from appinit_get_name",
DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
#else
ap[0] = EOS;
#endif
if (logman_start(dbeng_config.log, ap))
{
free(ap);
dbeng_io_code_log(mname, "exit:bad rc[TRUE] from logman_start",
DBENG_CONFIG_INVALID_LOG);
return(DBENG_CONFIG_INVALID_LOG);
}
free(ap);
}
else
logman_end();
dbeng_config.log_flag = flag;
dbeng_io_code_log(mname, "normal exit", DBENG_OK);
return(DBENG_OK);
}
#ifdef MULTIUSER
int dbeng_config_set_session_flag(int flag)
{
/* Set 'dbeng_config.session_flag' to the value of
'flag' which must be zero or one. The session
table will be flushed when the session flag
is set to on. Function returns 'DBENG_OK' upon
success, an engine i/o code otherwise. */
char mname[] = "dbeng_config_set_session_flag";
int ret;
logman("%s:enter", mname);
if (flag != TRUE && flag != FALSE)
{
dbeng_io_code_log(mname, "exit:[flag]not 0 or 1", DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
dbeng_config.session_flag = flag;
if (flag)
if ((ret = dbeng_session_flush_all()) != DBENG_OK)
dbeng_io_code_log(mname, "bad rc from dbeng_session_flush_all", ret);
dbeng_io_code_log(mname, "normal exit", DBENG_OK);
return(DBENG_OK);
}
#endif
int dbeng_config_set_catalog_flag(int flag)
{
/* Set 'dbeng_config.catalog_flag' to the value of
'flag' which must be zero or one. Function
returns 'DBENG_OK' upon success, an
engine i/o code otherwise. */
char mname[30];
strcpy(mname, "dbeng_config_set_catalog_flag");
logman("%s:enter", mname);
if (flag != TRUE && flag != FALSE)
{
dbeng_io_code_log(mname, "exit:[flag]not 0 or 1", DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
// if activating catalog, make sure catalog name is loaded
if (flag == TRUE)
if (dbeng_config.catalog == (char *)NULL || !strlen(dbeng_config.catalog))
{
dbeng_io_code_log(mname, "exit:no catalog name", DBENG_NO_CATALOG);
return(DBENG_NO_CATALOG);
}
dbeng_config.catalog_flag = flag;
dbeng_io_code_log(mname, "normal exit", DBENG_OK);
return(DBENG_OK);
}
#ifdef MULTIUSER
int dbeng_config_set_replicate_flag(int flag)
{
/* Set 'dbeng_config.replicate_flag' to the value of
'flag' which must be zero or one. Catalog must also
be active to activate replication. Function
returns 'DBENG_OK' upon success, an
engine i/o code otherwise. */
char mname[] = "dbeng_config_set_replicate_flag";
logman("%s:enter", mname);
if (flag != TRUE && flag != FALSE)
{
dbeng_io_code_log(mname, "exit:[flag]not 0 or 1", DBENG_INVALID_FUNCTION);
return(DBENG_INVALID_FUNCTION);
}
if (flag && !dbeng_config.catalog_flag)
{
dbeng_io_code_log(mname, "exit:catalog not active", DBENG_ACCESS_DENIED);
return(DBENG_ACCESS_DENIED);
}
dbeng_config.replicate_flag = flag;
dbeng_io_code_log(mname, "normal exit", DBENG_OK);
return(DBENG_OK);
}
#endif
static int dbeng_config_valid_tmp_path(char *path)
{
/* Validate the temporary 'path' by attempting
to open a file for writing. Function
returns 'DBENG_OK' upon success, an engine
code otherwise. */
FILE *tst;
char mname[30];
char rname[15], *tname;
strcpy(mname, "dbeng_config_valid_tmp_path");
logman("%s:enter", mname);
if (path == (char *)NULL || !strlen(path))
{
dbeng_io_code_log(mname, "exit:[path]null or empty",
DBENG_CONFIG_INVALID_TMP_PATH);
return(DBENG_CONFIG_INVALID_TMP_PATH);
}
if (!unique(path, rname))
{
dbeng_io_code_log(mname, "bad ret unique",
DBENG_CONFIG_INVALID_TMP_PATH);
return(DBENG_CONFIG_INVALID_TMP_PATH);
}
if ((tname = (char *)malloc(DBENG_PATH_LIMIT + 16)) == (char *)NULL)
{
dbeng_io_code_log(mname, "exit:alloc fail[tname]", DBENG_MEMORY_FAIL);
return(DBENG_MEMORY_FAIL);
}
sprintf(tname, "%s%c%s", path, PATH_SEP, rname);
if ((tst = fopen(tname, "w")) == (FILE *)NULL)
{
free(tname);
dbeng_io_code_log(mname, "exit:cannot create tmp file",
DBENG_CONFIG_INVALID_TMP_PATH);
return(DBENG_CONFIG_INVALID_TMP_PATH);
}
fclose(tst);
unlink(tname);
free(tname);
dbeng_io_code_log(mname, "normal exit", DBENG_OK);
return(DBENG_OK);
}
#ifdef MULTIUSER
static int dbeng_config_valid_session(char *ses_table)
{
/* Validate the session table path/name by attempting
to open it. Function returns 'DBENG_OK' upon
success, an engine code otherwise. */
char mname[35];
int tid;
int ret;
strcpy(mname, "dbeng_config_valid_session");
logman("%s:enter", mname);
if (ses_table == (char *)NULL || !strlen(ses_table))
{
dbeng_io_code_log(mname, "exit:[ses_table]null or empty",
DBENG_CONFIG_INVALID_SESSION_TABLE);
return(DBENG_CONFIG_INVALID_SESSION_TABLE);
}
if ((ret = db_open(ses_table, &tid)) != DBENG_OK)
{
dbeng_io_code_log(mname, "exit:bad ret db_open", ret);
return(ret);
}
(void)db_close(tid);
dbeng_io_code_log(mname, "normal exit", DBENG_OK);
return(DBENG_OK);
}
#endif
static int dbeng_config_valid_catalog(char *cat)
{
/* Validate the system catalog path/name by attempting
to open it. Function returns 'DBENG_OK' upon
success, an engine code otherwise. */
char mname[30];
int tid;
int ret;
strcpy(mname, "dbeng_config_valid_catalog");
logman("%s:enter", mname);
if (cat == (char *)NULL || !strlen(cat))
{
dbeng_io_code_log(mname, "exit:[cat]null or empty",
DBENG_CONFIG_INVALID_CATALOG);
return(DBENG_CONFIG_INVALID_CATALOG);
}
if ((ret = db_open(cat, &tid)) != DBENG_OK)
{
dbeng_io_code_log(mname, "exit:bad ret db_open", ret);
return(ret);
}
(void)db_close(tid);
dbeng_io_code_log(mname, "normal exit", DBENG_OK);
return(DBENG_OK);
}