8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 15:23:02 +01:00

The merge continued.

This commit is contained in:
dimitr 2008-01-16 06:11:50 +00:00
parent 845259bf3f
commit 12c4322ab9
15 changed files with 969 additions and 751 deletions

View File

@ -47,6 +47,7 @@
#include "../jrd/align.h" #include "../jrd/align.h"
#include "../jrd/gdsassert.h" #include "../jrd/gdsassert.h"
#include "../jrd/thd.h" #include "../jrd/thd.h"
#include "../jrd/constants.h"
#include "../common/stuff.h" #include "../common/stuff.h"
#include "../burp/backu_proto.h" #include "../burp/backu_proto.h"
#include "../burp/burp_proto.h" #include "../burp/burp_proto.h"
@ -126,6 +127,7 @@ void write_functions(void);
void write_function_args(GDS_NAME); void write_function_args(GDS_NAME);
void write_generators(void); void write_generators(void);
void write_sql_roles(void); void write_sql_roles(void);
void write_mapping(void);
void write_global_fields(void); void write_global_fields(void);
void write_procedures(void); void write_procedures(void);
void write_procedure_prms(GDS_NAME); void write_procedure_prms(GDS_NAME);
@ -158,13 +160,17 @@ enum backup_capabilities
BCK_ods10 = 8192, // FIELD_PRECISION BCK_ods10 = 8192, // FIELD_PRECISION
BCK_ods11 = 16384,// rdb$description in rdb$roles and rdb$generators BCK_ods11 = 16384,// rdb$description in rdb$roles and rdb$generators
// rdb$base_collation_name and rdb$specific_attributes in rdb$collations // rdb$base_collation_name and rdb$specific_attributes in rdb$collations
BCK_ods11_1 = 32768 // rdb$relation_type in rdb$relations BCK_ods11_1 = 32768,// rdb$relation_type in rdb$relations
// rdb$procedure_type in rdb$procedures // rdb$procedure_type in rdb$procedures
// rdb$valid_blr in rdb$triggers // rdb$valid_blr in rdb$triggers
// rdb$valid_blr in rdb$procedures // rdb$valid_blr in rdb$procedures
// rdb$default_value, rdb$default_source, rdb$collation_id, // rdb$default_value, rdb$default_source, rdb$collation_id,
// rdb$null_flag and rdb$parameter_mechanism in rdb$procedure_parameters // rdb$null_flag and rdb$parameter_mechanism in rdb$procedure_parameters
BCK_ods11_2 = 65536 // rdb$field_name and rdb$relation_name in rdb$procedure_parameters
// rdb$admin system role
}; };
// ASF: Engine that works with ODS11.1 supports access to non-existent system fields.
// Reads returns NULL and writes do nothing.
#ifdef DEBUG #ifdef DEBUG
UCHAR debug_on = 0; // able to turn this on in debug mode UCHAR debug_on = 0; // able to turn this on in debug mode
@ -217,6 +223,8 @@ const rfr_tab_t rfr_table[] =
//{"RDB$PROCEDURE_PARAMETERS", "RDB$COLLATION_ID", BCK_ods11_1}, //{"RDB$PROCEDURE_PARAMETERS", "RDB$COLLATION_ID", BCK_ods11_1},
//{"RDB$PROCEDURE_PARAMETERS", "RDB$NULL_FLAG", BCK_ods11_1}, //{"RDB$PROCEDURE_PARAMETERS", "RDB$NULL_FLAG", BCK_ods11_1},
//{"RDB$PROCEDURE_PARAMETERS", "RDB$PARAMETER_MECHANISM", BCK_ods11_1}, //{"RDB$PROCEDURE_PARAMETERS", "RDB$PARAMETER_MECHANISM", BCK_ods11_1},
{"RDB$PROCEDURE_PARAMETERS", "RDB$FIELD_NAME", BCK_ods11_2},
//{"RDB$PROCEDURE_PARAMETERS", "RDB$RELATION_NAME", BCK_ods11_2},
{0, 0, 0} {0, 0, 0}
}; };
@ -333,7 +341,7 @@ int BACKUP_backup(const TEXT* dbb_file, const TEXT* file_name)
tdgbl->action->act_file = fil; tdgbl->action->act_file = fil;
if (MVOL_split_hdr_write() == FALSE) if (MVOL_split_hdr_write() == FALSE)
{ {
BURP_error(269, true, tdgbl->action->act_file->fil_name); BURP_error(269, true, tdgbl->action->act_file->fil_name.c_str());
// msg 269 can't write a header record to file %s // msg 269 can't write a header record to file %s
} }
} }
@ -500,6 +508,14 @@ int BACKUP_backup(const TEXT* dbb_file, const TEXT* file_name)
write_sql_roles(); write_sql_roles();
} }
if (tdgbl->BCK_capabilities & BCK_ods11)
{
// Write names mapping
BURP_verbose(296);
// msg 296 writing mapping
write_mapping();
}
// Finish up // Finish up
put(tdgbl, (UCHAR) (rec_end)); put(tdgbl, (UCHAR) (rec_end));
@ -3438,7 +3454,8 @@ void write_procedures(void)
BurpGlobals* tdgbl = BurpGlobals::getSpecific(); BurpGlobals* tdgbl = BurpGlobals::getSpecific();
if (tdgbl->BCK_capabilities & BCK_ods11_1) { if (tdgbl->BCK_capabilities & BCK_ods11_1)
{
FOR (REQUEST_HANDLE req_handle1) FOR (REQUEST_HANDLE req_handle1)
X IN RDB$PROCEDURES X IN RDB$PROCEDURES
WITH X.RDB$SYSTEM_FLAG MISSING OR X.RDB$SYSTEM_FLAG NE 1 WITH X.RDB$SYSTEM_FLAG MISSING OR X.RDB$SYSTEM_FLAG NE 1
@ -3521,7 +3538,7 @@ void write_procedure_prms( GDS_NAME procptr)
BurpGlobals* tdgbl = BurpGlobals::getSpecific(); BurpGlobals* tdgbl = BurpGlobals::getSpecific();
if (tdgbl->BCK_capabilities & BCK_ods11) if (tdgbl->BCK_capabilities & BCK_ods11_1)
{ {
FOR (REQUEST_HANDLE tdgbl->handles_write_procedure_prms_req_handle1) FOR (REQUEST_HANDLE tdgbl->handles_write_procedure_prms_req_handle1)
X IN RDB$PROCEDURE_PARAMETERS WITH X.RDB$PROCEDURE_NAME EQ procptr X IN RDB$PROCEDURE_PARAMETERS WITH X.RDB$PROCEDURE_NAME EQ procptr
@ -3544,6 +3561,13 @@ void write_procedure_prms( GDS_NAME procptr)
put_numeric (att_procedureprm_null_flag, X.RDB$NULL_FLAG); put_numeric (att_procedureprm_null_flag, X.RDB$NULL_FLAG);
if (!X.RDB$PARAMETER_MECHANISM.NULL) if (!X.RDB$PARAMETER_MECHANISM.NULL)
put_numeric (att_procedureprm_mechanism, X.RDB$PARAMETER_MECHANISM); put_numeric (att_procedureprm_mechanism, X.RDB$PARAMETER_MECHANISM);
// BCK_ods11_2
if (!X.RDB$FIELD_NAME.NULL)
PUT_TEXT(att_procedureprm_field_name, X.RDB$FIELD_NAME);
if (!X.RDB$RELATION_NAME.NULL)
PUT_TEXT(att_procedureprm_relation_name, X.RDB$RELATION_NAME);
put(tdgbl, att_end); put(tdgbl, att_end);
END_FOR; END_FOR;
ON_ERROR ON_ERROR
@ -3896,7 +3920,7 @@ void write_sql_roles(void)
{ {
FOR (REQUEST_HANDLE req_handle1) FOR (REQUEST_HANDLE req_handle1)
X IN RDB$ROLES X IN RDB$ROLES
WITH X.RDB$SYSTEM_FLAG NE 1 OR X.RDB$SYSTEM_FLAG MISSING WITH X.RDB$SYSTEM_FLAG EQ 0 OR X.RDB$SYSTEM_FLAG MISSING
put(tdgbl, rec_sql_roles); put(tdgbl, rec_sql_roles);
const SSHORT l = PUT_TEXT(att_role_name, X.RDB$ROLE_NAME); const SSHORT l = PUT_TEXT(att_role_name, X.RDB$ROLE_NAME);
@ -3937,6 +3961,48 @@ void write_sql_roles(void)
MISC_release_request_silent(req_handle1); MISC_release_request_silent(req_handle1);
} }
void write_mapping(void)
{
/**************************************
*
* w r i t e _ m a p p i n g
*
**************************************
*
* Functional description
* write a record in the burp file for
* each names mapping.
*
**************************************/
isc_req_handle req_handle = 0;
BurpGlobals* tdgbl = BurpGlobals::getSpecific();
if (tdgbl->BCK_capabilities & BCK_ods11_2)
{
FOR (REQUEST_HANDLE req_handle)
X IN RDB$ROLES
WITH X.RDB$ROLE_NAME EQ ADMIN_ROLE
if (X.RDB$SYSTEM_FLAG == (ROLE_FLAG_MAY_TRUST | ROLE_FLAG_DBO))
{
put(tdgbl, rec_mapping);
put_text(att_map_os, DOMAIN_ADMINS, strlen(DOMAIN_ADMINS) + 1);
put_text(att_map_role, ADMIN_ROLE, strlen(ADMIN_ROLE) + 1);
put(tdgbl, att_end);
BURP_verbose (297, ADMIN_ROLE);
// msg 297 writing mapping for @1
}
END_FOR;
ON_ERROR
general_on_error();
END_ERROR;
}
MISC_release_request_silent(req_handle);
}
void write_triggers(void) void write_triggers(void)
{ {
/************************************** /**************************************

File diff suppressed because it is too large Load Diff

View File

@ -35,7 +35,8 @@
#include "../jrd/dsc.h" #include "../jrd/dsc.h"
#include "../burp/misc_proto.h" #include "../burp/misc_proto.h"
#include "../jrd/gds_proto.h" #include "../jrd/gds_proto.h"
#include "../jrd/thd.h" #include "../jrd/ThreadData.h"
#include "../common/UtilSvc.h"
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
@ -109,7 +110,8 @@ enum rec_type {
rec_chk_constraint, // Check constraints rec_chk_constraint, // Check constraints
rec_charset, // Character sets rec_charset, // Character sets
rec_collation, // Collations rec_collation, // Collations
rec_sql_roles // SQL roles rec_sql_roles, // SQL roles
rec_mapping // Mapping of security names
}; };
@ -474,6 +476,8 @@ enum att_type {
att_procedureprm_collation_id, att_procedureprm_collation_id,
att_procedureprm_null_flag, att_procedureprm_null_flag,
att_procedureprm_mechanism, att_procedureprm_mechanism,
att_procedureprm_field_name,
att_procedureprm_relation_name,
// Exception attributes // Exception attributes
@ -528,7 +532,12 @@ enum att_type {
att_coll_description, att_coll_description,
att_coll_funct, att_coll_funct,
att_coll_base_collation_name, att_coll_base_collation_name,
att_coll_specific_attr att_coll_specific_attr,
// Names mapping
att_map_os = SERIES,
att_map_user,
att_map_role
}; };
@ -731,16 +740,20 @@ enum SIZE_CODE {
size_e // error size_e // error
}; };
struct burp_fil { class burp_fil
{
public:
burp_fil* fil_next; burp_fil* fil_next;
TEXT* fil_name; Firebird::PathName fil_name;
ULONG fil_length; ULONG fil_length;
DESC fil_fd; DESC fil_fd;
USHORT fil_seq; USHORT fil_seq;
SIZE_CODE fil_size_code; SIZE_CODE fil_size_code;
};
const size_t FIL_LEN = sizeof(burp_fil); burp_fil(Firebird::MemoryPool& p)
: fil_next(0), fil_name(p), fil_length(0),
fil_fd(INVALID_HANDLE_VALUE), fil_seq(0), fil_size_code(size_n) { }
};
/* Split & Join stuff */ /* Split & Join stuff */
@ -792,15 +805,12 @@ static const char HDR_SPLIT_TAG6[] = "InterBase/gbak, ";
const unsigned int MIN_SPLIT_SIZE = 2048; // bytes const unsigned int MIN_SPLIT_SIZE = 2048; // bytes
// Global switches and data // Global switches and data
#ifndef SERVICE_THREAD
class BurpGlobals;
extern BurpGlobals* gdgbl;
#endif
class BurpGlobals : public ThreadData class BurpGlobals : public ThreadData
{ {
public: public:
BurpGlobals() : ThreadData(ThreadData::tddGBL), flag_on_line(true) BurpGlobals(Firebird::UtilSvc* us)
: ThreadData(ThreadData::tddGBL), flag_on_line(true), uSvc(us), firstMap(true)
{ {
// this is VERY dirty hack to keep current behaviour // this is VERY dirty hack to keep current behaviour
memset (&gbl_database_file_name, 0, memset (&gbl_database_file_name, 0,
@ -828,8 +838,6 @@ public:
USHORT gbl_sw_blk_factor; USHORT gbl_sw_blk_factor;
bool gbl_sw_no_reserve; bool gbl_sw_no_reserve;
bool gbl_sw_old_descriptions; bool gbl_sw_old_descriptions;
bool gbl_sw_service_gbak;
bool gbl_sw_service_thd;
bool gbl_sw_convert_ext_tables; bool gbl_sw_convert_ext_tables;
bool gbl_sw_mode; bool gbl_sw_mode;
bool gbl_sw_mode_val; bool gbl_sw_mode_val;
@ -837,9 +845,7 @@ public:
const SCHAR* gbl_sw_sql_role; const SCHAR* gbl_sw_sql_role;
const SCHAR* gbl_sw_user; const SCHAR* gbl_sw_user;
const SCHAR* gbl_sw_password; const SCHAR* gbl_sw_password;
#ifdef TRUSTED_SERVICES
const SCHAR* gbl_sw_tr_user; const SCHAR* gbl_sw_tr_user;
#endif
SLONG gbl_sw_skip_count; SLONG gbl_sw_skip_count;
SLONG gbl_sw_page_buffers; SLONG gbl_sw_page_buffers;
burp_fil* gbl_sw_files; burp_fil* gbl_sw_files;
@ -877,10 +883,8 @@ public:
ISC_STATUS_ARRAY status_vector; ISC_STATUS_ARRAY status_vector;
int exit_code; int exit_code;
UCHAR* head_of_mem_list; UCHAR* head_of_mem_list;
Jrd::pfn_svc_output output_proc;
Jrd::Service* output_data;
FILE* output_file; FILE* output_file;
Jrd::Service* service_blk;
/* /*
* Link list of global fields that were converted from V3 sub_type * Link list of global fields that were converted from V3 sub_type
* to V4 char_set_id/collate_id. Needed for local fields conversion. * to V4 char_set_id/collate_id. Needed for local fields conversion.
@ -917,6 +921,7 @@ public:
isc_req_handle handles_get_relation_req_handle1; isc_req_handle handles_get_relation_req_handle1;
isc_req_handle handles_get_security_class_req_handle1; isc_req_handle handles_get_security_class_req_handle1;
isc_req_handle handles_get_sql_roles_req_handle1; isc_req_handle handles_get_sql_roles_req_handle1;
isc_req_handle handles_get_mapping_req_handle1;
isc_req_handle handles_get_trigger_message_req_handle1; isc_req_handle handles_get_trigger_message_req_handle1;
isc_req_handle handles_get_trigger_message_req_handle2; isc_req_handle handles_get_trigger_message_req_handle2;
isc_req_handle handles_get_trigger_old_req_handle1; isc_req_handle handles_get_trigger_old_req_handle1;
@ -941,7 +946,6 @@ public:
USHORT hdr_forced_writes; USHORT hdr_forced_writes;
TEXT database_security_class[GDS_NAME_LEN]; // To save database security class for deferred update TEXT database_security_class[GDS_NAME_LEN]; // To save database security class for deferred update
#ifdef SERVICE_THREAD
static inline BurpGlobals* getSpecific() { static inline BurpGlobals* getSpecific() {
return (BurpGlobals*) ThreadData::getSpecific(); return (BurpGlobals*) ThreadData::getSpecific();
} }
@ -951,21 +955,13 @@ public:
static inline void restoreSpecific() { static inline void restoreSpecific() {
ThreadData::restoreSpecific(); ThreadData::restoreSpecific();
} }
#else
static inline BurpGlobals* getSpecific() {
return gdgbl;
}
static inline void putSpecific(BurpGlobals* tdgbl) {
gdgbl = tdgbl;
}
static inline void restoreSpecific() {
}
#endif
char veryEnd; char veryEnd;
//starting after this members must be initialized in constructor explicitly //starting after this members must be initialized in constructor explicitly
bool flag_on_line; // indicates whether we will bring the database on-line bool flag_on_line; // indicates whether we will bring the database on-line
Firebird::UtilSvc* uSvc;
bool firstMap; // this is the first time we entered get_mapping()
}; };
// CVC: This aux routine declared here to not force inclusion of burp.h with burp_proto.h // CVC: This aux routine declared here to not force inclusion of burp.h with burp_proto.h
@ -1009,9 +1005,6 @@ inline static ULONG BURP_UP_TO_BLOCK(const ULONG size)
#ifdef WIN_NT #ifdef WIN_NT
static const ULONG MODE_READ = GENERIC_READ; static const ULONG MODE_READ = GENERIC_READ;
static const ULONG MODE_WRITE = GENERIC_WRITE; static const ULONG MODE_WRITE = GENERIC_WRITE;
#elif defined(VMS)
static const ULONG MODE_READ = O_RDONLY;
static const ULONG MODE_WRITE = O_WRONLY | O_CREAT | O_TRUNC;
#else #else
static const ULONG MODE_READ = O_RDONLY; static const ULONG MODE_READ = O_RDONLY;
static const ULONG MODE_WRITE = O_WRONLY | O_CREAT; static const ULONG MODE_WRITE = O_WRONLY | O_CREAT;

48
src/burp/burpMain.cpp Normal file
View File

@ -0,0 +1,48 @@
/*
* PROGRAM: Firebird utilities
* MODULE: burpMain.cpp
* DESCRIPTION: Proxy for real gbak main function
*
* 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 Alex Peshkov
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2007 Alex Peshkov <peshkoff at mail dot ru>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
*
*/
#include "firebird.h"
#include "../burp/burp_proto.h"
#include "../common/classes/auto.h"
int CLIB_ROUTINE main( int argc, char* argv[])
{
/**************************************
*
* m a i n
*
**************************************
*
* Functional description
* Invoke real gbak main function
*
**************************************/
Firebird::AutoPtr<Firebird::UtilSvc> uSvc(Firebird::UtilSvc::createStandalone(argc, argv));
return gbak(uSvc);
}

View File

@ -24,12 +24,12 @@
#ifndef BURP_BURP_PROTO_H #ifndef BURP_BURP_PROTO_H
#define BURP_BURP_PROTO_H #define BURP_BURP_PROTO_H
#include "../jrd/thd.h" #include "../jrd/ThreadData.h"
#include "../common/classes/MsgPrint.h" #include "../common/classes/MsgPrint.h"
#include "../common/UtilSvc.h"
#ifdef SERVICE_THREAD
THREAD_ENTRY_DECLARE BURP_main(THREAD_ENTRY_PARAM); THREAD_ENTRY_DECLARE BURP_main(THREAD_ENTRY_PARAM);
#endif int gbak(Firebird::UtilSvc*);
void BURP_abort(void); void BURP_abort(void);
void BURP_error(USHORT, bool, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg()); void BURP_error(USHORT, bool, const MsgFormat::SafeArg& arg = MsgFormat::SafeArg());

View File

@ -28,6 +28,7 @@
#define BURP_BURPSWI_H #define BURP_BURPSWI_H
#include "../jrd/common.h" #include "../jrd/common.h"
#include "../jrd/constants.h"
#include "../jrd/ibase.h" #include "../jrd/ibase.h"
/* Local copies of global variables. They will be copied into /* Local copies of global variables. They will be copied into
@ -84,9 +85,8 @@ const int IN_SW_BURP_NOD = 39; // do not run database triggers
#ifdef TRUSTED_AUTH #ifdef TRUSTED_AUTH
const int IN_SW_BURP_TRUSTED_USER = 40; // force trusted auth const int IN_SW_BURP_TRUSTED_USER = 40; // force trusted auth
#endif #endif
#ifdef TRUSTED_SERVICES
const int IN_SW_BURP_TRUSTED_SVC = 41; // trusted user name to use on attach const int IN_SW_BURP_TRUSTED_SVC = 41; // trusted user name to use on attach
#endif const int IN_SW_BURP_TRUSTED_ROLE = 42; // use trusted role on attach
/**************************************************************************/ /**************************************************************************/
// used 0BCDEFGILMNOPRSTUVYZ available AHJQWX // used 0BCDEFGILMNOPRSTUVYZ available AHJQWX
@ -156,9 +156,8 @@ static in_sw_tab_t burp_in_sw_table [] =
{IN_SW_BURP_TRUSTED_USER, 0, "TRUSTED", 0, 0, 0, FALSE, 295, 0, NULL}, {IN_SW_BURP_TRUSTED_USER, 0, "TRUSTED", 0, 0, 0, FALSE, 295, 0, NULL},
// msg 295: @1TRU(STED) use trusted authentication // msg 295: @1TRU(STED) use trusted authentication
#endif #endif
#ifdef TRUSTED_SERVICES {IN_SW_BURP_TRUSTED_SVC, 0, TRUSTED_USER_SWITCH, 0, 0, 0, FALSE, 0, 0, NULL},
{IN_SW_BURP_TRUSTED_SVC, 0, "TRUSTED_SVC", 0, 0, 0, FALSE, 0, 0, NULL}, {IN_SW_BURP_TRUSTED_ROLE, 0, TRUSTED_ROLE_SWITCH, 0, 0, 0, FALSE, 0, 0, NULL},
#endif
/* /*
{IN_SW_BURP_U, 0, "UNPROTECTED", 0, 0, 0, FALSE, 0, 0, NULL}, {IN_SW_BURP_U, 0, "UNPROTECTED", 0, 0, 0, FALSE, 0, 0, NULL},
*/ */

View File

@ -405,7 +405,7 @@ static bool_t burp_putlong(XDR* xdrs, const SLONG* lp)
**************************************/ **************************************/
SLONG l = htonl(*lp); SLONG l = htonl(*lp);
return (*xdrs->x_ops->x_putbytes) (xdrs, return (*xdrs->x_ops->x_putbytes) (xdrs,
reinterpret_cast<char*>(AOF32L(l)), reinterpret_cast<char*>(&l),
4); 4);
} }

View File

@ -31,10 +31,6 @@
#include "../burp/burp_proto.h" #include "../burp/burp_proto.h"
#include "../burp/misc_proto.h" #include "../burp/misc_proto.h"
#ifdef SERVICE_THREAD
#include "../jrd/thd.h"
#endif
UCHAR *MISC_alloc_burp(ULONG size) UCHAR *MISC_alloc_burp(ULONG size)
{ {

View File

@ -45,13 +45,8 @@
#include "../jrd/gds_proto.h" #include "../jrd/gds_proto.h"
#include "../jrd/gdsassert.h" #include "../jrd/gdsassert.h"
#include "../jrd/thd.h" #include "../jrd/thd.h"
#ifndef VMS
#include <fcntl.h> #include <fcntl.h>
#include <sys/types.h> #include <sys/types.h>
#else
#include <types.h>
#include <file.h>
#endif
#if (defined WIN_NT) #if (defined WIN_NT)
#include <io.h> // isatty #include <io.h> // isatty
@ -68,10 +63,6 @@ using MsgFormat::SafeArg;
const int open_mask = 0666; const int open_mask = 0666;
#ifdef VMS
const char* TERM_INPUT = "sys$input";
const char* TERM_OUTPUT = "sys$error";
#else
#ifdef WIN_NT #ifdef WIN_NT
const char* TERM_INPUT = "CONIN$"; const char* TERM_INPUT = "CONIN$";
const char* TERM_OUTPUT = "CONOUT$"; const char* TERM_OUTPUT = "CONOUT$";
@ -79,7 +70,6 @@ const char* TERM_OUTPUT = "CONOUT$";
const char* TERM_INPUT = "/dev/tty"; const char* TERM_INPUT = "/dev/tty";
const char* TERM_OUTPUT = "/dev/tty"; const char* TERM_OUTPUT = "/dev/tty";
#endif #endif
#endif
const int MAX_HEADER_SIZE = 512; const int MAX_HEADER_SIZE = 512;
@ -263,7 +253,7 @@ void MVOL_init_write(const char* database_name, // unused?
{ {
if (tdgbl->action->act_action == ACT_backup_split) if (tdgbl->action->act_action == ACT_backup_split)
{ {
BURP_error(269, true, tdgbl->action->act_file->fil_name); BURP_error(269, true, tdgbl->action->act_file->fil_name.c_str());
// msg 269 can't write a header record to file %s // msg 269 can't write a header record to file %s
} }
tdgbl->file_desc = next_volume(tdgbl->file_desc, MODE_WRITE, false); tdgbl->file_desc = next_volume(tdgbl->file_desc, MODE_WRITE, false);
@ -297,28 +287,25 @@ int MVOL_read(int* cnt, UCHAR** ptr)
break; break;
} }
if (!tdgbl->mvol_io_cnt || errno == EIO)
{ {
if (!tdgbl->mvol_io_cnt || errno == EIO) tdgbl->file_desc = next_volume(tdgbl->file_desc, MODE_READ, false);
if (tdgbl->mvol_io_cnt > 0)
{ {
tdgbl->file_desc = next_volume(tdgbl->file_desc, MODE_READ, false); break;
if (tdgbl->mvol_io_cnt > 0)
{
break;
}
} }
}
else if (!SYSCALL_INTERRUPTED(errno)) else if (!SYSCALL_INTERRUPTED(errno))
{
if (cnt)
{ {
if (cnt) BURP_error_redirect(0, 220);
{
BURP_error_redirect(0, 220);
// msg 220 Unexpected I/O error while reading from backup file // msg 220 Unexpected I/O error while reading from backup file
} }
else else
{ {
BURP_error_redirect(0, 50); BURP_error_redirect(0, 50);
// msg 50 unexpected end of file on backup file // msg 50 unexpected end of file on backup file
}
} }
} }
} }
@ -352,23 +339,21 @@ int MVOL_read(int* cnt, UCHAR** ptr)
tdgbl->mvol_io_ptr = tdgbl->mvol_io_buffer; tdgbl->mvol_io_ptr = tdgbl->mvol_io_buffer;
if (tdgbl->mvol_io_cnt > 0) if (tdgbl->mvol_io_cnt > 0)
break; break;
else
if (!tdgbl->mvol_io_cnt)
{ {
if (!tdgbl->mvol_io_cnt) tdgbl->file_desc = next_volume(tdgbl->file_desc, MODE_READ, false);
{ if (tdgbl->mvol_io_cnt > 0)
tdgbl->file_desc = next_volume(tdgbl->file_desc, MODE_READ, false); break;
if (tdgbl->mvol_io_cnt > 0) }
break; else if (GetLastError() != ERROR_HANDLE_EOF)
} {
else if (GetLastError() != ERROR_HANDLE_EOF) if (cnt)
{ BURP_error_redirect(NULL, 220);
if (cnt)
BURP_error_redirect(NULL, 220);
// msg 220 Unexpected I/O error while reading from backup file // msg 220 Unexpected I/O error while reading from backup file
else else
BURP_error_redirect(NULL, 50); BURP_error_redirect(NULL, 50);
// msg 50 unexpected end of file on backup file // msg 50 unexpected end of file on backup file
}
} }
} }
@ -388,7 +373,7 @@ int MVOL_read(int* cnt, UCHAR** ptr)
// Read a chunk of data from the IO buffer. // Read a chunk of data from the IO buffer.
// Return a pointer to the first position NOT read into. // Return a pointer to the first position NOT read into.
// //
UCHAR* MVOL_read_block(BurpGlobals* tdgbl, UCHAR * ptr, ULONG count) UCHAR* MVOL_read_block(BurpGlobals* tdgbl, UCHAR* ptr, ULONG count)
{ {
// To handle tape drives & Multi-volume boundaries, use the normal // To handle tape drives & Multi-volume boundaries, use the normal
// read function, instead of doing a more optimal bulk read. // read function, instead of doing a more optimal bulk read.
@ -405,7 +390,7 @@ UCHAR* MVOL_read_block(BurpGlobals* tdgbl, UCHAR * ptr, ULONG count)
count--; count--;
} }
ULONG n = MIN(count, (ULONG) tdgbl->io_cnt); const ULONG n = MIN(count, (ULONG) tdgbl->io_cnt);
// Copy data from the IO buffer // Copy data from the IO buffer
@ -445,7 +430,7 @@ void MVOL_skip_block( BurpGlobals* tdgbl, ULONG count)
count--; count--;
} }
ULONG n = MIN(count, (ULONG) tdgbl->io_cnt); const ULONG n = MIN(count, (ULONG) tdgbl->io_cnt);
// Skip ahead in current buffer // Skip ahead in current buffer
@ -462,7 +447,7 @@ void MVOL_skip_block( BurpGlobals* tdgbl, ULONG count)
// detect if it's a tape, rewind if so // detect if it's a tape, rewind if so
// and set the buffer size // and set the buffer size
// //
DESC MVOL_open(const char * name, ULONG mode, ULONG create) DESC MVOL_open(const char* name, ULONG mode, ULONG create)
{ {
HANDLE handle; HANDLE handle;
TAPE_GET_MEDIA_PARAMETERS param; TAPE_GET_MEDIA_PARAMETERS param;
@ -526,18 +511,17 @@ DESC MVOL_open(const char * name, ULONG mode, ULONG create)
// //
// Write a buffer's worth of data. // Write a buffer's worth of data.
// //
UCHAR MVOL_write(UCHAR c, int *io_cnt, UCHAR ** io_ptr) UCHAR MVOL_write(const UCHAR c, int* io_cnt, UCHAR** io_ptr)
{ {
UCHAR *ptr; const UCHAR* ptr;
SLONG left, cnt; SLONG cnt = 0;
BurpGlobals* tdgbl = BurpGlobals::getSpecific(); BurpGlobals* tdgbl = BurpGlobals::getSpecific();
ULONG size_to_write = BURP_UP_TO_BLOCK(*io_ptr - tdgbl->mvol_io_buffer); const ULONG size_to_write = BURP_UP_TO_BLOCK(*io_ptr - tdgbl->mvol_io_buffer);
ULONG left = size_to_write;
for (ptr = tdgbl->mvol_io_buffer, left = size_to_write; for (ptr = tdgbl->mvol_io_buffer; left > 0; ptr += cnt, left -= cnt)
left > 0;
ptr += cnt, left -= cnt)
{ {
if (tdgbl->action->act_action == ACT_backup_split) if (tdgbl->action->act_action == ACT_backup_split)
{ {
@ -579,7 +563,7 @@ UCHAR MVOL_write(UCHAR c, int *io_cnt, UCHAR ** io_ptr)
DWORD err = 0; DWORD err = 0;
// Assumes DWORD <==> ULONG // Assumes DWORD <==> ULONG
if (!WriteFile(tdgbl->file_desc, ptr, nBytesToWrite, if (!WriteFile(tdgbl->file_desc, ptr, nBytesToWrite,
reinterpret_cast <DWORD *>(&cnt), NULL)) reinterpret_cast<DWORD*>(&cnt), NULL))
{ {
err = GetLastError(); err = GetLastError();
} }
@ -624,9 +608,9 @@ UCHAR MVOL_write(UCHAR c, int *io_cnt, UCHAR ** io_ptr)
tdgbl->action->act_file->fil_fd = INVALID_HANDLE_VALUE; tdgbl->action->act_file->fil_fd = INVALID_HANDLE_VALUE;
BURP_print(272, SafeArg() << BURP_print(272, SafeArg() <<
tdgbl->action->act_file->fil_name << tdgbl->action->act_file->fil_name.c_str() <<
tdgbl->action->act_file->fil_length << tdgbl->action->act_file->fil_length <<
tdgbl->action->act_file->fil_next->fil_name); tdgbl->action->act_file->fil_next->fil_name.c_str());
// msg 272 Warning -- free disk space exhausted for file %s, // msg 272 Warning -- free disk space exhausted for file %s,
// the rest of the bytes (%d) will be written to file %s // the rest of the bytes (%d) will be written to file %s
tdgbl->action->act_file->fil_next->fil_length += tdgbl->action->act_file->fil_next->fil_length +=
@ -644,7 +628,7 @@ UCHAR MVOL_write(UCHAR c, int *io_cnt, UCHAR ** io_ptr)
continue; continue;
} }
if (tdgbl->gbl_sw_service_gbak) if (tdgbl->uSvc->isService())
{ {
BURP_error(270, true); BURP_error(270, true);
// msg 270 free disk space exhausted // msg 270 free disk space exhausted
@ -711,9 +695,9 @@ UCHAR MVOL_write(UCHAR c, int *io_cnt, UCHAR ** io_ptr)
tdgbl->mvol_io_buffer_size = tdgbl->mvol_actual_buffer_size; tdgbl->mvol_io_buffer_size = tdgbl->mvol_actual_buffer_size;
ptr = tdgbl->mvol_io_buffer + left; UCHAR* newptr = tdgbl->mvol_io_buffer + left;
*ptr++ = c; *newptr++ = c;
*io_ptr = ptr; *io_ptr = newptr;
*io_cnt = tdgbl->mvol_io_buffer_size - 1 - left; *io_cnt = tdgbl->mvol_io_buffer_size - 1 - left;
return c; return c;
@ -725,7 +709,7 @@ UCHAR MVOL_write(UCHAR c, int *io_cnt, UCHAR ** io_ptr)
// Write a chunk of data to the IO buffer. // Write a chunk of data to the IO buffer.
// Return a pointer to the first position NOT written from. // Return a pointer to the first position NOT written from.
// //
const UCHAR *MVOL_write_block(BurpGlobals* tdgbl, const UCHAR * ptr, ULONG count) const UCHAR* MVOL_write_block(BurpGlobals* tdgbl, const UCHAR* ptr, ULONG count)
{ {
// To handle tape drives & Multi-volume boundaries, use the normal // To handle tape drives & Multi-volume boundaries, use the normal
// write function, instead of doing a more optimal bulk write. // write function, instead of doing a more optimal bulk write.
@ -741,7 +725,7 @@ const UCHAR *MVOL_write_block(BurpGlobals* tdgbl, const UCHAR * ptr, ULONG count
count--; count--;
} }
ULONG n = MIN(count, (ULONG) tdgbl->io_cnt); const ULONG n = MIN(count, (ULONG) tdgbl->io_cnt);
// Copy data to the IO buffer // Copy data to the IO buffer
@ -964,15 +948,15 @@ static void prompt_for_name(SCHAR* name, int length)
// Unless we are operating as a service, stdin can't necessarily be trusted. // Unless we are operating as a service, stdin can't necessarily be trusted.
// Get a location to read from. // Get a location to read from.
fb_assert(!tdgbl->uSvc->isService());
if (tdgbl->gbl_sw_service_gbak || if (isatty(fileno(stdout)) ||
isatty(fileno(stdout)) ||
!(term_out = fopen(TERM_OUTPUT, "w"))) !(term_out = fopen(TERM_OUTPUT, "w")))
{ {
term_out = stdout; term_out = stdout;
} }
if (tdgbl->gbl_sw_service_gbak ||
isatty(fileno(stdin)) || if (isatty(fileno(stdin)) ||
!(term_in = fopen(TERM_INPUT, "r"))) !(term_in = fopen(TERM_INPUT, "r")))
{ {
term_in = stdin; term_in = stdin;
@ -1003,10 +987,6 @@ static void prompt_for_name(SCHAR* name, int length)
BURP_msg_get(228, msg); // " Name: " BURP_msg_get(228, msg); // " Name: "
fprintf(term_out, msg); fprintf(term_out, msg);
if (tdgbl->gbl_sw_service_gbak)
{
putc('\001', term_out);
}
fflush(term_out); fflush(term_out);
if (fgets(name, length, term_in) == NULL) if (fgets(name, length, term_in) == NULL)
{ {
@ -1361,7 +1341,7 @@ bool MVOL_split_hdr_write(void)
sprintf(buffer, "%s%.24s , file No. %4d of %4d, %-27.27s", sprintf(buffer, "%s%.24s , file No. %4d of %4d, %-27.27s",
HDR_SPLIT_TAG, ctime(&seconds), tdgbl->action->act_file->fil_seq, HDR_SPLIT_TAG, ctime(&seconds), tdgbl->action->act_file->fil_seq,
tdgbl->action->act_total, tdgbl->action->act_file->fil_name); tdgbl->action->act_total, tdgbl->action->act_file->fil_name.c_str());
#ifdef WIN_NT #ifdef WIN_NT
DWORD bytes_written = 0; DWORD bytes_written = 0;
@ -1419,4 +1399,3 @@ bool MVOL_split_hdr_read(void)
return false; return false;
} }

View File

@ -37,7 +37,7 @@ bool MVOL_split_hdr_read();
int MVOL_read(int*, UCHAR**); int MVOL_read(int*, UCHAR**);
UCHAR* MVOL_read_block(BurpGlobals*, UCHAR*, ULONG); UCHAR* MVOL_read_block(BurpGlobals*, UCHAR*, ULONG);
void MVOL_skip_block(BurpGlobals*, ULONG); void MVOL_skip_block(BurpGlobals*, ULONG);
UCHAR MVOL_write(UCHAR, int*, UCHAR**); UCHAR MVOL_write(const UCHAR, int*, UCHAR**);
const UCHAR* MVOL_write_block(BurpGlobals*, const UCHAR*, ULONG); const UCHAR* MVOL_write_block(BurpGlobals*, const UCHAR*, ULONG);
#if defined WIN_NT #if defined WIN_NT

View File

@ -77,10 +77,11 @@ const int DB_VERSION_DDL4 = 40; // ods4 db
const int DB_VERSION_DDL5 = 50; // ods5 db const int DB_VERSION_DDL5 = 50; // ods5 db
const int DB_VERSION_DDL8 = 80; // ods8 db const int DB_VERSION_DDL8 = 80; // ods8 db
const int DB_VERSION_CURRENT = DB_VERSION_DDL8; // IB4.0 is ods8 const int DB_VERSION_CURRENT = DB_VERSION_DDL8; // IB4.0 is ods8
const int DB_VERSION_DDL9 = 90; // ods9 db, IB5 const int DB_VERSION_DDL9 = 90; // ods9 db, IB5
const int DB_VERSION_DDL10 = 100; // ods10 db, IB6, FB1, FB1.5 const int DB_VERSION_DDL10 = 100; // ods10 db, IB6, FB1, FB1.5
const int DB_VERSION_DDL11 = 110; // ods11 db, FB2 const int DB_VERSION_DDL11 = 110; // ods11 db, FB2
const int DB_VERSION_DDL11_1 = 111; // ods11.1 db, FB2.1 const int DB_VERSION_DDL11_1 = 111; // ods11.1 db, FB2.1
const int DB_VERSION_DDL11_2 = 112; // ods11.2 db, FB2.5
const int DEFERRED_ACTIVE = 3; /* RDB$INDEX_INACTIVE setting for Foreign Keys const int DEFERRED_ACTIVE = 3; /* RDB$INDEX_INACTIVE setting for Foreign Keys
* This setting is used temporarily while * This setting is used temporarily while
@ -141,6 +142,7 @@ bool get_rel_constraint(BurpGlobals* tdgbl);
bool get_relation(BurpGlobals* tdgbl); bool get_relation(BurpGlobals* tdgbl);
bool get_relation_data(BurpGlobals* tdgbl); bool get_relation_data(BurpGlobals* tdgbl);
bool get_sql_roles(BurpGlobals* tdgbl); bool get_sql_roles(BurpGlobals* tdgbl);
bool get_mapping(BurpGlobals* tdgbl);
bool get_security_class(BurpGlobals* tdgbl); bool get_security_class(BurpGlobals* tdgbl);
void get_source_blob(BurpGlobals* tdgbl, ISC_QUAD&, bool); void get_source_blob(BurpGlobals* tdgbl, ISC_QUAD&, bool);
USHORT get_text (BurpGlobals* tdgbl, TEXT*, ULONG); USHORT get_text (BurpGlobals* tdgbl, TEXT*, ULONG);
@ -603,7 +605,7 @@ int RESTORE_restore (const TEXT* file_name,
if (tdgbl->gbl_sw_password) if (tdgbl->gbl_sw_password)
{ {
dpb.insertString(tdgbl->gbl_sw_service_gbak ? dpb.insertString(tdgbl->uSvc->isService() ?
isc_dpb_password_enc : isc_dpb_password, isc_dpb_password_enc : isc_dpb_password,
tdgbl->gbl_sw_password, tdgbl->gbl_sw_password,
strlen(tdgbl->gbl_sw_password)); strlen(tdgbl->gbl_sw_password));
@ -648,7 +650,7 @@ int RESTORE_restore (const TEXT* file_name,
} }
if (tdgbl->gbl_sw_password) if (tdgbl->gbl_sw_password)
{ {
dpb.insertString(tdgbl->gbl_sw_service_gbak ? dpb.insertString(tdgbl->uSvc->isService() ?
isc_dpb_password_enc : isc_dpb_password, isc_dpb_password_enc : isc_dpb_password,
tdgbl->gbl_sw_password, tdgbl->gbl_sw_password,
strlen(tdgbl->gbl_sw_password)); strlen(tdgbl->gbl_sw_password));
@ -698,19 +700,19 @@ void add_files(BurpGlobals* tdgbl,
for (burp_fil* file = tdgbl->gbl_sw_files; file; file = file->fil_next) for (burp_fil* file = tdgbl->gbl_sw_files; file; file = file->fil_next)
{ {
if (strcmp (file->fil_name, file_name)) if (file->fil_name != file_name)
{ {
count++; count++;
STORE (REQUEST_HANDLE req_handle1) STORE (REQUEST_HANDLE req_handle1)
X IN RDB$FILES X IN RDB$FILES
strcpy (X.RDB$FILE_NAME, file->fil_name); strcpy (X.RDB$FILE_NAME, file->fil_name.c_str());
X.RDB$FILE_START = start; X.RDB$FILE_START = start;
END_STORE; END_STORE;
ON_ERROR ON_ERROR
general_on_error (); general_on_error ();
END_ERROR; END_ERROR;
MISC_release_request_silent(req_handle1); MISC_release_request_silent(req_handle1);
BURP_verbose (57, SafeArg() << file->fil_name << start); BURP_verbose (57, SafeArg() << file->fil_name.c_str() << start);
// msg 57 adding file %s, starting at page %ld // msg 57 adding file %s, starting at page %ld
} }
else if (((SLONG) file->fil_length) >= start - 1) else if (((SLONG) file->fil_length) >= start - 1)
@ -846,9 +848,10 @@ void check_db_version(BurpGlobals* tdgbl)
const rel_field_t rel_fields[] = const rel_field_t rel_fields[] =
{ {
{"RDB$FIELDS", "RDB$FIELD_PRECISION", DB_VERSION_DDL10}, // FB1, FB1.5 {"RDB$FIELDS", "RDB$FIELD_PRECISION", DB_VERSION_DDL10}, // FB1, FB1.5
{"RDB$ROLES", "RDB$DESCRIPTION", DB_VERSION_DDL11}, // FB2 {"RDB$ROLES", "RDB$DESCRIPTION", DB_VERSION_DDL11}, // FB2
{"RDB$RELATIONS", "RDB$RELATION_TYPE", DB_VERSION_DDL11_1}, // FB2.1 {"RDB$RELATIONS", "RDB$RELATION_TYPE", DB_VERSION_DDL11_1}, // FB2.1
{"RDB$PROCEDURE_PARAMETERS", "RDB$FIELD_NAME", DB_VERSION_DDL11_2}, // FB2.5
{0, 0, 0} {0, 0, 0}
}; };
@ -1002,7 +1005,7 @@ void create_database(BurpGlobals* tdgbl,
} }
if (tdgbl->gbl_sw_password) if (tdgbl->gbl_sw_password)
{ {
dpb.insertString(tdgbl->gbl_sw_service_gbak ? dpb.insertString(tdgbl->uSvc->isService() ?
isc_dpb_password_enc : isc_dpb_password, isc_dpb_password_enc : isc_dpb_password,
tdgbl->gbl_sw_password, tdgbl->gbl_sw_password,
strlen(tdgbl->gbl_sw_password)); strlen(tdgbl->gbl_sw_password));
@ -5012,6 +5015,16 @@ bool get_procedure_prm (BurpGlobals* tdgbl, GDS_NAME procptr)
bad_attribute (scan_next_attr, attribute, 291); bad_attribute (scan_next_attr, attribute, 291);
break; break;
// DB_VERSION_DDL11_2
case att_procedureprm_field_name:
GET_TEXT(X.RDB$FIELD_NAME);
break;
// DB_VERSION_DDL11_2
case att_procedureprm_relation_name:
GET_TEXT(X.RDB$RELATION_NAME);
break;
default: default:
bad_attribute (scan_next_attr, attribute, 291); bad_attribute (scan_next_attr, attribute, 291);
// msg 291 procedure parameter // msg 291 procedure parameter
@ -5755,6 +5768,84 @@ bool get_sql_roles(BurpGlobals* tdgbl)
return true; return true;
} }
bool get_mapping(BurpGlobals* tdgbl)
{
/**************************************
*
* g e t _ m a p p i n g
*
**************************************
*
* Functional description
* Restore mapping to users and roles
* Restricted version - only single
* mapping is accepted
*
**************************************/
ATT_TYPE attribute;
scan_attr_t scan_next_attr;
TEXT temp[GDS_NAME_LEN];
SSHORT l;
Firebird::string role, os;
if (tdgbl->RESTORE_ods >= DB_VERSION_DDL11_1)
{
skip_init(&scan_next_attr);
while (skip_scan(&scan_next_attr), get_attribute(&attribute, tdgbl) != att_end)
{
switch (attribute)
{
case att_map_role:
l = GET_TEXT(temp);
role.assign(temp, l);
break;
case att_map_os:
l = GET_TEXT(temp);
os.assign(temp, l);
break;
default:
// msg 299 name mapping
bad_attribute (scan_next_attr, attribute, 299);
break;
}
}
if (tdgbl->RESTORE_ods < DB_VERSION_DDL11_2)
{
return true; // silently skip attributes on old server
}
if (os != DOMAIN_ADMINS || role != ADMIN_ROLE)
{
BURP_error(300, false);
return true;
}
if (tdgbl->firstMap)
{
tdgbl->firstMap = false;
BURP_verbose(301);
//msg 301, restoring names mapping
}
BURP_verbose(298, ADMIN_ROLE);
//msg 298, restoring map @1
Firebird::string sql;
sql.printf("%s ('%s',%d) %s",
"UPDATE OR INSERT INTO RDB$ROLES(RDB$ROLE_NAME, RDB$SYSTEM_FLAG) VALUES",
ADMIN_ROLE, ROLE_FLAG_MAY_TRUST | ROLE_FLAG_DBO,
"MATCHING (RDB$ROLE_NAME)");
isc_dsql_execute_immediate(tdgbl->status, &tdgbl->db_handle, &tdgbl->tr_handle,
sql.length(), sql.c_str(), 1, NULL);
if (tdgbl->status[1])
{
general_on_error ();
}
}
return true;
}
bool is_ascii_name (const TEXT *name, const SSHORT len) bool is_ascii_name (const TEXT *name, const SSHORT len)
{ {
/************************************** /**************************************
@ -7369,6 +7460,12 @@ bool restore(BurpGlobals* tdgbl,
flag = true; flag = true;
break; break;
case rec_mapping:
if (!get_mapping(tdgbl))
return false;
flag = true;
break;
default: default:
BURP_error(43, true, SafeArg() << record); BURP_error(43, true, SafeArg() << record);
// msg 43 don't recognize record type %ld // msg 43 don't recognize record type %ld

109
src/common/UtilSvc.cpp Normal file
View File

@ -0,0 +1,109 @@
/*
* PROGRAM: Firebird utilities interface
* MODULE: UtilSvc.cpp
* DESCRIPTION: Interface making it possible to use same code
* as both utility or service
*
* 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 Alex Peshkov
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2007 Alex Peshkov <peshkoff at mail dot ru>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
*
*/
#include "firebird.h"
#include "../common/UtilSvc.h"
#include "../common/classes/alloc.h"
#include "iberror.h"
#include <string.h>
#include <stdarg.h>
namespace Firebird {
class StandaloneUtilityInterface : public UtilSvc
{
public:
StandaloneUtilityInterface(Firebird::MemoryPool& p, int ac, char** av)
: UtilSvc(p)
{
while (ac--)
{
argv.push(*av++);
}
}
virtual void printf(const SCHAR* format, ...)
{
va_list arglist;
va_start(arglist, format);
int rc = ::vprintf(format, arglist);
va_end(arglist);
if (rc < 0)
{
Firebird::system_call_failed::raise(
"StandaloneUtilityInterface::printf()/vprintf()");
}
}
virtual void hidePasswd(ArgvType& argv, int pos)
{
const size_t l = strlen(argv[pos]);
char* data = FB_NEW(getPool()) char[l + 1];
memcpy(data, argv[pos], l);
data[l] = 0;
// here const-correctness is violated to make the rest 99.9%
// places of code much more clear
char* hide = const_cast<char*>(argv[pos]);
argv[pos] = data;
memset(hide, '*', l);
}
virtual bool isService()
{
return false;
}
virtual void checkService()
{
Firebird::status_exception::raise(isc_utl_trusted_switch, 0);
}
// do nothing for non-service
virtual void finish() { }
virtual void started() { }
virtual void putLine(char, const char*) { }
virtual void putSLong(char, SLONG) { }
virtual void putChar(char, char) { }
virtual void stuffStatus(const ISC_STATUS*) { }
virtual void stuffStatus(const USHORT, const USHORT, const MsgFormat::SafeArg&) { }
virtual ISC_STATUS* getStatus() { return 0; }
};
UtilSvc* UtilSvc::createStandalone(int ac, char** av)
{
return FB_NEW(*getDefaultMemoryPool())
StandaloneUtilityInterface(*getDefaultMemoryPool(), ac, av);
}
} // namespace Firebird

81
src/common/UtilSvc.h Normal file
View File

@ -0,0 +1,81 @@
/*
* PROGRAM: Firebird utilities interface
* MODULE: UtilSvc.h
* DESCRIPTION: Interface making it possible to use same code
* as both utility or service
*
* 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 Alex Peshkov
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2007 Alex Peshkov <peshkoff at mail dot ru>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
*
*/
#ifndef FB_UTILFACE
#define FB_UTILFACE
#include "../common/classes/alloc.h"
#include "../common/classes/array.h"
namespace MsgFormat {
class SafeArg;
}
namespace Firebird {
class UtilSvc : public PermanentStorage
{
public:
typedef Firebird::HalfStaticArray<const char*, 20> ArgvType;
public:
explicit UtilSvc(Firebird::MemoryPool& p) : PermanentStorage(p), argv(getPool()) { }
void output(const char* text)
{
printf("%s", text);
}
virtual void printf(const SCHAR* format, ...) = 0;
virtual bool isService() = 0;
virtual void started() = 0;
virtual void finish() = 0;
virtual void putLine(char, const char*) = 0;
virtual void putSLong(char, SLONG) = 0;
virtual void putChar(char, char) = 0;
virtual void stuffStatus(const ISC_STATUS*) = 0;
virtual void stuffStatus(const USHORT, const USHORT, const MsgFormat::SafeArg&) = 0;
virtual void hidePasswd(ArgvType&, int) = 0;
virtual ISC_STATUS* getStatus() = 0;
virtual void checkService() = 0;
virtual ~UtilSvc() { }
static UtilSvc* createStandalone(int ac, char** argv);
public:
ArgvType argv;
};
} // namespace Firebird
#endif // FB_UTILFACE

View File

@ -25,6 +25,7 @@
// ===================================== // =====================================
// Utility functions // Utility functions
#include "firebird.h"
#include "../jrd/common.h" #include "../jrd/common.h"
#ifdef HAVE_SYS_TYPES_H #ifdef HAVE_SYS_TYPES_H
@ -285,6 +286,8 @@ int snprintf(char* buffer, size_t count, const char* format...)
// Copy password to newly allocated place and replace existing one in argv with spaces. // Copy password to newly allocated place and replace existing one in argv with spaces.
// Allocated space is released upon exit from utility. // Allocated space is released upon exit from utility.
// This is planned leak of a few bytes of memory in utilities. // This is planned leak of a few bytes of memory in utilities.
// This function is deprecated. Use UtilSvc::hidePasswd(ArgvType&, int) whenever possible.
// However, there are several usages through fb_utils::get_passwd(char* arg);
char* cleanup_passwd(char* arg) char* cleanup_passwd(char* arg)
{ {
if (! arg) if (! arg)
@ -292,7 +295,7 @@ char* cleanup_passwd(char* arg)
return arg; return arg;
} }
int lpass = strlen(arg); const int lpass = strlen(arg);
char* savePass = (char*) gds__alloc(lpass + 1); char* savePass = (char*) gds__alloc(lpass + 1);
if (! savePass) if (! savePass)
{ {

View File

@ -48,21 +48,13 @@ namespace fb_utils
bool readenv(const char* env_name, Firebird::PathName& env_value); bool readenv(const char* env_name, Firebird::PathName& env_value);
int snprintf(char* buffer, size_t count, const char* format...); int snprintf(char* buffer, size_t count, const char* format...);
char* cleanup_passwd(char* arg); char* cleanup_passwd(char* arg);
#ifdef SERVICE_THREAD
inline const char* get_passwd(const char* arg)
{
return arg;
}
typedef const char* arg_string;
#else
inline char* get_passwd(char* arg) inline char* get_passwd(char* arg)
{ {
return cleanup_passwd(arg); return cleanup_passwd(arg);
} }
typedef char* arg_string; typedef char* arg_string;
#endif
// Warning: Only wrappers: // Warning: Only wrappers:
// ******************** // ********************
// s t r i c m p // s t r i c m p