File: v5cbsu.m

package info (click to toggle)
fis-gtm 6.3-007-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 36,284 kB
  • sloc: ansic: 328,861; asm: 5,182; csh: 5,102; sh: 1,918; awk: 291; makefile: 69; sed: 13
file content (333 lines) | stat: -rwxr-xr-x 12,768 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;								;
	;	Copyright 2005, 2010 Fidelity Information Services, Inc	;
	;								;
	;	This source code contains the intellectual property	;
	;	of its copyright holder(s), and is made available	;
	;	under a license.  If you do not know the terms of	;
	;	the license, please stop and do not read further.	;
	;								;
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;
	; If invoked as "mumps -run v5cbsu", this is the V5 Certify Block Split Utility
	;	Reads scan phase output file from DBCERTIFY and processes level-0 GVT blocks.
	;	Rewrites the scan phase output file minus those blocks.
	;
	; If invoked as "mumps -run dump^v5cbsu", this is the DBCERTSCAN file dump utility.
	;	Reads scan phase output file from DBCERTIFY and prints the contents of the
	;	records that it finds. Does not touch the database or the scan file.
	;	Only dumps the contents.
	; On OpenVMS, "define gtm_v5cbsu dump" to invoke the dump utility.
	;
	; On OpenVMS, "define gtm_v5cbsu fix512" to remove zero padding
	; which may have been added during dbcertify scan runs on some
	; OpenVMS 7.3-1 systems.  This produces an output file with a
	; suffix of _FIX512 to be used as input to v5cbsu (after
	; deassigning gtm_v5cbsu) or dbcertify certify.  Both "dump" and
	; "fix512" can be specified in the value of gtm_v5cbsu for the same run.
	;
	; Note that our input and output files contain binary data in the file and
	; record headers. GT.M I/O does not deal with this type of data well so these binary
	; stream files are treated as fixed record length files so far as GT.M is concerned
	; and we do our own buffering of the read and write IOs. This is basically the same
	; approach that GDE uses.
	;
	; If additional M utility routines are used by V5CBSU.m, remember
	; to modify the gtmdckitinstal.com section which creates GTMDCBUILD.COM
	; and any OpenVMS test system scripts which link V5CBSU.
	;
