Subversion Repositories Kolibri OS

Rev

Rev 4617 | Rev 4623 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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