/* * This file is part of blabouncer (https://www.blatech.co.uk/l_bratch/blabouncer). * Copyright (C) 2019 Luke Bratch . * * Blabouncer is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * Blabouncer is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with blabouncer. If not, see . */ #ifndef FUNCTIONS_H_INCLUDED #define FUNCTIONS_H_INCLUDED #include #include #include #include #include #include #include #include #include #include #include #include #include #include "sockets.h" #include "structures.h" #include "replay.h" #include "config.h" // getstdin() return codes #define OK 0 #define NO_INPUT 1 #define TOO_LONG 2 #define DEBUG_CRIT 0 #define DEBUG_SOME 1 #define DEBUG_FULL 2 #define EXCEPT_NONE 0 #define MAXDATASIZE 513 // Maximum number of bytes we can get at once (RFC2812 says 512, plus one for null terminator) #define MAXCLIENTS 32 // Maximum number of clients that can connect to the bouncer at a time #define MAXCHANNELS 1024 // Let's assume 1024 is reasonable for now (it's configured per IRCd) #define MAXRFCNICKLEN 9 // From RFC 1459 #define MAXTOKENS 100 // For strsep string splitting //#define VERSION "" // VERSION is now passed via -DVERSION by the Makefile // Write debug string to file. // Debug level is provided by level, set to one of DEBUG_CRIT, DEBUG_SOME or DEBUG_FULL. // 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. // 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) void appendcrlf(char *string); // Remove leading colon ':' which is the starting character of a prefix in an IRC message // If no leading colon present, string is left unchanged. // "debug" is used to determine whether stripprefix() should produce all debug output, // used as debug output with stripprefix() can be particularly noisy. void stripprefix(char *string, int debug); // Extract final parameter from IRC message, removing the leading colon ':' void extractfinalparameter(char *string); // Extract the IRC nick from a prefix // e.g. given this string: // ":foo!bar@baz" // We want to end up with: // "foo" // "debug" is used to determine whether extractnickfromprefix() should produce all debug output, // used as debug output with extractnickfromprefix() can be particularly noisy. void extractnickfromprefix(char *string, int debug); // Update an existing nickuserhost string with a new nick void updatenickuserhost(char *nickuserhost, char *nick); // Update an existing 001 greeting with a new nickuserhost void updategreetings(char *greeting001, char *greeting002, char *greeting003, char *greeting004, char *greeting005a, char *greeting005b, char *greeting005c, char *newnickuserhost, char *oldnickuserhost, char *newnick, char *oldnick); // Return index of requested client FD within the clients array. // Returns 0 or more on success, or -1 on failure. // TODO - Use this wherever we are calculating the position (various places) instead of // duplicating code. int arrindex(struct client *clients, int clientfd); // Send whatever string to a specific client by providing the FD // If "bypass" == 1 then permit sending to client even if unauthenticated (for instance for a CAP LS response) int sendtoclient(int fd, char *strsrc, struct client *clients, struct settings *settings, int bypass); // Relay/send message to all clients (optionally except one) // "except" is used to send to all clients _except_ the fd provided (except = 0 (EXCEPT_NONE) avoids this, i.e. sends to all) // "except" is really the "sourcefd" and is also used as part of the authentication check - this is messy and they should perhaps be two separate arguments. int sendtoallclients(struct client *clients, char *strsrc, int except, struct settings *settings); // Send whatever string to the real IRC server // Client FD and arrays needed to make sure anything relayed from a client is from an authenticated client. // clientfd of "0" means trusted, used when we are sending things ourselves that weren't relayed // from a real client. int sendtoserver(SSL *server_ssl, char *strsrc, int str_len, int clientfd, struct client *clients, struct settings *settings); // Disconnect the client fd "fd" by close()ing it and remove // it from the array of clients. // Also set its authentication and registration statuses to 0. // Also set the pending statuses to 0 int disconnectclient(int fd, struct client *clients, struct ircdstate *ircdstate, struct settings *settings, struct clientcodes *clientcodes); int createchannel(struct channel *channels, struct ircdstate *ircdstate, char *name, char *topic, char *topicwho, char *topicwhen); int setchanneltopicwhotime(struct channel *channels, int maxchannelcount, char *channelname, char *who, char *when); int setchanneltopic(struct channel *channels, int maxchannelcount, char *channelname, char *topic); int getchannelcount(struct channel *channels, int maxchannelcount); int removechannel(struct channel *channels, int maxchannelcount, char *name); // Check if we have the NAMES for the channel 'name' already. // Return the 1 if we do, 0 if we don't, or -1 if there's an error. int channelgotnames(struct channel *channels, int maxchannelcount, char *name); // Check if we are in a channel named "name" or not. // Return 1 if we are, or 0 if not. int inchannel(struct channel *channels, int maxchannelcount, char *name); // Returns the array index in the 'channels' array of the channel // named 'channel'. // Returns -1 if there was an error. int channelindex(struct channel *channels, int maxchannelcount, char *name); // Send the auto replay to the requested client, where 'sourcefd' is the client // to send to. The type of replay will depend on the user's settings. // Returns 1 for success or 0 for failure. int doautoreplay(int sourcefd, struct client *clients, struct settings *settings, struct ircdstate *ircdstate, struct channel *channels); // Return a count of the number of connected clients int numclients(struct client *clients); // Join any channels that were configured to be automatically // joined in the configuration file. // Returns 1 on success or 0 on failure. int joinautochannels(SSL *server_ssl, struct client *clients, struct settings *settings); // Try to make a new nick if no configured are available or liked by the server // Do this by sticking a number on the end of the current nick and trying numbers // 1 through to 9. void tryautonick(struct ircdstate *ircdstate); // Exit the program cleanly - tell clients, tell the server, then exit(0) // Optional quit message string "quitmsg" // "sourcefd" of 0 means the request didn't come from a client void cleanexit(SSL *server_ssl, struct client *clients, int sourcefd, struct ircdstate *ircdstate, struct settings *settings, char *quitmsg); // Re-read the configuration file, setting 'failuremsg' to a failure message on failure. // Returns 1 on success or 0 on failure. int rehash(struct settings *settings, char *failuremsg); // Check the password provided in the string 'str' against what is in // the settings structure 'settings'. // Return 0 for password mismatch, or 1 for password match. int checkpassword(char *password, struct settings *settings); // Adds a client code to the clientcode structure if it doesn't already exist. // On success, copy it to the client's clientcode field. // Returns 1 on adding a new code, 0 if the code already existed, or -1 on error. int addclientcode(int sourcefd, char *code, struct clientcodes *clientcodes, struct client *clients); // Sets a given client code as last disconnecting at the current time. // Returns 1 on success or 0 on failure. int setclientcodetime(char *code, struct clientcodes *clientcodes); // Return the timestamp that a given client last disconnected, or 0 on failure. int getclientcodetime(char *code, struct clientcodes *clientcodes); // Replace any instances of "find" with "replace" in the string "str" void replacechar(char *str, char find, char replace); // Add nick (passed as a :nick!user@host) to channel 'channel' // Returns 1 on success or 0 on failure int addnicktochannel(char *nickuserhost, char *channel, struct channel *channels, int maxchannelcount); // Remove nick(passed as a :nick!user@host) from channel 'channel' // Returns 1 on success or 0 on failure int removenickfromchannel(char *nickuserhost, char *channel, struct channel *channels, int maxchannelcount); // Remove nick (passed as a :nick!user@host) from all channels // Returns 1 on success or 0 on failure int removenickfromallchannels(char *nickuserhost, struct channel *channels, int maxchannelcount); // Update old nick (passed as a :nick!user@host) to 'newnick' in all channels // Returns 1 on success or 0 on failure int updatenickinallchannels(char *nickuserhost, char *newnick, struct channel *channels, int maxchannelcount); // Check if "nick" is in a channel or not. // Return 1 if it is, or 0 if not. int isnickinanychannel(struct channel *channels, int maxchannelcount, char *nick); // Populate our channels struct with all nicks in a RPL_NAMREPLY // Returns 1 on success or 0 on failure int addnamereplytochannel(char *namereply, struct channel *channels, int maxchannelcount); // Strips all leading prefixes (colons, user modes) from a nick void stripprefixesfromnick(char *nick); // Convert the given 'string' into lowercase void strlower(char *string); #endif