v5cbsu
	If ($data(dumpmode)=0) set dumpmode=0
	Set p1outfile=$ZCMDLINE
	If p1outfile="" Use $P Write "Must specify the name of the SCAN phase output file",! Halt
	D init
	Do doopen(.p1outfile,readflg)
	D readp1hd
	If p1tag'=p1tagread  Do  Quit
	. Use $P
	. Write "%GTM-E-DBCBADFILE, Source file ",p1outfile
	. Write " does not appear to have been generated by DBCERTIFY SCAN - rerun SCAN or specify correct file",!
	set quitnow=0
	If 'dumpmode&'fix512mode  Do  If quitnow Quit
	. If (0=gvtleafc) Use $P Write "There are no GVT leaf (level 0) blocks to process in this database",! Set quitnow=1 Quit
	. If (version="V4.4-004")!(version]"V4.4-004") View "GVDUPSETNOOP":0
	. Set dbfname=$View("GVFILE",regnameP)
	. If dbfnP'=dbfname  Do  Quit
	. . Use $P
	. . Write "Database for region ",regnameP,"(",dbfname,") does not match the recorded name from the scan phase (",dbfnP,")",!
	. . Set quitnow=1
	. ;
	. ; Process the input file. Any records we do not handle are rewritten to tmpfile1.
	. ;
	. Do doopen(.tmpfile1,writeflg)
	. Set outrecs=0,byprecs=0,prorecs=0,releaf=0
	If fix512mode Do
	. Set tmpfile1=p1outfile_"_FIX512"	; File without zero padding
	. Use $P Write "V5CBSU: FIX512 mode, use "_tmpfile1_" for real v5cbsu or dbcertify certify input",!
	. Do doopen(.tmpfile1,writeflg)
	. Do dowrite(.tmpfile1,p1hdr)	; copy header as is
	If dumpmode Do
	. Use $P
	. Write !!,"Database referenced: ",dbfnP,!
	. ;
	. ; Process the input file.
	. ;
	. Write "  BlkNum   BlkType    BlkLevl   BlkKey",!!
	For rec=1:1:blkcnt Do
	. If $TLevel Use $P Zshow "*" Write "V5CBSU - GTMASSERT: $TLEVEL non zero at top of processing loop",! Halt
	. Do readp1rc(.p1outfile)
	. If dumpmode Do
	. . Use $P
	. . Write $$FUNC^%DH(blknum,8),"   ",blktypes(blktype)," ",$J(blklevl,6),"   "
	. . If akeylen'=0 Write reckey
	. . Write !
	. If fix512mode Do
	. . Set p1rec=p1rec_reckey
	. . Do dowrite(.tmpfile1,p1rec)		; copy record header and key
	. If 'dumpmode&'fix512mode Do
	. . TStart ():TRANSACTION="BATCH" ; BATCH needed to avoid hardening wait in case of journaling
	. . Set processed=0
	. . If ""'=reckey Do
	. . . Set exist=$DATA(@reckey)
	. . . If (1=exist)!(11=exist) Set value=$Get(@reckey) Set @reckey=value  Set processed=1
	. . TCommit
	. . If processed=1 Set prorecs=prorecs+1
	. . Else  Do
	. . . If ""'=reckey Set byprecs=byprecs+1  Set p1rec=p1rec_reckey
	. . . Do dowrite(.tmpfile1,p1rec)
	. . . Set outrecs=outrecs+1
	. . . If gvtleaf=blktype Set releaf=releaf+1	; This is a leaf block we did not process
	;
	; If in dump    mode, close input file and we are done.
	; If in fix512  mode, close input and output file and we are done.
	; If in regular mode, close input and output file. Also open new output file
	;	that will include the fileheader with the correct record count
	;
	Do doclose(.p1outfile)
	If dumpmode&'fix512mode quit
	Do doclose(.tmpfile1)
	If fix512mode Quit
	Set newp1hdr=p1tag_$$num2bin(hdrtn)_$$num2bin(outrecs)_$$num2bin(totblks)_$$num2bin(dtleafc)_$$num2bin(dtindxc)
	Set newp1hdr=newp1hdr_$$num2bin(releaf)_$$num2bin(gvtindxc)_regname_$Char(0)_dbfn_$Char(0)_$$num2bin(uidlen)_uniqueid
	Set $Piece(hdrpad,$C(0),33-$Length(uniqueid)+filBufSz-360)="" ; create zero padding of correct length to fill fixed size hdr
	Set newp1hdr=newp1hdr_hdrpad
	If $Length(newp1hdr)'=p1hdrlen  Do
	. Use $P
	. Zshow "*"
	. Write "V5CBSU - GTMASSERT: New fileheader not expected size. Size is ",$Length(newp1hdr)," - Expecting ",p1hdrlen,!
	. Halt
	Do doopen(.tmpfile1,readflg)
	Do doopen(.tmpfile2,writeflg)
	Do dowrite(.tmpfile2,newp1hdr)
	For recs=1:1:outrecs Do
	. Do readp1rc(.tmpfile1)
	. If ""'=reckey Set p1rec=p1rec_reckey
	. Do dowrite(.tmpfile2,p1rec)
	;
	; New version of dbcertp1 file is written to tmpfile2. Close both files and effect the proper name change.
	;
	Do doclose(.tmpfile1)
	Do doclose(.tmpfile2)
	If VMS Set rename="RENAME" Set renamever=";" Set delete="DELETE" Set delver=".*"
	Else   Set rename="mv"     Set renamever=""  Set delete="rm -f"  Set delver=""
	If 'VMS ZSystem delete_" "_p1outfile_"_orig"	; in VMS multiple versions would be automatically created
	ZSystem rename_" "_p1outfile_renamever_" "_p1outfile_"_orig"_renamever
	ZSystem rename_" "_tmpfile2_renamever_" "_p1outfile_renamever
	ZSystem delete_" "_tmpfile1_delver

	Use $P
	Write "Scan phase records read:      ",blkcnt,!
	Write "Scan phase records bypassed:  ",byprecs,!
	Write "Scan phase records processed: ",prorecs,!
	Write "Scan phase records left:      ",outrecs,!
	Quit

	;
	; Entry point for DUMP mode operation (dump contents of scan file)
	;
dump	;
	set dumpmode=1
	Do v5cbsu
	quit

	;
	; Read in scan phase file header
	;
