/*
 * $VER: MultiMaus 1.2 (15.1.93)
 *       © by Martin Horneffer
 *
 * Aufruf:
 *   RX MausTausch <Mauskürzel> <Mauskürzel> ..
 *
 * History:
 *  3. 1.93:  1.0  erste öffentliche Version
 * 15. 1.93:  1.1  Erweiterung f. Gateway-MausTausch
 * 19. 1.93:  1.1  'NO DIALTONE'
 */

/*
 * Konfiguration:
 *  die folgenden Zeilen, aber nur diese, sollten jedem System angepaßt werden
 */

MAUSDIR = "Spool:Maus"
VLTCOMMAND = "run >NIL: <NIL: wb:comm/vlt/vlt"
CAPTUREFILE = "Spool:cap/vlt-mt.cap"
PACKER = "LHA -2"
/* PACKER = "" */
PKEXT = ".lzh"
TEMPDIR = "T:"
BACKUPS = 5
AFTERCONNECT = "ati2"
REDIALDELAY = 30
PENALTY.busy = 5
PENALTY.dialtone = 5
PENALTY.nocarrier = 100
PENALTY.mausnet = 100

/* Maus-Liste einlesen */
/*
 * Format:
 *
 * Zeile     1: <Mauskürzel> <Wählstring>
 * Zeilen 2..n: <Userkürzel(UMS)> <Passwort(Maus)> <Vorname Nachname(Maus)>
 * Zeile   n+1: [Leerzeile]
 * Zeile   n+2: [wie Zeile 1]
 * ...
 */

olddir = pragma('Directory',MAUSDIR)

if open( file, "mausliste", "r") = 0 then do
  say "Kann Maus-Liste nicht öffnen!"
  exit
end

do i = 0 by 0
  line = readln(file)
  parse var line mausname dialstring
  if mausname = "" then leave
  i = i + 1
  mausname = upper(mausname)
  maus.mausname = i
  maus.i.call = 0
  maus.i.penalty = 0
  maus.i.name = strip(mausname)
  maus.i.dial = strip(dialstring)
  do j = 0 by 0
    line = readln(file)
    parse var line usershort userpwd userlong
    if userlong = "" then leave
    j = j + 1
    maus.i.user.j.short = strip(usershort)
    maus.i.user.j.pwd = strip(userpwd)
    maus.i.user.j.long = strip(userlong)
    maus.i.user.j.isgate = left(upper(userlong),5) = "GATE "
  end
  maus.i.user.0 = j
  if eof(file) then leave
end
call close(file)
maus.0 = i

/*
 *   Commandline auswerten
 */

parse arg args

do forever
  parse var args mausname args
  if mausname = "" then break
  mausname = upper(mausname)
  i = maus.mausname
  if (i <= 0) | (i > maus.0) then say "Maus" mausname "ist nicht bekannt!"
    else if maus.i.user.0 > 0 then maus.i.call = 1
end

/*
 *   Infiles erzeugen
 */

say
call makeinfiles()


/*
 *   VLT starten
 */

say
say "VLT starten.."

if show(PORTS,"VLT") = 0 then do
  address command
  VLTCOMMAND
  do while show(PORTS,"VLT") = 0
    "wait 2"
  end
end

/*
 *   Setup
 */

address VLT

"function 10 (~rx (call setclip(MULTIMAUS.IMODE,1)))"
"Echo off"
"Transfer Mode Image"
"Transfer Protocol External"
XPR select xprzmodem.library
XPR Init "'P"MAUSDIR",TN,OY,AN,DN,KY,SN,RN'"
"capture "capturefile


/*
 *   Jetzt geht's los:
 */

state = "OFFLINE"
i = maus.0

done = 0
do until done
  select
    when state = "OFFLINE"   then state = newmaus()
    when state = "DISCON"    then state = resetmodem()
    when state = "DIAL"      then state = dialmaus()
    when state = "CONNECTED" then state = login()
    when state = "LOGGEDIN"  then state = startmt()
    when state = "STARTEDMT" then state = runmt()
    when state = "MTOK"      then state = relogin()
    otherwise do
      say "Ende:" state
      done = 1
    end
  end
end
if state = "DONE" then "exit VLT"


/*
 *   Ende.
 */

call pragma('Directory',olddir)
exit


/*
 *   Implementierung der verschiedenen Zustände
 */

