1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
/*
* This file is part of blabouncer (https://www.blatech.co.uk/l_bratch/blabouncer).
* Copyright (C) 2019 Luke Bratch <luke@bratch.co.uk>.
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <stdarg.h>
#include <limits.h>
#include "sockets.h"
#include "structures.h"
#include "replay.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
// 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
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
void stripprefix(char *string);
// Extract final parameter from IRC message, removing the leading colon ':'
void extractfinalparameter(char *string);
// Extract the IRC nick from a prefix
void extractnickfromprefix(char *string);
// 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.
// 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);
int createchannel(struct channel *channels, char *name, char *topic, char *topicwho, char *topicwhen);
int setchanneltopicwhotime(struct channel *channels, char *channelname, char *who, char *when);
int setchanneltopic(struct channel *channels, char *channelname, char *topic);
int getchannelcount(struct channel *channels);
int removechannel(struct channel *channels, 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, 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, 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, char *name);
// Send the requested number of lines of replay log to the requested client.
// 'sourcefd' is the client to send to, and replayseconds is the number of
// seconds of replay log to replay.
// Returns 1 for success or 0 for failure.
int doreplay(int sourcefd, int replayseconds, struct client *clients, struct settings *settings, struct ircdstate *ircdstate, struct channel *channels);
// 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);
#endif
|