/*************************************************************************
 *
 *	Function: sql_create_socket
 *
 *	Purpose: Establish connection to the db
 *
 *************************************************************************/
static int sql_init_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config)
{
	LOGINREC *login;
	rlm_sql_freetds_sock *freetds_sock;
	
	if (!sqlsocket->conn) {
		sqlsocket->conn = (rlm_sql_freetds_sock *)rad_malloc(sizeof(struct rlm_sql_freetds_sock));
		if (!sqlsocket->conn) {
			return -1;
		}
	}
	
	if (dbinit() == FAIL) {
		radlog(L_ERR, "rlm_sql_freetds: Unable to init FreeTDS");
		return -1;		
	}
	
	dbsetversion(DBVERSION_80);
	dberrhandle(err_handler);
	
	// Timeout so that FreeTDS doesn't wait for ever.
	dbsetlogintime((unsigned long)config->query_timeout);
	dbsettime((unsigned long)config->query_timeout);
	
	freetds_sock = sqlsocket->conn;
	memset(freetds_sock, 0, sizeof(*freetds_sock));
	
	DEBUG("rlm_sql_freetds (%s): Starting connect to FreeTDS/MSSQL server", config->xlat_name);
	
	if (!(login = dblogin())) {
		radlog(L_ERR, "rlm_sql_freetds (%s): Unable to allocate login record", config->xlat_name);
		return -1;
	}
	
	DBSETLUSER(login, config->sql_login);
	DBSETLPWD(login, config->sql_password);
	
	if ((freetds_sock->dbproc = dbopen(login, config->sql_server)) == FAIL) {
		radlog(L_ERR, "rlm_sql_freetds (%s): Unable to connect to FreeTDS/MSSQL server %s@%s", 
			   config->xlat_name, config->sql_login, config->sql_server);
		dbloginfree(login);
		return -1;
	}
	
	dbloginfree(login);
	
	if ((dbuse(freetds_sock->dbproc, config->sql_db)) == FAIL) {
		radlog(L_ERR, "rlm_sql_freetds (%s): Unable to select database on FreeTDS/MSSQL server %s@%s:%s", 
			   config->xlat_name, config->sql_login, config->sql_server, config->sql_db);
		return -1;
	}
	
	/* I know this may look strange, but it sets a pointer to
	 the freetds_sock struct so that it can be used within the
	 query_timeout_handler function to be able to timeout properly */
	dbsetinterrupt(freetds_sock->dbproc, query_timeout_handler, query_timeout_handler);
	dbsetuserdata(freetds_sock->dbproc, (BYTE *)freetds_sock);
	
	return 0;
}
Exemple #2
0
static int dblib_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val)
{
	switch(attr) {
		case PDO_ATTR_TIMEOUT:
		case PDO_DBLIB_ATTR_QUERY_TIMEOUT:
			return SUCCEED == dbsettime(zval_get_long(val)) ? 1 : 0;
		case PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER:
			((pdo_dblib_db_handle *)dbh->driver_data)->stringify_uniqueidentifier = zval_get_long(val);
			return 1;
		default:
			return 0;
	}
}
Exemple #3
0
int
timeout_err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr)
{
	/*
	 * For server messages, cancel the query and rely on the
	 * message handler to spew the appropriate error messages out.
	 */
	if (dberr == SYBESMSG)
		return INT_CANCEL;
		
	if (dberr == SYBETIME) {
		fprintf(stderr, "%d timeouts received in %ld seconds, ", ++ntimeouts, (long int) (time(NULL) - start_time));
		if (ntimeouts > max_timeouts) {
			if (++ncancels > 1) {
				fprintf(stderr, "could not timeout cleanly, breaking connection\n");
				ncancels = 0;
				return INT_CANCEL;
			}
			fprintf(stderr, "lost patience, cancelling (allowing 10 seconds)\n");
			if (dbsettime(10) == FAIL) 
				fprintf(stderr, "... but dbsettime() failed in error handler\n");
			return INT_TIMEOUT;
		}
		fprintf(stderr, "continuing to wait\n");
		return INT_CONTINUE;
	}
	
	ntimeouts = 0; /* reset */

	fprintf(stderr,
		"DB-LIBRARY error (severity %d, dberr %d, oserr %d, dberrstr %s, oserrstr %s):\n",
		severity, dberr, oserr, dberrstr ? dberrstr : "(null)", oserrstr ? oserrstr : "(null)");
	fflush(stderr);

	/*
	 * If the dbprocess is dead or the dbproc is a NULL pointer and
	 * we are not in the middle of logging in, then we need to exit.
	 * We can't do anything from here on out anyway.
	 * It's OK to end up here in response to a dbconvert() that
	 * resulted in overflow, so don't exit in that case.
	 */
	if ((dbproc == NULL) || DBDEAD(dbproc)) {
		if (dberr != SYBECOFL) {
			fprintf(stderr, "error: dbproc (%p) is %s, goodbye\n", 
					dbproc, dbproc? (DBDEAD(dbproc)? "DEAD" : "OK") : "NULL");
			exit(255);
		}
	}

	return INT_CANCEL;
}
Exemple #4
0
static VALUE rb_tinytds_connect(VALUE self, VALUE opts) {
    /* Parsing options hash to local vars. */
    VALUE user, pass, dataserver, database, app, version, ltimeout, timeout, charset;
    user = rb_hash_aref(opts, sym_username);
    pass = rb_hash_aref(opts, sym_password);
    dataserver = rb_hash_aref(opts, sym_dataserver);
    database = rb_hash_aref(opts, sym_database);
    app = rb_hash_aref(opts, sym_appname);
    version = rb_hash_aref(opts, sym_tds_version);
    ltimeout = rb_hash_aref(opts, sym_login_timeout);
    timeout = rb_hash_aref(opts, sym_timeout);
    charset = rb_hash_aref(opts, sym_encoding);
    /* Dealing with options. */
    if (dbinit() == FAIL) {
        rb_raise(cTinyTdsError, "failed dbinit() function");
        return self;
    }
    dberrhandle(tinytds_err_handler);
    dbmsghandle(tinytds_msg_handler);
    GET_CLIENT_WRAPPER(self);
    cwrap->login = dblogin();
    if (!NIL_P(user))
        dbsetluser(cwrap->login, StringValuePtr(user));
    if (!NIL_P(pass))
        dbsetlpwd(cwrap->login, StringValuePtr(pass));
    if (!NIL_P(app))
        dbsetlapp(cwrap->login, StringValuePtr(app));
    if (!NIL_P(version))
        dbsetlversion(cwrap->login, NUM2INT(version));
    if (!NIL_P(ltimeout))
        dbsetlogintime(NUM2INT(ltimeout));
    if (!NIL_P(timeout))
        dbsettime(NUM2INT(timeout));
    if (!NIL_P(charset))
        DBSETLCHARSET(cwrap->login, StringValuePtr(charset));
    cwrap->client = dbopen(cwrap->login, StringValuePtr(dataserver));
    if (cwrap->client) {
        cwrap->closed = 0;
        cwrap->charset = charset;
        dbsetuserdata(cwrap->client, (BYTE*)cwrap->userdata);
        cwrap->userdata->closed = 0;
        if (!NIL_P(database))
            dbuse(cwrap->client, StringValuePtr(database));
#ifdef HAVE_RUBY_ENCODING_H
        VALUE transposed_encoding = rb_funcall(cTinyTdsClient, intern_transpose_iconv_encoding, 1, charset);
        cwrap->encoding = rb_enc_find(StringValuePtr(transposed_encoding));
#endif
    }
    return self;
}
Exemple #5
0
static int dblib_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val)
{
	pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data;

	switch(attr) {
		case PDO_ATTR_DEFAULT_STR_PARAM:
			H->assume_national_character_set_strings = zval_get_long(val) == PDO_PARAM_STR_NATL ? 1 : 0;
			return 1;
		case PDO_ATTR_TIMEOUT:
		case PDO_DBLIB_ATTR_QUERY_TIMEOUT:
			return SUCCEED == dbsettime(zval_get_long(val)) ? 1 : 0;
		case PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER:
			H->stringify_uniqueidentifier = zval_get_long(val);
			return 1;
		case PDO_DBLIB_ATTR_SKIP_EMPTY_ROWSETS:
			H->skip_empty_rowsets = zval_is_true(val);
			return 1;
		default:
			return 0;
	}
}
Exemple #6
0
static VALUE rb_tinytds_connect(VALUE self, VALUE opts) {
  /* Parsing options hash to local vars. */
  VALUE user, pass, dataserver, database, app, version, ltimeout, timeout, charset, azure;
  GET_CLIENT_WRAPPER(self);

  user = rb_hash_aref(opts, sym_username);
  pass = rb_hash_aref(opts, sym_password);
  dataserver = rb_hash_aref(opts, sym_dataserver);
  database = rb_hash_aref(opts, sym_database);
  app = rb_hash_aref(opts, sym_appname);
  version = rb_hash_aref(opts, sym_tds_version);
  ltimeout = rb_hash_aref(opts, sym_login_timeout);
  timeout = rb_hash_aref(opts, sym_timeout);
  charset = rb_hash_aref(opts, sym_encoding);
  azure = rb_hash_aref(opts, sym_azure);
  /* Dealing with options. */
  if (dbinit() == FAIL) {
    rb_raise(cTinyTdsError, "failed dbinit() function");
    return self;
  }
  dberrhandle(tinytds_err_handler);
  dbmsghandle(tinytds_msg_handler);
  cwrap->login = dblogin();
  if (!NIL_P(version))
    dbsetlversion(cwrap->login, NUM2INT(version));
  if (!NIL_P(user))
    dbsetluser(cwrap->login, StringValueCStr(user));
  if (!NIL_P(pass))
    dbsetlpwd(cwrap->login, StringValueCStr(pass));
  if (!NIL_P(app))
    dbsetlapp(cwrap->login, StringValueCStr(app));
  if (!NIL_P(ltimeout))
    dbsetlogintime(NUM2INT(ltimeout));
  if (!NIL_P(timeout))
    dbsettime(NUM2INT(timeout));
  if (!NIL_P(charset))
    DBSETLCHARSET(cwrap->login, StringValueCStr(charset));
  if (!NIL_P(database) && (azure == Qtrue)) {
    #ifdef DBSETLDBNAME
      DBSETLDBNAME(cwrap->login, StringValueCStr(database));
    #else
      rb_warn("TinyTds: Azure connections not supported in this version of FreeTDS.\n");
    #endif
  }
  cwrap->client = dbopen(cwrap->login, StringValueCStr(dataserver));
  if (cwrap->client) {
    VALUE transposed_encoding;

    cwrap->closed = 0;
    cwrap->charset = charset;
    if (!NIL_P(version))
      dbsetversion(NUM2INT(version));
    dbsetuserdata(cwrap->client, (BYTE*)cwrap->userdata);
    cwrap->userdata->closed = 0;
    if (!NIL_P(database) && (azure != Qtrue)) {
      dbuse(cwrap->client, StringValueCStr(database));
    }
    transposed_encoding = rb_funcall(cTinyTdsClient, intern_transpose_iconv_encoding, 1, charset);
    cwrap->encoding = rb_enc_find(StringValueCStr(transposed_encoding));
    if (dbtds(cwrap->client) <= 7) {
      cwrap->identity_insert_sql = "SELECT CAST(@@IDENTITY AS bigint) AS Ident";
    } else {
      cwrap->identity_insert_sql = "SELECT CAST(SCOPE_IDENTITY() AS bigint) AS Ident";
    }
  }
  return self;
}
Exemple #7
0
static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options)
{
	pdo_dblib_db_handle *H;
	int i, nvars, nvers, ret = 0;

	const pdo_dblib_keyval tdsver[] = {
		 {"4.2",DBVERSION_42}
		,{"4.6",DBVERSION_46}
		,{"5.0",DBVERSION_70} /* FIXME: This does not work with Sybase, but environ will */
		,{"6.0",DBVERSION_70}
		,{"7.0",DBVERSION_70}
#ifdef DBVERSION_71
		,{"7.1",DBVERSION_71}
#endif
#ifdef DBVERSION_72
		,{"7.2",DBVERSION_72}
		,{"8.0",DBVERSION_72}
#endif
#ifdef DBVERSION_73
		,{"7.3",DBVERSION_73}
#endif
#ifdef DBVERSION_74
		,{"7.4",DBVERSION_74}
#endif
		,{"10.0",DBVERSION_100}
		,{"auto",0} /* Only works with FreeTDS. Other drivers will bork */

	};
	
	struct pdo_data_src_parser vars[] = {
		{ "charset",	NULL,	0 }
		,{ "appname",	"PHP " PDO_DBLIB_FLAVOUR,	0 }
		,{ "host",		"127.0.0.1", 0 }
		,{ "dbname",	NULL,	0 }
		,{ "secure",	NULL,	0 } /* DBSETLSECURE */
		,{ "version",	NULL,	0 } /* DBSETLVERSION */
	};

	nvars = sizeof(vars)/sizeof(vars[0]);
	nvers = sizeof(tdsver)/sizeof(tdsver[0]);
	
	php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, nvars);

	H = pecalloc(1, sizeof(*H), dbh->is_persistent);
	H->login = dblogin();
	H->err.sqlstate = dbh->error_code;
	H->stringify_uniqueidentifier = 0;

	if (!H->login) {
		goto cleanup;
	}

	if (driver_options) {
		int connect_timeout = pdo_attr_lval(driver_options, PDO_DBLIB_ATTR_CONNECTION_TIMEOUT, -1);
		int query_timeout = pdo_attr_lval(driver_options, PDO_DBLIB_ATTR_QUERY_TIMEOUT, -1);
		int timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, 30);

		if (connect_timeout == -1) {
			connect_timeout = timeout;
		}
		if (query_timeout == -1) {
			query_timeout = timeout;
		}

		dbsetlogintime(connect_timeout); /* Connection/Login Timeout */
		dbsettime(query_timeout); /* Statement Timeout */

		H->stringify_uniqueidentifier = pdo_attr_lval(driver_options, PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER, 0);
	}

	DBERRHANDLE(H->login, (EHANDLEFUNC) pdo_dblib_error_handler);
	DBMSGHANDLE(H->login, (MHANDLEFUNC) pdo_dblib_msg_handler);

	if(vars[5].optval) {
		for(i=0;i<nvers;i++) {
			if(strcmp(vars[5].optval,tdsver[i].key) == 0) {
				if(FAIL==dbsetlversion(H->login, tdsver[i].value)) {
					pdo_raise_impl_error(dbh, NULL, "HY000", "PDO_DBLIB: Failed to set version specified in connection string.");
					goto cleanup;
				}
				break;
			}
		}

		if (i==nvers) {
			printf("Invalid version '%s'\n", vars[5].optval);
			pdo_raise_impl_error(dbh, NULL, "HY000", "PDO_DBLIB: Invalid version specified in connection string.");
			goto cleanup; /* unknown version specified */
		}
	}

	if (dbh->username) {
		if(FAIL == DBSETLUSER(H->login, dbh->username)) {
			goto cleanup;
		}
	}

	if (dbh->password) {
		if(FAIL == DBSETLPWD(H->login, dbh->password)) {
			goto cleanup;
		}
	}

