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 5106 by michael, Wed Dec 24 12:47:21 2014 UTC vs.
Revision 5198 by michael, Mon Dec 29 16:53:16 2014 UTC

# Line 1 | Line 1
1 /* vim: set shiftwidth=3 softtabstop=3 expandtab: */
2
1   /*
2   * Copyright (C) 2002-2003  Erik Fears
3   *
# Line 101 | Line 99 | extern struct cnode *nc_head;
99   * again so global scope is given.
100   */
101  
102 < char                 IRC_RAW[MSGLENMAX];         /* Buffer to read data into              */
103 < char                 IRC_SENDBUFF[MSGLENMAX];    /* Send buffer                           */
104 < int                  IRC_RAW_LEN    = 0;         /* Position of IRC_RAW                   */
105 <
106 < int                  IRC_FD         = 0;        /* File descriptor for IRC client        */
107 <
108 < struct bopm_sockaddr IRC_SVR;                   /* Sock Address Struct for IRC server    */
109 < struct bopm_ircaddr  IRC_LOCAL;                 /* Sock Address Struct for Bind          */
110 <
111 < fd_set               IRC_READ_FDSET;             /* fd_set for IRC (read) data for select()*/
112 < struct timeval       IRC_TIMEOUT;                /* timeval struct for select() timeout   */
113 <
114 < time_t               IRC_LAST = 0;               /* Last full line of data from irc server*/
115 < time_t               IRC_LASTRECONNECT = 0;      /* Time of last reconnection */
116 <
117 < /* Table should be ordered with most occuring (or priority)
118 <   commands at the top of the list. */
119 <
120 < static struct CommandHash COMMAND_TABLE[] = {
121 <         {"NOTICE",               m_notice         },
122 <         {"PRIVMSG",              m_privmsg        },
123 <         {"PING",                 m_ping           },
124 <         {"INVITE",               m_invite         },
125 <         {"001",                  m_perform        },
126 <         {"302",                  m_userhost       },
127 <         {"471",                  m_cannot_join    },
128 <         {"473",                  m_cannot_join    },
129 <         {"474",                  m_cannot_join    },
130 <         {"475",                  m_cannot_join    },
131 <         {"KILL",                 m_kill           }
132 <      };
102 > static char          IRC_RAW[MSGLENMAX];         /* Buffer to read data into              */
103 > static unsigned int  IRC_RAW_LEN    = 0;         /* Position of IRC_RAW                   */
104 > static int           IRC_FD         = 0;         /* File descriptor for IRC client        */
105 >
106 > static struct bopm_sockaddr IRC_SVR;             /* Sock Address Struct for IRC server    */
107 > static struct bopm_ircaddr  IRC_LOCAL;           /* Sock Address Struct for Bind          */
108 >
109 > static fd_set        IRC_READ_FDSET;             /* fd_set for IRC (read) data for select()*/
110 > static struct timeval IRC_TIMEOUT;               /* timeval struct for select() timeout   */
111 >
112 > static time_t IRC_LAST = 0;                      /* Last full line of data from irc server*/
113 > static time_t IRC_LASTRECONNECT = 0;             /* Time of last reconnection */
114 >
115 > /*
116 > * Table should be ordered with most occuring (or priority)
117 > * commands at the top of the list.
118 > */
119 > static struct CommandHash COMMAND_TABLE[] =
120 > {
121 >  { "NOTICE",   m_notice      },
122 >  { "PRIVMSG",  m_privmsg     },
123 >  { "PING",     m_ping        },
124 >  { "INVITE",   m_invite      },
125 >  { "001",      m_perform     },
126 >  { "302",      m_userhost    },
127 >  { "471",      m_cannot_join },
128 >  { "473",      m_cannot_join },
129 >  { "474",      m_cannot_join },
130 >  { "475",      m_cannot_join },
131 >  { "KILL",     m_kill        },
132 >  { NULL,       NULL          }
133 > };
134  
135   /* irc_cycle
136   *
# Line 142 | Line 141 | static struct CommandHash COMMAND_TABLE[
141   *
142   * Return:
143   *    None
145 *
144   */
145 <
146 < void irc_cycle(void)
145 > void
146 > irc_cycle(void)
147   {
148 <   if (IRC_FD <= 0)
149 <   {
150 <      /* Initialise negative cache. */
151 <      if (OptionsItem->negcache > 0)
152 <         nc_init(&nc_head);
153 <
154 <      /* Resolve remote host. */
155 <      irc_init();
156 <
157 <      /* Connect to remote host. */
158 <      irc_connect();
159 <
162 <      return;      /* In case connect() immediately failed */
148 >  if (IRC_FD <= 0)
149 >  {
150 >    /* Initialise negative cache. */
151 >    if (OptionsItem->negcache > 0)
152 >      nc_init(&nc_head);
153 >
154 >    /* Resolve remote host. */
155 >    irc_init();
156 >
157 >    /* Connect to remote host. */
158 >    irc_connect();
159 >    return;  /* In case connect() immediately failed */
160    }
161  
162 <   IRC_TIMEOUT.tv_sec  = 0;
166 <   /* Block .025 seconds to avoid excessive CPU use on select(). */
167 <   IRC_TIMEOUT.tv_usec = 25000;
168 <
169 <   FD_ZERO(&IRC_READ_FDSET);
170 <   FD_SET(IRC_FD, &IRC_READ_FDSET);
162 >  IRC_TIMEOUT.tv_sec  = 0;
163  
164 <   switch (select((IRC_FD + 1), &IRC_READ_FDSET, 0, 0, &IRC_TIMEOUT))
165 <   {
174 <      case -1:
175 <         return;
176 <         break;
177 <      case 0:
178 <         break;
179 <      default:
180 <         /* Check if IRC data is available. */
181 <         if (FD_ISSET(IRC_FD, &IRC_READ_FDSET))
182 <            irc_read();
183 <         break;
184 <   }
185 < }
164 >  /* Block .025 seconds to avoid excessive CPU use on select(). */
165 >  IRC_TIMEOUT.tv_usec = 25000;
166  
167 +  FD_ZERO(&IRC_READ_FDSET);
168 +  FD_SET(IRC_FD, &IRC_READ_FDSET);
169  
170 +  switch (select((IRC_FD + 1), &IRC_READ_FDSET, 0, 0, &IRC_TIMEOUT))
171 +  {
172 +    case -1:
173 +      return;
174 +      break;
175 +    case 0:
176 +      break;
177 +    default:
178 +      /* Check if IRC data is available. */
179 +      if (FD_ISSET(IRC_FD, &IRC_READ_FDSET))
180 +        irc_read();
181  
182 +      break;
183 +  }
184 + }
185  
186   /* irc_init
187   *
# Line 196 | Line 192 | void irc_cycle(void)
192   *
193   * Return:
194   *    None
199 *
195   */
196 <
197 < static void irc_init(void)
196 > static void
197 > irc_init(void)
198   {
199 <   node_t *node;
200 <   struct ChannelConf *chan;
206 <   struct bopm_sockaddr bsaddr;
207 <   struct in_addr *irc_host;
208 <
209 <
210 <   if (IRC_FD)
211 <      close(IRC_FD);
212 <
213 <   memset(&IRC_SVR, 0, sizeof(IRC_SVR));
214 <   memset(&IRC_LOCAL, 0, sizeof(IRC_LOCAL));
215 <   memset(&bsaddr, 0, sizeof(struct bopm_sockaddr));
216 <
217 <   /* Resolve IRC host. */
218 <   if ((irc_host = firedns_resolveip4(IRCItem->server)) == NULL)
219 <   {
220 <      log_printf("IRC -> firedns_resolveip4(\"%s\"): %s", IRCItem->server,
221 <            firedns_strerror(fdns_errno));
222 <      exit(EXIT_FAILURE);
223 <   }
199 >  struct bopm_sockaddr bsaddr;
200 >  struct in_addr *irc_host;
201  
202 <   IRC_SVR.sa4.sin_family = AF_INET;
203 <   IRC_SVR.sa4.sin_port = htons(IRCItem->port);
204 <   IRC_SVR.sa4.sin_addr = *irc_host;
205 <
206 <   if (IRC_SVR.sa4.sin_addr.s_addr == INADDR_NONE)
207 <   {
208 <      log_printf("IRC -> Unknown error resolving remote host (%s)",
209 <          IRCItem->server);
210 <      exit(EXIT_FAILURE);
211 <   }
202 >  if (IRC_FD)
203 >    close(IRC_FD);
204 >
205 >  memset(&IRC_SVR, 0, sizeof(IRC_SVR));
206 >  memset(&IRC_LOCAL, 0, sizeof(IRC_LOCAL));
207 >  memset(&bsaddr, 0, sizeof(struct bopm_sockaddr));
208 >
209 >  /* Resolve IRC host. */
210 >  if ((irc_host = firedns_resolveip4(IRCItem->server)) == NULL)
211 >  {
212 >    log_printf("IRC -> firedns_resolveip4(\"%s\"): %s", IRCItem->server,
213 >               firedns_strerror(fdns_errno));
214 >    exit(EXIT_FAILURE);
215 >  }
216  
217 <   /* Request file desc for IRC client socket */
218 <   IRC_FD = socket(AF_INET, SOCK_STREAM, 0);
217 >  IRC_SVR.sa4.sin_family = AF_INET;
218 >  IRC_SVR.sa4.sin_port = htons(IRCItem->port);
219 >  IRC_SVR.sa4.sin_addr = *irc_host;
220 >
221 >  if (IRC_SVR.sa4.sin_addr.s_addr == INADDR_NONE)
222 >  {
223 >    log_printf("IRC -> Unknown error resolving remote host (%s)",
224 >               IRCItem->server);
225 >    exit(EXIT_FAILURE);
226 >  }
227  
228 <   if (IRC_FD == -1)
229 <   {
230 <      switch(errno)
231 <      {
232 <         case EINVAL:
233 <         case EPROTONOSUPPORT:
234 <            log_printf("IRC -> socket(): SOCK_STREAM is not "
235 <                "supported on this domain");
236 <            break;
237 <         case ENFILE:
238 <            log_printf("IRC -> socket(): Not enough free file "
239 <                "descriptors to allocate IRC socket");
240 <            break;
241 <         case EMFILE:
242 <            log_printf("IRC -> socket(): Process table overflow when "
243 <                "requesting file descriptor");
244 <            break;
245 <         case EACCES:
246 <            log_printf("IRC -> socket(): Permission denied to create "
247 <                "socket of type SOCK_STREAM");
248 <            break;
249 <         case ENOMEM:
250 <            log_printf("IRC -> socket(): Insufficient memory to "
251 <                "allocate socket");
252 <            break;
253 <         default:
254 <            log_printf("IRC -> socket(): Unknown error allocating "
255 <                "socket");
256 <            break;
257 <      }
228 >  /* Request file desc for IRC client socket */
229 >  IRC_FD = socket(AF_INET, SOCK_STREAM, 0);
230 >
231 >  if (IRC_FD == -1)
232 >  {
233 >    switch (errno)
234 >    {
235 >      case EINVAL:
236 >      case EPROTONOSUPPORT:
237 >        log_printf("IRC -> socket(): SOCK_STREAM is not supported on this domain");
238 >        break;
239 >      case ENFILE:
240 >        log_printf("IRC -> socket(): Not enough free file descriptors to allocate IRC socket");
241 >        break;
242 >      case EMFILE:
243 >        log_printf("IRC -> socket(): Process table overflow when requesting file descriptor");
244 >        break;
245 >      case EACCES:
246 >        log_printf("IRC -> socket(): Permission denied to create socket of type SOCK_STREAM");
247 >        break;
248 >      case ENOMEM:
249 >        log_printf("IRC -> socket(): Insufficient memory to allocate socket");
250 >        break;
251 >      default:
252 >        log_printf("IRC -> socket(): Unknown error allocating socket");
253 >        break;
254 >    }
255 >
256 >    exit(EXIT_FAILURE);
257 >  }
258 >
259 >  /* Bind */
260 >  if (!EmptyString(IRCItem->vhost))
261 >  {
262 >    int bindret = 0;
263 >
264 >    if (inet_pton(AF_INET, IRCItem->vhost, &(IRC_LOCAL.in4.s_addr)) <= 0)
265 >    {
266 >      log_printf("IRC -> bind(): %s is an invalid address", IRCItem->vhost);
267        exit(EXIT_FAILURE);
268 <   }
268 >    }
269  
270 <   /* Bind */
271 <   if (!EmptyString(IRCItem->vhost))
272 <   {
275 <      int bindret = 0;
276 <      if (!inet_pton(AF_INET, IRCItem->vhost, &(IRC_LOCAL.in4.s_addr)))
277 <      {
278 <         log_printf("IRC -> bind(): %s is an invalid address", IRCItem->vhost);
279 <         exit(EXIT_FAILURE);
280 <      }
281 <      bsaddr.sa4.sin_addr.s_addr = IRC_LOCAL.in4.s_addr;
282 <      bsaddr.sa4.sin_family = AF_INET;
283 <      bsaddr.sa4.sin_port = htons(0);
270 >    bsaddr.sa4.sin_addr.s_addr = IRC_LOCAL.in4.s_addr;
271 >    bsaddr.sa4.sin_family = AF_INET;
272 >    bsaddr.sa4.sin_port = htons(0);
273  
274 <      bindret = bind(IRC_FD, (struct sockaddr *) &(bsaddr.sa4), sizeof(bsaddr.sa4));
274 >    bindret = bind(IRC_FD, (struct sockaddr *) &(bsaddr.sa4), sizeof(bsaddr.sa4));
275  
276 <      if (bindret)
276 >    if (bindret)
277 >    {
278 >      switch (errno)
279        {
280 <         switch(errno)
281 <         {
282 <            case EACCES:
283 <               log_printf("IRC -> bind(): No access to bind to %s",
284 <                   IRCItem->vhost);
285 <               break;
295 <            default:
296 <               log_printf("IRC -> bind(): Error binding to %s (%d)",
297 <                   IRCItem->vhost, errno);
298 <               break;
299 <         }
300 <         exit(EXIT_FAILURE);
280 >        case EACCES:
281 >          log_printf("IRC -> bind(): No access to bind to %s", IRCItem->vhost);
282 >          break;
283 >        default:
284 >          log_printf("IRC -> bind(): Error binding to %s (%d)", IRCItem->vhost, errno);
285 >          break;
286        }
287  
288 <   }
288 >      exit(EXIT_FAILURE);
289 >    }
290 >  }
291   }
292  
306
293   /* irc_send
294   *
295   *    Send data to remote IRC host.
# Line 314 | Line 300 | static void irc_init(void)
300   *
301   * Return: NONE
302   */
303 <
304 <
319 < void irc_send(const char *data, ...)
303 > void
304 > irc_send(const char *data, ...)
305   {
306 <   va_list arglist;
307 <   char    data2[MSGLENMAX];
308 <   char    tosend[MSGLENMAX];
309 <
310 <   va_start(arglist, data);
311 <   vsnprintf(data2, MSGLENMAX, data, arglist);
312 <   va_end(arglist);
313 <
314 <   if (OPT_DEBUG >= 2)
315 <      log_printf("IRC SEND -> %s", data2);
316 <
317 <   snprintf(tosend, MSGLENMAX, "%s\n", data2);
318 <
319 <   if (send(IRC_FD, tosend, strlen(tosend), 0) == -1)
320 <   {
321 <      /* Return of -1 indicates error sending data; we reconnect. */
322 <      log_printf("IRC -> Error sending data to server\n");
323 <      irc_reconnect();
324 <   }
306 >  va_list arglist;
307 >  char buf[MSGLENMAX];
308 >  int len = 0;
309 >
310 >  va_start(arglist, data);
311 >  len = vsnprintf(buf, sizeof(buf), data, arglist);
312 >  va_end(arglist);
313 >
314 >  if (OPT_DEBUG >= 2)
315 >    log_printf("IRC SEND -> %s", buf);
316 >
317 >  if (len > 510)
318 >    len = 510;
319 >
320 >  buf[len++] = '\r';
321 >  buf[len++] = '\n';
322 >
323 >  if (send(IRC_FD, buf, len, 0) == -1)
324 >  {
325 >    /* Return of -1 indicates error sending data; we reconnect. */
326 >    log_printf("IRC -> Error sending data to server\n");
327 >    irc_reconnect();
328 >  }
329   }
330  
331   /* irc_send
# Line 349 | Line 338 | void irc_send(const char *data, ...)
338   *
339   * Return: NONE
340   */
341 <
342 < void irc_send_channels(const char *data, ...)
341 > void
342 > irc_send_channels(const char *data, ...)
343   {
344 <   const node_t *node;
345 <   va_list arglist;
346 <   char    buf[MSGLENMAX];
344 >  const node_t *node;
345 >  va_list arglist;
346 >  char buf[MSGLENMAX];
347  
348 <   va_start(arglist, data);
349 <   vsnprintf(buf, sizeof(buf), data, arglist);
350 <   va_end(arglist);
348 >  va_start(arglist, data);
349 >  vsnprintf(buf, sizeof(buf), data, arglist);
350 >  va_end(arglist);
351  
352  
353 <   LIST_FOREACH(node, IRCItem->channels->head)
354 <   {
355 <     const struct ChannelConf *chan = node->data;
353 >  LIST_FOREACH(node, IRCItem->channels->head)
354 >  {
355 >    const struct ChannelConf *chan = node->data;
356  
357 <     irc_send("PRIVMSG %s :%s", chan->name, buf);
358 <   }
357 >    irc_send("PRIVMSG %s :%s", chan->name, buf);
358 >  }
359   }
360  
372
373
374
361   /* irc_connect
362   *
363   *    Connect to IRC server.
# Line 379 | Line 365 | void irc_send_channels(const char *data,
365   *
366   * Parameters: NONE
367   * Return: NONE
382 *
368   */
369 <
370 < static void irc_connect(void)
369 > static void
370 > irc_connect(void)
371   {
372 <   /* Connect to IRC server as client. */
373 <   if (connect(IRC_FD, (struct sockaddr *) &IRC_SVR,
374 <               sizeof(IRC_SVR)) == -1)
375 <   {
376 <      switch(errno)
377 <      {
378 <         case EISCONN:
379 <            /* Already connected */
380 <            return;
381 <         case ECONNREFUSED:
382 <            log_printf("IRC -> connect(): Connection refused by (%s)",
383 <                IRCItem->server);
384 <            break;
385 <         case ETIMEDOUT:
386 <            log_printf("IRC -> connect(): Timed out connecting to (%s)",
387 <                IRCItem->server);
388 <            break;
389 <         case ENETUNREACH:
390 <            log_printf("IRC -> connect(): Network unreachable");
391 <            break;
392 <         case EALREADY:
393 <            /* Previous attempt not complete */
394 <            return;
395 <         default:
396 <            log_printf("IRC -> connect(): Unknown error connecting to (%s)",
412 <                IRCItem->server);
413 <
414 <            if (OPT_DEBUG >= 1)
415 <               log_printf("%s", strerror(errno));
416 <      }
417 <      /* Try to connect again */
418 <      irc_reconnect();
419 <      return;
420 <   }
372 >  /* Connect to IRC server as client. */
373 >  if (connect(IRC_FD, (struct sockaddr *)&IRC_SVR, sizeof(IRC_SVR)) == -1)
374 >  {
375 >    switch (errno)
376 >    {
377 >      case EISCONN:
378 >        /* Already connected */
379 >        return;
380 >      case ECONNREFUSED:
381 >        log_printf("IRC -> connect(): Connection refused by (%s)",
382 >                   IRCItem->server);
383 >        break;
384 >      case ETIMEDOUT:
385 >        log_printf("IRC -> connect(): Timed out connecting to (%s)",
386 >                   IRCItem->server);
387 >        break;
388 >      case ENETUNREACH:
389 >        log_printf("IRC -> connect(): Network unreachable");
390 >        break;
391 >      case EALREADY:
392 >        /* Previous attempt not complete */
393 >        return;
394 >      default:
395 >        log_printf("IRC -> connect(): Unknown error connecting to (%s)",
396 >                   IRCItem->server);
397  
398 <   irc_send("NICK %s", IRCItem->nick);
398 >        if (OPT_DEBUG >= 1)
399 >          log_printf("%s", strerror(errno));
400 >    }
401 >
402 >    /* Try to connect again */
403 >    irc_reconnect();
404 >    return;
405 >  }
406  
407 <   if (!EmptyString(IRCItem->password))
425 <      irc_send("PASS %s", IRCItem->password);
407 >  irc_send("NICK %s", IRCItem->nick);
408  
409 <   irc_send("USER %s %s %s :%s",
410 <            IRCItem->username, IRCItem->username, IRCItem->username,
429 <            IRCItem->realname);
409 >  if (!EmptyString(IRCItem->password))
410 >    irc_send("PASS %s", IRCItem->password);
411  
412 <   time(&IRC_LAST);
412 >  irc_send("USER %s %s %s :%s",
413 >           IRCItem->username,
414 >           IRCItem->username,
415 >           IRCItem->username,
416 >           IRCItem->realname);
417 >  time(&IRC_LAST);
418   }
419  
434
420   /* irc_reconnect
421   *
422   *    Close connection to IRC server.
# Line 440 | Line 425 | static void irc_connect(void)
425   *
426   * Return: NONE
427   */
428 <
429 < static void irc_reconnect(void)
428 > static void
429 > irc_reconnect(void)
430   {
431 +  time_t present;
432  
433 <   time_t present;
448 <  
449 <   time(&present);
450 <  
451 <   /* Only try to reconnect every RECONNECT_INTERVAL seconds */
452 <   if((present - IRC_LASTRECONNECT) < RECONNECTINTERVAL)
453 <   {
454 <      /* Sleep to avoid excessive CPU */
455 <      sleep(1);
456 <      return;
457 <   }
458 <
459 <   time(&IRC_LASTRECONNECT);
433 >  time(&present);
434  
435 <   if(IRC_FD > 0)
436 <      close(IRC_FD);
435 >  /* Only try to reconnect every RECONNECT_INTERVAL seconds */
436 >  if ((present - IRC_LASTRECONNECT) < RECONNECTINTERVAL)
437 >  {
438 >    /* Sleep to avoid excessive CPU */
439 >    sleep(1);
440 >    return;
441 >  }
442  
443 <   /* Set IRC_FD 0 for reconnection on next irc_cycle(). */
465 <   IRC_FD = 0;
443 >  time(&IRC_LASTRECONNECT);
444  
445 <   log_printf("IRC -> Connection to (%s) failed, reconnecting.", IRCItem->server);
446 < }
445 >  if (IRC_FD > 0)
446 >    close(IRC_FD);
447  
448 +  /* Set IRC_FD 0 for reconnection on next irc_cycle(). */
449 +  IRC_FD = 0;
450  
451 +  log_printf("IRC -> Connection to (%s) failed, reconnecting.", IRCItem->server);
452 + }
453  
454   /* irc_read
455   *
456   *    irc_read is called my irc_cycle when new data is ready to be
457 < *    read from the irc server.
457 > *    read from the irc server.
458   *
459   * Parameters: NONE
460   * Return: NONE
479 *
461   */
462 <
463 < static void irc_read(void)
462 > static void
463 > irc_read(void)
464   {
465 <   int len;
466 <   char c;
465 >  int len;
466 >  char c;
467  
468 <   while ((len = read(IRC_FD, &c, 1)) > 0)
469 <   {
470 <      if (c == '\r')
471 <         continue;
468 >  while ((len = read(IRC_FD, &c, 1)) > 0)
469 >  {
470 >    if (c == '\r')
471 >      continue;
472 >
473 >    if (c == '\n')
474 >    {
475 >      /* Null string. */
476 >      IRC_RAW[IRC_RAW_LEN] = '\0';
477  
478 <      if (c == '\n')
479 <      {
494 <         /* Null string. */
495 <         IRC_RAW[IRC_RAW_LEN] = '\0';
496 <         /* Parse line. */
497 <         irc_parse();
498 <         /* Reset counter. */
499 <         IRC_RAW_LEN = 0;
500 <         break;
501 <      }
478 >      /* Parse line. */
479 >      irc_parse();
480  
481 <      if (c != '\r' && c != '\n' && c != '\0')
504 <         IRC_RAW[IRC_RAW_LEN++] = c;
505 <   }
506 <
507 <   if((len <= 0) && (errno != EAGAIN))
508 <   {
509 <      if(OPT_DEBUG >= 2)
510 <         log_printf("irc_read -> errno=%d len=%d", errno, len);
511 <      irc_reconnect();
481 >      /* Reset counter. */
482        IRC_RAW_LEN = 0;
483 <      return;
484 <   }
485 < }
483 >      break;
484 >    }
485 >
486 >    if (c != '\0')
487 >      IRC_RAW[IRC_RAW_LEN++] = c;
488 >  }
489  
490 +  if ((len <= 0) && (errno != EAGAIN))
491 +  {
492 +    if (OPT_DEBUG >= 2)
493 +      log_printf("irc_read -> errno=%d len=%d", errno, len);
494 +
495 +    irc_reconnect();
496 +    IRC_RAW_LEN = 0;
497 +    return;
498 +  }
499 + }
500  
501   /* irc_parse
502   *
# Line 522 | Line 505 | static void irc_read(void)
505   *
506   * Parameters: NONE
507   * Return: NONE
525 *
508   */
509 <
510 <
529 < static void irc_parse(void)
509 > static void
510 > irc_parse(void)
511   {
512 <   struct UserInfo *source_p;
513 <   char *pos;
533 <   unsigned int i;
534 <
535 <   /*
536 <      parv stores the parsed token, parc is the count of the parsed
537 <      tokens
538 <    
539 <      parv[0] is ALWAYS the source, and is the server name of the source
540 <      did not exist
541 <   */
542 <
543 <   static char            *parv[17];
544 <   static unsigned int     parc;
545 <   static char             msg[MSGLENMAX];    /* Temporarily stores IRC msg to pass to handlers */
546 <
547 <   parc = 1;
548 <
549 <   if(IRC_RAW_LEN <= 0)
550 <      return;
551 <
552 <   if (OPT_DEBUG >= 2)
553 <      log_printf("IRC READ -> %s", IRC_RAW);
512 >  struct UserInfo *source_p;
513 >  char *pos;
514  
515 <   time(&IRC_LAST);
516 <
517 <   /* Store a copy of IRC_RAW for the handlers (for functions that need PROOF) */
518 <   strlcpy(msg, IRC_RAW, sizeof(msg));
519 <
520 <   /* parv[0] is always the source */
521 <   if(IRC_RAW[0] == ':')
522 <      parv[0] = IRC_RAW + 1;
523 <   else
524 <   {
525 <      parv[0] = IRCItem->server;
526 <      parv[parc++] = IRC_RAW;
527 <   }
528 <
529 <   pos = IRC_RAW;
530 <
531 <   while((pos = strchr(pos, ' ')) && parc <= 17)
532 <   {
533 <
534 <      /* Avoid excessive spaces and end of IRC_RAW */
535 <      if(*(pos + 1) == ' ' && *(pos + 1) == '\0')
536 <      {
537 <         pos++;
538 <         continue;
539 <      }
515 >  /*
516 >   * parv stores the parsed token, parc is the count of the parsed
517 >   * tokens
518 >   *
519 >   * parv[0] is ALWAYS the source, and is the server name of the source
520 >   * did not exist
521 >   */
522 >  char            *parv[17];
523 >  unsigned int     parc = 1;
524 >  char             msg[MSGLENMAX];    /* Temporarily stores IRC msg to pass to handlers */
525 >
526 >  if (IRC_RAW_LEN == 0)
527 >    return;
528 >
529 >  if (OPT_DEBUG >= 2)
530 >    log_printf("IRC READ -> %s", IRC_RAW);
531 >
532 >  time(&IRC_LAST);
533 >
534 >  /* Store a copy of IRC_RAW for the handlers (for functions that need PROOF) */
535 >  strlcpy(msg, IRC_RAW, sizeof(msg));
536 >
537 >  /* parv[0] is always the source */
538 >  if (IRC_RAW[0] == ':')
539 >    parv[0] = IRC_RAW + 1;
540 >  else
541 >  {
542 >    parv[0] = IRCItem->server;
543 >    parv[parc++] = IRC_RAW;
544 >  }
545  
546 <      /* Anything after a : is considered the final string of the
582 <            message */
583 <      if(*(pos + 1) == ':')
584 <      {
585 <         parv[parc++] = pos + 2;
586 <         *pos = '\0';
587 <         break;
588 <      }
546 >  pos = IRC_RAW;
547  
548 <      /* Set the next parv at this position and replace the space with a
549 <         \0 for the previous parv */
550 <      parv[parc++] = pos + 1;
551 <      *pos = '\0';
548 >  while ((pos = strchr(pos, ' ')) && parc <= 17)
549 >  {
550 >    /* Avoid excessive spaces and end of IRC_RAW */
551 >    if (*(pos + 1) == ' ' && *(pos + 1) == '\0')
552 >    {
553        pos++;
554 <   }
554 >      continue;
555 >    }
556  
557 <   /* Generate a UserInfo struct from the source */
557 >    /* Anything after a : is considered the final string of the message */
558 >    if (*(pos + 1) == ':')
559 >    {
560 >      parv[parc++] = pos + 2;
561 >      *pos = '\0';
562 >      break;
563 >    }
564  
565 <   source_p = userinfo_create(parv[0]);
565 >    /*
566 >     * Set the next parv at this position and replace the space with a
567 >     * \0 for the previous parv
568 >     */
569 >    parv[parc++] = pos + 1;
570 >    *pos = '\0';
571 >    pos++;
572 >  }
573  
574 <   /* Determine which command this is from the command table
575 <      and let the handler for that command take control */
574 >  /* Generate a UserInfo struct from the source */
575 >  source_p = userinfo_create(parv[0]);
576  
577 <   for(i = 0; i < (sizeof(COMMAND_TABLE) / sizeof(struct CommandHash)); i++)
578 <      if(strcasecmp(COMMAND_TABLE[i].command, parv[1]) == 0)
579 <      {
580 <         (*COMMAND_TABLE[i].handler)(parv, parc, msg, source_p);
581 <         break;
582 <      }
577 >  /*
578 >   * Determine which command this is from the command table
579 >   * and let the handler for that command take control
580 >   */
581 >  for (const struct CommandHash *cmd = COMMAND_TABLE; cmd->command; ++cmd)
582 >  {
583 >    if (strcasecmp(cmd->command, parv[1]) == 0)
584 >    {
585 >      cmd->handler(parv, parc, msg, source_p);
586 >      break;
587 >    }
588 >  }
589  
590 <   userinfo_free(source_p);
590 >  userinfo_free(source_p);
591   }
592  
614
615
616
593   /* irc_timer
594   *
595   *    Functions to be performed every ~seconds.
596   *
597   * Parameters: NONE
598   * Return: NONE
623 *
599   */
600 <
601 < void irc_timer(void)
600 > void
601 > irc_timer(void)
602   {
603 <   time_t present, delta;
603 >  time_t present, delta;
604  
605 <   time(&present);
605 >  time(&present);
606  
607 <   delta = present - IRC_LAST;
607 >  delta = present - IRC_LAST;
608  
609 <   /* No data in NODATA_TIMEOUT minutes (set in options.h). */
610 <   if (delta >= NODATA_TIMEOUT)
611 <   {
612 <      log_printf("IRC -> Timeout awaiting data from server.");
613 <      irc_reconnect();
639 <      /* Make sure we dont do this again for a while */
640 <      time(&IRC_LAST);
641 <   }
642 <   else if (delta >= NODATA_TIMEOUT / 2)
643 <   {
644 <      /*
645 <       * Generate some data so high ping times or bugs in certain
646 <       * ircds (*cough* unreal *cough*) don't cause uneeded
647 <       * reconnections
648 <       */
649 <      irc_send("PING :HOPM");
650 <   }
609 >  /* No data in IRCItem->readtimeout seconds */
610 >  if (delta >= IRCItem->readtimeout)
611 >  {
612 >    log_printf("IRC -> Timeout awaiting data from server.");
613 >    irc_reconnect();
614  
615 +    /* Make sure we dont do this again for a while */
616 +    time(&IRC_LAST);
617 +  }
618 +  else if (delta >= IRCItem->readtimeout / 2)
619 +  {
620 +    /*
621 +     * Generate some data so high ping times or bugs in certain
622 +     * ircds (*cough* unreal *cough*) don't cause uneeded
623 +     * reconnections
624 +     */
625 +    irc_send("PING :HOPM");
626 +  }
627   }
628  
654
655
656
629   /* get_channel
630   *
631   *    Check if a channel is defined in our conf. If so return
# Line 664 | Line 636 | void irc_timer(void)
636   *
637   * Return: Pointer to ChannelConf containing the channel
638   */
639 <
640 < static struct ChannelConf *get_channel(const char *channel)
639 > static struct ChannelConf *
640 > get_channel(const char *channel)
641   {
642 <   node_t *node;
671 <   struct ChannelConf *item;
642 >  node_t *node;
643  
644 <   LIST_FOREACH(node, IRCItem->channels->head)
645 <   {
646 <      item = node->data;
644 >  LIST_FOREACH(node, IRCItem->channels->head)
645 >  {
646 >    struct ChannelConf *item = node->data;
647  
648 <      if(strcasecmp(item->name, channel) == 0)
649 <         return item;
650 <   }
648 >    if (strcasecmp(item->name, channel) == 0)
649 >      return item;
650 >  }
651  
652 <   return NULL;
652 >  return NULL;
653   }
654  
684
655   /* userinfo_create
656   *
657   *    Parse a nick!user@host into a UserInfo struct
# Line 692 | Line 662 | static struct ChannelConf *get_channel(c
662   *
663   * Return:
664   *    pointer to new UserInfo struct, or NULL if parsing failed
695 *
665   */
666 <
667 < static struct UserInfo *userinfo_create(char *source)
666 > static struct UserInfo *
667 > userinfo_create(char *source)
668   {
669 <   struct UserInfo *ret;
670 <
671 <   char *nick;
672 <   char *username;
673 <   char *hostname;
674 <   char *tmp;
675 <
676 <   int i, len;
677 <
678 <   nick = username = hostname = NULL;
679 <   tmp = xstrdup(source);
680 <   len = strlen(tmp);
681 <
682 <   nick = tmp;
683 <
684 <   for(i = 0; i < len; i++)
685 <   {
686 <      if(tmp[i] == '!')
687 <      {
688 <         tmp[i] = '\0';
689 <         username = tmp + i + 1;
690 <      }
691 <      if(tmp[i] == '@')
692 <      {
693 <         tmp[i] = '\0';
694 <         hostname = tmp + i + 1;
726 <      }
727 <   }
728 <
729 <   if(nick == NULL || username == NULL || hostname == NULL)
730 <   {
731 <      MyFree(tmp);
732 <      return NULL;
733 <   }
669 >  struct UserInfo *ret;
670 >  char *nick;
671 >  char *username;
672 >  char *hostname;
673 >  char *tmp;
674 >  int i, len;
675 >
676 >  nick = username = hostname = NULL;
677 >  tmp = xstrdup(source);
678 >  len = strlen(tmp);
679 >  nick = tmp;
680 >
681 >  for (i = 0; i < len; ++i)
682 >  {
683 >    if (tmp[i] == '!')
684 >    {
685 >      tmp[i] = '\0';
686 >      username = tmp + i + 1;
687 >    }
688 >
689 >    if (tmp[i] == '@')
690 >    {
691 >      tmp[i] = '\0';
692 >      hostname = tmp + i + 1;
693 >    }
694 >  }
695  
696 <   ret = MyMalloc(sizeof *ret);
696 >  if (nick == NULL || username == NULL || hostname == NULL)
697 >  {
698 >    MyFree(tmp);
699 >    return NULL;
700 >  }
701  
702 <   ret->irc_nick     = xstrdup(nick);
703 <   ret->irc_username = xstrdup(username);
704 <   ret->irc_hostname = xstrdup(hostname);
702 >  ret = MyMalloc(sizeof *ret);
703 >  ret->irc_nick     = xstrdup(nick);
704 >  ret->irc_username = xstrdup(username);
705 >  ret->irc_hostname = xstrdup(hostname);
706  
707 <   MyFree(tmp);
707 >  MyFree(tmp);
708  
709 <   return ret;
709 >  return ret;
710   };
711  
746
747
712   /* userinfo_free
713   *
714   *    Free a UserInfo struct created with userinfo_create.
715   *
716   * Parameters:
717   *    source: struct to free
754 *
755 * Return: None
718   *
719 + * Return: None
720   */
721 <
722 < static void userinfo_free(struct UserInfo *source_p)
721 > static void
722 > userinfo_free(struct UserInfo *source_p)
723   {
724 <   if(source_p == NULL)
725 <      return;
724 >  if (source_p == NULL)
725 >    return;
726  
727 <   MyFree(source_p->irc_nick);
728 <   MyFree(source_p->irc_username);
729 <   MyFree(source_p->irc_hostname);
730 <   MyFree(source_p);
727 >  MyFree(source_p->irc_nick);
728 >  MyFree(source_p->irc_username);
729 >  MyFree(source_p->irc_hostname);
730 >  MyFree(source_p);
731   }
732  
770
771
733   /* m_perform
734   *
735   *    actions to perform on IRC connection
# Line 781 | Line 742 | static void userinfo_free(struct UserInf
742   * source_p: UserInfo struct of the source user, or NULL if
743   * the source (parv[0]) is a server.
744   */
745 <
746 < static void m_perform(char **parv, unsigned int parc, char *msg, struct UserInfo *notused)
745 > static void
746 > m_perform(char **parv, unsigned int parc, char *msg, struct UserInfo *notused)
747   {
748 <   node_t *node;
788 <   struct ChannelConf *channel;
748 >  node_t *node;
749  
750 <   log_printf("IRC -> Connected to %s:%d", IRCItem->server, IRCItem->port);
750 >  log_printf("IRC -> Connected to %s:%d", IRCItem->server, IRCItem->port);
751  
752 <   /* Identify to nickserv if needed */
753 <   if (!EmptyString(IRCItem->nickserv))
754 <      irc_send("%s", IRCItem->nickserv);
752 >  /* Identify to nickserv if needed */
753 >  if (!EmptyString(IRCItem->nickserv))
754 >    irc_send("%s", IRCItem->nickserv);
755  
756 <   /* Oper */
757 <   irc_send("OPER %s", IRCItem->oper);
756 >  /* Oper */
757 >  irc_send("OPER %s", IRCItem->oper);
758  
759 <   /* Set modes */
760 <   irc_send("MODE %s %s", IRCItem->nick, IRCItem->mode);
759 >  /* Set modes */
760 >  irc_send("MODE %s %s", IRCItem->nick, IRCItem->mode);
761  
762 <   /* Set Away */
762 >  /* Set Away */
763    if (!EmptyString(IRCItem->away))
764      irc_send("AWAY :%s", IRCItem->away);
765  
766 <   /* Perform */
767 <   LIST_FOREACH(node, IRCItem->performs->head)
768 <      irc_send("%s", node->data);
769 <
770 <   /* Join all listed channels. */
771 <   LIST_FOREACH(node, IRCItem->channels->head)
772 <   {
773 <      channel = node->data;
774 <
775 <      if (EmptyString(channel->name))
776 <         continue;
777 <
778 <      if (!EmptyString(channel->key))
779 <         irc_send("JOIN %s %s", channel->name, channel->key);
780 <      else
781 <         irc_send("JOIN %s", channel->name);
782 <   }
766 >  /* Perform */
767 >  LIST_FOREACH(node, IRCItem->performs->head)
768 >    irc_send("%s", node->data);
769 >
770 >  /* Join all listed channels. */
771 >  LIST_FOREACH(node, IRCItem->channels->head)
772 >  {
773 >    struct ChannelConf *channel = node->data;
774 >
775 >    if (EmptyString(channel->name))
776 >      continue;
777 >
778 >    if (!EmptyString(channel->key))
779 >      irc_send("JOIN %s %s", channel->name, channel->key);
780 >    else
781 >      irc_send("JOIN %s", channel->name);
782 >  }
783   }
784  
825
785   /* m_ping
786   *
787   * parv[0]  = source
# Line 832 | Line 791 | static void m_perform(char **parv, unsig
791   * source_p: UserInfo struct of the source user, or NULL if
792   * the source (parv[0]) is a server.
793   */
794 < static void m_ping(char **parv, unsigned int parc, char *msg, struct UserInfo *source_p)
794 > static void
795 > m_ping(char **parv, unsigned int parc, char *msg, struct UserInfo *source_p)
796   {
797 <   if(parc < 3)
798 <      return;
797 >  if (parc < 3)
798 >    return;
799  
800 <   if(OPT_DEBUG >= 2)
801 <      log_printf("IRC -> PING? PONG!");
800 >  if (OPT_DEBUG >= 2)
801 >    log_printf("IRC -> PING? PONG!");
802  
803 <   irc_send("PONG %s", parv[2]);
803 >  irc_send("PONG %s", parv[2]);
804   }
805  
846
847
806   /* m_invite
807   *
808   * parv[0]  = source
# Line 854 | Line 812 | static void m_ping(char **parv, unsigned
812   *
813   * source_p: UserInfo struct of the source user, or NULL if
814   * the source (parv[0]) is a server.
857 *
815   */
816 <
817 < static void m_invite(char **parv, unsigned int parc, char *msg, struct UserInfo *source_p)
816 > static void
817 > m_invite(char **parv, unsigned int parc, char *msg, struct UserInfo *source_p)
818   {
819 <   struct ChannelConf *channel;
863 <  
864 <   if(parc < 4)
865 <      return;
866 <
867 <   log_printf("IRC -> Invited to %s by %s", parv[3], parv[0]);
819 >  struct ChannelConf *channel;
820  
821 <   if((channel = get_channel(parv[3])) == NULL)
822 <      return;
871 <
872 <   irc_send("JOIN %s %s", channel->name, channel->key);
873 < }
821 >  if (parc < 4)
822 >    return;
823  
824 +  log_printf("IRC -> Invited to %s by %s", parv[3], parv[0]);
825  
826 +  if ((channel = get_channel(parv[3])) == NULL)
827 +    return;
828  
829 +  irc_send("JOIN %s %s", channel->name, channel->key);
830 + }
831  
832   /* m_privmsg
833   *
# Line 884 | Line 838 | static void m_invite(char **parv, unsign
838   *
839   * source_p: UserInfo struct of the source user, or NULL if
840   * the source (parv[0]) is a server.
887 *
841   */
842 <
843 < static void m_privmsg(char **parv, unsigned int parc, char *msg, struct UserInfo *source_p)
842 > static void
843 > m_privmsg(char **parv, unsigned int parc, char *msg, struct UserInfo *source_p)
844   {
845 <   struct ChannelConf *channel;
846 <   size_t nick_len;
894 <
895 <   if(source_p == NULL)
896 <      return;
897 <
898 <   if(parc < 4)
899 <      return;
845 >  struct ChannelConf *channel;
846 >  size_t nick_len;
847  
848 <   /* CTCP */
849 <   if(parv[3][0] == '\001')
903 <      m_ctcp(parv, parc, msg, source_p);
848 >  if (source_p == NULL)
849 >    return;
850  
851 <   /* Only interested in privmsg to channels */
852 <   if(parv[2][0] != '#' && parv[2][0] != '&')
853 <      return;
854 <
855 <   /* Get a target */
856 <   if((channel = get_channel(parv[2])) == NULL)
857 <      return;
858 <
859 <   /* Find a suitable length to compare with */
860 <   nick_len = strcspn(parv[3], " :,");
861 <   if(nick_len < 3 && strlen(IRCItem->nick) >= 3)
862 <      nick_len = 3;
863 <  
864 <   /* message is a command */
865 <   if(strncasecmp(parv[3], IRCItem->nick, nick_len) == 0  ||
866 <         strncasecmp(parv[3], "!all", 4) == 0)
867 <   {
868 <      /* XXX command_parse will alter parv[3]. */
869 <      command_parse(parv[3], msg, channel, source_p);
870 <   }
851 >  if (parc < 4)
852 >    return;
853 >
854 >  /* CTCP */
855 >  if (parv[3][0] == '\001')
856 >    m_ctcp(parv, parc, msg, source_p);
857 >
858 >  /* Only interested in privmsg to channels */
859 >  if (parv[2][0] != '#' && parv[2][0] != '&')
860 >    return;
861 >
862 >  /* Get a target */
863 >  if ((channel = get_channel(parv[2])) == NULL)
864 >    return;
865 >
866 >  /* Find a suitable length to compare with */
867 >  nick_len = strcspn(parv[3], " :,");
868 >
869 >  if (nick_len < 3 && strlen(IRCItem->nick) >= 3)
870 >    nick_len = 3;
871 >
872 >  /* message is a command */
873 >  if (strncasecmp(parv[3], IRCItem->nick, nick_len) == 0  ||
874 >      strncasecmp(parv[3], "!all", 4) == 0)
875 >  {
876 >    /* XXX command_parse will alter parv[3]. */
877 >    command_parse(parv[3], msg, channel, source_p);
878 >  }
879   }
880  
927
928
929
930
881   /* m_ctcp
882   * parv[0]  = source
883   * parv[1]  = PRIVMSG
# Line 938 | Line 888 | static void m_privmsg(char **parv, unsig
888   * the source (parv[0]) is a server.
889   *
890   */
891 <
892 < static void m_ctcp(char **parv, unsigned int parc, char *msg, struct UserInfo *source_p)
891 > static void
892 > m_ctcp(char **parv, unsigned int parc, char *msg, struct UserInfo *source_p)
893   {
894    if (strncasecmp(parv[3], "\001VERSION\001", 9) == 0)
895      irc_send("NOTICE %s :\001VERSION Hybrid Open Proxy Monitor %s\001",
896               source_p->irc_nick, VERSION);
897   }
898  
949
950
951
952
899   /* m_notice
900   *
901   * parv[0]  = source
# Line 962 | Line 908 | static void m_ctcp(char **parv, unsigned
908   * the source (parv[0]) is a server.
909   *
910   */
911 <
912 < static void m_notice(char **parv, unsigned int parc, char *msg, struct UserInfo *source_p)
911 > static void
912 > m_notice(char **parv, unsigned int parc, char *msg, struct UserInfo *source_p)
913   {
914 +  static regex_t *preg = NULL;
915 +  regmatch_t pmatch[5];
916  
917 +  static char errmsg[256];
918 +  int errnum, i;
919 +  char *user[4];
920 +
921 +  if (parc < 4)
922 +    return;
923 +
924 +  /* Not interested in notices from users */
925 +  if (source_p)
926 +    return;
927 +
928 +  /* Compile the regular expression if it has not been already */
929 +  if (preg == NULL)
930 +  {
931 +    preg = MyMalloc(sizeof *preg);
932 +
933 +    if ((errnum = regcomp(preg, IRCItem->connregex, REG_ICASE | REG_EXTENDED)))
934 +    {
935 +      regerror(errnum, preg, errmsg, 256);
936 +      log_printf("IRC REGEX -> Error when compiling regular expression");
937 +      log_printf("IRC REGEX -> %s", errmsg);
938  
939 <   static regex_t *preg = NULL;
940 <   regmatch_t pmatch[5];
972 <
973 <   static char errmsg[256];
974 <   int errnum, i;
975 <
976 <   char *user[4];
977 <
978 <   if(parc < 4)
939 >      MyFree(preg);
940 >      preg = NULL;
941        return;
942 +    }
943 +  }
944  
945 <   /* Not interested in notices from users */
946 <   if(source_p != NULL)
947 <      return;
948 <
949 <   /* Compile the regular expression if it has not been already */
950 <   if(preg == NULL)
951 <   {
952 <      preg = MyMalloc(sizeof *preg);
953 <
954 <      if((errnum = regcomp(preg, IRCItem->connregex, REG_ICASE | REG_EXTENDED)) != 0)
955 <      {
956 <
993 <         regerror(errnum, preg, errmsg, 256);
994 <         log_printf("IRC REGEX -> Error when compiling regular expression");
995 <         log_printf("IRC REGEX -> %s", errmsg);
996 <
997 <         MyFree(preg);
998 <         preg = NULL;
999 <         return;
1000 <      }
1001 <   }
1002 <
1003 <   /* Match the expression against the possible connection notice */
1004 <   if(regexec(preg, parv[3], 5, pmatch, 0) != 0)
1005 <      return;
1006 <
1007 <   if(OPT_DEBUG > 0)
1008 <      log_printf("IRC REGEX -> Regular expression caught connection notice. Parsing.");
1009 <
1010 <   if(pmatch[4].rm_so == -1)
1011 <   {
1012 <      log_printf("IRC REGEX -> pmatch[4].rm_so is -1 while parsing??? Aborting.");
1013 <      return;
1014 <   }
945 >  /* Match the expression against the possible connection notice */
946 >  if (regexec(preg, parv[3], 5, pmatch, 0))
947 >    return;
948 >
949 >  if (OPT_DEBUG > 0)
950 >    log_printf("IRC REGEX -> Regular expression caught connection notice. Parsing.");
951 >
952 >  if (pmatch[4].rm_so == -1)
953 >  {
954 >    log_printf("IRC REGEX -> pmatch[4].rm_so is -1 while parsing??? Aborting.");
955 >    return;
956 >  }
957  
958 <   /*
959 <       Offsets for data in the connection notice:
958 >  /*
959 >   *   Offsets for data in the connection notice:
960 >   *
961 >   *   NICKNAME: pmatch[1].rm_so  TO  pmatch[1].rm_eo
962 >   *   USERNAME: pmatch[2].rm_so  TO  pmatch[2].rm_eo
963 >   *   HOSTNAME: pmatch[3].rm_so  TO  pmatch[3].rm_eo
964 >   *   IP      : pmatch[4].rm_so  TO  pmatch[4].rm_eo
965 >   */
966 >  for (i = 0; i < 4; ++i)
967 >  {
968 >    user[i] = (parv[3] + pmatch[i + 1].rm_so);
969 >    *(parv[3] + pmatch[i + 1].rm_eo) = '\0';
970 >  }
971  
972 <       NICKNAME: pmatch[1].rm_so  TO  pmatch[1].rm_eo
973 <       USERNAME: pmatch[2].rm_so  TO  pmatch[2].rm_eo
974 <       HOSTNAME: pmatch[3].rm_so  TO  pmatch[3].rm_eo
1022 <       IP      : pmatch[4].rm_so  TO  pmatch[4].rm_eo
1023 <
1024 <    */
1025 <
1026 <   for(i = 0; i < 4; i++)
1027 <   {
1028 <      user[i] = (parv[3] + pmatch[i + 1].rm_so);
1029 <      *(parv[3] + pmatch[i + 1].rm_eo) = '\0';
1030 <   }
1031 <
1032 <   if(OPT_DEBUG > 0)
1033 <      log_printf("IRC REGEX -> Parsed %s!%s@%s [%s] from connection notice.",
1034 <          user[0], user[1], user[2], user[3]);
972 >  if (OPT_DEBUG > 0)
973 >    log_printf("IRC REGEX -> Parsed %s!%s@%s [%s] from connection notice.",
974 >               user[0], user[1], user[2], user[3]);
975  
976 <   /*FIXME (reminder) In the case of any rehash to the regex, preg MUST be freed first.
977 <       regfree(preg);
976 >  /*FIXME (reminder) In the case of any rehash to the regex, preg MUST be freed first.
977 >      regfree(preg);
978     */
979  
980 <   /* Pass this information off to scan.c */
981 <   scan_connect(user, msg);
982 <   /* Record the connect for stats purposes */
983 <   stats_connect();
980 >  /* Pass this information off to scan.c */
981 >  scan_connect(user, msg);
982 >
983 >  /* Record the connect for stats purposes */
984 >  stats_connect();
985   }
986  
987   /* m_userhost
# Line 1055 | Line 996 | static void m_notice(char **parv, unsign
996   * the source (parv[0]) is a server.
997   *
998   */
999 <
1000 < static void m_userhost(char **parv, unsigned int parc, char *msg,
1060 <      struct UserInfo *source_p)
999 > static void
1000 > m_userhost(char **parv, unsigned int parc, char *msg, struct UserInfo *source_p)
1001   {
1002 <   if(parc < 4)
1003 <      return;
1002 >  if (parc < 4)
1003 >    return;
1004  
1005 <   command_userhost(parv[3]);
1005 >  command_userhost(parv[3]);
1006   }
1007  
1008   /* m_cannot_join
# Line 1074 | Line 1014 | static void m_userhost(char **parv, unsi
1014   * parv[4]  = error text
1015   *
1016   */
1017 <
1018 < static void m_cannot_join(char **parv, unsigned int parc, char *msg,
1079 <      struct UserInfo *source_p)
1017 > static void
1018 > m_cannot_join(char **parv, unsigned int parc, char *msg, struct UserInfo *source_p)
1019   {
1020 <   struct ChannelConf *channel;
1020 >  struct ChannelConf *channel;
1021  
1022 <   if(parc < 5)
1023 <      return;
1022 >  if (parc < 5)
1023 >    return;
1024  
1025 <   /* Is it one of our channels? */
1026 <   if((channel = get_channel(parv[3])) == NULL)
1027 <      return;
1025 >  /* Is it one of our channels? */
1026 >  if ((channel = get_channel(parv[3])) == NULL)
1027 >    return;
1028  
1029 <   if (EmptyString(channel->invite))
1030 <      return;
1029 >  if (EmptyString(channel->invite))
1030 >    return;
1031  
1032 <   irc_send("%s", channel->invite);
1032 >  irc_send("%s", channel->invite);
1033   }
1034  
1096
1035   /* m_kill
1036   *
1037   * parv[0]  = source
# Line 1103 | Line 1041 | static void m_cannot_join(char **parv, u
1041   * parv[4]  = error text
1042   *
1043   */
1044 <
1045 < static void m_kill(char **parv, unsigned int parc, char *msg, struct UserInfo *source_p)
1044 > static void
1045 > m_kill(char **parv, unsigned int parc, char *msg, struct UserInfo *source_p)
1046   {
1047    /* Restart hopm to rehash */
1048    main_restart();

Comparing hopm/trunk/src/irc.c (property svn:eol-style):
Revision 5106 by michael, Wed Dec 24 12:47:21 2014 UTC vs.
Revision 5198 by michael, Mon Dec 29 16:53:16 2014 UTC

# Line 0 | Line 1
1 + native

Comparing hopm/trunk/src/irc.c (property svn:keywords):
Revision 5106 by michael, Wed Dec 24 12:47:21 2014 UTC vs.
Revision 5198 by michael, Mon Dec 29 16:53:16 2014 UTC

# Line 0 | Line 1
1 + Id

Diff Legend

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