IPv6 Support for mcbot
We initialize the socket functions with AF_UNSPEC and let the library
fill in the proper values. Connects to IPv4 or IPv6.
committer: Markus Bröker <mbroeker@largo.homelinux.org>
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,4 +1,4 @@
-mcbot (0.99-4) unstable; urgency=low
+mcbot (0.99-5) unstable; urgency=low
* Initial Release
* the location of mcbot.cgi is stored in the db
@@ -36,5 +36,6 @@
* user and hostname handling improved
* useless feof handling removed
* spelling error fixed
+ * ipv6 support added
- -- Markus Bröker <mbroeker@largo.homelinux.org> Fri, 22 Oct 2010 19:18:00 +0200
+ -- Markus Bröker <mbroeker@largo.homelinux.org> Sat, 13 Nov 2010 08:13:37 +0100
--- a/include/config.h
+++ b/include/config.h
@@ -11,7 +11,7 @@
char *nick;
char *pass;
char *server;
- int port;
+ char *port;
char *topic;
char *channel;
};
--- a/include/irc.h
+++ b/include/irc.h
@@ -24,7 +24,7 @@
typedef struct Message MSG;
-FILE *irc_connect (char *, unsigned int);
+FILE *irc_connect (char *, char *);
int irc_login (FILE *, char *, char *, char *);
char *irc_parsemessage (const char *, MSG *);
#endif
--- a/src/config.c
+++ b/src/config.c
@@ -46,7 +46,7 @@
* We can easily provide default values ...
*/
uc->nick = uc->pass = uc->server = uc->channel = uc->topic = NULL;
- uc->port = 6667;
+ uc->port = "6667";
while (!feof (f)) {
if (fgets (buffer, sizeof (buffer), f) == NULL)
@@ -91,7 +91,7 @@
free (line[map]);
break;
case PORT:
- uc->port = atoi (line[map]);
+ uc->port = compat_strdup (line[map]);
free (line[map]);
break;
case CHANNEL:
--- a/src/irc.c
+++ b/src/irc.c
@@ -34,33 +34,41 @@
"KICK", NULL
};
-FILE *irc_connect (char *server, unsigned int port)
+FILE *irc_connect (char *server, char *port)
{
- struct hostent *he;
- char *ip;
- struct sockaddr_in ca;
- int csocket;
+ struct addrinfo hints;
+ struct addrinfo *result, *rp;
+
+ int csocket = -1;
FILE *stream;
- he = gethostbyname (server);
- if (he == NULL) {
- perror ("GETHOSTBYNAME");
+ memset (&hints, 0, sizeof (struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = 0;
+ hints.ai_protocol = IPPROTO_TCP;
+
+ if (getaddrinfo (server, port, &hints, &result) != 0) {
+ perror ("getaddrinfo");
return NULL;
}
- if ((ip = inet_ntoa (*((struct in_addr *)he->h_addr_list[0]))) == NULL) {
- perror ("INET_NTOA");
- return NULL;
- } else
- printf ("IP: %s\n", ip);
+ for (rp = result; rp != NULL; rp = rp->ai_next) {
+ if ((csocket = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol)) == -1)
+ continue;
- ca.sin_family = AF_INET;
- ca.sin_addr.s_addr = inet_addr (ip);
- ca.sin_port = htons (port);
+ if (connect (csocket, rp->ai_addr, rp->ai_addrlen) != -1) {
+ fprintf (stderr, "Connected via %s\n", (rp->ai_family == AF_INET6) ? "IPv6" : "IPv4");
+ break;
+ }
+ close (csocket);
+ }
- csocket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (connect (csocket, (struct sockaddr *)&ca, (socklen_t) sizeof (ca)) == -1) {
- perror ("CONNECT");
+ if (result != NULL)
+ freeaddrinfo (result);
+
+ if (csocket < 0) {
+ perror ("Cannot connect");
return NULL;
}