Added code :D
This commit is contained in:
parent
818f88b329
commit
671b0cc8dd
|
@ -0,0 +1,50 @@
|
||||||
|
IDENTIFICATION DIVISION.
|
||||||
|
PROGRAM-ID. "IRC-MSG".
|
||||||
|
|
||||||
|
DATA DIVISION.
|
||||||
|
WORKING-STORAGE SECTION.
|
||||||
|
01 PREFIX-WORK PIC X(96).
|
||||||
|
01 MSG-POINTER PIC 9(3).
|
||||||
|
|
||||||
|
LINKAGE SECTION.
|
||||||
|
01 BUFFER.
|
||||||
|
03 MSG-LENGTH PIC 9(3).
|
||||||
|
03 MSG-BODY PIC X(512).
|
||||||
|
03 MSG-BODY-1 REDEFINES MSG-BODY PIC X.
|
||||||
|
88 HAS-PREFIX VALUE ":".
|
||||||
|
01 IRC-MESSAGE.
|
||||||
|
03 PREFIX.
|
||||||
|
05 NICK PIC X(16).
|
||||||
|
05 IDENT PIC X(16).
|
||||||
|
05 HOST PIC X(64).
|
||||||
|
03 COMMAND PIC X(16).
|
||||||
|
03 PARAMETERS.
|
||||||
|
05 TARGET PIC X(50).
|
||||||
|
05 REST PIC X(480).
|
||||||
|
|
||||||
|
PROCEDURE DIVISION USING BUFFER, IRC-MESSAGE.
|
||||||
|
INITIALIZE IRC-MESSAGE, PREFIX-WORK, MSG-POINTER.
|
||||||
|
IF HAS-PREFIX THEN
|
||||||
|
PERFORM WITH-PREFIX
|
||||||
|
ELSE
|
||||||
|
MOVE 1 TO MSG-POINTER.
|
||||||
|
UNSTRING MSG-BODY,
|
||||||
|
DELIMITED BY SPACES,
|
||||||
|
INTO COMMAND, TARGET
|
||||||
|
WITH POINTER MSG-POINTER.
|
||||||
|
UNSTRING MSG-BODY,
|
||||||
|
DELIMITED BY " ",
|
||||||
|
INTO REST,
|
||||||
|
WITH POINTER MSG-POINTER.
|
||||||
|
|
||||||
|
WITH-PREFIX.
|
||||||
|
MOVE 2 TO MSG-POINTER.
|
||||||
|
UNSTRING MSG-BODY,
|
||||||
|
DELIMITED BY SPACES,
|
||||||
|
INTO PREFIX-WORK,
|
||||||
|
WITH POINTER MSG-POINTER.
|
||||||
|
UNSTRING PREFIX-WORK,
|
||||||
|
DELIMITED BY "!" OR "@",
|
||||||
|
INTO NICK,
|
||||||
|
IDENT,
|
||||||
|
HOST.
|
|
@ -0,0 +1,70 @@
|
||||||
|
IDENTIFICATION DIVISION.
|
||||||
|
PROGRAM-ID. "PRINT-CONFIG".
|
||||||
|
|
||||||
|
ENVIRONMENT DIVISION.
|
||||||
|
INPUT-OUTPUT SECTION.
|
||||||
|
FILE-CONTROL.
|
||||||
|
SELECT CONFIG
|
||||||
|
ORGANIZATION IS INDEXED
|
||||||
|
ACCESS MODE IS SEQUENTIAL
|
||||||
|
RECORD KEY IS CONFIG-KEY.
|
||||||
|
SELECT USERS
|
||||||
|
ORGANIZATION IS INDEXED
|
||||||
|
ACCESS MODE IS SEQUENTIAL
|
||||||
|
RECORD KEY IS USER-NAME.
|
||||||
|
SELECT CHANNELS
|
||||||
|
ORGANIZATION IS SEQUENTIAL.
|
||||||
|
|
||||||
|
DATA DIVISION.
|
||||||
|
FILE SECTION.
|
||||||
|
FD CONFIG.
|
||||||
|
01 CONFIG-RECORD.
|
||||||
|
03 CONFIG-KEY PIC X(16).
|
||||||
|
03 CONFIG-VALUE PIC X(64).
|
||||||
|
FD USERS.
|
||||||
|
01 USER-RECORD.
|
||||||
|
03 USER-NAME PIC X(16).
|
||||||
|
03 USER-LEVEL PIC 9(2).
|
||||||
|
FD CHANNELS.
|
||||||
|
01 CHANNEL-RECORD.
|
||||||
|
03 CHANNEL-NAME PIC X(50).
|
||||||
|
|
||||||
|
WORKING-STORAGE SECTION.
|
||||||
|
01 STATE PIC 9(2) VALUE 0.
|
||||||
|
88 DONE VALUE 10.
|
||||||
|
|
||||||
|
PROCEDURE DIVISION.
|
||||||
|
DISPLAY "CONFIGURATION ENTRIES:"
|
||||||
|
OPEN INPUT CONFIG.
|
||||||
|
PERFORM PRINT-CONFIG-ENTRY UNTIL DONE.
|
||||||
|
INITIALIZE STATE.
|
||||||
|
CLOSE CONFIG.
|
||||||
|
DISPLAY "USER ENTRIES:"
|
||||||
|
OPEN INPUT USERS.
|
||||||
|
PERFORM PRINT-USER-ENTRY UNTIL DONE.
|
||||||
|
INITIALIZE STATE.
|
||||||
|
CLOSE USERS.
|
||||||
|
DISPLAY "CHANNEL ENTRIES:"
|
||||||
|
OPEN INPUT CHANNELS.
|
||||||
|
PERFORM PRINT-CHANNEL-ENTRY UNTIL DONE.
|
||||||
|
INITIALIZE STATE.
|
||||||
|
CLOSE CHANNELS.
|
||||||
|
EXIT PROGRAM.
|
||||||
|
|
||||||
|
PRINT-CONFIG-ENTRY.
|
||||||
|
READ CONFIG NEXT RECORD
|
||||||
|
AT END MOVE 10 TO STATE.
|
||||||
|
IF NOT DONE THEN
|
||||||
|
DISPLAY CONFIG-RECORD.
|
||||||
|
|
||||||
|
PRINT-USER-ENTRY.
|
||||||
|
READ USERS NEXT RECORD
|
||||||
|
AT END MOVE 10 TO STATE.
|
||||||
|
IF NOT DONE THEN
|
||||||
|
DISPLAY USER-RECORD.
|
||||||
|
|
||||||
|
PRINT-CHANNEL-ENTRY.
|
||||||
|
READ CHANNELS NEXT RECORD
|
||||||
|
AT END MOVE 10 TO STATE.
|
||||||
|
IF NOT DONE THEN
|
||||||
|
DISPLAY CHANNEL-RECORD.
|
|
@ -0,0 +1,81 @@
|
||||||
|
IDENTIFICATION DIVISION.
|
||||||
|
PROGRAM-ID. "WOPO-CNF".
|
||||||
|
|
||||||
|
ENVIRONMENT DIVISION.
|
||||||
|
INPUT-OUTPUT SECTION.
|
||||||
|
FILE-CONTROL.
|
||||||
|
SELECT CONFIG
|
||||||
|
ORGANIZATION IS INDEXED
|
||||||
|
ACCESS MODE IS RANDOM
|
||||||
|
RECORD KEY IS CONFIG-KEY.
|
||||||
|
SELECT USERS
|
||||||
|
ORGANIZATION IS INDEXED
|
||||||
|
ACCESS MODE IS RANDOM
|
||||||
|
RECORD KEY IS USER-NAME.
|
||||||
|
SELECT CHANNELS
|
||||||
|
ORGANIZATION IS SEQUENTIAL.
|
||||||
|
|
||||||
|
DATA DIVISION.
|
||||||
|
FILE SECTION.
|
||||||
|
FD CONFIG.
|
||||||
|
01 CONFIG-RECORD.
|
||||||
|
03 CONFIG-KEY PIC X(16).
|
||||||
|
03 CONFIG-VALUE PIC X(64).
|
||||||
|
FD USERS.
|
||||||
|
01 USER-RECORD.
|
||||||
|
03 USER-NAME PIC X(16).
|
||||||
|
03 USER-LEVEL PIC 9(2).
|
||||||
|
FD CHANNELS.
|
||||||
|
01 CHANNEL-RECORD.
|
||||||
|
03 CHANNEL-NAME PIC X(50).
|
||||||
|
|
||||||
|
WORKING-STORAGE SECTION.
|
||||||
|
01 STATE PIC 9(2) VALUE 0.
|
||||||
|
88 DONE VALUE 10.
|
||||||
|
|
||||||
|
PROCEDURE DIVISION.
|
||||||
|
DISPLAY "WOPO CONFIGURATION PROGRAM".
|
||||||
|
DISPLAY "BLANK ENTRY TO EXIT SECTION".
|
||||||
|
DISPLAY "WRITING CONFIGURATION ENTRIES:".
|
||||||
|
OPEN OUTPUT CONFIG.
|
||||||
|
PERFORM WRITE-CONFIG-ENTRY UNTIL DONE.
|
||||||
|
INITIALIZE STATE.
|
||||||
|
CLOSE CONFIG.
|
||||||
|
DISPLAY "WRITING USER ENTRIES:"
|
||||||
|
OPEN OUTPUT USERS.
|
||||||
|
PERFORM WRITE-USER-ENTRY UNTIL DONE.
|
||||||
|
INITIALIZE STATE.
|
||||||
|
CLOSE USERS.
|
||||||
|
OPEN OUTPUT CHANNELS.
|
||||||
|
DISPLAY "WRITING CHANNEL AUTOJOINS:"
|
||||||
|
PERFORM WRITE-CHANNEL-ENTRY UNTIL DONE.
|
||||||
|
INITIALIZE STATE.
|
||||||
|
CLOSE CHANNELS.
|
||||||
|
CALL "PRINT-CONFIG".
|
||||||
|
STOP RUN.
|
||||||
|
|
||||||
|
WRITE-CONFIG-ENTRY.
|
||||||
|
DISPLAY "KEY?"
|
||||||
|
ACCEPT CONFIG-KEY.
|
||||||
|
DISPLAY "VALUE?"
|
||||||
|
ACCEPT CONFIG-VALUE.
|
||||||
|
IF CONFIG-KEY EQUALS SPACES OR CONFIG-VALUE EQUALS SPACES
|
||||||
|
THEN MOVE 10 TO STATE
|
||||||
|
ELSE WRITE CONFIG-RECORD.
|
||||||
|
|
||||||
|
WRITE-USER-ENTRY.
|
||||||
|
DISPLAY "USER?"
|
||||||
|
ACCEPT USER-NAME.
|
||||||
|
DISPLAY "LEVEL?"
|
||||||
|
ACCEPT USER-LEVEL.
|
||||||
|
IF USER-NAME EQUALS SPACES OR USER-LEVEL EQUALS 0
|
||||||
|
THEN MOVE 10 TO STATE
|
||||||
|
ELSE WRITE USER-RECORD.
|
||||||
|
|
||||||
|
WRITE-CHANNEL-ENTRY.
|
||||||
|
DISPLAY "CHANNEL?"
|
||||||
|
ACCEPT CHANNEL-NAME.
|
||||||
|
IF CHANNEL-NAME EQUALS SPACES
|
||||||
|
THEN MOVE 10 TO STATE
|
||||||
|
ELSE WRITE CHANNEL-RECORD.
|
||||||
|
|
|
@ -0,0 +1,355 @@
|
||||||
|
IDENTIFICATION DIVISION.
|
||||||
|
PROGRAM-ID. "WOPO".
|
||||||
|
|
||||||
|
ENVIRONMENT DIVISION.
|
||||||
|
INPUT-OUTPUT SECTION.
|
||||||
|
FILE-CONTROL.
|
||||||
|
SELECT CONFIG
|
||||||
|
ORGANIZATION IS INDEXED
|
||||||
|
ACCESS MODE IS RANDOM
|
||||||
|
RECORD KEY IS CONFIG-KEY.
|
||||||
|
SELECT USERS
|
||||||
|
ORGANIZATION IS INDEXED
|
||||||
|
ACCESS MODE IS RANDOM
|
||||||
|
RECORD KEY IS USER-NAME.
|
||||||
|
SELECT CHANNELS
|
||||||
|
ORGANIZATION IS SEQUENTIAL.
|
||||||
|
|
||||||
|
DATA DIVISION.
|
||||||
|
FILE SECTION.
|
||||||
|
FD CONFIG.
|
||||||
|
01 CONFIG-RECORD.
|
||||||
|
03 CONFIG-KEY PIC X(16).
|
||||||
|
03 CONFIG-VALUE PIC X(64).
|
||||||
|
FD USERS.
|
||||||
|
01 USER-RECORD.
|
||||||
|
03 USER-NAME PIC X(16).
|
||||||
|
03 USER-LEVEL PIC 9(2).
|
||||||
|
FD CHANNELS.
|
||||||
|
01 CHANNEL-RECORD.
|
||||||
|
03 CHANNEL-NAME PIC X(50).
|
||||||
|
|
||||||
|
WORKING-STORAGE SECTION.
|
||||||
|
01 STATE PIC 9(2).
|
||||||
|
88 SUCCESS VALUE 0.
|
||||||
|
88 DONE VALUE 99.
|
||||||
|
01 BUFFER.
|
||||||
|
03 MSG-LENGTH PIC 9(3).
|
||||||
|
03 MSG-BODY PIC X(512).
|
||||||
|
01 IRC-MESSAGE.
|
||||||
|
03 PREFIX.
|
||||||
|
05 NICK PIC X(16).
|
||||||
|
05 IDENT PIC X(16).
|
||||||
|
05 HOST PIC X(64).
|
||||||
|
03 COMMAND PIC X(16).
|
||||||
|
88 PING VALUE "PING".
|
||||||
|
88 PRIVMSG VALUE "PRIVMSG".
|
||||||
|
03 PARAMETERS.
|
||||||
|
05 TARGET PIC X(50).
|
||||||
|
05 REST PIC X(480).
|
||||||
|
01 WAITING-COMMAND PIC X(16).
|
||||||
|
01 PARAMS.
|
||||||
|
03 WORK PIC X(50).
|
||||||
|
03 WORK-PREFIX REDEFINES WORK PIC X.
|
||||||
|
88 IS-COMMAND VALUE "$".
|
||||||
|
88 REST-PARAM VALUE ":".
|
||||||
|
03 PARAM PIC X(50) OCCURS 5 TIMES.
|
||||||
|
03 REG PIC X(50) OCCURS 5 TIMES.
|
||||||
|
|
||||||
|
PROCEDURE DIVISION.
|
||||||
|
DISPLAY "CONFIGURATION FOLLOWS:".
|
||||||
|
CALL "PRINT-CONFIG".
|
||||||
|
MOVE LENGTH OF MSG-BODY TO MSG-LENGTH.
|
||||||
|
CALL "CHANNEL-INIT"
|
||||||
|
USING BUFFER.
|
||||||
|
OPEN INPUT CONFIG.
|
||||||
|
MOVE "SERVER" TO CONFIG-KEY.
|
||||||
|
PERFORM READ-CONFIG-ENTRY.
|
||||||
|
MOVE 1 TO MSG-LENGTH.
|
||||||
|
STRING
|
||||||
|
CONFIG-VALUE, DELIMITED BY SPACE,
|
||||||
|
INTO MSG-BODY,
|
||||||
|
WITH POINTER MSG-LENGTH.
|
||||||
|
CALL "CHANNEL-OPEN", GIVING STATE.
|
||||||
|
IF NOT SUCCESS THEN DISPLAY MSG-BODY
|
||||||
|
GO TO DIE.
|
||||||
|
MOVE "NICK" TO CONFIG-KEY.
|
||||||
|
PERFORM READ-CONFIG-ENTRY.
|
||||||
|
MOVE 1 TO MSG-LENGTH.
|
||||||
|
INITIALIZE MSG-BODY.
|
||||||
|
STRING "NICK"
|
||||||
|
INTO MSG-BODY
|
||||||
|
WITH POINTER MSG-LENGTH.
|
||||||
|
ADD 1 TO MSG-LENGTH.
|
||||||
|
STRING CONFIG-VALUE DELIMITED BY SPACE,
|
||||||
|
INTO MSG-BODY
|
||||||
|
WITH POINTER MSG-LENGTH.
|
||||||
|
PERFORM SEND-LINE.
|
||||||
|
MOVE 1 TO MSG-LENGTH.
|
||||||
|
INITIALIZE MSG-BODY.
|
||||||
|
STRING "USER"
|
||||||
|
INTO MSG-BODY
|
||||||
|
WITH POINTER MSG-LENGTH.
|
||||||
|
ADD 1 TO MSG-LENGTH.
|
||||||
|
MOVE "IDENT" TO CONFIG-KEY.
|
||||||
|
PERFORM READ-CONFIG-ENTRY.
|
||||||
|
STRING CONFIG-VALUE DELIMITED BY SPACE,
|
||||||
|
INTO MSG-BODY
|
||||||
|
WITH POINTER MSG-LENGTH.
|
||||||
|
ADD 1 TO MSG-LENGTH.
|
||||||
|
MOVE "REAL-NAME" TO CONFIG-KEY.
|
||||||
|
PERFORM READ-CONFIG-ENTRY.
|
||||||
|
STRING "BOGUS HOST :" DELIMITED BY SIZE,
|
||||||
|
CONFIG-VALUE DELIMITED BY " ",
|
||||||
|
INTO MSG-BODY
|
||||||
|
WITH POINTER MSG-LENGTH.
|
||||||
|
PERFORM SEND-LINE.
|
||||||
|
MOVE "NICKSERV-PASSWORD" TO CONFIG-KEY.
|
||||||
|
READ CONFIG RECORD
|
||||||
|
INVALID KEY MOVE SPACES TO CONFIG-KEY.
|
||||||
|
IF CONFIG-KEY IS NOT EQUAL TO SPACES THEN
|
||||||
|
INITIALIZE MSG-BODY
|
||||||
|
MOVE 1 TO MSG-LENGTH
|
||||||
|
STRING "PRIVMSG NICKSERV :IDENTIFY " DELIMITED BY SIZE,
|
||||||
|
CONFIG-VALUE DELIMITED BY SPACE,
|
||||||
|
INTO MSG-BODY
|
||||||
|
WITH POINTER MSG-LENGTH
|
||||||
|
PERFORM SEND-LINE.
|
||||||
|
OPEN INPUT CHANNELS.
|
||||||
|
PERFORM AUTOJOIN-CHANNELS UNTIL DONE.
|
||||||
|
CLOSE CHANNELS.
|
||||||
|
OPEN I-O USERS.
|
||||||
|
PERFORM MAIN FOREVER.
|
||||||
|
|
||||||
|
DIE.
|
||||||
|
DISPLAY STATE.
|
||||||
|
STOP RUN.
|
||||||
|
|
||||||
|
AUTOJOIN-CHANNELS.
|
||||||
|
READ CHANNELS RECORD
|
||||||
|
AT END MOVE 99 TO STATE.
|
||||||
|
IF NOT DONE THEN
|
||||||
|
MOVE 1 TO MSG-LENGTH
|
||||||
|
STRING "JOIN " DELIMITED BY SIZE,
|
||||||
|
CHANNEL-NAME DELIMITED BY SPACES,
|
||||||
|
INTO MSG-BODY
|
||||||
|
WITH POINTER MSG-LENGTH
|
||||||
|
PERFORM SEND-LINE.
|
||||||
|
|
||||||
|
READ-CONFIG-ENTRY.
|
||||||
|
READ CONFIG RECORD
|
||||||
|
INVALID KEY DISPLAY "REQUIRED KEY UNSPECIFIED:"
|
||||||
|
DISPLAY CONFIG-KEY
|
||||||
|
GO TO DIE.
|
||||||
|
|
||||||
|
SEND-LINE.
|
||||||
|
CALL "CHANNEL-SEND" GIVING STATE.
|
||||||
|
IF NOT SUCCESS THEN DISPLAY MSG-BODY
|
||||||
|
GO TO DIE.
|
||||||
|
|
||||||
|
RECEIVE-LINE.
|
||||||
|
INITIALIZE MSG-BODY.
|
||||||
|
CALL "CHANNEL-RECV" GIVING STATE.
|
||||||
|
IF NOT SUCCESS THEN GO TO DIE.
|
||||||
|
CALL "IRC-MSG" USING BUFFER, IRC-MESSAGE.
|
||||||
|
|
||||||
|
WAIT-FOR-COMMAND.
|
||||||
|
PERFORM RECEIVE-LINE UNTIL COMMAND EQUALS WAITING-COMMAND.
|
||||||
|
|
||||||
|
GET-PARAMS.
|
||||||
|
UNSTRING REST DELIMITED BY SPACE INTO
|
||||||
|
PARAM(1)
|
||||||
|
PARAM(2)
|
||||||
|
PARAM(3)
|
||||||
|
PARAM(4)
|
||||||
|
PARAM(5).
|
||||||
|
MOVE PARAM(1) TO WORK.
|
||||||
|
IF REST-PARAM THEN
|
||||||
|
UNSTRING WORK DELIMITED BY ":" INTO PARAM(1), PARAM(1).
|
||||||
|
|
||||||
|
VALIDATE-USER.
|
||||||
|
MOVE NICK TO USER-NAME.
|
||||||
|
READ USERS RECORD
|
||||||
|
INVALID KEY MOVE 0 TO USER-LEVEL.
|
||||||
|
DISPLAY USER-RECORD.
|
||||||
|
IF USER-LEVEL IS GREATER THAN 0 THEN
|
||||||
|
INITIALIZE MSG-BODY
|
||||||
|
MOVE 1 TO MSG-LENGTH
|
||||||
|
STRING "PRIVMSG NICKSERV :ACC"
|
||||||
|
INTO MSG-BODY
|
||||||
|
WITH POINTER MSG-LENGTH
|
||||||
|
ADD 1 TO MSG-LENGTH
|
||||||
|
STRING NICK
|
||||||
|
INTO MSG-BODY
|
||||||
|
WITH POINTER MSG-LENGTH
|
||||||
|
PERFORM SEND-LINE
|
||||||
|
MOVE "NOTICE" TO WAITING-COMMAND
|
||||||
|
MOVE 0 TO STATE
|
||||||
|
PERFORM WAIT-FOR-ACC UNTIL DONE.
|
||||||
|
|
||||||
|
WAIT-FOR-ACC.
|
||||||
|
PERFORM WAIT-FOR-COMMAND.
|
||||||
|
PERFORM GET-PARAMS.
|
||||||
|
IF PARAM(1) EQUALS USER-NAME AND PARAM(2) EQUALS "ACC" THEN
|
||||||
|
MOVE 99 TO STATE
|
||||||
|
IF PARAM(3) IS NOT EQUAL TO "3" THEN
|
||||||
|
MOVE 0 TO USER-LEVEL
|
||||||
|
ELSE NEXT SENTENCE
|
||||||
|
ELSE INITIALIZE COMMAND.
|
||||||
|
|
||||||
|
MAIN.
|
||||||
|
PERFORM RECEIVE-LINE.
|
||||||
|
MOVE 1 TO MSG-LENGTH.
|
||||||
|
IF PING THEN
|
||||||
|
PERFORM PONG
|
||||||
|
ELSE IF PRIVMSG THEN
|
||||||
|
PERFORM HANDLE-PRIVMSG.
|
||||||
|
|
||||||
|
PONG.
|
||||||
|
DISPLAY "PONG".
|
||||||
|
STRING "PONG"
|
||||||
|
INTO MSG-BODY
|
||||||
|
WITH POINTER MSG-LENGTH.
|
||||||
|
PERFORM SEND-LINE.
|
||||||
|
|
||||||
|
HANDLE-PRIVMSG.
|
||||||
|
PERFORM GET-PARAMS.
|
||||||
|
MOVE PARAM(1) TO WORK.
|
||||||
|
IF IS-COMMAND THEN
|
||||||
|
UNSTRING WORK DELIMITED BY "$" INTO PARAM(1), PARAM(1)
|
||||||
|
IF PARAM(1) IS EQUAL TO "HELP" THEN
|
||||||
|
PERFORM HANDLE-HELP
|
||||||
|
ELSE IF PARAM(1) IS EQUAL TO "SOURCE" THEN
|
||||||
|
PERFORM HANDLE-SOURCE
|
||||||
|
ELSE IF PARAM(1) IS EQUAL TO "LEVEL" THEN
|
||||||
|
PERFORM HANDLE-LEVEL
|
||||||
|
ELSE IF PARAM(1) IS EQUAL TO "OP" THEN
|
||||||
|
PERFORM HANDLE-OP
|
||||||
|
ELSE IF PARAM(1) IS EQUAL TO "JOIN" THEN
|
||||||
|
PERFORM HANDLE-JOIN
|
||||||
|
ELSE IF PARAM(1) IS EQUAL TO "PART" THEN
|
||||||
|
PERFORM HANDLE-PART
|
||||||
|
ELSE IF PARAM(1) IS EQUAL TO "QUIT" THEN
|
||||||
|
PERFORM HANDLE-QUIT
|
||||||
|
ELSE IF PARAM(1) IS EQUAL TO "RELEVEL" THEN
|
||||||
|
PERFORM HANDLE-RELEVEL.
|
||||||
|
|
||||||
|
HANDLE-HELP.
|
||||||
|
INITIALIZE MSG-BODY.
|
||||||
|
MOVE 1 TO MSG-LENGTH.
|
||||||
|
STRING "PRIVMSG "
|
||||||
|
TARGET
|
||||||
|
INTO MSG-BODY
|
||||||
|
WITH POINTER MSG-LENGTH.
|
||||||
|
ADD 1 TO MSG-LENGTH.
|
||||||
|
STRING ":$HELP $LEVEL $OP $JOIN $PART $QUIT $RELEVEL"
|
||||||
|
INTO MSG-BODY
|
||||||
|
WITH POINTER MSG-LENGTH.
|
||||||
|
PERFORM SEND-LINE.
|
||||||
|
|
||||||
|
HANDLE-SOURCE.
|
||||||
|
INITIALIZE MSG-BODY.
|
||||||
|
MOVE 1 TO MSG-LENGTH.
|
||||||
|
STRING "PRIVMSG "
|
||||||
|
TARGET
|
||||||
|
INTO MSG-BODY
|
||||||
|
WITH POINTER MSG-LENGTH.
|
||||||
|
ADD 1 TO MSG-LENGTH.
|
||||||
|
STRING ":HTTPS://GITHUB.COM/HEDDWCH/WOPO"
|
||||||
|
INTO MSG-BODY
|
||||||
|
WITH POINTER MSG-LENGTH.
|
||||||
|
PERFORM SEND-LINE.
|
||||||
|
|
||||||
|
HANDLE-LEVEL.
|
||||||
|
IF PARAM(2) IS NOT EQUAL TO SPACES THEN
|
||||||
|
MOVE PARAM(2) TO USER-NAME
|
||||||
|
ELSE
|
||||||
|
MOVE NICK TO USER-NAME.
|
||||||
|
READ USERS RECORD
|
||||||
|
INVALID KEY MOVE 0 TO USER-LEVEL.
|
||||||
|
INITIALIZE MSG-BODY.
|
||||||
|
MOVE 1 TO MSG-LENGTH.
|
||||||
|
STRING USER-RECORD
|
||||||
|
INTO MSG-BODY
|
||||||
|
WITH POINTER MSG-LENGTH.
|
||||||
|
PERFORM SEND-LINE.
|
||||||
|
|
||||||
|
HANDLE-OP.
|
||||||
|
MOVE TARGET TO REG(1).
|
||||||
|
MOVE PARAM(2) TO REG(2).
|
||||||
|
IF REG(2) IS EQUAL TO SPACES THEN
|
||||||
|
MOVE NICK TO REG(2).
|
||||||
|
PERFORM VALIDATE-USER.
|
||||||
|
IF USER-LEVEL IS GREATER THAN 50 THEN
|
||||||
|
INITIALIZE MSG-BODY
|
||||||
|
MOVE 1 TO MSG-LENGTH
|
||||||
|
STRING "MODE " DELIMITED BY SIZE,
|
||||||
|
REG(1) DELIMITED BY SPACES
|
||||||
|
INTO MSG-BODY
|
||||||
|
WITH POINTER MSG-LENGTH
|
||||||
|
ADD 1 TO MSG-LENGTH
|
||||||
|
STRING "+O " DELIMITED BY SIZE,
|
||||||
|
REG(2) DELIMITED BY SPACES
|
||||||
|
INTO MSG-BODY
|
||||||
|
WITH POINTER MSG-LENGTH
|
||||||
|
PERFORM SEND-LINE.
|
||||||
|
|
||||||
|
HANDLE-JOIN.
|
||||||
|
MOVE PARAM(2) TO REG(1).
|
||||||
|
PERFORM VALIDATE-USER.
|
||||||
|
IF USER-LEVEL IS GREATER THAN 80 THEN
|
||||||
|
INITIALIZE MSG-BODY
|
||||||
|
MOVE 1 TO MSG-LENGTH
|
||||||
|
STRING "JOIN ", REG(1)
|
||||||
|
INTO MSG-BODY
|
||||||
|
WITH POINTER MSG-LENGTH
|
||||||
|
PERFORM SEND-LINE.
|
||||||
|
|
||||||
|
HANDLE-PART.
|
||||||
|
MOVE PARAM(2) TO REG(1).
|
||||||
|
IF REG(1) EQUALS SPACES THEN
|
||||||
|
MOVE TARGET TO REG(1).
|
||||||
|
PERFORM VALIDATE-USER.
|
||||||
|
IF USER-LEVEL IS GREATER THAN 80 THEN
|
||||||
|
INITIALIZE MSG-BODY
|
||||||
|
MOVE 1 TO MSG-LENGTH
|
||||||
|
STRING "PART ", REG(1)
|
||||||
|
INTO MSG-BODY
|
||||||
|
WITH POINTER MSG-LENGTH
|
||||||
|
PERFORM SEND-LINE.
|
||||||
|
|
||||||
|
HANDLE-QUIT.
|
||||||
|
MOVE "QUIT-MESSAGE" TO CONFIG-KEY.
|
||||||
|
READ CONFIG RECORD
|
||||||
|
INVALID KEY MOVE SPACES TO CONFIG-VALUE.
|
||||||
|
PERFORM VALIDATE-USER.
|
||||||
|
IF USER-LEVEL IS GREATER THAN 90 THEN
|
||||||
|
INITIALIZE MSG-BODY
|
||||||
|
MOVE 1 TO MSG-LENGTH
|
||||||
|
STRING "QUIT :", CONFIG-VALUE
|
||||||
|
INTO MSG-BODY
|
||||||
|
WITH POINTER MSG-LENGTH
|
||||||
|
PERFORM SEND-LINE
|
||||||
|
GO TO QUIT.
|
||||||
|
|
||||||
|
HANDLE-RELEVEL.
|
||||||
|
MOVE PARAM(2) TO USER-NAME.
|
||||||
|
MOVE PARAM(3) TO USER-LEVEL.
|
||||||
|
PERFORM VALIDATE-USER.
|
||||||
|
IF USER-LEVEL IS EQUAL TO 99 THEN
|
||||||
|
WRITE USER-RECORD.
|
||||||
|
READ USERS RECORD
|
||||||
|
INVALID KEY MOVE 0 TO USER-LEVEL.
|
||||||
|
INITIALIZE MSG-BODY.
|
||||||
|
MOVE 1 TO MSG-LENGTH.
|
||||||
|
STRING USER-RECORD
|
||||||
|
INTO MSG-BODY
|
||||||
|
WITH POINTER MSG-LENGTH.
|
||||||
|
PERFORM SEND-LINE.
|
||||||
|
|
||||||
|
QUIT.
|
||||||
|
CALL "CHANNEL-CLOSE".
|
||||||
|
CLOSE CONFIG.
|
||||||
|
CLOSE USERS.
|
||||||
|
STOP RUN.
|
||||||
|
|
|
@ -0,0 +1,211 @@
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define LENGTH_DIGITS 3
|
||||||
|
#define DEFAULT_PORT "6667"
|
||||||
|
#define RECV_BUF_SIZE 1024
|
||||||
|
/*
|
||||||
|
* 01 BUFFER
|
||||||
|
* 03 MSG-LENGTH PIC 9(LENGTH_DIGITS)
|
||||||
|
* 03 MSG-BODY PIC X(x)
|
||||||
|
*/
|
||||||
|
#define BODY(buf) (char *)(buf + LENGTH_DIGITS)
|
||||||
|
|
||||||
|
// 01 CHANNEL-STATUS PIC 9(2)
|
||||||
|
#define EBADDEST 10
|
||||||
|
#define EOPENFAIL 20
|
||||||
|
#define EHUP 30
|
||||||
|
#define ESERV 40
|
||||||
|
|
||||||
|
char *msg_length, *msg_body;
|
||||||
|
int msg_body_len;
|
||||||
|
int sockfd;
|
||||||
|
char recv_buf[RECV_BUF_SIZE];
|
||||||
|
size_t recv_buf_pos = 0;
|
||||||
|
|
||||||
|
int channel_message_length(void)
|
||||||
|
{
|
||||||
|
char c_length[LENGTH_DIGITS + 1];
|
||||||
|
memcpy(c_length, msg_length, LENGTH_DIGITS);
|
||||||
|
c_length[LENGTH_DIGITS] = '\0';
|
||||||
|
return (int)strtol(c_length, NULL, 10) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void channel_from_cobol(void)
|
||||||
|
{
|
||||||
|
int message_length = channel_message_length();
|
||||||
|
memset(msg_body + message_length, 0, msg_body_len - message_length);
|
||||||
|
for(char *c = msg_body; *c; c++) {
|
||||||
|
*c = tolower(*c);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void channel_to_cobol(void)
|
||||||
|
{
|
||||||
|
char *c;
|
||||||
|
for(c = msg_body; *c; c++) {
|
||||||
|
*c = toupper(*c);
|
||||||
|
}
|
||||||
|
memset(c, ' ', msg_body_len - strlen(msg_body));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void channel_string_to_cobol(const char *s)
|
||||||
|
{
|
||||||
|
strncpy(msg_body, s, msg_body_len - 2);
|
||||||
|
msg_body[msg_body_len - 1] = '\0';
|
||||||
|
channel_to_cobol();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MOVE LENGTH OF MSG-BODY OF BUFFER TO MSG-LENGTH OF BUFFER.
|
||||||
|
* CALL "CHANNEL-INIT" USING BUFFER.
|
||||||
|
*/
|
||||||
|
void CHANNEL__INIT(char *buffer)
|
||||||
|
{
|
||||||
|
msg_length = buffer;
|
||||||
|
msg_body = BODY(buffer);
|
||||||
|
msg_body_len = channel_message_length();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* STRING "HOST[:PORT]"
|
||||||
|
* INTO MSG-BODY
|
||||||
|
* WITH POINTER MSG-LENGTH.
|
||||||
|
* CALL "CHANNEL-OPEN" GIVING CHANNEL-STATUS.
|
||||||
|
*/
|
||||||
|
int CHANNEL__OPEN(void)
|
||||||
|
{
|
||||||
|
channel_from_cobol();
|
||||||
|
printf("Connecting to: %s\n", msg_body);
|
||||||
|
if(!strlen(msg_body)) {
|
||||||
|
channel_string_to_cobol("No host specified");
|
||||||
|
return EBADDEST;
|
||||||
|
}
|
||||||
|
char *port = strchr(msg_body, ':');
|
||||||
|
if(port) {
|
||||||
|
*port = '\0';
|
||||||
|
port++;
|
||||||
|
if(!strlen(port)) {
|
||||||
|
channel_string_to_cobol("Port separator specified, but not port");
|
||||||
|
return EBADDEST;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
port = DEFAULT_PORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct addrinfo hints, *res;
|
||||||
|
int status;
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_flags = AI_ADDRCONFIG;
|
||||||
|
if((status = getaddrinfo(msg_body, port, &hints, &res))) {
|
||||||
|
channel_string_to_cobol(gai_strerror(status));
|
||||||
|
return EBADDEST;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct addrinfo *curr_addr;
|
||||||
|
for(curr_addr = res; curr_addr; curr_addr = curr_addr->ai_next) {
|
||||||
|
sockfd = socket(curr_addr->ai_family, curr_addr->ai_socktype, curr_addr->ai_protocol);
|
||||||
|
if(sockfd == -1) {
|
||||||
|
perror("socket");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(connect(sockfd, curr_addr->ai_addr, curr_addr->ai_addrlen) == -1) {
|
||||||
|
perror("connect");
|
||||||
|
close(sockfd);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!curr_addr) {
|
||||||
|
channel_string_to_cobol("Unable to connect to host");
|
||||||
|
return EOPENFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CHANNEL__SEND(void)
|
||||||
|
{
|
||||||
|
char *msg;
|
||||||
|
int sent, total;
|
||||||
|
channel_from_cobol();
|
||||||
|
printf("Sending: %s\n", msg_body);
|
||||||
|
sent = 0;
|
||||||
|
total = strlen(msg_body);
|
||||||
|
msg_body[total++] = '\n';
|
||||||
|
while(sent < total) {
|
||||||
|
int status = send(sockfd, msg_body + sent, total - sent, 0);
|
||||||
|
if(status == -1) {
|
||||||
|
perror("send");
|
||||||
|
close(sockfd);
|
||||||
|
channel_string_to_cobol("Hung up");
|
||||||
|
return EHUP;
|
||||||
|
}
|
||||||
|
sent += status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CHANNEL__RECV(void)
|
||||||
|
{
|
||||||
|
char *message_end;
|
||||||
|
get_buffered:
|
||||||
|
message_end = memchr(recv_buf, '\n', recv_buf_pos);
|
||||||
|
if(message_end) {
|
||||||
|
size_t message_size = message_end - recv_buf;
|
||||||
|
if (message_size > msg_body_len) {
|
||||||
|
channel_string_to_cobol("Server sent too-long message");
|
||||||
|
return ESERV;
|
||||||
|
}
|
||||||
|
memcpy(msg_body, recv_buf, message_size);
|
||||||
|
msg_body[message_size - 1] = '\0';
|
||||||
|
recv_buf_pos -= message_size + 1;
|
||||||
|
message_end++;
|
||||||
|
for(size_t i = 0; i < recv_buf_pos; i++) {
|
||||||
|
recv_buf[i] = message_end[i];
|
||||||
|
}
|
||||||
|
printf("Received: %s\n", msg_body);
|
||||||
|
channel_to_cobol();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(recv_buf_pos < RECV_BUF_SIZE - 1) {
|
||||||
|
ssize_t received = recv(sockfd, recv_buf + recv_buf_pos, RECV_BUF_SIZE - recv_buf_pos, 0);
|
||||||
|
if(received != -1) {
|
||||||
|
recv_buf_pos += received;
|
||||||
|
goto get_buffered;
|
||||||
|
}
|
||||||
|
perror("recv");
|
||||||
|
channel_string_to_cobol("Hung up");
|
||||||
|
return EHUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
channel_string_to_cobol("Server failed to send newline");
|
||||||
|
return ESERV;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHANNEL__CLOSE(void)
|
||||||
|
{
|
||||||
|
close(sockfd);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/sh
|
||||||
|
${CC:-cc} -o channel.o -c channel.c
|
||||||
|
${COBC:-cobc} -x WOPO-CNF.COB PRINTCNF.COB
|
||||||
|
${COBC:-cobc} -x WOPO.COB IRC-MSG.COB PRINTCNF.COB channel.o
|
||||||
|
|
Loading…
Reference in New Issue