comparison rogue4/mach_dep.c @ 12:9535a08ddc39

Import Rogue 5.2 from the Roguelike Restoration Project (r1490)
author edwarj4
date Sat, 24 Oct 2009 16:52:52 +0000
parents
children 63b9fd7d70ce
comparison
equal deleted inserted replaced
11:949d558c2162 12:9535a08ddc39
1 /*
2 * Various installation dependent routines
3 *
4 * @(#)mach_dep.c 4.23 (Berkeley) 5/19/82
5 *
6 * Rogue: Exploring the Dungeons of Doom
7 * Copyright (C) 1980, 1981, 1982 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 * MAXLOAD What (if any) the maximum load average should be
18 * when people are playing. If defined, then
19 * LOADAV Should rogue define it's own routine to
20 * get the load average?
21 * NAMELIST If so, where does the system namelist hide?
22 * MAXUSERS What (if any) the maximum user count should be
23 * when people are playing. If defined, then
24 * UCOUNT Should rogue define it's own routine to
25 * count users?
26 * UTMP If so, where does the user list hide?
27 * CHECKTIME How often/if rogue should check during the game
28 * for high load average.
29 */
30
31 #include <limits.h>
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <curses.h>
35 #include <time.h>
36 #include <signal.h>
37 #include <sys/stat.h>
38 #include <fcntl.h>
39 #include <string.h>
40 #include "rogue.h"
41
42 int num_checks; /* times we've gone over in checkout() */
43
44 #ifdef SCOREFILE
45 #ifdef LOCKFILE
46 static char *lockfile = LOCKFILE;
47 #endif
48 #endif
49
50 /*
51 * init_check:
52 * Check out too see if it is proper to play the game now
53 */
54 init_check()
55 {
56 if (too_much())
57 {
58 printf("Sorry, %s, but the system is too loaded now.\n", whoami);
59 printf("Try again later. Meanwhile, why not enjoy a%s %s?\n",
60 vowelstr(fruit), fruit);
61 if (author())
62 printf("However, since you're a good guy, it's up to you\n");
63 else
64 exit(1);
65 }
66 }
67
68 /*
69 * open_score:
70 * Open up the score file for future use, and then
71 * setuid(getuid()) in case we are running setuid.
72 */
73 open_score()
74 {
75 #ifdef SCOREFILE
76 fd = open(SCOREFILE, O_RDWR | O_CREAT, 0666 );
77 #else
78 fd = -1;
79 #endif
80 md_normaluser();
81 }
82
83 /*
84 * setup:
85 * Get starting setup for all games
86 */
87 setup()
88 {
89 void auto_save(), quit(), endit(), tstp();
90 #ifdef CHECKTIME
91 int checkout();
92 #endif
93
94 /*
95 * make sure that large terminals don't overflow the bounds
96 * of the program
97 */
98 if (LINES > MAXLINES)
99 LINES = MAXLINES;
100 if (COLS > MAXCOLS)
101 COLS = MAXCOLS;
102
103 #ifdef SIGHUP
104 signal(SIGHUP, auto_save);
105 #endif
106 #ifndef DUMP
107 signal(SIGILL, auto_save);
108 #ifdef SIGTRAP
109 signal(SIGTRAP, auto_save);
110 #endif
111 #ifdef SIGIOT
112 signal(SIGIOT, auto_save);
113 #endif
114 #ifdef SIGEMT
115 signal(SIGEMT, auto_save);
116 #endif
117 signal(SIGFPE, auto_save);
118 #ifdef SIGBUS
119 signal(SIGBUS, auto_save);
120 #endif
121 signal(SIGSEGV, auto_save);
122 #ifdef SIGSYS
123 signal(SIGSYS, auto_save);
124 #endif
125 signal(SIGTERM, auto_save);
126 #endif
127
128 signal(SIGINT, quit);
129 #ifndef DUMP
130 #ifdef SIGQUIT
131 signal(SIGQUIT, endit);
132 #endif
133 #endif
134 #ifdef CHECKTIME
135 signal(SIGALRM, checkout);
136 alarm(CHECKTIME * 60);
137 num_checks = 0;
138 #endif
139 crmode(); /* Cbreak mode */
140 noecho(); /* Echo off */
141 }
142
143 /*
144 * start_score:
145 * Start the scoring sequence
146 */
147 start_score()
148 {
149 #ifdef SIGALRM
150 signal(SIGALRM, SIG_IGN);
151 #endif
152 }
153
154 /*
155 * issymlink:
156 * See if the file has a symbolic link
157 */
158 issymlink(sp)
159 char *sp;
160 {
161 #ifdef S_IFLNK
162 struct stat sbuf2;
163
164 if (lstat(sp, &sbuf2) < 0)
165 return FALSE;
166 else
167 return ((sbuf2.st_mode & S_IFMT) != S_IFREG);
168 #else
169 return FALSE;
170 #endif
171 }
172
173 /*
174 * too_much:
175 * See if the system is being used too much for this game
176 */
177 too_much()
178 {
179 #ifdef MAXLOAD
180 double avec[3];
181
182 if (md_getloadavg(avec) == 0)
183 if (avec[2] > (MAXLOAD / 10.0))
184 return(1);
185 #endif
186 #ifdef MAXUSERS
187 if (md_ucount() > MAXUSERS)
188 return(1) ;
189 #endif
190 return(0);
191 }
192
193 /*
194 * author:
195 * See if a user is an author of the program
196 */
197 author()
198 {
199 #ifdef WIZARD
200 if (wizard)
201 return TRUE;
202 #endif
203 switch (md_getuid())
204 {
205 case 0:
206 return TRUE;
207 default:
208 return FALSE;
209 }
210 }
211
212 /*
213 * checkout:
214 * Check each CHECKTIME seconds to see if the load is too high
215 */
216 void
217 checkout(int s)
218 {
219 static char *msgs[] = {
220 "The load is too high to be playing. Please leave in %0.1f minutes",
221 "Please save your game. You have %0.1f minutes",
222 "Last warning. You have %0.1f minutes to leave",
223 };
224 int checktime = 0;
225
226 #ifdef SIGALRM
227 signal(SIGALRM, checkout);
228 #endif
229
230 if (too_much())
231 {
232 if (author())
233 {
234 num_checks = 1;
235 chmsg("The load is rather high, O exaulted one");
236 }
237 else if (num_checks++ == 3)
238 fatal("Sorry. You took to long. You are dead\n");
239
240 #ifdef CHECKTIME
241 checktime = (CHECKTIME * 60) / num_checks;
242 #endif
243 #ifdef SIGALRM
244 alarm(checktime);
245 #endif
246
247 chmsg(msgs[num_checks - 1], ((double) checktime / 60.0));
248 }
249 else
250 {
251 if (num_checks)
252 {
253 num_checks = 0;
254 chmsg("The load has dropped back down. You have a reprieve");
255 }
256 #ifdef CHECKTIME
257 #ifdef SIGALRM
258 alarm(CHECKTIME * 60);
259 #endif
260 #endif
261 }
262 }
263
264 /*
265 * chmsg:
266 * checkout()'s version of msg. If we are in the middle of a
267 * shell, do a printf instead of a msg to avoid the refresh.
268 */
269 chmsg(fmt, arg)
270 char *fmt;
271 int arg;
272 {
273 if (in_shell)
274 {
275 printf(fmt, arg);
276 putchar('\n');
277 fflush(stdout);
278 }
279 else
280 msg(fmt, arg);
281 }
282
283 /*
284 * lock_sc:
285 * lock the score file. If it takes too long, ask the user if
286 * they care to wait. Return TRUE if the lock is successful.
287 */
288 lock_sc()
289 {
290 #ifdef SCOREFILE
291 #ifdef LOCKFILE
292 register int cnt;
293 static struct stat sbuf;
294
295 over:
296 if (creat(lockfile, 0000) > 0)
297 return TRUE;
298 for (cnt = 0; cnt < 5; cnt++)
299 {
300 md_sleep(1);
301 if (creat(lockfile, 0000) > 0)
302 return TRUE;
303 }
304 if (stat(lockfile, &sbuf) < 0)
305 {
306 creat(lockfile, 0000);
307 return TRUE;
308 }
309 if (time(NULL) - sbuf.st_mtime > 10)
310 {
311 if (md_unlink(lockfile) < 0)
312 return FALSE;
313 goto over;
314 }
315 else
316 {
317 printf("The score file is very busy. Do you want to wait longer\n");
318 printf("for it to become free so your score can get posted?\n");
319 printf("If so, type \"y\"\n");
320 fgets(prbuf, MAXSTR, stdin);
321 if (prbuf[0] == 'y')
322 for (;;)
323 {
324 if (creat(lockfile, 0000) > 0)
325 return TRUE;
326 if (stat(lockfile, &sbuf) < 0)
327 {
328 creat(lockfile, 0000);
329 return TRUE;
330 }
331 if (time(NULL) - sbuf.st_mtime > 10)
332 {
333 if (md_unlink(lockfile) < 0)
334 return FALSE;
335 }
336 md_sleep(1);
337 }
338 else
339 return FALSE;
340 }
341 #endif
342 #endif
343 }
344
345 /*
346 * unlock_sc:
347 * Unlock the score file
348 */
349 unlock_sc()
350 {
351 #ifdef SCOREFILE
352 #ifdef LOCKFILE
353 md_unlink(lockfile);
354 #endif
355 #endif
356 }
357
358 /*
359 * flush_type:
360 * Flush typeahead for traps, etc.
361 */
362 flush_type()
363 {
364 flushinp();
365 }