GOOGLE
/************************************************************************
* psybnc2.3, src/p_network.c
* Copyright (C) 2001 the most psychoid and
* the cool lam3rz IRC Group, IRCnet
* http://www.psychoid.lam3rz.de
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 1, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef lint
static char rcsid[] = "@(#)$Id: p_network.c, v 2.3 2001/07/13 02:03:00 psychoid Exp $";
#endif
#define P_NETWORK
#include <p_global.h>
/* check parent users */
int checkparents(int usernum)
{
int uparent;
pcontext;
if (user(usernum)->parent != 0)
{
uparent=user(usernum)->parent;
if (user(uparent)->instate == STD_NOUSE)
{
deluser(usernum);
loaduser(usernum);
} else {
strmncpy(user(usernum)->login,user(uparent)->login,sizeof(user(usernum)->login));
strmncpy(user(usernum)->user,user(uparent)->user,sizeof(user(usernum)->user));
strmncpy(user(usernum)->pass,user(uparent)->pass,sizeof(user(usernum)->pass));
user(usernum)->insock=user(uparent)->insock;
user(usernum)->instate=user(uparent)->instate;
user(usernum)->rights=user(uparent)->rights;
}
}
}
/* converting a outbounded input string to the nick of the parent */
int parentnick(int usern)
{
char *pt;
char *pt1;
char *pt2;
int uparent;
char tmpbuf[8192];
int intnet=0;
char nicktmp[70];
#ifdef INTNET
if(usern>10000)
{
usern-=10000;
intnet=1;
}
else
#endif
if (user(usern)->parent==0) return 0x0;
pcontext;
uparent=user(usern)->parent;
if (strmcmp(user(usern)->nick,user(uparent)->nick)==1) return 0x0;
if (ircbuf[0]==':')
{
ap_snprintf(nicktmp,sizeof(nicktmp),":%s!",user(usern)->nick);
pt=strstr(ircbuf,nicktmp);
if (pt==ircbuf) {
pt=ircbuf+strlen(nicktmp);
if(intnet==1)
ap_snprintf(tmpbuf,sizeof(tmpbuf),gettxt(637),user(usern)->nick,pt);
else
ap_snprintf(tmpbuf,sizeof(tmpbuf),gettxt(638),user(uparent)->nick,pt);
strmncpy(ircbuf,tmpbuf,sizeof(ircbuf));
}
}
ap_snprintf(nicktmp,sizeof(nicktmp)," %s ",user(usern)->nick);
if (strlen(ircbuf)<1) return 0x0;
pt=ircbuf;
pt2=strchr(pt+1,':');
while (1)
{
pt=strstr(pt+1,nicktmp);
if (pt==NULL) break;
if (pt>pt2 && pt2 != NULL) break;
/* its the nick */
pt1=pt+strlen(nicktmp);
pt1--;
*pt1=0;
pt1++;
*pt=0;
if(intnet==1)
ap_snprintf(tmpbuf,sizeof(tmpbuf),gettxt(639),ircbuf,user(usern)->nick,pt1);
else
ap_snprintf(tmpbuf,sizeof(tmpbuf),gettxt(640),ircbuf,user(uparent)->nick,pt1);
strmncpy(ircbuf,tmpbuf,sizeof(ircbuf));
}
}
/* this routine checks for a network token - phew */
int checknetwork(int usern)
{
struct usernodes *th;
char tmpircbuf[8192];
int i;
char *pt;
char *pt1;
char *pt2;
pcontext;
th=usernode;
strmncpy(tmpircbuf,ircbuf,sizeof(tmpircbuf));
pt=strchr(tmpircbuf,'~');
if (pt!=NULL)
{
pt1=pt;
pt1--;
if (*pt1=='*' || *pt1=='!') { /* if its a userflag, try next item */
pt1=pt;pt1++;
pt=strchr(pt1,'~');
if (pt==NULL) return usern;
}
pt1=tmpircbuf+1;
pt1=strchr(pt1,':');
if (pt1 != NULL && pt>pt1 && ifcommand("NICK")==0) /* if network specified in content, bye */
return usern;
pt1=pt;
while (pt1!=tmpircbuf && *pt1!=' ' && *pt1!=':') pt1--;
if (pt1==tmpircbuf) return usern; /* at start of the buffer ? nah */
/* in pt1 = start of networktoken, in pt = end of network token */
*pt1=0; /* buffer part 1 */
*pt=0; /* buffer part 2 */
pt2=pt;pt2++;pt1++;
if (*pt1=='#') pt1++; /* filtering the channels */
#ifdef INTNET
if(strmcmp(pt1,"int")==1)
{
i=usern+10000;
ap_snprintf(ircbuf,sizeof(ircbuf),gettxt(641),tmpircbuf,pt2);
return i;
} else {
#endif
while (th!=NULL)
{
i=th->uid;
if (user(i)->parent==usern)
{
if (strmcmp(user(i)->network,pt1)==1)
{
/* ok, we got it. its a valid network. Network user is in i
pt2 has the second part of the buffer, tmpircbuf is terminated
before start of network token. Lets craft the untokened ircbuf now */
ap_snprintf(ircbuf,sizeof(ircbuf),gettxt(642),tmpircbuf,pt2);
/* setting parents inbound flags to child */
if(i<10000)
{
user(i)->insock=user(usern)->insock;
user(i)->instate=user(usern)->instate;
}
/* returning the network uid */
return i;
}
}
th=th->next;
}
/* interesting network token, but not existent, telling the user its unknown */
ssnprintf(user(usern)->insock,gettxt(643),pt1);
/* clearing ircbuf */
ircbuf[0]=0;
#ifdef INTNET
}
#endif
}
return usern;
}
/* this is a bitch -> adding the network token to the currents network-Users-
Inbound */
int addtoken(int usern)
{
char *pt;
char *pt1;
char *pt2;
char tmpircbuf[8192];
char tmpircbuf2[8192];
char nameline[512];
char netname[20];
char myparentnick[64];
char l;
int intnet=0;
char flg;
int broken;
int eflg;
int sku=0;
char mm[2];
pcontext;
eflg=0;
#ifdef INTNET
if(usern>10000)
{
strmncpy(netname,"int",sizeof(netname));
usern=usern-10000;
intnet=10000;
strmncpy(myparentnick,user(usern)->nick,sizeof(myparentnick));
} else {
#endif
strmncpy(netname,user(usern)->network,sizeof(netname));
strmncpy(myparentnick,user(user(usern)->parent)->nick,sizeof(myparentnick));
#ifdef INTNET
}
#endif
/* skip nick message, if we are already changed */
if(ifcommand("NICK") && strmcmp(user(usern)->nick,ircto)==1)
{
*ircbuf=0;
return 0x0;
}
/* parsing channels */
pt1=strstr(ircbuf,ircto);
if (pt1!=NULL && *ircto!=0 && !ifcommand("QUIT"))
{
pt2=strchr(ircbuf+1,':');
if (ifcommand("JOIN") || ifcommand("PART") || ifcommand("NICK")) pt2=NULL;
pt=strchr(pt1,'#');
if (pt==NULL) pt=strchr(pt1,'+');
if (pt==NULL) pt=strchr(pt1,'&');
if (pt==NULL) pt=strchr(pt1,'!');
pcontext;
if (pt!=NULL)
{
if (pt>pt2 && pt2!=NULL)
{
sku=0;
} else {
pt=strstr(ircbuf,pt);
/* a channel. We preceed the 'to' parameter */
if (pt!= NULL)
{
pt--;
l=*pt;
*pt=0;
pt++;
ap_snprintf(tmpircbuf,sizeof(tmpircbuf),gettxt(644),ircbuf,l,netname,pt);
strmncpy(ircbuf,tmpircbuf,sizeof(ircbuf));
}
sku=1;
}
}
}
if(sku==0)
{
/* no, its a user ! */
/* checking, if we are the dest */
pcontext;
if (ifcommand("NICK"))
{
ap_snprintf(tmpircbuf,sizeof(tmpircbuf)," :%s",ircto);
pt=strstr(ircbuf,tmpircbuf);
if (pt!=NULL)
{
pt++;
*pt=0;
pt++;
ap_snprintf(tmpircbuf,sizeof(tmpircbuf),gettxt(645),ircbuf,netname,pt);
strmncpy(ircbuf,tmpircbuf,sizeof(ircbuf));
}
}
}
pcontext;
/* parsing Users */
if (strchr(ircfrom,'@') != NULL) { /* if theres a @ in the from, its a user */
if (strmcmp(ircnick,user(usern)->nick)!=1)
{
ap_snprintf(tmpircbuf,sizeof(tmpircbuf),gettxt(646),*ircbuf,netname,ircbuf+1);
strmncpy(ircbuf,tmpircbuf,sizeof(ircbuf));
}
}
pcontext;
if(intnet==0)
parentnick(usern);
/* special content parsing has to be done on NAMES and WHO */
broken=0;
if (ifcommand("353"))
{ /* names */
pt=ircbuf;
pt++;
pt=strchr(pt,':');
if (pt!=NULL)
{
pt++;
l=*pt;
*pt=0;
strmncpy(tmpircbuf,ircbuf,sizeof(tmpircbuf));
strmncpy(nameline,ircbuf,sizeof(nameline));
*pt=l;
/* now the hard stuff.. we precede every Nick */
while(eflg==0)
{
pt1=strchr(pt,' ');
if (pt1!=NULL) {
*pt1=0;l=32;
} else {
eflg=1;l=0;
}
flg=0;
/* the modes */
if (*pt=='@' || *pt=='+' || *pt=='%') {
flg=*pt;
pt++;
}
/* if its us, we dont parse */
if (strmcmp(pt,user(usern)->nick))
{
if(flg!=0)
ap_snprintf(tmpircbuf2,sizeof(tmpircbuf2),gettxt(647),tmpircbuf,flg,myparentnick,l);
else
ap_snprintf(tmpircbuf2,sizeof(tmpircbuf2),gettxt(648),tmpircbuf,myparentnick,l);
} else {
if (l==0)
ap_snprintf(tmpircbuf2,sizeof(tmpircbuf2),gettxt(649),tmpircbuf,pt,l);
else
{
if(flg!=0)
ap_snprintf(tmpircbuf2,sizeof(tmpircbuf2),gettxt(650),tmpircbuf,flg,netname,pt,l);
else
ap_snprintf(tmpircbuf2,sizeof(tmpircbuf2),gettxt(651),tmpircbuf,netname,pt,l);
}
}
strmncpy(tmpircbuf,tmpircbuf2,sizeof(tmpircbuf));
/* avoiding the limit exceed */
if (strlen(tmpircbuf)>500)
{
/* sending the result up to here */
writesock(user(usern)->insock,tmpircbuf);
/* building new names line */
strmncpy(tmpircbuf,nameline,sizeof(tmpircbuf));
}
pt=pt1+1;
}
strmncpy(ircbuf,tmpircbuf,sizeof(ircbuf));
}
}
pcontext;
if (ifcommand("311") || ifcommand("312") || ifcommand("313") || ifcommand("318") || ifcommand("319"))
{ /* the whois answers */
pt=strchr(ircbuf,' ');
if(pt!=NULL)
{
pt++;
pt=strchr(pt,' ');
if(pt!=NULL)
{
pt++;
pt=strchr(pt,' ');
if(pt!=NULL)
{
*pt=0;
pt++;
ap_snprintf(tmpircbuf,sizeof(tmpircbuf),gettxt(652),ircbuf,netname,pt);
strmncpy(ircbuf,tmpircbuf,sizeof(ircbuf));
}
}
}
}
pcontext;
if (ifcommand("319"))
{ /* the channel answer of whois */
ap_snprintf(tmpircbuf,sizeof(tmpircbuf)," :%s",irccontent);
pt=strstr(ircbuf,tmpircbuf);
if(pt!=NULL)
{
*pt=0; /* cutting */
/* and now: the channels: */
pt=irccontent;
tmpircbuf2[0]=0;
mm[0]=0;mm[1]=0;
while(pt!=NULL)
{
pt2=strchr(pt,' ');
if(pt2!=NULL)
{
*pt2=0;pt2++;
}
flg=0;
if(*pt=='+' || *pt=='^' || *pt=='@' || *pt=='%')
{
flg=*pt;
pt++;
}
if(strlen(tmpircbuf2)+strlen(netname)+6+strlen(pt)<sizeof(tmpircbuf2) && *pt!=' ' && *pt!=0)
{
if(flg!=0)
{
mm[0]=flg;
strcat(tmpircbuf2,mm);
}
strcat(tmpircbuf2,"#");
strcat(tmpircbuf2,netname);
strcat(tmpircbuf2,"~");
strcat(tmpircbuf2,pt);
strcat(tmpircbuf2," ");
}
pt=pt2;
}
ap_snprintf(tmpircbuf,sizeof(tmpircbuf),gettxt(653),ircbuf,tmpircbuf2);
strmncpy(ircbuf,tmpircbuf,sizeof(ircbuf));
}
}
pcontext;
if (ifcommand("352"))
{ /* who */
pt=ircbuf;
for (eflg=0;eflg<7;eflg++)
{
pt=strchr(pt+1,' ');if (pt==NULL) return 0x0;
}
*pt=0;
pt++;
pt2=strchr(pt,' ');
if (pt2==NULL) return 0x0;
*pt2=0;
pt2++;
/* here also, we skip us */
if (strstr(user(usern)->nick,pt) && strlen(pt)==strlen(user(usern)->nick)) {
ap_snprintf(tmpircbuf,sizeof(tmpircbuf),gettxt(654),ircbuf,myparentnick,pt2);
} else {
ap_snprintf(tmpircbuf,sizeof(tmpircbuf),gettxt(655),ircbuf,netname,pt,pt2);
}
strmncpy(ircbuf,tmpircbuf,sizeof(ircbuf));
}
pcontext;
if (ifcommand("MODE"))
{ /* this is funny. we have to decide, that a parameter is no hostmask and preceed it */
pt=strchr(ircbuf,' ');
if (pt==NULL) return 0x0;
pt=strchr(pt+1,' ');
if (pt==NULL) return 0x0;
pt++;
if (*pt == '#' || *pt == '&' || *pt == '+' || *pt == '!')
{ /* a channel, ok, check the parameters */
pt=strchr(pt,' ');
if (pt==NULL) return 0x0;
/* million of ircds, thousands of networks.. we cant parse the modes
we parse the parameters */
pt++;
pt=strchr(pt,' ');
if (pt==NULL) return 0x0;
/* now the parameters. Its no nick, if: @ is in, no user.
if first character is numeric, no user. Problem is:
Channel Key. Events Client side on NickBan. */
*pt=0;
ap_snprintf(tmpircbuf,sizeof(tmpircbuf),"%s ",ircbuf);
pt++;
eflg=0;
/* "bleh!blah@bloh MODE #x +o Irgs " */
while (eflg==0)
{
pt2=strchr(pt,' ');
if (pt2!=NULL)
{
l=*pt2;
*pt2=0;
pt2++;
} else {
l=0;eflg=1;
}
if (strchr(gettxt(656),*pt) == NULL && strchr(pt,'@')==NULL && strlen(pt)>0 && *pt!=' ' && *pt!=0 && pt!=pt2-1)
{
/* fixed for v2.2 - modes for us, no parse */
if ((strstr(pt,user(usern)->nick) && strlen(pt)==strlen(user(usern)->nick)) || *pt==' ')
{
ap_snprintf(tmpircbuf2,sizeof(tmpircbuf2),gettxt(657),tmpircbuf,pt,l);
} else {
ap_snprintf(tmpircbuf2,sizeof(tmpircbuf2),gettxt(658),tmpircbuf,netname,pt,l);
}
} else {
ap_snprintf(tmpircbuf2,sizeof(tmpircbuf2),gettxt(659),tmpircbuf,pt,l);
}
strmncpy(tmpircbuf,tmpircbuf2,sizeof(tmpircbuf));
pt=pt2;
}
strmncpy(ircbuf,tmpircbuf,sizeof(ircbuf));
}
}
pcontext;
if (ifcommand(gettxt(660)))
{ /* the content */
ap_snprintf(tmpircbuf,sizeof(tmpircbuf)," :%s",irccontent);
pt=strstr(ircbuf,tmpircbuf);
if(pt!=NULL)
{
*pt=0;
ap_snprintf(tmpircbuf2,sizeof(tmpircbuf2),gettxt(661),ircbuf,netname,irccontent);
strmncpy(ircbuf,tmpircbuf2,sizeof(ircbuf));
}
}
pcontext;
if (ifcommand("KICK"))
{ /* a kick. we need to preceed the victim */
pt=strchr(ircbuf,' ');
if (pt==NULL) return 0x0;
pt++;
pt=strchr(pt,' ');
if (pt==NULL) return 0x0;
pt++;
pt=strchr(pt,' ');
if (pt==NULL) return 0x0;
*pt=0;
pt++;
/* the victim */
pt2=strchr(pt,' ');
if (pt2==NULL) return 0x0;
*pt2=0;
pt2++;
if (strmcmp(myparentnick,pt)==1)
{
ap_snprintf(tmpircbuf,sizeof(tmpircbuf),gettxt(662),ircbuf,pt,pt2);
} else {
ap_snprintf(tmpircbuf,sizeof(tmpircbuf),gettxt(663),ircbuf,netname,pt,pt2);
}
strmncpy(ircbuf,tmpircbuf,sizeof(ircbuf));
}
return 0x0;
}
/* checking, if network exists for a user */
int checkusernetwork(int usern)
{
struct usernodes *th;
int uind;
pcontext;
#ifdef INTNET
if(strmcmp(user(uind)->network,"int")==1) return 0x0;
#endif
th=usernode;
while(th!=NULL)
{
uind=th->uid;
if (user(uind)->parent==usern) {
if (strmcmp(user(uind)->network,irccontent)) return uind;
}
th=th->next;
}
return 0;
}
Copyright © 1945 -