Manuale per la progettazione d'interfaccia Tivoli Service Desk 6.0 Developer's Toolkit

Capitolo 7: Utilizzo di CPIC

Ritorna all'Indice analitico


Introduzione

Panoramica

CPIC (Common Programming Interface for Communications) fornisce un'API consistente per applicazioni che richiedono la comunicazione da applicazione ad applicazione. L'interfaccia CPIC utilizza la LU 6.2 di SNA per creare una serie di servizi per applicazioni collegate, che comprende:

I comandi CPIC sono creati nel linguaggio del TSD Script per estendere questi servizi al programmatore del TSD Script. CPIC è stata scelta sulla base di macro APPC per assicurare la consistenza tra le piattaforme.

Questa sezione del manuale è concepita come una guida per i programmatori del TSD Script che utilizzano CPIC per creare i TP. Per informazioni dettagliate sulla programmazione CPIC SAA, fare riferimento al manuale IBM, Systems Application Architecture Common Programming Interface for Communications Reference, SC26-4399.

E' necessario che CPIC sia installato perché i comandi CPIC siano operativi. Se CPIC non è installato correttamente, l'utilizzo dei comandi CPIC provoca la visualizzazione, da parte del TSD Developer's Toolkit, di un messaggio di errore che indica che è stato impossibile caricare CPIC.

Condizioni & Concetti

APPC

APPC è un tipo di comunicazione avanzata peer to peer.

Conversazione di base

La conversazione di base è un tipo di conversazione in cui le applicazioni si scambiano i dati in un formato flusso di byte standard. Questo formato contiene campi di due-byte di lunghezza (denominati LL) che specificano la lunghezza del buffer che segue. Ogni raggruppamento di dati LL è denominato record logico.

Conversazione

Una conversazione è una connessione logica tra due applicazioni che utilizzano CPIC o APPC per scambiarsi i dati. Esistono due tipi di conversazione, mappata, e di base. Una conversazione connette le applicazioni tramite una sessione. Un'applicazione CPIC può conversare con un'applicazione APPC allo stesso modo in cui conversa con un'altra applicazione CPIC.

DDF

Un DDF è un file utilizzato per definire la relazione tra le strutture del record TSD Script e i buffer di byte trasmessi.

LU

Una LU (Logical Unit) è, in realtà, una macchina virtuale. E' possibile definire ogni macchina fisica come una LU ed è anche possibile configurare più LU in una macchina fisica. Notare che CPIC utilizza solo nodi LU Type 6.2.

Conversazione mappata

Una conversazione mappata è un tipo di conversazione che consente ai partner di scambiare i record dei dati in formati predeterminati.

Nome modalità

Un nome modalità viene utilizzato da APPC per definire le proprietà per la sessione tra le LU durante una conversazione. Queste proprietà comprendono la classe di servizio.

Servizio di nodo

Un servizio di nodo è un'applicazione (o serie di applicazioni) che fornisce le funzioni del programma di utilità di base per una LU. I servizi forniti comprendono la manipolazione di informazioni secondarie, l'elaborazione di avvio e di termine dell'applicazione. I servizi di nodo di OS/2 sono forniti da CM (Communications Manager) o CM/2 (Communications Manager/2).

Partner

I partner sono due applicazioni CPIC che si scambiano dati su conversazioni CPIC.

Le conversazioni CPIC possono essere full duplex. Ciò indica che, in un momento specificato della conversazione CPIC, un partner ha la possibilità di inviare e l'altro è in stato di ricezione (cioè, è pronto a ricevere i dati). Un'applicazione in stato di ricezione può emettere una richiesta di invio quando necessita di inviare dati. Al partner viene notificata la richiesta e l'applicazione richiedente ne riceve notifica nel parametro StatusReceived.

SDN

SDN (Symbolic Destination Name) è un nome di configurazione CPIC in CM/2 che consente a un'applicazione di indicare una serie di attributi da utilizzare per la richiesta di assegnazione della conversazione.

Sessione

Una sessione è una connessione logica tra due LU. Le LU comunicano attraverso le sessioni.

Informazioni secondarie

Informazioni di inizializzazione utilizzate da CPIC durante un tentativo di stabilire una conversazione. Le informazioni secondarie comprendono il nome LU del partner, il nome modalità e il nome TP. Queste informazioni vengono configurate prima della conversazione.

