srvx-commits Mailing List for srvx IRC Services (Page 16)
                
                Brought to you by:
                
                    entrope
                    
                
            
            
        
        
        
    You can subscribe to this list here.
| 2001 | Jan | Feb | Mar | Apr | May | Jun | Jul | Aug (80) | Sep (51) | Oct (94) | Nov (132) | Dec (85) | 
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2002 | Jan (163) | Feb (96) | Mar (70) | Apr (182) | May (173) | Jun (73) | Jul (101) | Aug (101) | Sep (71) | Oct (76) | Nov (58) | Dec (60) | 
| 2003 | Jan (61) | Feb (14) | Mar (3) | Apr | May (7) | Jun (22) | Jul (81) | Aug (41) | Sep (34) | Oct (41) | Nov (16) | Dec (28) | 
| 2004 | Jan (7) | Feb | Mar (3) | Apr (15) | May (11) | Jun (1) | Jul (4) | Aug (1) | Sep (4) | Oct (1) | Nov (1) | Dec (1) | 
| 2005 | Jan (13) | Feb (6) | Mar (1) | Apr | May (2) | Jun (1) | Jul (2) | Aug | Sep | Oct | Nov | Dec | 
| 2008 | Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec (1) | 
| 2009 | Jan | Feb | Mar (5) | Apr | May | Jun | Jul | Aug (1) | Sep (2) | Oct | Nov | Dec | 
| 2010 | Jan (2) | Feb (3) | Mar (4) | Apr (1) | May | Jun | Jul | Aug | Sep | Oct | Nov (2) | Dec | 
| 2011 | Jan | Feb | Mar | Apr | May (1) | Jun (1) | Jul | Aug | Sep | Oct (2) | Nov (1) | Dec | 
| 2012 | Jan (1) | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec | 
| 2016 | Jan | Feb | Mar | Apr (3) | May (4) | Jun | Jul (1) | Aug | Sep (3) | Oct (2) | Nov | Dec | 
| 2017 | Jan | Feb | Mar (1) | Apr | May (1) | Jun | Jul | Aug | Sep | Oct | Nov | Dec | 
| 2018 | Jan (2) | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec | 
| 2020 | Jan | Feb | Mar | Apr (1) | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec | 
| 2023 | Jan | Feb (3) | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov (3) | Dec | 
| 2025 | Jan | Feb (1) | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec | 
| 
      
      
      From: Entrope <en...@us...> - 2003-06-14 12:52:27
      
     | 
| Update of /cvsroot/srvx/services/src
In directory sc8-pr-cvs1:/tmp/cvs-serv27743/src
Modified Files:
	opserv.c 
Log Message:
fix "part" command reasons
Index: opserv.c
===================================================================
RCS file: /cvsroot/srvx/services/src/opserv.c,v
retrieving revision 1.311
retrieving revision 1.312
diff -C2 -r1.311 -r1.312
*** opserv.c	12 Jun 2003 10:56:11 -0000	1.311
--- opserv.c	14 Jun 2003 12:52:25 -0000	1.312
***************
*** 1097,1101 ****
              return 0;
          }
!         reason = (argc < 2) ? "Leaving." : unsplit_string(argv+1, argc-1, NULL);
          opserv_notice(user, OSMSG_LEAVING, channel->name);
          DelChannelUser(opserv, channel, reason, 0);
--- 1097,1101 ----
              return 0;
          }
!         reason = (argc < 3) ? "Leaving." : unsplit_string(argv+2, argc-2, NULL);
          opserv_notice(user, OSMSG_LEAVING, channel->name);
          DelChannelUser(opserv, channel, reason, 0);
 | 
| 
      
      
      From: Entrope <en...@us...> - 2003-06-14 12:50:51
      
     | 
| Update of /cvsroot/srvx/services/src
In directory sc8-pr-cvs1:/tmp/cvs-serv27543/src
Modified Files:
	chanserv.help 
Log Message:
Update "help thanks" to show BA's new nick
Index: chanserv.help
===================================================================
RCS file: /cvsroot/srvx/services/src/chanserv.help,v
retrieving revision 1.49
retrieving revision 1.50
diff -C2 -r1.49 -r1.50
*** chanserv.help	12 Mar 2003 23:33:20 -0000	1.49
--- chanserv.help	14 Jun 2003 12:50:48 -0000	1.50
***************
*** 514,517 ****
          "$bGamesNET IRC Network$b - All the users and staff there bear with our shortcomings and bugs and let us know what needs to be fixed.",
          "$bIC5 Networks$b (and JohnM in particular) - Never afraid to critique things, even if GamesNET is the 800 pound gorilla.",
!         "$bBuLLeT_ATTrAcToR, eraser, hock(ey), KilledInAction, MadEwokHerd, Milon and Shoat$b - Hardcore beta testing and bug finding on the testnet.",
          "$bCrips$b - Reading through all the boring messages and finding ways to make them clearer.");
--- 514,517 ----
          "$bGamesNET IRC Network$b - All the users and staff there bear with our shortcomings and bugs and let us know what needs to be fixed.",
          "$bIC5 Networks$b (and JohnM in particular) - Never afraid to critique things, even if GamesNET is the 800 pound gorilla.",
!         "$bMeeko, eraser, hock(ey), KilledInAction, MadEwokHerd, Milon and Shoat$b - Hardcore beta testing and bug finding on the testnet.",
          "$bCrips$b - Reading through all the boring messages and finding ways to make them clearer.");
 | 
| 
      
      
      From: Entrope <en...@us...> - 2003-06-14 12:50:19
      
     | 
| Update of /cvsroot/srvx/services/src
In directory sc8-pr-cvs1:/tmp/cvs-serv27452/src
Modified Files:
	chanserv.c 
Log Message:
Send a reply to the "opchan" command (in case someone is not in the channel)
Index: chanserv.c
===================================================================
RCS file: /cvsroot/srvx/services/src/chanserv.c,v
retrieving revision 1.350
retrieving revision 1.351
diff -C2 -r1.350 -r1.351
*** chanserv.c	12 Jun 2003 10:57:26 -0000	1.350
--- chanserv.c	14 Jun 2003 12:50:13 -0000	1.351
***************
*** 168,171 ****
--- 168,172 ----
  #define CSMSG_ALREADY_DOWN	"You are not opped or voiced in $b%s$b."
  #define CSMSG_ALREADY_OPCHANNED "There has been no net.join since the opchan in $b%s$b."
+ #define CSMSG_OPCHAN_DONE       "I have (re-)opped myself in $b%s$b."
  
  /* User management */
***************
*** 2436,2444 ****
      if(!IsPrivileged(user) && !channel->channel_info->may_opchan)
      {
!         chanserv_notice(user, CSMSG_ALREADY_OPCHANNED, channel->name);
          return 0;
      }
      channel->channel_info->may_opchan = 0;
      AddChannelOp(1, &chanserv, channel, chanserv, 1);
      return 1;
  }
--- 2437,2446 ----
      if(!IsPrivileged(user) && !channel->channel_info->may_opchan)
      {
!         reply(CSMSG_ALREADY_OPCHANNED, channel->name);
          return 0;
      }
      channel->channel_info->may_opchan = 0;
      AddChannelOp(1, &chanserv, channel, chanserv, 1);
+     reply(CSMSG_OPCHAN_DONE, channel->name);
      return 1;
  }
***************
*** 7023,7027 ****
      }
  
!     if(!cData->users)
      {
          log(CS_LOG, LOG_ERROR, "Channel %s had no users in database, unregistering it.\n", key);
--- 7025,7029 ----
      }
  
