53 |
|
#include "listener.h" |
54 |
|
#include "irc_res.h" |
55 |
|
#include "userhost.h" |
56 |
+ |
#include "watch.h" |
57 |
|
|
58 |
|
dlink_list listing_client_list = { NULL, NULL, 0 }; |
59 |
|
/* Pointer to beginning of Client list */ |
123 |
|
client_p->since = client_p->lasttime = client_p->firsttime = CurrentTime; |
124 |
|
|
125 |
|
client_p->localClient = BlockHeapAlloc(lclient_heap); |
126 |
+ |
client_p->localClient->registration = REG_INIT; |
127 |
|
/* as good a place as any... */ |
128 |
|
dlinkAdd(client_p, make_dlink_node(), &unknown_list); |
129 |
|
} |
150 |
|
assert(client_p != NULL); |
151 |
|
assert(client_p != &me); |
152 |
|
assert(client_p->hnext == client_p); |
151 |
– |
assert(client_p->invited.head == NULL); |
153 |
|
assert(client_p->channel.head == NULL); |
153 |
– |
assert(dlink_list_length(&client_p->invited) == 0); |
154 |
|
assert(dlink_list_length(&client_p->channel) == 0); |
155 |
|
|
156 |
|
MyFree(client_p->away); |
158 |
|
|
159 |
|
if (MyConnect(client_p)) |
160 |
|
{ |
161 |
+ |
assert(client_p->localClient->invited.head == NULL); |
162 |
+ |
assert(dlink_list_length(&client_p->localClient->invited) == 0); |
163 |
|
assert(IsClosing(client_p) && IsDead(client_p)); |
164 |
|
|
165 |
|
MyFree(client_p->localClient->response); |
318 |
|
ilog(L_NOTICE, "No response from %s, closing link", |
319 |
|
get_client_name(client_p, HIDE_IP)); |
320 |
|
} |
321 |
+ |
|
322 |
|
ircsprintf(scratch, "Ping timeout: %d seconds", |
323 |
|
(int)(CurrentTime - client_p->lasttime)); |
321 |
– |
|
324 |
|
exit_client(client_p, &me, scratch); |
325 |
|
} |
326 |
|
else if (!IsPingWarning(client_p) && pingwarn > 0 && |
364 |
|
if (client_p->localClient->reject_delay > 0) |
365 |
|
{ |
366 |
|
if (client_p->localClient->reject_delay <= CurrentTime) |
367 |
< |
exit_client(client_p, &me, "Rejected"); |
367 |
> |
exit_client(client_p, &me, "Rejected"); |
368 |
|
continue; |
369 |
|
} |
370 |
|
|
371 |
< |
/* Check UNKNOWN connections - if they have been in this state |
371 |
> |
/* |
372 |
> |
* Check UNKNOWN connections - if they have been in this state |
373 |
|
* for > 30s, close them. |
374 |
|
*/ |
375 |
< |
if (client_p->firsttime ? ((CurrentTime - client_p->firsttime) > 30) : 0) |
376 |
< |
exit_client(client_p, &me, "Connection timed out"); |
375 |
> |
if (IsAuthFinished(client_p) && (CurrentTime - client_p->firsttime) > 30) |
376 |
> |
exit_client(client_p, &me, "Registration timed out"); |
377 |
|
} |
378 |
|
} |
379 |
|
|
761 |
|
DLINK_FOREACH_SAFE(lp, next_lp, source_p->channel.head) |
762 |
|
remove_user_from_channel(lp->data); |
763 |
|
|
761 |
– |
/* Clean up invitefield */ |
762 |
– |
DLINK_FOREACH_SAFE(lp, next_lp, source_p->invited.head) |
763 |
– |
del_invite(lp->data, source_p); |
764 |
– |
|
764 |
|
/* Clean up allow lists */ |
765 |
|
del_all_accepts(source_p); |
766 |
|
add_history(source_p, 0); |
767 |
|
off_history(source_p); |
768 |
|
|
769 |
+ |
watch_check_hash(source_p, RPL_LOGOFF); |
770 |
+ |
|
771 |
|
if (!MyConnect(source_p)) |
772 |
|
{ |
773 |
|
source_p->from->serv->dep_users--; |
774 |
|
assert(source_p->from->serv->dep_users >= 0); |
775 |
|
} |
776 |
+ |
else |
777 |
+ |
{ |
778 |
+ |
/* Clean up invitefield */ |
779 |
+ |
DLINK_FOREACH_SAFE(lp, next_lp, source_p->localClient->invited.head) |
780 |
+ |
del_invite(lp->data, source_p); |
781 |
+ |
} |
782 |
|
} |
783 |
|
|
784 |
|
/* Remove source_p from the client lists */ |
969 |
|
if (source_p->localClient->list_task != NULL) |
970 |
|
free_list_task(source_p->localClient->list_task, source_p); |
971 |
|
|
972 |
+ |
watch_del_watch_list(source_p); |
973 |
|
sendto_realops_flags(UMODE_CCONN, L_ALL, "Client exiting: %s (%s@%s) [%s] [%s]", |
974 |
|
source_p->name, source_p->username, source_p->host, comment, |
975 |
|
ConfigFileEntry.hide_spoof_ips && IsIPSpoof(source_p) ? |
976 |
|
"255.255.255.255" : source_p->sockhost); |
977 |
+ |
sendto_realops_flags(UMODE_CCONN_FULL, L_ALL, "CLIEXIT: %s %s %s %s 0 %s", |
978 |
+ |
source_p->name, |
979 |
+ |
source_p->username, |
980 |
+ |
source_p->host, |
981 |
+ |
|
982 |
+ |
ConfigFileEntry.hide_spoof_ips && IsIPSpoof(source_p) ? |
983 |
+ |
"255.255.255.255" : source_p->sockhost, |
984 |
+ |
comment); |
985 |
|
} |
986 |
|
|
987 |
|
/* As soon as a client is known to be a server of some sort |
1069 |
|
} |
1070 |
|
else if (IsClient(source_p) && !IsKilled(source_p)) |
1071 |
|
{ |
1072 |
< |
sendto_server(NULL, source_p, NULL, CAP_TS6, NOCAPS, NOFLAGS, |
1072 |
> |
sendto_server(from->from, source_p, NULL, CAP_TS6, NOCAPS, NOFLAGS, |
1073 |
|
":%s QUIT :%s", ID(source_p), comment); |
1074 |
< |
sendto_server(NULL, source_p, NULL, NOCAPS, CAP_TS6, NOFLAGS, |
1074 |
> |
sendto_server(from->from, source_p, NULL, NOCAPS, CAP_TS6, NOFLAGS, |
1075 |
|
":%s QUIT :%s", source_p->name, comment); |
1076 |
|
} |
1077 |
|
|
1149 |
|
} |
1150 |
|
else |
1151 |
|
{ |
1152 |
< |
report_error(L_ADMIN, "Lost connection to %s: %d", |
1152 |
> |
report_error(L_ADMIN, "Lost connection to %s: %s", |
1153 |
|
get_client_name(client_p, SHOW_IP), current_error); |
1154 |
< |
report_error(L_OPER, "Lost connection to %s: %d", |
1154 |
> |
report_error(L_OPER, "Lost connection to %s: %s", |
1155 |
|
get_client_name(client_p, MASK_IP), current_error); |
1156 |
|
} |
1157 |
|
|
1247 |
|
if (IsSoftCallerId(target)) |
1248 |
|
{ |
1249 |
|
DLINK_FOREACH(ptr, target->channel.head) |
1250 |
< |
if (IsMember(source, ptr->data)) |
1250 |
> |
if (IsMember(source, ((struct Membership *)ptr->data)->chptr)) |
1251 |
|
return (1); |
1252 |
|
} |
1253 |
|
|
1351 |
|
|
1352 |
|
/* This had to be copied here to avoid problems.. */ |
1353 |
|
source_p->tsinfo = CurrentTime; |
1354 |
+ |
source_p->localClient->registration &= ~REG_NEED_NICK; |
1355 |
|
|
1356 |
|
if (source_p->name[0]) |
1357 |
|
hash_del_client(source_p); |
1365 |
|
/* They have the nick they want now.. */ |
1366 |
|
client_p->llname[0] = '\0'; |
1367 |
|
|
1368 |
< |
if (source_p->flags & FLAGS_GOTUSER) |
1368 |
> |
if (!source_p->localClient->registration) |
1369 |
|
{ |
1370 |
|
strlcpy(buf, source_p->username, sizeof(buf)); |
1371 |
|
|
1392 |
|
void |
1393 |
|
change_local_nick(struct Client *client_p, struct Client *source_p, const char *nick) |
1394 |
|
{ |
1395 |
+ |
int samenick = 0; |
1396 |
+ |
|
1397 |
|
/* |
1398 |
|
** Client just changing his/her nick. If he/she is |
1399 |
|
** on a channel, send note of change to all clients |
1411 |
|
!ConfigFileEntry.anti_nick_flood || |
1412 |
|
(IsOper(source_p) && ConfigFileEntry.no_oper_flood)) |
1413 |
|
{ |
1414 |
< |
if (irccmp(source_p->name, nick)) |
1414 |
> |
samenick = !irccmp(source_p->name, nick); |
1415 |
> |
|
1416 |
> |
if (!samenick) |
1417 |
> |
{ |
1418 |
> |
/* |
1419 |
> |
* Make sure everyone that has this client on its accept list |
1420 |
> |
* loses that reference. |
1421 |
> |
*/ |
1422 |
> |
del_all_their_accepts(source_p); |
1423 |
|
source_p->tsinfo = CurrentTime; |
1424 |
+ |
clear_ban_cache_client(source_p); |
1425 |
+ |
} |
1426 |
|
|
1427 |
|
/* XXX - the format of this notice should eventually be changed |
1428 |
|
* to either %s[%s@%s], or even better would be get_client_name() -bill |
1432 |
|
sendto_common_channels_local(source_p, 1, ":%s!%s@%s NICK :%s", |
1433 |
|
source_p->name, source_p->username, |
1434 |
|
source_p->host, nick); |
1406 |
– |
|
1435 |
|
add_history(source_p, 1); |
1436 |
< |
|
1437 |
< |
/* Only hubs care about lazy link nicks not being sent on yet |
1438 |
< |
* lazylink leafs/leafs always send their nicks up to hub, |
1439 |
< |
* hence must always propagate nick changes. |
1440 |
< |
* hubs might not propagate a nick change, if the leaf |
1441 |
< |
* does not know about that client yet. |
1442 |
< |
*/ |
1436 |
> |
|
1437 |
> |
/* |
1438 |
> |
* Only hubs care about lazy link nicks not being sent on yet |
1439 |
> |
* lazylink leafs/leafs always send their nicks up to hub, |
1440 |
> |
* hence must always propagate nick changes. |
1441 |
> |
* hubs might not propagate a nick change, if the leaf |
1442 |
> |
* does not know about that client yet. |
1443 |
> |
*/ |
1444 |
|
sendto_server(client_p, source_p, NULL, CAP_TS6, NOCAPS, NOFLAGS, |
1445 |
|
":%s NICK %s :%lu", |
1446 |
|
ID(source_p), nick, (unsigned long)source_p->tsinfo); |
1460 |
|
if (source_p->name[0]) |
1461 |
|
hash_del_client(source_p); |
1462 |
|
|
1463 |
+ |
if (!samenick) |
1464 |
+ |
{ |
1465 |
+ |
clear_ban_cache_client(source_p); |
1466 |
+ |
watch_check_hash(source_p, RPL_LOGOFF); |
1467 |
+ |
} |
1468 |
+ |
|
1469 |
|
strcpy(source_p->name, nick); |
1470 |
|
hash_add_client(source_p); |
1471 |
|
|
1472 |
< |
/* Make sure everyone that has this client on its accept list |
1473 |
< |
* loses that reference. |
1439 |
< |
*/ |
1440 |
< |
del_all_their_accepts(source_p); |
1472 |
> |
if (!samenick) |
1473 |
> |
watch_check_hash(source_p, RPL_LOGON); |
1474 |
|
|
1475 |
|
/* fd_desc is long enough */ |
1476 |
|
fd_note(&client_p->localClient->fd, "Nick: %s", nick); |