srogue: add a complete mdport.c.

srogue/mdport.c is copied from rogue5/mdport.c, with slight changes.
This commit is contained in:
John "Elwin" Edwards 2014-04-27 08:29:14 -07:00
parent 9dc4559375
commit de1e0f2759
3 changed files with 908 additions and 10 deletions

View file

@ -12,7 +12,7 @@ AC_PROG_CC
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_PROG_GCC_TRADITIONAL
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"] )

View file

@ -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 @@ md_readchar(WINDOW *win)
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 @@ md_readchar(WINDOW *win)
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

View file

@ -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. */
/*