#if !PHP_DBLIB_IS_MSSQL
	if (vars[0].optval) {
		DBSETLCHARSET(H->login, vars[0].optval);
	}
#endif

	DBSETLAPP(H->login, vars[1].optval);

/* DBSETLDBNAME is only available in FreeTDS 0.92 or above */
#ifdef DBSETLDBNAME
	if (vars[3].optval) {
		if(FAIL == DBSETLDBNAME(H->login, vars[3].optval)) goto cleanup;
	}
#endif

	H->link = dbopen(H->login, vars[2].optval);

	if (!H->link) {
		goto cleanup;
	}

/*
 * FreeTDS < 0.92 does not support the DBSETLDBNAME option
 * Send use database here after login (Will not work with SQL Azure)
 */
#ifndef DBSETLDBNAME
	if (vars[3].optval) {
		if(FAIL == dbuse(H->link, vars[3].optval)) goto cleanup;
	}
#endif

#if PHP_DBLIB_IS_MSSQL
	/* dblib do not return more than this length from text/image */
	DBSETOPT(H->link, DBTEXTLIMIT, "2147483647");
#endif

	/* limit text/image from network */
	DBSETOPT(H->link, DBTEXTSIZE, "2147483647");

	/* allow double quoted indentifiers */
	DBSETOPT(H->link, DBQUOTEDIDENT, "1");

	ret = 1;
	dbh->max_escaped_char_length = 2;
	dbh->alloc_own_columns = 1;

