* Copyright (c) 1987 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
"@(#) Copyright (c) 1987 Regents of the University of California.\n\
static char sccsid
[] = "@(#)dm.c 5.2 (Berkeley) %G%";
#include <sys/resource.h>
#define GAMEHIDE "/usr/games/hide"
#define NOGAMING "/etc/nogames"
#define CONTROL "/usr/games/game.control"
#define LOGFILE "/usr/adm/gamelog"
static time_t now
; /* current time value */
static int priority
= 0; /* priority game runs at */
static char *game
, /* requested game */
*gametty
; /* from tty? */
if (!strcmp(*argv
, "dm"))
if (!(cfp
= fopen(CONTROL
, "r"))) {
fprintf(stderr
, "dm: unable to read %s.\n", CONTROL
);
game
= (C
= rindex(*argv
, '/')) ? ++C
: *argv
;
if (priority
&& setpriority(PRIO_PROCESS
, 0, priority
) < 0)
fputs("dm: unable to set priority!\n", stderr
);
setgid(getgid()); /* we run setgid kmem; lose it */
#define lcontrol(buf) (buf[0] == '%' && buf[1] == '%')
#define lignore(buf) (buf[0] == '\n' || buf[0] == '#')
* read through days listed in the control file, decide
* if current time is an okay play time.
"sunday", "monday", "tuesday", "wednesday",
"thursday", "friday", "saturday",
char lbuf
[BUFSIZ
], f1
[40], f2
[40], f3
[40];
while (fgets(lbuf
, sizeof(lbuf
), cfp
)) {
if (sscanf(lbuf
, "%s%s%s", f1
, f2
, f3
) != 3)
if (!strcasecmp(dp
, f1
)) {
if (!isdigit(*f2
) || !isdigit(*f3
))
if (ct
->tm_hour
>= start
&& ct
->tm_hour
<= stop
) {
fputs("dm: Sorry, games are not available from ", stderr
);
fputs(" today.\n", stderr
);
* read through ttys listed in the control file, decide if this
* tty can be used for games.
char lbuf
[BUFSIZ
], f1
[40], f2
[40],
if (p_tty
= rindex(gametty
, '/'))
while (fgets(lbuf
, sizeof(lbuf
), cfp
)) {
if (sscanf(lbuf
, "%s%s", f1
, f2
) != 2)
if (strcasecmp("badtty", f1
))
if (!strcmp(gametty
, f2
) || p_tty
&& !strcmp(p_tty
, f2
)) {
fprintf(stderr
, "dm: Sorry, you may not play games on %s.\n", gametty
);
* read through games listed in the control file, decide if this
* game can be played now.
char lbuf
[BUFSIZ
], f1
[40], f2
[40], f3
[40], f4
[40];
while (fgets(lbuf
, sizeof(lbuf
), cfp
)) {
if (sscanf(lbuf
, "%s%s%s%s", f1
, f2
, f3
, f4
) != 4)
if (!strcmp(game
, f1
) || !strcasecmp("default", f1
)) {
if (isdigit(*f2
) && atoi(f2
) < load()) {
fputs("dm: Sorry, the load average is too high right now.\n", stderr
);
if (isdigit(*f3
) && atoi(f3
) <= users()) {
fputs("dm: Sorry, there are too many users logged on right now.\n", stderr
);
if (isdigit(*f4
) || *f4
== '-' || *f4
== '+')
static struct nlist nl
[] = {
* return 15 minute load average
if (nlist("/vmunix", nl
)) {
fputs("dm: nlist of /vmunix failed.\n", stderr
);
if ((kmem
= open("/dev/kmem", O_RDONLY
, 0)) < 0) {
(void)lseek(kmem
, (long)nl
[X_AVENRUN
].n_value
, L_SET
);
(void)read(kmem
, avenrun
, sizeof(avenrun
));
* return current number of users
if ((utmp
= open("/etc/utmp", O_RDONLY
, 0)) < 0) {
for (nusers
= 0; read(utmp
, (char *)&buf
, sizeof(struct utmp
)) > 0;)
if (buf
.ut_name
[0] != '\0')
* if the file NOGAMING exists, no games allowed.
* file may also contain a message for the user.
if ((fd
= open(NOGAMING
, O_RDONLY
, 0)) >= 0) {
#define MESG "Sorry, no games right now.\n\n"
(void)write(2, MESG
, sizeof(MESG
) - 1);
while ((n
= read(fd
, buf
, sizeof(buf
))) > 0)
* print out the hour in human form
fputs("midnight", stderr
);
fprintf(stderr
, "%dpm", h
- 12);
fprintf(stderr
, "%dam", h
);
struct passwd
*pw
, *getpwuid();
if (lp
= fopen(LOGFILE
, "a")) {
for (lock_cnt
= 0;; ++lock_cnt
) {
if (!flock(fileno(lp
), LOCK_EX
))
if (pw
= getpwuid(uid
= getuid()))
fprintf(lp
, "\t%s\t%s\t%s", game
, gametty
, ctime(&now
));
(void)flock(fileno(lp
), LOCK_UN
);