1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-06-30 06:36:38 +02:00
Files
unrealircd/src/webtv.c
T
stskeeps 155374409d +- Added Member and Membership and made the IRCd support this. Using
+  "freelinks", todo: garbage collection
+- Added find_member_link and find_membership_link. Made Floodopt only
+  get allocated for local users. Removed aFloodOpt in Link,
+- Made a speedup in is_halfop (dumb code)
2001-02-28 16:24:37 +00:00

388 lines
9.9 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 "userload.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[]);
aMessage webtv_cmds[] =
{
{"WHOIS", w_whois, 15},
{NULL, 0, 15}
};
int webtv_parse(aClient *sptr, char *string)
{
char *cmd = NULL, *s = NULL;
int i;
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;
}
cmd = strtok(string, " ");
if (!cmd)
return -2;
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*/
cmd[strlen(cmd)]= ' ';
return -2;
}
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;
(*message->func) (sptr->from, sptr, i, para);
return 0;
}
int w_whois(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
static anUser UnknownUser = {
NULL, /* nextu */
NULL, /* channel */
NULL, /* invited */
NULL, /* silence */
NULL, /* away */
0, /* last */
0, /* servicestamp */
1, /* refcount */
0, /* joined */
"<Unknown>", /* username */
"<Unknown>", /* host */
"<Unknown>" /* server */
};
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, 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;
user = acptr->user ? acptr->user : &UnknownUser;
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;
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 = strlen(me.name) + strlen(sptr->name) + 6 +
strlen(name);
for (len = 0, *buf = '\0', lp = user->channel; lp;
lp = lp->next)
{
chptr = lp->chptr;
if (IsAnOper(sptr) || ShowChannel(sptr, chptr) || (acptr == sptr))
{
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;
}
if (!(acptr == sptr) && IsAnOper(sptr)
&& (showsecret == 1) && SecretChannel(chptr))
*(buf + len++) = '~';
if (is_chanowner(acptr, chptr))
*(buf + len++) = '*';
else if (is_chanprot(acptr, chptr))
*(buf + len++) = '^';
else if (is_chan_op(acptr, chptr))
*(buf + len++) = '@';
else if (is_half_op(acptr, chptr))
*(buf + len++) = '%';
else if (has_voice(acptr, chptr))
*(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' && !IsULine(acptr) && (!IsHiding(acptr) ||
IsNetAdmin(sptr) || IsTechAdmin(sptr) || sptr == acptr))
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 (IsTechAdmin(acptr))
strcat(buf,
"a Technical Administrator");
else if (IsSAdmin(acptr))
strcat(buf, "a Services Operator");
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() - user->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;
}