|
|
1.1 root 1: /*
2: * Various installation dependent routines
3: *
4: * @(#)find.c 4.37 (Berkeley) 5/23/83
5: */
6:
7: /*
8: * The various tuneable defines are:
9: *
10: * SCOREFILE Where/if the score file should live.
11: * ALLSCORES Score file is top ten scores, not top ten
12: * players. This is only useful when only a few
13: * people will be playing; otherwise the score file
14: * gets hogged by just a few people.
15: * NUMSCORES Number of scores in the score file (default 10).
16: * NUMNAME String version of NUMSCORES (first character
17: * should be capitalized) (default "Ten").
18: * MAXLOAD What (if any) the maximum load average should be
19: * when people are playing. Since it is divided
20: * by 10, to specify a load limit of 4.0, MAXLOAD
21: * should be "40". If defined, then
22: * LOADAV Should it use it's own routine to get
23: * the load average?
24: * NAMELIST If so, where does the system namelist
25: * hide?
26: * MAXUSERS What (if any) the maximum user count should be
27: * when people are playing. If defined, then
28: * UCOUNT Should it use it's own routine to count
29: * users?
30: * UTMP If so, where does the user list hide?
31: * CHECKTIME How often/if it should check during the game
32: * for high load average.
33: */
34:
35: #include <curses.h>
36: #include "extern.h"
37: #include <signal.h>
38: #include <sys/types.h>
39: #include <sys/stat.h>
40:
41: #ifdef SCOREFILE
42:
43: static char *Lockfile = "/tmp/.fredlock";
44:
45: # ifndef NUMSCORES
46: # define NUMSCORES 10
47: # define NUMNAME "Ten"
48: # endif
49:
50: unsigned int numscores = NUMSCORES;
51: char *Numname = NUMNAME;
52:
53: # ifdef ALLSCORES
54: bool Allscore = TRUE;
55: # else ALLSCORES
56: bool Allscore = FALSE;
57: # endif ALLSCORES
58:
59: #endif SCOREFILE
60:
61: #ifdef CHECKTIME
62: static int Num_checks; /* times we've gone over in checkout() */
63: #endif CHECKTIME
64:
65: /*
66: * init_check:
67: * Check out too see if it is proper to play the game now
68: */
69: init_check()
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, and then
88: * setuid(getuid()) in case we are running setuid.
89: */
90: open_score()
91: {
92: #ifdef SCOREFILE
93: Fd = open(SCOREFILE, 2);
94: if (Fd < 0)
95: perror(SCOREFILE);
96: #else
97: Fd = -1;
98: #endif
99: setuid(getuid());
100: setgid(getgid());
101: }
102:
103: /*
104: * setup:
105: * Get starting setup for all games
106: */
107: setup()
108: {
109: int auto_save(), quit(), endit(), tstp();
110: #ifdef CHECKTIME
111: int checkout();
112: #endif
113:
114: signal(SIGHUP, auto_save);
115: #ifndef DUMP
116: signal(SIGILL, auto_save);
117: signal(SIGTRAP, auto_save);
118: signal(SIGIOT, auto_save);
119: signal(SIGEMT, auto_save);
120: signal(SIGFPE, auto_save);
121: signal(SIGBUS, auto_save);
122: signal(SIGSEGV, auto_save);
123: signal(SIGSYS, auto_save);
124: signal(SIGTERM, auto_save);
125: #endif
126:
127: signal(SIGINT, quit);
128: #ifndef DUMP
129: signal(SIGQUIT, endit);
130: #endif
131: #ifdef CHECKTIME
132: signal(SIGALRM, checkout);
133: alarm(CHECKTIME * 60);
134: Num_checks = 0;
135: #endif
136: crmode(); /* Cbreak mode */
137: noecho(); /* Echo off */
138: #ifdef TIOCGLTC
139: getltchars(); /* get the local tty chars */
140: #endif
141: }
142:
143: /*
144: * getltchars:
145: * Get the local tty chars for later use
146: */
147: getltchars()
148: {
149: #ifdef TIOCGLTC
150: ioctl(1, TIOCGLTC, &Ltc);
151: Got_ltc = TRUE;
152: Orig_dsusp = Ltc.t_dsuspc;
153: Ltc.t_dsuspc = Ltc.t_suspc;
154: ioctl(1, TIOCSLTC, &Ltc);
155: #endif
156: }
157:
158: /*
159: * start_score:
160: * Start the scoring sequence
161: */
162: start_score()
163: {
164: #ifdef CHECKTIME
165: signal(SIGALRM, SIG_IGN);
166: #endif
167: }
168:
169: /*
170: * symlink:
171: * See if the file has a symbolic link
172: */
173: symlink(sp)
174: char *sp;
175: {
176: #ifdef S_IFLNK
177: struct stat sbuf2;
178:
179: if (lstat(sp, &sbuf2) < 0)
180: return FALSE;
181: else
182: return ((sbuf2.st_mode & S_IFMT) != S_IFREG);
183: #else
184: return FALSE;
185: #endif
186: }
187:
188: #if defined(MAXLOAD) || defined(MAXUSERS)
189: /*
190: * too_much:
191: * See if the system is being used too much for this game
192: */
193: too_much()
194: {
195: #ifdef MAXLOAD
196: double avec[3];
197: #else
198: register int cnt;
199: #endif
200:
201: #ifdef MAXLOAD
202: loadav(avec);
203: if (avec[1] > (MAXLOAD / 10.0))
204: return TRUE;
205: #endif
206: #ifdef MAXUSERS
207: if (ucount() > MAXUSERS)
208: return TRUE;
209: #endif
210: return FALSE;
211: }
212:
213: /*
214: * author:
215: * See if a user is an author of the program
216: */
217: author()
218: {
219: #ifdef MASTER
220: if (Wizard)
221: return TRUE;
222: #endif
223: switch (getuid())
224: {
225: case -1:
226: return TRUE;
227: default:
228: return FALSE;
229: }
230: }
231: #endif
232:
233: #ifdef CHECKTIME
234: /*
235: * checkout:
236: * Check each CHECKTIME seconds to see if the load is too high
237: */
238: checkout()
239: {
240: static char *msgs[] = {
241: "The load is too high to be playing. Please leave in %0.1f minutes",
242: "Please save your game. You have %0.1f minutes",
243: "Last warning. You have %0.1f minutes to leave",
244: };
245: int checktime;
246:
247: signal(SIGALRM, checkout);
248: if (too_much())
249: {
250: if (author())
251: {
252: Num_checks = 1;
253: chmsg("The load is rather high, O exaulted one");
254: }
255: else if (Num_checks++ == 3)
256: fatal("Sorry. You took too long. You are dead\n");
257: checktime = (CHECKTIME * 60) / Num_checks;
258: alarm(checktime);
259: chmsg(msgs[Num_checks - 1], ((double) checktime / 60.0));
260: }
261: else
262: {
263: if (Num_checks)
264: {
265: Num_checks = 0;
266: chmsg("The load has dropped back down. You have a reprieve");
267: }
268: alarm(CHECKTIME * 60);
269: }
270: }
271:
272: /*
273: * chmsg:
274: * checkout()'s version of msg. If we are in the middle of a
275: * shell, do a printf instead of a msg to avoid the refresh.
276: */
277: /* VARARGS1 */
278: chmsg(fmt, arg)
279: char *fmt;
280: int arg;
281: {
282: if (!In_shell)
283: msg(fmt, arg);
284: else
285: {
286: printf(fmt, arg);
287: putchar('\n');
288: fflush(stdout);
289: }
290: }
291: #endif
292:
293: #ifdef LOADAV
294: /*
295: * loadav:
296: * Looking up load average in core (for system where the loadav()
297: * system call isn't defined
298: */
299:
300: #include <nlist.h>
301:
302: struct nlist avenrun = {
303: "_avenrun"
304: };
305:
306: loadav(avg)
307: register double *avg;
308: {
309: register int kmem;
310:
311: if ((kmem = open("/dev/kmem", 0)) < 0)
312: goto bad;
313: nlist(NAMELIST, &avenrun);
314: if (avenrun.n_type == 0)
315: {
316: close(kmem);
317: bad:
318: avg[0] = 0.0;
319: avg[1] = 0.0;
320: avg[2] = 0.0;
321: return;
322: }
323:
324: lseek(kmem, (long) avenrun.n_value, 0);
325: read(kmem, (char *) avg, 3 * sizeof (double));
326: close(kmem);
327: }
328: #endif
329:
330: #ifdef UCOUNT
331: /*
332: * ucount:
333: * Count number of users on the system
334: */
335: #include <utmp.h>
336:
337: struct utmp buf;
338:
339: ucount()
340: {
341: register struct utmp *up;
342: register FILE *utmp;
343: register int count;
344:
345: if ((utmp = fopen(UTMP, "r")) == NULL)
346: return 0;
347:
348: up = &buf;
349: count = 0;
350:
351: while (fread(up, 1, sizeof (*up), utmp) > 0)
352: if (buf.ut_name[0] != '\0')
353: count++;
354: fclose(utmp);
355: return count;
356: }
357: #endif
358:
359: /*
360: * lock_sc:
361: * lock the score file. If it takes too long, ask the user if
362: * they care to wait. Return TRUE if the lock is successful.
363: */
364: lock_sc()
365: {
366: #ifdef SCOREFILE
367: register int cnt;
368: static struct stat sbuf;
369: time_t time();
370:
371: over:
372: close(8); /* just in case there are no files left */
373: if (creat(Lockfile, 0000) >= 0)
374: return TRUE;
375: for (cnt = 0; cnt < 5; cnt++)
376: {
377: sleep(1);
378: if (creat(Lockfile, 0000) >= 0)
379: return TRUE;
380: }
381: if (stat(Lockfile, &sbuf) < 0)
382: {
383: creat(Lockfile, 0000);
384: return TRUE;
385: }
386: if (time(NULL) - sbuf.st_mtime > 10)
387: {
388: if (unlink(Lockfile) < 0)
389: return FALSE;
390: goto over;
391: }
392: else
393: {
394: printf("The score file is very busy. Do you want to wait longer\n");
395: printf("for it to become free so your score can get posted?\n");
396: printf("If so, type \"y\"\n");
397: fgets(Prbuf, MAXSTR, stdin);
398: if (Prbuf[0] == 'y')
399: for (;;)
400: {
401: if (creat(Lockfile, 0000) >= 0)
402: return TRUE;
403: if (stat(Lockfile, &sbuf) < 0)
404: {
405: creat(Lockfile, 0000);
406: return TRUE;
407: }
408: if (time(NULL) - sbuf.st_mtime > 10)
409: {
410: if (unlink(Lockfile) < 0)
411: return FALSE;
412: }
413: sleep(1);
414: }
415: else
416: return FALSE;
417: }
418: #endif
419: }
420:
421: /*
422: * unlock_sc:
423: * Unlock the score file
424: */
425: unlock_sc()
426: {
427: #ifdef SCOREFILE
428: unlink(Lockfile);
429: #endif
430: }
431:
432: /*
433: * flush_type:
434: * Flush typeahead for traps, etc.
435: */
436: flush_type()
437: {
438: crmode();
439: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.