!  File  NMOUSE:FSMUX

! Filestore multiplexor process

%begin
%option "-nons-nocheck-nodiag"
%include "mouse.inc"
%include "2meg.inc"

! The IO_F module in the user process sends requests either straight
! to the ether driver (when file transactions are already established)
! or via this process (for non-file-transaction operations).
! Messages coming to us simply carry the filestore number as CONTEXT,
! which we translate to an ether context number, establishing one
! if necessary.  We also keep track of the user number.  Any packets
! "passing through" with '*' as the reference digit have the user
! number substituted ('0' if not logged on).  Filestore connections
! are closed at logoff, and there is also an automatic logoff before
! logon (but on a per-filestore basis, so you can be logged on to
! several filestores simultaneously, but only once on each).

%recordformat f(%byte context,usernumber)
%record(f)%array fsa(16:127)
%record(f)%name fs

%integer c
%bytename b
%record(mailboxfm)%name fmbx, embx, rmbx
%record(ether buffer fm)%name punters, mine

  fsa = 0
  fmbx == create mailbox("Filestore_Multiplexor",create semaphore("",0))
  rmbx == create mailbox("",create semaphore("",0))
  becomeprocess(5000)
  embx == lookup mailbox(ether mailbox name)
  %cycle
    punters == record(addr(receive message(fmbx)))
    c = punters_context&255
    %unless 16<=c<=127 %start
      punters_status = ether dud context
      send message(punters_system part, punters_system part_reply)
      %continue
    %finish
    fs == fsa(c)
    %if fs_context=0 %start
      fs_usernumber = '0'
      mine == acquire packet buffer
      mine_ra = c; mine_rp = 0
      mine_code = ether old define
      ether request(mine)
      mine == ether reply
      ->shit %if mine_status<0
      fs_context = mine_context
      b == mine_data(mine_offset)
      b = 2; mine_bytes = 1
      mine_code = ether old write read
      ether request(mine)
      mine == ether reply
      ->shit %if mine_status<0
      b == mine_data(mine_offset)
      %if b='-' %start
shit:   mine_tag = punters_tag
        send message(mine_system part,punters_system part_reply)
        discard packet buffer(punters)
        %continue
      %finish
      mine_rp = b-'0'
      mine_code = ether old redefine
      ether request(mine)
      mine == nil
      discard packet buffer(ether reply)
    %finish
    punters_context = fs_context
    b == punters_data(punters_offset)
    b[1] = fs_usernumber %if b[1]='*'
    %if b='L' %start
      rmbx == punters_system part_reply
      ether request(punters)
      punters == ether reply
      b == punters_data(punters_offset)
      c = fs_usernumber
      fs_usernumber = b %if b>'0'
      send message(punters_system part,rmbx)
      %if c>'0' %start
        mine == acquire packet buffer
        mine_context = fs_context
        b == mine_data(mine_offset)
        b = 'M'; b[1] = c; b[2] = 3; mine_bytes = 3
        ether request(mine)
        discard packet buffer(ether reply)
      %finish
    %elseif b='M'
      rmbx == punters_system part_reply
      fs_usernumber = '0'
      %if b[1]='0' %start
        punters_status = 0; send message(punters_system part,rmbx)
      %else
        ether request(punters)
        send message(ether reply_system part,rmbx)
      %finish
      mine == acquire packet buffer
      mine_context = fs_context
      fs_context = 0
      mine_data(mine_offset) = 4
      mine_bytes = 1
      mine_code = ether old write
      ether request(mine)
      mine == ether reply
      mine_code = ether old undefine
      ether request(mine)
      discard packet buffer(ether reply)
    %else
      send message(punters_system part,embx)
    %finish
  %repeat
%end
