summaryrefslogtreecommitdiff
path: root/servertest
diff options
context:
space:
mode:
authorTimo Sirainen <cras@irssi.org>1999-09-03 14:27:29 +0000
committercras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564>1999-09-03 14:27:29 +0000
commit770ae4596d3e826c63e8c9fa441d65bd0889f03c (patch)
tree1b1a77a220278cd77da9bfd7958f6ea0a498165b /servertest
parent2d97cd3cc42428155df573e5002a0359da3cdfc1 (diff)
downloadirssi-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/.cvsignore8
-rw-r--r--servertest/Makefile.am13
-rw-r--r--servertest/server.c463
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;
+}