$ git clone http://tcclient.ion.nu/tc_client.git
commit 12564543b0a7e9a2a0be24acb662d487e48bada5
Author: Alicia <...>
Date: Tue Apr 7 06:49:01 2015 +0200
Version 0.10
diff --git a/ChangeLog b/ChangeLog
index 4b17eb0..121b8cd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+0.10:
+irchack: stay connected if joining a channel fails and tell the IRC client if a channel password is required.
+irchack: keep listening for connections and accept the next after a session ends.
0.9:
Added compatibility workarounds for android.
Keep track of who is a moderator. (contributed by Jade)
diff --git a/Makefile b/Makefile
index 7b7cee2..90bc106 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-VERSION=0.9
+VERSION=0.10
CFLAGS=-g3 -Wall $(shell curl-config --cflags)
LIBS=-g3 $(shell curl-config --libs)
diff --git a/irchack.c b/irchack.c
index 95484cb..c13fa8b 100644
--- a/irchack.c
+++ b/irchack.c
@@ -96,6 +96,8 @@ int findcolor_ansi(char* irc, char** end)
return -1;
}
+extern char session(int sock, const char* nick, const char* channel, const char* pass);
+
int main(int argc, char** argv)
{
int port=(argc>1?atoi(argv[1]):6667);
@@ -108,57 +110,66 @@ int main(int argc, char** argv)
if(bind(lsock, (struct sockaddr*)&addr, sizeof(addr))){perror("bind"); return 1;}
listen(lsock, 1);
printf("Done! Open an IRC client and connect to localhost on port %i\n", port);
- int sock=accept(lsock, 0, 0);
- close(lsock);
- char buf[2048];
- char* nick=0;
- char* channel=0;
- char* pass=0;
- int len;
- while(!nick || !channel) // Init loop, wait for USER, NICK and JOIN, well not USER
+ int sock;
+ while((sock=accept(lsock, 0, 0))>-1)
{
- len=0;
+ char buf[2048];
+ char* nick=0;
+ char* channel=0;
+ char* pass=0;
+ int len;
while(1)
{
- if(read(sock, &buf[len], 1)!=1 || buf[len]=='\r' || buf[len]=='\n'){break;}
- ++len;
- }
- buf[len]=0;
- if(!strncmp(buf, "NICK ", 5))
- {
- char* newnick=&buf[5];
- if(newnick[0]==':'){newnick=&nick[1];}
- if(!nick)
+ len=0;
+ while(len<2047)
{
- dprintf(sock, ":irchack 001 %s :Welcome\n", newnick);
- }else{
- dprintf(sock, ":%s!user@host NICK :%s\n", nick, newnick);
+ if(read(sock, &buf[len], 1)!=1 || buf[len]=='\r' || buf[len]=='\n'){break;}
+ ++len;
}
- free(nick);
- nick=strdup(newnick);
- }
- else if(!strncmp(buf, "JOIN ", 5))
- {
- free(channel);
- channel=&buf[5];
- if(channel[0]==':'){channel=&channel[1];}
- free(pass);
- pass=strchr(channel, ' ');
- if(pass)
+ buf[len]=0;
+ if(!strncmp(buf, "NICK ", 5))
{
- pass[0]=0;
- pass=&pass[1];
- if(pass[0]==':'){pass=strdup(&pass[1]);}
+ char* newnick=&buf[5];
+ if(newnick[0]==':'){newnick=&nick[1];}
+ if(!nick)
+ {
+ dprintf(sock, ":irchack 001 %s :Welcome\n", newnick);
+ }else{
+ dprintf(sock, ":%s!user@host NICK :%s\n", nick, newnick);
+ }
+ free(nick);
+ nick=strdup(newnick);
+ }
+ else if(nick && !strncmp(buf, "JOIN ", 5))
+ {
+ free(channel);
+ channel=&buf[5];
+ if(channel[0]==':'){channel=&channel[1];}
+ free(pass);
+ pass=strchr(channel, ' ');
+ if(pass)
+ {
+ pass[0]=0;
+ pass=&pass[1];
+ if(pass[0]==':'){pass=strdup(&pass[1]);}
+ }
+ if(channel[0]=='#'){channel=&channel[1];}
+ channel=strdup(channel);
+ if(!session(sock, nick, channel, pass)){break;}
+ }
+ else if(!strncmp(buf, "PING ", 5))
+ {
+ dprintf(sock, ":irchack PONG %s\n", &buf[5]);
}
- if(channel[0]=='#'){channel=&channel[1];}
- channel=strdup(channel);
- }
- else if(!strncmp(buf, "PING ", 5))
- {
- dprintf(sock, ":irchack PONG %s\n", &buf[5]);
}
+ shutdown(sock, SHUT_RDWR);
}
- // We now have what we need to launch tc_client
+ close(lsock);
+ return 0;
+}
+
+char session(int sock, const char* nick, const char* channel, const char* pass)
+{
printf("Nick: %s\n", nick);
printf("Channel: %s\n", channel);
printf("Password: %s\n", pass);
@@ -173,7 +184,7 @@ int main(int argc, char** argv)
dup2(tc_in[0], 0);
dup2(tc_out[1], 1);
execl("./tc_client", "./tc_client", channel, nick, pass, (char*)0);
- printf("Failed to exec tc_client\n");
+ perror("Failed to exec tc_client");
_exit(1);
}
close(tc_in[0]);
@@ -185,6 +196,9 @@ int main(int argc, char** argv)
pfd[1].fd=sock;
pfd[1].events=POLLIN;
pfd[1].revents=0;
+ char buf[2048];
+ int len;
+ char joins=0;
while(1)
{
poll(pfd, 2, -1);
@@ -192,18 +206,13 @@ int main(int argc, char** argv)
{
pfd[0].revents=0;
len=0;
- while(1)
+ while(len<2047)
{
if(read(tc_out[0], &buf[len], 1)!=1 || buf[len]=='\r' || buf[len]=='\n'){break;}
++len;
}
buf[len]=0;
printf("Got from tc_client: '%s'\n", buf);
- if(!strncmp(buf, "Guest ID: ", 10))
- {
- dprintf(sock, ":%s!user@host NICK :guest-%s\n", nick, &buf[10]);
- continue;
- }
if(!strncmp(buf, "Currently online: ", 18))
{
dprintf(sock, ":irchack 353 %s = #%s :", nick, channel);
@@ -216,7 +225,24 @@ printf("Got from tc_client: '%s'\n", buf);
user=next;
}
write(sock, "\n", 1);
+ joins=1;
+ continue;
+ }
+ else if(joins)
+ {
dprintf(sock, ":irchack 366 %s #%s :End of /NAMES list.\n", nick, channel);
+ joins=0;
+ }
+ if(!strcmp(buf, "Password required"))
+ {
+ dprintf(sock, ":irchack 475 %s :Cannot join %s without the correct password\n", channel, channel);
+ close(tc_in[1]);
+ close(tc_out[0]);
+ return 1;
+ }
+ if(!strncmp(buf, "Guest ID: ", 10))
+ {
+ dprintf(sock, ":%s!user@host NICK :guest-%s\n", nick, &buf[10]);
continue;
}
char* space=strchr(buf, ' ');
@@ -284,7 +310,7 @@ printf("Got from tc_client: '%s'\n", buf);
{
pfd[1].revents=0;
len=0;
- while(1)
+ while(len<2047)
{
if(read(sock, &buf[len], 1)!=1 || buf[len]=='\r' || buf[len]=='\n'){break;}
++len;
@@ -331,6 +357,5 @@ printf("Got from IRC client: '%s'\n", buf);
close(tc_in[1]);
close(tc_out[0]);
- shutdown(sock, SHUT_RDWR);
return 0;
}