# Optional functions
AC_CHECK_FUNCS_ONCE([
arc4random arc4random_stir gai_strerror getnameinfo inet_aton \
- sigaction sigprocmask snprintf vsnprintf strdup strndup strlcpy strlcat \
- strtok_r unsetenv waitpid])
+ setgroups sigaction sigprocmask snprintf strdup strlcat strlcpy \
+ strndup strtok_r unsetenv vsnprintf waitpid])
WORKING_GETADDRINFO
generated after each server start.
.TP
\fBCloakUserToNick\fR (boolean)
-Set every clients' user name to their nickname and hide the one supplied
-by the IRC client. Default: no.
+Set every clients' user name and real name to their nickname and hide the one
+supplied by the IRC client. Default: no.
.TP
\fBConnectIPv4\fR (boolean)
Set this to no if you do not want ngIRCd to connect to other IRC servers using
.TP
\fBMorePrivacy\fR (boolean)
This will cause ngIRCd to censor user idle time, logon time as well as the
-part/quit messages (that are sometimes used to inform everyone about which
-client software is being used). WHOWAS requests are also silently ignored.
+PART/QUIT messages (that are sometimes used to inform everyone about which
+client software is being used). WHOWAS requests are also silently ignored,
+and NAMES output doesn't list any clients for non-members.
This option is most useful when ngIRCd is being used together with
anonymizing software such as TOR or I2P and one does not wish to make it
too easy to collect statistics on the users.
}
}
+ /* Send list head */
+ if (!IRC_WriteStrClient(from, RPL_LISTSTART_MSG, Client_ID(from)))
+ return DISCONNECTED;
+
while (pattern) {
/* Loop through all the channels */
if (Req->argc > 0)
/* Gotcha! */
if (!Channel_HasMode(chan, 's')
|| Channel_IsMemberOf(chan, from)
- || (!Conf_MorePrivacy
- && Client_HasMode(Client, 'o')
- && Client_Conn(Client) > NONE))
+ || Client_HasMode(from, 'o'))
{
if ((Conf_MaxListSize > 0)
&& IRC_CheckListTooBig(from, count,
/* Local client and requester is the user itself or an IRC Op? */
if (Client_Conn(c) > NONE &&
- (from == c || (!Conf_MorePrivacy && Client_HasMode(from, 'o')))) {
+ (from == c || Client_HasMode(from, 'o'))) {
/* Client hostname */
if (!IRC_WriteStrClient(from, RPL_WHOISHOST_MSG,
Client_ID(from), Client_ID(c),
GLOBAL bool
Match( const char *Pattern, const char *String )
{
- if( Matche( Pattern, String ) == MATCH_VALID ) return true;
- else return false;
+ if (Matche(Pattern, String) == MATCH_VALID)
+ return true;
+ else
+ return false;
} /* Match */
/**
GLOBAL bool
MatchCaseInsensitive(const char *Pattern, const char *String)
{
- char haystack[COMMAND_LEN];
+ char needle[COMMAND_LEN], haystack[COMMAND_LEN];
+ strlcpy(needle, Pattern, sizeof(needle));
strlcpy(haystack, String, sizeof(haystack));
- return Match(Pattern, ngt_LowerStr(haystack));
+
+ return Match(ngt_LowerStr(needle), ngt_LowerStr(haystack));
} /* MatchCaseInsensitive */
/**
MatchCaseInsensitiveList(const char *Pattern, const char *String,
const char *Separator)
{
- char tmp_pattern[COMMAND_LEN], haystack[COMMAND_LEN], *ptr;
+ char tmp_pattern[COMMAND_LEN], *ptr;
strlcpy(tmp_pattern, Pattern, sizeof(tmp_pattern));
- strlcpy(haystack, String, sizeof(haystack));
- ngt_LowerStr(haystack);
ptr = strtok(tmp_pattern, Separator);
while (ptr) {
ngt_TrimStr(ptr);
- if (Match(ptr, haystack))
+ if (MatchCaseInsensitive(ptr, String))
return true;
ptr = strtok(NULL, Separator);
}
#define RPL_WHOISIDLE_MSG "317 %s %s %lu %lu :seconds idle, signon time"
#define RPL_ENDOFWHOIS_MSG "318 %s %s :End of WHOIS list"
#define RPL_WHOISCHANNELS_MSG "319 %s %s :"
+#define RPL_LISTSTART_MSG "321 %s Channel :Users Name"
#define RPL_LIST_MSG "322 %s %s %ld :%s"
#define RPL_LISTEND_MSG "323 %s :End of LIST"
#define RPL_CHANNELMODEIS_MSG "324 %s %s +%s"
if (real_errno != EPERM)
goto out;
}
+#ifdef HAVE_SETGROUPS
if (setgroups(0, NULL) != 0) {
real_errno = errno;
Log(LOG_ERR, "Can't drop supplementary group IDs: %s!",
if (real_errno != EPERM)
goto out;
}
+#else
+ Log(LOG_WARNING,
+ "Can't drop supplementary group IDs: setgroups(3) missing!");
+#endif
}
#endif