aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--general_network.c41
-rw-r--r--general_network.h2
-rw-r--r--protocols.c5
-rw-r--r--protocols.h5
-rw-r--r--protocols/inspircd2.c177
-rw-r--r--protocols/inspircd2.h6
-rw-r--r--server_network.c4
7 files changed, 190 insertions, 50 deletions
diff --git a/general_network.c b/general_network.c
index 432faa0..ad7016c 100644
--- a/general_network.c
+++ b/general_network.c
@@ -284,6 +284,34 @@ int add_user(struct string from, struct string attached_to, struct string uid, s
return 1;
}
+int rename_user(struct string from, struct user_info *user, struct string nick, size_t timestamp) {
+ struct string timestamp_str;
+ if (unsigned_to_str(timestamp, &timestamp_str) != 0)
+ return 1;
+
+ void *tmp = malloc(nick.len);
+ if (!tmp) {
+ free(timestamp_str.data);
+ return 1;
+ }
+
+#ifdef USE_SERVER
+#ifdef USE_HAXIRCD_PROTOCOL
+ protocols[HAXIRCD_PROTOCOL].propagate_rename_user(from, user, nick, timestamp, timestamp_str);
+#endif
+#ifdef USE_INSPIRCD2_PROTOCOL
+ protocols[INSPIRCD2_PROTOCOL].propagate_rename_user(from, user, nick, timestamp, timestamp_str);
+#endif
+#endif
+
+ free(user->nick.data);
+ user->nick.data = tmp;
+ memcpy(user->nick.data, nick.data, nick.len);
+ user->nick.len = nick.len;
+
+ return 0;
+}
+
void remove_user(struct string from, struct user_info *user, struct string reason, char propagate) {
#ifdef USE_SERVER
if (propagate) {
@@ -318,3 +346,16 @@ void remove_user(struct string from, struct user_info *user, struct string reaso
free(user->address.data);
free(user);
}
+
+void kill_user(struct string from, struct string source, struct user_info *user, struct string reason) {
+#ifdef USE_SERVER
+#ifdef USE_HAXIRCD_PROTOCOL
+ protocols[HAXIRCD_PROTOCOL].propagate_kill_user(from, source, user, reason);
+#endif
+#ifdef USE_INSPIRCD2_PROTOCOL
+ protocols[INSPIRCD2_PROTOCOL].propagate_kill_user(from, source, user, reason);
+#endif
+#endif
+
+ remove_user(from, user, reason, 0);
+}
diff --git a/general_network.h b/general_network.h
index 1413741..34a3d0c 100644
--- a/general_network.h
+++ b/general_network.h
@@ -96,7 +96,9 @@ int resolve(struct string address, struct string port, struct sockaddr *sockaddr
int init_general_network(void);
int add_user(struct string from, struct string attached_to, struct string uid, struct string nick, struct string fullname, struct string ident, struct string vhost, struct string host, struct string address, size_t user_ts, size_t nick_ts, void *handle, size_t protocol, size_t net);
+int rename_user(struct string from, struct user_info *user, struct string nick, size_t timestamp);
void remove_user(struct string from, struct user_info *user, struct string reason, char propagate);
+void kill_user(struct string from, struct string source, struct user_info *user, struct string reason);
extern char casemap[UCHAR_MAX+1];
#define CASEMAP(x) (casemap[(unsigned char)x])
diff --git a/protocols.c b/protocols.c
index 04dd2f9..4b8afc3 100644
--- a/protocols.c
+++ b/protocols.c
@@ -40,9 +40,12 @@ struct protocol protocols[NUM_PROTOCOLS] = {
.update_propagations = inspircd2_protocol_update_propagations,
.propagate_new_server = inspircd2_protocol_propagate_new_server,
- .propagate_unlink = inspircd2_protocol_propagate_unlink,
+ .propagate_unlink_server = inspircd2_protocol_propagate_unlink_server,
+
.propagate_new_user = inspircd2_protocol_propagate_new_user,
+ .propagate_rename_user = inspircd2_protocol_propagate_rename_user,
.propagate_remove_user = inspircd2_protocol_propagate_remove_user,
+ .propagate_kill_user = inspircd2_protocol_propagate_kill_user,
.do_unlink = inspircd2_protocol_do_unlink,
},
diff --git a/protocols.h b/protocols.h
index 723d971..c9fcc58 100644
--- a/protocols.h
+++ b/protocols.h
@@ -34,9 +34,12 @@ struct protocol {
void (*update_propagations)(void);
void (*propagate_new_server)(struct string from, struct string attached_to, struct server_info *info);
- void (*propagate_unlink)(struct string from, struct server_info *a, struct server_info *b, size_t protocol);
+ void (*propagate_unlink_server)(struct string from, struct server_info *a, struct server_info *b, size_t protocol);
+
void (*propagate_new_user)(struct string from, struct user_info *info);
+ void (*propagate_rename_user)(struct string from, struct user_info *info, struct string nick, size_t timestamp, struct string timestamp_str);
void (*propagate_remove_user)(struct string from, struct user_info *info, struct string reason);
+ void (*propagate_kill_user)(struct string from, struct string source, struct user_info *info, struct string reason);
void (*do_unlink)(struct string from, struct server_info *a, struct server_info *b);
};
diff --git a/protocols/inspircd2.c b/protocols/inspircd2.c
index 46c9f8b..2d6fe96 100644
--- a/protocols/inspircd2.c
+++ b/protocols/inspircd2.c
@@ -132,8 +132,9 @@ int init_inspircd2_protocol(void) {
set_table_index(&inspircd2_protocol_commands, STRING("RSQUIT"), &inspircd2_protocol_handle_rsquit);
set_table_index(&inspircd2_protocol_commands, STRING("UID"), &inspircd2_protocol_handle_uid);
+ set_table_index(&inspircd2_protocol_commands, STRING("NICK"), &inspircd2_protocol_handle_nick);
set_table_index(&inspircd2_protocol_commands, STRING("QUIT"), &inspircd2_protocol_handle_quit);
-// set_table_index(&inspircd2_protocol_commands, STRING("KILL"), &inspircd2_protocol_handle_kill);
+ set_table_index(&inspircd2_protocol_commands, STRING("KILL"), &inspircd2_protocol_handle_kill);
return 0;
}
@@ -505,7 +506,7 @@ void inspircd2_protocol_propagate_new_server(struct string from, struct string a
}
}
-void inspircd2_protocol_propagate_unlink(struct string from, struct server_info *a, struct server_info *b, size_t protocol) {
+void inspircd2_protocol_propagate_unlink_server(struct string from, struct server_info *a, struct server_info *b, size_t protocol) {
struct server_info *source;
struct server_info *target;
if (a->distance == 0 && !STRING_EQ(a->sid, SID)) {
@@ -567,6 +568,24 @@ void inspircd2_protocol_propagate_new_user(struct string from, struct user_info
}
}
+void inspircd2_protocol_propagate_rename_user(struct string from, struct user_info *user, struct string nick, size_t timestamp, struct string timestamp_str) {
+ struct server_info *self = get_table_index(server_list, SID);
+
+ for (size_t i = 0; i < self->connected_to.len; i++) {
+ struct server_info *adjacent = self->connected_to.array[i].ptr;
+ if (adjacent->protocol != INSPIRCD2_PROTOCOL || STRING_EQ(from, adjacent->sid))
+ continue;
+
+ networks[adjacent->net].send(adjacent->handle, STRING(":"));
+ networks[adjacent->net].send(adjacent->handle, user->uid);
+ networks[adjacent->net].send(adjacent->handle, STRING(" NICK "));
+ networks[adjacent->net].send(adjacent->handle, nick);
+ networks[adjacent->net].send(adjacent->handle, STRING(" "));
+ networks[adjacent->net].send(adjacent->handle, timestamp_str);
+ networks[adjacent->net].send(adjacent->handle, STRING("\n"));
+ }
+}
+
void inspircd2_protocol_propagate_remove_user(struct string from, struct user_info *info, struct string reason) {
struct server_info *self = get_table_index(server_list, SID);
@@ -583,6 +602,24 @@ void inspircd2_protocol_propagate_remove_user(struct string from, struct user_in
}
}
+void inspircd2_protocol_propagate_kill_user(struct string from, struct string source, struct user_info *info, struct string reason) {
+ struct server_info *self = get_table_index(server_list, SID);
+
+ for (size_t i = 0; i < self->connected_to.len; i++) {
+ struct server_info *adjacent = self->connected_to.array[i].ptr;
+ if (adjacent->protocol != INSPIRCD2_PROTOCOL || STRING_EQ(from, adjacent->sid))
+ continue;
+
+ networks[adjacent->net].send(adjacent->handle, STRING(":"));
+ networks[adjacent->net].send(adjacent->handle, source);
+ networks[adjacent->net].send(adjacent->handle, STRING(" KILL "));
+ networks[adjacent->net].send(adjacent->handle, info->uid);
+ networks[adjacent->net].send(adjacent->handle, STRING(" :"));
+ networks[adjacent->net].send(adjacent->handle, reason);
+ networks[adjacent->net].send(adjacent->handle, STRING("\n"));
+ }
+}
+
void inspircd2_protocol_do_unlink_inner(struct string from, struct server_info *target, struct string reason) {
target->distance = 1; // Reusing distance for `have passed`, since its set to 0 bc severed anyways
@@ -654,6 +691,30 @@ void inspircd2_protocol_introduce_servers_to(size_t net, void *handle) {
}
}
+void inspircd2_protocol_introduce_user_to(size_t net, void *handle, struct user_info *user) {
+ networks[net].send(handle, STRING(":"));
+ networks[net].send(handle, user->server);
+ networks[net].send(handle, STRING(" UID "));
+ networks[net].send(handle, user->uid);
+ networks[net].send(handle, STRING(" "));
+ networks[net].send(handle, user->user_ts_str);
+ networks[net].send(handle, STRING(" "));
+ networks[net].send(handle, user->nick);
+ networks[net].send(handle, STRING(" "));
+ networks[net].send(handle, user->host);
+ networks[net].send(handle, STRING(" "));
+ networks[net].send(handle, user->vhost);
+ networks[net].send(handle, STRING(" "));
+ networks[net].send(handle, user->ident);
+ networks[net].send(handle, STRING(" "));
+ networks[net].send(handle, user->address);
+ networks[net].send(handle, STRING(" "));
+ networks[net].send(handle, user->nick_ts_str);
+ networks[net].send(handle, STRING(" + :"));
+ networks[net].send(handle, user->fullname);
+ networks[net].send(handle, STRING("\n"));
+}
+
// CAPAB <type> [<args> [, ...]]
int inspircd2_protocol_init_handle_capab(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config **config, char is_incoming) {
if (argc < 1) {
@@ -730,48 +791,8 @@ int inspircd2_protocol_init_handle_server(struct string source, size_t argc, str
inspircd2_protocol_introduce_servers_to(net, handle);
- for (size_t i = 0; i < user_list.len; i++) {
- struct user_info *user = user_list.array[i].ptr;
-
- networks[net].send(handle, STRING(":"));
- networks[net].send(handle, user->server);
- networks[net].send(handle, STRING(" UID "));
- networks[net].send(handle, user->uid);
- networks[net].send(handle, STRING(" "));
-
- struct string timestamp;
- char err = unsigned_to_str(user->nick_ts, &timestamp);
-
- if (err) {
- return -1;
- }
- networks[net].send(handle, timestamp);
- free(timestamp.data);
-
- networks[net].send(handle, STRING(" "));
- networks[net].send(handle, user->nick);
- networks[net].send(handle, STRING(" "));
- networks[net].send(handle, user->host);
- networks[net].send(handle, STRING(" "));
- networks[net].send(handle, user->vhost);
- networks[net].send(handle, STRING(" "));
- networks[net].send(handle, user->ident);
- networks[net].send(handle, STRING(" "));
- networks[net].send(handle, user->address);
- networks[net].send(handle, STRING(" "));
-
- err = unsigned_to_str(user->nick_ts, &timestamp);
-
- if (err) {
- return -1;
- }
- networks[net].send(handle, timestamp);
- free(timestamp.data);
-
- networks[net].send(handle, STRING(" + :"));
- networks[net].send(handle, user->fullname);
- networks[net].send(handle, STRING("\n"));
- }
+ for (size_t i = 0; i < user_list.len; i++)
+ inspircd2_protocol_introduce_user_to(net, handle, user_list.array[i].ptr);
networks[net].send(handle, STRING(":"));
networks[net].send(handle, SID);
@@ -965,7 +986,31 @@ int inspircd2_protocol_handle_uid(struct string source, size_t argc, struct stri
return 0;
}
-// :source QUIT <reason>
+// :source NICK <nick> <timestamp>
+int inspircd2_protocol_handle_nick(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming) {
+ if (argc < 2) {
+ WRITES(2, STRING("[InspIRCd v2] Invalid NICK recieved! (Missing parameters)\r\n"));
+ return -1;
+ }
+
+ char err;
+ size_t nick_ts = str_to_unsigned(argv[1], &err);
+ if (err) {
+ WRITES(2, STRING("[InspIRCd v2] Invalid NICK recieved! (Invalid timestamp)\r\n"));
+ return -1;
+ }
+
+ struct user_info *user = get_table_index(user_list, source);
+ if (!user)
+ return 0; // KILL timings, etc
+
+ if (rename_user(config->sid, user, argv[0], nick_ts) != 0)
+ return -1;
+
+ return 0;
+}
+
+// :source QUIT [<reason>?]
int inspircd2_protocol_handle_quit(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming) {
struct string reason;
if (argc < 1)
@@ -986,3 +1031,45 @@ int inspircd2_protocol_handle_quit(struct string source, size_t argc, struct str
return 0;
}
+
+// [:source] KILL <target> [<reason>?]
+int inspircd2_protocol_handle_kill(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming) {
+ if (argc < 1) {
+ WRITES(2, STRING("[InspIRCd v2] Invalid KILL recieved! (Missing parameters)\r\n"));
+ return -1;
+ }
+
+ struct user_info *user = get_table_index(user_list, argv[0]);
+ if (!user) {
+ for (size_t i = 0; i < user_list.len; i++) {
+ struct user_info *tmp = user_list.array[i].ptr;
+ if (STRING_EQ(tmp->nick, argv[0])) {
+ user = tmp;
+ break;
+ }
+ }
+
+ if (!user)
+ return 0;
+ }
+
+ if (STRING_EQ(user->server, SID)) {
+ if (config->ignore_local_kills) {
+ inspircd2_protocol_introduce_user_to(net, handle, user);
+ } else {
+ if (argc > 1)
+ kill_user(config->sid, source, user, argv[1]);
+ else
+ kill_user(config->sid, source, user, STRING(""));
+ }
+ } else if (config->ignore_remote_kills) {
+ inspircd2_protocol_introduce_user_to(net, handle, user);
+ } else {
+ if (argc > 1)
+ kill_user(config->sid, source, user, argv[1]);
+ else
+ kill_user(config->sid, source, user, STRING(""));
+ }
+
+ return 0;
+}
diff --git a/protocols/inspircd2.h b/protocols/inspircd2.h
index 03963b6..0a19964 100644
--- a/protocols/inspircd2.h
+++ b/protocols/inspircd2.h
@@ -42,9 +42,12 @@ void * inspircd2_protocol_autoconnect(void *type);
void inspircd2_protocol_update_propagations(void);
void inspircd2_protocol_propagate_new_server(struct string from, struct string attached_to, struct server_info *info);
-void inspircd2_protocol_propagate_unlink(struct string from, struct server_info *a, struct server_info *b, size_t protocol);
+void inspircd2_protocol_propagate_unlink_server(struct string from, struct server_info *a, struct server_info *b, size_t protocol);
+
void inspircd2_protocol_propagate_new_user(struct string from, struct user_info *info);
+void inspircd2_protocol_propagate_rename_user(struct string from, struct user_info *info, struct string nick, size_t timestamp, struct string timestamp_str);
void inspircd2_protocol_propagate_remove_user(struct string from, struct user_info *info, struct string reason);
+void inspircd2_protocol_propagate_kill_user(struct string from, struct string source, struct user_info *info, struct string reason);
void inspircd2_protocol_do_unlink(struct string from, struct server_info *a, struct server_info *b);
@@ -61,6 +64,7 @@ int inspircd2_protocol_handle_squit(struct string source, size_t argc, struct st
int inspircd2_protocol_handle_rsquit(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming);
int inspircd2_protocol_handle_uid(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming);
+int inspircd2_protocol_handle_nick(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming);
int inspircd2_protocol_handle_quit(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming);
int inspircd2_protocol_handle_kill(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming);
diff --git a/server_network.c b/server_network.c
index aeca696..6908a31 100644
--- a/server_network.c
+++ b/server_network.c
@@ -285,10 +285,10 @@ void unlink_server(struct string from, struct server_info *a, struct server_info
protocols[protocol].update_propagations();
#ifdef USE_HAXIRCD_PROTOCOL
- protocols[HAXIRCD_PROTOCOL].propagate_unlink(from, a, b, protocol);
+ protocols[HAXIRCD_PROTOCOL].propagate_unlink_server(from, a, b, protocol);
#endif
#ifdef USE_INSPIRCD2_PROTOCOL
- protocols[INSPIRCD2_PROTOCOL].propagate_unlink(from, a, b, protocol);
+ protocols[INSPIRCD2_PROTOCOL].propagate_unlink_server(from, a, b, protocol);
#endif
protocols[protocol].do_unlink(from, a, b);