ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/irc.c
(Generate patch)

Comparing hopm/trunk/src/irc.c (file contents):
Revision 5358 by michael, Sun Jan 11 18:51:07 2015 UTC vs.
Revision 5367 by michael, Mon Jan 12 20:13:22 2015 UTC

# Line 26 | Line 26
26   #include <string.h>
27   #include <sys/types.h>
28   #include <sys/socket.h>
29 + #include <netdb.h>
30   #include <netinet/in.h>
31   #include <arpa/inet.h>
32   #include <poll.h>
# Line 82 | Line 83 | static char          IRC_RAW[MSGLENMAX];
83   static unsigned int  IRC_RAW_LEN    = 0;         /* Position of IRC_RAW                   */
84   static int           IRC_FD         = 0;         /* File descriptor for IRC client        */
85  
86 < static struct sockaddr_in IRC_SVR;              /* Sock Address Struct for IRC server    */
86 < static struct in_addr IRC_LOCAL;                /* Sock Address Struct for Bind          */
86 > static struct sockaddr_storage IRC_SVR;          /* Sock Address Struct for IRC server    */
87  
88   static time_t IRC_LAST = 0;                      /* Last full line of data from irc server*/
89   static time_t IRC_LASTRECONNECT = 0;             /* Time of last reconnection */
# Line 168 | Line 168 | irc_cycle(void)
168   static void
169   irc_init(void)
170   {
171 <  struct sockaddr_in bsaddr;
172 <  struct in_addr *irc_host;
171 >  const void *address = NULL;
172  
173    if (IRC_FD)
174      close(IRC_FD);
175  
176    memset(&IRC_SVR, 0, sizeof(IRC_SVR));
178  memset(&IRC_LOCAL, 0, sizeof(IRC_LOCAL));
179  memset(&bsaddr, 0, sizeof(bsaddr));
177  
178    /* Resolve IRC host. */
179 <  if ((irc_host = firedns_resolveip4(IRCItem->server)) == NULL)
179 >  if ((address = firedns_resolveip6(IRCItem->server)))
180    {
181 <    log_printf("IRC -> firedns_resolveip4(\"%s\"): %s", IRCItem->server,
185 <               firedns_strerror(fdns_errno));
186 <    exit(EXIT_FAILURE);
187 <  }
181 >    struct sockaddr_in6 *in = (struct sockaddr_in6 *)&IRC_SVR;
182  
183 <  IRC_SVR.sin_family = AF_INET;
184 <  IRC_SVR.sin_port = htons(IRCItem->port);
185 <  IRC_SVR.sin_addr = *irc_host;
183 >    IRC_SVR.ss_family = AF_INET6;
184 >    in->sin6_port = htons(IRCItem->port);
185 >    memcpy(&in->sin6_addr, address, sizeof(in->sin6_addr));
186 >  }
187 >  else if ((address = firedns_resolveip4(IRCItem->server)))
188 >  {
189 >    struct sockaddr_in *in = (struct sockaddr_in *)&IRC_SVR;
190  
191 <  if (IRC_SVR.sin_addr.s_addr == INADDR_NONE)
191 >    IRC_SVR.ss_family = AF_INET;
192 >    in->sin_port = htons(IRCItem->port);
193 >    memcpy(&in->sin_addr, address, sizeof(in->sin_addr));
194 >  }
195 >  else
196    {
197 <    log_printf("IRC -> Unknown error resolving remote host (%s)",
198 <               IRCItem->server);
197 >    log_printf("IRC -> firedns_resolveip(\"%s\"): %s", IRCItem->server,
198 >               firedns_strerror(fdns_errno));
199      exit(EXIT_FAILURE);
200    }
201  
202    /* Request file desc for IRC client socket */
203 <  IRC_FD = socket(AF_INET, SOCK_STREAM, 0);
203 >  IRC_FD = socket(IRC_SVR.ss_family, SOCK_STREAM, 0);
204  
205    if (IRC_FD == -1)
206    {
# Line 209 | Line 211 | irc_init(void)
211    /* Bind */
212    if (!EmptyString(IRCItem->vhost))
213    {
214 <    if (inet_pton(AF_INET, IRCItem->vhost, &IRC_LOCAL.s_addr) <= 0)
214 >    struct addrinfo hints, *res;
215 >
216 >    memset(&hints, 0, sizeof(hints));
217 >
218 >    hints.ai_family = AF_UNSPEC;
219 >    hints.ai_socktype = SOCK_STREAM;
220 >    hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
221 >
222 >    if (getaddrinfo(IRCItem->vhost, NULL, &hints, &res))
223      {
224        log_printf("IRC -> bind(): %s is an invalid address", IRCItem->vhost);
225        exit(EXIT_FAILURE);
226      }
227 <
218 <    bsaddr.sin_addr.s_addr = IRC_LOCAL.s_addr;
219 <    bsaddr.sin_family = AF_INET;
220 <    bsaddr.sin_port = htons(0);
221 <
222 <    if (bind(IRC_FD, (struct sockaddr *)&bsaddr, sizeof(bsaddr)))
227 >    else if (bind(IRC_FD, res->ai_addr, res->ai_addrlen))
228      {
229        log_printf("IRC -> bind(): error binding to %s: %s", IRCItem->vhost, strerror(errno));
230        exit(EXIT_FAILURE);
231      }
232 +
233 +    freeaddrinfo(res);
234    }
235   }
236  
# Line 308 | Line 315 | irc_connect(void)
315    /* Connect to IRC server as client. */
316    if (connect(IRC_FD, (struct sockaddr *)&IRC_SVR, sizeof(IRC_SVR)) == -1)
317    {
318 <    switch (errno)
319 <    {
313 <      case EISCONN:
314 <        /* Already connected */
315 <        return;
316 <      case ECONNREFUSED:
317 <        log_printf("IRC -> connect(): Connection refused by (%s)",
318 <                   IRCItem->server);
319 <        break;
320 <      case ETIMEDOUT:
321 <        log_printf("IRC -> connect(): Timed out connecting to (%s)",
322 <                   IRCItem->server);
323 <        break;
324 <      case ENETUNREACH:
325 <        log_printf("IRC -> connect(): Network unreachable");
326 <        break;
327 <      case EALREADY:
328 <        /* Previous attempt not complete */
329 <        return;
330 <      default:
331 <        log_printf("IRC -> connect(): Unknown error connecting to (%s)",
332 <                   IRCItem->server);
318 >    log_printf("IRC -> connect(): error connecting to %s: %s",
319 >               IRCItem->server, strerror(errno));
320  
321 <        if (OPT_DEBUG >= 1)
322 <          log_printf("%s", strerror(errno));
336 <    }
321 >    if (errno == EISCONN /* Already connected */ || errno == EALREADY /* Previous attempt not complete */)
322 >      return;
323  
324      /* Try to connect again */
325      irc_reconnect();
# Line 682 | Line 668 | m_perform(char *parv[], unsigned int par
668   {
669    node_t *node;
670  
671 <  log_printf("IRC -> Connected to %s:%d", IRCItem->server, IRCItem->port);
671 >  log_printf("IRC -> Connected to %s/%d", IRCItem->server, IRCItem->port);
672  
673    /* Identify to nickserv if needed */
674    if (!EmptyString(IRCItem->nickserv))

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)