summaryrefslogtreecommitdiff
path: root/src/irc/core/irc-server.h
blob: bc51839f091da3f1fe41525ffdf07d84fbeac161 (plain)
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
#ifndef __IRC_SERVER_H
#define __IRC_SERVER_H

#include "server.h"

enum {
	SERVER_TYPE_IRC
};

/* return if `server' doesn't point to IRC server record. */
#define irc_server_check(server) \
	((server) != NULL && module_find_id("IRC SERVER", (server)->type) != -1)

/* all strings should be either NULL or dynamically allocated */
/* address and nick are mandatory, rest are optional */
typedef struct {
        /* -- GENERIC SERVER_CONNECT_REC - don't change! -- */
	/* if we're connecting via proxy, or just NULLs */
	char *proxy;
	int proxy_port;
	char *proxy_string;

	/* server where we want to connect */
	char *address;
	int port;
	char *ircnet;

	IPADDR *own_ip;

	char *password;
	char *nick;
	char *username;
	char *realname;

	/* when reconnecting, the old server status */
	int reconnection:1; /* we're trying to reconnect */
	char *channels;
	char *away_reason;
	char *usermode;

	/* -- IRC specific - change if you wish -- */
	char *alternate_nick;

	int max_cmds_at_once;
	int cmd_queue_speed;
	int max_kicks, max_msgs, max_modes, max_whois;
} IRC_SERVER_CONNECT_REC;

typedef struct {
        /* -- GENERIC SERVER_REC - don't change! -- */
	int type; /* server type */

	IRC_SERVER_CONNECT_REC *connrec;
	time_t connect_time; /* connection time */
	time_t real_connect_time; /* time when server replied that we really are connected */

	char *tag; /* tag name for addressing server */
	char *nick; /* current nick */

	int connected:1; /* connected to server */
	int connection_lost:1; /* Connection lost unintentionally */

        void *handle; /* NET_SENDBUF_REC socket */
	int readtag; /* input tag */

	/* for net_connect_nonblock() */
	int connect_pipe[2];
	int connect_tag;
	int connect_pid;

	/* For deciding if event should be handled internally */
	GHashTable *eventtable; /* "event xxx" : GSList* of REDIRECT_RECs */
	GHashTable *eventgrouptable; /* event group : GSList* of REDIRECT_RECs */
	GHashTable *cmdtable; /* "command xxx" : REDIRECT_CMD_REC* */

	void *rawlog;
	void *buffer; /* receive buffer */
	GHashTable *module_data;

	char *version; /* server version - taken from 004 event */
	char *away_reason;
	int usermode_away:1;
	int banned:1; /* not allowed to connect to this server */

	/* -- IRC specific - change if you wish -- */
	char *real_address; /* address the irc server gives */
	char *usermode; /* The whole mode string .. */
        char *userhost; /* /USERHOST <nick> - set when joined to first channel */
        char *last_invite; /* channel where you were last invited */
	int server_operator:1;

	int whois_coming:1; /* Mostly just to display away message right.. */
	int whois_found:1; /* Did WHOIS return any entries? */
	int whowas_found:1; /* Did WHOWAS return any entries? */

	int emode_known:1; /* Server understands ban exceptions and invite lists */
	int no_multi_mode:1; /* Server doesn't understand MODE #chan1,#chan2,... */
	int no_multi_who:1; /* Server doesn't understand WHO #chan1,#chan2,... */
	int one_endofwho:1; /* /WHO #a,#b,.. replies only with one End of WHO message */

	int max_kicks_in_cmd; /* max. number of people to kick with one /KICK command */
	int max_modes_in_cmd; /* max. number of mode changes in one /MODE command */
	int max_whois_in_cmd; /* max. number of nicks in one /WHOIS command */
	int max_msgs_in_cmd; /* max. number of targets in one /MSG */

	/* Command sending queue */
	int cmdcount; /* number of commands in `cmdqueue'. Can be more than
	                 there actually is, to make flood control remember
			 how many messages can be sent before starting the
			 flood control */
	int cmd_last_split; /* Last command wasn't sent entirely to server.
	                       First item in `cmdqueue' should be re-sent. */
	GSList *cmdqueue;
	GTimeVal last_cmd; /* last time command was sent to server */

	int max_cmds_at_once; /* How many messages can be sent immediately before timeouting starts */
	int cmd_queue_speed; /* Timeout between sending commands */

	GSList *idles; /* Idle queue - send these commands to server
	                  if there's nothing else to do */

	GSList *ctcpqueue; /* CTCP flood protection - list of tags in idle queue */

	/* /knockout ban list */
	GSList *knockoutlist;
	time_t knockout_lastcheck;

	GHashTable *splits; /* For keeping track of netsplits */
	GSList *split_servers; /* Servers that are currently in split */

	time_t lag_sent; /* 0 or time when last lag query was sent to server */
	time_t lag_last_check; /* last time we checked lag */
	int lag; /* server lag in milliseconds */

	GSList *channels;
        GSList *queries;

	GSList *rejoin_channels; /* try to join to these channels after a while -
	                            channels go here if they're "temporarily unavailable"
				    because of netsplits */
	gpointer chanqueries;
} IRC_SERVER_REC;

IRC_SERVER_REC *irc_server_connect(IRC_SERVER_CONNECT_REC *conn);

/* Return a string of all channels (and keys, if any have them) in server,
   like "#a,#b,#c,#d x,b_chan_key,x,x" or just "#e,#f,#g" */
char *irc_server_get_channels(IRC_SERVER_REC *server);

/* INTERNAL: Free memory used by connection record */
void irc_server_connect_free(IRC_SERVER_CONNECT_REC *rec);

void irc_servers_init(void);
void irc_servers_deinit(void);

#endif