Forward port missing fixes from Kev, beware and someone else.
[ircu2.10.12-pk.git] / ircd / s_user.c
index 8986e108c640a23ccfd9a56827ee5dbcb22d0f70..4082ea39c49ac11b31e6627f2b310b61c3cf1464 100644 (file)
@@ -348,7 +348,7 @@ int register_user(struct Client *cptr, struct Client *sptr,
                   const char *nick, char *username)
 {
   struct ConfItem* aconf;
-  char*            parv[3];
+  char*            parv[4];
   char*            tmpstr;
   char*            tmpstr2;
   char             c = 0;    /* not alphanum */
@@ -362,7 +362,7 @@ int register_user(struct Client *cptr, struct Client *sptr,
   short            badid = 0;
   short            digitgroups = 0;
   struct User*     user = cli_user(sptr);
-  struct Flags flag;
+  int              killreason;
   char             ip_base64[8];
 
   user->last = CurrentTime;
@@ -433,7 +433,6 @@ int register_user(struct Client *cptr, struct Client *sptr,
         && strcmp(cli_passwd(sptr), aconf->passwd))
     {
       ServerStats->is_ref++;
-      IPcheck_connect_fail(cli_ip(sptr));
       send_reply(sptr, ERR_PASSWDMISMATCH);
       return exit_client(cptr, sptr, &me, "Bad Password");
     }
@@ -441,10 +440,11 @@ int register_user(struct Client *cptr, struct Client *sptr,
     /*
      * following block for the benefit of time-dependent K:-lines
      */
-    if (find_kill(sptr)) {
+    killreason = find_kill(sptr);
+    if (killreason) {
       ServerStats->is_ref++;
-      IPcheck_connect_fail(cli_ip(sptr));
-      return exit_client(cptr, sptr, &me, "K-lined");
+      return exit_client(cptr, sptr, &me,
+                         (killreason == -1 ? "K-lined" : "G-lined"));
     }
     /*
      * Check for mixed case usernames, meaning probably hacked.  Jon2 3-94
@@ -540,9 +540,10 @@ int register_user(struct Client *cptr, struct Client *sptr,
   if (MyConnect(sptr)) {
     cli_handler(sptr) = CLIENT_HANDLER;
     release_dns_reply(sptr);
-
+    SetLocalNumNick(sptr);
     send_reply(sptr,
                RPL_WELCOME,
+               feature_str(FEAT_NETWORK),
                feature_str(FEAT_PROVIDER) ? " via " : "",
                feature_str(FEAT_PROVIDER) ? feature_str(FEAT_PROVIDER) : "",
                nick);
@@ -562,11 +563,21 @@ int register_user(struct Client *cptr, struct Client *sptr,
       set_snomask(sptr, cli_snomask(sptr) & SNO_NOISY, SNO_ADD);
     if (feature_bool(FEAT_CONNEXIT_NOTICES))
       sendto_opmask_butone(0, SNO_CONNEXIT,
-                           "Client connecting: %s (%s@%s) [%s] {%d}",
+                           "Client connecting: %s (%s@%s) [%s] {%d} [%s] <%s%s>",
                            cli_name(sptr), user->username, user->host,
-                           cli_sock_ip(sptr), get_client_class(sptr));
+                           cli_sock_ip(sptr), get_client_class(sptr),
+                           cli_info(sptr), NumNick(cptr) /* two %s's */);
 
     IPcheck_connect_succeeded(sptr);
+    /*
+     * Set user's initial modes
+     */
+    parv[0] = (char*)nick;
+    parv[1] = (char*)nick;
+    parv[2] = (char*)client_get_default_umode(sptr);
+    parv[3] = NULL; /* needed in case of +s */
+    set_user_mode(sptr, sptr, 3, parv);
+    ClearHiddenHost(sptr); /* just in case somebody stuck +x in there */
   }
   else
     /* if (IsServer(cptr)) */
@@ -615,14 +626,9 @@ int register_user(struct Client *cptr, struct Client *sptr,
                        inttobase64(ip_base64, ntohl(cli_ip(sptr).s_addr), 6),
                        NumNick(sptr), cli_info(sptr));
   
-  /* Send umode to client */
-  if (MyUser(sptr))
-  {
-    memset(&flag, 0, sizeof(flag));
-    send_umode(cptr, sptr, &flag, ALL_UMODES);
-    if (cli_snomask(sptr) != SNO_DEFAULT && HasFlag(sptr, FLAG_SERVNOTICE))
-      send_reply(sptr, RPL_SNOMASK, cli_snomask(sptr), cli_snomask(sptr));
-  }
+  /* Send server notice mask to client */
+  if (MyUser(sptr) && (cli_snomask(sptr) != SNO_DEFAULT) && HasFlag(sptr, FLAG_SERVNOTICE))
+    send_reply(sptr, RPL_SNOMASK, cli_snomask(sptr), cli_snomask(sptr));
 
   return 0;
 }
@@ -704,8 +710,17 @@ int set_nick_name(struct Client* cptr, struct Client* sptr,
     ircd_strncpy(cli_user(new_client)->host, parv[5], HOSTLEN);
     ircd_strncpy(cli_user(new_client)->realhost, parv[5], HOSTLEN);
     ircd_strncpy(cli_info(new_client), parv[parc - 1], REALLEN);
-    if (account)
-      ircd_strncpy(cli_user(new_client)->account, account, ACCOUNTLEN);
+    if (account) {
+      int len = ACCOUNTLEN;
+      if ((p = strchr(account, ':'))) {
+       len = (p++) - account;
+       cli_user(new_client)->acc_create = atoi(p);
+       Debug((DEBUG_DEBUG, "Received timestamped account in user mode; "
+              "account \"%s\", timestamp %Tu", account,
+              cli_user(new_client)->acc_create));
+      }
+      ircd_strncpy(cli_user(new_client)->account, account, len);
+    }
     if (HasHiddenHost(new_client))
       ircd_snprintf(0, cli_user(new_client)->host, HOSTLEN, "%s.%s",
         account, feature_str(FEAT_HIDDEN_HOST));
@@ -789,7 +804,6 @@ int set_nick_name(struct Client* cptr, struct Client* sptr,
       cli_user(sptr) = make_user(sptr);
       cli_user(sptr)->server = &me;
     }
-    SetLocalNumNick(sptr);
     hAddClient(sptr);
 
     /*
@@ -841,8 +855,6 @@ add_target(struct Client *sptr, void *target)
 
   targets = cli_targets(sptr);
 
-  if (IsChannelName(cli_name(sptr)) && IsInvited(sptr, target))
-    return;
   /* 
    * Already in table?
    */
@@ -877,6 +889,10 @@ int check_target_limit(struct Client *sptr, void *target, const char *name,
   assert(cli_local(sptr));
   targets = cli_targets(sptr);
 
+  /* If user is invited to channel, give him/her a free target */
+  if (IsChannelName(name) && IsInvited(sptr, target))
+    return 0;
+
   /*
    * Same target as last time?
    */
@@ -1082,20 +1098,22 @@ hide_hostmask(struct Client *cptr, unsigned int flag)
    */
   for (chan = cli_user(cptr)->channel; chan; chan = chan->next_channel)
   {
+    if (IsZombie(chan))
+      continue;
     /* For a user with no modes in a join-delayed channel, do not show
      * the rejoin. */
     if (!IsChanOp(chan) && !HasVoice(chan)
         && (chan->channel->mode.mode & MODE_DELJOINS))
       SetDelayedJoin(chan);
     else
-      sendcmdto_channel_butserv_butone(cptr, CMD_JOIN, chan->channel, cptr,
+      sendcmdto_channel_butserv_butone(cptr, CMD_JOIN, chan->channel, cptr, 0,
                                          "%H", chan->channel);
     if (IsChanOp(chan) && HasVoice(chan))
-      sendcmdto_channel_butserv_butone(&me, CMD_MODE, chan->channel, cptr,
+      sendcmdto_channel_butserv_butone(&me, CMD_MODE, chan->channel, cptr, 0,
                                        "%H +ov %C %C", chan->channel, cptr,
                                        cptr);
     else if (IsChanOp(chan) || HasVoice(chan))
-      sendcmdto_channel_butserv_butone(&me, CMD_MODE, chan->channel, cptr,
+      sendcmdto_channel_butserv_butone(&me, CMD_MODE, chan->channel, cptr, 0,
         "%H +%c %C", chan->channel, IsChanOp(chan) ? 'o' : 'v', cptr);
   }
   return 0;
@@ -1261,6 +1279,7 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv
          do_host_hiding = 1;
        break;
       default:
+        send_reply(sptr, ERR_UMODEUNKNOWNFLAG, *m);
         break;
       }
     }
@@ -1301,7 +1320,7 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv
   {
     if ((FlagHas(&setflags, FLAG_OPER) || FlagHas(&setflags, FLAG_LOCOP)) &&
         !IsAnOper(sptr))
-      det_confs_butmask(sptr, CONF_CLIENT & ~CONF_OPS);
+      det_confs_butmask(sptr, CONF_CLIENT & ~CONF_OPERATOR);
 
     if (SendServNotice(sptr))
     {
@@ -1373,6 +1392,18 @@ char *umode_str(struct Client *cptr)
     *m++ = ' ';
     while ((*m++ = *t++))
       ; /* Empty loop */
+
+    if (cli_user(cptr)->acc_create) {
+      char nbuf[20];
+      Debug((DEBUG_DEBUG, "Sending timestamped account in user mode for "
+            "account \"%s\"; timestamp %Tu", cli_user(cptr)->account,
+            cli_user(cptr)->acc_create));
+      ircd_snprintf(0, t = nbuf, sizeof(nbuf), ":%Tu",
+                   cli_user(cptr)->acc_create);
+      m--; /* back up over previous nul-termination */
+      while ((*m++ = *t++))
+       ; /* Empty loop */
+    }
   }
 
   *m = '\0';