8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 22:43:03 +01:00

Extend format of firebird configuration file with a set of additional parameters for any parameter.

Use traditional firebird configuration files format in all places (intl, trace, etc.).
Add per-database configuration facility to aliases.conf (currently 15 parameters from firebird.conf).
This commit is contained in:
alexpeshkoff 2010-02-28 18:00:51 +00:00
parent d581d5384f
commit e5017f1a12
87 changed files with 1873 additions and 5923 deletions

View File

@ -1,377 +1,377 @@
<intl_module builtin>
icu_versions default
</intl_module>
intl_module = builtin {
icu_versions = default
}
<intl_module fbintl>
filename $(this)/fbintl
icu_versions default
</intl_module>
intl_module = fbintl {
filename = $(this)/fbintl
icu_versions = default
}
<charset SJIS_0208>
intl_module fbintl
collation SJIS_0208
collation SJIS_0208_UNICODE
</charset>
charset = SJIS_0208 {
intl_module = fbintl
collation = SJIS_0208
collation = SJIS_0208_UNICODE
}
<charset EUCJ_0208>
intl_module fbintl
collation EUCJ_0208
collation EUCJ_0208_UNICODE
</charset>
charset = EUCJ_0208 {
intl_module = fbintl
collation = EUCJ_0208
collation = EUCJ_0208_UNICODE
}
<charset DOS437>
intl_module fbintl
collation DOS437
collation DOS437_UNICODE
collation DB_DEU437
collation DB_ESP437
collation DB_FIN437
collation DB_FRA437
collation DB_ITA437
collation DB_NLD437
collation DB_SVE437
collation DB_UK437
collation DB_US437
collation PDOX_ASCII
collation PDOX_INTL
collation PDOX_SWEDFIN
</charset>
charset = DOS437 {
intl_module = fbintl
collation = DOS437
collation = DOS437_UNICODE
collation = DB_DEU437
collation = DB_ESP437
collation = DB_FIN437
collation = DB_FRA437
collation = DB_ITA437
collation = DB_NLD437
collation = DB_SVE437
collation = DB_UK437
collation = DB_US437
collation = PDOX_ASCII
collation = PDOX_INTL
collation = PDOX_SWEDFIN
}
<charset DOS850>
intl_module fbintl
collation DOS850
collation DOS850_UNICODE
collation DB_DEU850
collation DB_ESP850
collation DB_FRA850
collation DB_FRC850
collation DB_ITA850
collation DB_NLD850
collation DB_PTB850
collation DB_SVE850
collation DB_UK850
collation DB_US850
</charset>
charset = DOS850 {
intl_module = fbintl
collation = DOS850
collation = DOS850_UNICODE
collation = DB_DEU850
collation = DB_ESP850
collation = DB_FRA850
collation = DB_FRC850
collation = DB_ITA850
collation = DB_NLD850
collation = DB_PTB850
collation = DB_SVE850
collation = DB_UK850
collation = DB_US850
}
<charset DOS865>
intl_module fbintl
collation DOS865
collation DOS865_UNICODE
collation DB_DAN865
collation DB_NOR865
collation PDOX_NORDAN4
</charset>
charset = DOS865 {
intl_module = fbintl
collation = DOS865
collation = DOS865_UNICODE
collation = DB_DAN865
collation = DB_NOR865
collation = PDOX_NORDAN4
}
<charset ISO8859_1>
intl_module fbintl
collation ISO8859_1
collation ISO8859_1_UNICODE
collation DA_DA
collation DE_DE
collation DU_NL
collation EN_UK
collation EN_US
collation ES_ES
collation ES_ES_CI_AI
collation FI_FI
collation FR_CA
collation FR_FR
collation IS_IS
collation IT_IT
collation NO_NO
collation SV_SV
collation PT_BR
collation PT_PT
</charset>
charset = ISO8859_1 {
intl_module = fbintl
collation = ISO8859_1
collation = ISO8859_1_UNICODE
collation = DA_DA
collation = DE_DE
collation = DU_NL
collation = EN_UK
collation = EN_US
collation = ES_ES
collation = ES_ES_CI_AI
collation = FI_FI
collation = FR_CA
collation = FR_FR
collation = IS_IS
collation = IT_IT
collation = NO_NO
collation = SV_SV
collation = PT_BR
collation = PT_PT
}
<charset ISO8859_2>
intl_module fbintl
collation ISO8859_2
collation ISO8859_2_UNICODE
collation CS_CZ
collation ISO_HUN
collation ISO_PLK
</charset>
charset = ISO8859_2 {
intl_module = fbintl
collation = ISO8859_2
collation = ISO8859_2_UNICODE
collation = CS_CZ
collation = ISO_HUN
collation = ISO_PLK
}
<charset ISO8859_3>
intl_module fbintl
collation ISO8859_3
collation ISO8859_3_UNICODE
</charset>
charset = ISO8859_3 {
intl_module = fbintl
collation = ISO8859_3
collation = ISO8859_3_UNICODE
}
<charset ISO8859_4>
intl_module fbintl
collation ISO8859_4
collation ISO8859_4_UNICODE
</charset>
charset = ISO8859_4 {
intl_module = fbintl
collation = ISO8859_4
collation = ISO8859_4_UNICODE
}
<charset ISO8859_5>
intl_module fbintl
collation ISO8859_5
collation ISO8859_5_UNICODE
</charset>
charset = ISO8859_5 {
intl_module = fbintl
collation = ISO8859_5
collation = ISO8859_5_UNICODE
}
<charset ISO8859_6>
intl_module fbintl
collation ISO8859_6
collation ISO8859_6_UNICODE
</charset>
charset = ISO8859_6 {
intl_module = fbintl
collation = ISO8859_6
collation = ISO8859_6_UNICODE
}
<charset ISO8859_7>
intl_module fbintl
collation ISO8859_7
collation ISO8859_7_UNICODE
</charset>
charset = ISO8859_7 {
intl_module = fbintl
collation = ISO8859_7
collation = ISO8859_7_UNICODE
}
<charset ISO8859_8>
intl_module fbintl
collation ISO8859_8
collation ISO8859_8_UNICODE
</charset>
charset = ISO8859_8 {
intl_module = fbintl
collation = ISO8859_8
collation = ISO8859_8_UNICODE
}
<charset ISO8859_9>
intl_module fbintl
collation ISO8859_9
collation ISO8859_9_UNICODE
</charset>
charset = ISO8859_9 {
intl_module = fbintl
collation = ISO8859_9
collation = ISO8859_9_UNICODE
}
<charset ISO8859_13>
intl_module fbintl
collation ISO8859_13
collation ISO8859_13_UNICODE
collation LT_LT
</charset>
charset = ISO8859_13 {
intl_module = fbintl
collation = ISO8859_13
collation = ISO8859_13_UNICODE
collation = LT_LT
}
<charset DOS852>
intl_module fbintl
collation DOS852
collation DOS852_UNICODE
collation DB_CSY
collation DB_PLK
collation DB_SLO
collation PDOX_CSY
collation PDOX_HUN
collation PDOX_PLK
collation PDOX_SLO
</charset>
charset = DOS852 {
intl_module = fbintl
collation = DOS852
collation = DOS852_UNICODE
collation = DB_CSY
collation = DB_PLK
collation = DB_SLO
collation = PDOX_CSY
collation = PDOX_HUN
collation = PDOX_PLK
collation = PDOX_SLO
}
<charset DOS857>
intl_module fbintl
collation DOS857
collation DOS857_UNICODE
collation DB_TRK
</charset>
charset = DOS857 {
intl_module = fbintl
collation = DOS857
collation = DOS857_UNICODE
collation = DB_TRK
}
<charset DOS860>
intl_module fbintl
collation DOS860
collation DOS860_UNICODE
collation DB_PTG860
</charset>
charset = DOS860 {
intl_module = fbintl
collation = DOS860
collation = DOS860_UNICODE
collation = DB_PTG860
}
<charset DOS861>
intl_module fbintl
collation DOS861
collation DOS861_UNICODE
collation PDOX_ISL
</charset>
charset = DOS861 {
intl_module = fbintl
collation = DOS861
collation = DOS861_UNICODE
collation = PDOX_ISL
}
<charset DOS863>
intl_module fbintl
collation DOS863
collation DOS863_UNICODE
collation DB_FRC863
</charset>
charset = DOS863 {
intl_module = fbintl
collation = DOS863
collation = DOS863_UNICODE
collation = DB_FRC863
}
<charset CYRL>
intl_module fbintl
collation CYRL
collation CYRL_UNICODE
collation DB_RUS
collation PDOX_CYRL
</charset>
charset = CYRL {
intl_module = fbintl
collation = CYRL
collation = CYRL_UNICODE
collation = DB_RUS
collation = PDOX_CYRL
}
<charset DOS737>
intl_module fbintl
collation DOS737
collation DOS737_UNICODE
</charset>
charset = DOS737 {
intl_module = fbintl
collation = DOS737
collation = DOS737_UNICODE
}
<charset DOS775>
intl_module fbintl
collation DOS775
collation DOS775_UNICODE
</charset>
charset = DOS775 {
intl_module = fbintl
collation = DOS775
collation = DOS775_UNICODE
}
<charset DOS858>
intl_module fbintl
collation DOS858
collation DOS858_UNICODE
</charset>
charset = DOS858 {
intl_module = fbintl
collation = DOS858
collation = DOS858_UNICODE
}
<charset DOS862>
intl_module fbintl
collation DOS862
collation DOS862_UNICODE
</charset>
charset = DOS862 {
intl_module = fbintl
collation = DOS862
collation = DOS862_UNICODE
}
<charset DOS864>
intl_module fbintl
collation DOS864
collation DOS864_UNICODE
</charset>
charset = DOS864 {
intl_module = fbintl
collation = DOS864
collation = DOS864_UNICODE
}
<charset DOS866>
intl_module fbintl
collation DOS866
collation DOS866_UNICODE
</charset>
charset = DOS866 {
intl_module = fbintl
collation = DOS866
collation = DOS866_UNICODE
}
<charset DOS869>
intl_module fbintl
collation DOS869
collation DOS869_UNICODE
</charset>
charset = DOS869 {
intl_module = fbintl
collation = DOS869
collation = DOS869_UNICODE
}
<charset WIN1250>
intl_module fbintl
collation WIN1250
collation WIN1250_UNICODE
collation PXW_CSY
collation PXW_HUN
collation PXW_HUNDC
collation PXW_PLK
collation PXW_SLOV
collation BS_BA
collation WIN_CZ
collation WIN_CZ_CI_AI
</charset>
charset = WIN1250 {
intl_module = fbintl
collation = WIN1250
collation = WIN1250_UNICODE
collation = PXW_CSY
collation = PXW_HUN
collation = PXW_HUNDC
collation = PXW_PLK
collation = PXW_SLOV
collation = BS_BA
collation = WIN_CZ
collation = WIN_CZ_CI_AI
}
<charset WIN1251>
intl_module fbintl
collation WIN1251
collation WIN1251_UNICODE
collation PXW_CYRL
collation WIN1251_UA
</charset>
charset = WIN1251 {
intl_module = fbintl
collation = WIN1251
collation = WIN1251_UNICODE
collation = PXW_CYRL
collation = WIN1251_UA
}
<charset WIN1252>
intl_module fbintl
collation WIN1252
collation WIN1252_UNICODE
collation PXW_INTL
collation PXW_INTL850
collation PXW_NORDAN4
collation WIN_PTBR
collation PXW_SPAN
collation PXW_SWEDFIN
</charset>
charset = WIN1252 {
intl_module = fbintl
collation = WIN1252
collation = WIN1252_UNICODE
collation = PXW_INTL
collation = PXW_INTL850
collation = PXW_NORDAN4
collation = WIN_PTBR
collation = PXW_SPAN
collation = PXW_SWEDFIN
}
<charset WIN1253>
intl_module fbintl
collation WIN1253
collation WIN1253_UNICODE
collation PXW_GREEK
</charset>
charset = WIN1253 {
intl_module = fbintl
collation = WIN1253
collation = WIN1253_UNICODE
collation = PXW_GREEK
}
<charset WIN1254>
intl_module fbintl
collation WIN1254
collation WIN1254_UNICODE
collation PXW_TURK
</charset>
charset = WIN1254 {
intl_module = fbintl
collation = WIN1254
collation = WIN1254_UNICODE
collation = PXW_TURK
}
<charset NEXT>
intl_module fbintl
collation NEXT
collation NEXT_UNICODE
collation NXT_DEU
collation NXT_ESP
collation NXT_FRA
collation NXT_ITA
collation NXT_US
</charset>
charset = NEXT {
intl_module = fbintl
collation = NEXT
collation = NEXT_UNICODE
collation = NXT_DEU
collation = NXT_ESP
collation = NXT_FRA
collation = NXT_ITA
collation = NXT_US
}
<charset WIN1255>
intl_module fbintl
collation WIN1255
collation WIN1255_UNICODE
</charset>
charset = WIN1255 {
intl_module = fbintl
collation = WIN1255
collation = WIN1255_UNICODE
}
<charset WIN1256>
intl_module fbintl
collation WIN1256
collation WIN1256_UNICODE
</charset>
charset = WIN1256 {
intl_module = fbintl
collation = WIN1256
collation = WIN1256_UNICODE
}
<charset WIN1257>
intl_module fbintl
collation WIN1257
collation WIN1257_UNICODE
collation WIN1257_EE
collation WIN1257_LT
collation WIN1257_LV
</charset>
charset = WIN1257 {
intl_module = fbintl
collation = WIN1257
collation = WIN1257_UNICODE
collation = WIN1257_EE
collation = WIN1257_LT
collation = WIN1257_LV
}
<charset KSC_5601>
intl_module fbintl
collation KSC_5601
collation KSC_5601_UNICODE
collation KSC_DICTIONARY
</charset>
charset = KSC_5601 {
intl_module = fbintl
collation = KSC_5601
collation = KSC_5601_UNICODE
collation = KSC_DICTIONARY
}
<charset BIG_5>
intl_module fbintl
collation BIG_5
collation BIG_5_UNICODE
</charset>
charset = BIG_5 {
intl_module = fbintl
collation = BIG_5
collation = BIG_5_UNICODE
}
<charset GB_2312>
intl_module fbintl
collation GB_2312
collation GB_2312_UNICODE
</charset>
charset = GB_2312 {
intl_module = fbintl
collation = GB_2312
collation = GB_2312_UNICODE
}
<charset KOI8R>
intl_module fbintl
collation KOI8R
collation KOI8R_UNICODE
collation KOI8R_RU
</charset>
charset = KOI8R {
intl_module = fbintl
collation = KOI8R
collation = KOI8R_UNICODE
collation = KOI8R_RU
}
<charset KOI8U>
intl_module fbintl
collation KOI8U
collation KOI8U_UNICODE
collation KOI8U_UA
</charset>
charset = KOI8U {
intl_module = fbintl
collation = KOI8U
collation = KOI8U_UNICODE
collation = KOI8U_UA
}
<charset WIN1258>
intl_module fbintl
collation WIN1258
collation WIN1258_UNICODE
</charset>
charset = WIN1258 {
intl_module = fbintl
collation = WIN1258
collation = WIN1258_UNICODE
}
<charset TIS620>
intl_module fbintl
collation TIS620
collation TIS620_UNICODE
</charset>
charset = TIS620 {
intl_module = fbintl
collation = TIS620
collation = TIS620_UNICODE
}
<charset GBK>
intl_module fbintl
collation GBK
collation GBK_UNICODE
</charset>
charset = GBK {
intl_module = fbintl
collation = GBK
collation = GBK_UNICODE
}
<charset CP943C>
intl_module fbintl
collation CP943C ibm-943_P15A-2003
collation CP943C_UNICODE
</charset>
charset = CP943C {
intl_module = fbintl
collation = CP943C ibm-943_P15A-2003
collation = CP943C_UNICODE
}
<charset GB18030>
intl_module fbintl
collation GB18030
collation GB18030_UNICODE
</charset>
charset = GB18030 {
intl_module = fbintl
collation = GB18030
collation = GB18030_UNICODE
}

View File

@ -105,6 +105,8 @@
# paths (for Win32 this may be something like 'C:\ExternalTables',
# for unix - '/db/extern;/mnt/extern').
#
# Per-database configurable.
#
# NOTE: THE EXTERNAL TABLE ENGINE FEATURE COULD BE USED TO COMPROMISE
# THE SERVER/HOST AS WELL AS DATABASE SECURITY!!
#
@ -213,6 +215,8 @@
# SuperServer allocates 2048 pages for each database and the classic
# allocates 75 pages per client connection per database.
#
# Per-database configurable.
#
# Type: integer
#
#DefaultDbCachePages = 2048
@ -228,6 +232,8 @@
# default). To disable preallocation set DatabaseGrowthIncrement to zero.
# Shadow database files are not preallocated.
#
# Per-database configurable.
#
# Type: integer
#
#DatabaseGrowthIncrement = 134217728
@ -246,6 +252,8 @@
#
# Type: integer, measured in database pages
#
# Per-database configurable.
#
#FileSystemCacheThreshold = 65536
# ----------------------------
@ -335,6 +343,8 @@
# The smallest block size being allocated in the temporary storage.
# This value reflects the allocation granularity.
#
# Per-database configurable.
#
# Type: integer
#
#TempBlockSize = 1048576
@ -347,6 +357,8 @@
# Although it can be increased, the value applies to each client
# connection/server instance and thus consumes a lot of memory.
#
# Per-database configurable.
#
# Type: integer
#
#TempCacheLimit = 67108864
@ -360,6 +372,8 @@
# in all normal cases, so this value affects things only if something goes
# wrong. Setting it too low may degrade system performance.
#
# Per-database configurable.
#
# Type: integer
#
#DeadlockTimeout = 10
@ -374,6 +388,8 @@
# flushed, at the next transaction commit. For non-Win32 ports,
# the default value is -1 (Disabled)
#
# Per-database configurable.
#
# Type: integer
#
#MaxUnflushedWrites = 100
@ -383,6 +399,8 @@
# before they are flushed, at the next transaction commit. For non-Win32
# ports, the default value is -1 (Disabled)
#
# Per-database configurable.
#
# Type: integer
#
#MaxUnflushedWriteTime = 5
@ -549,6 +567,8 @@
# table expands dynamically up to the limit of memory. In SuperServer, the
# initial size is also the final size.
#
# Per-database configurable.
#
# Type: integer
#
#LockMemSize = 1048576
@ -566,6 +586,8 @@
# as soon as they are available; can result in lock request
# starvation.
#
# Per-database configurable.
#
# Type: integer/boolean
#
#LockGrantOrder = 1
@ -579,6 +601,8 @@
# will be made conditionally. Zero value means unconditional mode.
# Relevant only on SMP machines.
#
# Per-database configurable.
#
# Type: integer
#
#LockAcquireSpins = 0
@ -587,6 +611,8 @@
# Tune lock hash list; more hash slots mean shorter hash chains. Only
# necessary under very high load. Prime number values are recommended.
#
# Per-database configurable.
#
# Type: integer
#
#LockHashSlots = 1009
@ -595,6 +621,8 @@
#
# Bytes of shared memory allocated for event manager.
#
# Per-database configurable.
#
# Type: integer
#
#EventMemSize = 65536
@ -660,6 +688,8 @@
# Classic has by default "cooperative" policy.
# Other values are ignored by classic server build
#
# Per-database configurable.
#
# Type: string (special format)
#
#GCPolicy = combined

View File

@ -40,7 +40,8 @@ include $(ROOT)/gen/make.shared.variables
LOCKPRINT_Other_Sources = jrd/isc_sync.cpp jrd/isc.cpp jrd/db_alias.cpp \
common/config/config.cpp common/config/config_file.cpp $(OS_SPECIFIC_Sources)
common/config/config.cpp common/config/config_file.cpp common/config/ConfigCache.cpp \
$(OS_SPECIFIC_Sources)
LOCKPRINT_Files= print.cpp
LOCKPRINT_Sources = $(addprefix lock/, $(LOCKPRINT_Files)) $(LOCKPRINT_Other_Sources)
LOCKPRINT_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(LOCKPRINT_Sources)))) \
@ -59,7 +60,8 @@ CREATEDB_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(CREATEDB_So
DROP_Other_Sources = common/utils.cpp lock/lock.cpp jrd/isc_sync.cpp jrd/isc.cpp \
common/config/config.cpp common/config/config_file.cpp $(OS_SPECIFIC_Sources)
common/config/config.cpp common/config/config_file.cpp common/config/ConfigCache.cpp \
$(OS_SPECIFIC_Sources)
DROP_Files= drop.cpp
DROP_Sources = $(addprefix utilities/, $(DROP_Files)) $(DROP_Other_Sources)

View File

@ -62,7 +62,8 @@ CREATEDB_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(CREATEDB_So
DROP_Other_Sources += common/utils.cpp jrd/isc_sync.cpp jrd/isc.cpp \
common/config/config.cpp common/config/config_file.cpp $(OS_SPECIFIC_Sources)
common/config/config.cpp common/config/config_file.cpp common/config/ConfigCache.cpp \
$(OS_SPECIFIC_Sources)
DROP_Files= drop.cpp
DROP_Sources = $(addprefix utilities/, $(DROP_Files)) $(DROP_Other_Sources)
@ -71,9 +72,8 @@ DROP_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(DROP_Sources)))
GSEC_Other_Sources = jrd/enc.cpp jrd/sha.cpp jrd/guid.cpp \
jrd/isc_file.cpp common/config/config.cpp common/config/config_file.cpp \
common/config/dir_list.cpp \
jrd/ThreadData.cpp \
$(OS_SPECIFIC_Sources)
common/config/ConfigCache.cpp common/config/dir_list.cpp \
jrd/ThreadData.cpp $(OS_SPECIFIC_Sources)
GSEC_Files = gsec.cpp security.cpp call_service.cpp gsecMain.cpp
GSEC_Sources = $(addprefix utilities/gsec/, $(GSEC_Files)) $(GSEC_Other_Sources)

View File

@ -32,8 +32,7 @@
# Please don't use compiler/platform specific flags here - nmcc 02-Nov-2002
WFLAGS:=-I$(SRC_ROOT)/include/gen -I$(SRC_ROOT)/include -I$(SRC_ROOT)/vulcan \
-DNAMESPACE=Vulcan
WFLAGS:=-I$(SRC_ROOT)/include/gen -I$(SRC_ROOT)/include
ifeq ($(STD_ICU),false)
WFLAGS:= $(WFLAGS) -I$(ROOT)/extern/icu/source/common -I$(ROOT)/extern/icu/source/i18n

View File

@ -78,6 +78,7 @@ $(SRC_ROOT)/dsql/keywords.cpp: $(SRC_ROOT)/dsql/dsql.tab.h
$(OBJ)/dsql/Parser.h: $(SRC_ROOT)/dsql/dsql.tab.h
$(OBJ)/dsql/StmtNodes.o: $(SRC_ROOT)/include/gen/blrtable.h
$(OBJ)/dsql/AggNodes.o: $(SRC_ROOT)/include/gen/blrtable.h
# Special cases for building cpp from epp
$(OBJ)/dsql/metd.cpp: $(SRC_ROOT)/dsql/metd.epp

View File

