📄 xchat.c
字号:
/* case SESS_CHANNEL: case SESS_DIALOG: case SESS_NOTICES: case SESS_SNOTICES:*/ sess = new_session (serv, name, type); break; } irc_init (sess); return sess;}static voidkill_server_callback (server * serv){ server_cleanup (serv);/* fe_server_callback (serv);*/ serv_list = g_slist_remove (serv_list, serv); dcc_notify_kill (serv); flush_server_queue (serv); free_away_messages (serv); free (serv->nick_modes); free (serv->nick_prefixes); free (serv->chanmodes); free (serv->chantypes); if (serv->bad_nick_prefixes) free (serv->bad_nick_prefixes); if (serv->last_away_reason) free (serv->last_away_reason); if (serv->eom_cmd) free (serv->eom_cmd); free (serv->gui); free (serv); notify_cleanup ();}static voidlog_notify_kill (session * sess){ if (sess->logfd != -1) end_logging (sess->logfd);}static voidexec_notify_kill (session * sess){#ifndef WIN32 struct nbexec *re; if (sess->running_exec != NULL) { re = sess->running_exec; sess->running_exec = NULL; kill (re->childpid, SIGKILL); waitpid (re->childpid, NULL, WNOHANG); fe_input_remove (re->iotag); close (re->myfd); if (re->linebuf) free(re->linebuf); free (re); }#endif}static voidsend_quit_or_part (session * killsess){ int willquit = TRUE; GSList *list; session *sess; server *killserv = killsess->server; /* check if this is the last session using this server */ list = sess_list; while (list) { sess = (session *) list->data; if (sess->server == killserv && sess != killsess) { willquit = FALSE; list = 0; } else list = list->next; } if (xchat_is_quitting) willquit = TRUE; if (killserv->connected) { if (willquit) { if (!killserv->sent_quit) { flush_server_queue (killserv); server_sendquit (killsess); killserv->sent_quit = TRUE; } } else { if (killsess->type == SESS_CHANNEL && killsess->channel[0]) { server_sendpart (killserv, killsess->channel, 0); } } }}voidkill_session_callback (session * killsess){ server *killserv = killsess->server; session *sess; GSList *list; if (current_tab == killsess) current_tab = NULL; if (killserv->front_session == killsess) { /* front_session is closed, find a valid replacement */ killserv->front_session = NULL; list = sess_list; while (list) { sess = (session *) list->data; if (sess != killsess && sess->server == killserv) { killserv->front_session = sess; break; } list = list->next; } } sess_list = g_slist_remove (sess_list, killsess); if (killsess->type == SESS_CHANNEL) free_userlist (killsess); fe_session_callback (killsess); exec_notify_kill (killsess);#ifdef USE_PERL perl_notify_kill (killsess);#endif log_notify_kill (killsess); send_quit_or_part (killsess); history_free (&killsess->history); free (killsess->gui); if (killsess->topic) free (killsess->topic); free (killsess->current_modes); free (killsess); if (!sess_list && !in_xchat_exit) xchat_exit (); /* sess_list is empty, quit! */ list = sess_list; while (list) { sess = (session *) list->data; if (sess->server == killserv) return; /* this server is still being used! */ list = list->next; } kill_server_callback (killserv);}static voidfree_sessions (void){ GSList *list = sess_list; while (list) { fe_close_window (list->data); list = sess_list; }}struct away_msg *find_away_message (struct server *serv, char *nick){ struct away_msg *away; GSList *list = away_list; while (list) { away = (struct away_msg *) list->data; if (away->server == serv && !strcasecmp (nick, away->nick)) return away; list = list->next; } return 0;}static voidfree_away_messages (server *serv){ GSList *list, *next; struct away_msg *away; list = away_list; while (list) { away = list->data; next = list->next; if (away->server == serv) { away_list = g_slist_remove (away_list, away); if (away->message) free (away->message); free (away); next = away_list; } list = next; }}voidsave_away_message (struct server *serv, char *nick, char *msg){ struct away_msg *away = find_away_message (serv, nick); if (away) /* Change message for known user */ { if (away->message) free (away->message); away->message = strdup (msg); } else /* Create brand new entry */ { away = malloc (sizeof (struct away_msg)); if (away) { away->server = serv; safe_strcpy (away->nick, nick, sizeof (away->nick)); away->message = strdup (msg); away_list = g_slist_prepend (away_list, away); } }}#define defaultconf_ctcp \ "NAME TIME\n" "CMD /nctcp %s TIME %t\n\n"\ "NAME PING\n" "CMD /nctcp %s PING %d\n\n"#define defaultconf_popup \ "NAME SUB\n" "CMD Direct Client-To-Client\n\n"\ "NAME Send File\n" "CMD /dcc send %s\n\n"\ "NAME Offer Chat\n" "CMD /dcc chat %s\n\n"\ "NAME Abort Chat\n" "CMD /dcc close chat %s\n\n"\ "NAME ENDSUB\n" "CMD \n\n"\ "NAME SUB\n" "CMD CTCP\n\n"\ "NAME Version\n" "CMD /ctcp %s VERSION\n\n"\ "NAME Userinfo\n" "CMD /ctcp %s USERINFO\n\n"\ "NAME Clientinfo\n" "CMD /ctcp %s CLIENTINFO\n\n"\ "NAME Ping\n" "CMD /ping %s\n\n"\ "NAME Time\n" "CMD /ctcp %s TIME\n\n"\ "NAME Finger\n" "CMD /ctcp %s FINGER\n\n"\ "NAME XDCC List\n" "CMD /ctcp %s XDCC LIST\n\n"\ "NAME CDCC List\n" "CMD /ctcp %s CDCC LIST\n\n"\ "NAME ENDSUB\n" "CMD \n\n"\ "NAME SUB\n" "CMD Oper\n\n"\ "NAME Kill this user\n" "CMD /quote KILL %s :die!\n\n"\ "NAME ENDSUB\n" "CMD \n\n"\ "NAME SUB\n" "CMD Mode\n\n"\ "NAME Give Voice\n" "CMD /voice %s\n\n"\ "NAME Take Voice\n" "CMD /devoice %s\n"\ "NAME SEP\n" "CMD \n\n"\ "NAME Give Ops\n" "CMD /op %s\n\n"\ "NAME Take Ops\n" "CMD /deop %s\n\n"\ "NAME ENDSUB\n" "CMD \n\n"\ "NAME SUB\n" "CMD Ignore\n\n"\ "NAME Ignore User\n" "CMD /ignore %s!*@* ALL\n\n"\ "NAME UnIgnore User\n" "CMD /unignore %s!*@*\n\n"\ "NAME ENDSUB\n" "CMD \n\n"\ "NAME SUB\n" "CMD Kick/Ban\n\n"\ "NAME Kick\n" "CMD /kick %s\n\n"\ "NAME Ban\n" "CMD /ban %s\n\n"\ "NAME SEP\n" "CMD \n\n"\ "NAME Ban *!*@*.host\n" "CMD /ban %s 0\n\n"\ "NAME Ban *!*@domain\n" "CMD /ban %s 1\n\n"\ "NAME Ban *!*user@*.host\n""CMD /ban %s 2\n\n"\ "NAME Ban *!*user@domain\n""CMD /ban %s 3\n\n"\ "NAME SEP\n" "CMD \n\n"\ "NAME KickBan *!*@*.host\n""CMD /kickban %s 0\n\n"\ "NAME KickBan *!*@domain\n""CMD /kickban %s 1\n\n"\ "NAME KickBan *!*user@*.host\n""CMD /kickban %s 2\n\n"\ "NAME KickBan *!*user@domain\n""CMD /kickban %s 3\n\n"\ "NAME ENDSUB\n" "CMD \n\n"\ "NAME SUB\n" "CMD Info\n\n"\ "NAME Who\n" "CMD /quote WHO %s\n\n"\ "NAME Whois\n" "CMD /quote WHOIS %s\n\n"\ "NAME DNS Lookup\n" "CMD /dns %s\n\n"\ "NAME Trace\n" "CMD /quote TRACE %s\n\n"\ "NAME UserHost\n" "CMD /quote USERHOST %s\n\n"\ "NAME ENDSUB\n" "CMD \n\n"\ "NAME SUB\n" "CMD External\n\n"\ "NAME Traceroute\n" "CMD !x-terminal-emulator -e /bin/sh -c \"/usr/sbin/traceroute %h ; sleep 30\"\n\n"\ "NAME Ping\n" "CMD !x-terminal-emulator -e /bin/sh -c \"ping -c 4 %h ; sleep 30\"\n\n"\ "NAME Telnet\n" "CMD !x-terminal-emulator -e telnet %h\n\n"\ "NAME ENDSUB\n" "CMD \n\n"\ "NAME Open Query\n" "CMD /query %s\n\n"#define defaultconf_buttons \ "NAME Op\n" "CMD /op %a\n\n"\ "NAME DeOp\n" "CMD /deop %a\n\n"\ "NAME Ban\n" "CMD /ban %s\n\n"\ "NAME Kick\n" "CMD /kick %s\n\n"\ "NAME Sendfile\n" "CMD /dcc send %s\n\n"\ "NAME Dialog\n" "CMD /query %s\n\n"#define defaultconf_dlgbuttons \ "NAME Whois\n" "CMD /whois %s\n\n"\ "NAME Send\n" "CMD /dcc send %s\n\n"\ "NAME Chat\n" "CMD /dcc chat %s\n\n"\ "NAME Ping\n" "CMD /ping %s\n\n"\ "NAME Clear\n" "CMD /clear\n\n"\#define defaultconf_replace \ "NAME teh\n" "CMD the\n\n"\ "NAME r\n" "CMD are\n\n"\ "NAME u\n" "CMD you\n\n"#define defaultconf_commands \ "NAME ACTION\n" "CMD /me &2\n\n"\ "NAME AME\n" "CMD /allchan /me &2\n\n"\ "NAME AMSG\n" "CMD /allchan &2\n\n"\ "NAME BACK\n" "CMD /away\n\n"\ "NAME BANLIST\n" "CMD /quote MODE %c +b\n\n"\ "NAME CHAT\n" "CMD /dcc chat %2\n\n"\ "NAME DIALOG\n" "CMD /query %2\n\n"\ "NAME DMSG\n" "CMD /msg =%2 &3\n\n"\ "NAME EXIT\n" "CMD /quit\n\n"\ "NAME J\n" "CMD /join &2\n\n"\ "NAME KILL\n" "CMD /quote KILL %2 :&3\n\n"\ "NAME LEAVE\n" "CMD /part &2\n\n"\ "NAME M\n" "CMD /msg &2\n\n"\ "NAME ONOTICE\n" "CMD /notice @%c &2\n\n"\ "NAME RAW\n" "CMD /quote &2\n\n"\ "NAME SERVHELP\n" "CMD /quote HELP\n\n"\ "NAME SPING\n" "CMD /ping\n\n"\ "NAME SSLSERVER\n" "CMD /server -ssl &2\n\n"\ "NAME SV\n" "CMD /echo xchat %v %m\n\n"\ "NAME UMODE\n" "CMD /mode %n &2\n\n"\ "NAME UPTIME\n" "CMD /quote STATS u\n\n"\ "NAME VER\n" "CMD /ctcp %2 VERSION\n\n"\ "NAME VERSION\n" "CMD /ctcp %2 VERSION\n\n"\ "NAME WALLOPS\n" "CMD /quote WALLOPS :&2\n\n"\ "NAME WII\n" "CMD /quote WHOIS %2 %2\n\n"#define defaultconf_usermenu \ "NAME SUB\n" "CMD IRC Stuff\n\n"\ "NAME Disconnect\n" "CMD /discon\n\n"\ "NAME Reconnect\n" "CMD /reconnect\n\n"\ "NAME Part Channel\n" "CMD /part\n\n"\ "NAME Cycle Channel\n" "CMD /cycle\n\n"\ "NAME Server Map\n" "CMD /quote MAP\n\n"\ "NAME Server Links\n" "CMD /quote LINKS\n\n"\ "NAME Ping Server\n" "CMD /ping\n\n"\ "NAME ENDSUB\n" "CMD \n\n"\ "NAME SUB\n" "CMD Connect\n\n"\ "NAME irc.xchat.org #Linux\n""CMD /servchan irc.xchat.org 6667 #linux\n\n"\ "NAME Go to EFNet\n" "CMD /newserver irc.efnet.net\n\n"\ "NAME ENDSUB\n" "CMD \n\n"\ "NAME SUB\n" "CMD Settings\n\n"\ "NAME TOGGLE Hide Version\n" "CMD hide_version\n\n"\ "NAME TOGGLE Colored Nicks\n" "CMD colorednicks\n\n"\ "NAME TOGGLE 1.4.x Nick Comp.\n" "CMD old_nickcompletion\n\n"\ "NAME TOGGLE Strip mIRC color\n" "CMD stripcolor\n\n"\ "NAME TOGGLE Filter Beeps\n" "CMD filterbeep\n\n"\ "NAME TOGGLE Raw MODE Display\n" "CMD raw_modes\n\n"\ "NAME TOGGLE Perl Warnings\n" "CMD perlwarnings\n\n"\ "NAME TOGGLE Mail Checker\n" "CMD mail_check\n\n"\ "NAME ENDSUB\n" "CMD \n\n"\ "NAME SUB\n" "CMD External\n\n"\ "NAME Run XMMS\n" "CMD !xmms\n\n"\ "NAME Open Terminal\n" "CMD !x-terminal-emulator\n\n"\ "NAME ENDSUB\n" "CMD \n\n"#ifdef WIN32#define defaultconf_urlhandlers \ "NAME Open URL\n" "CMD !start %s\n\n"\ "NAME Connect as IRC server\n" "CMD /newserver %s\n\n"#else#define defaultconf_urlhandlers \ "NAME SUB\n" "CMD Netscape...\n\n"\ "NAME Open in existing\n" "CMD !netscape -remote 'openURL(%s)'\n\n"\ "NAME Open in new window\n" "CMD !netscape -remote 'openURL(%s,new-window)'\n\n"\ "NAME Run new Netscape\n" "CMD !netscape %s\n\n"\ "NAME ENDSUB\n" "CMD \n\n"\ "NAME SUB\n" "CMD Mozilla...\n\n"\ "NAME Open in existing\n" "CMD !mozilla -remote 'openURL(%s)'\n\n"\ "NAME Open in new window\n" "CMD !mozilla -remote 'openURL(%s,new-window)'\n\n"\ "NAME Run new Mozilla\n" "CMD !mozilla %s\n\n"\ "NAME ENDSUB\n" "CMD \n\n"\ "NAME SUB\n" "CMD Galeon...\n\n"\ "NAME Open in existing\n" "CMD !galeon -x '%s'\n\n"\ "NAME Open in new window\n" "CMD !galeon -w '%s'\n\n"\ "NAME Open in new tab\n" "CMD !galeon -n '%s'\n\n"\ "NAME Run new Galeon\n" "CMD !galeon '%s'\n\n"\ "NAME ENDSUB\n" "CMD \n\n"\ "NAME SUB\n" "CMD Opera...\n\n"\ "NAME Open in existing\n" "CMD !opera -remote 'openURL(%s)'\n\n"\ "NAME Open in new window\n" "CMD !opera -remote 'openURL(%s,new-window)'\n\n"\ "NAME Run new Opera\n" "CMD !opera %s\n\n"\ "NAME ENDSUB\n" "CMD \n\n"\ "NAME SUB\n" "CMD Send URL to...\n\n"\ "NAME Gnome URL Handler\n" "CMD !gnome-moz-remote %s\n\n"\ "NAME Lynx\n" "CMD !x-terminal-emulator -e lynx %s\n\n"\ "NAME Links\n" "CMD !x-terminal-emulator -e links %s\n\n"\ "NAME w3m\n" "CMD !x-terminal-emulator -e w3m %s\n\n"\ "NAME Mutt (for mail)\n" "CMD !x-terminal-emulator -e mutt %s\n\n"\ "NAME NcFTP\n" "CMD !x-terminal-emulator -e ncftp %s\n\n"\ "NAME gFTP\n" "CMD !gftp %s\n\n"\ "NAME KFM\n" "CMD !kfmclient openURL %s\n\n"\ "NAME Telnet\n" "CMD !x-terminal-emulator -e telnet %s\n\n"\ "NAME Ping\n" "CMD !x-terminal-emulator -e ping -c 4 %s\n\n"\ "NAME ENDSUB\n" "CMD \n\n"\ "NAME Connect as IRC server\n" "CMD /newserver %s\n\n"#endifstatic voidxchat_init (void){#ifdef WIN32 WSADATA wsadata; WSAStartup(0x0101, &wsadata);#else struct sigaction act; /* ignore SIGPIPE's */ act.sa_handler = SIG_IGN; act.sa_flags = 0; sigemptyset (&act.sa_mask); sigaction (SIGPIPE, &act, NULL);#endif signal_setup (); load_text_events (); notify_load (); ignore_load (); list_loadconf ("popup.conf", &popup_list, defaultconf_popup); list_loadconf ("ctcpreply.conf", &ctcp_list, defaultconf_ctcp); list_loadconf ("buttons.conf", &button_list, defaultconf_buttons); list_loadconf ("dlgbuttons.conf", &dlgbutton_list, defaultconf_dlgbuttons); list_loadconf ("commands.conf", &command_list, defaultconf_commands); list_loadconf ("replace.conf", &replace_list, defaultconf_replace); list_loadconf ("usermenu.conf", &usermenu_list, defaultconf_usermenu); list_loadconf ("urlhandlers.conf", &urlhandler_list, defaultconf_urlhandlers);#ifdef USE_TRANS if (prefs.use_trans) { if (load_trans_table (prefs.trans_file) == 0) prefs.use_trans = 0; }#endif /* if serverlist didnt open any irc windows .... */ if (!fe_open_serverlist (NULL, auto_connect, prefs.skipserverlist)) { /* and serverlist isn't open .... */ if (prefs.skipserverlist) /* we'll have to open one. */ new_ircwindow (NULL, NULL, SESS_SERVER); }}voidxchat_exit (void){ xchat_is_quitting = TRUE; in_xchat_exit = TRUE;#ifdef USE_PERL perl_end ();#endif#ifdef USE_PYTHON pys_kill ();#endif fe_cleanup (); if (prefs.autosave) { save_config (); pevent_save (NULL); } notify_save (); ignore_save (); free_sessions (); fe_exit ();}#ifndef WIN32static intchild_handler (int pid){ if (waitpid (pid, 0, WNOHANG) == pid) return 0; /* remove timeout handler */ return 1; /* keep the timeout handler */}#endifvoidxchat_exec (char *cmd){#ifdef WIN32 util_exec (cmd);#else int pid = util_exec (cmd); if (pid != -1) /* zombie avoiding system. Don't ask! it has to be like this to work with zvt (which overrides the default handler) */ fe_timeout_add (1000, child_handler, (void *)pid);#endif}intmain (int argc, char *argv[]){#ifdef SOCKS SOCKSinit (argv[0]);#endif#ifdef USE_OPENSSL if (!(ctx = _SSL_context_init (ssl_cb_info, FALSE))) { fprintf(stderr, "_SSL_context_init failed\n"); exit(1); }#endif if (!fe_args (argc, argv)) return 0; load_config (); fe_init (); xchat_init (); fe_main ();#ifdef USE_DEBUG xchat_mem_list ();#endif#ifdef USE_OPENSSL _SSL_context_free (ctx);#endif return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -