| 1 | TMGPAT1  ;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/17/08
 | 
|---|
| 7 | 
 | 
|---|
| 8 |  ;"=======================================================================
 | 
|---|
| 9 |  ;" API -- Public Functions.
 | 
|---|
| 10 |  ;"=======================================================================
 | 
|---|
| 11 |  ;"DONEXT -- Ask for package, and install next appropriate patch
 | 
|---|
| 12 |  ;"DONEXTPJ -- do next patch within the same project
 | 
|---|
| 13 |  ;"FIXMISEQ -- allow fixing a missing patch, based on sequence order
 | 
|---|
| 14 |  ;"FIXMISPT -- allow fixing a missing patch, based on patch number
 | 
|---|
| 15 |  ;"DONEXTPK(PckInit,Ver)-- a common entry point
 | 
|---|
| 16 |  ;"GO(Option,Info,Msg) -- Entry point to allow automatic loading and installation of a patch.
 | 
|---|
| 17 |  ;"LOAD -- Entry point to allow manual loading of a patch (like old way, but using new code)
 | 
|---|
| 18 | 
 | 
|---|
| 19 |  ;"=======================================================================
 | 
|---|
| 20 |  ;"Private Functions
 | 
|---|
| 21 |  ;"=======================================================================
 | 
|---|
| 22 |  ;"Logo
 | 
|---|
| 23 |  ;"FixMissing(Mode) allow fixing a missing patch, even if it is out of sequence order
 | 
|---|
| 24 |  ;"FixMisInit(PckInit,Ver,Mode) -- Based on PckInit, and Version, allow fixing a missing patch, even if it is out of sequence order
 | 
|---|
| 25 |  ;"DoFixMissing(IENS,Mode) -- fix a missing patch, even if it is out of sequence order
 | 
|---|
| 26 |  ;"DoIENS(NextIENS,NextPatch,PckDirFName) -- install patch, given IENS to it's entry in 22709.11
 | 
|---|
| 27 |  ;"GetPckVer(PckInit,Ver) -- query user for package, and desired version
 | 
|---|
| 28 |  ;"GetLastPackage(PckInit,Ver) -- for given package initials, return the last patch applied
 | 
|---|
| 29 |  ;"GetPVIEN(PckInit,Ver,IEN9d4,IEN9d49) -- convert PckInit and Ver into IEN's for file 9.4 ad 9.49
 | 
|---|
| 30 |  ;"GetLastInst(PckInit,Ver,InstIEN) -- for given package initials, return the last patch applied in INSTALL file
 | 
|---|
| 31 |  ;"GetVers(PckInit,VerArray) --for given package initials, return possible versions
 | 
|---|
| 32 |  ;"PickFile(pArray) -- Pick a filename from a list, in a menu
 | 
|---|
| 33 | 
 | 
|---|
| 34 |  ;"=======================================================================
 | 
|---|
| 35 | 
 | 
|---|
| 36 | Logo    write !!,"===================",!
 | 
|---|
| 37 |         write "TMG Patcher Helper",!
 | 
|---|
| 38 |         write "===================",!
 | 
|---|
| 39 |         quit
 | 
|---|
| 40 | 
 | 
|---|
| 41 | DONEXT
 | 
|---|
| 42 |         ;"Purpose: Ask for package, and install next appropriate patch
 | 
|---|
| 43 |         do Logo
 | 
|---|
| 44 |         new PckInit,Ver
 | 
|---|
| 45 |         do GetPckVer(.PckInit,.Ver)
 | 
|---|
| 46 |         if Ver="^" goto DNDone
 | 
|---|
| 47 |         do DONEXTPK(PckInit,Ver)
 | 
|---|
| 48 |         goto DONEXT
 | 
|---|
| 49 | DNDone
 | 
|---|
| 50 |         quit
 | 
|---|
| 51 | 
 | 
|---|
| 52 | DONEXTPJ
 | 
|---|
| 53 |         ;"Purpose: to do next patch within the same project
 | 
|---|
| 54 |         do Logo
 | 
|---|
| 55 |         new PckInit,Ver
 | 
|---|
| 56 |         new s set s=$get(^TMG("KIDS","PROJECT"))
 | 
|---|
| 57 |         if s'="" do
 | 
|---|
| 58 |         . set PckInit=$piece(s,"^",1)
 | 
|---|
| 59 |         . set Ver=$piece(s,"^",2)
 | 
|---|
| 60 |         else  do
 | 
|---|
| 61 |         . do GetPckVer(.PckInit,.Ver)
 | 
|---|
| 62 |         . set s=PckInit_"^"_Ver
 | 
|---|
| 63 |         . set ^TMG("KIDS","PROJECT")=s
 | 
|---|
| 64 |         if Ver="^" goto DNDone
 | 
|---|
| 65 |         do DONEXTPK(PckInit,Ver)
 | 
|---|
| 66 | DNPJDone
 | 
|---|
| 67 |         quit
 | 
|---|
| 68 | 
 | 
|---|
| 69 | 
 | 
|---|
| 70 | FIXMISEQ
 | 
|---|
| 71 |         ;"Purpose: to allow fixing a missing patch, based on sequence order
 | 
|---|
| 72 |         do FixMissing(1)
 | 
|---|
| 73 |         quit
 | 
|---|
| 74 | 
 | 
|---|
| 75 | 
 | 
|---|
| 76 | FIXMISPT
 | 
|---|
| 77 |         ;"Purpose: to allow fixing a missing patch, based on patch number
 | 
|---|
| 78 |         do FixMissing(2)
 | 
|---|
| 79 |         quit
 | 
|---|
| 80 | 
 | 
|---|
| 81 | 
 | 
|---|
| 82 | FixMissing(Mode)
 | 
|---|
| 83 |         ;"Purpose: to allow fixing a missing patch, even if it is out of sequence order
 | 
|---|
| 84 |         ;"         This will prepare, then call DoFixMissing()
 | 
|---|
| 85 |         ;"Input: Mode -- 1: search by SEQ#, 2: search by Patch#
 | 
|---|
| 86 |         do Logo
 | 
|---|
| 87 |         write "Fix missing patches, regardless of order",!
 | 
|---|
| 88 |         new PckInit,Ver
 | 
|---|
| 89 |         do GetPckVer(.PckInit,.Ver) goto:(Ver="^") FMIDone
 | 
|---|
| 90 |         ;"set IENS=$$AskIENS^TMGDBAPI(22709.01) goto:(IENS="") FMIDone
 | 
|---|
| 91 |         do FixMisInit(.PckInit,.Ver,.Mode)
 | 
|---|
| 92 | FMDone  quit
 | 
|---|
| 93 | 
 | 
|---|
| 94 | 
 | 
|---|
| 95 | FixMisInit(PckInit,Ver,Mode)
 | 
|---|
| 96 |         ;"Purpose: Based on PckInit, and Version, allow fixing a missing patch, even if it is out of sequence order
 | 
|---|
| 97 |         ;"         This will prepare, then call DoFixMissing()
 | 
|---|
| 98 |         ;"Input: Mode -- 1: search by SEQ#, 2: search by Patch#
 | 
|---|
| 99 |         set PckInit=$get(PckInit) goto:(PckInit="") FMIDone
 | 
|---|
| 100 |         set Ver=$get(Ver) goto:(Ver="") FMIDone
 | 
|---|
| 101 |         new IENS set IENS=$$GetIENS2^TMGPAT2(PckInit_"*"_Ver) goto:(IENS="") FMIDone
 | 
|---|
| 102 |         do DoFixMissing(IENS,.Mode)
 | 
|---|
| 103 | FMIDone quit
 | 
|---|
| 104 | 
 | 
|---|
| 105 | 
 | 
|---|
| 106 | DoFixMissing(IENS,Mode)
 | 
|---|
| 107 |         ;"Purpose: fix a missing patch, even if it is out of sequence order
 | 
|---|
| 108 |         ;"Input: IENS -- should be IENS from file 27709.01
 | 
|---|
| 109 |         ;"              i.e. 'IEN22709d01,IEN22709,'
 | 
|---|
| 110 |         ;"       Mode -- 1: search by SEQ#, 2: search by Patch#
 | 
|---|
| 111 | 
 | 
|---|
| 112 |         new PckInit,Ver,Y,PatchName,Msg,PckDirFName
 | 
