This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Undernet IRC Server Source Code.".

The branch, u2_10_12_branch has been updated
       via  ca5c084b1d9d0dfe97f001718dc8dce43c0eb4f3 (commit)
       via  a22917fd394f5e04553e69c5f3bda1111b1b96be (commit)
       via  3c2a199f6f1b73192638969eb414b0a3972f6f28 (commit)
       via  25c0fe836e5478b6ab1d7371ff100d769e5b5526 (commit)
       via  57384c2a60e96454ed79169a3083da0457a9ba6b (commit)
       via  0c3d0f6f9eb138bdb7229045e02391207aa23e33 (commit)
       via  6343d2da49f18acedee9098ea0478933db4c77dd (commit)
       via  199064aebd873818ba4ea41822ae0b82218034b1 (commit)
      from  b5812efe472180bf1734a02240a6cf69a768ee94 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit ca5c084b1d9d0dfe97f001718dc8dce43c0eb4f3
Author: Michael Poole <mdpo...@troilus.org>
Date:   Wed Oct 12 23:31:24 2016 -0400

    m_opmode.c: Implement CFV-0333.
    
    Allow a UWorld-type service to remotely oper (and de-oper) clients.

diff --git a/doc/example.conf b/doc/example.conf
index a246770..e962d7a 100644
--- a/doc/example.conf
+++ b/doc/example.conf
@@ -238,6 +238,10 @@ Class {
  #  rehash, local_gline, local_jupe, local_opmode, whox, display,
  #  force_local_opmode
  # Any privileges listed in a Class block override the defaults.
+ #
+ # If a Class block with "local = no;" and name "RemoteOpers" exists,
+ # it controls the privileges granted when a UWorld service sends an
+ # OPMODE command to make a client into an oper.
 
  local = no;
 };
diff --git a/include/client.h b/include/client.h
index b67baf3..3d62cc7 100644
--- a/include/client.h
+++ b/include/client.h
@@ -744,7 +744,8 @@ extern int client_get_ping(const struct Client* 
local_client);
 extern void client_drop_sendq(struct Connection* con);
 extern void client_add_sendq(struct Connection* con,
                             struct Connection** con_p);
-extern void client_set_privs(struct Client *client, struct ConfItem *oper);
+extern void client_set_privs(struct Client *client, struct ConfItem *oper,
+                            int forceOper);
 extern int client_report_privs(struct Client* to, struct Client* client);
 
 #endif /* INCLUDED_client_h */
diff --git a/include/s_conf.h b/include/s_conf.h
index 56fceef..8b7a024 100644
--- a/include/s_conf.h
+++ b/include/s_conf.h
@@ -34,6 +34,8 @@ struct Message;
 
 #define CONF_AUTOCONNECT        0x0001     /**< Autoconnect to a server */
 
+#define CONF_UWORLD_OPER        0x0001     /**< UWorld server can remotely 
oper users */
+
 /** Indicates ConfItem types that count associated clients. */
 #define CONF_CLIENT_MASK        (CONF_CLIENT | CONF_OPERATOR | CONF_SERVER)
 
diff --git a/ircd/client.c b/ircd/client.c
index e3961b4..f69198f 100644
--- a/ircd/client.c
+++ b/ircd/client.c
@@ -126,18 +126,17 @@ static struct Privs privs_local;
 /** Non-zero if #privs_global and #privs_local have been initialized. */
 static int privs_defaults_set;
 
-/* client_set_privs(struct Client* client)
- *
- * Sets the privileges for opers.
- */
 /** Set the privileges for a client.
  * @param[in] client Client who has become an operator.
  * @param[in] oper Configuration item describing oper's privileges.
+ * @param[in] forceOper Make the user into an operator even if \a oper
+ *   is null.
  */
 void
-client_set_privs(struct Client *client, struct ConfItem *oper)
+client_set_privs(struct Client *client, struct ConfItem *oper, int forceOper)
 {
   struct Privs *source, *defaults;
+  struct ConnectionClass *class;
   enum Priv priv;
 
   if (!MyConnect(client))
@@ -146,7 +145,7 @@ client_set_privs(struct Client *client, struct ConfItem 
*oper)
   /* Clear out client's privileges. */
   memset(cli_privs(client), 0, sizeof(struct Privs));
 
-  if (!IsAnOper(client) || !oper)
+  if (!IsAnOper(client) || (!oper && !forceOper))
       return;
 
   if (!privs_defaults_set)
@@ -176,11 +175,24 @@ client_set_privs(struct Client *client, struct ConfItem 
*oper)
     privs_defaults_set = 1;
   }
 
+  /* Should we look up the default remote oper block? */
+  if (oper)
+  {
+    class = oper->conn_class;
+  }
+  else
+  {
+    class = find_class("RemoteOpers");
+    if (class && (!FlagHas(&class->privs_dirty, PRIV_PROPAGATE
+              || !FlagHas(&class->privs, PRIV_PROPAGATE))))
+      class = NULL;
+  }
+
   /* Decide whether to use global or local oper defaults. */
-  if (FlagHas(&oper->privs_dirty, PRIV_PROPAGATE))
+  if (oper && FlagHas(&oper->privs_dirty, PRIV_PROPAGATE))
     defaults = FlagHas(&oper->privs, PRIV_PROPAGATE) ? &privs_global : 
