               <<< STAR::NOTESD$:[NOTES$LIBRARY]WIZARDS.NOTE;1 >>>
                            -<  "ASK THE WIZARDS" >-
================================================================================
Note 812.1           Open: network mailbox to exchange data?              1 of 2
GIDDAY::GILLINGS "a crucible of informative mistak" 419 lines  23-JUL-1996 22:07
                                -< reply sent >-
--------------------------------------------------------------------------------
  Nacho,

>Is it possible to create a network mailbox to exchange 
>data between two processes running in two Vax's in a LAN
>(there is no cluster) ?

    Certainly. There are numerous ways to achieve this. I have included
  an example of DECnet non-transparent task to task communication written
  in Pascal. You can obtain other examples from DSNlink.

						John Gillings, Sydney CSC

[DECnet-VAX] Nontransparent Task Source / Target Example In PASCAL


COPYRIGHT (c) 1988, 1993 by Digital Equipment Corporation.
ALL RIGHTS RESERVED. No distribution except as provided under contract.

Copyright (c) Digital Equipment Corporation 1991. All rights reserved
LAYERED PRODUCT: DECnet-VAX        OP/SYS: VMS V5.X

SOURCE:     Digital Customer Support Center


OVERVIEW:

Nontransparent task-to-task source/target program example in PASCAL

CAUTION:  This sample program has been tested using:
          PRODUCT: PASCAL on OPERATING SYSTEM: VMS V5.4

However, we cannot guarantee its effectiveness because of the possibility
of errors in transmitting or implementing it.  It is meant to be used
as a template for writing your own program, and it may require
modification for use on your system.


PROGRAM NOTES:

There are three program examples here.
        1. A command file to start the remote task
        2. Nontransparent task-to-task source program in PASCAL
        3. Nontransparent task-to-task target program in PASCAL

**************************************************************************
$! RECEIVE.COM
$!
$! This command file will run the receive process on the TARGETNODE.
$! This command file must be in the top level directory on the TARGET node.
$! If RECEIVE.EXE does not reside in the top level directory you must
$! specify    device:[directory]receive.exe
$!
$ RUN RECEIVE.EXE
$ EXIT


**************************************************************************

[INHERIT ('SYS$LIBRARY:STARLET')]

PROGRAM send (input, output);  { Nontransparent Task to Task Source }

