changeset 118:8d1dfc5a912c

srogue: add a complete mdport.c. srogue/mdport.c is copied from rogue5/mdport.c, with slight changes.
author John "Elwin" Edwards
date Sun, 27 Apr 2014 08:29:14 -0700
parents 2c62bd925c17
children 458df24e973d
files srogue/configure.ac srogue/mdport.c srogue/rogue.h
diffstat 3 files changed, 908 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/srogue/configure.ac	Sat Apr 26 08:52:26 2014 -0700
+++ b/srogue/configure.ac	Sun Apr 27 08:29:14 2014 -0700
@@ -12,7 +12,7 @@
 MP_WITH_CURSES
 # Checks for header files.
 AC_HEADER_STDC
-#AC_CHECK_HEADERS([arpa/inet.h pwd.h errno.h fcntl.h limits.h nlist.h stdlib.h string.h sys/ioctl.h termios.h unistd.h utmp.h utmpx.h term.h ncurses/term.h process.h])
+AC_CHECK_HEADERS([arpa/inet.h pwd.h errno.h fcntl.h limits.h nlist.h stdlib.h string.h sys/ioctl.h termios.h unistd.h term.h ncurses/term.h process.h])
 
 # Checks for typedefs, structures, and compiler characteristics.
 AC_TYPE_SIZE_T
@@ -23,7 +23,7 @@
 AC_TYPE_SIGNAL
 AC_FUNC_STAT
 AC_FUNC_VPRINTF
-#AC_CHECK_FUNCS([erasechar killchar alarm getpass memset setenv strchr nlist _spawnl spawnl getpwuid loadav getloadavg strerror setgid setuid getuid getgid])
+AC_CHECK_FUNCS([erasechar killchar alarm getpass memset setenv strchr nlist _spawnl spawnl getpwuid loadav getloadavg strerror setgid setuid getuid getgid])
 AC_PROG_INSTALL
 
 AC_ARG_WITH(program-name, AC_HELP_STRING([--with-program-name=NAME],[alternate executable name]),[progname="$withval" ], [progname="srogue"] )
--- a/srogue/mdport.c	Sat Apr 26 08:52:26 2014 -0700
+++ b/srogue/mdport.c	Sun Apr 27 08:29:14 2014 -0700
@@ -29,11 +29,6 @@
     SUCH DAMAGE.
 */
 
-/* This is a temporary stub version of rogue5's mdport.c.  It is only to make 
- * md_readchar() available until srogue is ported to autoconf.  Then the 
- * whole file should work.
- */
-
 #include <stdlib.h>
 #include <string.h>
 
@@ -49,12 +44,758 @@
 #undef MOUSE_MOVED
 #endif
 
+#include <curses.h>
+#include "rogue.h"
+
+#if defined(HAVE_SYS_TYPES)
 #include <sys/types.h>
+#endif
+
+#if defined(HAVE_PROCESS_H)
+#include <process.h>
+#endif
+
+#if defined(HAVE_PWD_H)
+#include <pwd.h>
+#endif
+
+#if defined(HAVE_SYS_UTSNAME)
+#include <sys/utsname.h>
+#endif
+
+#if defined(HAVE_ARPA_INET_H)
+#include <arpa/inet.h> /* Solaris 2.8 required this for htonl() and ntohl() */
+#endif
+
+#if defined(HAVE_TERMIOS_H)
+#include <termios.h>
+#endif
+
+#if defined(HAVE_UNISTD_H)
+#ifndef __USE_GNU
+#define __USE_GNU
+#include <unistd.h>
+#undef __USE_GNU
+#else
+#include <unistd.h>
+#endif
+#endif
 
 #include <curses.h> /* AIX requires curses.h be included before term.h */
 
+#if defined(HAVE_TERM_H)
+#include <term.h>
+#elif defined(HAVE_NCURSES_TERM_H)
+#include <ncurses/term.h>
+#endif
+
+#if defined(HAVE_WORKING_FORK)
+#include <sys/wait.h>
+#endif
+
 #include <ctype.h>
