Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2013. All rights reserved.         ;;
  4. ;; Distributed under terms of the GNU General Public License       ;;
  5. ;;                                                                 ;;
  6. ;;  ftpc.asm - FTP 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__               = 0
  18. __DEBUG_LEVEL__         = 1
  19. BUFFERSIZE              = 1024
  20.  
  21. STATUS_CONNECTING       = 0
  22. STATUS_CONNECTED        = 1
  23. STATUS_NEEDPASSWORD     = 1
  24. STATUS_LOGGED_IN        = 3
  25.  
  26. use32
  27. ; standard header
  28.         db      'MENUET01'      ; signature
  29.         dd      1               ; header version
  30.         dd      start           ; entry point
  31.         dd      i_end           ; initialized size
  32.         dd      mem+0x1000      ; required memory
  33.         dd      mem+0x1000      ; stack pointer
  34.         dd      s               ; parameters
  35.         dd      0               ; path
  36.  
  37. include '../macros.inc'
  38. purge mov,add,sub
  39. include '../proc32.inc'
  40. include '../dll.inc'
  41. include '../debug-fdo.inc'
  42. include '../network.inc'
  43.  
  44. include 'usercommands.inc'
  45. include 'servercommands.inc'
  46.  
  47. ; entry point
  48. start:
  49.  
  50.         DEBUGF  1, "hello"
  51. ; load libraries
  52.         stdcall dll.Load, @IMPORT
  53.         test    eax, eax
  54.         jnz     exit
  55. ; initialize console
  56.         push    1
  57.         call    [con_start]
  58.         push    title
  59.         push    25
  60.         push    80
  61.         push    25
  62.         push    80
  63.         call    [con_init]
  64.  
  65. ; Check for parameters
  66.         cmp     byte [s], 0
  67.         jne     resolve
  68.  
  69. main:
  70.         call    [con_cls]
  71. ; Welcome user
  72.         push    str1
  73.         call    [con_write_asciiz]
  74.  
  75. ; write prompt
  76.         push    str2
  77.         call    [con_write_asciiz]
  78. ; read string
  79.         mov     esi, s
  80.         push    256
  81.         push    esi
  82.         call    [con_gets]
  83. ; check for exit
  84.         test    eax, eax
  85.         jz      done
  86.         cmp     byte [esi], 10
  87.         jz      done
  88.  
  89. resolve:
  90.  
  91. ; delete terminating '\n'
  92.         mov     esi, s
  93.   @@:
  94.         lodsb
  95.         cmp     al, 0x20
  96.         ja      @r
  97.         mov     byte [esi-1], 0
  98.  
  99. ;        call    [con_cls]
  100.         push    str3
  101.         call    [con_write_asciiz]
  102.         push    s
  103.         call    [con_write_asciiz]
  104.  
  105. ; resolve name
  106.         push    esp     ; reserve stack place
  107.         push    esp     ; fourth parameter
  108.         push    0       ; third parameter
  109.         push    0       ; second parameter
  110.         push    s       ; first parameter
  111.         call    [getaddrinfo]
  112.         pop     esi
  113. ; test for error
  114.         test    eax, eax
  115.         jnz     fail
  116.  
  117. ; write results
  118.         push    str8
  119.         call    [con_write_asciiz]
  120. ;        mov     edi, esi
  121.  
  122. ; convert IP address to decimal notation
  123.         mov     eax, [esi+addrinfo.ai_addr]
  124.         mov     eax, [eax+sockaddr_in.sin_addr]
  125.         mov     [sockaddr1.ip], eax
  126.         push    eax
  127.         call    [inet_ntoa]
  128. ; write result
  129.         push    eax
  130.         call    [con_write_asciiz]
  131. ; free allocated memory
  132.         push    esi
  133.         call    [freeaddrinfo]
  134.  
  135.         push    str9
  136.         call    [con_write_asciiz]
  137.  
  138.         mcall   socket, AF_INET4, SOCK_STREAM, 0
  139.         cmp     eax, -1
  140.         jz      fail2
  141.         mov     [socketnum], eax
  142.  
  143.         mcall   connect, [socketnum], sockaddr1, 18
  144.  
  145.         mcall   40, 1 shl 7
  146.  
  147.         mov     [status], STATUS_CONNECTING
  148.         mov     [offset], buffer_ptr
  149.  
  150. wait_for_serverdata:
  151.         mcall   10
  152.  
  153.         call    [con_get_flags]
  154.         test    eax, 0x200                      ; con window closed?
  155.         jnz     exit
  156.  
  157. ; receive socket data
  158.         mcall   recv, [socketnum], [offset], BUFFERSIZE, 0
  159.         inc     eax
  160.         jz      wait_for_serverdata
  161.         dec     eax
  162.         jz      wait_for_serverdata
  163.  
  164. ; extract commands, copy them to "s" buffer
  165.         add     eax, buffer_ptr                 ; eax = end pointer
  166.         mov     esi, buffer_ptr                 ; esi = current pointer
  167.   .nextcommand:
  168.         mov     edi, s
  169.   .byteloop:
  170.         cmp     esi, eax
  171.         jae     wait_for_serverdata
  172.         lodsb
  173.         cmp     al, 10                          ; excellent, we might have a command
  174.         je      .got_command
  175.         cmp     al, 13                          ; just ignore this crap
  176.         je      .byteloop
  177.         stosb
  178.         jmp     .byteloop
  179.  
  180. ; we have a newline check if its a command
  181.   .got_command:
  182.         xor     al, al
  183.         stosb
  184. ;        push    esi eax
  185.  
  186. ; print it to the screen
  187.         pushd   s
  188.         call    [con_write_asciiz]
  189.         pushd   str4                            ; newline
  190.         call    [con_write_asciiz]
  191.  
  192. ;        cmp     byte[s+2], " "
  193. ;        jne     .not_command
  194.  
  195.         lea     ecx, [edi - s]
  196.         call    server_parser
  197.  
  198. ;  .not_command:
  199. ;        pop     eax esi
  200. ;        jmp     .nextcommand
  201.  
  202.  
  203.  
  204.  
  205. wait_for_usercommand:
  206.  
  207.         cmp     [status], STATUS_CONNECTED
  208.         je      .connected
  209.  
  210.         cmp     [status], STATUS_NEEDPASSWORD
  211.         je      .needpass
  212.  
  213.  
  214. ; write prompt
  215.         push    str2
  216.         call    [con_write_asciiz]
  217. ; read string
  218.         mov     esi, s
  219.         push    256
  220.         push    esi
  221.         call    [con_gets]
  222.  
  223.         call    [con_get_flags]
  224.         test    eax, 0x200                      ; con window closed?
  225.         jnz     exit
  226.  
  227.         cmp     dword[s], "list"
  228.         je      cmd_list
  229.  
  230.         cmp     dword[s], "help"
  231.         je      cmd_help
  232.  
  233.         push    str_unkown
  234.         call    [con_write_asciiz]
  235.  
  236.         jmp     wait_for_usercommand
  237.  
  238.  
  239.   .connected:
  240.  
  241.         push    str_user
  242.         call    [con_write_asciiz]
  243.  
  244.         mov     dword[s], "USER"
  245.         mov     byte[s+4], " "
  246.  
  247.         jmp     .send
  248.  
  249.  
  250.   .needpass:
  251.         push    str_pass
  252.         call    [con_write_asciiz]
  253.  
  254.         mov     dword[s], "PASS"
  255.         mov     byte[s+4], " "
  256.  
  257.   .send:
  258. ; read string
  259.         mov     esi, s+5
  260.         push    256
  261.         push    esi
  262.         call    [con_gets]
  263.  
  264.         mov     edi, s+5
  265.         mov     ecx, 256
  266.         xor     al, al
  267.         repne   scasb
  268.         lea     esi, [edi-s-1]
  269.         mcall   send, [socketnum], s
  270.  
  271.         jmp     wait_for_usercommand
  272.  
  273.  
  274.  
  275.  
  276.  
  277.  
  278. open_dataconnection:
  279.         cmp     [status], STATUS_LOGGED_IN
  280.         jne     .fail
  281.  
  282.         mov     dword[s], "PASV"
  283.         mov     byte[s+4], 10
  284.         mcall   send, [socketnum], s, 5
  285.  
  286.         ret
  287.  
  288.   .fail:
  289.         push    str6
  290.         call    [con_write_asciiz]
  291.  
  292.         ret
  293.  
  294.  
  295. fail2:
  296.         push    str6
  297.         call    [con_write_asciiz]
  298.  
  299.         jmp     fail.wait
  300.  
  301. fail:
  302.         push    str5
  303.         call    [con_write_asciiz]
  304.   .wait:
  305.         push    str10
  306.         call    [con_write_asciiz]
  307.         call    [con_getch2]
  308.         jmp     main
  309.  
  310. done:
  311.         push    1
  312.         call    [con_exit]
  313. exit:
  314.  
  315.         mcall   close, [socketnum]
  316.         mcall   -1
  317.  
  318.  
  319.  
  320. ; data
  321. title   db 'FTP client',0
  322. str1    db 'FTP client for KolibriOS v0.01',10,10,'Please enter ftp server address.',10,0
  323. str2    db '> ',0
  324. str3    db 'Connecting to ',0
  325. str4    db 10,0
  326. str5    db 10,'Name resolution failed.',10,0
  327. str6    db 10,'Socket error.',10,0
  328. str8    db ' (',0
  329. str9    db ')',10,0
  330. str10   db 'Push any key to continue.',0
  331. str_user db "username: ",0
  332. str_pass db "password: ",0
  333. str_unkown db "unkown command",10,0
  334. str_help db "available commands:",10,10
  335.          db "help       list",10,0
  336.  
  337. str_open db "opening data socket",10,0
  338.  
  339. sockaddr1:
  340.         dw AF_INET4
  341. .port   dw 0x1500       ; 21
  342. .ip     dd 0
  343.         rb 10
  344.  
  345. sockaddr2:
  346.         dw AF_INET4
  347. .port   dw 0
  348. .ip     dd 0
  349.         rb 10
  350.  
  351. include_debug_strings    ; ALWAYS present in data section
  352.  
  353.  
  354.  
  355. ; import
  356. align 4
  357. @IMPORT:
  358.  
  359. library network, 'network.obj', console, 'console.obj'
  360.  
  361. import  network,        \
  362.         getaddrinfo,    'getaddrinfo',  \
  363.         freeaddrinfo,   'freeaddrinfo', \
  364.         inet_ntoa,      'inet_ntoa'
  365.  
  366. import  console,        \
  367.         con_start,      'START',        \
  368.         con_init,       'con_init',     \
  369.         con_write_asciiz,'con_write_asciiz',     \
  370.         con_exit,       'con_exit',     \
  371.         con_gets,       'con_gets',\
  372.         con_cls,        'con_cls',\
  373.         con_getch2,     'con_getch2',\
  374.         con_set_cursor_pos, 'con_set_cursor_pos',\
  375.         con_write_string, 'con_write_string',\
  376.         con_get_flags,  'con_get_flags'
  377.  
  378.  
  379. i_end:
  380.  
  381. active_passive  db ?
  382. socketnum       dd ?
  383. datasocket      dd ?
  384. buffer_ptr      rb 2*BUFFERSIZE
  385. status          db ?
  386. offset          dd ?
  387.  
  388. s       rb      1024
  389.  
  390. mem:
  391.