!     if(!cData->users && !IsProtected(cData))
      {
          log(CS_LOG, LOG_ERROR, "Channel %s had no users in database, unregistering it.\n", key);
 | 
| 
      
      
      From: Entrope <en...@us...> - 2003-06-13 00:46:40
      
     | 
| Update of /cvsroot/srvx/services/src
In directory sc8-pr-cvs1:/tmp/cvs-serv32180/src
Modified Files:
	proto-p10.c 
Log Message:
protect ourselves from boneheaded admins (I dub this "the Byte special")
Index: proto-p10.c
===================================================================
RCS file: /cvsroot/srvx/services/src/proto-p10.c,v
retrieving revision 1.63
retrieving revision 1.64
diff -C2 -r1.63 -r1.64
*** proto-p10.c	2 Jun 2003 03:23:33 -0000	1.63
--- proto-p10.c	13 Jun 2003 00:46:36 -0000	1.64
***************
*** 1350,1354 ****
  {
      const char *str, *desc;
!     int numnick, usermask;
      char numer[COMBO_NUMERIC_LEN+1];
  
--- 1350,1354 ----
  {
      const char *str, *desc;
!     int numnick, usermask, max_users;
      char numer[COMBO_NUMERIC_LEN+1];
  
***************
*** 1367,1371 ****
      numnick = atoi(str);
      str = conf_get_data("server/max_users", RECDB_QSTRING);
!     usermask = (str ? atoi(str) : 4096) - 1;
      if ((numnick < 64) && (usermask < 4096) && !force_n2k) {
          inttobase64(numer, (numnick << 12) + (usermask & 0x00fff), 3);
--- 1367,1373 ----
      numnick = atoi(str);
      str = conf_get_data("server/max_users", RECDB_QSTRING);
!     max_users = str ? atoi(str) : 4096;
!     for (usermask = 4; usermask < max_users; usermask <<= 1) ;
!     usermask--;
      if ((numnick < 64) && (usermask < 4096) && !force_n2k) {
          inttobase64(numer, (numnick << 12) + (usermask & 0x00fff), 3);
 | 
| 
      
      
      From: Entrope <en...@us...> - 2003-06-12 10:57:30
      
     | 
| Update of /cvsroot/srvx/services/src
In directory sc8-pr-cvs1:/tmp/cvs-serv14773/src
Modified Files:
	chanserv.c 
Log Message:
do not allow normal users to unregister a suspended channel
Index: chanserv.c
===================================================================
RCS file: /cvsroot/srvx/services/src/chanserv.c,v
retrieving revision 1.349
retrieving revision 1.350
diff -C2 -r1.349 -r1.350
*** chanserv.c	24 May 2003 18:50:41 -0000	1.349
--- chanserv.c	12 Jun 2003 10:57:26 -0000	1.350
***************
*** 140,143 ****
--- 140,144 ----
  #define CSMSG_UNREG_SUCCESS	"$b%s$b has been unregistered."
  #define CSMSG_UNREG_NODELETE	"$b%s$b is protected from unregistration."
+ #define CSMSG_CHAN_SUSPENDED    "$b$C$b access to $b%s$b has been temporarily suspended (%s)."
  #define CSMSG_CONFIRM_UNREG	"To confirm this unregistration, you must append 'CONFIRM' to the end of your command. For example, 'unregister CONFIRM'."
  
***************
*** 2007,2010 ****
--- 2008,2016 ----
      if(!IsPrivileged(user))
      {
+         if(IsSuspended(cData))
+         {
+             reply(CSMSG_CHAN_SUSPENDED, cData->suspended->name, cData->suspended->reason);
+             return 0;
+         }
  	if(argc < confirm + 1 || strcmp(argv[confirm], "CONFIRM"))
  	{
 | 
| 
      
      
      From: Entrope <en...@us...> - 2003-06-12 10:56:16
      
     | 
| Update of /cvsroot/srvx/services/src
In directory sc8-pr-cvs1:/tmp/cvs-serv14135/src
Modified Files:
	opserv.c 
Log Message:
make cmd_join work properly for non-OpServ bots
Index: opserv.c
===================================================================
RCS file: /cvsroot/srvx/services/src/opserv.c,v
retrieving revision 1.310
retrieving revision 1.311
diff -C2 -r1.310 -r1.311
*** opserv.c	8 Jun 2003 02:46:30 -0000	1.310
--- opserv.c	12 Jun 2003 10:56:11 -0000	1.311
***************
*** 935,938 ****
--- 935,940 ----
  {
      int announce_op;
+     struct userNode *bot = cmd->parent->bot;
+ 
      OPSERV_MIN_PARMS(2, false);
      if (!IsChannelName(argv[1])) {
***************
*** 941,945 ****
      }
      if ((channel = GetChannel(argv[1]))) {
!         if (GetUserMode(channel, opserv)) {
              reply(OSMSG_ALREADY_JOINED, channel->name);
              return 0;
--- 943,947 ----
      }
      if ((channel = GetChannel(argv[1]))) {
!         if (GetUserMode(channel, bot)) {
              reply(OSMSG_ALREADY_JOINED, channel->name);
              return 0;
***************
*** 950,956 ****
          announce_op = 0;
      }
!     AddChannelUser(opserv, channel);
!     AddChannelOp(1, &opserv, channel, opserv, announce_op);
!     irc_fetchtopic(opserv, channel->name);
      reply(OSMSG_JOIN_DONE, channel->name);
      return 1;
--- 952,958 ----
          announce_op = 0;
      }
!     AddChannelUser(bot, channel);
!     AddChannelOp(1, &bot, channel, bot, announce_op);
!     irc_fetchtopic(bot, channel->name);
      reply(OSMSG_JOIN_DONE, channel->name);
      return 1;
 | 
| 
      
      
      From: Entrope <en...@us...> - 2003-06-08 02:46:50
      
     | 
| Update of /cvsroot/srvx/services/src
In directory sc8-pr-cvs1:/tmp/cvs-serv22166/src
Modified Files:
	opserv.c 
Log Message:
fix typo in last commit
Index: opserv.c
===================================================================
RCS file: /cvsroot/srvx/services/src/opserv.c,v
retrieving revision 1.309
retrieving revision 1.310
diff -C2 -r1.309 -r1.310
*** opserv.c	5 Jun 2003 14:28:01 -0000	1.309
--- opserv.c	8 Jun 2003 02:46:30 -0000	1.310
***************
*** 387,391 ****
      target = (argc > 1) ? (const char*)argv[1] : user->nick;
      if (!(hi = smart_get_handle_info(opserv, user, target))) return 0;
!     res = (argc > 2) ? oper_try_set_access(user, opserv, hi, strtoul(argv[0], NULL, 0)) : 0;
      opserv_notice(user, OSMSG_USER_ACCESS_IS, target, hi->handle, hi->opserv_level);
      return res;
--- 387,391 ----
      target = (argc > 1) ? (const char*)argv[1] : user->nick;
      if (!(hi = smart_get_handle_info(opserv, user, target))) return 0;
!     res = (argc > 2) ? oper_try_set_access(user, opserv, hi, strtoul(argv[2], NULL, 0)) : 0;
      opserv_notice(user, OSMSG_USER_ACCESS_IS, target, hi->handle, hi->opserv_level);
      return res;
 | 
| 
      
      
      From: Entrope <en...@us...> - 2003-06-05 14:28:08
      
     | 
| Update of /cvsroot/srvx/services/src
In directory sc8-pr-cvs1:/tmp/cvs-serv17095/src
Modified Files:
	opserv.c nickserv.h nickserv.c messages.h 
Log Message:
Do not let an oper demote themself (I dub this the "Spike Special")
Index: opserv.c
===================================================================
RCS file: /cvsroot/srvx/services/src/opserv.c,v
retrieving revision 1.308
retrieving revision 1.309
diff -C2 -r1.308 -r1.309
*** opserv.c	24 May 2003 17:02:20 -0000	1.308
--- opserv.c	5 Jun 2003 14:28:01 -0000	1.309
***************
*** 382,402 ****
      struct handle_info *hi;
      const char *target;
!     unsigned int new_level;
      (void)channel;
  
      target = (argc > 1) ? (const char*)argv[1] : user->nick;
      if (!(hi = smart_get_handle_info(opserv, user, target))) return 0;
!     if ((argc > 2) && oper_can_set_access(user, opserv) && oper_outranks(user, hi)) {
!         new_level = strtoul(argv[2], NULL, 0);
!         if (user->handle_info->opserv_level < new_level) {
!             opserv_notice(user, OSMSG_OPSERV_LEVEL_BAD);            
!         } else {
!             log(NS_LOG, LOG_INFO, "Account %s setting oper level for account %s to %d (from %d)\n",
!                 user->handle_info->handle, hi->handle, new_level, hi->opserv_level);
!             hi->opserv_level = new_level;
!         }
!     }
      opserv_notice(user, OSMSG_USER_ACCESS_IS, target, hi->handle, hi->opserv_level);
!     return 1;
  }
  
--- 382,393 ----
      struct handle_info *hi;
      const char *target;
!     unsigned int res;
      (void)channel;
  
      target = (argc > 1) ? (const char*)argv[1] : user->nick;
      if (!(hi = smart_get_handle_info(opserv, user, target))) return 0;
!     res = (argc > 2) ? oper_try_set_access(user, opserv, hi, strtoul(argv[0], NULL, 0)) : 0;
      opserv_notice(user, OSMSG_USER_ACCESS_IS, target, hi->handle, hi->opserv_level);
!     return res;
  }
  
Index: nickserv.h
===================================================================
RCS file: /cvsroot/srvx/services/src/nickserv.h,v
retrieving revision 1.40
retrieving revision 1.41
diff -C2 -r1.40 -r1.41
*** nickserv.h	11 Nov 2002 05:31:08 -0000	1.40
--- nickserv.h	5 Jun 2003 14:28:02 -0000	1.41
***************
*** 113,117 ****
  struct handle_info *get_handle_info(const char *handle);
  struct handle_info *smart_get_handle_info(struct userNode *service, struct userNode *user, const unsigned char *name);
! int oper_can_set_access(struct userNode *user, struct userNode *bot);
  int oper_outranks(struct userNode *user, struct handle_info *hi);
  struct nick_info *get_nick_info(const char *nick);
--- 113,117 ----
  struct handle_info *get_handle_info(const char *handle);
  struct handle_info *smart_get_handle_info(struct userNode *service, struct userNode *user, const unsigned char *name);
! int oper_try_set_access(struct userNode *user, struct userNode *bot, struct handle_info *target, unsigned int new_level);
  int oper_outranks(struct userNode *user, struct handle_info *hi);
  struct nick_info *get_nick_info(const char *nick);
Index: nickserv.c
===================================================================
RCS file: /cvsroot/srvx/services/src/nickserv.c,v
retrieving revision 1.232
retrieving revision 1.233
diff -C2 -r1.232 -r1.233
*** nickserv.c	24 May 2003 14:48:15 -0000	1.232
--- nickserv.c	5 Jun 2003 14:28:02 -0000	1.233
***************
*** 2170,2179 ****
  
  int
! oper_can_set_access(struct userNode *user, struct userNode *bot) {
!     return oper_has_access(user, bot, nickserv_conf.modoper_level, 0);
  }
  
  static OPTION_FUNC(opt_level)
  {
      if (!override) {
  	nickserv_notice(user, MSG_SETTING_PRIVILEGED, argv[0]);
--- 2170,2202 ----
  
  int
! oper_try_set_access(struct userNode *user, struct userNode *bot, struct handle_info *target, unsigned int new_level) {
!     if (!oper_has_access(user, bot, nickserv_conf.modoper_level, 0)) return 0;
!     if ((user->handle_info->opserv_level < target->opserv_level)
!         || ((user->handle_info->opserv_level == target->opserv_level)
!             && (user->handle_info->opserv_level < 1000))) {
!         send_message(user, bot, MSG_USER_OUTRANKED, target->handle);
!         return 0;
!     }
!     if ((user->handle_info->opserv_level < new_level)
!         || ((user->handle_info->opserv_level == new_level)
!             && (user->handle_info->opserv_level < 1000))) {
!         send_message(user, bot, NSMSG_OPSERV_LEVEL_BAD);
!         return 0;
!     }
!     if (user->handle_info == target) {
!         send_message(user, bot, MSG_STUPID_ACCESS_CHANGE);
!         return 0;
!     }
!     if (target->opserv_level == new_level) return 0;
!     log(NS_LOG, LOG_INFO, "Account %s setting oper level for account %s to %d (from %d)\n",
!         user->handle_info->handle, target->handle, new_level, target->opserv_level);
!     target->opserv_level = new_level;
!     return 1;
  }
  
  static OPTION_FUNC(opt_level)
  {
+     int res;
+ 
      if (!override) {
  	nickserv_notice(user, MSG_SETTING_PRIVILEGED, argv[0]);
***************
*** 2181,2197 ****
      }
  
!     if (argc > 1) {
! 	if (oper_can_set_access(user, nickserv)) {
! 	    unsigned int new_level = strtoul(argv[1], NULL, 0);
! 	    if (user->handle_info->opserv_level < new_level) {
! 		nickserv_notice(user, NSMSG_OPSERV_LEVEL_BAD);
! 	    } else {
! 		hi->opserv_level = new_level;
! 	    }
! 	}
!     }
! 
      nickserv_notice(user, NSMSG_NUM_SETTING, "LEVEL:", hi->opserv_level);
!     return 1;
  }
  
--- 2204,2210 ----
      }
  
!     res = (argc > 1) ? oper_try_set_access(user, nickserv, hi, strtoul(argv[1], NULL, 0)) : 0;
      nickserv_notice(user, NSMSG_NUM_SETTING, "LEVEL:", hi->opserv_level);
!     return res;
  }
  
Index: messages.h
===================================================================
RCS file: /cvsroot/srvx/services/src/messages.h,v
retrieving revision 1.32
retrieving revision 1.33
diff -C2 -r1.32 -r1.33
*** messages.h	3 Dec 2002 20:08:59 -0000	1.32
--- messages.h	5 Jun 2003 14:28:03 -0000	1.33
***************
*** 67,70 ****
--- 67,71 ----
  #define MSG_OPER_SUSPENDED	"Your $b$O$b access has been suspended."
  #define MSG_USER_OUTRANKED	"$b%s$b outranks you (command has no effect)."
+ #define MSG_STUPID_ACCESS_CHANGE "Please ask someone $belse$b to demote you."
  
  #define MSG_INVALID_CRITERIA	"$b%s$b is an invalid search criteria."
 | 
| 
      
      
      From: Adrian D. <sai...@us...> - 2003-06-02 20:10:50
      
     | 
| Update of /cvsroot/srvx/services/src
In directory sc8-pr-cvs1:/tmp/cvs-serv31187
Modified Files:
	helpserv.c 
Log Message:
Track all helper information for the previous 4 weeks
Modify cmd_stats to show some of the extra information
Convert all helper time stats to "x hours, y minutes"
Add number of requests picked up + reassigned to the helper in cmd_statsreport (Featreq #690260)
Index: helpserv.c
===================================================================
RCS file: /cvsroot/srvx/services/src/helpserv.c,v
retrieving revision 1.67
retrieving revision 1.68
diff -C2 -r1.67 -r1.68
*** helpserv.c	2 Jun 2003 01:32:10 -0000	1.67
--- helpserv.c	2 Jun 2003 20:10:44 -0000	1.68
***************
*** 439,448 ****
      /* statistics */
      time_t join_time; /* when they joined, or 0 if not in channel */
!     unsigned int time_per_week[4]; /* how long they've were in the channel the past 4 weeks */
!     /* These statistics are kept both per-week (in [0]) and total (in [1]).  */
!     unsigned int picked_up[2]; /* how many requests they have picked up */
!     unsigned int closed[2]; /* how many requests they have closed */
!     unsigned int reassigned_from[2]; /* how many requests reassigned from them to others */
!     unsigned int reassigned_to[2]; /* how many requests reassigned from others to them */
  };
  
--- 439,448 ----
      /* statistics */
      time_t join_time; /* when they joined, or 0 if not in channel */
!     /* [0] through [3] are n weeks ago, [4] is the total of everything before that */
!     unsigned int time_per_week[5]; /* how long they've were in the channel the past 4 weeks */
!     unsigned int picked_up[5]; /* how many requests they have picked up */
!     unsigned int closed[5]; /* how many requests they have closed */
!     unsigned int reassigned_from[5]; /* how many requests reassigned from them to others */
!     unsigned int reassigned_to[5]; /* how many requests reassigned from others to them */
  };
  
***************
*** 558,561 ****
--- 558,567 ----
  };
  
+ static void helpserv_interval(char *output, time_t interval) {
+     int num_hours = interval / 3600;
+     int num_minutes = (interval % 3600) / 60;
+     sprintf(output, "%u hour%s, %u minute%s", num_hours, num_hours == 1 ? "" : "s", num_minutes, num_minutes == 1 ? "" : "s");
+ }
+ 
  static const char * helpserv_level2str(enum helpserv_level level) {
      if (level <= HlOper) {
***************
*** 1450,1454 ****
  
      hs_user->closed[0]++;
!     hs_user->closed[1]++;
  
      /* Set these to keep track of the lists after the request is gone, but
--- 1456,1460 ----
  
      hs_user->closed[0]++;
!     hs_user->closed[4]++;
  
      /* Set these to keep track of the lists after the request is gone, but
***************
*** 1648,1658 ****
          helpserv_notice(user, HSMSG_REQ_REASSIGNED, req->id, old_helper->handle->handle);
          req->helper->reassigned_to[0]++;
!         req->helper->reassigned_to[1]++;
          old_helper->reassigned_from[0]++;
!         old_helper->reassigned_from[1]++;
      } else {
          helpserv_notice(user, HSMSG_REQ_ASSIGNED_YOU, req->id);
          req->helper->picked_up[0]++;
!         req->helper->picked_up[1]++;
      }
      helpserv_show(from_opserv, hs, user, req);
--- 1654,1664 ----
          helpserv_notice(user, HSMSG_REQ_REASSIGNED, req->id, old_helper->handle->handle);
          req->helper->reassigned_to[0]++;
!         req->helper->reassigned_to[4]++;
          old_helper->reassigned_from[0]++;
!         old_helper->reassigned_from[4]++;
      } else {
          helpserv_notice(user, HSMSG_REQ_ASSIGNED_YOU, req->id);
          req->helper->picked_up[0]++;
!         req->helper->picked_up[4]++;
      }
      helpserv_show(from_opserv, hs, user, req);
***************
*** 1813,1817 ****
      int i;
      char weekstr[32]; /* "September 10" should be the longest, but with other locales, who knows */
!     char intervalstr[INTERVALLEN];
      char buf[12];
      struct tm *week_tm;
--- 1819,1823 ----
      int i;
      char weekstr[32]; /* "September 10" should be the longest, but with other locales, who knows */
!     char intervalstr[32]; /* Should be at least 1 more than enough */
      char buf[12];
      struct tm *week_tm;
***************
*** 1849,1853 ****
      helpserv_notice(user, HSMSG_STATS_TOP, hs->helpserv->nick, target->handle->handle);
  
!     tbl.length = 5;
      tbl.width = 2;
      tbl.flags = TABLE_NO_FREE;
--- 1855,1859 ----
      helpserv_notice(user, HSMSG_STATS_TOP, hs->helpserv->nick, target->handle->handle);
  
!     tbl.length = 6;
      tbl.width = 2;
      tbl.flags = TABLE_NO_FREE;
***************
*** 1858,1872 ****
      week_tm = localtime(&last_stats_update);
      week_tm->tm_mday -= week_tm->tm_wday; /* Ensure it'll start on Sunday */
!     for (i=0; i < 4; i++) {
          unsigned int week_time = target->time_per_week[i];
          tbl.contents[i+1] = alloca(tbl.width * sizeof(**tbl.contents));
!         mktime(week_tm); /* To fix up other stuff after messing with tm_mday */
!         if (!strftime(weekstr, 32, "%B %d", week_tm)) {
!             tbl.contents[i+1][0] = strdup("(Error)");
          } else {
!             tbl.contents[i+1][0] = strdup(weekstr);
          }
!         if ((i == 0) && target->join_time) week_time += now - target->join_time;
!         intervalString(intervalstr, week_time);
          tbl.contents[i+1][1] = strdup(intervalstr);
          week_tm->tm_mday -= 7;
--- 1864,1882 ----
      week_tm = localtime(&last_stats_update);
      week_tm->tm_mday -= week_tm->tm_wday; /* Ensure it'll start on Sunday */
!     for (i=0; i < 5; i++) {
          unsigned int week_time = target->time_per_week[i];
          tbl.contents[i+1] = alloca(tbl.width * sizeof(**tbl.contents));
!         if (i == 4) {
!             tbl.contents[i+1][0] = strdup("Total");
          } else {
!             mktime(week_tm); /* To fix up other stuff after messing with tm_mday */
!             if (!strftime(weekstr, 32, "%B %d", week_tm)) {
!                 tbl.contents[i+1][0] = strdup("(Error)");
!             } else {
!                 tbl.contents[i+1][0] = strdup(weekstr);
!             }
          }
!         if ((i == 0 || i == 4) && target->join_time) week_time += now - target->join_time;
!         helpserv_interval(intervalstr, week_time);
          tbl.contents[i+1][1] = strdup(intervalstr);
          week_tm->tm_mday -= 7;
***************
*** 1882,1886 ****
  
      tbl.length = 5;
!     tbl.width = 3;
      tbl.flags = TABLE_NO_FREE;
      tbl.contents = alloca(tbl.length * sizeof(*tbl.contents));
--- 1892,1896 ----
  
      tbl.length = 5;
!     tbl.width = 4;
      tbl.flags = TABLE_NO_FREE;
      tbl.contents = alloca(tbl.length * sizeof(*tbl.contents));
***************
*** 1892,1915 ****
      tbl.contents[0][0] = "Category";
      tbl.contents[0][1] = "This week";
!     tbl.contents[0][2] = "Total";
  
      tbl.contents[1][0] = "Requests picked up";
!     for (i=0; i < 2; i++) {
!         sprintf(buf, "%u", target->picked_up[i]);
          tbl.contents[1][i+1] = strdup(buf);
      }
      tbl.contents[2][0] = "Requests closed";
!     for (i=0; i < 2; i++) {
!         sprintf(buf, "%u", target->closed[i]);
          tbl.contents[2][i+1] = strdup(buf);
      }
      tbl.contents[3][0] = "Reassigned from";
!     for (i=0; i < 2; i++) {
!         sprintf(buf, "%u", target->reassigned_from[i]);
          tbl.contents[3][i+1] = strdup(buf);
      }
      tbl.contents[4][0] = "Reassigned to";
!     for (i=0; i < 2; i++) {
!         sprintf(buf, "%u", target->reassigned_to[i]);
          tbl.contents[4][i+1] = strdup(buf);
      }
--- 1902,1926 ----
      tbl.contents[0][0] = "Category";
      tbl.contents[0][1] = "This week";
!     tbl.contents[0][2] = "Last week";
!     tbl.contents[0][3] = "Total";
  
      tbl.contents[1][0] = "Requests picked up";
!     for (i=0; i < 3; i++) {
!         sprintf(buf, "%u", target->picked_up[(i == 2 ? 4 : i)]);
          tbl.contents[1][i+1] = strdup(buf);
      }
      tbl.contents[2][0] = "Requests closed";
!     for (i=0; i < 3; i++) {
!         sprintf(buf, "%u", target->closed[(i == 2 ? 4 : i)]);
          tbl.contents[2][i+1] = strdup(buf);
      }
      tbl.contents[3][0] = "Reassigned from";
!     for (i=0; i < 3; i++) {
!         sprintf(buf, "%u", target->reassigned_from[(i == 2 ? 4 : i)]);
          tbl.contents[3][i+1] = strdup(buf);
      }
      tbl.contents[4][0] = "Reassigned to";
!     for (i=0; i < 3; i++) {
!         sprintf(buf, "%u", target->reassigned_to[(i == 2 ? 4 : i)]);
          tbl.contents[4][i+1] = strdup(buf);
      }
***************
*** 1921,1924 ****
--- 1932,1936 ----
          free((char *)tbl.contents[i][1]);
          free((char *)tbl.contents[i][2]);
+         free((char *)tbl.contents[i][3]);
      }
  
***************
*** 1942,1951 ****
  
      tbl.length = dict_size(hs->users)+1;
!     tbl.width = 2;
      tbl.flags = TABLE_NO_FREE;
      tbl.contents = alloca(tbl.length * sizeof(*tbl.contents));
      tbl.contents[0] = alloca(tbl.width * sizeof(**tbl.contents));
!     tbl.contents[0][0] = "Handle";
!     tbl.contents[0][1] = "Time helping";
  
      for (it=dict_first(hs->users), line=0; it; it=iter_next(it)) {
--- 1954,1964 ----
  
      tbl.length = dict_size(hs->users)+1;
!     tbl.width = 3;
      tbl.flags = TABLE_NO_FREE;
      tbl.contents = alloca(tbl.length * sizeof(*tbl.contents));
      tbl.contents[0] = alloca(tbl.width * sizeof(**tbl.contents));
!     tbl.contents[0][0] = "Account";
!     tbl.contents[0][1] = "Requests";
!     tbl.contents[0][2] = "Time helping";
  
      for (it=dict_first(hs->users), line=0; it; it=iter_next(it)) {
***************
*** 1954,1958 ****
          tbl.contents[++line] = alloca(tbl.width * sizeof(**tbl.contents));
          tbl.contents[line][0] = hs_user->handle->handle;
!         tbl.contents[line][1] = malloc(INTERVALLEN);
      }
  
--- 1967,1972 ----
          tbl.contents[++line] = alloca(tbl.width * sizeof(**tbl.contents));
          tbl.contents[line][0] = hs_user->handle->handle;
!         tbl.contents[line][1] = malloc(12);
!         tbl.contents[line][2] = malloc(32); /* A bit more than needed */
      }
  
***************
*** 1960,1970 ****
      week_tm.tm_mday -= week_tm.tm_wday; /* Ensure it'll start on Sunday */
      week_tm.tm_mday -= 7 * 3; /* Oldest to newest */
!     /* 4 to 1 because it's unsigned */
      for (i=4; i > 0; i--, week_tm.tm_mday += 7) {
          for (it=dict_first(hs->users), line=0; it; it=iter_next(it)) {
              struct helpserv_user *hs_user=iter_data(it);
              unsigned int week_time = hs_user->time_per_week[i-1];
              if ((i==1) && hs_user->join_time) week_time += now - hs_user->join_time;
!             intervalString((char *)tbl.contents[++line][1], week_time);
          }
          mktime(&week_tm); /* To fix up stuff after messing with tm_mday */
--- 1974,1988 ----
      week_tm.tm_mday -= week_tm.tm_wday; /* Ensure it'll start on Sunday */
      week_tm.tm_mday -= 7 * 3; /* Oldest to newest */
!     /* 4 to 1 instead of 3 to 0 because it's unsigned */
      for (i=4; i > 0; i--, week_tm.tm_mday += 7) {
          for (it=dict_first(hs->users), line=0; it; it=iter_next(it)) {
              struct helpserv_user *hs_user=iter_data(it);
+             /* Time */
              unsigned int week_time = hs_user->time_per_week[i-1];
              if ((i==1) && hs_user->join_time) week_time += now - hs_user->join_time;
!             helpserv_interval((char *)tbl.contents[++line][2], week_time);
! 
!             /* Requests */
!             sprintf((char *)tbl.contents[line][1], "%u", hs_user->picked_up[i-1]+hs_user->reassigned_to[i-1]);
          }
          mktime(&week_tm); /* To fix up stuff after messing with tm_mday */
***************
*** 1976,1979 ****
--- 1994,1998 ----
      for (line=1; line <= dict_size(hs->users); line++) {
          free((char *)tbl.contents[line][1]);
+         free((char *)tbl.contents[line][2]);
      }
  
***************
*** 2879,2883 ****
      struct saxdb_context *ctx = extra;
      struct string_list strlist;
!     char str[4][16], *strs[4];
      unsigned int i;
  
--- 2898,2902 ----
      struct saxdb_context *ctx = extra;
      struct string_list strlist;
!     char str[5][16], *strs[5];
      unsigned int i;
  
***************
*** 2890,2916 ****
      for (i=0; i < ArrayLength(strs); ++i) strs[i] = str[i];
      strlist.list = strs;
      /* Time in help channel */
-     strlist.used = 4;
      for (i=0; i < strlist.used; i++) {
          unsigned int week_time = hs_user->time_per_week[i];
!         if ((i==0) && hs_user->join_time) week_time += now - hs_user->join_time;
          sprintf(str[i], "%u", week_time);
      }
      saxdb_write_string_list(ctx, KEY_HELPER_STATS_TIME, &strlist);
      /* Requests picked up */
-     strlist.used = 2;
      for (i=0; i < strlist.used; i++) sprintf(str[i], "%u", hs_user->picked_up[i]);
      saxdb_write_string_list(ctx, KEY_HELPER_STATS_PICKUP, &strlist);
      /* Requests closed */
-     strlist.used = 2;
      for (i=0; i < strlist.used; i++) sprintf(str[i], "%u", hs_user->closed[i]);
      saxdb_write_string_list(ctx, KEY_HELPER_STATS_CLOSE, &strlist);
      /* Requests reassigned from user */
-     strlist.used = 2;
      for (i=0; i < strlist.used; i++) sprintf(str[i], "%u", hs_user->reassigned_from[i]);
      saxdb_write_string_list(ctx, KEY_HELPER_STATS_REASSIGNFROM, &strlist);
      /* Requests reassigned to user */
!     strlist.used = 2;
!     for (i=0; i < 2; i++) sprintf(str[i], "%u", hs_user->reassigned_to[i]);
      saxdb_write_string_list(ctx, KEY_HELPER_STATS_REASSIGNTO, &strlist);
      /* End of stats and whole record. */
--- 2909,2931 ----
      for (i=0; i < ArrayLength(strs); ++i) strs[i] = str[i];
      strlist.list = strs;
+     strlist.used = 5;
      /* Time in help channel */
      for (i=0; i < strlist.used; i++) {
          unsigned int week_time = hs_user->time_per_week[i];
!         if ((i==0 || i==4) && hs_user->join_time) week_time += now - hs_user->join_time;
          sprintf(str[i], "%u", week_time);
      }
      saxdb_write_string_list(ctx, KEY_HELPER_STATS_TIME, &strlist);
      /* Requests picked up */
      for (i=0; i < strlist.used; i++) sprintf(str[i], "%u", hs_user->picked_up[i]);
      saxdb_write_string_list(ctx, KEY_HELPER_STATS_PICKUP, &strlist);
      /* Requests closed */
      for (i=0; i < strlist.used; i++) sprintf(str[i], "%u", hs_user->closed[i]);
      saxdb_write_string_list(ctx, KEY_HELPER_STATS_CLOSE, &strlist);
      /* Requests reassigned from user */
      for (i=0; i < strlist.used; i++) sprintf(str[i], "%u", hs_user->reassigned_from[i]);
      saxdb_write_string_list(ctx, KEY_HELPER_STATS_REASSIGNFROM, &strlist);
      /* Requests reassigned to user */
!     for (i=0; i < strlist.used; i++) sprintf(str[i], "%u", hs_user->reassigned_to[i]);
      saxdb_write_string_list(ctx, KEY_HELPER_STATS_REASSIGNTO, &strlist);
      /* End of stats and whole record. */
***************
*** 2961,2974 ****
  
      if (stats) {
          strlist = database_get_data(stats, KEY_HELPER_STATS_TIME, RECDB_STRING_LIST);
!         if (strlist) for (i=0; i < 4 && i < strlist->used; i++) hs_user->time_per_week[i] = strtoul(strlist->list[i], NULL, 0);
          strlist = database_get_data(stats, KEY_HELPER_STATS_PICKUP, RECDB_STRING_LIST);
!         if (strlist) for (i=0; i < 2 && i < strlist->used; i++) hs_user->picked_up[i] = strtoul(strlist->list[i], NULL, 0);
          strlist = database_get_data(stats, KEY_HELPER_STATS_CLOSE, RECDB_STRING_LIST);
!         if (strlist) for (i=0; i < 2 && i < strlist->used; i++) hs_user->closed[i] = strtoul(strlist->list[i], NULL, 0);
          strlist = database_get_data(stats, KEY_HELPER_STATS_REASSIGNFROM, RECDB_STRING_LIST);
!         if (strlist) for (i=0; i < 2 && i < strlist->used; i++) hs_user->reassigned_from[i] = strtoul(strlist->list[i], NULL, 0);
          strlist = database_get_data(stats, KEY_HELPER_STATS_REASSIGNTO, RECDB_STRING_LIST);
!         if (strlist) for (i=0; i < 2 && i < strlist->used; i++) hs_user->reassigned_to[i] = strtoul(strlist->list[i], NULL, 0);
      }
  
--- 2976,2995 ----
  
      if (stats) {
+         /* The tests for strlist->used are for converting the old format to the new one */
          strlist = database_get_data(stats, KEY_HELPER_STATS_TIME, RECDB_STRING_LIST);
!         if (strlist) for (i=0; i < 5 && i < strlist->used; i++) hs_user->time_per_week[i] = strtoul(strlist->list[i], NULL, 0);
!         if (strlist->used == 4) hs_user->time_per_week[4] = hs_user->time_per_week[0]+hs_user->time_per_week[1]+hs_user->time_per_week[2]+hs_user->time_per_week[3];
          strlist = database_get_data(stats, KEY_HELPER_STATS_PICKUP, RECDB_STRING_LIST);
!         if (strlist) for (i=0; i < 5 && i < strlist->used; i++) hs_user->picked_up[i] = strtoul(strlist->list[i], NULL, 0);
!         if (strlist->used == 2) hs_user->picked_up[4] = hs_user->picked_up[0]+hs_user->picked_up[1];
          strlist = database_get_data(stats, KEY_HELPER_STATS_CLOSE, RECDB_STRING_LIST);
!         if (strlist) for (i=0; i < 5 && i < strlist->used; i++) hs_user->closed[i] = strtoul(strlist->list[i], NULL, 0);
!         if (strlist->used == 2) hs_user->closed[4] = hs_user->closed[0]+hs_user->closed[1];
          strlist = database_get_data(stats, KEY_HELPER_STATS_REASSIGNFROM, RECDB_STRING_LIST);
!         if (strlist) for (i=0; i < 5 && i < strlist->used; i++) hs_user->reassigned_from[i] = strtoul(strlist->list[i], NULL, 0);
!         if (strlist->used == 2) hs_user->reassigned_from[4] = hs_user->reassigned_from[0]+hs_user->reassigned_from[1];
          strlist = database_get_data(stats, KEY_HELPER_STATS_REASSIGNTO, RECDB_STRING_LIST);
!         if (strlist) for (i=0; i < 5 && i < strlist->used; i++) hs_user->reassigned_to[i] = strtoul(strlist->list[i], NULL, 0);
!         if (strlist->used == 2) hs_user->reassigned_to[4] = hs_user->reassigned_to[0]+hs_user->reassigned_to[1];
      }
  
***************
*** 3372,3375 ****
--- 3393,3397 ----
              if (hs_user->join_time && (hs_user->join_time < now)) {
                  hs_user->time_per_week[0] += (unsigned int)(now - hs_user->join_time);
+                 hs_user->time_per_week[4] += (unsigned int)(now - hs_user->join_time);
              }
              hs_user->join_time = 0;
***************
*** 4032,4040 ****
              if (hs_user->join_time) {
                  hs_user->time_per_week[0] += now - hs_user->join_time;
                  hs_user->join_time = now;
              }
  
!             /* Shift time */
!             for (i=3; i > 0; i--) hs_user->time_per_week[i] = hs_user->time_per_week[i-1];
  
              /* Reset it for this week */
--- 4054,4069 ----
              if (hs_user->join_time) {
                  hs_user->time_per_week[0] += now - hs_user->join_time;
+                 hs_user->time_per_week[4] += now - hs_user->join_time;
                  hs_user->join_time = now;
              }
  
!             /* Shift everything */
!             for (i=3; i > 0; i--) {
!                 hs_user->time_per_week[i] = hs_user->time_per_week[i-1];
!                 hs_user->picked_up[i] = hs_user->picked_up[i-1];
!                 hs_user->closed[i] = hs_user->closed[i-1];
!                 hs_user->reassigned_from[i] = hs_user->reassigned_from[i-1];
!                 hs_user->reassigned_to[i] = hs_user->reassigned_to[i-1];
!             }
  
              /* Reset it for this week */
 | 
| 
      
      
      From: Entrope <en...@us...> - 2003-06-02 03:28:12
      
     | 
| Update of /cvsroot/srvx/services/src In directory sc8-pr-cvs1:/tmp/cvs-serv6262/src Modified Files: tools.c Log Message: for matching, use irc_tolower(x) instead of C's tolower() Index: tools.c =================================================================== RCS file: /cvsroot/srvx/services/src/tools.c,v retrieving revision 1.120 retrieving revision 1.121 diff -C2 -r1.120 -r1.121 *** tools.c 17 Dec 2002 20:24:56 -0000 1.120 --- tools.c 2 Jun 2003 03:28:06 -0000 1.121 *************** *** 81,84 **** --- 81,86 ---- static unsigned char irc_tolower[256]; + #undef tolower + #define tolower(X) irc_tolower[(unsigned char)(X)] int | 
| 
      
      
      From: Entrope <en...@us...> - 2003-06-02 03:24:31
      
     | 
| Update of /cvsroot/srvx/services/src
In directory sc8-pr-cvs1:/tmp/cvs-serv5259/src
Modified Files:
	sendmail.c 
Log Message:
close the unused ends of pipes in each sendmail child generation
Index: sendmail.c
===================================================================
RCS file: /cvsroot/srvx/services/src/sendmail.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -r1.9 -r1.10
*** sendmail.c	17 Jan 2003 03:18:33 -0000	1.9
--- sendmail.c	2 Jun 2003 03:24:23 -0000	1.10
***************
*** 144,147 ****
--- 144,151 ----
          int res, rv;
  
+         /* Close the end of pipes we do not use. */
+         close(infds[0]);
+         close(outfds[1]);
+ 
          /* Do we have any "extra" headers to send? */
          extras = conf_get_data("mail/extra_headers", RECDB_STRING_LIST);
***************
*** 207,210 ****
--- 211,218 ----
          const char *argv[10], *mpath;
          unsigned int argc = 0;
+ 
+         /* Close the end of pipes we do not use. */
+         close(infds[1]);
+         close(outfds[0]);
  
          dup2(infds[0], STDIN_FILENO);
 | 
| 
      
      
      From: Entrope <en...@us...> - 2003-06-02 03:23:37
      
     | 
| Update of /cvsroot/srvx/services/src
In directory sc8-pr-cvs1:/tmp/cvs-serv5049/src
Modified Files:
	proto-p10.c 
Log Message:
ignore SETTIME from other servers, so it doesn't spam main.log with parse errors
Index: proto-p10.c
===================================================================
RCS file: /cvsroot/srvx/services/src/proto-p10.c,v
retrieving revision 1.62
retrieving revision 1.63
diff -C2 -r1.62 -r1.63
*** proto-p10.c	28 Feb 2003 17:17:56 -0000	1.62
--- proto-p10.c	2 Jun 2003 03:23:33 -0000	1.63
***************
*** 1464,1467 ****
--- 1464,1470 ----
      dict_insert(irc_func_dict, CMD_WALLOPS, cmd_dummy);
      dict_insert(irc_func_dict, TOK_WALLOPS, cmd_dummy);
+     /* We have reliable clock!  Always!  Wraaa! */
+     dict_insert(irc_func_dict, CMD_SETTIME, cmd_dummy);
+     dict_insert(irc_func_dict, TOK_SETTIME, cmd_dummy);
      /* handle topics */
      dict_insert(irc_func_dict, "331", cmd_num_topic);
 | 
| 
      
      
      From: Adrian D. <sai...@us...> - 2003-06-02 01:32:14
      
     | 
| Update of /cvsroot/srvx/services/src
In directory sc8-pr-cvs1:/tmp/cvs-serv7953
Modified Files:
	helpserv.c 
Log Message:
List the total number of requests waiting when whining (featreq #731618)
Index: helpserv.c
===================================================================
RCS file: /cvsroot/srvx/services/src/helpserv.c,v
retrieving revision 1.66
retrieving revision 1.67
diff -C2 -r1.66 -r1.67
*** helpserv.c	24 May 2003 14:48:16 -0000	1.66
--- helpserv.c	2 Jun 2003 01:32:10 -0000	1.67
***************
*** 200,204 ****
  #define HSMSG_PAGE_ASSIGN_REQUEST "Request ID#%lu from $b%s$b (Account %s) has been assigned to %s."
  #define HSMSG_PAGE_HELPER_GONE   "Request ID#%lu from $b%s$b (Account %s) $bhas been unassigned$b, as its helper, %s has %s."
! #define HSMSG_PAGE_WHINE_HEADER  "$b%u unhandled request%s$b waiting at least $b%s$b"
  #define HSMSG_PAGE_IDLE_HEADER   "$b%u users$b in %s $bidle at least %s$b:"
  #define HSMSG_PAGE_EMPTYALERT    "$b%s has no helpers present$b"
--- 200,204 ----
  #define HSMSG_PAGE_ASSIGN_REQUEST "Request ID#%lu from $b%s$b (Account %s) has been assigned to %s."
  #define HSMSG_PAGE_HELPER_GONE   "Request ID#%lu from $b%s$b (Account %s) $bhas been unassigned$b, as its helper, %s has %s."
! #define HSMSG_PAGE_WHINE_HEADER  "$b%u unhandled request%s$b waiting at least $b%s$b (%u total)"
  #define HSMSG_PAGE_IDLE_HEADER   "$b%u users$b in %s $bidle at least %s$b:"
  #define HSMSG_PAGE_EMPTYALERT    "$b%s has no helpers present$b"
***************
*** 2170,2177 ****
--- 2170,2179 ----
          struct helpserv_request *unh;
          struct helpserv_reqlist reqlist;
+         unsigned int queuesize=0;
  
          helpserv_reqlist_init(&reqlist);
  
          for (unh = hs->unhandled; unh; unh = unh->next_unhandled) {
+             queuesize++;
              if ((now - unh->opened) >= TIME_T_CAST hs->intervals[INTERVAL_WHINE_DELAY]) {
                  helpserv_reqlist_append(&reqlist, unh);
***************
*** 2207,2211 ****
              }
  
!             helpserv_page(PGSRC_ALERT, HSMSG_PAGE_WHINE_HEADER, reqlist.used, (reqlist.used == 1 ? "" : "s"), strwhinedelay);
              table_send(hs->helpserv, hs->page_targets[PGSRC_ALERT]->name, 0, page_type_funcs[hs->page_types[PGSRC_ALERT]], tbl);
  
--- 2209,2213 ----
              }
  
!             helpserv_page(PGSRC_ALERT, HSMSG_PAGE_WHINE_HEADER, reqlist.used, (reqlist.used == 1 ? "" : "s"), strwhinedelay, queuesize);
              table_send(hs->helpserv, hs->page_targets[PGSRC_ALERT]->name, 0, page_type_funcs[hs->page_types[PGSRC_ALERT]], tbl);
  
***************
*** 2215,2219 ****
              }
  #else
!             helpserv_page(PGSRC_ALERT, HSMSG_PAGE_WHINE_HEADER, reqlist.used, (reqlist.used == 1 ? "" : "s"), strwhinedelay);
  #endif
          }
--- 2217,2221 ----
              }
  #else
!             helpserv_page(PGSRC_ALERT, HSMSG_PAGE_WHINE_HEADER, reqlist.used, (reqlist.used == 1 ? "" : "s"), strwhinedelay, queuesize);
  #endif
          }
 | 
| 
      
      
      From: Entrope <en...@us...> - 2003-05-31 00:06:17
      
     | 
| Update of /cvsroot/srvx/services/src In directory sc8-pr-cvs1:/tmp/cvs-serv4959/src Added Files: config.h.in Log Message: add missing config.h.in file | 
| 
      
      
      From: Entrope <en...@us...> - 2003-05-31 00:04:01
      
     | 
| Update of /cvsroot/srvx/services/src In directory sc8-pr-cvs1:/tmp/cvs-serv5882/src Removed Files: config.h.in Log Message: true reason not to have src/config.h.in: it is generated by autoheader (see autogen.sh) --- config.h.in DELETED --- | 
| 
      
      
      From: Entrope <en...@us...> - 2003-05-24 18:50:44
      
     | 
| Update of /cvsroot/srvx/services/src
In directory sc8-pr-cvs1:/tmp/cvs-serv28350/src
Modified Files:
	chanserv.c 
Log Message:
Fix possible NULL dereference
Index: chanserv.c
===================================================================
RCS file: /cvsroot/srvx/services/src/chanserv.c,v
retrieving revision 1.348
retrieving revision 1.349
diff -C2 -r1.348 -r1.349
*** chanserv.c	24 May 2003 14:48:16 -0000	1.348
--- chanserv.c	24 May 2003 18:50:41 -0000	1.349
***************
*** 4324,4328 ****
  
      if(IsSuspended(cData)) chanserv_notice(user, CSMSG_CHANNEL_SUSPENDED, chan_name);
!     if((cData->suspended) && ((uData->access >= ulCoowner) || IsPrivileged(user)))
      {
          struct suspended *suspended;
--- 4324,4328 ----
  
      if(IsSuspended(cData)) chanserv_notice(user, CSMSG_CHANNEL_SUSPENDED, chan_name);
!     if((cData->suspended) && (((uData && (uData->access >= ulCoowner)) || IsPrivileged(user))))
      {
          struct suspended *suspended;
 | 
| 
      
      
      From: Entrope <en...@us...> - 2003-05-24 17:02:24
      
     | 
| Update of /cvsroot/srvx/services/src
In directory sc8-pr-cvs1:/tmp/cvs-serv27030/src
Modified Files:
	opserv.c modcmd.h log.h 
Log Message:
Fix SourceForge bugs #684122, 690263, 692505, 696506, 708259, 721438,
724570, 726176 (include missing files)
in log.h, "#define log srvx_log" to avoid gcc-3.3 complaints
Index: opserv.c
===================================================================
RCS file: /cvsroot/srvx/services/src/opserv.c,v
retrieving revision 1.307
retrieving revision 1.308
diff -C2 -r1.307 -r1.308
*** opserv.c	24 Jan 2003 18:16:56 -0000	1.307
--- opserv.c	24 May 2003 17:02:20 -0000	1.308
***************
*** 3247,3251 ****
          return 0;
      }
!     if (!svccmd_can_invoke(user, opserv, subcmd, channel, 0, 0, 1)) return 0;
      if (!irccasecmp(argv[1], "print")) action = trace_print_func;
      else if (!irccasecmp(argv[1], "count")) action = trace_count_func;
--- 3247,3251 ----
          return 0;
      }
!     if (!svccmd_can_invoke(user, opserv, subcmd, channel, SVCCMD_NOISY)) return 0;
      if (!irccasecmp(argv[1], "print")) action = trace_print_func;
      else if (!irccasecmp(argv[1], "count")) action = trace_count_func;
***************
*** 3465,3469 ****
      sprintf(buf, "%s %s", argv[0], argv[0]);
      if ((subcmd = opserv_get_command(buf))
!         && !svccmd_can_invoke(user, cmd->parent->bot, subcmd, channel, 0, 0, 1)) {
          return 0;
      }
--- 3465,3469 ----
      sprintf(buf, "%s %s", argv[0], argv[0]);
      if ((subcmd = opserv_get_command(buf))
!         && !svccmd_can_invoke(user, cmd->parent->bot, subcmd, channel, SVCCMD_NOISY)) {
          return 0;
      }
***************
*** 3559,3563 ****
      sprintf(buf, "%s %s", argv[0], argv[0]);
      if ((subcmd = opserv_get_command(buf))
!         && !svccmd_can_invoke(user, cmd->parent->bot, subcmd, channel, 0, 0, 1)) {
          return 0;
      }
--- 3559,3563 ----
      sprintf(buf, "%s %s", argv[0], argv[0]);
      if ((subcmd = opserv_get_command(buf))
!         && !svccmd_can_invoke(user, cmd->parent->bot, subcmd, channel, SVCCMD_NOISY)) {
          return 0;
      }
***************
*** 3807,3811 ****
  	return 0;
      }
!     if (!svccmd_can_invoke(user, opserv, subcmd, channel, 0, 0, 1)) return 0;
      if (!opserv_add_user_alert(user, name, reaction, unsplit_string(argv + 3, argc - 3, NULL))) return 0;
      opserv_notice(user, OSMSG_ADDED_ALERT, name);
--- 3807,3811 ----
  	return 0;
      }
!     if (!svccmd_can_invoke(user, opserv, subcmd, channel, SVCCMD_NOISY)) return 0;
      if (!opserv_add_user_alert(user, name, reaction, unsplit_string(argv + 3, argc - 3, NULL))) return 0;
      opserv_notice(user, OSMSG_ADDED_ALERT, name);
Index: modcmd.h
===================================================================
RCS file: /cvsroot/srvx/services/src/modcmd.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -C2 -r1.13 -r1.14
*** modcmd.h	29 Oct 2002 04:31:29 -0000	1.13
--- modcmd.h	24 May 2003 17:02:21 -0000	1.14
***************
*** 69,72 ****
--- 69,77 ----
  #define MODCMD_REQUIRE_STAFF          (MODCMD_REQUIRE_OPER|MODCMD_REQUIRE_NETWORK_HELPER|MODCMD_REQUIRE_SUPPORT_HELPER)
  
+ #define SVCCMD_QUALIFIED              0x000001
+ #define SVCCMD_DEBIT                  0x000002
+ #define SVCCMD_NOISY                  0x000004
+ #define SVCCMD_IN_CHANNEL             0x000008
+ 
  /* Modularized commands work like this:
   *
***************
*** 168,172 ****
   * 
   */
! int svccmd_can_invoke(struct userNode *user, struct userNode *bot, struct svccmd *cmd, struct chanNode *channel, char server_qualified, char debit, char noisy);
  /* Execute a command.  Returns non-zero on success. */
  int svccmd_invoke_argv(struct userNode *user, struct service *service, struct chanNode *channel, unsigned int argc, unsigned char *argv[], unsigned int server_qualified);
--- 173,177 ----
   * 
   */
! int svccmd_can_invoke(struct userNode *user, struct userNode *bot, struct svccmd *cmd, struct chanNode *channel, int flags);
  /* Execute a command.  Returns non-zero on success. */
  int svccmd_invoke_argv(struct userNode *user, struct service *service, struct chanNode *channel, unsigned int argc, unsigned char *argv[], unsigned int server_qualified);
Index: log.h
===================================================================
RCS file: /cvsroot/srvx/services/src/log.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -C2 -r1.19 -r1.20
*** log.h	15 Aug 2002 03:50:09 -0000	1.19
--- log.h	24 May 2003 17:02:21 -0000	1.20
***************
*** 73,76 ****
--- 73,77 ----
  int init_logs(void);
  void reopen_logs(void);
+ #define log srvx_log
  void log(enum log_type lt, enum log_severity ls, char *format, ...);
  
 | 
| 
      
      
      From: Entrope <en...@us...> - 2003-05-24 14:55:15
      
     | 
| Update of /cvsroot/srvx/services/src
In directory sc8-pr-cvs1:/tmp/cvs-serv15505/src
Modified Files:
	nickserv.c modcmd.c mod-snoop.c main.c helpserv.c hash.c 
	chanserv.c 
Log Message:
Fix SourceForge bugs #684122, 690263, 692505, 696506, 708259, 721438, 724570, 726176:
Kick pre-banned users on !addban, !addtimedban
Only show suspension history to coowners and above in the channel
Ignore autoinvite flag for suspended channel users
Pay attention to kicks coming from servers
dict_delete(sChannels) after unregistering them (which tries to dict_remove(sChannels, ...))
When a merge happens, update req->handle as well as req->parent_hand_list
Update copyright year in banner
Put back "!set pubcmd" checking
Only let authed users use email and password change cookies
Destroy cookies when an oper uses NickServ's "oset email" on an account
Index: nickserv.c
===================================================================
RCS file: /cvsroot/srvx/services/src/nickserv.c,v
retrieving revision 1.231
retrieving revision 1.232
diff -C2 -r1.231 -r1.232
*** nickserv.c	25 Mar 2003 09:19:32 -0000	1.231
--- nickserv.c	24 May 2003 14:48:15 -0000	1.232
***************
*** 116,119 ****
--- 116,120 ----
  #define NSMSG_EMAIL_UNACTIVATED   "That email address already has an unused cookie outstanding.  Please use the cookie or wait for it to expire."
  #define NSMSG_NO_COOKIE           "Your account does not have any cookie issued right now."
+ #define NSMSG_CANNOT_COOKIE       "You cannot use that kind of cookie when you are logged in."
  #define NSMSG_BAD_COOKIE          "That cookie is not the right one.  Please make sure you are copying it EXACTLY from the email; it is case-sensitive, so $bABC$b is different from $babc$b."
  #define NSMSG_HANDLE_ACTIVATED    "Your account is now activated (with the password you entered when you registered).  You are now authenticated to your account."
***************
*** 1618,1622 ****
  
      if ((argc == 2) && (hi = user->handle_info) && hi->cookie && (hi->cookie->type == EMAIL_CHANGE)) {
-         hi = user->handle_info;
          cookie = argv[1];
      } else {
--- 1619,1622 ----
***************
*** 1634,1637 ****
--- 1634,1646 ----
      }
  
+     /* Check validity of operation before comparing cookie to
+      * prohibit guessing by authed users. */
+     if (user->handle_info
+         && (hi->cookie->type != EMAIL_CHANGE)
+         && (hi->cookie->type != PASSWORD_CHANGE)) {
+         nickserv_notice(user, NSMSG_CANNOT_COOKIE);
+         return 0;
+     }
+ 
      if (strcmp(cookie, hi->cookie->cookie)) {
          nickserv_notice(user, NSMSG_BAD_COOKIE);
***************
*** 2146,2149 ****
--- 2155,2159 ----
              if (override) {
                  nickserv_set_email_addr(hi, argv[1]);
+                 if (hi->cookie) nickserv_eat_cookie(hi->cookie);
                  nickserv_notice(user, NSMSG_STR_SETTING, "EMAIL:", visible_email_addr(user, hi));
              } else {
***************
*** 2830,2834 ****
      }
  
!     if (subcmd && !svccmd_can_invoke(user, nickserv, subcmd, NULL, 0, 0, 1)) return 0;
  
      discrim = nickserv_discrim_create(user, argc-2, argv+2);
--- 2840,2844 ----
      }
  
!     if (subcmd && !svccmd_can_invoke(user, nickserv, subcmd, NULL, SVCCMD_NOISY)) return 0;
  
      discrim = nickserv_discrim_create(user, argc-2, argv+2);
Index: modcmd.c
===================================================================
RCS file: /cvsroot/srvx/services/src/modcmd.c,v
retrieving revision 1.53
retrieving revision 1.54
diff -C2 -r1.53 -r1.54
*** modcmd.c	21 Feb 2003 07:24:17 -0000	1.53
--- modcmd.c	24 May 2003 14:48:15 -0000	1.54
***************
*** 87,90 ****
--- 87,91 ----
  #define MCMSG_SERVICE_INFO        "Commands bound to service $b%s$b:"
  #define MCMSG_TOYS_DISABLED       "Toys are disabled in %s."
+ #define MCMSG_PUBLIC_DENY         "Public commands in $b%s$b are restricted."
  #define MCMSG_NO_TEMPLATE_SELF    "You cannot make a command its own template."
  #define MCMSG_RESOLVE_LOOP        "Invalid template loop detected: %s"
***************
*** 422,426 ****
   */
  int
! svccmd_can_invoke(struct userNode *user, struct userNode *bot, struct svccmd *cmd, struct chanNode *channel, char server_qualified, char debit, char noisy) {
      unsigned int uData_checked = 0;
      struct userData *uData = NULL;
--- 423,428 ----
   */
  int
! svccmd_can_invoke(struct userNode *user, struct userNode *bot, struct svccmd *cmd, struct chanNode *channel, int options) {
!     extern struct userNode *chanserv;
      unsigned int uData_checked = 0;
      struct userData *uData = NULL;
***************
*** 428,451 ****
  
      if (flags & MODCMD_DISABLED) {
!         if (noisy) send_message(user, bot, MSG_COMMAND_DISABLED, cmd->name);
          return 0;
      }
!     if ((flags & MODCMD_REQUIRE_QUALIFIED) && !server_qualified) {
!         if (noisy) send_message(user, bot, MCMSG_MUST_QUALIFY, bot->nick, cmd->name, bot->nick);
          return 0;
      }
      if (flags & MODCMD_REQUIRE_AUTHED) {
          if (!user->handle_info) {
!             if (noisy) send_message(user, bot, MSG_AUTHENTICATE);
              return 0;
          }
          if (HANDLE_FLAGGED(user->handle_info, SUSPENDED)) {
!             if (noisy) send_message(user, bot, MCMSG_ACCOUNT_SUSPENDED);
              return 0;
          }
      }
!     if (channel || noisy) {
          if ((flags & MODCMD_REQUIRE_CHANNEL) && !channel) {
!             if (noisy) send_message(user, bot, MSG_INVALID_CHANNEL);
              return 0;
          }
--- 430,453 ----
  
      if (flags & MODCMD_DISABLED) {
!         if (options & SVCCMD_NOISY) send_message(user, bot, MSG_COMMAND_DISABLED, cmd->name);
          return 0;
      }
!     if ((flags & MODCMD_REQUIRE_QUALIFIED) && !(options & SVCCMD_QUALIFIED)) {
!         if (options & SVCCMD_NOISY) send_message(user, bot, MCMSG_MUST_QUALIFY, bot->nick, cmd->name, bot->nick);
          return 0;
      }
      if (flags & MODCMD_REQUIRE_AUTHED) {
          if (!user->handle_info) {
!             if (options & SVCCMD_NOISY) send_message(user, bot, MSG_AUTHENTICATE);
              return 0;
          }
          if (HANDLE_FLAGGED(user->handle_info, SUSPENDED)) {
!             if (options & SVCCMD_NOISY) send_message(user, bot, MCMSG_ACCOUNT_SUSPENDED);
              return 0;
          }
      }
!     if (channel || (options & SVCCMD_NOISY)) {
          if ((flags & MODCMD_REQUIRE_CHANNEL) && !channel) {
!             if (options & SVCCMD_NOISY) send_message(user, bot, MSG_INVALID_CHANNEL);
              return 0;
          }
***************
*** 453,463 ****
              if (!channel) {
                  /* XXX: could maybe figure out better way to handle this case */
!                 if (noisy) send_message(user, bot, MSG_INVALID_CHANNEL);
                  return 0;
              } else if (!channel->channel_info) {
!                 if (noisy) send_message(user, bot, MCMSG_CHAN_NOT_REGISTERED, channel->name);
                  return 0;
              } else if (IsSuspended(channel->channel_info)) {
!                 if (noisy) send_message(user, bot, MCMSG_CHAN_SUSPENDED, channel->name, channel->channel_info->suspended->reason);
                  return 0;
              }
--- 455,465 ----
              if (!channel) {
                  /* XXX: could maybe figure out better way to handle this case */
!                 if (options & SVCCMD_NOISY) send_message(user, bot, MSG_INVALID_CHANNEL);
                  return 0;
              } else if (!channel->channel_info) {
!                 if (options & SVCCMD_NOISY) send_message(user, bot, MCMSG_CHAN_NOT_REGISTERED, channel->name);
                  return 0;
              } else if (IsSuspended(channel->channel_info)) {
!                 if (options & SVCCMD_NOISY) send_message(user, bot, MCMSG_CHAN_SUSPENDED, channel->name, channel->channel_info->suspended->reason);
                  return 0;
              }
***************
*** 466,473 ****
              if (!uData_checked) uData = _GetChannelUser(channel->channel_info, user->handle_info, 1, 0), uData_checked = 1;
              if (!uData) {
!                 if (noisy) send_message(user, bot, MCMSG_NO_CHANNEL_ACCESS, channel->name);
                  return 0;
              } else if (uData->access < cmd->min_channel_access) {
!                 if (noisy) send_message(user, bot, MCMSG_LOW_CHANNEL_ACCESS, channel->name);
                  return 0;
              }
--- 468,475 ----
              if (!uData_checked) uData = _GetChannelUser(channel->channel_info, user->handle_info, 1, 0), uData_checked = 1;
              if (!uData) {
!                 if (options & SVCCMD_NOISY) send_message(user, bot, MCMSG_NO_CHANNEL_ACCESS, channel->name);
                  return 0;
              } else if (uData->access < cmd->min_channel_access) {
!                 if (options & SVCCMD_NOISY) send_message(user, bot, MCMSG_LOW_CHANNEL_ACCESS, channel->name);
                  return 0;
              }
***************
*** 479,483 ****
                  && !IsService(user)
                  && !GetUserMode(channel, user)) {
!                 if (noisy) send_message(user, bot, MCMSG_REQUIRES_JOINABLE, channel->name);
                  return 0;
              }
--- 481,485 ----
                  && !IsService(user)
                  && !GetUserMode(channel, user)) {
!                 if (options & SVCCMD_NOISY) send_message(user, bot, MCMSG_REQUIRES_JOINABLE, channel->name);
                  return 0;
              }
***************
*** 487,491 ****
              switch (opt) {
              case 'd':
!                 if (noisy) send_message(user, bot, MCMSG_TOYS_DISABLED, channel->name);
                  return 0;
              case 'n':
--- 489,493 ----
              switch (opt) {
              case 'd':
!                 if (options & SVCCMD_NOISY) send_message(user, bot, MCMSG_TOYS_DISABLED, channel->name);
                  return 0;
              case 'n':
***************
*** 497,500 ****
--- 499,524 ----
          }
      }
+     /* Count the abstraction violations while we support !set pubcmd.. */
+     if ((options & SVCCMD_IN_CHANNEL)
+         && channel->channel_info && (bot == chanserv)
+         && (channel->channel_info->options[optPubCmd] != 'a')) {
+         char pubcmd = channel->channel_info->options[optPubCmd];
+         int prohibit = 0;
+         if (!uData_checked) uData = _GetChannelUser(channel->channel_info, user->handle_info, 1, 0), uData_checked = 1;
+         if (uData) {
+             switch (pubcmd) {
+             case 'p': prohibit = uData->access < ulPeon; break;
+             case 'o': prohibit = uData->access < ulOp; break;
+             case 'm': prohibit = uData->access < ulMaster; break;
+             case 'c': prohibit = uData->access < ulCoowner; break;
+             case 'w': prohibit = uData->access < ulOwner; break;
+             case 'n': prohibit = uData->access < ulHelper; break;
+             }
+         } else prohibit = 1;
+         if (prohibit) {
+             if (options & SVCCMD_NOISY) send_message(user, bot, MCMSG_PUBLIC_DENY, channel->name);
+             return 0;
+         }
+     }
      if (flags & MODCMD_REQUIRE_STAFF) {
          if (((flags & MODCMD_REQUIRE_OPER) && IsOper(user))
***************
*** 503,520 ****
              /* allow it */
          } else {
!             if (noisy) send_message(user, bot, MSG_COMMAND_PRIVILEGED, cmd->name);
              return 0;
          }
      }
      if ((flags & MODCMD_REQUIRE_HELPING) && !HANDLE_FLAGGED(user->handle_info, HELPING)) {
!         if (noisy) send_message(user, bot, MCMSG_MUST_BE_HELPING);
          return 0;
      }
      if (cmd->min_opserv_level > 0) {
!         if (!oper_has_access(user, bot, cmd->min_opserv_level, !noisy)) return 0;
      }
      if (cmd->req_account_flags || cmd->deny_account_flags) {
          if (!user->handle_info) {
!             if (noisy) send_message(user, bot, MSG_AUTHENTICATE);
              return 0;
          }
--- 527,544 ----
              /* allow it */
          } else {
!             if (options & SVCCMD_NOISY) send_message(user, bot, MSG_COMMAND_PRIVILEGED, cmd->name);
              return 0;
          }
      }
      if ((flags & MODCMD_REQUIRE_HELPING) && !HANDLE_FLAGGED(user->handle_info, HELPING)) {
!         if (options & SVCCMD_NOISY) send_message(user, bot, MCMSG_MUST_BE_HELPING);
          return 0;
      }
      if (cmd->min_opserv_level > 0) {
!         if (!oper_has_access(user, bot, cmd->min_opserv_level, !(options & SVCCMD_NOISY))) return 0;
      }
      if (cmd->req_account_flags || cmd->deny_account_flags) {
          if (!user->handle_info) {
!             if (options & SVCCMD_NOISY) send_message(user, bot, MSG_AUTHENTICATE);
              return 0;
          }
***************
*** 522,531 ****
          if ((cmd->req_account_flags & ~user->handle_info->flags)
              || (cmd->deny_account_flags & user->handle_info->flags)) {
!             if (noisy) send_message(user, bot, MSG_COMMAND_PRIVILEGED, cmd->name);
              return 0;
          }
      }
!     if (debit && !policer_conforms(user->command_policer, now, cmd->weight)) {
!         if (noisy) send_message(user, bot, MSG_COMMAND_FLOOD);
          return 0;
      }
--- 546,555 ----
          if ((cmd->req_account_flags & ~user->handle_info->flags)
              || (cmd->deny_account_flags & user->handle_info->flags)) {
!             if (options & SVCCMD_NOISY) send_message(user, bot, MSG_COMMAND_PRIVILEGED, cmd->name);
              return 0;
          }
      }
!     if ((options & SVCCMD_DEBIT) && !policer_conforms(user->command_policer, now, cmd->weight)) {
!         if (options & SVCCMD_NOISY) send_message(user, bot, MSG_COMMAND_FLOOD);
          return 0;
      }
***************
*** 533,537 ****
      /* If it's an override, return a special value. */
      if ((flags & MODCMD_REQUIRE_CHANUSER)
!         && noisy
          && (uData->access > ulOwner)
          && (!(uData = _GetChannelUser(channel->channel_info, user->handle_info, 0, 0))
--- 557,561 ----
      /* If it's an override, return a special value. */
      if ((flags & MODCMD_REQUIRE_CHANUSER)
!         && (options & SVCCMD_NOISY)
          && (uData->access > ulOwner)
          && (!(uData = _GetChannelUser(channel->channel_info, user->handle_info, 0, 0))
***************
*** 595,601 ****
  svccmd_invoke_argv(struct userNode *user, struct service *service, struct chanNode *channel, unsigned int argc, unsigned char *argv[], unsigned int server_qualified) {
      struct svccmd *cmd;
!     unsigned int cmd_arg, perms, pos, flags;
      char logbuf[2*MAXLEN];
  
      /* Find the command argument. */
      cmd_arg = IsChannelName(argv[0]) ? 1 : 0;
--- 619,626 ----
  svccmd_invoke_argv(struct userNode *user, struct service *service, struct chanNode *channel, unsigned int argc, unsigned char *argv[], unsigned int server_qualified) {
      struct svccmd *cmd;
!     unsigned int cmd_arg, perms, pos, flags, options;
      char logbuf[2*MAXLEN];
  
+     options = (server_qualified ? SVCCMD_QUALIFIED : 0) | (channel ? SVCCMD_IN_CHANNEL : 0) | SVCCMD_DEBIT | SVCCMD_NOISY;
      /* Find the command argument. */
      cmd_arg = IsChannelName(argv[0]) ? 1 : 0;
***************
*** 678,682 ****
          channel = NULL;
      }
!     perms = svccmd_can_invoke(user, service->bot, cmd, channel, server_qualified, 1, 1);
      if (!perms) return 0;
      if (argc < cmd->command->min_argc) {
--- 703,707 ----
          channel = NULL;
      }
!     perms = svccmd_can_invoke(user, service->bot, cmd, channel, (server_qualified ? SVCCMD_QUALIFIED : 0) | SVCCMD_DEBIT | SVCCMD_NOISY);
      if (!perms) return 0;
      if (argc < cmd->command->min_argc) {
***************
*** 1510,1514 ****
          svccmd = iter_data(it);
          if (strchr(svccmd->name, ' ')) continue;
!         if (!svccmd_can_invoke(user, svccmd->parent->bot, svccmd, channel, 1, 0, 0)) continue;
          if (svccmd->min_opserv_level > max_opserv_level) continue;
          if (svccmd->min_channel_access > max_chanserv_level) continue;
--- 1535,1539 ----
          svccmd = iter_data(it);
          if (strchr(svccmd->name, ' ')) continue;
!         if (!svccmd_can_invoke(user, svccmd->parent->bot, svccmd, channel, SVCCMD_QUALIFIED)) continue;
          if (svccmd->min_opserv_level > max_opserv_level) continue;
          if (svccmd->min_channel_access > max_chanserv_level) continue;
Index: mod-snoop.c
===================================================================
RCS file: /cvsroot/srvx/services/src/mod-snoop.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -C2 -r1.10 -r1.11
*** mod-snoop.c	7 Jan 2003 04:24:25 -0000	1.10
--- mod-snoop.c	24 May 2003 14:48:16 -0000	1.11
***************
*** 82,86 ****
      if (!snoop_cfg.enabled) return;
      UPDATE_TIMESTAMP();
!     SNOOP("$bKICK$b %s from %s by %s", victim->nick, chan->name, kicker->nick);
  }
  
--- 82,86 ----
      if (!snoop_cfg.enabled) return;
      UPDATE_TIMESTAMP();
!     SNOOP("$bKICK$b %s from %s by %s", victim->nick, chan->name, (kicker ? kicker->nick : "some server"));
  }
  
Index: main.c
===================================================================
RCS file: /cvsroot/srvx/services/src/main.c,v
retrieving revision 1.145
retrieving revision 1.146
diff -C2 -r1.145 -r1.146
*** main.c	21 Jan 2003 00:56:27 -0000	1.145
--- main.c	24 May 2003 14:48:16 -0000	1.146
***************
*** 594,598 ****
      printf("    --------------------------------------------------\n"
             "    - "PACKAGE_STRING" ("CODENAME"), Built: " __DATE__ ", " __TIME__".\n"
!            "    - Copyright (C) 2000 - 2002, srvx Development Team\n"
             "    --------------------------------------------------\n");
  }
--- 594,598 ----
      printf("    --------------------------------------------------\n"
             "    - "PACKAGE_STRING" ("CODENAME"), Built: " __DATE__ ", " __TIME__".\n"
!            "    - Copyright (C) 2000 - 2003, srvx Development Team\n"
             "    --------------------------------------------------\n");
  }
Index: helpserv.c
===================================================================
RCS file: /cvsroot/srvx/services/src/helpserv.c,v
retrieving revision 1.65
retrieving revision 1.66
diff -C2 -r1.65 -r1.66
*** helpserv.c	17 Feb 2003 04:55:47 -0000	1.65
--- helpserv.c	24 May 2003 14:48:16 -0000	1.66
***************
*** 3963,3966 ****
--- 3963,3967 ----
              }
              req->parent_hand_list = reqlist_to;
+             req->handle = handle_to;
              helpserv_reqlist_append(reqlist_to, req);
          }
Index: hash.c
===================================================================
RCS file: /cvsroot/srvx/services/src/hash.c,v
retrieving revision 1.173
retrieving revision 1.174
diff -C2 -r1.173 -r1.174
*** hash.c	28 Feb 2003 22:14:40 -0000	1.173
--- hash.c	24 May 2003 14:48:16 -0000	1.174
***************
*** 581,588 ****
      struct modeNode *mn;
  
!     if (!kicker || !victim || !channel || IsService(victim) || !GetUserMode(channel, victim)) return;
  
!     /* Update the kicker's idle time */
!     if ((mn = GetUserMode(channel, kicker))) {
          mn->idle_since = now;
      }
--- 581,588 ----
      struct modeNode *mn;
  
!     if (!victim || !channel || IsService(victim) || !GetUserMode(channel, victim)) return;
  
!     /* Update the kicker's idle time (kicker may be null if it was a server) */
!     if (kicker && (mn = GetUserMode(channel, kicker))) {
          mn->idle_since = now;
      }
Index: chanserv.c
===================================================================
RCS file: /cvsroot/srvx/services/src/chanserv.c,v
retrieving revision 1.347
retrieving revision 1.348
diff -C2 -r1.347 -r1.348
*** chanserv.c	19 May 2003 19:23:45 -0000	1.347
--- chanserv.c	24 May 2003 14:48:16 -0000	1.348
***************
*** 163,167 ****
  #define CSMSG_STRUCTURE_LIMIT	"This channel has reached the maximum %s limit of $b%d$b."
  #define CSMSG_ILLEGAL_CHANNEL	"$b%s$b is an illegal channel, and cannot be registered."
- #define CSMSG_PUBLIC_DENY	"Public commands in $b%s$b are restricted."
  #define CSMSG_GODMODE_UP        "You may not use $b%s$b to op yourself unless you are on the user list.  Use the $bop$b command instead."
  #define CSMSG_ALREADY_UP	"You are already %s in $b%s$b."
--- 163,166 ----
***************
*** 3120,3127 ****
                      safestrncpy(bData->owner, (user->handle_info ? user->handle_info->handle : user->nick), sizeof(bData->owner));
  		    chanserv_notice(user, CSMSG_REASON_CHANGE, ban);
! 		    if(!bData->expires)
! 		    {
! 			return 0;
! 		    }
  		}
  		if(exact && bData->expires)
--- 3119,3123 ----
                      safestrncpy(bData->owner, (user->handle_info ? user->handle_info->handle : user->nick), sizeof(bData->owner));
  		    chanserv_notice(user, CSMSG_REASON_CHANGE, ban);
! 		    if(!bData->expires) goto post_add_ban;
  		}
  		if(exact && bData->expires)
***************
*** 3166,3171 ****
  			}
  
! 			free(ban);
! 			return 0;
  		    }
  		}
