diff options
| -rw-r--r-- | channel.c | 32 | ||||
| -rw-r--r-- | handle.c | 52 | ||||
| -rw-r--r-- | ircd.h | 2 | ||||
| -rw-r--r-- | loop.c | 2 | ||||
| -rw-r--r-- | peer.c | 9 | ||||
| -rw-r--r-- | reply.c | 2 | ||||
| -rw-r--r-- | writef.c | 28 |
7 files changed, 83 insertions, 44 deletions
diff --git a/channel.c b/channel.c index 0cf0b30..94b0d6c 100644 --- a/channel.c +++ b/channel.c @@ -73,8 +73,38 @@ channel_exit(struct Channel *channel, struct Peer *peer) ensure(i != channels_c, warnx( "channel_exit(): couldn't find empty channel" ), 1); - channels[i] = channels[--channels_c]; + channel_remove(i); } return 0; } + +void +channel_remove(size_t cid) +{ + struct Channel *tofix; + size_t i, j; + + tofix = &channels[channels_c-1]; + for (i = 0; i < tofix->users_c; ++i) + { + for (j = 0; j < tofix->users[i]->channels_c; ++j) + if (!strcmp(tofix->users[i]->channels[j]->name, tofix->name)) + break; + if (j == tofix->users[i]->channels_c) + { + warnx( + "channel_remove(): %s doesn't belong to %s@%s, " + "though they believe in the opposite", + tofix->name, + getnick(tofix->users[i]), + tofix->users[i]->host + ); + continue; + } + + tofix->users[i]->channels[j] = &channels[cid]; + } + + channels[cid] = channels[--channels_c]; +} diff --git a/handle.c b/handle.c index 2a6fe1c..74e354c 100644 --- a/handle.c +++ b/handle.c @@ -26,7 +26,7 @@ static int join(struct Message *msg, struct Peer *peer) { - size_t i, j; + size_t i; /* TODO: support comma separated list of channels, keys */ ensure(peer->type, reply(peer, 451), 0); @@ -34,19 +34,16 @@ join(struct Message *msg, struct Peer *peer) ensure(peer->channels_c != lengthof(peer->channels), reply(peer, 405, msg->params[0]), 0) ensure(*msg->params[0] == '#', reply(peer, 403, msg->params[0]), 0); + for (i = 0; i < peer->channels_c; ++i) + ensure(strcmp(channels[i].name, msg->params[0]), (void)0, 0); + for (i = 0; i < channels_c; ++i) { if (strcmp(channels[i].name, msg->params[0])) continue; - for (j = 0; j < channels[i].users_c; ++j) - ensure( - strcmp(channels[i].users[j]->nick, peer->nick), - (void)0, - 0 - ); - - ensure(!channel_join(&channels[i], peer), reply(peer, 471), 0); + if (channel_join(&channels[i], peer)) + reply(peer, 471); return 0; } @@ -107,11 +104,21 @@ nick(struct Message *msg, struct Peer *peer) for (i = 0; i < peers_c; ++i) if (peers[i].fd != peer->fd) ensure( - !strcmp(peers[i].nick, peer->nick), + strcmp(peers[i].nick, msg->params[0]), reply(peer, 433, msg->params[0]), 0 ); + if (peer->type) + announce( + peer, + ":%s!%s@%s NICK %s", + getnick(peer), + peer->user, + peer->host, + msg->params[0] + ); + user_reg(peer, msg->params[0], NULL, NULL, NULL); return 0; @@ -210,39 +217,20 @@ privmsg(struct Message *msg, struct Peer *peer) static int quit(struct Message *msg, struct Peer *peer) { - size_t i, j; + size_t i; ensure(peer->type, (void)0, 1) - writef( - peer->fd, + announce( + peer, ":%s!%s@%s QUIT :%s", getnick(peer), peer->user, peer->host, msg->params[0] ? msg->params[0] : "Client Quit" ); - for (i = 0; i < peer->channels_c; ++i) - { channel_exit(peer->channels[i], peer); - for (j = 0; j < peer->channels[i]->users_c; ++j) - peer->channels[i]->users[j]->flags |= ANNOUNCE; - } - - for (i = 0; i < peers_c; ++i) - if (peers[i].flags & ANNOUNCE) - { - writef( - peers[i].fd, - ":%s!%s@%s QUIT :%s", - getnick(peer), - peer->user, - peer->host, - msg->params[0] ? msg->params[0] : "Client Quit" - ); - peers[i].flags &= ~ANNOUNCE; - } return 1; } diff --git a/ircd.h b/ircd.h index 2c4b144..0cb20dc 100644 --- a/ircd.h +++ b/ircd.h @@ -92,11 +92,13 @@ void user_remove(size_t pid); int channel_join(struct Channel *channel, struct Peer *peer); int channel_exit(struct Channel *channel, struct Peer *peer); +void channel_remove(size_t cid); 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); +void announce(struct Peer *peer, const char *fmt, ...); int writef(int fd, const char *fmt, ...); int writechanf(const struct Peer *except, const struct Channel *channel, const char *fmt, ...); void ircd(void); diff --git a/loop.c b/loop.c index cfba4b6..fdb2e66 100644 --- a/loop.c +++ b/loop.c @@ -126,7 +126,7 @@ loop: writef(peers[i].fd, "ERROR :Closing Link: %s", peers[i].host); close(peers[i].fd); user_remove(i); - i = 0; + --i; } goto loop; } diff --git a/peer.c b/peer.c index 21dba70..3634834 100644 --- a/peer.c +++ b/peer.c @@ -60,14 +60,5 @@ handle(struct Peer *peer) next: move(peer, p - peer->buf + 2); } - if (peer->recvd == sizeof(peer->buf)) - { - /* - * TODO: maybe somehow be more careful with peer data? - * or drop them? - */ - memset(peer->buf, 0, sizeof(peer->buf)); - peer->recvd = 0; - } return 0; } diff --git a/reply.c b/reply.c index 5409908..f89a8c9 100644 --- a/reply.c +++ b/reply.c @@ -126,7 +126,7 @@ vreply(const struct Peer *peer, int number, va_list ap) getnick(peer) ), _); REPLY(433, WRITE( - ":%s 431 %s %s :Nickname is already in use", + ":%s 433 %s %s :Nickname is already in use", hostname, getnick(peer), nick diff --git a/writef.c b/writef.c index e010ca4..c5e6b95 100644 --- a/writef.c +++ b/writef.c @@ -65,3 +65,31 @@ writechanf(const struct Peer *except, const struct Channel *channel, const char return count; } + +void +announce(struct Peer *peer, const char *fmt, ...) +{ + va_list args; + size_t i, j; + + va_start(args, fmt); + vstoref(fmt, args); + va_end(args); + + if (!peer->channels_c) + { + write(peer->fd, buf, written); + return; + } + + for (i = 0; i < peer->channels_c; ++i) + for (j = 0; j < peer->channels[i]->users_c; ++j) + peer->channels[i]->users[j]->flags |= ANNOUNCE; + + for (i = 0; i < peers_c; ++i) + if (peers[i].flags & ANNOUNCE) + { + write(peers[i].fd, buf, written); + peers[i].flags &= ~ANNOUNCE; + } +} |