1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-06-28 19:36:38 +02:00
Files
unrealircd/src/webtv.c
T
2004-06-17 21:16:58 +00:00

424 lines
11 KiB
C

/************************************************************************
* Unreal Internet Relay Chat Daemon, src/webtv.c
* (C) Carsten V. Munk (Stskeeps <stskeeps@tspre.org>) 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 1, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "msg.h"
#include "channel.h"
#include "version.h"
#include <time.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <io.h>
#endif
#include <fcntl.h>
#include "h.h"
#include "proto.h"
ID_Copyright("(C) Carsten Munk 2000");
extern ircstats IRCstats;
typedef struct zMessage aMessage;
struct zMessage {
char *command;
int (*func) ();
int maxpara;
};
int w_whois(aClient *cptr, aClient *sptr, int parc, char *parv[]);
/* This really has nothing to do with WebTV yet, but eventually it will, so I figured
* it's easiest to put it here so why not? -- codemastr
*/
int ban_version(aClient *cptr, aClient *sptr, int parc, char *parv[]);
MODVAR aMessage webtv_cmds[] =
{
{"WHOIS", w_whois, 15},
{"\1VERSION", ban_version, 1},
{"\1SCRIPT", ban_version, 1},
{NULL, 0, 15}
};
int webtv_parse(aClient *sptr, char *string)
{
char *cmd = NULL, *s = NULL;
int i, n;
aMessage *message = webtv_cmds;
static char *para[16];
if (!string || !*string)
{
sendto_one(sptr, ":IRC %s %s :No command given", MSG_PRIVATE, sptr->name);
return 0;
}
n = strlen(string);
cmd = strtok(string, " ");
if (!cmd)
return -99;
for (message = webtv_cmds; message->command; message++)
if (strcasecmp(message->command, cmd) == 0)
break;
if (!message->command || !message->func)
{
/* sendto_one(sptr, ":IRC %s %s :Sorry, \"%s\" is an unknown command to me",
MSG_PRIVATE, sptr->name, cmd); */
/* restore the string*/
if (strlen(cmd) < n)
cmd[strlen(cmd)]= ' ';
return -99;
}
i = 0;
s = strtok(NULL, "");
if (s)
{
if (message->maxpara > 15)
message->maxpara = 15;
for (;;)
{
/*
** Never "FRANCE " again!! ;-) Clean
** out *all* blanks.. --msa
*/
while (*s == ' ')
*s++ = '\0';
if (*s == '\0')
break;
if (*s == ':')
{
/*
** The rest is single parameter--can
** include blanks also.
*/
para[++i] = s + 1;
break;
}
para[++i] = s;
if (i >= message->maxpara)
break;
for (; *s != ' ' && *s; s++)
;
}
}
para[++i] = NULL;
return (*message->func) (sptr->from, sptr, i, para);
}
int w_whois(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
Membership *lp;
anUser *user;
aClient *acptr, *a2cptr;
aChannel *chptr;
char *nick, *tmp, *name;
char *p = NULL;
char buf[512];
int found, len, mlen;
if (parc < 2)
{
sendto_one(sptr, ":IRC %s %s :Syntax error, correct is WHOIS <nick>",
MSG_PRIVATE, sptr->name);
return 0;
}
for (tmp = parv[1]; (nick = strtoken(&p, tmp, ",")); tmp = NULL)
{
int invis, showsecret = 0, showchannel, showperson, member, wilds;
found = 0;
(void)collapse(nick);
wilds = (index(nick, '?') || index(nick, '*'));
if (wilds)
continue;
for (acptr = client; (acptr = next_client(acptr, nick));
acptr = acptr->next)
{
if (IsServer(acptr))
continue;
/*
* I'm always last :-) and acptr->next == NULL!!
*/
if (IsMe(acptr))
break;
/*
* 'Rules' established for sending a WHOIS reply:
*
* - only allow a remote client to get replies for
* local clients if wildcards are being used;
*
* - if wildcards are being used dont send a reply if
* the querier isnt any common channels and the
* client in question is invisible and wildcards are
* in use (allow exact matches only);
*
* - only send replies about common or public channels
* the target user(s) are on;
*/
if (!MyConnect(sptr) && !MyConnect(acptr) && wilds)
continue;
if (!IsPerson(acptr))
continue;
user = acptr->user;
name = (!*acptr->name) ? "?" : acptr->name;
invis = acptr != sptr && IsInvisible(acptr);
member = (user->channel) ? 1 : 0;
showperson = (wilds && !invis && !member) || !wilds;
for (lp = user->channel; lp; lp = lp->next)
{
chptr = lp->chptr;
member = IsMember(sptr, chptr);
if (invis && !member)
continue;
if (member || (!invis && PubChannel(chptr)))
{
showperson = 1;
break;
}
if (!invis && HiddenChannel(chptr) &&
!SecretChannel(chptr))
showperson = 1;
else if (IsAnOper(sptr) && SecretChannel(chptr)) {
showperson = 1;
showsecret = 1;
}
}
if (!showperson)
continue;
a2cptr = find_server_quick(user->server);
/* if (!IsPerson(acptr))
continue; ** moved to top -- Syzop */
sendto_one(sptr, ":IRC PRIVMSG %s :WHOIS information for %s", sptr->name, acptr->name);
if (IsWhois(acptr))
{
sendto_one(acptr,
":%s NOTICE %s :*** %s (%s@%s) did a /whois on you.",
me.name, acptr->name, sptr->name,
sptr->user->username,
IsHidden(acptr) ? sptr->user->
virthost : sptr->user->realhost);
}
sendto_one(sptr, ":IRC PRIVMSG %s :%s is %s@%s * %s", sptr->name,
name, user->username,
IsHidden(acptr) ? user->virthost : user->realhost,
acptr->info);
if (IsEyes(sptr))
{
/* send the target user's modes */
sendto_one(sptr, ":IRC PRIVMSG %s :%s uses modes %s",
sptr->name, acptr->name, get_mode_str(acptr));
}
if ((IsAnOper(sptr) && IsHidden(acptr)) ||
(acptr == sptr && IsHidden(sptr)))
{
sendto_one(sptr, ":IRC PRIVMSG %s :%s is connecting from %s",
sptr->name, acptr->name,
acptr->user->realhost);
}
if (IsARegNick(acptr))
sendto_one(sptr, ":IRC PRIVMSG %s :%s is a registered nick",
sptr->name, name);
found = 1;
mlen = 24 + strlen(sptr->name) + strlen(name);
for (len = 0, *buf = '\0', lp = user->channel; lp;
lp = lp->next)
{
chptr = lp->chptr;
showchannel = 0;
if (ShowChannel(sptr, chptr))
showchannel = 1;
#ifndef SHOW_SECRET
if (IsAnOper(sptr) && !SecretChannel(chptr))
#else
if (IsAnOper(sptr))
#endif
showchannel = 1;
if ((acptr->umodes & UMODE_HIDEWHOIS) && !IsMember(sptr, chptr) && !IsAnOper(sptr))
showchannel = 0;
if (IsServices(acptr) && !IsNetAdmin(sptr))
showchannel = 0;
if (acptr == sptr)
showchannel = 1;
if (showchannel)
{
long access;
if (len + strlen(chptr->chname)
> (size_t)BUFSIZE - 4 - mlen)
{
sendto_one(sptr,
":IRC PRIVMSG %s :%s is on %s",
sptr->name, name, buf);
*buf = '\0';
len = 0;
}
#ifdef SHOW_SECRET
if (IsAnOper(sptr)
#else
if (IsNetAdmin(sptr)
#endif
&& SecretChannel(chptr) && !IsMember(sptr, chptr))
*(buf + len++) = '?';
if (acptr->umodes & UMODE_HIDEWHOIS && !IsMember(sptr, chptr)
&& IsAnOper(sptr))
*(buf + len++) = '!';
access = get_access(acptr, chptr);
#ifndef PREFIX_AQ
if (access & CHFL_CHANOWNER)
*(buf + len++) = '*';
else if (access & CHFL_CHANPROT)
*(buf + len++) = '^';
#else
if (access & CHFL_CHANOWNER)
*(buf + len++) = '~';
else if (access & CHFL_CHANPROT)
*(buf + len++) = '&';
#endif
else if (access & CHFL_CHANOP)
*(buf + len++) = '@';
else if (access & CHFL_HALFOP)
*(buf + len++) = '%';
else if (access & CHFL_VOICE)
*(buf + len++) = '+';
if (len)
*(buf + len) = '\0';
(void)strcpy(buf + len, chptr->chname);
len += strlen(chptr->chname);
(void)strcat(buf + len, " ");
len++;
}
}
if (buf[0] != '\0')
sendto_one(sptr,
":IRC PRIVMSG %s :%s is on %s",
sptr->name, name, buf);
sendto_one(sptr, ":IRC PRIVMSG %s :%s is on irc via %s %s",
sptr->name, name, user->server,
a2cptr ? a2cptr->info : "*Not On This Net*");
if (user->away)
sendto_one(sptr, ":IRC PRIVMSG %s :%s is away: %s",
sptr->name, name, user->away);
/* makesure they aren't +H (we'll also check
before we display a helpop or IRCD Coder msg)
-- codemastr */
if ((IsAnOper(acptr) || IsServices(acptr))
&& (!IsHideOper(acptr) || sptr == acptr || IsAnOper(sptr)))
{
buf[0] = '\0';
if (IsNetAdmin(acptr))
strcat(buf, "a Network Administrator");
else if (IsSAdmin(acptr))
strcat(buf, "a Services Administrator");
else if (IsAdmin(acptr) && !IsCoAdmin(acptr))
strcat(buf, "a Server Administrator");
else if (IsCoAdmin(acptr))
strcat(buf, "a Co Administrator");
else if (IsServices(acptr))
strcat(buf, "a Network Service");
else if (IsOper(acptr))
strcat(buf, "an IRC Operator");
else
strcat(buf, "a Local IRC Operator");
if (buf[0])
sendto_one(sptr,
":IRC PRIVMSG %s :%s is an %s on %s",
sptr->name, name, buf, ircnetwork);
}
if (IsHelpOp(acptr) && (!IsHideOper(acptr) || sptr == acptr || IsAnOper(sptr)))
if (!acptr->user->away)
sendto_one(sptr, ":IRC PRIVMSG %s :%s is available for help.",
sptr->name, acptr->name);
if (acptr->umodes & UMODE_BOT)
{
sendto_one(sptr, ":IRC PRIVMSG %s :%s is an Bot on %s",
sptr->name, name, ircnetwork);
}
if (acptr->umodes & UMODE_SECURE)
{
sendto_one(sptr, ":IRC PRIVMSG %s :%s is a Secure Connection",
sptr->name, acptr->name);
}
if (acptr->user->swhois)
{
if (*acptr->user->swhois != '\0')
sendto_one(sptr, ":IRC PRIVMSG %s :%s %s",
sptr->name, acptr->name,
acptr->user->swhois);
}
if (acptr->user && MyConnect(acptr))
sendto_one(sptr, ":IRC PRIVMSG %s :%s has been idle for %s signed on at %s",
sptr->name, acptr->name,
(char *)convert_time(TStime() - acptr->last),
date(acptr->firsttime));
}
if (!found)
{
sendto_one(sptr, ":IRC PRIVMSG %s :%s - No such nick",
sptr->name, nick);
}
if (p)
p[-1] = ',';
}
sendto_one(sptr, ":IRC PRIVMSG %s :End of whois information for %s",
sptr->name, parv[1]);
return 0;
}
int ban_version(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
int len;
ConfigItem_ban *ban;
if (parc < 2)
return 0;
len = strlen(parv[1]);
if (!len)
return 0;
if (parv[1][len-1] == '\1')
parv[1][len-1] = '\0';
if ((ban = Find_ban(NULL, parv[1], CONF_BAN_VERSION)))
return place_host_ban(sptr, ban->action, ban->reason, BAN_VERSION_TKL_TIME);
return 0;
}