-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.l
executable file
·119 lines (95 loc) · 2.42 KB
/
server.l
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#!/usr/bin/picolisp /usr/lib/picolisp/lib.l
#
# Internet Chat(without relay) Server
#
# Code based on PicoLisp chat-server example by Alexander Burger
#
# (c) Alexander Sharikhin
# 20 June 17
(load "@lib/misc.l" "@lib/btree.l" "@lib/db.l")
### Configuration goes here ###
(setq *Port (port 4004))
# Code
(pool (tmp "online.db"))
# User entity & methods
(class +User +Entity)
(rel ky (+Need +Key +Number))
(rel nm (+Ref +String))
# DB method for user list
(de create-user-record (name)
(new!
'(+User)
'ky
(genKey 'ky '+User)
'nm
name ) )
(de to-list (This)
(list (: nm)) )
(de is-free (nick)
(= NIL (db 'nm '+User nick)) )
(de get-online NIL
(mapcar to-list (collect 'ky '+User)) )
(de delete-user-record (nick)
(if nick (lose!> (db 'nm '+User nick))) )
# Broadcasting.
(de chat Lst
(out *Sock (mapc prin Lst) (prinl)) )
# Private message
(de private-msg (From To Msg)
(when (and (= To *Name) Msg)
(out *Sock (prin "@" From "> " Msg) (prinl)) ) )
# Connection loop
(loop
(setq *Sock (listen *Port))
(NIL (fork) (close *Port))
(close *Sock) )
# Auth
(loop
(out *Sock (prinl "AUTH") (flush))
(in *Sock (setq *Auth (line T)))
(setq *AuthFields (mapcar pack (split (chop *Auth) " ")))
(T (is-free (car *AuthFields))) )
(setq *Name (car *AuthFields))
(unless *Name (bye))
# Authed loop
(create-user-record *Name)
# on connect list all online users
(out *Sock
(prinl "OK")
(mapc
'((usr) (prin "+") (prinl usr))
(get-online) )
(prinl) )
# tell to all that user connected
(tell 'chat "+" *Name)
# Send message. In our socket too
# Removing non-symbolic chars and not sent empty strings
(de send-public-message (Msg)
(setq Msg
(pack
(filter
'((Chr) (>= (char Chr) 32))
(chop Msg) ) ) )
(when (pack (split (chop Msg) " "))
(tell 'chat "*" *Name "> " Msg) ) )
# Send private message
(de send-private-message (To Msg)
(when Msg (tell 'private-msg *Name To Msg)) )
# Send message
(de send-message (Msg)
(setq MsgChars (chop Msg))
(ifn (= (car MsgChars) "@")
(send-public-message Msg)
(send-private-message
(pack (car (split (cdr MsgChars) " ")))
(glue " " (cdr (split (cdr MsgChars) " "))) ) ) )
# Chat loop
(task
*Sock
(in @
(ifn (eof)
(send-message (line T))
(tell 'chat "-" *Name)
(delete-user-record *Name)
(bye) ) ) )
(wait)