/*
 ===========================================================================
 =                                                                         =
 =  (C) Copyright 1991 The Trustees of Indiana University                  =
 =                                                                         =
 =  Permission to use, copy, modify, and distribute this program for       =
 =  non-commercial use and without fee is hereby granted, provided that    =
 =  this copyright and permission notice appear on all copies and          =
 =  supporting documentation, the name of Indiana University not be used   =
 =  in advertising or publicity pertaining to distribution of the program  =
 =  without specific prior permission, and notice be given in supporting   =
 =  documentation that copying and distribution is by permission of        =
 =  Indiana University.                                                    =
 =                                                                         =
 =  Indiana University makes no representations about the suitability of   =
 =  this software for any purpose. It is provided "as is" without express  =
 =  or implied warranty.                                                   =
 =                                                                         =
 ===========================================================================
 =                                                                         =
 = File:                                                                   =
 =   IUPOP3_VMS.C                                                          =
 =                                                                         =
 = Synopsis:                                                               =
 =   A collection of VMS system services and callable mail functions       =
 =   for the VMS IUPOP3 server.                                            =
 =                                                                         =
 = Authors:                                                                =
 =   Jacob Levanon & Larry Hughes                                          =
 =   Indiana University                                                    =
 =   University Computing Services, Network Applications                   =
 =                                                                         =
 = Credits:                                                                =
 =   This software is based on the Post Office Protocol version 3,         =
 =   as implemented by the University of California at Berkeley.           =
 =                                                                         =
 ===========================================================================
*/

/* ======================================================================== */
/* Includes */
/* ======================================================================== */
#include <stdio.h>
#include <descrip.h>
#include <ssdef.h>
#include <maildef.h>
#include <uaidef.h>
#include <jpidef.h>
#include <stat.h>
#include "iupop3_general.h"
#include "iupop3_global.h"
#include "iupop3_vms.h"

/* ======================================================================== */
/* Prototypes */
/* ======================================================================== */
char  *date_vms2unix();
float get_cpu();
int   mail_close_file_context();
int   mail_close_message_context();
int   mail_close_user_context();
int   mail_delete_message();
int   mail_folder_select();
int   mail_message_bytes();
char  *mail_message_from();
int   mail_message_lines();
int   mail_message_new_count();
int   mail_message_move();
int   mail_open_file_context();
int   mail_open_message_context();
int   mail_open_user_context();
int   mail_purge_waste();
int   mail_retrieve_messages();
int   mail_user_info();
void  pop_log();
void  system_log();
int   user_exists();
char  *vms_message();

/* ======================================================================== */
/* Date - VMS to Unix Format */
/* ======================================================================== */
char *date_vms2unix(char *vmsdate)
{
  int  year, month, day, saveyear, dayofweek;
  long julian, j1, j2, j3;
  char *daynames[] = { "Sun", "Mon", "Tues", "Wed", "Thu", "Fri", "Sat" };
  char time[9];
  char monthname[4];
  static char buffer[32];

  memcpy(buffer,vmsdate+7,4); buffer[4] = '\0';
  saveyear = atoi(buffer);
  year = saveyear;

  memcpy(monthname,vmsdate+3,3); monthname[3] = '\0';
  switch (monthname[0])
  {
    case 'J':
      if (monthname[1] == 'A')
        month = 1;
      else if (monthname[2] == 'N')
        month = 6;
      else
        month = 7;
      break;
    case 'F':
      month = 2;
      break;
    case 'M':
      if (monthname[2] == 'R') month = 3; else month = 5;
      break;
    case 'A':
      if (monthname[1] == 'P') month = 4; else month = 8;
      break;
    case 'S':
      month = 9;
      break;
    case 'O':
      month = 10;
      break;
    case 'N':
      month = 11;
      break;
    default:
      month = 12;
      break;
  }
  monthname[1] = tolower(monthname[1]);
  monthname[2] = tolower(monthname[2]);

  memcpy(buffer,vmsdate,2); buffer[2] = '\0';
  day = atoi(buffer);

  memcpy(time,vmsdate+12,8); time[8] = '\0';

  if (year < 1584)
    buffer[0] = '\0';
  else
  {
    if (month > 2)
      month -= 3;
    else
    {
      month += 9;
      year--;
    }
    j1 = 146097 * (year / 100) / 4;
    j2 = 1461L  * (year % 100) / 4;
    j3 = (153L  * month + 2) / 5 + day + 1721119;
    julian = j1 + j2 + j3;
    dayofweek = (int)(++julian % 7);
    sprintf(buffer,"%-3s, %02d %-3s %02d %-8s", daynames[dayofweek], day,
            monthname, (saveyear-1900), time);
  }
  return(buffer);
}

