Added code :D
This commit is contained in:
parent
818f88b329
commit
671b0cc8dd
6 changed files with 772 additions and 0 deletions
50
IRC-MSG.COB
Normal file
50
IRC-MSG.COB
Normal file
|
@ -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.
|
70
PRINTCNF.COB
Normal file
70
PRINTCNF.COB
Normal file
|
@ -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.
|
81
WOPO-CNF.COB
Normal file
81
WOPO-CNF.COB
Normal file
|
@ -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.
|
||||
|
355
WOPO.COB
Normal file
355
WOPO.COB
Normal file
|
@ -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.
|
||||
|
211
channel.c
Normal file
211
channel.c
Normal file
|
@ -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;
|
||||
}
|
||||
|
5
gnu-cobol.sh
Normal file
5
gnu-cobol.sh
Normal file
|
@ -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 a new issue