summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Bratch <luke@bratch.co.uk>2023-04-08 17:36:49 +0200
committerLuke Bratch <luke@bratch.co.uk>2023-04-08 17:36:49 +0200
commitca8c31cdb180bd5758a4a4f9d868eca31197081c (patch)
tree3aed35a062e426188642ed8e44a0ab4e8a64a0af
parentd151ca51f94be04d8e70f72773e073a471a799de (diff)
Improve stdin handling (only available when running in foreground mode) - don't get stuck in a loop when handling EOF/^D/Ctrl+D, improve debug output, improve comments, initialise variables more safely, exit main loop on errors.
-rw-r--r--TODO2
-rw-r--r--blabouncer.c22
-rw-r--r--functions.c14
-rw-r--r--functions.h3
4 files changed, 33 insertions, 8 deletions
diff --git a/TODO b/TODO
index bf8e642..a800c79 100644
--- a/TODO
+++ b/TODO
@@ -37,8 +37,6 @@ Some servers have a user send ^VERSION^ upon connection - (optionally?) respond
Git version in code.
-Sending ^D when running with ./blabouncer -f does crazy stuff.
-
Connecting from irssi triggers doautoreplay() from "USER received" in message.c twice.
Use the line number based replay log reading method from lastspoke rather than the inefficient re-read + line offset method in time replays? (And potentially remove a bunch of code re-use.)
diff --git a/blabouncer.c b/blabouncer.c
index 89add3e..c7b5f6f 100644
--- a/blabouncer.c
+++ b/blabouncer.c
@@ -715,42 +715,56 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) {
// see if there's anything from stdin (unless we're in background/daemon mode)
if (!settings->background && FD_ISSET(STDIN, &rfds)) {
- debugprint(DEBUG_FULL, "reading stdin!\n");
+ debugprint(DEBUG_FULL, "dochat(): stdin: reading stdin!\n");
char outgoingmsg[MAXDATASIZE]; // String to send to server
+ outgoingmsg[0] = '\0';
int outgoingmsgrc; // Return code from getstdin() for outgoing message
outgoingmsgrc = getstdin(NULL, outgoingmsg, sizeof(outgoingmsg));
if (outgoingmsgrc == NO_INPUT) {
- printf("\nError! No input.\n");
+ printf("Error, no input.\n");
+ debugprint(DEBUG_SOME, "dochat(): stdin: Error, no input.\n");
+ continue;
} else if (outgoingmsgrc == TOO_LONG) {
- printf ("Error! Too long. Would have allowed up to: [%s]\n", outgoingmsg);
+ debugprint(DEBUG_SOME, "dochat(): stdin: Error, input too long. Max length is %d.\n", MAXDATASIZE - 1);
+ printf ("Error, input too long. Max length is %d.\n", MAXDATASIZE - 1);
+ continue;
+ } else {
+ debugprint(DEBUG_FULL, "dochat(): stdin: Got '%s'.\n", outgoingmsg);
}
// STDIN based commands for debugging
if (strncmp(outgoingmsg, "listchannels", strlen("listchannels")) == 0) {
printf("STDIN command starting: listchannels\n");
+ debugprint(DEBUG_SOME, "dochat(): stdin: STDIN command starting: listchannels\n");
int channelcount = getchannelcount(channels, ircdstate.maxchannelcount);
for (int i = 0; i < ircdstate.maxchannelcount; i++) {
printf("Checking channel[%d] out of %d.\n", i, channelcount);
+ debugprint(DEBUG_FULL, "dochat(): stdin: Checking channel[%d] out of %d.\n", i, channelcount);
// Skip this one if it's a blank channel
if (!channels[i].name[0]) {
- debugprint(DEBUG_FULL, "Skipping blank channel channel[%d].\n", i);
+ debugprint(DEBUG_FULL, "dochat(): stdin: Skipping blank channel channel[%d].\n", i);
continue;
}
+ debugprint(DEBUG_FULL, "dochat(): stdin: Found channel '%s'.\n", channels[i].name);
printf("Found channel '%s'.\n", channels[i].name);
}
+ debugprint(DEBUG_SOME, "dochat(): stdin: STDIN command complete: listchannels\n");
printf("STDIN command complete: listchannels\n");
+
continue;
}
+ debugprint(DEBUG_FULL, "dochat(): stdin: '%s' not processed as a command, sending to server.\n", outgoingmsg);
// sourcefd = 0 as this is a trusted message
sendtoserver(server_ssl, outgoingmsg, strlen(outgoingmsg), 0, clients, settings);
+ continue;
}
// go through all the remaining sockets to see if there's anything from the client sockets (either new connections or existing clients sending messages)
diff --git a/functions.c b/functions.c
index cd56904..31282ed 100644
--- a/functions.c
+++ b/functions.c
@@ -132,8 +132,15 @@ void debugprint(int level, char *format, ...) {
va_end(args);
}
-// Get stdin line with buffer overrun protection
+// Get stdin line with buffer overrun protection.
+// Returns OK, NO_INPUT, or TOO_LONG as appropriate.
int getstdin(char *prompt, char *buff, size_t sz) {
+ if (prompt != NULL) {
+ debugprint(DEBUG_FULL, "getstdin(): '%s' (len %d), '%s' (len %d), size %zu.\n", prompt, strlen(prompt), buff, strlen(buff), sz);
+ } else {
+ debugprint(DEBUG_FULL, "getstdin(): '<null>' (len <null>), '%s' (len %d), size %zu.\n", buff, strlen(buff), sz);
+ }
+
int ch, extra;
// Print optional prompt
@@ -144,6 +151,11 @@ int getstdin(char *prompt, char *buff, size_t sz) {
// Get the intput from stdin
if (fgets (buff, sz, stdin) == NULL) {
+ if (feof(stdin)) {
+ debugprint(DEBUG_FULL, "getstdin(): Clearing EOF indicator on stdin.\n");
+ clearerr(stdin);
+ }
+
return NO_INPUT;
}
diff --git a/functions.h b/functions.h
index 5799aa6..30ae4e4 100644
--- a/functions.h
+++ b/functions.h
@@ -62,7 +62,8 @@
// Debug is only written if the global int "debug" is greater than or equal to the level.
void debugprint(int level, char *format, ...);
-// Get stdin line with buffer overrun protection
+// Get stdin line with buffer overrun protection.
+// Returns OK, NO_INPUT, or TOO_LONG as appropriate.
int getstdin(char *prompt, char *buff, size_t sz);
// Append CR-LF to the end of a string (after cleaning up any existing trailing CR or LF)