|
|
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.