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

📄 xchat.c

📁 The major functionality added in this release includes: - Rootless mode in X11 - Widget Templt
💻 C
📖 第 1 页 / 共 2 页
字号:
/* X-Chat * Copyright (C) 1998 Peter Zelezny. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <time.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#define WANTSOCKET#include "inet.h"#ifndef WIN32#include <sys/wait.h>#include <signal.h>#endif#include "xchat.h"#include "fe.h"#include "util.h"#include "cfgfiles.h"#include "ignore.h"#include "plugin.h"#include "notify.h"#include "server.h"#include "pythonc.h"#include "outbound.h"#include "text.h"#include "perlc.h"#include "xchatc.h"#ifdef USE_OPENSSL#include <openssl/ssl.h>		  /* SSL_() */#include "ssl.h"#endif#ifdef USE_JCODE#include "jcode.h"#endifGSList *popup_list = 0;GSList *button_list = 0;GSList *dlgbutton_list = 0;GSList *command_list = 0;GSList *ctcp_list = 0;GSList *replace_list = 0;GSList *sess_list = 0;GSList *serv_list = 0;GSList *dcc_list = 0;GSList *ignore_list = 0;GSList *usermenu_list = 0;GSList *urlhandler_list = 0;static GSList *away_list = 0;static int in_xchat_exit = FALSE;int xchat_is_quitting = FALSE;int auto_connect = TRUE;struct session *current_tab;struct session *menu_sess = 0;struct xchatprefs prefs;#ifdef USE_OPENSSLSSL_CTX *ctx = NULL;void ssl_cb_info (SSL * s, int where, int ret);#endifstatic void free_away_messages (server *serv);/* actually send to the socket. This might do a character translation or   send via SSL */static inttcp_send_real (struct server *serv, char *buf, int len){	int ret = 1;	unsigned char *tbuf = buf;#ifdef USE_TRANS#define TRANS_STAT_BUF_LEN 1024	static unsigned char sbuf[TRANS_STAT_BUF_LEN];	if (prefs.use_trans)	{		if (len >= TRANS_STAT_BUF_LEN)			tbuf = malloc (len + 1);		else			tbuf = sbuf;		if (!tbuf)			return -1;		strcpy (tbuf, buf);		user2serv (tbuf);	}#endif	fe_add_rawlog (serv, tbuf, TRUE);	if (!EMIT_SIGNAL (XP_IF_SEND, (void *) serv->sok, tbuf, (void *)len,							NULL, NULL, 0))	{#ifdef USE_OPENSSL		if (!serv->ssl)			ret = send (serv->sok, tbuf, len, 0);		else			ret = _SSL_send (serv->ssl, tbuf, len);#else		ret = send (serv->sok, tbuf, len, 0);#endif	}#ifdef USE_TRANS	if (prefs.use_trans)	{		if (tbuf != sbuf)			free (tbuf);	}#endif	return ret;}/* new throttling system, uses the same method as the Undernet   ircu2.10 server; under test, a 200-line paste didn't flood   off the client */static inttcp_send_queue (struct server *serv){	char *buf, *p;	int len, i;	GSList *list;	time_t now = time (0);	/* did the server close since the timeout was added? */	if (!is_server (serv))		return 0;	list = serv->outbound_queue;	while (list)	{		buf = (char *) list->data;		len = strlen (buf);		if (serv->next_send < now)			serv->next_send = now;		if (serv->next_send - now >= 10)			return 1;				  /* don't remove the timeout handler */		for (p = buf, i = len; i && *p != ' '; p++, i--);			serv->next_send += (2 + i / 120);		serv->sendq_len -= len;		fe_set_throttle (serv);		tcp_send_real (serv, buf, len);		serv->outbound_queue = g_slist_remove (serv->outbound_queue, buf);		free (buf);		list = serv->outbound_queue;	}	return 0;						  /* remove the timeout handler */}#ifdef USE_JCODEstatic voidfe_add_ja_rawlog (struct server *serv, char *buf,  int outbound){	char *jbuf =  kanji_conv_to_locale(buf);	if (jbuf)	{		fe_add_rawlog (serv, jbuf, TRUE);		free(jbuf);	} else			fe_add_rawlog (serv, buf, TRUE);}#endifinttcp_send_len (struct server *serv, char *buf, int len){    char *dbuf;    int noqueue = !serv->outbound_queue;#ifdef USE_JCODE    unsigned char *jbuf = NULL;    if ( prefs.kanji_conv ) {        jbuf = kanji_conv_auto(buf, "ISO-2022-JP");        if (!jbuf)            return 0;        else {            buf = strdup(jbuf); free(jbuf);            len = strlen(buf);        }    } else        buf = strdup(buf); /* freed after all */#endif    	if (!prefs.throttle)		return tcp_send_real (serv, buf, len);	dbuf = malloc (len + 1);	memcpy (dbuf, buf, len);	dbuf[len] = 0;	/* only privmsg and notice go to the back of the queue */	if (strncasecmp (dbuf, "PRIVMSG", 7) == 0 ||		 strncasecmp (dbuf, "NOTICE", 6) == 0)		serv->outbound_queue = g_slist_append (serv->outbound_queue, dbuf);	else		serv->outbound_queue = g_slist_prepend (serv->outbound_queue, dbuf);	serv->sendq_len += len; /* tcp_send_queue uses strlen */	if (tcp_send_queue (serv) && noqueue)		fe_timeout_add (500, tcp_send_queue, serv);    	return 1;}inttcp_send (struct server *serv, char *buf){	return tcp_send_len (serv, buf, strlen (buf));}static intis_in_list (GSList *list, void *data){	while (list)	{		if (list->data == data)			return TRUE;		list = list->next;	}	return FALSE;}intis_server (server * serv){	return is_in_list (serv_list, serv);}intis_session (session * sess){	return is_in_list (sess_list, sess);}struct session *find_dialog (struct server *serv, char *nick){	GSList *list = sess_list;	struct session *sess;	while (list)	{		sess = (struct session *) list->data;		if (sess->server == serv && sess->type == SESS_DIALOG)		{			if (!strcasecmp (nick, sess->channel))				return (sess);		}		list = list->next;	}	return 0;}session *find_session_from_channel (char *chan, server *serv){	session *sess;	GSList *list = sess_list;	while (list)	{		sess = list->data;		if (sess->type != SESS_SHELL && !strcasecmp (chan, sess->channel))		{			if (!serv || serv == sess->server)				return sess;		}		list = list->next;	}	return 0;}#ifndef WIN32static intmail_items (char *file){	FILE *fp;	int items;	char buf[512];	fp = fopen (file, "r");	if (!fp)		return 1;	items = 0;	while (fgets (buf, sizeof buf, fp))	{		if (!strncmp (buf, "From ", 5))			items++;	}	fclose (fp);	return items;}static voidxchat_mail_check (void){	static int last_size = -1;	int size;	struct stat st;	char buf[512];	char *maildir;	maildir = getenv ("MAIL");	if (!maildir)	{		snprintf (buf, sizeof (buf), "/var/spool/mail/%s", g_get_user_name ());		maildir = buf;	}	if (stat (maildir, &st) < 0)		return;	size = st.st_size;	if (last_size == -1)	{		last_size = size;		return;	}	if (size > last_size)	{		sprintf (buf, "%d", mail_items (maildir));		sprintf (buf + 16, "%d", size);		if (menu_sess && menu_sess->type != SESS_SHELL)			EMIT_SIGNAL (XP_TE_NEWMAIL, menu_sess, buf, buf + 16, NULL, NULL, 0);	}	last_size = size;}#endifstatic intlagcheck_update (void){	server *serv;	GSList *list = serv_list;		if (!prefs.lagometer)		return 1;	while (list)	{		serv = list->data;		if (serv->lag_sent)			fe_set_lag (serv, -1);		list = list->next;	}	return 1;}voidlag_check (void){	server *serv;	GSList *list = serv_list;	unsigned long tim;	char tbuf[256];	time_t now = time (0);	int lag;	tim = make_ping_time ();	while (list)	{		serv = list->data;		if (serv->connected && serv->end_of_motd)		{			lag = now - serv->ping_recv;			if (prefs.pingtimeout && lag > prefs.pingtimeout && lag > 0)			{				sprintf (tbuf, "%d", lag);				EMIT_SIGNAL (XP_TE_PINGTIMEOUT, serv->front_session, tbuf, NULL,								 NULL, NULL, 0);				auto_reconnect (serv, FALSE, -1);			} else			{				/*sprintf (tbuf, "PING LAG%lu :%s\r\n", tim, serv->servername);*/				sprintf (tbuf, "PING LAG%lu\r\n", tim);				tcp_send (serv, tbuf);				serv->lag_sent = tim;				fe_set_lag (serv, -1);			}		}		list = list->next;	}}static intxchat_misc_checks (void)		  /* this gets called every 2 seconds */{	static int count = 0;	dcc_check_timeouts ();	count++;	if (count == 7 && prefs.lagometer)	/* every 30 seconds */		lag_check ();	if (count == 15)							/* every 30 seconds */	{		count = 0;#ifndef WIN32		if (prefs.mail_check)			xchat_mail_check ();#endif	}	return 1;}/* executed when the first irc window opens */static voidirc_init (session *sess){	static int done_init = FALSE;	if (done_init)		return;	done_init = TRUE;#ifdef USE_PYTHON	pys_init ();#endif#ifdef USE_PLUGIN	module_setup ();#endif#ifdef USE_PERL	perl_auto_load (sess);#endif	if (prefs.notify_timeout)		notify_tag = fe_timeout_add (prefs.notify_timeout * 1000,											  notify_checklist, 0);	fe_timeout_add (2000, xchat_misc_checks, 0);	fe_timeout_add (500, lagcheck_update, 0);}static session *new_session (server *serv, char *from, int type){	session *sess;	sess = malloc (sizeof (struct session));	memset (sess, 0, sizeof (struct session));	sess->server = serv;	sess->logfd = -1;	sess->type = type;	sess->current_modes = strdup ("");	if (from != NULL)		safe_strcpy (sess->channel, from, CHANLEN);	sess_list = g_slist_prepend (sess_list, sess);	fe_new_window (sess);	return sess;}voidset_server_defaults (server *serv){	if (serv->chantypes)		free (serv->chantypes);	if (serv->chanmodes)		free (serv->chanmodes);	if (serv->nick_prefixes)		free (serv->nick_prefixes);	if (serv->nick_modes)		free (serv->nick_modes);	serv->chantypes = strdup ("#&!+");	serv->chanmodes = strdup ("beI,k,l");	serv->nick_prefixes = strdup ("@%+");	serv->nick_modes = strdup ("ohv");	serv->nickcount = 1;	serv->end_of_motd = FALSE;	serv->is_away = FALSE;	serv->supports_watch = FALSE;	serv->bad_prefix = FALSE;}static server *new_server (void){	server *serv;	serv = malloc (sizeof (struct server));	memset (serv, 0, sizeof (struct server));	serv->sok = -1;	strcpy (serv->nick, prefs.nick1);	set_server_defaults (serv);	serv_list = g_slist_prepend (serv_list, serv);	fe_new_server (serv);	return serv;}session *new_ircwindow (server *serv, char *name, int type){	session *sess;	switch (type)	{	case SESS_SHELL:		sess = new_session (new_server (), name, SESS_SHELL);		break;	case SESS_SERVER:		serv = new_server ();		if (prefs.use_server_tab)		{			register unsigned int oldh = prefs.hideuserlist;			prefs.hideuserlist = 1;			sess = new_session (serv, name, SESS_SERVER);			prefs.hideuserlist = oldh;			serv->front_session = sess;		} else		{			sess = new_session (serv, name, SESS_CHANNEL);		}		break;	default:

⌨️ 快捷键说明

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