/****************************************
 *                                      *
 *  Code for the commands starts here   *
 *                                      *
 ****************************************/
#include "mb.h"

#define btmax 112   /* Max text in beacon line */
#ifdef MCH_AMIGA
extern char passchr,vhfstream,hfstream;
extern char tmpstr[];
extern short all_number;
#endif

extern char  orgmsg[6], orgbbs[7], orgtime[5], orgdate[7];

extern char  *mbfile, *mbbfile, *msgdir, *bidfile;


extern char  *bfwd;  /* Calls with unread msgs, for forwarding */

extern short ufwdm, ufwdn, bfwdm, bfwdn;
extern short tstaleb, tstalen, tstaleu;
extern int bidok, hidok, hasbid, needbid, holdit;

extern char  *mm[num_mm];
extern char  wpcall[ln_call];
extern XBBS  *xbbs;
extern HOLD  *hold;

extern MAIL_HDR  *mfhs;
extern MSG_HDR   *tmmhs;

extern FILE *bfl;

extern int mfl, mflb;


/*
 *  GM or GR command: backup the mail file.
 */

untmsg()
{
  register word inhdr, me;
  if (port->opt2 isnt 'A') { if (sure()) return; }
  if (!mfhs->count) { port->msg = mm[5]; return; }
  prtx(mm[6]);

  close(mfl);         /*  Close current.  */

  unlink(mbbfile);    /*  Delete backup   */

/*
 *  Copy current to backup.
 */

  if (samedir(mbfile, mbbfile)) rename(mbfile, mbbfile);
  else copy(mbfile, mbbfile, false);

  unlink(mbfile);     /*  Delete current.  */

/*
 *  Open new current and backup.
 */

  mfl  = open(mbfile,  O_CREAT  | O_RDWR | O_BINARY, pmode);
  mflb = open(mbbfile, O_RDONLY | O_BINARY);

  read_rec(mflb, 0, (char *)mfhs);
  me = mfhs->last;
  inhdr = mfhs->first;
  inithdr();

  if (port->opt2 is 'R')
  {
    if (port->flds is 1) mfhs->next_msg = 1;
    else mfhs->next_msg = atoi(port->fld[1]);
  }


  while(inhdr <= me)        /*  For each message header ... */
  {
    read_rec(mflb, inhdr, (char *)port->mmhs); /* Read the header. */

/*
 *  Tell the sysop about this message.
 */

    sprintf(port->line, "Hdr %6u Size %6u # %6u Read %6u",
      inhdr, port->mmhs->size, port->mmhs->number, port->mmhs->read);
    outstr(port->line);

    inhdr++;

    if (!(port->mmhs->stat & ( m_kill | m_busy)))
    {
       outstr("\n");

/*
 *  If renumbering messages, renumber this message.
 */

       if (port->opt2 is 'R')
       {
         msgfile(port->line, port->mmhs->number);
         msgfile(port->cmd,  mfhs->next_msg);
         rename(port->line, port->cmd);
         port->mmhs->number = mfhs->next_msg++;
       }

/*
 *  Write the header.
 */

       port->mmhs->rn = ++mfhs->count;
       wt_mmhs();
    }
    else arcmsg();
  }


/*
 *  Write the file header.
 */
  if (mfhs->count) mfhs->first = 1;
  mfhs->next = mfhs->count + 1;
  mfhs->last = mfhs->count;
  mfhs->unt_msg = mfhs->next_msg;
  write_rec(mfl, 0, (char *)mfhs);
  close(mflb);
  clnmsg();
#ifdef MCH_AMIGA
   titles();
#endif
}


/*
 *  Print headers of unread messages for this user.
 */

newmsg()
{
  if (findfwd(port->user->call, ufwd, ufwdn) or
      findfwd(port->user->call, bfwd, bfwdn))
  {
    prtx(mm[2]);
    port->opt2 = '\0';
    port->flds = 1;
    lstmsg();
  }
}

/*
 *  L command, list messages.
 */

lstmsg()
{
  register char *p;
  register short done, ok;
  word h, found, more;

/*
 *  First set up arguments.
 */

  found = 0; more = 0; done = false;
  if ((*port->fld[1] is ';') or (*port->fld[2] is ';')) port->flds--;
  switch(port->opt2)
  {
    case '@' :
    case '<' :
    case '>' : pcall(tcall, port->fld[1]); break;
    case '\0': break;
    case 'E' :
    case ' ' : if (port->flds is 1) more = port->user->msg_number;
    default  : if (port->flds is 2)
      {
        if (!num(port->fld[1])) { port->msg = mwhat; return; }
        more = atoi(port->fld[1]);
      }
  }

/*
 *  Log it, unless is initial login check for msgs.
 */

  if (port->opt2)
  {
    sprintf(port->line, "%u", more);
    log('M', 'L', port->opt2, port->line);
  }

/*
 *  Paw through the messages and show what requested.
 */

  for (h = mfhs->last; h and !done; h--)
  {
    read_rec(mfl, h, (char *)port->mmhs);
    if ((port->opt2 is 'L') or ((port->opt2 is 'E') and (port->flds is 2)))
      done = (found is more); else done = (port->mmhs->number < more);

    ok = !done;

/*
 *  Does this user have read permission for this message?
 */

    if (ok) ok = lpermit();
    if (ok) if (port->mmhs->stat & m_kill)
    ok = ((port->opt2 is 'K') or (port->opt2 is 'E'));
    if (ok) if (port->mmhs->stat & m_busy) ok = (port->opt2 is 'E');

/*
 *  Is this message wanted?
 */

    if (ok) switch(port->opt2)
    {
      case '\0': ok = matchn(port->user->call, port->mmhs->to, ln_call); break;
      case 'E' : break;
      case 'K' : ok = (port->mmhs->stat & m_kill); break;
      case 'F' : ok = (port->mmhs->stat & m_fwd);  break;
      case 'H' : ok = (port->mmhs->stat & m_hold); break;
      case 'L' : break;
      case 'M' : ok = matchn(port->user->call, port->mmhs->to, ln_call);
                if (!ok) ok = matchn(port->user->call, port->mmhs->from, ln_call);
                break;

      case 'O' : ok = (port->mmhs->stat & m_stale); break;
      case 'U' : ok = !((port->mmhs->type is 'B')or(port->mmhs->type is 'A')
                       or (port->mmhs->stat & (m_fwd | m_read))); break;
      case 'Y' : ok = (port->mmhs->stat & m_read);  break;
      case '@' : ok = matchn(tcall, port->mmhs->bbs, ln_call); break;
      case '<' : ok = matchn(tcall, port->mmhs->from, ln_call); break;
      case '>' : ok = matchn(tcall, port->mmhs->to, ln_call); break;
      default  : ok = ((port->mmhs->type is port->opt2) or
                       (port->opt2 is ' '));
    }
    if (ok) prthdr(!found++);
  }
  if (!found) port->msg = mfind;
  s_flag setbit s_update;
}

/*
 *  CM command: duplicate a message.
 */

dupmsg()
{
  word tmpsize;
  if (!findmsg(atoi(port->fld[2]))) { port->msg = mnmsg; return; }
  port->opt1 = 'S';

  prthdr(true);
  pcall(port->mmhs->to, port->fld[1]);
  fill(port->mmhs->bbs, ' ', ln_call);
  port->mmhs->ext = 0;

  if (port->flds > 3) atfrom(port->flds - 2);
  if (port->flds > 5) atfrom(port->flds - 4);
  tmpsize = port->mmhs->size;
/* Override @bbs if the user is on file */
#ifdef MCH_AMIGA
   replace_bbs(&port->mmhs->to,&port->mmhs->bbs);
#endif

  msgfile(port->cmd, port->mmhs->number);
  initmsg(false);
  msgfile(port->line, mfhs->next_msg);
  copy(port->cmd, port->line, false);
  filesize = tmpsize;
  cremsg();
}

/*
 *  F command: copy a message to a file.
 */

