📄 outbound.c
字号:
/* 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 <string.h>#include <stdlib.h>#include <stdio.h>#include <ctype.h>#include <limits.h>#define WANTSOCKET#define WANTARPA#include "inet.h"#ifndef WIN32#include <sys/wait.h>#endif#include <unistd.h>#include <time.h>#include <signal.h>#include <sys/stat.h>#include <fcntl.h>#include "xchat.h"#include "plugin.h"#include "ignore.h"#include "util.h"#include "fe.h"#include "cfgfiles.h" /* get_xdir() */#include "network.h" /* net_ip() */#include "modes.h"#include "notify.h"#include "inbound.h"#include "text.h"#include "xchatc.h"#include "server.h"#include "perlc.h"#include "pythonc.h"#include "outbound.h"#ifdef MEMORY_DEBUGextern int current_mem_usage;#endif#ifdef USE_TRANSstatic unsigned char trans_serv2user[256];static unsigned char trans_user2serv[256];voidserv2user (unsigned char *s){ for (; *s; ++s) *s = trans_serv2user[*s];}voiduser2serv (unsigned char *s){ for (; *s; ++s) *s = trans_user2serv[*s];}intload_trans_table (char *full_path){ int tf, i, st, val = 0, t; char r; if ((tf = open (full_path, OFLAGS | O_RDONLY)) != -1) { st = 0; i = 0; t = 0; while (read (tf, &r, 1) == 1) { switch (st) { case 0: /*nothing yet... */ if (r == '0') st = 1; break; case 1: if (r == 'x') st = 2; else st = 0; break; case 2: if (r <= '9' && r >= '0') val = 16 * (r - '0'); else if (r <= 'f' && r >= 'a') val = 16 * (r - 'a' + 10); else if (r <= 'F' && r >= 'A') val = 16 * (r - 'A' + 10); else { st = 0; break; } st = 3; break; case 3: if (r <= '9' && r >= '0') val += r - '0'; else if (r <= 'f' && r >= 'a') val += r - 'a' + 10; else if (r <= 'F' && r >= 'A') val += r - 'A' + 10; else { st = 0; break; } st = 0; if (t == 0) trans_serv2user[i++] = val; else trans_user2serv[i++] = val; if (i == 256) { if (t == 1) { close (tf); return 1; } t = 1; i = 0; } break; default: /* impossible */ close (tf); return 0; } } close (tf); } for (tf = 0; tf < 256; ++tf) { trans_user2serv[tf] = tf; trans_serv2user[tf] = tf; } return 0;}#endif /* !USE_TRANS */voidnotj_msg (struct session *sess){ PrintText (sess, _("No channel joined. Try /join #<channel>\n"));}voidnotc_msg (struct session *sess){ PrintText (sess, _("Not connected. Try /server <host> [<port>]\n"));}static char *random_line (char *file_name){ FILE *fh; char buf[512]; int lines, ran; if (!file_name[0]) goto nofile; snprintf (buf, sizeof (buf), "%s/%s", get_xdir (), file_name); fh = fopen (buf, "r"); if (!fh) { nofile: /* reason is not a file, an actual reason! */ return strdup (file_name); } /* count number of lines in file */ lines = 0; while (fgets (buf, sizeof (buf), fh)) lines++; if (lines < 1) goto nofile; /* go down a random number */ rewind (fh); srand (time (0)); ran = rand () % lines; do { fgets (buf, sizeof (buf), fh); lines--; } while (lines > ran); fclose (fh); buf[strlen (buf) - 1] = 0; /* remove the trailing '\n' */ return strdup (buf);}voidserver_sendpart (server * serv, char *channel, char *reason){ char tbuf[512]; if (!reason) { reason = random_line (prefs.partreason); snprintf (tbuf, sizeof (tbuf), "PART %s :%s\r\n", channel, reason); free (reason); } else { /* reason set by /quit, /close argument */ snprintf (tbuf, sizeof (tbuf), "PART %s :%s\r\n", channel, reason); } tcp_send (serv, tbuf);}voidserver_sendquit (session * sess){ char tbuf[512]; char *rea; if (!sess->quitreason) { rea = random_line (prefs.quitreason); snprintf (tbuf, sizeof (tbuf), "QUIT :%s\r\n", rea); free (rea); } else { /* reason set by /quit, /close argument */ snprintf (tbuf, sizeof (tbuf), "QUIT :%s\r\n", sess->quitreason); } tcp_send (sess->server, tbuf);}voidprocess_data_init (unsigned char *buf, char *cmd, char *word[], char *word_eol[], int handle_quotes){ int wordcount = 2; int space = FALSE; int quote = FALSE; int j = 0; word[1] = cmd; word_eol[1] = buf; while (1) { switch (*cmd) { case 0: jump: buf[j] = 0; for (j = wordcount; j < PDIWORDS; j++) { word[j] = "\000\000"; word_eol[j] = "\000\000"; } return; case '\042': if (!handle_quotes) goto def; if (quote) quote = FALSE; else quote = TRUE; break; case ' ': if (!quote) { if (!space) { buf[j] = 0; j++; word[wordcount] = &buf[j]; word_eol[wordcount] = cmd + 1; wordcount++; if (wordcount == PDIWORDS - 1) goto jump; space = TRUE; } break; } default:def: space = FALSE; buf[j] = *cmd; j++; } cmd++; }}static int cmd_addbutton (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_allchannels (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_allservers (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_away (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_ban (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_unban (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_clear (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_close (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_ctcp (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_country (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_cycle (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_dcc (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_debug (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_delbutton (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_deop (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_dehop (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_devoice (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_discon (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_dns (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_echo (struct session *sess, char *tbuf, char *word[], char *word_eol[]);#ifndef WIN32static int cmd_exec (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_execk (struct session *sess, char *tbuf, char *word[], char *word_eol[]);#ifndef __EMX__static int cmd_execs (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_execc (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_execw (struct session *sess, char *tbuf, char *word[], char *word_eol[]);#endif#endifstatic int cmd_gate (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_help (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_hop (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_ignore (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_invite (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_join (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_kick (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_kickban (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_lastlog (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_list (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_load (struct session *sess, char *tbuf, char *word[], char *word_eol[]);int cmd_loaddll (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_lagcheck (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_mdeop (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_mdehop (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_me (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_mkick (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_mkickb (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_msg (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_names (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_nctcp (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_newserver (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_nick (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_notice (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_notify (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_op (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_part (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_ping (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_query (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_quit (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_quote (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_reconnect (struct session *sess, char *tbuf, char *word[], char *word_eol[]);int cmd_rmdll (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_say (struct session *sess, char *tbuf, char *word[], char *word_eol[]);int cmd_scpinfo (struct session *sess, char *tbuf, char *word[], char *word_eol[]);int cmd_set (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_settab (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_servchan (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_server (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_timer (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_topic (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_unignore (struct session *sess, char *tbuf, char *word[], char *word_eol[]);int cmd_unloadall (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_userlist (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_wallchop (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_wallchan (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_voice (struct session *sess, char *tbuf, char *word[], char *word_eol[]);static int cmd_flushq (struct session *sess, char *tbuf, char *word[], char *word_eol[]);struct commands xc_cmds[] = { {"ADDBUTTON", cmd_addbutton, 0, 0, N_("/ADDBUTTON <name> <action>, adds a button under the user-list\n")}, {"ALLCHAN", cmd_allchannels, 0, 0, N_("/ALLCHAN <cmd>, sends a command to all channels you're in\n")}, {"ALLSERV", cmd_allservers, 0, 0, N_("/ALLSERV <cmd>, sends a command to all servers you're in\n")}, {"AWAY", cmd_away, 1, 0, N_("/AWAY [<reason>], sets you away\n")}, {"BAN", cmd_ban, 1, 1, N_("/BAN <mask> [<bantype>], bans everyone matching the mask from the current channel. If they are already on the channel this doesn't kick them (needs chanop)\n")}, {"UNBAN", cmd_unban, 1, 1, N_("/UNBAN <mask> [<mask>...], unbans the specified masks.\n")}, {"CLEAR", cmd_clear, 0, 0, N_("/CLEAR, Clears the current text window\n")}, {"CLOSE", cmd_close, 0, 0, N_("/CLOSE, Closes the current window/tab\n")}, {"CTCP", cmd_ctcp, 1, 0, N_("/CTCP <nick> <message>, send the CTCP message to nick, common messages are VERSION and USERINFO\n")}, {"COUNTRY", cmd_country, 0, 0, N_("/COUNTRY <code>, finds a country code, eg: au = australia\n")}, {"CYCLE", cmd_cycle, 1, 1, N_("/CYCLE, parts current channel and immediately rejoins\n")}, {"DCC", cmd_dcc, 0, 0, N_("\n" "/DCC GET <nick> - receive an offered file\n" "/DCC SEND <nick> <file> - send a file to someone\n" "/DCC LIST - show DCC list\n" "/DCC CHAT <nick> - offer DCC CHAT to someone\n" "/DCC CLOSE <type> <nick> <file> example:\n" " /dcc close send johnsmith file.tar.gz\n")}, {"DEBUG", cmd_debug, 0, 0, 0}, {"DELBUTTON", cmd_delbutton, 0, 0, N_("/DELBUTTON <name>, deletes a button from under the user-list\n")}, {"DEHOP", cmd_dehop, 1, 1, N_("/DEHOP <nick>, removes chanhalf-op status from the nick on the current channel (needs chanop)\n")}, {"DEOP", cmd_deop, 1, 1, N_("/DEOP <nick>, removes chanop status from the nick on the current channel (needs chanop)\n")}, {"DEVOICE", cmd_devoice, 1, 1, N_("/DEVOICE <nick>, removes voice status from the nick on the current channel (needs chanop)\n")}, {"DISCON", cmd_discon, 0, 0, N_("/DISCON, Disconnects from server\n")}, {"DNS", cmd_dns, 0, 0, N_("/DNS <nick|host|ip>, Finds a users IP number\n")}, {"ECHO", cmd_echo, 0, 0, N_("/ECHO <text>, Prints text locally\n")},#ifndef WIN32 {"EXEC", cmd_exec, 0, 0, N_("/EXEC [-o] <command>, runs the command. If -o flag is used then output is sent to current channel, else is printed to current text box\n")}, {"EXECKILL", cmd_execk, 0, 0, N_("/EXECKILL [-9], kills a running exec in the current session. If -9 is given the process is SIGKILL'ed\n")},#ifndef __EMX__ {"EXECSTOP", cmd_execs, 0, 0, N_("/EXECSTOP, sends the process SIGSTOP\n")}, {"EXECCONT", cmd_execc, 0, 0, N_("/EXECCONT, sends the process SIGCONT\n")}, {"EXECWRITE", cmd_execw, 0, 0, N_("/EXECWRITE, sends data to the processes stdin\n")},#endif#endif {"FLUSHQ", cmd_flushq, 0, 0, N_("/FLUSHQ, flushes the current server's send queue\n")}, {"GATE", cmd_gate, 0, 0, N_("/GATE <host> [<port>], proxies through a host, port defaults to 23\n")}, {"HELP", cmd_help, 0, 0, 0}, {"HOP", cmd_hop, 1, 1, N_("/HOP <nick>, gives chanhalf-op status to the nick (needs chanop)\n")}, {"IGNORE", cmd_ignore, 0, 0, N_("/IGNORE <mask> <types..> <options..>\n" " mask - host mask to ignore, eg: *!*@*.aol.com\n" " types - types of data to ignore, one or all of:\n" " PRIV, CHAN, NOTI, CTCP, INVI, ALL\n" " options - NOSAVE, QUIET\n")}, {"INVITE", cmd_invite, 1, 0, N_("/INVITE <nick> [<channel>], invites someone to a channel, by default the current channel (needs chanop)\n")}, {"JOIN", cmd_join, 1, 0, N_("/JOIN <channel>, joins the channel\n")}, {"KICK", cmd_kick, 1, 1, N_("/KICK <nick>, kicks the nick from the current channel (needs chanop)\n")}, {"KICKBAN", cmd_kickban, 1, 1, N_("/KICKBAN <nick>, bans then kicks the nick from the current channel (needs chanop)\n")}, {"LAGCHECK", cmd_lagcheck, 0, 0, N_("/LAGCHECK, forces a new lag check\n")}, {"LASTLOG", cmd_lastlog, 0, 0, N_("/LASTLOG <string>, searches for a string in the buffer.\n")}, {"LIST", cmd_list, 1, 0, ""},#ifdef USE_PLUGIN {"LISTDLL", module_list, 0, 0, N_("/LISTDLL, Lists all currenly loaded plugins\n")},#endif {"LOAD", cmd_load, 0, 0, N_("/LOAD <file>, loads a Perl script\n")},#ifdef USE_PLUGIN {"LOADDLL", cmd_loaddll, 0, 0, N_("/LOADDLL <file>, loads a plugin\n")},#endif {"MDEHOP", cmd_mdehop, 1, 1, N_("/MDEHOP, Mass deop's all chanhalf-ops in the current channel (needs chanop)\n")}, {"MDEOP", cmd_mdeop, 1, 1, N_("/MDEOP, Mass deop's all chanops in the current channel (needs chanop)\n")}, {"MKICK", cmd_mkick, 1, 1, N_("/MKICK, Mass kicks everyone except you in the current channel (needs chanop)\n")}, {"MKICKB", cmd_mkickb, 1, 1, N_("/MKICKB, Sets a ban of *@* and mass kicks everyone except you in the current channel (needs chanop)\n")}, {"ME", cmd_me, 0, 0, N_("/ME <action>, sends the action to the current channel (actions are written in the 3rd person, like /me jumps)\n")}, {"MSG", cmd_msg, 0, 0, N_("/MSG <nick> <message>, sends a private message\n")}, {"NAMES", cmd_names, 1, 0, N_("/NAMES, Lists the nicks on the current channel\n")}, {"NCTCP", cmd_nctcp, 1, 0, N_("/NCTCP <nick> <message>, Sends a CTCP notice\n")}, {"NEWSERVER", cmd_newserver, 0, 0, N_("/NEWSERVER <hostname> [<port>]\n")}, {"NICK", cmd_nick, 0, 0, N_("/NICK <nickname>, sets your nick\n")}, {"NOTICE", cmd_notice, 1, 0, N_("/NOTICE <nick/channel> <message>, sends a notice. Notices are a type of message that should be auto reacted to\n")}, {"NOTIFY", cmd_notify, 0, 0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -