//BCHJOB JOB(JRSNMSG) JOBD(NERONI2/NERONI2) OUTQ(QPRINT) + ENDSEV(60) LOG(4 00 *SECLVL) MSGQ(*USRPRF) CCSID(280) /* Open source from www.neroni.it */ /* LA JOB DESCRIPTION "NERONI2/NERONI2" DEVE PREESISTERE. PUO' ESSERE */ /* IDENTICA A QBATCH E PUO' ESSERE SOSTITUITA DA QBATCH O SIMILE. */ /* From System: "DEV720" */ /* From Library: "NERONI2" */ /* Unload Time: 2016-06-15 10:10 */ /* To File : "JRSNMSG" */ /* To Library : "NERONI2" */ /* To Text : "Resend messages. Src" */ /********* INIZIO ISTRUZIONI **************************************************/ /* LE SUCCESSIVE ISTRUZIONI PERMETTONO DI RICARICARE I SORGENTI. */ /* 1) DA UN VIDEO COMANDI DELL'AS400 RICEVENTE */ /* CREARE UN FILE SORGENTE DI LUNGHEZZA RECORD 112: */ /* CRTSRCPF FILE(NERONI2/STRINGHE) RCDLEN(112) */ /* 2) SPOSTARE IL FILE "JRSNMSG.txt" NELL'INDIRIZZARIO */ /* DI UN PC CONNESSO IN RETE CON L'AS400 RICEVENTE */ /* (AD ES.: "c:\"). */ /* 3) DAL VIDEO COMANDI DEL PC CHIAMARE FTP: */ /* ftp nomeas400 */ /* 4) DIGITARE UTENTE E PASSWORD. */ /* 5) ESEGUIRE IL COMANDO DI COPIA DA FILE PC A MEMBRO AS400: */ /* put "c:\JRSNMSG.txt" "/qsys.lib/NERONI2.lib/stringhe.file/JRSNMSG.mbr" */ /* 6) ABBANDONARE FTP: */ /* quit */ /* 7) DA UN VIDEO COMANDI DELL'AS400 RICEVENTE */ /* ESEGUIRE LA STRINGA COPIATA NEL MEMBRO SORGENTE: */ /* SBMDBJOB FILE(NERONI2/STRINGHE) MBR(JRSNMSG) JOBQ(QBATCH) */ /* LE SUCCESSIVE ISTRUZIONI PERMETTONO DI CREARE L'UTILITY. */ /* 8) DA UN VIDEO COMANDI DELL'AS400 RICEVENTE */ /* ESEGUIRE LA STRINGA O LE STRINGHE SORGENTE DI TIPO SEU "CL" */ /* (IL CUI NOME TERMINA SEMPRE CON ".") */ /* PRESENTI NEL FILE RICARICATO "NERONI2/JRSNMSG" */ /* FACENDO ATTENZIONE ALL'ORDINE DI ESECUZIONE INDICATO NEL */ /* MEMBRO FACOLTATIVO "A.LEGGIMI", AD ESEMPIO: */ /* SBMDBJOB FILE(NERONI2/JRSNMSG) MBR(JRSNMSG.) JOBQ(QBATCH) */ /********* FINE ISTRUZIONI ****************************************************/ /* Crea la libreria. */ MKDIR DIR('/qsys.lib/NERONI2.lib') CHGLIB LIB(NERONI2) TEXT('Claudio Neroni Utility') /* Imposta la lista librerie. */ CHGLIBL LIBL(QTEMP NERONI2 QGPL) /* Crea il file sorgente. */ DLTF FILE(NERONI2/JRSNMSG) CRTSRCPF FILE(NERONI2/JRSNMSG) RCDLEN(112) + TEXT('Resend messages. Src') /* Copia il sorgente dalla stringa al membro del file sorgente. */ /* Modifica testo e tipo seu del sorgente caricato. */ CPYF FROMFILE(JRSNMSG) TOFILE(NERONI2/JRSNMSG) + TOMBR(JRSNMSG) MBROPT(*REPLACE) SRCOPT(*SEQNBR) CHGPFM FILE(NERONI2/JRSNMSG) MBR(JRSNMSG) + SRCTYPE(CMD) + TEXT('Resend messages. Cmd') /* Copia il sorgente dalla stringa al membro del file sorgente. */ /* Modifica testo e tipo seu del sorgente caricato. */ CPYF FROMFILE(JRSNMSG.) TOFILE(NERONI2/JRSNMSG) + TOMBR(JRSNMSG.) MBROPT(*REPLACE) SRCOPT(*SEQNBR) CHGPFM FILE(NERONI2/JRSNMSG) MBR(JRSNMSG.) + SRCTYPE(CL) + TEXT('Resend messages. Cjs') /* Copia il sorgente dalla stringa al membro del file sorgente. */ /* Modifica testo e tipo seu del sorgente caricato. */ CPYF FROMFILE(JRSNMSGC) TOFILE(NERONI2/JRSNMSG) + TOMBR(JRSNMSGC) MBROPT(*REPLACE) SRCOPT(*SEQNBR) CHGPFM FILE(NERONI2/JRSNMSG) MBR(JRSNMSGC) + SRCTYPE(CLLE) + TEXT('Resend messages. Cpp') /* Copia il sorgente dalla stringa al membro del file sorgente. */ /* Modifica testo e tipo seu del sorgente caricato. */ CPYF FROMFILE(JRSNMSGP) TOFILE(NERONI2/JRSNMSG) + TOMBR(JRSNMSGP) MBROPT(*REPLACE) SRCOPT(*SEQNBR) CHGPFM FILE(NERONI2/JRSNMSG) MBR(JRSNMSGP) + SRCTYPE(PNLGRP) + TEXT('Resend messages. Help') /*----------------------------------------------------------------------------*/ //DATA FILE(JRSNMSG) FILETYPE(*SRC) ENDCHAR('//ENDSRC') /* Claudio Neroni 19-08-1982 Creato. */ /* Resend messages. Cmd */ /* Rimanda messaggi. Cmd */ /* Rimanda al nonno i messaggi del padre */ /* trasformando gli escape in diagnostic. */ /* Claudio Neroni 09-06-2016 Modificato. */ /* Datrice resta sempre la coda programma del pgm chiamante. */ /* Reso invece variabile il pgm destinatario. */ /* Non piu' il chiamante del chiamante, che resta il default, */ /* ma il chiamante del programma ricevuto nel nuovo parametro REFPGM. */ CMD PROMPT('Resend messages') PARM KWD(RMV) TYPE(*CHAR) LEN(4) RSTD(*YES) + DFT(*NO) VALUES(*NO *YES) PROMPT('Remove + resent messages') PARM KWD(STR) TYPE(*CHAR) LEN(4) RSTD(*YES) + DFT(*YES) VALUES(*NO *YES) PROMPT('Start + message') PARM KWD(REFPGM) TYPE(*NAME) LEN(10) DFT(*CALLER) + SPCVAL((*CALLER)) PROMPT('Reference + program for messages') //ENDSRC /*----------------------------------------------------------------------------*/ //DATA FILE(JRSNMSG.) FILETYPE(*SRC) ENDCHAR('//ENDSRC') //BCHJOB JOB(JRSNMSG.) JOBD(NERONI2/NERONI2) OUTQ(QPRINTS) + ENDSEV(60) LOG(4 00 *SECLVL) MSGQ(*USRPRF) CCSID(280) jmy /* Claudio Neroni 19-08-1982 Creato. */ /* JRSNMSG */ /* Resend messages. */ /* Rimanda messaggi. */ /* Prerequisiti: nessuno. */ /* Imposta la lista librerie. */ CHGLIBL LIBL(QTEMP QGPL) ADDLIBLE LIB(NERONI2) POSITION(*AFTER QTEMP) /* Cancella il file messaggi preesistente. */ /* Cancella i testi d'aiuto preesistenti. */ DLTPNLGRP PNLGRP(NERONI2/JRSNMSGP) /* Cancella i logici preesistenti. */ /* Cancella i fisici preesistenti. */ /* Cancella i comandi preesistenti. */ DLTCMD CMD(NERONI2/JRSNMSG) /* Cancella i programmi preesistenti. */ DLTPGM PGM(NERONI2/JRSNMSGC) /* Crea i file fisici. */ /* Crea i file logici. */ /* Crea i comandi. */ CRTCMD CMD(NERONI2/JRSNMSG) PGM(JRSNMSGC) SRCFILE(JRSNMSG) + HLPPNLGRP(JRSNMSGP) HLPID(CMD) PRDLIB(NERONI2) /* Duplica i comandi in QGPL. */ CRTPRXCMD CMD(QGPL/JRSNMSG) TGTCMD(NERONI2/JRSNMSG) AUT(*USE) + REPLACE(*YES) /* Crea i programmi. */ CRTBNDCL PGM(NERONI2/JRSNMSGC) SRCFILE(JRSNMSG) LOG(*NO) + TGTRLS(*CURRENT) DBGVIEW(*ALL) /* Crea il file messaggi. */ /* Fotografia comandi (xxxA001). */ /* Messaggi comuni a pgm di comandi diversi (xxx0001). */ /* Messaggi nei pgm del Cmd 1 (xxx0101). */ /* Messaggi nei pgm del Cmd 2 (xxx0201). */ /* Messaggi dei Cmd (xxx1001). */ /* Crea i testi d'aiuto. */ CRTPNLGRP PNLGRP(NERONI2/JRSNMSGP) SRCFILE(JRSNMSG) //ENDBCHJOB //ENDSRC /*----------------------------------------------------------------------------*/ //DATA FILE(JRSNMSGC) FILETYPE(*SRC) ENDCHAR('//ENDSRC') /* Claudio Neroni 19-08-1982 Creato. */ /* Resend messages. Cpp */ /* Rimanda messaggi. Cpp */ /* Rimanda al nonno i messaggi del padre */ /* trasformando gli escape in diagnostic. */ /* Claudio Neroni 09-06-2016 Modificato. */ /* Datrice resta sempre la coda programma del pgm chiamante. */ /* Reso invece variabile il pgm destinatario. */ /* Non piu' il chiamante del chiamante, che resta il default, */ /* ma il chiamante del programma ricevuto nel nuovo parametro REFPGM. */ /* Claudio Neroni 10-06-2016 Modificato. */ /* Introdotta richiesta messaggio di partenza del reinvio, parametro STR. */ /* */ PGM PARM(&RMV &STR &REFPGM) /* Riceve Richiesta di rimuovere i messaggi ricevuti. */ DCL VAR(&RMV) TYPE(*CHAR) LEN(4) /* Riceve Richiesta di inserire un messaggio all'inizio della rispedizione. */ DCL VAR(&STR) TYPE(*CHAR) LEN(4) /* Riceve Programma di riferimento per i messaggi. */ DCL VAR(&REFPGM) TYPE(*CHAR) LEN(10) /* Dati per i messaggi. */ DCL VAR(&MSGDTA) TYPE(*CHAR) LEN(512) /* Testo di primo livello del messaggio. */ DCL VAR(&MSG) TYPE(*CHAR) LEN(512) /* Identificatore del messaggio. */ DCL VAR(&MSGID) TYPE(*CHAR) LEN(7) /* Tipo del messaggio. */ DCL VAR(&MSGTYPE) TYPE(*CHAR) LEN(7) /* Chiave del messaggio. */ DCL VAR(&KEYVAR) TYPE(*CHAR) LEN(4) /* Codice del tipo di messaggio ricevuto. */ DCL VAR(&RTNTYPE) TYPE(*CHAR) LEN(2) /* File messaggi. */ DCL VAR(&MSGF) TYPE(*CHAR) LEN(10) /* Libreria del file messaggi. */ DCL VAR(&MSGFLIB) TYPE(*CHAR) LEN(10) /* Identificazione del mittente di un messaggio. */ DCL VAR(&SENDER) TYPE(*CHAR) LEN(80) /* Nome del programma chiamante o padre. */ DCL VAR(&CALLER) TYPE(*CHAR) LEN(10) /* Intercetta gli errori imprevisti saltando a fine senza errori. */ MONMSG MSGID(CPF0000 MCH0000 CEE0000) EXEC(GOTO + CMDLBL(ENDPGM)) /* Se richiesto *CALLER, cerca il nome del programma padre. */ IF COND(&REFPGM *EQ *CALLER) THEN(DO) /* Manda un messaggio al padre. */ SNDPGMMSG MSG('Messaggio di comodo per + l''individuazione del programma padre.') + KEYVAR(&KEYVAR) /* Riceve il messaggio appena inviato rimuovendolo. */ RCVMSG PGMQ(*PRV) MSGTYPE(*INFO) MSGKEY(&KEYVAR) + RMV(*YES) SENDER(&SENDER) /* Dal campo mittente estrae il programma-ricevente-messaggio */ /* che corrisponde al chiamante-del-programma-corrente. */ CHGVAR VAR(&CALLER) VALUE(%SUBSTRING(&SENDER 56 10)) /* Assume il chiamante come programma di riferimento. */ CHGVAR VAR(&REFPGM) VALUE(&CALLER) /* Se richiesto *CALLER, cerca il nome del programma padre. */ ENDDO /* Se richiesto, invia Messaggio di inizio rispedizione. */ IF COND(&STR *EQ *YES) THEN(DO) SNDPGMMSG MSG('<--- Resending start --->') TOPGMQ(*PRV + (&REFPGM)) ENDDO /* Cicla. */ DOWHILE COND('1') /* Riceve un messaggio dalla coda del padre. */ RCVMSG PGMQ(*PRV) RMV(&RMV) KEYVAR(&KEYVAR) + MSG(&MSG) MSGDTA(&MSGDTA) MSGID(&MSGID) + RTNTYPE(&RTNTYPE) MSGF(&MSGF) + MSGFLIB(&MSGFLIB) /* Se non ce ne sono altri, abbandona. */ MONMSG MSGID(CPF0000) EXEC(LEAVE) IF COND(&RTNTYPE *EQ ' ') THEN(LEAVE) /* Trasforma il codicillo RTNTYPE nella decodifica MSGTYPE. */ /* Gli *ESCAPE (15) vengono rispediti come *DIAG (02). */ SELECT WHEN COND(&RTNTYPE *EQ '01') THEN(CHGVAR + VAR(&MSGTYPE) VALUE(*COMP)) WHEN COND(&RTNTYPE *EQ '02') THEN(CHGVAR + VAR(&MSGTYPE) VALUE(*DIAG)) WHEN COND(&RTNTYPE *EQ '04') THEN(CHGVAR + VAR(&MSGTYPE) VALUE(*INFO)) WHEN COND(&RTNTYPE *EQ '05') THEN(CHGVAR + VAR(&MSGTYPE) VALUE(*INQ)) WHEN COND(&RTNTYPE *EQ '08') THEN(CHGVAR + VAR(&MSGTYPE) VALUE(*RQS)) WHEN COND(&RTNTYPE *EQ '10') THEN(CHGVAR + VAR(&MSGTYPE) VALUE(*RQS)) WHEN COND(&RTNTYPE *EQ '14') THEN(CHGVAR + VAR(&MSGTYPE) VALUE(*NOTIFY)) WHEN COND(&RTNTYPE *EQ '15') THEN(CHGVAR + VAR(&MSGTYPE) VALUE(*DIAG)) OTHERWISE CMD(CHGVAR VAR(&MSGTYPE) VALUE(*INFO)) ENDSELECT /* Se l'identificatore del messaggio ricevuto non è bianco. */ IF COND(&MSGID *NE ' ') THEN(DO) /* Rispedisce il messaggio usando l'identificazione. */ SNDPGMMSG MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) + MSGDTA(&MSGDTA) TOPGMQ(*PRV (&REFPGM)) + MSGTYPE(&MSGTYPE) /* Se durante la spedizione rileva un errore, abbandona. */ MONMSG MSGID(CPF0000) EXEC(LEAVE) /* Se l'identificatore del messaggio ricevuto non è bianco. */ ENDDO /* Se l'identificatore del messaggio ricevuto è bianco. */ ELSE CMD(DO) /* Rispedisce il messaggio usando il testo di primo livello. */ SNDPGMMSG MSG(&MSG) TOPGMQ(*PRV &REFPGM) + MSGTYPE(&MSGTYPE) /* Se durante la spedizione rileva un errore, abbandona. */ MONMSG MSGID(CPF0000) EXEC(LEAVE) /* Se l'identificatore del messaggio ricevuto è bianco. */ ENDDO /* Cicla. */ ENDDO /* Ritorna. */ RETURN /* Label di fine. */ ENDPGM: SNDPGMMSG MSG('--> JRSNMSG: Resending error') ENDPGM //ENDSRC /*----------------------------------------------------------------------------*/ //DATA FILE(JRSNMSGP) FILETYPE(*SRC) ENDCHAR('//ENDSRC') :PNLGRP. .*------------------------------------------------------------------------------ :HELP NAME=CMD. :H3.Comando JRSNMSG :H2.Resend messages :P.Rimanda i messaggi del programma chiamante al chiamante del programma di riferimento. :P.Prerequisito della maggior parte delle altre utility da :HP2.neroni.it:EHP2. anche se non dichiarato. :P.I messaggi ricevuti da un CPP (Command Processing Program) sono visibili nella joblog di dettaglio del lavoro esecutore ma non risultano in evidenza, ad esempio, sul video comandi chiamante del comando eseguito dal CPP. Il presente comando, compilato all'interno di un CPP in Control Language, si incarica di mettere tali messaggi in bella vista ritrasmettendoli dalla coda messaggi di programma del CPP ospitante alla coda messaggi del programma di riferimento, presente nella lista di chiamata del CPP ospitante stesso. :H2.Genesi del tool :P.Tutti i programmatori costruttori di comandi mettono in fondo ai loro CPP in Control Language qualcosa per restituire i messaggi di errore al chiamante quando si presenta un errore imprevisto. :P.Non volendo ripetere in ogni CPP sempre le stesse istruzioni, questo tool, richiamato nel CPP solo se si presenta un errore imprevisto, provvede in proprio a rimandare al chiamante i messaggi ricevuti dal CPP. :P.All'inizio dei tempi basto' restituire i messaggi del padre al nonno. Recentemente, invece, la costruzione di tool piu' complessi e a piu' livelli ha reso necessario parametrizzare il nome del programma destinatario della rispedizione: non piu' solo il nonno (chiamante del chiamante) ma anche il chiamante di un programma di riferimento a piacere tra quelli in lista di chiamata. :EHELP. .*------------------------------------------------------------------------------ :HELP name='CMD/rmv'. :H3.Remove resent messages (RMV) :P.Richiede la rimozione dei messaggi rispediti dal programma chiamante al chiamante del programma di riferimento. :P.:HP2.Valori permessi::EHP2. :PARML. :PT.:PK DEF.*NO:EPK. :PD.Non rimuove dalla coda del padre i messaggi rispediti. :PT.*YES :PD.Rimuove dalla coda del padre i messaggi rispediti. :EPARML. :EHELP. .*------------------------------------------------------------------------------ :HELP name='CMD/str'. :H3.Start message (STR) :P.Richiede l'invio di un messaggio di inizio rispedizione. :P.Per chiarire dove iniziano i messaggi rispediti, e' stato introdotto un messaggio :HP2.<--- Resending start --->:EHP2. che viene inviato come intestazione alla stessa coda messaggi di programma alla quale saranno rispediti i messaggi del padre. :P.:HP2.Valori permessi::EHP2. :PARML. :PT.:PK DEF.*YES:EPK. :PD.Invia il messaggio di inizio rispedizione. :PT.*NO :PD.NON invia il messaggio di inizio rispedizione. :EPARML. :EHELP. .*------------------------------------------------------------------------------ :HELP name='CMD/refpgm'. :H3.Reference program for messages (REFPGM) :P.Programma di riferimento dei messaggi. :P.Nei tool complessi a piu' livelli, il presente parametro permette di condividere un programma di riferimento al cui chiamante verranno spediti tutti i messaggi di tutti i tool chiamati. :P.Normalmente il programma di riferimento e' il command processing program del tool di cappello che chiama tutti gli altri. :P.:HP2.Valori permessi::EHP2. :PARML. :PT.Nome del programma in lista di chiamata. :PD.Il nome di un programma presente nella lista di chiamata del programma corrente. :P.I messaggi emessi dal programma corrente saranno indirizzati al chiamante del programma di riferimento, preferibilmete un video comandi. :P.Utile quando il comando corrente e' chiamato da un altro comando. :EPARML. :P.:HP2.Valori speciali::EHP2. :PARML. :PT.:PK DEF.*CALLER:EPK. :PD.Il valore viene sostituito con il nome del programma chiamante del presente tool. :P.Utile quando il comando corrente e' usato per rimandare messaggi al chiamante in un tool a un solo livello. :P.Utile inoltre in tutti i vecchi utilizzi del presente tool. :EPARML. :EHELP. .*------------------------------------------------------------------------------ :HELP NAME='CMD/COMMAND/EXAMPLES'. :XH3.Esempi per JRSNMSG :P.:HP2.Esempio 1: Rimanda i messaggi eliminando gli originali.:EHP2. :XMP. Con i soli parametri necessari: :HP2. JRSNMSG RMV(*YES) :EHP2. Anche con i parametri di default: :HP2. JRSNMSG RMV(*YES) STR(*YES) REFPGM(*CALLER) :EHP2. :EXMP. :P.Questo comando, richiamato da un Command Processing Program quando viene intercettato in modo generico un errore imprevisto, tipicamente con un :HP2.MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERRORE)):EHP2., restituisce al chiamante del CPP tutti i messaggi accumulati nella coda del CPP stesso per evitare di costringere l'utente a cercarli nel log di tettaglio. I messaggi originali vengono rimossi dalla coda del CPP. :P.:HP2.Esempio 2: Rimanda i messaggi senza eliminare gli originali.:EHP2. :XMP. Con i parametri necessari: :HP2. JRSNMSG :EHP2. Anche con i parametri di default: :HP2. JRSNMSG RMV(*NO) STR(*YES) REFPGM(*CALLER) :EHP2. :EXMP. :P.Vale quanto detto nell'esempio 1 ma i messaggi originali non vengono rimossi dalla coda del CPP. :EHELP. .*------------------------------------------------------------------------------ :HELP NAME='CMD/ERROR/MESSAGES'. :XH3.Messaggi di errore :P.Vista la funzione marginale del comando, non e' stata considerato necessario interrompere l'esecuzione del chiamante in caso di malfunzionamento. :P.Nessun messaggio di rilascio viene quindi restituito al chiamante. :EHELP. .*------------------------------------------------------------------------------ :EPNLGRP. //ENDSRC //ENDBCHJOB