--- ircservices-5.1a5/extern.h Tue Jan 24 00:04:52 2006 +++ ircservices-5.1a5.patch/extern.h Mon Jan 30 18:34:14 2006 @@ -306,7 +306,9 @@ E void split_usermask(const char *mask, char **nick, char **user, char **host); E char *create_mask(User *u, int use_fakehost); -E char *make_guest_nick(void); +E char *make_guest_nick(const char *nick); +E char *format_guestprefix(const char *format, const char *nick); + E int is_guest_nick(const char *nick); --- ircservices-5.1a5/modules/nickserv/collide.c Tue Jan 24 00:04:54 2006 +++ ircservices-5.1a5.patch/modules/nickserv/collide.c Mon Jan 30 18:39:11 2006 @@ -48,7 +48,7 @@ if (call_callback_1(cb_collide, ni->user) > 0) return; if (NSForceNickChange) { - char *guestnick = make_guest_nick(); + char *guestnick = make_guest_nick(ni->nick); notice_lang(s_NickServ, ni->user, FORCENICKCHANGE_NOW, guestnick); send_nickchange_remote(ni->nick, guestnick); ni->status |= NS_GUESTED; --- ircservices-5.1a5/modules/operserv/sline.c Tue Jan 24 00:04:54 2006 +++ ircservices-5.1a5.patch/modules/operserv/sline.c Mon Jan 30 18:39:54 2006 @@ -135,7 +135,7 @@ if (!SQlineKill && (protocol_features & PF_CHANGENICK)) { send_cmd(ServerName, "432 %s %s Invalid nickname (%s)", nick, nick, reason); - send_nickchange_remote(nick, make_guest_nick()); + send_nickchange_remote(nick, make_guest_nick(nick)); } else { /* User is to be killed */ retval = reason; --- ircservices-5.1a5/users.c Tue Jan 24 00:04:53 2006 +++ ircservices-5.1a5.patch/users.c Mon Jan 30 18:59:49 2006 @@ -832,7 +832,7 @@ * restarted. */ -char *make_guest_nick(void) +char *make_guest_nick(const char *nick) { static char nickbuf[NICKMAX+1]; /* +1 to check for overrun */ static uint32 counter = 0; /* Unique suffix counter */ @@ -841,8 +841,10 @@ uint32 suffixmod; /* Modulo for suffix counter */ int i; + char *p_GuestNickPrefix = format_guestprefix(GuestNickPrefix, nick); + /* Sanity checks on nick prefix length */ - prefixlen = strlen(GuestNickPrefix); + prefixlen = strlen(p_GuestNickPrefix); if (protocol_nickmax <= 4) { /* This violates RFC1459 as well as common sense, so just blow * ourselves out of the water. */ @@ -851,9 +853,9 @@ } else if (prefixlen+4 > protocol_nickmax) { /* Reserve at least 4 digits for the suffix */ prefixlen = protocol_nickmax-4; - log("warning: make_guest_nick(): GuestNickPrefix too long," + log("warning: make_guest_nick(): p_GuestNickPrefix too long," " shortening to %d characters", prefixlen); - GuestNickPrefix[prefixlen] = 0; + p_GuestNickPrefix[prefixlen] = 0; } /* Calculate number of digits available for suffix -> suffix modulo */ @@ -878,7 +880,7 @@ counter %= suffixmod; if (counter == 0) /* if rand() gave us 0 or N*suffixmod... */ counter = 1; /* ... use 1 instead */ - i = snprintf(nickbuf, sizeof(nickbuf), "%s%u", GuestNickPrefix, counter); + i = snprintf(nickbuf, sizeof(nickbuf), "%s%u", p_GuestNickPrefix, counter); if (i > protocol_nickmax) { log("BUG: make_guest_nick() generated %s but nickmax == %d!", nickbuf, protocol_nickmax); @@ -904,6 +906,38 @@ /* Return the nick */ return nickbuf; }; + +/* Create and return the nickname for the given nick and format + * string. The nickname will be truncated at protocol_nickmax-1 bytes. + * The nickname is returned in a static buffer, and will be overwritten + * by subsequent calls. + */ + +char *format_guestprefix(const char *format, const char *nick) +{ + static char guestnick[NICKMAX-4]; + char *s; + int nick_guestnick_len = -1; + + s = guestnick; + while (*format && s-guestnick < sizeof(guestnick)-1) { + if (*format == '%' && format[1] == 's') { + int left = (sizeof(guestnick)-1) - (s-guestnick); + if (nick_guestnick_len < 0) + nick_guestnick_len = strlen(nick); + if (left > nick_guestnick_len) + left = nick_guestnick_len; + memcpy(s, nick, left); + s += left; + format += 2; + } else { + *s++ = *format++; + } + } + *s = 0; + return guestnick; +} + /*************************************************************************/