Subversion Repositories Kolibri OS

Rev

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

  1. ;
  2. ; Kolibrios FTP Daemon
  3. ;
  4. ; hidnplayr@gmail.com
  5. ;
  6. ; GPLv2
  7. ;
  8.  
  9. BUFFERSIZE              = 4096
  10.  
  11. STATE_DISCONNECTED      = 0
  12. STATE_CONNECTED         = 1
  13. STATE_LOGIN             = 2
  14. STATE_ACTIVE            = 3
  15.  
  16. TYPE_UNDEF              = 0
  17.  
  18. TYPE_ASCII              = 00000100b
  19. TYPE_EBDIC              = 00001000b
  20. ; subtypes for ascii & ebdic (np = default)
  21. TYPE_NP                 = 00000001b     ; non printable
  22. TYPE_TELNET             = 00000010b
  23. TYPE_ASA                = 00000011b
  24.  
  25. TYPE_IMAGE              = 01000000b     ; binary data
  26. TYPE_LOCAL              = 10000000b     ; bits per byte must be specified
  27.                                         ; lower 4 bits will hold this value
  28.  
  29. MODE_NOTREADY           = 0
  30. MODE_ACTIVE             = 1
  31. MODE_PASSIVE_WAIT       = 2
  32. MODE_PASSIVE_OK         = 3
  33.  
  34. use32
  35.         db      'MENUET01'      ; signature
  36.         dd      1               ; header version
  37.         dd      start           ; entry point
  38.         dd      i_end           ; initialized size
  39.         dd      mem+0x1000      ; required memory
  40.         dd      mem+0x1000      ; stack pointer
  41.         dd      0               ; parameters
  42.         dd      path            ; path
  43.  
  44. include '../macros.inc'
  45. purge mov,add,sub
  46. include '../proc32.inc'
  47. include '../dll.inc'
  48. include '../struct.inc'
  49. include '../libio.inc'
  50.  
  51. include '../network.inc'
  52. include 'commands.inc'
  53.  
  54. align 4
  55. start:
  56. ; load libraries
  57.         stdcall dll.Load, @IMPORT
  58.         test    eax, eax
  59.         jnz     exit
  60.  
  61. ; find path to main settings file
  62.         mov     edi, path      ; Calculate the length of zero-terminated string
  63.         xor     al , al
  64.         mov     ecx, 1024
  65.         repne   scasb
  66.         dec     edi
  67.         mov     esi, filename
  68.         movsd
  69.         movsb
  70.  
  71. ; initialize console
  72.         push    1
  73.         call    [con_start]
  74.  
  75.         push    title
  76.         push    -1
  77.         push    -1
  78.         push    -1
  79.         push    -1
  80.         call    [con_init]
  81.  
  82.         mcall   40, 1 shl 7     ; we only want network events
  83.  
  84.         invoke  ini.get_int, path, str_ftpd, str_port, 21
  85.         mov     [sockaddr1.port], ax
  86.  
  87.         push    eax
  88.         push    str1
  89.         call    [con_printf]
  90.  
  91.         mcall   socket, AF_INET4, SOCK_STREAM, 0
  92.         cmp     eax, -1
  93.         je      sock_err
  94.  
  95.         mov     [socketnum], eax
  96.  
  97.         push    str2
  98.         call    [con_write_asciiz]
  99.  
  100. ;;        mcall   setsockopt, [socketnum], SOL_SOCKET, SO_REUSEADDR, &yes,
  101. ;;        cmp     eax, -1
  102. ;;        je      opt_err
  103.  
  104.         mcall   bind, [socketnum], sockaddr1, sockaddr1.length
  105.         cmp     eax, -1
  106.         je      bind_err
  107.  
  108.         push    str2
  109.         call    [con_write_asciiz]
  110.  
  111.         invoke  ini.get_int, path, str_ftpd, str_conn, 1        ; Backlog (max connections)
  112.         mov     edx, eax
  113.  
  114.         push    str2
  115.         call    [con_write_asciiz]
  116.  
  117.         mcall   listen, [socketnum]
  118.         cmp     eax, -1
  119.         je      listen_err
  120.  
  121.         push    str2b
  122.         call    [con_write_asciiz]
  123.  
  124.         mcall   10
  125.  
  126.         mcall   accept, [socketnum], sockaddr1, sockaddr1.length
  127.         cmp     eax, -1
  128.         je      acpt_err
  129.  
  130.         mov     [socketnum2], eax
  131.  
  132.         mcall   send, [socketnum2], str220, str220.length, 0    ; send welcome string
  133.  
  134.   .loop:
  135.         mcall   10
  136.  
  137.         cmp     [mode], MODE_PASSIVE_WAIT
  138.         jne     @f
  139.         mcall   accept, [passivesocknum], datasock, datasock.length
  140.         cmp     eax, -1
  141.         je      @f
  142.         mov     [datasocketnum], eax
  143.         mov     [mode], MODE_PASSIVE_OK
  144.  
  145.         push    str_datasock
  146.         call    [con_write_asciiz]
  147.        @@:
  148.  
  149.         mcall   recv, [socketnum2], buffer, buffer.length
  150.         cmp     eax, -1
  151.         je      .loop
  152.         or      eax, eax
  153.         jz      .loop
  154.         push    eax
  155.  
  156.         mov     byte[buffer+eax], 0
  157.  
  158.         pushd   0x0a
  159.         call    [con_set_flags]
  160.  
  161.         push    buffer
  162.         call    [con_write_asciiz]
  163.  
  164.         pushd   0x07
  165.         call    [con_set_flags]
  166.  
  167.         pop     ecx
  168.         mov     esi, buffer
  169.         call    parse_cmd
  170.  
  171.         jmp     .loop
  172.  
  173. acpt_err:
  174.  
  175.         pushd   0x0c
  176.         call    [con_set_flags]
  177.  
  178.         push    str8
  179.         call    [con_write_asciiz]
  180.         jmp     done
  181.  
  182. listen_err:
  183.  
  184.         pushd   0x0c
  185.         call    [con_set_flags]
  186.  
  187.         push    str3
  188.         call    [con_write_asciiz]
  189.         jmp     done
  190.  
  191. bind_err:
  192.  
  193.         pushd   0x0c
  194.         call    [con_set_flags]
  195.  
  196.         push    str4
  197.         call    [con_write_asciiz]
  198.         jmp     done
  199.  
  200. sock_err:
  201.  
  202.         pushd   0x0c
  203.         call    [con_set_flags]
  204.  
  205.         push    str6
  206.         call    [con_write_asciiz]
  207.         jmp     done
  208.  
  209. done:
  210.         call    [con_getch2]
  211.         push    1
  212.         call    [con_exit]
  213. exit:
  214.         mcall   -1
  215.  
  216.  
  217.  
  218. ; data
  219. title   db      'KolibriOS FTP daemon 0.1', 0
  220. str1    db      'Starting FTP daemon on port %u', 0
  221. str2    db      '.', 0
  222. str2b   db      ' OK!',10,10,0
  223. str3    db      'Listen error',10,10,0
  224. str4    db      'Bind error',10,10,0
  225. str5    db      'Setsockopt error.',10,10,0
  226. str6    db      'Could not open socket',10,10,0
  227. str7    db      'Got data!',10,10,0
  228. str8    db      'Error accepting connection',10,10,0
  229.  
  230. str_logged_in   db 'Login ok',10,10,0
  231. str_pass_ok     db 'Password ok - Logged in',10,10,0
  232. str_pwd         db 'Current directory is "%s"\n',0
  233. str_err1        db 'ERROR: cannot connect to remote socket',10,10,0
  234. str_err2        db 'ERROR: cannot open directory',10,10,0
  235. str_datasock    db 'Passive data socket connected!',10,10,0
  236.  
  237.  
  238. str_mask        db '*', 0
  239.  
  240.  
  241. months:
  242.         dd     'Jan ','Feb ','Mar ','Apr ','May ','Jun '
  243.         dd     'Jul ','Aug ','Sep ','Oct ','Nov ','Dec '
  244.  
  245. filename db '.ini', 0
  246. str_port db 'port', 0
  247. str_ftpd db 'ftpd', 0
  248. str_conn db 'conn', 0
  249.  
  250. sockaddr1:
  251.         dw AF_INET4
  252. .port   dw 21
  253. .ip     dd 0
  254.         rb 10
  255. .length = $ - sockaddr1
  256.  
  257. ; import
  258. align 4
  259. @IMPORT:
  260.  
  261. library console, 'console.obj', \
  262.         libini, 'libini.obj', \
  263.         libio, 'libio.obj'
  264.  
  265. import  console,        \
  266.         con_start,      'START',        \
  267.         con_init,       'con_init',     \
  268.         con_write_asciiz,       'con_write_asciiz',     \
  269.         con_exit,       'con_exit',     \
  270.         con_gets,       'con_gets',\
  271.         con_cls,        'con_cls',\
  272.         con_printf,     'con_printf',\
  273.         con_getch2,     'con_getch2',\
  274.         con_set_cursor_pos, 'con_set_cursor_pos',\
  275.         con_set_flags,  'con_set_flags'
  276.  
  277. import  libini,         \
  278.         ini.get_str,    'ini_get_str',\
  279.         ini.get_int,    'ini_get_int'
  280.  
  281. import  libio,          \
  282.         libio.init , 'lib_init'   , \
  283.         file.size  , 'file_size'  , \
  284.         file.open  , 'file_open'  , \
  285.         file.read  , 'file_read'  , \
  286.         file.close , 'file_close' , \
  287.         file.find.first , 'file_find_first', \
  288.         file.find.next ,  'file_find_next', \
  289.         file.find.close , 'file_find_close'
  290.  
  291.  
  292. i_end:
  293.  
  294. socketnum       dd ?
  295.  
  296.  
  297. ; thread specific data
  298. socketnum2      dd ?
  299. state           dd ?
  300. home_dir        db '/rd/1/',0
  301. work_dir        rb 1024
  302. type            db ?
  303. mode            db ?    ; active/passive
  304.  
  305. passivesocknum  dd ?
  306. datasocketnum   dd ?
  307.  
  308. datasock:
  309.         dw AF_INET4
  310. .port   dw ?
  311. .ip     dd ?
  312.         rb 10
  313. .length = $ - datasock
  314.  
  315. buffer  rb BUFFERSIZE
  316. .length = $ - buffer
  317.  
  318. path    rb 1024
  319. mem:
  320.