?login_element?

Subversion Repositories NedoOS

Rev

Rev 875 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.         DEVICE ZXSPECTRUM128
  2.         include "../_sdk/sys_h.asm"
  3.  
  4. STDINBUF_SZ=256
  5. NETINBUF_SZ=256
  6.  
  7. STACK=0x4000
  8.  
  9. PORT=2323
  10.  
  11. SHUT_RDWR               EQU 2
  12. ERR_EAGAIN              EQU 35          ;/* Try again */
  13. ERR_EWOULDBLOCK EQU ERR_EAGAIN  ;/* Operation would block */
  14. ERR_INTR                EQU 4
  15. ERR_NFILE               EQU 23
  16. ERR_ALREADY     EQU 37
  17. ERR_NOTSOCK     EQU 38
  18. ERR_EMSGSIZE    EQU 40    ;/* Message too long */
  19. ERR_PROTOTYPE   EQU 41
  20. ERR_AFNOSUPPORT EQU 47
  21. ERR_HOSTUNREACH EQU 65
  22. ERR_ECONNABORTED EQU    53      ;/* Software caused connection abort */
  23. ERR_CONNRESET   EQU 54
  24. ERR_NOTCONN     EQU 57
  25.  
  26. ;************************* Протоколы соединений *************************
  27. SOCK_STREAM EQU 0x01            ;tcp/ip
  28. SOCK_ICMP       EQU 0x02                ;icmp
  29. SOCK_DGRAM      EQU 0x03                ;udp/ip
  30.  
  31. AF_INET EQU 2
  32.  
  33.         org PROGSTART
  34. begin
  35.         ld sp,STACK
  36.         OS_HIDEFROMPARENT
  37.         ;ld e,6 ;textmode
  38.         ;OS_SETGFX
  39.         OS_GETMAINPAGES ;dehl
  40.         push de
  41.         push hl
  42.         ld e,l
  43.         OS_DELPAGE
  44.         pop hl
  45.         ld e,h
  46.         OS_DELPAGE
  47.         pop de
  48.         OS_DELPAGE
  49.  
  50.         ld de,tpipename
  51.         push de
  52.         OS_OPENHANDLE
  53.         ld a,b
  54.         ld (stdinhandle),a
  55.         pop de
  56.         OS_OPENHANDLE
  57.         ld a,b
  58.         ld (stdouthandle),a
  59.  
  60.         OS_GETMAINPAGES ;out: d,e,h,l=pages in 0000,4000,8000,c000, c=flags, b=id
  61.         ld a,(stdinhandle)
  62.         ld e,a
  63.         ld a,(stdouthandle)
  64.         ld d,a
  65.         ld h,0xff ;rnd
  66. ;b=id, e=stdin, d=stdout, h=stderr        
  67.         OS_SETSTDINOUT
  68.  
  69. ;TODO запускать файл, указанный в параметре (по умолчанию cmd, искать в bin)
  70. ;TODO здесь не надо запускать CMD, запускать надо после коннекта клиента
  71.                 ld a,(waitpid_id)
  72.                 inc a
  73.                 jr z,nul_id
  74.                 ;TODO тут надо закрыть cmd
  75. nul_id
  76.         ld de,cmd_filename
  77.         OS_OPENHANDLE
  78.         or a
  79.         jr nz,execcmd_error
  80.        
  81.         call readapp ;делает CLOSE
  82.        
  83.         push af
  84.         ld b,a
  85.         ld a,(stdinhandle)
  86.         ld d,a
  87.         ld a,(stdouthandle)
  88.         ld e,a
  89.         ld h,0xff ;rnd
  90. ;b=id, e=stdin, d=stdout, h=stderr        
  91.         OS_SETSTDINOUT
  92.        
  93.         pop af ;id
  94.  
  95.         ld e,a ;id
  96.         ld (waitpid_id),a
  97.         OS_RUNAPP
  98.  
  99. execcmd_error
  100.         display $
  101. gotostart
  102.         ld sp,STACK
  103.         ld a,(soc)
  104.         or a
  105.         jr z,nul_soc
  106.         ld e,0
  107.         OS_NETSHUTDOWN
  108.         xor a
  109.         ld (soc),a
  110. nul_soc
  111.         ld a,(soc_client)
  112.         or a
  113.         jr z,nul_soc_client
  114.         ld e,0
  115.         OS_NETSHUTDOWN
  116.         xor a
  117.         ld (soc_client),a
  118. nul_soc_client
  119. ;1. s = OS_NETSOCKET
  120.         LD D,AF_INET
  121.         LD E,SOCK_STREAM
  122.         OS_NETSOCKET
  123.         BIT 7,L
  124.         JP NZ,inet_exiterr      ;обработка ошибки
  125.         LD A,L
  126.         ld (soc),a
  127. ;2. OS_BIND(s)
  128.         ld a,(soc)
  129.         LD DE,destination_host
  130.         OS_BIND
  131.         BIT 7,L
  132.         JP NZ,inet_exiterr
  133. ;3. OS_LISTEN(s)
  134.         ld a,(soc)
  135.         OS_LISTEN
  136.         bit 7,l
  137.         JP NZ,inet_exiterr
  138. ;4. s1 = OS_ACCEPT(s)
  139. ;5. если s1<0 гото 4
  140. WAIT_CLIENTS
  141.         LD A,(soc)
  142.         OS_ACCEPT
  143.         BIT 7,L
  144.         JR Z,ESTABLISHED
  145.         CP ERR_EAGAIN
  146.         JP NZ,inet_exiterr      ;обработка ошибки
  147.         YIELD   ;не обязательно. Если время реагирования на подключение не критично,
  148.                                 ;то отдадим квант времени системе.
  149.         JR WAIT_CLIENTS ;никто не подключился, ждём
  150. ESTABLISHED
  151.         LD A,L                          ;удачно
  152.         LD (soc_client),A       ;сохраняем дескриптор сокета.
  153. ;6. OS_NETSHUTDOWN(s)
  154. ;close_wait:
  155.         LD A,(soc)
  156.         LD E,0 ;0 - закрыть немедленно, 1 - закрыть только если буфер отправки пуст
  157.         OS_NETSHUTDOWN
  158.         xor a
  159.         ld (soc),a
  160.         ;BIT 7,L
  161.         ;jp z,close_ok       ;сокет закрылся
  162.         ;CP ERR_EAGAIN
  163.         ;JP NZ,inet_exiterr             ;обработка ошибки не связанной с ожиданием отправки.
  164.         ;YIELD          ;не обязательно. Если время не критично,
  165.                                         ;то отдадим квант времени системе.
  166.         ;JR close_wait ;ожидаем отправки данных
  167. close_ok
  168.         ;TODO тут надо запустить CMD
  169. ;7. если надо то OS_WIZNETWRITE(s1)
  170. ;8. hl = OS_WIZNETREAD(s1)          
  171. ;9. if hl > 0 then обработаем и goto 7
  172. ;10. if A == ERR_EAGAIN goto 7
  173. ;11. OS_NETSHUTDOWN(s1)
  174. ;12. goto 1
  175.  
  176. mainloop
  177.         YIELD
  178.         call checkquit
  179.        
  180.         call send_stdin ;stdin to internet client
  181.        
  182. mainloop_afterkey
  183.         call readsocket_key ;GET_KEY
  184.         or a ;cp NOKEY ;keylang==0?
  185.         ;jr nz,$+3
  186.         ;cp c ;keynolang==0?
  187.         jr z,mainloop
  188.        
  189.          ;push af
  190.          ;call prhex ;debug
  191.          ;pop af
  192.        
  193.          cp 240 ;telnet codes
  194.          jr nc,parsetelnetcodes
  195. will_do_flag=$
  196.         or a
  197.         jr c,will_do_off ;skip one byte
  198. subnegotiation_flag=$
  199.         or a
  200.         jr c,mainloop_afterkey
  201.         call sendchar
  202.         jr mainloop_afterkey
  203.  
  204. parsetelnetcodes
  205.          ;cp 240
  206.          jr z,subnegotiation_off
  207.          cp 250
  208.          jr z,subnegotiation_on
  209.          cp 251 ;do
  210.          jr z,will_do_on ;skip next byte
  211.          cp 253 ;will
  212.          jr z,will_do_on ;skip next byte
  213.          jr mainloop
  214.        
  215. will_do_off
  216. ;will_do_off_once_flag=$+1
  217. ;        ld a,2
  218. ;        dec a
  219. ;        jp z,will_do_off_once_skip
  220. ;        ld (will_do_off_once_flag),a
  221.         if 1==0
  222.         ld a,255
  223.         call term_prfsm_prchar
  224.         ld a,253 ;will
  225.         call term_prfsm_prchar
  226.         ld a,34 ;??? не воспринимается putty, пишет символ 34
  227.         call term_prfsm_prchar
  228.         endif
  229.        
  230.         ;ld a,255
  231.         ;call term_prfsm_prchar
  232.         ;ld a,251 ;do
  233.         ;call term_prfsm_prchar
  234.         ;ld a,0x2d ;??? не воспринимается putty, пишет символ 2d
  235.         ;call term_prfsm_prchar ;disable local echo
  236.        
  237.         if 1==0
  238.         ld a,255
  239.         call term_prfsm_prchar
  240.         ;ld a,254 ;don't
  241.         ld a,251 ;do
  242.         call term_prfsm_prchar
  243.         ld a,1 ;echo
  244.         call term_prfsm_prchar ;если делать IAC IAC_DO IAC_Echo, то клиент посылает кнопки только по ентеру, но процесс редактирования не отображает
  245.         endif
  246.  
  247.         if 1==0
  248.         ld a,255
  249.         call term_prfsm_prchar
  250.         ld a,254 ;don't
  251.         ;ld a,251 ;do
  252.         call term_prfsm_prchar
  253.         ld a,7 ;Remote Controlled Trans and Echo
  254.         call term_prfsm_prchar ;ни на что не влияет
  255.         endif
  256.        
  257.         if 1==0
  258.         ld a,255
  259.         call term_prfsm_prchar
  260.         ld a,250 ;Начало субопции
  261.         call term_prfsm_prchar
  262.         ld a,34
  263.         call term_prfsm_prchar
  264.         ld a,1
  265.         call term_prfsm_prchar
  266.         ld a,1;0
  267.         call term_prfsm_prchar
  268.         ld a,255
  269.         call term_prfsm_prchar
  270.         ld a,240 ;Завершение согласования параметров (конец субопции)
  271.         call term_prfsm_prchar ;disable local line editing
  272.         endif
  273.  
  274.         ld a,255
  275.         call term_prfsm_prchar
  276.         ld a,251
  277.         call term_prfsm_prchar
  278.         ld a,1
  279.         call term_prfsm_prchar
  280.  
  281.         ld a,255
  282.         call term_prfsm_prchar
  283.         ld a,251
  284.         call term_prfsm_prchar
  285.         ld a,3
  286.         call term_prfsm_prchar
  287. will_do_off_once_skip
  288.         ld a,55+128 ;or a
  289.         jr will_do_onoff
  290. will_do_on
  291.         ld a,55 ;scf
  292. will_do_onoff
  293.         ld (will_do_flag),a
  294.         jp mainloop_afterkey
  295.  
  296. subnegotiation_off      
  297.         ld a,55+128 ;or a
  298.         jr subnegotiation_onoff
  299. subnegotiation_on
  300.         ld a,55 ;scf
  301. subnegotiation_onoff
  302.         ld (subnegotiation_flag),a
  303.         jp mainloop_afterkey
  304.  
  305.  
  306. checkquit
  307. waitpid_id=$+1
  308.         ld e,0xff
  309.         OS_CHECKPID
  310.         or a
  311.         ret nz ;jp z,quit
  312. ;dead
  313.         ;ret
  314.                 dec a
  315.                 ld (waitpid_id),a
  316. quit
  317. ;cmd closed!!!
  318.         LD A,(soc_client)
  319.         LD E,0 ;0 - закрыть немедленно, 1 - закрыть только если буфер отправки пуст
  320.         OS_NETSHUTDOWN
  321.  
  322.         dup 2 ;close twice - as stdin and as stdout! на случай, если клиент не закрыл у себя
  323.         ld a,(stdinhandle)
  324.         ld b,a
  325.         OS_CLOSEHANDLE
  326.         ld a,(stdouthandle)
  327.         ld b,a
  328.         OS_CLOSEHANDLE
  329.         edup
  330. inet_exiterr
  331.         jp gotostart
  332.  
  333.         QUIT
  334.  
  335.         if 1==0
  336. prhex
  337.         push af
  338.         ld a,'#'
  339.         PRCHAR
  340.         pop af
  341.         call prhexdigit
  342. prhexdigit
  343.         rrca
  344.         rrca
  345.         rrca
  346.         rrca
  347.         push af
  348.         or 0xf0
  349.         daa
  350.         add a,0xa0
  351.         adc a,0x40
  352.         PRCHAR
  353.         pop af
  354.         ret
  355.         endif
  356.  
  357. readsocket_key
  358. datain_size=$+1
  359.         ld hl,0
  360.         ld a,h
  361.         or l
  362.         jr z,WAIT_DATA
  363. datain_addr=$+1
  364.         ld hl,netinbuf
  365.         ld a,(hl)
  366.         inc hl
  367.         ld (datain_addr),hl
  368.         ld hl,(datain_size)
  369.         dec hl
  370.         ld (datain_size),hl
  371.         ret
  372. WAIT_DATA
  373. ;out:hl=datain_size
  374.         ld hl,netinbuf
  375.         ld (datain_addr),hl
  376. wait_data0
  377.         LD A,(soc_client)
  378.         LD DE,netinbuf
  379.         LD HL,NETINBUF_SZ
  380.         OS_WIZNETREAD
  381.         BIT 7,H
  382.         JR Z,RECEIVED   ;ошибок нет
  383.         CP ERR_EAGAIN
  384.         JP NZ,inet_exiterr      ;обработка ошибки
  385.         YIELD           ;не обязательно. Если время реагирования на пришедшие данные не критично,
  386.                                                 ;то отдадим квант времени системе.
  387.         call checkquit
  388.         call send_stdin
  389.         JR wait_data0   ;данных нет, ждём
  390. RECEIVED
  391.         ld (datain_size),HL     ;удачно. если требуется, то сохраняем количество принятых данных.
  392.         ;push hl
  393.         ;call term_print
  394.         ;pop hl
  395.         jr readsocket_key
  396.  
  397. sendchar
  398. ;to stdout
  399.         ;cp 0x80
  400.         ;jr nc,sendchar_rustoutf8
  401.         ;cp 0x08 ;backspace
  402.         ;cp 0x0d ;enter
  403. ;        ld c,a
  404. ;sendchar_byte
  405. ;        ld a,c
  406. sendchar_byte_a
  407.         ld (stdoutbuf),a
  408. sendchar_repeat
  409.         ld hl,1
  410.         ld de,stdoutbuf
  411. stdouthandle=$+1
  412.         ld b,0
  413.         OS_WRITEHANDLE
  414.         ld a,h
  415.         or l
  416.         ret nz
  417.         YIELDKEEP
  418.         call checkquit
  419.         jr sendchar_repeat
  420.  
  421. send_stdin
  422. ;stdin to internet client
  423.         ld de,stdinbuf
  424.         ld hl,STDINBUF_SZ
  425. stdinhandle=$+1
  426.         ld b,0
  427.         ;ld b,0xff
  428.         OS_READHANDLE
  429. ;hl=size
  430.         ld a,h
  431.         or l
  432.         ret z;jr z,mainloop_afterkey
  433.         ld de,stdinbuf
  434.         jr term_prfsm_prchars
  435.         if 1==0
  436.         ld b,h
  437.         ld c,l
  438.         ld hl,stdinbuf
  439. term_print0
  440.         push bc
  441.         push hl
  442.         ld a,(hl)
  443.         call term_prfsm_prchar ;to internet client
  444.         pop hl
  445.         pop bc
  446.         cpi
  447.         jp pe,term_print0
  448.         ret
  449.         endif
  450.  
  451. term_prfsm_prchar
  452. ;to internet client
  453. ;a=char
  454.         ld (netoutbuf),a        
  455. ;send_data_addr=$+1
  456.         LD DE,netoutbuf
  457. ;send_data_size=$+1
  458.         LD HL,1
  459. term_prfsm_prchars
  460. send_data0
  461.         push de
  462.         push hl
  463.         LD A,(soc_client)
  464.         OS_WIZNETWRITE
  465.         BIT 7,H
  466.         pop hl
  467.         pop de
  468.         JR Z,send_ok    ;ошибок нет
  469.         CP ERR_EMSGSIZE
  470.         JP NZ,inet_exiterr      ;обработка ошибки
  471.         push de
  472.         push hl
  473.         YIELD           ;не обязательно. Если время не критично,
  474.                                                 ;то отдадим квант времени системе.
  475.         call checkquit
  476.         pop hl
  477.         pop de
  478.         JR send_data0   ;буфер отправки переполнен, ждём освобождения
  479. send_ok
  480.         ;LD (DATA_SIZE),HL      ;удачно. если требуется, то сохраняем количество отправленных данных.
  481.         ;ld bc,(send_data_size)
  482.         ;or a
  483.         ;sbc hl,bc        
  484.         ret
  485.  
  486. readapp
  487.         ld a,b
  488.         ld (curhandle),a
  489.        
  490.         OS_NEWAPP ;для первой создаваемой задачи будут созданы первые два пайпа и подключены
  491. ;dehl=номера страниц в 0000,4000,8000,c000 нового приложения, b=id, a=error
  492.         push bc ;b=id
  493.  
  494.         ld a,d
  495.         SETPG32KHIGH
  496.         push de
  497.         push hl
  498.         ld hl,COMMANDLINE ;command line
  499.         call skipword
  500.         call skipspaces ;пропустили первое слово (там было term.com, а дальше, например, cmd.com autoexec.bat)
  501.         ld de,0xc080
  502.         ld bc,128  
  503.         ldir ;command line
  504.         pop hl
  505.         pop de
  506.  
  507.         call readfile_pages_dehl
  508.  
  509.         ld a,(curhandle)
  510.         ld b,a
  511.         OS_CLOSEHANDLE
  512.  
  513.         pop af ;id
  514.         ret
  515.  
  516. readfile_pages_dehl
  517.         ld a,d
  518.         SETPG32KHIGH
  519.         ld a,0xc100/256
  520.         call cmd_loadpage
  521.         or a
  522.         ret nz
  523.        
  524.         ld a,e
  525.         SETPG32KHIGH
  526.         ld a,0xc000/256
  527.         call cmd_loadpage
  528.         or a
  529.         ret nz
  530.        
  531.         ld a,h
  532.         SETPG32KHIGH
  533.         ld a,0xc000/256
  534.         call cmd_loadpage
  535.         or a
  536.         ret nz
  537.        
  538.         ld a,l
  539.         SETPG32KHIGH
  540.         ld a,0xc000/256
  541.  
  542. cmd_loadpage
  543. ;out: a=error
  544. ;keeps hl,de
  545.         push de
  546.         push hl
  547.         ld d,a
  548.         xor a
  549.         ld l,a
  550.         ld e,a
  551.         sub d
  552.         ld h,a ;de=buffer, hl=size
  553. curhandle=$+1
  554.         ld b,0
  555.         OS_READHANDLE
  556.         pop hl
  557.         pop de
  558.         ret
  559.  
  560. skipword
  561. ;hl=string
  562. ;out: hl=terminator/space addr
  563. skipword0
  564.         ld a,(hl)
  565.         or a
  566.         ret z
  567.         sub ' '
  568.         ret z
  569.         inc hl
  570.         jp skipword0
  571.  
  572. skipspaces
  573. ;hl=string
  574. ;out: hl=after last space
  575.         ld a,(hl)
  576.         cp ' '
  577.         ret nz
  578.         inc hl
  579.         jr skipspaces
  580.  
  581. cmd_filename
  582.         db "cmd.com",0
  583.  
  584. tpipename
  585.         ;db "z:",0
  586.         db "z:/a25",0
  587.  
  588. stdoutbuf
  589.         db 0
  590.  
  591. netoutbuf
  592.         db 0
  593.  
  594. stdinbuf
  595.         ds STDINBUF_SZ
  596.  
  597. netinbuf
  598.         ds NETINBUF_SZ
  599.  
  600. soc
  601.         db 0
  602. soc_client
  603.         db 0
  604.  
  605. ;struct sockaddr_in {unsigned char sin_family;unsigned short sin_port;
  606. ;       struct in_addr sin_addr;char sin_zero[8];};
  607. destination_host               
  608.         DEFB AF_INET
  609.         DEFB PORT/256,PORT&0xff ;port (big endian)
  610.         DEFB 0,0,0,0                    ;исходящий IP адрес (не используется в текущей реализации)
  611.         DEFB 0,0,0,0,0,0,0,0    ;резерв
  612.        
  613. end
  614.         savebin "netterm.com",begin,end-begin
  615.        
  616.         LABELSLIST "..\..\us\user.l"
  617.