]> git.cameronkatri.com Git - bsdgames-darwin.git/blobdiff - rogue/machdep.c
Revert arc4random usage for now
[bsdgames-darwin.git] / rogue / machdep.c
index baedb47bed773179d42955c19393cdf84ad8081e..e6d6292deb09d1a9dd1ca4ac959644ff3a1e45aa 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: machdep.c,v 1.3 1995/04/22 10:27:39 cgd Exp $  */
+/*     $NetBSD: machdep.c,v 1.20 2012/12/01 11:37:27 mbalmer Exp $     */
 
 /*
  * Copyright (c) 1988, 1993
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
  * SUCH DAMAGE.
  */
 
+#include <sys/cdefs.h>
 #ifndef lint
 #if 0
 static char sccsid[] = "@(#)machdep.c  8.1 (Berkeley) 5/31/93";
 #else
-static char rcsid[] = "$NetBSD: machdep.c,v 1.3 1995/04/22 10:27:39 cgd Exp $";
+__RCSID("$NetBSD: machdep.c,v 1.20 2012/12/01 11:37:27 mbalmer Exp $");
 #endif
 #endif /* not lint */
 
@@ -66,7 +63,7 @@ static char rcsid[] = "$NetBSD: machdep.c,v 1.3 1995/04/22 10:27:39 cgd Exp $";
  *
  * All UNIX code should be included between the single "#ifdef UNIX" at the
  * top of this file, and the "#endif" at the bottom.
- * 
+ *
  * To change a routine to include a new UNIX system, simply #ifdef the
  * existing routine, as in the following example:
  *
@@ -87,7 +84,7 @@ static char rcsid[] = "$NetBSD: machdep.c,v 1.3 1995/04/22 10:27:39 cgd Exp $";
  *      #endif
  *      }
  *
- * Appropriate variations of this are of course acceptible.
+ * Appropriate variations of this are of course acceptable.
  * The use of "#elseif" is discouraged because of non-portability.
  * If the correct #define doesn't exist, "UNIX_SYSV" in this case, make it up
  * and insert it in the list at the top of the file.  Alter the CFLAGS
@@ -97,23 +94,24 @@ static char rcsid[] = "$NetBSD: machdep.c,v 1.3 1995/04/22 10:27:39 cgd Exp $";
 
 #ifdef UNIX
 
-#include <stdio.h>
 #include <sys/types.h>
+#include <sys/wait.h>
 #include <sys/file.h>
 #include <sys/stat.h>
 #include <pwd.h>
 
 #ifdef UNIX_BSD4_2
 #include <sys/time.h>
-#include <sgtty.h>
 #endif
 
 #ifdef UNIX_SYSV
 #include <time.h>
-#include <termio.h>
 #endif
 
 #include <signal.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
 #include "rogue.h"
 #include "pathnames.h"
 
@@ -129,82 +127,12 @@ static char rcsid[] = "$NetBSD: machdep.c,v 1.3 1995/04/22 10:27:39 cgd Exp $";
  * big deal.
  */
 
-md_slurp()
+void
+md_slurp(void)
 {
        (void)fpurge(stdin);
 }
 
-/* md_control_keyboard():
- *
- * This routine is much like md_cbreak_no_echo_nonl() below.  It sets up the
- * keyboard for appropriate input.  Specifically, it prevents the tty driver
- * from stealing characters.  For example, ^Y is needed as a command
- * character, but the tty driver intercepts it for another purpose.  Any
- * such behavior should be stopped.  This routine could be avoided if
- * we used RAW mode instead of CBREAK.  But RAW mode does not allow the
- * generation of keyboard signals, which the program uses.
- *
- * The parameter 'mode' when true, indicates that the keyboard should
- * be set up to play rogue.  When false, it should be restored if
- * necessary.
- *
- * This routine is not strictly necessary and may be stubbed.  This may
- * cause certain command characters to be unavailable.
- */
-
-md_control_keybord(mode)
-boolean mode;
-{
-       static boolean called_before = 0;
-#ifdef UNIX_BSD4_2
-       static struct ltchars ltc_orig;
-       static struct tchars tc_orig;
-       struct ltchars ltc_temp;
-       struct tchars tc_temp;
-#endif
-#ifdef UNIX_SYSV
-       static struct termio _oldtty;
-       struct termio _tty;
-#endif
-
-       if (!called_before) {
-               called_before = 1;
-#ifdef UNIX_BSD4_2
-               ioctl(0, TIOCGETC, &tc_orig);
-               ioctl(0, TIOCGLTC, &ltc_orig);
-#endif
-#ifdef UNIX_SYSV
-               ioctl(0, TCGETA, &_oldtty);
-#endif
-       }
-#ifdef UNIX_BSD4_2
-       ltc_temp = ltc_orig;
-       tc_temp = tc_orig;
-#endif
-#ifdef UNIX_SYSV
-       _tty = _oldtty;
-#endif
-
-       if (!mode) {
-#ifdef UNIX_BSD4_2
-               ltc_temp.t_suspc = ltc_temp.t_dsuspc = -1;
-               ltc_temp.t_rprntc = ltc_temp.t_flushc = -1;
-               ltc_temp.t_werasc = ltc_temp.t_lnextc = -1;
-               tc_temp.t_startc = tc_temp.t_stopc = -1;
-#endif
-#ifdef UNIX_SYSV
-               _tty.c_cc[VSWTCH] = CNSWTCH;
-#endif
-       }
-#ifdef UNIX_BSD4_2
-       ioctl(0, TIOCSETC, &tc_temp);
-       ioctl(0, TIOCSLTC, &ltc_temp);
-#endif
-#ifdef UNIX_SYSV
-       ioctl(0, TCSETA, &_tty);
-#endif
-}
-
 /* md_heed_signals():
  *
  * This routine tells the program to call particular routines when
@@ -221,7 +149,8 @@ boolean mode;
  * input, this is not usually critical.
  */
 