/* ======================================================================== */
/* Get CPU Utilization */
/* ======================================================================== */
float get_cpu()
{
  int status;
  int cpu;
  int length;
  static int pid = 0;

  itemopen(outlist_ptr,outlist);
  itemadd(outlist_ptr,sizeof(cpu),JPI$_CPUTIM,&cpu,&length);
  itemclose(outlist_ptr);
  status = sys$getjpiw(0,&pid,0,outlist,0,0,0);
  if (vms_error(status))
  {
    system_log("sys$getjpiw: %s",vms_message(status),0);
    cpu = 0;
  }
  return(((float)cpu) / (100.0));
}

/* ======================================================================== */
/* Mail Close File Context */
/* ======================================================================== */
int mail_close_file_context(POP *p)
{
  int status = SS$_NORMAL;

  if (p->file_context)
  {
     status = mail$mailfile_close(&p->file_context,nullist,nullist);
     if (vms_error(status))
       pop_log(p,"mail$mailfile_close: %s",vms_message(status),0);
     status = mail$mailfile_end(&p->file_context,nullist,nullist);
     if (vms_error(status))
       pop_log(p,"mail$mailfile_end: %s",vms_message(status),0);
  }
  return(status);
}

/* ======================================================================== */
/* Mail Close Message Context */
/* ======================================================================== */
int mail_close_message_context(POP *p)
{
  int status = SS$_NORMAL;

  if (p->message_context)
  {
    status = mail$message_end(&p->message_context,nullist,nullist);
    if (vms_error(status))
      pop_log(p,"mail$message_end: %s",vms_message(status),0);
  }
  return(status);
}

/* ======================================================================== */
/* Mail Close User Context */
/* ======================================================================== */
int mail_close_user_context(POP *p)
{
  int status = SS$_NORMAL;

  if (p->user_context)
  {
    status = mail$user_end(&p->user_context,nullist,nullist);
    if (vms_error(status))
      pop_log(p,"mail$user_end: %s",vms_message(status),0);
  }
  return(status);
}

/* ======================================================================== */
/* Mail Delete Message */
/* ======================================================================== */
int mail_delete_message(POP *p,int *message_id)
{
  int status = SS$_NORMAL;

  if (!p->newmail_selected)
    status = mail_folder_select(p,newmail_folder);
  if (!vms_error(status))
  {
    itemopen(inlist_ptr,inlist);
    itemadd(inlist_ptr,sizeof(message_id),MAIL$_MESSAGE_ID,message_id,0);
    itemadd(inlist_ptr,0,MAIL$_NOSIGNAL,0,0);
    itemclose(inlist_ptr);
    status = mail$message_delete(&p->message_context,inlist,nullist);
    if (vms_error(status))
      pop_log(p,"mail$message_delete: %s",vms_message(status),0);
  }
  return(status);
}

