]> git.pond.sub.org Git - empserver/blob - src/lib/common/wantupd.c
Declare all configuration parameters in optlist.h. Remove some
[empserver] / src / lib / common / wantupd.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  *  wantupd.c: Check to se if an update is wanted and/or allowed.
29  * 
30  *  Known contributors to this file:
31  *     Doug Hay, 1990
32  */
33
34 #include <stdio.h>
35 #if !defined(_WIN32)
36 #include <unistd.h>
37 #endif
38 #include "misc.h"
39 #include "nat.h"
40 #include "file.h"
41 #include "keyword.h"
42 #include "wantupd.h"
43 #include "optlist.h"
44 #include "common.h"
45
46 #include <sys/types.h>
47 #include <fcntl.h>
48 #include <time.h>
49
50 void
51 update_policy_check(void)
52 {
53     if (update_policy < 0)
54         update_policy = UDP_DEFAULT;
55     if (update_policy > UDP_MAX)
56         update_policy = UDP_DEFAULT;
57     if (update_demandpolicy < 0)
58         update_demandpolicy = UDDEM_DEFAULT;
59     if (update_demandpolicy > UDDEM_MAX)
60         update_demandpolicy = UDDEM_DEFAULT;
61     if (update_wantmin < 0)
62         update_wantmin = 0;
63     if (update_wantmin > MAXNOC)
64         update_wantmin = MAXNOC;
65     if (blitz_time < 0)
66         blitz_time = 0;
67 }
68
69 static int
70 demand_update_time(time_t * now)
71 {
72     struct tm *tm;
73     s_char *p;
74     int curtime;
75     int hour[2];
76
77     tm = localtime(now);
78     curtime = tm->tm_min + tm->tm_hour * 60;
79     p = update_demandtimes;
80     if (*p == 0)
81         return (1);
82     while (NULL != (p = kw_parse(CF_TIMERANGE, p, &hour[0]))) {
83         if (curtime >= hour[0] && curtime < hour[1])
84             return (1);
85     }
86     return (0);
87 }
88
89 /* When is the next regularly scheduled update from now. */
90 static void
91 regular_update_time(time_t * now, time_t * tim, time_t * delta)
92 {
93     s_char *p;
94     time_t tw;
95     int secs_per_update;
96
97     tw = *now + adj_update;
98     secs_per_update = etu_per_update * s_p_etu;
99     *delta = secs_per_update - (tw % secs_per_update);
100     *tim = *now + *delta;
101 }
102
103 /* Is this a valid time for a scheduled update. */
104 static int
105 scheduled_update_time(time_t * now, int *which)
106 {
107     struct tm *tm;
108     s_char *p, *p1;
109     int curtime;
110     int hour;
111
112     *which = -1;
113     p = update_times;
114     if (*p == 0)
115         return (0);
116
117     tm = localtime(now);
118     curtime = tm->tm_min + tm->tm_hour * 60;
119     while (NULL != (p = kw_parse(CF_TIME, p, &hour))) {
120         (*which)++;
121         if (curtime >= hour && curtime < hour + hourslop)
122             return (1);
123     }
124
125     return 0;
126 }
127
128 static int
129 next_scheduled_time(time_t * now, time_t * tim, time_t * delta)
130 {
131     struct tm *tm;
132     s_char *p;
133     int curtime;
134     int hour;
135     int mintime;
136
137     p = update_times;
138     if (*p == 0)
139         return (0);
140
141     tm = localtime(now);
142     curtime = tm->tm_min + tm->tm_hour * 60;    /* now - in minutes */
143     mintime = curtime + 24 * 60 + 1;    /* start with now + 1 day */
144     while (NULL != (p = kw_parse(CF_TIME, p, &hour))) {
145         if (hour <= curtime)
146             hour += 24 * 60;    /* this must be tomorrow */
147         if (hour < mintime)
148             mintime = hour;     /* this is best bet so far */
149     }
150     *delta = 60 * (mintime - curtime);
151     *tim = *now + *delta - tm->tm_sec;
152     return (1);
153 }
154
155 int
156 demand_update_want(int *want, int *pop, int which)
157 {
158     natid cn;
159     struct natstr *natp;
160     int totpop;
161     int totwant;
162     int whichwants;
163
164     whichwants = totpop = totwant = 0;
165     for (cn = 1; 0 != (natp = getnatp(cn)); cn++) {
166         /* Only countries which are normal. */
167         /* Should probably include sanctuaries ..... */
168         if (((natp->nat_stat & NORM) == NORM) &&
169             ((natp->nat_stat & GOD) != GOD)) {
170             totpop++;
171             if ((natp->nat_update & WUPD_WANT) == WUPD_WANT) {
172                 totwant++;
173                 if (which == cn)
174                     whichwants++;
175             }
176         }
177     }
178     *want = totwant;
179     *pop = totpop;
180     return (whichwants);
181 }
182
183 static int
184 demand_check(void)
185 {
186     struct natstr *natp;
187     int want, pop, cn, veto;
188     time_t now;
189     time_t cur;
190
191     time(&cur);
192
193 /*
194         if (last_demand_update == 0){
195                 natp=getnatp(0);
196                 last_demand_update = natp->nat_reserve;
197         }
198
199         logerror("last_demand_update = %d\n",last_demand_update);
200         logerror("update_between = %d\n",update_between());
201         logerror("now = %d\n",cur);
202         diff = (cur-(last_demand_update + update_between()));
203         logerror("diff = %d\n",diff);
204         if (diff >= 0){
205                 logerror("Forced update!\n");
206                 last_demand_update = cur;
207                 for (cn = 1; natp = getnatp(cn); cn++){
208                         if (((natp->nat_stat & NORM) == NORM)  &&
209                                 ((natp->nat_stat & GOD) != GOD)){
210                                 natp->nat_missed = 0;
211                         }
212                 }
213                 return(1);
214         }
215
216         logerror("No forced update!\n");
217 */
218     if (0 == update_wantmin) {
219         logerror("no demand update allowed, wantmin = 0");
220         return (0);
221     }
222
223     demand_update_want(&want, &pop, 0);
224     if (want < update_wantmin) {
225         logerror("no demand update, want = %d, min = %d",
226                  want, update_wantmin);
227         return (0);
228     }
229
230     time(&now);
231     if (!demand_update_time(&now)) {
232         logerror("no demand update, not within hours allowed.");
233         return (0);
234     }
235
236
237     veto = 0;
238     for (cn = 1; 0 != (natp = getnatp(cn)); cn++) {
239         if (((natp->nat_stat & NORM) == NORM) &&
240             ((natp->nat_stat & GOD) != GOD)) {
241             if (natp->nat_missed >= update_missed)
242                 veto = cn + 1;
243         }
244     }
245
246     if (veto) {
247         logerror("no demand update, %d has missed more than %d updates",
248                  veto - 1, update_missed);
249         return (0);
250     }
251
252     last_demand_update = cur;
253     natp = getnatp(0);
254     /* A dumb way to do it, but simple */
255     last_demand_update = natp->nat_reserve;
256     return (1);
257 }
258
259 /* Check if enough countries want an update,
260  * and if demand updates are allowed now.
261  */
262 int
263 demandupdatecheck(void)
264 {
265     if (UDDEM_COMSET != update_demandpolicy) {
266         logerror("no demand update, not policy.");
267         return (0);
268     }
269
270     return (demand_check());
271 }
272
273 /* Is it time for a regular or scheduled update?
274  * As well, if none of the above, check to see if
275  * a demand update can occur.
276  */
277 int
278 updatetime(time_t * now)
279 {
280     int which;
281
282     if (opt_BLITZ && update_policy == UDP_BLITZ) {
283         logerror("BLITZ Update.");
284         return (1);
285     }
286
287     if (UDP_NORMAL == update_policy) {
288         logerror("Regular update, etu type.");
289         return (1);
290     }
291
292     if (UDP_TIMES == update_policy) {
293         if (scheduled_update_time(now, &which)) {
294             logerror("Scheduled update, %d.", which);
295             return (1);
296         }
297     }
298     if (opt_DEMANDUPDATE) {
299         if (demand_check()) {
300             logerror("Demand update, at check time.");
301             return (1);
302         }
303     }
304     return (0);
305 }
306
307 /* Return the time, and delta seconds, of the next update.
308  * If the policy is no regular updates, return the time of
309  * the next possible check.
310  */
311 void
312 next_update_time(time_t * now, time_t * tim, time_t * delta)
313                         /* From when */
314                         /* Time of next update */
315                         /* Seconds till next update */
316 {
317     time_t stim, sdelta;
318
319     switch (update_policy) {
320     case UDP_NORMAL:
321         regular_update_time(now, tim, delta);
322         break;
323     case UDP_TIMES:
324         if (!next_scheduled_time(now, tim, delta))
325             regular_update_time(now, tim, delta);
326         break;
327     case UDP_BLITZ:
328         *delta = (blitz_time * 60) - (*now % (blitz_time * 60));
329         *tim = *now + *delta;
330         break;
331
332     case UDP_NOREG:
333     default:
334         regular_update_time(now, tim, delta);
335         if (next_scheduled_time(now, &stim, &sdelta)) {
336             if (*delta > sdelta) {
337                 *delta = sdelta;
338                 *tim = stim;
339             }
340         }
341         break;
342     }
343 }
344
345 void
346 next_update_check_time(time_t * now, time_t * tim, time_t * delta)
347                         /* From when */
348                         /* Time of next update */
349                         /* Seconds till next update check */
350 {
351     time_t stim, sdelta;
352
353     switch (update_policy) {
354     case UDP_NORMAL:
355         regular_update_time(now, tim, delta);
356         break;
357     case UDP_BLITZ:
358         *delta = (blitz_time * 60) - (*now % (blitz_time * 60));
359         *tim = *now + *delta;
360         break;
361     case UDP_TIMES:
362     case UDP_NOREG:
363     default:
364         regular_update_time(now, tim, delta);
365         if (next_scheduled_time(now, &stim, &sdelta)) {
366             if (*delta > sdelta) {
367                 *delta = sdelta;
368                 *tim = stim;
369             }
370         }
371     }
372 }
373
374 int
375 updates_disabled(void)
376 {
377     int fd;
378
379     if ((fd = open(disablefil, O_RDONLY, 0)) < 0)
380         return 0;
381     close(fd);
382     return 1;
383 }