Nota:Si fa riferimento alle informazioni secondarie come a un SDN.

Rete SNA

Una rete SNA è una rete logica di LU.

Livello di sinc.

Livello di sinc. indica il grado di sincronizzazione utilizzato da una conversazione CPIC. Il livello di sinc. può essere uno dei seguenti:

SYNC_POINT

SYNC_POINT indica che l'applicazione supporta operazioni complete di Correzione risorsa SAA come le notifiche Take Commit e Take Backout.

Nota: SYNC_POINT non è supportato in OS/2.

TP

TP (Transaction Program) è un'applicazione che utilizza comandi CPIC o APPC per partecipare a una conversazione.

Nome TP

Il nome TP è il nome di un'applicazione di transazione. Questo nome è specificato nelle informazioni secondarie. A seconda del sistema operativo, il nome TP può specificare una voce tabella per l'applicazione servizi nodo della LU di destinazione. Questa tabella viene utilizzata per consultare le informazioni necessarie per avviare il TP.

Avvio di una conversazione con un altro programma

Esempio di una conversazione semplice

Di seguito è riportato un breve esempio del metodo utilizzato quando un'applicazione avvia una conversazione con un'altra applicazione.

  1. Il Programma A emette un comando CPICInitialize per prepararsi ad avviare la conversazione. Fornisce un SDN per designare il Programma C come destinazione della conversazione. Il Programma A riceve un identificativo univoco per la conversazione.
  2. Il Programma A emette un comando CPICAllocate che utilizza l'identificativo della conversazione.
  3. Tramite servizi di nodo, CPIC riferisce alla LU del partner (specificato nelle informazioni secondarie utilizzate nella fase 1) che il Programma C è stato avviato per accettare la nuova conversazione.
    Risultato: Il Programma C si avvia ed emette il comando CPICAccept. Riceve un identificativo della conversazione da utilizzare per successivi comandi CPIC scambiati durante la conversazione.

DDF del TSD Script

Panoramica

TSD Script non consente il controllo diretto della dimensione assegnata delle strutture di memoria, che evita ai programmatori di preoccuparsi della dimensione dei record dichiarati.

Sebbene questo sia considerato un attributo interessante per un linguaggio di quarta generazione, può presentare difficoltà nella gestione di applicazioni CPIC. Le applicazioni CPIC inviano e ricevono buffer di byte di un formato e una dimensione specifici. Un'applicazione del partner può utilizzare formati di memoria diversi da quella locale, compresi i numeri interi non-Intel e stringhe di caratteri EBCDIC.

I DDF indicano la possibilità di utilizzare dimensioni di buffer differenti. Un DDF definisce il tipo adatto di un buffer di byte trasmessi e specifica la traduzione/conversione dl formato. TSD Developer's Toolkit utilizza questi DDF come "filtri" per i buffer, sia in entrata che in uscita, di un'applicazione CPIC.

La struttura di base di un DDF è:

-- Doppio trattino indica un commento alla fine della riga.
-- La prima sezione è quella del partner.
*PARTNER
-- tipi di conversione carattere
EBCDIC=TRUE
-- ordine byte numero intero
NON_INTEL=TRUE
-- tabella di conversione carattere. Se non specificata, TSD
Developer's
Toolkit
-- utilizza la tabella AE CM/2. Questa tabella di default
-- può risultare insufficiente (ad esempio, essa
-- converte spazi incorporati in x'00'). Se si desidera una
-- tabella di conversione più normale, impostare il nome
file della tabella
-- di traduzione CM/2 su ACSGTAB.DAT, fornito con
-- CM/2. Quindi, impostare CUSTOM_CONVERT su TRUE.
CUSTOM_CONVERT=TRUE
-- Questa è la sezione campo. Viene utilizzata
-- 11 per descrivere ogni campo del record e la sua traduzione
-- e definizione byte. In sostanza, questa sezione
-- mostra come il buffer dei dati dovrebbe apparire appena
-- ricevuto (prima della conversione) o appena prima di un
-- invio (dopo la conversione).
*FIELDS
-- Fieldname Type ByteWidth SendUnknowns? Default
   name CHAR 20 FALSE
   street CHAR 20 TRUE
   age INTEGER 20 TRUE
   birthDate CCYYMMDD 8 FALSE

