Subversion Repositories Kolibri OS

Rev

Rev 4623 | Rev 4982 | 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.   .not_me:
  687.  
  688. ; Update in userlist
  689.         mov     ebx, windows
  690.         mov     ecx, MAX_WINDOWS
  691.   .window_loop:
  692.         push    ecx ebx
  693.         cmp     [ebx + window.type], WINDOWTYPE_CHANNEL
  694.         jne     .next_window
  695.  
  696.         mov     esi, servercommand+1
  697.         call    user_remove
  698.         test    edi, edi
  699.         jz      .next_window
  700.  
  701.         mov     esi, [esp + 8]
  702.         call    user_add
  703.  
  704. ; And print a notification in the channel
  705.         mov     [window_print], ebx
  706.  
  707.         if TIMESTAMP
  708.         call    print_timestamp
  709.         end if
  710.  
  711.         mov     esi, nick_header
  712.         call    print_asciiz
  713.  
  714.         mov     esi, servercommand+1
  715.         mov     bl, '!'
  716.         call    print_string
  717.  
  718.         mov     esi, is_now_known_as
  719.         call    print_asciiz
  720.  
  721.         mov     esi, [esp + 8]
  722.         call    print_asciiz
  723.  
  724.         mov     al, 10
  725.         call    print_char
  726.  
  727. ; Now do this for all open windows
  728.   .next_window:
  729.         pop     ebx ecx
  730.         add     ebx, sizeof.window
  731.         dec     ecx
  732.         jnz     .window_loop
  733.  
  734.         pop     esi
  735.  
  736.   .fail:
  737.  
  738.         ret
  739.  
  740.  
  741.  
  742.  
  743. cmd_kick:
  744.  
  745.         cmp     byte [esi+4], ' '
  746.         jne     .fail
  747.         add     esi, 5  ; skip 'KICK '
  748.  
  749. ; TODO: Is it me who got kicked?
  750. ; if so, mark channel as disconnected
  751.  
  752.   .not_me:
  753. ; find the channel user has been kicked from
  754.         push    esi
  755.         call    window_open
  756.         test    ebx, ebx
  757.         jz      .fail
  758.         push    esi
  759.  
  760.         if TIMESTAMP
  761.         call    print_timestamp
  762.         end if
  763.  
  764.         mov     esi, kick_header
  765.         call    print_asciiz
  766.  
  767.         pop     esi
  768.         mov     bl, ' '
  769.         call    print_string
  770.  
  771.         mov     esi, str_kicked
  772.         call    print_asciiz
  773.  
  774.         pop     esi
  775.         mov     bl, ' '
  776.         call    print_string
  777.  
  778.         mov     esi, str_by
  779.         call    print_asciiz
  780.  
  781.         mov     esi, servercommand+1
  782.         mov     bl, '!'
  783.         call    print_string
  784.  
  785.         mov     al, 10
  786.         call    print_char
  787.  
  788.         mov     ebx, [window_print]
  789.         mov     esi, servercommand+1
  790.         call    user_remove
  791.  
  792.         ret
  793.  
  794.   .fail:
  795.         pop     esi
  796.  
  797.         ret
  798.  
  799.  
  800.  
  801. cmd_quit:
  802.  
  803.         cmp     byte [esi+4], ' '
  804.         jne     .fail
  805.  
  806.         mov     ebx, windows
  807.         mov     ecx, MAX_WINDOWS
  808.  
  809.   .window_loop:
  810.         push    ecx
  811.         cmp     [ebx + window.type], WINDOWTYPE_CHANNEL
  812.         jne     .next_window
  813.  
  814.         mov     esi, servercommand+1
  815.         call    user_remove
  816.         test    edi, edi
  817.         jz      .next_window
  818.  
  819.         push    ebx
  820.         mov     [window_print], ebx
  821.  
  822.         if TIMESTAMP
  823.         call    print_timestamp
  824.         end if
  825.  
  826.         mov     esi, quit_header
  827.         call    print_asciiz
  828.  
  829.         mov     esi, servercommand+1
  830.         mov     bl, '!'
  831.         call    print_string
  832.  
  833.         mov     esi, has_quit_irc
  834.         call    print_asciiz
  835.  
  836. ; TODO: check if quit message was given, and print it to the window
  837.         pop     ebx
  838.   .next_window:
  839.         pop     ecx
  840.         add     ebx, sizeof.window
  841.         dec     ecx
  842.         jnz     .window_loop
  843.  
  844.   .fail:
  845.  
  846.  
  847.         ret
  848.  
  849.  
  850.  
  851. cmd_mode:
  852.  
  853.         cmp     byte [esi+4], ' '
  854.         jne     .fail
  855.         add     esi, 5  ; skip 'MODE '
  856.         push    esi
  857.         call    window_find
  858.         test    ebx, ebx
  859.         jz      .user
  860.         mov     [esp], esi
  861.         mov     [window_print], ebx
  862.  
  863.         if TIMESTAMP
  864.         call    print_timestamp
  865.         end if
  866.  
  867.         mov     esi, mode_header
  868.         call    print_asciiz
  869.  
  870.         mov     esi, servercommand+1
  871.         mov     bl, '!'
  872.         call    print_string
  873.  
  874.         mov     esi, sets_mode
  875.         call    print_asciiz
  876.  
  877.         pop     esi
  878.         call    print_asciiz
  879.  
  880.         mov     al, 10
  881.         call    print_char
  882.  
  883. ; TODO: keep track of user modes in username list
  884.  
  885.   .fail:
  886.         ret
  887.  
  888.  
  889.   .user:
  890.         if TIMESTAMP
  891.         call    print_timestamp
  892.         end if
  893.  
  894.         mov     esi, mode_header
  895.         call    print_asciiz
  896.  
  897.         mov     esi, [esp]
  898.         mov     bl, ' '
  899.         call    print_string
  900.  
  901.         mov     esi, sets_mode
  902.         call    print_asciiz
  903.  
  904.         pop     esi
  905.         call    skip_parameter
  906.         call    print_asciiz
  907.  
  908.         mov     al, 10
  909.         call    print_char
  910.  
  911.         ret
  912.  
  913.  
  914. cmd_353:                ; channel usernames reply
  915.  
  916.         add     esi, 4  ; skip '353 '
  917.         call    skip_parameter
  918.         inc     esi     ; channel type '*', '=' or '@'
  919.         inc     esi     ; ' '
  920.         call    window_open
  921.         test    ebx, ebx
  922.         jz      .fail
  923.  
  924. ; now find window ptr and check if this is the first 353 message
  925.         mov     ebx, [window_print]
  926.         test    [ebx + window.flags], FLAG_RECEIVING_NAMES
  927.         jnz     .add
  928.  
  929.         or      [ebx + window.flags], FLAG_RECEIVING_NAMES
  930. ;        mov     [ebx + window.users], 0
  931.         ; TODO: remove all users?
  932.  
  933.   .add:
  934.         push    esi
  935.         call    user_add
  936.         pop     esi
  937.  
  938.   .namesloop:
  939.         lodsb
  940.         test    al, al
  941.         jz      .done
  942.         cmp     al, ' '                 ; names list is separated with spaces
  943.         jne     .namesloop
  944.         jmp     .add
  945.  
  946.   .done:
  947.         call    draw_channel_list
  948.   .fail:
  949.  
  950.         ret
  951.  
  952.  
  953.  
  954.  
  955.  
  956. cmd_366:        ; channel usernames end
  957.  
  958.         add     esi, 4          ; skip '366 '
  959.         call    skip_parameter
  960.         call    window_open
  961.         test    ebx, ebx
  962.         jz      .fail
  963.         and     [ebx + window.flags], not FLAG_RECEIVING_NAMES
  964.   .fail:
  965.  
  966.         ret
  967.  
  968.  
  969.  
  970.  
  971. cmd_topic:
  972.  
  973.         add     esi, 4          ; skip '332 '
  974.         call    skip_parameter
  975.         call    window_open
  976.         test    ebx, ebx
  977.         jz      .fail
  978.  
  979.         if TIMESTAMP
  980.         call    print_timestamp
  981.         end if
  982.  
  983.         push    esi
  984.         mov     esi, topic_header
  985.         call    print_asciiz
  986.  
  987.         mov     esi, str_topic
  988.         call    print_asciiz
  989.  
  990.         pop     esi
  991.         call    print_asciiz
  992.  
  993.         mov     esi, str_topic_end
  994.         call    print_asciiz
  995.  
  996.   .fail:
  997.  
  998.         ret
  999.  
  1000.  
  1001. cmd_333:
  1002.  
  1003.         add     esi, 4          ; skip '333 '
  1004.         call    skip_parameter
  1005.         call    window_open
  1006.         test    ebx, ebx
  1007.         jz      .fail
  1008.  
  1009.         if TIMESTAMP
  1010.         call    print_timestamp
  1011.         end if
  1012.  
  1013.         push    esi
  1014.         mov     esi, topic_header
  1015.         call    print_asciiz
  1016.  
  1017.         mov     esi, str_setby
  1018.         call    print_asciiz
  1019.  
  1020.         pop     esi
  1021.         mov     bl, '!'
  1022.         call    print_string
  1023.  
  1024.         mov     al, 10
  1025.         call    print_char
  1026.  
  1027.   .fail:
  1028.  
  1029.         ret
  1030.  
  1031.  
  1032.  
  1033. cmd_322:        ; LIST
  1034.  
  1035.         add     esi, 4
  1036.         call    skip_parameter
  1037.  
  1038.         push    esi
  1039.         mov     esi, str_list
  1040.         call    window_open
  1041.         test    ebx, ebx
  1042.         jz      .fail
  1043.  
  1044.         mov     [window_active], ebx
  1045.         call    draw_windowtabs
  1046.         pop     esi
  1047.         call    print_asciiz
  1048.         mov     al, 10
  1049.         call    print_char
  1050.  
  1051.         ret
  1052.  
  1053.   .fail:
  1054.         pop     esi
  1055.  
  1056.         ret
  1057.  
  1058. cmd_323:        ; LIST END
  1059.  
  1060.         ret