Compare commits
6
Commits
911fbb4681
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5492c95dd3 | ||
|
|
21d73bc185 | ||
|
|
2ee1ff809c | ||
|
|
33ce55f862 | ||
|
|
7a2e4b570e | ||
|
|
8b3fb39b21 |
@@ -0,0 +1,4 @@
|
||||
irc_echo_boy.py
|
||||
irc_server
|
||||
load_test
|
||||
motd.txt
|
||||
@@ -29,9 +29,9 @@ This project consists of an IRC server implementation and a load testing tool de
|
||||
### Running the IRC Server
|
||||
To start the IRC server, run the following command:
|
||||
```bash
|
||||
./irc_server
|
||||
./irc_server --log
|
||||
```
|
||||
The server will listen on port 6667 by default.
|
||||
The server will listen on port 6667 by default and will log messages to the terminal when the `--log` flag is used.
|
||||
|
||||
### Running the Load Testing Tool
|
||||
To execute the load testing tool, run:
|
||||
@@ -47,5 +47,3 @@ After running the load test, the following metrics will be displayed:
|
||||
- Messages per second
|
||||
- Total bytes sent and received
|
||||
- Send and receive rates in MB/s
|
||||
|
||||
|
||||
|
||||
+98
-50
@@ -21,12 +21,12 @@
|
||||
// MIT License
|
||||
|
||||
#define MAX_EVENTS 4096
|
||||
#define MAX_CHANNELS 1024
|
||||
#define MAX_NICKLEN 51
|
||||
#define MAX_USERLEN 51
|
||||
#define MAX_CHANNELLEN 51
|
||||
#define MAX_TOPICLEN 256
|
||||
#define MAX_MSG 512
|
||||
#define MAX_CHANNELS 4096
|
||||
#define MAX_NICKLEN 4096
|
||||
#define MAX_USERLEN 4096
|
||||
#define MAX_CHANNELLEN 128
|
||||
#define MAX_TOPICLEN 4096
|
||||
#define MAX_MSG 4096
|
||||
#define MOTD_FILE "motd.txt"
|
||||
#define SERVER_NAME "rirc"
|
||||
#define VERSION "1.0"
|
||||
@@ -39,7 +39,7 @@ typedef struct Client {
|
||||
char nickname[MAX_NICKLEN+1];
|
||||
char user[MAX_USERLEN+1];
|
||||
char realname[MAX_USERLEN+1];
|
||||
char host[64];
|
||||
char host[128];
|
||||
int registered;
|
||||
int pass_ok;
|
||||
char readbuf[MAX_MSG*2];
|
||||
@@ -69,6 +69,22 @@ static Channel *channels = NULL;
|
||||
static int listen_fd;
|
||||
static int epoll_fd;
|
||||
static char *password = NULL;
|
||||
static int logging_enabled = 0;
|
||||
|
||||
static void log_event(const char *fmt, ...) {
|
||||
if (!logging_enabled) return;
|
||||
char timebuf[32];
|
||||
time_t now = time(NULL);
|
||||
struct tm tm;
|
||||
gmtime_r(&now, &tm);
|
||||
strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%SZ", &tm);
|
||||
fprintf(stderr, "%s ", timebuf);
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
static void fatal(const char *msg) {
|
||||
perror(msg);
|
||||
@@ -101,6 +117,12 @@ static void del_epoll(int fd) {
|
||||
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL);
|
||||
}
|
||||
|
||||
static void update_client_events(Client *c) {
|
||||
uint32_t events = EPOLLIN;
|
||||
if (c->writebuf_len > 0) events |= EPOLLOUT;
|
||||
mod_epoll(c->fd, events, c);
|
||||
}
|
||||
|
||||
static void send_reply(Client *c, const char *fmt, ...) {
|
||||
char buf[MAX_MSG];
|
||||
va_list ap;
|
||||
@@ -109,6 +131,7 @@ static void send_reply(Client *c, const char *fmt, ...) {
|
||||
va_end(ap);
|
||||
int n = snprintf(c->writebuf + c->writebuf_len, sizeof(c->writebuf) - c->writebuf_len, ":%s %s\r\n", SERVER_NAME, buf);
|
||||
if (n > 0 && c->writebuf_len + n < sizeof(c->writebuf)) c->writebuf_len += n;
|
||||
update_client_events(c);
|
||||
}
|
||||
|
||||
static void send_raw(Client *c, const char *fmt, ...) {
|
||||
@@ -119,6 +142,7 @@ static void send_raw(Client *c, const char *fmt, ...) {
|
||||
va_end(ap);
|
||||
int n = snprintf(c->writebuf + c->writebuf_len, sizeof(c->writebuf) - c->writebuf_len, "%s\r\n", buf);
|
||||
if (n > 0 && c->writebuf_len + n < sizeof(c->writebuf)) c->writebuf_len += n;
|
||||
update_client_events(c);
|
||||
}
|
||||
|
||||
static Channel *find_channel(const char *name) {
|
||||
@@ -151,6 +175,7 @@ static void add_client_to_channel(Client *c, Channel *ch) {
|
||||
c->channels = realloc(c->channels, c->channel_capacity * sizeof(Channel*));
|
||||
}
|
||||
c->channels[c->channel_count++] = ch;
|
||||
log_event("user joined: %s (%s) joined channel %s", c->nickname[0]?c->nickname:"<unreg>", c->host, ch->name);
|
||||
}
|
||||
|
||||
static void remove_client_from_channel(Client *c, Channel *ch) {
|
||||
@@ -159,6 +184,7 @@ static void remove_client_from_channel(Client *c, Channel *ch) {
|
||||
for (int j = i; j < ch->member_count-1; ++j)
|
||||
ch->members[j] = ch->members[j+1];
|
||||
ch->member_count--;
|
||||
log_event("user left: %s (%s) left channel %s", c->nickname[0]?c->nickname:"<unreg>", c->host, ch->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -194,23 +220,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, "%s :MOTD File is missing", c->nickname[0]?c->nickname:"*");
|
||||
send_reply(c, "422 %s :MOTD File is missing", c->nickname[0]?c->nickname:"*");
|
||||
return;
|
||||
}
|
||||
send_reply(c, "%s :- %s Message of the day -", c->nickname, SERVER_NAME);
|
||||
send_reply(c, "375 %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, "%s :- %s", c->nickname, line);
|
||||
send_reply(c, "372 %s :- %s", c->nickname, line);
|
||||
}
|
||||
send_reply(c, "%s :End of /MOTD command", c->nickname);
|
||||
send_reply(c, "376 %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, "%s :There are %d users and 0 services on 1 server", c->nickname, count);
|
||||
send_reply(c, "251 %s :There are %d users and 0 services on 1 server", c->nickname, count);
|
||||
}
|
||||
|
||||
static void send_names(Client *c, Channel *ch) {
|
||||
@@ -220,49 +246,53 @@ 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, "%s = %s :%s", c->nickname, ch->name, names);
|
||||
send_reply(c, "%s %s :End of NAMES list", c->nickname, ch->name);
|
||||
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);
|
||||
}
|
||||
|
||||
static void send_list(Client *c, Channel *ch) {
|
||||
send_reply(c, "%s %s %d :%s", c->nickname, ch->name, ch->member_count, ch->topic[0]?ch->topic:"");
|
||||
send_reply(c, "322 %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, "%s %s rirc-%s o o", c->nickname, SERVER_NAME, VERSION);
|
||||
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_lusers(c);
|
||||
send_motd(c);
|
||||
}
|
||||
|
||||
static void handle_line(Client *c, char *line) {
|
||||
log_event("message received: %s (%s): %s", c->nickname[0]?c->nickname:"<unreg>", c->host, line);
|
||||
char *cmd = strtok(line, " ");
|
||||
if (!cmd) return;
|
||||
if (strcasecmp(cmd, "NICK") == 0) {
|
||||
char *nick = strtok(NULL, " ");
|
||||
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; }
|
||||
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; }
|
||||
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, "* USER :Not enough parameters"); return; }
|
||||
if (!user || !realname) { send_reply(c, "461 * 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, "* PASS :Not enough parameters"); return; }
|
||||
if (!pass) { send_reply(c, "461 * PASS :Not enough parameters"); return; }
|
||||
if (strcmp(pass, password) == 0) c->pass_ok = 1;
|
||||
else send_reply(c, ":Password incorrect");
|
||||
else send_reply(c, "464 :Password incorrect");
|
||||
} else if (strcasecmp(cmd, "PING") == 0) {
|
||||
char *arg = strtok(NULL, " ");
|
||||
if (!arg) { send_reply(c, "%s :No origin specified", c->nickname); return; }
|
||||
if (!arg) { send_reply(c, "409 %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;
|
||||
@@ -272,57 +302,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, "%s JOIN :Not enough parameters", c->nickname); return; }
|
||||
if (!chan) { send_reply(c, "461 %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, "%s %s :%s", c->nickname, ch->name, ch->topic);
|
||||
send_reply(c, "332 %s %s :%s", c->nickname, ch->name, ch->topic);
|
||||
else
|
||||
send_reply(c, "%s %s :No topic is set", c->nickname, ch->name);
|
||||
send_reply(c, "331 %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, "%s %s :No such channel", c->nickname, chan); return; }
|
||||
if (!ch) { send_reply(c, "403 %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, "%s :No recipient given (%s)", c->nickname, cmd); return; }
|
||||
if (!msg) { send_reply(c, "%s :No text to send", c->nickname); return; }
|
||||
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; }
|
||||
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, "%s %s :No such nick/channel", c->nickname, target);
|
||||
else send_reply(c, "401 %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, "%s %s :No such channel", c->nickname, chan); return; }
|
||||
if (!ch) { send_reply(c, "403 %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, "%s %s :%s", c->nickname, ch->name, ch->topic);
|
||||
send_reply(c, "332 %s %s :%s", c->nickname, ch->name, ch->topic);
|
||||
else
|
||||
send_reply(c, "%s %s :No topic is set", c->nickname, ch->name);
|
||||
send_reply(c, "331 %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, "%s :End of LIST", c->nickname);
|
||||
send_reply(c, "323 %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, "%s %s :No such channel", c->nickname, chan);
|
||||
else send_reply(c, "403 %s %s :No such channel", c->nickname, chan);
|
||||
} else {
|
||||
for (int i = 0; i < c->channel_count; ++i)
|
||||
send_names(c, c->channels[i]);
|
||||
@@ -330,20 +360,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, "%s %s :No such channel", c->nickname, chan); return; }
|
||||
if (!ch) { send_reply(c, "403 %s %s :No such channel", c->nickname, chan); return; }
|
||||
char *flag = strtok(NULL, " ");
|
||||
if (!flag) {
|
||||
send_reply(c, "%s %s +", c->nickname, ch->name);
|
||||
send_reply(c, "324 %s %s +", c->nickname, ch->name);
|
||||
} else if (strcmp(flag, "+k") == 0) {
|
||||
char *key = strtok(NULL, " ");
|
||||
if (!key) { send_reply(c, "%s MODE :Not enough parameters", c->nickname); return; }
|
||||
if (!key) { send_reply(c, "461 %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, "%s %s :Unknown MODE flag", c->nickname, flag);
|
||||
send_reply(c, "472 %s %s :Unknown MODE flag", c->nickname, flag);
|
||||
}
|
||||
} else if (strcasecmp(cmd, "MOTD") == 0) {
|
||||
send_motd(c);
|
||||
@@ -360,33 +390,33 @@ static void handle_line(Client *c, char *line) {
|
||||
}
|
||||
nick = strtok(NULL, " ");
|
||||
}
|
||||
send_reply(c, "%s :%s", c->nickname, buf);
|
||||
send_reply(c, "303 %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, "%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, "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 :End of WHO list", c->nickname, ch->name);
|
||||
send_reply(c, "315 %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, "%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);
|
||||
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);
|
||||
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, "%s %s :%s", c->nickname, u->nickname, buf);
|
||||
send_reply(c, "%s %s :End of WHOIS list", c->nickname, u->nickname);
|
||||
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);
|
||||
} else {
|
||||
send_reply(c, "%s %s :No such nick", c->nickname, nick);
|
||||
send_reply(c, "401 %s %s :No such nick", c->nickname, nick);
|
||||
}
|
||||
} else if (strcasecmp(cmd, "AWAY") == 0) {
|
||||
} else if (strcasecmp(cmd, "WALLOPS") == 0) {
|
||||
@@ -403,7 +433,7 @@ static void handle_line(Client *c, char *line) {
|
||||
send_raw(c, "CAP * NAK :%s", arg ? arg : "");
|
||||
}
|
||||
} else {
|
||||
send_reply(c, "%s %s :Unknown command", c->nickname, cmd);
|
||||
send_reply(c, "421 %s %s :Unknown command", c->nickname, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,6 +447,7 @@ static void remove_client(Client *c) {
|
||||
while (prev && prev->next != c) prev = prev->next;
|
||||
if (prev) prev->next = c->next;
|
||||
}
|
||||
log_event("user disconnected: %s (%s)", c->nickname[0]?c->nickname:"<unreg>", c->host);
|
||||
del_epoll(c->fd);
|
||||
if (c->fd >= 0) close(c->fd);
|
||||
c->fd = -1;
|
||||
@@ -436,12 +467,28 @@ static void accept_new_client() {
|
||||
c->next = clients;
|
||||
clients = c;
|
||||
add_epoll(fd, EPOLLIN, c);
|
||||
log_event("user connected: %s", c->host);
|
||||
}
|
||||
|
||||
static int parse_args(int argc, char **argv, int *port, char **pass, int *log_enabled) {
|
||||
*port = 6667;
|
||||
*pass = NULL;
|
||||
*log_enabled = 0;
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
if (strcmp(argv[i], "--port") == 0 && i+1 < argc) {
|
||||
*port = atoi(argv[++i]);
|
||||
} else if (strcmp(argv[i], "--password") == 0 && i+1 < argc) {
|
||||
*pass = argv[++i];
|
||||
} else if (strcmp(argv[i], "--log") == 0) {
|
||||
*log_enabled = 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int port = 6667;
|
||||
if (argc > 1) port = atoi(argv[1]);
|
||||
if (argc > 2) password = argv[2];
|
||||
int port;
|
||||
parse_args(argc, argv, &port, &password, &logging_enabled);
|
||||
|
||||
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
int opt = 1;
|
||||
@@ -478,6 +525,7 @@ int main(int argc, char **argv) {
|
||||
char *line, *saveptr;
|
||||
line = strtok_r(c->readbuf, "\r\n", &saveptr);
|
||||
while (line) {
|
||||
printf("%s\n",line);
|
||||
handle_line(c, line);
|
||||
line = strtok_r(NULL, "\r\n", &saveptr);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user