Initial commit of code released on 2002-07-15
This commit is contained in:
27
Sources/Makefile
Normal file
27
Sources/Makefile
Normal file
@@ -0,0 +1,27 @@
|
||||
# Undernet Channel Service (X)
|
||||
# Copyright (C) 1995-2002 Robin Thellend
|
||||
#
|
||||
# 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
#
|
||||
# Please note that this software is unsupported and mostly
|
||||
# obsolete. It was replaced by GNUworld/CMaster. See
|
||||
# http://gnuworld.sourceforge.net/ for more information.
|
||||
#
|
||||
|
||||
|
||||
all:
|
||||
@cd ..; make; cd Sources;
|
||||
72
Sources/Sources.mak
Normal file
72
Sources/Sources.mak
Normal file
@@ -0,0 +1,72 @@
|
||||
# Undernet Channel Service (X)
|
||||
# Copyright (C) 1995-2002 Robin Thellend
|
||||
#
|
||||
# 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
#
|
||||
# Please note that this software is unsupported and mostly
|
||||
# obsolete. It was replaced by GNUworld/CMaster. See
|
||||
# http://gnuworld.sourceforge.net/ for more information.
|
||||
|
||||
|
||||
all: ../cs
|
||||
|
||||
.c.o:
|
||||
${CC} ${CFLAGS} ${DEFINES} -c $<
|
||||
|
||||
../cs: ver ${OBJECTS} cksum.o cksum
|
||||
${CC} ${CFLAGS} ${DEFINES} ${LIBS} -o ../cs main.c cksum.o ${OBJECTS} -DBINCKSUM1=0 -DBINCKSUM2=0
|
||||
${CC} ${CFLAGS} ${DEFINES} ${LIBS} -o ../cs main.c cksum.o ${OBJECTS} `./cksum ../cs`
|
||||
|
||||
ver:
|
||||
@chmod +x version.SH
|
||||
@./version.SH
|
||||
|
||||
cksum: cksum.c
|
||||
${CC} ${CFLAGS} -o cksum cksum.c -DMAIN
|
||||
|
||||
list: ../list
|
||||
|
||||
../list: list.c
|
||||
${CC} -o ../list list.c
|
||||
|
||||
listall: ../listall
|
||||
|
||||
../listall: listall.c
|
||||
${CC} -o ../listall listall.c
|
||||
|
||||
fixdb: match.o
|
||||
${CC} fixdb.c match.o -DMAIN -o ../fixdb
|
||||
|
||||
showdb: match.o
|
||||
${CC} -Wall showdb.c match.o -DMAIN -o ../showdb
|
||||
|
||||
show_old_managers: match.o
|
||||
${CC} -Wall -o ../show_old_managers show_old_managers.c match.o -DMAIN
|
||||
|
||||
clean:
|
||||
$(RM) -f *.o *.bak
|
||||
|
||||
depend:
|
||||
-gcc -MM ${CFLAGS} ${SOURCES} > make.dep
|
||||
|
||||
backup: ${SOURCES} list.c listall.c
|
||||
-cd ..; backups/backup
|
||||
|
||||
love:
|
||||
-@echo "With you?? dream on! :P"
|
||||
|
||||
include make.dep
|
||||
427
Sources/bans.c
Normal file
427
Sources/bans.c
Normal file
@@ -0,0 +1,427 @@
|
||||
/* @(#)$Id: bans.c,v 1.12 1999/04/04 17:00:03 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
|
||||
void ban(char *source, char *chan, char *nicklist)
|
||||
{
|
||||
char buffer[300];
|
||||
char OneNick[NICK_LENGTH];
|
||||
char channel[CHANNELNAME_LENGTH];
|
||||
register auser *user;
|
||||
register aluser *luser;
|
||||
register achannel *ch;
|
||||
register int i = 0;
|
||||
|
||||
if (*nicklist == '#')
|
||||
{
|
||||
GetWord(0, nicklist, channel);
|
||||
nicklist = ToWord(1, nicklist);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(channel, chan);
|
||||
GuessChannel(source, channel);
|
||||
}
|
||||
|
||||
if (!strcmp(channel, "*"))
|
||||
{
|
||||
notice(source, "SYNTAX: ban <channel> <nick1|addr1> [nick2|addr2] [...]");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("BAN REQUEST FOR %s\nON CHANNEL %s\nBY %s (%d)\n",
|
||||
nicklist, channel, source, Access(channel, source));
|
||||
#endif
|
||||
|
||||
if (*source && Access(channel, source) < BAN_LEVEL)
|
||||
{
|
||||
notice(source, "Your Access on this channel is too low");
|
||||
return;
|
||||
}
|
||||
|
||||
ch = ToChannel(channel);
|
||||
|
||||
/* I'm not on this channel.. so screw it! */
|
||||
if (ch == NULL || !ch->on)
|
||||
{
|
||||
notice(source, "I'm NOT on that channel!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ch->AmChanOp)
|
||||
{
|
||||
notice(source, "I'm not channel operator!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!*nicklist)
|
||||
{
|
||||
notice(source, "SYNTAX: ban <channel> <nick1|addr1> [nick2|addr2] [...]");
|
||||
return;
|
||||
}
|
||||
|
||||
GetWord(0, nicklist, OneNick);
|
||||
|
||||
while (*OneNick)
|
||||
{
|
||||
luser = ToLuser(OneNick);
|
||||
if (luser)
|
||||
sprintf(buffer, "%s!%s@%s", luser->nick,
|
||||
luser->username, luser->site);
|
||||
if (luser)
|
||||
{
|
||||
sprintf(buffer, "I BAN %s!%s@%s ON %s", luser->nick,
|
||||
luser->username, luser->site, channel);
|
||||
log(buffer);
|
||||
|
||||
user = ToUser(channel, OneNick);
|
||||
if (user && user->chanop)
|
||||
{
|
||||
changemode(channel, "-o", user->N->nick, 0);
|
||||
}
|
||||
|
||||
MakeBanMask(luser, buffer);
|
||||
changemode(channel, "+b", buffer, 0);
|
||||
}
|
||||
GetWord(++i, nicklist, OneNick);
|
||||
}
|
||||
flushmode(channel);
|
||||
}
|
||||
|
||||
void mban(char *source, char *ch, char *args)
|
||||
{
|
||||
char buffer[200];
|
||||
char channel[80];
|
||||
register int found = 0;
|
||||
register achannel *chan;
|
||||
register auser *user;
|
||||
|
||||
if (*args == '#')
|
||||
{
|
||||
GetWord(0, args, channel);
|
||||
args = ToWord(1, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(channel, ch);
|
||||
GuessChannel(source, channel);
|
||||
}
|
||||
|
||||
if (!strcmp(channel, "*"))
|
||||
{
|
||||
notice(source, "SYNTAX: mban <channel> <nick!username@hostname>");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((chan = ToChannel(channel)) == NULL || !chan->on)
|
||||
{
|
||||
if (*source)
|
||||
notice(source, "I'm NOT on that channel!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!chan->AmChanOp)
|
||||
{
|
||||
if (*source)
|
||||
notice(source, "I am NOT channel operator!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (*source && Access(channel, source) < MASS_BAN_LEVEL)
|
||||
{
|
||||
notice(source, "Your Access on this channel is too low!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!*args)
|
||||
{
|
||||
notice(source, "SYNTAX: mban <channel> <nick!username@hostname>");
|
||||
return;
|
||||
}
|
||||
|
||||
user = chan->users;
|
||||
|
||||
while (user)
|
||||
{
|
||||
sprintf(buffer, "%s!%s@%s",
|
||||
user->N->nick, user->N->username, user->N->site);
|
||||
if (match(buffer, args))
|
||||
{
|
||||
sprintf(buffer, "I BAN %s!%s@%s on %s (%s)", user->N->nick,
|
||||
user->N->username, user->N->site, channel, args);
|
||||
log(buffer);
|
||||
|
||||
if (user->chanop)
|
||||
{
|
||||
changemode(channel, "-o", user->N->nick, 0);
|
||||
user->chanop = 0;
|
||||
}
|
||||
|
||||
/*MakeBanMask(user->N,buffer); */
|
||||
if (!found)
|
||||
changemode(channel, "+b", args, 0);
|
||||
found = 1;
|
||||
}
|
||||
user = user->next;
|
||||
}
|
||||
if (found)
|
||||
flushmode(channel);
|
||||
else if (*source)
|
||||
{
|
||||
notice(source, "No match.");
|
||||
}
|
||||
}
|
||||
|
||||
void unban(char *source, char *ch, char *list)
|
||||
{
|
||||
register aban *bans;
|
||||
register aluser *luser;
|
||||
register achannel *chan;
|
||||
char channel[CHANNELNAME_LENGTH];
|
||||
char buffer[512];
|
||||
char one[200];
|
||||
register int found;
|
||||
register int i, exact;
|
||||
|
||||
if (*list == '#')
|
||||
{
|
||||
GetWord(0, list, channel);
|
||||
list = ToWord(1, list);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(channel, ch);
|
||||
GuessChannel(source, channel);
|
||||
}
|
||||
|
||||
chan = ToChannel(channel);
|
||||
if (chan == NULL || !chan->on)
|
||||
{
|
||||
notice(source, "I am NOT on that channel!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!chan->AmChanOp)
|
||||
{
|
||||
notice(source, "I am not channel operator!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (*source && Access(channel, source) < BAN_LEVEL)
|
||||
{
|
||||
notice(source, "You're Access on this channel is too low");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!*list)
|
||||
{
|
||||
notice(source, "SYNTAX: unban [#channel] <nick1|addr1> [<nick2|addr2>] [...]");
|
||||
return;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
GetWord(0, list, one);
|
||||
while (*one)
|
||||
{
|
||||
found = 0;
|
||||
luser = ToLuser(one);
|
||||
if (luser != NULL)
|
||||
{
|
||||
sprintf(one, "%s!%s@%s", luser->nick, luser->username,
|
||||
luser->site);
|
||||
exact = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
exact = 1;
|
||||
}
|
||||
bans = chan->bans;
|
||||
while (bans != NULL)
|
||||
{
|
||||
if ((!exact && match(one, bans->pattern)) ||
|
||||
(exact && !strcasecmp(one, bans->pattern)))
|
||||
{
|
||||
sprintf(buffer, "I UNBAN %s ON %s",
|
||||
bans->pattern, chan->name);
|
||||
log(buffer);
|
||||
changemode(channel, "-b", bans->pattern, 0);
|
||||
RemBan(channel, bans->pattern);
|
||||
bans = chan->bans;
|
||||
found = 1;
|
||||
if (exact)
|
||||
break;
|
||||
}
|
||||
else
|
||||
bans = bans->next;
|
||||
}
|
||||
if (*source && !found)
|
||||
{
|
||||
sprintf(buffer, "%s is not in %s's banlist!",
|
||||
one, channel);
|
||||
notice(source, buffer);
|
||||
}
|
||||
GetWord(++i, list, one);
|
||||
}
|
||||
flushmode(channel);
|
||||
}
|
||||
|
||||
|
||||
void showbanlist(char *source, char *ch, char *args)
|
||||
{
|
||||
char buffer[200];
|
||||
char channel[80];
|
||||
register achannel *chan;
|
||||
register aban *curr;
|
||||
|
||||
if (*args == '#')
|
||||
{
|
||||
GetWord(0, args, channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(channel, ch);
|
||||
GuessChannel(source, channel);
|
||||
}
|
||||
|
||||
if (!strcmp(channel, "*"))
|
||||
{
|
||||
notice(source, "SYNTAX: banlist <channel>");
|
||||
return;
|
||||
}
|
||||
|
||||
/* user must be on a channel to see the ban list
|
||||
*/
|
||||
if (ToUser(channel, source) == NULL)
|
||||
{
|
||||
sprintf(buffer, "%s: You are not on that channel", channel);
|
||||
notice(source, buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
chan = ToChannel(channel);
|
||||
curr = chan->bans;
|
||||
if (curr == NULL)
|
||||
{
|
||||
sprintf(buffer, "%s: ban list is empty.", channel);
|
||||
notice(source, buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
while (curr != NULL)
|
||||
{
|
||||
notice(source, curr->pattern);
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
sprintf(buffer, "%s: End of ban list", channel);
|
||||
notice(source, buffer);
|
||||
}
|
||||
|
||||
void MakeBanMask(aluser * luser, char *output)
|
||||
{
|
||||
register int isip = 1;
|
||||
register int i, j;
|
||||
int a1, a2, a3, a4;
|
||||
char hostmask[200];
|
||||
register char *ptr;
|
||||
|
||||
if (luser == NULL)
|
||||
{
|
||||
/* Don't do anything */
|
||||
return;
|
||||
}
|
||||
|
||||
/* check if hostname is a numeric IP address
|
||||
*/
|
||||
for (i = 0; luser->site[i] != '\0' && isip; i++)
|
||||
{
|
||||
if (!isdigit(luser->site[i]) && luser->site[i] != '.')
|
||||
isip = 0;
|
||||
}
|
||||
|
||||
if (isip)
|
||||
{
|
||||
sscanf(luser->site, "%d.%d.%d.%d", &a1, &a2, &a3, &a4);
|
||||
|
||||
if (a1 <= 127)
|
||||
{ /* class A */
|
||||
/*sprintf(hostmask,"%d.*",a1); *shrugs* */
|
||||
sprintf(hostmask, "%d.%d.*", a1, a2);
|
||||
}
|
||||
else if (a1 <= 191)
|
||||
{ /* class B */
|
||||
sprintf(hostmask, "%d.%d.*", a1, a2);
|
||||
}
|
||||
else
|
||||
{ /* class C */
|
||||
sprintf(hostmask, "%d.%d.%d.*", a1, a2, a3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* not numeric address */
|
||||
ptr = luser->site + strlen(luser->site);
|
||||
i = 0;
|
||||
|
||||
if (!strcasecmp(luser->site + strlen(luser->site) - 3, ".AU") ||
|
||||
!strncasecmp(luser->site + strlen(luser->site) - 7, ".NET.", 4) ||
|
||||
!strncasecmp(luser->site + strlen(luser->site) - 7, ".COM.", 4) ||
|
||||
!strncasecmp(luser->site + strlen(luser->site) - 7, ".EDU.", 4) ||
|
||||
!strncasecmp(luser->site + strlen(luser->site) - 6, ".AC.", 3))
|
||||
j = 3;
|
||||
else
|
||||
j = 2;
|
||||
|
||||
while (i != j && ptr != luser->site)
|
||||
{
|
||||
if (*ptr == '.')
|
||||
i++;
|
||||
ptr--;
|
||||
}
|
||||
if (i == j)
|
||||
ptr += 2;
|
||||
|
||||
if (ptr == luser->site)
|
||||
strcpy(hostmask, ptr);
|
||||
else
|
||||
sprintf(hostmask, "*.%s", ptr);
|
||||
}
|
||||
|
||||
if (!strncasecmp(luser->username, "^wld", 4))
|
||||
{
|
||||
/* special case for telnet users */
|
||||
sprintf(output, "*!^wld*@%s", hostmask);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = luser->username;
|
||||
while (strlen(ptr) == 10 || *ptr == '~')
|
||||
ptr++;
|
||||
|
||||
sprintf(output, "*!*%s@%s", ptr, hostmask);
|
||||
}
|
||||
}
|
||||
288
Sources/buffer.c
Normal file
288
Sources/buffer.c
Normal file
@@ -0,0 +1,288 @@
|
||||
/* @(#)$Id: buffer.c,v 1.3 1996/11/13 00:40:34 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
/* These routines were first developed for the telnet3d project.
|
||||
* Special thanks to Danny Mitchell (wildthang@irc) for his help
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
|
||||
static struct buffer_block *avail=NULL;
|
||||
/*static unsigned long MEM_buffers=0;*/
|
||||
static unsigned long NB_avail_buffer_blocks=0;
|
||||
static unsigned long NB_alloc_buffer_blocks=0;
|
||||
|
||||
|
||||
/* get_buffer_block() by SeKs <intru@step.polymtl.ca>
|
||||
* returns a ptr to an empty buffer_block or NULL if malloc()
|
||||
* returns an error.
|
||||
*/
|
||||
struct buffer_block *get_buffer_block(void)
|
||||
{
|
||||
register struct buffer_block *block;
|
||||
|
||||
/* I would like to move this to the GetMemory
|
||||
** and linklist functions as soon as we get them
|
||||
** finished. Mainly for use in keeping track
|
||||
** of overall memory usage, and such.
|
||||
** just a reminder. --DVM
|
||||
*/
|
||||
|
||||
if(avail==NULL){
|
||||
block=(struct buffer_block *)malloc(sizeof(struct buffer_block));
|
||||
block->next=NULL;
|
||||
}else{
|
||||
block=avail;
|
||||
avail=avail->next;
|
||||
NB_avail_buffer_blocks--;
|
||||
}
|
||||
|
||||
block->offset_read=0;
|
||||
block->offset_write=0;
|
||||
block->next=NULL;
|
||||
|
||||
NB_alloc_buffer_blocks++;
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
/* return_buffer_block() by SeKs <intru@step.polymtl.ca>
|
||||
* returns the given "block" to the "system". Blocks are not
|
||||
* free()'d. They are kept in order to be re-allocated by
|
||||
* get_buffer_block().
|
||||
*/
|
||||
void return_buffer_block(struct buffer_block *block)
|
||||
{
|
||||
block->next=avail;
|
||||
avail=block;
|
||||
NB_avail_buffer_blocks++;
|
||||
NB_alloc_buffer_blocks--;
|
||||
}
|
||||
|
||||
/* copy_from_buffer() by SeKs <intru@step.polymtl.ca>
|
||||
* copies characters from the buffer starting at the buffer_block
|
||||
* '*block' into 'string' until a char in 'stop' is encountered or
|
||||
* 'max' bytes are read.
|
||||
* Blocks that are completely copied are returned to the system with
|
||||
* return_buffer_block().
|
||||
* Returns the number of characters that were copied.
|
||||
*/
|
||||
int
|
||||
copy_from_buffer(struct buffer_block **block,char *string,char stop,int max)
|
||||
{
|
||||
register struct buffer_block *tmp;
|
||||
register int count=0;
|
||||
|
||||
if(block==NULL || *block==NULL || string==NULL)
|
||||
return -1;
|
||||
|
||||
while(count<max && *block!=NULL){
|
||||
if((*block)->offset_read == (*block)->offset_write){
|
||||
tmp=*block;
|
||||
*block=(*block)->next;
|
||||
return_buffer_block(tmp);
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
|
||||
*string=(*block)->buf[(*block)->offset_read++];
|
||||
|
||||
if((*block)->offset_read == BUFFER_BLOCK_SIZE){
|
||||
tmp=*block;
|
||||
*block=(*block)->next;
|
||||
return_buffer_block(tmp);
|
||||
}
|
||||
|
||||
string++;
|
||||
if(stop!='\0' && stop==*(string-1))
|
||||
break;
|
||||
}
|
||||
*string='\0';
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
/* look_in_buffer() by SeKs <intru@step.polymtl.ca>
|
||||
* Same as copy_from_buffer() except that the buffer remains unchanged
|
||||
* when the function returns.
|
||||
* ** Added offset counter otherwise offset_read IS changed when returned -DVM
|
||||
*/
|
||||
int
|
||||
look_in_buffer(struct buffer_block **block,char *string,char stop,int max)
|
||||
{
|
||||
register int count=0;
|
||||
register int offset=0; /* added DVM */
|
||||
|
||||
if(block==NULL || *block==NULL || string==NULL)
|
||||
return -1;
|
||||
|
||||
if((*block)->offset_read == (*block)->offset_write){
|
||||
return_buffer_block(*block);
|
||||
*block=NULL;
|
||||
}
|
||||
|
||||
while(count<max && *block!=NULL){
|
||||
if((*block)->offset_read+offset == (*block)->offset_write)
|
||||
break;
|
||||
|
||||
count++;
|
||||
*string=(*block)->buf[(*block)->offset_read+offset];
|
||||
offset++;
|
||||
if((*block)->offset_read+offset == BUFFER_BLOCK_SIZE){
|
||||
block=&(*block)->next;
|
||||
offset=0;
|
||||
}
|
||||
string++;
|
||||
if(stop!='\0' && stop==*(string-1))
|
||||
break;
|
||||
}
|
||||
*string='\0';
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
/* copy_to_buffer() by SeKs <intru@step.polymtl.ca>
|
||||
* adds a string to the specified buffer.
|
||||
* New buffer_blocks are requested when necessary.
|
||||
* Returns the number of characters in the buffer after the
|
||||
* new string is added.
|
||||
* arguments are:
|
||||
* ( struct buffer_block **block, char *format, args... )
|
||||
*/
|
||||
long copy_to_buffer(struct buffer_block **block, char *string,int length)
|
||||
{
|
||||
register long count=0;
|
||||
|
||||
if(block==NULL || length<=0)
|
||||
return -1;
|
||||
|
||||
if(*block==NULL)
|
||||
*block=get_buffer_block();
|
||||
|
||||
while((*block)->next!=NULL){
|
||||
count+=(BUFFER_BLOCK_SIZE)-(*block)->offset_read;
|
||||
block=&(*block)->next;
|
||||
}
|
||||
count+=(*block)->offset_write-(*block)->offset_read;
|
||||
|
||||
while(length--){
|
||||
count++;
|
||||
(*block)->buf[(*block)->offset_write++]=*(string++);
|
||||
if((*block)->offset_write == BUFFER_BLOCK_SIZE){
|
||||
(*block)->offset_write=-1;
|
||||
(*block)->next=get_buffer_block();
|
||||
block=&(*block)->next;
|
||||
if(*block==NULL){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* zap_buffer() by SeKs <intru@step.polymtl.ca>
|
||||
* clears the buffer starting at the buffer_block '*block'
|
||||
* return -1 if block is NULL
|
||||
* 0 otherwise
|
||||
*/
|
||||
int zap_buffer(struct buffer_block **block)
|
||||
{
|
||||
struct buffer_block *tmp;
|
||||
|
||||
if(block==NULL)
|
||||
return -1;
|
||||
|
||||
while((tmp=*block)!=NULL){
|
||||
*block=(*block)->next;
|
||||
return_buffer_block(tmp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* find_char_in_buffer() by SeKs <intru@step.polymtl.ca>
|
||||
* returns 1 if any character of string 'findit' is present within the first
|
||||
* 'max' characters of the buffer.
|
||||
* returns 0 otherwise.
|
||||
*/
|
||||
int find_char_in_buffer(struct buffer_block **block, char findit,int max)
|
||||
{
|
||||
register int offset;
|
||||
register int count=0;
|
||||
|
||||
if( (block == NULL) || (*block == NULL))
|
||||
return 0; /* DVM */
|
||||
|
||||
offset=(*block)->offset_read;
|
||||
loop:
|
||||
if(offset == (*block)->offset_write)
|
||||
return 0;
|
||||
if(findit == (*block)->buf[offset])
|
||||
return 1;
|
||||
if(++count > max)
|
||||
return 0;
|
||||
if(++offset == BUFFER_BLOCK_SIZE){
|
||||
block=&(*block)->next;
|
||||
if(*block == NULL)
|
||||
return 0;
|
||||
offset=0;
|
||||
}
|
||||
goto loop;
|
||||
}
|
||||
|
||||
/* skip_char_in_buffer() by SeKs <intru@step.polymtl.ca>
|
||||
* flushes the first 'n' characters in buffer starting at
|
||||
* buffer_block '*block'
|
||||
*/
|
||||
int skip_char_in_buffer(struct buffer_block **block, int n)
|
||||
{
|
||||
register struct buffer_block *tmp;
|
||||
register int count=0;
|
||||
|
||||
while(count<n){
|
||||
if((*block)->offset_read == (*block)->offset_write){
|
||||
tmp=*block;
|
||||
*block=(*block)->next;
|
||||
return_buffer_block(tmp);
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
(*block)->offset_read++;
|
||||
if((*block)->offset_read == BUFFER_BLOCK_SIZE){
|
||||
tmp=*block;
|
||||
*block=(*block)->next;
|
||||
return_buffer_block(tmp);
|
||||
if(*block==NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
185
Sources/change_byte_order.c
Normal file
185
Sources/change_byte_order.c
Normal file
@@ -0,0 +1,185 @@
|
||||
/* @(#)$Id: change_byte_order.c,v 1.3 1996/11/13 00:40:34 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <netinet/in.h>
|
||||
#include "defines.h"
|
||||
#include "struct.h"
|
||||
#include "version.h"
|
||||
#include "../config.h"
|
||||
|
||||
typedef struct DiskUser {
|
||||
char realname[80];
|
||||
char match[80];
|
||||
int Access;
|
||||
char passwd[20];
|
||||
char channel[80];
|
||||
unsigned long flags;
|
||||
char reserved[20];
|
||||
time_t suspend;
|
||||
time_t lastseen;
|
||||
} DiskUser;
|
||||
|
||||
typedef struct ShitDisk {
|
||||
time_t time;
|
||||
time_t expiration;
|
||||
char match[80];
|
||||
char from[80];
|
||||
char reason[200];
|
||||
char channel[50];
|
||||
int level;
|
||||
} ShitDisk;
|
||||
|
||||
|
||||
void main(void)
|
||||
{
|
||||
FILE *in;
|
||||
FILE *out;
|
||||
DiskUser olduser;
|
||||
DiskUser user;
|
||||
adefchan oldchan;
|
||||
adefchan chan;
|
||||
ShitDisk oldshit,shit;
|
||||
time_t now;
|
||||
char swap, *ptr;
|
||||
|
||||
|
||||
if(chdir(HOMEDIR)<0){
|
||||
perror(HOMEDIR);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
now=time(NULL);
|
||||
|
||||
out=fopen("userlist.dat.new","w");
|
||||
if(out==NULL){
|
||||
perror("userlist.dat.new");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
in=fopen(USERFILE,"r");
|
||||
if(in==NULL){
|
||||
perror(USERFILE);
|
||||
return;
|
||||
}
|
||||
while(fread(&user,sizeof(DiskUser),1,in)>0){
|
||||
ptr=(char *)&user.Access;
|
||||
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
|
||||
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
|
||||
|
||||
ptr=(char *)&user.flags;
|
||||
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
|
||||
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
|
||||
|
||||
ptr=(char *)&user.suspend;
|
||||
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
|
||||
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
|
||||
|
||||
ptr=(char *)&user.lastseen;
|
||||
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
|
||||
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
|
||||
|
||||
fwrite(&user,sizeof(DiskUser),1,out);
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
out=fopen("channellist.dat.new","w");
|
||||
if(out==NULL){
|
||||
perror("channellist.dat.new");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
in=fopen(DEFAULT_CHANNELS_FILE,"r");
|
||||
if(in==NULL){
|
||||
perror(DEFAULT_CHANNELS_FILE);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while(fread(&chan,sizeof(adefchan),1,in)>0){
|
||||
ptr=(char *)&chan.MassDeopPro;
|
||||
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
|
||||
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
|
||||
|
||||
ptr=(char *)&chan.NickFloodPro;
|
||||
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
|
||||
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
|
||||
|
||||
ptr=(char *)&chan.MsgFloodPro;
|
||||
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
|
||||
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
|
||||
|
||||
ptr=(char *)&chan.TS;
|
||||
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
|
||||
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
|
||||
|
||||
ptr=(char *)&chan.flags;
|
||||
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
|
||||
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
|
||||
|
||||
ptr=(char *)&chan.uflags;
|
||||
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
|
||||
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
|
||||
|
||||
fwrite(&chan,sizeof(adefchan),1,out);
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
|
||||
out=fopen("shitlist.dat.new","w");
|
||||
if(out==NULL){
|
||||
perror("shitlist.dat.new");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
in=fopen(SHITLIST_FILE,"r");
|
||||
if(in==NULL){
|
||||
perror(SHITLIST_FILE);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while(fread(&shit,sizeof(ShitDisk),1,in)>0){
|
||||
ptr=(char *)&shit.time;
|
||||
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
|
||||
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
|
||||
|
||||
ptr=(char *)&shit.expiration;
|
||||
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
|
||||
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
|
||||
|
||||
ptr=(char *)&shit.level;
|
||||
swap=ptr[0]; ptr[0]=ptr[3]; ptr[3]=swap;
|
||||
swap=ptr[1]; ptr[1]=ptr[2]; ptr[2]=swap;
|
||||
|
||||
fwrite(&shit,sizeof(ShitDisk),1,out);
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
}
|
||||
1833
Sources/channels.c
Normal file
1833
Sources/channels.c
Normal file
File diff suppressed because it is too large
Load Diff
266
Sources/chat.c
Normal file
266
Sources/chat.c
Normal file
@@ -0,0 +1,266 @@
|
||||
/* @(#)$Id: chat.c,v 1.10 2000/09/09 15:38:13 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
|
||||
#ifdef DOHTTP
|
||||
|
||||
struct chat_user
|
||||
{
|
||||
char user[10];
|
||||
char host[80];
|
||||
aluser *luser;
|
||||
};
|
||||
|
||||
|
||||
void chat_sendtoall(char *from, char *msg)
|
||||
{
|
||||
register http_socket *scan = HttpList;
|
||||
while (scan != NULL)
|
||||
{
|
||||
if (scan->status == HTTP_CHAT && ((struct chat_user *)scan->hook)->luser)
|
||||
{
|
||||
if (from)
|
||||
sendto_http(scan, "<%s> %s\n", from, msg);
|
||||
else
|
||||
sendto_http(scan, "%s\n", msg);
|
||||
}
|
||||
scan = scan->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void login_ok(struct http_socket *hsock, RegUser * reg)
|
||||
{
|
||||
char buffer[512], nick[15];
|
||||
struct chat_user *cu = (struct chat_user *)hsock->hook;
|
||||
register http_socket *scan;
|
||||
int count = 0;
|
||||
|
||||
sprintf(buffer, "1 %ld %s %s %s", now, cu->user + 1, cu->host, VirtualServer.name);
|
||||
|
||||
strcpy(nick, cu->user);
|
||||
|
||||
while (ToLuser(nick) != NULL)
|
||||
sprintf(nick, "+%d%s", ++count, cu->user + 1);
|
||||
|
||||
nick[9] = '\0';
|
||||
onnick(VirtualServer.name, nick, buffer);
|
||||
|
||||
cu->luser = ToLuser(nick);
|
||||
|
||||
cu->luser->valchan = (avalchan *) MALLOC(sizeof(avalchan));
|
||||
cu->luser->valchan->name = (char *)MALLOC(strlen(reg->channel) + 1);
|
||||
strcpy(cu->luser->valchan->name, reg->channel);
|
||||
cu->luser->valchan->reg = reg;
|
||||
reg->inuse++;
|
||||
reg->lastseen = now;
|
||||
reg->modified = 1;
|
||||
cu->luser->valchan->next = NULL;
|
||||
|
||||
sendto_http(hsock, "Welcome to %s's chat line\n", mynick);
|
||||
|
||||
count = 0;
|
||||
sprintf(buffer, "*** Currently on: ");
|
||||
|
||||
for (scan = HttpList; scan != NULL; scan = scan->next)
|
||||
{
|
||||
if (scan->status != HTTP_CHAT || ((struct chat_user *)scan->hook)->luser == NULL)
|
||||
continue;
|
||||
if (strlen(buffer) > 70)
|
||||
{
|
||||
sendto_http(hsock, "%s\n", buffer);
|
||||
sprintf(buffer, "*** ");
|
||||
}
|
||||
strcat(buffer, ((struct chat_user *)scan->hook)->luser->nick + 1);
|
||||
strcat(buffer, " ");
|
||||
}
|
||||
sendto_http(hsock, "%s\n", buffer);
|
||||
|
||||
sprintf(buffer, "*** JOIN: %s@%s", cu->luser->nick + 1, cu->host);
|
||||
chat_sendtoall(NULL, buffer);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
chat_login_callback(int *fd, off_t off, int action, void *hook1, void *hook2,
|
||||
dbuser * dbu, int count)
|
||||
{
|
||||
extern RegUser *load_dbuser(off_t, dbuser *);
|
||||
register RegUser *reg;
|
||||
struct http_socket *hsock = (struct http_socket *)hook1;
|
||||
struct chat_user *cu;
|
||||
char userhost[200];
|
||||
|
||||
if (dbu != NULL)
|
||||
{
|
||||
cu = (struct chat_user *)hsock->hook;
|
||||
reg = load_dbuser(off, dbu);
|
||||
|
||||
sprintf(userhost, "%s!%s@%s", cu->user, cu->user + 1, cu->host);
|
||||
|
||||
if (reg != NULL && *reg->match == '+' && match(userhost, reg->match))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("login_ok: %s %s\n", userhost, reg->match);
|
||||
#endif
|
||||
login_ok(hsock, reg);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendto_http(hsock, "Authentication failed!\n");
|
||||
hsock->status = HTTP_ENDING;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (count == 0)
|
||||
{
|
||||
sendto_http(hsock, "Authentication failed!\n");
|
||||
hsock->status = HTTP_ENDING;
|
||||
hsock->dbio = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void chat_login(struct http_socket *hsock, char *user, char *password)
|
||||
{
|
||||
char userhost[200], channel[] = "*", buffer[200];
|
||||
struct chat_user *cu;
|
||||
register RegUser *ruser;
|
||||
|
||||
cu = (struct chat_user *)malloc(sizeof(struct chat_user));
|
||||
sprintf(buffer, "+%s", user);
|
||||
strncpy(cu->user, buffer, 9);
|
||||
cu->user[9] = '\0';
|
||||
strcpy(cu->host, inet_ntoa(hsock->peer.sin_addr));
|
||||
cu->luser = NULL;
|
||||
hsock->hook = (void *)cu;
|
||||
|
||||
sprintf(userhost, "%s!%s@%s", cu->user, cu->user + 1, cu->host);
|
||||
|
||||
ruser = UserList[ul_hash(channel)];
|
||||
while (ruser != NULL)
|
||||
{
|
||||
if (!strcasecmp(ruser->channel, channel) &&
|
||||
*ruser->match == '+' && match(userhost, ruser->match) &&
|
||||
!strcmp(ruser->passwd, password))
|
||||
break;
|
||||
ruser = ruser->next;
|
||||
}
|
||||
|
||||
if (ruser == NULL)
|
||||
{ /* ok.. not in memory.. send db query */
|
||||
db_fetch(channel, DBGETUHPASS, userhost, password, 0,
|
||||
hsock, NULL, chat_login_callback);
|
||||
hsock->dbio = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("login_ok: %s %s\n", userhost, ruser->match);
|
||||
#endif
|
||||
login_ok(hsock, ruser);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void chat_notice(char *user, char *msg)
|
||||
{
|
||||
register http_socket *scan = HttpList;
|
||||
register struct chat_user *cu;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("chat: ->%s %s\n", user, msg);
|
||||
#endif
|
||||
|
||||
while (scan != NULL)
|
||||
{
|
||||
cu = (struct chat_user *)scan->hook;
|
||||
if (scan->status == HTTP_CHAT && cu->luser &&
|
||||
!strcasecmp(cu->luser->nick, user))
|
||||
{
|
||||
sendto_http(scan, "-%s- %s\n", mynick, msg);
|
||||
break;
|
||||
}
|
||||
scan = scan->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void parse_chat(struct http_socket *hsock, char *line)
|
||||
{
|
||||
char buffer[200], global[] = "*", *ptr;
|
||||
|
||||
if (hsock == NULL || hsock->hook == NULL ||
|
||||
((struct chat_user *)hsock->hook)->luser == NULL)
|
||||
return;
|
||||
|
||||
if ((ptr = strpbrk(line, "\r\n")) != NULL)
|
||||
*ptr = '\0';
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("chat: <%s> %s\n", ((struct chat_user *)hsock->hook)->luser->nick + 1, line);
|
||||
#endif
|
||||
|
||||
if ((*line == '/') || (*line == '.'))
|
||||
{
|
||||
sprintf(buffer, "%s@%s", mynick, SERVERNAME);
|
||||
parse_command(((struct chat_user *)hsock->hook)->luser->nick,
|
||||
buffer, global, line + 1);
|
||||
}
|
||||
else
|
||||
chat_sendtoall(((struct chat_user *)hsock->hook)->luser->nick + 1, line);
|
||||
}
|
||||
|
||||
|
||||
void chat_close(http_socket * hsock, char *comment)
|
||||
{
|
||||
char buffer[512];
|
||||
struct chat_user *cu = (struct chat_user *)hsock->hook;
|
||||
|
||||
if (cu->luser)
|
||||
{
|
||||
sprintf(buffer, "*** LEAVE: %s@%s", cu->luser->nick + 1, cu->host);
|
||||
chat_sendtoall(NULL, buffer);
|
||||
onquit(cu->luser->nick);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DccMe(char *source, char *arg)
|
||||
{
|
||||
char global[] = "*", buffer[512];
|
||||
if(Access(global, source) >= 600)
|
||||
{
|
||||
unsigned long addr = inet_addr(BINDADDR);
|
||||
addr = ntohl(addr);
|
||||
sprintf(buffer, ":%s PRIVMSG %s :\001DCC CHAT chat %u %u\001\n",
|
||||
mynick, source, addr, HTTP_PORT);
|
||||
sendtoserv(buffer);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
100
Sources/cksum.c
Normal file
100
Sources/cksum.c
Normal file
@@ -0,0 +1,100 @@
|
||||
/* $Id: cksum.c,v 1.1 1997/06/30 03:48:05 cvs Exp $
|
||||
*/
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
void cksum(char *file, unsigned int *sum1, unsigned int *sum2)
|
||||
{
|
||||
int fd=-1, size;
|
||||
unsigned char buffer[1024];
|
||||
|
||||
if(strchr(file,'/') != NULL)
|
||||
{
|
||||
fd = open(file,O_RDONLY);
|
||||
}
|
||||
else /* check path */
|
||||
{
|
||||
char *tok,*path = getenv("PATH");
|
||||
if(path == NULL)
|
||||
return;
|
||||
for(tok=strtok(path,":"); tok!=NULL; tok=strtok(NULL,":"))/* mangles PATH*/
|
||||
{
|
||||
strncpy(buffer,tok,1023);
|
||||
strncat(buffer,"/",1023);
|
||||
strncat(buffer,file,1023);
|
||||
buffer[1023] = '\0';
|
||||
fd = open(buffer,O_RDONLY);
|
||||
if(fd >= 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(fd<0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
*sum1 = *sum2 = 0;
|
||||
|
||||
while((size=read(fd,buffer,1023))>0)
|
||||
{
|
||||
while(size--)
|
||||
{
|
||||
*sum1 += buffer[size];
|
||||
*sum2 += (size&1)?-buffer[size]:buffer[size];
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
|
||||
#ifdef MAIN
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
unsigned int sum,pro;
|
||||
|
||||
if(argc != 2)
|
||||
{
|
||||
fprintf(stderr,"usage: %s file\n",argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cksum(argv[1],&sum,&pro);
|
||||
printf("-DBINCKSUM1=0x%x -DBINCKSUM2=0x%x\n",sum,pro);
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
241
Sources/conf.c
Normal file
241
Sources/conf.c
Normal file
@@ -0,0 +1,241 @@
|
||||
/* @(#)$Id: conf.c,v 1.5 1998/01/22 09:36:11 chaos Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
|
||||
void read_conf(char *conf)
|
||||
{
|
||||
FILE *fp;
|
||||
char buffer[1024], *ptr;
|
||||
|
||||
fp = fopen(conf, "r");
|
||||
if (fp == NULL)
|
||||
{
|
||||
perror(conf);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (fgets(buffer, 1024, fp) != NULL)
|
||||
{
|
||||
if (*buffer == '#' || *buffer == '\0')
|
||||
continue;
|
||||
if ((ptr = strchr(buffer, '\n')) != NULL)
|
||||
*ptr = '\0';
|
||||
|
||||
if (!strncasecmp(buffer, "NICKNAME ", 9))
|
||||
{
|
||||
strncpy(mynick, buffer + 9, NICK_LENGTH);
|
||||
mynick[NICK_LENGTH - 1] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "USERNAME ", 9))
|
||||
{
|
||||
strncpy(myuser, buffer + 9, USERNAME_LENGTH);
|
||||
myuser[USERNAME_LENGTH - 1] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "HOSTNAME ", 9))
|
||||
{
|
||||
strncpy(mysite, buffer + 9, SITE_LENGTH);
|
||||
mysite[SITE_LENGTH - 1] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "REALNAME ", 9))
|
||||
{
|
||||
strncpy(myrealname, buffer + 9, REALNAME_LENGTH);
|
||||
myrealname[REALNAME_LENGTH - 1] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "UPLINK ", 7))
|
||||
{
|
||||
strncpy(server, buffer + 7, SERVER_NAME_LENGTH);
|
||||
server[SERVER_NAME_LENGTH - 1] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "PORT ", 5))
|
||||
{
|
||||
DEFAULT_PORTNUM = atoi(buffer + 5);
|
||||
}
|
||||
else if (!strncasecmp(buffer, "UMODE ", 6))
|
||||
{
|
||||
strncpy(UMODE, buffer + 6, 10);
|
||||
UMODE[9] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "SERVERNAME ", 11))
|
||||
{
|
||||
strncpy(SERVERNAME, buffer + 11, 80);
|
||||
SERVERNAME[79] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "SERVERINFO ", 11))
|
||||
{
|
||||
strncpy(SERVERINFO, buffer + 11, 80);
|
||||
SERVERINFO[79] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "PASSWORD ", 9))
|
||||
{
|
||||
strncpy(PASSWORD, buffer + 9, 80);
|
||||
PASSWORD[79] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "HOMEDIR ", 8))
|
||||
{
|
||||
strncpy(HOMEDIR, buffer + 8, 256);
|
||||
HOMEDIR[255] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "UMASK ", 6))
|
||||
{
|
||||
sscanf(buffer + 6, "%d", &UMASK);
|
||||
}
|
||||
else if (!strncasecmp(buffer, "EXEC ", 5))
|
||||
{
|
||||
strncpy(EXEC_FILE, buffer + 5, 256);
|
||||
EXEC_FILE[255] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "MOTD ", 5))
|
||||
{
|
||||
strncpy(MOTD_FILE, buffer + 5, 256);
|
||||
MOTD_FILE[255] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "LOG ", 4))
|
||||
{
|
||||
strncpy(LOGFILE, buffer + 4, 256);
|
||||
LOGFILE[255] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "LOGBAK ", 7))
|
||||
{
|
||||
strncpy(LOGFILEBAK, buffer + 7, 256);
|
||||
LOGFILEBAK[255] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "PID ", 4))
|
||||
{
|
||||
strncpy(PIDFILE, buffer + 4, 256);
|
||||
PIDFILE[255] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "HELPDIR ", 8))
|
||||
{
|
||||
strncpy(HELP_DIR, buffer + 8, 256);
|
||||
HELP_DIR[255] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "MASTER_NICK ", 12))
|
||||
{
|
||||
strncpy(MASTER_REALNAME, buffer + 12, 80);
|
||||
MASTER_REALNAME[79] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "MASTER_MASK ", 12))
|
||||
{
|
||||
strncpy(MASTER_MATCH, buffer + 12, 80);
|
||||
MASTER_MATCH[79] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "MASTER_PASSWD ", 14))
|
||||
{
|
||||
strncpy(MASTER_PASSWD, buffer + 14, 20);
|
||||
MASTER_PASSWD[19] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "BROADCAST ", 10))
|
||||
{
|
||||
strncpy(BROADCAST_CHANNEL, buffer + 10, 80);
|
||||
BROADCAST_CHANNEL[79] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "VERIFYID ", 9))
|
||||
{
|
||||
strncpy(VERIFY_ID, buffer + 9, 256);
|
||||
VERIFY_ID[255] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "UWORLD_NICK ", 12))
|
||||
{
|
||||
strncpy(UWORLD, buffer + 12, 10);
|
||||
UWORLD[9] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "UWORLD_HOST ", 12))
|
||||
{
|
||||
strncpy(UWORLD_HOST, buffer + 12, 80);
|
||||
UWORLD_HOST[79] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "UWORLD_SERVER ", 14))
|
||||
{
|
||||
strncpy(UWORLD_SERVER, buffer + 14, 80);
|
||||
UWORLD_SERVER[79] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "UWORLD2_NICK ", 13))
|
||||
{
|
||||
strncpy(UWORLD2_NICK, buffer + 13, 10);
|
||||
UWORLD2_NICK[9] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "UWORLD2_HOST ", 13))
|
||||
{
|
||||
strncpy(UWORLD2_HOST, buffer + 13, 80);
|
||||
UWORLD2_HOST[79] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "UWORLD2_SERVER ", 15))
|
||||
{
|
||||
strncpy(UWORLD2_SERVER, buffer + 15, 80);
|
||||
UWORLD2_SERVER[79] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "CALMDOWNTOPIC ", 14))
|
||||
{
|
||||
strncpy(CALMDOWNTOPIC, buffer + 14, 512);
|
||||
CALMDOWNTOPIC[511] = '\0';
|
||||
}
|
||||
else if (!strncasecmp(buffer, "NSERV_NICK ", 11))
|
||||
{
|
||||
#ifdef NICKSERV
|
||||
strncpy(NSERV_NICK, buffer + 11, 10);
|
||||
NSERV_NICK[9] = '\0';
|
||||
#endif
|
||||
}
|
||||
else if (!strncasecmp(buffer, "NSERV_USER ", 11))
|
||||
{
|
||||
#ifdef NICKSERV
|
||||
strncpy(NSERV_USER, buffer + 11, 10);
|
||||
NSERV_USER[9] = '\0';
|
||||
#endif
|
||||
}
|
||||
else if (!strncasecmp(buffer, "NSERV_HOST ", 11))
|
||||
{
|
||||
#ifdef NICKSERV
|
||||
strncpy(NSERV_HOST, buffer + 11, 80);
|
||||
NSERV_HOST[79] = '\0';
|
||||
#endif
|
||||
}
|
||||
else if (!strncasecmp(buffer, "NSERV_INFO ", 11))
|
||||
{
|
||||
#ifdef NICKSERV
|
||||
strncpy(NSERV_INFO, buffer + 11, 200);
|
||||
NSERV_INFO[199] = '\0';
|
||||
#endif
|
||||
}
|
||||
else if (!strncasecmp(buffer, "NSERV_STAT ", 11))
|
||||
{
|
||||
#ifdef NICKSERV
|
||||
if (!strncmp(buffer + 11, "on", 2))
|
||||
NServ_status = 1;
|
||||
else if (!strncmp(buffer + 11, "off", 3))
|
||||
NServ_status = 0;
|
||||
else
|
||||
fprintf(stderr, "NSERV_STAT: Unknown value. Must be ON or OFF\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "%s: Unknown keyword \"%s\"\n", conf, buffer);
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
696
Sources/connect.c
Normal file
696
Sources/connect.c
Normal file
@@ -0,0 +1,696 @@
|
||||
/* @(#)$Id: connect.c,v 1.12 1998/01/25 18:35:42 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
#ifndef FD_ZERO
|
||||
#define FD_ZERO(set) (((set)->fds_bits[0]) = 0)
|
||||
#define FD_SET(s1, set) (((set)->fds_bits[0]) |= 1 << (s1))
|
||||
#define FD_ISSET(s1, set) (((set)->fds_bits[0]) & (1 << (s1)))
|
||||
#define FD_SETSIZE 30
|
||||
#endif
|
||||
|
||||
int read_from_server(int);
|
||||
int write_to_server(irc_socket *);
|
||||
|
||||
int connection(char *serv)
|
||||
{
|
||||
char buffer[200];
|
||||
int portnum;
|
||||
char *ptr;
|
||||
struct sockaddr_in socketname;
|
||||
#ifdef BINDADDR
|
||||
struct sockaddr_in myname;
|
||||
#endif
|
||||
struct hostent *remote_host;
|
||||
|
||||
if ((ptr = strchr(serv, ':')) != NULL)
|
||||
{
|
||||
*(ptr++) = 0;
|
||||
sscanf(ptr, "%d", &portnum);
|
||||
#ifdef DEBUG
|
||||
printf("Server: %s\nPort: %d\n", serv, portnum);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
portnum = DEFAULT_PORTNUM;
|
||||
}
|
||||
|
||||
sprintf(buffer, "CONNECTING TO %s ON PORT %d", serv, portnum);
|
||||
log(buffer);
|
||||
|
||||
if (Irc.outbuf)
|
||||
zap_buffer(&Irc.outbuf);
|
||||
if (Irc.inbuf)
|
||||
zap_buffer(&Irc.inbuf);
|
||||
read_from_server(1); /* reset input buffer */
|
||||
|
||||
now = time(NULL);
|
||||
|
||||
/* open an inet socket */
|
||||
if ((Irc.fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "ERROR: Can't assign fd for socket, darn!\n");
|
||||
#endif
|
||||
log("ERROR ASSIGNING FD FOR SOCKET");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef BINDADDR
|
||||
memset(&myname, 0, sizeof(myname));
|
||||
myname.sin_family = AF_INET;
|
||||
myname.sin_port = 0;
|
||||
myname.sin_addr.s_addr = inet_addr(BINDADDR);
|
||||
if (bind(Irc.fd, (struct sockaddr *)&myname, sizeof(myname)) < 0)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "ERROR: Can't bind local address %s\n", BINDADDR);
|
||||
#endif
|
||||
log("Can't bind local address");
|
||||
log(BINDADDR);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* make it non-blocking */
|
||||
fcntl(Irc.fd, F_SETFL, O_NONBLOCK);
|
||||
|
||||
/* lookup host */
|
||||
socketname.sin_family = AF_INET;
|
||||
if ((remote_host = gethostbyname(serv)) == NULL)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "ERROR: Host %s is unknown, wtf?\n", serv);
|
||||
#endif
|
||||
log("ERROR: BULLSHIT HOST!");
|
||||
exit(1);
|
||||
}
|
||||
memcpy((void *)&socketname.sin_addr, (void *)remote_host->h_addr, remote_host->h_length);
|
||||
socketname.sin_port = htons(portnum);
|
||||
|
||||
/* connect socket */
|
||||
if (connect(Irc.fd, (struct sockaddr *)&socketname, sizeof(socketname)) < 0
|
||||
&& errno != EINPROGRESS)
|
||||
{
|
||||
close(Irc.fd);
|
||||
Irc.fd = -1;
|
||||
#ifdef DEBUG
|
||||
printf("ERROR: connect() %d: %s\n", errno, strerror(errno));
|
||||
#endif
|
||||
log("ERROR: COULDN'T CONNECT");
|
||||
return (1);
|
||||
}
|
||||
TSconnect = Irc.TS = now = time(NULL);
|
||||
errno = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wait_msg(void)
|
||||
{
|
||||
fd_set readfds, writefds;
|
||||
struct timeval timeout;
|
||||
static int pingflag = 0;
|
||||
int maxfd = -1;
|
||||
int to;
|
||||
#ifdef DOHTTP
|
||||
void http_log(char *fmt,...);
|
||||
register http_socket *hsock, *hsocktmp;
|
||||
register http_file_pipe *fpipe, *fpipetmp;
|
||||
#endif
|
||||
#ifdef UPGRADE
|
||||
register misc_socket *msock, *msocktmp;
|
||||
#endif
|
||||
register dbquery **dq, *dqtmp;
|
||||
register dbsync **ds, *dstmp;
|
||||
|
||||
/* initialize the fd_sets
|
||||
*/
|
||||
FD_ZERO(&readfds);
|
||||
FD_ZERO(&writefds);
|
||||
|
||||
/* set timeout
|
||||
*/
|
||||
if (EventList != NULL)
|
||||
{
|
||||
to = EventList->time - now;
|
||||
if (to < PING_FREQ)
|
||||
timeout.tv_sec = (to > 0) ? to : 0;
|
||||
else
|
||||
timeout.tv_sec = PING_FREQ;
|
||||
}
|
||||
else
|
||||
{
|
||||
timeout.tv_sec = PING_FREQ;
|
||||
}
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
/* Check the DBQuery list before the server fd because
|
||||
* end_db_read() might writing something in the server's
|
||||
* buffer.
|
||||
*/
|
||||
dq = &DBQuery;
|
||||
while (*dq)
|
||||
{
|
||||
if ((*dq)->fd < 0)
|
||||
{
|
||||
dqtmp = *dq;
|
||||
*dq = (*dq)->next;
|
||||
end_db_read(dqtmp);
|
||||
free(dqtmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((*dq)->fd > maxfd)
|
||||
maxfd = (*dq)->fd;
|
||||
FD_SET((*dq)->fd, &readfds);
|
||||
dq = &(*dq)->next;
|
||||
}
|
||||
}
|
||||
|
||||
ds = &DBSync;
|
||||
while (*ds)
|
||||
{
|
||||
if ((*ds)->fd < 0)
|
||||
{
|
||||
dstmp = *ds;
|
||||
*ds = (*ds)->next;
|
||||
end_db_sync(dstmp);
|
||||
free(dstmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((*ds)->fd > maxfd)
|
||||
maxfd = (*ds)->fd;
|
||||
if ((*ds)->status == SYNC_PENDWRITE)
|
||||
FD_SET((*ds)->fd, &writefds);
|
||||
else
|
||||
FD_SET((*ds)->fd, &readfds);
|
||||
ds = &(*ds)->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* check if the uplink's socket is ready for reading..
|
||||
*/
|
||||
FD_SET(Irc.fd, &readfds);
|
||||
|
||||
/* check if the uplink's socket is ready for writing only if
|
||||
* we have something to write
|
||||
*/
|
||||
if (Irc.outbuf != NULL)
|
||||
FD_SET(Irc.fd, &writefds);
|
||||
|
||||
if (Irc.fd > maxfd)
|
||||
maxfd = Irc.fd;
|
||||
|
||||
#ifdef DOHTTP
|
||||
fpipe = FilePipes;
|
||||
while (fpipe != NULL)
|
||||
{
|
||||
if (fpipe->fd > maxfd)
|
||||
maxfd = fpipe->fd;
|
||||
|
||||
FD_SET(fpipe->fd, &readfds);
|
||||
fpipe = fpipe->next;
|
||||
}
|
||||
|
||||
hsock = HttpList;
|
||||
while (hsock != NULL)
|
||||
{
|
||||
if (hsock->fd < 0 || hsock->status == HTTP_ERROR)
|
||||
{
|
||||
hsock = hsock->next; /* am I an idiot or what? -Kev */
|
||||
continue; /* you should see the logs from below! -Kev */
|
||||
}
|
||||
if (hsock->fd > maxfd)
|
||||
maxfd = hsock->fd;
|
||||
if (hsock->status != HTTP_LISTEN &&
|
||||
hsock->status != HTTP_CHAT &&
|
||||
hsock->since + 2 * HTTP_TIMEOUT < now)
|
||||
{
|
||||
http_log("ERROR: absolute timeout for fd %d (%d)",
|
||||
hsock->fd, hsock->status);
|
||||
close(hsock->fd);
|
||||
hsock->fd = -1;
|
||||
hsock->status = HTTP_ERROR;
|
||||
}
|
||||
if (hsock->status != HTTP_LISTEN &&
|
||||
hsock->status != HTTP_CHAT &&
|
||||
hsock->TS + HTTP_TIMEOUT < now)
|
||||
{
|
||||
close(hsock->fd);
|
||||
hsock->fd = -1;
|
||||
hsock->status = HTTP_ERROR;
|
||||
}
|
||||
if (hsock->status == HTTP_ENDING &&
|
||||
hsock->outbuf == NULL)
|
||||
{
|
||||
close(hsock->fd);
|
||||
hsock->fd = -1;
|
||||
hsock->status = HTTP_ERROR;
|
||||
}
|
||||
if (hsock->status != HTTP_ERROR)
|
||||
{
|
||||
if (hsock->status != HTTP_ENDING &&
|
||||
hsock->status != HTTP_PIPE)
|
||||
FD_SET(hsock->fd, &readfds);
|
||||
if (hsock->outbuf != NULL)
|
||||
FD_SET(hsock->fd, &writefds);
|
||||
}
|
||||
hsock = hsock->next;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UPGRADE
|
||||
msock = MiscList;
|
||||
while (msock != NULL)
|
||||
{
|
||||
if (msock->fd > maxfd)
|
||||
maxfd = msock->fd;
|
||||
if (msock->TS + MISC_TIMEOUT < now)
|
||||
{
|
||||
close(msock->fd);
|
||||
msock->fd = -1;
|
||||
msock->status = MISC_ERROR;
|
||||
notice(msock->link, "connection timeout!");
|
||||
}
|
||||
if (msock->status != MISC_ERROR)
|
||||
{
|
||||
FD_SET(msock->fd, &readfds);
|
||||
if (msock->outbuf != NULL)
|
||||
FD_SET(msock->fd, &writefds);
|
||||
}
|
||||
msock = msock->next;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Wait till the socket is ready for reading
|
||||
* and/or writing and/or a timeout
|
||||
*/
|
||||
if (select(maxfd + 1, &readfds, &writefds, NULL, &timeout) < 0)
|
||||
{
|
||||
log("ERROR: select()");
|
||||
log((char *)sys_errlist[errno]);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
now = time(NULL);
|
||||
|
||||
/* The uplink's socket is ready for reading... */
|
||||
if (FD_ISSET(Irc.fd, &readfds))
|
||||
{
|
||||
if (read_from_server(0) < 0)
|
||||
{
|
||||
log("ERROR: in read_from_server()");
|
||||
return (-1);
|
||||
}
|
||||
pingflag = 0;
|
||||
Irc.TS = now;
|
||||
}
|
||||
|
||||
/* The uplink's socket is ready for writing... */
|
||||
if (FD_ISSET(Irc.fd, &writefds))
|
||||
{
|
||||
if (write_to_server(&Irc) < 0)
|
||||
{
|
||||
log("ERROR: in write_to_server()");
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DOHTTP
|
||||
fpipe = FilePipes;
|
||||
while (fpipe != NULL)
|
||||
{
|
||||
fpipetmp = fpipe;
|
||||
fpipe = fpipe->next;
|
||||
if (FD_ISSET(fpipetmp->fd, &readfds))
|
||||
{
|
||||
readfrom_file(fpipetmp);
|
||||
}
|
||||
}
|
||||
|
||||
hsock = HttpList;
|
||||
while (hsock != NULL)
|
||||
{
|
||||
while (hsock != NULL && hsock->status == HTTP_ERROR)
|
||||
{
|
||||
hsocktmp = hsock;
|
||||
hsock = hsock->next;
|
||||
remove_httpsock(hsocktmp);
|
||||
}
|
||||
if (hsock == NULL)
|
||||
break;
|
||||
|
||||
if (hsock->fd >= 0 && FD_ISSET(hsock->fd, &readfds))
|
||||
{
|
||||
if (hsock->status == HTTP_LISTEN)
|
||||
{
|
||||
http_accept(hsock->fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
readfrom_http(hsock);
|
||||
hsock->TS = now;
|
||||
}
|
||||
}
|
||||
if (hsock->fd >= 0 && FD_ISSET(hsock->fd, &writefds))
|
||||
{
|
||||
if (flush_http_buffer(hsock) != -1)
|
||||
hsock->TS = now;
|
||||
if (hsock->status == HTTP_ENDING && hsock->outbuf == NULL)
|
||||
{
|
||||
close(hsock->fd);
|
||||
hsock->fd = -1;
|
||||
hsock->status = HTTP_ERROR;
|
||||
}
|
||||
}
|
||||
hsock = hsock->next;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UPGRADE
|
||||
msocktmp = NULL;
|
||||
msock = MiscList;
|
||||
while (msock != NULL)
|
||||
{
|
||||
while (msock != NULL && msock->status == MISC_ERROR)
|
||||
{
|
||||
if (msocktmp == NULL)
|
||||
{
|
||||
MiscList = msock->next;
|
||||
free(msock);
|
||||
msock = MiscList;
|
||||
}
|
||||
else
|
||||
{
|
||||
msocktmp->next = msock->next;
|
||||
free(msock);
|
||||
msock = msocktmp->next;
|
||||
}
|
||||
}
|
||||
if (msock == NULL)
|
||||
break;
|
||||
|
||||
if (msock->fd >= 0 && FD_ISSET(msock->fd, &readfds))
|
||||
{
|
||||
readfrom_misc(msock);
|
||||
msock->TS = now;
|
||||
}
|
||||
if (msock->fd >= 0 && FD_ISSET(msock->fd, &writefds))
|
||||
{
|
||||
if (flush_misc_buffer(msock) != -1)
|
||||
msock->TS = now;
|
||||
}
|
||||
msocktmp = msock;
|
||||
msock = msock->next;
|
||||
}
|
||||
#endif
|
||||
|
||||
dqtmp = DBQuery;
|
||||
while (dqtmp)
|
||||
{
|
||||
if (FD_ISSET(dqtmp->fd, &readfds))
|
||||
read_db(dqtmp);
|
||||
dqtmp = dqtmp->next;
|
||||
}
|
||||
|
||||
dstmp = DBSync;
|
||||
while (dstmp)
|
||||
{
|
||||
if (FD_ISSET(dstmp->fd, &readfds) || FD_ISSET(dstmp->fd, &writefds))
|
||||
db_sync_ready(dstmp);
|
||||
dstmp = dstmp->next;
|
||||
}
|
||||
|
||||
if (EventList != NULL && now >= EventList->time)
|
||||
CheckEvent();
|
||||
|
||||
/* send a PING to the server if nothing is received within
|
||||
* PING_FREQ seconds... if yet nothing arrives within 3 * PING_FREQ
|
||||
* seconds it's a ping timeout and the connection should be closed
|
||||
*/
|
||||
if ((now - Irc.TS) >= (3 * PING_FREQ + 1))
|
||||
{
|
||||
log("Errr PING TIMEOUT");
|
||||
#ifdef DEBUG
|
||||
printf("Ping timeout..\n");
|
||||
#endif
|
||||
sendtoserv("ERROR :Connection timeout\n");
|
||||
return (-1);
|
||||
}
|
||||
else if (pingflag == 0 && (now - Irc.TS) >= (PING_FREQ - 1))
|
||||
{
|
||||
sendtoserv("PING :");
|
||||
sendtoserv(SERVERNAME);
|
||||
sendtoserv("\n");
|
||||
pingflag = 1;
|
||||
}
|
||||
|
||||
if (DB_Save_Status != -1)
|
||||
do_cold_sync_slice();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sendtoserv(char *msg)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("#OUT#%s", msg);
|
||||
#endif
|
||||
CurrentSendQ = copy_to_buffer(&Irc.outbuf, msg, strlen(msg));
|
||||
|
||||
if (CurrentSendQ > MAX_SENDQ)
|
||||
{
|
||||
log("ERROR: Reached MAX_SENDQ!!!");
|
||||
zap_buffer(&Irc.outbuf);
|
||||
close(Irc.fd);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void dumpbuff(void)
|
||||
{
|
||||
if (Irc.fd < 0)
|
||||
return;
|
||||
|
||||
/* remove the O_NONBLOCK flag */
|
||||
fcntl(Irc.fd, F_SETFL, 0);
|
||||
|
||||
write_to_server(&Irc);
|
||||
|
||||
if (Irc.fd >= 0)
|
||||
/* reset the O_NONBLOCK flag */
|
||||
fcntl(Irc.fd, F_SETFL, O_NONBLOCK);
|
||||
}
|
||||
|
||||
int read_from_server(int reset)
|
||||
{
|
||||
static char inbuff[1025] = "";
|
||||
static char source[SERVER_NAME_LENGTH] = "";
|
||||
static char function[10] = "";
|
||||
static char target[513] = "";
|
||||
static char body[513] = "";
|
||||
|
||||
static int in_pos = 0;
|
||||
static int in_offset = 0;
|
||||
static int length = 0;
|
||||
char *inchar;
|
||||
int end;
|
||||
#ifdef HISTORY
|
||||
char buffer[600];
|
||||
#endif
|
||||
|
||||
if (reset)
|
||||
{
|
||||
*inbuff = *source = *function = *target = *body = '\0';
|
||||
in_pos = in_offset = length = 0;
|
||||
return 0;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("#IN#");
|
||||
#endif
|
||||
end = 1;
|
||||
while (end > 0)
|
||||
{
|
||||
errno = 0;
|
||||
if ((length = read(Irc.fd, inbuff, 1024)) <= 0)
|
||||
{
|
||||
if (errno == EWOULDBLOCK || errno == EAGAIN || length == 0)
|
||||
{
|
||||
end = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
end = -1;
|
||||
in_pos = in_offset = 0;
|
||||
*source = *function = *target = *body = '\0';
|
||||
#ifdef DEBUG
|
||||
printf("Read error.. not EWOULDBLOCK!\n");
|
||||
#endif
|
||||
}
|
||||
return (end);
|
||||
}
|
||||
TTLREADBYTES += length;
|
||||
|
||||
inchar = inbuff;
|
||||
while (length--)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
putchar(*inchar);
|
||||
#endif
|
||||
if (*inchar != '\n' && *inchar != '\r')
|
||||
{
|
||||
if (*inchar == ' ' && in_pos < 3)
|
||||
{
|
||||
switch (in_pos)
|
||||
{
|
||||
case 0:
|
||||
source[in_offset] = '\0';
|
||||
break;
|
||||
|
||||
case 1:
|
||||
function[in_offset] = '\0';
|
||||
break;
|
||||
|
||||
case 2:
|
||||
target[in_offset] = '\0';
|
||||
break;
|
||||
|
||||
default:
|
||||
exit(1);
|
||||
}
|
||||
in_pos++;
|
||||
in_offset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (in_pos)
|
||||
{
|
||||
case 0:
|
||||
if (in_offset == 0 && *inchar != ':')
|
||||
{
|
||||
source[0] = '\0';
|
||||
in_pos++;
|
||||
function[in_offset++] = *inchar;
|
||||
}
|
||||
else
|
||||
source[in_offset++] = *inchar;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
function[in_offset++] = *inchar;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
target[in_offset++] = *inchar;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
body[in_offset++] = *inchar;
|
||||
break;
|
||||
|
||||
default: /*shouldn't happen */
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (*inchar == '\n')
|
||||
{
|
||||
if (in_pos >= 3)
|
||||
body[in_offset] = '\0';
|
||||
else
|
||||
{
|
||||
body[0] = '\0';
|
||||
switch (in_pos)
|
||||
{
|
||||
case 2:
|
||||
target[in_offset] = '\0';
|
||||
break;
|
||||
|
||||
case 1:
|
||||
function[in_offset] = '\0';
|
||||
break;
|
||||
|
||||
case 0:
|
||||
source[in_offset] = '\0';
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* parse the received line */
|
||||
#ifdef HISTORY
|
||||
sprintf(buffer, "%s %s %s %s", source, function, target, body);
|
||||
History(buffer);
|
||||
#endif
|
||||
proc(source, function, target, body);
|
||||
in_pos = in_offset = end = 0;
|
||||
*source = *function = *target = *body = '\0';
|
||||
}
|
||||
inchar++;
|
||||
} /* while */
|
||||
} /*while */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int write_to_server(irc_socket * isock)
|
||||
{
|
||||
char buf[1024];
|
||||
int length;
|
||||
int count;
|
||||
|
||||
if (isock == NULL || isock->outbuf == NULL)
|
||||
return -1;
|
||||
|
||||
while ((count = look_in_buffer(&isock->outbuf, buf, '\0', 1023)) > 0)
|
||||
{
|
||||
if ((length = write(isock->fd, buf, count)) <= 0)
|
||||
{
|
||||
if (errno == EWOULDBLOCK || errno == EAGAIN)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
close(isock->fd);
|
||||
isock->fd = -1;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TTLSENTBYTES += length;
|
||||
CurrentSendQ -= length;
|
||||
skip_char_in_buffer(&isock->outbuf, length);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
755
Sources/dbio.c
Normal file
755
Sources/dbio.c
Normal file
@@ -0,0 +1,755 @@
|
||||
/* @(#)$Id: dbio.c,v 1.12 1998/01/02 18:30:08 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
|
||||
|
||||
char *make_dbfname(char *channel)
|
||||
{
|
||||
static char fname[600];
|
||||
char tmp[600];
|
||||
register char *ptr;
|
||||
|
||||
strcpy(tmp, channel);
|
||||
for (ptr = tmp; *ptr; ptr++)
|
||||
{
|
||||
if (*ptr == '/')
|
||||
*ptr = ' ';
|
||||
else
|
||||
*ptr = tolower(*ptr);
|
||||
}
|
||||
|
||||
sprintf(fname, "db/channels/%04X/%s", ul_hash(channel), tmp);
|
||||
return fname;
|
||||
}
|
||||
|
||||
|
||||
/* db_query()
|
||||
* This is used to *retreive* information from the database.
|
||||
* The arguments are:
|
||||
* channel := channel name (null terminated string)
|
||||
* type := query type, either of:
|
||||
* DBGETNICK (Get entry by nick)
|
||||
* DBGET1STUH (Get first matching userhost)
|
||||
* DBGETALLUH (Get all matching userhosts)
|
||||
* DBCOUNTUH (Count the number of matching userhosts)
|
||||
* ...
|
||||
* info := Either a nick or a userhost depending on type
|
||||
* action := value passed to the callback function
|
||||
* hook1 := pointer passed to the callback function
|
||||
* hook2 := pointer passed to the callback function
|
||||
* callback := callback function
|
||||
*
|
||||
* Since the database is accessed asychronously, 'hook' should not point to
|
||||
* a structure that can be free()'d by a function other than callback,
|
||||
* e.g. a pointer to a luser structure.
|
||||
*/
|
||||
int db_fetch(char *channel, unsigned int type, char *info, char *passwd,
|
||||
int action, void *hook1, void *hook2, DBCALLBACK(callback))
|
||||
{
|
||||
dbquery *new;
|
||||
int fd;
|
||||
|
||||
if ((fd = open(make_dbfname(channel), O_RDONLY | O_NONBLOCK)) < 0)
|
||||
{
|
||||
callback(&fd, (off_t) 0, action, hook1, hook2, NULL, 0);
|
||||
return -1; /* caller can check errno to see want happened */
|
||||
}
|
||||
|
||||
new = (dbquery *) malloc(sizeof(dbquery));
|
||||
new->fd = fd;
|
||||
new->offset = (off_t) 0;
|
||||
new->time = now;
|
||||
new->type = type;
|
||||
new->action = action;
|
||||
new->count = 0;
|
||||
new->callback = callback;
|
||||
new->buf = NULL;
|
||||
new->hook1 = hook1;
|
||||
new->hook2 = hook2;
|
||||
strcpy(new->info, info);
|
||||
strncpy(new->channel, channel, 79);
|
||||
new->channel[79] = '\0';
|
||||
if (passwd)
|
||||
strcpy(new->passwd, passwd);
|
||||
else
|
||||
new->passwd[0] = '\0';
|
||||
new->next = DBQuery;
|
||||
DBQuery = new;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* fix_db()
|
||||
* Remove db entries that are not in the right file.
|
||||
*/
|
||||
static void fix_db(char *channel, off_t offset)
|
||||
{
|
||||
register RegUser *reg;
|
||||
register int idx;
|
||||
|
||||
idx = ul_hash(channel);
|
||||
/* check if already taken care of */
|
||||
reg = UserList[idx];
|
||||
while (reg != NULL && (reg->offset != offset || strcasecmp(reg->channel, channel)))
|
||||
reg = reg->next;
|
||||
|
||||
if (reg) /* already there.. disregard */
|
||||
return;
|
||||
|
||||
reg = (RegUser *) MALLOC(sizeof(RegUser));
|
||||
memset(reg, 0, sizeof(RegUser));
|
||||
reg->realname = (char *)MALLOC(6);
|
||||
strcpy(reg->realname, "!DEL!");
|
||||
reg->passwd = (char *)MALLOC(1);
|
||||
*reg->passwd = '\0';
|
||||
reg->match = (char *)MALLOC(6);
|
||||
strcpy(reg->match, "!DEL!");
|
||||
reg->channel = (char *)MALLOC(strlen(channel) + 1);
|
||||
strcpy(reg->channel, channel);
|
||||
reg->modif = (char *)MALLOC(1);
|
||||
*reg->modif = '\0';
|
||||
reg->modified = 1;
|
||||
reg->offset = offset;
|
||||
reg->next = UserList[idx];
|
||||
UserList[idx] = reg;
|
||||
}
|
||||
|
||||
/* read_db()
|
||||
* This should be called from the select() loop. Data is read sequentially
|
||||
* and the query is processed according to 'type'.
|
||||
*/
|
||||
void read_db(dbquery * query)
|
||||
{
|
||||
struct dbuser buffer[11];
|
||||
int size, status, end = 0;
|
||||
|
||||
size = read(query->fd, buffer, 10 * sizeof(dbuser));
|
||||
if (size <= 0)
|
||||
{
|
||||
if (errno != EAGAIN && errno != EWOULDBLOCK)
|
||||
{
|
||||
close(query->fd);
|
||||
query->fd = -1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
copy_to_buffer(&query->buf, (char *)buffer, size);
|
||||
while (!end && look_in_buffer(&query->buf, (char *)buffer, '\0', sizeof(dbuser))
|
||||
== sizeof(dbuser))
|
||||
{
|
||||
if (buffer[0].header[0] == 0xFF && buffer[0].header[1] == 0xFF &&
|
||||
buffer[0].footer[0] == 0xFF && buffer[0].footer[1] == 0xFF)
|
||||
{
|
||||
status = 1; /* block is used */
|
||||
}
|
||||
else if (buffer[0].header[0] == 0x00 && buffer[0].header[1] == 0x00 &&
|
||||
buffer[0].footer[0] == 0x00 && buffer[0].footer[1] == 0x00)
|
||||
{
|
||||
status = 0; /* block is free */
|
||||
}
|
||||
else
|
||||
{
|
||||
status = -1; /* block has been written to while reading it */
|
||||
}
|
||||
|
||||
if (status == 1 && strcasecmp(query->channel, buffer[0].channel))
|
||||
{
|
||||
fix_db(query->channel, query->offset);
|
||||
skip_char_in_buffer(&query->buf, sizeof(dbuser));
|
||||
query->offset += sizeof(dbuser);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("hdr: %X%X nick: %s match: %s passwd: %s channel: %s "
|
||||
"modif: %s access: %d flags: %ld susp: %ld last: %ld ftr: %X%X"
|
||||
"sta: %d\n",
|
||||
buffer[0].header[0], buffer[0].header[1], buffer[0].nick, buffer[0].match, buffer[0].passwd,
|
||||
buffer[0].channel, buffer[0].modif, buffer[0].access, buffer[0].flags, buffer[0].suspend,
|
||||
buffer[0].lastseen, buffer[0].footer[0], buffer[0].footer[1], status);
|
||||
#endif
|
||||
|
||||
switch (query->type)
|
||||
{
|
||||
case DBGETNICK:
|
||||
if (status == 1 && !strcasecmp(buffer[0].nick, query->info))
|
||||
{
|
||||
close(query->fd);
|
||||
query->fd = -1;
|
||||
query->count++;
|
||||
query->callback(&query->fd, query->offset, query->action, query->hook1,
|
||||
query->hook2, buffer, query->count);
|
||||
end = 1;
|
||||
}
|
||||
break;
|
||||
case DBGET1STUH:
|
||||
if (status == 1 && match(query->info, buffer[0].match))
|
||||
{
|
||||
close(query->fd);
|
||||
query->fd = -1;
|
||||
query->count++;
|
||||
query->callback(&query->fd, query->offset, query->action, query->hook1,
|
||||
query->hook2, buffer, query->count);
|
||||
end = 1;
|
||||
}
|
||||
break;
|
||||
case DBGETALLUH:
|
||||
if (status == 1 && match(query->info, buffer[0].match))
|
||||
{
|
||||
query->count++;
|
||||
query->callback(&query->fd, query->offset, query->action, query->hook1,
|
||||
query->hook2, buffer, query->count);
|
||||
}
|
||||
break;
|
||||
case DBGETUHPASS:
|
||||
if (status == 1 && match(query->info, buffer[0].match) &&
|
||||
!strcmp(query->passwd, buffer[0].passwd))
|
||||
{
|
||||
close(query->fd);
|
||||
query->fd = -1;
|
||||
query->count++;
|
||||
query->callback(&query->fd, query->offset, query->action, query->hook1,
|
||||
query->hook2, buffer, query->count);
|
||||
end = 1;
|
||||
}
|
||||
break;
|
||||
case DBCOUNTUH:
|
||||
if (status == 1 && match(query->info, buffer[0].match))
|
||||
{
|
||||
query->count++;
|
||||
}
|
||||
break;
|
||||
case DBGET1STCMP:
|
||||
if (status == 1 && (!*query->info || compare(query->info, buffer[0].match)))
|
||||
{
|
||||
close(query->fd);
|
||||
query->fd = -1;
|
||||
query->count++;
|
||||
query->callback(&query->fd, query->offset, query->action, query->hook1,
|
||||
query->hook2, buffer, query->count);
|
||||
end = 1;
|
||||
}
|
||||
break;
|
||||
case DBGETALLCMP:
|
||||
if (status == 1 && (!*query->info || compare(query->info, buffer[0].match)))
|
||||
{
|
||||
query->count++;
|
||||
query->callback(&query->fd, query->offset, query->action, query->hook1,
|
||||
query->hook2, buffer, query->count);
|
||||
}
|
||||
break;
|
||||
case DBCNTCMP:
|
||||
if (status == 1 && (!*query->info || compare(query->info, buffer[0].match)))
|
||||
{
|
||||
query->count++;
|
||||
}
|
||||
break;
|
||||
case DBGET1STFREE:
|
||||
if (status == 0)
|
||||
{
|
||||
close(query->fd);
|
||||
query->fd = -1;
|
||||
query->count++;
|
||||
query->callback(&query->fd, query->offset, query->action, query->hook1,
|
||||
query->hook2, buffer, query->count);
|
||||
end = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
skip_char_in_buffer(&query->buf, sizeof(dbuser));
|
||||
query->offset += sizeof(dbuser);
|
||||
if (query->fd < 0)
|
||||
end = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void end_db_read(dbquery * query)
|
||||
{
|
||||
zap_buffer(&query->buf);
|
||||
query->callback(&query->fd, query->offset, query->action, query->hook1,
|
||||
query->hook2, NULL, query->count);
|
||||
}
|
||||
|
||||
|
||||
void make_dbuser(RegUser * reg, dbuser * dbu)
|
||||
{
|
||||
memset(dbu, 0, sizeof(dbuser));
|
||||
if (reg->access != 0)
|
||||
{
|
||||
strncpy(dbu->nick, reg->realname, 79);
|
||||
dbu->nick[79] = '\0';;
|
||||
strncpy(dbu->match, reg->match, 79);
|
||||
dbu->match[79] = '\0';
|
||||
strncpy(dbu->channel, reg->channel, 49);
|
||||
dbu->channel[49] = '\0';
|
||||
strncpy(dbu->passwd, reg->passwd, 19);
|
||||
dbu->passwd[19] = '\0';
|
||||
strncpy(dbu->modif, reg->modif, 79);
|
||||
dbu->modif[79] = '\0';
|
||||
dbu->access = reg->access;
|
||||
dbu->flags = reg->flags;
|
||||
dbu->suspend = reg->suspend;
|
||||
dbu->lastseen = reg->lastseen;
|
||||
dbu->header[0] = 0xFF;
|
||||
dbu->header[1] = 0xFF;
|
||||
dbu->footer[0] = 0xFF;
|
||||
dbu->footer[1] = 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
void sync_next_channel(void)
|
||||
{
|
||||
register syncchan *tmp;
|
||||
|
||||
if ((tmp = SyncChan) != NULL)
|
||||
{
|
||||
SyncChan = SyncChan->next;
|
||||
db_sync(tmp->name);
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
static void set_sync(dbsync * sync)
|
||||
{
|
||||
struct dbuser dbu;
|
||||
|
||||
if (*sync->reg == NULL)
|
||||
{
|
||||
close(sync->fd);
|
||||
sync->fd = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((*sync->reg)->access == 0) /* delete */
|
||||
{
|
||||
make_dbuser(*sync->reg, &dbu);
|
||||
zap_buffer(&sync->buf);
|
||||
copy_to_buffer(&sync->buf, (char *)&dbu, sizeof(dbuser));
|
||||
sync->type = SYNC_DELETE;
|
||||
sync->status = SYNC_PENDWRITE;
|
||||
sync->offset = (*sync->reg)->offset;
|
||||
lseek(sync->fd, (*sync->reg)->offset, SEEK_SET);
|
||||
}
|
||||
else if ((*sync->reg)->offset != (off_t) - 1) /* update */
|
||||
{
|
||||
make_dbuser(*sync->reg, &dbu);
|
||||
zap_buffer(&sync->buf);
|
||||
copy_to_buffer(&sync->buf, (char *)&dbu, sizeof(dbuser));
|
||||
sync->type = SYNC_UPDATE;
|
||||
sync->status = SYNC_PENDWRITE;
|
||||
sync->offset = (*sync->reg)->offset;
|
||||
lseek(sync->fd, (*sync->reg)->offset, SEEK_SET);
|
||||
}
|
||||
else
|
||||
/* add */
|
||||
{
|
||||
sync->type = SYNC_ADD;
|
||||
sync->status = SYNC_SEEKFREE;
|
||||
sync->offset = (off_t) 0;
|
||||
lseek(sync->fd, 0L, SEEK_SET);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void sync_next(dbsync * sync, char *channel)
|
||||
{
|
||||
register RegUser **reg = sync->reg;
|
||||
|
||||
if (*reg == NULL)
|
||||
{
|
||||
close(sync->fd);
|
||||
sync->fd = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
while (*reg != NULL && ((*reg)->modified == 0 || (*reg)->access == 1000 ||
|
||||
strcasecmp((*reg)->channel, channel)))
|
||||
{
|
||||
if ((*reg)->inuse == 0 && (*reg)->lastused + CACHE_TIMEOUT < now)
|
||||
free_user(reg);
|
||||
else
|
||||
reg = &(*reg)->next;
|
||||
}
|
||||
|
||||
sync->time = now;
|
||||
sync->reg = reg;
|
||||
set_sync(sync);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void db_sync(char *channel)
|
||||
{
|
||||
register RegUser **reg, *tmp;
|
||||
register char *ch;
|
||||
register dbsync *sync;
|
||||
struct stat st;
|
||||
int fd;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("SYNC: %s\n", channel);
|
||||
#endif
|
||||
|
||||
if (DBSync != NULL && (DBSync->fd != -1 || DBSync->next != NULL))
|
||||
{
|
||||
log("ERROR: simultaneous syncs??");
|
||||
return;
|
||||
}
|
||||
|
||||
ch = make_dbfname(channel);
|
||||
|
||||
/* IF file does not exist.. remove all deletes and mark
|
||||
* all other entries as new.
|
||||
*/
|
||||
if (stat(ch, &st) < 0)
|
||||
{
|
||||
/* remove all deletes */
|
||||
reg = &UserList[ul_hash(channel)];
|
||||
while (*reg)
|
||||
{
|
||||
(*reg)->offset = (off_t) - 1;
|
||||
if ((*reg)->access == 0 && (*reg)->inuse == 0 &&
|
||||
!strcasecmp((*reg)->channel, channel))
|
||||
{
|
||||
tmp = *reg;
|
||||
*reg = (*reg)->next;
|
||||
free_user(reg);
|
||||
}
|
||||
else
|
||||
reg = &(*reg)->next;
|
||||
}
|
||||
fd = open(ch, O_RDWR | O_CREAT | O_EXCL | O_NONBLOCK, 0600);
|
||||
}
|
||||
else
|
||||
{
|
||||
fd = open(ch, O_RDWR | O_NONBLOCK);
|
||||
}
|
||||
|
||||
/* create new sync struct
|
||||
*/
|
||||
sync = (dbsync *) malloc(sizeof(dbsync));
|
||||
sync->fd = fd;
|
||||
sync->reg = &UserList[ul_hash(channel)];
|
||||
sync->buf = NULL;
|
||||
sync->next = DBSync;
|
||||
DBSync = sync;
|
||||
|
||||
sync_next(sync, channel);
|
||||
}
|
||||
|
||||
|
||||
void db_sync_ready(dbsync * sync)
|
||||
{
|
||||
struct dbuser buffer[10];
|
||||
register RegUser **reg = sync->reg;
|
||||
int size;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("SYNC_READY: status= %d\n", sync->status);
|
||||
#endif
|
||||
|
||||
if (sync->status == SYNC_PENDWRITE)
|
||||
{
|
||||
size = look_in_buffer(&sync->buf, (char *)buffer, '\0', sizeof(dbuser));
|
||||
if (size == 0)
|
||||
zap_buffer(&sync->buf);
|
||||
if (sync->buf == NULL)
|
||||
{
|
||||
if ((*reg)->access == 0 && (*reg)->inuse == 0)
|
||||
free_user(reg);
|
||||
else
|
||||
(*reg)->modified = 0;
|
||||
sync_next(sync, (*reg)->channel);
|
||||
return;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("PENDWRITE: %d bytes to write...", size);
|
||||
#endif
|
||||
size = write(sync->fd, buffer, size);
|
||||
#ifdef DEBUG
|
||||
printf("%d written\n", size);
|
||||
#endif
|
||||
if (size <= 0)
|
||||
{
|
||||
if (errno != EWOULDBLOCK && errno != EAGAIN)
|
||||
{
|
||||
close(sync->fd);
|
||||
sync->fd = -1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
skip_char_in_buffer(&sync->buf, size);
|
||||
}
|
||||
|
||||
else if (sync->status == SYNC_SEEKFREE)
|
||||
{
|
||||
size = read(sync->fd, buffer, 10 * sizeof(dbuser));
|
||||
if (size <= 0)
|
||||
{
|
||||
if (errno != EAGAIN && errno != EWOULDBLOCK)
|
||||
{
|
||||
make_dbuser(*sync->reg, buffer);
|
||||
zap_buffer(&sync->buf);
|
||||
copy_to_buffer(&sync->buf, (char *)buffer, sizeof(dbuser));
|
||||
sync->status = SYNC_PENDWRITE;
|
||||
lseek(sync->fd, 0L, SEEK_END);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
copy_to_buffer(&sync->buf, (char *)buffer, size);
|
||||
while (look_in_buffer(&sync->buf, (char *)buffer, '\0', sizeof(dbuser))
|
||||
== sizeof(dbuser))
|
||||
{
|
||||
if (buffer[0].header[0] == 0x00 && buffer[0].header[1] == 0x00 &&
|
||||
buffer[0].footer[0] == 0x00 && buffer[0].footer[1] == 0x00)
|
||||
{
|
||||
make_dbuser(*sync->reg, buffer);
|
||||
zap_buffer(&sync->buf);
|
||||
copy_to_buffer(&sync->buf, (char *)buffer, sizeof(dbuser));
|
||||
sync->status = SYNC_PENDWRITE;
|
||||
(*sync->reg)->offset = sync->offset;
|
||||
lseek(sync->fd, sync->offset, SEEK_SET);
|
||||
return;
|
||||
}
|
||||
skip_char_in_buffer(&sync->buf, sizeof(dbuser));
|
||||
sync->offset += sizeof(dbuser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void end_db_sync(dbsync * sync)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("SYNC_END\n");
|
||||
#endif
|
||||
sync_next_channel();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void cold_save_one(RegUser * reg)
|
||||
{
|
||||
struct stat st;
|
||||
dbuser dbu;
|
||||
char *fname;
|
||||
register int fd;
|
||||
off_t off;
|
||||
|
||||
fname = make_dbfname(reg->channel);
|
||||
|
||||
if (stat(fname, &st) < 0) /* file doesn't exist -- don't save delete */
|
||||
{
|
||||
if (reg->access == 0)
|
||||
return;
|
||||
fd = open(fname, O_RDWR | O_CREAT, 0600);
|
||||
}
|
||||
else
|
||||
fd = open(fname, O_RDWR | O_EXCL);
|
||||
|
||||
if (fd < 0) /* hmmm? */
|
||||
return;
|
||||
|
||||
if (reg->offset == (off_t) - 1) /* new ==> seek for empty slot */
|
||||
{
|
||||
lseek(fd, 0L, SEEK_SET);
|
||||
off = (off_t) 0;
|
||||
while (read(fd, &dbu, sizeof(dbuser)) == sizeof(dbuser))
|
||||
{
|
||||
if (dbu.header[0] == 0x00 && dbu.header[1] == 0x00 &&
|
||||
dbu.footer[0] == 0x00 && dbu.footer[1] == 0x00)
|
||||
break; /* found empty slot */
|
||||
off += sizeof(dbuser);
|
||||
}
|
||||
}
|
||||
else
|
||||
off = reg->offset;
|
||||
|
||||
lseek(fd, off, SEEK_SET); /* go to write position */
|
||||
|
||||
if (reg->access != 0)
|
||||
make_dbuser(reg, &dbu);
|
||||
else
|
||||
memset(&dbu, 0, sizeof(dbuser));
|
||||
|
||||
write(fd, &dbu, sizeof(dbuser));
|
||||
|
||||
if (reg->access != 0)
|
||||
reg->offset = off;
|
||||
else
|
||||
reg->offset = (off_t) - 1;
|
||||
|
||||
reg->modified = 0;
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
|
||||
void do_cold_sync_slice(void)
|
||||
{
|
||||
register RegUser **reg;
|
||||
|
||||
if (DB_Save_Status < 0)
|
||||
return;
|
||||
|
||||
reg = &UserList[DB_Save_Status];
|
||||
while (*reg != NULL)
|
||||
{
|
||||
if ((*reg)->modified && (*reg)->access < 1000)
|
||||
cold_save_one(*reg);
|
||||
if ((*reg)->inuse == 0 && (*reg)->access < 1000 &&
|
||||
((*reg)->access == 0 || (*reg)->lastused + CACHE_TIMEOUT < now))
|
||||
free_user(reg);
|
||||
else
|
||||
reg = &(*reg)->next;
|
||||
}
|
||||
|
||||
if (++DB_Save_Status == 1000)
|
||||
{
|
||||
DB_Save_Status = -1;
|
||||
if (*DB_Save_Nick)
|
||||
notice(DB_Save_Nick, "Userlist sync complete!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void do_cold_sync(void)
|
||||
{
|
||||
register dbsync *sync;
|
||||
register syncchan *schan;
|
||||
register RegUser **reg;
|
||||
register int i;
|
||||
char buffer[200];
|
||||
|
||||
/* SET AWAY MESSAGE */
|
||||
sprintf(buffer, ":%s AWAY :Busy saving precious user list\n", mynick);
|
||||
sendtoserv(buffer);
|
||||
dumpbuff();
|
||||
|
||||
/* First, cancel *all* sync requests */
|
||||
while ((sync = DBSync) != NULL)
|
||||
{
|
||||
DBSync = DBSync->next;
|
||||
if (sync->fd >= 0)
|
||||
close(sync->fd);
|
||||
zap_buffer(&sync->buf);
|
||||
free(sync);
|
||||
}
|
||||
|
||||
/* Also, clear *all* pending syncs */
|
||||
while ((schan = SyncChan) != NULL)
|
||||
{
|
||||
SyncChan = SyncChan->next;
|
||||
free(schan);
|
||||
}
|
||||
|
||||
/* Now, go thru *all* the user entries in memory and save them
|
||||
* to their respective files.
|
||||
*/
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
reg = &UserList[i];
|
||||
while (*reg != NULL)
|
||||
{
|
||||
if ((*reg)->modified && (*reg)->access < 1000)
|
||||
cold_save_one(*reg);
|
||||
if ((*reg)->inuse == 0 && (*reg)->access < 1000 &&
|
||||
((*reg)->access == 0 || (*reg)->lastused + CACHE_TIMEOUT < now))
|
||||
free_user(reg);
|
||||
else
|
||||
reg = &(*reg)->next;
|
||||
}
|
||||
}
|
||||
sprintf(buffer, ":%s AWAY\n", mynick);
|
||||
sendtoserv(buffer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
void db_test_callback(int *fd, off_t off, int action, void *hook1, void *hook2,
|
||||
dbuser * dbu, int count)
|
||||
{
|
||||
char buffer[512];
|
||||
|
||||
sprintf(buffer, "off: %ld act: %d hook=%p cnt: %d", off, action, hook1, count);
|
||||
notice((char *)hook1, buffer);
|
||||
|
||||
if (dbu)
|
||||
{
|
||||
sprintf(buffer, "hdr: %X%X nick: %s match: %s passwd: %s channel: %s "
|
||||
"modif: %s access: %d flags: %ld susp: %ld last: %ld ftr: %X%X",
|
||||
dbu->header[0], dbu->header[1], dbu->nick, dbu->match, dbu->passwd,
|
||||
dbu->channel, dbu->modif, dbu->access, dbu->flags, dbu->suspend,
|
||||
dbu->lastseen, dbu->footer[0], dbu->footer[1]);
|
||||
notice((char *)hook1, buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
notice((char *)hook1, "End.");
|
||||
free(hook1);
|
||||
}
|
||||
}
|
||||
|
||||
void db_test(char *source, char *chan, char *args)
|
||||
{
|
||||
char channel[80], type[80], info[80], *hook;
|
||||
|
||||
GetWord(0, args, channel);
|
||||
GetWord(1, args, type);
|
||||
GetWord(2, args, info);
|
||||
hook = (char *)malloc(strlen(source) + 1);
|
||||
strcpy(hook, source);
|
||||
|
||||
if (!strcmp(type, "nick"))
|
||||
db_fetch(channel, DBGETNICK, info, NULL, 0, hook, NULL, db_test_callback);
|
||||
|
||||
else if (!strcmp(type, "alluh"))
|
||||
db_fetch(channel, DBGETALLUH, info, NULL, 0, hook, NULL, db_test_callback);
|
||||
|
||||
else if (!strcmp(type, "1stuh"))
|
||||
db_fetch(channel, DBGET1STUH, info, NULL, 0, hook, NULL, db_test_callback);
|
||||
|
||||
else if (!strcmp(type, "count"))
|
||||
db_fetch(channel, DBCOUNTUH, info, NULL, 0, hook, NULL, db_test_callback);
|
||||
|
||||
else if (!strcmp(type, "1stcmp"))
|
||||
db_fetch(channel, DBGET1STCMP, info, NULL, 0, hook, NULL, db_test_callback);
|
||||
|
||||
else if (!strcmp(type, "allcmp"))
|
||||
db_fetch(channel, DBGETALLCMP, info, NULL, 0, hook, NULL, db_test_callback);
|
||||
|
||||
else if (!strcmp(type, "cntcmp"))
|
||||
db_fetch(channel, DBCNTCMP, info, NULL, 0, hook, NULL, db_test_callback);
|
||||
|
||||
else if (!strcmp(type, "sync"))
|
||||
db_sync(channel);
|
||||
}
|
||||
#endif
|
||||
43
Sources/dbio.h
Normal file
43
Sources/dbio.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/* @(#)$Id: dbio.h,v 1.3 1996/11/13 00:40:36 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#define DBGETNICK 0x00000001
|
||||
#define DBGET1STUH 0x00000002
|
||||
#define DBGETALLUH 0x00000004
|
||||
#define DBCOUNTUH 0x00000008
|
||||
#define DBGET1STCMP 0x00000010
|
||||
#define DBGETALLCMP 0x00000020
|
||||
#define DBCNTCMP 0x00000040
|
||||
#define DBGETUHPASS 0x00000080
|
||||
#define DBGET1STFREE 0x00000100
|
||||
|
||||
#define SYNC_UPDATE 0x00000001
|
||||
#define SYNC_DELETE 0x00000002
|
||||
#define SYNC_ADD 0x00000004
|
||||
|
||||
#define SYNC_PENDWRITE 0x00000001
|
||||
#define SYNC_SEEKFREE 0x00000002
|
||||
|
||||
70
Sources/debug.c
Normal file
70
Sources/debug.c
Normal file
@@ -0,0 +1,70 @@
|
||||
/* @(#)$Id: debug.c,v 1.3 1996/11/13 00:40:36 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
|
||||
#ifdef DEBUG_MALLOC
|
||||
|
||||
#include <stdarg.h>
|
||||
#undef malloc
|
||||
#undef free
|
||||
|
||||
static FILE *debug_malloc_file;
|
||||
|
||||
void open_debug_malloc(void)
|
||||
{
|
||||
debug_malloc_file=fopen("malloc.log","w");
|
||||
}
|
||||
|
||||
void close_debug_malloc(void)
|
||||
{
|
||||
fclose(debug_malloc_file);
|
||||
}
|
||||
|
||||
void log_malloc(char *fmt,...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap,fmt);
|
||||
vfprintf(debug_malloc_file,fmt,ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void *debug_malloc(char *file, int line, size_t size)
|
||||
{
|
||||
register void *ptr;
|
||||
ptr=malloc(size);
|
||||
log_malloc("%s(%d):malloc(%ld)= %p\n",file,line,(long)size,ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void debug_free(char *file, int line, void *ptr)
|
||||
{
|
||||
log_malloc("%s(%d):free(%p)\n",file,line,ptr);
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
37
Sources/debug.h
Normal file
37
Sources/debug.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/* @(#)$Id: debug.h,v 1.3 1996/11/13 00:40:37 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG_MALLOC
|
||||
void open_debug_malloc(void);
|
||||
void close_debug_malloc(void);
|
||||
void *debug_malloc(char *,int,size_t);
|
||||
void debug_free(char *,int,void *);
|
||||
|
||||
#define malloc(X) debug_malloc(__FILE__,__LINE__,X)
|
||||
#define free(X) debug_free(__FILE__,__LINE__,X)
|
||||
|
||||
#endif
|
||||
|
||||
493
Sources/defchan.c
Normal file
493
Sources/defchan.c
Normal file
@@ -0,0 +1,493 @@
|
||||
/* @(#)$Id: defchan.c,v 1.7 1999/12/19 16:33:13 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
|
||||
#define FORMATNO 0x02
|
||||
|
||||
typedef struct adefchan0 {
|
||||
char name[50];
|
||||
char mode[80];
|
||||
char reserved[20];
|
||||
int MassDeopPro;
|
||||
int NickFloodPro;
|
||||
int MsgFloodPro;
|
||||
time_t TS;
|
||||
unsigned long flags;
|
||||
unsigned long uflags;
|
||||
struct adefchan *next;
|
||||
} adefchan0;
|
||||
|
||||
typedef struct adefchan1 {
|
||||
char name[50];
|
||||
char mode[80];
|
||||
int MassDeopPro;
|
||||
int NickFloodPro;
|
||||
int MsgFloodPro;
|
||||
int lang;
|
||||
time_t TS;
|
||||
unsigned long flags;
|
||||
unsigned long uflags;
|
||||
struct adefchan *next;
|
||||
} adefchan1;
|
||||
|
||||
static int active=0;
|
||||
|
||||
void SearchChan(char *source,char *ch,char *args)
|
||||
{
|
||||
char buffer[200],keylist[512];
|
||||
char *tok[16];
|
||||
adefchan *list[11];
|
||||
register adefchan *curr;
|
||||
register int found=0,i=0;
|
||||
|
||||
if(!*args){
|
||||
notice(source,"SYNTAX: search <keywords>");
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(keylist,args);
|
||||
|
||||
tok[0]=strtok(keylist," ");
|
||||
while(i<16 && (tok[++i]=strtok(NULL," "))!=NULL);
|
||||
tok[i]=NULL;
|
||||
|
||||
for(curr=DefChanList; curr; curr=curr->next){
|
||||
if((key_match(curr->name,tok)||key_match(curr->topic,tok)) &&
|
||||
!IsSet(curr->name,'s',"") && !IsSet(curr->name,'p',"")){
|
||||
list[found]=curr;
|
||||
found++;
|
||||
if(found>10){
|
||||
sprintf(buffer,"There are more than 10 entries matching [%s]",args);
|
||||
notice(source,buffer);
|
||||
sprintf(buffer,"Please restrict your search mask");
|
||||
notice(source,buffer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!found){
|
||||
sprintf(buffer,"No matching entries for [%s]",args);
|
||||
notice(source,buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
for(i=0; i<found; i++){
|
||||
sprintf(buffer,"%-15s - %s",list[i]->name,list[i]->topic);
|
||||
notice(source,buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AddChan(char *source,char *ch,char *args)
|
||||
{
|
||||
char buffer[200];
|
||||
char channel[80];
|
||||
register adefchan *curr,**scan;
|
||||
register achannel *chan;
|
||||
register int found=0;
|
||||
|
||||
if(*args=='#'){
|
||||
GetWord(0,args,channel);
|
||||
}else{
|
||||
strcpy(channel,ch);
|
||||
GuessChannel(source,channel);
|
||||
}
|
||||
|
||||
if(!strcmp(channel,"*")){
|
||||
notice(source,"SYNTAX: addchan <channel>");
|
||||
return;
|
||||
}
|
||||
|
||||
chan=ToChannel(channel);
|
||||
if(chan==NULL || !chan->on){
|
||||
notice(source,replies[RPL_NOTONCHANNEL][L_DEFAULT]);
|
||||
return;
|
||||
}
|
||||
|
||||
if(Access(channel,source)<SET_DEFAULT_LEVEL){
|
||||
ReplyNotAccess(source,channel);
|
||||
return;
|
||||
}
|
||||
|
||||
chan=ChannelList[cl_hash(channel)];
|
||||
|
||||
while(chan && !found){
|
||||
if(!strcasecmp(chan->name,channel)){
|
||||
/* look if the channel is already in the
|
||||
* default channels list
|
||||
*/
|
||||
|
||||
curr=DefChanList;
|
||||
while(curr&&strcasecmp(curr->name,channel))
|
||||
curr=curr->next;
|
||||
|
||||
/* The channel *IS NOT* in the list */
|
||||
if(curr==NULL){
|
||||
curr=(adefchan *)MALLOC(sizeof(adefchan));
|
||||
scan=&DefChanList;
|
||||
while(*scan && strcasecmp((*scan)->name,chan->name)<0)
|
||||
scan=&(*scan)->next;
|
||||
curr->next=*scan;
|
||||
*scan=curr;
|
||||
|
||||
curr->url[0]='\0';
|
||||
curr->topic[0]='\0';
|
||||
}
|
||||
|
||||
strcpy(curr->name,chan->name);
|
||||
strcpy(curr->mode,chan->mode);
|
||||
curr->MassDeopPro=chan->MassDeopPro;
|
||||
curr->NickFloodPro=chan->NickFloodPro;
|
||||
curr->MsgFloodPro=chan->MsgFloodPro;
|
||||
curr->lang=chan->lang;
|
||||
curr->flags=chan->flags;
|
||||
curr->uflags=chan->uflags;
|
||||
curr->TS=chan->TS;
|
||||
|
||||
found=1;
|
||||
}else
|
||||
chan=chan->next;
|
||||
}
|
||||
sprintf(buffer,"I ADD DEFAULT CHANNEL %s",channel);
|
||||
log(buffer);
|
||||
|
||||
if(found){
|
||||
notice(source,replies[RPL_SETCHANDEFS][chan->lang]);
|
||||
#ifdef BACKUP
|
||||
notice(source,"This modification will not be permanent");
|
||||
#endif
|
||||
}else{
|
||||
notice(source,replies[RPL_NOTONCHANNEL][L_DEFAULT]);
|
||||
}
|
||||
}
|
||||
|
||||
void RemChan(char *source, char *ch, char *arg)
|
||||
{
|
||||
char buffer[200];
|
||||
char channel[80];
|
||||
register adefchan *chan,*prev;
|
||||
|
||||
if(*arg=='#'){
|
||||
GetWord(0,arg,channel);
|
||||
}else{
|
||||
strcpy(channel,ch);
|
||||
GuessChannel(source,channel);
|
||||
}
|
||||
|
||||
if(!strcmp(channel,"*")){
|
||||
notice(source,"SYNTAX: remchan <channel>");
|
||||
return;
|
||||
}
|
||||
|
||||
if(*source && Access(channel,source)<SET_DEFAULT_LEVEL){
|
||||
ReplyNotAccess(source,channel);
|
||||
return;
|
||||
}
|
||||
|
||||
prev=NULL;
|
||||
for(chan=DefChanList;chan&&strcasecmp(channel,chan->name);chan=chan->next)
|
||||
prev=chan;
|
||||
|
||||
if(!chan){
|
||||
notice(source,replies[RPL_NOTDEF][L_DEFAULT]);
|
||||
return;
|
||||
}
|
||||
|
||||
if(prev)
|
||||
prev->next=chan->next;
|
||||
else
|
||||
DefChanList=chan->next;
|
||||
|
||||
TTLALLOCMEM-=sizeof(adefchan);
|
||||
free(chan);
|
||||
|
||||
sprintf(buffer,"I REMOVE DEFAULT CHANNEL %s",channel);
|
||||
log(buffer);
|
||||
if(*source){
|
||||
notice(source,replies[RPL_REMDEF][L_DEFAULT]);
|
||||
#ifdef BACKUP
|
||||
notice(source,"This modification will not be permanent");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void SaveDefs(char *source)
|
||||
{
|
||||
register int file;
|
||||
register adefchan *curr;
|
||||
adefchan buff;
|
||||
filehdr hdr;
|
||||
char global[]="*";
|
||||
char buffer[200];
|
||||
|
||||
if(*source&&Access(global,source)<SAVE_DEFAULTS_LEVEL){
|
||||
notice(source,"Your admin Access is too low!");
|
||||
return;
|
||||
}
|
||||
|
||||
if(*source)
|
||||
notice(source,"Saving defaults file...");
|
||||
|
||||
if(active)
|
||||
return;
|
||||
active=1;
|
||||
|
||||
sprintf(buffer,":%s AWAY :Busy saving precious channel list\n",mynick);
|
||||
sendtoserv(buffer);
|
||||
dumpbuff();
|
||||
|
||||
alarm(5); /* avoid NFS hangs */
|
||||
file=open(DEFAULT_CHANNELS_FILE".new",O_WRONLY|O_CREAT|O_TRUNC,0600);
|
||||
alarm(0);
|
||||
|
||||
if(file<0){
|
||||
if(*source)
|
||||
notice(source,"Error while opening file. Aborted!");
|
||||
log("ERROR Saving defaults channels");
|
||||
}else{
|
||||
hdr.magic=0xff;
|
||||
hdr.no=FORMATNO;
|
||||
alarm(2);
|
||||
if(write(file,&hdr,sizeof(hdr))<=0){
|
||||
alarm(0);
|
||||
close(file);
|
||||
log("ERROR: Can't save channel list");
|
||||
log((char *)sys_errlist[errno]);
|
||||
alarm(2);
|
||||
remove(DEFAULT_CHANNELS_FILE".new");
|
||||
alarm(0);
|
||||
active=0;
|
||||
sprintf(buffer,":%s AWAY\n",mynick);
|
||||
sendtoserv(buffer);
|
||||
return;
|
||||
}
|
||||
alarm(0);
|
||||
|
||||
curr=DefChanList;
|
||||
while(curr){
|
||||
achannel *chan = ToChannel(curr->name);
|
||||
|
||||
buff = *curr;
|
||||
if(chan)
|
||||
buff.TS = chan->TS;
|
||||
else
|
||||
buff.TS = curr->TS;
|
||||
buff.flags = curr->flags;
|
||||
|
||||
alarm(2);
|
||||
if(write(file,&buff,sizeof(adefchan))<=0){
|
||||
alarm(0);
|
||||
close(file);
|
||||
log("ERROR: Can't save channel list");
|
||||
log((char *)sys_errlist[errno]);
|
||||
alarm(2);
|
||||
remove(DEFAULT_CHANNELS_FILE".new");
|
||||
alarm(0);
|
||||
active=0;
|
||||
sprintf(buffer,":%s AWAY\n",mynick);
|
||||
sendtoserv(buffer);
|
||||
return;
|
||||
}
|
||||
alarm(0);
|
||||
curr=curr->next;
|
||||
}
|
||||
close(file);
|
||||
alarm(20);
|
||||
rename(DEFAULT_CHANNELS_FILE".new",DEFAULT_CHANNELS_FILE);
|
||||
alarm(0);
|
||||
if(*source)
|
||||
notice(source,"Done.");
|
||||
}
|
||||
active=0;
|
||||
sprintf(buffer,":%s AWAY\n",mynick);
|
||||
sendtoserv(buffer);
|
||||
}
|
||||
|
||||
void LoadDefs(char *source)
|
||||
{
|
||||
register adefchan *curr,**scan;
|
||||
adefchan buffer;
|
||||
adefchan0 bufold0;
|
||||
adefchan1 bufold1;
|
||||
filehdr hdr;
|
||||
register int file;
|
||||
char global[]="*";
|
||||
|
||||
if(*source&&Access(global,source)<LOAD_DEFAULT_LEVEL){
|
||||
notice(source,"Your admin Access is too low!");
|
||||
return;
|
||||
}
|
||||
|
||||
if(active)
|
||||
return;
|
||||
active=1;
|
||||
|
||||
file=open(DEFAULT_CHANNELS_FILE,O_RDONLY);
|
||||
if(file<0){
|
||||
if(*source) notice(source,"Error opening file! Aborted.");
|
||||
log("ERROR Loading the default channels");
|
||||
active=0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* empty existing defaults */
|
||||
|
||||
while((curr=DefChanList)!=NULL){
|
||||
DefChanList=DefChanList->next;
|
||||
TTLALLOCMEM-=sizeof(adefchan);
|
||||
free(curr);
|
||||
}
|
||||
|
||||
/* find file format */
|
||||
read(file,&hdr,sizeof(hdr));
|
||||
if(hdr.magic!=0xff){
|
||||
lseek(file,0L,SEEK_SET);
|
||||
hdr.no=0x00;
|
||||
}
|
||||
|
||||
if(hdr.no == FORMATNO){
|
||||
scan=&DefChanList;
|
||||
while(read(file,&buffer,sizeof(adefchan))>0){
|
||||
#ifdef DEBUG
|
||||
printf("DEFCHAN: %s %d %d %d %ld\n",buffer.name,
|
||||
buffer.MassDeopPro,buffer.NickFloodPro,
|
||||
buffer.MsgFloodPro,buffer.flags);
|
||||
printf("TS: %lu\n",buffer.TS);
|
||||
#endif
|
||||
if(logTS==0||buffer.TS<logTS){
|
||||
#ifdef DEBUG
|
||||
printf("TS is older than %lu\n",logTS);
|
||||
#endif
|
||||
logTS=buffer.TS;
|
||||
}
|
||||
|
||||
if(buffer.TS<0){
|
||||
/* if the TS of a channel is negative
|
||||
* the file is prolly corrupted!
|
||||
*/
|
||||
log("Channel file is corrupted");
|
||||
quit("LoadDefs(): corrupted file!", 1);
|
||||
}
|
||||
|
||||
curr=(adefchan *)MALLOC(sizeof(adefchan));
|
||||
*curr=buffer;
|
||||
curr->next=*scan;
|
||||
*scan=curr;
|
||||
scan=&(*scan)->next;
|
||||
}
|
||||
}else if(hdr.no == 0x01){
|
||||
while(read(file,&bufold1,sizeof(adefchan1))>0){
|
||||
#ifdef DEBUG
|
||||
printf("DEFCHAN: %s %d %d %d %ld\n",bufold1.name,
|
||||
bufold1.MassDeopPro,bufold1.NickFloodPro,
|
||||
bufold1.MsgFloodPro,bufold1.flags);
|
||||
printf("TS: %lu\n",bufold1.TS);
|
||||
#endif
|
||||
if(logTS==0||bufold1.TS<logTS){
|
||||
#ifdef DEBUG
|
||||
printf("TS is older than %lu\n",logTS);
|
||||
#endif
|
||||
logTS=bufold1.TS;
|
||||
}
|
||||
|
||||
if(bufold1.TS<0){
|
||||
/* if the TS of a channel is negative
|
||||
* the file is prolly corrupted!
|
||||
*/
|
||||
log("Channel file is corrupted");
|
||||
quit("LoadDefs(): corrupted file!", 1);
|
||||
}
|
||||
|
||||
curr=(adefchan *)MALLOC(sizeof(adefchan));
|
||||
strcpy(curr->name,bufold1.name);
|
||||
strcpy(curr->mode,bufold1.mode);
|
||||
curr->url[0]='\0';
|
||||
curr->topic[0]='\0';
|
||||
curr->MassDeopPro=bufold1.MassDeopPro;
|
||||
curr->NickFloodPro=bufold1.NickFloodPro;
|
||||
curr->MsgFloodPro=bufold1.MsgFloodPro;
|
||||
curr->lang=bufold1.lang;
|
||||
curr->TS=bufold1.TS;
|
||||
curr->flags=bufold1.flags;
|
||||
curr->uflags=bufold1.uflags;
|
||||
scan=&DefChanList;
|
||||
while(*scan && strcasecmp((*scan)->name,curr->name)<0)
|
||||
scan=&(*scan)->next;
|
||||
curr->next=*scan;
|
||||
*scan=curr;
|
||||
}
|
||||
}else{ /* old file format */
|
||||
while(read(file,&bufold0,sizeof(adefchan0))>0){
|
||||
#ifdef DEBUG
|
||||
printf("DEFCHAN: %s %d %d %d %ld\n",bufold0.name,
|
||||
bufold0.MassDeopPro,bufold0.NickFloodPro,
|
||||
bufold0.MsgFloodPro,bufold0.flags);
|
||||
printf("TS: %lu\n",bufold0.TS);
|
||||
#endif
|
||||
if(logTS==0||bufold0.TS<logTS){
|
||||
#ifdef DEBUG
|
||||
printf("TS is older than %lu\n",logTS);
|
||||
#endif
|
||||
logTS=bufold0.TS;
|
||||
}
|
||||
|
||||
if(bufold0.TS<0){
|
||||
/* if the TS of a channel is negative
|
||||
* the file is prolly corrupted!
|
||||
*/
|
||||
log("Channel file is corrupted");
|
||||
quit("LoadDefs(): corrupted file!", 1);
|
||||
}
|
||||
|
||||
curr=(adefchan *)MALLOC(sizeof(adefchan));
|
||||
strcpy(curr->name,bufold0.name);
|
||||
strcpy(curr->mode,bufold0.mode);
|
||||
curr->url[0]='\0';
|
||||
curr->topic[0]='\0';
|
||||
curr->MassDeopPro=bufold0.MassDeopPro;
|
||||
curr->NickFloodPro=bufold0.NickFloodPro;
|
||||
curr->MsgFloodPro=bufold0.MsgFloodPro;
|
||||
curr->lang=L_DEFAULT;
|
||||
curr->TS=bufold0.TS;
|
||||
curr->flags=bufold0.flags;
|
||||
curr->uflags=bufold0.uflags;
|
||||
scan=&DefChanList;
|
||||
while(*scan && strcasecmp((*scan)->name,curr->name)<0)
|
||||
scan=&(*scan)->next;
|
||||
curr->next=*scan;
|
||||
*scan=curr;
|
||||
}
|
||||
}
|
||||
|
||||
close(file);
|
||||
|
||||
if(*source)
|
||||
notice(source,"Defaults file loaded!");
|
||||
|
||||
active=0;
|
||||
}
|
||||
141
Sources/defines.h
Normal file
141
Sources/defines.h
Normal file
@@ -0,0 +1,141 @@
|
||||
/* @(#)$Id: defines.h,v 1.11 2000/06/04 16:54:16 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#define NICK_LENGTH 20
|
||||
#define USERNAME_LENGTH 20
|
||||
#define SITE_LENGTH 80
|
||||
#define REALNAME_LENGTH 80
|
||||
#define CHANNELNAME_LENGTH 80
|
||||
#define SERVER_NAME_LENGTH 80
|
||||
#define PASSWD_LENGTH 20
|
||||
|
||||
#define COMMAND_PREFIX "X "
|
||||
#define MAX_MODE_PER_LINE 6
|
||||
|
||||
#define MAX_DEOP_RATE 3 /* deops within 15 seconds */
|
||||
#define MASSDEOP_SUSPEND_TIME 600 /* seconds */
|
||||
#define MASSDEOP_SHITLIST_TIME 1 /* hours */
|
||||
#define MASSDEOP_SHITLIST_LEVEL 20
|
||||
|
||||
#define MAX_NICKCHANGE_RATE 5 /* nick change within 15 seconds */
|
||||
#define NICK_FLOOD_SUSPEND_TIME 600 /* seconds */
|
||||
|
||||
#define MAX_PUBLIC_MSG_RATE 7 /* within 15 seconds */
|
||||
#define PUBLIC_FLOOD_SUSPEND_TIME 600 /* seconds */
|
||||
#define PUBLIC_FLOOD_SHITLIST_TIME 24 /* hour */
|
||||
#define PUBLIC_FLOOD_SHITLIST_LEVEL 75
|
||||
|
||||
#define PRIVATE_FLOOD_RATE 10 /* messages per 30 seconds */
|
||||
#define PRIVATE_FLOOD_SIZE 800 /* bytes per 30 seconds */
|
||||
#define FLOOD_FLOOD_RATE 10 /* messages per 30 seconds */
|
||||
#define FLOOD_FLOOD_SIZE 60 /* lines per 30 seconds */
|
||||
#define MAX_IGNORE_PER_SITE 3 /* ignores per site */
|
||||
#define IGNORE_TIME 3600 /* in seconds */
|
||||
#define FLOOD_FLOOD_IGNORE 300 /* in seconds */
|
||||
|
||||
#define LEVEL_DIE 900
|
||||
#define LEVEL_CORE 900
|
||||
#define RUSAGE_ACCESS 900
|
||||
#define LEVEL_UPGRADE 900
|
||||
#define LEVEL_JOIN 450
|
||||
#define LEVEL_PART 450
|
||||
#define INVITE_LEVEL 100
|
||||
#define OP_LEVEL 100
|
||||
#define TOPIC_LEVEL 50
|
||||
#define KICK_LEVEL 50
|
||||
#define MASS_KICK_LEVEL 200
|
||||
#define BAN_LEVEL 75
|
||||
#define MASS_BAN_LEVEL 200
|
||||
#define ADD_USER_LEVEL 400
|
||||
#define SHOW_ACCESS_LEVEL 0
|
||||
#define REMOVE_USER_LEVEL 400
|
||||
#define MOD_USERINFO_LEVEL 400
|
||||
#define LEVEL_SUSPEND 100
|
||||
#define ADD_TO_SHITLIST_LEVEL 75
|
||||
#define CLEAN_SHITLIST_LEVEL 200
|
||||
#define SET_DEFAULT_LEVEL 450
|
||||
#define LOAD_DEFAULT_LEVEL 999
|
||||
#define SAVE_DEFAULTS_LEVEL 600
|
||||
#define SAVE_SHITLIST_LEVEL 600
|
||||
#define LOAD_SHITLIST_LEVEL 999
|
||||
#define SAVE_USERLIST_LEVEL 600
|
||||
#define LOAD_USERLIST_LEVEL 999
|
||||
#define STATUS_ACCESS 1
|
||||
#define STATUS_ACCESS_MODE 200
|
||||
#define CH_FLOOD_LIMIT_LEVEL 500
|
||||
#define CH_NICK_FLOOD_LIMIT_LEVEL 450
|
||||
#define CH_MASSDEOP_LIMIT_LEVEL 450
|
||||
#define CH_NOOP_LEVEL 500
|
||||
#define CH_OPONLY_LEVEL 500
|
||||
#define CH_AUTOTOPIC_LEVEL 450
|
||||
#define CH_ALWAYSOP_LEVEL 450
|
||||
#define CH_STRICTOP_LEVEL 500
|
||||
#define CH_USERFLAGS_LEVEL 450
|
||||
#define CH_LANG_LEVEL 500
|
||||
#define CH_TOPIC_LEVEL 450
|
||||
#define CH_URL_LEVEL 450
|
||||
#define ACCESS_BAN_PRIORITY 450
|
||||
#define ALWAYSOP_OVERRIDE_LEVEL 450
|
||||
#define PROTECT_OVERRIDE_LEVEL 450
|
||||
#define MASSDEOP_IMMUNE_LEVEL 450
|
||||
#define CLEARMODE_LEVEL 400
|
||||
#define XADMIN_LEVEL 750
|
||||
|
||||
#define AUTO_KICK_SHIT_LEVEL 75
|
||||
#define NO_OP_SHIT_LEVEL 20
|
||||
#define SHITLIST_DEFAULT_TIME (24*3) /* hours */
|
||||
#define SUSPEND_TIME_FOR_OPPING_A_SHITLISTED_USER 600 /* seconds */
|
||||
#define SUSPEND_TIME_FOR_BANNING_A_PROTECTED_USER 600 /* seconds */
|
||||
#define DEOPME_SUSPEND_TIME 3600 /* seconds */
|
||||
#define DEOP_SHITLIST_TIME 1 /* hours */
|
||||
#define DEOP_SHITLIST_LEVEL 20
|
||||
#define MAX_BAN 50
|
||||
|
||||
#define MIN_LASTSEEN (3*24*3600) /* 3 days */
|
||||
|
||||
#define HTTP_LISTEN 1
|
||||
#define HTTP_ACTIVE 2
|
||||
#define HTTP_ENDING 3
|
||||
#define HTTP_RECV_POST 4
|
||||
#define HTTP_PIPE 5
|
||||
#define HTTP_CSRAW 6
|
||||
#define HTTP_CHAT 7
|
||||
#define HTTP_ERROR 0
|
||||
|
||||
#define MISC_GETPATCH 1
|
||||
#define MISC_PIPE_PATCH 2
|
||||
#define MISC_PIPE_MAKE 3
|
||||
|
||||
#define MISC_ERROR -1
|
||||
#define MISC_CONNECTING 1
|
||||
#define MISC_HANDSHAKE 2
|
||||
#define MISC_RECV 3
|
||||
|
||||
#define BUFFER_BLOCK_SIZE 512
|
||||
|
||||
#define CACHE_TIMEOUT 4800 /* 1.5 hours */
|
||||
|
||||
#define AUTOTOPIC_FREQ 1800 /* 30 minutes*/
|
||||
189
Sources/events.c
Normal file
189
Sources/events.c
Normal file
@@ -0,0 +1,189 @@
|
||||
/* @(#)$Id: events.c,v 1.6 1998/01/02 18:30:09 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
|
||||
void InitEvent(void)
|
||||
{
|
||||
AddEvent(EVENT_SAVESHITLIST, now + SHITLIST_SAVE_FREQ + 300, "");
|
||||
AddEvent(EVENT_SAVEDEFCHANNELS, now + DEFS_SAVE_FREQ + 600, "");
|
||||
AddEvent(EVENT_SYNC, now + SYNC_FREQ + 900, "");
|
||||
AddEvent(EVENT_CHECK_IDLE, now + CHECK_IDLE_FREQ, "");
|
||||
AddEvent(EVENT_RENAME_LOGFILE, now + RENAME_LOGFILE_FREQ, "");
|
||||
AddEvent(EVENT_SYNCDB, now + CACHE_TIMEOUT, "");
|
||||
#ifdef CHANNEL_LOG
|
||||
AddEvent(EVENT_LOG_CHANNEL, now + CHANNEL_LOG_FREQ, "");
|
||||
#endif
|
||||
#ifdef NICKSERV
|
||||
AddEvent(EVENT_SAVENICKSERV, now + NSERV_SAVE_FREQ, "");
|
||||
#endif
|
||||
}
|
||||
|
||||
void AddEvent(int event, time_t time, char *param)
|
||||
{
|
||||
register anevent **curr = &EventList;
|
||||
register anevent *new;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("AddEvent( %d, %ld, %s)\n", event, time, param);
|
||||
#endif
|
||||
|
||||
/* the events are store in ascending time order, so the new
|
||||
* event is inserted before the first event with a greater
|
||||
* time
|
||||
*/
|
||||
while (*curr && (*curr)->time < time)
|
||||
curr = &(*curr)->next;
|
||||
|
||||
/* create a new event structure
|
||||
*/
|
||||
new = (anevent *) MALLOC(sizeof(anevent));
|
||||
new->time = time;
|
||||
new->event = event;
|
||||
strncpy(new->param, param, 79);
|
||||
new->param[79] = '\0';
|
||||
|
||||
/* link the new structure to the list
|
||||
*/
|
||||
new->next = *curr;
|
||||
*curr = new;
|
||||
}
|
||||
|
||||
void CheckEvent(void)
|
||||
{
|
||||
register anevent *curr;
|
||||
register achannel *chan;
|
||||
|
||||
while (EventList != NULL && EventList->time <= now)
|
||||
{
|
||||
/* remove the event from the list */
|
||||
curr = EventList;
|
||||
EventList = EventList->next;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Scheduled event %d\n", curr->event);
|
||||
#endif
|
||||
switch (curr->event)
|
||||
{
|
||||
case EVENT_SAVEUSERLIST:
|
||||
/* replaced by SYNCDB */
|
||||
break;
|
||||
|
||||
case EVENT_SAVESHITLIST:
|
||||
SaveShitList("", "");
|
||||
AddEvent(EVENT_SAVESHITLIST,
|
||||
now + SHITLIST_SAVE_FREQ, "");
|
||||
break;
|
||||
|
||||
case EVENT_SAVEDEFCHANNELS:
|
||||
SaveDefs("");
|
||||
AddEvent(EVENT_SAVEDEFCHANNELS,
|
||||
now + DEFS_SAVE_FREQ, "");
|
||||
break;
|
||||
|
||||
case EVENT_CLEANSHITLIST:
|
||||
CleanShitList("", curr->param);
|
||||
break;
|
||||
|
||||
case EVENT_FLUSHMODEBUFF:
|
||||
flushmode(curr->param);
|
||||
break;
|
||||
|
||||
case EVENT_GETOPS:
|
||||
chan = ToChannel(curr->param);
|
||||
if (chan != NULL && chan->on &&
|
||||
(IsOpless(curr->param) ||
|
||||
((chan->flags & CFL_ALWAYSOP) &&
|
||||
!chan->AmChanOp)))
|
||||
GetOps(curr->param);
|
||||
break;
|
||||
|
||||
case EVENT_SYNC:
|
||||
sync();
|
||||
AddEvent(EVENT_SYNC,
|
||||
now + SYNC_FREQ, "");
|
||||
break;
|
||||
|
||||
case EVENT_CLEAN_IGNORES:
|
||||
CleanIgnores();
|
||||
break;
|
||||
|
||||
case EVENT_CHECK_IDLE:
|
||||
CheckIdleChannels();
|
||||
AddEvent(EVENT_CHECK_IDLE, now + CHECK_IDLE_FREQ, "");
|
||||
break;
|
||||
|
||||
case EVENT_RENAME_LOGFILE:
|
||||
log("Closing log file");
|
||||
close(logfile);
|
||||
rename(LOGFILE, LOGFILEBAK);
|
||||
logfile = open(LOGFILE, O_WRONLY | O_CREAT | O_APPEND, 0600); /* "a" in case rename() fails */
|
||||
log("Opening log file");
|
||||
AddEvent(EVENT_RENAME_LOGFILE, now + RENAME_LOGFILE_FREQ, "");
|
||||
break;
|
||||
|
||||
case EVENT_SYNCDB:
|
||||
if (DB_Save_Status == -1)
|
||||
{
|
||||
DB_Save_Status = 0;
|
||||
*DB_Save_Nick = '\0';
|
||||
}
|
||||
/*SaveUserList("",""); */
|
||||
/*
|
||||
gather_sync_channels();
|
||||
if(DBSync==NULL)
|
||||
sync_next_channel();
|
||||
sync_next_channel();
|
||||
*/
|
||||
AddEvent(EVENT_SYNCDB, now + CACHE_TIMEOUT, "");
|
||||
break;
|
||||
|
||||
#ifdef CHANNEL_LOG
|
||||
case EVENT_LOG_CHANNEL:
|
||||
LogChan();
|
||||
AddEvent(EVENT_LOG_CHANNEL, now + CHANNEL_LOG_FREQ, "");
|
||||
break;
|
||||
#endif
|
||||
#ifdef NICKSERV
|
||||
case EVENT_CHECKREGNICK:
|
||||
nserv_checkregnick(curr->param);
|
||||
break;
|
||||
|
||||
case EVENT_SAVENICKSERV:
|
||||
nserv_save();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
#ifdef DEBUG
|
||||
printf("Err.. unknown event %d\n", curr->event);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
TTLALLOCMEM -= sizeof(anevent);
|
||||
free(curr);
|
||||
}
|
||||
}
|
||||
40
Sources/events.h
Normal file
40
Sources/events.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/* @(#)$Id: events.h,v 1.4 1997/07/01 21:51:08 cvs Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#define EVENT_SAVEUSERLIST 1
|
||||
#define EVENT_SAVESHITLIST 2
|
||||
#define EVENT_SAVEDEFCHANNELS 3
|
||||
#define EVENT_SYNC 4
|
||||
#define EVENT_CLEANSHITLIST 5
|
||||
#define EVENT_FLUSHMODEBUFF 6
|
||||
#define EVENT_GETOPS 7
|
||||
#define EVENT_CLEAN_IGNORES 8
|
||||
#define EVENT_CHECK_IDLE 9
|
||||
#define EVENT_RENAME_LOGFILE 10
|
||||
#define EVENT_LOG_CHANNEL 11
|
||||
#define EVENT_SYNCDB 12
|
||||
#define EVENT_CHECKREGNICK 13
|
||||
#define EVENT_SAVENICKSERV 14
|
||||
203
Sources/fixdb.c
Normal file
203
Sources/fixdb.c
Normal file
@@ -0,0 +1,203 @@
|
||||
/* @(#)$Id: fixdb.c,v 1.5 1998/01/12 20:02:17 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
#include "dirent.h"
|
||||
#define SPECFILE "special.log"
|
||||
|
||||
struct node
|
||||
{
|
||||
dbuser dbu;
|
||||
struct node *next;
|
||||
};
|
||||
|
||||
unsigned long ttlread = 0L, ttlwrite = 0L;
|
||||
time_t now;
|
||||
|
||||
void SpecLog(char *text)
|
||||
{
|
||||
int fd;
|
||||
char date[80], buffer[1024];
|
||||
strcpy(date, ctime(&now));
|
||||
*strchr(date, '\n') = '\0';
|
||||
|
||||
if ((fd = open(SPECFILE, O_WRONLY | O_CREAT | O_APPEND, 0600)) >= 0)
|
||||
{
|
||||
sprintf(buffer, "%s: %s\n", date, text);
|
||||
write(fd, buffer, strlen(buffer));
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void fix_user_file(char *file, char *channel)
|
||||
{
|
||||
char tmpfile[256], buffer[200];
|
||||
struct node *List = NULL, *tmp;
|
||||
dbuser dbu;
|
||||
int fd;
|
||||
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
fprintf(stderr, "Can't open %s [%s]\n", file, sys_errlist[errno]);
|
||||
return;
|
||||
}
|
||||
|
||||
while (read(fd, &dbu, sizeof(dbuser)) == sizeof(dbuser))
|
||||
{
|
||||
ttlread += sizeof(dbuser);
|
||||
|
||||
if (dbu.header[0] != 0xFF || dbu.header[1] != 0xFF ||
|
||||
dbu.footer[0] != 0xFF || dbu.footer[1] != 0xFF)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (strcasecmp(channel, dbu.channel))
|
||||
continue;
|
||||
|
||||
if (!strcmp(dbu.match, "!DEL!"))
|
||||
continue;
|
||||
|
||||
if (dbu.lastseen + USERLIST_EXP_TIME <= now)
|
||||
{
|
||||
sprintf(buffer, "Exp: %s [%s] (%d) on %s",
|
||||
dbu.nick, dbu.match, dbu.access, dbu.channel);
|
||||
SpecLog(buffer);
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp = (struct node *)malloc(sizeof(struct node));
|
||||
memcpy(&tmp->dbu, &dbu, sizeof(dbuser));
|
||||
tmp->next = List;
|
||||
List = tmp;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
sprintf(tmpfile, "%s.new", file);
|
||||
|
||||
fd = open(tmpfile, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||
if (fd < 0)
|
||||
{
|
||||
fprintf(stderr, "Can't open %s\n", tmpfile);
|
||||
/* don't return.. need to free the list! */
|
||||
}
|
||||
|
||||
while ((tmp = List) != NULL)
|
||||
{
|
||||
write(fd, &tmp->dbu, sizeof(dbuser));
|
||||
ttlwrite += sizeof(dbuser);
|
||||
List = List->next;
|
||||
free(tmp);
|
||||
}
|
||||
close(fd);
|
||||
|
||||
if (fd >= 0)
|
||||
rename(tmpfile, file);
|
||||
}
|
||||
|
||||
void fix_user_db(void)
|
||||
{
|
||||
DIR *dp;
|
||||
struct dirent *ent;
|
||||
char dir[256], file[256], channel[80], *ptr;
|
||||
int count;
|
||||
|
||||
for (count = 0; count < 1000; count++)
|
||||
{
|
||||
sprintf(dir, "db/channels/%04X", count);
|
||||
dp = opendir(dir);
|
||||
if (dp == NULL)
|
||||
{
|
||||
fprintf(stderr, "Can't read %s [%s]\n", dir, sys_errlist[errno]);
|
||||
continue;
|
||||
}
|
||||
while ((ent = readdir(dp)) != NULL)
|
||||
{
|
||||
if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
|
||||
continue;
|
||||
strcpy(channel, ent->d_name);
|
||||
for (ptr = channel; *ptr; ptr++)
|
||||
if (*ptr == ' ')
|
||||
*ptr = '/';
|
||||
sprintf(file, "db/channels/%04X/%s", count, ent->d_name);
|
||||
|
||||
/* If no comma in channel name, proceed with clean up */
|
||||
if (strchr(channel, ',') == NULL)
|
||||
fix_user_file(file, channel);
|
||||
}
|
||||
closedir(dp);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int pid = 0;
|
||||
FILE *fp;
|
||||
|
||||
if (chdir(HOMEDIR) < 0)
|
||||
{
|
||||
perror(HOMEDIR);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((fp = fopen(PIDFILE, "r")) != NULL)
|
||||
{
|
||||
fscanf(fp, "%d", &pid);
|
||||
fclose(fp);
|
||||
if (!kill((pid_t) pid, 0))
|
||||
{
|
||||
fprintf(stderr, "Detected cs is running [pid %d]. Abort.\n", pid);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (rename("cs", "cs.fixdb") < 0)
|
||||
{
|
||||
perror("rename");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (symlink("/bin/true", "cs") < 0)
|
||||
{
|
||||
perror("symlink");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
time(&now);
|
||||
|
||||
fix_user_db();
|
||||
|
||||
if (unlink("cs") < 0)
|
||||
perror("unlink");
|
||||
|
||||
if (rename("cs.fixdb", "cs") < 0)
|
||||
perror("rename");
|
||||
|
||||
printf("ttlread= %ld ttlwrite= %ld\n", ttlread, ttlwrite);
|
||||
|
||||
return 0;
|
||||
}
|
||||
36
Sources/flags.h
Normal file
36
Sources/flags.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/* @(#)$Id: flags.h,v 1.4 1996/11/13 00:40:39 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#define UFL_AUTOOP 1
|
||||
/*#define UFL_PROTECT 2*/
|
||||
|
||||
#define CFL_NOOP 1
|
||||
#define CFL_ALWAYSOP 2
|
||||
#define CFL_OPONLY 4
|
||||
#define CFL_STRICTOP 8
|
||||
#define CFL_AUTOTOPIC 16
|
||||
|
||||
#define LFL_ISOPER 1
|
||||
135
Sources/floodpro.c
Normal file
135
Sources/floodpro.c
Normal file
@@ -0,0 +1,135 @@
|
||||
/* @(#)$Id: floodpro.c,v 1.4 1999/04/04 17:00:06 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
|
||||
int CheckFlood(char *source, char *channel, int length)
|
||||
{
|
||||
char buffer[200];
|
||||
register achannel *chan;
|
||||
register auser *user;
|
||||
register amsg *msg, *prev;
|
||||
register int count = 0;
|
||||
|
||||
chan = ToChannel(channel);
|
||||
user = ToUser(channel, source);
|
||||
|
||||
if (!chan || !chan->on || !user)
|
||||
return 0;
|
||||
|
||||
/* BEGINNING OF FLOOD PROTECTION ROUTINE */
|
||||
/* 1st clean msghist older than 15 seconds */
|
||||
prev = NULL;
|
||||
msg = user->msghist;
|
||||
while (msg)
|
||||
{
|
||||
if (msg->time < (now - 15))
|
||||
{
|
||||
if (prev)
|
||||
{
|
||||
prev->next = msg->next;
|
||||
TTLALLOCMEM -= sizeof(amsg);
|
||||
free(msg);
|
||||
msg = prev->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
user->msghist = msg->next;
|
||||
TTLALLOCMEM -= sizeof(amsg);
|
||||
free(msg);
|
||||
msg = user->msghist;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prev = msg;
|
||||
msg = msg->next;
|
||||
}
|
||||
}
|
||||
/* now add the current msg to the history */
|
||||
msg = (amsg *) MALLOC(sizeof(amsg));
|
||||
msg->time = now;
|
||||
msg->length = length;
|
||||
msg->next = user->msghist;
|
||||
user->msghist = msg;
|
||||
|
||||
/* now count the number of entry in the history..
|
||||
if it's greater than the max allowed... bite! */
|
||||
|
||||
count = 0;
|
||||
for (msg = user->msghist; msg; msg = msg->next, count++);
|
||||
|
||||
if (chan->MsgFloodPro != 0 && count == chan->MsgFloodPro)
|
||||
{
|
||||
notice(source, "### FLOOD PROTECTION ACTIVATED ###");
|
||||
sprintf(buffer, "%s!%s@%s %d", user->N->nick,
|
||||
user->N->username, user->N->site, PUBLIC_FLOOD_SUSPEND_TIME);
|
||||
suspend("", channel, buffer);
|
||||
|
||||
count = IsShit(channel, source, NULL, NULL);
|
||||
#ifdef DEBUG
|
||||
printf("Argh! %s has a shit level %d\n", source, count);
|
||||
#endif
|
||||
sprintf(buffer, "FLOODPRO ACTIVATED BY %s ON %s", source, channel);
|
||||
log(buffer);
|
||||
|
||||
switch (count)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
log("First warning");
|
||||
sprintf(buffer, "%s That was not very smart!", source);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
log("Second warning");
|
||||
sprintf(buffer, "%s You're pushing your luck too far!", source);
|
||||
break;
|
||||
|
||||
default:
|
||||
sprintf(buffer, "%s That was one time too many", source);
|
||||
}
|
||||
|
||||
kick("", channel, buffer);
|
||||
|
||||
sprintf(buffer, "%s %d %d *** FLOOD ***",
|
||||
user->N->nick,
|
||||
PUBLIC_FLOOD_SHITLIST_TIME,
|
||||
(count < 10) ? count + 5 :
|
||||
PUBLIC_FLOOD_SHITLIST_LEVEL);
|
||||
AddToShitList("", channel, buffer, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
105
Sources/globalvar.h
Normal file
105
Sources/globalvar.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/* @(#)$Id: globalvar.h,v 1.12 2000/10/24 15:15:53 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#if !defined(__FreeBSD__) && !defined(__linux__)
|
||||
|
||||
extern int errno;
|
||||
extern char *sys_errlist[];
|
||||
#endif
|
||||
extern char mynick[NICK_LENGTH];
|
||||
extern char myuser[USERNAME_LENGTH];
|
||||
extern char mysite[SITE_LENGTH];
|
||||
extern char myrealname[REALNAME_LENGTH];
|
||||
extern char server[SERVER_NAME_LENGTH];
|
||||
extern int logfile;
|
||||
extern RegUser *UserList[1000];
|
||||
extern ShitUser *ShitList[1000];
|
||||
extern aluser *Lusers[1000];
|
||||
extern achannel *ChannelList[1000];
|
||||
extern adefchan *DefChanList;
|
||||
extern anevent *EventList;
|
||||
extern aserver *ServerList;
|
||||
extern aserver VirtualServer;
|
||||
extern dbquery *DBQuery;
|
||||
extern dbsync *DBSync;
|
||||
extern syncchan *SyncChan;
|
||||
#ifdef DOHTTP
|
||||
extern http_socket *HttpList;
|
||||
extern http_file_pipe *FilePipes;
|
||||
#endif
|
||||
extern misc_socket *MiscList;
|
||||
extern irc_socket Irc;
|
||||
extern char *TmpPtr;
|
||||
extern time_t now;
|
||||
extern time_t logTS;
|
||||
extern time_t TSoffset;
|
||||
extern time_t TSonline;
|
||||
extern time_t TSconnect;
|
||||
extern unsigned long long TTLREADBYTES;
|
||||
extern unsigned long long TTLSENTBYTES;
|
||||
extern unsigned long TTLALLOCMEM;
|
||||
extern unsigned long long HTTPTTLSENTBYTES;
|
||||
extern alang Lang[NO_LANG];
|
||||
extern char *replies[][NO_LANG];
|
||||
#ifdef FAKE_UWORLD
|
||||
extern int Uworld_status;
|
||||
extern time_t UworldTS,UworldServTS;
|
||||
#endif
|
||||
#ifdef NICKSERV
|
||||
extern int NServ_status;
|
||||
#endif
|
||||
extern unsigned long MEM_buffers;
|
||||
extern unsigned long NB_avail_buffer_blocks;
|
||||
extern unsigned long NB_alloc_buffer_blocks;
|
||||
extern long CurrentSendQ;
|
||||
|
||||
extern int DB_Save_Status;
|
||||
extern char DB_Save_Nick[NICK_LENGTH];
|
||||
|
||||
#define MALLOC(X) ((TmpPtr=(char *)malloc(X))? \
|
||||
TmpPtr : (char *)quit("ERROR: malloc() failed", 1));\
|
||||
TTLALLOCMEM+=X
|
||||
|
||||
#define close(X) if((X)>=0) close(X)
|
||||
#define ABS(X) ((X>0)?(X):(-(X)))
|
||||
|
||||
/* I use '}' and ']' instead of 'z' and 'Z'
|
||||
* in order to respect RFC-1459 (section 2.2)
|
||||
*/
|
||||
#undef toupper
|
||||
#undef tolower
|
||||
#if 0
|
||||
#define toupper(X) ( ((X)>='a'&&(X)<='~') ? ((X)&223) : (X) )
|
||||
#define tolower(X) ( ((X)>='A'&&(X)<='^') ? ((X)|32) : (X) )
|
||||
#endif
|
||||
#define toupper(X) ( ((X)>='a'&&(X)<='~') || ((unsigned char)(X)>=0xe0&&(unsigned char)(X)<=0xff&&(unsigned char)(X)!=0xf7)? ((X)&223) : (X) )
|
||||
#define tolower(X) ( ((X)>='A'&&(X)<='^') || ((unsigned char)(X)>=0xc0&&(unsigned char)(X)<=0xdf&&(unsigned char)(X)!=0xd7)? ((X)|32) : (X) )
|
||||
|
||||
#define touppertmp(X) ( ((X)>='a'&&(X)<='~') || ((unsigned char)(X)>=0xe0&&(unsigned char)(X)<=0xff&&(unsigned char)(X)!=0xf7)? ((X)&223) : (X) )
|
||||
#define tolowertmp(X) ( ((X)>='A'&&(X)<='^') || ((unsigned char)(X)>=0xc0&&(unsigned char)(X)<=0xdf&&(unsigned char)(X)!=0xd7)? ((X)|32) : (X) )
|
||||
|
||||
#define strcasecmp mycasecmp
|
||||
#define strcmp mycasecmp
|
||||
56
Sources/h.h
Normal file
56
Sources/h.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/* @(#)$Id: h.h,v 1.3 1996/11/13 00:40:40 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/resource.h>
|
||||
#include "../config.h"
|
||||
#include "debug.h"
|
||||
#include "defines.h"
|
||||
#include "struct.h"
|
||||
#include "lang.h"
|
||||
#include "replies.h"
|
||||
#include "prototypes.h"
|
||||
#include "globalvar.h"
|
||||
#include "events.h"
|
||||
#include "flags.h"
|
||||
#include "dbio.h"
|
||||
#include "version.h"
|
||||
761
Sources/help.c
Normal file
761
Sources/help.c
Normal file
@@ -0,0 +1,761 @@
|
||||
/* @(#)$Id: help.c,v 1.22 2000/10/02 00:55:13 lgm Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
|
||||
static struct item
|
||||
{
|
||||
char *name;
|
||||
int Access;
|
||||
char *file;
|
||||
}
|
||||
commands[] =
|
||||
{
|
||||
{
|
||||
"showcommands", 0, "SHOWCOMMANDS"
|
||||
}
|
||||
,
|
||||
{
|
||||
"status", STATUS_ACCESS, "STATUS"
|
||||
}
|
||||
,
|
||||
{
|
||||
"join", LEVEL_JOIN, "JOIN"
|
||||
}
|
||||
,
|
||||
{
|
||||
"invite", INVITE_LEVEL, "INVITE"
|
||||
}
|
||||
,
|
||||
{
|
||||
"part", LEVEL_PART, "JOIN"
|
||||
}
|
||||
,
|
||||
{
|
||||
"topic", TOPIC_LEVEL, "TOPIC"
|
||||
}
|
||||
,
|
||||
{
|
||||
"kick", KICK_LEVEL, "KICK"
|
||||
}
|
||||
,
|
||||
{
|
||||
"ban", BAN_LEVEL, "BAN"
|
||||
}
|
||||
,
|
||||
{
|
||||
"unban", BAN_LEVEL, "BAN"
|
||||
}
|
||||
,
|
||||
{
|
||||
"banlist", 0, "BAN"
|
||||
}
|
||||
,
|
||||
{
|
||||
"lbanlist", 0, "BAN"
|
||||
}
|
||||
,
|
||||
{
|
||||
"adduser", ADD_USER_LEVEL, "ADDUSER"
|
||||
}
|
||||
,
|
||||
{
|
||||
"access", SHOW_ACCESS_LEVEL, "ACCESS"
|
||||
}
|
||||
,
|
||||
{
|
||||
"verify", 0, "VERIFY"
|
||||
}
|
||||
,
|
||||
{
|
||||
"remuser", REMOVE_USER_LEVEL, "ADDUSER"
|
||||
}
|
||||
,
|
||||
{
|
||||
"modinfo", MOD_USERINFO_LEVEL, "ADDUSER"
|
||||
}
|
||||
,
|
||||
{
|
||||
"purge", XADMIN_LEVEL, "XADMIN"
|
||||
}
|
||||
,
|
||||
{
|
||||
"isreg", 0, "ISREG"
|
||||
}
|
||||
,
|
||||
{
|
||||
"set", CH_FLOOD_LIMIT_LEVEL, "SET"
|
||||
}
|
||||
,
|
||||
{
|
||||
"suspend", LEVEL_SUSPEND, "SUSPEND"
|
||||
}
|
||||
,
|
||||
{
|
||||
"unsuspend", LEVEL_SUSPEND, "SUSPEND"
|
||||
}
|
||||
,
|
||||
{
|
||||
"saveuserlist", SAVE_USERLIST_LEVEL, "SAVEUSERLIST"
|
||||
}
|
||||
,
|
||||
{
|
||||
"addchan", SET_DEFAULT_LEVEL, "DEFCHAN"
|
||||
}
|
||||
,
|
||||
{
|
||||
"remchan", SET_DEFAULT_LEVEL, "DEFCHAN"
|
||||
}
|
||||
,
|
||||
{
|
||||
"savedefs", SAVE_DEFAULTS_LEVEL, "DEFCHAN"
|
||||
}
|
||||
,
|
||||
{
|
||||
"loaddefs", LOAD_DEFAULT_LEVEL, "LOADDEFS"
|
||||
}
|
||||
,
|
||||
{
|
||||
"savebanlist", SAVE_SHITLIST_LEVEL, "SAVEBANLIST"
|
||||
}
|
||||
,
|
||||
{
|
||||
"loadbanlist", LOAD_SHITLIST_LEVEL, "LOADBANLIST"
|
||||
}
|
||||
,
|
||||
{
|
||||
"pass", 0, "PASSWORD"
|
||||
}
|
||||
,
|
||||
{
|
||||
"login", 0, "PASSWORD"
|
||||
}
|
||||
,
|
||||
{
|
||||
"newpass", 0, "PASSWORD"
|
||||
}
|
||||
,
|
||||
{
|
||||
"deauth", 0, "PASSWORD"
|
||||
}
|
||||
,
|
||||
{
|
||||
"die", LEVEL_DIE, "DIE"
|
||||
}
|
||||
,
|
||||
{
|
||||
"restart", LEVEL_DIE, "RESTART"
|
||||
}
|
||||
,
|
||||
{
|
||||
"core", LEVEL_CORE, "CORE"
|
||||
}
|
||||
,
|
||||
{
|
||||
"rusage", RUSAGE_ACCESS, "RUSAGE"
|
||||
}
|
||||
,
|
||||
#ifdef UPGRADE
|
||||
{
|
||||
"upgrade", LEVEL_UPGRADE, "UPGRADE"
|
||||
}
|
||||
,
|
||||
#endif
|
||||
{
|
||||
"op", OP_LEVEL, "OP"
|
||||
}
|
||||
,
|
||||
{
|
||||
"deop", OP_LEVEL, "OP"
|
||||
}
|
||||
,
|
||||
{
|
||||
"clearmode", CLEARMODE_LEVEL, "CLEARMODE"
|
||||
}
|
||||
,
|
||||
{
|
||||
"map", 0, "MAP"
|
||||
}
|
||||
,
|
||||
{
|
||||
"help", 0, "HELP"
|
||||
}
|
||||
,
|
||||
{
|
||||
"motd", 0, "MOTD"
|
||||
}
|
||||
,
|
||||
{
|
||||
"showignore", 0, "SHOWIGNORE"
|
||||
}
|
||||
,
|
||||
{
|
||||
"remignore", XADMIN_LEVEL, "REMIGNORE"
|
||||
}
|
||||
,
|
||||
{
|
||||
"chaninfo", 0, "CHANINFO"
|
||||
}
|
||||
,
|
||||
{
|
||||
NULL, -1, NULL
|
||||
}
|
||||
};
|
||||
static int N = 0;
|
||||
|
||||
static void sort(void)
|
||||
{
|
||||
struct item tmp;
|
||||
register int i, j, k;
|
||||
|
||||
/* sort the command list using a simple bubble sort algo.
|
||||
* 1st sort the commands by decreasing access
|
||||
*/
|
||||
for (i = 0; i < N - 1; i++)
|
||||
{
|
||||
for (j = N - 1; j > i; j--)
|
||||
{
|
||||
if (commands[j - 1].Access < commands[j].Access)
|
||||
{
|
||||
tmp = commands[j - 1];
|
||||
commands[j - 1] = commands[j];
|
||||
commands[j] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Then, sort the commands by alphabetical order
|
||||
*/
|
||||
i = k = 0;
|
||||
while (k < N - 1)
|
||||
{
|
||||
while (commands[k].Access == commands[i].Access)
|
||||
k++;
|
||||
|
||||
while (i < k - 1)
|
||||
{
|
||||
for (j = k - 1; j > i; j--)
|
||||
{
|
||||
if (strcmp(commands[j - 1].name, commands[j].name) > 0)
|
||||
{
|
||||
tmp = commands[j - 1];
|
||||
commands[j - 1] = commands[j];
|
||||
commands[j] = tmp;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
i = k;
|
||||
}
|
||||
}
|
||||
|
||||
static void listinit(void)
|
||||
{
|
||||
static int sorted = 0;
|
||||
|
||||
/* count the number of commands
|
||||
*/
|
||||
if (N == 0)
|
||||
{
|
||||
for (N = 0; commands[N].name != NULL; N++);
|
||||
N--;
|
||||
}
|
||||
|
||||
/* sort the list if not already done
|
||||
*/
|
||||
if (!sorted)
|
||||
{
|
||||
sort();
|
||||
sorted = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void showcommands(char *source, char *chan, char *args)
|
||||
{
|
||||
char buffer[500];
|
||||
char channel[80];
|
||||
register aluser *luser;
|
||||
register int useraccess;
|
||||
register int i, j;
|
||||
|
||||
if (*args == '#' || *args == '*')
|
||||
GetWord(0, args, channel);
|
||||
else
|
||||
{
|
||||
strcpy(channel, chan);
|
||||
GuessChannel(source, channel);
|
||||
}
|
||||
|
||||
luser = ToLuser(source);
|
||||
if (!luser)
|
||||
return;
|
||||
|
||||
if (!strcmp(channel, "*") && !IsValid(luser, channel))
|
||||
{
|
||||
notice(source, "SYNTAX: showcommands <channel>");
|
||||
return;
|
||||
}
|
||||
|
||||
useraccess = LAccess(channel, luser);
|
||||
|
||||
listinit();
|
||||
|
||||
/* Now show the sorted command list to the user.
|
||||
*/
|
||||
i = useraccess;
|
||||
sprintf(buffer, "Level%5d:", i);
|
||||
|
||||
for (j = 0; j < N + 1; j++)
|
||||
{
|
||||
if (commands[j].Access < i)
|
||||
{
|
||||
if (strlen(buffer) > 13)
|
||||
notice(source, buffer);
|
||||
i = commands[j].Access;
|
||||
sprintf(buffer, "Level%5d:", i);
|
||||
}
|
||||
|
||||
if (commands[j].Access <= useraccess)
|
||||
{
|
||||
strcat(buffer, " ");
|
||||
strcat(buffer, commands[j].name);
|
||||
}
|
||||
}
|
||||
|
||||
notice(source, buffer);
|
||||
}
|
||||
|
||||
void showhelp(char *source, char *chan, char *args)
|
||||
{
|
||||
struct buffer_block *dyn = NULL;
|
||||
char buffer[512], word[80], *ptr;
|
||||
int i, l, index = 0, found = 0, file, linecount = 0;
|
||||
|
||||
if (CurrentSendQ > HIGHSENDQTHRESHOLD)
|
||||
{
|
||||
notice(source, "Cannot process your request at this time. Try again later.");
|
||||
return;
|
||||
}
|
||||
|
||||
GetWord(0, args, word);
|
||||
if (!*word)
|
||||
strcpy(word, "help");
|
||||
|
||||
listinit();
|
||||
|
||||
/* find the command index */
|
||||
for (i = 0; i <= N; i++)
|
||||
{
|
||||
if (!strcasecmp(word, commands[i].name))
|
||||
{
|
||||
found = 1;
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
else if (!strncasecmp(word, commands[i].name, strlen(word)))
|
||||
{
|
||||
found++;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (found > 1)
|
||||
{
|
||||
sprintf(buffer, "%s is ambiguous", word);
|
||||
notice(source, buffer);
|
||||
return;
|
||||
}
|
||||
else if (found == 0)
|
||||
{
|
||||
if (!strcasecmp(word, "INFO"))
|
||||
{
|
||||
sprintf(buffer, "%s/INFO", HELP_DIR);
|
||||
}
|
||||
else if (!strcasecmp(word, "FORM"))
|
||||
{
|
||||
sprintf(buffer, "%s/FORM", HELP_DIR);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buffer, "No help on %s. Please use "
|
||||
"showcommands to get a list of commands "
|
||||
"available to you", word);
|
||||
notice(source, buffer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buffer, "%s/%s", HELP_DIR, commands[index].file);
|
||||
}
|
||||
|
||||
alarm(2);
|
||||
file = open(buffer, O_RDONLY);
|
||||
alarm(0);
|
||||
if (file < 0)
|
||||
{
|
||||
if (found)
|
||||
sprintf(buffer, "The help file for command %s "
|
||||
"is not available", commands[index].name);
|
||||
else
|
||||
sprintf(buffer, "This help file is not available");
|
||||
|
||||
notice(source, buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
sprintf(buffer,
|
||||
" HELP on %-20s Minimum access: %4d ",
|
||||
commands[index].name, commands[index].Access);
|
||||
notice(source, buffer);
|
||||
}
|
||||
|
||||
alarm(3);
|
||||
while ((l = read(file, buffer, 511)) > 0)
|
||||
{
|
||||
copy_to_buffer(&dyn, buffer, l);
|
||||
}
|
||||
alarm(0);
|
||||
close(file);
|
||||
|
||||
while (dyn != NULL)
|
||||
{
|
||||
copy_from_buffer(&dyn, buffer, '\n', 199);
|
||||
if ((ptr = strchr(buffer, '\n')) != NULL)
|
||||
*ptr = '\0';
|
||||
else
|
||||
continue;
|
||||
if (*buffer == '\0')
|
||||
strcpy(buffer, " ");
|
||||
string_swap(buffer, 512, "$NICK", mynick);
|
||||
string_swap(buffer, 512, "$SERVER", SERVERNAME);
|
||||
notice(source, buffer);
|
||||
linecount++;
|
||||
}
|
||||
|
||||
if (linecount > 0)
|
||||
CheckFloodFlood(source, linecount);
|
||||
}
|
||||
|
||||
void showmotd(char *source)
|
||||
{
|
||||
struct buffer_block *dyn = NULL;
|
||||
char buffer[512];
|
||||
int fd, l;
|
||||
|
||||
alarm(3);
|
||||
fd = open(MOTD_FILE, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
notice(source, "MOTD is empty");
|
||||
return;
|
||||
}
|
||||
|
||||
if (CurrentSendQ > HIGHSENDQTHRESHOLD)
|
||||
{
|
||||
notice(source, "Cannot process your request at this time. Try again later.");
|
||||
return;
|
||||
}
|
||||
|
||||
while ((l = read(fd, buffer, 511)) > 0)
|
||||
{
|
||||
copy_to_buffer(&dyn, buffer, l);
|
||||
}
|
||||
close(fd);
|
||||
alarm(0);
|
||||
|
||||
while (dyn != NULL)
|
||||
{
|
||||
char *ptr;
|
||||
copy_from_buffer(&dyn, buffer, '\n', 199);
|
||||
if ((ptr = strchr(buffer, '\n')) != NULL)
|
||||
*ptr = '\0';
|
||||
else
|
||||
continue;
|
||||
if (*buffer == '\0')
|
||||
strcpy(buffer, " ");
|
||||
notice(source, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
chaninfo_callback(int *fd, off_t off, int action, void *hook1, void *hook2,
|
||||
dbuser * dbu, int count)
|
||||
{
|
||||
char buffer[512];
|
||||
register adefchan *def;
|
||||
time_t t;
|
||||
|
||||
if (count == 1 && dbu != NULL)
|
||||
{
|
||||
sprintf(buffer, "%s is registered by:", (char *)hook2);
|
||||
notice((char *)hook1, buffer);
|
||||
}
|
||||
|
||||
if (dbu == NULL)
|
||||
{
|
||||
if (count == 0)
|
||||
{
|
||||
notice((char *)hook1, "That channel is not registered");
|
||||
}
|
||||
else
|
||||
{
|
||||
def = DefChanList;
|
||||
while (def && strcasecmp(def->name, (char *)hook2))
|
||||
def = def->next;
|
||||
|
||||
if (def)
|
||||
{
|
||||
if (*def->topic)
|
||||
{
|
||||
sprintf(buffer, "Desc: %s", def->topic);
|
||||
notice((char *)hook1, buffer);
|
||||
}
|
||||
if (*def->url)
|
||||
{
|
||||
sprintf(buffer, "URL: %s", def->url);
|
||||
notice((char *)hook1, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(hook1);
|
||||
free(hook2);
|
||||
}
|
||||
else if (dbu->access >= 500)
|
||||
{
|
||||
t = now - dbu->lastseen;
|
||||
|
||||
sprintf(buffer, "%s (%s) last seen: %s ago",
|
||||
dbu->nick, dbu->match,
|
||||
time_remaining(t));
|
||||
notice((char *)hook1, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void ShowChanInfo(char *source, char *chan, char *args)
|
||||
{
|
||||
char channel[80], *hook1, *hook2;
|
||||
|
||||
if (*args == '#')
|
||||
GetWord(0, args, channel);
|
||||
else
|
||||
{
|
||||
strcpy(channel, chan);
|
||||
GuessChannel(source, channel);
|
||||
}
|
||||
|
||||
if (!strcmp(channel, "*"))
|
||||
{
|
||||
notice(source, "SYNTAX: chaninfo <channel>");
|
||||
return;
|
||||
}
|
||||
|
||||
hook1 = (char *)malloc(strlen(source) + 1);
|
||||
strcpy(hook1, source);
|
||||
hook2 = (char *)malloc(strlen(channel) + 1);
|
||||
strcpy(hook2, channel);
|
||||
|
||||
db_fetch(channel, DBGETALLCMP, "", NULL, 0, hook1, hook2, chaninfo_callback);
|
||||
}
|
||||
|
||||
|
||||
void isreg(char *source, char *chan, char *args)
|
||||
{
|
||||
char channel[80], buffer[512];
|
||||
struct stat st;
|
||||
|
||||
if (*args == '#')
|
||||
GetWord(0, args, channel);
|
||||
else
|
||||
{
|
||||
strcpy(channel, chan);
|
||||
GuessChannel(source, channel);
|
||||
}
|
||||
|
||||
if (!strcmp(channel, "*"))
|
||||
{
|
||||
notice(source, "SYNTAX: isreg <channel>");
|
||||
return;
|
||||
}
|
||||
|
||||
if (stat(make_dbfname(channel), &st) < 0)
|
||||
sprintf(buffer, "%s is not registered.",channel);
|
||||
else
|
||||
sprintf(buffer, "%s is registered.",channel);
|
||||
notice(source, buffer);
|
||||
}
|
||||
|
||||
|
||||
#ifdef DOHTTP
|
||||
void http_show_help(http_socket * hsock, char *command)
|
||||
{
|
||||
char buffer[512], buffer2[200];
|
||||
struct buffer_block *dyn = NULL;
|
||||
register char *ptr, *ptr2;
|
||||
register int i, index = 0, found = 0;
|
||||
int file, l;
|
||||
|
||||
listinit();
|
||||
|
||||
/* find the command index */
|
||||
for (i = 0; i <= N; i++)
|
||||
{
|
||||
if (!strcasecmp(command, commands[i].name))
|
||||
{
|
||||
found = 1;
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
else if (!strncasecmp(command, commands[i].name, strlen(command)))
|
||||
{
|
||||
found++;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
buffer[0] = '\0';
|
||||
|
||||
sendto_http(hsock, HTTP_HEADER, command);
|
||||
sendto_http(hsock, HTTP_BODY);
|
||||
|
||||
sendto_http(hsock, "<H1>HELP ON %s</H1>\n", (*command) ? command : "COMMANDS");
|
||||
sendto_http(hsock, "<PRE>\n");
|
||||
|
||||
if (found > 1)
|
||||
{
|
||||
if (*command)
|
||||
sendto_http(hsock, "%s is ambiguous\n", command);
|
||||
}
|
||||
else if (found == 0)
|
||||
{
|
||||
if (!strcasecmp(command, "INFO"))
|
||||
{
|
||||
sprintf(buffer, "%s/INFO", HELP_DIR);
|
||||
}
|
||||
else if (!strcasecmp(command, "FORM"))
|
||||
{
|
||||
sprintf(buffer, "%s/FORM", HELP_DIR);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendto_http(hsock, "No help on %s.\n", command);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buffer, "%s/%s", HELP_DIR, commands[index].file);
|
||||
}
|
||||
|
||||
if (buffer[0] != '\0')
|
||||
{
|
||||
alarm(2);
|
||||
file = open(buffer, O_RDONLY);
|
||||
if (file < 0)
|
||||
{
|
||||
alarm(0);
|
||||
if (found)
|
||||
sendto_http(hsock, "The help file for command %s "
|
||||
"is not available\n", commands[index].name);
|
||||
else
|
||||
sendto_http(hsock, "This help file is not available\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
alarm(2);
|
||||
while ((l = read(file, buffer, 511)) > 0)
|
||||
{
|
||||
copy_to_buffer(&dyn, buffer, l);
|
||||
}
|
||||
alarm(0);
|
||||
close(file);
|
||||
|
||||
while (dyn != NULL)
|
||||
{
|
||||
copy_from_buffer(&dyn, buffer, '\n', 199);
|
||||
if ((ptr = strchr(buffer, '\n')) == NULL)
|
||||
continue;
|
||||
if ((ptr = strstr(buffer, "$NICK")) != NULL)
|
||||
{
|
||||
*ptr = '\0';
|
||||
sprintf(buffer2, "%s%s%s", buffer, mynick, ptr + 5);
|
||||
strcpy(buffer, buffer2);
|
||||
}
|
||||
|
||||
/* Some nasty char quoting required.. */
|
||||
ptr = buffer;
|
||||
ptr2 = buffer2;
|
||||
do
|
||||
{
|
||||
if (*ptr == '<')
|
||||
{
|
||||
ptr2[0] = '&';
|
||||
ptr2[1] = 'l';
|
||||
ptr2[2] = 't';
|
||||
ptr2[3] = ';';
|
||||
ptr2 += 4;
|
||||
}
|
||||
else if (*ptr == '>')
|
||||
{
|
||||
ptr2[0] = '&';
|
||||
ptr2[1] = 'g';
|
||||
ptr2[2] = 't';
|
||||
ptr2[3] = ';';
|
||||
ptr2 += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr2[0] = ptr[0];
|
||||
ptr2++;
|
||||
}
|
||||
}
|
||||
while (*(ptr++) != '\0');
|
||||
sendto_http(hsock, "%s", buffer2);
|
||||
}
|
||||
}
|
||||
sendto_http(hsock, "</PRE>\n");
|
||||
}
|
||||
else
|
||||
{ /* show list of commands */
|
||||
sendto_http(hsock, "</PRE>\n<H2>List of commands:</H2>\n");
|
||||
sendto_http(hsock, "<FONT SIZE=+1>\n");
|
||||
for (i = 0; i < N + 1; i++)
|
||||
{
|
||||
if (commands[i].Access <= 500)
|
||||
sendto_http(hsock, "<A HREF=\"/HELP/%s\">%s</A>\n",
|
||||
commands[i].name, commands[i].name);
|
||||
}
|
||||
sendto_http(hsock, "</FONT><P>\n");
|
||||
}
|
||||
|
||||
sendto_http(hsock, "<HR>%s\n", HTTP_FOOTER);
|
||||
sendto_http(hsock, "</BODY></HTML>\n");
|
||||
hsock->status = HTTP_ENDING;
|
||||
}
|
||||
#endif
|
||||
1427
Sources/http.c
Normal file
1427
Sources/http.c
Normal file
File diff suppressed because it is too large
Load Diff
572
Sources/ignore.c
Normal file
572
Sources/ignore.c
Normal file
@@ -0,0 +1,572 @@
|
||||
/* @(#)$Id: ignore.c,v 1.19 2000/10/24 16:04:24 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
|
||||
typedef struct aprivmsg
|
||||
{
|
||||
char user[200];
|
||||
time_t time;
|
||||
int length;
|
||||
struct aprivmsg *next;
|
||||
}
|
||||
aprivmsg;
|
||||
|
||||
typedef struct aignore
|
||||
{
|
||||
char mask[200];
|
||||
time_t time;
|
||||
struct aignore *next;
|
||||
}
|
||||
aignore;
|
||||
|
||||
|
||||
static aprivmsg *MessageList = NULL;
|
||||
static aprivmsg *FloodList = NULL;
|
||||
static aprivmsg *AddUserFloodList = NULL;
|
||||
static aignore *IgnoreList = NULL;
|
||||
|
||||
void add_silence(char *, char *);
|
||||
void rem_silence(char *);
|
||||
|
||||
int CheckPrivateFlood(char *source, int length, char *type)
|
||||
{
|
||||
char buffer[200];
|
||||
char userhost[200];
|
||||
char global[] = "*";
|
||||
register aluser *user;
|
||||
register aprivmsg *msg, *prev;
|
||||
register int count, size;
|
||||
|
||||
if ((user = ToLuser(source)) == NULL)
|
||||
{
|
||||
sprintf(buffer, "ERROR! CheckPrivateFlood(): %s not found", source);
|
||||
log(buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Don't check flood from admins */
|
||||
if (IsValid(user, global) && Access(global, source) >= 1)
|
||||
return 0;
|
||||
|
||||
if (!strcasecmp(user->username, DEFAULT_USERNAME) &&
|
||||
!strcasecmp(user->site, DEFAULT_HOSTNAME))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* clean messages older than 30 seconds */
|
||||
prev = NULL;
|
||||
msg = MessageList;
|
||||
while (msg != NULL)
|
||||
{
|
||||
if (msg->time < (now - 30))
|
||||
{
|
||||
if (prev)
|
||||
{
|
||||
prev->next = msg->next;
|
||||
TTLALLOCMEM -= sizeof(aprivmsg);
|
||||
free(msg);
|
||||
msg = prev->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageList = msg->next;
|
||||
TTLALLOCMEM -= sizeof(aprivmsg);
|
||||
free(msg);
|
||||
msg = MessageList;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prev = msg;
|
||||
msg = msg->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* now add the current message in the list */
|
||||
sprintf(userhost, "%s@%s", user->username, user->site);
|
||||
msg = (aprivmsg *) MALLOC(sizeof(aprivmsg));
|
||||
strcpy(msg->user, userhost);
|
||||
msg->time = now;
|
||||
msg->length = length;
|
||||
msg->next = MessageList;
|
||||
MessageList = msg;
|
||||
|
||||
/* count how many messages were received from that user
|
||||
* and also how many bytes
|
||||
*/
|
||||
count = size = 0;
|
||||
for (msg = MessageList; msg != NULL; msg = msg->next)
|
||||
{
|
||||
if (compare(userhost, msg->user))
|
||||
{
|
||||
count++;
|
||||
size += msg->length;
|
||||
}
|
||||
}
|
||||
|
||||
if (count >= PRIVATE_FLOOD_RATE || size >= PRIVATE_FLOOD_SIZE)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("FLOODED by %s!%s\n", user->nick, userhost);
|
||||
#endif
|
||||
if (!IsIgnored(source))
|
||||
{
|
||||
sprintf(buffer, "%sFLOOD from %s!%s", type, user->nick, userhost);
|
||||
log(buffer);
|
||||
|
||||
sprintf(buffer, "%sFLOOD from %s!%s (%s)", type,
|
||||
user->nick, userhost, user->server->name);
|
||||
broadcast(buffer, 1);
|
||||
}
|
||||
MakeBanMask(user, buffer);
|
||||
AddIgnore(source, buffer, IGNORE_TIME);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AddIgnore(char *source, char *mask, int t)
|
||||
{
|
||||
char buffer[200];
|
||||
char *site;
|
||||
aignore *curr;
|
||||
int count;
|
||||
|
||||
if (IsIgnored(source))
|
||||
return;
|
||||
|
||||
/* count number of ignores from the same site */
|
||||
site = strchr(mask, '@') + 1;
|
||||
count = 0;
|
||||
curr = IgnoreList;
|
||||
while (curr)
|
||||
{
|
||||
if (!mycasecmp(strchr(curr->mask, '@') + 1, site))
|
||||
count++;
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
/* add the entry in the list */
|
||||
curr = (aignore *) MALLOC(sizeof(aignore));
|
||||
curr->time = now + t;
|
||||
curr->next = IgnoreList;
|
||||
IgnoreList = curr;
|
||||
strcpy(curr->mask, mask);
|
||||
|
||||
add_silence(source, curr->mask);
|
||||
notice(source, "I don't like being flooded! "
|
||||
"I will ignore you from now on.");
|
||||
|
||||
/* schedule ignore removal */
|
||||
AddEvent(EVENT_CLEAN_IGNORES, curr->time, "");
|
||||
|
||||
/* If there are already too many ignores from this site
|
||||
* ignore the whole site
|
||||
*/
|
||||
if (count >= (MAX_IGNORE_PER_SITE - 1))
|
||||
{
|
||||
curr = (aignore *) MALLOC(sizeof(aignore));
|
||||
curr->time = now + 300;
|
||||
curr->next = IgnoreList;
|
||||
IgnoreList = curr;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("TOO MANY IGNORES FROM THE SAME SITE\n");
|
||||
#endif
|
||||
log("Too many ignores.. ignoring the whole site");
|
||||
sprintf(curr->mask, "*!*@%s", site);
|
||||
sprintf(buffer, "Ignoring the whole site! (%s)", site);
|
||||
broadcast(buffer, 1);
|
||||
add_silence(source, curr->mask);
|
||||
AddEvent(EVENT_CLEAN_IGNORES, curr->time, "");
|
||||
}
|
||||
}
|
||||
|
||||
void CleanIgnores(void)
|
||||
{
|
||||
char buffer[200];
|
||||
aignore *curr, *prev;
|
||||
|
||||
prev = NULL;
|
||||
curr = IgnoreList;
|
||||
while (curr != NULL)
|
||||
{
|
||||
if (curr->time <= now)
|
||||
{
|
||||
sprintf(buffer, "Removing ignore for %s", curr->mask);
|
||||
log(buffer);
|
||||
rem_silence(curr->mask);
|
||||
if (prev != NULL)
|
||||
{
|
||||
prev->next = curr->next;
|
||||
TTLALLOCMEM -= sizeof(aignore);
|
||||
free(curr);
|
||||
curr = prev->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
IgnoreList = curr->next;
|
||||
TTLALLOCMEM -= sizeof(aignore);
|
||||
free(curr);
|
||||
curr = IgnoreList;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int IsIgnored(char *nick)
|
||||
{
|
||||
char userhost[200];
|
||||
register aignore *curr;
|
||||
register aluser *user;
|
||||
register int found = 0;
|
||||
|
||||
if ((user = ToLuser(nick)) == NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
sprintf(userhost, "%s!%s@%s", user->nick, user->username, user->site);
|
||||
|
||||
curr = IgnoreList;
|
||||
while (curr != NULL && !found)
|
||||
{
|
||||
if (compare(userhost, curr->mask))
|
||||
{
|
||||
add_silence(nick, curr->mask);
|
||||
found++;
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
return (found);
|
||||
}
|
||||
|
||||
void ShowIgnoreList(char *source, char *channel, char *args)
|
||||
{
|
||||
char buffer[200];
|
||||
aignore *curr = IgnoreList;
|
||||
time_t m;
|
||||
|
||||
if (curr == NULL)
|
||||
{
|
||||
notice(source, "Ignore list is empty");
|
||||
}
|
||||
else
|
||||
{
|
||||
notice(source, "Ignore list:");
|
||||
while (curr != NULL)
|
||||
{
|
||||
m = (curr->time - now) / 60 + 1;
|
||||
sprintf(buffer, "%s for %ld minute%s",
|
||||
curr->mask, m, (m > 1) ? "s" : "");
|
||||
notice(source, buffer);
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void add_silence(char *nick, char *mask)
|
||||
{
|
||||
char buffer[200];
|
||||
|
||||
sprintf(buffer, ":%s SILENCE %s :%s\n", mynick, nick, mask);
|
||||
sendtoserv(buffer);
|
||||
#ifdef FAKE_UWORLD
|
||||
if (Uworld_status == 1)
|
||||
{
|
||||
sprintf(buffer, ":%s SILENCE %s :%s\n", UFAKE_NICK, nick, mask);
|
||||
sendtoserv(buffer);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void rem_silence(char *mask)
|
||||
{
|
||||
char buffer[200];
|
||||
|
||||
sprintf(buffer, ":%s SILENCE * -%s\n", mynick, mask);
|
||||
sendtoserv(buffer);
|
||||
#ifdef FAKE_UWORLD
|
||||
if (Uworld_status == 1)
|
||||
{
|
||||
sprintf(buffer, ":%s SILENCE * -%s\n", UFAKE_NICK, mask);
|
||||
sendtoserv(buffer);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int CheckFloodFlood(char *source, int length)
|
||||
{
|
||||
char buffer[200];
|
||||
char userhost[200];
|
||||
char global[] = "*";
|
||||
register aluser *user;
|
||||
register aprivmsg *msg, *prev;
|
||||
register int count, size;
|
||||
|
||||
if ((user = ToLuser(source)) == NULL)
|
||||
{
|
||||
sprintf(buffer, "ERROR! CheckFloodFlood(): %s not found", source);
|
||||
log(buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Don't check flood from admins */
|
||||
if (IsValid(user, global) && Access(global, source) >= 1)
|
||||
return 0;
|
||||
|
||||
if (!strcasecmp(user->username, DEFAULT_USERNAME) &&
|
||||
!strcasecmp(user->site, DEFAULT_HOSTNAME))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* clean messages older than 30 seconds */
|
||||
prev = NULL;
|
||||
msg = FloodList;
|
||||
while (msg != NULL)
|
||||
{
|
||||
if (msg->time < (now - 30))
|
||||
{
|
||||
if (prev)
|
||||
{
|
||||
prev->next = msg->next;
|
||||
TTLALLOCMEM -= sizeof(aprivmsg);
|
||||
free(msg);
|
||||
msg = prev->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
FloodList = msg->next;
|
||||
TTLALLOCMEM -= sizeof(aprivmsg);
|
||||
free(msg);
|
||||
msg = FloodList;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prev = msg;
|
||||
msg = msg->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* now add the current message in the list */
|
||||
sprintf(userhost, "%s@%s", user->username, user->site);
|
||||
msg = (aprivmsg *) MALLOC(sizeof(aprivmsg));
|
||||
strcpy(msg->user, userhost);
|
||||
msg->time = now;
|
||||
msg->length = length;
|
||||
msg->next = FloodList;
|
||||
FloodList = msg;
|
||||
|
||||
/* count how many messages were received from that user
|
||||
* and also how many bytes
|
||||
*/
|
||||
count = size = 0;
|
||||
for (msg = FloodList; msg != NULL; msg = msg->next)
|
||||
{
|
||||
if (compare(userhost, msg->user))
|
||||
{
|
||||
count++;
|
||||
size += msg->length;
|
||||
}
|
||||
}
|
||||
|
||||
if (count >= FLOOD_FLOOD_RATE || size >= FLOOD_FLOOD_SIZE)
|
||||
{
|
||||
if (!IsIgnored(source))
|
||||
{
|
||||
sprintf(buffer, "OUTPUT-FLOOD from %s!%s", user->nick, userhost);
|
||||
log(buffer);
|
||||
|
||||
sprintf(buffer, "OUTPUT-FLOOD from %s!%s (%s)",
|
||||
user->nick, userhost, user->server->name);
|
||||
broadcast(buffer, 1);
|
||||
}
|
||||
MakeBanMask(user, buffer);
|
||||
AddIgnore(source, buffer, FLOOD_FLOOD_IGNORE);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CheckAdduserFlood(char *source, char *channel)
|
||||
{
|
||||
char buffer[200];
|
||||
char userhost[200];
|
||||
char global[] = "*";
|
||||
register aluser *user;
|
||||
register aprivmsg *msg, *prev;
|
||||
register int count;
|
||||
|
||||
if ((user = ToLuser(source)) == NULL)
|
||||
{
|
||||
sprintf(buffer, "ERROR! CheckAdduserFlood(): %s not found", source);
|
||||
log(buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Don't check flood from admins */
|
||||
if (IsValid(user, global) && Access(global, source) >= 1)
|
||||
return 0;
|
||||
|
||||
if (!strcasecmp(user->username, DEFAULT_USERNAME) &&
|
||||
!strcasecmp(user->site, DEFAULT_HOSTNAME))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* clean messages older than 1 hour */
|
||||
prev = NULL;
|
||||
msg = AddUserFloodList;
|
||||
while (msg != NULL)
|
||||
{
|
||||
if (msg->time < (now - 3600))
|
||||
{
|
||||
if (prev)
|
||||
{
|
||||
prev->next = msg->next;
|
||||
TTLALLOCMEM -= sizeof(aprivmsg);
|
||||
free(msg);
|
||||
msg = prev->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
AddUserFloodList = msg->next;
|
||||
TTLALLOCMEM -= sizeof(aprivmsg);
|
||||
free(msg);
|
||||
msg = AddUserFloodList;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prev = msg;
|
||||
msg = msg->next;
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(userhost, "%s@%s", user->username, user->site);
|
||||
|
||||
/* now add the current message in the list */
|
||||
msg = (aprivmsg *) MALLOC(sizeof(aprivmsg));
|
||||
strcpy(msg->user, channel);
|
||||
msg->time = now;
|
||||
msg->length = 0;
|
||||
msg->next = AddUserFloodList;
|
||||
AddUserFloodList = msg;
|
||||
|
||||
/* count how many messages were received from that user
|
||||
* and also how many bytes
|
||||
*/
|
||||
count = 0;
|
||||
for (msg = AddUserFloodList; msg != NULL; msg = msg->next)
|
||||
{
|
||||
if (!strcmp(channel, msg->user))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count >= 20)
|
||||
{
|
||||
if (!IsIgnored(source))
|
||||
{
|
||||
sprintf(buffer, "ADDUSER-FLOOD from %s!%s [%s]", user->nick, userhost, channel);
|
||||
log(buffer);
|
||||
|
||||
sprintf(buffer, "ADDUSER-FLOOD from %s!%s [%s] (%s)",
|
||||
user->nick, userhost, channel, user->server->name);
|
||||
broadcast(buffer, 1);
|
||||
}
|
||||
MakeBanMask(user, buffer);
|
||||
AddIgnore(source, buffer, 120);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void AdminRemoveIgnore(char *source, char *ch, char *args)
|
||||
{
|
||||
char mask[200], global[] = "*";
|
||||
char buffer[200];
|
||||
aignore **curr, *tmp;
|
||||
int change = 0;
|
||||
|
||||
if (Access(global, source) < XADMIN_LEVEL)
|
||||
{
|
||||
ReplyNotAccess(source, global);
|
||||
return;
|
||||
}
|
||||
|
||||
GetWord(0, args, mask);
|
||||
|
||||
if (!*mask)
|
||||
{
|
||||
notice(source, "SYNTAX: remignore <mask|all>");
|
||||
return;
|
||||
}
|
||||
|
||||
curr = &IgnoreList;
|
||||
while (*curr != NULL)
|
||||
{
|
||||
if (!strcasecmp((*curr)->mask, mask) || !strcasecmp(mask, "all"))
|
||||
{
|
||||
change = 1;
|
||||
sprintf(buffer, "removed %s", (*curr)->mask);
|
||||
notice(source, buffer);
|
||||
log(buffer);
|
||||
rem_silence((*curr)->mask);
|
||||
|
||||
tmp = *curr;
|
||||
*curr = tmp->next;
|
||||
|
||||
free(tmp);
|
||||
TTLALLOCMEM -= sizeof(aignore);
|
||||
}
|
||||
else
|
||||
{
|
||||
curr = &(*curr)->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (change)
|
||||
{
|
||||
sprintf(buffer, "%s removed ignore for [%s]", source, mask);
|
||||
broadcast(buffer, 1);
|
||||
}
|
||||
}
|
||||
148
Sources/kicks.c
Normal file
148
Sources/kicks.c
Normal file
@@ -0,0 +1,148 @@
|
||||
/* @(#)$Id: kicks.c,v 1.5 1997/07/18 07:55:04 cvs Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
|
||||
void kick(char *source,char *chanarg,char *args)
|
||||
{
|
||||
char buffer[500];
|
||||
char nick[80];
|
||||
char channel[80];
|
||||
char *comment;
|
||||
int found=0;
|
||||
achannel *chan;
|
||||
auser *user;
|
||||
|
||||
if(*args=='#'){
|
||||
GetWord(0,args,channel);
|
||||
GetWord(1,args,nick);
|
||||
comment=ToWord(2,args);
|
||||
}else{
|
||||
GetWord(0,args,nick);
|
||||
comment=ToWord(1,args);
|
||||
strcpy(channel,chanarg);
|
||||
GuessChannel(source,channel);
|
||||
}
|
||||
|
||||
if(strlen(comment)>200)
|
||||
comment[200]='\0';
|
||||
|
||||
if(!strcmp(channel,"*") || !*nick){
|
||||
notice(source,"SYNTAX: kick [#channel] <nick|pattern> [reason]");
|
||||
return;
|
||||
}
|
||||
|
||||
chan=ToChannel(channel);
|
||||
if(!chan||!chan->on){
|
||||
if(*source)
|
||||
notice(source,replies[RPL_NOTONCHANNEL][L_DEFAULT]);
|
||||
return;
|
||||
}
|
||||
|
||||
if(*source && (chan->flags&CFL_OPONLY)){
|
||||
notice(source,replies[RPL_OPONLY][chan->lang]);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!chan->AmChanOp){
|
||||
if(*source)
|
||||
notice(source,replies[RPL_NOTCHANOP][chan->lang]);
|
||||
return;
|
||||
}
|
||||
|
||||
/* check whether there are wildcards or not.
|
||||
* if there are wildcards, it's a masskick and nick is a match pattern
|
||||
* otherwise, it's an ordinary kick and nick is the nick to kick
|
||||
*/
|
||||
if(!strpbrk(nick,"*?")){
|
||||
#ifdef DEBUG
|
||||
printf("KICK REQUEST (NO WILDCARDS)\nSOURCE %s\nCHANNEL %s\nTARGET %s\n",
|
||||
source,channel,nick);
|
||||
#endif
|
||||
if(*source&&Access(channel,source)<KICK_LEVEL){
|
||||
ReplyNotAccess(source,channel);
|
||||
return;
|
||||
}
|
||||
|
||||
user=ToUser(channel,nick);
|
||||
if(!user) return;
|
||||
|
||||
if(*comment){
|
||||
if(*source)
|
||||
sprintf(buffer,":%s KICK %s %s :(%s) %s\n",
|
||||
mynick,channel,nick,source,comment);
|
||||
else
|
||||
sprintf(buffer,":%s KICK %s %s :%s\n",
|
||||
mynick,channel,nick,comment);
|
||||
}else{
|
||||
if(*source)
|
||||
sprintf(buffer,":%s KICK %s %s :From %s\n",
|
||||
mynick,channel,nick,source);
|
||||
else
|
||||
sprintf(buffer,":%s KICK %s %s :%s\n",
|
||||
mynick,channel,nick,mynick);
|
||||
}
|
||||
sendtoserv(buffer);
|
||||
sprintf(buffer,"I KICK %s OFF %s",nick,channel);
|
||||
log(buffer);
|
||||
}else{
|
||||
#ifdef DEBUG
|
||||
printf("KICK REQUEST (WITH WILDCARDS)\nSOURCE %s\nCHANNEL %s\nTARGET %s\n",
|
||||
source,channel,nick);
|
||||
#endif
|
||||
if(*source&&Access(channel,source)<MASS_KICK_LEVEL){
|
||||
ReplyNotAccess(source,channel);
|
||||
return;
|
||||
}
|
||||
|
||||
user=chan->users;
|
||||
while(user){
|
||||
sprintf(buffer,"%s!%s@%s",user->N->nick,user->N->username,user->N->site);
|
||||
if(match(buffer,nick)&&(!*source||strcasecmp(user->N->nick,source))){
|
||||
if(*comment){
|
||||
if(*source)
|
||||
sprintf(buffer,":%s KICK %s %s :(%s) %s\n",mynick,channel,user->N->nick,source,comment);
|
||||
else
|
||||
sprintf(buffer,":%s KICK %s %s :%s\n",mynick,channel,user->N->nick,comment);
|
||||
}else{
|
||||
if(*source)
|
||||
sprintf(buffer,":%s KICK %s %s :From %s\n",
|
||||
mynick,channel,user->N->nick,source);
|
||||
else
|
||||
sprintf(buffer,":%s KICK %s %s :%s\n",
|
||||
mynick,channel,user->N->nick,mynick);
|
||||
}
|
||||
sendtoserv(buffer);
|
||||
sprintf(buffer,"I KICK %s OFF %s",user->N->nick,channel);
|
||||
log(buffer);
|
||||
found=1;
|
||||
}
|
||||
user=user->next;
|
||||
}
|
||||
if(*source && !found)
|
||||
notice(source,replies[RPL_NOMATCH][chan->lang]);
|
||||
}
|
||||
}
|
||||
35
Sources/lang.h
Normal file
35
Sources/lang.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/* @(#)$Id: lang.h,v 1.5 1999/01/09 16:51:31 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#define NO_LANG 5
|
||||
|
||||
#define L_ENGLISH 0
|
||||
#define L_DUTCH 1
|
||||
#define L_FRENCH 2
|
||||
#define L_SPANISH 3
|
||||
#define L_GERMAN 4
|
||||
|
||||
#define L_DEFAULT L_ENGLISH
|
||||
122
Sources/list.c
Normal file
122
Sources/list.c
Normal file
@@ -0,0 +1,122 @@
|
||||
/* @(#)$Id: list.c,v 1.3 1996/11/13 00:40:43 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <netinet/in.h>
|
||||
#include "defines.h"
|
||||
#include "struct.h"
|
||||
#include "version.h"
|
||||
#include "../config.h"
|
||||
|
||||
typedef struct DiskUser {
|
||||
char realname[80];
|
||||
char match[80];
|
||||
int Access;
|
||||
char passwd[20];
|
||||
char channel[80];
|
||||
unsigned long flags;
|
||||
char reserved[20];
|
||||
time_t suspend;
|
||||
time_t lastseen;
|
||||
} DiskUser;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
FILE *in1,*in2;
|
||||
FILE *out;
|
||||
char *ptr;
|
||||
adefchan channel;
|
||||
DiskUser user;
|
||||
time_t currtime;
|
||||
|
||||
|
||||
if(chdir(HOMEDIR)<0){
|
||||
perror(HOMEDIR);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
out=fopen("Registered_Channels","w");
|
||||
if(out==NULL){
|
||||
fclose(in1);
|
||||
perror("Registered_Channels");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
currtime=time(NULL);
|
||||
|
||||
fprintf(out,
|
||||
"%s\n"
|
||||
"(c) 1995,1996 by Robin Thellend <intru@info.polymtl.ca>\n"
|
||||
"\n"
|
||||
"This is the list of currently registered channels on Undernet.\n"
|
||||
"Note that secret and private channels are NOT showed here.\n"
|
||||
"This file is updated every hour.\n"
|
||||
"\n"
|
||||
"Last update: %s"
|
||||
"Montreal's local time is used.\n\n",
|
||||
VERSION,ctime(&currtime));
|
||||
|
||||
in1=fopen(DEFAULT_CHANNELS_FILE,"r");
|
||||
if(in1==NULL){
|
||||
fprintf(out,"There are no registered channels\n");
|
||||
return;
|
||||
}
|
||||
|
||||
while(fread(&channel,sizeof(adefchan),1,in1)>0){
|
||||
ptr=strchr(channel.mode,' ');
|
||||
if(ptr!=NULL)
|
||||
*ptr='\0';
|
||||
|
||||
/* don't show secret or private channel */
|
||||
if(strpbrk(channel.mode,"sp"))
|
||||
continue;
|
||||
|
||||
fprintf(out,"%s Created: %s",channel.name,ctime(&channel.TS));
|
||||
|
||||
in2=fopen(USERFILE,"r");
|
||||
if(in2==NULL){
|
||||
fprintf(out,"Can't open \"%s\"\n",USERFILE);
|
||||
}else{
|
||||
while(fread(&user,sizeof(DiskUser),1,in2)>0){
|
||||
if(!strcasecmp(user.channel,channel.name)&&
|
||||
user.Access>=SET_DEFAULT_LEVEL){
|
||||
fprintf(out," %s %s Last seen: %s",
|
||||
user.realname,user.match,
|
||||
ctime(&user.lastseen));
|
||||
}
|
||||
}
|
||||
fclose(in2);
|
||||
}
|
||||
fprintf(out,"\n");
|
||||
}
|
||||
|
||||
fclose(in1);
|
||||
fclose(out);
|
||||
}
|
||||
79
Sources/listall.c
Normal file
79
Sources/listall.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/* @(#)$Id: listall.c,v 1.3 1996/11/13 00:40:43 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <netinet/in.h>
|
||||
#include "defines.h"
|
||||
#include "struct.h"
|
||||
#include "version.h"
|
||||
#include "../config.h"
|
||||
|
||||
typedef struct DiskUser {
|
||||
char realname[80];
|
||||
char match[80];
|
||||
char passwd[20];
|
||||
char channel[80];
|
||||
char modif[80];
|
||||
int Access;
|
||||
unsigned long flags;
|
||||
time_t suspend;
|
||||
time_t lastseen;
|
||||
} DiskUser;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
FILE *in1,*in2;
|
||||
FILE *out;
|
||||
char *ptr;
|
||||
adefchan channel;
|
||||
DiskUser user;
|
||||
time_t currtime;
|
||||
|
||||
|
||||
if(chdir(HOMEDIR)<0){
|
||||
perror(HOMEDIR);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
out=stdout;
|
||||
|
||||
currtime=time(NULL);
|
||||
|
||||
in2=fopen(USERFILE,"r");
|
||||
while(fread(&user,sizeof(DiskUser),1,in2)>0){
|
||||
for(ptr=user.channel;*ptr;ptr++)
|
||||
*ptr=tolower(*ptr);
|
||||
fprintf(out,"[%s] %s %s (%d) Last modif: %s, Last seen: %s",
|
||||
user.channel,
|
||||
user.realname,user.match,user.Access,
|
||||
user.modif,ctime(&user.lastseen));
|
||||
}
|
||||
fclose(in2);
|
||||
fclose(out);
|
||||
}
|
||||
1002
Sources/main.c
Normal file
1002
Sources/main.c
Normal file
File diff suppressed because it is too large
Load Diff
0
Sources/make.dep
Normal file
0
Sources/make.dep
Normal file
316
Sources/match.c
Normal file
316
Sources/match.c
Normal file
@@ -0,0 +1,316 @@
|
||||
/* @(#)$Id: match.c,v 1.10 1999/03/06 19:15:34 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
#include <regex.h>
|
||||
|
||||
static int matchX(char *, char *);
|
||||
|
||||
int mycasecmp(char *s1, char *s2)
|
||||
{
|
||||
register unsigned char *c1 = (unsigned char *)s1, *c2 = (unsigned char *)s2;
|
||||
register int d;
|
||||
|
||||
while (!(d = (toupper(*c1) - toupper(*c2))) && *c1)
|
||||
{
|
||||
c1++;
|
||||
c2++;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
char *strcasestr(register char *s1, char *s2)
|
||||
{
|
||||
register char *a, *b;
|
||||
|
||||
while (*s1)
|
||||
{
|
||||
a = s1;
|
||||
b = s2;
|
||||
while (*b && *a && toupper(*a) == toupper(*b))
|
||||
{
|
||||
a++;
|
||||
b++;
|
||||
}
|
||||
if (!*b)
|
||||
return s1;
|
||||
s1++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* xmatch() returns 1 if both pat1 and pat2 can *possibly*
|
||||
* match the same string. It returns 0 otherwise.
|
||||
*/
|
||||
int xmatch(char *pat1, char *pat2)
|
||||
{
|
||||
if (!strcmp(pat1, "*") || !strcmp(pat2, "*"))
|
||||
return 1;
|
||||
while (*pat1 && *pat2)
|
||||
{
|
||||
if (*pat1 == '*' && *pat2 == '*')
|
||||
return (matchX(pat1 + 1, pat2 + 1) || matchX(pat2 + 1, pat1 + 1));
|
||||
if (*pat1 == '*')
|
||||
return matchX(pat1 + 1, pat2);
|
||||
if (*pat2 == '*')
|
||||
return matchX(pat2 + 1, pat1);
|
||||
if (*pat1 == '?' || *pat2 == '?' || toupper(*pat1) == toupper(*pat2))
|
||||
{
|
||||
pat1++;
|
||||
pat2++;
|
||||
if ((!*pat1 && !strcmp(pat2, "*")) ||
|
||||
(!*pat2 && !strcmp(pat1, "*")))
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
if (*pat1 || *pat2)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int matchX(char *pat1, char *pat2)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (xmatch(pat1, pat2))
|
||||
return 1;
|
||||
}
|
||||
while (*pat2++);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int match(register char *string, register char *mask)
|
||||
{
|
||||
char *stack[200][2] = {{NULL, NULL}};
|
||||
register char type = 0;
|
||||
register short quote, level = 0;
|
||||
|
||||
while (*string)
|
||||
{
|
||||
quote = 0;
|
||||
switch (*mask)
|
||||
{
|
||||
case '*':
|
||||
type = '*';
|
||||
if (++level == 200)
|
||||
return 0;
|
||||
stack[level][0] = mask;
|
||||
stack[level][1] = string;
|
||||
while (*++mask == '*'); /* '*' eats any following '*' */
|
||||
break;
|
||||
case '\\':
|
||||
quote++;
|
||||
mask++;
|
||||
/* no break! */
|
||||
default:
|
||||
if (toupper(*string) == toupper(*mask) || (*mask == '?' && !quote))
|
||||
{
|
||||
mask++;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (stack[level][0] == NULL && --level > 0);
|
||||
if (level <= 0)
|
||||
return 0;
|
||||
mask = stack[level][0];
|
||||
string = stack[level][1];
|
||||
level--;
|
||||
}
|
||||
string++;
|
||||
}
|
||||
}
|
||||
while (*mask == '*') /* Skip everything that can */
|
||||
mask++; /* match an empty string. */
|
||||
|
||||
return (*mask) ? 0 : 1;
|
||||
}
|
||||
|
||||
|
||||
/* compare() will return 1 if p1 and p2 can match the same
|
||||
* nick!user@host. p1 and p2 are nick!user@host masks.
|
||||
*/
|
||||
int compare(char *p1, char *p2)
|
||||
{
|
||||
char tmp1[200], tmp2[200];
|
||||
register char *s1 = tmp1, *s2 = tmp2;
|
||||
register int ip1, ip2, in_uh = 0;
|
||||
|
||||
do
|
||||
{
|
||||
ip1 = ip2 = 1;
|
||||
|
||||
while (*p1 && *p1 != '!' && *p1 != '@')
|
||||
{
|
||||
if (ip1 && !isdigit(*p1) && *p1 != '.' && (*p1 != '*' || p1[1]) && (*p1 == '*' || s1 != tmp1))
|
||||
ip1 = 0;
|
||||
*(s1++) = *(p1++);
|
||||
}
|
||||
if (!in_uh && *p1 == '\0')
|
||||
in_uh = 1;
|
||||
|
||||
while (*p2 && *p2 != '!' && *p2 != '@')
|
||||
{
|
||||
if (ip2 && !isdigit(*p2) && *p2 != '.' && (*p2 != '*' || p2[1]) && (*p2 == '*' || s2 != tmp2))
|
||||
ip2 = 0;
|
||||
*(s2++) = *(p2++);
|
||||
}
|
||||
|
||||
*s2 = *s1 = '\0';
|
||||
|
||||
if (*p1 != *p2)
|
||||
{
|
||||
if (*p1 == '!')
|
||||
{
|
||||
s1 = tmp1;
|
||||
if (*p1)
|
||||
p1++;
|
||||
while (*p1 && *p1 != '@')
|
||||
{
|
||||
if (ip1 && !isdigit(*p1) && *p1 != '.' && (*p1 != '*' || p1[1]) && (*p1 == '*' || s1 != tmp1))
|
||||
ip1 = 0;
|
||||
*(s1++) = *(p1++);
|
||||
}
|
||||
if (!in_uh && *p1 == '\0')
|
||||
in_uh = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
s2 = tmp2;
|
||||
if (*p2)
|
||||
p2++;
|
||||
while (*p2 && *p2 != '@')
|
||||
{
|
||||
if (ip2 && !isdigit(*p2) && *p2 != '.' && (*p2 != '*' || p2[1]) && (*p1 == '*' || s2 != tmp2))
|
||||
ip2 = 0;
|
||||
*(s2++) = *(p2++);
|
||||
}
|
||||
}
|
||||
*s2 = *s1 = '\0';
|
||||
}
|
||||
if ((in_uh && ip1 != ip2) || !xmatch(tmp1, tmp2))
|
||||
return 0;
|
||||
|
||||
if (*p1)
|
||||
p1++;
|
||||
if (*p2)
|
||||
p2++;
|
||||
|
||||
s1 = tmp1;
|
||||
s2 = tmp2;
|
||||
|
||||
}
|
||||
while (*p1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int key_match(char *s, char *tok[])
|
||||
{
|
||||
register int k;
|
||||
|
||||
for (k = 0; tok[k] != NULL; k++)
|
||||
{
|
||||
if (!strcasestr(s, tok[k]))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void string_swap(char *buf, size_t size, char *orig, char *new)
|
||||
{
|
||||
char *ptr, *buf2;
|
||||
|
||||
buf2 = (char *)alloca(sizeof(char) * size);
|
||||
while ((ptr = strstr((buf), orig)))
|
||||
{
|
||||
*ptr = '\0';
|
||||
strncpy(buf2, buf, size - 1);
|
||||
strncat(buf2, new, size - strlen(buf) - 1);
|
||||
strncat(buf2, ptr + strlen(orig), size - strlen(buf) - strlen(new) - 1);
|
||||
strcpy(buf, buf2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* regex_cmp() (stolen from RCSD)
|
||||
* This function compares a regular expression (patern) with a string.
|
||||
* Return value: 1 if there is a match
|
||||
* 0 otherwise
|
||||
*
|
||||
* Note: if patern is NULL, the last patern that was passed to the
|
||||
* function is used.
|
||||
*/
|
||||
#define HAVE_REGEXEC
|
||||
int regex_cmp(char *patern, char *string)
|
||||
{
|
||||
#if defined(HAVE_REGEXEC)
|
||||
static regex_t preg;
|
||||
static int called_once = 0;
|
||||
register int cmpv = 0, execv;
|
||||
|
||||
if (patern != NULL)
|
||||
{
|
||||
if (called_once)
|
||||
regfree(&preg);
|
||||
cmpv = regcomp(&preg, patern, REG_EXTENDED | REG_ICASE | REG_NOSUB);
|
||||
}
|
||||
|
||||
called_once = 1;
|
||||
|
||||
if (cmpv == 0)
|
||||
execv = regexec(&preg, string, 0, NULL, 0);
|
||||
|
||||
return cmpv ? 0 : execv ? 0 : 1;
|
||||
|
||||
#elif defined(HAVE_RE_EXEC)
|
||||
register char *ptr;
|
||||
|
||||
ptr = re_comp(patern);
|
||||
return ptr ? 0 : re_exec(string);
|
||||
|
||||
#else
|
||||
#error neither re_exec() nor rexexec() :/
|
||||
#endif
|
||||
}
|
||||
#ifdef MATCHALONE
|
||||
void main(void)
|
||||
{
|
||||
char str1[80];
|
||||
char str2[80];
|
||||
puts("#1");
|
||||
gets(str1);
|
||||
puts("#2");
|
||||
gets(str2);
|
||||
printf("match: %d\n", match(str1, str2));
|
||||
}
|
||||
#endif
|
||||
970
Sources/modes.c
Normal file
970
Sources/modes.c
Normal file
@@ -0,0 +1,970 @@
|
||||
/* @(#)$Id: modes.c,v 1.10 1999/04/04 17:00:11 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
|
||||
static void AddFlag(char *, char, char *);
|
||||
static void RemFlag(char *, char);
|
||||
|
||||
void setchanmode(char *line)
|
||||
{
|
||||
register char *mode;
|
||||
register achannel *chan;
|
||||
|
||||
if ((mode = strchr(line, ' ')) != NULL)
|
||||
*(mode++) = 0;
|
||||
chan = ToChannel(line);
|
||||
if (!chan)
|
||||
return;
|
||||
strcpy(chan->mode, mode + 1); /* why +1 ???? coz I don't want the + */
|
||||
}
|
||||
|
||||
void AddFlag(char *string, char flag, char *arg)
|
||||
{
|
||||
char newmode[15];
|
||||
char newarg[200];
|
||||
|
||||
if (strchr(string, flag))
|
||||
RemFlag(string, flag);
|
||||
|
||||
GetWord(0, string, newmode);
|
||||
*(newmode + strlen(newmode) + 1) = 0;
|
||||
*(newmode + strlen(newmode)) = flag;
|
||||
strcpy(newarg, ToWord(1, string));
|
||||
if (arg)
|
||||
{
|
||||
strcat(newarg, arg);
|
||||
strcat(newarg, " ");
|
||||
}
|
||||
|
||||
sprintf(string, "%s %s", newmode, newarg);
|
||||
}
|
||||
|
||||
void RemFlag(char *string, char flag)
|
||||
{
|
||||
char newmode[15];
|
||||
char newarg[200];
|
||||
register char *ptr;
|
||||
register char *curr = newmode;
|
||||
register int count = 0;
|
||||
|
||||
GetWord(0, string, newmode);
|
||||
strcpy(newarg, ToWord(1, string));
|
||||
|
||||
while (*curr)
|
||||
{
|
||||
ptr = strchr("lk", *curr);
|
||||
if (*curr == flag)
|
||||
{
|
||||
strcpy(curr, curr + 1);
|
||||
if (ptr)
|
||||
strcpy(ToWord(count, newarg), ToWord(count + 1, newarg));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ptr)
|
||||
count++;
|
||||
curr++;
|
||||
}
|
||||
}
|
||||
sprintf(string, "%s %s", newmode, newarg);
|
||||
}
|
||||
|
||||
int IsSet(char *channel, char flag, char *param)
|
||||
{
|
||||
register achannel *chan;
|
||||
register char *setmode;
|
||||
char setflags[20];
|
||||
char setparam[80];
|
||||
register int out;
|
||||
register int i, j;
|
||||
|
||||
chan = ToChannel(channel);
|
||||
if (chan == NULL)
|
||||
return 0;
|
||||
|
||||
setmode = chan->mode;
|
||||
GetWord(0, setmode, setflags);
|
||||
|
||||
j = 0;
|
||||
for (i = 0; setflags[i] != '\0' && setflags[i] != flag; i++)
|
||||
{
|
||||
if (setflags[i] == 'l' || setflags[i] == 'k')
|
||||
j++;
|
||||
}
|
||||
|
||||
if (setflags[i] != '\0')
|
||||
{
|
||||
if (flag == 'l' || flag == 'k')
|
||||
{
|
||||
GetWord(j + 1, setmode, setparam);
|
||||
if (!strcmp(setparam, param))
|
||||
out = 1;
|
||||
else
|
||||
out = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
out = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
out = 0;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("IsSet(): +%c %s on %s (%d)\n", flag, param, channel, out);
|
||||
#endif
|
||||
return (out);
|
||||
}
|
||||
|
||||
void bounce(char *channel, char *change, time_t TS)
|
||||
{
|
||||
char buffer[200];
|
||||
char arg[200];
|
||||
register char sign = '+';
|
||||
register auser *user;
|
||||
register achannel *chan;
|
||||
register int pos = 1;
|
||||
register int i;
|
||||
|
||||
chan = ToChannel(channel);
|
||||
|
||||
for (i = 0; change[i] != '\0' && change[i] != ' '; i++)
|
||||
{
|
||||
if (change[i] == '+')
|
||||
sign = '+';
|
||||
else if (change[i] == '-')
|
||||
sign = '-';
|
||||
else if (change[i] == 'o')
|
||||
{
|
||||
GetWord(pos++, change, arg);
|
||||
user = ToUser(channel, arg);
|
||||
if (user == NULL)
|
||||
continue;
|
||||
if (sign == '+')
|
||||
{
|
||||
if (!user->chanop)
|
||||
{
|
||||
changemode(channel, "-o", arg, 1);
|
||||
user->chanop = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (user->chanop)
|
||||
{
|
||||
/*
|
||||
changemode(channel,"+o",arg,1);
|
||||
user->chanop=1;
|
||||
*/
|
||||
/* don't bounce -o */
|
||||
user->chanop = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (change[i] == 'v')
|
||||
{
|
||||
GetWord(pos++, change, arg);
|
||||
if (sign == '+')
|
||||
changemode(channel, "-v", arg, 1);
|
||||
else
|
||||
changemode(channel, "+v", arg, 1);
|
||||
}
|
||||
else if (change[i] == 'k')
|
||||
{
|
||||
GetWord(pos++, change, arg);
|
||||
if (sign == '+')
|
||||
{
|
||||
if (!IsSet(channel, 'k', arg))
|
||||
changemode(channel, "-k", arg, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsSet(channel, 'k', arg))
|
||||
changemode(channel, "+k", arg, 1);
|
||||
}
|
||||
}
|
||||
else if (change[i] == 'l')
|
||||
{
|
||||
pos++;
|
||||
if (sign == '+' && !IsSet(channel, 'l', arg))
|
||||
changemode(channel, "-l", "", 1);
|
||||
|
||||
}
|
||||
else if ((IsSet(channel, change[i], "") && sign == '-') ||
|
||||
(!IsSet(channel, change[i], "") && sign == '+'))
|
||||
{
|
||||
sprintf(buffer, "%c%c",
|
||||
(sign == '+') ? '-' : '+',
|
||||
change[i]);
|
||||
changemode(channel, buffer, "", 1);
|
||||
}
|
||||
}
|
||||
AddEvent(EVENT_FLUSHMODEBUFF, now + MODE_DELAY, channel);
|
||||
}
|
||||
|
||||
|
||||
void ModeChange(char *source, char *channel, char *change)
|
||||
{
|
||||
register char sign = '+';
|
||||
char arg[200];
|
||||
register char *ptr;
|
||||
register achannel *chan;
|
||||
register aluser *u;
|
||||
register int count = 1;
|
||||
int desync = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("ModeChange(%s, %s, %s)\n", source, channel, change);
|
||||
#endif
|
||||
chan = ToChannel(channel);
|
||||
/* if chan == NULL at this point.. we're dealing with a
|
||||
* user mode change
|
||||
*/
|
||||
if (chan != NULL)
|
||||
chan->lastact = now;
|
||||
|
||||
u = ToLuser(source);
|
||||
if (chan == NULL && u == NULL)
|
||||
{
|
||||
return; /* probably a lost MODE */
|
||||
}
|
||||
if (u == NULL)
|
||||
{
|
||||
/* This is a mode change from a server.. if it is not
|
||||
* a +b, then the last argument is a TS
|
||||
*/
|
||||
for (ptr = change; *ptr != 'b' && *ptr != ' '; ptr++);
|
||||
if (*ptr != 'b' && strcasecmp(UWORLD_SERVER, source)
|
||||
#ifdef UWORLD2
|
||||
&& strcasecmp(UWORLD2_SERVER, source)
|
||||
#endif
|
||||
#ifdef FAKE_UWORLD
|
||||
&& strcasecmp(UFAKE_SERVER, source)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
ptr = change + strlen(change);
|
||||
while (*ptr != ' ')
|
||||
ptr--;
|
||||
*(ptr++) = '\0';
|
||||
if (atol(ptr) > chan->TS && atol(ptr) != 0 && chan->on)
|
||||
{
|
||||
log(source);
|
||||
log(channel);
|
||||
log(change);
|
||||
log(ptr);
|
||||
bounce(channel, change, chan->TS);
|
||||
return;
|
||||
}
|
||||
if (atol(ptr) != 0)
|
||||
chan->TS = atol(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
while (*change && *change != ' ')
|
||||
{
|
||||
if (*change == '+')
|
||||
{
|
||||
sign = '+';
|
||||
}
|
||||
else if (*change == '-')
|
||||
{
|
||||
sign = '-';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sign == '+')
|
||||
{
|
||||
if (chan != NULL)
|
||||
{
|
||||
ptr = strchr("blkov", *change);
|
||||
if (ptr)
|
||||
{
|
||||
GetWord(count, change, arg);
|
||||
if (strchr("lk", *change) && *arg)
|
||||
AddFlag(chan->mode, *change, arg);
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strchr("imntps", *change))
|
||||
AddFlag(chan->mode, *change, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* user mode change (+) */
|
||||
if (*change == 'o')
|
||||
{
|
||||
u->mode |= LFL_ISOPER;
|
||||
#ifdef DEBUG
|
||||
printf("%s is now IRCOP\n", source);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (chan != NULL)
|
||||
{
|
||||
ptr = strchr("bkov", *change);
|
||||
if (strchr("ilkmntps", *change))
|
||||
RemFlag(chan->mode, *change);
|
||||
if (ptr)
|
||||
{
|
||||
GetWord(count, change, arg);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* user mode change (-) */
|
||||
if (*change == 'o')
|
||||
{
|
||||
u->mode &= ~LFL_ISOPER;
|
||||
#ifdef DEBUG
|
||||
printf("%s is no longer IRCOP\n", source);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** other tests should go here **/
|
||||
|
||||
if (chan != NULL)
|
||||
{
|
||||
if (*change == 'o')
|
||||
{
|
||||
if (sign == '+')
|
||||
onop(source, channel, arg);
|
||||
else
|
||||
ondeop(source, channel, arg, &desync);
|
||||
}
|
||||
else if (*change == 'b')
|
||||
{
|
||||
if (sign == '+')
|
||||
onban(source, channel, arg);
|
||||
else
|
||||
onunban(source, channel, arg);
|
||||
}
|
||||
else if (*change == 'l')
|
||||
{
|
||||
if (sign == '+' && atoi(arg) < 2)
|
||||
{
|
||||
if (chan->on && chan->AmChanOp)
|
||||
{
|
||||
changemode(channel, "-l", "", 0);
|
||||
RemFlag(chan->mode, *change);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
change++;
|
||||
if (*change == ' ')
|
||||
{
|
||||
change = ToWord(count, change);
|
||||
count = 1;
|
||||
}
|
||||
}
|
||||
if (chan != NULL)
|
||||
{
|
||||
if (desync)
|
||||
{
|
||||
part("", channel, "");
|
||||
join("", channel, "");
|
||||
}
|
||||
CheckFlood(source, channel, 80);
|
||||
flushmode(channel);
|
||||
}
|
||||
}
|
||||
|
||||
void onop(char *source, char *channel, char *target)
|
||||
{
|
||||
register auser *user;
|
||||
register aluser *luser;
|
||||
register achannel *chan;
|
||||
char buffer[200];
|
||||
|
||||
chan = ToChannel(channel);
|
||||
luser = ToLuser(source);
|
||||
|
||||
user = ToUser(channel, target);
|
||||
|
||||
if (!strcasecmp(mynick, target))
|
||||
{
|
||||
if (!chan)
|
||||
{
|
||||
log("ERROR: onop() channel not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
chan->AmChanOp = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("OP for %s on %s\n", target, channel);
|
||||
#endif
|
||||
if (!user)
|
||||
{
|
||||
sprintf(buffer, "ERROR: onop() user not found (%s)",
|
||||
target);
|
||||
log(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
user->chanop = 1;
|
||||
|
||||
sprintf(buffer, "%s!%s@%s", user->N->nick, user->N->username, user->N->site);
|
||||
|
||||
if (luser && chan->on && (chan->flags & CFL_NOOP))
|
||||
{
|
||||
sprintf(buffer, "NoOp MODE! deopping %s and %s",
|
||||
target, source);
|
||||
log(buffer);
|
||||
notice(target, replies[RPL_NOOP][chan->lang]);
|
||||
notice(source, replies[RPL_NOOP][chan->lang]);
|
||||
changemode(channel, "-o", target, 0);
|
||||
changemode(channel, "-o", source, 0);
|
||||
user->chanop = 0;
|
||||
user = ToUser(channel, source);
|
||||
if (user != NULL)
|
||||
{
|
||||
user->chanop = 0;
|
||||
}
|
||||
|
||||
}
|
||||
else if (luser && chan->on && (chan->flags & CFL_STRICTOP) &&
|
||||
Access(channel, target) < OP_LEVEL)
|
||||
{
|
||||
sprintf(buffer, "StrictOp MODE! deopping %s and %s",
|
||||
target, source);
|
||||
log(buffer);
|
||||
notice(target, "Only authenticated users may be op in StrictOp mode");
|
||||
notice(source, "Only authenticated users may be op in StrictOp mode");
|
||||
changemode(channel, "-o", target, 0);
|
||||
user->chanop = 0;
|
||||
if (Access(channel, source) < OP_LEVEL)
|
||||
{
|
||||
changemode(channel, "-o", source, 0);
|
||||
user = ToUser(channel, source);
|
||||
if (user != NULL)
|
||||
{
|
||||
user->chanop = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (luser && chan->on && IsShit(channel, buffer, NULL, NULL) >= NO_OP_SHIT_LEVEL)
|
||||
{
|
||||
if (Access(channel, source) < ACCESS_BAN_PRIORITY)
|
||||
{
|
||||
sprintf(buffer, "%s is shitlisted (NO-OP LEVEL)!"
|
||||
"Deopping %s and %s", target, target, source);
|
||||
log(buffer);
|
||||
notice(target, replies[RPL_CANTBEOP][chan->lang]);
|
||||
notice(source, replies[RPL_CANTBEOPPED][chan->lang]);
|
||||
changemode(channel, "-o", target, 0);
|
||||
changemode(channel, "-o", source, 0);
|
||||
user->chanop = 0;
|
||||
user = ToUser(channel, source);
|
||||
if (user != NULL)
|
||||
user->chanop = 0;
|
||||
|
||||
sprintf(buffer, "%s %d", source, SUSPEND_TIME_FOR_OPPING_A_SHITLISTED_USER);
|
||||
suspend("", channel, buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
unban(source, channel, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** further tests should be put here **/
|
||||
#ifdef NICKSERV
|
||||
nserv_onop(channel, user);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ondeop(char *source, char *channel, char *target, int *desync)
|
||||
{
|
||||
char buffer[200];
|
||||
register auser *user1, *user2;
|
||||
register achannel *chan;
|
||||
register adeop *curr, *prec;
|
||||
register int i;
|
||||
|
||||
chan = ToChannel(channel);
|
||||
if (!chan)
|
||||
{
|
||||
log("ERROR: ondeop() channel not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
user1 = ToUser(channel, source);
|
||||
user2 = ToUser(channel, target);
|
||||
|
||||
if (chan->on && user1 == NULL)
|
||||
{ /* desync! */
|
||||
if (user2 != NULL)
|
||||
{
|
||||
user2->chanop = 0;
|
||||
}
|
||||
sprintf(buffer, "DESYNC detected! (%s deopped %s on %s)",
|
||||
source, target, channel);
|
||||
log(buffer);
|
||||
|
||||
/* part("",channel,"");
|
||||
join("",channel,""); now doing this in ChangeMode */
|
||||
|
||||
*desync = 1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcasecmp(mynick, target))
|
||||
{
|
||||
if ((chan->flags & CFL_ALWAYSOP) &&
|
||||
Access(channel, source) >= ALWAYSOP_OVERRIDE_LEVEL)
|
||||
{
|
||||
chan->flags &= ~CFL_ALWAYSOP;
|
||||
sprintf(buffer, "AlwaysOp is turned off on %s (deopped by %s!%s@%s)",
|
||||
channel, user1->N->nick, user1->N->username, user1->N->site);
|
||||
log(buffer);
|
||||
notice(source, replies[RPL_ALWAYSOPWASACTIVE][chan->lang]);
|
||||
}
|
||||
if (chan->flags & CFL_ALWAYSOP)
|
||||
{
|
||||
if (user1 != NULL)
|
||||
{
|
||||
sprintf(buffer, "DEOPPED by %s!%s@%s (%d) while AlwaysOp active on %s",
|
||||
user1->N->nick, user1->N->username, user1->N->site,
|
||||
Access(channel, source), channel);
|
||||
log(buffer);
|
||||
broadcast(buffer, 0);
|
||||
i = IsShit(channel, source, NULL, NULL);
|
||||
notice(source, replies[RPL_ALWAYSOP][chan->lang]);
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
log("First warning");
|
||||
notice(source, replies[RPL_DEOPPED1ST][chan->lang]);
|
||||
changemode(channel, "-o", source, 0);
|
||||
flushmode(channel);
|
||||
user1->chanop = 0;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
log("Second warning");
|
||||
notice(source, replies[RPL_DEOPPED2ND][chan->lang]);
|
||||
kick("", channel, source);
|
||||
break;
|
||||
|
||||
default:
|
||||
notice(source, "I warned you!");
|
||||
changemode(channel, "-o", source, 0);
|
||||
flushmode(channel);
|
||||
user1->chanop = 0;
|
||||
sprintf(buffer, "%s!%s@%s %d",
|
||||
user1->N->nick, user1->N->username,
|
||||
user1->N->site,
|
||||
DEOPME_SUSPEND_TIME);
|
||||
suspend("", channel, buffer);
|
||||
sprintf(buffer, "Suspended %s!%s@%s on %s for repeatedly deopping me",
|
||||
user1->N->nick, user1->N->username, user1->N->site, channel);
|
||||
SpecLog(buffer);
|
||||
broadcast(buffer, 0);
|
||||
}
|
||||
sprintf(buffer, "%s %d %d *** DEOP WHILE ALWAYSOP ACTIVE ***",
|
||||
source, DEOP_SHITLIST_TIME,
|
||||
(i < 10) ? i + 5 :
|
||||
DEOP_SHITLIST_LEVEL);
|
||||
AddToShitList("", channel, buffer, 0);
|
||||
chan->AmChanOp = 0; /* to remove if I reop myself */
|
||||
GetOps(channel);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
chan->AmChanOp = 0;
|
||||
if (IsOpless(channel))
|
||||
onopless(channel);
|
||||
}
|
||||
}
|
||||
|
||||
/* massdeop protection does NOT apply to the bot itself!
|
||||
if(!strcasecmp(source,mynick)) return; obsolete */
|
||||
|
||||
/* No protection against server deop :/
|
||||
Hey! I'm not gonna /squit it just for doing a deop!! ;) */
|
||||
if (!user1)
|
||||
return;
|
||||
|
||||
if (user2)
|
||||
user2->chanop = 0;
|
||||
|
||||
chan = ToChannel(channel);
|
||||
if (!chan)
|
||||
{
|
||||
log("ERROR: ondeop() channel not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
/* If not on channel.. do NOT check for massdeop
|
||||
*/
|
||||
if (!chan->on)
|
||||
return;
|
||||
|
||||
curr = user1->deophist;
|
||||
prec = NULL;
|
||||
|
||||
/* ok.. let's free the *old* deops from history */
|
||||
while (curr)
|
||||
{
|
||||
if (curr->time < (now - 15) || !strcasecmp(curr->nick, target))
|
||||
{
|
||||
if (prec)
|
||||
{
|
||||
prec->next = curr->next;
|
||||
TTLALLOCMEM -= sizeof(adeop);
|
||||
free(curr);
|
||||
curr = prec->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
user1->deophist = curr->next;
|
||||
TTLALLOCMEM -= sizeof(adeop);
|
||||
free(curr);
|
||||
curr = user1->deophist;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prec = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* now store the deop in the user's deop history */
|
||||
curr = (adeop *) MALLOC(sizeof(adeop));
|
||||
strcpy(curr->nick, target);
|
||||
curr->time = now;
|
||||
curr->next = user1->deophist;
|
||||
user1->deophist = curr;
|
||||
|
||||
/* now we count the number of deop in the user's history
|
||||
if it's equal to the max number of deops per 15 seconds
|
||||
interval.. activate the massdeop protection */
|
||||
for (curr = user1->deophist, i = 0; curr; curr = curr->next, i++);
|
||||
|
||||
if (i == chan->MassDeopPro && chan->MassDeopPro != 0 && chan->on)
|
||||
{
|
||||
sprintf(buffer, "MASSDEOP from %s on %s", source, channel);
|
||||
log(buffer);
|
||||
notice(source, "### MASSDEOP PROTECTION ACTIVATED ###");
|
||||
if (Access(channel, source) >= MASSDEOP_IMMUNE_LEVEL)
|
||||
{
|
||||
notice(source, "You are lucky your access is so high :P");
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buffer, "%s %d", source, MASSDEOP_SUSPEND_TIME);
|
||||
suspend("", channel, buffer);
|
||||
sprintf(buffer, "%s %d %d *** MASSDEOP ***", source,
|
||||
MASSDEOP_SHITLIST_TIME,
|
||||
MASSDEOP_SHITLIST_LEVEL);
|
||||
AddToShitList("", channel, buffer, 0);
|
||||
sprintf(buffer, "%s ### MASSDEOP PROTECTION ###", source);
|
||||
kick("", channel, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void onban(char *nick, char *channel, char *pattern)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("Wah! BAN FROM: %s\nON CHANNEL %s\nTARGET: %s\n",
|
||||
nick, channel, pattern);
|
||||
#endif
|
||||
AddBan(channel, pattern);
|
||||
}
|
||||
|
||||
void onunban(char *source, char *channel, char *pattern)
|
||||
{
|
||||
/*register achannel *chan; */
|
||||
|
||||
RemBan(channel, pattern);
|
||||
|
||||
/* mode -b no longer removes the ban from X's banlist
|
||||
** it has to be removed with the 'unban' command.
|
||||
chan=ToChannel(channel);
|
||||
if(chan!=NULL && chan->on)
|
||||
RemShitList(source,channel,pattern,1);
|
||||
* */
|
||||
}
|
||||
|
||||
void AddBan(char *channel, char *pattern)
|
||||
{
|
||||
register achannel *chan;
|
||||
register aban *theban;
|
||||
char buffer[200];
|
||||
|
||||
chan = ToChannel(channel);
|
||||
if (chan == NULL)
|
||||
{
|
||||
sprintf(buffer, "ERROR: AddBan(): can't find %s", channel);
|
||||
log(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
/* check if ban isn't already there */
|
||||
for (theban = chan->bans; theban != NULL; theban = theban->next)
|
||||
{
|
||||
if (!strncasecmp(theban->pattern, pattern, 79))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
theban = (aban *) MALLOC(sizeof(aban));
|
||||
strncpy(theban->pattern, pattern, 79);
|
||||
theban->pattern[79] = '\0';
|
||||
theban->next = chan->bans;
|
||||
chan->bans = theban;
|
||||
}
|
||||
|
||||
|
||||
void RemBan(char *channel, char *pattern)
|
||||
{
|
||||
register achannel *chan;
|
||||
register aban **b, *theban = NULL;
|
||||
|
||||
chan = ToChannel(channel);
|
||||
b = &chan->bans;
|
||||
while (*b != NULL)
|
||||
{
|
||||
if (!strncasecmp((*b)->pattern, pattern, 79))
|
||||
{
|
||||
theban = *b;
|
||||
*b = theban->next;
|
||||
TTLALLOCMEM -= sizeof(aban);
|
||||
free(theban);
|
||||
}
|
||||
else
|
||||
{
|
||||
b = &(*b)->next;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (theban == NULL)
|
||||
{
|
||||
printf("WARNING: RemBan(): pattern NOT found!!\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void changemode(char *channel, char *flag, char *arg, int AsServer)
|
||||
{
|
||||
register achannel *chan;
|
||||
register modequeue *mode, *curr;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Queueing mode change for channel %s %s %s %d\n", channel, flag, arg, AsServer);
|
||||
#endif
|
||||
|
||||
chan = ToChannel(channel);
|
||||
if (!AsServer && (!chan || !chan->on))
|
||||
return; /* not on the channel.. ignore */
|
||||
|
||||
/* first, cancel previous contradicting mode changes..
|
||||
ex.. mode #test +o-o+o-o+o .. the bot won't do that.. */
|
||||
|
||||
mode = chan->modebuff;
|
||||
while (mode)
|
||||
{
|
||||
if (!strcmp(arg, mode->arg) && flag[1] == mode->flag[1] &&
|
||||
((flag[0] == '+' && mode->flag[0] == '-') ||
|
||||
(flag[0] == '-' && mode->flag[0] == '+')))
|
||||
{
|
||||
if (mode->prev)
|
||||
mode->prev->next = mode->next;
|
||||
else
|
||||
chan->modebuff = mode->next;
|
||||
|
||||
if (mode->next)
|
||||
mode->next->prev = mode->prev;
|
||||
|
||||
curr = mode;
|
||||
TTLALLOCMEM -= sizeof(modequeue);
|
||||
free(curr);
|
||||
}
|
||||
else if (!strcmp(arg, mode->arg) && flag[1] == mode->flag[1] &&
|
||||
flag[0] == mode->flag[0])
|
||||
return;
|
||||
mode = mode->next;
|
||||
}
|
||||
|
||||
curr = (modequeue *) MALLOC(sizeof(modequeue));
|
||||
strcpy(curr->arg, arg);
|
||||
strcpy(curr->flag, flag);
|
||||
curr->AsServer = AsServer;
|
||||
curr->next = NULL;
|
||||
|
||||
for (mode = chan->modebuff; mode && mode->next; mode = mode->next);
|
||||
|
||||
if (mode)
|
||||
{
|
||||
curr->prev = mode;
|
||||
mode->next = curr;
|
||||
}
|
||||
else
|
||||
{
|
||||
chan->modebuff = curr;
|
||||
curr->prev = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void flushmode(char *channel)
|
||||
{
|
||||
char buffer[500];
|
||||
register achannel *chan;
|
||||
register modequeue *mode, *tmp;
|
||||
char flags[20] = "";
|
||||
char args[500] = "";
|
||||
register char lastsign;
|
||||
register int AsServer;
|
||||
register int count = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Flushing mode change buffer.. for channel %s\n", channel);
|
||||
#endif
|
||||
|
||||
/* gotta pass thru the list twice:
|
||||
* the first time, check for Server mode changes
|
||||
* the second time, check for user mode changes
|
||||
*/
|
||||
|
||||
chan = ToChannel(channel);
|
||||
|
||||
if (chan == NULL)
|
||||
return;
|
||||
|
||||
#ifdef FAKE_UWORLD
|
||||
#define ASSERVERMAX 2
|
||||
#else
|
||||
#define ASSERVERMAX 1
|
||||
#endif
|
||||
for (AsServer = ASSERVERMAX; AsServer >= 0; AsServer--)
|
||||
{
|
||||
#undef ASSERVERMAX
|
||||
lastsign = '\0';
|
||||
mode = chan->modebuff;
|
||||
while (mode != NULL)
|
||||
{
|
||||
if (!strcmp(mode->flag, "-b"))
|
||||
{
|
||||
RemBan(channel, mode->arg);
|
||||
}
|
||||
else if (!strcmp(mode->flag, "+b"))
|
||||
{
|
||||
AddBan(channel, mode->arg);
|
||||
}
|
||||
if (AsServer == mode->AsServer)
|
||||
{
|
||||
if (mode->arg[0] != '\0')
|
||||
{
|
||||
count++;
|
||||
strcat(args, " ");
|
||||
strcat(args, mode->arg);
|
||||
}
|
||||
if (lastsign != mode->flag[0])
|
||||
{
|
||||
strcat(flags, mode->flag);
|
||||
lastsign = mode->flag[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
strcat(flags, mode->flag + 1);
|
||||
}
|
||||
if (mode->prev)
|
||||
mode->prev->next = mode->next;
|
||||
else
|
||||
chan->modebuff = mode->next;
|
||||
if (mode->next)
|
||||
mode->next->prev = mode->prev;
|
||||
tmp = mode;
|
||||
mode = mode->next;
|
||||
TTLALLOCMEM -= sizeof(modequeue);
|
||||
free(tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
mode = mode->next;
|
||||
}
|
||||
|
||||
if (count == MAX_MODE_PER_LINE || !mode)
|
||||
{
|
||||
if (AsServer == 0 && chan->AmChanOp && *flags != '\0')
|
||||
{
|
||||
sprintf(buffer, ":%s MODE %s %s%s\n",
|
||||
mynick, channel, flags, args);
|
||||
sendtoserv(buffer);
|
||||
}
|
||||
else if (AsServer == 1 && *flags != '\0')
|
||||
{
|
||||
sprintf(buffer, ":%s MODE %s %s%s %ld\n",
|
||||
SERVERNAME, channel,
|
||||
flags, args, chan->TS);
|
||||
sendtoserv(buffer);
|
||||
}
|
||||
#ifdef FAKE_UWORLD
|
||||
else if (AsServer == 2 && Uworld_status == 1 && *flags != '\0')
|
||||
{
|
||||
sprintf(buffer, ":%s MODE %s %s%s\n",
|
||||
UFAKE_SERVER, channel,
|
||||
flags, args);
|
||||
sendtoserv(buffer);
|
||||
}
|
||||
#endif
|
||||
count = *args = *flags = 0;
|
||||
lastsign = '+';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
81
Sources/nick.c
Normal file
81
Sources/nick.c
Normal file
@@ -0,0 +1,81 @@
|
||||
/* @(#)$Id: nick.c,v 1.3 1996/11/13 00:40:44 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
|
||||
void NickInUse(void)
|
||||
{
|
||||
char buffer[200];
|
||||
|
||||
sprintf(buffer,":%s SQUIT %s 0 :Unexpected nick collision\n",
|
||||
SERVERNAME,SERVERNAME);
|
||||
sendtoserv(buffer);
|
||||
dumpbuff();
|
||||
close(Irc.fd);
|
||||
Irc.fd=-1;
|
||||
QuitAll();
|
||||
if(reconnect(server)){
|
||||
try_later(server);
|
||||
}
|
||||
#if 0
|
||||
char *ptr;
|
||||
achannel *chan;
|
||||
int index=0;
|
||||
|
||||
do{
|
||||
if(!strcmp(mynick,DEFAULT_NICKNAME)){
|
||||
strcat(mynick,"1");
|
||||
}else{
|
||||
ptr = (mynick+strlen(mynick)-1);
|
||||
(*ptr)++;
|
||||
if(*ptr>'z') *ptr='0';
|
||||
}
|
||||
}while(ToLuser(mynick)!=NULL);
|
||||
|
||||
sprintf(buffer,
|
||||
"ERROR: ARGH! Nick already in use! Changing to %s",mynick);
|
||||
log(buffer);
|
||||
|
||||
for(index=0;index<1000;index++){
|
||||
chan=ChannelList[index];
|
||||
while(chan!=NULL){
|
||||
chan->on=chan->AmChanOp=0;
|
||||
chan=chan->next;
|
||||
}
|
||||
}
|
||||
/*logTS=time(NULL);*/
|
||||
signon();
|
||||
joindefault();
|
||||
#endif
|
||||
}
|
||||
|
||||
void ChNick(char *newnick)
|
||||
{
|
||||
char buffer[80];
|
||||
sprintf(buffer,":%s NICK %s :%ld\n",mynick,newnick,now);
|
||||
sendtoserv(buffer);
|
||||
strcpy(mynick,newnick);
|
||||
}
|
||||
763
Sources/opcom.c
Normal file
763
Sources/opcom.c
Normal file
@@ -0,0 +1,763 @@
|
||||
/* @(#)$Id: opcom.c,v 1.19 2000/10/24 16:07:33 lgm Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
|
||||
void CalmDown(char *source, char *chan, char *args)
|
||||
{
|
||||
register aluser *user;
|
||||
register achannel *ch;
|
||||
char buffer[200], channel[80], global[] = "*";
|
||||
|
||||
if ((user = ToLuser(source)) == NULL)
|
||||
{
|
||||
log("ERROR: CalmDown() can't locate user!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (*args == '#')
|
||||
{
|
||||
GetWord(0, args, channel);
|
||||
args = ToWord(1, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(channel, chan);
|
||||
GuessChannel(source, channel);
|
||||
}
|
||||
|
||||
if (!(user->mode & LFL_ISOPER) && Access(global, source) < XADMIN_LEVEL)
|
||||
{
|
||||
notice(source, "This command is reserved for IRC Operators");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(channel, "*"))
|
||||
{
|
||||
notice(source, "SYNTAX: calmdown [channel]");
|
||||
return;
|
||||
}
|
||||
|
||||
ch = ToChannel(channel);
|
||||
|
||||
if (ch == NULL || !ch->on)
|
||||
{
|
||||
notice(source, replies[RPL_NOTONCHANNEL][L_DEFAULT]);
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(buffer, ":%s WALLOPS :%s!%s@%s is asking me to calm down on %s\n",
|
||||
SERVERNAME, user->nick, user->username, user->site, ch->name);
|
||||
sendtoserv(buffer);
|
||||
|
||||
sprintf(buffer, "%s!%s@%s is asking me to calm down on %s\n",
|
||||
user->nick, user->username, user->site, ch->name);
|
||||
broadcast(buffer, 0);
|
||||
|
||||
sprintf(buffer, "CALMDOWN requested by %s!%s@%s on %s",
|
||||
user->nick, user->username, user->site, ch->name);
|
||||
SpecLog(buffer);
|
||||
|
||||
/*
|
||||
part("",channel,"");
|
||||
RemChan("",channel,"");
|
||||
*/
|
||||
ch->flags |= CFL_NOOP;
|
||||
massdeop(channel);
|
||||
#ifdef CALMDOWNTOPIC
|
||||
topic("", channel, CALMDOWNTOPIC);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void OperJoin(char *source, char *chan, char *args)
|
||||
{
|
||||
register aluser *user;
|
||||
register achannel *ch;
|
||||
char buffer[200], channel[80];
|
||||
|
||||
if ((user = ToLuser(source)) == NULL)
|
||||
{
|
||||
log("ERROR: OperJoin() can't locate user!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (*args == '#')
|
||||
{
|
||||
GetWord(0, args, channel);
|
||||
args = ToWord(1, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(channel, chan);
|
||||
GuessChannel(source, channel);
|
||||
}
|
||||
|
||||
if (!(user->mode & LFL_ISOPER))
|
||||
{
|
||||
notice(source, "This command is reserved for IRC Operators");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(channel, "*"))
|
||||
{
|
||||
notice(source, "SYNTAX: operjoin <channel>");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsReg(channel))
|
||||
{
|
||||
notice(source, "That channel is not registered");
|
||||
return;
|
||||
}
|
||||
|
||||
ch = ToChannel(channel);
|
||||
|
||||
if (ch != NULL && ch->on)
|
||||
{
|
||||
notice(source, "I am already on that channel");
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(buffer, ":%s WALLOPS :%s!%s@%s is asking me to join channel %s\n",
|
||||
SERVERNAME, user->nick, user->username, user->site, channel);
|
||||
sendtoserv(buffer);
|
||||
|
||||
sprintf(buffer, "%s!%s@%s is asking me join channel %s\n",
|
||||
user->nick, user->username, user->site, channel);
|
||||
broadcast(buffer, 0);
|
||||
|
||||
sprintf(buffer, "OPERJOIN requested by %s!%s@%s on %s",
|
||||
user->nick, user->username, user->site, channel);
|
||||
SpecLog(buffer);
|
||||
|
||||
join("", channel, "");
|
||||
}
|
||||
|
||||
|
||||
void OperPart(char *source, char *chan, char *args)
|
||||
{
|
||||
register aluser *user;
|
||||
register achannel *ch;
|
||||
char buffer[200], channel[80];
|
||||
|
||||
if ((user = ToLuser(source)) == NULL)
|
||||
{
|
||||
log("ERROR: OperPart() can't locate user!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (*args == '#')
|
||||
{
|
||||
GetWord(0, args, channel);
|
||||
args = ToWord(1, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(channel, chan);
|
||||
GuessChannel(source, channel);
|
||||
}
|
||||
|
||||
if (!(user->mode & LFL_ISOPER))
|
||||
{
|
||||
notice(source, "This command is reserved for IRC Operators");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(channel, "*"))
|
||||
{
|
||||
notice(source, "SYNTAX: operpart [channel]");
|
||||
return;
|
||||
}
|
||||
|
||||
ch = ToChannel(channel);
|
||||
|
||||
if (ch == NULL || !ch->on)
|
||||
{
|
||||
notice(source, "I am not on that channel");
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(buffer, ":%s WALLOPS :%s!%s@%s is asking me to leave channel %s\n",
|
||||
SERVERNAME, user->nick, user->username, user->site, channel);
|
||||
sendtoserv(buffer);
|
||||
|
||||
sprintf(buffer, "%s!%s@%s is asking me to leave channel %s\n",
|
||||
user->nick, user->username, user->site, channel);
|
||||
broadcast(buffer, 0);
|
||||
|
||||
sprintf(buffer, "OPERPART requested by %s!%s@%s on %s",
|
||||
user->nick, user->username, user->site, channel);
|
||||
SpecLog(buffer);
|
||||
|
||||
part("", channel, "");
|
||||
}
|
||||
|
||||
|
||||
void ClearMode(char *source, char *chan, char *args)
|
||||
{
|
||||
register aluser *user;
|
||||
register achannel *ch;
|
||||
register char *curr;
|
||||
register int i;
|
||||
char buffer[200], channel[80], arg[80];
|
||||
|
||||
if ((user = ToLuser(source)) == NULL)
|
||||
{
|
||||
log("ERROR: ClearMode() can't locate user!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (*args == '#')
|
||||
{
|
||||
GetWord(0, args, channel);
|
||||
args = ToWord(1, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(channel, chan);
|
||||
GuessChannel(source, channel);
|
||||
}
|
||||
|
||||
if (!strcmp(channel, "*"))
|
||||
{
|
||||
notice(source, "SYNTAX: clearmode [channel]");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Access(channel, source) < CLEARMODE_LEVEL)
|
||||
{
|
||||
if (user->mode & LFL_ISOPER)
|
||||
{
|
||||
sprintf(buffer, ":%s WALLOPS :%s is using clearmode on %s\n",
|
||||
SERVERNAME, source, channel);
|
||||
sendtoserv(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
ReplyNotAccess(source, channel);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ch = ToChannel(channel)) == NULL)
|
||||
{
|
||||
notice(source, "No such channel!");
|
||||
return;
|
||||
}
|
||||
if (!ch->on || !ch->AmChanOp)
|
||||
{
|
||||
notice(source, replies[RPL_NOTCHANOP][ch->lang]);
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(buffer, "CLEARMODE on %s requested by %s!%s@%s",
|
||||
channel, user->nick, user->username, user->site);
|
||||
log(buffer);
|
||||
|
||||
curr = ch->mode;
|
||||
i = 1;
|
||||
|
||||
while (*curr && *curr != ' ')
|
||||
{
|
||||
if (strchr("kl", *curr))
|
||||
{
|
||||
GetWord(i++, ch->mode, arg);
|
||||
if (*curr == 'k')
|
||||
{
|
||||
changemode(channel, "-k", arg, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
changemode(channel, "-l", "", 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buffer, "-%c", *curr);
|
||||
changemode(channel, buffer, "", 0);
|
||||
}
|
||||
|
||||
curr++;
|
||||
}
|
||||
|
||||
ch->mode[0] = '\0';
|
||||
flushmode(channel);
|
||||
}
|
||||
|
||||
|
||||
void verify(char *source, char *arg)
|
||||
{
|
||||
aluser *luser;
|
||||
char buffer[200], nick[80], global[] = "*", *oper;
|
||||
int acc;
|
||||
|
||||
GetWord(0, arg, nick);
|
||||
if (!*nick)
|
||||
{
|
||||
notice(source, "SYNTAX: verify <nick>");
|
||||
return;
|
||||
}
|
||||
|
||||
luser = ToLuser(nick);
|
||||
if (luser == NULL)
|
||||
{
|
||||
sprintf(buffer, "No such nick: %s", nick);
|
||||
notice(source, buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (luser->mode & LFL_ISOPER)
|
||||
{
|
||||
oper = " and an IRC operator";
|
||||
}
|
||||
else
|
||||
{
|
||||
oper = "";
|
||||
}
|
||||
|
||||
acc = Access(global, nick);
|
||||
if (acc == 1000)
|
||||
{
|
||||
sprintf(buffer, "%s!%s@%s is my daddy%s",
|
||||
luser->nick, luser->username, luser->site, oper);
|
||||
}
|
||||
else if (acc > 900)
|
||||
{
|
||||
sprintf(buffer, "%s!%s@%s is an Official %s coder%s",
|
||||
luser->nick, luser->username, luser->site, VERIFY_ID, oper);
|
||||
}
|
||||
else if (acc == 900)
|
||||
{
|
||||
sprintf(buffer, "%s!%s@%s is my grandma%s",
|
||||
luser->nick, luser->username, luser->site, oper);
|
||||
}
|
||||
else if (acc == 800)
|
||||
{
|
||||
sprintf(buffer, "%s!%s@%s is a Co-ordinator of %s%s",
|
||||
luser->nick, luser->username, luser->site, VERIFY_ID, oper);
|
||||
}
|
||||
else if (acc > 500)
|
||||
{
|
||||
sprintf(buffer, "%s!%s@%s is an Official %s admin%s",
|
||||
luser->nick, luser->username, luser->site, VERIFY_ID, oper);
|
||||
}
|
||||
else if (acc > 0)
|
||||
{
|
||||
sprintf(buffer, "%s!%s@%s is an Official %s helper%s",
|
||||
luser->nick, luser->username, luser->site, VERIFY_ID, oper);
|
||||
}
|
||||
else if (acc < 0)
|
||||
{
|
||||
sprintf(buffer, "%s!%s@%s is a well-known TROUBLEMAKER%s",
|
||||
luser->nick, luser->username, luser->site, oper);
|
||||
}
|
||||
else if (luser->mode & LFL_ISOPER)
|
||||
{
|
||||
sprintf(buffer, "%s!%s@%s is an IRC operator",
|
||||
luser->nick, luser->username, luser->site);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buffer, "%s!%s@%s is NOT an authenticated %s representative",
|
||||
luser->nick, luser->username, luser->site, VERIFY_ID);
|
||||
}
|
||||
notice(source, buffer);
|
||||
}
|
||||
|
||||
#ifdef FAKE_UWORLD
|
||||
void Uworld_switch(char *source, char *ch, char *args)
|
||||
{
|
||||
char buffer[200];
|
||||
aluser *user, *user2;
|
||||
|
||||
user = ToLuser(source);
|
||||
if (!user || !(user->mode & LFL_ISOPER))
|
||||
{
|
||||
notice(source, "This command is reserved to IRC Operators");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcasecmp(args, "ON"))
|
||||
{
|
||||
if (Uworld_status == 1)
|
||||
{
|
||||
sprintf(buffer, "%s is already active", UFAKE_NICK);
|
||||
notice(source, buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((user2 = ToLuser(UFAKE_NICK)) != NULL &&
|
||||
!strcmp(user2->site, DEFAULT_HOSTNAME))
|
||||
{
|
||||
sprintf(buffer, "%s already present!", UFAKE_NICK);
|
||||
notice(source, buffer);
|
||||
return;
|
||||
}
|
||||
if (user2 != NULL)
|
||||
{
|
||||
onquit(UFAKE_NICK);
|
||||
}
|
||||
if (FindServer(&ServerList, UFAKE_SERVER) != NULL)
|
||||
{
|
||||
sprintf(buffer, "%s already present!", UFAKE_SERVER);
|
||||
notice(source, buffer);
|
||||
return;
|
||||
}
|
||||
sprintf(buffer, ":%s WALLOPS :%s activated %s\n",
|
||||
SERVERNAME, source, UFAKE_NICK);
|
||||
sendtoserv(buffer);
|
||||
Uworld_status = 1;
|
||||
IntroduceUworld();
|
||||
sprintf(buffer, "%s activated by %s!%s@%s",
|
||||
UFAKE_NICK, user->nick, user->username, user->site);
|
||||
log(buffer);
|
||||
}
|
||||
}
|
||||
else if (!strcasecmp(args, "OFF"))
|
||||
{
|
||||
if (Uworld_status == 0)
|
||||
{
|
||||
sprintf(buffer, "%s is not active", UFAKE_NICK);
|
||||
notice(source, buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buffer, ":%s WALLOPS :%s deactivated %s\n",
|
||||
SERVERNAME, source, UFAKE_NICK);
|
||||
sendtoserv(buffer);
|
||||
Uworld_status = 0;
|
||||
sprintf(buffer, "Deactivated by %s!%s@%s",
|
||||
user->nick, user->username, user->site);
|
||||
KillUworld(buffer);
|
||||
sprintf(buffer, "%s deactivated by %s!%s@%s",
|
||||
UFAKE_NICK, user->nick, user->username, user->site);
|
||||
log(buffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
notice(source, "SYNTAX: uworld [ON|OFF]");
|
||||
}
|
||||
}
|
||||
|
||||
void parse_uworld_command(char *source, char *args)
|
||||
{
|
||||
char command[80];
|
||||
GetWord(0, args, command);
|
||||
args = ToWord(1, args);
|
||||
|
||||
if (!strcasecmp(command, "OPCOM"))
|
||||
Uworld_opcom(source, args);
|
||||
else if (!strcasecmp(command, "CLEARCHAN"))
|
||||
ClearChan(source, args);
|
||||
else if (!strcasecmp(command, "REOP"))
|
||||
Uworld_reop(source, args);
|
||||
}
|
||||
|
||||
void Uworld_opcom(char *source, char *args)
|
||||
{
|
||||
char buffer[512];
|
||||
char command[80];
|
||||
char channel[80];
|
||||
aluser *user;
|
||||
|
||||
user = ToLuser(source);
|
||||
if (!user || !(user->mode & LFL_ISOPER))
|
||||
{
|
||||
notice(source, "This command is reserved to IRC Operators");
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(buffer, "%s!%s@%s", user->nick, user->username, user->site);
|
||||
if (IsOperSuspended(buffer))
|
||||
{
|
||||
notice(source, "Sorry, Your Uworld access is suspended");
|
||||
return;
|
||||
}
|
||||
|
||||
GetWord(0, args, command);
|
||||
GetWord(1, args, channel);
|
||||
args = ToWord(2, args);
|
||||
|
||||
if (!strcasecmp(command, "MODE"))
|
||||
{
|
||||
if (*channel != '#')
|
||||
{
|
||||
sprintf(buffer, ":%s NOTICE %s :bad channel name\n",
|
||||
UFAKE_NICK, source);
|
||||
sendtoserv(buffer);
|
||||
return;
|
||||
}
|
||||
sprintf(buffer, ":%s WALLOPS :%s is using %s to: MODE %s %s\n",
|
||||
UFAKE_SERVER, source, UFAKE_NICK, channel, args);
|
||||
sendtoserv(buffer);
|
||||
sprintf(buffer, ":%s MODE %s %s\n", UFAKE_SERVER, channel, args);
|
||||
sendtoserv(buffer);
|
||||
sprintf(buffer, "OPCOM MODE %s %s (%s!%s@%s)",
|
||||
channel, args, user->nick, user->username, user->site);
|
||||
log(buffer);
|
||||
ModeChange(UFAKE_SERVER, channel, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buffer, ":%s NOTICE %s :(yet) unsupported command (%s)\n",
|
||||
UFAKE_NICK, source, command);
|
||||
sendtoserv(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ClearChan(char *source, char *args)
|
||||
{
|
||||
register aluser *user;
|
||||
register auser *chanuser;
|
||||
register achannel *ch;
|
||||
register char *curr;
|
||||
register aban *oneban;
|
||||
register int i;
|
||||
char buffer[200], channel[80], arg[80];
|
||||
|
||||
if ((user = ToLuser(source)) == NULL)
|
||||
{
|
||||
log("ERROR: ClearMode() can't locate user!");
|
||||
return;
|
||||
}
|
||||
|
||||
GetWord(0, args, channel);
|
||||
|
||||
if (!strcmp(channel, "*"))
|
||||
{
|
||||
notice(source, "SYNTAX: clearmode [channel]");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!user->mode & LFL_ISOPER)
|
||||
{
|
||||
sprintf(buffer, ":%s NOTICE %s :This command is reserved to IRC Operators\n",
|
||||
UFAKE_NICK, source);
|
||||
sendtoserv(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(buffer, "%s!%s@%s", user->nick, user->username, user->site);
|
||||
if (IsOperSuspended(buffer))
|
||||
{
|
||||
notice(source, "Sorry, Your Uworld access is suspended");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ch = ToChannel(channel)) == NULL)
|
||||
{
|
||||
sprintf(buffer, ":%s NOTICE %s :That channel does not exist\n",
|
||||
UFAKE_NICK, source);
|
||||
sendtoserv(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(buffer, ":%s WALLOPS :%s is using %s to: CLEARCHAN %s\n",
|
||||
UFAKE_SERVER, source, UFAKE_NICK, channel);
|
||||
sendtoserv(buffer);
|
||||
|
||||
sprintf(buffer, "CLEARCHAN on %s requested by %s!%s@%s",
|
||||
channel, user->nick, user->username, user->site);
|
||||
log(buffer);
|
||||
|
||||
chanuser = ch->users;
|
||||
while (chanuser != NULL)
|
||||
{
|
||||
if (chanuser->chanop)
|
||||
{
|
||||
changemode(channel, "-o", chanuser->N->nick, 2);
|
||||
chanuser->chanop = 0;
|
||||
}
|
||||
chanuser = chanuser->next;
|
||||
}
|
||||
|
||||
curr = ch->mode;
|
||||
i = 1;
|
||||
while (*curr && *curr != ' ')
|
||||
{
|
||||
if (strchr("kl", *curr))
|
||||
{
|
||||
GetWord(i++, ch->mode, arg);
|
||||
if (*curr == 'k')
|
||||
{
|
||||
changemode(channel, "-k", arg, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
changemode(channel, "-l", "", 2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buffer, "-%c", *curr);
|
||||
changemode(channel, buffer, "", 2);
|
||||
}
|
||||
|
||||
curr++;
|
||||
}
|
||||
|
||||
ch->mode[0] = '\0';
|
||||
|
||||
for (oneban = ch->bans; oneban != NULL; oneban = oneban->next)
|
||||
{
|
||||
changemode(channel, "-b", oneban->pattern, 2);
|
||||
}
|
||||
flushmode(channel);
|
||||
}
|
||||
|
||||
void Uworld_reop(char *source, char *channel)
|
||||
{
|
||||
register aluser *user;
|
||||
char buffer[200];
|
||||
|
||||
user = ToLuser(source);
|
||||
if (user != NULL && !strcasecmp(user->username, DEFAULT_USERNAME) &&
|
||||
!strcasecmp(user->site, DEFAULT_HOSTNAME))
|
||||
{
|
||||
sprintf(buffer, "%s called for REOP on %s", source, channel);
|
||||
log(buffer);
|
||||
changemode(channel, "+o", source, 2);
|
||||
flushmode(channel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OperSuspend(char *source, char *args)
|
||||
{
|
||||
FILE *in, *out;
|
||||
char Mask[200], strtimeout[80], global[] = "*", buffer[120], tmp[80],
|
||||
*mask = Mask, *ptr;
|
||||
time_t timeout;
|
||||
int add = 1, count = 0;
|
||||
|
||||
if (Access(global, source) < 900)
|
||||
{
|
||||
notice(source, "You don't have access to that command");
|
||||
return;
|
||||
}
|
||||
|
||||
GetWord(0, args, mask);
|
||||
GetWord(1, args, strtimeout);
|
||||
|
||||
if (!*mask)
|
||||
{
|
||||
notice(source, "SYNTAX: opersuspend [+/-]<mask> [timeout]");
|
||||
return;
|
||||
}
|
||||
|
||||
if (*mask == '+')
|
||||
{
|
||||
add = 1;
|
||||
mask++;
|
||||
}
|
||||
else if (*mask == '-')
|
||||
{
|
||||
add = 0;
|
||||
mask++;
|
||||
}
|
||||
|
||||
if (add)
|
||||
{
|
||||
out = fopen("opersuspend.dat", "a");
|
||||
if (!out)
|
||||
{
|
||||
notice(source, "Can't open file opersuspend.dat :(");
|
||||
return;
|
||||
}
|
||||
|
||||
timeout = atol(strtimeout);
|
||||
if (timeout <= 0)
|
||||
timeout = 1999999999;
|
||||
else
|
||||
timeout += now;
|
||||
|
||||
fprintf(out, "%s %ld\n", mask, timeout);
|
||||
fclose(out);
|
||||
notice(source, "1 entry added");
|
||||
}
|
||||
else
|
||||
{
|
||||
in = fopen("opersuspend.dat", "r");
|
||||
if (!in)
|
||||
{
|
||||
notice(source, "Can't open file opersuspend.dat :(");
|
||||
return;
|
||||
}
|
||||
out = fopen("opersuspend.dat.new", "w");
|
||||
if (!in)
|
||||
{
|
||||
notice(source, "Can't open file opersuspend.dat.new :(");
|
||||
return;
|
||||
}
|
||||
|
||||
while (fgets(buffer, 120, in) != NULL)
|
||||
{
|
||||
if ((ptr = strchr(buffer, '\n')) != NULL)
|
||||
*ptr = '\0';
|
||||
GetWord(0, buffer, tmp);
|
||||
if (strcasecmp(tmp, mask) && atol(ToWord(1, buffer)) > now)
|
||||
fprintf(out, "%s\n", buffer);
|
||||
else
|
||||
count++;
|
||||
}
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
rename("opersuspend.dat.new", "opersuspend.dat");
|
||||
|
||||
sprintf(buffer, "Removed %d entry(ies)", count);
|
||||
notice(source, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int IsOperSuspended(char *userhost)
|
||||
{
|
||||
FILE *fp;
|
||||
char buffer[120], mask[200], *ptr;
|
||||
|
||||
if ((fp = fopen("opersuspend.dat", "r")) == NULL)
|
||||
return 0;
|
||||
|
||||
while (fgets(buffer, 120, fp) != NULL)
|
||||
{
|
||||
if ((ptr = strchr(buffer, '\n')) != NULL)
|
||||
*ptr = '\0';
|
||||
GetWord(0, buffer, mask);
|
||||
|
||||
if (atol(ToWord(1, buffer)) > now && match(userhost, mask))
|
||||
{
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
266
Sources/ops.c
Normal file
266
Sources/ops.c
Normal file
@@ -0,0 +1,266 @@
|
||||
/* @(#)$Id: ops.c,v 1.6 1999/04/04 17:00:13 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
|
||||
void op(char *source, char *chan, char *nicklist)
|
||||
{
|
||||
char channel[80];
|
||||
char nick[80];
|
||||
char buffer[200];
|
||||
register auser *user;
|
||||
register achannel *ch;
|
||||
register int i;
|
||||
|
||||
/* if the 1st arg is a channel name.. use it instead of 'chan' */
|
||||
if (*nicklist == '#')
|
||||
{
|
||||
GetWord(0, nicklist, channel);
|
||||
nicklist = ToWord(1, nicklist);
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(channel, chan, 79);
|
||||
channel[79] = '\0';
|
||||
GuessChannel(source, channel);
|
||||
}
|
||||
|
||||
if (!strcmp(channel, "*"))
|
||||
{
|
||||
notice(source, "SYNTAX: op <channel> <nick1> [nick2] [nick3] [...]");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Bad channel.. geez what am I supposed to do with it?? */
|
||||
if ((ch = ToChannel(channel)) == NULL || !ch->on)
|
||||
{
|
||||
notice(source, replies[RPL_NOTONCHANNEL][L_DEFAULT]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ch->AmChanOp)
|
||||
{
|
||||
notice(source, replies[RPL_NOTCHANOP][ch->lang]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (*source && (ch->flags & CFL_OPONLY) &&
|
||||
*nicklist && strcasecmp(nicklist, source))
|
||||
{
|
||||
notice(source, replies[RPL_OPSELFONLY][ch->lang]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (*source && (ch->flags & CFL_NOOP))
|
||||
{
|
||||
notice(source, replies[RPL_NOOP][ch->lang]);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("OP requested....\nCHANNEL: %s\nNICKS: %s\n", channel, nicklist);
|
||||
#endif
|
||||
if (*source && Access(channel, source) < OP_LEVEL)
|
||||
{
|
||||
ReplyNotAccess(source, channel);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!*nicklist)
|
||||
{
|
||||
strcpy(nick, source);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetWord(0, nicklist, nick);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (*nick)
|
||||
{
|
||||
user = ToUser(channel, nick);
|
||||
#ifdef DEBUG
|
||||
if (user)
|
||||
{
|
||||
printf("USER FOUND!\n");
|
||||
printf("nick: %s\n", user->N->nick);
|
||||
printf("Chanop: %s\n", (user->chanop) ? "YES" : "NO");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("USER %s NOT FOUND ON CHANNEL %s\n", nick, channel);
|
||||
}
|
||||
#endif
|
||||
/* the user might be shitlisted.. */
|
||||
|
||||
if (user)
|
||||
{
|
||||
sprintf(buffer, "%s!%s@%s", user->N->nick, user->N->username, user->N->site);
|
||||
if (ch->flags & CFL_STRICTOP && Access(channel, user->N->nick) < OP_LEVEL)
|
||||
{
|
||||
if (*source)
|
||||
{
|
||||
notice(source, "StrictOp is active and user is not authenticated");
|
||||
}
|
||||
}
|
||||
else if (IsShit(channel, buffer, NULL, NULL) < NO_OP_SHIT_LEVEL)
|
||||
{
|
||||
if (user && !user->chanop)
|
||||
{
|
||||
user->chanop = 1;
|
||||
changemode(channel, "+o", nick, 0);
|
||||
if (*source && strcasecmp(source, nick))
|
||||
{
|
||||
sprintf(buffer, replies[RPL_YOUREOPPEDBY][ch->lang], source);
|
||||
notice(nick, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buffer, "%s: %s", nick, replies[RPL_CANTBEOPPED][ch->lang]);
|
||||
notice(source, buffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buffer, replies[RPL_USERNOTONCHANNEL][ch->lang], nick, channel);
|
||||
notice(source, buffer);
|
||||
}
|
||||
|
||||
GetWord(++i, nicklist, nick);
|
||||
}
|
||||
AddEvent(EVENT_FLUSHMODEBUFF, now + MODE_DELAY, channel);
|
||||
}
|
||||
|
||||
void deop(char *source, char *ch, char *nicklist)
|
||||
{
|
||||
char channel[CHANNELNAME_LENGTH];
|
||||
char nick[80];
|
||||
char buffer[200];
|
||||
register auser *user;
|
||||
register achannel *chan;
|
||||
register int i;
|
||||
|
||||
/* if the 1st arg is a channel name.. use it instead of 'channel' */
|
||||
if (*nicklist == '#')
|
||||
{
|
||||
GetWord(0, nicklist, channel);
|
||||
nicklist = ToWord(1, nicklist);
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(channel, ch, CHANNELNAME_LENGTH);
|
||||
GuessChannel(source, channel);
|
||||
}
|
||||
|
||||
if (!strcmp(channel, "*"))
|
||||
{
|
||||
notice(source, "SYNTAX: deop <channel> <nick1> [nick2] [nick3] [...]");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("DEOP requested....\nCHANNEL: %s\nNICKS: %s\n", channel, nicklist);
|
||||
#endif
|
||||
|
||||
if ((chan = ToChannel(channel)) == NULL || !chan->on)
|
||||
{
|
||||
notice(source, replies[RPL_NOTONCHANNEL][L_DEFAULT]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (*source && (chan->flags & CFL_OPONLY))
|
||||
{
|
||||
notice(source, replies[RPL_OPONLY][chan->lang]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!chan->AmChanOp)
|
||||
{
|
||||
notice(source, replies[RPL_NOTCHANOP][chan->lang]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (*source && Access(channel, source) < OP_LEVEL)
|
||||
{
|
||||
ReplyNotAccess(source, channel);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!*nicklist)
|
||||
{
|
||||
notice(source, "SYNTAX: deop [channel] <nick1> [nick2] [nick3] [...]");
|
||||
return;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
GetWord(i, nicklist, nick);
|
||||
while (*nick)
|
||||
{
|
||||
user = ToUser(channel, nick);
|
||||
if (user)
|
||||
{
|
||||
sprintf(buffer, "%s!%s@%s",
|
||||
user->N->nick, user->N->username, user->N->site);
|
||||
if (user && user->chanop)
|
||||
{
|
||||
user->chanop = 0;
|
||||
changemode(channel, "-o", nick, 0);
|
||||
if (*source && strcasecmp(source, nick))
|
||||
{
|
||||
sprintf(buffer, replies[RPL_YOUREDEOPPEDBY][chan->lang], source);
|
||||
notice(nick, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
GetWord(++i, nicklist, nick);
|
||||
}
|
||||
AddEvent(EVENT_FLUSHMODEBUFF, now + MODE_DELAY, channel);
|
||||
}
|
||||
|
||||
void massdeop(char *channel)
|
||||
{
|
||||
achannel *chan;
|
||||
auser *user;
|
||||
|
||||
chan = ToChannel(channel);
|
||||
if (chan == NULL || !chan->on || !chan->AmChanOp)
|
||||
return;
|
||||
|
||||
user = chan->users;
|
||||
while (user != NULL)
|
||||
{
|
||||
if (user->chanop)
|
||||
{
|
||||
changemode(channel, "-o", user->N->nick, 0);
|
||||
user->chanop = 0;
|
||||
}
|
||||
user = user->next;
|
||||
}
|
||||
flushmode(channel);
|
||||
}
|
||||
351
Sources/patch.c
Normal file
351
Sources/patch.c
Normal file
@@ -0,0 +1,351 @@
|
||||
/* @(#)$Id: patch.c,v 1.3 1996/11/13 00:40:46 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef UPGRADE
|
||||
|
||||
static void misc_closed_conn(misc_socket *);
|
||||
|
||||
void upgrade(char *source, char *args)
|
||||
{
|
||||
char global[]="*";
|
||||
|
||||
if(Access(global,source)<LEVEL_UPGRADE){
|
||||
notice(source,"This command is not for you");
|
||||
return;
|
||||
}
|
||||
|
||||
open_patch_socket(source);
|
||||
}
|
||||
|
||||
void open_patch_socket(char *source)
|
||||
{
|
||||
misc_socket *msock;
|
||||
struct sockaddr_in socketname;
|
||||
struct hostent *remote_host;
|
||||
char pserver[80]=PATCH_SERVER, buffer[200], *ptr;
|
||||
int port;
|
||||
|
||||
if((ptr=strchr(pserver,':'))==NULL){
|
||||
notice(source,"PATCH_SERVER needs to be \"server:port\"!");
|
||||
return;
|
||||
}
|
||||
*(ptr++)='\0';
|
||||
sscanf(ptr,"%d",&port);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Connecting to patch server %s on port %d\n",pserver,port);
|
||||
#endif
|
||||
sprintf(buffer,"Connecting to patch server %s on port %d",pserver,port);
|
||||
log(buffer);
|
||||
|
||||
notice(source,"Attempting to contact patch server...");
|
||||
|
||||
msock=(misc_socket *)MALLOC(sizeof(misc_socket));
|
||||
msock->type=MISC_GETPATCH;
|
||||
msock->status=MISC_CONNECTING;
|
||||
msock->TS=now;
|
||||
strcpy(msock->link,source);
|
||||
msock->inbuf=NULL;
|
||||
msock->outbuf=NULL;
|
||||
|
||||
if((msock->fd=socket(AF_INET,SOCK_STREAM,0))<0){
|
||||
free(msock);
|
||||
sprintf(buffer,"Can't assigned fd for socket: %s",sys_errlist[errno]);
|
||||
notice(source,buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
fcntl(msock->fd,F_SETFL,O_NONBLOCK);
|
||||
|
||||
socketname.sin_family=AF_INET;
|
||||
if((remote_host=gethostbyname(pserver))==NULL){
|
||||
sprintf(buffer,"gethostbyname() failed for %s: %s",pserver,sys_errlist[errno]);
|
||||
notice(source,buffer);
|
||||
close(msock->fd);
|
||||
free(msock);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy((void *)&socketname.sin_addr,(void *)remote_host->h_addr,remote_host->h_length);
|
||||
socketname.sin_port = htons(port);
|
||||
|
||||
if(connect(msock->fd,(struct sockaddr *)&socketname,sizeof(socketname))<0
|
||||
&& errno != EINPROGRESS){
|
||||
close(msock->fd);
|
||||
sprintf(buffer,"Can't connect() to %s: %s",pserver,sys_errlist[errno]);
|
||||
notice(source,buffer);
|
||||
free(msock);
|
||||
return;
|
||||
}
|
||||
|
||||
msock->next=MiscList;
|
||||
MiscList=msock;
|
||||
|
||||
send_misc_handshake(msock);
|
||||
}
|
||||
|
||||
|
||||
int readfrom_misc(misc_socket *msock)
|
||||
{
|
||||
void parse_misc(misc_socket *,char *);
|
||||
char buf[1024];
|
||||
int length;
|
||||
if((length=read(msock->fd,buf,1023))<=0){
|
||||
if(errno==EWOULDBLOCK || errno==EAGAIN){
|
||||
return 0;
|
||||
}else{
|
||||
misc_closed_conn(msock);
|
||||
close(msock->fd);
|
||||
msock->fd=-1;
|
||||
msock->status=MISC_ERROR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
buf[length]='\0';
|
||||
|
||||
copy_to_buffer(&msock->inbuf,buf,length);
|
||||
|
||||
if(find_char_in_buffer(&msock->inbuf,'\n',1023)){
|
||||
while(find_char_in_buffer(&msock->inbuf,'\n',1023)){
|
||||
copy_from_buffer(&msock->inbuf,buf,'\n',1023);
|
||||
parse_misc(msock,buf);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int flush_misc_buffer(misc_socket *msock)
|
||||
{
|
||||
char buf[1024];
|
||||
int length;
|
||||
int count;
|
||||
|
||||
if(msock->status==MISC_CONNECTING){
|
||||
msock->status=MISC_HANDSHAKE;
|
||||
notice(msock->link,"Connected.");
|
||||
}
|
||||
|
||||
if(msock==NULL || msock->outbuf==NULL)
|
||||
return -1;
|
||||
|
||||
while((count = look_in_buffer(&msock->outbuf,buf,'\0',1023))>0){
|
||||
if((length=write(msock->fd,buf,count))<=0){
|
||||
if((errno==EWOULDBLOCK || errno==EAGAIN) && length!=0){
|
||||
return 0;
|
||||
}else{
|
||||
misc_closed_conn(msock);
|
||||
close(msock->fd);
|
||||
msock->fd=-1;
|
||||
msock->status=MISC_ERROR;
|
||||
return -1;
|
||||
}
|
||||
}else{
|
||||
skip_char_in_buffer(&msock->outbuf,length);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long sendto_misc(misc_socket *msock, char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
char string[1024];
|
||||
|
||||
va_start(args,format);
|
||||
vsprintf(string,format,args);
|
||||
#ifdef DEBUG
|
||||
vprintf(format,args);
|
||||
#endif
|
||||
va_end(args);
|
||||
|
||||
return copy_to_buffer(&msock->outbuf,string,strlen(string));
|
||||
}
|
||||
|
||||
|
||||
void send_misc_handshake(misc_socket *msock)
|
||||
{
|
||||
struct stat stlast;
|
||||
char tag[80], buffer[200];
|
||||
FILE *fp;
|
||||
|
||||
if(msock->type==MISC_GETPATCH){
|
||||
if(stat("lastupgrade",&stlast)<0){
|
||||
sprintf(buffer,"lastupgrade: %s",
|
||||
sys_errlist[errno]);
|
||||
notice(msock->link,buffer);
|
||||
close(msock->fd);
|
||||
msock->status=MISC_ERROR;
|
||||
}
|
||||
fp=fopen("lastupgrade","r");
|
||||
if(fp==NULL){
|
||||
close(msock->fd);
|
||||
msock->fd=-1;
|
||||
msock->status=MISC_ERROR;
|
||||
sprintf(buffer,"lastupgrade: %s",sys_errlist[errno]);
|
||||
notice(msock->link,buffer);
|
||||
return;
|
||||
}
|
||||
fgets(tag,80,fp);
|
||||
fclose(fp);
|
||||
|
||||
sendto_misc(msock,"%s\n%s\n",GETPATCHPASS,tag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void misc_closed_conn(misc_socket *msock)
|
||||
{
|
||||
int pipefd[2],i;
|
||||
char *ptr;
|
||||
|
||||
if(msock->type==MISC_GETPATCH){
|
||||
if(msock->status==MISC_CONNECTING)
|
||||
notice(msock->link,"Connection refused.");
|
||||
else if(msock->status==MISC_HANDSHAKE)
|
||||
notice(msock->link,"Handshake failed.");
|
||||
else
|
||||
notice(msock->link,"Connection closed.");
|
||||
}else if(msock->type==MISC_PIPE_PATCH){
|
||||
notice(msock->link,"patch process exited.");
|
||||
|
||||
pipe(pipefd);
|
||||
switch(fork()){
|
||||
case 0:
|
||||
dup2(pipefd[1],1);
|
||||
dup2(pipefd[1],2);
|
||||
close(0);
|
||||
for(i=3;i<MAX_CONNECTIONS;i++) close(i);
|
||||
execl(MAKE,MAKE,(char *)0);
|
||||
exit(-1);
|
||||
case -1:
|
||||
notice(msock->link,"fork() failed!");
|
||||
/* socket already closed.. */
|
||||
break;
|
||||
default:
|
||||
notice(msock->link,"Spawning make..");
|
||||
close(pipefd[1]);
|
||||
ptr=msock->link;
|
||||
msock=(misc_socket *)MALLOC(sizeof(misc_socket));
|
||||
msock->fd=pipefd[0];
|
||||
msock->type=MISC_PIPE_MAKE;
|
||||
msock->status=MISC_RECV;
|
||||
msock->TS=now;
|
||||
strcpy(msock->link,ptr);
|
||||
msock->inbuf=NULL;
|
||||
msock->outbuf=NULL;
|
||||
msock->next=MiscList;
|
||||
MiscList=msock;
|
||||
break;
|
||||
}
|
||||
}else if(msock->type==MISC_PIPE_MAKE){
|
||||
notice(msock->link,"make process exited.");
|
||||
}else{
|
||||
notice(msock->link,"Connection closed.");
|
||||
}
|
||||
}
|
||||
|
||||
void parse_misc(misc_socket *msock, char *line)
|
||||
{
|
||||
FILE *fp;
|
||||
int fdpipe[2],i;
|
||||
char *ptr;
|
||||
|
||||
if(msock->status==MISC_CONNECTING){
|
||||
msock->status=MISC_HANDSHAKE;
|
||||
notice(msock->link,"Connected!");
|
||||
}
|
||||
|
||||
while((ptr=strpbrk(line,"\r\n"))!=NULL)
|
||||
*ptr='\0';
|
||||
|
||||
if(!*line)
|
||||
return;
|
||||
|
||||
if(msock->type==MISC_GETPATCH){
|
||||
if(msock->status==MISC_HANDSHAKE){
|
||||
if(strcmp(RECPATCHPASS,line)){
|
||||
close(msock->fd);
|
||||
msock->fd=-1;
|
||||
msock->status=MISC_ERROR;
|
||||
notice(msock->link,"Bad password!");
|
||||
return;
|
||||
}
|
||||
msock->status=MISC_RECV;
|
||||
}else if(msock->status==MISC_RECV){
|
||||
fp=fopen("lastupgrade","w");
|
||||
if(fp!=NULL){
|
||||
fprintf(fp,"%s\n",line);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/* spawn patch */
|
||||
pipe(fdpipe);
|
||||
switch(fork()){
|
||||
case 0:
|
||||
fcntl(msock->fd,F_SETFL,0);
|
||||
dup2(msock->fd,0);
|
||||
dup2(fdpipe[1],1);
|
||||
dup2(fdpipe[1],2);
|
||||
for(i=3;i<MAX_CONNECTIONS;i++) close(i);
|
||||
putenv("IFS="); /* I'm paranoid */
|
||||
execl("/bin/sh","[patch script]","-c",
|
||||
"tee upgrade.patch | "PATCH" -p1",
|
||||
(char *)0);
|
||||
exit(-1);
|
||||
case -1:
|
||||
notice(msock->link,"fork() failed");
|
||||
close(msock->fd);
|
||||
msock->fd=-1;
|
||||
msock->status=MISC_ERROR;
|
||||
break;
|
||||
default:
|
||||
notice(msock->link,"Spawning patch script..");
|
||||
close(msock->fd);
|
||||
while(msock->inbuf!=NULL){
|
||||
char buf[512];
|
||||
int l;
|
||||
l=copy_from_buffer(&msock->inbuf,buf,'\0',511);
|
||||
write(fdpipe[1],buf,l);
|
||||
}
|
||||
close(fdpipe[1]);
|
||||
msock->fd=fdpipe[0];
|
||||
msock->type=MISC_PIPE_PATCH;
|
||||
zap_buffer(&msock->outbuf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else if(msock->type==MISC_PIPE_PATCH || msock->type==MISC_PIPE_MAKE){
|
||||
notice(msock->link,line);
|
||||
}
|
||||
}
|
||||
#endif /* UPGRADE */
|
||||
405
Sources/privmsg.c
Normal file
405
Sources/privmsg.c
Normal file
@@ -0,0 +1,405 @@
|
||||
/* @(#)$Id: privmsg.c,v 1.22 2000/10/24 16:04:24 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
|
||||
void privmsg(char *source, char *target, char *body)
|
||||
{
|
||||
register auser *user;
|
||||
register achannel *chan;
|
||||
register char *ptr;
|
||||
char global[] = "*";
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("PRIVMSG from %s to %s\n", source, target);
|
||||
#endif
|
||||
|
||||
if ((*target == '#' || *target == '$') && strchr(target, '*'))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("Received WALL... ignoring.. \n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/* CTCP */
|
||||
if (body[1] == '\001' && (ptr = strchr(body + 2, '\001')) != NULL)
|
||||
{
|
||||
if (*target == '#' || *target == '&')
|
||||
{
|
||||
if (CheckFlood(source, target, strlen(ToWord(1, body + 1))))
|
||||
return;
|
||||
}
|
||||
|
||||
*ptr = '\0';
|
||||
if (!IsIgnored(source) &&
|
||||
!CheckPrivateFlood(source, strlen(body), "CTCP-"))
|
||||
parse_ctcp(source, target, body + 2);
|
||||
}
|
||||
|
||||
/* PRIVMSG TO A CHANNEL */
|
||||
else if (*target == '#' || *target == '&')
|
||||
{
|
||||
/* PRIVMSG #blah@channels.undernet.org ?? */
|
||||
if (!(chan = ToChannel(target)))
|
||||
return;
|
||||
chan->lastact = now;
|
||||
user = ToUser(target, source);
|
||||
if (!user)
|
||||
return; /* not on channel.. happens if not +n */
|
||||
user->lastact = now;
|
||||
|
||||
if (CheckFlood(source, target, strlen(ToWord(1, body + 1))))
|
||||
return;
|
||||
|
||||
if (!strncmp(body + 1, COMMAND_PREFIX, strlen(COMMAND_PREFIX)))
|
||||
parse_command(source, target, target, body + strlen(COMMAND_PREFIX) + 1);
|
||||
|
||||
/* PRIVATE PRIVMSG */
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!IsIgnored(source) && !CheckPrivateFlood(source, strlen(body), "MSG-"))
|
||||
{
|
||||
#ifdef FAKE_UWORLD
|
||||
if (!strcasecmp(target, UFAKE_NICK))
|
||||
{
|
||||
parse_uworld_command(source, body + 1);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
parse_command(source, target, global, body + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void parse_command(char *source, char *target, char *channel, char *commandline)
|
||||
{
|
||||
char buffer[1024];
|
||||
char command[80];
|
||||
char global[] = "*";
|
||||
register aluser *user;
|
||||
|
||||
GetWord(0, commandline, command);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("PARSING COMMAND: %s\nCOMMAND: %s\nARGS: %s\nSOURCE: %s\n",
|
||||
commandline, command, ToWord(1, commandline), source);
|
||||
#endif
|
||||
|
||||
user = ToLuser(source);
|
||||
|
||||
/* all commands must come from a user */
|
||||
if (user == NULL)
|
||||
return;
|
||||
|
||||
if (strcasecmp(command, "pass") && strcasecmp(command, "login") &&
|
||||
strcasecmp(command, "newpass"))
|
||||
{
|
||||
sprintf(buffer, "COMMAND FROM %s!%s@%s on %s: %s",
|
||||
user->nick, user->username, user->site,
|
||||
channel, commandline);
|
||||
log(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buffer, "COMMAND FROM %s!%s@%s on %s: %s XXXXXXX",
|
||||
user->nick, user->username, user->site,
|
||||
channel, command);
|
||||
log(buffer);
|
||||
}
|
||||
|
||||
if (!strcmp(command, "showcommands"))
|
||||
showcommands(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "pass") || !strcmp(command, "login"))
|
||||
validate(source, target, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "deauth"))
|
||||
DeAuth(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "die") && Access(global, source) >= LEVEL_DIE)
|
||||
quit(ToWord(1, commandline), 0);
|
||||
|
||||
else if (!strcmp(command, "restart") && Access(global, source) >= LEVEL_DIE)
|
||||
restart(ToWord(1, commandline)); /* added by Kev; restarts */
|
||||
|
||||
else if (!strcmp(command, "search"))
|
||||
SearchChan(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "join"))
|
||||
join(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "part"))
|
||||
part(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "op"))
|
||||
op(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "deop"))
|
||||
deop(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "banlist"))
|
||||
showbanlist(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "kick"))
|
||||
kick(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "invite"))
|
||||
invite(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "topic"))
|
||||
topic(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "adduser"))
|
||||
AddUser(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "remuser"))
|
||||
RemoveUser(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "modinfo"))
|
||||
ModUserInfo(source, target, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "newpass"))
|
||||
ChPass(source, target, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "set"))
|
||||
SetChanFlag(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "access"))
|
||||
showaccess(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "suspend"))
|
||||
suspend(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "unsuspend"))
|
||||
unsuspend(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "saveuserlist"))
|
||||
SaveUserList(source, channel);
|
||||
|
||||
else if (!strcmp(command, "lbanlist"))
|
||||
ShowShitList(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "ban"))
|
||||
AddToShitList(source, channel, ToWord(1, commandline), 0);
|
||||
|
||||
else if (!strcmp(command, "unban"))
|
||||
RemShitList(source, channel, ToWord(1, commandline), 0);
|
||||
|
||||
else if (!strcmp(command, "cleanbanlist"))
|
||||
CleanShitList(source, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "addchan"))
|
||||
AddChan(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "remchan"))
|
||||
RemChan(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "savedefs"))
|
||||
SaveDefs(source);
|
||||
|
||||
else if (!strcmp(command, "loaddefs"))
|
||||
LoadDefs(source);
|
||||
|
||||
else if (!strcmp(command, "saveshitlist"))
|
||||
SaveShitList(source, channel);
|
||||
|
||||
else if (!strcmp(command, "loadshitlist"))
|
||||
LoadShitList(source);
|
||||
|
||||
else if (!strcmp(command, "status"))
|
||||
showstatus(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "map"))
|
||||
showmap(source);
|
||||
|
||||
else if (!strcmp(command, "help"))
|
||||
showhelp(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "chaninfo"))
|
||||
ShowChanInfo(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "motd"))
|
||||
showmotd(source);
|
||||
|
||||
else if (!strcmp(command, "isreg"))
|
||||
isreg(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "core"))
|
||||
dumpcore(source);
|
||||
|
||||
#ifdef RUSAGE_SELF
|
||||
else if (!strcmp(command, "rusage"))
|
||||
show_rusage(source);
|
||||
#endif
|
||||
|
||||
else if (!strcmp(command, "showignore"))
|
||||
ShowIgnoreList(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "remignore"))
|
||||
AdminRemoveIgnore(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "calmdown"))
|
||||
CalmDown(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "operjoin"))
|
||||
OperJoin(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "operpart"))
|
||||
OperPart(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "clearmode"))
|
||||
ClearMode(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "purge"))
|
||||
purge(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "verify"))
|
||||
verify(source, ToWord(1, commandline));
|
||||
|
||||
#ifdef UPGRADE
|
||||
else if (!strcmp(command, "upgrade"))
|
||||
upgrade(source, ToWord(1, commandline));
|
||||
#endif
|
||||
|
||||
else if (!strcmp(command, "random"))
|
||||
RandomChannel(source);
|
||||
|
||||
else if (!strcmp(command, "say"))
|
||||
Say(source, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "servnotice"))
|
||||
ServNotice(source, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "fuck"))
|
||||
notice(source, "This command is obsolete");
|
||||
|
||||
#ifdef DEBUG
|
||||
else if (!strcmp(command, "db"))
|
||||
db_test(source, channel, ToWord(1, commandline));
|
||||
#endif
|
||||
|
||||
#ifdef DOHTTP
|
||||
else if (!strcmp(command, "rehash"))
|
||||
read_http_conf(source);
|
||||
#endif
|
||||
#ifdef FAKE_UWORLD
|
||||
else if (!strcmp(command, "uworld"))
|
||||
Uworld_switch(source, channel, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "opersuspend"))
|
||||
OperSuspend(source, ToWord(1, commandline));
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
else if (!strcmp(command, "showusers"))
|
||||
showusers(ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "showchannels"))
|
||||
showchannels();
|
||||
#endif
|
||||
|
||||
#ifdef NICKSERV
|
||||
else if (!strcmp(command, "nickserv"))
|
||||
nserv_nickserv(source, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "addnick"))
|
||||
nserv_addnick(source, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "remnick"))
|
||||
nserv_remnick(source, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "addmask"))
|
||||
nserv_addmask(source, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "remmask"))
|
||||
nserv_remmask(source, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "nickinfo"))
|
||||
nserv_nickinfo(source, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "identify"))
|
||||
nserv_identify(source, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "ghost"))
|
||||
nserv_ghost(source, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "nicknewpass"))
|
||||
nserv_nicknewpass(source, ToWord(1, commandline));
|
||||
|
||||
else if (!strcmp(command, "nicknewemail"))
|
||||
nserv_nicknewemail(source, ToWord(1, commandline));
|
||||
#endif
|
||||
#ifdef DOHTTP
|
||||
else if (!strcmp(command, "dccme"))
|
||||
DccMe(source, ToWord(1, commandline));
|
||||
#endif
|
||||
}
|
||||
|
||||
void parse_ctcp(char *source, char *target, char *body)
|
||||
{
|
||||
char func[80];
|
||||
char buffer[1024];
|
||||
char tmp[80];
|
||||
|
||||
GetWord(0, body, func);
|
||||
body = ToWord(1, body);
|
||||
|
||||
if (strcmp(func, "ACTION"))
|
||||
{
|
||||
sprintf(buffer, "CTCP %s from %s [%s]", func, source, body);
|
||||
log(buffer);
|
||||
}
|
||||
|
||||
if (match(func, "PING"))
|
||||
{
|
||||
sprintf(buffer, "\001PING %s\001", body);
|
||||
notice(source, buffer);
|
||||
}
|
||||
else if (match(func, "TIME"))
|
||||
{
|
||||
strcpy(tmp, ctime(&now));
|
||||
*strchr(tmp, '\n') = '\0';
|
||||
sprintf(buffer, "\001TIME %s\001", tmp);
|
||||
notice(source, buffer);
|
||||
}
|
||||
else if (match(func, "ITIME"))
|
||||
{
|
||||
sprintf(buffer, "\001ITIME @%03ld\001",
|
||||
1000 * ((now + 3600) % 86400) / 86400);
|
||||
notice(source, buffer);
|
||||
}
|
||||
else if (match(func, "VERSION"))
|
||||
{
|
||||
sprintf(buffer, "\001VERSION %s\001", VERSION);
|
||||
notice(source, buffer);
|
||||
}
|
||||
else if (match(func, "GENDER"))
|
||||
{
|
||||
notice(source, "\001GENDER I'm a male bot! Are you a pretty young bottesse?\001");
|
||||
}
|
||||
}
|
||||
271
Sources/prototypes.h
Normal file
271
Sources/prototypes.h
Normal file
@@ -0,0 +1,271 @@
|
||||
/* @(#)$Id: prototypes.h,v 1.20 2000/10/24 15:15:53 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
void log(char *);
|
||||
void SpecLog(char *);
|
||||
void LogChan(void);
|
||||
int connection(char *);
|
||||
void try_later(char *);
|
||||
void sendtoserv(char *);
|
||||
int wait_msg(void);
|
||||
void dumpbuff(void);
|
||||
void rec_sigsegv(int);
|
||||
void rec_sigbus(int);
|
||||
void rec_sigterm(int);
|
||||
void rec_sigint(int);
|
||||
void dumpcore(char *);
|
||||
void show_rusage(char *);
|
||||
void regist(void);
|
||||
void signon(void);
|
||||
void onserver(char *,char *,char *);
|
||||
void onsettime(char *,char *);
|
||||
void onsquit(char *,char *,char *);
|
||||
aserver *ToServer(char *);
|
||||
aserver **FindServer(aserver **, char *);
|
||||
char *ToWord(int,char *);
|
||||
void GetWord(int,char *,char *);
|
||||
char *time_remaining(time_t);
|
||||
void proc(char *,char *, char *, char *);
|
||||
void pong(char *);
|
||||
void showversion(char *);
|
||||
int reconnect(char *server);
|
||||
int xmatch(char *, char *);
|
||||
int compare(char *, char *);
|
||||
int match(char *, char *);
|
||||
int regex_cmp(char *patern, char *string);
|
||||
int mycasecmp(char *,char *);
|
||||
int key_match(char *,char *[]);
|
||||
void string_swap(char *, size_t, char *, char *);
|
||||
int quit(char *, int);
|
||||
int restart(char *); /* added for restart function -Kev */
|
||||
void showcommands(char *,char *,char *);
|
||||
void showhelp(char *,char *,char *);
|
||||
void showmotd(char *);
|
||||
void ShowChanInfo(char *,char *,char *);
|
||||
void isreg(char *,char *,char *);
|
||||
void LoadUserList(char *);
|
||||
void SaveUserList(char *,char *);
|
||||
void DelChannel(char *);
|
||||
void FreeUser(auser *);
|
||||
void NewChannel(char *,time_t,int);
|
||||
void QuitAll(void);
|
||||
void privmsg(char *,char *,char *);
|
||||
void parse_command(char *,char *,char *,char *);
|
||||
int GuessChannel(char *, char *);
|
||||
void try_find(char *,aluser *);
|
||||
int LAccess(char *,aluser *);
|
||||
int Access(char *,char *);
|
||||
void verify(char *, char *);
|
||||
RegUser *IsValid(aluser *,char *);
|
||||
int IsShit(char *,char *,char *, char *);
|
||||
void AddUser(char *,char *,char *);
|
||||
void showaccess(char *,char *,char *);
|
||||
void RemoveUser(char *,char *,char *);
|
||||
void ModUserInfo(char *,char *,char *,char *);
|
||||
void purge(char *,char *,char *);
|
||||
void ChPass(char *,char *,char *);
|
||||
void SetChanFlag(char *,char *,char *);
|
||||
void free_user(RegUser **);
|
||||
void validate(char *,char *,char *);
|
||||
void DeAuth(char *, char *, char *);
|
||||
void join(char *,char *,char *);
|
||||
void joindefault(void);
|
||||
void SendBurst(void);
|
||||
void invite(char *,char *,char *);
|
||||
void part(char *,char *,char *);
|
||||
void oninvite(char *,char *);
|
||||
void onjoin(char *,char *);
|
||||
void onpart(char *,char *);
|
||||
void onkick(char *,char *,char *);
|
||||
void onop(char *,char *,char *);
|
||||
void ondeop(char *,char *,char *,int *);
|
||||
void GetOps(char *);
|
||||
int IsOpless(char *);
|
||||
void onopless(char *);
|
||||
void onnick(char *,char *,char *);
|
||||
void onban(char *,char *,char *);
|
||||
void onunban(char *,char *,char *);
|
||||
void showbanlist(char *,char *,char *);
|
||||
void AddBan(char *,char *);
|
||||
void RemBan(char *,char *);
|
||||
void onwhois(char *,char *);
|
||||
void UserQuit(char *);
|
||||
achannel *ToChannel(char *);
|
||||
auser *ToUser(char *,char *);
|
||||
aluser *ToLuser(char *);
|
||||
void onquit(char *);
|
||||
void onkill(char *,char *,char *);
|
||||
void onwho(char *);
|
||||
void showusers(char *);
|
||||
void showchannels(void);
|
||||
void setchanmode(char *);
|
||||
void ModeChange(char *,char *,char *);
|
||||
void changemode(char *,char *,char *,int);
|
||||
void flushmode(char *);
|
||||
void bounce(char *,char *,time_t);
|
||||
int IsSet(char *,char,char *);
|
||||
void op(char *,char *,char *);
|
||||
void deop(char *,char *,char *);
|
||||
void massdeop(char *);
|
||||
void MakeBanMask(aluser *, char *);
|
||||
void ban(char *,char *,char *);
|
||||
void mban(char *,char *,char *);
|
||||
void unban(char *,char *,char *);
|
||||
void kick(char *,char *,char *);
|
||||
void topic(char *,char *,char *);
|
||||
void notice(char *,char *);
|
||||
void servnotice(char *,char *);
|
||||
void broadcast(char *,int);
|
||||
void NickInUse(void);
|
||||
void ChNick(char *);
|
||||
void AddToShitList(char *, char *, char *,int);
|
||||
void RemShitList(char *,char *,char *,int);
|
||||
void CleanShitList(char *,char *);
|
||||
void suspend(char *, char *, char *);
|
||||
void unsuspend(char *, char *, char *);
|
||||
void ShowShitList(char *,char *,char *);
|
||||
void LoadDefs(char *);
|
||||
void SearchChan(char *,char *,char *);
|
||||
void AddChan(char *,char *,char *);
|
||||
void SaveDefs(char *);
|
||||
void RemChan(char *, char *, char *);
|
||||
int CheckFlood(char *,char *,int);
|
||||
int CheckAdduserFlood(char *, char *);
|
||||
void ontopic(char *,char *,char *);
|
||||
void onnotice(char *,char *,char *);
|
||||
void LoadShitList(char *);
|
||||
void SaveShitList(char *,char *);
|
||||
void parse_ctcp(char *,char *,char *);
|
||||
void showstatus(char *,char *,char *);
|
||||
void showmap(char *);
|
||||
void showserv(char *,aserver *, int *);
|
||||
void InitEvent(void);
|
||||
void AddEvent(int, time_t, char *);
|
||||
void CheckEvent(void);
|
||||
void CleanIgnores(void);
|
||||
void AddIgnore(char *,char *,int);
|
||||
int CheckPrivateFlood(char *,int,char *);
|
||||
int CheckFloodFlood(char *,int);
|
||||
int IsIgnored(char *);
|
||||
void ShowIgnoreList(char *,char *,char *);
|
||||
void AdminRemoveIgnore(char *, char *, char *);
|
||||
void CalmDown(char *,char *,char *);
|
||||
void OperJoin(char *,char *,char *);
|
||||
void OperPart(char *,char *,char *);
|
||||
void ClearMode(char *, char *, char *);
|
||||
void ReplyNotAccess(char *,char *);
|
||||
void CheckIdleChannels(void);
|
||||
void RandomChannel(char *);
|
||||
void Say(char *,char *);
|
||||
void RobinSay(char *,char *);
|
||||
void ServNotice(char *,char *);
|
||||
int IsReg(char *);
|
||||
#ifdef FAKE_UWORLD
|
||||
void IntroduceUworld(void);
|
||||
void KillUworld(char *);
|
||||
void Uworld_switch(char *,char *,char *);
|
||||
void parse_uworld_command(char *,char *);
|
||||
void Uworld_opcom(char *,char *);
|
||||
void ClearChan(char *, char *);
|
||||
void Uworld_reop(char *, char *);
|
||||
void OperSuspend(char *, char *);
|
||||
int IsOperSuspended(char *);
|
||||
#endif
|
||||
#ifdef NICKSERV
|
||||
void IntroduceNickserv(void);
|
||||
#endif
|
||||
#ifdef DOHTTP
|
||||
void open_http(void);
|
||||
void remove_httpsock(http_socket *old);
|
||||
void http_accept(int sock);
|
||||
void parse_http(http_socket *hsock, char *buf);
|
||||
void readfrom_file(http_file_pipe *fpipe);
|
||||
void destroy_file_pipe(http_file_pipe *old);
|
||||
void read_http_conf(char *);
|
||||
long sendto_http(http_socket *sck, char *format, ...);
|
||||
int readfrom_http(http_socket *);
|
||||
int flush_http_buffer(http_socket *);
|
||||
#endif
|
||||
void upgrade(char *,char *);
|
||||
void open_patch_socket(char *);
|
||||
int readfrom_misc(misc_socket *);
|
||||
int flush_misc_buffer(misc_socket *);
|
||||
long sendto_misc(misc_socket *, char *, ...);
|
||||
void send_misc_handshake(misc_socket *);
|
||||
|
||||
struct buffer_block *get_buffer_block(void);
|
||||
void return_buffer_block(struct buffer_block *);
|
||||
int copy_from_buffer(struct buffer_block **, char *, char, int);
|
||||
int look_in_buffer(struct buffer_block **, char *, char, int);
|
||||
long copy_to_buffer(struct buffer_block **, char *,int);
|
||||
int zap_buffer(struct buffer_block **);
|
||||
int find_char_in_buffer(struct buffer_block **, char,int);
|
||||
int skip_char_in_buffer(struct buffer_block **, int);
|
||||
char *make_dbfname(char *);
|
||||
int db_fetch(char *,unsigned int,char *,char *,int,void *,void *,DBCALLBACK(x));
|
||||
void read_db(dbquery *);
|
||||
void end_db_read(dbquery *);
|
||||
void db_sync(char *);
|
||||
void db_sync_ready(dbsync *);
|
||||
void end_db_sync(dbsync *);
|
||||
void db_test(char *, char *,char *);
|
||||
void gather_sync_channels(void);
|
||||
void sync_next_channel(void);
|
||||
void do_cold_sync(void);
|
||||
void do_cold_sync_slice(void);
|
||||
#ifdef HISTORY
|
||||
void History(char *);
|
||||
#endif
|
||||
|
||||
|
||||
int ul_hash(char *);
|
||||
int sl_hash(char *);
|
||||
int lu_hash(char *);
|
||||
int cl_hash(char *);
|
||||
int su_hash(char *);
|
||||
|
||||
|
||||
#ifdef NICKSERV
|
||||
void IntroduceNickserv(void);
|
||||
void KillNickserv(char *msg);
|
||||
void nserv_nickserv(char *source, char *args);
|
||||
void nserv_addnick(char *source, char *args);
|
||||
void nserv_addmask(char *source, char *args);
|
||||
void nserv_remnick(char *source, char *args);
|
||||
void nserv_remmask(char *source, char *args);
|
||||
void nserv_nickinfo(char *source, char *args);
|
||||
void nserv_identify(char *source, char *args);
|
||||
void nserv_ghost(char *source, char *args);
|
||||
void nserv_nicknewpass(char *source, char *args);
|
||||
void nserv_nicknewemail(char *source, char *args);
|
||||
void nserv_save(void);
|
||||
void nserv_load(void);
|
||||
void nserv_checkregnick(char *nick);
|
||||
void nserv_quit(aluser *user);
|
||||
void nserv_nick(char *newnick, aluser *user);
|
||||
void nserv_onop(char *channel, auser *user);
|
||||
#endif
|
||||
void DccMe(char *, char *);
|
||||
614
Sources/replies.c
Normal file
614
Sources/replies.c
Normal file
@@ -0,0 +1,614 @@
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
|
||||
/* Very appreciated contribution from: (just add your name here)
|
||||
Stephan Mantler aka Step <smantler@atpibm6000.tuwien.ac.at>
|
||||
Carlo Kid aka Run <carlo@tnrunaway.tn.tudelft.nl>
|
||||
nirvana <nirvana@nil.fut.es>
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
|
||||
alang Lang[NO_LANG] =
|
||||
{
|
||||
{L_ENGLISH, "en", "english"},
|
||||
{L_DUTCH, "nl", "dutch"},
|
||||
{L_FRENCH, "fr", "fran<EFBFBD>ais"},
|
||||
{L_SPANISH, "es", "espa<EFBFBD>ol"},
|
||||
{L_GERMAN, "de", "deutsch"}
|
||||
};
|
||||
|
||||
/* the %s will be expanded to the channel name
|
||||
notaccessreply is only english for now */
|
||||
char *notaccessreply[] =
|
||||
{
|
||||
"%s: Nice try. But I'm not a fool!",
|
||||
"%s: Cheating is very bad you know!",
|
||||
"%s: Do I know you?",
|
||||
"You should come on %s more often",
|
||||
"Ha! Ha! I don't think people on %s would like that!",
|
||||
"%s: Pfft! Nice try!",
|
||||
"%s: No, I don't think so.. you're not my type :P",
|
||||
"go read the %s manual.. then I might consider it",
|
||||
"I would.. but.. one teensy problem. You're not in %s's database",
|
||||
"Oh.. are you trying to communicate with me?",
|
||||
"You see, %s is some kinda private thing...",
|
||||
NULL
|
||||
};
|
||||
|
||||
void ReplyNotAccess(char *nick, char *channel)
|
||||
{
|
||||
static int index = 0;
|
||||
register int i;
|
||||
char buffer[200];
|
||||
|
||||
for (i = rand() % 5 + 1; i > 0; i--)
|
||||
if (notaccessreply[++index] == NULL)
|
||||
index = 0;
|
||||
|
||||
sprintf(buffer, notaccessreply[index], channel);
|
||||
notice(nick, buffer);
|
||||
}
|
||||
|
||||
void RandomChannel(char *source)
|
||||
{
|
||||
register int hash, offset;
|
||||
register achannel *chan;
|
||||
char buffer[200];
|
||||
|
||||
hash = rand() % 1000;
|
||||
offset = rand() % 100;
|
||||
|
||||
chan = ChannelList[hash];
|
||||
while (chan == NULL)
|
||||
{
|
||||
chan = ChannelList[(++hash) % 1000];
|
||||
if (hash > 2000)
|
||||
return;
|
||||
}
|
||||
while (offset > 0 && !chan->on)
|
||||
{
|
||||
chan = chan->next;
|
||||
if (chan == NULL)
|
||||
{
|
||||
while (chan == NULL)
|
||||
{
|
||||
chan = ChannelList[(++hash) % 1000];
|
||||
if (hash > 2000)
|
||||
return;
|
||||
}
|
||||
}
|
||||
offset--;
|
||||
}
|
||||
sprintf(buffer, "%s is cool!", chan->name);
|
||||
notice(source, buffer);
|
||||
}
|
||||
|
||||
void Say(char *source, char *args)
|
||||
{
|
||||
char buffer[1024], target[80], global[] = "*";
|
||||
|
||||
if (Access(global, source) < 900)
|
||||
{
|
||||
return; /*silently */
|
||||
}
|
||||
|
||||
GetWord(0, args, target);
|
||||
args = ToWord(1, args);
|
||||
|
||||
if (!*target || !*args)
|
||||
{
|
||||
notice(source, "Syntax: say [#channel] [whatever]");
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(buffer, ":%s PRIVMSG %s :%s\n", mynick, target, args);
|
||||
sendtoserv(buffer);
|
||||
}
|
||||
|
||||
|
||||
void ServNotice(char *source, char *args)
|
||||
{
|
||||
char buffer[1024], target[80], global[] = "*";
|
||||
|
||||
if (Access(global, source) < 600)
|
||||
{
|
||||
return; /*silently */
|
||||
}
|
||||
|
||||
GetWord(0, args, target);
|
||||
args = ToWord(1, args);
|
||||
|
||||
if (!*target || !*args)
|
||||
{
|
||||
notice(source, "SYNTAX: servnotice [#channel] [whatever]");
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(buffer, "[Channel Service: %s] %s", source, args);
|
||||
servnotice(target, buffer);
|
||||
}
|
||||
|
||||
|
||||
char *replies[][NO_LANG] =
|
||||
{
|
||||
/* RPL_NOTONCHANNEL */
|
||||
{"I am not on that channel!", /* english */
|
||||
"Ik zit niet op dat kanaal!", /* dutch */
|
||||
"Je ne suis pas sur ce canal!", /* french */
|
||||
"No estoy en ese canal!", /* spanish */
|
||||
"Ich bin nicht auf diesem Kanal!" /* german */
|
||||
},
|
||||
|
||||
/* RPL_NOTCHANOP */
|
||||
{"I am not channel operator", /* english */
|
||||
"Ik ben geen channel operator", /* dutch */
|
||||
"Je ne suis pas op<6F>rateur de canal", /* french */
|
||||
"No soy operador del canal", /* spanish */
|
||||
"Ich bin kein Betreiber auf diesem Kanal" /* german */
|
||||
},
|
||||
|
||||
/* RPL_OPONLY */
|
||||
{"This channel is in OpOnly Mode", /* english */
|
||||
"Dit kanaal is in OpOnly Mode", /* dutch */
|
||||
"Ce canal est en mode OpOnly", /* french */
|
||||
"Ese canal est<73> en modo OpOnly", /* spanish */
|
||||
"Dieser Kanal is im OpOnly-Modus" /* german */
|
||||
},
|
||||
|
||||
/* RPL_OPSELFONLY */
|
||||
{"You can only op yourself in OpOnly mode", /* english */
|
||||
"In OpOnly mode mag je alleen jezelf operator maken", /* dutch */
|
||||
"Vous ne pouvez opper que vous-m<>me en mode OpOnly", /* french */
|
||||
"Solo puedes ser operador en modo OpOnly", /* spanish */
|
||||
"Sie koennen nur sich selbst zum Betreiber machen (Kanal im OpOnly-Modus)" /* german */
|
||||
},
|
||||
|
||||
/* RPL_NOSUCHNICK */
|
||||
{"No such nickname", /* english */
|
||||
"Deze NICK is niet in gebruik", /* dutch */
|
||||
"Ce nick n'existe pas", /* french */
|
||||
"Ese nick no existe", /* spanish */
|
||||
"Diesen Nickname gibt es nicht" /* german */
|
||||
},
|
||||
|
||||
/* RPL_ALREADYONCHANNEL */
|
||||
{"This user is already on channel", /* english */
|
||||
"Deze persoon is al op dat kanaal", /* dutch */
|
||||
"Cet usager est d<>j<EFBFBD> sur le canal", /* french */
|
||||
"Ese usuario ya est<73> en el canal", /* spanish */
|
||||
"Dieser Benutzer ist bereits auf dem Kanal" /* german */
|
||||
},
|
||||
|
||||
/* RPL_IINVITED */
|
||||
{"I invited %s to %s", /* english */
|
||||
"%s is uitgenodigd naar %s te komen", /* dutch */
|
||||
"J'ai invit<69> %s sur %s", /* french */
|
||||
"Yo he invitado a %s en %s", /* spanish */
|
||||
"Ich haben %s eingeladen, auf %s zu kommen" /* german */
|
||||
},
|
||||
|
||||
/* RPL_YOUAREINVITED */
|
||||
{"%s invites you to %s", /* english */
|
||||
"%s vraagt of naar %s komt", /* dutch */
|
||||
"%s vous invite sur %s", /* french */
|
||||
"%s te invita en %s", /* spanish */
|
||||
"%s laedt Sie ein, auf %s zu kommen" /* german */
|
||||
},
|
||||
|
||||
/* RPL_ALWAYSOPWASACTIVE */
|
||||
{"AlwaysOp was active! It's now deactivated", /* english */
|
||||
"AlwaysOp was actief! Het is nu uitgeschakeld", /* dutch */
|
||||
"AlwaysOp <20>tait actif! Il est maintenant d<>sactiv<69>", /* french */
|
||||
"AlwaysOp estaba activado! Ahora ya esta desactivado", /* spanish */
|
||||
"AlwaysOp war aktiv! Es wurde ausgeschalten" /* german */
|
||||
},
|
||||
|
||||
/* RPL_ALWAYSOP */
|
||||
{"This channel is in AlwaysOp mode!", /* english */
|
||||
"Dit kanaal is in AlwaysOp mode!", /* dutch */
|
||||
"Ce canal est en mode AlwaysOp!", /* french */
|
||||
"Este canal est<73> en modo AlwaysOp!", /* spanish */
|
||||
"Dieser Kanal is im AlwaysOp-Modus!" /* german */
|
||||
},
|
||||
|
||||
/* RPL_KICK1ST */
|
||||
{"You are not allowed to KICK me!", /* english */
|
||||
"Het is niet toegestaan mij te KICKen!", /* dutch */
|
||||
"Vous n'avez pas le droit de me kicker!", /* french */
|
||||
"No estas autorizado para kickearme!", /* spanish */
|
||||
"Sie duerfen mich nicht kicken!" /* german */
|
||||
},
|
||||
|
||||
/* RPL_KICK2ND */
|
||||
{"Please STOP kicking me!", /* english */
|
||||
"STOP mij te KICKen!", /* dutch */
|
||||
"Veuillez arr<72>ter de me kicker!", /* french */
|
||||
"Por favor <20>para de kickearme!", /* spanish */
|
||||
"Bitte hoeren Sie auf, mich zu kicken!" /* german */
|
||||
},
|
||||
|
||||
/* RPL_CHANNOTEXIST */
|
||||
{"That channel does not exist!", /* english */
|
||||
"Dat kanaal bestaat niet!", /* dutch */
|
||||
"Ce canal n'existe pas!", /* french */
|
||||
"Ese canal no existe!", /* spanish */
|
||||
"Diesen Kanal gibt es nicht!" /* german */
|
||||
},
|
||||
|
||||
/* RPL_BADFLOODLIMIT */
|
||||
{"value of FLOODPRO must be in the range [3-20] or 0 to turn it off",
|
||||
"FLOODPRO moet een waarde hebben tussen 3 en 20 of 0 om het uit te schakelen",
|
||||
"la valeur de FLOODPRO doit <20>tre entre 3 et 20 ou 0 pour le d<>sactiver",
|
||||
"El valor de FLOODPRO tiene que estar entre 3 y 20 <20> 0 para desactivarlo",
|
||||
"der Wert fon FLOODPRO muss im Bereich von 3 und 20 sein (oder 0 um es abzuschalten)"
|
||||
},
|
||||
|
||||
/* RPL_SETFLOODLIMIT */
|
||||
{"value of FLOODPRO is now %d", /* english */
|
||||
"De waarde van FLOODPRO is nu %d", /* dutch */
|
||||
"la valeur de FLOODPRO est maintenant %d", /* french */
|
||||
"El valor de FLOOPRO est<73> ahora %d", /* spanish */
|
||||
"FLOODPRO hat jetzt den Wert %d" /* german */
|
||||
},
|
||||
|
||||
/* RPL_BADNICKFLOODLIMIT */
|
||||
{"value of NICKFLOODPRO must be in the range [3-10] or 0 to turn it off",
|
||||
"NICKFLOODPRO moet een waarde hebben tussen 3 en 10 of 0 om het uit te schakelen",
|
||||
"la valeur de NICKFLOODPRO doit <20>tre entre 3 et 10 ou 0 pour le d<>sactiver",
|
||||
"El valor de NICKFLOOPRO tiene que estar entre 3 y 10 <20> 0 para desactivarlo",
|
||||
"Werte fuer NICKFLOODPRO muessen im Bereich von 3 bis 10 sein. Oder 0 um es abzuschalten"
|
||||
},
|
||||
|
||||
/* RPL_SETNICKFLOODLIMIT */
|
||||
{"value of NICKFLOODPRO is now %d", /* english */
|
||||
"De waarde van NICKFLOODPRO is nu %d", /* dutch */
|
||||
"la valeur de NICKFLOODPRO est maintenant %d", /* french */
|
||||
"El valor de NICKFLOOPRO est<73> ahora en %d", /* spanish */
|
||||
"der Wert fuer NICKFLOODPRO ist jetzt %d" /* german */
|
||||
},
|
||||
|
||||
/* RPL_BADMASSDEOPLIMIT */
|
||||
{"value of MASSDEOPPRO must be in the range [3-10] or 0 to turn it off",
|
||||
"MASSDEOPPRO moet een waarde hebben tussen 3 en 10 of 0 om het uit te schakelen",
|
||||
"la valeur de MASSDEOPPRO doit <20>tre entre 3 et 10 ou 0 pour le d<>sactiver",
|
||||
"El valor de MASSDEOPPRO tiene que estar entre 3 y 10 <20> 0 para desactivarlo",
|
||||
"der Wert von MASSDEOPPRO muss zwischen 3 und 10 liegen, oder 0 um es abzuschalten"
|
||||
},
|
||||
|
||||
/* RPL_SETMASSDEOPLIMIT */
|
||||
{"value of MASSDEOPPRO is now %d", /* english */
|
||||
"De waarde van MASSDEOPPRO is nu %d", /* dutch */
|
||||
"la valeur de MASSDEOPPRO est maintenant %d", /* french */
|
||||
"El valor de MASSDEOPPRO est<73> ahora en %d", /* spanish */
|
||||
"MASSDEOPPRO ist jetzt %d" /* german */
|
||||
},
|
||||
|
||||
/* RPL_NOOPON */
|
||||
{"value of NOOP is now ON", /* english */
|
||||
"NOOP mode is nu ingeschakeld", /* dutch */
|
||||
"la valeur de NOOP est maintenant ON", /* french */
|
||||
"El valor de NOOP est<73> ahora en ON", /* spanish */
|
||||
"NOOP hat jetzt den Wert EIN" /* german */
|
||||
},
|
||||
|
||||
/* RPL_NOOPOFF */
|
||||
{"value of NOOP is now OFF", /* english */
|
||||
"NOOP mode is nu uit", /* dutch */
|
||||
"la valeur de NOOP est maintenant OFF", /* french */
|
||||
"El valor de NOOP est<73> ahora en OFF", /* spanish */
|
||||
"NOOP hat jetzt den Wert AUS" /* german */
|
||||
},
|
||||
|
||||
/* RPL_BADNOOP */
|
||||
{"value of NOOP must be ON or OFF", /* english */
|
||||
"Kies 'ON' of 'OFF' voor de waarde van NOOP", /* dutch */
|
||||
"la valeur de NOOP doit <20>tre ON ou OFF", /* french */
|
||||
"El valor de NOOP debe ser ON o OFF", /* spanish */
|
||||
"NOOP kann nur EIN oder AUS sein" /* german */
|
||||
},
|
||||
|
||||
/* RPL_ALWAYSOPON */
|
||||
{"value of ALWAYSOP is now ON", /* english */
|
||||
"ALWAYSOP mode is nu ingeschakeld", /* dutch */
|
||||
"la valeur de ALWAYSOP est maintenant ON", /* french */
|
||||
"El valor de ALWAYSOP es ahora ON", /* spanish */
|
||||
"ALWAYSOP ist jetzt EIN" /* german */
|
||||
},
|
||||
|
||||
/* RPL_ALWAYSOPOFF */
|
||||
{"value of ALWAYSOP is now OFF", /* english */
|
||||
"ALWAYSOP mode is nu uit", /* dutch */
|
||||
"la valeur de ALWAYSOP est maintenant OFF", /* french */
|
||||
"El valor de ALWAYSOP es ahora OFF", /* spanish */
|
||||
"ALWAYSOP ist jetzt AUS" /* german */
|
||||
},
|
||||
|
||||
/* RPL_BADALWAYSOP */
|
||||
{"value of ALWAYSOP must be ON or OFF", /* english */
|
||||
"Kies 'ON' of 'OFF' voor de waarde van ALWAYSOP", /* dutch */
|
||||
"la valeur de ALWAYSOP doit <20>tre ON ou OFF", /* french */
|
||||
"El valor de ALWAYSOP debe ser ON o OFF", /* spanish */
|
||||
"Werte fuer ALWAYSOP sind EIN oder AUS" /* german */
|
||||
},
|
||||
|
||||
/* RPL_OPONLYON */
|
||||
{"value of OPONLY is now ON", /* english */
|
||||
"OPONLY mode is nu ingeschakeld", /* dutch */
|
||||
"la valeur de OPONLY est maintenant ON", /* french */
|
||||
"El valor de OPONLY es ahora ON", /* spanish */
|
||||
"der Wert fuer OPONLY ist jetzt EIN" /* german */
|
||||
},
|
||||
|
||||
/* RPL_OPONLYOFF */
|
||||
{"value of OPONLY is now OFF", /* english */
|
||||
"OPONLY mode is nu uit", /* dutch */
|
||||
"la valeur de OPONLY est maintenant OFF", /* french */
|
||||
"El valor de OPONLY es ahora OFF", /* spanish */
|
||||
"der Wert fuer OPONLY ist jetzt AUS" /* german */
|
||||
},
|
||||
|
||||
/* RPL_BADOPONLY */
|
||||
{"value of OPONLY must be ON or OFF", /* english */
|
||||
"Kies 'ON' of 'OFF' voor de waarde van OPONLY", /* dutch */
|
||||
"la valeur de OPONLY doit <20>tre ON ou OFF", /* french */
|
||||
"El valor de OPONLY debe ser ON o OFF", /* spanish */
|
||||
"Werte fuer OPONLY sind EIN oder AUS" /* german */
|
||||
},
|
||||
|
||||
/* RPL_AUTOTOPICON */
|
||||
{"value of AUTOTOPIC is now ON", /* english */
|
||||
"AUTOTOPIC mode is nu ingeschakeld", /* dutch */
|
||||
"la valeur de AUTOTOPIC est maintenant ON", /* french */
|
||||
"El valor de AUTOTOPIC es ahora ON", /* spanish */
|
||||
"der Wert fuer AUTOTOPIC ist jetzt EIN" /* german */
|
||||
},
|
||||
|
||||
/* RPL_AUTOTOPICOFF */
|
||||
{"value of AUTOTOPIC is now OFF", /* english */
|
||||
"AUTOTOPIC mode is nu uit", /* dutch */
|
||||
"la valeur de AUTOTOPIC est maintenant OFF", /* french */
|
||||
"El valor de AUTOTOPIC es ahora OFF", /* spanish */
|
||||
"der Wert fuer AUTOTOPIC ist jetzt AUS" /* german */
|
||||
},
|
||||
|
||||
/* RPL_BADAUTOTOPIC */
|
||||
{"value of AUTOTOPIC must be ON or OFF", /* english */
|
||||
"Kies 'ON' of 'OFF' voor de waarde van AUTOTOPIC", /* dutch */
|
||||
"la valeur de AUTOTOPIC doit <20>tre ON ou OFF", /* french */
|
||||
"El valor de AUTOTOPIC debe ser ON o OFF", /* spanish */
|
||||
"Werte fuer AUTOTOPIC sind EIN oder AUS" /* german */
|
||||
},
|
||||
|
||||
/* RPL_STRICTOPON */
|
||||
{"value of STRICTOP is now ON", /* english */
|
||||
"value of STRICTOP is now ON", /* dutch */
|
||||
"value of STRICTOP is now ON", /* french */
|
||||
"El valor de STRICTOP es ahora ON", /* spanish */
|
||||
"value of STRICTOP is now ON" /* german */
|
||||
},
|
||||
|
||||
/* RPL_STRICTOPOFF */
|
||||
{"value of STRICTOP is now OFF", /* english */
|
||||
"value of STRICTOP is now OFF", /* dutch */
|
||||
"value of STRICTOP is now OFF", /* french */
|
||||
"El valor de STRICTOP es ahora OFF", /* spanish */
|
||||
"value of STRICTOP is now OFF" /* german */
|
||||
},
|
||||
|
||||
/* RPL_BADSTRICTOP */
|
||||
{"value of STRICTOP must be ON or OFF", /* english */
|
||||
"value of STRICTOP must be ON or OFF", /* dutch */
|
||||
"value of STRICTOP must be ON or OFF", /* french */
|
||||
"El valor de STRICTOP debe ser ON o OFF", /* spanish */
|
||||
"value of STRICTOP must be ON or OFF" /* german */
|
||||
},
|
||||
|
||||
/* RPL_BADUSERFLAGS */
|
||||
{"New value can be 1-AUTOOP or 0-NO AUTOOP",
|
||||
"De nieuwe waarde kan zijn 1-AUTOOP, 2-PROTECT ou 3-BOTH",
|
||||
"La nouvelle valeur peut <20>tre 1-AUTOOP ou 0-PAS DE AUTOOP",
|
||||
"El nuevo valor puede ser 1-AUTOOP o 0- NOAUTOOP", /* spanish */
|
||||
"Der neue Wert kann 1-AUTOOP, 2-PROTECT oder 3-BEIDE sein."
|
||||
},
|
||||
|
||||
/* RPL_SETUSERFLAGS */
|
||||
{"value of USERFLAGS is now %d", /* english */
|
||||
"de waarde van USERFLAGS is nu %d", /* dutch */
|
||||
"la nouvelles valeur de USERFLAGS est %d", /* french */
|
||||
"El nuevo valor de USERFLAGS es ahora %d", /* spanish */
|
||||
"USERFLAGS ist jetzt %d" /* german */
|
||||
},
|
||||
|
||||
/* RPL_KNOWNLANG */
|
||||
{"Known languages are", /* english */
|
||||
"De volgende talen zijn bekend", /* dutch */
|
||||
"Je connais les langues", /* french */
|
||||
"Yo hablo y escribo los siguientes idiomas", /* spanish */
|
||||
"Folgende Sprachen sind bekannt" /* german */
|
||||
},
|
||||
|
||||
/* RPL_SETLANG */
|
||||
{"Default language is now %s (%s)", /* english */
|
||||
"De default taal is nu %s (%s)", /* dutch */
|
||||
"La langue par d<>faut est maintenant %s (%s)", /* french */
|
||||
"El idioma configurado por defecto es ahora %s (%s)", /* spanish */
|
||||
"Die neue Default-Sprache ist %s (%s)" /* german */
|
||||
},
|
||||
|
||||
/* RPL_STATUS1 */
|
||||
{"Channel %s has %d user%s (%d operator%s)", /* english */
|
||||
"Kanaal %s heeft %d deelnemer%s (%d operator%s)", /* dutch */
|
||||
"Canal %s a %d usager%s (%d op<6F>rateur%s)", /* french */
|
||||
"El canal %s tiene %d usuarios%s (%d operadores%s)", /* spanish */
|
||||
"Kanal %s hat %d Benutzer (%d Betreiber)" /* german */
|
||||
/* ### NOTE the german version does not use plurals!
|
||||
The code reflects this. */
|
||||
},
|
||||
|
||||
/* RPL_STATUS2 */
|
||||
{"Mode is +%s", /* english */
|
||||
"Mode is +%s", /* dutch */
|
||||
"Le mode est +%s", /* french */
|
||||
"El modo es +%s", /* spanish */
|
||||
"Der Modus ist +%s" /* german */
|
||||
},
|
||||
|
||||
/* RPL_STATUS3 */
|
||||
{"Default user flags%s", /* english */
|
||||
"Default 'user flags'%s", /* dutch */
|
||||
"Flags d'usager par d<>faut%s", /* french */
|
||||
"Flags por defectos son %s", /* spanish */
|
||||
"Default-Flags fuer Benutzer %s" /* german */
|
||||
},
|
||||
|
||||
/* RPL_STATUS4 */
|
||||
{"Default language is %s", /* english */
|
||||
"Default taal is %s", /* dutch */
|
||||
"Langue par d<>faut %s", /* french */
|
||||
"Idioma por defecto %s", /* spanish */
|
||||
"Default-Sprache ist %s" /* german */
|
||||
},
|
||||
|
||||
/* RPL_STATUS5 */
|
||||
{"Channel has been idle for %d second%s", /* english */
|
||||
"Het kanaal is %d second%s idle", /* dutch */
|
||||
"Le canal est inactif depuis %d seconde%s", /* french */
|
||||
"El canal no est<73> activo desde hace %d segundos%s", /* spanish */
|
||||
"Der Kanal ist seit %d Sekunden inaktiv." /* german */
|
||||
},
|
||||
|
||||
/* RPL_SETCHANDEFS */
|
||||
{"Channel defaults set.", /* english */
|
||||
"Kanaal defaults geregistreerd.", /* dutch */
|
||||
"L'<27>tat du canal est enregistr<74>", /* french */
|
||||
"Los nuevos cambios han sido registrados", /* spanish */
|
||||
"Default-Werte fuer den Kanal wurden gesetzt" /* german */
|
||||
},
|
||||
|
||||
/* RPL_NOTDEF */
|
||||
{"That channel is not in my default channel list", /* english */
|
||||
"Dat kanaal staat niet in mijn default kanaal lijst", /* dutch */
|
||||
"Ce canal n'est pas sur ma liste", /* french */
|
||||
"Ese canal no est<73> en mi lista por defecto", /* spanish */
|
||||
"Dieser Kanal ist nicht auf meiner Liste" /* german */
|
||||
},
|
||||
|
||||
/* RPL_REMDEF */
|
||||
{"Channel removed from default channel list", /* english */
|
||||
"Het kanaal is van de default kanaal lijst verwijderd", /* dutch */
|
||||
"Ce canal n'est plus sur ma liste", /* french */
|
||||
"Canal eliminado de la lista por defecto", /* spanish */
|
||||
"Der Kanal wurde aus meiner Liste entfernt" /* german */
|
||||
},
|
||||
|
||||
/* RPL_NOMATCH */
|
||||
{"No match.", /* english */
|
||||
"Niet gevonden.", /* dutch */
|
||||
"Introuvable", /* french */
|
||||
"No se encuentra", /* spanish */
|
||||
"Nicht gefunden." /* german */
|
||||
},
|
||||
|
||||
/* RPL_NOOP */
|
||||
{"Sorry. This channel is in NoOp mode!", /* english */
|
||||
"Sorry. Dit kanaal is in NoOp mode!", /* dutch */
|
||||
"D<EFBFBD>sol<EFBFBD>. Ce canal est en mode NoOp!", /* french */
|
||||
"Lo siento, <20>Ese canal est<73> en modo NoOp!", /* spanish */
|
||||
"Tut mir leid, aber dieser Kanal ist im NoOp-Modus!" /* german */
|
||||
},
|
||||
|
||||
/* RPL_CANTBEOP */
|
||||
{"Sorry. You are not allowed to be chanop", /* english */
|
||||
"Sorry. Het is niet toegestaan dat u kanaal operator bent", /* dutch */
|
||||
"D<EFBFBD>sol<EFBFBD>. Il ne vous est pas permis d'<27>tre op<6F>rateur", /* french */
|
||||
"Lo siento. No estas autorizado para ser operador en el canal", /* spanish */
|
||||
"Tut mir leid, aber Sie duerfen nicht Betreiber werden." /*german */
|
||||
},
|
||||
|
||||
/* RPL_CANTBEOPPED */
|
||||
{"This user is not allowed to be chanop", /* english */
|
||||
"Deze gebruiker is het niet toegestaan kanaal operator te zijn", /* dutch */
|
||||
"Cet usager n'a pas le droit d'<27>tre op<6F>rateur", /* french */
|
||||
"Ese usuario no est<73> autorizado para ser operador en el canal", /* spanish */
|
||||
"Dieser Benutzer darf nicht Betreiber werden." /* german */
|
||||
},
|
||||
|
||||
/* RPL_DEOPPED1ST */
|
||||
{"You are not allowed to DEOP me!", /* english */
|
||||
"Je mag me niet deoppen!", /* dutch */
|
||||
"Vous ne pouvez pas me deopper!", /* french */
|
||||
"<EFBFBD>No me puedes quitar el op!", /* spanish */
|
||||
"Sie duerfen mich nicht deoppen!" /* german */
|
||||
},
|
||||
|
||||
/* RPL_DEOPPED2ND */
|
||||
{"Please STOP deopping me!", /* english */
|
||||
"STOP met me te de-oppen!", /* dutch */
|
||||
"Veuillez arr<72>ter de me deopper!", /* french */
|
||||
"Por favor, <20>para de quitarme el op!", /* spanish */
|
||||
"Bitte hoeren Sie auf, mich zu deoppen!" /* german */
|
||||
},
|
||||
|
||||
/* RPL_DEOPPED3RD */
|
||||
{"I warned you!", /* english */
|
||||
"Je was gewaarschuwd!", /* dutch */
|
||||
"Je vous aurai pr<70>venu!", /* french */
|
||||
"<EFBFBD>Te he hecho una advertencia!", /* spanish */
|
||||
"Sie wurden gewarnt!" /* german */
|
||||
},
|
||||
|
||||
/* RPL_USERISPROTECTED */
|
||||
{"This user is protected", /* english */
|
||||
"Deze gebruiker is beschermd", /* dutch */
|
||||
"Cet usager est prot<6F>g<EFBFBD>", /* french */
|
||||
"Este usuario est<73> protegido", /* spanish */
|
||||
"Dieser Benutzer ist geschuetzt" /* german */
|
||||
},
|
||||
|
||||
/* RPL_YOUREOPPEDBY */
|
||||
{"You're opped by %s", /* english */
|
||||
"U bent kanaal operator gemaakt door %s", /* dutch */
|
||||
"Vous <20>tes opp<70> par %s", /* french */
|
||||
"El %s te ha puesto de operador en el canal", /*spanish */
|
||||
"Sie wurden von %s zum Betreiber gemacht." /* german */
|
||||
},
|
||||
|
||||
/* RPL_USERNOTONCHANNEL */
|
||||
{"User %s is not on channel %s!", /* english */
|
||||
"%s bevindt zich niet op kanaal %s!", /* dutch */
|
||||
"%s n'est pas sur %s!", /* french */
|
||||
"El usuario %s no est<73> presente en el canal %s!", /* spanish */
|
||||
"%s ist nicht auf dem Kanal %s!" /* german */
|
||||
},
|
||||
|
||||
/* RPL_YOUREDEOPPEDBY */
|
||||
{"You're deopped by %s", /* english */
|
||||
"Het kanaal operatorschap is u ontnomen door %s", /* dutch */
|
||||
"Vous <20>tes d<>opp<70> par %s", /* french */
|
||||
"El %s te quit<69> el status de op%s", /* spanish */
|
||||
"%s hat ihnen den Betreiberstatus entzogen" /* german */
|
||||
}
|
||||
};
|
||||
83
Sources/replies.h
Normal file
83
Sources/replies.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/* @(#)$Id: replies.h,v 1.4 1996/11/13 00:40:47 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#define RPL_NOTONCHANNEL 0
|
||||
#define RPL_NOTCHANOP 1
|
||||
#define RPL_OPONLY 2
|
||||
#define RPL_OPSELFONLY 3
|
||||
#define RPL_NOSUCHNICK 4
|
||||
#define RPL_ALREADYONCHANNEL 5
|
||||
#define RPL_IINVITED 6
|
||||
#define RPL_YOUAREINVITED 7
|
||||
#define RPL_ALWAYSOPWASACTIVE 8
|
||||
#define RPL_ALWAYSOP 9
|
||||
#define RPL_KICK1ST 10
|
||||
#define RPL_KICK2ND 11
|
||||
#define RPL_CHANNOTEXIST 12
|
||||
#define RPL_BADFLOODLIMIT 13
|
||||
#define RPL_SETFLOODLIMIT 14
|
||||
#define RPL_BADNICKFLOODLIMIT 15
|
||||
#define RPL_SETNICKFLOODLIMIT 16
|
||||
#define RPL_BADMASSDEOPLIMIT 17
|
||||
#define RPL_SETMASSDEOPLIMIT 18
|
||||
#define RPL_NOOPON 19
|
||||
#define RPL_NOOPOFF 20
|
||||
#define RPL_BADNOOP 21
|
||||
#define RPL_ALWAYSOPON 22
|
||||
#define RPL_ALWAYSOPOFF 23
|
||||
#define RPL_BADALWAYSOP 24
|
||||
#define RPL_OPONLYON 25
|
||||
#define RPL_OPONLYOFF 26
|
||||
#define RPL_BADOPONLY 27
|
||||
#define RPL_AUTOTOPICON 28
|
||||
#define RPL_AUTOTOPICOFF 29
|
||||
#define RPL_BADAUTOTOPIC 30
|
||||
#define RPL_STRICTOPON 31
|
||||
#define RPL_STRICTOPOFF 32
|
||||
#define RPL_BADSTRICTOP 33
|
||||
#define RPL_BADUSERFLAGS 34
|
||||
#define RPL_SETUSERFLAGS 35
|
||||
#define RPL_KNOWNLANG 36
|
||||
#define RPL_SETLANG 37
|
||||
#define RPL_STATUS1 38
|
||||
#define RPL_STATUS2 39
|
||||
#define RPL_STATUS3 40
|
||||
#define RPL_STATUS4 41
|
||||
#define RPL_STATUS5 42
|
||||
#define RPL_SETCHANDEFS 43
|
||||
#define RPL_NOTDEF 44
|
||||
#define RPL_REMDEF 45
|
||||
#define RPL_NOMATCH 46
|
||||
#define RPL_NOOP 47
|
||||
#define RPL_CANTBEOP 48
|
||||
#define RPL_CANTBEOPPED 49
|
||||
#define RPL_DEOPPED1ST 50
|
||||
#define RPL_DEOPPED2ND 51
|
||||
#define RPL_DEOPPED3RD 52
|
||||
#define RPL_USERISPROTECTED 53
|
||||
#define RPL_YOUREOPPEDBY 54
|
||||
#define RPL_USERNOTONCHANNEL 55
|
||||
#define RPL_YOUREDEOPPEDBY 56
|
||||
265
Sources/servers.c
Normal file
265
Sources/servers.c
Normal file
@@ -0,0 +1,265 @@
|
||||
/* @(#)$Id: servers.c,v 1.9 1998/01/25 18:35:47 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
|
||||
aserver **FindServer(aserver ** head, char *name)
|
||||
{
|
||||
register aserver **tmp;
|
||||
|
||||
if (head == NULL || *head == NULL)
|
||||
return NULL;
|
||||
|
||||
while (*head != NULL)
|
||||
{
|
||||
if (!strcasecmp((*head)->name, name))
|
||||
{
|
||||
return head;
|
||||
}
|
||||
if ((tmp = FindServer(&(*head)->down, name)) != NULL)
|
||||
{
|
||||
return tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
head = &(*head)->next;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
aserver *ToServer(char *name)
|
||||
{
|
||||
return (*FindServer(&ServerList, name));
|
||||
}
|
||||
|
||||
void onserver(char *source, char *newserver, char *args)
|
||||
{
|
||||
register aserver *head;
|
||||
register aserver *tmp;
|
||||
register int i;
|
||||
char TS[80];
|
||||
|
||||
if (source[0] != '\0')
|
||||
{
|
||||
head = ToServer(source);
|
||||
}
|
||||
else
|
||||
{
|
||||
head = NULL;
|
||||
}
|
||||
|
||||
#ifdef BACKUP
|
||||
if (!strcasecmp(newserver, MAIN_SERVERNAME))
|
||||
{
|
||||
quit(MAIN_NICK " is back", 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
tmp = (aserver *) MALLOC(sizeof(aserver));
|
||||
tmp->name = (char *)MALLOC(strlen(newserver) + 1);
|
||||
strcpy(tmp->name, newserver);
|
||||
GetWord(2, args, TS);
|
||||
tmp->TS = atol(TS);
|
||||
if (head == NULL)
|
||||
{
|
||||
tmp->next = ServerList;
|
||||
ServerList = tmp;
|
||||
TSoffset = tmp->TS - now;
|
||||
#ifdef DEBUG
|
||||
printf("New connection: my time: %ld others' time %ld (%ld)\n",
|
||||
now, tmp->TS, TSoffset);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp->next = head->down;
|
||||
head->down = tmp;
|
||||
}
|
||||
tmp->up = head;
|
||||
tmp->down = NULL;
|
||||
for (i = 0; i < 100; i++)
|
||||
tmp->users[i] = NULL;
|
||||
}
|
||||
|
||||
void onsquit(char *source, char *theserver, char *args)
|
||||
{
|
||||
register aserver *serv, **s;
|
||||
register int i;
|
||||
char TS[80];
|
||||
|
||||
#ifdef FAKE_UWORLD
|
||||
if (!strcasecmp(theserver, UFAKE_SERVER) && Uworld_status == 1)
|
||||
{
|
||||
GetWord(0, args, TS);
|
||||
if (atol(TS) == UworldServTS)
|
||||
{
|
||||
char buffer[200];
|
||||
sprintf(buffer, "%s squitted", UFAKE_NICK);
|
||||
log(buffer);
|
||||
Uworld_status = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
s = FindServer(&ServerList, theserver);
|
||||
|
||||
if (s == NULL)
|
||||
{
|
||||
char buffer[200];
|
||||
sprintf(buffer, "ERROR: SQUIT unknown server %s (from %s)",
|
||||
theserver, source);
|
||||
log(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
serv = *s;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("SQUIT: %s %s\n", source, theserver);
|
||||
#endif
|
||||
|
||||
if (args != NULL)
|
||||
{
|
||||
GetWord(0, args, TS);
|
||||
#ifdef DEBUG
|
||||
if (s != NULL)
|
||||
printf("ConnectTS: %ld SquitTS: %ld\n", serv->TS, atol(TS));
|
||||
#endif
|
||||
}
|
||||
|
||||
if (serv != ServerList && args != NULL && serv->TS != atol(TS))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("TS's are different.. ignoring squit!\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
while (serv->down != NULL)
|
||||
{
|
||||
onsquit(NULL, serv->down->name, NULL);
|
||||
}
|
||||
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
while (serv->users[i] != NULL)
|
||||
{
|
||||
onquit(serv->users[i]->N->nick);
|
||||
}
|
||||
}
|
||||
|
||||
TTLALLOCMEM -= strlen(serv->name) + 1;
|
||||
free(serv->name);
|
||||
*s = serv->next;
|
||||
TTLALLOCMEM -= sizeof(aserver);
|
||||
free(serv);
|
||||
}
|
||||
|
||||
void showmap(char *source)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
if (CurrentSendQ > HIGHSENDQTHRESHOLD)
|
||||
{
|
||||
notice(source, "Cannot process your request at this time. Try again later.");
|
||||
return;
|
||||
}
|
||||
notice(source, SERVERNAME);
|
||||
showserv(source, ServerList, &count);
|
||||
CheckFloodFlood(source, count);
|
||||
}
|
||||
|
||||
void showserv(char *source, aserver * server, int *count)
|
||||
{
|
||||
static char prefix[80] = "";
|
||||
static int offset = 0;
|
||||
char buffer[200];
|
||||
register asuser *suser;
|
||||
register int nbusers = 0, i;
|
||||
|
||||
if (server == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
(*count)++; /* number of servers */
|
||||
|
||||
/* count number of users */
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
suser = server->users[i];
|
||||
while (suser != NULL)
|
||||
{
|
||||
nbusers++;
|
||||
suser = suser->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (server->next == NULL)
|
||||
{
|
||||
sprintf(buffer, "%s`-%s (%d client%s)", prefix, server->name, nbusers, (nbusers != 1) ? "s" : "");
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buffer, "%s|-%s (%d client%s)", prefix, server->name, nbusers, (nbusers != 1) ? "s" : "");
|
||||
}
|
||||
notice(source, buffer);
|
||||
|
||||
if (server->next != NULL)
|
||||
strcpy(prefix + offset, "| ");
|
||||
else
|
||||
strcpy(prefix + offset, " ");
|
||||
|
||||
offset += 2;
|
||||
showserv(source, server->down, count);
|
||||
offset -= 2;
|
||||
prefix[offset] = '\0';
|
||||
|
||||
showserv(source, server->next, count);
|
||||
}
|
||||
|
||||
void onsettime(char *source, char *value)
|
||||
{
|
||||
char buffer[200];
|
||||
|
||||
TSoffset = atol(value) - now;
|
||||
sprintf(buffer, "SETTIME from %s (%s) (%ld)", source, value, TSoffset);
|
||||
log(buffer);
|
||||
#ifdef DEBUG
|
||||
puts(buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
void showversion(char *source)
|
||||
{
|
||||
char buffer[200];
|
||||
|
||||
sprintf(buffer, ":%s 351 %s . %s :%s\n", SERVERNAME, source, SERVERNAME, VERSION);
|
||||
sendtoserv(buffer);
|
||||
}
|
||||
791
Sources/shitlist.c
Normal file
791
Sources/shitlist.c
Normal file
@@ -0,0 +1,791 @@
|
||||
/* @(#)$Id: shitlist.c,v 1.12 2000/01/28 01:29:14 lgm Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
|
||||
typedef struct ShitDisk
|
||||
{
|
||||
time_t time;
|
||||
time_t expiration;
|
||||
char match[80];
|
||||
char from[80];
|
||||
char reason[200];
|
||||
char channel[50];
|
||||
int level;
|
||||
}
|
||||
ShitDisk;
|
||||
|
||||
static int active = 0;
|
||||
|
||||
int sl_hash(char *channel)
|
||||
{
|
||||
register int i, j = 0;
|
||||
for (i = 1; i < strlen(channel); i++)
|
||||
j += (unsigned char)toupper(channel[i]);
|
||||
return (j % 1000);
|
||||
}
|
||||
|
||||
void AddToShitList(char *source, char *ch, char *args, int force)
|
||||
{
|
||||
char buffer[1024];
|
||||
char srcuh[200];
|
||||
char channel[80];
|
||||
char pattern[200];
|
||||
char strtime[80];
|
||||
char strlevel[80];
|
||||
char *reason;
|
||||
time_t exp;
|
||||
int shitlevel;
|
||||
int srcAccess;
|
||||
int exact;
|
||||
register char *ptr1, *ptr2;
|
||||
register aluser *luser;
|
||||
register ShitUser *curr;
|
||||
register achannel *chan;
|
||||
|
||||
if (*args == '#')
|
||||
{
|
||||
GetWord(0, args, channel);
|
||||
args = ToWord(1, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(channel, ch);
|
||||
GuessChannel(source, channel);
|
||||
}
|
||||
|
||||
if (*source && force == 0)
|
||||
{
|
||||
chan = ToChannel(channel);
|
||||
if (chan != NULL && (chan->flags & CFL_OPONLY))
|
||||
{
|
||||
notice(source, replies[RPL_OPONLY][chan->lang]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcmp(channel, "*"))
|
||||
{
|
||||
notice(source, "SYNTAX: ban <#channel> <nick|address> "
|
||||
"<duration in hours> <level> <reason>");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!*source || force > 0)
|
||||
srcAccess = (MASTER_ACCESS + 1);
|
||||
else
|
||||
srcAccess = Access(channel, source);
|
||||
|
||||
if (srcAccess < ADD_TO_SHITLIST_LEVEL)
|
||||
{
|
||||
ReplyNotAccess(source, channel);
|
||||
return;
|
||||
}
|
||||
|
||||
GetWord(0, args, pattern);
|
||||
GetWord(1, args, strtime);
|
||||
GetWord(2, args, strlevel);
|
||||
reason = ToWord(3, args);
|
||||
|
||||
if (strlen(reason) > 200)
|
||||
reason[199] = '\0';
|
||||
|
||||
if (!*pattern || (*strtime != '\0' && !isdigit(*strtime)))
|
||||
{
|
||||
notice(source, "SYNTAX: ban [#channel] <nick|address> "
|
||||
"[duration in hours] [level] [reason]");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!*strtime)
|
||||
{
|
||||
exp = SHITLIST_DEFAULT_TIME;
|
||||
}
|
||||
else
|
||||
{
|
||||
exp = atoi(strtime);
|
||||
}
|
||||
|
||||
if (!*strlevel)
|
||||
{
|
||||
shitlevel = AUTO_KICK_SHIT_LEVEL;
|
||||
}
|
||||
else
|
||||
{
|
||||
shitlevel = atoi(strlevel);
|
||||
}
|
||||
|
||||
exp *= 3600;
|
||||
if (exp < 0 || exp > (MAX_BAN_DURATION * 24 * 3600))
|
||||
{
|
||||
sprintf(buffer, "Invalid duration (Max %d days)", MAX_BAN_DURATION);
|
||||
notice(source, buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (shitlevel < 1 || shitlevel > 1000)
|
||||
{
|
||||
notice(source, "Ban level must be in the range 1-1000");
|
||||
return;
|
||||
}
|
||||
|
||||
if (srcAccess < shitlevel)
|
||||
{
|
||||
notice(source, "Can't ban to a higher level than your access level.");
|
||||
return;
|
||||
}
|
||||
|
||||
exp += now;
|
||||
|
||||
if ((luser = ToLuser(source)) != NULL)
|
||||
{
|
||||
sprintf(srcuh, "%s!%s@%s", luser->nick, luser->username, luser->site);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(srcuh, source);
|
||||
}
|
||||
|
||||
/* look if the user is on the channel, if so, take his address */
|
||||
|
||||
luser = ToLuser(pattern);
|
||||
if (luser != NULL)
|
||||
{
|
||||
MakeBanMask(luser, pattern);
|
||||
exact = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ptr2 = strchr(pattern, '@')) == NULL)
|
||||
{
|
||||
strcat(pattern, "@*");
|
||||
ptr2 = strchr(pattern, '@');
|
||||
}
|
||||
if ((ptr1 = strchr(pattern, '!')) == NULL)
|
||||
{
|
||||
char tmp[200];
|
||||
sprintf(tmp, "*!%s", pattern);
|
||||
strncpy(pattern, tmp, 200);
|
||||
pattern[199] = '\0';
|
||||
ptr1 = pattern + 1;
|
||||
}
|
||||
if (ptr1 > ptr2)
|
||||
{
|
||||
notice(source, "Illegal ban mask");
|
||||
return;
|
||||
}
|
||||
exact = 1;
|
||||
}
|
||||
|
||||
/* count number of bans.. if it's > MAX_BAN.. refuse to add */
|
||||
if (!force && *source && shitlevel > 0)
|
||||
{
|
||||
register int count = 0;
|
||||
curr = ShitList[sl_hash(channel)];
|
||||
while (curr)
|
||||
{
|
||||
if (!strcasecmp(curr->channel, channel))
|
||||
count++;
|
||||
curr = curr->next;
|
||||
}
|
||||
if (count > MAX_BAN)
|
||||
{
|
||||
notice(source, "Sorry, there are too many bans on"
|
||||
" your channel. You'll have to remove some first.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now, seek thru the ShitList if the pattern is already there.
|
||||
if it is, only change the information already present */
|
||||
curr = ShitList[sl_hash(channel)];
|
||||
if (exact)
|
||||
{
|
||||
while (curr && (strcasecmp(curr->match, pattern) || strcasecmp(curr->channel, channel)))
|
||||
{
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (curr && (!match(pattern, curr->match) || strcasecmp(curr->channel, channel)))
|
||||
{
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (curr)
|
||||
{
|
||||
/* if the user is already on the shitlist.. */
|
||||
|
||||
/* if this is the result of a flood protection.. we have to
|
||||
make sure the user is not already shitlisted for a longer
|
||||
time.. */
|
||||
|
||||
if (shitlevel == 0 || curr->expiration < exp)
|
||||
curr->expiration = exp;
|
||||
|
||||
curr->time = now;
|
||||
|
||||
/* if this is the result of a flood protection.. we have to
|
||||
make sure the user is not already shitlisted at a higher
|
||||
level.. */
|
||||
|
||||
if (shitlevel == 0 || curr->level < shitlevel)
|
||||
curr->level = shitlevel;
|
||||
|
||||
TTLALLOCMEM -= strlen(curr->from) + 1;
|
||||
free(curr->from);
|
||||
curr->from = (char *)MALLOC(strlen(srcuh) + 1);
|
||||
strcpy(curr->from, srcuh);
|
||||
|
||||
TTLALLOCMEM -= strlen(curr->reason) + 1;
|
||||
free(curr->reason);
|
||||
curr->reason = (char *)MALLOC(strlen(reason) + 1);
|
||||
strcpy(curr->reason, reason);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("TIME: %ld EXP: %ld LEVEL %d\n", now, exp, shitlevel);
|
||||
#endif
|
||||
/* if the user is NOT already on the shitlist */
|
||||
/* first, create a new structure */
|
||||
|
||||
curr = (ShitUser *) MALLOC(sizeof(ShitUser));
|
||||
|
||||
curr->time = now;
|
||||
curr->expiration = exp;
|
||||
curr->level = shitlevel;
|
||||
|
||||
curr->match = (char *)MALLOC(strlen(pattern) + 1);
|
||||
strcpy(curr->match, pattern);
|
||||
|
||||
curr->from = (char *)MALLOC(strlen(srcuh) + 1);
|
||||
strcpy(curr->from, srcuh);
|
||||
|
||||
curr->reason = (char *)MALLOC(strlen(reason) + 1);
|
||||
strcpy(curr->reason, reason);
|
||||
|
||||
curr->channel = (char *)MALLOC(strlen(channel) + 1);
|
||||
strcpy(curr->channel, channel);
|
||||
|
||||
/* Then, link it to the list.. */
|
||||
|
||||
curr->next = ShitList[sl_hash(channel)];
|
||||
ShitList[sl_hash(channel)] = curr;
|
||||
|
||||
}
|
||||
|
||||
/* schedule the removal of the entry..
|
||||
*/
|
||||
AddEvent(EVENT_CLEANSHITLIST, exp, channel);
|
||||
|
||||
|
||||
if (*source && !force)
|
||||
notice(source, "Ban list updated");
|
||||
|
||||
if (shitlevel >= AUTO_KICK_SHIT_LEVEL && !force)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("Calling mban(\"\",%s,%s)\n", channel, pattern);
|
||||
#endif
|
||||
mban("", channel, pattern);
|
||||
|
||||
sprintf(buffer, "%s (%s) %s", pattern, source, reason);
|
||||
kick("", channel, buffer);
|
||||
}
|
||||
|
||||
/* Now, clean the shitlist */
|
||||
if (!force)
|
||||
CleanShitList("", channel);
|
||||
}
|
||||
|
||||
void RemShitList(char *source, char *ch, char *args, int force)
|
||||
{
|
||||
char channel[80];
|
||||
char pattern[2][200];
|
||||
register aluser *luser;
|
||||
register ShitUser *curr;
|
||||
register achannel *chan;
|
||||
int srcaccess, exact;
|
||||
|
||||
if (*args == '#')
|
||||
{
|
||||
GetWord(0, args, channel);
|
||||
args = ToWord(1, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(channel, ch);
|
||||
GuessChannel(source, channel);
|
||||
}
|
||||
|
||||
if (*source && force == 0)
|
||||
{
|
||||
chan = ToChannel(channel);
|
||||
if (chan != NULL && (chan->flags & CFL_OPONLY))
|
||||
{
|
||||
notice(source, replies[RPL_OPONLY][chan->lang]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcmp(channel, "*"))
|
||||
{
|
||||
notice(source, "SYNTAX: unban <#channel> <nick|address>");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!*source || force > 0)
|
||||
srcaccess = (MASTER_ACCESS + 1);
|
||||
else
|
||||
srcaccess = Access(channel, source);
|
||||
|
||||
if (srcaccess < ADD_TO_SHITLIST_LEVEL)
|
||||
{
|
||||
ReplyNotAccess(source, channel);
|
||||
return;
|
||||
}
|
||||
|
||||
GetWord(0, args, pattern[0]);
|
||||
|
||||
if (!*pattern[0])
|
||||
{
|
||||
notice(source, "SYNTAX: unban [#channel] <nick|address>");
|
||||
return;
|
||||
}
|
||||
|
||||
/* look if the user is on the channel, if so, take his address */
|
||||
|
||||
luser = ToLuser(pattern[0]);
|
||||
if (luser != NULL)
|
||||
{
|
||||
sprintf(pattern[1], "%s!%s@%s",
|
||||
luser->nick, luser->username, luser->site);
|
||||
exact = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
exact = 1;
|
||||
}
|
||||
|
||||
/* Now, seek thru the ShitList if the pattern is already there. */
|
||||
|
||||
curr = ShitList[sl_hash(channel)];
|
||||
if (exact)
|
||||
{
|
||||
while (curr && (strcasecmp(curr->match, pattern[0]) || strcasecmp(curr->channel, channel) || srcaccess < curr->level))
|
||||
{
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (curr && (!match(pattern[1], curr->match) || strcasecmp(curr->channel, channel) || srcaccess < curr->level))
|
||||
{
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (curr)
|
||||
{
|
||||
curr->expiration = now - 1;
|
||||
if (*source && !force)
|
||||
notice(source, "Ban list updated");
|
||||
CleanShitList("", channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
unban("", channel, pattern[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CleanShitList(char *source, char *channel)
|
||||
{
|
||||
char buffer[200];
|
||||
register ShitUser *curr, *prev;
|
||||
register achannel *chan;
|
||||
int i;
|
||||
|
||||
if (*source && Access(channel, source) < CLEAN_SHITLIST_LEVEL)
|
||||
{
|
||||
notice(source, "Your admin Access is too low");
|
||||
return;
|
||||
}
|
||||
|
||||
i = sl_hash(channel);
|
||||
curr = ShitList[i];
|
||||
prev = NULL;
|
||||
|
||||
while (curr)
|
||||
{
|
||||
chan = ToChannel(curr->channel);
|
||||
if (chan == NULL || (curr->expiration <= now && !strcasecmp(channel, chan->name))
|
||||
|| curr->level == 0)
|
||||
{
|
||||
if (chan != NULL && chan->on && chan->AmChanOp)
|
||||
{
|
||||
unban("", curr->channel, curr->match);
|
||||
}
|
||||
if (prev)
|
||||
{
|
||||
prev->next = curr->next;
|
||||
TTLALLOCMEM -= strlen(curr->match) + 1;
|
||||
free(curr->match);
|
||||
TTLALLOCMEM -= strlen(curr->from) + 1;
|
||||
free(curr->from);
|
||||
TTLALLOCMEM -= strlen(curr->reason) + 1;
|
||||
free(curr->reason);
|
||||
TTLALLOCMEM -= strlen(curr->channel) + 1;
|
||||
free(curr->channel);
|
||||
TTLALLOCMEM -= sizeof(ShitUser);
|
||||
free(curr);
|
||||
curr = prev->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
ShitList[i] = curr->next;
|
||||
TTLALLOCMEM -= strlen(curr->match) + 1;
|
||||
free(curr->match);
|
||||
TTLALLOCMEM -= strlen(curr->from) + 1;
|
||||
free(curr->from);
|
||||
TTLALLOCMEM -= strlen(curr->reason) + 1;
|
||||
free(curr->reason);
|
||||
TTLALLOCMEM -= strlen(curr->channel) + 1;
|
||||
free(curr->channel);
|
||||
TTLALLOCMEM -= sizeof(ShitUser);
|
||||
free(curr);
|
||||
curr = ShitList[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (*source)
|
||||
notice(source, "Ban list is now up-to-date");
|
||||
|
||||
sprintf(buffer, "Cleaned banlist on %s", channel);
|
||||
log(buffer);
|
||||
}
|
||||
|
||||
int IsShit(char *channel, char *user, char *out, char *reason)
|
||||
{
|
||||
register ShitUser *curr;
|
||||
register aluser *luser;
|
||||
char uh[200];
|
||||
|
||||
if (strchr(user, '!') != NULL)
|
||||
{
|
||||
strcpy(uh, user);
|
||||
}
|
||||
else
|
||||
{
|
||||
luser = ToLuser(user);
|
||||
sprintf(uh, "%s!%s@%s", luser->nick, luser->username, luser->site);
|
||||
}
|
||||
|
||||
curr = ShitList[sl_hash(channel)];
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("IsShit(%s,%s,%s)\n", channel, user, out);
|
||||
#endif
|
||||
|
||||
while (curr && (!match(channel, curr->channel) || !match(uh, curr->match)))
|
||||
curr = curr->next;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (curr)
|
||||
printf("Banlevel: %d\n", curr->level);
|
||||
#endif
|
||||
|
||||
if (curr)
|
||||
{
|
||||
if (out != NULL)
|
||||
strcpy(out, curr->match);
|
||||
if (reason != NULL)
|
||||
strcpy(reason, curr->reason);
|
||||
return (curr->level);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ShowShitList(char *source, char *ch, char *args)
|
||||
{
|
||||
register ShitUser *curr;
|
||||
struct tm *tp;
|
||||
char buffer[1024], global[] = "*";
|
||||
char channel[80];
|
||||
int found = 0;
|
||||
|
||||
if (*args == '#')
|
||||
{
|
||||
GetWord(0, args, channel);
|
||||
args = ToWord(1, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(channel, ch);
|
||||
GuessChannel(source, channel);
|
||||
}
|
||||
|
||||
if (!strcmp(channel, "*") || !*args)
|
||||
{
|
||||
notice(source, "SYNTAX: lbanlist [#channel] <search pattern>");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ToUser(channel, source) &&
|
||||
Access(channel, source) < 500 && Access(global, source) < 500)
|
||||
{
|
||||
notice(source, "You are not on that channel");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
curr = ShitList[sl_hash(channel)];
|
||||
while (curr)
|
||||
{
|
||||
if (!strcasecmp(channel, curr->channel) && match(curr->match, args))
|
||||
{
|
||||
found++;
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
if ((found > 15) && (source[0] != '+'))
|
||||
{
|
||||
sprintf(buffer, "There are %d matching entries. Please use a userhost mask to narrow down the list.", found);
|
||||
notice(source, buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (found == 0)
|
||||
{
|
||||
sprintf(buffer, "*** No entry matching with %s ***", args);
|
||||
notice(source, buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
sprintf(buffer, "*** Ban List for channel %s ***", channel);
|
||||
notice(source, buffer);
|
||||
|
||||
curr = ShitList[sl_hash(channel)];
|
||||
|
||||
while (curr)
|
||||
{
|
||||
if (!strcasecmp(channel, curr->channel) && match(curr->match, args))
|
||||
{
|
||||
sprintf(buffer, "%s %s Level: %d", curr->channel,
|
||||
curr->match, curr->level);
|
||||
notice(source, buffer);
|
||||
|
||||
sprintf(buffer, "ADDED BY: %s (%s)", curr->from,
|
||||
(*curr->reason) ? curr->reason : "No reason given");
|
||||
notice(source, buffer);
|
||||
|
||||
tp = gmtime(&curr->time);
|
||||
sprintf(buffer, "SINCE: %sUCT", asctime(tp));
|
||||
*strchr(buffer, '\n') = ' ';
|
||||
notice(source, buffer);
|
||||
|
||||
sprintf(buffer, "EXP: %s", time_remaining(curr->expiration - now));
|
||||
notice(source, buffer);
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
notice(source, "*** END ***");
|
||||
}
|
||||
|
||||
void SaveShitList(char *source, char *channel)
|
||||
{
|
||||
ShitDisk tmp;
|
||||
register ShitUser *user;
|
||||
register int file;
|
||||
char buffer[200];
|
||||
int i;
|
||||
|
||||
if (*source && Access(channel, source) < SAVE_SHITLIST_LEVEL)
|
||||
{
|
||||
notice(source, "Your admin Access is too low!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (active)
|
||||
return;
|
||||
active = 1;
|
||||
|
||||
alarm(5); /* avoid NFS hangs */
|
||||
file = open(SHITLIST_FILE ".new", O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||
alarm(0);
|
||||
|
||||
if (file < 0)
|
||||
{
|
||||
if (*source)
|
||||
notice(source, "Error opening BanList file! Aborted.");
|
||||
log("Error saving shitlist");
|
||||
active = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(buffer, ":%s AWAY :Busy saving precious ban list\n", mynick);
|
||||
sendtoserv(buffer);
|
||||
dumpbuff();
|
||||
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
user = ShitList[i];
|
||||
while (user)
|
||||
{
|
||||
tmp.time = user->time;
|
||||
tmp.expiration = user->expiration;
|
||||
strncpy(tmp.match, user->match, 79);
|
||||
tmp.match[79] = '\0';
|
||||
strncpy(tmp.from, user->from, 79);
|
||||
tmp.from[79] = '\0';
|
||||
strncpy(tmp.reason, user->reason, 199);
|
||||
tmp.reason[199] = '\0';
|
||||
strncpy(tmp.channel, user->channel, 49);
|
||||
tmp.channel[49] = '\0';
|
||||
tmp.level = user->level;
|
||||
|
||||
alarm(2);
|
||||
if (write(file, &tmp, sizeof(ShitDisk)) <= 0)
|
||||
{
|
||||
alarm(0);
|
||||
close(file);
|
||||
log("ERROR: Can't save banlist");
|
||||
log((char *)sys_errlist[errno]);
|
||||
alarm(2);
|
||||
remove(SHITLIST_FILE ".new");
|
||||
alarm(0);
|
||||
active = 0;
|
||||
sprintf(buffer, ":%s AWAY\n", mynick);
|
||||
sendtoserv(buffer);
|
||||
return;
|
||||
}
|
||||
alarm(0);
|
||||
|
||||
user = user->next;
|
||||
}
|
||||
}
|
||||
|
||||
close(file);
|
||||
alarm(20);
|
||||
rename(SHITLIST_FILE ".new", SHITLIST_FILE);
|
||||
alarm(0);
|
||||
if (*source)
|
||||
notice(source, "banlist saved.");
|
||||
active = 0;
|
||||
sprintf(buffer, ":%s AWAY\n", mynick);
|
||||
sendtoserv(buffer);
|
||||
}
|
||||
|
||||
void LoadShitList(char *source)
|
||||
{
|
||||
ShitDisk tmp;
|
||||
ShitUser *user;
|
||||
int file;
|
||||
int i;
|
||||
|
||||
if (*source && Access("*", source) < LOAD_SHITLIST_LEVEL)
|
||||
{
|
||||
notice(source, "Your admin access is too low!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (active)
|
||||
return;
|
||||
active = 1;
|
||||
|
||||
file = open(SHITLIST_FILE, O_RDONLY);
|
||||
if (file < 0)
|
||||
{
|
||||
if (*source)
|
||||
notice(source, "Error opening BanList file! Aborted.");
|
||||
log("ERROR loading banlist");
|
||||
active = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* empty existing shitlist */
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
while ((user = ShitList[i]) != NULL)
|
||||
{
|
||||
ShitList[i] = ShitList[i]->next;
|
||||
TTLALLOCMEM -= strlen(user->match) + 1;
|
||||
free(user->match);
|
||||
TTLALLOCMEM -= strlen(user->from) + 1;
|
||||
free(user->from);
|
||||
TTLALLOCMEM -= strlen(user->reason) + 1;
|
||||
free(user->reason);
|
||||
TTLALLOCMEM -= strlen(user->channel) + 1;
|
||||
free(user->channel);
|
||||
TTLALLOCMEM -= sizeof(ShitUser);
|
||||
free(user);
|
||||
}
|
||||
}
|
||||
|
||||
while (read(file, &tmp, sizeof(ShitDisk)) > 0)
|
||||
{
|
||||
if (tmp.expiration < now)
|
||||
continue;
|
||||
user = (ShitUser *) MALLOC(sizeof(ShitUser));
|
||||
user->time = tmp.time;
|
||||
user->expiration = tmp.expiration;
|
||||
if (tmp.level > 500)
|
||||
tmp.level = 500;
|
||||
user->level = tmp.level;
|
||||
user->match = (char *)MALLOC(strlen(tmp.match) + 1);
|
||||
strcpy(user->match, tmp.match);
|
||||
user->from = (char *)MALLOC(strlen(tmp.from) + 1);
|
||||
strcpy(user->from, tmp.from);
|
||||
user->reason = (char *)MALLOC(strlen(tmp.reason) + 1);
|
||||
strcpy(user->reason, tmp.reason);
|
||||
user->channel = (char *)MALLOC(strlen(tmp.channel) + 1);
|
||||
strcpy(user->channel, tmp.channel);
|
||||
|
||||
user->next = ShitList[sl_hash(tmp.channel)];
|
||||
ShitList[sl_hash(tmp.channel)] = user;
|
||||
}
|
||||
|
||||
close(file);
|
||||
|
||||
if (*source)
|
||||
notice(source, "BanList loaded!");
|
||||
|
||||
active = 0;
|
||||
}
|
||||
133
Sources/show_old_managers.c
Normal file
133
Sources/show_old_managers.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/* @(#)$Id: show_old_managers.c,v 1.2 1998/01/08 17:02:18 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
#include "dirent.h"
|
||||
|
||||
time_t now;
|
||||
|
||||
#define HOWLONG (30*24*60*60) /* 30 days */
|
||||
|
||||
void fix_user_file(char *file, char *channel)
|
||||
{
|
||||
dbuser dbu;
|
||||
int fd;
|
||||
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
fprintf(stderr, "Can't open %s [%s]\n", file, sys_errlist[errno]);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find at least one 500 seen within the last 30 days */
|
||||
while (read(fd, &dbu, sizeof(dbuser)) == sizeof(dbuser))
|
||||
{
|
||||
if (dbu.header[0] != 0xFF || dbu.header[1] != 0xFF ||
|
||||
dbu.footer[0] != 0xFF || dbu.footer[1] != 0xFF)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(dbu.match, "!DEL!"))
|
||||
continue;
|
||||
|
||||
if (dbu.access == 500 && (now - dbu.lastseen) < HOWLONG)
|
||||
{
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Ok.. at this point, there is no channel manager that was seen
|
||||
* within 30 days. Show all of them.
|
||||
*/
|
||||
lseek(fd, 0L, SEEK_SET);
|
||||
|
||||
while (read(fd, &dbu, sizeof(dbuser)) == sizeof(dbuser))
|
||||
{
|
||||
if (dbu.header[0] != 0xFF || dbu.header[1] != 0xFF ||
|
||||
dbu.footer[0] != 0xFF || dbu.footer[1] != 0xFF)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(dbu.match, "!DEL!"))
|
||||
continue;
|
||||
|
||||
if (dbu.access != 500)
|
||||
continue;
|
||||
|
||||
printf("%-14s %-9s %03d %-26s %.24s\n",
|
||||
dbu.channel, dbu.nick, dbu.access, dbu.match, ctime(&dbu.lastseen));
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void fix_user_db(void)
|
||||
{
|
||||
DIR *dp;
|
||||
struct dirent *ent;
|
||||
char dir[256], file[256], channel[80], *ptr;
|
||||
int count;
|
||||
|
||||
for (count = 0; count < 1000; count++)
|
||||
{
|
||||
sprintf(dir, "db/channels/%04X", count);
|
||||
dp = opendir(dir);
|
||||
if (dp == NULL)
|
||||
{
|
||||
fprintf(stderr, "Can't read %s [%s]\n", dir, sys_errlist[errno]);
|
||||
continue;
|
||||
}
|
||||
while ((ent = readdir(dp)) != NULL)
|
||||
{
|
||||
if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
|
||||
continue;
|
||||
strcpy(channel, ent->d_name);
|
||||
for (ptr = channel; *ptr; ptr++)
|
||||
if (*ptr == ' ')
|
||||
*ptr = '/';
|
||||
sprintf(file, "db/channels/%04X/%s", count, ent->d_name);
|
||||
fix_user_file(file, channel);
|
||||
}
|
||||
closedir(dp);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (chdir(HOMEDIR) < 0)
|
||||
{
|
||||
perror(HOMEDIR);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
time(&now);
|
||||
|
||||
fix_user_db();
|
||||
|
||||
return 0;
|
||||
}
|
||||
110
Sources/showdb.c
Normal file
110
Sources/showdb.c
Normal file
@@ -0,0 +1,110 @@
|
||||
/* @(#)$Id: showdb.c,v 1.6 1999/01/18 04:17:40 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
#include "dirent.h"
|
||||
|
||||
time_t now;
|
||||
|
||||
|
||||
void fix_user_file(char *file, char *channel)
|
||||
{
|
||||
dbuser dbu;
|
||||
int fd;
|
||||
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
fprintf(stderr, "Can't open %s [%s]\n", file, sys_errlist[errno]);
|
||||
return;
|
||||
}
|
||||
|
||||
while (read(fd, &dbu, sizeof(dbuser)) == sizeof(dbuser))
|
||||
{
|
||||
if (dbu.header[0] != 0xFF || dbu.header[1] != 0xFF ||
|
||||
dbu.footer[0] != 0xFF || dbu.footer[1] != 0xFF)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(dbu.match, "!DEL!"))
|
||||
continue;
|
||||
|
||||
printf("%-14s %-9s %03d %-26s %.24s\n",
|
||||
dbu.channel, dbu.nick, dbu.access, dbu.match, ctime(&dbu.lastseen));
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void fix_user_db(void)
|
||||
{
|
||||
DIR *dp;
|
||||
struct dirent *ent;
|
||||
char dir[256], file[256], channel[80], *ptr;
|
||||
int count;
|
||||
|
||||
for (count = 0; count < 1000; count++)
|
||||
{
|
||||
sprintf(dir, "db/channels/%04X", count);
|
||||
dp = opendir(dir);
|
||||
if (dp == NULL)
|
||||
{
|
||||
fprintf(stderr, "Can't read %s [%s]\n", dir, sys_errlist[errno]);
|
||||
continue;
|
||||
}
|
||||
while ((ent = readdir(dp)) != NULL)
|
||||
{
|
||||
if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
|
||||
continue;
|
||||
strcpy(channel, ent->d_name);
|
||||
for (ptr = channel; *ptr; ptr++)
|
||||
if (*ptr == ' ')
|
||||
*ptr = '/';
|
||||
sprintf(file, "db/channels/%04X/%s", count, ent->d_name);
|
||||
fix_user_file(file, channel);
|
||||
}
|
||||
closedir(dp);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (chdir(HOMEDIR) < 0)
|
||||
{
|
||||
perror(HOMEDIR);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
time(&now);
|
||||
|
||||
if (argc == 3)
|
||||
{
|
||||
fix_user_file(argv[1], argv[2]);
|
||||
}
|
||||
else
|
||||
fix_user_db();
|
||||
|
||||
return 0;
|
||||
}
|
||||
183
Sources/socketio.c
Normal file
183
Sources/socketio.c
Normal file
@@ -0,0 +1,183 @@
|
||||
/* @(#)$Id: socketio.c,v 1.7 1998/06/23 23:35:08 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
/* These routines were first developed for the telnet3d project.
|
||||
* Special thanks to Danny Mitchell (wildthang@irc) for his help.
|
||||
*/
|
||||
|
||||
|
||||
#include "h.h"
|
||||
|
||||
#ifdef DOHTTP
|
||||
#include <stdarg.h>
|
||||
|
||||
extern void chat_close(http_socket *, char *);
|
||||
|
||||
int readfrom_http(http_socket * client)
|
||||
{
|
||||
void http_log(char *fmt,...);
|
||||
char buf[1024];
|
||||
int length;
|
||||
|
||||
if ((length = read(client->fd, buf, 1023)) <= 0)
|
||||
{
|
||||
if (errno == EWOULDBLOCK || errno == EAGAIN)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (client->status == HTTP_CHAT)
|
||||
chat_close(client, "read error");
|
||||
close(client->fd);
|
||||
client->fd = -1;
|
||||
client->status = HTTP_ERROR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
buf[length] = '\0';
|
||||
#ifdef DEBUG
|
||||
printf("AA: |%s|\n", buf);
|
||||
#endif
|
||||
|
||||
if (copy_to_buffer(&client->inbuf, buf, length) >= 4096)
|
||||
{
|
||||
http_log("ERROR: Recv'd more than 4K from client! (flood?)");
|
||||
if (client->status == HTTP_CHAT)
|
||||
chat_close(client, "Input packet too big");
|
||||
client->status = HTTP_ERROR;
|
||||
close(client->fd);
|
||||
client->fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (find_char_in_buffer(&client->inbuf, '\n', 1023))
|
||||
{
|
||||
while (find_char_in_buffer(&client->inbuf, '\n', 1023) &&
|
||||
client->status != HTTP_PIPE &&
|
||||
client->status != HTTP_ENDING &&
|
||||
client->status != HTTP_ERROR)
|
||||
{
|
||||
copy_from_buffer(&client->inbuf, buf, '\n', 1023);
|
||||
parse_http(client, buf);
|
||||
}
|
||||
/* Check for STUPID MSIE! who doesn't send a \n after post data
|
||||
** so check for a = in the first 10 chars, assume *ugh* it's post data
|
||||
*/
|
||||
if (find_char_in_buffer(&client->inbuf, '=', 10))
|
||||
{
|
||||
if (client->status != HTTP_PIPE &&
|
||||
client->status != HTTP_ENDING &&
|
||||
client->status != HTTP_ERROR)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("SEND\n");
|
||||
#endif
|
||||
copy_from_buffer(&client->inbuf, buf, '\0', 1023);
|
||||
parse_http(client, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (length > 200)
|
||||
{
|
||||
if (client->status == HTTP_CHAT)
|
||||
chat_close(client, "line too long");
|
||||
client->status = HTTP_ERROR;
|
||||
close(client->fd);
|
||||
client->fd = -1;
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int flush_http_buffer(http_socket * client)
|
||||
{
|
||||
http_file_pipe *fpipe;
|
||||
char buf[1024];
|
||||
int length;
|
||||
int count;
|
||||
|
||||
if (client == NULL || client->outbuf == NULL)
|
||||
return -1;
|
||||
|
||||
while ((count = look_in_buffer(&client->outbuf, buf, '\0', 1023)) > 0)
|
||||
{
|
||||
if ((length = write(client->fd, buf, count)) <= 0)
|
||||
{
|
||||
if ((errno == EWOULDBLOCK || errno == EAGAIN) && length != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (client->status == HTTP_PIPE)
|
||||
{
|
||||
for (fpipe = FilePipes; fpipe != NULL; fpipe = fpipe->next)
|
||||
{
|
||||
if (fpipe->hsock == client)
|
||||
{
|
||||
close(fpipe->fd);
|
||||
destroy_file_pipe(fpipe);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (client->status == HTTP_CHAT)
|
||||
chat_close(client, "write error");
|
||||
close(client->fd);
|
||||
client->fd = -1;
|
||||
client->status = HTTP_ERROR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
skip_char_in_buffer(&client->outbuf, length);
|
||||
HTTPTTLSENTBYTES += length;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* sendto_client() by SeKs <intru@step.polymtl.ca>
|
||||
* args (struct buffer_block **block, char *format, args...)
|
||||
* adds 'args' according to 'format' to the client's output
|
||||
* buffer.
|
||||
*/
|
||||
long sendto_http(http_socket * sck, char *format,...)
|
||||
{
|
||||
va_list args;
|
||||
char string[1024];
|
||||
|
||||
va_start(args, format);
|
||||
vsprintf(string, format, args);
|
||||
va_end(args);
|
||||
|
||||
return copy_to_buffer(&sck->outbuf, string, strlen(string));
|
||||
}
|
||||
|
||||
#endif /* DOHTTP */
|
||||
198
Sources/special.c
Normal file
198
Sources/special.c
Normal file
@@ -0,0 +1,198 @@
|
||||
/* @(#)$Id: special.c,v 1.3 1996/11/13 00:40:49 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
|
||||
#define SPECFILE "special.log"
|
||||
|
||||
void SpecLog(char *text)
|
||||
{
|
||||
int fd;
|
||||
char date[80],buffer[1024];
|
||||
strcpy(date,ctime(&now));
|
||||
*strchr(date,'\n')='\0';
|
||||
|
||||
alarm(2);
|
||||
if((fd=open(SPECFILE,O_WRONLY|O_CREAT|O_APPEND,0600))>=0){
|
||||
alarm(0);
|
||||
sprintf(buffer,"%s: %s\n",date,text);
|
||||
alarm(2);
|
||||
write(fd,buffer,strlen(buffer));
|
||||
alarm(0);
|
||||
close(fd);
|
||||
}
|
||||
alarm(0);
|
||||
}
|
||||
|
||||
|
||||
void logmap(aserver *server,FILE *fp)
|
||||
{
|
||||
static char prefix[80]="";
|
||||
static int offset=0;
|
||||
asuser *suser;
|
||||
int nbusers=0,i;
|
||||
|
||||
|
||||
if(server==NULL){
|
||||
return;
|
||||
}
|
||||
|
||||
/* count number of users */
|
||||
for(i=0;i<100;i++){
|
||||
suser=server->users[i];
|
||||
while(suser!=NULL){
|
||||
nbusers++;
|
||||
suser=suser->next;
|
||||
}
|
||||
}
|
||||
|
||||
if(server->next==NULL){
|
||||
fprintf(fp,"%s`-%s (%d user%s)\n",prefix,server->name,nbusers,(nbusers>1)?"s":"");
|
||||
}else{
|
||||
fprintf(fp,"%s|-%s (%d user%s)\n",prefix,server->name,nbusers,(nbusers>1)?"s":"");
|
||||
}
|
||||
|
||||
if(server->next!=NULL)
|
||||
strcpy(prefix+offset,"| ");
|
||||
else
|
||||
strcpy(prefix+offset," ");
|
||||
|
||||
offset+=2;
|
||||
logmap(server->down,fp);
|
||||
offset-=2;
|
||||
prefix[offset]='\0';
|
||||
|
||||
logmap(server->next,fp);
|
||||
}
|
||||
|
||||
void SpecMap(void)
|
||||
{
|
||||
FILE *fp;
|
||||
if((fp=fopen(SPECFILE,"a"))!=NULL){
|
||||
logmap(ServerList,fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CHANNEL_LOG
|
||||
void LogChan(void)
|
||||
{
|
||||
register achannel *chan;
|
||||
register auser *user;
|
||||
register aluser *luser;
|
||||
register int i,isreg,count;
|
||||
register FILE *fp;
|
||||
char mode[80];
|
||||
char flag;
|
||||
|
||||
if((fp=fopen(CHANNEL_LOG,"a"))==NULL)
|
||||
return;
|
||||
|
||||
fprintf(fp,"%ld %s",now,ctime(&now));
|
||||
|
||||
for(i=0;i<1000;i++){
|
||||
for(chan=ChannelList[i];chan!=NULL;chan=chan->next){
|
||||
count=isreg=(chan->on)?1:0;
|
||||
|
||||
for(user=chan->users;user;user=user->next){
|
||||
count++;
|
||||
if(!isreg &&
|
||||
!strcasecmp(user->N->username,DEFAULT_USERNAME)&&
|
||||
!strcasecmp(user->N->site,DEFAULT_HOSTNAME)){
|
||||
isreg=1;
|
||||
}
|
||||
}
|
||||
GetWord(0,chan->mode,mode);
|
||||
if(strchr(mode,'s'))
|
||||
flag='S';
|
||||
else if(strchr(mode,'p'))
|
||||
flag='P';
|
||||
else
|
||||
flag='+';
|
||||
|
||||
fprintf(fp,"%s %c %d %s\n",
|
||||
chan->name,flag,count,isreg?"REG'D":"");
|
||||
}
|
||||
}
|
||||
count=0;
|
||||
for(i=0;i<1000;i++){
|
||||
luser=Lusers[i];
|
||||
while(luser!=NULL){
|
||||
count++;
|
||||
luser=luser->next;
|
||||
}
|
||||
}
|
||||
fprintf(fp,"* %d \n",count);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HISTORY
|
||||
void HistLog(char *text)
|
||||
{
|
||||
int fd;
|
||||
char date[80],buffer[1024];
|
||||
strcpy(date,ctime(&now));
|
||||
*strchr(date,'\n')='\0';
|
||||
|
||||
alarm(2);
|
||||
if((fd=open("hist.log",O_WRONLY|O_CREAT|O_APPEND,0600))>=0){
|
||||
alarm(0);
|
||||
sprintf(buffer,"%s: %s\n",date,text);
|
||||
alarm(2);
|
||||
write(fd,buffer,strlen(buffer));
|
||||
alarm(0);
|
||||
close(fd);
|
||||
}
|
||||
alarm(0);
|
||||
}
|
||||
|
||||
void History(char *line)
|
||||
{
|
||||
static char Log[25][512];
|
||||
static int offset=0;
|
||||
|
||||
if(line==NULL){
|
||||
int i=offset,top=offset-1;
|
||||
if(top==-1)
|
||||
top=25;
|
||||
while(i!=top){
|
||||
if(i==25)
|
||||
i=0;
|
||||
HistLog(Log[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(Log[offset],line,511);
|
||||
Log[offset][511]='\0';
|
||||
if(++offset==25)
|
||||
offset=0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
303
Sources/struct.h
Normal file
303
Sources/struct.h
Normal file
@@ -0,0 +1,303 @@
|
||||
/* @(#)$Id: struct.h,v 1.6 1997/07/01 21:51:09 cvs Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#ifdef NICKSERV
|
||||
#include "nickserv.h"
|
||||
#endif
|
||||
|
||||
typedef struct filehdr {
|
||||
unsigned char magic;
|
||||
unsigned int no;
|
||||
} filehdr;
|
||||
|
||||
typedef struct RegUser {
|
||||
char *realname;
|
||||
char *match;
|
||||
char *channel;
|
||||
char *passwd;
|
||||
char *modif;
|
||||
int access;
|
||||
unsigned long flags;
|
||||
time_t suspend;
|
||||
time_t lastseen;
|
||||
off_t offset;
|
||||
int modified;
|
||||
int inuse;
|
||||
time_t lastused;
|
||||
struct RegUser *next;
|
||||
} RegUser;
|
||||
|
||||
|
||||
typedef struct dbuser {
|
||||
unsigned char header[2];
|
||||
char nick[80];
|
||||
char match[80];
|
||||
char passwd[20];
|
||||
char channel[50];
|
||||
char modif[80];
|
||||
int access;
|
||||
unsigned long flags;
|
||||
time_t suspend;
|
||||
time_t lastseen;
|
||||
unsigned char footer[2];
|
||||
} dbuser;
|
||||
|
||||
|
||||
typedef struct achannel {
|
||||
char *name;
|
||||
int AmChanOp;
|
||||
int on;
|
||||
int MassDeopPro;
|
||||
int NickFloodPro;
|
||||
int MsgFloodPro;
|
||||
int lang;
|
||||
time_t TS;
|
||||
time_t lastact;
|
||||
time_t lasttopic;
|
||||
unsigned long flags;
|
||||
unsigned long uflags;
|
||||
char mode[80];
|
||||
char lastjoin[20];
|
||||
struct modequeue *modebuff;
|
||||
struct aban *bans;
|
||||
struct auser *users;
|
||||
struct achannel *next;
|
||||
} achannel;
|
||||
|
||||
typedef struct adefchan {
|
||||
char name[50];
|
||||
char mode[80];
|
||||
char url[80];
|
||||
char topic[80];
|
||||
int MassDeopPro;
|
||||
int NickFloodPro;
|
||||
int MsgFloodPro;
|
||||
int lang;
|
||||
time_t TS;
|
||||
unsigned long flags;
|
||||
unsigned long uflags;
|
||||
struct adefchan *next;
|
||||
} adefchan;
|
||||
|
||||
typedef struct achannelnode {
|
||||
struct achannel *N;
|
||||
struct anickchange *nickhist;
|
||||
struct achannelnode *next;
|
||||
} achannelnode;
|
||||
|
||||
typedef struct aserver {
|
||||
char *name;
|
||||
time_t TS;
|
||||
struct asuser *users[100];
|
||||
struct aserver *up;
|
||||
struct aserver *down;
|
||||
struct aserver *next;
|
||||
} aserver;
|
||||
|
||||
typedef struct asuser {
|
||||
struct aluser *N;
|
||||
struct asuser *next;
|
||||
} asuser;
|
||||
|
||||
typedef struct aluser {
|
||||
char *nick;
|
||||
char *username;
|
||||
char *site;
|
||||
time_t time;
|
||||
char mode;
|
||||
struct aserver *server;
|
||||
struct achannelnode *channel;
|
||||
struct avalchan *valchan;
|
||||
struct aluser *next;
|
||||
#ifdef NICKSERV
|
||||
struct aregnick *regnick;
|
||||
time_t reglimit;
|
||||
#endif
|
||||
} aluser;
|
||||
|
||||
typedef struct avalchan {
|
||||
char *name;
|
||||
RegUser *reg;
|
||||
struct avalchan *next;
|
||||
} avalchan;
|
||||
|
||||
typedef struct auser {
|
||||
struct aluser *N;
|
||||
char chanop;
|
||||
time_t lastact;
|
||||
struct amsg *msghist;
|
||||
struct adeop *deophist;
|
||||
struct auser *next;
|
||||
} auser;
|
||||
|
||||
typedef struct aban {
|
||||
char pattern[80];
|
||||
struct aban *next;
|
||||
} aban;
|
||||
|
||||
typedef struct adeop {
|
||||
time_t time;
|
||||
char nick[NICK_LENGTH];
|
||||
struct adeop *next;
|
||||
} adeop;
|
||||
|
||||
typedef struct anickchange {
|
||||
time_t time;
|
||||
char nick[NICK_LENGTH];
|
||||
struct anickchange *next;
|
||||
} anickchange;
|
||||
|
||||
typedef struct modequeue {
|
||||
int AsServer;
|
||||
char flag[3];
|
||||
char arg[80];
|
||||
struct modequeue *prev;
|
||||
struct modequeue *next;
|
||||
} modequeue;
|
||||
|
||||
typedef struct amsg {
|
||||
time_t time;
|
||||
int length;
|
||||
struct amsg *next;
|
||||
} amsg;
|
||||
|
||||
typedef struct ShitUser {
|
||||
time_t time;
|
||||
time_t expiration;
|
||||
char *match;
|
||||
char *from;
|
||||
char *reason;
|
||||
char *channel;
|
||||
int level;
|
||||
struct ShitUser *next;
|
||||
} ShitUser;
|
||||
|
||||
typedef struct anevent {
|
||||
time_t time;
|
||||
int event;
|
||||
char param[80];
|
||||
struct anevent *next;
|
||||
} anevent;
|
||||
|
||||
typedef struct alang {
|
||||
int no;
|
||||
char *abbr;
|
||||
char *name;
|
||||
} alang;
|
||||
|
||||
struct buffer_block {
|
||||
char buf[BUFFER_BLOCK_SIZE];
|
||||
short offset_read;
|
||||
short offset_write;
|
||||
struct buffer_block *next;
|
||||
};
|
||||
|
||||
typedef struct irc_socket {
|
||||
int fd;
|
||||
time_t TS;
|
||||
struct buffer_block *inbuf;
|
||||
struct buffer_block *outbuf;
|
||||
struct irc_socket *next;
|
||||
} irc_socket;
|
||||
|
||||
typedef struct http_raw {
|
||||
unsigned long key;
|
||||
} http_raw;
|
||||
|
||||
typedef struct http_post {
|
||||
char path[80];
|
||||
char protocol[80];
|
||||
int count;
|
||||
int ready;
|
||||
} http_post;
|
||||
|
||||
typedef struct http_socket {
|
||||
int fd;
|
||||
int status;
|
||||
int dbio;
|
||||
time_t TS;
|
||||
time_t since;
|
||||
void *hook;
|
||||
struct buffer_block *inbuf;
|
||||
struct buffer_block *outbuf;
|
||||
struct sockaddr_in peer;
|
||||
struct http_socket *next;
|
||||
} http_socket;
|
||||
|
||||
typedef struct http_file_pipe {
|
||||
int fd;
|
||||
http_socket *hsock;
|
||||
struct http_file_pipe *next;
|
||||
} http_file_pipe;
|
||||
|
||||
typedef struct misc_socket {
|
||||
int fd;
|
||||
int type;
|
||||
int status;
|
||||
time_t TS;
|
||||
char link[80];
|
||||
struct buffer_block *inbuf;
|
||||
struct buffer_block *outbuf;
|
||||
struct misc_socket *next;
|
||||
} misc_socket;
|
||||
|
||||
|
||||
#define DBCALLBACK(X) void (*X)(int *,off_t,int,void *,void *,dbuser*,int)
|
||||
|
||||
typedef struct dbquery {
|
||||
int fd;
|
||||
off_t offset;
|
||||
time_t time;
|
||||
unsigned int type;
|
||||
int action;
|
||||
int count;
|
||||
DBCALLBACK(callback);
|
||||
struct buffer_block *buf;
|
||||
void *hook1;
|
||||
void *hook2;
|
||||
struct dbquery *next;
|
||||
char channel[80];
|
||||
char info[80];
|
||||
char passwd[80];
|
||||
} dbquery;
|
||||
|
||||
|
||||
typedef struct dbsync {
|
||||
int fd;
|
||||
off_t offset;
|
||||
time_t time;
|
||||
int type; /* update, delete, add */
|
||||
int status; /* pending_write, seeking_empty_slot */
|
||||
RegUser **reg;
|
||||
struct buffer_block *buf;
|
||||
struct dbsync *next;
|
||||
} dbsync;
|
||||
|
||||
typedef struct syncchan {
|
||||
char name[50];
|
||||
struct syncchan *next;
|
||||
} syncchan;
|
||||
|
||||
2139
Sources/userlist.c
Normal file
2139
Sources/userlist.c
Normal file
File diff suppressed because it is too large
Load Diff
521
Sources/users.c
Normal file
521
Sources/users.c
Normal file
@@ -0,0 +1,521 @@
|
||||
/* @(#)$Id: users.c,v 1.7 1998/11/21 14:58:43 seks Exp $ */
|
||||
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
#include "h.h"
|
||||
|
||||
int lu_hash(char *nick)
|
||||
{
|
||||
register int i, j;
|
||||
|
||||
for (i = 0, j = 0; i < strlen(nick); i++)
|
||||
j += toupper((unsigned char)nick[i]);
|
||||
|
||||
return (j % 1000);
|
||||
}
|
||||
|
||||
int su_hash(char *nick)
|
||||
{
|
||||
register int i, j;
|
||||
|
||||
for (i = 0, j = 0; i < strlen(nick); i++)
|
||||
j += toupper((unsigned char)nick[i]);
|
||||
|
||||
return (j % 100);
|
||||
}
|
||||
|
||||
aluser *ToLuser(char *nick)
|
||||
{
|
||||
register aluser *curr;
|
||||
curr = Lusers[lu_hash(nick)];
|
||||
while (curr && strcasecmp(nick, curr->nick))
|
||||
curr = curr->next;
|
||||
|
||||
return (curr);
|
||||
}
|
||||
|
||||
void onnick(char *source, char *newnick, char *body)
|
||||
{
|
||||
register aluser *user, **u;
|
||||
register asuser *suser, **s;
|
||||
register aserver *serv;
|
||||
char username[80];
|
||||
char hostname[80];
|
||||
char TS[80];
|
||||
char server[80];
|
||||
register achannelnode *chan;
|
||||
register anickchange *curr, *prec;
|
||||
char buffer[512];
|
||||
int i = 0;
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("NICK: %s --> %s ...\n", source, newnick);
|
||||
#endif
|
||||
|
||||
/* a new user */
|
||||
if (!ToLuser(source))
|
||||
{ /* Not a user, so a server or nothing */
|
||||
if (strchr(source, '.') == NULL)
|
||||
{
|
||||
/* Source is not a user and not a server either */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcasecmp(newnick, mynick))
|
||||
{
|
||||
log("ERROR: I'm nick collided");
|
||||
#ifdef DEBUG
|
||||
printf("ARGH!!! I'M NICK COLLIDED!\n");
|
||||
#endif
|
||||
GetWord(1, body, TS);
|
||||
GetWord(2, body, username);
|
||||
GetWord(3, body, hostname);
|
||||
|
||||
if (atol(TS) <= logTS &&
|
||||
strcasecmp(username, myuser) &&
|
||||
strcasecmp(hostname, mysite))
|
||||
{
|
||||
NickInUse();
|
||||
log(source);
|
||||
log(newnick);
|
||||
log(body);
|
||||
}
|
||||
else
|
||||
{
|
||||
onquit(source);
|
||||
return; /*ignore */
|
||||
}
|
||||
#ifdef BACKUP
|
||||
}
|
||||
else if (!strcasecmp(newnick, MAIN_NICK))
|
||||
{
|
||||
return; /* ignore */
|
||||
#endif
|
||||
}
|
||||
else if (ToLuser(newnick))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("ARGH!!! NICK COLLISION\n");
|
||||
#endif
|
||||
onquit(newnick);
|
||||
}
|
||||
GetWord(1, body, TS);
|
||||
GetWord(2, body, username);
|
||||
GetWord(3, body, hostname);
|
||||
GetWord(4, body, server);
|
||||
|
||||
#ifdef FAKE_UWORLD
|
||||
if (Uworld_status == 1 && !strcasecmp(newnick, UFAKE_NICK))
|
||||
{
|
||||
if (atol(TS) <= UworldTS && atol(TS) != 0 &&
|
||||
strcasecmp(username, UFAKE_NICK) &&
|
||||
strcasecmp(hostname, UFAKE_HOST))
|
||||
{
|
||||
sprintf(buffer, "%s nick collided", UFAKE_NICK);
|
||||
log(buffer);
|
||||
Uworld_status = 0;
|
||||
KillUworld("nick collision");
|
||||
return; /* ignore if younger */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
user = (aluser *) MALLOC(sizeof(aluser));
|
||||
|
||||
user->nick = (char *)MALLOC(strlen(newnick) + 1);
|
||||
strcpy(user->nick, newnick);
|
||||
|
||||
user->username = (char *)MALLOC(strlen(username) + 1);
|
||||
strcpy(user->username, username);
|
||||
|
||||
user->site = (char *)MALLOC(strlen(hostname) + 1);
|
||||
strcpy(user->site, hostname);
|
||||
|
||||
if (*newnick == '+')
|
||||
serv = &VirtualServer;
|
||||
else
|
||||
serv = ToServer(server);
|
||||
|
||||
user->server = serv;
|
||||
|
||||
user->time = atol(TS);
|
||||
user->mode = 0;
|
||||
|
||||
user->channel = NULL;
|
||||
user->valchan = NULL;
|
||||
|
||||
user->next = Lusers[lu_hash(newnick)];
|
||||
Lusers[lu_hash(newnick)] = user;
|
||||
|
||||
/* add user in server's userlist
|
||||
*/
|
||||
suser = (asuser *) MALLOC(sizeof(asuser));
|
||||
suser->N = user;
|
||||
suser->next = serv->users[su_hash(newnick)];
|
||||
serv->users[su_hash(newnick)] = suser;
|
||||
|
||||
#ifdef NICKSERV
|
||||
nserv_nick(newnick, user);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{ /* nick change */
|
||||
|
||||
#if 0
|
||||
if (!strcasecmp(source, DEFAULT_NICKNAME) &&
|
||||
strcasecmp(newnick, DEFAULT_NICKNAME))
|
||||
{
|
||||
ChNick(DEFAULT_NICKNAME);
|
||||
}
|
||||
#endif
|
||||
if (!strcasecmp(newnick, mynick))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("ARGH!!! I'M NICK COLLIDED!\n");
|
||||
#endif
|
||||
GetWord(0, body, TS);
|
||||
if (atol(TS + 1) <= logTS)
|
||||
{
|
||||
NickInUse();
|
||||
log(source);
|
||||
log(newnick);
|
||||
log(body);
|
||||
}
|
||||
else
|
||||
{
|
||||
onquit(source);
|
||||
return; /*ignore */
|
||||
}
|
||||
}
|
||||
|
||||
u = &Lusers[lu_hash(source)];
|
||||
while (*u && strcasecmp(source, (*u)->nick))
|
||||
u = &(*u)->next;
|
||||
user = *u;
|
||||
|
||||
#ifdef NICKSERV
|
||||
nserv_nick(newnick, user);
|
||||
#endif
|
||||
|
||||
if (user == NULL)
|
||||
quit("ERROR! onnick() can't find user", 1);
|
||||
|
||||
s = &user->server->users[su_hash(source)];
|
||||
while (*s && strcasecmp((*s)->N->nick, user->nick))
|
||||
s = &(*s)->next;
|
||||
suser = *s;
|
||||
|
||||
/* change the nick in memory */
|
||||
|
||||
TTLALLOCMEM -= strlen(user->nick) + 1;
|
||||
free(user->nick);
|
||||
user->nick = (char *)MALLOC(strlen(newnick) + 1);
|
||||
strcpy(user->nick, newnick);
|
||||
|
||||
/* now relocate the structure */
|
||||
*u = user->next;
|
||||
user->next = Lusers[lu_hash(newnick)];
|
||||
Lusers[lu_hash(newnick)] = user;
|
||||
|
||||
*s = suser->next;
|
||||
suser->next = user->server->users[su_hash(newnick)];
|
||||
user->server->users[su_hash(newnick)] = suser;
|
||||
|
||||
/* NICK FLOOD PROTECTION */
|
||||
/* 1st wipe old nick changes off */
|
||||
chan = user->channel;
|
||||
while (chan)
|
||||
{
|
||||
curr = chan->nickhist;
|
||||
prec = NULL;
|
||||
|
||||
/* if not on channel.. ignore nick flood pro */
|
||||
if (!chan->N->on)
|
||||
{
|
||||
chan = chan->next;
|
||||
continue; /* yurk.. as bad as a goto ;) */
|
||||
}
|
||||
|
||||
while (curr)
|
||||
{
|
||||
if (curr->time < (now - 15))
|
||||
{
|
||||
if (prec)
|
||||
{
|
||||
prec->next = curr->next;
|
||||
TTLALLOCMEM -= sizeof(anickchange);
|
||||
free(curr);
|
||||
curr = prec->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
chan->nickhist = curr->next;
|
||||
TTLALLOCMEM -= sizeof(anickchange);
|
||||
free(curr);
|
||||
curr = chan->nickhist;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prec = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* now add the new nick change to the history */
|
||||
curr = (anickchange *) MALLOC(sizeof(anickchange));
|
||||
strcpy(curr->nick, source);
|
||||
curr->time = now; /* a lil confusing :( */
|
||||
curr->next = chan->nickhist;
|
||||
chan->nickhist = curr;
|
||||
|
||||
/* now count the nick changes in history
|
||||
if there are more than allowed.. grrrr */
|
||||
for (i = 0, curr = chan->nickhist; curr;
|
||||
curr = curr->next, i++);
|
||||
|
||||
if (i == chan->N->NickFloodPro && chan->N->NickFloodPro != 0
|
||||
&& chan->N->on)
|
||||
{
|
||||
sprintf(buffer, "%s!%s@%s", user->nick, user->username, user->site);
|
||||
notice(newnick,
|
||||
"### NICK FLOOD PROTECTION ACTIVATED ###");
|
||||
sprintf(buffer, "%s %d", newnick,
|
||||
NICK_FLOOD_SUSPEND_TIME);
|
||||
suspend("", chan->N->name, buffer);
|
||||
ban("", chan->N->name, newnick);
|
||||
}
|
||||
chan = chan->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void onquit(char *nick)
|
||||
{
|
||||
register aluser *user, **u;
|
||||
register asuser *suser, **s;
|
||||
register avalchan *valchan;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Detected user quit..\n");
|
||||
#endif
|
||||
u = &Lusers[lu_hash(nick)];
|
||||
while (*u && strcasecmp(nick, (*u)->nick))
|
||||
u = &(*u)->next;
|
||||
|
||||
user = *u;
|
||||
|
||||
if (user == NULL)
|
||||
{
|
||||
log("ERROR: onquit() can't find user!");
|
||||
#ifdef HISTORY
|
||||
History(NULL);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/* remove from memory */
|
||||
while ((valchan = user->valchan) != NULL)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("\twas validated on %s\n", valchan->name);
|
||||
#endif
|
||||
valchan->reg->inuse--;
|
||||
user->valchan = valchan->next;
|
||||
TTLALLOCMEM -= strlen(valchan->name) + 1;
|
||||
free(valchan->name);
|
||||
TTLALLOCMEM -= sizeof(avalchan);
|
||||
free(valchan);
|
||||
}
|
||||
while (user->channel != NULL)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("\twas on %s\n", user->channel->N->name);
|
||||
#endif
|
||||
/* onpart() free's the chan structure
|
||||
* we can't do chan=chan->next after the
|
||||
* onpart() call. We must start from the
|
||||
* beginning of the list every time
|
||||
*/
|
||||
onpart(nick, user->channel->N->name);
|
||||
}
|
||||
|
||||
/* remove user from server's userlist
|
||||
*/
|
||||
s = &user->server->users[su_hash(user->nick)];
|
||||
while (*s != NULL && strcasecmp((*s)->N->nick, user->nick))
|
||||
{
|
||||
s = &(*s)->next;
|
||||
}
|
||||
|
||||
if (*s != NULL)
|
||||
{
|
||||
suser = *s;
|
||||
*s = (*s)->next;
|
||||
TTLALLOCMEM -= sizeof(asuser);
|
||||
free(suser);
|
||||
}
|
||||
else
|
||||
{
|
||||
log("ERROR: onquit() user not found in server's userlist!");
|
||||
}
|
||||
|
||||
*u = user->next;
|
||||
#if 0
|
||||
if (!strcasecmp(user->nick, DEFAULT_NICKNAME))
|
||||
{
|
||||
ChNick(DEFAULT_NICKNAME);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NICKSERV
|
||||
nserv_quit(user);
|
||||
#endif
|
||||
|
||||
TTLALLOCMEM -= strlen(user->nick) + 1;
|
||||
free(user->nick);
|
||||
TTLALLOCMEM -= strlen(user->username) + 1;
|
||||
free(user->username);
|
||||
TTLALLOCMEM -= strlen(user->site) + 1;
|
||||
free(user->site);
|
||||
TTLALLOCMEM -= sizeof(aluser);
|
||||
free(user);
|
||||
}
|
||||
|
||||
void onkill(char *source, char *target, char *comment)
|
||||
{
|
||||
char buffer[200];
|
||||
|
||||
if (!strcasecmp(target, mynick))
|
||||
{
|
||||
#if 0
|
||||
/* ignore kill for nick collisions because we
|
||||
* already check in onnick() if we're collided.
|
||||
* This kill is prolly a lost kill resulting of
|
||||
* another nick collision..
|
||||
*/
|
||||
if (strstr(comment, "older nick overruled") ||
|
||||
strstr(comment, "collided yourself"))
|
||||
{
|
||||
log("ERROR: Nick collision on me?");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
sprintf(buffer, ":%s SQUIT %s 0 :killed by %s\n",
|
||||
SERVERNAME, SERVERNAME, source);
|
||||
sendtoserv(buffer);
|
||||
dumpbuff();
|
||||
close(Irc.fd);
|
||||
Irc.fd = -1;
|
||||
if (reconnect(server))
|
||||
{
|
||||
try_later(server);
|
||||
}
|
||||
#ifdef BACKUP
|
||||
}
|
||||
else if (!strcasecmp(target, MAIN_NICK))
|
||||
{
|
||||
quit(MAIN_NICK " is back", 0);
|
||||
#endif
|
||||
#ifdef FAKE_UWORLD
|
||||
}
|
||||
else if (!strcasecmp(target, UFAKE_NICK))
|
||||
{
|
||||
char buffer[200];
|
||||
sprintf(buffer, "%s is KILLED by %s", UFAKE_NICK, source);
|
||||
log(buffer);
|
||||
Uworld_status = 0;
|
||||
KillUworld("Killed");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
onquit(target);
|
||||
}
|
||||
|
||||
void onwhois(char *source, char *nick)
|
||||
{
|
||||
register aluser *user;
|
||||
register auser *usr;
|
||||
register achannelnode *chan;
|
||||
char buffer[512];
|
||||
|
||||
user = ToLuser(nick);
|
||||
|
||||
if (user == NULL)
|
||||
{
|
||||
sprintf(buffer, ":%s 401 %s %s :No such nick\n", SERVERNAME, source, nick);
|
||||
sendtoserv(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buffer, ":%s 311 %s %s %s %s * :\n", SERVERNAME, source, user->nick,
|
||||
user->username, user->site);
|
||||
sendtoserv(buffer);
|
||||
|
||||
chan = user->channel;
|
||||
if (chan != NULL && strcmp(user->nick, "X") && strcmp(user->nick, "W"))
|
||||
{
|
||||
sprintf(buffer, ":%s 319 %s %s :", SERVERNAME, source, nick);
|
||||
while (chan != NULL)
|
||||
{
|
||||
/* show a channel only if it is
|
||||
* not +s or +p
|
||||
*/
|
||||
if (!IsSet(chan->N->name, 's', "") &&
|
||||
!IsSet(chan->N->name, 'p', ""))
|
||||
{
|
||||
usr = ToUser(chan->N->name, nick);
|
||||
if (usr->chanop)
|
||||
strcat(buffer, "@");
|
||||
strcat(buffer, chan->N->name);
|
||||
strcat(buffer, " ");
|
||||
}
|
||||
chan = chan->next;
|
||||
if (strlen(buffer) > 300)
|
||||
{
|
||||
strcat(buffer, "\n");
|
||||
sendtoserv(buffer);
|
||||
sprintf(buffer, ":%s 319 %s %s :",
|
||||
SERVERNAME, source, nick);
|
||||
}
|
||||
}
|
||||
strcat(buffer, "\n");
|
||||
sendtoserv(buffer);
|
||||
}
|
||||
sprintf(buffer, ":%s 312 %s %s %s :\n", SERVERNAME, source, source, user->server->name);
|
||||
sendtoserv(buffer);
|
||||
|
||||
if (user->mode & LFL_ISOPER)
|
||||
{
|
||||
sprintf(buffer, ":%s 313 %s %s :is an IRC Operator\n",
|
||||
SERVERNAME, source, user->nick);
|
||||
sendtoserv(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(buffer, ":%s 318 %s :End of /WHOIS list.\n", SERVERNAME, source);
|
||||
sendtoserv(buffer);
|
||||
}
|
||||
38
Sources/version.SH
Executable file
38
Sources/version.SH
Executable file
@@ -0,0 +1,38 @@
|
||||
#!/bin/sh
|
||||
|
||||
TAG="v20020715 build-`date -u '+%Y%m%d%H%M%S'`"
|
||||
|
||||
echo Updating version... $TAG
|
||||
|
||||
cat << NUFF > version.c
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
/* This file is generated by version.SH and any change will be
|
||||
* overwritten when you recompile.
|
||||
*/
|
||||
|
||||
char VERSION[]="Undernet Channel Service $TAG ";
|
||||
|
||||
NUFF
|
||||
30
Sources/version.c
Normal file
30
Sources/version.c
Normal file
@@ -0,0 +1,30 @@
|
||||
/* Undernet Channel Service (X)
|
||||
* Copyright (C) 1995-2002 Robin Thellend
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* The author can be contact by email at <csfeedback@robin.pfft.net>
|
||||
*
|
||||
* Please note that this software is unsupported and mostly
|
||||
* obsolete. It was replaced by GNUworld/CMaster. See
|
||||
* http://gnuworld.sourceforge.net/ for more information.
|
||||
*/
|
||||
|
||||
/* This file is generated by version.SH and any change will be
|
||||
* overwritten when you recompile.
|
||||
*/
|
||||
|
||||
char VERSION[]="Undernet Channel Service v20020715151606 ";
|
||||
|
||||
4
Sources/version.h
Normal file
4
Sources/version.h
Normal file
@@ -0,0 +1,4 @@
|
||||
/* @(#)$Id: version.h,v 1.3 1996/11/13 00:40:51 seks Exp $ */
|
||||
|
||||
extern char VERSION[];
|
||||
|
||||
Reference in New Issue
Block a user