channel_part(cl, chan, reason, kicker);
return 0;
}
+static int fn_channel_new(lua_State *L)
+{
+ const char *channel = luaL_checkstring(L, 1);
+ time_t creation = luaL_optinteger(L, 2, 0);
+ size_t chanlen = strlen(channel);
+ if (chanlen > 32)
+ return 0; // FIXME: error
+ char key[33];
+ memcpy(key, channel, chanlen+1);
+ stringlower(key);
+ struct channel *chan = map_get(&channel_map, key);
+ if (!chan) {
+ chan = channel_new(channel, key, creation ? creation : get_time());
+ if (map_set(&channel_map, key, chan, NULL) == -1)
+ abort();
+ }
+ return 0;
+}
+static int fn_channel_mode(lua_State *L)
+{
+ struct channel *chan = *(struct channel **)luaL_checkudata(L, 1, "channel");
+ size_t as, bs;
+ const char *a = luaL_checklstring(L, 2, &as);
+ const char *b = luaL_optlstring(L, 3, 0, &bs);
+ char *buf = malloc(as+bs+2);
+ memcpy(buf, a, as+1);
+ if (b)
+ memcpy(buf+as+1, b, bs+1);
+ char *args[] = { buf, b ? buf+as+1 : 0, 0 };
+ channel_mode(0, chan, args);
+ free(buf);
+ return 0;
+}
+static int fn_channel_topic(lua_State *L)
+{
+ struct channel *chan = *(struct channel **)luaL_checkudata(L, 1, "channel");
+ const char *topic = luaL_checkstring(L, 2);
+ const char *who = luaL_checkstring(L, 3);
+ time_t when = luaL_optinteger(L, 4, 0);
+ channel_topic(0, chan, topic, who, when ? when : get_time());
+ return 0;
+}
static int fn_client_chghost(lua_State *L)
{
struct client_data *cl = *(struct client_data **)luaL_checkudata(L, 1, "client");
lua_setglobal(L, "channel_join");
lua_pushcfunction(L, fn_channel_part);
lua_setglobal(L, "channel_part");
+ lua_pushcfunction(L, fn_channel_new);
+ lua_setglobal(L, "channel_new");
+ lua_pushcfunction(L, fn_channel_mode);
+ lua_setglobal(L, "channel_mode");
+ lua_pushcfunction(L, fn_channel_topic);
+ lua_setglobal(L, "channel_topic");
lua_pushcfunction(L, fn_client_chghost);
lua_setglobal(L, "client_chghost");
lua_pushcfunction(L, fn_rpl_whoisspecial);
// TODO: membership check, maybe?
if (chan->dmode & DMODE_TOPICPROT && !map_get(&chan->o, client->key))
return 0; // FIXME: error 482
- free(chan->topic);
- free(chan->topic_who);
- if (!*args[1]) {
- chan->topic = NULL;
- chan->topic_who = NULL;
- chan->topic_when = 0;
- } else {
- chan->topic = mystrdup(args[1]);
- if (!chan->topic) abort();
- chan->topic_who = mystrdup(client->nick);
- if (!chan->topic_who) abort();
- chan->topic_when = get_time();
- }
- msg_topic(client, chan);
- chanlog_time(chan->topic_when);
- sendbuf_chan(chan);
+ channel_topic(client, chan, args[1], client->nick, get_time());
}
} else if(strcmp(command, "INVITE") == 0) {
if (!is_registered(client))
struct channel *chan = map_get(&channel_map, key);
int newchan = !chan;
if (!chan) {
- chan = malloc(sizeof(struct channel));
- if (!chan) abort();
- memset(chan, 0, sizeof(struct channel));
- chan->creation = get_time();
- chan->member_limit = -1;
- chan->dmode = DMODE_NOEXTERNAL | DMODE_TOPICPROT;
- chan->key = mystrdup(key);
- if (!chan->key) abort();
- chan->name = mystrdup(channel);
- if (!chan->name) abort();
+ chan = channel_new(channel, key, get_time());
+ chan->dmode &= ~DMODE_PERSIST;
if (map_set(&channel_map, key, chan, NULL) == -1)
abort();
if (map_set(&chan->o, client->key, client, NULL) == -1)
// send names
channel_sendnames(client, chan);
}
+struct channel *channel_new(const char *channel, const char *key, time_t creation)
+{
+ struct channel *chan = malloc(sizeof(struct channel));
+ if (!chan) abort();
+ memset(chan, 0, sizeof(struct channel));
+ chan->creation = creation;
+ chan->member_limit = -1;
+ chan->dmode = DMODE_NOEXTERNAL | DMODE_TOPICPROT | DMODE_PERSIST;
+ chan->key = mystrdup(key);
+ if (!chan->key) abort();
+ chan->name = mystrdup(channel);
+ if (!chan->name) abort();
+ return chan;
+}
void channel_part(struct client_data *client, struct channel *chan, const char *reason, struct client_data *kicker)
{
if (!map_get(&chan->members, client->key))
p++;
}
}
+void channel_topic(struct client_data *src, struct channel *chan, const char *topic, const char *who, time_t when)
+{
+ free(chan->topic);
+ free(chan->topic_who);
+ if (!*topic) {
+ chan->topic = NULL;
+ chan->topic_who = NULL;
+ chan->topic_when = 0;
+ } else {
+ chan->topic = mystrdup(topic);
+ if (!chan->topic) abort();
+ chan->topic_who = mystrdup(who);
+ if (!chan->topic_who) abort();
+ chan->topic_when = when;
+ }
+ if (src)
+ msg_topic(src, chan);
+ else
+ copy_strf(&databuf, ":cia!cia@cia.gov TOPIC %s :%s\r\n",
+ chan->name, chan->topic ? chan->topic : "");
+ chanlog_time(chan->topic_when);
+ sendbuf_chan(chan);
+}
struct client_data *findClient(const char *nickname)
{
char key[MAX_NICKLEN];
void channel_sendtopic(struct client_data *client, struct channel *chan, int joining);
void channel_sendnames(struct client_data *client, struct channel *chan);
void channel_join(struct client_data *client, const char *channel, const char *chankey);
+struct channel *channel_new(const char *channel, const char *key, time_t creation);
void channel_part(struct client_data *client, struct channel *chan, const char *reason, struct client_data *kicker);
void channel_kill(struct channel *chan);
void channel_mode(struct client_data *client, struct channel *chan, char *args[]);
+void channel_topic(struct client_data *src, struct channel *chan, const char *topic, const char *who, time_t when);
extern struct dynarr databuf;
#endif