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

📄 server.c

📁 The major functionality added in this release includes: - Rootless mode in X11 - Widget Templt
💻 C
📖 第 1 页 / 共 2 页
字号:
						 NULL, NULL, 0);		if (prefs.autoreconnectonfail)			auto_reconnect (serv, FALSE, -1);		break;	case '3':						  /* gethostbyname finished */		waitline2 (source, host, sizeof host);		waitline2 (source, ip, sizeof ip);		waitline2 (source, outbuf, sizeof outbuf);		EMIT_SIGNAL (XP_TE_CONNECT, sess, host, ip, outbuf, NULL, 0);		break;	case '4':						  /* success */		waitline2 (source, tbuf, sizeof (tbuf));		serv->sok = atoi (tbuf);#ifdef USE_IPV6		/* close the one we didn't end up using */		if (serv->sok == serv->sok4)			closesocket (serv->sok6);		else			closesocket (serv->sok4);#endif#ifdef USE_OPENSSL#define	SSLDOCONNTMOUT	300		if (serv->use_ssl)		{			char *err;			/* it'll be a memory leak, if connection isn't terminated by			   server_cleanup() */			serv->ssl = _SSL_socket (ctx, serv->sok);			if ((err = _SSL_set_verify (ctx, ssl_cb_verify, NULL)))			{				EMIT_SIGNAL (XP_TE_CONNFAIL, serv->front_session, err, NULL,								 NULL, NULL, 0);				server_cleanup (serv);	/* ->connecting = FALSE */				return TRUE;			}			/* FIXME: it'll be needed by new servers */			/* send(serv->sok, "STLS\r\n", 6, 0); sleep(1); */			set_nonblocking (serv->sok);			serv->ssl_do_connect_tag = fe_timeout_add (SSLDOCONNTMOUT,																	 ssl_do_connect, serv);		} else		{			serv->ssl = NULL;#endif			server_stopconnecting (serv);	/* ->connecting = FALSE */			/* activate gtk poll */			server_connected (serv);#ifdef USE_OPENSSL		}#endif		break;	case '5':						  /* prefs ip discovered */		waitline2 (source, tbuf, sizeof tbuf);		prefs.local_ip = inet_addr (tbuf);		break;	case '7':						  /* gethostbyname (prefs.hostname) failed */		sprintf (outbuf,					"Cannot resolve hostname %s\nCheck your IP Settings!\n",					prefs.hostname);		PrintText (sess, outbuf);		break;	case '8':		PrintText (sess, "Proxy traversal failed.\n");		disconnect_server (sess, FALSE, -1);		break;	case '9':		waitline2 (source, tbuf, sizeof tbuf);		EMIT_SIGNAL (XP_TE_SERVERLOOKUP, sess, tbuf, NULL, NULL, NULL, 0);		break;	}	return TRUE;}static voidserver_stopconnecting (server * serv){	if (serv->iotag)	{		fe_input_remove (serv->iotag);		serv->iotag = 0;	}#ifndef WIN32	/* kill the child process trying to connect */	kill (serv->childpid, SIGKILL);	waitpid (serv->childpid, NULL, 0);#else	TerminateThread ((HANDLE)serv->childpid, 0);	CloseHandle ((HANDLE)serv->childpid);#endif	close (serv->childwrite);	close (serv->childread);#ifdef USE_OPENSSL	if (serv->ssl_do_connect_tag)	{		fe_timeout_remove (serv->ssl_do_connect_tag);		serv->ssl_do_connect_tag = 0;	}#endif	fe_progressbar_end (serv->front_session);	serv->connecting = FALSE;}/* kill all sockets & iotags of a server. Stop a connection attempt, or   disconnect if already connected. */intserver_cleanup (server * serv){	fe_set_lag (serv, 0.0);	if (serv->iotag)	{		fe_input_remove (serv->iotag);		serv->iotag = 0;	}#ifdef USE_OPENSSL	if (serv->ssl)	{		_SSL_close (serv->ssl);		serv->ssl = NULL;	}#endif	if (serv->connecting)	{		server_stopconnecting (serv);		closesocket (serv->sok4);		if (serv->sok6 >= 0)			closesocket (serv->sok6);		return 1;	}	if (serv->connected)	{		close_socket (serv->sok);		serv->connected = FALSE;		return 2;	}	/* is this server in a reconnect delay? remove it! */	if (serv->recondelay_tag)	{		fe_timeout_remove (serv->recondelay_tag);		serv->recondelay_tag = 0;		return 3;	}	return 0;}voiddisconnect_server (session * sess, int sendquit, int err){	server *serv = sess->server;	GSList *list;	char tbuf[64];	/* send our QUIT reason */	if (sendquit && serv->connected)		server_sendquit (sess);	/* close all sockets & io tags */	switch (server_cleanup (serv))	{	case 0:							  /* it wasn't even connected! */		notc_msg (sess);		return;	case 1:							  /* it was in the process of connecting */		sprintf (tbuf, "%d", sess->server->childpid);		EMIT_SIGNAL (XP_TE_SCONNECT, sess, tbuf, NULL, NULL, NULL, 0);		return;	}	flush_server_queue (serv);	list = sess_list;	while (list)					  /* print "Disconnected" to each window using this server */	{		sess = (struct session *) list->data;		if (sess->server == serv)			EMIT_SIGNAL (XP_TE_DISCON, sess, errorstring (err), NULL, NULL, NULL,							 0);		list = list->next;	}	serv->pos = 0;	serv->motd_skipped = FALSE;	serv->no_login = FALSE;	serv->servername[0] = 0;	list = sess_list;	while (list)	{		sess = (struct session *) list->data;		if (sess->server == serv)		{			if (sess->channel[0])			{				if (sess->type == SESS_CHANNEL)				{					clear_channel (sess);				}			} else			{				clear_channel (sess);			}		}		list = list->next;	}	notify_cleanup ();}struct sock_connect{	char version;	char type;	unsigned short port;	unsigned long address;	char username[10];};/* traverse_socks() returns: *				0 success                * *          1 socks traversal failed */static inttraverse_socks (int sok, char *serverAddr, int port){	struct sock_connect sc;	unsigned char buf[10];	sc.version = 4;	sc.type = 1;	sc.port = htons (port);	sc.address = inet_addr (serverAddr);	strncpy (sc.username, prefs.username, 9);	send (sok, (char *) &sc, 8 + strlen (sc.username) + 1, 0);	buf[1] = 0;	recv (sok, buf, 10, 0);	if (buf[1] == 90)		return 0;	return 1;}struct sock5_connect1{	char version;	char nmethods;	char method;};static inttraverse_socks5 (int sok, char *serverAddr, int port){	struct sock5_connect1 sc1;	unsigned char *sc2;	unsigned int packetlen, addrlen;	unsigned char buf[10];	sc1.version = 5;	sc1.nmethods = 1;	sc1.method = 0;	send (sok, (char *) &sc1, 3, 0);	if (recv (sok, buf, 2, 0) != 2)		return 1;	if (buf[0] != 5 && buf[1] != 0)		return 1;	addrlen = strlen (serverAddr);	packetlen = 4 + 1 + addrlen + 2;	sc2 = malloc (packetlen);	sc2[0] = 5;						  /* version */	sc2[1] = 1;						  /* command */	sc2[2] = 0;						  /* reserved */	sc2[3] = 3;						  /* address type */	sc2[4] = (unsigned char) addrlen;	/* hostname length */	memcpy (sc2 + 5, serverAddr, addrlen);	*((unsigned short *) (sc2 + 5 + addrlen)) = htons (port);	send (sok, sc2, packetlen, 0);	/* consume all of the reply */	if (recv (sok, buf, 4, 0) != 4)		return 1;	if (buf[0] != 5 && buf[1] != 0)		return 1;	if (buf[3] == 1)	{		if (recv (sok, buf, 6, 0) != 6)			return 1;	} else if (buf[3] == 4)	{		if (recv (sok, buf, 18, 0) != 18)			return 1;	} else if (buf[3] == 3)	{		if (recv (sok, buf, 1, 0) != 1)			return 1;		packetlen = buf[0] + 2;		if (recv (sok, buf, packetlen, 0) != packetlen)			return 1;	}	return 0;}static inttraverse_wingate (int sok, char *serverAddr, int port){	char buf[128];	snprintf (buf, sizeof (buf), "%s %d\r\n", serverAddr, port);	send (sok, buf, strlen (buf), 0);	return 0;}static inttraverse_http (int sok, char *serverAddr, int port){	char buf[128];	int n;	n = snprintf (buf, sizeof (buf), "CONNECT %s:%d HTTP/1.1\r\n\r\n",					  serverAddr, port);	send (sok, buf, n, 0);#ifndef WIN32	waitline (sok, buf, sizeof (buf)); /* FIXME: win32 cant read() sok */	/* "HTTP/1.0 200 OK" */	if (strlen (buf) < 12)		return 1;	if (memcmp (buf, "HTTP/", 5) || memcmp (buf + 9, "200", 3))		return 1;	for (;;)	{		/* read until blank line */		waitline (sok, buf, sizeof (buf));		if (!buf[0] || (buf[0] == '\r' && !buf[1]))			break;	}#endif	return 0;}static inttraverse_proxy (int sok, char *ip, int port){	switch (prefs.proxy_type)	{	case 1:		return traverse_wingate (sok, ip, port);	case 2:		return traverse_socks (sok, ip, port);	case 3:		return traverse_socks5 (sok, ip, port);	case 4:		return traverse_http (sok, ip, port);	}	return 1;}/* this is the child process making the connection attempt */static intserver_child (server * serv){	netstore *ns_server;	netstore *ns_proxy = NULL;	netstore *ns_local;	int port = serv->port;	int error;	int sok;	char *hostname = serv->hostname;	char *real_hostname = NULL;	char *ip;	char *proxy_ip = NULL;	char *local_ip;	int connect_port;	FILE *fd;	fd = fdopen (serv->childwrite, "w");	ns_server = net_store_new ();	/* is a hostname set? - bind to it */	if (prefs.hostname[0])	{		ns_local = net_store_new ();		local_ip = net_resolve (ns_local, prefs.hostname, 0, &real_hostname);		if (local_ip != NULL)		{			fprintf (fd, "5\n%s\n", local_ip);			net_bind (ns_local, serv->sok4, serv->sok6);		} else		{			fprintf (fd, "7\n");		}		net_store_destroy (ns_local);		fflush (fd);	}	/* first resolve where we want to connect to */	if (!serv->dont_use_proxy && prefs.proxy_host[0] && prefs.proxy_type > 0)	{		fprintf (fd, "9\n%s\n", prefs.proxy_host);		fflush (fd);		ip = net_resolve (ns_server, prefs.proxy_host, prefs.proxy_port,								&real_hostname);		if (!ip)		{			fprintf (fd, "1\n");			goto xit;		}		connect_port = prefs.proxy_port;		/* if using socks4, attempt to resolve ip for irc server */		if (prefs.proxy_type == 2)		{			ns_proxy = net_store_new ();			proxy_ip = net_resolve (ns_proxy, hostname, port, &real_hostname);			if (!proxy_ip)			{				fprintf (fd, "1\n");				goto xit;			}		} else						  /* otherwise we can just use the hostname */			proxy_ip = strdup (hostname);	} else	{		ip = net_resolve (ns_server, hostname, port, &real_hostname);		if (!ip)		{			fprintf (fd, "1\n");			goto xit;		}		connect_port = port;	}	fprintf (fd, "3\n%s\n%s\n%d\n", real_hostname, ip, connect_port);	fflush (fd);	error = net_connect (ns_server, serv->sok4, serv->sok6, &sok);	if (error != 0)	{		fprintf (fd, "2\n%d\n", sock_error ());	} else	{		/* connect succeeded */		if (proxy_ip)		{			switch (traverse_proxy (sok, proxy_ip, port))			{			case 0:				fprintf (fd, "4\n%d\n", sok);	/* success */				break;			case 1:				fprintf (fd, "8\n");	  /* socks traversal failed */				break;			}		} else		{			fprintf (fd, "4\n%d\n", sok);		}	}xit:	fflush (fd);	net_store_destroy (ns_server);	if (ns_proxy)		net_store_destroy (ns_proxy);	/* no need to free ip/real_hostname, this process is exiting */#ifdef WIN32	/* under win32 we use a thread -> shared memory, must free! */	if (proxy_ip)		free (proxy_ip);	if (ip)		free (ip);	if (real_hostname)		free (real_hostname);#endif	return 0;}voidconnect_server (session * sess, char *hostname, int port, int no_login){	int pid, read_des[2];	server *serv = sess->server;	if (!hostname[0])		return;	sess = serv->front_session;	if (serv->connected || serv->connecting || serv->recondelay_tag)		disconnect_server (sess, TRUE, -1);	fe_progressbar_start (sess);	EMIT_SIGNAL (XP_TE_SERVERLOOKUP, sess, hostname, NULL, NULL, NULL, 0);	strcpy (serv->servername, hostname);	strcpy (serv->hostname, hostname);	set_server_defaults (serv);	serv->connecting = TRUE;	serv->port = port;	serv->no_login = no_login;	fe_set_away (serv);	flush_server_queue (serv);	/* pipe is #defined on win32 in gwin32.h to use _pipe and O_BINARY */	if (pipe (read_des) < 0)		return;#ifdef __EMX__ /* os/2 */	setmode (read_des[0], O_BINARY);	setmode (read_des[1], O_BINARY);#endif	serv->childread = read_des[0];	serv->childwrite = read_des[1];	/* create both sockets now, drop one later */	net_sockets (&serv->sok4, &serv->sok6);#ifdef WIN32	pid = (int)CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)server_child,									 serv, 0, (DWORD *)&pid);#else	switch (pid = fork ())	{	case -1:		return;	case 0:		/* this is the child */		setuid (getuid ());		server_child (serv);		_exit (0);	}#endif	serv->childpid = pid;	/* the 3 tells input_add that it's a fd, not a socket */	serv->iotag =		fe_input_add (serv->childread, 3, 0, 0, connected_signal, serv);}

⌨️ 快捷键说明

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