int main(int argc, char** argv) { if (argc != 2) { printf("Usage: %s <new db name>\n", argv[0]); return -1; } ISC_STATUS_ARRAY sv; isc_db_handle db = 0; isc_tr_handle tr = 0; isc_create_database(sv, 0, argv[1], &db, 0, 0, 0); if (sv[0] == 1 && sv[1] > 0) { isc_print_status(sv); return -2; } isc_start_transaction(sv, &tr, 1, &db, 0, 0); if (sv[0] == 1 && sv[1] > 0) { isc_print_status(sv); return -3; } isc_commit_transaction(sv, &tr); if (sv[0] == 1 && sv[1] > 0) { isc_print_status(sv); return -3; } isc_detach_database(sv, &db); if (sv[0] == 1 && sv[1] > 0) { isc_print_status(sv); return -3; } Firebird::ClumpletWriter dpb(Firebird::ClumpletReader::Tagged, MAX_DPB_SIZE, isc_dpb_version1); dpb.insertByte(isc_dpb_set_db_readonly, TRUE); isc_attach_database(sv, 0, argv[1], &db, dpb.getBufferLength(), reinterpret_cast<const char*>(dpb.getBuffer())); if (sv[0] == 1 && sv[1] > 0) { isc_print_status(sv); return -4; } isc_detach_database(sv, &db); if (sv[0] == 1 && sv[1] > 0) { isc_print_status(sv); return -5; } return 0; }
/** * This method provides the close method for the Connection class. * * @param self A reference to the object that the call is being made on. * * @return A reference to the closed Connection on success, nil otherwise or * if the method is called on a closed Connection. * */ static VALUE closeConnection(VALUE self) { VALUE result = Qnil; ConnectionHandle *connection = NULL; Data_Get_Struct(self, ConnectionHandle, connection); if(connection->handle != 0) { VALUE transactions = rb_iv_get(self, "@transactions"), transaction = Qnil; ISC_STATUS status[ISC_STATUS_LENGTH]; /* Roll back an outstanding transactions. */ while((transaction = rb_ary_pop(transactions)) != Qnil) { VALUE active = rb_funcall(transaction, rb_intern("active?"), 0); if(active == Qtrue) { rb_funcall(transaction, rb_intern("rollback"), 0); } } /* Detach from the database. */ if(isc_detach_database(status, &connection->handle) == 0) { connection->handle = 0; result = self; } else { /* Generate an error. */ rb_fireruby_raise(status, "Error closing connection."); } } return(result); }
/* ** Closes a connection. ** Lua Returns: ** 1 if close was sucsessful, 0 if already closed ** nil and error message otherwise. */ static int conn_close (lua_State *L) { conn_data *conn = (conn_data *)luaL_checkudata(L,1,LUASQL_CONNECTION_FIREBIRD); luaL_argcheck (L, conn != NULL, 1, "connection expected"); /* already closed */ if(conn->closed != 0) { lua_pushboolean(L, 0); return 1; } /* are all related cursors closed? */ if(conn->lock > 0) return luasql_faildirect(L, "there are still open cursors"); if(conn->autocommit != 0) isc_commit_transaction(conn->env->status_vector, &conn->transaction); else isc_rollback_transaction(conn->env->status_vector, &conn->transaction); if ( CHECK_DB_ERROR(conn->env->status_vector) ) return return_db_error(L, conn->env->status_vector); isc_detach_database(conn->env->status_vector, &conn->db); if ( CHECK_DB_ERROR(conn->env->status_vector) ) return return_db_error(L, conn->env->status_vector); conn->closed = 1; --conn->env->lock; /* check environment can be GC'd */ if(conn->env->lock == 0) lua_unregisterobj(L, conn->env); lua_pushboolean(L, 1); return 1; }
void connectionFree(void *connection) { if(connection != NULL) { ConnectionHandle *handle = (ConnectionHandle *)connection; if(handle->handle != 0) { ISC_STATUS status[20]; isc_detach_database(status, &handle->handle); } free(handle); } }
static int _sql_socket_destructor(rlm_sql_firebird_conn_t *conn) { int i; DEBUG2("rlm_sql_firebird: socket destructor called, closing socket"); fb_commit(conn); if (conn->dbh) { fb_free_statement(conn); isc_detach_database(conn->status, &(conn->dbh)); if (fb_error(conn)) { WDEBUG("rlm_sql_firebird: Got error " "when closing socket: %s", conn->error); } } #ifdef _PTHREAD_H pthread_mutex_destroy (&conn->mut); #endif for (i=0; i < conn->row_fcount; i++) { free(conn->row[i]); } free(conn->row); free(conn->row_sizes); fb_free_sqlda(conn->sqlda_out); free(conn->sqlda_out); free(conn->tpb); free(conn->dpb); return 0; }
int start_firebird(int s, char *ip, int port, unsigned char options, char *miscptr, FILE * fp) { char *empty = ""; char *login, *pass; char database[256]; char connection_string[1024]; isc_db_handle db; /* database handle */ ISC_STATUS_ARRAY status; /* status vector */ char *dpb = NULL; /* DB parameter buffer */ short dpb_length = 0; if (miscptr) strncpy(database, miscptr, sizeof(database)); else strncpy(database, DEFAULT_DB, sizeof(database)); if (strlen(login = hydra_get_next_login()) == 0) login = empty; if (strlen(pass = hydra_get_next_password()) == 0) pass = empty; dpb_length = (short) (1 + strlen(login) + 2 + strlen(pass) + 2); if ((dpb = (char *) malloc(dpb_length)) == NULL) { hydra_report(stderr, "[ERROR] Can't allocate memory\n"); return 1; } /* Add user and password to dpb */ *dpb = isc_dpb_version1; dpb_length = 1; isc_modify_dpb(&dpb, &dpb_length, isc_dpb_user_name, login, strlen(login)); isc_modify_dpb(&dpb, &dpb_length, isc_dpb_password, pass, strlen(pass)); /* Create connection string */ snprintf(connection_string, sizeof(connection_string), "%s:%s", hydra_address2string(ip), database); if (isc_attach_database(status, 0, connection_string, &db, dpb_length, dpb)) { /* for debugging perpose */ if (verbose) { hydra_report(stderr, "[VERBOSE] "); isc_print_status(status); } isc_free(dpb); hydra_completed_pair(); if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) return 2; } else { isc_detach_database(status, &db); isc_free(dpb); hydra_report_found_host(port, ip, "firebird", fp); hydra_completed_pair_found(); if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) return 3; return 2; } return 1; }
EXPORT RM_ENTRY(rmc_detach_database) { ClearParamPool(); ISC_STATUS *stat = AllocStatusPool(); isc_detach_database(stat, (isc_db_handle *)arg_vector[1].a_address); StatusToCobol(&arg_vector[0], stat); return (0); }
static void _php_ibase_close_link(zend_resource *rsrc) /* {{{ */ { ibase_db_link *link = (ibase_db_link *) rsrc->ptr; _php_ibase_commit_link(link); if (link->handle != 0) { IBDEBUG("Closing normal link..."); isc_detach_database(IB_STATUS, &link->handle); } IBG(num_links)--; efree(link); }
static void ibase_tidy(void) { ibase_connection *cn; ISC_STATUS status[20]; while ((cn = ibase_connections) != NULL) { ibase_connections = cn->next; DEBUG(D_lookup) debug_printf("close Interbase connection: %s\n", cn->server); isc_commit_transaction(status, &cn->transh); isc_detach_database(status, &cn->dbh); } }
/* ** GCs an connection object */ static int conn_gc (lua_State *L) { conn_data *conn = (conn_data *)luaL_checkudata(L,1,LUASQL_CONNECTION_FIREBIRD); if(conn->closed == 0) { if(conn->autocommit != 0) isc_commit_transaction(conn->env->status_vector, &conn->transaction); else isc_rollback_transaction(conn->env->status_vector, &conn->transaction); isc_detach_database(conn->env->status_vector, &conn->db); conn->closed = 1; --conn->env->lock; /* check environment can be GC'd */ if(conn->env->lock == 0) lua_unregisterobj(L, conn->env); } return 0; }
int main() { char dpb[ 48 ]; int i = 0, len; long status[ 20 ]; dpb[ i++ ] = isc_dpb_version1; dpb[ i++ ] = isc_dpb_user_name; len = strlen( USER ); dpb[ i++ ] = ( char ) len; strncpy( &( dpb[ i ] ), USER, len ); i += len; dpb[ i++ ] = isc_dpb_password; len = strlen( PASSWORD ); dpb[ i++ ] = len; strncpy( &( dpb[ i ] ), PASSWORD, len ); i += len; if( isc_attach_database( status, 0, DATABASE, &db, i, dpb ) ) ERREXIT( status, 1 ); execute( "DROP TABLE TESTE" ); execute( "CREATE TABLE TESTE (code smallint)" ); execute( "INSERT INTO TESTE (code) VALUES (100)" ); query( "SELECT * FROM TESTE" ); while( fetch() == 0 ) printf( "%s\n", getdata( 0 ) ); qclose(); if( isc_detach_database( status, &db ) ) ERREXIT( status, 1 ); return 1; }
/** * This function provides the create class method for Database class. * * @param usused Like it says, not used. * @param file A String containing the name of the primary file for the * database to be created. * @param user The database user that will be used in creating the new * database. * @param password A String containing the password for the user to be used * in creating the database. * @param size The size of pages that will be used by the database. * @param set A String containing the name of the character set to be * used in creating the database. * * @return A reference to a Database object on success, nil on failure. * */ static VALUE createDatabase(int argc, VALUE *argv, VALUE unused) { VALUE database = Qnil, set = Qnil, tmp_str = Qnil; char sql[512] = "", *text = NULL; int value = 1024; isc_db_handle connection = 0; isc_tr_handle transaction = 0; ISC_STATUS status[ISC_STATUS_LENGTH]; /* Check that sufficient parameters have been provided. */ if(argc < 3) { rb_raise(rb_eArgError, "Wrong number of parameters (%d for %d).", argc, 3); } /* Check values that are permitted restricted values. */ if(argc > 3) { value = FIX2INT(argv[3]); if(value != 1024 && value != 2048 && value != 4096 && value != 8192) { rb_raise(rb_eException, "Invalid database page size value . Valid values are 1024, " \ "2048 4096 or 8192."); } } /* Prepare the SQL statement. */ tmp_str = rb_funcall(argv[0], rb_intern("to_s"), 0); sprintf(sql, "CREATE DATABASE '%s'", StringValuePtr(tmp_str)); tmp_str = rb_funcall(argv[1], rb_intern("to_s"), 0); text = StringValuePtr(tmp_str); if(strlen(text) > 0) { strcat(sql, " USER '"); strcat(sql, text); strcat(sql, "'"); } tmp_str = rb_funcall(argv[2], rb_intern("to_s"), 0); text = StringValuePtr(tmp_str); if(strlen(text) > 0) { strcat(sql, " PASSWORD '"); strcat(sql, text); strcat(sql, "'"); } if(argc > 3) { char text[50]; sprintf(text, " PAGE_SIZE = %d", value); strcat(sql, text); } if(argc > 4 && argv[4] != Qnil) { char *text = NULL; set = rb_funcall(argv[4], rb_intern("to_s"), 0); text = StringValuePtr(set); if(strlen(text) > 0) { strcat(sql, " DEFAULT CHARACTER SET "); strcat(sql, text); } } strcat(sql, ";"); if(isc_dsql_execute_immediate(status, &connection, &transaction, 0, sql, 3, NULL) != 0) { rb_fireruby_raise(status, "Database creation error."); } if(connection != 0) { isc_detach_database(status, &connection); } database = rb_database_new(argv[0]); if(set != Qnil) { setDatabaseCharacterSet(database, set); } return(database); }
~connection() { isc_detach_database(service.status, &impl); }
int main(int argc, char * argv[]) { #if HAVE_PTHREAD_ATTR_GETSTACK pthread_attr_t attr; pthread_attr_init(&attr); void * stackaddr; size_t stacksize; pthread_attr_getstack(&attr, &stackaddr, &stacksize); printf("stackaddr = %p, stacksize = %u\n", stackaddr, stacksize); pthread_attr_destroy(&attr); #endif /* sigset_t signal_set; sigemptyset(&signal_set); sigaddset(&signal_set, SIGHUP); sigaddset(&signal_set, SIGUSR1); sigaddset(&signal_set, SIGUSR2); sigaddset(&signal_set, SIGTERM); sigaddset(&signal_set, SIGINT); sigaddset(&signal_set, SIGQUIT); pthread_sigmask(SIG_BLOCK, &signal_set, NULL);*/ void * fbclient = dlopen("libgds.so", 0); printf("fbclient = %p\n", fbclient); ISC_STATUS status[20]; union { ISC_STATUS ISC_EXPORT (* isc_dsql_execute_immediate)(ISC_STATUS *, isc_db_handle *, isc_tr_handle *, unsigned short, char *, unsigned short, XSQLDA *); void * p0; }; p0 = dlsym(fbclient, "isc_dsql_execute_immediate"); if( p0 != NULL ){ isc_db_handle dbHandle = NULL; isc_tr_handle trHandle = NULL; long r = isc_dsql_execute_immediate(status, &dbHandle, &trHandle, 0, "CREATE DATABASE 'localhost:/usr/local/firebird/MACROSCOPE.FDB' user 'sysdba' password 'masterkey'", 3, NULL); printf("isc_dsql_execute_immediate = %ld, dbHandle = %p, trHandle = %p\n", r, dbHandle, trHandle); union { ISC_STATUS ISC_EXPORT (* isc_detach_database)(ISC_STATUS * status, isc_db_handle * handle); void * p2; }; p2 = dlsym(fbclient, "isc_detach_database"); r = isc_detach_database(status, &dbHandle); printf("isc_detach_database = %ld, dbHandle = %p\n", r, dbHandle); union { ISC_STATUS ISC_EXPORT (* isc_attach_database)(ISC_STATUS * status, short dbNameLen, const char * dbName, isc_db_handle * handle, short dpbLen, const char * dpb); void * p1; }; p1 = dlsym(fbclient, "isc_attach_database"); printf("isc_attach_database = %p\n", p1); char dpb[] = { isc_dpb_version1, isc_dpb_user_name, 6, 'S', 'Y', 'S', 'D', 'B', 'A', isc_dpb_password, 9, 'm', 'a', 's', 't', 'e', 'r', 'k', 'e', 'y' }; r = isc_attach_database(status, 0, "localhost:/usr/local/firebird/MACROSCOPE.FDB", &dbHandle, sizeof(dpb), dpb); printf("isc_attach_database = %ld, dbHandle = %p\n", r, dbHandle); r = isc_detach_database(status, &dbHandle); printf("isc_detach_database = %ld, dbHandle = %p\n", r, dbHandle); } dlclose(fbclient); return 0; }
static int perform_ibase_search(uschar * query, uschar * server, uschar ** resultptr, uschar ** errmsg, BOOL * defer_break) { isc_stmt_handle stmth = NULL; XSQLDA *out_sqlda; XSQLVAR *var; char buffer[256]; ISC_STATUS status[20], *statusp = status; int i; int ssize = 0; int offset = 0; int yield = DEFER; uschar *result = NULL; ibase_connection *cn; uschar *server_copy = NULL; uschar *sdata[3]; /* Disaggregate the parameters from the server argument. The order is host, database, user, password. We can write to the string, since it is in a nextinlist temporary buffer. The copy of the string that is used for caching has the password removed. This copy is also used for debugging output. */ for (i = 2; i > 0; i--) { uschar *pp = Ustrrchr(server, '|'); if (pp == NULL) { *errmsg = string_sprintf("incomplete Interbase server data: %s", (i == 3) ? server : server_copy); *defer_break = TRUE; return DEFER; } *pp++ = 0; sdata[i] = pp; if (i == 2) server_copy = string_copy(server); /* sans password */ } sdata[0] = server; /* What's left at the start */ /* See if we have a cached connection to the server */ for (cn = ibase_connections; cn != NULL; cn = cn->next) { if (Ustrcmp(cn->server, server_copy) == 0) { break; } } /* Use a previously cached connection ? */ if (cn != NULL) { static char db_info_options[] = { isc_info_base_level }; /* test if the connection is alive */ if (isc_database_info (status, &cn->dbh, sizeof(db_info_options), db_info_options, sizeof(buffer), buffer)) { /* error occurred: assume connection is down */ DEBUG(D_lookup) debug_printf ("Interbase cleaning up cached connection: %s\n", cn->server); isc_detach_database(status, &cn->dbh); } else { DEBUG(D_lookup) debug_printf("Interbase using cached connection for %s\n", server_copy); } } else { cn = store_get(sizeof(ibase_connection)); cn->server = server_copy; cn->dbh = NULL; cn->transh = NULL; cn->next = ibase_connections; ibase_connections = cn; } /* If no cached connection, we must set one up. */ if (cn->dbh == NULL || cn->transh == NULL) { char *dpb, *p; short dpb_length; static char trans_options[] = { isc_tpb_version3, isc_tpb_read, isc_tpb_read_committed, isc_tpb_rec_version }; /* Construct the database parameter buffer. */ dpb = buffer; *dpb++ = isc_dpb_version1; *dpb++ = isc_dpb_user_name; *dpb++ = strlen(sdata[1]); for (p = sdata[1]; *p;) *dpb++ = *p++; *dpb++ = isc_dpb_password; *dpb++ = strlen(sdata[2]); for (p = sdata[2]; *p;) *dpb++ = *p++; dpb_length = dpb - buffer; DEBUG(D_lookup) debug_printf("new Interbase connection: database=%s user=%s\n", sdata[0], sdata[1]); /* Connect to the database */ if (isc_attach_database (status, 0, sdata[0], &cn->dbh, dpb_length, buffer)) { isc_interprete(buffer, &statusp); *errmsg = string_sprintf("Interbase attach() failed: %s", buffer); *defer_break = FALSE; goto IBASE_EXIT; } /* Now start a read-only read-committed transaction */ if (isc_start_transaction (status, &cn->transh, 1, &cn->dbh, sizeof(trans_options), trans_options)) { isc_interprete(buffer, &statusp); isc_detach_database(status, &cn->dbh); *errmsg = string_sprintf("Interbase start_transaction() failed: %s", buffer); *defer_break = FALSE; goto IBASE_EXIT; } } /* Run the query */ if (isc_dsql_allocate_statement(status, &cn->dbh, &stmth)) { isc_interprete(buffer, &statusp); *errmsg = string_sprintf("Interbase alloc_statement() failed: %s", buffer); *defer_break = FALSE; goto IBASE_EXIT; } out_sqlda = store_get(XSQLDA_LENGTH(1)); out_sqlda->version = SQLDA_VERSION1; out_sqlda->sqln = 1; if (isc_dsql_prepare (status, &cn->transh, &stmth, 0, query, 1, out_sqlda)) { isc_interprete(buffer, &statusp); store_reset(out_sqlda); out_sqlda = NULL; *errmsg = string_sprintf("Interbase prepare_statement() failed: %s", buffer); *defer_break = FALSE; goto IBASE_EXIT; } /* re-allocate the output structure if there's more than one field */ if (out_sqlda->sqln < out_sqlda->sqld) { XSQLDA *new_sqlda = store_get(XSQLDA_LENGTH(out_sqlda->sqld)); if (isc_dsql_describe (status, &stmth, out_sqlda->version, new_sqlda)) { isc_interprete(buffer, &statusp); isc_dsql_free_statement(status, &stmth, DSQL_drop); store_reset(out_sqlda); out_sqlda = NULL; *errmsg = string_sprintf("Interbase describe_statement() failed: %s", buffer); *defer_break = FALSE; goto IBASE_EXIT; } out_sqlda = new_sqlda; } /* allocate storage for every returned field */ for (i = 0, var = out_sqlda->sqlvar; i < out_sqlda->sqld; i++, var++) { switch (var->sqltype & ~1) { case SQL_VARYING: var->sqldata = (char *) store_get(sizeof(char) * var->sqllen + 2); break; case SQL_TEXT: var->sqldata = (char *) store_get(sizeof(char) * var->sqllen); break; case SQL_SHORT: var->sqldata = (char *) store_get(sizeof(short)); break; case SQL_LONG: var->sqldata = (char *) store_get(sizeof(ISC_LONG)); break; #ifdef SQL_INT64 case SQL_INT64: var->sqldata = (char *) store_get(sizeof(ISC_INT64)); break; #endif case SQL_FLOAT: var->sqldata = (char *) store_get(sizeof(float)); break; case SQL_DOUBLE: var->sqldata = (char *) store_get(sizeof(double)); break; #ifdef SQL_TIMESTAMP case SQL_DATE: var->sqldata = (char *) store_get(sizeof(ISC_QUAD)); break; #else case SQL_TIMESTAMP: var->sqldata = (char *) store_get(sizeof(ISC_TIMESTAMP)); break; case SQL_TYPE_DATE: var->sqldata = (char *) store_get(sizeof(ISC_DATE)); break; case SQL_TYPE_TIME: var->sqldata = (char *) store_get(sizeof(ISC_TIME)); break; #endif } if (var->sqltype & 1) { var->sqlind = (short *) store_get(sizeof(short)); } } /* finally, we're ready to execute the statement */ if (isc_dsql_execute (status, &cn->transh, &stmth, out_sqlda->version, NULL)) { isc_interprete(buffer, &statusp); *errmsg = string_sprintf("Interbase describe_statement() failed: %s", buffer); isc_dsql_free_statement(status, &stmth, DSQL_drop); *defer_break = FALSE; goto IBASE_EXIT; } while (isc_dsql_fetch(status, &stmth, out_sqlda->version, out_sqlda) != 100L) { /* check if an error occurred */ if (status[0] & status[1]) { isc_interprete(buffer, &statusp); *errmsg = string_sprintf("Interbase fetch() failed: %s", buffer); isc_dsql_free_statement(status, &stmth, DSQL_drop); *defer_break = FALSE; goto IBASE_EXIT; } if (result != NULL) result = string_catn(result, &ssize, &offset, US "\n", 1); /* Find the number of fields returned. If this is one, we don't add field names to the data. Otherwise we do. */ if (out_sqlda->sqld == 1) { if (out_sqlda->sqlvar[0].sqlind == NULL || *out_sqlda->sqlvar[0].sqlind != -1) /* NULL value yields nothing */ result = string_catn(result, &ssize, &offset, US buffer, fetch_field(buffer, sizeof(buffer), &out_sqlda->sqlvar[0])); } else for (i = 0; i < out_sqlda->sqld; i++) { int len = fetch_field(buffer, sizeof(buffer), &out_sqlda->sqlvar[i]); result = string_cat(result, &ssize, &offset, US out_sqlda->sqlvar[i].aliasname, out_sqlda->sqlvar[i].aliasname_length); result = string_catn(result, &ssize, &offset, US "=", 1); /* Quote the value if it contains spaces or is empty */ if (*out_sqlda->sqlvar[i].sqlind == -1) { /* NULL value */ result = string_catn(result, &ssize, &offset, US "\"\"", 2); } else if (buffer[0] == 0 || Ustrchr(buffer, ' ') != NULL) { int j; result = string_catn(result, &ssize, &offset, US "\"", 1); for (j = 0; j < len; j++) { if (buffer[j] == '\"' || buffer[j] == '\\') result = string_cat(result, &ssize, &offset, US "\\", 1); result = string_cat(result, &ssize, &offset, US buffer + j, 1); } result = string_catn(result, &ssize, &offset, US "\"", 1); } else { result = string_catn(result, &ssize, &offset, US buffer, len); } result = string_catn(result, &ssize, &offset, US " ", 1); } } /* If result is NULL then no data has been found and so we return FAIL. Otherwise, we must terminate the string which has been built; string_cat() always leaves enough room for a terminating zero. */ if (result == NULL) { yield = FAIL; *errmsg = US "Interbase: no data found"; } else { result[offset] = 0; store_reset(result + offset + 1); } /* Get here by goto from various error checks. */ IBASE_EXIT: if (stmth != NULL) isc_dsql_free_statement(status, &stmth, DSQL_drop); /* Non-NULL result indicates a successful result */ if (result != NULL) { *resultptr = result; return OK; } else { DEBUG(D_lookup) debug_printf("%s\n", *errmsg); return yield; /* FAIL or DEFER */ } }
int CLIB_ROUTINE main( int argc, char** argv) { /************************************** * * m a i n * ************************************** * * Functional description * Run the server with apollo mailboxes. * **************************************/ try { RemPortPtr port; // We should support 3 modes: // 1. Standalone single-process listener (like SS). // 2. Standalone listener, forking on each packet accepted (look -s switch in CS). // 3. Process spawned by (x)inetd (like CS). bool classic = false; bool standaloneClassic = false; bool super = false; // It's very easy to detect that we are spawned - just check fd 0 to be a socket. const int channel = 0; struct stat stat0; if (fstat(channel, &stat0) == 0 && S_ISSOCK(stat0.st_mode)) { // classic server mode classic = true; } const TEXT* const* const end = argc + argv; argv++; bool debug = false; USHORT INET_SERVER_flag = 0; protocol[0] = 0; bool done = false; while (argv < end) { TEXT c; const TEXT* p = *argv++; if (*p++ == '-') { while (c = *p++) { switch (UPPER(c)) { case 'D': debug = true; break; case 'E': if (argv < end) { if (ISC_set_prefix(p, *argv) == -1) printf("Invalid argument Ignored\n"); else argv++; // do not skip next argument if this one is invalid } else { printf("Missing argument, switch -E ignored\n"); } done = true; break; case 'P': if (argv < end) { if (!classic) { fb_utils::snprintf(protocol, sizeof(protocol), "/%s", *argv++); } else { gds__log("Switch -P ignored in CS mode\n"); } } else { printf("Missing argument, switch -P ignored\n"); } break; case 'H': case '?': printf("Firebird TCP/IP server options are:\n"); printf(" -d : debug on\n"); printf(" -p <port> : specify port to listen on\n"); printf(" -z : print version and exit\n"); printf(" -h|? : print this help\n"); printf("\n"); printf(" (The following -e options used to be -h options)\n"); printf(" -e <firebird_root_dir> : set firebird_root path\n"); printf(" -el <firebird_lock_dir> : set runtime firebird_lock dir\n"); printf(" -em <firebird_msg_dir> : set firebird_msg dir path\n"); exit(FINI_OK); case 'Z': printf("Firebird TCP/IP server version %s\n", FB_VERSION); exit(FINI_OK); default: printf("Unknown switch '%c', ignored\n", c); break; } if (done) break; } } } if (Config::getServerMode() == MODE_CLASSIC) { if (!classic) standaloneClassic = true; } else { if (classic) { gds__log("Server misconfigured - to start it from (x)inetd add ServerMode=Classic to firebird.conf"); Firebird::Syslog::Record(Firebird::Syslog::Error, "Server misconfigured - add ServerMode=Classic to firebird.conf"); exit(STARTUP_ERROR); } INET_SERVER_flag |= SRVR_multi_client; super = true; } { // scope Firebird::MasterInterfacePtr master; master->serverMode(super ? 1 : 0); } if (debug) { INET_SERVER_flag |= SRVR_debug; } // activate paths set with -e family of switches ISC_set_prefix(0, 0); // ignore some signals set_signal(SIGPIPE, signal_handler); set_signal(SIGUSR1, signal_handler); set_signal(SIGUSR2, signal_handler); // First of all change directory to tmp if (chdir(TEMP_DIR)) { // error on changing the directory gds__log("Could not change directory to %s due to errno %d", TEMP_DIR, errno); } #ifdef FB_RAISE_LIMITS #ifdef RLIMIT_NPROC raiseLimit(RLIMIT_NPROC); #endif #if !(defined(DEV_BUILD)) if (Config::getBugcheckAbort()) #endif { // try to force core files creation raiseLimit(RLIMIT_CORE); } #if (defined SOLARIS || defined HPUX || defined LINUX) if (super) { // Increase max open files to hard limit for Unix // platforms which are known to have low soft limits. raiseLimit(RLIMIT_NOFILE); } #endif // Unix platforms #endif // FB_RAISE_LIMITS #ifdef HAVE_LOCALE_H // Pick up the system locale to allow SYSTEM<->UTF8 conversions inside the engine setlocale(LC_CTYPE, ""); #endif if (!(debug || classic)) { int mask = 0; // FD_ZERO(&mask); mask |= 1 << 2; // FD_SET(2, &mask); divorce_terminal(mask); } // check firebird.conf presence - must be for server if (Config::missFirebirdConf()) { Firebird::Syslog::Record(Firebird::Syslog::Error, "Missing master config file firebird.conf"); exit(STARTUP_ERROR); } if (super || standaloneClassic) { try { port = INET_connect(protocol, 0, INET_SERVER_flag, 0, NULL); } catch (const Firebird::Exception& ex) { iscLogException("startup:INET_connect:", ex); Firebird::StaticStatusVector st; ex.stuffException(st); gds__print_status(st.begin()); exit(STARTUP_ERROR); } } if (classic) { port = INET_server(channel); if (!port) { gds__log("Unable to start INET_server"); Firebird::Syslog::Record(Firebird::Syslog::Error, "Unable to start INET_server"); exit(STARTUP_ERROR); } } { // scope for interface ptr Firebird::PluginManagerInterfacePtr pi; Auth::registerSrpServer(pi); } if (super) { // Server tries to attach to security2.fdb to make sure everything is OK // This code fixes bug# 8429 + all other bug of that kind - from // now on the server exits if it cannot attach to the database // (wrong or no license, not enough memory, etc. ISC_STATUS_ARRAY status; isc_db_handle db_handle = 0L; const Firebird::RefPtr<Config> defConf(Config::getDefaultConfig()); const char* path = defConf->getSecurityDatabase(); const char dpb[] = {isc_dpb_version1, isc_dpb_sec_attach, 1, 1, isc_dpb_address_path, 0}; isc_attach_database(status, strlen(path), path, &db_handle, sizeof dpb, dpb); if (status[0] == 1 && status[1] > 0) { logSecurityDatabaseError(path, status); } isc_detach_database(status, &db_handle); if (status[0] == 1 && status[1] > 0) { logSecurityDatabaseError(path, status); } } // end scope fb_shutdown_callback(NULL, closePort, fb_shut_exit, port); SRVR_multi_thread(port, INET_SERVER_flag); #ifdef DEBUG_GDS_ALLOC // In Debug mode - this will report all server-side memory leaks due to remote access Firebird::PathName name = fb_utils::getPrefix( Firebird::IConfigManager::DIR_LOG, "memdebug.log"); FILE* file = os_utils::fopen(name.c_str(), "w+t"); if (file) { fprintf(file, "Global memory pool allocated objects\n"); getDefaultMemoryPool()->print_contents(file); fclose(file); } #endif // perform atexit shutdown here when all globals in embedded library are active // also sync with possibly already running shutdown in dedicated thread fb_shutdown(10000, fb_shutrsn_exit_called); return FINI_OK; } catch (const Firebird::Exception& ex) { Firebird::StaticStatusVector st; ex.stuffException(st); char s[100]; const ISC_STATUS* status = st.begin(); fb_interpret(s, sizeof(s), &status); iscLogException("Firebird startup error:", ex); Firebird::Syslog::Record(Firebird::Syslog::Error, "Firebird startup error"); Firebird::Syslog::Record(Firebird::Syslog::Error, s); exit(STARTUP_ERROR); } }
ISC_STATUS API_ROUTINE gds__detach_database(ISC_STATUS * status_vector, FB_API_HANDLE* db_handle) { return isc_detach_database(status_vector, db_handle); }
int FB_EXPORTED server_main( int argc, char** argv) { /************************************** * * m a i n * ************************************** * * Functional description * Run the server with apollo mailboxes. * **************************************/ RemPortPtr port; // 01 Sept 2003, Nickolay Samofatov // In GCC version 3.1-3.3 we need to install special error handler // in order to get meaningful terminate() error message on stderr. // In GCC 3.4 or later this is the default. //#if __GNUC__ == 3 && __GNUC_MINOR__ >= 1 && __GNUC_MINOR__ < 4 // std::set_terminate (__gnu_cxx::__verbose_terminate_handler); //#endif const TEXT* const* const end = argc + argv; argv++; bool debug = false, standalone = false; INET_SERVER_flag = 0; int channel = 0; protocol[0] = 0; bool multi_client = false, multi_threaded = false; #ifdef SUPERSERVER INET_SERVER_flag |= SRVR_multi_client; multi_client = multi_threaded = standalone = true; #endif int clients = 0; bool done = false; while (argv < end) { TEXT c; const TEXT* p = *argv++; if (*p++ == '-') while (c = *p++) { switch (UPPER(c)) { case 'D': INET_SERVER_flag |= SRVR_debug; debug = true; break; #ifndef SUPERSERVER case 'M': INET_SERVER_flag |= SRVR_multi_client; if (argv < end) { if (clients = atoi(*argv)) argv++; } multi_client = standalone = true; break; case 'S': standalone = true; break; case 'I': standalone = false; break; case 'T': multi_threaded = true; break; case 'U': multi_threaded = false; break; #endif // SUPERSERVER case 'E': if (ISC_set_prefix(p, *argv) == -1) printf("Invalid argument Ignored\n"); else argv++; // do not skip next argument if this one is invalid done = true; break; case 'P': fb_utils::snprintf(protocol, sizeof(protocol), "/%s", *argv++); break; case 'H': case '?': printf("Firebird TCP/IP server options are:\n"); printf(" -d : debug on\n"); #ifndef SUPERSERVER // These options are not applicable to super server printf(" -m : multiclient - on\n"); printf(" -s : standalone - true\n"); printf(" -i : standalone - false\n"); printf(" -t : multithread - true (non pc only)\n"); printf(" -u : multithread - false (pc only)\n"); #endif printf(" -p<protocol> : specify protocol\n"); printf(" -h|? : print this help\n"); printf("\n"); printf(" (The following -e options used to be -h options)\n"); printf(" -e <firebird_root_dir> : set firebird_root path\n"); printf(" -el <firebird_lock_dir> : set runtime firebird_lock dir\n"); printf(" -em <firebird_msg_dir> : set firebird_msg dir path\n"); printf(" -z : print version\n"); exit(FINI_OK); case 'Z': printf("Firebird TCP/IP server version %s\n", GDS_VERSION); exit(FINI_OK); } if (done) break; } } // activate paths set with -e family of switches ISC_set_prefix(0, 0); #ifdef UNIX set_signal(SIGPIPE, signal_handler); set_signal(SIGUSR1, signal_handler); set_signal(SIGUSR2, signal_handler); #endif #if defined(UNIX) && defined(HAVE_SETRLIMIT) && defined(HAVE_GETRLIMIT) #ifdef RLIMIT_NPROC raiseLimit(RLIMIT_NPROC); #endif #if !(defined(DEV_BUILD)) if (Config::getBugcheckAbort()) #endif { // try to force core files creation raiseLimit(RLIMIT_CORE); // we need some writable directory for core file // on any unix /tmp seems to be the best place if (CHANGE_DIR(TEMP_DIR)) { // error on changing the directory gds__log("Could not change directory to %s due to errno %d", TEMP_DIR, errno); } } #if defined(SUPERSERVER) && (defined SOLARIS || defined HPUX || defined LINUX) // Increase max open files to hard limit for Unix // platforms which are known to have low soft limits. raiseLimit(RLIMIT_NOFILE); #endif #endif // Fork off a server, wait for it to die, then fork off another, // but give up after 100 tries #ifndef SUPERSERVER if (multi_client && !debug) { #ifdef UNIX set_signal(SIGUSR1, signal_handler); #endif int child; for (int n = 0; n < 100; n++) { INET_SERVER_start = 0; if (!(child = fork())) break; while (wait(0) != child) if (INET_SERVER_start) { n = 0; // reset error counter on "real" signal break; } gds__log("INET_SERVER/main: gds_inet_server restarted"); } #ifdef UNIX set_signal(SIGUSR1, SIG_DFL); #endif } #endif if (standalone) { if (multi_client) { #ifdef SUPERSERVER // Remove restriction on username, for DEV builds // restrict only for production builds. MOD 21-July-2002 #ifndef DEV_BUILD Firebird::string user_name; // holds the user name // check user id ISC_get_user(&user_name, NULL, NULL, NULL); if (user_name != "root" && user_name != FIREBIRD_USER_NAME && user_name != INTERBASE_USER_NAME && user_name != INTERBASE_USER_SHORT) { // invalid user -- bail out fprintf(stderr, "%s: Invalid user (must be %s, %s, %s or root).\n", "fbserver", FIREBIRD_USER_NAME, INTERBASE_USER_NAME, INTERBASE_USER_SHORT); exit(STARTUP_ERROR); } #endif #else if (setreuid(0, 0) < 0) printf("Inet_server: couldn't set uid to superuser.\n"); #endif INET_set_clients(clients); } if (!debug) { int mask = 0; // FD_ZERO(&mask); mask |= 1 << 2; // FD_SET(2, &mask); divorce_terminal(mask); } { // scope block ISC_STATUS_ARRAY status_vector; port = INET_connect(protocol, 0, status_vector, INET_SERVER_flag, 0); if (!port) { gds__print_status(status_vector); exit(STARTUP_ERROR); } } // end scope block } else { port = INET_server(channel); if (!port) { fprintf(stderr, "fbserver: Unable to start INET_server\n"); exit(STARTUP_ERROR); } } #ifdef SUPERSERVER // before starting the superserver stuff change directory to tmp if (CHANGE_DIR(TEMP_DIR)) { // error on changing the directory gds__log("Could not change directory to %s due to errno %d", TEMP_DIR, errno); } // Server tries to attach to security2.fdb to make sure everything is OK // This code fixes bug# 8429 + all other bug of that kind - from // now on the server exits if it cannot attach to the database // (wrong or no license, not enough memory, etc. { // scope TEXT path[MAXPATHLEN]; ISC_STATUS_ARRAY status; isc_db_handle db_handle = 0L; Jrd::SecurityDatabase::getPath(path); const char dpb[] = {isc_dpb_version1, isc_dpb_gsec_attach, 1, 1}; isc_attach_database(status, strlen(path), path, &db_handle, sizeof dpb, dpb); if (status[0] == 1 && status[1] > 0) { gds__log_status(path, status); isc_print_status(status); exit(STARTUP_ERROR); } isc_detach_database(status, &db_handle); if (status[0] == 1 && status[1] > 0) { gds__log_status(path, status); isc_print_status(status); exit(STARTUP_ERROR); } } // end scope shutdownInit(); #endif SRVR_multi_thread(port, INET_SERVER_flag); #ifdef DEBUG_GDS_ALLOC // In Debug mode - this will report all server-side memory leaks due to remote access //gds_alloc_report(0, __FILE__, __LINE__); Firebird::PathName name = fb_utils::getPrefix(fb_utils::FB_DIR_LOG, "memdebug.log"); FILE* file = fopen(name.c_str(), "w+t"); if (file) { fprintf(file, "Global memory pool allocated objects\n"); getDefaultMemoryPool()->print_contents(file); fclose(file); } #endif // perform atexit shutdown here when all globals in embedded library are active // also sync with possibly already running shutdown in dedicated thread fb_shutdown(10000, fb_shutrsn_exit_called); return FINI_OK; }