1$! MKSHARED.COM -- script to created shareable images on VMS
2$!
3$! No command line parameters.  This should be run at the start of the source
4$! tree (the same directory where one finds INSTALL.VMS).
5$!
6$! Input:	[.UTIL]LIBEAY.NUM,[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB
7$!		[.UTIL]SSLEAY.NUM,[.xxx.EXE.SSL]LIBSSL.OLB
8$! Output:	[.xxx.EXE.CRYPTO]LIBCRYPTO.OPT,.MAP,.EXE
9$!		[.xxx.EXE.SSL]LIBSSL.OPT,.MAP,.EXE
10$!
11$! So far, tests have only been made on VMS for Alpha.  VAX will come in time.
12$! ===========================================================================
13$
14$! ----- Prepare info for processing: version number and file info
15$ gosub read_version_info
16$ if libver .eqs. ""
17$ then
18$   write sys$error "ERROR: Couldn't find any library version info..."
19$   exit
20$ endif
21$
22$ if (f$getsyi("cpu").lt.128)
23$ then
24$     arch := VAX
25$ else
26$     arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
27$     if (arch .eqs. "") then arch = "UNK"
28$ endif
29$
30$ if arch .nes. "VAX"
31$ then
32$   arch_vax = 0
33$   libid  = "Crypto"
34$   libnum = "[.UTIL]LIBEAY.NUM"
35$   libdir = "[.''ARCH'.EXE.CRYPTO]"
36$   libolb = "''libdir'LIBCRYPTO.OLB"
37$   libopt = "''libdir'LIBCRYPTO.OPT"
38$   libmap = "''libdir'LIBCRYPTO.MAP"
39$   libgoal= "''libdir'LIBCRYPTO.EXE"
40$   libref = ""
41$   gosub create_nonvax_shr
42$   libid  = "SSL"
43$   libnum = "[.UTIL]SSLEAY.NUM"
44$   libdir = "[.''ARCH'.EXE.SSL]"
45$   libolb = "''libdir'LIBSSL.OLB"
46$   libopt = "''libdir'LIBSSL.OPT"
47$   libmap = "''libdir'LIBSSL.MAP"
48$   libgoal= "''libdir'LIBSSL.EXE"
49$   libref = "[.''ARCH'.EXE.CRYPTO]LIBCRYPTO.EXE"
50$   gosub create_nonvax_shr
51$ else
52$   arch_vax = 1
53$   libtit = "CRYPTO_TRANSFER_VECTOR"
54$   libid  = "Crypto"
55$   libnum = "[.UTIL]LIBEAY.NUM"
56$   libdir = "[.''ARCH'.EXE.CRYPTO]"
57$   libmar = "''libdir'LIBCRYPTO.MAR"
58$   libolb = "''libdir'LIBCRYPTO.OLB"
59$   libopt = "''libdir'LIBCRYPTO.OPT"
60$   libobj = "''libdir'LIBCRYPTO.OBJ"
61$   libmap = "''libdir'LIBCRYPTO.MAP"
62$   libgoal= "''libdir'LIBCRYPTO.EXE"
63$   libref = ""
64$   libvec = "LIBCRYPTO"
65$   gosub create_vax_shr
66$   libtit = "SSL_TRANSFER_VECTOR"
67$   libid  = "SSL"
68$   libnum = "[.UTIL]SSLEAY.NUM"
69$   libdir = "[.''ARCH'.EXE.SSL]"
70$   libmar = "''libdir'LIBSSL.MAR"
71$   libolb = "''libdir'LIBSSL.OLB"
72$   libopt = "''libdir'LIBSSL.OPT"
73$   libobj = "''libdir'LIBSSL.OBJ"
74$   libmap = "''libdir'LIBSSL.MAP"
75$   libgoal= "''libdir'LIBSSL.EXE"
76$   libref = "[.''ARCH'.EXE.CRYPTO]LIBCRYPTO.EXE"
77$   libvec = "LIBSSL"
78$   gosub create_vax_shr
79$ endif
80$ exit
81$
82$! ----- Soubroutines to build the shareable libraries
83$! For each supported architecture, there's a main shareable library
84$! creator, which is called from the main code above.
85$! The creator will define a number of variables to tell the next levels of
86$! subroutines what routines to use to write to the option files, call the
87$! main processor, read_func_num, and when that is done, it will write version
88$! data at the end of the .opt file, close it, and link the library.
89$!
90$! read_func_num reads through a .num file and calls the writer routine for
91$! each line.  It's also responsible for checking that order is properly kept
92$! in the .num file, check that each line applies to VMS and the architecture,
93$! and to fill in "holes" with dummy entries.
94$!
95$! The creator routines depend on the following variables:
96$! libnum	The name of the .num file to use as input
97$! libolb	The name of the object library to build from
98$! libid	The identification string of the shareable library
99$! libopt	The name of the .opt file to write
100$! libtit	The title of the assembler transfer vector file (VAX only)
101$! libmar	The name of the assembler transfer vector file (VAX only)
102$! libmap	The name of the map file to write
103$! libgoal	The name of the shareable library to write
104$! libref	The name of a shareable library to link in
105$!
106$! read_func_num depends on the following variables from the creator:
107$! libwriter	The name of the writer routine to call for each .num file line
108$! -----
109$
110$! ----- Subroutines for non-VAX
111$! -----
112$! The creator routine
113$ create_nonvax_shr:
114$   open/write opt 'libopt'
115$   write opt "identification=""",libid," ",libverstr,""""
116$   write opt libolb,"/lib"
117$   if libref .nes. "" then write opt libref,"/SHARE"
118$   write opt "SYMBOL_VECTOR=(-"
119$   libfirstentry := true
120$   libwrch   := opt
121$   libwriter := write_nonvax_transfer_entry
122$   textcount = 0
123$   gosub read_func_num
124$   write opt ")"
125$   write opt "GSMATCH=",libvmatch,",",libver
126$   close opt
127$   link/map='libmap'/full/share='libgoal' 'libopt'/option
128$   return
129$
130$! The record writer routine
131$ write_nonvax_transfer_entry:
132$   if libentry .eqs. ".dummy" then return
133$   if info_kind .eqs. "VARIABLE"
134$   then
135$     pr:=DATA
136$   else
137$     pr:=PROCEDURE
138$   endif
139$   textcount_this = f$length(pr) + f$length(libentry) + 5
140$   if textcount + textcount_this .gt. 1024
141$   then
142$     write opt ")"
143$     write opt "SYMBOL_VECTOR=(-"
144$     textcount = 16
145$     libfirstentry := true
146$   endif
147$   if libfirstentry
148$   then
149$     write 'libwrch' "    ",libentry,"=",pr," -"
150$   else
151$     write 'libwrch' "    ,",libentry,"=",pr," -"
152$   endif
153$   libfirstentry := false
154$   textcount = textcount + textcount_this
155$   return
156$
157$! ----- Subroutines for VAX
158$! -----
159$! The creator routine
160$ create_vax_shr:
161$   open/write mar 'libmar'
162$   type sys$input:/out=mar:
163;
164; Transfer vector for VAX shareable image
165;
166$   write mar "	.TITLE ",libtit
167$   write mar "	.IDENT /",libid,"/"
168$   type sys$input:/out=mar:
169;
170; Define macro to assist in building transfer vector entries.  Each entry
171; should take no more than 8 bytes.
172;
173	.MACRO FTRANSFER_ENTRY routine
174	.ALIGN QUAD
175	.TRANSFER routine
176	.MASK	routine
177	JMP	routine+2
178	.ENDM FTRANSFER_ENTRY
179;
180; Place entries in own program section.
181;
182$   write mar "	.PSECT $$",libvec,",QUAD,PIC,USR,CON,REL,LCL,SHR,EXE,RD,NOWRT"
183$   write mar libvec,"_xfer:"
184$   libwrch   := mar
185$   libwriter := write_vax_ftransfer_entry
186$   gosub read_func_num
187$   type sys$input:/out=mar:
188;
189; Allocate extra storage at end of vector to allow for expansion.
190;
191$   write mar "	.BLKB 32768-<.-",libvec,"_xfer>	; 64 pages total."
192$!   libwriter := write_vax_vtransfer_entry
193$!   gosub read_func_num
194$   write mar "	.END"
195$   close mar
196$   open/write opt 'libopt'
197$   write opt "identification=""",libid," ",libverstr,""""
198$   write opt libobj
199$   write opt libolb,"/lib"
200$   if libref .nes. "" then write opt libref,"/SHARE"
201$   type sys$input:/out=opt:
202!
203! Ensure transfer vector is at beginning of image
204!
205CLUSTER=FIRST
206$   write opt "COLLECT=FIRST,$$",libvec
207$   write opt "GSMATCH=",libvmatch,",",libver
208$   type sys$input:/out=opt:
209!
210! make psects nonshareable so image can be installed.
211!
212PSECT_ATTR=$CHAR_STRING_CONSTANTS,NOWRT
213$   libwrch   := opt
214$   libwriter := write_vax_psect_attr
215$   gosub read_func_num
216$   close opt
217$   macro/obj='libobj' 'libmar'
218$   link/map='libmap'/full/share='libgoal' 'libopt'/option
219$   return
220$
221$! The record writer routine for VAX functions
222$ write_vax_ftransfer_entry:
223$   if info_kind .nes. "FUNCTION" then return
224$   if libentry .eqs ".dummy"
225$   then
226$     write 'libwrch' "	.BLKB 8" ! Dummy is zeroes...
227$   else
228$     write 'libwrch' "	FTRANSFER_ENTRY ",libentry
229$   endif
230$   return
231$! The record writer routine for VAX variables (should never happen!)
232$ write_vax_psect_attr:
233$   if info_kind .nes. "VARIABLE" then return
234$   if libentry .eqs ".dummy" then return
235$   write 'libwrch' "PSECT_ATTR=",libentry,",NOSHR"
236$   return
237$
238$! ----- Common subroutines
239$! -----
240$! The .num file reader.  This one has great responsability.
241$ read_func_num:
242$   open libnum 'libnum'
243$   goto read_nums
244$
245$ read_nums:
246$   libentrynum=0
247$   liblastentry:=false
248$   entrycount=0
249$   loop:
250$     read/end=loop_end/err=loop_end libnum line
251$     entrynum=f$int(f$element(1," ",f$edit(line,"COMPRESS,TRIM")))
252$     entryinfo=f$element(2," ",f$edit(line,"COMPRESS,TRIM"))
253$     curentry=f$element(0," ",f$edit(line,"COMPRESS,TRIM"))
254$     info_exist=f$element(0,":",entryinfo)
255$     info_platforms=","+f$element(1,":",entryinfo)+","
256$     info_kind=f$element(2,":",entryinfo)
257$     info_algorithms=","+f$element(3,":",entryinfo)+","
258$     if info_exist .eqs. "NOEXIST" then goto loop
259$     truesum = 0
260$     falsesum = 0
261$     negatives = 1
262$     plat_i = 0
263$     loop1:
264$       plat_entry = f$element(plat_i,",",info_platforms)
265$       plat_i = plat_i + 1
266$       if plat_entry .eqs. "" then goto loop1
267$       if plat_entry .nes. ","
268$       then
269$         if f$extract(0,1,plat_entry) .nes. "!" then negatives = 0
270$         if f$getsyi("CPU") .lt. 128
271$         then
272$           if plat_entry .eqs. "EXPORT_VAR_AS_FUNCTION" then -
273$             truesum = truesum + 1
274$           if plat_entry .eqs. "!EXPORT_VAR_AS_FUNCTION" then -
275$             falsesum = falsesum + 1
276$         endif
277$!
278$         if ((plat_entry .eqs. "VMS") .or. -
279            (arch_vax .and. (plat_entry .eqs. "VMSVAX"))) then -
280            truesum = truesum + 1
281$!
282$         if ((plat_entry .eqs. "!VMS") .or. -
283            (arch_vax .and. (plat_entry .eqs. "!VMSVAX"))) then -
284            falsesum = falsesum + 1
285$!
286$	  goto loop1
287$       endif
288$     endloop1:
289$!DEBUG!$     if info_platforms - "EXPORT_VAR_AS_FUNCTION" .nes. info_platforms
290$!DEBUG!$     then
291$!DEBUG!$       write sys$output line
292$!DEBUG!$       write sys$output "        truesum = ",truesum,-
293$!DEBUG!		", negatives = ",negatives,", falsesum = ",falsesum
294$!DEBUG!$     endif
295$     if falsesum .ne. 0 then goto loop
296$     if truesum+negatives .eq. 0 then goto loop
297$     alg_i = 0
298$     loop2:
299$       alg_entry = f$element(alg_i,",",info_algorithms)
300$	alg_i = alg_i + 1
301$       if alg_entry .eqs. "" then goto loop2
302$       if alg_entry .nes. ","
303$       then
304$         if alg_entry .eqs. "KRB5" then goto loop ! Special for now
305$	  if alg_entry .eqs. "STATIC_ENGINE" then goto loop ! Special for now
306$         if f$trnlnm("OPENSSL_NO_"+alg_entry) .nes. "" then goto loop
307$	  goto loop2
308$       endif
309$     endloop2:
310$     if info_platforms - "EXPORT_VAR_AS_FUNCTION" .nes. info_platforms
311$     then
312$!DEBUG!$     write sys$output curentry," ; ",entrynum," ; ",entryinfo
313$     endif
314$   redo:
315$     next:=loop
316$     tolibentry=curentry
317$     if libentrynum .ne. entrynum
318$     then
319$       entrycount=entrycount+1
320$       if entrycount .lt. entrynum
321$       then
322$!DEBUG!$         write sys$output "Info: entrycount: ''entrycount', entrynum: ''entrynum' => 0"
323$         tolibentry=".dummy"
324$         next:=redo
325$       endif
326$       if entrycount .gt. entrynum
327$       then
328$         write sys$error "Decreasing library entry numbers!  Can't continue"
329$         write sys$error """",line,""""
330$         close libnum
331$         return
332$       endif
333$       libentry=tolibentry
334$!DEBUG!$       write sys$output entrycount," ",libentry," ",entryinfo
335$       if libentry .nes. "" .and. libwriter .nes. "" then gosub 'libwriter'
336$     else
337$       write sys$error "Info: ""''curentry'"" is an alias for ""''libentry'"".  Overriding..."
338$     endif
339$     libentrynum=entrycount
340$     goto 'next'
341$   loop_end:
342$   close libnum
343$   return
344$
345$! The version number reader
346$ read_version_info:
347$   libver = ""
348$   open/read vf [.CRYPTO]OPENSSLV.H
349$   loop_rvi:
350$     read/err=endloop_rvi/end=endloop_rvi vf rvi_line
351$     if rvi_line - "SHLIB_VERSION_NUMBER """ .eqs. rvi_line then -
352	goto loop_rvi
353$     libverstr = f$element(1,"""",rvi_line)
354$     libvmajor = f$element(0,".",libverstr)
355$     libvminor = f$element(1,".",libverstr)
356$     libvedit = f$element(2,".",libverstr)
357$     libvpatch = f$cvui(0,8,f$extract(1,1,libvedit)+"@")-f$cvui(0,8,"@")
358$     libvedit = f$extract(0,1,libvedit)
359$     libver = f$string(f$int(libvmajor)*100)+","+-
360	f$string(f$int(libvminor)*100+f$int(libvedit)*10+f$int(libvpatch))
361$     if libvmajor .eqs. "0"
362$     then
363$       libvmatch = "EQUAL"
364$     else
365$       ! Starting with the 1.0 release, backward compatibility should be
366$       ! kept, so switch over to the following
367$       libvmatch = "LEQUAL"
368$     endif
369$   endloop_rvi:
370$   close vf
371$   return
372