readp1hd
	Set p1hdr=$$doread(.p1outfile,p1hdrlen)
	Set p1tagread=$Extract(p1hdr,1,8)
	Set hdrtn=$$bin2num($Extract(p1hdr,9,12))
	Set blkcnt=$$bin2num($Extract(p1hdr,13,16))
	Set totblks=$$bin2num($Extract(p1hdr,17,20))
	Set dtleafc=$$bin2num($Extract(p1hdr,21,24))
	Set dtindxc=$$bin2num($Extract(p1hdr,25,28))
	Set gvtleafc=$$bin2num($Extract(p1hdr,29,32))
	Set gvtindxc=$$bin2num($Extract(p1hdr,33,36))
	Set regname=$Extract(p1hdr,37,67)
	; 1 byte of filler we don't care about
	Set dbfn=$Extract(p1hdr,69,323)
	; 1 byte of filler we don't care about
	Set uidlen=$$bin2num($Extract(p1hdr,325,328))
	; Size of field  varys (by platform) length unique id fields (we don't process them)
	Set uniqueid=$Extract(p1hdr,329,329+uidlen-1)
	; Eliminate trailing nulls
	Set regnameP=$Piece(regname,$Char(0),1)
	Set dbfnP=$Piece(dbfn,$Char(0),1)
	; Now that we have a region name, define our temps with regname embedded
	Set tmpfile1="dbcertp1"_regnameP_".tmp1"
	Set tmpfile2="dbcertp1"_regnameP_".tmp2"
	Quit

	;
	; Read in scan phase record (fixed size with optional varying length ascii key following)
	;
readp1rc(outfile)
	Set p1rec=$$doread(.outfile,p1reclen)
	Set tn=$$bin2num($Extract(p1rec,1,4))
	Set blknum=$$bin2num($Extract(p1rec,5,8))
	Set blktype=$$bin2num($Extract(p1rec,9,12))
	Set blklevl=$$bin2num($Extract(p1rec,13,16))
	Set akeylen=$$bin2num($Extract(p1rec,17,20))
	If fix512mode Do
	. Set padnum=filBufSz-p1reclen
	. Set nulls=$$doread(.outfile,padnum)
	. If $Length(nulls,$Char(0))'=(padnum+1) Do
	. . Use $P ZShow "*"
	. . Write "V5CSBU - GTMASSERT: FIX512: No padding when expected after record header",!
	. . Halt
	If (blktype=gvtleaf)&(0'=akeylen) Do
	. Set reckey=$$doread(.outfile,akeylen)
	. If fix512mode Do
	. . Set padnum=filBufSz-akeylen
	. . Set nulls=$$doread(.outfile,padnum)
	. . If $Length(nulls,$Char(0))'=(padnum+1) Do
	. . . Use $P ZShow "*"
	. . . Write "V5CSBU - GTMASSERT: FIX512: No padding when expected after key",!
	. . . Halt
	Else  Do
	.	Set reckey=""
	.	If (0'=akeylen)  do
	.	.	Use $P ZShow "*"
	.	.	Write "V5CBSU - GTMASSERT: Error with non-zero akeylen for non-gvtleaf record",!
	.	.	Halt
	Quit

	;
	; Open given file (1st arg MUST be passed by refence) in read or write mode according to flag. Record flag
	; in file(1) so close knows whether to flush buffer or not. Buffer for this file is kept in file(2)
	;
doopen(file,readflag)
	Set file(1)=readflag
	new chsetstr
	set chsetstr=$SELECT($ZV["OS390":":chset=""BINARY""",1:"")
	If readflag Open file:@("(Readonly:Fixed"_chsetstr_":RecordSize="_filBufSz_":Blocksize="_filBufSz_")")
	Else        Open file:@("(New:Fixed"_chsetstr_":RecordSize="_filBufSz_":Blocksize="_filBufSz_")")
	Set file(2)=""	; Buffer for this file
	Quit

	;
	; Read given length from given file. Buffer is kept in file(2). We are rebuffering filBufSz byte fixed records
	; at the real IO level for the reasons described in the module header.
	;
doread(file,len)
	New rec,br
	; A record with ZWR format key can be very long indeed so read more than enough blocks to cover that
	; possibility. The max is higher than needs to be but satisfies criteria of not leaving the loop unbounded.
	For br=1:1:mxzwrxpr Quit:$Length(file(2))'<len  Do
	. Use file
	. Read rec#filBufSz
	. Set file(2)=file(2)_rec
	If br'<10 Use $P Zshow "*" Write !!,"V5CBSU - GTMASSERT: Read length exceeds buffer length",! Halt
	Set rec=$Extract(file(2),1,len)
	Set file(2)=$Extract(file(2),len+1,mxrecsln)
	Quit rec

	;
	; Write data to given file. If length of buffer (in file(2)) does not exceed filBufSz bytes
	; after the write, no real write is made.
	;
dowrite(file,data)
	New rec
	Set file(2)=file(2)_data
	If ($Length(file(2))<filBufSz) Quit  ; Return
	; Write filBufSz byte chunk of data
	Use file
	Set rec=$Extract(file(2),1,filBufSz)
	Write rec
	Set file(2)=$Extract(file(2),513,mxrecsln)
	Quit

	;
	; Close given file and flush its output buffer if necessary
	;
doclose(file)
	If writeflg=file(1) Do
	. ; File was opened for write so flush buffer before we close file
	. Use file
	. Write file(2)
	Close file
	Quit

	;
	; Initialize arrays and such we will be using
	;
init
	Set FALSE=0
	Set TRUE=1
	Set readflg=1
	Set writeflg=0
	Set endian("AXP")=FALSE
	Set endian("x86")=FALSE
	Set endian("x86_64")=FALSE
	Set endian("HP-PA")=TRUE
	Set endian("IA64/B")=TRUE
	Set endian("IA64/L")=FALSE
	Set endian("SPARC")=TRUE
	Set endian("RS6000")=TRUE
	Set endian("S390")=TRUE
	Set endian("S390X")=TRUE
	Set endian=endian($Piece($ZVersion," ",4))
	Set HEX(0)=1
	For x=1:1:8 Set HEX(x)=HEX(x-1)*16
	Set VMS=$ZVersion["VMS"
	Set gvtleaf=5		; gdsblk_gvtleaf - defined in dbcertify.h
	Set blktypes(1)="GVT-Generic"
	Set blktypes(2)="DT-Generic "
	Set blktypes(3)="GVT-Root   "
	Set blktypes(4)="GVT-Index  "
	Set blktypes(5)="GVT-Leaf   "
	Set blktypes(6)="DT-Root    "
	Set blktypes(7)="DT-Index   "
	Set blktypes(8)="DT-Leaf    "
	Set blktypes(9)="Bitmap     "
	Set version=$Piece($ZVersion," ",2)
	Set p1hdrlen=512	; p1hdr struct defined in dbcertify.h
	Set p1reclen=20		; p1rec struct defined in dbcertify.h
	Set p1tag="GTMDBC01"	; P1HDR_TAG define in dbcertify.h
	Set filBufSz=p1hdrlen	; Real IO is done at this buffer size. Should coicide with size of header
	Set mxzwrxpr=10		; MAX_ZWR_EXP_RATIO - key can (in actuality) be much larger when using $C() notation
	Set mxrecsln=filBufSz*mxzwrxpr ; Rather than use 99999 for max rec len, use blocksize * MAX_ZWR_EXP_RATIO
	If ($data(fix512mode)=0) Set fix512mode=0	; Flag to fixup OpenVMS 7.3-1 CRTL problem
	If VMS Do
	. Set vmsflags=$ZTRNLNM("GTM_V5CBSU")
	. Set vmsflags=$$FUNC^%UCASE(vmsflags)
	. If vmsflags["FIX512" Set fix512mode=1
	. If vmsflags["DUMP" Set dumpmode=1
	Quit

	;
	; Conversion routine - binary number from file to GT.M usable number
	;
bin2num:(bin)
	New num,i
	Set num=0
	If endian=TRUE For i=$l(bin):-1:1 Set num=$Ascii(bin,i)*HEX($Length(bin)-i*2)+num
	Else  For i=1:1:$l(bin) Set num=$Ascii(bin,i)*HEX(i-1*2)+num
	Quit num

	;
	; Conversion routine - GT.M number to binary (4 byte) number for file
	;
num2bin:(num)
	If endian=TRUE Quit $Char(num/16777216,num/65536#256,num/256#256,num#256)
	Quit $Char(num#256,num/256#256,num/65536#256,num/16777216)