1 // Network stuff for HaxServ
3 // Written by: Test_User <hax@andrewyu.org>
5 // This is free and unencumbered software released into the public
8 // Anyone is free to copy, modify, publish, use, compile, sell, or
9 // distribute this software, either in source code form or as a compiled
10 // binary, for any purpose, commercial or non-commercial, and by any
13 // In jurisdictions that recognize copyright laws, the author or authors
14 // of this software dedicate any and all copyright interest in the
15 // software to the public domain. We make this dedication for the benefit
16 // of the public at large and to the detriment of our heirs and
17 // successors. We intend this dedication to be an overt act of
18 // relinquishment in perpetuity of all present and future rights to this
19 // software under copyright law.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 // OTHER DEALINGS IN THE SOFTWARE.
37 char channel_mode_types
[UCHAR_MAX
+1] = {
38 ['v'] = MODE_TYPE_USERS
,
39 ['h'] = MODE_TYPE_USERS
,
40 ['o'] = MODE_TYPE_USERS
,
41 ['a'] = MODE_TYPE_USERS
,
42 ['q'] = MODE_TYPE_USERS
,
43 ['b'] = MODE_TYPE_MULTIPLE
,
44 ['e'] = MODE_TYPE_MULTIPLE
,
45 ['I'] = MODE_TYPE_MULTIPLE
,
46 ['c'] = MODE_TYPE_NOARGS
,
47 ['d'] = MODE_TYPE_REPLACE
,
48 ['f'] = MODE_TYPE_REPLACE
,
49 ['g'] = MODE_TYPE_MULTIPLE
,
50 ['i'] = MODE_TYPE_NOARGS
,
51 ['j'] = MODE_TYPE_REPLACE
,
52 ['k'] = MODE_TYPE_REPLACE
,
53 ['l'] = MODE_TYPE_REPLACE
,
54 ['m'] = MODE_TYPE_NOARGS
,
55 ['n'] = MODE_TYPE_NOARGS
,
56 ['p'] = MODE_TYPE_NOARGS
,
57 ['r'] = MODE_TYPE_NOARGS
,
58 ['s'] = MODE_TYPE_NOARGS
,
59 ['t'] = MODE_TYPE_NOARGS
,
60 ['u'] = MODE_TYPE_NOARGS
,
61 ['w'] = MODE_TYPE_MULTIPLE
,
62 ['z'] = MODE_TYPE_NOARGS
,
63 ['A'] = MODE_TYPE_NOARGS
,
64 ['B'] = MODE_TYPE_NOARGS
,
65 ['C'] = MODE_TYPE_NOARGS
,
66 ['D'] = MODE_TYPE_NOARGS
,
67 ['E'] = MODE_TYPE_REPLACE
,
68 ['F'] = MODE_TYPE_REPLACE
,
69 ['G'] = MODE_TYPE_NOARGS
,
70 ['H'] = MODE_TYPE_REPLACE
,
71 ['J'] = MODE_TYPE_REPLACE
,
72 ['K'] = MODE_TYPE_NOARGS
,
73 ['L'] = MODE_TYPE_REPLACE
,
74 ['M'] = MODE_TYPE_NOARGS
,
75 ['N'] = MODE_TYPE_NOARGS
,
76 ['O'] = MODE_TYPE_NOARGS
,
77 ['P'] = MODE_TYPE_NOARGS
,
78 ['Q'] = MODE_TYPE_NOARGS
,
79 ['R'] = MODE_TYPE_NOARGS
,
80 ['S'] = MODE_TYPE_NOARGS
,
81 ['T'] = MODE_TYPE_NOARGS
,
82 ['X'] = MODE_TYPE_MULTIPLE
,
85 int privmsg(struct string source
, struct string target
, size_t num_message_parts
, struct string message
[num_message_parts
]) {
86 if (!STRING_EQ(target
, STRING("1HC000001"))) { // if not sending to our one local user
87 if (source
.len
!= 0) {
90 SEND(STRING(" PRIVMSG "));
92 SEND(STRING("PRIVMSG "));
97 for (size_t i
= 0; i
< num_message_parts
; i
++)
104 if (target
.data
[0] == '#') {
105 struct channel_info
*channel
= get_table_index(channel_list
, target
);
106 if (channel
&& has_table_index(channel
->user_list
, STRING("1HC000001")))
114 if (source
.len
!= 0) {
115 SENDCLIENT(STRING(":"));
116 // TODO: Proper lookups of users and such
117 if (STRING_EQ(source
, STRING("1HC000000"))) {
119 SENDCLIENT(STRING("!"));
121 SENDCLIENT(STRING("@"));
122 SENDCLIENT(hostmask
);
123 } else if (STRING_EQ(source
, STRING("1HC"))) {
124 SENDCLIENT(server_name
);
128 SENDCLIENT(STRING(" PRIVMSG "));
130 SENDCLIENT(STRING(":"));
131 SENDCLIENT(server_name
);
132 SENDCLIENT(STRING(" PRIVMSG "));
135 if (STRING_EQ(target
, STRING("1HC000001")))
136 SENDCLIENT(client_nick
);
140 SENDCLIENT(STRING(" :"));
141 for (size_t i
= 0; i
< num_message_parts
; i
++)
142 SENDCLIENT(message
[i
]);
143 SENDCLIENT(STRING("\r\n"));
148 int remove_user(struct string uid
, struct string reason
) { // If disconnecting the local client, set client_connected = 0 *before* calling this
149 struct user_info
*info
= get_table_index(user_list
, uid
);
153 int send_client
= client_connected
;
154 for (uint64_t i
= 0; i
< channel_list
.len
; i
++) { // TODO: Use channel list attached to the user (doesn't exist yet)
155 struct channel_info
*chan_info
= channel_list
.array
[i
].ptr
;
156 if (has_table_index(chan_info
->user_list
, uid
)) {
157 if (send_client
&& has_table_index(chan_info
->user_list
, STRING("1HC000001"))) {
158 SENDCLIENT(STRING(":"));
159 SENDCLIENT(info
->nick
);
160 SENDCLIENT(STRING("!"));
161 SENDCLIENT(info
->ident
);
162 SENDCLIENT(STRING("@"));
163 SENDCLIENT(info
->vhost
);
164 if (reason
.len
!= 0) {
165 SENDCLIENT(STRING(" QUIT :"));
167 SENDCLIENT(STRING("\r\n"));
169 SENDCLIENT(STRING(" QUIT\r\n"));
175 remove_table_index(&(chan_info
->user_list
), uid
);
179 remove_table_index(&user_list
, uid
);
181 free(info
->server
.data
);
182 free(info
->nick
.data
);
183 free(info
->opertype
.data
);
184 free(info
->metadata
.array
);
185 free(info
->realname
.data
);
186 free(info
->hostname
.data
);
188 free(info
->ident
.data
);
189 free(info
->vhost
.data
);