/* ======================================================================== */
/* Mail Folder Select */
/* ======================================================================== */
int mail_folder_select(POP *p,char *folder_name)
{
#define MAX_MESSAGES 20  /* limit per connection per client */
  int length;
  int messages = 0;
  int status;

  p->msg_count = 0;

  itemopen(inlist_ptr,inlist);
  itemadd(inlist_ptr,strlen(folder_name),MAIL$_MESSAGE_FOLDER,folder_name,0);
  itemadd(inlist_ptr,0,MAIL$_NOSIGNAL,0,0);
  itemclose(inlist_ptr);

  itemopen(outlist_ptr,outlist);
  itemadd(outlist_ptr,sizeof(messages),MAIL$_MESSAGE_SELECTED,
          &messages,&length);
  itemadd(outlist_ptr,0,MAIL$_NOSIGNAL,0,0);
  itemclose(outlist_ptr);

  status = mail$message_select(&p->message_context,inlist,outlist);
  if (vms_error(status))
  {
    p->msg_count = 0;
    if (status == MAIL$_NOTEXIST)
      status = SS$_NORMAL;
    else
      pop_log(p,"mail$message_select: %s",vms_message(status),0);
  }
  else
  {
    p->msg_count        = min(messages,MAX_MESSAGES);
    p->newmail_selected = TRUE;
    p->msgs_deleted     = 0;
  }
  return(status);
}

/* ======================================================================== */
/* Mail Message Bytes */
/* ======================================================================== */
int mail_message_bytes(POP *p,int *message_id,unsigned int *bytes)
{
  int  length = 0, size;
  int  lines  = 0;
  int  i, status;
  char external_id[256];
  char path[256];
  char buffer[256];
  stat_t statbuf;
  Message *mp;
  int   tmp, is_external=0;
  char errmsg1[] = "An error has been detected in this VMS mail file !!!";
  char errmsg2[] =
           "It seems that the body of the message is missing on the VMS host";
  char errmsg3[] = "Use the return address to contact the original sender...";

  *bytes = 0;
  mp = &p->mptr[*message_id-1];
  itemopen(inlist_ptr,inlist);
  itemadd(inlist_ptr,sizeof(message_id),MAIL$_MESSAGE_ID,message_id,0);
  itemadd(inlist_ptr,0,MAIL$_NOSIGNAL,0,0);
  itemclose(inlist_ptr);
  itemopen(outlist_ptr,outlist);
  itemadd(outlist_ptr,sizeof(external_id)-1,MAIL$_MESSAGE_EXTID,external_id,
          &length);
  itemadd(outlist_ptr,0,MAIL$_NOSIGNAL,0,0);
  itemclose(outlist_ptr);
  status = mail$message_info(&p->message_context,inlist,outlist);
  if (vms_error(status))
  {
    pop_log(p,"mail$message_info: %s",vms_message(status),0);
    return(POP_FAILURE);
  }

  external_id[length] = '\0';
  is_external = length;
  if (is_external > 0)
  {                             /* Mail file is external to MAIL.MAI */
      sprintf(path,"%s%s",p->mail_directory,external_id);
      statbuf.st_size = 0;
      if (stat(path,&statbuf) < 0)      /* problems with external file */
      {
        pop_log(p,"stat failed",0);
        if ((tmp = creat(path ,0,"rat=cr","rfm=var","shr=nil")) < 0)
          pop_log(p,"creat failed",0);
        else
        {
            write(tmp, errmsg1, sizeof(errmsg1));
            write(tmp, errmsg2, sizeof(errmsg2));
            write(tmp, errmsg3, sizeof(errmsg3));
            close(tmp);
            mp->lines = 4;      /* adjust lines to report */
        }
      }
  }

  itemopen(inlist_ptr,inlist);
  itemadd(inlist_ptr,sizeof(message_id),MAIL$_MESSAGE_ID,message_id,0);
  itemadd(inlist_ptr,0,MAIL$_NOSIGNAL,0,0);
  itemclose(inlist_ptr);
  status = mail$message_get(&p->message_context,inlist,outlist);
  if (vms_error(status))
    pop_log(p,"mail$message_get: %s",vms_message(status),0);
  else
  {
    /* get the size of all header lines */
    status = SS$_NORMAL;
    itemopen(inlist_ptr,inlist);
    itemadd(inlist_ptr,0,MAIL$_MESSAGE_CONTINUE,0,0);
    itemadd(inlist_ptr,0,MAIL$_NOSIGNAL,0,0);
    itemclose(inlist_ptr);
    itemopen(outlist_ptr,outlist);
    itemadd(outlist_ptr,sizeof(buffer)-1,MAIL$_MESSAGE_RECORD,buffer,&length);
    itemadd(outlist_ptr,0,MAIL$_NOSIGNAL,0,0);
    itemclose(outlist_ptr);
    status = SS$_NORMAL;
    for (i=1; i <=4; i++)
    {
        status = mail$message_get(&p->message_context,inlist,outlist);
        if (vms_error(status))
        {
            pop_log(p,"mail$message_get in headers loop: %s",
                   vms_message(status),0);
            return(POP_FAILURE);
        }
        buffer[length] = '\0';
        *bytes += length;
    }
  }

  if (is_external > 0)
  {
      sprintf(path,"%s%s",p->mail_directory,external_id);
      statbuf.st_size = 0;
      if (stat(path,&statbuf) < 0)      /* possible problems in external file */
        pop_log(p,"stat failed",0);
      else
        *bytes = *bytes + statbuf.st_size;
  }

  /* Add bytes for "Date:" line */
  if (*bytes > 0) *bytes += strlen("Date: DAY, DD MMM YY HH:MM:SS");
  return(status);
}

