HP3000-L Archives

August 1999, Week 1

HP3000-L@RAVEN.UTC.EDU

Options: Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Subject:
From:
"\"Hanka\" S.A." <[log in to unmask]>
Reply To:
"Hanka" S.A.
Date:
Thu, 5 Aug 1999 06:47:39 +0200
Content-Type:
text/plain
Parts/Attachments:
text/plain (802 lines)
001000* Dedicateted to all Unix fans ;).
001100*96/10/06
001200$CONTROL SYNC32, INDEX32, OPTIMIZE, NOLIST
001300*=========================================================
001400* This is COBOL/iX version of SOCKCLTC.NET.SYS program,
001500* timeouts are not implemented.
001600* Conversion done by J. Rodzewicz.
001700* Link with SOCKETRL.NET.SYS relocatable library.
001800*=========================================================
001900 IDENTIFICATION DIVISION.
002000 PROGRAM-ID. SOCKCLTP.
002100*---------------------------------------------------------
002200* Constants defines for socket library
002300*---------------------------------------------------------
002400 REPLACE
002500  ==AF_INET==     BY ==2==
002600
002700  ==INADDR_ANY==  BY ==0==
002800
002900  ==SOCK_STREAM== BY ==1==
003000  ==SOCK_DGRAM==  BY ==2==.
003100*=========================================================
003200 DATA DIVISION.
003300*=========================================================
003400 WORKING-STORAGE SECTION.
003500*---------------------------------------------------------
003600 01 INFO-LEN            PIC S9(4) COMP.
003700 01 I-STATUS            PIC S9(4) COMP.
003800 01 C-JCW               PIC X(5) VALUE "CJCW ".
003900 01 C-EXIT-CODE         PIC S9(4) COMP VALUE 0.
004000 01 CHAR-0              PIC X VALUE %0.
004100 01 MODULO              PIC S9(4) COMP.
004200 01 INT-CONV            PIC S9(4) COMP.
004300 01 CHAR-CONV           REDEFINES INT-CONV.
004400    05 FILLER           PIC X.
004500    05 INT-CHAR         PIC X.
004600
004700 01 IDENT               PIC X(38)
004800      VALUE "@(#)  CLIENT(Cobol/iX)  10/6/96   1.0".
004900
005000  01 CDES               PIC S9(9) COMP.
005100  01 SOCK-TYPE          PIC S9(9) VALUE SOCK_STREAM.
005200  01 ER                 PIC S9(9) COMP.
005300  01 ERRNO              EXTERNAL PIC S9(9) COMP.
005400  01 ERR-DISP           PIC -(9)9.
005500  01 DISP2              PIC -9.
005600  01 DISP4              PIC -(3)9.
005700  01 DISP5              PIC -(4)9.
005800
005900 01 DIE                 PIC S9(4) COMP VALUE 0.
006000
006100 01 PORT-FLAG           PIC S9(4) COMP VALUE 0.
006200    88 PORT-SPEC        VALUE 1.
006300 01 SERV-NAME-FLAG      PIC S9(4) COMP VALUE 0.
006400    88 SERV-NAME-SPEC   VALUE 1.
006500 01 IP-FLAG             PIC S9(4) COMP VALUE 0.
006600    88 IP-SPEC          VALUE 1.
006700 01 KILL-FLAG           PIC S9(4) COMP VALUE 0.
006800    88 KILL-SERVER      VALUE 1.
006900 01 PRINT-FLAG          PIC S9(4) COMP VALUE 0.
007000    88 PRINT-ALL        VALUE 1.
007100
007200 01 MSG-COUNT           PIC S9(9) COMP VALUE 3.
007300 01 MSG-LEN             PIC S9(9) COMP VALUE 10.
007400 01 CHAR-SET            PIC X VALUE "n".
007500 01 CHAR-START          PIC S9(4) COMP VALUE 48.
007600 01 CHAR-SET-SIZE       PIC S9(4) COMP VALUE 10.
007700
007800 01 SERVER-ID.
007900    05 S-CHAR           PIC X OCCURS 1 TO 255 TIMES
008000                        DEPENDING ON ID-LEN.
008100 01 ID-LEN              PIC S9(9) COMP VALUE 255.
008200
008300* variables local to PARSE-ARGS
008400 01 ARG-MARKER          PIC S9(4) COMP.
008500 01 TEMP-LOC            INDEX.
008600 01 ARG-CNT             PIC S9(4) COMP.
008700 01 ARG-LEN             PIC S9(4) COMP.
008800 01 ARG-TYPE            PIC X.
008900 01 I                   PIC S9(9) COMP.
009000
009100* variables local to DO-RECV
009200 01 LOCAL-LEN           PIC S9(9) COMP.
009300 01 TOTAL-SO-FAR        PIC S9(9) COMP.
009400 01 ADDR-LEN            PIC S9(9) COMP.
009500 01 XX                  PIC S9(9) COMP.
009600
009700* variables local to CLIENT
009800 01 LEN                 PIC S9(9) COMP.
009900 01 X                   PIC S9(9) COMP.
010000 01 Y                   PIC S9(9) COMP.
010100
010200 01 HOSTENT-PTR         PIC S9(9) COMP.
010300*/ struct hostent /*
010400 01 HOSTENT.
010500    05 H-NAME           PIC S9(9) COMP.
010600    05 H-ALIASES        PIC S9(9) COMP.
010700    05 H-ADDRTYPE       PIC S9(9) COMP.
010800    05 H-LENGTH         PIC S9(9) COMP.
010900    05 H-ADDR-LIST      PIC S9(9) COMP.
011000
011100 01 IP-ADDR-PTR         PIC S9(9) COMP.
011200 01 BUF-PTR             PIC S9(9) COMP.
011300
011400*/ struct sockaddr_in /*
011500 01 SERVER-ADDR.
011600    05 SIN-FAMILY       PIC S9(4) COMP.
011700    05 SIN-PORT         PIC S9(4) COMP.
011800    05 SIN-ADDR         PIC S9(9) COMP.
011900    05 SIN-ZERO         PIC X(8).
012000
012100*/ struct sockaddr_in /*
012200 01 CLIENT-ADDR.
012300    05 SIN-FAMILY       PIC S9(4) COMP.
012400    05 SIN-PORT         PIC S9(4) COMP.
012500    05 SIN-ADDR         PIC S9(9) COMP.
012600    05 SIN-ZERO         PIC X(8).
012700
012800*/ struct sockaddr_in /*
012900 01 LOCAL-ADDR.
013000    05 SIN-FAMILY       PIC S9(4) COMP.
013100    05 SIN-PORT         PIC S9(4) COMP.
013200    05 SIN-ADDR         PIC S9(9) COMP.
013300    05 SIN-ZERO         PIC X(8).
013400
013500*/ struct comm_desc /*
013600 01 SERVER-CONTROL.
013700    05 NUM-MSGS         PIC S9(9) COMP.
013800    05 MSG-SIZE         PIC S9(9) COMP.
013900    05 MSG-SET          PIC X.
014000
014100* communication buffer
014200 01 BUF.
014300    05 BUF-LOC          PIC X OCCURS 1 TO 5000 TIMES
014400                        DEPENDING ON BUF-LEN
014500                        INDEXED BY CURR-LOC.
014600
014700 01 BUF-LEN             PIC S9(9) COMP VALUE 5000.
014800*========================================================
014900 PROCEDURE DIVISION.
015000*========================================================
015100$DEFINE %Perform=
015200     PERFORM !1
015300        THRU !1-EXIT#
015400
015500$DEFINE %CExit=
015600    MOVE !1 TO C-EXIT-CODE
015700    CALL INTRINSIC "PUTJCW"
015800         USING C-JCW, C-EXIT-CODE, I-STATUS
015900    STOP RUN#
016000*========================================================
016100 MAIN-LINE SECTION.
016200 PERFORM
016300    %Perform(PARSE-ARGS#)
016400    IF KILL-SERVER
016500       %Perform(KILL-IT#)
016600    ELSE
016700       %Perform(DUMP-PARMS#)
016800       %Perform(CLIENT#)
016900    END-IF
017000 %CExit(0#)
017100 END-PERFORM.
017200*---------------------------------------------------------
017300* Parse command line (INFO string) parameters
017400*---------------------------------------------------------
017500 PARSE-ARGS.
017600 PERFORM
017700    MOVE SPACES TO BUF
017800    MOVE 5000 TO INFO-LEN
017900    CALL INTRINSIC "GETINFO" USING BUF, INFO-LEN
018000      GIVING I-STATUS
018100    IF I-STATUS <> 0
018200       DISPLAY "ERROR in GETINFO"
018300       %CExit(1#)
018400    END-IF
018500    %Perform(ARG-COUNT#)
018600
018700    IF ARG-CNT = 0
018800       DISPLAY "ERROR in argument list: missing options"
018900       MOVE 1 TO DIE
019000       %Perform(DO-HELP#)
019100    END-IF
019200
019300    MOVE 0 TO X
019400    %Perform(FIRST-ARG#)
019500    PERFORM WITH TEST AFTER UNTIL X = ARG-CNT
019600***     argument must start with "-"
019700       IF BUF-LOC(CURR-LOC) <> "-"
019800          DISPLAY "ERROR in argument list"
019900          MOVE 1 TO DIE
020000          %Perform(DO-HELP#)
020100       END-IF
020200
020300       SET CURR-LOC UP BY 1
020400       MOVE BUF-LOC(CURR-LOC) TO ARG-TYPE
020500       EVALUATE ARG-TYPE
020600******    server name specification  *****
020700         WHEN "n"
020800           IF SERV-NAME-SPEC AND IP-SPEC
020900              DISPLAY "ERROR in argument list:"
021000                      " conflicting options"
021100              MOVE 1 TO DIE
021200              %Perform(DO-HELP#)
021300           ELSE
021400              SET SERV-NAME-SPEC TO TRUE;
021500              SET CURR-LOC UP BY 1
021600              IF BUF-LOC(CURR-LOC) = SPACE
021700***            get next in list
021800                 ADD 1 TO X
021900                 IF X < ARG-CNT
022000                    %Perform(NEXT-ARG#)
022100                 ELSE
022200***               no more arguments avaiable
022300                    MOVE " " TO BUF-LOC(CURR-LOC)
022400                 END-IF
022500              END-IF
022600
022700              %Perform(AARG-LEN#)
022800              PERFORM VARYING I FROM 1 BY 1
022900                      UNTIL I > ARG-LEN
023000                         OR I > 255
023100                 MOVE BUF-LOC(CURR-LOC) TO S-CHAR(I)
023200                 SET CURR-LOC UP BY 1
023300              END-PERFORM
023400              MOVE CHAR-0 TO S-CHAR(I)
023500              MOVE ARG-LEN TO ID-LEN
023600
023700              CALL "GETHOSTBYNAME" USING SERVER-ID
023800                GIVING HOSTENT-PTR
023900              IF HOSTENT-PTR = 0
024000                 DISPLAY  "ERROR gethostbyname of '",
024100                 SERVER-ID, "'; quitting"
024200                 %CExit(1#)
024300              END-IF
024400
024500***         sizeof(struct hostent)
024600              MOVE 20 TO I
024700              CALL "COBPTR" USING \HOSTENT-PTR\, HOSTENT, I
024800              MOVE 4 TO I
024900              CALL "COBPTR" USING \H-ADDR-LIST\,
025000                                  IP-ADDR-PTR, I
025100              CALL "COBPTR" USING \IP-ADDR-PTR\,
025200                        SIN-ADDR OF SERVER-ADDR, I
025300
025400           END-IF
025500******    server IP address specification  *****
025600         WHEN "i"
025700           IF SERV-NAME-SPEC AND IP-SPEC
025800              DISPLAY "ERROR in argument list:"
025900                      " conflicting options"
026000              MOVE 1 TO DIE
026100              %Perform(DO-HELP#)
026200           ELSE
026300              SET IP-SPEC TO TRUE
026400              SET CURR-LOC UP BY 1
026500              IF BUF-LOC(CURR-LOC) = SPACE
026600***            get next in list
026700                 ADD 1 TO X
026800                 IF X < ARG-CNT
026900                    %Perform(NEXT-ARG#)
027000                 ELSE
027100***               no more arguments avaiable
027200                    MOVE " " TO BUF-LOC(CURR-LOC)
027300                 END-IF
027400              END-IF
027500
027600              %Perform(AARG-LEN#)
027700              PERFORM VARYING I FROM 1 BY 1
027800                      UNTIL I > ARG-LEN
027900                         OR I > 255
028000                 MOVE BUF-LOC(CURR-LOC) TO S-CHAR(I)
028100                 SET CURR-LOC UP BY 1
028200              END-PERFORM
028300              MOVE CHAR-0 TO S-CHAR(I)
028400              MOVE ARG-LEN TO ID-LEN
028500
028600              CALL "INET_ADDR" USING SERVER-ID
028700                GIVING SIN-ADDR OF SERVER-ADDR
028800           END-IF
028900******    server port specification  *****
029000         WHEN "p"
029100           IF PORT-SPEC
029200              DISPLAY "ERROR in argument list:"
029300                      " duplicate options"
029400              MOVE 1 TO DIE
029500              %Perform(DO-HELP#)
029600           ELSE
029700              SET PORT-SPEC TO TRUE
029800           END-IF
029900           SET CURR-LOC UP BY 1
030000           IF BUF-LOC(CURR-LOC) = SPACE
030100***         get next in list
030200              ADD 1 TO X
030300              IF X < ARG-CNT
030400                 %Perform(NEXT-ARG#)
030500              ELSE
030600*****          no more arguments avaiable   *****
030700                 MOVE " " TO BUF-LOC(CURR-LOC)
030800              END-IF
030900           END-IF
031000           %Perform(AARG-LEN#)
031100           CALL INTRINSIC "BINARY" USING BUF-LOC(CURR-LOC),
031200                                         \ARG-LEN\
031300             GIVING SIN-PORT OF SERVER-ADDR
031400******    use a DGRAM socket for communication  *****
031500         WHEN "d"
031600           MOVE SOCK_DGRAM TO SOCK-TYPE
031700******    number of messages specification  *****
031800         WHEN "m"
031900           SET CURR-LOC UP BY 1
032000           IF BUF-LOC(CURR-LOC) = SPACE
032100***         get next in list
032200              ADD 1 TO X
032300              IF X < ARG-CNT
032400                 %Perform(NEXT-ARG#)
032500              ELSE
032600***            no more arguments avaiable
032700                 MOVE " " TO BUF-LOC(CURR-LOC)
032800              END-IF
032900           END-IF
033000           %Perform(AARG-LEN#)
033100           CALL INTRINSIC "DBINARY" USING BUF-LOC(CURR-LOC),
033200                                          \ARG-LEN\
033300             GIVING MSG-COUNT
033400           IF MSG-COUNT > 20
033500               DISPLAY "ERROR in argument list:"
033600                       " msg_count too large"
033700               MOVE 1 TO DIE
033800               %Perform(DO-HELP#)
033900           END-IF
034000******    message length specification  *****
034100         WHEN "l"
034200           SET CURR-LOC UP BY 1
034300           IF BUF-LOC(CURR-LOC) = SPACE
034400***         get next in list
034500              ADD 1 TO X
034600              IF X < ARG-CNT
034700                 %Perform(NEXT-ARG#)
034800              ELSE
034900***            no more arguments avaiable
035000                 MOVE " " TO BUF-LOC(CURR-LOC)
035100              END-IF
035200              MOVE BUF-LOC(CURR-LOC) TO CHAR-SET
035300           END-IF
035400           %Perform(AARG-LEN#)
035500           CALL INTRINSIC "DBINARY" USING BUF-LOC(CURR-LOC),
035600                                          \ARG-LEN\
035700             GIVING MSG-LEN
035800           IF MSG-LEN > 5000
035900               DISPLAY "ERROR in argument list:"
036000                       " msg_len to large"
036100               MOVE 1 TO DIE
036200               %Perform(DO-HELP#)
036300           END-IF
036400******    character set specification  *****
036500         WHEN "c"
036600           SET CURR-LOC UP BY 1
036700           IF BUF-LOC(CURR-LOC) <> SPACE
036800***         non-null, string there
036900              MOVE BUF-LOC(CURR-LOC) TO CHAR-SET
037000           ELSE
037100***         get next in list
037200              ADD 1 TO X
037300              IF X < ARG-CNT
037400                 %Perform(NEXT-ARG#)
037500              ELSE
037600***            no more arguments avaiable   *****
037700                 MOVE "?" TO BUF-LOC(CURR-LOC)
037800              END-IF
037900              MOVE BUF-LOC(CURR-LOC) TO CHAR-SET
038000           END-IF
038100           EVALUATE CHAR-SET
038200             WHEN "A"
038300*              char_start = 'A';
038400               MOVE 65  TO CHAR-START
038500               MOVE 26  TO CHAR-SET-SIZE
038600             WHEN "a"
038700*              char_start = 'a';
038800               MOVE 97  TO CHAR-START
038900               MOVE 26  TO CHAR-SET-SIZE
039000             WHEN "n"
039100*              char_start = '0';
039200               MOVE 48  TO CHAR-START
039300               MOVE 10  TO CHAR-SET-SIZE
039400             WHEN "c"
039500*              char_start = '!';
039600               MOVE 33  TO CHAR-START
039700               MOVE 94  TO CHAR-SET-SIZE
039800             WHEN OTHER
039900               DISPLAY "ERROR in argument list:"
040000                       " unknown char set"
040100               MOVE 1 TO DIE
040200               %Perform(DO-HELP#)
040300           END-EVALUATE
040400******    print entire message?  *****
040500         WHEN "a"
040600           SET PRINT-ALL TO TRUE
040700******    kill the server        *****
040800         WHEN "k"
040900           SET KILL-SERVER TO TRUE
041000******    print help message     *****
041100         WHEN "h"
041200           MOVE ZERO TO DIE
041300           %Perform(DO-HELP#)
041400         WHEN OTHER
041500           DISPLAY "ERROR in argument list: unrecognized option"
041600           MOVE 1 TO DIE
041700           %Perform(DO-HELP#)
041800       END-EVALUATE
041900
042000       ADD 1 TO X
042100       IF X < ARG-CNT
042200          %Perform(NEXT-ARG#)
042300       END-IF
042400    END-PERFORM
042500
042600***  check for required parms
042700    IF (NOT PORT-SPEC OR NOT (SERV-NAME-SPEC OR IP-SPEC))
042800       DISPLAY "ERROR in argument list: "
042900       "missing required option"
043000       MOVE 1 TO DIE
043100       %Perform(DO-HELP#)
043200    END-IF
043300 END-PERFORM.
043400 PARSE-ARGS-EXIT. EXIT.
043500*---------------------------------------------------------
043600* Setup connection using steam or datagram socket
043700*---------------------------------------------------------
043800 SETUP-CONNECT.
043900 PERFORM
044000    MOVE AF_INET TO SIN-FAMILY OF SERVER-ADDR
044100* cdes = socket(AF_INET, sock_type, 0)
044200    CALL "SOCKET"  USING \AF_INET\, \SOCK-TYPE\, \0\
044300      GIVING CDES
044400    IF CDES < 0
044500       CALL INTRINSIC "DASCII" USING \ERRNO\, \10\, BUF
044600         GIVING BUF-LEN
044700       DISPLAY  "ERROR in socket, errno ", BUF,
044800                "; quitting"
044900       %CExit(1#)
045000    END-IF
045100
045200    IF SOCK-TYPE = SOCK_STREAM
045300* er = connect(cdes, &server_addr, sizeof(struct sockaddr_in))
045400       CALL "CONNECT"  USING \CDES\, SERVER-ADDR, \16\
045500         GIVING ER
045600       IF ER <> 0
045700          CALL INTRINSIC "DASCII" USING \ERRNO\, \10\, BUF
045800            GIVING BUF-LEN
045900          DISPLAY  "ERROR connecting, errno ", BUF,
046000                "; quitting"
046100          %CExit(1#)
046200       END-IF
046300    ELSE
046400       MOVE AF_INET TO SIN-FAMILY OF CLIENT-ADDR
046500       COMPUTE
046600        SIN-PORT OF CLIENT-ADDR = SIN-PORT OF SERVER-ADDR - 2
046700       MOVE INADDR_ANY TO SIN-ADDR OF CLIENT-ADDR
046800
046900* er = bind(cdes, &client_addr, sizeof(struct sockaddr_in))
047000       CALL "BIND"  USING \CDES\, CLIENT-ADDR, \16\
047100         GIVING ER
047200       IF ER <> 0
047300          CALL INTRINSIC "DASCII" USING \ERRNO\, \10\, BUF
047400            GIVING BUF-LEN
047500          DISPLAY  "ERROR binding, errno ", BUF,
047600                "; quitting"
047700          %CExit(1#)
047800       END-IF
047900    END-IF
048000 END-PERFORM.
048100 SETUP-CONNECT-EXIT. EXIT.
048200*---------------------------------------------------------
048300* Print communication parameters
048400*---------------------------------------------------------
048500 DUMP-PARMS.
048600 PERFORM
048700    DISPLAY "Client version ", IDENT
048800    DISPLAY "COMMUNICATION PARAMETERS"
048900    DISPLAY "------------------------"
049000    MOVE SIN-PORT OF SERVER-ADDR TO DISP5
049100    DISPLAY "Server Port ", DISP5,
049200            "   Server Specification: '", SERVER-ID, "'"
049300    MOVE MSG-COUNT TO DISP2
049400    MOVE MSG-LEN   TO DISP4
049500    DISPLAY "Number of Messages: ", DISP2,
049600            "    Message Length " , DISP4
049700    IF SOCK-TYPE = SOCK_DGRAM
049800       DISPLAY "Datagram Sockets " WITH NO ADVANCING
049900    ELSE
050000       DISPLAY "Stream Sockets " WITH NO ADVANCING
050100    END-IF
050200
050300    IF PRINT-ALL
050400       DISPLAY "Print all of message u" WITH NO ADVANCING
050500    ELSE
050600       DISPLAY "u" WITH NO ADVANCING
050700    END-IF
050800    DISPLAY "sing character set ", CHAR-SET
050900    DISPLAY "------------------------"
051000 END-PERFORM.
051100 DUMP-PARMS-EXIT. EXIT.
051200*---------------------------------------------------------
051300* Print all help text
051400*---------------------------------------------------------
051500 DO-HELP.
051600 PERFORM
051700    DISPLAY IDENT
051800    DISPLAY "syntax is one of the following forms:"
051900    DISPLAY "   sockcltp -n<server> -p<port #> [-d]"
052000            " [-m#] [-l#] [-c?] [-a] [-k] [-t#]"
052100    DISPLAY "   sockcltp -i<IP addr> -p<port #> [-d]"
052200            " [-m#] [-l#] [-c?] [-a] [-k] [-t#]"
052300    DISPLAY "   sockcltp -h"
052400    DISPLAY "**** see the file sockcltc.net.sys"
052500            " for further explanation ***"
052600    %CExit(DIE#)
052700 END-PERFORM.
052800 DO-HELP-EXIT. EXIT.
052900*---------------------------------------------------------
053000* Client processing routine
053100*---------------------------------------------------------
053200 CLIENT.
053300 PERFORM
053400    %Perform(SETUP-CONNECT#)
053500
053600* send the control message
053700    MOVE MSG-COUNT TO NUM-MSGS OF SERVER-CONTROL
053800    MOVE MSG-LEN   TO MSG-SIZE OF SERVER-CONTROL
053900    MOVE CHAR-SET  TO MSG-SET  OF SERVER-CONTROL
054000
054100    MOVE SERVER-CONTROL TO BUF
054200    MOVE 9 TO LEN
054300    %Perform(DO-SEND#)
054400
054500    PERFORM VARYING X FROM 1 BY 1 UNTIL X > MSG-COUNT
054600       MOVE X TO DISP2
054700
054800***** client recvs first
054900       MOVE MSG-LEN TO LEN
055000       %Perform(DO-RECV#)
055100       DISPLAY "Received message ", DISP2, " '"
055200          WITH NO ADVANCING
055300       %Perform(PRINT-MSG-BUF#)
055400       MOVE LEN TO DISP4
055500       DISPLAY "' len ", DISP4
055600
055700***     now client does a send */
055800       MOVE ZERO TO MODULO
055900       PERFORM VARYING Y FROM 1 BY 1 UNTIL Y > MSG-LEN
056000*      msg[y] = (CHAR)((INT)CHAR-START + Y % CHAR-SET-SIZE);
056100          COMPUTE INT-CONV = CHAR-START + MODULO
056200          SET CURR-LOC TO Y
056300          MOVE INT-CHAR TO BUF-LOC(CURR-LOC)
056400          ADD 1 TO MODULO
056500          IF MODULO = CHAR-SET-SIZE
056600             MOVE ZERO TO MODULO
056700          END-IF
056800       END-PERFORM
056900       DISPLAY "Sending message  ", DISP2, " '"
057000          WITH NO ADVANCING
057100       %Perform(PRINT-MSG-BUF#)
057200       DISPLAY "'"
057300       MOVE MSG-LEN TO LEN
057400       %Perform(DO-SEND#)
057500
057600    END-PERFORM
057700
057800* now close the connection
057900    CALL "SCLOSE"  USING \CDES\
058000
058100 END-PERFORM.
058200 CLIENT-EXIT. EXIT.
058300*---------------------------------------------------------
058400* Send data to server using steam or datagram socket
058500*---------------------------------------------------------
058600 DO-SEND.
058700 PERFORM
058800    IF SOCK-TYPE = SOCK_STREAM
058900* er = send(cdes, buf, len, 0)
059000       CALL "SEND"  USING \CDES\, BUF , \LEN\, \0\
059100         GIVING ER
059200       IF ER < 0
059300          CALL INTRINSIC "DASCII" USING \ERRNO\, \10\, BUF
059400            GIVING BUF-LEN
059500          DISPLAY  "ERROR sending, errno ", BUF,
059600                   "; quitting"
059700          %CExit(1#)
059800       END-IF
059900    ELSE
060000* get the other side's address
060100       MOVE SERVER-ADDR TO LOCAL-ADDR
060200* er = sendto(cdes, buf, len, 0,
060300*             &local_addr, sizeof (struct sockaddr_in))
060400       CALL "SENDTO"  USING \CDES\, BUF , \LEN\, \0\
060500                            LOCAL-ADDR, \16\
060600         GIVING ER
060700       IF ER < 0
060800          CALL INTRINSIC "DASCII" USING \ERRNO\, \10\, BUF
060900            GIVING BUF-LEN
061000          DISPLAY  "ERROR sending to, errno ", BUF,
061100                   "; quitting"
061200          %CExit(1#)
061300       END-IF
061400    END-IF
061500 END-PERFORM.
061600 DO-SEND-EXIT. EXIT.
061700*---------------------------------------------------------
061800* Receive data from server using steam or datagram socket
061900*---------------------------------------------------------
062000 DO-RECV.
062100 PERFORM
062200    MOVE LEN TO XX
062300    MOVE 5000 TO BUF-LEN
062400    IF SOCK-TYPE = SOCK_STREAM
062500       MOVE LEN TO LOCAL-LEN
062600       MOVE 0   TO TOTAL-SO-FAR
062700       SET CURR-LOC TO 1
062800       PERFORM UNTIL LOCAL-LEN <= 0
062900*****    xx = recv(cdes, current_buf_loc, local_len, 0)
063000          CALL "RECV"  USING \CDES\,
063100                             BUF-LOC(CURR-LOC),
063200                             \LOCAL-LEN\, \0\
063300            GIVING XX
063400          IF XX < 0
063500             CALL INTRINSIC "DASCII" USING \ERRNO\, \10\, BUF
063600               GIVING BUF-LEN
063700             DISPLAY  "ERROR recving, errno ", BUF,
063800                      "; quitting"
063900             %CExit(1#)
064000          ELSE
064100             COMPUTE TOTAL-SO-FAR = TOTAL-SO-FAR + XX
064200             COMPUTE LOCAL-LEN = LOCAL-LEN - XX
064300             SET CURR-LOC UP BY XX
064400          END-IF
064500       END-PERFORM
064600       MOVE TOTAL-SO-FAR TO LEN
064700    ELSE
064800*      sizeof(struct sockaddr_in)
064900       MOVE 16 TO ADDR-LEN
065000*   len = recvfrom(cdes, buf, xx, 0, &local_addr, &addr_len)
065100       CALL "RECVFROM"  USING \CDES\, BUF, \XX\, \0\
065200                              LOCAL-ADDR, ADDR-LEN
065300         GIVING LEN
065400       IF LEN < 0
065500          CALL INTRINSIC "DASCII" USING \ERRNO\, \10\, BUF
065600            GIVING BUF-LEN
065700          DISPLAY  "ERROR recving from, errno ", BUF,
065800                   "; quitting"
065900          %CExit(1#)
066000       END-IF
066100       MOVE LOCAL-ADDR TO SERVER-ADDR
066200    END-IF
066300 END-PERFORM.
066400 DO-RECV-EXIT. EXIT.
066500*---------------------------------------------------------
066600* Print message buffer
066700*---------------------------------------------------------
066800 PRINT-MSG-BUF.
066900 PERFORM
067000    IF LEN < 50 OR PRINT-ALL
067100       MOVE LEN TO BUF-LEN
067200       DISPLAY BUF WITH NO ADVANCING
067300    ELSE
067400       MOVE 30  TO BUF-LEN
067500       DISPLAY BUF, "..." WITH NO ADVANCING
067600       MOVE 5000 TO BUF-LEN
067700       SET CURR-LOC TO LEN
067800       SET CURR-LOC DOWN BY 14
067900       PERFORM VARYING XX FROM 1 BY 1 UNTIL XX > 15
068000          DISPLAY BUF-LOC(CURR-LOC) WITH NO ADVANCING
068100          SET CURR-LOC UP BY 1
068200       END-PERFORM
068300    END-IF
068400 END-PERFORM.
068500 PRINT-MSG-BUF-EXIT. EXIT.
068600*---------------------------------------------------------
068700* Send kill message to server
068800*---------------------------------------------------------
068900 KILL-IT.
069000 PERFORM
069100    MOVE SOCK_DGRAM TO SOCK-TYPE
069200
069300    %Perform(SETUP-CONNECT#)
069400
069500    MOVE -1  TO NUM-MSGS OF SERVER-CONTROL
069600    MOVE -1  TO MSG-SIZE OF SERVER-CONTROL
069700    MOVE "k" TO MSG-SET  OF SERVER-CONTROL
069800
069900    DISPLAY "Sending the kill message to the server"
070000
070100    MOVE SERVER-CONTROL TO BUF
070200    MOVE 9 TO LEN
070300    %Perform(DO-SEND#)
070400 END-PERFORM.
070500 KILL-IT-EXIT. EXIT.
070600*=========================================================
070700* INFO string manipulation procedures
070800*=========================================================
070900* Command line arguments count
071000*---------------------------------------------------------
071100 ARG-COUNT.
071200 PERFORM
071300    IF INFO-LEN = ZERO
071400       MOVE ZERO TO ARG-CNT
071500    ELSE
071600       SET CURR-LOC TO 1
071700       MOVE 1 TO ARG-MARKER
071800       PERFORM WITH TEST AFTER UNTIL ARG-MARKER = INFO-LEN
071900          PERFORM UNTIL BUF-LOC(CURR-LOC) <> SPACE
072000                     OR ARG-MARKER = INFO-LEN
072100             ADD 1 TO ARG-MARKER
072200             SET CURR-LOC UP BY 1
072300          END-PERFORM
072400          IF BUF-LOC(CURR-LOC) <> SPACE
072500             ADD 1 TO ARG-CNT
072600          END-IF
072700          PERFORM UNTIL BUF-LOC(CURR-LOC) = SPACE
072800                     OR ARG-MARKER = INFO-LEN
072900             ADD 1 TO ARG-MARKER
073000             SET CURR-LOC UP BY 1
073100          END-PERFORM
073200       END-PERFORM
073300    END-IF
073400 END-PERFORM.
073500 ARG-COUNT-EXIT. EXIT.
073600*---------------------------------------------------------
073700* Get first argument (CURR-LOC will point to it)
073800*---------------------------------------------------------
073900 FIRST-ARG.
074000 PERFORM
074100    SET CURR-LOC TO 1
074200    MOVE 1 TO ARG-MARKER
074300    PERFORM UNTIL BUF-LOC(CURR-LOC) <> SPACE
074400               OR ARG-MARKER = INFO-LEN
074500       ADD 1 TO ARG-MARKER
074600       SET CURR-LOC UP BY 1
074700    END-PERFORM
074800 END-PERFORM.
074900 FIRST-ARG-EXIT. EXIT.
075000*---------------------------------------------------------
075100* Get next argument (CURR-LOC will point to it)
075200*---------------------------------------------------------
075300 NEXT-ARG.
075400 PERFORM
075500    SET CURR-LOC TO ARG-MARKER
075600    PERFORM UNTIL BUF-LOC(CURR-LOC) = SPACE
075700               OR ARG-MARKER = INFO-LEN
075800       ADD 1 TO ARG-MARKER
075900       SET CURR-LOC UP BY 1
076000    END-PERFORM
076100    PERFORM UNTIL BUF-LOC(CURR-LOC) <> SPACE
076200               OR ARG-MARKER = INFO-LEN
076300       ADD 1 TO ARG-MARKER
076400       SET CURR-LOC UP BY 1
076500    END-PERFORM
076600 END-PERFORM.
076700 NEXT-ARG-EXIT. EXIT.
076800*---------------------------------------------------------
076900* Length of argument pointed by CURR-LOC
077000*---------------------------------------------------------
077100 AARG-LEN.
077200 PERFORM
077300    MOVE ZERO TO ARG-LEN
077400    SET TEMP-LOC TO CURR-LOC
077500    PERFORM UNTIL BUF-LOC(CURR-LOC) = SPACE
077600       ADD 1 TO ARG-LEN
077700       SET CURR-LOC UP BY 1
077800    END-PERFORM
077900    SET CURR-LOC TO TEMP-LOC
078000 END-PERFORM.
078100 AARG-LEN-EXIT. EXIT.
078200*---------------------------------------------------------
078300 END PROGRAM SOCKCLTP.
078400*=========================================================
078500$CONTROL SUBPROGRAM, SYNC32
078600*=========================================================
078700 IDENTIFICATION DIVISION.
078800 PROGRAM-ID. COBPTR.
078900*========================================================
079000 DATA DIVISION.
079100*========================================================
079200 WORKING-STORAGE SECTION.
079300 01 COUNTER                         PIC S9(9) COMP.
079400*========================================================
079500 LINKAGE SECTION.
079600*========================================================
079700 01 FROM-BUF.
079800    05 FROM-CHAR   PIC X OCCURS 256 TIMES.
079900 01 TO-BUF.
080000    05 TO-CHAR     PIC X OCCURS 256 TIMES.
080100 01 LEN            PIC S9(9) COMP.
080200*========================================================
080300 PROCEDURE DIVISION USING FROM-BUF TO-BUF LEN.
080400*========================================================
080500 MAIN-LINE SECTION.
080600 PERFORM VARYING COUNTER FROM 1 BY 1 UNTIL COUNTER > LEN
080700    MOVE FROM-CHAR(COUNTER) TO TO-CHAR(COUNTER)
080800 END-PERFORM.
080900*-------------------------------------------------------------
081000

ATOM RSS1 RSS2