free bugs [fixed]
[coupserv.git] / general_network.c
blob335bfa85c7988ed93403cd7868529b19a52983f2
1 // Network stuff for HaxServ
2 //
3 // Written by: Test_User <hax@andrewyu.org>
4 //
5 // This is free and unencumbered software released into the public
6 // domain.
7 //
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
11 // means.
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.
29 #include <string.h>
30 #include <limits.h>
31 #include <stdlib.h>
33 #include "network.h"
34 #include "tls.h"
35 #include "config.h"
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) {
88 SEND(STRING(":"));
89 SEND(source);
90 SEND(STRING(" PRIVMSG "));
91 } else {
92 SEND(STRING("PRIVMSG "));
95 SEND(target);
96 SEND(STRING(" :"));
97 for (size_t i = 0; i < num_message_parts; i++)
98 SEND(message[i]);
99 SEND(STRING("\n"));
100 } else {
101 goto privmsg_client;
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")))
107 goto privmsg_client;
110 return 0;
112 privmsg_client:
114 if (source.len != 0) {
115 SENDCLIENT(STRING(":"));
116 // TODO: Proper lookups of users and such
117 if (STRING_EQ(source, STRING("1HC000000"))) {
118 SENDCLIENT(nick);
119 SENDCLIENT(STRING("!"));
120 SENDCLIENT(nick);
121 SENDCLIENT(STRING("@"));
122 SENDCLIENT(hostmask);
123 } else if (STRING_EQ(source, STRING("1HC"))) {
124 SENDCLIENT(server_name);
125 } else {
126 SENDCLIENT(source);
128 SENDCLIENT(STRING(" PRIVMSG "));
129 } else {
130 SENDCLIENT(STRING(":"));
131 SENDCLIENT(server_name);
132 SENDCLIENT(STRING(" PRIVMSG "));
135 if (STRING_EQ(target, STRING("1HC000001")))
136 SENDCLIENT(client_nick);
137 else
138 SENDCLIENT(target);
140 SENDCLIENT(STRING(" :"));
141 for (size_t i = 0; i < num_message_parts; i++)
142 SENDCLIENT(message[i]);
143 SENDCLIENT(STRING("\r\n"));
145 return 0;
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);
150 if (!info)
151 return 1;
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 :"));
166 SENDCLIENT(reason);
167 SENDCLIENT(STRING("\r\n"));
168 } else {
169 SENDCLIENT(STRING(" QUIT\r\n"));
172 send_client = 0;
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);
187 free(info->ip.data);
188 free(info->ident.data);
189 free(info->vhost.data);
190 free(info);
192 return 0;