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

📄 conn.c

📁 AnyQ服务端源代码(2004/10/28)源码
💻 C
📖 第 1 页 / 共 2 页
字号:
				}			}			close(fd);			fd = -1;		}	}	return fd;}/** * aim_cloneconn - clone an aim_conn_t * @sess: session containing parent * @src: connection to clone * * A new connection is allocated, and the values are filled in * appropriately. Note that this function sets the new connnection's * ->priv pointer to be equal to that of its parent: only the pointer * is copied, not the data it points to. * * This function returns a pointer to the new aim_conn_t, or %NULL on * error */faim_internal aim_conn_t *aim_cloneconn(aim_session_t *sess, aim_conn_t *src){	aim_conn_t *conn;	if (!(conn = aim_conn_getnext(sess)))		return NULL;	conn->fd = src->fd;	conn->type = src->type;	conn->subtype = src->subtype;	conn->seqnum = src->seqnum;	conn->priv = src->priv;	conn->internal = src->internal;	conn->lastactivity = src->lastactivity;	conn->forcedlatency = src->forcedlatency;	conn->sessv = src->sessv;	aim_clonehandlers(sess, conn, src);	if (src->inside) {		/*		 * XXX should clone this section as well, but since currently		 * this function only gets called for some of that rendezvous		 * crap, and not on SNAC connections, its probably okay for		 * now. 		 *		 */	}	return conn;}/** * aim_newconn - Open a new connection * @sess: Session to create connection in * @type: Type of connection to create * @dest: Host to connect to (in "host:port" syntax) * * Opens a new connection to the specified dest host of specified * type, using the proxy settings if available.  If @host is %NULL, * the connection is allocated and returned, but no connection  * is made. * * FIXME: Return errors in a more sane way. * */faim_export aim_conn_t *aim_newconn(aim_session_t *sess, int type, const char *dest){	aim_conn_t *connstruct;	fu16_t port = FAIM_LOGIN_PORT;	char *host;	int i, ret;	if (!(connstruct = aim_conn_getnext(sess)))		return NULL;	connstruct->sessv = (void *)sess;	connstruct->type = type;	if (!dest) { /* just allocate a struct */		connstruct->fd = -1;		connstruct->status = 0;		return connstruct;	}	/* 	 * As of 23 Jul 1999, AOL now sends the port number, preceded by a 	 * colon, in the BOS redirect.  This fatally breaks all previous 	 * libfaims.  Bad, bad AOL.	 *	 * We put this here to catch every case. 	 *	 */	for(i = 0; i < (int)strlen(dest); i++) {		if (dest[i] == ':') {			port = atoi(&(dest[i+1]));			break;		}	}	host = (char *)malloc(i+1);	strncpy(host, dest, i);	host[i] = '\0';	if ((ret = aim_proxyconnect(sess, host, port, &connstruct->status)) < 0) {		connstruct->fd = -1;		connstruct->status = (errno | AIM_CONN_STATUS_CONNERR);		free(host);		return connstruct;	} else		connstruct->fd = ret;	free(host);	return connstruct;}/** * aim_conngetmaxfd - Return the highest valued file discriptor in session * @sess: Session to search * * Returns the highest valued filed descriptor of all open  * connections in @sess. * */faim_export int aim_conngetmaxfd(aim_session_t *sess){	int j;	aim_conn_t *cur;	for (cur = sess->connlist, j = 0; cur; cur = cur->next) {		if (cur->fd > j)			j = cur->fd;	}	return j;}/** * aim_conn_in_sess - Predicate to test the precense of a connection in a sess * @sess: Session to look in * @conn: Connection to look for * * Searches @sess for the passed connection.  Returns 1 if its present, * zero otherwise. * */faim_export int aim_conn_in_sess(aim_session_t *sess, aim_conn_t *conn){	aim_conn_t *cur;	for (cur = sess->connlist; cur; cur = cur->next) {		if (cur == conn)			return 1;	}	return 0;}/** * aim_select - Wait for a socket with data or timeout * @sess: Session to wait on * @timeout: How long to wait * @status: Return status * * Waits for a socket with data or for timeout, whichever comes first. * See select(2). *  * Return codes in *status: *   -1  error in select() (%NULL returned) *    0  no events pending (%NULL returned) *    1  outgoing data pending (%NULL returned) *    2  incoming data pending (connection with pending data returned) * */ faim_export aim_conn_t *aim_select(aim_session_t *sess, struct timeval *timeout, int *status){	aim_conn_t *cur;	fd_set fds, wfds;	int maxfd, i, haveconnecting = 0;	if (!sess->connlist) {		*status = -1;		return NULL;	}	FD_ZERO(&fds);	FD_ZERO(&wfds);	for (cur = sess->connlist, maxfd = 0; cur; cur = cur->next) {		if (cur->fd == -1) {			/* don't let invalid/dead connections sit around */			*status = 2;			return cur;		} else if (cur->status & AIM_CONN_STATUS_INPROGRESS) {			FD_SET(cur->fd, &wfds);			haveconnecting++;		}		FD_SET(cur->fd, &fds);		if (cur->fd > maxfd)			maxfd = cur->fd;	}	/* 	 * If we have data waiting to be sent, return	 *	 * We have to not do this if theres at least one	 * connection thats still connecting, since that connection	 * may have queued data and this return would prevent	 * the connection from ever completing!  This is a major	 * inadequacy of the libfaim way of doing things.  It means	 * that nothing can transmit as long as there's connecting	 * sockets. Evil.	 *	 * But its still better than having blocking connects.	 *	 */	if (!haveconnecting && sess->queue_outgoing) {		*status = 1;		return NULL;	} 	if ((i = select(maxfd+1, &fds, &wfds, NULL, timeout))>=1) {		for (cur = sess->connlist; cur; cur = cur->next) {			if ((FD_ISSET(cur->fd, &fds)) || 					((cur->status & AIM_CONN_STATUS_INPROGRESS) && 					FD_ISSET(cur->fd, &wfds))) {				*status = 2;				return cur;			}		}		*status = 0; /* shouldn't happen */	} else if ((i == -1) && (errno == EINTR)) /* treat interrupts as a timeout */		*status = 0;	else		*status = i; /* can be 0 or -1 */	return NULL;  /* no waiting or error, return */}/** * aim_conn_setlatency - Set a forced latency value for connection * @conn: Conn to set latency for * @newval: Number of seconds to force between transmits * * Causes @newval seconds to be spent between transmits on a connection. * * This is my lame attempt at overcoming not understanding the rate * limiting.  * * XXX: This should really be replaced with something that scales and * backs off like the real rate limiting does. * */faim_export int aim_conn_setlatency(aim_conn_t *conn, int newval){	if (!conn)		return -1;	conn->forcedlatency = newval;	conn->lastactivity = 0; /* reset this just to make sure */	return 0;}/** * aim_setupproxy - Configure a proxy for this session * @sess: Session to set proxy for * @server: SOCKS server * @username: SOCKS username * @password: SOCKS password * * Call this with your SOCKS5 proxy server parameters before * the first call to aim_newconn().  If called with all %NULL * args, it will clear out a previously set proxy.   * * Set username and password to %NULL if not applicable. * */faim_export void aim_setupproxy(aim_session_t *sess, const char *server, const char *username, const char *password){	/* clear out the proxy info */	if (!server || !strlen(server)) {		memset(sess->socksproxy.server, 0, sizeof(sess->socksproxy.server));		memset(sess->socksproxy.username, 0, sizeof(sess->socksproxy.username));		memset(sess->socksproxy.password, 0, sizeof(sess->socksproxy.password));		return;	}	strncpy(sess->socksproxy.server, server, sizeof(sess->socksproxy.server));	if (username && strlen(username)) 		strncpy(sess->socksproxy.username, username, sizeof(sess->socksproxy.username));	if (password && strlen(password))		strncpy(sess->socksproxy.password, password, sizeof(sess->socksproxy.password));	return;}static void defaultdebugcb(aim_session_t *sess, int level, const char *format, va_list va){	vfprintf(stderr, format, va);	return;}/** * aim_session_init - Initializes a session structure * @sess: Session to initialize * @flags: Flags to use. Any of %AIM_SESS_FLAGS %OR'd together. * @debuglevel: Level of debugging output (zero is least) * * Sets up the initial values for a session. * */faim_export void aim_session_init(aim_session_t *sess, fu32_t flags, int debuglevel){	if (!sess)		return;	memset(sess, 0, sizeof(aim_session_t));	aim_connrst(sess);	sess->queue_outgoing = NULL;	sess->queue_incoming = NULL;	aim_initsnachash(sess);	sess->msgcookies = NULL;	sess->snacid_next = 0x00000001;	sess->flags = 0;	sess->debug = debuglevel;	sess->debugcb = defaultdebugcb;	sess->modlistv = NULL;	/*	 * Default to SNAC login unless XORLOGIN is explicitly set.	 */	if (!(flags & AIM_SESS_FLAGS_XORLOGIN))		sess->flags |= AIM_SESS_FLAGS_SNACLOGIN;	sess->flags |= flags;	/*	 * This must always be set.  Default to the queue-based	 * version for back-compatibility.  	 */	aim_tx_setenqueue(sess, AIM_TX_QUEUED, NULL);	/*	 * Register all the modules for this session...	 */	aim__registermodule(sess, misc_modfirst); /* load the catch-all first */	aim__registermodule(sess, general_modfirst);	aim__registermodule(sess, locate_modfirst);	aim__registermodule(sess, buddylist_modfirst);	aim__registermodule(sess, msg_modfirst);	aim__registermodule(sess, adverts_modfirst);	aim__registermodule(sess, invite_modfirst);	aim__registermodule(sess, admin_modfirst);	aim__registermodule(sess, popups_modfirst);	aim__registermodule(sess, bos_modfirst);	aim__registermodule(sess, search_modfirst);	aim__registermodule(sess, stats_modfirst);	aim__registermodule(sess, translate_modfirst);	aim__registermodule(sess, chatnav_modfirst);	aim__registermodule(sess, chat_modfirst);	/* missing 0x0f - 0x12 */	aim__registermodule(sess, ssi_modfirst);	/* missing 0x14 */	aim__registermodule(sess, icq_modfirst);	/* missing 0x16 */	aim__registermodule(sess, auth_modfirst);	return;}/** * aim_session_kill - Deallocate a session * @sess: Session to kill * */faim_export void aim_session_kill(aim_session_t *sess){	aim_cleansnacs(sess, -1);	aim_logoff(sess);	aim__shutdownmodules(sess);	return;}/** * aim_setdebuggingcb - Set the function to call when outputting debugging info * @sess: Session to change * @cb: Function to call * * The function specified is called whenever faimdprintf() is used within * libfaim, and the session's debugging level is greater tha nor equal to * the value faimdprintf was called with. * */faim_export int aim_setdebuggingcb(aim_session_t *sess, faim_debugging_callback_t cb){	if (!sess)		return -1;	sess->debugcb = cb;	return 0;}/** * aim_conn_isconnecting - Determine if a connection is connecting * @conn: Connection to examine * * Returns nonzero if the connection is in the process of * connecting (or if it just completed and aim_conn_completeconnect() * has yet to be called on it). * */faim_export int aim_conn_isconnecting(aim_conn_t *conn){	if (!conn)		return 0;	return !!(conn->status & AIM_CONN_STATUS_INPROGRESS);}/* * XXX this is nearly as ugly as proxyconnect(). */faim_export int aim_conn_completeconnect(aim_session_t *sess, aim_conn_t *conn){	fd_set fds, wfds;	struct timeval tv;	int res, error = ETIMEDOUT;	aim_rxcallback_t userfunc;	if (!conn || (conn->fd == -1))		return -1;	if (!(conn->status & AIM_CONN_STATUS_INPROGRESS))		return -1;	FD_ZERO(&fds);	FD_SET(conn->fd, &fds);	FD_ZERO(&wfds);	FD_SET(conn->fd, &wfds);	tv.tv_sec = 0;	tv.tv_usec = 0;	if ((res = select(conn->fd+1, &fds, &wfds, NULL, &tv)) == -1) {		error = errno;		aim_conn_close(conn);		errno = error;		return -1;	} else if (res == 0) {		faimdprintf(sess, 0, "aim_conn_completeconnect: false alarm on %d\n", conn->fd);		return 0; /* hasn't really completed yet... */	} 	if (FD_ISSET(conn->fd, &fds) || FD_ISSET(conn->fd, &wfds)) {		int len = sizeof(error);		if (getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)			error = errno;	}	if (error) {		aim_conn_close(conn);		errno = error;		return -1;	}	fcntl(conn->fd, F_SETFL, 0); /* XXX should restore original flags */	conn->status &= ~AIM_CONN_STATUS_INPROGRESS;	if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE)))		userfunc(sess, NULL, conn);	/* Flush out the queues if there was something waiting for this conn  */	aim_tx_flushqueue(sess);	return 0;}faim_export aim_session_t *aim_conn_getsess(aim_conn_t *conn){	if (!conn)		return NULL;	return (aim_session_t *)conn->sessv;}/* * aim_logoff() * * Closes -ALL- open connections. * */faim_export int aim_logoff(aim_session_t *sess){	aim_connrst(sess);  /* in case we want to connect again */	return 0;}/* * aim_flap_nop() * * No-op.  WinAIM 4.x sends these _every minute_ to keep * the connection alive.   */faim_export int aim_flap_nop(aim_session_t *sess, aim_conn_t *conn){	aim_frame_t *fr;	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x05, 0)))		return -ENOMEM;	aim_tx_enqueue(sess, fr);	return 0;}

⌨️ 快捷键说明

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