home *** CD-ROM | disk | FTP | other *** search
/ PDA Software Library / pdasoftwarelib.iso / PSION / 1997 / 946.ZIP / SYS$PS4E.OPL < prev   
Encoding:
Text File  |  1997-03-06  |  20.5 KB  |  859 lines

  1. REM Test > autooff feature
  2. REM WHAT HAPPENS IF ALARM FIRES WHILST IN THE PROCESS
  3. REM OF CANCELLLING.
  4. rem if delta time< autooff time - psion wont go off
  5. rem if switched on by alarm and password disabled
  6. rem   and showinf = true then it should show owner
  7. rem   information. Does it?
  8. rem there should only be one test for alarmed:()
  9. REM ------------------------------------------
  10. REM         Pason 4         for Psion 3/3a
  11. REM         1 Nov 1994     by Steve Hawtin
  12.  
  13. REM A routine to:
  14. REM   Turn the password on a regular intervals
  15. REM   Switch off alarm sounds
  16. REM   Switch off the remote link
  17. rem alarm sounds should come on even if pwd on
  18.  
  19. REM The idea is that the first time the 
  20. REM Psion is turned on for the day you must 
  21. REM provide a password, the rest of the day
  22. REM the password is disabled.
  23. REM ------------------------------------------
  24. REM ╕ 1994 Steve Hawtin
  25. REM ╕ 1995-7 Andrew Lord
  26. REM
  27. REM This file may be freely distributed 
  28. REM provided that the file pason.txt is 
  29. REM included in the distribution
  30. REM ------------------------------------------
  31. REM    1 Dec 1995    Modified by Andrew Lord
  32. REM ------------------------------------------
  33. REM     pason routine uses OS call to set/unset
  34. REM     password rather than using macro system.
  35. REM     This results in a smaller, more secure app
  36. REM
  37. REM     Added "LOCK ON" so that backup routines
  38. REM     don't fail tring to stop it.
  39. REM     Changed to APP type 0
  40.  
  41. REM ------------------------------------------
  42. REM    2 Jan 1996    Modified by Andrew Lord
  43. REM ------------------------------------------
  44. REM     Switches machine off immediately
  45. REM     Switches on alarms also
  46. REM   Bug fix - got out of sync if not switched on
  47. REM     Neater message logging
  48. REM     Validates password.
  49. REM     Quick Password feature
  50. REM ------------------------------------------
  51. REM    1 Feb 1996    Modified by Andrew Lord
  52. REM ------------------------------------------
  53. REM     Uses Event loop and timers
  54. REM     Optionally switch off link
  55. REM     Disabled <Shift-System> and <Psion-Esc>
  56. REM     Smaller run time footprint - shrunk bitmap
  57. REM     Only switches off if it was switched on
  58. REM     less than 1 sec. ago.
  59. REM     Password change mechanism. Its not perfect
  60. REM      press <enter> twice in quick sucession.
  61. REM ------------------------------------------
  62. REM    10 Feb 1996    Modified by Andrew Lord
  63. REM ------------------------------------------
  64. REM     Removed quick password feature
  65. REM     changed it to display owner information
  66. REM     Added Hot-Key feature.
  67. REM ------------------------------------------
  68. REM 10 Apr 1996
  69. REM  Hotkey bug fixed - Holger Pfaff
  70. REM  Display dialog after password entry stopped
  71. REM ------------------------------------------
  72. REM 14 Apr 1996
  73. REM  Pason can now activate a given number of
  74. REM  minutes after Switch on OR at set times
  75. REM  If the Psion is already in use then it 
  76. REM  should delay activation.
  77. REM ------------------------------------------
  78. REM 14 May 1996
  79. REM Oops. There is no "On Event" for Series 3
  80. REM Machines.
  81. REM ------------------------------------------
  82. REM 26 May 1996
  83. REM Fixed async events that complete before 
  84. REM IOWAIT. This was causing Pason to miss some
  85. REM foreground events.Now buf% is zeroed BEFORE
  86. REM ioa call.
  87. REM Fixed incorrect display of next event time (again!)
  88. REM Because Pason may momentarily switch on the Psion
  89. REM This my intefere with various "Switch on Programs"
  90. REM some of these programs play a sound
  91. rem so Pason will switch off sound momentarily
  92. REM replaced ioa() with ioc()
  93. REM ------------------------------------------
  94. REM NOV 1996
  95. REM Redesigned configuration menu.
  96. REM Sienna compatible (emulator!)
  97. REM Check passwd off time > autooff time 
  98. REM ------------------------------------------
  99. REM JAN 97
  100. REM ------------------------------------------
  101. REM Rewrote - buggy event loop 
  102. REM Used a signal to determine whether Pason
  103. REM switched the psion on. Not perfect but much
  104. REM more accurate than the previous method.
  105.  
  106. REM     Wish list
  107. REM         Stop "WORD" if a "sensitive" file is
  108. REM             left open.
  109. REM ------------------------------------------
  110. REM ------------------------------------------
  111.  
  112. app pason4e : type 0 :enda
  113.  
  114.  
  115. PROC main:
  116.     global ver$(10)
  117.     global deltatm&      REM Timer increment mode
  118.     global debug%
  119.     GLOBAL nextTim&    rem Next timer event
  120.     GLOBAL intrvl&     rem Seconds between each 
  121.                        rem activation.
  122.     GLOBAL pwmode%
  123.     GLOBAL crypt%(9)   rem Encryption Data
  124.     GLOBAL passwd$(10) rem System password
  125.     GLOBAL alarm%
  126.     rem xx global owninf% 
  127.     global linkoff%,infaddr%
  128.     GLOBAL buf%(6)     rem General buffer
  129.     local  evbuf%(2)    rem event buffer
  130.     GLOBAL evstat%      rem Event Async return status
  131.     local dbgkey%       rem Debug toggle key
  132.     global keycode%     rem Hot key to set password
  133.     global keymod%      rem Modifiers for hot-key
  134.     local alarmh%,a1&(3)    rem alarm handle & data
  135.     global dalarmh%,a2&(3)  rem alarm handle & data
  136.     global wait4pw%      rem -1 if waiting for passwd
  137.     global dstate$(1)
  138.     global newuse&,olduse&,ontime&
  139. rem xx    global showing%      rem -1 if showing owner inf
  140.     global gid%,ghgt%,gwid%          rem window id
  141.     global unit%
  142.     global onsig%
  143.     REM-----------------------------
  144.     REM Get all "SWITCH ON" events
  145.     call($6c8d) : gupdate
  146.     ver$ = "4e"
  147.     debug% = 0
  148.     
  149.     call($138B)
  150.     
  151.     REM-----------------------------
  152.     REM Alarm data blocks
  153.     pwmode% = 1
  154.     alarm% = 2
  155.     linkoff% = 1
  156.     alarmh%=addr(a1&())  : REM Regular alarm
  157.     dalarmh%=addr(a2&()) : REM Delta alarm
  158.  
  159.     alarmi:(alarmh%)
  160.     alarmi:(dalarmh%)
  161.     
  162.     unit% = 3600
  163.  
  164.     log:("INIT")
  165.     REM-----------------------------
  166.     REM Make pason "busy"
  167.     lock on
  168.  
  169.     REM-----------------------------
  170.     REM Trap PSION-ESC  (ESCAPE OFF!)
  171.     escape off
  172.  
  173.     REM-----------------------------
  174.     REM Keycode and modifiers for PSION-CONTROL-P
  175.     keycode% = asc("p")+$200
  176.     keymod% = $0c
  177.     keycap:(1,keycode%,keymod%)
  178.  
  179.     rem Toggle debug mode PSION/CTRL/SHIFT-D
  180.     dbgkey% = asc("d")+$200
  181.     keycap:(1,dbgkey%,keymod%)
  182.  
  183.     
  184.     REM-----------------------------
  185.     rem make the screen very small
  186.     rem this saves about 10K runtime!
  187.     ghgt% = gheight
  188.     gwid% = gwidth
  189.     gsetwin 1,1,1,1
  190.     log:("PASON BEGIN!")
  191.     REM -- show dialog panel
  192.     crypt$:("I",passwd$)
  193.     if shDialog: = 0 : stop : endif
  194.  
  195.     REM-----------------------------
  196.     
  197.     REM -- main loop
  198.     alarm&:(dalarmh%,deltatm&)
  199.     timeron:(alarmh%)
  200.     olduse& = runtime&:
  201.  
  202.     agetev%:(addr(evstat%),addr(evbuf%()))
  203.     WHILE 1
  204.         iowait
  205.         log:("")
  206.         if evstat% <> -46
  207.             buf%(1)=evbuf%(1)
  208.             buf%(2)=evbuf%(2)
  209.             
  210.             log:("EVENT!"+hex$(buf%(1))+","+hex$(buf%(2))+","+num$(evstat%,3))
  211.             log:("onsig%="+num$(onsig%,3))
  212.             REM Read the next event as soon as possible
  213.             agetev%:(addr(evstat%),addr(evbuf%()))
  214.             
  215.             REM Async Event occured
  216.             
  217.             if buf%(1) = $401 rem foreground
  218.  
  219. rem xx                if not showing% 
  220.                     foregrnd:(0)
  221. rem xx                endif
  222.  
  223.                 if wait4pw%
  224.                     REM The user has entered the password
  225.                     log:("=== done waiting for password")
  226.                     pason:(0,passwd$)
  227.                     wait4pw%=0
  228.                 endif
  229.  
  230.             elseif buf%(1) = $403  rem switch on
  231.                 rem if debug% : beep 3,400 : endif
  232.                 newuse& = runtime&:
  233.                 ontime& = max(0,newuse& - olduse&)
  234.                 olduse& = newuse&
  235.                 log:("previous ontime was "+num$(ontime&,5))
  236.  
  237.                 rem Return password on/off status
  238.                 if call($318B)
  239.  
  240.                     rem First switch on after pason activation
  241.                     rem wait til user enters password.
  242.                     rem otherwise everything gets out of step
  243.                     rem This should also cope with alarms
  244.                     log:("=== waiting for password")
  245.                     rem remove owner inf. screen if its present
  246.                     rem xx showinf:(0)
  247.                     foregrnd:(-1)
  248.                     wait4pw% = -1
  249.                     rem open agenda now
  250.                      
  251.                 endif
  252.                 onsig%=-1
  253.                 iosignal
  254.  
  255.             elseif (buf%(1)=keycode% and (buf%(2) and $ff)=keymod%)
  256.  
  257.                 REM HOT KEY
  258.                 foregrnd:(-1)
  259.                 mainmnu:(alarmh%,dalarmh%)
  260.                 foregrnd:(0)
  261.  
  262.             rem xx elseif ((buf%(1) > 26 and buf%(1) < $7f) or buf%(1)=$402) and showing%
  263.  
  264.                 rem xx REM Any button press should remove
  265.                 rem xx REM the owner information screen.
  266.                 rem xx showinf:(0)
  267.                 rem xx foregrnd:(0)
  268.                 
  269.             elseif buf%(1)=dbgkey% and (buf%(2) and $ff)=keymod%
  270.  
  271.                 REM CTRL+PSION+d toggle debug mode
  272.                 debug% = 1 - debug%
  273.  
  274.             endif
  275.  
  276.         elseif alarmed%:(dalarmh%)
  277.  
  278.             log:("DELTA ALARM!"+dstate$)
  279.             if onsig%
  280.                 if dstate$="W"
  281.                     dstate$="F"
  282.                     alarm&:(dalarmh%,ontime&)
  283.                 elseif dstate$="F"
  284.                     pason:(-1,passwd$)
  285.                     dstate$="D"
  286.                 endif
  287.             else
  288.                 redelta$:
  289.             endif
  290.  
  291.             log:("dstate$ = "+dstate$)
  292.             smartoff:
  293.             
  294.         elseif alarmed%:(alarmh%)
  295.  
  296.             log:("TIMER ALARM!")
  297.             if pwmode% = 2
  298.                 pason:(-1,passwd$)
  299.             endif
  300.  
  301.             if alarm%=2
  302.                 rem Enable alarm sounds
  303.                 soundon%:($4)
  304.             endif
  305.  
  306.             if linkoff%=2
  307.                 linkoff:
  308.             endif
  309.  
  310.             smartoff:
  311.             timeron:(alarmh%)
  312.  
  313.         elseif onsig%
  314.  
  315.             log:("NOT ON BY PASON SIGNAL!")
  316.             rem xx showinf:(-1)
  317.  
  318.             rem The other timers haven't kicked in so
  319.             rem We better restart the delta timer
  320.             redelta$:
  321.             log:("resetting onsig%")
  322.             onsig%=0
  323.             
  324. rem *************************
  325. rem Else the event is ignored
  326. rem *************************
  327.         endif
  328.  
  329.     endwh
  330.  
  331. ENDP
  332. proc mingap&:(tm&)
  333.     local aoff%
  334.     aoff%=call($178b)
  335.     if aoff% = -1
  336.         log:("Auto off disabled")
  337.         return tm&
  338.     else
  339.         log:("auto off in "+num$(aoff%,7)+" orig tm in "+num$(tm&,7))
  340.         return &0+max(&2+aoff%,tm&)
  341.     endif
  342. endp
  343.  
  344. rem Re-schedule the delta alarm
  345. proc redelta$:
  346.     dstate$="W"
  347.     
  348.     alarm&:(dalarmh%,mingap&:(deltatm&))
  349.     olduse& = runtime&:
  350.     ontime& = 0
  351.     log:("reset on time to 0")
  352. endp
  353.  
  354. rem ASYNC GETEVENT
  355. proc agetev%:(statptr%,bufptr%)
  356.     pokel bufptr%,0
  357.     pokew statptr%,0
  358.     ioc(-2,14,#statptr%,#bufptr%,#0)
  359.     ioyield
  360. endp
  361.  
  362. rem xx proc showinf:(mode%)
  363. rem xx     local inf$(255),i%
  364. rem xx     if owninf%<>2
  365. rem xx         return
  366. rem xx     elseif mode%=showing% : rem NEW
  367. rem xx         log:("Showinf ignored "+num$(showing%,2))
  368. rem xx         rem We must force pason to the foregrnd
  369. rem xx         rem in case it was switched on using
  370. rem xx         rem The button bar. This has the effect
  371. rem xx         rem of sending pason to the background
  372. rem xx         rem whilst showing% <> 0. Normally
  373. rem xx         rem we want pason to stop showing
  374. rem xx         rem butwe don't want that for this case
  375. rem xx         foregrnd:(mode%)
  376. rem xx         return
  377.  
  378. rem xx     elseif mode%
  379. rem xx             if not wait4pw%
  380. rem xx rem        if call($318B)
  381.  
  382. rem xx             log:("Showinf: on "+num$(call($318b),5))
  383. rem xx             REM Get owner Information
  384. rem xx             inf$ = "$WS_PW"+chr$(0)
  385. rem xx             infaddr%=uadd(addr(inf$),1)
  386. rem xx             call($258B,0,0,0,infaddr%,infaddr%)
  387. rem xx             gid% = gcreate(0,0,gwid%,ghgt%,1)
  388. rem xx             guse gid%
  389. rem xx             gborder $303
  390.         
  391. rem xx             gat 20,20 : gprint "Owner Information"
  392. rem xx             i% = 1
  393. rem xx             while i%<=4
  394. rem xx                 gat 20,20+i%*15 : gprint ownstr$:(infaddr%,-1+i%*4)
  395. rem xx                 i%=i%+1
  396. rem xx             endwh
  397. rem xx             foregrnd:(-1)
  398. rem xx             showing% = mode%
  399. rem xx             endif
  400. rem xx rem        endif
  401. rem xx     else
  402. rem xx         trap gclose gid%
  403. rem xx         showing% = mode%
  404. rem xx     endif
  405. rem xx endp
  406.  
  407. proc smartoff:
  408.     if onsig% 
  409.         log:("smartoff: waiting for signal")
  410.         iowait
  411.         log:("smartoff: switching off")
  412.         off
  413.     else
  414.         log:("smartoff: - staying on")
  415.     endif
  416.     onsig%=0
  417. endp
  418.  
  419. REM set a timer to wake up at next interval
  420. proc timeron:(alarmh%)
  421.     if alarm%=2 or linkoff%=2 or dstate$=""
  422.         rem Advance nextTim& to next switch on time
  423.         if intrvl& > 0
  424.             rem nextTim& = begTim&
  425.             while nextTim& <= now&:
  426.                 nextTim& = nextTim& + intrvl&
  427.             endwh
  428.             alarm&:(alarmh%,mingap&:(nextTim&-now&:))
  429.         endif
  430.     endif
  431. endp
  432.  
  433. rem Enable normal password security
  434. REM Change system password via pason.
  435. proc mainmnu:(alarmh%,dalarmh%)
  436.     local o$(8),n$(8),key%,k$(1)
  437.     while 1
  438.         dinit "PASON"+ver$+" - Password protected"
  439.         dxinput o$,"Password"
  440.         if dialog = 0
  441.             return
  442.         elseif o$ <> crypt$:("D",passwd$)
  443.             alert("Incorrect password")
  444.         else
  445.             break
  446.         endif
  447.     endwh
  448.     REM Main menu
  449.     minit
  450.     mcard "PASON"+ver$,"Configure",%c,"Change System Password",%p,"Change Hot-Key",%h,"Quit",%q
  451.     key% = menu
  452.     
  453.     REM Change Password
  454.     while key%=%p
  455.         dinit "Change System Password"
  456.         dxinput o$,"New password"
  457.         dxinput n$,"Confirm password"
  458.         if dialog = 0
  459.             break
  460.         elseif o$<>n$
  461.             alert("Password not confirmed")
  462.         elseif len(n$)<4
  463.             alert("Password too short")
  464.         else
  465.             REM set the new password
  466.             n$=crypt$:("E",n$)
  467.             setpwd%:(passwd$,n$)
  468.             passwd$ = n$
  469.             break
  470.         endif
  471.     endwh
  472.     
  473.     REM Hot Key
  474.     if key%=%h
  475.         dinit "PASON"+ver$+" Hot Key"
  476.         k$=chr$(keycode% and $FF) rem remove psion code
  477.          dedit k$,"Psion+Control+",1
  478.         if dialog 
  479.             keycap:(0,keycode%,keymod%)
  480.             keycode% = asc(k$)+$200 rem + psion code
  481.             keycap:(1,keycode%,keymod%)
  482.         endif
  483.         
  484.     elseif key%=%c
  485.  
  486.         alarm&:(alarmh%,&0)
  487.         alarm&:(dalarmh%,&0)
  488.         nexttim& = nexttim&-(nexttim&/86400)*86400
  489.         maincfg:(0)
  490.         timeron:(alarmh%)
  491.         alarm&:(dalarmh%,deltatm&)
  492.         dstate$="W"
  493.  
  494.     elseif key%=%q
  495.         pason:(-1,passwd$)
  496.         stop
  497.     endif
  498. endp
  499.  
  500. REM Encryption using OS calls
  501. PROC crypt$:(mode$,pwd$)
  502.     local q$(9)
  503.     if mode$="I"
  504.         rem (I)NIT
  505.         q$=pwd$
  506.         call($348b,0,0,0,addr(q$),addr(crypt%()))
  507.     else
  508.         rem (E)NCRYPT or (D)ECRYPT
  509.         q$=pwd$
  510.         crypt%(9) = 0
  511.         call($358b - $100 * (mode$="E"),0,len(q$),0,addr(crypt%()),uadd(addr(q$),1))
  512.     endif
  513.     return q$
  514. endp
  515.  
  516. rem The battery+mains time
  517. rem This is used to work out how long the 
  518. rem psion was on for. This can be used to 
  519. rem determine the after last switch off time
  520. rem without constantly polling.
  521.  
  522. proc runtime&:
  523.     local buf%(5),bat&,ext&,ma&
  524.     call($228e,addr(buf%()))
  525.     return bat&/32+ext&/32
  526. endp
  527.  
  528. PROC pason:(on%,pwd$)
  529.     REM using OS call $8B sub $30
  530.     REM Turn the password on
  531.  
  532.     local ax%,bx%,cx%,dx%,si%,di%
  533.     local buf$(8)
  534.  
  535.     buf$ = crypt$:("D",pwd$)
  536.  
  537.     ax% = $3000 - on%
  538.  
  539.     si% = addr(buf$)
  540.     IF (OS($8B,addr(ax%)) and 1 ) = 1
  541.         alert("Pason - Cant change pwd status",ERR$(ax% OR $FF00))
  542.         stop
  543.     ENDIF
  544.     log:("PASSWORD IS "+hex$(on%))
  545. ENDP
  546.  
  547. PROC shDialog:
  548.     REM -- show the dialog panel to setup job params
  549.  
  550.     if setpwd%:("CHK","")
  551.         alert("System password not set","Terminating")
  552.         return 0
  553.     endif
  554.  
  555.  
  556.     REM get the plaintext password required for
  557.     REM the os call.
  558. rem xx    owninf% = 1
  559.     deltatm& = 60*60
  560.     intrvl& = 24.0*unit%
  561.     return maincfg:(1)
  562. endp
  563.  
  564. REM main configuration parameters.
  565. REM The system password should be enabled.
  566. proc maincfg:(first%)
  567.     local ret%,p$(35)
  568.     
  569.     p$="PASON"+ver$+" ╕ S.Hawtin/A.Lord"
  570.     if first%
  571.         dINIT p$
  572.         dtext "","PASON needs your current"
  573.         dtext "","system password to work"
  574.         dtext ""," "
  575.         dXINPUT passwd$,"Password"
  576.         if dialog 
  577.             passwd$ = crypt$:("E",passwd$)
  578.             ret% = setpwd%:("CHK",passwd$) <> 0 
  579.             if ret% = 0
  580.                 alert("incorrect password","Terminating")
  581.             endif
  582.         endif
  583.     else
  584.         ret% = 1
  585.     endif
  586.  
  587.     if ret%
  588.         dINIT p$
  589.         dtext "","Activate password regularly after"
  590.         dtext "","a given time OR a number of minutes"
  591.         dtext "","after the psion is switched off?"
  592.         dtext ""," "
  593.         dchoice pwmode%,"Password mode","after switch off,Regular intervals"
  594.         ret% = dialog
  595.     endif
  596.     if ret%
  597.       if pwmode%=1
  598.             deltatm&=deltatm& / 60
  599.             dinit p$
  600.             dtext "","How many minutes after the psion is"
  601.             dtext "","switched off before password is "
  602.             dtext "","re-enabled ?"
  603.             dtext ""," "
  604.             dlong deltatm&,"minutes",1,1440
  605.           ret% = dialog
  606.             deltatm&=deltatm& * 60
  607.             dstate$="W"
  608.        else
  609.             deltatm& = 0
  610.             dstate$=""
  611.       endif
  612.     endif
  613.  
  614. rem xxrem xx    if ret%
  615. rem xx        dINIT p$
  616. rem xx        dtext "","Display owner information when the"
  617. rem xx        dtext "","Psion is first switched on ?"
  618. rem xx        dtext "","(if the password is not active)"
  619. rem xx        dtext ""," "
  620. rem xx        dchoice owninf%,"Show Owner Information","no,yes"
  621. rem xx      ret%=dialog
  622. rem xx  endif
  623.  
  624.     if ret%
  625.         dinit p$
  626.         dtext "","Do you want alarms enabled at "
  627.         dtext "","regular intervals?"
  628.         dtext ""," "
  629.         dchoice alarm%,"Switch on alarms","no,yes"
  630.         ret% = dialog
  631.     endif
  632.     if ret%
  633.         dinit p$
  634.         dtext "","Do you want the link disabled"
  635.         dtext "","at regular intervals?"
  636.         dtext ""," "
  637.         dchoice linkoff%,"Switch off Remote Link","no,yes"
  638.         ret% = dialog
  639.     endif
  640.     if ret%<>0 and ( pwmode%=2 or linkoff%=2 or alarm%=2)
  641.         intrvl&=intrvl&/unit%
  642.         if alarm% = 2
  643.             dinit "Regular intervals"
  644.         else
  645.             dinit "Regular intervals for alarm/link only"
  646.         endif
  647.         dtime nexttim&,"start time ",0,0,86399
  648.         dlong intrvl&,"interval (hrs)",1,24
  649.         ret% = dialog
  650.         intrvl&=intrvl&*unit%
  651.     endif
  652.  
  653.  
  654.     if ret%
  655.         if intrvl& > 0
  656.             if nexttim& = 0
  657.                 nexttim& = nexttim& + 86400
  658.             endif
  659.             nexttim&=nexttim&+datetosecs(year,month,day,0,0,0)
  660.         endif
  661.         pason:(0,passwd$)
  662.     endif
  663.     foregrnd:(0)
  664.     RETURN ret%
  665. ENDP
  666.  
  667. REM -- the time now in seconds
  668. PROC now&:
  669.     RETURN(DATETOSECS(YEAR,MONTH,DAY,HOUR,MINUTE,SECOND))
  670. ENDP
  671.  
  672. REM -- write a timed log message
  673. PROC log:(mess$)
  674.     local lg%,l$(255),l%,f$(255),e%
  675.     f$="\opd\pasout.txt"
  676.     if exist(f$) and mess$="INIT"
  677.         delete f$
  678.         return
  679.     endif
  680.     l$=right$(datim$,8)+" "+mess$
  681.     if debug%
  682.         rem ioopen(lg%,f$,$0021-2*exist(f$))
  683.         if exist(f$)
  684.             e%=ioopen(lg%,f$,$0123)
  685.         else
  686.         e%=ioopen(lg%,f$,$0121)
  687.         endif
  688.         if e% : raise e% : endif
  689.         l%=addr(l$)
  690.         e%=iowrite(lg%,uadd(l%,1),peekb(l%))
  691.         if e% : raise e% : endif
  692.         e%=ioclose(lg%)
  693.         if e% : raise e% : endif
  694.     endif
  695. ENDP
  696.  
  697. rem All sound off/on -> bit 15 set/unset
  698. rem alarm sounds on/off bit 2
  699. rem keys on/off     -> bit 0
  700. rem keys loud quite -> bit 3    rem beep on/off     -> bit 1
  701. rem beep loud/quite -> bit 4
  702.  
  703. proc soundoff:
  704.      call($108b,call($0f8b) or $8000)
  705. endp
  706.  
  707. proc soundon%:(flag%)
  708.     call($108b,(call($0f8b) and $7fff) or flag%)
  709. endp
  710.  
  711. REM Change the system password from old$ to pwd$
  712. proc setpwd%:(old$,pwd$)
  713.     local reg%(6),o$(10),pw$(10)
  714.  
  715.     pw$ = crypt$:("D",pwd$)
  716.  
  717.     if old$="CHK"
  718.         reg%(1) = $2F00
  719.         reg%(5) = addr(pw$)
  720.     else
  721.         o$ = crypt$:("D",old$)
  722.         reg%(1) = $2E00
  723.         reg%(5) = addr(o$)
  724.         reg%(6) = addr(pw$)
  725.     endif
  726.     return ( os($8B,addr(reg%(1))) and 1 ) = 0
  727. endp
  728.  
  729.  
  730. proc ownstr$:(buf%,lenp%)
  731.     local tmp$(255),len%,from%
  732.     
  733.     len% = peekb(uadd(buf%,lenp%))
  734.     from% = buf% + peekb(uadd(buf%,lenp%+1))
  735.     pokeb addr(tmp$),len%
  736.     call($A1,0,len%,0,from%,uadd(addr(tmp$),1))
  737.     return tmp$
  738. endp
  739.  
  740. rem switch off remote link.
  741. proc linkoff:
  742.     local name$(14),pattern$(20),pid%,name%,opid%
  743.     
  744.     name% = addr(name$)
  745.     pattern$ = "LINK.*"+chr$(0)
  746.     pid%=0
  747.     REM loop and kill all processes called "LINK.*"
  748.     do
  749.         buf%(1) = $0B00
  750.         buf%(2) = pid%
  751.         buf%(5) = uadd(name%,1)
  752.         buf%(6) = uadd(addr(pattern$),1)
  753.         if os($88,addr(buf%())) and 1
  754.             break
  755.         endif
  756.         rem Terminate the process
  757.         call($0D88,buf%(1))
  758.     until pid% = opid%
  759. endp
  760.  
  761. proc foregrnd:(i%)
  762.     rem Send Pason to the foreground/background
  763.     log:("foreground "+num$(i%,2))
  764.     call($198D,100*(i%+1),0)
  765.     gupdate
  766. endp
  767.  
  768. REM Capture/Release a PSION-CONTROL-<key> keycode
  769. proc keycap:(on%,code%,mod%)
  770.     buf%(1)=14+(on%<>0)
  771.     buf%(2)=code%
  772.     buf%(3)=mod%*$101
  773.     iow(-2,7,buf%(1),buf%(2))
  774. endp
  775.  
  776. rem xproc beep%:(x%,y%)
  777. rem x    if debug% : beep x%,y% : endif
  778. rem xendp
  779.  
  780. rem word 0 = io channel
  781. rem word 2 = status
  782. rem long 4 = due time
  783. rem byte 8 = true if pason thinks alarm still on
  784. rem            this is diff. to async status.
  785.  
  786. proc alarmi:(i%)
  787.     pokel uadd(i%,4),0
  788.     pokeb uadd(i%,8),0
  789. endp
  790.  
  791. rem True if it has alarmed
  792. rem test only succeeds once to prevent event loop
  793. rem getting confused.
  794. proc alarmed%:(tptr%)
  795.     local ptr%
  796.     ptr% = uadd(tptr%,2)
  797.     if peekw(ptr%) <> -46 and peekb(uadd(ptr%,6))=1
  798.         pokeb uadd(ptr%,6),0
  799.         return 1
  800.     else
  801.         return 0
  802.     endif
  803. endp
  804.  
  805. rem alarm in secs% seconds
  806. proc alarm&:(tptr%,secs&)
  807.     local timsptr%,abstime&
  808.     local yr%,mo%,dy%,hr%,mn%,sc%,yd%
  809.     
  810.     if secs&<0
  811.         abstime& = 0
  812.     elseif secs&<>0
  813.         abstime&=secs&+now&:
  814.     endif
  815.     timsptr% = uadd(tptr%,2)
  816.  
  817.     if peekw(tptr%) = 0 
  818.         REM Open channel timer
  819.         log:("opening timer "+hex$(tptr%))
  820.         ioopen(#tptr%,"TIM:",0)
  821.     endif
  822.  
  823.     if peekw(timsptr%) = -46
  824.         REM stop current timer
  825.         log:("cancelling timer "+hex$(tptr%)) 
  826.         yr%=iow(peekw(tptr%),4,#0,#0)
  827.         if yr% : log:(err$(yr%)) : endif
  828.         
  829.         rem wait for the timer to complete. A signal
  830.         rem is still sent
  831.         iowait
  832.         while peekw(timsptr%) = -46
  833.             log:("event while waiting for cancel")
  834.             ioyield
  835.         endwh
  836.     elseif peekb(uadd(tptr%,6)) = 1
  837.         rem The timer has expired but the signal
  838.         rem has not been processed yet!
  839.         rem This was the big bug - it was a race
  840.         rem condition!
  841.         log:("Discarding timer"+hex$(tptr%))
  842.         iowait
  843.     endif
  844.  
  845.     alarmi:(tptr%)
  846.  
  847.     if abstime&<>0
  848.         REM start new timer
  849.         ioc(peekw(tptr%),2,#timsptr%,abstime&,abstime&)
  850.         pokel uadd(tptr%,4),abstime&
  851.         pokeb uadd(tptr%,8),1
  852.         ioyield
  853.         secstodate abstime&,yr%,mo%,dy%,hr%,mn%,sc%,yd%
  854.         log:("timer "+hex$(tptr%)+" at "+num$(hr%,2)+":"+num$(mn%,2)+":"+num$(sc%,2)+" in "+num$(abstime&-now&:,6)+" secs")
  855.     endif
  856.     return abstime&
  857. endp
  858.  
  859.