00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <config.h>
00035
00036 #include <fcntl.h>
00037 #include <stdarg.h>
00038 #include <sys/uio.h>
00039 #include <unistd.h>
00040 #include "file.h"
00041 #include "misc.h"
00042 #include "nat.h"
00043 #include "optlist.h"
00044 #include "player.h"
00045 #include "prototypes.h"
00046 #include "server.h"
00047 #include "tel.h"
00048
00049 static struct telstr last_tel[MAXNOC];
00050
00051 void
00052 clear_telegram_is_new(natid to)
00053 {
00054 last_tel[to].tel_type = 0;
00055 last_tel[to].tel_from = 0;
00056 last_tel[to].tel_date = 0;
00057 }
00058
00059
00060
00061
00062
00063
00064 static int
00065 telegram_is_new(natid to, struct telstr *tel)
00066 {
00067 int is_new = 0;
00068
00069 is_new |= tel->tel_type != last_tel[to].tel_type;
00070 is_new |= tel->tel_from != last_tel[to].tel_from;
00071 is_new |= !update_running &&
00072 abs(tel->tel_date - last_tel[to].tel_date) > TEL_SECONDS;
00073
00074 last_tel[to].tel_type = tel->tel_type;
00075 last_tel[to].tel_from = tel->tel_from;
00076 last_tel[to].tel_date = tel->tel_date;
00077
00078 return is_new;
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 int
00091 wu(natid from, natid to, char *format, ...)
00092 {
00093 struct natstr *np;
00094 va_list ap;
00095 char buf[4096];
00096
00097 va_start(ap, format);
00098 (void)vsprintf(buf, format, ap);
00099 va_end(ap);
00100 np = getnatp(from);
00101 if (update_running)
00102 return typed_wu(from, to, buf, TEL_UPDATE);
00103 else if (np->nat_stat == STAT_GOD)
00104 return typed_wu(from, to, buf, TEL_BULLETIN);
00105 else
00106 return typed_wu(from, to, buf, TEL_NORM);
00107 }
00108
00109
00110
00111
00112
00113
00114
00115 int
00116 typed_wu(natid from, natid to, char *message, int type)
00117 {
00118 int len;
00119 struct telstr tel;
00120 struct natstr *np;
00121 struct iovec iov[2];
00122 int fd;
00123 char box[1024];
00124 int write_ok = 0;
00125 int new_tele = 0;
00126 struct player *other;
00127
00128 if (type == TEL_ANNOUNCE)
00129 strcpy(box, annfil);
00130 else
00131 mailbox(box, to);
00132
00133 if (type != TEL_ANNOUNCE)
00134 if ((np = getnatp(to)) == 0 || np->nat_stat < STAT_SANCT)
00135 return -1;
00136 #if !defined(_WIN32)
00137 if ((fd = open(box, O_WRONLY | O_APPEND, 0)) < 0) {
00138 #else
00139 if ((fd = open(box, O_WRONLY | O_APPEND | O_BINARY, 0)) < 0) {
00140 #endif
00141 logerror("telegram 'open' of %s (#%d) failed", box, to);
00142 return -1;
00143 }
00144 tel.tel_from = from;
00145 (void)time(&tel.tel_date);
00146 len = strlen(message);
00147 if (CANT_HAPPEN(len > MAXTELSIZE)) {
00148 len = MAXTELSIZE;
00149 message[len] = 0;
00150 }
00151 tel.tel_length = len;
00152 tel.tel_type = type;
00153 iov[0].iov_base = &tel;
00154 iov[0].iov_len = sizeof(tel);
00155 iov[1].iov_base = message;
00156 iov[1].iov_len = len;
00157 if (writev(fd, iov, 2) < (int)(iov[0].iov_len + iov[1].iov_len)) {
00158 logerror("telegram 'write' to #%d failed", to);
00159 } else
00160 write_ok = 1;
00161
00162 if (close(fd) == -1) {
00163 logerror("telegram 'write' to #%d failed to close.", to);
00164 } else if (write_ok && type == TEL_ANNOUNCE) {
00165 for (to = 0; NULL != (np = getnatp(to)); to++) {
00166 if (np->nat_stat < STAT_SANCT)
00167 continue;
00168 if (!player->god && (getrejects(from, np) & REJ_ANNO))
00169 continue;
00170 np->nat_ann++;
00171 putnat(np);
00172 }
00173 } else if (write_ok) {
00174 new_tele = telegram_is_new(to, &tel);
00175 np->nat_tgms += new_tele || np->nat_tgms == 0;
00176 putnat(np);
00177
00178 if (new_tele && np->nat_flags & NF_INFORM) {
00179 if (NULL != (other = getplayer(to))) {
00180 if (np->nat_tgms == 1)
00181 pr_inform(other, "[new tele]\n");
00182 else
00183 pr_inform(other, "[%d new teles]\n", np->nat_tgms);
00184 }
00185 }
00186 }
00187
00188 return 0;
00189 }