Subversion Repositories Kolibri OS

Rev

Rev 4659 | Rev 6026 | 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          ; our nickname
  175.  
  176.         call    print_asciiz
  177.  
  178.         mov     al, 10
  179.         call    print_char
  180.  
  181.         ret
  182.  
  183.  
  184. cmd_notice:
  185.  
  186.         if TIMESTAMP
  187.         call    print_timestamp
  188.         end if
  189.  
  190.         cmp     byte[servercommand], ':'
  191.         jne     .gogogo
  192.  
  193.         mov     byte [esi-1], 0
  194.         push    esi
  195.         mov     esi, str_1
  196.         call    print_asciiz
  197.         mov     esi, servercommand+1
  198.         mov     bl, '!'
  199.         call    print_string
  200.         mov     esi, str_2
  201.         call    print_asciiz
  202.         pop     esi
  203.  
  204.   .gogogo:
  205.         add     esi, 6
  206.         call    skip_parameter
  207.         call    skip_parameter
  208.         call    print_asciiz
  209.  
  210.         mov     al, 10
  211.         call    print_char
  212.  
  213.         ret
  214.  
  215.  
  216.  
  217. cmd_ping:
  218.  
  219. ; Just change PING to PONG
  220.         mov     dword[esi], 'PONG'
  221.  
  222. ; Find the end of the command
  223.         lea     edi, [esi + 5]
  224.         xor     al, al
  225.         repne   scasb
  226.  
  227. ; Now send it back
  228.         mov     edx, esi
  229.         mov     esi, edi
  230.         mov     word [esi], 0x0d0a
  231.         inc     esi
  232.         inc     esi
  233.         sub     esi, edx
  234.         mcall   send, [socketnum], , , 0
  235.  
  236.         ret
  237.  
  238.  
  239.  
  240. cmd_privmsg:
  241.  
  242.         mov     eax, dword[esi+4]
  243.         or      eax, 0x20202020
  244.         cmp     eax, 'msg '
  245.         jne     .fail
  246.         add     esi, 8          ; skip 'PRIVMSG '
  247.  
  248.         mov     edi, esi
  249.         call    compare_to_nick
  250.         jne     .channel
  251.  
  252. ; private chat message
  253.         push    esi
  254.         mov     esi, servercommand+1
  255.         call    window_open
  256.         test    ebx, ebx
  257.         jz      .fail2
  258.         pop     esi
  259.         call    skip_parameter  ; our own nickname
  260.         jmp     .print
  261.  
  262.   .channel:
  263.         call    window_open
  264.         test    ebx, ebx
  265.         jz      .fail
  266.  
  267.   .print:
  268.         cmp     byte[esi], 1    ; Client to Client protocol?
  269.         je      cmd_ctcp
  270.  
  271.         if TIMESTAMP
  272.         call    print_timestamp
  273.         end if
  274.  
  275.         push    esi
  276.         mov     al, '<'
  277.         call    print_char
  278.  
  279.         mov     esi, servercommand+1
  280.         mov     bl, '!'
  281.         call    print_string
  282.  
  283.         mov     al, '>'
  284.         call    print_char
  285.  
  286.         mov     al, ' '
  287.         call    print_char
  288.  
  289.         pop     esi
  290.         call    print_asciiz
  291.  
  292.         mov     al, 10
  293.         call    print_char
  294.  
  295.         ret
  296.  
  297.   .fail2:
  298.         pop     esi
  299.   .fail:
  300.         ret
  301.  
  302.  
  303.  
  304.  
  305. cmd_ctcp:
  306.  
  307.         inc     esi
  308.         mov     eax, dword[esi]
  309.         or      eax, 0x20202020
  310.  
  311.         cmp     eax, 'vers'
  312.         je      .version
  313.         cmp     eax, 'time'
  314.         je      .time
  315.         cmp     eax, 'ping'
  316.         je      .ping
  317.         cmp     eax, 'acti'
  318.         je      .action
  319.         cmp     eax, 'dcc '    ; TODO
  320.         je      cmd_dcc
  321.  
  322. ; Unknown CTCP command: TODO: just print to window??
  323.  
  324.   .fail:
  325.  
  326.         ret
  327.  
  328.   .time:
  329.         mov     byte[esi+4], ' '
  330.         lea     edi, [esi+5]
  331.  
  332.         ; TODO: add system date (fn 29) in human readable format
  333.  
  334.         mcall   3                       ; get system time
  335.  
  336.         mov     ecx, 3
  337.   .timeloop:
  338.         mov     bl, al
  339.         shr     al, 4
  340.         add     al, '0'
  341.         stosb
  342.  
  343.         mov     al, bl
  344.         and     al, 0x0f
  345.         add     al, '0'
  346.         stosb
  347.  
  348.         dec     ecx
  349.         jz      .timedone
  350.  
  351.         mov     al, ':'
  352.         stosb
  353.         shr     eax, 8
  354.         jmp     .timeloop
  355.  
  356.   .timedone:
  357.         xor     al, al
  358.         stosb
  359.         call    ctcp_reply
  360.  
  361.         if TIMESTAMP
  362.         call    print_timestamp
  363.         end if
  364.  
  365.         mov     esi, ctcp_header
  366.         call    print_asciiz
  367.  
  368.         mov     esi, servercommand+1
  369.         call    print_asciiz
  370.  
  371.         mov     esi, ctcp_time
  372.         call    print_asciiz
  373.  
  374.         ret
  375.  
  376.   .version:
  377.         mov     esi, str_version
  378.         call    ctcp_reply
  379.  
  380.         if TIMESTAMP
  381.         call    print_timestamp
  382.         end if
  383.  
  384.         mov     esi, ctcp_header
  385.         call    print_asciiz
  386.  
  387.         mov     esi, servercommand+1
  388.         call    print_asciiz
  389.  
  390.         mov     esi, ctcp_version
  391.         call    print_asciiz
  392.  
  393.         ret
  394.  
  395.   .ping:
  396.         call    ctcp_reply
  397.  
  398.         if TIMESTAMP
  399.         call    print_timestamp
  400.         end if
  401.  
  402.         mov     esi, ctcp_header
  403.         call    print_asciiz
  404.  
  405.         mov     esi, servercommand+1
  406.         call    print_asciiz
  407.  
  408.         mov     esi, ctcp_ping
  409.         call    print_asciiz
  410.  
  411.         ret
  412.  
  413.   .action:
  414.         add     esi, 7
  415.         push    esi
  416.  
  417.         if TIMESTAMP
  418.         call    print_timestamp
  419.         end if
  420.  
  421.         mov     esi, action_header
  422.         call    print_asciiz
  423.  
  424.         mov     esi, servercommand+1    ; print nickname
  425.         mov     bl, '!'
  426.         call    print_string
  427.  
  428.         mov     al, ' '
  429.         call    print_char
  430.  
  431.         pop     esi
  432.         call    print_asciiz
  433.  
  434.         mov     al, 10
  435.         call    print_char
  436.  
  437.         ret
  438.  
  439.  
  440. cmd_dcc:
  441.         add     esi, 4
  442.         mov     eax, dword[esi]
  443.         or      eax, 0x202020
  444.  
  445.         cmp     eax, 'send'
  446.         je      .send
  447.  
  448.         ret
  449.  
  450.   .send:
  451.         call    window_open
  452.         test    ebx, ebx
  453.         jz      .fail
  454.         mov     [ebx + window.type], WINDOWTYPE_DCC
  455.  
  456.   .fail:
  457.  
  458.         ret
  459.  
  460.  
  461.  
  462. ctcp_reply:
  463.  
  464.         push    esi
  465.         mov     dword [usercommand], 'NOTI'
  466.         mov     dword [usercommand+4], 'CE  '
  467.  
  468.         mov     esi, servercommand+1
  469.         mov     edi, usercommand+7
  470.   .nickloop:
  471.         lodsb
  472.         cmp     al, '!'
  473.         je      .done
  474.         cmp     al, ' '
  475.         je      .done
  476.         test    al, al
  477.         je      .fail
  478.         stosb
  479.         jmp     .nickloop
  480.   .done:
  481.         mov     byte [esi-1], 0
  482.         mov     ax, ' :'
  483.         stosw
  484.         mov     al, 1
  485.         stosb
  486.  
  487.         pop     esi
  488.   .replyloop:
  489.         lodsb
  490.         cmp     al, 1
  491.         jbe     .done2
  492.         stosb
  493.         jmp     .replyloop
  494.   .done2:
  495.  
  496.         mov     al, 1
  497.         stosb
  498.         mov     ax, 0x0a0d
  499.         stosw
  500.  
  501.         lea     esi, [edi - usercommand]
  502.         mcall   send, [socketnum], usercommand, , 0
  503.   .fail:
  504.         ret
  505.  
  506.  
  507.  
  508. cmd_part:
  509.  
  510.         cmp     byte [esi+4], ' '
  511.         jne     .fail
  512.         add     esi, 5  ; skip 'PART '
  513.  
  514. ; Is it me who parted?
  515.         mov     edi, servercommand+1
  516.         call    compare_to_nick
  517.         jne     .not_me
  518.  
  519. ; yes, close the window (if its open)
  520.         call    window_find
  521.         test    ebx, ebx
  522.         jz      @f
  523.         call    window_close
  524.   @@:
  525.   .fail:
  526.  
  527.         ret
  528.  
  529.  
  530. ; somebody else parted, just print message
  531.   .not_me:
  532.         push    esi
  533.         call    window_open
  534.         test    ebx, ebx
  535.         jz      .fail2
  536.  
  537.         if TIMESTAMP
  538.         call    print_timestamp
  539.         end if
  540.  
  541.         mov     esi, part_header
  542.         call    print_asciiz
  543.  
  544.         mov     esi, servercommand+1
  545.         mov     bl, '!'
  546.         call    print_string
  547.  
  548.         mov     esi, has_left_channel
  549.         call    print_asciiz
  550.  
  551.         pop     esi
  552.         call    print_asciiz
  553.  
  554.         mov     al, 10
  555.         call    print_char
  556.  
  557.         mov     ebx, [window_print]
  558.         mov     esi, servercommand+1
  559.         call    user_remove
  560.  
  561.         ret
  562.  
  563.   .fail2:
  564.         pop     esi
  565.  
  566.         ret
  567.  
  568.  
  569.  
  570. cmd_join:
  571.  
  572.         cmp     byte[esi+4], ' '
  573.         jne     .fail
  574.         add     esi, 5  ; skip 'JOIN '
  575.  
  576. ; did we join a channel?
  577.         mov     edi, servercommand+1
  578.         call    compare_to_nick
  579.         jne     .not_me
  580.  
  581.         push    esi
  582.         call    window_open
  583.         test    ebx, ebx
  584.         jz      .fail
  585.         mov     [ebx + window.type], WINDOWTYPE_CHANNEL
  586.         mov     [window_active], ebx
  587.  
  588.         if TIMESTAMP
  589.         call    print_timestamp
  590.         end if
  591.  
  592.         mov     esi, join_header
  593.         call    print_asciiz
  594.  
  595.         mov     esi, str_talking
  596.         call    print_asciiz
  597.  
  598.         pop     esi
  599.         mov     bl, ' '
  600.         call    print_string
  601.  
  602.         mov     al, 10
  603.         call    print_char
  604.  
  605.         call    draw_window
  606.  
  607.         ret
  608.  
  609.   .not_me:
  610.         push    esi
  611.         call    window_open
  612.         test    ebx, ebx
  613.         jz      .fail
  614.  
  615.         if TIMESTAMP
  616.         call    print_timestamp
  617.         end if
  618.  
  619.         mov     esi, join_header
  620.         call    print_asciiz
  621.  
  622.         mov     esi, servercommand+1
  623.         mov     bl, '!'
  624.         call    print_string
  625.  
  626.         mov     esi, joins_channel
  627.         call    print_asciiz
  628.  
  629.         pop     esi
  630.         call    print_asciiz
  631.  
  632.         mov     al, 10
  633.         call    print_char
  634.  
  635.         mov     ebx, [window_print]
  636.         mov     esi, servercommand+1
  637.         call    user_add
  638.  
  639.         ret
  640.  
  641.   .fail:
  642.         pop     esi
  643.         ret
  644.  
  645.  
  646.  
  647.  
  648. cmd_nick:
  649.  
  650.         cmp     byte[esi+4], ' '
  651.         jne     .fail
  652.         add     esi, 5          ; skip 'NICK '
  653.         cmp     byte[esi], ':'
  654.         jne     @f
  655.         inc     esi
  656.   @@:
  657.  
  658. ; Is it me who changed nick?
  659.         push    esi
  660.         mov     edi, servercommand+1
  661.         call    compare_to_nick
  662.         jne     .not_me
  663.  
  664. ; Yup, update user_nick
  665.         mov     ecx, MAX_NICK_LEN-1
  666.         mov     esi, [esp]
  667.         mov     edi, user_nick
  668.   @@:
  669.         lodsb
  670.         test    al, al
  671.         jz      @f
  672.         cmp     al, ' '
  673.         je      @f
  674.         cmp     al, 10
  675.         je      @f
  676.         cmp     al, 13
  677.         je      @f
  678.         cmp     al, ':'
  679.         je      @r
  680.         stosb
  681.         dec     ecx
  682.         jnz     @r
  683.   @@:
  684.         xor     al, al
  685.         stosb
  686.  
  687. ; Print a message on the server window
  688.         mov     [window_print], windows
  689.  
  690.         mov     esi, str_nickchange
  691.         call    print_asciiz
  692.  
  693.         mov     esi, user_nick
  694.         call    print_asciiz
  695.  
  696.         mov     al, 10
  697.         call    print_char
  698.  
  699.   .not_me:
  700.  
  701. ; Update in userlist
  702.         mov     ebx, windows
  703.         mov     ecx, MAX_WINDOWS
  704.   .window_loop:
  705.         push    ecx ebx
  706.         cmp     [ebx + window.type], WINDOWTYPE_CHANNEL
  707.         jne     .next_window
  708.  
  709.         mov     esi, servercommand+1
  710.         call    user_remove
  711.         test    edi, edi
  712.         jz      .next_window
  713.  
  714.         mov     esi, [esp + 8]
  715.         call    user_add
  716.  
  717. ; And print a notification in the channel
  718.         mov     [window_print], ebx
  719.  
  720.         if TIMESTAMP
  721.         call    print_timestamp
  722.         end if
  723.  
  724.         mov     esi, nick_header
  725.         call    print_asciiz
  726.  
  727.         mov     esi, servercommand+1
  728.         mov     bl, '!'
  729.         call    print_string
  730.  
  731.         mov     esi, is_now_known_as
  732.         call    print_asciiz
  733.  
  734.         mov     esi, [esp + 8]
  735.         call    print_asciiz
  736.  
  737.         mov     al, 10
  738.         call    print_char
  739.  
  740. ; Now do this for all open windows
  741.   .next_window:
  742.         pop     ebx ecx
  743.         add     ebx, sizeof.window
  744.         dec     ecx
  745.         jnz     .window_loop
  746.  
  747.         pop     esi
  748.  
  749.   .fail:
  750.  
  751.         ret
  752.  
  753.  
  754.  
  755.  
  756. cmd_kick:
  757.  
  758.         cmp     byte [esi+4], ' '
  759.         jne     .fail
  760.         add     esi, 5  ; skip 'KICK '
  761.  
  762. ; TODO: Is it me who got kicked?
  763. ; if so, mark channel as disconnected
  764.  
  765.   .not_me:
  766. ; find the channel user has been kicked from
  767.         push    esi
  768.         call    window_open
  769.         test    ebx, ebx
  770.         jz      .fail
  771.         push    esi
  772.  
  773.         if TIMESTAMP
  774.         call    print_timestamp
  775.         end if
  776.  
  777.         mov     esi, kick_header
  778.         call    print_asciiz
  779.  
  780.         pop     esi
  781.         mov     bl, ' '
  782.         call    print_string
  783.  
  784.         mov     esi, str_kicked
  785.         call    print_asciiz
  786.  
  787.         pop     esi
  788.         mov     bl, ' '
  789.         call    print_string
  790.  
  791.         mov     esi, str_by
  792.         call    print_asciiz
  793.  
  794.         mov     esi, servercommand+1
  795.         mov     bl, '!'
  796.         call    print_string
  797.  
  798.         mov     al, 10
  799.         call    print_char
  800.  
  801.         mov     ebx, [window_print]
  802.         mov     esi, servercommand+1
  803.         call    user_remove
  804.  
  805.         ret
  806.  
  807.   .fail:
  808.         pop     esi
  809.  
  810.         ret
  811.  
  812.  
  813.  
  814. cmd_quit:
  815.  
  816.         cmp     byte [esi+4], ' '
  817.         jne     .fail
  818.  
  819.         mov     ebx, windows
  820.         mov     ecx, MAX_WINDOWS
  821.  
  822.   .window_loop:
  823.         push    ecx
  824.         cmp     [ebx + window.type], WINDOWTYPE_CHANNEL
  825.         jne     .next_window
  826.  
  827.         mov     esi, servercommand+1
  828.         call    user_remove
  829.         test    edi, edi
  830.         jz      .next_window
  831.  
  832.         push    ebx
  833.         mov     [window_print], ebx
  834.  
  835.         if TIMESTAMP
  836.         call    print_timestamp
  837.         end if
  838.  
  839.         mov     esi, quit_header
  840.         call    print_asciiz
  841.  
  842.         mov     esi, servercommand+1
  843.         mov     bl, '!'
  844.         call    print_string
  845.  
  846.         mov     esi, has_quit_irc
  847.         call    print_asciiz
  848.  
  849. ; TODO: check if quit message was given, and print it to the window
  850.         pop     ebx
  851.   .next_window:
  852.         pop     ecx
  853.         add     ebx, sizeof.window
  854.         dec     ecx
  855.         jnz     .window_loop
  856.  
  857.   .fail:
  858.  
  859.  
  860.         ret
  861.  
  862.  
  863.  
  864. cmd_mode:
  865.  
  866.         cmp     byte [esi+4], ' '
  867.         jne     .fail
  868.         add     esi, 5  ; skip 'MODE '
  869.         push    esi
  870.         call    window_find
  871.         test    ebx, ebx
  872.         jz      .user
  873.         mov     [esp], esi
  874.         mov     [window_print], ebx
  875.  
  876.         if TIMESTAMP
  877.         call    print_timestamp
  878.         end if
  879.  
  880.         mov     esi, mode_header
  881.         call    print_asciiz
  882.  
  883.         mov     esi, servercommand+1
  884.         mov     bl, '!'
  885.         call    print_string
  886.  
  887.         mov     esi, sets_mode
  888.         call    print_asciiz
  889.  
  890.         pop     esi
  891.         call    print_asciiz
  892.  
  893.         mov     al, 10
  894.         call    print_char
  895.  
  896. ; TODO: keep track of user modes in username list
  897.  
  898.   .fail:
  899.         ret
  900.  
  901.  
  902.   .user:
  903.         if TIMESTAMP
  904.         call    print_timestamp
  905.         end if
  906.  
  907.         mov     esi, mode_header
  908.         call    print_asciiz
  909.  
  910.         mov     esi, [esp]
  911.         mov     bl, ' '
  912.         call    print_string
  913.  
  914.         mov     esi, sets_mode
  915.         call    print_asciiz
  916.  
  917.         pop     esi
  918.         call    skip_parameter
  919.         call    print_asciiz
  920.  
  921.         mov     al, 10
  922.         call    print_char
  923.  
  924.         ret
  925.  
  926.  
  927. cmd_353:                ; channel usernames reply
  928.  
  929.         add     esi, 4  ; skip '353 '
  930.         call    skip_parameter
  931.         inc     esi     ; channel type '*', '=' or '@'
  932.         inc     esi     ; ' '
  933.         call    window_open
  934.         test    ebx, ebx
  935.         jz      .fail
  936.  
  937. ; now find window ptr and check if this is the first 353 message
  938.         mov     ebx, [window_print]
  939.         test    [ebx + window.flags], FLAG_RECEIVING_NAMES
  940.         jnz     .add
  941.  
  942.         or      [ebx + window.flags], FLAG_RECEIVING_NAMES
  943. ;        mov     [ebx + window.users], 0
  944.         ; TODO: remove all users?
  945.  
  946.   .add:
  947.         push    esi
  948.         call    user_add
  949.         pop     esi
  950.  
  951.   .namesloop:
  952.         lodsb
  953.         test    al, al
  954.         jz      .done
  955.         cmp     al, ' '                 ; names list is separated with spaces
  956.         jne     .namesloop
  957.         jmp     .add
  958.  
  959.   .done:
  960.         call    draw_channel_list
  961.   .fail:
  962.  
  963.         ret
  964.  
  965.  
  966.  
  967.  
  968.  
  969. cmd_366:        ; channel usernames end
  970.  
  971.         add     esi, 4          ; skip '366 '
  972.         call    skip_parameter
  973.         call    window_open
  974.         test    ebx, ebx
  975.         jz      .fail
  976.         and     [ebx + window.flags], not FLAG_RECEIVING_NAMES
  977.   .fail:
  978.  
  979.         ret
  980.  
  981.  
  982.  
  983.  
  984. cmd_topic:
  985.  
  986.         add     esi, 4          ; skip '332 '
  987.         call    skip_parameter
  988.         call    window_open
  989.         test    ebx, ebx
  990.         jz      .fail
  991.  
  992.         if TIMESTAMP
  993.         call    print_timestamp
  994.         end if
  995.  
  996.         push    esi
  997.         mov     esi, topic_header
  998.         call    print_asciiz
  999.  
  1000.         mov     esi, str_topic
  1001.         call    print_asciiz
  1002.  
  1003.         pop     esi
  1004.         call    print_asciiz
  1005.  
  1006.         mov     esi, str_topic_end
  1007.         call    print_asciiz
  1008.  
  1009.   .fail:
  1010.  
  1011.         ret
  1012.  
  1013.  
  1014. cmd_333:
  1015.  
  1016.         add     esi, 4          ; skip '333 '
  1017.         call    skip_parameter
  1018.         call    window_open
  1019.         test    ebx, ebx
  1020.         jz      .fail
  1021.  
  1022.         if TIMESTAMP
  1023.         call    print_timestamp
  1024.         end if
  1025.  
  1026.         push    esi
  1027.         mov     esi, topic_header
  1028.         call    print_asciiz
  1029.  
  1030.         mov     esi, str_setby
  1031.         call    print_asciiz
  1032.  
  1033.         pop     esi
  1034.         mov     bl, '!'
  1035.         call    print_string
  1036.  
  1037.         mov     al, 10
  1038.         call    print_char
  1039.  
  1040.   .fail:
  1041.  
  1042.         ret
  1043.  
  1044.  
  1045.  
  1046. cmd_322:        ; LIST
  1047.  
  1048.         add     esi, 4
  1049.         call    skip_parameter
  1050.  
  1051.         push    esi
  1052.         mov     esi, str_list
  1053.         call    window_open
  1054.         test    ebx, ebx
  1055.         jz      .fail
  1056.  
  1057.         mov     [window_active], ebx
  1058.         call    draw_windowtabs
  1059.         pop     esi
  1060.         call    print_asciiz
  1061.         mov     al, 10
  1062.         call    print_char
  1063.  
  1064.         ret
  1065.  
  1066.   .fail:
  1067.         pop     esi
  1068.  
  1069.         ret
  1070.  
  1071. cmd_323:        ; LIST END
  1072.  
  1073.         ret