filmsg()
{
  register char *p;
  register short hdr, append;
  register FILE *out;

  if (!findmsg(atoi(port->fld[1]))) { port->msg = mnmsg; return; }

  hdr = true;
  append = false;

  if (port->flds is 4) for (p = port->fld[3]; *p; p++) switch (*p)
  {
    case 'A' : append = true; break;
    case 'N' : hdr    = false; break;
    default: ;
  }

  if (port->opt2 is ' ') strcpy(port->line, port->fld[2]);
  else if (getdir(port->fld[2]) is NULL) { port->msg = mndir; return; }

  if (append) out = fopen (port->line, "a"); else
  {
    if ((out = fopen (port->line, "r")) isnt NULL)
      { fclose(out); port->msg = mexst; return; }
    out = fopen (port->line, "w");
  }

  if (out is NULL) { port->msg = mcant; return; }

  sprintf(tmp->scr, "%s %s", port->fld[1], port->line);
  log('M', 'D', port->opt2, tmp->scr);

  prthdr(true);

  if (hdr) fputs(tmp->scr, out);

  msgfile(port->cmd, port->mmhs->number);

  if ((port->fl = fopen(port->cmd, "r")) is NULL)
    { fclose(out); nofile(port->cmd); return; }
  fseek( port->fl, (long)RECSIZE, 0);
  while (fgets(tmp->scr, scrmax, port->fl) isnt NULL) fputs(tmp->scr, out);

  fclose(port->fl);
  fclose(out);
}

/*
 *  Upload the message text file.
 */

uloadm(tname)
char *tname;
{
  register char *tp;
  register PORTS *p;
  short first;

  p = port;

  if ((p->fl = fopen(tname, "w")) is NULL) { p->msg = mcant; return false; }
  fseek( p->fl, (long)RECSIZE, 0);

  first = true;
  filesize = 0;
  while (true)
  {
    while(!getdat());

/*
 *  If user disconnected, timed out, or forced off, zap the file.
 */

    if (p->mode & gone)
    {
      fclose(p->fl);
      return false;
    }

/*
 *  If the first line is not a header (thus it is a human entering
 *  the message), make sure there is an initial blank line before
 *  the body of the message.
 */

    if (first)
    {
      first = false;
      if (!ishead(p->line)) if (*p->line isnt '\n') fputs("\n", p->fl);
    }

/*
 *  Stuff the line into the file.
 */

    if (match(p->line, "/EX\n") or match(p->line,"/ex\n"))
    {
      fclose(p->fl);
      return true;
    }


    if ((tp = strchr(p->line, cpmeof)) is NULL)
    {
      filesize += strlen(p->line);
      fputs(p->line, p->fl);
    }
    else
    {
      if (tp isnt p->line)
      {
        *tp++ = '\n';
        *tp   = '\0';
        filesize += strlen(p->line);
        fputs(p->line, p->fl);
      }
      fclose(p->fl);
      return true;
    }
  }
}

/*
 *  "Display the message text" utility.
 */

dloadm(sh)
short sh;
{
  short first;

  sprintf(port->line, "%u", port->mmhs->number);
  log('M', 'R', port->opt2, port->line);
  port->mmhs->read++;
  if (matchn(port->user->call, port->mmhs->to, ln_call))
    port->mmhs->stat setbit m_read;
  wt_mmhs();
  makehdr2();
  prthdr(true);

  msgfile(port->line, port->mmhs->number);

  if ((port->fl = fopen(port->line, "r")) is NULL)
    { nofile(port->line); return; }

  fseek( port->fl, (long)RECSIZE, 0 );
  pgst(NULL);
  pgck();   /* First line of header */
  pgck();   /* Second line of header */
  pgck();   /* Path line */
  if (port->mmhs->ext) pgck();
  if (*port->mmhs->bid isnt ' ') pgck();

  strcpy(tmp->scr, "  Path: ");
  first = true;

  while(fgets(port->line, linelen, port->fl) isnt NULL)
  {
    if (!sh)
    {
      sh = !parsehd(port->line);
      if (sh)
      {
        if (!first)
        {
          strcat(tmp->scr, "\n\n");
          outstr(tmp->scr);
          pgck();
          prtx("Date: $j/$k\n");  pgck();
          prtx("From: $P @ $a\n");  pgck();
          prtx("Message-Id: <$m@$a>\n");  pgck();
          prtx("To: $G @ ");
          if (*port->mmhs->bbs is ' ')  prtx("$O\n");
          else if (port->mmhs->ext is 2) prtx("$h\n");
          else prtx("$A\n");  pgck();
          prtx("Subject: $E\n\n");  pgck();
        }
      }
      else
      {
        if (!first) strcat(tmp->scr, "!");
        strcat(tmp->scr, orgbbs);   
        first = false;
      }
    }

    if (sh)
    {
      outstr(port->line);
      if ((pgck() is 'Q') or (chkdis())) { fclose(port->fl); return; }
    }
  }
  fclose (port->fl);
}