cleanup:
	for (i = 0; i < nvars; i++) {
		if (vars[i].freeme) {
			efree(vars[i].optval);
		}
	}

	dbh->methods = &dblib_methods;
	dbh->driver_data = H;

	if (!ret) {
		zend_throw_exception_ex(php_pdo_get_exception(), DBLIB_G(err).dberr,
			"SQLSTATE[%s] %s (severity %d)",
			DBLIB_G(err).sqlstate,
			DBLIB_G(err).dberrstr,
			DBLIB_G(err).severity);
	}

	return ret;
}
Exemple #8
0
static int
test(int close_socket)
{
	LOGINREC *login;
	DBPROCESS *dbproc;
	RETCODE ret;
	int expected_error = -1;

	printf("Starting %s\n", UNITTEST);

	dbinit();

	dberrhandle(syb_err_handler);
	dbmsghandle(syb_msg_handler);

	printf("About to logon\n");

	login = dblogin();
	DBSETLPWD(login, PASSWORD);
	DBSETLUSER(login, USER);
	DBSETLAPP(login, "t0020");

	printf("About to open\n");

	dbproc = dbopen(login, SERVER);
	dbsetuserdata(dbproc, (BYTE*) &expected_error);
	if (strlen(DATABASE))
		dbuse(dbproc, DATABASE);
	dbloginfree(login);

	dbcmd(dbproc, "select * from sysobjects");
	printf("dbsqlexec should not hang.\n");

	ret = dbsettime(15);
	if (ret != SUCCEED) {
		fprintf(stderr, "Failed.  Error setting timeout.\n");
		return 1;
	}

	if (!shutdown_socket(dbproc)) {
		fprintf(stderr, "Error shutting down connection\n");
		return 1;
	}
	if (close_socket)
		close(end_socket);

	alarm(20);
	expected_error = close_socket ? 20006 : 20003;
	ret = dbsqlexec(dbproc);
	alarm(0);
	if (ret != FAIL) {
		fprintf(stderr, "Failed.  Expected FAIL to be returned.\n");
		return 1;
	}

	dbsetuserdata(dbproc, NULL);
	if (!close_socket)
		close(end_socket);
	dbexit();

	printf("dblib okay on %s\n", __FILE__);
	return 0;
}
Exemple #9
0
int
main(int argc, char *argv[])
{
	int echo = 0;

#ifdef notyet
	int print_statistics = 0;
#endif
	int fipsflagger = 0;
	int perfstats = 0;
	int no_prompt = 0;
	int use_encryption = 0;
	int chained_transactions = 0;
	const char *cmdend = "go";
	int headers = 0;
	char *columnwidth = NULL;
	const char *colseparator = " ";
	const char *lineseparator = "\n";
	int timeout = 0;
	char *username = NULL;
	char *password = NULL;
	char *server = NULL;
	DBCHAR *char_set = NULL;
	const char *editor;
	char *hostname = NULL;
	char *sqlch;
	char *interfaces_filename = NULL;
	char *input_filename = NULL;
	char *output_filename = NULL;
	int logintime = -1;
	char *language = NULL;
	int size = 0;
	char *sybenv;
	DBPROCESS *dbproc;
	LOGINREC *login;
	char **ibuf = NULL;
	int ibuflines = 0;
	int printedlines;
	int i;
	char *line;
	int dbrc;
	char foobuf[512];
	char *firstword;
	char *cp;
	int c;
	int errflg = 0;
	char *prbuf;
	int prbuflen;
	FILE *fp;
	FILE *tmpfp;
	FILE *tmpfp2;
	char *tfn;
	char tmpfn[256];
	int num_cols;
	int selcol;
	int col;
	int collen;
	DBINT colid;
	const char *opname;
	char adbuf[512];
	DBINT convlen;
	int printedcompute = 0;
	char adash;
	const char *database_name = NULL;
	int default_exit = EXIT_SUCCESS;

	setlocale(LC_ALL, "");

#ifdef __VMS
	/* Convert VMS-style arguments to Unix-style */
	parse_vms_args(&argc, &argv);
#endif

	editor = getenv("EDITOR");
	if (!editor) {
		editor = getenv("VISUAL");
	}
	if (!editor) {
		editor = "vi";
	}

	opterr = 0;
	optarg = NULL;
	while (!errflg && (c = getopt(argc, argv, "eFgpnvXYa:c:D:E:h:H:i:I:J:l:m:o:P:s:S:t:U:w:y:z:A:"))
	       != -1) {
		switch (c) {
		case 'e':
			echo = 1;
			break;
		case 'F':
			fipsflagger = 1;
			break;
		case 'g':
			errflg++;
			break;
		case 'p':
			errflg++;
			perfstats = 1;
			break;
		case 'n':
			no_prompt = 1;
			break;
		case 'v':
			puts("fisql, a free isql replacement by Nicholas S. Castellano");
			exit(EXIT_SUCCESS);
			break;
		case 'X':
			/* XXX: We get a different error message than isql gives; neither seems
			 * to work
			 */
			use_encryption = 1;
			break;
		case 'Y':
			chained_transactions = 1;
			break;
		case 'c':
			cmdend = optarg;
			break;
		case 'E':
			editor = optarg;
			break;
		case 'h':
			headers = atoi(optarg);
			break;
		case 'H':
			hostname = optarg;
			break;
		case 'i':
			input_filename = optarg;
			break;
		case 'I':
			interfaces_filename = optarg;
			break;
		case 'J':
			errflg++;
			break;
		case 'l':
			logintime = atoi(optarg);
			break;
		case 'm':
			global_errorlevel = atoi(optarg);
			break;
		case 'o':
			output_filename = optarg;
			break;
		case 'P':
			password = optarg;
			break;
		case 's':
			colseparator = optarg;
			break;
		case 'S':
			server = optarg;
			break;
		case 't':
			timeout = atoi(optarg);
			break;
		case 'U':
			username = optarg;
			break;
		case 'w':
			columnwidth = optarg;
			break;
		case 'y':
			/* XXX: this doesn't seem to be what isql does with -y...it doesn't
			 * seem to do anything actually
			 */
			sybenv = (char *) xmalloc((strlen(optarg) + 8) * sizeof(char));
			strcpy(sybenv, "SYBASE=");
			strcat(sybenv, optarg);
			putenv(sybenv);
			break;
		case 'z':
			language = optarg;
			break;
		case 'A':
			size = atoi(optarg);
			break;
		case 'D':
			database_name = optarg;
			break;
		default:
			errflg++;
			break;
		}
	}

	if (errflg) {
		fprintf(stderr, "usage: fisql [-e] [-F] [-g] [-p] [-n] [-v] [-X] [-Y]\n");
		fprintf(stderr, "\t[-c cmdend] [-D database_name] [-E editor]\n");
		fprintf(stderr, "\t[-h headers] [-H hostname] [-i inputfile]\n");
		fprintf(stderr, "\t[-I interfaces_file] [-J client character set]\n");
		fprintf(stderr, "\t[-l login_timeout] [-m errorlevel]\n");
		fprintf(stderr, "\t[-o outputfile]\n");
		fprintf(stderr, "\t[-P password] [-s colseparator] [-S server]\n");
		fprintf(stderr, "\t[-t timeout] [-U username] [-w columnwidth]\n");
		fprintf(stderr, "\t[-y sybase_dir] [-z language]\n");
		exit(EXIT_FAILURE);
	}
	if (!(isatty(fileno(stdin)))) {
		no_prompt = 1;
		rl_outstream = fopen("/dev/null", "rw");
	}
	rl_readline_name = "fisql";
	rl_bind_key('\t', rl_insert);
	if (password == NULL) {
		password = (char *) xmalloc(READPASSPHRASE_MAXLEN);
		readpassphrase("Password: "******"r", stdin) == NULL) {
			/* XXX: sybase isql generates this error while parsing the options,
			 * but doesn't redirect the input until after the Password: prompt
			 */
			/* lack of newline for bug-compatibility with isql */
			fprintf(stderr, "Unable to open input file '%s'.", optarg);
			exit(EXIT_FAILURE);
		}
	}
	if (output_filename) {
		if (freopen(output_filename, "w", stdout) == NULL) {
			/* XXX: sybase isql generates this error while parsing the options,
			 * but doesn't redirect the output until after the Password: prompt
			 */
			/* lack of newline for bug-compatibility with isql */
			fprintf(stderr, "Unable to open output file '%s'.", output_filename);
			exit(EXIT_FAILURE);
		}
	}
	if (isatty(fileno(stdin))) {
		rl_outstream = stdout;
	}
	dbinit();
