diff rogue4/mach_dep.c @ 12:9535a08ddc39

Import Rogue 5.2 from the Roguelike Restoration Project (r1490)
author edwarj4
date Sat, 24 Oct 2009 16:52:52 +0000
parents
children 63b9fd7d70ce
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue4/mach_dep.c	Sat Oct 24 16:52:52 2009 +0000
@@ -0,0 +1,365 @@
+/*
+ * Various installation dependent routines
+ *
+ * @(#)mach_dep.c	4.23 (Berkeley) 5/19/82
+ *
+ * Rogue: Exploring the Dungeons of Doom
+ * Copyright (C) 1980, 1981, 1982 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+/*
+ * The various tuneable defines are:
+ *
+ *	SCOREFILE	Where/if the score file should live.
+ *	MAXLOAD		What (if any) the maximum load average should be
+ *			when people are playing.  If defined, then
+ *	LOADAV		Should rogue define it's own routine to
+ *			get the load average?
+ *	NAMELIST	If so, where does the system namelist hide?
+ *	MAXUSERS	What (if any) the maximum user count should be
+ *			when people are playing.  If defined, then
+ *	UCOUNT		Should rogue define it's own routine to
+ *			count users?
+ *	UTMP		If so, where does the user list hide?
+ *	CHECKTIME	How often/if rogue should check during the game
+ *			for high load average.
+ */
+
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <curses.h>
+#include <time.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include "rogue.h"
+
+int num_checks;		/* times we've gone over in checkout() */
+
+#ifdef SCOREFILE
+#ifdef LOCKFILE
+static char *lockfile = LOCKFILE;
+#endif
+#endif
+
+/*
+ * init_check:
+ *	Check out too see if it is proper to play the game now
+ */
+init_check()
+{
+    if (too_much())
+    {
+	printf("Sorry, %s, but the system is too loaded now.\n", whoami);
+	printf("Try again later.  Meanwhile, why not enjoy a%s %s?\n",
+	    vowelstr(fruit), fruit);
+	if (author())
+	    printf("However, since you're a good guy, it's up to you\n");
+	else
+	    exit(1);
+    }
+}
+
+/*
+ * open_score:
+ *	Open up the score file for future use, and then
+ *	setuid(getuid()) in case we are running setuid.
+ */
+open_score()
+{
+#ifdef SCOREFILE
+    fd = open(SCOREFILE, O_RDWR | O_CREAT, 0666 );
+#else
+    fd = -1;
+#endif
+    md_normaluser();
+}
+
+/*
+ * setup:
+ *	Get starting setup for all games
+ */
+setup()
+{
+    void  auto_save(), quit(), endit(), tstp();
+#ifdef CHECKTIME
+    int  checkout();
+#endif
+
+    /*
+     * make sure that large terminals don't overflow the bounds
+     * of the program
+     */
+    if (LINES > MAXLINES)
+	LINES = MAXLINES;
+    if (COLS > MAXCOLS)
+	COLS = MAXCOLS;
+
+#ifdef SIGHUP
+    signal(SIGHUP, auto_save);
+#endif
+#ifndef DUMP
+    signal(SIGILL, auto_save);
+#ifdef SIGTRAP
+    signal(SIGTRAP, auto_save);
+#endif
+#ifdef SIGIOT
+    signal(SIGIOT, auto_save);
+#endif
+#ifdef SIGEMT
+    signal(SIGEMT, auto_save);
+#endif
+    signal(SIGFPE, auto_save);
+#ifdef SIGBUS
+    signal(SIGBUS, auto_save);
+#endif
+    signal(SIGSEGV, auto_save);
+#ifdef SIGSYS
+    signal(SIGSYS, auto_save);
+#endif
+    signal(SIGTERM, auto_save);
+#endif
+
+    signal(SIGINT, quit);
+#ifndef DUMP
+#ifdef SIGQUIT
+    signal(SIGQUIT, endit);
+#endif
+#endif
+#ifdef CHECKTIME
+    signal(SIGALRM, checkout);
+    alarm(CHECKTIME * 60);
+    num_checks = 0;
+#endif
+    crmode();				/* Cbreak mode */
+    noecho();				/* Echo off */
+}
+
+/*
+ * start_score:
+ *	Start the scoring sequence
+ */
+start_score()
+{
+#ifdef SIGALRM
+    signal(SIGALRM, SIG_IGN);
+#endif
+}
+
+/*
+ * issymlink:
+ *	See if the file has a symbolic link
+ */
+issymlink(sp)
+char *sp;
+{
+#ifdef S_IFLNK
+    struct stat sbuf2;
+
+    if (lstat(sp, &sbuf2) < 0)
+	return FALSE;
+    else
+	return ((sbuf2.st_mode & S_IFMT) != S_IFREG);
+#else
+    return FALSE;
+#endif
+}
+
+/*
+ * too_much:
+ *	See if the system is being used too much for this game
+ */
+too_much()
+{
+#ifdef MAXLOAD
+    double avec[3];
+    
+    if (md_getloadavg(avec) == 0)
+        if (avec[2] > (MAXLOAD / 10.0))
+	    return(1);
+#endif
+#ifdef MAXUSERS
+    if (md_ucount() > MAXUSERS)
+	return(1) ;
+#endif
+    return(0);
+}
+
+/*
+ * author:
+ *	See if a user is an author of the program
+ */
+author()
+{
+#ifdef WIZARD
+    if (wizard)
+	return TRUE;
+#endif
+    switch (md_getuid())
+    {
+	case 0:
+	    return TRUE;
+	default:
+	    return FALSE;
+    }
+}
+
+/*
+ * checkout:
+ *	Check each CHECKTIME seconds to see if the load is too high
+ */
+void
+checkout(int s)
+{
+    static char *msgs[] = {
+	"The load is too high to be playing.  Please leave in %0.1f minutes",
+	"Please save your game.  You have %0.1f minutes",
+	"Last warning.  You have %0.1f minutes to leave",
+    };
+    int checktime = 0;
+
+#ifdef SIGALRM
+    signal(SIGALRM, checkout);
+#endif
+
+    if (too_much())
+    {
+	if (author())
+	{
+	    num_checks = 1;
+	    chmsg("The load is rather high, O exaulted one");
+	}
+	else if (num_checks++ == 3)
+	    fatal("Sorry.  You took to long.  You are dead\n");
+
+#ifdef CHECKTIME
+	checktime = (CHECKTIME * 60) / num_checks;
+#endif
+#ifdef SIGALRM
+	alarm(checktime);
+#endif
+
+	chmsg(msgs[num_checks - 1], ((double) checktime / 60.0));
+    }
+    else
+    {
+	if (num_checks)
+	{
+	    num_checks = 0;
+	    chmsg("The load has dropped back down.  You have a reprieve");
+	}
+#ifdef CHECKTIME
+#ifdef SIGALRM
+	alarm(CHECKTIME * 60);
+#endif
+#endif
+    }
+}
+
+/*
+ * chmsg:
+ *	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.
+ */
+chmsg(fmt, arg)
+char *fmt;
+int arg;
+{
+    if (in_shell)
+    {
+	printf(fmt, arg);
+	putchar('\n');
+	fflush(stdout);
+    }
+    else
+	msg(fmt, arg);
+}
+
+/*
+ * lock_sc:
+ *	lock the score file.  If it takes too long, ask the user if
+ *	they care to wait.  Return TRUE if the lock is successful.
+ */
+lock_sc()
+{
+#ifdef SCOREFILE
+#ifdef LOCKFILE
+    register int cnt;
+    static struct stat sbuf;
+
+over:
+    if (creat(lockfile, 0000) > 0)
+	return TRUE;
+    for (cnt = 0; cnt < 5; cnt++)
+    {
+	md_sleep(1);
+	if (creat(lockfile, 0000) > 0)
+	    return TRUE;
+    }
+    if (stat(lockfile, &sbuf) < 0)
+    {
+	creat(lockfile, 0000);
+	return TRUE;
+    }
+    if (time(NULL) - sbuf.st_mtime > 10)
+    {
+	if (md_unlink(lockfile) < 0)
+	    return FALSE;
+	goto over;
+    }
+    else
+    {
+	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 (prbuf[0] == 'y')
+	    for (;;)
+	    {
+		if (creat(lockfile, 0000) > 0)
+		    return TRUE;
+		if (stat(lockfile, &sbuf) < 0)
+		{
+		    creat(lockfile, 0000);
+		    return TRUE;
+		}
+		if (time(NULL) - sbuf.st_mtime > 10)
+		{
+		    if (md_unlink(lockfile) < 0)
+			return FALSE;
+		}
+		md_sleep(1);
+	    }
+	else
+	    return FALSE;
+    }
+#endif
+#endif
+}
+
+/*
+ * unlock_sc:
+ *	Unlock the score file
+ */
+unlock_sc()
+{
+#ifdef SCOREFILE
+#ifdef LOCKFILE
+    md_unlink(lockfile);
+#endif
+#endif
+}
+
+/*
+ * flush_type:
+ *	Flush typeahead for traps, etc.
+ */
+flush_type()
+{
+    flushinp();
+}