/*
* funny.c: Well, I put some stuff here and called it funny. So sue me.
*
* 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: funny.c,v 1.24 2004/07/02 18:04:52 f Exp $
*/
#include "irc.h"
#include "ircaux.h"
#include "hook.h"
#include "vars.h"
#include "funny.h"
#include "names.h"
#include "server.h"
#include "lastlog.h"
#include "ircterm.h"
#include "output.h"
#include "numbers.h"
#include "parse.h"
#include "screen.h"
/**************************** PATCHED by Flier ******************************/
#include "myvars.h"
extern void PrintNames _((char *, char *, ChannelList *));
extern void PrintSynch _((ChannelList *));
extern int IsIrcNetOperChannel _((char *));
#if defined(OPERVISION) && defined(WANTANSI)
extern void OperVisionReinit _((void));
#endif
extern void ChannelLogSave _((char *, ChannelList *));
/****************************************************************************/
static char *match_str = (char *) 0;
static int funny_min;
static int funny_max;
static int funny_flags;
void
funny_match(stuff)
char *stuff;
{
malloc_strcpy(&match_str, stuff);
}
void
set_funny_flags(min, max, flags)
int min,
max,
flags;
{
funny_min = min;
funny_max = max;
funny_flags = flags;
}
struct WideListInfoStru
{
char *channel;
int users;
};
typedef struct WideListInfoStru WideList;
static WideList **wide_list = (WideList **) 0;
static int wl_size = 0;
static size_t wl_elements = 0;
static int funny_widelist_users _((WideList **, WideList **));
static int funny_widelist_names _((WideList **, WideList **));
static int
funny_widelist_users(left, right)
WideList **left,
**right;
{
if ((**left).users > (**right).users)
return -1;
else if ((**right).users > (**left).users)
return 1;
else
return my_stricmp((**left).channel, (**right).channel);
}
static int
funny_widelist_names(left, right)
WideList **left,
**right;
{
int comp;
if ((comp = my_stricmp((**left).channel, (**right).channel)) != 0)
return comp;
else if ((**left).users > (**right).users)
return -1;
else if ((**right).users > (**left).users)
return 1;
else
return 0;
}
void
funny_print_widelist()
{
int i;
char buffer1[BIG_BUFFER_SIZE+1];
char buffer2[BIG_BUFFER_SIZE+1];
char *ptr;
if (!wide_list)
return;
if (funny_flags & FUNNY_NAME)
qsort((void *) wide_list, wl_elements, sizeof(WideList *),
(int (*) _((const void *, const void *))) funny_widelist_names);
else if (funny_flags & FUNNY_USERS)
qsort((void *) wide_list, wl_elements, sizeof(WideList *),
(int (*) _((const void *, const void *))) funny_widelist_users);
*buffer1 = '\0';
for (i = 0; i < wl_elements; i++)
{
snprintf(buffer2, sizeof buffer2, "%s(%d) ", wide_list[i]->channel,
wide_list[i]->users);
ptr = index(buffer1, '\0');
if (strlen(buffer1) + strlen(buffer2) > current_screen->co - 5)
{
if (do_hook(WIDELIST_LIST, "%s", buffer1))
say("%s", buffer1);
*buffer1 = '\0';
/**************************** Patched by Flier ******************************/
/*strcat(buffer1, buffer2);*/
strmcat(buffer1, buffer2, sizeof(buffer1));
/****************************************************************************/
}
else
/**************************** Patched by Flier ******************************/
/*strcpy(ptr, buffer2);*/
strmcpy(ptr, buffer2, sizeof(buffer1) - (ptr - buffer1));
/****************************************************************************/
}
if (*buffer1 && do_hook(WIDELIST_LIST, "%s", buffer1))
say("%s" , buffer1);
for (i = 0; i < wl_elements; i++)
{
new_free(&wide_list[i]->channel);
new_free(&wide_list[i]);
}
new_free(&wide_list);
wl_elements = wl_size = 0;
}
/*ARGSUSED*/
void
funny_list(from, ArgList)
char *from;
char **ArgList;
{
char *channel,
*user_cnt,
*line;
WideList **new_list;
int cnt;
static char format[25];
static int last_width = -1;
if (last_width != get_int_var(CHANNEL_NAME_WIDTH_VAR))
{
/**************************** PATCHED by Flier ******************************/
/*if ((last_width = get_int_var(CHANNEL_NAME_WIDTH_VAR)) != 0)
snprintf(CP(format), sizeof format, "*** %%-%u.%us %%-5s %%s",
(unsigned char) last_width,
(unsigned char) last_width);
else
strcpy(format, "*** %s\t%-5s %s");*/
if ((last_width = get_int_var(CHANNEL_NAME_WIDTH_VAR)) != 0)
snprintf(format, sizeof format, "*** %%-%u.%us %%-5s %%s",
(unsigned char) last_width,
(unsigned char) last_width);
else
strcpy(format, "%s\t%-5s %s");
/****************************************************************************/
}
channel = ArgList[0];
user_cnt = ArgList[1];
line = PasteArgs(ArgList, 2);
if (funny_flags & FUNNY_TOPIC && !(line && *line))
return;
cnt = atoi(user_cnt);
if (funny_min && (cnt < funny_min))
return;
if (funny_max && (cnt > funny_max))
return;
if ((funny_flags & FUNNY_PRIVATE) && (*channel != '*'))
return;
if ((funny_flags & FUNNY_PUBLIC) && (*channel == '*'))
return;
if (match_str)
{
if (wild_match(match_str, channel) == 0)
return;
}
if (funny_flags & FUNNY_WIDE)
{
if (wl_elements >= wl_size)
{
new_list = (WideList **) new_malloc(sizeof(WideList *) *
(wl_size + 50));
bzero(new_list, sizeof(WideList *) * (wl_size + 50));
if (wl_size)
bcopy(wide_list, new_list, sizeof(WideList *)
* wl_size);
wl_size += 50;
new_free(&wide_list);
wide_list = new_list;
}
wide_list[wl_elements] = (WideList *)
new_malloc(sizeof(WideList));
wide_list[wl_elements]->channel = (char *) 0;
wide_list[wl_elements]->users = cnt;
malloc_strcpy(&wide_list[wl_elements]->channel,
(*channel != '*') ? channel : "Prv");
wl_elements++;
return;
}
if (do_hook(current_numeric, "%s %s %s %s", from, channel, user_cnt,
line) && do_hook(LIST_LIST, "%s %s %s", channel, user_cnt, line))
{
if (channel && user_cnt)
{
if (*channel == '*')
/**************************** PATCHED by Flier ******************************/
/*put_it(format, "Prv", user_cnt, line);*/
say(format, "Prv", user_cnt, line);
/****************************************************************************/
else
/**************************** PATCHED by Flier ******************************/
/*put_it(format, channel, user_cnt, line);*/
say(format, channel, user_cnt, line);
/****************************************************************************/
}
}
}
void
funny_namreply(from, Args)
char *from;
char **Args;
{
char *type,
*nick,
*channel;
static char format[40];
static int last_width = -1;
int cnt;
char *ptr;
char *line;
ChannelList *tmp = (ChannelList *) 0;
PasteArgs(Args, 2);
type = Args[0];
channel = Args[1];
line = Args[2];
save_message_from();
message_from(channel, LOG_CRAP);
if ((tmp = lookup_channel(channel, parsing_server_index, CHAN_NOUNLINK)) && !((tmp->status & CHAN_NAMES) && (tmp->status & CHAN_MODE)))
{
if (do_hook(current_numeric, "%s %s %s %s", from, type, channel,
line) && get_int_var(SHOW_CHANNEL_NAMES_VAR))
/**************************** PATCHED by Flier ******************************/
/*say("Users on %s: %s", channel, line);
while ((nick = next_arg(line, &line)) != NULL)
add_to_channel(channel, nick, parsing_server_index, 0, 0);*/
PrintNames(channel, line, tmp);
while ((nick = next_arg(line, &line))!=NULL)
add_to_channel(channel, nick, parsing_server_index, 0, 0, 0, NULL, tmp);
/****************************************************************************/
tmp->status |= CHAN_NAMES;
goto out;
}
if (last_width != get_int_var(CHANNEL_NAME_WIDTH_VAR))
{
if ((last_width = get_int_var(CHANNEL_NAME_WIDTH_VAR)) != 0)
snprintf(format, sizeof format, "%%s: %%-%u.%us %%s",
(unsigned char) last_width,
(unsigned char) last_width);
else
strcpy(format, "%s: %s\t%s");
}
ptr = line;
for (cnt = -1; ptr; cnt++)
{
if ((ptr = index(ptr, ' ')) != NULL)
ptr++;
}
if (funny_min && (cnt < funny_min))
return;
else if (funny_max && (cnt > funny_max))
return;
if ((funny_flags & FUNNY_PRIVATE) && (*type == '='))
return;
if ((funny_flags & FUNNY_PUBLIC) && (*type == '*'))
return;
if (type && channel)
{
if (match_str)
{
if (wild_match(match_str, channel) == 0)
return;
}
if (do_hook(current_numeric, "%s %s %s %s", from, type, channel,
line) && do_hook(NAMES_LIST, "%s %s", channel, line))
{
switch (*type)
{
case '=':
if (last_width &&(strlen(channel) > last_width))
{
channel[last_width-1] = '>';
channel[last_width] = (char) 0;
}
/**************************** PATCHED by Flier ******************************/
/*put_it(format, "Pub", channel, line);*/
say("Users on %s are : %s", channel, line);
/****************************************************************************/
break;
case '*':
/**************************** PATCHED by Flier ******************************/
/*put_it(format, "Prv", channel, line);*/
say("Users on %s are : %s", channel, line);
/****************************************************************************/
break;
case '@':
/**************************** PATCHED by Flier ******************************/
/*put_it(format, "Sec", channel, line);*/
say("Users on %s are : %s", channel, line);
/****************************************************************************/
break;
}
}
}
out:
restore_message_from();
}
void
funny_mode(from, ArgList)
char *from,
**ArgList;
{
char *mode, *channel;
ChannelList *tmp = (ChannelList *) 0;
if (!ArgList[0])
return;
if (get_server_version(parsing_server_index) < Server2_6)
{
channel = (char *) 0;
mode = ArgList[0];
PasteArgs(ArgList, 0);
}
else
{
channel = ArgList[0];
mode = ArgList[1];
PasteArgs(ArgList, 1);
}
/* if (ignore_mode) */
if (channel && (tmp = lookup_channel(channel, parsing_server_index, CHAN_NOUNLINK)) && !((tmp->status & CHAN_NAMES) && (tmp->status & CHAN_MODE)))
{
/**************************** PATCHED by Flier ******************************/
/*update_channel_mode(channel, parsing_server_index, mode);*/
update_channel_mode(channel, parsing_server_index, mode, strlen(mode),
NULL, NULL, NULL, NULL, tmp);
if ((get_server_version(from_server) == Server2_9 ||
get_server_version(from_server) == Server2_10 ||
get_server_version(from_server) == Server2_11) &&
IsIrcNetOperChannel(channel)) {
tmp->gotbans = 1;
tmp->gotwho = 1;
if (server_list[from_server].SZUnban > 2)
server_list[from_server].SZUnban--;
else server_list[from_server].SZUnban = 0;
server_list[from_server].SZWho--;
PrintSynch(tmp);
}
if (tmp && tmp->ChanLog) {
char tmpbuf[mybufsize];
snprintf(tmpbuf, sizeof(tmpbuf), "Mode for channel %s is %s", channel, mode);
ChannelLogSave(tmpbuf, tmp);
}
/****************************************************************************/
tmp->status |= CHAN_MODE;
update_all_status();
}
else
{
save_message_from();
message_from(channel, LOG_CRAP);
if (channel)
{
if (do_hook(current_numeric, "%s %s %s", from,
channel, mode))
/**************************** Patched by Flier ******************************/
/*put_it("%s Mode for channel %s is \"%s\"",*/
put_it("%sMode for channel %s is \"%s\"",
/****************************************************************************/
numeric_banner(), channel, mode);
}
else
{
if (do_hook(current_numeric, "%s %s", from, mode))
/**************************** Patched by Flier ******************************/
/*put_it("%s Channel mode is \"%s\"",*/
put_it("%sChannel mode is \"%s\"",
/****************************************************************************/
numeric_banner(), mode);
}
restore_message_from();
}
}
/**************************** PATCHED by Flier ******************************/
void update_user_mode(modes)
char *modes;
{
int onoff = 1;
while (*modes) {
if (*modes == '-') onoff = 0;
else if (*modes == '+') onoff = 1;
else {
if (*modes == 'o' || *modes == 'O')
set_server_operator(parsing_server_index, onoff);
set_server_umode_flag(parsing_server_index, *modes, onoff);
}
modes++;
}
}
void reinstate_user_modes()
{
int i;
char modes[64]; /* more than enough */
char *c;
if (get_server_version(parsing_server_index) < Server2_7) return;
c = modes;
for (i = 0; i < 25; i++) {
if ('a' + i != 'o' && get_server_umode_flag(parsing_server_index, 'a' + i))
*c ++= 'a' + i;
}
for (i = 0; i < 25; i++) {
if ('A' + i != 'O' && get_server_umode_flag(parsing_server_index, 'A' + i))
*c ++= 'A' + i;
}
*c = '\0';
if (PermUserMode)
send_to_server("MODE %s %s", get_server_nickname(parsing_server_index), PermUserMode);
else if (c != modes) send_to_server("MODE %s +%s", get_server_nickname(parsing_server_index), modes);
#if defined(OPERVISION) && defined(WANTANSI)
if (OperV) OperVisionReinit();
#endif
}
/****************************************************************************/
syntax highlighted by Code2HTML, v. 0.9.1