/* ======================================================================== */
/* Mail Message From */
/* ======================================================================== */
char *mail_message_from(POP *p,int *message_id)
{
  int  length = 0;
  int  status;
  char from_line[256];

  if (!p->newmail_selected)
    status = mail_folder_select(p,newmail_folder);
  itemopen(inlist_ptr,inlist);
  itemadd(inlist_ptr,sizeof(message_id),MAIL$_MESSAGE_ID,message_id,0);
  itemadd(inlist_ptr,0,MAIL$_NOSIGNAL,0,0);
  itemclose(inlist_ptr);
  itemopen(outlist_ptr,outlist);
  itemadd(outlist_ptr,sizeof(from_line)-1,MAIL$_MESSAGE_FROM,from_line,
          &length);
  itemadd(outlist_ptr,0,MAIL$_NOSIGNAL,0,0);
  itemclose(outlist_ptr);
  status = mail$message_info(&p->message_context,inlist,outlist);
  from_line[length] = '\0';
  if (vms_error(status))
  {
    pop_log(p,"mail$message_info: %s",vms_message(status),0);
    return(NULL);
  }
  else
    return(&from_line);
}

/* ======================================================================== */
/* Mail Message Lines */
/* ======================================================================== */
int mail_message_lines(POP *p,int *message_id)
{
  int  length = 0;
  int  status;
  int  size = 0;

  itemopen(inlist_ptr,inlist);
  itemadd(inlist_ptr,sizeof(message_id),MAIL$_MESSAGE_ID,message_id,0);
  itemadd(inlist_ptr,0,MAIL$_NOSIGNAL,0,0);
  itemclose(inlist_ptr);
  itemopen(outlist_ptr,outlist);
  itemadd(outlist_ptr,sizeof(size),MAIL$_MESSAGE_SIZE,&size,&length);
  itemadd(outlist_ptr,0,MAIL$_NOSIGNAL,0,0);
  itemclose(outlist_ptr);
  status = mail$message_info(&p->message_context,inlist,outlist);
  if (vms_error(status))
  {
    pop_log(p,"mail$message_info: %s",vms_message(status),0);
    return(-1);
  }
  return(size);
}

