XTSUMCK ;Boise/MAW,SFISC/RSD -compute routine checksums ;10/04/96 11:11 [ 04/02/2003 8:29 AM ]
;;8.0;KERNEL;**1002,1003,1004,1005,1007**;APR 1, 2003
;;8.0;KERNEL;**44**;Jul 10, 1995
;^XTMP("XTSUMCK",DUZ)=end time^home cpu^status^task #^start time^# rtns
;^XTMP("XTSUMCK",DUZ,"SYS",system)=end time^active^status^task #^end time^# rtns
I '$G(DUZ) W *7,!!,"DUZ UNDEFINED...ABORTED." Q
S:'$D(DT) DT=$$DT^XLFDT S:'$D(U) U="^"
N DIR,I,XTCKSUM,XTHOME,XTROU,DIRUT,X,Y
X ^%ZOSF("UCI") S XTHOME=Y
;set expiration date on ^XTMP
S ^XTMP("XTSUMCK",0)=$$FMADD^XLFDT(DT,7)_U_DT
W !!,"You're on ",XTHOME,". Checksums for selected routines on other systems",!,"will be compared to those on this system."
I $G(^XTMP("XTSUMCK",DUZ))'="" S X=^XTMP("XTSUMCK",DUZ) D Q:$D(DIRUT)
.W *7,!!,"A checksum job, launched on ",$$FMTE^XLFDT($P(X,U,5))," from ",$P(X,U,2)," is",!," already on file."
.W:$P(X,U,3)]"" !," It has a status of: ",$P(X,U,3)
.S DIR(0)="Y",DIR("A")="Okay to delete the existing data",DIR("B")="NO"
.D ^DIR
.I Y'=1 W !!,"Nothing deleted...this job aborted." S DIRUT=1 Q
.K ^XTMP("XTSUMCK",DUZ) S ^(DUZ)=""
K ^UTILITY($J) W ! X ^%ZOSF("RSEL")
I '$D(^UTILITY($J)) W !,"No routines selected." Q
S ^XTMP("XTSUMCK",DUZ)=U_XTHOME_"^Loading routines^^"_$$NOW^XLFDT
;move list of routines into XTMP
M ^XTMP("XTSUMCK",DUZ,"ROU")=^UTILITY($J)
K ^UTILITY($J),DIR
;find systems to move to
S Y=$P(XTHOME,",",2),I=0
F S I=$O(^%ZIS(14.5,I)) Q:'I S X=$G(^(I,0)) S:$P(X,U)]""&$P(X,U,11)&($P(X,U)'=Y) ^XTMP("XTSUMCK",DUZ,"SYS",$P(X,U))=""
SYS I '$D(^XTMP("XTSUMCK",DUZ,"SYS")) W !!,"No Systems to Check",! G ABORT
W !!,"I will Check the Routines on the following Systems:",!
S I="" F S I=$O(^XTMP("XTSUMCK",DUZ,"SYS",I)) Q:I="" W ?3,I,!
W ! S DIR(0)="Y",DIR("A")="Accept this list and continue",DIR("B")="YES"
S DIR("?",1)="Enter Yes if you want to check the routines on the listed Systems",DIR("?")="Enter No if you want to create your own list of Systems."
D ^DIR G ZTLD:Y,ABORT:$D(DIRUT) D G SYS
.N DIC K ^XTMP("XTSUMCK",DUZ,"SYS")
.S DIC="^%ZIS(14.5,",DIC(0)="AEMQZ",DIC("S")="S %=^(0) I $P(%,U)'=$P(XTHOME,"","",2),$P(%,U,11)"
.;ask for systems
.F D ^DIC Q:Y'>0 S ^XTMP("XTSUMCK",DUZ,"SYS",Y(0,0))=""
ZTLD ;queue build of master routine set checksums
N ZTRTN,ZTDESC,ZTIO,ZTSAVE,ZTUCI,ZTCPU,ZTSK
S ZTRTN="MSTR^XTSUMCK",ZTDESC="Routine Checksum Checker",ZTIO="",ZTSAVE("DUZ")="",ZTSAVE("XTHOME")="",ZTUCI=$P(XTHOME,","),ZTCPU=$P(XTHOME,",",2)
D ^%ZTLOAD
W !!
I '$G(ZTSK) W *7,"Error...not queued!!" G ABORT
I $G(ZTSK) D
.S $P(^XTMP("XTSUMCK",DUZ),U,3,4)="Queued to run^"_ZTSK
.W "Task number ",ZTSK," will calculate checksums for the selected"
.W !,"routines here on ",XTHOME,"."
.W !!,"These values will be used for comparison with the same routine set on all"
.W !,"the other systems. You will receive an alert when the job finishes. The"
.W !,"alert action will allow you to view/print the report that lists any"
.W !,"routines that do not match the ""master"" calculated checksums."
K ^UTILITY($J)
Q
MSTR ;TaskMan entry point
;first, calculate the checksums for the "master" routine set
S $P(^XTMP("XTSUMCK",DUZ),U,3)="Calculating checksums",XTDUZ=DUZ,XTX=""
F XTCNT=0:1 S XTX=$O(^XTMP("XTSUMCK",DUZ,"ROU",XTX)) Q:XTX="" D
.S X=XTX
.X ^%ZOSF("RSUM")
.S ^XTMP("XTSUMCK",DUZ,"ROU",XTX)=Y
;next, job the checksum module on the other systems
S $P(^XTMP("XTSUMCK",DUZ),U,6)=XTCNT,XTX=""
F S XTX=$O(^XTMP("XTSUMCK",DUZ,"SYS",XTX)) Q:XTX="" D
.N ZTSK,ZTCPU,ZTDESC,ZTIO,ZTRTN,ZTSAVE,ZTDTH
.S ZTCPU=XTX,ZTRTN="CHK^XTSUMCK",ZTSAVE("XTDUZ")="",ZTUCI=$P(XTHOME,","),ZTDESC="Routine Checksum Checker for "_ZTUCI_","_ZTCPU,ZTDTH=$H,ZTIO=""
.D ^%ZTLOAD
.I $G(ZTSK) S ^XTMP("XTSUMCK",DUZ,"SYS",XTX)="^^Job Tasked^"_ZTSK,XTSUMCK(XTX)="0^"_$H Q
.S %=$$NOW^XLFDT,^XTMP("XTSUMCK",DUZ,"SYS",XTX)=%_"^^ERROR -- Job couldn't be tasked^^"_%
;monitor background tasks
;checking for completion of all checksum jobs. Once all completed,
;an alert is set up to notify the requester.
S $P(^XTMP("XTSUMCK",DUZ),U,3)="Waiting for jobs to finish",XTSFLG=""
F D Q:XTFLG H 60
.S XTFLG=1,XTSYS=""
.F S XTSYS=$O(^XTMP("XTSUMCK",DUZ,"SYS",XTSYS)) Q:XTSYS="" S X=^(XTSYS) D:'X
..S XTFLG=0
..;not complete, if still active then reset counter
..I $P(XTSUMCK(XTSYS),U,2)'=$P(X,U,2) S XTSUMCK(XTSYS)="0^"_$P(X,U,2) Q
..;hasn't been active for at least 30 minutes
..I XTSUMCK(XTSYS)>30 S X=^XTMP("XTSUMCK",XTDUZ,"SYS",XTSYS),$P(X,U)=$$NOW^XLFDT,$P(X,U,3)="ERROR - was idle for more than 30 minutes",^XTMP("XTSUMCK",XTDUZ,"SYS",XTSYS)=X
..S $P(XTSUMCK(XTSYS),U)=XTSUMCK(XTSYS)+1
;log the date.time job completed
S XTX=^XTMP("XTSUMCK",DUZ),XTX=$$NOW^XLFDT_U_$P(XTX,U,2)_"^Completed ^"_$P(XTX,U,4,6),^XTMP("XTSUMCK",DUZ)=XTX
;send an alert that the checksum job completed
S XQA(DUZ)=""
S XQAMSG="Routine checksum job completed."
S XQAROU="^XTSUMCK1"
D SETUP^XQALERT
I $D(ZTQUEUED) S ZTREQ="@"
Q
CHK ;jobbed entry point...
;XTDUZ=DUZ of the user who started the checksum job...
X ^%ZOSF("UCI") S XTSYS=$P(Y,",",2)
I $$NEWERR^%ZTER N $ETRAP,$ESTACK S $ETRAP="D ERR^XTSUMCK"
E S X="ERR^XTSUMCK",@^%ZOSF("TRAP")
S XTMST=$P(^XTMP("XTSUMCK",XTDUZ),U,2),XTHM=$P(XTMST,",")_","_XTSYS
S X=^XTMP("XTSUMCK",XTDUZ,"SYS",XTSYS),$P(X,U,2,3)=$H_"^Checking Routines",$P(X,U,5)=$$NOW^XLFDT,^XTMP("XTSUMCK",XTDUZ,"SYS",XTSYS)=X
S XTROU=""
F XTCNT=0:1 S XTROU=$O(^XTMP("XTSUMCK",XTDUZ,"ROU",XTROU)) Q:XTROU="" D
.S:'(XTCNT#10) $P(^XTMP("XTSUMCK",XTDUZ,XTSYS),U,2)=$H
.I $T(^@XTROU)="" S ^XTMP("XTSUMCK",XTDUZ,"SYS",XTSYS,XTROU)="NOT ON THIS SYSTEM" Q
.S XTCKSUM=+^XTMP("XTSUMCK",XTDUZ,"ROU",XTROU)
.S X=XTROU
.X ^%ZOSF("RSUM")
.I Y=XTCKSUM Q
.S ^XTMP("XTSUMCK",XTDUZ,"SYS",XTSYS,XTROU)="Checksum on "_XTHM_" = "_Y_" :: on "_XTMST_" = "_XTCKSUM
S X=^XTMP("XTSUMCK",XTDUZ,"SYS",XTSYS),$P(X,U)=$$NOW^XLFDT,$P(X,U,3)="Normal Completion",$P(X,U,6)=XTCNT,^XTMP("XTSUMCK",XTDUZ,"SYS",XTSYS)=X
Q
ABORT K ^XTMP("XTSUMCK",DUZ)
Q
ERR ;error in background job
S X=^XTMP("XTSUMCK",XTDUZ,"SYS",XTSYS),$P(X,U)=$$NOW^XLFDT,$P(X,U,3)="ERROR - Job terminated before completion",^XTMP("XTSUMCK",XTDUZ,"SYS",XTSYS)=X
D ^%ZTER,UNWIND^%ZTER
Q
XTSUMCK ;Boise/MAW,SFISC/RSD -compute routine checksums ;10/04/96 11:11 [ 04/02/2003 8:29 AM ]
+1 ;;8.0;KERNEL;**1002,1003,1004,1005,1007**;APR 1, 2003
+2 ;;8.0;KERNEL;**44**;Jul 10, 1995
+3 ;^XTMP("XTSUMCK",DUZ)=end time^home cpu^status^task #^start time^# rtns
+4 ;^XTMP("XTSUMCK",DUZ,"SYS",system)=end time^active^status^task #^end time^# rtns
+5 IF '$GET(DUZ)
WRITE *7,!!,"DUZ UNDEFINED...ABORTED."
QUIT
+6 IF '$DATA(DT)
SET DT=$$DT^XLFDT
IF '$DATA(U)
SET U="^"
+7 NEW DIR,I,XTCKSUM,XTHOME,XTROU,DIRUT,X,Y
+8 XECUTE ^%ZOSF("UCI")
SET XTHOME=Y
+9 ;set expiration date on ^XTMP
+10 SET ^XTMP("XTSUMCK",0)=$$FMADD^XLFDT(DT,7)_U_DT
+11 WRITE !!,"You're on ",XTHOME,". Checksums for selected routines on other systems",!,"will be compared to those on this system."
+12 IF $GET(^XTMP("XTSUMCK",DUZ))'=""
SET X=^XTMP("XTSUMCK",DUZ)
Begin DoDot:1
+13 WRITE *7,!!,"A checksum job, launched on ",$$FMTE^XLFDT($PIECE(X,U,5))," from ",$PIECE(X,U,2)," is",!," already on file."
+14 IF $PIECE(X,U,3)]""
WRITE !," It has a status of: ",$PIECE(X,U,3)
+15 SET DIR(0)="Y"
SET DIR("A")="Okay to delete the existing data"
SET DIR("B")="NO"
+16 DO ^DIR
+17 IF Y'=1
WRITE !!,"Nothing deleted...this job aborted."
SET DIRUT=1
QUIT
+18 KILL ^XTMP("XTSUMCK",DUZ)
SET ^(DUZ)=""
End DoDot:1
IF $DATA(DIRUT)
QUIT
+19 KILL ^UTILITY($JOB)
WRITE !
XECUTE ^%ZOSF("RSEL")
+20 IF '$DATA(^UTILITY($JOB))
WRITE !,"No routines selected."
QUIT
+21 SET ^XTMP("XTSUMCK",DUZ)=U_XTHOME_"^Loading routines^^"_$$NOW^XLFDT
+22 ;move list of routines into XTMP
+23 MERGE ^XTMP("XTSUMCK",DUZ,"ROU")=^UTILITY($JOB)
+24 KILL ^UTILITY($JOB),DIR
+25 ;find systems to move to
+26 SET Y=$PIECE(XTHOME,",",2)
SET I=0
+27 FOR
SET I=$ORDER(^%ZIS(14.5,I))
IF 'I
QUIT
SET X=$GET(^(I,0))
IF $PIECE(X,U)]""&$PIECE(X,U,11)&($PIECE(X,U)'=Y)
SET ^XTMP("XTSUMCK",DUZ,"SYS",$PIECE(X,U))=""
SYS IF '$DATA(^XTMP("XTSUMCK",DUZ,"SYS"))
WRITE !!,"No Systems to Check",!
GOTO ABORT
+1 WRITE !!,"I will Check the Routines on the following Systems:",!
+2 SET I=""
FOR
SET I=$ORDER(^XTMP("XTSUMCK",DUZ,"SYS",I))
IF I=""
QUIT
WRITE ?3,I,!
+3 WRITE !
SET DIR(0)="Y"
SET DIR("A")="Accept this list and continue"
SET DIR("B")="YES"
+4 SET DIR("?",1)="Enter Yes if you want to check the routines on the listed Systems"
SET DIR("?")="Enter No if you want to create your own list of Systems."
+5 DO ^DIR
IF Y
GOTO ZTLD
IF $DATA(DIRUT)
GOTO ABORT
Begin DoDot:1
+6 NEW DIC
KILL ^XTMP("XTSUMCK",DUZ,"SYS")
+7 SET DIC="^%ZIS(14.5,"
SET DIC(0)="AEMQZ"
SET DIC("S")="S %=^(0) I $P(%,U)'=$P(XTHOME,"","",2),$P(%,U,11)"
+8 ;ask for systems
+9 FOR
DO ^DIC
IF Y'>0
QUIT
SET ^XTMP("XTSUMCK",DUZ,"SYS",Y(0,0))=""
End DoDot:1
GOTO SYS
ZTLD ;queue build of master routine set checksums
+1 NEW ZTRTN,ZTDESC,ZTIO,ZTSAVE,ZTUCI,ZTCPU,ZTSK
+2 SET ZTRTN="MSTR^XTSUMCK"
SET ZTDESC="Routine Checksum Checker"
SET ZTIO=""
SET ZTSAVE("DUZ")=""
SET ZTSAVE("XTHOME")=""
SET ZTUCI=$PIECE(XTHOME,",")
SET ZTCPU=$PIECE(XTHOME,",",2)
+3 DO ^%ZTLOAD
+4 WRITE !!
+5 IF '$GET(ZTSK)
WRITE *7,"Error...not queued!!"
GOTO ABORT
+6 IF $GET(ZTSK)
Begin DoDot:1
+7 SET $PIECE(^XTMP("XTSUMCK",DUZ),U,3,4)="Queued to run^"_ZTSK
+8 WRITE "Task number ",ZTSK," will calculate checksums for the selected"
+9 WRITE !,"routines here on ",XTHOME,"."
+10 WRITE !!,"These values will be used for comparison with the same routine set on all"
+11 WRITE !,"the other systems. You will receive an alert when the job finishes. The"
+12 WRITE !,"alert action will allow you to view/print the report that lists any"
+13 WRITE !,"routines that do not match the ""master"" calculated checksums."
End DoDot:1
+14 KILL ^UTILITY($JOB)
+15 QUIT
MSTR ;TaskMan entry point
+1 ;first, calculate the checksums for the "master" routine set
+2 SET $PIECE(^XTMP("XTSUMCK",DUZ),U,3)="Calculating checksums"
SET XTDUZ=DUZ
SET XTX=""
+3 FOR XTCNT=0:1
SET XTX=$ORDER(^XTMP("XTSUMCK",DUZ,"ROU",XTX))
IF XTX=""
QUIT
Begin DoDot:1
+4 SET X=XTX
+5 XECUTE ^%ZOSF("RSUM")
+6 SET ^XTMP("XTSUMCK",DUZ,"ROU",XTX)=Y
End DoDot:1
+7 ;next, job the checksum module on the other systems
+8 SET $PIECE(^XTMP("XTSUMCK",DUZ),U,6)=XTCNT
SET XTX=""
+9 FOR
SET XTX=$ORDER(^XTMP("XTSUMCK",DUZ,"SYS",XTX))
IF XTX=""
QUIT
Begin DoDot:1
+10 NEW ZTSK,ZTCPU,ZTDESC,ZTIO,ZTRTN,ZTSAVE,ZTDTH
+11 SET ZTCPU=XTX
SET ZTRTN="CHK^XTSUMCK"
SET ZTSAVE("XTDUZ")=""
SET ZTUCI=$PIECE(XTHOME,",")
SET ZTDESC="Routine Checksum Checker for "_ZTUCI_","_ZTCPU
SET ZTDTH=$HOROLOG
SET ZTIO=""
+12 DO ^%ZTLOAD
+13 IF $GET(ZTSK)
SET ^XTMP("XTSUMCK",DUZ,"SYS",XTX)="^^Job Tasked^"_ZTSK
SET XTSUMCK(XTX)="0^"_$HOROLOG
QUIT
+14 SET %=$$NOW^XLFDT
SET ^XTMP("XTSUMCK",DUZ,"SYS",XTX)=%_"^^ERROR -- Job couldn't be tasked^^"_%
End DoDot:1
+15 ;monitor background tasks
+16 ;checking for completion of all checksum jobs. Once all completed,
+17 ;an alert is set up to notify the requester.
+18 SET $PIECE(^XTMP("XTSUMCK",DUZ),U,3)="Waiting for jobs to finish"
SET XTSFLG=""
+19 FOR
Begin DoDot:1
+20 SET XTFLG=1
SET XTSYS=""
+21 FOR
SET XTSYS=$ORDER(^XTMP("XTSUMCK",DUZ,"SYS",XTSYS))
IF XTSYS=""
QUIT
SET X=^(XTSYS)
IF 'X
Begin DoDot:2
+22 SET XTFLG=0
+23 ;not complete, if still active then reset counter
+24 IF $PIECE(XTSUMCK(XTSYS),U,2)'=$PIECE(X,U,2)
SET XTSUMCK(XTSYS)="0^"_$PIECE(X,U,2)
QUIT
+25 ;hasn't been active for at least 30 minutes
+26 IF XTSUMCK(XTSYS)>30
SET X=^XTMP("XTSUMCK",XTDUZ,"SYS",XTSYS)
SET $PIECE(X,U)=$$NOW^XLFDT
SET $PIECE(X,U,3)="ERROR - was idle for more than 30 minutes"
SET ^XTMP("XTSUMCK",XTDUZ,"SYS",XTSYS)=X
+27 SET $PIECE(XTSUMCK(XTSYS),U)=XTSUMCK(XTSYS)+1
End DoDot:2
End DoDot:1
IF XTFLG
QUIT
HANG 60
+28 ;log the date.time job completed
+29 SET XTX=^XTMP("XTSUMCK",DUZ)
SET XTX=$$NOW^XLFDT_U_$P(XTX,U,2)_"^Completed ^"_$PIECE(XTX,U,4,6)
SET ^XTMP("XTSUMCK",DUZ)=XTX
+30 ;send an alert that the checksum job completed
+31 SET XQA(DUZ)=""
+32 SET XQAMSG="Routine checksum job completed."
+33 SET XQAROU="^XTSUMCK1"
+34 DO SETUP^XQALERT
+35 IF $DATA(ZTQUEUED)
SET ZTREQ="@"
+36 QUIT
CHK ;jobbed entry point...
+1 ;XTDUZ=DUZ of the user who started the checksum job...
+2 XECUTE ^%ZOSF("UCI")
SET XTSYS=$PIECE(Y,",",2)
+3 IF $$NEWERR^%ZTER
NEW $ETRAP,$ESTACK
SET $ETRAP="D ERR^XTSUMCK"
+4 IF '$TEST
SET X="ERR^XTSUMCK"
SET @^%ZOSF("TRAP")
+5 SET XTMST=$PIECE(^XTMP("XTSUMCK",XTDUZ),U,2)
SET XTHM=$PIECE(XTMST,",")_","_XTSYS
+6 SET X=^XTMP("XTSUMCK",XTDUZ,"SYS",XTSYS)
SET $PIECE(X,U,2,3)=$HOROLOG_"^Checking Routines"
SET $PIECE(X,U,5)=$$NOW^XLFDT
SET ^XTMP("XTSUMCK",XTDUZ,"SYS",XTSYS)=X
+7 SET XTROU=""
+8 FOR XTCNT=0:1
SET XTROU=$ORDER(^XTMP("XTSUMCK",XTDUZ,"ROU",XTROU))
IF XTROU=""
QUIT
Begin DoDot:1
+9 IF '(XTCNT#10)
SET $PIECE(^XTMP("XTSUMCK",XTDUZ,XTSYS),U,2)=$HOROLOG
+10 IF $TEXT(^@XTROU)=""
SET ^XTMP("XTSUMCK",XTDUZ,"SYS",XTSYS,XTROU)="NOT ON THIS SYSTEM"
QUIT
+11 SET XTCKSUM=+^XTMP("XTSUMCK",XTDUZ,"ROU",XTROU)
+12 SET X=XTROU
+13 XECUTE ^%ZOSF("RSUM")
+14 IF Y=XTCKSUM
QUIT
+15 SET ^XTMP("XTSUMCK",XTDUZ,"SYS",XTSYS,XTROU)="Checksum on "_XTHM_" = "_Y_" :: on "_XTMST_" = "_XTCKSUM
End DoDot:1
+16 SET X=^XTMP("XTSUMCK",XTDUZ,"SYS",XTSYS)
SET $PIECE(X,U)=$$NOW^XLFDT
SET $PIECE(X,U,3)="Normal Completion"
SET $PIECE(X,U,6)=XTCNT
SET ^XTMP("XTSUMCK",XTDUZ,"SYS",XTSYS)=X
+17 QUIT
ABORT KILL ^XTMP("XTSUMCK",DUZ)
+1 QUIT
ERR ;error in background job
+1 SET X=^XTMP("XTSUMCK",XTDUZ,"SYS",XTSYS)
SET $PIECE(X,U)=$$NOW^XLFDT
SET $PIECE(X,U,3)="ERROR - Job terminated before completion"
SET ^XTMP("XTSUMCK",XTDUZ,"SYS",XTSYS)=X
+2 DO ^%ZTER
DO UNWIND^%ZTER
+3 QUIT