config.mk
setpass
ops.txt
+init.txt
ssize_t send_log(SOCKET socket, const char *buffer, size_t length, int flags) {
printf("SERVER %"PRISocket": %.*s", socket, (int)length, (char*)buffer);
fflush(stdout);
- return send(socket, buffer, length, flags);
+ if (socket != INVALID_SOCKET)
+ return send(socket, buffer, length, flags);
+ else
+ return -1;
}
ssize_t recv_log(SOCKET socket, char *buffer, size_t length, int flags) {
ssize_t bytesRead = recv(socket,buffer,length,flags);
if (!chan->topic) abort();
chan->topic_who = mystrdup(client->nick);
if (!chan->topic_who) abort();
- chan->topic_when = time(NULL);
+ chan->topic_when = get_time();
}
msg_topic(client, chan);
sendbuf_chan(chan);
return err_notregistered(client), sendbuf(client), 0;
if (argc < 2) // FIXME: error message
return 0;
- client->lastactivity = time(NULL);
+ client->lastactivity = get_time();
(command[0] == 'P' ? msg_privmsg : msg_notice)(client, args[0], args[1]);
// TODO: extra target forms such as nick@server #hostmask $servermask
int is_modmsg = !!strchr("@+", args[0][0]);
}
// FIXME: 64-bit time_t
copy_strf(&databuf, ":%s 317 %s %s %u %u :seconds idle, signon time\r\n",
- hostname, client->nick, cl->nick, (unsigned)(time(NULL)-cl->lastactivity), (unsigned)cl->signon);
+ hostname, client->nick, cl->nick, (unsigned)(get_time()-cl->lastactivity), (unsigned)cl->signon);
sendbuf(client);
if (cl->away) {
copy_strf(&databuf, ":%s 301 %s %s :%s\r\n", hostname, client->nick, cl->nick, cl->away);
setNick(client, client->nick_reg);
free(client->nick_reg);
client->nick_reg = NULL;
- client->signon = client->lastactivity = time(NULL);
+ client->signon = client->lastactivity = get_time();
if (!client->nick)
return;
client->regstate = REG_REGISTERED;
chan = malloc(sizeof(struct channel));
if (!chan) abort();
memset(chan, 0, sizeof(struct channel));
- chan->creation = time(NULL);
+ chan->creation = get_time();
chan->member_limit = -1;
chan->dmode = DMODE_NOEXTERNAL | DMODE_TOPICPROT;
chan->key = mystrdup(key);
trie_set(&chan->o, client->key, NULL, NULL);
trie_set(&chan->v, client->key, NULL, NULL);
chan->member_count--;
- if (!chan->member_count) {
+ if (!chan->member_count && !(chan->dmode & DMODE_PERSIST)) {
trie_set(&channel_map, chan->key, NULL, NULL);
free(chan->key);
free(chan->name);
}
#endif
-
+ FILE *f = fopen("init.txt", "rb");
+ if (f) {
+ struct client_data *fake = allocClient();
+ fake->bufCap = sizeof(fake->buf)-1;
+ fake->umode |= UMODE_OPER;
+ strcpy(fake->buf, "NICK :root\r\n");
+ fake->bufLen = strlen(fake->buf);
+ parsePacket(fake);
+ strcpy(fake->buf, "USER root 0 * :Patchouli Knowledge\r\n");
+ fake->bufLen = strlen(fake->buf);
+ parsePacket(fake);
+ while (fgets(fake->buf, sizeof(fake->buf), f)) {
+ int len = strlen(fake->buf);
+ if (!len || fake->buf[len-1] != '\n')
+ break;
+ unsigned long faketime;
+ if (sscanf(fake->buf, "$%lu", &faketime)) {
+ set_time((time_t)faketime);
+ char *p = strchr(fake->buf, ' ');
+ if (!p)
+ continue;
+ len -= ++p - fake->buf;
+ memmove(fake->buf, p, len);
+ }
+ if (fake->buf[0] == ':') {
+ char *sp = strchr(fake->buf, ' ');
+ char *bang = strchr(fake->buf, '!');
+ if (sp && bang && bang < sp) {
+ int nlen = bang - fake->buf - 1;
+ if (memcmp(&fake->buf[1], fake->nick, nlen) != 0) {
+ char *nnick = malloc(nlen+1);
+ if (!nnick)
+ abort();
+ memcpy(nnick, &fake->buf[1], nlen);
+ nnick[nlen] = '\0';
+ free(fake->nick);
+ fake->nick = nnick;
+ }
+ }
+ }
+ fake->bufLen = len;
+ parsePacket(fake);
+ }
+ strcpy(fake->buf, "QUIT :bye\r\n");
+ fake->bufLen = strlen(fake->buf);
+ parsePacket(fake);
+ set_time(0);
+ fclose(f);
+ }
// Main loop
while(is_running){
void killConnection(struct client_data *cl, bool byChoice) {
int i;
char data[1024];
- bool valid=false;
if(cl == 0) return;
for(i=0;i<CLIENTS;i++) {
if(clients[i] == cl) {
clients[i] = 0;
- valid=true;
}
}
- if(!valid){
- return;
- }
#ifdef SUPPORT_IPV4
if(cl->type == 4) {
getpeername(cl->FD,(struct sockaddr*)&serverAddrV4,(socklen_t*)&serverAddrV4len);
msg_error("Closing Link");
sendbuf(cl);
// End GitHub Copilot
- shutdown(cl->FD, SHUT_RDWR);
- closesocket(cl->FD);
+ if (cl->FD != INVALID_SOCKET) {
+ shutdown(cl->FD, SHUT_RDWR);
+ closesocket(cl->FD);
+ }
struct trie_find *f = NULL;
if (trie_findfirst(&f, &cl->channels) == 1)
do {
memcpy(buf, s, len+1);
return buf;
}
+
+static time_t faketime = 0;
+time_t get_time() {
+ return faketime ? faketime : time(NULL);
+}
+void set_time(time_t t) {
+ faketime = t;
+}
#include <stdlib.h>
#include <string.h>
+#include <time.h>
struct dynarr {
char *buf;
#pragma GCC poison strdup
#endif
char *mystrdup(const char *s);
+time_t get_time();
+void set_time(time_t t);