msa@clinet.FI (Markku Savela) (01/23/88)
*FIRST* Remember, that I cannot reply with netmail from this host. If you have any questions, I can receive them, but can reply only by posting to the news. These are my modifications to the CMU PC-IP package. It is a stripped down TELNET, which communicates through INT14- interface. The modules are of use only for those, who have the other required modules of CMU PC-IP. There is room for improvements. Hopefully this is usefull for some of you people out there -- if not, apologies for wasting net resources. I have added two new directories into my environment which contain the required files. The MAKEFILEs have been made in the "4N"-style (whatever that means). This message (part 1) contains the int14-catcher \PC-IP\SRCLIB\INT14 - int14 cather (ASM) MAKEFILE - build INT144N-module and add to library INT14TN.ASM - source of the "catcher". The next message (part 2) contains the modified TELNET modules. \PC-IP\SRCCMD\BTN - Modified Basic TN MAKEFILE - Build BTN.EXE (3COM variant only) TELNET.H - "tnsemulate" added TELNET.C - (modified from original TELNET.C) BTN.C - (modified from original TN.C) I use this version with the following command line btn <host-address> -e <terminal-emulation-command> I've added "-e" flag. If present, the remainder of the command line is executed by "system()"-call. If not present, it just spawns the COMMAND.COM. (Watch out for weird effects because of 'exit_hook'-feature-- using "-e"-style recommended...:-). Notice, that the catching is "hardcoded" for DX=1 (PRN:) at "int14_channel" (telnet.c). Easy to change to anything you want. I'm not a regular UNIX-user. I post the files as a text and not in shar-format. Hopefully nothing gets garbled. -- -- Markku Savela, UUCP: msa@clinet.fi -- Nokia Information Systems (or Nokia Data Systems?) -- P.O.BOX 780 SF-00101 HELSINKI, FINLAND -- -*cut here*------------ \pc-ip\srclib\int14\makefile ----------------- int14tn.obj: int14tn.asm masm /ml int14tn; lib ..\..\lib\int144n-+int14tn; -*cut here*------------ \pc-ip\srclib\int14\int14tn ----------------- ; INT14 Interrupt Catcher ; TITLE int14tn INCLUDE ..\..\include\dos.mac PUBLIC _int14_enter ; Replace INT14 vector (initialize) PUBLIC _int14_exit ; Restore Original INT14 (terminate) _TEXT SEGMENT EXTRN _int14_write:NEAR ; Send one character to telnet EXTRN _int14_yield:NEAR ; Relinquish control for a while EXTRN _int14_fetch:NEAR ; Get Data from net buffer _TEXT ENDS _DATA SEGMENT EXTRN _int14_channel:WORD ; Channel to Intercept EXTRN _int14_count:WORD ; Number of chars in buffer EXTRN _int14_tcpfull:WORD ; =1, if tcpfull status! _DATA ENDS INT14H = 14H ; Interrupt Vector Number DOS_SET_INT14 = 2514H ; Set Interrupt Vector 14h ; ; Function codes ; INT14_Init = 0 ; Initialize Communications port INT14_Send = 1 ; Send one character (in AL) to line INT14_Read = 2 ; Read one character (into AL) from line INT14_Status = 3 ; Return Port Status ; MODEM_Status = 030H ; Clear to send & Data set Ready LINE_DataReady = 001H ; Receive Data Available LINE_SendReady = 060H ; Transmit Holding & Shift Register empty LINE_Timeout = 080H ; Timeout. _TEXT SEGMENT mychannel dw 1 ; Channel to Catch oldint14 dd ? ; Original INT14 handler (address) intstack dd ? ; Bottom Address of an Internal stack extstack dd ? ; Saved External Stack Pointer newint14: cmp dx,word ptr cs:[mychannel] ; Is this for me? jz intercept ; --> YES! ; Don't touch this -- use old interrupt service jmp cs:[oldint14] intercept: push ds ; save registers (except AX) push es push si push di push bp push bx push cx push dx sti mov cx,SEG DGROUP ; Fix Datasegments ! mov ds,cx mov es,cx cmp ah,INT14_Status ; Inquire Status? jz linestatus cmp ah,INT14_Send ; Send Character? jz sendchar cmp ah,INT14_Read ; Read Character? jz readchar cmp ah,INT14_Init ; Initialize? jz noyield mov ax,0 ; Unknown, return ZERO! int14end: pop dx pop cx pop bx pop bp pop di pop si pop es pop ds iret linestatus: cmp _int14_count,0 ; Is there anything in buffer? jnz noyield ; Yes, don't release control mov di,offset _int14_yield call switch noyield: ; Set "Send Enabled", if not tcpfull mov ah,0 cmp _int14_tcpfull,0 jnz nosend mov ah,LINE_SendReady ; Set "Data Ready", if buffer non-empty nosend: cmp _int14_count,0 jz noread add ah,LINE_DataReady noread: mov al,MODEM_Status jmp int14end readchar: cmp _int14_count,0 jnz fetchdata mov ax, 0100H jmp int14end fetchdata: mov di,offset _int14_fetch call switch jmp int14end sendchar: mov di,offset _int14_write call switch jmp int14end ; ; Switch from external stack to internal stack and execute one ; c-function (address in 'di'). Pass one parameter from 'ax'. ; switch PROC NEAR cli mov word ptr cs:[extstack+0],sp mov word ptr cs:[extstack+2],ss mov sp,word ptr cs:[intstack+0] mov ss,word ptr cs:[intstack+2] sti ; Call C-function with internal stack cld push bp mov bp,sp push ax call di ; Restore original stack cli mov sp,word ptr cs:[extstack+0] mov ss,word ptr cs:[extstack+2] sti ret switch ENDP ; ; int14_enter(internal_stack_base) ; ; This is called to initialize the INT14 catcher. Whenever ; the normal PC-IP is called, the internal stack given here ; is used (within PC-IP calls from INT14 are executed under ; the process that spawned the command interpereter) ; _int14_enter PROC NEAR push bp mov bp,sp push si push di push es mov ax, _int14_channel mov word ptr cs:[mychannel],ax mov ax,[bp+4] mov word ptr cs:[intstack+0],ax ; Store Internal Stack Pointer. mov word ptr cs:[intstack+2],ss ; push ds sub ax, ax mov ds, ax les bx, dword ptr ds:[INT14H * 4] pop ds mov word ptr cs:[oldint14], bx mov word ptr cs:[oldint14+2], es push ds push cs pop ds mov dx, offset newint14 mov ax, DOS_SET_INT14 int 21h pop ds pop es pop di pop si mov sp,bp pop bp ret _int14_enter ENDP _int14_exit PROC NEAR push bp push si push di push es push ds mov dx,word ptr cs:[oldint14] mov ax,word ptr cs:[oldint14+2] mov ds,ax mov ax, DOS_SET_INT14 int 21h pop ds pop es pop di pop si pop bp ret _int14_exit ENDP _TEXT ENDS END