5615 lines
163 KiB
C
5615 lines
163 KiB
C
/*
|
||
* commands.c: This is really a mishmash of function and such that deal with IRCII
|
||
* commands (both normal and keybinding commands)
|
||
*
|
||
* Written By Michael Sandrof
|
||
* Portions are based on EPIC.
|
||
* Modified by panasync (Colten Edwards) 1995-97
|
||
* Copyright(c) 1990
|
||
* Random Ircname by Christian Deimel
|
||
*
|
||
* See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT
|
||
*/
|
||
|
||
#include "irc.h"
|
||
static char cvsrevision[] = "$Id$";
|
||
CVS_REVISION(commands_c)
|
||
|
||
/* These headers are for the local-address-finding routines. */
|
||
#ifdef IPV6
|
||
|
||
#include <net/if.h>
|
||
#include <ifaddrs.h>
|
||
|
||
#else /* IPV6 */
|
||
|
||
#include <sys/ioctl.h>
|
||
|
||
#ifdef HAVE_SYS_SOCKIO_H
|
||
#include <sys/sockio.h>
|
||
#endif /* HAVE_SYS_SOCKIO_H */
|
||
|
||
/* Some systems call it SIOCGIFCONF, some call it OSIOCGIFCONF */
|
||
#if defined(OSIOCGIFCONF)
|
||
#define SANE_SIOCGIFCONF OSIOCGIFCONF
|
||
#elif defined(SIOCGIFCONF)
|
||
#define SANE_SIOCGIFCONF SIOCGIFCONF
|
||
#endif
|
||
|
||
#ifdef HAVE_NET_IF_H
|
||
#include <net/if.h>
|
||
#endif /* HAVE_NET_IF_H */
|
||
|
||
#endif /* IPV6 */
|
||
|
||
#include <sys/stat.h>
|
||
#include "struct.h"
|
||
#include "commands.h"
|
||
#include "parse.h"
|
||
#include "server.h"
|
||
#include "chelp.h"
|
||
#include "encrypt.h"
|
||
#include "vars.h"
|
||
#include "ircaux.h"
|
||
#include "lastlog.h"
|
||
#include "log.h"
|
||
#include "window.h"
|
||
#include "screen.h"
|
||
#include "ircterm.h"
|
||
#include "who.h"
|
||
#include "hook.h"
|
||
#include "input.h"
|
||
#include "ignore.h"
|
||
#include "keys.h"
|
||
#include "names.h"
|
||
#include "alias.h"
|
||
#include "history.h"
|
||
#include "funny.h"
|
||
#include "ctcp.h"
|
||
#include "dcc.h"
|
||
#include "output.h"
|
||
#include "exec.h"
|
||
#include "notify.h"
|
||
#include "numbers.h"
|
||
#include "status.h"
|
||
#include "if.h"
|
||
#include "help.h"
|
||
#include "stack.h"
|
||
#include "queue.h"
|
||
#include "timer.h"
|
||
#include "list.h"
|
||
#include "userlist.h"
|
||
#include "misc.h"
|
||
#include "alist.h"
|
||
#include "tcl_bx.h"
|
||
#include "hash2.h"
|
||
#include "cset.h"
|
||
#include "notice.h"
|
||
#include "module.h"
|
||
|
||
#ifdef TRANSLATE
|
||
#include "translat.h"
|
||
#endif
|
||
|
||
#ifdef WANT_CD
|
||
#include "cdrom.h"
|
||
#endif
|
||
|
||
#define MAIN_SOURCE
|
||
#include "modval.h"
|
||
|
||
#ifdef WANT_TCL
|
||
Tcl_Interp *tcl_interp = NULL;
|
||
#endif
|
||
|
||
#define COMMENT_HACK
|
||
|
||
extern int doing_notice;
|
||
|
||
/* Used to handle and catch breaks and continues */
|
||
int will_catch_break_exceptions = 0;
|
||
int will_catch_continue_exceptions = 0;
|
||
int will_catch_return_exceptions = 0;
|
||
int break_exception = 0;
|
||
int continue_exception = 0;
|
||
int return_exception = 0;
|
||
|
||
|
||
|
||
static void oper_password_received (char *, char *);
|
||
|
||
int load_depth = -1;
|
||
|
||
extern char cx_function[];
|
||
|
||
/* used with /save */
|
||
#define SFLAG_ALIAS 0x0001
|
||
#define SFLAG_ASSIGN 0x0002
|
||
#define SFLAG_BIND 0x0004
|
||
#define SFLAG_ON 0x0008
|
||
#define SFLAG_SET 0x0010
|
||
#define SFLAG_NOTIFY 0x0020
|
||
#define SFLAG_SERVER 0x0040
|
||
#define SFLAG_DIGRAPH 0x0080
|
||
#define SFLAG_WATCH 0x0100
|
||
#define SFLAG_ALL 0xffff
|
||
|
||
/* The maximum number of recursive LOAD levels allowed */
|
||
#define MAX_LOAD_DEPTH 10
|
||
|
||
int interactive = 0;
|
||
|
||
|
||
typedef struct WaitCmdstru
|
||
{
|
||
char *stuff;
|
||
struct WaitCmdstru *next;
|
||
} WaitCmd;
|
||
|
||
static WaitCmd *start_wait_list = NULL,
|
||
*end_wait_list = NULL;
|
||
|
||
char lame_wait_nick[] = "***LW***";
|
||
char wait_nick[] = "***W***";
|
||
|
||
AJoinList *ajoin_list = NULL;
|
||
|
||
BUILT_IN_COMMAND(obits);
|
||
BUILT_IN_COMMAND(debug_user);
|
||
BUILT_IN_COMMAND(debugmsg);
|
||
BUILT_IN_COMMAND(debughook);
|
||
BUILT_IN_COMMAND(evalserver);
|
||
BUILT_IN_COMMAND(purge);
|
||
BUILT_IN_COMMAND(debugfunc);
|
||
BUILT_IN_COMMAND(url_grabber);
|
||
BUILT_IN_COMMAND(breakcmd);
|
||
BUILT_IN_COMMAND(returncmd);
|
||
BUILT_IN_COMMAND(continuecmd);
|
||
BUILT_IN_COMMAND(check_clones);
|
||
BUILT_IN_COMMAND(usleepcmd);
|
||
BUILT_IN_COMMAND(pastecmd);
|
||
BUILT_IN_COMMAND(oper);
|
||
BUILT_IN_COMMAND(epichelp);
|
||
BUILT_IN_COMMAND(spam);
|
||
BUILT_IN_COMMAND(do_mtopic);
|
||
BUILT_IN_COMMAND(xevalcmd);
|
||
BUILT_IN_COMMAND(send_kline);
|
||
BUILT_IN_COMMAND(show_revisions);
|
||
BUILT_IN_COMMAND(ctcp_simple);
|
||
|
||
#ifdef GUI
|
||
BUILT_IN_COMMAND(os2popupmenu);
|
||
BUILT_IN_COMMAND(os2popupmsg);
|
||
BUILT_IN_COMMAND(pmpaste);
|
||
BUILT_IN_COMMAND(pmprop);
|
||
BUILT_IN_COMMAND(os2menu);
|
||
BUILT_IN_COMMAND(os2menuitem);
|
||
BUILT_IN_COMMAND(os2submenu);
|
||
#endif
|
||
|
||
#ifdef __EMXPM__
|
||
BUILT_IN_COMMAND(pmcodepage);
|
||
#endif
|
||
|
||
#ifdef ALLOW_DETACH
|
||
BUILT_IN_COMMAND(detachcmd);
|
||
#endif
|
||
|
||
/*
|
||
* irc_command: all the available IRC commands. Note that the first entry has
|
||
* a zero length string name and a null server command... this little trick
|
||
* makes "/ blah blah blah" to always be sent to a channel, bypassing queries,
|
||
* etc. Neato. This list MUST be sorted.
|
||
*/
|
||
|
||
char relay_help[] = "%R[%n-list|-kick|-wall|-wallop|-msg|-notice|-topic|-kboot|-ansi|-kill|-help%R]%n %Y<%n#|channel|nick%Y> <%nchannel|nick%Y>";
|
||
char scripting_command[] = "- Scripting command";
|
||
|
||
IrcCommand irc_command[] =
|
||
{
|
||
{ "", empty_string, do_send_text, 0, NULL },
|
||
{ "#", NULL, comment, 0, NULL },
|
||
{ "4OP", NULL, do_4op, SERVERREQ, "%Y<%Cnick%Y>%n\n- Sets mode +oooo on %Y<%Cnick%Y>%n"},
|
||
{ ":", NULL, comment, 0, NULL },
|
||
{ "ABORT", NULL, abortcmd, 0, "- Saves IRCII settings then exits IRC" },
|
||
{ "ABOUT", NULL, about, 0, "- Shows yet another ansi screen with greets to people who have contributed to the %PBitchX%n project"},
|
||
{ "ADDFORWARD", "AddForward", do_forward, 0, "%Y<%Bchannel%G|%Cnick%Y>%n\n - Forward all messages to %Y<%Bchannel%G|%Cnick%Y>%n" },
|
||
{ "ADDIDLE", "AddIdle", addidle, 0, "%Y<%Bchannel%Y>%n %R[%nseconds%R]%n\n- Adds %Y<%Bchannel%Y>%n as idle channel with %R[%nseconds%R]%n" },
|
||
{ "ADDLAMENICK","AddLameNick", add_bad_nick, 0, "%Y<%Cnick%G|%Cnick%C nick nick%Y>%n\n - Adds %Y<%Cnick%Y>%n to your lame nicklist, bans nick!*@*"},
|
||
{ "ADDNOFLOOD", "AddNoFlood", add_no_flood, 0, "%Y<%Cnick%Y>%n\n - Adds %Cnick%n to your no flood list" },
|
||
#ifdef WANT_USERLIST
|
||
{ "ADDSHIT", "AddShit", add_shit, 0, "%Y<%Cnick%G|%Cnick%G!%nuser%Y@%nhostname%Y>%n %Y<%Bchannel%G|%Y*>%n %R[%nshitlevel%R]%n %R[%nreason%R]%n\n- Add %Y<%Cnick%G|%Cnick%G!%nuser%Y@%nhostname%Y>%n to your shitlist on %Y<%Bchannel%G|%Y*>%n with %R[%nshitlevel%R]%n and for %R[%nreason%R]%n" },
|
||
{ "ADDUSER", "AddUser", add_user, 0, "%Y<%Cnick%G|%Cnick%G!%nuser%Y@%nhostname%Y>%n %Y<%Bchannel%G|%Y*>%n %R[%nuserlevel%R]%n %R[%nauto-op%R]%n %R[%nprotection%R]%n %R[%npassword%R]%n\n - Adds %Y<%Cnick%G|%Cnick%G!%nuser%Y@%nhostname%Y>%n on %Y<%Bchannel%G|%Y*>%n with %R[%nuserlevel%R]%n %R[%nauto-op%R]%n and %R[%nprotection%R]%n levels to your userlist" },
|
||
#endif
|
||
{ "ADDWORD", NULL, add_ban_word, 0, "%Y<%Bchannel%G|%Y*>%n %Y<%nword%y(%ns%y)%Y>%n\n- Adds %Y<%nword%y(%ns%y)%Y>%n to wordlist, anyone saying it in %Y<%Bchannel%G|%Y*>%n will be kicked" },
|
||
{ "ADMIN", "ADMIN", send_comm, SERVERREQ, "%R[%nserver%R]%n\n- Shows the iRC Administration information on current server or %R[%nserver%R]%n" },
|
||
{ "AJOIN", "AJoin", auto_join, 0, "%Y<%Bchannel%y(%Bs%y)%Y>%n\n- Add %Y<%Bchannel%y(%Bs%y)%Y>%n to AJoin list%P;%n it joins %Y<%Bchannel%y(%Bs%y)%Y>%n on startup or change of server" },
|
||
{ "AJOINLIST", "AJoinList", auto_join, 0, "- Display list of ajoin channels" },
|
||
{ "ALIAS", zero, aliascmd, 0, scripting_command },
|
||
{ "ASSIGN", one, assigncmd, 0, scripting_command },
|
||
{ "AWAY", "Away", away, SERVERREQ, "%R[%nreason%R]%n\n- Sets you away on server if %R[%nreason%R]%n else sets you back" },
|
||
{ "AWAYLOG", "AwayLog", awaylog, 0, "%R[%nALL|MSGS|NOTICES|...%R]%n\n- Displays or changes what you want logged in your lastlog. This is a comma separated list" },
|
||
{ "AWAYMSG", "AwayMsg", away, 0, "Sets your auto-away msg" },
|
||
{ "B", NULL, ban, SERVERREQ, "See %YBAN%n" },
|
||
{ "BACK", "Back", back, SERVERREQ, "- Sets you back from being away" },
|
||
{ "BAN", NULL, ban, 0, "%Y<%Cnick%G|%Cnick%G!%nuser%y@%nhostname%Y>%n\n- Ban %Y<%Cnick%G|%Cnick%G!%nuser%y@%nhostname%Y>%n from current channel" },
|
||
{ "BANSTAT", NULL, banstat, 0, "%R[%Bchannel%R]%n\n- Show bans on current channel or %R[%Bchannel%R]%n" },
|
||
{ "BANTYPE", NULL, bantype, 0, "%W/%nbantype %Y<%nNormal%G|%nBetter%G|%nHost%G|%nDomain%G|%nScrew%G|%nIP%Y>%n\n- When a ban is done on a nick, it uses %Y<%nbantype%Y>%n" },
|
||
{ "BANWORDS", NULL, add_ban_word, 0, "%Y<%nchannel|*%Y>%n word(s)\n- Adds word or words to the banned words list for %Y<%nchannel%Y>" },
|
||
{ "BEEP", NULL, beepcmd, 0, "- Creates a beep noise" },
|
||
#ifdef WANT_CHELP
|
||
{ "BHELP", "BHELP", chelp, 0, "%Y<%nhelp%W|%nindex%W|%nother%Y>%n\n - BitchX help command" },
|
||
#endif
|
||
{ "BIND", NULL, bindcmd, 0, "- Command to bind a key to a function" },
|
||
{ "BK", "BK", kickban, SERVERREQ, "%Y<%Cnick%Y>%n %R[%nreason%R]%n\n- Deops, bans and kicks %Y<%Cnick%Y>%n for %R[%nreason%R]%n" },
|
||
{ "BKI", "BKI", kickban, SERVERREQ, "%Y<%Cnick%Y>%n %R[%nreason%R]%n\n- Deops, bans, kicks and ignores %Y<%Cnick%Y>%n for %R[%nreason%R]%n" },
|
||
{ "BLESS", NULL, blesscmd, 0, scripting_command },
|
||
{ "BREAK", NULL, breakcmd, 0, NULL },
|
||
{ "BYE", "QUIT", e_quit, 0, "- Quit Irc"},
|
||
{ "C", "MODE", send_mode, 0, "%Y<%nnick|channel%Y> <%nmode%Y>%n\n- Sets a mode for a channel or nick"},
|
||
{ "CALL", NULL, e_call, 0, scripting_command },
|
||
#ifndef BITCHX_LITE
|
||
{ "CBOOT", "Cboot", cboot, 0, "%Y<%nnick%Y>%n %R[%nreason%R]%n\n- Kicks a %Y<%nnick%Y>%n off the TwilightZone with %R[%nreason%R]" },
|
||
#endif
|
||
{ "CD", NULL, cd, 0, "%Y<%ndir%Y>%n\n - Changes current directory to %Y<%ndir%Y>%n or prints current directory" },
|
||
#ifdef WANT_CDCC
|
||
{ "CDCC", NULL, cdcc, 0, "%Y<%ncommand%Y>%n\n- Channel, DOffer, Echo, Load, List, MinSpeed, Notice, Offer, PList, Queue, ReSend, Save, Type Describe Note" },
|
||
#endif
|
||
#ifdef WANT_CD
|
||
{ "CDEJECT", NULL, cd_eject, 0, NULL },
|
||
{ "CDHELP", NULL, cd_help, 0, NULL },
|
||
{ "CDLIST", NULL, cd_list, 0, NULL },
|
||
{ "CDPAUSE", NULL, cd_pause, 0, NULL },
|
||
{ "CDPLAY", NULL, cd_play, 0, NULL },
|
||
{ "CDSTOP", NULL, cd_stop, 0, NULL },
|
||
{ "CDVOL", NULL, cd_volume, 0, NULL },
|
||
#endif
|
||
{ "CHANNEL", "JOIN", e_channel, SERVERREQ, "- Shows information on the channels, modes and server you are on" },
|
||
{ "CHANSERV", "CHANSERV", send_comm, SERVERREQ, "- Network services command" },
|
||
{ "CHANST", NULL, channel_stats, SERVERREQ, "%Y<%n-ALL%Y> %R[%Bchannel%R]%n\n- Shows statistics on current channel or %R[%Bchannel%R]%n" },
|
||
{ "CHAT", "Chat", chat, SERVERREQ, "%Y<%nNick%Y>%n\n- Attempts to dcc chat nick" },
|
||
{ "CHATOPS", "CHATOPS", e_wall, SERVERREQ, NULL },
|
||
#ifdef WANT_USERLIST
|
||
{ "CHGAOP", "ChgAop", change_user, 0, "%Y<%Cnick%Y>%n <auto-oplevel>" },
|
||
{ "CHGCHAN", "ChgChan", change_user, 0, "%Y<%Cnick%Y>%n %Y<%Bchannel%Y>%n" },
|
||
{ "CHGLEVEL", "ChgLevel", change_user, 0, "%Y<%Cnick%Y>%n %Y<%nlevel%Y>%n" },
|
||
{ "CHGPASS", "ChgPass", change_user, 0, "%Y<%Cnick%Y>%n %Y<%nprotection-level%Y>%n" },
|
||
{ "CHGPROT", "ChgProt", change_user, 0, "%Y<%Cnick%Y>%n %Y<%nprotection-level%Y>%n" },
|
||
{ "CHGUH", "ChgUH", change_user, 0, "%Y<%Cnick%Y>%n %Y<%nuserhost%Y>%n" },
|
||
#endif
|
||
{ "CHOPS", "Chops", users, SERVERREQ, "%R[%Bchannel%R]%n\n- Shows, in a full format, all the nicks with op status" },
|
||
{ "CLEAR", NULL, my_clear, 0, "- Clears the screen" },
|
||
{ "CLEARAUTO", "CLEARAUTO", clear_tab, 0, "- Clears all the nicks in the auto-response list" },
|
||
{ "CLEARLOCK", "ClearLock", mode_lock, 0, "%Y<%Cchannel%G|%Y*>%n\n- Unlocks the mode lock for %Y<%Cchannel%G|%Y*>%n" },
|
||
{ "CLEARTAB", NULL, clear_tab, 0, "- Clears the nicks in the tabkey list" },
|
||
#ifndef BITCHX_LITE
|
||
{ "CLINK", "Clink", clink, 0, "%Y<%Cnick%Y>%n %Y<%ntext%Y>%n" },
|
||
{ "CLONES", "Clones", check_clones, SERVERREQ, NULL },
|
||
{ "CMSG", "Cmsg", cmsg, 0, "%Y<%Cnick%Y>%n %Y<%ntext%Y>%n\n- While in the TwilightZone, a private message will be sent to %Y<%Cnick%Y>%n with %Y<%ntext%Y>%n" },
|
||
#else
|
||
{ "CLONES", "Clones", check_clones, SERVERREQ, NULL },
|
||
#endif
|
||
#ifdef __EMXPM__
|
||
{ "CODEPAGE", "CODEPAGE", pmcodepage, 0, "OS/2 - Changes the current VIO Codepage" },
|
||
#endif
|
||
{ "CONNECT", "CONNECT", send_comm, SERVERREQ, "%Y<%nserver1%Y>%n %Y<%nport%Y>%n %R[%nserver2%R]%n\n%Y*%n Requires irc operator status" },
|
||
{ "CONTINUE", NULL, continuecmd, 0, NULL },
|
||
#ifndef BITCHX_LITE
|
||
{ "CSAY", "Csay", csay, 0, "%Y<%ntext%Y>%n" },
|
||
#endif
|
||
{ "CSET", "Cset", cset_variable, 0, "%R[%n*|channel|chan*%R]%n\n- changes variables that affect a channel or displays them" },
|
||
{ "CTCP", NULL, ctcp, SERVERREQ, "%Y<%Cnick%Y>%n %Y<%nrequest%Y>%n\n- CTCP sends %Y<%Cnick%Y>%n with %Y<%nrequest%Y>%n" },
|
||
#ifndef BITCHX_LITE
|
||
{ "CTOGGLE", NULL, toggle_xlink, 0, NULL },
|
||
{ "CWHO", "Cwho", cwho, 0, "- Lists the clients and bots connected to the TwilightZone" },
|
||
{ "CWHOM", "Cwhom", cwho, 0, "- Lists the clients and bots connected to the TwilightZone" },
|
||
#endif
|
||
{ "CYCLE", NULL, cycle, SERVERREQ, "%R[%Bchannel%R]%n\n- Leaves current channel or %R[%Bchannel%R]%n and immediately rejoins" },
|
||
{ "D", NULL, describe, SERVERREQ, "See %YDESCRIBE%n" },
|
||
{ "DATE", "TIME", send_comm, SERVERREQ, "- Shows current time and date from current server" },
|
||
{ "DBAN", NULL, unban, SERVERREQ, "- Clears all bans on current channel" },
|
||
{ "DC", NULL, init_dcc_chat, SERVERREQ, "%Y<%Cnick%Y>%n\n- Starts a DCC CHAT to %Y<%Cnick%Y>%n" },
|
||
{ "DCA", "Dca", dcx, 0, "- Kills all dcc connections" },
|
||
{ "DCC", NULL, dcc, 0, "Displays a active DCC list. For more info /dcc help" },
|
||
{ "DCG", "Dcg", dcx, 0, "%Y<%nnick%Y>%n\n- Kills all dcc gets to %Y<%nnick%Y>" },
|
||
{ "DCS", "Dcs", dcx, 0, "%Y<%nnick%Y>%n\n- Kills all dcc sends to %Y<%nnick%Y>" },
|
||
{ "DCX", "Dcx", dcx, 0, "%Y<%nnick%Y>%n\n- Kills all dcc chats to %Y<%nnick%Y>" },
|
||
{ "DEBUG", NULL, e_debug, 0, "%R[%nflags%R]%n\n- Sets various debug flags in the client" },
|
||
{ "DEBUGFUNC", NULL, debugfunc, 0, NULL },
|
||
{ "DEBUGHASH", NULL, show_hash, 0, NULL },
|
||
{ "DEBUGMSG", NULL, debugmsg, 0, NULL },
|
||
#ifdef WANT_USERLIST
|
||
{ "DEBUGUSER", NULL, debug_user, 0, NULL },
|
||
#endif
|
||
{ "DEHOP", "h", dodeop, SERVERREQ, "%Y<%C%nnick(s)%Y>%n\n- Removes halfops from %Y<%Cnick%y(%Cs%y)%Y>%n" },
|
||
{ "DEOP", "o", dodeop, SERVERREQ, "%Y<%C%nnick(s)%Y>%n\n- Deops %Y<%Cnick%y(%Cs%y)%Y>%n" },
|
||
{ "DEOPER", NULL, deop, SERVERREQ, "%Y*%n Requires irc operator status\n- Removes irc operator status" },
|
||
{ "DESCRIBE", NULL, describe, SERVERREQ, "%Y<%Cnick%G|%Bchannel%Y>%n %Y<%naction%Y>%n\n- Describes to %Y<%Cnick%G|%Bchannel%Y>%n with %Y<%naction%Y>%n" },
|
||
#ifdef ALLOW_DETACH
|
||
{ "DETACH", NULL, detachcmd, 0, NULL },
|
||
#endif
|
||
{ "DEVOICE", "v", dodeop, SERVERREQ, "%Y<%C%nnick(s)%Y>%n\n- de-voices %Y<%Cnick%y(%Cs%y)%Y>%n" },
|
||
#if !defined(WINNT) && !defined(__EMX__)
|
||
{ "DF", "df", exec_cmd, 0, "- Show disk space usage" },
|
||
#endif
|
||
{ "DIE", "DIE", send_comm, SERVERREQ, "%Y*%n Requires irc operator status\n- Kills the IRC server you are on" },
|
||
#ifdef TRANSLATE
|
||
{ "DIGRAPH", NULL, digraph, 0, NULL },
|
||
#endif
|
||
{ "DISCONNECT", NULL, disconnectcmd, 0, "- Disconnects you from the current server" },
|
||
{ "DLINE", "DLINE", send_kline, SERVERREQ, NULL },
|
||
{ "DME", "dme", me, SERVERREQ, "<action>\n- Sends an action to current dcc" },
|
||
{ "DNS", "NSlookup", nslookup, 0, "%YDNS<%nnick|hostname%y>%n\n- Attempts to nslookup on nick or hostname"},
|
||
{ "DO", NULL, docmd, 0, scripting_command },
|
||
{ "DOP", "o", dodeop, SERVERREQ, "- See deop" },
|
||
{ "DS", NULL, dcc_stat_comm, 0, "- Displays some dcc file transfer stats" },
|
||
{ "DUMP", "Dump", dumpcmd, 0, "%Y<%ntype%Y>%n\n- Dumps %Y<%ntype%Y>%n to screen\n%Y<%ntype%Y>%n:\n%YAlias%n %YAll%n %YBind%n %YChstats%n %YFsets%n\n%YFile%n %YOn%n %YVar%n %YTimers%n %YWsets%n %YCsets%n" },
|
||
{ "ECHO", NULL, echocmd, 0, "<text>\n- Echos text to the screen" },
|
||
#ifdef WANT_EPICHELP
|
||
{ "EHELP", NULL, epichelp, 0, NULL },
|
||
#endif
|
||
{ "ENCRYPT", NULL, encrypt_cmd, 0, NULL },
|
||
{ "EVAL", "EVAL", evalcmd, 0, scripting_command },
|
||
{ "EVALSERVER", NULL, evalserver, 0, "<refnum> <command> sends to <refnum> server command" },
|
||
#if !defined(WINNT)
|
||
{ "EXEC", NULL, execcmd, 0, "%Y<%ncommand%Y>%n\n- Executes %Y<%ncommand%Y>%n with the shell set from %PSHELL%n" },
|
||
#endif
|
||
{ "EXIT", "QUIT", e_quit, 0, "- Quits IRC" },
|
||
{ "FE", "Fe", fe, 0, scripting_command },
|
||
{ "FEC", "Fec", fe, 0, scripting_command },
|
||
#ifdef GUI
|
||
{ "FILEDIALOG", NULL, filedialog, 0, "GUI - File dialog" },
|
||
#endif
|
||
{ "FINGER", "FINGER", ctcp_simple, 0, "%Y<%Cnick%Y>%n\n- Sends a CTCP FINGER query to %Y<%Cnick%Y>%n" },
|
||
{ "FK", "FK", masskick, SERVERREQ, "%Y<%Cnick%G!%nuser%Y@%nhostname%Y>%n%R[%nreason%R]%n\nFinds clienTs matching %Y<%Cnick%G!%nuser%Y@%nhostname%Y>%n and immediately kicks them from current channel for %R[%nreason%R]%n" },
|
||
{ "FLUSH", NULL, flush, 0, "- Flush ALL server output" },
|
||
#ifdef GUI
|
||
{ "FONTDIALOG", NULL, fontdialog, 0, "GUI - Font Dialog" },
|
||
#endif
|
||
{ "FOR", NULL, forcmd, 0, scripting_command },
|
||
{ "FOREACH", NULL, foreach, 0, scripting_command },
|
||
{ "FORWARD", "Forward", do_forward, 0, "%Y<%Cnick%Y>%n\n- Forwards all messages to %Y<%Cnick%Y>%n" },
|
||
{ "FPORTS", NULL, findports, 0, "%Y<%nhostname%Y>%n %R[%Y<%nlowport%Y>%n %Y<%nhighport%Y>%R]%n\n- Attempts to find ports on %Y<%nhostname%Y>%n on %R[%Y<%nlowport%Y>%n %Y<%n %Y<%nhighport%Y>%R]%n" },
|
||
{ "FPROT", "FProt", tog_fprot, 0, "- Toggles flood protection to be either on or off" },
|
||
{ "FSET", "Fset", fset_variable, 0, "- Setting various output formats" },
|
||
#ifdef WANT_FTP
|
||
{ "FTP", "Ftp", init_ftp, 0, "%Y<%nhostname%Y> %R[%nlogin%R] [%npassword%R] [%n-p port%R]%n\n- Open a ftp connection to a host" },
|
||
#endif
|
||
{ "FUCK", "Fuck", kickban, SERVERREQ, "%Y<%Cnick%Y>%n %R[%nreason%R]%n\n- Deops, bans and kicks %Y<%Cnick%Y>%n for %R[%nreason%R]%n" },
|
||
{ "FUCKEM", NULL, fuckem, SERVERREQ, NULL },
|
||
{ "GONE", "Gone", away, SERVERREQ, "%R[%nreason%R]%n\n- Sets you away on server if %R[%nreason%R]%n else sets you back. Does not announce to your channels." },
|
||
{ "HASH", "HASH", send_comm, SERVERREQ, "Server command"},
|
||
{ "HELP", NULL, help, 0, NULL },
|
||
{ "HELPOP", "HELPOP", send_comm, SERVERREQ, NULL },
|
||
{ "HELPSERV", "HELPSERV", send_comm, SERVERREQ, "- Network services command" },
|
||
{ "HISTORY", NULL, history, 0, "- Shows recently typed commands" },
|
||
{ "HOOK", NULL, hookcmd, 0, scripting_command },
|
||
{ "HOP", "h", doop, SERVERREQ, "%Y<%Cnick%Y>%n\n- Gives %Y<%Cnick%Y>%n +h" },
|
||
{ "HOST", "USERHOST", userhostcmd, 0, "- Shows host of yourself or %R[%Cnick%R]%n" },
|
||
{ "HOSTNAME", "HOSTNAME", e_hostname, 0, "%Y<%nhostname%Y>%n\n- Shows list of possible hostnames with option to change it on virtual hosts" },
|
||
{ "I", "INVITE", do_invite, SERVERREQ, "- See %YINVITE%n" },
|
||
{ "IF", "IF", ifcmd, 0, scripting_command },
|
||
{ "IG", "Ig", do_ig, 0, "+%G|%n-%Y<%Cnick%Y>%n\n- Ignores ALL except crap and public of nick!host matching %Y<%Cnick%Y>%n" },
|
||
{ "IGH", "IgH", do_ig, 0, "+%G|%n-%Y<%Cnick%Y>%n\n- Ignores ALL except crap and public of hostname matching %Y<%Cnick%Y>%n" },
|
||
{ "IGHT", "IgHt", do_ig, 0, "+%G|%n-%Y<%Cnick%Y>%n\n- Ignores ALL except crap and public of hostname matching %Y<%Cnick%Y>%n and expires this on a timer"},
|
||
{ "IGNORE", NULL, ignore, 0, NULL },
|
||
{ "IGT", "Igt", do_ig, 0, "+%G|%n-%Y<%Cnick%Y>%n\n- Ignores ALL except crap and public of nick!host matching %Y<%Cnick%Y>%n and expires this on a timer" },
|
||
{ "INFO", "INFO", info, 0, "- Shows current client info" },
|
||
{ "INPUT", "Input", inputcmd, 0, scripting_command },
|
||
{ "INPUT_CHAR", "Input_Char", inputcmd, 0, scripting_command },
|
||
{ "INVITE", "INVITE", do_invite, SERVERREQ, "%Y<%Cnick%Y>%n %R[%Bchannel%R]%n\n- Invites %Y<%Cnick%Y>%n to current channel or %R[%Bchannel%R]%n" },
|
||
{ "IRCHOST", "HOSTNAME", e_hostname, 0, "%Y<%nhostname%Y>%n\n- Shows list of possible hostnames with option to change it on virtual hosts" },
|
||
{ "IRCNAME", NULL, realname_cmd, 0, NULL },
|
||
{ "IRCUSER", NULL, set_username, 0, "<username>\n- Changes your <username>" },
|
||
{ "ISON", "ISON", isoncmd, SERVERREQ, NULL },
|
||
{ "J", "JOIN", e_channel, SERVERREQ, "%Y<%nchannel%Y> %R[%nkey%R]%n\n- Joins a %Y<%nchannel%Y>" },
|
||
{ "JNW", "Jnw", jnw, SERVERREQ, "%Y<%nchannel%Y> %R[%nkey%R]%n %R[%n-hide%R]%n\n- Joins a %Y<%nchannel%Y>%n in a new window"},
|
||
{ "JOIN", "JOIN", e_channel, SERVERREQ, NULL },
|
||
{ "K", NULL, dokick, SERVERREQ, "%Y<%Cnick%Y>%n %R[%nreason%R]%n\n- Kicks %Y<%Cnick%Y>%n for %R[%nreason%R]%n on current channel" },
|
||
{ "KB", "KB", kickban, SERVERREQ, "%Y<%Cnick%Y>%n %R[%nreason%R]%n\n- Deops, kicks and bans %Y<%Cnick%Y>%n for %R[%nreason%R]%n" },
|
||
{ "KBI", "KBI", kickban, SERVERREQ, "%Y<%Cnick%Y>%n %R[%nreason%R]%n\n- Deops, kicks and bans %Y<%Cnick%Y>%n for %R[%nreason%R]%n" },
|
||
{ "KICK", "KICK", send_kick, SERVERREQ, "%Y<%Bchannel%G|%Y*>%n %Y<%Cnick%Y>%n %R[%nreason%R]%n" },
|
||
{ "KICKIDLE", "KickIdle", kickidle, SERVERREQ, "%Y<%Bchannel%Y>%n\n- Kicks all idle people on %Y<%Bchannel%Y>%n" },
|
||
{ "KILL", "KILL", send_kill, SERVERREQ, "%Y<%Cnick%Y>%n %R[%nreason%R]%n\n%Y*%n Requires irc operator status\n- Kills %Y<%Cnick%Y>%n for %R[%nreason%R]%n" },
|
||
{ "KLINE", "KLINE", send_kline, SERVERREQ, "%Y<%nuser%y@%nhost%Y> <%nreason%Y>%n\n%Y*%n Requires irc operator status\n- Adds a K-line to the server configfile" },
|
||
{ "KNOCK", "KNOCK", send_channel_com, SERVERREQ, NULL },
|
||
{ "L", "PART", do_getout, SERVERREQ, "- See %YLEAVE" },
|
||
{ "LAMENICKLIST",NULL, add_bad_nick, 0, "- Lists nicks in your lame nick list" },
|
||
{ "LASTLOG", NULL, lastlog, 0, "-file filename%G|%n-clear%G|%n-max #%G|%n-liternal pat%G|%n-beep%G|%nlevel" },
|
||
{ "LEAVE", "PART", send_comm, SERVERREQ, "%Y<%Bchannel%Y>%n\n- Leaves current channel or %Y<%Bchannel%Y>%n" },
|
||
{ "LINKS", "LINKS", send_comm, SERVERREQ, "- Shows servers and links to other servers" },
|
||
{ "LIST", "LIST", funny_stuff, SERVERREQ, "- Lists all channels" },
|
||
#ifdef WANT_DLL
|
||
{ "LISTDLL", "LISTDLL", dll_load, 0, "- List currently loaded plugins" },
|
||
#endif
|
||
{ "LK", "LameKick", LameKick, SERVERREQ, "%R[%nreason%R]%n\n- Kicks all non +o people on current channel with %R[%nreason%R]%n" },
|
||
{ "LKW", "Lkw", lkw, SERVERREQ, "%R[%Bchannel%R]%n\n- Leave the current channel, killing the window in current channel or%R[%Bchannel%R]%n as well" },
|
||
{ "LLOOK", NULL, linklook, SERVERREQ, "%Y*%n Requires set %YLLOOK%n %RON%n\n- Lists all the servers which are current split from the IRC network" },
|
||
{ "LOAD", "LOAD", BX_load, 0, "filename\n- Loads filename as a irc script" },
|
||
#ifdef WANT_DLL
|
||
{ "LOADDLL", NULL, dll_load, 0, "filename.so\n- Loads filename as a dll"},
|
||
#endif
|
||
#ifdef WANT_TCL
|
||
{ "LOADTCL", NULL, tcl_load, 0, "filename.tcl\n- Loads a tcl file" },
|
||
#endif
|
||
|
||
{ "LOCAL", "2", localcmd, 0, scripting_command },
|
||
{ "LOCOPS", "LOCOPS", e_wall, SERVERREQ, NULL },
|
||
#if !defined(WINNT)
|
||
{ "LS", "ls", exec_cmd, 0, "- Displays list of file" },
|
||
#endif
|
||
{ "LUSERS", "LUSERS", send_comm, SERVERREQ, "- Shows stats on current server" },
|
||
{ "M", "PRIVMSG", e_privmsg, 0, "See %YMSG%n" },
|
||
{ "MAP", NULL, do_map, 0, "- Displays a map of the current servers"},
|
||
{ "MB", NULL, massban, SERVERREQ, "- Mass bans everybody on current channel" },
|
||
{ "MD", NULL, massdeop, SERVERREQ, "- Mass deops current channel" },
|
||
{ "MDOP", NULL, massdeop, SERVERREQ, "- Mass deops current channel" },
|
||
{ "MDVOICE", "MDVoice", massdeop, SERVERREQ, "- Mass de-voices current channel" },
|
||
{ "ME", NULL, me, SERVERREQ, "<action>\n- Sends an action to current channel" },
|
||
{ "MEMOSERV", "MEMOSERV", send_comm, SERVERREQ, "- Network services command" },
|
||
#ifdef GUI
|
||
{ "MENU", NULL, os2menu, 0, "GUI - Creates or removes a menu" },
|
||
{ "MENUITEM", NULL, os2menuitem, 0, "GUI - Adds a menuitem to a menu" },
|
||
#endif
|
||
{ "MESG", NULL, extern_write, 0, "<YesB|BNoB||BOnB|BOff>\n- Turns mesg <Yes|No|On|Off>" },
|
||
{ "MK", NULL, masskick, SERVERREQ, "- Mass kicks current channel" },
|
||
{ "MKB", "MKB", masskickban, SERVERREQ, "- Mass kick bans current channel" },
|
||
{ "MKNU", NULL, mknu, SERVERREQ, "- Mass kick bans non-userlist users on current channel" },
|
||
{ "MODE", "MODE", send_channel_com, SERVERREQ, "%Y<%n#channel%W|%nnick%Y>%B +-%Y<%nmode%Y>%n" },
|
||
{ "MODELOCK", "ModeLock", mode_lock, 0, "%Y<%Bchannel%Y>%n +%G|%n-%Y<%ninstampkl #%Y>%n\n- Locks %Y<%Bchannel%Y>%n with +%G|%n-%Y<%nmodes%Y>%n" },
|
||
{ "MOP", NULL, massop, SERVERREQ, "- Mass ops everybody on current channel" },
|
||
{ "MORE", "More", readlog, 0, "%R[%nfilename%R]%n\n- displays file in pages" },
|
||
{ "MOTD", "MOTD", send_comm, SERVERREQ, "%R[%nserver%R]%n\n- Shows MOTD on current server %R[%nserver%R]%n" },
|
||
{ "MSAY", "MSay", do_msay, 0, NULL },
|
||
{ "MSG", "PRIVMSG", e_privmsg, 0, "%Y<%C[=]nick%Y>%n %Y<%ntext%Y>%n\n- Send %Y<%Cnick%Y>%n a message with %Y<%ntext%Y>%n" },
|
||
{ "MTOPIC", "MTopic", do_mtopic, 0, NULL },
|
||
{ "MUB", NULL, unban, SERVERREQ, "- Mass unbans current channel" },
|
||
{ "MULT", NULL, multkick, SERVERREQ, "%Y<%nnick(s)%Y>%n %R[%nreason%R]%n\n- Kicks all %Y<%nnick(s)%Y>%n with %R[%nreason%R]" },
|
||
{ "MVOICE", "MVoice", massop, SERVERREQ, "%R[%Cnick%G|%Bchannel%G|%Cnick%Y!%Cuser%Y@%nhostname%Y]%n\n- Mass voice nicks matching %R[%Cnick%G|%Bchannel%G|%Cnick%Y!%Cuser%Y@%nhostname%Y]%n" },
|
||
{ "N", "NAMES", do_mynames, 0, NULL },
|
||
{ "NAMES", "NAMES", funny_stuff, SERVERREQ, "%R[%Bchannel%R]%n\n- Shows names on current channel or %R[%Bchannel%R]%n" },
|
||
{ "NEWNICK", NULL, newnick, 0, NULL },
|
||
{ "NEWUSER", NULL, newuser, 0, NULL },
|
||
{ "NICK", "NICK", e_nick, 0, "-Changes nick to specified nickname" },
|
||
{ "NICKSERV", "NICKSERV", send_comm, SERVERREQ, "- Network services command" },
|
||
{ "NOCHAT", "NoChat", chat, 0, "%Y<%nnick%Y>%n\n- Kills chat reqest from %Y<%nnick%Y>" },
|
||
{ "NOPS", "Nops", users, 0, "%R[%Bchannel%R]%n\n- Shows, in a full format, all the nicks without ops in %R[%Bchannel%R]%n or channel" },
|
||
{ "NOTE", "NOTE", send_comm, SERVERREQ, NULL },
|
||
{ "NOTICE", "NOTICE", e_privmsg, 0, "%Y<%Cnick%G|%Bchannel%Y> %Y<%ntext%Y>%n\n- Sends a notice to %Y<%Cnick%G|%Bchannel%Y> with %Y<%ntext%Y>%n" },
|
||
{ "NOTIFY", NULL, notify, 0, "%Y<%Cnick|+|-nick%Y>%n\n- Adds/displays/removes %Y<%Cnick%Y>%n to notify list" },
|
||
{ "NSLOOKUP", "NSLookup", nslookup, 0, "%Y<%nhostname%Y>%n\n- Looks up the IP addresses for %Y<%nhostname%Y>%n" },
|
||
{ "NWHOIS", NULL, nwhois, 0, "%Y<%Cnick|channel%Y>%n\n- Shows internal statistics for %Y<%Cnick%Y>%n" },
|
||
{ "NWHOWAS", NULL, whowas, 0, "- Displays internal whowas info for all channels. This information expires after 20 minutes for users on internal list, 10 minutes for others" },
|
||
{ "OBITS", NULL, obits, 0, "- Displays obituaries for some BitchX friends who have left us" },
|
||
{ "OFFERS", "Offers", do_offers, 0, NULL },
|
||
{ "ON", NULL, oncmd, 0, scripting_command },
|
||
{ "OOPS", NULL, do_oops, SERVERREQ, "%Y<%Cnick%Y>%n\n- Sends a oops message to last recipient of a message and sends the correct message to %Y<%Cnick%Y>%n" },
|
||
{ "OP", "o", doop, SERVERREQ, "%Y<%Cnick%Y>%n\n- Gives %Y<%Cnick%Y>%n +o" },
|
||
{ "OPER", "OPER", oper, SERVERREQ, "%Y*%n Requires irc operator status\n%Y<%Cnick%Y>%n %R[%npassword%R]%n" },
|
||
{ "OPERSERV", "OPERSERV", send_comm, SERVERREQ, "- Network services command" },
|
||
{ "OPERWALL", "OPERWALL", e_wall, 0, NULL },
|
||
{ "ORIGNICK", "OrigNick", orig_nick, 0, "%Y<%Cnick%Y>%n\n- Attempts to regain a nick that someone else has taken from you." },
|
||
{ "OSTAT", NULL, serv_stat, 0, "-Displays some internal statistics gathered about the server" },
|
||
#ifdef WANT_OPERVIEW
|
||
{ "OV", NULL, ov_window, 0, "%R[%non|off%R]%n %R[%-hide|+hide|hide%R]%n\n- turns on/off oper view window as well as creating hidden window" },
|
||
#endif
|
||
{ "P", "Ping", pingcmd, 0, "%Y<%nnick%Y>%n\n- Pings %Y<%nnick%Y>" },
|
||
{ "PARSEKEY", NULL, parsekeycmd, 0, scripting_command },
|
||
{ "PART", "PART", send_2comm, SERVERREQ, "- Leaves %Y<%nchannel%Y>%n" },
|
||
{ "PARTALL", "PARTALL", do_getout, 0, "- Leaves all channels" },
|
||
{ "PASTE", NULL, pastecmd, 0, NULL },
|
||
{ "PAUSE", NULL, e_pause, 0, scripting_command },
|
||
{ "PING", NULL, pingcmd, 0, "%Y<%nnick%Y>%n\n- Pings %Y<%nnick%Y>" },
|
||
#ifdef GUI
|
||
{ "PMPASTE", NULL, pmpaste, 0, "GUI - Clipboard Paste Command" },
|
||
#endif
|
||
{ "POP", NULL, pop_cmd, 0, scripting_command },
|
||
#ifdef GUI
|
||
{ "POPUPMENU", NULL, os2popupmenu, 0, "GUI - Popup Menu Command" },
|
||
{ "POPUPMSG", NULL, os2popupmsg, 0, "GUI - Popup Message Command" },
|
||
#endif
|
||
{ "PRETEND", NULL, pretend_cmd, 0, scripting_command },
|
||
#ifdef GUI
|
||
{ "PROPERTIES", NULL, pmprop, 0, "GUI - Properties Dialog" },
|
||
#endif
|
||
{ "PS", "ps", exec_cmd, 0, "- Displays process table" },
|
||
{ "PURGE", NULL, purge, 0, "<variable>\n- Removes all traces of variable(s) specified"},
|
||
{ "PUSH", NULL, push_cmd, 0, scripting_command },
|
||
{ "Q", NULL, query, 0, "%Y<%n-cmd cmdname%Y> <%Cnick%Y>%n\n- Starts a query to %Y<%Cnick%Y>%n" },
|
||
{ "QME", "qme", me, 0, "- Sends a action to a query" },
|
||
{ "QUERY", NULL, query, 0, "%Y<%n-cmd cmdname%Y> <%Cnick%Y>%n\n- Starts a query to %Y<%Cnick%Y>%n" },
|
||
{ "QUEUE", NULL, queuecmd, 0, scripting_command },
|
||
{ "QUIT", "QUIT", e_quit, 0, "- Quit BitchX" },
|
||
{ "QUOTE", "QUOTE", quotecmd, 0, "%Y<%ntext%Y>%n\n- Sends text directly to the server" },
|
||
{ "RANDOMNICK", NULL, randomnick, 0, "%Y<%Cnick%Y>%n\n- Changes your nick to a random nick. If nick is specified is is used as a prefix" },
|
||
{ "RBIND", NULL, rbindcmd, 0, "- Removes a key binding" },
|
||
{ "READLOG", "ReadLog", readlog, 0, "- Displays current away log" },
|
||
{ "RECONNECT", NULL, reconnect_cmd, 0, "- Reconnects you to current server" },
|
||
{ "REDIRECT", NULL, redirect, 0, "%Y<%Cnick%G|%Bchannel%Y> <command>\n- Redirects <command> to %Y<%Cnick%G|%Bchannel%Y>" },
|
||
{ "REHASH", "REHASH", send_comm, SERVERREQ, "%Y*%n Requires irc operator status\n- Rehashs ircd.conf for new configuration" },
|
||
{ "REINIT", NULL, init_vars, 0, "- Reinitializes internal variables" },
|
||
{ "REINITSTAT", NULL, init_window_vars, 0, "- Reinitializes window variables" },
|
||
|
||
{ "REL", "Rel", do_dirlasttype, 0, relay_help },
|
||
|
||
{ "RELC", "RelC", do_dirlasttype, 0, relay_help },
|
||
{ "RELCR", "RelCR", do_dirlasttype, 0, relay_help },
|
||
{ "RELCRT", "RelCRT", do_dirlasttype, 0, relay_help },
|
||
{ "RELCT", "RelCT", do_dirlasttype, 0, relay_help },
|
||
{ "RELD", "RelD", do_dirlasttype, 0, relay_help },
|
||
{ "RELDT", "RelDT", do_dirlasttype, 0, relay_help },
|
||
|
||
{ "RELI", "RelI", do_dirlasttype, 0, relay_help },
|
||
{ "RELIT", "RelIT", do_dirlasttype, 0, relay_help },
|
||
{ "RELM", "RelM", do_dirlasttype, 0, relay_help },
|
||
{ "RELMT", "RelMT", do_dirlasttype, 0, relay_help },
|
||
{ "RELN", "RelN", do_dirlasttype, 0, relay_help },
|
||
{ "RELNT", "RelNT", do_dirlasttype, 0, relay_help },
|
||
|
||
{ "RELOAD", NULL, reload_save, 0, "- Reloads BitchX.sav" },
|
||
|
||
{ "RELS", "RelS", do_dirlasttype, 0, relay_help },
|
||
{ "RELSD", "RelSd", do_dirlasttype, 0, relay_help },
|
||
{ "RELSDT", "RelSdT", do_dirlasttype, 0, relay_help },
|
||
{ "RELSM", "RelSM", do_dirlasttype, 0, relay_help },
|
||
{ "RELSMT", "RelSMT", do_dirlasttype, 0, relay_help },
|
||
|
||
{ "RELSN", "RelSN", do_dirlasttype, 0, relay_help },
|
||
{ "RELSNT", "RelSNT", do_dirlasttype, 0, relay_help },
|
||
{ "RELST", "RelST", do_dirlasttype, 0, relay_help },
|
||
{ "RELSTT", "RelSTT", do_dirlasttype, 0, relay_help },
|
||
|
||
{ "RELSW", "RelSW", do_dirlasttype, 0, relay_help },
|
||
{ "RELSWT", "RelSWT", do_dirlasttype, 0, relay_help },
|
||
|
||
{ "RELT", "RelT", do_dirlasttype, 0, relay_help },
|
||
{ "RELTT", "RelTT", do_dirlasttype, 0, relay_help },
|
||
{ "RELW", "RelW", do_dirlasttype, 0, relay_help },
|
||
{ "RELWT", "RelWT", do_dirlasttype, 0, relay_help },
|
||
|
||
|
||
{ "REMLOG", "RemLog", remove_log, 0, "- Removes logfile" },
|
||
{ "REPEAT", NULL, repeatcmd, 0, "%Y<%ntimes%Y>%n %Y<%ncommand%Y>%n\n- Repeats %Y<%ntimes%Y>%n %Y<%ncommand%Y>%n" },
|
||
{ "REQUEST", NULL, ctcp, 0, "%Y<%Cnick%G|%Bchannel%Y>%n %Y<%nrequest%Y>%n\n- Sends CTCP %Y<%nrequest%Y>%n to %Y<%Cnick%G|%Bchannel%Y>%n" },
|
||
{ "RESET", NULL, reset, 0, "- Fixes flashed terminals" },
|
||
{ "RESTART", "RESTART", send_comm, SERVERREQ, "%Y*%n Requires irc operator status\n- Restarts server" },
|
||
{ "RETURN", NULL, returncmd, 0, NULL },
|
||
{ "REVISIONS", NULL, show_revisions, 0, "- Shows CVS revisions of source files." },
|
||
/* nuxx requested this command */
|
||
{ "RMAP", "MAP", send_2comm, SERVERREQ, "- Sends out a /map command to the server%n" },
|
||
{ "RPING", "RPING", send_comm, SERVERREQ, NULL },
|
||
{ "SAVE", "SaveAll", savelists, 0, "- Saves ~/.BitchX/BitchX.sav" },
|
||
{ "SAVEIRC", NULL, save_settings, 0, "- Saves ~/.bitchxrc" },
|
||
{ "SAVELIST", NULL, savelists, 0, "- Saves ~/.BitchX/BitchX.sav" },
|
||
{ "SAY", empty_string, do_send_text, 0, "-%Y<%ntype%Y>%n Says whatever you write" },
|
||
{ "SC", "NAMES", do_mynames, 0, NULL },
|
||
{ "SCAN", "scan", do_scan, 0, "%R[%Bchannel%R]%n\n- Scans %R[%Bchannel%R]%n or current channel for all nicks" },
|
||
{ "SCANB", "ScanB", do_scan, 0, "%R[%Bchannel%R]%n\n- Scans %R[%Bchannel%R]%n or current channel for bots" },
|
||
{ "SCANF", "ScanF", do_scan, 0, "%R[%Bchannel%R]%n\n- Scans %R[%Bchannel%R]%n or current channel for friends" },
|
||
{ "SCANI", "ScanI", do_scan, 0, "%R[%Bchannel%R]%n\n- Scans %R[%Bchannel%R]%n or current channel for ircops" },
|
||
{ "SCANN", "ScanN", do_scan, 0, "%R[%Bchannel%R]%n\n- Scans %R[%Bchannel%R]%n or current channel for non-ops" },
|
||
{ "SCANO", "ScanO", do_scan, 0, "%R[%Bchannel%R]%n\n- Scans %R[%Bchannel%R]%n or current channel for ops" },
|
||
{ "SCANS", "ScanS", do_scan, 0, "%R[%Bchannel%R]%n\n- Scans %R[%Bchannel%R]%n or current channel for shitlisted nicks" },
|
||
{ "SCANV", "ScanV", do_scan, 0, "%R[%Bchannel%R]%n\n- Scans %R[%Bchannel%R]%n or current channel for voice" },
|
||
{ "SEND", NULL, do_send_text, 0, NULL },
|
||
{ "SENDLINE", empty_string, sendlinecmd, 0, NULL },
|
||
{ "SERVER", NULL, servercmd, 0, "%Y<%nserver%Y>%n\n- Changes to %Y<%nserver%Y>%n" },
|
||
{ "SERVLIST", "SERVLIST", send_comm, SERVERREQ, "- Displays available services" },
|
||
{ "SET", NULL, setcmd, 0, "- Set Variables" },
|
||
{ "SETAR", NULL, set_autoreply, 0, "%Y<%n-|d|pat1 pat2 ..%Y>%n\n- Adds or removes from your auto-response" },
|
||
{ "SETENV", NULL, setenvcmd, 0, NULL },
|
||
{ "SHIFT", NULL, shift_cmd, 0, scripting_command },
|
||
#ifdef WANT_USERLIST
|
||
{ "SHITLIST", NULL, showshitlist, 0, "- Displays internal shitlist" },
|
||
#endif
|
||
{ "SHOOK", NULL, shookcmd, 0, NULL },
|
||
{ "SHOWIDLE", "ShowIdle", showidle, 0, "%Y<-sort %R[none|time|host|nick%R]%Y> %R[%Bchannel%R]%n\n- Shows idle people on current channel or %R[%Bchannel%R]%n" },
|
||
{ "SHOWLOCK", "ShowLock", mode_lock, 0, "- Show the mode lock on the channel" },
|
||
{ "SHOWSPLIT", NULL, linklook, 0, "- Shows split servers" },
|
||
{ "SHOWWORDKICK",NULL, show_word_kick, 0, "- Shows the internal banned word list" },
|
||
{ "SILENCE", "SILENCE", send_comm, SERVERREQ, "%R[%n+nick|-nick%R]%n\n- Server-side ignore" },
|
||
{ "SLEEP", NULL, sleepcmd, 0, scripting_command },
|
||
{ "SPAM", NULL, spam, 0, NULL },
|
||
{ "SPING", "Sping", sping, 0, "%Y<%nserver|.|-clear%Y>%n\n- Checks how lagged you are to %Y<%nserver%Y>%n" },
|
||
{ "SQUERY", "SQUERY", send_2comm, SERVERREQ, "%Y<%nservice%Y> <%ntext%Y>%n\n - Sends %Y<%ntext%Y>%n to %Y<%nservice%Y>%n" },
|
||
{ "SQUIT", "SQUIT", send_2comm, SERVERREQ, "%Y<%nserver1%Y>%n %R[%nserver2%R]%n\n%Y*%n Requires irc operator status\n- Disconnects %Y<%nserver1%Y>%n from current server or %R[%nserver2%R]%n" },
|
||
{ "STACK", NULL, stackcmd, 0, scripting_command },
|
||
{ "STATS", "STATS", do_stats, 0, NULL },
|
||
{ "STUB", "Stub", stubcmd, 0, "(alias|assign) <name> <file> [<file ...]" },
|
||
#ifdef GUI
|
||
{ "SUBMENU", NULL, os2submenu, 0, "GUI - Adds a submenu to a menu" },
|
||
#endif
|
||
{ "SUMMON", "SUMMON", send_comm, SERVERREQ, "%Y<%nuser%Y> %R[%nserver%R [%nchannel%R]]%n\n- calls %Y<%nuser%Y>%n on %R[%nserver%R]%n to %R[%nchannel%R]%n" },
|
||
{ "SV", "Sv", show_version, 0, "%R[%nnick|#channel%R]%n\nShow Client Version information" },
|
||
{ "SWALLOP", "SWALLOPS", e_wall, 0, NULL },
|
||
#ifdef WANT_OPERVIEW
|
||
{ "SWATCH", NULL, s_watch, 0, "- Display or Modify what messages you want to see from the server"},
|
||
#endif
|
||
{ "SWITCH", "SWITCH", switchcmd, 0, scripting_command },
|
||
{ "T", "TOPIC", e_topic, 0, "%Y<%ntext%Y>%n\n- Sets %Y<%ntext%Y>%n as topic on current channel"},
|
||
{ "TBAN", NULL, tban, 0, "- Interactive channel ban delete" },
|
||
{ "TBK", "TBK", kickban, 0, "%Y<%Cnick%Y>%n %R[%ntime%R]%n\n- Deops, bans and kicks %Y<%Cnick%Y>%n for %R[%ntime%R]%n" },
|
||
{ "TCL", NULL, tcl_command, 0, "<-version> <command>" },
|
||
{ "TIGNORE", NULL, tignore, 0, NULL },
|
||
{ "TIME", "TIME", send_comm, SERVERREQ, "- Shows time and date of current server" },
|
||
{ "TIMER", "TIMER", timercmd, 0, NULL },
|
||
{ "TKB", "TKB", kickban, 0, "%Y<%Cnick%Y>%n %R[%ntime%R]%n\n- Deops, kicks, and bans %Y<%Cnick%Y>%n for %R[%ntime%R]%n" },
|
||
{ "TKLINE", "TKLINE", send_kline, 0, "%Y<%nuser%y@%nhost%Y> <%nreason%Y>%n\n%Y*%n Requires irc operator status\n- Adds a temporary K-line" },
|
||
{ "TLOCK", "TLock", topic_lock, 0, "%Y<%Bchannel%Y>%n %R[%non%G|%noff%R]%n\n- [Un]Locks %Y<%Bchannel%Y>%n with the current topic" },
|
||
{ "TOGGLE", NULL, do_toggle, 0, "- Various Client toggles which can be change" },
|
||
{ "TOPIC", "TOPIC", e_topic, 0, "- Change or show the current or specified channel topic" },
|
||
{ "TRACE", "TRACE", do_trace, 0, "<argument> <server>\n- Without a specified server it shows the current connections on local server\n- Arguments: -s -u -o trace for servers, users, ircops" },
|
||
{ "TRACEKILL", "TraceKill", tracekill, 0, NULL },
|
||
{ "TRACESERV", "TraceServ", traceserv, 0, NULL },
|
||
{ "TYPE", NULL, type, 0, scripting_command },
|
||
{ "U", NULL, users, 0, "- Shows users on current channel" },
|
||
{ "UB", NULL, unban, 0, "%R[%Cnick%R]%n\n- Removes ban on %R[%Cnick%R]%n" },
|
||
{ "UMODE", "MODE", umodecmd, 0, "%Y<%nmode%Y>%n\n- Sets %Y<%nmode%Y>%n on yourself" },
|
||
{ "UNAJOIN", "UnAjoin", auto_join, 0, "%Y<%Bchannel%Y>%n\n- Removes autojoin %Y<%Bchannel%Y>%n from list" },
|
||
{ "UNBAN", NULL, unban, 0, NULL },
|
||
{ "UNBANWORD", "UnWordKick", add_ban_word, 0, "- Removes a banned word" },
|
||
{ "UNFORWARD", "NoForward", do_forward, 0, "%Y<%Cnick%G|%Bchannel%Y>\n- Remove %Y<%Cnick%G|%Bchannel%Y> from forward list" },
|
||
{ "UNIDLE", "UnIdle", addidle, 0, "%Y<%Bchannel%Y>%n\n- Removes %Y<%Bchannel%Y>%n from idle list" },
|
||
{ "UNIG", "UnIg", do_ig, 0, "%Y<%Cnick%Y>%n\n- UnIgnores %Y<%Cnick%Y>%n"},
|
||
{ "UNIGH", "UnIgH", do_ig, 0, "%Y<%Cnick%Y>%n\n- Removes %Y<%Cnick%Y>%n's host from the ignore list" },
|
||
{ "UNKEY", NULL, do_unkey, 0, "- Removes channel key from current channel" },
|
||
{ "UNKLINE", "UNKLINE", send_kline, 0, "<host|host,host2> remove klines for host(s)" },
|
||
{ "UNLAMENICK","UnLameNick", add_bad_nick, 0, "%Y<%nnick(s)%Y>%n\n- Remove nicks from you lame nick list"},
|
||
{ "UNLESS", "UNLESS", ifcmd, 0, scripting_command },
|
||
{ "UNLOAD", NULL, unload, 0, "- Unloads all loaded scripts" },
|
||
#ifdef WANT_DLL
|
||
{ "UNLOADDLL", NULL, unload_dll, 0, "- Unloads loaded a plugin" },
|
||
#endif
|
||
{ "UNSCREW", NULL, do_unscrew, 0, "%Y<%Cnick%Y>%n\n- Unscrew %Y<%Cnick%Y>%n" },
|
||
{ "UNSHIFT", NULL, unshift_cmd, 0, scripting_command },
|
||
#ifdef WANT_USERLIST
|
||
{ "UNSHIT", "UnShit", add_shit, 0, "%Y<%nnick%Y> <%nchannel%Y>%n" },
|
||
#endif
|
||
{ "UNTIL", "UNTIL", whilecmd, 0, scripting_command },
|
||
{ "UNTOPIC", "UNTOPIC", untopic, 0, "- Unsets a channel topic" },
|
||
#ifdef WANT_USERLIST
|
||
{ "UNUSER", "UnUser", add_user, 0, "%Y<%nnick%W|%nnick!user@hostname%Y> <%n#channel%W|%n*%Y>%n" },
|
||
#endif
|
||
{ "UNVOICE", "v", dodeop, 0, NULL },
|
||
{ "UNWORDKICK", "UnWordKick", add_ban_word, 0, "%Y<%n#channel%Y> <%nword%Y>%n" },
|
||
{ "UPING", "uPing", pingcmd, 0, NULL },
|
||
{ "UPTIME", NULL, do_uptime, 0, NULL },
|
||
{ "URL", NULL, url_grabber, 0, NULL },
|
||
{ "USER", NULL, users, 0, NULL },
|
||
{ "USERHOST", NULL, userhostcmd, 0, NULL },
|
||
#ifdef WANT_USERLIST
|
||
{ "USERINFO", NULL, set_user_info, 0, NULL },
|
||
#endif
|
||
{ "USERIP", "USERIP", useripcmd, 0, NULL },
|
||
#ifdef WANT_USERLIST
|
||
{ "USERLIST", NULL, showuserlist, 0, NULL },
|
||
#endif
|
||
{ "USERS", "USERS", send_comm, SERVERREQ, "%R[%nserver%R]%n\n- Show users on %R[%nserver%R]%n (as finger @host)" },
|
||
#ifdef WANT_USERLIST
|
||
{ "USERSHOW", "UserShow", set_user_info, 0, NULL },
|
||
#endif
|
||
{ "USLEEP", NULL, usleepcmd, 0, NULL },
|
||
{ "USRIP", "USRIP", usripcmd, 0, NULL },
|
||
{ "VER", "VERSION", ctcp_simple, 0, "%Y<%Cnick%Y>%n\n- Sends a CTCP VERSION query to %Y<%Cnick%Y>%n" },
|
||
{ "VERSION", "VERSION", version1, 0, NULL },
|
||
{ "VOICE", "v", doop, 0, NULL },
|
||
{ "W", "W", whocmd, 0, NULL },
|
||
{ "WAIT", NULL, waitcmd, 0, scripting_command },
|
||
{ "WALL", "WALL", ChanWallOp, 0, NULL },
|
||
{ "WALLCHOPS", "WALLCHOPS", send_2comm, SERVERREQ, NULL },
|
||
{ "WALLMSG", NULL, ChanWallOp, 0, NULL },
|
||
{ "WALLOPS", "WALLOPS", e_wall, 0, NULL },
|
||
{ "WATCH", "WATCH", watchcmd, 0, NULL },
|
||
{ "WHICH", "WHICH", BX_load, 0, "- Shows which script would be loaded without loading it" },
|
||
{ "WHILE", "WHILE", whilecmd, 0, scripting_command },
|
||
{ "WHO", "Who", whocmd, SERVERREQ, NULL },
|
||
{ "WHOIS", "WHOIS", whois, SERVERREQ, NULL },
|
||
{ "WHOKILL", "WhoKill", whokill, SERVERREQ, "%Y<%Cnick%G!%nuser%Y@%nhostname%Y>%n %R[%nreason%R]%n\n%Y*%n Requires irc operator status\n- Kills multiple clients matching the filter %Y<%Cnick%G!%nuser%Y@%nhostname%Y>%n with %R[%n%W:%nreason%R]%n" },
|
||
{ "WHOLEFT", "WhoLeft", whowas, SERVERREQ, NULL },
|
||
{ "WHOWAS", "WhoWas", whois, SERVERREQ, NULL },
|
||
{ "WI", "Whois", whois, SERVERREQ, NULL },
|
||
{ "WII", NULL, my_whois, SERVERREQ, NULL },
|
||
{ "WILC", "WILC", my_whois, 0, NULL },
|
||
{ "WILCR", "WILCR", my_whois, 0, NULL },
|
||
{ "WILM", "WILM", my_whois, 0, NULL },
|
||
{ "WILN", "WILN", my_whois, 0, NULL },
|
||
{ "WINDOW", NULL, windowcmd, 0, "Various window commands. use /window help" },
|
||
{ "WORDLIST", NULL, show_word_kick, 0, NULL },
|
||
{ "WSET", NULL, wset_variable, 0, NULL },
|
||
{ "WW", "WhoWas", whois, 0, NULL },
|
||
{ "XDEBUG", NULL, xdebugcmd, 0, NULL },
|
||
{ "XECHO", "XECHO", echocmd, 0, NULL },
|
||
{ "XEVAL", "XEVAL", xevalcmd, 0, NULL },
|
||
{ "XQUOTE", "XQUOTE", quotecmd, 0, NULL },
|
||
{ "XTRA", "XTRA", e_privmsg, 0, NULL },
|
||
{ "XTYPE", NULL, xtypecmd, 0, NULL },
|
||
{ NULL, NULL, comment, 0, NULL }
|
||
};
|
||
|
||
/* number of entries in irc_command array */
|
||
#define NUMBER_OF_COMMANDS (sizeof(irc_command) / sizeof(IrcCommand)) - 2
|
||
|
||
BUILT_IN_COMMAND(about)
|
||
{
|
||
#ifdef GUI
|
||
static char *about_text =
|
||
"Grtz To: Trench, HappyCrappy, Yak, Zircon, Otiluke, Masonry,\n\
|
||
BuddahX, Hob, Lifendel, JondalaR, JVaughn, suicide, NovaLogic,\n\
|
||
Jordy, BigHead,Ananda, Hybrid, Reefa, BlackJac, GenX, MHacker,\n\
|
||
PSiLiCON, hop, Sheik, psykotyk, oweff, icetrey, Power, sideshow,\n\
|
||
Raistlin, Mustang, [Nuke], Rosmo, Sellfone, Drago and bark0de!\n\n\
|
||
Mailing list is at <bitchx-devel@lists.sourceforge.net>\n";
|
||
gui_about_box(about_text);
|
||
return;
|
||
#else
|
||
int i = strip_ansi_in_echo;
|
||
strip_ansi_in_echo = 0;
|
||
|
||
#if defined(WINNT) || defined(__EMX__)
|
||
put_it("[0;25;35;40m [0m");
|
||
#else
|
||
charset_ibmpc();
|
||
put_it("[0;25;35;40m [0m");
|
||
#endif
|
||
#ifdef ASCII_LOGO
|
||
put_it(" ,");
|
||
put_it(" . ,$");
|
||
put_it(" . ,$'");
|
||
put_it(" . . ,$'");
|
||
put_it(" : ,g$p, . $, ,$'");
|
||
put_it(" y&$ `\"` .,. $&y `$, ,$'");
|
||
put_it(" $$$ o oooy$$$yoo o $$$ `$, ,$' -acidjazz");
|
||
put_it(" . $$$%%yyyp, gyp`$$$'gyyyyyyp, $$$yyyyp, `$, ,$' .");
|
||
put_it(" . yxxxx $$$\"`\"$$$ $$$ $$$ $y$\"`\"$$$ $$$\"`\"$$$ xxx`$,$'xxxxxxy .");
|
||
put_it(" $ $$7 l$$ $$$ $$$ $$7 \"\"\" $$7 ly$ .$' $");
|
||
put_it(" $ $$b dy$ $$$ $y$ $$b $$$ $$b d$$ ,$`$, $");
|
||
put_it(" . $xxxx $$$uuu$$$ $$$ $$$ $$$uuu$$$ $$$ $$$ x ,$'x`$, xxxx$ .");
|
||
put_it(" . \"\"\" \"\"\" \"\"\" \"\"\" \"\"\" ,$' `$, .");
|
||
put_it(" b i t c h - x ,$' `$,");
|
||
put_it(" $' `$,");
|
||
put_it(" ' `$,");
|
||
put_it(" `$,");
|
||
put_it(" `$");
|
||
put_it(" `");
|
||
put_it(empty_string);
|
||
put_it("[0;30;47m [0m");
|
||
put_it("[0;30;47m Grtz To: Trench, HappyCrappy, Yak, Zircon, Otiluke, Masonry, BuddahX, Hob, [0m");
|
||
put_it("[0;30;47m Lifendel, JondalaR, JVaughn, Suicide, NovaLogic, Jordy, BigHead, [0m");
|
||
put_it("[0;30;47m Ananda, Hybrid, Reefa, BlackJac, GenX, MHacker, PSiLiCON, [0m");
|
||
put_it("[0;30;47m hop, Sheik, psykotyk, oweff, icetrey, Power, sideshow, Raistlin, [0m");
|
||
put_it("[0;30;47m [Nuke], Rosmo and Bark0de! [0m");
|
||
put_it("[0;30;47m [0m");
|
||
put_it("[0;30;47m Mailing list is at <bitchx-devel@lists.sourceforge.net> [0m");
|
||
put_it(empty_string);
|
||
#else
|
||
put_it("[35m <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[1;45m<35><6D><EFBFBD>[0;35;40m [1;45m<35><6D>[0;35;40m<30>[1;32m<32>[42m<32><6D>[40m<30>[0;35;40m [1;45m<35>[40m<30>[0m");
|
||
put_it("[35m [1;31m<31><6D>[0m [1;35;45m<35>[0;35;40m<30><6D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[1;31;41m<31>[40m<30>[0m [1;35;45m<35>[0;35;40m<30><6D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[1;31;41m<31>[40m<30>[0m [1;35;45m<35>[0;35;40m<30><6D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[1;32m<32><6D>[0;35;40m<30><6D><EFBFBD>[1;45m<35><6D>[0;35;40m [1m<31>[0;32;40m<30>[1;42m<32><6D><EFBFBD><EFBFBD>[40m<30>[0;35;40m [1;45m<35>[0;35;40m<30>[0m");
|
||
put_it("[35m<35>[1;31;41m<31>[0m [35m<35>[1;31m<31>[0;32;40m [35m<35><6D>[1;31;41m<31>[40m<30>[0;32;40m [1;35m<35>[45m<35>[31;41m<31>[0m [35m<35><6D><EFBFBD><EFBFBD>[1;45m<35>[0;35;40m<30><6D>[1;31;45m<35>[40m<30>[0;32;40m [35m<35>[1;31m<31>[0;32;40m [1;35m <20>[45m<35>[31;41m<31>[0m [35m<35>[1;31m<31>[0;32;40m <20><><EFBFBD><EFBFBD>[1;42m<32><6D><EFBFBD>[0m [35m<35><6D><EFBFBD><EFBFBD>[1;45m<35>[0;35;40m [32m<32>[1;42m<32><6D>[0;32;40m<30><6D>[1m<31>[35m<35>[45m<35>[0;35;40m [1;45m<35>[0;35;40m<30>[0m");
|
||
put_it("[35m<35>[1;31;41m<31>[0m [1;35;45m<35>[31;41m<31>[0m [1;35;45m [31m<31><6D>[0;35;40m<30><6D><EFBFBD><EFBFBD>[1;31;41m<31>[0m [1;35;45m<35>[31;41m<31>[40m<30>[0;32;40m [1;35;45m<35>[31;41m<31>[0m [1;35;45m<35>[31;41m<31>[0m [1;35;45m<35>[31;41m<31>[0m [1;35;45m<35>[31;41m<31>[0m [35m<35>[32m<32><6D><EFBFBD><EFBFBD>[1;42m<32><6D>[40m<30>[0;35;40m<30>[1;45m<35>[0;35;40m<30>[32m<32><6D><EFBFBD>[1;35m<35><6D>[45m<35>[40m<30>[0;35;40m [1;45m<35><6D>[0;35;40m <20><>[0m");
|
||
put_it("[35m<35>[1;31;41m [0m [1;35;45m<35>[31;41m<31>[0m [1;35;45m<35>[31;41m<31>[0m [1;35;45m<35>[31;41m [0m [1;35;45m<35>[31;41m<31>[0m [1;35;45m<35>[31;41m<31>[0m [1;35;45m<35>[31m<31>[0;35;40m<30><6D><EFBFBD><EFBFBD>[1;45m<35>[31;41m [0m [1;35;45m<35>[31;41m<31>[0m [1;35;45m<35>[0;35;40m<30><6D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[32m<32>[1m<31>[0;32;40m<30>[35m<35> [1;45m<35><6D><EFBFBD>[0;35;40m<30> [1;45m<35><6D>[0;35;40m <20>[1;30m<30>[0m");
|
||
put_it("[35m<35>[31;45m<35>[0m [1;35;45m<35>[31;41m<31>[0m [1;35;45m<35>[31;41m<31>[0m [1;35;45m<35>[0;31;45m<35>[0m [1;35;45m<35>[31;41m<31>[0m [1;35;45m<35>[31;41m<31>[0m [1;35;45m<35>[31;41m<31>[0m [1;35;45m<35>[0;31;45m<35>[0m [1;35;45m<35>[31;41m<31>[0m [1;35;45m<35>[0;35;40m<30><6D><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[32m<32><6D>[35m<35><6D>[1;32m<32><6D><EFBFBD>[0;32;40m<30>[35m<35><6D><EFBFBD> [1;45m<35>[0;35;40m<30> <20><>[0m");
|
||
put_it("[35m<35>[31;45m<35>[0m [1;35;45m<35>[31;41m<31>[0m [1;35;45m<35>[31;41m<31>[0m [1;35;45m<35>[0;31;45m<35>[0m [1;35;45m<35>[31;41m<31>[0m [1;35;45m<35>[31;41m<31>[0m [1;35;45m<35>[31;41m<31>[0m [1;35;45m<35>[0;31;45m<35>[0m [1;35;45m<35>[31;41m<31>[0m [1;35;45m<35>[0;35;40m<30><6D><EFBFBD><EFBFBD>[32m<32>[1;42m<32>[0;32;40m<30>[35m<35><6D>[1;30;45m<35>[0;35;40m<30>[1;32m<32><6D>[42m<32><6D><EFBFBD>[0;32;40m<30><6D><EFBFBD>[35m<35> <20><>[0m");
|
||
put_it("[35m<35>[31;45m<35>[0m [1;35m<35>[0;31;40m<30>[1;34m [35m<35>[45m<35>[31;41m [0m [1;35m<35>[45m<35>[0;31;45m<35>[40m<30>[1;34m [35m<35>[0;31;40m<30>[1;34m [35m<35>[45m<35>[0;31;45m<35>[40m<30>[1;34m [35m<35>[0;31;40m<30>[1;34m [35m<35>[45m<35>[0;31;45m<35>[0m [1;35m<35>[45m<35>[31;41m [0m [1;35m<35>[45m<35>[0;35;40m<30><6D>[1;32m<32>[42m<32><6D>[0;32;40m<30>[0m [35m<35><6D><EFBFBD><EFBFBD>[34m [1;32;42m<32><6D><EFBFBD>[0;32;40m<30>[1;42m<32>[0;32;40m<30><6D><EFBFBD><EFBFBD><EFBFBD>[1;30m<30>[0m");
|
||
put_it("[35m<35><6D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[1;32m<32>[42m<32><6D><EFBFBD>[0;32;40m<30><6D>[35m<35><6D>[1;30;45m<35>[0;35;40m<30>[1;30;45m<35>[0;35;40m [34m [1;32;42m<32><6D><EFBFBD>[0;32;40m<30><6D><EFBFBD><EFBFBD><EFBFBD>[1;30m<30>[0;35;40m<30>");
|
||
put_it(" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[1;32m<32>[42m<32><6D><EFBFBD>[0;32;40m<30><6D>[0m [35m<35><6D><EFBFBD>[1;30;45m<35><6D>[0;35;40m [34m [1;32;42m<32>[0;32;40m<30><6D>[35m [1;30m<30>[45m<35>[0;35;40m [1;30;45m<35>[40m<30>[0;35;40m");
|
||
put_it(" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[1;32m<32>[0;32;40m<30><6D><EFBFBD>[35m<35>[30;45mrE[35;40m<30>[1;30;45m<35><6D><EFBFBD>[0;35;40m [1;30;45m<35>[40m<30>[45m<35>[40m<30>[0;35;40m [1;30;45m<35><6D>[0;35;40m [1;30;45m<35>[40m<30>[0m");
|
||
put_it(empty_string);
|
||
put_it("[1m<31><6D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܲ[0m<30>");
|
||
put_it("[1;47m<37>[0;30;47m [0m");
|
||
put_it("[1;47m<37>[0;30;47m Grtz To: Trench, HappyCrappy, Yak, Zircon, Otiluke, Masonry, BuddahX, Hob, [1m<31>[0m");
|
||
put_it("[1;47m<37>[0;30;47m Lifendel, JondalaR, JVaughn, suicide, NovaLogic, Jordy, BigHead, [1m<31>[0m");
|
||
put_it("[1;47m<37>[0;30;47m Ananda, Hybrid, Reefa, BlackJac, GenX, MHacker, PSiLiCON, [1m<31>[0m");
|
||
put_it("[1;47m<37>[0;30;47m hop, Sheik, psykotyk, oweff, icetrey, Power, sideshow, Raistlin, [1m<31>[0m");
|
||
put_it("[1;47m<37>[0;30;47m Mustang, [Nuke], Rosmo, Sellfone, Drago and bark0de! [1m<31>[0m");
|
||
put_it("[1;47m<37>[0;30;47m Mailing list is at <bitchx-devel@lists.sourceforge.net> [1m<31>[0m");
|
||
put_it("<EFBFBD>[1;30m<30><6D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[0m");
|
||
put_it(empty_string);
|
||
#endif
|
||
#if !defined(WINNT) && !defined(__EMX__)
|
||
#if defined(LATIN1)
|
||
charset_lat1();
|
||
#elif defined(CHARSET_CUSTOM)
|
||
charset_cst();
|
||
#endif
|
||
#endif
|
||
strip_ansi_in_echo = i;
|
||
#endif
|
||
}
|
||
|
||
BUILT_IN_COMMAND(obits)
|
||
{
|
||
charset_ibmpc();
|
||
put_it("%s", convert_output_format("%P<><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD>---%p<>%P--%p<><70>%P-%p<><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD>---%K<>%p--<2D>%K<>-%p<><70><EFBFBD>%K<><4B><EFBFBD><EFBFBD>-%p<>-%K<><4B>---%K -- -%n", NULL, NULL));
|
||
put_it("%s", convert_output_format("%P|%n ", NULL, NULL));
|
||
put_it("%s", convert_output_format("%P<>%n From its humble beginnings to the latest release, BitchX has always been", NULL, NULL));
|
||
put_it("%s", convert_output_format("%P<>%n about community. Over the years, a handful of people have voluntarily ", NULL, NULL));
|
||
put_it("%s", convert_output_format("%P|%n contributed a great deal of time and energy to the project by writing ", NULL, NULL));
|
||
put_it("%s", convert_output_format("%p:%n scripts, providing support, troubleshooting, patches, enhancements - or ", NULL, NULL));
|
||
put_it("%s", convert_output_format("%P|%n simply making BitchX a fun thing to be involved with. With such a long ", NULL, NULL));
|
||
put_it("%s", convert_output_format("%p'%n history, we have had our losses. Several of the friends that we came to ", NULL, NULL));
|
||
put_it("%s", convert_output_format("%p|%n regard as a kind of extended family left us before their time, and we would", NULL, NULL));
|
||
put_it("%s", convert_output_format("%P<>%n like to remember them here.", NULL, NULL));
|
||
put_it("%s", convert_output_format("%p<>%n ", NULL, NULL));
|
||
put_it("%s", convert_output_format("%p:%n %P<>%n ", NULL, NULL));
|
||
put_it("%s", convert_output_format("%K|%n %P<>%n Jason Higham, known to his friends on IRC as ", NULL, NULL));
|
||
put_it("%s", convert_output_format("%p|%n %P<>%n %Wssshooter%n, left us on July 11th, 2004. He is ", NULL, NULL));
|
||
put_it("%s", convert_output_format(" %P<>%n remembered fondly by his family and friends. ", NULL, NULL));
|
||
put_it("%s", convert_output_format("%K|%n %P<>%n", NULL, NULL));
|
||
put_it("%s", convert_output_format(" %P<>%n On the 18th of July, 2004, our dearly missed", NULL, NULL));
|
||
put_it("%s", convert_output_format(" %P<>%n friend Miles Wilson (also known as %Wsellfone%n)", NULL, NULL));
|
||
put_it("%s", convert_output_format(" %P<>%n passed away in his sleep.", NULL, NULL));
|
||
put_it("%s", convert_output_format(" %P<>%n", NULL, NULL));
|
||
put_it("%s", convert_output_format(" %P<>%n Amy Elizabeth Haskew died on June 16, 2009 at", NULL, NULL));
|
||
put_it("%s", convert_output_format(" %P<>%n 34. Goodbye %Wturtlex%n, you'll always be", NULL, NULL));
|
||
put_it("%s", convert_output_format(" %P<>%n remembered as someone very kind, and wise beyond", NULL, NULL));
|
||
put_it("%s", convert_output_format(" %P<>%n your years.", NULL, NULL));
|
||
put_it("%s", convert_output_format(" %P<>%n", NULL, NULL));
|
||
put_it("%s", convert_output_format(" %P<>%n RIP Marc Casillo aka %Wfrash%n [25/Nov/1970 - 28/Sep/2009] ", NULL, NULL));
|
||
put_it("%s", convert_output_format(" %P<>%n", NULL, NULL));
|
||
put_it("%s", convert_output_format(" %P<>%n Matthew Luberto, known to his many friends online", NULL, NULL));
|
||
put_it("%s", convert_output_format(" %P<>%n as %Wvoid%n, passed away in his sleep on February 16, ", NULL, NULL));
|
||
put_it("%s", convert_output_format(" %P<>%n 2013 in his 38th year. We'll miss you, void.", NULL, NULL));
|
||
put_it(" ");
|
||
#if defined(LATIN1)
|
||
charset_lat1();
|
||
#elif defined(CHARSET_CUSTOM)
|
||
charset_cst();
|
||
#endif
|
||
}
|
||
|
||
BUILT_IN_COMMAND(dcc_stat_comm)
|
||
{
|
||
dcc_stats(NULL, NULL);
|
||
}
|
||
|
||
void handle_dcc_chat(UserhostItem *stuff, char *nick, char *args)
|
||
{
|
||
if (!stuff || !stuff->nick || !strcmp(stuff->user, "<UNKNOWN>") || !strcmp(stuff->host, "<UNKNOWN>"))
|
||
{
|
||
bitchsay("No such nick %s", nick);
|
||
return;
|
||
}
|
||
dcc_chat(NULL, args);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(init_dcc_chat)
|
||
{
|
||
char *nick = NULL;
|
||
if (args && *args)
|
||
{
|
||
char *n;
|
||
while ((nick = next_arg(args, &args)))
|
||
{
|
||
while ((n = next_in_comma_list(nick, &nick)))
|
||
{
|
||
if (!n || !*n) break;
|
||
if (!my_stricmp(n, get_server_nickname(from_server))) continue;
|
||
userhostbase(n, handle_dcc_chat, 1, n, NULL);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
#ifdef WANT_FTP
|
||
BUILT_IN_COMMAND(init_ftp)
|
||
{
|
||
if (args && *args)
|
||
dcc_ftpopen(NULL, args);
|
||
}
|
||
#endif
|
||
|
||
/*
|
||
* find_command: looks for the given name in the command list, returning a
|
||
* pointer to the first match and the number of matches in cnt. If no
|
||
* matches are found, null is returned (as well as cnt being 0). The command
|
||
* list is sorted, so we do a binary search. The returned commands always
|
||
* points to the first match in the list. If the match is exact, it is
|
||
* returned and cnt is set to the number of matches * -1. Thus is 4 commands
|
||
* matched, but the first was as exact match, cnt is -4.
|
||
*/
|
||
const IrcCommand *BX_find_command(const char *com, int *cnt)
|
||
{
|
||
IrcCommand *retval;
|
||
int loc;
|
||
|
||
/*
|
||
* As a special case, the empty or NULL command is send_text.
|
||
*/
|
||
if (!com || !*com)
|
||
{
|
||
*cnt = -1;
|
||
return irc_command;
|
||
}
|
||
|
||
retval = (IrcCommand *)find_fixed_array_item ((void *)irc_command, sizeof(IrcCommand), NUMBER_OF_COMMANDS + 1, com, cnt, &loc);
|
||
return retval;
|
||
}
|
||
|
||
/* IRCUSER command. Changes your userhost on the fly. Takes effect
|
||
* the next time you connect to a server
|
||
*/
|
||
BUILT_IN_COMMAND(set_username)
|
||
{
|
||
char *blah;
|
||
|
||
if ((blah = next_arg(args, &args)))
|
||
{
|
||
if (!strcmp(blah, "-"))
|
||
strlcpy(username, empty_string, sizeof username);
|
||
else
|
||
strlcpy(username, blah, sizeof username);
|
||
say("Username has been changed to '%s'",username);
|
||
}
|
||
}
|
||
|
||
/* This code is courtesy of Richie B. (richie@morra.et.tudelft.nl)
|
||
* Modified by Christian Deimel (defender@gmx.net), now, if no argument is
|
||
* given, a random name is chosen
|
||
*/
|
||
/*
|
||
* REALNAME command. Changes the current realname. This will only be parsed
|
||
* to the server when the client is connected again.
|
||
*/
|
||
BUILT_IN_COMMAND(realname_cmd)
|
||
{
|
||
|
||
if (*args)
|
||
{
|
||
strlcpy(realname, args, sizeof realname);
|
||
say("Realname at next server connnection: %s", realname);
|
||
}
|
||
else
|
||
{
|
||
char *s = NULL;
|
||
s = get_realname(get_server_nickname(from_server));
|
||
strlcpy(realname, s, sizeof realname);
|
||
say("Randomly chose a new ircname: %s", realname);
|
||
}
|
||
}
|
||
|
||
BUILT_IN_COMMAND(pop_cmd)
|
||
{
|
||
extern char *function_pop(char *, char *);
|
||
char *blah = function_pop(NULL, args);
|
||
new_free(&blah);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(push_cmd)
|
||
{
|
||
extern char *function_push(char *, char *);
|
||
char *blah = function_push(NULL, args);
|
||
new_free(&blah);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(shift_cmd)
|
||
{
|
||
extern char *function_shift(char *, char *);
|
||
char *blah = function_shift(NULL, args);
|
||
|
||
new_free(&blah);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(unshift_cmd)
|
||
{
|
||
extern char *function_unshift(char *, char *);
|
||
char *blah = function_unshift(NULL, args);
|
||
|
||
new_free(&blah);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(do_forward)
|
||
{
|
||
|
||
if (command && (!my_stricmp(command, "NOFORWARD") || !my_stricmp(command, "UNFORWARD")))
|
||
{
|
||
if (forwardnick)
|
||
{
|
||
bitchsay("No longer forwarding messages to %s", forwardnick);
|
||
send_to_server("NOTICE %s :%s is no longer forwarding to you",
|
||
forwardnick, get_server_nickname(from_server));
|
||
}
|
||
new_free(&forwardnick);
|
||
return;
|
||
}
|
||
if (args && *args)
|
||
{
|
||
char *q;
|
||
malloc_strcpy(&forwardnick, args);
|
||
if ((q = strchr(forwardnick, ' ')))
|
||
*q = 0;
|
||
send_to_server("NOTICE %s :%s is now forwarding messages to you",
|
||
forwardnick, get_server_nickname(from_server));
|
||
bitchsay("Now forwarding messages to %s", forwardnick);
|
||
}
|
||
return;
|
||
}
|
||
|
||
BUILT_IN_COMMAND(blesscmd)
|
||
{
|
||
bless_local_stack();
|
||
}
|
||
|
||
BUILT_IN_COMMAND(do_oops)
|
||
{
|
||
const char *to = next_arg(args, &args);
|
||
const char *sent_nick = get_server_sent_nick(from_server);
|
||
const char *sent_body = get_server_sent_body(from_server);
|
||
|
||
if (sent_nick && sent_body && to && *to)
|
||
{
|
||
send_to_server("PRIVMSG %s :Oops, that /msg wasn't for you", sent_nick);
|
||
send_to_server("PRIVMSG %s :%s", to, sent_body);
|
||
if (window_display && do_hook(SEND_MSG_LIST, "%s %s", to, sent_body))
|
||
put_it("%s", convert_output_format(fget_string_var(FORMAT_SEND_MSG_FSET), "%s %s %s %s", update_clock(GET_TIME),
|
||
to, get_server_nickname(from_server), sent_body));
|
||
}
|
||
}
|
||
|
||
/*
|
||
* RECONNECT command. Closes the server, and then reconnects again.
|
||
* Works also while connected to multiple servers. It only reconnects to the
|
||
* current server number (which is stored in from_server).
|
||
* This command puts the REALNAME command in effect.
|
||
*/
|
||
BUILT_IN_COMMAND(reconnect_cmd)
|
||
{
|
||
char scommnd[6];
|
||
|
||
if (from_server == -1)
|
||
{
|
||
bitchsay("Try connecting to a server first.");
|
||
return;
|
||
}
|
||
if (do_hook(DISCONNECT_LIST, "Reconnecting to server"))
|
||
put_it("%s", convert_output_format("$G Reconnecting to server %K[%W$1%K]", "%s %d", update_clock(GET_TIME), from_server));
|
||
|
||
snprintf(scommnd, 5, "+%i", from_server);
|
||
|
||
/* close server will take care of the .reconnect variable */
|
||
set_server_reconnecting(from_server, 1);
|
||
close_server(from_server,(args && *args) ? args : "Reconnecting");
|
||
window_check_servers(from_server);
|
||
servercmd(NULL, scommnd, empty_string, NULL);
|
||
|
||
}
|
||
|
||
/* End of contributed code */
|
||
|
||
/* clear: the CLEAR command. Figure it oUt */
|
||
BUILT_IN_COMMAND(my_clear)
|
||
{
|
||
char *arg;
|
||
int all = 0,
|
||
scrollback = 0,
|
||
unhold = 0;
|
||
|
||
|
||
while ((arg = next_arg(args, &args)) != NULL)
|
||
{
|
||
/* -ALL and ALL here because the help files used to be wrong */
|
||
if (!my_strnicmp(arg, "A", 1) || !my_strnicmp(arg+1, "A", 1))
|
||
all = 1;
|
||
/* UNHOLD */
|
||
else if (!my_strnicmp(arg+1, "U", 1))
|
||
unhold = 1;
|
||
else if (!my_strnicmp(arg+1, "S", 1))
|
||
scrollback = 1;
|
||
}
|
||
if (all)
|
||
clear_all_windows(unhold, scrollback);
|
||
else
|
||
{
|
||
if (scrollback)
|
||
clear_scrollback(get_window_by_refnum(0));
|
||
if (unhold)
|
||
set_hold_mode(NULL, OFF, 1);
|
||
clear_window_by_refnum(0);
|
||
}
|
||
#if defined(WINNT) || defined(__EMX__)
|
||
refresh_screen(0, NULL);
|
||
#endif
|
||
update_input(UPDATE_JUST_CURSOR);
|
||
}
|
||
|
||
|
||
BUILT_IN_COMMAND(do_invite)
|
||
{
|
||
char *inick;
|
||
ChannelList *chan = NULL;
|
||
int server = from_server;
|
||
|
||
|
||
if (args && *args)
|
||
{
|
||
while(1)
|
||
{
|
||
inick = next_arg(args, &args);
|
||
if (!inick)
|
||
return;
|
||
if (args && *args)
|
||
{
|
||
if (!is_channel(args) || !(chan = prepare_command(&server, args, NO_OP)))
|
||
return;
|
||
}
|
||
else
|
||
if (!(chan = prepare_command(&server, NULL, NO_OP)))
|
||
return;
|
||
|
||
if (!chan)
|
||
return;
|
||
my_send_to_server(server, "INVITE %s %s%s%s", inick, chan->channel, chan->key?space:empty_string, chan->key?chan->key:empty_string);
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
|
||
BUILT_IN_COMMAND(umodecmd)
|
||
{
|
||
|
||
send_to_server("%s %s %s", command, get_server_nickname(from_server),
|
||
(args && *args) ? args : empty_string);
|
||
}
|
||
|
||
|
||
BUILT_IN_COMMAND(do_getout)
|
||
{
|
||
char *channel = NULL;
|
||
ChannelList *chan = NULL;
|
||
AJoinList *tmp = NULL;
|
||
int server = from_server;
|
||
int all = 0;
|
||
|
||
|
||
if (command && !my_stricmp(command, "PARTALL"))
|
||
all = 1;
|
||
if (!all)
|
||
{
|
||
if (args)
|
||
channel = next_arg(args, &args);
|
||
if (!(chan = prepare_command(&server, channel?make_channel(channel):channel, NO_OP)))
|
||
return;
|
||
my_send_to_server(server, "PART %s", chan->channel);
|
||
if ((tmp = (AJoinList *)remove_from_list((List **)&ajoin_list, chan->channel)))
|
||
{
|
||
if (!tmp->ajoin_list)
|
||
{
|
||
new_free(&tmp->name);
|
||
new_free(&tmp->key);
|
||
new_free(&tmp);
|
||
}
|
||
else
|
||
add_to_list((List **)&ajoin_list, (List *)tmp);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (chan = get_server_channels(server); chan; chan = chan->next)
|
||
{
|
||
my_send_to_server(server, "PART %s", chan->channel);
|
||
if ((tmp = (AJoinList *)remove_from_list((List **)&ajoin_list, chan->channel)))
|
||
{
|
||
if (!tmp->ajoin_list)
|
||
{
|
||
new_free(&tmp->name);
|
||
new_free(&tmp->key);
|
||
new_free(&tmp);
|
||
}
|
||
else
|
||
add_to_list((List **)&ajoin_list, (List *)tmp);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 12-19-02 Logan, Tilt and Digital got totally drunk */
|
||
BUILT_IN_COMMAND(do_unscrew)
|
||
{
|
||
char *channel = NULL;
|
||
int server = from_server;
|
||
ChannelList *chan;
|
||
|
||
|
||
if (args && *args)
|
||
channel = next_arg(args, &args);
|
||
|
||
if (!(chan = prepare_command(&server, channel, NEED_OP)))
|
||
return;
|
||
|
||
my_send_to_server(server, "MODE %s -k %s", chan->channel, chan->key);
|
||
my_send_to_server(server, "MODE %s +k \033(B\033[2J", chan->channel);
|
||
my_send_to_server(server, "MODE %s -k \033(B\033[2J", chan->channel);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(do_4op)
|
||
{
|
||
char *channel = NULL;
|
||
char *nick = NULL;
|
||
ChannelList *chan;
|
||
int server = from_server;
|
||
|
||
|
||
|
||
if (args && *args)
|
||
channel = next_arg(args, &args);
|
||
|
||
if (channel)
|
||
{
|
||
if (is_channel(channel))
|
||
nick = args;
|
||
else
|
||
{
|
||
nick = channel;
|
||
channel = NULL;
|
||
}
|
||
}
|
||
if (!(chan = prepare_command(&server, channel, NEED_OP)))
|
||
return;
|
||
|
||
if (!nick)
|
||
return;
|
||
my_send_to_server(server, "MODE %s +oooo %s %s %s %s", chan->channel, nick, nick, nick, nick);
|
||
}
|
||
|
||
enum SCAN_TYPE {
|
||
SCAN_ALL, SCAN_VOICES, SCAN_CHANOPS, SCAN_NONOPS, SCAN_IRCOPS,
|
||
SCAN_FRIENDS, SCAN_SHITLISTED, SCAN_BOTS
|
||
};
|
||
|
||
/* nick_in_scan
|
||
*
|
||
* Test if a nick should be shown in a /SCAN, according to the
|
||
* scan type and nick!user@host mask. A NULL mask matches all nicks.
|
||
*/
|
||
int nick_in_scan(NickList *nick, enum SCAN_TYPE scan_type, char *mask)
|
||
{
|
||
switch(scan_type)
|
||
{
|
||
case SCAN_VOICES:
|
||
if (!nick_isvoice(nick)) return 0;
|
||
break;
|
||
|
||
case SCAN_CHANOPS:
|
||
if (!nick_isop(nick) && !nick_ishalfop(nick)) return 0;
|
||
break;
|
||
|
||
case SCAN_NONOPS:
|
||
if (nick_isop(nick) || nick_ishalfop(nick)) return 0;
|
||
break;
|
||
|
||
case SCAN_IRCOPS:
|
||
if (!nick_isircop(nick)) return 0;
|
||
break;
|
||
|
||
case SCAN_FRIENDS:
|
||
if (!nick->userlist) return 0;
|
||
break;
|
||
|
||
case SCAN_SHITLISTED:
|
||
if (!nick->shitlist) return 0;
|
||
break;
|
||
|
||
case SCAN_BOTS:
|
||
if (!nick->userlist || !(nick->userlist->flags & ADD_BOT)) return 0;
|
||
break;
|
||
|
||
case SCAN_ALL:
|
||
default:
|
||
break;
|
||
}
|
||
|
||
/* mask == NULL matches all nicks */
|
||
if (!mask)
|
||
return 1;
|
||
|
||
return nick_match(nick, mask);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(do_scan)
|
||
{
|
||
enum SCAN_TYPE scan_type = SCAN_ALL;
|
||
char *channel = NULL;
|
||
ChannelList *chan;
|
||
NickList *nick, *snick = NULL;
|
||
char *s;
|
||
char *buffer = NULL;
|
||
int n_inscan = 0, n_total = 0;
|
||
int count = 0;
|
||
int server;
|
||
int sorted = NICKSORT_NORMAL;
|
||
char *match_host = NULL;
|
||
int cols = get_int_var(NAMES_COLUMNS_VAR);
|
||
|
||
if (!cols)
|
||
cols = 1;
|
||
|
||
if (command)
|
||
{
|
||
if (!my_stricmp(command, "scanv"))
|
||
scan_type = SCAN_VOICES;
|
||
else if (!my_stricmp(command, "scano"))
|
||
scan_type = SCAN_CHANOPS;
|
||
else if (!my_stricmp(command, "scann"))
|
||
scan_type = SCAN_NONOPS;
|
||
else if (!my_stricmp(command, "scanf"))
|
||
scan_type = SCAN_FRIENDS;
|
||
else if (!my_stricmp(command, "scans"))
|
||
scan_type = SCAN_SHITLISTED;
|
||
else if (!my_stricmp(command, "scani"))
|
||
scan_type = SCAN_IRCOPS;
|
||
else if (!my_stricmp(command, "scanb"))
|
||
scan_type = SCAN_BOTS;
|
||
}
|
||
|
||
while ((s = next_arg(args, &args)))
|
||
{
|
||
if (is_channel(s)) {
|
||
if (!channel)
|
||
{
|
||
channel = s;
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
if (*s == '-')
|
||
{
|
||
if (!my_strnicmp(s, "-sort", 3))
|
||
sorted = NICKSORT_NONE;
|
||
else if (!my_strnicmp(s, "-nick", 3))
|
||
sorted = NICKSORT_NICK;
|
||
else if (!my_strnicmp(s, "-host", 3))
|
||
sorted = NICKSORT_HOST;
|
||
else if (!my_strnicmp(s, "-stat", 3))
|
||
sorted = NICKSORT_STAT;
|
||
|
||
continue;
|
||
}
|
||
|
||
if ((strlen(s) == 1) && (scan_type == SCAN_ALL))
|
||
{
|
||
switch(*s)
|
||
{
|
||
case 'v':
|
||
case 'V':
|
||
scan_type = SCAN_VOICES;
|
||
break;
|
||
|
||
case 'o':
|
||
case 'O':
|
||
scan_type = SCAN_CHANOPS;
|
||
break;
|
||
|
||
case 'n':
|
||
case 'N':
|
||
scan_type = SCAN_NONOPS;
|
||
break;
|
||
|
||
case 'f':
|
||
case 'F':
|
||
scan_type = SCAN_FRIENDS;
|
||
break;
|
||
|
||
case 's':
|
||
case 'S':
|
||
scan_type = SCAN_SHITLISTED;
|
||
break;
|
||
|
||
case 'i':
|
||
case 'I':
|
||
scan_type = SCAN_IRCOPS;
|
||
break;
|
||
|
||
case 'b':
|
||
case 'B':
|
||
scan_type = SCAN_BOTS;
|
||
break;
|
||
}
|
||
|
||
continue;
|
||
}
|
||
|
||
if (!match_host)
|
||
{
|
||
match_host = s;
|
||
}
|
||
}
|
||
|
||
if (!(chan = prepare_command(&server, channel, NO_OP)))
|
||
return;
|
||
|
||
reset_display_target();
|
||
|
||
snick = sorted_nicklist(chan, sorted);
|
||
|
||
/* Count nicks - total and shown */
|
||
for (nick = snick; nick; nick = nick->next)
|
||
{
|
||
n_total++;
|
||
|
||
if (nick_in_scan(nick, scan_type, match_host))
|
||
n_inscan++;
|
||
}
|
||
|
||
/* Output the header line */
|
||
switch(scan_type)
|
||
{
|
||
case SCAN_VOICES:
|
||
s = fget_string_var(FORMAT_NAMES_VOICE_FSET);
|
||
break;
|
||
|
||
case SCAN_CHANOPS:
|
||
s = fget_string_var(FORMAT_NAMES_OP_FSET);
|
||
break;
|
||
|
||
case SCAN_IRCOPS:
|
||
s = fget_string_var(FORMAT_NAMES_IRCOP_FSET);
|
||
break;
|
||
|
||
case SCAN_FRIENDS:
|
||
s = fget_string_var(FORMAT_NAMES_FRIEND_FSET);
|
||
break;
|
||
|
||
case SCAN_NONOPS:
|
||
s = fget_string_var(FORMAT_NAMES_NONOP_FSET);
|
||
break;
|
||
|
||
case SCAN_SHITLISTED:
|
||
s = fget_string_var(FORMAT_NAMES_SHIT_FSET);
|
||
break;
|
||
|
||
case SCAN_BOTS:
|
||
s = fget_string_var(FORMAT_NAMES_BOT_FSET);
|
||
break;
|
||
|
||
case SCAN_ALL:
|
||
default:
|
||
s = fget_string_var(FORMAT_NAMES_FSET);
|
||
}
|
||
|
||
put_it("%s",
|
||
convert_output_format(s, "%s %s %d %d %s",
|
||
update_clock(GET_TIME), chan->channel, n_inscan, n_total,
|
||
match_host ? match_host : empty_string));
|
||
|
||
for (nick = snick; nick; nick = nick->next)
|
||
{
|
||
char *nick_format;
|
||
char *user_format;
|
||
char *nick_buffer = NULL;
|
||
char nick_sym;
|
||
|
||
if (!nick_in_scan(nick, scan_type, match_host))
|
||
continue;
|
||
|
||
/* Determine the nick format string to use */
|
||
if (!my_stricmp(nick->nick, get_server_nickname(server)))
|
||
nick_format = fget_string_var(FORMAT_NAMES_NICK_ME_FSET);
|
||
else if (nick->userlist && (nick->userlist->flags & ADD_BOT))
|
||
nick_format = fget_string_var(FORMAT_NAMES_NICK_BOT_FSET);
|
||
else if (nick->userlist)
|
||
nick_format = fget_string_var(FORMAT_NAMES_NICK_FRIEND_FSET);
|
||
else if (nick->shitlist)
|
||
nick_format = fget_string_var(FORMAT_NAMES_NICK_SHIT_FSET);
|
||
else
|
||
nick_format = fget_string_var(FORMAT_NAMES_NICK_FSET);
|
||
|
||
/* Determine the user format and indicator symbol to use. */
|
||
if (nick_isop(nick))
|
||
{
|
||
user_format = fget_string_var(FORMAT_NAMES_USER_CHANOP_FSET);
|
||
nick_sym = '@';
|
||
}
|
||
else if (nick_ishalfop(nick))
|
||
{
|
||
user_format = fget_string_var(FORMAT_NAMES_USER_CHANOP_FSET);
|
||
nick_sym = '%';
|
||
}
|
||
else if (nick_isvoice(nick))
|
||
{
|
||
user_format = fget_string_var(FORMAT_NAMES_USER_VOICE_FSET);
|
||
nick_sym = '+';
|
||
}
|
||
else if (nick_isircop(nick))
|
||
{
|
||
user_format = fget_string_var(FORMAT_NAMES_USER_IRCOP_FSET);
|
||
nick_sym = '*';
|
||
}
|
||
else
|
||
{
|
||
user_format = fget_string_var(FORMAT_NAMES_USER_FSET);
|
||
nick_sym = '.';
|
||
}
|
||
|
||
/* Construct the string */
|
||
malloc_strcpy(&nick_buffer, convert_output_format(nick_format,
|
||
"%s", nick->nick));
|
||
malloc_strcat(&buffer,
|
||
convert_output_format(user_format, "%c %s", nick_sym,
|
||
nick_buffer));
|
||
malloc_strcat(&buffer, space);
|
||
new_free(&nick_buffer);
|
||
|
||
/* If this completes a line, output it */
|
||
if (count++ >= (cols - 1))
|
||
{
|
||
if (fget_string_var(FORMAT_NAMES_BANNER_FSET))
|
||
put_it("%s%s", convert_output_format(fget_string_var(FORMAT_NAMES_BANNER_FSET), NULL, NULL), buffer);
|
||
else
|
||
put_it("%s", buffer);
|
||
new_free(&buffer);
|
||
count = 0;
|
||
}
|
||
}
|
||
|
||
/* If a partial line is left, output it */
|
||
if (count)
|
||
{
|
||
if (fget_string_var(FORMAT_NAMES_BANNER_FSET))
|
||
put_it("%s%s", convert_output_format(fget_string_var(FORMAT_NAMES_BANNER_FSET), NULL, NULL), buffer);
|
||
else
|
||
put_it("%s", buffer);
|
||
new_free(&buffer);
|
||
}
|
||
|
||
/* Write the footer */
|
||
if (fget_string_var(FORMAT_NAMES_FOOTER_FSET))
|
||
put_it("%s",
|
||
convert_output_format(fget_string_var(FORMAT_NAMES_FOOTER_FSET),
|
||
"%s %s %d %d %s", update_clock(GET_TIME), chan->channel,
|
||
n_inscan, n_total, match_host ? match_host : empty_string));
|
||
|
||
clear_sorted_nicklist(&snick);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(do_mynames)
|
||
{
|
||
char *channel = NULL;
|
||
int server = from_server;
|
||
int all = 0;
|
||
ChannelList *chan;
|
||
|
||
|
||
if (args)
|
||
{
|
||
if (*args == '-' && tolower(*(args+1)) == 'a')
|
||
all = 1;
|
||
else
|
||
channel = next_arg(args, &args);
|
||
}
|
||
if (all)
|
||
{
|
||
for (chan = get_server_channels(from_server); chan; chan = chan->next)
|
||
my_send_to_server(server, "NAMES %s", chan->channel);
|
||
|
||
}
|
||
else
|
||
{
|
||
if (!(chan = prepare_command(&server, channel, NO_OP)))
|
||
return;
|
||
|
||
my_send_to_server(server, "NAMES %s", chan->channel);
|
||
}
|
||
}
|
||
|
||
BUILT_IN_COMMAND(my_whois)
|
||
{
|
||
char *nick = NULL;
|
||
|
||
if (command)
|
||
{
|
||
if (!strcmp(command, "WILM"))
|
||
nick = get_server_recv_nick(from_server);
|
||
else if (!strcmp(command, "WILN"))
|
||
nick = last_notice[0].from;
|
||
else if (!strcmp(command, "WILC"))
|
||
nick = last_sent_ctcp[0].to;
|
||
else if (!strcmp(command, "WILCR"))
|
||
nick = last_ctcp[0].from;
|
||
|
||
if (!nick)
|
||
{
|
||
bitchsay("You have no friends");
|
||
return;
|
||
}
|
||
}
|
||
else if (args && *args)
|
||
{
|
||
while ((nick = next_arg(args, &args)))
|
||
send_to_server("WHOIS %s %s", nick, nick);
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
nick = get_target_by_refnum(0);
|
||
|
||
if (!nick || is_channel(nick))
|
||
nick = get_server_nickname(from_server);
|
||
}
|
||
|
||
send_to_server("WHOIS %s %s", nick, nick);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(do_unkey)
|
||
{
|
||
char *channel = NULL;
|
||
int server = from_server;
|
||
ChannelList *chan;
|
||
|
||
|
||
if (args)
|
||
channel = next_arg(args, &args);
|
||
if (!(chan = prepare_command(&server, channel, NEED_OP)))
|
||
return;
|
||
if (chan->key)
|
||
my_send_to_server(server, "MODE %s -k %s", chan->channel, chan->key);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(pingcmd)
|
||
{
|
||
struct timeval tp;
|
||
char *to;
|
||
char buffer[101];
|
||
int ping_type = get_int_var(PING_TYPE_VAR);
|
||
|
||
|
||
if (command && !my_stricmp(command, "uPING"))
|
||
ping_type = 1;
|
||
get_time(&tp);
|
||
|
||
if ((to = next_arg(args, &args)) == NULL || !strcmp(to, "*"))
|
||
{
|
||
if ((to = get_current_channel_by_refnum(0)) == NULL)
|
||
if (!(to = get_target_by_refnum(0)))
|
||
to = zero;
|
||
}
|
||
|
||
switch(ping_type)
|
||
{
|
||
case 1:
|
||
snprintf(buffer, 100, "%s PING %lu %lu", to, (unsigned long)tp.tv_sec,(unsigned long)tp.tv_usec);
|
||
break;
|
||
case 2:
|
||
snprintf(buffer, 100, "%s ECHO %lu %lu", to, (unsigned long)tp.tv_sec,(unsigned long)tp.tv_usec);
|
||
break;
|
||
default:
|
||
snprintf(buffer, 100, "%s PING %lu", to, (unsigned long)now);
|
||
}
|
||
ctcp(command, buffer, empty_string, NULL);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(ctcp_simple)
|
||
{
|
||
char *person = next_arg(args, &args);
|
||
|
||
if (person == NULL || !strcmp(person, "*"))
|
||
{
|
||
if ((person = get_current_channel_by_refnum(0)) == NULL)
|
||
if ((person = get_target_by_refnum(0)) == NULL)
|
||
person = zero;
|
||
}
|
||
|
||
if (!in_ctcp())
|
||
{
|
||
send_ctcp(CTCP_PRIVMSG, person, get_ctcp_val(command), NULL);
|
||
put_it("%s", convert_output_format(fget_string_var(FORMAT_SEND_CTCP_FSET),
|
||
"%s %s %s",update_clock(GET_TIME), person, command));
|
||
add_last_type(&last_sent_ctcp[0], 1, NULL, NULL, person, command);
|
||
}
|
||
}
|
||
|
||
BUILT_IN_COMMAND(do_offers)
|
||
{
|
||
char *person;
|
||
int type = 0;
|
||
|
||
|
||
if ((person = next_arg(args, &args)) == NULL || !strcmp(person, "*"))
|
||
{
|
||
if ((person = get_current_channel_by_refnum(0)) == NULL)
|
||
person = zero;
|
||
}
|
||
if ((type = in_ctcp()) == -1)
|
||
echocmd(NULL, "*** You may noT use the CTCP command in an ON CTCP_REPLY!", empty_string, NULL);
|
||
else
|
||
{
|
||
send_ctcp(type, person, CTCP_CDCC2, "%s", "LIST");
|
||
put_it("%s", convert_output_format(fget_string_var(FORMAT_SEND_CTCP_FSET),
|
||
"%s %s %s",update_clock(GET_TIME), person, "XDCC LIST"));
|
||
add_last_type(&last_sent_ctcp[0], 1, NULL, NULL, person, "CDCC LIST");
|
||
}
|
||
}
|
||
|
||
/*ARGSUSED*/
|
||
BUILT_IN_COMMAND(ctcp)
|
||
{
|
||
char *to;
|
||
char *stag = NULL;
|
||
int tag;
|
||
int type;
|
||
|
||
|
||
if ((to = next_arg(args, &args)) != NULL)
|
||
{
|
||
if (!strcmp(to, "*"))
|
||
if ((to = get_current_channel_by_refnum(0)) == NULL)
|
||
to = zero;
|
||
|
||
if ((stag = next_arg(args, &args)) != NULL)
|
||
tag = get_ctcp_val(upper(stag));
|
||
else
|
||
tag = CTCP_VERSION;
|
||
|
||
if ((type = in_ctcp()) == -1)
|
||
say("You may not use the CTCP command from an ON CTCP_REPLY!");
|
||
else
|
||
{
|
||
if (args && *args)
|
||
send_ctcp(type, to, tag, "%s", args);
|
||
else
|
||
send_ctcp(type, to, tag, NULL);
|
||
put_it("%s", convert_output_format(fget_string_var(FORMAT_SEND_CTCP_FSET),
|
||
"%s %s %s %s",update_clock(GET_TIME), to, stag ? stag : "VERSION", args ? args: empty_string));
|
||
add_last_type(&last_sent_ctcp[0], 1, NULL, NULL, to, stag? stag : "VERSION");
|
||
}
|
||
}
|
||
}
|
||
|
||
/*ARGSUSED*/
|
||
BUILT_IN_COMMAND(hookcmd)
|
||
{
|
||
|
||
if (*args)
|
||
do_hook(HOOK_LIST, "%s", args);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(dcc)
|
||
{
|
||
|
||
if (*args)
|
||
process_dcc(args);
|
||
else
|
||
dcc_glist(NULL, NULL);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(deop)
|
||
{
|
||
send_to_server("MODE %s -o", get_server_nickname(from_server));
|
||
}
|
||
|
||
BUILT_IN_COMMAND(funny_stuff)
|
||
{
|
||
char *arg,
|
||
*stuff;
|
||
int min = 0,
|
||
max = 0,
|
||
flags = 0,
|
||
ircu = 0;
|
||
|
||
|
||
stuff = empty_string;
|
||
if (!args || !*args)
|
||
{
|
||
bitchsay("Doing this is not a good idea. Add -YES if you really mean it");
|
||
return;
|
||
}
|
||
while ((arg = next_arg(args, &args)) != NULL)
|
||
{
|
||
if (*arg == '/' || *arg == '-')
|
||
{
|
||
if (my_strnicmp(arg+1, "I", 1) == 0) /* MAX */
|
||
ircu = 1;
|
||
else if (my_strnicmp(arg+1, "MA", 2) == 0) /* MAX */
|
||
{
|
||
if ((arg = next_arg(args, &args)) != NULL)
|
||
max = atoi(arg);
|
||
}
|
||
else if (my_strnicmp(arg+1, "MI", 2) == 0) /* MIN */
|
||
{
|
||
if ((arg = next_arg(args, &args)) != NULL)
|
||
min = atoi(arg);
|
||
}
|
||
else if (my_strnicmp(arg+1, "A", 1) == 0) /* ALL */
|
||
flags &= ~(FUNNY_PUBLIC | FUNNY_PRIVATE);
|
||
else if (my_strnicmp(arg+1, "PU", 2) == 0) /* PUBLIC */
|
||
{
|
||
flags |= FUNNY_PUBLIC;
|
||
flags &= ~FUNNY_PRIVATE;
|
||
}
|
||
else if (my_strnicmp(arg+1, "PR", 2) == 0) /* PRIVATE */
|
||
{
|
||
flags |= FUNNY_PRIVATE;
|
||
flags &= ~FUNNY_PUBLIC;
|
||
}
|
||
else if (my_strnicmp(arg+1, "T", 1) == 0) /* TOPIC */
|
||
flags |= FUNNY_TOPIC;
|
||
else if (my_strnicmp(arg+1, "W", 1) == 0) /* WIDE */
|
||
flags |= FUNNY_WIDE;
|
||
else if (my_strnicmp(arg+1, "U", 1) == 0) /* USERS */
|
||
flags |= FUNNY_USERS;
|
||
else if (my_strnicmp(arg+1, "N", 1) == 0) /* NAME */
|
||
flags |= FUNNY_NAME;
|
||
else if (!my_strnicmp(arg+1, "Y", 1))
|
||
;
|
||
else
|
||
stuff = arg;
|
||
}
|
||
else stuff = arg;
|
||
}
|
||
set_funny_flags(min, max, flags);
|
||
if (!strcmp(stuff, "*"))
|
||
if (!(stuff = get_current_channel_by_refnum(0)))
|
||
stuff = empty_string;
|
||
if (strchr(stuff, '*'))
|
||
{
|
||
funny_match(stuff);
|
||
if (min && ircu)
|
||
{
|
||
if (max)
|
||
send_to_server("%s >%d,<%d", command, min - 1, max + 1);
|
||
else
|
||
send_to_server("%s >%d", command, min - 1);
|
||
}
|
||
else if (max && ircu)
|
||
send_to_server("%s <%d", command, max + 1);
|
||
else
|
||
send_to_server("%s %s", command, empty_string);
|
||
}
|
||
else
|
||
{
|
||
funny_match(NULL);
|
||
if (min && ircu)
|
||
{
|
||
if (max)
|
||
send_to_server("%s >%d,<%d", command, min - 1, max + 1);
|
||
else
|
||
send_to_server("%s >%d", command, min - 1);
|
||
}
|
||
else if (max && ircu)
|
||
send_to_server("%s <%d", command, max + 1);
|
||
else
|
||
send_to_server("%s %s", command, stuff);
|
||
}
|
||
}
|
||
|
||
/*
|
||
This isn't a command, it's used by the wait command. Since it's extern,
|
||
and it doesn't use anything static in this file, I'm sure it doesn't
|
||
belong here.
|
||
*/
|
||
void oh_my_wait (int servnum)
|
||
{
|
||
int w_server;
|
||
|
||
if ((w_server = servnum) == -1)
|
||
w_server = primary_server;
|
||
|
||
if (is_server_connected(w_server))
|
||
{
|
||
int old_doing_privmsg = doing_privmsg;
|
||
int old_doing_notice = doing_notice;
|
||
int old_in_ctcp_flag = in_ctcp_flag;
|
||
int old_from_server = from_server;
|
||
|
||
waiting_out++;
|
||
lock_stack_frame();
|
||
my_send_to_server(w_server, "%s", lame_wait_nick);
|
||
while (waiting_in < waiting_out)
|
||
io("oh_my_wait");
|
||
|
||
doing_privmsg = old_doing_privmsg;
|
||
doing_notice = old_doing_notice;
|
||
in_ctcp_flag = old_in_ctcp_flag;
|
||
from_server = old_from_server;
|
||
}
|
||
}
|
||
|
||
BUILT_IN_COMMAND(waitcmd)
|
||
{
|
||
char *ctl_arg = next_arg(args, &args);
|
||
|
||
if (from_server == -1)
|
||
return;
|
||
if (ctl_arg && !my_strnicmp(ctl_arg, "-c", 2))
|
||
{
|
||
WaitCmd *new_wait;
|
||
|
||
new_wait = (WaitCmd *) new_malloc(sizeof(WaitCmd));
|
||
new_wait->stuff = m_strdup(args);
|
||
new_wait->next = NULL;
|
||
|
||
if (end_wait_list)
|
||
end_wait_list->next = new_wait;
|
||
end_wait_list = new_wait;
|
||
if (!start_wait_list)
|
||
start_wait_list = new_wait;
|
||
send_to_server("%s", wait_nick);
|
||
}
|
||
|
||
else if (ctl_arg && !my_strnicmp(ctl_arg, "for", 3))
|
||
{
|
||
clear_sent_to_server(from_server);
|
||
parse_line(NULL, args, subargs, 0, 0, 1);
|
||
if (sent_to_server(from_server))
|
||
oh_my_wait(from_server);
|
||
clear_sent_to_server(from_server);
|
||
}
|
||
|
||
else if (ctl_arg && *ctl_arg == '%')
|
||
{
|
||
int w_index = is_valid_process(ctl_arg);
|
||
|
||
if (w_index != -1)
|
||
{
|
||
if (args && *args)
|
||
{
|
||
if (!my_strnicmp(args, "-cmd", 4))
|
||
next_arg(args, &args);
|
||
add_process_wait(w_index, args?args:empty_string);
|
||
}
|
||
else
|
||
{
|
||
set_input(empty_string);
|
||
lock_stack_frame();
|
||
while (process_is_running(ctl_arg))
|
||
io("wait %proc");
|
||
unlock_stack_frame();
|
||
}
|
||
}
|
||
}
|
||
else if (ctl_arg)
|
||
debugyell("Unknown argument to /WAIT");
|
||
else
|
||
{
|
||
oh_my_wait(from_server);
|
||
clear_sent_to_server(from_server);
|
||
}
|
||
}
|
||
|
||
int check_wait_command(char *nick)
|
||
{
|
||
if ((waiting_out > waiting_in) && !strcmp(nick, lame_wait_nick))
|
||
{
|
||
waiting_in++;
|
||
unlock_stack_frame();
|
||
return 1;
|
||
}
|
||
if (start_wait_list && !strcmp(nick, wait_nick))
|
||
{
|
||
WaitCmd *old = start_wait_list;
|
||
|
||
start_wait_list = old->next;
|
||
if (old->stuff)
|
||
{
|
||
parse_line("WAIT", old->stuff, empty_string, 0, 0, 1);
|
||
new_free(&old->stuff);
|
||
}
|
||
if (end_wait_list == old)
|
||
end_wait_list = NULL;
|
||
new_free((char **)&old);
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
BUILT_IN_COMMAND(redirect)
|
||
{
|
||
char *who;
|
||
|
||
|
||
if (!(who = next_arg(args, &args)))
|
||
return;
|
||
if (!strcmp(who, "*") && !(who = get_current_channel_by_refnum(0)))
|
||
{
|
||
bitchsay("Must be on a channel to redirect to '*'");
|
||
return;
|
||
}
|
||
|
||
if (!my_stricmp(who, get_server_nickname(from_server)))
|
||
{
|
||
bitchsay("You may not redirect output to yourself");
|
||
return;
|
||
}
|
||
|
||
|
||
if ((*who == '=') && !dcc_activechat(who + 1))
|
||
{
|
||
bitchsay("No active DCC CHAT:chat connection for %s", who+1);
|
||
return;
|
||
}
|
||
|
||
set_server_redirect(from_server, who);
|
||
clear_sent_to_server(from_server);
|
||
parse_line(NULL, args, NULL, 0, 0, 1);
|
||
|
||
if (sent_to_server(from_server))
|
||
send_to_server("***%s", who);
|
||
else
|
||
set_server_redirect(from_server, NULL);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(sleepcmd)
|
||
{
|
||
char *arg;
|
||
|
||
|
||
if ((arg = next_arg(args, &args)) != NULL)
|
||
sleep(atoi(arg));
|
||
}
|
||
|
||
/*
|
||
* echocmd: simply displays the args to the screen, or, if it's XECHO,
|
||
* processes the flags first, then displays the text on
|
||
* the screen
|
||
* XECHO
|
||
*/
|
||
BUILT_IN_COMMAND(echocmd)
|
||
{
|
||
unsigned display;
|
||
char *flag_arg;
|
||
int temp;
|
||
int all_windows = 0;
|
||
int x = -1, y = -1, raw = 0, more = 1;
|
||
int banner = 0;
|
||
int no_log = 0;
|
||
unsigned long from_level = 0;
|
||
unsigned long lastlog_level = 0;
|
||
|
||
char *stuff = NULL;
|
||
Window *old_target_window = target_window;
|
||
|
||
int old_und = 0, old_rev = 0, old_bold = 0,
|
||
old_color = 0, old_blink = 0, old_ansi = 0;
|
||
int xtended = 0;
|
||
const char *saved_from = NULL;
|
||
unsigned long saved_level = 0;
|
||
|
||
save_display_target(&saved_from, &saved_level);
|
||
if (command && *command == 'X')
|
||
{
|
||
while (more && args && (*args == '-' || *args == '/'))
|
||
{
|
||
switch(toupper(args[1]))
|
||
{
|
||
case 'C':
|
||
{
|
||
next_arg(args, &args);
|
||
target_window = current_window;
|
||
break;
|
||
}
|
||
case 'L':
|
||
{
|
||
flag_arg = next_arg(args, &args);
|
||
if (toupper(flag_arg[2]) == 'I') /* LINE */
|
||
{
|
||
int to_line = 0;
|
||
|
||
if (!target_window)
|
||
{
|
||
debugyell("%s: -LINE only works if -WIN is specified first", command);
|
||
target_window = old_target_window;
|
||
return;
|
||
}
|
||
else if (target_window->scratch_line == -1)
|
||
{
|
||
debugyell("%s: -LINE only works on scratch windows", command);
|
||
target_window = old_target_window;
|
||
return;
|
||
}
|
||
|
||
to_line = my_atol(next_arg(args, &args));
|
||
if (to_line < 0 || to_line >= target_window->display_size)
|
||
{
|
||
debugyell("%s: -LINE %d is out of range for window (max %d)",
|
||
command, to_line, target_window->display_size - 1);
|
||
target_window = old_target_window;
|
||
return;
|
||
}
|
||
target_window->scratch_line = to_line;
|
||
}
|
||
else /* LEVEL */
|
||
{
|
||
if (!(flag_arg = next_arg(args, &args)))
|
||
break;
|
||
if ((temp = parse_lastlog_level(flag_arg, 0)) != 0)
|
||
{
|
||
lastlog_level = set_lastlog_msg_level(temp);
|
||
from_level = message_from_level(temp);
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
|
||
case 'W':
|
||
{
|
||
flag_arg = next_arg(args, &args);
|
||
if (!(flag_arg = next_arg(args, &args)))
|
||
break;
|
||
if (isdigit((unsigned char)*flag_arg))
|
||
target_window = get_window_by_refnum(my_atol(flag_arg));
|
||
else
|
||
target_window = get_window_by_name(flag_arg);
|
||
break;
|
||
}
|
||
|
||
case 'T':
|
||
{
|
||
flag_arg = next_arg(args, &args);
|
||
if (!(flag_arg = next_arg(args, &args)))
|
||
break;
|
||
target_window = get_window_target_by_desc(flag_arg);
|
||
break;
|
||
}
|
||
case 'A':
|
||
case '*':
|
||
next_arg(args, &args);
|
||
all_windows = 1;
|
||
break;
|
||
case 'K': /* X -- allow all attributes to be outputted */
|
||
{
|
||
next_arg(args, &args);
|
||
|
||
old_und = get_int_var(UNDERLINE_VIDEO_VAR);
|
||
old_rev = get_int_var(INVERSE_VIDEO_VAR);
|
||
old_bold = get_int_var(BOLD_VIDEO_VAR);
|
||
old_color = get_int_var(COLOR_VAR);
|
||
old_blink = get_int_var(BLINK_VIDEO_VAR);
|
||
old_ansi = get_int_var(DISPLAY_ANSI_VAR);
|
||
|
||
set_int_var(UNDERLINE_VIDEO_VAR, 1);
|
||
set_int_var(INVERSE_VIDEO_VAR, 1);
|
||
set_int_var(BOLD_VIDEO_VAR, 1);
|
||
set_int_var(COLOR_VAR, 1);
|
||
set_int_var(BLINK_VIDEO_VAR, 1);
|
||
set_int_var(DISPLAY_ANSI_VAR, 1);
|
||
|
||
xtended = 1;
|
||
break;
|
||
}
|
||
case 'X':
|
||
next_arg(args, &args);
|
||
if (!(flag_arg = next_arg(args, &args)))
|
||
break;
|
||
x = my_atol(flag_arg);
|
||
break;
|
||
case 'Y':
|
||
next_arg(args, &args);
|
||
if (!(flag_arg = next_arg(args, &args)))
|
||
break;
|
||
y = my_atol(flag_arg);
|
||
break;
|
||
case 'R':
|
||
next_arg(args, &args);
|
||
if (target_window)
|
||
output_screen = target_window->screen;
|
||
else
|
||
output_screen = current_window->screen;
|
||
tputs_x(args);
|
||
term_flush();
|
||
target_window = old_target_window;
|
||
return;
|
||
case 'B':
|
||
next_arg(args, &args);
|
||
banner = 1;
|
||
break;
|
||
case 'N':
|
||
next_arg(args, &args);
|
||
no_log = 1;
|
||
break;
|
||
case 'S': /* SAY */
|
||
{
|
||
next_arg(args, &args);
|
||
if (!window_display)
|
||
{
|
||
target_window = old_target_window;
|
||
return;
|
||
}
|
||
break;
|
||
}
|
||
|
||
case '-':
|
||
{
|
||
next_arg(args, &args);
|
||
more = 0;
|
||
break;
|
||
}
|
||
default:
|
||
{
|
||
more = 0;
|
||
break;
|
||
}
|
||
}
|
||
if (!args)
|
||
args = empty_string;
|
||
}
|
||
}
|
||
|
||
display = window_display;
|
||
window_display = 1;
|
||
strip_ansi_in_echo = 0;
|
||
|
||
if (no_log)
|
||
inhibit_logging = 1;
|
||
|
||
if (banner == 1)
|
||
{
|
||
malloc_strcpy(&stuff, numeric_banner());
|
||
if (*stuff)
|
||
{
|
||
m_3cat(&stuff, space, args);
|
||
args = stuff;
|
||
}
|
||
}
|
||
else if (banner != 0)
|
||
abort();
|
||
|
||
if (all_windows == 1)
|
||
{
|
||
Window *win = NULL;
|
||
while ((traverse_all_windows(&win)))
|
||
{
|
||
target_window = win;
|
||
put_echo(args);
|
||
}
|
||
}
|
||
else if (all_windows != 0)
|
||
abort();
|
||
else if (x > -1 || y > -1 || raw)
|
||
{
|
||
if (x <= -1)
|
||
x = 0;
|
||
if (y <= -1)
|
||
{
|
||
if (target_window)
|
||
y = target_window->cursor;
|
||
else
|
||
y = current_window->cursor;
|
||
}
|
||
if (!raw)
|
||
term_move_cursor(x, y);
|
||
tputs_x(args);
|
||
term_flush();
|
||
}
|
||
else
|
||
put_echo(args);
|
||
|
||
strip_ansi_in_echo = 1;
|
||
if (xtended)
|
||
{
|
||
set_int_var(UNDERLINE_VIDEO_VAR, old_und);
|
||
set_int_var(INVERSE_VIDEO_VAR, old_rev);
|
||
set_int_var(BOLD_VIDEO_VAR, old_bold);
|
||
set_int_var(COLOR_VAR, old_color);
|
||
set_int_var(BLINK_VIDEO_VAR, old_blink);
|
||
set_int_var(DISPLAY_ANSI_VAR, old_ansi);
|
||
}
|
||
if (lastlog_level)
|
||
{
|
||
set_lastlog_msg_level(lastlog_level);
|
||
message_from_level(from_level);
|
||
}
|
||
if (stuff)
|
||
new_free(&stuff);
|
||
if (no_log)
|
||
inhibit_logging = 0;
|
||
window_display = display;
|
||
set_display_target(saved_from, saved_level);
|
||
target_window = old_target_window;
|
||
}
|
||
|
||
/*
|
||
*/
|
||
|
||
static void oper_password_received(char *data, char *line)
|
||
{
|
||
send_to_server("OPER %s %s", data, line);
|
||
if (line && *line)
|
||
memset(line, 0, strlen(line)-1);
|
||
}
|
||
|
||
/* oper: the OPER command. */
|
||
BUILT_IN_COMMAND(oper)
|
||
{
|
||
char *password;
|
||
char *nick;
|
||
|
||
oper_command = 1;
|
||
if (!(nick = next_arg(args, &args)))
|
||
nick = get_server_nickname(from_server);
|
||
if (!(password = next_arg(args, &args)))
|
||
{
|
||
add_wait_prompt("Operator Password:", oper_password_received, nick, WAIT_PROMPT_LINE, 0);
|
||
return;
|
||
}
|
||
send_to_server("OPER %s %s", nick, password);
|
||
memset(password, 0, strlen(password));
|
||
}
|
||
|
||
#ifndef PUBLIC_ACCESS
|
||
/* This generates a file of your ircII setup */
|
||
void really_save(char *ircrc_file, int flags, int save_all, int save_append)
|
||
{
|
||
FILE *fp;
|
||
char * mode[] = {"w", "a"};
|
||
|
||
if ((fp = fopen(ircrc_file, mode[save_append])) != NULL)
|
||
{
|
||
if (flags & SFLAG_ALIAS)
|
||
save_aliases(fp, save_all);
|
||
if (flags & SFLAG_ASSIGN)
|
||
save_assigns(fp, save_all);
|
||
if (flags & SFLAG_BIND)
|
||
save_bindings(fp, save_all);
|
||
if (flags & SFLAG_ON)
|
||
save_hooks(fp, save_all);
|
||
if (flags & SFLAG_NOTIFY)
|
||
save_notify(fp);
|
||
if (flags & SFLAG_WATCH)
|
||
save_watch(fp);
|
||
if (flags & SFLAG_SET)
|
||
save_variables(fp, save_all);
|
||
if (flags & SFLAG_SERVER)
|
||
save_servers(fp);
|
||
fclose(fp);
|
||
bitchsay("IRCII settings saved to %s", ircrc_file);
|
||
}
|
||
else
|
||
bitchsay("Error opening %s: %s", ircrc_file, strerror(errno));
|
||
}
|
||
#endif
|
||
|
||
/* Full scale abort. Does a "save" into the filename in line, and
|
||
then does a coredump */
|
||
BUILT_IN_COMMAND(abortcmd)
|
||
{
|
||
#ifdef PUBLIC_ACCESS
|
||
bitchsay("This command has been disabled on a public access system");
|
||
return;
|
||
#else
|
||
char *filename = next_arg(args, &args);
|
||
|
||
filename = filename ? filename : "irc.aborted";
|
||
really_save(filename, SFLAG_ALL, 0, 0);
|
||
abort();
|
||
#endif
|
||
}
|
||
|
||
|
||
|
||
/* save_settings: saves the current state of IRCII to a file */
|
||
BUILT_IN_COMMAND(save_settings)
|
||
{
|
||
#ifdef PUBLIC_ACCESS
|
||
bitchsay("This command has been disabled on a public access system");
|
||
return;
|
||
#else
|
||
char *arg = NULL;
|
||
char *fn = NULL;
|
||
int save_append = 0;
|
||
int save_global = 0;
|
||
int save_flags = 0;
|
||
|
||
while ((arg = next_arg(args, &args)) != NULL)
|
||
{
|
||
if ('-' != *arg && '/' != *arg) {
|
||
fn = arg;
|
||
continue;
|
||
}
|
||
upper(++arg);
|
||
if (!strncmp("ALIAS", arg, 3))
|
||
save_flags |= SFLAG_ALIAS;
|
||
else if (!strncmp("ASSIGN", arg, 2))
|
||
save_flags |= SFLAG_ALIAS;
|
||
else if (!strncmp("BIND", arg, 1))
|
||
save_flags |= SFLAG_BIND;
|
||
else if (!strncmp("ON", arg, 1))
|
||
save_flags |= SFLAG_ON;
|
||
else if (!strncmp("SERVER", arg, 3))
|
||
save_flags |= SFLAG_SERVER;
|
||
else if (!strncmp("SET", arg, 3))
|
||
save_flags |= SFLAG_SET;
|
||
else if (!strncmp("NOTIFY", arg, 1))
|
||
save_flags |= SFLAG_NOTIFY;
|
||
else if (!strncmp("WATCH", arg, 1))
|
||
save_flags |= SFLAG_WATCH;
|
||
else if (!strncmp("ALL", arg, 3))
|
||
save_flags = SFLAG_ALL;
|
||
else if (!strncmp("APPEND", arg, 3))
|
||
save_append = 1;
|
||
else if (!strncmp("GLOBAL", arg, 2))
|
||
save_global = 1;
|
||
else if (!strncmp("FILE", arg, 1))
|
||
fn = next_arg(args, &args);
|
||
else
|
||
bitchsay("Unrecognised option");
|
||
}
|
||
|
||
if (!save_flags)
|
||
return;
|
||
|
||
if (!(arg = expand_twiddle((fn && *fn) ? fn : bircrc_file)))
|
||
{
|
||
bitchsay("Unknown user");
|
||
return;
|
||
}
|
||
|
||
really_save(arg, save_flags, save_global, save_append);
|
||
new_free(&arg);
|
||
#endif
|
||
}
|
||
|
||
|
||
BUILT_IN_COMMAND(usleepcmd)
|
||
{
|
||
char *arg;
|
||
struct timeval pause;
|
||
time_t nms;
|
||
|
||
if ((arg = next_arg(args, &args)))
|
||
{
|
||
nms = (time_t)my_atol(arg);
|
||
pause.tv_sec = nms / 1000000;
|
||
pause.tv_usec = nms % 1000000;
|
||
select(0, NULL, NULL, NULL, &pause);
|
||
}
|
||
else
|
||
say("Usage: USLEEP <usec>");
|
||
}
|
||
|
||
AJoinList *add_to_ajoin_list(char *channel, char *args, int type)
|
||
{
|
||
/* type == 1, then we have a real autojoin entry.
|
||
* type == 0, then it's just a channel to join.
|
||
*/
|
||
AJoinList *new = NULL;
|
||
|
||
if (!(new = (AJoinList *)list_lookup((List **) &ajoin_list, channel, 0, !REMOVE_FROM_LIST)))
|
||
{
|
||
char *key, *group;
|
||
key = next_arg(args, &args);
|
||
|
||
new = (AJoinList *) new_malloc(sizeof(AJoinList));
|
||
new->name = m_strdup(channel);
|
||
if(key && *key == '-')
|
||
{
|
||
group = next_arg(args, &args);
|
||
|
||
if(group)
|
||
new->group = m_strdup(group);
|
||
key = next_arg(args, &args);
|
||
}
|
||
if (key && *key)
|
||
new->key = m_strdup(key);
|
||
new->ajoin_list = type;
|
||
new->server = -1;
|
||
add_to_list((List **)&ajoin_list, (List *)new);
|
||
}
|
||
return new;
|
||
}
|
||
|
||
BUILT_IN_COMMAND(auto_join)
|
||
{
|
||
char *channel = NULL;
|
||
AJoinList *new = NULL;
|
||
extern int run_level, do_ignore_ajoin;
|
||
|
||
if (command && *command && !my_stricmp(command, "AJoinList"))
|
||
{
|
||
int count = 0;
|
||
for (new = ajoin_list; new; new = new->next)
|
||
{
|
||
if (!new->ajoin_list) continue;
|
||
if (!count)
|
||
put_it("AJoin List");
|
||
put_it("%20s server/group: %s%s%s", new->name, new->group?new->group:"<none>",
|
||
new->key?" key: ":empty_string, new->key?new->key:empty_string);
|
||
count++;
|
||
}
|
||
if (count)
|
||
put_it("End of AJoin List");
|
||
return;
|
||
}
|
||
if (!args || !*args)
|
||
return;
|
||
|
||
/* If the user used the ignore ajoin switch and
|
||
* we aren't in interactive mode, abort.
|
||
*/
|
||
if(do_ignore_ajoin && run_level != 2)
|
||
return;
|
||
|
||
channel = next_arg(args, &args);
|
||
if (command && *command && !my_stricmp(command, "UNAJOIN"))
|
||
{
|
||
if (channel && (new = (AJoinList *)remove_from_list((List **)&ajoin_list, make_channel(channel))))
|
||
{
|
||
if (new->ajoin_list)
|
||
{
|
||
bitchsay("Removing Auto-Join channel %s", new->name);
|
||
new_free(&new->name);
|
||
new_free(&new->key);
|
||
new_free((char **)&new);
|
||
} else
|
||
add_to_list((List **)&ajoin_list, (List *)new);
|
||
}
|
||
return;
|
||
}
|
||
|
||
if (!channel || !(new = add_to_ajoin_list(make_channel(channel), args, 1)))
|
||
return;
|
||
if (is_server_connected(from_server)/* && get_server_channels(from_server)*/)
|
||
{
|
||
bitchsay("Auto-Joining %s%s%s", new->name, new->key?space:empty_string, new->key?new->key:empty_string);
|
||
if(!new->group || is_server_valid(new->group, from_server))
|
||
{
|
||
if(get_int_var(JOIN_NEW_WINDOW_VAR) && (current_window->current_channel || current_window->query_nick))
|
||
win_create(JOIN_NEW_WINDOW_VAR, 0);
|
||
send_to_server("JOIN %s %s", new->name, new->key? new->key:empty_string);
|
||
}
|
||
}
|
||
}
|
||
|
||
/*
|
||
* e_channel: does the channel command. I just added displaying your current
|
||
* channel if none is given
|
||
*/
|
||
BUILT_IN_COMMAND(e_channel)
|
||
{
|
||
char *chan;
|
||
char *buffer=NULL;
|
||
|
||
set_display_target(NULL, LOG_CURRENT);
|
||
if ((chan = next_arg(args, &args)) != NULL)
|
||
{
|
||
if (!my_strnicmp(chan, "-i", 2))
|
||
{
|
||
if (invite_channel)
|
||
send_to_server("%s %s %s", command, invite_channel, args);
|
||
else
|
||
bitchsay("You have not been invited to a channel!");
|
||
}
|
||
else
|
||
{
|
||
if (!(buffer = make_channel(chan)))
|
||
return;
|
||
if (!is_server_connected(from_server))
|
||
add_to_ajoin_list(buffer, args, 0);
|
||
else if (is_on_channel(buffer, from_server, get_server_nickname(from_server)))
|
||
{
|
||
/* XXXX -
|
||
right here we want to check to see if the
|
||
channel is bound to this window. if it is,
|
||
we set it as the default channel. If it
|
||
is not, we warn the user that we can't do it
|
||
*/
|
||
if (is_bound_anywhere(buffer) &&
|
||
!(is_bound_to_window(current_window, buffer)))
|
||
bitchsay("Channel %s is bound to another window", buffer);
|
||
|
||
else
|
||
{
|
||
is_current_channel(buffer, from_server, 1);
|
||
if (do_hook(CHANNEL_SWITCH_LIST, "%s", set_current_channel_by_refnum(0, buffer)))
|
||
bitchsay("You are now talking to channel %s", set_current_channel_by_refnum(0, buffer));
|
||
update_all_windows();
|
||
set_input_prompt(current_window, get_string_var(INPUT_PROMPT_VAR), 0);
|
||
update_input(UPDATE_ALL);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if(get_int_var(JOIN_NEW_WINDOW_VAR) && (current_window->current_channel || current_window->query_nick))
|
||
win_create(JOIN_NEW_WINDOW_VAR, 0);
|
||
send_to_server("%s %s%s%s", command, buffer, args?space:empty_string, args?args:empty_string);
|
||
if (!is_bound(buffer, from_server))
|
||
malloc_strcpy(¤t_window->waiting_channel, buffer);
|
||
}
|
||
}
|
||
update_all_status(current_window, NULL, 0);
|
||
}
|
||
else
|
||
list_channels();
|
||
reset_display_target();
|
||
}
|
||
|
||
/* comment: does the /COMMENT command, useful in .ircrc */
|
||
BUILT_IN_COMMAND(comment)
|
||
{
|
||
/* nothing to do... */
|
||
}
|
||
|
||
/*
|
||
* e_nick: does the /NICK command. Records the users current nickname and
|
||
* sends the command on to the server
|
||
*/
|
||
BUILT_IN_COMMAND(e_nick)
|
||
{
|
||
char *nick;
|
||
|
||
|
||
if (!(nick = next_arg(args, &args)))
|
||
{
|
||
bitchsay("Your nickname is %s", get_server_nickname(get_window_server(0)));
|
||
if (get_pending_nickname(get_window_server(0)))
|
||
say("A nickname change to %s is pending.", get_pending_nickname(get_window_server(0)));
|
||
|
||
return;
|
||
}
|
||
if (!(nick = check_nickname(nick)))
|
||
{
|
||
bitchsay("Nickname specified is illegal.");
|
||
return;
|
||
}
|
||
nick_command_is_pending(from_server, 1);
|
||
change_server_nickname(from_server, nick);
|
||
set_string_var(AUTO_RESPONSE_STR_VAR, nick);
|
||
}
|
||
|
||
/* version: does the /VERSION command with some IRCII version stuff */
|
||
BUILT_IN_COMMAND(version1)
|
||
{
|
||
char *host;
|
||
|
||
|
||
if ((host = next_arg(args, &args)) != NULL)
|
||
send_to_server("%s %s", command, host);
|
||
else
|
||
{
|
||
bitchsay("Client: %s (internal version %s)", irc_version, internal_version);
|
||
send_to_server("%s", command);
|
||
}
|
||
}
|
||
|
||
/* Functions used by e_hostname to generate a list of local interface
|
||
* addreses (vhosts).
|
||
*/
|
||
|
||
/* add_address()
|
||
*
|
||
* This converts a local address to a character string, and adds it to the
|
||
* list of addresses if not a duplicate or a special address. If norev
|
||
* is not set, it also looks up the hostname.
|
||
*/
|
||
void add_address(Virtuals **vhost_list, int norev, struct sockaddr *sa)
|
||
{
|
||
struct sockaddr_in * const sin = (struct sockaddr_in *)sa;
|
||
const char *result = NULL;
|
||
Virtuals *vhost;
|
||
#ifdef IPV6
|
||
struct sockaddr_in6 * const sin6 = (struct sockaddr_in6 *)sa;
|
||
char addr[128];
|
||
socklen_t slen = 0;
|
||
#else
|
||
struct hostent *host;
|
||
#endif /* IPV6 */
|
||
|
||
#ifdef IPV6
|
||
if (sa->sa_family == AF_INET)
|
||
{
|
||
slen = sizeof(struct sockaddr);
|
||
result = inet_ntop(sa->sa_family, &sin->sin_addr, addr, sizeof addr);
|
||
}
|
||
else if (sa->sa_family == AF_INET6)
|
||
{
|
||
slen = sizeof(struct sockaddr_in6);
|
||
result = inet_ntop(sa->sa_family, &sin6->sin6_addr, addr, sizeof addr);
|
||
}
|
||
#else /* IPV6 */
|
||
if (sa->sa_family == AF_INET)
|
||
{
|
||
result = inet_ntoa(sin->sin_addr);
|
||
}
|
||
#endif
|
||
|
||
if (result == NULL)
|
||
return;
|
||
|
||
/* Ignore INADDR_ANY, loopback and link-local addresses (see RFC 2373) */
|
||
if (!strcmp(result, "127.0.0.1") ||
|
||
!strcmp(result, "0.0.0.0") ||
|
||
!strcmp(result, "::1") ||
|
||
!strcmp(result, "0::1") ||
|
||
!strcmp(result, "::") ||
|
||
!strcmp(result, "0::0") ||
|
||
!strncasecmp(result, "fe8", 3) ||
|
||
!strncasecmp(result, "fe9", 3) ||
|
||
!strncasecmp(result, "fea", 3) ||
|
||
!strncasecmp(result, "feb", 3))
|
||
{
|
||
return;
|
||
}
|
||
|
||
for (vhost = *vhost_list; vhost ; vhost = vhost->next)
|
||
{
|
||
/* Ignore duplicates */
|
||
if (!strcasecmp(result, vhost->address))
|
||
return;
|
||
}
|
||
|
||
/* Got a new address, so add it to the list */
|
||
vhost = (Virtuals *) new_malloc(sizeof(Virtuals));
|
||
|
||
/* Set the address and hostname strings */
|
||
vhost->address = m_strdup(result);
|
||
#ifdef IPV6
|
||
if (!norev && !getnameinfo(sa, slen, addr, sizeof addr, NULL, 0, 0))
|
||
{
|
||
vhost->hostname = m_strdup(addr);
|
||
}
|
||
else
|
||
{
|
||
vhost->hostname = m_strdup(result);
|
||
}
|
||
#else
|
||
if (!norev && (host = gethostbyaddr(&sin->sin_addr, sizeof(sin->sin_addr),
|
||
AF_INET)))
|
||
{
|
||
vhost->hostname = m_strdup(host->h_name);
|
||
}
|
||
else
|
||
{
|
||
vhost->hostname = m_strdup(result);
|
||
}
|
||
#endif
|
||
|
||
add_to_list((List **)vhost_list, (List *)vhost);
|
||
|
||
return;
|
||
}
|
||
|
||
#ifdef IPV6
|
||
/* add_addrs_getifaddrs()
|
||
*
|
||
* This uses getifaddrs() to find local interface addresses.
|
||
* On some older versions of glibc this only finds IPv4 addreses. */
|
||
void add_addrs_getifaddrs(Virtuals **vhost_list, int norev)
|
||
{
|
||
struct ifaddrs *addr_list, *ifa;
|
||
|
||
if (getifaddrs(&addr_list) != 0)
|
||
{
|
||
yell("getifaddrs() failed.");
|
||
return;
|
||
}
|
||
|
||
for (ifa = addr_list; ifa; ifa = ifa->ifa_next)
|
||
{
|
||
if ((ifa->ifa_flags & IFF_UP) && ifa->ifa_addr)
|
||
add_address(vhost_list, norev, ifa->ifa_addr);
|
||
}
|
||
|
||
freeifaddrs(addr_list);
|
||
return;
|
||
}
|
||
|
||
/* add_addrs_proc_net
|
||
*
|
||
* For the benefit of systems with the older glibc, this function looks
|
||
* in /proc/net/if_inet6 for IPv6 addresses. This is called on all IPv6
|
||
* platforms, but if /proc/net/if_inet6 doesn't exist, no harm, no foul.
|
||
*
|
||
* A line in this file looks like:
|
||
fe80000000000000025056fffec00008 0a 40 20 80 vmnet8
|
||
*/
|
||
void add_addrs_proc_net(Virtuals **vhost_list, int norev)
|
||
{
|
||
FILE *fptr;
|
||
char proc_net_line[200];
|
||
char address[64];
|
||
char *p;
|
||
int i;
|
||
struct sockaddr_in6 sin6;
|
||
|
||
if ((fptr = fopen("/proc/net/if_inet6", "r")) == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
|
||
while (fgets(proc_net_line, sizeof proc_net_line, fptr))
|
||
{
|
||
/* Copy the address, adding : as necessary */
|
||
p = address;
|
||
|
||
for (i = 0; i < 32 && proc_net_line[i]; i++)
|
||
{
|
||
*p++ = proc_net_line[i];
|
||
if ((i < 31) && (i % 4 == 3))
|
||
{
|
||
*p++ = ':';
|
||
}
|
||
}
|
||
*p = '\0';
|
||
|
||
/* We rely on inet_pton to catch any bogus addresses here */
|
||
if (inet_pton(AF_INET6, p, &sin6.sin6_addr) > 0)
|
||
{
|
||
sin6.sin6_family = AF_INET6;
|
||
|
||
add_address(vhost_list, norev, (struct sockaddr *)&sin6);
|
||
}
|
||
}
|
||
|
||
fclose(fptr);
|
||
return;
|
||
}
|
||
|
||
#endif /* ifdef IPV6 */
|
||
|
||
#if defined(SANE_SIOCGIFCONF)
|
||
/* add_addrs_ioctl
|
||
*
|
||
* This uses the old SIOCGIFCONF ioctl to find local interface addresses.
|
||
* It can only find IPv4 addresses.
|
||
*/
|
||
void add_addrs_ioctl(Virtuals **vhost_list, int norev)
|
||
{
|
||
int s;
|
||
size_t len;
|
||
char *buf = NULL;
|
||
struct ifconf ifc;
|
||
struct ifreq *ifr;
|
||
|
||
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||
return;
|
||
|
||
len = 0;
|
||
do {
|
||
len += 4 * sizeof(*ifr);
|
||
RESIZE(buf, char, len);
|
||
|
||
ifc.ifc_buf = buf;
|
||
ifc.ifc_len = len;
|
||
|
||
if (ioctl(s, SANE_SIOCGIFCONF, &ifc) < 0)
|
||
return;
|
||
} while ((ifc.ifc_len + sizeof(*ifr) + 64 >= len) && (len < 200000));
|
||
|
||
for (ifr = (struct ifreq *)buf; (char *)ifr < buf + ifc.ifc_len; ifr++)
|
||
{
|
||
if (ioctl(s, SIOCGIFFLAGS, (char *)ifr) != 0)
|
||
continue;
|
||
|
||
if (!(ifr->ifr_flags & IFF_UP))
|
||
continue;
|
||
|
||
if (ioctl(s, SIOCGIFADDR,(char *)ifr) != 0)
|
||
continue;
|
||
|
||
add_address(vhost_list, norev, &ifr->ifr_addr);
|
||
}
|
||
|
||
close(s);
|
||
return;
|
||
}
|
||
#endif /* if defined(SANE_SIOCGIFCONF) */
|
||
|
||
/* get_local_addrs
|
||
*
|
||
* Construct a linked list of local interface addresses, using whatever
|
||
* methods are appropriate on the platform.
|
||
*/
|
||
void get_local_addrs(Virtuals **vhost_list, int norev)
|
||
{
|
||
*vhost_list = NULL;
|
||
|
||
#ifdef IPV6
|
||
add_addrs_getifaddrs(vhost_list, norev);
|
||
add_addrs_proc_net(vhost_list, norev);
|
||
#elif defined(SANE_SIOCGIFCONF)
|
||
add_addrs_ioctl(vhost_list, norev);
|
||
#endif
|
||
}
|
||
|
||
BUILT_IN_COMMAND(e_hostname)
|
||
{
|
||
int norev = 0;
|
||
char *newhost = NULL;
|
||
char *arg = next_arg(args, &args);
|
||
|
||
if (arg && !strcasecmp(arg, "-norev"))
|
||
{
|
||
norev = 1;
|
||
arg = next_arg(args, &args);
|
||
}
|
||
|
||
if (arg && *arg && *arg != '#' && !is_number(arg))
|
||
{
|
||
malloc_strcpy(&newhost, arg);
|
||
}
|
||
else
|
||
{
|
||
Virtuals *virtuals, *new;
|
||
int i;
|
||
int switch_to = 0;
|
||
|
||
if (arg)
|
||
{
|
||
if (*arg == '#')
|
||
arg++;
|
||
|
||
switch_to = my_atol(arg);
|
||
}
|
||
|
||
get_local_addrs(&virtuals, norev);
|
||
|
||
for (i = 1; virtuals; i++)
|
||
{
|
||
new = virtuals;
|
||
virtuals = virtuals->next;
|
||
if (i == 1)
|
||
put_it("%s", convert_output_format("$G Current hostnames available", NULL, NULL));
|
||
|
||
put_it("%s", convert_output_format("%K[%W$[3]0%K] %B$1", "%d %s", i, new->hostname));
|
||
if (i == switch_to)
|
||
newhost = new->hostname;
|
||
else
|
||
new_free(&new->hostname);
|
||
new_free(&new->address);
|
||
new_free(&new);
|
||
}
|
||
}
|
||
|
||
if (newhost)
|
||
{
|
||
int reconn = 0;
|
||
#ifndef IPV6
|
||
struct hostent *hp;
|
||
#endif
|
||
|
||
/* Reconnect if hostname has changed */
|
||
if (LocalHostName && strcmp(LocalHostName, newhost))
|
||
reconn = 1;
|
||
|
||
malloc_strcpy(&LocalHostName, newhost);
|
||
#ifndef IPV6
|
||
if ((hp = gethostbyname(LocalHostName)))
|
||
memcpy((void *)&LocalHostAddr.sf_addr, hp->h_addr, sizeof(struct in_addr));
|
||
#endif
|
||
|
||
bitchsay("Local host name is now [%s]", LocalHostName);
|
||
new_free(&newhost);
|
||
|
||
if (reconn)
|
||
reconnect_cmd(NULL, NULL, NULL, NULL);
|
||
}
|
||
}
|
||
|
||
extern void display_bitchx (int);
|
||
|
||
BUILT_IN_COMMAND(info)
|
||
{
|
||
|
||
if (!args || !*args)
|
||
{
|
||
display_bitchx(-1);
|
||
return;
|
||
}
|
||
else if (isdigit((unsigned char)*args))
|
||
{
|
||
display_bitchx(my_atol(args));
|
||
return;
|
||
}
|
||
send_to_server("%s %s", command, args);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(setenvcmd)
|
||
{
|
||
char *env_var;
|
||
|
||
if ((env_var = next_arg(args, &args)) != NULL)
|
||
setenv(env_var, args, 1);
|
||
else
|
||
say("Usage: SETENV <var-name> <value>");
|
||
}
|
||
|
||
/*
|
||
* whois: the WHOIS and WHOWAS commands. This translates the
|
||
* to the whois handlers in whois.c
|
||
*/
|
||
BUILT_IN_COMMAND(whois)
|
||
{
|
||
char *nick;
|
||
if (!my_stricmp(command, "WHOWAS"))
|
||
{
|
||
char *word_one = next_arg (args, &args);
|
||
#if 0
|
||
if (args && *args)
|
||
malloc_sprintf(&stuff, "%s %s", word_one, args);
|
||
else if (word_one && *word_one)
|
||
malloc_sprintf(&stuff, "%s %d", word_one, get_int_var(NUM_OF_WHOWAS_VAR));
|
||
else
|
||
malloc_sprintf(&stuff, "%s %d", get_server_nickname(from_server), get_int_var(NUM_OF_WHOWAS_VAR));
|
||
#endif
|
||
send_to_server("WHOWAS %s %s", (word_one && *word_one) ?
|
||
word_one : get_server_nickname(from_server),
|
||
(args && *args) ? args : ltoa(get_int_var(NUM_OF_WHOWAS_VAR)));
|
||
return;
|
||
}
|
||
if (!(nick = next_arg(args, &args))) /* whois command */
|
||
{
|
||
char *target;
|
||
target = get_target_by_refnum(0);
|
||
if (target && !is_channel(target))
|
||
send_to_server("WHOIS %s", target);
|
||
else
|
||
send_to_server("WHOIS %s", get_server_nickname(from_server));
|
||
}
|
||
else
|
||
send_to_server("WHOIS %s%s%s", nick, (args && *args) ? space : empty_string, (args && *args)? args : empty_string);
|
||
}
|
||
|
||
|
||
/*
|
||
* query: the /QUERY command. Works much like the /MSG, I'll let you figure
|
||
* it out.
|
||
*/
|
||
BUILT_IN_COMMAND(query)
|
||
{
|
||
if(args && *args)
|
||
win_create(QUERY_NEW_WINDOW_VAR, 0);
|
||
window_query(current_window, &args, NULL);
|
||
update_window_status(current_window, 0);
|
||
}
|
||
|
||
void read_away_log(char *stuff, char *line)
|
||
{
|
||
|
||
if (!line || !*line || (line && toupper(*line) == 'Y'))
|
||
readlog(NULL, NULL, NULL, NULL);
|
||
update_input(UPDATE_ALL);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(back)
|
||
{
|
||
int minutes = 0;
|
||
int hours = 0;
|
||
int seconds = 0;
|
||
int silent = 0;
|
||
|
||
if (!current_window || from_server == -1)
|
||
return;
|
||
if (command && !my_stricmp(command, "gone"))
|
||
silent = 1;
|
||
if (get_server_awaytime(from_server))
|
||
{
|
||
time_t current_t = now - get_server_awaytime(from_server);
|
||
int old_server = from_server;
|
||
from_server = current_window->server;
|
||
|
||
hours = current_t / 3600;
|
||
minutes = (current_t - (hours * 3600)) / 60;
|
||
seconds = current_t % 60;
|
||
|
||
|
||
if (get_int_var(SEND_AWAY_MSG_VAR) && !silent)
|
||
{
|
||
bitchsay("You were /away for %i hours %i minutes and %i seconds. [\002BX\002-MsgLog %s]",
|
||
hours, minutes, seconds,
|
||
on_off(get_int_var(MSGLOG_VAR)));
|
||
if (fget_string_var(FORMAT_BACK_FSET))
|
||
{
|
||
char str[BIG_BUFFER_SIZE+1];
|
||
char *fset;
|
||
char *reason = args ? args : get_server_away(from_server);
|
||
|
||
fset = stripansicodes(convert_output_format(
|
||
fget_string_var(FORMAT_BACK_FSET), "%s %d %d %d %d %s",
|
||
update_clock(GET_TIME), hours, minutes, seconds,
|
||
get_int_var(MSGCOUNT_VAR), reason));
|
||
snprintf(str, BIG_BUFFER_SIZE, "ACTION %s", fset);
|
||
send_msg_to_channels(from_server, str);
|
||
}
|
||
}
|
||
set_server_away(from_server, NULL, silent);
|
||
from_server = old_server;
|
||
}
|
||
else
|
||
set_server_away(from_server, NULL, silent);
|
||
if (get_int_var(MSGLOG_VAR))
|
||
log_toggle(0, NULL);
|
||
|
||
set_server_awaytime(from_server, 0);
|
||
if (get_int_var(MSGLOG_VAR))
|
||
{
|
||
char tmp[100];
|
||
sprintf(tmp, " read /away msgs (%d msg%s) log [Y/n]? ", get_int_var(MSGCOUNT_VAR), plural(get_int_var(MSGCOUNT_VAR)));
|
||
add_wait_prompt(tmp, read_away_log, empty_string, WAIT_PROMPT_LINE, 1);
|
||
}
|
||
set_int_var(MSGCOUNT_VAR, 0);
|
||
update_all_status(current_window, NULL, 0);
|
||
}
|
||
|
||
/*
|
||
* away: the /AWAY command. Keeps track of the away message locally, and
|
||
* sends the command on to the server.
|
||
*/
|
||
BUILT_IN_COMMAND(away)
|
||
{
|
||
char *arg = NULL;
|
||
int flag = AWAY_ONE;
|
||
int i,
|
||
silent = 0;
|
||
|
||
|
||
if (command && !my_stricmp(command, "awaymsg"))
|
||
{
|
||
extern char *awaymsg;
|
||
if (args && *args)
|
||
{
|
||
malloc_strcpy(&awaymsg, args);
|
||
bitchsay("Your auto-away msg has been set to \"%s\"", awaymsg);
|
||
}
|
||
else
|
||
{
|
||
new_free(&awaymsg);
|
||
bitchsay("Your auto-away msg has been unset");
|
||
}
|
||
return;
|
||
}
|
||
if (*args)
|
||
{
|
||
if ((*args == '-') || (*args == '/'))
|
||
{
|
||
arg = strchr(args, ' ');
|
||
if (arg)
|
||
*arg++ = '\0';
|
||
else
|
||
arg = empty_string;
|
||
if (!my_strnicmp(args+1, "A", 1)) /* all */
|
||
{
|
||
flag = AWAY_ALL;
|
||
args = arg;
|
||
}
|
||
else if (!my_strnicmp(args+1, "O", 1))/* one */
|
||
{
|
||
flag = AWAY_ONE;
|
||
args = arg;
|
||
}
|
||
else
|
||
return;
|
||
}
|
||
}
|
||
if (command && !my_stricmp(command, "gone"))
|
||
silent = 1;
|
||
if (flag == AWAY_ALL)
|
||
{
|
||
for (i = 0; i < server_list_size(); i++)
|
||
set_server_away(i, args, silent);
|
||
}
|
||
else
|
||
{
|
||
if (args && *args)
|
||
set_server_away(from_server, args, silent);
|
||
else
|
||
back(command, args, NULL, NULL);
|
||
}
|
||
update_all_status(current_window, NULL, 0);
|
||
}
|
||
|
||
#if 0
|
||
#ifndef RAND_MAX
|
||
#define RAND_MAX 213234444
|
||
#endif
|
||
#endif
|
||
|
||
static void real_quit (char *dummy, char *ptr)
|
||
{
|
||
|
||
if (ptr && *ptr)
|
||
{
|
||
if (*ptr == 'Y' || *ptr == 'y')
|
||
{
|
||
irc_exit(1, dummy, "%s", convert_output_format(fget_string_var(FORMAT_SIGNOFF_FSET), "%s %s %s %s", update_clock(GET_TIME), get_server_nickname(get_window_server(0)), m_sprintf("%s@%s", username, hostname), dummy));
|
||
}
|
||
}
|
||
bitchsay("Excelllaaant!!");
|
||
}
|
||
|
||
/* e_quit: The /QUIT, /EXIT, etc command */
|
||
BUILT_IN_COMMAND(e_quit)
|
||
{
|
||
int old_server = from_server;
|
||
char Reason[BIG_BUFFER_SIZE];
|
||
int active_dcc = 0;
|
||
|
||
|
||
if (args && *args)
|
||
strcpy(Reason, args);
|
||
else
|
||
strcpy(Reason, get_signoffreason(get_server_nickname(from_server)));
|
||
if (!*Reason)
|
||
strcpy(Reason, irc_version);
|
||
|
||
active_dcc = get_active_count();
|
||
if (active_dcc)
|
||
add_wait_prompt("Active DCC\'s. Really Quit [y/N] ? ", real_quit, Reason, WAIT_PROMPT_LINE, 1);
|
||
else
|
||
{
|
||
from_server = old_server;
|
||
irc_exit(1, Reason, "%s", convert_output_format(fget_string_var(FORMAT_SIGNOFF_FSET), "%s %s %s %s", update_clock(GET_TIME), get_server_nickname(get_window_server(0)), m_sprintf("%s@%s", username, hostname), Reason));
|
||
}
|
||
}
|
||
|
||
/* flush: flushes all pending stuff coming from the server */
|
||
BUILT_IN_COMMAND(flush)
|
||
{
|
||
|
||
if (get_int_var(HOLD_MODE_VAR))
|
||
flush_everything_being_held(NULL);
|
||
bitchsay("Standby, Flushing server output...");
|
||
flush_server();
|
||
bitchsay("Done");
|
||
}
|
||
|
||
/* e_wall: used for WALLOPS */
|
||
BUILT_IN_COMMAND(e_wall)
|
||
{
|
||
if (!args || !*args)
|
||
return;
|
||
|
||
set_display_target(NULL, LOG_WALLOP);
|
||
send_to_server("%s :%s", command, args);
|
||
|
||
/* Only show the message if we are _not_ +w, because if we are the server
|
||
* will echo our WALLOPS back to us. */
|
||
if (!get_server_umode(from_server, 'w'))
|
||
put_it("!! %s", args);
|
||
add_last_type(&last_sent_wall[0], 1, get_server_nickname(from_server), NULL, "*", args);
|
||
reset_display_target();
|
||
}
|
||
|
||
/*
|
||
* e_privmsg: The MSG command, displaying a message on the screen indicating
|
||
* the message was sent. Also, this works for the NOTICE command.
|
||
*/
|
||
BUILT_IN_COMMAND(e_privmsg)
|
||
{
|
||
unsigned stxt_flags = (window_display ? 0 : STXT_QUIET) | STXT_LOG;
|
||
char *nick;
|
||
|
||
if (command && !strcmp(command, "NOTICE"))
|
||
stxt_flags |= STXT_NOTICE;
|
||
|
||
if ((nick = next_arg(args, &args)) != NULL)
|
||
{
|
||
if (!strcmp(nick, "."))
|
||
{
|
||
if (!(nick = get_server_sent_nick(from_server)))
|
||
{
|
||
bitchsay("You have not sent a message to anyone yet");
|
||
return;
|
||
}
|
||
}
|
||
else if (!strcmp(nick, ","))
|
||
{
|
||
if (!(nick = get_server_recv_nick(from_server)))
|
||
{
|
||
bitchsay("You have not received a message from anyone yet");
|
||
return;
|
||
}
|
||
}
|
||
else if (!strcmp(nick, "*") && (!(nick = get_current_channel_by_refnum(0))))
|
||
nick = zero;
|
||
send_text(nick, args, stxt_flags);
|
||
}
|
||
}
|
||
|
||
/*
|
||
* quote: handles the QUOTE command. args are a direct server command which
|
||
* is simply send directly to the server
|
||
*/
|
||
BUILT_IN_COMMAND(quotecmd)
|
||
{
|
||
int old_from_server = from_server;
|
||
int all_servers = 0;
|
||
|
||
if (command && *command == 'X')
|
||
{
|
||
while (args && (*args == '-' || *args == '/'))
|
||
{
|
||
char *flag = next_arg(args, &args);
|
||
if (!my_strnicmp(flag + 1, "S", 1)) /* SERVER */
|
||
{
|
||
int sval = my_atol(next_arg(args, &args));
|
||
if (is_server_open(sval))
|
||
from_server = sval;
|
||
}
|
||
else if (!my_strnicmp(flag+1, "ALL", 3) && args && *args)
|
||
{
|
||
next_arg(args, &args);
|
||
all_servers++;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
if (args && *args)
|
||
{
|
||
char *comm = new_next_arg(args, &args);
|
||
int cnt;
|
||
int loc;
|
||
|
||
upper(comm);
|
||
find_fixed_array_item((void *)rfc1459, sizeof(protocol_command),
|
||
num_protocol_cmds + 1, comm, &cnt, &loc);
|
||
|
||
if (all_servers)
|
||
{
|
||
int i;
|
||
for (i = 0; i < server_list_size(); i++)
|
||
{
|
||
if (is_server_connected(i))
|
||
{
|
||
from_server = i;
|
||
send_to_server("%s %s", comm, args ? args:empty_string);
|
||
rfc1459[loc].bytes += strlen(args);
|
||
rfc1459[loc].count++;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
send_to_server("%s %s", comm, args ? args : empty_string);
|
||
rfc1459[loc].bytes += strlen(comm) + (args? strlen(args) : 0);
|
||
rfc1459[loc].count++;
|
||
}
|
||
}
|
||
|
||
from_server = old_from_server;
|
||
}
|
||
|
||
/*
|
||
* send_comm: the generic command function. Uses the full command name found
|
||
* in 'command', combines it with the 'args', and sends it to the server
|
||
*/
|
||
BUILT_IN_COMMAND(send_comm)
|
||
{
|
||
|
||
if (args && *args)
|
||
send_to_server("%s %s", command, args);
|
||
else
|
||
send_to_server("%s", command);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(do_trace)
|
||
{
|
||
char *flags = NULL, *serv = NULL;
|
||
|
||
set_server_trace_flag(from_server, 0);
|
||
while (args && *args)
|
||
{
|
||
flags = next_arg(args, &args);
|
||
if (flags && *flags=='-')
|
||
{
|
||
switch(toupper(*(flags+1)))
|
||
{
|
||
case 'O':
|
||
set_server_trace_flag(from_server, get_server_trace_flag(from_server) | TRACE_OPER);
|
||
break;
|
||
case 'U':
|
||
set_server_trace_flag(from_server, get_server_trace_flag(from_server) | TRACE_USER);
|
||
break;
|
||
case 'S':
|
||
set_server_trace_flag(from_server, get_server_trace_flag(from_server) | TRACE_SERVER);
|
||
default:
|
||
break;
|
||
}
|
||
continue;
|
||
}
|
||
if (flags && *flags != '-')
|
||
serv = flags;
|
||
else
|
||
serv = next_arg(args, &args);
|
||
}
|
||
if (get_server_trace_flag(from_server) & TRACE_OPER)
|
||
bitchsay("Tracing server %s%sfor Operators", serv?serv:empty_string,serv?space:empty_string);
|
||
if (get_server_trace_flag(from_server) & TRACE_USER)
|
||
bitchsay("Tracing server %s%sfor Users", serv?serv:empty_string,serv?space:empty_string);
|
||
if (get_server_trace_flag(from_server) & TRACE_SERVER)
|
||
bitchsay("Tracing server %s%sfor servers", serv?serv:empty_string,serv?space:empty_string);
|
||
send_to_server("%s%s%s", command, serv?space:empty_string, serv?serv:empty_string);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(do_stats)
|
||
{
|
||
char *flags = NULL, *serv = NULL;
|
||
char *new_flag = empty_string;
|
||
char *str = NULL;
|
||
|
||
set_server_stat_flag(from_server, 0);
|
||
flags = next_arg(args, &args);
|
||
if (flags)
|
||
{
|
||
switch(*flags)
|
||
{
|
||
case 'o':
|
||
set_server_stat_flag(from_server, get_server_stat_flag(from_server) | STATS_OLINE);
|
||
str = "%GType Host Nick";
|
||
break;
|
||
case 'y':
|
||
set_server_stat_flag(from_server, get_server_stat_flag(from_server) | STATS_YLINE);
|
||
str = "%GType Class PingF ConnF MaxLi SendQ";
|
||
break;
|
||
case 'i':
|
||
set_server_stat_flag(from_server, get_server_stat_flag(from_server) | STATS_ILINE);
|
||
str = "%GType Host Host Port Class";
|
||
break;
|
||
case 'h':
|
||
set_server_stat_flag(from_server, get_server_stat_flag(from_server) | STATS_HLINE);
|
||
str = "%GType Server Mask Server Name";
|
||
break;
|
||
case 'l':
|
||
set_server_stat_flag(from_server, get_server_stat_flag(from_server) | STATS_LINK);
|
||
str = "%Glinknick|server sendq smsgs sbytes rmsgs rbytes timeopen";
|
||
break;
|
||
case 'c':
|
||
set_server_stat_flag(from_server, get_server_stat_flag(from_server) | STATS_CLASS);
|
||
str = "%GType Host Host Port Class";
|
||
break;
|
||
case 'u':
|
||
set_server_stat_flag(from_server, get_server_stat_flag(from_server) | STATS_UPTIME);
|
||
break;
|
||
case 'k':
|
||
set_server_stat_flag(from_server, get_server_stat_flag(from_server) | STATS_TKLINE);
|
||
str = "%GType Host UserName Reason";
|
||
break;
|
||
case 'K':
|
||
set_server_stat_flag(from_server, get_server_stat_flag(from_server) | STATS_KLINE);
|
||
str = "%GType Host UserName Reason";
|
||
break;
|
||
case 'm':
|
||
set_server_stat_flag(from_server, get_server_stat_flag(from_server) | STATS_MLINE);
|
||
default:
|
||
break;
|
||
}
|
||
new_flag = flags;
|
||
}
|
||
if (args && *args)
|
||
serv = args;
|
||
else
|
||
serv = get_server_itsname(from_server);
|
||
if (str)
|
||
put_it("%s", convert_output_format(str, NULL, NULL));
|
||
send_to_server("%s %s %s", command, new_flag, serv);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(untopic)
|
||
{
|
||
char *channel = NULL;
|
||
ChannelList *chan;
|
||
int server;
|
||
|
||
args = inv_strpbrk(args, " ");
|
||
|
||
if (is_channel(args))
|
||
channel = next_arg(args, &args);
|
||
|
||
if (!(chan = prepare_command(&server, channel, PC_TOPIC)))
|
||
return;
|
||
|
||
my_send_to_server(server, "TOPIC %s :", chan->channel);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(e_topic)
|
||
{
|
||
char *channel = NULL;
|
||
ChannelList *chan;
|
||
int server;
|
||
|
||
args = inv_strpbrk(args, " ");
|
||
|
||
if (is_channel(args))
|
||
{
|
||
channel = next_arg(args, &args);
|
||
args = inv_strpbrk(args, " ");
|
||
}
|
||
|
||
if (!(chan = prepare_command(&server, channel, args ? PC_TOPIC : NO_OP)))
|
||
return;
|
||
|
||
if (args)
|
||
{
|
||
add_last_type(&last_sent_topic[0], 1, NULL, NULL, chan->channel, args);
|
||
my_send_to_server(server, "TOPIC %s :%s", chan->channel, args);
|
||
}
|
||
else
|
||
my_send_to_server(server, "TOPIC %s", chan->channel);
|
||
}
|
||
|
||
/* MTOPIC by singe_ stolen from an idea by MHacker
|
||
* the code is basically from below with a few mods,
|
||
* and some added bloatcode(tm). Further modified by panasync
|
||
*/
|
||
BUILT_IN_COMMAND(do_mtopic)
|
||
{
|
||
ChannelList *chan;
|
||
|
||
if (from_server != -1)
|
||
{
|
||
int count = 0;
|
||
for (chan = get_server_channels(from_server); chan; chan = chan->next)
|
||
{
|
||
if (!chan->have_op)
|
||
continue;
|
||
send_to_server("TOPIC %s :%s", chan->channel, args ? args : empty_string);
|
||
count++;
|
||
}
|
||
if (!count)
|
||
bitchsay("You're not an op on any channels");
|
||
} else
|
||
bitchsay("No server for this window");
|
||
}
|
||
|
||
BUILT_IN_COMMAND(send_2comm)
|
||
{
|
||
char *reason = NULL;
|
||
|
||
|
||
#ifdef CDE
|
||
args = next_arg(args, &reason);
|
||
if (!args)
|
||
args = empty_string;
|
||
#endif
|
||
if (!(args = next_arg(args, &reason)))
|
||
args = empty_string;
|
||
if (!reason || !*reason)
|
||
reason = empty_string;
|
||
|
||
if (!args || !*args || !strcmp(args, "*"))
|
||
{
|
||
args = get_current_channel_by_refnum(0);
|
||
if (!args || !*args)
|
||
args = "*"; /* what-EVER */
|
||
}
|
||
if (reason && *reason)
|
||
send_to_server("%s %s :%s", command, args, reason);
|
||
else
|
||
send_to_server("%s %s", command, args);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(send_kill)
|
||
{
|
||
char *target;
|
||
|
||
target = next_arg(args, &args);
|
||
|
||
if (!strcmp(target, "*"))
|
||
{
|
||
ChannelList *chan = lookup_channel("*", from_server, 0);
|
||
NickList *n = NULL;
|
||
|
||
if (!chan)
|
||
return;
|
||
for (n = next_nicklist(chan, NULL); n; n = next_nicklist(chan, n))
|
||
{
|
||
if (isme(n->nick))
|
||
continue;
|
||
|
||
if (args && *args)
|
||
send_to_server("%s %s :%s", command, n->nick, args);
|
||
else
|
||
send_to_server("%s %s :%s", command, n->nick,
|
||
get_kill_reason(n->nick, get_server_nickname(from_server)));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
const char *nick;
|
||
while ((nick = next_in_comma_list(target, &target)) && *nick)
|
||
{
|
||
if (args && *args)
|
||
send_to_server("%s %s :%s", command, nick, args);
|
||
else
|
||
send_to_server("%s %s :%s", command, nick,
|
||
get_kill_reason(nick, get_server_nickname(from_server)));
|
||
}
|
||
}
|
||
}
|
||
|
||
/*
|
||
* send_kick: sends a kick message to the server. Works properly with
|
||
* kick comments.
|
||
*/
|
||
|
||
BUILT_IN_COMMAND(send_kick)
|
||
{
|
||
const char *kickee, *comment;
|
||
char *channel;
|
||
ChannelList *chan;
|
||
int server = from_server;
|
||
|
||
if (!(channel = next_arg(args, &args)))
|
||
return;
|
||
|
||
if (!(kickee = next_arg(args, &args)))
|
||
return;
|
||
|
||
reset_display_target();
|
||
if (!(chan = prepare_command(&server, !strcmp(channel, "*") ? NULL : channel, NEED_OP)))
|
||
return;
|
||
|
||
comment = args ? args : get_kick_reason(kickee, get_server_nickname(server));
|
||
my_send_to_server(server, "%s %s %s :%s", command, chan->channel, kickee, comment);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(send_mode)
|
||
{
|
||
char *channel;
|
||
|
||
if ((channel = get_current_channel_by_refnum(0)))
|
||
send_to_server("%s %s %s", command, channel, args? args: empty_string);
|
||
else if (args && *args)
|
||
send_to_server("%s %s", command, args);
|
||
}
|
||
|
||
/*
|
||
* send_channel_com: does the same as send_com for command where the first
|
||
* argument is a channel name. If the first argument is *, it is expanded
|
||
* to the current channel (a la /WHO).
|
||
*/
|
||
BUILT_IN_COMMAND(send_channel_com)
|
||
{
|
||
char *ptr,
|
||
*s;
|
||
|
||
ptr = next_arg(args, &args);
|
||
|
||
if (ptr && !strcmp(ptr, "*"))
|
||
{
|
||
if ((s = get_current_channel_by_refnum(0)) != NULL)
|
||
send_to_server("%s %s %s", command, s, args?args:empty_string);
|
||
else
|
||
say("%s * is not valid since you are not on a channel", command);
|
||
}
|
||
else if (ptr)
|
||
send_to_server("%s %s %s", command, ptr, args?args:empty_string);
|
||
}
|
||
|
||
/*
|
||
* Returns 1 if the given built in command exists,
|
||
* Returns 0 if not.
|
||
*/
|
||
int command_exist (char *command)
|
||
{
|
||
int num;
|
||
char buf[BIG_BUFFER_SIZE];
|
||
|
||
if (!command || !*command)
|
||
return 0;
|
||
|
||
strcpy(buf, command);
|
||
upper(buf);
|
||
|
||
if (find_command(buf, &num))
|
||
return (num < 0) ? 1 : 0;
|
||
|
||
return 0;
|
||
}
|
||
|
||
void redirect_text(int to_server, const char *nick_list, const char *text, unsigned flags)
|
||
{
|
||
static int recursion = 0;
|
||
int old_from_server = from_server;
|
||
int allow = 0;
|
||
|
||
from_server = to_server;
|
||
if (recursion++ == 0)
|
||
allow = do_hook(REDIRECT_LIST, "%s %s", nick_list, text);
|
||
|
||
/*
|
||
* Don't hook /ON REDIRECT if we're being called recursively
|
||
*/
|
||
if (allow)
|
||
send_text(nick_list, text, flags);
|
||
|
||
recursion--;
|
||
from_server = old_from_server;
|
||
}
|
||
|
||
static int try_send_special_target(char *target, const char *text, unsigned stxt_flags)
|
||
{
|
||
/*
|
||
* It is legal to send an empty line to a process, but not legal
|
||
* to send an empty line anywhere else.
|
||
*/
|
||
switch (*target)
|
||
{
|
||
case '%':
|
||
{
|
||
int process_idx = get_process_index(&target);
|
||
|
||
if (process_idx == -1)
|
||
say("Invalid process specification");
|
||
else
|
||
text_to_process(process_idx, text, 1);
|
||
}
|
||
break;
|
||
|
||
#ifdef WANT_FTP
|
||
case '-':
|
||
if (text && *text)
|
||
dcc_ftpcommand(target + 1, (char *)text);
|
||
break;
|
||
#endif
|
||
|
||
case '"':
|
||
if (text && *text)
|
||
send_to_server("%s", text);
|
||
break;
|
||
|
||
case '/':
|
||
if (text && *text)
|
||
{
|
||
char *line = m_opendup(target, space, text, NULL);
|
||
parse_command(line, 0, empty_string);
|
||
new_free(&line);
|
||
}
|
||
break;
|
||
|
||
case '=':
|
||
if (text && *text)
|
||
{
|
||
const char *key;
|
||
int old_server;
|
||
char *line;
|
||
|
||
if (!is_number(target + 1) &&
|
||
!dcc_activechat(target + 1) &&
|
||
!dcc_activebot(target+1) &&
|
||
!dcc_activeraw(target+1))
|
||
{
|
||
yell("No DCC CHAT connection open to %s", target + 1);
|
||
break;
|
||
}
|
||
if ((key = is_crypted(target)))
|
||
line = sed_encrypt_msg(text, key);
|
||
else
|
||
line = m_strdup(text);
|
||
|
||
old_server = from_server;
|
||
from_server = -1;
|
||
if (dcc_activechat(target+1))
|
||
{
|
||
dcc_chat_transmit(target + 1, line, line, stxt_flags);
|
||
if (!(stxt_flags & STXT_QUIET))
|
||
addtabkey(target, "msg", 0);
|
||
}
|
||
else if (dcc_activebot(target + 1))
|
||
dcc_bot_transmit(target + 1, line, stxt_flags);
|
||
else
|
||
dcc_raw_transmit(target + 1, line, stxt_flags);
|
||
|
||
add_last_type(&last_sent_dcc[0], MAX_LAST_MSG, NULL, NULL, target+1, text);
|
||
from_server = old_server;
|
||
new_free(&line);
|
||
}
|
||
break;
|
||
|
||
default:
|
||
return 0;
|
||
}
|
||
|
||
return 1;
|
||
}
|
||
|
||
struct target_type
|
||
{
|
||
char *nick_list;
|
||
int hook_type;
|
||
char *command;
|
||
unsigned long level;
|
||
const char *output;
|
||
const char *other_output;
|
||
const char *format_encrypted;
|
||
};
|
||
|
||
int current_target = 0;
|
||
|
||
/*
|
||
* The whole shebang.
|
||
*
|
||
* The message targets are parsed and collected into one of 4 buckets.
|
||
* This is not too dissimilar to what was done before, except now i
|
||
* feel more comfortable about how the code works.
|
||
*
|
||
* Bucket 0 -- Unencrypted PRIVMSGs to nicknames
|
||
* Bucket 1 -- Unencrypted PRIVMSGs to channels
|
||
* Bucket 2 -- Unencrypted NOTICEs to nicknames
|
||
* Bucket 3 -- Unencrypted NOTICEs to channels
|
||
*
|
||
* All other messages (encrypted, and DCC CHATs) are dispatched
|
||
* immediately, and separately from all others. All messages that
|
||
* end up in one of the above mentioned buckets get sent out all
|
||
* at once.
|
||
*/
|
||
void BX_send_text(const char *nick_list, const char *text, unsigned flags)
|
||
{
|
||
static int sent_text_recursion = 0;
|
||
|
||
int i,
|
||
done_forward = 0,
|
||
is_current = 0,
|
||
old_window_display = window_display;
|
||
char *current_nick,
|
||
*next_nick,
|
||
*free_nick,
|
||
*line;
|
||
|
||
struct target_type target[4] =
|
||
{
|
||
{NULL, SEND_MSG_LIST, "PRIVMSG", LOG_MSG, NULL, NULL },
|
||
{NULL, SEND_PUBLIC_LIST, "PRIVMSG", LOG_PUBLIC, NULL, NULL },
|
||
{NULL, SEND_NOTICE_LIST, "NOTICE", LOG_NOTICE, NULL, NULL },
|
||
{NULL, SEND_NOTICE_LIST, "NOTICE", LOG_NOTICE, NULL, NULL }
|
||
};
|
||
|
||
target[0].output = fget_string_var(FORMAT_SEND_MSG_FSET);
|
||
target[0].format_encrypted = fget_string_var(FORMAT_SEND_ENCRYPTED_MSG_FSET);
|
||
target[1].output = fget_string_var(FORMAT_SEND_PUBLIC_FSET);
|
||
target[1].other_output = fget_string_var(FORMAT_SEND_PUBLIC_OTHER_FSET);
|
||
target[1].format_encrypted = fget_string_var(FORMAT_SEND_ENCRYPTED_PUBLIC_FSET);
|
||
target[2].output = fget_string_var(FORMAT_SEND_NOTICE_FSET);
|
||
target[2].format_encrypted = fget_string_var(FORMAT_SEND_ENCRYPTED_NOTICE_FSET);
|
||
target[3].output = fget_string_var(FORMAT_SEND_NOTICE_FSET);
|
||
target[3].other_output = fget_string_var(FORMAT_SEND_NOTICE_FSET);
|
||
target[3].format_encrypted = fget_string_var(FORMAT_SEND_ENCRYPTED_NOTICE_FSET);
|
||
|
||
if (sent_text_recursion)
|
||
flags |= STXT_QUIET;
|
||
sent_text_recursion++;
|
||
|
||
window_display = !(flags & STXT_QUIET);
|
||
|
||
free_nick = next_nick = m_strdup(nick_list);
|
||
|
||
while ((current_nick = next_nick))
|
||
{
|
||
const char *key;
|
||
|
||
if ((next_nick = strchr(current_nick, ',')))
|
||
*next_nick++ = 0;
|
||
|
||
if (!*current_nick)
|
||
continue;
|
||
|
||
if (try_send_special_target(current_nick, text, flags))
|
||
continue;
|
||
|
||
/*
|
||
* This test has to be here because it is legal to
|
||
* send an empty line to a process, but not legal
|
||
* to send an empty line anywhere else.
|
||
*/
|
||
if (!text || !*text)
|
||
continue;
|
||
|
||
if (doing_notice)
|
||
{
|
||
say("You cannot send a message from within ON NOTICE");
|
||
continue;
|
||
}
|
||
|
||
if (!(i = is_channel(current_nick)) && !(flags & STXT_QUIET))
|
||
addtabkey(current_nick, "msg", 0);
|
||
|
||
if (flags & STXT_NOTICE)
|
||
i += 2;
|
||
|
||
if ((key = is_crypted(current_nick)))
|
||
{
|
||
set_display_target(current_nick, target[i].level);
|
||
|
||
line = sed_encrypt_msg(text, key);
|
||
if (!(flags & STXT_QUIET) && do_hook(target[i].hook_type, "%s %s", current_nick, text))
|
||
put_it("%s", convert_output_format(target[i].format_encrypted,
|
||
"%s %s %s %s", update_clock(GET_TIME), current_nick, get_server_nickname(from_server), text));
|
||
|
||
send_to_server("%s %s :%s", target[i].command, current_nick, line);
|
||
new_free(&line);
|
||
reset_display_target();
|
||
}
|
||
else
|
||
{
|
||
if (target[i].nick_list)
|
||
malloc_strcat(&target[i].nick_list, ",");
|
||
malloc_strcat(&target[i].nick_list, current_nick);
|
||
}
|
||
}
|
||
|
||
for (i = 0; i < 4; i++)
|
||
{
|
||
char *s = NULL;
|
||
ChannelList *chan = NULL;
|
||
const char *old_mf;
|
||
unsigned long old_ml;
|
||
int blah_hook = 0;
|
||
|
||
if (!target[i].nick_list)
|
||
continue;
|
||
|
||
save_display_target(&old_mf, &old_ml);
|
||
set_display_target(target[i].nick_list, target[i].level);
|
||
|
||
/* do we forward this?*/
|
||
|
||
if (forwardnick && !done_forward)
|
||
{
|
||
send_to_server("NOTICE %s :-> *%s* %s", forwardnick, nick_list, text);
|
||
done_forward = 1;
|
||
}
|
||
|
||
/* log it if logging on */
|
||
if (flags & STXT_LOG)
|
||
logmsg(LOG_SEND_MSG, target[i].nick_list, 0, "%s", text);
|
||
/* save this for /oops */
|
||
|
||
if (i == 1 || i == 3)
|
||
{
|
||
char *channel;
|
||
is_current = is_current_channel(target[i].nick_list, from_server, 0);
|
||
if ((channel = get_current_channel_by_refnum(0)))
|
||
{
|
||
NickList *nick = NULL;
|
||
if ((chan = lookup_channel(channel, from_server, 0)))
|
||
{
|
||
nick = find_nicklist_in_channellist(get_server_nickname(from_server), chan, 0);
|
||
update_stats((i == 1) ?PUBLIC_LIST : NOTICE_LIST, nick, chan, 0);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
is_current = 1;
|
||
|
||
if (!(flags & STXT_QUIET) && (blah_hook = do_hook(target[i].hook_type, "%s %s", target[i].nick_list, text)))
|
||
;
|
||
/* supposedly if this is called before the do_hook
|
||
* it can cause a problem with scripts.
|
||
*/
|
||
|
||
if (blah_hook || chan)
|
||
s = convert_output_format(is_current ? target[i].output : target[i].other_output,
|
||
"%s %s %s %s",update_clock(GET_TIME), target[i].nick_list, get_server_nickname(from_server), text);
|
||
if (blah_hook)
|
||
put_it("%s", s);
|
||
|
||
if (chan)
|
||
add_to_log(chan->msglog_fp, now, s, logfile_line_mangler);
|
||
|
||
if ((i == 0))
|
||
{
|
||
set_server_sent_nick(from_server, target[0].nick_list);
|
||
set_server_sent_body(from_server, text);
|
||
add_last_type(&last_sent_msg[0], MAX_LAST_MSG, NULL, NULL, target[i].nick_list, text);
|
||
}
|
||
else if ((i == 2) || (i == 3))
|
||
add_last_type(&last_sent_notice[0], MAX_LAST_MSG, get_server_nickname(from_server), NULL, target[i].nick_list, text);
|
||
|
||
send_to_server("%s %s :%s", target[i].command, target[i].nick_list, text);
|
||
new_free(&target[i].nick_list);
|
||
restore_display_target(old_mf, old_ml);
|
||
}
|
||
|
||
if (!(flags & STXT_QUIET) && get_server_away(from_server) && get_int_var(AUTO_UNMARK_AWAY_VAR))
|
||
parse_line(NULL, "AWAY", empty_string, 0, 0, 1);
|
||
|
||
new_free(&free_nick);
|
||
window_display = old_window_display;
|
||
sent_text_recursion--;
|
||
}
|
||
|
||
BUILT_IN_COMMAND(do_send_text)
|
||
{
|
||
char *tmp;
|
||
char *text = args;
|
||
char *cmd = NULL;
|
||
|
||
if (command)
|
||
tmp = get_current_channel_by_refnum(0);
|
||
else
|
||
{
|
||
tmp = get_target_by_refnum(0);
|
||
cmd = get_target_cmd_by_refnum(0);
|
||
}
|
||
if (cmd)
|
||
{
|
||
#ifdef WANT_DLL
|
||
int dllcnt = -1;
|
||
IrcCommandDll *dll = NULL;
|
||
dll = find_dll_command(cmd, &dllcnt);
|
||
if (dll && (dllcnt == -1 || dllcnt == 1))
|
||
dll->func (dll_commands, dll->server_func, text, NULL, dll->help);
|
||
else
|
||
#endif
|
||
if (!my_stricmp(cmd, "SAY") || !my_stricmp(cmd, "PRIVMSG") || !my_stricmp(cmd, "MSG"))
|
||
send_text(tmp, text, STXT_LOG);
|
||
else if (!my_stricmp(cmd, "NOTICE"))
|
||
send_text(tmp, text, STXT_NOTICE | STXT_LOG);
|
||
else if (!my_strnicmp(cmd, "WALLO", 5))
|
||
e_wall("WALLOPS", text, NULL, NULL);
|
||
else if (!my_strnicmp(cmd, "SWALLO", 6))
|
||
e_wall("SWALLOPS", text, NULL, NULL);
|
||
else if(!my_strnicmp(cmd, "WALLC", 5))
|
||
ChanWallOp(NULL, text, NULL, NULL);
|
||
#ifndef BITCHX_LITE
|
||
else if (!my_stricmp(cmd, "CSAY"))
|
||
csay(NULL, text, NULL, NULL);
|
||
else if (!my_stricmp(cmd, "CMSG"))
|
||
cmsg(NULL, text, NULL, NULL);
|
||
#endif
|
||
else
|
||
send_text(tmp, text, STXT_LOG);
|
||
}
|
||
else
|
||
send_text(tmp, text, STXT_LOG);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(do_msay)
|
||
{
|
||
char *channels = NULL;
|
||
int i = get_window_server(0);
|
||
ChannelList *chan;
|
||
|
||
if (i != -1)
|
||
{
|
||
int old_from_server = from_server;
|
||
for (chan = get_server_channels(i); chan; chan = chan->next)
|
||
{
|
||
malloc_strcat(&channels, chan->channel);
|
||
if (chan->next)
|
||
malloc_strcat(&channels, ",");
|
||
}
|
||
from_server = i;
|
||
if (channels)
|
||
send_text(channels, args, STXT_LOG);
|
||
new_free(&channels);
|
||
from_server = old_from_server;
|
||
} else
|
||
bitchsay("No server for this window");
|
||
}
|
||
|
||
/*
|
||
* command_completion: builds lists of commands and aliases that match the
|
||
* given command and displays them for the user's lookseeing
|
||
*/
|
||
char **get_builtins (char *, int *);
|
||
void command_completion(char unused, char *not_used)
|
||
{
|
||
int do_aliases = 1,
|
||
do_functions = 1;
|
||
int cmd_cnt = 0,
|
||
alias_cnt = 0,
|
||
dll_cnt = 0,
|
||
function_cnt = 0,
|
||
i,
|
||
c;
|
||
char **aliases = NULL;
|
||
char **functions = NULL;
|
||
|
||
char *line = NULL,
|
||
*com,
|
||
*rest,
|
||
firstcmdchar[2] = "/";
|
||
const char *cmdchars = get_string_var(CMDCHARS_VAR);
|
||
const IrcCommand *command;
|
||
#ifdef WANT_DLL
|
||
IrcCommandDll *dll = NULL;
|
||
#endif
|
||
char buffer[BIG_BUFFER_SIZE];
|
||
|
||
malloc_strcpy(&line, get_input());
|
||
if ((com = next_arg(line, &rest)) != NULL)
|
||
{
|
||
if (*com == '/' || strchr(cmdchars, *com))
|
||
{
|
||
*firstcmdchar = *cmdchars;
|
||
com++;
|
||
if (*com && strchr(cmdchars, *com))
|
||
{
|
||
do_aliases = 0;
|
||
do_functions = 0;
|
||
alias_cnt = 0;
|
||
function_cnt = 0;
|
||
com++;
|
||
}
|
||
else if (*com && strchr("$", *com))
|
||
{
|
||
do_aliases = 0;
|
||
alias_cnt = 0;
|
||
do_functions = 1;
|
||
com++;
|
||
} else
|
||
do_aliases = do_functions = 1;
|
||
|
||
upper(com);
|
||
if (do_aliases)
|
||
aliases = glob_cmd_alias(com, &alias_cnt);
|
||
|
||
if (do_functions)
|
||
functions = get_builtins(com, &function_cnt);
|
||
|
||
if ((command = find_command(com, &cmd_cnt)) != NULL)
|
||
{
|
||
if (cmd_cnt < 0)
|
||
cmd_cnt *= -1;
|
||
/* special case for the empty string */
|
||
if (!*command->name)
|
||
{
|
||
command++;
|
||
cmd_cnt = NUMBER_OF_COMMANDS;
|
||
}
|
||
}
|
||
#ifdef WANT_DLL
|
||
if ((dll = find_dll_command(com, &dll_cnt)) != NULL)
|
||
{
|
||
if (dll_cnt < 0)
|
||
dll_cnt *= -1;
|
||
}
|
||
#endif
|
||
if ((alias_cnt == 1) && (cmd_cnt == 0) && (dll_cnt <= 0))
|
||
{
|
||
snprintf(buffer, sizeof buffer, "%s%s %s", firstcmdchar, *aliases, rest);
|
||
set_input(buffer);
|
||
new_free((char **)aliases);
|
||
new_free((char **)&aliases);
|
||
update_input(UPDATE_ALL);
|
||
}
|
||
else if (((cmd_cnt == 1) && (dll_cnt <= 0) && (alias_cnt == 0)) ||
|
||
((cmd_cnt == 0) && (dll_cnt == 1) && (alias_cnt == 0)) ||
|
||
(((cmd_cnt == 1) && (alias_cnt == 1) &&
|
||
!strcmp(aliases[0], command[0].name))
|
||
#ifdef WANT_DLL
|
||
|| ((dll_cnt == 1) && (alias_cnt == 1) && !strcmp(dll->name, aliases[0]))
|
||
#endif
|
||
))
|
||
{
|
||
snprintf(buffer, sizeof buffer, "%s%s%s %s",
|
||
firstcmdchar,
|
||
do_aliases ? empty_string : firstcmdchar,
|
||
#ifdef WANT_DLL
|
||
cmd_cnt ? command[0].name : dll->name,
|
||
#else
|
||
command[0].name,
|
||
#endif
|
||
rest);
|
||
set_input(buffer);
|
||
update_input(UPDATE_ALL);
|
||
}
|
||
else
|
||
{
|
||
*buffer = 0;
|
||
if (command)
|
||
{
|
||
*buffer = 0;
|
||
c = 0;
|
||
for (i = 0; i < cmd_cnt; i++)
|
||
{
|
||
if (i == 0)
|
||
bitchsay("Commands:");
|
||
strlcat(buffer, command[i].name, sizeof buffer);
|
||
strlcat(buffer, space, sizeof buffer);
|
||
if (++c == 4)
|
||
{
|
||
put_it("%s", convert_output_format("$G $[15]0 $[15]1 $[15]2 $[15]3", "%s", buffer));
|
||
*buffer = 0;
|
||
c = 0;
|
||
}
|
||
}
|
||
if (c)
|
||
put_it("%s", convert_output_format("$G $[15]0 $[15]1 $[15]2 $[15]3", "%s", buffer));
|
||
#ifdef WANT_DLL
|
||
if (dll_commands)
|
||
bitchsay("Plugin Commands:");
|
||
*buffer = 0;
|
||
c = 0;
|
||
for (dll = dll_commands; dll; dll = dll->next)
|
||
{
|
||
if (com && *com && my_strnicmp(com, dll->name, strlen(com)))
|
||
continue;
|
||
strlcat(buffer, dll->name, sizeof buffer);
|
||
strlcat(buffer, space, sizeof buffer);
|
||
if (++c == 4)
|
||
{
|
||
put_it("%s", convert_output_format("$G $[15]0 $[15]1 $[15]2 $[15]3", "%s", buffer));
|
||
*buffer = 0;
|
||
c = 0;
|
||
}
|
||
}
|
||
if (c)
|
||
put_it("%s", convert_output_format("$G $[15]0 $[15]1 $[15]2 $[15]3", "%s", buffer));
|
||
#endif
|
||
}
|
||
if (aliases)
|
||
{
|
||
*buffer = 0;
|
||
c = 0;
|
||
for (i = 0; i < alias_cnt; i++)
|
||
{
|
||
if (i == 0)
|
||
bitchsay("Aliases:");
|
||
strlcat(buffer, aliases[i], sizeof buffer);
|
||
strlcat(buffer, space, sizeof buffer);
|
||
if (++c == 4)
|
||
{
|
||
put_it("%s", convert_output_format("$G $[15]0 $[15]1 $[15]2 $[15]3", "%s", buffer));
|
||
*buffer = 0;
|
||
c = 0;
|
||
}
|
||
new_free(&(aliases[i]));
|
||
}
|
||
if (strlen(buffer) > 1)
|
||
put_it("%s", convert_output_format("$G $[15]0 $[15]1 $[15]2 $[15]3", "%s", buffer));
|
||
new_free((char **)&aliases);
|
||
}
|
||
if (functions)
|
||
{
|
||
*buffer = 0;
|
||
c = 0;
|
||
for (i = 0; i < function_cnt; i++)
|
||
{
|
||
if (i == 0)
|
||
bitchsay("Functions:");
|
||
strlcat(buffer, functions[i], sizeof buffer);
|
||
strlcat(buffer, space, sizeof buffer);
|
||
if (++c == 4)
|
||
{
|
||
put_it("%s", convert_output_format("$G $[15]0 $[15]1 $[15]2 $[15]3", "%s", buffer));
|
||
*buffer = 0;
|
||
c = 0;
|
||
}
|
||
new_free(&(functions[i]));
|
||
}
|
||
if (strlen(buffer) > 1)
|
||
put_it("%s", convert_output_format("$G $[15]0 $[15]1 $[15]2 $[15]3", "%s", buffer));
|
||
new_free((char **)&functions);
|
||
}
|
||
if (!*buffer)
|
||
term_beep();
|
||
}
|
||
}
|
||
else
|
||
term_beep();
|
||
}
|
||
else
|
||
term_beep();
|
||
new_free(&line);
|
||
}
|
||
|
||
|
||
BUILT_IN_COMMAND(e_call)
|
||
{
|
||
dump_call_stack();
|
||
}
|
||
|
||
static int oper_issued = 0;
|
||
|
||
/* parse_line: This is the main parsing routine. It should be called in
|
||
* almost all circumstances over parse_command().
|
||
*
|
||
* parse_line breaks up the line into commands separated by unescaped
|
||
* semicolons if we are in non interactive mode. Otherwise it tries to leave
|
||
* the line untouched.
|
||
*
|
||
* Currently, a carriage return or newline breaks the line into multiple
|
||
* commands too. This is expected to stop at some point when parse_command
|
||
* will check for such things and escape them using the ^P convention.
|
||
* We'll also try to check before we get to this stage and escape them before
|
||
* they become a problem.
|
||
*
|
||
* Other than these two conventions the line is left basically untouched.
|
||
*/
|
||
/* Ideas on parsing: Why should the calling function be responsible
|
||
* for removing {} blocks? Why can't this parser cope with and {}s
|
||
* that come up?
|
||
*/
|
||
void BX_parse_line (const char *name, char *org_line, const char *args, int hist_flag, int append_flag, int handle_local)
|
||
{
|
||
char *line = NULL,
|
||
*stuff,
|
||
*s;
|
||
int args_flag = 0,
|
||
die = 0;
|
||
|
||
if (handle_local)
|
||
make_local_stack((char *)name);
|
||
|
||
line = LOCAL_COPY(org_line);
|
||
|
||
if (!*org_line)
|
||
do_send_text(NULL, empty_string, empty_string, NULL);
|
||
else if (args) do
|
||
{
|
||
while (*line == '{')
|
||
{
|
||
if (!(stuff = next_expr(&line, '{')))
|
||
{
|
||
error("Unmatched {");
|
||
destroy_local_stack();
|
||
return;
|
||
}
|
||
if (((internal_debug & DEBUG_CMDALIAS) || (internal_debug & DEBUG_HOOK)) && alias_debug && !in_debug_yell)
|
||
debugyell("%3d %s", debug_count++, stuff);
|
||
parse_line(name, stuff, args, hist_flag, append_flag, handle_local);
|
||
|
||
if ((will_catch_break_exceptions && break_exception) ||
|
||
(will_catch_return_exceptions && return_exception) ||
|
||
(will_catch_continue_exceptions && continue_exception))
|
||
{
|
||
die = 1;
|
||
break;
|
||
}
|
||
|
||
while (*line == ';' || my_isspace(*line))
|
||
*line++ = '\0';
|
||
}
|
||
|
||
if (!*line || die)
|
||
break;
|
||
|
||
stuff = expand_alias(line, args, &args_flag, &line);
|
||
if (!line && append_flag && !args_flag && args && *args)
|
||
m_3cat(&stuff, space, args);
|
||
|
||
if (((internal_debug & DEBUG_CMDALIAS) || (internal_debug & DEBUG_HOOK)) && alias_debug && !in_debug_yell)
|
||
debugyell("%3d %s", debug_count++, stuff);
|
||
|
||
parse_command(stuff, hist_flag, (char *)args);
|
||
new_free(&stuff);
|
||
|
||
if ((will_catch_break_exceptions && break_exception) ||
|
||
(will_catch_return_exceptions && return_exception) ||
|
||
(will_catch_continue_exceptions && continue_exception))
|
||
break;
|
||
} while (line && *line);
|
||
else
|
||
{
|
||
if (load_depth != -1) /* CDE should this be != 1 or > 0 */
|
||
parse_command(line, hist_flag, (char *)args);
|
||
else
|
||
{
|
||
while ((s = line))
|
||
{
|
||
line = strpbrk(line, "\r\n");
|
||
if (line)
|
||
*line++ = '\0';
|
||
|
||
parse_command(s, hist_flag, (char *)args);
|
||
|
||
if ((will_catch_break_exceptions && break_exception) ||
|
||
(will_catch_return_exceptions && return_exception) ||
|
||
(will_catch_continue_exceptions && continue_exception))
|
||
break;
|
||
|
||
}
|
||
}
|
||
debug_count = 1;
|
||
}
|
||
if (oper_issued)
|
||
{
|
||
memset(org_line, 0, strlen(org_line));
|
||
oper_issued = 0;
|
||
}
|
||
if (handle_local)
|
||
destroy_local_stack();
|
||
return;
|
||
}
|
||
|
||
|
||
/*
|
||
* parse_command: parses a line of input from the user. If the first
|
||
* character of the line is equal to irc_variable[CMDCHAR_VAR].value, the
|
||
* line is used as an irc command and parsed appropriately. If the first
|
||
* character is anything else, the line is sent to the current channel or to
|
||
* the current query user. If hist_flag is true, commands will be added to
|
||
* the command history as appropriate. Otherwise, parsed commands will not
|
||
* be added.
|
||
*
|
||
* Parse_command() only parses a single command. In general, you will want
|
||
* to use parse_line() to execute things.Parse command recognized no quoted
|
||
* characters or anything (beyond those specific for a given command being
|
||
* executed).
|
||
*/
|
||
int BX_parse_command(char *line, int hist_flag, char *sub_args)
|
||
{
|
||
static unsigned int level = 0;
|
||
unsigned int display,
|
||
old_display_var;
|
||
const char *cmdchars = get_string_var(CMDCHARS_VAR);
|
||
const char *com;
|
||
char *this_cmd = NULL;
|
||
int args_flag = 0,
|
||
add_to_hist,
|
||
cmdchar_used = 0;
|
||
int noisy = 1;
|
||
|
||
int old_alias_debug = alias_debug;
|
||
|
||
if (!line || !*line)
|
||
return 0;
|
||
|
||
if (internal_debug & DEBUG_COMMANDS && !in_debug_yell)
|
||
debugyell("Executing [%d] %s", level, line);
|
||
level++;
|
||
|
||
this_cmd = LOCAL_COPY(line);
|
||
set_current_command(this_cmd);
|
||
add_to_hist = 1;
|
||
display = window_display;
|
||
old_display_var = (unsigned) get_int_var(DISPLAY_VAR);
|
||
for ( ;*line;line++)
|
||
{
|
||
if (*line == '^' && (!hist_flag || cmdchar_used))
|
||
{
|
||
if (!noisy)
|
||
break;
|
||
noisy = 0;
|
||
}
|
||
else if ((!hist_flag && *line == '/') || strchr(cmdchars, *line))
|
||
{
|
||
cmdchar_used++;
|
||
if (cmdchar_used > 2)
|
||
break;
|
||
}
|
||
else
|
||
break;
|
||
}
|
||
|
||
if (!noisy)
|
||
window_display = 0;
|
||
com = line;
|
||
|
||
/*
|
||
* always consider input a command unless we are in interactive mode
|
||
* and command_mode is off. -lynx
|
||
*/
|
||
if (hist_flag && !cmdchar_used && !get_int_var(COMMAND_MODE_VAR))
|
||
{
|
||
do_send_text(NULL, line, empty_string, NULL);
|
||
if (hist_flag && add_to_hist)
|
||
add_to_history(this_cmd);
|
||
/* Special handling for ' and : */
|
||
}
|
||
else if (*com == '\'' && get_int_var(COMMAND_MODE_VAR))
|
||
{
|
||
do_send_text(NULL, line+1, empty_string, NULL);
|
||
if (hist_flag && add_to_hist)
|
||
add_to_history(this_cmd);
|
||
}
|
||
else if ((*com == '@') || (*com == '('))
|
||
{
|
||
/* This kludge fixes a memory leak */
|
||
char *tmp;
|
||
char *my_line = LOCAL_COPY(line);
|
||
char *l_ptr;
|
||
/*
|
||
* This new "feature" masks a weakness in the underlying
|
||
* grammar that allowed variable names to begin with an
|
||
* lparen, which inhibited the expansion of $s inside its
|
||
* name, which caused icky messes with array subscripts.
|
||
*
|
||
* Anyhow, we now define any commands that start with an
|
||
* lparen as being "expressions", same as @ lines.
|
||
*/
|
||
if (*com == '(')
|
||
{
|
||
if ((l_ptr = MatchingBracket(my_line + 1, '(', ')')))
|
||
*l_ptr++ = 0;
|
||
}
|
||
|
||
if ((tmp = parse_inline(my_line + 1, sub_args, &args_flag)))
|
||
new_free(&tmp);
|
||
|
||
if (hist_flag && add_to_hist)
|
||
add_to_history(this_cmd);
|
||
}
|
||
else
|
||
{
|
||
char *rest,
|
||
*alias = NULL,
|
||
*alias_name = NULL,
|
||
*cline = NULL;
|
||
const IrcCommand *command = NULL;
|
||
void *arglist = NULL;
|
||
int cmd_cnt,
|
||
alias_cnt = 0;
|
||
#ifdef WANT_DLL
|
||
int dll_cnt;
|
||
IrcCommandDll *dll = NULL;
|
||
#endif
|
||
|
||
if ((rest = strchr(line, ' ')))
|
||
{
|
||
cline = alloca((rest - line) + 1);
|
||
memcpy(cline, line, rest - line);
|
||
cline[rest - line] = 0;
|
||
rest++;
|
||
}
|
||
else
|
||
{
|
||
cline = LOCAL_COPY(line);
|
||
rest = empty_string;
|
||
}
|
||
|
||
upper(cline);
|
||
if (cline && !strcmp(cline, "OPER"))
|
||
oper_issued++;
|
||
|
||
if (cmdchar_used < 2)
|
||
alias = get_cmd_alias(cline, &alias_cnt, &alias_name, &arglist);
|
||
|
||
if (alias && alias_cnt < 0)
|
||
{
|
||
if (hist_flag && add_to_hist && !oper_issued)
|
||
add_to_history(this_cmd);
|
||
call_user_alias(alias_name, alias, rest, arglist);
|
||
new_free(&alias_name);
|
||
}
|
||
else
|
||
{
|
||
/* History */
|
||
if (*cline == '!')
|
||
{
|
||
if ((cline = do_history(cline + 1, rest)) != NULL)
|
||
{
|
||
if (level == 1)
|
||
{
|
||
set_input(cline);
|
||
update_input(UPDATE_ALL);
|
||
}
|
||
else
|
||
parse_command(cline, 0, sub_args);
|
||
new_free(&cline);
|
||
}
|
||
else
|
||
set_input(empty_string);
|
||
}
|
||
else
|
||
{
|
||
if (hist_flag && add_to_hist && !oper_issued)
|
||
add_to_history(this_cmd);
|
||
command = find_command(cline, &cmd_cnt);
|
||
#ifdef WANT_DLL
|
||
dll = find_dll_command(cline, &dll_cnt);
|
||
if ((dll && (dll_cnt < 0)) || ((alias_cnt == 0) && (dll_cnt == 1)))
|
||
{
|
||
|
||
strcpy(cx_function, dll->name);
|
||
if (rest && *rest && !my_stricmp(rest, "-help") && dll->help)
|
||
userage(cline, dll->help);
|
||
else if (dll->func)
|
||
{
|
||
dll->func(dll_commands, dll->server_func, rest, sub_args, dll->help);
|
||
if (dll->result)
|
||
put_it("%s", dll->result);
|
||
}
|
||
else
|
||
bitchsay("%s: command disabled", dll->name);
|
||
*cx_function = 0;
|
||
}
|
||
else
|
||
#endif
|
||
if (cmd_cnt < 0 || (alias_cnt == 0 && cmd_cnt == 1))
|
||
{
|
||
if (rest && *rest && !my_stricmp(rest, "-help"))
|
||
{
|
||
if (command->help)
|
||
userage(cline, command->help);
|
||
#ifdef WANT_CHELP
|
||
else
|
||
chelp(NULL, cline, NULL, NULL);
|
||
#endif
|
||
} else if ((command->flags & SERVERREQ) && (connected_to_server == 0))
|
||
bitchsay("%s: You are not connected to a server. Use /SERVER to connect.", com);
|
||
else if (command->func)
|
||
command->func(command->server_func, rest, sub_args, command->help);
|
||
else
|
||
bitchsay("%s: command disabled", command->name);
|
||
}
|
||
else if ((alias_cnt == 1 && cmd_cnt == 1 && (!strcmp(alias_name, command->name))) ||
|
||
(alias_cnt == 1 && cmd_cnt == 0))
|
||
{
|
||
will_catch_return_exceptions++;
|
||
parse_line(alias_name, alias, rest, 0, 1, 1);
|
||
will_catch_return_exceptions--;
|
||
return_exception = 0;
|
||
}
|
||
else if (!my_stricmp(com, get_server_nickname(from_server)))
|
||
me(NULL, rest, empty_string, NULL);
|
||
#ifdef WANT_TCL
|
||
else if (tcl_interp)
|
||
{
|
||
int err;
|
||
const char *tcl_result;
|
||
|
||
err = Tcl_Invoke(tcl_interp, cline, rest);
|
||
tcl_result = Tcl_GetStringResult(tcl_interp);
|
||
|
||
if (err == TCL_OK)
|
||
{
|
||
bitchsay("%s", tcl_result);
|
||
}
|
||
else
|
||
{
|
||
if (*tcl_result)
|
||
{
|
||
if (check_help_bind(cline))
|
||
bitchsay("%s", tcl_result);
|
||
}
|
||
else if (get_int_var(DISPATCH_UNKNOWN_COMMANDS_VAR))
|
||
send_to_server("%s %s", cline, rest);
|
||
else if (alias_cnt + cmd_cnt > 1)
|
||
bitchsay("Ambiguous command: %s", cline);
|
||
else
|
||
bitchsay("Unknown command: %s", cline);
|
||
|
||
}
|
||
}
|
||
#endif
|
||
else if (get_int_var(DISPATCH_UNKNOWN_COMMANDS_VAR))
|
||
send_to_server("%s %s", cline, rest);
|
||
else if (alias_cnt + cmd_cnt > 1)
|
||
bitchsay("Ambiguous command: %s", cline);
|
||
else
|
||
bitchsay("Unknown command: %s", cline);
|
||
}
|
||
if (alias)
|
||
new_free(&alias_name);
|
||
}
|
||
}
|
||
|
||
if (oper_issued)
|
||
memset(this_cmd, 0, strlen(this_cmd));
|
||
|
||
if (old_display_var != get_int_var(DISPLAY_VAR))
|
||
window_display = get_int_var(DISPLAY_VAR);
|
||
else
|
||
window_display = display;
|
||
level--;
|
||
unset_current_command();
|
||
alias_debug = old_alias_debug;
|
||
return 0;
|
||
}
|
||
|
||
|
||
struct load_info
|
||
{
|
||
char *filename;
|
||
int line;
|
||
int start_line;
|
||
} load_level[MAX_LOAD_DEPTH] = {{ NULL, 0 }};
|
||
|
||
void dump_load_stack (int onelevel)
|
||
{
|
||
int i = load_depth;
|
||
|
||
if (i == -1)
|
||
return;
|
||
|
||
debugyell("Right before line [%d] of file [%s]", load_level[i].line,
|
||
load_level[i].filename);
|
||
|
||
if (!onelevel)
|
||
{
|
||
while (--i >= 0)
|
||
{
|
||
debugyell("Loaded right before line [%d] of file [%s]",
|
||
load_level[i].line, load_level[i].filename);
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
const char *current_filename (void)
|
||
{
|
||
if (load_depth == -1)
|
||
return empty_string;
|
||
else if (load_level[load_depth].filename)
|
||
return load_level[load_depth].filename;
|
||
else
|
||
return empty_string;
|
||
}
|
||
|
||
int current_line (void)
|
||
{
|
||
if (load_depth == -1)
|
||
return -1;
|
||
else
|
||
return load_level[load_depth].line;
|
||
}
|
||
|
||
|
||
/*
|
||
* load: the /LOAD command. Reads the named file, parsing each line as
|
||
* though it were typed in (passes each line to parse_command).
|
||
Right now, this is broken, as it doesn't handle the passing of
|
||
the '-' flag, which is meant to force expansion of expandos
|
||
with the arguments after the '-' flag. I think it's a lame
|
||
feature, anyhow. *sigh*.
|
||
*/
|
||
|
||
BUILT_IN_COMMAND(BX_load)
|
||
{
|
||
#ifdef PUBLIC_ACCESS
|
||
if (!never_connected)
|
||
{
|
||
bitchsay("This command is disabled for public access systems");
|
||
return;
|
||
}
|
||
#else
|
||
FILE *fp;
|
||
char *filename,
|
||
*expanded = NULL;
|
||
int flag = 0;
|
||
int paste_level = 0;
|
||
register char *start;
|
||
char *current_row = NULL;
|
||
#define MAX_LINE_LEN 5 * BIG_BUFFER_SIZE
|
||
char buffer[MAX_LINE_LEN + 1];
|
||
int no_semicolon = 1;
|
||
char *irc_path;
|
||
int display = window_display;
|
||
int ack = 0;
|
||
|
||
|
||
if (!(irc_path = get_string_var(LOAD_PATH_VAR)))
|
||
{
|
||
bitchsay("LOAD_PATH has not been set");
|
||
return;
|
||
}
|
||
|
||
if (++load_depth == MAX_LOAD_DEPTH)
|
||
{
|
||
load_depth--;
|
||
dump_load_stack(0);
|
||
bitchsay("No more than %d levels of LOADs allowed", MAX_LOAD_DEPTH);
|
||
return;
|
||
}
|
||
|
||
display = window_display;
|
||
window_display = 0;
|
||
status_update(0);
|
||
|
||
/*
|
||
* We iterate over the whole list -- if we use the -args flag, the
|
||
* we will make a note to exit the loop at the bottom after we've
|
||
* gone through it once...
|
||
*/
|
||
while (args && *args && (filename = next_arg(args, &args)))
|
||
{
|
||
/*
|
||
If we use the args flag, then we will get the next
|
||
filename (via continue) but at the bottom of the loop
|
||
we will exit the loop
|
||
*/
|
||
if (!my_strnicmp(filename, "-args", strlen(filename)))
|
||
{
|
||
flag = 1;
|
||
continue;
|
||
}
|
||
if (!end_strcmp(filename, ".tcl", 4))
|
||
{
|
||
#ifdef WANT_TCL
|
||
if (Tcl_EvalFile(tcl_interp, filename) != TCL_OK)
|
||
error("Unable to load filename %s [%s]", filename, Tcl_GetStringResult(tcl_interp));
|
||
#endif
|
||
continue;
|
||
}
|
||
if (!(expanded = expand_twiddle(filename)))
|
||
{
|
||
error("Unknown user for file %s", filename);
|
||
continue;
|
||
}
|
||
|
||
if (!(fp = uzfopen(&expanded, irc_path, 0)))
|
||
{
|
||
int owc = window_display;
|
||
/* uzfopen emits an error if the file
|
||
* is not found, so we don't have to. */
|
||
window_display = 1;
|
||
#ifdef WANT_DLL
|
||
if (expanded)
|
||
{
|
||
dll_load(NULL, expanded, NULL, NULL);
|
||
new_free(&expanded);
|
||
window_display = owc;
|
||
continue;
|
||
}
|
||
#endif
|
||
if (connected_to_server && !load_depth)
|
||
bitchsay("Unable to open file %s", filename);
|
||
new_free(&expanded);
|
||
window_display = owc;
|
||
continue;
|
||
}
|
||
|
||
if (command && *command == 'W')
|
||
{
|
||
yell ("%s", expanded);
|
||
if (fp)
|
||
fclose (fp);
|
||
new_free(&expanded);
|
||
continue;
|
||
}
|
||
/* Reformatted by jfn */
|
||
/* *_NOT_* attached, so don't "fix" it */
|
||
{
|
||
int in_comment = 0;
|
||
int comment_line = -1;
|
||
int paste_line = -1;
|
||
|
||
current_row = NULL;
|
||
load_level[load_depth].filename = expanded;
|
||
load_level[load_depth].line = 1;
|
||
|
||
for (;;load_level[load_depth].line++)
|
||
{
|
||
int len;
|
||
register char *ptr;
|
||
|
||
if (!(fgets(buffer,MAX_LINE_LEN, fp)))
|
||
break;
|
||
|
||
for (start = buffer; my_isspace(*start); start++)
|
||
;
|
||
if (!*start || *start == '#')
|
||
continue;
|
||
|
||
len = strlen(start);
|
||
|
||
/*
|
||
* this line from stargazer to allow \'s in scripts for continued
|
||
* lines <spz@specklec.mpifr-bonn.mpg.de>
|
||
* If we have \\ at the end of the line, that
|
||
* should indicate that we DON'T want the slash to
|
||
* escape the newline (hop)
|
||
* We can't just do start[len-2] because we can't say
|
||
* what will happen if len = 1... (a blank line)
|
||
* SO....
|
||
* If the line ends in a newline, and
|
||
* If there are at least 2 characters in the line
|
||
* and the 2nd to the last one is a \ and,
|
||
* If there are EITHER 2 characters on the line or
|
||
* the 3rd to the last character is NOT a \ and,
|
||
* If the line isn't too big yet and,
|
||
* If we can read more from the file,
|
||
* THEN -- adjust the length of the string
|
||
*/
|
||
|
||
while ( (start[len-1] == '\n') &&
|
||
(len >= 2 && start[len-2] == '\\') &&
|
||
(len < 3 || start[len-3] != '\\') &&
|
||
(len < MAX_LINE_LEN) &&
|
||
(fgets(&(start[len-2]), MAX_LINE_LEN - len, fp)))
|
||
{
|
||
len = strlen(start);
|
||
load_level[load_depth].line++;
|
||
}
|
||
|
||
if (start[len - 1] == '\n')
|
||
start[--len] = 0;
|
||
if (start[len-1] == '\r')
|
||
start[--len] = 0;
|
||
|
||
while (start && *start)
|
||
{
|
||
char *optr = start;
|
||
|
||
/* Skip slashed brackets */
|
||
while ((ptr = strpbrk(optr, "{};/")) &&
|
||
ptr != optr && ptr[-1] == '\\')
|
||
optr = ptr+1;
|
||
|
||
/*
|
||
* if no_semicolon is set, we will not attempt
|
||
* to parse this line, but will continue
|
||
* grabbing text
|
||
*/
|
||
if (no_semicolon)
|
||
no_semicolon = 0;
|
||
else if ((!ptr || (ptr != start || *ptr == '/')) && current_row)
|
||
{
|
||
if (!paste_level)
|
||
{
|
||
parse_line(NULL, current_row, flag ? args :get_int_var(INPUT_ALIASES_VAR) ?empty_string: NULL, 0, 0, 1);
|
||
new_free(¤t_row);
|
||
}
|
||
else if (!in_comment)
|
||
malloc_strcat(¤t_row, ";");
|
||
}
|
||
|
||
if (ptr)
|
||
{
|
||
char c = *ptr;
|
||
|
||
*ptr = '\0';
|
||
if (!in_comment)
|
||
malloc_strcat(¤t_row, start);
|
||
*ptr = c;
|
||
|
||
switch (c)
|
||
{
|
||
/* switch statement tabbed back */
|
||
case '/' :
|
||
{
|
||
/* If we're in a comment, any slashes that aren't preceded by
|
||
a star are just ignored. */
|
||
if (in_comment)
|
||
{
|
||
/* ooops! can't do ptr[-1] if ptr == optr... doh! */
|
||
if ((ptr > start) && (ptr[-1] == '*'))
|
||
{
|
||
in_comment = 0;
|
||
comment_line = -1;
|
||
}
|
||
else
|
||
break;
|
||
}
|
||
/* We're not in a comment... should we start one? */
|
||
else
|
||
{
|
||
/* COMMENT_BREAKAGE_VAR */
|
||
if ((ptr[1] == '*') && (!get_int_var(COMMENT_BREAKAGE_VAR) || ptr == start))
|
||
{
|
||
/* Yep. its the start of a comment. */
|
||
in_comment = 1;
|
||
comment_line = load_level[load_depth].line;
|
||
}
|
||
else
|
||
{
|
||
/* Its NOT a comment. Tack it on the end */
|
||
malloc_strcat(¤t_row, "/");
|
||
|
||
/* Is the / is at the EOL? */
|
||
if (ptr[1] == '\0')
|
||
{
|
||
/* If we are NOT in a block alias, */
|
||
if (!paste_level)
|
||
{
|
||
/* Send the line off to parse_line */
|
||
parse_line(NULL, current_row, flag ? args : get_int_var(INPUT_ALIASES_VAR) ? empty_string : NULL, 0, 0, 1);
|
||
new_free(¤t_row);
|
||
ack = 0; /* no semicolon.. */
|
||
}
|
||
else
|
||
/* Just add a semicolon and keep going */
|
||
ack = 1; /* tack on a semicolon */
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
no_semicolon = 1 - ack;
|
||
ack = 0;
|
||
break;
|
||
}
|
||
case '{' :
|
||
{
|
||
if (in_comment)
|
||
break;
|
||
|
||
/* If we are opening a brand new {} pair, remember the line */
|
||
if (!paste_level)
|
||
paste_line = load_level[load_depth].line;
|
||
|
||
paste_level++;
|
||
if (ptr == start)
|
||
malloc_strcat(¤t_row, " {");
|
||
else
|
||
malloc_strcat(¤t_row, "{");
|
||
no_semicolon = 1;
|
||
break;
|
||
}
|
||
case '}' :
|
||
{
|
||
if (in_comment)
|
||
break;
|
||
if (!paste_level)
|
||
error("Unexpected } in %s, line %d", expanded, load_level[load_depth].line);
|
||
else
|
||
{
|
||
--paste_level;
|
||
|
||
if (!paste_level)
|
||
paste_line = -1;
|
||
malloc_strcat(¤t_row, "}"); /* } */
|
||
no_semicolon = ptr[1]? 1: 0;
|
||
}
|
||
break;
|
||
}
|
||
case ';' :
|
||
{
|
||
if (in_comment)
|
||
break;
|
||
malloc_strcat(¤t_row, ";");
|
||
if (!ptr[1] && !paste_level)
|
||
{
|
||
parse_line(NULL, current_row, flag ? args : get_int_var(INPUT_ALIASES_VAR) ? empty_string : NULL, 0, 0, 1);
|
||
new_free(¤t_row);
|
||
}
|
||
else if (!ptr[1] && paste_level)
|
||
no_semicolon = 0;
|
||
else
|
||
no_semicolon = 1;
|
||
break;
|
||
}
|
||
/* End of reformatting */
|
||
}
|
||
start = ptr+1;
|
||
}
|
||
else
|
||
{
|
||
if (!in_comment)
|
||
malloc_strcat(¤t_row, start);
|
||
start = NULL;
|
||
}
|
||
}
|
||
}
|
||
if (in_comment)
|
||
error("File %s ended with an unterminated comment in line %d", expanded, comment_line);
|
||
if (current_row)
|
||
{
|
||
if (paste_level)
|
||
error("Unexpected EOF in %s trying to match '[' at line %d",
|
||
expanded, paste_line);
|
||
else
|
||
parse_line(NULL,current_row, flag ? args: get_int_var(INPUT_ALIASES_VAR) ? empty_string : NULL,0,0, 1);
|
||
new_free(¤t_row);
|
||
}
|
||
}
|
||
new_free(&expanded);
|
||
fclose(fp);
|
||
} /* end of the while loop that allows you to load
|
||
more then one file at a time.. */
|
||
|
||
if (get_int_var(DISPLAY_VAR))
|
||
window_display = display;
|
||
|
||
status_update(1);
|
||
load_depth--;
|
||
#endif
|
||
}
|
||
|
||
|
||
|
||
/* The SENDLINE command.. */
|
||
BUILT_IN_COMMAND(sendlinecmd)
|
||
{
|
||
int server;
|
||
int display;
|
||
|
||
|
||
server = from_server;
|
||
display = window_display;
|
||
window_display = 1;
|
||
if (args && *args)
|
||
parse_line(NULL, args, get_int_var(INPUT_ALIASES_VAR) ?empty_string : NULL, 1, 0, 1);
|
||
update_input(UPDATE_ALL);
|
||
window_display = display;
|
||
from_server = server;
|
||
}
|
||
|
||
BUILT_IN_COMMAND(cd)
|
||
{
|
||
char *arg,
|
||
*expand;
|
||
char buffer[BIG_BUFFER_SIZE + 1];
|
||
|
||
if ((arg = new_next_arg(args, &args)) != NULL && *arg)
|
||
{
|
||
if ((expand = expand_twiddle(arg)) != NULL)
|
||
{
|
||
if (chdir(expand))
|
||
{
|
||
bitchsay("CD: %s %s", arg, strerror(errno));
|
||
new_free(&expand);
|
||
return;
|
||
}
|
||
new_free(&expand);
|
||
}
|
||
else
|
||
{
|
||
bitchsay("CD: %s No such directory", arg);
|
||
return;
|
||
}
|
||
}
|
||
if (getcwd(buffer, BIG_BUFFER_SIZE))
|
||
bitchsay("Current directory: %s", buffer);
|
||
else
|
||
bitchsay("CD: %s", strerror(errno));
|
||
}
|
||
|
||
BUILT_IN_COMMAND(exec_cmd)
|
||
{
|
||
char buffer[BIG_BUFFER_SIZE + 1];
|
||
|
||
snprintf(buffer, BIG_BUFFER_SIZE, "%s %s", command, args);
|
||
execcmd(NULL, buffer, subargs, helparg);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(describe)
|
||
{
|
||
char *target;
|
||
|
||
|
||
target = next_arg(args, &args);
|
||
if (target && args && *args)
|
||
{
|
||
char *message;
|
||
|
||
message = args;
|
||
if (!strcmp(target, "*"))
|
||
if ((target = get_current_channel_by_refnum(0)) == NULL)
|
||
target = zero;
|
||
set_display_target(target, LOG_ACTION);
|
||
send_ctcp(CTCP_PRIVMSG, target, CTCP_ACTION, "%s", message);
|
||
|
||
if (do_hook(SEND_ACTION_LIST, "%s %s", target, message))
|
||
put_it("%s", convert_output_format(fget_string_var(FORMAT_SEND_ACTION_OTHER_FSET),
|
||
"%s %s %s %s", update_clock(GET_TIME), get_server_nickname(from_server), target, message));
|
||
reset_display_target();
|
||
}
|
||
}
|
||
|
||
/*
|
||
* New 'me' command.
|
||
*/
|
||
|
||
BUILT_IN_COMMAND(me)
|
||
{
|
||
|
||
if (args && *args)
|
||
{
|
||
char *target = NULL;
|
||
if (!command)
|
||
target = get_current_channel_by_refnum(0);
|
||
else if (!my_stricmp(command, "dme"))
|
||
{
|
||
DCC_int *n = NULL;
|
||
SocketList *s;
|
||
int i;
|
||
for (i = 0; i < get_max_fd()+1; i++)
|
||
{
|
||
if (!check_dcc_socket(i))
|
||
continue;
|
||
s = get_socket(i);
|
||
n = (DCC_int *) s->info;
|
||
if (!((s->flags & DCC_TYPES) == DCC_CHAT))
|
||
continue;
|
||
target = n->user;
|
||
break;
|
||
}
|
||
}
|
||
else if (!my_stricmp(command, "qme"))
|
||
{
|
||
target = current_window->query_nick;
|
||
if (!target)
|
||
{
|
||
Window *tmp = NULL;
|
||
while((traverse_all_windows(&tmp)))
|
||
if((target = tmp->query_nick))
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
if (!(target = get_target_by_refnum(0)))
|
||
target = get_current_channel_by_refnum(0);
|
||
if (target)
|
||
{
|
||
char *message;
|
||
message = args;
|
||
set_display_target(target, LOG_ACTION);
|
||
send_ctcp(CTCP_PRIVMSG, target, CTCP_ACTION, "%s", message);
|
||
|
||
if (do_hook(SEND_ACTION_LIST, "%s %s", target, message))
|
||
{
|
||
if (strchr("&#", *target))
|
||
put_it("%s", convert_output_format(fget_string_var(FORMAT_SEND_ACTION_FSET),
|
||
"%s %s %s %s", update_clock(GET_TIME), get_server_nickname(from_server), target, message));
|
||
else
|
||
put_it("%s", convert_output_format(fget_string_var(FORMAT_SEND_ACTION_OTHER_FSET),
|
||
"%s %s %s %s", update_clock(GET_TIME), get_server_nickname(from_server), target, message));
|
||
}
|
||
reset_display_target();
|
||
}
|
||
}
|
||
}
|
||
|
||
/*
|
||
* eval_inputlist: Cute little wrapper that calls parse_line() when we
|
||
* get an input prompt ..
|
||
*/
|
||
|
||
void eval_inputlist(char *args, char *line)
|
||
{
|
||
|
||
parse_line(NULL, args, line ? line : empty_string, 0, 0, 1);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(xevalcmd)
|
||
{
|
||
char * flag;
|
||
int old_from_server = from_server;
|
||
Window *old_target_window = target_window;
|
||
int old_refnum = current_window->refnum;
|
||
|
||
if (*command == 'X')
|
||
{
|
||
while (args && (*args == '-' || *args == '/'))
|
||
{
|
||
flag = next_arg(args, &args);
|
||
if (!my_strnicmp(flag + 1, "S", 1)) /* SERVER */
|
||
{
|
||
int val = my_atol(next_arg(args, &args));
|
||
if (is_server_open(val))
|
||
from_server = val;
|
||
}
|
||
else if (!my_strnicmp(flag + 1, "W", 1)) /* WINDOW */
|
||
{
|
||
Window *win = get_window_by_desc(next_arg(args, &args));
|
||
if (win)
|
||
{
|
||
current_window = win;
|
||
target_window = win;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
parse_line(NULL, args, subargs ? subargs : empty_string, 0, 0, 0);
|
||
target_window = old_target_window;
|
||
make_window_current_by_winref(old_refnum);
|
||
from_server = old_from_server;
|
||
}
|
||
|
||
BUILT_IN_COMMAND(evalcmd)
|
||
{
|
||
parse_line(NULL, args, subargs ? subargs : empty_string, 0, 0, 0);
|
||
}
|
||
|
||
/*
|
||
* inputcmd: the INPUT command. Takes a couple of arguments...
|
||
* the first surrounded in double quotes, and the rest makes up
|
||
* a normal ircII command. The command is evalutated, with $*
|
||
* being the line that you input. Used add_wait_prompt() to prompt
|
||
* the user... -phone, jan 1993.
|
||
*/
|
||
|
||
BUILT_IN_COMMAND(inputcmd)
|
||
{
|
||
char *prompt;
|
||
int wait_type;
|
||
char *argument;
|
||
int echo = 1;
|
||
|
||
|
||
|
||
|
||
while (*args == '-')
|
||
{
|
||
argument = next_arg(args, &args);
|
||
if (!my_stricmp(argument, "-noecho"))
|
||
echo = 0;
|
||
}
|
||
|
||
if (!(prompt = new_next_arg(args, &args)))
|
||
{
|
||
say("Usage: %s \"prompt\" { commands }", command);
|
||
return;
|
||
}
|
||
|
||
if (!my_stricmp(command, "INPUT"))
|
||
wait_type = WAIT_PROMPT_LINE;
|
||
else
|
||
wait_type = WAIT_PROMPT_KEY;
|
||
|
||
while (my_isspace(*args))
|
||
args++;
|
||
|
||
add_wait_prompt(prompt, eval_inputlist, args, wait_type, echo);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(xtypecmd)
|
||
{
|
||
char *arg;
|
||
|
||
|
||
if (args && (*args == '-' || *args == '/'))
|
||
{
|
||
char saved = *args;
|
||
args++;
|
||
if ((arg = next_arg(args, &args)) != NULL)
|
||
{
|
||
if (!my_strnicmp(arg, "L", 1))
|
||
{
|
||
for (; *args; args++)
|
||
input_add_character(*args, empty_string);
|
||
}
|
||
else
|
||
bitchsay ("Unknown flag -%s to XTYPE", arg);
|
||
return;
|
||
}
|
||
input_add_character(saved, empty_string);
|
||
}
|
||
else
|
||
type(command, args, empty_string, helparg);
|
||
return;
|
||
}
|
||
|
||
BUILT_IN_COMMAND(beepcmd)
|
||
{
|
||
term_beep();
|
||
}
|
||
|
||
BUILT_IN_COMMAND(e_debug)
|
||
{
|
||
int x;
|
||
char buffer[BIG_BUFFER_SIZE + 1];
|
||
|
||
if (args && *args)
|
||
{
|
||
char *s, *copy;
|
||
|
||
copy = LOCAL_COPY(args);
|
||
upper(copy);
|
||
while ((s = next_arg(copy, ©)))
|
||
{
|
||
char *t, *c;
|
||
x = 1;
|
||
c = new_next_arg(copy, ©);
|
||
if (!c || !*c)
|
||
break;
|
||
while ((t = next_in_comma_list(c, &c)))
|
||
{
|
||
if (!t || !*t)
|
||
break;
|
||
if (*t == '-')
|
||
{
|
||
t++;
|
||
x = 0;
|
||
}
|
||
if (!my_stricmp(s, "ALIAS"))
|
||
debug_alias(t, x);
|
||
else if (!my_stricmp(s, "HOOK"))
|
||
debug_hook(t, x);
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
*buffer = 0;
|
||
for (x = 0; x < FD_SETSIZE; x++)
|
||
{
|
||
if (FD_ISSET(x, &readables))
|
||
{
|
||
strcat(buffer, space);
|
||
strcat(buffer, ltoa(x));
|
||
}
|
||
}
|
||
yell(buffer);
|
||
}
|
||
|
||
BUILT_IN_COMMAND(pretend_cmd)
|
||
{
|
||
parse_server(args);
|
||
}
|
||
|
||
/*
|
||
* This is a quick and dirty hack (emphasis on dirty) that i whipped up
|
||
* just for the heck of it. I feel really dirty about using the add_timer
|
||
* call (bletch!) to fake a timeout for io(). The better answer would be
|
||
* for io() to take an argument specifying the maximum threshold for a
|
||
* timeout, but i didnt want to deal with that here. So i just add a
|
||
* dummy timer event that does nothing (wasting two function calls and
|
||
* about 20 bytes of memory), and call io() until the whole thing blows
|
||
* over. Nice and painless. You might want to try this instead of /sleep,
|
||
* since this is (obviously) non-blocking. This also calls time() for every
|
||
* io event, so that might also start adding up. Oh well, TIOLI.
|
||
*
|
||
* Without an argument, it waits for the user to press a key. Any key.
|
||
* and the key is accepted. That's probably not right, I'll work on that.
|
||
*/
|
||
static int e_pause_cb_throw = 0;
|
||
static void e_pause_cb (char *u1, char *u2) { e_pause_cb_throw--; }
|
||
|
||
BUILT_IN_COMMAND(e_pause)
|
||
{
|
||
char *sec;
|
||
long milliseconds;
|
||
struct timeval start;
|
||
|
||
if (!(sec = next_arg(args, &args)))
|
||
{
|
||
int c_level = e_pause_cb_throw;
|
||
|
||
add_wait_prompt(empty_string, e_pause_cb,
|
||
NULL, WAIT_PROMPT_DUMMY, 0);
|
||
e_pause_cb_throw++;
|
||
while (e_pause_cb_throw > c_level)
|
||
io("pause");
|
||
return;
|
||
}
|
||
|
||
milliseconds = (long)(atof(sec) * 1000);
|
||
get_time(&start);
|
||
start.tv_usec += (milliseconds * 1000);
|
||
start.tv_sec += (start.tv_usec / 1000000);
|
||
start.tv_usec %= 1000000;
|
||
|
||
/*
|
||
* I use comment here simply because it's not going to mess
|
||
* with the arguments.
|
||
*/
|
||
add_timer(0, empty_string, milliseconds, 1, (int (*)(void *, char *))comment, NULL, NULL, get_current_winref(), "pause");
|
||
while (time_until(&start) > 0)
|
||
io("e_pause");
|
||
}
|
||
|
||
#ifndef WANT_TCL
|
||
|
||
char tcl_versionstr[] = "";
|
||
BUILT_IN_COMMAND(tcl_command)
|
||
{
|
||
bitchsay("This Client is not compiled with tcl support.");
|
||
}
|
||
|
||
BUILT_IN_COMMAND(tcl_load)
|
||
{
|
||
tcl_command(NULL, NULL, NULL, NULL);
|
||
}
|
||
|
||
#else
|
||
BUILT_IN_COMMAND(tcl_load)
|
||
{
|
||
char *filename = NULL;
|
||
int result = 0;
|
||
reset_display_target();
|
||
if ((filename = next_arg(args, &args)))
|
||
{
|
||
char *bla = NULL;
|
||
const char *tcl_result;
|
||
|
||
if (get_string_var(LOAD_PATH_VAR))
|
||
bla = path_search(filename, get_string_var(LOAD_PATH_VAR));
|
||
|
||
result = Tcl_EvalFile(tcl_interp, bla ? bla : filename);
|
||
tcl_result = Tcl_GetStringResult(tcl_interp);
|
||
|
||
if (result != TCL_OK)
|
||
put_it("Tcl Error: [%s]", tcl_result);
|
||
else if (*tcl_result)
|
||
put_it("Tcl: [%s]", tcl_result);
|
||
}
|
||
}
|
||
|
||
|
||
#endif
|
||
|
||
|
||
BUILT_IN_COMMAND(breakcmd)
|
||
{
|
||
if (!will_catch_break_exceptions)
|
||
say("Cannot BREAK here.");
|
||
else
|
||
break_exception++;
|
||
}
|
||
|
||
BUILT_IN_COMMAND(continuecmd)
|
||
{
|
||
if (!will_catch_continue_exceptions)
|
||
say("Cannot CONTINUE here.");
|
||
else
|
||
continue_exception++;
|
||
}
|
||
|
||
BUILT_IN_COMMAND(returncmd)
|
||
{
|
||
if (!will_catch_return_exceptions)
|
||
say("Cannot RETURN here.");
|
||
else
|
||
{
|
||
if (args && *args)
|
||
{
|
||
int o_w_d = window_display;
|
||
window_display = 0;
|
||
add_local_alias("FUNCTION_RETURN", args);
|
||
window_display = o_w_d;
|
||
}
|
||
return_exception++;
|
||
}
|
||
}
|
||
|
||
|
||
BUILT_IN_COMMAND(help)
|
||
{
|
||
const IrcCommand *cmd = NULL;
|
||
#ifdef WANT_DLL
|
||
IrcCommandDll *cmddll = NULL;
|
||
#endif
|
||
int cnt = 1, cntdll = 0, c, i;
|
||
char *comm = NULL;
|
||
char buffer[BIG_BUFFER_SIZE];
|
||
|
||
reset_display_target();
|
||
if (args && *args)
|
||
{
|
||
comm = next_arg(args, &args);
|
||
cmd = find_command(upper(comm), &cnt);
|
||
#ifdef WANT_DLL
|
||
cmddll = find_dll_command(comm, &cntdll);
|
||
if (!cmd && !cmddll)
|
||
#else
|
||
if (!cmd)
|
||
#endif
|
||
{
|
||
bitchsay("No such command [%s]", comm);
|
||
return;
|
||
}
|
||
if (cmd == irc_command)
|
||
{
|
||
cmd = NULL;
|
||
cnt = 0;
|
||
}
|
||
if (cnt < 0)
|
||
{
|
||
userage(cmd->name, cmd->help ? cmd->help : "No Help available Yet");
|
||
return;
|
||
}
|
||
#ifdef WANT_DLL
|
||
if (cntdll < 0 && cmddll)
|
||
{
|
||
userage(cmddll->name, cmddll->help ? cmddll->help : "No Help available Yet");
|
||
return;
|
||
}
|
||
#endif
|
||
}
|
||
#ifdef WANT_DLL
|
||
if (!cmd && !cmddll)
|
||
#else
|
||
if (!cmd)
|
||
#endif
|
||
{
|
||
cmd = irc_command;
|
||
cmd++;
|
||
cnt = NUMBER_OF_COMMANDS;
|
||
#ifdef WANT_DLL
|
||
for (cmddll = dll_commands; cmddll; cmddll = cmddll->next)
|
||
cntdll++;
|
||
cmddll = dll_commands;
|
||
#endif
|
||
}
|
||
else if (comm && *comm)
|
||
{
|
||
int tcnt = 0;
|
||
tcnt = cnt + cntdll;
|
||
put_it("%s", convert_output_format("$G Found %K[%W$0%K]%n matches for %K[%W$1%K]", "%d %s", tcnt, comm));
|
||
}
|
||
*buffer = 0;
|
||
c = 0;
|
||
for (i = 0; i < cnt; i++)
|
||
{
|
||
strlcat(buffer, cmd[i].name, sizeof buffer);
|
||
strlcat(buffer, space, sizeof buffer);
|
||
if (++c == 5)
|
||
{
|
||
put_it("%s", convert_output_format("$G $[13]0 $[13]1 $[13]2 $[13]3 $[13]4", "%s", buffer));
|
||
*buffer = 0;
|
||
c = 0;
|
||
}
|
||
}
|
||
#ifdef WANT_DLL
|
||
for (i = 0; i < cntdll && cmddll; cmddll = cmddll->next, i++)
|
||
{
|
||
strlcat(buffer, cmddll->name, sizeof buffer);
|
||
strlcat(buffer, space, sizeof buffer);
|
||
if (++c == 5)
|
||
{
|
||
put_it("%s", convert_output_format("$G $[13]0 $[13]1 $[13]2 $[13]3 $[13]4", "%s", buffer));
|
||
*buffer = 0;
|
||
c = 0;
|
||
}
|
||
}
|
||
#endif
|
||
if (c)
|
||
put_it("%s", convert_output_format("$G $[13]0 $[13]1 $[13]2 $[13]3 $[13]4", "%s", buffer));
|
||
userage("help", "%R[%ncommand%R]%n or /command -help %n to get help on specific commands");
|
||
}
|