1
0
Fork 0
mirror of git://git.psyced.org/git/psyced synced 2024-08-15 03:25:10 +00:00

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

@ -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