linkCleanUp()

This commit is contained in:
psyc://psyced.org/~lynX 2009-03-20 11:47:20 +01:00
parent 18aa0276d1
commit 836709492f
5 changed files with 69 additions and 31 deletions

View File

@ -1779,6 +1779,10 @@ see also: http://about.psyc.eu/SPAM
evtl nicht alle im richtigen channel, um den enter zu sehen..)
== IRC ISSUES 1.0 ======================================================
- according to rfc and ircd source IRC parser should accept when the last
argument is just a word instead of a phrase prefixed by :
this is unusual, but legal: "PRIVMSG #blah hello"
+ some irc clients do not implement their own pinging, and some NATs really
kill your irc session if it is too quiet too long. we need optional server
side pings

View File

@ -44,6 +44,11 @@ parse(a) {
if (a == "") return; // don't let " \n" execute "/s"
unless (sscanf(a, ":%s %s", from, t)) t = a;
sscanf(t, "%s :%s", t, text);
// when 'text' is not present, the last argument could be a single
// word text according to rfc. this has never seemed to hurt, but
// we are not exactly compliant in that sense. we could copy the
// last arg over into text, but that requires to change the api
// into explode()-based. WONTFIX
unless (sscanf(t, "%s %s", cmd, args)) cmd = t;
if (cmd) ircMsg(from, lower_case(cmd), args, text, a);
return 1;

View File

@ -476,10 +476,15 @@ qLocation(string service) {
return v("locations")[service];
}
// returns 0 if that was just an update
// 1 on success
// returns 0 if that was just an update. 1 on success.
// this was originally used by sip/udp only, then slowly
// integrated into existing code
sLocation(string service, mixed data) {
ASSERT("sLocation", v("locations"), v("locations"))
// should this function also call register_location ?
// yes because a delivery error should remove clients
// from the location table, too.. not just proper
// unlink requests FIXME
if (v("locations")[service] == data) return 0;
unless (data) {
string retval = v("locations")[service];
@ -526,7 +531,8 @@ static linkSet(service, location, source) {
}
#endif
#ifdef NEW_UNLINK
static linkDel(service, source) {
static linkDel(service, source, variant) {
string mc = "_notice_unlink";
string candidate = v("locations")[service];
unless (candidate) {
P3(("linkDel(%O, %O) called in %O: no such candidate!\n",
@ -536,19 +542,42 @@ static linkDel(service, source) {
P1(("linkDel(%O, %O) called in %O: unlinking %O.\n",
service, source, ME, candidate));
unless (source) source = candidate;
// sLocation?
register_location(candidate, 0);
// maybe actual deletion would need to be delayed after
// letting locations know. they might still be sending
// stuff to us, right?
m_delete(v("locations"), service || 0);
if (service) sendmsg(source, "_notice_unlink_service", 0,
if (variant) mc += variant;
if (service) sendmsg(source, mc, 0,
([ "_service" : service,
"_location_service" : candidate,
"_identification" : v("_source") ]));
else sendmsg(source, "_notice_unlink", 0,
else sendmsg(source, mc, 0,
([ "_location" : candidate,
"_identification" : v("_source") ]));
return candidate;
}
#endif
static linkCleanUp(variant) {
mixed type, loc;
foreach (type, loc : v("locations")) {
P2(("linkCleanUp(%O) to %O's ex-%O-client %O\n",
variant, ME, type, loc))
#ifdef NEW_UNLINK
linkDel(type, 0, variant);
#else
// no clue if the UNL is still out there..
// lets send a ping so it can reconnect
// but first we have to delete it from our structures!
m_delete(v("locations"), 0);
sendmsg(loc, "_status_unlinked", 0, ([]));
#endif
}
}
// extend sName() from name.c
sName2(a) {
int e;
@ -615,7 +644,9 @@ sName2(a) {
availability = v("availability");
#endif // _flag_disable_module_presence
unless (v("locations")) vSet("locations", ([ ]));
if (v("locations")) linkCleanUp("_crash");
else vSet("locations", ([ ]));
// protection against file read errors
if (IS_NEWBIE) {
if (boss(a)) {
@ -630,7 +661,7 @@ sName2(a) {
destruct(ME);
return 0;
}
#ifndef RELAY
#ifdef _flag_enable_administrator_by_nick
else if (strstr(lower_case(a), "admin") != -1) {
this_player()->w("_failure_object_create_admin",
"This nickname is available to administrators only.");
@ -647,20 +678,6 @@ sName2(a) {
// maybe use v("identification") here?
vSet("_source", psyc_name(ME));
// TODO: needs to be foreached for all types of locations?
if (e = v("locations")[0]) {
#ifdef NEW_UNLINK
linkDel(0);
#else
P2(("sending _status_unlinked to ex-client %O\n", e))
// no clue if the UNL is still out there..
// lets send a ping so it can reconnect
// but first we have to delete it from our structures!
m_delete(v("locations"), 0);
sendmsg(e, "_status_unlinked", 0, ([]));
#endif
}
return MYNICK; // means new name accepted
}
@ -2640,9 +2657,12 @@ quit(immediate, variant) {
int rc;
P3(("person:QUIT(%O,%O) in %O\n", immediate,variant, ME))
#ifdef NEW_UNLINK
linkDel(0);
#endif
// keeping services running while logging out should be possible.. but
//linkDel(0);
if (v("locations")) {
linkCleanUp();
vDel("locations");
}
if (immediate == 1 || (immediate && find_call_out(#'quit) != -1)) {
rc = save();
if (sizeof(places)) {

View File

@ -10,7 +10,7 @@ qHasCurrentPlace() { return 0; }
logon() {
#ifdef NO_EXTERNAL_LOGINS
return destruct(ME);
return destruct(ME);
#endif
// psyc users dont have their own socket, so the driver
// does not call disconnected() for them - this enables the

View File

@ -896,19 +896,27 @@ case "_status_presence":
case "_notice_person_absent_netburp":
if (vars["_context"] != place) return 1;
break;
#if 1
case "_failure_unsuccessful_delivery":
case "_failure_network_connect_invalid_port":
// is this the right place to do this? i have seen a recursion where
// person.c was never asked for opinion, so i'm putting this into user.c
#ifdef ALPHA
string loc;
foreach (t, loc : v("locations"))
if (vars["_source_relay"] == loc) {
P1(("%O in %O talking to its %O location at %O.",
mc, ME, t, loc))
sLocation(t, 0);
}
#else
// TODO: walk thru entire locations mapping!
if (vars["_source_relay"] == v("locations")[0]) {
P0(("%O got %O, deleting 0 from %O\n", ME,
mc, v("locations")))
m_delete(v("locations"), 0);
P0(("%O got %O, deleting 0 from %O\n", ME,
mc, v("locations")))
m_delete(v("locations"), 0);
}
// fall thru - not strictly necessary but adds a feature
#endif
// fall thru - not strictly necessary but adds a feature
case "_failure_redirect_permanent":
// we currently have no implementation for permanent changes
case "_failure_redirect_temporary":
@ -1271,7 +1279,8 @@ w(string mc, string data, mapping vars, mixed source, int showingLog) {
if (!loc) {
// oh.. happens on beta?
P1(("%O late deletion of a %O zero location - should never happen\n", ME, type))
m_delete(v("locations"), type);
//m_delete(v("locations"), type);
sLocation(type, 0);
continue;
}
#endif