&privs_local;
-  else if (FlagHas(&oper->conn_class->privs_dirty, PRIV_PROPAGATE))
-    defaults = FlagHas(&oper->conn_class->privs, PRIV_PROPAGATE) ? 
&privs_global : &privs_local;
+  else if (!class || FlagHas(&class->privs_dirty, PRIV_PROPAGATE))
+    defaults = (!class || FlagHas(&class->privs, PRIV_PROPAGATE)) ? 
&privs_global : &privs_local;
   else {
     assert(0 && "Oper has no propagation and neither does connection class");
     return;
@@ -192,10 +204,10 @@ client_set_privs(struct Client *client, struct ConfItem 
*oper)
   for (priv = 0; priv < PRIV_LAST_PRIV; ++priv)
   {
     /* Figure out most applicable definition for the privilege. */
-    if (FlagHas(&oper->privs_dirty, priv))
+    if (oper && FlagHas(&oper->privs_dirty, priv))
       source = &oper->privs;
-    else if (FlagHas(&oper->conn_class->privs_dirty, priv))
-      source = &oper->conn_class->privs;
+    else if (class && FlagHas(&class->privs_dirty, priv))
+      source = &class->privs;
     else
       source = defaults;
 
diff --git a/ircd/ircd_parser.y b/ircd/ircd_parser.y
index 05ddb76..9735036 100644
--- a/ircd/ircd_parser.y
+++ b/ircd/ircd_parser.y
@@ -566,11 +566,17 @@ connectauto: AUTOCONNECT '=' YES ';' { flags |= 
CONF_AUTOCONNECT; }
 
 uworldblock: UWORLD '{' uworlditems '}' ';';
 uworlditems: uworlditem uworlditems | uworlditem;
-uworlditem: uworldname;
+uworlditem: uworldname | uworldoper;
 uworldname: NAME '=' QSTRING ';'
 {
   make_conf(CONF_UWORLD)->host = $3;
 };
+uworldoper: OPER '=' QSTRING ';'
+{
+  struct ConfItem *conf = make_conf(CONF_UWORLD);
+  conf->host = $3;
+  conf->flags = CONF_UWORLD_OPER;
+}
 
 operblock: OPER '{' operitems '}' ';'
 {
diff --git a/ircd/m_oper.c b/ircd/m_oper.c
index c820fe9..7227797 100644
--- a/ircd/m_oper.c
+++ b/ircd/m_oper.c
@@ -168,7 +168,7 @@ int m_oper(struct Client* cptr, struct Client* sptr, int 
parc, char* parv[])
       return 0;
     }
     SetLocOp(sptr);
-    client_set_privs(sptr, aconf);
+    client_set_privs(sptr, aconf, 1);
     if (HasPriv(sptr, PRIV_PROPAGATE))
     {
       ClearLocOp(sptr);
diff --git a/ircd/m_opmode.c b/ircd/m_opmode.c
index 829b323..4ff019a 100644
--- a/ircd/m_opmode.c
+++ b/ircd/m_opmode.c
@@ -93,11 +93,49 @@
 #include "msg.h"
 #include "numeric.h"
 #include "numnicks.h"
+#include "querycmds.h"
 #include "send.h"
 #include "s_conf.h"
+#include "s_user.h"
 
 /* #include <assert.h> -- Now using assert in ircd_log.h */
 
+static void make_oper(struct Client *dptr)
+{
+  ++UserStats.opers;
+  SetOper(dptr);
+  if (MyConnect(dptr))
+  {
+    cli_handler(dptr) = OPER_HANDLER;
+    SetWallops(dptr);
+    SetDebug(dptr);
+    SetServNotice(dptr);
+    det_confs_butmask(dptr, CONF_CLIENT & ~CONF_OPERATOR);
+    client_set_privs(dptr, NULL, 1);
+  }
+}
+
+static void de_oper(struct Client *dptr)
+{
+  --UserStats.opers;
+  ClearOper(dptr);
+  if (MyConnect(dptr))
+  {
+    cli_handler(dptr) = CLIENT_HANDLER;
+    if (feature_bool(FEAT_WALLOPS_OPER_ONLY))
+      ClearWallops(dptr);
+    if (feature_bool(FEAT_HIS_DEBUG_OPER_ONLY))
+      ClearDebug(dptr);
+    if (feature_bool(FEAT_HIS_SNOTICES_OPER_ONLY))
+    {
+      ClearServNotice(dptr);
+      set_snomask(dptr, 0, SNO_SET);
+    }
+    det_confs_butmask(dptr, CONF_CLIENT & ~CONF_OPERATOR);
+    client_set_privs(dptr, NULL, 0);
+  }
+}
+
 /*
  * ms_opmode - server message handler
  */
@@ -112,7 +150,34 @@ int ms_opmode(struct Client* cptr, struct Client* sptr, 
int parc, char* parv[])
   if (IsLocalChannel(parv[1]))
     return 0;
 
-  if ('#' != *parv[1] || !(chptr = FindChannel(parv[1])))
+  if (('#' != *parv[1]) && IsServer(sptr))
+  {
+    struct ConfItem *conf;
+    struct Client *dptr;
+
+    conf = find_conf_byhost(cli_confs(cptr), cli_name(sptr), CONF_UWORLD);
+    if (!conf || !(conf->flags & CONF_UWORLD_OPER))
+      return send_reply(sptr, ERR_NOPRIVILEGES, parv[1]);
+
+    dptr = findNUser(parv[1]);
+    if (!dptr)
+      return send_reply(sptr, ERR_NOSUCHNICK, parv[1]);
+
+    sendcmdto_serv_butone(sptr, CMD_OPMODE, cptr, "%s %s",
+      parv[1], parv[2]);
+
+    /* At the moment, we only support +o and -o.  set_user_mode() does
+     * not support remote mode setting or setting +o.
+     */
+    if (!strcmp(parv[2], "+o") && !IsOper(dptr))
+      make_oper(dptr);
+    else if (!strcmp(parv[2], "-o") && IsOper(dptr))
+      de_oper(dptr);
+
+    return 0;
+  }
+
+  if (!(chptr = FindChannel(parv[1])))
     return send_reply(sptr, ERR_NOSUCHCHANNEL, parv[1]);
 
   modebuf_init(&mbuf, sptr, cptr, chptr,
diff --git a/ircd/s_user.c b/ircd/s_user.c
index 42c7a15..595fabb 100644
--- a/ircd/s_user.c
+++ b/ircd/s_user.c
@@ -477,7 +477,7 @@ int register_user(struct Client *cptr, struct Client *sptr)
       FlagSet(&flags, FLAG_ACCOUNT);
     else
       FlagClr(&flags, FLAG_ACCOUNT);
-    client_set_privs(sptr, NULL);
+    client_set_privs(sptr, NULL, 0);
     send_umode(cptr, sptr, &flags, ALL_UMODES);
     if ((cli_snomask(sptr) != SNO_DEFAULT) && HasFlag(sptr, FLAG_SERVNOTICE))
       send_reply(sptr, RPL_SNOMASK, cli_snomask(sptr), cli_snomask(sptr));
@@ -932,13 +932,12 @@ hide_hostmask(struct Client *cptr, unsigned int flag)
   return 0;
 }
 
-/** Set a user's mode.  This function checks that \a cptr is trying to
- * set his own mode, prevents local users from setting inappropriate
- * modes through this function, and applies any other side effects of
+/** Set a user's mode.  This function prevents local users from setting
+ * unauthorized modes and applies any other side effects of
  * a successful mode change.
  *
- * @param[in,out] cptr User setting someone's mode.
- * @param[in] sptr Client who sent the mode change message.
+ * @param[in] cptr Neighbor that sent the mode change message.
+ * @param[in] sptr Source (originator) of the mode change.
  * @param[in] parc Number of parameters in \a parv.
  * @param[in] parv Parameters to MODE.
  * @param[in] allow_modes ALLOWMODES_ANY for any mode, ALLOWMODES_DEFAULT for 
@@ -1163,7 +1162,7 @@ int set_user_mode(struct Client *cptr, struct Client 
*sptr, int parc,
     if (!FlagHas(&setflags, FLAG_OPER) && IsOper(sptr)) {
       /* user now oper */
       ++UserStats.opers;
-      client_set_privs(sptr, NULL); /* may set propagate privilege */
+      client_set_privs(sptr, NULL, 0); /* may set propagate privilege */
     }
     /* remember propagate privilege setting */
     if (HasPriv(sptr, PRIV_PROPAGATE)) {
@@ -1176,7 +1175,7 @@ int set_user_mode(struct Client *cptr, struct Client 
*sptr, int parc,
         assert(UserStats.opers > 0);
         --UserStats.opers;
       }
-      client_set_privs(sptr, NULL); /* will clear propagate privilege */
+      client_set_privs(sptr, NULL, 0); /* will clear propagate privilege */
     }
     if (FlagHas(&setflags, FLAG_INVISIBLE) && !IsInvisible(sptr)) {
       assert(UserStats.inv_clients > 0);
commit a22917fd394f5e04553e69c5f3bda1111b1b96be
Author: Michael Poole <mdpo...@troilus.org>
Date:   Sat Oct 8 21:11:06 2016 -0400

    s_auth: Check G-lines before IAuth.
    
    Add a new function, iauth_notify(), that sends the appropriate message
    to the IAuth service when some information about a client is updated.
    
    check_auth_finished() now calls this function, and as a result needs to
    know what information was just updated.  However, it also calls
    register_user() before sending the last required information to IAuth,
    so that a G-line keeps the IAuth service from performing full checks.
    
    The syntax for the U message to IAuth is updated to remove fields that
    ircu interprets as mode requests.

diff --git a/doc/readme.iauth b/doc/readme.iauth
index 1962d9c..bbaa241 100644
--- a/doc/readme.iauth
+++ b/doc/readme.iauth
@@ -162,14 +162,13 @@ Comments: Indicates the client's password information.  
This may be a
   enabled by requesting the A policy.
 
 U - Client Username
-Syntax: <id> U <username> <hostname> <servername> :<userinfo ...>
-Example: 5 U buddha bodhisattva.example.com irc.undernet.org :Gautama 
Siddhartha
+Syntax: <id> U <username> :<userinfo ...>
+Example: 5 U buddha :Gautama Siddhartha
 States: REGISTER(1+)
 Next State: -
 Comments: Indicates the client's claimed username and "GECOS"
-  information, along with client hostname and server name.  This
-  information is not reliable.  This message is enabled by requesting
-  the A policy.
+  information.  This information has not been checked against identd
+  or DNS.  This message is enabled by requesting the A policy.
 Compatibility: ircd only sends the <username> parameter.
 
 u - Client Username
diff --git a/ircd/s_auth.c b/ircd/s_auth.c
index b6a0fe5..665d9c5 100644
--- a/ircd/s_auth.c
+++ b/ircd/s_auth.c
@@ -73,6 +73,7 @@
 
 /** Pending operations during registration. */
 enum AuthRequestFlag {
+    AR_UNUSED,          /**< unused bit, see check_auth_finished() */
     AR_AUTH_PENDING,    /**< ident connecting or waiting for response */
     AR_DNS_PENDING,     /**< dns request sent, waiting for response */
     AR_CAP_PENDING,     /**< in middle of CAP negotiations */
@@ -248,7 +249,6 @@ static int auth_set_username(struct AuthRequest *auth)
   struct User   *user = cli_user(sptr);
   char *d;
   char *s;
-  int   killreason;
   short upper = 0;
   short lower = 0;
   short leadcaps = 0;
@@ -285,14 +285,6 @@ static int auth_set_username(struct AuthRequest *auth)
       || ((user->username[0] == '~') && (user->username[1] == '\0')))
     return exit_client(sptr, sptr, &me, "USER: Bogus userid.");
 
-  /* Check for K- or G-line. */
-  killreason = find_kill(sptr);
-  if (killreason) {
-    ServerStats->is_ref++;
-    return exit_client(sptr, sptr, &me,
-                       (killreason == -1 ? "K-lined" : "G-lined"));
-  }
-
   if (!FlagHas(&auth->flags, AR_IAUTH_FUSERNAME))
   {
     /* Check for mixed case usernames, meaning probably hacked.  Jon2 3-94
@@ -372,6 +364,50 @@ badid:
   return exit_client(sptr, sptr, &me, "USER: Bad username");
 }
 
+/** Notifies IAuth of a status change for the client.
+ *
+ * @param[in] auth Authorization request that was updated.
+ * @param[in] flag Which flag was updated.
+ */
+static void iauth_notify(struct AuthRequest *auth, enum AuthRequestFlag flag)
+{
+  struct Client *sptr = auth->client;
+
+  switch (flag)
+  {
+  case AR_AUTH_PENDING:
+    if (IAuthHas(iauth, IAUTH_UNDERNET))
+      sendto_iauth(sptr, "u %s", cli_username(sptr));
+    break;
+
+  case AR_DNS_PENDING:
+    if (cli_sockhost(auth->client)[0] == '\0')
+      sendto_iauth(sptr, "d");
+    else
+      sendto_iauth(sptr, "N %s", cli_sockhost(auth->client));
+    break;
+
+  case AR_NEEDS_USER:
+    if (IAuthHas(iauth, IAUTH_UNDERNET))
+      sendto_iauth(sptr, "U %s :%s", cli_user(sptr)->username, cli_info(sptr));
+    else if (IAuthHas(iauth, IAUTH_ADDLINFO))
+      sendto_iauth(sptr, "U %s", cli_user(sptr)->username);
+    break;
+
+  case AR_NEEDS_NICK:
+    if (IAuthHas(iauth, IAUTH_UNDERNET))
+      sendto_iauth(auth->client, "n %s", cli_name(sptr));
+    break;
+
+  case AR_IAUTH_PENDING:
+    sendto_iauth(sptr, "T");
+    break;
+
+  default:
+    break;
+  }
+}
+
 /** Check whether an authorization request is complete.
  * This means that no flags from 0 to #AR_LAST_SCAN are set on \a auth.
  * If #AR_IAUTH_PENDING is set, optionally go into "hurry" state.  If
@@ -379,21 +415,62 @@ badid:
  * destroy \a auth, clear the password, set the username, and register
  * the client.
  * @param[in] auth Authorization request to check.
+ * @param[in] bitclr A value from AuthRequestFlag, or a negative
+ *   version of such a value to indicate iauth as the source.
  * @return Zero if client is kept, CPTR_KILLED if client rejected.
  */
-static int check_auth_finished(struct AuthRequest *auth)
+static int check_auth_finished(struct AuthRequest *auth, int bitclr)
 {
   enum AuthRequestFlag flag;
+  int from_iauth;
+  int hurry_up;
   int res;
 
+  /* Handle \a bitclr. */
+  from_iauth = (bitclr < 0);
+  if (from_iauth)
+    bitclr = -bitclr;
+  if (bitclr != AR_IAUTH_SOFT_DONE)
+    FlagClr(&auth->flags, bitclr);
+
+  /* Should we set (or update) the client's username? */
+  if ((bitclr == AR_AUTH_PENDING) && IsUserPort(auth->client))
+  {
+    res = auth_set_username(auth);
+    if (res)
+      return res;
+  }
+
+  /* Did this affect username and/or hostname?
+   * If so, and we have both of those, we should look for a matching
+   * G-line or Kill block.
+   */
+  if (((bitclr == AR_AUTH_PENDING) || (bitclr == AR_DNS_PENDING))
+      && !FlagHas(&auth->flags, AR_AUTH_PENDING)
+      && !FlagHas(&auth->flags, AR_DNS_PENDING))
+  {
+    struct Client *sptr = auth->client;
+    int killreason = find_kill(sptr);
+    if (killreason)
+    {
+      ServerStats->is_ref++;
+      return exit_client(sptr, sptr, &me,
+                         (killreason == -1 ? "K-lined" : "G-lined"));
+    }
+  }
+
   /* Check non-iauth registration blocking flags. */
-  for (flag = 0; flag <= AR_LAST_SCAN; ++flag)
+  for (flag = 1; flag <= AR_LAST_SCAN; ++flag)
+  {
     if (FlagHas(&auth->flags, flag))
     {
       Debug((DEBUG_INFO, "Auth %p [%d] still has flag %d", auth,
              cli_fd(auth->client), flag));
+      if (!from_iauth)
+        iauth_notify(auth, (enum AuthRequestFlag)bitclr);
       return 0;
     }
+  }
 
   /* If appropriate, do preliminary assignment to connection class. */
   if (IsUserPort(auth->client)
@@ -423,6 +500,7 @@ static int check_auth_finished(struct AuthRequest *auth)
   }
 
   /* Check if iauth is done. */
+  hurry_up = 0;
   if (FlagHas(&auth->flags, AR_IAUTH_PENDING))
   {
     /* Switch auth request to hurry-up state. */
@@ -430,16 +508,16 @@ static int check_auth_finished(struct AuthRequest *auth)
     {
       /* Set "hurry" flag in auth request. */
       FlagSet(&auth->flags, AR_IAUTH_HURRY);
-
-      /* If iauth wants it, send notification. */
-      if (IAuthHas(iauth, IAUTH_UNDERNET))
-        sendto_iauth(auth->client, "H %s", get_client_class(auth->client));
+      hurry_up = 1;
 
       /* If iauth wants it, give client more time. */
       if (IAuthHas(iauth, IAUTH_EXTRAWAIT))
         cli_firsttime(auth->client) = CurrentTime;
     }
 
+    if (!from_iauth)
+      iauth_notify(auth, (enum AuthRequestFlag)bitclr);
+
     Debug((DEBUG_INFO, "Auth %p [%d] still has flag %d", auth,
            cli_fd(auth->client), AR_IAUTH_PENDING));
     return 0;
@@ -447,15 +525,18 @@ static int check_auth_finished(struct AuthRequest *auth)
   else
     FlagSet(&auth->flags, AR_IAUTH_HURRY);
 
+  res = 0;
   if (IsUserPort(auth->client))
   {
     memset(cli_passwd(auth->client), 0, sizeof(cli_passwd(auth->client)));
-    res = auth_set_username(auth);
-    if (res == 0)
-      res = register_user(auth->client, auth->client);
+    res = register_user(auth->client, auth->client);
+    /* Notify IAuth (if appropriate). */
+    if ((res == 0) && !from_iauth)
+      iauth_notify(auth, (enum AuthRequestFlag)bitclr);
+    /* Do we need to tell IAuth to hurry up? */
+    if ((res == 0) && hurry_up && IAuthHas(iauth, IAUTH_UNDERNET))
+      sendto_iauth(auth->client, "H %s", get_client_class(auth->client));
   }
-  else
-    res = 0;
   if (res == 0)
     destroy_auth_request(auth);
   return res;
@@ -577,8 +658,7 @@ static void send_auth_query(struct AuthRequest* auth)
     ++ServerStats->is_abad;
     if (IsUserPort(auth->client))
       sendheader(auth->client, REPORT_FAIL_ID);
-    FlagClr(&auth->flags, AR_AUTH_PENDING);
-    check_auth_finished(auth);
+    check_auth_finished(auth, AR_AUTH_PENDING);
   }
 }
 
@@ -697,8 +777,6 @@ static void read_auth_reply(struct AuthRequest* auth)
     if (IsUserPort(auth->client))
       sendheader(auth->client, REPORT_FAIL_ID);
     ++ServerStats->is_abad;
-    if (IAuthHas(iauth, IAUTH_UNDERNET))
-      sendto_iauth(auth->client, "u");
   } else {
     if (IsUserPort(auth->client))
       sendheader(auth->client, REPORT_FIN_ID);
@@ -707,12 +785,9 @@ static void read_auth_reply(struct AuthRequest* auth)
       ircd_strncpy(cli_username(auth->client), username, USERLEN);
       SetGotId(auth->client);
     }
-    if (IAuthHas(iauth, IAUTH_UNDERNET))
-      sendto_iauth(auth->client, "u %s", username);
   }
 
-  FlagClr(&auth->flags, AR_AUTH_PENDING);
-  check_auth_finished(auth);
+  check_auth_finished(auth, AR_AUTH_PENDING);
 }
 
 /** Handle socket I/O activity.
@@ -817,9 +892,7 @@ int auth_ping_timeout(struct Client *cptr)
       sendheader(cptr, REPORT_FAIL_IAUTH);
       return exit_client_msg(cptr, cptr, &me, "Authorization Timeout");
     }
-    sendto_iauth(cptr, "T");
-    FlagClr(&auth->flags, AR_IAUTH_PENDING);
-    return check_auth_finished(auth);
+    return check_auth_finished(auth, AR_IAUTH_PENDING);
   }
 
   assert(0 && "Unexpectedly reached end of auth_ping_timeout()");
@@ -840,27 +913,31 @@ static void auth_timeout_callback(struct Event* ev)
   auth = (struct AuthRequest*) t_data(ev_timer(ev));
 
   if (ev_type(ev) == ET_EXPIRE) {
+    int flag = 0;
+
     /* Report the timeout in the log. */
     log_write(LS_RESOLVER, L_INFO, 0, "Registration timeout %s",
               get_client_name(auth->client, HIDE_IP));
 
     /* Notify client if ident lookup failed. */
     if (FlagHas(&auth->flags, AR_AUTH_PENDING)) {
-      FlagClr(&auth->flags, AR_AUTH_PENDING);
+      flag = AR_AUTH_PENDING;
       if (IsUserPort(auth->client))
         sendheader(auth->client, REPORT_FAIL_ID);
     }
 
     /* Likewise if dns lookup failed. */
     if (FlagHas(&auth->flags, AR_DNS_PENDING)) {
-      FlagClr(&auth->flags, AR_DNS_PENDING);
+      if (flag != 0)
+        FlagClr(&auth->flags, flag);
+      flag = AR_DNS_PENDING;
       delete_resolver_queries(auth);
       if (IsUserPort(auth->client))
         sendheader(auth->client, REPORT_FAIL_DNS);
     }
 
     /* Try to register the client. */
-    check_auth_finished(auth);
+    check_auth_finished(auth, flag);
   }
 }
 
