Subversion Repositories Kolibri OS

Rev

Rev 3981 | Go to most recent revision | Details | Last modification | View Log | RSS feed

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