pdirt/data/
pdirt/data/HELP/
pdirt/data/HELP/0/
pdirt/data/HELP/F/
pdirt/data/HELP/G/
pdirt/data/HELP/H/
pdirt/data/HELP/J/
pdirt/data/HELP/K/
pdirt/data/HELP/O/
pdirt/data/HELP/Q/
pdirt/data/HELP/R/
pdirt/data/HELP/U/
pdirt/data/HELP/V/
pdirt/data/HELP/Y/
pdirt/data/HELP/Z/
pdirt/data/MESSAGES/
pdirt/data/POWERINFO/
pdirt/data/WIZ_ZONES/
pdirt/drv/
pdirt/drv/bin/
pdirt/drv/compiler/converter/
pdirt/drv/compiler/libs/
pdirt/drv/compiler/scripts/
pdirt/drv/include/AberChat/
pdirt/drv/include/InterMud/
pdirt/drv/include/machine/
pdirt/drv/src/InterMud/
pdirt/drv/src/Players/
pdirt/drv/utils/UAFPort/
pdirt/drv/utils/dnsresolv/
pdirt/drv/utils/gdbm/
/* iDIRT Message System Version 1.03/PE (Public Edition)
 * by Illusion (1995)
 *
 * Derived from the DYRT mailer from DYRT 1.1c
 * by Thrace [Valentin Popescu] (vpopesc@calstatela.edu)
 * -------------------------------------------------------------------------
 *                       *** NOTE ***
 * DO NOT CHANGE THE VERSION INFORMATION IN THIS MAILER!!
 * IF YOU CHANGE THE MAILER CONSIDERABLY, GIVE CREDIT TO
 * BOTH ILLUSION AND THRACE. THRACE WORKED HARD ON THIS
 * MAILER, AND ILLUSION WORKED HARD TO DEBUG IT, THEY
 * DESERVE CREDIT FOR DOING SO.
 *
 * Basically what I did was take this source code from the Dyrt 1.1c 
 * source code and started rewriting it and trying to make it work with 
 * the iDIRT (or any other Dirt) code. I had to fix a few bugs that the 
 * mailer had which were:
 *
 * 1.00
 * ----
 *	- A bug in the dump_headers() function that made the whole MUD crash 
 *        when you scan your mail when you typed 'mail' to read it (read
 *        the headers). What was happening was this: the MUD was calling a 
 *        bflush() that seemed to be crashing the MUD. Removing this bflush() 
 *        still killed it. After trying out many different techniques I 
 *        figured (basically guessed *grin*) that the error was coming from 
 *        the bflush() calling fflush() when the mail file was at the EOF (or
 *        past it, that was my idea). So I had the dump_headers() check to see
 *        if the pointer that accesses the mail file is located past the EOF 
 *        or not. Well, this fixed it and it no longer crashes.
 *
 *     - A bug in the write_mail() function that didn't let you abort the 
 *       message if you had a blank subject. 
 *
 *     - Fixed a bug in the mail menu that would cause it to stay in an 
 *       infinite mail loop. This bug was caused by a user running the 
 *       mailer from within the mailer again (*mail).
 *
 *     - Players can now no longer alias from the mail menu.
 *
 * 1.01
 * ----
 *     - Fixed the bug that allowed players to put the EOM text in the 
 *       message. Change the EOM_MARKER #define to whatever you see fit
 *	 and keep it a secret so that nobody can kill players mail files.
 *	 You may even wish to use control characters for the EOM marker, 
 *	 your decision.
 *
 *     - Added some color to the mailer.
 *
 * 1.02
 * ----
 *     - Fixed a bug in which if users entered any format character into 
 *       the subject, it crashed the MUD.
 *
 * 1.03
 * ----
 *     - Fixed a bug in which if users entered any format character into
 *	 the text, it crashed the MUD.
 *
 *     - Now the mailer saves the player's prompt before entering the mailer.
 *   
 *     - Released a Public Version removing the iDIRT specific code.
 */
#define MAIL_C

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#ifdef RS6000
#include <strings.h>
#endif
#include "kernel.h"
#include "mobile.h"
#include "lflags.h"
#include "sflags.h"
#include "pflags.h"
#include "mflags.h"
#include "cflags.h"
#include "sendsys.h"
#include "levels.h"
#include "parse.h"
#include "rooms.h"
#include "mail.h"
#include "bprintf.h"
#include "uaf.h"
#include "log.h"
#include "mud.h"
#include "misc.h"