#if 0
#ifdef DBVERSION_100
	dbsetversion(DBVERSION_100);
#endif
#endif
	if ((login = dblogin()) == NULL) {
		reset_term();
		exit(EXIT_FAILURE);
	}
	dbmsghandle(msg_handler);
	dberrhandle(err_handler);
	DBSETLAPP(login, "fisql");
	if (username) {
		DBSETLUSER(login, username);
	}
	DBSETLPWD(login, password);
	memset(password, 0, strlen(password));

	if (char_set) {
		DBSETLCHARSET(login, char_set);
	}
	if (use_encryption) {
		DBSETLENCRYPT(login, TRUE);
	}
	if (hostname) {
		DBSETLHOST(login, hostname);
	}
	if (language) {
		DBSETLNATLANG(login, language);
	}
	if (size) {
		DBSETLPACKET(login, (short) size);
	}
	if (interfaces_filename) {
		dbsetifile(interfaces_filename);
	}
	dbsettime(timeout);
	if (logintime >= 0) {
		dbsetlogintime(logintime);
	}
	if ((dbproc = dbopen(login, server)) == NULL) {
		fprintf(stderr, "fisql: dbopen() failed.\n");
		reset_term();
		exit(EXIT_FAILURE);
	}

	dbsetopt(dbproc, DBPRLINESEP, lineseparator, strlen(lineseparator));
	if (colseparator) {
		dbsetopt(dbproc, DBPRCOLSEP, colseparator, strlen(colseparator));
	}
	if (columnwidth) {
		dbsetopt(dbproc, DBPRLINELEN, columnwidth, 0);
	}
	if (chained_transactions) {
		dbsetopt(dbproc, DBCHAINXACTS, NULL, 0);
	}
	if (fipsflagger) {
		dbsetopt(dbproc, DBFIPSFLAG, NULL, 0);
	}
	if (perfstats) {
		dbsetopt(dbproc, DBSTAT, "time", 0);
	}
	if (database_name) {
		dbuse(dbproc, database_name);
	}

	while (1) {
		if (sigsetjmp(restart, 1)) {
			if (ibuf) {
				for (i = 0; i < ibuflines; i++) {
					free(ibuf[i]);
				}
				ibuflines = 0;
				free(ibuf);
				ibuf = NULL;
			}
			fputc('\n', stdout);
			rl_on_new_line();
			rl_reset_line_state();
		}
		dbcancel(dbproc);
		signal(SIGINT, inactive_interrupt_handler);
		ibuf = (char **) xmalloc(sizeof(char *));
		ibuflines = 0;
		while (1) {
			if (no_prompt) {
				foobuf[0] = '\0';
			} else {
				sprintf(foobuf, "%d>> ", ibuflines + 1);
			}
			line = readline(foobuf);
			if (line == NULL) {
				line = "exit";
			}
			for (cp = line; *cp && isspace((unsigned char) *cp); cp++)
				continue;
			if (*cp) {
				add_history(line);
			}
			if (!(strncasecmp(line, "!!", 2))) {
				int rv;
				cp = line + 2;
				switch (rv = system(cp)) {
				case 0:
					continue;
				case -1:
					fprintf(stderr,
					    "Failed to execute `%s'\n", cp);
					continue;
				default:
					fprintf(stderr, "Command `%s' exited "
					    "with code %d\n", cp, rv);
					continue;
				}
			}
			/* XXX: isql off-by-one line count error for :r not duplicated */
			if (!(strncasecmp(line, ":r", 2))) {
				for (cp = line + 2; *cp && (isspace((unsigned char) *cp)); cp++)
					continue;
				tfn = cp;
				for (; *cp && !(isspace((unsigned char) *cp)); cp++)
					continue;
				*cp = '\0';
				if ((fp = fopen(tfn, "r")) == NULL) {
					fprintf(stderr, "Operating system error: Failed to open %s.\n", tfn);
					continue;
				}
				tmpfp = rl_instream;
				tmpfp2 = rl_outstream;
				rl_instream = fp;
				rl_outstream = fopen("/dev/null", "w");
				while ((line = readline("")) != NULL) {
					ibuf[ibuflines++] = line;
					ibuf = (char **) xrealloc(ibuf, (ibuflines + 1) * sizeof(char *));
				}
				rl_instream = tmpfp;
				fclose(rl_outstream);
				rl_outstream = tmpfp2;
				fclose(fp);
				fputc('\r', stdout);
				fflush(stdout);
				continue;
			}
			firstword = (char *) xmalloc((strlen(line) + 1) * sizeof(char));
			strcpy(firstword, line);
			for (cp = firstword; *cp; cp++) {
				if (isspace((unsigned char) *cp)) {
					*cp = '\0';
					break;
				}
			}
			if ((!(strcasecmp(firstword, "exit")))
			    || (!(strcasecmp(firstword, "quit")))) {
				reset_term();
				dbexit();
				exit(default_exit);
			}
			if (!(strcasecmp(firstword, "reset"))) {
				for (i = 0; i < ibuflines; i++) {
					free(ibuf[i]);
				}
				ibuflines = 0;
				continue;
			}
			if (!(strcasecmp(firstword, cmdend))) {
				if (ibuflines == 0) {
					continue;
				}
				free(firstword);
				break;
			}
			if ((!(strcasecmp(firstword, "vi")))
			    || (!(strcasecmp(firstword, editor)))) {
				int tmpfd;

				strcpy(tmpfn, "/tmp/fisqlXXXXXX");
				tmpfd = mkstemp(tmpfn);
				if ((fp = fdopen(tmpfd, "w")) == NULL) {
					perror("fisql");
					reset_term();
					dbexit();
					exit(2);
				}
				if (ibuflines) {
					for (i = 0; i < ibuflines; i++) {
						fputs(ibuf[i], fp);
						fputc('\n', fp);
						free(ibuf[i]);
					}
				} else {
					for (i = 0; ((sqlch = dbgetchar(dbproc, i)) != NULL); i++) {
						fputc(*sqlch, fp);
					}
				}
				fclose(fp);
				if (!(strcmp(firstword, "vi"))) {
					edit("vi", tmpfn);
				} else {
					edit(editor, tmpfn);
				}
				ibuflines = 0;
				fp = fopen(tmpfn, "r");
				tmpfp = rl_instream;
				rl_instream = fp;
				strcpy(foobuf, "1>> ");
				while ((line = readline(foobuf)) != NULL) {
					ibuf[ibuflines++] = line;
					sprintf(foobuf, "%d>> ", ibuflines + 1);
					ibuf = (char **) xrealloc(ibuf, (ibuflines + 1) * sizeof(char *));
				}
				rl_instream = tmpfp;
				fclose(fp);
				fputc('\r', stdout);
				fflush(stdout);
				unlink(tmpfn);
				continue;
			}
			free(firstword);
			ibuf[ibuflines++] = line;
			ibuf = (char **) xrealloc(ibuf, (ibuflines + 1) * sizeof(char *));
		}
		dbfreebuf(dbproc);
		for (i = 0; i < ibuflines; i++) {
			if (echo) {
				puts(ibuf[i]);
			}
			dbcmd(dbproc, ibuf[i]);
			dbcmd(dbproc, "\n");
			free(ibuf[i]);
		}
		free(ibuf);
		ibuf = NULL;
		signal(SIGINT, active_interrupt_handler);
		dbsetinterrupt(dbproc, (void *) active_interrupt_pending, (void *) active_interrupt_servhandler);
		if (dbsqlexec(dbproc) == SUCCEED) {
			maybe_handle_active_interrupt();
			while ((dbrc = dbresults(dbproc)) != NO_MORE_RESULTS) {
				printedlines = 0;
#define USE_DBPRROW 0
#if USE_DBPRROW
				dbprhead(dbproc);
				dbprrow(dbproc);
#else
				if ((dbrc == SUCCEED) && (DBROWS(dbproc) == SUCCEED)) {
					prbuflen = dbspr1rowlen(dbproc);
					prbuf = (char *) xmalloc(prbuflen * sizeof(char));
					dbsprhead(dbproc, prbuf, prbuflen);
					fputs(prbuf, stdout);
					fputc('\n', stdout);
					dbsprline(dbproc, prbuf, prbuflen, '-');
					fputs(prbuf, stdout);
					fputc('\n', stdout);
					maybe_handle_active_interrupt();
					while ((dbrc = dbnextrow(dbproc)) != NO_MORE_ROWS) {
						if (dbrc == FAIL) {
							break;
						}
						if (dbrc != REG_ROW) {
							num_cols = dbnumalts(dbproc, dbrc);
							for (selcol = col = 1; col <= num_cols; col++) {
								colid = dbaltcolid(dbproc, dbrc, col);
								while (selcol < colid) {
									collen = get_printable_column_size(dbproc, selcol);
									for (i = 0; i < collen; i++) {
										putchar(' ');
									}
									selcol++;
									printf("%s", colseparator);
								}
								opname = dbprtype(dbaltop(dbproc, dbrc, col));
								printf("%s", opname);
								collen = get_printable_column_size(dbproc, colid);
								collen -= strlen(opname);
								while (collen-- > 0) {
									putchar(' ');
								}
								selcol++;
								printf("%s", colseparator);
							}
							printf("%s", lineseparator);
							for (selcol = col = 1; col <= num_cols; col++) {
								colid = dbaltcolid(dbproc, dbrc, col);
								while (selcol < colid) {
									collen = get_printable_column_size(dbproc, selcol);
									for (i = 0; i < collen; i++) {
										putchar(' ');
									}
									selcol++;
									printf("%s", colseparator);
								}
								collen = get_printable_column_size(dbproc, colid);
								adash = '-';
								for (i = 0; i < collen; i++) {
									putchar(adash);
								}
								selcol++;
								printf("%s", colseparator);
							}
							printf("%s", lineseparator);
							for (selcol = col = 1; col <= num_cols; col++) {
								colid = dbaltcolid(dbproc, dbrc, col);
								while (selcol < colid) {
									collen = get_printable_column_size(dbproc, selcol);
									for (i = 0; i < collen; i++) {
										putchar(' ');
									}
									selcol++;
									printf("%s", colseparator);
								}
								convlen = dbconvert(dbproc,
										    dbalttype(dbproc, dbrc, col),
										    dbadata(dbproc, dbrc, col),
										    dbadlen(dbproc, dbrc, col),
										    SYBCHAR, (BYTE *) adbuf, sizeof(adbuf));
								printf("%.*s", (int) convlen, adbuf);
								collen = get_printable_column_size(dbproc, colid);
								collen -= convlen;
								while (collen-- > 0) {
									putchar(' ');
								}
								selcol++;
								printf("%s", colseparator);
							}
							printf("%s", lineseparator);
							printedcompute = 1;
							continue;
						}
						if (printedcompute || (headers && (printedlines >= headers)
								       && ((printedlines % headers) == 0))) {
							fputc('\n', stdout);
							dbsprhead(dbproc, prbuf, prbuflen);
							fputs(prbuf, stdout);
							fputc('\n', stdout);
							dbsprline(dbproc, prbuf, prbuflen, '-');
							fputs(prbuf, stdout);
							fputc('\n', stdout);
							printedcompute = 0;
						}
						printedlines++;
						dbspr1row(dbproc, prbuf, prbuflen);
						fputs(prbuf, stdout);
						fputc('\n', stdout);
						maybe_handle_active_interrupt();
					}
					fputc('\n', stdout);
					free(prbuf);
					maybe_handle_active_interrupt();
				}
#endif
				if (dbrc != FAIL) {
					if ((DBCOUNT(dbproc) >= 0) || dbhasretstat(dbproc)) {
						if (DBCOUNT(dbproc) >= 0) {
							fprintf(stdout, "(%d rows affected", (int) DBCOUNT(dbproc));
							if (dbhasretstat(dbproc)) {
								dbrc = dbretstatus(dbproc);
								fprintf(stdout, ", return status = %d", dbrc);
							}
							fprintf(stdout, ")\n");
						} else {
							if (dbhasretstat(dbproc)) {
								dbrc = dbretstatus(dbproc);
								fprintf(stdout, "(return status = %d)\n", dbrc);
							}
						}
					}
				}
			}
		} else {
			/* Something failed, so change the default
			 * exit status to reflect that.
			 */
			default_exit = EXIT_FAILURE;
		}
	}
	reset_term();
	dbexit();
	exit(EXIT_FAILURE);
	return (0);
}
Exemple #10
0
static VALUE rb_tinytds_connect(VALUE self, VALUE opts) {
  /* Parsing options hash to local vars. */
  VALUE user, pass, dataserver, database, app, version, ltimeout, timeout, charset, azure, contained, use_utf16;
  GET_CLIENT_WRAPPER(self);

  user = rb_hash_aref(opts, sym_username);
  pass = rb_hash_aref(opts, sym_password);
  dataserver = rb_hash_aref(opts, sym_dataserver);
  database = rb_hash_aref(opts, sym_database);
  app = rb_hash_aref(opts, sym_appname);
  version = rb_hash_aref(opts, sym_tds_version);
  ltimeout = rb_hash_aref(opts, sym_login_timeout);
  timeout = rb_hash_aref(opts, sym_timeout);
  charset = rb_hash_aref(opts, sym_encoding);
  azure = rb_hash_aref(opts, sym_azure);
  contained = rb_hash_aref(opts, sym_contained);
  use_utf16 = rb_hash_aref(opts, sym_use_utf16);
  cwrap->userdata->message_handler = rb_hash_aref(opts, sym_message_handler);
  /* Dealing with options. */
  if (dbinit() == FAIL) {
    rb_raise(cTinyTdsError, "failed dbinit() function");
    return self;
  }
  dberrhandle(tinytds_err_handler);
  dbmsghandle(tinytds_msg_handler);
  cwrap->login = dblogin();
  if (!NIL_P(version))
    dbsetlversion(cwrap->login, NUM2INT(version));
  if (!NIL_P(user))
    dbsetluser(cwrap->login, StringValueCStr(user));
  if (!NIL_P(pass))
    dbsetlpwd(cwrap->login, StringValueCStr(pass));
  if (!NIL_P(app))
    dbsetlapp(cwrap->login, StringValueCStr(app));
  if (!NIL_P(ltimeout))
    dbsetlogintime(NUM2INT(ltimeout));
  if (!NIL_P(charset))
    DBSETLCHARSET(cwrap->login, StringValueCStr(charset));
  if (!NIL_P(database)) {
    if (azure == Qtrue || contained == Qtrue) {
      #ifdef DBSETLDBNAME
        DBSETLDBNAME(cwrap->login, StringValueCStr(database));
      #else
        if (azure == Qtrue) {
          rb_warn("TinyTds: :azure option is not supported in this version of FreeTDS.\n");
        }
        if (contained == Qtrue) {
          rb_warn("TinyTds: :contained option is not supported in this version of FreeTDS.\n");
        }
      #endif
    }
  }
  #ifdef DBSETUTF16
    if (use_utf16 == Qtrue)  { DBSETLUTF16(cwrap->login, 1); }
    if (use_utf16 == Qfalse) { DBSETLUTF16(cwrap->login, 0); }
  #else
    if (use_utf16 == Qtrue || use_utf16 == Qfalse) {
      rb_warning("TinyTds: Please consider upgrading to FreeTDS 0.99 or higher for better unicode support.\n");
    }
  #endif

  cwrap->client = dbopen(cwrap->login, StringValueCStr(dataserver));
  if (cwrap->client) {
    VALUE transposed_encoding, timeout_string;

    cwrap->closed = 0;
    cwrap->charset = charset;
    if (!NIL_P(version))
      dbsetversion(NUM2INT(version));
    if (!NIL_P(timeout)) {
      timeout_string = rb_sprintf("%"PRIsVALUE"", timeout);
      if (dbsetopt(cwrap->client, DBSETTIME, StringValueCStr(timeout_string), 0) == FAIL) {
        dbsettime(NUM2INT(timeout));
      }
    }
    dbsetuserdata(cwrap->client, (BYTE*)cwrap->userdata);
    cwrap->userdata->closed = 0;
    if (!NIL_P(database) && (azure != Qtrue)) {
      dbuse(cwrap->client, StringValueCStr(database));
    }
    transposed_encoding = rb_funcall(cTinyTdsClient, intern_transpose_iconv_encoding, 1, charset);
    cwrap->encoding = rb_enc_find(StringValueCStr(transposed_encoding));
    if (dbtds(cwrap->client) <= 7) {
      cwrap->identity_insert_sql = "SELECT CAST(@@IDENTITY AS bigint) AS Ident";
    } else {
      cwrap->identity_insert_sql = "SELECT CAST(SCOPE_IDENTITY() AS bigint) AS Ident";
    }
  }
  return self;
}
Exemple #11
0
int
main(int argc, char **argv)
{
	LOGINREC *login;
	DBPROCESS *dbproc;
	int i,r, failed = 0;
	RETCODE erc, row_code;
	int num_resultset = 0;
	char teststr[1024];

	/*
	 * Connect to server
	 */
	set_malloc_options();
	
	read_login_info(argc, argv);

	fprintf(stdout, "Starting %s\n", argv[0]);

	dbinit();

	dberrhandle(timeout_err_handler);
	dbmsghandle(syb_msg_handler);

	fprintf(stdout, "About to logon\n");

	login = dblogin();
	DBSETLPWD(login, PASSWORD);
	DBSETLUSER(login, USER);
	DBSETLAPP(login, "#t0022");

	fprintf(stdout, "About to open %s.%s\n", SERVER, DATABASE);

	/*
	 * One way to test the login timeout is to connect to a discard server (grep discard /etc/services).
	 * It's normally supported by inetd.
	 */
	printf ("using %d 1-second login timeouts\n", max_timeouts);
	dbsetlogintime(1);
	
	start_time = time(NULL);	/* keep track of when we started for reporting purposes */

	if (NULL == (dbproc = dbopen(login, SERVER))){
		fprintf(stderr, "Failed: dbopen\n");
		exit(1);
	}
	
	printf ("connected.\n");

	if (strlen(DATABASE))
		dbuse(dbproc, DATABASE);
	
	dbloginfree(login);

	/* send something that will take awhile to execute */
	printf ("using %d %d-second query timeouts\n", max_timeouts, timeout_seconds);
	if (FAIL == dbsettime(timeout_seconds)) {
		fprintf(stderr, "Failed: dbsettime\n");
		exit(1);
	}
	printf ("issuing a query that will take 30 seconds\n");

	if (FAIL == sql_cmd(dbproc)) {
		fprintf(stderr, "Failed: dbcmd\n");
		exit(1);
	}
	
	start_time = time(NULL);
	ntimeouts = 0;
	dbsetinterrupt(dbproc, (void*)chkintr, (void*)hndlintr);
	
	if (FAIL == dbsqlsend(dbproc)) {
		fprintf(stderr, "Failed: dbsend\n");
		exit(1);
	}

	/* wait for it to execute */
	printf("executing dbsqlok\n");
	erc = dbsqlok(dbproc);
	if (erc != FAIL) {
		fprintf(stderr, "dbsqlok should fail for timeout\n");
		exit(1);
	}

	/* retrieve outputs per usual */
	r = 0;
	for (i=0; (erc = dbresults(dbproc)) != NO_MORE_RESULTS; i++) {
		int nrows, ncols;
		switch (erc) {
		case SUCCEED:
			if (DBROWS(dbproc) == FAIL){
				r++;
				continue;
			}
			assert(DBROWS(dbproc) == SUCCEED);
			printf("dbrows() returned SUCCEED, processing rows\n");

			ncols = dbnumcols(dbproc);
			++num_resultset;
			printf("bound 1 of %d columns ('%s') in result %d.\n", ncols, dbcolname(dbproc, 1), ++r);
			dbbind(dbproc, 1, STRINGBIND, 0, (BYTE *) teststr);

			printf("\t%s\n\t-----------\n", dbcolname(dbproc, 1));
			while ((row_code = dbnextrow(dbproc)) != NO_MORE_ROWS) {
				if (row_code == REG_ROW) {
					printf("\t%s\n", teststr);
				} else {
					/* not supporting computed rows in this unit test */
					failed = 1;
					fprintf(stderr, "Failed.  Expected a row\n");
					exit(1);
				}
			}
			nrows = (int) dbcount(dbproc);
			printf("row count %d\n", nrows);
			if (nrows < 0){
				failed++;
				printf("error: dbrows() returned SUCCEED, but dbcount() returned -1\n");
			}
			break;
		case FAIL:
			printf("dbresults returned FAIL\n");
			exit(1);
		default:
			printf("unexpected return code %d from dbresults\n", erc);
			exit(1);
		}
		if ( i > 1) {
			failed++;
			break;
		}
	} /* while dbresults */
	
	dbexit();

	fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
	return failed ? 1 : 0;
}