          <<< NOTED::DISK$NOTES7:[NOTES$LIBRARY_7OF4]HACKERS.NOTE;1 >>>
                               -< ** Hackers ** >-
================================================================================
Note 1760.2         DCL Code For Reading Alpha Image Header?              2 of 5
RANGER::VATNE "Peter Vatne, PATHWORKS Server Engin" 444 lines   5-APR-1995 12:10
               -< PWRK$VERSIONS.COM does most of what you want >-
--------------------------------------------------------------------------------
$! Copyright © Digital Equipment Corporation, 1993, 1994.  All rights reserved.
$!
$ put := write sys$output
$ on error then continue
$ on control_y then goto use_ivp_loop_end
$ GOTO VERSION_START
$!
$! PWRK$VERSIONS.COM
$!
$! This command file displays image information for all of the images
$! included in PATHWORKS for OpenVMS (LAN Manager).  The following
$! is displayed for each image:
$!
$!		Internal name string
$!		Architecture type (VAX or AXP)
$!		ID string (usually a version number)
$!		Date/time when linked
$!		Linker ID string
$! 
$! Command format:
$!
$!	@SYS$UPDATE:PWRK$VERSIONS [ALL or filespec]
$!
$! where [filespec] is the name of a file whose version information you
$! wish to display. If a wildcard is present, information on all of the
$! files that match will be given. The file type defaults to .EXE.
$! If device and directory information is omitted from the filespec
$! parameter, SYS$SYSROOT:[*...].EXE will be used as defaults for the
$! search.
$!
$! 
$! If the filespec parmeter is blank, the version information for the major
$! PATHWORKS images will be displayed.
$!
$!
$! If the keyword ALL is given, the version information for all of the
$! PATHWORKS images will be displayed. PWRK$VERSIONS will read the file
$! SYS$TEST:PWRK$IVP.DAT to determine which images to display. If this
$! file is missing, PWRK$VERSIONS will search for the file
$! SYS$TEST:PWVN$IVP.DAT (the PATHWORKS for OpenVMS (NetWare) V1.1 IVP
$! data file).  If neither of those is present, PWRK$VERSIONS  will
$! display an error message and fall back to searching SYS$SYSROOT:[*...]
$! for PWRK$*.EXE and PWVN$*.EXE. This will miss several images whose
$! names do not begin with the PWRK$ or PWVN$ prefix. For proper
$! operation of this command file, either reinstall PATHWORKS for OpenVMS
$! (LAN Manager), PATHWORKS for  OpenVMS(NetWare), or restore the
$! PWRK$IVP.DAT and/or PWVN$IVP.DAT files from the distribution kits.
$! 
$! If, again, the keyword ALL is given and both the PWRK$IVP.DAT file and
$! the PWVN$IVP.DAT file exist on SYS$TEST, they will be copied to a single
$! file on SYS$SCRATCH, which will then be passed through SORT to remove
$! possible duplicate lines.  
$!
$!The IHD$ and IHI$ symbol definitions are taken from SYS$LIBRARY:LIB.
$!
$
$!**********************************************************************
$GET_IMAGE_INFO:	subroutine
$
$ !Blank out return parameters
$
$ 'p2' == ""	!Image name
$ 'p3' == ""	!Image type
$ 'p4' == ""	!Image id
$ 'p5' == ""	!Link time
$ 'p6' == ""	!Linker ID
$
$ vax = vaxdef
$ axp = axpdef
$! gii$_error_flag :== false
$ fullfile = f$search(p1)
$ if fullfile .eqs. "" then goto gii$_failure_exit
$ open/read/share/error=gii$_failure_exit PWRK$IDENT_FILE 'p1'
$ read/end=gii$_failure_exit/error=gii$_failure_exit PWRK$IDENT_FILE header
$ close PWRK$IDENT_FILE
$ if f$length(header) .lt. 512 then goto gii$_bad_image_format
$ if f$cvui(0,16,f$ext(0,2,header)) .lt. 48
$ then
$	vax := false
$	axp := true
$	imgflag = "AXP$"
$ else
$	vax := true
$	axp := false
$	imgflag = "VAX$"	
$ endif
$ 'p3' == imgflag - "$"		!Send Image type to caller (less the $)
$
$ tmp = f$extract('imgflag'ihd$size,'imgflag'ihd$size_s,header)
$ dtmp = f$cvui(0,'imgflag'ihd$size_s*8,tmp)
$ if dtmp .gt. 8192 then goto gii$_bad_image_format 
$ tmp = f$extract('imgflag'ihd$imgidoff,'imgflag'ihd$imgidoff_s,header)
$ 'imgflag'ihi = f$cvui(0,'imgflag'ihd$imgidoff_s*8,tmp)
$ tmp = f$extract('imgflag'ihi+'imgflag'ihi$t_imgnam,1,header)
$ len = f$cvui(0,8,tmp)		!1st byte is count of string
$ 'p2' == f$extract('imgflag'ihi+'imgflag'ihi$t_imgnam+1,len,header)
$ tmp = f$extract('imgflag'ihi+'imgflag'ihi$t_imgid,1,header)
$ len = f$cvui(0,8,tmp)
$ 'p4' == f$extract('imgflag'ihi+'imgflag'ihi$t_imgid+1,len,header)
$ tmp = f$extract('imgflag'ihi+'imgflag'ihi$q_linktime,'imgflag'ihi$s_linktime,header)
$ 'p5' == f$fao("!%D",f$cvui(0,32,f$fao("!AD",4,'f$fao("%x!XL",tmp)+4)))
$ tmp = f$extract('imgflag'ihi+'imgflag'ihi$t_linkid,1,header)
$ len = f$cvui(0,8,tmp)
$ 'p6' == f$extract('imgflag'ihi+'imgflag'ihi$t_linkid+1,len,header)	!Linker ID
$
$
$GII$_SUCCESS_EXIT:
$ exit
$
$GII$_BAD_IMAGE_FORMAT:
$ if VAX then savstat = %X104D8C84
$ if AXP then savstat = %X104D8CFC
$ goto gii$_unexpected_exit
$
$GII$_EOF_EXIT:
$GII$_FAILURE_EXIT:
$ savstat = $status
$GII$_UNEXPECTED_EXIT:
$ close/nolog PWRK$IDENT_FILE
$ exit "''savstat'"
$ endsubroutine
$
$!************************************************************************
$! FILESPEC_FINDER - Finds and displays the information for a given
$! filespec supplied in P1 as input.  Handles wildcards.
$!************************************************************************
$
$FILESPEC_FINDER: subroutine
$ on error then continue
$ fnfmsg = %x10018292
$ first_file := true
$ if f$type(reqflag) .eqs. "" then reqflag := true
$ file = p1
$ filelen = f$length(p1)
$ wildcard := false
$ if f$locate("*",file) .ne. filelen then wildcard := TRUE
$ if f$locate("%",file) .ne. filelen then wildcard := true
$
$ if .not. pwrk_header_displayed
$ then
$	put ""
$	put header_line_0
$	put ""
$ 	put header_line_1
$ 	put header_line_2
$	pwrk_header_displayed :== true
$ endif
$
$FILESPEC_FIND_LOOP:
$ active_file = f$search(file)
$ if active_file .eqs. ""
$ then
$ 	if .not. first_file 
$	then 
$		exit			!Null means no more wildcarded files
$	else
$		badstat = fnfmsg
$		active_file = file	!So error message will come out right
$		goto filespec_find_error
$	endif
$ endif
$ pwrk_imagename == ""
$ pwrk_imagetype == ""
$ pwrk_imageid == ""
$ pwrk_linktime == ""
$ pwrk_linkerid == ""
$ call get_image_info 'active_file' -
	pwrk_imagename -
	pwrk_imagetype -
	pwrk_imageid -
	pwrk_linktime -
	pwrk_linkerid
$ if .not. $status 
$ then 
$	badstat = $status
$	goto filespec_find_error
$ endif
$ if pwrk_imageid .nes. ""
$ then
$ 	line := ""
$ 	line[ 0,30] := "''pwrk_imagename'"
$	line[31,16] := "''pwrk_imageid'"
$	line[48,17] := "''pwrk_linktime'"
$	line[67,13] := "''pwrk_linkerid'"
$	put line
$	orig_filename = f$parse(active_file,,,"name")
$ 	if pwrk_imagename .nes. orig_filename
$	then
$		line = "(Above image is stored in file ''active_file')"
$		put line
$	endif
$ endif
$ if wildcard 
$ then 
$	if first_file then first_file := false
	goto filespec_find_loop
$ endif
$ exit
$
$FILESPEC_FIND_ERROR:
$ if .not. reqflag
$ then
$	line := "%PWRK-I-NOINFO, couldn't get info for optional image ''active_file'"
$ else
$ 	line := "%PWRK-I-NOINFO, couldn't get image info for ''active_file'"
$ endif
$ put line
$!$ line := "''f$message(badstat)'"
$!$ put line
$ if wildcard .and. .not. first_file then goto filespec_find_loop
$ exit
$ endsubroutine
$!***************************************************************************
$
$
$
$!***************************************************************************
$! Start of main program is below.  
$!
$!***************************************************************************
$VERSION_START:
$!
$! Set some initial constants
$!
$ header_line_0 = -
"Information on PATHWORKS for OpenVMS images installed on this system:"
$ header_line_1 = -
"          Image Name            Image Version      Link date        Linker ID"
$ header_line_2 = -
"------------------------------ ---------------- -----------------  -------------"
$ byte = 1
$ word = 2
$ longword = 4
$ quadword = 8
$ lanman_installed = f$search("SYS$SYSTEM:PWRK$LMMCP.EXE") .nes. ""
$ majors_only := true
$ pwrk_header_displayed :== false
$ arch = f$getsyi("arch_type")
$ if arch .eq. 2
$ then
$	VAXdef := false
$	AXPdef := true
$ else
$	VAXdef := true
$	AXPdef := false
$ endif
$ reqflag := true
$ dir1 := sys$system:
$ dir2 := sys$share:
$ dir3 := sys$loadable_images:
$ file1 := pwrk$*.exe
$ file2 := pwvn$*.exe
$ defspec := sys$system:.exe
$
$! Table of major files to display.  If you add or remove entries from
$! this list, be sure to change the major_file_count symbol to reflect an
$! accurate count of table entries.
$!
$ if lanman_installed
$ then
$ major_file_1 := SYS$COMMON:[SYSEXE]PWRK$LMSRV.EXE
$ major_file_2 := SYS$COMMON:[SYSEXE]PWRK$LMMCP.EXE
$ major_file_3 := SYS$COMMON:[SYSEXE]PWRK$LMDMN.EXE
$ else
$ major_file_1 := SYS$COMMON:[SYSEXE]PWRK$LICENSE_SERVER.EXE
$ major_file_2 := SYS$COMMON:[SYSEXE]PWRK$LICENSE_MANAGER.EXE
$ major_file_3 := SYS$COMMON:[SYSLIB]PWRK$LICENSE_LIBSHR.EXE
$ endif
$ major_file_4 := SYS$COMMON:[SYSEXE]PWRK$MASTER.EXE
$ major_file_5 := SYS$COMMON:[SYSEXE]PWRK$MONITOR.EXE
$ major_file_6 := SYS$COMMON:[SYSEXE]PWRK$NBDAEMON.EXE
$ major_file_7 := SYS$COMMON:[SYSEXE]PWRK$KNBDAEMON.EXE
$ if AXPdef then -
  major_file_8 := SYS$COMMON:[SYS$LDR]PWRK$STREAMSOS_V1.EXE
$ if VAXdef then -
  major_file_8 := SYS$COMMON:[SYS$LDR]PWRK$STREAMSOS_V5.EXE
$ major_file_9 := SYS$COMMON:[SYS$LDR]PWRK$STREAMSOS_V6.EXE
$ if lanman_installed
$ then
$ major_file_10 := SYS$COMMON:[SYSEXE]PWRK$ADMIN.EXE
$ else
$ major_file_10 := SYS$COMMON:[SYSEXE]PWVN$NPSD.EXE
$ endif
$ major_file_11 := SYS$COMMON:[SYSEXE]NETBIOS.EXE
$ major_file_12 := SYS$COMMON:[SYSLIB]NETBIOSSHR.EXE
$ major_file_count = 12
$!
$! File header constants.
$!
$! First, for VAX:
$!
$ VAX$ihd$size		= 0	! Size in bytes of Image Header record 
$ VAX$ihd$size_s	= word
$ VAX$ihd$activoff	= 2	! Byte offset to activation data 
$ VAX$ihd$activoff_s	= word
$ VAX$ihd$symdbgoff 	= 4	! Byte offset to symbol table and debug data 
$ VAX$ihd$symdbgoff_s 	= word
$ VAX$ihd$imgidoff  	= 6	! Byte offset to image ident data 
$ VAX$ihd$imgidoff_s  	= word
$ VAX$ihd$patchoff	= 8	! Byte offset to patch data 
$ VAX$ihd$patchoff_s  	= word
$ VAX$ihd$majorid	= 12	! Major id (ASCII on VAX)
$ VAX$ihd$majorid_s	= word
$ VAX$ihd$minorid 	= 14	! Minor id 
$ VAX$ihd$minorid_s	= word
$ VAX$ihd$imgtype  	= 17	! Image type 
$ VAX$ihd$imgtype_s	= byte
$
$ VAX$ihi$k_length    	= 80	! Length of image header ident section 
$ VAX$ihi$t_imgnam    	= 0	! Image name string 
$ VAX$ihi$s_imgnam    	= 40
$ VAX$ihi$t_imgid     	= 40	! Image ident string 
$ VAX$ihi$s_imgid     	= 16
$ VAX$ihi$q_linktime  	= 56	! Date and time this image was linked 
$ VAX$ihi$s_linktime  	= 8
$ VAX$ihi$t_linkid    	= 64	! Linker ident string 
$ VAX$ihi$s_linkid    	= 16
$!
$! Now, for AXP:
$!
$ AXP$ihd$majorid   	= 0	! Major id (in binary on AXP)
$ AXP$ihd$majorid_s	= longword
$ AXP$ihd$minorid   	= 4	! Minor id (ditto)
$ AXP$ihd$minorid_s	= longword
$ AXP$ihd$size		= 8	! Size in bytes of Image Header record 
$ AXP$ihd$size_s	= longword
$ AXP$ihd$activoff  	= 16	! Longword offset to activation data 
$ AXP$ihd$activoff_s  	= longword
$ AXP$ihd$symdbgoff 	= 20	! Longword offset to symbol table and debug data 
$ AXP$ihd$symdbgoff_s 	= longword
$ AXP$ihd$imgidoff  	= 24	! Longword offset to image ident data 
$ AXP$ihd$imgidoff_s  	= longword
$ AXP$ihd$patchoff  	= 28	! Longword offset to patch data 
$ AXP$ihd$patchoff_s  	= longword
$ AXP$ihd$hdrblkcnt 	= 76	! Count of header blocks 
$ AXP$ihd$hdrblkcnt_s 	= longword
$ AXP$ihd$imgtype   	= 52	! Image type 
$ AXP$ihd$imgtype_s   	= longword
$
$ AXP$ihi$k_length    	= 104	! Length of image header ident section 
$ AXP$ihi$t_imgnam    	= 16	! Image name string 
$ AXP$ihi$s_imgnam    	= 40
$ AXP$ihi$t_imgid     	= 56	! Image ident string 
$ AXP$ihi$s_imgid     	= 16
$ AXP$ihi$q_linktime  	= 8	! Date and time this image was linked 
$ AXP$ihi$s_linktime  	= 8
$ AXP$ihi$t_linkid    	= 72	! Linker ident string 
$ AXP$ihi$s_linkid    	= 16
$!
$! All constants defined.  Now lets DO something with them!
$!
$ p1 = f$edit(p1,"compress,trim,upcase")
$ if p1 .nes. "" 
$ then 
$ 	if p1 .eqs. "ALL" 
$	then
$		majors_only := FALSE
$	else
$		p1 = f$parse(p1,defspec,,,"syntax_only")
$		call filespec_finder 'p1'
$		goto common_exit	!Nothing more to do
$	endif
$ endif
$
$ if .not. majors_only then goto use_ivp_file
$ 
$ maj_loop_count = 1
$
$MAJOR_FILE_LOOP:
$ temp = major_file_'maj_loop_count'
$ call filespec_finder 'temp'
$ maj_loop_count = maj_loop_count + 1
$ if maj_loop_count .le. major_file_count then goto major_file_loop
$ goto common_exit
$	
$USE_IVP_FILE:
$ pwrk_ivp_present := false
$ pwvn_ivp_present := false
$ pwrk_ivp_filespec := SYS$TEST:PWRK$IVP.DAT
$ pwvn_ivp_filespec := SYS$TEST:PWVN$IVP.DAT
$ if f$search(pwrk_ivp_filespec) .nes. "" then pwrk_ivp_present := true
$ if f$search(pwvn_ivp_filespec) .nes. "" then pwvn_ivp_present := true
$ if (.not. pwrk_ivp_present) .and. (.not. pwvn_ivp_present)
$ then
$	put "%PWRK-W-NOIVPDAT, PWRK$IVP.DAT and PWVN$IVP.DAT were not found on SYS$TEST:"
$	put "-PWRK-W-FALLBACK, Using wildcard search method to find Pathworks images"
$	call filespec_finder 'dir1''file1'
$	call filespec_finder 'dir2''file1'
$	call filespec_finder 'dir3''file1'
$	call filespec_finder 'dir1''file2'
$	call filespec_finder 'dir2''file2'
$	call filespec_finder 'dir3''file2'
$	goto common_exit
$ endif
$ temp_file_used := false
$ if pwrk_ivp_present .and. pwvn_ivp_present	!Both present?
$ then						!Yes - make temp file of both
$	mypid = f$getjpi("","pid")		!Get my pid
$	mytemp := PWRK$VERSION-'MYPID'.TMP
$	copy/nolog/noconfirm -
		'pwrk_ivp_filespec', -
		'pwvn_ivp_filespec' -
		SYS$SCRATCH:'MYTEMP'
$	sort/noduplicate sys$scratch:'mytemp' sys$scratch:'mytemp'
$	ivp_file_to_use := SYS$SCRATCH:'MYTEMP'
$	temp_file_used := true
$ endif
$ if pwrk_ivp_present .and. .not. pwvn_ivp_present then - 
	ivp_file_to_use = pwrk_ivp_filespec
$ if pwvn_ivp_present .and. .not. pwrk_ivp_present then -
	ivp_file_to_use = pwvn_ivp_filespec
$ open/read/share PWRK$IVP_FILE 'ivp_file_to_use'
$
$USE_IVP_LOOP:
$ read/end=use_ivp_loop_end PWRK$IVP_FILE ivp_line
$ ivp_line = f$edit(ivp_line,"compress,trim,upcase")
$ ivp_reqflag = f$element(1,",",ivp_line)
$ if (ivp_reqflag .nes. "REQ") .and. (ivp_reqflag .nes. "OPT") -
	then goto use_ivp_loop	!Line is old-style PWVN IVP line - ignore
$ if ivp_reqflag .eqs. "REQ" 
$ then 
$	reqflag := true
$ else
$	reqflag := false
$ endif
$ ivp_filespec = f$element(2,",",ivp_line)
$ ivp_filetype = f$parse(ivp_filespec,,,"type")
$ if ivp_filetype .eqs. ".EXE" then call filespec_finder 'ivp_filespec'
$ goto use_ivp_loop
$
$USE_IVP_LOOP_END:
$ close/nolog PWRK$IVP_FILE
$ if temp_file_used .and. f$search(ivp_file_to_use) .nes. "" then -
	delete/nolog/noconfirm 'ivp_file_to_use';*
$ 
$COMMON_EXIT:
$ delsym := delete/symbol/global
$ if "''pwrk_header_displayed'".nes.""	then delsym pwrk_header_displayed
$ if "''pwrk_imagename'".nes.""		then delsym pwrk_imagename
$ if "''pwrk_imagetype'".nes.""		then delsym pwrk_imagetype
$ if "''pwrk_imageid'".nes.""		then delsym pwrk_imageid
$ if "''pwrk_linktime'".nes.""		then delsym pwrk_linktime
$ if "''pwrk_linkerid'".nes.""		then delsym pwrk_linkerid
$ exit