@@ -876,12 +953,10 @@ static void auth_dns_callback(void* vptr, const struct 
irc_in_addr *addr, const
   struct AuthRequest* auth = (struct AuthRequest*) vptr;
   assert(0 != auth);
 
-  FlagClr(&auth->flags, AR_DNS_PENDING);
   if (!addr) {
     /* DNS entry was missing for the IP. */
     if (IsUserPort(auth->client))
       sendheader(auth->client, REPORT_FAIL_DNS);
-    sendto_iauth(auth->client, "d");
   } else if (!irc_in_addr_valid(addr)
              || (irc_in_addr_cmp(&cli_ip(auth->client), addr)
                  && irc_in_addr_cmp(&auth->original, addr))) {
@@ -899,15 +974,13 @@ static void auth_dns_callback(void* vptr, const struct 
irc_in_addr *addr, const
     /* Hostname did not look valid. */
     if (IsUserPort(auth->client))
       sendheader(auth->client, REPORT_INVAL_DNS);
-    sendto_iauth(auth->client, "d");
   } else {
     /* Hostname and mappings checked out. */
     if (IsUserPort(auth->client))
       sendheader(auth->client, REPORT_FIN_DNS);
     ircd_strncpy(cli_sockhost(auth->client), h_name, HOSTLEN);
-    sendto_iauth(auth->client, "N %s", h_name);
   }
-  check_auth_finished(auth);
+  check_auth_finished(auth, AR_DNS_PENDING);
 }
 
 /** Flag the client to show an attempt to contact the ident server on
@@ -1067,7 +1140,7 @@ void start_auth(struct Client* client)
   add_client_to_list(client);
 
   /* Check which auth events remain pending. */
-  check_auth_finished(auth);
+  check_auth_finished(auth, 0);
 }
 
 /** Mark that a user has PONGed while unregistered.
@@ -1087,8 +1160,7 @@ int auth_set_pong(struct AuthRequest *auth, unsigned int 
cookie)
     return 0;
   }
   cli_lasttime(auth->client) = CurrentTime;
-  FlagClr(&auth->flags, AR_NEEDS_PONG);
-  return check_auth_finished(auth);
+  return check_auth_finished(auth, AR_NEEDS_PONG);
 }
 
 /** Record a user's claimed username and userinfo.
@@ -1108,16 +1180,11 @@ int auth_set_user(struct AuthRequest *auth, const char 
*username, const char *ho
   assert(auth != NULL);
   if (FlagHas(&auth->flags, AR_IAUTH_HURRY))
     return 0;
-  FlagClr(&auth->flags, AR_NEEDS_USER);
   cptr = auth->client;
   ircd_strncpy(cli_info(cptr), userinfo, REALLEN);
   clean_username(cli_user(cptr)->username, username);
   ircd_strncpy(cli_user(cptr)->host, cli_sockhost(cptr), HOSTLEN);
-  if (IAuthHas(iauth, IAUTH_UNDERNET))
-    sendto_iauth(cptr, "U %s %s %s :%s", cli_user(cptr)->username, hostname, 
servername, userinfo);
-  else if (IAuthHas(iauth, IAUTH_ADDLINFO))
-    sendto_iauth(cptr, "U %s", username);
-  return check_auth_finished(auth);
+  return check_auth_finished(auth, AR_NEEDS_USER);
 }
 
 /** Handle authorization-related aspects of initial nickname selection.
@@ -1129,7 +1196,6 @@ int auth_set_user(struct AuthRequest *auth, const char 
*username, const char *ho
 int auth_set_nick(struct AuthRequest *auth, const char *nickname)
 {
   assert(auth != NULL);
-  FlagClr(&auth->flags, AR_NEEDS_NICK);
   /*
    * If the client hasn't gotten a cookie-ping yet,
    * choose a cookie and send it. -record!jegel...@cloud9.net
@@ -1141,9 +1207,7 @@ int auth_set_nick(struct AuthRequest *auth, const char 
*nickname)
     sendrawto_one(auth->client, "PING :%u", auth->cookie);
     FlagSet(&auth->flags, AR_NEEDS_PONG);
   }
-  if (IAuthHas(iauth, IAUTH_UNDERNET))
-    sendto_iauth(auth->client, "n %s", nickname);
-  return check_auth_finished(auth);
+  return check_auth_finished(auth, AR_NEEDS_NICK);
 }
 
 /** Record a user's password.
@@ -1198,8 +1262,7 @@ int auth_cap_start(struct AuthRequest *auth)
 int auth_cap_done(struct AuthRequest *auth)
 {
   assert(auth != NULL);
-  FlagClr(&auth->flags, AR_CAP_PENDING);
-  return check_auth_finished(auth);
+  return check_auth_finished(auth, AR_CAP_PENDING);
 }
 
 /** Set a client's username, hostname and IP with minimal checking.
@@ -1246,7 +1309,7 @@ int auth_spoof_user(struct AuthRequest *auth, const char 
*username, const char *
   if (IAuthHas(iauth, IAUTH_UNDERNET))
     sendto_iauth(sptr, "u %s", cli_username(sptr));
 
-  return check_auth_finished(auth);
+  return check_auth_finished(auth, 0);
 }
 
 /** Attempt to spawn the process for an IAuth instance.
@@ -1770,20 +1833,19 @@ static int iauth_cmd_stats(struct IAuth *iauth, struct 
Client *cli,
  * @param[in] cli Client referenced by command.
  * @param[in] parc Number of parameters (1).
  * @param[in] params Forced username.
- * @return One.
+ * @return \a AR_AUTH_PENDING.
  */
 static int iauth_cmd_username_forced(struct IAuth *iauth, struct Client *cli,
                                     int parc, char **params)
 {
   assert(cli_auth(cli) != NULL);
-  FlagClr(&cli_auth(cli)->flags, AR_AUTH_PENDING);
   if (!EmptyString(params[0])) {
     ircd_strncpy(cli_username(cli), params[0], USERLEN);
     SetGotId(cli);
     FlagSet(&cli_auth(cli)->flags, AR_IAUTH_USERNAME);
     FlagSet(&cli_auth(cli)->flags, AR_IAUTH_FUSERNAME);
   }
-  return 1;
+  return AR_AUTH_PENDING;
 }
 
 /** Set client's username to a trusted string.
@@ -1791,19 +1853,18 @@ static int iauth_cmd_username_forced(struct IAuth 
*iauth, struct Client *cli,
  * @param[in] cli Client referenced by command.
  * @param[in] parc Number of parameters (1).
  * @param[in] params Trusted username.
- * @return One.
+ * @return \a AR_AUTH_PENDING.
  */
 static int iauth_cmd_username_good(struct IAuth *iauth, struct Client *cli,
                                   int parc, char **params)
 {
   assert(cli_auth(cli) != NULL);
-  FlagClr(&cli_auth(cli)->flags, AR_AUTH_PENDING);
   if (!EmptyString(params[0])) {
     ircd_strncpy(cli_username(cli), params[0], USERLEN);
     SetGotId(cli);
     FlagSet(&cli_auth(cli)->flags, AR_IAUTH_USERNAME);
   }
-  return 1;
+  return AR_AUTH_PENDING;
 }
 
 /** Set client's username to an untrusted string.
@@ -1811,16 +1872,14 @@ static int iauth_cmd_username_good(struct IAuth *iauth, 
struct Client *cli,
  * @param[in] cli Client referenced by command.
  * @param[in] parc Number of parameters (1).
  * @param[in] params Untrusted username.
- * @return One.
+ * @return \a AR_AUTH_PENDING.
  */
 static int iauth_cmd_username_bad(struct IAuth *iauth, struct Client *cli,
                                  int parc, char **params)
 {
-  assert(cli_auth(cli) != NULL);
-  FlagClr(&cli_auth(cli)->flags, AR_AUTH_PENDING);
   if (!EmptyString(params[0]))
     ircd_strncpy(cli_user(cli)->username, params[0], USERLEN);
-  return 1;
+  return AR_AUTH_PENDING;
 }
 
 /** Set client's hostname.
@@ -1828,7 +1887,8 @@ static int iauth_cmd_username_bad(struct IAuth *iauth, 
struct Client *cli,
  * @param[in] cli Client referenced by command.
  * @param[in] parc Number of parameters (1).
  * @param[in] params New hostname for client.
- * @return Non-zero if \a cli authorization should be checked for completion.
+ * @return \a AR_DNS_PENDING if \a cli authorization should be checked
+ *   for completion, else zero.
  */
 static int iauth_cmd_hostname(struct IAuth *iauth, struct Client *cli,
                              int parc, char **params)
