diff options
author | Timo Sirainen <cras@irssi.org> | 1999-09-03 14:27:29 +0000 |
---|---|---|
committer | cras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564> | 1999-09-03 14:27:29 +0000 |
commit | 770ae4596d3e826c63e8c9fa441d65bd0889f03c (patch) | |
tree | 1b1a77a220278cd77da9bfd7958f6ea0a498165b /servertest | |
parent | 2d97cd3cc42428155df573e5002a0359da3cdfc1 (diff) | |
download | irssi-770ae4596d3e826c63e8c9fa441d65bd0889f03c.zip |
Initial revision
git-svn-id: http://svn.irssi.org/repos/irssi/trunk@3 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'servertest')
-rw-r--r-- | servertest/.cvsignore | 8 | ||||
-rw-r--r-- | servertest/Makefile.am | 13 | ||||
-rw-r--r-- | servertest/server.c | 463 |
3 files changed, 484 insertions, 0 deletions
diff --git a/servertest/.cvsignore b/servertest/.cvsignore new file mode 100644 index 00000000..ca8c752b --- /dev/null +++ b/servertest/.cvsignore @@ -0,0 +1,8 @@ +*.la +*.lo +.deps +.libs +Makefile +Makefile.in +so_locations +ircserver diff --git a/servertest/Makefile.am b/servertest/Makefile.am new file mode 100644 index 00000000..4eb03cdf --- /dev/null +++ b/servertest/Makefile.am @@ -0,0 +1,13 @@ +bin_PROGRAMS = ircserver + +INCLUDES = $(GLIB_CFLAGS) -I$(top_srcdir)/src + +if BUILD_MEMDEBUG +memdebug_src=../src/irc-base/memdebug.o +else +memdebug_src= +endif + +ircserver_LDADD = -lglib ../src/irc-base/network.o $(memdebug_src) + +ircserver_SOURCES = server.c diff --git a/servertest/server.c b/servertest/server.c new file mode 100644 index 00000000..90ce2bd5 --- /dev/null +++ b/servertest/server.c @@ -0,0 +1,463 @@ +#include <common.h> + +#include <irc-base/network.h> + +#define FLOOD_TIMEOUT 100000 + +typedef struct +{ + gchar *name; + GList *nicks; +} +CHANNEL_REC; + +GList *channels; +gchar *clientnick, *clienthost; + +int clienth; + +/* Read a line */ +gint read_line(gboolean socket, gint handle, GString *output, GString *buffer) +{ + gchar tmpbuf[512]; + gint recvlen, pos; + + g_return_val_if_fail(handle != -1, -1); + g_return_val_if_fail(output != NULL, -1); + g_return_val_if_fail(buffer != NULL, -1); + + g_string_truncate(output, 0); + + recvlen = socket ? + net_receive(handle, tmpbuf, sizeof(tmpbuf)-1) : + read(handle, tmpbuf, sizeof(tmpbuf)-1); + + if (recvlen <= 0) + { + if (buffer->len > 0) + { + /* no new data got but still something in buffer.. */ + for (pos = 0; pos < buffer->len; pos++) + { + if (buffer->str[pos] == 13 || buffer->str[pos] == 10) + { + recvlen = 0; + break; + } + } + if (recvlen < 0 && buffer->len > 0) + { + /* connection closed and last line is missing \n .. + just add it so we can see if it had anything useful.. */ + recvlen = 0; + g_string_append_c(buffer, '\n'); + } + } + + if (recvlen < 0) return -1; + } + else + { + /* append received data to buffer */ + tmpbuf[recvlen] = '\0'; + g_string_append(buffer, tmpbuf); + } + + for (pos = 0; pos < buffer->len; pos++) + { + if (buffer->str[pos] == 13 || buffer->str[pos] == 10) + { + /* end of line */ + buffer->str[pos] = '\0'; + g_string_assign(output, buffer->str); + + if (buffer->str[pos] == 13 && buffer->str[pos+1] == 10) + { + /* skip \n too */ + pos++; + } + + g_string_erase(buffer, 0, pos+1); + return 1; + } + } + + /* EOL wasn't found, wait for more data.. */ + return 0; +} +void client_send(char *text) +{ + write(clienth, text, strlen(text)); + write(clienth, "\r\n", 2); +} + +void makerand(char *str, int len) +{ + for (; len > 0; len--) + *str++ = (rand() % 20)+'A'; +} + +void makerand2(char *str, int len) +{ +#if 0 + gchar c; + + while (len > 0) + { + c = rand() & 255; + if (c != 0 && c != 13 && c != 10) + { + *str++ = c; + len--; + } + } +#else + makerand(str, len); +#endif +} + +void send_cmd(void) +{ + static gint nicks = 0; + GList *tmp; + char str[512]; + int pos; + + /* send msg to every channel */ + str[511] = '\0'; + + for (tmp = g_list_first(channels); tmp != NULL; tmp = tmp->next) + { + CHANNEL_REC *rec = tmp->data; + + makerand(str, 511); + str[0] = ':'; + str[10] = '!'; + str[20] = '@'; + + switch (rand() % 10) + { + case 0: + /* join */ + pos = 2+sprintf(str+2, "%d", nicks++); /* don't use same nick twice */ + str[pos] = '-'; + str[10] = '\0'; + g_list_append(rec->nicks, g_strdup(str+1)); + str[10] = '!'; + sprintf(str+30, " JOIN :%s", rec->name); + break; + case 1: + /* part */ + if (g_list_length(rec->nicks) > 1 && rand() % 3 == 0) + { + gchar *nick; + + nick = g_list_nth(rec->nicks, rand()%(g_list_length(rec->nicks)-1)+1)->data; + if (rand() % 3 == 0) + sprintf(str, ":kicker!some@where KICK %s %s :go away", rec->name, nick); + else if (rand() % 3 == 0) + sprintf(str, ":%s!dunno@where QUIT %s :i'm outta here", nick, rec->name); + else + sprintf(str, ":%s!dunno@where PART %s", nick, rec->name); + rec->nicks = g_list_remove(rec->nicks, nick); + g_free(nick); + } + else + str[0] = '\0'; + break; + case 2: + /* nick change */ + if (g_list_length(rec->nicks) > 1) + { + gchar *nick; + + nick = g_list_nth(rec->nicks, rand()%(g_list_length(rec->nicks)-1)+1)->data; + pos = sprintf(str, ":%s!dunno@where NICK ", nick); + str[pos] = '_'; + str[50] = '\0'; + rec->nicks = g_list_remove(rec->nicks, nick); + rec->nicks = g_list_append(rec->nicks, g_strdup(str+pos)); + g_free(nick); + } + else + str[0] = '\0'; + break; + case 3: + /* topic */ + pos = 30+sprintf(str+30, " TOPIC %s :", rec->name); + str[pos] = 'x'; + break; + case 4: + /* mode */ + sprintf(str+30, " MODE %s :%cnt", rec->name, (rand() & 1) ? '+' : '-'); + break; + case 5: + /* notice */ + pos = 30+sprintf(str+30, " NOTICE %s :", rec->name); + str[pos] = 'X'; + break; + case 6: + /* nick mode change */ + if (g_list_length(rec->nicks) > 1) + { + gchar *nick; + + nick = g_list_nth(rec->nicks, rand()%(g_list_length(rec->nicks)-1)+1)->data; + pos = sprintf(str, ":server MODE %s +%c %s", rec->name, rand()&1 ? 'o' : 'v', nick); + str[pos] = '_'; + str[50] = '\0'; + rec->nicks = g_list_remove(rec->nicks, nick); + rec->nicks = g_list_append(rec->nicks, g_strdup(str+pos)); + g_free(nick); + } + else + str[0] = '\0'; + break; + default: + pos = 30+sprintf(str+30, " PRIVMSG %s :", rec->name); + makerand2(str+pos, 511-pos); + if (rand() % 4 == 0) + { + pos += sprintf(str+pos, "\001ACTION "); + str[510] = 1; + } + else if (rand() % 10 == 0) + { + pos += sprintf(str+pos, "\001VERSION\001"); + pos++; + } + else if (rand() % 2 == 0) + { + pos += sprintf(str+pos, "%s: ", clientnick); + } + str[pos] = 'X'; + break; + } + + client_send(str); + } + + makerand(str, 511); + str[0] = ':'; + str[10] = '!'; + str[20] = '@'; + + switch (rand() % 11) + { + case 0: + /* join */ + if (g_list_length(channels) < 20) + { + CHANNEL_REC *rec; + int n, pos; + + n = (rand()%20)+25; + pos = sprintf(str, ":%s!%s JOIN :", clientnick, clienthost); + str[pos] = '#'; + str[n] = '\0'; + + rec = g_new(CHANNEL_REC, 1); + rec->name = g_strdup(str+pos); + rec->nicks = g_list_append(NULL, g_strdup(clientnick)); + + channels = g_list_append(channels, rec); + client_send(str); + + sprintf(str, ":server 353 %s = %s :@%s", clientnick, rec->name, clientnick); + client_send(str); + sprintf(str, ":server 366 %s %s :End of /NAMES list.", clientnick, rec->name); + } + else + str[0] = '\0'; + break; + case 1: + /* leave channel (by kick) */ + if (g_list_length(channels) > 3) + { + CHANNEL_REC *chan; + + chan = g_list_nth(channels, rand()%g_list_length(channels))->data; + if (rand() % 3 != 0) + { + pos = sprintf(str, ":%s!%s PART %s :", clientnick, clienthost, chan->name); + str[pos] = 'x'; + } + else + { + str[0] = ':'; + sprintf(str+30, " KICK %s %s :byebye", chan->name, clientnick); + } + + g_free(chan->name); + g_list_foreach(chan->nicks, (GFunc) g_free, NULL); g_list_free(chan->nicks); + g_free(chan); + channels = g_list_remove(channels, chan); + } + else + str[0] = '\0'; + break; + case 2: + /* ctcp version */ + sprintf(str+30, " PRIVMSG %s :\001VERSION\001", clientnick); + break; + case 3: + /* ctcp ping */ + sprintf(str+30, " PRIVMSG %s :\001PING\001", clientnick); + break; + case 4: + /* user mode */ + sprintf(str+30, " MODE %s :%ciw", clientnick, (rand() & 1) ? '+' : '-'); + break; + case 5: + /* msg */ + pos = 30+sprintf(str+30, " PRIVMSG %s :", clientnick); + str[pos] = 'X'; + break; + case 6: + /* notice */ + pos = 30+sprintf(str+30, " NOTICE %s :", clientnick); + str[pos] = 'X'; + break; + case 7: + /* invite */ + pos = 30+sprintf(str+30, " INVITE %s", clientnick); + str[pos] = 'X'; + break; + case 8: + /* error */ + pos = sprintf(str, ":server ERROR :"); + str[pos] = 'X'; + break; + case 9: + /* wallops */ + pos = sprintf(str, ":server WALLOPS :"); + str[pos] = 'X'; + break; + case 10: + /* ping */ + pos = sprintf(str, ":server PING :"); + str[pos] = 'X'; + break; + } + client_send(str); +} + +void handle_command(char *str) +{ + if (strncmp(str, "NICK ", 5) == 0) + { + clientnick = g_strdup(str+5); /* got the nick */ + } +} + +guint gui_timeout_add(guint32 interval, GUITimeoutFunction function, gpointer data) +{ + return -1; +} + +int main(void) +{ + static fd_set fdset; + struct timeval tv; + int serverh, port; + IPADDR ip; + +#ifdef HAVE_IPV6 + if (net_gethostname("::1", &ip) != 0) + { + printf("net_gethostname()\n"); + return 1; + } +#else + if (net_gethostname("127.0.0.1", &ip) != 0) + { + printf("net_gethostname()\n"); + return 1; + } +#endif + + srand(0); + port = 6660; + serverh = net_listen(&ip, &port); + if (serverh == -1) + { + printf("listen()\n"); + return 1; + } + + clienth = -1; channels = NULL; + for (;;) + { + FD_ZERO(&fdset); + if (clienth != -1) FD_SET(clienth, &fdset); + FD_SET(serverh, &fdset); + + tv.tv_sec = 0; + tv.tv_usec = FLOOD_TIMEOUT; + if (select((serverh > clienth ? serverh : clienth)+1, &fdset, NULL, NULL, &tv) <= 0) + { + /* nothing happened, bug the client with some commands.. */ + if (clienth != -1 && clientnick != NULL) send_cmd(); + } + else + { + if (FD_ISSET(serverh, &fdset)) + { + /* client connecting! */ + if (clienth != -1) + { + /* only one client allowed.. */ + int handle; + + handle = net_accept(serverh, NULL, &port); + if (handle != -1) + { + client_send("Only one client allowed"); + close(handle); + continue; + } + } + else + { + IPADDR clientip; + + clienth = net_accept(serverh, &clientip, &port); + if (clienth != -1) + { + clienthost = g_strdup(net_ip2host(&clientip)); + client_send(":server 001 pla"); + client_send(":server 002 plapla"); + client_send(":server 003 plaplapla"); + client_send(":server 004 connected!"); + } + } + } + else + { + /* clients sending something.. */ + GString *str, *buf; + int ret; + + str = g_string_new(NULL); + buf = g_string_new(NULL); + do + { + ret = read_line(TRUE, clienth, str, buf); + if (ret == -1) + { + /* client disconnected */ + close(clienth); + clienth = -1; + break; + } + if (ret == 1) handle_command(str->str); + } + while (ret == 1); + g_string_free(str, TRUE); + g_string_free(buf, TRUE); + } + } + } + + return 0; +} |