* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
"@(#) Copyright (c) 1980 Regents of the University of California.\n\
static char sccsid
[] = "@(#)machdep.c 5.3 (Berkeley) 5/29/89";
* Various installation dependent routines
* $Revision: 1.7 $, $Date: 85/04/05 11:33:30 $
* The various tuneable defines are:
* SCOREFILE Where/if the score file should live.
* ALLSCORES Score file is top ten scores, not top ten
* players. This is only useful when only a few
* people will be playing; otherwise the score file
* gets hogged by just a few people.
* NUMSCORES Number of scores in the score file (default 10).
* NUMNAME String version of NUMSCORES (first character
* should be capitalized) (default "Ten").
* MAXLOAD What (if any) the maximum load average should be
* when people are playing.
* LOADAV Should it use it's own routine to get
* NAMELIST If so, where does the system namelist
* MAXUSERS What (if any) the maximum user count should be
* when people are playing. If defined, then
* UCOUNT Should it use it's own routine to count
* UTMP If so, where does the user list hide?
* CHECKTIME How often/if it should check during the game
* WARNTIME How much time between warnings when load gets
* too high (if not defined, it is the same as
# undef LOADAV /* use getloadavg() by default */
static char *Lockfile
= "/tmp/.fredlock";
unsigned int Numscores
= NUMSCORES
;
static int Num_checks
; /* times we've gone over in checkout() */
# define WARNTIME CHECKTIME
* Check out too see if it is proper to play the game now
# if defined(MAXLOAD) || defined(MAXUSERS)
printf("Sorry, %s, but the system is too loaded now.\n",
printf("Try again later. Meanwhile, why not enjoy a%s %s?\n",
printf("However, since you're a good guy, it's up to you\n");
# endif defined(MAXLOAD) || defined(MAXUSERS)
* Open up the score file for future use, and then
* setuid(getuid()) in case we are running setuid.
* Get starting setup for all games
extern int auto_save(), quit(), endit(), tstp();
signal(SIGHUP
, auto_save
);
signal(SIGILL
, auto_save
);
signal(SIGTRAP
, auto_save
);
signal(SIGIOT
, auto_save
);
signal(SIGEMT
, auto_save
);
signal(SIGFPE
, auto_save
);
signal(SIGBUS
, auto_save
);
signal(SIGSEGV
, auto_save
);
signal(SIGSYS
, auto_save
);
signal(SIGTERM
, auto_save
);
signal(SIGALRM
, checkout
);
crmode(); /* Cbreak mode */
getltchars(); /* get the local tty chars */
* Get the local tty chars for later use
ioctl(1, TIOCGLTC
, &Ltc
);
Orig_dsusp
= Ltc
.t_dsuspc
;
if (Orig_dsusp
== CTRL(Y
)) {
Ltc
.t_dsuspc
= Ltc
.t_suspc
;
ioctl(1, TIOCSLTC
, &Ltc
);
* Start the scoring sequence
signal(SIGALRM
, SIG_IGN
); /* NOSTRICT */
* See if the file has a symbolic link
if (lstat(sp
, &sbuf2
) < 0)
return ((sbuf2
.st_mode
& S_IFMT
) != S_IFREG
);
# if defined(MAXLOAD) || defined(MAXUSERS)
* See if the system is being used too much for this game
if (getloadavg(avec
, sizeof(avec
)/sizeof(avec
[0])) < 0)
avec
[0] = avec
[1] = avec
[2] = 0.0;
* See if a user is an author of the program
# endif defined(MAXLOAD) || defined(MAXUSERS)
* Check each CHECKTIME seconds to see if the load is too high
"The load is too high to be playing. Please leave in %.2f minutes",
"Please save your game. You have %.2f minutes",
"Last warning. You have %.2f minutes to leave",
signal(SIGALRM
, checkout
);
chmsg("The load is rather high, O exaulted one");
else if (Num_checks
++ == 3)
fatal("Sorry. You took too long. You are dead\n");
checktime
= (WARNTIME
* 60) / Num_checks
;
chmsg(msgs
[Num_checks
- 1], ((double) checktime
/ 60.0));
chmsg("The load has dropped back down. You have a reprieve");
* checkout()'s version of msg. If we are in the middle of a
* shell, do a printf instead of a msg to avoid the refresh.
# endif defined(MAXLOAD) || defined(MAXUSERS)
* Looking up load average in core (for system where the loadav()
* system call isn't defined
# define NAMELIST "/vmunix"
if ((kmem
= open("/dev/kmem", 0)) < 0)
nlist(NAMELIST
, &avenrun
);
if (avenrun
.n_type
== 0) {
lseek(kmem
, (long) avenrun
.n_value
, 0);
read(kmem
, (char *) avg
, 3 * sizeof (double));
* Count number of users on the system
register struct utmp
*up
;
if ((utmp
= fopen(UTMP
, "r")) == NULL
)
while (fread(up
, 1, sizeof (*up
), utmp
) > 0)
if (buf
.ut_name
[0] != '\0')
* lock the score file. If it takes too long, ask the user if
* they care to wait. Return TRUE if the lock is successful.
return (flock(Fd
, LOCK_EX
) >= 0);
close(8); /* just in case there are no files left */
if (creat(Lockfile
, 0000) >= 0)
for (cnt
= 0; cnt
< 5; cnt
++) {
if (creat(Lockfile
, 0000) >= 0)
if (stat(Lockfile
, &sbuf
) < 0) {
if (time(NULL
) - sbuf
.st_mtime
> 10) {
if (unlink(Lockfile
) < 0)
printf("The score file is very busy. Do you want to wait longer\n");
printf("for it to become free so your score can get posted?\n");
printf("If so, type \"y\"\n");
fgets(Prbuf
, MAXSTR
, stdin
);
if (creat(Lockfile
, 0000) >= 0)
if (stat(Lockfile
, &sbuf
) < 0) {
if (time(NULL
) - sbuf
.st_mtime
> 10)
if (unlink(Lockfile
) < 0)