From fc633a4f1fe8900b08fca8e9975b38fcfbd23808 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sat, 5 Feb 2011 11:09:37 +0100 Subject: [PATCH] Fix racy detection of ally rejecting flashes sendmessage() checked NF_FLASH on two places: when deciding whether to send the message, and later when telling the player why it didn't send a flash. This can race with the toggle command as follows: if a flash could not be sent because the recipient's NF_FLASH was off, and the recipient toggled it on before the flag was checked again, the flash command claimed the sender wasn't logged on. --- src/lib/commands/flash.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/lib/commands/flash.c b/src/lib/commands/flash.c index e07ea128b..87a1e605c 100644 --- a/src/lib/commands/flash.c +++ b/src/lib/commands/flash.c @@ -119,7 +119,7 @@ sendmessage(struct natstr *us, struct natstr *to, char *message, int verbose) struct player *other; struct tm *tm; time_t now; - int sent = 0; + int sent = 0, rejected = 0; struct natstr *wto; time(&now); @@ -127,16 +127,18 @@ sendmessage(struct natstr *us, struct natstr *to, char *message, int verbose) for (other = player_next(NULL); other; other = player_next(other)) { if (other->state != PS_PLAYING) continue; + if (player == other) + continue; if (to && other->cnum != to->nat_cnum) continue; if (!(wto = getnatp(other->cnum))) continue; if (!to && !player->god && getrel(wto, player->cnum) != ALLIED) continue; - if (!player->god && !(wto->nat_flags & NF_FLASH)) - continue; - if (player == other) + if (!player->god && !(wto->nat_flags & NF_FLASH)) { + rejected++; continue; + } if (verbose) if (to) pr_flash(other, "FLASH from %s (#%d) @ %02d:%02d%s\n", @@ -162,14 +164,13 @@ sendmessage(struct natstr *us, struct natstr *to, char *message, int verbose) else pr("No-one is logged in\n"); } - if (to && !player->god) { + if (to && !player->god && getrel(to, player->cnum) == ALLIED) { /* If they are allied with us, we would normally see that * they are logged in anyway, so just tell us */ - if ((getrel(to, player->cnum) == ALLIED) && !sent) { - if (to->nat_flags & NF_FLASH) - pr("%s is not logged on\n", to->nat_cnam); - else - pr("%s is not accepting flashes\n", to->nat_cnam); + if (rejected) + pr("%s is not accepting flashes\n", to->nat_cnam); + else if (!sent) { + pr("%s is not logged on\n", to->nat_cnam); } } return 0; -- 2.43.0