Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2010-2015. 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. BUFFERSIZE      = 4096
  18.  
  19. use32
  20. ; standard header
  21.         db      'MENUET01'      ; signature
  22.         dd      1               ; header version
  23.         dd      start           ; entry point
  24.         dd      i_end           ; initialized size
  25.         dd      mem+4096        ; required memory
  26.         dd      mem+4096        ; stack pointer
  27.         dd      hostname        ; parameters
  28.         dd      0               ; path
  29.  
  30. include '../../macros.inc'
  31. purge mov,add,sub
  32. include '../../proc32.inc'
  33. include '../../dll.inc'
  34. include '../../network.inc'
  35.  
  36. ; entry point
  37. start:
  38. ; load libraries
  39.         stdcall dll.Load, @IMPORT
  40.         test    eax, eax
  41.         jnz     exit
  42. ; initialize console
  43.         invoke  con_start, 1
  44.         invoke  con_init, 80, 25, 80, 25, title
  45.  
  46. ; Check for parameters
  47.         cmp     byte[hostname], 0
  48.         jne     resolve
  49.  
  50. main:
  51.         invoke  con_cls
  52. ; Welcome user
  53.         invoke  con_write_asciiz, str1
  54.  
  55. prompt:
  56. ; write prompt
  57.         invoke  con_write_asciiz, str2
  58. ; read string (wait for input)
  59.         mov     esi, hostname
  60.         invoke  con_gets, esi, 256
  61. ; check for exit
  62.         test    eax, eax
  63.         jz      done
  64.         cmp     byte[esi], 10
  65.         jz      done
  66.  
  67. resolve:
  68.         mov     [sockaddr1.port], 23 shl 8      ; Port is in network byte order
  69.  
  70. ; delete terminating newline from URL and parse port, if any.
  71.         mov     esi, hostname
  72.   @@:
  73.         lodsb
  74.         cmp     al, ':'
  75.         je      .do_port
  76.         cmp     al, 0x20
  77.         ja      @r
  78.         mov     byte[esi-1], 0
  79.         jmp     .done
  80.  
  81.   .do_port:
  82.         xor     eax, eax
  83.         xor     ebx, ebx
  84.         mov     byte[esi-1], 0
  85.   .portloop:
  86.         lodsb
  87.         cmp     al, ' '
  88.         jbe     .port_done
  89.         sub     al, '0'
  90.         jb      hostname_error
  91.         cmp     al, 9
  92.         ja      hostname_error
  93.         lea     ebx, [ebx*4+ebx]
  94.         shl     ebx, 1
  95.         add     ebx, eax
  96.         jmp     .portloop
  97.  
  98.   .port_done:
  99.         xchg    bl, bh
  100.         mov     [sockaddr1.port], bx
  101.  
  102.   .done:
  103.  
  104. ; resolve name
  105.         push    esp     ; reserve stack place
  106.         invoke  getaddrinfo, hostname, 0, 0, esp
  107.         pop     esi
  108. ; test for error
  109.         test    eax, eax
  110.         jnz     dns_error
  111.  
  112.         invoke  con_cls
  113.         invoke  con_write_asciiz, str3
  114.         invoke  con_write_asciiz, hostname
  115.  
  116. ; write results
  117.         invoke  con_write_asciiz, str8
  118.  
  119. ; convert IP address to decimal notation
  120.         mov     eax, [esi+addrinfo.ai_addr]
  121.         mov     eax, [eax+sockaddr_in.sin_addr]
  122.         mov     [sockaddr1.ip], eax
  123.         invoke  inet_ntoa, eax
  124. ; write result
  125.         invoke  con_write_asciiz, eax
  126. ; free allocated memory
  127.         invoke  freeaddrinfo, esi
  128.  
  129.         invoke  con_write_asciiz, str9
  130.  
  131.         mcall   socket, AF_INET4, SOCK_STREAM, 0
  132.         cmp     eax, -1
  133.         jz      socket_err
  134.         mov     [socketnum], eax
  135.  
  136.         mcall   connect, [socketnum], sockaddr1, 18
  137.         test    eax, eax
  138.         jnz     socket_err
  139.  
  140.         mcall   40, EVM_STACK
  141.         invoke  con_cls
  142.  
  143.         mcall   18, 7
  144.         push    eax
  145.         mcall   51, 1, thread, mem - 2048
  146.         pop     ecx
  147.         mcall   18, 3
  148.  
  149. mainloop:
  150.         invoke  con_get_flags
  151.         test    eax, 0x200                      ; con window closed?
  152.         jnz     exit
  153.  
  154.         mcall   recv, [socketnum], buffer_ptr, BUFFERSIZE, 0
  155.         cmp     eax, -1
  156.         je      closed
  157.  
  158.         mov     esi, buffer_ptr
  159.         lea     edi, [esi+eax]
  160.         mov     byte[edi], 0
  161.   .scan_cmd:
  162.         cmp     byte[esi], 0xff         ; Interpret As Command
  163.         jne     .no_cmd
  164. ; TODO: parse options
  165. ; for now, we will reply with 'WONT' to everything
  166.         mov     byte[esi+1], 252        ; WONT
  167.         add     esi, 3                  ; a command is always 3 bytes
  168.         jmp     .scan_cmd
  169.   .no_cmd:
  170.  
  171.         cmp     esi, buffer_ptr
  172.         je      .print
  173.  
  174.         push    esi edi
  175.         sub     esi, buffer_ptr
  176.         mcall   send, [socketnum], buffer_ptr, , 0
  177.         pop     edi esi
  178.  
  179.   .print:
  180.         cmp     esi, edi
  181.         jae     mainloop
  182.  
  183.         invoke  con_write_asciiz, esi
  184.  
  185.   .loop:
  186.         lodsb
  187.         test    al, al
  188.         jz      .print
  189.         jmp     .loop
  190.  
  191.  
  192. socket_err:
  193.         invoke  con_write_asciiz, str6
  194.         jmp     prompt
  195.  
  196. dns_error:
  197.         invoke  con_write_asciiz, str5
  198.         jmp     prompt
  199.  
  200. hostname_error:
  201.         invoke  con_write_asciiz, str11
  202.         jmp     prompt
  203.  
  204. closed:
  205.         invoke  con_write_asciiz, str12
  206.         jmp     prompt
  207.  
  208. done:
  209.         invoke  con_exit, 1
  210. exit:
  211.  
  212.         mcall   close, [socketnum]
  213.         mcall   -1
  214.  
  215.  
  216.  
  217. thread:
  218.         mcall   40, 0
  219.   .loop:
  220.         invoke  con_getch2
  221.         mov     [send_data], ax
  222.         xor     esi, esi
  223.         inc     esi
  224.         test    al, al
  225.         jnz     @f
  226.         inc     esi
  227.   @@:
  228.         mcall   send, [socketnum], send_data
  229.  
  230.         invoke  con_get_flags
  231.         test    eax, 0x200                      ; con window closed?
  232.         jz      .loop
  233.         mcall   -1
  234.  
  235. ; data
  236. title   db      'Telnet',0
  237. str1    db      'Telnet for KolibriOS',10,10,\
  238.                 'Please enter URL of telnet server (host:port)',10,10,\
  239.                 'fun stuff:',10,\
  240.                 'telehack.com            - arpanet simulator',10,\
  241.                 'towel.blinkenlights.nl  - ASCII Star Wars',10,\
  242.                 'nyancat.dakko.us        - Nyan cat',10,10,0
  243. str2    db      '> ',0
  244. str3    db      'Connecting to ',0
  245. str4    db      10,0
  246. str8    db      ' (',0
  247. str9    db      ')',10,0
  248.  
  249. str5    db      'Name resolution failed.',10,10,0
  250. str6    db      'Could not open socket.',10,10,0
  251. str11   db      'Invalid hostname.',10,10,0
  252. str12   db      10,'Remote host closed the connection.',10,10,0
  253.  
  254. sockaddr1:
  255.         dw AF_INET4
  256. .port   dw 0
  257. .ip     dd 0
  258.         rb 10
  259.  
  260. align 4
  261. @IMPORT:
  262.  
  263. library network, 'network.obj', console, 'console.obj'
  264. import  network,        \
  265.         getaddrinfo,    'getaddrinfo',  \
  266.         freeaddrinfo,   'freeaddrinfo', \
  267.         inet_ntoa,      'inet_ntoa'
  268. import  console,        \
  269.         con_start,      'START',        \
  270.         con_init,       'con_init',     \
  271.         con_write_asciiz,       'con_write_asciiz',     \
  272.         con_exit,       'con_exit',     \
  273.         con_gets,       'con_gets',\
  274.         con_cls,        'con_cls',\
  275.         con_getch2,     'con_getch2',\
  276.         con_set_cursor_pos, 'con_set_cursor_pos',\
  277.         con_write_string, 'con_write_string',\
  278.         con_get_flags,  'con_get_flags'
  279.  
  280.  
  281. i_end:
  282.  
  283. socketnum       dd ?
  284. buffer_ptr      rb BUFFERSIZE+1
  285. send_data       dw ?
  286.  
  287. hostname        rb 1024
  288.  
  289. mem:
  290.