/* ======================================================================== */
/* Mail Open File Context */
/* ======================================================================== */
int mail_open_file_context(POP *p)
{
  int status;

  pop_log(p,"opening %s",p->mail_file,0);
  status = mail$mailfile_begin(&p->file_context,nullist,nullist);
  if (vms_error(status))
    pop_log(p,"mail$mailfile_begin: %s",vms_message(status),0);
  else
  {
    itemopen(inlist_ptr,inlist);
    itemadd(inlist_ptr,strlen(p->mail_file),MAIL$_MAILFILE_NAME,
            &p->mail_file,0);
    itemadd(inlist_ptr,0,MAIL$_NOSIGNAL,0,0);
    itemclose(inlist_ptr);
    status = mail$mailfile_open(&p->file_context,inlist,nullist);
    if (vms_error(status))
      pop_log(p,"mail$mailfile_open: %s",vms_message(status),0);
  }

  if (vms_error(status))
    p->file_context = NO_CONTEXT;

  return(status);
}

/* ======================================================================== */
/* Mail Open Message Context */
/* ======================================================================== */
int mail_open_message_context(POP *p)
{
  int status;

  itemopen(inlist_ptr,inlist);
  itemadd(inlist_ptr,sizeof(p->file_context),MAIL$_MESSAGE_FILE_CTX,
          &p->file_context,0);
  itemadd(inlist_ptr,0,MAIL$_NOSIGNAL,0,0);
  itemclose(inlist_ptr);
  status = mail$message_begin(&p->message_context,inlist,nullist);
  if (vms_error(status))
  {
    pop_log(p,"mail$message_begin: %s",vms_message(status),0);
    p->message_context = NO_CONTEXT;
  }
  return(status);
}

/* ======================================================================== */
/* Mail Open User Context */
/* ======================================================================== */
int mail_open_user_context(POP *p)
{
  int status;

  status = mail$user_begin(&p->user_context,nullist,nullist);
  if (vms_error(status))
  {
    p->user_context = NO_CONTEXT;
    pop_log(p,"mail$user_begin: %s",vms_message(status),0);
  }
  return(status);
}

