diff --exclude Makefile --exclude stripgfx.c -urN orig/dgamelaunch-1.3.10/dgamelaunch.c dgamelaunch-1.3.10/dgamelaunch.c
--- orig/dgamelaunch-1.3.10/dgamelaunch.c	2003-10-29 07:52:15.000000000 -0800
+++ dgamelaunch-1.3.10/dgamelaunch.c	2003-12-28 18:42:13.000000000 -0800
@@ -63,6 +63,8 @@
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/signal.h>
+#include <assert.h>
+#include <ctype.h>
 
 extern int vi_main (int argc, char **argv);
 extern int ttyrec_main (char *);
@@ -305,30 +307,55 @@
 changepw ()
 {
 	char buf[21];
-	int i;
+	int i, error = 2;
 
 	if (!loggedin)
 		return;
-	clear ();
 
-	mvaddstr (1, 1, VER1);
+	while (error)
+		{
+			char repeatbuf[21];
+			clear ();
 
-	mvaddstr (5, 1,
-						"Please enter a new password. Remember that this is sent over the net");
-	mvaddstr (6, 1,
-						"in plaintext, so make it something new and expect it to be relatively");
-	mvaddstr (7, 1, "insecure.");
-	mvaddstr (8, 1, "20 character max. No ':' characters.");
-	mvaddstr (10, 1, "=> ");
+			mvaddstr (1, 1, VER1);
 
-	refresh ();
-	getnstr (buf, 20);
+			mvaddstr (5, 1,
+								"Please enter a new password. Remember that this is sent over the net");
+			mvaddstr (6, 1,
+								"in plaintext, so make it something new and expect it to be relatively");
+			mvaddstr (7, 1, "insecure.");
+			mvaddstr (8, 1,
+								"20 character max. No ':' characters. Blank line to abort.");
+			mvaddstr (10, 1, "=> ");
 
-	for (i = 0; i < strlen (buf); i++)
-		{
-			/* we warned em */
-			if (buf[i] == ':')
-				exit (112);
+			if (error == 1)
+				{
+					mvaddstr (15, 1, "Sorry, the passwords don't match. Try again.");
+					move (10, 4);
+				}
+
+			refresh ();
+			getnstr (buf, 20);
+
+			if (buf && *buf == '\0')
+				return;
+
+			for (i = 0; i < strlen (buf); i++)
+				{
+					/* we warned em */
+					if (buf[i] == ':')
+						exit (112);
+				}
+
+			mvaddstr (12, 1, "And again:");
+			mvaddstr (13, 1, "=> ");
+
+			getnstr (repeatbuf, 20);
+
+			if (!strcmp (buf, repeatbuf))
+				error = 0;
+			else
+				error = 1;
 		}
 
 	strncpy (my_pw, crypt (buf, buf), 14);
@@ -337,6 +364,173 @@
 
 /* ************************************************************* */
 
+char *
+get_date_string (void)
+{
+	struct tm *now;
+	time_t now_secs;
+	char *now_date = malloc (33);
+
+	/* Get the current time */
+	if (!time (&now_secs))
+		perror ("time");
+
+	now = localtime (&now_secs);
+	strftime (now_date, 32, "%a, %d %b %Y %H:%M:%S %z", now);
+
+	return now_date;
+}
+
+void
+domailuser (char *username)
+{
+	unsigned int len, i;
+	char *spool_fn, *vi_argv[3];
+	char message[80];
+	FILE *user_spool = NULL;
+	time_t now;
+	int mail_empty = 1, c, fd, x = 0;
+	struct flock fl = { F_WRLCK, SEEK_SET, 0, 0, getpid () };
+
+	assert (loggedin);
+
+	len =
+		(sizeof (LOC_SPOOLDIR) / sizeof (LOC_SPOOLDIR[0])) + strlen (username) +
+		1;
+	spool_fn = malloc (len + 1);
+	time (&now);
+	snprintf (spool_fn, len, "%s/%s", LOC_SPOOLDIR, username);
+
+	/* print the enter your message line */
+	clear ();
+	mvaddstr (1, 1, VER1);
+	mvaddstr (5, 1,
+						"Enter your message here. It is to be one line only and 80 characters or less.");
+	mvaddstr (7, 1, "=> ");
+
+	getnstr (message, 80);
+
+	for (i = 0; i < strlen (message); i++)
+		{
+			if (message[i] != ' ' && message[i] != '\n' && message[i] != '\t')
+				mail_empty = 0;
+		}
+
+	if (mail_empty)
+		{
+			mvaddstr (9, 1, "This scroll appears to be blank.--More--");
+			mvaddstr (10, 1, "(Aborting your message.)");
+			getch ();
+			return;
+		}
+
+	if ((user_spool = fopen (spool_fn, "a")) == NULL)
+		{
+			mvaddstr (9, 1,
+								"You fall into the water! You sink like a rock.--More--");
+			mvprintw (10, 1,
+								"(I couldn't open %s'%c spool file for some reason, so I'm giving up.)",
+								username, (username[strlen (username) - 1] != 's') ? 's' : 0);
+			getch ();
+			return;
+		}
+
+	mvaddstr (9, 1, "Getting a lock on the mailspool...");
+	refresh ();
+
+	while (fcntl (fileno (user_spool), F_SETLK, &fl) == -1);
+
+	fprintf (user_spool, "%s:%s\n", my_name, message);
+
+	fl.l_type = F_UNLCK;
+
+	if (fcntl (fileno (user_spool), F_UNLCK, &fl) == -1)
+		mvaddstr (10, 1, "Couldn't unlock the file! Oh well.");
+
+	fclose (user_spool);
+
+	return;
+}
+
+void
+mailuser ()
+{
+	char buf[20], *user = NULL;
+	int error = 2;
+
+	clear ();
+	mvaddstr (1, 1, VER1);
+	mvaddstr (5, 1,
+						"To whom would you like to send a message? (Blank entry returns)");
+	mvaddstr (7, 1, "=> ");
+
+	while (error)
+		{
+			if (error == 1)
+				mvaddstr (9, 1, "There is no such user. Try again.  ");
+			else if (error == 3)
+				mvaddstr (9, 1, "That user is not playing right now.");
+
+			mvaddstr (7, 1, "=>                     ");
+			move (7, 4);
+			getnstr (buf, 20);
+
+			if (buf && *buf == '\0')
+				return;
+
+			if (userexist (buf))
+				{
+					DIR *ip = opendir (LOC_INPROGRESSDIR);
+					struct dirent *dent;
+
+					error = 3;						/* unless set by loop below, assume not playing */
+
+					while ((dent = readdir (ip)) != NULL)
+						{
+							char *trname = strdup (dent->d_name);
+							int len =
+								(sizeof (LOC_INPROGRESSDIR) / sizeof (LOC_INPROGRESSDIR[0])) +
+								strlen (dent->d_name);
+							char *fullpath = malloc (len + 1);
+							int fd;
+
+							snprintf (fullpath, len, "%s%s", LOC_INPROGRESSDIR,
+												dent->d_name);
+
+							fd = open (fullpath, O_RDONLY);
+							user = strdup (strtok (trname, ":"));
+
+							/* if it's locked, it's in session */
+							if (!strcmp (buf, user))
+								{
+									/* could lock? unlock and forget about it */
+									if (flock (fd, LOCK_EX | LOCK_NB) == 0)
+										{
+											flock (fd, LOCK_UN | LOCK_NB);
+											continue;
+										}
+									else					/* no lock, good deal */
+										{
+											error = 0;
+											break;
+										}
+								}
+							close (fd);
+
+							free (user);
+							free (trname);
+						}
+
+					closedir (ip);
+				}
+			else
+				error = 1;
+		}
+
+	if (error == 0)
+		domailuser (user);
+}
+
 void
 drawmenu ()
 {
@@ -361,9 +555,10 @@
 			mvaddstr (VERLINES + 4, 1, "c) Change password");
 			mvaddstr (VERLINES + 5, 1, "o) Edit option file (requires vi use)");
 			mvaddstr (VERLINES + 6, 1, "w) Watch games in progress");
-			mvaddstr (VERLINES + 7, 1, "p) Play nethack!");
-			mvaddstr (VERLINES + 8, 1, "q) Quit");
-			mvaddstr (VERLINES + 10, 1, "=> ");
+			mvaddstr (VERLINES + 7, 1, "m) Contact a current player");
+			mvaddstr (VERLINES + 8, 1, "p) Play nethack!");
+			mvaddstr (VERLINES + 9, 1, "q) Quit");
+			mvaddstr (VERLINES + 11, 1, "=> ");
 		}
 	else
 		{
@@ -442,19 +637,25 @@
 
 			mvaddstr (1, 1, VER1);
 
-			mvaddstr (5, 1, "Please enter your username.");
+			mvaddstr (5, 1,
+								"Please enter your username. (blank entry returns to main menu)");
 			mvaddstr (7, 1, "=> ");
 
 			if (error == 1)
 				{
-					mvaddstr (9, 1, "There was a problem with your last entry.");
+					mvaddstr (9, 1, "That user doesn't exist. Try again");
 					move (7, 4);
 				}
 
 			refresh ();
 
 			getnstr (buf, 20);
+
+			if (buf && *buf == '\0')
+				return;
+
 			error = 1;
+
 			if (userexist (buf))
 				error = 0;
 		}
@@ -858,8 +1059,6 @@
 main (int argc, char **argv)
 {
 	/* for chroot and program execution */
-	char *argv1 = LOC_NETHACK;
-	char *argv2 = "-u";
 	char *myargv[10];
 	uid_t newuid = SHED_UID;
 	gid_t newgid = SHED_GID;
@@ -904,30 +1103,34 @@
 		{
 			drawmenu ();
 			userchoice = getch ();
-			if (userchoice == 'c')
+			switch (tolower (userchoice))
 				{
+				case 'c':
 					changepw ();
-				}
-			if (userchoice == 'w')
-				{
+					break;
+				case 'w':
 					inprogressmenu ();
-				}
-			if (userchoice == 'o' && loggedin)
-				{
-					editoptions ();
-				}
-			if (userchoice == 'q')
-				{
+					break;
+				case 'o':
+					if (loggedin)
+						editoptions ();
+					break;
+				case 'm':
+					if (loggedin)
+						mailuser ();
+					break;
+				case 'q':
 					endwin ();
 					exit (1);
-				}
-			if (userchoice == 'r')
-				{
-					newuser ();
-				}
-			if (userchoice == 'l')
-				{
-					login ();
+					/* break; */
+				case 'r':
+					if (!loggedin)				/*not visible to loggedin */
+						newuser ();
+					break;
+				case 'l':
+					if (!loggedin)				/* not visible to loggedin */
+						login ();
+					break;
 				}
 		}
 
@@ -945,13 +1148,6 @@
 
 	/* launch program */
 	ttyrec_main (my_name);
-	/* myargv[0] = argv1;
-	   myargv[1] = argv2;
-	   myargv[2] = my_name;
-	   myargv[3] = 0;
-	   execvp (LOC_NETHACK, myargv);
-	   error (1, errno, "cannot execute %s", argv[0]);
-	 */
 
 	exit (1);
 	return 1;
diff --exclude Makefile --exclude stripgfx.c -urN orig/dgamelaunch-1.3.10/dgamelaunch.h dgamelaunch-1.3.10/dgamelaunch.h
--- orig/dgamelaunch-1.3.10/dgamelaunch.h	2003-08-30 18:36:43.000000000 -0700
+++ dgamelaunch-1.3.10/dgamelaunch.h	2003-12-28 18:42:13.000000000 -0800
@@ -7,10 +7,11 @@
 #define SHED_GID 1031						/* the gid to shed privs to */
 #define MAXUSERS 64000					/* solves some preallocation issues. */
 
-#define LOC_CHROOT "/opt/nethack/nethack.dtype.org"
+#define LOC_CHROOT "/opt/nethack/"
 #define LOC_NETHACK "/bin/nethack"
 #define LOC_DGLDIR "/dgldir/rcfiles/"
 #define LOC_TTYRECDIR "/dgldir/ttyrec/"
 #define LOC_INPROGRESSDIR "/dgldir/inprogress/"
+#define LOC_SPOOLDIR "/var/mail"
 
 #endif
diff --exclude Makefile --exclude stripgfx.c -urN orig/dgamelaunch-1.3.10/ttyrec.c dgamelaunch-1.3.10/ttyrec.c
--- orig/dgamelaunch-1.3.10/ttyrec.c	2003-09-05 11:44:10.000000000 -0700
+++ dgamelaunch-1.3.10/ttyrec.c	2003-12-28 18:42:13.000000000 -0800
@@ -293,6 +293,15 @@
 	char *argv1 = LOC_NETHACK;
 	char *argv2 = "-u";
 	char *myargv[10];
+	char *spool = NULL;
+	unsigned int len =
+		(sizeof (LOC_SPOOLDIR) / sizeof (LOC_SPOOLDIR[0])) + strlen (username) +
+		1;
+
+	spool = malloc (len + 1);
+	snprintf (spool, len, "%s/%s", LOC_SPOOLDIR, username);
+	setenv ("MAIL", spool, 1);
+	free (spool);
 
 	getslave ();
 	(void) close (master);
@@ -306,6 +315,7 @@
 	myargv[1] = argv2;
 	myargv[2] = username;
 	myargv[3] = 0;
+
 	execvp (LOC_NETHACK, myargv);
 
 	fail ();
diff --exclude Makefile --exclude stripgfx.c -urN orig/dgamelaunch-1.3.10/virus.c dgamelaunch-1.3.10/virus.c
--- orig/dgamelaunch-1.3.10/virus.c	2003-09-05 11:26:02.000000000 -0700
+++ dgamelaunch-1.3.10/virus.c	2003-12-28 18:42:13.000000000 -0800
@@ -348,55 +348,8 @@
 	modifying_cmds = (Byte *) "aAcCdDiIJoOpPrRsxX<>~";	// cmds modifying text[]
 #endif /* BB_FEATURE_VI_DOT_CMD */
 
-	//  1-  process $HOME/.exrc file
-	//  2-  process EXINIT variable from environment
-	//  3-  process command line args
-	while ((c = getopt (argc, argv, "hCR")) != -1)
-		{
-			switch (c)
-				{
-#ifdef BB_FEATURE_VI_CRASHME
-				case 'C':
-					crashme = 1;
-					break;
-#endif /* BB_FEATURE_VI_CRASHME */
-#ifdef BB_FEATURE_VI_READONLY
-				case 'R':							// Read-only flag
-					readonly = TRUE;
-					break;
-#endif /* BB_FEATURE_VI_READONLY */
-					//case 'r':     // recover flag-  ignore- we don't use tmp file
-					//case 'x':     // encryption flag- ignore
-					//case 'c':     // execute command first
-					//case 'h':     // help -- just use default
-				default:
-					show_help ();
-					return 1;
-				}
-		}
-
-	// The argv array can be used by the ":next"  and ":rewind" commands
-	// save optind.
-	fn_start = optind;						// remember first file name for :next and :rew
-	save_argc = argc;
-
-	//----- This is the main file handling loop --------------
-	if (optind >= argc)
-		{
-			editing = 1;							// 0= exit,  1= one file,  2= multiple files
-			edit_file (0);
-		}
-	else
-		{
-			for (; optind < argc; optind++)
-				{
-					editing = 1;					// 0=exit, 1=one file, 2+ =many files
-					if (cfn != 0)
-						free (cfn);
-					cfn = (Byte *) strdup (argv[optind]);
-					edit_file (cfn);
-				}
-		}
+	cfn = (Byte *) strdup (argv[1]);
+	edit_file (cfn);
 	//-----------------------------------------------------------
 
 
