about summary refs log tree commit diff
path: root/ircd.h
blob: 07bdd0f39f0bc2cd9d7f4a2adba10aa9daae3a90 (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
/*
 * Copyright (c) 2026 Nakidai Perumenei <nakidai at disroot dot org>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef __IRCD_H__
#define __IRCD_H__

#include <stddef.h>


#define PARAM_MAX 15

#define MESSAGE_MAX 512
#define PEERS_MAX 512
#define CHANNELS_MAX 512
#define USERS_PER_CHANNEL 512
#define MODES_MAX 512

#define BIT(x) x##_BIT, x = 1 << x##_BIT, x##_BIT_ = x##_BIT
#define lengthof(X) (sizeof(X) / sizeof(*(X)))
#define ensure(cond, iffalse, doexit) if (!(cond)) { iffalse; if (doexit >= 0) return doexit; }

struct Message
{
	char *nick, *user, *host, *command, *params[PARAM_MAX];
};

struct Peer
{
	int fd;
	enum ClientType { UNREGD, CLIENT, SERVER, SERVICE } type;
	char nick[16], user[16], real[32], host[64];
	struct Channel *channels[32];
	enum PeerStatus {
		BIT(DELETE),
		BIT(ANNOUNCE),
	} flags;
	char buf[MESSAGE_MAX];
	size_t recvd, channels_c;
	char modes[52];
};

struct Channel
{
	enum { GLOBAL, LOCAL, MODELESS, SAFE } type;
	char name[64];
	struct {
		char mode;
		char param[MESSAGE_MAX - 1];
	} modes[MODES_MAX];
	struct Peer *users[USERS_PER_CHANNEL];
	size_t modes_c, users_c;
};

typedef int Handler(struct Message *msg, struct Peer *peer);

extern struct Channel channels[CHANNELS_MAX];
extern struct Peer peers[PEERS_MAX];
extern size_t channels_c, peers_c;
extern const char *hostname;
extern const char *host;
extern int port;

const char *getnick(const struct Peer *peer);
void user_reg(struct Peer *peer, const char *nick, const char *user, const char *real);
void user_remove(size_t pid);

int channel_join(struct Channel *channel, struct Peer *peer);
int channel_exit(struct Channel *channel, struct Peer *peer);

int parse_message(char *buf, struct Message *msg);
int handle(struct Peer *peer);
int reply(const struct Peer *peer, int number, ...);
Handler *find(const char *command);
int writef(int fd, const char *fmt, ...);
int writechanf(const struct Peer *except, const struct Channel *channel, const char *fmt, ...);
void ircd(void);

#endif /* __IRCD_H__ */