@@ -1845,7 +1905,6 @@ static int iauth_cmd_hostname(struct IAuth *iauth, struct 
Client *cli,
 
   /* If a DNS request is pending, abort it. */
   if (FlagHas(&auth->flags, AR_DNS_PENDING)) {
-    FlagClr(&auth->flags, AR_DNS_PENDING);
     delete_resolver_queries(auth);
     if (IsUserPort(cli))
       sendheader(cli, REPORT_FIN_DNS);
@@ -1860,7 +1919,7 @@ static int iauth_cmd_hostname(struct IAuth *iauth, struct 
Client *cli,
     ircd_strncpy(cli_user(cli)->host, cli_sockhost(cli), HOSTLEN);
     ircd_strncpy(cli_user(cli)->realhost, cli_sockhost(cli), HOSTLEN);
   }
-  return 1;
+  return AR_DNS_PENDING;
 }
 
 /** Set client's IP address.
@@ -1869,7 +1928,7 @@ static int iauth_cmd_hostname(struct IAuth *iauth, struct 
Client *cli,
  * @param[in] parc Number of parameters (1).
  * @param[in] params New IP address for client in dotted quad or
  *   standard IPv6 format.
- * @return Zero.
+ * @return Zero or \a AR_DNS_PENDING.
  */
 static int iauth_cmd_ip_address(struct IAuth *iauth, struct Client *cli,
                                int parc, char **params)
@@ -1906,7 +1965,8 @@ static int iauth_cmd_ip_address(struct IAuth *iauth, 
struct Client *cli,
   memcpy(&cli_ip(cli), &addr, sizeof(cli_ip(cli)));
   IPcheck_remote_connect(cli, 0);
 
-  return 0;
+  /* Treat as a DNS update to trigger G-line/Kill checks. */
+  return AR_DNS_PENDING;
 }
 
 /** Find a ConfItem structure for a named connection class.
@@ -1958,7 +2018,7 @@ static struct ConfItem *auth_find_class_conf(const char 
*class_name)
  * @param[in] cli Client referenced by command.
  * @param[in] parc Number of parameters.
  * @param[in] params Optional class name for client.
- * @return Negative (CPTR_KILLED) if the connection is refused, one otherwise.
+ * @return \a AR_IAUTH_SOFT_DONE.
  */
 static int iauth_cmd_soft_done(struct IAuth *iauth, struct Client *cli,
                               int parc, char **params)
@@ -1966,7 +2026,7 @@ static int iauth_cmd_soft_done(struct IAuth *iauth, 
struct Client *cli,
   /* Clear iauth pending flag. */
   assert(cli_auth(cli) != NULL);
   FlagSet(&cli_auth(cli)->flags, AR_IAUTH_SOFT_DONE);
-  return 1;
+  return AR_IAUTH_SOFT_DONE;
 }
 
 /** Accept a client in IAuth.
@@ -1974,17 +2034,14 @@ static int iauth_cmd_soft_done(struct IAuth *iauth, 
struct Client *cli,
  * @param[in] cli Client referenced by command.
  * @param[in] parc Number of parameters.
  * @param[in] params Optional class name for client.
- * @return Negative (CPTR_KILLED) if the connection is refused, one otherwise.
+ * @return Negative (CPTR_KILLED) if the connection is refused, \a
+ *   AR_IAUTH_PENDING otherwise.
  */
 static int iauth_cmd_done_client(struct IAuth *iauth, struct Client *cli,
                                 int parc, char **params)
 {
   static time_t warn_time;
 
-  /* Clear iauth pending flag. */
-  assert(cli_auth(cli) != NULL);
-  FlagClr(&cli_auth(cli)->flags, AR_IAUTH_PENDING);
-
   /* If a connection class was specified (and usable), assign the client to 
it. */
   if (!EmptyString(params[0])) {
     struct ConfItem *aconf;
@@ -2013,7 +2070,7 @@ static int iauth_cmd_done_client(struct IAuth *iauth, 
struct Client *cli,
                                        params[0]);
   }
 
-  return 1;
+  return AR_IAUTH_PENDING;
 }
 
 /** Accept a client in IAuth and assign them to an account.
@@ -2021,8 +2078,9 @@ static int iauth_cmd_done_client(struct IAuth *iauth, 
struct Client *cli,
  * @param[in] cli Client referenced by command.
  * @param[in] parc Number of parameters.
  * @param[in] params Account name and optional class name for client.
- * @return Negative if the connection is refused, otherwise non-zero
- *   if \a cli authorization should be checked for completion.
+ * @return Negative if the connection is refused, otherwise \a
+ *   AR_IAUTH_PENDING if \a cli authorization should be checked for
+ *   completion.
  */
 static int iauth_cmd_done_account(struct IAuth *iauth, struct Client *cli,
                                  int parc, char **params)
@@ -2256,9 +2314,13 @@ static void iauth_parse(struct IAuth *iauth, char 
*message)
        /* Report mismatch to iauth. */
        sendto_iauth(cli, "E Mismatch :[%s] != [%s]", params[1],
                     ircd_ntoa(&cli_ip(cli)));
-      else if (handler(iauth, cli, parc - 3, params + 3) > 0)
-       /* Handler indicated a possible state change. */
-       check_auth_finished(auth);
+      else
+      {
+        /* Does handler indicate a possible state change? */
+        int bitclr = handler(iauth, cli, parc - 3, params + 3);
+        if (bitclr > 0)
+          check_auth_finished(auth, -bitclr);
+      }
     }
   }
 }
