-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstate.c
167 lines (135 loc) · 3.31 KB
/
state.c
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
160
161
162
163
164
165
166
167
#define MODULE_NAME "state"
#include <stdlib.h>
#include <string.h>
#include "util.h"
#include "sett.h"
#include "clt.h"
#include "srv.h"
#include "state.h"
#include "log.h"
#define MAX_CHANNELS 20
#define INITIAL_BUFFER_SIZE 10
#define BUFFER_GFACTOR 2
#define MAX_005LINES 5
struct channel {
char name[200];
char *buffer;
size_t buffer_cur;
};
static char g_sumodes[32];
static char g_scmodes[32];
static char g_005[MAX_005LINES][513];
static int g_n005 = 0;
static char g_nick[10];
static char g_user[32];
static bool g_away = false;
struct channel g_channels[MAX_CHANNELS] = {{"", NULL, 0}};
int g_nchannels = 0;
void state_init(void)
{
INF("Initializing...");
struct settings *s = sett_get();
state_nick_set(s->nick);
}
bool state_nick_set(char *nick)
{
if(strlen(nick) > 9)
return false;
strcpy(g_nick, nick);
return true;
}
const char *state_nick(void) { return g_nick; }
const char *state_server_umodes(void) { return g_sumodes; }
const char *state_server_cmodes(void) { return g_scmodes; }
void state_server_umodes_set(char *s)
{
util_strncpy(g_sumodes, s, sizeof g_sumodes);
}
void state_server_cmodes_set(char *s)
{
util_strncpy(g_scmodes, s, sizeof g_scmodes);
}
void state_server_005_store(char *s)
{
if(g_n005 == MAX_005LINES){ //IDK wat do
DBG("Number of 005 lines exceed "XSTR(MAX_005LINES));
return;
}
util_strncpy(g_005[g_n005++], s, sizeof g_005[0]); //Probably need to modify this a bit
}
void state_server_005(int id)
{
for(int i = 0; i < g_n005; i++)
clt_message_send(id, g_005[i]);
}
void state_channel_join(char *chan)
{
for(int i = 0; i < MAX_CHANNELS; i++)
if(g_channels[i].name[0] == '\0')
util_strncpy(g_channels[i].name, chan, sizeof g_channels[0].name);
g_nchannels++;
}
int state_channel_id_get(char *chan)
{
for(int i = 0; i < MAX_CHANNELS; i++)
if(!strcmp(g_channels[i].name, chan))
return i;
return -1;
}
void state_channel_part(char *chan)
{
g_channels[state_channel_id_get(chan)].name[0] = '\0';
g_nchannels--;
}
void state_channel_client_init(int id)
{
struct settings *s = sett_get();
for(int i = 0; i < MAX_CHANNELS; i++){
if(g_channels[i].name[0] != '\0'){
clt_message_sendf(id, ":%s!%s@%s JOIN %s", g_nick, g_user, s->host, g_channels[i]);
srv_message_sendf("NAMES %s", g_channels[i].name); //Need to route the replies
}
}
}
bool state_is_away(void) { return g_away; }
void state_mark_away(void)
{
g_away = true;
}
void state_unmark_away(void)
{
g_away = false;
for(int i = 0; i < MAX_CHANNELS; i++)
free(g_channels[i].buffer);
}
void state_buffer(char *channel, char* msg)
{
struct channel *c = &g_channels[state_channel_id_get(channel)];
if(!c->buffer){
c->buffer = malloc(sizeof *g_channels[0].buffer * 513 * INITIAL_BUFFER_SIZE);
c->buffer_cur = 0;
}
if(!c->buffer){
DBG("OOM in state_buffer()");
return;
}
char *tmp = NULL;
if(c->buffer_cur && c->buffer_cur % INITIAL_BUFFER_SIZE == 0)
tmp = realloc(c->buffer, sizeof *g_channels[0].buffer * 513 * c->buffer_cur * BUFFER_GFACTOR);
if(!tmp){
DBG("OOM in state_buffer()");
return;
}
else
c->buffer = tmp;
util_strncpy(&c->buffer[c->buffer_cur++], msg, 513);
}
void state_buffer_play(int clid)
{
for(int i = 0; i < MAX_CHANNELS; i++){
struct channel *c = &g_channels[i];
for(int j = 0; j < c->buffer_cur; j++)
clt_message_send(clid, &c->buffer[j]);
}
}
#undef MODULE_NAME