|---|
| 113 |         new IEN1 set IEN1=+$piece(IENS,",",2) goto:(IEN1'>0) FMSDone
 | 
|---|
| 114 |         new IEN2 set IEN2=+$piece(IENS,",",1) goto:(IEN2'>0) FMSDone
 | 
|---|
| 115 |         new IEN9d4 set IEN9d4=$piece($get(^TMG(22709,IEN1,0)),"^",1) goto:(IEN9d4'>0) FMSDone
 | 
|---|
| 116 |         set PckInit=$piece($get(^DIC(9.4,IEN9d4,0)),"^",2)
 | 
|---|
| 117 |         set Ver=$piece($get(^TMG(22709,IEN1,1,IEN2,0)),"^",1) goto:(Ver="") FMSDone
 | 
|---|
| 118 |         new saveIENS set saveIENS=IENS
 | 
|---|
| 119 |         set Mode=+$get(Mode,1)
 | 
|---|
| 120 | 
 | 
|---|
| 121 |         do MAKFRESH^TMGPAT2(PckInit,.Msg,.PckDirFName)
 | 
|---|
| 122 | FMLoop  new SrchNum,DIR
 | 
|---|
| 123 |         set DIR(0)="N^1:9999:0"
 | 
|---|
| 124 |         if Mode=1 set DIR("A")="Enter missing patch SEQUENCE NUMBER"
 | 
|---|
| 125 |         else  set DIR("A")="Enter missing PATCH NUMBER"
 | 
|---|
| 126 |         do ^DIR write !
 | 
|---|
| 127 |         if $get(DIRUT) goto FMSDone
 | 
|---|
| 128 |         set SrchNum=+Y
 | 
|---|
| 129 | 
 | 
|---|
| 130 |         ;"Search for specified Patch/Seq #
 | 
|---|
| 131 |         new found set found=0
 | 
|---|
| 132 |         new IEN3 set IEN3=0
 | 
|---|
| 133 |         new PatchNum set PatchNum=0
 | 
|---|
| 134 |         new SeqNum set SeqNum=0
 | 
|---|
| 135 |         for  set IEN3=$order(^TMG(22709,IEN1,1,IEN2,1,IEN3)) quit:(IEN3'>0)!found  do
 | 
|---|
| 136 |         . set PatchNum=$piece($get(^TMG(22709,IEN1,1,IEN2,1,IEN3,0)),"^",1)
 | 
|---|
| 137 |         . set SeqNum=$piece($get(^TMG(22709,IEN1,1,IEN2,1,IEN3,0)),"^",2)
 | 
|---|
| 138 |         . if (Mode=1),(SeqNum=SrchNum) set found=IEN3
 | 
|---|
| 139 |         . else  if (Mode=2),(PatchNum=SrchNum) set found=IEN3
 | 
|---|
| 140 |         . if found do
 | 
|---|
| 141 |         . . set IENS=IEN3_","_IENS
 | 
|---|
| 142 |         . . set PatchName=PckInit_"*"_Ver_"*"_PatchNum_" SEQ #"_SeqNum
 | 
|---|
| 143 | 
 | 
|---|
| 144 |         if found=0 do  goto FMSDone
 | 
|---|
| 145 |         . write "Sorry.  Can't find that Patch/Seq Number in downloaded info from ftp.va.gov",!
 | 
|---|
| 146 | 
 | 
|---|
| 147 |         write "Found: ",PatchName," on ftp.va.gov server.",!
 | 
|---|
| 148 | 
 | 
|---|
| 149 |         ;"Now see if already installed
 | 
|---|
| 150 |         new DIC,X,Y,IEN9d49
 | 
|---|
| 151 |         ;"set IEN9d49=+$order(^DIC(9.4,IEN9d4,22,"B",Ver,""))
 | 
|---|
| 152 |         set DIC="^DIC(9.4,"_IEN9d4_",22,"
 | 
|---|
| 153 |         set DIC(0)="M"
 | 
|---|
| 154 |         set X=Ver
 | 
|---|
| 155 |         do ^DIC
 | 
|---|
| 156 |         set IEN9d49=+Y
 | 
|---|
| 157 |         if IEN9d49'>0 do  goto FMSDone
 | 
|---|
| 158 |         . write "?? Can't find that version in the PACKAGE file",!
 | 
|---|
| 159 | 
 | 
|---|
| 160 |         set found=0
 | 
|---|
| 161 |         new i set i=""
 | 
|---|
| 162 |         for  set i=$order(^DIC(9.4,IEN9d4,22,IEN9d49,"PAH","B",i)) quit:(i="")!found  do
 | 
|---|
| 163 |         . new onePatchNum set onePatchNum=$piece(i," ",1)
 | 
|---|
| 164 |         . ;"write onePatchNum,!
 | 
|---|
| 165 |         . if onePatchNum=PatchNum set found=$order(^DIC(9.4,IEN9d4,22,IEN9d49,"PAH","B",i,""))
 | 
|---|
| 166 | 
 | 
|---|
| 167 |         if found do  goto FMSMore
 | 
|---|
| 168 |         . new newIENS set newIENS=found_","_IEN9d49_","_IEN9d4
 | 
|---|
| 169 |         . write "Sorry, that patch is already installed.  IENS='",newIENS,"'",!
 | 
|---|
| 170 |         . do ForceP2^TMGPAT2(PckInit,Ver,PatchNum,SeqNum)
 | 
|---|
| 171 | 
 | 
|---|
| 172 | 
 | 
|---|
| 173 |         new % set %=1
 | 
|---|
| 174 |         write "Do you want to work on this patch now (out of sequence order)" do YN^DICN write !
 | 
|---|
| 175 |         if %'=1 goto FMSDone
 | 
|---|
| 176 | 
 | 
|---|
| 177 |         if $$DoIENS(IENS,PatchName,.PckDirFName)  ;"actually process patch
 | 
|---|
| 178 | 
 | 
|---|
| 179 | FMSMore set %=1
 | 
|---|
| 180 |         write "Fix others in this same Package-Version" do YN^DICN write !
 | 
|---|
| 181 |         if %=1 do  goto FMLoop
 | 
|---|
| 182 |         . set IENS=saveIENS
 | 
|---|
| 183 | 
 | 
|---|
| 184 | FMSDone
 | 
|---|
| 185 |         quit
 | 
|---|
| 186 | 
 | 
|---|
| 187 | 
 | 
|---|
| 188 | DONEXTPK(PckInit,Ver)
 | 
|---|
| 189 |         ;"Purpose: a common entry point
 | 
|---|
| 190 |         ;"Input: PckInit -- package initials
 | 
|---|
| 191 |         ;"       Ver -- version e.g. '22.0'
 | 
|---|
| 192 |         ;"Result: None
 | 
|---|
| 193 | 
 | 
|---|
| 194 |         new LastPck,NextIENS,NextPatch,LastInst,PckDirFName
 | 
|---|
| 195 |         new Info,Msg,Option,result,restart,InstIEN,abort,chgVer
 | 
|---|
| 196 | 
 | 
|---|
| 197 |         set (abort,restart,chgVer)=0
 | 
|---|
| 198 |         do MAKFRESH^TMGPAT2(PckInit,.Msg,.PckDirFName)
 | 
|---|
| 199 | DNP1    set LastPck=$$GetLastPackage(PckInit,Ver)
 | 
|---|
| 200 |         if LastPck="" do  goto AllDone
 | 
|---|
| 201 |         . write "Sorry, can't find any installed packges in that version.",!
 | 
|---|
| 202 |         set LastInst=$$GetLastInst(PckInit,Ver,.InstIEN)
 | 
|---|
| 203 |         write "The last patch installed into PACKAGE file was: ",?50,LastPck,!
 | 
|---|
| 204 |         if LastInst="" goto DNP2
 | 
|---|
| 205 |         write "The last patch loaded into the INSTALL file was: ",?50,LastInst," (FYI)",!
 | 
|---|
| 206 |         if +$piece(LastPck,"SEQ #",2)<+$piece(LastInst,"SEQ #",2) do  goto:(restart) AllDone
 | 
|---|
| 207 |         . new % set %=2
 | 
|---|
| 208 |         . write !,"Undelete entry in INSTALL FILE" do YN^DICN write !
 | 
|---|
| 209 |         . if %=1 do  quit
 | 
|---|
| 210 |         . . do EN1^TMGXPDIU(InstIEN)
 | 
|---|
| 211 |         . . set restart=1
 | 
|---|
| 212 |         . set %=1
 | 
|---|
| 213 |         . write "Try to continue with existing files" do YN^DICN write !
 | 
|---|
| 214 |         . if %'=1 set restart=1 quit
 | 
|---|
| 215 |         if restart goto AllDone
 | 
|---|
| 216 | DNP2    set NextIENS=$$GetNextIENS^TMGPAT2(LastPck,.NextPatch)
 | 
|---|
| 217 |         new pendingCt set pendingCt=$$Rpt1Avail^TMGPAT3(LastPck)
 | 
|---|
| 218 |         if pendingCt>0 write "Number of pending patches for this package:",?50,pendingCt,!
 | 
|---|
| 219 |         else  do  goto:(chgVer) DNP1
 | 
|---|
| 220 |         . if $$RptAvail^TMGPAT3(PckInit)=0 set chgVer=0 quit
 | 
|---|
| 221 |         . do AskVer(PckInit,.Ver)
 | 
|---|
| 222 |         . set chgVer=1
 | 
|---|
| 223 | 
 | 
|---|
| 224 |         if $$DoIENS(NextIENS,NextPatch,.PckDirFName)=0 goto AllDone
 | 
|---|
| 225 | 
 | 
|---|
| 226 | More    set %=1
 | 
|---|
| 227 |         write "Do more patch installations in this package" do YN^DICN write !!
 | 
|---|
| 228 |         if %=1 goto DNP1
 | 
|---|
| 229 | AllDone
 | 
|---|
| 230 |         quit
 | 
|---|
| 231 | 
 | 
|---|
| 232 | DoIENS(NextIENS,NextPatch,PckDirFName)
 | 
|---|
| 233 |         ;"Purpose: install patch, given IENS to it's entry in 22709.11
 | 
|---|
| 234 |         ;"Input: NextIENS -- IENS for entry in 22709.11
 | 
|---|
| 235 |         ;"       NextPatch -- Patch Name of patch to be applied.
 | 
|---|
| 236 |         ;"Results: 1 if OK, 0 if problem.
 | 
|---|
| 237 | 
 | 
|---|
| 238 |         new abort set abort=0
 | 
|---|
| 239 |         if NextPatch'="" do
 | 
|---|
| 240 |         . write "Next patch to install is: ",?50,NextPatch,!
 | 
|---|
| 241 |         else  do  goto DNPDone
 | 
|---|
| 242 |         . write "No more patches available for this package.",!
 | 
|---|
| 243 |         . set abort=1
 | 
|---|
| 244 |         . quit;  ;"//kt fix below later...
 | 
|---|
| 245 |         . write "View list of all patches for this package on ftp server"
 | 
|---|
| 246 |         . set %=2
 | 
|---|
| 247 |         . do YN^DICN write !
 | 
|---|
| 248 |         . if %=1 if $$EditHFSFile^TMGKERNL(PckDirFName)
 | 
|---|
| 249 |         . if %=-1 set restart=1 quit
 | 
|---|
| 250 |         new Option set Option("VERBOSE")=1
 | 
|---|
| 251 |         set result=$$EnsureLocal^TMGPAT2(NextIENS,.Info,.Msg,.Option)
 | 
|---|
| 252 |         if result=0 do  goto DNPDone
 | 
|---|
| 253 |         . do AddMsg^TMGPAT2("Unable to find patch on local file system.",1,Msg)
 | 
|---|
| 254 |         . if $$ShowMsg^TMGPAT2(.Msg)
 | 
|---|
| 255 | 
 | 
|---|
| 256 |         new % set %=1
 | 
|---|
| 257 |         if $get(Info("KID FILE"))'="" do PAnalyze^TMGPAT4(.Info,.Option)
 | 
|---|
| 258 |         if $get(Info("TEXT FILE"))'="" do  goto:(abort=1) DNPDone
 | 
|---|
| 259 |         . do Analyze^TMGPAT4(.Info,.Option)
 | 
|---|
| 260 |         . new tempMsg
 | 
|---|
| 261 |         . do ShowAnalysis^TMGPAT4(.Info,.tempMsg)
 | 
|---|
| 262 |         . if $$ShowMsg^TMGPAT2(.tempMsg,1)
 | 
|---|
| 263 |         . kill tempMsg
 | 
|---|
| 264 |         . new FilePathName set FilePathName=$get(Info("PATH"))_$get(Info("TEXT FILE"))
 | 
|---|
| 265 |         . set %=1
 | 
|---|
| 266 |         . write "View INFO FILE for patch" do YN^DICN write !
 | 
|---|
| 267 |         . if %=-1 quit
 | 
|---|
| 268 |         . if %=1 if $$EditHFSFile^TMGKERNL(FilePathName)
 | 
|---|
| 269 |         . if $get(Info("KID FILE"))="" do
 | 
|---|
| 270 |         . . new FName set FName=""
 | 
|---|
| 271 |         . . if $get(Info("MULTI-PATCH","FILENAME"))'="" do
 | 
|---|
| 272 |         . . . set Info("KID FILE")=Info("MULTI-PATCH","FILENAME")
 | 
|---|
| 273 |         . . else  if ($$ListCt^TMGMISC($name(Info("PATCH CATEGORY")))=1)&($data(Info("PATCH CATEGORY","Informational"))) quit
 | 
|---|
| 274 |         . . else  if $data(Info("MISC KID FILES")) do
 | 
|---|
| 275 |         . . . write !,"No typical KIDS file found for this patch.  However, one or more filenames",!
 | 
|---|
| 276 |         . . . write "were scraped from the TEXT file.  Having read the TEXT file, see if one of these",!
 | 
|---|
| 277 |         . . . write "names is correct.",!!
 | 
|---|
| 278 |         . . . set Info("KID FILE")=$$PickFile($name(Info("MISC KID FILES")))
 | 
|---|
| 279 |         . . if $get(Info("KID FILE"))'="" set Info("TEXT ONLY")=0
 | 
|---|
| 280 |         . . set FName=$get(Info("KID FILE"))
 | 
|---|
| 281 |         . . if FName="" quit
 | 
|---|
| 282 |         . . set %=2
 | 
|---|
| 283 |         . . write !,"Attempt to download ",FName," from ftp.va.gov?",!
 | 
|---|
| 284 |         . . write "NOTE: if this file doesn't exist on the server, then the process will HANG.",!
 | 
|---|
| 285 |         . . write "If this happens, then use a utility to abort process #",$J," from OS prompt.",!
 | 
|---|
| 286 |         . . write "Download '",FName,"'" do YN^DICN write !
 | 
|---|
| 287 |         . . if %'=1 quit
 | 
|---|
| 288 |         . . if $$DownloadPatch^TMGPAT2(FName,"ftp://",.Option,.tempMsg,.Info)=0
 | 
|---|
| 289 |         . . . write "ERROR: Can't download file: ",Info("KID FILE")," from ftp server.",!
 | 
|---|
| 290 |         . . . do PressToCont^TMGUSRIF
 | 
|---|
| 291 |         . . . ;"handle error here...
 | 
|---|
| 292 |         . . if $$ShowMsg^TMGPAT2(.tempMsg,1)
 | 
|---|
| 293 |         if %=-1 goto DNPDone
 | 
|---|
| 294 | 
 | 
|---|
| 295 |         if $data(Info("STILL NEEDED")) do  goto:(abort=1) DNPDone
 | 
|---|
| 296 |         . new pArray set pArray=$name(Info("STILL NEEDED"))
 | 
|---|
| 297 |         . do StoreMissing^TMGPAT3(PckInit,pArray)
 | 
|---|
| 298 |         . write "It seems that the system is not ready for this patch.",!
 | 
|---|
| 299 |         . write "(However, sometimes this can be ignored and one can proceed anyway.)",!
 | 
|---|
| 300 |         . set %=1
 | 
|---|
| 301 |         . write "Quit this patch and try another" do YN^DICN write !
 | 
|---|
| 302 |         . if %'=2 set abort=1
 | 
|---|
| 303 | 
 | 
|---|
| 304 |         if $get(Info("TEXT ONLY"))=1 do  goto DNPDone
 | 
|---|
| 305 |         . write "This 'patch' doesn't have a corresponding KID file.",!
 | 
|---|
| 306 |         . write "Perhaps it was informational only.  I'm not smart enough to figure that out.",!
 | 
|---|
| 307 |         . write "If you didn't read the INFO FILE, then answer NO, and loop back and read it.",!
 | 
|---|
| 308 |         . set %=2
 | 
|---|
| 309 |         . write "Ready to consider the patch 'installed'" do YN^DICN write !
 | 
|---|
| 310 |         . if %'=1 quit
 | 
|---|
| 311 |         . if $$MakePatchEntry^TMGPAT2(NextPatch,.Msg)
 | 
|---|
| 312 | 
 | 
|---|
| 313 |         if $get(Info("KID FILE"))="" do  goto DNPDone
 | 
|---|
| 314 |         . write "?? No name for KID file ??",!
 | 
|---|
| 315 | 
 | 
|---|
| 316 |         set %=1
 | 
|---|
| 317 |         write "Ready to load patch "_Info("KID FILE")_" into system" do YN^DICN write !
 | 
|---|
| 318 |         if %'=1 set %=-1 goto DNPDone
 | 
|---|
| 319 |         new result set result=$$GO(.Option,.Info,.Msg)
 | 
|---|
| 320 | 
 | 
|---|
| 321 |         quit result
 | 
|---|
| 322 | 
 | 
|---|
| 323 | 
 | 
|---|
| 324 | GO(Option,Info,Msg)
 | 
|---|
| 325 |         ;"Purpose: Entry point to allow automatic loading and installation of a patch.
 | 
|---|
| 326 |         ;"Input: Option -- PASS BY REFERENCE.  Can be an empty array.
 | 
|---|
| 327 |         ;"       Info -- PASS BY REFERENCE.
 | 
|---|
| 328 |         ;"       Msg -- PASS BY REFERNCE.
 | 
|---|
| 329 |         ;"Results: 1 if OK, 0 if problem.
 | 
|---|
| 330 | 
 | 
|---|
| 331 |         new abort set abort=0
 | 
|---|
| 332 |         set Option("HFSNAME")=$get(Info("PATH"))_Info("KID FILE")
 | 
|---|
| 333 |         set Option("FORCE CONT LOAD")=1
 | 
|---|
| 334 |         set Option("DO ENV CHECK")=1
 | 
|---|
| 335 |         do EN1^TMGXPDIL(.Option,.Msg)
 | 
|---|
| 336 |         new errorFound set errorFound=$$ShowMsg^TMGPAT2(.Msg,1)
 | 
|---|
| 337 |         if errorFound goto DNP3
 | 
|---|
| 338 |         new InstallName set InstallName=$get(Option("INSTALL NAME"))
 | 
|---|
| 339 |         if InstallName="" do  goto DNPDone
 | 
|---|
| 340 |         . write "No installation name found.  Aborting.",!
 | 
|---|
| 341 |         . set abort=1
 | 
|---|
| 342 |         new % set %=1
 | 
|---|
| 343 |         write "Proceed with installation" do YN^DICN write !
 | 
|---|
| 344 |         kill Msg
 | 
|---|
| 345 |         new Option ;"... FINISH..., add presets to avoid user interactivity later...
 | 
|---|
| 346 |         set Option("Want to DISABLE Scheduled Options, Menu Options, and Protocols","DEFAULT")="NO"
 | 
|---|
| 347 |         set Option("Want KIDS to INHIBIT LOGONs during the install","DEFAULT")="NO"
 | 
|---|
| 348 |         set Option("Want KIDS to Rebuild Menu Trees Upon Completion of Install","DEFAULT")="NO"
 | 
|---|
| 349 |         if %=1 do EN^TMGXPDI(InstallName,.Option,.Msg)
 | 
|---|
| 350 |         if $$ShowMsg^TMGPAT2(.Msg,1)
 | 
|---|
| 351 | DNP3
 | 
|---|
| 352 |         new tempNull
 | 
|---|
| 353 |         if $data(PckInit) do
 | 
|---|
| 354 |         . do StoreMissing^TMGPAT3(PckInit,"tempNull") ;"clear out pending patches...
 | 
|---|
| 355 |         else  goto DNPDone
 | 
|---|
| 356 | 
 | 
|---|
| 357 |         set %=1
 | 
|---|
| 358 |         write "Clean up local files for this patch" do YN^DICN write !
 | 
|---|
| 359 |         if %=-1 goto DNPDone
 | 
|---|
| 360 |         if %=1 do
 | 
|---|
| 361 |         . new path set path=$get(Info("PATH"))
 | 
|---|
| 362 |         . new fileName set fileName=$get(Info("KID FILE"))
 | 
|---|
| 363 |         . if fileName'="" if $$DelFile^TMGIOUTL(path_fileName)
 | 
|---|
| 364 |         . set fileName=$get(Info("TEXT FILE"))
 | 
|---|
| 365 |         . if fileName'="" if $$DelFile^TMGIOUTL(path_fileName)
 | 
|---|
| 366 | 
 | 
|---|
| 367 | DNPDone quit (abort=0)
 | 
|---|
| 368 | 
 | 
|---|
| 369 | 
 | 
|---|
| 370 | LOAD
 | 
|---|
| 371 |         ;"Purpose: Entry point to allow manual loading of a patch (like old way, but using new code)
 | 
|---|
| 372 |         do Logo^TMGPAT1 write !
 | 
|---|
| 373 |         new FPName,FPath,FName,Msg,Option,Info
 | 
|---|
| 374 |         set FPName=$$GetFName^TMGIOUTL("Select Patch to Load",,,,.FPath,.FName)
 | 
|---|
| 375 |         if (FPName'="")&(FPName'="^") do
 | 
|---|
| 376 |         . set Info("PATH")=FPath,Info("KID FILE")=FName
 | 
|---|
| 377 |         . new result set result=$$GO(.Option,.Info,.Msg)
 | 
|---|
| 378 |         quit
 | 
|---|
| 379 | 
 | 
|---|
| 380 | 
 | 
|---|
| 381 | GetPckVer(PckInit,Ver)
 | 
|---|
| 382 |         ;"Purpose: query user for package, and desired version
 | 
|---|
| 383 |         ;"Input: PckInit - PASS BY REFERENCE.  An OUT PARAMETER. The package initials, e.g. 'DI' in the case of filemant
 | 
|---|
| 384 |         ;"       Ver -- PASS BY REFERENCE.  An OUT PARAMETER.  The version of the package to match.
 | 
|---|
| 385 |         ;"results: none;  (if user aborted, Ver="^")
 | 
|---|
| 386 | 
 | 
|---|
| 387 |         set Ver="^"
 | 
|---|
| 388 |         new DIC,X,Y
 | 
|---|
| 389 |         set DIC=9.4,DIC(0)="MAEQ"  ;"ask for package name
 | 
|---|
| 390 |         do ^DIC write !
 | 
|---|
| 391 |         if +Y'>0 goto GPVDone
 | 
|---|
| 392 |         new Package set Package=$piece(Y,"^",2)
 | 
|---|
| 393 |         set PckInit=$piece($get(^DIC(9.4,+Y,0)),"^",2)
 | 
|---|
| 394 |         if PckInit="" do  goto GPVDone
 | 
|---|
| 395 |         . write "Error.  Unable to obtain package prefix.",!
 | 
|---|
| 396 |         do AskVer(PckInit,.Ver)
 | 
|---|
| 397 | 
 | 
|---|
| 398 | GPVDone quit
 | 
|---|
| 399 | 
 | 
|---|
| 400 | AskVer(PckInit,Ver,Package)
 | 
|---|
| 401 |         ;"Purpose: query user for desired version from specified package
 | 
|---|
| 402 |         ;"Input: PckInit - The package initials, e.g. 'DI' in the case of filemant
 | 
|---|
| 403 |         ;"       Ver -- PASS BY REFERENCE.  An OUT PARAMETER.  The version of the package to match.
 | 
|---|
| 404 |         ;"       Package -- OPTIONAL.  Name of Package.  Default is same as PckInit
 | 
|---|
| 405 |         ;"results: none;  (if user aborted, Ver="^")
 | 
|---|
| 406 | 
 | 
|---|
| 407 |         new VerArray
 | 
|---|
| 408 |         do GetVers(PckInit,.VerArray)
 | 
|---|
| 409 |         if $data(VerArray)=0 do  goto AVrDone
 | 
|---|
| 410 |         . write "Error. No version number available.",!
 | 
|---|
| 411 |         if $get(Package)="" set Package=PckInit
 | 
|---|
| 412 |         ;
 | 
|---|
| 413 |         new Menu,i,Usr
 | 
|---|
| 414 |         set Menu(0)="Select Version of "_Package
 | 
|---|
| 415 |         set Ver="",i=0
 | 
|---|
| 416 |         for  set Ver=$order(VerArray(Ver)) quit:(Ver="")  do
 | 
|---|
| 417 |         . set i=i+1
 | 
|---|
| 418 |         . new tempPatch set tempPatch=PckInit_"*"_Ver_"*1"
 | 
|---|
| 419 |         . new count set count=+$$Rpt1Avail^TMGPAT3(tempPatch)
 | 
|---|
| 420 |         . set Menu(i)="Version "_Ver_" ("_count_" patches pending)"_$C(9)_Ver
 | 
|---|
| 421 |         if i=1 set Ver=$order(VerArray(""))  ;"must be only one option, so skip menu
 | 
|---|
| 422 |         else  do
 | 
|---|
| 423 |         . set Ver=$$Menu^TMGUSRIF(.Menu,"^")
 | 
|---|
| 424 |         ;
 | 
|---|
| 425 | AVrDone quit
 | 
|---|
| 426 | 
 | 
|---|
| 427 | 
 | 
|---|
| 428 | GetPVIEN(PckInit,Ver,IEN9d4,IEN9d49)
 | 
|---|
| 429 |         ;"Purpose: to convert PckInit and Ver into IEN's for file 9.4 ad 9.49
 | 
|---|
| 430 |         ;"Input: PckInit - .  The package initials, e.g. 'DI' in the case of filemant
 | 
|---|
| 431 |         ;"       Ver -- The version of the package to match.
 | 
|---|
| 432 |         ;"       IEN9d4 - PASS BY REFERENCE.  The IEN in 9.4 to return
 | 
|---|
| 433 |         ;"       IEN9d49 -- PASS BY REFERENCE.  The IEN in 9.49 to return
 | 
|---|
| 434 |         ;"result: 1 if OK, 0 if not found.
 | 
|---|
| 435 | 
 | 
|---|
| 436 |         new result set result=0
 | 
|---|
| 437 |         ;
 | 
|---|
| 438 |         set IEN9d4=+$order(^DIC(9.4,"C",PckInit,""))
 | 
|---|
| 439 |         if IEN9d4'>0 goto GPVIDne
 | 
|---|
| 440 |         new DIC,X,Y
 | 
|---|
| 441 |         set DIC="^DIC(9.4,"_IEN9d4_",22,"
 | 
|---|
| 442 |         set DIC(0)="M"
 | 
|---|
| 443 |         set X=Ver
 | 
|---|
| 444 |         do ^DIC
 | 
|---|
| 445 |         set IEN9d49=+Y
 | 
|---|
| 446 |         if IEN9d49'>0 goto GPVIDne
 | 
|---|
| 447 |         set result=1
 | 
|---|
| 448 |         ;
 | 
|---|
| 449 | GPVIDne quit result
 | 
|---|
| 450 | 
 | 
|---|
| 451 | 
 | 
|---|
| 452 | GetLastPackage(PckInit,Ver)
 | 
|---|
| 453 |         ;"Purpose: for given package initials, return the last patch applied
 | 
|---|
| 454 |         ;"         This searches the PACKAGE file
 | 
|---|
| 455 |         ;"Input: PckInit - the package initials, e.g. 'DI' in the case of filemant
 | 
|---|
| 456 |         ;"       Ver -- the version of the package to match.
 | 
|---|
| 457 |         ;"Results: returns e.g. 'DI*22.0*140 SEQ# 123'
 | 
|---|
| 458 |         ;"         or "" if problem or not found.
 | 
|---|
| 459 | 
 | 
|---|
| 460 |         new result set result=""
 | 
|---|
| 461 |         set Ver=$get(Ver)
 | 
|---|
| 462 |         set PckInit=$get(PckInit)
 | 
|---|
| 463 |         if (PckInit="")!(Ver="") goto GLPDone
 | 
|---|
| 464 |         new IEN9d4,IEN9d49
 | 
|---|
| 465 |         set IEN9d4=+$order(^DIC(9.4,"C",PckInit,""))
 | 
|---|
| 466 |         if IEN9d4'>0 goto GLPDone
 | 
|---|
| 467 |         set IEN9d49=+$order(^DIC(9.4,IEN9d4,22,"B",Ver,""))
 | 
|---|
| 468 |         if IEN9d49'>0 goto GLPDone
 | 
|---|
| 469 | 
 | 
|---|
| 470 |         new i,array
 | 
|---|
| 471 |         set i=""
 | 
|---|
| 472 |         for  set i=$order(^DIC(9.4,IEN9d4,22,IEN9d49,"PAH","B",i)) quit:(i="")  do
 | 
|---|
| 473 |         . new patchNum set patchNum=$piece(i," ",1)
 | 
|---|
| 474 |         . new seqNum set seqNum=$piece(i,"SEQ #",2)
 | 
|---|
| 475 |         . new tempName set tempName=i
 | 
|---|
| 476 |         . if seqNum="" do
 | 
|---|
| 477 |         . . set tempName=PckInit_"*"_Ver_"*"_patchNum
 | 
|---|
| 478 |         . . set tempName=$$GetSeq^TMGPAT4(tempName)
 | 
|---|
| 479 |         . . set seqNum=$piece(tempName,"SEQ #",2)
 | 
|---|
| 480 |         . . if seqNum="" quit
 | 
|---|
| 481 |         . . new IEN9d4901 set IEN9d4901=$order(^DIC(9.4,IEN9d4,22,IEN9d49,"PAH","B",i,""))
 | 
|---|
| 482 |         . . ;"write "The PACKAGE file entry for patch "_PckInit_"*"_Ver_"*"_patchNum_" doesn't have a SEQ #",!
 | 
|---|
| 483 |         . . ;"write "By comparing this to patch files available on ftp.va.gov network site, it",!
 | 
|---|
| 484 |         . . ;"write "appears that this patch should be SEQ #",tempName,!
 | 
|---|
| 485 |         . . ;"new % set %=1
 | 
|---|
| 486 |         . . ;"write "Shall I correct this in the PACKAGE file" do YN^DICN write !
 | 
|---|
| 487 |         . . ;"if %'=1 quit
 | 
|---|
| 488 |         . . new TMGFDA,TMGMSG
 | 
|---|
| 489 |         . . set TMGFDA(9.4901,IEN9d4901_","_IEN9d49_","_IEN9d4_",",.01)=patchNum_" SEQ #"_seqNum
 | 
|---|
| 490 |         . . do FILE^DIE("K","TMGFDA","TMGMSG")
 | 
|---|
| 491 |         . . ;"do ShowIfDIERR^TMGDEBUG(.TMGMSG)
 | 
|---|
| 492 |         . ;"if seqNum is still "" at this point, it won't find the patch, could be bug...
 | 
|---|
| 493 |         . set seqNum=$$RJ^XLFSTR(seqNum,6,"0")
 | 
|---|
| 494 |         . if tempName["*" set tempName=$piece(tempName,"*",3)
 | 
|---|
| 495 |         . set array(seqNum)=tempName
 | 
|---|
| 496 | 
 | 
|---|
| 497 |         set i=$order(array(""),-1)
 | 
|---|
| 498 |         if i'="" set result=PckInit_"*"_Ver_"*"_$get(array(i))
 | 
|---|
| 499 |         else  set result=PckInit_"*"_Ver_"*0 SEQ #0"
 | 
|---|
| 500 |         ;"else  set result=$piece($get(^DIC(9.4,IEN9d4,0)),"^",1)_" SEQ #0"
 | 
|---|
| 501 | 
 | 
|---|
| 502 | GLPDone
 | 
|---|
| 503 |         quit result
 | 
|---|
| 504 | 
 | 
|---|
| 505 | GetLastInst(PckInit,Ver,InstIEN)
 | 
|---|
| 506 |         ;"Purpose: for given package initials, return the last patch applied
 | 
|---|
| 507 |         ;"         This searches the INSTALL file
 | 
|---|
| 508 |         ;"Input: PckInit - the package initials, e.g. 'DI' in the case of filemant
 | 
|---|
| 509 |         ;"       Ver -- the version of the package to match.
 | 
|---|
| 510 |         ;"       InstIEN -- Optional.  Pass by Reference, an OUT PARAMETER.
 | 
|---|
| 511 |         ;"Results: returns last patch + 'SEQ# 123' (123 is example)
 | 
|---|
| 512 |         ;"         or "" if problem or not found.
 | 
|---|
| 513 | 
 | 
|---|
| 514 |         new result set result=""
 | 
|---|
| 515 |         new array
 | 
|---|
| 516 |         set Ver=$get(Ver)
 | 
|---|
| 517 |         new i set i=$get(PckInit)
 | 
|---|
| 518 |         if (i="")!(Ver="") goto GLIDone
 | 
|---|
| 519 |         new done set done=0
 | 
|---|
| 520 |         for  set i=$order(^XPD(9.7,"B",i)) quit:(i="")!done  do
 | 
|---|
| 521 |         . if $piece(i,"*",1)'=PckInit set done=1 quit
 | 
|---|
| 522 |         . if $piece(i,"*",2)'=Ver quit
 | 
|---|
| 523 |         . new patch set patch=$piece(i,"*",3)
 | 
|---|
| 524 |         . set patch=$$RJ^XLFSTR(patch,6,"0")
 | 
|---|
| 525 |         . new IEN set IEN=$order(^XPD(9.7,"B",i,""))
 | 
|---|
| 526 |         . if IEN=0 quit
 | 
|---|
| 527 |         . new seq set seq=$$GET1^DIQ(9.7,IEN_",",42001)
 | 
|---|
| 528 |         . if seq="" quit
 | 
|---|
| 529 |         . ;"write "SEQ #"_seq_"  "_i,!
 | 
|---|
| 530 |         . set array(seq)=i_" SEQ #"_seq_"^"_IEN
 | 
|---|
| 531 | 
 | 
|---|
| 532 |         set i=$order(array(""),-1)
 | 
|---|
| 533 |         set result=$get(array(i))
 | 
|---|
| 534 |         set InstIEN=$piece(result,"^",2)
 | 
|---|
| 535 |         set result=$piece(result,"^",1)
 | 
|---|
| 536 | 
 | 
|---|
| 537 |         if result'="" do
 | 
|---|
| 538 |         . new PatIEN set PatIEN=+$order(^XPD(9.7,"B",result,""))
 | 
|---|
| 539 |         . if PatIEN=0 quit
 | 
|---|
| 540 |         . new Seq set Seq=$$GET1^DIQ(9.7,PatIEN_",",42001)
 | 
|---|
| 541 |         . if Seq="" quit
 | 
|---|
| 542 |         . set result=result_" SEQ #"_Seq
 | 
|---|
| 543 | 
 | 
|---|
| 544 | GLIDone
 | 
|---|
| 545 |         quit result
 | 
|---|
| 546 | 
 | 
|---|
| 547 | 
 | 
|---|
| 548 | 
 | 
|---|
| 549 | GetVers(PckInit,VerArray)
 | 
|---|
| 550 |         ;"Purpose: for given package initials, return possible versions
 | 
|---|
| 551 |         ;"Input: PckInit - the package initials, e.g. 'DI' in the case of filemant
 | 
|---|
| 552 |         ;"       VerArray -- PASS BY REFERENCE -- an OUT PARAMETER.  Format
 | 
|---|
| 553 |         ;"              VerArray("22")=""
 | 
|---|
| 554 |         ;"              VerArray("23")=""
 | 
|---|
| 555 |         ;"Results: none
 | 
|---|
| 556 | 
 | 
|---|
| 557 |         new ver
 | 
|---|
| 558 |         kill VerArray
 | 
|---|
| 559 |         if $get(PckInit)="" goto GVDone
 | 
|---|
| 560 |         new done set done=0
 | 
|---|
| 561 |         new ien9d4 set ien9d4=+$order(^DIC(9.4,"C",PckInit,"")) goto:(ien9d4'>0) GVDone
 | 
|---|
| 562 |         set ver=""
 | 
|---|
| 563 |         for  set ver=$order(^DIC(9.4,ien9d4,22,"B",ver)) quit:(ver="")!done  do
 | 
|---|
| 564 |         . if ver'="" set VerArray(ver)=""
 | 
|---|
| 565 | 
 | 
|---|
| 566 | GVDone  quit
 | 
|---|
| 567 | 
 | 
|---|
| 568 |         ;"Discard below later ============================================
 | 
|---|
| 569 |         for  set i=$order(^XPD(9.7,"B",i)) quit:(i="")!done  do
 | 
|---|
| 570 |         . if i["*" do
 | 
|---|
| 571 |         . . if $piece(i,"*",1)'=PckInit set done=1 quit
 | 
|---|
| 572 |         . . set ver=$piece(i,"*",2)
 | 
|---|
| 573 |         . else  do
 | 
|---|
| 574 |         . . new ien set ien=+$order(^XPD(9.7,"B",i,""))
 | 
|---|
| 575 |         . . write i,!
 | 
|---|
| 576 |         . . write "From the above name, please enter version number"
 | 
|---|
| 577 |         . . new DIR set DIR(0)="N^0:999:2" do ^DIR write !
 | 
|---|
| 578 |         . . if $data(DIRUT) set ver="" quit
 | 
|---|
| 579 |         . . set ver=X  ;"why doesn't Y return decimals???
 | 
|---|
| 580 |         . . set done=1
 | 
|---|
| 581 |         . if ver'="" set VerArray(ver)=""
 | 
|---|
| 582 |         ;"Discard above later ============================================
 | 
|---|
| 583 | 
 | 
|---|
| 584 | 
 | 
|---|
| 585 | PickFile(pArray)
 | 
|---|
| 586 |         ;"Purpose: Pick a filename from a list, in a menu
 | 
|---|
| 587 |         ;"Input: pArray -- PASS BY NAME.  format:
 | 
|---|
| 588 |         ;"        @pArray@(name)=""
 | 
|---|
| 589 |         ;"        @pArray@(name)=""
 | 
|---|
| 590 |         ;"Result: the chosen name, or "" if problem.
 | 
|---|
| 591 | 
 | 
|---|
| 592 |         new menu set menu(0)="Select IF one of the following files is the patch file."
 | 
|---|
| 593 |         new count set count=1
 | 
|---|
| 594 |         new name set name=""
 | 
|---|
| 595 |         for  set name=$order(@pArray@(name)) quit:(name="")  do
 | 
|---|
| 596 |         . set menu(count)=name_$C(9)_name
 | 
|---|
| 597 |         . set count=count+1
 | 
|---|
| 598 |         set menu(count)="(None of these / Cancel)"_$C(9)_"@"
 | 
|---|
| 599 |         set count=count+1
 | 
|---|
| 600 | 
 | 
|---|
| 601 |         set result=$$Menu^TMGUSRIF(.menu)
 | 
|---|
| 602 |         if "@^"[result set result=""
 | 
|---|
| 603 |         quit result | 
|---|