/*
 *  RM command: read my messages.
 */

rdmsgm()
{
  register short found;
  register word h;

  found = false;
  for (h = mfhs->first; h and h <= mfhs->last; h++)
  {
    read_rec(mfl, h, (char *)port->mmhs);
    if (!(port->mmhs->stat & (m_read | m_fwd | m_hold | m_busy)) and
      matchn(port->user->call, port->mmhs->to, ln_call))
    {
      dloadm(false);
      found = true;
      if (pause() is 'Q') return;
    }
  }
  if (!found) port->msg = mfind;
}

/*
 *  R command: read one message.
 */

rdmsg()
{
  if (!num(port->fld[1]))           { port->msg = mwhat; return; }
  if (!findmsg(atoi(port->fld[1]))) { port->msg = mnmsg; return; }
  if (!rpermit())                   { port->msg = mprot; return; }

  dloadm(port->opt2 is 'H');
}

/*
 *  KF, KM, KO, KY, KK commands, kill multiple messages.
 */

klmsgm()
{
  register short ok;
  register short found;
  word h, next;

  if (port->flds is 2) pcall(tcall, port->fld[1]);

  found = false;
  for (h = mfhs->first; h and h <= mfhs->last; h++)
  {
    read_rec(mfl, h, (char *)port->mmhs);

    ok = kpermit();
    if (ok) ok = !(port->mmhs->stat & m_hold);

    if (ok) if (port->flds is 2) ok = matchn(tcall, port->mmhs->to, ln_call);

    if (ok) switch(port->opt2)
    {
      case 'F' : ok = (port->mmhs->stat & m_fwd); break;
      case 'M' :
        ok = ((port->mmhs->stat & m_read) and
          matchn(port->user->call, port->mmhs->to, ln_call));
        break;
      case 'O' : ok = (port->mmhs->stat & m_stale); break;
      case 'Y' : ok = (port->mmhs->stat & m_read);  break;
    }

    if (ok)
    {
      sprintf(port->line, "%u", port->mmhs->number);
      log('M', 'K', port->opt2, port->line);
      prtx(mm[7]);
      found = true;
      port->mmhs->stat setbit m_kill;
      write_rec(mfl, port->mmhs->rn, (char *)port->mmhs);
      makehdr2();
    }
  }
#ifdef MCH_AMIGA
   titles();
#endif
  if (!found) port->msg = mfind;
}

/*
 *  K command, kill a message.
 */

klmsg()
{
  register short dosvc;

  if (!num(port->fld[1]))           { port->msg = mwhat; return; }
  if (!findmsg(atoi(port->fld[1]))) { port->msg = mnmsg; return; }
  if (port->mmhs->stat & m_kill)    { port->msg = mnmsg; return; }
  if (!kpermit())                   { port->msg = mprot; return; }

  log('M', 'K', port->opt2, port->fld[1]);

  dosvc = (port->opt2 is 'T') and
          (port->mmhs->type is 'T') and
          (s_param & s_svc);

  if (dosvc) findat();

/*
 *  Marked the message as  Killed.
 */

  port->mmhs->stat setbit m_kill;
  write_rec(mfl, port->mmhs->rn, (char *)port->mmhs);
  makehdr2();

/*
 *  If this is KT of T type message, and we do service messages,
 *  do the service message.
 */

  if (dosvc)
  {
    port->opt1 = 'S';
    strncpy(port->mmhs->to, port->mmhs->from, ln_call);
    strncpy(port->mmhs->from, cport->user->call, ln_call);
    port->mmhs->type = 'S';
    fill(port->mmhs->bid, ' ', ln_bid);
    port->mmhs->ext = 0;
    initmsg(false);
    msgfile(port->line, mfhs->next_msg);
    port->fl = fopen(port->line, "w");
    fseek(port->fl, (long)RECSIZE, 0);
    fprintf(port->fl, "Msg %5u taken from %6.6s by %6.6s at %4.4s on %6.6s\n",
      port->mmhs->number, cport->user->call, port->user->call, l_time, l_date);
    fclose(port->fl);

    filesize = 56;
    cremsg();
  }
  port->msg = mdone;
#ifdef MCH_AMIGA
   titles();
#endif
}

