aboutsummaryrefslogtreecommitdiff
path: root/commands.c
diff options
context:
space:
mode:
authorTest_User <hax@andrewyu.org>2024-06-08 21:13:43 -0400
committerTest_User <hax@andrewyu.org>2024-06-08 21:13:43 -0400
commitf84129633bb025ab0fb0eee19c9142268193acf1 (patch)
tree47bf0d2964160f8e28a21e2192cfc4fd30b86d6b /commands.c
parentb8b1b474d0a270ed56745db5f6a3ecf717b35310 (diff)
downloadcoupserv-f84129633bb025ab0fb0eee19c9142268193acf1.tar.gz
coupserv-f84129633bb025ab0fb0eee19c9142268193acf1.zip
Fix bug with getline() usage, make sh spawn a new thread so it won't hang everything else while running
Diffstat (limited to '')
-rw-r--r--commands.c107
1 files changed, 74 insertions, 33 deletions
diff --git a/commands.c b/commands.c
index 479f2ca..b2f45f7 100644
--- a/commands.c
+++ b/commands.c
@@ -279,6 +279,55 @@ static struct command_def clear_command_def = {
.summary = STRING("Clears a channel"),
};
+struct sh_command_args {
+ char *command;
+ struct string to;
+};
+void * async_sh_command(void *tmp) {
+ struct sh_command_args *sh_args = tmp;
+
+ FILE *f = popen(sh_args->command, "r");
+ free(sh_args->command);
+
+ char *line = NULL;
+ size_t buflen;
+ while (1) {
+ ssize_t len = getline(&line, &buflen, f);
+ if (len <= 0)
+ break;
+
+ struct string linestr = {.data = line, .len = (size_t)(len)};
+ while (linestr.len > 0 && (linestr.data[linestr.len-1] == '\n' || linestr.data[linestr.len-1] == '\r'))
+ linestr.len--;
+ if (linestr.len == 0)
+ linestr = STRING(" ");
+ pthread_mutex_lock(&send_lock);
+ SEND(STRING(":1HC000000 PRIVMSG "));
+ SEND(sh_args->to);
+ SEND(STRING(" :"));
+ SEND(linestr);
+ SEND(STRING("\n"));
+
+ SENDCLIENT(STRING(":"));
+ SENDCLIENT(nick);
+ SENDCLIENT(STRING("!e@e PRIVMSG "));
+ SENDCLIENT(sh_args->to);
+ SENDCLIENT(STRING(" :"));
+ SENDCLIENT(linestr);
+ SENDCLIENT(STRING("\r\n"));
+ pthread_mutex_unlock(&send_lock);
+ }
+
+ free(line);
+
+ pclose(f);
+
+ free(sh_args->to.data);
+ free(sh_args);
+
+ return 0;
+}
+
int sh_command(struct string sender, struct string original_message, struct string to, uint64_t argc, struct string *argv, char is_local) {
if (!is_local) {
return 0;
@@ -304,42 +353,34 @@ int sh_command(struct string sender, struct string original_message, struct stri
struct string command = {.data = original_message.data + offset, .len = original_message.len - offset};
- char command_nullstr[command.len+1];
- memcpy(command_nullstr, command.data, command.len);
- command_nullstr[command.len] = '\0';
-
- FILE *f = popen(command_nullstr, "r");
-
- char *line = NULL;
- size_t buflen;
- while (1) {
- ssize_t len = getline(&line, &buflen, f);
- if (len <= 0)
- break;
-
- struct string linestr = {.data = line, .len = (size_t)(len) - 1};
- if (linestr.len > 0 && linestr.data[linestr.len-1] == '\n')
- linestr.len--;
- if (linestr.len > 0 && linestr.data[linestr.len-1] == '\r')
- linestr.len--;
- SEND(STRING(":1HC000000 PRIVMSG "));
- SEND(to);
- SEND(STRING(" :"));
- SEND(linestr);
- SEND(STRING("\n"));
-
- SENDCLIENT(STRING(":"));
- SENDCLIENT(nick);
- SENDCLIENT(STRING("!e@e PRIVMSG "));
- SENDCLIENT(to);
- SENDCLIENT(STRING(" :"));
- SENDCLIENT(linestr);
- SENDCLIENT(STRING("\r\n"));
+ struct sh_command_args *sh_args;
+ sh_args = malloc(sizeof(*sh_args));
+ if (!sh_args) {
+ WRITES(2, STRING("ERROR: OOM\n"));
+ return 0;
}
- free(line);
+ sh_args->command = malloc(command.len+1);
+ if (!sh_args->command) {
+ free(sh_args);
+ WRITES(2, STRING("ERROR: OOM\n"));
+ return 0;
+ }
+ memcpy(sh_args->command, command.data, command.len);
+ sh_args->command[command.len] = '\0';
+
+ sh_args->to.len = to.len;
+ sh_args->to.data = malloc(to.len);
+ if (!sh_args->to.data) {
+ free(sh_args->command);
+ free(sh_args);
+ WRITES(2, STRING("ERROR: OOM\n"));
+ return 0;
+ }
+ memcpy(sh_args->to.data, to.data, to.len);
- pclose(f);
+ pthread_t trash;
+ pthread_create(&trash, NULL, async_sh_command, sh_args);
return 0;
}