/* Mail system defines */
#define EOM_MARKER 	"\001\002\003"
#define MAX_LETTERS	150
#define READ		1
#define WRITE		0
#define SUBJECT		"&+wSubject: &+w"
#define SENT		"\n&+wMessage sent.\n"
#define MAILP		"&+w:&+w> &+w"
#define PROMPT		"&+w[&+wMail&+w] &+w:&+w "
#define NOTICE1		"\
&+w=============================================================================\n\
&+wEnter your message. To save your message type &+w'=s' &+wor &+w'**' &+won \
a blank line.\nTo abort your message type &+w'=a' &+wor &+w'*abort' &+won \
a blank line.\n\
&+w=============================================================================\n"


int count;

/* mailcom(): Main loop for the mail program. This function checks to see if
 * the person trying to access the mailer is aliased, and then checks if a
 * player's name was passed through the command line and will startup the
 * mail sender if they are found.
 */
A_COMMAND(mailcom)
{
  PERSONA p;

  if (ltstflg(ploc(mynum),LFL_JAIL) && (plev(mynum) < LVL_ARCHWIZARD) )
  {  bprintf("Sorry.... we have jailed the postman as well.\n");
     return;
  }
  /* Do not let aliased players use the mailer */
  if (cur_player->aliased || cur_player->polymorphed != -1)
    {
      bprintf ("You cannot use the mailer while you are aliased.\n");
      return;
    }

  /* Save the mail header */
  cur_player->mails.old_handler = cur_player->inp_handler->inp_handler;

  /* Save the prompt */
  strcpy(cur_player->mails.prompt, cur_player->prompt);

  if (brkword () != -1) 
  {
    if (!getuaf (wordbuf, &p)) 
    {
      bprintf ("&+wPlayer not found in database.\n");
      return;
    }
    strcpy (cur_player->mails.w_name, p.p_name);
    bprintf ("&+wTo: &+w%s\n", cur_player->mails.w_name);

    bprintf (SUBJECT);
    cur_player->inmailer = True;
    cur_player->mails.old_handler = cur_player->inp_handler->inp_handler;
    strcpy (cur_player->cprompt, SUBJECT);

    replace_input_handler(write_mail);
    return;
  }
  read_mail (pname(mynum));
  return;
}

/* write_mail(): Gets the message subject and checks to see if to abort 
 * the message (if subject is a blank) and creates the header in the 
 * temporary mail file. Also, now you can abort the message here (before
 * it just asked you for the subject again).
 */
void write_mail (char *u)
{
  if (EMPTY (u) || u[0] == '\n') 
  {
    bprintf ("&+wMessage Aborted.\n");
    replace_input_handler (cur_player->mails.old_handler);
    strcpy(cur_player->prompt, cur_player->mails.prompt);
    strcpy (cur_player->cprompt, build_prompt (mynum));
    cur_player->inmailer= False;
    bprintf("\r%s", cur_player->cprompt);
    setup_globals (mynum);
    return;
  } 
  else 
  { 
    ssetflg(mynum,SFL_NOCOMM);
    bprintf (NOTICE1);
    bprintf (MAILP);
    open_mail (WRITE, True);
    if (cur_player->mails.write == (FILE *) 0)
      return;
    fprintf (cur_player->mails.write, "%s\n%s\n%d\n", pname (mynum), u, (int)time (0));
    fflush (cur_player->mails.write);
    strcpy (cur_player->prompt, MAILP);
    replace_input_handler (input_mail);
  }
  return;
}

/* input_mail(): Handles the input of the message text */
void input_mail (char *x)
{ int p;
  char to[256];
  char from[256];
  Boolean abort = False;

  if (!strcasecmp(x,"=s") || !strcasecmp(x,"=a") ||
      !strcasecmp(x,"**") || !strcasecmp(x,"*abort")) 
  {
    fprintf (cur_player->mails.write, "\n%s\n", EOM_MARKER);
    close_mail (WRITE);
    strcpy(cur_player->prompt, cur_player->mails.prompt);
    strcpy (cur_player->cprompt, (char *) build_prompt (mynum));
    sprintf (to, "%s/%s", MAIL_DIR, cur_player->mails.w_name);
    sprintf (from, "%s/%s.from-%s", MAIL_DIR, cur_player->mails.w_name,pname (mynum));

    if (!strcasecmp(x,"=a") || !strcasecmp(x, "*abort")) 
    {
      bprintf("&+wMail aborted.\n");
      abort = True;
    } 
    else
      concat_files (to, from);
      
    unlink (from);
    if (!abort) bprintf (SENT);

    if ((p = fpbns (cur_player->mails.w_name)) >= 0) 
    {
      if (p < max_players && !abort)
        sendf (p, "&+w* &+wYou have new mail from %s &+w*\n", pname (mynum));
    }

    if (cur_player->mails.level)
      replace_input_handler (mail_menu);
    else 
    { sclrflg(mynum,SFL_NOCOMM);
      cur_player->inmailer = False;
      replace_input_handler (cur_player->mails.old_handler);
      strcpy(cur_player->prompt, cur_player->mails.prompt);
      strcpy (cur_player->cprompt, build_prompt (mynum));
      bprintf("\r%s", cur_player->cprompt);
    }
    return;
  }

  fprintf (cur_player->mails.write, "%s\n", x);
  bprintf (MAILP);
  fflush (cur_player->mails.write);
  return;
}

