Subversion Repositories Kolibri OS

Rev

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

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