/*
 *  S command: send a message.
 */

sndmsg()
{
  FILE *out;
  char *a, *b;

  holdit = false;   /* initialize it to something */

  pfld();
  if (port->mode & gone) return;

  if (bidok) {
    if (!needbid) return;
  }
  else {
    if (port->user->options & (u_bbs | u_expert)) outstr("Msg:\n");
    else prtx(mm[1]);
  }

  msgfile(port->cmd, mfhs->next_msg);
  if (!uloadm(port->cmd)) return;

/*
 *  If this is a Bulletin and has no BID, 
 *  parse the headers and give it one.
 */
  if (!hasbid)
  if (!iscall(port->mmhs->to))
  if (port->mmhs->type is 'B')
  {
        msgfile(port->cmd, mfhs->next_msg);
        a = port->line;
        b = cport->user->call;
        unbl(a, b, 6);

/* Default the BID as to coming from this BBS with our msg number. */

        sprintf(tmp->scr, "%-u_%-s", mfhs->next_msg, port->line);

/* Now parse the headers if it came from another BBS. */

        if ((out = fopen(port->cmd, "r")) is NULL)
        {
           nofile(port->cmd); return;
        }
        fseek(out, (long)RECSIZE, 0);
        while (fgets(port->line, linelen, out) isnt NULL)
        {
           if (parsehd(port->line))
           {
             sprintf(tmp->scr, "%s_%s", orgmsg, orgbbs);
           }
        }
        fclose(out);
        strncpy(port->mmhs->bid, tmp->scr, ln_bid);
        hasbid = true;
  }
  checkbid(); 
  if (!needbid) holdit = true;
  else holdit = false;
  
  /*  If a message is to an individual, 
   *  automatically make it a private message.
   */

  if (port->opt2 is ' ')
  if (iscall(port->mmhs->to)) port->mmhs->type = 'P';

  cremsg();
}

/*
 *  SM command, send a message to a distribution list.
 */

sndmlt()
{
  register FILE *fl;
  char fn[80];
  register short first = true;
  word tmpsize;
  
  holdit = false;
  fill(port->mmhs->bid, ' ', ln_bid);

  if ((fl = fopen(port->fld[1], "r")) is NULL)
    { nofile(port->fld[1]); return; }

  prtx(mm[0]);
  get_title();
  if (port->mode & gone) { fclose(fl); return; }

  if (port->flds is 3) if (*port->fld[port->flds-1] is '$')
  {
    if (*(port->fld[port->flds-1] + 1) isnt NULL)
    {
      strncpy(port->mmhs->bid, port->fld[port->flds-1] + 1, ln_bid);
      hasbid = true;
    }
  }

  prtx(mm[1]);

  strncpy(port->mmhs->from, port->user->call, ln_call);
  port->mmhs->ext = 0;
  initmsg(false);
  msgfile(fn, mfhs->next_msg);
  if (!uloadm(fn)) { fclose(fl); return; }
  tmpsize = filesize;

  while (fgets(port->line, linelen, fl) isnt NULL)
  {
    parse();
    if (!first)
    {
      port->mmhs->ext = 0;
      initmsg(false);
      msgfile(port->line, mfhs->next_msg);
      copy(fn, port->line, false);
    }
    port->mmhs->type = port->opt2;
    pcall(port->mmhs->to, port->fld[1]);
    fill(port->mmhs->bbs, ' ', ln_call);

    if(port->flds > 3) atfrom(2);
    if(port->flds > 5) atfrom(4);
    filesize = tmpsize;
#ifdef MCH_AMIGA
   replace_bbs(&port->mmhs->to,&port->mmhs->bbs);
#endif
    cremsg();
    first = false;
  }
  fclose(fl);
}

/*
 *  M command, make a message from a file.
 */

makmsg()
{
  if ((port->fl = fopen(port->fld[2], "r")) is NULL)
    { nofile(port->fld[2]); return; }
  fclose(port->fl);
  pfld();
  if (port->mode & gone) return;
  msgfile(port->line, mfhs->next_msg);
  copy(port->fld[2], port->line, true);
  cremsg();
}

/*
 *  MM command, make multiple messages from a file.
 */

makmlt()
{
  register FILE *dfl;
  char tnm[80];

  holdit = false;
  fill(port->mmhs->bid, ' ', ln_bid);

  if ((port->fl = fopen(port->fld[2], "r")) is NULL)
    { nofile(port->fld[2]); return; }
  fclose(port->fl);

  if ((dfl = fopen(port->fld[1], "r")) is NULL)
    { nofile(port->fld[1]); return; }

  strcpy(tnm, port->fld[2]);
 
  if (port->flds is 4) if (*port->fld[port->flds-1] is '$')
  {
    if (*(port->fld[port->flds - 1] + 1) isnt NULL)
    {
      strncpy(port->mmhs->bid, port->fld[port->flds-1] + 1, ln_bid);
      hasbid = true;
    }
  }
 
  prtx(mm[0]);
  get_title();
  if (port->mode & gone) { fclose(dfl); return; }

  while (fgets(port->line, linelen, dfl) isnt NULL)
  {
    parse();
    port->mmhs->type = port->opt2;
    pcall(port->mmhs->to, port->fld[1]);
    strncpy(port->mmhs->from, port->user->call, ln_call);
    fill(port->mmhs->bbs, ' ', ln_call);
    port->mmhs->ext = 0;

    if (port->flds > 3) atfrom(2);
    if (port->flds > 5) atfrom(4);
#ifdef MCH_AMIGA
    replace_bbs(&port->mmhs->to,&port->mmhs->bbs);
#endif
    initmsg(false);
    msgfile(port->line, mfhs->next_msg);
    copy(tnm, port->line, true);
    cremsg();
  }
  fclose(dfl);
}

/*
 *  Mark stale messages.
 */

stale()
{
  register word i;
  register int ts;

  for (i = mfhs->first; i and i <= mfhs->last; i++)
  {
    read_rec(mfl, i, (char *)port->mmhs);

    ts = tstaleb;
    if (port->mmhs->type is 'T') ts = tstalen;
    else if (iscall(port->mmhs->to)) ts = tstaleu;

    if (!(port->mmhs->stat & m_stale))
    if (ddiff(port->mmhs->date, l_date) > ts)
    {
      port->mmhs->stat setbit m_stale;
      write_rec(mfl, i, (char *)port->mmhs);
    }
  }
}

/*
 *  DW command: make wp message from user file.
 */

dwuser()
{
  register int i;
  register short first = true;
  short doall;

  if (*wpcall is ' ') return;

  doall = port->flds is 2;
  port->opt1 = 'S';
  filesize = 0;

  for (i = 1; i <= ufhs->count; i++)
  {
    read_rec(ufl, i, (char *)tuser);
    if ((tuser->state & u_home) and (tuser->state & u_zip))
    if (doall or !(tuser->state & u_sent))
    {
      if (first)
      {
        first = false;
        port->mmhs->type = 'P';
        strncpy(port->mmhs->to, "WP    ", ln_call);
        strncpy(port->mmhs->from, cport->user->call, ln_call);
        strncpy(port->mmhs->bbs, wpcall, ln_call);
        strcpy(port->mmhs->title, "WP Update");
        fill(port->mmhs->bid, ' ', ln_bid);
        port->mmhs->ext = 0;
        initmsg(false);
        msgfile(port->line, mfhs->next_msg);
        port->fl = fopen(port->line, "w");
      }

      filesize += 29;
      fseek(port->fl, (long)RECSIZE, 0);
      fprintf(port->fl, "%6.6s qth %6.6s zip %6.6s\n",
          tuser->call, tuser->home_bbs, tuser->zip);
      tuser->state setbit u_sent;
      write_rec(ufl, i, (char *)tuser);
      if (i is port->user->rn) port->user->state setbit u_sent;
    }
  }

  if (!first)
  {
    fclose(port->fl);
    cremsg();
  }
}

/*
 *  E command, edit a message header.
 */

edmsg()
{
  FILE *out;
  char *a, *b;

  if (!findmsg(atoi(port->fld[1]))) { port->msg = mnmsg; return; }
  while (*port->fld[0] isnt '\0')
  {
    prthdr();
    outstr("t(Y)pe, (S)tatus, (T)o, (F)rom, (B)bs, t(I)tle, bi(D)\n");
    getcmd();
    if (port->mode & gone) return;
    switch (*port->fld[0])
    {
      case 'T' : pcall(port->mmhs->to, port->fld[1]); break;
      case 'F' : pcall(port->mmhs->from, port->fld[1]); break;
      case 'B' : edbbs(1); break;
      case 'I' : if (*port->fld[1])
                 {
                   remnl(port->line);
                   strncpy(port->mmhs->title, port->line+2, mhtitl);
                 }
                 else *port->mmhs->title = '\0';
                 break;
      case 'S' : switch(*port->fld[1])
                 {
                   case 'F' : port->mmhs->stat = m_fwd;   break;
                   case 'H' : port->mmhs->stat = m_hold;  break;
                   case 'N' : port->mmhs->stat = 0;       break;
                   case 'O' : port->mmhs->stat = m_stale; break;
                   case 'Y' : port->mmhs->stat = m_read;  break;
                 }
                 break;
      case 'Y' : if(*port->fld[1]) port->mmhs->type = *port->fld[1];
                 else port->mmhs->type = ' '; break;

      case 'D' : if(*port->fld[1]) strncpy(port->mmhs->bid, port->fld[1], ln_bid);
                 else fill(port->mmhs->bid, ' ', ln_bid);
                 break;
    }
  }
  wt_mmhs();
  makehdr2();
  if (*port->mmhs->bid isnt ' ')
  {
    checkbid();
    if  (needbid)
    {
      if ((out = fopen(bidfile,"a")) is NULL)
      {
        port->msg = mcant; return; 
      }

      a = port->cmd;
      b = port->mmhs->bid;
      unbl(a, b, ln_bid);      

      sprintf(port->line, "%4.4s%s\n", port->mmhs->date + 2, port->cmd);
      if (s_flag & s_dv) begin_lock();
      fputs(port->line, out);
      if (s_flag & s_dv) end_lock();
      fclose(out);
    }
  }
}

/*
 *  ET command, edit an NTS traffic message header.
 */

edtfc()
{
  register short ok;

  if (!findmsg(atoi(port->fld[1]))) { port->msg = mnmsg; return; }
  prthdr();

  ok = (port->mmhs->type is 'T');
  if (!ok) ok = ((port->mmhs->type is ' ') and matchn(port->mmhs->to, "NTS", 3));
  if (!ok) { port->msg = mm[12]; return; }

  prtx(mm[8]);
  getcmd();
  if (port->mode & gone) return;
  if (port->flds) pcall(port->mmhs->to, port->fld[0]);

  prtx(mm[9]);
  getcmd();
  if (port->mode & gone) return;
  edbbs(0);

  prtx(mm[10]);
  getcmd();
  if (port->mode & gone) return;
  if (port->flds)
  {
    remnl(port->line);
    strncpy(port->mmhs->title, port->line, mhtitl);
  }
  else if (*port->line is ' ') *port->mmhs->title = '\0';

  prtx(mm[11]);
  getcmd();
  if (port->mode & gone) return;
  if (port->flds) port->mmhs->type = *port->fld[0];
  else if (*port->line is ' ') port->mmhs->type = ' ';

  port->mmhs->stat = 0;
  prthdr();
  wt_mmhs();
  makehdr2();
  sprintf(port->line, "%u %-.6s %s",
    port->mmhs->number, port->mmhs->to, port->mmhs->title);
  log('M', 'E', port->opt2, port->line);
}

edbbs(f)
int f;
{
  fill(port->mmhs->call, '\0', 125);
  port->mmhs->ext = 0;
  fill(port->mmhs->bbs, ' ', ln_call);
  if(*port->fld[f])
  {
    pcall(port->mmhs->bbs, port->fld[f]);
    if (strchr(port->fld[f], '.') is NULL) dodis();
    else
    {
      port->mmhs->ext = 2;
      strncpy(port->mmhs->call[0], port->fld[f], 64);
    }
  }
}