@ -217,7 +217,7 @@ FBCLASSES_Objects = $(FBCLASSES_ClientObjects) $(FBCLASSES_ServerObjects) $(FBCL
#
# common/config
FBCONFIG_ClientFiles=config.cpp config_file.cpp dir_list.cpp
FBCONFIG_ClientFiles=config.cpp config_file.cpp dir_list.cpp ConfigCache.cpp
FBCONFIG_ServerFiles=
FBCONFIG_Files= $(FBCONFIG_ClientFiles) $(FBCONFIG_ServerFiles)
@ -229,10 +229,7 @@ FBCONFIG_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(FBCONFIG_So
#
# config
CONFIG_ClientFiles=AdminException.cpp Args.cpp ArgsException.cpp \
ConfObj.cpp ConfObject.cpp ConfigFile.cpp Configuration.cpp \
Element.cpp FileName.cpp InputFile.cpp \
InputStream.cpp Lex.cpp ScanDir.cpp Stream.cpp StreamSegment.cpp
CONFIG_ClientFiles=ScanDir.cpp
CONFIG_ServerFiles=
CONFIG_Files= $(CONFIG_ClientFiles) $(CONFIG_ServerFiles)
@ -244,7 +241,7 @@ CONFIG_Objects = $(addprefix $(OBJ)/, $(addsuffix .o, $(basename $(CONFIG_Source
#
# vulcan
VULCAN_ClientFiles=PathName.cpp RefObject.cpp
VULCAN_ClientFiles=
VULCAN_ServerFiles=
VULCAN_Files= $(VULCAN_ClientFiles) $(VULCAN_ServerFiles)

View File

@ -114,7 +114,7 @@ LIB_LINK_SONAME=
OS_ServerFiles=inet_server.cpp
INTL_Files2=common/utils.cpp \
common/config/config.cpp common/config/config_file.cpp \
common/config/config.cpp common/config/config_file.cpp common/config/ConfigCache.cpp \
common/classes/MsgPrint.cpp common/classes/SafeArg.cpp \
common/classes/BaseStream.cpp common/classes/fb_string.cpp \
common/classes/TempFile.cpp \

View File

@ -154,12 +154,12 @@ namespace Firebird
public:
explicit Hash(MemoryPool&)
{
memset(data, 0, sizeof data);
clean();
}
Hash()
{
memset(data, 0, sizeof data);
clean();
}
~Hash()
@ -232,6 +232,11 @@ namespace Firebird
// disable use of default operator=
Hash& operator= (const Hash&);
void clean()
{
memset(data, 0, sizeof data);
}
public:
class iterator
{

View File

@ -60,12 +60,12 @@ public:
MetaName(const char* s) { assign(s); }
MetaName(const char* s, size_t l) { assign(s, l); }
MetaName(const MetaName& m) { set(m); }
MetaName(const string& s) { assign(s.c_str(), s.length()); }
MetaName(const AbstractString& s) { assign(s.c_str(), s.length()); }
explicit MetaName(MemoryPool&) { init(); count = 0; }
MetaName(MemoryPool&, const char* s) { assign(s); }
MetaName(MemoryPool&, const char* s, size_t l) { assign(s, l); }
MetaName(MemoryPool&, const MetaName& m) { set(m); }
MetaName(MemoryPool&, const string& s) { assign(s.c_str(), s.length()); }
MetaName(MemoryPool&, const AbstractString& s) { assign(s.c_str(), s.length()); }
MetaName& assign(const char* s, size_t l);
MetaName& assign(const char* s) { return assign(s, s ? strlen(s) : 0); }

View File

@ -154,6 +154,11 @@ namespace Firebird
return ptr ? true : false;
}*/
bool hasData() const
{
return ptr ? true : false;
}
bool operator !() const
{
return !ptr;

View File

@ -83,6 +83,11 @@ public:
return ptr;
}
operator const Where*() const
{
return ptr;
}
bool operator !() const
{
return !ptr;

View File

@ -0,0 +1,81 @@
/*
* PROGRAM: JRD Access Method
* MODULE: ConfigCache.cpp
* DESCRIPTION: Base for class, representing cached config file.
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Alexander Peshkoff
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2010 Alexander Peshkoff <peshkoff@mail.ru>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
*/
#include "../common/config/ConfigCache.h"
#include "../common/config/config_file.h"
#ifndef WIN_NT
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#endif
ConfigCache::ConfigCache(Firebird::MemoryPool& p, const Firebird::PathName& fName)
: PermanentStorage(p), fileName(getPool(), fName), fileTime(0)
{ }
ConfigCache::~ConfigCache() { }
void ConfigCache::checkLoadConfig()
{
unsigned long newTime = getTime();
if (fileTime == newTime)
{
return;
}
Firebird::WriteLockGuard guard(rwLock);
// may be someone already reloaded?
newTime = getTime();
if (fileTime == newTime)
{
return;
}
fileTime = newTime;
loadConfig();
}
#ifndef WIN_NT
unsigned long ConfigCache::getTime()
{
struct stat st;
if (stat(fileName.c_str(), &st) != 0)
{
if (errno == ENOENT)
{
// config file is missing, but this is not our problem
return 0;
}
Firebird::system_call_failed::raise("stat");
}
return st.st_mtime;
}
#else // WIN_NT
error: add getTime() for windows
#endif // WIN_NT

View File

@ -0,0 +1,57 @@
/*
* PROGRAM: JRD Access Method
* MODULE: ConfigCache.h
* DESCRIPTION: Base for class, representing cached config file.
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Alexander Peshkoff
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2010 Alexander Peshkoff <peshkoff@mail.ru>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
*/
#ifndef CONFIG_CONFIG_CASHE_H
#define CONFIG_CONFIG_CASHE_H
#include "../common/classes/alloc.h"
#include "../common/classes/fb_string.h"
#include "../common/classes/rwlock.h"
class ConfigCache : public Firebird::PermanentStorage
{
public:
ConfigCache(Firebird::MemoryPool& p, const Firebird::PathName& fName);
virtual ~ConfigCache();
void checkLoadConfig();
protected:
virtual void loadConfig() = 0;
private:
unsigned long getTime();
public:
Firebird::RWLock rwLock;
Firebird::PathName fileName;
private:
unsigned long fileTime;
};
#endif // CLASSES_HASH_H

View File

@ -22,17 +22,78 @@
#include "firebird.h"
#include "../../common/config/config.h"
#include "../../common/config/config_impl.h"
#include "../../common/config/config_file.h"
#include "../../common/classes/init.h"
#include "../common/config/config.h"
#include "../common/config/config_file.h"
#include "../jrd/os/config_root.h"
#include "../common/classes/init.h"
#include "../jrd/os/fbsyslog.h"
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
// config_file works with OS case-sensitivity
typedef Firebird::PathName string;
typedef Firebird::PathName String;
namespace {
/******************************************************************************
*
* firebird.conf implementation
*/
class ConfigImpl : public ConfigRoot
{
public:
explicit ConfigImpl(Firebird::MemoryPool& p) : ConfigRoot(p)
{
try
{
root_dir = getRootDirectory();
ConfigFile file(getConfigFilePath(), ConfigFile::EXCEPTION_ON_ERROR | ConfigFile::NO_MACRO);
defaultConfig = new Config(file);
}
catch (const Firebird::fatal_exception& ex)
{
Firebird::Syslog::Record(Firebird::Syslog::Error, ex.what());
(Firebird::Arg::Gds(isc_random) << "Problems with master configuration file - "
"inform server admin please").raise();
}
}
/* void changeDefaultConfig(Config* newConfig)
{
defaultConfig = newConfig;
}
*/
Firebird::RefPtr<Config> getDefaultConfig() const
{
return defaultConfig;
}
const char* getCachedRootDir()
{
return root_dir;
}
private:
const char* root_dir;
Firebird::RefPtr<Config> defaultConfig;
ConfigImpl(const ConfigImpl&);
void operator=(const ConfigImpl&);
};
/******************************************************************************
*
* Static instance of the system configuration file
*/
Firebird::InitInstance<ConfigImpl> firebirdConf;
} // anonymous namespace
/******************************************************************************
*
@ -52,7 +113,7 @@ const char* AmNative = "native";
const char* AmTrusted = "trusted";
const char* AmMixed = "mixed";
const ConfigImpl::ConfigEntry ConfigImpl::entries[] =
const Config::ConfigEntry Config::entries[MAX_CONFIG_KEY] =
{
{TYPE_STRING, "RootDirectory", (ConfigValue) 0},
{TYPE_INTEGER, "TempBlockSize", (ConfigValue) 1048576}, // bytes
@ -127,74 +188,77 @@ const ConfigImpl::ConfigEntry ConfigImpl::entries[] =
/******************************************************************************
*
* Static instance of the system configuration file
* Config routines
*/
static Firebird::InitInstance<ConfigImpl> sysConfig;
/******************************************************************************
*
* Implementation interface
*/
ConfigImpl::ConfigImpl(MemoryPool& p) : ConfigRoot(p)
Config::Config(const ConfigFile& file)
{
// Prepare some stuff
ConfigFile file(p, true);
root_dir = getRootDirectory();
const int size = FB_NELEM(entries);
values = FB_NEW(p) ConfigValue[size];
//string val_sep = ",";
file.setConfigFilePath(getConfigFilePath());
// Iterate through the known configuration entries
for (int i = 0; i < size; i++)
for (unsigned int i = 0; i < MAX_CONFIG_KEY; i++)
{
const ConfigEntry entry = entries[i];
const string value = getValue(file, entries[i].key);
values[i] = entries[i].default_value;
}
if (!value.length())
loadValues(file);
}
Config::Config(const ConfigFile& file, const Config& base)
{
// Iterate through the known configuration entries
for (unsigned int i = 0; i < MAX_CONFIG_KEY; i++)
{
values[i] = base.values[i];
}
loadValues(file);
}
void Config::loadValues(const ConfigFile& file)
{
// Iterate through the known configuration entries
for (int i = 0; i < MAX_CONFIG_KEY; i++)
{
const ConfigEntry& entry = entries[i];
const String value = getValue(file, entry.key);
if (value.length())
{
// Assign the default value
// Assign the actual value
values[i] = entries[i].default_value;
continue;
}
// Assign the actual value
switch (entry.data_type)
{
case TYPE_BOOLEAN:
values[i] = (ConfigValue) asBoolean(value);
break;
case TYPE_INTEGER:
values[i] = (ConfigValue) asInteger(value);
break;
case TYPE_STRING:
switch (entry.data_type)
{
const char* src = asString(value);
char* dst = FB_NEW(p) char[strlen(src) + 1];
case TYPE_BOOLEAN:
values[i] = (ConfigValue) asBoolean(value);
break;
case TYPE_INTEGER:
values[i] = (ConfigValue) asInteger(value);
break;
case TYPE_STRING:
values[i] = (ConfigValue) asString(value);
break;
//case TYPE_STRING_VECTOR:
// break;
}
if (entry.data_type == TYPE_STRING && values[i] != entry.default_value)
{
const char* src = (const char*) values[i];
char* dst = FB_NEW(getPool()) char[strlen(src) + 1];
strcpy(dst, src);
values[i] = (ConfigValue) dst;
}
break;
//case TYPE_STRING_VECTOR:
// break;
}
}
}
ConfigImpl::~ConfigImpl()
Config::~Config()
{
const int size = FB_NELEM(entries);
// Free allocated memory
for (int i = 0; i < size; i++)
for (int i = 0; i < MAX_CONFIG_KEY; i++)
{
if (values[i] == entries[i].default_value)
continue;
@ -208,37 +272,48 @@ ConfigImpl::~ConfigImpl()
// break;
}
}
delete[] values;
}
string ConfigImpl::getValue(ConfigFile& file, const ConfigKey key)
String Config::getValue(const ConfigFile& file, ConfigName key)
{
return file.doesKeyExist(key) ? file.getString(key) : "";
const ConfigFile::Parameter* p = file.findParameter(key);
return p ? p->value : "";
}
int ConfigImpl::asInteger(const string &value)
int Config::asInteger(const String &value)
{
return atoi(value.data());
}
bool ConfigImpl::asBoolean(const string &value)
bool Config::asBoolean(const String &value)
{
return (atoi(value.data()) != 0);
}
const char* ConfigImpl::asString(const string &value)
const char* Config::asString(const String &value)
{
return value.c_str();
}
template <typename T>
T Config::get(Config::ConfigKey key) const
{
return (T) values[key];
}
/******************************************************************************
*
* Public interface
*/
const Firebird::RefPtr<Config> Config::getDefaultConfig()
{
return firebirdConf().getDefaultConfig();
}
const char* Config::getInstallDirectory()
{
return sysConfig().getInstallDirectory();
return firebirdConf().getInstallDirectory();
}
static Firebird::PathName* rootFromCommandLine = 0;
@ -263,39 +338,39 @@ const char* Config::getRootDirectory()
return rootFromCommandLine->c_str();
}
const char* result = (char*) sysConfig().values[KEY_ROOT_DIRECTORY];
return result ? result : sysConfig().root_dir;
const char* result = (char*) getDefaultConfig()->values[KEY_ROOT_DIRECTORY];
return result ? result : firebirdConf().getCachedRootDir();
}
int Config::getTempBlockSize()
int Config::getTempBlockSize() const
{
return (int) sysConfig().values[KEY_TEMP_BLOCK_SIZE];
return get<int>(KEY_TEMP_BLOCK_SIZE);
}
int Config::getTempCacheLimit()
int Config::getTempCacheLimit() const
{
int v = (int) sysConfig().values[KEY_TEMP_CACHE_LIMIT];
int v = get<int>(KEY_TEMP_CACHE_LIMIT);
return v < 0 ? 0 : v;
}
bool Config::getRemoteFileOpenAbility()
{
return (bool) sysConfig().values[KEY_REMOTE_FILE_OPEN_ABILITY];
return (bool) getDefaultConfig()->values[KEY_REMOTE_FILE_OPEN_ABILITY];
}
int Config::getGuardianOption()
{
return (int) sysConfig().values[KEY_GUARDIAN_OPTION];
return (int) getDefaultConfig()->values[KEY_GUARDIAN_OPTION];
}
int Config::getCpuAffinityMask()
{
return (int) sysConfig().values[KEY_CPU_AFFINITY_MASK];
return (int) getDefaultConfig()->values[KEY_CPU_AFFINITY_MASK];
}
int Config::getTcpRemoteBufferSize()
{
int rc = (int) sysConfig().values[KEY_TCP_REMOTE_BUFFER_SIZE];
int rc = (int) getDefaultConfig()->values[KEY_TCP_REMOTE_BUFFER_SIZE];
if (rc < 1448)
rc = 1448;
if (rc > MAX_SSHORT)
@ -305,57 +380,57 @@ int Config::getTcpRemoteBufferSize()
bool Config::getTcpNoNagle()
{
return (bool) sysConfig().values[KEY_TCP_NO_NAGLE];
return (bool) getDefaultConfig()->values[KEY_TCP_NO_NAGLE];
}
int Config::getDefaultDbCachePages()
int Config::getDefaultDbCachePages() const
{
return (int) sysConfig().values[KEY_DEFAULT_DB_CACHE_PAGES];
return get<int>(KEY_DEFAULT_DB_CACHE_PAGES);
}
int Config::getConnectionTimeout()
{
return (int) sysConfig().values[KEY_CONNECTION_TIMEOUT];
return (int) getDefaultConfig()->values[KEY_CONNECTION_TIMEOUT];
}
int Config::getDummyPacketInterval()
{
return (int) sysConfig().values[KEY_DUMMY_PACKET_INTERVAL];
return (int) getDefaultConfig()->values[KEY_DUMMY_PACKET_INTERVAL];
}
int Config::getLockMemSize()
int Config::getLockMemSize() const
{
return (int) sysConfig().values[KEY_LOCK_MEM_SIZE];
return get<int>(KEY_LOCK_MEM_SIZE);
}
bool Config::getLockGrantOrder()
bool Config::getLockGrantOrder() const
{
return (bool) sysConfig().values[KEY_LOCK_GRANT_ORDER];
return get<bool>(KEY_LOCK_GRANT_ORDER);
}
int Config::getLockHashSlots()
int Config::getLockHashSlots() const
{
return (int) sysConfig().values[KEY_LOCK_HASH_SLOTS];
return get<int>(KEY_LOCK_HASH_SLOTS);
}
int Config::getLockAcquireSpins()
int Config::getLockAcquireSpins() const
{
return (int) sysConfig().values[KEY_LOCK_ACQUIRE_SPINS];
return get<int>(KEY_LOCK_ACQUIRE_SPINS);
}
int Config::getEventMemSize()
int Config::getEventMemSize() const
{
return (int) sysConfig().values[KEY_EVENT_MEM_SIZE];
return get<int>(KEY_EVENT_MEM_SIZE);
}
int Config::getDeadlockTimeout()
int Config::getDeadlockTimeout() const
{
return (int) sysConfig().values[KEY_DEADLOCK_TIMEOUT];
return get<int>(KEY_DEADLOCK_TIMEOUT);
}
int Config::getPrioritySwitchDelay()
{
int rc = (int) sysConfig().values[KEY_PRIORITY_SWITCH_DELAY];
int rc = (int) getDefaultConfig()->values[KEY_PRIORITY_SWITCH_DELAY];
if (rc < 1)
rc = 1;
return rc;
@ -363,7 +438,7 @@ int Config::getPrioritySwitchDelay()
int Config::getPriorityBoost()
{
int rc = (int) sysConfig().values[KEY_PRIORITY_BOOST];
int rc = (int) getDefaultConfig()->values[KEY_PRIORITY_BOOST];
if (rc < 1)
rc = 1;
if (rc > 1000)
@ -373,62 +448,62 @@ int Config::getPriorityBoost()
bool Config::getUsePriorityScheduler()
{
return (bool) sysConfig().values[KEY_USE_PRIORITY_SCHEDULER];
return (bool) getDefaultConfig()->values[KEY_USE_PRIORITY_SCHEDULER];
}
const char *Config::getRemoteServiceName()
{
return (const char*) sysConfig().values[KEY_REMOTE_SERVICE_NAME];
return (const char*) getDefaultConfig()->values[KEY_REMOTE_SERVICE_NAME];
}
unsigned short Config::getRemoteServicePort()
{
return (unsigned short) sysConfig().values[KEY_REMOTE_SERVICE_PORT];
return (unsigned short) getDefaultConfig()->values[KEY_REMOTE_SERVICE_PORT];
}
const char *Config::getRemotePipeName()
{
return (const char*) sysConfig().values[KEY_REMOTE_PIPE_NAME];
return (const char*) getDefaultConfig()->values[KEY_REMOTE_PIPE_NAME];
}
const char *Config::getIpcName()
{
return (const char*) sysConfig().values[KEY_IPC_NAME];
return (const char*) getDefaultConfig()->values[KEY_IPC_NAME];
}
int Config::getMaxUnflushedWrites()
int Config::getMaxUnflushedWrites() const
{
return (int) sysConfig().values[KEY_MAX_UNFLUSHED_WRITES];
return get<int>(KEY_MAX_UNFLUSHED_WRITES);
}
int Config::getMaxUnflushedWriteTime()
int Config::getMaxUnflushedWriteTime() const
{
return (int) sysConfig().values[KEY_MAX_UNFLUSHED_WRITE_TIME];
return get<int>(KEY_MAX_UNFLUSHED_WRITE_TIME);
}
int Config::getProcessPriorityLevel()
{
return (int) sysConfig().values[KEY_PROCESS_PRIORITY_LEVEL];
return (int) getDefaultConfig()->values[KEY_PROCESS_PRIORITY_LEVEL];
}
int Config::getRemoteAuxPort()
{
return (int) sysConfig().values[KEY_REMOTE_AUX_PORT];
return (int) getDefaultConfig()->values[KEY_REMOTE_AUX_PORT];
}
const char *Config::getRemoteBindAddress()
{
return (const char*) sysConfig().values[KEY_REMOTE_BIND_ADDRESS];
return (const char*) getDefaultConfig()->values[KEY_REMOTE_BIND_ADDRESS];
}
const char *Config::getExternalFileAccess()
const char *Config::getExternalFileAccess() const
{
return (const char*) sysConfig().values[KEY_EXTERNAL_FILE_ACCESS];
return get<const char*>(KEY_EXTERNAL_FILE_ACCESS);
}
const char *Config::getDatabaseAccess()
{
return (const char*) sysConfig().values[KEY_DATABASE_ACCESS];
return (const char*) getDefaultConfig()->values[KEY_DATABASE_ACCESS];
}
const char *Config::getUdfAccess()
@ -449,7 +524,7 @@ const char *Config::getUdfAccess()
return value;
}
const char* v = (const char*) sysConfig().values[KEY_UDF_ACCESS];
const char* v = (const char*) getDefaultConfig()->values[KEY_UDF_ACCESS];
if (CASE_SENSITIVITY ? (! strcmp(v, UDF_DEFAULT_CONFIG_VALUE) && FB_UDFDIR[0]) :
(! fb_utils::stricmp(v, UDF_DEFAULT_CONFIG_VALUE) && FB_UDFDIR[0]))
{
@ -465,66 +540,66 @@ const char *Config::getUdfAccess()
const char *Config::getTempDirectories()
{
return (const char*) sysConfig().values[KEY_TEMP_DIRECTORIES];
return (const char*) getDefaultConfig()->values[KEY_TEMP_DIRECTORIES];
}
bool Config::getBugcheckAbort()
{
return (bool) sysConfig().values[KEY_BUGCHECK_ABORT];
return (bool) getDefaultConfig()->values[KEY_BUGCHECK_ABORT];
}
bool Config::getLegacyHash()
{
return (bool) sysConfig().values[KEY_LEGACY_HASH];
return (bool) getDefaultConfig()->values[KEY_LEGACY_HASH];
}
const char *Config::getGCPolicy()
const char *Config::getGCPolicy() const
{
return (const char*) sysConfig().values[KEY_GC_POLICY];
return get<const char*>(KEY_GC_POLICY);
}
bool Config::getRedirection()
{
return (bool) sysConfig().values[KEY_REDIRECTION];
return (bool) getDefaultConfig()->values[KEY_REDIRECTION];
}
const char *Config::getAuthMethod()
{
return (const char*) sysConfig().values[KEY_AUTH_METHOD];
return (const char*) getDefaultConfig()->values[KEY_AUTH_METHOD];
}
int Config::getDatabaseGrowthIncrement()
int Config::getDatabaseGrowthIncrement() const
{
return (int) sysConfig().values[KEY_DATABASE_GROWTH_INCREMENT];
return get<int>(KEY_DATABASE_GROWTH_INCREMENT);
}
int Config::getFileSystemCacheThreshold()
int Config::getFileSystemCacheThreshold() const
{
int rc = (int) sysConfig().values[KEY_FILESYSTEM_CACHE_THRESHOLD];
int rc = get<int>(KEY_FILESYSTEM_CACHE_THRESHOLD);
return rc < 0 ? 0 : rc;
}
bool Config::getRelaxedAliasChecking()
{
return (bool) sysConfig().values[KEY_RELAXED_ALIAS_CHECKING];
return (bool) getDefaultConfig()->values[KEY_RELAXED_ALIAS_CHECKING];
}
bool Config::getOldSetClauseSemantics()
{
return (bool) sysConfig().values[KEY_OLD_SET_CLAUSE_SEMANTICS];
return (bool) getDefaultConfig()->values[KEY_OLD_SET_CLAUSE_SEMANTICS];
}
int Config::getFileSystemCacheSize()
{
return (int) sysConfig().values[KEY_FILESYSTEM_CACHE_SIZE];
return (int) getDefaultConfig()->values[KEY_FILESYSTEM_CACHE_SIZE];
}
const char *Config::getAuditTraceConfigFile()
{
return (const char*) sysConfig().values[KEY_TRACE_CONFIG];
return (const char*) getDefaultConfig()->values[KEY_TRACE_CONFIG];
}
int Config::getMaxUserTraceLogSize()
{
return (int) sysConfig().values[KEY_MAX_TRACELOG_SIZE];
return (int) getDefaultConfig()->values[KEY_MAX_TRACELOG_SIZE];
}

View File

@ -23,8 +23,9 @@
#ifndef COMMON_CONFIG_H
#define COMMON_CONFIG_H
#include "../common/classes/alloc.h"
#include "../common/classes/fb_string.h"
#include "../jrd/os/path_utils.h"
#include "../common/classes/RefCounted.h"
/**
Since the original (isc.cpp) code wasn't able to provide powerful and
@ -68,8 +69,13 @@ extern const char* AmMixed;
enum AmCache {AM_UNKNOWN, AM_DISABLED, AM_ENABLED};
class Config
class ConfigFile;
class Config : public Firebird::RefCounted, public Firebird::GlobalStorage
{
public:
typedef IPTR ConfigValue;
enum ConfigKey
{
KEY_ROOT_DIRECTORY,
@ -116,13 +122,45 @@ class Config
KEY_OLD_SET_CLAUSE_SEMANTICS,
KEY_TRACE_CONFIG,
KEY_MAX_TRACELOG_SIZE,
KEY_FILESYSTEM_CACHE_SIZE
KEY_FILESYSTEM_CACHE_SIZE,
MAX_CONFIG_KEY // keep it last
};
private:
enum ConfigType
{
TYPE_BOOLEAN,
TYPE_INTEGER,
TYPE_STRING
//TYPE_STRING_VECTOR // CVC: Unused
};
typedef const char* ConfigName;
struct ConfigEntry
{
ConfigType data_type;
ConfigName key;
ConfigValue default_value;
};
static Firebird::PathName getValue(const ConfigFile&, ConfigName);
static int asInteger(const Firebird::PathName&);
static bool asBoolean(const Firebird::PathName&);
static const char* asString(const Firebird::PathName&);
void loadValues(const ConfigFile& file);
template <typename T> T get(Config::ConfigKey key) const;
static const ConfigEntry entries[MAX_CONFIG_KEY];
ConfigValue values[MAX_CONFIG_KEY];
public:
Config(const ConfigFile& file); // use to build default config
Config(const ConfigFile& file, const Config& base); // use to build db-specific config
~Config();
// Interface to support command line root specification.
// This ugly solution was required to make it possible to specify root
// in command line to load firebird.conf from that root, though in other
// cases firebird.conf may be also used to specify root.
@ -130,6 +168,12 @@ public:
static void setRootDirectoryFromCommandLine(const Firebird::PathName& newRoot);
static const Firebird::PathName* getCommandLineRootDirectory();
// Master config - needed to provide per-database config
static const Firebird::RefPtr<Config> getDefaultConfig();
// Static functions apply to instance-wide values,
// non-static may be specified per database.
// Installation directory
static const char* getInstallDirectory();
@ -137,10 +181,10 @@ public:
static const char* getRootDirectory();
// Allocation chunk for the temporary spaces
static int getTempBlockSize();
int getTempBlockSize() const;
// Caching limit for the temporary data
static int getTempCacheLimit();
int getTempCacheLimit() const;
// Whether remote (NFS) files can be opened
static bool getRemoteFileOpenAbility();
@ -158,7 +202,7 @@ public:
static bool getTcpNoNagle();
// Default database cache size
static int getDefaultDbCachePages();
int getDefaultDbCachePages() const;
// Connection timeout
static int getConnectionTimeout();
@ -167,22 +211,22 @@ public:
static int getDummyPacketInterval();
// Lock manager memory size
static int getLockMemSize();
int getLockMemSize() const;
// Lock manager grant order
static bool getLockGrantOrder();
bool getLockGrantOrder() const;
// Lock manager hash slots
static int getLockHashSlots();
int getLockHashSlots() const;
// Lock manager acquire spins
static int getLockAcquireSpins();
int getLockAcquireSpins() const;
// Event manager memory size
static int getEventMemSize();
int getEventMemSize() const;
// Deadlock timeout
static int getDeadlockTimeout();
int getDeadlockTimeout() const;
// Priority switch delay
static int getPrioritySwitchDelay();
@ -206,10 +250,10 @@ public:
static const char *getIpcName();
// Unflushed writes number
static int getMaxUnflushedWrites();
int getMaxUnflushedWrites() const;
// Unflushed write time
static int getMaxUnflushedWriteTime();
int getMaxUnflushedWriteTime() const;
// Process priority level
static int getProcessPriorityLevel();
@ -221,7 +265,7 @@ public:
static const char *getRemoteBindAddress();
// Directory list for external tables
static const char *getExternalFileAccess();
const char *getExternalFileAccess() const;
// Directory list for databases
static const char *getDatabaseAccess();
@ -239,7 +283,7 @@ public:
static bool getLegacyHash();
// GC policy
static const char *getGCPolicy();
const char *getGCPolicy() const;
// Redirection
static bool getRedirection();
@ -247,9 +291,9 @@ public:
// Use native, trusted or mixed authentication
static const char *getAuthMethod();
static int getDatabaseGrowthIncrement();
int getDatabaseGrowthIncrement() const;
static int getFileSystemCacheThreshold();
int getFileSystemCacheThreshold() const;
static int getFileSystemCacheSize();

View File

@ -22,176 +22,371 @@
#include "firebird.h"
#include "../../common/classes/alloc.h"
#include "../../common/classes/auto.h"
#include "../../common/config/config_file.h"
#include "../jrd/os/fbsyslog.h"
#include "../common/classes/alloc.h"
#include "../common/classes/auto.h"
#include "../common/config/config_file.h"
#include "../common/config/config.h"
#include "../jrd/os/path_utils.h"
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
// Invalid or missing CONF_FILE may lead to severe errors
// in applications. That's why for regular SERVER builds
// it's better to exit with appropriate diags rather continue
// with missing / wrong configuration.
#if (! defined(BOOT_BUILD)) && (! defined(EMBEDDED)) && (! defined(SUPERCLIENT))
#define EXCEPTION_ON_NO_CONF
#else
#undef EXCEPTION_ON_NO_CONF
#endif
using namespace Firebird;
// config_file works with OS case-sensitivity
typedef Firebird::PathName string;
namespace {
/******************************************************************************
*
* Strip any comments
*/
bool ConfigFile::stripComments(string& s) const
class MainStream : public ConfigFile::Stream
{
if (!parsingAliases)
public:
MainStream(const char* fname, bool fExceptionOnError)
: file(fopen(fname, "rt")), l(0)
{
// Simple, fast processing for firebird.conf
// Note that this is only a hack. It won't work in case inputLine
// contains hash-marks embedded in quotes! Not that I know if we
// should care about that case.
const string::size_type commentPos = s.find('#');
if (commentPos != string::npos)
if ((!file) && fExceptionOnError)
{
s = s.substr(0, commentPos);
// config file does not exist
fatal_exception::raiseFmt("Missing configuration file: ", fname);
}
}
bool getLine(ConfigFile::String& input, unsigned int& line)
{
input = "";
if (!file)
{
return false;
}
// this loop efficiently skips almost all comment lines
do
{
if (feof(file))
{
return false;
}
input.LoadFromFile(file);
++l;
input.alltrim(" \t\r");
} while (input.isEmpty() || input[0] == '#');
line = l;
return true;
}
// Paranoid, slow processing for aliases.conf
bool equalSeen = false, inString = false;
const char* iter = s.begin();
const char* end = s.end();
private:
AutoPtr<FILE, FileClose> file;
unsigned int l;
};
while (iter < end)
class TextStream : public ConfigFile::Stream
{
public:
TextStream(const char* configText)
: s(configText), l(0)
{
switch (*iter)
if (s && !*s)
{
case '"':
if (!equalSeen) // quoted string to the left of = doesn't make sense
return false;
inString = !inString; // We don't support embedded quotes
if (!inString) // we finished a quoted string
s = NULL;
}
}
bool getLine(ConfigFile::String& input, unsigned int& line)
{
do
{
if (!s)
{
// We don't want trash after closing the quoted string, except comments
const string::size_type startPos = s.find_first_not_of(" \t\r", iter + 1 - s.begin());
if (startPos == string::npos || s[startPos] == '#')
input = "";
return false;
}
const char* ptr = strchr(s, '\n');
if (!ptr)
{
input.assign(s);
s = NULL;
}
else
{
input.assign(s, ptr - s);
s = ptr + 1;
if (!*s)
{
s = s.substr(0, iter + 1 - s.begin());
return true;
s = NULL;
}
return false;
}
break;
case '=':
equalSeen = true;
break;
case '#':
if (!inString)
{
s = s.substr(0, iter - s.begin());
return true;
}
break;
++l;
input.alltrim(" \t\r");
} while (input.isEmpty() || input[0] == '#');
line = l;
return true;
}
private:
const char* s;
unsigned int l;
};
class SubStream : public ConfigFile::Stream
{
public:
SubStream()
: cnt(0)
{ }
bool getLine(ConfigFile::String& input, unsigned int& line)
{
if (cnt >= data.getCount())
{
input = "";
return false;
}
++iter;
input = data[cnt].first;
line = data[cnt].second;
++cnt;
return true;
}
return !inString; // If we are still inside a string, it's error
void putLine(const ConfigFile::String& input, unsigned int line)
{
data.push(Line(input, line));
}
private:
typedef Pair<Left<ConfigFile::String, unsigned int> > Line;
ObjectsArray<Line> data;
size_t cnt;
};
} // anonymous namespace
ConfigFile::ConfigFile(const ConfigFile::String& file, USHORT fl)
: AutoStorage(), configFile(getPool(), file), parameters(getPool()), flags(fl)
{
MainStream s(configFile.c_str(), flags & EXCEPTION_ON_ERROR);
parse(&s);
}
ConfigFile::ConfigFile(const char* file, USHORT fl)
: AutoStorage(), configFile(getPool(), String(file)), parameters(getPool()), flags(fl)
{
MainStream s(configFile.c_str(), flags & EXCEPTION_ON_ERROR);
parse(&s);
}
ConfigFile::ConfigFile(UseText, const char* configText, USHORT fl)
: AutoStorage(), configFile(getPool()), parameters(getPool()), flags(fl)
{
TextStream s(configText);
parse(&s);
}
ConfigFile::ConfigFile(MemoryPool& p, ConfigFile::Stream* s, USHORT fl, const String& file)
: AutoStorage(p), configFile(getPool(), file), parameters(getPool()), flags(fl)
{
parse(s);
}
ConfigFile::Stream::~Stream() { }
/******************************************************************************
*
* Parse line, taking quotes into an account
*/
ConfigFile::LineType ConfigFile::parseLine(const String& input, String& key, String& value)
{
int inString = 0;
String::size_type valStart = 0;
String::size_type eol = String::npos;
bool hasSub = false;
for (String::size_type n=0; n < input.length(); ++n)
{
switch (input[n])
{
case '"':
if (key.isEmpty()) // quoted string to the left of = doesn't make sense
return LINE_BAD;
if (inString >= 2) // one more quote after quoted string doesn't make sense
return LINE_BAD;
inString++;
break;
case '=':
key = input.substr(0, n);
key.rtrim(" \t\r");
if (key.isEmpty()) // not good - no key
return LINE_BAD;
valStart = n + 1;
break;
case '#':
if (inString != 1)
{
eol = n;
n = input.length(); // skip the rest of symbols
}
break;
case ' ':
case '\t':
case '\r':
break;
case '{':
case '}':
if (flags & HAS_SUB_CONF)
{
if (inString != 1) {
if (input[n] == '}') // Subconf close mark not expected
{
return LINE_BAD;
}
hasSub = true;
inString = 2;
eol = n;
}
break;
}
// fall through ....
default:
if (inString >= 2) // Something after the end of line
return LINE_BAD;
break;
}
}
if (inString == 1) // If we are still inside a string, it's error
return LINE_BAD;
if (key.isEmpty())
{
key = input.substr(0, eol);
key.rtrim(" \t\r");
}
else
{
value = input.substr(valStart, eol - valStart);
value.alltrim(" \t\r");
value.alltrim("\"");
}
// Now expand macros in value
String::size_type subFrom;
while ((subFrom = value.find("$(")) != String::npos)
{
String::size_type subTo = value.find(")", subFrom);
if (subTo != String::npos)
{
String macro;
String m = value.substr(subFrom + 2, subTo - (subFrom + 2));
if (! translate(m, macro))
{
return LINE_BAD;
}
value.replace(subFrom, subTo + 1 - subFrom, macro);
}
else
{
return LINE_BAD;
}
}
return hasSub ? LINE_START_SUB : LINE_REGULAR;
}
/******************************************************************************
*
* Check whether the given key exists or not
* Find macro value
*/
bool ConfigFile::doesKeyExist(const string& key)
bool ConfigFile::translate(const String& from, String& to)
{
checkLoadConfig();
if (flags & NO_MACRO)
{
return false;
}
const string data = getString(key);
if (from == "root")
{
to = Config::getRootDirectory();
}
else if (from == "install")
{
to = Config::getInstallDirectory();
}
else if (from == "this")
{
if (configFile.isEmpty())
{
return false;
}
PathName file;
PathUtils::splitLastComponent(to, file, configFile);
}
/* else if (!substituteOneOfStandardFirebirdDirs(from, to))
{
return false;
} */
else
{
return false;
}
return !data.empty();
return true;
}
/******************************************************************************
*
* Return string value corresponding the given key
* Return parameter corresponding the given key
*/
string ConfigFile::getString(const string& key)
const ConfigFile::Parameter* ConfigFile::findParameter(const String& name) const
{
checkLoadConfig();
size_t pos;
return parameters.find(key, pos) ? parameters[pos].second : string();
return parameters.find(name, pos) ? &parameters[pos] : NULL;
}
/******************************************************************************
*
* Parse key
* Return parameter corresponding the given key and value
*/
string ConfigFile::parseKeyFrom(const string& inputLine, string::size_type& endPos)
const ConfigFile::Parameter* ConfigFile::findParameter(const String& name, const String& value) const
{
endPos = inputLine.find_first_of("=");
if (endPos == string::npos)
size_t pos;
if (!parameters.find(name, pos))
{
return inputLine;
return NULL;
}
return inputLine.substr(0, endPos);
while(pos < parameters.getCount() && parameters[pos].name == name)
{
if (parameters[pos].value == value)
{
return &parameters[pos];
}
++pos;
}
return NULL;
}
/******************************************************************************
*
* Parse value
* Take into an account fault line
*/
string ConfigFile::parseValueFrom(string inputLine, string::size_type initialPos)
void ConfigFile::badLine(const String& line)
{
if (initialPos == string::npos)
if (flags & EXCEPTION_ON_ERROR)
{
return string();
}
// skip leading white spaces
const string::size_type startPos = inputLine.find_first_not_of("= \t", initialPos);
if (startPos == string::npos)
{
return string();
}
inputLine.rtrim(" \t\r");
// stringComments demands paired quotes but trimming \r may render startPos invalid.
if (parsingAliases && inputLine.length() > startPos + 1 &&
inputLine[startPos] == '"' && inputLine.end()[-1] == '"')
{
return inputLine.substr(startPos + 1, inputLine.length() - startPos - 2);
}
return inputLine.substr(startPos);
}
/******************************************************************************
*
* Load file, if necessary
*/
void ConfigFile::checkLoadConfig()
{
if (!isLoadedFlg)
{
loadConfig();
fatal_exception::raiseFmt("%s: illegal line <%s>" ,
configFile.hasData() ? configFile.c_str() : "Passed text",
line.c_str());
}
}
@ -200,73 +395,61 @@ void ConfigFile::checkLoadConfig()
* Load file immediately
*/
void ConfigFile::loadConfig()
void ConfigFile::parse(Stream* stream)
{
isLoadedFlg = true;
String inputLine;
Parameter* previous = NULL;
unsigned int line;
parameters.clear();
Firebird::AutoPtr<FILE, Firebird::FileClose> ifile(fopen(configFile.c_str(), "rt"));
#ifdef EXCEPTION_ON_NO_CONF
int BadLinesCount = 0;
#endif
if (!ifile)
while (stream->getLine(inputLine, line))
{
// config file does not exist
#ifdef EXCEPTION_ON_NO_CONF
if (fExceptionOnError)
Parameter current;
current.line = line;
switch(parseLine(inputLine, current.name, current.value))
{
const Firebird::string msg =
"Missing configuration file: " + configFile.ToString() + ", exiting";
Firebird::Syslog::Record(Firebird::Syslog::Error, msg.c_str());
Firebird::fatal_exception::raise(msg.c_str());
case LINE_BAD:
badLine(inputLine);
break;
case LINE_REGULAR:
if (current.name.isEmpty())
{
badLine(inputLine);
break;
}
previous = &parameters[parameters.add(current)];
break;
case LINE_START_SUB:
if (current.name.hasData())
{
size_t n = parameters.add(current);
previous = &parameters[n];
}
{ // subconf scope
SubStream subStream;
while (stream->getLine(inputLine, line))
{
if (inputLine[0] == '}')
{
String s = inputLine.substr(1);
s.ltrim(" \t\r");
if (s.hasData() && s[0] != '#')
{
badLine(s);
continue;
}
break;
}
subStream.putLine(inputLine, line);
}
previous->sub = FB_NEW(getPool()) ConfigFile(getPool(), &subStream,
flags & ~HAS_SUB_CONF, configFile);
}
break;
}
#endif //EXCEPTION_ON_NO_CONF
return;
}
string inputLine;
while (!feof(ifile))
{
inputLine.LoadFromFile(ifile);
const bool goodLine = stripComments(inputLine);
inputLine.ltrim(" \t\r");
if (!inputLine.size())
{
continue; // comment-line or empty line
}
if (!goodLine || inputLine.find('=') == string::npos)
{
const Firebird::string msg =
(configFile + ": illegal line \"" + inputLine + "\"").ToString();
Firebird::Syslog::Record(fExceptionOnError ?
Firebird::Syslog::Error : Firebird::Syslog::Warning,
msg.c_str());
#ifdef EXCEPTION_ON_NO_CONF
BadLinesCount++;
#endif
continue;
}
string::size_type endPos;
string key = parseKeyFrom(inputLine, endPos);
key.rtrim(" \t\r");
// TODO: here we must check for correct parameter spelling !
const string value = parseValueFrom(inputLine, endPos);
parameters.add(Parameter(getPool(), key, value));
}
#ifdef EXCEPTION_ON_NO_CONF
if (BadLinesCount && fExceptionOnError)
{
Firebird::fatal_exception::raise("Bad lines in firebird.conf");
}
#endif
}

View File

@ -23,10 +23,11 @@
#ifndef CONFIG_CONFIG_FILE_H
#define CONFIG_CONFIG_FILE_H
#include "../../common/classes/alloc.h"
#include "../../common/classes/fb_pair.h"
#include "../../common/classes/objects_array.h"
#include "../common/classes/alloc.h"
#include "../common/classes/fb_pair.h"
#include "../common/classes/objects_array.h"
#include "../common/classes/fb_string.h"
#include "../common/classes/auto.h"
/**
Since the original (isc.cpp) code wasn't able to provide powerful and
@ -45,56 +46,82 @@
(common/config/config.cpp) and server-side alias manager (jrd/db_alias.cpp).
**/
class ConfigFile : public Firebird::AutoStorage
class ConfigFile : public Firebird::AutoStorage, public Firebird::RefCounted
{
// config_file works with OS case-sensitivity
typedef Firebird::PathName string;
typedef Firebird::Pair<Firebird::Full<string, string> > Parameter;
typedef Firebird::SortedObjectsArray <Parameter,
Firebird::InlineStorage<Parameter *, 100>,
string, Firebird::FirstPointerKey<Parameter> > mymap_t;
public:
ConfigFile(MemoryPool& p, bool ExceptionOnError)
: AutoStorage(p), isLoadedFlg(false),
fExceptionOnError(ExceptionOnError), parsingAliases(false),
parameters(getPool()) {}
ConfigFile(bool ExceptionOnError, bool useForAliases)
: AutoStorage(), isLoadedFlg(false),
fExceptionOnError(ExceptionOnError), parsingAliases(useForAliases),
parameters(getPool()) {}
// flags for config file
static const USHORT EXCEPTION_ON_ERROR = 0x01;
static const USHORT HAS_SUB_CONF = 0x02;
static const USHORT NO_MACRO = 0x04;
explicit ConfigFile(bool ExceptionOnError)
: AutoStorage(), isLoadedFlg(false),
fExceptionOnError(ExceptionOnError), parsingAliases(false),
parameters(getPool()) {}
// enum to distinguish ctors
enum UseText {USE_TEXT};
// configuration file management
const string getConfigFilePath() const { return configFile; }
void setConfigFilePath(const string& newFile) { configFile = newFile; }
// config_file works with OS case-sensitivity
typedef Firebird::PathName String;
bool isLoaded() const { return isLoadedFlg; }
class Stream
{
public:
virtual ~Stream();
virtual bool getLine(String&, unsigned int&) = 0;
};
void loadConfig();
void checkLoadConfig();
struct Parameter : public AutoStorage
{
Parameter(MemoryPool& p, const Parameter& par)
: AutoStorage(p), name(getPool(), par.name), value(getPool(), par.value),
sub(par.sub), line(par.line)
{ }
Parameter()
: AutoStorage(), name(getPool()), value(getPool()), sub(0), line(0)
{ }
String name;
String value;
Firebird::RefPtr<ConfigFile> sub;
unsigned int line;
// key and value management
bool doesKeyExist(const string&);
string getString(const string&);
static const String* generate(const void* /*sender*/, const Parameter* item)
{
return &item->name;
}
};
typedef Firebird::SortedObjectsArray <Parameter, Firebird::InlineStorage<Parameter*, 100>,
String, Parameter> Parameters;
// utilities
bool stripComments(string&) const;
static string parseKeyFrom(const string&, string::size_type&);
string parseValueFrom(string, string::size_type);
ConfigFile(const String& file, USHORT fl);
ConfigFile(const char* file, USHORT fl);
ConfigFile(UseText, const char* configText, USHORT fl);
private:
string configFile;
bool isLoadedFlg;
const bool fExceptionOnError;
const bool parsingAliases;
mymap_t parameters;
ConfigFile(MemoryPool& p, ConfigFile::Stream* s, USHORT fl, const String& file);
public:
// key and value management
const Parameter* findParameter(const String& name) const;
const Parameter* findParameter(const String& name, const String& value) const;
// all parameters access
const Parameters& getParameters() const
{
return parameters;
}
private:
enum LineType {LINE_BAD, LINE_REGULAR, LINE_START_SUB};
String configFile;
Parameters parameters;
USHORT flags;
USHORT badLinesCount;
// utilities
void parse(Stream* stream);
LineType parseLine(const String& input, String& key, String& value);
bool translate(const String& from, String& to);
void badLine(const String& line);
};
#endif // CONFIG_CONFIG_FILE_H

View File

@ -1,81 +0,0 @@
/*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Dmitry Yemanov
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2002 Dmitry Yemanov <dimitr@users.sf.net>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
#ifndef CONFIG_IMPL_H
#define CONFIG_IMPL_H
#include "fb_types.h"
#include "../../common/classes/fb_string.h"
#include "../../common/config/config.h"
#include "../../common/config/config_file.h"
#include "../jrd/os/config_root.h"
/******************************************************************************
*
* Main implementation class
*/
class ConfigImpl : public ConfigRoot
{
friend class Config;
// config_file works with OS case-sensitivity
typedef Firebird::PathName string;
enum ConfigType
{
TYPE_BOOLEAN,
TYPE_INTEGER,
TYPE_STRING
//TYPE_STRING_VECTOR // CVC: Unused
};
typedef const char* ConfigKey;
typedef IPTR ConfigValue;
struct ConfigEntry
{
ConfigType data_type;
ConfigKey key;
ConfigValue default_value;
};
public:
explicit ConfigImpl(MemoryPool& p);
~ConfigImpl();
static string getValue(ConfigFile&, const ConfigKey);
static int asInteger(const string&);
static bool asBoolean(const string&);
static const char* asString(const string&);
private:
static const ConfigEntry entries[];
const char *root_dir;
ConfigValue *values;
ConfigImpl(const ConfigImpl&);
void operator=(const ConfigImpl&);
};
#endif // CONFIG_IMPL_H

View File

@ -1,68 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
// AdminException.cpp: implementation of the AdminException class.
//
//////////////////////////////////////////////////////////////////////
#include "firebird.h"
#include <stdio.h>
#include <stdarg.h>
#include "../common/classes/alloc.h"
#include "AdminException.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
AdminException::AdminException(const char* txt, ...) :
text(getPool()), fileName(getPool())
{
va_list args;
va_start (args, txt);
text.vprintf(txt, args);
va_end(args);
}
AdminException::~AdminException()
{
}
const char* AdminException::getText() const
{
return text.c_str();
}
void AdminException::setLocation(const Firebird::PathName& file, int lineNumber)
{
fileName = file;
Firebird::string buffer;
buffer.printf("%s, line %d: %s", fileName.c_str(), lineNumber, text.c_str());
text = buffer;
}

View File

@ -1,53 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
// AdminException.h: interface for the AdminException class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_ADMINEXCEPTION_H__ED22B745_F780_416D_8291_0A2D49EF5B43__INCLUDED_)
#define AFX_ADMINEXCEPTION_H__ED22B745_F780_416D_8291_0A2D49EF5B43__INCLUDED_
#if defined _MSC_VER && _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER > 1000
#include "../common/classes/fb_string.h"
class AdminException : public Firebird::GlobalStorage
{
public:
AdminException(const char* txt, ...);
virtual ~AdminException();
void setLocation (const Firebird::PathName& fileName, int lineNumber);
const char* getText() const;
private:
Firebird::string text;
Firebird::PathName fileName;
};
#endif // !defined(AFX_ADMINEXCEPTION_H__ED22B745_F780_416D_8291_0A2D49EF5B43__INCLUDED_)

View File

@ -1,262 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
// Args.cpp: implementation of the Args class.
//
//////////////////////////////////////////////////////////////////////
#ifdef _WIN32
#include <windows.h>
#else
#include <termios.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "firebird.h"
#include "Args.h"
#include "ArgsException.h"
namespace
{
class ConsoleNoEcho
{
public:
ConsoleNoEcho();
~ConsoleNoEcho();
private:
#ifdef _WIN32
HANDLE m_stdin;
DWORD m_orgSettings;
#else
termios m_orgSettings;
#endif
};
ConsoleNoEcho::ConsoleNoEcho()
{
#ifdef _WIN32
m_stdin = GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode(m_stdin, &m_orgSettings);
const DWORD newSettings = m_orgSettings & ~(ENABLE_ECHO_INPUT);
SetConsoleMode(m_stdin, newSettings);
#else
tcgetattr(0, &m_orgSettings);
termios newSettings = m_orgSettings;
newSettings.c_lflag &= (~ECHO);
tcsetattr(0, TCSANOW, &newSettings);
#endif
}
ConsoleNoEcho::~ConsoleNoEcho()
{
#ifdef _WIN32
SetConsoleMode(m_stdin, m_orgSettings);
#else
tcsetattr(0, TCSANOW, &m_orgSettings);
#endif
}
} // namespace
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
Args::Args()
{
}
Args::~Args()
{
}
void Args::parse(const Switches* switches, int argc, const char* const* argv)
{
const char* const* const end = argv + argc;
while (argv < end)
{
const char* p = *argv++;
const Switches* parameter = NULL;
bool hit = false;
for (const Switches* sw = switches; sw->string; ++sw)
{
if (strcmp (sw->string, p) == 0)
{
if (sw->boolean)
*sw->boolean = true;
if (sw->argument)
{
if (argv >= end)
throw ArgsException ("an argument is required for \"%s\"", sw->string);
*sw->argument = *argv++;
}
hit = true;
break;
}
if (!sw->string [0])
parameter = sw;
}
if (!hit)
{
if (parameter)
{
if (parameter->boolean)
*parameter->boolean = true;
if (parameter->argument)
*parameter->argument = p;
}
else
throw ArgsException ("invalid option \"%s\"", p);
}
}
}
void Args::init(const Switches* switches)
{
for (const Switches *sw = switches; sw->string; ++sw)
{
if (sw->boolean)
*sw->boolean = false;
if (sw->argument)
*sw->argument = NULL;
}
}
void Args::printHelp(const char* helpText, const Switches* switches)
{
int switchLength = 0;
int argLength = 0;
const Switches *sw;
for (sw = switches; sw->string; ++sw)
{
if (sw->description)
{
int l = (int) strlen (sw->string);
if (l > switchLength)
switchLength = l;
if (sw->argName)
{
l = (int) strlen (sw->argName);
if (l > argLength)
argLength = l;
}
}
}
if (helpText)
printf (helpText);
printf ("Options are:\n");
for (sw = switches; sw->string; ++sw)
{
if (sw->description)
{
const char *arg = (sw->argName) ? sw->argName : "";
printf (" %-*s %-*s %s\n", switchLength, sw->string, argLength, arg, sw->description);
}
}
}
bool Args::readPasswords(const char *msg, char *pw1, int length)
{
ConsoleNoEcho instance;
char pw2 [100];
bool hit = false;
for (;;)
{
if (msg)
printf (msg);
printf ("New password: ");
if (!fgets (pw1, length, stdin))
break;
char *p = strchr (pw1, '\n');
if (p)
*p = 0;
// blanks not detected here, need something like trim()
if (!pw1 [0])
{
printf ("\nPassword may not be null. Please re-enter.\n");
continue;
}
printf ("\nRepeat new password: ");
if (!fgets (pw2, sizeof (pw2), stdin))
break;
if (p = strchr (pw2, '\n'))
*p = 0;
if (strcmp (pw1, pw2) == 0)
{
hit = true;
break;
}
printf ("\nPasswords do not match. Please re-enter.\n");
}
printf ("\n");
return hit;
}
bool Args::readPassword(const char *msg, char *pw1, int length)
{
ConsoleNoEcho instance;
bool hit = false;
for (;;)
{
if (msg)
printf (msg);
if (!fgets (pw1, length, stdin))
break;
char *p = strchr (pw1, '\n');
if (p)
*p = 0;
// blanks not detected here, need something like trim()
if (pw1 [0])
{
hit = true;
break;
}
printf ("\nPassword may not be null. Please re-enter.\n");
}
printf ("\n");
return hit;
}

View File

@ -1,66 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
// Args.h: interface for the Args class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_ARGS_H__7C584339_5A11_4040_889B_417B607C858B__INCLUDED_)
#define AFX_ARGS_H__7C584339_5A11_4040_889B_417B607C858B__INCLUDED_
#if defined _MSC_VER && _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER > 1000
#include "../common/classes/alloc.h"
//#define WORD_ARG(value,name) "", NULL, &value, name, NULL,
//#define ARG_ARG(sw,value,help) sw, NULL, &value, NULL, help,
//#define SW_ARG(sw,value,help) sw, &value,NULL, NULL, help,
class Args : public Firebird::GlobalStorage
{
public:
struct Switches
{
const char* string;
bool* boolean;
const char** argument;
const char* argName;
const char* description;
};
Args();
virtual ~Args();
static bool readPassword (const char* msg, char* pw1, int length);
static bool readPasswords(const char* msg, char* pw1, int length);
static void printHelp (const char* helpText, const Switches* switches);
static void init (const Switches* switches);
static void parse (const Switches* switches, int argc, const char* const* argv);
};
#endif // !defined(AFX_ARGS_H__7C584339_5A11_4040_889B_417B607C858B__INCLUDED_)

View File

@ -1,58 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
// ArgsException.cpp: implementation of the ArgsException class.
//
//////////////////////////////////////////////////////////////////////
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include "firebird.h"
#include "ArgsException.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
ArgsException::ArgsException(const char* txt, ...) :
text(getPool())
{
va_list args;
va_start (args, txt);
text.vprintf(txt, args);
va_end(args);
}
ArgsException::~ArgsException()
{
}
const char* ArgsException::getText() const
{
return text.c_str();
}

View File

@ -1,50 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
// ArgsException.h: interface for the ArgsException class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_ARGSEXCEPTION_H__0546C1B7_E895_4AC1_A951_AF1812A505B0__INCLUDED_)
#define AFX_ARGSEXCEPTION_H__0546C1B7_E895_4AC1_A951_AF1812A505B0__INCLUDED_
#if defined _MSC_VER && _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER > 1000
#include "../common/classes/fb_string.h"
class ArgsException : public Firebird::GlobalStorage
{
public:
ArgsException(const char* txt, ...);
virtual ~ArgsException();
const char* getText() const;
private:
Firebird::string text;
};
#endif // !defined(AFX_ARGSEXCEPTION_H__0546C1B7_E895_4AC1_A951_AF1812A505B0__INCLUDED_)

View File

@ -1,72 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
#include "firebird.h"
#include "ConfObj.h"
#include "ConfObject.h"
ConfObj::ConfObj()
{
object = NULL;
}
ConfObj::ConfObj(ConfObject* confObject)
{
if (object = confObject)
object->addRef();
}
ConfObj::ConfObj(ConfObj& source)
{
if (object = source.object)
object->addRef();
}
ConfObj::~ConfObj()
{
if (object)
object->release();
}
bool ConfObj::hasObject() const
{
return object != NULL;
}
ConfObject* ConfObj::operator = (ConfObject* source)
{
if (object)
object->release();
object = source;
if (object)
object->addRef();
return object;
}

View File

@ -1,57 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
#ifndef _CONFOBJ_H_
#define _CONFOBJ_H_
#include "../common/classes/alloc.h"
START_NAMESPACE
class ConfObject;
class ConfObj : public Firebird::GlobalStorage
{
public:
ConfObj();
explicit ConfObj(ConfObject* confObject);
ConfObj(ConfObj& source);
~ConfObj();
operator ConfObject*() { return object; }
ConfObject* operator -> () { return object; }
const ConfObject* operator -> () const { return object; }
ConfObject* operator = (ConfObject* source);
bool hasObject() const;
private:
ConfObject *object;
};
END_NAMESPACE
#endif

View File

@ -1,384 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
#include <string.h>
#include <memory.h>
#include "firebird.h"
#include "../jrd/common.h"
#include "ConfObject.h"
#include "Element.h"
#include "AdminException.h"
#include "ConfigFile.h"
#include "PathName.h"
#ifdef _WIN32
#ifndef strcasecmp
#define strcasecmp stricmp
//#define strncasecmp strnicmp
#endif
#endif
#define IS_DIGIT(c) (c >= '0' && c <= '9')
struct BooleanName
{
const char *string;
bool value;
};
static const BooleanName booleanNames [] =
{
{"yes", true},
{"true", true},
{"false", false},
{"no", false},
{NULL}
};
ConfObject::ConfObject(ConfigFile *confFile) :
source(getPool()), tempValue(getPool())
{
configFile = confFile;
configFile->addRef();
object = NULL;
chain = NULL;
}
ConfObject::~ConfObject()
{
configFile->release();
if (chain)
chain->release();
}
bool ConfObject::matches(Element* element, const char* type, const char* string)
{
if (element->name != type)
return false;
const Element *attribute = element->findAttribute (0);
if (!attribute)
return false;
//const char *name = configFile->translate (attribute->name, attribute->name);
const Firebird::string name = expand (attribute->name.c_str());
numberStrings = 0;
end = buffer + sizeof (buffer);
next = buffer;
if (!match (0, name.c_str(), string))
return false;
object = element;
source = string;
return true;
}
void ConfObject::putString(int position, const char* string, int stringLength)
{
if (position >= MAX_STRINGS)
throw AdminException("ConfObject: string segments overflow");
strings [position] = next;
if (next + stringLength + 1 >= end)
throw AdminException ("ConfObject: string overflow");
memcpy (next, string, stringLength);
next [stringLength] = 0;
next += stringLength + 1;
if (position >= numberStrings)
numberStrings = position + 1;
}
bool ConfObject::match(int position, const char* pattern, const char* string)
{
char c;
const char *s = string;
for (const char *p = pattern; (c = *p++); ++s)
{
if (c == '*')
{
if (!*p)
{
putString (position, string, (int) strlen (string));
return true;
}
for (; *s; ++s)
{
if (match (position + 1, pattern + 1, s))
{
putString (position, string, (int) (s - string));
return true;
}
}
return false;
}
if (!*s)
return false;
if (c != '%' && c != *s)
{
#ifdef _WIN32
if (UPPER (c) == UPPER (*s))
continue;
if ((c == '/' || c == '\\') && (*s == '/' || *s == '\\'))
continue;
#endif
return false;
}
}
if (c || *s)
return false;
putString (position, string, (int) strlen (string));
return true;
}
const char* ConfObject::getValue (const char* option, const char *defaultValue)
{
const Element *element = findAttribute (option);
if (!element)
return defaultValue;
tempValue = expand (getValue (element));
return tempValue.c_str();
}
int ConfObject::getValue(const char* option, int defaultValue)
{
Element *element = findAttribute (option);
if (!element)
return defaultValue;
const Firebird::string value (expand (getValue (element)));
int n = 0;
for (const char *p = value.c_str(); *p;)
{
const char c = *p++;
if (c >= '0' && c <= '9')
n = n * 10 + c - '0';
else
throw AdminException ("expected numeric value for option \"%s\", got \"%s\"", option, value.c_str());
}
return n;
}
bool ConfObject::getValue(const char* option, bool defaultValue)
{
const Element *element = findAttribute (option);
if (!element)
return defaultValue;
const Firebird::string value = expand (getValue (element));
const char* valueName = value.c_str();
for (const BooleanName *name = booleanNames; name->string; ++name)
{
if (strcasecmp (name->string, valueName) == 0)
return name->value;
}
throw AdminException ("expected boolean value for option \"%s\", got \"%s\"", option, value.c_str());
}
Firebird::string ConfObject::expand(const char* rawValue)
{
if (!rawValue)
return "";
char temp [1024];
char *p = temp;
const char* const temp_end = temp + sizeof(temp) - 1;
bool changed = false;
// FIX THIS: detect overflow instead of silenty truncating content, as it's done in ConfigFile::expand
for (const char *s = rawValue; *s;)
{
char c = *s++;
if (c == '$')
{
if (*s == '(')
{
++s;
char name [256];
char* n = name;
while (*s && (c = *s++) != ')' && n < name + sizeof(name) - 1)
*n++ = c;
*n = 0;
const char *subst = configFile->translate (name, object);
if (!subst)
throw AdminException ("can't substitute for \"%s\"", name);
changed = true;
for (const char *t = subst; *t && p < temp_end;)
*p++ = *t++;
}
else
{
int n = 0;
while (IS_DIGIT (*s))
n = n * 10 + *s++ - '0';
if (n > numberStrings)
throw AdminException ("substitution index exceeds available segments");
for (const char *t = (n == 0) ? source.c_str() : strings [n - 1]; *t && p < temp_end;)
*p++ = *t++;
}
}
else if (p < temp_end)
*p++ = c;
}
*p = 0;
if (!changed)
return temp;
return temp;
}
Firebird::string ConfObject::getValue(const char* attributeName)
{
const Element *attribute = findAttribute (attributeName);
if (!attribute)
return "";
return expand (getValue (attribute));
}
const char* ConfObject::getValue(int instanceNumber, const char* attributeName)
{
const Element *attribute = findAttribute (attributeName);
if (!attribute)
return "";
const Element *val = attribute->findAttribute (instanceNumber);
if (!val)
return "";
tempValue = expand (val->name.c_str());
return tempValue.c_str();
}
const char* ConfObject::getConcatenatedValues(const char* attributeName)
{
const Element *attribute = findAttribute (attributeName);
if (!attribute)
return "";
Firebird::string value;
for (const Element *att = attribute->getAttributes(); att; att = att->sibling)
{
if (value.hasData())
value += " ";
value += att->name;
}
tempValue = value;
return tempValue.c_str();
}
Element* ConfObject::findAttribute(const char* attributeName)
{
if (object)
{
Element *element = object->findChild (attributeName);
if (element)
return element;
}
if (chain)
return chain->findAttribute (attributeName);
return configFile->findGlobalAttribute (attributeName);
}
ConfObject* ConfObject::getChain()
{
return chain;
}
void ConfObject::setChain(ConfObject* obj)
{
if (chain)
chain->release();
if (chain = obj)
chain->addRef();
}
const char* ConfObject::getValue(const Element* attribute)
{
if (!attribute)
return NULL;
const Element *value = attribute->findAttribute (0);
if (!value)
return NULL;
return value->name.c_str();
}
const char* ConfObject::getName()
{
if (!object)
return NULL;
const Element *attribute = object->findAttribute (0);
if (!attribute)
return NULL;
return attribute->name.c_str();
}
ConfObject* ConfObject::findObject(const char* objectType, const char* objectName)
{
return configFile->findObject(objectType, objectName);
}

View File

@ -1,82 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
#ifndef _CONFOBJECT_H_
#define _CONFOBJECT_H_
#include "../common/classes/fb_string.h"
#include "../vulcan/RefObject.h"
START_NAMESPACE
class Element;
class ConfigFile;
class ConfObject : public RefObject, public Firebird::GlobalStorage
{
public:
explicit ConfObject(ConfigFile *confFile);
virtual ~ConfObject();
virtual const char* getValue(const char* option, const char *defaultValue);
virtual int getValue(const char* option, int defaultValue);
virtual bool getValue(const char* option, bool defaultValue);
virtual const char* getValue(int instanceNumber, const char* attributeName);
virtual bool matches(Element* element, const char* type, const char* string);
virtual void setChain(ConfObject* object);
virtual const char* getName();
virtual const char* getConcatenatedValues(const char* attributeName);
virtual Firebird::string expand(const char* rawValue);
virtual ConfObject* findObject(const char* objectType, const char* objectName);
virtual ConfObject* getChain();
protected:
virtual void putString(int position, const char* string, int stringLength);
virtual bool match(int position, const char* p1, const char* p2);
virtual Firebird::string getValue(const char* attributeName);
virtual Element* findAttribute(const char* attributeName);
virtual const char* getValue(const Element* attribute);
public:
Element* object;
private:
enum { MAX_STRINGS = 32 };
ConfObject* chain;
ConfigFile* configFile;
Firebird::string source;
Firebird::string tempValue;
int numberStrings;
const char* strings [MAX_STRINGS];
char buffer [1024];
char* next;
const char* end;
};
END_NAMESPACE
#endif

View File

@ -1,373 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
#include "firebird.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include "../common/classes/alloc.h"
#include "ConfigFile.h"
#include "ConfObject.h"
#include "InputFile.h"
#include "Element.h"
#include "AdminException.h"
#include "ScanDir.h"
#include "../common/config/config.h"
#ifdef _WIN32
#include <windows.h>
#define IS_SEPARATOR(c) (c == '\\' || c == '/')
#ifndef strcasecmp
#define strcasecmp stricmp
//#define strncasecmp strnicmp
#endif
//#define KEY "SOFTWARE\\Firebird Project\\Firebird Server\\Instances"
//#define SUB_KEY NULL
//#define PATH_KEY "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\Firebird"
#else
#define IS_SEPARATOR(c) (c == '/')
#endif
ConfigFile::ConfigFile(const LEX_flags configFlags) :
Lex ("/<>=", configFlags),
rootDirectory(getPool()), installDirectory(getPool()), currentDirectory(getPool())
{
init (configFlags);
}
ConfigFile::ConfigFile(const char* configFile, const LEX_flags configFlags) :
Lex ("/<>=", configFlags),
rootDirectory(getPool()), installDirectory(getPool()), currentDirectory(getPool())
{
init (configFlags);
InputFile *inputFile = new InputFile;
Firebird::PathName expandedFile (expand (configFile));
if (!inputFile->openInputFile(expandedFile.c_str()))
{
delete inputFile;
throw AdminException ("can't open configuration file \"%s\"", configFile);
}
pushStream (inputFile);
parse();
}
void ConfigFile::init(const LEX_flags configFlags)
{
flags = configFlags;
setLineComment ("#");
setContinuationChar ('\\');
objects = NULL;
memset (hashTable, 0, sizeof (hashTable));
}
ConfigFile::~ConfigFile()
{
delete objects;
for (int n = 0; n < HASH_SIZE; ++n)
{
for (Element *element; element = hashTable [n];)
{
hashTable [n] = element->sibling;
delete element;
}
}
}
InputFile* ConfigFile::openConfigFile()
{
fb_assert(false);
// Vulcan specific code removed
return NULL;
}
void ConfigFile::addText(const char* text)
{
InputStream *stream = new InputStream(text);
pushStream(stream);
}
void ConfigFile::parse()
{
objects = new Element ("ConfObjects");
getToken();
while (tokenType != END_OF_STREAM)
{
while (match ("include"))
{
Firebird::PathName fileName = expand (reparseFilename());
if (fileName.find('*') != Firebird::PathName::npos)
wildCardInclude(fileName.c_str());
else
pushStream (new InputFile (fileName.c_str()));
getToken();
}
if (match ("<"))
objects->addChild (parseObject());
else
{
Element *element = parseAttribute();
const int slot = element->name.hash (HASH_SIZE);
element->sibling = hashTable [slot];
hashTable [slot] = element;
}
}
}
Element* ConfigFile::parseObject()
{
const Firebird::string name = getName();
Element *element = new Element (name);
element->setSource (priorLineNumber, priorInputStream);
while (!match (">"))
{
element->addAttribute (new Element (reparseFilename().ToString()));
getToken();
}
for (;;)
{
if (match ("<"))
{
if (match ("/"))
{
if (!match (element->name.c_str()))
syntaxError ("closing element");
if (!match (">"))
syntaxError ("\">\"");
element->numberLines = priorLineNumber - element->lineNumber + 1;
return element;
}
element->addChild (parseObject());
}
else
element->addChild (parseAttribute());
}
}
Element* ConfigFile::parseAttribute()
{
Element *element = new Element (getName());
element->setSource (priorLineNumber, priorInputStream);
match ("=");
while (!eol)
{
element->addAttribute (new Element (reparseFilename().ToString()));
getToken();
}
element->numberLines = priorLineNumber - element->lineNumber + 1;
return element;
}
ConfObject* ConfigFile::findObject(const char* objectType, const char* objectName)
{
if (!objects)
return NULL;
ConfObject *object = new ConfObject (this);
for (Element *child = objects->children; child; child = child->sibling)
{
if (object->matches (child, objectType, objectName))
return object;
}
object->release();
return NULL;
}
const char* ConfigFile::getRootDirectory()
{
return Config::getRootDirectory();
}
ConfObject* ConfigFile::getObject(const char* /*objectType*/)
{
return new ConfObject (this);
}
Element* ConfigFile::findGlobalAttribute(const char *attributeName)
{
for (Element *element = hashTable [Firebird::string::hash (attributeName, HASH_SIZE)]; element; element = element->sibling)
{
if (element->name == attributeName)
return element;
}
return NULL;
}
const char* ConfigFile::getInstallDirectory()
{
return Config::getInstallDirectory();
}
Firebird::PathName ConfigFile::expand(const Firebird::PathName& rawString)
{
const char* const errstr = "filename expansion reached implementation limit at %d";
char temp [1024];
char* p = temp;
const char* const temp_end = temp + sizeof(temp) - 1;
bool change = false;
for (const char *s = rawString.c_str(); *s;)
{
char c = *s++;
if (c == '$')
{
if (*s == '(')
{
++s;
change = true;
char name [256];
const char* const name_end = name + sizeof(name) - 1;
char* n = name;
bool overflow = false;
while (*s && (c = *s++) != ')' && !overflow)
{
if (n < name_end)
*n++ = c;
else
overflow = true;
}
*n = 0;
if (overflow)
{
n[-3] = n[-2] = n[-1] = '.';
throw AdminException("name to be substituted \"%s\" is too long", name);
}
const char *subst = translate (name, NULL);
if (!subst)
throw AdminException ("can't substitute for \"%s\"", name);
for (const char *t = subst; *t;)
{
if (p < temp_end)
*p++ = *t++;
else
throw AdminException(errstr, sizeof(temp) - 1);
}
}
}
else if (p < temp_end)
*p++ = c;
else
throw AdminException(errstr, sizeof(temp) - 1);
}
if (!change)
return rawString;
*p = 0;
return temp;
}
const char* ConfigFile::translate(const char* value, const Element* object)
{
if (strcasecmp (value, "root") == 0)
return getRootDirectory();
if (strcasecmp (value, "install") == 0)
return getInstallDirectory();
if (strcasecmp (value, "this") == 0)
{
const char *source = NULL;
if (object && object->inputStream)
source = object->inputStream->getFileName();
if (!source && inputStream)
source = inputStream->getFileName();
if (!source)
throw AdminException("no context for $(this)");
const Firebird::PathName currentFile = expand (source);
const char *fileName = currentFile.c_str();
const char *p = NULL;
for (const char *q = fileName; *q; ++q)
{
if (IS_SEPARATOR(*q))
p = q;
}
if (p)
currentDirectory = Firebird::PathName(fileName, p - fileName);
else
currentDirectory = ".";
return currentDirectory.c_str();
}
return NULL;
}
void ConfigFile::wildCardInclude(const char* fileName)
{
char directory [256];
if (strlen(fileName) >= sizeof(directory))
throw AdminException("Too long filename in wildCardInclude()");
strcpy (directory, fileName);
const char *wildcard = fileName;
char *p = strrchr (directory, '/');
if (p)
{
*p = 0;
wildcard = p + 1;
}
else
directory [0] = 0;
// OK, expand wildcard
ScanDir scanDir (directory, wildcard);
while (scanDir.next())
pushStream (new InputFile (scanDir.getFilePath()));
}

View File

@ -1,83 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
#ifndef _ConfigFile_h_
#define _ConfigFile_h_
#include "../config/Lex.h"
#include "../vulcan/RefObject.h"
#include "../common/classes/fb_string.h"
//static const int CONFIG_trace = 1;
//static const int CONFIG_list = 2;
//static const int CONFIG_verbose = 4;
START_NAMESPACE
class InputFile;
class Element;
class ConfObject;
class ConfigFile : public Lex, public RefObject
{
public:
explicit ConfigFile(const LEX_flags configFlags);
ConfigFile(const char* configFile, const LEX_flags configFlags);
//protected:
virtual ~ConfigFile();
public:
InputFile* openConfigFile();
void addText(const char* text);
void parse();
Element* parseObject();
Element* parseAttribute();
ConfObject* findObject(const char* objectType, const char* objectName);
const char* getRootDirectory();
ConfObject* getObject(const char* objectType);
Element* findGlobalAttribute(const char *attributeName);
const char* getInstallDirectory();
virtual Firebird::PathName expand(const Firebird::PathName& rawString);
const char* translate(const char* value, const Element* object);
void wildCardInclude(const char* fileName);
const Element* getObjects() const { return objects; }
private:
enum { HASH_SIZE = 101 };
void init(const LEX_flags configFlags);
Element* objects;
Firebird::PathName rootDirectory;
Firebird::PathName installDirectory;
Firebird::PathName currentDirectory;
Element* hashTable [HASH_SIZE];
};
END_NAMESPACE
#endif

View File

@ -1,96 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
#include "firebird.h"
#include "../common/classes/alloc.h"
#include "Configuration.h"
#include "ConfigFile.h"
// This var could be a static member of the class.
static ConfigFile* configFile;
// Non MT-safe code follows, maybe it was intended?
Configuration::Configuration()
{
fb_assert(!configFile); // only one instance of Configuration at a given time.
configFile = NULL;
}
Configuration::~Configuration()
{
if (configFile)
{
configFile->release();
configFile = NULL;
}
}
ConfObject* Configuration::findObject(const char* objectType, const char* objectName)
{
if (!configFile)
loadConfigFile();
return configFile->findObject (objectType, objectName);
}
const char* Configuration::getRootDirectory()
{
if (!configFile)
loadConfigFile();
return configFile->getRootDirectory();
}
void Configuration::loadConfigFile()
{
if (!configFile)
configFile = new ConfigFile (ConfigFile::LEX_none);
}
void Configuration::setConfigFilePath(const char* filename)
{
if (!configFile)
configFile = new ConfigFile (filename, ConfigFile::LEX_none);
}
ConfObject* Configuration::getObject(const char* objectType)
{
if (!configFile)
loadConfigFile();
return configFile->getObject (objectType);
}
ConfObject* Configuration::getObject(const char* objectType, const char* objectName)
{
ConfObject* object = findObject (objectType, objectName);
if (!object)
object = getObject (objectType);
return object;
}

View File

@ -1,53 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
#ifndef _CONFIGURATION_H_
#define _CONFIGURATION_H_
#include "../common/classes/alloc.h"
START_NAMESPACE
class ConfigFile;
class ConfObject;
class Configuration : public Firebird::GlobalStorage
{
public:
Configuration();
virtual ~Configuration();
static ConfObject* findObject(const char* objectType, const char* objectName);
static const char* getRootDirectory();
static void loadConfigFile();
static void setConfigFilePath(const char* filename);
static ConfObject* getObject(const char* objectType);
static ConfObject* getObject(const char* objectType, const char* objectName);
};
END_NAMESPACE
#endif

View File

@ -1,497 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
// Element.cpp: implementation of the Element class.
//
//////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <string.h>
//#include <stdlib.h>
//#include "Engine.h"
#include "firebird.h"
#include "../common/classes/alloc.h"
#include "Element.h"
#include "Stream.h"
#include "InputStream.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
static const int quoted = 1;
static const int illegal = 2;
static int charTable [256];
inline void setCharTable(UCHAR pos, int val)
{
charTable[pos] = val;
}
static int init();
static int foo = init();
int init()
{
setCharTable('<', quoted);
setCharTable('>', quoted);
setCharTable('&', quoted);
for (int n = 0; n < 10; ++n)
charTable[n] = illegal;
return 0;
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
Element::Element(const Firebird::string& elementName) :
name(getPool()), value(getPool()), innerText(getPool())
{
init (elementName);
}
Element::Element(const Firebird::string& elementName, const Firebird::string& elementValue) :
name(getPool()), value(getPool()), innerText(getPool())
{
init (elementName);
value = elementValue;
}
void Element::init(const Firebird::string& elementName)
{
name = elementName;
attributes = NULL;
sibling = NULL;
children = NULL;
parent = NULL;
lineNumber = 0;
numberLines = 0;
inputStream = NULL;
}
Element::~Element()
{
Element *child;
while (child = children)
{
children = child->sibling;
delete child;
}
while (child = attributes)
{
attributes = child->sibling;
delete child;
}
if (inputStream)
inputStream->release();
}
void Element::addChild(Element *child)
{
child->parent = this;
child->sibling = NULL;
Element** ptr = &children;
while (*ptr)
ptr = &(*ptr)->sibling;
*ptr = child;
}
Element* Element::addChild(const Firebird::string& childName)
{
Element *element = new Element (childName);
addChild (element);
return element;
}
void Element::addAttribute(Element *child)
{
child->parent = this;
child->sibling = NULL;
Element** ptr = &attributes;
while (*ptr)
ptr = &(*ptr)->sibling;
*ptr = child;
}
void Element::addAttribute(const Firebird::string& attributeName)
{
addAttribute (new Element (attributeName));
}
Element* Element::addAttribute(const Firebird::string& attributeName, const Firebird::string& attributeValue)
{
Element *attribute = new Element (attributeName, attributeValue);
addAttribute (attribute);
return attribute;
}
Element* Element::addAttribute(const Firebird::string& attributeName, int attributeValue)
{
Firebird::string buffer;
buffer.printf ("%d", attributeValue);
return addAttribute (attributeName, buffer);
}
void Element::print(int level) const
{
printf ("%*s%s", level * 3, "", name.c_str());
const Element *element;
for (element = attributes; element; element = element->sibling)
{
printf (" %s", element->name.c_str());
if (element->value != "")
printf ("=%s", (const char*) element->value.c_str());
}
printf ("\n");
++level;
for (element = children; element; element = element->sibling)
element->print (level);
}
Element* Element::findChild(const char *childName)
{
for (Element *child = children; child; child = child->sibling)
{
if (child->name == childName)
return child;
}
return NULL;
}
const Element* Element::findChild(const char *childName) const
{
for (const Element *child = children; child; child = child->sibling)
{
if (child->name == childName)
return child;
}
return NULL;
}
Element* Element::findAttribute(const char *childName)
{
for (Element *child = attributes; child; child = child->sibling)
{
if (child->name == childName)
return child;
}
return NULL;
}
const Element* Element::findAttribute(const char *childName) const
{
for (const Element *child = attributes; child; child = child->sibling)
{
if (child->name == childName)
return child;
}
return NULL;
}
Element* Element::findAttribute(int seq)
{
int n = 0;
for (Element *attribute = attributes; attribute; attribute = attribute->sibling)
{
if (n++ == seq)
return attribute;
}
return NULL;
}
const Element* Element::findAttribute(int seq) const
{
int n = 0;
for (const Element *attribute = attributes; attribute; attribute = attribute->sibling)
{
if (n++ == seq)
return attribute;
}
return NULL;
}
void Element::genXML(int level, Stream *stream) const
{
indent (level, stream);
stream->putCharacter ('<');
stream->putSegment (name.c_str());
for (const Element *attribute = attributes; attribute; attribute = attribute->sibling)
{
stream->putCharacter (' ');
stream->putSegment (attribute->name.c_str());
stream->putSegment ("=\"");
for (const char *p = attribute->value.c_str(); *p; ++p)
{
switch (*p)
{
case '"': stream->putSegment ("&quot;"); break;
case '\'': stream->putSegment ("&apos;"); break;
case '&': stream->putSegment ("&amp;"); break;
case '<': stream->putSegment ("&lt;"); break;
case '>': stream->putSegment ("&gt;"); break;
default: stream->putCharacter (*p); break;
}
}
//stream->putSegment (attribute->value);
stream->putCharacter ('"');
}
if (innerText.hasData())
{
stream->putCharacter('>');
putQuotedText(innerText.c_str(), stream);
}
else if (!children)
{
if (name.at(0) == '?')
stream->putSegment ("?>\n");
else
stream->putSegment ("/>\n");
return;
}
else
stream->putSegment (">\n");
++level;
for (const Element *child = children; child; child = child->sibling)
child->genXML (level, stream);
if (innerText.isEmpty())
indent (level - 1, stream);
stream->putSegment ("</");
stream->putSegment (name.c_str());
stream->putSegment (">\n");
}
void Element::indent(int level, Stream *stream) const
{
int count = level * 3;
for (int n = 0; n < count; ++n)
stream->putCharacter (' ');
}
Element* Element::findChildIgnoreCase(const char *childName)
{
for (Element *child = children; child; child = child->sibling)
{
if (child->name.equalsNoCase (childName))
return child;
}
return NULL;
}
const char* Element::getAttributeName(int position) const
{
const Element *element = findAttribute (position);
if (!element)
return NULL;
return element->name.c_str();
}
const char* Element::getAttributeValue(const char *attributeName)
{
return getAttributeValue (attributeName, NULL);
}
const char* Element::getAttributeValue(const char *attributeName, const char *defaultValue)
{
Element *attribute = findAttribute (attributeName);
if (!attribute)
return defaultValue;
return attribute->value.c_str();
}
void Element::setSource(int line, InputStream *stream)
{
lineNumber = line;
inputStream = stream;
inputStream->addRef();
}
void Element::gen(int level, Stream *stream) const
{
for (int n = 0; n < level; ++n)
stream->putSegment (" ");
if (children)
stream->putCharacter ('<');
stream->putSegment (name.c_str());
const Element *element;
for (element = attributes; element; element = element->sibling)
{
stream->putCharacter (' ');
stream->putSegment (element->name.c_str());
if (element->value != "")
{
stream->putCharacter ('=');
stream->putSegment (element->value.c_str());
}
}
if (!children)
{
stream->putCharacter ('\n');
return;
}
stream->putSegment (">\n");
++level;
for (element = children; element; element = element->sibling)
element->gen (level, stream);
stream->putSegment ("</");
stream->putSegment (name.c_str());
stream->putSegment (">\n");
}
Element* Element::findChild(const char *childName, const char *attribute, const char *attributeValue)
{
for (Element *child = children; child; child = child->sibling)
{
if (child->name == childName)
{
const char *p = child->getAttributeValue (attribute, NULL);
if (p && strcmp (p, attributeValue) == 0)
return child;
}
}
return NULL;
}
int Element::analyseText(const char* text)
{
int count = 0;
for (const char *p = text; *p; p++)
{
const int n = charTable[(UCHAR) *p];
if (n)
{
if (n & illegal)
return -1;
++count;
}
}
return count;
}
void Element::putQuotedText(const char* text, Stream* stream) const
{
const char *start = text;
const char *p;
for (p = text; *p; p++)
{
if (charTable[(UCHAR) *p])
{
const char* escape = NULL;
switch (*p)
{
case '>':
escape = "&gt;";
break;
case '<':
escape = "&lt;";
break;
case '&':
escape = "&amp;";
break;
default:
continue;
}
if (p > start)
stream->putSegment(p - start, start, true);
stream->putSegment(escape);
start = p + 1;
}
}
if (p > start)
stream->putSegment(p - start, start, true);
}
int Element::analyzeData(const UCHAR* bytes)
{
int count = 0;
for (const UCHAR *p = bytes; *p; p++)
{
const int n = charTable[*p];
if (n)
{
if (n & illegal)
return -1;
++count;
}
}
return count;
}

View File

@ -1,99 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
// Element.h: interface for the Element class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_ELEMENT_H__36AF5EE7_6842_4000_B3C5_DB8DECEC79B7__INCLUDED_)
#define AFX_ELEMENT_H__36AF5EE7_6842_4000_B3C5_DB8DECEC79B7__INCLUDED_
#if defined _MSC_VER && _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER > 1000
#include "../common/classes/fb_string.h"
START_NAMESPACE
class Stream;
class InputStream;
class Element : public Firebird::GlobalStorage
{
public:
explicit Element(const Firebird::string& elementName);
Element (const Firebird::string& elementName, const Firebird::string& elementValue);
virtual ~Element();
void addChild (Element *child);
Element* addChild (const Firebird::string& name);
void addAttribute (Element *child);
void addAttribute (const Firebird::string& name);
Element* addAttribute (const Firebird::string& name, const Firebird::string& value);
Element* addAttribute (const Firebird::string& name, int value);
Element* findChild (const char *name, const char *attribute, const char *value);
void gen (int level, Stream *stream) const;
void setSource (int line, InputStream *stream);
const char* getAttributeValue (const char *name, const char *defaultValue);
const char* getAttributeValue (const char *name);
const char* getAttributeName (int position) const;
Element* findChildIgnoreCase (const char *name);
void indent (int level, Stream *stream) const;
void genXML (int level, Stream *stream) const;
Element* findAttribute (const char *name);
const Element* findAttribute (const char *name) const;
Element* findAttribute (int seq);
const Element* findAttribute (int seq) const;
Element* findChild (const char *name);
const Element* findChild (const char *name) const;
void print (int level) const;
const Element* getAttributes() const { return attributes; }
Firebird::string name;
Firebird::string value;
Element *sibling;
Element *children;
int lineNumber;
int numberLines;
InputStream *inputStream;
static int analyseText(const char* text);
void putQuotedText(const char* text, Stream* stream) const;
static int analyzeData(const UCHAR* data);
private:
void init(const Firebird::string& elementName);
Firebird::string innerText;
Element *parent; // assigned but never used.
Element *attributes;
};
END_NAMESPACE
#endif // !defined(AFX_ELEMENT_H__36AF5EE7_6842_4000_B3C5_DB8DECEC79B7__INCLUDED_)

View File

@ -1,45 +0,0 @@
#include "firebird.h"
#include "FileName.h"
#ifdef WIN_NT
#define IS_SLASH(c) (c == '/' || c == '\\')
#else
#define IS_SLASH(c) (c == '/')
#endif
FileName::FileName(const Firebird::PathName& name) :
pathName(getPool()), directory(getPool()), root(getPool()), extension(getPool())
{
pathName = name;
const char* const start = pathName.c_str();
const char* slash = NULL;
const char* dot = NULL;
const char* rootName = start;
absolute = IS_SLASH (start [0]);
for (const char* p = start; *p; ++p)
{
if (!dot && IS_SLASH (*p))
slash = p;
else if (*p == '.')
dot = p;
}
if (slash)
{
directory.assign (start, (int) (slash - rootName));
rootName = slash + 1;
}
if (dot)
{
extension = dot + 1;
root.assign (rootName, (int) (dot - rootName));
}
else
root = rootName;
}
FileName::~FileName()
{
}

View File

@ -1,22 +0,0 @@
#ifndef _FILENAME_H_
#define _FILENAME_H_
#include "../common/classes/fb_string.h"
class FileName : public Firebird::GlobalStorage
{
public:
explicit FileName(const Firebird::PathName& name);
~FileName();
Firebird::PathName pathName;
Firebird::PathName directory;
Firebird::PathName root;
Firebird::PathName extension;
bool isAbsolute() const { return absolute; }
private:
bool absolute;
};
#endif

View File

@ -1,235 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
// InputFile.cpp: implementation of the InputFile class.
//
//////////////////////////////////////////////////////////////////////
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_IO_H
#include <io.h>
#endif
#include <stdio.h>
#include <string.h>
#include "firebird.h"
#include "../common/classes/alloc.h"
#include "InputFile.h"
#include "AdminException.h"
#define ISLOWER(c) (c >= 'a' && c <= 'z')
//#define ISUPPER(c) (c >= 'A' && c <= 'Z')
//#define ISDIGIT(c) (c >= '0' && c <= '9')
#ifndef UPPER
#define UPPER(c) ((ISLOWER (c)) ? c - 'a' + 'A' : c)
#endif
static const int BACKUP_FILES = 5;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
InputFile::InputFile(const char *name) : fileName(getPool())
{
changes = NULL;
file = NULL;
if (!openInputFile (name))
throw AdminException ("can't open file \"%s\"", name);
}
InputFile::InputFile() : fileName(getPool())
{
changes = NULL;
file = NULL;
}
InputFile::~InputFile()
{
close();
for (FileChange *change; change = changes;)
{
changes = change->next;
delete change;
}
}
void InputFile::close()
{
if (file)
{
fclose ((FILE*) file);
file = NULL;
}
}
const char* InputFile::getSegment()
{
if (!file)
throw AdminException ("file has been closed");
if (!fgets (buffer, sizeof (buffer), (FILE*) file))
return NULL;
//++lineNumber;
segmentLength = (int) strlen (buffer);
return buffer;
}
const char* InputFile::getFileName() const
{
return fileName.c_str();
}
InputFile* InputFile::getInputFile()
{
return this;
}
void InputFile::postChange(int line, int skip, const Firebird::string& insertion)
{
FileChange *change = new FileChange;
change->lineNumber = line;
change->linesSkipped = skip;
change->insertion = insertion;
for (FileChange **p = &changes;; p = &(*p)->next)
{
FileChange *next = *p;
if (!next || next->lineNumber > change->lineNumber)
{
change->next = *p;
*p = change;
break;
}
}
}
/* Commented out by Alex as unused and problematic.
void InputFile::rewrite()
{
FILE *input = fopen (fileName.c_str(), "r");
if (!input)
throw AdminException ("can't open \"%s\" for input", fileName.c_str());
Firebird::PathName tempName;
tempName.printf("%.*s.tmp", MAXPATHLEN - 5, fileName.c_str());
FILE *output = fopen (tempName.c_str(), "w");
if (!output)
throw AdminException ("can't open \"%s\" for output", tempName.c_str());
char temp [1024];
int line = 0;
for (FileChange *change = changes; change; change = change->next)
{
for (; line < change->lineNumber; ++line)
{
if (fgets (temp, sizeof (temp), input))
fputs (temp, output);
}
//fputs ("#insertion starts here\n", output);
fputs (change->insertion.c_str(), output);
//fputs ("#insertion end here\n", output);
for (int n = 0; n < change->linesSkipped; ++n)
fgets (temp, sizeof (temp), input);
line += change->linesSkipped;
}
while (fgets (temp, sizeof (temp), input))
fputs (temp, output);
fclose (input);
fclose (output);
Firebird::PathName filename1, filename2;
fb_assert(BACKUP_FILES < 10); // assumption to avoid too long filenames
for (int n = BACKUP_FILES; n >= 0; --n)
{
filename1.printf("%.*s.%d", MAXPATHLEN - 3, fileName.c_str(), n);
if (n)
filename2.printf("%.*s.%d", MAXPATHLEN - 3, fileName.c_str(), n - 1);
else
filename2 = fileName; // limited to correct length in openInputFile
if (n == BACKUP_FILES)
unlink (filename1.c_str());
rename (filename2.c_str(), filename1.c_str());
}
if (rename (tempName.c_str(), fileName.c_str()))
perror ("rename");
}
*/
bool InputFile::pathEqual(const char *path1, const char *path2)
{
#ifdef _WIN32
for (; *path1 && *path2; ++path1, ++path2)
{
if (*path1 != *path2 &&
UPPER (*path1) != UPPER (*path2) &&
!((*path1 == '/' || *path1 == '\\') &&
(*path2 == '/' || *path2 == '\\')))
{
return false;
}
}
#else
for (; *path1 && *path2; ++path1, ++path2)
{
if (*path1 != *path2)
return false;
}
#endif
return *path1 == 0 && *path2 == 0;
}
bool InputFile::openInputFile(const char* name)
{
// It's good idea to keep file names limited to meet OS requirements
if (!name || strlen(name) >= MAXPATHLEN)
return false;
if (!(file = fopen (name, "r")))
return false;
fileName = name;
segment = buffer;
changes = NULL;
return true;
}

View File

@ -1,78 +0,0 @@
// InputFile.h: interface for the InputFile class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_INPUTFILE_H__8FAAB146_720E_43EE_A79B_262761DD0921__INCLUDED_)
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
#define AFX_INPUTFILE_H__8FAAB146_720E_43EE_A79B_262761DD0921__INCLUDED_
#if defined _MSC_VER && _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER > 1000
#include "InputStream.h"
#include "../common/classes/fb_string.h"
START_NAMESPACE
class InputFile : public InputStream
{
public:
explicit InputFile(const char* name);
InputFile();
virtual ~InputFile();
static bool pathEqual(const char *path1, const char *path2);
// void rewrite();
void postChange (int lineNumber, int skip, const Firebird::string& insertion);
virtual InputFile* getInputFile();
virtual const char* getFileName() const;
virtual const char* getSegment();
virtual void close();
bool openInputFile(const char* fileName); // caller is ConfigFile.cpp
private:
struct FileChange : public Firebird::GlobalStorage
{
FileChange *next;
int lineNumber;
int linesSkipped;
Firebird::string insertion;
public:
FileChange() : insertion(getPool()) { }
};
void *file;
char buffer [1024];
Firebird::PathName fileName;
FileChange* changes;
};
END_NAMESPACE
#endif // !defined(AFX_INPUTFILE_H__8FAAB146_720E_43EE_A79B_262761DD0921__INCLUDED_)

View File

@ -1,113 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
// InputStream.cpp: implementation of the InputStream class.
//
//////////////////////////////////////////////////////////////////////
#include <string.h>
#include <stdio.h>
#include "firebird.h"
#include "../jrd/common.h"
#include "InputStream.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
InputStream::InputStream()
{
init();
segmentLength = 0;
}
InputStream::InputStream(const char* stuff)
{
init();
segment = stuff;
segmentLength = (int) strlen (segment);
}
InputStream::~InputStream()
{
}
void InputStream::init()
{
prior = NULL;
ptr = segment;
useCount = 1;
lineNumber = 0;
segment = NULL;
segmentOffset = 0;
}
const char* InputStream::getSegment()
{
if (segmentOffset)
return NULL;
segmentOffset = 1;
return segment;
}
int InputStream::getOffset(const char* pointer)
{
return (int) (segmentOffset + pointer - segment);
}
const char* InputStream::getEnd()
{
return segment + segmentLength;
}
void InputStream::close()
{
}
void InputStream::addRef()
{
++useCount;
}
void InputStream::release()
{
if (--useCount == 0)
delete this;
}
const char* InputStream::getFileName() const
{
return NULL;
}
InputFile* InputStream::getInputFile()
{
return NULL;
}

View File

@ -1,75 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
// InputStream.h: interface for the InputStream class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_INPUTSTREAM_H__63114A0E_18FF_41F4_85A4_CCB8711487C7__INCLUDED_)
#define AFX_INPUTSTREAM_H__63114A0E_18FF_41F4_85A4_CCB8711487C7__INCLUDED_
#if defined _MSC_VER && _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER > 1000
#include "../common/classes/alloc.h"
START_NAMESPACE
class InputFile;
class InputStream : public Firebird::GlobalStorage
{
public:
explicit InputStream (const char* stuff);
InputStream();
virtual ~InputStream();
virtual InputFile* getInputFile();
virtual const char* getFileName() const;
void init();
void release();
virtual void addRef();
virtual void close();
virtual const char* getEnd();
virtual int getOffset (const char* ptr);
virtual const char* getSegment();
int lineNumber;
const char* segment;
const char* ptr;
InputStream* prior;
protected:
int segmentLength; // used by InputFile
private:
int segmentOffset;
int useCount;
};
END_NAMESPACE
#endif // !defined(AFX_INPUTSTREAM_H__63114A0E_18FF_41F4_85A4_CCB8711487C7__INCLUDED_)

View File

@ -1,400 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
// Lex.cpp: implementation of the Lex class.
//
//////////////////////////////////////////////////////////////////////
#include <string.h>
#include <stdio.h>
#include <memory.h>
#include "firebird.h"
#include "Lex.h"
#include "AdminException.h"
#include "InputStream.h"
#define WHITE_SPACE " \t\n\r"
//#define PUNCTUATION_CHARS "<>="
//#define MULTI_CHARS "" //"+=*/%!~<>~^|&="
//#define MAX_TOKEN 1024
#define UPCASE(c) ((c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c)
const int TYPE_WHITE = 1;
const int TYPE_PUNCT = 2;
//const int TYPE_MULTI_CHAR = 4;
const int TYPE_DIGIT = 8;
//#define TERM (TYPE_WHITE | TYPE_PUNCT)
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
Lex::Lex(const char* punctuation, const LEX_flags debugFlags)
{
lineComment = NULL;
commentStart = NULL;
memset (charTableArray, 0, sizeof (charTableArray));
setCharacters (TYPE_PUNCT, punctuation);
setCharacters (TYPE_WHITE, WHITE_SPACE);
setCharacters (TYPE_DIGIT, "0123456789");
ptr = end = NULL;
inputStream = NULL;
tokenType = TT_NONE;
lineNumber = 0;
continuationChar = 0;
captureStart = captureEnd = 0;
flags = debugFlags;
}
Lex::~Lex()
{
if (inputStream)
inputStream->release();
}
void Lex::skipWhite()
{
for (;;)
{
while (ptr >= end)
{
if (!getSegment())
return;
}
while (ptr < end)
{
if (lineComment && lineComment [0] == *ptr && match (lineComment, ptr))
{
while (ptr < end && *ptr++ != '\n')
;
++inputStream->lineNumber;
}
else if (commentStart && commentStart [0] == *ptr && match (commentStart, ptr))
{
ptr += strlen (commentStart);
while (ptr < end)
{
if (commentEnd [0] == *ptr && match (commentEnd, ptr))
{
ptr += strlen (commentEnd);
break;
}
if (*ptr++ == '\n')
++inputStream->lineNumber;
}
}
else if (*ptr == continuationChar && ptr [1] == '\n')
{
ptr += 2;
++inputStream->lineNumber;
}
else if (charTable(*ptr) & TYPE_WHITE)
{
if (*ptr++ == '\n')
{
eol = true;
++inputStream->lineNumber;
}
}
else
return;
}
}
}
// Just another custom memcmp-like routine.
bool Lex::match(const char *pattern, const char *string)
{
while (*pattern && *string)
{
if (*pattern++ != *string++)
return false;
}
return *pattern == 0;
}
void Lex::getToken()
{
priorInputStream = tokenInputStream;
priorLineNumber = tokenLineNumber;
if (tokenType == END_OF_STREAM)
throw AdminException ("expected token, got end-of-file");
eol = false;
skipWhite();
if (tokenInputStream = inputStream)
tokenLineNumber = inputStream->lineNumber;
if (ptr >= end)
{
tokenType = END_OF_STREAM;
strcpy (token, "-end-of-file-");
return;
}
tokenOffset = inputStream->getOffset (ptr);
char *p = token;
const char* const endToken = token + sizeof(token) - 1; // take into account the '\0'
const char c = *p++ = *ptr++;
if (charTable(c) & TYPE_PUNCT)
tokenType = TT_PUNCT;
else if (c == '\'' || c == '"')
{
p = token;
for (;;)
{
if (ptr >= end)
{
if (!getSegment())
throw AdminException ("end of file in quoted string");
}
else if (*ptr == c)
break;
else
{
if (p >= endToken)
throw AdminException ("token overflow in quoted string");
*p++ = *ptr++;
}
}
++ptr;
tokenType = (c == '"') ? QUOTED_STRING : SINGLE_QUOTED_STRING;
}
else if (charTable(c) & TYPE_DIGIT)
{
tokenType = TT_NUMBER;
while (ptr < end && (charTable(*ptr) & TYPE_DIGIT))
{
if (p >= endToken)
throw AdminException ("token overflow in number");
*p++ = *ptr++;
}
}
else
{
tokenType = TT_NAME;
if (flags & LEX_upcase)
{
p [-1] = UPCASE(c);
while (ptr < end && !(charTable(*ptr) & (TYPE_WHITE | TYPE_PUNCT)))
{
if (p >= endToken)
throw AdminException ("token overflow in name (uppercase)");
const char c2 = *ptr++;
*p++ = UPCASE(c2);
}
}
else
{
while (ptr < end && !(charTable(*ptr) & (TYPE_WHITE | TYPE_PUNCT)))
{
if (p >= endToken)
throw AdminException ("token overflow in name");
*p++ = *ptr++;
}
}
}
*p = 0;
}
void Lex::setCharacters(int type, const char *characters)
{
for (const char *p = characters; *p; ++p)
charTable(*p) |= type;
}
/***
void Lex::openFile(const char *fileName)
{
inputStream = new InputFile (fileName, inputStream);
}
***/
void Lex::setLineComment(const char *string)
{
lineComment = string;
}
void Lex::setCommentString(const char *start, const char *cend)
{
commentStart = start;
commentEnd = cend;
}
bool Lex::isKeyword(const char *word) const
{
return strcmp (token, word) == 0;
}
bool Lex::match(const char *word)
{
if (!isKeyword (word))
return false;
if (*word == captureStart)
captureStuff();
getToken();
return true;
}
Firebird::PathName Lex::reparseFilename()
{
char *p = token;
while (*p)
++p;
while (ptr < end && *ptr != '>' && !(charTable(*ptr) & TYPE_WHITE))
*p++ = *ptr++;
*p = 0;
const Firebird::PathName string = token;
//getToken();
return string;
}
Firebird::string Lex::getName()
{
if (tokenType != TT_NAME)
syntaxError ("name");
const Firebird::string name = token;
getToken();
return name;
}
void Lex::syntaxError(const char *expected)
{
AdminException exception ("expected %s, got \"%s\"", expected, token);
if (tokenInputStream)
exception.setLocation (tokenInputStream->getFileName(), tokenLineNumber);
throw exception;
}
/***
InputFile* Lex::pushFile(const char *fileName)
{
if (inputStream)
inputStream->ptr = ptr;
InputFile *inputFile = new InputFile (fileName, inputStream);
inputStream = inputFile;
ptr = end = NULL;
tokenType = TT_NONE;
return inputFile;
}
***/
void Lex::setContinuationChar(char c)
{
continuationChar = c;
}
void Lex::pushStream(InputStream *stream)
{
stream->addRef();
if (flags & LEX_trace)
{
const char *fileName = stream->getFileName();
if (fileName)
printf ("Opening %s\n", fileName);
}
if (inputStream)
inputStream->ptr = ptr;
stream->prior = inputStream;
inputStream = stream;
ptr = end = NULL;
tokenType = TT_NONE;
}
bool Lex::getSegment()
{
if (!inputStream)
{
tokenType = END_OF_STREAM;
eol = true;
return false;
}
if (!(ptr = inputStream->getSegment()))
{
end = ptr;
InputStream *prior = inputStream->prior;
inputStream->close();
inputStream->release();
if (!(inputStream = prior))
return false;
ptr = inputStream->ptr;
}
end = ptr ? inputStream->getEnd() : NULL;
if (end && (flags & LEX_list))
printf (" %s", ptr);
return true;
}
void Lex::captureStuff()
{
stuff.clear();
for (;;)
{
if (ptr >= end)
{
if (!getSegment())
return;
continue;
}
if (*ptr == captureEnd)
return;
stuff.putCharacter (*ptr++);
}
}
int& Lex::charTable(int ch)
{
return charTableArray [static_cast<UCHAR>(ch)];
}

View File

@ -1,114 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
// Lex.h: interface for the Lex class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_LEX_H__89737590_2C93_4F77_99AD_4C3881906C96__INCLUDED_)
#define AFX_LEX_H__89737590_2C93_4F77_99AD_4C3881906C96__INCLUDED_
#if defined _MSC_VER && _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER > 1000
#include "Stream.h"
#include "../common/classes/alloc.h"
START_NAMESPACE
class InputStream;
class InputFile;
class Stream;
class Lex : public Firebird::GlobalStorage
{
public:
enum LEX_flags { LEX_none = 0, LEX_trace = 1, LEX_list = 2, /* LEX_verbose = 4, */ LEX_upcase = 8 };
enum TokenType
{
END_OF_STREAM,
TT_PUNCT,
TT_NAME,
//QUOTED_NAME,
TT_NUMBER,
//TT_END,
QUOTED_STRING,
SINGLE_QUOTED_STRING,
//DECIMAL_NUMBER,
//IP_ADDRESS,
TT_NONE
};
Lex(const char* punctuation, const LEX_flags debugFlags);
virtual ~Lex();
void captureStuff();
int& charTable(int ch);
bool getSegment();
void pushStream (InputStream *stream);
void setContinuationChar (char c);
virtual void syntaxError (const char* expected);
Firebird::string getName();
Firebird::PathName reparseFilename();
bool match (const char *word);
bool isKeyword (const char *word) const;
void setCommentString (const char *start, const char *end);
void setLineComment (const char *string);
void setCharacters (int type, const char *characters);
void getToken();
static bool match (const char *pattern, const char *string);
void skipWhite();
protected:
LEX_flags flags;
TokenType tokenType;
int priorLineNumber;
bool eol;
InputStream* inputStream;
InputStream* priorInputStream;
private:
enum { MAXTOKEN = 4096 };
InputStream* tokenInputStream;
Stream stuff;
int tokenOffset;
char captureStart;
char captureEnd;
char token [MAXTOKEN];
int lineNumber;
int tokenLineNumber;
const char* ptr;
const char* end;
const char* lineComment;
const char* commentStart;
const char* commentEnd;
char continuationChar;
int charTableArray [256]; // Don't use directly. Use through charTable.
};
END_NAMESPACE
#endif // !defined(AFX_LEX_H__89737590_2C93_4F77_99AD_4C3881906C96__INCLUDED_)

View File

@ -1,77 +0,0 @@
#ifndef STR_PARAMETER
#define STR_PARAMETER(name, value) static const char* name = #name; static const char* name##Value = value;
#define INT_PARAMETER(name, value) static const char* name = #name; static int name##Value = value;
#define BOOL_PARAMETER(name, value) static const char* name = #name; static bool name##Value = value;
#endif
STR_PARAMETER (RootDirectory, 0)
INT_PARAMETER (SortMemBlockSize, 1048576) // bytes
#ifdef SUPERSERVER
INT_PARAMETER (SortMemUpperLimit, 67108864) // bytes
#elif defined(WIN_NT) // win32 CS
INT_PARAMETER (SortMemUpperLimit, 8388608) // bytes
#else // non-win32 CS
INT_PARAMETER (SortMemUpperLimit, 0) // bytes
#endif
BOOL_PARAMETER (RemoteFileOpenAbility, false)
INT_PARAMETER (GuardianOption, 1)
INT_PARAMETER (CpuAffinityMask, 1)
BOOL_PARAMETER (OldParameterOrdering, false)
INT_PARAMETER (TcpRemoteBufferSize, 8192) // bytes
BOOL_PARAMETER (TcpNoNagle, false)
INT_PARAMETER (IpcMapSize, 4096) // bytes
#ifdef SUPERSERVER
INT_PARAMETER (DefaultDbCachePages, 2048) // pages
#else
INT_PARAMETER (DefaultDbCachePages, 75) // pages
#endif
INT_PARAMETER (ConnectionTimeout, 180) // seconds
INT_PARAMETER (DummyPacketInterval, 0) // seconds
#if defined(WIN_NT) && !defined(SUPERSERVER)
INT_PARAMETER (LockMemSize, 1048576) // bytes
#else
INT_PARAMETER (LockMemSize, 262144) // bytes
#endif
INT_PARAMETER (LockSemCount, 32) // semaphores
INT_PARAMETER (LockSignal, 16) // signal #
BOOL_PARAMETER (LockGrantOrder, true)
INT_PARAMETER (LockHashSlots, 101) // slots
INT_PARAMETER (LockAcquireSpins, 0)
INT_PARAMETER (EventMemSize, 65536) // bytes
INT_PARAMETER (DeadlockTimeout, 10) // seconds
INT_PARAMETER (SolarisStallValue, 60) // seconds
BOOL_PARAMETER (TraceMemoryPools, false) // for internal use only
INT_PARAMETER (PrioritySwitchDelay, 100) // milliseconds
INT_PARAMETER (DeadThreadsCollection, 50) // number of PrioritySwitchDelay cycles before dead threads collection
INT_PARAMETER (PriorityBoost, 5) // ratio oh high- to low-priority thread ticks in jrd.cpp
#ifdef FB_SERVICE_NAME
STR_PARAMETER (RemoteServiceName, FB_SERVICE_NAME)
INT_PARAMETER (RemoteServicePort, 0)
STR_PARAMETER (RemotePipeName, FB_PIPE_NAME)
STR_PARAMETER (IpcName, FB_IPC_NAME)
#endif
#ifdef WIN_NT
INT_PARAMETER (MaxUnflushedWrites, 100)
INT_PARAMETER (MaxUnflushedWriteTime, 5)
#else
INT_PARAMETER (MaxUnflushedWrites, -1)
INT_PARAMETER (MaxUnflushedWriteTime, -1)
#endif
INT_PARAMETER (ProcessPriorityLevel, 0)
BOOL_PARAMETER (CreateInternalWindow, true)
BOOL_PARAMETER (CompleteBooleanEvaluation, false)
INT_PARAMETER (RemoteAuxPort, 0)
STR_PARAMETER (RemoteBindAddress, 0)
STR_PARAMETER (ExternalFileAccess, "None") // location(s) of external files for tables
STR_PARAMETER (DatabaseAccess, "Full") // location(s) of databases
STR_PARAMETER (UdfAccess, "Restrict UDF") // location(s) of UDFs
STR_PARAMETER (TempDirectories, 0)
//INT_PARAMETER (TraceDSQL, 0} // bitmask
STR_PARAMETER (LockFileName, 0)
STR_PARAMETER (SecurityDatabase, "None")
BOOL_PARAMETER (DatabaseFileShared, false)
INT_PARAMETER (TraceFlags, 0)
STR_PARAMETER (SecurityManager, "SecurityDb")
INT_PARAMETER (CommitInterval, 200)

View File

@ -47,7 +47,7 @@
#include "../common/classes/fb_string.h"
class ScanDir : public Firebird::GlobalStorage
class ScanDir : public Firebird::AutoStorage
{
public:
ScanDir(const char *dir, const char *pattern);

View File

@ -1,625 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
// Stream.cpp: implementation of the Stream class.
//
//////////////////////////////////////////////////////////////////////
#include <memory.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include "firebird.h"
#include "../common/classes/alloc.h"
#include "Stream.h"
#include "StreamSegment.h"
// CVC: The logic in this module seems to overwrite constant params passed into the
// address field of the Segment structure. This includes literal strings (see Element.cpp).
#ifndef MAX
#define MAX(a, b) ((a > b) ? a : b)
#define MIN(a, b) ((a < b) ? a : b)
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
Stream::Stream(int minSegmentSize)
{
segments = NULL;
current = NULL;
totalLength = 0;
minSegment = minSegmentSize;
copyFlag = true;
}
Stream::~Stream()
{
clear();
}
void Stream::putCharacter(char c)
{
if (!segments || current->length >= currentLength)
allocSegment (MAX (100, minSegment));
current->address [current->length] = c;
++current->length;
++totalLength;
}
void Stream::putSegment(int length, const char *ptr, bool copy)
{
#ifdef ENGINE
ASSERT (length >= 0);
#endif
if (length == 0)
return;
const char *address = ptr;
totalLength += length;
if (!segments)
{
if (copyFlag = copy)
{
allocSegment (MAX (length, minSegment));
current->length = length;
memcpy (current->address, address, length);
}
else
{
//copyFlag = copy;
current = segments = &first;
current->length = length;
current->address = (char*) address;
current->next = NULL;
}
}
else if (copyFlag)
{
int l = currentLength - current->length;
if (l > 0)
{
const int l2 = MIN (l, length);
memcpy (current->address + current->length, address, l2);
current->length += l2;
length -= l2;
address += l2;
}
if (length)
{
allocSegment (MAX (length, minSegment));
current->length = length;
memcpy (current->address, address, length);
}
}
else
{
allocSegment (0);
current->address = (char*) address;
current->length = length;
}
}
int Stream::getSegment(int offset, int len, void* ptr) const
{
int n = 0;
int length = len;
char* address = static_cast<char*>(ptr);
for (const Segment *segment = segments; segment; n += segment->length, segment = segment->next)
{
if (n + segment->length >= offset)
{
const int off = offset - n;
const int l = MIN (length, segment->length - off);
memcpy (address, segment->address + off, l);
address += l;
length -= l;
offset += l;
if (!length)
break;
}
}
return len - length;
}
void Stream::setSegment(Segment * segment, int length, void* address)
{
segment->length = length;
totalLength += length;
if (copyFlag)
{
segment->address = new char [length];
memcpy (segment->address, address, length);
}
else
segment->address = (char*) address;
}
void Stream::setMinSegment(int length)
{
minSegment = length;
}
Stream::Segment* Stream::allocSegment(int tail)
{
fb_assert(tail >= 0);
Segment *segment;
int length = tail;
if (!current && tail <= FIXED_SEGMENT_SIZE)
{
segment = &first;
length = FIXED_SEGMENT_SIZE;
}
else
{
// CVC: What do we do here in the release build if tail is smaller than FIXED_SEGMENT_SIZE?
fb_assert(tail >= FIXED_SEGMENT_SIZE);
segment = (Segment*) new char [sizeof(Segment) + tail - FIXED_SEGMENT_SIZE];
}
segment->address = segment->tail;
segment->next = NULL;
segment->length = 0;
currentLength = length;
if (current)
{
current->next = segment;
current = segment;
}
else
segments = current = segment;
return segment;
}
int Stream::getSegment(int offset, int len, void * ptr, char delimiter) const
{
int n = 0;
int length = len;
char *address = static_cast<char*>(ptr);
for (const Segment *segment = segments; segment; n += segment->length, segment = segment->next)
{
if (n + segment->length >= offset)
{
const int off = offset - n;
const int l = MIN (length, segment->length - off);
const char *p = segment->address + off;
for (const char *end = p + l; p < end;)
{
const char c = *address++ = *p++;
--length;
if (c == delimiter)
return len - length;
}
if (!length)
break;
}
}
return len - length;
}
void Stream::putSegment(const char * string)
{
if (string [0])
putSegment ((int) strlen (string), string, true);
}
char* Stream::getString()
{
char* const string = new char [totalLength + 1];
getSegment (0, totalLength, string);
string [totalLength] = 0;
return string;
}
#ifdef ENGINE
void Stream::compress(int length, const void * address)
{
//printShorts ("Original data", (length + 1) / 2, (short*) address);
Segment *segment = allocSegment (length + 5);
short *q = (short*) segment->address;
const short *p = (short*) address;
const short* const end = p + (length + 1) / 2;
const short* const yellow = end - 2;
*q++ = length;
while (p < end)
{
short *start = ++q;
while (p < end && (p >= yellow || p[0] != p[1] || p[1] != p[2]))
*q++ = *p++;
int n = q - start;
if (n)
start [-1] = -n;
else
--q;
if (p >= end)
break;
const short* start2 = p++;
while (p < end && *p == *start2)
++p;
n = p - start2;
*q++ = n;
*q++ = *start2;
}
totalLength = segment->length = (char*) q - segment->address;
}
char* Stream::decompress(int tableId, int recordNumber)
{
char *data;
short *q, *limit;
int run = 0;
decompressedLength = 0;
for (Segment *segment = segments; segment; segment = segment->next)
{
if (segment->length == 0)
continue;
const short* p = (short*) segment->address;
const short* end = (short*) (segment->address + segment->length);
if (decompressedLength == 0)
{
decompressedLength = *p++;
if (decompressedLength <= 0)
{
Log::log ("corrupted record, table %d, record %d, decompressed length %d\n",
tableId, recordNumber, decompressedLength);
throw SQLEXCEPTION (RUNTIME_ERROR, "corrupted record, table %d, record %d, decompressed length %d",
tableId, recordNumber, decompressedLength);
}
int len = ((decompressedLength + 1) / 2) * 2;
//data = new char [len];
data = ALLOCATE_RECORD (len);
limit = (short*) (data + decompressedLength);
if (decompressedLength & 1)
++limit;
q = (short*) data;
}
while (p < end)
{
const short n = *p++;
//#ifdef ENGINE
if (n == 0 && run == 0)
{
Log::log ("corrupted record (zero run), table %d, record %d\n", tableId, recordNumber);
printShorts ("Zero run", (segment->length + 1) / 2, (short*) segment->address);
printChars ("Zero run", segment->length, segment->address);
}
//#endif
if (run > 0)
{
for (; run; --run)
*q++ = n;
}
else if (run < 0)
{
*q++ = n;
++run;
}
else
{
run = n;
if (q + run > limit)
{
//#ifdef ENGINE
Log::log ("corrupted record (overrun), table %d, record %d\n", tableId, recordNumber);
printShorts ("Compressed", (segment->length + 1)/2, (short*) segment->address);
printChars ("Compressed", segment->length, segment->address);
//#endif
if (q == limit)
return data;
throw SQLEXCEPTION (RUNTIME_ERROR, "corrupted record, table %d, record %d", tableId, recordNumber);
}
}
}
}
//printShorts ("Decompressed", (decompressedLength + 1) / 2, (short*) data);
return data;
}
void Stream::printShorts(const char * msg, int length, short * data)
{
Log::debug ("%s", msg);
for (int n = 0; n < length; ++n)
{
if (n % 10 == 0)
Log::debug ("\n ");
Log::debug ("%d, ", data [n]);
}
Log::debug ("\n");
}
void Stream::printChars(const char * msg, int length, const char * data)
{
Log::debug ("%s", msg);
for (int n = 0; n < length; ++n)
{
if (n % 50 == 0)
Log::debug ("\n ");
const char c = data [n];
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'))
putchar (c);
else
putchar ('.');
}
Log::debug ("\n");
}
#endif
void Stream::clear()
{
Segment *segment;
while (segment = segments)
{
segments = segment->next;
if (segment != &first)
delete[] (char*) segment;
}
current = NULL;
totalLength = 0;
}
void Stream::putSegment(int length, const unsigned short *chars)
{
if (length == 0)
return;
totalLength += length;
const unsigned short *wc = chars;
if (!segments)
{
allocSegment (MAX (length, minSegment));
current->length = length;
}
else
{
int l = currentLength - current->length;
if (l > 0)
{
const int l2 = MIN (l, length);
char *p = current->address + current->length;
for (int n = 0; n < l2; ++n)
*p++ = (char) *wc++;
//memcpy (current->address + current->length, address, l2);
current->length += l2;
length -= l2;
//address += l2;
}
if (length)
{
allocSegment (MAX (length, minSegment));
current->length = length;
//memcpy (current->address, address, length);
}
}
char *p = current->address;
for (int n = 0; n < length; ++n)
*p++ = (char) *wc++;
}
int Stream::getLength() const
{
return totalLength;
}
int Stream::getSegmentLength(int offset) const
{
int n = 0;
for (const Segment *segment = segments; segment; segment = segment->next)
{
if (offset >= n && offset < n + segment->length)
return n + segment->length - offset;
n += segment->length;
}
return 0;
}
void* Stream::getSegment(int offset)
{
int n = 0;
for (Segment *segment = segments; segment; segment = segment->next)
{
if (offset >= n && offset < n + segment->length)
return segment->address + offset - n;
n += segment->length;
}
return NULL;
}
const void* Stream::getSegment(int offset) const
{
int n = 0;
for (const Segment *segment = segments; segment; segment = segment->next)
{
if (offset >= n && offset < n + segment->length)
return segment->address + offset - n;
n += segment->length;
}
return NULL;
}
void Stream::putSegment(Stream * stream)
{
/***
for (Segment *segment = stream->segments; segment; segment = segment->next)
putSegment (segment->length, segment->address, true);
***/
if (stream->totalLength == 0)
return;
StreamSegment seg(stream);
if (current)
{
for (int len = currentLength - current->length; len && seg.available;)
{
const int l = MIN (len, seg.available);
putSegment (l, seg.data, true);
seg.advance (l);
len -= l;
}
}
if (seg.remaining)
seg.copy (alloc (seg.remaining), seg.remaining);
}
Firebird::string Stream::getFBString() const
{
Firebird::string string;
char *p = string.getBuffer (totalLength);
for (const Segment *segment = segments; segment; segment = segment->next)
{
memcpy (p, segment->address, segment->length);
p += segment->length;
}
fb_assert(p - string.begin() == totalLength);
return string;
}
char* Stream::alloc(int length)
{
totalLength += length;
if (!current || length > currentLength - current->length)
allocSegment (length);
char* const p = current->tail + current->length;
current->length += length;
return p;
}
void Stream::format(const char *pattern, ...)
{
Firebird::string temp;
va_list args;
va_start (args, pattern);
temp.vprintf(pattern, args);
va_end(args);
putSegment (temp.c_str());
}
void Stream::truncate(int length)
{
int n = 0;
for (Segment *segment = segments; segment; segment = segment->next)
{
if (length >= n && length < n + segment->length)
{
current = segment;
current->length = length - n;
totalLength = length;
while (segment = current->next)
{
current->next = segment->next;
delete[] (char*) segment; // Was deallocation bug
}
return;
}
n += segment->length;
}
}
int Stream::compare(const Stream *stream) const
{
for (int offset = 0;;)
{
const int length1 = getSegmentLength(offset);
const int length2 = stream->getSegmentLength(offset);
if (length1 == 0)
{
if (length2)
return -1;
return 0;
}
if (length2 == 0)
return 1;
const int length = MIN (length1, length2);
const char *p1 = (const char*) getSegment (offset);
const char *p2 = (const char*) stream->getSegment (offset);
for (const char *end = p1 + length; p1 < end;)
{
int n = *p1++ - *p2++;
if (n)
return n;
}
offset += length;
}
}

View File

@ -1,97 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
// Stream.h: interface for the Stream class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_STREAM_H__02AD6A53_A433_11D2_AB5B_0000C01D2301__INCLUDED_)
#define AFX_STREAM_H__02AD6A53_A433_11D2_AB5B_0000C01D2301__INCLUDED_
#if defined _MSC_VER && _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#include "../common/classes/fb_string.h"
START_NAMESPACE
class Stream : public Firebird::GlobalStorage
{
public:
enum { FIXED_SEGMENT_SIZE = 1024 };
struct Segment
{
int length;
char *address;
Segment *next;
char tail [FIXED_SEGMENT_SIZE];
};
explicit Stream (int minSegmentSize = FIXED_SEGMENT_SIZE);
virtual ~Stream();
int compare (const Stream *stream) const;
void truncate (int length);
void format (const char *pattern, ...);
void putSegment (int length, const unsigned short *chars);
void putSegment (Stream *stream);
virtual void putSegment (const char *string);
virtual void putSegment (int length, const char *address, bool copy);
void putCharacter (char c);
virtual void setSegment (Segment *segment, int length, void* address);
virtual int getSegment (int offset, int len, void* ptr) const;
virtual int getSegment (int offset, int len, void *ptr, char delimiter) const;
void* getSegment (int offset);
const void* getSegment (int offset) const;
int getSegmentLength(int offset) const;
Firebird::string getFBString() const;
virtual char* getString();
void clear();
virtual int getLength() const;
virtual char* alloc (int length);
Segment* allocSegment (int tail);
void setMinSegment (int length);
int totalLength;
//int useCount;
Segment *segments; // used by StreamSegment::setStream
private:
int minSegment;
int currentLength;
int decompressedLength;
bool copyFlag;
Segment first;
Segment *current;
};
END_NAMESPACE
#endif // !defined(AFX_STREAM_H__02AD6A53_A433_11D2_AB5B_0000C01D2301__INCLUDED_)

View File

@ -1,112 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
// StreamSegment.cpp: implementation of the StreamSegment class.
//
//////////////////////////////////////////////////////////////////////
#include <memory.h>
#include "firebird.h"
#include "../jrd/common.h"
#include "StreamSegment.h"
#include "Stream.h"
#ifndef MAX
//#define MAX(a, b) ((a > b) ? a : b)
#define MIN(a, b) ((a < b) ? a : b)
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
StreamSegment::StreamSegment(Stream *stream)
{
setStream (stream);
}
StreamSegment::~StreamSegment()
{
}
void StreamSegment::setStream(Stream *stream)
{
remaining = stream->totalLength;
if (segment = stream->segments)
{
data = segment->address;
available = segment->length;
}
else
{
data = NULL;
available = 0;
}
}
void StreamSegment::advance()
{
advance (available);
}
void StreamSegment::advance(int size)
{
for (int len = size; len;)
{
const int l = MIN (available, len);
available -= l;
remaining -= l;
len -= size;
if (remaining == 0)
return;
if (available)
data += l;
else
{
segment = segment->next;
data = segment->address;
available = segment->length;
}
}
}
char* StreamSegment::copy(void *target, int length)
{
char* targ = static_cast<char*>(target);
for (int len = length; len;)
{
const int l = MIN (len, available);
memcpy (targ, data, l);
targ += l;
len -= l;
advance (l);
}
return targ;
}

View File

@ -1,65 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
// StreamSegment.h: interface for the StreamSegment class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_STREAMSEGMENT_H__11469FBB_A55A_4BB1_A96B_D95A4C75F0C7__INCLUDED_)
#define AFX_STREAMSEGMENT_H__11469FBB_A55A_4BB1_A96B_D95A4C75F0C7__INCLUDED_
#if defined _MSC_VER && _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER > 1000
#include "../common/classes/alloc.h"
#include "Stream.h"
START_NAMESPACE
class StreamSegment : public Firebird::GlobalStorage
{
public:
explicit StreamSegment(Stream *stream);
virtual ~StreamSegment();
char* copy (void *target, int length);
void advance (int size);
void advance();
void setStream (Stream *stream);
private:
friend class Stream; // for "available" and "remaining"
int available;
int remaining;
char* data;
Stream::Segment* segment;
};
END_NAMESPACE
#endif // !defined(AFX_STREAMSEGMENT_H__11469FBB_A55A_4BB1_A96B_D95A4C75F0C7__INCLUDED_)

View File

@ -63,6 +63,7 @@
#include "../jrd/os/thd_priority.h"
#include "../jrd/event_proto.h"
#include "../lock/lock_proto.h"
#include "../common/config/config.h"
class CharSetContainer;
@ -77,6 +78,7 @@ namespace Jrd
class TxPageCache;
class BackupManager;
class vcl;
class ExternalFileDirectoryList;
typedef Firebird::ObjectsArray<Trigger> trig_vec;
@ -455,6 +457,8 @@ public:
Firebird::Array<Function*> dbb_functions; // User defined functions
Firebird::GenericMap<Firebird::Pair<Firebird::Left<
Firebird::MetaName, USHORT> > > dbb_charset_ids; // Character set ids
ExternalFileDirectoryList* dbb_external_file_directory_list;
Firebird::RefPtr<Config> dbb_config;
// returns true if primary file is located on raw device
bool onRawDevice() const;
@ -489,7 +493,8 @@ private:
dbb_charsets(*p),
dbb_creation_date(Firebird::TimeStamp::getCurrentTimeStamp()),
dbb_functions(*p),
dbb_charset_ids(*p)
dbb_charset_ids(*p),
dbb_external_file_directory_list(NULL)
{
dbb_pools.add(p);
dbb_internal.grow(irq_MAX);

View File

@ -623,7 +623,7 @@ RecordBuffer* DatabaseSnapshot::allocBuffer(thread_db* tdbb, MemoryPool& pool, i
Format* format = MET_current(tdbb, relation);
fb_assert(format);
RecordBuffer* buffer = FB_NEW(pool) RecordBuffer(pool, format);
RecordBuffer* buffer = FB_NEW(pool) RecordBuffer(pool, format, tdbb->getDatabase()->dbb_config);
RelationData data = {relation->rel_id, buffer};
snapshot.add(data);

View File

@ -45,18 +45,13 @@
#include "../jrd/mov_proto.h"
#include "../jrd/thread_proto.h"
#include "../jrd/Function.h"
#include "../jrd/isc_proto.h"
#include "../common/classes/auto.h"
#include "../common/classes/fb_string.h"
#include "../common/classes/init.h"
#include "../common/classes/objects_array.h"
#include "../common/config/config.h"
#include "../config/ConfigFile.h"
#include "../config/ConfObj.h"
#include "../config/ConfObject.h"
#include "../config/Element.h"
#include "../config/ScanDir.h"
#include "../config/AdminException.h"
using namespace Firebird;
@ -313,7 +308,7 @@ void ExtEngineManager::ExternalContextImpl::setTransaction(thread_db* tdbb)
transaction = FB_NEW(*internalAttachment->att_pool) TransactionImpl(traHandle);
}
ExternalEngine* ExtEngineManager::ExternalContextImpl::getEngine(Firebird::Error* /*error*/)
ExternalEngine* ExtEngineManager::ExternalContextImpl::getEngine(Error* /*error*/)
{
return engine;
}
@ -336,7 +331,7 @@ Firebird::Transaction* FB_CALL ExtEngineManager::ExternalContextImpl::getTransac
}
const Firebird::Utf8* FB_CALL ExtEngineManager::ExternalContextImpl::getClientCharSet()
const Utf8* FB_CALL ExtEngineManager::ExternalContextImpl::getClientCharSet()
{
return clientCharSet.c_str();
}
@ -368,14 +363,14 @@ void* FB_CALL ExtEngineManager::ExternalContextImpl::setInfo(int code, void* val
//---------------------
static InitInstance<GenericMap<Pair<Full<MetaName, string> > > > enginesModules;
static InitInstance<GenericMap<Pair<Full<MetaName, PathName> > > > enginesModules;
//---------------------
ExtEngineManager::Function::Function(thread_db* tdbb, ExtEngineManager* aExtManager,
ExternalEngine* aEngine, Firebird::ExternalFunction* aFunction,
ExternalEngine* aEngine, ExternalFunction* aFunction,
const Jrd::Function* aUdf)
: extManager(aExtManager),
engine(aEngine),
@ -405,7 +400,7 @@ void ExtEngineManager::Function::execute(thread_db* tdbb, jrd_nod* args, impure_
MemoryPool& pool = *tdbb->getDefaultPool();
ValueImpl result(pool, &impure->vlu_desc, "", true);
Firebird::HalfStaticArray<impure_value, 32> impureArgs;
HalfStaticArray<impure_value, 32> impureArgs;
impure_value* impureArgsPtr = impureArgs.getBuffer(args->nod_count);
try
@ -470,7 +465,7 @@ void ExtEngineManager::Function::execute(thread_db* tdbb, jrd_nod* args, impure_
ExtEngineManager::Procedure::Procedure(thread_db* tdbb, ExtEngineManager* aExtManager,
ExternalEngine* aEngine, Firebird::ExternalProcedure* aProcedure,
ExternalEngine* aEngine, ExternalProcedure* aProcedure,
const jrd_prc* aPrc)
: extManager(aExtManager),
engine(aEngine),
@ -552,7 +547,7 @@ bool ExtEngineManager::ResultSet::fetch(thread_db* tdbb)
ExtEngineManager::Trigger::Trigger(thread_db* tdbb, ExtEngineManager* aExtManager,
ExternalEngine* aEngine, Firebird::ExternalTrigger* aTrigger,
ExternalEngine* aEngine, ExternalTrigger* aTrigger,
const Jrd::Trigger* aTrg)
: extManager(aExtManager),
engine(aEngine),
@ -568,7 +563,7 @@ ExtEngineManager::Trigger::~Trigger()
}
void ExtEngineManager::Trigger::execute(thread_db* tdbb, Firebird::ExternalTrigger::Action action,
void ExtEngineManager::Trigger::execute(thread_db* tdbb, ExternalTrigger::Action action,
record_param* oldRpb, record_param* newRpb)
{
EngineAttachmentInfo* attInfo = extManager->getEngineAttachment(tdbb, engine);
@ -675,22 +670,26 @@ ExtEngineManager::~ExtEngineManager()
void ExtEngineManager::initialize()
{
Firebird::PathName pluginsPath = PluginManager::getPluginsDirectory();
PathName pluginsPath = PluginManager::getPluginsDirectory();
ScanDir dir(pluginsPath.c_str(), "*.conf");
try
{
SortedObjectsArray<MetaName> conflicts(*getDefaultMemoryPool());
SortedArray<MetaName> conflicts;
while (dir.next())
{
Vulcan::ConfigFile configFile(dir.getFilePath(), Vulcan::ConfigFile::LEX_none);
ConfigFile configFile(dir.getFilePath(),
ConfigFile::EXCEPTION_ON_ERROR | ConfigFile::HAS_SUB_CONF);
for (Element* el = configFile.getObjects()->children; el; el = el->sibling)
const ConfigFile::Parameters& params = configFile.getParameters();
for (size_t n = 0; n < params.getCount(); ++n)
{
const ConfigFile::Parameter* el = &params[n];
if (el->name == "external_engine")
{
MetaName name = el->getAttributeName(0);
MetaName name(el->value);
if (enginesModules().exist(name) || conflicts.exist(name))
{
@ -702,22 +701,23 @@ void ExtEngineManager::initialize()
continue;
}
Element* plugin = el->findChild("plugin_module");
const ConfigFile::Parameter* plugin = el->sub->findParameter("plugin_module");
if (plugin)
enginesModules().put(name, plugin->getAttributeName(0));
enginesModules().put(name, plugin->value);
else
conflicts.add(name);
}
}
}
}
catch (AdminException& ex)
catch (const Exception& ex)
{
string s;
s.printf("Error in plugin config file '%s': %s'", dir.getFilePath(), ex.getText());
gds__log(s.c_str());
s.printf("Error in plugin config file '%s':", dir.getFilePath());
iscLogException(s.c_str(), ex);
}
}
@ -751,8 +751,8 @@ void ExtEngineManager::closeAttachment(thread_db* tdbb, Attachment* /*attachment
ExtEngineManager::Function* ExtEngineManager::makeFunction(thread_db* tdbb, const Jrd::Function* udf,
const Firebird::MetaName& engine, const Firebird::string& entryPoint,
const Firebird::string& body)
const MetaName& engine, const string& entryPoint,
const string& body)
{
string entryPointTrimmed = entryPoint;
entryPointTrimmed.trim();
@ -794,8 +794,8 @@ ExtEngineManager::Function* ExtEngineManager::makeFunction(thread_db* tdbb, cons
ExtEngineManager::Procedure* ExtEngineManager::makeProcedure(thread_db* tdbb, const jrd_prc* prc,
const Firebird::MetaName& engine, const Firebird::string& entryPoint,
const Firebird::string& body)
const MetaName& engine, const string& entryPoint,
const string& body)
{
string entryPointTrimmed = entryPoint;
entryPointTrimmed.trim();
@ -837,8 +837,8 @@ ExtEngineManager::Procedure* ExtEngineManager::makeProcedure(thread_db* tdbb, co
ExtEngineManager::Trigger* ExtEngineManager::makeTrigger(thread_db* tdbb, const Jrd::Trigger* trg,
const Firebird::MetaName& engine, const Firebird::string& entryPoint,
const Firebird::string& body, Firebird::ExternalTrigger::Type type)
const MetaName& engine, const string& entryPoint,
const string& body, ExternalTrigger::Type type)
{
string entryPointTrimmed = entryPoint;
entryPointTrimmed.trim();
@ -880,7 +880,7 @@ ExtEngineManager::Trigger* ExtEngineManager::makeTrigger(thread_db* tdbb, const
}
ExternalEngine* ExtEngineManager::getEngine(thread_db* tdbb, const Firebird::MetaName& name)
ExternalEngine* ExtEngineManager::getEngine(thread_db* tdbb, const MetaName& name)
{
ReadLockGuard readGuard(enginesLock);
ExternalEngine* engine = NULL;
@ -892,7 +892,7 @@ ExternalEngine* ExtEngineManager::getEngine(thread_db* tdbb, const Firebird::Met
if (!engines.get(name, engine))
{
string pluginName;
PathName pluginName;
if (enginesModules().get(name, pluginName))
{
PluginImpl* plugin = PluginManager::getPlugin(pluginName);
@ -958,7 +958,7 @@ ExternalEngine* ExtEngineManager::getEngine(thread_db* tdbb, const Firebird::Met
ExtEngineManager::EngineAttachmentInfo* ExtEngineManager::getEngineAttachment(
thread_db* tdbb, const Firebird::MetaName& name)
thread_db* tdbb, const MetaName& name)
{
ExternalEngine* engine = getEngine(tdbb, name);
return getEngineAttachment(tdbb, engine);
@ -1007,7 +1007,7 @@ ExtEngineManager::EngineAttachmentInfo* ExtEngineManager::getEngineAttachment(
}
void ExtEngineManager::setupAdminCharSet(thread_db* tdbb, Firebird::ExternalEngine* engine,
void ExtEngineManager::setupAdminCharSet(thread_db* tdbb, ExternalEngine* engine,
EngineAttachmentInfo* attInfo)
{
ContextManager<ExternalFunction> ctxManager(tdbb, attInfo, CS_UTF8);

View File

@ -29,18 +29,15 @@
#include "../jrd/os/mod_loader.h"
#include "../jrd/intlobj_new.h"
#include "../jrd/intl_proto.h"
#include "../jrd/isc_proto.h"
#include "../common/config/config.h"
#include "../common/classes/GenericMap.h"
#include "../common/classes/objects_array.h"
#include "../common/classes/fb_string.h"
#include "../common/classes/init.h"
#include "../config/ConfigFile.h"
#include "../config/ConfObj.h"
#include "../config/ConfObject.h"
#include "../config/Element.h"
#include "../config/ScanDir.h"
#include "../config/AdminException.h"
#include "../common/config/config_file.h"
using namespace Firebird;
@ -421,7 +418,7 @@ const IntlManager::CollationDefinition IntlManager::defaultCollations[] =
bool IntlManager::initialize()
{
bool ok = true;
ObjectsArray<string> conflicts;
ObjectsArray<ConfigFile::String> conflicts;
string builtinConfig;
Firebird::PathName intlPath = fb_utils::getPrefix(fb_utils::FB_DIR_INTL, "");
@ -432,94 +429,122 @@ bool IntlManager::initialize()
{
while (dir.next())
{
ConfigFile configFile(dir.getFilePath(), ConfigFile::LEX_none);
ConfigFile configFile(dir.getFilePath(), ConfigFile::HAS_SUB_CONF);
ConfObj builtinModule(configFile.findObject("intl_module", "builtin"));
const ConfigFile::Parameter* builtinModule = configFile.findParameter("intl_module", "builtin");
string s = getConfigInfo(builtinModule);
if (s.hasData())
builtinConfig = s;
for (const Element* el = configFile.getObjects()->children; el; el = el->sibling)
const ConfigFile::Parameters& params = configFile.getParameters();
for (size_t n = 0; n < params.getCount(); ++n)
{
if (el->name == "charset")
const ConfigFile::Parameter* ch = &params[n];
if (ch->name != "charset")
{
const string charSetName = el->getAttributeName(0);
PathName filename;
string configInfo;
continue;
}
if (!ch->sub)
{
continue;
}
const Element* module = el->findChild("intl_module");
if (module)
const ConfigFile::String charSetName = ch->value;
PathName filename;
string configInfo;
const ConfigFile::Parameter* module = ch->sub->findParameter("intl_module");
const ConfigFile::Parameter* objModule;
if (module &&
(objModule = configFile.findParameter("intl_module", module->value.c_str())))
{
if (!objModule->sub)
{
const Firebird::string moduleName(module->getAttributeName(0));
ConfObj objModule(configFile.findObject("intl_module", moduleName.c_str()));
filename = objModule->getValue("filename", "");
configInfo = getConfigInfo(objModule);
fatal_exception::raiseFmt("Missing parameters for intl_module %s\n", module->value.c_str());
}
const ConfigFile::Parameter* fname = objModule->sub->findParameter("filename");
if (!fname)
{
fatal_exception::raiseFmt("Missing parameter 'filename' for intl_module %s\n", module->value.c_str());
}
filename = fname->value;
configInfo = getConfigInfo(objModule);
if (!modules->exist(filename))
if (!modules->exist(filename))
{
ModuleLoader::Module* mod = ModuleLoader::loadModule(filename);
if (!mod)
{
ModuleLoader::Module* mod = ModuleLoader::loadModule(filename);
if (!mod)
{
ModuleLoader::doctorModuleExtension(filename);
mod = ModuleLoader::loadModule(filename);
}
if (mod)
{
// Negotiate version
pfn_INTL_version versionFunction;
USHORT version;
ModuleLoader::doctorModuleExtension(filename);
mod = ModuleLoader::loadModule(filename);
}
if (mod)
{
// Negotiate version
pfn_INTL_version versionFunction;
USHORT version;
if (mod->findSymbol(STRINGIZE(INTL_VERSION_ENTRYPOINT), versionFunction))
{
version = INTL_VERSION_2;
versionFunction(&version);
}
else
version = INTL_VERSION_1;
if (version != INTL_VERSION_1 && version != INTL_VERSION_2)
{
string err_msg;
err_msg.printf("INTL module '%s' is of incompatible version number %d",
filename.c_str(), version);
gds__log(err_msg.c_str());
ok = false;
}
else
modules->put(filename, mod);
if (mod->findSymbol(STRINGIZE(INTL_VERSION_ENTRYPOINT), versionFunction))
{
version = INTL_VERSION_2;
versionFunction(&version);
}
else
version = INTL_VERSION_1;
if (version != INTL_VERSION_1 && version != INTL_VERSION_2)
{
gds__log((string("Can't load INTL module '") +
filename.c_str() + "'").c_str());
string err_msg;
err_msg.printf("INTL module '%s' is of incompatible version number %d",
filename.c_str(), version);
gds__log(err_msg.c_str());
ok = false;
}
else
modules->put(filename, mod);
}
else
{
gds__log((string("Can't load INTL module '") +
filename.c_str() + "'").c_str());
ok = false;
}
}
}
for (const Element* el2 = el->children; el2; el2 = el2->sibling)
const ConfigFile::Parameters& sub = ch->sub->getParameters();
for (size_t coll = 0; coll < sub.getCount(); ++coll)
{
if (sub[coll].name != "collation")
{
if (el2->name == "collation")
{
const string collationName = el2->getAttributeName(0);
const string charSetCollation = charSetName + ":" + collationName;
const char* externalName = el2->getAttributeName(1);
continue;
}
ConfigFile::String collationName = sub[coll].value;
ConfigFile::String externalName;
size_t pos = collationName.find(' ');
if (pos != ConfigFile::String::npos)
{
externalName = collationName.substr(pos);
externalName.ltrim(" \t");
collationName = collationName.substr(0, pos);
}
const ConfigFile::String charSetCollation = charSetName + ":" + collationName;
if (!registerCharSetCollation(charSetCollation, filename,
(externalName ? externalName : collationName), configInfo))
{
conflicts.add(charSetCollation);
ok = false;
}
}
if (!registerCharSetCollation(charSetCollation.ToString(), filename,
(externalName.hasData() ? externalName : collationName).ToString(), configInfo))
{
conflicts.add(charSetCollation);
ok = false;
}
}
}
}
}
catch (AdminException& ex)
catch (const Exception& ex)
{
gds__log((string("Error in INTL plugin config file '") + dir.getFilePath() + "': " + ex.getText()).c_str());
string message = "Error in INTL plugin config file ";
message += dir.getFilePath();
iscLogException(message.c_str(), ex);
ok = false;
}
@ -538,8 +563,8 @@ bool IntlManager::initialize()
registerCharSetCollation("UTF32:UCS_BASIC", "", "UCS_BASIC", builtinConfig);
#endif
for (ObjectsArray<string>::const_iterator name(conflicts.begin()); name != conflicts.end(); ++name)
charSetCollations->remove(*name);
for (ObjectsArray<ConfigFile::String>::const_iterator name(conflicts.begin()); name != conflicts.end(); ++name)
charSetCollations->remove(name->ToString());
return ok;
}
@ -683,31 +708,28 @@ bool IntlManager::setupCollationAttributes(
}
Firebird::string IntlManager::getConfigInfo(const ConfObj& confObj)
Firebird::string IntlManager::getConfigInfo(const ConfigFile::Parameter* confObj)
{
if (!confObj.hasObject())
return "";
string configInfo;
for (const Element* el = confObj->object->children; el; el = el->sibling)
if (!confObj || !confObj->sub)
{
string values;
for (int i = 0; el->getAttributeName(i); ++i)
{
if (i > 0)
values.append(" ");
values.append(el->getAttributeName(i));
}
if (configInfo.hasData())
configInfo.append(";");
configInfo.append(string(el->name.c_str()) + "=" + values);
return "";
}
return configInfo;
ConfigFile::String configInfo;
const ConfigFile::Parameters& all = confObj->sub->getParameters();
for (size_t n = 0; n < all.getCount(); ++n)
{
const ConfigFile::Parameter& par = all[n];
if (configInfo.hasData())
{
configInfo.append(";");
}
configInfo.append(par.name + "=" + par.value);
}
return configInfo.ToString();
}

View File

@ -28,7 +28,7 @@
#define JRD_INTLMANAGER_H
#include "../common/classes/fb_string.h"
#include "../config/ConfObj.h"
#include "../common/config/config_file.h"
struct charset;
struct texttype;
@ -84,7 +84,7 @@ public:
const static CollationDefinition defaultCollations[];
private:
static Firebird::string getConfigInfo(const ConfObj& confObj);
static Firebird::string getConfigInfo(const ConfigFile::Parameter* par);
static bool registerCharSetCollation(const Firebird::string& name,
const Firebird::PathName& filename, const Firebird::string& externalName,

View File

@ -28,15 +28,12 @@
#include "../jrd/ErrorImpl.h"
#include "../jrd/os/path_utils.h"
#include "../jrd/err_proto.h"
#include "../jrd/isc_proto.h"
#include "../common/classes/fb_string.h"
#include "../common/classes/init.h"
#include "../common/config/config.h"
#include "../config/ConfigFile.h"
#include "../config/ConfObj.h"
#include "../config/ConfObject.h"
#include "../config/Element.h"
#include "../common/config/config_file.h"
#include "../config/ScanDir.h"
#include "../config/AdminException.h"
using namespace Firebird;
using Firebird::uint;
@ -46,11 +43,11 @@ namespace Jrd {
namespace
{
class PluginsMap : public GenericMap<Pair<Left<string, PluginImpl*> > >
class PluginsMap : public GenericMap<Pair<Left<PathName, PluginImpl*> > >
{
public:
explicit PluginsMap(MemoryPool& p)
: GenericMap<Pair<Left<string, PluginImpl*> > >(p)
: GenericMap<Pair<Left<PathName, PluginImpl*> > >(p)
{
}
@ -91,68 +88,74 @@ void PluginManager::initialize()
try
{
SortedObjectsArray<string> conflicts(*getDefaultMemoryPool());
SortedObjectsArray<ConfigFile::String> conflicts(*getDefaultMemoryPool());
while (dir.next())
{
Vulcan::ConfigFile configFile(dir.getFilePath(), Vulcan::ConfigFile::LEX_none);
ConfigFile configFile(dir.getFilePath(),
ConfigFile::HAS_SUB_CONF | ConfigFile::EXCEPTION_ON_ERROR);
for (Element* el = configFile.getObjects()->children; el; el = el->sibling)
const ConfigFile::Parameters& params = configFile.getParameters();
for (size_t n = 0; n < params.getCount(); ++n)
{
if (el->name == "plugin_module")
const ConfigFile::Parameter* pm = &params[n];
if (pm->name != "plugin_module")
{
AutoPtr<PluginImpl> plugin(new PluginImpl);
plugin->name = el->getAttributeName(0);
continue;
}
if (plugins->exist(plugin->name) || conflicts.exist(plugin->name))
AutoPtr<PluginImpl> plugin(new PluginImpl);
plugin->name = pm->value;
if (plugins->exist(plugin->name) || conflicts.exist(plugin->name))
{
gds__log("Plugin %s defined more than once.", plugin->name.c_str());
conflicts.add(plugin->name);
continue;
}
if (!pm->sub)
{
fatal_exception::raiseFmt("Missing required parameters for plugin %s",
plugin->name.c_str());
}
const ConfigFile::Parameter* par = pm->sub->findParameter("filename");
if (!par)
{
fatal_exception::raiseFmt("Missing required parameter 'filename' for plugin %s",
plugin->name.c_str());
}
plugin->filename = par->value;
par = pm->sub->findParameter("plugin_config");
if (par)
{
par = configFile.findParameter("plugin_config", par->value);
if (!par)
{
string s;
s.printf("Plugin %s defined more than once.", plugin->name.c_str());
gds__log(s.c_str());
conflicts.add(plugin->name);
continue;
fatal_exception::raiseFmt("Missing required config for plugin %s",
plugin->name.c_str());
}
ConfObj objModule(configFile.findObject("plugin_module", plugin->name.c_str()));
plugin->filename = objModule->getValue("filename", "");
Element* config = el->findChild("plugin_config");
if (config)
if (par->sub)
{
string configName(config->getAttributeName(0));
ConfObj objConfig(configFile.findObject("plugin_config",
configName.c_str()));
for (Element* elConfig = objConfig->object->children;
elConfig; elConfig = elConfig->sibling)
const ConfigFile::Parameters& all = par->sub->getParameters();
for (size_t n = 0; n < all.getCount(); ++n)
{
const string key = elConfig->name;
string value;
const char* attribute;
for (int i = 0; (attribute = elConfig->getAttributeName(i)); ++i)
{
if (i != 0)
value += PathUtils::dir_list_sep;
value += objConfig->expand(attribute);
}
plugin->configInfo.add(ConfigEntry(*getDefaultMemoryPool(), key, value));
plugin->configInfo.add(ConfigEntry(*getDefaultMemoryPool(), all[n].name, all[n].value));
}
PluginImpl* p = plugin.release();
plugins->put(p->name, p);
}
}
PluginImpl* p = plugin.release();
plugins->put(p->name, p);
}
}
}
catch (AdminException& ex)
catch (const Exception& ex)
{
string s;
s.printf("Error in plugin config file '%s': %s'", dir.getFilePath(), ex.getText());
gds__log(s.c_str());
s.printf("Error in plugin config file '%s'", dir.getFilePath());
iscLogException(s.c_str(), ex);
}
}
@ -165,7 +168,7 @@ PathName PluginManager::getPluginsDirectory()
}
PluginImpl* PluginManager::getPlugin(const string& name)
PluginImpl* PluginManager::getPlugin(const PathName& name)
{
PluginImpl* plugin;

View File

@ -37,7 +37,7 @@
namespace Jrd {
typedef Firebird::Pair<Firebird::Full<Firebird::string, Firebird::string> > ConfigEntry;
typedef Firebird::Pair<Firebird::Full<Firebird::PathName, Firebird::PathName> > ConfigEntry;
class PluginImpl : public Firebird::Plugin, public Firebird::GlobalStorage
{
@ -66,12 +66,12 @@ public:
Firebird::ExternalEngineFactory* getExternalEngineFactory();
private:
Firebird::string name;
Firebird::PathName name;
Firebird::PathName filename;
Firebird::SortedObjectsArray<
ConfigEntry,
Firebird::EmptyStorage<ConfigEntry*>,
Firebird::string, Firebird::FirstPointerKey<ConfigEntry>
Firebird::PathName, Firebird::FirstPointerKey<ConfigEntry>
> configInfo;
Firebird::AutoPtr<ModuleLoader::Module> module;
Firebird::ExternalEngineFactory* externalEngineFactory;
@ -83,7 +83,7 @@ class PluginManager
public:
static void initialize();
static Firebird::PathName getPluginsDirectory();
static PluginImpl* getPlugin(const Firebird::string& name);
static PluginImpl* getPlugin(const Firebird::PathName& name);
};

View File

@ -31,10 +31,10 @@ const char* const SCRATCH = "fb_recbuf_";
using namespace Jrd;
RecordBuffer::RecordBuffer(MemoryPool& pool, const Format* format)
RecordBuffer::RecordBuffer(MemoryPool& pool, const Format* format, Firebird::RefPtr<Config> conf)
: length(format->fmt_length), count(0), filled(false)
{
space = FB_NEW(pool) TempSpace(pool, SCRATCH);
space = FB_NEW(pool) TempSpace(pool, SCRATCH, conf);
record = FB_NEW_RPT(pool, length) Record(pool);
record->rec_format = format;

View File

@ -31,7 +31,7 @@ namespace Jrd {
class RecordBuffer
{
public:
RecordBuffer(MemoryPool&, const Format*);
RecordBuffer(MemoryPool&, const Format*, Firebird::RefPtr<Config> conf);
~RecordBuffer();
size_t getCount() const

View File

@ -137,8 +137,8 @@ size_t TempSpace::FileBlock::write(offset_t offset, const void* buffer, size_t l
// Constructor
//
TempSpace::TempSpace(MemoryPool& p, const Firebird::PathName& prefix)
: pool(p), filePrefix(p, prefix),
TempSpace::TempSpace(MemoryPool& p, const Firebird::PathName& prefix, Firebird::RefPtr<Config> conf)
: pool(p), filePrefix(p, prefix), config(conf),
logicalSize(0), physicalSize(0), localCacheUsage(0),
head(NULL), tail(NULL), tempFiles(p),
freeSegments(NULL), notUsedSegments(NULL)
@ -150,7 +150,7 @@ TempSpace::TempSpace(MemoryPool& p, const Firebird::PathName& prefix)
{
MemoryPool& def_pool = *getDefaultMemoryPool();
tempDirs = FB_NEW(def_pool) Firebird::TempDirectoryList(def_pool);
minBlockSize = Config::getTempBlockSize();
minBlockSize = config->getTempBlockSize();
if (minBlockSize < MIN_TEMP_BLOCK_SIZE)
minBlockSize = MIN_TEMP_BLOCK_SIZE;
@ -284,7 +284,7 @@ void TempSpace::extend(size_t size)
Block* block = NULL;
if (globalCacheUsage + size <= size_t(Config::getTempCacheLimit()))
if (globalCacheUsage + size <= size_t(config->getTempCacheLimit()))
{
try
{

View File

@ -29,11 +29,12 @@
#include "../common/classes/TempFile.h"
#include "../common/config/dir_list.h"
#include "../common/classes/init.h"
#include "../common/config/config.h"
class TempSpace : public Firebird::File
{
public:
TempSpace(MemoryPool& pool, const Firebird::PathName& prefix);
TempSpace(MemoryPool& pool, const Firebird::PathName& prefix, Firebird::RefPtr<Config> conf);
virtual ~TempSpace();
size_t read(offset_t offset, void* buffer, size_t length);
@ -163,6 +164,7 @@ private:
MemoryPool& pool;
Firebird::PathName filePrefix;
Firebird::RefPtr<Config> config;
offset_t logicalSize;
offset_t physicalSize;
offset_t localCacheUsage;

View File

@ -1221,8 +1221,8 @@ void CCH_flush(thread_db* tdbb, USHORT flush_flag, SLONG tra_number)
//
// Check if flush needed
//
const int max_unflushed_writes = Config::getMaxUnflushedWrites();
const time_t max_unflushed_write_time = Config::getMaxUnflushedWriteTime();
const int max_unflushed_writes = dbb->dbb_config->getMaxUnflushedWrites();
const time_t max_unflushed_write_time = dbb->dbb_config->getMaxUnflushedWriteTime();
bool max_num = (max_unflushed_writes >= 0);
bool max_time = (max_unflushed_write_time >= 0);

View File

@ -24,10 +24,16 @@
#include "../common/classes/init.h"
#include "../common/config/config.h"
#include "../common/config/config_file.h"
#include "../common/config/ConfigCache.h"
#include "../common/config/dir_list.h"
#include "../jrd/os/path_utils.h"
#include "../jrd/gds_proto.h"
#include "../jrd/isc_proto.h"
#include "../jrd/Database.h"
#include "../common/utils_proto.h"
#include "../common/classes/Hash.h"
#include <ctype.h>
using namespace Firebird;
@ -63,50 +69,254 @@ namespace
}
}
}
template <typename T>
struct PathHash
{
static const PathName& generate(const void* /*sender*/, const T& item)
{
return item.name;
}
static size_t hash(const PathName& value, size_t hashSize)
{
return hash(value.c_str(), value.length(), hashSize);
}
static void upcpy(size_t* toPar, const char* from, size_t length)
{
char* to = reinterpret_cast<char*>(toPar);
while (length--)
{
if (CASE_SENSITIVITY)
{
*to++ = *from++;
}
else
{
*to++ = toupper(*from++);
}
}
}
static size_t hash(const char* value, size_t length, size_t hashSize)
{
size_t sum = 0;
size_t val;
while (length >= sizeof(size_t))
{
upcpy(&val, value, sizeof(size_t));
sum += val;
value += sizeof(size_t);
length -= sizeof(size_t);
}
if (length)
{
val = 0;
upcpy(&val, value, length);
sum += val;
}
size_t rc = 0;
while (sum)
{
rc += (sum % hashSize);
sum /= hashSize;
}
return rc % hashSize;
}
};
struct DbName;
typedef Hash<DbName, 127, PathName, PathHash<DbName>, PathHash<DbName> > DbHash;
struct DbName : public DbHash::Entry
{
DbName(MemoryPool& p, const PathName& db)
: name(p, db) { }
DbName* get()
{
return this;
}
bool isEqual(const PathName& val) const
{
return val == name;
}
PathName name;
RefPtr<Config> config;
};
struct AliasName;
typedef Hash<AliasName, 251, PathName, PathHash<AliasName>, PathHash<AliasName> > AliasHash;
struct AliasName : public AliasHash::Entry
{
AliasName(MemoryPool& p, const PathName& al, DbName* db)
: name(p, al), database(db) { }
AliasName* get()
{
return this;
}
bool isEqual(const PathName& val) const
{
return val == name;
}
PathName name;
DbName* database;
};
class AliasesConf : public ConfigCache
{
public:
explicit AliasesConf(MemoryPool& p)
: ConfigCache(p, fb_utils::getPrefix(fb_utils::FB_DIR_CONF, ALIAS_FILE)),
databases(getPool()), aliases(getPool())
{ }
void loadConfig()
{
size_t n;
// clean old data
for (n = 0; n < aliases.getCount(); ++n)
{
delete aliases[n];
}
aliases.clear();
for (n = 0; n < databases.getCount(); ++n)
{
delete databases[n];
}
databases.clear();
ConfigFile aliasConfig(fileName, ConfigFile::HAS_SUB_CONF);
const ConfigFile::Parameters& params = aliasConfig.getParameters();
for (n = 0; n < params.getCount(); ++n)
{
const ConfigFile::Parameter* par = &params[n];
PathName file(par->value);
replace_dir_sep(file);
if (PathUtils::isRelative(file))
{
gds__log("Value %s configured for alias %s "
"is not a fully qualified path name, ignored",
file.c_str(), par->name.c_str());
continue;
}
DbName* db = dbHash.lookup(file);
if (! db)
{
db = FB_NEW(getPool()) DbName(getPool(), file);
databases.add(db);
dbHash.add(db);
}
else
{
// check for duplicated config
if (par->sub && db->config.hasData())
{
fatal_exception::raiseFmt("Duplicated configuration for database %s\n",
file.c_str());
}
}
if (par->sub)
{
// load per-database configuration
db->config = new Config(*par->sub, *Config::getDefaultConfig());
}
PathName correctedAlias(par->name);
AliasName* alias = aliasHash.lookup(correctedAlias);
if (alias)
{
fatal_exception::raiseFmt("Duplicated alias %s\n", correctedAlias.c_str());
}
alias = FB_NEW(getPool()) AliasName(getPool(), correctedAlias, db);
aliases.add(alias);
aliasHash.add(alias);
}
}
private:
HalfStaticArray<DbName*, 100> databases;
HalfStaticArray<AliasName*, 200> aliases;
public:
DbHash dbHash;
AliasHash aliasHash;
};
InitInstance<AliasesConf> aliasesConf;
}
bool ResolveDatabaseAlias(const PathName& alias, PathName& database)
bool ResolveDatabaseAlias(const PathName& alias, PathName& file, RefPtr<Config>* config)
{
PathName alias_filename = fb_utils::getPrefix(fb_utils::FB_DIR_CONF, ALIAS_FILE);
ConfigFile aliasConfig(false, true);
aliasConfig.setConfigFilePath(alias_filename);
try
{
aliasesConf().checkLoadConfig();
}
catch (const fatal_exception& ex)
{
gds__log("File aliases.conf contains bad data: %s", ex.what());
(Arg::Gds(isc_random) << "Server misconfigured - contact administrator please").raise();
}
ReadLockGuard guard(aliasesConf().rwLock);
PathName corrected_alias = alias;
replace_dir_sep(corrected_alias);
database = aliasConfig.getString(corrected_alias);
if (!database.empty())
bool rc = true;
AliasName* a = aliasesConf().aliasHash.lookup(corrected_alias);
DbName* db = a ? a->database : NULL;
if (db)
{
replace_dir_sep(database);
if (PathUtils::isRelative(database))
file = db->name;
}
else
{
// If file_name has no path part, expand it in DatabasesPath
PathName path, name;
PathUtils::splitLastComponent(path, name, corrected_alias);
// if path component not present in file_name
if (path.isEmpty())
{
gds__log("Value %s configured for alias %s "
"is not a fully qualified path name, ignored",
database.c_str(), alias.c_str());
return false;
// try to expand to existing file
if (!databaseDirectoryList().expandFileName(file, name))
{
// try to use default path
if (!databaseDirectoryList().defaultName(file, name))
{
rc = false;
}
}
}
return true;
else
{
rc = false;
}
if (! rc)
{
file = corrected_alias;
}
db = aliasesConf().dbHash.lookup(file);
}
// If file_name has no path part, expand it in DatabasesPath
Firebird::PathName path, name;
PathUtils::splitLastComponent(path, name, corrected_alias);
// if path component not present in file_name
if (path.isEmpty())
if (config)
{
// try to expand to existing file
if (databaseDirectoryList().expandFileName(database, name))
{
return true;
}
// try to use default path
if (databaseDirectoryList().defaultName(database, name))
{
return true;
}
*config = (db && db->config.hasData()) ? db->config : Config::getDefaultConfig();
}
return false;
return rc;
}

View File

@ -24,6 +24,11 @@
#define JRD_DB_ALIAS_H
#include "../common/classes/fb_string.h"
#include "../common/classes/RefCounted.h"
bool ResolveDatabaseAlias(const Firebird::PathName& alias, Firebird::PathName& database);
class Config;
bool ResolveDatabaseAlias(const Firebird::PathName& alias,
Firebird::PathName& file,
Firebird::RefPtr<Config>* config);
#endif // JRD_DB_ALIAS_H

View File

@ -85,7 +85,7 @@ void EventManager::init(Database* dbb)
EventManager* eventMgr = NULL;
if (!g_emMap->get(id, eventMgr))
{
eventMgr = new EventManager(id);
eventMgr = new EventManager(id, dbb->dbb_config);
}
fb_assert(eventMgr);
@ -95,12 +95,13 @@ void EventManager::init(Database* dbb)
}
EventManager::EventManager(const Firebird::string& id)
EventManager::EventManager(const Firebird::string& id, Firebird::RefPtr<Config> conf)
: PID(getpid()),
m_header(NULL),
m_process(NULL),
m_processOffset(0),
m_dbId(getPool(), id),
m_config(conf),
m_sharedFileCreated(false),
m_exiting(false)
{
@ -170,7 +171,7 @@ void EventManager::attach_shared_file()
if (!(m_header = (evh*) ISC_map_file(localStatus,
name.c_str(),
init_shmem, this,
Config::getEventMemSize(),
m_config->getEventMemSize(),
&m_shmemData)))
{
localStatus.raise();
@ -618,7 +619,7 @@ frb* EventManager::alloc_global(UCHAR type, ULONG length, bool recurse)
if (!best && !recurse)
{
const ULONG old_length = m_shmemData.sh_mem_length_mapped;
const ULONG ev_length = old_length + Config::getEventMemSize();
const ULONG ev_length = old_length + m_config->getEventMemSize();
evh* header = NULL;

View File

@ -31,6 +31,8 @@
#include "../jrd/ThreadData.h"
#include "../jrd/event.h"
class Config;
namespace Jrd {
class Database;
@ -47,7 +49,7 @@ class EventManager : public Firebird::RefCounted, public Firebird::GlobalStorage
public:
static void init(Database*);
explicit EventManager(const Firebird::string&);
EventManager(const Firebird::string& id, Firebird::RefPtr<Config> conf);
~EventManager();
SLONG createSession();
@ -108,6 +110,7 @@ private:
sh_mem m_shmemData;
Firebird::string m_dbId;
Firebird::RefPtr<Config> m_config;
Firebird::Semaphore m_startupSemaphore;
Firebird::Semaphore m_cleanupSemaphore;

View File

@ -74,9 +74,36 @@ __int64 __cdecl _ftelli64(FILE*);
#define FSEEK64 fseeko
#endif
using namespace Jrd;
using namespace Firebird;
namespace Jrd {
class ExternalFileDirectoryList : public Firebird::DirectoryList
{
private:
const Firebird::PathName getConfigString() const
{
return Firebird::PathName(config->getExternalFileAccess());
}
public:
ExternalFileDirectoryList(const Database* dbb)
: DirectoryList(*dbb->dbb_permanent), config(dbb->dbb_config)
{
initialize();
}
static void create(Database* dbb)
{
if (!dbb->dbb_external_file_directory_list)
{
dbb->dbb_external_file_directory_list =
FB_NEW(*dbb->dbb_permanent) ExternalFileDirectoryList(dbb);
}
}
private:
Firebird::RefPtr<Config> config;
};
}
using namespace Jrd;
namespace {
@ -87,29 +114,12 @@ namespace {
#endif
static const char* const FOPEN_READ_ONLY = "rb";
FILE *ext_fopen(Database* dbb, ExternalFile* ext_file);
class ExternalFileDirectoryList : public Firebird::DirectoryList
{
private:
const Firebird::PathName getConfigString() const
{
return Firebird::PathName(Config::getExternalFileAccess());
}
public:
explicit ExternalFileDirectoryList(MemoryPool& p)
: DirectoryList(p)
{
initialize();
}
};
Firebird::InitInstance<ExternalFileDirectoryList> iExternalFileDirectoryList;
FILE *ext_fopen(Database* dbb, ExternalFile* ext_file)
{
const char* file_name = ext_file->ext_filename;
if (!iExternalFileDirectoryList().isPathInList(file_name))
ExternalFileDirectoryList::create(dbb);
if (!dbb->dbb_external_file_directory_list->isPathInList(file_name))
{
ERR_post(Arg::Gds(isc_conf_access_denied) << Arg::Str("external file") <<
Arg::Str(file_name));
@ -190,9 +200,10 @@ ExternalFile* EXT_file(jrd_rel* relation, const TEXT* file_name) //, bid* descri
if (Path.length() == 0)
{
// path component not present in file_name
if (!(iExternalFileDirectoryList().expandFileName(Path, Name)))
ExternalFileDirectoryList::create(dbb);
if (!(dbb->dbb_external_file_directory_list->expandFileName(Path, Name)))
{
iExternalFileDirectoryList().defaultName(Path, Name);
dbb->dbb_external_file_directory_list->defaultName(Path, Name);
}
file_name = Path.c_str();
}

View File

@ -35,6 +35,7 @@
#include <stdio.h>
#include <string.h>
#include "../common/config/config.h"
#include "../jrd/os/path_utils.h"
#include "../jrd/common.h"
#include "../jrd/jrd.h"
#include "../jrd/val.h"

View File

@ -486,8 +486,22 @@ public:
memset(this, 0,
reinterpret_cast<char*>(&this->dpb_sys_user_name) - reinterpret_cast<char*>(this));
}
void get(const UCHAR*, USHORT, bool&);
void setBuffers(Firebird::RefPtr<Config> config)
{
if (dpb_buffers == 0)
{
dpb_buffers = config->getDefaultDbCachePages();
if (dpb_buffers < MIN_PAGE_BUFFERS)
dpb_buffers = MIN_PAGE_BUFFERS;
if (dpb_buffers > MAX_PAGE_BUFFERS)
dpb_buffers = MAX_PAGE_BUFFERS;
}
}
private:
void getPath(ClumpletReader& reader, PathName& s)
{
@ -561,7 +575,7 @@ static ISC_STATUS unwindAttach(thread_db* tdbb, const Exception& ex, ISC_STATUS*
static void ExtractDriveLetter(const TEXT*, ULONG*);
#endif
static Database* init(thread_db*, const PathName&, bool);
static Database* init(thread_db*, const PathName&, Firebird::RefPtr<Config>, bool);
static void prepare(thread_db*, jrd_tra*, USHORT, const UCHAR*);
static void start_multiple(thread_db* tdbb, bool transliterate, jrd_tra** tra_handle,
USHORT count, TEB* vector, FB_API_HANDLE public_handle = 0);
@ -902,6 +916,7 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
UserId userId;
DatabaseOptions options;
Firebird::RefPtr<Config> config;
bool invalid_client_SQL_dialect = false;
PathName file_name, expanded_name;
bool is_alias = false;
@ -926,7 +941,7 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
ISC_utf8ToSystem(file_name);
// Resolve given alias name
is_alias = ResolveDatabaseAlias(file_name, expanded_name);
is_alias = ResolveDatabaseAlias(file_name, expanded_name, &config);
if (is_alias)
{
ISC_systemToUtf8(expanded_name);
@ -975,7 +990,7 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
try
{
// Unless we're already attached, do some initialization
dbb = init(tdbb, expanded_name, true);
dbb = init(tdbb, expanded_name, config, true);
}
catch (const Exception& ex)
{
@ -1096,7 +1111,7 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
pageSpace->file = PIO_open(dbb, expanded_name, file_name, false);
// Initialize the lock manager
dbb->dbb_lock_mgr = LockManager::create(dbb->getUniqueFileId());
dbb->dbb_lock_mgr = LockManager::create(dbb->getUniqueFileId(), dbb->dbb_config);
LCK_init(tdbb, LCK_OWNER_database);
dbb->dbb_flags |= DBB_lck_init_done;
@ -1124,6 +1139,7 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
dbb->dbb_page_buffers = options.dpb_page_buffers;
}
options.setBuffers(dbb->dbb_config);
CCH_init(tdbb, options.dpb_buffers);
// Initialize backup difference subsystem. This must be done before WAL and shadowing
@ -1980,6 +1996,7 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
DatabaseOptions options;
PathName file_name, expanded_name;
bool is_alias = false;
Firebird::RefPtr<Config> config;
try
{
@ -2005,7 +2022,7 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
ISC_utf8ToSystem(file_name);
// Resolve given alias name
is_alias = ResolveDatabaseAlias(file_name, expanded_name);
is_alias = ResolveDatabaseAlias(file_name, expanded_name, &config);
if (is_alias)
{
ISC_systemToUtf8(expanded_name);
@ -2054,7 +2071,7 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
try
{
dbb = init(tdbb, expanded_name, false);
dbb = init(tdbb, expanded_name, config, false);
}
catch (const Exception& ex)
{
@ -2188,7 +2205,7 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
const jrd_file* const first_dbb_file = pageSpace->file;
// Initialize the lock manager
dbb->dbb_lock_mgr = LockManager::create(dbb->getUniqueFileId());
dbb->dbb_lock_mgr = LockManager::create(dbb->getUniqueFileId(), dbb->dbb_config);
LCK_init(tdbb, LCK_OWNER_database);
dbb->dbb_flags |= DBB_lck_init_done;
@ -2208,14 +2225,15 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
if (options.dpb_set_page_buffers)
dbb->dbb_page_buffers = options.dpb_page_buffers;
CCH_init(tdbb, options.dpb_buffers);
#ifdef WIN_NT
dbb->dbb_filename.assign(first_dbb_file->fil_string);
#else
dbb->dbb_filename = expanded_name;
#endif
options.setBuffers(dbb->dbb_config);
CCH_init(tdbb, options.dpb_buffers);
// NS: Use alias as database ID only if accessing database using file name is not possible.
//
// This way we:
@ -4740,13 +4758,7 @@ void DatabaseOptions::get(const UCHAR* dpb, USHORT dpb_length, bool& invalid_cli
**************************************/
SSHORT num_old_files = 0;
ULONG page_cache_size = Config::getDefaultDbCachePages();
if (page_cache_size < MIN_PAGE_BUFFERS)
page_cache_size = MIN_PAGE_BUFFERS;
if (page_cache_size > MAX_PAGE_BUFFERS)
page_cache_size = MAX_PAGE_BUFFERS;
dpb_buffers = page_cache_size;
dpb_buffers = 0;
dpb_sweep_interval = -1;
dpb_overwrite = false;
dpb_sql_dialect = 99;
@ -5114,6 +5126,7 @@ static ISC_STATUS handle_error(ISC_STATUS* user_status, ISC_STATUS code)
static Database* init(thread_db* tdbb,
const PathName& expanded_filename, // only for SS
Firebird::RefPtr<Config> config,
bool attach_flag) // only for SS
{
/**************************************
@ -5163,6 +5176,7 @@ static Database* init(thread_db* tdbb,
#endif
dbb = Database::create();
dbb->dbb_config = config;
tdbb->setDatabase(dbb);
dbb->dbb_bufferpool = dbb->createPool();
@ -5182,7 +5196,7 @@ static Database* init(thread_db* tdbb,
if ((dbb->dbb_flags & (DBB_gc_cooperative | DBB_gc_background)) == 0)
{
string gc_policy = Config::getGCPolicy();
string gc_policy = dbb->dbb_config->getGCPolicy();
gc_policy.lower();
if (gc_policy == GCPolicyCooperative) {
dbb->dbb_flags |= DBB_gc_cooperative;

View File

@ -94,8 +94,6 @@ public:
config_file = root_dir + string(CONFIG_FILE);
}
virtual ~ConfigRoot() {}
const char* getInstallDirectory()
{
return install_dir.c_str();

View File

@ -1071,7 +1071,8 @@ void PAG_header(thread_db* tdbb, bool info)
Arg::Str(attachment->att_filename));
}
const bool useFSCache = dbb->dbb_bcb->bcb_count < ULONG(Config::getFileSystemCacheThreshold());
const bool useFSCache = dbb->dbb_bcb->bcb_count <
ULONG(dbb->dbb_config->getFileSystemCacheThreshold());
if ((header->hdr_flags & hdr_force_write) || !useFSCache)
{
@ -2046,13 +2047,13 @@ bool PageSpace::extend(thread_db* tdbb, const ULONG pageNum)
* extend file(s)
*
**************************************/
const int MAX_EXTEND_BYTES = Config::getDatabaseGrowthIncrement();
fb_assert(dbb == tdbb->getDatabase())
const int MAX_EXTEND_BYTES = dbb->dbb_config->getDatabaseGrowthIncrement();
if (pageNum < maxPageNumber || MAX_EXTEND_BYTES < MIN_EXTEND_BYTES)
return true;
fb_assert(dbb == tdbb->getDatabase())
if (pageNum >= maxAlloc())
{
const ULONG minExtendPages = MIN_EXTEND_BYTES / dbb->dbb_page_size;

View File

@ -117,7 +117,8 @@ void BufferedStream::open(thread_db* tdbb)
delete impure->irsb_buffer;
MemoryPool& pool = *tdbb->getDefaultPool();
impure->irsb_buffer = FB_NEW(pool) RecordBuffer(pool, m_format);
impure->irsb_buffer = FB_NEW(pool) RecordBuffer(pool, m_format,
tdbb->getDatabase()->dbb_config);
impure->irsb_position = 0;
}

View File

@ -297,7 +297,8 @@ bool MergeJoin::getRecord(thread_db* tdbb)
if (!mfb->mfb_space)
{
MemoryPool& pool = *getDefaultMemoryPool();
mfb->mfb_space = FB_NEW(pool) TempSpace(pool, SCRATCH);
mfb->mfb_space = FB_NEW(pool) TempSpace(pool, SCRATCH,
tdbb->getDatabase()->dbb_config);
}
SORT_write_block(mfb->mfb_space, mfb->mfb_block_size * mfb->mfb_current_block,
@ -509,7 +510,8 @@ SLONG MergeJoin::getRecord(thread_db* tdbb, size_t index)
if (!mfb->mfb_space)
{
MemoryPool& pool = *getDefaultMemoryPool();
mfb->mfb_space = FB_NEW(pool) TempSpace(pool, SCRATCH);
mfb->mfb_space = FB_NEW(pool) TempSpace(pool, SCRATCH,
tdbb->getDatabase()->dbb_config);
}
SORT_write_block(mfb->mfb_space, mfb->mfb_block_size * mfb->mfb_current_block,

View File

@ -382,7 +382,7 @@ sort_context* SORT_init(Database* dbb,
// Set up the temp space
scb->scb_space = FB_NEW(pool) TempSpace(pool, SCRATCH);
scb->scb_space = FB_NEW(pool) TempSpace(pool, SCRATCH, dbb->dbb_config);
// Set up to receive the first record

View File

@ -282,7 +282,7 @@ public:
return tra_outer->getBlobSpace();
if (!tra_blob_space)
tra_blob_space = FB_NEW(*tra_pool) TempSpace(*tra_pool, TRA_BLOB_SPACE);
tra_blob_space = FB_NEW(*tra_pool) TempSpace(*tra_pool, TRA_BLOB_SPACE, tra_attachment->att_database->dbb_config);
return tra_blob_space;
}
@ -290,7 +290,7 @@ public:
TempSpace* getUndoSpace()
{
if (!tra_undo_space)
tra_undo_space = FB_NEW(*tra_pool) TempSpace(*tra_pool, TRA_UNDO_SPACE);
tra_undo_space = FB_NEW(*tra_pool) TempSpace(*tra_pool, TRA_UNDO_SPACE, tra_attachment->att_database->dbb_config);
return tra_undo_space;
}

View File

@ -165,14 +165,14 @@ Firebird::GlobalPtr<LockManager::DbLockMgrMap> LockManager::g_lmMap;
Firebird::GlobalPtr<Firebird::Mutex> LockManager::g_mapMutex;
LockManager* LockManager::create(const Firebird::string& id)
LockManager* LockManager::create(const Firebird::string& id, Firebird::RefPtr<Config> conf)
{
Firebird::MutexLockGuard guard(g_mapMutex);
LockManager* lockMgr = NULL;
if (!g_lmMap->get(id, lockMgr))
{
lockMgr = new LockManager(id);
lockMgr = new LockManager(id, conf);
}
fb_assert(lockMgr);
@ -181,7 +181,7 @@ LockManager* LockManager::create(const Firebird::string& id)
}
LockManager::LockManager(const Firebird::string& id)
LockManager::LockManager(const Firebird::string& id, Firebird::RefPtr<Config> conf)
: PID(getpid()),
m_bugcheck(false),
m_sharedFileCreated(false),
@ -189,8 +189,9 @@ LockManager::LockManager(const Firebird::string& id)
m_process(NULL),
m_processOffset(0),
m_dbId(getPool(), id),
m_acquireSpins(Config::getLockAcquireSpins()),
m_memorySize(Config::getLockMemSize())
m_config(conf),
m_acquireSpins(m_config->getLockAcquireSpins()),
m_memorySize(m_config->getLockMemSize())
#ifdef USE_SHMEM_EXT
, m_extents(getPool())
#endif
@ -2338,14 +2339,14 @@ void LockManager::initialize(sh_mem* shmem_data, bool initializeMemory)
}
#endif
int hash_slots = Config::getLockHashSlots();
int hash_slots = m_config->getLockHashSlots();
if (hash_slots < HASH_MIN_SLOTS)
hash_slots = HASH_MIN_SLOTS;
if (hash_slots > HASH_MAX_SLOTS)
hash_slots = HASH_MAX_SLOTS;
m_header->lhb_hash_slots = (USHORT) hash_slots;
m_header->lhb_scan_interval = Config::getDeadlockTimeout();
m_header->lhb_scan_interval = m_config->getDeadlockTimeout();
m_header->lhb_acquire_spins = m_acquireSpins;
// Initialize lock series data queues and lock hash chains
@ -2363,7 +2364,7 @@ void LockManager::initialize(sh_mem* shmem_data, bool initializeMemory)
// Set lock_ordering flag for the first time
if (Config::getLockGrantOrder())
if (m_config->getLockGrantOrder())
m_header->lhb_flags |= LHB_lock_ordering;
const ULONG length = sizeof(lhb) + (m_header->lhb_hash_slots * sizeof(m_header->lhb_hash[0]));

View File

@ -307,6 +307,8 @@ namespace Firebird {
class RWLock;
}
class Config;
namespace Jrd {
class Database;
@ -321,7 +323,7 @@ class LockManager : public Firebird::RefCounted, public Firebird::GlobalStorage
const int PID;
public:
static LockManager* create(const Firebird::string&);
static LockManager* create(const Firebird::string&, Firebird::RefPtr<Config>);
bool initializeOwner(Firebird::Arg::StatusVector&, LOCK_OWNER_T, UCHAR, SRQ_PTR*);
void shutdownOwner(Database*, SRQ_PTR*);
@ -340,7 +342,7 @@ public:
SLONG writeData(SRQ_PTR, SLONG);
private:
explicit LockManager(const Firebird::string&);
explicit LockManager(const Firebird::string&, Firebird::RefPtr<Config>);
~LockManager();
bool lockOrdering() const
@ -434,6 +436,7 @@ private:
Firebird::Semaphore m_startupSemaphore;
Firebird::string m_dbId;
Firebird::RefPtr<Config> m_config;
const ULONG m_acquireSpins;
const ULONG m_memorySize;

View File

@ -386,7 +386,7 @@ int CLIB_ROUTINE main( int argc, char *argv[])
{
Firebird::PathName org_name = db_file;
Firebird::PathName db_name;
if (!ResolveDatabaseAlias(org_name, db_name))
if (!ResolveDatabaseAlias(org_name, db_name, NULL))
{
db_name = org_name;
}

View File

@ -557,7 +557,7 @@ int gstat(Firebird::UtilSvc* uSvc)
}
}
if (ResolveDatabaseAlias(fileName, tempStr)) {
if (ResolveDatabaseAlias(fileName, tempStr, NULL)) {
fileName = tempStr;
}

View File

@ -266,7 +266,7 @@ public:
if (strncmp(db.c_str(), local_prefix, sizeof(local_prefix) - 1) == 0)
db = db.substr(sizeof(local_prefix) - 1);
if (!ResolveDatabaseAlias(db, dbname))
if (!ResolveDatabaseAlias(db, dbname, NULL))
dbname = db;
}

View File

@ -47,14 +47,14 @@ void TraceCfgReader::readTraceConfiguration(const char* text,
#define PATH_PARAMETER(NAME, VALUE) \
if (!found && el->name == #NAME) { \
string temp; \
ConfigFile::String temp; \
expandPattern(el, temp); \
m_config.NAME = temp.c_str(); \
found = true; \
}
#define STR_PARAMETER(NAME, VALUE) \
if (!found && el->name == #NAME) { \
m_config.NAME = el->getAttributeName(0); \
m_config.NAME = el->value; \
found = true; \
}
#define BOOL_PARAMETER(NAME, VALUE) \
@ -92,21 +92,8 @@ namespace
void TraceCfgReader::readConfig()
{
Firebird::AutoPtr<ConfigFile> cfgFile(new ConfigFile(Lex::LEX_none));
cfgFile->addText(m_text);
try
{
cfgFile->parse();
}
catch (const AdminException& ex)
{
fatal_exception::raiseFmt("error while parsing trace configuration\n\t%s",
ex.getText());
}
catch (...)
{
fatal_exception::raiseFmt("unknown error while parsing trace configuration");
}
ConfigFile cfgFile(ConfigFile::USE_TEXT, m_text,
ConfigFile::HAS_SUB_CONF | ConfigFile::EXCEPTION_ON_ERROR);
m_subpatterns[0].start = 0;
m_subpatterns[0].end = m_databaseName.length();
@ -130,14 +117,16 @@ void TraceCfgReader::readConfig()
Jrd::TextType textType(0, &tt, charSet);
bool defDB = false, defSvc = false, exactMatch = false;
const Element* section = cfgFile->getObjects()->children;
for (; section && !exactMatch; section = section->sibling)
const ConfigFile::Parameters& params = cfgFile.getParameters();
for (size_t n = 0; n < params.getCount() && !exactMatch; ++n)
{
const ConfigFile::Parameter* section = &params[n];
const bool isDatabase = (section->name == "database");
if (!isDatabase && section->name != "services")
continue;
const string pattern = section->getAttributes() ? section->getAttributeName(0) : "";
const ConfigFile::String pattern = section->value;
bool match = false;
if (pattern.empty())
{
@ -146,7 +135,7 @@ void TraceCfgReader::readConfig()
if (defDB)
{
fatal_exception::raiseFmt("line %d: second default database section is not allowed",
section->lineNumber + 1);
section->line);
}
match = !m_databaseName.empty();
@ -157,7 +146,7 @@ void TraceCfgReader::readConfig()
if (defSvc)
{
fatal_exception::raiseFmt("line %d: second default service section is not allowed",
section->lineNumber + 1);
section->line);
}
match = m_databaseName.empty();
defSvc = true;
@ -205,12 +194,12 @@ void TraceCfgReader::readConfig()
if (regExpOk) {
fatal_exception::raiseFmt(
"line %d: error while processing string \"%s\" against regular expression \"%s\"",
section->lineNumber + 1, m_databaseName.c_str(), pattern.c_str());
section->line, m_databaseName.c_str(), pattern.c_str());
}
else {
fatal_exception::raiseFmt(
"line %d: error while compiling regular expression \"%s\"",
section->lineNumber + 1, pattern.c_str());
section->line, pattern.c_str());
}
}
}
@ -219,12 +208,15 @@ void TraceCfgReader::readConfig()
if (!match)
continue;
for (const Element* el = section->children; el; el = el->sibling)
const ConfigFile::Parameters& elements = section->sub->getParameters();
for (size_t p = 0; p < elements.getCount(); ++p)
{
if (!el->getAttributes())
const ConfigFile::Parameter* el = &elements[p];
if (!el->value.hasData())
{
fatal_exception::raiseFmt("line %d: element \"%s\" have no attribute value set",
el->lineNumber + 1, el->name.c_str());
el->line, el->name.c_str());
}
bool found = false;
@ -244,7 +236,7 @@ void TraceCfgReader::readConfig()
if (!found)
{
fatal_exception::raiseFmt("line %d: element \"%s\" is unknown",
el->lineNumber + 1, el->name.c_str());
el->line, el->name.c_str());
}
}
}
@ -255,10 +247,9 @@ void TraceCfgReader::readConfig()
#undef BOOL_PARAMETER
#undef UINT_PARAMETER
bool TraceCfgReader::parseBoolean(const Element* el) const
bool TraceCfgReader::parseBoolean(const ConfigFile::Parameter* el) const
{
const char* value = el->getAttributeName(0);
string tempValue(value);
ConfigFile::String tempValue(el->value);
tempValue.upper();
if (tempValue == "1" || tempValue == "ON" || tempValue == "YES" || tempValue == "TRUE")
@ -267,24 +258,24 @@ bool TraceCfgReader::parseBoolean(const Element* el) const
return false;
fatal_exception::raiseFmt("line %d, element \"%s\": \"%s\" is not a valid boolean value",
el->lineNumber + 1, el->name.c_str(), value);
el->line, el->name.c_str(), el->value.c_str());
return false; // Silence the compiler
}
ULONG TraceCfgReader::parseUInteger(const Element* el) const
ULONG TraceCfgReader::parseUInteger(const ConfigFile::Parameter* el) const
{
const char *value = el->getAttributeName(0);
const char *value = el->value.c_str();
ULONG result = 0;
if (!sscanf(value, "%"ULONGFORMAT, &result)) {
fatal_exception::raiseFmt("line %d, element \"%s\": \"%s\" is not a valid integer value",
el->lineNumber + 1, el->name.c_str(), value);
el->line, el->name.c_str(), value);
}
return result;
}
void TraceCfgReader::expandPattern(const Element* el, string& valueToExpand)
void TraceCfgReader::expandPattern(const ConfigFile::Parameter* el, ConfigFile::String& valueToExpand)
{
valueToExpand = el->getAttributeName(0);
valueToExpand = el->value;
string::size_type pos = 0;
while (pos < valueToExpand.length())
{
@ -293,7 +284,7 @@ void TraceCfgReader::expandPattern(const Element* el, string& valueToExpand)
{
if (pos + 1 >= valueToExpand.length())
fatal_exception::raiseFmt("line %d, element \"%s\": pattern is invalid\n\t %s",
el->lineNumber + 1, el->name.c_str(), el->getAttributeName(0));
el->line, el->name.c_str(), el->value.c_str());
c = valueToExpand[pos + 1];
if (c == '\\')
@ -321,7 +312,7 @@ void TraceCfgReader::expandPattern(const Element* el, string& valueToExpand)
}
fatal_exception::raiseFmt("line %d, element \"%s\": pattern is invalid\n\t %s",
el->lineNumber + 1, el->name.c_str(), el->getAttributeName(0));
el->line, el->name.c_str(), el->value.c_str());
}
pos++;

View File

@ -31,11 +31,7 @@
#include "firebird.h"
#include "../../common/classes/auto.h"
#include "../../common/classes/fb_string.h"
#include "../../config/ConfigFile.h"
#include "../../config/ConfObj.h"
#include "../../config/ConfObject.h"
#include "../../config/Element.h"
#include "../../config/AdminException.h"
#include "../../common/config/config_file.h"
#include "TracePluginConfig.h"
#include <sys/types.h>
@ -62,9 +58,9 @@ private:
void readConfig();
void expandPattern(const Element* el, Firebird::string& valueToExpand);
bool parseBoolean(const Element* el) const;
ULONG parseUInteger(const Element* el) const;
void expandPattern(const ConfigFile::Parameter* el, Firebird::PathName& valueToExpand);
bool parseBoolean(const ConfigFile::Parameter* el) const;
ULONG parseUInteger(const ConfigFile::Parameter* el) const;
const char* const m_text;
const Firebird::PathName& m_databaseName;

View File

@ -38,7 +38,7 @@ struct TracePluginConfig
#define SERVICE_PARAMS
#define PATH_PARAMETER(NAME, VALUE) Firebird::PathName NAME;
#define STR_PARAMETER(NAME, VALUE) Firebird::string NAME;
#define STR_PARAMETER(NAME, VALUE) Firebird::PathName NAME;
#define BOOL_PARAMETER(NAME, VALUE) bool NAME;
#define UINT_PARAMETER(NAME, VALUE) ULONG NAME;
#include "paramtable.h"

View File

@ -15,20 +15,20 @@
# \\ is backslash.
# default database section
#
<database>
database
{
# Do we trace database events or not
enabled false
enabled = 0
# Operations log file name. For use by system audit trace only
#log_filename
#log_filename = name
# Maximum size of log file (megabytes). Used by system audit trace for
# log's rotation : when current log file reached this limit it is renamed
# using current date and time and new log file is created. Value of zero
# means that the log file size is unlimited and rotation will never happen.
max_log_size 0
#max_log_size 0
# SQL query filters.
@ -43,83 +43,83 @@
# Put attach/detach log records
log_connections false
#log_connections = 0
# Trace only given connection id. If zero - trace all connections
#connection_id 0
#connection_id = 0
# Put transaction start/end records
log_transactions false
#log_transactions = 0
# Put sql statement prepare records
log_statement_prepare false
#log_statement_prepare = 0
# Put sql statement free records
log_statement_free false
#log_statement_free = 0
# Put sql statement execution start records
log_statement_start false
#log_statement_start = 0
# Put sql statement execution finish\fetch to eof records
log_statement_finish false
#log_statement_finish = 0
# Put record when stored procedure is start execution
log_procedure_start false
#log_procedure_start = 0
# Put record when stored procedure is finish execution
log_procedure_finish false
#log_procedure_finish = 0
# Put trigger execute records
log_trigger_start false
#log_trigger_start = 0
# Put trigger execute records
log_trigger_finish false
#log_trigger_finish = 0
# Put context variable change records (RDB$SET_CONTEXT)
#log_context false
#log_context = 0
# Print access path (plan) with sql statement
print_plan false
#print_plan = 0
# Print detailed performance info when applicable
print_perf false
#print_perf = 0
# Put blr requests compile/execute records
log_blr_requests false
@log_blr_requests = 0
# Print blr requests or not
print_blr false
#print_blr = 0
# Put dyn requests execute records
log_dyn_requests false
#log_dyn_requests = 0
# Print dyn requests or not
print_dyn false
#print_dyn = 0
# Put xxx_finish record only if its timing exceeds this number of milliseconds
time_threshold 100
#time_threshold = 100
# Maximum length of SQL string logged
# Beware when adjusting max_xxx parameters! Maximum length of log record
# for one event should never exceed 64K.
max_sql_length 300
#max_sql_length = 300
# Maximum length of blr request logged
max_blr_length 500
#max_blr_length = 500
# Maximum length of dyn request logged
max_dyn_length 500
#max_dyn_length = 500
# Maximum length of individual string argument we log
max_arg_length 80
#max_arg_length = 80
# Maximum number of query arguments to put in log
max_arg_count 30
</database>
#max_arg_count = 30
}
@ -147,16 +147,17 @@
# Set Domain Admins Mapping to RDB$ADMIN
# Drop Domain Admins Mapping to RDB$ADMIN
#
<services>
services
{
# Do we trace services events or not
enabled false
#enabled =0
# Operations log file name. For use by system audit trace only
#log_filename
#log_filename name
# Maximum size of log file (megabytes). Used by system audit trace for
# log's rotation
max_log_size 0
#max_log_size 0
# Services filters.
#
@ -169,27 +170,29 @@
#exclude_filter
# Put service attach, detach and start records
log_services false
#log_services false
# Put service query records
log_service_query false
</services>
#log_service_query false
}
# Example of trace customization:
#
# Enable logging for my_database.fdb in any folder
#
<database %[\\/]my_database.fdb>
enabled true
</database>
database = %[\\/]my_database.fdb
{
enabled = 1
}
# Enable logging for test.fdb, azk2.fdb and rulez.fdb in any directory
# into log file name matching database name - test.log, azk2.log and
# rulez.log appropriately
#
<database %[\\/](test|azk2|rulez).fdb>
database = %[\\/](test|azk2|rulez).fdb
{
enabled true
log_filename \1.log
</database>
}

View File

@ -1,187 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 2004 James A. Starkey
* All Rights Reserved.
*/
#include <string.h>
#include <stdlib.h>
#include <memory.h>
#include "firebird.h"
#include "../jrd/common.h"
#include "../jrd/ibase.h"
#include "PathName.h"
#ifdef _WIN32
#include <windows.h>
#define SEPARATOR '\\'
#define IS_SEPARATOR(c) (c == '/' || c == '\\')
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
#ifndef SEPARATOR
#define SEPARATOR '/'
#define IS_SEPARATOR(c) (c == '/')
#endif
#define IS_LETTER(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
//#define UPPER(c) ((c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c)
PathName::PathName()
{
}
PathName::~PathName()
{
}
int PathName::merge(const char* fileName, const char* workingDirectory, int bufferLength, char* buffer)
{
const char* const endBuffer = buffer + bufferLength - 1;
if (isAbsolute (fileName))
{
char* rc = copyCanonical (fileName, buffer, endBuffer);
return rc - buffer;
}
// Copy working directory, making slashes canonical
char* q = copyCanonical (workingDirectory, buffer, endBuffer);
#ifdef _WIN32
if (IS_SEPARATOR (fileName [0]))
{
for (q = buffer; *q && *q++ != ':';)
;
q = copyCanonical (fileName, q, endBuffer);
return q - buffer;
}
#endif
// And add a trailing slash, if necessary
if (q == buffer || q [-1] != '/')
*q++ = '/';
// Handle self relative segments
const char* p = fileName;
while (*p == '.')
{
if (IS_SEPARATOR (p[1]))
p += 2;
else if (p [1] == '.' && IS_SEPARATOR (p [2]))
{
p += 3;
q -= 1;
while (q > buffer && q [-1] != '/')
--q;
if (q == buffer || q [-1] != '/')
*q++ = '/';
}
else if (!p [1])
++p;
}
// skip over extra separators in the file name
while (IS_SEPARATOR (*p))
++p;
// and move in the final filename
q = copyCanonical (p, q, endBuffer);
return q - buffer;
}
bool PathName::isAbsolute(const char* fileName)
{
#ifdef _WIN32
return (IS_LETTER (fileName [0]) &&
fileName [1] == ':' && (fileName [2] == '/' || fileName [2] == '\\')) ||
(fileName[0] == '/' && fileName[1] == '/') ||
(fileName[0] == '\\' && fileName[1] == '\\');
#else
return fileName [0] == '/';
#endif
}
char* PathName::copyCanonical(const char* fileName, char* buffer, const char* endBuffer)
{
char* q = buffer;
const char* p = fileName;
#ifdef _WIN32
if (IS_SEPARATOR (*p))
{
*q++ = '/';
++p;
}
#endif
while (*p && q < endBuffer)
{
char c = *p++;
if (IS_SEPARATOR (c))
{
c = '/';
while (IS_SEPARATOR (*p))
++p;
}
*q++ = c;
}
*q = 0;
return q;
}
bool PathName::hasDirectory(const char* fileName)
{
for (const char* p = fileName; *p; ++p)
{
if (IS_SEPARATOR (*p))
return true;
}
return false;
}
bool PathName::pathsEquivalent(const char* path1, const char* path2)
{
#ifdef _WIN32
return stricmp(path1, path2) == 0;
#else
return strcmp (path1, path2) == 0;
#endif
}

View File

@ -1,49 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 2004 James A. Starkey
* All Rights Reserved.
*/
#ifndef VULCAN_PATHNAME_H_
#define VULCAN_PATHNAME_H_
#if defined _MSC_VER && _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER > 1000
#include "../common/classes/fb_string.h"
class PathName : public Firebird::GlobalStorage
{
public:
PathName();
virtual ~PathName();
static int merge(const char* fileName, const char* workingDirectory, int bufferLength, char* buffer);
static bool isAbsolute(const char* fileName);
static char* copyCanonical(const char* fileName, char* buffer, const char* endBuffer);
static bool hasDirectory(const char* fileName);
static bool pathsEquivalent(const char* path1, const char* path2);
};
#endif // VULCAN_PATHNAME_H_

View File

@ -1,57 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
// RefObject.cpp: implementation of the RefObject class.
//
//////////////////////////////////////////////////////////////////////
#include "firebird.h"
#include "../common/classes/alloc.h"
#include "RefObject.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
RefObject::RefObject()
{
useCount = 1;
}
RefObject::~RefObject()
{
}
void RefObject::addRef()
{
++useCount;
}
void RefObject::release()
{
if (--useCount == 0)
delete this;
}

View File

@ -1,49 +0,0 @@
/*
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/idpl.html.
*
* Software distributed under the License is distributed on
* an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The contents of this file or any work derived from this file
* may not be distributed under any other license whatsoever
* without the express prior written permission of the original
* author.
*
*
* The Original Code was created by James A. Starkey for IBPhoenix.
*
* Copyright (c) 1997 - 2000, 2001, 2003 James A. Starkey
* Copyright (c) 1997 - 2000, 2001, 2003 Netfrastructure, Inc.
* All Rights Reserved.
*/
// RefObject.h: interface for the RefObject class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_REFOBJECT_H__B78AA20E_CBF1_4191_B648_177D9CE87E32__INCLUDED_)
#define AFX_REFOBJECT_H__B78AA20E_CBF1_4191_B648_177D9CE87E32__INCLUDED_
#if defined _MSC_VER && _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER > 1000
class RefObject
{
public:
RefObject();
virtual ~RefObject();
virtual void addRef();
virtual void release();
private:
int useCount;
};
#endif // !defined(AFX_REFOBJECT_H__B78AA20E_CBF1_4191_B648_177D9CE87E32__INCLUDED_)