Annotation of early-roguelike/rogue4/mach_dep.c, Revision 1.1.1.1
1.1 rubenllo 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 <errno.h>
41:
42: #ifdef CHECKTIME
43: #include <unistd.h>
44: #endif
45:
46: #include "rogue.h"
47:
48: int num_checks; /* times we've gone over in checkout() */
49:
50: #ifdef SCOREFILE
51: #ifdef LOCKFILE
52: static char *lockfile = LOCKFILE;
53: #endif
54: #endif
55:
56: int too_much(void);
57: bool author(void);
58: void checkout(int s);
59: void chmsg(char *fmt, int arg);
60:
61: /*
62: * init_check:
63: * Check out too see if it is proper to play the game now
64: */
65: void
66: init_check(void)
67: {
68: if (too_much())
69: {
70: printf("Sorry, %s, but the system is too loaded now.\n", whoami);
71: printf("Try again later. Meanwhile, why not enjoy a%s %s?\n",
72: vowelstr(fruit), fruit);
73: if (author())
74: printf("However, since you're a good guy, it's up to you\n");
75: else
76: exit(1);
77: }
78: }
79:
80: /*
81: * open_score:
82: * Open up the score file for future use, and then
83: * setuid(getuid()) in case we are running setuid.
84: */
85: void
86: open_score(void)
87: {
88: #ifdef SCOREFILE
89: score_file = fopen(SCOREFILE, "r+");
90: if ((score_file == NULL) && (errno == ENOENT)) {
91: score_file = fopen(SCOREFILE, "w+");
92: }
93: #else
94: score_file = NULL;
95: #endif
96: if (!use_savedir)
97: md_normaluser();
98: return;
99: }
100:
101: void
102: open_log(void)
103: {
104: #ifdef LOGFILE
105: log_file = fopen(LOGFILE, "a");
106: #else
107: log_file = NULL;
108: #endif
109: return;
110: }
111:
112: /*
113: * setup:
114: * Get starting setup for all games
115: */
116: void
117: setup(void)
118: {
119: void auto_save(), quit(), endit(), tstp();
120:
121: /*
122: * make sure that large terminals don't overflow the bounds
123: * of the program
124: */
125: if (LINES > MAXLINES)
126: LINES = MAXLINES;
127: if (COLS > MAXCOLS)
128: COLS = MAXCOLS;
129:
130: #ifdef SIGHUP
131: signal(SIGHUP, auto_save);
132: #endif
133: #ifndef DUMP
134: signal(SIGILL, auto_save);
135: #ifdef SIGTRAP
136: signal(SIGTRAP, auto_save);
137: #endif
138: #ifdef SIGIOT
139: signal(SIGIOT, auto_save);
140: #endif
141: #ifdef SIGEMT
142: signal(SIGEMT, auto_save);
143: #endif
144: signal(SIGFPE, auto_save);
145: #ifdef SIGBUS
146: signal(SIGBUS, auto_save);
147: #endif
148: /* Don't bother saving a game that segfaulted. */
149: signal(SIGSEGV, SIG_DFL);
150: #ifdef SIGSYS
151: signal(SIGSYS, auto_save);
152: #endif
153: signal(SIGTERM, auto_save);
154: #endif
155:
156: signal(SIGINT, quit);
157: #ifndef DUMP
158: #ifdef SIGQUIT
159: signal(SIGQUIT, endit);
160: #endif
161: #endif
162: #ifdef CHECKTIME
163: signal(SIGALRM, checkout);
164: alarm(CHECKTIME * 60);
165: num_checks = 0;
166: #endif
167: nonl();
168: crmode(); /* Cbreak mode */
169: noecho(); /* Echo off */
170: }
171:
172: /*
173: * start_score:
174: * Start the scoring sequence
175: */
176: void
177: start_score(void)
178: {
179: #ifdef SIGALRM
180: signal(SIGALRM, SIG_IGN);
181: #endif
182: }
183:
184: /*
185: * issymlink:
186: * See if the file has a symbolic link
187: */
188: bool
189: issymlink(char *sp)
190: {
191: #ifdef S_IFLNK
192: struct stat sbuf2;
193:
194: if (lstat(sp, &sbuf2) < 0)
195: return FALSE;
196: else
197: return ((sbuf2.st_mode & S_IFMT) != S_IFREG);
198: #else
199: return FALSE;
200: #endif
201: }
202:
203: /*
204: * too_much:
205: * See if the system is being used too much for this game
206: */
207: int
208: too_much(void)
209: {
210: #ifdef MAXLOAD
211: double avec[3];
212:
213: if (md_getloadavg(avec) == 0)
214: if (avec[2] > (MAXLOAD / 10.0))
215: return(1);
216: #endif
217: #ifdef MAXUSERS
218: if (md_ucount() > MAXUSERS)
219: return(1) ;
220: #endif
221: return(0);
222: }
223:
224: /*
225: * author:
226: * See if a user is an author of the program
227: */
228: bool
229: author(void)
230: {
231: #ifdef WIZARD
232: if (wizard)
233: return TRUE;
234: #endif
235: switch (md_getuid())
236: {
237: case 0:
238: return TRUE;
239: default:
240: return FALSE;
241: }
242: }
243:
244: /*
245: * checkout:
246: * Check each CHECKTIME seconds to see if the load is too high
247: */
248: void
249: checkout(int s)
250: {
251: static char *msgs[] = {
252: "The load is too high to be playing. Please leave in %0.1f minutes",
253: "Please save your game. You have %0.1f minutes",
254: "Last warning. You have %0.1f minutes to leave",
255: };
256: int checktime = 0;
257:
258: #ifdef SIGALRM
259: signal(SIGALRM, checkout);
260: #endif
261:
262: if (too_much())
263: {
264: if (author())
265: {
266: num_checks = 1;
267: chmsg("The load is rather high, O exaulted one", 0);
268: }
269: else if (num_checks++ == 3)
270: fatal("Sorry. You took to long. You are dead\n");
271:
272: #ifdef CHECKTIME
273: checktime = (CHECKTIME * 60) / num_checks;
274: #ifdef SIGALRM
275: alarm(checktime);
276: #endif
277: #endif
278:
279: chmsg(msgs[num_checks - 1], ((double) checktime / 60.0));
280: }
281: else
282: {
283: if (num_checks)
284: {
285: num_checks = 0;
286: chmsg("The load has dropped back down. You have a reprieve", 0);
287: }
288: #ifdef CHECKTIME
289: #ifdef SIGALRM
290: alarm(CHECKTIME * 60);
291: #endif
292: #endif
293: }
294: }
295:
296: /*
297: * chmsg:
298: * checkout()'s version of msg. If we are in the middle of a
299: * shell, do a printf instead of a msg to avoid the refresh.
300: */
301: void
302: chmsg(char *fmt, int arg)
303: {
304: if (in_shell)
305: {
306: printf(fmt, arg);
307: putchar('\n');
308: fflush(stdout);
309: }
310: else
311: msg(fmt, arg);
312: }
313:
314: /*
315: * lock_sc:
316: * lock the score file. If it takes too long, ask the user if
317: * they care to wait. Return TRUE if the lock is successful.
318: */
319: bool
320: lock_sc(void)
321: {
322: #ifdef SCOREFILE
323: #ifdef LOCKFILE
324: register int cnt;
325: static struct stat sbuf;
326:
327: over:
328: if (creat(lockfile, 0000) > 0)
329: return TRUE;
330: for (cnt = 0; cnt < 5; cnt++)
331: {
332: md_sleep(1);
333: if (creat(lockfile, 0000) > 0)
334: return TRUE;
335: }
336: if (stat(lockfile, &sbuf) < 0)
337: {
338: creat(lockfile, 0000);
339: return TRUE;
340: }
341: if (time(NULL) - sbuf.st_mtime > 10)
342: {
343: if (md_unlink(lockfile) < 0)
344: return FALSE;
345: goto over;
346: }
347: else
348: {
349: printf("The score file is very busy. Do you want to wait longer\n");
350: printf("for it to become free so your score can get posted?\n");
351: printf("If so, type \"y\"\n");
352: fgets(prbuf, MAXSTR, stdin);
353: if (prbuf[0] == 'y')
354: for (;;)
355: {
356: if (creat(lockfile, 0000) > 0)
357: return TRUE;
358: if (stat(lockfile, &sbuf) < 0)
359: {
360: creat(lockfile, 0000);
361: return TRUE;
362: }
363: if (time(NULL) - sbuf.st_mtime > 10)
364: {
365: if (md_unlink(lockfile) < 0)
366: return FALSE;
367: }
368: md_sleep(1);
369: }
370: else
371: return FALSE;
372: }
373: #endif
374: #endif
375: return TRUE;
376: }
377:
378: /*
379: * unlock_sc:
380: * Unlock the score file
381: */
382: void
383: unlock_sc(void)
384: {
385: #ifdef SCOREFILE
386: #ifdef LOCKFILE
387: md_unlink(lockfile);
388: #endif
389: #endif
390: }
391:
392: /*
393: * flush_type:
394: * Flush typeahead for traps, etc.
395: */
396: void
397: flush_type(void)
398: {
399: flushinp();
400: }
CVSweb