-#include "rogue.h"
+#include <fcntl.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <signal.h>
+
+#if !defined(PATH_MAX) && defined(_MAX_PATH)
+#define PATH_MAX _MAX_PATH
+#endif
+
+#if !defined(PATH_MAX) && defined(_PATH_MAX)
+#define PATH_MAX _PATH_MAX
+#endif
+
+#define NOOP(x) (x += 0)
+
+void
+md_init(void)
+{
+#if defined(__INTERIX)
+    char *term;
+
+    term = getenv("TERM");
+
+    if (term == NULL)
+        setenv("TERM","interix");
+#elif defined(__DJGPP__)
+    _fmode = _O_BINARY;
+#elif defined(_WIN32)
+    _fmode = _O_BINARY;
+#endif
+
+#if defined(HAVE_ESCDELAY) || defined(NCURSES_VERSION)
+    ESCDELAY=64;
+#endif
+
+#if defined(DUMP)
+	md_onsignal_default();
+#else
+	md_onsignal_exit();
+#endif
+}
+
+void
+md_onsignal_default(void)
+{
+#ifdef SIGHUP
+    signal(SIGHUP, SIG_DFL);
+#endif
+#ifdef SIGQUIT
+    signal(SIGQUIT, SIG_DFL);
+#endif
+#ifdef SIGILL
+    signal(SIGILL, SIG_DFL);
+#endif
+#ifdef SIGTRAP
+    signal(SIGTRAP, SIG_DFL);
+#endif
+#ifdef SIGIOT
+    signal(SIGIOT, SIG_DFL);
+#endif
+#ifdef SIGEMT
+    signal(SIGEMT, SIG_DFL);
+#endif
+#ifdef SIGFPE
+    signal(SIGFPE, SIG_DFL);
+#endif
+#ifdef SIGBUS
+    signal(SIGBUS, SIG_DFL);
+#endif
+#ifdef SIGSEGV
+    signal(SIGSEGV, SIG_DFL);
+#endif
+#ifdef SIGSYS
+    signal(SIGSYS, SIG_DFL);
+#endif
+#ifdef SIGTERM
+    signal(SIGTERM, SIG_DFL);
+#endif
+}
+
+void
+md_onsignal_exit(void)
+{
+#ifdef SIGHUP
+    signal(SIGHUP, SIG_DFL);
+#endif
+#ifdef SIGQUIT
+    signal(SIGQUIT, exit);
+#endif
+#ifdef SIGILL
+    signal(SIGILL, exit);
+#endif
+#ifdef SIGTRAP
+    signal(SIGTRAP, exit);
+#endif
+#ifdef SIGIOT
+    signal(SIGIOT, exit);
+#endif
+#ifdef SIGEMT
+    signal(SIGEMT, exit);
+#endif
+#ifdef SIGFPE
+    signal(SIGFPE, exit);
+#endif
+#ifdef SIGBUS
+    signal(SIGBUS, exit);
+#endif
+#ifdef SIGSEGV
+    signal(SIGSEGV, exit);
+#endif
+#ifdef SIGSYS
+    signal(SIGSYS, exit);
+#endif
+#ifdef SIGTERM
+    signal(SIGTERM, exit);
+#endif
+}
+
+extern void auto_save(int sig);
+extern void endit(int sig);
+extern void quit(int sig);
+
+void
+md_onsignal_autosave(void)
+{
+
+#ifdef SIGHUP
+    signal(SIGHUP, auto_save);
+#endif
+#ifdef SIGQUIT
+	signal(SIGQUIT, endit);
+#endif
+#ifdef SIGILL
+    signal(SIGILL, auto_save);
+#endif
+#ifdef SIGTRAP
+    signal(SIGTRAP, auto_save);
+#endif
+#ifdef SIGIOT
+    signal(SIGIOT, auto_save);
+#endif
+#ifdef SIGEMT
+    signal(SIGEMT, auto_save);
+#endif
+#ifdef SIGFPE
+    signal(SIGFPE, auto_save);
+#endif
+#ifdef SIGBUS
+    signal(SIGBUS, auto_save);
+#endif
+#ifdef SIGSEGV
+    signal(SIGSEGV, auto_save);
+#endif
+#ifdef SIGSYS
+    signal(SIGSYS, auto_save);
+#endif
+#ifdef SIGTERM
+    signal(SIGTERM, auto_save);
+#endif
+#ifdef SIGINT
+    signal(SIGINT, quit);
+#endif
+}
+
+int
+md_hasclreol(void)
+{
+#if defined(clr_eol)
+#ifdef NCURSES_VERSION
+    if (cur_term == NULL)
+	return(0);
+    if (cur_term->type.Strings == NULL)
+	return(0);
+#endif
+    return((clr_eol != NULL) && (*clr_eol != 0));
+#elif defined(__PDCURSES__)
+    return(TRUE);
+#else
+    return((CE != NULL) && (*CE != 0));
+#endif
+}
+
+void
+md_putchar(int c)
+{
+    putchar(c);
+}
+
+#ifdef _WIN32
+static int md_standout_mode = 0;
+#endif
+
+void
+md_raw_standout(void)
+{
+#ifdef _WIN32
+    CONSOLE_SCREEN_BUFFER_INFO csbiInfo; 
+    HANDLE hStdout;
+    WORD fgattr,bgattr;
+
+    if (md_standout_mode == 0)
+    {
+        hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 
+        GetConsoleScreenBufferInfo(hStdout, &csbiInfo);
+        fgattr = (csbiInfo.wAttributes & 0xF);
+        bgattr = (csbiInfo.wAttributes & 0xF0);
+        SetConsoleTextAttribute(hStdout,(fgattr << 4) | (bgattr >> 4));
+        md_standout_mode = 1;
+    }
+#elif defined(SO)
+    tputs(SO,0,md_putchar);
+    fflush(stdout);
+#endif
+}
+
+void
+md_raw_standend(void)
+{
+#ifdef _WIN32
+    CONSOLE_SCREEN_BUFFER_INFO csbiInfo; 
+    HANDLE hStdout;
+    WORD fgattr,bgattr;
+
+    if (md_standout_mode == 1)
+    {
+        hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 
+        GetConsoleScreenBufferInfo(hStdout, &csbiInfo);
+        fgattr = (csbiInfo.wAttributes & 0xF);
+        bgattr = (csbiInfo.wAttributes & 0xF0);
+        SetConsoleTextAttribute(hStdout,(fgattr << 4) | (bgattr >> 4));
+        md_standout_mode = 0;
+    }
+#elif defined(SE)
+    tputs(SE,0,md_putchar);
+    fflush(stdout);
+#endif
+}
+
+int
+md_unlink_open_file(const char *file, FILE *inf)
+{
+#ifdef _WIN32
+    fclose(inf);
+    (void) _chmod(file, 0600);
+    return( _unlink(file) );
+#else
+    return(unlink(file));
+#endif
+}
+
+int
+md_unlink(char *file)
+{
+#ifdef _WIN32
+    (void) _chmod(file, 0600);
+    return( _unlink(file) );
+#else
+    return(unlink(file));
+#endif
+}
+
+int
+md_chmod(const char *filename, int mode)
+{
+#ifdef _WIN32
+    return( _chmod(filename, mode) );
+#else
+    return( chmod(filename, mode) );
+#endif
+}
+
+void
+md_normaluser(void)
+{
+#if defined(HAVE_GETGID) && defined(HAVE_GETUID)
+	gid_t realgid = getgid();
+	uid_t realuid = getuid();
+
+#if defined(HAVE_SETRESGID)
+    if (setresgid(-1, realgid, realgid) != 0) {
+#elif defined (HAVE_SETREGID) 
+    if (setregid(realgid, realgid) != 0) {
+#elif defined (HAVE_SETGID)
+	if (setgid(realgid) != 0) {
+#else
+	if (0) {
+#endif
+		perror("Could not drop setgid privileges.  Aborting.");
+		exit(1);
+    }
+
+#if defined(HAVE_SETRESUID)
+    if (setresuid(-1, realuid, realuid) != 0) {
+#elif defined(HAVE_SETREUID)
+    if (setreuid(realuid, realuid) != 0) {
+#elif defined(HAVE_SETUID)
+	if (setuid(realuid) != 0) {
+#else
+	if (0) {
+#endif
+	perror("Could not drop setuid privileges.  Aborting.");
+	exit(1);
+    }
+#endif
+}
+
+uid_t
+md_getuid(void)
+{
+#ifdef HAVE_GETUID
+    return( getuid() );
+#else
+    return(42);
+#endif
+}
+
+pid_t
+md_getpid(void)
+{
+#ifdef _WIN32
+    return( _getpid() );
+#else
+    return( getpid() );
+#endif
+}
+
+char *
+md_getusername(void)
+{
+    static char login[80];
+    char *l = NULL;
+
+    /* POSIX Shell has priority, then O/S specific methods */
+    if ( (l = getenv("LOGNAME")) != NULL )
+    {
+        strncpy(login,l,80);
+        login[79] = 0;
+        return(login);
+    }
+
+#ifdef _WIN32
+    LPSTR mybuffer;
+    DWORD size = UNLEN + 1;
+    TCHAR buffer[UNLEN + 1];
+
+    mybuffer = buffer;
+    GetUserName(mybuffer,&size);
+    l = mybuffer;
+#elif defined(HAVE_GETPWUID)&& !defined(__DJGPP__)
+    struct passwd *pw;
+
+    pw = getpwuid(getuid());
+
+    if (pw != NULL)
+        l = pw->pw_name;
+    else
+        l = NULL;
+#endif
+
+    if ((l == NULL) || (*l == '\0'))
+        if ( (l = getenv("USERNAME")) == NULL )
+            if ( (l = getenv("LOGNAME")) == NULL )
+                if ( (l = getenv("USER")) == NULL )
+                    l = "nobody";
+
+    strncpy(login,l,80);
+    login[79] = 0;
+
+    return(login);
+}
+
+char *
+md_gethomedir(void)
+{
+    static char homedir[PATH_MAX];
+    char *h = NULL;
+    size_t len;
+#if defined(_WIN32)
+    TCHAR szPath[PATH_MAX];
+#endif
+#if defined(_WIN32) || defined(DJGPP)
+        char slash = '\\';
+#else
+    char slash = '/';
+    struct passwd *pw;
+    pw = getpwuid(getuid());
+
+    if (pw != NULL)
+        h = pw->pw_dir;
+    else
+        h = "";
+
+    if (strcmp(h,"/") == 0)
+        h = "";
+#endif
+    homedir[0] = 0;
+#ifdef _WIN32
+    if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, szPath)))
+        h = szPath;
+#endif
+
+    if ( (h == NULL) || (*h == '\0') )
+    {
+        if ( (h = getenv("HOME")) == NULL )
+	{
+            if ( (h = getenv("HOMEDRIVE")) == NULL)
+                h = "";
+            else
+            {
+                strncpy(homedir,h,PATH_MAX-1);
+                homedir[PATH_MAX-1] = 0;
+
+                if ( (h = getenv("HOMEPATH")) == NULL)
+                    h = "";
+            }
+	}
+    }
+
+
+    len = strlen(homedir);
+    strncat(homedir,h,PATH_MAX-len-1);
+    len = strlen(homedir);
+
+    if ((len > 0) && (homedir[len-1] != slash)) {
+        homedir[len] = slash;
+        homedir[len+1] = 0;
+    }
+
+    return(homedir);
+}
+
+void
+md_sleep(int s)
+{
+#ifdef _WIN32
+    Sleep(s);
+#else
+    sleep(s);
+#endif
+}
+
+char *
+md_getshell(void)
+{
+    static char shell[PATH_MAX];
+    char *s = NULL;
+#ifdef _WIN32
+    char *def = "C:\\WINDOWS\\SYSTEM32\\CMD.EXE";
+#elif defined(__DJGPP__)
+    char *def = "C:\\COMMAND.COM";
+#else
+    char *def = "/bin/sh";
+    struct passwd *pw;
+    pw = getpwuid(getuid());
+    if (pw != NULL)
+        s = pw->pw_shell;
+#endif
+    if ((s == NULL) || (*s == '\0'))
+        if ( (s = getenv("COMSPEC")) == NULL)
+            if ( (s = getenv("SHELL")) == NULL)
+                if ( (s = getenv("SystemRoot")) == NULL)
+                    s = def;
+
+    strncpy(shell,s,PATH_MAX);
+    shell[PATH_MAX-1] = 0;
+
+    return(shell);
+}
+
+int
+md_shellescape(void)
+{
+#if defined(HAVE_WORKING_FORK)
+    int ret_status;
+    int pid;
+    void (*myquit)(int);
+    void (*myend)(int);
+    char *sh;
+
+    sh = md_getshell();
+
+    while((pid = fork()) < 0)
+        sleep(1);
+
+    if (pid == 0) /* Shell Process */
+    {
+        /*
+         * Set back to original user, just in case
+         */
+        md_normaluser();
+        execl(sh == NULL ? "/bin/sh" : sh, "shell", "-i", NULL);
+        perror("No shelly");
+        _exit(-1);
+    }
+    else /* Application */
+    {
+    	myend = signal(SIGINT, SIG_IGN);
+#ifdef SIGQUIT
+        myquit = signal(SIGQUIT, SIG_IGN);
+#endif  
+        while (wait(&ret_status) != pid)
+            continue;
+	    
+        signal(SIGINT, myquit);
+#ifdef SIGQUIT
+        signal(SIGQUIT, myend);
+#endif
+    }
+    return(ret_status);
+#elif defined(HAVE__SPAWNL) 
+    return((int)_spawnl(_P_WAIT,md_getshell(),"shell",NULL,0));
+#elif defined(HAVE_SPAWNL)
+    return ( spawnl(P_WAIT,md_getshell(),"shell",NULL,0) );
+#else
+	return(0);
+#endif
+}
+
+char *
+md_getrealname(uid_t uid)
+{
+    static char uidstr[20];
+#if !defined(_WIN32) && !defined(DJGPP)
+    struct passwd *pp;
+
+	if ((pp = getpwuid(uid)) == NULL)
+    {
+        sprintf(uidstr,"%d", uid);
+        return(uidstr);
+    }
+	else
+	    return(pp->pw_name);
+#else
+   sprintf(uidstr,"%ld", uid);
+   return(uidstr);
+#endif
+}
+
+char *
+md_crypt(const char *key, const char *salt)
+{
+    return( xcrypt(key,salt) );
+}
+
+char *
+md_getpass(char *prompt)
+{
+#ifndef HAVE_GETPASS
+    static char password_buffer[9];
+    char *p = password_buffer;
+    int c, count = 0;
+    int max_length = 9;
+
+    fflush(stdout);
+    /* If we can't prompt, abort */
+    if (fputs(prompt, stderr) < 0)
+    {
+        *p = '\0';
+        return NULL;
+    }
+
+    for(;;)
+    {
+        /* Get a character with no echo */
+        c = _getch();
+
+        /* Exit on interrupt (^c or ^break) */
+        if (c == '\003' || c == 0x100)
+            exit(1);
+
+        /* Terminate on end of line or file (^j, ^m, ^d, ^z) */
+        if (c == '\r' || c == '\n' || c == '\004' || c == '\032')
+            break;
+
+        /* Back up on backspace */
+        if (c == '\b')
+        {
+            if (count)
+                count--;
+            else if (p > password_buffer)
+                p--;
+            continue;
+        }
+
+        /* Ignore DOS extended characters */
+        if ((c & 0xff) != c)
+            continue;
+
+        /* Add to password if it isn't full */
+        if (p < password_buffer + max_length - 1)
+            *p++ = (char) c;
+        else
+            count++;
+    }
+   *p = '\0';
+
+   fputc('\n', stderr);
+
+   return password_buffer;
+#else
+   return( getpass(prompt) );
+#endif
+}
+
+int
+md_erasechar(void)
+{
+#ifdef HAVE_ERASECHAR
+    return( erasechar() ); /* process erase character */
+#elif defined(VERASE)
+    return(_tty.c_cc[VERASE]); /* process erase character */
+#else
+    return(_tty.sg_erase); /* process erase character */
+#endif
+}
+
+int
+md_killchar(void)
+{
+#ifdef HAVE_KILLCHAR
+    return( killchar() );
+#elif defined(VKILL)
+    return(_tty.c_cc[VKILL]);
+#else
+    return(_tty.sg_kill);
+#endif
+}
+
+int
+md_dsuspchar(void)
+{
+#if defined(VDSUSP)			/* POSIX has priority */
+    struct termios attr;
+    tcgetattr(STDIN_FILENO, &attr);
+    return( attr.c_cc[VDSUSP] );
+#elif defined(TIOCGLTC)
+    struct ltchars ltc;
+    ioctl(1, TIOCGLTC, &ltc);
+    return(ltc.t_dsuspc);
+#elif defined(_POSIX_VDISABLE)
+    return(_POSIX_VDISABLE);
+#else
+    return(0);
+#endif
+}
+
+int
+md_setdsuspchar(int c)
+{
+#if defined(VDSUSP)			/* POSIX has priority */
+    struct termios attr;
+    tcgetattr(STDIN_FILENO, &attr);
+    attr.c_cc[VDSUSP] = c;
+    tcgetattr(STDIN_FILENO, &attr);
+#elif defined(TIOCSLTC)
+    struct ltchars ltc;
+    ioctl(1, TIOCGLTC, &ltc);
+    ltc.t_dsuspc = c;
+    ioctl(1, TIOCSLTC, &ltc);
+#else
+    NOOP(c);
+#endif
+    return(0);
+}
+
+int
+md_suspchar(void)
+{
+#if defined(VSUSP)			/* POSIX has priority */
+    struct termios attr;
+    tcgetattr(STDIN_FILENO, &attr);
+    return( attr.c_cc[VSUSP] );
+#elif defined(TIOCGLTC)
+    struct ltchars ltc;
+    ioctl(1, TIOCGLTC, &ltc);
+    return(ltc.t_suspc);
+#elif defined(_POSIX_VDISABLE)
+    return(_POSIX_VDISABLE);
+#else
+    return(0);
+#endif
+}
+
+int
+md_setsuspchar(int c)
+{
+#if defined(VSUSP)			/* POSIX has priority */
+    struct termios attr;
+    tcgetattr(STDIN_FILENO, &attr);
+    attr.c_cc[VSUSP] = c;
+    tcgetattr(STDIN_FILENO, &attr);
+#elif defined(TIOCSLTC)
+    struct ltchars ltc;
+    ioctl(1, TIOCGLTC, &ltc);
+    ltc.t_suspc = c;
+    ioctl(1, TIOCSLTC, &ltc);
+#else
+    NOOP(c);
+#endif
+
+    return(0);
+}
 
 /*
     Cursor/Keypad Support
@@ -631,8 +1372,8 @@
 	    case ALT_PAD8   : ch = CTRL('K'); break;
 	    case ALT_PAD9   : ch = CTRL('U'); break;
 #endif
-#ifdef KEY_BACKSPACE /* NCURSES in Keypad mode sends this for Ctrl-H */
-            case KEY_BACKSPACE: ch = erasechar(); break;
+#ifdef KEY_BACKSPACE
+            case KEY_BACKSPACE: ch = md_erasechar(); break;
 #endif
 	}
 
@@ -646,3 +1387,122 @@
 
     return(ch & 0x7F);
 }
+
+#if defined(LOADAV) && defined(HAVE_NLIST_H) && defined(HAVE_NLIST)
+/*
+ * loadav:
+ *	Looking up load average in core (for system where the loadav()
+ *	system call isn't defined
+ */
+
+#include <nlist.h>
+
+struct nlist avenrun = {
+    "_avenrun"
+};
+
+void
+md_loadav(double *avg)
+{
+    int kmem;
+
+    if ((kmem = open("/dev/kmem", 0)) < 0)
+	goto bad;
+    nlist(NAMELIST, &avenrun);
+    if (avenrun.n_type == 0)
+    {
+	close(kmem);
+bad:
+	avg[0] = 0.0;
+	avg[1] = 0.0;
+	avg[2] = 0.0;
+	return;
+    }
+
+    lseek(kmem, avenrun.n_value, 0);
+    read(kmem, (char *) avg, 3 * sizeof (double));
+    close(kmem);
+}
+#else
+void
+md_loadav(double *avg)
+{
+#if defined(HAVE_LOADAV)
+	loadav(avg);
+#elif defined(HAVE_GETLOADAVG)
+	getloadavg(avg,3);
+#else
+	avg[0] = avg[1] = avg[2] = 0;
+#endif
+}
+#endif
+
+#ifndef NSIG
+#define NSIG 32
+#endif
+
+void
+md_ignoreallsignals(void)
+{
+	int i;
+
+	for (i = 0; i < NSIG; i++)
+		signal(i, SIG_IGN);
+}
+
+#if 0
+/* tstp() isn't ported until I make sure it really works. */
+void
+md_tstphold(void)
+{
+#ifdef SIGTSTP
+    /*
+     * If a process can be suspended, this code wouldn't work
+     */
+# ifdef SIG_HOLD
+    signal(SIGTSTP, SIG_HOLD);
+# else
+    signal(SIGTSTP, SIG_IGN);
+# endif
+#endif
+}
+
+void
+md_tstpresume(void)
+{
+#ifdef SIGTSTP
+    signal(SIGTSTP, tstp);
+#endif
+}
+
+void
+md_tstpsignal(void)
+{
+#ifdef SIGTSTP
+    kill(0, SIGTSTP);		/* send actual signal and suspend process */
+#endif
+}
+#endif
+
+#if defined(CHECKTIME)
+void
+md_start_checkout_timer(int time)
+{
+    int  checkout();
+
+#if defined(HAVE_ALARM) && defined(SIGALRM)
+    signal(SIGALRM, checkout);
+	alarm(time);
+#endif
+}
+
+void
+md_stop_checkout_timer(void)
+{
+#if defined(SIGALRM)
+    signal(SIGALRM, SIG_IGN);
+#endif
+}
+
+#endif
+
--- a/srogue/rogue.h	Sat Apr 26 08:52:26 2014 -0700
+++ b/srogue/rogue.h	Sun Apr 27 08:29:14 2014 -0700
@@ -31,6 +31,44 @@
 #include "config.h"
 #endif
 
+/* mdport functions */
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+int	md_chmod(const char *filename, int mode);
+char	*md_crypt(const char *key, const char *salt);
+int	md_dsuspchar(void);
+int	md_erasechar(void);
+char	*md_gethomedir(void);
+char	*md_getusername(void);
+uid_t	md_getuid(void);
+char	*md_getpass(char *prompt);
+pid_t	md_getpid(void);
+char	*md_getrealname(uid_t uid);
+void	md_init(void);
+int	md_killchar(void);
+void	md_normaluser(void);
+void	md_raw_standout(void);
+void	md_raw_standend(void);
+int	md_readchar(WINDOW *win);
+int	md_setdsuspchar(int c);
+int	md_shellescape(void);
+void	md_sleep(int s);
+int	md_suspchar(void);
+int	md_hasclreol(void);
+int	md_unlink(char *file);
+int	md_unlink_open_file(const char *file, FILE *inf);
+void md_tstpsignal(void);
+void md_tstphold(void);
+void md_tstpresume(void);
+void md_ignoreallsignals(void);
+void md_onsignal_autosave(void);
+void md_onsignal_exit(void);
+void md_onsignal_default(void);
+int md_issymlink(char *sp);
+char *xcrypt(const char *key, const char *setting);
+
 #define reg     register        /* register abbr.       */
 
 /*