/* read_mail(): Lets the player read a message */
void read_mail (char *u)
{
  strcpy (cur_player->mails.r_name, pname (mynum));

  open_mail (READ, False);
  if (!(cur_player->mails.read)) 
  {
    bprintf ("&+wSorry, you have no mail.\n");
    return;
  }

/*
  strcpy (cur_player->cprompt, PROMPT);
*/
  strcpy (cur_player->prompt, PROMPT);
  dump_headers (cur_player->mails.read);
  bprintf (PROMPT);
  replace_input_handler (mail_menu);
  return;
}

   
/* dump_headers(): Displays the message headers for your message file. 
 * There was a bug with the original code that caused the MUD to crash when
 * the bflush() was called and if the EOF of the mail file had been reached.
 * This was fixed by Illusion for iDIRT.
 */
void dump_headers (FILE * m)
{ char   b[MAX_COM_LEN];
  char   from[MAX_COM_LEN];
  time_t time_sent;
  char   s[MAX_COM_LEN];
  count = 1;

  rewind (cur_player->mails.read);

  bprintf ("&+w No.  From         Date Sent                 Subject\n");
  bprintf ("&+w----- ------------ ------------------------  ---------------------------\n");

  while (!feof (cur_player->mails.read)) 
  {
    fgets (b, MAX_COM_LEN, cur_player->mails.read);	/* From Field */
    if (feof(cur_player->mails.read)) 
      return;
    b[strlen (b) - 1] = '\0';
    strncpy (from, b, 12);

    fgets (s, MAX_COM_LEN, cur_player->mails.read);	/* Subject Field */

    fgets (b, 40, cur_player->mails.read);		/* Date Send Field */
    time_sent = atol (b);

    for (;;) 						/* Find the EOF text */
    {
      if (feof (cur_player->mails.read))
        break;
        
      fgets (b, MAX_COM_LEN, cur_player->mails.read);
      
      if (strncmp (b, EOM_MARKER, 3) == 0)
	break;
    }

    if (strlen (s) > 27) 				/* Dump Header */
    {
      s[24] = ' ';
      s[25] = s[26] = s[27] = '.';
      s[28] = '\n';
      s[29] = '\0';
    }
    bprintf("&+w[%3.3d] %-12.12s %24.24s  %s", 
            count, from, ctime (&time_sent),
	    (cur_player->mails.data)[count - 1] ? "&+w[ To Be Deleted ]\n" : s);
      
    count++;
    if (!feof(cur_player->mails.read)) /* [iDIRT] Bug fix. The MUD used */
      bflush();                        /* to crash here until the mail  */
  }                                  /* file was checked for EOF.     */
  return;
}

