Subversion Repositories Kolibri OS

Rev

Rev 3803 | Rev 3813 | Go to most recent revision | Blame | Compare with Previous | 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. BUFFERSIZE              = 4096
  18.  
  19. STATUS_CONNECTING       = 0
  20. STATUS_CONNECTED        = 1
  21. STATUS_NEEDPASSWORD     = 2
  22. STATUS_LOGGED_IN        = 3
  23.  
  24. OPERATION_LIST          = 0
  25. OPERATION_RETR          = 1
  26. OPERATION_STOR          = 2
  27.  
  28. use32
  29. ; standard header
  30.         db      'MENUET01'      ; signature
  31.         dd      1               ; header version
  32.         dd      start           ; entry point
  33.         dd      i_end           ; initialized size
  34.         dd      mem+0x1000      ; required memory
  35.         dd      mem+0x1000      ; stack pointer
  36.         dd      s               ; parameters
  37.         dd      0               ; path
  38.  
  39. include '../../macros.inc'
  40. purge mov,add,sub
  41. include '../../proc32.inc'
  42. include '../../dll.inc'
  43. include '../../network.inc'
  44.  
  45. include 'usercommands.inc'
  46. include 'servercommands.inc'
  47.  
  48. ; entry point
  49. start:
  50.  
  51.         mcall   40, 0
  52. ; load libraries
  53.         stdcall dll.Load, @IMPORT
  54.         test    eax, eax
  55.         jnz     exit
  56. ; initialize console
  57.         invoke  con_start, 1
  58.         invoke  con_init, 80, 25, 80, 250, title
  59.  
  60. ; Check for parameters
  61.         cmp     byte [s], 0
  62.         jne     resolve
  63.  
  64. main:
  65.         invoke  con_cls
  66. ; Welcome user
  67.         invoke  con_write_asciiz, str1
  68.  
  69. ; write prompt
  70.         invoke  con_set_flags, 0x0a
  71.         invoke  con_write_asciiz, str2
  72. ; read string
  73.         mov     esi, s
  74.         invoke  con_gets, esi, 256
  75.         invoke  con_write_asciiz, str4  ; newline
  76.         invoke  con_set_flags, 0x07
  77. ; check for exit
  78.         test    eax, eax
  79.         jz      done
  80.         cmp     byte [esi], 10
  81.         jz      done
  82.  
  83. resolve:
  84. ; delete terminating '\n'
  85.         mov     esi, s
  86.   @@:
  87.         lodsb
  88.         cmp     al, 0x20
  89.         ja      @r
  90.         mov     byte [esi-1], 0
  91.  
  92.         invoke  con_write_asciiz, str3
  93.         invoke  con_write_asciiz, s
  94.  
  95. ; resolve name
  96.         push    esp     ; reserve stack place
  97.         invoke  getaddrinfo, s, 0, 0, esp
  98.         pop     esi
  99. ; test for error
  100.         test    eax, eax
  101.         jnz     fail
  102.  
  103. ; write results
  104.         invoke  con_write_asciiz, str8          ; ' (',0
  105.         mov     eax, [esi+addrinfo.ai_addr]     ; convert IP address to decimal notation
  106.         mov     eax, [eax+sockaddr_in.sin_addr] ;
  107.         mov     [sockaddr1.ip], eax             ;
  108.         invoke  inet_ntoa, eax                  ;
  109.         invoke  con_write_asciiz, eax           ; print ip
  110.         invoke  freeaddrinfo, esi               ; free allocated memory
  111.         invoke  con_write_asciiz, str9          ; ')',10,0
  112.  
  113. ; open the socket
  114.         mcall   socket, AF_INET4, SOCK_STREAM, 0
  115.         cmp     eax, -1
  116.         je      socket_error
  117.         mov     [socketnum], eax
  118.  
  119. ; connect to the server
  120.         invoke  con_write_asciiz, str11
  121.         mcall   connect, [socketnum], sockaddr1, 18
  122.         mov     [status], STATUS_CONNECTING
  123.  
  124.         invoke  con_write_asciiz, str12         ; 'waiting for welcome'
  125.  
  126.         mov     [offset], 0
  127.  
  128. wait_for_servercommand:
  129.  
  130.         cmp     [offset], 0
  131.         je      .receive
  132.         mov     esi, [offset]
  133.         mov     edi, s
  134.         mov     ecx, [size]
  135.         add     ecx, esi
  136.         jmp     .byteloop
  137.  
  138. ; receive socket data
  139.   .receive:
  140.         mcall   recv, [socketnum], buffer_ptr, BUFFERSIZE, 0
  141.         inc     eax
  142.         jz      socket_error
  143.         dec     eax
  144.         jz      wait_for_servercommand
  145.  
  146.         mov     [offset], 0
  147.  
  148. ; extract commands, copy them to "s" buffer
  149.         lea     ecx, [eax + buffer_ptr]         ; ecx = end pointer
  150.         mov     esi, buffer_ptr                 ; esi = current pointer
  151.         mov     edi, s
  152.   .byteloop:
  153.         cmp     esi, ecx
  154.         jae     wait_for_servercommand
  155.         lodsb
  156.         cmp     al, 10                          ; excellent, we might have a command
  157.         je      .got_command
  158.         cmp     al, 13                          ; just ignore this byte
  159.         je      .byteloop
  160.         stosb
  161.         jmp     .byteloop
  162.   .got_command:                                 ; we have a newline check if its a command
  163.         cmp     esi, ecx
  164.         je      .no_more_data
  165.         mov     [offset], esi
  166.         sub     ecx, esi
  167.         mov     [size], ecx
  168.         jmp     .go_cmd
  169.   .no_more_data:
  170.         mov     [offset], 0
  171.   .go_cmd:
  172.         xor     al, al
  173.         stosb
  174.  
  175.         invoke  con_set_flags, 0x03             ; change color
  176.         invoke  con_write_asciiz, s             ; print servercommand
  177.         invoke  con_write_asciiz, str4          ; newline
  178.         invoke  con_set_flags, 0x07             ; reset color
  179.  
  180.         jmp     server_parser                   ; parse command
  181.  
  182. wait_for_usercommand:
  183.  
  184.         invoke  con_set_flags, 0x0a
  185.  
  186.         cmp     [status], STATUS_CONNECTED
  187.         je      .connected
  188.  
  189.         cmp     [status], STATUS_NEEDPASSWORD
  190.         je      .needpass
  191.  
  192. ; write prompt
  193.         invoke  con_write_asciiz, str2
  194. ; read string
  195.         mov     esi, s
  196.         invoke  con_gets, esi, 256
  197.  
  198.         invoke  con_write_asciiz, str4          ; newline
  199.         invoke  con_set_flags, 0x07
  200.  
  201.         cmp     dword[s], "list"
  202.         je      cmd_list
  203.  
  204.         cmp     dword[s], "help"
  205.         je      cmd_help
  206.  
  207.         cmp     dword[s], "cwd "
  208.         je      cmd_cwd
  209.  
  210.         cmp     dword[s], "retr"
  211.         je      cmd_retr
  212.  
  213.         cmp     dword[s], "pwd" + 10 shl 24
  214.         je      cmd_pwd
  215.  
  216.         cmp     dword[s], "stor"
  217.         je      cmd_stor
  218.  
  219.         cmp     dword[s], "dele"
  220.         je      cmd_dele
  221.  
  222.         cmp     dword[s], "bye" + 10 shl 24
  223.         je      cmd_bye
  224.  
  225.         cmp     dword[s], "lcwd"
  226.         je      cmd_lcwd
  227.  
  228.         cmp     dword[s], "mkd "
  229.         je      cmd_mkd
  230.  
  231.         cmp     dword[s], "rmd "
  232.         je      cmd_rmd
  233.  
  234.         cmp     dword[s], "cdup"
  235.         je      cmd_cdup
  236.  
  237.         invoke  con_write_asciiz, str_unknown
  238.         jmp     wait_for_usercommand
  239.  
  240.  
  241.   .connected:
  242.  
  243.         invoke  con_write_asciiz, str_user
  244.         mov     dword[s], "USER"
  245.         mov     byte[s+4], " "
  246.         jmp     .send
  247.  
  248.  
  249.   .needpass:
  250.  
  251.         invoke  con_write_asciiz, str_pass
  252.         mov     dword[s], "PASS"
  253.         mov     byte[s+4], " "
  254.         invoke  con_set_flags, 0x00     ; black text on black background for password
  255.  
  256.   .send:
  257. ; read string
  258.         mov     esi, s+5
  259.         invoke  con_gets, esi, 256
  260.  
  261. ; find end of string
  262.         mov     edi, s+5
  263.         mov     ecx, 256
  264.         xor     al, al
  265.         repne   scasb
  266.         lea     esi, [edi-s-1]
  267. ; and send it to the server
  268.         mcall   send, [socketnum], s, , 0
  269.  
  270.         invoke  con_write_asciiz, str4  ; newline
  271.         invoke  con_set_flags, 0x07     ; reset color
  272.         jmp     wait_for_servercommand
  273.  
  274.  
  275.  
  276. open_dataconnection:                    ; only passive for now..
  277.         cmp     [status], STATUS_LOGGED_IN
  278.         jne     .fail
  279.  
  280.         mov     dword[s], "PASV"
  281.         mov     byte[s+4], 10
  282.         mcall   send, [socketnum], s, 5, 0
  283.         ret
  284.  
  285.   .fail:
  286.         invoke  con_write_asciiz, str6
  287.         ret
  288.  
  289.  
  290.  
  291. socket_error:
  292.         invoke  con_write_asciiz, str6
  293.         jmp     fail.wait
  294.  
  295. fail:
  296.         invoke  con_write_asciiz, str5
  297.   .wait:
  298.         invoke  con_write_asciiz, str10
  299.         invoke  con_getch2
  300.         jmp     main
  301.  
  302. done:
  303.         invoke  con_exit, 1
  304.  
  305. exit:
  306.         mcall   close, [socketnum]
  307.         mcall   -1
  308.  
  309.  
  310.  
  311. ; data
  312. title   db 'FTP client',0
  313. str1    db 'FTP client for KolibriOS v0.07',10,10,'Please enter ftp server address.',10,0
  314. str2    db '> ',0
  315. str3    db 'Resolving ',0
  316. str4    db 10,0
  317. str5    db 10,'Name resolution failed.',10,0
  318. str6    db 10,'Socket error.',10,0
  319. str8    db ' (',0
  320. str9    db ')',10,0
  321. str10   db 'Push any key to continue.',0
  322. str11   db 'Connecting...',10,0
  323. str12   db 'Waiting for welcome message.',10,0
  324. str_user db "username: ",0
  325. str_pass db "password: ",0
  326. str_unknown db "unknown command or insufficient parameters",10,0
  327. str_lcwd db "local working directory is now: ",0
  328.  
  329. str_help db "available commands:",10
  330.          db "help - help",10
  331.          db 10
  332.          db "bye  - close connection",10
  333.          db "cdup - change to parent of current directory on server",10
  334.          db "cwd  - change working directoy on server",10
  335.          db "dele - delete file from server",10
  336.          db "list - list files and folders in current directory",10
  337.          db "lcwd - change local working directory",10
  338.          db "mkd  - make directory on the server",10
  339.          db "pwd  - print working directory",10
  340.          db "retr - retreive file from server",10
  341.          db "rmd  - remove directory from the server",10
  342.          db "stor - store file on server",10
  343.          db 10,0
  344.  
  345. str_open db "opening data socket",10,0
  346.  
  347. sockaddr1:
  348.         dw AF_INET4
  349. .port   dw 0x1500       ; 21
  350. .ip     dd 0
  351.         rb 10
  352.  
  353. sockaddr2:
  354.         dw AF_INET4
  355. .port   dw 0
  356. .ip     dd 0
  357.         rb 10
  358.  
  359. ; import
  360. align 4
  361. @IMPORT:
  362.  
  363. library network, 'network.obj', console, 'console.obj'
  364.  
  365. import  network,        \
  366.         getaddrinfo,    'getaddrinfo',  \
  367.         freeaddrinfo,   'freeaddrinfo', \
  368.         inet_ntoa,      'inet_ntoa'
  369.  
  370. import  console,        \
  371.         con_start,      'START',        \
  372.         con_init,       'con_init',     \
  373.         con_write_asciiz,'con_write_asciiz',     \
  374.         con_exit,       'con_exit',     \
  375.         con_gets,       'con_gets',\
  376.         con_cls,        'con_cls',\
  377.         con_getch2,     'con_getch2',\
  378.         con_set_cursor_pos, 'con_set_cursor_pos',\
  379.         con_write_string, 'con_write_string',\
  380.         con_get_flags,  'con_get_flags', \
  381.         con_set_flags,  'con_set_flags'
  382.  
  383.  
  384. i_end:
  385.  
  386. status          db ?
  387. active_passive  db ?
  388.  
  389. socketnum       dd ?
  390. datasocket      dd ?
  391. offset          dd ?
  392. size            dd ?
  393. operation       dd ?
  394.  
  395. filestruct:
  396. .subfn  dd ?
  397. .offset dd ?
  398.         dd ?
  399. .size   dd ?
  400. .ptr    dd ?
  401. .name   rb 1024
  402.  
  403. buffer_ptr      rb BUFFERSIZE+1
  404. buffer_ptr2     rb BUFFERSIZE+1
  405.  
  406. s               rb 1024
  407.  
  408. mem:
  409.