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

📄 mapi.mx

📁 这个是内存数据库的客户端
💻 MX
📖 第 1 页 / 共 5 页
字号:
	hdl->prev = NULL;	hdl->next = NULL;	hdl->mid = NULL;	free(hdl);	return MOK;}/* Allocate a new connection handle. */static Mapimapi_new(void){	Mapi mid;	mid = malloc(sizeof(*mid));	if (mid == NULL)		return NULL;	assert(mid);	/* initialize everything to 0 */	memset(mid, 0, sizeof(*mid));	/* then fill in some details */	mid->auto_commit = 1;	mid->error = MOK;	mid->hostname = strdup("localhost");	mid->server = NULL;	mid->language = strdup("mil");	mid->languageId = LANG_MIL;	mid->versionId = 4;	mid->noexplain = NULL;	mid->motd = NULL;	mid->mapiversion = "mapi 1.0";	mid->username = NULL;	mid->password = NULL;	mid->cachelimit = 100;	mid->redircnt = 0;	mid->tracelog = NULL;	mid->blk.eos = 0;	mid->blk.buf = malloc(BLOCK + 1);	mid->blk.buf[BLOCK] = 0;	mid->blk.buf[0] = 0;	mid->blk.nxt = 0;	mid->blk.end = 0;	mid->blk.lim = BLOCK;	mid->first = NULL;	return mid;}/* Allocate a new connection handle and fill in the information needed   to connect to a server, but don't connect yet. */Mapimapi_mapi(const char *host, int port, const char *username, const char *password, const char *lang, const char *dbname){	Mapi mid;	if (!mapi_initialized) {		mapi_initialized = 1;		if (stream_init() < 0)			return NULL;	}	mid = mapi_new();	if (mid == NULL)		return NULL;	if (host) {		free(mid->hostname);		mid->hostname = strdup(host);	}	if (port == 0) {		char *def;		if ((def = getenv("MAPIPORT")) != NULL)			port = atoi(def);	}	if (port == 0)		port = 50000;	/* hardwired default */	/* fill some defaults for user/pass, this should actually never happen */	if (username == NULL)		username = "guest";	if (mid->username != NULL) free(mid->username);	mid->username = strdup(username);	if (password == NULL)		password = "guest";	if (mid->password) free(mid->password);	mid->password = strdup(password);	mid->port = port;#ifdef HAVE_OPENSSL	mid->secure = 0;#endif	if (lang == NULL)		lang = "mil";	free(mid->language);	mid->language = strdup(lang);	if (strcmp(lang, "mil") == 0)		mid->languageId = LANG_MIL;	else if (strcmp(lang, "mal") == 0)		mid->languageId = LANG_MAL;	else if (strcmp(lang, "sql") == 0)		mid->languageId = LANG_SQL;	else if (strcmp(lang, "xquery") == 0)		mid->languageId = LANG_XQUERY;	if (mid->database) free(mid->database);	mid->database = dbname ? strdup(dbname) : NULL;	return mid;}/* Close a connection and free all memory associated with the   connection handle. */MapiMsgmapi_destroy(Mapi mid){	mapi_clrError(mid);	while (mid->first)		mapi_close_handle(mid->first);	if (mid->connected)		(void) mapi_disconnect(mid);	if (mid->blk.buf)		free(mid->blk.buf);	if (mid->errorstr)		free(mid->errorstr);	if (mid->hostname)		free(mid->hostname);	if (mid->username)		free(mid->username);	if (mid->password)		free(mid->password);	if (mid->language)		free(mid->language);	if (mid->database)		free(mid->database);	if (mid->server)		free(mid->server);	free(mid);	return MOK;}@- Channel ConstructorThe first call of an application is to establish a connection withan already server. The username and password are sent as part ofthe initialization sequence.@c#ifdef HAVE_OPENSSLstatic char *ssl_error(int err, int ret){	char *errstr;	char buf[120];	unsigned long e;	switch (err) {	case SSL_ERROR_ZERO_RETURN:		errstr = "TLS/SSL connection has been closed";		break;	case SSL_ERROR_WANT_READ:		errstr = "The operation did not complete (read)";		break;	case SSL_ERROR_WANT_WRITE:		errstr = "The operation did not complete (write)";		break;	case SSL_ERROR_WANT_X509_LOOKUP:		errstr = "The operation did not complete (X509 lookup)";		break;	case SSL_ERROR_WANT_CONNECT:		errstr = "The operation did not complete (connect)";		break;	case SSL_ERROR_SYSCALL:		e = ERR_get_error();		if (e == 0) {			if (ret == 0) {				errstr = "EOF occurred in violation of protocol";			} else if (ret == -1) {				/* the underlying BIO reported an I/O error */				errstr = "I/O error";			} else {	/* possible? */				errstr = "Some I/O error occurred";			}		} else {			errstr = ERR_error_string(e, buf);		}		break;	case SSL_ERROR_SSL:		e = ERR_get_error();		if (e != 0)			errstr = ERR_error_string(e, buf);		else {		/* possible? */			errstr = "A failure in the SSL library occurred";		}		break;	default:		errstr = "Invalid error code";	}	return strdup(errstr);}#endif /* HAVE_OPENSSL *//* (Re-)establish a connection with the server. */static MapiMsgconnect_to_server(Mapi mid){	struct sockaddr_in server;#ifdef HAVE_SYS_UN_H	struct sockaddr_un userver;#endif	struct sockaddr *serv;	socklen_t servsize;	SOCKET s;#ifdef HAVE_OPENSSL	SSL *ssl = NULL;#endif	if (mid->connected)		close_connection(mid);#ifdef HAVE_SYS_UN_H	if (#ifdef HAVE_OPENSSL		   !mid->secure &&#endif		   mid->hostname && mid->hostname[0] == '/') {		if (strlen(mid->hostname) >= sizeof(userver.sun_path)) {			return mapi_setError(mid, "path name too long", "mapi_reconnect", MERROR);		}		userver.sun_family = AF_UNIX;		strncpy(userver.sun_path, mid->hostname, sizeof(userver.sun_path));		serv = (struct sockaddr *) &userver;		servsize = sizeof(userver);	} else#endif	{		struct hostent *hp;		hp = gethostbyname(mid->hostname);		if (hp == NULL) {			return mapi_setError(mid, "gethostbyname failed", "mapi_reconnect", MERROR);		}		memset(&server, 0, sizeof(server));		memcpy(&server.sin_addr, hp->h_addr, hp->h_length);		server.sin_family = hp->h_addrtype;		server.sin_port = htons((unsigned short) (mid->port & 0xFFFF));		serv = (struct sockaddr *) &server;		servsize = sizeof(server);	}#ifdef HAVE_OPENSSL	if (mid->secure && mapi_ssl_ctx == NULL) {		mapi_ssl_ctx = SSL_CTX_new(SSLv23_method());		if (mapi_ssl_ctx == 0) {			char *errstr = ssl_error(SSL_ERROR_SSL, 0);			mapi_setError(mid, errstr, "mapi_reconnect", MERROR);			free(errstr);			return mid->error;		}		SSL_CTX_set_verify(mapi_ssl_ctx, SSL_VERIFY_NONE, NULL);	}#endif	s = socket(serv->sa_family, SOCK_STREAM, IPPROTO_TCP);	if (s < 0) {		return mapi_setError(mid, "Open socket failed", "mapi_reconnect", MERROR);	}	if (connect(s, serv, servsize) < 0) {#ifdef NATIVE_WIN32		fprintf(stderr, "!ERROR mapi_reconnect: connect: error %d\n", WSAGetLastError());#else		perror("!ERROR mapi_reconnect: connect");#endif		return mapi_setError(mid, "Setup connection failed", "mapi_reconnect", MERROR);	}#ifdef HAVE_OPENSSL	if (mid->secure) {		if ((ssl = SSL_new(mapi_ssl_ctx)) == 0) {			char *errstr = ssl_error(SSL_ERROR_SSL, 0);			mapi_setError(mid, errstr, "mapi_reconnect", MERROR);			free(errstr);			close(s);			return mid->error;		}		if (!SSL_set_fd(ssl, s)) {			char *errstr = ssl_error(SSL_ERROR_SSL, 0);			mapi_setError(mid, errstr, "mapi_reconnect", MERROR);			free(errstr);			SSL_free(ssl);			close(s);			return mid->error;		}		SSL_set_connect_state(ssl);		for (;;) {			int ret, err;			char *errstr;			ret = SSL_connect(ssl);			err = SSL_get_error(ssl, ret);			switch (err) {			case SSL_ERROR_WANT_READ:			case SSL_ERROR_WANT_WRITE:				/* try again */				continue;			case SSL_ERROR_NONE:				/* successful connect */				break;			case SSL_ERROR_WANT_CONNECT:			case SSL_ERROR_WANT_ACCEPT:			case SSL_ERROR_WANT_X509_LOOKUP:			default:				/* some error occurred */				SSL_free(ssl);				close(s);				errstr = ssl_error(err, ret);				mapi_setError(mid, errstr, "mapi_reconnect", MERROR);				free(errstr);				return mid->error;			}			break;		}		mid->to = ssl_wastream(ssl, "Mapi client write");		mid->from = ssl_rastream(ssl, "Mapi client read");	} else#endif	{		mid->to = socket_wastream(s, "Mapi client write");		mid->from = socket_rastream(s, "Mapi client read");	}	check_stream(mid, mid->to, "Cannot open socket for writing", "mapi_reconnect", mid->error);	check_stream(mid, mid->from, "Cannot open socket for reading", "mapi_reconnect", mid->error);	mid->connected = 1;	return MOK;}MapiMsgmapi_start_talking(Mapi mid){	char buf[BLOCK];	size_t len;	MapiHdl hdl;	int pversion = 0;	char *chal;	char *server;	char *protover;	char *rest;	mid->to = block_stream(mid->to);	check_stream(mid, mid->to, stream_error(mid->to), "mapi_start_talking", mid->error);	mid->from = block_stream(mid->from);	check_stream(mid, mid->from, stream_error(mid->from), "mapi_start_talking", mid->error);	/* consume server challenge */	len = stream_read_block(mid->from, buf, 1, BLOCK);	check_stream(mid, mid->from, "Connection terminated", "mapi_start_talking", (mid->blk.eos = 1, mid->error));	assert(len < BLOCK);	/* buf at this point looks like "challenge:servertype:protover[:.*]" */	chal = buf;	server = strchr(chal, ':');	if (server == NULL) {		mapi_setError(mid, "Challenge string is not valid", "mapi_start_talking", MERROR);		return mid->error;	}	*server++ = '\0';	protover = strchr(server, ':');	if (protover == NULL) {		mapi_setError(mid, "Challenge string is not valid", "mapi_start_talking", MERROR);		return mid->error;	}	*protover++ = '\0';	rest = strchr(protover, ':');	if (rest != NULL) {		*rest++ = '\0';	}	pversion = atoi(protover);	if (pversion < 8) {		/* because the headers changed, and because it makes no sense to		 * try and be backwards compatible, we bail out with a friendly		 * message saying so.		 */		snprintf(buf, BLOCK, "Unsupported protocol version: %d.  "				"This client only supports version 8 and up.  "				"Sorry, can't help you here!", pversion);		mapi_setError(mid, buf,	"mapi_start_talking", MERROR);		return mid->error;	} else if (pversion == 8) {		char* hash = NULL;		char* hashes = NULL;		/* the database has sent a list of supported hashes to us, it's		 * in the form of a comma separated list and in the variable		 * rest.  We try to use the strongest algorithm.		 */		hashes = rest;		hash = strchr(hashes, ':'); /* temp misuse hash */		if (hash) {			*hash = '\0';			rest = hash + 1;		}		hash = NULL;		/* TODO: make this actually obey the separation by comm

⌨️ 快捷键说明

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