| $set verify
$! COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1986
$!
$! This tool is for Digital internal use ONLY.
$!-----------------------------------------------------------------------------
$ goto end_of_header_comments
$!-----------------------------------------------------------------------------
$!
$! Purpose: Mail user new notes and replies from a batch job.
$! This frees up the user to do other work instead of
$! waiting for the slow network. The user may then
$! read the notes at her leisure in MAIL. Also, a
$! "directory" of the extracted notes is prepended to
$! the beginning of the output to aid the user in
$! quickly determining if there are any notes worth
$! reading.
$!
$! Suggested invocation:
$!
$! $ submit this-procedure
$!
$! Also, the use of the CURRENT/EDIT command within MAIL
$! is recommended for reading/scanning the extracted notes.
$!
$! Advanced features:
$!
$! All advanced features are specified with:
$!
$! $ submit this-procedure /param = -
$! "/feature=<value> /feature=<value>"
$!
$! The quotes and slashes are required. Switch names may
$! be abbreviated to as few as four characters. Some
$! switches allow the value to be defaulted. Flag switches
$! which are specified without a value default to "yes".
$! When specifying a value, the equal sign is required, as
$! is the value. The angle brackets are required for values
$! that must be taken literally.
$!
$! When submitted without any optional feature switches, all new
$! notes for all conferences in all your classes in your default
$! notebook are mailed to you.
$!
$! The available features (illustrated with pseudo-examples) are:
$!
$! $ submit this-procedure /param = "/again_at=<tomorrow+3:0:0>"
$! !
$! ! Cause procedure to run every morning at 3 a.m.
$! ! Note that the exact same procedure will be resubmitted,
$! ! rather than the one with the highest version number.
$! ! To use a newer version of the procedure, delete the
$! ! current job from the queue and resubmit the new procedure
$! ! with the same parameters as the original job.
$!
$! $ submit this-procedure /param = "/not_now"
$! !
$! ! This is useful in conjunction with /again_at, in order
$! ! to not run now at all. The value can be "yes" or "no",
$! ! with "yes" the default (as shown in the example) if the
$! ! switch is specified without a value. "No" is the default
$! ! if the switch is absent.
$!
$! $ submit this-procedure /param = "/class=<contact sports>"
$! !
$! ! Extract notes only from class "contact sports". Only one
$! ! name is allowed, although you can submit multiple jobs.
$! ! This switch may be combined with /conference.
$!
$! $ submit this-procedure /param = "/conference=<askenet>"
$! ! Extract notes only from conference "askenet". Only one
$! ! name is allowed, although you can submit multiple jobs.
$! ! This switch may be combined with /class.
$!
$! $ submit this-procedure /param = "/entry=<askenet>"
$! ! Synonym for "/conference".
$!
$! $ submit this-procedure /param = "/verbose"
$! ! Produce detailed log file for error analysis or education.
$! ! The value can be "yes" or "no", with "yes" the default (as
$! ! shown in the example) if the switch is specified without a
$! ! value. "No" is the default if the switch is absent.
$!
$! $ submit this-procedure /param = "/mail_to=<node::username>"
$! ! Mail output from this procedure to the specified user(s)
$! ! rather than the user under whose account the procedure is
$! ! executing. This will also include error output, unless
$! ! this parameter has not yet been parsed. Note that no
$! ! attempt is made to recover from a bad mail address. For
$! ! this and other reasons, the use of a store-and-forward
$! ! mechanism (e.g., NMAIL) is suggested.
$!
$! $ submit this-procedure /param = "/name=<batch name>"
$! ! Only useful in conjunction with /AGAIN_AT, specifies
$! ! what job name the subsequent batch job should have.
$!
$! $ submit this-procedure /param = "/limit=200"
$! ! Specify the maximum number of unseen notes that this
$! ! procedure will allow to be extracted from a single
$! ! conference. If a conference has more than the specified
$! ! number of unseen notes, you will be notified and the
$! ! extraction will not be performed. If the switch or switch
$! ! value is not specified, the default is 1000. This switch
$! ! may be used to either increase or decrease the default.
$!
$! See variable "allowed_names" below for a listing of the allowed
$! switch names and the default values (if any) that they have when
$! the switch name is specified without a value being present.
$!
$!-----------------------------------------------------------------------------
$! Author, Eric Osman
$! Modified by: Dan Schullman, Eric Osman
$! Modification history:
$!
$! EO 08DEC86 Use SET SYMBOL instead of defining dictionary.
$! Allow /NAME=name, for subsequent batch job name (v 25)
$! DS 06NOV86 Add initials to non-author modifications in the history,
$! change some examples to use new switch syntax,
$! further clarify some switch usage,
$! allow default values if only a switch name is specified,
$! allow angle brackets to be omitted from switch value,
$! preserve alphabetic case of original switches,
$! increase minimum switch length from three to four,
$! add /LIMIT qualifier and remove /NOLIMIT_FLAG,
$! add switch information to extraction information,
$! and move extraction information after new notes. (v 24)
$! DS 04NOV86 Change author's node address from RAYNAL to VIDEO,
$! allow specification of alternate author for testing purposes,
$! add comment about version retention on /AGAIN_AT resubmissions,
$! "modularize" specification for "MAIL_VAXNOTES installed" file,
$! make qualifier-parsing algorithm more rigorous and flexible,
$! send mail for all (vs. some) switch-related errors,
$! change "exit 0" commands to use "exit %x10" so user is notified,
$! shorten algorithm for scanning entry info,
$! use string subtraction to check for substring presence,
$! add extraction date and time to directory listing,
$! shorten various mail messages through formatting changes,
$! and change formatting to hopefully improve readability. (v 23)
$! DS 31OCT86 Add DEC copyright notice, etc. "to be safe",
$! skip around header comments to reduce verified output,
$! add /MAIL_TO to specify recepient(s) for the output,
$! modularize determination of procedure spec and name,
$! remove commented-out code which had tested for VMS V4,
$! remove unused definition for ESCAPE character code,
$! prefix internal-use switches with "z_" and remove "/mail_log",
$! terminate procedure on unexpected qualifiers,
$! don't truncate qualifiers to three characters for validation,
$! change subject and text of bad-parameter mail message,
$! simplify "melting" of boolean values,
$! parameterize width of generated dictionary listing,
$! use continuation lines for SEARCH command to prevent overflow,
$! extract note numbers, titles, and authors differently,
$! prevent inclusion of title text in note number in directory,
$! reduce occurrence of embedded topics/replies in directory,
$! prevent topic title overflow in the directory,
$! trim trailing blanks from directory listing,
$! prefix notes with one rather than two form feeds,
$! include username and procedure info in output,
$! simplify determination of relative resubmission times,
$! and change some formatting of modified code. (v 22)
$! 14OCT86 Reset verification on exit. (v 21)
$! Add /NOLIMIT_FLAG to mail large entries (see 31MAR86)
$! 10SEP86 On unexpected output, mail the unexpected output. (v 20)
$! 03SEP86 If unexpected output, skip entry instead of dying. (v 19)
$! 15JUL86 Turn off verification to save disk space. Correctly handle
$! long entry names. (v 18)
$! DS 19JUN86 Reverse modification history so most recent first,
$! change qualifier checks to accept abbreviations,
$! add /ENTRY as synonym for /CONFERENCE,
$! and spell NOTES "directory" commands in full. (v 17)
$! 03JUN86 Use unique names so PURGE is o.k. (v 16)
$! 23MAY86 Do updates as we go, rather than all first. (v 15)
$! 12MAY86 Don't mail error on node note reachable (v 14)
$! 09MAY86 Minor directory improvement (more dashes) (v 13)
$! 09MAY86 Fix not_now_flag, delete .pre's on cleanup. (v 12)
$! 02MAY86 Improved directory indicating topics and titles (v 11)
$! 17APR86 Mail error NUMBERS and start list of disk-full
$! and over-quota ones so we don't mail out those (v 10)
$! 15APR86 Make switch internal names more obscure (v 9)
$! 08APR86 Allow /class=<class> and /conference=<name> (v 8)
$! 04APR86 Use /class=* on open to avoid opening wrong name (v 7)
$! 31MAR86 Don't mail entries having more than 1000 items
$! 24FEB86 Allow spaces in entry names
$! 11FEB86 Use /noautomatic to avoid losing one entry.
$! 10FEB86 Fix bug in resubmission.
$! 07FEB86 Allow /not_now_flag=<yes>, /again_at=<+time-from-now>,
$! /again_at=<specific-date>
$!-----------------------------------------------------------------------------
$end_of_header_comments:
$!
$ set = "set"
$ set symbol/scope=(noglobal,nolocal)
$ version = "25"
$!
$! Define needed symbols.
$!
$ tab = ""
$ tab[0,8] = 9
$ ff = ""
$ ff[0,8] = 12
$ default_limit = 1000
$!
$! Get file specification and displayable info for this procedure.
$!
$ procedure_spec = f$environment( "procedure" )
$ procedure_info = procedure_spec + " -- v" + version
$ if f$parse( procedure_spec,,,"node" ) .eqs. "" -
then procedure_info = f$trnlnm( "sys$node" ) + procedure_info
$!
$! Choose name for intermediate files such that they won't conflict
$! with another process. (First, we get hex pid with leading 0's
$! removed, with method due to GOLLY::GILBERT 7/25/85).
$!
$ pid = "XXX"+f$getjpi("","pid")-"X0000"-"X00"-"X0"-"XX"-"X"
$ q = "sys$scratch:mail_vaxnotes_''pid'"
$!
$! Determine user address and error address, and default mailing address.
$!
$ username = "''f$edit (f$getjpi ("","username"), "trim")'"
$ user_address = "''f$trnlnm ("sys$node")'" + username
$ mail_address = user_address !until /MAIL_TO has been parsed
$ author = f$trnlnm( "mail_vaxnotes_author" )
$ if author .eqs. "" then author = "VIDEO::OSMAN"
$ error_addresses = "&mail_address" !to defer eval of "mail_address"
$ if author .nes. user_address -
then error_addresses = error_addresses + ",''author'"
$!
$! Turn on error handling, now that minimal support has been set up.
$!
$ on warning then goto whoops
$!
$! Announce existence if newly installed.
$!
$ install_file = "sys$login:mail_vaxnotes.installed"
$ if f$search( install_file ) .nes. "" then goto already_installed
$ on warning then continue
$ mail nl: 'author' /subject = -
"MAIL_VAXNOTES version ''version' installed by ''user_address'"
$ on warning then goto whoops
$ create 'install_file'
This file indicates that you have installed the MAIL_VAXNOTES procedure.
Please leave the file in place.
$already_installed:
$!
$! The following is an alphabetical list of allowed switch names, plus the
$! default values for those switches that allow a default value when only
$! the switch name is specified. The default value field must begin with
$! a SPACE to differentiate it from a switch name.
$!
$ allowed_names = "" -
+ "/again_at" -
+ "/class" -
+ "/conference" -
+ "/entry" -
+ "/limit/ " + f$string( default_limit ) -
+ "/mail_to/" -
+ "/name" -
+ "/not_now_flag/ yes" -
+ "/verbose_flag/ yes" -
+ ""
$!
$! Pick up parameters.
$!
$ original_params = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8
$ params = f$edit( original_params, "lowercase" )
$param_lup:
$ param = f$element( 0, "/", params ) !should be spaces, if anything
$ if f$edit( param, "trim" ) .nes. "" then goto bp_leading_garbage
$ params = params - param !remove leading spaces
$ if params .eqs. "" then goto params_done
$ params_length = f$length( params )
$ equal_loc = 'f$locate( "=", params )'
$ slash_loc = 'f$locate( "/", f$extract( 1, 999, params ) )' + 1
$ param = f$extract( 0, slash_loc, params )
$ switch_value = ""
$ if equal_loc .ge. slash_loc then goto got_value
$ if param - "<" - ">" .nes. param then goto angle_brackets_present
$ switch_value = f$edit( f$extract( equal_loc + 1, 999, param ), "trim" )
$ if switch_value .eqs. "" then goto bp_null_value
$ goto got_value
$angle_brackets_present:
$ open_loc = 'f$locate( "<", params )' + 1
$ close_loc = 'f$locate( ">", params )'
$ param = f$extract( 0, close_loc + 1, params )
$ if equal_loc .ge. open_loc .or open_loc .gt. close_loc -
.or. close_loc .ge. params_length then goto bp_value_syntax
$ if open_loc .eq. close_loc then goto bp_null_value
$ switch_value = f$extract( open_loc, close_loc - open_loc, param )
$got_value:
$ if f$extract( 0, 1, param ) .nes. "/" then goto bp_no_slash
$ if f$extract( 1, 1, param ) .eqs. " " then goto bp_leading_space
$ switch_name = f$edit( f$extract( 1, equal_loc - 1, param ), "trim" )
$ remaining = param - "/" - switch_name - "=" - "<" - switch_value - ">"
$ if f$edit( remaining, "trim" ) .nes. "" then goto bp_value_syntax
$ params = params - param
$!
$! Check for abbreviated switch names, and "lengthen" variable name as
$! necessary to generate the full variable name. If switch name is not
$! allowed, it is rejected and the procedure terminated. Switch names
$! beginning with "z_" are assumed to be for internal use and are not
$! validated or lengthened.
$!
$! It is assumed that all allowed switch names will be unique when truncated
$! to their first four characters.
$!
$ if f$length( switch_name ) .lt. 4 then goto bp_short_name
$ variable_info = f$extract( -
f$locate( "/" + switch_name, allowed_names ), 999, allowed_names )
$ variable_name = f$element( 1, "/", variable_info ) - "/"
$ if f$extract( 0, 2, switch_name ) .eqs. "z_" -
then variable_name = switch_name !for internal-use parameters
$ if variable_name .eqs. "" then goto bp_invalid_name
$!
$! Supply a default switch value if necessary and possible.
$!
$ if switch_value .nes. "" then goto value_specified
$ value_info = f$element( 2, "/", variable_info )
$ if f$extract( 0, 1, value_info ) .nes. " " then goto bp_no_default
$ switch_value = f$extract( 1, 999, value_info )
$value_specified:
$!
$! Change /ENTRY references (which is the qualifier that NOTES uses)
$! to /CONFERENCE (which is what this procedure historically used).
$!
$ if variable_name .eqs. "entry" then variable_name = "conference"
$!
$! Use prefix to lessen chances that user already has a symbol whose
$! name is the switch, which would fool us into thinking switch
$! was given when it really wasn't.
$!
$ on warning then goto bp_whoops
$ mv_'variable_name' = "''switch_value'"
$ on warning then goto whoops
$ goto param_lup
$!
$! Come here to report a bad parameter, with variable "param" appropriately set.
$!
$bp_leading_garbage:
$ control = "character(s) ""!AS"" not allowed in front of slash"
$ goto bad_param
$bp_value_syntax:
$ control = "invalid value syntax in ""!AS"""
$ goto bad_param
$bp_null_value:
$ control = "missing value in ""!AS"""
$ goto bad_param
$bp_no_slash:
$ control = "the ""!AS"" switch does not start with a slash"
$ goto bad_param
$bp_leading_space:
$ control = "the slash in ""!AS"" must not be followed by a space"
$ goto bad_param
$bp_short_name:
$ control = "switch name ""!AS"" is not the minimum of four characters"
$ goto bad_param
$bp_invalid_name:
$ control = "unrecognized switch name ""!AS"""
$ goto bad_param
$bp_no_default:
$ control = "no default value exists for ""!AS"""
$ goto bad_param
$bp_whoops:
$ control = "bad value in ""!AS"""
$ goto bad_param
$!
$! Generate specific error message,
$! and be careful about embedded quotes in the resulting message.
$! Actually, quotes within the parameter should be quadrupled.
$!
$bad_param:
$ msg = f$fao( control, param )
$ quote = -2
$double_quotes:
$ quote = f$locate( """", f$extract( quote+2, 999, msg ) ) + quote + 2
$ msg = f$extract( 0, quote+1, msg ) + f$extract( quote, 999, msg )
$ if quote .lt. f$length( msg ) then goto double_quotes
$ mail sys$input 'mail_address' /subject = -
"ERROR: ''msg', detected by ''procedure_info'"
The general syntax of a switch is "/switch_name = <switch_value>". The quotes
and slash are required. Switch names may be abbreviated to four or more
characters, and must match the beginning of one of the allowed switches. Some
switches allow the value to be defaulted. When specifying a value, the equal
sign is required, as is the value itself. The angle brackets are required for
values that must be taken literally. The comments at the beginning of the
procedure describe the allowed switches more fully.
If you can't figure out what's wrong, try using "/LOG=file-spec/KEEP" when
you submit the procedure. Then, examine the log file after the error occurs.
If you get real frustrated, please ask whomever told you about the procedure.
$ exit %x10 !exit with "badparam" status value
$params_done:
$!
$! Turn off verification to keep the log file small, unless /VERBOSE specified.
$!
$ old_verify = f$verify( 1 .and. "''mv_verbose_flag'" )
$!
$! Do some post-processing of the various options.
$!
$ mv_not_now_flag = 1 .and. "''mv_not_now_flag'"
$ if f$type( mv_mail_to ) .nes. "" -
then mail_address = f$edit( mv_mail_to, "trim,compress,upcase" )
$ if f$type( mv_class ) .eqs. "" then mv_class = ""
$ if f$type( mv_conference ) .eqs. "" then mv_conference = ""
$ if f$type( mv_limit ) .eqs. "" then mv_limit = default_limit
$ if mv_class .eqs. "" then mv_class = "*"
$ if mv_conference .eqs. "" then mv_conference = "*"
$ if f$type (mv_name) .eqs. "" then mv_name = "MAIL_VAXNOTES"
$!
$! Set process name to whatever user specifed, or some default.
$!
$ set noon
$ set process/name=&mv_name
$ set on
$!
$ if "''mv_z_first_tag'" .nes. "" then goto 'mv_z_first_tag'
$!
$! Perhaps we're not supposed to run now at all.
$!
$ if mv_not_now_flag then goto finished
$!
$ if f$search ("''q'.entries") .nes. "" then delete 'q'.entries.*
$ close/error=nc1 nm$com
$nc1:
$ open/write nm$com 'q'.com
$ write nm$com "$ notes"
$ write nm$com -
"directory/entries ""''mv_conference'""/class=""''mv_class'"""
$ close nm$com
$ @'q'/out='q'.entries
$ delete 'q'.com.
$ if f$trnlnm ("nm$entries") .nes. "" then close nm$entries
$ open/error=no_entry_file nm$entries 'q'.entries
$find_first_entry:
$ read/end=no_entries nm$entries line
$ if line - "Entry Name" .eqs. line then goto find_first_entry
$ read/end=whoops nm$entries line
$check_next_entry:
$ read/end=whoops nm$entries line
$ if line - "End of" .nes. line then goto no_more_entries
$ entry = f$edit( f$extract( 1, 21, line ), "trim" )
$!
$! We now have a possibly-abbreviated entry name, and must determine the full
$! entry name because some commands require the full entry name.
$!
$! The full entry name is obtained by parsing the output from "show entry",
$! examples of which are below (with two spaces deleted to get the "$!" to fit).
$!
$!0 unseen notes Entry HOW_LONG_WILL_IT_ACTUALLY_ALLOW_ME_TO_MAKE_31 topic notes
$!0 unseen notes Entry NOT_QUITE_AS_LONG_AS_BEFORE 31 topic notes
$!252 unseen notes Entry ASKENET 479 topic notes
$!
$ entry_keyword = "Entry "
$ entry_keyword_length = f$length( entry_keyword )
$ topic_keyword = " topic note"
$ digits = "0123456789"
$ open/write nm$com 'q'2.com
$ write nm$com "$ notes"
$ write nm$com "set class ""''mv_class'"""
$ write nm$com "show entry ""''entry'"""
$ close nm$com
$ @'q'2/out='q'.entry
$ delete 'q'2.com.
$ open nm$com 'q'.entry
$find_name:
$ read/end=no_entry_info nm$com line
$ bpos = f$locate( entry_keyword, line ) + entry_keyword_length
$ epos = f$locate( topic_keyword, line )
$ if bpos .ge. epos .or. epos .ge. f$length( line ) then goto find_name
$ close nm$com
$ delete 'q'.entry.
$find_end:
$ epos = epos - 1
$ if digits - f$extract( epos, 1, line ) .nes. digits then goto find_end
$ entry = f$edit( f$extract( bpos, epos-bpos+1, line ), "trim" )
$!
$! Now that full entry name is known,
$! update the information on it and determine the count of unseen notes.
$!
$ open/write nm$com 'q'2.com
$ write nm$com "$ notes"
$ write nm$com "update ""''entry'""/class=""''mv_class'"""
$ write nm$com "show entry ""''entry'"""
$ close nm$com
$ @'q'2/out='q'.entry
$ delete 'q'2.com.
$ open nm$com 'q'.entry
$find_unseen:
$ read/end=no_entry_info nm$com line
$ if line - entry .eqs. line .or. line - topic_keyword .eqs. line -
then goto find_unseen
$ close nm$com
$ delete 'q'.entry.
$ entry_unseen = 'f$element( 0, " ", line )'
$ if entry_unseen .le. 0 then goto check_next_entry
$ if entry_unseen .le. mv_limit then goto not_too_much
$!
$! Come here if there are too many unseen notes.
$!
$ mail sys$input: 'mail_address' /subject = -
"Conference ''entry' has more than ''mv_limit' unseen entries"
The specified conference has too many unseen entries, which will not be
mailed to you. If you have ample disk space available, you may wish to
resubmit the procedure with a higher value for the /LIMIT switch.
Please use NOTES and visit the conference yourself, or use a higher value
for the /LIMIT switch as mentioned above.
If the reason for the unseemly unseen count is that you've recently added
this conference to your notebook, you may want to open the conference and
issue a "SET SEEN/BEFORE=TODAY" command to skip the old items.
$ goto check_next_entry
$!
$! Come here if the SHOW ENTRY doesn't give information or the UPDATE fails.
$!
$no_entry_info:
$ close nm$com
$ mail 'q'.entry 'mail_address' /subject = -
"FAILURE extracting from conference ''entry'. Please read it with VAXNOTES."
$ delete 'q'.entry.
$ goto check_next_entry
$!
$not_too_much:
$ if f$trnlnm ("nm$extract") .nes. "" then close nm$extract
$ open/write nm$extract 'q'.com
$ write nm$extract "$ on warning then exit"
$ write nm$extract "$ notes"
$ write nm$extract "open/noautomatic/class=""''mv_class'"" ""''entry'"""
$ write nm$extract "show error"
$ write nm$extract "extract/seen/unseen/append ''q'.txt *.*"
$ write nm$extract "show error"
$ write nm$extract "close"
$ close nm$extract
$ if f$search ("''q'.txt") .nes. "" then delete 'q'.txt.*
$ on warning then goto extract_failed
$ extract_time = f$time() ! save extraction time
$ @'q'/out='q'.out
$ on warning then goto whoops
$ goto extract_succeeded
$extract_failed:
$ status = $status
$ on warning then goto whoops
$ if f$search ("''q'.out") .nes. "" -
then mail 'q'.out 'mail_address' /subject = -
"Failure extracting new notes for conference ''entry', ''f$message (status)'"
$extract_succeeded:
$ delete 'q'.com.
$!
$! Compose directory. This directory allows the user to see what topic
$! titles have replies, even if the original topics themselves aren't new.
$!
$ if f$search ("''q'.txt") .eqs. "" then goto nothing_extracted
$ dict_width = 80 !max width of dictionary lines
$ tracks = f$fao ("!80*=") ! railroad
$ dashes = f$fao ("!80*-")
$ on warning then goto mail_failed
$ search /window=(1,3)/out='q'.pre -
'q'.txt -
"''tracks'"
$ if $status .ne. 1 then goto update_lied
$ on warning then goto whoops
$ if f$trnlnm ("mv$s") .nes. "" then close mv$s
$ open mv$s 'q'.pre
$ if f$trnlnm ("mv$d") .nes. "" then close mv$d
$ open/write mv$d 'q'.pre
$ track_line = ""
$ first_topic = 1
$ previous_topic_number = -1
$find_tracks:
$ ff_line = track_line
$ read/end=done_dir mv$s track_line
$ if track_line .nes. tracks then goto find_tracks
$ read/end=done_dir mv$s topic_line
$ read/end=done_dir mv$s writer_line
$ read/end=done_dir mv$s title_line
$ if title_line .eqs. dashes then title_line = ""
$ note_number = f$element( 1, " ", topic_line )
$ topic_number = f$element( 0, ".", note_number )
$ writer = f$element( 0, " ", writer_line )
$ title = f$edit (title_line, "trim")
$ if topic_number .eqs. previous_topic_number then goto same_topic
$!
$! Avoid listing embedded notes inserted from other files by rejecting any
$! topic (except the first) whose "track_line" is not preceded by a FORM FEED.
$!
$ if ff_line .nes. ff then if .not. first_topic then goto find_tracks
$ previous_topic_number = topic_number
$ first_topic = 0
$!
$! Find ending position of topic, by finding last occurence of each of
$! the keywords in "n of n" and "{n|NO} {replies|reply}" and then scanning
$! backwards past the count. If no keywords are found, use line length.
$!
$ keyword_list = " of , replies, reply"
$ kpos = -1
$try_next_keyword:
$ keyword = "''f$element( 0, ",", keyword_list )'"
$ keyword_list = keyword_list - keyword - ","
$find_terminal_keyword:
$ pkpos = kpos
$ kpos = f$locate( keyword, f$extract( kpos+1, 999, topic_line ) ) -
+ kpos + 1
$ if kpos .lt. f$length( topic_line ) then goto find_terminal_keyword
$ kpos = 'pkpos'
$ if keyword_list .nes. "" then goto try_next_keyword
$ if kpos .eq. -1 then goto terminal_keyword_not_found
$find_count:
$ kpos = 'kpos' - 1
$ if f$extract( kpos, 1, topic_line ) .nes. " " then goto find_count
$terminal_keyword_not_found:
$ tpos = f$length( f$element( 0, " ", topic_line ) ) + 1 -
+ f$length( note_number )
$ topic = f$edit( f$extract( tpos, kpos-tpos, topic_line ), "trim" )
$!
$! Generate topic line for dictionary,
$! being sure to avoid numeric underflow for the number of dashes.
$!
$ dash_left = 24 !indentation of topic title
$ dash_right = dict_width - f$length( topic ) - dash_left
$ if dash_right .lt. 0 then dash_right = 0
$ write/error=mail_failed mv$d -
f$fao ( "!#<!#*-!AS!#*-!>", dict_width, dash_left, topic, dash_right )
$!
$same_topic:
$!
$ write/error=mail_failed mv$d f$edit( f$fao( "!#<!7AS !21AS !AS!>", -
dict_width, note_number, writer, title ), "trim")
$ goto find_tracks
$!
$! Generate "trailer" for directory, including some information that may
$! be of interest to the recepient and/or useful for support reasons.
$!
$done_dir:
$ write/error=mail_failed mv$d ""
$ write/error=mail_failed mv$d tab, tab, "Notes start on next page."
$ close mv$d
$ close mv$s
$!
$! Append new notes to the generated directory listing.
$!
$ on warning then goto mail_failed
$ convert/append 'q'.txt 'q'.pre
$!
$! Append additional information about the extraction to the end of the file.
$!
$ open/append mv$d 'q'.pre
$ weekday = f$cvtime( extract_time,,"weekday" ) ! "Wwww..."
$ date = f$edit( f$extract( 0, 4, extract_time ), "trim" ) - ! "dd-M"
+ f$edit( f$extract( 4, 3, extract_time ), "lowercase" ) - ! "mm-"
+ f$extract( 9, 2, extract_time ) ! "yy"
$ time = f$extract( 12, 11, extract_time ) ! "hh:mm:ss.cc"
$ write/error=mail_failed mv$d ff
$ write/error=mail_failed mv$d -
f$fao( "Extraction performed by !AS at !5AS on !AS (!3AS)", -
user_address, time, date, weekday )
$ write/error=mail_failed mv$d " using ", procedure_info
$ write/error=mail_failed mv$d -
" with switches """, original_params, """"
$ close mv$d
$!
$! Mail the new stuff. If error, mail the error which is probably an
$! "over quota" message.
$!
$ mail 'q'.pre 'mail_address' /subject = "New notes for conference ''entry'"
$update_lied:
$ on warning then goto whoops
$ delete 'q'.pre.*, 'q'.out., 'q'.txt.
$ goto check_next_entry
$mail_failed:
$ status = $status
$!
$! Try to tell user that we couldn't mail the notes, and which
$! text files the notes are in. If we can't even do that, give
$! up.
$!
$ on warning then goto exit
$ mail sys$input 'mail_address' /subject = -
"Read files ''q'.txt and ''q'.out, re: conf. ''entry', ''f$message (status)'"
An error occured while trying to mail you the new notes for the above
conference.
The files named above contain the new notes and status information.
After checking the files and correcting the error, you may submit the
procedure again, in order to continue receiving the rest of your new notes.
$ goto exit
$no_entry_file:
$ status = $status
$ mail nl: 'mail_address' /subject = -
"Failed to get conference entries list, ''f$message (status)'"
$ exit status
$nothing_extracted:
$ mail 'q'.out 'mail_address' /subject = -
"Incomplete extraction for conference ''entry'"
$ delete 'q'.out.
$ goto check_next_entry
$no_more_entries:
$ close nm$entries
$ delete 'q'.entries.
$!
$! See if we're supposed to resubmit ourself.
$!
$finished:
$ if "''mv_again_at'" .eqs. "" then goto exit
$ if f$extract (0, 1, mv_again_at) .nes. "+" then goto literal
$ now = f$time()
$ now_date = f$cvtime( now, "absolute", "date" )
$ now_time = f$cvtime( now, "absolute", "time" )
$ mv_again_at = "''now_date':''now_time'" + "''mv_again_at'"
$literal:
$ allow_now = " /Not_Now=<No>"
$ original_params = original_params - allow_now + allow_now
$ on warning then goto again_error
$! CARL Leeber
$! submit/notify/nokeep/noprint/name=&mv_name/after=&mv_again_at -
$! 'procedure_spec' /param = &original_params
$ submit/notify/keep/log/noprint/name=&mv_name/after=&mv_again_at -
'procedure_spec' /param = &original_params
$ on warning then goto whoops
$ goto exit
$!
$! Error doing the submit. If it's because of invalid date-time
$! format, tell user.
$!
$again_error:
$ status = $status
$ on warning then goto whoops
$ if status .ne. %x38290 then goto whoops
$ mail sys$input 'mail_address' -
/subject= "ERROR parsing ""''mv_again_at'""."
The SUBMIT command failed to understand the above value for a date-and-time.
Please resubmit the procedure with the correct value for /AGAIN_AT. You may
want to check the VMS documentation or on-line help.
If you're still confused, please ask whomever told you about the procedure
in the first place.
$ exit status
$!
$! Come here during startup if no conferences are found.
$!
$no_entries:
$ close nm$entries
$ mail 'q'.entries 'mail_address' /subject = "No conferences found"
$ delete 'q'.entries.
$ goto exit
$!
$! Come here on an error. We attempt to mail our log file to
$! author for analysis.
$!
$whoops:
$ status = $status
$ if "''mv_z_first_tag'" .eqs. "mail_log" then exit status
$ if f$trnlnm ("sys$output",,,,,"access_mode") .eqs. "USER" -
then deassign/user sys$output
$ deassign sys$output
$ show symbol/all
$!
$!Files accessed on device _DRB1: on 10-JAN-1986 10:23:24.94
$!
$!Process name PID File name
$! 00000000 [000000]INDEXF.SYS;1
$!Eric's batchjob 0000085E [OSMAN]MAILNOTES_85D.LOG;1
$!Eric's batchjob 0000085E [OSMAN.COMFILES]MAILNOTES.COM;207
$!BATCH_195 0000080A [OSMAN.COMFILES]MAILNOTES.COM;207
$ on warning then goto double_whammy
$ long_pid = f$getjpi ("", "pid")
$ device = f$trnlnm ("sys$output")
$ show device 'device'/file/output='q'.dev
$ if f$trnlnm ("nm$dev") .nes. "" then close nm$dev
$ open nm$dev 'q'.dev
$ delete 'q'.dev.
$find_ourself:
$ read/end=no_log_file nm$dev line
$ if "''f$extract (16, 8, line)'" .nes. long_pid then goto find_ourself
$ old_log_file = device + f$extract (26, 999, line)
$ if f$parse (old_log_file,,,"type") .nes. ".LOG" then goto find_ourself
$ close nm$dev
$ rename 'old_log_file' 'q'.saved_log
$ params = "/z_first_tag=<mail_log>/z_error_code=<''status'>" -
+ "/z_old_log_file=<''old_log_file'>/z_log_file=<''q'.saved_log>" -
+ "/mail_to=<''mail_address'>"
$! CARL Leeber
$! submit 'procedure_spec' /params = ¶ms/nolog
$ submit 'procedure_spec' /params = ¶ms/log/keep
$ exit status
$!
$! Come here during startup if /z_first_tag=<mail_log>
$!
$mail_log:
$ subject = "FAILURE executing ''procedure_info', " -
+ "error = ''mv_z_error_code', ''f$message (mv_z_error_code)'"
$ mail 'mv_z_log_file' 'error_addresses' /subject = &subject
$ rename 'mv_z_log_file' 'mv_z_old_log_file'
$ goto exit
$no_log_file:
$ close nm$dev
$ mail sys$input 'error_addresses' /subject = -
"FAILURE executing ''procedure_info', ''f$message (status)'"
The subject line of this message indicates the error message.
Sorry, no log file was found.
$ exit status
$!
$! Here when some sort of error within an error.
$!
$double_whammy:
$ second_status = $status
$ mail sys$input 'author', 'mail_address' /subject = -
"FAILURE executing ''procedure_info', ''f$message (status)', ''f$message (second_status)'"
Also, an error occured during error analysis !
The subject line of this message indicates the error messages.
$ goto exit
$!
$! Get out
$!
$exit:
$ old_verify = f$verify(old_verify)
$ exit
|