Use strtok_r instead of strchr in IRC_JOIN.

This patch does significant cleanup on the join code by using strtok_r
instead of mangling strchr to parse channel names and keys in parallel when
a JOIN command contains a list of channels and keys.

Also adds an strtok_r implementation to libportab.
This commit is contained in:
Scott Perry 2008-05-26 12:38:15 +02:00 committed by Florian Westphal
parent d060e90de0
commit b90f71ca2a
5 changed files with 41 additions and 26 deletions

View File

@ -139,7 +139,7 @@ AC_CHECK_FUNCS([ \
bind gethostbyaddr gethostbyname gethostname inet_ntoa \
setsid setsockopt socket strcasecmp waitpid],,AC_MSG_ERROR([required function missing!]))
AC_CHECK_FUNCS(inet_aton isdigit sigaction snprintf vsnprintf strdup strlcpy strlcat)
AC_CHECK_FUNCS(inet_aton isdigit sigaction snprintf vsnprintf strdup strlcpy strlcat strtok_r)
# -- Configuration options --

View File

@ -182,7 +182,7 @@ join_send_topic(CLIENT *Client, CLIENT *target, CHANNEL *chan,
GLOBAL bool
IRC_JOIN( CLIENT *Client, REQUEST *Req )
{
char *channame, *channame_ptr, *key, *key_ptr, *flags;
char *channame, *key = NULL, *flags, *lastkey, *lastchan;
CLIENT *target;
CHANNEL *chan;
@ -208,16 +208,11 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
return part_from_all_channels(Client, target);
/* Are channel keys given? */
if (Req->argc > 1) {
key = Req->argv[1];
key_ptr = strchr(key, ',');
if (key_ptr) *key_ptr = '\0';
} else {
key = key_ptr = NULL;
}
if (Req->argc > 1)
key = strtok_r(Req->argv[1], ",", &lastkey);
channame = Req->argv[0];
channame_ptr = strchr(channame, ',');
if (channame_ptr) *channame_ptr = '\0';
channame = strtok_r(channame, ",", &lastchan);
while (channame) {
flags = NULL;
@ -288,18 +283,9 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
break; /* write error */
/* next channel? */
channame = channame_ptr;
if (channame) {
channame++;
channame_ptr = strchr(channame, ',');
if (channame_ptr) *channame_ptr = '\0';
if (key_ptr) {
key = ++key_ptr;
key_ptr = strchr(key, ',');
if (key_ptr) *key_ptr = '\0';
}
}
channame = strtok_r(NULL, ",", &lastchan);
if (channame && key)
key = strtok_r(NULL, ",", &lastkey);
}
return CONNECTED;
} /* IRC_JOIN */

View File

@ -9,14 +9,12 @@
# Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
# der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
#
# $Id: Makefile.am,v 1.8 2005/04/16 09:23:01 fw Exp $
#
AUTOMAKE_OPTIONS = ansi2knr
noinst_LIBRARIES = libngportab.a
libngportab_a_SOURCES = strlcpy.c strdup.c vsnprintf.c
libngportab_a_SOURCES = strdup.c strlcpy.c strtok_r.c vsnprintf.c
check_PROGRAMS = portabtest

View File

@ -148,6 +148,10 @@ extern size_t strlcpy PARAMS(( char *dst, const char *src, size_t size ));
extern char * strdup PARAMS(( const char *s ));
#endif
#ifndef HAVE_STRTOK_R
extern char * strtok_r PARAMS((char *str, const char *delim, char **saveptr));
#endif
#ifndef HAVE_VSNPRINTF
#include <stdarg.h>
extern int vsnprintf PARAMS(( char *str, size_t count, const char *fmt, va_list args ));

27
src/portab/strtok_r.c Normal file
View File

@ -0,0 +1,27 @@
#include "portab.h"
#include <string.h>
#ifndef HAVE_STRTOK_R
char *
strtok_r(char *str, const char *delim, char **saveptr)
{
char *tmp;
if (!str)
str = *saveptr;
str += strspn(str, delim);
if (*str == 0)
return NULL;
tmp = str + strcspn(str, delim); /* get end of token */
if (*tmp) { /* another delimiter */
*tmp = 0;
tmp++;
}
*saveptr = tmp;
return str;
}
#endif