Author: Kev <klmitch@mit.edu>
authorKevin L. Mitchell <klmitch@mit.edu>
Thu, 2 Nov 2000 17:31:27 +0000 (17:31 +0000)
committerKevin L. Mitchell <klmitch@mit.edu>
Thu, 2 Nov 2000 17:31:27 +0000 (17:31 +0000)
Log message:

1) Use do_names() directly instead of calling through m_names(), which is
ugly.

2) Add channel creation TS to JOIN protocol messages, which also requires
us to seperate them; never transmute a JOIN into a CREATE, but create the
channel with the proper TS, or with MAGIC_REMOTE_JOIN_TS.

3) Remove a compiler warning.

Testing done: Checked for correct behavior; checked at the server<->server
level to ensure channels are created with appropriate timestamps; also
checked that CREATE gets bounced with MODE -o in appropriate circumstances.

Testing needed: Beat on this heavily and make sure nothing weird happens ;)

git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@306 c9e4aea6-c8fd-4c43-8297-357d70d61c8c

ChangeLog
include/s_user.h
ircd/channel.c
ircd/m_join.c
ircd/m_names.c
ircd/m_whois.c

index 81f7ace8a5f946572de42a9c0b93cc3b60d4a846..e3b236258f7d6810d78c01166d391fd2cca0b62a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2000-11-02  Kevin L. Mitchell  <klmitch@mit.edu>
+
+       * ircd/m_whois.c: remove compiler warning by adding a newline to
+       end of file
+
+       * ircd/m_names.c: moved the flags up to s_user.h
+
+       * ircd/m_join.c: call do_names instead of m_names; restructure
+       ms_join to never transmute a JOIN into a CREATE, but use the TS in
+       the JOIN (if present) to timestamp the channel
+
+       * ircd/channel.c: send JOINs individually, instead of grouping
+       them, so that we can send the channel's creation time
+
+       * include/s_user.h: declare do_names()
+
 2000-10-30  Isomer <isomer@coders.net>
        * ircd/m_oper.c: Fixed warning
 
index 70da19bfa9333f87c3ecd79fd75da67c0e95d59d..e3e70c7846d87d0e0e1839b4ed249674e0904077 100644 (file)
@@ -13,6 +13,7 @@
 struct Client;
 struct User;
 struct Gline;
+struct Channel;
 
 /*
  * Macros
@@ -93,5 +94,9 @@ extern void add_target(struct Client *sptr, void *target);
 extern unsigned int umode_make_snomask(unsigned int oldmask, char *arg,
                                        int what);
 
+#define NAMES_ALL 1 /* List all users in channel */
+#define NAMES_VIS 2 /* List only visible users in non-secret channels */
+
+void do_names(struct Client* sptr, struct Channel* chptr, int filter);
 
 #endif /* INCLUDED_s_user_h */
index fcb4661f4284ba3d4384bcbe900775b4a2baa3e4..3a1ff755d57cc469c7672ae67ed593d94a629bdf 100644 (file)
@@ -3943,46 +3943,56 @@ joinbuf_join(struct JoinBuf *jbuf, struct Channel *chan, unsigned int flags)
 
   assert(0 != jbuf);
 
-  if (chan) {
-    if (jbuf->jb_type == JOINBUF_TYPE_PART ||
-       jbuf->jb_type == JOINBUF_TYPE_PARTALL) {
-      /* Send notification to channel */
-      if (!(flags & CHFL_ZOMBIE))
-       sendcmdto_channel_butserv(jbuf->jb_source, CMD_PART, chan,
-                                 (flags & CHFL_BANNED || !jbuf->jb_comment) ?
-                                 ":%H" : "%H :%s", chan, jbuf->jb_comment);
-      else if (MyUser(jbuf->jb_source))
-       sendcmdto_one(jbuf->jb_source, CMD_PART, jbuf->jb_source,
-                     (flags & CHFL_BANNED || !jbuf->jb_comment) ?
-                     ":%H" : "%H :%s", chan, jbuf->jb_comment);
-      /* XXX: Shouldn't we send a PART here anyway? */
-      /* to users on the channel?  Why?  From their POV, the user isn't on
-       * the channel anymore anyway.  We don't send to servers until below,
-       * when we gang all the channel parts together.  Note that this is
-       * exactly the same logic, albeit somewhat more concise, as was in
-       * the original m_part.c */
-
-      if (jbuf->jb_type == JOINBUF_TYPE_PARTALL ||
-         IsLocalChannel(chan->chname)) /* got to remove user here */
-       remove_user_from_channel(jbuf->jb_source, chan);
-    } else {
-      /* Add user to channel */
-      add_user_to_channel(chan, jbuf->jb_source, flags);
+  if (!chan) {
+    if (jbuf->jb_type == JOINBUF_TYPE_JOIN)
+      sendcmdto_serv_butone(jbuf->jb_source, CMD_JOIN, jbuf->jb_connect, "0");
 
-      /* Send the notification to the channel */
-      sendcmdto_channel_butserv(jbuf->jb_source, CMD_JOIN, chan, ":%H", chan);
+    return;
+  }
 
-      /* send an op, too, if needed */
-      if (!MyUser(jbuf->jb_source) && jbuf->jb_type == JOINBUF_TYPE_CREATE &&
-         !IsModelessChannel(chan->chname))
-       sendcmdto_channel_butserv(jbuf->jb_source, CMD_MODE, chan, "%H +o %C",
-                                 chan, jbuf->jb_source);
-    }
+  if (jbuf->jb_type == JOINBUF_TYPE_PART ||
+      jbuf->jb_type == JOINBUF_TYPE_PARTALL) {
+    /* Send notification to channel */
+    if (!(flags & CHFL_ZOMBIE))
+      sendcmdto_channel_butserv(jbuf->jb_source, CMD_PART, chan,
+                               (flags & CHFL_BANNED || !jbuf->jb_comment) ?
+                               ":%H" : "%H :%s", chan, jbuf->jb_comment);
+    else if (MyUser(jbuf->jb_source))
+      sendcmdto_one(jbuf->jb_source, CMD_PART, jbuf->jb_source,
+                   (flags & CHFL_BANNED || !jbuf->jb_comment) ?
+                   ":%H" : "%H :%s", chan, jbuf->jb_comment);
+    /* XXX: Shouldn't we send a PART here anyway? */
+    /* to users on the channel?  Why?  From their POV, the user isn't on
+     * the channel anymore anyway.  We don't send to servers until below,
+     * when we gang all the channel parts together.  Note that this is
+     * exactly the same logic, albeit somewhat more concise, as was in
+     * the original m_part.c */
+
+    if (jbuf->jb_type == JOINBUF_TYPE_PARTALL ||
+       IsLocalChannel(chan->chname)) /* got to remove user here */
+      remove_user_from_channel(jbuf->jb_source, chan);
+  } else {
+    /* Add user to channel */
+    add_user_to_channel(chan, jbuf->jb_source, flags);
 
-    if (jbuf->jb_type == JOINBUF_TYPE_PARTALL || IsLocalChannel(chan->chname))
-      return; /* don't send to remote */
+    /* send notification to all servers */
+    if (jbuf->jb_type != JOINBUF_TYPE_CREATE && !IsLocalChannel(chan->chname))
+      sendcmdto_serv_butone(jbuf->jb_source, CMD_JOIN, jbuf->jb_connect,
+                           "%H %Tu", chan, chan->creationtime);
+
+    /* Send the notification to the channel */
+    sendcmdto_channel_butserv(jbuf->jb_source, CMD_JOIN, chan, ":%H", chan);
+
+    /* send an op, too, if needed */
+    if (!MyUser(jbuf->jb_source) && jbuf->jb_type == JOINBUF_TYPE_CREATE &&
+       !IsModelessChannel(chan->chname))
+      sendcmdto_channel_butserv(jbuf->jb_source, CMD_MODE, chan, "%H +o %C",
+                               chan, jbuf->jb_source);
   }
 
+  if (jbuf->jb_type == JOINBUF_TYPE_PARTALL || IsLocalChannel(chan->chname))
+    return; /* don't send to remote */
+
   /* figure out if channel name will cause buffer to be overflowed */
   len = chan ? strlen(chan->chname) + 1 : 2;
   if (jbuf->jb_strlen + len > IRC_BUFSIZE)
@@ -4007,7 +4017,8 @@ joinbuf_flush(struct JoinBuf *jbuf)
   int chanlist_i = 0;
   int i;
 
-  if (!jbuf->jb_count || jbuf->jb_type == JOINBUF_TYPE_PARTALL)
+  if (!jbuf->jb_count || jbuf->jb_type == JOINBUF_TYPE_PARTALL ||
+      jbuf->jb_type == JOINBUF_TYPE_JOIN)
     return 0; /* no joins to process */
 
   for (i = 0; i < jbuf->jb_count; i++) { /* build channel list */
@@ -4022,18 +4033,12 @@ joinbuf_flush(struct JoinBuf *jbuf)
   }
 
   jbuf->jb_count = 0; /* reset base counters */
-  jbuf->jb_strlen = ((jbuf->jb_type == JOINBUF_TYPE_JOIN ||
-                     jbuf->jb_type == JOINBUF_TYPE_PART ?
+  jbuf->jb_strlen = ((jbuf->jb_type == JOINBUF_TYPE_PART ?
                      STARTJOINLEN : STARTCREATELEN) +
                     (jbuf->jb_comment ? strlen(jbuf->jb_comment) + 2 : 0));
 
   /* and send the appropriate command */
   switch (jbuf->jb_type) {
-  case JOINBUF_TYPE_JOIN:
-    sendcmdto_serv_butone(jbuf->jb_source, CMD_JOIN, jbuf->jb_connect,
-                         "%s", chanlist);
-    break;
-
   case JOINBUF_TYPE_CREATE:
     sendcmdto_serv_butone(jbuf->jb_source, CMD_CREATE, jbuf->jb_connect,
                          "%s %Tu", chanlist, jbuf->jb_create);
index 86582b26244b134c20e5a0747f6bd027e2957dbc..657bc4e7398c54abb4df031f022b3a532725da29 100644 (file)
@@ -292,8 +292,7 @@ int m_join(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
                 chptr->topic_time);
     }
 
-    parv[1] = name;
-    m_names(cptr, sptr, 2, parv); /* XXX find a better way */
+    do_names(sptr, chptr, NAMES_ALL); /* send /names list */
   }
 
   joinbuf_flush(&join); /* must be first, if there's a JOIN 0 */
@@ -310,8 +309,8 @@ int ms_join(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
   struct Membership *member;
   struct Channel *chptr;
   struct JoinBuf join;
-  struct JoinBuf create;
   unsigned int flags = 0;
+  time_t creation = 0;
   char *p = 0;
   char *chanlist;
   char *name;
@@ -324,8 +323,10 @@ int ms_join(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
   if (parc < 2 || *parv[1] == '\0')
     return need_more_params(sptr, "JOIN");
 
+  if (parc > 2 && parv[2])
+    creation = atoi(parv[2]);
+
   joinbuf_init(&join, sptr, cptr, JOINBUF_TYPE_JOIN, 0, 0);
-  joinbuf_init(&create, sptr, cptr, JOINBUF_TYPE_CREATE, 0, TStime());
 
   chanlist = last0(parv[1]); /* find last "JOIN 0" */
 
@@ -349,29 +350,19 @@ int ms_join(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
        chptr = FindChannel(name);
       } else
        flags = CHFL_DEOPPED | ((sptr->flags & FLAGS_TS8) ? CHFL_SERVOPOK : 0);
-    } else
-      flags = IsModelessChannel(name) ? CHFL_DEOPPED : CHFL_CHANOP;
+    } else {
+      flags = CHFL_DEOPPED | ((sptr->flags & FLAGS_TS8) ? CHFL_SERVOPOK : 0);
 
-    if (chptr)
-      joinbuf_join(&join, chptr, flags);
-    /* Strange that a channel should get created by a JOIN, but as long
-     * as there are desynchs, we have to assume it's possible.  Previous
-     * solutions involved sending a TS with the JOIN, but that seems
-     * unworkable to me; my solution is to transmute the JOIN into a
-     * CREATE, and let the next BURST try to fix the problem.  Another
-     * solution would be to simply issue an upstream KICK, but that
-     * won't currently be accepted.  Is this what DESTRUCT is for?
-     */
-    else if (!(chptr = get_channel(sptr, name, CGT_CREATE)))
-      continue; /* couldn't get channel */
-    else {
-      chptr->creationtime = TStime(); /* have to set the creation TS */
-      joinbuf_join(&create, chptr, flags);
+      if ((chptr = get_channel(sptr, name, CGT_CREATE)))
+       chptr->creationtime = creation ? creation : MAGIC_REMOTE_JOIN_TS;
+      else
+       continue; /* couldn't get channel */
     }
+
+    joinbuf_join(&join, chptr, flags);
   }
 
-  joinbuf_flush(&join); /* must be first, if there's a JOIN 0 */
-  joinbuf_flush(&create);
+  joinbuf_flush(&join); /* flush joins... */
 
   return 0;
 }
index 330b6f8e0183f223964d73810cd647a4d8dd00a1..56cc590a7538770287dd7b1fee510e9ad120b922 100644 (file)
 #include <assert.h>
 #include <string.h>
 
-#define NAMES_ALL 1 /* List all users in channel */
-#define NAMES_VIS 2 /* List only visible users in non-secret channels */
-
 /*
  *  Sends a suitably formatted 'names' reply to 'sptr' consisting of nicks within
  *  'chptr', depending on 'filter'.
index c2b3fa191fe4fb4355e2d3bcf2cf197ba1699b3a..eb041e13af21ef89bcdd77816abcd16d204387c7 100644 (file)
@@ -466,4 +466,4 @@ int ms_whois(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
   send_reply(sptr, RPL_ENDOFWHOIS, parv[1]);
 
   return 0;
-}
\ No newline at end of file
+}