In questo esempio, l'applicazione del partner esegue su una macchina EBCDIC con numeri interi di stile non-Intel (come un IBM System 370). Il record inviato viene dichiarato in TSD Script come segue:

SomeRecordName IS RECORD
   name :STRING;
   street :STRING;
   age :INTEGER;
   birthDate :DATE;
   description:STRING;
END;

Il campo descrizione non è compreso nel DDF, ciò significa che il campo descrizione non viene trasferito durante le comunicazioni CPIC.

Sezione Partner

Questa sezione di un DDF descrive il tipo di macchina dell'applicazione del partner. L'inizio di questa sezione è contrassegnato dal testo *PARTNER. La sezione del partner indica i tipi di conversioni di dati che TSD Developer's Toolkit esegue. Ad esempio, impostando EBCDIC=TRUE, TSD Developer's Toolkit converte tutte le stringhe di caratteri in e da EBCDIC quando comunica con l'applicazione del partner.

Attributi del partner

Nella sezione Partner, è necessario impostare i seguenti attributi. Ogni attributo non impostato prende il valore di default indicato.

Sezione Campi

Questa sezione DDF specifica i campi e i tipi di campo da impacchettare o spacchettare in buffer di dati CPIC. Questa sezione nel DDF comincia con la riga che contiene "*FIELDS". Ogni riga nella sezione Campi si applica a un campo record TSD Script trasferito. Il formato di tale riga è il seguente:

{fieldname} {fieldtype} {bytewidth} {sendunknowns?} {default}

Ogni colonna è divisa da spazi bianchi; di seguito sono elencate le definizioni di colonna:

Comando $INCLUDE

Il comando $INCLUDE semplifica l'organizzazione di un DDF. Questo comando fornisce la possibilità di "collegare" altri file dinamicamente. Quando TSD Developer's Toolkit è sottoposto al comando $INCLUDE, carica il DDF specificato e colloca le sue definizioni di campo nel DDF corrente.

Il comando $INCLUDE può essere incluso in un qualsiasi punto della sezione Campi. Il formato del comando $INCLUDE è:

$INCLUDE({DDFname})

Se il file non è nella directory corrente, TSD Developer's Toolkit inquiry il DPATH per il file. Se non viene trovato, TSD Developer's Toolkit restituisce un errore.

Comando $SIZEOF

Il comando $SIZEOF ricalcola automaticamente la dimensione dei file inclusi. Non è necessario che i file inclusi vengano ricontati manualmente se viene aggiunto ad essi un altro campo.

I comandi $SIZEOF e $INCLUDE vengono utilizzati in casi speciali, come nel caso dell'impostazione di un buffer a vettori. Possono essere utilizzati in combinazioni come:

*PARTNER
   EBCDIC =TRUE
   NON_INTEL =TRUE
   CUSTOM_CONVERT =TRUE
*FIELDS
GDS1310 INT 2 TRUE 4880
GDS1311LEN INT 2 TRUE
   $SIZEOF(1311.DDF) + 2 $INCLUDE(1311.DDF)
GDS1549LEN INT 2 TRUE
   $SIZEOF(1549.DDF) + 2 $INCLUDE(1549.DDF)
DataLen INT 2 TRUE
   $SIZEOF(RTRNDATA.DDF) + 2 $INCLUDE(RTRNDATA.DDF)

Tipi di campo DDF

I tipi riconosciuti per l'elaborazione del DDF sono:

Utilizzo di CPIC con CM/2

Panoramica

E' necessario conoscere alcuni dettagli prima di tentare di scrivere un'applicazione CPIC OS/2. Alcuni possono essere raggruppati per tipo di servizi di nodo presenti sul sistema.

Assegnazioni in entrata

Per il modo in cui servizi di nodo imposta un TP per ricevere un'assegnazione in entrata, un'applicazione CPIC OS/2 non può essere un SNA Service TP. Consultare le fasi successive che riassumono come viene gestita un'assegnazione in entrata:

  1. Servizi di nodo avvia un processo e imposta una variabile di ambiente denominata APPCTPN uguale al nome TP.
  2. Quando l'applicazione emette un comando Accetta, servizi di nodo controlla il APPCTPN dell'ambiente che accetta l'applicazione.
  3. Servizi di nodo esegue la scansione dell'elenco delle assegnazioni in entrata in attesa per una con lo stesso nome TP.
  4. Se il nome viene trovato, servizi di nodo completa la chiamata. Poiché i nomi TP del servizio SNA cominciano con un numero esadecimale, non è possibile impostarli in una variabile di ambiente OS/2.

