X-Git-Url: http://git.pond.sub.org/?p=empserver;a=blobdiff_plain;f=src%2Flib%2Fsubs%2Fwu.c;h=6bcaf0009bffe8d415ad86c5e61fa88a34c5c43e;hp=b92e74c3b981172159e1309bc24ae959997ec9b8;hb=e23882161e21b6e14dc9283933967d344f231954;hpb=71e164ed30d504bbc7e8f3caa8eea84e7ecdcf77 diff --git a/src/lib/subs/wu.c b/src/lib/subs/wu.c index b92e74c3b..6bcaf0009 100644 --- a/src/lib/subs/wu.c +++ b/src/lib/subs/wu.c @@ -1,11 +1,11 @@ /* * Empire - A multi-player, client/server Internet based war game. - * Copyright (C) 1986-2005, Dave Pare, Jeff Bailey, Thomas Ruschak, - * Ken Stevens, Steve McClure + * Copyright (C) 1986-2021, Dave Pare, Jeff Bailey, Thomas Ruschak, + * Ken Stevens, Steve McClure, Markus Armbruster * - * This program is free software; you can redistribute it and/or modify + * Empire is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, @@ -14,76 +14,63 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * along with this program. If not, see . * * --- * - * See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the - * related information and legal notices. It is expected that any future - * projects/authors will amend these files as needed. + * See files README, COPYING and CREDITS in the root of the source + * tree for related information and legal notices. It is expected + * that future projects/authors will amend these files as needed. * * --- * * wu.c: Write a telegram to a user from another - * + * * Known contributors to this file: * Steve McClure, 2000 - * + * Markus Armbruster, 2005-2021 */ -#include -#include "misc.h" +#include + #include -#if !defined(_WIN32) +#include #include -#endif +#include +#include "misc.h" #include "nat.h" -#include "tel.h" -#include "file.h" -#include "player.h" -#include "server.h" #include "optlist.h" #include "prototypes.h" +#include "tel.h" +#include "update.h" static struct telstr last_tel[MAXNOC]; void clear_telegram_is_new(natid to) { - last_tel[to].tel_type = 0; - last_tel[to].tel_from = 0; - last_tel[to].tel_date = 0; + last_tel[to].tel_from = NATID_BAD; } -/* - * telegram_is_new counts new telegrams the same as read_telegrams in - * lib/commands/mail.c and lib/commands/rea.c - */ - static int telegram_is_new(natid to, struct telstr *tel) { - int is_new = 0; - - is_new |= tel->tel_type != last_tel[to].tel_type; - is_new |= tel->tel_from != last_tel[to].tel_from; - is_new |= !update_pending && /* sometimes updates take a long time */ - abs(tel->tel_date - last_tel[to].tel_date) > TEL_SECONDS; - - last_tel[to].tel_type = tel->tel_type; - last_tel[to].tel_from = tel->tel_from; - last_tel[to].tel_date = tel->tel_date; - - return is_new; + if (tel->tel_from != last_tel[to].tel_from + || tel->tel_type != last_tel[to].tel_type + || (tel->tel_type != TEL_UPDATE + && tel->tel_date - last_tel[to].tel_date > TEL_SECONDS)) { + last_tel[to] = *tel; + return 1; + } + return 0; } /* - * Send a telegram from FROM to TO. - * Format text to send using printf-style FORMAT and optional + * Send a telegram from @from to @to. + * Format text to send using printf-style @format and optional * arguments. It is plain ASCII. * If running from the update, telegram type is TEL_UPDATE. - * Else if FROM is a deity, type is TEL_BULLETIN. + * Else if @from is a deity, type is TEL_BULLETIN. * Else it is TEL_NORM. * Return 0 on success, -1 on error. */ @@ -98,109 +85,97 @@ wu(natid from, natid to, char *format, ...) (void)vsprintf(buf, format, ap); va_end(ap); np = getnatp(from); - if (update_pending) + if (update_running) return typed_wu(from, to, buf, TEL_UPDATE); - else if (np->nat_stat & STAT_GOD) + else if (np->nat_stat == STAT_GOD) return typed_wu(from, to, buf, TEL_BULLETIN); else return typed_wu(from, to, buf, TEL_NORM); } /* - * Send a telegram from FROM to TO. - * MESSAGE is the text to send, in UTF-8. - * TYPE is the telegram type. + * Send a telegram from @from to @to. + * @message is the text to send, in UTF-8. + * @type is the telegram type. * Return 0 on success, -1 on error. */ int typed_wu(natid from, natid to, char *message, int type) { - int len; + size_t len; struct telstr tel; struct natstr *np; -#if !defined(_WIN32) struct iovec iov[2]; -#endif int fd; char box[1024]; - int notify = 0; - int write_ok = 0; - int new_tele = 0; struct player *other; - if (type == TEL_ANNOUNCE) + if (type == TEL_ANNOUNCE) { strcpy(box, annfil); - else + np = NULL; + } else { mailbox(box, to); - - if (type != TEL_ANNOUNCE) - if ((np = getnatp(to)) == 0 || - ((np->nat_stat & STAT_NORM) == 0 && - (np->nat_stat & STAT_SANCT) == 0)) { + np = getnatp(to); + if (!np || np->nat_stat < STAT_SANCT) return -1; - } + } + #if !defined(_WIN32) if ((fd = open(box, O_WRONLY | O_APPEND, 0)) < 0) { #else if ((fd = open(box, O_WRONLY | O_APPEND | O_BINARY, 0)) < 0) { #endif - logerror("telegram 'open' of %s (#%d) failed", box, to); + logerror("telegram 'open' of %s failed", box); return -1; } + + memset(&tel, 0, sizeof(tel)); tel.tel_from = from; (void)time(&tel.tel_date); len = strlen(message); - if (CANT_HAPPEN(len > MAXTELSIZE)) { - len = MAXTELSIZE; - message[len] = 0; - } + CANT_HAPPEN(len && message[len - 1] != '\n'); tel.tel_length = len; tel.tel_type = type; -#if !defined(_WIN32) + tel.tel_cont = !telegram_is_new(to, &tel); iov[0].iov_base = &tel; iov[0].iov_len = sizeof(tel); iov[1].iov_base = message; iov[1].iov_len = len; if (writev(fd, iov, 2) < (int)(iov[0].iov_len + iov[1].iov_len)) { -#else - if ((write(fd, &tel, sizeof(tel)) != sizeof(tel)) || - (write(fd, message, len) != len)) { -#endif - logerror("telegram 'write' to #%d failed", to); - } else - write_ok = 1; + logerror("telegram 'write' to %s failed", box); + close(fd); + return -1; + } + if (close(fd) < 0) { + logerror("telegram 'write' to %s failed to close.", box); + return -1; + } - if (close(fd) == -1) { - logerror("telegram 'write' to #%d failed to close.", to); - } else if (write_ok && type == TEL_ANNOUNCE) { + if (type == TEL_ANNOUNCE) { for (to = 0; NULL != (np = getnatp(to)); to++) { - if (!(np->nat_stat & STAT_NORM) && - !(np->nat_stat & STAT_SANCT)) + if (np->nat_stat < STAT_SANCT) continue; - if (!player->god && (getrejects(from, np) & REJ_ANNO)) + if (!nat_accepts(to, from, REJ_ANNO)) continue; - notify = (np->nat_ann == 0); - np->nat_ann++; - putnat(np); - if (notify) - player_wakeup_all(to); + if (!np->nat_ann || !tel.tel_cont) { + np->nat_ann++; + putnat(np); + } } - } else if (write_ok) { - notify = (np->nat_tgms == 0); - new_tele = telegram_is_new(to, &tel); - np->nat_tgms += new_tele || notify; - putnat(np); - - if (new_tele && np->nat_flags & NF_INFORM) { - if (NULL != (other = getplayer(to))) { - if (np->nat_tgms == 1) - pr_inform(other, "[new tele]\n"); - else - pr_inform(other, "[%d new teles]\n", np->nat_tgms); - player_wakeup_all(to); + } else { + if (!np->nat_tgms || !tel.tel_cont) { + np->nat_tgms++; + putnat(np); + if (np->nat_flags & NF_INFORM) { + other = getplayer(to); + if (other) { + if (np->nat_tgms == 1) + pr_inform(other, "[new tele]\n"); + else + pr_inform(other, "[%d new teles]\n", np->nat_tgms); + } } - } else if (notify) - player_wakeup_all(to); + } } return 0;