comparison rogue5/mach_dep.c @ 33:f502bf60e6e4

Import Rogue 5.4 from the Roguelike Restoration Project (r1490)
author elwin
date Mon, 24 May 2010 20:10:59 +0000
parents
children 655c317b6237
comparison
equal deleted inserted replaced
32:2dcd75e6a736 33:f502bf60e6e4
1 /*
2 * Various installation dependent routines
3 *
4 * @(#)mach_dep.c 4.37 (Berkeley) 05/23/83
5 *
6 * Rogue: Exploring the Dungeons of Doom
7 * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
8 * All rights reserved.
9 *
10 * See the file LICENSE.TXT for full copyright and licensing information.
11 */
12
13 /*
14 * The various tuneable defines are:
15 *
16 * SCOREFILE Where/if the score file should live.
17 * ALLSCORES Score file is top ten scores, not top ten
18 * players. This is only useful when only a few
19 * people will be playing; otherwise the score file
20 * gets hogged by just a few people.
21 * NUMSCORES Number of scores in the score file (default 10).
22 * NUMNAME String version of NUMSCORES (first character
23 * should be capitalized) (default "Ten").
24 * MAXLOAD What (if any) the maximum load average should be
25 * when people are playing. Since it is divided
26 * by 10, to specify a load limit of 4.0, MAXLOAD
27 * should be "40". If defined, then
28 * LOADAV Should it use it's own routine to get
29 * the load average?
30 * NAMELIST If so, where does the system namelist
31 * hide?
32 * MAXUSERS What (if any) the maximum user count should be
33 * when people are playing. If defined, then
34 * UCOUNT Should it use it's own routine to count
35 * users?
36 * UTMP If so, where does the user list hide?
37 * CHECKTIME How often/if it should check during the game
38 * for high load average.
39 */
40
41 #include <signal.h>
42 #include <sys/types.h>
43 #include <sys/stat.h>
44 #include <limits.h>
45 #include <string.h>
46 #include <fcntl.h>
47 #include <errno.h>
48 #include <time.h>
49 #include <curses.h>
50 #include "extern.h"
51
52 #define NOOP(x) (x += 0)
53
54 # ifndef NUMSCORES
55 # define NUMSCORES 10
56 # define NUMNAME "Ten"
57 # endif
58
59 #ifdef CHECKTIME
60 static int num_checks = 0; /* times we've gone over in checkout() */
61 #endif /* CHECKTIME */
62
63 /*
64 * init_check:
65 * Check out too see if it is proper to play the game now
66 */
67
68 void
69 init_check(void)
70 {
71 #if defined(MAXLOAD) || defined(MAXUSERS)
72 if (too_much())
73 {
74 printf("Sorry, %s, but the system is too loaded now.\n", whoami);
75 printf("Try again later. Meanwhile, why not enjoy a%s %s?\n",
76 vowelstr(fruit), fruit);
77 if (author())
78 printf("However, since you're a good guy, it's up to you\n");
79 else
80 exit(1);
81 }
82 #endif
83 }
84
85 /*
86 * open_score:
87 * Open up the score file for future use
88 */
89
90 void
91 open_score(void)
92 {
93 #ifdef SCOREFILE
94 char *scorefile = SCOREFILE;
95
96 numscores = NUMSCORES;
97 Numname = NUMNAME;
98
99 #ifdef ALLSCORES
100 allscore = TRUE;
101 #else /* ALLSCORES */
102 allscore = FALSE;
103 #endif /* ALLSCORES */
104
105 /*
106 * We drop setgid privileges after opening the score file, so subsequent
107 * open()'s will fail. Just reuse the earlier filehandle.
108 */
109
110 if (scoreboard != NULL) {
111 rewind(scoreboard);
112 return;
113 }
114
115 scoreboard = fopen(scorefile, "r+");
116
117 if ((scoreboard == NULL) && (errno == ENOENT))
118 {
119 scoreboard = fopen(scorefile, "w+");
120 md_chmod(scorefile,0664);
121 }
122
123 if (scoreboard == NULL) {
124 fprintf(stderr, "Could not open %s for writing: %s\n", scorefile, strerror(errno));
125 fflush(stderr);
126 }
127 #else
128 scoreboard = NULL;
129 #endif
130 }
131
132 /*
133 * getltchars:
134 * Get the local tty chars for later use
135 */
136
137 void
138 getltchars(void)
139 {
140 got_ltc = TRUE;
141 orig_dsusp = md_dsuspchar();
142 md_setdsuspchar( md_suspchar() );
143 }
144
145 /*
146 * setup:
147 * Get starting setup for all games
148 */
149
150 void
151 setup(void)
152 {
153 #ifdef DUMP
154 md_onsignal_autosave();
155 #else
156 md_onsignal_default();
157 #endif
158
159 #ifdef CHECKTIME
160 md_start_checkout_timer(CHECKTIME*60);
161 num_checks = 0;
162 #endif
163
164 raw(); /* Raw mode */
165 noecho(); /* Echo off */
166 keypad(stdscr,1);
167 getltchars(); /* get the local tty chars */
168 }
169
170 /*
171 * resetltchars:
172 * Reset the local tty chars to original values.
173 */
174 void
175 resetltchars(void)
176 {
177 if (got_ltc) {
178 md_setdsuspchar(orig_dsusp);
179 }
180 }
181
182 /*
183 * playltchars:
184 * Set local tty chars to the values we use when playing.
185 */
186 void
187 playltchars(void)
188 {
189 if (got_ltc) {
190 md_setdsuspchar( md_suspchar() );
191 }
192 }
193
194 /*
195 * start_score:
196 * Start the scoring sequence
197 */
198
199 void
200 start_score(void)
201 {
202 #ifdef CHECKTIME
203 md_stop_checkout_timer();
204 #endif
205 }
206
207 /*
208 * is_symlink:
209 * See if the file has a symbolic link
210 */
211 int
212 is_symlink(char *sp)
213 {
214 #ifdef S_IFLNK
215 struct stat sbuf2;
216
217 if (lstat(sp, &sbuf2) < 0)
218 return FALSE;
219 else
220 return ((sbuf2.st_mode & S_IFMT) != S_IFREG);
221 #else
222 NOOP(sp);
223 return FALSE;
224 #endif
225 }
226
227 #if defined(MAXLOAD) || defined(MAXUSERS)
228 /*
229 * too_much:
230 * See if the system is being used too much for this game
231 */
232 int
233 too_much(void)
234 {
235 #ifdef MAXLOAD
236 double avec[3];
237 #else
238 int cnt;
239 #endif
240
241 #ifdef MAXLOAD
242 md_loadav(avec);
243 if (avec[1] > (MAXLOAD / 10.0))
244 return TRUE;
245 #endif
246 #ifdef MAXUSERS
247 if (ucount() > MAXUSERS)
248 return TRUE;
249 #endif
250 return FALSE;
251 }
252
253 /*
254 * author:
255 * See if a user is an author of the program
256 */
257 int
258 author(void)
259 {
260 #ifdef MASTER
261 if (wizard)
262 return TRUE;
263 #endif
264 switch (md_getuid())
265 {
266 case -1:
267 return TRUE;
268 default:
269 return FALSE;
270 }
271 }
272 #endif
273
274 #ifdef CHECKTIME
275 /*
276 * checkout:
277 * Check each CHECKTIME seconds to see if the load is too high
278 */
279
280 checkout(int sig)
281 {
282 char *msgs[] = {
283 "The load is too high to be playing. Please leave in %0.1f minutes",
284 "Please save your game. You have %0.1f minutes",
285 "Last warning. You have %0.1f minutes to leave",
286 };
287 int checktime;
288
289 if (too_much())
290 {
291 if (author())
292 {
293 num_checks = 1;
294 chmsg("The load is rather high, O exaulted one");
295 }
296 else if (num_checks++ == 3)
297 fatal("Sorry. You took too long. You are dead\n");
298 checktime = (CHECKTIME * 60) / num_checks;
299 chmsg(msgs[num_checks - 1], ((double) checktime / 60.0));
300 }
301 else
302 {
303 if (num_checks)
304 {
305 num_checks = 0;
306 chmsg("The load has dropped back down. You have a reprieve");
307 }
308 checktime = (CHECKTIME * 60);
309 }
310
311 md_start_checkout_timer(checktime);
312 }
313
314 /*
315 * chmsg:
316 * checkout()'s version of msg. If we are in the middle of a
317 * shell, do a printf instead of a msg to a the refresh.
318 */
319 /* VARARGS1 */
320
321 chmsg(char *fmt, int arg)
322 {
323 if (!in_shell)
324 msg(fmt, arg);
325 else
326 {
327 printf(fmt, arg);
328 putchar('\n');
329 fflush(stdout);
330 }
331 }
332 #endif
333
334 #ifdef UCOUNT
335 /*
336 * ucount:
337 * count number of users on the system
338 */
339 #include <utmp.h>
340
341 struct utmp buf;
342
343 int
344 ucount(void)
345 {
346 struct utmp *up;
347 FILE *utmp;
348 int count;
349
350 if ((utmp = fopen(UTMP, "r")) == NULL)
351 return 0;
352
353 up = &buf;
354 count = 0;
355
356 while (fread(up, 1, sizeof (*up), utmp) > 0)
357 if (buf.ut_name[0] != '\0')
358 count++;
359 fclose(utmp);
360 return count;
361 }
362 #endif
363
364 /*
365 * lock_sc:
366 * lock the score file. If it takes too long, ask the user if
367 * they care to wait. Return TRUE if the lock is successful.
368 */
369 static FILE *lfd = NULL;
370 int
371 lock_sc(void)
372 {
373 #if defined(SCOREFILE) && defined(LOCKFILE)
374 int cnt;
375 struct stat sbuf;
376 char *lockfile = LOCKFILE;
377
378 over:
379 if ((lfd=fopen(lockfile, "w+")) != NULL)
380 return TRUE;
381 for (cnt = 0; cnt < 5; cnt++)
382 {
383 md_sleep(1);
384 if ((lfd=fopen(lockfile, "w+")) != NULL)
385 return TRUE;
386 }
387 if (stat(lockfile, &sbuf) < 0)
388 {
389 lfd=fopen(lockfile, "w+");
390 return TRUE;
391 }