123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- // Network stuff for HaxServ
- //
- // Written by: Test_User <hax@andrewyu.org>
- //
- // This is free and unencumbered software released into the public
- // domain.
- //
- // Anyone is free to copy, modify, publish, use, compile, sell, or
- // distribute this software, either in source code form or as a compiled
- // binary, for any purpose, commercial or non-commercial, and by any
- // means.
- //
- // In jurisdictions that recognize copyright laws, the author or authors
- // of this software dedicate any and all copyright interest in the
- // software to the public domain. We make this dedication for the benefit
- // of the public at large and to the detriment of our heirs and
- // successors. We intend this dedication to be an overt act of
- // relinquishment in perpetuity of all present and future rights to this
- // software under copyright law.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- // OTHER DEALINGS IN THE SOFTWARE.
- #include <string.h>
- #include <limits.h>
- #include <stdlib.h>
- #include "network.h"
- #include "tls.h"
- #include "config.h"
- char channel_mode_types[UCHAR_MAX+1] = {
- ['v'] = MODE_TYPE_USERS,
- ['h'] = MODE_TYPE_USERS,
- ['o'] = MODE_TYPE_USERS,
- ['a'] = MODE_TYPE_USERS,
- ['q'] = MODE_TYPE_USERS,
- ['b'] = MODE_TYPE_MULTIPLE,
- ['e'] = MODE_TYPE_MULTIPLE,
- ['I'] = MODE_TYPE_MULTIPLE,
- ['c'] = MODE_TYPE_NOARGS,
- ['d'] = MODE_TYPE_REPLACE,
- ['f'] = MODE_TYPE_REPLACE,
- ['g'] = MODE_TYPE_MULTIPLE,
- ['i'] = MODE_TYPE_NOARGS,
- ['j'] = MODE_TYPE_REPLACE,
- ['k'] = MODE_TYPE_REPLACE,
- ['l'] = MODE_TYPE_REPLACE,
- ['m'] = MODE_TYPE_NOARGS,
- ['n'] = MODE_TYPE_NOARGS,
- ['p'] = MODE_TYPE_NOARGS,
- ['r'] = MODE_TYPE_NOARGS,
- ['s'] = MODE_TYPE_NOARGS,
- ['t'] = MODE_TYPE_NOARGS,
- ['u'] = MODE_TYPE_NOARGS,
- ['w'] = MODE_TYPE_MULTIPLE,
- ['z'] = MODE_TYPE_NOARGS,
- ['A'] = MODE_TYPE_NOARGS,
- ['B'] = MODE_TYPE_NOARGS,
- ['C'] = MODE_TYPE_NOARGS,
- ['D'] = MODE_TYPE_NOARGS,
- ['E'] = MODE_TYPE_REPLACE,
- ['F'] = MODE_TYPE_REPLACE,
- ['G'] = MODE_TYPE_NOARGS,
- ['H'] = MODE_TYPE_REPLACE,
- ['J'] = MODE_TYPE_REPLACE,
- ['K'] = MODE_TYPE_NOARGS,
- ['L'] = MODE_TYPE_REPLACE,
- ['M'] = MODE_TYPE_NOARGS,
- ['N'] = MODE_TYPE_NOARGS,
- ['O'] = MODE_TYPE_NOARGS,
- ['P'] = MODE_TYPE_NOARGS,
- ['Q'] = MODE_TYPE_NOARGS,
- ['R'] = MODE_TYPE_NOARGS,
- ['S'] = MODE_TYPE_NOARGS,
- ['T'] = MODE_TYPE_NOARGS,
- ['X'] = MODE_TYPE_MULTIPLE,
- };
- int privmsg(struct string source, struct string target, size_t num_message_parts, struct string message[num_message_parts]) {
- if (!STRING_EQ(target, STRING("1HC000001"))) { // if not sending to our one local user
- if (source.len != 0) {
- SEND(STRING(":"));
- SEND(source);
- SEND(STRING(" PRIVMSG "));
- } else {
- SEND(STRING("PRIVMSG "));
- }
- SEND(target);
- SEND(STRING(" :"));
- for (size_t i = 0; i < num_message_parts; i++)
- SEND(message[i]);
- SEND(STRING("\n"));
- } else {
- goto privmsg_client;
- }
- if (target.data[0] == '#') {
- struct channel_info *channel = get_table_index(channel_list, target);
- if (channel && has_table_index(channel->user_list, STRING("1HC000001")))
- goto privmsg_client;
- }
- return 0;
- privmsg_client:
- if (source.len != 0) {
- SENDCLIENT(STRING(":"));
- // TODO: Proper lookups of users and such
- if (STRING_EQ(source, STRING("1HC000000"))) {
- SENDCLIENT(nick);
- SENDCLIENT(STRING("!"));
- SENDCLIENT(nick);
- SENDCLIENT(STRING("@"));
- SENDCLIENT(hostmask);
- } else if (STRING_EQ(source, STRING("1HC"))) {
- SENDCLIENT(server_name);
- } else {
- SENDCLIENT(source);
- }
- SENDCLIENT(STRING(" PRIVMSG "));
- } else {
- SENDCLIENT(STRING(":"));
- SENDCLIENT(server_name);
- SENDCLIENT(STRING(" PRIVMSG "));
- }
- if (STRING_EQ(target, STRING("1HC000001")))
- SENDCLIENT(client_nick);
- else
- SENDCLIENT(target);
- SENDCLIENT(STRING(" :"));
- for (size_t i = 0; i < num_message_parts; i++)
- SENDCLIENT(message[i]);
- SENDCLIENT(STRING("\r\n"));
- return 0;
- }
- int remove_user(struct string uid, struct string reason) { // If disconnecting the local client, set client_connected = 0 *before* calling this
- struct user_info *info = get_table_index(user_list, uid);
- if (!info)
- return 1;
- int send_client = client_connected;
- for (uint64_t i = 0; i < channel_list.len; i++) { // TODO: Use channel list attached to the user (doesn't exist yet)
- struct channel_info *chan_info = channel_list.array[i].ptr;
- if (has_table_index(chan_info->user_list, uid)) {
- if (send_client && has_table_index(chan_info->user_list, STRING("1HC000001"))) {
- SENDCLIENT(STRING(":"));
- SENDCLIENT(info->nick);
- SENDCLIENT(STRING("!"));
- SENDCLIENT(info->ident);
- SENDCLIENT(STRING("@"));
- SENDCLIENT(info->vhost);
- if (reason.len != 0) {
- SENDCLIENT(STRING(" QUIT :"));
- SENDCLIENT(reason);
- SENDCLIENT(STRING("\r\n"));
- } else {
- SENDCLIENT(STRING(" QUIT\r\n"));
- }
- send_client = 0;
- }
- remove_table_index(&(chan_info->user_list), uid);
- }
- }
- remove_table_index(&user_list, uid);
- free(info->server.data);
- free(info->nick.data);
- free(info->opertype.data);
- free(info->metadata.array);
- free(info->realname.data);
- free(info->hostname.data);
- free(info->ip.data);
- free(info->ident.data);
- free(info->vhost.data);
- free(info);
- return 0;
- }
|