Subversion Repositories Kolibri OS

Rev

Rev 2562 | 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.         push    buffer
  161.         call    [con_write_asciiz]
  162.         pushd   0x07
  163.         call    [con_set_flags]
  164.  
  165.         pop     ecx
  166.         mov     esi, buffer
  167.         call    parse_cmd
  168.  
  169.         jmp     .loop
  170.  
  171. acpt_err:
  172.  
  173.         pushd   0x0c
  174.         call    [con_set_flags]
  175.  
  176.         push    str8
  177.         call    [con_write_asciiz]
  178.         jmp     done
  179.  
  180. listen_err:
  181.  
  182.         pushd   0x0c
  183.         call    [con_set_flags]
  184.  
  185.         push    str3
  186.         call    [con_write_asciiz]
  187.         jmp     done
  188.  
  189. bind_err:
  190.  
  191.         pushd   0x0c
  192.         call    [con_set_flags]
  193.  
  194.         push    str4
  195.         call    [con_write_asciiz]
  196.         jmp     done
  197.  
  198. sock_err:
  199.  
  200.         pushd   0x0c
  201.         call    [con_set_flags]
  202.  
  203.         push    str6
  204.         call    [con_write_asciiz]
  205.         jmp     done
  206.  
  207. done:
  208.         call    [con_getch2]
  209.         push    1
  210.         call    [con_exit]
  211. exit:
  212.         mcall   -1
  213.  
  214.  
  215.  
  216. ; data
  217. title   db      'KolibriOS FTP daemon 0.1', 0
  218. str1    db      'Starting FTP daemon on port %u', 0
  219. str2    db      '.', 0
  220. str2b   db      ' OK!',10,10,0
  221. str3    db      'Listen error',10,10,0
  222. str4    db      'Bind error',10,10,0
  223. str5    db      'Setsockopt error.',10,10,0
  224. str6    db      'Could not open socket',10,10,0
  225. str7    db      'Got data!',10,10,0
  226. str8    db      'Error accepting connection',10,10,0
  227.  
  228. str_logged_in   db 'Login ok',10,10,0
  229. str_pass_ok     db 'Password ok - Logged in',10,10,0
  230. str_pwd         db 'Current directory is "%s"\n',0
  231. str_err1        db 'ERROR: cannot connect to remote socket',10,10,0
  232. str_err2        db 'ERROR: cannot open directory',10,10,0
  233. str_datasock    db 'Passive data socket connected!',10,10,0
  234.  
  235.  
  236. str_mask        db '*', 0
  237.  
  238.  
  239. months:
  240.         dd     'Jan ','Feb ','Mar ','Apr ','May ','Jun '
  241.         dd     'Jul ','Aug ','Sep ','Oct ','Nov ','Dec '
  242.  
  243. filename db '.ini', 0
  244. str_port db 'port', 0
  245. str_ftpd db 'ftpd', 0
  246. str_conn db 'conn', 0
  247.  
  248. sockaddr1:
  249.         dw AF_INET4
  250. .port   dw 21
  251. .ip     dd 0
  252.         rb 10
  253. .length = $ - sockaddr1
  254.  
  255. ; import
  256. align 4
  257. @IMPORT:
  258.  
  259. library console, 'console.obj', \
  260.         libini, 'libini.obj', \
  261.         libio, 'libio.obj'
  262.  
  263. import  console,        \
  264.         con_start,      'START',        \
  265.         con_init,       'con_init',     \
  266.         con_write_asciiz,       'con_write_asciiz',     \
  267.         con_exit,       'con_exit',     \
  268.         con_gets,       'con_gets',\
  269.         con_cls,        'con_cls',\
  270.         con_printf,     'con_printf',\
  271.         con_getch2,     'con_getch2',\
  272.         con_set_cursor_pos, 'con_set_cursor_pos',\
  273.         con_set_flags,  'con_set_flags'
  274.  
  275. import  libini,         \
  276.         ini.get_str,    'ini_get_str',\
  277.         ini.get_int,    'ini_get_int'
  278.  
  279. import  libio,          \
  280.         libio.init , 'lib_init'   , \
  281.         file.size  , 'file_size'  , \
  282.         file.open  , 'file_open'  , \
  283.         file.read  , 'file_read'  , \
  284.         file.close , 'file_close' , \
  285.         file.find.first , 'file_find_first', \
  286.         file.find.next ,  'file_find_next', \
  287.         file.find.close , 'file_find_close'
  288.  
  289.  
  290. i_end:
  291.  
  292. socketnum       dd ?
  293.  
  294.  
  295. ; thread specific data
  296. socketnum2      dd ?
  297. state           dd ?
  298. home_dir        db '/rd/1/', 0
  299.                 rb 1024
  300. work_dir        rb 1024
  301. fpath           rb 2048
  302.  
  303. type            db ?
  304. mode            db ?    ; active/passive
  305.  
  306. passivesocknum  dd ?
  307. datasocketnum   dd ?
  308.  
  309. datasock:
  310.         dw AF_INET4
  311. .port   dw ?
  312. .ip     dd ?
  313.         rb 10
  314. .length = $ - datasock
  315.  
  316. buffer  rb BUFFERSIZE
  317. .length = $ - buffer
  318.  
  319. path    rb 1024
  320. mem:
  321.