| 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
 | 
|---|