| $! MKSHARED.COM -- script to created shareable images on VMS | 
 | $! | 
 | $! No command line parameters.  This should be run at the start of the source | 
 | $! tree (the same directory where one finds INSTALL.VMS). | 
 | $! | 
 | $! Input:	[.UTIL]LIBEAY.NUM,[.AXP.EXE.CRYPTO]LIBCRYPTO.OLB | 
 | $!		[.UTIL]SSLEAY.NUM,[.AXP.EXE.SSL]LIBSSL.OLB | 
 | $! Output:	[.AXP.EXE.CRYPTO]LIBCRYPTO.OPT,.MAP,.EXE | 
 | $!		[.AXP.EXE.SSL]LIBSSL.OPT,.MAP,.EXE | 
 | $! | 
 | $! So far, tests have only been made on VMS for Alpha.  VAX will come in time. | 
 | $! =========================================================================== | 
 | $ | 
 | $! ----- Prepare info for processing: version number and file info | 
 | $ gosub read_version_info | 
 | $ if libver .eqs. "" | 
 | $ then | 
 | $   write sys$error "ERROR: Couldn't find any library version info..." | 
 | $   exit | 
 | $ endif | 
 | $ | 
 | $ if f$getsyi("CPU") .ge. 128 | 
 | $ then | 
 | $   libid  = "Crypto" | 
 | $   libnum = "[.UTIL]LIBEAY.NUM" | 
 | $   libdir = "[.AXP.EXE.CRYPTO]" | 
 | $   libolb = "''libdir'LIBCRYPTO.OLB" | 
 | $   libopt = "''libdir'LIBCRYPTO.OPT" | 
 | $   libmap = "''libdir'LIBCRYPTO.MAP" | 
 | $   libgoal= "''libdir'LIBCRYPTO.EXE" | 
 | $   libref = "" | 
 | $   gosub create_axp_shr | 
 | $   libid  = "SSL" | 
 | $   libnum = "[.UTIL]SSLEAY.NUM" | 
 | $   libdir = "[.AXP.EXE.SSL]" | 
 | $   libolb = "''libdir'LIBSSL.OLB" | 
 | $   libopt = "''libdir'LIBSSL.OPT" | 
 | $   libmap = "''libdir'LIBSSL.MAP" | 
 | $   libgoal= "''libdir'LIBSSL.EXE" | 
 | $   libref = "[.AXP.EXE.CRYPTO]LIBCRYPTO.EXE" | 
 | $   gosub create_axp_shr | 
 | $ else | 
 | $   libtit = "CRYPTO_TRANSFER_VECTOR" | 
 | $   libid  = "Crypto" | 
 | $   libnum = "[.UTIL]LIBEAY.NUM" | 
 | $   libdir = "[.VAX.EXE.CRYPTO]" | 
 | $   libmar = "''libdir'LIBCRYPTO.MAR" | 
 | $   libolb = "''libdir'LIBCRYPTO.OLB" | 
 | $   libopt = "''libdir'LIBCRYPTO.OPT" | 
 | $   libobj = "''libdir'LIBCRYPTO.OBJ" | 
 | $   libmap = "''libdir'LIBCRYPTO.MAP" | 
 | $   libgoal= "''libdir'LIBCRYPTO.EXE" | 
 | $   libref = "" | 
 | $   libvec = "LIBCRYPTO" | 
 | $   gosub create_vax_shr | 
 | $   libtit = "SSL_TRANSFER_VECTOR" | 
 | $   libid  = "SSL" | 
 | $   libnum = "[.UTIL]SSLEAY.NUM" | 
 | $   libdir = "[.VAX.EXE.SSL]" | 
 | $   libmar = "''libdir'LIBSSL.MAR" | 
 | $   libolb = "''libdir'LIBSSL.OLB" | 
 | $   libopt = "''libdir'LIBSSL.OPT" | 
 | $   libobj = "''libdir'LIBSSL.OBJ" | 
 | $   libmap = "''libdir'LIBSSL.MAP" | 
 | $   libgoal= "''libdir'LIBSSL.EXE" | 
 | $   libref = "[.VAX.EXE.CRYPTO]LIBCRYPTO.EXE" | 
 | $   libvec = "LIBSSL" | 
 | $   gosub create_vax_shr | 
 | $ endif | 
 | $ exit | 
 | $ | 
 | $! ----- Soubroutines to actually build the shareable libraries | 
 | $! The way things work, there's a main shareable library creator for each | 
 | $! supported architecture, which is called from the main code above. | 
 | $! The creator will define a number of variables to tell the next levels of | 
 | $! subroutines what routines to use to write to the option files, call the | 
 | $! main processor, read_func_num, and when that is done, it will write version | 
 | $! data at the end of the .opt file, close it, and link the library. | 
 | $! | 
 | $! read_func_num reads through a .num file and calls the writer routine for | 
 | $! each line.  It's also responsible for checking that order is properly kept | 
 | $! in the .num file, check that each line applies to VMS and the architecture, | 
 | $! and to fill in "holes" with dummy entries. | 
 | $! | 
 | $! The creator routines depend on the following variables: | 
 | $! libnum	The name of the .num file to use as input | 
 | $! libolb	The name of the object library to build from | 
 | $! libid	The identification string of the shareable library | 
 | $! libopt	The name of the .opt file to write | 
 | $! libtit	The title of the assembler transfer vector file (VAX only) | 
 | $! libmar	The name of the assembler transfer vector file (VAX only) | 
 | $! libmap	The name of the map file to write | 
 | $! libgoal	The name of the shareable library to write | 
 | $! libref	The name of a shareable library to link in | 
 | $! | 
 | $! read_func_num depends on the following variables from the creator: | 
 | $! libwriter	The name of the writer routine to call for each .num file line | 
 | $! ----- | 
 | $ | 
 | $! ----- Subroutines for AXP | 
 | $! ----- | 
 | $! The creator routine | 
 | $ create_axp_shr: | 
 | $   open/write opt 'libopt' | 
 | $   write opt "identification=""",libid," ",libverstr,"""" | 
 | $   write opt libolb,"/lib" | 
 | $   if libref .nes. "" then write opt libref,"/SHARE" | 
 | $   write opt "SYMBOL_VECTOR=(-" | 
 | $   libfirstentry := true | 
 | $   libwrch   := opt | 
 | $   libwriter := write_axp_transfer_entry | 
 | $   textcount = 0 | 
 | $   gosub read_func_num | 
 | $   write opt ")" | 
 | $   write opt "GSMATCH=",libvmatch,",",libver | 
 | $   close opt | 
 | $   link/map='libmap'/full/share='libgoal' 'libopt'/option | 
 | $   return | 
 | $ | 
 | $! The record writer routine | 
 | $ write_axp_transfer_entry: | 
 | $   if libentry .eqs. ".dummy" then return | 
 | $   if info_kind .eqs. "VARIABLE" | 
 | $   then | 
 | $     pr:=DATA | 
 | $   else | 
 | $     pr:=PROCEDURE | 
 | $   endif | 
 | $   textcount_this = f$length(pr) + f$length(libentry) + 5 | 
 | $   if textcount + textcount_this .gt. 1024 | 
 | $   then | 
 | $     write opt ")" | 
 | $     write opt "SYMBOL_VECTOR=(-" | 
 | $     textcount = 16 | 
 | $     libfirstentry := true | 
 | $   endif | 
 | $   if libfirstentry | 
 | $   then | 
 | $     write 'libwrch' "    ",libentry,"=",pr," -" | 
 | $   else | 
 | $     write 'libwrch' "    ,",libentry,"=",pr," -" | 
 | $   endif | 
 | $   libfirstentry := false | 
 | $   textcount = textcount + textcount_this | 
 | $   return | 
 | $ | 
 | $! ----- Subroutines for AXP | 
 | $! ----- | 
 | $! The creator routine | 
 | $ create_vax_shr: | 
 | $   open/write mar 'libmar' | 
 | $   type sys$input:/out=mar: | 
 | ; | 
 | ; Transfer vector for VAX shareable image | 
 | ; | 
 | $   write mar "	.TITLE ",libtit | 
 | $   write mar "	.IDENT /",libid,"/" | 
 | $   type sys$input:/out=mar: | 
 | ; | 
 | ; Define macro to assist in building transfer vector entries.  Each entry | 
 | ; should take no more than 8 bytes. | 
 | ; | 
 | 	.MACRO FTRANSFER_ENTRY routine | 
 | 	.ALIGN QUAD | 
 | 	.TRANSFER routine | 
 | 	.MASK	routine | 
 | 	JMP	routine+2 | 
 | 	.ENDM FTRANSFER_ENTRY | 
 | ; | 
 | ; Place entries in own program section. | 
 | ; | 
 | $   write mar "	.PSECT $$",libvec,",QUAD,PIC,USR,CON,REL,LCL,SHR,EXE,RD,NOWRT" | 
 | $   write mar libvec,"_xfer:" | 
 | $   libwrch   := mar | 
 | $   libwriter := write_vax_ftransfer_entry | 
 | $   gosub read_func_num | 
 | $   type sys$input:/out=mar: | 
 | ; | 
 | ; Allocate extra storage at end of vector to allow for expansion. | 
 | ; | 
 | $   write mar "	.BLKB 32768-<.-",libvec,"_xfer>	; 64 pages total." | 
 | $!   libwriter := write_vax_vtransfer_entry | 
 | $!   gosub read_func_num | 
 | $   write mar "	.END" | 
 | $   close mar | 
 | $   open/write opt 'libopt' | 
 | $   write opt "identification=""",libid," ",libverstr,"""" | 
 | $   write opt libobj | 
 | $   write opt libolb,"/lib" | 
 | $   if libref .nes. "" then write opt libref,"/SHARE" | 
 | $   type sys$input:/out=opt: | 
 | ! | 
 | ! Ensure transfer vector is at beginning of image | 
 | ! | 
 | CLUSTER=FIRST | 
 | $   write opt "COLLECT=FIRST,$$",libvec | 
 | $   write opt "GSMATCH=",libvmatch,",",libver | 
 | $   type sys$input:/out=opt: | 
 | ! | 
 | ! make psects nonshareable so image can be installed. | 
 | ! | 
 | PSECT_ATTR=$CHAR_STRING_CONSTANTS,NOWRT | 
 | $   libwrch   := opt | 
 | $   libwriter := write_vax_psect_attr | 
 | $   gosub read_func_num | 
 | $   close opt | 
 | $   macro/obj='libobj' 'libmar' | 
 | $   link/map='libmap'/full/share='libgoal' 'libopt'/option | 
 | $   return | 
 | $ | 
 | $! The record writer routine for VAX functions | 
 | $ write_vax_ftransfer_entry: | 
 | $   if info_kind .nes. "FUNCTION" then return | 
 | $   if libentry .eqs ".dummy" | 
 | $   then | 
 | $     write 'libwrch' "	.BLKB 8" ! Dummy is zeroes... | 
 | $   else | 
 | $     write 'libwrch' "	FTRANSFER_ENTRY ",libentry | 
 | $   endif | 
 | $   return | 
 | $! The record writer routine for VAX variables (should never happen!) | 
 | $ write_vax_psect_attr: | 
 | $   if info_kind .nes. "VARIABLE" then return | 
 | $   if libentry .eqs ".dummy" then return | 
 | $   write 'libwrch' "PSECT_ATTR=",libentry,",NOSHR" | 
 | $   return | 
 | $ | 
 | $! ----- Common subroutines | 
 | $! ----- | 
 | $! The .num file reader.  This one has great responsability. | 
 | $ read_func_num: | 
 | $   open libnum 'libnum' | 
 | $   goto read_nums | 
 | $ | 
 | $ read_nums: | 
 | $   libentrynum=0 | 
 | $   liblastentry:=false | 
 | $   entrycount=0 | 
 | $   loop: | 
 | $     read/end=loop_end/err=loop_end libnum line | 
 | $     entrynum=f$int(f$element(1," ",f$edit(line,"COMPRESS,TRIM"))) | 
 | $     entryinfo=f$element(2," ",f$edit(line,"COMPRESS,TRIM")) | 
 | $     curentry=f$element(0," ",f$edit(line,"COMPRESS,TRIM")) | 
 | $     info_exist=f$element(0,":",entryinfo) | 
 | $     info_platforms=","+f$element(1,":",entryinfo)+"," | 
 | $     info_kind=f$element(2,":",entryinfo) | 
 | $     info_algorithms=","+f$element(3,":",entryinfo)+"," | 
 | $     if info_exist .eqs. "NOEXIST" then goto loop | 
 | $     truesum = 0 | 
 | $     falsesum = 0 | 
 | $     negatives = 1 | 
 | $     plat_i = 0 | 
 | $     loop1: | 
 | $       plat_entry = f$element(plat_i,",",info_platforms) | 
 | $       plat_i = plat_i + 1 | 
 | $       if plat_entry .eqs. "" then goto loop1 | 
 | $       if plat_entry .nes. "," | 
 | $       then | 
 | $         if f$extract(0,1,plat_entry) .nes. "!" then negatives = 0 | 
 | $         if f$getsyi("CPU") .lt. 128 | 
 | $         then | 
 | $           if plat_entry .eqs. "EXPORT_VAR_AS_FUNCTION" then - | 
 | $             truesum = truesum + 1 | 
 | $           if plat_entry .eqs. "!EXPORT_VAR_AS_FUNCTION" then - | 
 | $             falsesum = falsesum + 1 | 
 | $         endif | 
 | $         if plat_entry .eqs. "VMS" then truesum = truesum + 1 | 
 | $         if plat_entry .eqs. "!VMS" then falsesum = falsesum + 1 | 
 | $	  goto loop1 | 
 | $       endif | 
 | $     endloop1: | 
 | $!DEBUG!$     if info_platforms - "EXPORT_VAR_AS_FUNCTION" .nes. info_platforms | 
 | $!DEBUG!$     then | 
 | $!DEBUG!$       write sys$output line | 
 | $!DEBUG!$       write sys$output "        truesum = ",truesum,- | 
 | $!DEBUG!		", negatives = ",negatives,", falsesum = ",falsesum | 
 | $!DEBUG!$     endif | 
 | $     if falsesum .ne. 0 then goto loop | 
 | $     if truesum+negatives .eq. 0 then goto loop | 
 | $     alg_i = 0 | 
 | $     loop2: | 
 | $       alg_entry = f$element(alg_i,",",info_algorithms) | 
 | $	alg_i = alg_i + 1 | 
 | $       if alg_entry .eqs. "" then goto loop2 | 
 | $       if alg_entry .nes. "," | 
 | $       then | 
 | $         if alg_entry .eqs. "KRB5" then goto loop ! Special for now | 
 | $         if f$trnlnm("OPENSSL_NO_"+alg_entry) .nes. "" then goto loop | 
 | $	  goto loop2 | 
 | $       endif | 
 | $     endloop2: | 
 | $     if info_platforms - "EXPORT_VAR_AS_FUNCTION" .nes. info_platforms | 
 | $     then | 
 | $!DEBUG!$     write sys$output curentry," ; ",entrynum," ; ",entryinfo | 
 | $     endif | 
 | $   redo: | 
 | $     next:=loop | 
 | $     tolibentry=curentry | 
 | $     if libentrynum .ne. entrynum | 
 | $     then | 
 | $       entrycount=entrycount+1 | 
 | $       if entrycount .lt. entrynum | 
 | $       then | 
 | $!DEBUG!$         write sys$output "Info: entrycount: ''entrycount', entrynum: ''entrynum' => 0" | 
 | $         tolibentry=".dummy" | 
 | $         next:=redo | 
 | $       endif | 
 | $       if entrycount .gt. entrynum | 
 | $       then | 
 | $         write sys$error "Decreasing library entry numbers!  Can't continue" | 
 | $         write sys$error """",line,"""" | 
 | $         close libnum | 
 | $         return | 
 | $       endif | 
 | $       libentry=tolibentry | 
 | $!DEBUG!$       write sys$output entrycount," ",libentry," ",entryinfo | 
 | $       if libentry .nes. "" .and. libwriter .nes. "" then gosub 'libwriter' | 
 | $     else | 
 | $       write sys$error "Info: ""''curentry'"" is an alias for ""''libentry'"".  Overriding..." | 
 | $     endif | 
 | $     libentrynum=entrycount | 
 | $     goto 'next' | 
 | $   loop_end: | 
 | $   close libnum | 
 | $   return | 
 | $ | 
 | $! The version number reader | 
 | $ read_version_info: | 
 | $   libver = "" | 
 | $   open/read vf [.CRYPTO]OPENSSLV.H | 
 | $   loop_rvi: | 
 | $     read/err=endloop_rvi/end=endloop_rvi vf rvi_line | 
 | $     if rvi_line - "SHLIB_VERSION_NUMBER """ .eqs. rvi_line then - | 
 | 	goto loop_rvi | 
 | $     libverstr = f$element(1,"""",rvi_line) | 
 | $     libvmajor = f$element(0,".",libverstr) | 
 | $     libvminor = f$element(1,".",libverstr) | 
 | $     libvedit = f$element(2,".",libverstr) | 
 | $     libvpatch = f$cvui(0,8,f$extract(1,1,libvedit)+"@")-f$cvui(0,8,"@") | 
 | $     libvedit = f$extract(0,1,libvedit) | 
 | $     libver = f$string(f$int(libvmajor)*100)+","+- | 
 | 	f$string(f$int(libvminor)*100+f$int(libvedit)*10+f$int(libvpatch)) | 
 | $     if libvmajor .eqs. "0" | 
 | $     then | 
 | $       libvmatch = "EQUAL" | 
 | $     else | 
 | $       ! Starting with the 1.0 release, backward compatibility should be | 
 | $       ! kept, so switch over to the following | 
 | $       libvmatch = "LEQUAL" | 
 | $     endif | 
 | $   endloop_rvi: | 
 | $   close vf | 
 | $   return |