/* mail_menu(): The menuing system for the mailer */
void mail_menu (char *u)
{ time_t tim;
  char   buffer[MAX_COM_LEN + 5];
  int    quitting_mail = False;

  cur_player->inmailer = True;

  if (cur_player->mails.level) 
  {
    bprintf (PROMPT);
    cur_player->mails.level = 0;
  }

 /* strcpy (cur_player->cprompt, PROMPT);*/
  strcpy(cur_player->prompt, PROMPT);

  if (isupper (u[0]))
    u[0] = tolower (u[0]);

  switch (u[0]) {
  case 'r':			/* Reply */
      tim = time (0);
      
      if (EMPTY (cur_player->mails.last))
	bprintf ("&+wYou haven't read any messages yet.\n");
      else 
      {
	if (strncasecmp (cur_player->mails.subject, "Re: ", 4) != 0)
	  sprintf (buffer, "&+wRe: &+w%s", cur_player->mails.subject);
	else
	  strcpy (buffer, cur_player->mails.subject);

	strcpy (cur_player->mails.w_name, cur_player->mails.last);
	open_mail (WRITE, True);
	if (!cur_player->mails.write) 
	{
          close_mail (READ);
	  return;
	}
        
	bprintf ("&+wTo: &+w%s\n&+wSubject: &+w%s\n", 
		  cur_player->mails.last, buffer);
        bprintf(NOTICE1);
        bprintf (MAILP);
        fprintf (cur_player->mails.write, "%s\n%s%d\n", 
                 pname (mynum), buffer, (int)tim);

        cur_player->mails.level = 1;
        replace_input_handler (input_mail);
	return;
      }
      break;
    
  case 'd':			/* Delete */
      if (u[1] != ' ' || !isdigit (u[2]))
	bprintf ("\nUsage: d [message number]\n");
      else
						/*or statement added by jwn*/
        if ((atoi(&u[2]) - 1) > MAX_LETTERS || atoi(&u[2]) > (count-1) )  
        {
          bprintf("Message number cannot be greater than %d\n", (count-1));
          mudlog("Bad &+wMAIL&* by %s, Number was %d",
                 pname(mynum), (atoi(&u[2]) - 1));
          bprintf (PROMPT);
          return;
        }     

      (cur_player->mails.data)[atoi (&u[2]) - 1] = True;
      break;

  case 'u':			/* Undelete */
      if (u[1] != ' ' || !isdigit (u[2]))
	bprintf ("\nUsage: u [message number]\n");
      else
        if ((atoi(&u[2]) - 1) > MAX_LETTERS || atoi(&u[2]) > (count-1) )  
        {
          bprintf("Message number cannot be greater than %d\n", MAX_LETTERS);
          mudlog("Bad &+wMAIL&* by %s, Number was %d",
                 pname(mynum), (atoi(&u[2]) - 1));
          bprintf (PROMPT);
          return;
        }     
      
      (cur_player->mails.data)[atoi (&u[2]) - 1] = False;
      break;
    
  case '*':			/* Game command */
      Game_Com (&u[1], False);
      break;
 
  case 'i':			/* Info */
      bprintf ("\001fHELP/%s\003\n", "mail.info");
      break;
    
  case '?':
      bprintf ("\001fHELP/%s\003\n", "mail.help");
      break;
    
  case 'h':
      bprintf ("\n");
      dump_headers (cur_player->mails.read);
      break;

  case 'v':
      bprintf("iDIRT Mailer Version 1.03/PE (Public Edition)\n");
      bprintf("1994, 95 by Illusion\n\n");
      bprintf("Derived from the DYRT mailer from DYRT 1.1c\n");
      bprintf("by Valentin Popescu (vpopesc@calstatela.edu)\n");
      break;

  case '\0':
    
  case '\n':
      break;

  case 'x':
    
  case 'q':			/* quit the mailer */
      replace_input_handler (cur_player->mails.old_handler); 
      close_mail (WRITE);
      delete_mail ();
      close_mail (READ);
      strcpy(cur_player->prompt, cur_player->mails.prompt);
      strcpy (cur_player->cprompt, build_prompt (mynum));
      setup_globals (mynum);
      cur_player->inmailer = False;
      quitting_mail = True;
      break;
    
  default:
    
    /* Check to see if a number was inputed */
    {
      int number;
      number = atoi (u);
      if (number < 1 || number > MAX_LETTERS) {
        bprintf ("\nUnknown command. Type '?' for help.\n");
        break;
      }
      read_msg (number);
    }
    break;
  } /* End switch */

  if (!quitting_mail) 
    bprintf (PROMPT);
  else 
  { bprintf("&+wQuitting Mailer.\n");
    strcpy(cur_player->prompt, cur_player->mails.prompt);
    bprintf ((char *) build_prompt (mynum));
  }

  return;
}

void abort_mail(void)
{
      replace_input_handler (cur_player->mails.old_handler); 
      close_mail (WRITE);
      close_mail (READ);
      strcpy(cur_player->prompt, cur_player->mails.prompt);
      strcpy (cur_player->cprompt, build_prompt (mynum));
      setup_globals (mynum);
      cur_player->inmailer = False;
}