Più applicazioni TSD Script con i TP

Se si dispone di più di un'applicazione TSD Script per cui si desidera impostare un TP, è necessaria un'impostazione speciale. CM/2 consente solo di specificare kml.exe come file e PATH dell'applicazione OS/2 per una definizione TP. Per l'altra, creare un file di comandi OS/2 contenente i seguenti comandi:

SET APPCTPN={il nome TP}
START /C KML /U{il percorso ai KB} {il nome KB}
EXIT

CM/2 Versione 1.1 (CM/2)

CM/2 consente a un processo CPIC singolo di accettare più conversazioni. Inoltre, un'applicazione CPIC può emettere un comando Inizializza se non è stato precedentemente emesso alcun comando Accetta.

Studio di CPIC TSD Script

Panoramica

Questa sezione è un breve studio del processo di creazione di un'applicazione CPIC semplice. L'applicazione è concepita per completare un trasferimento di file.

Per illustrare i benefici di CPIC, lo studio dispone di due moduli di esempio. L'applicazione viene creata nel primo modulo di esempio. Nel secondo modulo di esempio, sono state apportate minori modifiche all'applicazione per migliorare le prestazioni.

Presupposti

Questo studio fa una serie di ipotesi sulla familiarità dell'utente con CPIC, CM/2 e l'elaborazione delle comunicazioni in generale. Ad esempio, si presume che l'utente abbia familiarità con il programma di utilità CMSETUP di CM/2.

L'applicazione del partner (RCV.CMD)

Per cominciare, rivisualizzare l'applicazione del partner scritta in REXX.

L'applicazione REXX del partner è denominata RCV.CMD. In sostanza, questa applicazione riceve i dati (memorizzandoli in una variabile stem) fino a quando il parametro stato ricevuto non indica che l'applicazione può inviare i dati.

Dopo questo esempio di codice seguono spiegazioni che forniscono ulteriori dettagli sull'applicazione.

/* RCV.CMD */
/* Riceve le stringhe di dati, creando un buffer di tutti i dati.
/*Al completamento della*/
/* ricezione, manda indietro il buffer. */
/* Comandi CPIC utilizzati: CMACCP */
/*                     CMCFMD */
/*                     CMDEAL */
1/*                     CMRCV */
/*                     CMSEND */ 
/* alcune costanti utili */
CM_OK               = 0
/* stato ricevuto */
CM_SEND_RECEIVED    = 1
CM_CONFIRM_RECEIVED = 2
/* dati ricevuti */
CM_NO_DATA_RECEIVED = 0
MaxLength           = 257;
BufferLen           = 0;
FileBuffer.0        = 0;
'CPICREXX' 
address cpicomm
'CMACCP Conv_ID RetC';
if \(RetC = CM_OK) then do
     SAY 'ACCP = 'Retc
   end; 
'CMRCV Conv_ID Data MaxLength DataReceived
ReceivedLength StatusRecvd ReqToSendRecvd Retc';
if \(RetC = CM_OK) then do 
      SAY 'RCV = 'Retc
   end; 
do while (RetC = CM_OK) &
  (StatusRecvd \= CM_SEND_RECEIVED)
  if (DataReceived \= CM_NO_DATA_RECEIVED) then do
/*    SAY Data */
      FileBuffer.0 = FileBuffer.0 + 1;
      i = FileBuffer.0;
      FileBuffer.i = Data;
   end;
   if (StatusRecvd = CM_CONFIRM_RECEIVED) then do
      'CMCFMD Conv_ID RetC';
   end; 
   'CMRCV Conv_ID Data MaxLength DataReceived
    ReceivedLength StatusRecvd ReqToSendRecvd Retc';
   if (RetC \= CM_OK) then do
      SAY 'RCV = 'Retc
end; 
   end; 
SAY 'Re-transmitting file' 
DO i = 1 TO FileBuffer.0
   BufferLen = LENGTH(FileBuffer.i);
   Data = FileBuffer.i;
   'CMSEND Conv_ID Data BufferLen ReqToSendRecvd RetC';
   if (RetC \= CM_OK) then do 
      SAY 'SND = 'Retc
   end; 
END;
'CMDEAL Conv_ID RetC';
address cmd
'EXIT'

