⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 common.c

📁 在Linux/Unix下面访问WINDOWS SQLSERVER 的ODBC驱动程序
💻 C
字号:
#include "common.h"#if HAVE_UNISTD_H#include <unistd.h>#endif#if HAVE_LIBGEN_H#include <libgen.h>#endif /* HAVE_LIBGEN_H */#if HAVE_SYS_PARAM_H#include <sys/param.h>#endif /* HAVE_SYS_PARAM_H */#ifndef DBNTWIN32#include "replacements.h"#endifstatic char software_version[] = "$Id: common.c,v 1.23 2007/11/30 08:55:13 freddy77 Exp $";static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };typedef struct _tag_memcheck_t{	int item_number;	unsigned int special;	struct _tag_memcheck_t *next;}memcheck_t;static memcheck_t *breadcrumbs = NULL;static int num_breadcrumbs = 0;static const unsigned int BREADCRUMB = 0xABCD7890;char USER[512];char SERVER[512];char PASSWORD[512];char DATABASE[512];static char *DIRNAME = NULL;static const char *BASENAME = NULL;#if HAVE_MALLOC_OPTIONSextern const char *malloc_options;#endif /* HAVE_MALLOC_OPTIONS */voidset_malloc_options(void){#if HAVE_MALLOC_OPTIONS	/*	 * Options for malloc	 * A- all warnings are fatal	 * J- init memory to 0xD0	 * R- always move memory block on a realloc	 */	malloc_options = "AJR";#endif /* HAVE_MALLOC_OPTIONS */}#if defined(__MINGW32__) || defined(_MSC_VER)static char *tds_dirname(char* path){	char *p, *p2;	for (p = path + strlen(path); --p > path && (*p == '/' || *p == '\\');)		*p = '\0';	p = strrchr(path, '/');	if (!p)		p = path;	p2 = strrchr(p, '\\');	if (p2)		p = p2;	*p = 0;	return path;}#define dirname tds_dirname#endif#ifndef MAXPATHLEN#define MAXPATHLEN 512#endifintread_login_info(int argc, char **argv){	extern char *optarg;	extern int optind;		FILE *in;#if !defined(__MINGW32__) && !defined(_MSC_VER)	int ch;#endif	char line[512];	char *s1, *s2;	char filename[MAXPATHLEN];	static const char *PWD = "../../../PWD";	struct { char *username, *password, *servername, *database; char fverbose; } options;		BASENAME = tds_basename((char *)argv[0]);	DIRNAME = dirname((char *)argv[0]);		memset(&options, 0, sizeof(options));	#if !defined(__MINGW32__) && !defined(_MSC_VER)	/* process command line options (handy for manual testing) */	while ((ch = getopt(argc, (char**)argv, "U:P:S:D:f:v")) != -1) {		switch (ch) {		case 'U':			options.username = strdup(optarg);			break;		case 'P':			options.password = strdup(optarg);			break;		case 'S':			options.servername = strdup(optarg);			break;		case 'D':			options.database = strdup(optarg);			break;		case 'f': /* override default PWD file */			PWD = strdup(optarg);			break;		case 'v':			options.fverbose = 1; /* doesn't normally do anything */			break;		case '?':		default:			fprintf(stderr, "usage:  %s \n"					"        [-U username] [-P password]\n"					"        [-S servername] [-D database]\n"					"        [-i input filename] [-o output filename] "					"[-e error filename]\n"					, BASENAME);			exit(1);		}	}#endif	strcpy(filename, PWD);		in = fopen(filename, "r");	if (!in)		in = fopen("PWD", "r");	if (!in) {		sprintf(filename, "%s/%s", (DIRNAME) ? DIRNAME : ".", PWD);		in = fopen(filename, "r");		if (!in) {			fprintf(stderr, "Can not open %s file\n\n", filename);			return 1;		}	}	while (fgets(line, 512, in)) {		s1 = strtok(line, "=");		s2 = strtok(NULL, "\n");		if (!s1 || !s2)			continue;		if (!strcmp(s1, "UID")) {			strcpy(USER, s2);		} else if (!strcmp(s1, "SRV")) {			strcpy(SERVER, s2);		} else if (!strcmp(s1, "PWD")) {			strcpy(PASSWORD, s2);		} else if (!strcmp(s1, "DB")) {			strcpy(DATABASE, s2);		}	}	fclose(in);		/* apply command-line overrides */	if (options.username) {		strcpy(USER, options.username);		free(options.username);	}	if (options.password) {		strcpy(PASSWORD, options.password);		free(options.password);	}	if (options.servername) {		strcpy(SERVER, options.servername);		free(options.servername);	}	if (options.database) {		strcpy(DATABASE, options.database);		free(options.database);	}		printf("found %s.%s for %s in \"%s\"\n", SERVER, DATABASE, USER, filename);	return 0;}voidcheck_crumbs(void){	int i;	memcheck_t *ptr = breadcrumbs;	i = num_breadcrumbs;	while (ptr != NULL) {		if (ptr->special != BREADCRUMB || ptr->item_number != i) {			fprintf(stderr, "Somebody overwrote one of the bread crumbs!!!\n");			abort();		}		i--;		ptr = ptr->next;	}}voidadd_bread_crumb(void){	memcheck_t *tmp;	check_crumbs();	tmp = (memcheck_t *) calloc(sizeof(memcheck_t), 1);	if (tmp == NULL) {		fprintf(stderr, "Out of memory");		abort();		exit(1);	}	num_breadcrumbs++;	tmp->item_number = num_breadcrumbs;	tmp->special = BREADCRUMB;	tmp->next = breadcrumbs;	breadcrumbs = tmp;}voidfree_bread_crumb(void){	memcheck_t *tmp, *ptr = breadcrumbs;	check_crumbs();	while (ptr) {		tmp = ptr->next;		free(ptr);		ptr = tmp;	}	num_breadcrumbs = 0;}intsyb_msg_handler(DBPROCESS * dbproc, DBINT msgno, int msgstate, int severity, char *msgtext, char *srvname, char *procname, int line){	char var_value[31];	int i;	char *c;	int *pexpected_msgno;		/*	 * Check for "database changed", or "language changed" messages from	 * the client.  If we get one of these, then we need to pull the	 * name of the database or charset from the message and set the	 * appropriate variable.	 */	if (msgno == 5701 ||	/* database context change */	    msgno == 5703 ||	/* language changed */	    msgno == 5704) {	/* charset changed */		/* fprintf( stderr, "msgno = %d: %s\n", msgno, msgtext ) ; */		if (msgtext != NULL && (c = strchr(msgtext, '\'')) != NULL) {			i = 0;			for (++c; i <= 30 && *c != '\0' && *c != '\''; ++c)				var_value[i++] = *c;			var_value[i] = '\0';		}		return 0;	}	/*	 * If the user data indicates this is an expected error message (because we're testing the 	 * error propogation, say) then indicate this message was anticipated.	 */	if (dbproc != NULL) {		pexpected_msgno = (int *) dbgetuserdata(dbproc);		if (pexpected_msgno && *pexpected_msgno == msgno) {			fprintf(stdout, "OK: anticipated message arrived: %d %s\n", msgno, msgtext);			*pexpected_msgno = 0;			return 0;		}	}	/*	 * If the severity is something other than 0 or the msg number is	 * 0 (user informational messages).	 */	if (severity >= 0 || msgno == 0) {		/*		 * If the message was something other than informational, and		 * the severity was greater than 0, then print information to		 * stderr with a little pre-amble information.		 */		if (msgno > 0 && severity > 0) {			fprintf(stderr, "Msg %d, Level %d, State %d\n", (int) msgno, (int) severity, (int) msgstate);			fprintf(stderr, "Server '%s'", srvname);			if (procname != NULL && *procname != '\0')				fprintf(stderr, ", Procedure '%s'", procname);			if (line > 0)				fprintf(stderr, ", Line %d", line);			fprintf(stderr, "\n");			fprintf(stderr, "%s\n", msgtext);			fflush(stderr);		} else {			/*			 * Otherwise, it is just an informational (e.g. print) message			 * from the server, so send it to stdout.			 */			fprintf(stdout, "%s\n", msgtext);			fflush(stdout);		}	}	assert(0); /* no unanticipated messages allowed in unit tests */	return 0;}intsyb_err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr){	int *pexpected_dberr;	/*	 * 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 the user data indicates this is an expected error message (because we're testing the 	 * error propogation, say) then indicate this message was anticipated.	 */	if (dbproc != NULL) {		pexpected_dberr = (int *) dbgetuserdata(dbproc);		if (pexpected_dberr && *pexpected_dberr == dberr) {			fprintf(stdout, "OK: anticipated error %d (%s) arrived\n", dberr, dberrstr);			*pexpected_dberr = 0;			return INT_CANCEL;		}	}	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) {			exit(255);		}	}	assert(0); /* no unanticipated errors allowed in unit tests */	return INT_CANCEL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -