/*
 *  MBLOG.C - 3/01/87 - Logging and Monitoring.
 */

#include "mb.h"
#ifndef MCH_AMIGA
#define ln_jstr (ln_callp + ln_time)
#else
int ln_jstr = (ln_callp + ln_time  + ln_date);
#endif

char *lgfile;
FILE *lfl;

char *monfile;

char *hrdfile, *hrd;
int  hrdmax, hrdn;

/*
 *  Clean the log file.
 *  Force drain of buffers, update of directory item.
 */

clnlog()
{
  if (s_param & s_log_on)
  {
    fclose(lfl);
    lfl = fopen(lgfile, "a+");
  }
}

clslog()
{
  if (s_param & s_log_on) fclose (lfl);
}

/*
 *  Open the log file.
 */

opnlog()
{
  if (s_param & s_log_on)
    if ((lfl = fopen(lgfile, "a+")) is NULL) { nofile(lgfile); exit(1); }
}

/*
 *  Log an event.
 */

log(event, fn, sfn, text)
char event, fn, sfn, *text;
{

/*
 *  Do we log this type of event?
 */

  if (!(s_param & s_log_on)) return;

  if (port->dev is p_console) if (!(s_param & s_log_loc))
  if (!((event is 'M') and ((fn is 'S') or (fn is 'M')))) return;

  switch(event)
  {
    case 'G' : if (!(s_param & s_log_gate)) return; break;
    case 'M' : if (!(s_param & s_log_msg))  return; break;
    case 'F' : if (!(s_param & s_log_file)) return; break;
  }

/*
 *  Yes, so log it.
 */

  curtim();
  fprintf(lfl, "%c%s%s%c%c %s\n", event, l_date, l_time, fn, sfn, text);
}

/*
 *  Monitoring ...
 */

clsmon()
{
  register short  i;
  register char  *c;
  register PORTS *p;

/*
 *  Write out the heard log.
 */

  if ((port->fl = fopen(hrdfile, "w")) isnt NULL)
  {
    sort(hrd, hrdn, ln_call, tmp->scr);
    for (i = 0, c = hrd; i < hrdn; i++, c += ln_call)
      fprintf(port->fl, "%6.6s\n", c);
    fclose(port->fl);
  }

/*
 *  Write out the J list for each port.
 */

  if ((port->fl = fopen(monfile, "w")) isnt NULL)
  {
    for (p = porthd; p isnt NULL; p = p->next)
    {
      for (i = 0, c = p->heard; i < p->nhrd; i++, c += ln_jstr)
#ifndef MCH_AMIGA
         fprintf (port->fl, "%13.13s\n", c);
#else
         fprintf (port->fl, "%19.19s\n", c);
#endif
      fprintf (port->fl, "*** EOF\n");
    }
    fprintf (port->fl, "%s%s\n", l_date, l_time);
    fclose (port->fl);
  }
}

/*
 *  Open "heard log" and "monitor log".
 */

opnmon()
{
  register char *i, *j, *st;
  register PORTS *p;

/*
 *  Open the "heard list" file.
 */

  if ((hrd = (char *)malloc(ln_call * hrdmax)) is NULL) errall();

  hrdn = 0;

  if ((port->fl = fopen(hrdfile, "r")) isnt NULL)
  {
    i = hrd;
    while((hrdn < hrdmax) and (fgets (port->line, linelen, port->fl) isnt NULL))
    {
      pcall(i, port->line);
      hrdn++; i += ln_call;
    }
    fclose(port->fl);
    sprintf(port->line, "%d calls in %s", hrdn, hrdfile); outstr(port->line);
    if (hrdn is hrdmax) outstr(" (File is full.)");
    outchar('\n');
  }

/*
 *  Open the monitor file and read the J list for each port.
 */

  if ((port->fl = fopen(monfile, "r")) isnt NULL)
  {
    for (p = porthd; p isnt NULL; p = p->next)
    {
      st = fgets (port->line, linelen, port->fl);
      j = p->heard;
      while (!iseof(port->line) and (st isnt NULL))
      {
        if (p->nhrd < p->maxhrd)
        {
          for (i = port->line; i < port->line + ln_jstr;) *j++ = *i++;
          p->nhrd++;
        }
        st = fgets (port->line, linelen, port->fl);
      }
    }
    fclose(port->fl);
  }
}

/*
 *  Add call in monitored packet to J list of current port.
 */

monitor()
{
  register short l1, l2;

  if (port->heard is NULL) return;

  for (l1 = 0; l1 < ln_callp; l1++) if (port->line[l1] is '>')
  {
    if (l1 < 4) return;

    port->line[l1] = '\0';

    for (l2 = 1; l2 < 10; l2++)
    if ((port->line[l1 + l2] is ':') or
        (port->line[l1 + l2] is ',') or
        (port->line[l1 + l2] is ' ') or
        (port->line[l1 + l2] is '\0'))
    {
      if (l2 > 4) { addcall(port->line, port); addhrd(); }
      return;
    }
    return;
  }
}

/*
 *  Add call to heard list.
 */

addhrd()
{
  register int i;
  register char *p;

  if (hrdn >= hrdmax) return;
  pcall(tmp->scr, port->line);

  for (i = 0, p = hrd; i < hrdn; i++, p += ln_call)
  if (matchn(tmp->scr, p, ln_call)) return;

  strncpy(hrd + (ln_call * hrdn++), tmp->scr, ln_call);
}

/*
 *  Add call to J list.
 */

addcall(cp, p)
char *cp;
PORTS *p;
{
  register char  *k;
  register short i;
  register char  *sk;
  register short si;

  ljsf(tmp->scr, cp, ln_callp);

/*
 *  Check if this call already in list for this port.
 */

  si = -1;
  for (i = 0, k = p->heard; i < p->nhrd; i++, k += ln_jstr)
  if (matchn(tmp->scr, k, ln_callp)) { si = i; sk = k; }

/*
 *  If not already in the list ...
 */

  if (si is -1)
  {
    si = p->nhrd; sk = p->heard + ln_jstr * p->nhrd;
    if (p->nhrd < p->maxhrd) p->nhrd++; else { si--; sk -= ln_jstr; }
  }

/*
 *  Put call at top of list for this port.
 */

  for (; si; si--, sk -= ln_jstr) strncpy (sk, sk - ln_jstr, ln_jstr);
  curtim();
#ifdef MCH_AMIGA
  strncpy(p->heard + ln_callp + ln_time, l_date, ln_date);
#endif
  strncpy(p->heard + ln_callp, l_time, ln_time);
  strncpy(p->heard, tmp->scr, ln_callp);
}

/*
 *  J command, print list of calls heard.
 */

prthrd()
{
  register short i;
  register char *j;
  register PORTS *p;

  if (port->opt2 is ' ') { shports(); return; }

  if ((p = findport(port->opt2)) is NULL) { prtx(mnport); return; }

  sprintf(tmp->scr, "Port %c, %s\n", p->id, p->name);
  outstr(tmp->scr);

  if (!(p->nhrd)) { prtx(mfind); return; }

  for (i = 0, j = p->heard; i < p->nhrd; i++, j += ln_jstr)
  {
#ifndef MCH_AMIGA
    sprintf(tmp->scr, "%9.9s %4.4s %6.6s\n", j, j + ln_callp);
#else
    sprintf(tmp->scr, "%9.9s %4.4s %6.6s\n",
                         j, j + ln_callp, j+ln_callp+ln_time);
#endif
    outstr(tmp->scr);
  }
}
