/*
* alias.c Handles command aliases for irc.c
*
* 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: alias.c,v 1.45 2006/04/30 14:15:43 f Exp $
*/
#include "irc.h"
#include "alias.h"
#include "dcc.h"
#include "status.h"
#include "edit.h"
#include "history.h"
#include "vars.h"
#include "ircaux.h"
#include "server.h"
#include "screen.h"
#include "window.h"
#include "input.h"
#include "names.h"
#include "server.h"
#include "output.h"
#include "names.h"
#include "parse.h"
#include "notify.h"
#include "ignore.h"
#include "exec.h"
#include "ircterm.h"
#include "sys/stat.h"
/*
* define this to use the old way of managing allocations
* inside the guts of alias handling (static buffers, not
* malloc & realloc'ed ones).
*/
#undef USE_OLD_ALIAS_ALLOC
/**************************** Patched by Flier ******************************/
#ifdef HAVE_REGCOMP
#include <regex.h>
#endif
#include "myvars.h"
extern int OpenFileRead _((char *));
extern int OpenFileWrite _((char *, char *));
extern int FileClose _((int));
extern int FileEof _((int));
extern int FileWrite _((int, char *));
extern char *FileRead _((int));
extern struct friends *CheckUsers _((char *, char *));
extern void StripAnsi _((char *, char *, int));
extern struct autobankicks *CheckABKs _((char *, char *));
extern NickList *CheckJoiners _((char *, char *, int , ChannelList *));
extern void BuildPrivs _((struct friends *, char *));
extern void PrintUsage _((char *));
extern int ColorNumber _((char *));
extern char *TimeStamp _((int));
#ifndef CELESCRP
extern int TotalSendDcc _((void));
extern int TotalQueue _((void));
extern int is_voiced _((char *, char *));
#endif
extern char VersionInfo[];
extern char *ScrollZver1;
/****************************************************************************/
extern int parse_number _((char **));
static char *next_unit _((char *, char *, int *, int));
/**************************** PATCHED by Flier ******************************/
/*static long randm _((long));*/
/****************************************************************************/
static char *lastop _((char *));
static char *arg_number _((int, int, char *));
static void do_alias_string _((void));
static Alias *find_alias _((Alias **, char *, int, int *));
static void insert_alias _((Alias **, Alias *));
static char *alias_arg _((char **, u_int *));
static char *find_inline _((char *));
static u_char *built_in_alias _((int));
#ifndef USE_OLD_ALIAS_ALLOC
static void expander_addition _((char **, char *, int, char *));
static char *alias_special_char _((char *, char **, char *, char *, char *, int *));
#else /* USE_OLD_ALIAS_ALLOC */
static void expander_addition _((char *, char *, int, char *));
static char *alias_special_char _((char *, char *, char *, char *, char *, int *));
#endif /* USE_OLD_ALIAS_ALLOC */
static u_char *alias_detected _((void));
static u_char *alias_sent_nick _((void));
static u_char *alias_recv_nick _((void));
#ifndef LITE
static u_char *alias_msg_body _((void));
#endif
static u_char *alias_joined_nick _((void));
static u_char *alias_public_nick _((void));
static u_char *alias_dollar _((void));
static u_char *alias_channel _((void));
static u_char *alias_server _((void));
static u_char *alias_query_nick _((void));
static u_char *alias_target _((void));
static u_char *alias_nick _((void));
static u_char *alias_invite _((void));
static u_char *alias_cmdchar _((void));
#ifndef LITE
static u_char *alias_line _((void));
#endif
static u_char *alias_away _((void));
static u_char *alias_oper _((void));
static u_char *alias_chanop _((void));
static u_char *alias_modes _((void));
static u_char *alias_buffer _((void));
static u_char *alias_time _((void));
static u_char *alias_version _((void));
static u_char *alias_currdir _((void));
static u_char *alias_current_numeric _((void));
static u_char *alias_server_version _((void));
/**************************** Patched by Flier ******************************/
static u_char *alias_ScrollZ_version _((void));
/*static char *function_pattern _((void));
static char *function_chops _((void));
static char *function_chnops _((void));*/
/* Patched by Zakath */
#ifdef CELE
static u_char *alias_Celerity_version _((void));
#endif
/* ***************** */
/****************************************************************************/
typedef struct
{
char name;
u_char *(*func) _((void));
} BuiltIns;
static FAR BuiltIns built_in[] =
{
{ '.', alias_sent_nick },
{ ',', alias_recv_nick },
{ ':', alias_joined_nick },
{ ';', alias_public_nick },
{ '$', alias_dollar },
{ 'A', alias_away },
#ifndef LITE
{ 'B', alias_msg_body },
#endif
{ 'C', alias_channel },
{ 'D', alias_detected },
/*
{ 'E' },
{ 'F' },
{ 'G' },
*/
{ 'H', alias_current_numeric },
{ 'I', alias_invite },
/**************************** PATCHED by Flier ******************************/
/*
{ 'J' },
*/
{ 'J', alias_ScrollZ_version },
/****************************************************************************/
{ 'K', alias_cmdchar },
#ifndef LITE
{ 'L', alias_line },
#endif
{ 'M', alias_modes },
{ 'N', alias_nick },
{ 'O', alias_oper },
{ 'P', alias_chanop },
{ 'Q', alias_query_nick },
{ 'R', alias_server_version },
{ 'S', alias_server },
{ 'T', alias_target },
{ 'U', alias_buffer },
{ 'V', alias_version },
{ 'W', alias_currdir },
/**************************** PATCHED by Flier ******************************/
/*
{ 'X' },
{ 'Y' },
*/
#ifdef CELE
{ 'Y', alias_Celerity_version },
#endif
/****************************************************************************/
{ 'Z', alias_time },
{ (char) 0, NULL }
};
/**************************** PATCHED by Flier ******************************/
/*char *command_line = (char *) 0;*/
/****************************************************************************/
u_char *function_left _((u_char *));
u_char *function_right _((u_char *));
u_char *function_mid _((u_char *));
u_char *function_rand _((u_char *));
u_char *function_srand _((u_char *));
u_char *function_time _((u_char *));
u_char *function_stime _((u_char *));
u_char *function_index _((u_char *));
u_char *function_rindex _((u_char *));
u_char *function_match _((u_char *));
u_char *function_rmatch _((u_char *));
u_char *function_userhost _((u_char *));
u_char *function_strip _((u_char *));
u_char *function_encode _((u_char *));
u_char *function_decode _((u_char *));
u_char *function_ischannel _((u_char *));
u_char *function_ischanop _((u_char *));
#ifdef HAVE_CRYPT
u_char *function_crypt _((u_char *));
#endif /* HAVE_CRYPT */
u_char *function_hasvoice _((u_char *));
u_char *function_dcclist _((u_char *));
u_char *function_chatpeers _((u_char *));
u_char *function_word _((u_char *));
u_char *function_winnum _((u_char *));
u_char *function_winnam _((u_char *));
u_char *function_winrows _((u_char *));
u_char *function_wincols _((u_char *));
u_char *function_winvisible _((u_char *));
u_char *function_winserver _((u_char *));
u_char *function_winservergroup _((u_char *));
u_char *function_connect _((u_char *));
u_char *function_listen _((u_char *));
u_char *function_tdiff _((u_char *));
u_char *function_toupper _((u_char *));
u_char *function_tolower _((u_char *));
u_char *function_channels _((u_char *));
u_char *function_servers _((u_char *));
u_char *function_servertype _((u_char *));
u_char *function_curpos _((u_char *));
u_char *function_onchannel _((u_char *));
u_char *function_pid _((u_char *));
u_char *function_ppid _((u_char *));
/**************************** PATCHED by Flier ******************************/
#ifndef CELESCRP
u_char *function_chanusers _((u_char *));
#endif
/****************************************************************************/
u_char *function_idle _((u_char *));
u_char *function_querynick _((u_char *));
#ifdef HAVE_STRFTIME
u_char *function_strftime _((u_char *));
#endif /* HAVE_STRFTIME */
/**************************** PATCHED by Flier ******************************/
#ifndef LITE
u_char *function_windows _((u_char *));
u_char *function_screens _((u_char *));
u_char *function_notify _((u_char *));
u_char *function_ignored _((u_char *));
u_char *function_urlencode _((u_char *));
u_char *function_shellfix _((u_char *));
u_char *function_filestat _((u_char *));
#endif
u_char *function_open _((u_char *));
u_char *function_close _((u_char *));
u_char *function_write _((u_char *));
u_char *function_read _((u_char *));
u_char *function_eof _((u_char *));
u_char *function_rename _((u_char *));
u_char *function_intuhost _((u_char *));
u_char *function_checkuser _((u_char *));
u_char *function_checkshit _((u_char *));
u_char *function_stripansi _((u_char *));
#ifndef CELESCRP
u_char *function_isvoiced _((u_char *));
u_char *function_uhost _((u_char *));
u_char *function_hhost _((u_char *));
u_char *function_topic _((u_char *));
u_char *function_strlen _((u_char *));
u_char *function_strnum _((u_char *));
#endif
u_char *function_fsize _((u_char *));
u_char *function_chankey _((u_char *));
#ifndef CELESCRP
u_char *function_sar _((u_char *));
u_char *function_cdccslots _((u_char *));
u_char *function_cdccqslots _((u_char *));
u_char *function_url _((u_char *));
u_char *function_strstr _((u_char *));
u_char *function_szvar _((u_char *));
u_char *function_stamp _((u_char *));
#endif
#ifdef HAVE_REGCOMP
u_char *function_regexp _((u_char *));
u_char *function_regexpreplace _((u_char *));
#endif /* REGCOMP */
#ifdef COUNTRY
u_char *function_country _((u_char *));
#endif
#ifdef WANTANSI
u_char *function_color _((u_char *));
#endif
/* u_char *function_pattern _((u_char *));
u_char *function_chops _((u_char *));
u_char *function_chnops _((u_char *)); */
/****************************************************************************/
typedef struct
{
char *name;
u_char *(*func) _((u_char *));
} BuiltInFunctions;
static BuiltInFunctions FAR built_in_functions[] =
{
/**************************** Patched by Flier ******************************/
{ "UH", function_intuhost },
#ifndef CELE
{ "STAMP", function_stamp },
#endif
/****************************************************************************/
{ "LEFT", function_left },
{ "RIGHT", function_right },
{ "MID", function_mid },
{ "RAND", function_rand },
{ "SRAND", function_srand },
{ "TIME", function_time },
#ifndef LITE
{ "TDIFF", function_tdiff },
{ "STIME", function_stime },
#endif
{ "INDEX", function_index },
{ "RINDEX", function_rindex },
/**************************** PATCHED by Flier ******************************/
#ifdef HAVE_REGCOMP
{ "REGEXP", function_regexp },
{ "REGEXPREP", function_regexpreplace },
#endif /* HAVE_REGCOMP */
/****************************************************************************/
{ "MATCH", function_match },
#ifndef LITE
{ "RMATCH", function_rmatch },
#endif
{ "USERHOST", function_userhost },
{ "STRIP", function_strip },
{ "ENCODE", function_encode },
{ "DECODE", function_decode },
/**************************** Patched by Flier ******************************/
{ "STRIPANSI", function_stripansi },
#if !defined(CELESCRP) && !defined(LITE)
{ "STRSTR", function_strstr },
{ "STRLEN", function_strlen },
{ "STRNUM", function_strnum },
{ "UHOST", function_uhost },
{ "HHOST", function_hhost },
#endif
{ "CHECKUSER", function_checkuser },
{ "CHECKSHIT", function_checkshit },
/****************************************************************************/
{ "ISCHANNEL", function_ischannel },
{ "ISCHANOP", function_ischanop },
#if defined(HAVE_CRYPT) && !defined(LITE)
{ "CRYPT", function_crypt },
#endif /* HAVE_CRYPT */
/**************************** PATCHED by Flier ******************************/
#if !defined(CELESCRP) && !defined(LITE)
{ "HASVOICE", function_hasvoice },
#endif
/****************************************************************************/
#ifndef LITE
{ "DCCLIST", function_dcclist },
{ "CHATPEERS", function_chatpeers },
#endif
{ "WORD", function_word },
#ifndef LITE
{ "WINNUM", function_winnum },
{ "WINNAM", function_winnam },
{ "WINVIS", function_winvisible },
{ "WINROWS", function_winrows },
{ "WINCOLS", function_wincols },
{ "WINSERVER", function_winserver },
#endif
{ "WINSERVERGROUP", function_winservergroup },
#ifndef LITE
{ "CONNECT", function_connect },
{ "LISTEN", function_listen },
#endif
{ "TOUPPER", function_toupper },
{ "TOLOWER", function_tolower },
{ "MYCHANNELS", function_channels },
#ifndef LITE
{ "MYSERVERS", function_servers },
{ "SERVERTYPE", function_servertype },
{ "CURPOS", function_curpos },
#endif
/**************************** PATCHED by Flier ******************************/
#if defined(WANTANSI) && !defined(LITE)
{ "COLOR", function_color },
#endif
/****************************************************************************/
{ "ONCHANNEL", function_onchannel },
#ifndef LITE
{ "PID", function_pid },
{ "PPID", function_ppid },
#endif
/**************************** PATCHED by Flier ******************************/
#ifndef CELESCRP
{ "CHANUSERS", function_chanusers },
#endif
/****************************************************************************/
#ifdef HAVE_STRFTIME
{ "STRFTIME", function_strftime },
#endif
{ "IDLE", function_idle },
{ "QUERYNICK", function_querynick },
/**************************** PATCHED by Flier ******************************/
#ifndef LITE
{ "WINDOWS", function_windows },
{ "SCREENS", function_screens },
{ "NOTIFY", function_notify },
{ "IGNORED", function_ignored },
{ "URLENCODE", function_urlencode },
{ "SHELLFIX", function_shellfix },
{ "FILESTAT", function_filestat },
#endif
/*{ "PATTERN", function_pattern },
{ "CHOPS", function_chops },
{ "CHNOPS", function_chnops },*/
#if !defined(CELESCRP) && !defined(LITE)
{ "SZVAR", function_szvar },
{ "TOPIC", function_topic },
{ "SAR", function_sar },
#endif
#ifdef COUNTRY
{ "COUNTRY", function_country },
#endif
#if !defined(CELESCRP) && !defined(LITE)
{ "URL", function_url },
{ "CDCCSLOTS", function_cdccslots },
{ "CDCCQSLOTS", function_cdccqslots },
#endif
{ "CHANKEY", function_chankey },
#ifndef LITE
{ "OPEN", function_open },
{ "FSIZE", function_fsize },
{ "CLOSE", function_close },
{ "READ", function_read },
{ "WRITE", function_write },
{ "EOF", function_eof },
{ "RENAME", function_rename },
#endif
/****************************************************************************/
{ (char *) 0, NULL }
};
/* alias_illegals: characters that are illegal in alias names */
char alias_illegals[] = " #+-*/\\()={}[]<>!@$%^~`,?;:|'\"";
static Alias *alias_list[] =
{
(Alias *) 0,
(Alias *) 0
};
/* alias_string: the thing that gets replaced by the $"..." construct */
static char *alias_string = (char *) 0;
static int eval_args;
/* function_stack and function_stkptr - hold the return values from functions */
static u_char * FAR function_stack[128] =
{
(u_char *) 0
};
static int function_stkptr = 0;
/*
* find_alias: looks up name in in alias list. Returns the Alias entry if
* found, or null if not found. If do_unlink is set, the found entry is
* removed from the list as well. If match is null, only perfect matches
* will return anything. Otherwise, the number of matches will be returned.
*/
static Alias *
find_alias(list, name, do_unlink, match)
Alias **list;
char *name;
int do_unlink;
int *match;
{
Alias *tmp,
*last = (Alias *) 0;
int cmp;
size_t len;
int (*cmp_func) _((char *, char *, size_t));
if (match)
{
*match = 0;
cmp_func = my_strnicmp;
}
else
cmp_func = (int (*) _((char *, char *, size_t))) my_stricmp;
if (name)
{
len = strlen(name);
for (tmp = *list; tmp; tmp = tmp->next)
{
if ((cmp = cmp_func(name, tmp->name, len)) == 0)
{
if (do_unlink)
{
if (last)
last->next = tmp->next;
else
*list = tmp->next;
}
if (match)
{
(*match)++;
if (strlen(tmp->name) == len)
{
*match = 0;
return (tmp);
}
}
else
return (tmp);
}
else if (cmp < 0)
break;
last = tmp;
}
}
if (match && (*match == 1))
return (last);
else
return ((Alias *) 0);
}
/*
* insert_alias: adds the given alias to the alias list. The alias list is
* alphabetized by name
*/
static void
insert_alias(list, nalias)
Alias **list;
Alias *nalias;
{
Alias *tmp,
*last,
*foo;
last = (Alias *) 0;
for (tmp = *list; tmp; tmp = tmp->next)
{
if (strcmp(nalias->name, tmp->name) < 0)
break;
last = tmp;
}
if (last)
{
foo = last->next;
last->next = nalias;
nalias->next = foo;
}
else
{
nalias->next = *list;
*list = nalias;
}
}
/*
* add_alias: given the alias name and "stuff" that makes up the alias,
* add_alias() first checks to see if the alias name is already in use... if
* so, the old alias is replaced with the new one. If the alias is not
* already in use, it is added.
*/
void
add_alias(type, name, stuff)
int type;
char *name,
*stuff;
{
Alias *tmp;
char *ptr;
upper(name);
if (type == COMMAND_ALIAS)
say("Alias %s added", name);
else
{
if (!strcmp(name, "FUNCTION_RETURN"))
{
if (function_stack[function_stkptr])
new_free(&function_stack[function_stkptr]);
malloc_strcpy((char **) &function_stack[function_stkptr], stuff);
return;
}
if ((ptr = sindex(name, alias_illegals)) != NULL)
{
yell("Assign names may not contain '%c'", *ptr);
return;
}
say("Assign %s added", name);
}
if ((tmp = find_alias(&(alias_list[type]), name, 1, (int *) 0)) ==
(Alias *) 0)
{
tmp = (Alias *) new_malloc(sizeof(Alias));
if (tmp == (Alias *) 0)
{
yell("Couldn't allocate memory for new alias!");
return;
}
tmp->name = (char *) 0;
tmp->stuff = (char *) 0;
}
malloc_strcpy(&(tmp->name), name);
malloc_strcpy(&(tmp->stuff), stuff);
tmp->mark = 0;
tmp->global = loading_global;
insert_alias(&(alias_list[type]), tmp);
}
/* alias_arg: a special version of next_arg for aliases */
static char *
alias_arg(str, pos)
char **str;
u_int *pos;
{
char *ptr;
if (!*str)
return (char *) 0;
*pos = 0;
ptr = *str;
while (' ' == *ptr)
{
ptr++;
(*pos)++;
}
if (*ptr == '\0')
{
*str = empty_string;
return ((char *) 0);
}
if ((*str = sindex(ptr, " ")) != NULL)
*((*str)++) = '\0';
else
*str = empty_string;
return (ptr);
}
/* word_count: returns the number of words in the given string */
extern int
word_count(str)
char *str;
{
int cnt = 0;
char *ptr;
while (1)
{
if ((ptr = sindex(str, "^ ")) != NULL)
{
cnt++;
if ((str = sindex(ptr, " ")) == (char *) 0)
return (cnt);
}
else
return (cnt);
}
}
static u_char *
built_in_alias(c)
int c;
{
BuiltIns *tmp;
u_char *ret = (u_char *) 0;
for (tmp = built_in; tmp->name; tmp++)
if ((char)c == tmp->name)
{
malloc_strcpy((char **) &ret, (char *) tmp->func());
break;
}
return (ret);
}
/*
* find_inline: This simply looks up the given str. It first checks to see
* if its a user variable and returns it if so. If not, it checks to see if
* it's an IRC variable and returns it if so. If not, it checks to see if
* its and environment variable and returns it if so. If not, it returns
* null. It mallocs the returned string
*/
static char *
find_inline(str)
char *str;
{
Alias *nalias;
char *ret = NULL;
char *tmp;
if ((nalias = find_alias(&(alias_list[VAR_ALIAS]), str, 0, (int *) NULL))
!= NULL)
{
malloc_strcpy(&ret, nalias->stuff);
return (ret);
}
if ((strlen(str) == 1) && (ret = (char *) built_in_alias(*str)))
return(ret);
if ((ret = make_string_var(str)) != NULL)
return (ret);
#ifdef DAEMON_UID
if (getuid() == DAEMON_UID)
malloc_strcpy(&ret, (getuid() != DAEMON_UID) && (tmp = getenv(str)) ?
tmp : empty_string);
#else
malloc_strcpy(&ret, (tmp = getenv(str)) ? tmp : empty_string);
#endif /* DAEMON_UID */
return (ret);
}
char *
call_function(name, f_args, args, args_flag)
char *name,
*f_args,
*args;
int *args_flag;
{
u_char *tmp;
u_char *result = (u_char *) 0;
char *sub_buffer = (char *) 0;
int builtnum;
char *debug_copy = (char *) 0;
char *cmd = (char *) 0;
malloc_strcpy(&cmd, name);
upper(cmd);
tmp = (u_char *) expand_alias((char *) 0, f_args, args, args_flag, NULL);
if (get_int_var(DEBUG_VAR) & DEBUG_FUNCTIONS)
malloc_strcpy(&debug_copy, (char *) tmp);
for (builtnum = 0; built_in_functions[builtnum].name != NULL &&
strcmp((char *) built_in_functions[builtnum].name, cmd);
builtnum++)
;
new_free(&cmd);
if (built_in_functions[builtnum].name)
result = built_in_functions[builtnum].func(tmp);
else
{
sub_buffer = new_malloc(strlen(name)+strlen((char *) tmp)+2);
strcpy(sub_buffer, name);
strcat(sub_buffer, " ");
strcat(sub_buffer, (char *) tmp);
function_stack[++function_stkptr] = (u_char *) 0;
parse_command(sub_buffer, 0, empty_string);
new_free(&sub_buffer);
eval_args=1;
result = function_stack[function_stkptr];
function_stack[function_stkptr] = (u_char *) 0;
if (!result)
malloc_strcpy((char **) &result, empty_string);
function_stkptr--;
}
if (debug_copy)
{
yell("Function %s(%s) returned %s",
name, debug_copy, result);
new_free(&debug_copy);
}
new_free(&tmp);
return (result);
}
/* Given a pointer to an operator, find the last operator in the string */
static char *
lastop(ptr)
char *ptr;
{
while (ptr[1] && index("!=<>&^|#+/-*", ptr[1]))
ptr++;
return ptr;
}
#define NU_EXPR 0
#define NU_CONJ NU_EXPR
#define NU_ASSN 1
#define NU_COMP 2
#define NU_ADD 3
#define NU_MULT 4
#define NU_UNIT 5
#define NU_TERT 6
#define NU_BITW 8
static char *
next_unit(str, args, arg_flag, stage)
char *str,
*args;
int *arg_flag,
stage;
{
char *ptr,
*ptr2,
*right;
int got_sloshed = 0;
char *lastc;
char tmp[40];
char *result1 = (char *) 0,
*result2 = (char *) 0;
long value1 = 0,
value2,
value3;
char op;
int display;
char *ArrayIndex,
*EndIndex;
while (isspace(*str))
++str;
if (!*str)
{
malloc_strcpy(&result1, empty_string);
return result1;
}
lastc = str+strlen(str)-1;
while (isspace(*lastc))
*lastc-- = '\0';
if (stage == NU_UNIT && *lastc == ')' && *str == '(')
{
str++, *lastc-- = '\0';
return next_unit(str, args, arg_flag, NU_EXPR);
}
if (!*str)
{
malloc_strcpy(&result1, empty_string);
return result1;
}
for (ptr = str; *ptr; ptr++)
{
if (got_sloshed) /* Help! I'm drunk! */
{
got_sloshed = 0;
continue;
}
switch(*ptr)
{
case '\\':
got_sloshed = 1;
continue;
case '(':
if (stage != NU_UNIT || ptr == str)
{
if (!(ptr2 = MatchingBracket(ptr+1, (int)'(', (int)')')))
ptr = ptr+strlen(ptr)-1;
else
ptr = ptr2;
break;
}
*ptr++ = '\0';
right = ptr;
ptr = MatchingBracket(right, (int)LEFT_PAREN, (int)RIGHT_PAREN);
if (ptr)
*ptr++ = '\0';
result1 = (char *)call_function(str, right, args, arg_flag);
if (ptr && *ptr)
{
malloc_strcat(&result1, ptr);
result2 = next_unit(result1, args, arg_flag,
stage);
new_free(&result1);
result1 = result2;
}
return result1;
case '[':
if (stage != NU_UNIT)
{
if (!(ptr2 = MatchingBracket(ptr+1, (int)'[', (int)']')))
ptr = ptr+strlen(ptr)-1;
else
ptr = ptr2;
break;
}
*ptr++ = '\0';
right = ptr;
ptr = MatchingBracket(right, (int)LEFT_BRACKET, (int)RIGHT_BRACKET);
if (ptr)
*ptr++ = '\0';
result1 = expand_alias((char *) 0, right, args, arg_flag, NULL);
if (*str)
{
result2 = new_malloc(strlen(str)+
(result1?strlen(result1):0)+
(ptr?strlen(ptr):0) + 2);
strcpy(result2, str);
strcat(result2, ".");
strcat(result2, result1);
new_free(&result1);
if (ptr && *ptr)
{
strcat(result2, ptr);
result1 = next_unit(result2, args,
arg_flag, stage);
}
else
{
result1 = find_inline(result2);
if (!result1)
malloc_strcpy(&result1,
empty_string);
}
new_free(&result2);
}
else if (ptr && *ptr)
{
malloc_strcat(&result1, ptr);
result2 = next_unit(result1, args, arg_flag,
stage);
new_free(&result1);
result1 = result2;
}
return result1;
case '-':
case '+':
if (*(ptr+1) == *(ptr)) /* index operator */
{
char *tptr;
*ptr++ = '\0';
if (ptr == str + 1) /* Its a prefix */
{
tptr = str + 2;
}
else /* Its a postfix */
{
tptr = str;
}
result1 = find_inline(tptr);
if (!result1)
malloc_strcpy(&result1, irczero);
{ /* This isnt supposed to be
attached to the if, so
dont "fix" it. */
int r;
r = atoi(result1);
if (*ptr == '+')
r++;
else r--;
snprintf(tmp, sizeof tmp, "%d", r);
display = window_display;
window_display = 0;
add_alias(VAR_ALIAS, tptr, tmp);
window_display = display;
}
/* A kludge? Cheating? Maybe.... */
if (ptr == str + 1)
{
*(ptr-1) = ' ';
*ptr = ' ';
} else
{
if (*ptr == '+')
*(ptr-1) = '-';
else
*(ptr-1) = '+';
*ptr = '1';
}
ptr = str;
new_free(&result1);
break;
}
if (ptr == str) /* It's unary..... do nothing */
break;
if (stage != NU_ADD)
{
ptr = lastop(ptr);
break;
}
op = *ptr;
*ptr++ = '\0';
result1 = next_unit(str, args, arg_flag, stage);
result2 = next_unit(ptr, args, arg_flag, stage);
value1 = atol(result1);
value2 = atol(result2);
new_free(&result1);
new_free(&result2);
if (op == '-')
value3 = value1 - value2;
else
value3 = value1 + value2;
snprintf(tmp, sizeof tmp, "%ld", value3);
malloc_strcpy(&result1, tmp);
return result1;
case '/':
case '*':
case '%':
if (stage != NU_MULT)
{
ptr = lastop(ptr);
break;
}
op = *ptr;
*ptr++ = '\0';
result1 = next_unit(str, args, arg_flag, stage);
result2 = next_unit(ptr, args, arg_flag, stage);
value1 = atol(result1);
value2 = atol(result2);
new_free(&result1);
new_free(&result2);
if (op == '/')
{
if (value2)
value3 = value1 / value2;
else
{
value3 = 0;
say("Division by zero");
}
}
else
if (op == '*')
value3 = value1 * value2;
else
{
if (value2)
value3 = value1 % value2;
else
{
value3 = 0;
say("Mod by zero");
}
}
snprintf(tmp, sizeof tmp, "%ld", value3);
malloc_strcpy(&result1, tmp);
return result1;
case '#':
if (stage != NU_ADD || ptr[1] != '#')
{
ptr = lastop(ptr);
break;
}
*ptr = '\0';
ptr += 2;
result1 = next_unit(str, args, arg_flag, stage);
result2 = next_unit(ptr, args, arg_flag, stage);
malloc_strcat(&result1, result2);
new_free(&result2);
return result1;
/* Reworked - Jeremy Nelson, Feb 1994
* & or && should both be supported, each with different
* stages, same with || and ^^. Also, they should be
* short-circuit as well.
*/
case '&':
if (ptr[0] == ptr[1])
{
if (stage != NU_CONJ)
{
ptr = lastop(ptr);
break;
}
*ptr = '\0';
ptr += 2;
result1 = next_unit(str, args, arg_flag, stage);
value1 = atol(result1);
if (value1)
{
result2 = next_unit(ptr, args, arg_flag, stage);
value2 = atol(result2);
value3 = value1 && value2;
}
else
value3 = 0;
new_free(&result1);
new_free(&result2);
tmp[0] = '0' + (value3?1:0);
tmp[1] = '\0';
malloc_strcpy(&result1, tmp);
return result1;
}
else
{
if (stage != NU_BITW)
{
ptr = lastop(ptr);
break;
}
*ptr = '\0';
ptr += 1;
result1 = next_unit(str, args, arg_flag, stage);
result2 = next_unit(ptr, args, arg_flag, stage);
value1 = atol(result1);
value2 = atol(result2);
new_free(&result1);
new_free(&result2);
value3 = value1 & value2;
snprintf(tmp, sizeof tmp, "%ld", value3);
malloc_strcpy(&result1, tmp);
return result1;
}
case '|':
if (ptr[0] == ptr[1])
{
if (stage != NU_CONJ)
{
ptr = lastop(ptr);
break;
}
*ptr = '\0';
ptr += 2;
result1 = next_unit(str, args, arg_flag, stage);
value1 = atol(result1);
if (!value1)
{
result2 = next_unit(ptr, args, arg_flag, stage);
value2 = atol(result2);
value3 = value1 || value2;
}
else
value3 = 1;
new_free(&result1);
new_free(&result2);
tmp[0] = '0' + (value3 ? 1 : 0);
tmp[1] = '\0';
malloc_strcpy(&result1, tmp);
return result1;
}
else
{
if (stage != NU_BITW)
{
ptr = lastop(ptr);
break;
}
*ptr = '\0';
ptr += 1;
result1 = next_unit(str, args, arg_flag, stage);
result2 = next_unit(ptr, args, arg_flag, stage);
value1 = atol(result1);
value2 = atol(result2);
new_free(&result1);
new_free(&result2);
value3 = value1 | value2;
snprintf(tmp, sizeof tmp, "%ld", value3);
malloc_strcpy(&result1, tmp);
return result1;
}
case '^':
if (ptr[0] == ptr[1])
{
if (stage != NU_CONJ)
{
ptr = lastop(ptr);
break;
}
*ptr = '\0';
ptr += 2;
result1 = next_unit(str, args, arg_flag, stage);
result2 = next_unit(ptr, args, arg_flag, stage);
value1 = atol(result1);
value2 = atol(result2);
value1 = value1?1:0;
value2 = value2?1:0;
value3 = value1 ^ value2;
new_free(&result1);
new_free(&result2);
tmp[0] = '0' + (value3 ? 1 : 0);
tmp[1] = '\0';
malloc_strcpy(&result1, tmp);
return result1;
}
else
{
if (stage != NU_BITW)
{
ptr = lastop(ptr);
break;
}
*ptr = '\0';
ptr += 1;
result1 = next_unit(str, args, arg_flag, stage);
result2 = next_unit(ptr, args, arg_flag, stage);
value1 = atol(result1);
value2 = atol(result2);
new_free(&result1);
new_free(&result2);
value3 = value1 ^ value2;
snprintf(tmp, sizeof tmp, "%ld", value3);
malloc_strcpy(&result1, tmp);
return result1;
}
case '?':
if (stage != NU_TERT)
{
ptr = lastop(ptr);
break;
}
*ptr++ = '\0';
result1 = next_unit(str, args, arg_flag, stage);
ptr2 = index(ptr, ':');
*ptr2++ = '\0';
right = result1;
value1 = parse_number(&right);
if ((value1 == -1) && (*right == (char) 0))
value1 = 0;
if ( value1 == 0 )
while (isspace(*right))
*(right++) = '\0';
if ( value1 || *right )
result2 = next_unit(ptr, args, arg_flag, stage);
else
result2 = next_unit(ptr2, args, arg_flag, stage);
*(ptr2-1) = ':';
new_free(&result1);
return result2;
case '=':
if (ptr[1] != '=')
{
if (stage != NU_ASSN)
{
ptr = lastop(ptr);
break;
}
*ptr++ = '\0';
result1 = expand_alias((char *) 0, str,
args, arg_flag, NULL);
result2 = next_unit(ptr, args, arg_flag, stage);
display = window_display;
window_display = 0;
lastc = result1 + strlen(result1) - 1;
while (lastc > result1 && *lastc == ' ')
*lastc-- = '\0';
for (ptr = result1; *ptr == ' '; ptr++);
while ((ArrayIndex = (char *) index(ptr, '['))
!= NULL)
{
*ArrayIndex++='.';
if ((EndIndex = MatchingBracket(ArrayIndex,
(int)LEFT_BRACKET, (int)RIGHT_BRACKET)) != NULL)
{
*EndIndex++='\0';
strcat(ptr, EndIndex);
}
else
break;
}
if (*ptr)
add_alias(VAR_ALIAS, ptr, result2);
else
yell("Invalid assignment expression");
window_display = display;
new_free(&result1);
return result2;
}
if (stage != NU_COMP)
{
ptr = lastop(ptr);
break;
}
*ptr = '\0';
ptr += 2;
result1 = next_unit(str, args, arg_flag, stage);
result2 = next_unit(ptr, args, arg_flag, stage);
if (!my_stricmp(result1, result2))
malloc_strcpy(&result1, one);
else
malloc_strcpy(&result1, irczero);
new_free(&result2);
return result1;
case '>':
case '<':
if (stage != NU_COMP)
{
ptr = lastop(ptr);
break;
}
op = *ptr;
if (ptr[1] == '=')
value3 = 1, *ptr++ = '\0';
else
value3 = 0;
*ptr++ = '\0';
result1 = next_unit(str, args, arg_flag, stage);
result2 = next_unit(ptr, args, arg_flag, stage);
if (isdigit(*result1) && isdigit(*result2))
{
value1 = atol(result1);
value2 = atol(result2);
value1 = (value1 == value2) ? 0 : ((value1 <
value2) ? -1 : 1);
}
else
value1 = my_stricmp(result1, result2);
if (value1)
{
value2 = (value1 > 0) ? 1 : 0;
if (op == '<')
value2 = 1 - value2;
}
else
value2 = value3;
new_free(&result2);
snprintf(tmp, sizeof tmp, "%ld", value2);
malloc_strcpy(&result1, tmp);
return result1;
case '~':
if (ptr == str)
{
if (stage != NU_BITW)
break;
result1 = next_unit(str+1, args, arg_flag,
stage);
if (isdigit(*result1))
{
value1 = atol(result1);
value2 = ~value1;
}
else
value2 = 0;
snprintf(tmp, sizeof tmp, "%ld", value2);
malloc_strcpy(&result1, tmp);
return result1;
}
else
{
ptr = lastop(ptr);
break;
}
case '!':
if (ptr == str)
{
if (stage != NU_UNIT)
break;
result1 = next_unit(str+1, args, arg_flag,
stage);
if (isdigit(*result1))
{
value1 = atol(result1);
value2 = value1 ? 0 : 1;
}
else
{
value2 = ((*result1)?0:1);
}
snprintf(tmp, sizeof tmp, "%ld", value2);
malloc_strcpy(&result1, tmp);
return result1;
}
if (stage != NU_COMP || ptr[1] != '=')
{
ptr = lastop(ptr);
break;
}
*ptr = '\0';
ptr += 2;
result1 = next_unit(str, args, arg_flag, stage);
result2 = next_unit(ptr, args, arg_flag, stage);
if (!my_stricmp(result1, result2))
malloc_strcpy(&result1, irczero);
else
malloc_strcpy(&result1, one);
new_free(&result2);
return result1;
case ',':
/*
* this utterly kludge code is needed (?) to get
* around bugs introduced from hop's patches to
* alias.c. the $, variable stopped working
* because of this. -mrg, july 94.
*/
if (ptr == str || (ptr > str && ptr[-1] == '$'))
break;
if (stage != NU_EXPR)
{
ptr = lastop(ptr);
break;
}
*ptr++ = '\0';
result1 = next_unit(str, args, arg_flag, stage);
result2 = next_unit(ptr, args, arg_flag, stage);
new_free(&result1);
return result2;
}
}
if (stage != NU_UNIT)
return next_unit(str, args, arg_flag, stage+1);
if (isdigit(*str) || *str == '+' || *str == '-')
malloc_strcpy(&result1, str);
else
{
if (*str == '#' || *str=='@')
op = *str++;
else
op = '\0';
result1 = find_inline(str);
if (!result1)
malloc_strcpy(&result1, empty_string);
if (op)
{
if (op == '#')
value1 = word_count(result1);
else if (op == '@')
value1 = strlen(result1);
snprintf(tmp, sizeof tmp, "%ld", value1);
malloc_strcpy(&result1, tmp);
}
}
return result1;
}
/*
* parse_inline: This evaluates user-variable expression. I'll talk more
* about this at some future date. The ^ function and some fixes by
* troy@cbme.unsw.EDU.AU (Troy Rollo)
*/
char *
parse_inline(str, args, args_flag)
char *str;
char *args;
int *args_flag;
{
return next_unit(str, args, args_flag, NU_EXPR);
}
/*
* arg_number: Returns the argument 'num' from 'str', or, if 'num' is
* negative, returns from argument 'num' to the end of 'str'. You might be
* wondering what's going on down there... here goes. First we copy 'str' to
* malloced space. Then, using next_arg(), we strip out each argument ,
* putting them in arg_list, and putting their position in the original
* string in arg_list_pos. Anyway, once parsing is done, the arguments are
* returned directly from the arg_list array... or in the case of negative
* 'num', the arg_list_pos is used to return the postion of the rest of the
* args in the original string... got it? Anyway, the bad points of the
* routine: 1) Always parses out everything, even if only one arg is used.
* 2) The malloced stuff remains around until arg_number is called with a
* different string. Even then, some malloced stuff remains around. This can
* be fixed.
*/
#define LAST_ARG 8000
static char *
arg_number(lower_lim, upper_lim, str)
int lower_lim,
upper_lim;
char *str;
{
char *ptr,
*arg,
c;
int use_full = 0;
unsigned int pos,
start_pos;
static char *last_args = (char *) 0;
static char *last_range = (char *) 0;
static char **arg_list = (char **) 0;
static unsigned int *arg_list_pos = (unsigned int *) 0;
static unsigned int *arg_list_end_pos = (unsigned int *) 0;
static int arg_list_size;
if (eval_args)
{
int arg_list_limit;
eval_args = 0;
new_free(&arg_list);
new_free(&arg_list_pos);
new_free(&arg_list_end_pos);
arg_list_size = 0;
arg_list_limit = 10;
arg_list = (char **) new_malloc(sizeof(char *) *
arg_list_limit);
arg_list_pos = (unsigned int *) new_malloc(sizeof(unsigned int)
* arg_list_limit);
arg_list_end_pos = (unsigned int *) new_malloc(sizeof(unsigned
int) * arg_list_limit);
malloc_strcpy(&last_args, str);
ptr = last_args;
pos = 0;
while ((arg = alias_arg(&ptr, &start_pos)) != NULL)
{
arg_list_pos[arg_list_size] = pos;
pos += start_pos + strlen(arg);
arg_list_end_pos[arg_list_size] = pos++;
arg_list[arg_list_size++] = arg;
if (arg_list_size == arg_list_limit)
{
arg_list_limit += 10;
arg_list = (char **) new_realloc((char *) arg_list, sizeof(char *) * arg_list_limit);
arg_list_pos = (unsigned int *) new_realloc((char *) arg_list_pos, sizeof(unsigned int) * arg_list_limit);
arg_list_end_pos = (unsigned int *) new_realloc((char *) arg_list_end_pos, sizeof(unsigned int) * arg_list_limit);
}
}
}
if (upper_lim == LAST_ARG && lower_lim == LAST_ARG)
upper_lim = lower_lim = arg_list_size - 1;
if (arg_list_size == 0)
return (empty_string);
if ((upper_lim >= arg_list_size) || (upper_lim < 0))
{
use_full = 1;
upper_lim = arg_list_size - 1;
}
if (upper_lim < lower_lim)
return (empty_string);
if (lower_lim >= arg_list_size)
lower_lim = arg_list_size - 1;
else if (lower_lim < 0)
lower_lim = 0;
if ((use_full == 0) && (lower_lim == upper_lim))
return (arg_list[lower_lim]);
c = *(str + arg_list_end_pos[upper_lim]);
*(str + arg_list_end_pos[upper_lim]) = (char) 0;
malloc_strcpy(&last_range, str + arg_list_pos[lower_lim]);
*(str + arg_list_end_pos[upper_lim]) = c;
return (last_range);
}
/*
* parse_number: returns the next number found in a string and moves the
* string pointer beyond that point in the string. Here's some examples:
*
* "123harhar" returns 123 and str as "harhar"
*
* while:
*
* "hoohar" returns -1 and str as "hoohar"
*/
extern int
parse_number(str)
char **str;
{
int ret;
char *ptr;
ptr = *str;
if (isdigit(*ptr))
{
ret = atoi(ptr);
for (; isdigit(*ptr); ptr++);
*str = ptr;
}
else
ret = -1;
return (ret);
}
static void
do_alias_string()
{
malloc_strcpy(&alias_string, get_input());
irc_io_loop = 0;
}
/*
* expander_addition: This handles string width formatting for irc variables
* when [] is specified.
*/
static void
expander_addition(buff, add, length, quote_em)
#ifndef USE_OLD_ALIAS_ALLOC
char **buff,
#else /* USE_OLD_ALIAS_ALLOC */
char *buff,
#endif /* USE_OLD_ALIAS_ALLOC */
*add;
int length;
char *quote_em;
{
char format[40],
buffer[BIG_BUFFER_SIZE+1],
*ptr;
if (length)
{
snprintf(format, sizeof format, "%%%d.%ds", -length, (length < 0 ? -length :
length));
snprintf(buffer, sizeof buffer, format, add);
add = buffer;
}
if (quote_em)
{
ptr = double_quote(add, quote_em);
#ifndef USE_OLD_ALIAS_ALLOC
malloc_strcat(buff, ptr);
#else /* USE_OLD_ALIAS_ALLOC */
strmcat(buff, ptr, BIG_BUFFER_SIZE);
#endif /* USE_OLD_ALIAS_ALLOC */
new_free(&ptr);
}
#ifndef USE_OLD_ALIAS_ALLOC
else if (add && *add)
malloc_strcat(buff, add);
#else /* USE_OLD_ALIAS_ALLOC */
else
if (buff)
strmcat(buff, add, BIG_BUFFER_SIZE);
#endif /* USE_OLD_ALIAS_ALLOC */
}
/* MatchingBracket returns the next unescaped bracket of the given type */
char *
MatchingBracket(string, left, right)
char *string;
int left;
int right;
{
int bracket_count = 1;
while (*string && bracket_count)
{
if (*string == (char)left)
bracket_count++;
else if (*string == (char)right)
{
if (!--bracket_count)
return string;
}
else if (*string == '\\' && string[1])
string++;
string++;
}
return (char *) 0;
}
/*
* alias_special_char: Here we determin what to do with the character after
* the $ in a line of text. The special characters are described more fulling
* in the help/ALIAS file. But they are all handled here. Paremeters are the
* name of the alias (if applicable) to prevent deadly recursion, a
* destination buffer (that we are malloc_str*ing) to which things are appended,
* a ptr to the string (the first character of which is the special
* character, the args to the alias, and a character indication what
* characters in the string should be quoted with a backslash). It returns a
* pointer to the character right after the converted alias.
The args_flag is set to 1 if any of the $n, $n-, $n-m, $-m, $*, or $() is used
in the alias. Otherwise it is left unchanged.
*/
/*ARGSUSED*/
static char *
alias_special_char(name, lbuf, ptr, args, quote_em, args_flag)
char *name;
#ifndef USE_OLD_ALIAS_ALLOC
char **lbuf;
#else /* USE_OLD_ALIAS_ALLOC */
char *lbuf;
#endif /* USE_OLD_ALIAS_ALLOC */
char *ptr;
char *args;
char *quote_em;
int *args_flag;
{
char *tmp,
c;
int is_upper,
is_lower,
length;
length = 0;
if ((c = *ptr) == LEFT_BRACKET)
{
ptr++;
if ((tmp = (char *) index(ptr, RIGHT_BRACKET)) != NULL)
{
*(tmp++) = (char) 0;
length = atoi(ptr);
#ifdef USE_OLD_ALIAS_ALLOC
/* XXX hack to avoid core dumps */
if (length > ((BIG_BUFFER_SIZE * 5) / 3))
length = ((BIG_BUFFER_SIZE * 5) / 3);
#endif /* USE_OLD_ALIAS_ALLOC */
ptr = tmp;
c = *ptr;
}
else
{
say("Missing %c", RIGHT_BRACKET);
return (ptr);
}
}
tmp = ptr+1;
switch (c)
{
case LEFT_PAREN:
{
#ifndef USE_OLD_ALIAS_ALLOC
char *sub_buffer = (char *) 0;
#else /* USE_OLD_ALIAS_ALLOC */
char sub_buffer[BIG_BUFFER_SIZE+1];
#endif /* USE_OLD_ALIAS_ALLOC */
if ((ptr = MatchingBracket(tmp, (int)LEFT_PAREN,
(int)RIGHT_PAREN)) || (ptr = (char *) index(tmp,
RIGHT_PAREN)))
*(ptr++) = (char) 0;
tmp = expand_alias((char *) 0, tmp, args, args_flag,
NULL);
#ifndef USE_OLD_ALIAS_ALLOC
malloc_strcpy(&sub_buffer, empty_string);
alias_special_char((char *) 0, &sub_buffer, tmp,
#else /* USE_OLD_ALIAS_ALLOC */
*sub_buffer = (char) 0;
alias_special_char((char *) 0, sub_buffer, tmp,
#endif /* USE_OLD_ALIAS_ALLOC */
args, quote_em, args_flag);
expander_addition(lbuf, sub_buffer, length, quote_em);
#ifndef USE_OLD_ALIAS_ALLOC
new_free(&sub_buffer);
#endif /* not USE_OLD_ALIAS_ALLOC */
new_free(&tmp);
*args_flag = 1;
}
return (ptr);
case '!':
if ((ptr = (char *) index(tmp, '!')) != NULL)
*(ptr++) = (char) 0;
if ((tmp = do_history(tmp, empty_string)) != NULL)
{
expander_addition(lbuf, tmp, length, quote_em);
new_free(&tmp);
}
return (ptr);
case LEFT_BRACE:
if ((ptr = (char *) index(tmp, RIGHT_BRACE)) != NULL)
*(ptr++) = (char) 0;
if ((tmp = parse_inline(tmp, args, args_flag)) != NULL)
{
expander_addition(lbuf, tmp, length, quote_em);
new_free(&tmp);
}
return (ptr);
case DOUBLE_QUOTE:
if ((ptr = (char *) index(tmp, DOUBLE_QUOTE)) != NULL)
*(ptr++) = (char) 0;
alias_string = (char *) 0;
/* XXX - the cast in the following is an ugly hack! */
if (irc_io(tmp, (void (*) _((u_int, char *))) do_alias_string, use_input, 1))
{
yell("Illegal recursive edit");
break;
}
expander_addition(lbuf, alias_string, length, quote_em);
new_free(&alias_string);
return (ptr);
case '*':
expander_addition(lbuf, args, length, quote_em);
*args_flag = 1;
return (ptr + 1);
default:
if (isdigit(c) || (c == '-') || c == '~')
{
*args_flag = 1;
if (*ptr == '~')
{
is_lower = is_upper = LAST_ARG;
ptr++;
}
else
{
is_lower = parse_number(&ptr);
if (*ptr == '-')
{
ptr++;
is_upper = parse_number(&ptr);
}
else
is_upper = is_lower;
}
expander_addition(lbuf, arg_number(is_lower, is_upper,
args), length, quote_em);
return (ptr ? ptr : empty_string);
}
else
{
char *rest,
c2 = (char) 0;
/*
* Why use ptr+1? Cause try to maintain backward compatability
* can be a pain in the butt. Basically, we don't want any of
* the illegal characters in the alias, except that things like
* $* and $, were around first, so they must remain legal. So
* we skip the first char after the $. Does this make sense?
*/
/* special case for $ */
if (*ptr == '$')
{
rest = ptr+1;
c2 = *rest;
*rest = (char) 0;
}
else if ((rest = sindex(ptr+1, alias_illegals)) != NULL)
{
if (isalpha(*ptr) || *ptr == '_')
while ((*rest == LEFT_BRACKET ||
*rest == LEFT_PAREN) &&
(tmp = MatchingBracket(rest+1,
(int)*rest, (int)(*rest == LEFT_BRACKET) ?
RIGHT_BRACKET : RIGHT_PAREN)))
rest = tmp + 1;
c2 = *rest;
*rest = (char) 0;
}
if ((tmp = parse_inline(ptr, args, args_flag)) != NULL)
{
expander_addition(lbuf, tmp, length,
quote_em);
new_free(&tmp);
}
if (rest)
*rest = c2;
return(rest);
}
}
return NULL;
}
/*
* expand_alias: Expands inline variables in the given string and returns the
* expanded string in a new string which is malloced by expand_alias().
*
* Also unescapes anything that was quoted with a backslash
*
* Behaviour is modified by the following:
* Anything between brackets (...) {...} is left unmodified.
* If more_text is supplied, the text is broken up at
* semi-colons and returned one at a time. The unprocessed
* portion is written back into more_text.
* Backslash escapes are unescaped.
*/
char *
expand_alias(name, string, args, args_flag, more_text)
char *name,
*string,
*args;
int *args_flag;
char **more_text;
{
#ifndef USE_OLD_ALIAS_ALLOC
char *lbuf = (char *) 0,
#else /* USE_OLD_ALIAS_ALLOC */
char lbuf[BIG_BUFFER_SIZE + 1],
#endif /* USE_OLD_ALIAS_ALLOC */
*ptr,
*stuff = (char *) 0,
*free_stuff;
char *quote_em,
*quote_str = (char *) 0;
char ch;
int quote_cnt = 0;
int is_quote = 0;
#ifndef USE_OLD_ALIAS_ALLOC
void (*str_cat) _((char **, char *));
#else /* USE_OLD_ALIAS_ALLOC */
void (*str_cat) _((char *, char *, size_t));
#endif /* USE_OLD_ALIAS_ALLOC */
if (*string == '@' && more_text)
{
#ifndef USE_OLD_ALIAS_ALLOC
str_cat = malloc_strcat;
#else /* USE_OLD_ALIAS_ALLOC */
str_cat = strmcat;
#endif /* USE_OLD_ALIAS_ALLOC */
*args_flag = 1; /* Stop the @ command from auto appending */
}
else
#ifndef USE_OLD_ALIAS_ALLOC
str_cat = malloc_strcat_ue;
#else /* USE_OLD_ALIAS_ALLOC */
str_cat = strmcat_ue;
#endif /* USE_OLD_ALIAS_ALLOC */
malloc_strcpy(&stuff, string);
free_stuff = stuff;
#ifndef USE_OLD_ALIAS_ALLOC
malloc_strcpy(&lbuf, empty_string);
#else /* USE_OLD_ALIAS_ALLOC */
*lbuf = (char) 0;
#endif /* USE_OLD_ALIAS_ALLOC */
eval_args = 1;
ptr = stuff;
if (more_text)
*more_text = NULL;
while (ptr && *ptr)
{
if (is_quote)
{
is_quote = 0;
++ptr;
continue;
}
switch(*ptr)
{
case '$':
/*
* The test here ensures that if we are in the expression
* evaluation command, we don't expand $. In this case we
* are only coming here to do command separation at ';'s.
* If more_text is not defined, and the first character is
* '@', we have come here from [] in an expression.
*/
if (more_text && *string == '@')
{
ptr++;
break;
}
*(ptr++) = (char) 0;
#ifndef USE_OLD_ALIAS_ALLOC
(*str_cat)(&lbuf, stuff);
#else /* USE_OLD_ALIAS_ALLOC */
(*str_cat)(lbuf, stuff, BIG_BUFFER_SIZE);
#endif /* USE_OLD_ALIAS_ALLOC */
while (*ptr == '^')
{
ptr++;
if (quote_str)
quote_str = (char *)
new_realloc(quote_str,
sizeof(char) * (quote_cnt + 2));
else
quote_str = (char *)
new_malloc(sizeof(char) *
(quote_cnt + 2));
quote_str[quote_cnt++] = *(ptr++);
quote_str[quote_cnt] = (char) 0;
}
quote_em = quote_str;
#ifndef USE_OLD_ALIAS_ALLOC
stuff = alias_special_char(name, &lbuf, ptr, args,
#else /* USE_OLD_ALIAS_ALLOC */
stuff = alias_special_char(name, lbuf, ptr, args,
#endif /* USE_OLD_ALIAS_ALLOC */
quote_em, args_flag);
if (stuff)
new_free("e_str);
quote_cnt = 0;
ptr = stuff;
break;
case ';':
if (!more_text)
{
ptr++;
break;
}
*more_text = string + (ptr - free_stuff) +1;
*ptr = '\0'; /* To terminate the loop */
break;
case LEFT_PAREN:
case LEFT_BRACE:
ch = *ptr;
*ptr = '\0';
#ifndef USE_OLD_ALIAS_ALLOC
(*str_cat)(&lbuf, stuff);
#else /* USE_OLD_ALIAS_ALLOC */
(*str_cat)(lbuf, stuff, BIG_BUFFER_SIZE);
#endif /* USE_OLD_ALIAS_ALLOC */
stuff = ptr;
*args_flag = 1;
if (!(ptr = MatchingBracket(stuff + 1, (int)ch,
(int)(ch == LEFT_PAREN) ?
RIGHT_PAREN : RIGHT_BRACE)))
{
yell("Unmatched %c", ch);
ptr = stuff + strlen(stuff+1)+1;
}
else
ptr++;
*stuff = ch;
ch = *ptr;
*ptr = '\0';
#ifndef USE_OLD_ALIAS_ALLOC
malloc_strcat(&lbuf, stuff);
#else /* USE_OLD_ALIAS_ALLOC */
strmcat(lbuf, stuff, BIG_BUFFER_SIZE);
#endif /* USE_OLD_ALIAS_ALLOC */
stuff = ptr;
*ptr = ch;
break;
case '\\':
is_quote = 1;
ptr++;
break;
default:
ptr++;
break;
}
}
if (stuff)
#ifndef USE_OLD_ALIAS_ALLOC
(*str_cat)(&lbuf, stuff);
#else /* USE_OLD_ALIAS_ALLOC */
(*str_cat)(lbuf, stuff, BIG_BUFFER_SIZE);
#endif /* USE_OLD_ALIAS_ALLOC */
ptr = (char *) 0;
new_free(&free_stuff);
#ifndef USE_OLD_ALIAS_ALLOC
ptr = lbuf;
#else /* USE_OLD_ALIAS_ALLOC */
malloc_strcpy(&ptr, lbuf);
#endif /* USE_OLD_ALIAS_ALLOC */
if (get_int_var(DEBUG_VAR) & DEBUG_EXPANSIONS)
yell("Expanded [%s] to [%s]",
string, ptr);
return (ptr);
}
/*
* get_alias: returns the alias matching 'name' as the function value. 'args'
* are expanded as needed, etc. If no matching alias is found, null is
* returned, cnt is 0, and full_name is null. If one matching alias is
* found, it is retuned, with cnt set to 1 and full_name set to the full name
* of the alias. If more than 1 match are found, null is returned, cnt is
* set to the number of matches, and fullname is null. NOTE: get_alias()
* mallocs the space for the full_name, but returns the actual value of the
* alias if found!
*/
char *
get_alias(type, name, cnt, full_name)
int type;
char *name,
**full_name;
int *cnt;
{
Alias *tmp;
*full_name = (char *) 0;
if ((name == (char *) 0) || (*name == (char) 0))
{
*cnt = 0;
return ((char *) 0);
}
if ((tmp = find_alias(&(alias_list[type]), name, 0, cnt)) != NULL)
{
if (*cnt < 2)
{
malloc_strcpy(full_name, tmp->name);
return (tmp->stuff);
}
}
return ((char *) 0);
}
/*
* match_alias: this returns a list of alias names that match the given name.
* This is used for command completion etc. Note that the returned array is
* malloced in this routine. Returns null if no matches are found
*/
char **
match_alias(name, cnt, type)
char *name;
int *cnt;
int type;
{
Alias *tmp;
char **matches = (char **) 0;
int matches_size = 5;
size_t len;
char *last_match = (char *) 0;
char *dot;
len = strlen(name);
*cnt = 0;
matches = (char **) new_malloc(sizeof(char *) * matches_size);
for (tmp = alias_list[type]; tmp; tmp = tmp->next)
{
if (strncmp(name, tmp->name, len) == 0)
{
if ((dot = (char *) index(tmp->name+len, '.')) != NULL)
{
if (type == COMMAND_ALIAS)
continue;
else
{
*dot = '\0';
if (last_match && !strcmp(last_match,
tmp->name))
{
*dot = '.';
continue;
}
}
}
matches[*cnt] = (char *) 0;
malloc_strcpy(&(matches[*cnt]), tmp->name);
last_match = matches[*cnt];
if (dot)
*dot = '.';
if (++(*cnt) == matches_size)
{
matches_size += 5;
matches = (char **) new_realloc((char *) matches, sizeof(char *) * matches_size);
}
}
else if (*cnt)
break;
}
if (*cnt)
{
matches = (char **) new_realloc((char *) matches, sizeof(char *) * (*cnt + 1));
matches[*cnt] = (char *) 0;
}
else
new_free(&matches);
return (matches);
}
/* delete_alias: The alias name is removed from the alias list. */
void
delete_alias(type, name)
int type;
char *name;
{
Alias *tmp;
upper(name);
if ((tmp = find_alias(&(alias_list[type]), name, 1, (int *) NULL))
!= NULL)
{
new_free(&(tmp->name));
new_free(&(tmp->stuff));
new_free(&tmp);
if (type == COMMAND_ALIAS)
say("Alias %s removed", name);
else
say("Assign %s removed", name);
}
else
say("No such alias: %s", name);
}
/*
* list_aliases: Lists all aliases matching 'name'. If name is null, all
* aliases are listed
*/
void
list_aliases(type, name)
int type;
char *name;
{
Alias *tmp;
size_t len;
int lastlog_level;
size_t DotLoc,
LastDotLoc = 0;
char *LastStructName = NULL;
char *s;
lastlog_level = message_from_level(LOG_CRAP);
if (type == COMMAND_ALIAS)
say("Aliases:");
else
say("Assigns:");
if (name)
{
upper(name);
len = strlen(name);
}
else
len = 0;
for (tmp = alias_list[type]; tmp; tmp = tmp->next)
{
if (!name || !strncmp(tmp->name, name, len))
{
s = index(tmp->name + len, '.');
if (!s)
say("\t%s\t%s", tmp->name, tmp->stuff);
else
{
DotLoc = s - tmp->name;
if (!LastStructName || (DotLoc != LastDotLoc) || strncmp(tmp->name, LastStructName, DotLoc))
{
say("\t%*.*s\t<Structure>", DotLoc, DotLoc, tmp->name);
LastStructName = tmp->name;
LastDotLoc = DotLoc;
}
}
}
}
(void)message_from_level(lastlog_level);
}
/*
* mark_alias: sets the mark field of the given alias to 'flag', and returns
* the previous value of the mark. If the name is not found, -1 is returned.
* This is used to prevent recursive aliases by marking and unmarking
* aliases, and not reusing an alias that has previously been marked. I'll
* explain later
*/
int
mark_alias(name, flag)
char *name;
int flag;
{
int old_mark;
Alias *tmp;
int match;
if ((tmp = find_alias(&(alias_list[COMMAND_ALIAS]), name, 0, &match))
!= NULL)
{
if (match < 2)
{
old_mark = tmp->mark;
/* New handling of recursion */
if (flag)
{
int i;
/* Count recursion */
tmp->mark = tmp->mark + flag;
if ((i = get_int_var(MAX_RECURSIONS_VAR)) > 1)
{
if (tmp->mark > i)
{
tmp->mark = 0;
return(1); /* MAX exceeded. */
}
else return(0);
/* In recursion but it's ok */
}
else
{
if (tmp->mark > 1)
{
tmp->mark = 0;
return(1);
/* max of 1 here.. exceeded */
}
else return(0);
/* In recursion but it's ok */
}
}
else
/* Not in recursion at all */
{
tmp->mark = 0;
return(old_mark);
/* This one gets ignored anyway */
}
}
}
return (-1);
}
/*
* execute_alias: After an alias has been identified and expanded, it is sent
* here for proper execution. This routine mainly prevents recursive
* aliasing. The name is the full name of the alias, and the alias is
* already expanded alias (both of these parameters are returned by
* get_alias())
*/
void
execute_alias(alias_name, ealias, args)
char *alias_name,
*ealias,
*args;
{
if (mark_alias(alias_name, 1))
say("Maximum recursion count exceeded in: %s", alias_name);
else
{
parse_line(alias_name, ealias, args, 0, 1, 0);
mark_alias(alias_name, 0);
}
}
/*
* save_aliases: This will write all of the aliases to the FILE pointer fp in
* such a way that they can be read back in using LOAD or the -l switch
*/
void
save_aliases(fp, do_all)
FILE *fp;
int do_all;
{
Alias *tmp;
for (tmp = alias_list[VAR_ALIAS]; tmp; tmp = tmp->next)
if (!tmp->global || do_all)
fprintf(fp, "ASSIGN %s %s\n", tmp->name, tmp->stuff);
for (tmp = alias_list[COMMAND_ALIAS]; tmp; tmp = tmp->next)
if (!tmp->global || do_all)
fprintf(fp, "ALIAS %s %s\n", tmp->name, tmp->stuff);
}
/* The Built-In Alias expando functions */
#ifndef LITE
static u_char *
alias_line()
{
return ((u_char *) get_input());
}
#endif
static u_char *
alias_buffer()
{
return ((u_char *) cut_buffer);
}
static u_char *
alias_time()
{
static char timestr[16];
return ((u_char *) update_clock(timestr, 16, GET_TIME));
}
static u_char *
alias_dollar()
{
return ((u_char *) "$");
}
static u_char *
alias_detected()
{
return (last_notify_nick);
}
static u_char *
alias_nick()
{
return (u_char *) ((from_server >= 0) ? get_server_nickname(from_server) : nickname);
}
static u_char *
alias_away()
{
return (u_char *) ((from_server >= 0) ? server_list[from_server].away : empty_string);
}
static u_char *
alias_sent_nick()
{
return (sent_nick) ? sent_nick : (u_char *) empty_string;
}
static u_char *
alias_recv_nick()
{
return (recv_nick) ? recv_nick : (u_char *) empty_string;
}
#ifndef LITE
static u_char *
alias_msg_body()
{
return (sent_body) ? sent_body : (u_char *) empty_string;
}
#endif
static u_char *
alias_joined_nick()
{
return (joined_nick) ? joined_nick : (u_char *) empty_string;
}
static u_char *
alias_public_nick()
{
return (public_nick) ? public_nick : (u_char *) empty_string;
}
static u_char *
alias_channel()
{
char *tmp;
return (u_char *) ((tmp = get_channel_by_refnum(0)) ? tmp : irczero);
}
static u_char *
alias_server()
{
return (u_char *) ((parsing_server_index != -1) ?
get_server_itsname(parsing_server_index) :
(get_window_server(0) != -1) ?
get_server_itsname(get_window_server(0)) : empty_string);
}
static u_char *
alias_query_nick()
{
char *tmp;
return (u_char *) ((tmp = query_nick()) ? tmp : empty_string);
}
static u_char *
alias_target()
{
char *tmp;
return (u_char *) ((tmp = get_target_by_refnum(0)) ? tmp : empty_string);
}
static u_char *
alias_invite()
{
return (u_char *) ((invite_channel) ? invite_channel : empty_string);
}
static u_char *
alias_cmdchar()
{
static u_char thing[2];
u_char *cmdu_chars;
if ((cmdu_chars = get_string_var(CMDCHARS_VAR)) == (u_char *) 0)
cmdu_chars = DEFAULT_CMDCHARS;
thing[0] = cmdu_chars[0];
thing[1] = (u_char) 0;
return (thing);
}
static u_char *
alias_oper()
{
return (u_char *) ((from_server >= 0 && get_server_operator(from_server)) ?
get_string_var(STATUS_OPER_VAR) : empty_string);
}
static u_char *
alias_chanop()
{
u_char *tmp;
return (u_char *) ((from_server >= 0 && (tmp = get_channel_by_refnum(0)) &&
get_channel_oper(tmp, from_server)) ?
"@" : empty_string);
}
static u_char *
alias_modes()
{
u_char *tmp;
return (u_char *) ((from_server >= 0 && (tmp = get_channel_by_refnum(0))) ?
get_channel_mode(tmp, from_server) : empty_string);
}
static u_char *
alias_version()
{
return (irc_version);
}
static u_char *
alias_currdir()
{
static u_char dirbuf[1024];
getcwd(CP(dirbuf), 1024);
return (dirbuf);
}
static u_char *
alias_current_numeric()
{
static u_char number[4];
snprintf(CP(number), sizeof number, "%03d", -current_numeric);
return (number);
}
static u_char *
alias_server_version()
{
char *s;
return (u_char *) ((curr_scr_win->server >= 0 &&
(s = server_list[curr_scr_win->server].version_string)) ?
s : empty_string);
}
/**************************** PATCHED by Flier ******************************/
static u_char *alias_ScrollZ_version() {
static u_char tmpbuf[mybufsize / 16];
snprintf((char *) tmpbuf, sizeof(tmpbuf), "%s [%s]", ScrollZver1, VersionInfo);
return(tmpbuf);
}
#ifdef CELE
static u_char *alias_Celerity_version() {
static u_char tmpbuf[32];
snprintf((char *) tmpbuf, sizeof(tmpbuf), "%s", CelerityVersion);
return(tmpbuf);
}
#endif
/****************************************************************************/
/*
* alias: the /ALIAS command. Calls the correct alias function depending on
* the args
*/
void
alias(command, args, subargs)
char *command,
*args,
*subargs;
{
char *name,
*rest;
int type;
char *ArrayIndex;
char *EndIndex;
type = *command - 48; /*
* A trick! Yes, well, what the hell. Note
* the the command part of ALIAS is "0" and
* the command part of ASSIGN is "1" in the
* command array list
*/
if ((name = next_arg(args, &rest)) != NULL)
{
while ((ArrayIndex = (char *) index(name, '[')) != NULL)
{
*ArrayIndex++ = '.';
if ((EndIndex = MatchingBracket(ArrayIndex,
(int)LEFT_BRACKET, (int)RIGHT_BRACKET)) != NULL)
{
*EndIndex++ = '\0';
strcat(name, EndIndex);
}
else
break;
}
if (*rest)
{
if (*rest == LEFT_BRACE)
{
char *ptr;
ptr = MatchingBracket(++rest,
(int)LEFT_BRACE, (int)RIGHT_BRACE);
if (!ptr)
say("Unmatched brace in ALIAS or ASSIGN");
else if (ptr[1])
{
say("Junk after closing brace in ALIAS or ASSIGN");
}
else
{
*ptr = '\0';
add_alias(type, name, rest);
}
}
else
add_alias(type, name, rest);
}
else
{
if (*name == '-')
{
if (*(name + 1))
delete_alias(type, name + 1);
else
say("You must specify an alias to be removed");
}
else
list_aliases(type, name);
}
}
else
list_aliases(type, (char *) 0);
}
u_char *
function_left(input)
u_char *input;
{
u_char *result = (u_char *) 0;
char *count;
int cvalue;
count = next_arg((char *) input, (char **) &input);
if (count)
cvalue = atoi(count);
else
cvalue = 0;
if ((int) strlen((char *) input) > cvalue)
input[cvalue] = '\0';
malloc_strcpy((char **) &result, (char *) input);
return (result);
}
u_char *
function_right(input)
u_char *input;
{
u_char *result = (u_char *) 0;
char *count;
int cvalue;
int len;
count = next_arg((char *) input, (char **) &input);
if (count)
cvalue = atoi(count);
else
cvalue = 0;
if ((len = (int) strlen((char *) input)) > cvalue)
input += len - cvalue;
malloc_strcpy((char **) &result, (char *) input);
return (result);
}
u_char *
function_mid(input)
u_char *input;
{
u_char *result = (u_char *) 0;
char *mid_index;
int ivalue;
char *count;
int cvalue;
mid_index = next_arg((char *) input, (char **) &input);
if (mid_index)
ivalue = atoi(mid_index);
else
ivalue = 0;
count = next_arg((char *) input, (char **) &input);
if (count)
cvalue = atoi(count);
else
cvalue = 0;
if (ivalue >= 0 && (int) strlen(CP(input)) > ivalue)
input += ivalue;
else
*input = '\0';
if (cvalue > 0 && (int) strlen(CP(input)) > cvalue)
input[cvalue] = '\0';
malloc_strcpy((char **) &result, (char *) input);
return (result);
}
/* patch from Sarayan to make $rand() better */
/**************************** PATCHED by Flier ******************************/
/*#define RAND_A 16807L
#define RAND_M 2147483647L
#define RAND_Q 127773L
#define RAND_R 2836L
static long
randm(l)
long l;
{
static u_long z = 0;
long t;
#ifndef __MSDOS__
if (!z)
z = (u_long) getuid();
#endif*/ /* __MSDOS__ */
/* if (!l)
{
t = RAND_A * (z % RAND_Q) - RAND_R * (z / RAND_Q);
if (t > 0)
z = t;
else
z = t + RAND_M;
return (z >> 8) | ((z & 255) << 23);
}
else
{
if (l < 0)
#ifdef __MSDOS__
z = 0;
#else
z = (u_long) getuid();
#endif*/ /* __MSDOS__ */
/* else
z = l;
return 0;
}
}*/
/****************************************************************************/
u_char *
function_rand(input)
u_char *input;
{
u_char *result = (u_char *) 0;
char tmp[40];
/**************************** PATCHED by Flier ******************************/
/*long tempin;*/
int value = 0;
/****************************************************************************/
#ifdef _Windows
snprintf(tmp, sizeof tmp, "%ld", random(atol(CP(input))));
#else
/**************************** PATCHED by Flier ******************************/
/*snprintf(CP(tmp), sizeof tmp, "%ld", (tempin = my_atol(input)) ? randm(0L) % tempin : 0);*/
if (input && * input) value = atoi(input);
if (!value) value = 1;
snprintf(tmp, sizeof(tmp), "%d", (input && *input) ? rand() % value : rand());
/****************************************************************************/
#endif /* _Windows */
malloc_strcpy((char **) &result, tmp);
return (result);
}
u_char *
function_srand(input)
u_char *input;
{
u_char *result = (u_char *) 0;
/**************************** PATCHED by Flier ******************************/
/*if (input && *input)
(void) randm(atol((char *) input));
else
(void) randm((long) time(NULL));*/
if (input && *input) srand(atol((char *) input));
else srand(time((time_t *) 0));
/****************************************************************************/
malloc_strcpy((char **) &result, empty_string);
return (result);
}
/*ARGSUSED*/
u_char *
function_time(input)
u_char *input;
{
u_char *result = (u_char *) 0;
time_t ltime;
char tmp[40];
(void) time(<ime);
snprintf(tmp, sizeof tmp, "%ld", (long)ltime);
malloc_strcpy((char **) &result, tmp);
return (result);
}
#ifndef LITE
u_char *
function_stime(input)
u_char *input;
{
u_char *result = (u_char *) 0;
time_t ltime;
ltime = atol((char *) input);
malloc_strcpy((char **) &result, ctime(<ime));
result[strlen((char *) result) - 1] = (u_char) 0;
return (result);
}
u_char *
function_tdiff(input)
u_char *input;
{
u_char *result = (u_char *) 0;
time_t ltime;
time_t days,
hours,
minutes,
seconds;
char tmp[80];
char *tstr;
ltime = atol((char *) input);
seconds = ltime % 60;
ltime = (ltime - seconds) / 60;
minutes = ltime%60;
ltime = (ltime - minutes) / 60;
hours = ltime % 24;
days = (ltime - hours) / 24;
tstr = tmp;
if (days)
{
snprintf(tstr, sizeof(tmp) - (tstr - tmp), "%ld day%s ", (long) days, (days==1)?"":"s");
tstr += strlen(tstr);
}
if (hours)
{
snprintf(tstr, sizeof(tmp) - (tstr - tmp), "%ld hour%s ", (long) hours, (hours==1)?"":"s");
tstr += strlen(tstr);
}
if (minutes)
{
snprintf(tstr, sizeof(tmp) - (tstr - tmp), "%ld minute%s ", (long) minutes, (minutes==1)?"":"s");
tstr += strlen(tstr);
}
if (seconds || (!days && !hours && !minutes))
{
snprintf(tstr, sizeof(tmp) - (tstr - tmp), "%ld second%s", (long) seconds, (seconds==1)?"":"s");
tstr += strlen(tstr);
}
malloc_strcpy((char **) &result, tmp);
return (result);
}
#endif
u_char *
function_index(input)
u_char *input;
{
u_char *result = (u_char *) 0;
char *schars;
char *iloc;
int ival;
char tmp[40];
schars = next_arg((char *) input, (char **) &input);
iloc = (schars) ? sindex((char *) input, schars) : NULL;
ival = (iloc) ? iloc - (char *) input : -1;
snprintf(tmp, sizeof tmp, "%d", ival);
malloc_strcpy((char **) &result, tmp);
return (result);
}
u_char *
function_rindex(input)
u_char *input;
{
u_char *result = (u_char *) 0;
char *schars;
char *iloc;
int ival;
char tmp[40];
schars = next_arg((char *) input, (char **) &input);
iloc = (schars) ? srindex((char *) input, schars) : NULL;
ival = (iloc) ? iloc - (char *) input : -1;
snprintf(tmp, sizeof tmp, "%d", ival);
malloc_strcpy((char **) &result, tmp);
return (result);
}
u_char *
function_match(input)
u_char *input;
{
u_char *result = (u_char *) 0;
char *pattern;
char *word;
int current_match;
int best_match = 0;
int match = 0;
int match_index = 0;
char tmp[40];
if ((pattern = next_arg((char *) input, (char **) &input)) != NULL)
{
while ((word = next_arg((char *) input, (char **) &input)) != NULL)
{
match_index++;
if ((current_match = wild_match(pattern, word))
> best_match)
{
match = match_index;
best_match = current_match;
}
}
}
snprintf(tmp, sizeof tmp, "%d", match);
malloc_strcpy((char **) &result, tmp);
return (result);
}
#ifndef LITE
u_char *
function_rmatch(input)
u_char *input;
{
u_char *result = (u_char *) 0;
char *pattern;
char *word;
int current_match;
int best_match = 0;
int match = 0;
int rmatch_index = 0;
char tmp[40];
if ((pattern = next_arg((char *) input, (char **) &input)) != NULL)
{
while ((word = next_arg((char *) input, (char **) &input)) != NULL)
{
rmatch_index++;
if ((current_match = wild_match(word, pattern)) >
best_match)
{
match = rmatch_index;
best_match = current_match;
}
}
}
snprintf(tmp, sizeof tmp, "%d", match);
malloc_strcpy((char **) &result, tmp);
return (result);
}
#endif
/*ARGSUSED*/
u_char *
function_userhost(input)
u_char *input;
{
u_char *result = (u_char *) 0;
malloc_strcpy((char **) &result, FromUserHost ? FromUserHost : empty_string);
return (result);
}
u_char *
function_strip(input)
u_char *input;
{
char tmpbuf[128], *result;
u_char *retval = (u_char *) 0;
char *chars;
char *cp, *dp;
size_t len = 0;
if ((chars = next_arg((char *) input, (char **) &input)) && input)
{
len = strlen((char *) input);
if (len > 127)
result = (char *) new_malloc(len + 1);
else
result = tmpbuf;
for (cp = (char *) input, dp = result; *cp; cp++)
{
if (!index(chars, *cp))
*dp++ = *cp;
}
*dp = '\0';
}
malloc_strcpy((char **) &retval, result);
if (len > 127)
new_free(&result); /* we could use this copy, but it might be extra-long */
return (retval);
}
u_char *
function_encode(input)
u_char *input;
{
u_char *result;
u_char *c;
int i = 0;
result = (u_char *) new_malloc(strlen((char *) input) * 2 + 1);
for (c = input; *c; c++)
{
result[i++] = (*c >> 4) + 0x41;
result[i++] = (*c & 0x0f) + 0x41;
}
result[i] = '\0';
return (result);
}
u_char *
function_decode(input)
u_char *input;
{
u_char *result;
u_char *c;
u_char d, e;
int i = 0;
c = input;
result = (u_char *) new_malloc(strlen((char *) input) / 2 + 2);
while((d = *c) && (e = *(c+1)))
{
result[i] = ((d - 0x41) << 4) | (e - 0x41);
c += 2;
i++;
}
result[i] = '\0';
return (result);
}
u_char *
function_ischannel(input)
u_char *input;
{
u_char *result = (u_char *) 0;
malloc_strcpy((char **) &result, is_channel((char *) input) ? one : irczero);
return (result);
}
u_char *
function_ischanop(input)
u_char *input;
{
u_char *result = (u_char *) 0;
char *nick;
char *channel = NULL;
if (!(nick = next_arg((char *) input, &channel)))
malloc_strcpy((char **) &result, irczero);
else
malloc_strcpy((char **) &result, is_chanop(channel, nick) ? one : irczero);
return (result);
}
#ifndef LITE
#ifdef HAVE_CRYPT
u_char *
function_crypt(input)
u_char *input;
{
u_char *result = (char *)0;
char *salt;
char *key = NULL;
if (!(salt = next_arg((char *) input, &key)))
malloc_strcpy((char **) &result, irczero);
else
malloc_strcpy((char **) &result, (char *) crypt(key, salt));
return (result);
}
#endif /* HAVE_CRYPT */
u_char *
function_hasvoice(input)
u_char *input;
{
u_char *result = (u_char *)0;
char *nick;
char *channel = NULL;
if (!(nick = next_arg((char *) input, &channel)))
malloc_strcpy((char **) &result, irczero);
else
malloc_strcpy((char **) &result, has_voice(channel, nick, from_server) ? one : irczero);
return (result);
}
u_char *
function_dcclist(Nick)
u_char *Nick;
{
u_char *result;
DCC_list *Client;
size_t len = 0;
int i;
if (!Nick)
{
malloc_strcpy((char **)&result, irczero);
return (result);
}
for (i = 0, Client = ClientList; Client != NULL; Client = Client->next)
if (!my_stricmp((char *) Nick, Client->user))
len += 3;
result = (u_char *) new_malloc(len + 1);
for (i = 0, Client = ClientList; Client != NULL; Client = Client->next)
if (!my_stricmp((char *) Nick, Client->user))
{
int b = Client->flags;
int a = (b & DCC_TYPES);
result[i++] =
(a == DCC_CHAT) ? 'C' /* CHAT */
: (a == DCC_FILEOFFER) ? 'S' /* SEND */
: (a == DCC_FILEREAD) ? 'G' /* GET */
/**************************** PATCHED by Flier ******************************/
/*: (a == DCC_TALK) ? 'T' *//* TALK */
/*: (a == DCC_SUMMON) ? 'U' *//* SUMMON */
/****************************************************************************/
: (a == DCC_RAW_LISTEN) ? 'L' /* RAW_LISTEN */
: (a == DCC_RAW) ? 'R' /* RAW */
: 'x';
result[i++] =
(b & DCC_OFFER) ? 'O' /* OFFERED */
: (b & DCC_DELETE) ? 'C' /* CLOSED */
: (b & DCC_ACTIVE) ? 'A' /* ACTIVE */
: (b & DCC_WAIT) ? 'W' /* WAITING */
: 'x';
result[i++] = ' ';
}
result[i] = '\0';
return (result);
}
u_char *
function_chatpeers(dummy)
u_char *dummy;
{
u_char *result;
DCC_list *Client;
int notfirst = 0;
size_t len = 0;
/* calculate size */
for (Client = ClientList; Client != NULL; Client = Client->next)
if ((Client->flags & (DCC_CHAT|DCC_ACTIVE)) == (DCC_CHAT|DCC_ACTIVE))
len += (strlen(Client->user) + 1);
result = (u_char *) new_malloc(len);
*result = '\0';
for (Client = ClientList; Client != NULL; Client = Client->next)
if ((Client->flags & (DCC_CHAT|DCC_ACTIVE)) == (DCC_CHAT|DCC_ACTIVE))
{
if (notfirst)
strcat((char *) result, ",");
else
notfirst = 1;
strcat((char *) result, Client->user);
}
return (result);
}
#endif /* LITE */
u_char *
function_word(input)
u_char *input;
{
u_char *result = (u_char *) 0;
char *count;
int cvalue;
char *word;
count = next_arg((char *) input, (char **) &input);
if (count)
cvalue = atoi(count);
else
cvalue = 0;
if (cvalue < 0)
malloc_strcpy((char **) &result, empty_string);
else
{
for (word = next_arg((char *) input, (char **) &input); word && cvalue--;
word = next_arg((char *) input, (char **) &input))
;
malloc_strcpy((char **) &result, (word) ? word : empty_string);
}
return (result);
}
u_char *
function_querynick(input)
u_char *input;
{
u_char *result = (u_char *) 0;
Window *win;
if (input && isdigit(*input))
win = get_window_by_refnum((u_int)atoi((char *) input));
else
win = curr_scr_win;
malloc_strcpy((char **) &result, win ? win->query_nick : "-1");
return (result);
}
#ifndef LITE
u_char *
function_windows(input)
u_char *input;
{
u_char *result = (u_char *) 0;
Win_Trav stuff;
Window *tmp;
malloc_strcat((char **) &result, empty_string);
stuff.flag = 1;
while ((tmp = window_traverse(&stuff)))
{
if (tmp->name)
{
malloc_strcat((char **) &result, tmp->name);
malloc_strcat((char **) &result, " ");
}
else
{
char buf[32];
snprintf(buf, sizeof buf, "%u ", tmp->refnum);
malloc_strcat((char **) &result, buf);
}
}
return (result);
}
u_char *
function_screens(input)
u_char *input;
{
Screen *list;
u_char *result = (u_char *) 0;
char buf[32];
malloc_strcat((char **) &result, empty_string);
for (list = screen_list; list; list = list->next)
{
if (list->alive)
{
snprintf(buf, sizeof buf, "%u ", list->screennum);
malloc_strcat((char **) &result, buf);
}
}
return (result);
}
u_char *
function_notify(input)
u_char *input;
{
u_char *result;
if (input && my_stricmp(input, "gone") == 0)
result = get_notify_list(NOTIFY_LIST_GONE);
else if (input && my_stricmp(input, "all") == 0)
result = get_notify_list(NOTIFY_LIST_ALL);
else
result = get_notify_list(NOTIFY_LIST_HERE);
return result;
}
/*
* $ignored(nick!user@host type) with type from:
* ALL MSGS PUBLIC WALLS WALLOPS INVITES NOTICES NOTES CTCP CRAP
*/
u_char *
function_ignored(input)
u_char *input;
{
u_char *result = (u_char *) 0, *userhost, *nick;
int type;
if ((nick = next_arg((char *) input, (char **) &input)) != NULL)
{
type = get_ignore_type(input);
if (type == 0 || type == -1 || type == IGNORE_ALL)
goto do_zero;
if ((userhost = index(nick, '!')))
*userhost++ = 0;
switch (double_ignore(nick, userhost, type))
{
case DONT_IGNORE:
malloc_strcpy((char **) &result, "dont");
break;
case HIGHLIGHTED:
malloc_strcpy((char **) &result, "highlighted");
break;
case IGNORED:
malloc_strcpy((char **) &result, "ignored");
break;
default:
goto do_zero;
}
}
else
do_zero:
malloc_strcpy((char **) &result, irczero);
return (result);
}
u_char *
function_winserver(input)
u_char *input;
{
u_char *result = (u_char *) 0;
char tmp[10];
Window *win;
if (input && isdigit(*input))
win = get_window_by_refnum((u_int)atoi((char *) input));
else
win = curr_scr_win;
snprintf(tmp, sizeof tmp, "%d", win ? win->server : -1);
malloc_strcpy((char **) &result, tmp);
return (result);
}
#endif
u_char *
function_winservergroup(input)
u_char *input;
{
u_char *result = (u_char *) 0;
char tmp[10];
Window *win;
if (input && isdigit(*input))
win = get_window_by_refnum((u_int)atoi((char *) input));
else
win = curr_scr_win;
snprintf(tmp, sizeof tmp, "%d", win ? win->server_group : -1);
malloc_strcpy((char **) &result, tmp);
return (result);
}
#ifndef LITE
u_char *
function_winvisible(input)
u_char *input;
{
u_char *result = (u_char *) 0;
char tmp[10];
Window *win;
if (input && isdigit(*input))
win = get_window_by_refnum((u_int)atoi((char *) input));
else
win = curr_scr_win;
snprintf(tmp, sizeof tmp, "%d", win ? win->visible : -1);
malloc_strcpy((char **) &result, tmp);
return (result);
}
u_char *
function_winnum(input)
u_char *input;
{
u_char *result = (u_char *) 0;
char tmp[10];
snprintf(tmp, sizeof tmp, "%d", curr_scr_win ? (int)curr_scr_win->refnum : -1);
malloc_strcpy((char **) &result, tmp);
return (result);
}
u_char *
function_winnam(input)
u_char *input;
{
u_char *result = (u_char *) 0;
Window *win;
if (input && isdigit(*input))
win = get_window_by_refnum((u_int)atoi((char *) input));
else
win = curr_scr_win;
malloc_strcpy((char **) &result, (win && win->name) ? win->name : empty_string);
return (result);
}
/*
* returns the current window's display (len) size counting for double
* status bars, etc.. -Toasty
*/
u_char *
function_winrows(input)
u_char *input;
{
u_char *result = (u_char *) 0;
if (curr_scr_win)
{
char tmp[10];
snprintf(tmp, sizeof tmp, "%d", curr_scr_win->display_size);
malloc_strcpy((char **) &result, tmp);
}
else
malloc_strcpy((char **) &result, "-1");
return (result);
}
/*
* returns the current screen's (since all windows have the same
* column/width) column value -Toasty
*/
u_char *
function_wincols(input)
u_char *input;
{
u_char *result = (u_char *) 0;
if (curr_scr_win)
{
char tmp[10];
snprintf(tmp, sizeof tmp, "%d", current_screen->co);
malloc_strcpy((char **) &result, tmp);
}
else
malloc_strcpy((char **) &result, "-1");
return (result);
}
u_char *
function_connect(input)
u_char *input;
{
u_char *result = (u_char *) 0;
char *host;
#ifdef DAEMON_UID
if (getuid() == DAEMON_UID)
put_it("You are not permitted to use CONNECT()");
else
#endif
if ((host = next_arg((char *) input, (char **) &input)) != NULL)
result = (u_char *) dcc_raw_connect(host, (u_int) atoi((char *) input));
return (result);
}
u_char *
function_listen(input)
u_char *input;
{
u_char *result = (u_char *) 0;
#ifdef DAEMON_UID
if (getuid() == DAEMON_UID)
malloc_strcpy((char **) &result, irczero);
else
#endif
result = (u_char *) dcc_raw_listen((u_int) atoi((char *) input));
return (result);
}
#endif /* LITE */
u_char *
function_toupper(input)
u_char *input;
{
u_char *new = (u_char *) 0,
*ptr;
if (!input)
return (u_char *) empty_string;
malloc_strcpy((char **) &new, (char *) input);
for (ptr = new; *ptr; ptr++)
*ptr = islower(*ptr) ? toupper(*ptr) : *ptr;
return new;
}
u_char *
function_tolower(input)
u_char *input;
{
u_char *new = (u_char *) 0,
*ptr;
if (!input)
return (u_char *) empty_string;
malloc_strcpy((char **) &new, (char *) input);
for (ptr = new; *ptr; ptr++)
*ptr = (isupper(*ptr)) ? tolower(*ptr) : *ptr;
return new;
}
u_char *
function_channels(input)
u_char *input;
{
Window *window;
if (input)
window = isdigit(*input) ? get_window_by_refnum((u_int) atoi((char *) input))
: curr_scr_win;
else
window = curr_scr_win;
return (u_char *) create_channel_list(window);
}
/* function_curpos moved to input.c */
#ifndef LITE
u_char *
function_servers(input)
u_char *input;
{
return (u_char *) create_server_list();
}
u_char *
function_servertype(input)
u_char *input;
{
int server;
char *s;
u_char *result = NULL;
if (from_server < 0)
server = primary_server;
else
server = from_server;
if (server < 0)
s = empty_string;
else
switch (server_list[server].version) {
case Server2_5:
s = "IRC2.5";
break;
case Server2_6:
s = "IRC2.6";
break;
case Server2_7:
s = "IRC2.7";
break;
case Server2_8:
s = "IRC2.8";
break;
case Server2_9:
s = "IRC2.9";
break;
case Server2_10:
s = "IRC2.10";
break;
case Server2_11:
s = "IRC2.11";
break;
/**************************** PATCHED by Flier ******************************/
case Server2_90:
s = "IRC2.90";
break;
/****************************************************************************/
default:
s = "IRC unknown";
break;
}
malloc_strcpy((char **) &result, s);
return (result);
}
#endif /* LITE */
u_char *
function_onchannel(input)
u_char *input;
{
u_char *result = (u_char *) 0;
char *nick;
char *channel = NULL;
if (from_server < 0 || !(nick = next_arg((char *) input, &channel)))
malloc_strcpy((char **) &result, irczero);
else
malloc_strcpy((char **) &result,
is_on_channel(channel, from_server, nick) ? one : irczero);
return (result);
}
#ifndef LITE
u_char *
function_pid(input)
u_char *input;
{
u_char *result = (u_char *) 0;
u_char lbuf[32]; /* plenty big enough for %d */
snprintf(CP(lbuf), sizeof lbuf, "%d", (int) getpid());
malloc_strcpy((char **) &result, lbuf);
return (result);
}
u_char *
function_ppid(input)
u_char *input;
{
u_char *result = (u_char *) 0;
u_char lbuf[32]; /* plenty big enough for %d */
snprintf(CP(lbuf), sizeof lbuf, "%d", (int) getppid());
malloc_strcpy((char **) &result, lbuf);
return (result);
}
#endif /* LITE */
/**************************** PATCHED by Flier ******************************/
/* Modified so if you call it $chanusers(#blah 1) it will return
@nick if nick is channel operator
+nick if nick is voiced
%nick if nick is halfopped
.nick otherwise */
#ifndef CELESCRP
/****************************************************************************/
u_char *
function_chanusers(input)
u_char *input;
{
ChannelList *chan;
NickList *nicks;
u_char *result = (u_char *) 0;
int len = 0;
int notfirst = 0;
/**************************** PATCHED by Flier ******************************/
int nickst=0;
char *channel;
/****************************************************************************/
/**************************** PATCHED by Flier ******************************/
/*chan = lookup_channel((char *) input, from_server, CHAN_NOUNLINK);*/
channel=new_next_arg((char *) input,(char **) &input);
if (!channel) {
channel=get_channel_by_refnum(0);
if (!channel) return (u_char *) 0;
}
chan=lookup_channel(channel,from_server,CHAN_NOUNLINK);
if (input && *input=='1') nickst=1;
/****************************************************************************/
if ((ChannelList *) 0 == chan)
return (u_char *) 0;
for (nicks = chan->nicks; nicks; nicks = nicks->next)
/**************************** PATCHED by Flier ******************************/
{
/****************************************************************************/
len += (strlen(nicks->nick) + 1);
/**************************** PATCHED by Flier ******************************/
if (nickst) len++;
}
/****************************************************************************/
result = (u_char *) new_malloc(len + 1);
*result = '\0';
for (nicks = chan->nicks; nicks; nicks = nicks->next)
{
if (notfirst)
strcat((char *)result, " ");
else
notfirst = 1;
/**************************** PATCHED by Flier ******************************/
if (nickst) {
if (nicks->chanop) strcat((char *) result,"@");
else if (nicks->halfop) strcat((char *) result,"%");
else if (nicks->hasvoice) strcat((char *) result,"+");
else strcat((char *) result,".");
}
/****************************************************************************/
strcat((char *)result, nicks->nick);
}
return (result);
}
/**************************** PATCHED by Flier ******************************/
#endif /* CELESCRP */
/****************************************************************************/
/*
* strftime() patch from hari (markc@arbld.unimelb.edu.au)
*/
#ifdef HAVE_STRFTIME
u_char *
function_strftime(input)
u_char *input;
{
char result[128];
time_t ltime;
char *fmt = (char *) 0;
ltime = atol((char *) input);
fmt = (char *) input;
/* skip the time field */
while (isdigit(*fmt))
++fmt;
if (*fmt && *++fmt)
{
struct tm *tm;
tm = localtime(<ime);
if (strftime(result, 128, fmt, tm))
{
u_char *s = (u_char *) 0;
malloc_strcpy((char **) &s, result);
return s;
}
else
return (u_char *) 0;
}
else
{
return (u_char *) 0;
}
}
#endif
/*
* idle() patch from scottr (scott.reynolds@plexus.com)
*/
u_char *
function_idle(input)
u_char *input;
{
u_char *result = (u_char *) 0;
char lbuf[20];
snprintf(lbuf, sizeof lbuf, "%ld", (long)(time(0) - idle_time));
malloc_strcpy((char **) &result, lbuf);
return (result);
}
#ifndef LITE
u_char *
function_urlencode(input)
u_char *input;
{
u_char *result;
u_char *c;
int i = 0;
for (c = input; *c; c++)
if(*c == '+' || *c == '%' || *c == '&')
i += 3;
else
++i;
result = (u_char *) new_malloc(i + 1);
for (i = 0, c = input; *c; c++)
{
if (*c == ' ')
result[i++] = '+';
else if (*c == '+')
{
result[i++] = '%';
result[i++] = '2';
result[i++] = 'B';
}
else if (*c == '&')
{
result[i++] = '%';
result[i++] = '2';
result[i++] = '6';
}
else
result[i++] = *c;
}
result[i] = '\0';
return (result);
}
u_char *
function_shellfix(input)
u_char *input;
{
u_char *result;
u_char *c;
int i = 2;
for (c = input; *c; c++)
if (*c == '\'')
i += 4;
else
++i;
result = (u_char *) new_malloc(i + 1);
i = 0;
result[i++] = '\'';
for (c = input; *c; c++)
{
if (*c == '\'')
{
result[i++] = '\'';
result[i++] = '\\';
result[i++] = '\'';
result[i++] = '\'';
}
else
result[i++] = *c;
}
result[i++] = '\'';
result[i] = '\0';
return (result);
}
u_char *
function_filestat(input)
u_char *input;
{
struct stat statbuf;
u_char *result = (char *) 0;
char lbuf[40]; /* 40 should be enough */
if (stat(input, &statbuf) == -1)
malloc_strcpy((char **) &result, empty_string);
else
{
snprintf(lbuf, sizeof lbuf, "%lu,%d,%d,%o,%s",
(unsigned long)statbuf.st_size,
(int)statbuf.st_uid,
(int)statbuf.st_gid,
statbuf.st_mode,
input);
malloc_strcpy((char **) &result, lbuf);
}
return (result);
}
#endif
/**************************** Patched by Flier ******************************/
#ifndef LITE
u_char *function_open(words)
u_char *words;
{
u_char *result=(char *) 0;
char *filename=(char *) 0;
char locbuf[mybufsize/64];
filename=next_arg((char *) words,(char **) &words);
if (words && *words) {
*(words+1)='\0';
upper(words);
if (*words=='R') snprintf(locbuf,sizeof(locbuf),"%d",OpenFileRead(filename));
else if (*words=='W' || *words=='A')
snprintf(locbuf,sizeof(locbuf),"%d",OpenFileWrite(filename,words));
}
else strcpy(locbuf,"-1");
malloc_strcpy((char **) &result,locbuf);
return(result);
}
u_char *function_close(words)
u_char *words;
{
char *args=(char *) 0;
u_char *result=(char *) 0;
char locbuf[mybufsize/64];
if (words && *words) {
args=next_arg((char *) words,(char **) &words);
snprintf(locbuf,sizeof(locbuf),"%d",FileClose(atoi(args)));
}
else strcpy(locbuf,"-1");
malloc_strcpy((char **) &result,locbuf);
return(result);
}
u_char *function_read(words)
u_char *words;
{
char *args=(char *) 0;
u_char *result=(char *) 0;
if (words && *words) {
args=next_arg((char *) words,(char **) &words);
malloc_strcpy((char **) &result,FileRead(atoi(args)));
}
else malloc_strcpy((char **) &result,"-1");
return(result);
}
u_char *function_write(words)
u_char *words;
{
char *args=(char *) 0;
u_char *result=(char *) 0;
char locbuf[mybufsize/64];
if (words && *words) {
args=next_arg((char *) words,(char **) &words);
if (words && *words) snprintf(locbuf,sizeof(locbuf),"%d",FileWrite(atoi(args),words));
else strcpy(locbuf,"-1");
}
else strcpy(locbuf,"-1");
malloc_strcpy((char **) &result,locbuf);
return(result);
}
u_char *function_eof(words)
u_char *words;
{
char *args=(char *) 0;
u_char *result=(char *) 0;
char locbuf[mybufsize/64];
if (words && *words) {
args=next_arg((char *) words,(char **) &words);
snprintf(locbuf,sizeof(locbuf),"%d",FileEof(atoi(args)));
}
else strcpy(locbuf,"-1");
malloc_strcpy((char **) &result,locbuf);
return(result);
}
u_char *function_rename(words)
u_char *words;
{
char *oldname=(char *) 0;
char *newname=(char *) 0;
u_char *result=(char *) 0;
char locbuf[mybufsize/64];
if (words && *words) {
oldname=next_arg((char *) words,(char **) &words);
newname=next_arg((char *) words,(char **) &words);
if (newname && *newname) {
snprintf(locbuf,sizeof(locbuf),"%d",rename(oldname,newname));
malloc_strcpy((char **) &result,locbuf);
}
else malloc_strcpy((char **) &result,"-1");
}
else malloc_strcpy((char **) &result,"-1");
return(result);
}
#endif
u_char *function_intuhost(words)
u_char *words;
{
u_char *result=(char *) 0;
char *args=(char *) 0;
char locbuf[mybufsize/2];
NickList *joiner;
if (words && *words) {
args=next_arg((char *) words,(char **) &words);
joiner=CheckJoiners(args,0,from_server,NULL);
if (joiner && joiner->userhost) snprintf(locbuf,sizeof(locbuf),"%s!%s",joiner->nick,joiner->userhost);
else strcpy(locbuf,"-1");
malloc_strcpy((char **) &result,locbuf);
}
else malloc_strcpy((char **) &result,"-1");
return(result);
}
u_char *function_checkuser(words)
u_char *words;
{
u_char *result=(char *) 0;
char *args=(char *) 0;
char locbuf[2*mybufsize];
struct friends *tmpfriend;
if (words && *words) {
args=next_arg((char *) words,(char **) &words);
if (words && *words) {
if ((tmpfriend=CheckUsers(args,words))) {
*locbuf='\0';
BuildPrivs(tmpfriend,locbuf);
strmcat(locbuf," ",sizeof(locbuf));
strmcat(locbuf,tmpfriend->userhost,sizeof(locbuf));
strmcat(locbuf," ",sizeof(locbuf));
strmcat(locbuf,tmpfriend->channels,sizeof(locbuf));
malloc_strcpy((char **) &result,locbuf);
return(result);
}
}
}
malloc_strcpy((char **) &result,"-1");
return(result);
}
u_char *function_checkshit(words)
u_char *words;
{
u_char *result=(char *) 0;
char *args=(char *) 0;
char locbuf[2*mybufsize];
struct autobankicks *abk;
if (words && *words) {
args=next_arg((char *) words,(char **) &words);
if (words && *words) {
*locbuf='\0';
if ((abk=CheckABKs(args,words))!=NULL) {
if ((abk->shit)&1) strcat(locbuf,"K");
if ((abk->shit)&2) strcat(locbuf,"B");
if ((abk->shit)&4) strcat(locbuf,"I");
if ((abk->shit)&8) strcat(locbuf,"P");
if ((abk->shit)&16) strcat(locbuf,"D");
strmcat(locbuf," ",sizeof(locbuf));
strmcat(locbuf,abk->userhost,sizeof(locbuf));
strmcat(locbuf," ",sizeof(locbuf));
strmcat(locbuf,abk->channels,sizeof(locbuf));
strmcat(locbuf," ",sizeof(locbuf));
strmcat(locbuf,abk->reason,sizeof(locbuf));
}
else strcpy(locbuf,"-1");
malloc_strcpy((char **) &result,locbuf);
}
else malloc_strcpy((char **) &result,"-1");
}
else malloc_strcpy((char **) &result,"-1");
return(result);
}
u_char *function_stripansi(words)
u_char *words;
{
u_char *result=(char *) 0;
char locbuf[2*mybufsize];
if (words && *words) {
StripAnsi(words,locbuf,0);
malloc_strcpy((char **) &result,locbuf);
}
else malloc_strcpy((char **) &result,empty_string);
return(result);
}
/*u_char *function_pattern(words)
u_char *words;
{
char *tmpstr;
char *pattern;
u_char *result=(char *) 0;
*tmpbuf='\0';
if ((pattern=next_arg((char *) words,(char **) &words))) {
while (((tmpstr=next_arg((char *) words,(char **) &words))!=NULL)) {
if (wild_match(pattern,tmpstr)) {
strcat(tmpbuf,tmpstr);
strcat(tmpbuf," ");
}
}
tmpbuf[strlen(tmpbuf)-1]='\0';
malloc_strcpy((char **) &result,tmpbuf);
}
else malloc_strcpy((char **) &result,empty_string);
return(result);
}
u_char *function_chops(words)
u_char *words;
{
u_char *nicks=(char *) 0;
char *curr_chan;
int count=0;
NickList *tmp;
ChannelList *chan;
*tmpbuf2='\0';
if (words && *words) strmcpy(tmpbuf,next_arg((char *) words,(char **) &words),mybufsize/2);
else *tmpbuf='\0';
curr_chan=get_channel_by_refnum(0);
if (!curr_chan) curr_chan=empty_string;
if ((tmpbuf[0]==0) || (!strcmp(tmpbuf,"*"))) strmcpy(tmpbuf,curr_chan,mybufsize/2);
if (tmpbuf[0]==0 || tmpbuf[0]=='0') {
malloc_strcpy((char **) &nicks,tmpbuf2);
return(nicks);
}
chan=lookup_channel(tmpbuf,curr_scr_win->server,0);
if (!chan) {
malloc_strcpy((char **) &nicks,tmpbuf2);
return(nicks);
}
for (tmp=chan->nicks;tmp;tmp=tmp->next) {
if (tmp->chanop) {
count++;
strcat(tmpbuf2,tmp->nick);
strcat(tmpbuf2," ");
if (count>50) {
tmpbuf2[strlen(tmpbuf2)-1]='\0';
malloc_strcat((char **) &nicks,tmpbuf2);
*tmpbuf2='\0';
count=0;
}
}
}
if (count) {
tmpbuf2[strlen(tmpbuf2)-1]='\0';
malloc_strcat((char **) &nicks,tmpbuf2);
}
return(nicks);
}
u_char *function_chnops(words)
u_char *words;
{
u_char *nicks=(char *) 0;
char *curr_chan;
int count=0;
NickList *tmp;
ChannelList *chan;
*tmpbuf2='\0';
if (words && *words) strmcpy(tmpbuf,next_arg((char *) words,(char **) &words),mybufsize/2);
else *tmpbuf='\0';
curr_chan=get_channel_by_refnum(0);
if (!curr_chan) curr_chan=empty_string;
if ((tmpbuf[0]==0) || (!strcmp(tmpbuf,"*"))) strmcpy(tmpbuf,curr_chan,mybufsize/2);
if (tmpbuf[0]==0 || tmpbuf[0]=='0') {
malloc_strcpy((char **) &nicks,tmpbuf2);
return(nicks);
}
chan=lookup_channel(tmpbuf,curr_scr_win->server,0);
if (!chan) {
malloc_strcpy((char **) &nicks,tmpbuf2);
return(nicks);
}
for (tmp=chan->nicks;tmp;tmp=tmp->next) {
if (!(tmp->chanop)) {
count++;
strcat(tmpbuf2,tmp->nick);
strcat(tmpbuf2," ");
if (count>50) {
tmpbuf2[strlen(tmpbuf2)-1]='\0';
malloc_strcat((char **) &nicks,tmpbuf2);
*tmpbuf2='\0';
count=0;
}
}
}
if (count) {
tmpbuf2[strlen(tmpbuf2)-1]='\0';
malloc_strcat((char **) &nicks,tmpbuf2);
}
return(nicks);
}*/
#ifndef LITE
u_char *function_color(words)
u_char *words;
{
u_char *result=(char *) 0;
#ifdef WANTANSI
int colnum=0;
int eventnum=0;
char *tmp=(char *) 0;
char *tmpstr=(char *) 0;
char locbuf[2*mybufsize];
if (words && *words) {
tmp=next_arg((char *) words,(char **) &words);
if (tmp && words && *words) {
eventnum=atoi(tmp);
colnum=atoi(words);
}
if (eventnum>=1 && eventnum<=NUMCMDCOLORS && colnum>=1 && colnum<=6) {
eventnum--;
malloc_strcpy((char **) &result,Colors[COLOFF]);
switch (colnum) {
case 1 : malloc_strcat((char **) &result,CmdsColors[eventnum].color1);
break;
case 2 : malloc_strcat((char **) &result,CmdsColors[eventnum].color2);
break;
case 3 : malloc_strcat((char **) &result,CmdsColors[eventnum].color3);
break;
case 4 : malloc_strcat((char **) &result,CmdsColors[eventnum].color4);
break;
case 5 : malloc_strcat((char **) &result,CmdsColors[eventnum].color5);
break;
case 6 : malloc_strcat((char **) &result,CmdsColors[eventnum].color6);
break;
}
}
else {
malloc_strcpy((char **) &result,Colors[COLOFF]);
strmcpy(locbuf,tmp,sizeof(locbuf));
tmp=locbuf;
for (;*tmp;tmp++)
if (*tmp==',') {
*tmp++='\0';
if (!tmpstr) tmpstr=locbuf;
if ((colnum=ColorNumber(tmpstr))!=-1)
malloc_strcat((char **) &result,Colors[colnum]);
tmpstr=tmp;
}
if (!tmpstr) tmpstr=locbuf;
if (tmpstr)
if ((colnum=ColorNumber(tmpstr))!=-1)
malloc_strcat((char **) &result,Colors[colnum]);
}
}
else malloc_strcpy((char **) &result,empty_string);
return(result);
#else
malloc_strcpy((char **) &result,empty_string);
return(result);
#endif
}
#endif /* LITE */
#if !defined(CELESCRP) && !defined(LITE)
u_char *function_uhost(input)
u_char *input;
{
char *tmp;
u_char *result=(char *) 0;
if ((tmp=index(input,'!'))) malloc_strcpy((char **) &result,tmp+1);
else malloc_strcpy((char **) &result,empty_string);
return(result);
}
u_char *function_hhost(input)
u_char *input;
{
char *tmp;
u_char *result=(char *) 0;
if ((tmp=index(input,'@'))) malloc_strcpy((char **) &result,tmp+1);
else malloc_strcpy((char **) &result,empty_string);
return(result);
}
u_char *function_topic(input)
u_char *input;
{
u_char *result=(char *) 0;
char *channel;
char locbuf[2*mybufsize];
ChannelList *chan;
if ((channel=next_arg((char *) input,(char **) &channel)) &&
(chan=lookup_channel(channel,from_server,0)) && chan->topicstr) {
if (chan->topicwho) snprintf(locbuf,sizeof(locbuf),"%s %ld ",chan->topicwho,chan->topicwhen);
else strcpy(locbuf,"unknown 0 ");
strmcat(locbuf,chan->topicstr,sizeof(locbuf));
malloc_strcpy((char **) &result,locbuf);
}
else malloc_strcpy((char **) &result,empty_string);
return(result);
}
u_char *function_strlen(input)
u_char *input;
{
u_char *result=(char *) 0;
char locbuf[2*mybufsize];
if (input && *input) {
snprintf(locbuf,sizeof(locbuf),"%d",strlen(input));
malloc_strcpy((char **) &result,locbuf);
}
else malloc_strcpy((char **) &result,"0");
return(result);
}
u_char *function_strnum(input)
u_char *input;
{
int count=0;
char *tmp=input;
u_char *result=(char *) 0;
char locbuf[2*mybufsize];
if (tmp && *tmp) {
while (*tmp) {
while (*tmp && isspace(*tmp)) tmp++;
if (*tmp) {
count++;
while (*tmp && !isspace(*tmp)) tmp++;
}
if (*tmp) tmp++;
}
snprintf(locbuf,sizeof(locbuf),"%d",count);
malloc_strcpy((char **) &result,locbuf);
}
else malloc_strcpy((char **) &result,"0");
return(result);
}
#endif /* !CELESCRP && !LITE */
#ifndef LITE
u_char *function_fsize(input)
u_char *input;
{
int fexists;
char *filename=(char *) 0;
u_char *result=(char *) 0;
char locbuf[mybufsize/64];
struct stat statbuf;
if (input && *input) {
if (!(filename=expand_twiddle(input))) malloc_strcpy(&filename,input);
fexists=stat(filename,&statbuf);
new_free(&filename);
if (fexists==-1) malloc_strcpy((char **) &result,"-1");
else {
snprintf(locbuf,sizeof(locbuf),"%ld",statbuf.st_size);
malloc_strcpy((char **) &result,locbuf);
}
}
else malloc_strcpy((char **) &result,"-1");
return(result);
}
/* Search and replace function --
Usage: $sar(command/search/replace/data)
Commands:
r - treat data as a variable name and
return the replaced data to the variable
g - Replace all instances, not just the first one
The delimiter may be any character that is not a command (typically /)
The delimiter MUST be the first character after the command
Returns empty string on error
*/
#ifndef CELESCRP
u_char *function_sar(word)
u_char *word;
{
int variable=0,global=0,searchlen;
unsigned int display=window_display;
char delimiter;
char *data=(char *) 0;
char *value=(char *) 0;
char *svalue;
char *search=(char *) 0;
u_char *result=(char *) 0;
char *replace=(char *) 0;
char *pointer=(char *) 0;
Alias *tmp;
while (((*word=='r') && (variable=1)) || ((*word=='g') && (global=1))) word++;
if (!(word && *word)) {
malloc_strcpy((char **) &result,empty_string);
return(result);
}
delimiter=*word;
search=word+1;
if (!(replace=strchr(search,delimiter))) {
malloc_strcpy((char **) &result,empty_string);
return(result);
}
*replace++='\0';
if (!(data=strchr(replace,delimiter))) {
malloc_strcpy((char **) &result,empty_string);
return(result);
}
*data++='\0';
if (variable) {
if ((tmp=find_alias(&(alias_list[VAR_ALIAS]),data,1,(int *) 0)))
malloc_strcpy(&value,tmp->stuff);
}
else malloc_strcpy(&value,data);
if (!value || !*value) {
if (value) new_free(&value);
malloc_strcpy((char **) &result,empty_string);
return(result);
}
svalue=value;
pointer=value;
searchlen=strlen(search)-1;
if (searchlen<0) searchlen=0;
if (global) {
while ((pointer=strstr(pointer,search))) {
pointer[0]=pointer[searchlen]=0;
pointer+=searchlen+1;
malloc_strcat((char **) &result,value);
malloc_strcat((char **) &result,replace);
value=pointer;
if (!*pointer) break;
}
}
else {
if ((pointer=strstr(pointer,search))) {
pointer[0]=pointer[searchlen]=0;
pointer+=searchlen+1;
malloc_strcat((char **) &result,value);
malloc_strcat((char **) &result,replace);
value=pointer;
}
}
malloc_strcat((char **) &result,value);
if (variable) {
window_display=0;
add_alias(VAR_ALIAS,data,result);
window_display=display;
}
new_free(&svalue);
return(result);
}
#endif /* CELESCRP */
#endif /* LITE */
#ifdef COUNTRY
u_char *function_country(input)
u_char *input;
{
int i;
u_char *result=(char *) 0;
char locbuf[mybufsize/64+1];
struct domain_str {
char *id;
char *description;
} domain[] = {
{ "AD", "Andorra" },
{ "AE", "United Arab Emirates" },
{ "AF", "Afghanistan" },
{ "AG", "Antigua and Barbuda" },
{ "AI", "Anguilla" },
{ "AL", "Albania" },
{ "AM", "Armenia" },
{ "AN", "Netherlands Antilles" },
{ "AO", "Angola" },
{ "AQ", "Antarctica" },
{ "AR", "Argentina" },
{ "AS", "American Samoa" },
{ "AT", "Austria" },
{ "AU", "Australia" },
{ "AW", "Aruba" },
{ "AZ", "Azerbaijan" },
{ "BA", "Bosnia and Herzegovina" },
{ "BB", "Barbados" },
{ "BD", "Bangladesh" },
{ "BE", "Belgium" },
{ "BF", "Burkina Faso" },
{ "BG", "Bulgaria" },
{ "BH", "Bahrain" },
{ "BI", "Burundi" },
{ "BJ", "Benin" },
{ "BM", "Bermuda" },
{ "BN", "Brunei Darussalam" },
{ "BO", "Bolivia" },
{ "BR", "Brazil" },
{ "BS", "Bahamas" },
{ "BT", "Bhutan" },
{ "BV", "Bouvet Island" },
{ "BW", "Botswana" },
{ "BY", "Belarus" },
{ "BZ", "Belize" },
{ "CA", "Canada" },
{ "CC", "Cocos Islands" },
{ "CF", "Central African Republic" },
{ "CG", "Congo" },
{ "CH", "Switzerland" },
{ "CI", "Cote D'ivoire" },
{ "CK", "Cook Islands" },
{ "CL", "Chile" },
{ "CM", "Cameroon" },
{ "CN", "China" },
{ "CO", "Colombia" },
{ "CR", "Costa Rica" },
{ "CS", "Former Czechoslovakia" },
{ "CU", "Cuba" },
{ "CV", "Cape Verde" },
{ "CX", "Christmas Island" },
{ "CY", "Cyprus" },
{ "CZ", "Czech Republic" },
{ "DE", "Germany" },
{ "DJ", "Djibouti" },
{ "DK", "Denmark" },
{ "DM", "Dominica" },
{ "DO", "Dominican Republic" },
{ "DZ", "Algeria" },
{ "EC", "Ecuador" },
{ "EE", "Estonia" },
{ "EG", "Egypt" },
{ "EH", "Western Sahara" },
{ "ER", "Eritrea" },
{ "ES", "Spain" },
{ "ET", "Ethiopia" },
{ "FI", "Finland" },
{ "FJ", "Fiji" },
{ "FK", "Falkland Islands" },
{ "FM", "Micronesia" },
{ "FO", "Faroe Islands" },
{ "FR", "France" },
{ "FX", "France, Metropolitan" },
{ "GA", "Gabon" },
{ "GB", "Great Britain" },
{ "GD", "Grenada" },
{ "GE", "Georgia" },
{ "GF", "French Guiana" },
{ "GH", "Ghana" },
{ "GI", "Gibraltar" },
{ "GL", "Greenland" },
{ "GM", "Gambia" },
{ "GN", "Guinea" },
{ "GP", "Guadeloupe" },
{ "GQ", "Equatorial Guinea" },
{ "GR", "Greece" },
{ "GS", "S. Georgia and S. Sandwich Isls." },
{ "GT", "Guatemala" },
{ "GU", "Guam" },
{ "GW", "Guinea-Bissau" },
{ "GY", "Guyana" },
{ "HK", "Hong Kong" },
{ "HM", "Heard and McDonald Islands" },
{ "HN", "Honduras" },
{ "HR", "Croatia" },
{ "HT", "Haiti" },
{ "HU", "Hungary" },
{ "ID", "Indonesia" },
{ "IE", "Ireland" },
{ "IL", "Israel" },
{ "IN", "India" },
{ "IO", "British Indian Ocean Territory" },
{ "IQ", "Iraq" },
{ "IR", "Iran" },
{ "IS", "Iceland" },
{ "IT", "Italy" },
{ "JM", "Jamaica" },
{ "JO", "Jordan" },
{ "JP", "Japan" },
{ "KE", "Kenya" },
{ "KG", "Kyrgyzstan" },
{ "KH", "Cambodia" },
{ "KI", "Kiribati" },
{ "KM", "Comoros" },
{ "KN", "St. Kitts and Nevis" },
{ "KP", "North Korea" },
{ "KR", "South Korea" },
{ "KW", "Kuwait" },
{ "KY", "Cayman Islands" },
{ "KZ", "Kazakhstan" },
{ "LA", "Laos" },
{ "LB", "Lebanon" },
{ "LC", "Saint Lucia" },
{ "LI", "Liechtenstein" },
{ "LK", "Sri Lanka" },
{ "LR", "Liberia" },
{ "LS", "Lesotho" },
{ "LT", "Lithuania" },
{ "LU", "Luxembourg" },
{ "LV", "Latvia" },
{ "LY", "Libya" },
{ "MA", "Morocco" },
{ "MC", "Monaco" },
{ "MD", "Moldova" },
{ "MG", "Madagascar" },
{ "MH", "Marshall Islands" },
{ "MK", "Macedonia" },
{ "ML", "Mali" },
{ "MM", "Myanmar" },
{ "MN", "Mongolia" },
{ "MO", "Macau" },
{ "MP", "Northern Mariana Islands" },
{ "MQ", "Martinique" },
{ "MR", "Mauritania" },
{ "MS", "Montserrat" },
{ "MT", "Malta" },
{ "MU", "Mauritius" },
{ "MV", "Maldives" },
{ "MW", "Malawi" },
{ "MX", "Mexico" },
{ "MY", "Malaysia" },
{ "MZ", "Mozambique" },
{ "NA", "Namibia" },
{ "NC", "New Caledonia" },
{ "NE", "Niger" },
{ "NF", "Norfolk Island" },
{ "NG", "Nigeria" },
{ "NI", "Nicaragua" },
{ "NL", "Netherlands" },
{ "NO", "Norway" },
{ "NP", "Nepal" },
{ "NR", "Nauru" },
{ "NT", "Neutral Zone" },
{ "NU", "Niue" },
{ "NZ", "New Zealand" },
{ "OM", "Oman" },
{ "PA", "Panama" },
{ "PE", "Peru" },
{ "PF", "French Polynesia" },
{ "PG", "Papua New Guinea" },
{ "PH", "Philippines" },
{ "PK", "Pakistan" },
{ "PL", "Poland" },
{ "PM", "St. Pierre and Miquelon" },
{ "PN", "Pitcairn" },
{ "PR", "Puerto Rico" },
{ "PT", "Portugal" },
{ "PW", "Palau" },
{ "PY", "Paraguay" },
{ "QA", "Qatar" },
{ "RE", "Reunion" },
{ "RO", "Romania" },
{ "RU", "Russian Federation" },
{ "RW", "Rwanda" },
{ "SA", "Saudi Arabia" },
{ "SB", "Solomon Islands" },
{ "SC", "Seychelles" },
{ "SD", "Sudan" },
{ "SE", "Sweden" },
{ "SG", "Singapore" },
{ "SH", "St. Helena" },
{ "SI", "Slovenia" },
{ "SJ", "Svalbard and Jan Mayen Islands" },
{ "SK", "Slovak Republic" },
{ "SL", "Sierra Leone" },
{ "SM", "San Marino" },
{ "SN", "Senegal" },
{ "SO", "Somalia" },
{ "SR", "Suriname" },
{ "ST", "Sao Tome and Principe" },
{ "SU", "Former USSR" },
{ "SV", "El Salvador" },
{ "SY", "Syria" },
{ "SZ", "Swaziland" },
{ "TC", "Turks and Caicos Islands" },
{ "TD", "Chad" },
{ "TF", "French Southern Territories" },
{ "TG", "Togo" },
{ "TH", "Thailand" },
{ "TJ", "Tajikistan" },
{ "TK", "Tokelau" },
{ "TM", "Turkmenistan" },
{ "TN", "Tunisia" },
{ "TO", "Tonga" },
{ "TP", "East Timor" },
{ "TR", "Turkey" },
{ "TT", "Trinidad and Tobago" },
{ "TV", "Tuvalu" },
{ "TW", "Taiwan" },
{ "TZ", "Tanzania" },
{ "UA", "Ukraine" },
{ "UG", "Uganda" },
{ "UK", "United Kingdom" },
{ "UM", "US Minor Outlying Islands" },
{ "US", "United States of America" },
{ "UY", "Uruguay" },
{ "UZ", "Uzbekistan" },
{ "VA", "Vatican City State" },
{ "VC", "St. Vincent and the grenadines" },
{ "VE", "Venezuela" },
{ "VG", "British Virgin Islands" },
{ "VI", "US Virgin Islands" },
{ "VN", "Vietnam" },
{ "VU", "Vanuatu" },
{ "WF", "Wallis and Futuna Islands" },
{ "WS", "Samoa" },
{ "YE", "Yemen" },
{ "YT", "Mayotte" },
{ "YU", "Yugoslavia" },
{ "ZA", "South Africa" },
{ "ZM", "Zambia" },
{ "ZR", "Zaire" },
{ "ZW", "Zimbabwe" },
{ "COM", "Commercial" },
{ "EDU", "Educational Institution" },
{ "GOV", "Government" },
{ "INT", "International" },
{ "MIL", "Military" },
{ "NET", "Network" },
{ "ORG", "Non-Profit Organization" },
{ "RPA", "Old School ARPAnet" },
{ "ATO", "Nato Fiel" },
{ "MED", "United States Medical" },
{ "ARPA", "Reverse DNS" },
{ NULL, NULL }
};
if (input && *input) {
strmcpy(locbuf,input,mybufsize/64);
upper(locbuf);
for (i=0;domain[i].id;i++)
if (!strcmp(domain[i].id,locbuf)) {
malloc_strcpy((char **) &result,domain[i].description);
return(result);
}
}
malloc_strcpy((char **) &result,"Unknown");
return(result);
}
#endif
#if !defined(CELESCRP) && !defined(LITE)
u_char *function_cdccslots(input)
u_char *input;
{
int slots=0;
u_char *result=(char *) 0;
char locbuf[mybufsize/64];
slots=CdccLimit-TotalSendDcc();
if (slots<0) slots=0;
snprintf(locbuf,sizeof(locbuf),"%d",slots);
malloc_strcpy((char **) &result,locbuf);
return(result);
}
u_char *function_cdccqslots(input)
u_char *input;
{
int slots=0;
u_char *result=(char *) 0;
char locbuf[mybufsize/64];
if (CdccQueueLimit) slots=CdccQueueLimit-TotalQueue();
else slots=10;
if (slots<0) slots=0;
snprintf(locbuf,sizeof(locbuf),"%d",slots);
malloc_strcpy((char **) &result,locbuf);
return(result);
}
u_char *function_url(input)
u_char *input;
{
int urlnum = 99;
int showtarget = 0;
u_char *result = NULL;
struct urlstr *tmpurl = urllist;
if (!tmpurl) malloc_strcpy((char **) &result, empty_string);
else {
if (input && *input) {
char *tmpstr = new_next_arg(input, (char **) &input);
urlnum = atoi(tmpstr);
if (input && *input) showtarget = 1;
}
while (tmpurl && urlnum--) tmpurl = tmpurl->next;
if (tmpurl) {
malloc_strcpy((char **) &result, tmpurl->urls);
if (showtarget && tmpurl->source) {
malloc_strcat((char **) &result, " ");
malloc_strcat((char **) &result, tmpurl->source);
}
}
else malloc_strcpy((char **) &result, empty_string);
}
return(result);
}
u_char *function_strstr(input)
u_char *input;
{
u_char *result=(char *) 0;
char *tmpstr=(char *) 0;
char *findstr=(char *) 0;
char locbuf[2*mybufsize+1];
if (input && *input) {
strmcpy(locbuf,&input[1],2*mybufsize);
if ((tmpstr=index(locbuf,*input))) {
*tmpstr++='\0';
if (*tmpstr) tmpstr++;
else tmpstr=(char *) 0;
}
if (tmpstr) findstr=strstr(locbuf,tmpstr);
}
if (!findstr) findstr=empty_string;
malloc_strcpy((char **) &result,findstr);
return(result);
}
u_char *function_szvar(input)
u_char *input;
{
int i;
u_char *result=(char *) 0;
char locbuf[mybufsize+1];
struct commands {
char *command;
int type; /* 1=numeric 2=string 3=on channels/off */
int *ivar;
char **svar;
} command_list[]= {
{ "EXTMES" , 1, &ExtMes , NULL },
{ "NHPROT" , 3, &NHProt , &NHProtChannels },
/* defban is character that should be returned as string */
{ "BANTYPE" , 2, NULL , NULL },
/* Cdcc limit should return CdccLimit and CdccQueueLimit */
{ "CDCCLIMIT" , 1, &CdccLimit , NULL },
{ "CDCCIDLE" , 1, &CdccIdle , NULL },
{ "CDCCAUTOGET" , 1, &AutoGet , NULL },
{ "CDCCSECURE" , 1, &Security , NULL },
{ "CDCCPTIME" , 1, &PlistTime , NULL },
{ "CDCCNTIME" , 1, &NlistTime , NULL },
{ "CDCCCHANNELS" , 2, NULL , &CdccChannels },
{ "CDCCLONGSTATUS" , 1, &LongStatus , NULL },
{ "CDCCOVERWRITE" , 1, &CdccOverWrite , NULL },
{ "CDCCSTATUS" , 1, &ShowDCCStatus , NULL },
{ "CDCCSTATS" , 1, &CdccStats , NULL },
{ "CDCCWARNING" , 1, &DCCWarning , NULL },
{ "CDCCULDIR" , 2, NULL , &CdccUlDir },
{ "CDCCDLDIR" , 2, NULL , &CdccDlDir },
{ "DEOPS" , 1, &DeopSensor , NULL },
{ "KICKS" , 1, &KickSensor , NULL },
{ "NICKS" , 1, &NickSensor , NULL },
{ "DEOPT" , 1, &MDopTimer , NULL },
{ "KICKT" , 1, &KickTimer , NULL },
{ "NICKT" , 1, &NickTimer , NULL },
{ "AWAYT" , 1, &AutoAwayTime , NULL },
{ "IGTIME" , 1, &IgnoreTime , NULL },
#ifdef EXTRAS
{ "IDLETIME" , 1, &IdleTime , NULL },
#endif
{ "NPROT" , 3, &NickWatch , &NickWatchChannels },
{ "DPROT" , 3, &MDopWatch , &MDopWatchChannels },
{ "KPROT" , 3, &KickWatch , &KickWatchChannels },
{ "AREJOIN" , 3, &AutoRejoin , &AutoRejoinChannels },
{ "AJOIN" , 3, &AutoJoinOnInv , &AutoJoinChannels },
#if defined(EXTRAS) || defined(FLIER)
{ "AUTOINV" , 3, &AutoInv , &AutoInvChannels },
#endif
/* Floodp should return FloodProt, FloodMessages and FloodSeconds */
{ "FLOODP" , 1, &FloodProt , NULL },
{ "SERVNOTICE" , 1, &ServerNotice , NULL },
{ "CTCPCLOAK" , 1, &CTCPCloaking , NULL },
{ "FAKE" , 3, &ShowFakes , &ShowFakesChannels },
{ "SHOWAWAY" , 3, &ShowAway , &ShowAwayChannels },
{ "KICKOPS" , 3, &KickOps , &KickOpsChannels },
{ "KICKONFLOOD" , 3, &KickOnFlood , &KickOnFloodChannels },
{ "SHOWNICK" , 1, &ShowNick , NULL },
{ "KICKONBAN" , 3, &KickOnBan , &KickOnBanChannels },
{ "REPWORD" , 2, NULL , &AutoReplyBuffer },
{ "ORIGNICK" , 3, &OrigNickChange , &OrigNick },
{ "NTFYMODE" , 1, &NotifyMode , NULL },
{ "URLCATCH" , 1, &URLCatch , NULL },
{ "EGO" , 1, &Ego , NULL },
{ "AUTOCOMPL" , 3, &AutoNickCompl , &AutoReplyString },
{ "BITCH" , 3, &Bitch , &BitchChannels },
{ "FRLIST" , 3, &FriendList , &FriendListChannels },
#ifdef EXTRAS
{ "IDLEKICK" , 3, &IdleKick , &IdleKickChannels },
{ "CHSIGNOFF" , 3, &ShowSignoffChan , &SignoffChannels },
#endif
{ "COMPRESS" , 3, &CompressModes , &CompressModesChannels },
{ "STAMP" , 1, &Stamp , NULL },
{ "ARINWIN" , 1, &ARinWindow , NULL },
{ "BKLIST" , 3, &BKList , &BKChannels },
#ifdef WANTANSI
{ "MIRC" , 1, &DisplaymIRC , NULL },
#endif
#ifdef EXTRAS
{ "SHOWSIGN" , 1, &ShowSignAllChan , NULL },
#endif
{ "EXTPUB" , 1, &ExtPub , NULL },
{ "CHANLOG" , 3, &ChanLog , &ChanLogChannels },
{ "CHANLOGDEST" , 2, NULL , &ChanLogDir },
{ "CHANLOGPREFIX" , 2, NULL , &ChanLogPrefix },
{ "CHANLOGPOST" , 2, NULL , &ChanLogPostfix },
#ifdef EXTRAS
{ "NICKCHAN" , 1, &ShowNickAllChan , NULL },
#endif
{ "AWAYENCR" , 1, &AwayEncrypt , NULL },
{ NULL , 0, NULL , NULL }
};
if (input && *input) {
strmcpy(locbuf,(char *) input,mybufsize);
upper(locbuf);
for (i=0;command_list[i].command;i++)
if (!strcmp(command_list[i].command,locbuf)) break;
if (!(command_list[i].command)) {
malloc_strcpy((char **) &result,empty_string);
return(result);
}
*locbuf='\0';
switch (command_list[i].type) {
case 1:
/* Cdcc limit is special case */
if (!strcmp(command_list[i].command,"CDCCLIMIT"))
snprintf(locbuf,sizeof(locbuf),"%d %d",*(command_list[i].ivar),CdccQueueLimit);
/* Floodp is special case */
else if (!strcmp(command_list[i].command,"FLOODP"))
snprintf(locbuf,sizeof(locbuf),"%d %d %d",
*(command_list[i].ivar),FloodMessages,FloodSeconds);
else snprintf(locbuf,sizeof(locbuf),"%d",*(command_list[i].ivar));
break;
case 2:
/* Bantype is special case */
if (!strcmp(command_list[i].command,"BANTYPE")) {
*locbuf=tolower(defban);
*(locbuf+1)='\0';
}
else if (*(command_list[i].svar)) strmcpy(locbuf,*(command_list[i].svar),sizeof(locbuf));
break;
case 3:
if (*(command_list[i].ivar) && *(command_list[i].svar)) {
snprintf(locbuf,sizeof(locbuf),"%d %s",*(command_list[i].ivar),*(command_list[i].svar));
/* Orignick is special case */
if (OrigNickQuiet && !strcmp(command_list[i].command,"ORIGNICK"))
*locbuf='2';
}
else strcpy(locbuf,"0");
/* Nhprot is special case */
if (!strcmp(command_list[i].command,"NHPROT"))
snprintf(locbuf+strlen(locbuf),sizeof(locbuf)-strlen(locbuf)," %s",
NHDisp == 0 ? "q" : (NHDisp == 1 ? "m" : "f"));
break;
}
if (*locbuf) {
malloc_strcpy((char **) &result,locbuf);
return(result);
}
}
malloc_strcpy((char **) &result,empty_string);
return(result);
}
#endif /* !CELESCRP && !LITE */
u_char *function_stamp(input)
u_char *input;
{
u_char *result = NULL;
char *stampbuf = TimeStamp(0);
if (stampbuf) malloc_strcpy((char **) &result, stampbuf);
else malloc_strcpy((char **) &result,empty_string);
return(result);
}
u_char *function_chankey(input)
u_char *input;
{
char *channel;
u_char *result = NULL;
ChannelList *chan;
if ((channel = next_arg((char *) input,(char **) &channel)) &&
(chan = lookup_channel(channel, from_server, 0)) && chan->key) {
malloc_strcpy((char **) &result, chan->key);
}
else malloc_strcpy((char **) &result, empty_string);
return(result);
}
#ifdef HAVE_REGCOMP
u_char *function_regexp(input)
u_char *input;
{
char *pattern;
u_char *result = NULL;
regex_t regex;
if (((pattern = new_next_arg((char *) input, (char **) &input)) != NULL) &&
input && *input) {
if (regcomp(®ex, pattern, REG_EXTENDED | REG_NOSUB | REG_ICASE) == 0) {
if (regexec(®ex, input, 0, NULL, 0) == 0) {
malloc_strcpy((char **) &result, "1");
}
}
regfree(®ex);
}
if (result == NULL) malloc_strcpy((char **) &result, "0");
return(result);
}
#define REGREPL_COUNT 10
u_char *function_regexpreplace(input)
u_char *input;
{
char *x;
char *pattern;
char *search;
char *replace = NULL;
u_char *result = NULL;
regex_t regex;
if (((pattern = new_next_arg((char *) input, (char **) &input)) != NULL) &&
input && *input) {
search = pattern;
if (*search == '/') {
search++;
replace = search;
while (*replace && *replace != '/') replace++;
if (*replace) {
*replace++ = '\0';
x = replace;
while (*x && *x != '/') x++;
if (*x == '/') *x++ = '\0';
}
}
if (replace && *replace) {
if (regcomp(®ex, search, REG_EXTENDED | REG_ICASE) == 0) {
regmatch_t pmatch[REGREPL_COUNT];
if (regexec(®ex, input, REGREPL_COUNT, pmatch, 0) == 0) {
int i;
char *tmp = replace;
char *tmpstr = NULL;
char *prevtmp = replace;
while (*tmp) {
if (*tmp == '$') {
if (prevtmp != tmp) {
tmpstr = (char *) new_malloc(tmp - prevtmp + 2);
strmcpy(tmpstr, prevtmp, tmp - prevtmp + 1);
malloc_strcat((char **) &result, tmpstr);
new_free(&tmpstr);
}
tmp++;
i = atoi(tmp);
while (*tmp && isdigit(*tmp)) tmp++;
prevtmp = tmp;
if (i >=0 && i <= REGREPL_COUNT) {
int l = pmatch[i].rm_eo - pmatch[i].rm_so;
tmpstr = (char *) new_malloc(l + 2);
strmcpy(tmpstr, &input[pmatch[i].rm_so], l + 1);
malloc_strcat((char **) &result, tmpstr);
new_free(&tmpstr);
}
}
else tmp++;
}
if (prevtmp != tmp) {
tmpstr = (char *) new_malloc(tmp - prevtmp + 2);
strmcpy(tmpstr, prevtmp, tmp - prevtmp + 1);
malloc_strcat((char **) &result, tmpstr);
new_free(&tmpstr);
}
}
}
regfree(®ex);
}
}
if (result == NULL) malloc_strcpy((char **) &result, empty_string);
return(result);
}
#endif /* REGCOMP */
/* Removes all aliases */
void DumpAliases(type)
int type;
{
Alias *tmp;
Alias *tmpdel;
for (tmp=alias_list[type];tmp;) {
tmpdel=tmp;
tmp=tmp->next;
new_free(&(tmpdel->name));
new_free(&(tmpdel->stuff));
new_free(&tmpdel);
}
alias_list[type]=(Alias *) 0;
}
/* Really removes structure */
void DumpAssign(name)
char *name;
{
int found=0;
int namelen;
char locbuf[mybufsize];
Alias *tmp;
Alias *tmprem;
snprintf(locbuf,sizeof(locbuf),"%s.",name);
namelen=strlen(locbuf);
for (tmp=alias_list[VAR_ALIAS];tmp;) {
tmprem=tmp;
tmp=tmp->next;
if (!strncmp(tmprem->name,locbuf,namelen))
if ((tmprem=find_alias(&(alias_list[VAR_ALIAS]),tmprem->name,1,NULL))) {
new_free(&(tmprem->name));
new_free(&(tmprem->stuff));
new_free(&tmprem);
found=1;
}
}
if (found) say("Assign structure %s removed",name);
else say("Assign structure %s not found",name);
}
/* Clears assigned structure */
#ifndef LITE
void Purge(command,args,subargs)
char *command;
char *args;
char *subargs;
{
char *name;
if (!(args && *args)) {
PrintUsage("PURGE name");
return;
}
name=new_next_arg(args,&args);
upper(name);
DumpAssign(name);
}
#endif
/****************************************************************************/
syntax highlighted by Code2HTML, v. 0.9.1