--- 3162,3166 ----
  			}
  
! 			goto post_add_ban;
  		    }
  		}
***************
*** 3188,3191 ****
--- 3183,3187 ----
      }
  
+   post_add_ban:
      if(action & ACTION_BAN)
      {
***************
*** 4328,4332 ****
  
      if(IsSuspended(cData)) chanserv_notice(user, CSMSG_CHANNEL_SUSPENDED, chan_name);
!     if((cData->suspended) && (uData || IsPrivileged(user)))
      {
          struct suspended *suspended;
--- 4324,4328 ----
  
      if(IsSuspended(cData)) chanserv_notice(user, CSMSG_CHANNEL_SUSPENDED, chan_name);
!     if((cData->suspended) && ((uData->access >= ulCoowner) || IsPrivileged(user)))
      {
          struct suspended *suspended;
***************
*** 6367,6371 ****
              continue;
          }
!         if(!GetUserMode(cn, user))
          {
              if(IsUserAutoInvite(channel->user)
--- 6363,6367 ----
              continue;
          }
!         if(!GetUserMode(cn, user) && !IsUserSuspended(channel->user))
          {
              if(IsUserAutoInvite(channel->user)
***************
*** 6449,6453 ****
      char *reason = CSMSG_PROTECT_REASON;
  
!     if(!channel->channel_info || IsService(kicker) || (kicker == victim) || (kicker->handle_info && kicker->handle_info == victim->handle_info) || IsSuspended(channel->channel_info)) return;
  
      if(protect_user(victim, kicker, channel->channel_info))
--- 6445,6449 ----
      char *reason = CSMSG_PROTECT_REASON;
  
!     if(!channel->channel_info || !kicker || IsService(kicker) || (kicker == victim) || (kicker->handle_info && kicker->handle_info == victim->handle_info) || IsSuspended(channel->channel_info)) return;
  
      if(protect_user(victim, kicker, channel->channel_info))
***************
*** 7295,7300 ****
  chanserv_db_cleanup(void) {
      unreg_part_func(handle_part);
-     dict_delete(sChannels);
      while(channelList) unregister_channel(channelList);
      dict_delete(handle_dnrs);
      dict_delete(plain_dnrs);
--- 7291,7296 ----
  chanserv_db_cleanup(void) {
      unreg_part_func(handle_part);
      while(channelList) unregister_channel(channelList);
+     dict_delete(sChannels);
      dict_delete(handle_dnrs);
      dict_delete(plain_dnrs);
 | 
| 
      
      
      From: Entrope <en...@us...> - 2003-05-19 19:23:48
      
     | 
| Update of /cvsroot/srvx/services/src
In directory sc8-pr-cvs1:/tmp/cvs-serv29502/src
Modified Files:
	chanserv.c 
Log Message:
require users to have owner (or above) access in target channel for a merge
Index: chanserv.c
===================================================================
RCS file: /cvsroot/srvx/services/src/chanserv.c,v
retrieving revision 1.346
retrieving revision 1.347
diff -C2 -r1.346 -r1.347
*** chanserv.c	25 Mar 2003 09:20:16 -0000	1.346
--- chanserv.c	19 May 2003 19:23:45 -0000	1.347
***************
*** 150,153 ****
--- 150,154 ----
  #define CSMSG_MERGE_SELF	"Merging cannot be performed if the source and target channels are the same."
  #define CSMSG_MERGE_SUSPENDED	"Merging cannot be performed if the source or target channel is suspended."
+ #define CSMSG_MERGE_NOTOWNER    "You must be the owner of the target channel (or a helper) to merge into the channel."
  
  /* Handle unregistration */
***************
*** 2377,2380 ****
--- 2378,2382 ----
  static CHANSERV_FUNC(cmd_merge)
  {
+     struct userData *target_user;
      struct chanNode *target;
      char reason[MAXLEN];
***************
*** 2406,2409 ****
--- 2408,2418 ----
  	chanserv_notice(user, CSMSG_MERGE_SELF);
  	return 0;
+     }
+ 
+     target_user = GetChannelUser(target->channel_info, user->handle_info);
+     if(!target_user || (target_user->access < ulOwner))
+     {
+         chanserv_notice(user, CSMSG_MERGE_NOTOWNER);
+         return 0;
      }
  
 | 
| 
      
      
      From: Entrope <en...@us...> - 2003-05-19 19:23:01
      
     | 
| Update of /cvsroot/srvx/services
In directory sc8-pr-cvs1:/tmp/cvs-serv28762
Modified Files:
	configure.in 
Log Message:
add -fno-builtin-log to work with gcc 3.3
Index: configure.in
===================================================================
RCS file: /cvsroot/srvx/services/configure.in,v
retrieving revision 1.67
retrieving revision 1.68
diff -C2 -r1.67 -r1.68
*** configure.in	9 Jan 2003 06:18:19 -0000	1.67
--- configure.in	19 May 2003 19:22:56 -0000	1.68
***************
*** 64,68 ****
  
  dnl will be used for portability stuff
- AC_C_CONST
  AC_HEADER_TIME
  AC_STRUCT_TM
--- 64,67 ----
***************
*** 335,339 ****
  fi
  MY_SUBDIRS="$MY_SUBDIRS src"
! CFLAGS="$CFLAGS $ANSI_SRC -W -Wall"
  if test "z$USE_MAINTAINER_MODE" = zyes ; then
    CFLAGS="$CFLAGS -Werror"
--- 334,338 ----
  fi
  MY_SUBDIRS="$MY_SUBDIRS src"
! CFLAGS="$CFLAGS $ANSI_SRC -fno-builtin-log -W -Wall"
  if test "z$USE_MAINTAINER_MODE" = zyes ; then
    CFLAGS="$CFLAGS -Werror"
 | 
| 
      
      
      From: Zoot <zo...@us...> - 2003-03-25 09:20:28
      
     | 
| Update of /cvsroot/srvx/services/src
In directory sc8-pr-cvs1:/tmp/cvs-serv10237/src
Modified Files:
	chanserv.c 
Log Message:
Don't protect a user from a kick when the kicker and victim are authenticated to the same account.
Index: chanserv.c
===================================================================
RCS file: /cvsroot/srvx/services/src/chanserv.c,v
retrieving revision 1.345
retrieving revision 1.346
diff -C2 -r1.345 -r1.346
*** chanserv.c	28 Feb 2003 22:23:11 -0000	1.345
--- chanserv.c	25 Mar 2003 09:20:16 -0000	1.346
***************
*** 6440,6444 ****
      char *reason = CSMSG_PROTECT_REASON;
  
!     if(!channel->channel_info || IsService(kicker) || (kicker == victim) || IsSuspended(channel->channel_info)) return;
  
      if(protect_user(victim, kicker, channel->channel_info))
--- 6440,6444 ----
      char *reason = CSMSG_PROTECT_REASON;
  
!     if(!channel->channel_info || IsService(kicker) || (kicker == victim) || (kicker->handle_info && kicker->handle_info == victim->handle_info) || IsSuspended(channel->channel_info)) return;
  
      if(protect_user(victim, kicker, channel->channel_info))
 | 
| 
      
      
      From: Zoot <zo...@us...> - 2003-03-25 09:19:39
      
     | 
| Update of /cvsroot/srvx/services/src
In directory sc8-pr-cvs1:/tmp/cvs-serv9717/src
Modified Files:
	nickserv.c 
Log Message:
Remember to register NickServ's configuration reload callback (Patch thanks to Shoat).
Index: nickserv.c
===================================================================
RCS file: /cvsroot/srvx/services/src/nickserv.c,v
retrieving revision 1.230
retrieving revision 1.231
diff -C2 -r1.230 -r1.231
*** nickserv.c	21 Jan 2003 04:00:11 -0000	1.230
--- nickserv.c	25 Mar 2003 09:19:32 -0000	1.231
***************
*** 3346,3350 ****
      }
  
!     nickserv_conf_read();
      nickserv_opt_dict = dict_new();
      nickserv_email_dict = dict_new();
--- 3346,3350 ----
      }
  
!     conf_register_reload(nickserv_conf_read);
      nickserv_opt_dict = dict_new();
      nickserv_email_dict = dict_new();
 | 
| 
      
      
      From: Zoot <zo...@us...> - 2003-03-12 23:33:23
      
     | 
| Update of /cvsroot/srvx/services/src
In directory sc8-pr-cvs1:/tmp/cvs-serv18996/src
Modified Files:
	chanserv.help 
Log Message:
Update help files to note that ChanServ user list commands can be used with a mask to match account names against before display.
Index: chanserv.help
===================================================================
RCS file: /cvsroot/srvx/services/src/chanserv.help,v
retrieving revision 1.48
retrieving revision 1.49
diff -C2 -r1.48 -r1.49
*** chanserv.help	31 Dec 2002 23:55:59 -0000	1.48
--- chanserv.help	12 Mar 2003 23:33:20 -0000	1.49
***************
*** 126,131 ****
          "This command lists all permanent and timed bans in the channel.",
          "$uSee Also:$u addban, delban, mdelban");
! "CLIST" ("/msg $C CLIST <#channel>",
!         "This command lists all users of level $bCoowner$b on a channel's userlist.",
          "$uSee Also:$u addcoowner, delcoowner, mdelcoowner, users");
  "CLVL" ("/msg $C CLVL <#channel> <nick|*account> <level>",
--- 126,131 ----
          "This command lists all permanent and timed bans in the channel.",
          "$uSee Also:$u addban, delban, mdelban");
! "CLIST" ("/msg $C CLIST <#channel> [mask]",
!         "This command lists all users of level $bCoowner$b on a channel's userlist. If a mask is supplied, only coowners matching the mask will be shown.",
          "$uSee Also:$u addcoowner, delcoowner, mdelcoowner, users");
  "CLVL" ("/msg $C CLVL <#channel> <nick|*account> <level>",
***************
*** 227,232 ****
          "Merges the source channel's registration, users, bans, and other data into the target channel. Users with access to both the source and target channels will retain the higher access level; if the access levels are the same, the more recent seen time is kept. Bans are also merged, with bans expiring later taking precedence.",
          "$uSee Also:$u register, move, unregister");
! "MLIST" ("/msg $C MLIST <#channel>",
!         "This command lists all users of level $bMaster$b on a channel's userlist.",
          "$uSee Also:$u addmaster, delmaster, mdelmaster, users");
  "MODE" ("/msg $C MODE <#channel>",
--- 227,232 ----
          "Merges the source channel's registration, users, bans, and other data into the target channel. Users with access to both the source and target channels will retain the higher access level; if the access levels are the same, the more recent seen time is kept. Bans are also merged, with bans expiring later taking precedence.",
          "$uSee Also:$u register, move, unregister");
! "MLIST" ("/msg $C MLIST <#channel> [mask]",
!         "This command lists all users of level $bMaster$b on a channel's userlist. If a mask is supplied, only masters matching the mask will be shown.",
          "$uSee Also:$u addmaster, delmaster, mdelmaster, users");
  "MODE" ("/msg $C MODE <#channel>",
***************
*** 251,256 ****
          "${notes}",
          "$uSee Also:$u note, delnote");
! "OLIST" ("/msg $C OLIST <#channel>",
!         "This command lists all users of level $bOp$b on a channel's userlist.",
          "$uSee Also:$u addop, delop, mdelop, users");
  "OP" ("/msg $C OP <#channel> <nick> [nick]...",
--- 251,256 ----
          "${notes}",
          "$uSee Also:$u note, delnote");
! "OLIST" ("/msg $C OLIST <#channel> [mask]",
!         "This command lists all users of level $bOp$b on a channel's userlist.  If a mask is supplied, only ops matching the mask will be shown.",
          "$uSee Also:$u addop, delop, mdelop, users");
  "OP" ("/msg $C OP <#channel> <nick> [nick]...",
***************
*** 266,270 ****
          "$uSee Also:$u info");
  "PLIST" ("/msg $C PLIST <#channel>",
!         "This command lists all users of level $bPeon$b on a channel's userlist.",
          "$uSee Also:$u addpeon, delpeon, mdelpeon, users");
  "REGISTER" ("/msg $C REGISTER <#channel> [user|*account] [force]",
--- 266,270 ----
          "$uSee Also:$u info");
  "PLIST" ("/msg $C PLIST <#channel>",
!         "This command lists all users of level $bPeon$b on a channel's userlist. If a mask is supplied, only peons matching the mask will be shown.",
          "$uSee Also:$u addpeon, delpeon, mdelpeon, users");
  "REGISTER" ("/msg $C REGISTER <#channel> [user|*account] [force]",
***************
*** 486,491 ****
           "NOTE: The NoAutoOp setting is equivalent to the !togop command in previous versions of srvx.",
           "$uSee Also:$u set");
! "USERS" ("/msg $C USERS <#channel>",
!         "Displays the userlist for the specified channel.",
          "$uSee Also:$u clist, mlist, olist, plist, wlist");
  "VERSION" ("/msg $C VERSION",
--- 486,491 ----
           "NOTE: The NoAutoOp setting is equivalent to the !togop command in previous versions of srvx.",
           "$uSee Also:$u set");
! "USERS" ("/msg $C USERS <#channel> [mask]",
!         "Displays the userlist for the specified channel. If a mask is supplied, only users matching the mask will be shown.",
          "$uSee Also:$u clist, mlist, olist, plist, wlist");
  "VERSION" ("/msg $C VERSION",
***************
*** 496,501 ****
  "WIPEINFO" ("/msg $C WIPEINFO <#channel> <nick|*account>",
          "Removes the named user's infoline in the channel.");
! "WLIST" ("/msg $C WLIST <#channel>",
!         "This command lists all users of level $bOwner$b on a channel's userlist.",
          "$uSee Also:$u addcoowner, delcoowner, mdelcoowner, users");
  
--- 496,501 ----
  "WIPEINFO" ("/msg $C WIPEINFO <#channel> <nick|*account>",
          "Removes the named user's infoline in the channel.");
! "WLIST" ("/msg $C WLIST <#channel> [mask]",
!         "This command lists all users of level $bOwner$b on a channel's userlist. If a mask is supplied, only owners matching the mask will be shown.",
          "$uSee Also:$u addcoowner, delcoowner, mdelcoowner, users");
  
 | 
| 
      
      
      From: Zoot <zo...@us...> - 2003-02-28 22:23:20
      
     | 
| Update of /cvsroot/srvx/services/src
In directory sc8-pr-cvs1:/tmp/cvs-serv17334/src
Modified Files:
	chanserv.c 
Log Message:
Make the ChanServ noregister command search the account DNR list too.
Index: chanserv.c
===================================================================
RCS file: /cvsroot/srvx/services/src/chanserv.c,v
retrieving revision 1.344
retrieving revision 1.345
diff -C2 -r1.344 -r1.345
*** chanserv.c	28 Feb 2003 22:15:51 -0000	1.344
--- chanserv.c	28 Feb 2003 22:23:11 -0000	1.345
***************
*** 1726,1730 ****
          target = argv[1];
  
!         if (argc > 2)
          {
              const char *reason = unsplit_string(argv + 2, argc - 2, NULL);
--- 1726,1730 ----
          target = argv[1];
  
!         if(argc > 2)
          {
              const char *reason = unsplit_string(argv + 2, argc - 2, NULL);
***************
*** 1739,1743 ****
          }
  
!         if((dnr = chanserv_is_dnr(target, NULL)))
          {
              reply(CSMSG_DNR_INFO, dnr->chan_name, dnr->setter, dnr->reason);
--- 1739,1755 ----
          }
  
!         if(*target == '*')
!         {
!             struct handle_info *handle;
! 
!             handle = get_handle_info(target + 1);
!             dnr = chanserv_is_dnr(NULL, handle);
!         }
!         else
!         {
!             dnr = chanserv_is_dnr(target, NULL);
!         }
! 
!         if(dnr)
          {
              reply(CSMSG_DNR_INFO, dnr->chan_name, dnr->setter, dnr->reason);
 | 
| 
      
      
      From: Zoot <zo...@us...> - 2003-02-28 22:15:57
      
     | 
| Update of /cvsroot/srvx/services/src
In directory sc8-pr-cvs1:/tmp/cvs-serv13835/src
Modified Files:
	chanserv.c 
Log Message:
Make ChanServ enforce specific keys and limits; fix ChanServ sending out mode strings that aren't totally valid.
Index: chanserv.c
===================================================================
RCS file: /cvsroot/srvx/services/src/chanserv.c,v
retrieving revision 1.343
retrieving revision 1.344
diff -C2 -r1.343 -r1.344
*** chanserv.c	21 Feb 2003 17:14:25 -0000	1.343
--- chanserv.c	28 Feb 2003 22:15:51 -0000	1.344
***************
*** 985,992 ****
  
  static void
! create_mode_lock(unsigned char *buffer, struct chanData *channel)
  {
      int pos = 0, n;
      long mode = channel->mode_on;
  
      for(n=0; n<2; n++)
--- 985,993 ----
  
  static void
! create_mode_lock(unsigned char *buffer, struct chanData *channel, int display)
  {
      int pos = 0, n;
      long mode = channel->mode_on;
+     char *key = NULL;
  
      for(n=0; n<2; n++)
***************
*** 1013,1017 ****
  	/* parse_mode_lock() restricts limit to positive numbers. */
   	if(mode & MODE_LIMIT) buffer[pos++] = 'l';
! 	if(mode & MODE_KEY) buffer[pos++] = 'k';
  
  	mode = channel->mode_off;
--- 1014,1053 ----
  	/* parse_mode_lock() restricts limit to positive numbers. */
   	if(mode & MODE_LIMIT) buffer[pos++] = 'l';
! 
!         /* Figure out if the 'k' character should be included in
!            the mode string and if a key should be appended. */
! 	if(mode & MODE_KEY)
!         {
!             if(mode == channel->mode_on || display)
!             {
!                 /* If the key is getting locked on, or if the mode
!                    string is getting displayed (key locked on or
!                    off), include the 'k' character. */
!                 buffer[pos++] = 'k';
!                 if(mode == channel->mode_on)
!                 {
!                     /* If the key is getting locked on, include the
!                        actual key (whether the mode's displayed or
!                        not). */
!                     key = channel->key;
!                 }
!             }
!             else
!             {
!                 /* The key is locked off and the mode string isn't
!                    displayed, so add in the 'k' and key if there's
!                    a key to remove. If not and the key is the only
!                    mode locked off, back up over the '-'. */
!                 if(channel->channel && channel->channel->key[0])
!                 {
!                     buffer[pos++] = 'k';
!                     key = channel->channel->key;
!                 }
!                 else if(mode == MODE_KEY)
!                 {
!                     pos--;
!                 }
!             }
!         }
  
  	mode = channel->mode_off;
***************
*** 1025,1034 ****
      }
  
!     if((channel->mode_on & MODE_KEY) && channel->key)
      {
! 	int len = strlen(channel->key);
  	buffer[pos++] = ' ';
  
! 	memcpy(buffer + pos, channel->key, len);
  	pos += len;
      }
--- 1061,1070 ----
      }
  
!     if(key)
      {
! 	int len = strlen(key);
  	buffer[pos++] = ' ';
  
! 	memcpy(buffer + pos, key, len);
  	pos += len;
      }
***************
*** 1038,1041 ****
--- 1074,1105 ----
  
  static int
+ mode_lock_violated(struct chanNode *channel)
+ {
+     chan_mode_t on, off;
+ 
+     on = channel->channel_info->mode_on;
+     off = channel->channel_info->mode_off;
+ 
+     if((on & (channel->modes ^ on)) || (channel->modes & off))
+     {
+         return 1;
+     }
+ 
+     if(on & MODE_KEY)
+     {
+         if(strcmp(channel->key, channel->channel_info->key))
+             return 1;
+     }
+ 
+     if(on & MODE_LIMIT)
+     {
+         if(channel->limit != channel->channel_info->limit)
+             return 1;
+     }
+ 
+     return 0;
+ }
+ 
+ static int
  append_entry(const char *key, void *data, void *extra)
  {
***************
*** 3973,3977 ****
  	if(channel->channel_info->mode_on || channel->channel_info->mode_off)
  	{
! 	    create_mode_lock(modes, channel->channel_info);
  	    mod_chanmode(channel, chanserv, modes);
  	    irc_mode(chanserv, channel, modes);
--- 4037,4041 ----
  	if(channel->channel_info->mode_on || channel->channel_info->mode_off)
  	{
! 	    create_mode_lock(modes, channel->channel_info, 0);
  	    mod_chanmode(channel, chanserv, modes);
  	    irc_mode(chanserv, channel, modes);
***************
*** 3994,4006 ****
      if(!check_user_level(user, channel, channel->channel_info->options[optEnfModes], 1, 0))
      {
! 	chan_mode_t on = channel->channel_info->mode_on;
! 
! 	if((on && ((channel->modes & on) != on)) || (channel->modes & channel->channel_info->mode_off))
  	{
! 	    create_mode_lock(modes, channel->channel_info);
! 
  	    mod_chanmode(channel, chanserv, modes);
- 	    irc_mode(chanserv, channel, modes);
  
  	    chanserv_notice(user, CSMSG_MODE_LOCKED, modes, channel->name);
  	    return 0;
--- 4058,4070 ----
      if(!check_user_level(user, channel, channel->channel_info->options[optEnfModes], 1, 0))
      {
!         if(mode_lock_violated(channel))
  	{
!             /* verify_mod_chanmode() modified srvx's channel mode data
!                but didn't send it out, so just undo it and don't worry
!                about sending the corrections out. */
! 	    create_mode_lock(modes, channel->channel_info, 0);
  	    mod_chanmode(channel, chanserv, modes);
  
+ 	    create_mode_lock(modes, channel->channel_info, 1);
  	    chanserv_notice(user, CSMSG_MODE_LOCKED, modes, channel->name);
  	    return 0;
***************
*** 4190,4194 ****
      if(uData && uData->access >= ulOp)
      {
!         create_mode_lock(modes, cData);
  	chanserv_notice(user, CSMSG_CHANNEL_TOPIC, cData->topic);
  	chanserv_notice(user, CSMSG_CHANNEL_MODES, modes[0] ? modes : "None.");
--- 4254,4258 ----
      if(uData && uData->access >= ulOp)
      {
!         create_mode_lock(modes, cData, 1);
  	chanserv_notice(user, CSMSG_CHANNEL_TOPIC, cData->topic);
  	chanserv_notice(user, CSMSG_CHANNEL_MODES, modes[0] ? modes : "None.");
***************
*** 5265,5278 ****
  	    }
  
! 	    create_mode_lock(modes, channel->channel_info);
  	    mod_chanmode(channel, chanserv, modes);
  	    irc_mode(chanserv, channel, modes);
  	}
      }
-     else
-     {
- 	create_mode_lock(modes, channel->channel_info);
-     }
  
      chanserv_notice(user, CSMSG_STRING_VALUE, "Modes        ", strlen(modes) ? modes : "None.");
      return 1;
--- 5329,5339 ----
  	    }
  
! 	    create_mode_lock(modes, channel->channel_info, 0);
  	    mod_chanmode(channel, chanserv, modes);
  	    irc_mode(chanserv, channel, modes);
  	}
      }
  
+     create_mode_lock(modes, channel->channel_info, 1);
      chanserv_notice(user, CSMSG_STRING_VALUE, "Modes        ", strlen(modes) ? modes : "None.");
      return 1;
***************
*** 6063,6067 ****
      {
  	char modes[MODELEN];
! 	create_mode_lock(modes, cData);
  	mod_chanmode(channel, chanserv, modes);
  	irc_mode(chanserv, channel, modes);
--- 6124,6128 ----
      {
  	char modes[MODELEN];
! 	create_mode_lock(modes, cData, 0);
  	mod_chanmode(channel, chanserv, modes);
  	irc_mode(chanserv, channel, modes);
***************
*** 6411,6428 ****
      if(change_type == MODE_CHANGE_MISC)
      {
- 	chan_mode_t on;
  	(void)change;
  
  	if(!check_user_level(user, channel, channel->channel_info->options[optEnfModes], 1, 0))
  	{
!             on = channel->channel_info->mode_on;
! 	    if((on && ((channel->modes & on) != on)) || (channel->modes & channel->channel_info->mode_off))
  	    {
  		char correct[MODELEN];
- 		create_mode_lock(correct, channel->channel_info);
  
  		mod_chanmode(channel, chanserv, correct);
  		irc_mode(chanserv, channel, correct);
  
  		chanserv_notice(user, CSMSG_MODE_LOCKED, correct, channel->name);
  	    }
--- 6472,6488 ----
      if(change_type == MODE_CHANGE_MISC)
      {
  	(void)change;
  
  	if(!check_user_level(user, channel, channel->channel_info->options[optEnfModes], 1, 0))
  	{
!             if(mode_lock_violated(channel))
  	    {
  		char correct[MODELEN];
  
+ 		create_mode_lock(correct, channel->channel_info, 0);
  		mod_chanmode(channel, chanserv, correct);
  		irc_mode(chanserv, channel, correct);
  
+ 		create_mode_lock(correct, channel->channel_info, 1);
  		chanserv_notice(user, CSMSG_MODE_LOCKED, correct, channel->name);
  	    }
***************
*** 7109,7113 ****
      if(channel->mode_on || channel->mode_off)
      {
! 	create_mode_lock(buf, channel);
          saxdb_write_string(ctx, KEY_MODES, buf);
      }
--- 7169,7173 ----
      if(channel->mode_on || channel->mode_off)
      {
! 	create_mode_lock(buf, channel, 1);
          saxdb_write_string(ctx, KEY_MODES, buf);
      }
 |