Modulo di esempio 1 - FILESND.KB

L'obbiettivo di questa applicazione è di leggere un file di testo e trasmettere ogni riga a un'applicazione del partner. Dopo che l'applicazione ha completato il trasferimento del file, comincia a ricevere nuovamente lo stesso file e visualizza ogni riga in una finestra di visualizzazione.

  1. Analizzare il file col comando KP FILESND.
  2. Avviare l'applicazione CMSETUP dalla cartella CM/2.
    Risultato: Viene visualizzata la casella di dialogo Programma di utilità configurazione CM CPI.
  3. Immettere il nome FILESND nella casella di dialogo.
  4. Dal menu Comunicazioni CPI, selezionare Caratteristiche SNA.
    Risultato: Viene visualizzata la casella di dialogo Definizione configurazione CM/2.
  5. Impostare la voce per informazioni secondarie.
  6. Nella casella di dialogo Caratteristiche SNA, selezionare la voce Informazioni secondarie comunicazioni CPI.
  7. Selezionare Crea.
  8. Immettere quanto segue nella casella di dialogo:
    SDN = FILESND
    LU di destinazione= {il nome della macchina di destinazione}
    Nome TP = FILERCV
    Sicurezza = NONE
    Modalità = #INTER
  9. Selezionare OK.
  10. Selezionare la voce Definizioni TP
  11. Selezionare Crea.
  12. Immettere questi valori nella casella di dialogo:
    TP servizio = deselezionato
    Nome TP = FILERCV
    Nome file e PERCORSO Programma OS/2 = CMD.EXE
    Richiesta sicurezza conversazione = deselezionato
    Parametri del Programma = /C {PERCORSO al codice d'istruzione}RCV.CMD
  13. Selezionare Continua.
  14. Immettere quanto segue:
    Tipo presentazione = Sfondo
    Tipo operazione = Accodato, Attach Manager avviato

Rivisualizzazione della procedura di impostazione

A partire dalla Fase 3, si imposta una voce nella Tabella di informazioni secondarie di CM/2. La Tabella di informazioni secondarie viene utilizzata durante l'inizializzazione di una conversazione. L'inizializzazione si verifica come segue:

  1. Un'applicazione richiama CPICInitialize, passando un SDN come parametro. Un SDN agisce da chiave per la Tabella di informazioni secondarie.
  2. CPIC utilizza SDN per impostare attributi per la nuova conversazione. Gli attributi possono rappresentare la macchina di destinazione e il TP.

Utilizzando questo metodo, possono essere scritte applicazioni CPIC che non hanno informazioni a codice fisso e specifiche del sito. Fornisce anche un metodo standard per tutte le applicazioni CPIC per accedere a questo tipo di informazioni.

A partire dalla Fase 8, viene creata una definizione TP. Questa voce indica a servizi di nodo come avviare uno specifico TP.

Quando viene assegnata una conversazione, la LU che ha richiesto l'assegnazione invia il nome TP desiderato al sistema servizi di nodo della LU di destinazione. Il sistema servizi di nodo controlla se quel nome TP è definito sul sistema. Se è definito, servizi di nodo segue le istruzioni su come avviare TP. Se è possibile, avvia l'applicazione con esito positivo (quando l'Attach Manager avviato è stato impostato per il TP). Il TP, ora, emette un CPICAccept. La LU richiedente riceve un'indicazione di riuscita e la conversazione viene avviata.

Per questa applicazione REXX, si avvia un elaboratore comando OS/2 (CMD.EXE). La stringa parametro indica a CMD.EXE di uscire quando il comando è stato completato (/C) e quale comando eseguire (RCV.CMD).

Avvio del file RCV.CMD dalla riga comandi

La parte successiva dello studio avvia il file RCV.CMD dalla riga comandi OS/2.

  1. Impostare un indicatore che avverta CM/2 di quale TP è in attesa di una conversazione in entrata. Per fare ciò, impostare una variabile di ambiente per la sessione comando:

    SET APPCTPN=FILERCV

    (Facoltativo) Per evitare di attendere a lungo un'assegnazione in entrata, è possibile modificare l'NDF (Node Definition File) nella directory CMLIB. Questo file ha lo stesso nome del file di configurazione CM/2.
  2. Cercare la sessione che definisce gli attributi per il TP FILERCV (ricerca FILERCV).
  3. Modificare INCOMING_ALLOCATE_TIMEOUT e RECEIVE_ALLOCATE_TIMEOUT in numeri interi positivi (le unità sono in secondi-180 per ognuno è un buon punto di riferimento).
  4. Salvare il file.
  5. Per rendere effettive queste modifiche, avviare il programma di utilità Impostazione CM e apportare ai campi di dati modifiche sufficienti perché Impostazione CM verifichi nuovamente e applichi le modifiche dinamicamente.
  6. Eseguire l'applicazione REXX immettendo RCV e premendo INVIO.
    Risultato: L'applicazione viene sospesa fino a quando non arriva un'assegnazione o non viene oltrepassato il supero tempo per RECEIVE_ALLOCATE_TIMEOUT. Al completamento, questa applicazione termina l'elaborazione del comando corrente.
    Nota: Non avviare l'applicazione REXX fino a quando non si è pronti ad avviare FILESND.KB.

Esecuzione di FILESND.KB

Ciò trasmette il file origine da una all'altra applicazione e viceversa, quindi visualizza i risultati in una finestra.

E' possibile che occorra del tempo perché venga completato il doppio trasferimento. Sotto l'elenco dei file nella finestra, è possibile visualizzare i risultati della tempificazione.

Inoltre, notare il numero di riga di ogni riga del file. Questi numeri sono stati trasmessi, da un'applicazione all'altra, con ogni riga del file di testo.

Elenco di righe FILESND.KB

Dopo questa sezione di righe numerate segue una discussione sul file.

1
2      KNOWLEDGEBASE FILESND;
3
4      ROUTINES
5      PROCEDURE DoConversation(VAL Args:List of String);
6                              (* sdn, infile *)
7
8
9      PRIVATE
10
11     CONSTANTS
12        CPIC_SUCCESS IS 1;
13
14     TYPES
15        FileRec IS RECORD
16           LineNbr:Integer;
17           Buff:String;
18        END;
19
20     ROUTINES
21
22     FUNCTION RcvData(REF w:WINDOW, VAL
                        Conv:Conversation)
                        :INTEGER IS
23     VARIABLES
24        totalBuff :FileRec;
25        dataRcvd  :integer;
26        statRcvd  :integer;
27        reqTSRcvd :integer; 
28        rc        :integer; 
29     ACTIONS 
30        IF (not(Known(w))) THEN 
31        WinCreateScrollWindow($DESKTOP,w, 
32                              $NullHandler, 
                                1,1,67,7, 
                                'FileSnd','', 0, 
                                $WinBorder+ 
                                $WinTitle+ 
                                $WinHScroll+ 
                                $WinVScroll+ 
                                $WinSysMenu+ 
                                $WinResize); 
          END; 
33       REPEAT 
34       rc := CPICReceive(Conv,'FILEREC.DDF', 
                           totalBuff,DataRcvd, 
                           StatRcvd,ReqTSRcvd); 
35          IF (rc > 0) THEN 
36          IF ((StatRcvd = $CPICConfirmReceived) or 
37             (StatRcvd = $CPICConfirmSend 
                Received)) THEN 
38              rc := CPICConfirmed(Conv); 
39        END; 
40            totalBuff.buff := StrTrim 
                                (totalBuff.buff); 
41             WinWriteLn(w,totalBuff.lineNbr:5&' 
                         :'&totalBuff.buff); 
42        END; 
43       UNTIL ((rc <> 1) OR ((StatRcvd = 
                            $CPICSendReceived) OR 
44                  (StatRcvd = $CPICConfirmSend 
                     Received))); 
45       Exit(rc); 
46    END; -- RcvData
47
48
49 ---------------------------------------------
50 -- Description: Reads in the specified file,
      transmitting each line via CPIC
51 -- to the partner specified through the
      given SDN.
52 ---------------------------------------------
53 PROCEDURE DoConversation(VAL Args:List of
                            String) IS 
54 VARIABLES 
55    Conv     :Conversation; 
56    fRec     :FileRec; 
57    ReqTSRcvd:INTEGER; 
58    rc       :INTEGER; 
59    inf      :FILE; 
60    w        :WINDOW; 
61    t1,t2    :TIME; 
62 ACTIONS 
63    t1       := $NOW; 
64    IF (ListLength(Args) <2) THEN WinMessageBox($DESKTOP,