?? irc.c
字號:
/* * Copyright (C) 2001 Marco Ziech (mmz@gmx.net) * Copyright (C) 2005 Bryan Biedenkapp (gatekeep@gmail.com) * * 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 "common/setup_before.h"#ifdef STDC_HEADERS# include <stdlib.h>#else# ifdef HAVE_MALLOC_H# include <malloc.h># endif#endif#ifdef HAVE_STRING_H# include <string.h>#else# ifdef HAVE_STRINGS_H# include <strings.h># endif# ifdef HAVE_MEMORY_H# include <memory.h># endif#endif#include "compat/strdup.h"#include <errno.h>#include "compat/strerror.h"#ifdef TIME_WITH_SYS_TIME# include <sys/time.h># include <time.h>#else# ifdef HAVE_SYS_TIME_H# include <sys/time.h># else# include <time.h># endif#endif#include "common/irc_protocol.h"#include "common/packet.h"#include "common/eventlog.h"#include "connection.h"#include "common/bn_type.h"#include "common/field_sizes.h"#include "common/addr.h"#include "common/version.h"#include "common/queue.h"#include "common/list.h"#include "common/bnethash.h"#include "common/bnethashconv.h"#include "common/tag.h"#include "message.h"#include "account.h"#include "account_wrap.h"#include "channel.h"#include "irc.h"#include "prefs.h"#include "server.h"#include "tick.h"#include "message.h"#include "command_groups.h"#include "common/util.h"#include "common/xalloc.h"#include "common/setup_after.h"typedef struct { char const * nick; char const * user; char const * host;} t_irc_message_from;static char ** irc_split_elems(char * list, int separator, int ignoreblank);static int irc_unget_elems(char ** elems);static char * irc_message_preformat(t_irc_message_from const * from, char const * command, char const * dest, char const * text);extern int irc_send_cmd(t_connection * conn, char const * command, char const * params){ t_packet * p; char data[MAX_IRC_MESSAGE_LEN+1]; int len; char const * ircname = server_get_hostname(); char const * nick; if (!conn) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection"); return -1; } if (!command) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL command"); return -1; } if (!(p = packet_create(packet_class_raw))) { eventlog(eventlog_level_error,__FUNCTION__,"could not create packet"); return -1; } nick = conn_get_loggeduser(conn); if (!nick) nick = ""; /* snprintf isn't portable -> check message length first */ if (params) { len = 1+strlen(ircname)+1+strlen(command)+1+strlen(nick)+1+strlen(params)+2; if (len > MAX_IRC_MESSAGE_LEN) { eventlog(eventlog_level_error,__FUNCTION__,"message to send is too large (%d bytes)",len); return -1; } else sprintf(data,":%s %s %s %s\r\n",ircname,command,nick,params); } else { len = 1+strlen(ircname)+1+strlen(command)+1+strlen(nick)+1+2; if (len > MAX_IRC_MESSAGE_LEN) { eventlog(eventlog_level_error,__FUNCTION__,"message to send is too large (%d bytes)",len); return -1; } else sprintf(data,":%s %s %s\r\n",ircname,command,nick); } packet_set_size(p,0); packet_append_data(p,data,len); // eventlog(eventlog_level_debug,__FUNCTION__,"[%d] sent \"%s\"",conn_get_socket(conn),data); conn_push_outqueue(conn,p); packet_del_ref(p); return 0;}extern int irc_send(t_connection * conn, int code, char const * params){ char temp[4]; /* '000\0' */ if (!conn) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection"); return -1; } if ((code>999)||(code<0)) { /* more than 3 digits or negative */ eventlog(eventlog_level_error,__FUNCTION__,"invalid message code (%d)",code); return -1; } sprintf(temp,"%03u",code); return irc_send_cmd(conn,temp,params);}extern int irc_send_cmd2(t_connection * conn, char const * prefix, char const * command, char const * postfix, char const * comment){ t_packet * p; char data[MAX_IRC_MESSAGE_LEN+1]; int len; if (!conn) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection"); return -1; } if (!prefix) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL prefix"); return -1; } if (!command) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL command"); return -1; } if (!postfix) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL postfix"); return -1; } if (!(p = packet_create(packet_class_raw))) { eventlog(eventlog_level_error,__FUNCTION__,"could not create packet"); return -1; } if (comment) { len = 1+strlen(prefix)+1+strlen(command)+1+strlen(postfix)+2+strlen(comment)+1+2; if (len > MAX_IRC_MESSAGE_LEN) { eventlog(eventlog_level_error,__FUNCTION__,"message to send is too large (%d bytes)",len); return -1; } else sprintf(data,":%s %s %s :%s\r\n",prefix,command,postfix,comment); } else { len = 1+strlen(prefix)+1+strlen(command)+1+strlen(postfix)+1+2; if (len > MAX_IRC_MESSAGE_LEN) { eventlog(eventlog_level_error,__FUNCTION__,"message to send is too large (%d bytes)",len); return -1; } else sprintf(data,":%s %s %s\r\n",prefix,command,postfix); } packet_set_size(p,0); packet_append_data(p,data,len); // eventlog(eventlog_level_debug,__FUNCTION__,"[%d] sent \"%s\"",conn_get_socket(conn),data); conn_push_outqueue(conn,p); packet_del_ref(p); return 0;}extern int irc_send_ping(t_connection * conn){ t_packet * p; char data[MAX_IRC_MESSAGE_LEN]; if (!conn) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection"); return -1; } if (!(p = packet_create(packet_class_raw))) { eventlog(eventlog_level_error,__FUNCTION__,"could not create packet"); return -1; } if((conn_get_wol(conn) == 1)) return 0; conn_set_ircping(conn,get_ticks()); if (conn_get_state(conn)==conn_state_bot_username) sprintf(data,"PING :%u\r\n",conn_get_ircping(conn)); /* Undernet doesn't reveal the servername yet ... neither do we */ else if ((6+strlen(server_get_hostname())+2+1)<=MAX_IRC_MESSAGE_LEN) sprintf(data,"PING :%s\r\n",server_get_hostname()); else eventlog(eventlog_level_error,__FUNCTION__,"maximum message length exceeded"); eventlog(eventlog_level_debug,__FUNCTION__,"[%d] sent \"%s\"",conn_get_socket(conn),data); packet_set_size(p,0); packet_append_data(p,data,strlen(data)); conn_push_outqueue(conn,p); packet_del_ref(p); return 0;}extern int irc_send_pong(t_connection * conn, char const * params){ t_packet * p; char data[MAX_IRC_MESSAGE_LEN]; if (!conn) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection"); return -1; } if ((1+strlen(server_get_hostname())+1+4+1+strlen(server_get_hostname())+((params)?(2+strlen(params)):(0))+2+1) > MAX_IRC_MESSAGE_LEN) { eventlog(eventlog_level_error,__FUNCTION__,"max message length exceeded"); return -1; } if (!(p = packet_create(packet_class_raw))) { eventlog(eventlog_level_error,__FUNCTION__,"could not create packet"); return -1; } if (params) sprintf(data,":%s PONG %s :%s\r\n",server_get_hostname(),server_get_hostname(),params); else sprintf(data,":%s PONG %s\r\n",server_get_hostname(),server_get_hostname()); eventlog(eventlog_level_debug,__FUNCTION__,"[%d] sent \"%s\"",conn_get_socket(conn),data); packet_set_size(p,0); packet_append_data(p,data,strlen(data)); conn_push_outqueue(conn,p); packet_del_ref(p); return 0;}extern int irc_authenticate(t_connection * conn, char const * passhash){ t_hash h1; t_hash h2; t_account * a; char const * temphash; char const * username; char const * tempapgar; if (!conn) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection"); return 0; } if (!passhash) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL passhash"); return 0; } username = conn_get_loggeduser(conn); if (!username) { /* redundant sanity check */ eventlog(eventlog_level_error,__FUNCTION__,"got NULL conn->protocol.loggeduser"); return 0; } a = accountlist_find_account(username); if (!a) { irc_send_cmd(conn,"NOTICE",":Authentication failed."); /* user does not exist */ return 0; } if (connlist_find_connection_by_account(a) && prefs_get_kick_old_login()==0) { irc_send_cmd(conn,"NOTICE",":Authentication rejected (already logged in) "); } else if (account_get_auth_lock(a)==1) { irc_send_cmd(conn,"NOTICE",":Authentication rejected (account is locked) "); } else { if((conn_get_wol(conn) == 1)) { temphash = account_get_wol_apgar(a); tempapgar = conn_wol_get_apgar(conn); if(temphash == NULL) { account_set_wol_apgar(a,tempapgar); temphash = account_get_wol_apgar(a); } if(tempapgar == NULL) { irc_send_cmd(conn,"NOTICE",":Authentication failed."); /* bad APGAR */ conn_increment_passfail_count(conn); return 0; } if(strcmp(temphash,tempapgar) == 0) { conn_login(conn,a,username); conn_set_state(conn,conn_state_loggedin); conn_set_clienttag(conn,CLIENTTAG_WWOL_UINT); /* WWOL hope here is ok */ return 1; } else { conn_increment_passfail_count(conn); return 0; } } hash_set_str(&h1,passhash); temphash = account_get_pass(a); hash_set_str(&h2,temphash); if (hash_eq(h1,h2)) { conn_login(conn,a,username); conn_set_state(conn,conn_state_loggedin); conn_set_clienttag(conn,CLIENTTAG_IIRC_UINT); /* IIRC hope here is ok */ irc_send_cmd(conn,"NOTICE",":Authentication successful. You are now logged in."); return 1; } else { irc_send_cmd(conn,"NOTICE",":Authentication failed."); /* wrong password */ conn_increment_passfail_count(conn); } } return 0;}extern int irc_welcome(t_connection * conn){ char temp[MAX_IRC_MESSAGE_LEN]; time_t temptime; char const * tempname; char const * temptimestr; char const * filename; FILE *fp; char * line, * formatted_line; char send_line[MAX_IRC_MESSAGE_LEN]; char motd_failed = 0; if (!conn) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection"); return -1; } tempname = conn_get_loggeduser(conn); if ((34+strlen(tempname)+1)<=MAX_IRC_MESSAGE_LEN) sprintf(temp,":Welcome to the %s IRC Network %s",prefs_get_irc_network_name(), tempname); else sprintf(temp,":Maximum length exceeded"); irc_send(conn,RPL_WELCOME,temp);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -