Fix IRC_Send_NAMES not sending correct prefix for certain clients.
I. Introduction
~~~~~~~~~~~~~~~
-ngIRCd is an Open Source server for the Internet Relay Chat (IRC), which
-is developed and published under the terms of the GNU General Public
-Licence, see the file COPYING for details. ngIRCd means "next generation
-IRC daemon" (which is a little bit exaggerated, "lightweight Internet Relay
-Chat server" would be better), it's written from scratch and not deduced
-from the "grandfather of IRC daemons", the daemon of the IRCNet.
+ngIRCd is a free, portable and lightweight Internet Relay Chat server for
+small or private networks, developed under the GNU General Public License
+(GPL; please see the file COPYING for details). It is simple to configure,
+can cope with dynamic IP addresses, and supports IPv6 as well as SSL. It is
+written from scratch and not based on the original IRCd.
+
+The name ngIRCd means next generation IRC daemon, which is a little bit
+exaggerated: lightweight Internet Relay Chat server most probably would be a
+better name :-)
Please see the INSTALL document for installation and upgrade information!
Depends: ${shlibs:Depends}, ${misc:Depends}
Provides: ircd
Description: lightweight Internet Relay Chat server
- This package provides ngIRCd, a lightweight Internet Relay Chat
- server for small or private networks. It is simple to configure, can
- cope with dynamic IP addresses, and supports IPv6 as well as SSL. It
- is written from scratch, not based on the original IRCd and quite
- portable.
+ This package provides ngIRCd, a portable and lightweight Internet Relay
+ Chat server for small or private networks, developed under the GNU
+ General Public License (GPL). It is simple to configure, can cope with
+ dynamic IP addresses, and supports IPv6 as well as SSL. It is written
+ from scratch and not based on the original IRCd.
.
This package contains the "standard distribution", including support for
syslog logging and compressed server-links using zlib. Please have a look
Provides: ircd
Conflicts: ngircd, ngircd-dbg
Description: lightweight Internet Relay Chat server
- This package provides ngIRCd, a lightweight Internet Relay Chat
- server for small or private networks. It is simple to configure, can
- cope with dynamic IP addresses, and supports IPv6 as well as SSL. It
- is written from scratch, not based on the original IRCd and quite
- portable.
+ This package provides ngIRCd, a portable and lightweight Internet Relay
+ Chat server for small or private networks, developed under the GNU
+ General Public License (GPL). It is simple to configure, can cope with
+ dynamic IP addresses, and supports IPv6 as well as SSL. It is written
+ from scratch and not based on the original IRCd.
.
In addition to the features of the "standard package", this package
includes support for TCP wrappers, IDENT requests, the IPv6 protocol and
Provides: ircd
Conflicts: ngircd, ngircd-full
Description: lightweight Internet Relay Chat server
- This package provides ngIRCd, a lightweight Internet Relay Chat
- server for small or private networks. It is simple to configure, can
- cope with dynamic IP addresses, and supports IPv6 as well as SSL. It
- is written from scratch, not based on the original IRCd and quite
- portable.
+ This package provides ngIRCd, a portable and lightweight Internet Relay
+ Chat server for small or private networks, developed under the GNU
+ General Public License (GPL). It is simple to configure, can cope with
+ dynamic IP addresses, and supports IPv6 as well as SSL. It is written
+ from scratch and not based on the original IRCd.
.
In addition to the features of the "standard package", this package
includes support for TCP wrappers, IDENT requests, the IPv6 protocol and
ngircd-bsd.sh \
ngIRCd-Logo.gif \
ngircd-redhat.init \
- ngircd.service
+ ngircd.service \
ngircd.spec \
platformtest.sh \
systrace.policy
BuildRequires: zlib-devel, openssl-devel
%description
-This package provides ngIRCd, a lightweight Internet Relay Chat
-server for small or private networks. It is simple to configure, can
-cope with dynamic IP addresses, and supports IPv6 as well as SSL. It
-is written from scratch, not based on the original IRCd and quite
-portable.
+This package provides ngIRCd, a portable and lightweight Internet Relay
+Chat server for small or private networks, developed under the GNU
+General Public License (GPL). It is simple to configure, can cope with
+dynamic IP addresses, and supports IPv6 as well as SSL. It is written
+from scratch and not based on the original IRCd.
Advantages:
- well arranged (lean) configuration file
ngIRCd - Next Generation IRC Server
http://ngircd.barton.de/
- (c)2001-2011 Alexander Barton and Contributors.
+ (c)2001-2012 Alexander Barton and Contributors.
ngIRCd is free software and published under the
terms of the GNU General Public License.
mode since description
a 0.3.0 User is away.
+ B 20 User is flagged as a "bot".
c 17 IRC operator wants to receive connect/disconnect NOTICEs.
C 19 Only users that share a channel are allowed to send messages.
i 0.0.1 User is "invisible".
k 0.6.0 Channel has a "key" (a password).
l 0.6.0 Channel has a user limit.
m 0.3.0 Channel is moderated, only "voiced" users can send messages.
+ M 20 Only registered users (and IRC Ops) can send messages.
n 0.3.0 Channel doesn't allow messages of users not being members.
O 18 Only IRC operators are allowed to join this channel.
P 0.5.0 Channel is "persistent".
GLOBAL void
Channel_Init( void )
{
- CHANNEL *sc;
-
My_Channels = NULL;
My_Cl2Chan = NULL;
-
- sc = Channel_Create("&SERVER");
- if (sc) {
- Channel_SetModes(sc, "mnPt");
- Channel_SetTopic(sc, Client_ThisServer(), "Server Messages");
- }
} /* Channel_Init */
}
+/**
+ * Generate predefined persistent channels and &SERVER
+ */
GLOBAL void
Channel_InitPredefined( void )
{
- /* Generate predefined persistent channels */
-
CHANNEL *new_chan;
const struct Conf_Channel *conf_chan;
const char *c;
}
if (channel_count)
array_free(&Conf_Channels);
+
+ /* Make sure the local &SERVER channel exists */
+ if (!Channel_Search("&SERVER")) {
+ new_chan = Channel_Create("&SERVER");
+ if (new_chan) {
+ Channel_SetModes(new_chan, "mnPt");
+ Channel_SetTopic(new_chan, Client_ThisServer(),
+ "Server Messages");
+ } else
+ Log(LOG_ERR, "Failed to create \"&SERVER\" channel!");
+ } else
+ LogDebug("Required channel \"&SERVER\" already exists, ok.");
} /* Channel_InitPredefined */
if (strchr(Channel_Modes(Chan), 'n') && !is_member)
return false;
+ if (strchr(Channel_Modes(Chan), 'M') && !Client_HasMode(From, 'R')
+ && !Client_HasMode(From, 'o'))
+ return false;
+
if (is_op || has_voice)
return true;
/**
* Get potentially cloaked hostname of a client.
+ *
* If the client has not enabled cloaking, the real hostname is used.
+ * Please note that this function uses a global static buffer, so you can't
+ * nest invocations without overwriting earlier results!
+ *
* @param Client Pointer to client structure
* @return Pointer to client hostname
*/
GLOBAL char *
Client_HostnameCloaked(CLIENT *Client)
{
+ static char Cloak_Buffer[CLIENT_HOST_LEN];
+
assert(Client != NULL);
- if (Client_HasMode(Client, 'x'))
- return Client_ID(Client->introducer);
- else
+
+ if (!Client_HasMode(Client, 'x'))
return Client_Hostname(Client);
+
+ /* Do simple mapping to the server ID? */
+ if (!*Conf_CloakHostModeX)
+ return Client_ID(Client->introducer);
+
+ strlcpy(Cloak_Buffer, Client->host, CLIENT_HOST_LEN);
+ strlcat(Cloak_Buffer, Conf_CloakHostSalt, CLIENT_HOST_LEN);
+
+ snprintf(Cloak_Buffer, CLIENT_HOST_LEN, Conf_CloakHostModeX,
+ Hash(Cloak_Buffer));
+
+ return Cloak_Buffer;
} /* Client_HostnameCloaked */
/**
* Return ID of a client with cloaked hostname: "client!user@server-name"
+ *
* This client ID is used for IRC prefixes, for example.
* Please note that this function uses a global static buffer, so you can't
* nest invocations without overwriting earlier results!
* If the client has not enabled cloaking, the real hostname is used.
+ *
* @param Client Pointer to client structure
* @return Pointer to global buffer containing the client ID
*/
Client_MaskCloaked(CLIENT *Client)
{
static char Mask_Buffer[GETID_LEN];
- char Cloak_Buffer[GETID_LEN];
assert (Client != NULL);
if (!Client_HasMode(Client, 'x'))
return Client_Mask(Client);
- if(*Conf_CloakHostModeX) {
- strlcpy(Cloak_Buffer, Client->host, GETID_LEN);
- strlcat(Cloak_Buffer, Conf_CloakHostSalt, GETID_LEN);
- snprintf(Cloak_Buffer, GETID_LEN, Conf_CloakHostModeX, Hash(Cloak_Buffer));
- } else {
- strncpy(Cloak_Buffer, Client_ID(Client->introducer), GETID_LEN);
- }
-
- snprintf(Mask_Buffer, GETID_LEN, "%s!%s@%s",
- Client->id, Client->user, Cloak_Buffer);
+ snprintf(Mask_Buffer, GETID_LEN, "%s!%s@%s", Client->id, Client->user,
+ Client_HostnameCloaked(Client));
return Mask_Buffer;
} /* Client_MaskCloaked */
puts("[LIMITS]");
printf(" ConnectRetry = %d\n", Conf_ConnectRetry);
- printf(" MaxConnections = %ld\n", Conf_MaxConnections);
+ printf(" MaxConnections = %d\n", Conf_MaxConnections);
printf(" MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP);
printf(" MaxJoins = %d\n", Conf_MaxJoins > 0 ? Conf_MaxJoins : -1);
printf(" MaxNickLength = %u\n", Conf_MaxNickLength - 1);
return;
}
if (strcasecmp(Var, "MaxConnections") == 0) {
- Conf_MaxConnections = atol(Arg);
+ Conf_MaxConnections = atoi(Arg);
if (!Conf_MaxConnections && strcmp(Arg, "0"))
Config_Error_NaN(Line, Var);
return;
bool config_valid = true;
char *ptr;
+ /* Emit a warning when the config file is not a full path name */
+ if (NGIRCd_ConfFile[0] && NGIRCd_ConfFile[0] != '/') {
+ Config_Error(LOG_WARNING,
+ "Not specifying a full path name to \"%s\" can cause problems when rehashing the server!",
+ NGIRCd_ConfFile);
+ }
+
/* Validate configured server name, see RFC 2812 section 2.3.1 */
ptr = Conf_ServerName;
do {
GLOBAL bool Conf_ConnectIPv4;
/** Maximum number of simultaneous connections to this server */
-GLOBAL long Conf_MaxConnections;
+GLOBAL int Conf_MaxConnections;
/** Maximum number of channels a user can join */
GLOBAL int Conf_MaxJoins;
#endif /* _GNUTLS */
Conn_OPTION_DEL(c, (CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ|CONN_SSL_CONNECT));
ConnSSL_LogCertInfo(c);
+
+ Conn_StartLogin(CONNECTION2ID(c));
return 1;
}
static bool Handle_Write PARAMS(( CONN_ID Idx ));
static bool Conn_Write PARAMS(( CONN_ID Idx, char *Data, size_t Len ));
-static int New_Connection PARAMS(( int Sock ));
+static int New_Connection PARAMS(( int Sock, bool IsSSL ));
static CONN_ID Socket2Index PARAMS(( int Sock ));
static void Read_Request PARAMS(( CONN_ID Idx ));
static unsigned int Handle_Buffer PARAMS(( CONN_ID Idx ));
cb_listen(int sock, short irrelevant)
{
(void) irrelevant;
- (void) New_Connection(sock);
+ (void) New_Connection(sock, false);
}
int fd;
(void) irrelevant;
- fd = New_Connection(sock);
+ fd = New_Connection(sock, true);
if (fd < 0)
return;
io_event_setcb(My_Connections[fd].sock, cb_clientserver_ssl);
* Initialize new client connection on a listening socket.
*
* @param Sock Listening socket descriptor.
+ * @param IsSSL true if this socket expects SSL-encrypted data.
* @returns Accepted socket descriptor or -1 on error.
*/
static int
-New_Connection(int Sock)
+New_Connection(int Sock, UNUSED bool IsSSL)
{
#ifdef TCPWRAP
struct request_info req;
#endif
ng_ipaddr_t new_addr;
char ip_str[NG_INET_ADDRSTRLEN];
- int new_sock, new_sock_len, identsock;
+ int new_sock, new_sock_len;
CLIENT *c;
long cnt;
Log(LOG_INFO, "Accepted connection %d from %s:%d on socket %d.",
new_sock, My_Connections[new_sock].host,
ng_ipaddr_getport(&new_addr), Sock);
+ Account_Connection();
+
+#ifdef SSL_SUPPORT
+ /* Delay connection initalization until SSL handshake is finished */
+ if (!IsSSL)
+#endif
+ Conn_StartLogin(new_sock);
+
+ return new_sock;
+} /* New_Connection */
+
+
+/**
+ * Finish connection initialization, start resolver subprocess.
+ *
+ * @param Idx Connection index.
+ */
+GLOBAL void
+Conn_StartLogin(CONN_ID Idx)
+{
+ int ident_sock = -1;
+
+ assert(Idx >= 0);
+
+ /* Nothing to do if DNS (and resolver subprocess) is disabled */
+ if (!Conf_DNS)
+ return;
- identsock = new_sock;
#ifdef IDENTAUTH
- if (!Conf_Ident)
- identsock = -1;
+ /* Should we make an IDENT request? */
+ if (Conf_Ident)
+ ident_sock = My_Connections[Idx].sock;
#endif
- if (Conf_DNS) {
- if (Conf_NoticeAuth) {
+
+ if (Conf_NoticeAuth) {
+ /* Send "NOTICE AUTH" messages to the client */
#ifdef IDENTAUTH
- if (Conf_Ident)
- (void)Conn_WriteStr(new_sock,
- "NOTICE AUTH :*** Looking up your hostname and checking ident");
- else
+ if (Conf_Ident)
+ (void)Conn_WriteStr(Idx,
+ "NOTICE AUTH :*** Looking up your hostname and checking ident");
+ else
#endif
- (void)Conn_WriteStr(new_sock,
- "NOTICE AUTH :*** Looking up your hostname");
- }
- Resolve_Addr(&My_Connections[new_sock].proc_stat, &new_addr,
- identsock, cb_Read_Resolver_Result);
+ (void)Conn_WriteStr(Idx,
+ "NOTICE AUTH :*** Looking up your hostname");
+ (void)Handle_Write(Idx);
}
- Account_Connection();
- return new_sock;
-} /* New_Connection */
+ Resolve_Addr(&My_Connections[Idx].proc_stat, &My_Connections[Idx].addr,
+ ident_sock, cb_Read_Resolver_Result);
+}
/**
Client_SetHostname(c, readbuf);
if (Conf_NoticeAuth)
(void)Conn_WriteStr(i,
- "NOTICE AUTH :*** Found your hostname");
+ "NOTICE AUTH :*** Found your hostname: %s",
+ My_Connections[i].host);
#ifdef IDENTAUTH
++identptr;
if (*identptr) {
}
if (Conf_NoticeAuth) {
(void)Conn_WriteStr(i,
- "NOTICE AUTH :*** Got %sident response",
- *ptr ? "invalid " : "");
+ "NOTICE AUTH :*** Got %sident response%s%s",
+ *ptr ? "invalid " : "",
+ *ptr ? "" : ": ",
+ *ptr ? "" : identptr);
}
} else {
Log(LOG_INFO, "IDENT lookup for connection %d: no result.", i);
"NOTICE AUTH :*** No ident response");
}
#endif
+
+ if (Conf_NoticeAuth)
+ (void)Handle_Write(i);
+
Class_HandleServerBans(c);
}
#ifdef DEBUG
#define CONN_SSL_WANT_READ 128 /* SSL/TLS library needs to read protocol data */
#define CONN_SSL_FLAGS_ALL (CONN_SSL_CONNECT|CONN_SSL|CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ)
#endif
-typedef long CONN_ID;
+typedef int CONN_ID;
#include "client.h"
#include "proc.h"
GLOBAL CONN_ID Pool_Size;
GLOBAL long WCounter;
+#define CONNECTION2ID(x) (long)(x - My_Connections)
+
#endif /* CONN_MODULE */
GLOBAL unsigned int Conn_InitListeners PARAMS(( void ));
GLOBAL void Conn_ExitListeners PARAMS(( void ));
+GLOBAL void Conn_StartLogin PARAMS((CONN_ID Idx));
+
GLOBAL void Conn_Handler PARAMS(( void ));
GLOBAL bool Conn_WriteStr PARAMS(( CONN_ID Idx, const char *Format, ... ));
GLOBAL CONN_ID Conn_GetFromProc PARAMS((int fd));
GLOBAL CLIENT* Conn_GetClient PARAMS((CONN_ID i));
GLOBAL PROC_STAT* Conn_GetProcStat PARAMS((CONN_ID i));
+
#ifdef SSL_SUPPORT
GLOBAL bool Conn_GetCipherInfo PARAMS((CONN_ID Idx, char *buf, size_t len));
GLOBAL bool Conn_UsesSSL PARAMS((CONN_ID Idx));
#endif
/** Supported user modes. */
-#define USERMODES "acCiorRswx"
+#define USERMODES "aBcCiorRswx"
/** Supported channel modes. */
-#define CHANMODES "beiIklmnoOPrRstvz"
+#define CHANMODES "beiIklmMnoOPrRstvz"
/** Away message for users connected to linked servers. */
#define DEFAULT_AWAY_MSG "Away"
static int io_dispatch_kqueue(struct timeval *tv);
static bool io_event_change_kqueue(int, short, const int action);
+
+#ifndef EV_SET
+/* Taken from /usr/include/sys/event.h of FreeBSD 8.1 and required by all
+ * platforms that have kqueue but lack EV_SET() -- for example FreeBSD 4. */
+#define EV_SET(kevp, a, b, c, d, e, f) do { \
+ struct kevent *__kevp__ = (kevp); \
+ __kevp__->ident = (a); \
+ __kevp__->filter = (b); \
+ __kevp__->flags = (c); \
+ __kevp__->fflags = (d); \
+ __kevp__->data = (e); \
+ __kevp__->udata = (f); \
+} while(0)
+#endif
#endif
#ifdef IO_USE_POLL
* @param Capabilities Capability flags (bitmask).
* @return Pointer to textual representation.
*/
-char
-*Get_CAP_String(int Capabilities)
+char *
+Get_CAP_String(int Capabilities)
{
static char txt[COMMAND_LEN];
assert( Client != NULL );
assert( Chan != NULL );
+ IRC_SetPenalty(Client, 1);
+
is_member = Channel_IsMemberOf(Chan, Client);
/* Secret channel? */
is_visible = strchr(client_modes, 'i') == NULL;
if (is_member || is_visible) {
- if (IRC_CheckListTooBig(Client, count, MAX_RPL_WHO, "WHO"))
- break;
-
strcpy(flags, who_flags_status(client_modes));
if (is_ircop)
strlcat(flags, "*", sizeof(flags));
count++;
}
}
+
+ /* If there are a lot of clients, augment penalty a bit */
+ if (count > MAX_RPL_WHO)
+ IRC_SetPenalty(Client, 1);
+
return IRC_WriteStrClient(Client, RPL_ENDOFWHO_MSG, Client_ID(Client),
Channel_Name(Chan));
}
if (Mask)
ngt_LowerStr(Mask);
+ IRC_SetPenalty(Client, 3);
for (c = Client_First(); c != NULL; c = Client_Next(c)) {
if (Client_Type(c) != CLIENT_USER)
continue;
chan = Channel_Search(Req->argv[0]);
if (chan) {
/* Members of a channel have been requested */
- IRC_SetPenalty(Client, 1);
return IRC_WHO_Channel(Client, chan, only_ops);
}
if (strcmp(Req->argv[0], "0") != 0) {
/* A mask has been given. But please note this RFC
* stupidity: "0" is same as no arguments ... */
- IRC_SetPenalty(Client, 3);
return IRC_WHO_Mask(Client, Req->argv[0], only_ops);
}
}
Client_ID(from), Client_ID(c)))
return DISCONNECTED;
+ /* IRC-Bot? */
+ if (Client_HasMode(c, 'B') &&
+ !IRC_WriteStrClient(from, RPL_WHOISBOT_MSG,
+ Client_ID(from), Client_ID(c)))
+ return DISCONNECTED;
+
/* Connected using SSL? */
if (Conn_UsesSSL(Client_Conn(c)) &&
!IRC_WriteStrClient(from, RPL_WHOISSSL_MSG, Client_ID(from),
static bool
Show_MOTD_End(CLIENT *Client)
{
- return IRC_WriteStrClient( Client, RPL_ENDOFMOTD_MSG, Client_ID( Client ));
+ if (!IRC_WriteStrClient(Client, RPL_ENDOFMOTD_MSG, Client_ID(Client)))
+ return DISCONNECTED;
+
+ if (*Conf_CloakHost)
+ return IRC_WriteStrClient(Client, RPL_HOSTHIDDEN_MSG,
+ Client_ID(Client),
+ Client_Hostname(Client));
+
+ return CONNECTED;
}
#ifdef SSL_SUPPORT
{
char the_modes[COMMAND_LEN], x[2], *mode_ptr;
bool ok, set;
+ bool send_RPL_HOSTHIDDEN_MSG = false;
int mode_arg;
size_t len;
ERR_NOPRIVILEGES_MSG,
Client_ID(Origin));
break;
+ case 'B': /* Bot */
+ if (Client_HasMode(Client, 'r'))
+ ok = IRC_WriteStrClient(Origin,
+ ERR_RESTRICTED_MSG,
+ Client_ID(Origin));
+ else
+ x[0] = 'B';
+ break;
case 'c': /* Receive connect notices
* (only settable by IRC operators!) */
if (!set || Client_Type(Client) == CLIENT_SERVER
ERR_RESTRICTED_MSG,
Client_ID(Origin));
break;
+ case 'R': /* Registered (not [un]settable by clients) */
+ if (Client_Type(Client) == CLIENT_SERVER)
+ x[0] = 'R';
+ else
+ ok = IRC_WriteStrClient(Origin,
+ ERR_NICKREGISTER_MSG,
+ Client_ID(Origin));
+ break;
case 'x': /* Cloak hostname */
if (Client_HasMode(Client, 'r'))
ok = IRC_WriteStrClient(Origin,
Client_ID(Origin));
else
x[0] = 'x';
+ send_RPL_HOSTHIDDEN_MSG = true;
break;
default:
if (Client_Type(Client) != CLIENT_SERVER) {
"MODE %s :%s",
Client_ID(Target),
the_modes);
+ if (send_RPL_HOSTHIDDEN_MSG)
+ IRC_WriteStrClient(Client, RPL_HOSTHIDDEN_MSG,
+ Client_ID(Client),
+ Client_HostnameCloaked(Client));
}
LogDebug("%s \"%s\": Mode change, now \"%s\".",
Client_TypeText(Target), Client_Mask(Target),
switch (*mode_ptr) {
/* --- Channel modes --- */
case 'i': /* Invite only */
+ case 'M': /* Only identified nicks can write */
case 'm': /* Moderated */
case 'n': /* Only members can write */
case 'R': /* Registered users only */
#define RPL_YOURHOST_MSG "002 %s :Your host is %s, running version ngircd-%s (%s/%s/%s)"
#define RPL_CREATED_MSG "003 %s :This server has been started %s"
#define RPL_MYINFO_MSG "004 %s %s ngircd-%s %s %s"
-#define RPL_ISUPPORT1_MSG "005 %s RFC2812 IRCD=ngIRCd CASEMAPPING=ascii PREFIX=(ov)@+ CHANTYPES=#&+ CHANMODES=beI,k,l,imnOPRstz CHANLIMIT=#&+:%d :are supported on this server"
+#define RPL_ISUPPORT1_MSG "005 %s RFC2812 IRCD=ngIRCd CASEMAPPING=ascii PREFIX=(ov)@+ CHANTYPES=#&+ CHANMODES=beI,k,l,imMnOPRstz CHANLIMIT=#&+:%d :are supported on this server"
#define RPL_ISUPPORT2_MSG "005 %s CHANNELLEN=%d NICKLEN=%d TOPICLEN=%d AWAYLEN=%d KICKLEN=%d MODES=%d MAXLIST=beI:%d EXCEPTS=e INVEX=I PENALTY :are supported on this server"
#define RPL_TRACELINK_MSG "200 %s Link %s-%s %s %s V%s %ld %d %d"
#define RPL_NOTOPIC_MSG "331 %s %s :No topic is set"
#define RPL_TOPIC_MSG "332 %s %s :%s"
#define RPL_TOPICSETBY_MSG "333 %s %s %s %u"
+#define RPL_WHOISBOT_MSG "335 %s %s :is a IRC Bot"
#define RPL_INVITING_MSG "341 %s %s %s%s"
#define RPL_INVITELIST_MSG "346 %s %s %s"
#define RPL_ENDOFINVITELIST_MSG "347 %s %s :End of channel invite list"
#define RPL_YOUREOPER_MSG "381 %s :You are now an IRC Operator"
#define RPL_YOURESERVICE_MSG "383 %s :You are service %s"
#define RPL_TIME_MSG "391 %s %s :%s"
+#define RPL_HOSTHIDDEN_MSG "396 %s %s :is your displayed hostname now"
#define ERR_NOSUCHNICK_MSG "401 %s %s :No such nick or channel name"
#define ERR_NOSUCHSERVER_MSG "402 %s %s :No such server"
#define ERR_CHANOPRIVSNEEDED_MSG "482 %s %s :You are not channel operator"
#define ERR_CANTKILLSERVER_MSG "483 %s :You can't kill a server!"
#define ERR_RESTRICTED_MSG "484 %s :Your connection is restricted"
+#define ERR_NICKREGISTER_MSG "484 %s :Cannot modify user mode (+R) -- Use IRC services"
#define ERR_NOOPERHOST_MSG "491 %s :Not configured for your host"
#define ERR_NOTONSAMECHANNEL_MSG "493 %s :You must share a common channel with %s"
Channel_Exit();
Class_Exit();
Log_Exit();
+ Signals_Exit();
}
Pidfile_Delete();
#endif
close(signalpipe[1]);
close(signalpipe[0]);
+ signalpipe[0] = signalpipe[1] = 0;
}
/* -eof- */
* Fill a String with random chars
*/
GLOBAL char *
-ngt_RandomStr( char *String, const size_t len)
+ngt_RandomStr(char *String, const size_t len)
{
- assert(String != NULL);
+ static const char chars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!\"#$&'()*+,-./:;<=>?@[\\]^_`";
+ struct timeval t;
+ size_t i;
- static const char chars[] =
- "0123456789ABCDEFGHIJKLMNO"
- "PQRSTUVWXYZabcdefghijklmn"
- "opqrstuvwxyz!\"#$&'()*+,-"
- "./:;<=>?@[\\]^_`";
+ assert(String != NULL);
- struct timeval t;
gettimeofday(&t, NULL);
srand((unsigned)(t.tv_usec * t.tv_sec));
- for (size_t i = 0; i < len; ++i) {
+ for (i = 0; i < len; ++i) {
String[i] = chars[rand() % (sizeof(chars) - 1)];
}
-
String[len] = '\0';
return String;