mirror of
https://github.com/pissnet/pissircd.git
synced 2025-08-06 10:15:24 +01:00
Added NICKIP
This commit is contained in:
parent
2313035766
commit
c1af4a4516
17 changed files with 1514 additions and 924 deletions
2
Changes
2
Changes
|
@ -3190,3 +3190,5 @@ This is the 3.2 fixes branch.
|
|||
- German doc updates (week 21)
|
||||
- Fixed a permanent modules bug: custom allow/except/ban/deny types were lost
|
||||
after /rehash. Reported by AngryWolf (#0001837).
|
||||
- Fixed a problem with NICK collisions not using NICKv2 (#0001773) reported by thilo
|
||||
- Added NICKIP (#0000605 & #0001376)
|
||||
|
|
|
@ -125,6 +125,14 @@ extern char *inet_ntoa(struct IN_ADDR);
|
|||
extern int inet_netof(struct IN_ADDR);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_INET_NTOP
|
||||
const char *inet_ntop(int, const void *, char *, size_t);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_INET_PTON
|
||||
int inet_pton(int af, const char *src, void *dst);
|
||||
#endif
|
||||
|
||||
MODVAR int global_count, max_global_count;
|
||||
extern char *myctime(time_t);
|
||||
extern char *strtoken(char **, char *, char *);
|
||||
|
@ -314,7 +322,8 @@ extern struct SLink *find_user_link( /* struct SLink *, struct Client * */ );
|
|||
" SJ3" \
|
||||
" NS" \
|
||||
" SJB64" \
|
||||
" TKLEXT"
|
||||
" TKLEXT" \
|
||||
" NICKIP"
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
|
@ -338,6 +347,7 @@ extern int lu_noninv, lu_inv, lu_serv, lu_oper,
|
|||
|
||||
MODVAR TS now;
|
||||
|
||||
#ifndef _WIN32
|
||||
#if defined(__STDC__)
|
||||
#define __const const
|
||||
#define __signed signed
|
||||
|
@ -360,6 +370,9 @@ MODVAR TS now;
|
|||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
#define READBUF_SIZE 8192
|
||||
|
||||
|
|
|
@ -688,3 +688,5 @@ extern void reread_motdsandrules();
|
|||
extern MODVAR int SVSNOOP;
|
||||
extern int callbacks_check(void);
|
||||
extern void callbacks_switchover(void);
|
||||
extern char *encode_ip(char *);
|
||||
extern char *decode_ip(char *);
|
||||
|
|
|
@ -278,6 +278,8 @@ typedef unsigned int u_int32_t; /* XXX Hope this works! */
|
|||
#define OPT_NOT_VHP 0x2000
|
||||
#define OPT_TKLEXT 0x4000
|
||||
#define OPT_NOT_TKLEXT 0x8000
|
||||
#define OPT_NICKIP 0x10000
|
||||
#define OPT_NOT_NICKIP 0x20000
|
||||
|
||||
/* client->flags (32 bits): 28 used, 4 free */
|
||||
#define FLAGS_PINGSENT 0x0001 /* Unreplied ping sent */
|
||||
|
@ -345,6 +347,8 @@ typedef unsigned int u_int32_t; /* XXX Hope this works! */
|
|||
#define PROTO_VHP 0x0400 /* Send hostnames in NICKv2 even if not sethosted */
|
||||
#define PROTO_SJB64 0x0800
|
||||
#define PROTO_TKLEXT 0x1000 /* TKL extension: 10 parameters instead of 8 (3.2RC2) */
|
||||
#define PROTO_NICKIP 0x2000 /* Send IP addresses in the NICK command */
|
||||
|
||||
/* note: client->proto is currently a 'short' (max is 0x8000) */
|
||||
|
||||
/*
|
||||
|
@ -484,6 +488,7 @@ typedef unsigned int u_int32_t; /* XXX Hope this works! */
|
|||
#define IsToken(x) ((x)->proto & PROTO_TOKEN)
|
||||
#define SupportSJOIN(x) ((x)->proto & PROTO_SJOIN)
|
||||
#define SupportNICKv2(x) ((x)->proto & PROTO_NICKv2)
|
||||
#define SupportNICKIP(x) ((x)->proto & PROTO_NICKIP)
|
||||
#define SupportSJOIN2(x) ((x)->proto & PROTO_SJOIN2)
|
||||
#define SupportUMODE2(x) ((x)->proto & PROTO_UMODE2)
|
||||
#define SupportNS(x) ((x)->proto & PROTO_NS)
|
||||
|
@ -701,6 +706,7 @@ struct User {
|
|||
#ifdef LIST_DEBUG
|
||||
aClient *bcptr;
|
||||
#endif
|
||||
char *ip_str; /* The IP in string form */
|
||||
char *operlogin; /* Only used if person is/was opered, used for oper::maxlogins */
|
||||
struct {
|
||||
time_t nick_t;
|
||||
|
|
|
@ -142,6 +142,9 @@ typedef unsigned short u_int16_t;
|
|||
* IPv4 or IPv6 structures?
|
||||
*/
|
||||
|
||||
# define MYDUMMY_SIZE 128
|
||||
|
||||
|
||||
#ifdef INET6
|
||||
|
||||
# define AND16(x) ((x)[0]&(x)[1]&(x)[2]&(x)[3]&(x)[4]&(x)[5]&(x)[6]&(x)[7]&(x)[8]&(x)[9]&(x)[10]&(x)[11]&(x)[12]&(x)[13]&(x)[14]&(x)[15])
|
||||
|
@ -160,7 +163,6 @@ typedef unsigned short u_int16_t;
|
|||
//# define uint32_t __u32
|
||||
// # endif
|
||||
|
||||
# define MYDUMMY_SIZE 128
|
||||
char mydummy[MYDUMMY_SIZE];
|
||||
char mydummy2[MYDUMMY_SIZE];
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ MODDBGCFLAG=/LD
|
|||
!ENDIF
|
||||
|
||||
FD_SETSIZE=/D FD_SETSIZE=16384
|
||||
CFLAGS=$(DBGCFLAG) $(LIBCURL_INC) $(ZLIB_INC) $(OPENSSL_INC) /I ./INCLUDE /Fosrc/ /nologo \
|
||||
CFLAGS=$(DBGCFLAG) $(LIBCURL_INC) $(ZLIB_INC) $(OPENSSL_INC) /I ./INCLUDE /Fosrc/ /nologo \
|
||||
$(ZIPCFLAGS) $(CURLCFLAGS) $(FD_SETSIZE) $(SSLCFLAGS) $(NS_ADDRESS) /D NOSPOOF=1 /c
|
||||
LFLAGS=kernel32.lib user32.lib gdi32.lib shell32.lib ws2_32.lib advapi32.lib \
|
||||
dbghelp.lib oldnames.lib libcmt.lib comctl32.lib comdlg32.lib $(ZLIB_LIB) $(ZIPLIB) \
|
||||
|
|
|
@ -151,7 +151,11 @@ int EventMod(Event *event, EventInfo *mods) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
inline void DoEvents(void)
|
||||
#else
|
||||
void DoEvents(void)
|
||||
#endif
|
||||
{
|
||||
Event *eventptr;
|
||||
Event temp;
|
||||
|
|
11
src/list.c
11
src/list.c
|
@ -199,6 +199,7 @@ anUser *make_user(aClient *cptr)
|
|||
user->snomask = 0;
|
||||
*user->realhost = '\0';
|
||||
user->virthost = NULL;
|
||||
user->ip_str = NULL;
|
||||
cptr->user = user;
|
||||
}
|
||||
return user;
|
||||
|
@ -235,11 +236,13 @@ void free_user(anUser *user, aClient *cptr)
|
|||
if (--user->refcnt <= 0)
|
||||
{
|
||||
if (user->away)
|
||||
MyFree((char *)user->away);
|
||||
MyFree(user->away);
|
||||
if (user->swhois)
|
||||
MyFree((char *)user->swhois);
|
||||
MyFree(user->swhois);
|
||||
if (user->virthost)
|
||||
MyFree((char *)user->virthost);
|
||||
MyFree(user->virthost);
|
||||
if (user->ip_str)
|
||||
MyFree(user->ip_str);
|
||||
if (user->operlogin)
|
||||
MyFree(user->operlogin);
|
||||
/*
|
||||
|
@ -252,7 +255,7 @@ void free_user(anUser *user, aClient *cptr)
|
|||
user->username, user->realhost, user,
|
||||
user->invited, user->channel, user->joined,
|
||||
user->refcnt);
|
||||
MyFree((char *)user);
|
||||
MyFree(user);
|
||||
#ifdef DEBUGMODE
|
||||
users.inuse--;
|
||||
#endif
|
||||
|
|
|
@ -310,6 +310,11 @@ CMD_FUNC(m_protoctl)
|
|||
Debug((DEBUG_ERROR, "Chose protocol %s for link %s", proto, cptr->name));
|
||||
SetTKLEXT(cptr);
|
||||
}
|
||||
else if (strcmp(s, "NICKIP") == 0)
|
||||
{
|
||||
Debug((DEBUG_ERROR, "Chose protocol %s for link %s", proto, cptr->name));
|
||||
cptr->proto |= PROTO_NICKIP;
|
||||
}
|
||||
/*
|
||||
* Add other protocol extensions here, with proto
|
||||
* containing the base option, and options containing
|
||||
|
|
|
@ -798,9 +798,9 @@ int m_server_synch(aClient *cptr, long numeric, ConfigItem_link *aconf)
|
|||
{
|
||||
sendto_one(cptr,
|
||||
((cptr->proto & PROTO_SJB64) ?
|
||||
"%s %s %d %B %s %s %b %lu %s %s :%s"
|
||||
"%s %s %d %B %s %s %b %lu %s %s %s%s:%s"
|
||||
:
|
||||
"%s %s %d %lu %s %s %b %lu %s %s :%s"),
|
||||
"%s %s %d %lu %s %s %b %lu %s %s %s%s:%s"),
|
||||
(IsToken(cptr) ? TOK_NICK : MSG_NICK),
|
||||
acptr->name,
|
||||
acptr->hopcount + 1,
|
||||
|
@ -811,15 +811,16 @@ int m_server_synch(aClient *cptr, long numeric, ConfigItem_link *aconf)
|
|||
(unsigned long)acptr->user->servicestamp,
|
||||
(!buf || *buf == '\0' ? "+" : buf),
|
||||
((IsHidden(acptr) && (acptr->umodes & UMODE_SETHOST)) ? acptr->user->virthost : "*"),
|
||||
acptr->info);
|
||||
SupportNICKIP(cptr) ? encode_ip(acptr->user->ip_str) : "",
|
||||
SupportNICKIP(cptr) ? " " : "", acptr->info);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendto_one(cptr,
|
||||
(cptr->proto & PROTO_SJB64 ?
|
||||
"%s %s %d %B %s %s %s %lu %s %s :%s"
|
||||
"%s %s %d %B %s %s %s %lu %s %s %s%s:%s"
|
||||
:
|
||||
"%s %s %d %lu %s %s %s %lu %s %s :%s"),
|
||||
"%s %s %d %lu %s %s %s %lu %s %s %s%s:%s"),
|
||||
(IsToken(cptr) ? TOK_NICK : MSG_NICK),
|
||||
acptr->name,
|
||||
acptr->hopcount + 1,
|
||||
|
@ -830,12 +831,13 @@ int m_server_synch(aClient *cptr, long numeric, ConfigItem_link *aconf)
|
|||
(unsigned long)acptr->user->servicestamp,
|
||||
(!buf || *buf == '\0' ? "+" : buf),
|
||||
((IsHidden(acptr) && (acptr->umodes & UMODE_SETHOST)) ? acptr->user->virthost : "*"),
|
||||
acptr->info);
|
||||
SupportNICKIP(cptr) ? encode_ip(acptr->user->ip_str) : "",
|
||||
SupportNICKIP(cptr) ? " " : "", acptr->info);
|
||||
}
|
||||
}
|
||||
else
|
||||
sendto_one(cptr,
|
||||
"%s %s %d %ld %s %s %s %lu %s %s :%s",
|
||||
"%s %s %d %ld %s %s %s %lu %s %s %s%s:%s",
|
||||
(IsToken(cptr) ? TOK_NICK :
|
||||
MSG_NICK), acptr->name,
|
||||
acptr->hopcount + 1,
|
||||
|
@ -851,7 +853,8 @@ int m_server_synch(aClient *cptr, long numeric, ConfigItem_link *aconf)
|
|||
(!buf
|
||||
|| *buf == '\0' ? "+" : buf),
|
||||
GetHost(acptr),
|
||||
acptr->info);
|
||||
SupportNICKIP(cptr) ? encode_ip(acptr->user->ip_str) : "",
|
||||
SupportNICKIP(cptr) ? " " : "", acptr->info);
|
||||
}
|
||||
|
||||
if (acptr->user->away)
|
||||
|
|
|
@ -182,11 +182,11 @@ DLLFUNC int m_whois(aClient *cptr, aClient *sptr, int parc, char *parv[])
|
|||
me.name, parv[0], name,
|
||||
get_mode_str(acptr));
|
||||
}
|
||||
if (IsHidden(acptr) && ((acptr == sptr) || IsAnOper(sptr)))
|
||||
if ((acptr == sptr) || IsAnOper(sptr))
|
||||
{
|
||||
sendto_one(sptr, rpl_str(RPL_WHOISHOST),
|
||||
me.name, parv[0], acptr->name,
|
||||
user->realhost);
|
||||
user->realhost, user->ip_str ? user->ip_str : "");
|
||||
}
|
||||
|
||||
if (IsARegNick(acptr))
|
||||
|
|
|
@ -415,7 +415,7 @@ static char *replies[] = {
|
|||
/* 375 RPL_MOTDSTART */ ":%s 375 %s :- %s Message of the Day - ",
|
||||
/* 376 RPL_ENDOFMOTD */ ":%s 376 %s :End of /MOTD command.",
|
||||
/* 377 */ NULL,
|
||||
/* 378 RPL_WHOISHOST */ ":%s 378 %s %s :is connecting from *@%s",
|
||||
/* 378 RPL_WHOISHOST */ ":%s 378 %s %s :is connecting from *@%s %s",
|
||||
/* 379 RPL_WHOISMODES */ ":%s 379 %s %s :is using modes %s",
|
||||
/* 380 */ NULL,
|
||||
/* 381 RPL_YOUREOPER */ ":%s 381 %s :You are now an IRC Operator",
|
||||
|
|
|
@ -673,11 +673,7 @@ static void exit_one_client(aClient *cptr, aClient *sptr, aClient *from, char *c
|
|||
|
||||
if (!IsULine(sptr) && !split)
|
||||
if (sptr->user->server != me_hash)
|
||||
sendto_snomask(SNO_FCLIENT,
|
||||
"*** Notice -- Client exiting at %s: %s!%s@%s (%s)",
|
||||
sptr->user->server, sptr->name,
|
||||
sptr->user->username,
|
||||
sptr->user->realhost, comment);
|
||||
sendto_fconnectnotice(sptr->name, sptr->user, sptr, 1, comment);
|
||||
if (!MyClient(sptr))
|
||||
{
|
||||
RunHook2(HOOKTYPE_REMOTE_QUIT, sptr, comment);
|
||||
|
|
56
src/s_user.c
56
src/s_user.c
|
@ -775,7 +775,7 @@ extern MODVAR char cmodestring[512];
|
|||
extern MODVAR aTKline *tklines;
|
||||
extern int badclass;
|
||||
|
||||
extern int register_user(aClient *cptr, aClient *sptr, char *nick, char *username, char *umode, char *virthost)
|
||||
extern int register_user(aClient *cptr, aClient *sptr, char *nick, char *username, char *umode, char *virthost, char *ip)
|
||||
{
|
||||
ConfigItem_ban *bconf;
|
||||
char *parv[3], *tmpstr;
|
||||
|
@ -1089,6 +1089,8 @@ extern int register_user(aClient *cptr, aClient *sptr, char *nick, char *usernam
|
|||
/* Here pig.. yeah you .. -Stskeeps */
|
||||
sptr->user->virthost = strdup(virthost);
|
||||
}
|
||||
if (ip)
|
||||
sptr->user->ip_str = strdup(decode_ip(ip));
|
||||
}
|
||||
|
||||
hash_check_watch(sptr, RPL_LOGON); /* Uglier hack */
|
||||
|
@ -1098,9 +1100,7 @@ extern int register_user(aClient *cptr, aClient *sptr, char *nick, char *usernam
|
|||
sptr->hopcount + 1, sptr->lastnick, user->username, user->realhost,
|
||||
user->server, user->servicestamp, sptr->info,
|
||||
(!buf || *buf == '\0' ? "+" : buf),
|
||||
/* ((IsHidden(sptr)
|
||||
&& (sptr->umodes & UMODE_SETHOST)) ? sptr->user->virthost : "*"));*/
|
||||
sptr->user->virthost);
|
||||
sptr->umodes & UMODE_SETHOST ? sptr->user->virthost : NULL);
|
||||
|
||||
/* Send password from sptr->passwd to NickServ for identification,
|
||||
* if passwd given and if NickServ is online.
|
||||
|
@ -1174,6 +1174,9 @@ extern int register_user(aClient *cptr, aClient *sptr, char *nick, char *usernam
|
|||
** parv[8] = umodes
|
||||
** parv[9] = virthost, * if none
|
||||
** parv[10] = info
|
||||
** if NICKIP:
|
||||
** parv[10] = ip
|
||||
** parv[11] = info
|
||||
*/
|
||||
CMD_FUNC(m_nick)
|
||||
{
|
||||
|
@ -1550,16 +1553,8 @@ CMD_FUNC(m_nick)
|
|||
|
||||
sendto_one(cptr, ":%s KILL %s :%s (Nick Collision)",
|
||||
me.name, parv[1], me.name);
|
||||
sendto_one(cptr, "NICK %s %d %ld %s %s %s :%s",
|
||||
acptr->name, acptr->hopcount + 1, acptr->lastnick,
|
||||
acptr->user->username, acptr->user->realhost,
|
||||
acptr->user->server, acptr->info);
|
||||
send_umode(cptr, acptr, 0, SEND_UMODES, buf);
|
||||
if (IsHidden(acptr))
|
||||
{
|
||||
sendto_one(cptr, ":%s SETHOST %s", acptr->name,
|
||||
acptr->user->virthost);
|
||||
}
|
||||
send_umode(NULL, acptr, 0, SEND_UMODES, buf);
|
||||
sendto_one_nickcmd(cptr, acptr, buf);
|
||||
if (acptr->user->away)
|
||||
sendto_one(cptr, ":%s AWAY :%s", acptr->name,
|
||||
acptr->user->away);
|
||||
|
@ -1629,19 +1624,11 @@ CMD_FUNC(m_nick)
|
|||
/* Kill their user. */
|
||||
sendto_one(cptr, ":%s KILL %s :%s (Nick Collision)",
|
||||
me.name, parv[1], me.name);
|
||||
sendto_one(cptr, "NICK %s %d %ld %s %s %s :%s",
|
||||
acptr->name, acptr->hopcount + 1, acptr->lastnick,
|
||||
acptr->user->username, acptr->user->realhost,
|
||||
acptr->user->server, acptr->info);
|
||||
send_umode(cptr, acptr, 0, SEND_UMODES, buf);
|
||||
send_umode(NULL, acptr, 0, SEND_UMODES, buf);
|
||||
sendto_one_nickcmd(cptr, acptr, buf);
|
||||
if (acptr->user->away)
|
||||
sendto_one(cptr, ":%s AWAY :%s", acptr->name,
|
||||
acptr->user->away);
|
||||
if (IsHidden(acptr))
|
||||
{
|
||||
sendto_one(cptr, ":%s SETHOST %s", acptr->name,
|
||||
acptr->user->virthost);
|
||||
}
|
||||
|
||||
send_user_joins(cptr, acptr);
|
||||
return 0; /* their user lost, ignore the NICK */
|
||||
|
@ -1799,7 +1786,7 @@ CMD_FUNC(m_nick)
|
|||
#endif
|
||||
sptr->lastnick = TStime(); /* Always local client */
|
||||
if (register_user(cptr, sptr, nick,
|
||||
sptr->user->username, NULL, NULL) == FLUSH_BUFFER)
|
||||
sptr->user->username, NULL, NULL, NULL) == FLUSH_BUFFER)
|
||||
return FLUSH_BUFFER;
|
||||
strcpy(nick, sptr->name); /* don't ask, but I need this. do not remove! -- Syzop */
|
||||
update_watch = 0;
|
||||
|
@ -1822,10 +1809,7 @@ CMD_FUNC(m_nick)
|
|||
parv[3] = nick;
|
||||
m_user(cptr, sptr, parc - 3, &parv[3]);
|
||||
if (GotNetInfo(cptr) && !IsULine(sptr))
|
||||
sendto_snomask(SNO_FCLIENT,
|
||||
"*** Notice -- Client connecting at %s: %s (%s@%s)",
|
||||
sptr->user->server, sptr->name,
|
||||
sptr->user->username, sptr->user->realhost);
|
||||
sendto_fconnectnotice(sptr->name, sptr->user, sptr, 0, NULL);
|
||||
}
|
||||
else if (IsPerson(sptr) && update_watch)
|
||||
hash_check_watch(sptr, RPL_LOGON);
|
||||
|
@ -1929,7 +1913,7 @@ CMD_FUNC(m_user)
|
|||
{
|
||||
#define UFLAGS (UMODE_INVISIBLE|UMODE_WALLOP|UMODE_SERVNOTICE)
|
||||
char *username, *host, *server, *realname, *umodex = NULL, *virthost =
|
||||
NULL;
|
||||
NULL, *ip = NULL;
|
||||
u_int32_t sstamp = 0;
|
||||
anUser *user;
|
||||
aClient *acptr;
|
||||
|
@ -1981,6 +1965,15 @@ CMD_FUNC(m_user)
|
|||
umodex = parv[5];
|
||||
virthost = parv[6];
|
||||
}
|
||||
else if (parc == 9 && IsServer(cptr))
|
||||
{
|
||||
if (isdigit(*parv[4]))
|
||||
sstamp = atol(parv[4]);
|
||||
realname = (BadPtr(parv[8])) ? "<bad-realname>" : parv[8];
|
||||
umodex = parv[5];
|
||||
virthost = parv[6];
|
||||
ip = parv[7];
|
||||
}
|
||||
else
|
||||
{
|
||||
realname = (BadPtr(parv[4])) ? "<bad-realname>" : parv[4];
|
||||
|
@ -2028,6 +2021,7 @@ CMD_FUNC(m_user)
|
|||
* which seemed bad. Not to say this is much better ;p. -- Syzop
|
||||
*/
|
||||
strncpyzt(user->realhost, Inet_ia2p(&sptr->ip), sizeof(user->realhost));
|
||||
user->ip_str = strdup(Inet_ia2p(&sptr->ip));
|
||||
user->server = me_hash;
|
||||
user_finish:
|
||||
user->servicestamp = sstamp;
|
||||
|
@ -2041,7 +2035,7 @@ CMD_FUNC(m_user)
|
|||
|
||||
return(
|
||||
register_user(cptr, sptr, sptr->name, username, umodex,
|
||||
virthost));
|
||||
virthost,ip));
|
||||
}
|
||||
else
|
||||
strncpyzt(sptr->user->username, username, USERLEN + 1);
|
||||
|
|
155
src/send.c
155
src/send.c
|
@ -841,6 +841,10 @@ void sendto_serv_butone_token_opt(aClient *one, int opt, char *prefix, char *com
|
|||
continue;
|
||||
if ((opt & OPT_NOT_TKLEXT) && (cptr->proto & PROTO_TKLEXT))
|
||||
continue;
|
||||
if ((opt & OPT_NICKIP) && !(cptr->proto & PROTO_TKLEXT))
|
||||
continue;
|
||||
if ((opt & OPT_NOT_NICKIP) && (cptr->proto & PROTO_NICKIP))
|
||||
continue;
|
||||
|
||||
if (IsToken(cptr))
|
||||
{
|
||||
|
@ -1808,6 +1812,44 @@ void sendto_connectnotice(char *nick, anUser *user, aClient *sptr, int disconnec
|
|||
}
|
||||
}
|
||||
|
||||
void sendto_fconnectnotice(char *nick, anUser *user, aClient *sptr, int disconnect, char *comment)
|
||||
{
|
||||
aClient *cptr;
|
||||
int i;
|
||||
char connectd[1024];
|
||||
char connecth[1024];
|
||||
|
||||
if (!disconnect)
|
||||
{
|
||||
ircsprintf(connectd, "*** Notice -- Client connecting at %s: %s (%s@%s)",
|
||||
user->server, nick, user->username, user->realhost);
|
||||
ircsprintf(connecth,
|
||||
"*** Notice -- Client connecting at %s: %s (%s@%s) [%s] {0}", user->server, nick,
|
||||
user->username, user->realhost, user->ip_str ? user->ip_str : "0");
|
||||
}
|
||||
else
|
||||
{
|
||||
ircsprintf(connectd, "*** Notice -- Client exiting at %s: %s!%s@%s (%s)",
|
||||
user->server, nick, user->username, user->realhost, comment);
|
||||
ircsprintf(connecth, "*** Notice -- Client exiting at %s: %s (%s@%s) [%s] [%s]",
|
||||
user->server, nick, user->username, user->realhost, comment,
|
||||
user->ip_str ? user->ip_str : "0");
|
||||
}
|
||||
|
||||
for (i = 0; i <= LastSlot; i++)
|
||||
if ((cptr = local[i]) && !IsServer(cptr) && !IsMe(cptr) &&
|
||||
IsAnOper(cptr) && (cptr->user->snomask & SNO_FCLIENT))
|
||||
{
|
||||
if (IsHybNotice(cptr))
|
||||
sendto_one(cptr, ":%s NOTICE %s :%s", me.name,
|
||||
cptr->name, connecth);
|
||||
else
|
||||
sendto_one(cptr, ":%s NOTICE %s :%s", me.name,
|
||||
cptr->name, connectd);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* sendto_server_butone_nickcmd
|
||||
*
|
||||
|
@ -1836,30 +1878,47 @@ void sendto_serv_butone_nickcmd(aClient *one, aClient *sptr,
|
|||
if (IsServer(cptr))
|
||||
#endif
|
||||
{
|
||||
char *vhost;
|
||||
if (SupportVHP(cptr))
|
||||
{
|
||||
if (IsHidden(sptr))
|
||||
vhost = sptr->user->virthost;
|
||||
else
|
||||
vhost = sptr->user->realhost;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsHidden(sptr) && sptr->umodes & UMODE_SETHOST)
|
||||
vhost = sptr->user->virthost;
|
||||
else
|
||||
vhost = "*";
|
||||
}
|
||||
|
||||
if (SupportNICKv2(cptr))
|
||||
{
|
||||
if (sptr->srvptr->serv->numeric && SupportNS(cptr))
|
||||
sendto_one(cptr,
|
||||
(cptr->proto & PROTO_SJB64) ?
|
||||
"%s %s %d %B %s %s %b %lu %s %s :%s"
|
||||
/* Ugly double %s to prevent excessive spaces */
|
||||
"%s %s %d %B %s %s %b %lu %s %s %s%s:%s"
|
||||
:
|
||||
"%s %s %d %d %s %s %b %lu %s %s :%s"
|
||||
"%s %s %d %d %s %s %b %lu %s %s %s%s:%s"
|
||||
,
|
||||
(IsToken(cptr) ? TOK_NICK : MSG_NICK), nick,
|
||||
hopcount, lastnick, username, realhost,
|
||||
(long)(sptr->srvptr->serv->numeric),
|
||||
servicestamp, umodes,
|
||||
(SupportVHP(cptr) ? (IsHidden(sptr) ? sptr->user->virthost : realhost) : (virthost ? virthost : "*")),
|
||||
info);
|
||||
servicestamp, umodes, vhost,
|
||||
SupportNICKIP(cptr) ? encode_ip(sptr->user->ip_str) : "",
|
||||
SupportNICKIP(cptr) ? " " : "", info);
|
||||
else
|
||||
sendto_one(cptr,
|
||||
"%s %s %d %d %s %s %s %lu %s %s :%s",
|
||||
"%s %s %d %d %s %s %s %lu %s %s %s%s:%s",
|
||||
(IsToken(cptr) ? TOK_NICK : MSG_NICK), nick,
|
||||
hopcount, lastnick, username, realhost,
|
||||
SupportNS(cptr) && sptr->srvptr->serv->numeric ? base64enc(sptr->srvptr->serv->numeric) : server,
|
||||
servicestamp, umodes,
|
||||
(SupportVHP(cptr) ? (IsHidden(sptr) ? sptr->user->virthost : realhost) : (virthost ? virthost : "*")),
|
||||
info);
|
||||
servicestamp, umodes, vhost,
|
||||
SupportNICKIP(cptr) ? encode_ip(sptr->user->ip_str) : "",
|
||||
SupportNICKIP(cptr) ? " " : "", info);
|
||||
|
||||
}
|
||||
else
|
||||
|
@ -1897,6 +1956,84 @@ void sendto_serv_butone_nickcmd(aClient *one, aClient *sptr,
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* sendto_one_nickcmd
|
||||
*
|
||||
*/
|
||||
void sendto_one_nickcmd(aClient *cptr, aClient *sptr, char *umodes)
|
||||
{
|
||||
if (SupportNICKv2(cptr))
|
||||
{
|
||||
char *vhost;
|
||||
if (SupportVHP(cptr))
|
||||
{
|
||||
if (IsHidden(sptr))
|
||||
vhost = sptr->user->virthost;
|
||||
else
|
||||
vhost = sptr->user->realhost;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsHidden(sptr) && sptr->umodes & UMODE_SETHOST)
|
||||
vhost = sptr->user->virthost;
|
||||
else
|
||||
vhost = "*";
|
||||
}
|
||||
if (sptr->srvptr->serv->numeric && SupportNS(cptr))
|
||||
sendto_one(cptr,
|
||||
(cptr->proto & PROTO_SJB64) ?
|
||||
/* Ugly double %s to prevent excessive spaces */
|
||||
"%s %s %d %B %s %s %b %lu %s %s %s%s:%s"
|
||||
:
|
||||
"%s %s %d %d %s %s %b %lu %s %s %s%s:%s"
|
||||
,
|
||||
(IsToken(cptr) ? TOK_NICK : MSG_NICK), sptr->name,
|
||||
sptr->hopcount+1, sptr->lastnick, sptr->user->username,
|
||||
sptr->user->realhost, (long)(sptr->srvptr->serv->numeric),
|
||||
sptr->user->servicestamp, umodes, vhost,
|
||||
SupportNICKIP(cptr) ? encode_ip(sptr->user->ip_str) : "",
|
||||
SupportNICKIP(cptr) ? " " : "", sptr->info);
|
||||
else
|
||||
sendto_one(cptr,
|
||||
"%s %s %d %d %s %s %s %lu %s %s %s%s:%s",
|
||||
(IsToken(cptr) ? TOK_NICK : MSG_NICK), sptr->name,
|
||||
sptr->hopcount+1, sptr->lastnick, sptr->user->username,
|
||||
sptr->user->realhost, SupportNS(cptr) &&
|
||||
sptr->srvptr->serv->numeric ? base64enc(sptr->srvptr->serv->numeric)
|
||||
: sptr->user->server, sptr->user->servicestamp, umodes, vhost,
|
||||
SupportNICKIP(cptr) ? encode_ip(sptr->user->ip_str) : "",
|
||||
SupportNICKIP(cptr) ? " " : "", sptr->info);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendto_one(cptr, "%s %s %d %d %s %s %s %lu :%s",
|
||||
(IsToken(cptr) ? TOK_NICK : MSG_NICK),
|
||||
sptr->name, sptr->hopcount+1, sptr->lastnick, sptr->user->username,
|
||||
sptr->user->realhost, sptr->user->server, sptr->user->servicestamp,
|
||||
sptr->info);
|
||||
if (strcmp(umodes, "+"))
|
||||
{
|
||||
sendto_one(cptr, ":%s %s %s :%s",
|
||||
sptr->name, (IsToken(cptr) ? TOK_MODE :
|
||||
MSG_MODE), sptr->name, umodes);
|
||||
}
|
||||
if (IsHidden(sptr) && (sptr->umodes & UMODE_SETHOST))
|
||||
{
|
||||
sendto_one(cptr, ":%s %s %s",
|
||||
sptr->name, (IsToken(cptr) ? TOK_SETHOST :
|
||||
MSG_SETHOST), sptr->user->virthost);
|
||||
}
|
||||
else if (SupportVHP(cptr))
|
||||
{
|
||||
sendto_one(cptr, ":%s %s %s", sptr->name,
|
||||
(IsToken(cptr) ? TOK_SETHOST : MSG_SETHOST),
|
||||
(IsHidden(sptr) ? sptr->user->virthost :
|
||||
sptr->user->realhost));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void sendto_message_one(aClient *to, aClient *from, char *sender,
|
||||
char *cmd, char *nick, char *msg)
|
||||
{
|
||||
|
|
432
src/support.c
432
src/support.c
|
@ -121,7 +121,6 @@ char *strtok2(char *str, char *fs)
|
|||
** argv 11/90
|
||||
** $Id$
|
||||
*/
|
||||
|
||||
char *strerror(int err_no)
|
||||
{
|
||||
extern char *sys_errlist[]; /* Sigh... hopefully on all systems */
|
||||
|
@ -326,9 +325,6 @@ int dgets(int fd, char *buf, int num)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
|
||||
|
||||
/*
|
||||
* inetntop: return the : notation of a given IPv6 internet number.
|
||||
* make sure the compressed representation (rfc 1884) isn't used.
|
||||
|
@ -382,7 +378,6 @@ char *inetntop(int af, const void *in, char *out, size_t the_size)
|
|||
bcopy(local_dummy, out, 64);
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Made by Potvin originally, i guess */
|
||||
time_t atime_exp(char *base, char *ptr)
|
||||
|
@ -1850,3 +1845,430 @@ time_t unreal_getfilemodtime(char *filename)
|
|||
return fullTime.LowPart;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef AF_INET6
|
||||
#define AF_INET6 AF_MAX+1 /* just to let this compile */
|
||||
#endif
|
||||
|
||||
char *encode_ip(u_char *ip)
|
||||
{
|
||||
static char buf[25];
|
||||
u_char *cp;
|
||||
struct in_addr ia; /* For IPv4 */
|
||||
u_char ia6[16]; /* For IPv6 */
|
||||
|
||||
if (strchr(ip, ':'))
|
||||
{
|
||||
inet_pton(AF_INET6, ip, ia6);
|
||||
cp = (u_char *)ia6;
|
||||
if (cp[0] == 0 && cp[1] == 0 && cp[2] == 0 && cp[3] == 0 && cp[4] == 0
|
||||
&& cp[5] == 0 && cp[6] == 0 && cp[7] == 0 && cp[8] == 0
|
||||
&& cp[9] == 0 && cp[10] == 0xff
|
||||
&& cp[11] == 0xff)
|
||||
b64_encode((char *)&cp[12], sizeof(struct in_addr), buf, 25);
|
||||
else
|
||||
b64_encode((char *)cp, 16, buf, 25);
|
||||
}
|
||||
else
|
||||
{
|
||||
ia.s_addr = inet_addr(ip);
|
||||
cp = (u_char *)ia.s_addr;
|
||||
b64_encode((char *)&cp, sizeof(struct in_addr), buf, 25);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *decode_ip(char *buf)
|
||||
{
|
||||
int len = strlen(buf);
|
||||
char targ[25];
|
||||
|
||||
b64_decode(buf, targ, 25);
|
||||
if (len == 24) /* IPv6 */
|
||||
{
|
||||
static char result[64];
|
||||
return inetntop(AF_INET6, targ, result, 64);
|
||||
}
|
||||
else if (len == 8) /* IPv4 */
|
||||
return inet_ntoa(*(struct in_addr *)targ);
|
||||
else /* Error?? */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* IPv6 stuff */
|
||||
|
||||
#ifndef IN6ADDRSZ
|
||||
#define IN6ADDRSZ 16
|
||||
#endif
|
||||
|
||||
#ifndef INT16SZ
|
||||
#define INT16SZ 2
|
||||
#endif
|
||||
|
||||
#ifndef INADDRSZ
|
||||
#define INADDRSZ 4
|
||||
#endif
|
||||
|
||||
/* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_INET_NTOP
|
||||
/*
|
||||
* WARNING: Don't even consider trying to compile this on a system where
|
||||
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
|
||||
*/
|
||||
|
||||
static const char *inet_ntop4(const u_char *src, char *dst, size_t size);
|
||||
static const char *inet_ntop6(const u_char *src, char *dst, size_t size);
|
||||
|
||||
/* char *
|
||||
* inet_ntop(af, src, dst, size)
|
||||
* convert a network format address to presentation format.
|
||||
* return:
|
||||
* pointer to presentation format address (`dst'), or NULL (see errno).
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
const char *inet_ntop(int af, const void *src, char *dst, size_t size)
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_ntop4(src, dst, size));
|
||||
case AF_INET6:
|
||||
return (inet_ntop6(src, dst, size));
|
||||
default:
|
||||
#ifndef _WIN32
|
||||
errno = EAFNOSUPPORT;
|
||||
#else
|
||||
WSASetLastError(WSAEAFNOSUPPORT);
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* const char *
|
||||
* inet_ntop4(src, dst, size)
|
||||
* format an IPv4 address, more or less like inet_ntoa()
|
||||
* return:
|
||||
* `dst' (as a const)
|
||||
* notes:
|
||||
* (1) uses no statics
|
||||
* (2) takes a u_char* not an in_addr as input
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static const char *inet_ntop4(const u_char *src, char *dst, size_t size)
|
||||
{
|
||||
static const char fmt[] = "%u.%u.%u.%u";
|
||||
char tmp[sizeof "255.255.255.255"];
|
||||
|
||||
sprintf(tmp, fmt, src[0], src[1], src[2], src[3]);
|
||||
if ((size_t)strlen(tmp) > size) {
|
||||
#ifndef _WIN32
|
||||
errno = ENOSPC;
|
||||
#else
|
||||
WSASetLastError(WSAENOBUFS);
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
return (dst);
|
||||
}
|
||||
|
||||
/* const char *
|
||||
* inet_ntop6(src, dst, size)
|
||||
* convert IPv6 binary address into presentation (printable) format
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static const char *inet_ntop6(const u_char *src, char *dst, size_t size)
|
||||
{
|
||||
/*
|
||||
* Note that int32_t and int16_t need only be "at least" large enough
|
||||
* to contain a value of the specified size. On some systems, like
|
||||
* Crays, there is no such thing as an integer variable with 16 bits.
|
||||
* Keep this in mind if you think this function should have been coded
|
||||
* to use pointer overlays. All the world's not a VAX.
|
||||
*/
|
||||
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
|
||||
struct { int base, len; } best, cur;
|
||||
u_int32_t words[IN6ADDRSZ / INT16SZ];
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Preprocess:
|
||||
* Copy the input (bytewise) array into a wordwise array.
|
||||
* Find the longest run of 0x00's in src[] for :: shorthanding.
|
||||
*/
|
||||
memset(words, 0, sizeof words);
|
||||
for (i = 0; i < IN6ADDRSZ; i++)
|
||||
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||
best.base = -1;
|
||||
cur.base = -1;
|
||||
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
|
||||
if (words[i] == 0) {
|
||||
if (cur.base == -1)
|
||||
cur.base = i, cur.len = 1;
|
||||
else
|
||||
cur.len++;
|
||||
} else {
|
||||
if (cur.base != -1) {
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
cur.base = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cur.base != -1) {
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
}
|
||||
if (best.base != -1 && best.len < 2)
|
||||
best.base = -1;
|
||||
|
||||
/*
|
||||
* Format the result.
|
||||
*/
|
||||
tp = tmp;
|
||||
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
|
||||
/* Are we inside the best run of 0x00's? */
|
||||
if (best.base != -1 && i >= best.base &&
|
||||
i < (best.base + best.len)) {
|
||||
if (i == best.base)
|
||||
*tp++ = ':';
|
||||
continue;
|
||||
}
|
||||
/* Are we following an initial run of 0x00s or any real hex? */
|
||||
if (i != 0)
|
||||
*tp++ = ':';
|
||||
/* Is this address an encapsulated IPv4? */
|
||||
if (i == 6 && best.base == 0 &&
|
||||
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
|
||||
if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
|
||||
return (NULL);
|
||||
tp += strlen(tp);
|
||||
break;
|
||||
}
|
||||
sprintf(tp, "%x", words[i]);
|
||||
tp += strlen(tp);
|
||||
}
|
||||
/* Was it a trailing run of 0x00's? */
|
||||
if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
|
||||
*tp++ = ':';
|
||||
*tp++ = '\0';
|
||||
|
||||
/*
|
||||
* Check for overflow, copy, and we're done.
|
||||
*/
|
||||
if ((size_t) (tp - tmp) > size) {
|
||||
#ifndef _WIN32
|
||||
errno = ENOSPC;
|
||||
#else
|
||||
WSASetLastError(WSAENOBUFS);
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
return (dst);
|
||||
}
|
||||
|
||||
#endif /* !HAVE_INET_NTOP */
|
||||
|
||||
#ifndef HAVE_INET_PTON
|
||||
/*
|
||||
* WARNING: Don't even consider trying to compile this on a system where
|
||||
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
|
||||
*/
|
||||
|
||||
static int inet_pton4(const char *src, unsigned char *dst);
|
||||
static int inet_pton6(const char *src, unsigned char *dst);
|
||||
|
||||
/* int
|
||||
* inet_pton(af, src, dst)
|
||||
* convert from presentation format (which usually means ASCII printable)
|
||||
* to network format (which is usually some kind of binary format).
|
||||
* return:
|
||||
* 1 if the address was valid for the specified address family
|
||||
* 0 if the address wasn't valid (`dst' is untouched in this case)
|
||||
* -1 if some other error occurred (`dst' is untouched in this case, too)
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
int inet_pton(int af, const char *src, void *dst)
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_pton4(src, dst));
|
||||
case AF_INET6:
|
||||
return (inet_pton6(src, dst));
|
||||
default:
|
||||
#ifndef _WIN32
|
||||
errno = EAFNOSUPPORT;
|
||||
#else
|
||||
WSASetLastError(WSAEAFNOSUPPORT);
|
||||
#endif
|
||||
return (-1);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* int
|
||||
* inet_pton4(src, dst)
|
||||
* like inet_aton() but without all the hexadecimal and shorthand.
|
||||
* return:
|
||||
* 1 if `src' is a valid dotted quad, else 0.
|
||||
* notice:
|
||||
* does not touch `dst' unless it's returning 1.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int
|
||||
inet_pton4(const char *src, unsigned char *dst)
|
||||
{
|
||||
static const char digits[] = "0123456789";
|
||||
int saw_digit, octets, ch;
|
||||
unsigned char tmp[INADDRSZ], *tp;
|
||||
|
||||
saw_digit = 0;
|
||||
octets = 0;
|
||||
*(tp = tmp) = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if ((pch = strchr(digits, ch)) != NULL) {
|
||||
u_int new = *tp * 10 + (pch - digits);
|
||||
|
||||
if (new > 255)
|
||||
return (0);
|
||||
*tp = new;
|
||||
if (! saw_digit) {
|
||||
if (++octets > 4)
|
||||
return (0);
|
||||
saw_digit = 1;
|
||||
}
|
||||
} else if (ch == '.' && saw_digit) {
|
||||
if (octets == 4)
|
||||
return (0);
|
||||
*++tp = 0;
|
||||
saw_digit = 0;
|
||||
} else
|
||||
return (0);
|
||||
}
|
||||
if (octets < 4)
|
||||
return (0);
|
||||
/* bcopy(tmp, dst, INADDRSZ); */
|
||||
memcpy(dst, tmp, INADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* int
|
||||
* inet_pton6(src, dst)
|
||||
* convert presentation level address to network order binary form.
|
||||
* return:
|
||||
* 1 if `src' is a valid [RFC1884 2.2] address, else 0.
|
||||
* notice:
|
||||
* (1) does not touch `dst' unless it's returning 1.
|
||||
* (2) :: in a full address is silently ignored.
|
||||
* credit:
|
||||
* inspired by Mark Andrews.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int
|
||||
inet_pton6(const char *src, unsigned char *dst)
|
||||
{
|
||||
static const char xdigits_l[] = "0123456789abcdef",
|
||||
xdigits_u[] = "0123456789ABCDEF";
|
||||
unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
|
||||
const char *xdigits, *curtok;
|
||||
int ch, saw_xdigit;
|
||||
u_int val;
|
||||
|
||||
memset((tp = tmp), 0, IN6ADDRSZ);
|
||||
endp = tp + IN6ADDRSZ;
|
||||
colonp = NULL;
|
||||
/* Leading :: requires some special handling. */
|
||||
if (*src == ':')
|
||||
if (*++src != ':')
|
||||
return (0);
|
||||
curtok = src;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
|
||||
pch = strchr((xdigits = xdigits_u), ch);
|
||||
if (pch != NULL) {
|
||||
val <<= 4;
|
||||
val |= (pch - xdigits);
|
||||
if (val > 0xffff)
|
||||
return (0);
|
||||
saw_xdigit = 1;
|
||||
continue;
|
||||
}
|
||||
if (ch == ':') {
|
||||
curtok = src;
|
||||
if (!saw_xdigit) {
|
||||
if (colonp)
|
||||
return (0);
|
||||
colonp = tp;
|
||||
continue;
|
||||
}
|
||||
if (tp + INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (unsigned char) (val >> 8) & 0xff;
|
||||
*tp++ = (unsigned char) val & 0xff;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
|
||||
inet_pton4(curtok, tp) > 0) {
|
||||
tp += INADDRSZ;
|
||||
saw_xdigit = 0;
|
||||
break; /* '\0' was seen by inet_pton4(). */
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
if (saw_xdigit) {
|
||||
if (tp + INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (unsigned char) (val >> 8) & 0xff;
|
||||
*tp++ = (unsigned char) val & 0xff;
|
||||
}
|
||||
if (colonp != NULL) {
|
||||
/*
|
||||
* Since some memmove()'s erroneously fail to handle
|
||||
* overlapping regions, we'll do the shift by hand.
|
||||
*/
|
||||
const int n = tp - colonp;
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= n; i++) {
|
||||
endp[- i] = colonp[n - i];
|
||||
colonp[n - i] = 0;
|
||||
}
|
||||
tp = endp;
|
||||
}
|
||||
if (tp != endp)
|
||||
return (0);
|
||||
/* bcopy(tmp, dst, IN6ADDRSZ); */
|
||||
memcpy(dst, tmp, IN6ADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
#endif /* !HAVE_INET_PTON */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue