/*
 *  MBCONV10 - 10/1/91A
 *
 *  Copyright (C) 1991
 *  By the CBBS Group.
 *
 *  This program converts the mail datafile from a version 9
 *  mail system to version 10 format.
 *  Version 9 & 10 format requires that the file header information
 *  be included in the first record of the textfile.
 *  Normal textfile data starts at offset 256 in the file.
 *
 *  It is expected that MBCONV10.EXE be placed in the directory
 *  containing the textfiles and be executed from there.
 *  It is also expected that the file MAIL.DAT will be located in the
 *  directory \MB\BBS but if this is not the case, the user will be
 *  given the option of entering the actual directory path information.
 *  Optionally the program can be invoked with the path to the mail.dat
 *  as a command line parameter such as MBCONV10 \HF\BBS.
 *
 */

#include "mb.h"
#define ln_hier 64

/*  Old message header record. */


typedef struct omsg_hdr_s
{
  byte ext;           /* Header extension record, or zero                */
  word rn;            /* Record number of this record                    */
  word read;          /* # times the message has been read               */
  word number;        /* Message number                                  */
  word size;          /* Size in bytes                                   */
  char type;          /* Message type                                    */
  byte stat;          /* Message status, see bit definitions above       */
  char to  [ln_call]; /* Destination call                                */
  char from[ln_call]; /* Originator call                                 */
  char bbs [ln_call]; /* Destination BBS, or distribution list           */
  char date[ln_date]; /* Entry date                                      */
  char time[ln_time]; /* Entry time                                      */
  char bid[ln_bid];   /* Bulletin ID, if this is a bulletin              */
  char title[80];     /* Title of message                                */
  char call[16] [ln_call];    /*Distribution calls                       */
  byte flag[16];      /* Distribution flags                              */
  byte count;         /* Number of calls in list                         */
  char fwdc[ln_call]; /* Forwarded callsign                              */
#ifdef MCH_AMIGA
  unsigned char lifetime; /* Lifetime field for compatibility with THEBOX*/
  char unu[5];
#else
  char unu[6];
#endif
} OMSG_HDR;

OMSG_HDR  *o_tmmhs;

/*
 *  Old mail file header record.
 */


typedef struct omail_hdr_s
{
  word next;          /* Next record to allocate         */
  word first;         /* First message header record     */
  word last;          /* Last message header record      */
  word next_msg;      /* Next message number             */
  word unt_msg;       /* next_msg at last untangle       */
  byte version;       /* File format version number      */
  word free;          /* Number of records in free chain */
  word count;         /* Number of messages              */
  char date[ln_date]; /* Date of last untangle           */
  char time[ln_time]; /* Time of last untangle           */
  char unu[231];
} OMAIL_HDR;

OMAIL_HDR *o_mfhs;



main(argc, argv)
int argc;
char *argv[];
{

register word h, rec;
register char c;
char *mpath;
char mbfile[80], mbnfile[80];
char flags[mmesn];
int mfl,  mfln, n;
MAIL_HDR  *mfhs;
MSG_HDR   *tmmhs;


/*
 *  Allocate space for the mail file records.
 */

  mfhs    =  (MAIL_HDR *) malloc(sizeof(MAIL_HDR));
  tmmhs   =  (MSG_HDR *)  malloc(sizeof(MSG_HDR));
  o_tmmhs =  (OMSG_HDR *) malloc(sizeof(OMSG_HDR));
  o_mfhs  =  (OMAIL_HDR *)malloc(sizeof(OMAIL_HDR));

#ifndef MCH_AMIGA
  if(argc > 1) mpath = argv[1]; else mpath = "\\mb\\bbs";
  sprintf(mbfile, "%s\\MAIL.DAT", mpath);
#else
  if(argc > 1) mpath = argv[1]; else mpath = "";
  sprintf(mbfile, "%s/MAIL.DAT", mpath);
#endif

/*
 *  Open the mail file.
 */

  if ((mfl = open(mbfile, O_RDONLY | O_BINARY)) < 0)
     { puts("MAIL.DAT is not in this directory.\nInput directory");
       gets(mpath);
#ifndef MCH_AMIGA
       sprintf(mbfile, "%s\\MAIL.DAT", mpath);
#else
       sprintf(mbfile, "%s/MAIL.DAT", mpath);
#endif
       if ((mfl = open(mbfile, O_RDONLY | O_BINARY)) < 0)
    { puts("MAIL.DAT is not in that directory either. Aborting\n");
      exit(1);
    }
     }

/*
 *  Read the mail file header.
 */

  read_rec(mfl, 0, (char *)mfhs);
  if (mfhs->version is 10)
   { puts("Mailfile has been converted previously. Aborting\n"); exit(1);}
  read_rec(mfl, 0, (char *)o_mfhs);   
  if (o_mfhs->version < 9 )
   { puts("Mailfile is wrong version. Aborting\n"); exit(1);}

/*
 *  Creat the NEW mail file
 */

  sprintf(mbnfile, "%s\\MAIL.NEW", mpath);
  if((mfln = open(mbnfile, O_CREAT | O_RDWR | O_BINARY, pmode)) < 0)
   { puts("MAIL.NEW cannot be opened");
     exit (1);
   }
  rec = 0;
/*
 *  Read the mail file records in sequence and
 *  process each corresponding text file.
 */

  for (h = o_mfhs->first; h and h < o_mfhs->next; h++)
  {
    read_rec(mfl, h, (char *)o_tmmhs);
    printf("\r%u",h);

    fill(tmmhs, '\0', 256);
    fill(flags, ' ', mmesn);

    tmmhs->read     = o_tmmhs->read;
    tmmhs->number   = o_tmmhs->number;
    tmmhs->size     = o_tmmhs->size;
    tmmhs->type     = o_tmmhs->type;
    tmmhs->stat     = o_tmmhs->stat;
    strncpy(tmmhs->to, o_tmmhs->to, ln_call);
    strncpy(tmmhs->from, o_tmmhs->from, ln_call);
    strncpy(tmmhs->bbs, o_tmmhs->bbs, ln_call);
    strncpy(tmmhs->date, o_tmmhs->date, ln_date);
    strncpy(tmmhs->time, o_tmmhs->time, ln_time);
    strncpy(tmmhs->bid, o_tmmhs->bid, ln_bid);
    strcpy(tmmhs->title, o_tmmhs->title);
    strncpy(tmmhs->fwdc, o_tmmhs->fwdc, ln_call);
#ifdef MCH_AMIGA
    tmmhs->lifetime = o_tmmhs->lifetime;
#endif
    tmmhs->ext = o_tmmhs->ext;

    if (o_tmmhs->count > mmesn) o_tmmhs->count = mmesn;
    if(o_tmmhs->ext is 1)
    {
      for (c = 0; c < o_tmmhs->count; c++)
      {
     strncpy(tmmhs->call[c], o_tmmhs->call[c], ln_call);
     tmmhs->flag[c] = o_tmmhs->flag[c];
     flags[c] = tmmhs->flag[c] + '0';
      }
      tmmhs->count = o_tmmhs->count;
    }
    if (o_tmmhs->ext is 2)
    strncpy(tmmhs->call[0], o_tmmhs->call[0], ln_hier);

    ++rec;
    tmmhs->rn = rec;

    fill( tmmhs->fwdd, '\0', ln_call);
    fill( tmmhs->fwdl, '\0', ln_call);
    tmmhs->orgnum = 0;
    tmmhs->sp1 = 0;
    tmmhs->sp2 = 0;
    tmmhs->htype = 0;
    tmmhs->fport = 'F';

    write_rec(mfln, rec, (char *)tmmhs);

  }

/*
 *  Write new version number to mailfile and close the file.
 */

  printf(" records converted.\n");
  printf("MAIL.DAT had %u messages, MAIL.NEW has %u messages.\n",
     o_mfhs->count, rec);
  mfhs->version = mb_version;
  mfhs->count = mfhs->last = rec;
  mfhs->first = 1;
  mfhs->next = rec + 1;
  mfhs->free = 0;
  mfhs->next_msg = o_mfhs->next_msg;
  mfhs->unt_msg = o_mfhs->unt_msg;
  strncpy(mfhs->date, o_mfhs->date, ln_date);
  strncpy(mfhs->time, o_mfhs->time, ln_time);
  fill(mfhs->unu, '\0', mfhsunu);

  write_rec(mfln, 0, (char *)mfhs);
  close(mfl);
  unlink(mbfile);
  printf("Deleting %s\n", mbfile);
  close(mfln);
  printf("Renameing %s to %s\n", mbnfile, mbfile);
  rename(mbnfile, mbfile);

}

/*
 *  Write random record.
 */

write_rec(fid, rec, buffer)
int fid;
int rec;
char buffer[];
{
#ifndef MCH_AMIGA
  long lseek();
#endif
  long offs;

  offs = (long)rec * (long)RECSIZE;
  lseek(fid, offs, 0);
  return (write(fid, buffer, RECSIZE) is RECSIZE);
}

/*
 *  Read random record.
 */

read_rec(fid, rec, buffer)
int fid;
int rec;
char buffer[];
{
#ifndef MCH_AMIGA
  long lseek();
#endif
  long offs;

  offs = (long)rec * (long)RECSIZE;
  lseek(fid, offs, 0);
  return (read(fid, buffer, RECSIZE) is RECSIZE);
}

/*
 *  Fill some memory with a character.
 */

fill(adr, ch, len)
char *adr;
char ch;
int len;
{
  while (len--) *adr++ = ch;
}

