summaryrefslogtreecommitdiff
path: root/blabouncer.c
diff options
context:
space:
mode:
authorLuke Bratch <luke@bratch.co.uk>2019-05-30 22:02:07 +0100
committerLuke Bratch <luke@bratch.co.uk>2019-05-30 22:02:07 +0100
commitfd33289346881b96841a598a1f8980212b0bab62 (patch)
tree2de9e0c65af5c2d138e3141c88fb826c0ea133dc /blabouncer.c
parent6d183c02a50a42743c3031532f458ab5cea0685d (diff)
Remove most (all?) exit()s with error handling without exiting where possible. Convert most remaining printing to stdout/stderr to debugprint() instead.
Diffstat (limited to 'blabouncer.c')
-rw-r--r--blabouncer.c89
1 files changed, 61 insertions, 28 deletions
diff --git a/blabouncer.c b/blabouncer.c
index 1ca16ea..f7e38a1 100644
--- a/blabouncer.c
+++ b/blabouncer.c
@@ -292,7 +292,8 @@ int disconnectclient(int fd, struct client *clients, struct ircdstrings *ircdstr
char alertmsg[MAXDATASIZE];
if (!snprintf(alertmsg, MAXDATASIZE, "NOTICE %s :blabouncer: client with fd %d has disconnected.", ircdstrings->ircnick, fd)) {
fprintf(stderr, "Error while preparing authentication failure NOTICE!\n");
- exit(1);
+ debugprint(DEBUG_CRIT, "Error while preparing authentication failure NOTICE!\n");
+ alertmsg[0] = '\0';
}
// Remove the client from the clients array
for (int i = 0; i < MAXCLIENTS; i++) {
@@ -545,7 +546,7 @@ int doreplay(int sourcefd, int replayseconds, struct client *clients, struct set
for (int j = 0; j < 3; j++) {
// Try to split
if ((token = strsep(&strcopy, " ")) == NULL) {
- debugprint(DEBUG_CRIT, "doreplay(): error splitting string on iteration '%d', exiting!\n", j);
+ debugprint(DEBUG_CRIT, "doreplay(): error splitting string on iteration '%d', returning!\n", j);
return 0;
}
// Copy into the token array (strlen + 1 to get the NULL terminator)
@@ -629,6 +630,7 @@ int joinautochannels(SSL *server_ssl, struct client *clients, struct settings *s
strncpy(tokens[counter], token, strlen(token) + 1);
if (strlen(tokens[counter]) > MAXCHANLENGTH) {
printf("error: channel name '%s' from configuration file too long, max length is '%d'.\n", tokens[counter], MAXCHANLENGTH);
+ debugprint(DEBUG_CRIT, "error: channel name '%s' from configuration file too long, max length is '%d'.\n", tokens[counter], MAXCHANLENGTH);
exit(1);
}
counter++;
@@ -657,6 +659,7 @@ void tryautonick(struct ircdstrings *ircdstrings) {
if (ircdstrings->autonicknum == 10) {
// We've already tried 9 nicks and failed, give up
printf("tryautonick(): Tried 9 automatic nicks and the server didn't like any, giving up.\n");
+ debugprint(DEBUG_CRIT, "tryautonick(): Tried 9 automatic nicks and the server didn't like any, giving up.\n");
exit(1);
}
@@ -812,7 +815,8 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli
char outgoingmsg[MAXDATASIZE]; // String to send to server
if (!snprintf(outgoingmsg, MAXDATASIZE, "PONG %s", tokens[1])) { // TODO - Make sure tokens[1] actually has a token
fprintf(stderr, "Error while preparing PONG response!\n");
- exit(1);
+ debugprint(DEBUG_CRIT, "Error while preparing PONG response!\n");
+ outgoingmsg[0] = '\0';
}
// sourcefd = 0 as this is a trusted response
sendtoserver(server_ssl, outgoingmsg, strlen(outgoingmsg), 0, clients, settings);
@@ -837,6 +841,7 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli
// Prepend a colon (:) first since everything (so far) needs one
if (!snprintf(ircdstrings->nickuserhost, MAXDATASIZE, ":%s", tokens[counter - 1])) {
fprintf(stderr, "Error while preparing nickuserhost for storage!\n");
+ debugprint(DEBUG_CRIT, "Error while preparing nickuserhost for storage!\n");
exit(1);
}
// Null the end of the new string
@@ -1545,7 +1550,8 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli
char alertmsg[MAXDATASIZE];
if (!snprintf(alertmsg, MAXDATASIZE, "NOTICE %s :blabouncer: new client with fd %d has successfully authenticated.", ircdstrings->ircnick, sourcefd)) {
fprintf(stderr, "Error while preparing authentication success NOTICE!\n");
- exit(1);
+ debugprint(DEBUG_CRIT, "Error while preparing authentication success NOTICE!\n");
+ alertmsg[0] = '\0';
}
// "except" the current fd - we can use this as "except/sourcefd" since we set them as authed just above
sendtoallclients(clients, alertmsg, sourcefd, settings);
@@ -1558,7 +1564,8 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli
char alertmsg[MAXDATASIZE];
if (!snprintf(alertmsg, MAXDATASIZE, "NOTICE %s :blabouncer: new client with fd %d has failed to authenticate.", ircdstrings->ircnick, sourcefd)) {
fprintf(stderr, "Error while preparing authentication failure NOTICE!\n");
- exit(1);
+ debugprint(DEBUG_CRIT, "Error while preparing authentication failure NOTICE!\n");
+ alertmsg[0] = '\0';
}
// "except" 0 since we trust this message
sendtoallclients(clients, alertmsg, 0, settings);
@@ -1586,7 +1593,8 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli
if (strncasecmp(tokens[1], "LS", strlen(tokens[1])) == 0) {
if (!snprintf(outgoingmsg, MAXDATASIZE, ":%s CAP * LS :multi-prefix", ircdstrings->ircdname)) {
fprintf(stderr, "Error while preparing CAP LS response!\n");
- exit(1);
+ debugprint(DEBUG_CRIT, "Error while preparing CAP LS response!\n");
+ outgoingmsg[0] = '\0';
}
// ...even if unauthenticated
sendtoclient(sourcefd, outgoingmsg, clients, settings, 1);
@@ -1598,7 +1606,8 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli
if (strncasecmp(tokens[2], ":multi-prefix", strlen(tokens[2])) == 0) {
if (!snprintf(outgoingmsg, MAXDATASIZE, ":%s CAP %s ACK :multi-prefix ", ircdstrings->ircdname, ircdstrings->ircnick)) {
fprintf(stderr, "Error while preparing CAP ACK response!\n");
- exit(1);
+ debugprint(DEBUG_CRIT, "Error while preparing CAP ACK response!\n");
+ outgoingmsg[0] = '\0';
}
// ...even if unauthenticated
sendtoclient(sourcefd, outgoingmsg, clients, settings, 1);
@@ -1691,7 +1700,9 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli
// Get client to join channels
if (!snprintf(outgoingmsg, MAXDATASIZE, "%s JOIN :%s", ircdstrings->nickuserhost, channels[i].name)) {
fprintf(stderr, "Error while preparing USER just connected, channel JOIN responses!\n");
- exit(1);
+ debugprint(DEBUG_CRIT, "Error while preparing USER just connected, channel JOIN responses!\n");
+ free(strcopyPtr);
+ return 0;
}
sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
@@ -1701,7 +1712,9 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli
// Prepare the no topic message...
if (!snprintf(outgoingmsg, MAXDATASIZE, ":%s 331 %s %s :No topic is set.", ircdstrings->ircdname, ircdstrings->ircnick, channels[i].name)) {
fprintf(stderr, "Error while preparing USER just connected, channel JOIN responses, 331 RPL_NOTOPIC!\n");
- exit(1);
+ debugprint(DEBUG_CRIT, "Error while preparing USER just connected, channel JOIN responses, 331 RPL_NOTOPIC!\n");
+ free(strcopyPtr);
+ return 0;
}
// ..and send it to the client
sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
@@ -1710,7 +1723,9 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli
// Prepare the topic message...
if (!snprintf(outgoingmsg, MAXDATASIZE, ":%s 332 %s %s :%s", ircdstrings->ircdname, ircdstrings->ircnick, channels[i].name, channels[i].topic)) {
fprintf(stderr, "Error while preparing USER just connected, channel JOIN responses, 332 RPL_TOPIC!\n");
- exit(1);
+ debugprint(DEBUG_CRIT, "Error while preparing USER just connected, channel JOIN responses, 332 RPL_TOPIC!\n");
+ free(strcopyPtr);
+ return 0;
}
// ..and send it to the client
sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
@@ -1718,7 +1733,9 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli
// Next prepare the topic who/when message...
if (!snprintf(outgoingmsg, MAXDATASIZE, ":%s 333 %s %s %s %s", ircdstrings->ircdname, ircdstrings->ircnick, channels[i].name, channels[i].topicwho, channels[i].topicwhen)) {
fprintf(stderr, "Error while preparing USER just connected, channel JOIN responses, 333 RPL_TOPICWHOTIME!\n");
- exit(1);
+ debugprint(DEBUG_CRIT, "Error while preparing USER just connected, channel JOIN responses, 333 RPL_TOPICWHOTIME!\n");
+ free(strcopyPtr);
+ return 0;
}
// ..and send it to the client
sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
@@ -1734,7 +1751,9 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli
if (strlen(ircdstrings->mode) > 0) {
if (!snprintf(outgoingmsg, MAXDATASIZE, ":%s MODE %s %s", ircdstrings->ircnick, ircdstrings->ircnick, ircdstrings->mode)) {
fprintf(stderr, "Error while preparing USER just connected, MODE response!\n");
- exit(1);
+ debugprint(DEBUG_CRIT, "Error while preparing USER just connected, MODE response!\n");
+ free(strcopyPtr);
+ return 0;
}
sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
}
@@ -1767,7 +1786,8 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli
char outgoingmsg[MAXDATASIZE]; // String to send to client
if (!snprintf(outgoingmsg, MAXDATASIZE, "PONG %s", tokens[1])) { // TODO - Make sure tokens[1] actually has a token
fprintf(stderr, "Error while preparing PONG response!\n");
- exit(1);
+ debugprint(DEBUG_CRIT, "Error while preparing PONG response!\n");
+ outgoingmsg[0] = '\0';
}
sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
@@ -1809,7 +1829,9 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli
if (!snprintf(outgoingmsg, MAXDATASIZE, "%s %s", ircdstrings->nickuserhost, str)) {
fprintf(stderr, "Error while preparing PRIVMSG relay from another bouncer client.\n");
- exit(1);
+ debugprint(DEBUG_CRIT, "Error while preparing PRIVMSG relay from another bouncer client.\n");
+ free(strcopyPtr);
+ return 0;
}
// Send to all except source client
sendtoallclients(clients, outgoingmsg, sourcefd, settings);
@@ -1929,7 +1951,9 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli
if (!snprintf(fullmsg, MAXDATASIZE, "%s %s", ircdstrings->nickuserhost, str)) {
fprintf(stderr, "Error while preparing NOTICE string for logging.\n");
- exit(1);
+ debugprint(DEBUG_CRIT, "Error while preparing NOTICE string for logging.\n");
+ free(strcopyPtr);
+ return 0;
}
// Write to replay log if replay logging enabled
@@ -2005,7 +2029,8 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli
debugprint(DEBUG_SOME, "Invalid number '%s' requested by REPLAY command. Telling client.\n", timetokens[i]);
if (!snprintf(outgoingmsg, MAXDATASIZE, "NOTICE %s :Invalid number '%s' requested by REPLAY command.", ircdstrings->ircnick, timetokens[i])) {
fprintf(stderr, "Error while preparing REPLAY invalid number response!\n");
- exit(1);
+ debugprint(DEBUG_CRIT, "Error while preparing REPLAY invalid number response!\n");
+ outgoingmsg[0] = '\0';
}
sendtoclient(sourcefd, outgoingmsg, clients, settings, 0);
free(timestrcopyPtr);
@@ -2083,7 +2108,9 @@ int processircmessage(SSL *server_ssl, char *str, int source, struct client *cli
break;
default:
fprintf(stderr, "Unexpected raw IRC string source!\n");
- exit(1);
+ debugprint(DEBUG_CRIT, "Unexpected raw IRC string source!\n");
+ free(strcopyPtr);
+ return 0;
}
// =============================================>
@@ -2198,7 +2225,8 @@ int processrawstring(SSL *server_ssl, char *str, int source, struct client *clie
break;
default:
fprintf(stderr, "Unexpected raw IRC string source for unprocessed message \"%s\", length %zd.!\n", messages[i], strlen(messages[i]));
- exit(1);
+ debugprint(DEBUG_CRIT, "Unexpected raw IRC string source for unprocessed message \"%s\", length %zd.!\n", messages[i], strlen(messages[i]));
+ return 0;
}
}
}
@@ -2326,8 +2354,9 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) {
debugprint(DEBUG_FULL, "select()ing...\n");
// check to see if anything in the fd_set is waiting - waits here until one of the fds in the set does something
if (select(fdmax + 1, &rfds, NULL, NULL, NULL) < 0) { // network socket + 1, rfds, no writes, no exceptions/errors, no timeout
- printf("receive error, exiting!?\n");
perror("select");
+ debugprint(DEBUG_CRIT, "select() error, errno '%d'.\n", errno);
+ continue;
}
// TODO - switch around the serversockfd and STDIN FD_ISSET if-statements? They feel the wrong way round. Are they like this on purpose? I can't remember.
@@ -2338,13 +2367,14 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) {
debugprint(DEBUG_FULL, "reading server socket!\n");
if ((servernumbytes = sockread(server_ssl, serverbuf, MAXRCVSIZE - 1, settings->servertls)) == -1) {
- printf("receive error (-1), exiting...\n");
perror("recv");
- debugprint(DEBUG_CRIT, "serversockfd receive error (-1), errno '%d'.\n");
+ printf("receive error (-1), skipping loop iteration...\n");
+ debugprint(DEBUG_CRIT, "serversockfd receive error (-1), skipping loop iteration, errno '%d'.\n");
+ continue;
} else if (servernumbytes == 0) {
- printf("socket closed (or no data received) (0), exiting...\n");
perror("recv");
- debugprint(DEBUG_CRIT, "serversockfd socket closed (or no data received) (0), errno '%d'.\n");
+ printf("socket closed (or no data received) (0), skipping loop iteration...\n");
+ debugprint(DEBUG_CRIT, "serversockfd socket closed (or no data received) (0), skipping loop iteration, errno '%d'.\n");
}
// If there was a socket error (receive error or socket closed)
@@ -2382,7 +2412,7 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) {
// TODO - What if there were two server respones/commands and only one didn't need relaying?
if (!processrawstring(server_ssl, serverbuf, SOURCE_SERVER, clients, EXCEPT_NONE, &ircdstrings, channels, settings)) {
fprintf(stderr, "Error: bouncer-server failed to process raw string.\n");
- exit(1);
+ debugprint(DEBUG_CRIT, "Error: bouncer-server failed to process raw string.\n");
}
}
@@ -2443,8 +2473,10 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) {
debugprint(DEBUG_SOME, "...new connection!\n");
// handle new connections
if (numclients(clients) >= MAXCLIENTS) {
- fprintf(stderr, "too many clients!\n");
- exit(1); // TODO - handle cleanly instead of exiting!
+ fprintf(stderr, "too many clients, disconnecting and skipping loop iteration!\n");
+ debugprint(DEBUG_CRIT, "too many clients, disconnecting and skipping loop iteration!\n");
+ disconnectclient(i, clients, &ircdstrings, settings);
+ continue;
}
addrlen = sizeof remoteaddr;
newfd = accept(*clientsockfd, (struct sockaddr *)&remoteaddr, &addrlen);
@@ -2489,7 +2521,8 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) {
if (!snprintf(alertmsg, MAXDATASIZE, "NOTICE %s :blabouncer: new client connected from %s with fd %d.", ircdstrings.ircnick,
inet_ntop(remoteaddr.ss_family, get_in_addr((struct sockaddr*)&remoteaddr), remoteIP, INET6_ADDRSTRLEN), newfd)) {
fprintf(stderr, "Error while preparing new client connection NOTICE!\n");
- exit(1);
+ debugprint(DEBUG_CRIT, "Error while preparing new client connection NOTICE!\n");
+ alertmsg[0] = '\0';
}
// "except" 0 since we trust this message
sendtoallclients(clients, alertmsg, 0, settings);
@@ -2526,7 +2559,7 @@ void dochat(int *serversockfd, int *clientsockfd, struct settings *settings) {
// TODO - What if there were two server respones/commands and only one didn't need relaying?
if (!processrawstring(server_ssl, clientbuf, SOURCE_CLIENT, clients, i, &ircdstrings, channels, settings)) {
fprintf(stderr, "Error: bouncer-client failed to process raw string.\n");
- exit(1);
+ debugprint(DEBUG_CRIT, "Error: bouncer-client failed to process raw string.\n");
}
}
}