[796] | 1 | TMGPAT3 ;TMG/kst/Patching tools ;09/17/08
|
---|
| 2 | ;;1.0;TMG-LIB;**1**;09/17/08
|
---|
| 3 | ;
|
---|
| 4 | ;"Kevin Toppenberg MD
|
---|
| 5 | ;"GNU General Public License (GPL) applies
|
---|
| 6 | ;"9/26/08
|
---|
| 7 |
|
---|
| 8 | ;"=======================================================================
|
---|
| 9 | ;" API -- Public Functions.
|
---|
| 10 | ;"=======================================================================
|
---|
| 11 | ;"NEWPACK -- Install a new package from ftp server.
|
---|
| 12 | ;"CONSOLE --show how many patches for a package are available and have not been installed yet
|
---|
| 13 | ;"RESCAN -- show how many patches for a package are available and have not been installed yet
|
---|
| 14 | ;"ShowPatches(PckInit,Ver) -- show installed patches, using scroll box.
|
---|
| 15 | ;"EditNotes -- launch an editor for editing notes about patching.
|
---|
| 16 |
|
---|
| 17 | ;"=======================================================================
|
---|
| 18 | ;"Private Functions
|
---|
| 19 | ;"=======================================================================
|
---|
| 20 | ;"PrepAvail(pArray,Option) -- prepair an array with patch status, for use with Scroller^TMGUSRIF
|
---|
| 21 | ;"HndOnSel(pArray,Option,Info) -- handle ON SELECT event from Scroller^TMGUSRIF
|
---|
| 22 | ;"HndOnCmd(pArray,Option,Info) -- handle ON SELECT event from Scroller
|
---|
| 23 | ;"StoreMissing(PckInit,pArray) store the list of missing patches with the pending patches
|
---|
| 24 | ;"DownPck(PatchName,Option,Msg) -- Given a package name, ensure all pending patches are local.
|
---|
| 25 | ;"$$Rpt1Avail^TMGPAT3(PatchName)
|
---|
| 26 | ;"$$RptAvail^TMGPAT3(PckInit)
|
---|
| 27 | ;"Scan4New(MaxDays,Option) -- scan all packages and determine how many patches are pending for each
|
---|
| 28 | ;"Scan41(PckInit,MaxDays,Option) -- scan one package and determine how many patches are pending
|
---|
| 29 | ;"Scan41a1Ver(PckInit,Ver,MaxDays,Option) -- scan one package and determine how many patches are pending
|
---|
| 30 | ;"GetNew(PckInit,Ver,pArray,RefreshNeeded,Option) -- Get array of **just** patches still to be installed for a given package/version
|
---|
| 31 | ;"GetAvail(PckInit,Ver,pArray,RefreshNeeded,Option) -- return array of all patches for a given package/version
|
---|
| 32 | ;"GetPList(PckInit,Ver,pArray) -- get a list of applied patches, from PACKAGE file, into Array
|
---|
| 33 | ;"PrepPatchList(PckInit,Ver,pShowArray,ByPatchNum) -- prepair the patch list for display in scroll box.
|
---|
| 34 | ;"HndOnPCmd(pArray,Option,Info) -- handle ON SELECT event from Scroller
|
---|
| 35 | ;"ShowAvail -- Show data that tallies the available patches.
|
---|
| 36 | ;"IncLineCt(lineCount,pageLen)
|
---|
| 37 | ;"=======================================================================
|
---|
| 38 | ;"=======================================================================
|
---|
| 39 |
|
---|
| 40 | ;"NOTE: This Module should be re-written. Rather than store the data in the global ^TMG(...
|
---|
| 41 | ;" the Fileman file 22709 should be used. As it is now, it is a duplication of organization.
|
---|
| 42 |
|
---|
| 43 | NEWPACK
|
---|
| 44 | ;"Purpose: Install a new package from ftp server.
|
---|
| 45 |
|
---|
| 46 | new %,DIR,PckInit,Ver,X,Y,Msg
|
---|
| 47 |
|
---|
| 48 | do Logo^TMGPAT1
|
---|
| 49 | set %=1
|
---|
| 50 | write "Install a NEW PACKAGE from ftp.va.gov" do YN^DICN write !
|
---|
| 51 | if %'=1 goto NPDone
|
---|
| 52 | set DIR(0)="F^2:4"
|
---|
| 53 | set DIR("A")="Enter PACKAGE prefix (? for help)"
|
---|
| 54 | set DIR("?")="Enter Namespace initials."
|
---|
| 55 | set DIR("?",1)="Enter namespace package prefix initials."
|
---|
| 56 | set DIR("?",2)="E.g. for Fileman, enter: DI"
|
---|
| 57 | set DIR("?",3)="Enter ^ to abort."
|
---|
| 58 | do ^DIR write ! ;"results in X and Y
|
---|
| 59 | if Y="^" goto NPDone
|
---|
| 60 | set PckInit=Y
|
---|
| 61 |
|
---|
| 62 | new Array,result
|
---|
| 63 | write "Fetching info from VA ftp server..."
|
---|
| 64 | set result=$$GetPckList^TMGKERNL(PckInit,.Array)
|
---|
| 65 | write " Done.",!
|
---|
| 66 | if result=0 goto NPDone
|
---|
| 67 | new IEN9d4 set IEN9d4=+$order(^DIC(9.4,"C",PckInit,""))
|
---|
| 68 | if IEN9d4'>0 do goto NPDone
|
---|
| 69 | . do AddMsg^TMGPAT2("Can't find PACKAGE named '"_PckInit_"'",1,.Msg)
|
---|
| 70 |
|
---|
| 71 | NPDone
|
---|
| 72 | if $$ShowMsg^TMGPAT2(.Msg)
|
---|
| 73 | write "Goodbye.",!
|
---|
| 74 | quit
|
---|
| 75 |
|
---|
| 76 | ;"====================================================================
|
---|
| 77 |
|
---|
| 78 | CONSOLE
|
---|
| 79 | new Array,Option
|
---|
| 80 | do PrepAvail("Array",.Option)
|
---|
| 81 | set Option("FOOTER",1,1)="^ Exit"
|
---|
| 82 | set Option("FOOTER",1,2)="? Help"
|
---|
| 83 | set Option("FOOTER",1,3)="[F1] SHOW Compl"
|
---|
| 84 | set Option("FOOTER",1,4)="[F3] Hx"
|
---|
| 85 | set Option("FOOTER",1,5)="[F4] Downld Pak"
|
---|
| 86 | set Option("FOOTER",1,6)="[F5] Notes"
|
---|
| 87 | set Option("FOOTER",1,7)="[F6] Add Waiting"
|
---|
| 88 | set Option("ON SELECT")="HndOnSel^TMGPAT3"
|
---|
| 89 | set Option("ON CMD")="HndOnCmd^TMGPAT3"
|
---|
| 90 | write #
|
---|
| 91 | do Scroller^TMGUSRIF("Array",.Option)
|
---|
| 92 | quit
|
---|
| 93 |
|
---|
| 94 | PrepAvail(pArray,Option)
|
---|
| 95 | ;"Purpose: To prepair an array with patch status, for use with Scroller^TMGUSRIF
|
---|
| 96 | ;"Input: pArray -- PASS BY NAME. Array to put info into. Prior data is killed.
|
---|
| 97 | ;" Option -- PASS BY REFERENCE. Prior data is NOT killed. See Scroller^TMGUSRIF for details
|
---|
| 98 | ;" Option("HIDE EMPTY")=0 OPTIONAL. Default is 0. If 1 then, entries with no patches.
|
---|
| 99 | ;" Also-- Uses global variable...
|
---|
| 100 | ;" ^TMG("KIDS","PENDING PATCHES",PackageInitials,Version)=Count
|
---|
| 101 | ;" ^TMG("KIDS","PENDING PATCHES",PackageInitials,Version,"DATE REFRESHED")=Last date server checked.
|
---|
| 102 | ;" ^TMG("KIDS","PENDING PATCHES",PackageInitials,Version,"PATCHES",######)=AAAA*NN.NN*NNNN SEQ #1234"
|
---|
| 103 | ;" ^TMG("KIDS","PENDING PATCHES",PackageInitials,Version,"PATCHES",######)=AAAA*NN.NN*NNNN SEQ #1234"
|
---|
| 104 | ;" ^TMG("KIDS","PENDING PATCHES",PackageInitials,"FULL NAME")=Package name
|
---|
| 105 | ;"Results: None
|
---|
| 106 |
|
---|
| 107 | set pArray=$get(pArray) goto:(pArray="") pAvDone
|
---|
| 108 | kill @pArray
|
---|
| 109 | new Hinder,Blocked
|
---|
| 110 | new oneLine,lineCt set lineCt=1
|
---|
| 111 | new PckInit set PckInit=""
|
---|
| 112 | new grandTotal set grandTotal=0
|
---|
| 113 | new hideEmpty set hideEmpty=$get(Option("HIDE EMPTY"),1)
|
---|
| 114 | for set PckInit=$order(^TMG("KIDS","PENDING PATCHES",PckInit)) quit:(PckInit="") do
|
---|
| 115 | . new total set total=0
|
---|
| 116 | . new Ver set Ver=""
|
---|
| 117 | . new PackageName set PackageName=$get(^TMG("KIDS","PENDING PATCHES",PckInit,"FULL NAME"))
|
---|
| 118 | . for set Ver=$order(^TMG("KIDS","PENDING PATCHES",PckInit,Ver)) quit:(+Ver'>0) do
|
---|
| 119 | . . set total=total+$get(^TMG("KIDS","PENDING PATCHES",PckInit,Ver))
|
---|
| 120 | . set grandTotal=grandTotal+total
|
---|
| 121 | . if (total=0)&(hideEmpty=1) quit
|
---|
| 122 | . set oneLine="("_PckInit_") "_PackageName_" "
|
---|
| 123 | . set oneLine=$$LJ^XLFSTR($extract(oneLine,1,40),40)_"--> "_$$RJ^XLFSTR(total,3)_" patches. "
|
---|
| 124 | . new tempArray,current,maxVer
|
---|
| 125 | . set maxVer=0,Ver="",current=""
|
---|
| 126 | . for set Ver=$order(^TMG("KIDS","PENDING PATCHES",PckInit,Ver)) quit:(+Ver'>0) do
|
---|
| 127 | . . if Ver'>maxVer quit
|
---|
| 128 | . . new temp set temp=$$GetLastPackage^TMGPAT1(PckInit,Ver)
|
---|
| 129 | . . if temp'="" set maxVer=Ver,current=temp
|
---|
| 130 | . set oneLine=oneLine_"Currently @ "_current
|
---|
| 131 | . set @pArray@(lineCt,oneLine)=$piece(current,"*",1,2)
|
---|
| 132 | . set lineCt=lineCt+1
|
---|
| 133 | . new i set i=""
|
---|
| 134 | . for set i=$order(^TMG("KIDS","PENDING PATCHES",PckInit,"WAITING FOR",i)) quit:(i="") do
|
---|
| 135 | . . set oneLine=" Waiting for "_i
|
---|
| 136 | . . set @pArray@(lineCt,oneLine)=$piece(i,"*",1,2)
|
---|
| 137 | . . set lineCt=lineCt+1
|
---|
| 138 | . . new init set init=$piece(i,"*",1)
|
---|
| 139 | . . set Hinder(init,PckInit)=""
|
---|
| 140 | . . set Blocked(PckInit)=1
|
---|
| 141 |
|
---|
| 142 | if '$data(Hinder) goto pAV2
|
---|
| 143 |
|
---|
| 144 | new count for count=1:1:5 do
|
---|
| 145 | . set init="" for set init=$order(Hinder(init)) quit:(init="") do
|
---|
| 146 | . . new init1,init2 set init1=init,init2=""
|
---|
| 147 | . . for set init2=$order(Hinder(init,init2)) quit:(init2="") do
|
---|
| 148 | . . . quit:(init2=init)
|
---|
| 149 | . . . merge Hinder(init,init2)=Hinder(init2)
|
---|
| 150 |
|
---|
| 151 | set @pArray@(lineCt,"--- SUMMARY ------------------------------")=""
|
---|
| 152 | set lineCt=lineCt+1
|
---|
| 153 | new spaces set $piece(spaces," ",20)=" "
|
---|
| 154 | new ref set ref="Hinder"
|
---|
| 155 | new hideArray
|
---|
| 156 | set init=""
|
---|
| 157 | for set ref=$query(@ref) quit:(ref="") do
|
---|
| 158 | . if $$OREF^DILF($query(@ref))[$$OREF^DILF(ref) quit
|
---|
| 159 | . new count,node,done set done=0
|
---|
| 160 | . for count=1:1:$qlength(ref) do quit:done
|
---|
| 161 | . . set node=$qsubscript(ref,count)
|
---|
| 162 | . . set oneLine=$select((count=1):"#",1:"")
|
---|
| 163 | . . set oneLine=oneLine_$extract(spaces,1,count*3)_"Package "_node
|
---|
| 164 | . . if (count=1)&($get(Blocked(node))=1) set done=1 quit
|
---|
| 165 | . . if count=1 set oneLine=oneLine_" is hindering..."
|
---|
| 166 | . . else if count<$qlength(ref) set oneLine=oneLine_", which is hindering..."
|
---|
| 167 | . . if $get(hideArray(count))=oneLine quit
|
---|
| 168 | . . set hideArray(count)=oneLine
|
---|
| 169 | . . set @pArray@(lineCt,oneLine)="",lineCt=lineCt+1
|
---|
| 170 |
|
---|
| 171 | pAV2 set Option("HEADER",1)="TMG Patch Helper-- "_grandTotal_" Patches to be installed in all packages."
|
---|
| 172 |
|
---|
| 173 | pAvDone
|
---|
| 174 | quit
|
---|
| 175 |
|
---|
| 176 |
|
---|
| 177 | HndOnSel(pArray,Option,Info)
|
---|
| 178 | ;"Purpose: handle ON SELECT event from Scroller^TMGUSRIF
|
---|
| 179 | ;"Input: pArray,Option,Info -- see documentation in Scroller^TMGUSRIF
|
---|
| 180 | ;" Info has this:
|
---|
| 181 | ;" Info("CURRENT LINE","NUMBER")=number currently highlighted line
|
---|
| 182 | ;" Info("CURRENT LINE","TEXT")=Text of currently highlighted line
|
---|
| 183 | ;" Info("CURRENT LINE","RETURN")=return value of currently highlighted line
|
---|
| 184 |
|
---|
| 185 | new PatchName,PckInit,Ver
|
---|
| 186 | set PatchName=$get(Info("CURRENT LINE","RETURN"))
|
---|
| 187 | do ParsePatchName^TMGPAT2(PatchName,.PckInit,.Ver)
|
---|
| 188 | if (PckInit="")&(Ver="") do goto HOSDone
|
---|
| 189 | . write "?? The line selected specify any command ??",!
|
---|
| 190 | do DONEXTPK^TMGPAT1(PckInit,Ver)
|
---|
| 191 | do PrepAvail(pArray,.Option)
|
---|
| 192 | HOSDone
|
---|
| 193 | do PressToCont^TMGUSRIF
|
---|
| 194 | write #
|
---|
| 195 | quit
|
---|
| 196 |
|
---|
| 197 |
|
---|
| 198 | HndOnCmd(pArray,Option,Info) ;"Part of TestScrl
|
---|
| 199 | ;"Purpose: handle ON SELECT event from Scroller
|
---|
| 200 | ;"Input: pArray,Option,Info -- see documentation in Scroller
|
---|
| 201 | ;" Info has this:
|
---|
| 202 | ;" Info("USER INPUT")=input
|
---|
| 203 | ;" Info("CURRENT LINE","NUMBER")=number currently highlighted line
|
---|
| 204 | ;" Info("CURRENT LINE","TEXT")=Text of currently highlighted line
|
---|
| 205 | ;" Info("CURRENT LINE","RETURN")=return value of currently highlighted line
|
---|
| 206 |
|
---|
| 207 | new input set input=$$UP^XLFSTR($get(Info("USER INPUT")))
|
---|
| 208 | if input["F2" do
|
---|
| 209 | . set Option("FOOTER",1,3)="[F1] SHOW compl"
|
---|
| 210 | . set Option("HIDE EMPTY")=1
|
---|
| 211 | else if input="RESCAN" do
|
---|
| 212 | . do RESCAN
|
---|
| 213 | else if input["F1" do
|
---|
| 214 | . set Option("FOOTER",1,3)="[F2] HIDE compl"
|
---|
| 215 | . set Option("HIDE EMPTY")=0
|
---|
| 216 | else if input["F3" do
|
---|
| 217 | . new PatchName set PatchName=$get(Info("CURRENT LINE","RETURN")) quit:(PatchName="")
|
---|
| 218 | . new PckInit,Ver
|
---|
| 219 | . do ParsePatchName^TMGPAT2(PatchName,.PckInit,.Ver)
|
---|
| 220 | . if $$ShowPatches(PckInit,Ver)
|
---|
| 221 | else if input["F4" do
|
---|
| 222 | . new PatchName set PatchName=$get(Info("CURRENT LINE","RETURN")) quit:(PatchName="")
|
---|
| 223 | . new Option set Option("VERBOSE")=1
|
---|
| 224 | . new % set %=1
|
---|
| 225 | . write "Ensure that all pending patches for ",PatchName," have been downloaded"
|
---|
| 226 | . do YN^DICN write !
|
---|
| 227 | . if %'=1 quit
|
---|
| 228 | . do DownPck(PatchName,.Option)
|
---|
| 229 | . do PressToCont^TMGUSRIF
|
---|
| 230 | else if input["F5" do
|
---|
| 231 | . do EditNotes
|
---|
| 232 | . do PressToCont^TMGUSRIF
|
---|
| 233 | else if input["F6" do ;"Add Waiting"
|
---|
| 234 | . if Info("CURRENT LINE","TEXT")'["-->" do quit
|
---|
| 235 | . . write !,"Please first select containing '-->'",!
|
---|
| 236 | . . do PressToCont^TMGUSRIF
|
---|
| 237 | . new PatchName set PatchName=$get(Info("CURRENT LINE","RETURN")) quit:(PatchName="")
|
---|
| 238 | . new PckInit set PckInit=$piece(PatchName,"*",1)
|
---|
| 239 | . new % set %=1
|
---|
| 240 | . write !,"Manually add a 'Waiting For' entry for ",PatchName
|
---|
| 241 | . do YN^DICN write !
|
---|
| 242 | . if %'=1 quit
|
---|
| 243 | . new DIR,DIRUT set DIR(0)="F",DIR("A")="Enter what "_PatchName_" is waiting for"
|
---|
| 244 | . do ^DIR write ! if $data(DIRUT) quit
|
---|
| 245 | . do AddMissing(PckInit,Y)
|
---|
| 246 | . do PressToCont^TMGUSRIF
|
---|
| 247 | else if input="NEWPACK" do
|
---|
| 248 | . do NEWPACK
|
---|
| 249 | else if input="?" do
|
---|
| 250 | . write !,"Use UP and DOWN cursor keys to select package, then ENTER to work on.",!
|
---|
| 251 | . write "Enter 'NEWPACK' to install a NEW package.",!
|
---|
| 252 | . write "Enter 'RESCAN' to rescan the ftp.va.gov server",!
|
---|
| 253 | . write "Enter ^ at the ':' prompt to quit",!
|
---|
| 254 | . do PressToCont^TMGUSRIF
|
---|
| 255 | else if input'="" do
|
---|
| 256 | . write !,"Input ",$get(Info("USER INPUT"))," not recognized.",!
|
---|
| 257 | . do PressToCont^TMGUSRIF
|
---|
| 258 |
|
---|
| 259 | do PrepAvail(pArray,.Option)
|
---|
| 260 | write #
|
---|
| 261 | quit
|
---|
| 262 |
|
---|
| 263 |
|
---|
| 264 | StoreMissing(PckInit,pArray)
|
---|
| 265 | ;"Purpose: to store the list of missing patches with the pending patches
|
---|
| 266 | kill ^TMG("KIDS","PENDING PATCHES",PckInit,"WAITING FOR")
|
---|
| 267 | merge ^TMG("KIDS","PENDING PATCHES",PckInit,"WAITING FOR")=@pArray
|
---|
| 268 | quit
|
---|
| 269 |
|
---|
| 270 | AddMissing(PckInit,PatchName)
|
---|
| 271 | ;"Purpose: Add a missing patche to pending patches
|
---|
| 272 | set ^TMG("KIDS","PENDING PATCHES",PckInit,"WAITING FOR",PatchName)=""
|
---|
| 273 | quit
|
---|
| 274 |
|
---|
| 275 | DownPck(PatchName,Option,Msg)
|
---|
| 276 | ;"Purpose: given a patch name, ensure all pending patches are local.
|
---|
| 277 | ;"Input: PatchName -- patch name, e.g. ABC*1.0*123
|
---|
| 278 | ;" Option -- Optional. PASS BY REFERENCE.
|
---|
| 279 | ;" Option("VERBOSE")=1 --> puts output to console
|
---|
| 280 | ;" Msg -- PASS BY REFERANCE, an OUT PARAMETER
|
---|
| 281 | ;" Errors are stored in Msg("ERROR",x)=Message
|
---|
| 282 | ;" Msg("ERROR")=count of last error
|
---|
| 283 | ;" Message are store in Msg(x)=Message
|
---|
| 284 | ;" Msg=count of last message+1
|
---|
| 285 | ;"Results: none
|
---|
| 286 |
|
---|
| 287 | new PckInit,Ver,PatchNum,seqNum,Info
|
---|
| 288 | do ParsePatchName^TMGPAT2(PatchName,.PckInit,.Ver,.PatchNum,.seqNum)
|
---|
| 289 | do Scan41a1Ver(PckInit,Ver,90)
|
---|
| 290 | new total set total=+$get(^TMG("KIDS","PENDING PATCHES",PckInit,Ver))
|
---|
| 291 | new count set count=1
|
---|
| 292 | new patch set patch=""
|
---|
| 293 | for set patch=$order(^TMG("KIDS","PENDING PATCHES",PckInit,Ver,"PATCHES",patch)) quit:(patch="") do
|
---|
| 294 | . new patchName set patchName=$get(^TMG("KIDS","PENDING PATCHES",PckInit,Ver,"PATCHES",patch))
|
---|
| 295 | . if $get(Option("VERBOSE"))=1 write count,"/",total,". ---- ",patchName," ----",!
|
---|
| 296 | . new IENS set IENS=$$GetIENS^TMGPAT2(patchName) quit:(IENS="")
|
---|
| 297 | . if $$EnsureLocal^TMGPAT2(IENS,.Info,.Msg,.Option)=0 do
|
---|
| 298 | . . do AddMsg^TMGPAT2("Unable to download patch to local file system.",1,Msg)
|
---|
| 299 | . set count=count+1
|
---|
| 300 |
|
---|
| 301 | if $get(Option("VERBOSE"))=1 do
|
---|
| 302 | . if $$ShowMsg^TMGPAT2(.Msg)
|
---|
| 303 |
|
---|
| 304 | quit
|
---|
| 305 |
|
---|
| 306 | Rpt1Avail(PatchName)
|
---|
| 307 | ;"Purpose: given a patch name (e.g. ABC*1.0*123), return pending patches.
|
---|
| 308 | new PckInit,Ver,PatchNum,seqNum
|
---|
| 309 | new count set count=-1
|
---|
| 310 | do ParsePatchName^TMGPAT2(PatchName,.PckInit,.Ver,.PatchNum,.seqNum)
|
---|
| 311 | if ($get(PckInit)="")!($get(Ver)="") goto Rpt1Done
|
---|
| 312 | do Scan41a1Ver(PckInit,Ver,90)
|
---|
| 313 | set count=+$get(^TMG("KIDS","PENDING PATCHES",PckInit,Ver))
|
---|
| 314 | Rpt1Done
|
---|
| 315 | quit count
|
---|
| 316 |
|
---|
| 317 | RptAvail(PckInit)
|
---|
| 318 | ;"Purpose: given a package (e.g. ABC), return pending patches.
|
---|
| 319 | new total set total=0
|
---|
| 320 | new Ver set Ver=""
|
---|
| 321 | for set Ver=$order(^TMG("KIDS","PENDING PATCHES",PckInit,Ver)) quit:(+Ver'>0) do
|
---|
| 322 | . set total=total+$get(^TMG("KIDS","PENDING PATCHES",PckInit,Ver))
|
---|
| 323 | quit total
|
---|
| 324 |
|
---|
| 325 | RESCAN
|
---|
| 326 | ;"Purpose: To show how many patches for a package are available and have not been installed yet
|
---|
| 327 | write !
|
---|
| 328 | new DUOUT,DIR
|
---|
| 329 | set DIR("A")="Search ftp server if data is older than __ days old? (SLOW!)"
|
---|
| 330 | set DIR("B")=90
|
---|
| 331 | set DIR(0)="N^0:999:0"
|
---|
| 332 | do ^DIR write !
|
---|
| 333 | new Option
|
---|
| 334 | set Option("VERBOSE")=0
|
---|
| 335 | if $get(DUOUT) quit
|
---|
| 336 | do Scan4New(+Y,.Option)
|
---|
| 337 | ;"if '$get(DUOUT) do ShowAvail
|
---|
| 338 | SADone quit
|
---|
| 339 |
|
---|
| 340 |
|
---|
| 341 |
|
---|
| 342 | Scan4New(MaxDays,Option)
|
---|
| 343 | ;"Purpose: to scan all packages and determine how many patches are pending for each
|
---|
| 344 | ;"Input: MaxDays -- the number of days that old days can be used. If last refresh
|
---|
| 345 | ;" was greater than this number, then ftp.va.gov is queried again.
|
---|
| 346 | ;" Option -- Optional. PASS BY REFERENCE.
|
---|
| 347 | ;" Option("VERBOSE")=1 --> puts output to console
|
---|
| 348 | ;"Output: Results will be stored:
|
---|
| 349 | ;" ^TMG("KIDS","PENDING PATCHES",PackageInitials,Version)=Count
|
---|
| 350 | ;" ^TMG("KIDS","PENDING PATCHES",PackageInitials,Version,"DATE REFRESHED")=Last date server checked.
|
---|
| 351 | ;" ^TMG("KIDS","PENDING PATCHES",PackageInitials,Version,"PATCHES",######)=AAAA*NN.NN*NNNN SEQ #1234"
|
---|
| 352 | ;" ^TMG("KIDS","PENDING PATCHES",PackageInitials,Version,"PATCHES",######)=AAAA*NN.NN*NNNN SEQ #1234"
|
---|
| 353 | ;" ^TMG("KIDS","PENDING PATCHES",PackageInitials,"FULL NAME")=Package name
|
---|
| 354 | ;"
|
---|
| 355 | ;"Results: none
|
---|
| 356 |
|
---|
| 357 | ;"NOTE: This function should be re-written. Rather than store the data in the global ^TMG(...
|
---|
| 358 | ;" the Fileman file 22709 should be used. As it is now, it is a duplication of organization.
|
---|
| 359 |
|
---|
| 360 | set MaxDays=+$get(MaxDays)
|
---|
| 361 | new PackageName set PackageName=""
|
---|
| 362 | for set PackageName=$order(^DIC(9.4,"B",PackageName)) quit:(PackageName="") do
|
---|
| 363 | . new IEN9d4 set IEN9d4=+$order(^DIC(9.4,"B",PackageName,"")) quit:(IEN9d4'>0)
|
---|
| 364 | . new PckInit set PckInit=$piece($get(^DIC(9.4,IEN9d4,0)),"^",2) ;"0;2 = Package prefix
|
---|
| 365 | . do Scan41(PckInit,MaxDays,.Option)
|
---|
| 366 |
|
---|
| 367 | quit
|
---|
| 368 |
|
---|
| 369 | Scan41(PckInit,MaxDays,Option)
|
---|
| 370 | ;"Purpose: to scan one package and determine how many patches are pending
|
---|
| 371 | ;"Input: PckInit -- Package Initials/prefix
|
---|
| 372 | ;" MaxDays -- the cutoff for when to requery the server
|
---|
| 373 | ;" Option -- PASS BY REFERENCE.
|
---|
| 374 | ;" Option("VERBOSE")=1 to be verbose.
|
---|
| 375 | ;"Output: Results will be stored:
|
---|
| 376 | ;" ^TMG("KIDS","PENDING PATCHES",PackageInitials,Version)=Count
|
---|
| 377 | ;" ^TMG("KIDS","PENDING PATCHES",PackageInitials,Version,"DATE REFRESHED")=Last date server checked.
|
---|
| 378 | ;" ^TMG("KIDS","PENDING PATCHES",PackageInitials,Version,"PATCHES",######)=AAAA*NN.NN*NNNN SEQ #1234"
|
---|
| 379 | ;" ^TMG("KIDS","PENDING PATCHES",PackageInitials,Version,"PATCHES",######)=AAAA*NN.NN*NNNN SEQ #1234"
|
---|
| 380 | ;" ^TMG("KIDS","PENDING PATCHES",PackageInitials,"FULL NAME")=Package name
|
---|
| 381 | ;"Results: none
|
---|
| 382 |
|
---|
| 383 | new IEN9d4 set IEN9d4=+$order(^DIC(9.4,"C",PckInit,""))
|
---|
| 384 | new PackageName set PackageName=""
|
---|
| 385 | if IEN9d4>0 set PackageName=$piece($get(^DIC(9.4,IEN9d4,0)),"^",1)
|
---|
| 386 | if $get(Option("VERBOSE"))=1 write "Checking Package: ",PackageName," (",PckInit,")...",!
|
---|
| 387 | set ^TMG("KIDS","PENDING PATCHES",PckInit,"FULL NAME")=PackageName
|
---|
| 388 | ;"kill ^TMG("KIDS","PENDING PATCHES",PckInit,"DATE REFRESHED") ;"force refresh
|
---|
| 389 | set Ver=""
|
---|
| 390 | for set Ver=$order(^DIC(9.4,IEN9d4,22,"B",Ver)) quit:(Ver="") do
|
---|
| 391 | . do Scan41a1Ver(PckInit,Ver,MaxDays,.Option)
|
---|
| 392 |
|
---|
| 393 | quit
|
---|
| 394 |
|
---|
| 395 |
|
---|
| 396 | Scan41a1Ver(PckInit,Ver,MaxDays,Option)
|
---|
| 397 | ;"Purpose: to scan one package and determine how many patches are pending
|
---|
| 398 | ;"Input: PckInit -- Package Initials/prefix
|
---|
| 399 | ;" Ver -- The version of the Package
|
---|
| 400 | ;" MaxDays -- the cutoff for when to requery the server
|
---|
| 401 | ;" Option -- PASS BY REFERENCE.
|
---|
| 402 | ;" Option("VERBOSE")=1 to be verbose.
|
---|
| 403 | ;"Output: Results will be stored:
|
---|
| 404 | ;" ^TMG("KIDS","PENDING PATCHES",PackageInitials,Version)=Count
|
---|
| 405 | ;" ^TMG("KIDS","PENDING PATCHES",PackageInitials,Version,"DATE REFRESHED")=Last date server checked.
|
---|
| 406 | ;" ^TMG("KIDS","PENDING PATCHES",PackageInitials,Version,"PATCHES",######)=AAAA*NN.NN*NNNN SEQ #1234"
|
---|
| 407 | ;" ^TMG("KIDS","PENDING PATCHES",PackageInitials,Version,"PATCHES",######)=AAAA*NN.NN*NNNN SEQ #1234"
|
---|
| 408 | ;" ^TMG("KIDS","PENDING PATCHES",PackageInitials,"FULL NAME")=Package name
|
---|
| 409 | ;"Results: none
|
---|
| 410 |
|
---|
| 411 | ;"kill ^TMG("KIDS","PENDING PATCHES",PckInit,"DATE REFRESHED") ;"force refresh
|
---|
| 412 | if $get(PckInit)="" goto S41Done
|
---|
| 413 | if $get(Ver)="" goto S41Done
|
---|
| 414 | set MaxDays=+$get(MaxDays,90)
|
---|
| 415 | if $get(Option("VERBOSE"))=1 write " Ver: ",Ver," ",!
|
---|
| 416 | new RefreshNeeded
|
---|
| 417 | new lastCheck set lastCheck=$get(^TMG("KIDS","PENDING PATCHES",PckInit,"DATE REFRESHED"))
|
---|
| 418 | if lastCheck'="" do
|
---|
| 419 | . new X,Y,%DT,X1,X2
|
---|
| 420 | . set X=lastCheck,%DT="TS"
|
---|
| 421 | . do ^%DT ;"result in Y
|
---|
| 422 | . set X=0
|
---|
| 423 | . do NOW^%DTC ;"returns date in X
|
---|
| 424 | . set X1=X,X2=Y
|
---|
| 425 | . do ^%DTC ;"returns X=X1-X2
|
---|
| 426 | . set RefreshNeeded=(X>MaxDays)
|
---|
| 427 | else set RefreshNeeded=1
|
---|
| 428 | new pArray set pArray=$name(^TMG("KIDS","PENDING PATCHES",PckInit,Ver,"PATCHES"))
|
---|
| 429 | new count set count=$$GetNew(PckInit,Ver,pArray,RefreshNeeded,.Option)
|
---|
| 430 | if $get(Option("VERBOSE"))=1 write " ",count," patches to be installed.",!
|
---|
| 431 | set ^TMG("KIDS","PENDING PATCHES",PckInit,Ver)=count
|
---|
| 432 | if RefreshNeeded do
|
---|
| 433 | . new %,%I,X,Y
|
---|
| 434 | . do NOW^%DTC set Y=%
|
---|
| 435 | . X ^DD("DD") ;"result in Y
|
---|
| 436 | . set ^TMG("KIDS","PENDING PATCHES",PckInit,"DATE REFRESHED")=Y
|
---|
| 437 |
|
---|
| 438 | S41Done
|
---|
| 439 | quit
|
---|
| 440 |
|
---|
| 441 |
|
---|
| 442 | GetNew(PckInit,Ver,pArray,RefreshNeeded,Option)
|
---|
| 443 | ;"Purpose: Get array of **just** patches still to be installed for a given package/version
|
---|
| 444 | ;"Input: PckInit -- this is the namespace of the package to get patches for, e.g. 'DI' for fileman
|
---|
| 445 | ;" Ver -- the package version
|
---|
| 446 | ;" pArray -- PASS BY NAME. An OUT PARAMETER. Format:
|
---|
| 447 | ;" @pArray@(######)=AAAA*NN.NN*NNNN SEQ #1234"
|
---|
| 448 | ;" @pArray@(######)=AAAA*NN.NN*NNNN SEQ #1234"
|
---|
| 449 | ;" NeedsRefresh -- 0 if refreshing not needed (just ensure file exists)
|
---|
| 450 | ;" Option -- Optional. PASS BY REFERENCE.
|
---|
| 451 | ;" Option("VERBOSE")=1 --> puts output to console
|
---|
| 452 | ;"Results: Number of patches still to be installed.
|
---|
| 453 |
|
---|
| 454 | new count set count=0
|
---|
| 455 |
|
---|
| 456 | do GetAvail(PckInit,Ver,pArray,.RefreshNeeded,.Option)
|
---|
| 457 | new LastPck set LastPck=$$GetLastPackage^TMGPAT1(PckInit,Ver)
|
---|
| 458 | new lastSeq set lastSeq=+$piece(LastPck,"SEQ #",2)
|
---|
| 459 | if lastSeq="" kill @pArray goto GNDone
|
---|
| 460 | new i set i=""
|
---|
| 461 | for set i=$order(@pArray@(i)) quit:(i="") do
|
---|
| 462 | . if +i'>lastSeq kill @pArray@(i) quit
|
---|
| 463 | . set count=count+1
|
---|
| 464 | GNDone
|
---|
| 465 | quit count
|
---|
| 466 |
|
---|
| 467 |
|
---|
| 468 |
|
---|
| 469 | GetAvail(PckInit,Ver,pArray,RefreshNeeded,Option)
|
---|
| 470 | ;"Purpose: return array of all patches for a given package/version
|
---|
| 471 | ;"Input: PckInit -- this is the namespace of the package to get patches for, e.g. 'DI' for fileman
|
---|
| 472 | ;" Ver -- the package version
|
---|
| 473 | ;" pArray -- PASS BY NAME. An OUT PARAMETER. Format:
|
---|
| 474 | ;" @pArray@(######)=AAAA*NN.NN*NNNN SEQ #1234"
|
---|
| 475 | ;" @pArray@(######)=AAAA*NN.NN*NNNN SEQ #1234"
|
---|
| 476 | ;" NeedsRefresh -- 0 if refreshing not needed (just ensure file exists)
|
---|
| 477 | ;" Option -- Optional. PASS BY REFERENCE.
|
---|
| 478 | ;" Option("VERBOSE")=1 --> puts output to console
|
---|
| 479 | ;"results: none
|
---|
| 480 |
|
---|
| 481 | kill @pArray
|
---|
| 482 | if $$RefreshPackge^TMGPAT2(PckInit,.Msg,.RefreshNeeded,.Option)
|
---|
| 483 |
|
---|
| 484 | new IEN9d4 set IEN9d4=+$order(^DIC(9.4,"C",PckInit,""))
|
---|
| 485 | if IEN9d4'>0 goto GADone
|
---|
| 486 | new PckIEN set PckIEN=+$order(^TMG(22709,"B",IEN9d4,""))
|
---|
| 487 | if PckIEN'>0 goto GADone
|
---|
| 488 | new VerIEN set VerIEN=+$order(^TMG(22709,PckIEN,1,"B",Ver,""))
|
---|
| 489 | if VerIEN'>0 set VerIEN=+$order(^TMG(22709,PckIEN,1,"B",$piece(Ver,".0",1),""))
|
---|
| 490 | if VerIEN'>0 goto GADone
|
---|
| 491 |
|
---|
| 492 | new patchIEN,nextSeq
|
---|
| 493 | set patchIEN=0
|
---|
| 494 | for set patchIEN=$order(^TMG(22709,PckIEN,1,VerIEN,1,patchIEN)) quit:(patchIEN'>0) do
|
---|
| 495 | . new node0 set node0=$get(^TMG(22709,PckIEN,1,VerIEN,1,patchIEN,0)) quit:(node0="")
|
---|
| 496 | . new patchNum set patchNum=$piece(node0,"^",2)
|
---|
| 497 | . new oneSeqNum set oneSeqNum=$piece(node0,"^",2)
|
---|
| 498 | . if oneSeqNum'>0 set oneSeqNum=0
|
---|
| 499 | . set @pArray@($$RJ^XLFSTR(oneSeqNum,6,"0"))=PckInit_"*"_Ver_"*"_patchNum_" SEQ #"_oneSeqNum
|
---|
| 500 |
|
---|
| 501 | GADone
|
---|
| 502 | quit
|
---|
| 503 |
|
---|
| 504 |
|
---|
| 505 | TestPList ;"temp function.
|
---|
| 506 | new PckInit,Ver,Array
|
---|
| 507 | do GetPckVer^TMGPAT1(.PckInit,.Ver)
|
---|
| 508 | if Ver="^" goto TPLDone
|
---|
| 509 | if $$GetPList(PckInit,Ver,"Array")=0 goto TPLDone
|
---|
| 510 | zwr Array(*)
|
---|
| 511 | TPLDone quit
|
---|
| 512 |
|
---|
| 513 |
|
---|
| 514 | GetPList(PckInit,Ver,pArray)
|
---|
| 515 | ;"Purpose: to get a list of applied patches, from PACKAGE file, into Array
|
---|
| 516 | ;"Input:
|
---|
| 517 | ;"Input: PckInit -- this is the namespace of the package to get patches for, e.g. 'DI' for fileman
|
---|
| 518 | ;" Ver -- the package version
|
---|
| 519 | ;" pArray -- PASS BY NAME. An OUT PARAMETER. Format:
|
---|
| 520 | ;" @pArray@(OrderNum)=PatchName
|
---|
| 521 | ;" @pArray@(OrderNum,"i",".01")=PatchName
|
---|
| 522 | ;" @pArray@(OrderNum,"i",".02")=Patch Date
|
---|
| 523 | ;" @pArray@(OrderNum,"i",".03")=Applied By
|
---|
| 524 | ;" @pArray@(OrderNum)=PatchName
|
---|
| 525 | ;"Results: 1 if OK, 0 if error
|
---|
| 526 | ;
|
---|
| 527 | new result set result=1
|
---|
| 528 | ;
|
---|
| 529 | new IEN9d4,IEN9d49
|
---|
| 530 | if $$GetPVIEN^TMGPAT1(PckInit,Ver,.IEN9d4,.IEN9d49)=0 set result=0 goto GPLDone
|
---|
| 531 | ;
|
---|
| 532 | new orderNum set orderNum=1
|
---|
| 533 | new patchIEN set patchIEN=0
|
---|
| 534 | for set patchIEN=$order(^DIC(9.4,IEN9d4,22,IEN9d49,"PAH",patchIEN)) quit:(+patchIEN'>0) do
|
---|
| 535 | . new s set s=$get(^DIC(9.4,IEN9d4,22,IEN9d49,"PAH",patchIEN,0))
|
---|
| 536 | . set @pArray@(orderNum)=$piece(s,"^",1) ;"0;1=.01 --PATCH APPLICATION HISTORY
|
---|
| 537 | . new IENS set IENS=patchIEN_","_IEN9d49_","_IEN9d4_","
|
---|
| 538 | . new TMGDATA,TMGMSG
|
---|
| 539 | . do GETS^DIQ(9.4901,IENS,".01;.02;.03","","TMGDATA","TMGMSG")
|
---|
| 540 | . merge @pArray@(orderNum,"i")=TMGDATA("9.4901",IENS)
|
---|
| 541 | . ;"zwr TMGDATA(*)
|
---|
| 542 | . set orderNum=orderNum+1
|
---|
| 543 | ;
|
---|
| 544 | GPLDone quit result
|
---|
| 545 |
|
---|
| 546 |
|
---|
| 547 | SHOWPLST
|
---|
| 548 | ;"Purpose: query user for package and version, then show patches.
|
---|
| 549 | new PckInit,Ver,Array
|
---|
| 550 | do GetPckVer^TMGPAT1(.PckInit,.Ver)
|
---|
| 551 | if Ver="^" goto SLPDone
|
---|
| 552 | if $$ShowPatches(PckInit,Ver)
|
---|
| 553 | SLPDone quit
|
---|
| 554 |
|
---|
| 555 |
|
---|
| 556 | ShowPatches(PckInit,Ver)
|
---|
| 557 | ;"Purpose: to show installed patches, using scroll box.
|
---|
| 558 | ;"Input: PckInit -- this is the namespace of the package to get patches for, e.g. 'DI' for fileman
|
---|
| 559 | ;" Ver -- the package version
|
---|
| 560 | ;"Results: 1 if OK, 0 if error
|
---|
| 561 |
|
---|
| 562 | new TMGPCKI set TMGPCKI=PckInit ;"used in HndOnPCmd^TMGPAT3
|
---|
| 563 | new TMGPVER set TMGPVER=Ver ;"used in HndOnPCmd^TMGPAT3
|
---|
| 564 | new TMGSORT set TMGSORT=2 ;"sort by SEQ number. Used in HndOnPCmd^TMGPAT3
|
---|
| 565 | new TMGSARRAY
|
---|
| 566 | set TMGSARRAY(0)="SORT by IEN order"
|
---|
| 567 | set TMGSARRAY(1)="SORT by PATCH num"
|
---|
| 568 | set TMGSARRAY(2)="SORT by SEQ num"
|
---|
| 569 | new Option,ShowArray,result
|
---|
| 570 | set Option("HEADER",1)="Applied patches for package "_PckInit_" "_TMGSARRAY(TMGSORT)
|
---|
| 571 | set Option("FOOTER",1,1)="^ Done"
|
---|
| 572 | set Option("FOOTER",1,2)="? Help"
|
---|
| 573 | set Option("FOOTER",1,3)="[F1] "_TMGSARRAY(0)
|
---|
| 574 | set Option("FOOTER",1,4)="[F2] Fix Missing PATCH"
|
---|
| 575 | set Option("FOOTER",1,5)="[F3] Fix Missing SEQ"
|
---|
| 576 | set Option("ON CMD")="HndOnPCmd^TMGPAT3"
|
---|
| 577 | set Option("SHOW INDEX")=1
|
---|
| 578 |
|
---|
| 579 | do PrepPatchList(PckInit,Ver,"ShowArray",TMGSORT)
|
---|
| 580 | if $data(ShowArray)=0 do
|
---|
| 581 | . do AskVer^TMGPAT1(PckInit,.Ver)
|
---|
| 582 | . do PrepPatchList(PckInit,Ver,"ShowArray",TMGSORT)
|
---|
| 583 |
|
---|
| 584 | write #
|
---|
| 585 | do Scroller^TMGUSRIF("ShowArray",.Option)
|
---|
| 586 |
|
---|
| 587 | SPDone quit 1
|
---|
| 588 |
|
---|
| 589 | PrepPatchList(PckInit,Ver,pShowArray,Mode)
|
---|
| 590 | ;"Purpose: to prepair the patch list for display in scroll box.
|
---|
| 591 | ;"Input: PckInit -- this is the namespace of the package to get patches for, e.g. 'DI' for fileman
|
---|
| 592 | ;" Ver -- the package version
|
---|
| 593 | ;" pShowArray -- PASS BY NAME, an OUT PARAMATER
|
---|
| 594 | ;" Mode -- OPTIONAL. 0: Otherwise by IEN order
|
---|
| 595 | ;" 1: Then sorted by patch number,
|
---|
| 596 | ;" 2: Otherwise by SEQ Num
|
---|
| 597 |
|
---|
| 598 | set ByPatchNum=+$get(ByPatchNum)
|
---|
| 599 | new index set index=1
|
---|
| 600 | new showI set showI=1
|
---|
| 601 | kill @pShowArray
|
---|
| 602 | new Array,tempA
|
---|
| 603 | if $$GetPList(.PckInit,.Ver,"Array")=0 goto PPLDone
|
---|
| 604 | if Mode=0 goto PPL2
|
---|
| 605 |
|
---|
| 606 | new Num
|
---|
| 607 | for set index=$order(Array(index)) quit:(index="") do
|
---|
| 608 | . if Mode=1 set Num=+$piece(Array(index)," ",1)
|
---|
| 609 | . else set Num=+$piece(Array(index),"SEQ #",2)
|
---|
| 610 | . new s,patch
|
---|
| 611 | . set patch=PckInit_"*"_Ver_"*"_$get(Array(index))
|
---|
| 612 | . set s=$$LJ^XLFSTR(patch,25)
|
---|
| 613 | . set s=s_" Applied: "_$get(Array(index,"i",".02"))_" "
|
---|
| 614 | . set s=s_" By: "_$get(Array(index,"i",".03"))
|
---|
| 615 | . set tempA(Num)=s
|
---|
| 616 | set Num=""
|
---|
| 617 | for set Num=$order(tempA(Num)) quit:(Num="") do
|
---|
| 618 | . new s set s=$get(tempA(Num)) quit:(s="")
|
---|
| 619 | . set @pShowArray@(showI,s)=$piece(s," Applied",1)
|
---|
| 620 | . set showI=showI+1
|
---|
| 621 | goto PPLDone
|
---|
| 622 |
|
---|
| 623 | PPL2 for set index=$order(Array(index)) quit:(index="") do
|
---|
| 624 | . new s,patch
|
---|
| 625 | . set patch=PckInit_"*"_Ver_"*"_$get(Array(index))
|
---|
| 626 | . set s=$$LJ^XLFSTR(patch,25)
|
---|
| 627 | . set s=s_" Applied: "_$get(Array(index,"i",".02"))_" "
|
---|
| 628 | . set s=s_" By: "_$get(Array(index,"i",".03"))
|
---|
| 629 | . set @pShowArray@(showI,s)=patch
|
---|
| 630 | . set showI=showI+1
|
---|
| 631 |
|
---|
| 632 | PPLDone quit
|
---|
| 633 |
|
---|
| 634 | HndOnPCmd(pArray,Option,Info)
|
---|
| 635 | ;"Purpose: handle ON SELECT event from Scroller
|
---|
| 636 | ;"Input: pArray,Option,Info -- see documentation in Scroller
|
---|
| 637 | ;" Info has this: Info("USER INPUT")=input
|
---|
| 638 | ;"NOTE: uses global-scope vars set up in ShowPatches:
|
---|
| 639 | ;" TMGPCKI,TMGPVER,TMGSORT
|
---|
| 640 |
|
---|
| 641 | new input set input=$$UP^XLFSTR($get(Info("USER INPUT")))
|
---|
| 642 | if input["F1" do
|
---|
| 643 | . set Option("HEADER",1)="Applied patches for package "_PckInit_" "_TMGSARRAY(TMGSORT)
|
---|
| 644 | . do PrepPatchList(TMGPCKI,TMGPVER,pArray,TMGSORT)
|
---|
| 645 | . set TMGSORT=TMGSORT+1
|
---|
| 646 | . if TMGSORT=3 set TMGSORT=0
|
---|
| 647 | . set Option("FOOTER",1,3)="[F1] "_TMGSARRAY(TMGSORT)
|
---|
| 648 | else if input["F2" do
|
---|
| 649 | . do FixMisInit^TMGPAT1(TMGPCKI,TMGPVER,0)
|
---|
| 650 | . do PressToCont^TMGUSRIF
|
---|
| 651 | else if input["F3" do
|
---|
| 652 | . do FixMisInit^TMGPAT1(TMGPCKI,TMGPVER,1)
|
---|
| 653 | . do PrepPatchList(TMGPCKI,TMGPVER,pArray,TMGSORT)
|
---|
| 654 | . do PressToCont^TMGUSRIF
|
---|
| 655 | else if input="?" do
|
---|
| 656 | . write !,"Use UP and DOWN cursor keys to scroll.",!
|
---|
| 657 | . write "Press F1 or F2 to change sorting",!
|
---|
| 658 | . write "Enter ^ at the ':' prompt when done",!
|
---|
| 659 | . do PressToCont^TMGUSRIF
|
---|
| 660 | else if input'="" do
|
---|
| 661 | . write !,"Input ",$get(Info("USER INPUT"))," not recognized.",!
|
---|
| 662 | . do PressToCont^TMGUSRIF
|
---|
| 663 |
|
---|
| 664 | write #
|
---|
| 665 | quit
|
---|
| 666 |
|
---|
| 667 | EditNotes
|
---|
| 668 | ;"Purpose: to launch an editor for editing notes about patching.
|
---|
| 669 | new FPName set FPName=$get(^TMG("KIDS","PATCH DIR"),"/tmp/")_"Patch_Notes.txt"
|
---|
| 670 | if $$EditHFSFile^TMGKERNL(FPName)
|
---|
| 671 | quit
|
---|