]> git.pond.sub.org Git - empserver/commitdiff
Fix racy detection of ally rejecting flashes
authorMarkus Armbruster <armbru@pond.sub.org>
Sat, 5 Feb 2011 10:09:37 +0000 (11:09 +0100)
committerMarkus Armbruster <armbru@pond.sub.org>
Sun, 13 Feb 2011 15:06:23 +0000 (16:06 +0100)
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

index e07ea128b8fdf3c1296707486d729082be9bfe96..87a1e605c5ab0b3f965355c15428f08746293ee5 100644 (file)
@@ -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;