/* ======================================================================== */
/*  Mail Retrieve Messages */
/* ======================================================================== */
int mail_retrieve_messages(POP *p,int message_id, int numlines)
{
#define MAXHEADERS 4
  int  status = SS$_NORMAL;
  int  bytes;
  int  length;
  int  lines=0, headers=1;
  short int  record_type;
  char buffer[256], hold_cc[256], hold_to[256], tmp[256], message_date[32];
  char *pointer;

  if (!p->newmail_selected)
    status = mail_folder_select(p,newmail_folder);
  if (!vms_error(status))
  {
   if ((message_id < 1) || (message_id > p->msg_count))
        return (pop_msg
            (p,POP_FAILURE,"Message %d does not exist.",message_id,0));
   else
   {
      retrieved_messages++;
      if (message_id > p->last_msg) p->last_msg = message_id;
      itemopen(inlist_ptr,inlist);
      itemadd(inlist_ptr,sizeof(message_id),MAIL$_MESSAGE_ID,&message_id,0);
      itemadd(inlist_ptr,0,MAIL$_NOSIGNAL,0,0);
      itemclose(inlist_ptr);
      itemopen(outlist_ptr,outlist);
      itemadd(outlist_ptr,sizeof(message_date),MAIL$_MESSAGE_DATE,
              message_date,&length);
      itemadd(outlist_ptr,0,MAIL$_NOSIGNAL,0,0);
      itemclose(outlist_ptr);
      status = mail$message_get(&p->message_context,inlist,outlist);
      if (vms_error(status))
      {
        pop_log(p,"mail$message_get: %s",vms_message(status),0);
        return(POP_FAILURE);
      }
      else
      {
        pop_log(p,"headers follow",0);
        message_date[length] = '\0';
        sprintf(buffer,"Date: %s",date_vms2unix(message_date));
        pop_sendline(p, buffer);
        printf("   %s",buffer);

        itemopen(inlist_ptr,inlist);
        itemadd(inlist_ptr,0,MAIL$_MESSAGE_CONTINUE,0,0);
        itemadd(inlist_ptr,0,MAIL$_NOSIGNAL,0,0);
        itemclose(inlist_ptr);
        itemopen(outlist_ptr,outlist);
        itemadd(outlist_ptr,sizeof(buffer)-1,MAIL$_MESSAGE_RECORD,buffer,
                &length);
        itemadd(outlist_ptr,sizeof(record_type),MAIL$_MESSAGE_RECORD_TYPE,
                &record_type,0);
        itemadd(outlist_ptr,0,MAIL$_NOSIGNAL,0,0);
        itemclose(outlist_ptr);
        status = SS$_NORMAL;
        for (headers=1; headers<=MAXHEADERS && !vms_error(status); headers++)
        {
          status = mail$message_get(&p->message_context,inlist,outlist);
          if (vms_error(status))
          {
            pop_log(p,"mail$message_get: %s",vms_message(status),0);
            return(POP_FAILURE);
          }
          else
          {
            buffer[length] = '\0';
            while ((pointer = strchr(buffer,'\t')) != NULL) *pointer = ' ';
            switch (headers)
            {
                case FROM_LINE:
                        printf("   %s\n",buffer);
#ifdef PATCH_FROM_LINE
                        patch_from_line(p,buffer);
#endif
                        pop_sendline(p, buffer);
                        printf("   %s",buffer);
                        break;

                case CC_LINE:
                        strcpy(hold_cc, buffer);
                        lower(&hold_cc[1]);
                        break;

                case SUBJECT_LINE:
                        sprintf(tmp,"Subject%s", &buffer[4]);
                        p->newmail_size = p->newmail_size+3;
                        pop_sendline(p, tmp);
                        printf("   %s",tmp);
                        pop_sendline(p, hold_to);
                        printf("   %s",hold_to);
                        pop_sendline(p, hold_cc);
                        printf("   %s",hold_cc);
                        break;

                case TO_LINE:
                        strcpy(hold_to, buffer);
                        lower(&hold_to[1]);
                        break;
            }
          }
        }

        while (lines < numlines && !vms_error(status))
        {
            status = mail$message_get(&p->message_context,inlist,outlist);
            if (vms_error(status))
            {
              pop_log(p,"mail$message_get: %s",vms_message(status),0);
              return(POP_FAILURE);
            }
            else
            {
              buffer[length] = '\0';
              lines++;
              pop_sendline(p, buffer);
            }
         }
      }
    }
  }
  else
  {
    pop_log(p,"retrieve_message context: %s",vms_message(status),0);
    return(POP_FAILURE);
  }

  return(POP_SUCCESS);
}

/* ======================================================================== */
/* Mail User Info */
/* ======================================================================== */
int mail_user_info(POP *p)
{
  int  status;
  int  length = 0;
  char scratch[256];

  itemopen(inlist_ptr,inlist);
  itemadd(inlist_ptr,strlen(p->user),MAIL$_USER_USERNAME,
          &p->user,0);
  itemadd(inlist_ptr,0,MAIL$_NOSIGNAL,0,0);
  itemclose(inlist_ptr);
  itemopen(outlist_ptr,outlist);
  itemadd(outlist_ptr,sizeof(scratch)-1,MAIL$_USER_FULL_DIRECTORY,scratch,
          &length);
  itemadd(outlist_ptr,0,MAIL$_NOSIGNAL,0,0);
  itemclose(outlist_ptr);
  status = mail$user_get_info(&p->user_context,inlist,outlist);
  scratch[length] = '\0';
  if (vms_error(status))
    pop_log(p,"mail$user_get_info: %s",vms_message(status),0);
  else
  {
    strcpy(p->mail_directory,scratch);
    strcpy(p->mail_file,scratch);
    strcat(p->mail_file,"MAIL.MAI");
  }
  return(status);
}

