Subversion Repositories Kolibri OS

Rev

Rev 3574 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2010-2012. All rights reserved.    ;;
  4. ;; Distributed under terms of the GNU General Public License       ;;
  5. ;;                                                                 ;;
  6. ;;  telnet.asm - Telnet client for KolibriOS                       ;;
  7. ;;                                                                 ;;
  8. ;;  Written by hidnplayr@kolibrios.org                             ;;
  9. ;;                                                                 ;;
  10. ;;          GNU GENERAL PUBLIC LICENSE                             ;;
  11. ;;             Version 2, June 1991                                ;;
  12. ;;                                                                 ;;
  13. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  14.  
  15. format binary as ""
  16.  
  17. __DEBUG__       equ 0
  18. __DEBUG_LEVEL__ equ 1
  19. BUFFERSIZE      equ 4096
  20.  
  21. use32
  22. ; standard header
  23.         db      'MENUET01'      ; signature
  24.         dd      1               ; header version
  25.         dd      start           ; entry point
  26.         dd      i_end           ; initialized size
  27.         dd      mem             ; required memory
  28.         dd      mem             ; stack pointer
  29.         dd      s               ; parameters
  30.         dd      0               ; path
  31.  
  32. include '../macros.inc'
  33. purge mov,add,sub
  34. include '../proc32.inc'
  35. include '../dll.inc'
  36. include '../debug-fdo.inc'
  37. include '../network.inc'
  38.  
  39. ; entry point
  40. start:
  41. ; load libraries
  42.         stdcall dll.Load, @IMPORT
  43.         test    eax, eax
  44.         jnz     exit
  45. ; initialize console
  46.         push    1
  47.         call    [con_start]
  48.         push    title
  49.         push    25
  50.         push    80
  51.         push    25
  52.         push    80
  53.         call    [con_init]
  54.  
  55. ; Check for parameters
  56.         cmp     byte [s], 0
  57.         jne     resolve
  58.  
  59. main:
  60.         call    [con_cls]
  61. ; Welcome user
  62.         push    str1
  63.         call    [con_write_asciiz]
  64.  
  65. ; write prompt
  66.         push    str2
  67.         call    [con_write_asciiz]
  68. ; read string
  69.         mov     esi, s
  70.         push    256
  71.         push    esi
  72.         call    [con_gets]
  73. ; check for exit
  74.         test    eax, eax
  75.         jz      done
  76.         cmp     byte [esi], 10
  77.         jz      done
  78.  
  79. resolve:
  80.  
  81. ; delete terminating '\n'
  82.         mov     esi, s
  83.   @@:
  84.         lodsb
  85.         cmp     al, 0x20
  86.         ja      @r
  87.         mov     byte [esi-1], 0
  88.  
  89.         call    [con_cls]
  90.         push    str3
  91.         call    [con_write_asciiz]
  92.         push    s
  93.         call    [con_write_asciiz]
  94.  
  95. ; resolve name
  96.         push    esp     ; reserve stack place
  97.         push    esp     ; fourth parameter
  98.         push    0       ; third parameter
  99.         push    0       ; second parameter
  100.         push    s       ; first parameter
  101.         call    [getaddrinfo]
  102.         pop     esi
  103. ; test for error
  104.         test    eax, eax
  105.         jnz     fail
  106.  
  107. ; write results
  108.         push    str8
  109.         call    [con_write_asciiz]
  110. ;        mov     edi, esi
  111.  
  112. ; convert IP address to decimal notation
  113.         mov     eax, [esi+addrinfo.ai_addr]
  114.         mov     eax, [eax+sockaddr_in.sin_addr]
  115.         mov     [sockaddr1.ip], eax
  116.         push    eax
  117.         call    [inet_ntoa]
  118. ; write result
  119.         push    eax
  120.         call    [con_write_asciiz]
  121. ; free allocated memory
  122.         push    esi
  123.         call    [freeaddrinfo]
  124.  
  125.         push    str9
  126.         call    [con_write_asciiz]
  127.  
  128.         mcall   socket, AF_INET4, SOCK_STREAM, 0
  129.         cmp     eax, -1
  130.         jz      fail2
  131.         mov     [socketnum], eax
  132.  
  133.         mcall   connect, [socketnum], sockaddr1, 18
  134.  
  135.         mcall   40, 1 shl 7 ; + 7
  136.         call    [con_cls]
  137.  
  138.         mcall   18, 7
  139.         push    eax
  140.         mcall   51, 1, thread, mem - 2048
  141.         pop     ecx
  142.         mcall   18, 3
  143.  
  144. mainloop:
  145.     DEBUGF  1, 'TELNET: Waiting for events\n'
  146.         mcall   10
  147.     DEBUGF  1, 'TELNET: EVENT %x !\n', eax
  148.  
  149.         call    [con_get_flags]
  150.         test    eax, 0x200                      ; con window closed?
  151.         jnz     exit
  152.  
  153.         mcall   recv, [socketnum], buffer_ptr, BUFFERSIZE, 0
  154.         cmp     eax, -1
  155.         je      mainloop
  156.  
  157.     DEBUGF  1, 'TELNET: got %u bytes of data !\n', eax
  158.  
  159.         mov     esi, buffer_ptr
  160.         lea     edi, [esi + eax]
  161.         mov     byte [edi], 0
  162.  
  163.   .scan_cmd:
  164.         cmp     byte [esi], 0xff        ; Interpret As Command
  165.         jne     .no_cmd
  166.         ; TODO: parse options, for now, we will reply with 'WONT' to everything
  167.         mov     byte [esi + 1], 252     ; WONT
  168.         add     esi, 3                  ; a command is always 3 bytes
  169.         jmp     .scan_cmd
  170.   .no_cmd:
  171.  
  172.         cmp     esi, buffer_ptr
  173.         je      .print_loop
  174.  
  175.     DEBUGF  1, 'TELNET: sending data\n'
  176.  
  177.         push    esi edi
  178.         sub     esi, buffer_ptr
  179.         mcall   send, [socketnum], buffer_ptr, , 0
  180.         pop     edi esi
  181.  
  182.   .print_loop:
  183.     DEBUGF  1, 'TELNET: printloop\n'
  184.         cmp     esi, edi
  185.         jae     mainloop
  186.  
  187.         cmp     byte [esi], 0x1b        ; escape character
  188.         jne     .print_byte
  189.         inc     esi
  190.  
  191.         cmp     word [esi], 0x485b      ; move cursor to beginning
  192.         jne     @f
  193.         inc     esi
  194.         inc     esi
  195.  
  196.     DEBUGF  1, 'TELNET: resetting cursor \n'
  197.  
  198.         push    0
  199.         push    0
  200.         call    [con_set_cursor_pos]
  201.         jmp     .print_loop
  202.  
  203.   @@:
  204.         inc     esi
  205.         inc     esi
  206.         jmp     .print_loop
  207.  
  208.   .print_byte:
  209.         push    dword 1
  210.         push    esi                     ; next string to print
  211.         inc     esi
  212.         call    [con_write_string]
  213.         jmp     .print_loop
  214.  
  215.  
  216. fail2:
  217.         push    str6
  218.         call    [con_write_asciiz]
  219.  
  220.         jmp     fail.wait
  221.  
  222. fail:
  223.         push    str5
  224.         call    [con_write_asciiz]
  225.   .wait:
  226.         push    str10
  227.         call    [con_write_asciiz]
  228.         call    [con_getch2]
  229.         jmp     main
  230.  
  231. done:
  232.         push    1
  233.         call    [con_exit]
  234. exit:
  235.  
  236.         mcall   close, [socketnum]
  237.         mcall   -1
  238.  
  239.  
  240.  
  241. thread:
  242.         mcall   40, 0
  243.   .loop:
  244.         call    [con_getch2]
  245.         mov     byte [send_data], al
  246.         mcall   send, [socketnum], send_data, 1
  247.  
  248.         call    [con_get_flags]
  249.         test    eax, 0x200                      ; con window closed?
  250.         jz      .loop
  251.         mcall   -1
  252.  
  253. ; data
  254. title   db      'Telnet',0
  255. str1    db      'Telnet for KolibriOS v0.11',10,10,'Please enter URL of telnet server (for example: towel.blinkenlights.nl)',10,10,0
  256. str2    db      '> ',0
  257. str3    db      'Connecting to: ',0
  258. str4    db      10,0
  259. str5    db      10,'Name resolution failed.',10,0
  260. str6    db      10,'Could not open socket.',10,0
  261. str8    db      ' (',0
  262. str9    db      ')',10,0
  263. str10   db      'Push any key to continue.',0
  264.  
  265. sockaddr1:
  266.         dw AF_INET4
  267. .port   dw 0x1700       ; 23
  268. .ip     dd 0
  269.         rb 10
  270.  
  271. include_debug_strings    ; ALWAYS present in data section
  272.  
  273.  
  274.  
  275. ; import
  276. align 4
  277. @IMPORT:
  278.  
  279. library network, 'network.obj', console, 'console.obj'
  280. import  network,        \
  281.         getaddrinfo,    'getaddrinfo',  \
  282.         freeaddrinfo,   'freeaddrinfo', \
  283.         inet_ntoa,      'inet_ntoa'
  284. import  console,        \
  285.         con_start,      'START',        \
  286.         con_init,       'con_init',     \
  287.         con_write_asciiz,       'con_write_asciiz',     \
  288.         con_exit,       'con_exit',     \
  289.         con_gets,       'con_gets',\
  290.         con_cls,        'con_cls',\
  291.         con_getch2,     'con_getch2',\
  292.         con_set_cursor_pos, 'con_set_cursor_pos',\
  293.         con_write_string, 'con_write_string',\
  294.         con_get_flags,  'con_get_flags'
  295.  
  296.  
  297. i_end:
  298.  
  299. socketnum       dd ?
  300. buffer_ptr      rb BUFFERSIZE+1
  301. send_data       rb 100
  302.  
  303. s       rb      1024
  304.         rb      4096    ; stack
  305. mem:
  306.