home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / PACKET / RLI120.ARK / MAIL.MAC < prev    next >
Text File  |  1987-05-11  |  24KB  |  1,107 lines

  1. ; MAIL.MAC - 5/11/87 - The MailBox.
  2.  
  3.     .z80
  4.     maclib    TNC.LIB
  5.  
  6.     entry    klmsg1,klmsg2,klmsg3,rdmsg1,rdmsg2,rdmsg3
  7.     entry    msnoop,mplsno,logmnr
  8.     entry    smsg1,smsg2,smsg3,smsg4,smsg5,smsg6,smsg7
  9.     entry    wthdr,opnmsg,clsmsg,filmsg,lstmsg
  10.     entry    newmsg,getto,change,firmsg,phdr,prtmsg,kmsg
  11.     entry    svcmsg,mfcb,mbfcb,msgfcb,mrec
  12.     entry    mm1,mm2,mm3,mm4,mm5,mm6,mm15
  13.     entry    btchm,ucmax,ucalls,uccnt
  14.  
  15.     external    mfhs,mfhsl,mfhd,mlhd,mffree,mlfree,mnr
  16.     external    mvers,mfree,mcnt
  17.     external    tmfhs,tmnext,tmfhd,tmlhd,tmffree,tmlfree,tmnr
  18.     external    tmfree,tmcnt
  19.     external    mhprev,mhcur,msgnr
  20.     external    mmhs,mhtitl,mhfmsg,mhlmsg,mhnext,mhnr,mhsize
  21.     external    mhtype,mhstat,mhto,mhbbs,mhfrom,mhdate,mhtime
  22.     external    mhread,mhtit,mhext,mmts,mtitle,mtnext,mttext
  23.  
  24.     external    rcv,div8,muldec,mcall,ocall,scall
  25.     external    usport,usopt,usosys,usoexa,usoexb
  26.     external    curtime,log,event,logtxt,date,time
  27.     external    fcb,fcb1,fcb2,fcb3,opt1,opt2
  28.     external    flds,f1l,f1st,f2l,f2st,f3l,f3st,f4l,f4st
  29.     external    f5l,f5st,f6l,f6st,f7l,f7st
  30.     external    movcal,cmd,cmdlen
  31.     external    decbin,bindec,numb,@move,@upper,@fill,@mcmd
  32.     external    @openr,@openw,@opena,@openn,@closew
  33.     external    @ntobuf,@ctobuf
  34.     external    ckname,rdcmd,fmbuf,tobuf,rfcb,wfcb,setb7
  35.     external    @outch,@prtx,@cmp
  36.     external    @src,@srct,@srcl,@srcn,@srcw,@srcc
  37.     external    usmnr,unt,pause,waitc,iscall
  38.     external    addcr0,getcmd,getdat,cmdtyp,$memry
  39.     external    ername,erfind,ercant,erprot,erdone,erwhat
  40.  
  41.     asciictl
  42.     bdosdef
  43.     tncdefs
  44.     timdef
  45.  
  46. btchm    equ    120        ; Max length of beacon text
  47.  
  48.     dseg
  49. change:    ds    1        ; True if mail file changed (send/kill)
  50.  
  51. ; File control blocks.
  52.  
  53. mfcb:    ds    fcbsize
  54. mrec    equ    mfcb+33
  55.  
  56. mbfcb:    ds    fcbsize
  57.  
  58. msgfcb:    ds    fcbsize
  59. ver:    ds    1
  60.  
  61. ; Open (or create and open) the mail file.
  62. ; Allocate memory for call lists.
  63.  
  64.     cseg
  65. opnmsg:    movw    ucalls,$memry
  66.     ld    de,(ucmax)
  67.     ld    c,6
  68.     call    muldec
  69.     add    hl,de
  70.     ld    ($memry),hl
  71.     dodosa    setdma,mfhs
  72.     ld    hl,mbfcb+10
  73.     call    setb7        ; Set $sys attribute
  74.     ld    hl,mfcb+10
  75.     call    setb7        ; Set $sys attribute
  76.     dodosa    open,mfcb
  77.     inc    a
  78.     jr    z,opnma
  79.     movb    ver,mvers    ; Save current version
  80.     dodosa    read,mfcb
  81.     ld    hl,ver
  82.     ld    a,(mvers)
  83.     cp    (hl)        ; Is file current version?
  84.     jr    z,opnmb        ; Yes
  85.     mvim    opt2,' '    ; Make sure no renumber
  86.     call    unt        ; Let untangle fix it
  87.     movb    mvers,ver    ; Set current version
  88.     jr    opnmb
  89. opnma:    dodosa    make,mfcb    ; Make a mail file
  90.     call    wtmfhs        ; Write a blank file header
  91. opnmb:    call    getto
  92.     ret
  93.  
  94. ; Close the mail file.
  95.  
  96. clsmsg:    dodosa    close,mfcb
  97.     ret
  98.  
  99. ; General "bad status" return. Returns zero flag cleared.
  100. ; Can inspect cmdtyp to find out what happened.
  101.  
  102. badret:    retnz
  103.  
  104. ; Check permission for the operation:
  105. ; Message to or from user, or user is system owner.
  106. ; Return zero set if permission ok.
  107.  
  108. permit:    ld    a,(usopt)
  109.     and    usosys
  110.     jr    z,pera
  111.     xor    a
  112.     ret            ; With zero set
  113. pera:    comp    mcall,mhto,6
  114.     ret    z
  115.     comp    mcall,mhfrom,6
  116.     ret
  117.  
  118. ; See if mail is to or from this user, or  he is sysop.
  119. ; If not, see if it is to a real callsign.
  120. ; If so, then user is snooping on someone's mail
  121. ; (unless it is T or B type mail),
  122. ; so broadcast that fact to the world.
  123.  
  124. snoopq:    call permit        ; To or from him, or is sysop?
  125.     jr z,    snoopn        ; If so, no problem
  126.     ld hl,    mhto        ; No. See if is TO a real callsign
  127.     call    iscall
  128.     jr c,    snoopn        ; If not, like to ALL, anyone can read it
  129.     cmpm    mhtype,'T'    ; Real callsign. NTS traffic msg?
  130.     jr z,    snoopn        ; OK, that's not really snooping
  131.     cmpm    mhtype,'S'    ; NTS service msg?
  132.     jr z,    snoopn        ; Allow that
  133.     cmpm    mhtype,'B'    ; Bulletin to someone?
  134.     jr z,    snoopn        ; That's OK, too.
  135.     prtx    msnoop        ; But if someone else's real mail, gripe.
  136.     or    0ffH        ; and return NZ
  137.     ret
  138.  
  139. snoopn:    xor    a        ; If ok, return Z
  140.     ret
  141.  
  142. ; Make list of calls with unread messages.
  143. ; Construct a beacon line from that list.
  144.  
  145.     dseg
  146. msnoop:    ds    2    ; Msg to fink on mail snooper
  147. mplsno:    ds    2    ; Msg to ask not to S while *** linked
  148. lktflg:    ds    1    ; Flag for Linked Send filtering
  149. temp:    ds    2
  150. uccnt:    ds    2    ; Count of calls mail for
  151. ucalls:    ds    2    ; Address of list of calls mail for
  152. ucmax:    ds    2    ; Max calls in unread mail list
  153.  
  154.     cseg
  155. getto:    dodosa    setdma,mmhs
  156.     movw    temp,ucalls
  157.     lxim    uccnt,0
  158.     movw    mrec,mlhd
  159. gettoa:    dtz    mrec
  160.     ret    z
  161.     dodosa    rrec,mfcb
  162.     cmpm    mhstat,'N'    ; Message read or forwarded yet?
  163.     jp    nz,gettoc    ; Yes
  164.     cmpm    mhbbs,' '    ; Destination bbs specified?
  165.     jr    z,gettob    ; No
  166.     comp    mhbbs,ocall,6    ; Is it us?
  167.     jr    z,gettob    ; Yes, put user call in list
  168.  
  169. ; Destination bbs specified, it is not us,
  170. ; put the bbs call in the list, leave the user call out.
  171.  
  172.     zmov    scall,mhbbs,6
  173.     ld    a,(scall)
  174.     or    80h        ; Set B7 to indicate bbs not user
  175.     ld    (scall),a
  176.     srclst    scall,ucalls,uccnt,6,6
  177.     jr    z,gettoc    ; Destination bbs already on list
  178.     ld    hl,(temp)
  179.     move    ,scall,6    ; Add destination bbs to list
  180.     ld    (temp),hl
  181.     inxm    uccnt
  182.     ld    de,(ucmax)
  183.     or    a        ; Clear carry
  184.     sbc    hl,de
  185.     ret    z        ; List now full
  186.     jr    gettoc        ; Next msg
  187.  
  188. ; Put the users call in the list.
  189.  
  190. gettob:    srclst    mhto,ucalls,uccnt,6,6
  191.     jr    z,gettoc    ; User already on list
  192.     ld    hl,(temp)
  193.     move    ,mhto,6        ; Add user to list
  194.     ld    (temp),hl
  195.     inxm    uccnt
  196.     ld    de,(ucmax)
  197.     or    a        ; Clear carry
  198.     sbc    hl,de
  199.     ret    z        ; List now full
  200. gettoc:    movw    mrec,mhprev
  201.     jp    gettoa
  202.  
  203.  
  204. ; Print the current message.
  205.  
  206. prtmsg:    dodosa    setdma,mmts
  207.     movw    mrec,mhfmsg
  208. prmsga:    dtz    mrec
  209.     ret    z
  210.     dodosa    rrec,mfcb
  211.     ld    hl,mttext
  212.     ld    e,126
  213. prmsgb:    ld    a,(hl)
  214.     cp    eof
  215.     ret    z
  216.     ld    c,a
  217.     call    @outch
  218.     inc    hl
  219.     dec    e
  220.     jr    nz,prmsgb
  221.     movw    mrec,mtnext
  222.     call    pause
  223.     jr    prmsga
  224.  
  225.     dseg
  226. mtcnt:    ds    1
  227. mtptr:    ds    2
  228. tmhsz:    ds    2
  229. tmhlms:    ds    2
  230. tmhnx:    ds    2
  231. tmhpr:    ds    2
  232. mtemp:    ds    128
  233.     cseg
  234.  
  235. ; Allocate a mail file record.
  236.  
  237. alloc:    dtz    tmffree        ; Any in free chain?
  238.     jr    nz,alloca    ; Yes, allocate the next one
  239.     inxm    tmnext        ; Allocate next at end of file.
  240.     dec    hl
  241.     ret
  242. alloca:    ld    (mrec),hl    ; Rec # of first in free chain.
  243.     dodosa    setdma,mtemp    ; Read into temp buffer
  244.     dodosa    rrec,mfcb
  245.     movw    tmffree,mtemp    ; New first in free chain
  246.     dcxm    tmfree        ; Decrement count of free records
  247.     ld    a,l
  248.     or    h
  249.     jr    nz,allocb    ; More free records
  250.     lxim    tmlfree,0    ; No free records left
  251. allocb:    ld    hl,(mrec)    ; Rec #
  252.     ret
  253.  
  254. ; Get new msg text record. Chain current to it. Write current.
  255.  
  256. newbuf:    push    de
  257.     push    bc
  258.     ld    hl,(mhlmsg)    ; Save pointer to current record
  259.     push    hl
  260.     call    alloc        ; Get new record
  261.     ld    (mtnext),hl    ; New is next from current
  262.     ld    (mhlmsg),hl    ; New is also last
  263.     pop    hl        ; Pointer to current
  264.     ld    (mrec),hl    ; Point IO to correct record
  265.     dodosa    setdma,mmts    ; Point IO to buffer
  266.     dodosa    wrec,mfcb    ; and write it
  267.     lxim    mtnext,0    ; Mark new as end of chain
  268.     lxim    mtptr,mttext    ; Init pointer into buffer
  269.     mvim    mtcnt,126    ; Init count to data size
  270.     pop    bc
  271.     pop    de
  272.     ret
  273.  
  274. ; Make message header info string.
  275.  
  276.     dseg
  277. mm6:    ds    2
  278. firmsg:    ds    1
  279.  
  280.     cseg
  281. mkhdr:    ld    hl,(mhnr)
  282.     call    bindec
  283.     ld    hl,($memry)
  284.     move    ,numb+1,4
  285.     ld    (hl),' '
  286.     inc    hl
  287.     ld    a,(mhtype)
  288.     ld    (hl),a
  289.     inc    hl
  290.     ld    a,(mhstat)
  291.     ld    (hl),a
  292.     inc    hl
  293.     ld    (hl),' '
  294.     inc    hl
  295.     push    hl
  296.     ld    hl,(mhsize)
  297.     call    bindec
  298.     pop    hl
  299.     move    ,numb,5
  300.     ld    (hl),' '
  301.     inc    hl
  302.     move    ,mhto,6
  303.     ld    (hl),' '
  304.     inc    hl
  305.     move    ,mhfrom,6
  306.     ld    (hl),' '
  307.     inc    hl
  308.     move    ,mhbbs,6
  309.     ld    (hl),' '
  310.     inc    hl
  311.     move    ,mhdate,6
  312.     ld    (hl),' '
  313.     inc    hl
  314.     ld    de,mhtit
  315.     ld    b,mhtitl
  316. mkhdra:    ld    a,(de)
  317.     cp    cr
  318.     jr    z,mkhdrb
  319.     ld    (hl),a
  320.     inc    hl
  321.     inc    de
  322.     dec    b
  323.     jr    nz,mkhdra
  324. mkhdrb:    call    addcr0        ; Add CR,0 to end of string
  325.     ret
  326.  
  327. ; Print message header info
  328.  
  329. phdr:    cmpm    firmsg,false
  330.     jr    z,phdra
  331.     mvim    firmsg,false
  332.     prtx    mm6
  333. phdra:    call    mkhdr
  334.     prtx    $memry
  335.     ret
  336.  
  337. ; Write the mail file header sector.
  338. ; Close and re-open the file so it not lost on crash.
  339.  
  340. wthdr:    lxim    mrec,0
  341.     dodosa    setdma,mfhs
  342.     dodosa    wrec,mfcb
  343.     ret
  344. wtmfhs:    call    wthdr
  345.     dodosa    close,mfcb
  346.     dodosa    open,mfcb
  347.     ret
  348.  
  349. ; Log a message event
  350.  
  351. logmnr:    ld    hl,(msgnr)
  352.     call    bindec
  353.     move    logtxt+2,numb,5
  354.     ld    (hl),cr
  355.     mvim    event,'M'
  356.     jp    log
  357.  
  358. ; Insert message into message file.
  359.  
  360.     dseg
  361. tocall:    ds    6
  362. bbcall:    ds    6
  363. fmcall:    ds    6
  364. sndtyp:    ds    1
  365. type:    ds    1
  366. svcmsg:    ds    1
  367. mm1:    ds    2
  368. mm2:    ds    2
  369. mm3:    ds    2
  370. mm4:    ds    2
  371.     cseg
  372.  
  373. ; Parse an optional field.
  374. ; (DE) - loc of delimiter, (HL) - loc of text, (B) - Length of text.
  375.  
  376. pfl:    ld    b,a
  377.     ld    a,(de)        ; Delimiter
  378.     ld    de,bbcall
  379.     cp    '@'        ; BBS call?
  380.     jp    z,pfla        ; Yes
  381.     ld    de,fmcall
  382.     cp    '<'        ; FROM call?
  383.     ret    nz        ; Unknown, ignore
  384. pfla:    ld    a,b        ; Field length
  385.     jp    movcal        ; Get call
  386.  
  387. ; Parse fields 2 and 3.
  388.  
  389. p23:    ld    a,(f3l)
  390.     ld    hl,(f3st)
  391.     ld    de,(f2st)
  392.     jr    pfl
  393.  
  394. ; Parse fields 3 and 4.
  395.  
  396. p34:    ld    a,(f4l)
  397.     ld    hl,(f4st)
  398.     ld    de,(f3st)
  399.     jr    pfl
  400.  
  401. ; Parse fields 4 and 5.
  402.  
  403. p45:    ld    a,(f5l)
  404.     ld    hl,(f5st)
  405.     ld    de,(f4st)
  406.     jr    pfl
  407.  
  408. ; Parse fields 5 and 6.
  409.  
  410. p56:    ld    a,(f6l)
  411.     ld    hl,(f6st)
  412.     ld    de,(f5st)
  413.     jr    pfl
  414.  
  415. ; Parse fields 6 and 7.
  416.  
  417. p67:    ld    a,(f7l)
  418.     ld    hl,(f7st)
  419.     ld    de,(f6st)
  420.     jr    pfl
  421.  
  422. savpar:    fill    bbcall,6,' '
  423.     zmov    fmcall,mcall,6
  424.     fill    mtitle,mhtitl,' '
  425.     movb    type,opt2    ; Save message type
  426.     movw    msgnr,mnr    ; Save number for logging
  427.     movb    sndtyp,opt1    ; Save source of text
  428.     ret
  429.  
  430. ; Make message from file.
  431.  
  432. smsg7:    call    savpar
  433.     call    p67        ; Parse 6 and 7
  434.     jr    smsga
  435.  
  436. smsg5:    call    savpar
  437. smsga:    call    p45        ; Parse 4 and 5
  438.     jr    smsgb
  439.  
  440. smsg3:    call    savpar
  441. smsgb:    ld    hl,fcb3
  442.     call    ckname        ; Legal file name?
  443.     jp    z,ername    ; No
  444.     openr    fcb3        ; File there?
  445.     jp    z,erfind    ; No
  446.     jr    smsgg        ; Move the file to the msg
  447.  
  448. ; User is going to enter the message.
  449.  
  450. smsg1:    call    savpar
  451.     prtx    mm1        ; Ask for TO call
  452. smsgc:    call    getcmd        ; Get TO call
  453.     ckcmd    smsgc,badret,badret
  454.     ld    a,(flds)
  455.     cp    1        ; Call only?
  456.     jr    z,smsge        ; Yes
  457.     cp    3        ; @ or < ?
  458.     jr    z,smsgd        ; Yes
  459.     cp    5        ; @ and < ?
  460.     jp    nz,erwhat    ; No, what was?
  461.     call    p45
  462. smsgd:    call    p23
  463. smsge:    ld    a,(f1l)        ; Length of TO call
  464.     ld    hl,(f1st)    ; Location of TO call
  465.     jr    smsgh
  466.  
  467. smsg6:    call    savpar
  468.     call    p56        ; Parse 5 and 6
  469.     jr    smsgf
  470.  
  471. smsg4:    call    savpar
  472. smsgf:    call    p34        ; Parse 3 and 4
  473.     jr    smsgg
  474.  
  475. smsg2:    call    savpar
  476. smsgg:    ld    a,(f2l)        ; Length of TO call
  477.     ld    hl,(f2st)    ; Location of TO call
  478. smsgh:    ld    de,tocall
  479.     cp    6+1        ; Too long to be a callsign?
  480.     jp nc,    erwhat        ; Avoid W1XYZ@W2XYZ errors
  481.     call    movcal        ; Save TO call
  482.     prtx    mm2        ; Ask for title
  483. smsgi:    call    getdat        ; Get title
  484.     ckcmd    smsgi,badret,badret
  485.     movcmd    mtitle,0,mhtitl-1
  486.     ld    (hl),cr
  487.     cmpm    sndtyp,'M'
  488.     jr    z,cremsg
  489.  
  490. ; Gather the message into temp file.
  491.  
  492.     prtx    mm3
  493.     openw    msgfcb
  494.     jp    z,ercant
  495.     call    rcv        ; Gather text into temp file
  496. ; Returns zero set if I/O err
  497.     ld    a,(cmdtyp)
  498.     ckcmd    smsgj,badret,badret
  499. smsgj:    openr    msgfcb
  500.     jp    z,ercant
  501.  
  502. ; Move message from temp file into message file.
  503.  
  504. cremsg:    xor    a            ; Not a KT msg
  505.     jr    crems0
  506. crems1:    ld a,    1            ; Here from KT/SS logic
  507. crems0:    ld    (lktflg),a        ; Remember whether due to KT
  508.     zmov    tmfhs,mfhs,mfhsl    ; Make copy of file header
  509.     inxm    tmnr
  510.     inxm    tmcnt        ; Count the active message
  511.     movw    mhprev,tmlhd    ; Last hdr is previous to this
  512.     call    alloc        ; Allocate message header record
  513.     ld    (tmlhd),hl
  514.     dtz    tmfhd
  515.     jr    nz,cmsga
  516.     movw    tmfhd,tmlhd
  517. cmsga:    ld    hl,0
  518.     ld    (mhnext),hl    ; Mark as end of header chain
  519.     ld    (mhread),hl    ; Read zero times
  520.     ld    (mhsize),hl    ; Zero bytes
  521.     ld    (mhext),hl    ; No extension of header record
  522.     call    alloc        ; Allocate first text record
  523.     ld    (mhfmsg),hl
  524.     ld    (mhlmsg),hl
  525.     movw    mhnr,mnr
  526.     movb    mhtype,type
  527.     mvim    mhstat,'N'
  528.     call    curtime
  529.     zmov    mhdate,date,6
  530.     zmov    mhtime,time,4
  531.     zmov    mhto,tocall,6
  532.     zmov    mhfrom,fmcall,6
  533.     zmov    mhbbs,bbcall,6
  534.     zmov    mhtit,mtitle,mhtitl
  535.     lxim    mtnext,0
  536.     lxim    mtptr,mttext
  537.     mvim    mtcnt,126+1
  538.  
  539. ; Copy message text from temp file to mail file.
  540.  
  541. cmsgb:    call    fmbuf
  542.     jr    nz,cmsgc
  543.     ld    c,eof
  544. cmsgc:    ld    a,c
  545.     cp    lf
  546.     jr    z,cmsgb
  547.     ld    hl,mtcnt
  548.     dec    (hl)
  549.     call    z,newbuf
  550.     ld    hl,(mtptr)
  551.     ld    (hl),c
  552.     inc    hl
  553.     ld    (mtptr),hl
  554.     inxm    mhsize
  555.     ld    a,c
  556.     cp    eof
  557.     jr    nz,cmsgb
  558.  
  559. ; Write the last buffer
  560.  
  561.     movw    mrec,mhlmsg
  562.     dodosa    setdma,mmts
  563.     dodosa    wrec,mfcb
  564.  
  565. ; Write the message header
  566.  
  567.     movw    mrec,tmlhd
  568.     dodosa    setdma,mmhs
  569.     dodosa    wrec,mfcb
  570.  
  571. ; Read previous header, update its next header pointer.
  572.  
  573.     dtz    mlhd
  574.     jr    z,cmsgd
  575.     movw    mrec,mlhd
  576.     dodosa    rrec,mfcb
  577.     movw    mhnext,tmlhd
  578.     dodosa    wrec,mfcb
  579. cmsgd:    zmov    mfhs,tmfhs,mfhsl
  580.     call    wtmfhs        ; Write the file header
  581.     mvim    change,true
  582.     cmpm    sndtyp,'M'
  583.     jr    z,yy
  584.     dodosa    delete,rfcb    ; Delete the temp file
  585. ; Build the log file item.
  586. yy:    call    uslnkq        ; Gripe if that was done over a link
  587.     ld    hl,(msgnr)
  588.     call    bindec
  589.     move    logtxt+2,numb,5
  590.     ld    (hl),' '
  591.     inc    hl
  592.     move    ,tocall,6
  593.     ld    (hl),' '
  594.     inc    hl
  595. ; Put first 32 char of title in log
  596.     ld    de,mtitle
  597.     ld    b,32
  598. cmsge:    ld    a,(de)
  599.     cp    cr
  600.     jr    z,cmsgf
  601.     ld    (hl),a
  602.     inc    hl
  603.     inc    de
  604.     dec    b
  605.     jr    nz,cmsge
  606. cmsgf:    ld    (hl),cr
  607.     mvim    event,'M'
  608.     jp    log
  609.  
  610. ; Routine to gripe about Sends done via a Linked connect
  611.  
  612. uslnkq:    ld a,    (usport)
  613.     cp    'L'        ; Through a gateway link?
  614.     ret    nz        ; No, OK.
  615.     ld a,    (lktflg)
  616.     or    a        ; Due to KT?
  617.     ret    nz        ; KT's SS shouldn't generate a gripe
  618.     prtx    mplsno        ; Ask not to S while *** linked
  619.     ret
  620.  
  621. ; Copy a message to a file.
  622.  
  623. filmsg:    movb    type,opt2
  624.     zmov    numb,fcb2+1,5
  625.     call    decbin
  626.     jp    c,erwhat    ; Not a number
  627.     ld    (msgnr),hl
  628.     ckname    fcb3
  629.     jp    z,ername
  630.     dodosa    setdma,mmhs
  631.     movw    mrec,mlhd
  632. flmsga:    dtz    mrec
  633.     jp    z,erfind
  634.     dodosa    rrec,mfcb
  635.     ld    hl,(msgnr)
  636.     ld    de,(mhnr)
  637.     or    a        ; Clear carry
  638.     sbc    hl,de
  639.     jr    z,flmsgb
  640.     movw    mrec,mhprev
  641.     jr    flmsga
  642.  
  643. flmsgb:    cmpm    type,'A'
  644.     jr    z,flmsgx
  645.     openwn    fcb3
  646.     jp    z,waitc
  647.     jr    flmsgy
  648. flmsgx:    opena    fcb3
  649.     jp    z,waitc
  650. flmsgy:    mvim    firmsg,true
  651.     call    phdr
  652.     ld    hl,($memry)
  653.     call    @ctobuf        ; Put header into file
  654.     movw    mrec,mhfmsg
  655. flmsgc:    dtz    mrec
  656.     jr    z,flmsgf
  657.     dodosa    setdma,mmts
  658.     dodosa    rrec,mfcb
  659.     ld    hl,mttext
  660.     ld    e,126
  661. flmsgd:    ld    c,(hl)
  662.     call    tobuf
  663.     ld    a,c
  664.     cp    eof
  665.     jr    z,flmsgf
  666.     cp    cr
  667.     jr    nz,flmsgg
  668.     ld    c,lf
  669.     call    tobuf
  670. flmsgg:    inc    hl
  671.     dec    e
  672.     jr    nz,flmsgd
  673.     movw    mrec,mtnext
  674.     jr    flmsgc
  675. flmsgf:    closew
  676.     jp    z,ercant
  677.     jp    waitc
  678.  
  679. ; Delete current message from message file.
  680. ; Input: mhcur = record # of current msg header
  681.  
  682. kmsg:    movw    tmhsz,mhsize
  683.     movw    tmhlms,mhlmsg
  684.     movw    tmhnx,mhnext
  685.     movw    tmhpr,mhprev
  686.     dtz    tmhnx        ; Is there a next hdr?
  687.     jr    z,kmsgx        ; No (last msg)
  688.     movw    mrec,tmhnx    ; Point to next hdr
  689.     dodosa    setdma,mmhs    ; Point I/O to hdr buffer
  690.     dodosa    rrec,mfcb    ; Read next hdr
  691.     movw    mhprev,tmhpr    ; Replace next prev with cur prev
  692.     dodosa    wrec,mfcb    ; Write next hdr back
  693.  
  694. kmsgx:    dtz    tmhpr        ; Is there a previous hdr?
  695.     jr    z,kmsga        ; No (1st msg)
  696.     movw    mrec,tmhpr    ; Point to previous hdr
  697.     dodosa    setdma,mmhs    ; Point I/O to hdr buffer
  698.     dodosa    rrec,mfcb    ; Read previous hdr
  699.     movw    mhnext,tmhnx    ; Replace prev next with cur next
  700.     dodosa    wrec,mfcb    ; Write previous hdr back
  701.  
  702. ; Chain message sectors into free chain
  703.  
  704. kmsga:    dtz    mlfree
  705.     jr    z,kmsgb        ; Nothing in chain yet
  706.     movw    mrec,mlfree
  707.     dodosa    setdma,mmts
  708.     dodosa    rrec,mfcb
  709.     movw    mtnext,mhcur
  710.     dodosa    wrec,mfcb
  711.  
  712. ; Update file header record.
  713.  
  714. kmsgb:    dtz    mffree
  715.     jr    nz,kmsgc
  716.     movw    mffree,mhcur
  717. kmsgc:    movw    mlfree,tmhlms
  718.     ld    hl,(tmhsz)
  719.     ld    de,125
  720.     add    hl,de
  721.     ld    e,126
  722.     call    div8
  723.     ld    e,l
  724.     ld    d,0
  725.     inc    de        ; Add header sector
  726.     ld    hl,(mfree)
  727.     add    hl,de
  728.     ld    (mfree),hl
  729.     ld    hl,(mfhd)
  730.     ld    de,(mhcur)
  731.     or    a        ; Clear carry
  732.     sbc    hl,de
  733.     jr    nz,kmsgd
  734.     movw    mfhd,tmhnx
  735. kmsgd:    ld    hl,(mlhd)
  736.     or    a        ; Clear carry
  737.     sbc    hl,de
  738.     jr    nz,kmsge
  739.     movw    mlhd,tmhpr
  740. kmsge:    dcxm    mcnt        ; One less message
  741.     mvim    change,true
  742.     ret
  743.  
  744. ; Kill a message.
  745.  
  746.     dseg
  747. mm15:    ds    2
  748.     cseg
  749.  
  750. ; KF and KM command.
  751.  
  752. klmsg3:    movw    mhcur,mfhd    ; Point to first hdr
  753. klmsga:    dodosa    setdma,mmhs    ; Do I/O into hdr buffer
  754.     movw    mrec,mhcur    ; Point I/O to current hdr
  755.     ld    a,l
  756.     or    h        ; Any more hdrs?
  757.     jp    nz,xx    ; Yes
  758.     cmpm    change,true    ; Any killed?
  759.     call    z,wthdr        ; Write file hdr back
  760.     jp    erdone
  761.  
  762. xx:    dodosa    rrec,mfcb    ; Read the hdr
  763.     movw    temp,mhnext
  764.     ld    a,(opt2)    ; Type to kill
  765.     cp    'M'        ; Kill mine?
  766.     jr    z,klmsgb    ; Yes
  767.     cp    'F'        ; Kill forwarded?
  768.     jr    nz,klmsgd    ; No
  769.     ld    a,(mhstat)    ; Msg type
  770.     cp    'F'        ; forwarded?
  771.     jr    z,klmsgc    ; Yes, kill
  772.     jr    klmsgd
  773.  
  774. klmsgb:    ld    a,(mhstat)
  775.     cp    'Y'        ; Is read?
  776.     jr    nz,klmsgd    ; No, dont kill
  777.     comp    mhto,mcall,6    ; His message?
  778.     jr    nz,klmsgd    ; No, dont kill
  779. klmsgc:    movw    msgnr,mhnr    ; Save message # for logging
  780.     prtx    mm15
  781.     call    kmsg
  782.     call    logmnr
  783. klmsgd:    movw    mhcur,temp    ; Next becomes current
  784.     jr    klmsga        ; Go check this one
  785.  
  786. ; K <number> or KT <number> command
  787.  
  788. klmsg2:    movb    type,opt2    ; Save msg type
  789.     ld    hl,fcb2+1
  790.     jr    klmsgf
  791.  
  792. ; K or KT command, prompt for message number.
  793.  
  794. klmsg1:    movb    type,opt2
  795.     prtx    mm4
  796. klmsge:    call    getcmd
  797.     ckcmd    klmsge,badret,badret
  798.     ld    hl,fcb1+1
  799. klmsgf:    zmov    numb,,5
  800.     call    decbin
  801.     jp    c,erwhat    ; Was not a number
  802.     ld    (msgnr),hl
  803.     movw    mhcur,mlhd    ; Point to last hdr
  804.     dodosa    setdma,mmhs    ; Do I/O into hdr buffer
  805. klmsgg:    movw    mrec,mhcur    ; Point I/O to current hdr
  806.     ld    a,l
  807.     or    h        ; Any more hdrs?
  808.     jp    z,erfind    ; No
  809.     dodosa    rrec,mfcb    ; Read the hdr
  810.     ld    hl,(msgnr)
  811.     ld    de,(mhnr)
  812.     or    a        ; Clear carry
  813.     sbc    hl,de        ; Right msg?
  814.     jr    z,klmsgh    ; Yes
  815.     movw    mhcur,mhprev    ; Previous becomes current
  816.     jr    klmsgg        ; Go check this one
  817. ; Found the message.
  818. klmsgh:    call    permit        ; Permission to kill?
  819.     jr    z,klmsgi    ; Yes
  820.     cmpm    type,'T'    ; Killing NTS traffic msg?
  821.     jp    nz,erprot    ; No
  822.     cmpm    mhtype,'T'    ; NTS traffic msg?
  823.     jp    nz,erprot    ; No
  824. klmsgi:    ld a,    (mhtype)
  825.     push    psw
  826.     zmov    mtitle,mhtit,mhtitl
  827.     zmov    tocall,mhfrom,6
  828.     call    kmsg        ; Kill the msg
  829.     call    logmnr        ; Log the event
  830.     pop    psw        ; Type of msg just killed
  831.     cp    'T'        ; Was it NTS tfc?
  832.     jr nz,    klmsgj        ; Go if not
  833.     cmpm    type,'T'    ; Killing by KT command?
  834.     jr    nz,klmsgj    ; No
  835.     cmpm    svcmsg,true    ; Config says to gen svc msg?
  836.     jr    z,gensvc    ; Yes
  837. klmsgj:    call    wthdr        ; Write file hdr back
  838.     jp    erdone        ; Tell user it done
  839.  
  840. ; Killed NTS msg, generate a service msg.
  841.  
  842. gensvc:    fill    bbcall,6,' '    ; Don't know bbs yet
  843.     zmov    fmcall,ocall,6
  844.     ld    a,'S'
  845.     ld    (type),a    ; S for service msg
  846.     ld    (sndtyp),a    ; S so will delete MSG.TMP
  847.     ld    (logtxt),a    ; Log as send
  848.     ld    (logtxt+1),a    ; Log as SS
  849. ; Create the message in MSG.TMP
  850.     openw    msgfcb
  851.     ntobuf    sm1,sm1l
  852.     ld    hl,(msgnr)    ; # of msg killed
  853.     call    bindec
  854.     ntobuf    numb,5
  855.     ntobuf    sm2,sm2l
  856.     ntobuf    ocall,6
  857.     ntobuf    sm3,sm3l
  858.     ntobuf    mcall,6
  859.     ntobuf    sm4,sm4l
  860.     ntobuf    time,4
  861.     ntobuf    sm5,sm5l
  862.     ntobuf    date,6
  863.     ld    c,cr
  864.     call    tobuf
  865.     ld    c,lf
  866.     call    tobuf
  867.     ld    c,eof
  868.     call    tobuf
  869.     closew    msgfcb
  870.     openr    msgfcb
  871.     movw    msgnr,mnr    ; Set current msg # for logging
  872.     call    crems1
  873.     jp    erdone        ; Tell user it done
  874.  
  875. sm1:    db    'Msg '
  876. sm1l    equ    $-sm1
  877. sm2:    db    ' was taken from '
  878. sm2l    equ    $-sm2
  879. sm3:    db    ' by '
  880. sm3l    equ    $-sm3
  881. sm4:    db    ' at '
  882. sm4l    equ    $-sm4
  883. sm5:    db    ' on '
  884. sm5l    equ    $-sm5
  885.  
  886. ; Check if user has unread mail
  887.  
  888.     dseg
  889. mm5:    ds    2
  890.     cseg
  891. newmsg:    srclst    mcall,ucalls,uccnt,6,6
  892.     ret    nz        ; User has no mail
  893.     prtx    mm5        ; Has unread mail, say so
  894.     lxim    msgnr,1        ; Search all msgs
  895.     mvim    opt2,1        ; Option for "list unread"
  896.     jr    lmsgd
  897.  
  898. ; List message headers.
  899.  
  900. lstmsg:    movw    msgnr,usmnr    ; Min msg # to list
  901.     ld    a,(opt2)
  902.     cp    ' '        ; Just "L"?
  903.     jr    z,lmsgc        ; Yes
  904.     lxim    msgnr,0        ; Assume search all
  905.     cp    '@'        ; List msgs @ BBS?
  906.     jr    z,lmsga        ; Yes
  907.     cp    '<'        ; List msgs FROM call?
  908.     jr    z,lmsga        ; Yes
  909.     cp    '>'        ; List msgs TO call?
  910.     jr    nz,lmsgc    ; No
  911. lmsga:    zmov    scall,fcb2+1,6    ; Save the call
  912.     jr    lmsgd
  913.  
  914. lmsgc:    ld    a,(f2l)
  915.     or    a        ; Message # given?
  916.     jr    z,lmsgd        ; No
  917.     zmov    numb,fcb2+1,5
  918.     call    decbin
  919.     jp    c,erwhat    ; Not a number
  920.     ld    (msgnr),hl
  921. lmsgd:    dodosa    setdma,mmhs    ; Do I/O into header buffer
  922.     mvim    firmsg,true    ; Force header
  923.     movw    mrec,mlhd    ; Point to last header
  924. lmsge:    dtz    mrec        ; More headers?
  925.     jr    z,lmsgh        ; No
  926.     dodosa    rrec,mfcb    ; Read the msg header
  927.     cmpm    opt2,'L'    ; Listing n last?
  928.     jr    z,lmsgf        ; Yes
  929.     ld    de,(msgnr)    ; Number wanted
  930.     ld    hl,(mhnr)    ; Message number
  931.     or    a        ; Clear carry
  932.     sbc    hl,de        ; This msg # < # wanted?
  933.     jr    c,lmsgh        ; Yes, done
  934.     jr    lmsgg
  935.  
  936. lmsgf:    dtz    msgnr        ; More to list?
  937.     jr    z,lmsgh        ; No
  938. lmsgg:    call    lms        ; List the msg hdr
  939.     movw    mrec,mhprev    ; Point to previous header
  940.     call    pause        ; Check for xoff
  941.     jr    lmsge        ; Check next msg header
  942.  
  943. lmsgh:    cmpm    opt2,1        ; Listing users unread?
  944.     call    nz,logmnr    ; Log if not
  945.     cmpm    firmsg,true    ; Find any to list?
  946.     jp    z,erfind    ; No
  947.     jp    waitc
  948.  
  949. lms:    cmpm    mhtype,'P'    ; Personal?
  950.     jr    nz,lmsa        ; No, ok to list
  951.     call    permit        ; Personal and users?
  952.     ret    nz        ; No, no list
  953. lmsa:    ld    a,(opt2)
  954.     cp    ' '        ; List specific type?
  955.     jr    nz,lmsc        ; Yes
  956. lmsb:    cmpm    mhtype,'T'    ; Traffic?
  957.     ret    z        ; Yes, no list
  958.     cmpm    mhtype,'S'    ; Traffic service?
  959.     ret    z        ; Yes, no list
  960.     jp    phdr
  961.  
  962. lmsc:    cp    'M'        ; TO or FROM user only?
  963.     jr    nz,lmsd        ; No
  964.     comp    mhto,mcall,6    ; TO this user?
  965.     jp    z,phdr        ; Yes
  966.     comp    mhfrom,mcall,6    ; FROM this user?
  967.     jp    z,phdr        ; Yes
  968.     ret
  969.  
  970. lmsd:    cp    1        ; TO and UNREAD only?
  971.     jr    nz,lmse        ; No
  972.     cmpm    mhstat,'N'    ; Unread?
  973.     ret    nz        ; No, no list
  974.     comp    mhto,mcall,6    ; To user?
  975.     ret    nz        ; No, no list
  976.     jp    phdr
  977.  
  978. lmse:    cp    '>'        ; List msgs TO given call?
  979.     jr    nz,lmsf        ; No
  980.     comp    mhto,scall,6    ; This msg?
  981.     ret    nz        ; No
  982.     jp    phdr
  983.  
  984. lmsf:    cp    '<'        ; List msgs FROM given call?
  985.     jr    nz,lmsg        ; No
  986.     comp    mhfrom,scall,6    ; This msg?
  987.     ret    nz        ; No
  988.     jp    phdr
  989.  
  990. lmsg:    cp    '@'        ; List msgs @ given call?
  991.     jr    nz,lmsi        ; No
  992.     cmpm    scall,' '    ; Call given?
  993.     jr    z,lmsh        ; No
  994.     comp    mhbbs,scall,6    ; This msg?
  995.     ret    nz        ; No
  996.     jp    phdr
  997. lmsh:    cmpm    mhbbs,' '    ; Is an @?
  998.     ret    z        ; No, no list
  999.     jp    phdr
  1000.  
  1001. lmsi:    cp    'L'        ; List Last n?
  1002.     jr    nz,lmsj        ; No
  1003.     dcxm    msgnr        ; Count this one
  1004.     jp    phdr
  1005.  
  1006. lmsj:    cp    'F'        ; Forwarded msgs only?
  1007.     jr    nz,lmsk        ; No
  1008.     cmpm    mhstat,'F'    ; This one forwarded?
  1009.     ret    nz        ; No
  1010.     jp    phdr        ; Yes, list
  1011.  
  1012. lmsk:    cp    'Y'        ; "Read" msgs only?
  1013.     jr    nz,lmsl        ; No
  1014.     cmpm    mhstat,'Y'    ; This one read?
  1015.     ret    nz        ; No
  1016.     jp    phdr        ; Yes, list
  1017.  
  1018. lmsl:    ld    hl,mhtype    ; List msgs of given type.
  1019.     cp    (hl)        ; This type?
  1020.     ret    nz        ; No
  1021.     jp    phdr
  1022.  
  1023. ; Read a message.
  1024.  
  1025.     dseg
  1026. found:    ds    1
  1027. rdnr:    ds    2
  1028.     cseg
  1029.  
  1030. ; RM command
  1031.  
  1032. rdmsg3:    movb    type,opt2
  1033.     lxim    rdnr,0        ; Look at all msgs
  1034.     jr    rdmsgc
  1035.  
  1036. ; R <number> command
  1037.  
  1038. rdmsg2:    movb    type,opt2
  1039.     ld    hl,fcb2+1
  1040.     jr    rdmsgb
  1041.  
  1042. ; R command
  1043.  
  1044. rdmsg1:    movb    type,opt2
  1045.     prtx    mm4
  1046. rdmsga:    call    getcmd
  1047.     ckcmd    rdmsga,badret,badret
  1048.     ld    hl,fcb1+1
  1049. rdmsgb:    zmov    numb,,5
  1050.     call    decbin
  1051.     jp    c,erwhat    ; Not a number
  1052.     ld    (rdnr),hl
  1053.  
  1054. rdmsgc:    movw    mrec,mlhd    ; Point to last header
  1055.     mvim    found,false    ; None found yet
  1056. rdmsgd:    dtz    mrec        ; More headers?
  1057.     jr    z,rdmsgh    ; No, done
  1058.     dodosa    setdma,mmhs
  1059.     dodosa    rrec,mfcb    ; Read header
  1060.     ld    de,(rdnr)    ; Number wanted
  1061.     ld    hl,(mhnr)    ; Message number
  1062.     or    a        ; Clear carry
  1063.     sbc    hl,de        ; This msg # < # wanted?
  1064.     jr    c,rdmsgh    ; Yes, done
  1065.     jr    z,rdmsgf    ; Is the one wanted
  1066.     cmpm    type,'M'    ; Read mine?
  1067.     jr    nz,rdmsge    ; No
  1068.     comp    mcall,mhto,6    ; Mine?
  1069.     call    z,pmsg        ; Yes, print it
  1070. rdmsge:    movw    mrec,mhprev    ; No, point to previous header
  1071.     jr    rdmsgd        ; and read it
  1072.  
  1073. rdmsgf:    cmpm    mhtype,'P'    ; Private msg?
  1074.     jr    nz,rdmsgg    ; No
  1075.     call    permit        ; Ok to read?
  1076.     jp    nz,erprot    ; No, tell user
  1077. rdmsgg:    call    snoopq        ; Tell the world if snooping on other's mail
  1078.     jr nz,    rmsgsn        ; Check whether to allow the read if snoop
  1079. rmsgsr:    call    pmsg        ; Print the msg
  1080.     jp    waitc        ; Done
  1081.  
  1082. rmsgsn:    ld    a,(usopt)    ; Temp, key on either exclusion
  1083.     and    usoexa+usoexb    ; If not excluded anywhere,
  1084.     jr    z,rmsgsr    ;  allow the read anyway
  1085.     jp    erprot        ; If excluded somewhere, suppress it.
  1086.     
  1087. rdmsgh:    cmpm    found,false    ; Any found?
  1088.     jp    z,erfind    ; No
  1089.     jp    waitc        ; Done
  1090.  
  1091. pmsg:    inxm    mhread        ; Increment # times msg read
  1092.     comp    mhto,mcall,6    ; Users msg?
  1093.     jr    nz,pmsga    ; No
  1094.     mvim    mhstat,'Y'    ; Mark as read
  1095. pmsga:    mvim    change,true    ; Mark file changed
  1096.     dodosa    wrec,mfcb    ; Write header back
  1097.     ld    a,true
  1098.     ld    (found),a
  1099.     ld    (firmsg),a
  1100.     call    phdr        ; Print msg header
  1101.     call    prtmsg        ; Print the msg
  1102.     movw    msgnr,mhnr
  1103.     call    logmnr        ; Log the event
  1104.     ret
  1105.     end
  1106. 
  1107.