OpenVMS Source Code Demos
ADVOCATE_SERVER_103.BAS
1000 %TITLE "Advocate_server_xxx"
%IDENT "Version_103.1"
declare string constant k_version = "103.1"
!=========================================================================================================================
!1 2 3 4 5 6 7 8 9 0 1 2 3
!0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
!=========================================================================================================================
! Title : Advocate_server_xxx
! Author : Neil S. Rieck
! Purpose: Receives DCL commands from people with no privs and executes them on their behalf
!=========================================================================================================================
! History:
!
! Ver Who When What
! --- --- ------ -------------------------------------------------------------------------------------------------------
! 100 NSR 010307 1. derived from alarm_server_126.bas (written many years ago)
! 2. many changes and additions
! 101 NSR 010308 1. started adding two-way support
! 2. added a third mailbox (lck) which is only used to control client access to the tool
! 102 NSR 030807 1. started STARLET renovation
! 2. program renovation
! 103 NSR 070813 1. inlined a few functions for release to public domain
!=========================================================================================================================
! Overview:
!
! +--------+ +---------+ +--------+
! | client +-----+ MBX:lck | | server |
! | | +---------+ | |
! | | +---------+ | |
! | +---->+ MBX:cmd +---->+--->+ |
! | | +---------+ | | |
! | | +---------+ | | |
! | +<----+ MBX:rsp +<----+<---+ |
! +--------+ +---------+ +--------+
!
!=========================================================================================================================
OPTION type = explicit ! cuz tricks are for kids
!
%include "starlet" %from %library "sys$library:basic$starlet" ! system services
%include "$ssdef" %from %library "sys$library:basic$starlet" ! ss$
%include "$iodef" %from %library "sys$library:basic$starlet" ! io$
%include "lib$routines" %from %library "sys$library:basic$starlet" ! lib$
%include "$libdef" %from %library "sys$library:basic$starlet" ! eg. lib$_normal
%include "$clidef" %from %library "sys$library:basic$starlet" ! cli$
!
external long ast_service_routine ! my AST service routine
declare string constant k_program = "Advocate_server"
declare string constant advocate_out$ = "csmis$tmp:advocate_outfile.txt"
!
%if %declared ( %basic$quadword_declared ) = 0 %then
record basic$quadword
long fill ( 2 )
end record
%let %basic$quadword_declared = 1
%end %if
!
! /// I/O Status Block ///
!
%if %declared (%IOSBREC) = 0 %then
record IosbRec ! structure of I/O Status Block
variant
case
group one
word rc ! return code
word xfer_count ! transfer count
long long_0 ! device specific info
end group one
case
group two
basic$quadword quad_0 ! unsigned quad word (system calls)
end group two
end variant
end record IosbRec
%let %IOSBREC = 1
%end %if
!+
!========================================
! Internal Declarations
!========================================
!-
external string function WCSM_DT_Stamp ! home brewed code
external string function WCSM_TrnLnm( string, string)
!
declare long rc% , ! Return Code (system status) &
csa% , ! completion status address &
junk% , ! &
flags% ,! ! &
count% , ! &
response_sent% , ! &
word funct% , ! &
string junk$ , ! &
temp$ , ! &
temp2$
!+
!========================================
! Misc Declarations
!========================================
!-
map(xyz)string dcl_command_line = 255%
!
! the next constant and map must be identical with the one in the AST
!
declare long constant k_ring_size = 60%
map(qio)IosbRec qio_sb_recv , ! &
qio_sb_xmit , ! &
string qio_buffer_recv = 255% , ! &
qio_buffer_xmit = 255% , ! &
line$(k_ring_size) = 255% , ! ring buffer &
word chan_recv% , ! &
chan_xmit% , ! &
chan_l% , ! &
long line_insert% , ! insert pointer (subscript) &
line_remove% , ! remove pointer (subscript) &
qio_rc% , ! &
logging_flag% , ! &
logging_flag_old% !
!+
!========================================
! Main
!========================================
!-
2000 on error goto trap
margin #0, 132%
print k_program +"_"+ k_version
print string$(len(k_program +"_"+ k_version), asc("=")) ! underline previous line
!
declare string constant mbx_name_lck = "CSMIS$ADVOCATE_LCK"
declare string constant mbx_name_cmd = "CSMIS$ADVOCATE_CMD"
declare string constant mbx_name_rsp = "CSMIS$ADVOCATE_RSP"
!
! create the permanent mailbox (if it already exists, a new one won't be created but a channel will be opened to it)
!
print "-i-Creating MailBox: ";mbx_name_cmd
rc% = sys$CreMbx( 1% by value ! mbx=permanent &
,chan_recv%,,,, ! VMS will assign the channel number &
,mbx_name_cmd, ! mbx name &
) !
print "-e-sys$CreMbx-rc: ";rc% if (rc% and 7%) <> 1
print "-i-chan-r: ";str$(chan_recv%)
!
print "-i-Creating MailBox: ";mbx_name_rsp
rc% = sys$CreMbx( 1% by value ! mbx=permanent &
,chan_xmit%,,,, ! VMS will assign the channel number &
,mbx_name_rsp, ! mbx name &
) !
print "-i-sys$CreMbx-rc: ";rc% if (rc% and 7%) <> 1
print "-i-chan-x: ";str$(chan_xmit%)
!
print "-i-Creating MailBox: ";mbx_name_lck
rc% = sys$CreMbx( 1% by value ! mbx=permanent &
,chan_l%,,,, ! VMS will assign the channel number &
,mbx_name_lck, ! mbx name &
) !
print "-i-sys$CreMbx-rc: ";rc% if (rc% and 7%) <> 1
print "-i-chan-l: ";str$(chan_l%)
rc% = sys$dassgn( chan_l% by value ) ! now release this mail box
print "-i-sys$dassgn-rc: ";rc%
!
! purge mbx-read
!
print "-i-purge-mbx-r"
qio_sb_recv::rc = ss$_normal
while qio_sb_recv::rc = ss$_normal
map (QioPurge) string qio_purge$=80
qio_rc% = sys$qiow( &
,chan_recv% by value &
,(io$_readvblk or io$m_now) by value &
,qio_sb_recv::quad_0 by ref &
,, &
,qio_purge$ by ref &
,len( qio_purge$ ) by value &
,,,, )
print "-e- $Qio-rc(1): ";qio_rc% if (qio_rc% and 7%) <> 1
!
select qio_sb_recv::rc
case ss$_normal
print "Discarded-r = ";left$(qio_purge$, qio_sb_recv::xfer_count )
case ss$_EndOfFile
case else
print "-e-qiow-r-rc = ";qio_sb_recv::rc
end select
next
!
! purge mbx-write (xmit)
!
print "-i-purge-mbx-x"
qio_sb_xmit::rc = ss$_normal
while qio_sb_xmit::rc = ss$_normal
qio_rc% = sys$qiow( ,chan_xmit% by value &
,(io$_readvblk or io$m_now) by value &
,qio_sb_xmit::quad_0 by ref &
,, &
,qio_purge$ by ref &
,len( qio_purge$ ) by value &
,,,, )
print "-e- $Qio-rc(2): ";rc% if (rc% and 7%) <> 1
!
select qio_sb_xmit::rc
case ss$_normal
print "Discarded-x = ";left$(qio_purge$, qio_sb_xmit::xfer_count )
case ss$_EndOfFile
case else
print "-e-qiow-x-rc = ";qio_sb_xmit::rc
end select
next
!
! now raise the priority (so 'ast_service_routine' will work like an interrupt service routine)
!
! Note: consider controlling priority from batch job that starts the program
!
!~~~ print "Raising Priority to 9"
!~~~ rc% = sys$SetPri( ,,9%,)
!~~~ print "-e- rc: ";rc% if (rc% and 7%) <> 1
!
! do the first qio READ to start things off
!
! SYS$QIO [efn] ,chan ,func ,[iosb] ,[astadr] ,[astprm] ,[p1] ,[p2] ,[p3] ,[p4] ,[p5] ,[p6]
!
print "-i-Starting 1st qio"
qio_rc% = sys$Qio( ! event flag &
,chan_recv% by value ! channel &
,io$_readvblk by value ! function &
,qio_sb_recv::quad_0 by ref ! i/o status &
,ast_service_routine by ref ! ast address &
, ! ast parameter &
,qio_buffer_recv by ref ! p1 buf address &
,len( qio_buffer_recv ) by value ! p2 buf length &
,,,, )
print "-e- $Qio-rc(3): ";qio_rc% if (qio_rc% and 7%) <> 1
!
! /// do this forever ///
!
logging_flag_old% = -1%
while 1%=1%
!
! support logging verbage level
!
select edit$( WCSM_TrnLnm( "CSMIS$ADVOCATE_SERVER_VERBAGE", "LNM$SYSTEM_TABLE" ), 2%)
case "2"
logging_flag% = 2%
case "YES", "1"
logging_flag% = 1%
case else
logging_flag% = 0%
end select
!
if logging_flag% <> logging_flag_old% then
logging_flag_old% = logging_flag%
print "-i-Verbage level now at: ";str$(logging_flag%)
end if
!
while line_insert% <> line_remove% ! if we have work to do
if line_insert% <> line_remove% then !
!
! extract the data from the ring buffer
! (and place it into my alarm buffer)
!
dcl_command_line = edit$( line$( line_remove% ), 128%+4% )
!
! advance the remove pointer NOW
!
select line_remove%
case < k_ring_size
line_remove% = line_remove% + 1%
case else
line_remove% = 0%
end select
!
! process the extracted string
!
junk$ = edit$(dcl_command_line,128%+32%) ! no trailing + upcase
junk% = 0% ! default to reject
junk% = 1% if pos(junk$,"SHOW TIME" ,1%)=1%
junk% = 1% if pos(junk$,"SHOW QUEUE" ,1%)=1%
junk% = 1% if pos(junk$,"START/QUEUE" ,1%)=1%
junk% = 1% if pos(junk$,"STOP/QUEUE" ,1%)=1%
junk% = 1% if pos(junk$,"INITIALIZE/QUEUE" ,1%)=1%
junk% = 1% if pos(junk$,"DELETE/QUEUE" ,1%)=1%
junk% = 1% if pos(junk$,"PRINT/QUEUE" ,1%)=1%
!
if junk% = 0% then !
temp$ = "-e- dcl cmd rejected>"+junk$+"<"
print temp$
gosub send_response if junk$ <> ""
else
print "-i- dcl cmd>";junk$;"<"
!
! LIB$SPAWN [command-string] [,input-file] [,output-file] [,flags] [,process-name]
! [,process-id] [,completion-status-address] [,byte-integer-event-flag-num] [,AST-address]
! [,varying-AST-argument] [,prompt-string] [,cli] [,table]
!
! flags: CLI$M_NOWAIT, CLI$M_NOCLISYM, CLI$M_NOLOGNAM, CLI$M_NOKEYPAD, CLI$M_NOTIFY,
! CLI$M_NOCONTROL, CLI$M_TRUSTED, CLI$M_AUTHPRIV, and CLI$M_SUBSYSTEM.
!
flags% = CLI$M_NOCLISYM or CLI$M_NOLOGNAM or CLI$M_TRUSTED ! just fooling around
rc% = lib$spawn(junk$,,advocate_out$,flags%,,,csa%,,,,,,)
print "-i- lib$spawn:"
print " rc : "+ str$(rc%) +" -"+ mid$("wseif???",(rc% and 7%)+1%, 1%) +"-" ! return code
print " csa: "+ str$(csa%) ! completion status address
!
! this section of code is just exploring some future possibilities
!
response_sent% = 0%
when error in
!
! open the response file
!
open advocate_out$ for input as #1 &
,organization sequential &
,recordtype any
count% = 0%
!
! copy the ressponse file to the server's ".out" file
!
while 1
linput #1, temp2$ ! read a line
temp2$ = edit$(temp2$, 128) ! no trailing white space
count% = count% + 1% !
print "-i- resp-0 ";format$(count%,"###");">";temp2$;"<"
while len(temp2$)>0% !
temp$ = left$(temp2$,70%) ! slice-n-dice long lines
if len(temp$)>0 then !
gosub send_response ! send temp$
response_sent% = response_sent% + 1% !
print "-i- resp-1 ";format$(response_sent%,"###");">";temp2$
end if
junk$ = right$(temp2$,71%) ! scoop up the rest
junk$ = edit$(junk$,8) ! drop any leading white space
if len(junk$)>0 then ! if we've got something...
temp2$ = " "+ junk$ ! ...then prefix with 2 spaces (continuation)
else
temp2$ = "" ! else show us empty
end if
next
next
use
print "-e-err: ";str$(err);" while processing advocate_out$" if err<>11%
end when
print "=========="
close #1
!
when error in
while 1
kill advocate_out$ ! now delete all response files
next
use
end when
if response_sent% = 0% then ! cuz not all DCL commands have a response
temp$ = "Done"
gosub send_response
end if
end if
!
end if
!
next
!
call sys$hiber ! sleep until we receive another message
!
next
!----------------------------------------------------------------------------------------------------
! send response back to connected process
!----------------------------------------------------------------------------------------------------
send_response:
print "-i- Starting qio write"
temp$ = temp$ + cr ! cuz every line needs an EOL
qio_buffer_xmit = temp$
funct% = io$_writevblk or io$m_now or io$m_norswait
qio_rc% = sys$Qio( ! event flag &
,chan_xmit% by value ! channel &
,funct% by value ! function &
,qio_sb_xmit::quad_0 by ref ! i/o status &
, ! ast address &
, ! ast parameter &
,qio_buffer_xmit by ref ! p1 buf address &
,len( temp$ ) by value ! p2 buf length &
,,,, )
print "-e- $Qio-rc(4): ";qio_rc% if (qio_rc% and 7%) <> 1
return
!
!========================================
! Trap (BASIC error handler)
!
! this will go to sys$output (sys$error)
!========================================
20000 trap:
print cr + lf + "Line = "+ str$(erl) + &
cr + lf + "Error= "+ str$(err) + &
cr + lf + "Text = "+ ert$(err)
resume fini ! fix stack + exit
!========================================
! adios
!========================================
Fini:
32000 END !
!
!########################################################################################################################
!
!===============================================================================================================
! <<< ast_service_routine >>>
!
! param%: user defined parameter
! gpr_0%: general purpose register 0
! gpr_1%: general purpose register 1
! pc% : program counter
! pcl% : program status long word
!
! Note : this routine works like an interrupt service routine so it should do as little processing as possible
!===============================================================================================================
32100 sub ast_service_routine by ref (LONG param%, gpr_0%, gpr_1%, pc%, psl%)
!
OPTION type = explicit ! cuz tricks are for kids
!
%include "starlet" %from %library "sys$library:basic$starlet" ! system services
%include "$ssdef" %from %library "sys$library:basic$starlet" ! ss$
%include "$iodef" %from %library "sys$library:basic$starlet" ! io$
%include "lib$routines" %from %library "sys$library:basic$starlet" ! lib$
%include "$libdef" %from %library "sys$library:basic$starlet" ! eg. lib$_normal
!
external long ast_service_routine ! my AST service routine
!
%if %declared ( %basic$quadword_declared ) = 0 %then
record basic$quadword
long fill ( 2 )
end record
%let %basic$quadword_declared = 1
%end %if
!
! /// I/O Status Block ///
!
%if %declared (%IOSBREC) = 0 %then
record IosbRec ! structure of I/O Status Block
variant
case
group one
word rc ! return code
word xfer_count ! transfer count
long long_0 ! device specific info
end group one
case
group two
basic$quadword quad_0 ! unsigned quad word (system calls)
end group two
end variant
end record IosbRec
%let %IOSBREC = 1
%end %if
!
! the next constant and map must be identical with the one in MAIN
!
declare long constant k_ring_size = 60%
map(qio)IosbRec qio_sb_recv , ! &
qio_sb_xmit , ! &
string qio_buffer_recv = 255% , ! &
qio_buffer_xmit = 255% , ! &
line$(k_ring_size) = 255% , ! ring buffer &
word chan_recv% , ! &
chan_xmit% , ! &
chan_l% , ! &
long line_insert% , ! insert pointer (subscript) &
line_remove% , ! remove pointer (subscript) &
qio_rc% , ! &
logging_flag% , ! &
logging_flag_old% !
!
!~~~ print "ast iosb_rc: " + str$( qio_sb_r::rc) + " iosb_bc: " + str$( qio_sb_recv::xfer_count )
!
! erase old mapped string
! then copy over received data
!
line$( line_insert% ) = "" ! zap old text
line$( line_insert% ) = left$( qio_buffer_recv, integer(qio_sb_recv::xfer_count) )
!
! Anomaly #3:
! There is a <cr> in the middle of this mapped string so remove it before printing (or the trailing blanks will
! overwrite your text and make it disappear)
!
!~~~ print "ast buf: "+ edit$( line$( line_insert% ), 128%+4%)
!
! move the insertion pointer (main will try to catch up by advancing the removal pointer)
!
select line_insert%
case < k_ring_size
line_insert% = line_insert% + 1%
case else
line_insert% = 0%
end select
!
! SYS$QIO [efn] ,chan ,func ,[iosb] ,[astadr] ,[astprm] ,[p1] ,[p2] ,[p3] ,[p4] ,[p5] ,[p6]
!
qio_rc% = sys$Qio( ! event flag &
,chan_recv% by value ! channel &
,io$_readvblk by value ! function &
,qio_sb_recv::quad_0 by ref ! i/o status &
,ast_service_routine by ref ! ast address &
, ! ast parameter &
,qio_buffer_recv by ref ! p1 buf address &
,len( qio_buffer_recv ) by value ! p2 buf length &
,,,, )
print "-e- $Qio-rc(5): ";qio_rc% if (qio_rc% and 7%) <> 1
!
! BASIC Anomaly #1.b (above)
! ------------------
! The QIO system call expects to pass the address of the AST service routine my value which is not the same as by REF
!
! the upper half of this program may be hybernating so wake it up
!
call sys$wake(,) ! wake up main
!
subend ! that's all
!
32200 function string WCSM_TrnLnm ( string logical_name$, table_name$ )
!========================================================================================================================
! Title : wcsm_trnlnm.fun
! Author : Neil S. Rieck
! Purpose: an external function to translate logical names
! Notes : 1. all our programs call this function so optimizations here will speed up the whole system
! : 2. use LIB$TRNLNM if speed isn't important
! History:
! 100 NSR 910911 1. original work
! NSR 940420 2. changed mapsize from 31 to 255
! NSR 000208 3. modified for use with 'starlet'
! NSR 021019 4. optimizations
! NSR 040516 5. now only do SUPERVISOR mode translations bf_100.5
! NSR 040519 6. returned this program to its previous functionality
!========================================================================================================================
! Notes :
!
! 1. please include the next line near the top of your source program (after 'option type=explicit')
!
! external string function WCSM_TrnLnm (string, string)
!
! 2. please include the next 2 lines near the bottom of of your source program (after 'END' of the main module)
!
! %include "[.fun]wcsm_trnlnm.fun"
!! ! function string WCSM_TrnLnm ( logical_name$, table_name$ )
!
!========================================================================================================================
option type=explicit ! cuz tricks are for kids...
!
!~~~ %include "[.inc]vms_externals.inc" x calls many modules from starlet
%include "starlet" %from %library "sys$library:basic$starlet" ! system services
%include "$ssdef" %from %library "sys$library:basic$starlet" ! ss$
%include "$lnmdef" %from %library "sys$library:basic$starlet" ! lnm$
%include "$psldef" %from %library "sys$library:basic$starlet" ! psl$
%include "[.inc]vms_structures.inc" ! IosbRec etc.
!
declare long constant MapSize% = 255
!
! <<< declare variables >>>
!
map(WCSM_TrnLnm)string Equiv_Name$ = MapSize%
declare long sys_status , ! for return codes &
bytes_returned% , ! for system calls &
my_attributes% , ! '' &
string temp$ , ! &
byte access_mode% !
!
declare ItemRec LogLst(2) ! 3 items (0-2)
!
!==================================================
! clean up data (before table fill)
!==================================================
!
logical_name$ = edit$(logical_name$, 32+4+2)
table_name$ = edit$(table_name$, 32+4+2)
!~~~ access_mode% = PSL$C_SUPER x bf_100.5
!
!==================================================
! prep for call (fill in table)
!==================================================
!
my_attributes% = LNM$M_TERMINAL
!
LogLst(0%)::BuffLen = 4% ! 4 bytes=long
LogLst(0%)::ItemCode = lnm$_Attributes ! desired code
LogLst(0%)::BuffAddr = loc(my_attributes%) !
LogLst(0%)::RtnLenAdr = 0% ! don't care
!
LogLst(1%)::BuffLen = MapSize% ! from map statement
LogLst(1%)::ItemCode = lnm$_String ! desired code
LogLst(1%)::BuffAddr = loc(Equiv_Name$) ! address of string variable
LogLst(1%)::RtnLenAdr = loc(Bytes_Returned%) ! address of length variable
!
LogLst(2%)::List_Terminator = 0% ! end of list
!
! this is it folks, the big Kahoona...
!
sys_status = sys$trnlnm( , ! attributes &
table_name$ , ! &
logical_name$ , ! &
, ! bf_105.6 &
LogLst() ) !
!
select sys_status
case ss$_nolognam
temp$ = "" ! make sure this is clear
case ss$_normal
temp$ = left$(Equiv_Name$, bytes_returned%)
case else ! paranoia, should never happen
temp$ = "-e-SYSERR_" + str$(sys_status) !
print temp$ + bel + " In 'WCSM_TrnLnm'" !
sleep 2% !
end select
!
! copy data back to function and return to caller
!
WCSM_TrnLnm = temp$
!
end function
!
32300 function string Wcsm_DT_Stamp
!===================================================================================================================
! Title : Wcsm_DT_Stamp_100?.inc
! Author : Neil S. Rieck
! Purpose: an external function to return a y2k compliant system time in the form ccyymmddhhmmss (14 chars)
! Notes : all our programs call this function so optimizations here will speed up the whole system
! History:
! 100a NSR 911229 1. original work
! NSR 940423 2. changed 'ON ERROR' to 'WHEN ERROR'
! 100b NSR 961108 1. cleaned up
! 100c NSR 961108 1. optimized
! 100d NSR ?????? 1. optimized
! 100e NSR 980618 1. optimized
! 2. added XX to month names so adding a skew wouldn't be necessary
! 3. replaced left hand mid$ with tens mapping
! 100f NSR 980619 1. optimized
! 2. added some code so I could remove the call to RSET (this may increase the size of both $PDATA
! and $CODE but might reduce execution time by avoiding one call to the BASIC RTL. Only
! benchmarking will determine wether this change is better or worse)
!===================================================================================================================
! Usage:
!
! 1. please include the next line near the top of your source
! program (after 'option type=explicit' )
!
! external string function Wcsm_DT_Stamp (string, long)
!
! 2. please include the next 2 lines near the bottom of of your
! source program (after 'END' of the main module)
!
! %include "[.fun]wcsm_dt_stamp.fun"
!! ! function string Wcsm_DT_Stamp
!===================================================================================================================
option type=explicit ! cuz tricks are for kids...
!
external long function sys$asctim
!
declare long sys_status
!
! this map is required for the call to sys$asctim (format: 19-JUN-1998 23:59:59.1)
!
map (WcsmDTStamp0) string Sys_buf_22 = 22
map (WcsmDTStamp0) string Sys_day = 2, ! &
Sys_dash1 = 1, !- &
Sys_month = 3, ! &
Sys_dash2 = 1, !- &
Sys_year = 4, ! &
Sys_space = 1, ! &
Sys_Hour = 2, ! &
Sys_colon1 = 1, !: &
Sys_Minute = 2, ! &
Sys_colon2 = 1, !: &
Sys_Second = 2, ! &
Sys_period = 1, !. &
Sys_Tenth = 1 !
!
! map for Wcsm date (output)
!
map (WcsmDTStamp1) string Wcsm_buf_14 = 14 !
map (WcsmDTStamp1) string Wcsm_year = 4, ! &
Wcsm_month = 2, ! &
Wcsm_day = 2, ! &
Wcsm_Hour = 2, ! &
Wcsm_Minute = 2, ! &
Wcsm_Second = 2
map (WcsmDTStamp1) string Wcsm_year = 4, ! &
Wcsm_month_tens = 1, ! &
Wcsm_month_ones = 1, ! &
Wcsm_day_tens = 1, ! &
Wcsm_day_ones = 1, ! &
Wcsm_Hour = 2, ! &
Wcsm_Minute = 2, ! &
Wcsm_Second = 2
!
! string constants
! 00000000011111111112222222222333333333
! 12345678901234567890123456789012345678
declare string constant k_month_names$ = "XXJANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"
! ||
! ++-- so I don't have to provide an offset in pos()
declare string constant my_space = '32'C
!
! <<< function 'code' starts here >>>
!
when error in
!
sys_status = sys$asctim(,Sys_buf_22,,) ! get ASCII time into sys_buf_22
!~~~ if (sys_status and 7%) <> 1% then cause error 11 x not required - call will never fail
!
! transfer data from one map to the other
!
Wcsm_year = Sys_year !
!~~~ rset Wcsm_month = str$( pos(k_month_names$,Sys_Month,1%) / 3%) x bf_100f
Wcsm_day = Sys_day !
Wcsm_hour = Sys_hour !
Wcsm_minute = Sys_minute !
Wcsm_second = Sys_second !
!
declare long temp% ! bf_100f
temp% = pos(k_month_names$,Sys_Month,1%) / 3% ! compute month number bf_100f
if temp% < 10% then ! if less than 10... bf_100f
Wcsm_month_ones = str$(temp%) ! ...then this goes into ONES bf_100f
Wcsm_month_tens = "0" ! ...and this goes into TENS bf_100f
else ! else >= 10 bf_100f
Wcsm_month = str$(temp%) ! bf_100f
end if
!
! make sure there are no spaces in the TENS area of our mapped variables (pad with '0' if necessary)
!
!~~~ Wcsm_month_tens = "0" if Wcsm_month_tens = my_space x disabled - see above code bf_100f
Wcsm_day_tens = "0" if Wcsm_day_tens = my_space !
!
! now pass result back to caller
!
Wcsm_DT_Stamp = Wcsm_Buf_14 ! this is it folks
use
Wcsm_DT_Stamp = "" ! error so return blank
end when
!
END Function
!========================================================================================================================
Back to
Home
Neil Rieck
Waterloo, Ontario, Canada.