{
CONST       iobsz                   = 70;
            ctrlz                   = 26;



TYPE        t_ubyte                 = [byte] 0..255;    {08bits 1byte}
            t_uword                 = [word] 0..65535;  {16bits 2bytes}
            t_ulong                 = [long] unsigned;  {32bits 4bytes}
            t_uquad                 = [quad, unsafe]    RECORD
                                                            l0,l1:unsigned;
                                                        END; {64bits 8bytes}

            t_mbx_buf   =   RECORD
                                msg_typ : t_uword;
                                unit    : t_uword;
                                name_sz : t_ubyte;
                                name    : PACKED ARRAY [1..15] OF char;
                                info_sz : t_ubyte;
                                info    : PACKED ARRAY [1..15] OF char;
                            END;

            t_iosb      =   RECORD
                                status,
                                dlen,
                                devdep1,
                                devdep2 : t_uword
                            END;





VAR         ncb                 :   [volatile] packed array [1..21] of char
                                               :='targetnode::"task=receive"';

            ncb_desc            :   [volatile] DSC1$TYPE;

            mbx_msg             :   t_mbx_buf;

            iosb                :   t_iosb;


            mbx_name    :   [volatile] PACKED ARRAY [1..7] OF char
                                                        := 'NET_MBX';

            dev_name    :   [volatile] PACKED ARRAY [1..5] OF char
                                                        := '_NET:';

            io_buf      :   PACKED ARRAY [1..iobsz] OF char;

            status      :   t_uword;

            mbx_chan,
            net_chan    :   t_uword;



PROCEDURE build_ncb;

{   Build the ncb descriptor   }

BEGIN
    WITH ncb_desc DO
        BEGIN
            DSC$W_MAXSTRLEN     := size(ncb);
            DSC$B_DTYPE         := DSC$K_DTYPE_VT;
            DSC$B_CLASS         := DSC$K_CLASS_VS;
            DSC$A_POINTER       := address(ncb)
        END
END;   { build_ncb }

BEGIN   { main }
    writeln('Sender');

    build_ncb;

    {   Create mailbox   }

    status := $crembx(  chan    := mbx_chan,
                        lognam  := mbx_name);

    IF NOT odd(status) THEN $exit(status);


    {   Assign a channel to the network device   }

    status := $assign(  devnam  := dev_name,
                        chan    := net_chan,
                        mbxnam  := mbx_name);

    IF NOT odd(status) THEN $exit(status);


    {   Set up a virtual call   }

    status := $qiow(    chan    := net_chan,
                        func    := IO$_ACCESS,
                        iosb    := iosb,
                        p2      := iaddress(ncb_desc) );

    IF NOT odd(status) THEN $exit(status);
    IF NOT odd(iosb.status) THEN $exit(iosb.status);


    {   Read mailbox to get the status of the connection   }

    status := $qiow(    chan    := mbx_chan,
                        func    := IO$_READVBLK,
                        iosb    := iosb,
                        p1      := mbx_msg,
                        p2      := size(mbx_msg));

    IF NOT odd(status) THEN $exit(status);
    IF NOT odd(iosb.status) THEN $exit(iosb.status);


    {   Loop to read lines from keyboard until control-z entered,
        send each line to remote process                            }

    write('> ');
    WHILE NOT eof DO
        BEGIN
            readln(io_buf);
            status := $qiow(    chan    := net_chan,
                                func    := IO$_WRITEVBLK,
                                iosb    := iosb,
                                p1      := io_buf,
                                p2      := size(io_buf) );

            IF NOT odd(status) THEN $exit(status);
            IF NOT odd(iosb.status) THEN $exit(iosb.status);

            write('> ');
        END;


    {   Send control-z to remote process to signal end of data   }

    status := $qiow(    chan    := net_chan,
                        func    := IO$_WRITEVBLK,
                        iosb    := iosb,
                        p1      := ctrlz,
                        p2      := 1        );

    IF NOT odd(status) THEN $exit(status);
    IF NOT odd(iosb.status) THEN $exit(iosb.status);



    {   Deaccess network channel   }

    status := $qiow(    chan    := net_chan,
                        func    := IO$_DEACCESS,
                        iosb    := iosb     );

    IF NOT odd(status) THEN $exit(status);
    IF NOT odd(iosb.status) THEN $exit(iosb.status);



    {   Deassign network device and mailbox channels   }

    status := $dassgn(  chan    := net_chan );

    IF NOT odd(status) THEN $exit(status);


    status := $dassgn(  chan    := mbx_chan );

    IF NOT odd(status) THEN $exit(status);


    $exit(ss$_normal);

END.

**************************************************************************

[INHERIT ('SYS$LIBRARY:STARLET')]

PROGRAM receive (input, output);  { Nontransparent Task to Task Target }

{
CONST       iobsz                   = 70;
            ctrlz                   = 26;


TYPE        t_ubyte                 = [byte] 0..255;    {08bits 1byte}
            t_uword                 = [word] 0..65535;  {16bits 2bytes}
            t_ulong                 = [long] unsigned;  {32bits 4bytes}
            t_uquad                 = [quad, unsafe]    RECORD
                                                            l0,l1:unsigned;
                                                        END; {64bits 8bytes}


            t_mbx_buf   =   RECORD
                             msg_typ : t_uword;
                             unit    : t_uword;
                             name_sz : t_ubyte;
                             name    : PACKED ARRAY [1..15] OF char;
                             info_sz : t_ubyte;
                             info    : [volatile] PACKED ARRAY [1..179] OF char;
                            END;

            t_iosb      =   RECORD
                                status,
                                dlen,
                                devdep1,
                                devdep2 : t_uword
                            END;

            word        =   [WORD] 0..65535;

            itemlist    =    RECORD
                CASE INTEGER OF               (* Build itmlst structure *)
                  1 : (buffer_length  : word; (*  for system service calls *)
                       code : word;
                       buffer  : INTEGER;
                       return_length  : INTEGER);
                  2 : (terminator : INTEGER);
                END;


VAR         ncb_desc    :   [volatile] DSC1$TYPE;

            length      :   word;

            mbx_msg     :   t_mbx_buf;

            iosb        :   t_iosb;

            mbx         :   DSC1$TYPE;


            mbx_name    :   [volatile] PACKED ARRAY [1..7] OF char
                                                        := 'NET_MBX';

            dev         :   DSC1$TYPE;

            dev_name    :   [volatile] PACKED ARRAY [1..5] OF char
                                                        := '_NET:';

            buffer      :   PACKED ARRAY [1..50] OF char;

            itmlst      :   PACKED ARRAY [1..6] OF itemlist;

            io_buf      :   PACKED ARRAY [1..iobsz] OF char;

            status      :   t_uword;

            mbx_chan    :   t_uword;

            net_chan    :   t_uword;

            fn_code     :   [unsafe] t_uword;

            table_name  :   PACKED ARRAY [1..17] OF char
                                            := 'LNM$PROCESS_TABLE';

            log_name    :   PACKED ARRAY [1..7] OF char
                                            := 'SYS$NET';
VALUE       ncb_desc    :=  (   0,
                                DSC$K_DTYPE_VT,
                                DSC$K_CLASS_VS,
                                0   );

BEGIN   { main }
    writeln('Receive');

    {   create mailbox }

    status := $crembx(  chan    := mbx_chan,
                        lognam  := mbx_name);
    IF NOT odd(status) THEN $exit(status);


    {   Assign channel to the network device   }

     status := $assign( devnam  := dev_name,
                        chan    := net_chan,
                        mbxnam  := mbx_name);
    IF NOT odd(status) THEN $exit(status);

    { Obtain the network control block by translating SYS$NET. }

        itmlst[1].buffer_length := 50;
        itmlst[1].code := LNM$_STRING;
        itmlst[1].buffer := IADDRESS(buffer);
        itmlst[1].return_length := IADDRESS(length);
        itmlst[2].terminator := 0;


    status := $trnlnm(  tabnam := table_name,
                        lognam := log_name,
                        itmlst := itmlst);

    IF NOT odd(status) THEN $exit(status);

    {   Load NCB descriptor }

    ncb_desc.DSC$W_MAXSTRLEN    := length;
    ncb_desc.DSC$A_POINTER      := iaddress(buffer);

    {   Accept the call   }

    fn_code := (IO$_ACCESS);

    status := $qiow(    chan    := net_chan,
                        func    := fn_code,
                        iosb    := iosb,
                        p2      := %ref(ncb_desc));

    IF NOT odd(status) THEN $exit(status);
    IF NOT odd(iosb.status) THEN $exit(iosb.status);

    {   Loop to read lines from remote process until control-z received   }

    REPEAT
        status := $qiow(        chan    := net_chan,
                                func    := IO$_READVBLK,
                                iosb    := iosb,
                                p1      := io_buf,
                                p2      := iobsz);

        IF NOT odd(status) THEN $exit(status);
        IF NOT odd(iosb.status) THEN $exit(iosb.status);

        IF ( io_buf[1] <> chr(ctrlz) ) THEN writeln(io_buf);

    UNTIL ( io_buf[1] = chr(ctrlz) );

    {   Clear the call   }

    status := $qiow(    chan    := net_chan,
                        func    := IO$_DEACCESS,
                        iosb    := iosb );

    IF NOT odd(status) THEN $exit(status);
    IF NOT odd(iosb.status) THEN $exit(iosb.status);


    {   Deassign network device and mailbox channels   }

    status := $dassgn(  chan    := net_chan );

    IF NOT odd(status) THEN $exit(status);


    status := $dassgn(  chan    := mbx_chan );

    IF NOT odd(status) THEN $exit(status);

    $exit(ss$_normal);

END.