commit 3c2a199f6f1b73192638969eb414b0a3972f6f28
Author: Michael Poole <mdpo...@troilus.org>
Date:   Sat Oct 8 21:08:24 2016 -0400

    tests/test-driver.pl: Allow specification of outbound IP address.

diff --git a/tests/readme.txt b/tests/readme.txt
index 98466d1..b615014 100644
--- a/tests/readme.txt
+++ b/tests/readme.txt
@@ -14,7 +14,7 @@ The test-driver.pl script accepts several command-line 
options:
 
  -D enables POE::Component::IRC debugging output
  -V enables test-driver.pl debugging output
- -Hipaddr sets the IPv4 address to use for connections to the server
+ -Hipaddr sets the default IPv4 address for clients to connect from
  one or more script names to interpret and execute
 
 The normal output is one dot for each line that is executed.  Using
@@ -34,10 +34,11 @@ abort.
 
 Following the variable definitions is usually one or more "connect"
 statements.  These have the syntax:
-       connect <tag> <nickname> <username> <server:port> :<Real Name or GECOS>
+       connect <tag[:ip[:port]]> <nickname> <username> <server:port> :<Real 
Name or GECOS>
 This creates a client and starts a connection to an IRC server.  The
-tag is used to issue commands for that client in the rest of the file.
-The remaining fields have their usual meanings for IRC.
+tag is used to issue commands for that client in the rest of the file,
+and may be followed by a colon, an IP address, and an optional colon and
+port number.  The remaining fields have their usual meanings for IRC.
 
 A number of IRC commands are supported natively, including:
        :<tag> join <channel>
