diff options
author | Luke Bratch <luke@bratch.co.uk> | 2019-04-18 01:58:02 +0200 |
---|---|---|
committer | Luke Bratch <luke@bratch.co.uk> | 2019-04-18 01:58:02 +0200 |
commit | 84b3f43a97da2b305cfa5c620aceec543168f6bc (patch) | |
tree | f6cda57d836c6e606648e135d300016510c8e115 /blabouncer.c | |
parent | 7d5fbb2c855ebe7e2a0dc373bfd3943e4728c750 (diff) |
Split functions into different files
Diffstat (limited to 'blabouncer.c')
-rw-r--r-- | blabouncer.c | 188 |
1 files changed, 3 insertions, 185 deletions
diff --git a/blabouncer.c b/blabouncer.c index 07784a9..4ed2c9a 100644 --- a/blabouncer.c +++ b/blabouncer.c @@ -16,197 +16,15 @@ #include <arpa/inet.h> #include <sys/select.h> +#include "functions.h" +#include "sockets.h" + #define MAXDATASIZE 513 // max number of bytes we can get at once (RFC2812 says 512, plus one for null terminator) #define STDIN 0 // stdin is fd 0 -#define BACKLOG 10 // maximum length to which the queue of pending connections for sockfd may grow #define MAXCLIENTS 32 // maximum number of clients that can connect to the bouncer at a time -#define BOUNCERLISTENPORT "1234" // TODO: change this to a config option! - -// getstdin() return codes -#define OK 0 -#define NO_INPUT 1 -#define TOO_LONG 2 - int debugmode = 0; -// Print a debugging message, if debugging enabled -void debug(char *string) { - if (debugmode) { - printf("DEBUG: %s\n", string); - } -} - -// Get stdin line with buffer overrun protection -static int getstdin(char *prompt, char *buff, size_t sz) { - int ch, extra; - - // Print optional prompt - if (prompt != NULL) { - printf ("%s", prompt); - fflush (stdout); - } - - // Get the intput from stdin - if (fgets (buff, sz, stdin) == NULL) { - return NO_INPUT; - } - - // If it was too long, there'll be no newline. In that case, we flush - // to end of line so that excess doesn't affect the next call. - if (buff[strlen(buff) - 1] != '\n') { // strlen of the actually entered line, not the original array size - extra = 0; - while (((ch = getchar()) != '\n') && (ch != EOF)) { - extra = 1; - } - return (extra == 1) ? TOO_LONG : OK; - } - - // Otherwise remove newline and give string back to caller. - buff[strlen(buff) - 1] = '\0'; - return OK; -} - -// Append CR-LF to the end of a string (after cleaning up any existing trailing CR or LF) -void appendcrlf(char *string) { - // Make sure it doesn't already end with CR or LF - while (string[strlen(string) - 1] == '\r' || string[strlen(string) - 1] == '\r') { - string[strlen(string) - 1] = '\0'; - } - - int startlen = strlen(string); - string[startlen] = '\r'; - string[startlen + 1] = '\n'; - string[startlen + 2] = '\0'; -} - -// get sockaddr, IPv4 or IPv6: -void *get_in_addr(struct sockaddr *sa) { - if (sa->sa_family == AF_INET) { - return &(((struct sockaddr_in*)sa)->sin_addr); - } - - return &(((struct sockaddr_in6*)sa)->sin6_addr); -} - -// Create socket to connect to real IRC server -int createserversocket(char *host, char *port) { - int sockfd; - struct addrinfo hints, *servinfo, *p; - int rv;// return value for getaddrinfo (for error message) - char s[INET6_ADDRSTRLEN]; - - memset(&hints, 0, sizeof hints); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - - if ((rv = getaddrinfo(host, port, &hints, &servinfo)) != 0) { - fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); - return 1; - } - - // loop through all the results and connect to the first we can - for (p = servinfo; p != NULL; p = p->ai_next) { - if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { - perror("bouncer-server: socket"); - continue; - } - - if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) { - close(sockfd); - perror("bouncer-server: connect"); - continue; - } - - break; - } - - if (p == NULL) { - fprintf(stderr, "bouncer-server: failed to connect\n"); - return 2; - } - - inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), s, sizeof s); - printf("bouncer-server: connecting to %s\n", s); - - freeaddrinfo(servinfo); // all done with this structure - - return sockfd; -} - -// Create listening socket to listen for bouncer client connections -int createclientsocket(char *listenport) { - listenport = BOUNCERLISTENPORT; - - int listener; // listening socket descriptor - int rv; // return value for getaddrinfo (for error message) - struct addrinfo hints, *ai, *p; - int yes = 1; // for enabling socket options with setsockopt - - // get us a socket and bind it - memset(&hints, 0, sizeof hints); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_PASSIVE; - - if ((rv = getaddrinfo(NULL, listenport, &hints, &ai)) != 0) { - fprintf(stderr, "bouncer-client: %s\n", gai_strerror(rv)); - exit(1); - } - - // Try for IPv6 - for (p = ai; p != NULL; p = p->ai_next) { - if (p->ai_family == AF_INET6) { - listener = socket(p->ai_family, p->ai_socktype, p->ai_protocol); - if (listener != -1) { - // success, got IPv6! - printf("success, got IPv6! ai_family: %d\n", p->ai_family); - break; - } - } - } - - // Try for IPv4 if IPv6 failed - if (listener < 0) { - for (p = ai; p != NULL; p = p->ai_next) { - if (p->ai_family == AF_INET) { - listener = socket(p->ai_family, p->ai_socktype, p->ai_protocol); - if (listener != -1) { - // moderate success, got IPv4! - printf("moderate success, got IPv4! ai_family: %d\n", p->ai_family); - break; - } - } - } - } - - // allow address re-use - setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); // 1 as in non-zero as in enable - - if (bind(listener, p->ai_addr, p->ai_addrlen) < 0) { - // failed to bind - close(listener); - printf("bouncer-client: failed to bind, exiting...\n"); - exit(1); - } - - // if we got here, it means we didn't get bound - if (p == NULL) { - fprintf(stderr, "bouncer-client: failed to bind\n"); - exit(2); - } - - freeaddrinfo(ai); // all done with this - - // listen - if (listen(listener, BACKLOG) == -1) { - perror("listen"); - exit(1); - } - - return listener; -} - // Relay/send message to all clients (optionally except one) // "except" is used to send to all clients _except_ the fd provided (except = 0 avoids this, i.e. sends to all) int sendtoallclients(int *clientsockfd, int fdmax, int arr_clients[], char *str, int str_len, int except) { |