Mercurial > hg > early-roguelike
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 } |