diff --git a/tests/test-driver.pl b/tests/test-driver.pl
index 8ba77a2..855adb1 100755
--- a/tests/test-driver.pl
+++ b/tests/test-driver.pl
@@ -163,8 +163,7 @@ sub drv_heartbeat {
     next if $line =~ /^\#/ or $line !~ /\S/;
 
     # expand any macros in the line
-    $line =~ s/(?<=[^\\])%(\S+?)%/$heap->{macros}->{$1}
-      or die "Use of undefined macro $1 at line $heap->{lineno}\n"/eg;
+    $line =~ s/(?:<=[^\\])%(\S+?)%/$heap->{macros}->{$1} or die "Use of 
undefined macro $1 at line $heap->{lineno}\n"/eg;
     # remove any \-escapes
     $line =~ s/\\(.)/$1/g;
     # figure out the type of line
@@ -178,7 +177,7 @@ sub drv_heartbeat {
       # connect a new session (named $1) to server $4
       my ($name, $nick, $ident, $server, $userinfo, $port) = ($1, $2, $3, $4, 
$5, 6667);
       $server = $heap->{servers}->{$server} || $server;
-      if ($server =~ /(.+):(\d+)/) {
+      if ($server =~ /(.+)(?::(\d+))?/) {
         $server = $1;
         $port = $2;
       }
@@ -192,14 +191,34 @@ sub drv_heartbeat {
                     expect_alarms => [],
                     params => { Nick     => $nick,
                                 Server   => $server,
-                                Port     => $port,
                                 Username => $ident,
                                 Ircname  => $userinfo,
                                 Debug    => $heap->{irc_debug},
                               }
                    };
+      $client->{params}->{Port} = $port
+        if $port;
       $client->{params}->{LocalAddr} = $heap->{local_address}
         if $heap->{local_address};
+      if ($name =~ /^([^:]+):(.+)$/) {
+        my $host = $2;
+        my $c_port;
+        $client->{name} = $name = $1;
+        if ($host =~ /^\[(.+)](?::(\d+))?$/) {
+          # [a:b::d]:e, IPv6-compatible host+port syntax
+          $c_port = $2;
+          $host = $1;
+        } elsif ($host =~ /^((?:\d+\.)+\d+):(\d+)$/) {
+          # IPv4 syntax
+          $c_port = $2;
+          $host = $1;
+        } elsif ($host =~ /:/) {
+          print "WARNING: connect using host '$host' looks ambiguous"
+        } # else assume it's a bare IP address
+        $client->{params}->{LocalAddr} = $host;
+        $client->{params}->{LocalPort} = $c_port
+          if defined $c_port;
+      }
       my $irc = POE::Component::IRC->spawn
         (
          alias => $alias,
commit 25c0fe836e5478b6ab1d7371ff100d769e5b5526
Author: Michael Poole <mdpo...@troilus.org>
Date:   Thu Sep 1 15:00:49 2016 -0400

    Reject invalid channel names in BURST and CREATE.

diff --git a/ircd/m_burst.c b/ircd/m_burst.c
index 00e4265..7e97104 100644
--- a/ircd/m_burst.c
+++ b/ircd/m_burst.c
@@ -215,6 +215,9 @@ int ms_burst(struct Client *cptr, struct Client *sptr, int 
parc, char *parv[])
 
   if (parc < 3)
     return protocol_violation(sptr,"Too few parameters for BURST");
+  
+  if (!IsChannelName(parv[1]))
+    return protocol_violation(sptr, "Invalid channel name in BURST");
 
   if (!(chptr = get_channel(sptr, parv[1], CGT_CREATE)))
     return 0; /* can't create the channel? */
diff --git a/ircd/m_create.c b/ircd/m_create.c
index df2085e..3a74224 100644
--- a/ircd/m_create.c
+++ b/ircd/m_create.c
@@ -155,6 +155,11 @@ int ms_create(struct Client* cptr, struct Client* sptr, 
int parc, char* parv[])
 
     if (IsLocalChannel(name))
       continue;
+    
+    if (!IsChannelName(name)) {
+      protocol_violation(sptr, "%s tried to CREATE a non-channel (%s)", 
cli_name(sptr), name);
+      continue;
+    }
 
     if ((chptr = FindChannel(name)))
     {
commit 57384c2a60e96454ed79169a3083da0457a9ba6b
Author: Michael Poole <mdpo...@troilus.org>
Date:   Tue Aug 23 23:17:13 2016 -0400

    channel.h: Remove trailing whitespace, fix a typo.

diff --git a/include/channel.h b/include/channel.h
index 57ed5dc..cddaf8f 100644
--- a/include/channel.h
+++ b/include/channel.h
@@ -66,19 +66,19 @@ struct Client;
 #define CHFL_BANVALID           0x0800  /**< CHFL_BANNED bit is valid */
 #define CHFL_BANNED             0x1000  /**< Channel member is banned */
 #define CHFL_SILENCE_IPMASK     0x2000  /**< silence mask is a CIDR */
-#define CHFL_BURST_ALREADY_OPPED       0x04000  
-                                       /**< In oob BURST, but was already 
-                                        * joined and opped 
+#define CHFL_BURST_ALREADY_OPPED       0x04000
+                                       /**< In oob BURST, but was already
+                                        * joined and opped
                                         */
-#define CHFL_BURST_ALREADY_VOICED      0x08000  
-                                       /**, In oob BURST, but was already 
-                                        * joined and voiced 
+#define CHFL_BURST_ALREADY_VOICED      0x08000
+                                       /**< In oob BURST, but was already
+                                        * joined and voiced
                                         */
-#define CHFL_CHANNEL_MANAGER   0x10000 /**< Set when creating channel or using 
-                                        * Apass 
+#define CHFL_CHANNEL_MANAGER   0x10000 /**< Set when creating channel or using
+                                        * Apass
                                         */
-#define CHFL_USER_PARTING       0x20000 /**< User is already parting that 
-                                        * channel 
+#define CHFL_USER_PARTING       0x20000 /**< User is already parting that
+                                        * channel
                                         */
 #define CHFL_DELAYED            0x40000 /**< User's join message is delayed */
 
@@ -103,14 +103,14 @@ struct Client;
 #define MODE_DELJOINS   0x1000         /**< New join messages are delayed */
 #define MODE_REGISTERED 0x2000         /**< Channel marked as registered
                                         * (for future semantic expansion) */
-#define MODE_SAVE      0x20000         /**< save this mode-with-arg 'til 
+#define MODE_SAVE      0x20000         /**< save this mode-with-arg 'til
                                         * later */
-#define MODE_FREE      0x40000         /**< string needs to be passed to 
+#define MODE_FREE      0x40000         /**< string needs to be passed to
                                         * MyFree() */
 #define MODE_BURSTADDED        0x80000         /**< channel was created by a 
BURST */
 #define MODE_UPASS     0x100000
 #define MODE_APASS     0x200000
-#define MODE_WASDELJOINS 0x400000      /**< Not DELJOINS, but some joins 
+#define MODE_WASDELJOINS 0x400000      /**< Not DELJOINS, but some joins
                                         * pending */
 /** mode flags which take another parameter (With PARAmeterS)
  */
commit 0c3d0f6f9eb138bdb7229045e02391207aa23e33
Author: Michael Poole <mdpo...@troilus.org>
Date:   Mon Aug 22 21:08:05 2016 -0400

    engine_epoll.c: Remove the syscall guessing code.
    
    All actively maintained distros (and many older ones) define this now.
    Not all distros have <linux/unistd.h>, which we used for _syscall4().

diff --git a/ircd/engine_epoll.c b/ircd/engine_epoll.c
index a9be737..73fbf03 100644
--- a/ircd/engine_epoll.c
+++ b/ircd/engine_epoll.c
@@ -32,68 +32,10 @@
 /* #include <assert.h> -- Now using assert in ircd_log.h */
 #include <errno.h>
 #include <sys/types.h>
-#ifdef HAVE_STDINT_H
-#include <stdint.h> /* bah */
-#endif
 #include <string.h>
 #include <sys/epoll.h>
 #include <sys/socket.h>
 #include <time.h>
-#include <linux/unistd.h>
-
-/* The GNU C library may have a valid header but stub implementations
- * of the epoll system calls.  If so, provide our own. */
-#if defined(__stub_epoll_create) || defined(__stub___epoll_create) || 
defined(EPOLL_NEED_BODY)
-
-/* Oh, did we mention that some glibc releases do not even define the
- * syscall numbers? */
-#if !defined(__NR_epoll_create)
-#if defined(__ia64__)
-#define __NR_epoll_create 1243
-#define __NR_epoll_ctl 1244
-#define __NR_epoll_wait 1245
-#elif defined(__x86_64__)
-#define __NR_epoll_create 214
-#define __NR_epoll_ctl 233
-#define __NR_epoll_wait 232
-#elif defined(__sparc64__) || defined(__sparc__)
-#define __NR_epoll_create 193
-#define __NR_epoll_ctl 194
-#define __NR_epoll_wait 195
-#elif defined(__s390__) || defined(__m68k__)
-#define __NR_epoll_create 249
-#define __NR_epoll_ctl 250
-#define __NR_epoll_wait 251
-#elif defined(__ppc64__) || defined(__ppc__)
-#define __NR_epoll_create 236
-#define __NR_epoll_ctl 237
-#define __NR_epoll_wait 238
-#elif defined(__parisc__) || defined(__arm26__) || defined(__arm__)
-#define __NR_epoll_create 224
-#define __NR_epoll_ctl 225
-#define __NR_epoll_wait 226
-#elif defined(__alpha__)
-#define __NR_epoll_create 407
-#define __NR_epoll_ctl 408
-#define __NR_epoll_wait 409
-#elif defined(__sh64__)
-#define __NR_epoll_create 282
-#define __NR_epoll_ctl 283
-#define __NR_epoll_wait 284
-#elif defined(__i386__) || defined(__sh__) || defined(__m32r__) || 
defined(__h8300__) || defined(__frv__)
-#define __NR_epoll_create 254
-#define __NR_epoll_ctl 255
-#define __NR_epoll_wait 256
-#else /* cpu types */
-#error No system call numbers defined for epoll family.
-#endif /* cpu types */
-#endif /* !defined(__NR_epoll_create) */
-
-_syscall1(int, epoll_create, int, size)
-_syscall4(int, epoll_ctl, int, epfd, int, op, int, fd, struct epoll_event *, 
event)
-_syscall4(int, epoll_wait, int, epfd, struct epoll_event *, pevents, int, 
maxevents, int, timeout)
-
-#endif /* epoll_create defined as stub */
 
 #define EPOLL_ERROR_THRESHOLD 20   /**< after 20 epoll errors, restart */
 #define ERROR_EXPIRE_TIME     3600 /**< expire errors after an hour */
commit 6343d2da49f18acedee9098ea0478933db4c77dd
Author: Michael Poole <mdpo...@troilus.org>
Date:   Mon Aug 22 21:06:37 2016 -0400

    engine_poll.c: Fix path for #include <poll.h>.
    
    <sys/poll.h> was from before POSIX.

diff --git a/ircd/engine_poll.c b/ircd/engine_poll.c
index e0c4bf4..83e0767 100644
--- a/ircd/engine_poll.c
+++ b/ircd/engine_poll.c
@@ -31,7 +31,7 @@
 
 /* #include <assert.h> -- Now using assert in ircd_log.h */
 #include <errno.h>
-#include <sys/poll.h>
+#include <poll.h>
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <time.h>
commit 199064aebd873818ba4ea41822ae0b82218034b1
Author: Michael Poole <mdpo...@troilus.org>
Date:   Wed Jul 27 22:12:24 2016 -0400

    Avoid calling os_get_sockerr(-1) for failed outbound connects.
    
    In this case, cli_fd(cptr) == -1, but cli_error(cptr) is set by
    client_sock_callback().

diff --git a/ircd/s_bsd.c b/ircd/s_bsd.c
index 283215c..185ca4f 100644
--- a/ircd/s_bsd.c
+++ b/ircd/s_bsd.c
@@ -315,7 +315,9 @@ static int completed_connection(struct Client* cptr)
    * get the socket status from the fd first to check if
    * connection actually succeeded
    */
-  if ((cli_error(cptr) = os_get_sockerr(cli_fd(cptr)))) {
+  if (cli_fd(cptr) >= 0)
+      cli_error(cptr) = os_get_sockerr(cli_fd(cptr));
+  if (cli_error(cptr) != 0) {
     const char* msg = strerror(cli_error(cptr));
     if (!msg)
       msg = "Unknown error";
-----------------------------------------------------------------------

Summary of changes:
 doc/example.conf     |    4 +
 doc/readme.iauth     |    9 +-
 include/channel.h    |   26 +++---
 include/client.h     |    3 +-
 include/s_conf.h     |    2 +
 ircd/client.c        |   36 +++++---
 ircd/engine_epoll.c  |   58 -------------
 ircd/engine_poll.c   |    2 +-
 ircd/ircd_parser.y   |    8 ++-
 ircd/m_burst.c       |    3 +
 ircd/m_create.c      |    5 +
 ircd/m_oper.c        |    2 +-
 ircd/m_opmode.c      |   67 +++++++++++++++-
 ircd/s_auth.c        |  228 ++++++++++++++++++++++++++++++++------------------
 ircd/s_bsd.c         |    4 +-
 ircd/s_user.c        |   15 ++--
 tests/readme.txt     |    9 +-
 tests/test-driver.pl |   27 +++++-
 18 files changed, 315 insertions(+), 193 deletions(-)


hooks/post-receive
-- 
Undernet IRC Server Source Code.
_______________________________________________
Patches mailing list
Patches@undernet.org
http://undernet.sbg.org/mailman/listinfo/patches

Reply via email to