/* read_msg(): Reads in a message number, taking the number as a parameter */
void read_msg (int num)
{
  /* to get to a particular message num, we must skip exactly num - 1 EOFs */

  char   buffer[MAX_COM_LEN];
  time_t time_sent;

  if (num <= 0 || num > MAX_LETTERS)
    return;

  rewind (cur_player->mails.read);

  for (num = num - 1; num != 0; num--) 
  {
    for (;;) 
    {
      fgets (buffer, MAX_COM_LEN, cur_player->mails.read);
        if (feof (cur_player->mails.read))
          break;
        if (strncmp (buffer, EOM_MARKER, 3) == 0)
	    break;
    }
  }

  /* Now we should be at the right place, and we dump the letter */

  fgets (buffer, MAX_COM_LEN, cur_player->mails.read);
  if (feof (cur_player->mails.read)) 
  {
    bprintf ("\n&+wMessage out of range.\n", num);
    return;
  }
  buffer[strlen (buffer) - 1] = '\0';
  strncpy (cur_player->mails.last, buffer, 12);

  if ((cur_player->mails.data)[num] == True)
    bprintf ("\n&+w* Note: This letter is marked for deletion *\n");

  /* dump the header */
  bprintf ("\n&+wFrom: &+w%s\n", buffer);
  fgets (buffer, MAX_COM_LEN, cur_player->mails.read);
  strncpy (cur_player->mails.subject, buffer, MAX_COM_LEN);
  bprintf ("&+wSubject: &+w%s", buffer);
  fgets (buffer, MAX_COM_LEN, cur_player->mails.read);
  time_sent = atoi (buffer);
  bprintf ("&+wSent: &+w%s", ctime (&time_sent));
  bprintf ("\n");

  /* Dump the message body */

  for (;;) 
  {
    fgets (buffer, MAX_COM_LEN, cur_player->mails.read);
    if (strncmp (buffer, EOM_MARKER, 3) == 0)
      break;
    bprintf("%s", buffer);
    if (feof (cur_player->mails.read))
      break;
  }
  bflush ();
  return;
}

/* open_mail(): Handles the opening of a mail file. */
void open_mail (char mode, Boolean complain)
{ char buf[1024];
  FILE *tf;
  Boolean fail = False;

  switch (mode) {
  case READ:
      sprintf (buf, "%s/%s", MAIL_DIR, cur_player->mails.r_name);
      tf = fopen (buf, "r");
      if (!tf)
        fail = True;
      else
        cur_player->mails.read = tf;
      break;
  case WRITE:
      sprintf (buf, "%s/%s.from-%s", MAIL_DIR, cur_player->mails.w_name, pname (mynum));

      tf = fopen (buf, "w");
      if (!tf) 
      {
        progerror ("mail-write");
        fail = True;
      }
      cur_player->mails.write = tf;
      break;
  } /* End switch */

  if (complain && fail) 
  {
    bprintf ("We are experiencing technical difficulties. Try again later.\n");
    progerror ("open_mail");
    if (cur_player->mails.read != NULL)
    {   fclose(cur_player->mails.read);
        cur_player->mails.read = NULL;
    }
    if (cur_player->mails.write != NULL)
    {   fclose(cur_player->mails.write);  
        cur_player->mails.write = NULL;
    }      
    replace_input_handler (cur_player->mails.old_handler);
  }
  return;
}

/* close_mail(): Handles the closing of the mail files */
void close_mail (char mode)
{
  switch (mode) {
  case READ:
      if (cur_player->mails.read)
        fclose (cur_player->mails.read);
      cur_player->mails.read = 0;
      break;
  case WRITE:
      if (cur_player->mails.write)
        fclose (cur_player->mails.write);
      cur_player->mails.write = 0;
      break;
  }
}