/* ========================================================================= */
/* User Exists */
/* ========================================================================= */
int user_exists(char *username)
{
  int  status;
  int  value = FALSE;
  int  flags;
  char upcase_username[80];
  struct dsc$descriptor_s username_desc = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};

  strcpy(upcase_username,username);
  upper(upcase_username);
  itemopen(outlist_ptr,outlist);
  itemadd(outlist_ptr,sizeof(flags),UAI$_FLAGS,&flags,0);
  itemclose(outlist_ptr);
  username_desc.dsc$a_pointer = upcase_username;
  username_desc.dsc$w_length  = strlen(upcase_username);
  status = sys$getuai(0,0,&username_desc,outlist,0,0,0);
  if (vms_error(status))
    system_log("sys$getuai error for \"%s\": %s",username,vms_message(status),0);
  else
  {
    if (!(flags & UAI$M_NOMAIL)) value = TRUE;
  }
  return(value);
}

/* ========================================================================== */
/* VMS Message String */
/* ========================================================================== */
char *vms_message(unsigned int code)
{
  static   char  message[256];
  unsigned short length = 0;
  struct   dsc$descriptor message_dx;

  memset(message,0,sizeof(message));
  message_dx.dsc$w_length  = sizeof(message);
  message_dx.dsc$a_pointer = &message;
  sys$getmsg(code,&length,&message_dx,0xf,0);
  message[length] = '\0';
  return(&message);
}

/* ======================================================================== */
/* Mail Message Move */
/* ======================================================================== */
int mail_message_move(POP *p,int message_id)
{
  int status = SS$_NORMAL;
  char mail_folder[] = "MAIL";

  if (!p->newmail_selected)
    status = mail_folder_select(p, newmail_folder);
  if (vms_error(status))
    return(POP_FAILURE);
  else
  {
    itemopen(inlist_ptr,inlist);
    itemadd(inlist_ptr,sizeof(message_id),MAIL$_MESSAGE_ID,&message_id,0);
    itemadd(inlist_ptr,strlen(p->mail_file),MAIL$_MESSAGE_DEFAULT_NAME,
            &p->mail_file,0);
    itemadd(inlist_ptr,strlen(mail_folder),MAIL$_MESSAGE_FOLDER,mail_folder,0);
    itemadd(inlist_ptr,0,MAIL$_MESSAGE_DELETE,0,0);
    itemadd(inlist_ptr,0,MAIL$_NOSIGNAL,0,0);
    itemclose(inlist_ptr);
    status = mail$message_copy(&p->message_context,inlist,nullist);
    if (vms_error(status))
    {
        pop_log(p,"mail$message_copy: %s",vms_message(status),0);
        return(POP_FAILURE);
    }
  }
  return(POP_SUCCESS);
}

/* ======================================================================== */
/* Mail Mark Deleted */
/* ======================================================================== */
int mail_message_new_count(POP *p)
{
    int status = SS$_NORMAL;

    itemopen(inlist_ptr,inlist);
    itemadd(inlist_ptr,strlen(p->user),MAIL$_USER_USERNAME, &p->user,0);
    itemadd(inlist_ptr, sizeof(p->msg_count),MAIL$_USER_SET_NEW_MESSAGES,
        &p->msg_count,0);
    itemadd(inlist_ptr,0,MAIL$_NOSIGNAL,0,0);
    itemclose(inlist_ptr);
    status = mail$user_set_info(&p->user_context,inlist,nullist);
    if (vms_error(status))
      pop_log("mail$user_set_info: %s",vms_message(status),0);
    return(status);
}

/* ======================================================================== */
/* MailFile Purge Waste */
/* ======================================================================== */
int mail_purge_waste(POP *p)
{
    int status = SS$_NORMAL;

    itemopen(inlist_ptr,inlist);
    itemadd(inlist_ptr,0,MAIL$_MAILFILE_RECLAIM,0,0);
    itemadd(inlist_ptr,0,MAIL$_NOSIGNAL,0,0);
    itemclose(inlist_ptr);
    status = mail$mailfile_purge_waste(&p->file_context,inlist,nullist);
    if (vms_error(status))
    {
      pop_log(p,"mail$mailfile_purge_waste: %s",vms_message(status),0);
      return(POP_FAILURE);
    }
    return(POP_SUCCESS);
}
