]> git.pond.sub.org Git - empserver/blob - src/lib/commands/rea.c
Import of Empire 4.2.12
[empserver] / src / lib / commands / rea.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2000, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                           Ken Stevens, Steve McClure
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  *  ---
21  *
22  *  See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
23  *  related information and legal notices. It is expected that any future
24  *  projects/authors will amend these files as needed.
25  *
26  *  ---
27  *
28  *  rea.c: Read telegrams
29  * 
30  *  Known contributors to this file:
31  *     Dave Pare
32  *     Doug Hay, 1998
33  *     Steve McClure, 1998-2000
34  */
35
36
37 #ifdef aix
38 #define L_SET 0
39 #endif /* aix */
40
41 #include "misc.h"
42 #include "player.h"
43 #include "nat.h"
44 #include "file.h"
45 #include "tel.h"
46 #include "deity.h"
47 #include "commands.h"
48
49 #include <stdio.h>
50 #include <fcntl.h>
51 #if !defined(_WIN32)
52 #include <sys/file.h>
53 #endif
54
55 int
56 rea(void)
57 {
58         extern  s_char *telnames[];
59         register s_char *p;
60         register s_char *mbox;
61         s_char mbox_buf[256]; /* Maximum path length */
62         struct  telstr tgm;
63         FILE   *telfp;
64         int     teles;
65         int     size;
66         unsigned int     nbytes;
67         s_char    buf[4096];
68         int     lasttype;
69         int     lastcnum;
70         time_t  lastdate;
71         int     header;
72         int     filelen;
73         s_char  kind[80];
74         int     n;
75         int     num = player->cnum;
76         struct natstr *np = getnatp(player->cnum);
77         time_t  now;    
78         time_t  then;
79         time_t  delta;
80         int     first = 1;
81         int     readit;
82
83         bzero(kind,80);
84         (void) time(&now);
85
86         if (*player->argp[0] == 'w') {
87                 sprintf(kind,"announcement");
88                 if (player->argp[1] && isdigit(*player->argp[1])) {
89                         delta = days(atoi(player->argp[1]));
90                         then = now - delta;
91                 } else
92                         then = np->nat_annotim;
93                 mbox = annfil;
94         } else {
95                 sprintf(kind,"telegram");
96                 if (player->god && player->argp[1] != 0) {
97                         if ((n = natarg(player->argp[1], "")) < 0)
98                                 return RET_SYN;
99                         num = n;
100                 }
101                 mbox = mailbox(mbox_buf, num);
102                 clear_telegram_is_new(player->cnum);
103         }
104         
105 #if !defined(_WIN32)
106         if ((telfp = fopen(mbox, "r+")) == 0) {
107 #else
108         if ((telfp = fopen(mbox, "r+b")) == 0) {
109 #endif
110                 logerror("telegram file %s", mbox);
111                 return RET_FAIL;
112         }
113         teles = 0;
114         fseek(telfp, 0L, 0);
115         size = fsize(fileno(telfp));
116 more:
117         lastdate = 0;
118         lastcnum = -1;
119         lasttype = -1;
120         while (fread((s_char *) &tgm, sizeof(tgm), 1, telfp) == 1) {
121                 readit = 1;
122                 if (tgm.tel_length < 0) {
123                         logerror("bad telegram file header in %s", mbox);
124                         break;
125                 }
126                 if (tgm.tel_type < 0 || tgm.tel_type > TEL_LAST) {
127                         pr("Bad telegram header.  Skipping telegram...\n");
128                         readit = 0;
129                         goto skip;
130                 }
131                 if (*kind == 'a') {
132                         if (!player->god &&
133                             (getrejects(tgm.tel_from, np) & REJ_ANNO)) {
134                                 readit = 0;
135                                 goto skip;
136                         }
137                         if (tgm.tel_date < then) {
138                                 readit = 0;
139                                 goto skip;
140                         }
141                 }
142                 if (first && *kind == 'a') {
143                         pr("\nAnnouncements since %s", ctime(&then));
144                         first = 0;
145                 }
146                 header = 0;
147                 if (tgm.tel_type != lasttype || tgm.tel_from != lastcnum)
148                         header++;
149                 if (abs((int)(tgm.tel_date - (long)lastdate)) > TEL_SECONDS)
150                         header++;
151                 if (header) {
152                         pr("\n> ");
153                         lastcnum = tgm.tel_from;
154                         lasttype = tgm.tel_type;
155                         pr("%s ", telnames[(int)tgm.tel_type]);
156                         if ((tgm.tel_type == TEL_NORM) ||
157                             (tgm.tel_type == TEL_ANNOUNCE)) {
158                                 pr("from %s, (#%d)",
159                                        cname(tgm.tel_from),
160                                        tgm.tel_from);
161                         }
162                         if (tgm.tel_type == TEL_BULLETIN){
163                                 pr("from %s, (#%d)", cname(tgm.tel_from), tgm.tel_from);
164                         }
165                         pr("  dated %s", ctime(&tgm.tel_date));
166                         lastdate = tgm.tel_date;
167                 }
168                 teles++;
169         skip:
170                 while (tgm.tel_length > 0) {
171                         nbytes = tgm.tel_length;
172                         if (nbytes > sizeof(buf)-1)
173                                 nbytes = sizeof(buf)-1;
174                         (void) fread(buf, sizeof(s_char), nbytes, telfp);
175                         buf[nbytes] = 0;
176                         if (readit)
177                                 prnf(buf);
178                         tgm.tel_length -= nbytes;
179                 }
180         }
181         p=NULL;
182         if (teles > 0 && player->cnum == num) { /* } */
183                 pr("\n");
184                 if (teles == 1) {
185                         if (chance(0.25))
186                                 p = "Forget this one? ";
187                         else
188                                 p = "Shall I burn it? ";
189                 } else {
190                         if (chance(0.25))
191                                 p = "Into the shredder, boss? ";
192                         else
193                                 p = "Can I throw away these old love letters? ";
194                 }
195                 if (player->god && *kind == 't')
196                         p = getstarg(player->argp[2], p, buf);
197                 else
198                         p = getstarg(player->argp[1], p, buf);
199                 if (p && *p == 'y') {
200                         if ((filelen = fsize(fileno(telfp))) > size) {
201                                 pr("Wait a sec!  A new %s has arrived...\n", kind);
202                                 /* force stdio to re-read tel file */
203                                 (void) fflush(telfp);
204 #if !defined(_WIN32)
205                                 (void) fseek(telfp, (long)size, L_SET);
206 #else
207                                 (void) fseek(telfp, (long)size, SEEK_SET);
208 #endif
209                                 size = filelen;
210                                 (void) time(&now);
211                                 goto more;
212                         }
213                         if (*kind == 'a') {
214                                 np->nat_annotim = now;
215                                 putnat(np);
216                         } else {
217                           /* Here, we just re-open the file for "w" only,
218                              and that will wipe the file clean automatically */
219                           (void)fclose(telfp);
220 #if !defined(_WIN32)
221                           telfp = fopen((char *)mbox, "w");
222 #else
223                           telfp = fopen((char *)mbox, "wb");
224 #endif
225                         }
226                 }
227         }
228         if (teles <= 0) {
229                 if(player->cnum == num)
230                         pr("No %ss for you at the moment...\n",kind);
231                 else
232                         pr("No %ss for %s at the moment...\n", kind,
233                                cname(num));
234         }
235         (void) fclose(telfp);
236         if (np->nat_flags & NF_INFORM) {
237                 pr_inform(player, "\n");
238                 np->nat_tgms = 0;
239                 putnat(np);
240         }
241         return RET_OK;
242 }
243