/* delete_mail(): Deletes messages that have been marked for removal */
void delete_mail (void)
{ char tempfile[128];
  char tempfile2[128];
  char b[MAX_COM_LEN];
  FILE *fout;
  FILE *fin;
  struct stat s;
  register int t;
  int pid;
  extern int errno;

  pid = getpid ();

  sprintf (tempfile, "%s/TEMP.%s.%d", MAIL_DIR, pname (mynum), pid);
  sprintf (tempfile2, "%s/%s", MAIL_DIR, pname (mynum));
  (void) unlink (tempfile);

  /* copy the file, filtering out the offending message */

  fout = fopen (tempfile, "w");
  if (!fout) 
  {
    bprintf ("System error detected, mail NOT deleted.\n");
    progerror ("delete_file write");
    return;
  }

  fin = fopen (tempfile2, "r");
  if (!fin) 
  {
    bprintf ("System error detected, mail NOT deleted.\n");
    progerror ("delete_file read");
    fclose (fout);
    unlink (tempfile);
    errno = 0;		/* unlink may cause an errorr */
    return;
  }

  /* now we have both files open */

  for (t = 0; t != MAX_LETTERS; t++) 
  {
    if (feof (fin) != 0)
      break;

    /* Should we delete messages? */
    if ((cur_player->mails.data)[t] != 0)  	/* Yes, delete messages */
    {  while (1) 				/* Search for 'EOF'     */
       {  bzero (b, MAX_COM_LEN);
	  fgets (b, MAX_COM_LEN, fin);
	  if (feof (fin) != 0)
             break;
	  if (strncmp (b, EOM_MARKER, 3) == 0)
             break;
       }
    } 
    else 					/* No, do not delete   */
    {  while (1) 
       {
          bzero (b, MAX_COM_LEN);
          fgets (b, MAX_COM_LEN, fin);
          fprintf (fout, "%s", b);
          if (feof (fin) != 0)
             break;
          if (strncmp (b, EOM_MARKER, 3) == 0)
             break;
       }
    }
    /* unset the marker */
    (cur_player->mails.data)[t] = 0;
  }

  rewind (fin);

  fclose (fin);
  fclose (fout);

  /* copy the file over */
  unlink (tempfile2);
  rename (tempfile, tempfile2);

  if (stat (tempfile2, &s) != -1)
    if (s.st_size < 4)
      unlink (tempfile2);

  return;
}

/* check_files(): Checks if any files have been updated since login. A 
 * problem with iDIRT (and any DIRT for that matter) has been fixed here and 
 * it uses all of the correct DIRT user variables now. 
 */
void check_files (void)
{ PERSONA me;
  struct stat s;
  time_t last;
  char buff[512];

  getuaf(pname(mynum), &me);
  last = me.p_last_on;

  sprintf (buff, "%s/%s", MAIL_DIR, pname (mynum));

  /* Check boards for new messages */
  if (stat("bboard_ply", &s) != -1) 
  {
    if (s.st_mtime > last)
      bprintf ("There are &+wNEW&* messages on the mortal bulletin board.\n");
  }
  if ((stat ("bboard_wiz", &s) != -1) && plev (mynum) >= LVL_WIZARD) 
  {
    if (s.st_mtime > last)
      bprintf ("There are &+wNEW&* messages on the Wizard board.\n");
  }
  if ((stat("bboard_awiz", &s) != -1) && plev(mynum) >= LVL_ARCHWIZARD)
  {  if (s.st_mtime > last)
        bprintf("There are &+wNEW&* messages on the Archwizard board.\n");
  }
  if ((stat("bboard_god",&s) != -1) && plev(mynum) >= LVL_GOD)
  {  if (s.st_mtime > last)
         bprintf("There are &+wNEW&* messages on the God board.\n");
  }
  if (stat(BUGSYSLOG,&s) != -1 && ptstflg(mynum,PFL_SYSLOG))
  {  if (s.st_mtime > last)
        bprintf("&+wNew &+wBugs &+wreported in buglog.\n");
  }
  if (stat(SUGGESTLOG,&s) != -1 && ptstflg(mynum,PFL_SYSLOG))
  {  if (s.st_mtime > last)
        bprintf("&+wNew &+wSuggestions &+wreported in suggestlog.\n");
  }

#ifdef USE_BULLETIN
  if (stat (BULLETIN1, &s) != -1) {
    if (s.st_mtime > last)
      bprintf ("New Mortal bulletin as of %19.19s.\nType 'bull' to read it.\n", ctime (&s.st_mtime));
  }
  if ((stat (BULLETIN2, &s) != -1) && plev (mynum) >= LVL_WIZARD) {
    if (s.st_mtime > last)
      bprintf ("New Wizard+ bulletin as of %19.19s.\nType 'bull' to read it.\n", ctime (&s.st_mtime));
  }
  if ((stat (BULLETIN3, &s) != -1) && plev (mynum) >= LVL_ARCHWIZARD) {
    if (s.st_mtime > last)
      bprintf ("New Arch-Wizard+ bulletin as of %19.19s.\nType 'bull' to read it.\n", ctime (&s.st_mtime));
  }
#endif

  if (stat (buff, &s) != -1) 
  {
    if (s.st_size > 3) 
    {
      if (s.st_mtime > last)
        bprintf ("&+wYou have &B&+wNEW&* mail.\n");
      else
        bprintf ("&+wYou have old mail in your mailbox.\n");
    }
  }
  bprintf("\n");
}