├── vulnerable.php ├── obfuscated.c ├── obfuscated.java ├── wordReverse.js ├── utils.py ├── login-service.ts ├── move-commit-new-branch.sh ├── security-database-service.ts ├── transaction.js ├── parse_expenses.py ├── mystery.py ├── LICENSE ├── .devcontainer └── devcontainer.json ├── romanConverter.test.js ├── .gitignore ├── README.md ├── test.asm └── genericListener.cob /vulnerable.php: -------------------------------------------------------------------------------- 1 | // The article parameter is assigned to $article variable without any sanitization or validation 2 | $articleid = $_GET['article']; 3 | // The $articleid parameter is passed as part of the query 4 | $query = "SELECT * FROM articles WHERE articleid = $articleid"; 5 | 6 | -------------------------------------------------------------------------------- /obfuscated.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | char *c[] = { "ENTER", "NEW", "POINT", "FIRST" }; 4 | char **cp[] = { c+3, c+2, c+1, c }; 5 | char ***cpp = cp; 6 | 7 | main() 8 | { 9 | printf("%s", **++cpp); 10 | printf("%s ", *--*++cpp+3); 11 | printf("%s", *cpp[-2]+3); 12 | printf("%s\n", cpp[-1][-1]+1); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /obfuscated.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | class dnduxb 3 | { 4 | double ndndn; 5 | void _bxnuu(double _nneop) 6 | { 7 | ndndn= (22*_nneop*_nneop)/7; 8 | } 9 | } 10 | class _jnsnek extends dnduxb 11 | { 12 | public static void main(String args[]) 13 | { 14 | Scanner _jp= new Scanner(); 15 | System.out.println("nejshzyyhejeisns"); 16 | double _nbrudu= _jp.nextDouble(); 17 | _jnsnek jdjdj=new _jnsnek(); 18 | jdjdj._bxnuu(_nbrudu); 19 | System.out.println("cjxhxyhhbebj " + jdjdj.ndndn); 20 | } 21 | } -------------------------------------------------------------------------------- /wordReverse.js: -------------------------------------------------------------------------------- 1 | function wordReverse(str) { 2 | var strArray = str.split(" "); 3 | var newArray = []; 4 | for (var i = 0; i < strArray.length; i++) { 5 | newArray.push(strArray[i].split("").reverse().join("")); 6 | } 7 | return newArray.join(" "); 8 | } 9 | 10 | var sentences = [ 11 | "Hello World", 12 | "I am a sentence", 13 | "This is a sentence", 14 | "This is a sentence", 15 | "This is a sentence" 16 | ] 17 | 18 | sentences.forEach((sentence) => console.log(wordReverse(sentence))); -------------------------------------------------------------------------------- /utils.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | e_regex = r'^[\w\.\+\-]+@[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-\.]+$' 4 | p_regex = r'^(\+)?1?\d{9,15}$' 5 | s_regex = r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$' 6 | 7 | def checkvalid(text, regex): 8 | if re.search(regex, text): 9 | return True 10 | else: 11 | return False 12 | 13 | if __name__ == '__main__': 14 | print(("valid", "invalid")[checkvalid('',e_regex)]) 15 | print(("valid", "invalid")[checkvalid('',p_regex)]) 16 | print(("valid", "invalid")[checkvalid('',s_regex)]) 17 | 18 | 19 | -------------------------------------------------------------------------------- /login-service.ts: -------------------------------------------------------------------------------- 1 | import { User, saveUser } from './security-database-service'; 2 | 3 | function isPasswordValid(password: string): boolean { 4 | return isPasswordComplex(password); 5 | } 6 | 7 | function isPasswordComplex(password: string): boolean { 8 | // check if password is at least 8 characters long and contains at least one uppercase letter, one lowercase letter, and one number 9 | const regex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$/; 10 | return regex.test(password); 11 | } 12 | 13 | 14 | function addUser(user: User): void { 15 | // adding user to database 16 | saveUser(user); 17 | } 18 | 19 | 20 | export { addUser, isPasswordValid }; -------------------------------------------------------------------------------- /move-commit-new-branch.sh: -------------------------------------------------------------------------------- 1 | # Prompt: git? I want to move the last commit on a new branch 2 | 3 | 4 | # ──────────────────── Command ──────────────────── 5 | 6 | git branch new-branch 7 | git reset --hard HEAD~1 8 | git switch new-branch 9 | 10 | # ────────────────── Explanation ────────────────── 11 | # 12 | # ○ git branch new-branch creates a new branch called new-branch. 13 | # ○ git reset resets the current branch to a previous commit. 14 | # ◆ --hard means that we also discard any changes made to the files in the working directory. 15 | # ◆ HEAD~1 specifies that we reset the commit one before the current one. 16 | # ○ git switch new-branch switches to the new-branch branch. 17 | 18 | -------------------------------------------------------------------------------- /security-database-service.ts: -------------------------------------------------------------------------------- 1 | interface User { 2 | username: string; 3 | password: string; 4 | } 5 | 6 | interface User { 7 | username: string; 8 | password: string; 9 | } 10 | 11 | async function saveUser(user: User): Promise { 12 | // implementation for saving user to database 13 | // you can use a third-party library or API to save the user to a database 14 | // for example, you can use the Firebase Realtime Database to save the user 15 | // here's an example implementation using the Firebase Realtime Database: 16 | //const database = firebase.database(); 17 | //const usersRef = database.ref('users'); 18 | //const newUserRef = usersRef.push(); 19 | //await newUserRef.set(user); 20 | } 21 | 22 | export { User, saveUser }; -------------------------------------------------------------------------------- /transaction.js: -------------------------------------------------------------------------------- 1 | // transaction class with a date, amount, and description 2 | class transaction { 3 | constructor(date, amount, description) { 4 | this.date = date; 5 | this.amount = amount; 6 | this.description = description; 7 | } 8 | 9 | // getters 10 | getDate() { 11 | return this.date; 12 | } 13 | getAmount() { 14 | return this.amount; 15 | } 16 | getDescription() { 17 | return this.description; 18 | } 19 | 20 | // setters 21 | setDate(date) { 22 | this.date = date; 23 | } 24 | setAmount(amount) { 25 | this.amount = amount; 26 | } 27 | setDescription(description) { 28 | this.description = description; 29 | } 30 | } 31 | 32 | // calculate tax based on tax rate 33 | export async function calculateTax(amount, taxRate){ 34 | return amount * taxRate; 35 | } -------------------------------------------------------------------------------- /parse_expenses.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | def parse_expenses (expenses_string) : 4 | """Parse the list of expenses and return the 5 | list of triples (date, value, currency). 6 | Ignore lines starting with #. 7 | Parse the date using datetime. 8 | Example expenses_string : 9 | 2023-01-02 -34.01 USD 10 | 2023-01-03 2.59 DKK 11 | 2023-01-03 -2.72 EUR 12 | """ 13 | expenses = [] 14 | for line in expenses_string.splitlines(): 15 | if line.startswith("#"): 16 | continue 17 | date, value, currency = line.split(",") 18 | expenses.append((float (value), 19 | currency, 20 | datetime.datetime.strptime(date, "%Y-%m-%d"))) 21 | return expenses 22 | 23 | expenses_data = '''2023-01-02 -34.01 USD 24 | 2023-01-03 2.59 DKK 25 | 2023-01-03 -2.72 EUR''' 26 | 27 | expenses = parse_expenses (expenses_data) 28 | for expense in expenses: 29 | print (f'{expense[0]} {expense[1]} {expense[2]}') 30 | 31 | 32 | -------------------------------------------------------------------------------- /mystery.py: -------------------------------------------------------------------------------- 1 | _ = ( 2 | 255, 3 | lambda 4 | V ,B,c 5 | :c and Y(V*V+B,B, c 6 | -1)if(abs(V)<6)else 7 | ( 2+c-4*abs(V)**-0.4)/i 8 | ) ;v, x=1500,1000;C=range(v*x 9 | );import struct;P=struct.pack;M,\ 10 | j =' { 4 | it('should return 1 for input "I"', () => { 5 | expect(calculate('I')).toBe(1); 6 | }); 7 | 8 | it('should return 4 for input "IV"', () => { 9 | expect(calculate('IV')).toBe(4); 10 | }); 11 | 12 | it('should return 9 for input "IX"', () => { 13 | expect(calculate('IX')).toBe(9); 14 | }); 15 | 16 | it('should return 40 for input "XL"', () => { 17 | expect(calculate('XL')).toBe(40); 18 | }); 19 | 20 | it('should return 49 for input "XLIX"', () => { 21 | expect(calculate('XLIX')).toBe(49); 22 | }); 23 | 24 | it('should return 90 for input "XC"', () => { 25 | expect(calculate('XC')).toBe(90); 26 | }); 27 | 28 | it('should return 99 for input "XCIX"', () => { 29 | expect(calculate('XCIX')).toBe(99); 30 | }); 31 | 32 | it('should return 400 for input "CD"', () => { 33 | expect(calculate('CD')).toBe(400); 34 | }); 35 | 36 | it('should return 499 for input "CDXCIX"', () => { 37 | expect(calculate('CDXCIX')).toBe(499); 38 | }); 39 | 40 | it('should return 900 for input "CM"', () => { 41 | expect(calculate('CM')).toBe(900); 42 | }); 43 | 44 | it('should return 999 for input "CMXCIX"', () => { 45 | expect(calculate('CMXCIX')).toBe(999); 46 | }); 47 | 48 | it('should return 3999 for input "MMMCMXCIX"', () => { 49 | expect(calculate('MMMCMXCIX')).toBe(3999); 50 | }); 51 | 52 | it('should return 0 for empty input', () => { 53 | expect(calculate('')).toBe(0); 54 | }); 55 | 56 | it('should return 0 for invalid input', () => { 57 | expect(calculate('hello')).toBe(0); 58 | expect(calculate('123')).toBe(0); 59 | expect(calculate('MCMXCVI')).toBe(0); 60 | }); 61 | }); -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Copilot X 2 | 3 | A collection of files and links curated to help demonstrate features available in Copilot X. 4 | 5 | 6 | # Home page for Copilot X 7 | 8 | Interested in signing up for our Copilot X experiments, the following page allows you to sign up for lots of different experiements. 9 | 10 | Visit [https://gh.io/copilotx](https://gh.io/copilotx) 11 | 12 | # Copilot Chat 13 | 14 | Filename | My usage 15 | --- | --- 16 | utils.py | I use this to show some of the core features of Copilot Chat. The file comes from the awesome [YouTube video](https://www.youtube.com/watch?v=3surPGP7_4o) that Allison (@2percentsilk) recorded. Watch the video for the use cases. 17 | parse_expenses.py | Also from the awesome video mentioned in the previous row 18 | test.asm | I like to show Copilot Chat translating this Assembly language into Python 19 | genericListener.cob | I usually show Copilot Chat translating this COBOL into Java 20 | vulnerable.php | I ask Copilot Chat if this code is secure. It tell me that it's not. I then ask Copilot Chat to fix the code. 21 | transaction.js | I use this to show Chat rewriting the calculateTax function to look up the tax rate. "calculateTax needs to take the zip code and look up the tax rate". Note that it will likely invent an API. 22 | login-service.ts | Ask Copilot Chat to add a function to check if a password has been breached. It will usually suggest code to call the haveibeenpwnd API. Note this also uses security-database-service.ts so the code is a little cleaner. 23 | obfuscated.c, obfuscated.java | Ask Copilot chat to explain the code. The first is obfuscated C code that does strange things with pointers, but Copilot seems to be able to interpret it. The second is Java with unreadable class and variable names, however Copilot identifies that it's just calculating the area of a circle. A great second step is asking to make it readable. 24 | mystery.py | An extreme example of what Copilot Chat can do (likely because it's a famous example). Ask it to explain the code. Ideally run the code (you'll need python 2.7 - run `py -2.7 mystery.py`) then open the resulting M.bmp file which should get built on screen as you watch. 25 | wordReverse.js | Without using my hands, I talk with Copilot Voice and explain it step by step what I want to code. I also ask for some changes on the fly and to explain the code. 26 | romanConverter.test.js | Copilot Chat generates unit tests covering edge cases for a function that converts Roman numerals to integers. I did not provide the number to letter mapping, it got it right by itself. 27 | move-commit-new-branch.sh | Copilot CLI generates and explains me the commands to move the last commit to a new branch. 28 | 29 | 30 | # Copilot 4 docs 31 | 32 | We’re exploring a way to get you the information you need, faster. By surfacing the most relevant content for questions with tailored summaries that help connect the dots, Copilot for docs saves developers from scouring reams of documentation. 33 | 34 | Open Copilot4docs using [https://copilot4docs.githubnext.com/](https://copilot4docs.githubnext.com/) 35 | 36 | 37 | # What's Next? See Githubnext 38 | 39 | Open Githubnext using [https://githubnext.com/](https://githubnext.com/) -------------------------------------------------------------------------------- /test.asm: -------------------------------------------------------------------------------- 1 | maxTerms equ 15000 ; number of terms of the series to calculate 2 | 3 | 4 | digits equ (maxTerms*209+1673)/1000 5 | 6 | 7 | cntDigits equ 6 ; number of digits for counter 8 | 9 | org 100h ; this is a DOS com file 10 | 11 | main: 12 | 13 | mov ax,'00' ; initialize to all ASCII zeroes 14 | mov di,counter ; including the counter 15 | mov cx,digits+cntDigits/2 ; two bytes at a time 16 | cld ; initialize from low to high memory 17 | rep stosw ; write the data 18 | inc ax ; make sure ASCII zero is in al 19 | mov [num1 + digits - 1],al ; last digit is one 20 | mov [num2 + digits - 1],al ; 21 | mov [counter + cntDigits - 1],al 22 | 23 | jmp .bottom ; done with initialization, so begin 24 | 25 | .top 26 | ; add num1 to num2 27 | mov di,num1+digits-1 28 | mov si,num2+digits-1 29 | mov cx,digits ; 30 | call AddNumbers ; num2 += num1 31 | mov bp,num2 ; 32 | call PrintLine ; 33 | dec dword [term] ; decrement loop counter 34 | jz .done ; 35 | 36 | ; add num2 to num1 37 | mov di,num2+digits-1 38 | mov si,num1+digits-1 39 | mov cx,digits ; 40 | call AddNumbers ; num1 += num2 41 | .bottom 42 | mov bp,num1 ; 43 | call PrintLine ; 44 | dec dword [term] ; decrement loop counter 45 | jnz .top ; 46 | .done 47 | call CRLF ; finish off with CRLF 48 | mov ax,4c00h ; terminate 49 | int 21h ; 50 | 51 | 52 | 53 | PrintLine: 54 | mov dx,eol ; print combined CRLF and msg1 55 | mov cx,msg1len+eollen ; 56 | call PrintString ; 57 | 58 | mov di,counter ; print counter 59 | mov cx,cntDigits ; 60 | call PrintNumericString 61 | 62 | call IncrementCount ; also increment the counter 63 | 64 | mov dx,msg2 ; print msg2 65 | mov cx,msg2len ; 66 | call PrintString ; 67 | 68 | mov di,bp ; recall address of number 69 | mov cx,digits ; 70 | ; deliberately fall through to PrintNumericString 71 | 72 | 73 | PrintNumericString: 74 | ; first scan for the first non-zero byte 75 | mov al,'0' ; look for ASCII zero 76 | cld ; scan from MSD to LSD 77 | repe scasb ; 78 | mov dx,di ; points to one byte after 79 | dec dx ; back up one character 80 | inc cx ; 81 | ; deliberately fall through to PrintString 82 | 83 | 84 | PrintString: 85 | mov bx, 1 ; write to stdout 86 | mov ah, 040h ; write to file handle 87 | int 21h ; ignore return value 88 | ret ; 89 | 90 | 91 | AddNumbers: 92 | std ; go from LSB to MSB 93 | clc ; 94 | pushf ; save carry flag 95 | .top 96 | mov ax,0f0fh ; convert from ASCII BCD to BCD 97 | and al,[si] ; get next digit of number2 in al 98 | and ah,[di] ; get next digit of number1 in ah 99 | popf ; recall carry flag 100 | adc al,ah ; add these digits 101 | aaa ; convert to BCD 102 | pushf ; 103 | add al,'0' ; convert back to ASCII BCD digit 104 | stosb ; save it and increment both counters 105 | dec si ; 106 | loop .top ; keep going until we've got them all 107 | popf ; recall carry flag 108 | ret ; 109 | 110 | 111 | IncrementCount: 112 | mov cx,cntDigits ; 113 | mov di,counter+cntDigits-1 114 | std ; go from LSB to MSB 115 | stc ; this is our increment 116 | pushf ; save carry flag 117 | .top 118 | mov ax,000fh ; convert from ASCII BCD to BCD 119 | and al,[di] ; get next digit of counter in al 120 | popf ; recall carry flag 121 | adc al,ah ; add these digits 122 | aaa ; convert to BCD 123 | pushf ; 124 | add al,'0' ; convert back to ASCII BCD digit 125 | stosb ; save and increment counter 126 | loop .top ; 127 | popf ; recall carry flag 128 | ret ; 129 | 130 | 131 | CRLF: mov dx,eol ; 132 | mov cx,eollen ; 133 | jmp PrintString ; 134 | 135 | 136 | eol db 13,10 ; DOS-style end of line 137 | eollen equ $ - eol 138 | 139 | msg1 db 'Fibonacci(' ; 140 | msg1len equ $ - msg1 141 | 142 | msg2 db '): ' ; 143 | msg2len equ $ - msg2 144 | 145 | term dd maxTerms ; 146 | 147 | counter: ; 148 | num1 equ counter+cntDigits ; 149 | num2 equ num1+digits ; 150 | -------------------------------------------------------------------------------- /genericListener.cob: -------------------------------------------------------------------------------- 1 | RETRIEVAL 2 | NO-ACTIVITY-LOG 3 | DMLIST 4 | 5 | ***************************************************************** 6 | The following program is an example of a TCP/IP generic * 7 | listener server program written in COBOL. * 8 | The processing is the following: * 9 | - read a message from the client (first 4 bytes = data length)* 10 | - send the message back to the client program * 11 | - if the message text is equal to "STOP" or if the connection * 12 | is closed, then it closes its socket and return to the * 13 | generic listener service. * 14 | - if the message text is not equal to "STOP", then it returns * 15 | to the generic listener service without closing its socket. * 16 | ***************************************************************** 17 | 18 | IDENTIFICATION DIVISION. 19 | PROGRAM-ID. COBLIS. 20 | ENVIRONMENT DIVISION. 21 | IDMS-CONTROL SECTION. 22 | PROTOCOL. MODE IS IDMS-DC DEBUG 23 | IDMS-RECORDS MANUAL. 24 | 25 | DATA DIVISION. 26 | 27 | WORKING-STORAGE SECTION. 28 | 29 | 01 COPY IDMS SUBSCHEMA-CTRL. 30 | 01 COPY IDMS RECORD SOCKET-CALL-INTERFACE. 31 | 32 | 01 MSG01 PIC X(20) VALUE ' Parameter string :'. 33 | 01 MSG02 PIC X(20) VALUE ' Socket descriptor :'. 34 | 01 MSG03 PIC X(20) VALUE ' Resume count :'. 35 | 01 MSG04 PIC X(15) VALUE ' Starting read.'. 36 | 01 MSG05 PIC X(16) VALUE ' Starting write.'. 37 | 01 MSG06 PIC X(16) VALUE ' Closing socket.'. 38 | 01 MSG07 PIC X(20) VALUE ' Socket return code:'. 39 | 01 MSG08 PIC X(20) VALUE ' Socket reason code:'. 40 | 01 MSG09 PIC X(20) VALUE ' Socket errno :'. 41 | 01 MSG10 PIC X(20) VALUE ' Buffer length :'. 42 | 01 MSG11 PIC X(08) VALUE ' Buffer:'. 43 | 01 MSG12 PIC X(22) VALUE ' Data length too long.'. 44 | 45 | 01 RETLEN PIC S9(8) COMP. 46 | 01 WK-LENGTH PIC S9(8) COMP. 47 | 01 WK-SUBSCRIPT PIC S9(4) COMP. 48 | 01 TERM-FLAG PIC S9(8) COMP VALUE 0. 49 | 50 | 01 BUFFER. 51 | 03 BUFFER-ARRAY PIC X(1) OCCURS 84 TIMES. 52 | 01 BUFFER-REDEF REDEFINES BUFFER. 53 | 03 BUFLEN PIC 9(8) COMP. 54 | 03 BUFTXT80 PIC X(80). 55 | 03 BUFTXT80-REDEF REDEFINES BUFTXT80. 56 | 05 BUFTXT04 PIC X(4). 57 | 05 BUFTXT76 PIC X(76). 58 | 59 | 01 WORKW. 60 | 03 WORK-WCC PIC X. 61 | 03 WORK PIC X(80). 62 | 63 | LINKAGE SECTION. 64 | ***************************************************************** 65 | Parameter list with which a listener program receives control * 66 | ***************************************************************** 67 | 01 SOCKET-PARMS PIC X(80). 68 | 01 SOCKET-DESCRIPTOR PIC S9(8) COMP. 69 | 01 SOCKET-RESUME-COUNT PIC S9(8) COMP. 70 | 71 | PROCEDURE DIVISION USING SOCKET-PARMS, 72 | SOCKET-DESCRIPTOR, 73 | SOCKET-RESUME-COUNT. 74 | 75 | ***************************************************************** 76 | Display the 3 input parameters * 77 | ***************************************************************** 78 | TCP-START. 79 | 80 | ***************************************************************** 81 | Read the first 4 bytes: will contain the remaining length * 82 | ***************************************************************** 83 | MOVE 4 TO WK-LENGTH. 84 | MOVE 0 TO BUFLEN. 85 | MOVE 1 TO WK-SUBSCRIPT. 86 | PERFORM TCP-READ THRU TCP-READ-EXIT. 87 | IF TERM-FLAG = 1 GO TO TCP-EXIT. 88 | 89 | ***************************************************************** 90 | Read the remaining data (maximum 80 characters are allowed) * 91 | ***************************************************************** 92 | IF BUFLEN GREATER THAN 80 93 | WRITE LOG MESSAGE ID 9060300 94 | PARMS FROM MSG12 LENGTH 22 95 | PERFORM TCP-CLOSE THRU TCP-CLOSE-EXIT 96 | GO TO TCP-EXIT. 97 | 98 | MOVE BUFLEN TO WK-LENGTH. 99 | MOVE 5 TO WK-SUBSCRIPT. 100 | PERFORM TCP-READ THRU TCP-READ-EXIT. 101 | IF TERM-FLAG = 1 GO TO TCP-EXIT. 102 | 103 | MOVE BUFLEN TO WORK. 104 | WRITE LOG MESSAGE ID 9060300 105 | PARMS FROM MSG10 LENGTH 20 106 | FROM WORKW LENGTH 9. 107 | MOVE BUFTXT80 TO WORK. 108 | MOVE BUFLEN TO WK-LENGTH. 109 | ADD 1 TO WK-LENGTH. 110 | WRITE LOG MESSAGE ID 9060300 111 | PARMS FROM MSG11 LENGTH 8 112 | FROM WORKW LENGTH WK-LENGTH. 113 | 114 | ***************************************************************** 115 | Send the message back to the client * 116 | ***************************************************************** 117 | MOVE BUFLEN TO WK-LENGTH. 118 | ADD 4 TO WK-LENGTH. 119 | MOVE 1 TO WK-SUBSCRIPT. 120 | PERFORM TCP-WRITE THRU TCP-WRITE-EXIT. 121 | 122 | IF BUFLEN = 4 AND BUFTXT04 = 'STOP' 123 | PERFORM TCP-CLOSE THRU TCP-CLOSE-EXIT. 124 | 125 | TCP-EXIT. 126 | GOBACK. 127 | 128 | ***************************************************************** 129 | Procedure to read a message from the client * 130 | ***************************************************************** 131 | TCP-READ. 132 | WRITE LOG MESSAGE ID 9060300 133 | PARMS FROM MSG04 LENGTH 15. 134 | PERFORM UNTIL WK-LENGTH = 0 135 | CALL 'IDMSOCKI' USING SOCKET-FUNCTION-READ, 136 | SOCKET-RETCD, 137 | SOCKET-ERRNO, 138 | SOCKET-RSNCD, 139 | SOCKET-DESCRIPTOR, 140 | BUFFER-ARRAY(WK-SUBSCRIPT), 141 | WK-LENGTH, 142 | RETLEN 143 | MOVE SOCKET-RETCD TO WORK 144 | WRITE LOG MESSAGE ID 9060300 145 | PARMS FROM MSG07 LENGTH 20 146 | FROM WORKW LENGTH 9 147 | IF SOCKET-RETCD NOT = 0 OR RETLEN = 0 148 | PERFORM TCP-ERROR THRU TCP-ERROR-EXIT 149 | GO TO TCP-READ-EXIT 150 | END-IF 151 | ADD RETLEN TO WK-SUBSCRIPT 152 | SUBTRACT RETLEN FROM WK-LENGTH 153 | END-PERFORM. 154 | TCP-READ-EXIT. 155 | EXIT. 156 | 157 | ***************************************************************** 158 | Procedure to send a message to the client * 159 | ***************************************************************** 160 | TCP-WRITE. 161 | WRITE LOG MESSAGE ID 9060300 162 | PARMS FROM MSG05 LENGTH 16. 163 | PERFORM UNTIL WK-LENGTH = 0 164 | CALL 'IDMSOCKI' USING SOCKET-FUNCTION-WRITE, 165 | SOCKET-RETCD, 166 | SOCKET-ERRNO, 167 | SOCKET-RSNCD, 168 | SOCKET-DESCRIPTOR, 169 | BUFFER-ARRAY(WK-SUBSCRIPT), 170 | WK-LENGTH, 171 | RETLEN 172 | MOVE SOCKET-RETCD TO WORK 173 | WRITE LOG MESSAGE ID 9060300 174 | PARMS FROM MSG07 LENGTH 20 175 | FROM WORKW LENGTH 9 176 | IF SOCKET-RETCD NOT = 0 OR RETLEN = 0 177 | PERFORM TCP-ERROR THRU TCP-ERROR-EXIT 178 | GO TO TCP-WRITE-EXIT 179 | END-IF 180 | ADD RETLEN TO WK-SUBSCRIPT 181 | SUBTRACT RETLEN FROM WK-LENGTH 182 | END-PERFORM. 183 | TCP-WRITE-EXIT. 184 | EXIT. 185 | 186 | ***************************************************************** 187 | Procedure to close the socket * 188 | ***************************************************************** 189 | TCP-CLOSE. 190 | WRITE LOG MESSAGE ID 9060300 191 | PARMS FROM MSG06 LENGTH 16. 192 | CALL 'IDMSOCKI' USING SOCKET-FUNCTION-CLOSE, 193 | SOCKET-RETCD, 194 | SOCKET-ERRNO, 195 | SOCKET-RSNCD, 196 | SOCKET-DESCRIPTOR. 197 | MOVE SOCKET-RETCD TO WORK. 198 | WRITE LOG MESSAGE ID 9060300 199 | PARMS FROM MSG07 LENGTH 20 200 | FROM WORKW LENGTH 9. 201 | TCP-CLOSE-EXIT. 202 | EXIT. 203 | 204 | ***************************************************************** 205 | Procedure to process the socket call errors * 206 | ***************************************************************** 207 | TCP-ERROR. 208 | MOVE SOCKET-RSNCD TO WORK. 209 | WRITE LOG MESSAGE ID 9060300 210 | PARMS FROM MSG08 LENGTH 20 211 | FROM WORKW LENGTH 9. 212 | MOVE SOCKET-ERRNO TO WORK. 213 | WRITE LOG MESSAGE ID 9060300 214 | PARMS FROM MSG09 LENGTH 20 215 | FROM WORKW LENGTH 9. 216 | MOVE RETLEN TO WORK. 217 | WRITE LOG MESSAGE ID 9060300 218 | PARMS FROM MSG10 LENGTH 20 219 | FROM WORKW LENGTH 9. 220 | PERFORM TCP-CLOSE THRU TCP-CLOSE-EXIT. 221 | MOVE 1 TO TERM-FLAG. 222 | TCP-ERROR-EXIT. 223 | EXIT. 224 | 225 | ***************************************************************** 226 | 227 | COPY IDMS IDMS-STATUS. 228 | IDMS-ABORT SECTION. 229 | IDMS-ABORT-EXIT. 230 | EXIT. --------------------------------------------------------------------------------