Esempio n. 1
0
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;
}
Esempio n. 2
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);
}
Esempio n. 3
0
/*
** 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;
}
Esempio n. 4
0
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;
}
Esempio n. 7
0
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);
}
Esempio n. 8
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);
}
Esempio n. 9
0
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);
    }
}
Esempio n. 10
0
/*
** 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;
}
Esempio n. 11
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;
}
Esempio n. 12
0
/**
 * 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);
}
Esempio n. 13
0
	~connection()
	{
		isc_detach_database(service.status, &impl);
	}
Esempio n. 14
0
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;
}
Esempio n. 15
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 */
    }
}
Esempio n. 16
0
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);
	}
}
Esempio n. 17
0
ISC_STATUS API_ROUTINE gds__detach_database(ISC_STATUS * status_vector,
											FB_API_HANDLE* db_handle)
{
	return isc_detach_database(status_vector, db_handle);
}
Esempio n. 18
0
    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;
    }