newmaus: procedure expose maus. i j
  ii = i
  do until maus.i.call | (i = ii)
    i = (i // (maus.0) ) + 1
  end
  if maus.i.call then return "DIAL"
                 else return "DONE"


resetmodem: procedure expose maus. afterconnect packer pkext tempdir backups
  call makeinfiles()
  address VLT
  "hangup; delay 2"
  if afterconnect ~= "" then "send ("afterconnect"*r)"
  "delay 5; capture flush"
  return "OFFLINE"


dialmaus: procedure expose maus. i j penalty. redialdelay
  say "Dial Maus" maus.i.name

  connectstr = "MAUS "||maus.i.name||" - Version"

  address VLT
  "trap add 1001 install ("connectstr")                  (cancel $main connected)"
  "trap add 1002 install case (BUSY*r)                   (cancel $main busy)"
  "trap add 1002 install case (NO DIALTONE*r)            (cancel $main dialtone)"
  "trap add 1003 install case (NO CARRIER*r)             (cancel $main nocarrier)"
  "trap add 1004 install case (WerDaAuchImmerHierAnruft) (cancel $main mausnet)"
  "trap add 1005 install case (MausNet laeuft, bitte)    (cancel $main mausnet)"
  "trap add 1006 install case (Zeit ist die MAUS nur f)  (cancel $main mausnet)"
  "trap add 1007 install case (RING*r)                   (cancel $main ring)"

  "$main: send ("maus.i.dial"*r); delay 3:00"
  event = upper(vlt.CANCELFLAG)
  if event = "VLT.CANCELFLAG" then  event = "TIMEOUT"
  say " ->" event

  "trap remove 1001 1002 1003 1004 1005 1006"

  if datatype(penalty.event) = "NUM" then  do
    maus.i.penalty = maus.i.penalty + penalty.event
    say "Penalty für Maus "maus.i.name":" maus.i.penalty
    if maus.i.penalty >= 100 then  maus.i.call = 0
                             else  "delay "redialdelay
    event = "OFFLINE"
  end
  if event = "CONNECTED" then do
    maus.i.call = 0
    j = 0
  end

  return event


login: procedure expose maus. i j
  j = j + 1
  if j > maus.i.user.0 then  return "LOGOUT"

  address VLT
  "trap add 1001 install case (Ihr letzter Anruf ) (cancel $main loggedin)"
  "schedule {$2: on (*r) (); wait (NO CARRIER*r); on (*r) goto $2; delay 2; cancel $main discon}"

  "$main: send (j"maus.i.user.j.long"*r"maus.i.user.j.pwd"*r); delay 1:00"
  event = upper(vlt.CANCELFLAG)
  if event = "VLT.CANCELFLAG" then  event = "TIMEOUT"
  say " ->" event

  "trap remove 1001"
  "cancel $2"
  return event


startmt: procedure expose maus. i j
  call setclip(MULTIMAUS.IMODE,0)

  address VLT
  "trap add 1001 install case (MausTausch Betatest-Version) (cancel $main startedmt)"
  "schedule {$2: on (*r) (); wait (NO CARRIER*r); on (*r) goto $2; delay 2; cancel $main discon}"

  "$main: delay 5"
  event = upper(vlt.CANCELFLAG)
  if event = "VLT.CANCELFLAG" then
    if getclip(MULTIMAUS.IMODE) then
      "$main: message ( - manueller Modus -*rweiter: (T) im Hauptmenü); pause"
    else
      "$main: send (t); pause"

  event = upper(vlt.CANCELFLAG)
  if event = "VLT.CANCELFLAG" then  event = "TIMEOUT"
  say " ->" event

  "trap remove 1001"
  "cancel $2"
  return event


runmt: procedure expose maus. i j pkext packer
  address VLT
  "trap add 1001 install case (Protokoll start) (cancel $main transfer)"
  "schedule {$2: on (*r) (); wait (NO CARRIER*r); on (*r) goto $2; delay 2; cancel $main discon}"

  "$main: send (Z); delay 1:00"
  event = upper(vlt.CANCELFLAG)
  if event = "VLT.CANCELFLAG" then  event = "TIMEOUT"
  if event = "TRANSFER" then do
    if maus.i.user.j.isgate then
         if PACKER = ""
           then sendfile = "infile-"maus.i.user.j.short".txt"
           else sendfile = "infile-"maus.i.user.j.short||pkext
    else if PACKER = ""
           then sendfile = "infile-"maus.i.user.j.short"-"maus.i.name".txt"
           else sendfile = "infile-"maus.i.user.j.short"-"maus.i.name||pkext
    "file send "sendfile
    "$main: send (Z); delay 30:00"
    event = upper(vlt.CANCELFLAG)
    if event = "VLT.CANCELFLAG" then  event = "TIMEOUT"
    if event = "TRANSFER" then do
      if PACKER = "" then do
        outfile = "outfile-"maus.i.user.j.short"-"maus.i.name".txt"
        getfile = "outfile.txt"
      end
      else do
        outfile = "outfile-"maus.i.user.j.short"-"maus.i.name||pkext
        getfile = "outfile"||pkext
      end
      "file receive "getfile
      if exists(getfile) then do
        address COMMAND
        'RENAME 'getfile' AS 'outfile
      end
      event = "MTOK"
    end
  end

  say " ->" event

  address VLT
  "trap remove 1001"
  "cancel $2"
  return event


relogin: procedure expose maus. i j
  call setclip(MULTIMAUS.IMODE,0)

  address VLT
  "trap add 1001 install case (Sind Sie eingetragener Benutzer) (cancel $main connected)"
  "schedule {$2: on (*r) (); wait (NO CARRIER*r); on (*r) goto $2; delay 2; cancel $main discon}"

  "$main: delay 5"
  event = upper(vlt.CANCELFLAG)
  if event = "VLT.CANCELFLAG" then
    if getclip(MULTIMAUS.IMODE) then
      "$main: message ( - manueller Modus -*rweiter: (L) im Hauptmenü); pause"
    else
      if j < maus.i.user.0 then
        "$main: send (LJ); pause"
      else
        "$main: send (SJ); delay 15"

  event = upper(vlt.CANCELFLAG)
  if event = "VLT.CANCELFLAG" then  event = "DISCON"
  say " ->" event

  "trap remove 1001"
  "cancel $2"
  return event


makeinfiles: procedure expose maus. packer pkext tempdir backups

  address COMMAND
  if ~exists("bk") then  'MAKEDIR bk'
  do i = 1 to maus.0
    do j = 1 to maus.i.user.0

      if PACKER = "" then do
        outfile = "outfile-"maus.i.user.j.short"-"maus.i.name".txt"
        bkofile = outfile
        if maus.i.user.j.isgate
          then  bkifile = "infile-"maus.i.user.j.short".txt"
          else  bkifile = "infile-"maus.i.user.j.short"-"maus.i.name".txt"
        delfile = ""
      end
      else do
        pkoutfile = "outfile-"maus.i.user.j.short"-"maus.i.name||pkext
        outfile = tempdir"outfile.txt"
        bkofile = pkoutfile
        if exists(outfile) then 'DELETE' outfile
        if exists(pkoutfile) then  PACKER 'x' pkoutfile tempdir
        if maus.i.user.j.isgate then do
          bkifile = "infile-"maus.i.user.j.short||pkext
          delfile = "infile-"maus.i.user.j.short".txt"
        end
        else do
          bkifile = "infile-"maus.i.user.j.short"-"maus.i.name||pkext
          delfile = "infile-"maus.i.user.j.short"-"maus.i.name".txt"
        end
      end

      if exists(outfile) then do
        maus.i.call = 0
        if maus.i.user.j.isgate
          then  'M2UMS' maus.i.user.j.short outfile
          else  'M2UMS' maus.i.name outfile
        if exists("bk/bk"backups"-"bkofile) then  'DELETE' "bk/bk"backups"-"bkofile
        if exists("bk/bk"backups"-"bkifile) then  'DELETE' "bk/bk"backups"-"bkifile
        do n=backups-1 to 1 by -1
          if exists("bk/bk"n"-"bkofile) then  'RENAME' "bk/bk"n"-"bkofile "bk/bk"n+1"-"bkofile
          if exists("bk/bk"n"-"bkifile) then  'RENAME' "bk/bk"n"-"bkifile "bk/bk"n+1"-"bkifile
        end
        'RENAME' bkofile "bk/bk1-"bkofile
        'RENAME' bkifile "bk/bk1-"bkifile
        if exists(delfile) then 'DELETE' delfile
      end
    end
  end
  do i = 1 to maus.0
    if maus.i.call then do j = 1 to maus.i.user.0
      say
      say "Nachrichten von User" maus.i.user.j.short "an Maus" maus.i.name "exportieren:"
      if maus.i.user.j.isgate
        then  'UMS2MNODE' maus.i.user.j.short
        else  'UMS2M' maus.i.name maus.i.user.j.short
      if maus.i.user.j.isgate
        then  infile = "infile-"maus.i.user.j.short".txt"
        else  infile = "infile-"maus.i.user.j.short"-"maus.i.name".txt"
      if PACKER ~= "" then do
        if maus.i.user.j.isgate
          then  pkinfile = "infile-"maus.i.user.j.short||pkext
          else  pkinfile = "infile-"maus.i.user.j.short"-"maus.i.name||pkext
        if exists(pkinfile) then  'DELETE 'pkinfile
        PACKER 'a' pkinfile infile
      end
    end
  end
  return 1
