summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTest_User <hax@andrewyu.org>2023-08-08 03:25:57 -0400
committerTest_User <hax@andrewyu.org>2023-08-08 03:25:57 -0400
commitc660db6c36ce50e2aa1c3ec99cb62d9aaf3c0102 (patch)
tree5a3ea9c5697b149d1f4fec1f50b51913aeff928e
parentfdf8e0a8f2561bd53dbfa65b5716ea916d5871b7 (diff)
downloadcoupserv-c660db6c36ce50e2aa1c3ec99cb62d9aaf3c0102.tar.gz
coupserv-c660db6c36ce50e2aa1c3ec99cb62d9aaf3c0102.zip
User lists for channels and such
-rw-r--r--client_network.c55
-rw-r--r--general_network.c49
-rw-r--r--network.h15
-rw-r--r--server_network.c211
4 files changed, 274 insertions, 56 deletions
diff --git a/client_network.c b/client_network.c
index bbeaec3..ca82379 100644
--- a/client_network.c
+++ b/client_network.c
@@ -43,8 +43,6 @@
#include "table.h"
#include "tls.h"
-// TODO: Lock sends (everywhere)
-
struct table client_network_commands = {0};
struct string client_nick = {0};
uint8_t client_connected;
@@ -111,7 +109,7 @@ int client_user_handler(uint64_t argc, struct string *argv) {
SENDCLIENT(STRING(":hax.irc.andrewyu.org 001 "));
SENDCLIENT(client_nick);
- SENDCLIENT(STRING(" :Welcome to the RunxiIRC Network\r\n"));
+ SENDCLIENT(STRING(" :Welcome to the Rexnet IRC Network\r\n"));
SENDCLIENT(STRING(":hax.irc.andrewyu.org 002 "));
SENDCLIENT(client_nick);
SENDCLIENT(STRING(" :Your host is hax.irc.andrewyu.org, running a totally not sus IRCd\r\n"));
@@ -153,7 +151,6 @@ int client_join_handler(uint64_t argc, struct string *argv) {
}
current_time = (uint64_t)ctime;
}
- snprintf(current_time_nulstr, 22, "%lu", time(NULL));
struct string channels = argv[0];
while (1) {
@@ -174,6 +171,8 @@ int client_join_handler(uint64_t argc, struct string *argv) {
}
*channel_info = (struct channel_info){
.ts = current_time,
+ .topic = {.data = malloc(0), .len = 0},
+ .topic_ts = 0,
.modes = {.array = malloc(0), .len = 0},
.user_list = {.array = malloc(0), .len = 0},
.metadata = {.array = malloc(0), .len = 0},
@@ -181,33 +180,37 @@ int client_join_handler(uint64_t argc, struct string *argv) {
set_table_index(&channel_list, channels, channel_info);
}
+ if (channel_info->ts < current_time)
+ current_time = channel_info->ts;
- set_table_index(&(channel_info->user_list), STRING("1HC000001"), get_table_index(user_list, STRING("1HC000001"))); // TODO: Actually add local users to that
+ snprintf(current_time_nulstr, 22, "%lu", current_time);
SENDCLIENT(STRING(":"));
SENDCLIENT(client_nick);
SENDCLIENT(STRING("!e@e JOIN :"));
SENDCLIENT(channels);
+ for (uint64_t i = 0; i < channel_info->user_list.len; i++) {
+ struct string user;
+ struct user_info *info = channel_info->user_list.array[i].ptr;
+ if (info)
+ user = info->nick;
+ else
+ user = user_list.array[i].name;
+
+ if (i%5 != 0) {
+ SENDCLIENT(STRING(" "));
+ SENDCLIENT(user);
+ } else {
+ SENDCLIENT(STRING("\r\n"));
+ SENDCLIENT(STRING(":hax.irc.andrewyu.org 353 "));
+ SENDCLIENT(client_nick);
+ SENDCLIENT(STRING(" = "));
+ SENDCLIENT(channels);
+ SENDCLIENT(STRING(" :"));
+ SENDCLIENT(user);
+ }
+ }
SENDCLIENT(STRING("\r\n"));
- SENDCLIENT(STRING(":hax.irc.andrewyu.org 332 "));
- SENDCLIENT(client_nick);
- SENDCLIENT(STRING(" "));
- SENDCLIENT(channels);
- SENDCLIENT(STRING(" :\r\n")); // TODO: Actual topic
- SENDCLIENT(STRING(":hax.irc.andrewyu.org 333 "));
- SENDCLIENT(client_nick);
- SENDCLIENT(STRING(" "));
- SENDCLIENT(channels);
- SENDCLIENT(STRING(" "));
- SENDCLIENT(client_nick); // TODO: Actual channel creator
- SENDCLIENT(STRING(" :"));
- SENDCLIENT(((struct string){.data = current_time_nulstr, .len = strlen(current_time_nulstr)}));
- SENDCLIENT(STRING("\r\n"));
- SENDCLIENT(STRING(":hax.irc.andrewyu.org 353 "));
- SENDCLIENT(client_nick);
- SENDCLIENT(STRING(" = "));
- SENDCLIENT(channels);
- SENDCLIENT(STRING(" :\r\n")); // TODO: NAMES list
SENDCLIENT(STRING(":hax.irc.andrewyu.org 366 "));
SENDCLIENT(client_nick);
SENDCLIENT(STRING(" "));
@@ -218,7 +221,9 @@ int client_join_handler(uint64_t argc, struct string *argv) {
SEND(channels);
SEND(STRING(" "));
SEND(((struct string){.data = current_time_nulstr, .len = strlen(current_time_nulstr)}));
- SEND(STRING(" +Cnt :,1HC000001\n"));
+ SEND(STRING(" + :,1HC000001\n"));
+
+ set_table_index(&(channel_info->user_list), STRING("1HC000001"), get_table_index(user_list, STRING("1HC000001"))); // TODO: Actually add local users to user_list
channels.len = oldlen;
diff --git a/general_network.c b/general_network.c
index 63d3d7d..9da36ce 100644
--- a/general_network.c
+++ b/general_network.c
@@ -27,11 +27,60 @@
// OTHER DEALINGS IN THE SOFTWARE.
#include <string.h>
+#include <limits.h>
#include "network.h"
#include "tls.h"
#include "config.h"
+char channel_mode_types[UCHAR_MAX] = {
+ ['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, struct string message) {
if (!(target.len == 9 && memcmp(target.data, "1HC000001", 9) == 0)) { // if not sending to our one local user
if (source.len != 0) {
diff --git a/network.h b/network.h
index 67d308d..7682ed4 100644
--- a/network.h
+++ b/network.h
@@ -30,12 +30,13 @@
#include <netinet/in.h>
#include <pthread.h>
+#include <limits.h>
#include "types.h"
#include "table.h"
// ID is the index you got this from
-struct remote_server {
+struct server_info {
uint64_t distance; // gl if you exceed this
struct string address;
@@ -69,6 +70,9 @@ struct user_info {
struct channel_info {
uint64_t ts;
+ struct string topic;
+ uint64_t topic_ts;
+
struct table modes; // TODO: Parse modes properly
struct table user_list; // points to corresponding user_info struct (if available, currently not)
@@ -93,6 +97,15 @@ extern int resolve(char* address, char* port, struct sockaddr *server);
extern int initservernetwork(void);
extern int initclientnetwork(void);
+#define MODE_TYPE_UNKNOWN 0
+#define MODE_TYPE_NOARGS 1
+#define MODE_TYPE_REPLACE 2
+#define MODE_TYPE_MULTIPLE 3
+// Mode goes away when the user leaves the channel
+#define MODE_TYPE_USERS 4
+
+extern char channel_mode_types[UCHAR_MAX];
+
#define SENDCLIENT(x) write(client_fd, x.data, x.len)
extern int PRIVMSG(struct string source, struct string target, struct string message);
diff --git a/server_network.c b/server_network.c
index cf7c435..3b58e70 100644
--- a/server_network.c
+++ b/server_network.c
@@ -117,7 +117,7 @@ int server_handler(struct string sender, uint64_t argc, struct string *argv) {
}
if (sender.len != 0) {
- struct remote_server *from = get_table_index(server_list, sender);
+ struct server_info *from = get_table_index(server_list, sender);
if (!from) {
puts("Invalid SERVER recieved! (Unknown source)");
return 1;
@@ -147,7 +147,7 @@ int server_handler(struct string sender, uint64_t argc, struct string *argv) {
name.len = argv[4].len;
memcpy(name.data, argv[4].data, argv[4].len);
- struct remote_server *server = malloc(sizeof(*server));
+ struct server_info *server = malloc(sizeof(*server));
if (server == 0)
goto server_handler_free_name;
@@ -163,7 +163,7 @@ int server_handler(struct string sender, uint64_t argc, struct string *argv) {
via = (struct string){0};
}
- *server = (struct remote_server){
+ *server = (struct server_info){
.name = name,
.address = address,
.distance = distance,
@@ -360,6 +360,25 @@ int quit_handler(struct string sender, uint64_t argc, struct string *argv) {
return 1;
}
+ 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, STRING("1HC000001"))) {
+ SENDCLIENT(STRING(":"));
+ SENDCLIENT(info->nick);
+ SENDCLIENT(STRING("!"));
+ SENDCLIENT(info->ident);
+ SENDCLIENT(STRING("@"));
+ SENDCLIENT(info->vhost);
+ if (argc >= 1) {
+ SENDCLIENT(STRING(" QUIT :"));
+ SENDCLIENT(argv[0]);
+ SENDCLIENT(STRING("\r\n"));
+ } else {
+ SENDCLIENT(STRING(" QUIT\r\n"));
+ }
+ }
+ }
+
free(info->server.data);
free(info->nick.data);
if (info->opertype.len)
@@ -431,6 +450,23 @@ int nick_handler(struct string sender, uint64_t argc, struct string *argv) {
return 1;
}
+ for (uint64_t i = 0; i < channel_list.len; i++) { // TODO: More efficient way of doing this
+ struct channel_info *channel = channel_list.array[i].ptr;
+ if (has_table_index(channel->user_list, sender) && has_table_index(channel->user_list, STRING("1HC000001"))) {
+ SENDCLIENT(STRING(":"));
+ SENDCLIENT(info->nick);
+ SENDCLIENT(STRING("!"));
+ SENDCLIENT(info->ident);
+ SENDCLIENT(STRING("@"));
+ SENDCLIENT(info->vhost);
+ SENDCLIENT(STRING(" NICK :"));
+ SENDCLIENT(argv[0]);
+ SENDCLIENT(STRING("\r\n"));
+
+ break;
+ }
+ }
+
void *tmp = malloc(argv[0].len);
if (!tmp) {
WRITES(2, STRING("OOM! (nick_handler)\n"));
@@ -464,38 +500,101 @@ int fjoin_handler(struct string sender, uint64_t argc, struct string *argv) {
return 1;
}
-// uint8_t err;
-// uint64_t timestamp = str_to_unsigned(argv[1], &err);
-// if (err) {
-// WRITES(2, STRING("Invalid FJOIN recieved! (Invalid timestamp given)\n"));
-// return 1;
-// }
-//
-// // TODO: Parse modes, then make the rest of this work
-//
-//
-// struct channel_info *channel = get_table_index(channel_list, argv[0]);
-// if (!channel) {
-// channel = malloc(sizeof(*channel));
-// if (!channel) {
-// WRITES(2, STRING("OOM! (fjoin_handler)\n"));
-// return 1;
-// }
-// *channel = (struct channel_info){
-// .ts = timestamp,
-//
-//
-// set_table_index(&channel_list, argv[0], channel);
-//
-//
-// }
+ uint8_t err;
+ uint64_t timestamp = str_to_unsigned(argv[1], &err);
+ if (err) {
+ WRITES(2, STRING("Invalid FJOIN recieved! (Invalid timestamp given)\n"));
+ return 1;
+ }
+
+ // TODO: Parse modes, then make the rest of this work
+ uint64_t userlist_offset = 3;
+ {
+ char dir = '?';
+ for (uint64_t offset = 0; offset < argv[2].len; offset++) {
+ if (argv[2].data[offset] == '+') {
+ dir = '+';
+ } else if (argv[2].data[offset] == '-') {
+ dir = '-';
+ } else if (dir == '?') {
+ WRITES(2, STRING("Invalid FJOIN recieved! (No direction set for modes)\n"));
+ return 1;
+ } else if (channel_mode_types[(unsigned char)argv[2].data[offset]] == MODE_TYPE_UNKNOWN) {
+ WRITES(2, STRING("Invalid FJOIN recieved! (Unknown mode set on the channel)\n"));
+ return 1;
+ } else if (channel_mode_types[(unsigned char)argv[2].data[offset]] != MODE_TYPE_NOARGS && dir == '+') {
+ userlist_offset++;
+ }
+ }
+ }
+
+ if (argc < userlist_offset + 1) {
+ WRITES(2, STRING("Invalid FJOIN recieved! (Missing mode parameters or user list)\n"));
+ return 1;
+ }
+
+ struct channel_info *channel = get_table_index(channel_list, argv[0]);
+ if (!channel) {
+ channel = malloc(sizeof(*channel));
+ if (!channel) {
+ WRITES(2, STRING("OOM! (fjoin_handler)\n"));
+ return 1;
+ }
+ *channel = (struct channel_info){
+ .ts = timestamp,
+ .topic = {.data = malloc(0), .len = 0},
+ .topic_ts = 0,
+ .modes = {.array = malloc(0), .len = 0},
+ .user_list = {.array = malloc(0), .len = 0},
+ .metadata = {.array = malloc(0), .len = 0},
+ };
+
+ set_table_index(&channel_list, argv[0], channel);
+ }
+
+ struct string userlist = argv[userlist_offset];
+
+ if (userlist.len < 10) // Not enough for any users
+ return 0;
+
+ uint8_t sendclient = has_table_index(channel->user_list, STRING("1HC000001"));
+
+ uint64_t offset = 0;
+ while (1) {
+ while (offset < userlist.len && userlist.data[offset] != ',')
+ offset++;
+
+ if (offset > (userlist.len - 1) - 9)
+ break;
+
+ offset++;
+
+ struct string user = {.data = &(userlist.data[offset]), .len = 9};
+ struct user_info *user_info = get_table_index(user_list, user);
+
+ set_table_index(&(channel->user_list), user, user_info);
+
+ if (user_info && sendclient) {
+ SENDCLIENT(STRING(":"));
+ SENDCLIENT(user_info->nick);
+ SENDCLIENT(STRING("!"));
+ SENDCLIENT(user_info->ident);
+ SENDCLIENT(STRING("@"));
+ SENDCLIENT(user_info->vhost);
+ SENDCLIENT(STRING(" JOIN :"));
+ SENDCLIENT(argv[0]);
+ SENDCLIENT(STRING("\r\n"));
+ }
+
+ offset += 10;
+ }
return 0;
}
int squit_handler(struct string sender, uint64_t argc, struct string *argv) {
if (argc < 1) {
- WRITES(2, STRING("Invalid SQUIT recieved! (Missing parameters)"));
+ WRITES(2, STRING("Invalid SQUIT recieved! (Missing parameters)\n"));
return 1;
}
@@ -521,7 +620,7 @@ int squit_handler(struct string sender, uint64_t argc, struct string *argv) {
}
}
- struct remote_server *server = remove_table_index(&server_list, argv[0]);
+ struct server_info *server = remove_table_index(&server_list, argv[0]);
free(server->name.data);
free(server->address.data);
if (server->via.data != 0)
@@ -572,6 +671,30 @@ int privmsg_handler(struct string sender, uint64_t argc, struct string *argv) {
SENDCLIENT(argv[1]);
SENDCLIENT(STRING("\r\n"));
}
+ } else {
+ struct server_info *server = get_table_index(server_list, sender);
+ if (server) {
+ if (argv[0].data[0] == '#') {
+ struct channel_info *channel = get_table_index(channel_list, argv[0]);
+ if (channel && has_table_index(channel->user_list, STRING("1HC000001"))) {
+ SENDCLIENT(STRING(":"));
+ SENDCLIENT(server->address);
+ SENDCLIENT(STRING(" PRIVMSG "));
+ SENDCLIENT(argv[0]);
+ SENDCLIENT(STRING(" :"));
+ SENDCLIENT(argv[1]);
+ SENDCLIENT(STRING("\r\n"));
+ }
+ } else if (argv[0].len == 9 && memcmp(argv[0].data, "1HC000001", 9) == 0) {
+ SENDCLIENT(STRING(":"));
+ SENDCLIENT(server->address);
+ SENDCLIENT(STRING(" PRIVMSG "));
+ SENDCLIENT(client_nick);
+ SENDCLIENT(STRING(" :"));
+ SENDCLIENT(argv[1]);
+ SENDCLIENT(STRING("\r\n"));
+ }
+ }
}
uint64_t offset;
@@ -689,6 +812,33 @@ int privmsg_handler(struct string sender, uint64_t argc, struct string *argv) {
}
}
+int part_handler(struct string sender, uint64_t argc, struct string *argv) {
+ if (argc < 1) {
+ WRITES(2, STRING("Invalid PART received! (Missing parameters)\n"));
+ return 1;
+ }
+
+ struct channel_info *channel = get_table_index(channel_list, argv[0]);
+ struct user_info *user = get_table_index(user_list, sender);
+ if (user && channel && has_table_index(channel->user_list, STRING("1HC000001"))) {
+ SENDCLIENT(STRING(":"));
+ SENDCLIENT(user->nick);
+ SENDCLIENT(STRING("!"));
+ SENDCLIENT(user->ident);
+ SENDCLIENT(STRING("@"));
+ SENDCLIENT(user->vhost);
+ SENDCLIENT(STRING(" PART "));
+ SENDCLIENT(argv[0]);
+ if (argc >= 2) {
+ SENDCLIENT(STRING(" :"));
+ SENDCLIENT(argv[1]);
+ }
+ SENDCLIENT(STRING("\r\n"));
+ }
+
+ return 0;
+}
+
int initservernetwork(void) {
server_network_commands.array = malloc(0);
server_list.array = malloc(0);
@@ -705,6 +855,7 @@ int initservernetwork(void) {
set_table_index(&server_network_commands, STRING("NICK"), &nick_handler);
set_table_index(&server_network_commands, STRING("FJOIN"), &fjoin_handler);
set_table_index(&server_network_commands, STRING("SQUIT"), &squit_handler);
+ set_table_index(&server_network_commands, STRING("PART"), &part_handler);
init_user_commands();