Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2004-2013. All rights reserved.    ;;
  4. ;; Distributed under terms of the GNU General Public License       ;;
  5. ;;                                                                 ;;
  6. ;;                                                                 ;;
  7. ;;         GNU GENERAL PUBLIC LICENSE                              ;;
  8. ;;          Version 2, June 1991                                   ;;
  9. ;;                                                                 ;;
  10. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  11.  
  12.  
  13. server_parser:
  14.  
  15.         mov     esi, servercommand
  16.  
  17.         cmp     byte [esi], ':'
  18.         jne     .parse
  19.  
  20.   .spaceloop:
  21.         lodsb
  22.         test    al, al
  23.         jz      .fail
  24.         cmp     al, ' '
  25.         jne     .spaceloop
  26.  
  27.   .parse:
  28.         mov     eax, [esi]
  29.         or      eax, 0x20202020
  30.         mov     edi, server_commands
  31.         mov     ecx, server_commands.number
  32.  
  33.   .loop:
  34.         scasd
  35.         je      .got_cmd
  36.         add     edi, 4
  37.         dec     ecx
  38.         jnz     .loop
  39.  
  40.   .fail:
  41.         ret
  42.  
  43.   .got_cmd:
  44.         jmp     dword[edi]
  45.  
  46.  
  47. server_commands:
  48.  
  49.         dd      '322 ', cmd_322         ; RPL_LIST
  50.         dd      '323 ', cmd_323         ; RPL_LISTEND
  51.         dd      '328 ', cmd_328
  52.         dd      '332 ', cmd_topic
  53.         dd      '333 ', cmd_333         ; nickname and time of topic
  54.         dd      '353 ', cmd_353         ; name reply
  55.         dd      '366 ', cmd_366         ; end of names list
  56.         dd      '372 ', cmd_372         ; motd
  57.         dd      '375 ', cmd_375         ; start of motd
  58.         dd      '376 ', cmd_376         ; end of motd
  59.         dd      '421 ', cmd_421         ; unknown command
  60.         dd      'join', cmd_join
  61.         dd      'kick', cmd_kick
  62.         dd      'mode', cmd_mode
  63.         dd      'nick', cmd_nick
  64.         dd      'part', cmd_part
  65.         dd      'ping', cmd_ping
  66.         dd      'priv', cmd_privmsg
  67.         dd      'quit', cmd_quit
  68.         dd      'noti', cmd_notice
  69.  
  70.         .number = ($ - server_commands) / 8
  71.  
  72.  
  73. align 4
  74. compare_to_nick:
  75.  
  76.         push    esi
  77.         mov     ecx, MAX_NICK_LEN
  78.         mov     esi, user_nick
  79.   .loop:
  80.         lodsb
  81.         cmp     al, ' '
  82.         jbe     .done
  83.         cmp     al, 'a'
  84.         jb      .ok
  85.         cmp     al, 'z'
  86.         ja      .ok
  87.         sub     al, 0x20
  88.   .ok:
  89.  
  90.         mov     bl, byte[edi]
  91.         cmp     bl, 'a'
  92.         jb      .ok2
  93.         cmp     bl, 'z'
  94.         ja      .ok2
  95.         sub     bl, 0x20
  96.   .ok2:
  97.         cmp     bl, al
  98.         jne     .not_equal
  99.         inc     edi
  100.         dec     ecx
  101.         jnz     .loop
  102.  
  103.   .done:
  104.         xor     eax, eax
  105.         pop     esi
  106.         ret
  107.  
  108.   .not_equal:
  109.         or      eax, -1
  110.         pop     esi
  111.         ret
  112.  
  113. align 4
  114. skip_nick:
  115.  
  116. ; First: skip the NICK (maybe we should verify it?)
  117.   .nick:
  118.         lodsb
  119.         cmp     al, ' '
  120.         je      .skip
  121.         cmp     al, ':'
  122.         je      .skip
  123.         jmp     .nick
  124.  
  125. ; skip all leading spaces and semicolons
  126.   .skip:
  127.         lodsb
  128.         cmp     al, ' '
  129.         je      .skip
  130.         cmp     al, ':'
  131.         je      .skip
  132.         dec     esi
  133.  
  134.         ret
  135.  
  136.  
  137. align 4
  138. find_window:                            ; esi is ptr to windowname
  139.  
  140. ; TODO: if the window in question does not exist, create it ???
  141.  
  142. ; now search for window in list
  143.         mov     ebx, windows
  144.         mov     [window_print], ebx     ; set first window (server window) as default output window
  145.   .scanloop:
  146.         cmp     [ebx + window.data_ptr], 0
  147.         je      .just_skip
  148.         push    esi
  149.         lea     edi, [ebx + window.name]
  150.         mov     ecx, MAX_WINDOWNAME_LEN
  151.         repe    cmpsb
  152.         cmp     byte[edi-1], 0
  153.         je      .got_it
  154.         pop     esi
  155.         add     ebx, sizeof.window
  156.         ; TODO: check buffer limits ?
  157.         jmp     .scanloop
  158.  
  159. ; window not found, just skip this name
  160.   .just_skip:
  161.         lodsb
  162.         test    al, al
  163.         jz      .quit
  164.         cmp     al, ' '
  165.         jne     .just_skip
  166.         dec     esi
  167.         jmp     .done
  168.  
  169. ; found it!
  170.   .got_it:
  171.         add     esp, 4
  172.         mov     [window_print], ebx
  173.         dec     esi
  174.  
  175. ; now skip trailing spaces and semicolons
  176.   .done:
  177.         lodsb
  178.         test    al, al
  179.         jz      .quit
  180.         cmp     al, ' '
  181.         je      .done
  182.         cmp     al, ':'
  183.         je      .done
  184.         dec     esi
  185.  
  186.   .quit:
  187.         call    window_refresh
  188.  
  189.         ret
  190.  
  191.  
  192.  
  193. cmd_328:
  194. cmd_421:
  195. cmd_372:
  196. cmd_375:
  197. cmd_376:
  198.         add     esi, 4
  199.         jmp     cmd_notice.loop
  200.  
  201. cmd_notice:
  202.  
  203.         cmp     byte[servercommand], ':'
  204.         jne     .gogogo
  205.  
  206.         mov     byte [esi-1], 0
  207.         push    esi
  208.         mov     esi, str_1
  209.         call    print_text2
  210.         mov     esi, servercommand+1
  211.         call    print_text2
  212.         mov     esi, str_2
  213.         call    print_text2
  214.         pop     esi
  215.  
  216.   .gogogo:
  217.         add     esi, 6
  218.  
  219.   .loop:
  220.         inc     esi
  221.         cmp     byte [esi], 0
  222.         je      .fail
  223.         cmp     byte [esi], ' '
  224.         jne     .loop
  225.  
  226.   .loop2:
  227.         inc     esi
  228.         cmp     byte [esi], 0
  229.         je      .fail
  230.         cmp     byte [esi], ' '
  231.         je      .loop2
  232.         cmp     byte [esi], ':'
  233.         je      .loop2
  234.  
  235.         call    print_text2
  236.         mov     esi, str_newline
  237.         call    print_text2
  238.  
  239.   .fail:
  240.  
  241.         ret
  242.  
  243.  
  244.  
  245. cmd_ping:
  246.  
  247. ; Just change PING to PONG
  248.         mov     dword[esi], 'PONG'
  249.  
  250. ; Find the end of the command
  251.         lea     edi, [esi + 5]
  252.         xor     al, al
  253.         repne   scasb
  254.  
  255. ; Now send it back
  256.         mov     edx, esi
  257.         mov     esi, edi
  258.         mov     word [esi], 0x0d0a
  259.         inc     esi
  260.         inc     esi
  261.         sub     esi, edx
  262.         mcall   send, [socketnum], , , 0
  263.  
  264.         ret
  265.  
  266.  
  267.  
  268. cmd_privmsg:
  269.  
  270.         add     esi, 8          ; skip 'PRIVMSG '
  271.         call    find_window     ; esi now points to end of destination name
  272.  
  273.         cmp     byte[esi], 1
  274.         je      cmd_ctcp
  275.  
  276.         cmp     dword[esi], 'ACTI'      ; Action?
  277.         je      .action
  278.  
  279. ; nope, just plain old privmsg
  280. if TIMESTAMP
  281.         call    print_timestamp
  282. end if
  283.  
  284.         push    esi
  285.         mov     bl, '<'
  286.         call    print_character
  287.  
  288.         mov     eax, servercommand+1
  289.         mov     dl, '!'
  290.         call    print_text
  291.  
  292.         mov     bl, '>'
  293.         call    print_character
  294.  
  295.         mov     bl, ' '
  296.         call    print_character
  297.  
  298.         pop     esi
  299.         call    print_text2
  300.  
  301.         mov     bl, 10
  302.         call    print_character
  303.  
  304.   .fail:
  305.         ret
  306.  
  307.   .action:
  308.         add     esi, 8
  309.         push    esi
  310.         if TIMESTAMP
  311.         call    print_timestamp
  312.         end if
  313.  
  314.         mov     esi, action_header_short
  315.         call    print_text2
  316.  
  317.         mov     eax, servercommand+1
  318.         mov     dl, ' '
  319.         call    print_text
  320.  
  321.         mov     bl, ' '
  322.         call    print_character
  323.  
  324.         pop     esi
  325.         call    print_text2
  326.  
  327.         mov     bl, 10
  328.         call    print_character
  329.  
  330.         ret
  331.  
  332. cmd_ctcp:
  333.         inc     esi
  334.  
  335.         cmp     dword[esi], 'VERS'
  336.         je      .version
  337.  
  338.         cmp     dword[esi], 'TIME'
  339.         je      .time
  340.  
  341.         cmp     dword[esi], 'PING'
  342.         je      .ping
  343.  
  344.         ret
  345.  
  346.   .time:
  347.         mov     byte [esi+4], ' '
  348.         lea     edi, [esi+5]
  349.  
  350.         ; TODO: add system date (fn 29) in human readable format
  351.  
  352.         mcall   3                       ; get system time
  353.  
  354.         mov     ecx, 3
  355.   .timeloop:
  356.         mov     bl, al
  357.         shr     al, 4
  358.         add     al, '0'
  359.         stosb
  360.  
  361.         mov     al, bl
  362.         and     al, 0x0f
  363.         add     al, '0'
  364.         stosb
  365.  
  366.         dec     ecx
  367.         jz      .timedone
  368.  
  369.         mov     al, ':'
  370.         stosb
  371.         shr     eax, 8
  372.         jmp     .timeloop
  373.  
  374.   .timedone:
  375.         xor     al, al
  376.         stosb
  377.         call    ctcp_reply
  378.  
  379.         if TIMESTAMP
  380.         call    print_timestamp
  381.         end if
  382.  
  383.         mov     esi, ctcp_header
  384.         call    print_text2
  385.  
  386.         mov     esi, servercommand+1
  387.         call    print_text2
  388.  
  389.         mov     esi, ctcp_time
  390.         call    print_text2
  391.  
  392.         ret
  393.  
  394.   .version:
  395.         mov     esi, str_version
  396.         call    ctcp_reply
  397.  
  398.         if TIMESTAMP
  399.         call    print_timestamp
  400.         end if
  401.  
  402.         mov     esi, ctcp_header
  403.         call    print_text2
  404.  
  405.         mov     esi, servercommand+1
  406.         call    print_text2
  407.  
  408.         mov     esi, ctcp_version
  409.         call    print_text2
  410.  
  411.         ret
  412.  
  413.   .ping:
  414.         call    ctcp_reply
  415.  
  416.         if TIMESTAMP
  417.         call    print_timestamp
  418.         end if
  419.  
  420.         mov     esi, ctcp_header
  421.         call    print_text2
  422.  
  423.         mov     esi, servercommand+1
  424.         call    print_text2
  425.  
  426.         mov     esi, ctcp_ping
  427.         call    print_text2
  428.  
  429.         ret
  430.  
  431.  
  432.  
  433. ctcp_reply:
  434.  
  435.         push    esi
  436.  
  437.         mov     dword [usercommand], 'NOTI'
  438.         mov     dword [usercommand+4], 'CE  '
  439.  
  440.         mov     esi, servercommand+1
  441.         mov     edi, usercommand+7
  442.   .nickloop:
  443.         lodsb
  444.         cmp     al, '!'
  445.         je      .done
  446.         cmp     al, ' '
  447.         je      .done
  448.         test    al, al
  449.         je      .fail
  450.         stosb
  451.         jmp     .nickloop
  452.   .done:
  453.         mov     byte [esi-1], 0
  454.         mov     ax, ' :'
  455.         stosw
  456.         mov     al, 1
  457.         stosb
  458.  
  459.         pop     esi
  460.   .replyloop:
  461.         lodsb
  462.         cmp     al, 1
  463.         jbe     .done2
  464.         stosb
  465.         jmp     .replyloop
  466.   .done2:
  467.  
  468.         mov     al, 1
  469.         stosb
  470.         mov     ax, 0x0a0d
  471.         stosw
  472.  
  473.         lea     esi, [edi - usercommand]
  474.         mcall   send, [socketnum], usercommand, , 0
  475.   .fail:
  476.         ret
  477.  
  478.  
  479.  
  480. cmd_part:
  481.         add     esi, 5  ; skip 'PART '
  482.         push    esi
  483.         call    skip_nick
  484.         call    find_window
  485.         pop     esi
  486.  
  487. ; Is it me who parted?
  488.         mov     edi, servercommand+1
  489.         call    compare_to_nick
  490.         jne     .dont_close
  491.  
  492. ; yes, close the window
  493.         mov     edi, [window_print]
  494.         mov     [edi + window.flags], FLAG_UPDATED + FLAG_CLOSE
  495.  
  496.         ret
  497.  
  498. ; somebody else parted, just print message
  499.   .dont_close:
  500.         push    esi
  501.         mov     esi, action_header
  502.         call    print_text2
  503.  
  504.         mov     eax, servercommand+1
  505.         mov     dl, '!'
  506.         mov     cl, ' '
  507.         call    print_text
  508.  
  509.         mov     esi, has_left_channel
  510.         call    print_text2
  511.  
  512.         pop     esi
  513.         call    print_text2
  514.  
  515.         mov     esi, str_newline
  516.         call    print_text2
  517.  
  518.         mov     ebx, [window_print]
  519.         mov     esi, servercommand+1
  520.         call    user_remove
  521.  
  522.         ret
  523.  
  524.  
  525.  
  526. cmd_join:
  527.         add     esi, 5  ; skip 'JOIN '
  528.  
  529. ; compare nick: did we join a channel?
  530.         mov     edi, servercommand+1
  531.         call    compare_to_nick
  532.         jne     .no_new_window
  533.  
  534. ; create channel window - search for empty slot
  535.         mov     ebx, windows
  536.         mov     ecx, MAX_WINDOWS
  537.   .loop:
  538.         cmp     [ebx + window.data_ptr], 0
  539.         je      .free_found
  540.         add     ebx, sizeof.window
  541.         dec     ecx
  542.         jnz     .loop
  543. ; Error: no more available windows!! ;;;;; TODO
  544.   .fail:
  545.         ret
  546.  
  547.   .free_found:
  548.         push    ebx
  549.         call    window_create
  550.         pop     ebx
  551.         test    eax, eax
  552.         jz      .fail
  553.         mov     [ebx + window.data_ptr], eax
  554.         mov     [ebx + window.type], WINDOWTYPE_CHANNEL
  555.         mov     [ebx + window.flags], 0
  556.  
  557.         call    window_set_name
  558.  
  559.         mov     [window_open], ebx
  560.         mov     [window_print], ebx
  561.         call    window_refresh
  562.  
  563.         push    esi
  564.         mov     esi, action_header
  565.         call    print_text2
  566.  
  567.         mov     esi, str_talking
  568.         call    print_text2
  569.  
  570.         pop     eax
  571.         mov     dl, ' '
  572.         call    print_text
  573.  
  574.         mov     esi, str_dotnewline
  575.         call    print_text2
  576.  
  577.         call    draw_window
  578.  
  579.         ret
  580.  
  581.   .no_new_window:
  582.         push    esi
  583.         call    find_window
  584.  
  585.         mov     esi, action_header
  586.         call    print_text2
  587.  
  588.         mov     eax, servercommand+1
  589.         mov     dl, '!'
  590.         call    print_text
  591.  
  592.         mov     esi, joins_channel
  593.         call    print_text2
  594.  
  595.         pop     esi
  596.         call    print_text2
  597.  
  598.         mov     esi, str_newline
  599.         call    print_text2
  600.  
  601.         mov     ebx, [window_print]
  602.         mov     esi, servercommand+1
  603.         call    user_add
  604.  
  605.         ret
  606.  
  607.  
  608.  
  609.  
  610. cmd_nick:
  611. ; NOTE: This command applies to a user, and thus has no specific channel
  612.         add     esi, 5  ; skip 'NICK '
  613.  
  614.         cmp     byte[esi], ':'          ; TODO: skip all spaces and semicolons?
  615.         jne     @f
  616.         inc     esi
  617.        @@:
  618.  
  619. ; Change the nick in the current userlist. TODO: check other channels too!
  620.         push    esi
  621.         mov     ebx, [window_print]
  622.  
  623.         mov     esi, servercommand+1
  624.         call    user_remove
  625.  
  626.         mov     esi, [esp]
  627.         call    user_add
  628.  
  629.         call    redraw_channel_list
  630.  
  631. ; Is it me who changed nick?
  632.         mov     edi, servercommand+1
  633.         call    compare_to_nick
  634.         pop     esi
  635.         jne     .not_me
  636.  
  637.         mov     ecx, MAX_NICK_LEN-1
  638.         push    esi
  639.   .copyloop:
  640.         lodsb
  641.         test    al, al
  642.         jz      .copydone
  643.         cmp     al, ' '
  644.         je      .copydone
  645.         stosb
  646.         dec     ecx
  647.         jnz     .copyloop
  648.   .copydone:
  649.         xor     al, al
  650.         stosb
  651.         pop     esi
  652.   .not_me:
  653.  
  654. ; Now print a message on the current channel
  655.         push    esi
  656.         mov     esi, action_header_short
  657.         call    print_text2
  658.  
  659.         mov     eax, servercommand+1
  660.         mov     dl, '!'
  661.         call    print_text
  662.  
  663.         mov     esi, is_now_known_as
  664.         call    print_text2
  665.  
  666.         pop     esi
  667.         call    print_text2
  668.  
  669.         mov     esi, str_newline
  670.         call    print_text2
  671.  
  672.         ret
  673.  
  674.  
  675.  
  676.  
  677. cmd_kick:
  678.         add     esi, 5  ; skip 'KICK '
  679. ; Is it me who got kicked?
  680.         mov     edi, servercommand+1
  681.         call    compare_to_nick
  682.         jne     .not_me
  683.  
  684. ; TODO: mark channel as disconnected
  685.  
  686.   .not_me:
  687. ; find the channel user has been kicked from
  688.         push    esi
  689.         call    skip_nick
  690.         call    find_window
  691.  
  692.         mov     esi, action_header_short
  693.         call    print_text2
  694.  
  695.         mov     eax, servercommand+1
  696.         mov     dl, '!'
  697.         call    print_text
  698.  
  699.         mov     esi, kicked
  700.         call    print_text2
  701.  
  702.         pop     esi
  703.         call    print_text2
  704.  
  705.         mov     esi, str_newline
  706.         call    print_text2
  707.  
  708.         mov     ebx, [window_print]
  709.         mov     esi, servercommand+1
  710.         call    user_remove
  711.  
  712.         ret
  713.  
  714.  
  715.  
  716. cmd_quit:
  717. ; NOTE: This command applies to a user, and thus has no specific channel
  718.  
  719.         mov     esi, action_header
  720.         call    print_text2
  721.  
  722.         mov     eax, servercommand+1
  723.         mov     dl, '!'
  724.         call    print_text
  725.  
  726.         mov     esi, has_quit_irc
  727.         call    print_text2
  728.  
  729. ; TODO: check other channels on same server too!
  730.         mov     ebx, [window_print]
  731.         mov     esi, servercommand+1
  732.         call    user_remove
  733.  
  734.         ret
  735.  
  736.  
  737.  
  738. cmd_mode:
  739.  
  740.         add     esi, 5  ; skip 'MODE '
  741.  
  742.         push    esi
  743.         mov     esi, action_header_short
  744.         call    print_text2
  745.  
  746.         mov     eax, servercommand+1
  747.         mov     dl, ' '
  748.         call    print_text
  749.  
  750.         mov     esi, sets_mode
  751.         call    print_text2
  752.  
  753.         pop     esi
  754.         call    print_text2
  755.  
  756.         mov     esi, str_newline
  757.         call    print_text2
  758.  
  759. ;;; TODO: change username if needed
  760.  
  761.         ret
  762.  
  763.  
  764. cmd_353:                ; channel usernames reply
  765.  
  766.         add     esi, 4  ; skip '353 '
  767.         call    skip_nick
  768.         inc     esi     ; channel type '*', '=' or '@'
  769.         inc     esi     ; ' '
  770.         call    find_window
  771.  
  772. ; now find window ptr and check if this is the first 353 message
  773.         mov     ebx, [window_print]
  774.         test    [ebx + window.flags], FLAG_RECEIVING_NAMES
  775.         jnz     .add
  776.  
  777.         or      [ebx + window.flags], FLAG_RECEIVING_NAMES
  778. ;        mov     [ebx + window.users], 0
  779.         ; TODO: remove all users?
  780.  
  781.   .add:
  782.         push    esi
  783.         call    user_add
  784.         pop     esi
  785.  
  786.   .namesloop:
  787.         lodsb
  788.         test    al, al
  789.         jz      .done
  790.         cmp     al, ' '                 ; names list is separated with spaces
  791.         jne     .namesloop
  792.         jmp     .add
  793.  
  794.   .done:
  795.         call    redraw_channel_list
  796.  
  797.         ret
  798.  
  799.  
  800.  
  801.  
  802.  
  803. cmd_366:        ; channel usernames end
  804.  
  805.         add     esi, 4          ; skip '366 '
  806.         call    skip_nick
  807.         call    find_window
  808.  
  809.         mov     ebx, [window_print]
  810.         and     [ebx + window.flags], not FLAG_RECEIVING_NAMES
  811.  
  812.         ret
  813.  
  814.  
  815.  
  816.  
  817. cmd_topic:
  818.  
  819.         add     esi, 4          ; skip '332 '
  820.         call    skip_nick
  821.         call    find_window
  822.  
  823.         push    esi
  824.         mov     esi, action_header
  825.         call    print_text2
  826.  
  827.         mov     esi, str_topic
  828.         call    print_text2
  829.  
  830.         pop     esi
  831.         call    print_text2
  832.  
  833.         mov     esi, str_newline
  834.         call    print_text2
  835.  
  836.         ret
  837.  
  838.  
  839. cmd_333:
  840.  
  841.         add     esi, 4          ; skip '333 '
  842.         call    skip_nick               ;;;;
  843.         call    find_window
  844.  
  845. ;        mov     ecx, 2  ; number of spaces to find    ;;; CHECKME
  846. ;  .loop:
  847. ;        lodsb
  848. ;        test    al, al
  849. ;        je      .fail
  850. ;        cmp     al, ' '
  851. ;        jne     .loop
  852. ;        dec     ecx
  853. ;        jnz     .loop   ; find some more spaces
  854.  
  855.         push    esi
  856.         mov     esi, action_header
  857.         call    print_text2
  858.  
  859.         mov     esi, str_setby
  860.         call    print_text2
  861.  
  862. ;        pop     esi
  863. ;        call    print_text2
  864.  
  865.         pop     eax
  866.         mov     dl, '!'
  867.         call    print_text
  868.  
  869.         mov     esi, str_newline
  870.         call    print_text2
  871.  
  872.   .fail:
  873.         ret
  874.  
  875. cmd_322:
  876.         add     esi, 4
  877.  
  878.         call    skip_nick
  879.  
  880.         call    print_text2
  881.  
  882.         mov     esi, str_newline
  883.         call    print_text2
  884.  
  885.         ret
  886.  
  887. cmd_323:
  888.  
  889.         ret