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