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

📄 dcc.c

📁 The major functionality added in this release includes: - Rootless mode in X11 - Widget Templt
💻 C
📖 第 1 页 / 共 2 页
字号:
			return TRUE;		dcc_send_data (NULL, 0, (gpointer)dcc);	}	if (dcc->pos >= dcc->size && dcc->ack >= dcc->size)	{		dcc_close (dcc, STAT_DONE, FALSE);		sprintf (buf, "%d", dcc->cps);		EMIT_SIGNAL (XP_TE_DCCSENDCOMP, dcc->serv->front_session,						 file_part (dcc->file), dcc->nick, buf, NULL, 0);	}	return TRUE;}static gbooleandcc_accept (GIOChannel *source, GIOCondition condition, struct DCC *dcc){	char host[128];	struct sockaddr_in CAddr;	int sok;	size_t len;	len = sizeof (CAddr);	sok = accept (dcc->sok, (struct sockaddr *) &CAddr, &len);	fe_input_remove (dcc->iotag);	dcc->iotag = 0;	closesocket (dcc->sok);	if (sok < 0)	{		dcc->sok = -1;		dcc_close (dcc, STAT_FAILED, FALSE);		return TRUE;	}	set_nonblocking (sok);	dcc->sok = sok;	dcc->addr = ntohl (CAddr.sin_addr.s_addr);	dcc->dccstat = STAT_ACTIVE;	dcc->lasttime = dcc->starttime = time (0);	dcc->fastsend = prefs.fastdccsend;	switch (dcc->type)	{	case TYPE_SEND:		if (dcc->fastsend)			dcc->wiotag = fe_input_add (sok, 0, 1, 0, dcc_send_data, dcc);		dcc->iotag = fe_input_add (sok, 1, 0, 1, dcc_read_ack, dcc);		dcc_send_data (NULL, 0, (gpointer)dcc);		break;	case TYPE_CHATSEND:		dcc->iotag = fe_input_add (dcc->sok, 1, 0, 1, dcc_read_chat, dcc);		dcc->dccchat = malloc (sizeof (struct dcc_chat));		dcc->dccchat->pos = 0;		break;	}	update_dcc_window (dcc->type);	snprintf (host, sizeof host, "%s:%d", net_ip (dcc->addr), dcc->port);	EMIT_SIGNAL (XP_TE_DCCCON, dcc->serv->front_session,					 dcctypes[(int) dcc->type], dcc->nick, host, "from", 0);	return TRUE;}static intdcc_listen_init (struct DCC *dcc, session *sess){	size_t len;	unsigned long my_addr;	struct sockaddr_in SAddr;	int i, bindretval = -1;	dcc->sok = socket (AF_INET, SOCK_STREAM, 0);	if (dcc->sok == -1)		return FALSE;	memset (&SAddr, 0, sizeof (struct sockaddr_in));	len = sizeof (SAddr);	getsockname (dcc->serv->sok, (struct sockaddr *) &SAddr, &len);	SAddr.sin_family = AF_INET;	/*if local_ip is specified use that*/	if (prefs.local_ip != 0)	{		my_addr = prefs.local_ip;		SAddr.sin_addr.s_addr = prefs.local_ip;	}	/*otherwise use the default*/	else		my_addr = SAddr.sin_addr.s_addr;	/*if we have a valid portrange try to use that*/	if (prefs.first_dcc_send_port > 0)	{		SAddr.sin_port = 0;		i = 0;		while ((prefs.last_dcc_send_port > ntohs(SAddr.sin_port)) &&				(bindretval == -1))		{			SAddr.sin_port = htons (prefs.first_dcc_send_port + i);			i++;			/*printf("Trying to bind against port: %d\n",ntohs(SAddr.sin_port));*/			bindretval = bind (dcc->sok, (struct sockaddr *) &SAddr, sizeof (SAddr));		}	}	/*if we didnt bind yet, try a random port*/	if (bindretval == -1)	{		SAddr.sin_port = 0;		bindretval = bind (dcc->sok, (struct sockaddr *) &SAddr, sizeof (SAddr));	}	if (bindretval == -1)	{		/* failed to bind */		PrintText (sess, "Failed to bind to any address or port.\n");		return FALSE;	}	len = sizeof (SAddr);	getsockname (dcc->sok, (struct sockaddr *) &SAddr, &len);	dcc->port = ntohs (SAddr.sin_port);	/*if we have a dcc_ip, we use that, so the remote client can connect*/	/*we would tell the client to connect to our LAN ip otherwise*/	if (prefs.ip_from_server != 0 && prefs.dcc_ip != 0)		dcc->addr = prefs.dcc_ip;	else if (prefs.dcc_ip_str[0])		dcc->addr = inet_addr ((const char *) prefs.dcc_ip_str);	else	/*else we use the one we bound to*/		dcc->addr = my_addr;	dcc->addr = ntohl (dcc->addr);	set_nonblocking (dcc->sok);	listen (dcc->sok, 1);	set_blocking (dcc->sok);	dcc->iotag = fe_input_add (dcc->sok, 1, 0, 1, dcc_accept, dcc);	return TRUE;}static struct session *dccsess;static char *dccto;				  /* lame!! */static char *dcctbuf;static voiddcc_send_wild (char *file){	dcc_send (dccsess, dcctbuf, dccto, file);}/* tbuf is at least 400 bytes */voiddcc_send (struct session *sess, char *tbuf, char *to, char *file){	struct stat st;	struct DCC *dcc = new_dcc ();	if (!dcc)		return;	dcc->file = expand_homedir (file);	if (strchr (dcc->file, '*') || strchr (dcc->file, '?'))	{		char path[256];		char wild[256];		strcpy (wild, file_part (dcc->file));		path_part (dcc->file, path);		path[strlen (path) - 1] = 0;	/* remove trailing slash */		dccsess = sess;		dccto = to;		dcctbuf = tbuf;		for_files (path, wild, dcc_send_wild);		dcc_close (dcc, 0, TRUE);		return;	}	if (stat (dcc->file, &st) != -1)	{		if (*file_part (dcc->file) && !S_ISDIR (st.st_mode))		{			if (st.st_size > 0)			{				dcc->offertime = time (0);				dcc->serv = sess->server;				dcc->dccstat = STAT_QUEUED;				dcc->size = st.st_size;				dcc->type = TYPE_SEND;				dcc->fp = open (dcc->file, OFLAGS | O_RDONLY);				if (dcc->fp != -1)				{					if (dcc_listen_init (dcc, sess))					{						char havespaces = 0;						file = dcc->file;						while (*file)						{							if (*file == ' ')							{								if (prefs.dcc_send_fillspaces)						    		*file = '_';							  	else							   	havespaces = 1;							}							file++;						}						dcc->nick = strdup (to);						if (prefs.autoopendccsendwindow)							fe_dcc_open_send_win (TRUE);						else							fe_dcc_update_send_win ();												if (havespaces)						{							snprintf (tbuf, 400,									 "PRIVMSG %s :\001DCC SEND \"%s\" %lu %d %d\001\r\n",									 to, file_part (dcc->file), dcc->addr, dcc->port,									 dcc->size);						}						else						{							snprintf (tbuf, 400,									 "PRIVMSG %s :\001DCC SEND %s %lu %d %d\001\r\n",									 to, file_part (dcc->file), dcc->addr, dcc->port,									 dcc->size);						}						tcp_send (sess->server, tbuf);						EMIT_SIGNAL (XP_TE_DCCOFFER, sess, file_part (dcc->file),										 to, NULL, NULL, 0);					} else					{						dcc_close (dcc, 0, TRUE);					}					return;				}			}		}	}	snprintf (tbuf, 400, _("Cannot access %s\n"), dcc->file);	PrintText (sess, tbuf);	dcc_close (dcc, 0, TRUE);}static struct DCC *find_dcc_from_port (int port, int type){	struct DCC *dcc;	GSList *list = dcc_list;	while (list)	{		dcc = (struct DCC *) list->data;		if (dcc->port == port &&			 dcc->dccstat == STAT_QUEUED && dcc->type == type)			return dcc;		list = list->next;	}	return 0;}struct DCC *find_dcc (char *nick, char *file, int type){	GSList *list = dcc_list;	struct DCC *dcc;	while (list)	{		dcc = (struct DCC *) list->data;		if (nick == NULL || !strcasecmp (nick, dcc->nick))		{			if (type == -1 || dcc->type == type)			{				if (!file[0])					return dcc;				if (!strcasecmp (file, file_part (dcc->file)))					return dcc;				if (!strcasecmp (file, dcc->file))					return dcc;			}		}		list = list->next;	}	return 0;}/* called when we receive a NICK change from server */voiddcc_change_nick (struct server *serv, char *oldnick, char *newnick){	struct DCC *dcc;	GSList *list = dcc_list;	while (list)	{		dcc = (struct DCC *) list->data;		if (dcc->serv == serv)		{			if (!strcasecmp (dcc->nick, oldnick))			{				if (dcc->nick)					free (dcc->nick);				dcc->nick = strdup (newnick);			}		}		list = list->next;	}}voiddcc_get (struct DCC *dcc){	switch (dcc->dccstat)	{	case STAT_QUEUED:		if (dcc->type != TYPE_CHATSEND)		{			dcc->resumable = 0;			dcc->pos = 0;			dcc_connect (dcc);		}		break;	case STAT_DONE:	case STAT_FAILED:	case STAT_ABORTED:		dcc_close (dcc, 0, TRUE);		break;	}}voiddcc_get_nick (struct session *sess, char *nick){	struct DCC *dcc;	GSList *list = dcc_list;	while (list)	{		dcc = (struct DCC *) list->data;		if (!strcasecmp (nick, dcc->nick))		{			if (dcc->dccstat == STAT_QUEUED && dcc->type == TYPE_RECV)			{				dcc->resumable = 0;				dcc->pos = 0;				dcc->ack = 0;				dcc_connect (dcc);				return;			}		}		list = list->next;	}	if (sess)		EMIT_SIGNAL (XP_TE_DCCIVAL, sess, NULL, NULL, NULL, NULL, 0);}static struct DCC *new_dcc (void){	struct DCC *dcc = malloc (sizeof (struct DCC));	if (!dcc)		return 0;	memset (dcc, 0, sizeof (struct DCC));	dcc->sok = -1;	dcc->fp = -1;	dcc_list = g_slist_prepend (dcc_list, dcc);	return (dcc);}voiddcc_chat (struct session *sess, char *nick){	char outbuf[400];	struct DCC *dcc;	dcc = find_dcc (nick, "", TYPE_CHATSEND);	if (dcc)	{		switch (dcc->dccstat)		{		case STAT_ACTIVE:		case STAT_QUEUED:		case STAT_CONNECTING:			EMIT_SIGNAL (XP_TE_DCCCHATREOFFER, sess, nick, NULL, NULL, NULL, 0);			return;		case STAT_ABORTED:		case STAT_FAILED:			dcc_close (dcc, 0, TRUE);		}	}	dcc = find_dcc (nick, "", TYPE_CHATRECV);	if (dcc)	{		switch (dcc->dccstat)		{		case STAT_QUEUED:			dcc_connect (dcc);			break;		case STAT_FAILED:		case STAT_ABORTED:			dcc_close (dcc, 0, TRUE);		}		return;	}	/* offer DCC CHAT */	dcc = new_dcc ();	if (!dcc)		return;	dcc->starttime = dcc->offertime = time (0);	dcc->serv = sess->server;	dcc->dccstat = STAT_QUEUED;	dcc->type = TYPE_CHATSEND;	dcc->nick = strdup (nick);	if (dcc_listen_init (dcc, sess))	{		if (prefs.autoopendccchatwindow)			fe_dcc_open_chat_win (TRUE);		else			fe_dcc_update_chat_win ();		snprintf (outbuf, sizeof (outbuf),					 "PRIVMSG %s :\001DCC CHAT chat %lu %d\001\r\n", nick,					 dcc->addr, dcc->port);		tcp_send (dcc->serv, outbuf);		EMIT_SIGNAL (XP_TE_DCCCHATOFFERING, sess, nick, NULL, NULL, NULL, 0);	} else	{		dcc_close (dcc, 0, TRUE);	}}static voiddcc_malformed (struct session *sess, char *nick, char *data){	EMIT_SIGNAL (XP_TE_MALFORMED_FROM, sess, nick, NULL, NULL, NULL, 0);	EMIT_SIGNAL (XP_TE_MALFORMED_PACKET, sess, data, NULL, NULL, NULL, 0);}voiddcc_resume (struct DCC *dcc){	char tbuf[400];	if (dcc->dccstat == STAT_QUEUED && dcc->resumable)	{		if (strchr (dcc->file, ' ') != NULL)		{	/*filename contains spaces*/			snprintf (tbuf, sizeof (tbuf),						 "PRIVMSG %s :\001DCC RESUME \"%s\" %d %d\001\r\n", dcc->nick,						 dcc->file, dcc->port, dcc->resumable);		}		else		{			snprintf (tbuf, sizeof (tbuf),						 "PRIVMSG %s :\001DCC RESUME %s %d %d\001\r\n", dcc->nick,						 dcc->file, dcc->port, dcc->resumable);		}		tcp_send (dcc->serv, tbuf);	}}voidhandle_dcc (struct session *sess, char *outbuf, char *nick, char *word[],				char *word_eol[]){	struct DCC *dcc;	char *type = word[5];	int port, size;	unsigned long addr;	if (!strcasecmp (type, "CHAT"))	{		port = atoi (word[8]);		sscanf (word[7], "%lu", &addr);		if (!addr || port < 1024)		{			dcc_malformed (sess, nick, word_eol[4] + 2);			return;		}		dcc = find_dcc (nick, "", TYPE_CHATSEND);		if (dcc)			dcc_close (dcc, 0, TRUE);		dcc = find_dcc (nick, "", TYPE_CHATRECV);		if (dcc)			dcc_close (dcc, 0, TRUE);		dcc = new_dcc ();		if (dcc)		{			dcc->serv = sess->server;			dcc->type = TYPE_CHATRECV;			dcc->dccstat = STAT_QUEUED;			dcc->addr = addr;			dcc->port = port;			dcc->nick = strdup (nick);			dcc->starttime = time (0);			EMIT_SIGNAL (XP_TE_DCCCHATOFFER, sess->server->front_session, nick,							 NULL, NULL, NULL, 0);			if (prefs.autoopendccchatwindow)				fe_dcc_open_chat_win (TRUE);			else				fe_dcc_update_chat_win ();			if (prefs.autodccchat)				dcc_connect (dcc);		}		return;	}	if (!strcasecmp (type, "RESUME"))	{		port = atoi (word[7]);		dcc = find_dcc_from_port (port, TYPE_SEND);		if (!dcc)			dcc = find_dcc (nick, word[6], TYPE_SEND);		if (dcc)		{			dcc->resumable = atoi (word[8]);			if (dcc->resumable < dcc->size)			{				dcc->pos = dcc->resumable;				dcc->ack = dcc->resumable;				lseek (dcc->fp, dcc->pos, SEEK_SET);				if (strchr (file_part (dcc->file), ' ') != NULL)				{	/*filename contains spaces*/					snprintf (outbuf, 400,								 "PRIVMSG %s :\001DCC ACCEPT \"%s\" %d %d\001\r\n", dcc->nick,								 file_part (dcc->file), port, dcc->resumable);				}				else				{					snprintf (outbuf, 400,								 "PRIVMSG %s :\001DCC ACCEPT %s %d %d\001\r\n", dcc->nick,								 file_part (dcc->file), port, dcc->resumable);				}				tcp_send (dcc->serv, outbuf);			}			sprintf (outbuf, "%d", dcc->pos);			EMIT_SIGNAL (XP_TE_DCCRESUMEREQUEST, sess, nick,							 file_part (dcc->file), outbuf, NULL, 0);		}		return;	}	if (!strcasecmp (type, "ACCEPT"))	{		port = atoi (word[7]);		dcc = find_dcc_from_port (port, TYPE_RECV);		if (dcc && dcc->dccstat == STAT_QUEUED)		{			dcc_connect (dcc);			return;		}	}	if (!strcasecmp (type, "SEND"))	{		char *file = file_part (word[6]);		port = atoi (word[8]);		size = atoi (word[9]);		sscanf (word[7], "%lu", &addr);		if (!addr || !size || port < 1024)		{			dcc_malformed (sess, nick, word_eol[4] + 2);			return;		}		dcc = new_dcc ();		if (dcc)		{			struct stat st;			dcc->file = strdup (file);			dcc->destfile =				malloc (strlen (prefs.dccdir) + strlen (nick) + strlen (file) +						  4);			strcpy (dcc->destfile, prefs.dccdir);			if (prefs.dccdir[strlen (prefs.dccdir) - 1] != '/')				strcat (dcc->destfile, "/");			if (prefs.dccwithnick)			{				strcat (dcc->destfile, nick);				strcat (dcc->destfile, ".");			}			strcat (dcc->destfile, file);			dcc->resumable = 0;			if (stat (dcc->destfile, &st) != -1)			{				if (st.st_size < size)					dcc->resumable = st.st_size;			}			dcc->pos = dcc->resumable;			dcc->serv = sess->server;			dcc->type = TYPE_RECV;			dcc->dccstat = STAT_QUEUED;			dcc->addr = addr;			dcc->port = port;			dcc->size = size;			dcc->nick = strdup (nick);			if (prefs.autodccsend)			{				if (prefs.autoresume && dcc->resumable)				{					/* don't resume the same file from two people! */					GSList *list = dcc_list;					struct DCC *d;					while (list)					{						d = list->data;						if (d->type == TYPE_RECV && d->dccstat != STAT_ABORTED &&							 d->dccstat != STAT_DONE && d->dccstat != STAT_FAILED)						{							if (d != dcc && strcmp (d->destfile, dcc->destfile) == 0)								goto dontresume;						}						list = list->next;					}					dcc_resume (dcc);				} else				{dontresume:					dcc->resumable = 0;					dcc->pos = 0;					dcc_connect (dcc);				}			}			if (prefs.autoopendccrecvwindow)				fe_dcc_open_recv_win (TRUE);			else				fe_dcc_update_recv_win ();		}		sprintf (outbuf, "%d", size);		EMIT_SIGNAL (XP_TE_DCCSENDOFFER, sess->server->front_session, nick,						 file, outbuf, NULL, 0);	} else		EMIT_SIGNAL (XP_TE_DCCGENERICOFFER, sess->server->front_session,						 word_eol[4] + 2, nick, NULL, NULL, 0);}voiddcc_show_list (struct session *sess, char *outbuf){	int i = 0;	struct DCC *dcc;	GSList *list = dcc_list;	EMIT_SIGNAL (XP_TE_DCCHEAD, sess, NULL, NULL, NULL, NULL, 0);	while (list)	{		dcc = (struct DCC *) list->data;		i++;		snprintf (outbuf, 255, " %-5.5s %-10.10s %-7.7s %-7d %-7d %s\n",					 dcctypes[(int) dcc->type], dcc->nick,					 _(dccstat[(int) dcc->dccstat].name), dcc->size, dcc->pos,					 file_part (dcc->file));		PrintText (sess, outbuf);		list = list->next;	}	if (!i)		PrintText (sess, _("No active DCCs\n"));}

⌨️ 快捷键说明

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