-md_heed_signals()
+void
+md_heed_signals(void)
 {
        signal(SIGINT, onintr);
        signal(SIGQUIT, byebye);
@@ -240,7 +169,8 @@ md_heed_signals()
  * file, corruption.
  */
 
-md_ignore_signals()
+void
+md_ignore_signals(void)
 {
        signal(SIGQUIT, SIG_IGN);
        signal(SIGINT, SIG_IGN);
@@ -257,15 +187,14 @@ md_ignore_signals()
  */
 
 int
-md_get_file_id(fname)
-char *fname;
+md_get_file_id(const char *fname)
 {
        struct stat sbuf;
 
        if (stat(fname, &sbuf)) {
                return(-1);
        }
-       return((int) sbuf.st_ino);
+       return((int)sbuf.st_ino);
 }
 
 /* md_link_count():
@@ -277,13 +206,12 @@ char *fname;
  */
 
 int
-md_link_count(fname)
-char *fname;
+md_link_count(const char *fname)
 {
        struct stat sbuf;
 
        stat(fname, &sbuf);
-       return((int) sbuf.st_nlink);
+       return((int)sbuf.st_nlink);
 }
 
 /* md_gct(): (Get Current Time)
@@ -297,14 +225,14 @@ char *fname;
  * system doesn't provide all of the time units requested here, then you
  * can provide only those that it does, and return zeros for the others.
  * If you cannot provide good time values, then users may be able to copy
- * saved-game files and play them.  
+ * saved-game files and play them.
  */
 
-md_gct(rt_buf)
-struct rogue_time *rt_buf;
+void
+md_gct(struct rogue_time *rt_buf)
 {
-       struct tm *t, *localtime();
-       long seconds;
+       struct tm *t;
+       time_t seconds;
 
        time(&seconds);
        t = localtime(&seconds);
@@ -328,21 +256,20 @@ struct rogue_time *rt_buf;
  * exactly the same here.
  * Or if md_gct() is implemented correctly, but your system does not provide
  * file modification dates, you may return some date far in the past so
- * that the program will never know that a saved-game file being modified.  
+ * that the program will never know that a saved-game file being modified.
  * You may also do this if you wish to be able to restore games from
  * saved-games that have been modified.
  */
 
-md_gfmt(fname, rt_buf)
-char *fname;
-struct rogue_time *rt_buf;
+void
+md_gfmt(const char *fname, struct rogue_time *rt_buf)
 {
        struct stat sbuf;
-       long seconds;
+       time_t seconds;
        struct tm *t;
 
        stat(fname, &sbuf);
-       seconds = (long) sbuf.st_mtime;
+       seconds = sbuf.st_mtime;
        t = localtime(&seconds);
 
        rt_buf->year = t->tm_year;
@@ -365,8 +292,7 @@ struct rogue_time *rt_buf;
  */
 
 boolean
-md_df(fname)
-char *fname;
+md_df(const char *fname)
 {
        if (unlink(fname)) {
                return(0);
@@ -383,14 +309,14 @@ char *fname;
  * function, but then the score file would only have one name in it.
  */
 
-char *
-md_gln()
+const char *
+md_gln(void)
 {
        struct passwd *p;
 
        if (!(p = getpwuid(getuid())))
-               return((char *)NULL);
-       return(p->pw_name);
+               return NULL;
+       return p->pw_name;
 }
 
 /* md_sleep:
@@ -402,10 +328,10 @@ md_gln()
  * delaying execution, which is useful to this program at some times.
  */
 
-md_sleep(nsecs)
-int nsecs;
+void
+md_sleep(int nsecs)
 {
-       (void) sleep(nsecs);
+       (void)sleep(nsecs);
 }
 
 /* md_getenv()
@@ -414,17 +340,6 @@ int nsecs;
  * values are strings, and each string is identified by a name.  The names
  * of the values needed, and their use, is as follows:
  *
- *   TERMCAP
- *     The name of the users's termcap file, NOT the termcap entries
- *     themselves.  This is used ONLY if the program is compiled with
- *     CURSES defined (-DCURSES).  Even in this case, the program need
- *     not find a string for TERMCAP.  If it does not, it will use the
- *     default termcap file as returned by md_gdtcf();
- *   TERM
- *     The name of the users's terminal.  This is used ONLY if the program
- *     is compiled with CURSES defined (-DCURSES).  In this case, the string
- *     value for TERM must be found, or the routines in curses.c cannot
- *     function, and the program will quit.
  *   ROGUEOPTS
  *     A string containing the various game options.  This need not be
  *     defined.
@@ -437,20 +352,15 @@ int nsecs;
  *
  * If your system does not provide a means of searching for these values,
  * you will have to do it yourself.  None of the values above really need
- * to be defined except TERM when the program is compiled with CURSES
- * defined.  In this case, as a bare minimum, you can check the 'name'
- * parameter, and if it is "TERM" find the terminal name and return that,
- * else return zero.  If the program is not compiled with CURSES, you can
- * get by with simply always returning zero.  Returning zero indicates
- * that their is no defined value for the given string.
+ * to be defined; you can get by with simply always returning zero.
+ * Returning zero indicates that their is no defined value for the
+ * given string.
  */
 
 char *
-md_getenv(name)
-char *name;
+md_getenv(const char *name)
 {
        char *value;
-       char *getenv();
 
        value = getenv(name);
 
@@ -465,11 +375,9 @@ char *name;
  * when no more memory can be allocated.
  */
 
-char *
-md_malloc(n)
-int n;
+void *
+md_malloc(size_t n)
 {
-       char *malloc();
        char *t;
 
        t = malloc(n);
@@ -479,7 +387,7 @@ int n;
 /* md_gseed() (Get Seed)
  *
  * This function returns a seed for the random number generator (RNG).  This
- * seed causes the RNG to begin generating numbers at some point in it's
+ * seed causes the RNG to begin generating numbers at some point in its
  * sequence.  Without a random seed, the RNG will generate the same set
  * of numbers, and every game will start out exactly the same way.  A good
  * number to use is the process id, given by getpid() on most UNIX systems.
@@ -487,16 +395,20 @@ int n;
  * You need to find some single random integer, such as:
  *   process id.
  *   current time (minutes + seconds) returned from md_gct(), if implemented.
- *   
+ *
  * It will not help to return "get_rand()" or "rand()" or the return value of
  * any pseudo-RNG.  If you don't have a random number, you can just return 1,
  * but this means your games will ALWAYS start the same way, and will play
  * exactly the same way given the same input.
  */
 
-md_gseed()
+int
+md_gseed(void)
 {
-       return(getpid());
+       time_t seconds;
+
+       time(&seconds);
+       return((int)seconds);
 }
 
 /* md_exit():
@@ -506,8 +418,8 @@ md_gseed()
  * hang when it should quit.
  */
 
-md_exit(status)
-int status;
+void
+md_exit(int status)
 {
        exit(status);
 }
@@ -523,22 +435,25 @@ int status;
  * the lock is released.
  */
 
-md_lock(l)
-boolean l;
+void
+md_lock(boolean l)
 {
-       static int fd;
+       static int fd = -1;
        short tries;
 
        if (l) {
+               setegid(egid);
                if ((fd = open(_PATH_SCOREFILE, O_RDONLY)) < 1) {
-                       message("cannot lock score file", 0);
+                       setegid(gid);
+                       messagef(0, "cannot lock score file");
                        return;
                }
+               setegid(gid);
                for (tries = 0; tries < 5; tries++)
                        if (!flock(fd, LOCK_EX|LOCK_NB))
                                return;
        } else {
-               (void)flock(fd, LOCK_NB);
+               (void)flock(fd, LOCK_UN|LOCK_NB);
                (void)close(fd);
        }
 }
@@ -546,135 +461,32 @@ boolean l;
 /* md_shell():
  *
  * This function spawns a shell for the user to use.  When this shell is
- * terminated, the game continues.  Since this program may often be run
- * setuid to gain access to privileged files, care is taken that the shell
- * is run with the user's REAL user id, and not the effective user id.
- * The effective user id is restored after the shell completes.
- */
-
-md_shell(shell)
-char *shell;
-{
-       long w[2];
-
-       if (!fork()) {
-               int uid;
-
-               uid = getuid();
-               setuid(uid);
-               execl(shell, shell, 0);
-       }
-       wait(w);
-}
-
-/* If you have a viable curses/termlib library, then use it and don't bother
- * implementing the routines below.  And don't compile with -DCURSES.
- */
-
-#ifdef CURSES
-
-/* md_cbreak_no_echo_nonl:
- *
- * This routine sets up some terminal characteristics.  The tty-driver
- * must be told to:
- *   1.)  Not echo input.
- *   2.)  Transmit input characters immediately upon typing. (cbreak mode)
- *   3.)  Move the cursor down one line, without changing column, and
- *        without generating a carriage-return, when it
- *        sees a line-feed.  This is only necessary if line-feed is ever
- *        used in the termcap 'do' (cursor down) entry, in which case,
- *        your system should must have a way of accomplishing this.
- *
- * When the parameter 'on' is true, the terminal is set up as specified
- * above.  When this parameter is false, the terminal is restored to the
- * original state.
- *
- * Raw mode should not to be used.  Keyboard signals/events/interrupts should
- * be sent, although they are not strictly necessary.  See notes in
- * md_heed_signals().
- *
- * This function must be implemented for rogue to run properly if the
- * program is compiled with CURSES defined to use the enclosed curses
- * emulation package.  If you are not using this, then this routine is
- * totally unnecessary.
- * 
- * Notice that information is saved between calls.  This is used to
- * restore the terminal to an initial saved state.
+ * terminated, the game continues.
  *
+ * It is important that the game not give the shell the privileges the
+ * game uses to access the scores file. This version of the game runs
+ * with privileges low by default; only the saved gid (if setgid) or uid
+ * (if setuid) will be privileged, but that privilege is discarded by
+ * exec().
  */
 
-md_cbreak_no_echo_nonl(on)
-boolean on;
+void
+md_shell(const char *shell)
 {
-#ifdef UNIX_BSD4_2
-       static struct sgttyb tty_buf;
-       static int tsave_flags;
-
-       if (on) {
-               ioctl(0, TIOCGETP, &tty_buf);
-               tsave_flags = tty_buf.sg_flags;
-               tty_buf.sg_flags |= CBREAK;
-               tty_buf.sg_flags &= ~(ECHO | CRMOD);    /* CRMOD: see note 3 above */
-               ioctl(0, TIOCSETP, &tty_buf);
-       } else {
-               tty_buf.sg_flags = tsave_flags;
-               ioctl(0, TIOCSETP, &tty_buf);
+       int w;
+       pid_t pid;
+
+       pid = fork();
+       switch (pid) {
+       case -1:
+               break;
+       case 0:
+               execl(shell, shell, (char *)NULL);
+               _exit(255);
+       default:
+               waitpid(pid, &w, 0);
+               break;
        }
-#endif
-#ifdef UNIX_SYSV
-       struct termio tty_buf;
-       static struct termio tty_save;
-
-       if (on) {
-               ioctl(0, TCGETA, &tty_buf);
-               tty_save = tty_buf;
-               tty_buf.c_lflag &= ~(ICANON | ECHO);
-               tty_buf.c_oflag &= ~ONLCR;
-               tty_buf.c_cc[4] = 1;  /* MIN */
-               tty_buf.c_cc[5] = 2;  /* TIME */
-               ioctl(0, TCSETAF, &tty_buf);
-       } else {
-               ioctl(0, TCSETAF, &tty_save);
-       }
-#endif
 }
 
-/* md_gdtcf(): (Get Default Termcap File)
- *
- * This function is called ONLY when the program is compiled with CURSES
- * defined.  If you use your system's curses/termlib library, this function
- * won't be called.  On most UNIX systems, "/etc/termcap" suffices.
- *
- * If their is no such termcap file, then return 0, but in that case, you
- * must have a TERMCAP file returned from md_getenv("TERMCAP").  The latter
- * will override the value returned from md_gdtcf().  If the program is
- * compiled with CURSES defined, and md_gdtcf() returns 0, and
- * md_getenv("TERMCAP") returns 0, the program will have no terminal
- * capability information and will quit.
- */
-
-char *
-md_gdtcf()
-{
-       return("/etc/termcap");
-}
-
-/* md_tstp():
- *
- * This function puts the game to sleep and returns to the shell.  This
- * only applies to UNIX 4.2 and 4.3.  For other systems, the routine should
- * be provided as a do-nothing routine.  md_tstp() will only be referenced
- * in the code when compiled with CURSES defined.
- *
- */
-
-md_tstp()
-{
-#ifdef UNIX_BSD4_2
-       kill(0, SIGTSTP);
-#endif
-}
-
-#endif
-
-#endif
+#endif /* UNIX */