update.
This commit is contained in:
parent
a44c5b9bc2
commit
911fbb4681
83
irc_server.c
83
irc_server.c
@ -194,23 +194,23 @@ static void broadcast_channel(Channel *ch, Client *from, const char *fmt, ...) {
|
||||
static void send_motd(Client *c) {
|
||||
FILE *f = fopen(MOTD_FILE, "r");
|
||||
if (!f) {
|
||||
send_reply(c, "422 %s :MOTD File is missing", c->nickname[0]?c->nickname:"*");
|
||||
send_reply(c, "%s :MOTD File is missing", c->nickname[0]?c->nickname:"*");
|
||||
return;
|
||||
}
|
||||
send_reply(c, "375 %s :- %s Message of the day -", c->nickname, SERVER_NAME);
|
||||
send_reply(c, "%s :- %s Message of the day -", c->nickname, SERVER_NAME);
|
||||
char line[256];
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
line[strcspn(line, "\r\n")] = 0;
|
||||
send_reply(c, "372 %s :- %s", c->nickname, line);
|
||||
send_reply(c, "%s :- %s", c->nickname, line);
|
||||
}
|
||||
send_reply(c, "376 %s :End of /MOTD command", c->nickname);
|
||||
send_reply(c, "%s :End of /MOTD command", c->nickname);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
static void send_lusers(Client *c) {
|
||||
int count = 0;
|
||||
for (Client *cl = clients; cl; cl = cl->next) count++;
|
||||
send_reply(c, "251 %s :There are %d users and 0 services on 1 server", c->nickname, count);
|
||||
send_reply(c, "%s :There are %d users and 0 services on 1 server", c->nickname, count);
|
||||
}
|
||||
|
||||
static void send_names(Client *c, Channel *ch) {
|
||||
@ -220,22 +220,19 @@ static void send_names(Client *c, Channel *ch) {
|
||||
strncat(names, ch->members[i]->nickname, sizeof(names) - strlen(names) - 1);
|
||||
if (i < ch->member_count-1 && strlen(names) + 2 < sizeof(names)) strncat(names, " ", sizeof(names) - strlen(names) - 1);
|
||||
}
|
||||
send_reply(c, "353 %s = %s :%s", c->nickname, ch->name, names);
|
||||
send_reply(c, "366 %s %s :End of NAMES list", c->nickname, ch->name);
|
||||
send_reply(c, "%s = %s :%s", c->nickname, ch->name, names);
|
||||
send_reply(c, "%s %s :End of NAMES list", c->nickname, ch->name);
|
||||
}
|
||||
|
||||
static void send_list(Client *c, Channel *ch) {
|
||||
send_reply(c, "322 %s %s %d :%s", c->nickname, ch->name, ch->member_count, ch->topic[0]?ch->topic:"");
|
||||
send_reply(c, "%s %s %d :%s", c->nickname, ch->name, ch->member_count, ch->topic[0]?ch->topic:"");
|
||||
}
|
||||
|
||||
static void handle_registration(Client *c) {
|
||||
if (c->registered) return;
|
||||
if (!c->nickname[0] || !c->user[0]) return;
|
||||
c->registered = 1;
|
||||
send_reply(c, "001 %s :Hi, welcome to IRC", c->nickname);
|
||||
send_reply(c, "002 %s :Your host is %s, running version rirc-%s", c->nickname, SERVER_NAME, VERSION);
|
||||
send_reply(c, "003 %s :This server was created sometime", c->nickname);
|
||||
send_reply(c, "004 %s %s rirc-%s o o", c->nickname, SERVER_NAME, VERSION);
|
||||
send_reply(c, "%s %s rirc-%s o o", c->nickname, SERVER_NAME, VERSION);
|
||||
send_lusers(c);
|
||||
send_motd(c);
|
||||
}
|
||||
@ -245,27 +242,27 @@ static void handle_line(Client *c, char *line) {
|
||||
if (!cmd) return;
|
||||
if (strcasecmp(cmd, "NICK") == 0) {
|
||||
char *nick = strtok(NULL, " ");
|
||||
if (!nick) { send_reply(c, "431 :No nickname given"); return; }
|
||||
if (find_client_by_nick(nick)) { send_reply(c, "433 * %s :Nickname is already in use", nick); return; }
|
||||
if (!nick) { send_reply(c, ":No nickname given"); return; }
|
||||
if (find_client_by_nick(nick)) { send_reply(c, "* %s :Nickname is already in use", nick); return; }
|
||||
strncpy(c->nickname, nick, MAX_NICKLEN);
|
||||
handle_registration(c);
|
||||
} else if (strcasecmp(cmd, "USER") == 0) {
|
||||
char *user = strtok(NULL, " ");
|
||||
strtok(NULL, " "); strtok(NULL, " ");
|
||||
char *realname = strtok(NULL, ":");
|
||||
if (!user || !realname) { send_reply(c, "461 * USER :Not enough parameters"); return; }
|
||||
if (!user || !realname) { send_reply(c, "* USER :Not enough parameters"); return; }
|
||||
strncpy(c->user, user, MAX_USERLEN);
|
||||
strncpy(c->realname, realname, MAX_USERLEN);
|
||||
handle_registration(c);
|
||||
} else if (strcasecmp(cmd, "PASS") == 0) {
|
||||
char *pass = strtok(NULL, " ");
|
||||
if (!password) { c->pass_ok = 1; return; }
|
||||
if (!pass) { send_reply(c, "461 * PASS :Not enough parameters"); return; }
|
||||
if (!pass) { send_reply(c, "* PASS :Not enough parameters"); return; }
|
||||
if (strcmp(pass, password) == 0) c->pass_ok = 1;
|
||||
else send_reply(c, "464 :Password incorrect");
|
||||
else send_reply(c, ":Password incorrect");
|
||||
} else if (strcasecmp(cmd, "PING") == 0) {
|
||||
char *arg = strtok(NULL, " ");
|
||||
if (!arg) { send_reply(c, "409 %s :No origin specified", c->nickname); return; }
|
||||
if (!arg) { send_reply(c, "%s :No origin specified", c->nickname); return; }
|
||||
send_reply(c, "PONG %s :%s", SERVER_NAME, arg);
|
||||
} else if (strcasecmp(cmd, "PONG") == 0) {
|
||||
c->sent_ping = 0;
|
||||
@ -275,57 +272,57 @@ static void handle_line(Client *c, char *line) {
|
||||
close(c->fd); c->fd = -1;
|
||||
} else if (strcasecmp(cmd, "JOIN") == 0) {
|
||||
char *chan = strtok(NULL, " ");
|
||||
if (!chan) { send_reply(c, "461 %s JOIN :Not enough parameters", c->nickname); return; }
|
||||
if (!chan) { send_reply(c, "%s JOIN :Not enough parameters", c->nickname); return; }
|
||||
Channel *ch = get_or_create_channel(chan);
|
||||
add_client_to_channel(c, ch);
|
||||
send_raw(c, ":%s!%s@%s JOIN %s", c->nickname, c->user, c->host, ch->name);
|
||||
if (ch->topic[0])
|
||||
send_reply(c, "332 %s %s :%s", c->nickname, ch->name, ch->topic);
|
||||
send_reply(c, "%s %s :%s", c->nickname, ch->name, ch->topic);
|
||||
else
|
||||
send_reply(c, "331 %s %s :No topic is set", c->nickname, ch->name);
|
||||
send_reply(c, "%s %s :No topic is set", c->nickname, ch->name);
|
||||
send_names(c, ch);
|
||||
} else if (strcasecmp(cmd, "PART") == 0) {
|
||||
char *chan = strtok(NULL, " ");
|
||||
Channel *ch = find_channel(chan);
|
||||
if (!ch) { send_reply(c, "403 %s %s :No such channel", c->nickname, chan); return; }
|
||||
if (!ch) { send_reply(c, "%s %s :No such channel", c->nickname, chan); return; }
|
||||
remove_client_from_channel(c, ch);
|
||||
send_raw(c, ":%s!%s@%s PART %s", c->nickname, c->user, c->host, ch->name);
|
||||
} else if (strcasecmp(cmd, "PRIVMSG") == 0 || strcasecmp(cmd, "NOTICE") == 0) {
|
||||
char *target = strtok(NULL, " ");
|
||||
char *msg = strtok(NULL, ":");
|
||||
if (!target) { send_reply(c, "411 %s :No recipient given (%s)", c->nickname, cmd); return; }
|
||||
if (!msg) { send_reply(c, "412 %s :No text to send", c->nickname); return; }
|
||||
if (!target) { send_reply(c, "%s :No recipient given (%s)", c->nickname, cmd); return; }
|
||||
if (!msg) { send_reply(c, "%s :No text to send", c->nickname); return; }
|
||||
Client *dest = find_client_by_nick(target);
|
||||
if (dest) send_raw(dest, ":%s!%s@%s %s %s :%s", c->nickname, c->user, c->host, cmd, target, msg);
|
||||
else {
|
||||
Channel *ch = find_channel(target);
|
||||
if (ch) broadcast_channel(ch, c, ":%s!%s@%s %s %s :%s", c->nickname, c->user, c->host, cmd, target, msg);
|
||||
else send_reply(c, "401 %s %s :No such nick/channel", c->nickname, target);
|
||||
else send_reply(c, "%s %s :No such nick/channel", c->nickname, target);
|
||||
}
|
||||
} else if (strcasecmp(cmd, "TOPIC") == 0) {
|
||||
char *chan = strtok(NULL, " ");
|
||||
Channel *ch = find_channel(chan);
|
||||
if (!ch) { send_reply(c, "403 %s %s :No such channel", c->nickname, chan); return; }
|
||||
if (!ch) { send_reply(c, "%s %s :No such channel", c->nickname, chan); return; }
|
||||
char *topic = strtok(NULL, ":");
|
||||
if (topic) {
|
||||
strncpy(ch->topic, topic, MAX_TOPICLEN);
|
||||
broadcast_channel(ch, NULL, ":%s!%s@%s TOPIC %s :%s", c->nickname, c->user, c->host, ch->name, ch->topic);
|
||||
} else {
|
||||
if (ch->topic[0])
|
||||
send_reply(c, "332 %s %s :%s", c->nickname, ch->name, ch->topic);
|
||||
send_reply(c, "%s %s :%s", c->nickname, ch->name, ch->topic);
|
||||
else
|
||||
send_reply(c, "331 %s %s :No topic is set", c->nickname, ch->name);
|
||||
send_reply(c, "%s %s :No topic is set", c->nickname, ch->name);
|
||||
}
|
||||
} else if (strcasecmp(cmd, "LIST") == 0) {
|
||||
for (Channel *ch = channels; ch; ch = ch->next)
|
||||
send_list(c, ch);
|
||||
send_reply(c, "323 %s :End of LIST", c->nickname);
|
||||
send_reply(c, "%s :End of LIST", c->nickname);
|
||||
} else if (strcasecmp(cmd, "NAMES") == 0) {
|
||||
char *chan = strtok(NULL, " ");
|
||||
if (chan) {
|
||||
Channel *ch = find_channel(chan);
|
||||
if (ch) send_names(c, ch);
|
||||
else send_reply(c, "403 %s %s :No such channel", c->nickname, chan);
|
||||
else send_reply(c, "%s %s :No such channel", c->nickname, chan);
|
||||
} else {
|
||||
for (int i = 0; i < c->channel_count; ++i)
|
||||
send_names(c, c->channels[i]);
|
||||
@ -333,20 +330,20 @@ static void handle_line(Client *c, char *line) {
|
||||
} else if (strcasecmp(cmd, "MODE") == 0) {
|
||||
char *chan = strtok(NULL, " ");
|
||||
Channel *ch = find_channel(chan);
|
||||
if (!ch) { send_reply(c, "403 %s %s :No such channel", c->nickname, chan); return; }
|
||||
if (!ch) { send_reply(c, "%s %s :No such channel", c->nickname, chan); return; }
|
||||
char *flag = strtok(NULL, " ");
|
||||
if (!flag) {
|
||||
send_reply(c, "324 %s %s +", c->nickname, ch->name);
|
||||
send_reply(c, "%s %s +", c->nickname, ch->name);
|
||||
} else if (strcmp(flag, "+k") == 0) {
|
||||
char *key = strtok(NULL, " ");
|
||||
if (!key) { send_reply(c, "461 %s MODE :Not enough parameters", c->nickname); return; }
|
||||
if (!key) { send_reply(c, "%s MODE :Not enough parameters", c->nickname); return; }
|
||||
strncpy(ch->key, key, MAX_CHANNELLEN);
|
||||
broadcast_channel(ch, NULL, ":%s!%s@%s MODE %s +k %s", c->nickname, c->user, c->host, ch->name, key);
|
||||
} else if (strcmp(flag, "-k") == 0) {
|
||||
ch->key[0] = 0;
|
||||
broadcast_channel(ch, NULL, ":%s!%s@%s MODE %s -k", c->nickname, c->user, c->host, ch->name);
|
||||
} else {
|
||||
send_reply(c, "472 %s %s :Unknown MODE flag", c->nickname, flag);
|
||||
send_reply(c, "%s %s :Unknown MODE flag", c->nickname, flag);
|
||||
}
|
||||
} else if (strcasecmp(cmd, "MOTD") == 0) {
|
||||
send_motd(c);
|
||||
@ -363,33 +360,33 @@ static void handle_line(Client *c, char *line) {
|
||||
}
|
||||
nick = strtok(NULL, " ");
|
||||
}
|
||||
send_reply(c, "303 %s :%s", c->nickname, buf);
|
||||
send_reply(c, "%s :%s", c->nickname, buf);
|
||||
} else if (strcasecmp(cmd, "WHO") == 0) {
|
||||
char *chan = strtok(NULL, " ");
|
||||
Channel *ch = find_channel(chan);
|
||||
if (ch) {
|
||||
for (int i = 0; i < ch->member_count; ++i) {
|
||||
Client *m = ch->members[i];
|
||||
send_reply(c, "352 %s %s %s %s %s %s H :0 %s", c->nickname, ch->name, m->user, m->host, SERVER_NAME, m->nickname, m->realname);
|
||||
send_reply(c, "%s %s %s %s %s %s H :0 %s", c->nickname, ch->name, m->user, m->host, SERVER_NAME, m->nickname, m->realname);
|
||||
}
|
||||
send_reply(c, "315 %s %s :End of WHO list", c->nickname, ch->name);
|
||||
send_reply(c, "%s %s :End of WHO list", c->nickname, ch->name);
|
||||
}
|
||||
} else if (strcasecmp(cmd, "WHOIS") == 0) {
|
||||
char *nick = strtok(NULL, " ");
|
||||
Client *u = find_client_by_nick(nick);
|
||||
if (u) {
|
||||
send_reply(c, "311 %s %s %s %s * :%s", c->nickname, u->nickname, u->user, u->host, u->realname);
|
||||
send_reply(c, "312 %s %s %s :%s", c->nickname, u->nickname, SERVER_NAME, SERVER_NAME);
|
||||
send_reply(c, "%s %s %s %s * :%s", c->nickname, u->nickname, u->user, u->host, u->realname);
|
||||
send_reply(c, "%s %s %s :%s", c->nickname, u->nickname, SERVER_NAME, SERVER_NAME);
|
||||
char buf[MAX_MSG] = "";
|
||||
for (int i = 0; i < u->channel_count; ++i) {
|
||||
if (strlen(buf) + strlen(u->channels[i]->name) + 2 >= sizeof(buf)) break;
|
||||
strncat(buf, u->channels[i]->name, sizeof(buf) - strlen(buf) - 1);
|
||||
strncat(buf, " ", sizeof(buf) - strlen(buf) - 1);
|
||||
}
|
||||
send_reply(c, "319 %s %s :%s", c->nickname, u->nickname, buf);
|
||||
send_reply(c, "318 %s %s :End of WHOIS list", c->nickname, u->nickname);
|
||||
send_reply(c, "%s %s :%s", c->nickname, u->nickname, buf);
|
||||
send_reply(c, "%s %s :End of WHOIS list", c->nickname, u->nickname);
|
||||
} else {
|
||||
send_reply(c, "401 %s %s :No such nick", c->nickname, nick);
|
||||
send_reply(c, "%s %s :No such nick", c->nickname, nick);
|
||||
}
|
||||
} else if (strcasecmp(cmd, "AWAY") == 0) {
|
||||
} else if (strcasecmp(cmd, "WALLOPS") == 0) {
|
||||
@ -406,7 +403,7 @@ static void handle_line(Client *c, char *line) {
|
||||
send_raw(c, "CAP * NAK :%s", arg ? arg : "");
|
||||
}
|
||||
} else {
|
||||
send_reply(c, "421 %s %s :Unknown command", c->nickname, cmd);
|
||||
send_reply(c, "%s %s :Unknown command", c->nickname, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user