/* * edit.c: This is really a mishmash of function and such that deal with IRCII * commands (both normal and keybinding commands) * * Written By Michael Sandrof * * Copyright (c) 1990 Michael Sandrof. * Copyright (c) 1991, 1992 Troy Rollo. * Copyright (c) 1992-2003 Matthew R. Green. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id: edit.c,v 1.107 2006/04/30 14:15:43 f Exp $ */ #include "irc.h" #include #ifdef ESIX # include #endif /* ESIX */ #include "parse.h" #include "ircterm.h" #include "server.h" #include "edit.h" #include "crypt.h" #include "vars.h" #include "ircaux.h" #include "lastlog.h" #include "window.h" #include "screen.h" #include "whois.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 "translat.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" /**************************** PATCHED by Flier ******************************/ #include "struct.h" #include "myvars.h" /****************************************************************************/ /* * current_exec_timer - used to make sure we don't remove a timer * from within itself. */ static int current_exec_timer = -1; static int save_which; static int save_do_all; static void show_timer _((char *)); static int create_timer_ref _((int)); static void get_history _((int)); static void oper_password_received _((char *, char *)); /**************************** Patched by Flier ******************************/ /*static char *do_channel _((char *, int));*/ static char *do_channel _((char *, int, int)); /****************************************************************************/ static void send_action _((char *, char *)); TimerList *PendingTimers = (TimerList *) 0; /* used with input_move_cursor */ #define RIGHT 1 #define LEFT 0 /* used with /save */ #define SFLAG_ALIAS 0x0001 #define SFLAG_BIND 0x0002 #define SFLAG_ON 0x0004 #define SFLAG_SET 0x0008 #define SFLAG_NOTIFY 0x0010 #define SFLAG_DIGRAPH 0x0020 /* The maximum number of recursive LOAD levels allowed */ #define MAX_LOAD_DEPTH 10 /* recv_nick: the nickname of the last person to send you a privmsg */ u_char *recv_nick = NULL; /* sent_nick: the nickname of the last person to whom you sent a privmsg */ u_char *sent_nick = NULL; u_char *sent_body = NULL; /* Used to keep down the nesting of /LOADs and to determine if we * should activate the warning for /ONs if the NOVICE variable is set. */ int load_depth = 0; /* Used to prevent global messaging */ extern int in_on_who; typedef struct WaitCmdstru { char *stuff; struct WaitCmdstru *next; } WaitCmd; static WaitCmd *start_wait_list = NULL, *end_wait_list = NULL; char lame_wait_nick[] = "1#LAME"; /* a few advance declarations */ #ifndef LITE static void sendlinecmd _((char *, char *, char *)); #endif static void do_send_text _((char *, char *, char *)); static void funny_stuff _((char *, char *, char *)); #ifndef LITE static void catter _((char *, char *, char *)); #endif static void cd _((char *, char *, char *)); #ifndef LITE static void e_wall _((char *, char *, char *)); static void send_squery _((char *, char *, char *)); #endif static void send_2comm _((char *, char *, char *)); static void send_comm _((char *, char *, char *)); static void send_topic _((char *, char *, char *)); static void send_channel_nargs _((char *, char *, char *)); static void send_channel_2args _((char *, char *, char *)); static void send_channel_1arg _((char *, char *, char *)); static void my_clear _((char *, char *, char *)); static void quote _((char *, char *, char *)); static void e_privmsg _((char *, char *, char *)); static void flush _((char *, char *, char *)); /**************************** PATCHED by Flier ******************************/ /*static void away _((char *, char *, char *));*/ void away _((char *, char *, char *)); /****************************************************************************/ static void oper _((char *, char *, char *)); /**************************** PATCHED by Flier ******************************/ /*static void e_channel _((char *, char *, char *));*/ void e_channel _((char *, char *, char *)); /****************************************************************************/ static void who _((char *, char *, char *)); static void whois _((char *, char *, char *)); static void ison _((char *, char *, char *)); /**************************** PATCHED by Flier ******************************/ /*static void userhost _((char *, char *, char *));*/ void userhost _((char *, char *, char *)); /****************************************************************************/ #ifndef LITE static void info _((char *, char *, char *)); #endif /**************************** PATCHED by Flier ******************************/ /*static void e_nick _((char *, char *, char *));*/ void e_nick _((char *, char *, char *)); /****************************************************************************/ static void commentcmd _((char *, char *, char *)); static void sleepcmd _((char *, char *, char *)); static void version _((char *, char *, char *)); static void ctcp _((char *, char *, char *)); static void dcc _((char *, char *, char *)); static void deop _((char *, char *, char *)); static void my_echo _((char *, char *, char *)); static void save_settings _((char *, char *, char *)); static void redirect _((char *, char *, char *)); /**************************** PATCHED by Flier ******************************/ /*static void waitcmd _((char *, char *, char *));*/ void waitcmd _((char *, char *, char *)); /*static void describe _((char *, char *, char *));*/ void describe _((char *, char *, char *)); /*static void me _((char *, char *, char *));*/ void me _((char *, char *, char *)); /****************************************************************************/ #ifndef LITE static void mload _((char *, char *, char *)); static void mlist _((char *, char *, char *)); #endif static void evalcmd _((char *, char *, char *)); static void hook _((char *, char *, char *)); /**************************** PATCHED by Flier ******************************/ /*static void timercmd _((char *, char *, char *));*/ void timercmd _((char *, char *, char *)); /****************************************************************************/ #ifndef LITE static void inputcmd _((char *, char *, char *)); #endif static void pingcmd _((char *, char *, char *)); #ifndef LITE static void xtypecmd _((char *, char *, char *)); static void beepcmd _((char *, char *, char *)); static void abortcmd _((char *, char *, char *)); #endif static void really_save _((char *, char *)); /**************************** PATCHED by Flier ******************************/ /******************* SHEIK ADDED FUNCTIONS *****************************/ extern void LameKick _((char *, char *, char *)); extern void ChanWallOp _((char *, char *, char *)); extern void NewUser _((char *, char *, char *)); extern void ReconnectServer _((char *, char *, char *)); extern void MegaDeop _((char *, char *, char *)); /***********************************************************************/ extern void MegaDehalfop _((char *, char *, char *)); extern char *TimeStamp _((int)); #ifdef OPER extern int StatskNumber; extern int StatsiNumber; extern int StatscNumber; extern int StatslNumber; #endif extern char *chars; extern NickList *tabnickcompl; /* Patched by Zakath */ extern char VersionInfo[]; extern char *ScrollZver1; #ifdef CELECOSM extern struct friends *whoisfriend; #endif /* End patch */ extern void AutoNickComplete _((char *, char *, ChannelList *)); extern void NoWindowChannel _((void)); extern int CheckServer _((int)); extern char *CheckJoinKey _((char *)); extern int EncryptMessage _((char *, char *)); extern int RateLimitJoin _((int)); extern void ListFriends _((char *, char *, char *)); extern void ListAutoBanKicks _((char *, char *, char *)); extern void Kick _((char *, char *, char *)); extern void BanKick _((char *, char *, char *)); extern void Op _((char *, char *, char *)); extern void Ban _((char *, char *, char *)); extern void BanType _((char *, char *, char *)); extern void Invite _((char *, char *, char *)); extern void Leave _((char *, char *, char *)); extern void ModeClear _((char *, char *, char *)); extern void ChannelScan _((char *, char *, char *)); extern void FServer _((char *, char *, char *)); extern void Topic _((char *, char *, char *)); extern void Cycle _((char *, char *, char *)); extern void ScrollZSave _((char *, char *, char *)); extern void DirLM _((char *, char *, char *)); extern void AddFriend _((char *, char *, char *)); extern void AddAutoBanKick _((char *, char *, char *)); extern void ShowBans _((char *, char *, char *)); extern void RemoveFriend _((char *, char *, char *)); extern void RemoveAutoBanKick _((char *, char *, char *)); extern void Version _((char *, char *, char *)); extern void Unban _((char *, char *, char *)); extern void CdBan _((char *, char *, char *)); extern void NoIgnore _((char *, char *, char *)); extern void Ignore _((char *, char *, char *)); extern void SetAway _((char *, char *, char *)); extern void SetBack _((char *, char *, char *)); extern void AddWord _((char *, char *, char *)); extern void RemoveWord _((char *, char *, char *)); extern void ListWords _((char *, char *, char *)); extern void WhoLeft _((char *, char *, char *)); extern void FilterKick _((char *, char *, char *)); extern void ClearKey _((char *, char *, char *)); extern void NHProtToggle _((char *, char *, char *)); extern void ChanStat _((char *, char *, char *)); extern void Cdcc _((char *, char *, char *)); extern void Ls _((char *, char *, char *)); extern void Chat _((char *, char *, char *)); extern void NoChat _((char *, char *, char *)); extern void Finger _((char *, char *, char *)); extern void UserMode _((char *, char *, char *)); extern void AutoJoinOnInvToggle _((char *, char *, char *)); extern void Settings _((char *, char *, char *)); extern void FloodProtToggle _((char *, char *, char *)); extern void Net _((char *, char *, char *)); extern void Reset _((char *, char *, char *)); extern void CTCPCloakingToggle _((char *, char *, char *)); extern void MassHalfop _((char *, char *, char *)); extern void MassOp _((char *, char *, char *)); extern void TBan _((char *, char *, char *)); #ifdef SCKICKS extern void ScatterKick _((char *, char *, char *)); extern void RandomScatterKick _((char *, char *, char *)); #endif extern void NickStat _((char *, char *, char *)); extern void AddNotify _((char *, char *, char *)); extern void RemoveNotify _((char *, char *, char *)); extern void ListNotify _((char *, char *, char *)); extern void MyQuit _((char *)); extern void AddNick2List _((char *, int)); extern void HandleTabNext _((void)); extern void AddServer _((char *, char *, char *)); extern void RemoveServer _((char *, char *, char *)); extern void ListServers _((char *, char *, char *)); extern void ClearTab _((char *, char *, char *)); extern void ShowKill _((char *, char *, char *)); #ifdef ACID extern void TagNick _((char *, char *, char *)); extern void WhereIs _((char *, char *, char *)); extern void WhereList _((char *, char *, char *)); #endif extern void UnFlash _((char *, char *, char *)); extern void Password _((char *, char *, char *)); extern void PrintPublic _((char *, char *, char *, char *, int, int)); extern void PlayBack _((char *, char *, char *)); extern void AwaySaveToggle _((char *, char *, char *)); #ifdef OPER extern void MassKill _((char *, char *, char *)); extern void FilterTrace _((char *, char *, char *)); extern void StatsKFilter _((char *, char *, char *)); extern void StatsIFilter _((char *, char *, char *)); extern void StatsLFilter _((char *, char *, char *)); extern void StatsCFilter _((char *, char *, char *)); extern void StatsDFilter _((char *, char *, char *)); extern void WhoKill _((char *, char *, char *)); extern void TraceKill _((char *, char *, char *)); #endif extern void CurrentChanMode _((char *, char *, char *)); extern void Nslookup _((char *, char *, char *)); extern void Dump _((char *, char *, char *)); extern void RemoveLog _((char *, char *, char *)); extern void DirLSM _((char *, char *, char *)); extern void ShowUser _((char *, char *, char *)); #ifdef WANTANSI extern void SetColor _((char *, char *, char *)); #endif extern void NotifyModeToggle _((char *, char *, char *)); extern void PingMe _((char *, char *, char *)); extern void NotePad _((char *, char *, char *)); extern void URLCatchToggle _((char *, char *, char *)); extern void URLSave _((char *, char *, char *)); extern void ReplyWord _((char *, char *, char *)); extern void MultiKick _((char *, char *, char *)); extern void Map _((char *, char *, char *)); extern void AddFriendPrivs _((char *, char *, char *)); extern void AddFriendChannel _((char *, char *, char *)); extern void MassKick _((char *, char *, char *)); extern void OnOffCommand _((char *, char *, char *)); extern void NumberCommand _((char *, char *, char *)); extern void SetAutoCompletion _((char *, char *, char *)); extern void ChannelCommand _((char *, char *, char *)); extern void AddChannel _((char *, char *, char *)); extern void ScrollZInfo _((char *, char *, char *)); extern void switchcmd _((char *, char *, char *)); extern void repeatcmd _((char *, char *, char *)); extern void Purge _((char *, char *, char *)); extern void EncryptMsg _((char *, char *, char *)); extern void AwaySave _((char *, int)); extern void ChangePassword _((char *, char *, char *)); #ifdef MGS_ extern void Terminate _((char *, char *, char *)); #endif extern void ARinWindowToggle _((char *, char *, char *)); extern void CJoin _((char *, char *, char *)); extern void ChanLogCommand _((char *, char *, char *)); extern void ChannelLogSave _((char *, ChannelList *)); extern void CdExceptions _((char *, char *, char *)); extern void ExtendTopic _((char *, char *, char *)); extern void TopicDelimiter _((char *, char *, char *)); /* Coded by Zakath */ extern void NewHost _((char *, char *, char *)); extern void MegaReop _((char *, char *, char *)); extern void ServerPing _((char *, char *, char *)); #ifdef CELE extern void ExecUptime _((char *, char *, char *)); extern void CTCPFing _((char *, char *, char *)); extern void Cquickstat _((char *, char *, char *)); extern void ScrollZTrace _((char *, char *, char *)); extern void Cstatusbar _((char *, char *, char *)); #endif #if defined(OPERVISION) && defined(WANTANSI) extern void OperVision _((char *, char *, char *)); #endif #ifdef EXTRAS extern void DoBans _((char *, char *, char *)); extern void MSay _((char *, char *, char *)); extern void ModeLocked _((char *, char *, char *)); extern void ModeUnlocked _((char *, char *, char *)); extern void RandomLamerKick _((char *, char *, char *)); extern void LastNoticeKick _((char *, char *, char *)); extern void LastMessageKick _((char *, char *, char *)); extern void LLook _((char *, char *, char *)); extern void LLookUp _((char *, char *, char *)); extern void MegaVoice _((char *, char *, char *)); extern void MegaDeVoice _((char *, char *, char *)); extern void SetIdleKick _((char *, char *, char *)); extern void ShowIdle _((char *, char *, char *)); extern void TopicLocked _((char *, char *, char *)); #endif #ifdef BLAXTHOS extern void EncryptString _((char *, char *, char *, int, int)); #endif /****************************************************************************/ /**************************** Patched by Flier ******************************/ /* moved to struct.h so we can do command completion with tab */ /* IrcCommand: structure for each command in the command table */ /*typedef struct { char FAR *name;*/ /* what the user types */ /*char *server_func;*/ /* what gets sent to the server * (if anything) */ /*void (*func) _((char *, char *, char *));*/ /* function that is the command */ /*unsigned flags; } IrcCommand;*/ /****************************************************************************/ static IrcCommand *find_command _((char *, int *)); #define NONOVICEABBREV 0x0001 #define NOINTERACTIVE 0x0002 #define NOSIMPLESCRIPT 0x0004 #define NOCOMPLEXSCRIPT 0x0008 #define SERVERREQ 0x0010 /* * 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. */ /**************************** Patched by Flier ******************************/ /*static IrcCommand FAR irc_command[] =*/ IrcCommand FAR irc_command[] = /****************************************************************************/ { { "", empty_string, do_send_text, NOSIMPLESCRIPT| NOCOMPLEXSCRIPT }, /* * I really want to remove #, but it will break a lot of scripts. - mycroft * * I agree - it should be converted to a special character in parse_line. * - Troy */ { "#", NULL, commentcmd, 0 }, { ":", NULL, commentcmd, 0 }, #ifndef LITE { "ABORT", NULL, abortcmd, 0 }, #endif { "ADDBK", NULL, AddAutoBanKick, 0 }, { "ADDCHAN", "ADD", AddChannel, 0 }, { "ADDF", NULL, AddFriend, 0 }, { "ADDFCHAN", "ADD", AddFriendChannel, 0 }, { "ADDFFLAG", "ADD", AddFriendPrivs, 0 }, { "ADDN", NULL, AddNotify, SERVERREQ }, #ifndef LITE { "ADDS", NULL, AddServer, 0 }, #endif { "ADDW", NULL, AddWord, 0 }, #ifndef LITE { "ADMIN", "ADMIN", send_comm, SERVERREQ }, #endif { "AJOIN", NULL, AutoJoinOnInvToggle, 0 }, { "ALIAS", "0", alias, 0 }, #ifdef ALLOC_DEBUG { "ALLOC", NULL, alloc_cmd, 0 }, #endif { "AREJOIN", "AREJOIN", ChannelCommand, 0 }, { "ARINWIN", NULL, ARinWindowToggle, 0 }, { "ASSIGN", "1", alias, 0 }, { "AUTOCOMPL", "AUTOCOMPL", SetAutoCompletion, 0 }, #if defined(EXTRAS) || defined(FLIER) { "AUTOINV", "AUTOINV", ChannelCommand, 0 }, #endif { "AUTOOPDELAY", "AUTOOPDELAY", NumberCommand, 0 }, { "AWAY", "AWAY", away, SERVERREQ }, { "AWAYENCR", "AWAYENCR", OnOffCommand, 0 }, { "AWAYSAVE", NULL, AwaySaveToggle, 0 }, { "AWAYT", "AWAYT", NumberCommand, 0 }, { "BAN", NULL, Ban, SERVERREQ }, { "BANTYPE", NULL, BanType, 0 }, #ifndef LITE { "BEEP", 0, beepcmd, 0 }, #endif { "BIND", NULL, bindcmd, 0 }, { "BITCH", "BITCH", ChannelCommand, 0 }, { "BK", "BK", BanKick, SERVERREQ }, #ifdef EXTRAS { "BKI", "BKI", BanKick, SERVERREQ }, #endif { "BKLIST", "BKLIST", ChannelCommand, 0 }, #ifdef EXTRAS { "BKT", "BKT", BanKick, SERVERREQ }, #endif { "BYE", "QUIT", e_quit, NONOVICEABBREV }, { "C", NULL, CurrentChanMode, SERVERREQ }, #ifndef LITE { "CAT", NULL, catter, 0 }, #endif { "CD", NULL, cd, 0 }, { "CDBAN", NULL, CdBan, SERVERREQ }, { "CDCC", NULL, Cdcc, 0 }, { "CDE", NULL, CdExceptions, SERVERREQ }, #ifdef CELE { "CH", NULL, CurrentChanMode, SERVERREQ }, #endif { "CHANLOG", "CHANLOG", ChannelCommand, 0 }, { "CHANLOGDIR", "CHANLOGDIR", ChanLogCommand, 0 }, { "CHANLOGPOST", "CHANLOGPOST", ChanLogCommand, 0 }, { "CHANLOGPREFIX", "CHANLOGPREFIX",ChanLogCommand, 0 }, { "CHANNEL", "JOIN", e_channel, SERVERREQ }, { "CHANST", NULL, ChanStat, SERVERREQ }, { "CHAT", NULL, Chat, SERVERREQ }, { "CHPASS", NULL, ChangePassword, SERVERREQ }, #ifdef EXTRAS { "CHSIGNOFF", "CHSIGNOFF", ChannelCommand, 0 }, #endif { "CJOIN", "CJOIN", CJoin, SERVERREQ }, { "CLEAR", NULL, my_clear, 0 }, { "CLEARTAB", NULL, ClearTab, 0 }, #ifdef WANTANSI { "COLOR", NULL, SetColor, 0 }, #endif #ifndef LITE { "COMMENT", NULL, commentcmd, 0 }, #endif { "COMPRESS", "COMPRESS", ChannelCommand, 0 }, { "CONNECT", "CONNECT", send_comm, SERVERREQ }, { "CSCAN", NULL, ChannelScan, SERVERREQ }, { "CTCC", NULL, dcc, SERVERREQ }, { "CTCP", NULL, ctcp, SERVERREQ }, { "CTCPCLOAK", NULL, CTCPCloakingToggle, 0 }, { "CYCLE", NULL, Cycle, SERVERREQ }, { "DATE", "TIME", send_comm, SERVERREQ }, { "DCC", NULL, dcc, SERVERREQ }, { "DEOP", NULL, deop, SERVERREQ }, { "DEOPS", "DEOPS", NumberCommand, 0 }, { "DEOPT", "DEOPT", NumberCommand, 0 }, { "DESCRIBE", NULL, describe, SERVERREQ }, { "DHOP", "DHOP", Op, SERVERREQ }, #ifndef LITE { "DIE", "DIE", send_comm, SERVERREQ }, #endif { "DIGRAPH", NULL, digraph, 0 }, { "DIRLM", "DIRLM", DirLM, SERVERREQ }, #ifdef EXTRAS { "DIRLMK", NULL, LastMessageKick, SERVERREQ }, #endif { "DIRLN", "DIRLN", DirLM, SERVERREQ }, #ifdef EXTRAS { "DIRLNK", NULL, LastNoticeKick, SERVERREQ }, #endif { "DIRLSM", "DIRLSM", DirLSM, SERVERREQ }, { "DIRLSN", "DIRLSN", DirLSM, SERVERREQ }, { "DISCONNECT", NULL, disconnectcmd, SERVERREQ }, #ifdef EXTRAS { "DOBANS", NULL, DoBans, SERVERREQ }, #endif { "DOP", "DOP", Op, SERVERREQ }, { "DPROT", "DPROT", ChannelCommand, 0 }, { "DUMP", NULL, Dump, 0 }, { "DVOICE", "DVOICE", Op, SERVERREQ }, { "ECHO", NULL, my_echo, 0 }, { "EGO", "EGO", OnOffCommand, 0 }, { "ENCRMSG", NULL, EncryptMsg, 0 }, #ifndef LITE { "ENCRYPT", NULL, encrypt_cmd, 0 }, #endif { "ETDELIM", NULL, TopicDelimiter, 0 }, { "ETOPIC", NULL, ExtendTopic, 0 }, { "EVAL", NULL, evalcmd, 0 }, { "EXEC", NULL, execcmd, 0 }, { "EXIT", "QUIT", e_quit, NONOVICEABBREV }, { "EXTMES", "EXTMES", OnOffCommand, 0 }, { "EXTPUB", "EXTPUB", OnOffCommand, 0 }, { "FAKE", "FAKE", ChannelCommand, 0 }, { "FBK", "FBK", FilterKick, SERVERREQ }, #ifdef OPER { "FCLINE", NULL, StatsCFilter, SERVERREQ }, { "FDLINE", NULL, StatsDFilter, SERVERREQ }, #endif { "FE", NULL, foreach_handler, 0 }, { "FEC", NULL, fec, 0 }, #ifdef OPER { "FILINE", NULL, StatsIFilter, SERVERREQ }, #endif #ifdef CELE { "FING", NULL, CTCPFing, SERVERREQ }, #endif #ifndef LITE { "FINGER", NULL, Finger, 0 }, #endif { "FK", "FK", FilterKick, SERVERREQ }, #ifdef OPER { "FKLINE", NULL, StatsKFilter, SERVERREQ }, { "FLLINE", NULL, StatsLFilter, SERVERREQ }, #endif { "FLOODP", NULL, FloodProtToggle, 0 }, { "FLUSH", NULL, flush, SERVERREQ }, { "FOR", NULL, foreach_handler, 0 }, #ifdef ACID { "FORCEJOIN", "FORCEJOIN", ChannelCommand, 0 }, #endif { "FOREACH", NULL, foreach_handler, 0 }, { "FRLIST", "FRLIST", ChannelCommand, 0 }, #ifdef OPER { "FTRACE", NULL, FilterTrace, 0 }, #endif #ifndef LITE { "HASH", "HASH", send_comm, SERVERREQ }, { "HELP", NULL, help, 0 }, #endif { "HISTORY", NULL, history, 0 }, { "HOOK", NULL, hook, 0 }, { "HOP", "HOP", Op, SERVERREQ }, #ifndef LITE { "HOST", "USERHOST", userhost, SERVERREQ }, #endif #ifdef EXTRAS { "IDLEKICK", NULL, SetIdleKick, 0 }, { "IDLETIME", "IDLETIME", NumberCommand, 0 }, #endif { "IF", NULL, ifcmd, 0 }, { "IG", NULL, Ignore, 0 }, /**************************** PATCHED by Flier ******************************/ /*{ "IGNORE", NULL, ignore, 0 },*/ { "IGNORE", "IGNORE", ignore, 0 }, /****************************************************************************/ { "IGTIME", "IGTIME", NumberCommand, 0 }, #ifndef LITE { "INFO", "INFO", info, SERVERREQ }, { "INPUT", NULL, inputcmd, 0 }, #endif { "INV", NULL, Invite, SERVERREQ }, { "INVITE", "INVITE", send_comm, SERVERREQ }, { "ISON", "ISON", ison, SERVERREQ }, { "J", "JOIN", e_channel, SERVERREQ }, { "JOIN", "JOIN", e_channel, SERVERREQ }, { "K", NULL, Kick, SERVERREQ }, { "KICK", "KICK", send_channel_2args, SERVERREQ }, { "KICKONBAN", "KICKONBAN", ChannelCommand, 0 }, { "KICKONFLOOD", "KICKONFLOOD", ChannelCommand, 0 }, { "KICKOPS", "KICKOPS", ChannelCommand, 0 }, { "KICKS", "KICKS", NumberCommand, 0 }, { "KICKT", "KICKT", NumberCommand, 0 }, { "KILL", "KILL", send_2comm, SERVERREQ }, { "KNOCK", "KNOCK", CJoin, SERVERREQ }, { "KPROT", "KPROT", ChannelCommand, 0 }, { "L", NULL, Leave, SERVERREQ }, { "LASTLOG", NULL, lastlog, 0 }, { "LEAVE", "PART", send_channel_1arg, SERVERREQ }, { "LINKS", "LINKS", send_comm, NONOVICEABBREV|SERVERREQ }, { "LIST", "LIST", funny_stuff, SERVERREQ }, { "LISTBK", NULL, ListAutoBanKicks, 0 }, { "LISTF", NULL, ListFriends, 0 }, { "LISTN", NULL, ListNotify, 0 }, #ifndef LITE { "LISTS", NULL, ListServers, 0 }, #endif { "LISTW", NULL, ListWords, 0 }, { "LK", NULL, LameKick, SERVERREQ }, #ifdef EXTRAS { "LLOOK", NULL, LLook, SERVERREQ }, { "LLOOKUP", NULL, LLookUp, SERVERREQ }, #endif { "LOAD", "LOAD", load, 0 }, { "LOGON", "LOGON", OnOffCommand, 0 }, #ifndef LITE { "LS", NULL, Ls, 0 }, #endif { "LUSERS", "LUSERS", send_comm, SERVERREQ }, { "M", "PRIVMSG", e_privmsg, 0 }, #ifndef LITE { "MAP", NULL, Map, SERVERREQ }, #endif #ifdef EXTRAS { "MASSDV", "MASSDV", MegaDeVoice, SERVERREQ }, { "MASSV", "MASSV", MegaVoice, SERVERREQ }, #endif { "MC", NULL, ModeClear, SERVERREQ }, { "MDHOP", NULL, MegaDehalfop, SERVERREQ }, { "MDOP", NULL, MegaDeop, SERVERREQ }, { "ME", NULL, me, SERVERREQ }, { "MHOP", NULL, MassHalfop, SERVERREQ }, #ifdef WANTANSI { "MIRC", "MIRC", OnOffCommand, 0 }, #endif { "MK", NULL, MassKick, SERVERREQ }, #ifdef OPER { "MKILL", NULL, MassKill, SERVERREQ }, #endif #ifndef LITE { "MLIST", NULL, mlist, 0 }, { "MLOAD", NULL, mload, 0 }, #endif { "MODE", "MODE", send_channel_nargs, SERVERREQ }, #ifdef EXTRAS { "MODELOCK", NULL, ModeLocked, 0 }, { "MODEUNLOCK", NULL, ModeUnlocked, 0 }, #endif { "MOP", NULL, MassOp, SERVERREQ }, { "MOTD", "MOTD", send_comm, SERVERREQ }, /* Patched by Zakath */ { "MREOP", NULL, MegaReop, SERVERREQ }, /* ***************** */ #ifdef EXTRAS { "MSAY", NULL, MSay, SERVERREQ }, #endif { "MSG", "PRIVMSG", e_privmsg, 0 }, #ifndef LITE { "MULTK", NULL, MultiKick, 0 }, #endif { "N", "NOTICE", e_privmsg, SERVERREQ }, { "NAMES", "NAMES", funny_stuff, SERVERREQ }, { "NET", NULL, Net, 0 }, { "NEWHOST", NULL, NewHost, SERVERREQ }, { "NEWUSER", NULL, NewUser, SERVERREQ }, { "NHPROT", NULL, NHProtToggle, 0 }, { "NICK", "NICK", e_nick, SERVERREQ }, #ifdef EXTRAS { "NICKCHAN", "NICKCHAN", OnOffCommand, 0 }, #endif { "NICKS", "NICKS", NumberCommand, 0 }, { "NICKT", "NICKT", NumberCommand, 0 }, { "NOCHAT", NULL, NoChat, 0 }, { "NOIG", NULL, NoIgnore, 0 }, { "NOKEY", NULL, ClearKey, SERVERREQ }, #ifndef LITE { "NOTE", "NOTE", send_comm, SERVERREQ }, { "NOTEPAD", NULL, NotePad, 0 }, #endif { "NOTICE", "NOTICE", e_privmsg, SERVERREQ }, { "NOTIFY", NULL, notify, SERVERREQ }, { "NPROT", "NPROT", ChannelCommand, 0 }, #ifndef LITE { "NSLOOKUP", NULL, Nslookup, 0 }, #endif { "NTFYMODE", NULL, NotifyModeToggle, 0 }, { "NWHOIS", NULL, NickStat, 0 }, { "ON", NULL, on, 0 }, { "OP", "OP", Op, SERVERREQ }, { "OPER", "OPER", oper, SERVERREQ }, { "ORIGNICK", "ORIGNICK", ChannelCommand, 0 }, { "ORIGNTIME", "ORIGNTIME", NumberCommand, 0 }, #if defined(OPERVISION) && defined(WANTANSI) { "OV", NULL, OperVision, 0 }, #endif { "P", NULL, pingcmd, SERVERREQ }, #ifndef LITE { "PARSEKEY", NULL, parsekeycmd, 0 }, #endif { "PART", "PART", send_channel_1arg, SERVERREQ }, { "PASSWD", NULL, Password, 0 }, { "PING", NULL, pingcmd, SERVERREQ }, { "PINGME", NULL, PingMe, SERVERREQ }, { "PLAYBACK", "PLAYBACK", PlayBack, 0 }, #ifndef LITE { "PURGE", NULL, Purge, 0 }, #endif { "QUERY", NULL, query, 0 }, #ifndef LITE { "QUEUE", NULL, queuecmd, 0 }, #endif #ifdef CELE { "QUICKSTAT", NULL, Cquickstat, 0 }, #endif { "QUIT", "QUIT", e_quit, NONOVICEABBREV }, { "QUOTE", NULL, quote, SERVERREQ }, #ifdef EXTRAS { "RANLK", NULL, RandomLamerKick, SERVERREQ }, #endif #ifdef SCKICKS { "RANSK", NULL, RandomScatterKick, SERVERREQ }, #endif #ifndef LITE { "RBIND", 0, rbindcmd, 0 }, #endif { "RE", NULL, redirect, 0 }, { "RECONNECT", NULL, ReconnectServer, SERVERREQ }, { "REDIRECT", NULL, redirect, 0 }, { "REHASH", "REHASH", send_comm, SERVERREQ }, #ifdef CELE { "RELM", "DIRLM", DirLM, SERVERREQ }, { "RELN", "DIRLN", DirLM, SERVERREQ }, #endif { "RELOAD", NULL, Reset, 0 }, { "REMBK", NULL, RemoveAutoBanKick, 0 }, { "REMCHAN", "REM", AddChannel, 0 }, { "REMF", NULL, RemoveFriend, 0 }, { "REMFCHAN", "REM", AddFriendChannel, 0 }, { "REMFFLAG", "REM", AddFriendPrivs, 0 }, { "REMLOG", NULL, RemoveLog, 0 }, { "REMN", NULL, RemoveNotify, 0 }, #ifndef LITE { "REMS", NULL, RemoveServer, 0 }, #endif { "REMW", NULL, RemoveWord, 0 }, #ifndef LITE { "REPEAT", NULL, repeatcmd, 0 }, #endif { "REPWORD", NULL, ReplyWord, 0 }, #ifndef LITE { "REQUEST", NULL, ctcp, SERVERREQ }, { "RESTART", "RESTART", send_comm, SERVERREQ }, #endif { "S", NULL, FServer, 0 }, { "SAVE", NULL, save_settings, 0 }, { "SAY", empty_string, do_send_text, SERVERREQ }, { "SB", NULL, ShowBans, SERVERREQ }, #ifdef CELE { "SC", NULL, ChannelScan, SERVERREQ }, #endif { "SEND", NULL, do_send_text, SERVERREQ }, #ifndef LITE { "SENDLINE", empty_string, sendlinecmd, 0 }, #endif { "SERVER", NULL, servercmd, 0 }, #ifndef LITE { "SERVLIST", "SERVLIST", send_comm, SERVERREQ }, #endif { "SERVNOTICE", "SERVNOTICE", OnOffCommand, 0 }, { "SET", NULL, set_variable, 0 }, { "SETAWAY", NULL, SetAway, SERVERREQ }, { "SETBACK", NULL, SetBack, SERVERREQ }, #ifndef LITE { "SETTINGS", NULL, Settings, 0 }, #endif { "SHOWAWAY", "SHOWAWAY", ChannelCommand, 0 }, #ifdef EXTRAS { "SHOWIDLE", NULL, ShowIdle, 0 }, #endif { "SHOWKILL", NULL, ShowKill, 0 }, { "SHOWNICK", "SHOWNICK", OnOffCommand, 0 }, #ifdef EXTRAS { "SHOWSIGN", "SHOWSIGN", OnOffCommand, 0 }, #endif { "SHOWUSER", NULL, ShowUser, SERVERREQ }, { "SHOWWALLOP", "SHOWWALLOP", OnOffCommand, 0 }, { "SIGNOFF", "QUIT", e_quit, NONOVICEABBREV }, /* Patched by Zakath */ { "SINFO", "LUSERS", send_comm, SERVERREQ }, /* ***************** */ #ifdef SCKICKS { "SK", NULL, ScatterKick, SERVERREQ }, #endif { "SLEEP", NULL, sleepcmd, 0 }, { "SPING", NULL, ServerPing, SERVERREQ }, #ifndef LITE { "SQUERY", "SQUERY", send_squery, SERVERREQ }, #endif { "SQUIT", "SQUIT", send_2comm, SERVERREQ }, #ifndef LITE { "STACK", NULL, stackcmd, 0 }, #endif { "STAMP", "STAMP", OnOffCommand, 0 }, { "STATS", "STATS", send_comm, SERVERREQ }, #ifdef CELE { "STATUS", NULL, Cstatusbar, SERVERREQ }, #endif #ifndef LITE { "SUMMON", "SUMMON", send_comm, SERVERREQ }, #endif { "SVE", NULL, ScrollZSave, 0 }, #ifndef LITE { "SWITCH", NULL, switchcmd, 0 }, #endif { "SZINFO", NULL, ScrollZInfo, 0 }, { "T", NULL, Topic, SERVERREQ }, #ifdef ACID { "TAG", NULL, TagNick, SERVERREQ }, #endif { "TBAN", NULL, TBan, SERVERREQ }, #ifdef MGS_ { "TERMINATE", NULL, Terminate, 0 }, #endif { "TIME", "TIME", send_comm, SERVERREQ }, { "TIMER", "TIMER", timercmd, 0 }, #ifdef OPER { "TKILL", NULL, TraceKill, SERVERREQ }, #endif { "TOPIC", "TOPIC", send_topic, SERVERREQ }, #ifdef EXTRAS { "TOPICLOCK", "TOPICLOCK", TopicLocked, 0 }, { "TOPICUNLOCK", "TOPICUNLOCK", TopicLocked, 0 }, #endif /**************************** PATCHED by Flier ******************************/ /*{ "TRACE", "TRACE", send_comm, 0 },*/ /* Patched by Zakath */ #ifdef CELE { "TRACE", NULL, ScrollZTrace, SERVERREQ }, #else { "TRACE", "TRACE", send_comm, SERVERREQ }, #endif /****************************************************************************/ #ifndef LITE { "TYPE", NULL, type, 0 }, #endif { "UMODE", NULL, UserMode, SERVERREQ }, { "UNBAN", NULL, Unban, SERVERREQ }, { "UNFLASH", NULL, UnFlash, 0 }, #ifdef CELE { "UPTIME", NULL, ExecUptime, 0 }, #endif { "URL", NULL, URLSave, 0 }, { "URLCATCH", "URLCATCH", URLCatchToggle, 0 }, { "USERHOST", NULL, userhost, SERVERREQ }, { "USERS", "USERS", send_comm, SERVERREQ }, { "VER", NULL, Version, SERVERREQ }, { "VERSION", "VERSION", version, 0 }, /**************************** PATCHED by Flier ******************************/ /*{ "VOICE", "VOICE", e_privmsg, SERVERREQ },*/ /****************************************************************************/ { "VOICE", "VOICE", Op, SERVERREQ }, { "W", "WHO", who, SERVERREQ }, { "WAIT", NULL, waitcmd, SERVERREQ }, /**************************** PATCHED by Flier ******************************/ /*{ "WALL", "WALL", e_wall, SERVERREQ },*/ { "WALL", NULL, ChanWallOp, SERVERREQ }, #ifndef LITE { "WALLMSG", "WALL", e_wall, SERVERREQ }, /****************************************************************************/ { "WALLOPS", "WALLOPS", e_wall, SERVERREQ }, #endif #ifdef ACID { "WHEREIS", NULL, WhereIs, SERVERREQ }, { "WHERELIST", NULL, WhereList, 0 }, #endif #ifndef LITE { "WHICH", "WHICH", load, 0 }, #endif { "WHILE", NULL, whilecmd, 0 }, { "WHO", "WHO", who, SERVERREQ }, { "WHOIS", "WHOIS", whois, SERVERREQ }, { "WHOLEFT", NULL, WhoLeft, 0 }, { "WHOWAS", "WHOWAS", whois, SERVERREQ }, { "WI", "WHOIS", whois, SERVERREQ }, { "WII", "WII", whois, SERVERREQ }, { "WINDOW", NULL, windowcmd, 0 }, #ifdef OPER { "WKILL", NULL, WhoKill, SERVERREQ }, #endif { "WW", "WHOWAS", whois, SERVERREQ }, #ifndef LITE { "XECHO", "XECHO", my_echo, 0 }, { "XTRA", "XTRA", e_privmsg, SERVERREQ }, { "XTYPE", NULL, xtypecmd, 0 }, #endif { NULL, NULL, commentcmd, 0 } }; /* number of entries in irc_command array */ # define NUMBER_OF_COMMANDS (sizeof(irc_command) / sizeof(IrcCommand)) - 2 /* * 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. */ static IrcCommand * find_command(com, cnt) char *com; int *cnt; { size_t len; if (com && (len = strlen(com))) { int min, max, pos, old_pos = -1, c; min = 1; max = NUMBER_OF_COMMANDS + 1; while (1) { pos = (max + min) / 2; if (pos == old_pos) { *cnt = 0; return ((IrcCommand *) 0); } old_pos = pos; c = strncmp(com, irc_command[pos].name, len); if (c == 0) break; else if (c > 0) min = pos; else max = pos; } *cnt = 0; (*cnt)++; min = pos - 1; while ((min > 0) && (strncmp(com, irc_command[min].name, len) == 0)) { (*cnt)++; min--; } min++; max = pos + 1; while ((max < NUMBER_OF_COMMANDS + 1) && (strncmp(com, irc_command[max].name, len) == 0)) { (*cnt)++; max++; } if (*cnt) { if (strlen(irc_command[min].name) == len) *cnt *= -1; else if (*cnt == 1 && irc_command[min].flags&NONOVICEABBREV && get_int_var(NOVICE_VAR)) { say("As a novice you may not abbreviate the %s command", irc_command[min].name); *cnt=0; return ((IrcCommand *) 0); } return (&(irc_command[min])); } else return ((IrcCommand *) 0); } else { *cnt = -1; return (irc_command); } } /*ARGSUSED*/ static void ctcp(command, args, subargs) char *command, *args, *subargs; { char *to, *tag; int ctcptype; if ((to = next_arg(args, &args)) != NULL) { if (!strcmp(to, "*")) if ((to = get_channel_by_refnum(0)) == NULL) to = irczero; if ((tag = next_arg(args, &args)) != NULL) upper(tag); else tag = "VERSION"; if ((ctcptype = in_ctcp()) == -1) my_echo(NULL, "*** You may not use the CTCP command in an ON CTCP_REPLY!", empty_string); else { if (args && *args) send_ctcp(ctcp_type[ctcptype], to, tag, "%s", args); else send_ctcp(ctcp_type[ctcptype], to, tag, NULL); } } else say("Request from whom?"); } /*ARGSUSED*/ static void hook(command, args, subargs) char *command, *args, *subargs; { if (*args) do_hook(HOOK_LIST, "%s", args); else say("Must supply an argument to HOOK"); } /*ARGSUSED*/ static void dcc(command, args, subargs) char *command, *args, *subargs; { if (*args) process_dcc(args); else /**************************** PATCHED by Flier ******************************/ /*dcc_list((char *) NULL);*/ Cdcc(NULL,NULL,NULL); /****************************************************************************/ } /*ARGSUSED*/ static void deop(command, args, subargs) char *command, *args, *subargs; { send_to_server("MODE %s -o", get_server_nickname(from_server)); } static void funny_stuff(command, args, subargs) char *command, *args, *subargs; { char *arg, *cmd = (char *) 0, *stuff, *s; int min = 0, max = 0, flags = 0; size_t len; /*************************** PATCHED by Flier ****************************/ if (!(args && *args)) { say("Type %s -YES if you really mean it",command); return; } /*************************************************************************/ stuff = empty_string; while ((arg = next_arg(args, &args)) != NULL) { len = strlen(arg); malloc_strcpy(&cmd, arg); upper(cmd); if (strncmp(cmd, "-MAX", len) == 0) { if ((arg = next_arg(args, &args)) != NULL) max = atoi(arg); } else if (strncmp(cmd, "-MIN", len) == 0) { if ((arg = next_arg(args, &args)) != NULL) min = atoi(arg); } else if (strncmp(cmd, "-ALL", len) == 0) { flags &= ~(FUNNY_PUBLIC | FUNNY_PRIVATE); } else if (strncmp(cmd, "-PUBLIC", len) == 0) { flags |= FUNNY_PUBLIC; flags &= ~FUNNY_PRIVATE; } else if (strncmp(cmd, "-PRIVATE", len) == 0) { flags |= FUNNY_PRIVATE; flags &= ~FUNNY_PUBLIC; } else if (strncmp(cmd, "-TOPIC", len) == 0) flags |= FUNNY_TOPIC; else if (strncmp(cmd, "-WIDE", len) == 0) flags |= FUNNY_WIDE; else if (strncmp(cmd, "-USERS", len) == 0) flags |= FUNNY_USERS; else if (strncmp(cmd, "-NAME", len) == 0) flags |= FUNNY_NAME; /*************************** PATCHED by Flier ****************************/ /*else*/ else if (my_strnicmp(arg,"-YES",len)) /*************************************************************************/ stuff = arg; new_free(&cmd); } set_funny_flags(min, max, flags); if (strcmp(stuff, "*") == 0) if (!(stuff = get_channel_by_refnum(0))) stuff = empty_string; if ((s = index(stuff, '*')) && !is_on_channel(stuff, from_server, get_server_nickname(from_server))) { funny_match(stuff); send_to_server("%s %s", command, empty_string); } else { funny_match(NULL); send_to_server("%s %s", command, stuff); } } /*ARGSUSED*/ /**************************** PATCHED by Flier ******************************/ /*static void*/ void /****************************************************************************/ waitcmd(command, args, subargs) char *command, *args, *subargs; { #ifdef _Windows yell("WAIT is not available under Windows"); #else /* Windows */ int wait_index; char *flag; char *procindex; int cmd = 0; size_t len; u_char buffer[BIG_BUFFER_SIZE+1]; while (args && *args == '-') { flag = next_arg(args, &args); len = strlen(++flag); if (!my_strnicmp("CMD", flag, len)) { cmd = 1; break; } else yell("Unknown argument to WAIT: %s", flag); } if ((procindex = next_arg(args, &args)) && *procindex == '%' && (wait_index = get_process_index(&procindex)) != -1) { if (is_process_running(wait_index)) { if (cmd) { add_process_wait(wait_index, args?args:empty_string); return; } else set_wait_process(wait_index); } else { say("Not a valid process!"); return; } } else if (cmd) { WaitCmd *new; snprintf(CP(buffer), sizeof buffer, "%s %s", procindex, args); new = (WaitCmd *) new_malloc(sizeof(WaitCmd)); new->stuff = NULL; malloc_strcpy(&new->stuff, buffer); new->next = NULL; if (end_wait_list) end_wait_list->next = new; end_wait_list = new; if (!start_wait_list) start_wait_list = new; send_to_server("%s", wait_nick); return; } else send_to_server("%s", lame_wait_nick); if (waiting) yell("WAIT has been called recursively."); waiting++; irc_io(NULL, NULL, 0, 1); waiting--; #endif /* _Windows */ } int check_wait_command(nick) char *nick; { if (waiting && !strcmp(nick, lame_wait_nick)) { irc_io_loop = 0; return 1; } if (start_wait_list && !strcmp(nick, wait_nick)) { if (start_wait_list->stuff) { parse_command(start_wait_list->stuff, 0, empty_string); new_free(&start_wait_list->stuff); } start_wait_list = start_wait_list->next; return 1; } return 0; } /*ARGSUSED*/ static void redirect(command, args, subargs) char *command, *args, *subargs; { char *to; if ((to = next_arg(args, &args)) != NULL) { /**************************** PATCHED by Flier ******************************/ DCC_list *Client; if (*to=='=') { to++; if (!(Client=dcc_searchlist((char *) 0,to,DCC_CHAT,0,(char *) 0)) || !(Client->flags&DCC_ACTIVE)) { say("No active DCC CHAT connection with %s",to); return; } to--; } /****************************************************************************/ if (!strcmp(to, "*")) if (!(to = get_channel_by_refnum(0))) { say("Must be on a channel to redirect to '*'"); return; } if (!my_stricmp(to, get_server_nickname(from_server))) { say("You may not redirect output to yourself"); return; } window_redirect(to, from_server); server_list[from_server].sent = 0; parse_line((char *) 0, args, (char *) 0, 0, 0, 0); if (server_list[from_server].sent) send_to_server("%s", current_screen->redirect_token, current_screen->screennum); else window_redirect(NULL, from_server); } else /**************************** PATCHED by Flier ******************************/ /*say("Usage: REDIRECT ");*/ say("Usage: REDIRECT "); /****************************************************************************/ } /*ARGSUSED*/ static void sleepcmd(command, args, subargs) char *command, *args, *subargs; { #ifndef _Windows char *arg; if ((arg = next_arg(args, &args)) != NULL) sleep((unsigned)atoi(arg)); else say("SLEEP: you must specify the amount of time to sleep (in seconds)"); #else say("SLEEP: Not available under Windows"); #endif /* _Windows */ } /* * my_echo: simply displays the args to the screen, or, if it's XECHO, * processes the flags first, then displays the text on * the screen */ static void my_echo(command, args, subargs) char *command, *args, *subargs; { unsigned int display; int lastlog_level = 0; int from_level = 0; char *flag_arg; int temp; Window *old_to_window; save_message_from(); old_to_window = to_window; if (command && *command == 'X') { while (args && *args == '-') { flag_arg = next_arg(args, &args); switch(flag_arg[1]) { case 'L': case 'l': if (!(flag_arg = next_arg(args, &args))) break; if ((temp = parse_lastlog_level(flag_arg)) != 0) { lastlog_level = set_lastlog_msg_level(temp); from_level = message_from_level(temp); } break; case 'W': case 'w': if (!(flag_arg = next_arg(args, &args))) break; if (isdigit(*flag_arg)) to_window = get_window_by_refnum((unsigned)atoi(flag_arg)); else to_window = get_window_by_name(flag_arg); lastlog_level = set_lastlog_msg_level(LOG_CRAP); from_level = message_from_level(LOG_CRAP); break; } if (!args) args = empty_string; } } display = window_display; window_display = 1; put_it("%s", args); window_display = display; if (lastlog_level) set_lastlog_msg_level(lastlog_level); if (from_level) message_from_level(from_level); restore_message_from(); to_window = old_to_window; } /* */ static void oper_password_received(data, line) char *data; char *line; { send_to_server("OPER %s %s", data, line); /**************************** PATCHED by Flier ******************************/ bzero(line,strlen(line)); say("Password's memory location has been cleared"); /****************************************************************************/ } /* oper: the OPER command. */ /*ARGSUSED*/ static void oper(command, args, subargs) char *command, *args, *subargs; { char *password; char *nick; oper_command = 1; if (!(nick = next_arg(args, &args))) nick = nickname; if (!(password = next_arg(args, &args))) { add_wait_prompt("Operator Password:", oper_password_received, nick, WAIT_PROMPT_LINE); return; } send_to_server("OPER %s %s", nick, password); /**************************** PATCHED by Flier ******************************/ #ifdef BLAXTHOS if (EncryptPassword) { int len = strlen(EncryptPassword); if (OperNick) new_free(&OperNick); OperNick = (char *) new_malloc(2 * strlen(nick) + 16); if (OperNick) { *OperNick = '\0'; EncryptString(OperNick, nick, EncryptPassword, 2 * strlen(nick) - 1, 1); } if (OperPassword) new_free(&OperPassword); OperPassword = (char *) new_malloc(2 * len + 16); if (OperPassword) { *OperPassword = '\0'; EncryptString(OperPassword, password, EncryptPassword, 2 * len - 1, 1); } if (OperNick && OperPassword) say("OPER password has been stored"); else say("OPER password not stored - probably memory allocation failure"); } else say("Master password not defined - OPER password not stored!"); #endif bzero(password, strlen(password)); say("Password's memory location has been cleared"); /****************************************************************************/ } /* Full scale abort. Does a "save" into the filename in line, and then does a coredump */ #ifndef LITE static void abortcmd(command, args, subargs) char *command, *args, *subargs; { char *filename = next_arg(args, &args); if (!filename) filename = "irc.aborted"; save_which = SFLAG_ALIAS | SFLAG_BIND | SFLAG_ON | SFLAG_SET | SFLAG_NOTIFY | SFLAG_DIGRAPH; really_save(filename, "y"); #ifdef ALLOC_DEBUG alloc_cmd("ALLOC", "d", (char *) 0); #endif abort(); } #endif /* LITE */ /* This generates a file of your ircII setup */ static void really_save(file, line) char *file; char *line; { /**************************** PATCHED by Flier ******************************/ int oldumask; /****************************************************************************/ FILE *fp; if (*line != 'y' && *line != 'Y') return; /**************************** PATCHED by Flier ******************************/ oldumask=umask(0177); /****************************************************************************/ if ((fp = fopen(file, "w")) != NULL) { if (save_which & SFLAG_BIND) save_bindings(fp, save_do_all); if (save_which & SFLAG_ON) save_hooks(fp, save_do_all); if (save_which & SFLAG_NOTIFY) save_notify(fp); if (save_which & SFLAG_SET) save_variables(fp, save_do_all); if (save_which & SFLAG_ALIAS) save_aliases(fp, save_do_all); if (save_which & SFLAG_DIGRAPH) save_digraphs(fp); fclose(fp); say("IRCII settings saved to %s", file); } else say("Error opening %s: %s", file, strerror(errno)); /**************************** PATCHED by Flier ******************************/ umask(oldumask); /****************************************************************************/ } /* save_settings: saves the current state of IRCII to a file */ /*ARGSUSED*/ static void save_settings(command, args, subargs) char *command, *args, *subargs; { char buffer[BIG_BUFFER_SIZE+1]; char *arg, *temp; int all = 1, save_force = 0; save_which = save_do_all = 0; while ((arg = next_arg(args, &args)) != NULL) { if ('-' == *arg) { char *cmd = NULL; all = 0; malloc_strcpy(&cmd, arg+1); upper(cmd); if (0 == strncmp("ALIAS", cmd, 5)) save_which |= SFLAG_ALIAS; else if (0 == strncmp("ASSIGN", cmd, 6)) save_which |= SFLAG_ALIAS; else if (0 == strncmp("BIND", cmd, 4)) save_which |= SFLAG_BIND; else if (0 == strncmp("ON", cmd, 2)) save_which |= SFLAG_ON; else if (0 == strncmp("SET", cmd, 3)) save_which |= SFLAG_SET; else if (0 == strncmp("NOTIFY", cmd, 6)) save_which |= SFLAG_NOTIFY; else if (0 == strncmp("DIGRAPH", cmd, 7)) save_which |= SFLAG_DIGRAPH; else if (0 == strncmp("ALL", cmd, 3)) save_do_all = 1; else if (0 == strncmp("FORCE", cmd, 3)) save_force = 1; else { say("%s: unknown argument", arg); new_free(&cmd); return; } new_free(&cmd); continue; } #ifdef DAEMON_UID if (getuid() == DAEMON_UID) { say("You may only use the default value"); return; } #endif /* DAEMON_UID */ temp = expand_twiddle(arg); if (temp) { if (ircrc_file) new_free(&ircrc_file); ircrc_file = temp; } else { say("Unknown user"); return; } } if (all) save_which = SFLAG_ALIAS | SFLAG_BIND | SFLAG_ON | SFLAG_SET | /**************************** PATCHED by Flier ******************************/ /*SFLAG_NOTIFY | SFLAG_DIGRAPH;*/ SFLAG_DIGRAPH; /****************************************************************************/ if (dumb || save_force) really_save(ircrc_file, "y"); /* REAL dumb! -lynx */ else { snprintf(buffer, sizeof buffer, "Really write %s? ", ircrc_file); add_wait_prompt(buffer, really_save, ircrc_file, WAIT_PROMPT_LINE); } } /* * do_channel : checks whether the channel has already been joined and * returns the channel's name if not */ static char * /**************************** Patched by Flier ******************************/ /*do_channel(chan, force)*/ do_channel(chan, force, nowho) char *chan; int force; int nowho; /****************************************************************************/ { ChannelList *channel; char *old; /**************************** PATCHED by Flier ******************************/ /* use serv_ind instead of curr_scr_win->server because we might * be called from hook or from timer and in that case curr_scr_win * might not have proper server context */ int serv_ind = from_server; /****************************************************************************/ if (serv_ind < 0) return (char *) 0; channel = lookup_channel(chan, serv_ind, CHAN_NOUNLINK); /**************************** PATCHED by Flier ******************************/ /* if you try to join same channel twice and you reached limit for maximum number of channels this fix prevents client from removing channel from memory */ if (channel && channel->connected == CHAN_JOINING) return(NULL); /****************************************************************************/ if (is_bound(chan, serv_ind) && channel && channel->window != curr_scr_win) say("Channel %s is bound", chan); else if (is_on_channel(chan, serv_ind, get_server_nickname(serv_ind))) { is_current_channel(chan, serv_ind, 1); say("You are now talking to channel %s", set_channel_by_refnum(0, chan)); update_all_windows(); } else { /* only do this if we're actually joining a new channel */ if (get_int_var(NOVICE_VAR)) { if ((old = get_channel_by_refnum(0)) && strcmp(old, irczero)) send_to_server("PART %s", old); } /**************************** Patched by Flier ******************************/ /* we should not add !!channel on ircd 2.10 as they denote channel creation */ if (*chan == '!' && (get_server_version(serv_ind) == Server2_10 || get_server_version(serv_ind) == Server2_11)) return(chan); /*add_channel(chan, serv_ind, CHAN_JOINING, (ChannelList *) 0);*/ add_channel(chan, serv_ind, CHAN_JOINING, NULL, NULL, nowho); /****************************************************************************/ force = 1; } if (force) return chan; else return (char *) 0; } /**************************** PATCHED by Flier ******************************/ /* fix_channel: add # in front of channel if necessary */ static char *fix_channel(channel) char *channel; { static char chanbuf[mybufsize / 2 + 2]; if (!is_channel(channel)) { strcpy(chanbuf, "#"); strmcat(chanbuf, channel, sizeof(chanbuf)); } else strmcpy(chanbuf, channel, sizeof(chanbuf)); return(chanbuf); } /****************************************************************************/ /* * e_channel: does the channel command. I just added displaying your current * channel if none is given */ /**************************** PATCHED by Flier ******************************/ /*static void*/ void /****************************************************************************/ e_channel(command, args, subargs) char *command, *args, *subargs; { char *chan; size_t len; char *chanstr = (char *) 0, *ptr; int force = 0; /**************************** PATCHED by Flier ******************************/ char *chankey; int nowho = 0; /****************************************************************************/ if (get_server_version(from_server) == Server2_5) command = "CHANNEL"; save_message_from(); message_from((char *) 0, LOG_CURRENT); /* XXX should delete this */ /**************************** PATCHED by Flier ******************************/ /* we are /CYCLEing */ if (args == subargs) { send_to_server("%s %s", command, args); restore_message_from(); return; } /****************************************************************************/ if ((chan = next_arg(args, &args)) != NULL) { len = MAX(2, strlen(chan)); if (my_strnicmp(chan, "-force", len) == 0) { force = 1; if ((chan = next_arg(args, &args)) == NULL) goto out; /* XXX: allow /alias join join -force */ len = MAX(2, strlen(chan)); } /**************************** Patched by Flier ******************************/ if (my_strnicmp(chan, "-nowho", len) == 0) { if ((chan = next_arg(args, &args)) == NULL) goto out; /* XXX: allow /alias join join -force */ nowho = 2; len = MAX(2, strlen(chan)); } /****************************************************************************/ if (my_strnicmp(chan, "-invite", len) == 0) { if (invite_channel) { /**************************** Patched by Flier ******************************/ /*if ((ptr = do_channel(invite_channel, force)))*/ if ((ptr = do_channel(invite_channel, force, nowho))) /*send_to_server("%s %s %s", command, invite_channel, args);*/ { chankey = CheckJoinKey(invite_channel); send_to_server("%s %s %s %s",command, invite_channel, args, chankey); } /****************************************************************************/ else say("You are already on %s ?", invite_channel); } else say("You have not been invited to a channel!"); } else { malloc_strcpy(&chanstr, chan); chan = chanstr; if (get_int_var(NOVICE_VAR)) chanstr = strtok(chanstr, ","); ptr = strtok(chanstr, ","); /**************************** PATCHED by Flier ******************************/ ptr = fix_channel(ptr); /*if ((ptr = do_channel(ptr, force)) && *ptr)*/ if ((ptr = do_channel(ptr, force, nowho)) && *ptr) /*send_to_server("%s %s %s", command, ptr, args);*/ { chankey = CheckJoinKey(ptr); send_to_server("%s %s %s %s", command, ptr, args, chankey); } /****************************************************************************/ while ((ptr = strtok(NULL, ","))) /**************************** PATCHED by Flier ******************************/ /*if ((ptr = do_channel(ptr, force)) && *ptr) send_to_server("%s %s %s", command, ptr, args);*/ { ptr = fix_channel(ptr); if (RateLimitJoin(from_server)) { ChannelList *newchan, *tmpchan; chankey = CheckJoinKey(ptr); newchan = (ChannelList *) new_malloc(sizeof(ChannelList)); newchan->channel = (char *) 0; newchan->key = (char *) 0; newchan->s_mode = (char *) 0; newchan->topicstr = (char *) 0; malloc_strcpy(&newchan->channel, ptr); malloc_strcpy(&newchan->key, chankey); malloc_strcpy(&newchan->s_mode, args); malloc_strcpy(&newchan->topicstr, command); newchan->status = force; newchan->connected = nowho; newchan->next = NULL; for (tmpchan = server_list[from_server].ChanPendingList; tmpchan && tmpchan->next; ) { tmpchan = tmpchan->next; } if (tmpchan) tmpchan->next = newchan; else server_list[from_server].ChanPendingList = newchan; } else { if ((ptr = do_channel(ptr, force, nowho)) && *ptr) { chankey = CheckJoinKey(ptr); send_to_server("%s %s %s %s", command, ptr, args, chankey); } } } /****************************************************************************/ new_free(&chan); } } else out: list_channels(); restore_message_from(); } /* comment: does the /COMMENT command, useful in .ircrc */ /*ARGSUSED*/ static void commentcmd(command, args, subargs) char *command, *args, *subargs; { /* nothing to do... */ } /* * e_nick: does the /NICK command. Records the users current nickname and * sends the command on to the server */ /*ARGSUSED*/ /**************************** PATCHED by Flier ******************************/ /*static void*/ void /****************************************************************************/ e_nick(command, args, subargs) char *command, *args, *subargs; { char *nick; if (!(nick = next_arg(args, &args))) { say("Your nickname is %s", get_server_nickname(get_window_server(0))); return; } /*************************** PATCHED by Flier ****************************/ /*#if 0*/ /* blundernet */ /*************************************************************************/ if ((nick = check_nickname(nick)) != NULL) { /*************************** PATCHED by Flier ****************************/ /*#endif*/ LastNick=time((time_t *) 0); /*************************************************************************/ send_to_server("NICK %s", nick); /**************************** PATCHED by Flier ******************************/ /* fix by Flier: this totally confuses client if connection to server fails, so only do this if we are not connected to server if (attempting_to_connect)*/ if (attempting_to_connect && !server_list[from_server].connected) /*set_server_nickname(get_window_server(0),nick); fix by Flier: use from_server here otherwise client gets totally confused when using /timer nick and the window where you issued /timer is not connected yet */ set_server_nickname(from_server,nick); /****************************************************************************/ if (get_server_version(from_server) == Server2_5) add_to_whois_queue(nick, whois_nickname, NULL); /**************************** PATCHED by Flier ******************************/ /*#if 0*/ /* blundernet */ /****************************************************************************/ } else say("Bad nickname"); /**************************** PATCHED by Flier ******************************/ /*#endif*/ /****************************************************************************/ } /* version: does the /VERSION command with some IRCII version stuff */ static void version(command, args, subargs) char *command, *args, *subargs; { char *host; if ((host = next_arg(args, &args)) != NULL) send_to_server("%s %s", command, host); else { /**************************** PATCHED by Flier ******************************/ /*say("Client: ircII %s", irc_version);*/ say("Client: ircII %s + ScrollZ %s [%s]", irc_version, ScrollZver1, VersionInfo); /****************************************************************************/ send_to_server("%s", command); } } /* * info: does the /INFO command. I just added some credits * I updated most of the text -phone, feb 1993. */ #ifndef LITE static void info(command, args, subargs) char *command, *args, *subargs; { if (!args || !*args) { say("ircii: originally written by Michael Sandrof"); say(" versions 2.1 to 2.2pre7 by Troy Rollo"); say(" development continued by matthew green"); say(" e-mail: mrg@eterna.com.au irc: phone"); say(" copyright (c) 1990-2003"); say(" do a /help ircii copyright for the full copyright"); say(" ircii includes software developed by the university"); say(" of california, berkeley and its contributors"); say(""); say("ircii contributors"); say(""); say(" \tMichael Sandrof Mark T. Dameu"); say(" \tStellan Klebom Carl v. Loesch"); say(" \tTroy Rollo Martin Friedrich"); say(" \tMichael Weber Bill Wisner"); say(" \tRiccardo Facchetti Stephen van den Berg"); say(" \tVolker Paulsen Kare Pettersson"); say(" \tIan Frechette Charles Hannum"); say(" \tmatthew green christopher williams"); say(" \tJonathan Lemon Brian Koehmstedt"); say(" \tNicolas Pioch Brian Fehdrau"); say(" \tDarren Reed Jeff Grills"); say(" \tJeremy Nelson Philippe Levan"); say(" \tScott Reynolds Glen McCready"); say(" \tChristopher Kalt Joel Yliluoma"); } send_to_server("%s %s", command, args); } #endif void /**************************** PATCHED by Flier ******************************/ /*ison_now(notused, nicklist, notused2)*/ ison_now(notused,notused2,nicklist) /****************************************************************************/ WhoisStuff *notused; char *nicklist, *notused2; { if (do_hook(current_numeric, "%s", nicklist)) /**************************** Patched by Flier ******************************/ /*put_it("%s Currently online: %s", numeric_banner(), nicklist);*/ put_it("%sCurrently online: %s", numeric_banner(), nicklist); /****************************************************************************/ } static void ison(command, args, subargs) char *command; char *args, *subargs; { if (!args[strspn(args, " ")]) args = get_server_nickname(from_server); add_ison_to_whois(args, ison_now); } /* * userhost: Does the USERHOST command. Need to split up the queries, * since the server will only reply to 5 at a time. */ /**************************** PATCHED by Flier ******************************/ /*static void*/ void /****************************************************************************/ userhost(command, args, subargs) char *command, *args, *subargs; { int n = 0, total = 0, userhost_cmd = 0; char *nick; char buffer[BIG_BUFFER_SIZE+1]; while ((nick = next_arg(args, &args)) != NULL) { size_t len; ++total; len = strlen(nick); if (!my_strnicmp(nick, "-CMD", len)) { if (total < 2) { yell("userhost -cmd with no nick!"); return; } userhost_cmd = 1; break; } else { if (n++) strmcat(buffer, " ", BIG_BUFFER_SIZE); else *buffer = '\0'; strmcat(buffer, nick, BIG_BUFFER_SIZE); } } if (n) { char *the_list = (char *) 0; char *s, *t; int i; malloc_strcpy(&the_list, buffer); s = t = the_list; while (n) { for (i = 5; i && *s; s++) if (' ' == *s) i--, n--; if (' ' == *(s - 1)) *(s - 1) = '\0'; else n--; /**************************** Patched by Flier ******************************/ /*strcpy(buffer, t);*/ strmcpy(buffer, t, sizeof(buffer)); /****************************************************************************/ t = s; if (userhost_cmd) add_to_whois_queue(buffer, userhost_cmd_returned, "%s", args); else add_to_whois_queue(buffer, USERHOST_USERHOST, 0); } new_free(&the_list); } else if (!total) /* Default to yourself. */ add_to_whois_queue(get_server_nickname(from_server), USERHOST_USERHOST, 0); } /* * whois: the WHOIS and WHOWAS commands. This translates the * to the whois handlers in whois.c */ static void whois(command, args, subargs) char *command, *args, *subargs; { /*************************** PATCHED by Flier ****************************/ /*if (args && *args) send_to_server("%s %s", command, args); else*/ /* Default to yourself -lynx */ /*send_to_server("%s %s", command, get_server_nickname(from_server));*/ #ifdef CELECOSM whoisfriend=(struct friends *) 0; #endif if (args && *args) { if (strcmp(command,"WII")) send_to_server("%s %s", command, args); else send_to_server("WHOIS %s %s",args,args); } else { if (strcmp(command,"WII")) send_to_server("%s %s", command, get_server_nickname(from_server)); else send_to_server("WHOIS %s %s",get_server_nickname(from_server),get_server_nickname(from_server)); } /*************************************************************************/ } /* * who: the /WHO command. Parses the who switches and sets the who_mask and * whoo_stuff accordingly. Who_mask and who_stuff are used in whoreply() in * parse.c */ static void who(command, args, subargs) char *command, *args, *subargs; { char *arg, *channel = NULL; int no_args = 1; size_t len; who_mask = 0; new_free(&who_name); new_free(&who_host); new_free(&who_server); new_free(&who_file); new_free(&who_nick); new_free(&who_real); while ((arg = next_arg(args, &args)) != NULL) { no_args = 0; if ((*arg == '-') && (!isdigit(*(arg + 1)))) { char *cmd = NULL; arg++; if ((len = strlen(arg)) == 0) { say("Unknown or missing flag"); return; } malloc_strcpy(&cmd, arg); lower(cmd); if (strncmp(cmd, "operators", len) == 0) who_mask |= WHO_OPS; else if (strncmp(cmd, "lusers", len) == 0) who_mask |= WHO_LUSERS; else if (strncmp(cmd, "chops", len) == 0) who_mask |= WHO_CHOPS; /**************************** Patched by Flier ******************************/ else if (strncmp(cmd, "hops", len) == 0) who_mask |= WHO_HOPS; /****************************************************************************/ else if (strncmp(cmd, "hosts", len) == 0) { if ((arg = next_arg(args, &args)) != NULL) { who_mask |= WHO_HOST; malloc_strcpy(&who_host, arg); channel = who_host; } else { say("WHO -HOSTS: missing arguement"); new_free(&cmd); return; } } else if (strncmp(cmd, "here", len) ==0) who_mask |= WHO_HERE; else if (strncmp(cmd, "away", len) ==0) who_mask |= WHO_AWAY; else if (strncmp(cmd, "servers", len) == 0) { if ((arg = next_arg(args, &args)) != NULL) { who_mask |= WHO_SERVER; malloc_strcpy(&who_server, arg); channel = who_server; } else { say("WHO -SERVERS: missing arguement"); new_free(&cmd); return; } } else if (strncmp(cmd, "name", len) == 0) { if ((arg = next_arg(args, &args)) != NULL) { who_mask |= WHO_NAME; malloc_strcpy(&who_name, arg); channel = who_name; } else { say("WHO -NAME: missing arguement"); new_free(&cmd); return; } } else if (strncmp(cmd, "realname", len) == 0) { if ((arg = next_arg(args, &args)) != NULL) { who_mask |= WHO_REAL; malloc_strcpy(&who_real, arg); channel = who_real; } else { say("WHO -REALNAME: missing arguement"); new_free(&cmd); return; } } else if (strncmp(cmd, "nick", len) == 0) { if ((arg = next_arg(args, &args)) != NULL) { who_mask |= WHO_NICK; malloc_strcpy(&who_nick, arg); channel = who_nick; } else { say("WHO -NICK: missing arguement"); new_free(&cmd); return; } /* WHO -FILE by Martin 'Efchen' Friedrich */ } else if (strncmp(cmd, "file", len) == 0) { who_mask |= WHO_FILE; if ((arg = next_arg(args, &args)) != NULL) { malloc_strcpy(&who_file, arg); } else { say("WHO -FILE: missing arguement"); new_free(&cmd); return; } } /**************************** PATCHED by Flier ******************************/ else if (strncmp(cmd,"show_server",len)==0) { who_mask |= WHO_SHOW_SERVER; } /****************************************************************************/ else { say("Unknown or missing flag"); new_free(&cmd); return; } new_free(&cmd); } else if (strcmp(arg, "*") == 0) { channel = get_channel_by_refnum(0); if (!channel || *channel == '0') { say("I wouldn't do that if I were you"); return; } } else channel = arg; } /**************************** PATCHED by Flier ******************************/ if (no_args) { /*say("No argument specified");*/ if (get_channel_by_refnum(0)) send_to_server("%s %s",command,get_channel_by_refnum(0)); else NoWindowChannel(); } /****************************************************************************/ else { if (!channel && who_mask & WHO_OPS) channel = "*"; /**************************** PATCHED by Flier ******************************/ if (!channel && (who_mask & WHO_SHOW_SERVER)) channel = "*"; /****************************************************************************/ send_to_server("%s %s %c", command, channel ? channel : empty_string, (who_mask & WHO_OPS) ? 'o' : '\0'); } } /* * query: the /QUERY command. Works much like the /MSG, I'll let you figure * it out. */ /*ARGSUSED*/ void query(command, args, subargs) char *command, *args, *subargs; { char *nick, *rest; save_message_from(); message_from((char *) 0, LOG_CURRENT); if ((nick = next_arg(args, &rest)) != NULL) { if (strcmp(nick, ".") == 0) { if (!(nick = (char *) sent_nick)) { say("You have not messaged anyone yet"); goto out; } } else if (strcmp(nick, ",") == 0) { if (!(nick = (char *) recv_nick)) { say("You have not recieved a message from \ anyone yet"); goto out; } } else if (strcmp(nick, "*") == 0) if (!(nick = get_channel_by_refnum(0))) { say("You are not on a channel"); goto out; } #ifndef _Windows if (*nick == '%') { if (is_process(nick) == 0) { say("Invalid processes specification"); goto out; } } #endif /* _Windows */ say("Starting conversation with %s", nick); set_query_nick(nick); } else { if (query_nick()) { say("Ending conversation with %s", query_nick()); set_query_nick(NULL); } else say("You aren't querying anyone!"); } update_input(UPDATE_ALL); out: restore_message_from(); } /* * away: the /AWAY command. Keeps track of the away message locally, and * sends the command on to the server. */ /**************************** PATCHED by Flier ******************************/ /*static void*/ void /****************************************************************************/ away(command, args, subargs) char *command, *args, *subargs; { size_t len; char *arg = NULL; int flag = AWAY_ONE; int i; if (*args) { if (*args == '-') { char *cmd = (char *) 0; args = next_arg(args, &arg); len = strlen(args); if (len == 0) { say("%s: No argument given with -", command); return; } malloc_strcpy(&cmd, args); upper(cmd); if (0 == strncmp(cmd, "-ALL", len)) { flag = AWAY_ALL; args = arg; } else if (0 == strncmp(cmd, "-ONE", len)) { flag = AWAY_ONE; args = arg; } else { say("%s: %s unknown flag", command, args); new_free(&cmd); return; } new_free(&cmd); } } if (flag == AWAY_ALL) if (*args) { away_set = 1; MarkAllAway(command, args); } else { away_set = 0; /**************************** PATCHED by Flier ******************************/ MarkAllAway(command, NULL); /****************************************************************************/ for(i = 0; (i < number_of_servers); i++) /**************************** PATCHED by Flier ******************************/ /*if (server_list[i].whois_stuff.away)*/ /****************************************************************************/ new_free(&(server_list[i].away)); } else { send_to_server("%s :%s", command, args); if (*args) { away_set = 1; malloc_strcpy(&(server_list[ curr_scr_win->server].away), args); } else { new_free(&(server_list[ curr_scr_win->server].away)); away_set = 0; for(i = 0; (i < number_of_servers) && !away_set ; i++) if (server_list[i].read != -1 && server_list[i].away) away_set = 1; } } update_all_status(); } /* e_quit: The /QUIT, /EXIT, etc command */ /*ARGSUSED*/ void e_quit(command, args, subargs) char *command, *args, *subargs; { /**************************** PATCHED by Flier ******************************/ /*int max; int i;*/ /****************************************************************************/ char *Reason; /**************************** PATCHED by Flier ******************************/ /*Reason = ((args && *args) ? args : "Leaving"); max = number_of_servers; for (i = 0; i < max; i++) if (is_server_connected(i)) { from_server = i; send_to_server("QUIT :%s", Reason); } irc_exit();*/ Reason = ((args && *args) ? args : NULL); IRCQuit=0; MyQuit(Reason); /****************************************************************************/ } /* flush: flushes all pending stuff coming from the server */ /*ARGSUSED*/ static void flush(command, args, subargs) char *command, *args, *subargs; { if (get_int_var(HOLD_MODE_VAR)) { while (curr_scr_win->held_lines) remove_from_hold_list(curr_scr_win); hold_mode((Window *) 0, OFF, 1); } say("Standby, Flushing server output..."); flush_server(); say("Done"); } /* e_wall: used for WALL and WALLOPS */ #ifndef LITE static void e_wall(command, args, subargs) char *command, *args, *subargs; { save_message_from(); if (strcmp(command, "WALL") == 0) { /* I hate this */ message_from(NULL, LOG_WALL); if (!get_server_operator(from_server)) put_it("## %s", args); } else { message_from(NULL, LOG_WALLOP); /**************************** PATCHED by Flier ******************************/ /*if (!get_server_flag(from_server, USER_MODE_W))*/ if (!get_server_umode_flag(from_server,'w')) put_it("!! %s", args); /****************************************************************************/ } if (!in_on_who) send_to_server("%s :%s", command, args); restore_message_from(); } #endif void redirect_msg(dest, msg) char *dest; char *msg; { char buffer[BIG_BUFFER_SIZE]; /**************************** Patched by Flier ******************************/ /*strcpy(buffer, dest); strcat(buffer, " "); strcat(buffer, msg);*/ strmcpy(buffer, dest, sizeof(buffer)); strmcat(buffer, " ", sizeof(buffer)); strmcat(buffer, msg, sizeof(buffer)); /****************************************************************************/ e_privmsg("PRIVMSG", buffer, NULL); } /* * e_privmsg: The MSG command, displaying a message on the screen indicating * the message was sent. Also, this works for the NOTICE command. */ static void e_privmsg(command, args, subargs) char *command, *args, *subargs; { char *nick; if ((nick = next_arg(args, &args)) != NULL) { if (strcmp(nick, ".") == 0) { if (!(nick = (char *) sent_nick)) { say("You have not sent a message to anyone yet"); return; } } else if (strcmp(nick, ",") == 0) { if (!(nick = (char *) recv_nick)) { say("You have not received a message from anyone yet"); return; } } else if (!strcmp(nick, "*")) if (!(nick = get_channel_by_refnum(0))) nick = irczero; /**************************** PATCHED by Flier ******************************/ if (my_stricmp(nick,"0")) AddNick2List(nick,from_server); /****************************************************************************/ send_text(nick, args, command); } else say("You must specify a nickname or channel!"); } /* * quote: handles the QUOTE command. args are a direct server command which * is simply send directly to the server */ /*ARGSUSED*/ static void quote(command, args, subargs) char *command, *args, *subargs; { if (!in_on_who) send_to_server("%s", args); } /* clear: the CLEAR command. Figure it out */ /*ARGSUSED*/ static void my_clear(command, args, subargs) char *command, *args, *subargs; { char *arg; int all = 0, unhold = 0; while ((arg = next_arg(args, &args)) != NULL) { upper(arg); /* -ALL and ALL here becuase the help files used to be wrong */ if (!strncmp(arg, "ALL", strlen(arg)) || !strncmp(arg, "-ALL", strlen(arg))) all = 1; else if (!strncmp(arg, "-UNHOLD", strlen(arg))) unhold = 1; else say("Unknown flag: %s", arg); } if (all) clear_all_windows(unhold); else { if (unhold) hold_mode((Window *) 0, OFF, 1); clear_window_by_refnum(0); } update_input(UPDATE_JUST_CURSOR); } /* * 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 */ static void send_comm(command, args, subargs) char *command, *args, *subargs; { /**************************** PATCHED by Flier ******************************/ if (command && *command) { if (!my_stricmp(command,"LINKS")) { time_t timenow=time((time_t *) 0); if (timenow-LastLinks<120 && inSZLinks) { say("Wait till previous LINKS, LLOOK, LLOOKUP or MAP completes"); return; } LastLinks=timenow; LinksNumber=0; inSZLinks=3; } else if (!my_stricmp(command,"STATS")) { #ifdef OPER StatskNumber=0; StatsiNumber=0; StatscNumber=0; StatslNumber=0; new_free(&StatskFilter); new_free(&StatsiFilter); new_free(&StatscFilter); new_free(&StatslFilter); new_free(&StatsdFilter); #endif } } /****************************************************************************/ if (args && *args) send_to_server("%s %s", command, args); else send_to_server("%s", command); } static void send_topic(command, args, subargs) char *command, *args, *subargs; { u_char *arg; u_char *arg2; if (!(arg = next_arg(args, &args)) || (strcmp(arg, "*") == 0)) arg = get_channel_by_refnum(0); if (!arg) { say("You aren't on a channel in this window"); return; } if (is_channel(arg)) { if ((arg2 = next_arg(args, &args)) != NULL) send_to_server("%s %s :%s %s", command, arg, arg2, args); else send_to_server("%s %s", command, arg); } else if (get_channel_by_refnum(0)) /**************************** Patched by Flier ******************************/ /*send_to_server("%s %s :%s", command, get_channel_by_refnum(0), subargs);*/ send_to_server("%s %s :%s %s",command,get_channel_by_refnum(0),arg,args); /****************************************************************************/ else say("You aren't on a channel in this window"); } #ifndef LITE static void send_squery(command, args, subargs) char *command, *args, *subargs; { put_it("*** Sent to service %s: %s", command, args); send_2comm(command, args, subargs); } #endif /* * send_2comm: Sends a command to the server with one arg and * one comment. Used for KILL and SQUIT. */ static void send_2comm(command, args, subargs) char *command, *args, *subargs; { char *comment; args = next_arg(args, &comment); send_to_server("%s %s %c%s", command, args && *args ? args : "", comment && *comment ? ':' : ' ', comment && *comment ? comment : ""); } /* * send_channel_nargs: Sends a command to the server with one channel, * and 0-n args. Used for MODE. */ static void send_channel_nargs(command, args, subargs) char *command, *args, *subargs; { char *arg1 = 0, *s = get_channel_by_refnum(0); args = next_arg(args, &arg1); if (!args || !strcmp(args, "*")) { if(s) args = s; else { say("You aren't on a channel in this window"); return; } } send_to_server("%s %s %s", command, args, arg1 && *arg1 ? arg1 : ""); } /* * send_channel_2args: Sends a command to the server with one channel, * one arg and one comment. Used for KICK */ static void send_channel_2args(command, args, subargs) char *command, *args, *subargs; { char *arg1 = 0, *comment = 0, *s = get_channel_by_refnum(0); args = next_arg(args, &arg1); if (!args || !strcmp(args, "*")) { if(s) args = s; else { say("You aren't on a channel in this window"); return; } } if (arg1 && *arg1) arg1 = next_arg(arg1, &comment); send_to_server("%s %s %s %c%s", command, args, arg1 && *arg1 ? arg1 : "", comment && *comment ? ':' : ' ', comment && *comment ? comment : ""); } /* * send_channel_1arg: Sends a command to the server with one channel * and one comment. Used for PART (LEAVE) */ static void send_channel_1arg(command, args, subargs) char *command, *args, *subargs; { char *comment, *s = get_channel_by_refnum(0); args = next_arg(args, &comment); if (!args || !strcmp(args, "*")) { if (s) args = s; else { say("You aren't on a channel in this window"); return; } } send_to_server("%s %s %c%s", command, args, comment && *comment ? ':' : ' ', comment && *comment ? comment : ""); } /* * send_text: Sends the line of text to whomever the user is currently * talking. If they are quering someone, it goes to that user, otherwise * it's the current channel. Some tricky parameter business going on. If * nick is null (as if you had typed "/ testing" on the command line) the * line is sent to your channel, and the command parameter is never used. If * nick is not null, and command is null, the line is sent as a PRIVMSG. If * nick is not null and command is not null, the message is sent using * command. Currently, only NOTICEs and PRIVMSGS work. * fixed to not be anal about "/msg foo,bar foobar" -phone */ void send_text(org_nick, line, command) char *org_nick; char *line; char *command; { #ifndef LITE crypt_key *key; #endif char *ptr, *free_nick, *nick = NULL; int lastlog_level, list_type, old_server; int check_away = 0; char the_thing; char *query_command = NULL; char nick_list[IRCD_BUFFER_SIZE+1]; int do_final_send = 0; /**************************** PATCHED by Flier ******************************/ int iscrypted; char *thing; char *mynick = get_server_nickname(from_server); char tmpbuf[BIG_BUFFER_SIZE + 1]; char *stampbuf = TimeStamp(2); ChannelList *chan; #ifdef HAVE_ICONV_H if (get_int_var(HIGH_ASCII_VAR)) thing = "\342\210\231"; #else if (get_int_var(HIGH_ASCII_VAR)) thing = "ù"; #endif /* HAVE_ICONV_H */ else thing = "-"; /****************************************************************************/ *nick_list = '\0'; malloc_strcpy(&nick, org_nick); free_nick = ptr = nick; save_message_from(); while ((nick = ptr) != NULL) { if ((ptr = index(nick, ',')) != NULL) *(ptr++) = (char) 0; if (!*nick) continue; #ifndef _Windows if (is_process(nick)) { int i; if ((i = get_process_index(&nick)) == -1) say("Invalid process specification"); else text_to_process(i, line, 1); continue; } #endif /* _Windows */ if (!*line) continue; /* lynx */ if (in_on_who && *nick != '=') /* allow dcc messages anyway */ { say("You may not send messages from ON WHO, ON WHOIS, or ON JOIN"); continue; } if (doing_privmsg) command = "NOTICE"; /* Query quote -lynx */ if (is_current_channel(nick, curr_scr_win->server, 0)) { /* nothing */ } else if (strcmp(nick, "\"") == 0) /* quote */ { send_to_server("%s", line); continue; } else if (*nick == '=') /* DCC chat */ { old_server = from_server; from_server = -1; dcc_chat_transmit(nick + 1, line); from_server = old_server; continue; } /**************************** PATCHED by Flier ******************************/ /*else if (*nick == '@')*/ /* DCC talk */ /*{ old_server = from_server; from_server = -1; dcc_message_transmit(nick + 1, line, DCC_TALK, 1); from_server = old_server; continue; }*/ /****************************************************************************/ else if (*nick == '/') /* Command */ { malloc_strcpy(&query_command, nick); malloc_strcat(&query_command, " "); malloc_strcat(&query_command, line); parse_command(query_command, 0, empty_string); new_free(&query_command); continue; } switch (send_text_flag) { case MSG_LIST: command = "NOTICE"; break; case NOTICE_LIST: say("You cannot send a message from a NOTICE"); new_free(&free_nick); goto out; } /**************************** PATCHED by Flier ******************************/ *tmpbuf = '\0'; iscrypted = EncryptMessage(tmpbuf,nick); /****************************************************************************/ if (is_channel(nick)) { int current; current = is_current_channel(nick, curr_scr_win->server, 0); if (!command || strcmp(command, "NOTICE")) { check_away = 1; command = "PRIVMSG"; lastlog_level = set_lastlog_msg_level(LOG_PUBLIC); message_from(nick, LOG_PUBLIC); list_type = SEND_PUBLIC_LIST; the_thing = '>'; } else { lastlog_level = set_lastlog_msg_level(LOG_NOTICE); message_from(nick, LOG_NOTICE); list_type = SEND_NOTICE_LIST; the_thing = '-'; } if (do_hook(list_type, "%s %s", nick, line)) { /**************************** PATCHED by Flier ******************************/ /*if (current) put_it("%c %s", the_thing, line); else put_it("%c%s> %s", the_thing, nick, line);*/ if (current) { if (!my_stricmp(command, "NOTICE")) put_it("%s%s-%s- %s", iscrypted ? "[!]" : "", stampbuf, nick, line); else PrintPublic(mynick, NULL, nick, line, 1, iscrypted); } else { if (!my_stricmp(command, "NOTICE")) put_it("%s%s-%s- %s", iscrypted ? "[!]" : "", stampbuf, nick, line); else PrintPublic(mynick, ":", nick, line, 1, iscrypted); } tabnickcompl = NULL; /****************************************************************************/ } /**************************** PATCHED by Flier ******************************/ else if (my_stricmp(command, "NOTICE")) PrintPublic(mynick, NULL, nick, line, 0, iscrypted); chan = lookup_channel(nick, parsing_server_index, 0); if (chan && chan->ChanLog && list_type == SEND_NOTICE_LIST) { snprintf(tmpbuf, sizeof(tmpbuf), "-%s- %s", mynick, line); ChannelLogSave(tmpbuf, chan); } if ((away_set || LogOn) && my_stricmp(command, "NOTICE")) { snprintf(tmpbuf, sizeof(tmpbuf), "<%s> %s", mynick, line); AwaySave(tmpbuf, SAVESENTMSG); } /****************************************************************************/ set_lastlog_msg_level(lastlog_level); #ifndef LITE if ((key = is_crypted(nick)) != 0) { char *crypt_line; if ((crypt_line = crypt_msg(line, key, 1))) send_to_server("%s %s :%s", command, nick, crypt_line); continue; } #endif /**************************** PATCHED by Flier ******************************/ strmcpy(tmpbuf, line, sizeof(tmpbuf)); if (EncryptMessage(tmpbuf, nick)) { send_to_server("%s %s :%s", command, nick, tmpbuf); continue; } /****************************************************************************/ if (!in_on_who) { if (*nick_list) { /**************************** Patched by Flier ******************************/ /*strcat(nick_list, ","); strcat(nick_list, nick);*/ strmcat(nick_list, ",", sizeof(nick_list)); strmcat(nick_list, nick, sizeof(nick_list)); /****************************************************************************/ } else /**************************** Patched by Flier ******************************/ /*strcpy(nick_list, nick);*/ strmcpy(nick_list, nick, sizeof(nick_list)); /****************************************************************************/ } do_final_send = 1; } else { if (!command || strcmp(command, "NOTICE")) { check_away = 1; lastlog_level = set_lastlog_msg_level(LOG_MSG); command = "PRIVMSG"; message_from(nick, LOG_MSG); list_type = SEND_MSG_LIST; the_thing = '*'; } else { lastlog_level = set_lastlog_msg_level(LOG_NOTICE); message_from(nick, LOG_NOTICE); list_type = SEND_NOTICE_LIST; the_thing = '-'; } /**************************** PATCHED by Flier ******************************/ /*if (window_display && do_hook(list_type, "%s %s", nick, line)) put_it("-> %c%s%c %s", the_thing, nick, the_thing, line);*/ if (window_display && do_hook(list_type, "%s %s", nick, line)) { if (!my_stricmp(command, "NOTICE")) { #ifdef WANTANSI #ifdef CELECOSM snprintf(tmpbuf, sizeof(tmpbuf), "%s[%s%s(notice)%s%s%s%s%s]%s", CmdsColors[COLNOTICE].color4, Colors[COLOFF], CmdsColors[COLCELE].color2, Colors[COLOFF], CmdsColors[COLNOTICE].color2, nick, Colors[COLOFF], CmdsColors[COLNOTICE].color4, Colors[COLOFF]); #else /* CELECOSM */ snprintf(tmpbuf, sizeof(tmpbuf), "%s<%s-%s%s%s-%s>%s", CmdsColors[COLNOTICE].color4, Colors[COLOFF], CmdsColors[COLNOTICE].color2, nick, Colors[COLOFF], CmdsColors[COLNOTICE].color4, Colors[COLOFF]); #endif /* CELECOSM */ put_it("%s%s%s %s%s%s", iscrypted ? "[!]" : "", stampbuf, tmpbuf, CmdsColors[COLNOTICE].color3, line, Colors[COLOFF]); #else /* WANTANSI */ put_it("%s%s<-%s-> %s", iscrypted ? "[!]" : "", stampbuf, nick, line); #endif /* WANTANSI */ } else { #ifdef WANTANSI #ifdef CELECOSM snprintf(tmpbuf,sizeof(tmpbuf),"%s[%s%s(msg)%s%s%s%s%s]%s", CmdsColors[COLMSG].color5, Colors[COLOFF], CmdsColors[COLCELE].color1, Colors[COLOFF], CmdsColors[COLMSG].color6, nick, Colors[COLOFF], CmdsColors[COLMSG].color5, Colors[COLOFF]); #else /* CELECOSM */ snprintf(tmpbuf,sizeof(tmpbuf),"%s[%s%s%s%s%s%s%s]%s", CmdsColors[COLMSG].color5, Colors[COLOFF], thing, CmdsColors[COLMSG].color6, nick, Colors[COLOFF], thing, CmdsColors[COLMSG].color5, Colors[COLOFF]); #endif /* CELECOSM */ put_it("%s%s%s %s%s%s", stampbuf, iscrypted ? "[!]" : "", tmpbuf, CmdsColors[COLMSG].color3, line, Colors[COLOFF]); #else /* WANTANSI */ put_it("%s%s[%s%s%s] %s", stampbuf, iscrypted ? "[!]" : "", thing, nick, thing, line); #endif /* WANTANSI */ } } if (line != server_list[from_server].LastMessageSent && line != server_list[from_server].LastNoticeSent) { if (!my_stricmp(command, "NOTICE")) { snprintf(tmpbuf, sizeof(tmpbuf), "-> -%s- %s", nick, line); if (CheckServer(from_server)) malloc_strcpy(&(server_list[from_server].LastNoticeSent), tmpbuf); } else { snprintf(tmpbuf,sizeof(tmpbuf),"-> [-%s-] %s", nick, line); if (CheckServer(from_server)) malloc_strcpy(&(server_list[from_server].LastMessageSent), tmpbuf); if (away_set || LogOn) AwaySave(tmpbuf, SAVESENTMSG); } } /****************************************************************************/ #ifndef LITE if ((key = is_crypted(nick)) != NULL) { char *crypt_line; if ((crypt_line = crypt_msg(line, key, 1))) send_to_server("%s %s :%s", command ? command : "PRIVMSG", nick, crypt_line); continue; } #endif set_lastlog_msg_level(lastlog_level); /**************************** PATCHED by Flier ******************************/ strmcpy(tmpbuf, line, sizeof(tmpbuf)); if (EncryptMessage(tmpbuf, nick)) { send_to_server("%s %s :%s", command ? command : "PRIVMSG", nick, tmpbuf); continue; } /****************************************************************************/ if (!in_on_who) { if (*nick_list) { /**************************** Patched by Flier ******************************/ /*strcat(nick_list, ","); strcat(nick_list, nick);*/ strmcat(nick_list, ",", sizeof(nick_list)); strmcat(nick_list, nick, sizeof(nick_list)); /****************************************************************************/ } else /**************************** Patched by Flier ******************************/ /*strcpy(nick_list, nick);*/ strmcpy(nick_list, nick, sizeof(nick_list)); /****************************************************************************/ } if (get_int_var(WARN_OF_IGNORES_VAR) && (is_ignored(nick, IGNORE_MSGS) == IGNORED)) say("Warning: You are ignoring private messages from %s", nick); malloc_strcpy((char **) &sent_nick, nick); do_final_send = 1; } } if (check_away && server_list[curr_scr_win->server].away && get_int_var(AUTO_UNMARK_AWAY_VAR)) away("AWAY", empty_string, empty_string); malloc_strcpy((char **) &sent_body, line); if (do_final_send) send_to_server("%s %s :%s", command ? command : "PRIVMSG", nick_list, line); new_free(&free_nick); out: restore_message_from(); } static void do_send_text(command, args, subargs) char *command, *args, *subargs; { char *tmp; /**************************** PATCHED by Flier ******************************/ char tmpbuf[mybufsize]; ChannelList *tmpchan; /****************************************************************************/ if (command) tmp = get_channel_by_refnum(0); else tmp = get_target_by_refnum(0); /**************************** PATCHED by Flier ******************************/ if (AutoNickCompl && tmp && args && *args && (tmpchan=lookup_channel(tmp,curr_scr_win->server,0))) { AutoNickComplete(args,tmpbuf,tmpchan); args=tmpbuf; } /****************************************************************************/ send_text(tmp, args, NULL); } /* * command_completion: builds lists of commands and aliases that match the * given command and displays them for the user's lookseeing */ void command_completion(key, ptr) u_int key; char * ptr; { int do_aliases; int cmd_cnt, alias_cnt, i, c, len; char **aliases = NULL; char *line = NULL, *com, *cmdchars, *rest, firstcmdchar = '/'; char buffer[BIG_BUFFER_SIZE+1]; IrcCommand *command; malloc_strcpy(&line, get_input()); if ((com = next_arg(line, &rest)) != NULL) { if (!(cmdchars = get_string_var(CMDCHARS_VAR))) cmdchars = DEFAULT_CMDCHARS; if (index(cmdchars, *com)) { firstcmdchar = *cmdchars; com++; if (*com && index(cmdchars, *com)) { do_aliases = 0; alias_cnt = 0; com++; } else do_aliases = 1; upper(com); if (do_aliases) aliases = match_alias(com, &alias_cnt, COMMAND_ALIAS); if ((command = find_command(com, &cmd_cnt)) != NULL) { if (cmd_cnt < 0) cmd_cnt *= -1; /* special case for the empty string */ if (*(command[0].name) == (char) 0) { command++; cmd_cnt = NUMBER_OF_COMMANDS; } } if ((alias_cnt == 1) && (cmd_cnt == 0)) { snprintf(buffer, sizeof buffer, "%c%s %s", firstcmdchar, aliases[0], rest); set_input(buffer); new_free(&(aliases[0])); new_free(&aliases); update_input(UPDATE_ALL); } else if (((cmd_cnt == 1) && (alias_cnt == 0)) || ((cmd_cnt == 1) && (alias_cnt == 1) && (strcmp(aliases[0], command[0].name) == 0))) { snprintf(buffer, sizeof buffer, "%c%s%s %s", firstcmdchar, do_aliases ? "" : &firstcmdchar, command[0].name, rest); set_input(buffer); update_input(UPDATE_ALL); } else { *buffer = (char) 0; if (command) { say("Commands:"); strmcpy(buffer, "\t", BIG_BUFFER_SIZE); c = 0; for (i = 0; i < cmd_cnt; i++) { strmcat(buffer, command[i].name, BIG_BUFFER_SIZE); for (len = strlen(command[i].name); len < 15; len++) strmcat(buffer, " ", BIG_BUFFER_SIZE); if (++c == 4) { say("%s", buffer); strmcpy(buffer, "\t", BIG_BUFFER_SIZE); c = 0; } } if (c) say("%s", buffer); } if (aliases) { say("Aliases:"); strmcpy(buffer, "\t", BIG_BUFFER_SIZE); c = 0; for (i = 0; i < alias_cnt; i++) { strmcat(buffer, aliases[i], BIG_BUFFER_SIZE); for (len = strlen(aliases[i]); len < 15; len++) strmcat(buffer, " ", BIG_BUFFER_SIZE); if (++c == 4) { say("%s", buffer); strmcpy(buffer, "\t", BIG_BUFFER_SIZE); c = 0; } new_free(&(aliases[i])); } if ((int) strlen(buffer) > 1) say("%s", buffer); new_free(&aliases); } if (!*buffer) term_beep(); } } else term_beep(); } else term_beep(); new_free(&line); } /* * 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. */ void parse_line(name, org_line, args, hist_flag, append_flag, eat_space) char *name, *org_line, *args; int hist_flag, append_flag, eat_space; { char *line = NULL, *free_line, *stuff, *start, *lbuf, *s, *t; int args_flag; malloc_strcpy(&line, org_line); free_line = line; args_flag = 0; if (!*line) do_send_text(NULL, empty_string, empty_string); else if (args) do { stuff = expand_alias(name, line, args, &args_flag, &line); start = stuff; if (eat_space) for (; isspace(*start); start++) ; if (!line && append_flag && !args_flag && args && *args) { lbuf = (char *) new_malloc(strlen(stuff) + 1 + strlen(args) + 1); strcpy(lbuf, start); strcat(lbuf, " "); strcat(lbuf, args); new_free(&stuff); start = stuff = lbuf; } parse_command(start, hist_flag, args); new_free(&stuff); } while (line); else { start = line; if (eat_space) for (; isspace(*start); start++) ; if (load_depth) parse_command(start, hist_flag, args); else while ((s = line)) { if ((t = sindex(line, "\r\n")) != NULL) { *t++ = '\0'; if (eat_space) for (; isspace(*t); t++) ; line = t; } else line = NULL; parse_command(s, hist_flag, args); } } new_free(&free_line); 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). */ void parse_command(line, hist_flag, sub_args) char *line; int hist_flag; char *sub_args; { static unsigned int level = 0; unsigned int display, old_display_var; char *cmdchars, *com, *this_cmd = NULL; int args_flag, add_to_hist, cmdchar_used; if (!line || !*line) return; if (get_int_var(DEBUG_VAR) & DEBUG_COMMANDS) yell("Executing [%d] %s", level, line); level++; if (!(cmdchars = get_string_var(CMDCHARS_VAR))) cmdchars = DEFAULT_CMDCHARS; malloc_strcpy(&this_cmd, line); add_to_hist = 1; if (index(cmdchars, *line)) { cmdchar_used = 1; com = line + 1; } else { cmdchar_used = 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); if (hist_flag && add_to_hist) { add_to_history(this_cmd); set_input(empty_string); } /* Special handling for ' and : */ } else if (*com == '\'' && get_int_var(COMMAND_MODE_VAR)) { do_send_text(NULL, line+1, empty_string); if (hist_flag && add_to_hist) { add_to_history(this_cmd); set_input(empty_string); } } else if (*com == '@') { /* This kludge fixes a memory leak */ char *tmp; tmp = parse_inline(line + 1, sub_args, &args_flag); if (tmp) new_free(&tmp); if (hist_flag && add_to_hist) { add_to_history(this_cmd); set_input(empty_string); } } else { char *rest, *nalias = NULL, *alias_name; int cmd_cnt, alias_cnt; IrcCommand *command; /* = (IrcCommand *) 0 */ display = window_display; old_display_var = (unsigned) get_int_var(DISPLAY_VAR); if ((rest = (char *) index(com, ' ')) != NULL) *(rest++) = (char) 0; else rest = empty_string; upper(com); /* first, check aliases */ if (*com && index(cmdchars, *com)) { alias_cnt = 0; com++; if (*com == '^') { com++; window_display = 0; } } else { if (*com == '^') { com++; window_display = 0; } nalias = get_alias(COMMAND_ALIAS, com, &alias_cnt, &alias_name); } if (nalias && (alias_cnt == 0)) { if (hist_flag && add_to_hist) { add_to_history(this_cmd); set_input(empty_string); } execute_alias(alias_name, nalias, rest); new_free(&alias_name); } else { /* History */ if (*com == '!') { if ((com = do_history(com + 1, rest)) != NULL) { if (level == 1) { set_input(com); update_input(UPDATE_ALL); } else parse_command(com, 0, sub_args); new_free(&com); } else set_input(empty_string); } else { if (hist_flag && add_to_hist) { add_to_history(this_cmd); set_input(empty_string); } command = find_command(com, &cmd_cnt); if ((command && cmd_cnt < 0) || (0 == alias_cnt && 1 == cmd_cnt)) { if ((command->flags & SERVERREQ) && connected_to_server == 0) say("%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); else say("%s: command disabled", command->name); } else if (nalias && 1 == alias_cnt && cmd_cnt == 1 && !strcmp(alias_name, command[0].name)) execute_alias(alias_name, nalias, rest); else if ((alias_cnt + cmd_cnt) > 1) say("Ambiguous command: %s", com); else if (nalias && 1 == alias_cnt) execute_alias(alias_name, nalias, rest); else if (!my_stricmp(com, nickname)) /* nick = /me -lynx */ me(NULL, rest, empty_string); else say("Unknown command: %s", com); } if (nalias) new_free(&alias_name); } if (old_display_var != get_int_var(DISPLAY_VAR)) window_display = get_int_var(DISPLAY_VAR); else window_display = display; } new_free(&this_cmd); level--; } /* * load: the /LOAD command. Reads the named file, parsing each line as * though it were typed in (passes each line to parse_command). */ /*ARGSUSED*/ void load(command, args, subargs) char *command, *args, *subargs; { FILE *fp; char *filename, *expanded = NULL; int flag = 0; struct stat stat_buf; int paste_level = 0; char *start, *current_row = NULL, lbuf[BIG_BUFFER_SIZE + 1]; int no_semicolon = 1; char *ircpath; int display; #ifdef ZCAT char *expand_z = NULL; int exists; int pos; #endif /**************************** PATCHED by Flier ******************************/ int linenumber = 0; int pasteline = -1; /****************************************************************************/ ircpath = get_string_var(LOAD_PATH_VAR); if (!ircpath) { say("LOAD_PATH has not been set"); return; } if (load_depth == MAX_LOAD_DEPTH) { say("No more than %d levels of LOADs allowed", MAX_LOAD_DEPTH); return; } load_depth++; status_update(0); #ifdef DAEMON_UID if (getuid() == DAEMON_UID) { say("You may only load your SAVED file"); filename = ircrc_file; } else #endif /* DAEMON_UID */ while ((filename = next_arg(args, &args)) != NULL) { if (my_strnicmp(filename, "-args", strlen(filename)) == 0) flag = 1; else break; } if (filename) { if ((expanded = expand_twiddle(filename)) != NULL) { #ifdef ZCAT /* Handle both and .Z */ pos = strlen(expanded) - strlen(ZSUFFIX); if (pos < 0 || strcmp(expanded + pos, ZSUFFIX)) { malloc_strcpy(&expand_z, expanded); malloc_strcat(&expand_z, ZSUFFIX); } #endif /*ZCAT*/ if (*expanded != '/') { filename = path_search(expanded, ircpath); #ifdef ZCAT if (!filename && expand_z) filename = path_search(expand_z, ircpath); #endif /*ZCAT*/ if (!filename) { say("%s: File not found", expanded); status_update(1); load_depth--; #ifdef ZCAT new_free(&expand_z); #endif /* ZCAT */ new_free(&expanded); return; } else malloc_strcpy(&expanded, filename); } #ifdef ZCAT if ((exists = stat(expanded, &stat_buf)) == -1) { if (!(exists = stat(expand_z, &stat_buf))) { if (expanded) new_free(&expanded); expanded = expand_z; } else new_free(&expand_z); } if (exists == 0) #else if (!stat(expanded, &stat_buf)) #endif /*ZCAT*/ { if (stat_buf.st_mode & S_IFDIR) { say("%s is a directory", expanded); status_update(1); load_depth--; #ifdef ZCAT new_free(&expand_z); #endif /* ZCAT */ new_free(&expanded); return; } /* sigh. this is lame */ #if defined(S_IXUSR) && defined(S_IXGRP) && defined(S_IXOTH) # define IS_EXECUTABLE (S_IXUSR|S_IXGRP|S_IXOTH) #else # define IS_EXECUTABLE 0111 #endif if (stat_buf.st_mode & IS_EXECUTABLE) { yell("*** %s is executable and may not be loaded", expanded); status_update(1); load_depth--; #ifdef ZCAT new_free(&expand_z); #endif /* ZCAT */ new_free(&expanded); return; } } if (command && *command == 'W') { say("%s", expanded); status_update(1); load_depth--; new_free(&expanded); #ifdef ZCAT new_free(&expand_z); #endif /* ZCAT */ return; } #ifdef ZCAT /* Open if uncompressed, zcat if compressed */ pos = strlen(expanded) - strlen(ZSUFFIX); if (pos >= 0 && !strcmp(expanded + pos, ZSUFFIX)) fp = zcat(expanded); else fp = fopen(expanded, "r"); if (fp != NULL) #else if (fp = fopen(expanded, "r")) #endif /*ZCAT*/ { display = window_display; window_display = 0; current_row = NULL; if (!flag) args = NULL; for (;;) { if (fgets(lbuf, BIG_BUFFER_SIZE / 2, fp)) /* XXX need better /load policy, but this will do for now */ { size_t len; char *ptr; /**************************** PATCHED by Flier ******************************/ linenumber++; /****************************************************************************/ for (start = lbuf; isspace(*start); start++) ; if (!*start || *start == '#') continue; len = strlen(start); /* * this line from stargazer to allow \'s in scripts for continued * lines */ while (start[len-1] == '\n' && start[len-2] == '\\' && len < BIG_BUFFER_SIZE / 2 && fgets(&(start[len-2]), (int)(BIG_BUFFER_SIZE / 2 - len), fp)) len = strlen(start); if (start[len - 1] == '\n') start[--len] = '\0'; while (start && *start) { char *optr = start; while ((ptr = sindex(optr, "{};")) && ptr != optr && ptr[-1] == '\\') optr = ptr+1; if (no_semicolon) no_semicolon = 0; else if ((!ptr || ptr != start) && current_row) { if (!paste_level) { parse_line(NULL, current_row, args, 0, 0, 0); new_free(¤t_row); } else malloc_strcat(¤t_row, ";"); } if (ptr) { char c = *ptr; *ptr = '\0'; malloc_strcat(¤t_row, start); *ptr = c; switch (c) { case '{' : /**************************** PATCHED by Flier ******************************/ if (!paste_level) pasteline = linenumber; /****************************************************************************/ paste_level++; if (ptr == start) malloc_strcat(¤t_row, " {"); else malloc_strcat(¤t_row, "{"); no_semicolon = 1; break; case '}' : if (!paste_level) /**************************** PATCHED by Flier ******************************/ /*yell("Unexpected }");*/ yell("Unexpected } in %s, line %d", expanded, linenumber); /****************************************************************************/ else { --paste_level; malloc_strcat(¤t_row, "}"); no_semicolon = ptr[1] ? 1 : 0; } /**************************** PATCHED by Flier ******************************/ if (!paste_level) pasteline = -1; /****************************************************************************/ break; case ';' : malloc_strcat(¤t_row, ";"); no_semicolon = 1; break; } start = ptr+1; } else { malloc_strcat(¤t_row, start); start = NULL; } } } else break; } if (current_row) { if (paste_level) /**************************** PATCHED by Flier ******************************/ /*yell("Unexpected EOF");*/ yell("Unexpected EOF in %s trying to match '{' at line %d", expanded, pasteline); /****************************************************************************/ else parse_line(NULL, current_row, args, 0, 0, 0); new_free(¤t_row); } window_display = display; fclose(fp); } else say("Couldn't open %s: %s", expanded, strerror(errno)); new_free(&expanded); #ifdef ZCAT new_free(&expand_z); #endif /* ZCAT */ } else say("Unknown user"); } else say("No filename specified"); status_update(1); load_depth--; } /* * get_history: gets the next history entry, either the PREV entry or the * NEXT entry, and sets it to the current input string */ static void get_history(which) int which; { char *ptr; if ((ptr = get_from_history(which)) != NULL) { set_input(ptr); update_input(UPDATE_ALL); } } /* BIND function: */ void forward_character(key, ptr) u_int key; char * ptr; { input_move_cursor(RIGHT); } void backward_character(key, ptr) u_int key; char * ptr; { input_move_cursor(LEFT); } void backward_history(key, ptr) u_int key; char * ptr; { get_history(PREV); } void forward_history(key, ptr) u_int key; char * ptr; { get_history(NEXT); } void toggle_insert_mode(key, ptr) u_int key; char * ptr; { /**************************** PATCHED by Flier ******************************/ /*set_var_value(INSERT_MODE_VAR, "TOGGLE");*/ HandleTabNext(); /****************************************************************************/ } /*ARGSUSED*/ void send_line(key, ptr) u_int key; char * ptr; { int server; WaitPrompt *OldPrompt; server = from_server; from_server = get_window_server(0); reset_hold((Window *) 0); hold_mode((Window *) 0, OFF, 1); if (current_screen->promptlist && current_screen->promptlist->type == WAIT_PROMPT_LINE) { OldPrompt = current_screen->promptlist; (*OldPrompt->func)(OldPrompt->data, get_input()); set_input(empty_string); current_screen->promptlist = OldPrompt->next; new_free(&OldPrompt->data); new_free(&OldPrompt->prompt); new_free(&OldPrompt); change_input_prompt(-1); } else { char *line, *tmp = NULL; line = get_input(); malloc_strcpy(&tmp, line); if (do_hook(INPUT_LIST, "%s", tmp)) { if (get_int_var(INPUT_ALIASES_VAR)) parse_line(NULL, tmp, empty_string, 1, 0, 0); else parse_line(NULL, tmp, NULL, 1, 0, 0); } update_input(UPDATE_ALL); new_free(&tmp); } from_server = server; /**************************** PATCHED by Flier ******************************/ tabnickcompl = NULL; /****************************************************************************/ } /* The SENDLINE command.. */ #ifndef LITE static void sendlinecmd(command, args, subargs) char *command, *args, *subargs; { int server; int display; server = from_server; display = window_display; window_display = 1; if (get_int_var(INPUT_ALIASES_VAR)) parse_line(NULL, args, empty_string, 1, 0, 0); else parse_line(NULL, args, NULL, 1, 0, 0); update_input(UPDATE_ALL); window_display = display; from_server = server; } #endif /*ARGSUSED*/ #ifndef LITE void meta8_char(key, ptr) u_int key; char * ptr; { current_screen->meta8_hit = 1; } /*ARGSUSED*/ void meta7_char(key, ptr) u_int key; char * ptr; { current_screen->meta7_hit = 1; } /*ARGSUSED*/ void meta6_char(key, ptr) u_int key; char * ptr; { current_screen->meta6_hit = 1; } #endif /* LITE */ /*ARGSUSED*/ void meta5_char(key, ptr) u_int key; char * ptr; { current_screen->meta5_hit = 1; } /*ARGSUSED*/ void meta4_char(key, ptr) u_int key; char * ptr; { current_screen->meta4_hit = 1 - current_screen->meta4_hit; } /*ARGSUSED*/ void meta3_char(key, ptr) u_int key; char * ptr; { current_screen->meta3_hit = 1; } /*ARGSUSED*/ void meta2_char(key, ptr) u_int key; char * ptr; { current_screen->meta2_hit = 1; } /*ARGSUSED*/ void meta1_char(key, ptr) u_int key; char * ptr; { current_screen->meta1_hit = 1; } void quote_char(key, ptr) u_int key; char * ptr; { current_screen->quote_hit = 1; } /* type_text: the BIND function TYPE_TEXT */ /*ARGSUSED*/ void type_text(key, ptr) u_int key; char *ptr; { for (; *ptr; ptr++) input_add_character((u_int)*ptr, (char *) 0); } /* * irc_clear_screen: the CLEAR_SCREEN function for BIND. Clears the screen and * starts it if it is held */ /*ARGSUSED*/ void irc_clear_screen(key, ptr) u_int key; char *ptr; { hold_mode((Window *) 0, OFF, 1); my_clear(NULL, empty_string, empty_string); } /* parse_text: the bindable function that executes its string */ void parse_text(key, ptr) u_int key; char *ptr; { parse_line(NULL, ptr, empty_string, 0, 0, 0); } /* * edit_char: handles each character for an input stream. Not too difficult * to work out. */ void edit_char(ikey) u_int ikey; { void (*func) _((u_int, char *)); char *str; u_char extended_key, key = (u_char)ikey; WaitPrompt *oldprompt; /**************************** PATCHED by Flier ******************************/ static int cloaktilde=0; /****************************************************************************/ if (current_screen->promptlist && current_screen->promptlist->type == WAIT_PROMPT_KEY) { oldprompt = current_screen->promptlist; (*oldprompt->func)(oldprompt->data, (char *)&key); set_input(empty_string); current_screen->promptlist = oldprompt->next; new_free(&oldprompt->data); new_free(&oldprompt->prompt); new_free(&oldprompt); change_input_prompt(-1); return; } if (!get_int_var(EIGHT_BIT_CHARACTERS_VAR)) key &= 0x7f; /* mask out non-ascii crap */ extended_key = key; if (current_screen->meta1_hit) { func = key_names[meta1_keys[key].index].func; str = meta1_keys[key].stuff; current_screen->meta1_hit = 0; } else if (current_screen->meta2_hit) { func = key_names[meta2_keys[key].index].func; str = meta2_keys[key].stuff; current_screen->meta2_hit = 0; } else if (current_screen->meta3_hit) { func = key_names[meta3_keys[key].index].func; str = meta3_keys[key].stuff; current_screen->meta3_hit = 0; } else if (current_screen->meta4_hit) { func = key_names[meta4_keys[key].index].func; str = meta4_keys[key].stuff; } else if (current_screen->meta5_hit) { func = key_names[meta5_keys[key].index].func; str = meta5_keys[key].stuff; current_screen->meta5_hit = 0; } #ifndef LITE else if (current_screen->meta6_hit) { func = key_names[meta6_keys[key].index].func; str = meta6_keys[key].stuff; current_screen->meta6_hit = 0; } else if (current_screen->meta7_hit) { func = key_names[meta7_keys[key].index].func; str = meta7_keys[key].stuff; current_screen->meta7_hit = 0; } else if (current_screen->meta8_hit) { func = key_names[meta8_keys[key].index].func; str = meta8_keys[key].stuff; current_screen->meta8_hit = 0; } #endif else { func = key_names[keys[key].index].func; str = keys[key].stuff; } /**************************** PATCHED by Flier ******************************/ /*if (!current_screen->meta1_hit && !current_screen->meta2_hit && !current_screen->meta3_hit)*/ if (!current_screen->meta1_hit && !current_screen->meta2_hit && !current_screen->meta3_hit && !current_screen->meta5_hit) /****************************************************************************/ { #ifndef LITE if (current_screen->inside_menu == 1) menu_key((u_int)key); else #endif if (current_screen->digraph_hit) { if (extended_key == 0x08 || extended_key == 0x7f) current_screen->digraph_hit = 0; else if (current_screen->digraph_hit == 1) { current_screen->digraph_first = extended_key; current_screen->digraph_hit = 2; } else if (current_screen->digraph_hit == 2) { if ((extended_key = get_digraph((u_int)extended_key)) != '\0') input_add_character((u_int)extended_key, (char *) 0); else term_beep(); } } else if (current_screen->quote_hit) { current_screen->quote_hit = 0; input_add_character((u_int)extended_key, (char *) 0); } /**************************** PATCHED by Flier ******************************/ /*else if (func) func(extended_key, str ? str : empty_string);*/ else if (func) { if (key==27) cloaktilde=1; else if (cloaktilde==1 && key==91) cloaktilde++; else if (cloaktilde==2 && key==91) cloaktilde=0; else if (cloaktilde==2 && key>=65 && key<=68) cloaktilde=0; else if (cloaktilde==2) cloaktilde++; else if (cloaktilde>=3 && key==126) { cloaktilde=0; return; } else if (cloaktilde==3) cloaktilde++; else cloaktilde=0; func(extended_key, str ? str : empty_string); } /****************************************************************************/ } else term_beep(); } /*ARGSUSED*/ #ifndef LITE static void catter(command, args, subargs) char *command; char *args; char *subargs; { char *target = next_arg(args, &args); if (target && args && *args) { char *text = args; FILE *fp = fopen(target, "r+"); if (!fp) { fp = fopen(target, "w"); if (!fp) { say("CAT: error: '%s': %s", target, strerror(errno)); return; } } fseek(fp, 0, SEEK_END); fprintf(fp, "%s\n", text), fclose(fp); } else say("Usage: /CAT "); } #endif /*ARGSUSED*/ static void cd(command, args, subargs) char *command, *args, *subargs; { char lbuf[BIG_BUFFER_SIZE+1]; char *arg, *expand; #ifdef DAEMON_UID if (getuid() == DAEMON_UID) { say("You are not permitted to use this command"); return; } #endif /* DAEMON_UID */ if ((arg = next_arg(args, &args)) != NULL) { if ((expand = expand_twiddle(arg)) != NULL) { if (chdir(expand)) say("CD: %s", strerror(errno)); new_free(&expand); } else say("CD: No such user"); } getcwd(lbuf, BIG_BUFFER_SIZE); say("Current directory: %s", lbuf); } static void send_action(target, text) char *target, *text; { /**************************** Patched by Flier ******************************/ if (ChanLog && is_channel(target)) { char tmpbuf[mybufsize]; ChannelList *chan; chan = lookup_channel(target, parsing_server_index, 0); if (chan && chan->ChanLog) { snprintf(tmpbuf, sizeof(tmpbuf), "* %s %s", get_server_nickname(parsing_server_index), text); ChannelLogSave(tmpbuf, chan); } } /****************************************************************************/ send_ctcp(ctcp_type[CTCP_PRIVMSG], target, "ACTION", "%s", text); } #ifdef LYNX_STUFF static char * prepare_action(string) char *string; { short last; char *message; last = strlen(string) - 1; while(string[last] == ' ') if (--last < 0) return NULL; if ((string[last] > 'a' && string[last] < 'z') || (string[last] > 'A' && string[last] < 'Z')) { message = new_malloc(last + 2); strmcpy (message, string, last+1); message[last + 1] = '.'; message[last + 2] = '\0'; return message; } else return NULL; } #endif /**************************** PATCHED by Flier ******************************/ /*static void*/ void /****************************************************************************/ describe(command, args, subargs) char *command, *args, *subargs; { char *target; /**************************** PATCHED by Flier ******************************/ char *thing; char *curchan; #ifdef WANTANSI char tmpbuf[mybufsize/2]; #endif #ifdef HAVE_ICONV_H if (get_int_var(HIGH_ASCII_VAR)) thing="\342\210\236"; #else if (get_int_var(HIGH_ASCII_VAR)) thing="ì"; #endif /* HAVE_ICONV_H */ else thing="*"; /****************************************************************************/ target = next_arg(args, &args); if (target && args && *args) { int old, from_level; #ifdef LYNX_STUFF char *result; #endif /* LYNX_STUFF */ char *message; #ifdef LYNX_STUFF if (result = prepare_action(args)) message = result; else #endif /* LYNX_STUFF */ message = args; old = set_lastlog_msg_level(LOG_ACTION); save_message_from(); from_level = message_from_level(LOG_ACTION); send_action(target, message); if (do_hook(SEND_ACTION_LIST, "%s %s", target, message)) /**************************** PATCHED by Flier ******************************/ /*put_it("* -> %s: %s %s", target, get_server_nickname(from_server), message);*/ { char *stampbuf=TimeStamp(2); if ((curchan=get_channel_by_refnum(0)) && !my_stricmp(curchan,target)) { #ifdef WANTANSI char *tmpstr=(char *) 0; malloc_strcpy(&tmpstr,stampbuf); malloc_strcat(&tmpstr,CmdsColors[COLME].color1); put_it("%s%s%s %s%s%s %s%s%s", tmpstr,thing,Colors[COLOFF], CmdsColors[COLME].color2,get_server_nickname(from_server),Colors[COLOFF], CmdsColors[COLME].color5,message,Colors[COLOFF]); new_free(&tmpstr); #else put_it("%s%c%s%c %s %s",stampbuf,bold,thing,bold, get_server_nickname(from_server),message); #endif } else { #ifdef WANTANSI snprintf(tmpbuf,sizeof(tmpbuf),"<%s%s%s> %s%s%s %s%s%s", CmdsColors[COLME].color4,target,Colors[COLOFF], CmdsColors[COLME].color1,thing,Colors[COLOFF], CmdsColors[COLME].color2,get_server_nickname(from_server),Colors[COLOFF]); put_it("%s%s %s%s%s",stampbuf,tmpbuf, CmdsColors[COLME].color5,message,Colors[COLOFF]); #else put_it("%s<%s> %c%s%c %s %s",stampbuf,target,bold,thing,bold, get_server_nickname(from_server),message); #endif } } /****************************************************************************/ set_lastlog_msg_level(old); restore_message_from(); #ifdef LYNX_STUFF if (result) new_free(&result); #endif } else say("Usage: /DESCRIBE "); } /* * New 'me' command - now automatically appends period. * Necessary for new 'action' script. -lynx'92 * Hardly, removed this as it was generally considered offensive */ /**************************** PATCHED by Flier ******************************/ /*static void*/ void /****************************************************************************/ me(command, args, subargs) char *command, *args, *subargs; { /**************************** PATCHED by Flier ******************************/ char *thing; #ifdef HAVE_ICONV_H if (get_int_var(HIGH_ASCII_VAR)) thing="\342\210\236"; #else if (get_int_var(HIGH_ASCII_VAR)) thing="ì"; #endif /* HAVE_ICONV_H */ else thing="*"; /****************************************************************************/ if (args && *args) { char *target; if ((target = get_target_by_refnum(0)) != NULL) { int old; #ifdef LYNX_STUFF char *result; #endif /* LYNX_STUFF */ char *message; /* handle "/ foo" */ if (!strncmp(target, get_string_var(CMDCHARS_VAR), 1) && (!(target = get_channel_by_refnum(0)))) { say("No target, neither channel nor query"); return; } #ifdef LYNX_STUFF if (result = prepare_action(args)) message = result; else #endif /* LYNX_STUFF */ message = args; old = set_lastlog_msg_level(LOG_ACTION); save_message_from(); message_from(target, LOG_ACTION); send_action(target, message); if (do_hook(SEND_ACTION_LIST, "%s %s", target, message)) /**************************** PATCHED by Flier ******************************/ /*put_it("* %s %s", get_server_nickname(from_server), message);*/ { #ifdef WANTANSI char *tmpstr=(char *) 0; #endif char *stampbuf=TimeStamp(2); #ifdef WANTANSI malloc_strcpy(&tmpstr,stampbuf); malloc_strcat(&tmpstr,CmdsColors[COLME].color1); put_it("%s%s%s %s%s%s %s%s%s", tmpstr,thing,Colors[COLOFF], CmdsColors[COLME].color2,get_server_nickname(from_server),Colors[COLOFF], CmdsColors[COLME].color5,message,Colors[COLOFF]); new_free(&tmpstr); #else put_it("%s%c%s%c %s %s",stampbuf,bold,thing,bold, get_server_nickname(from_server), message); #endif } /****************************************************************************/ set_lastlog_msg_level(old); restore_message_from(); #ifdef LYNX_STUFF if (result) new_free(&result); #endif } else say("No target, neither channel nor query"); } else say("Usage: /ME "); } #ifndef LITE static void mload(command, args, subargs) char *command, *args, *subargs; { char *file; while ((file = next_arg(args, &args)) != NULL) load_menu(file); } static void mlist(command, args, subargs) char *command, *args, *subargs; { char *menu; while ((menu = new_next_arg(args, &args)) != NULL) (void) ShowMenu(menu); } #endif /* LITE */ static void evalcmd(command, args, subargs) char *command, *args, *subargs; { parse_line(NULL, args, subargs ? subargs : empty_string, 0, 0, 0); } /* * execute_timer: checks to see if any currently pending timers have * gone off, and if so, execute them, delete them, etc, setting the * current_exec_timer, so that we can't remove the timer while its * still executing. */ extern void execute_timer() { struct timeval current; TimerList *next; int old_in_on_who, old_server = from_server; gettimeofday(¤t, NULL); while (PendingTimers && (PendingTimers->time < current.tv_sec || (PendingTimers->time == current.tv_sec && PendingTimers->microseconds <= current.tv_usec))) { old_in_on_who = in_on_who; in_on_who = PendingTimers->in_on_who; current_exec_timer = PendingTimers->ref; save_message_from(); (void)message_from_level(LOG_CURRENT); if (PendingTimers->server >= 0) from_server = PendingTimers->server; /**************************** PATCHED by Flier ******************************/ /*parse_command(PendingTimers->command, 0, empty_string);*/ if (PendingTimers->func) PendingTimers->func(PendingTimers->command); else parse_command(PendingTimers->command, 0, empty_string); /****************************************************************************/ from_server = old_server; restore_message_from(); current_exec_timer = -1; new_free(&PendingTimers->command); next = PendingTimers->next; new_free(&PendingTimers); PendingTimers = next; in_on_who = old_in_on_who; } } /* * timercmd: the bit that handles the TIMER command. If there are no * arguements, then just list the currently pending timers, if we are * give a -DELETE flag, attempt to delete the timer from the list. Else * consider it to be a timer to add, and add it. */ /**************************** PATCHED by Flier ******************************/ /*static void*/ void /****************************************************************************/ timercmd(command, args, subargs) char *command; char *args, *subargs; { char *waittime, *flag; struct timeval timertime; long waitsec, waitusec; TimerList **slot, *ntimer; int want = -1, refnum; /**************************** PATCHED by Flier ******************************/ int visible = 1; if (!strcmp(command,"FTIMER")) command = "TIMER"; else subargs = NULL; /****************************************************************************/ if (*args == '-') { size_t len; flag = next_arg(args, &args); len = strlen(flag); upper(flag); /* first check for the -DELETE flag */ if (!strncmp(flag, "-DELETE", len)) { char *ptr; int ref; TimerList *tmp, *prev; if (current_exec_timer != -1) { say("You may not remove a TIMER from itself"); return; } if (!(ptr = next_arg(args, &args))) { say("%s: Need a timer reference number for -DELETE", command); return; } ref = atoi(ptr); for (prev = tmp = PendingTimers; tmp; prev = tmp, tmp = tmp->next) { if (tmp->ref == ref) { if (tmp == prev) PendingTimers = PendingTimers->next; else prev->next = tmp->next; new_free(&tmp->command); new_free(&tmp); return; } } say("%s: Can't delete %d, no such refnum", command, ref); return; } else if (!strncmp(flag, "-REFNUM", len)) { char *ptr; ptr = next_arg(args, &args); /**************************** Patched by Flier ******************************/ if (!ptr) { say("%s: Need a reference number for -REFNUM", command); return; } /****************************************************************************/ want = atoi(ptr); if (want < 0) { say("%s: Illegal refnum %d", command, want); return; } } /**************************** PATCHED by Flier ******************************/ else if (!strncmp(flag, "-INVISIBLE", len)) visible = 0; /****************************************************************************/ else { say("%s: %s no such flag", command, flag); return; } } /* else check to see if we have no args -> list */ if (!(waittime = next_arg(args, &args))) { show_timer(command); return; } /* must be something to add */ if ((refnum = create_timer_ref(want)) == -1) { say("%s: Refnum %d already exists", command, want); return; } waitusec = waitsec = 0; while (isdigit(*waittime)) waitsec = waitsec*10 + ((*waittime++) - '0'); if (*waittime == '.') { long decimalmul = 100000; for(; isdigit(*++waittime); decimalmul /= 10) waitusec += (*waittime - '0') * decimalmul; } gettimeofday(&timertime, NULL); timertime.tv_sec += waitsec; timertime.tv_usec+= waitusec; timertime.tv_sec += (timertime.tv_usec/1000000); timertime.tv_usec %= 1000000; ntimer = (TimerList *) new_malloc(sizeof(TimerList)); ntimer->in_on_who = in_on_who; ntimer->time = timertime.tv_sec; ntimer->microseconds = timertime.tv_usec; /**************************** PATCHED by Flier ******************************/ ntimer->visible = visible; if (subargs) ntimer->func = (void *) subargs; else ntimer->func = NULL; /****************************************************************************/ ntimer->server = from_server; ntimer->ref = refnum; ntimer->command = NULL; malloc_strcpy(&ntimer->command, args); /* we've created it, now put it in order */ for (slot = &PendingTimers; *slot; slot = &(*slot)->next) { if ((*slot)->time > ntimer->time || ((*slot)->time == ntimer->time && (*slot)->microseconds > ntimer->microseconds)) break; } ntimer->next = *slot; *slot = ntimer; } /* * show_timer: Display a list of all the TIMER commands that are * pending to be executed. */ static void show_timer(command) char *command; { u_char lbuf[BIG_BUFFER_SIZE]; TimerList *tmp; struct timeval current, time_left; if (!PendingTimers) { say("%s: No commands pending to be executed", command); return; } gettimeofday(¤t, NULL); say("Timer Seconds Command"); for (tmp = PendingTimers; tmp; tmp = tmp->next) { time_left.tv_sec = tmp->time; time_left.tv_usec = tmp->microseconds; time_left.tv_sec -= current.tv_sec; if (time_left.tv_usec >= current.tv_usec) time_left.tv_usec -= current.tv_usec; else { time_left.tv_usec = time_left.tv_usec - current.tv_usec + 1000000; time_left.tv_sec--; } snprintf(lbuf, sizeof(lbuf), "%ld.%06d", (long)time_left.tv_sec, (int)time_left.tv_usec); say("%-5d %-12s %s", tmp->ref, lbuf, tmp->command); } } /* * create_timer_ref: returns the lowest unused reference number for * a timer */ static int create_timer_ref(want) int want; { TimerList *tmp; int ref = 0; int done = 0; if (want == -1) while (!done) { done = 1; for (tmp = PendingTimers; tmp; tmp = tmp->next) if (ref == tmp->ref) { ref++; done = 0; break; } } else { ref = want; for (tmp = PendingTimers; tmp; tmp = tmp->next) if (ref == tmp->ref) { ref = -1; break; } } return (ref); } /**************************** PATCHED by Flier ******************************/ /* Clean up all memory used by timers */ void CleanUpTimer() { TimerList *tmptimer; while (PendingTimers) { tmptimer = PendingTimers; PendingTimers = PendingTimers->next; new_free(&(tmptimer->command)); new_free(&tmptimer); } } /****************************************************************************/ /* * inputcmd: the INPUT command. Takes a couple of arguements... * 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. */ #ifndef LITE static void inputcmd(command, args, subargs) char *command, *args, *subargs; { char *prompt; if (!args || !*args) return; if (*args++ != '"') { say("Need \" to begin prompt for INPUT"); return; } prompt = args; if ((args = index(prompt, '"')) != NULL) *args++ = '\0'; else { say("Missing \" in INPUT"); return; } for (; *args == ' '; args++) ; add_wait_prompt(prompt, eval_inputlist, args, WAIT_PROMPT_LINE); } #endif /* * eval_inputlist: Cute little wrapper that calls parse_line() when we * get an input prompt .. */ void eval_inputlist(args, line) char *args, *line; { parse_line(NULL, args, line ? line : empty_string, 0, 0, 0); } /* pingcmd: ctcp ping, duh - phone, jan 1993. */ static void pingcmd(command, args, subargs) char *command, *args, *subargs; { char buffer[BIG_BUFFER_SIZE+1]; /**************************** PATCHED by Flier ******************************/ /*snprintf(buffer, sizeof buffer, "%s PING %ld", args, (long)time(NULL));*/ char *target; struct timeval timeofday; if (args && *args) target = new_next_arg(args, &args); else target = get_channel_by_refnum(0); if (!target) { NoWindowChannel(); return; } gettimeofday(&timeofday,NULL); snprintf(buffer, sizeof buffer, "%s PING %ld %ld", target, (long) timeofday.tv_sec,(long) timeofday.tv_usec); /****************************************************************************/ ctcp(command, buffer, empty_string); } #ifndef LITE static void xtypecmd(command, args, subargs) char *command, *args, *subargs; { char *arg; size_t len; if (args && *args == '-') { args++; if ((arg = next_arg(args, &args)) != NULL) { len = strlen(arg); if (!my_strnicmp(arg, "LITERAL", len)) { for (; *args; args++) input_add_character((u_int)*args, (char *) 0); } #ifdef _Windows else if (!my_strnicmp(arg, "REPLACE", len)) { set_input(args); term_resetall(); } #endif /* _Windows */ else say ("Unknown flag -%s to XTYPE", arg); return; } input_add_character('-', (char *) 0); } else type(command, args, empty_string); return; } static void beepcmd(command, args, subargs) char *command, *args, *subargs; { term_beep(); } #endif /* LITE */