|
|
1.1 root 1: /*
2: * Copyright (c) 1987 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that: (1) source distributions retain this entire copyright
7: * notice and comment, and (2) distributions including binaries display
8: * the following acknowledgement: ``This product includes software
9: * developed by the University of California, Berkeley and its contributors''
10: * in the documentation or other materials provided with the distribution
11: * and in all advertising materials mentioning features or use of this
12: * software. Neither the name of the University nor the names of its
13: * contributors may be used to endorse or promote products derived
14: * from this software without specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: char copyright[] =
22: "@(#) Copyright (c) 1987 Regents of the University of California.\n\
23: All rights reserved.\n";
24: #endif /* not lint */
25:
26: #ifndef lint
27: static char sccsid[] = "@(#)dm.c 5.15 (Berkeley) 6/1/90";
28: #endif /* not lint */
29:
30: #include <sys/param.h>
31: #include <sys/file.h>
32: #include <sys/time.h>
33: #include <sys/resource.h>
34: #include <pwd.h>
35: #include <utmp.h>
36: #include <nlist.h>
37: #include <stdio.h>
38: #include <ctype.h>
39: #include "pathnames.h"
40:
41: extern int errno;
42: static time_t now; /* current time value */
43: static int priority = 0; /* priority game runs at */
44: static char *game, /* requested game */
45: *gametty; /* from tty? */
46:
47: /*ARGSUSED*/
48: main(argc, argv)
49: int argc;
50: char **argv;
51: {
52: char *cp, *rindex(), *ttyname();
53: time_t time();
54:
55: nogamefile();
56: game = (cp = rindex(*argv, '/')) ? ++cp : *argv;
57:
58: if (!strcmp(game, "dm"))
59: exit(0);
60:
61: gametty = ttyname(0);
62: (void)time(&now);
63: read_config();
64: #ifdef LOG
65: logfile();
66: #endif
67: play(argv);
68: /*NOTREACHED*/
69: }
70:
71: /*
72: * play --
73: * play the game
74: */
75: static
76: play(args)
77: char **args;
78: {
79: char pbuf[MAXPATHLEN], *strcpy(), *strerror();
80:
81: (void)strcpy(pbuf, _PATH_HIDE);
82: (void)strcpy(pbuf + sizeof(_PATH_HIDE) - 1, game);
83: if (priority > 0) /* < 0 requires root */
84: (void)setpriority(PRIO_PROCESS, 0, priority);
85: setgid(getgid()); /* we run setgid kmem; lose it */
86: execv(pbuf, args);
87: (void)fprintf(stderr, "dm: %s: %s\n", pbuf, strerror(errno));
88: exit(1);
89: }
90:
91: /*
92: * read_config --
93: * read through config file, looking for key words.
94: */
95: static
96: read_config()
97: {
98: FILE *cfp;
99: char lbuf[BUFSIZ], f1[40], f2[40], f3[40], f4[40], f5[40];
100:
101: if (!(cfp = fopen(_PATH_CONFIG, "r")))
102: return;
103: while (fgets(lbuf, sizeof(lbuf), cfp))
104: switch(*lbuf) {
105: case 'b': /* badtty */
106: if (sscanf(lbuf, "%s%s", f1, f2) != 2 ||
107: strcasecmp(f1, "badtty"))
108: break;
109: c_tty(f2);
110: break;
111: case 'g': /* game */
112: if (sscanf(lbuf, "%s%s%s%s%s",
113: f1, f2, f3, f4, f5) != 5 || strcasecmp(f1, "game"))
114: break;
115: c_game(f2, f3, f4, f5);
116: break;
117: case 't': /* time */
118: if (sscanf(lbuf, "%s%s%s%s", f1, f2, f3, f4) != 4 ||
119: strcasecmp(f1, "time"))
120: break;
121: c_day(f2, f3, f4);
122: }
123: (void)fclose(cfp);
124: }
125:
126: /*
127: * c_day --
128: * if day is today, see if okay to play
129: */
130: static
131: c_day(s_day, s_start, s_stop)
132: char *s_day, *s_start, *s_stop;
133: {
134: static char *days[] = {
135: "sunday", "monday", "tuesday", "wednesday",
136: "thursday", "friday", "saturday",
137: };
138: static struct tm *ct;
139: int start, stop;
140:
141: if (!ct)
142: ct = localtime(&now);
143: if (strcasecmp(s_day, days[ct->tm_wday]))
144: return;
145: if (!isdigit(*s_start) || !isdigit(*s_stop))
146: return;
147: start = atoi(s_start);
148: stop = atoi(s_stop);
149: if (ct->tm_hour >= start && ct->tm_hour < stop) {
150: fputs("dm: Sorry, games are not available from ", stderr);
151: hour(start);
152: fputs(" to ", stderr);
153: hour(stop);
154: fputs(" today.\n", stderr);
155: exit(0);
156: }
157: }
158:
159: /*
160: * c_tty --
161: * decide if this tty can be used for games.
162: */
163: static
164: c_tty(tty)
165: char *tty;
166: {
167: static int first = 1;
168: static char *p_tty;
169: char *rindex();
170:
171: if (first) {
172: p_tty = rindex(gametty, '/');
173: first = 0;
174: }
175:
176: if (!strcmp(gametty, tty) || p_tty && !strcmp(p_tty, tty)) {
177: fprintf(stderr, "dm: Sorry, you may not play games on %s.\n", gametty);
178: exit(0);
179: }
180: }
181:
182: /*
183: * c_game --
184: * see if game can be played now.
185: */
186: static
187: c_game(s_game, s_load, s_users, s_priority)
188: char *s_game, *s_load, *s_users, *s_priority;
189: {
190: static int found;
191: double load();
192:
193: if (found)
194: return;
195: if (strcmp(game, s_game) && strcasecmp("default", s_game))
196: return;
197: ++found;
198: if (isdigit(*s_load) && atoi(s_load) < load()) {
199: fputs("dm: Sorry, the load average is too high right now.\n", stderr);
200: exit(0);
201: }
202: if (isdigit(*s_users) && atoi(s_users) <= users()) {
203: fputs("dm: Sorry, there are too many users logged on right now.\n", stderr);
204: exit(0);
205: }
206: if (isdigit(*s_priority))
207: priority = atoi(s_priority);
208: }
209:
210: /*
211: * load --
212: * return 15 minute load average
213: */
214: static double
215: load()
216: {
217: double avenrun[3];
218:
219: if (getloadavg(avenrun, sizeof(avenrun)/sizeof(avenrun[0])) < 0) {
220: fputs("dm: getloadavg() failed.\n", stderr);
221: exit(1);
222: }
223: return(avenrun[2]);
224: }
225:
226: /*
227: * users --
228: * return current number of users
229: * todo: check idle time; if idle more than X minutes, don't
230: * count them.
231: */
232: static
233: users()
234: {
235:
236: register int nusers, utmp;
237: struct utmp buf;
238:
239: if ((utmp = open(_PATH_UTMP, O_RDONLY, 0)) < 0) {
240: (void)fprintf(stderr, "dm: %s: %s\n",
241: _PATH_UTMP, strerror(errno));
242: exit(1);
243: }
244: for (nusers = 0; read(utmp, (char *)&buf, sizeof(struct utmp)) > 0;)
245: if (buf.ut_name[0] != '\0')
246: ++nusers;
247: return(nusers);
248: }
249:
250: static
251: nogamefile()
252: {
253: register int fd, n;
254: char buf[BUFSIZ];
255:
256: if ((fd = open(_PATH_NOGAMES, O_RDONLY, 0)) >= 0) {
257: #define MESG "Sorry, no games right now.\n\n"
258: (void)write(2, MESG, sizeof(MESG) - 1);
259: while ((n = read(fd, buf, sizeof(buf))) > 0)
260: (void)write(2, buf, n);
261: exit(1);
262: }
263: }
264:
265: /*
266: * hour --
267: * print out the hour in human form
268: */
269: static
270: hour(h)
271: int h;
272: {
273: switch(h) {
274: case 0:
275: fputs("midnight", stderr);
276: break;
277: case 12:
278: fputs("noon", stderr);
279: break;
280: default:
281: if (h > 12)
282: fprintf(stderr, "%dpm", h - 12);
283: else
284: fprintf(stderr, "%dam", h);
285: }
286: }
287:
288: #ifdef LOG
289: /*
290: * logfile --
291: * log play of game
292: */
293: static
294: logfile()
295: {
296: struct passwd *pw, *getpwuid();
297: FILE *lp;
298: uid_t uid;
299: int lock_cnt;
300: char *ctime();
301:
302: if (lp = fopen(_PATH_LOG, "a")) {
303: for (lock_cnt = 0;; ++lock_cnt) {
304: if (!flock(fileno(lp), LOCK_EX))
305: break;
306: if (lock_cnt == 4) {
307: perror("dm: log lock");
308: (void)fclose(lp);
309: return;
310: }
311: sleep((u_int)1);
312: }
313: if (pw = getpwuid(uid = getuid()))
314: fputs(pw->pw_name, lp);
315: else
316: fprintf(lp, "%u", uid);
317: fprintf(lp, "\t%s\t%s\t%s", game, gametty, ctime(&now));
318: (void)fclose(lp);
319: (void)flock(fileno(lp), LOCK_UN);
320: }
321: }
322: #endif /* LOG */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.