general_network.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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.
  12. //
  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.
  20. //
  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.
  28. #include <string.h>
  29. #include <limits.h>
  30. #include <stdlib.h>
  31. #include "network.h"
  32. #include "tls.h"
  33. #include "config.h"
  34. char channel_mode_types[UCHAR_MAX+1] = {
  35. ['v'] = MODE_TYPE_USERS,
  36. ['h'] = MODE_TYPE_USERS,
  37. ['o'] = MODE_TYPE_USERS,
  38. ['a'] = MODE_TYPE_USERS,
  39. ['q'] = MODE_TYPE_USERS,
  40. ['b'] = MODE_TYPE_MULTIPLE,
  41. ['e'] = MODE_TYPE_MULTIPLE,
  42. ['I'] = MODE_TYPE_MULTIPLE,
  43. ['c'] = MODE_TYPE_NOARGS,
  44. ['d'] = MODE_TYPE_REPLACE,
  45. ['f'] = MODE_TYPE_REPLACE,
  46. ['g'] = MODE_TYPE_MULTIPLE,
  47. ['i'] = MODE_TYPE_NOARGS,
  48. ['j'] = MODE_TYPE_REPLACE,
  49. ['k'] = MODE_TYPE_REPLACE,
  50. ['l'] = MODE_TYPE_REPLACE,
  51. ['m'] = MODE_TYPE_NOARGS,
  52. ['n'] = MODE_TYPE_NOARGS,
  53. ['p'] = MODE_TYPE_NOARGS,
  54. ['r'] = MODE_TYPE_NOARGS,
  55. ['s'] = MODE_TYPE_NOARGS,
  56. ['t'] = MODE_TYPE_NOARGS,
  57. ['u'] = MODE_TYPE_NOARGS,
  58. ['w'] = MODE_TYPE_MULTIPLE,
  59. ['z'] = MODE_TYPE_NOARGS,
  60. ['A'] = MODE_TYPE_NOARGS,
  61. ['B'] = MODE_TYPE_NOARGS,
  62. ['C'] = MODE_TYPE_NOARGS,
  63. ['D'] = MODE_TYPE_NOARGS,
  64. ['E'] = MODE_TYPE_REPLACE,
  65. ['F'] = MODE_TYPE_REPLACE,
  66. ['G'] = MODE_TYPE_NOARGS,
  67. ['H'] = MODE_TYPE_REPLACE,
  68. ['J'] = MODE_TYPE_REPLACE,
  69. ['K'] = MODE_TYPE_NOARGS,
  70. ['L'] = MODE_TYPE_REPLACE,
  71. ['M'] = MODE_TYPE_NOARGS,
  72. ['N'] = MODE_TYPE_NOARGS,
  73. ['O'] = MODE_TYPE_NOARGS,
  74. ['P'] = MODE_TYPE_NOARGS,
  75. ['Q'] = MODE_TYPE_NOARGS,
  76. ['R'] = MODE_TYPE_NOARGS,
  77. ['S'] = MODE_TYPE_NOARGS,
  78. ['T'] = MODE_TYPE_NOARGS,
  79. ['X'] = MODE_TYPE_MULTIPLE,
  80. };
  81. int privmsg(struct string source, struct string target, size_t num_message_parts, struct string message[num_message_parts]) {
  82. if (!STRING_EQ(target, STRING("1HC000001"))) { // if not sending to our one local user
  83. if (source.len != 0) {
  84. SEND(STRING(":"));
  85. SEND(source);
  86. SEND(STRING(" PRIVMSG "));
  87. } else {
  88. SEND(STRING("PRIVMSG "));
  89. }
  90. SEND(target);
  91. SEND(STRING(" :"));
  92. for (size_t i = 0; i < num_message_parts; i++)
  93. SEND(message[i]);
  94. SEND(STRING("\n"));
  95. } else {
  96. goto privmsg_client;
  97. }
  98. if (target.data[0] == '#') {
  99. struct channel_info *channel = get_table_index(channel_list, target);
  100. if (channel && has_table_index(channel->user_list, STRING("1HC000001")))
  101. goto privmsg_client;
  102. }
  103. return 0;
  104. privmsg_client:
  105. if (source.len != 0) {
  106. SENDCLIENT(STRING(":"));
  107. // TODO: Proper lookups of users and such
  108. if (STRING_EQ(source, STRING("1HC000000"))) {
  109. SENDCLIENT(nick);
  110. SENDCLIENT(STRING("!"));
  111. SENDCLIENT(nick);
  112. SENDCLIENT(STRING("@"));
  113. SENDCLIENT(hostmask);
  114. } else if (STRING_EQ(source, STRING("1HC"))) {
  115. SENDCLIENT(server_name);
  116. } else {
  117. SENDCLIENT(source);
  118. }
  119. SENDCLIENT(STRING(" PRIVMSG "));
  120. } else {
  121. SENDCLIENT(STRING(":"));
  122. SENDCLIENT(server_name);
  123. SENDCLIENT(STRING(" PRIVMSG "));
  124. }
  125. if (STRING_EQ(target, STRING("1HC000001")))
  126. SENDCLIENT(client_nick);
  127. else
  128. SENDCLIENT(target);
  129. SENDCLIENT(STRING(" :"));
  130. for (size_t i = 0; i < num_message_parts; i++)
  131. SENDCLIENT(message[i]);
  132. SENDCLIENT(STRING("\r\n"));
  133. return 0;
  134. }
  135. int remove_user(struct string uid, struct string reason) { // If disconnecting the local client, set client_connected = 0 *before* calling this
  136. struct user_info *info = get_table_index(user_list, uid);
  137. if (!info)
  138. return 1;
  139. int send_client = client_connected;
  140. for (uint64_t i = 0; i < channel_list.len; i++) { // TODO: Use channel list attached to the user (doesn't exist yet)
  141. struct channel_info *chan_info = channel_list.array[i].ptr;
  142. if (has_table_index(chan_info->user_list, uid)) {
  143. if (send_client && has_table_index(chan_info->user_list, STRING("1HC000001"))) {
  144. SENDCLIENT(STRING(":"));
  145. SENDCLIENT(info->nick);
  146. SENDCLIENT(STRING("!"));
  147. SENDCLIENT(info->ident);
  148. SENDCLIENT(STRING("@"));
  149. SENDCLIENT(info->vhost);
  150. if (reason.len != 0) {
  151. SENDCLIENT(STRING(" QUIT :"));
  152. SENDCLIENT(reason);
  153. SENDCLIENT(STRING("\r\n"));
  154. } else {
  155. SENDCLIENT(STRING(" QUIT\r\n"));
  156. }
  157. send_client = 0;
  158. }
  159. remove_table_index(&(chan_info->user_list), uid);
  160. }
  161. }
  162. remove_table_index(&user_list, uid);
  163. free(info->server.data);
  164. free(info->nick.data);
  165. free(info->opertype.data);
  166. free(info->metadata.array);
  167. free(info->realname.data);
  168. free(info->hostname.data);
  169. free(info->ip.data);
  170. free(info->ident.data);
  171. free(info->vhost.data);
  172. free(info);
  173. return 0;
  174. }