]> jfr.im git - irc/evilnet/x3.git/commitdiff
autoop, voice, bind, +Z mode
authorrubin <redacted>
Wed, 4 May 2005 06:30:32 +0000 (06:30 +0000)
committerrubin <redacted>
Wed, 4 May 2005 06:30:32 +0000 (06:30 +0000)
ChangeLog.X3
UPGRADE [new file with mode: 0644]
languages/README.txt [new file with mode: 0644]
src/chanserv.c
src/chanserv.h
src/chanserv.help
src/hash.h
src/modcmd.help
src/proto-p10.c

index 9fe0600d026a5ccb4a44f0304a105ff144ee9e41..e9beedd75c86d37f88c0f2e4a73efde2167e0977 100644 (file)
@@ -1,6 +1,24 @@
 /***********************************************************************
  X3 ChangeLog
 
+2005-05-04  Alex Schumann  <rubin@afternet.org>
+
+       * src/chanserv.c: changed uset noautoop to uset autoop (removed double
+       negitive). Added set voice to provide control over use of voice.
+       Implimented a basic chanserv db version control system for upgrading
+       seamlessly.
+
+       * src/chanserv.help: adjusted help to reflect voice and uset autoop
+       changes.
+
+       * src/hash.h: updated ssz comment from z to Z
+
+       * src/modcmd.help: rewrote BIND help
+
+       * src/proto-p10.c: Added Z (sslonly) support back in
+
+       * UPGRADE: created file to document upgrading procedures needed
+
 2005-04-23  Alex Schumann  <rubin@afternet.org>
        * src/chanserv.c: removed settings: oplevel, halfoplevel, and
        voicelevel, hard coding them to OP, HALFOP, and PEON. Changed
diff --git a/UPGRADE b/UPGRADE
new file mode 100644 (file)
index 0000000..80911e8
--- /dev/null
+++ b/UPGRADE
@@ -0,0 +1,24 @@
+**************************************
+*** X3 IRC Services                ***
+**************************************
+*** IMPORTANT UPGRADE INSTRUCTIONS ***
+**************************************
+From srvx 1.4:
+  Rename srvx.conf to x3.conf
+  Review .conf file settings. 
+    * remove giveops, givevoice from set_shows and add "Voice" above "Protect".
+    * you can change from srvx.db to x3.db here also (dont forget to rename the file)
+  Run all of the steps below
+
+As of CVS version 1.24:
+  bind chanserv 'uset autoop' and 'set voice' (see note below).
+
+
+NOTE about command bindings:
+You may do: 'bind x3 * *chanserv.*' to re-bind ALL builtin commands on chanserv. This
+is the simplest approach and probably a good idea to run for each module (chanserv, 
+opserv, nickserv, modcmd, etc) after upgrading or changing some features (such as email).  
+Alternatively you can edit the .db by hand or using the 'bind' command on irc. 
+IMPORTANT: You will need to shut down x3 gracefully (using the die or restart commands)
+after binding in order for 'set' and 'uset' subcommand changes to function properly since
+the listing is cached. 
diff --git a/languages/README.txt b/languages/README.txt
new file mode 100644 (file)
index 0000000..0e83647
--- /dev/null
@@ -0,0 +1,38 @@
+Using translations:
+  copy the languages folder into your x3 runtime directory, and restart x3.
+  alternate languages will be available in /msg authserv set lanugage
+  NOTE: Currently no other languages are caught up to recent development. 
+  if you speak them, please see below for updating instructions.
+
+Translating:
+Thanks for your interest in helping to translate X3 to other languages.
+
+How to make a new language:
+
+1: run the export script, to make an up-to-date "C" baseline db:
+   ./lang_export.sh > strings.db
+2: make a dir for your language such as de/
+   mkdir fo
+3: copy thi strings.db into your new dir
+   cp strings.db fo
+4: copy the help files into your new dir
+   cp ../src/*.help fo
+5: edit the .help and .db files, translating them to your laungage.
+   nano fo/strings.db  (etc)
+6: test the strings.db file
+   ./validate_lang.pl fo
+7: fix any problems.
+
+
+How to keep your language up to date after changes:
+
+1: run the export script, to make an up-to-date "C" baseline db:
+   ./lang_export.sh > strings.db
+2: test the strings.db file
+   ./validate_lang.pl fo
+3: fix any changes.
+
+You should also watch the cvs mailing list for changes in meaning of the strings
+since X3 is under active development.
+
+
index 7db33f1c9ea07bbefb2fc059e72522b71158e725..24b061b26417047151ce8a68c33e21ba3dd446e1 100644 (file)
 #define KEY_GIVEOWNERSHIP_PERIOD "giveownership_timeout"
 
 /* ChanServ database */
+#define KEY_VERSION_CONTROL     "version_control"
 #define KEY_CHANNELS           "channels"
 #define KEY_NOTE_TYPES          "note_types"
 
+/* version control paramiter */
+#define KEY_VERSION_NUMBER      "version_number"
+
 /* Note type parameters */
 #define KEY_NOTE_OPSERV_ACCESS  "opserv_access"
 #define KEY_NOTE_CHANNEL_ACCESS "channel_access"
@@ -275,12 +279,13 @@ static const struct message_entry msgtab[] = {
     { "CSMSG_SET_PUBCMD",        "$bPubCmd      $b %d" },
     { "CSMSG_SET_SETTERS",       "$bSetters     $b %d" },
     { "CSMSG_SET_CTCPUSERS",     "$bCTCPUsers   $b %d" },
+    { "CSMSG_SET_VOICE",         "$bvoice       $b %d - %s" },
     { "CSMSG_SET_PROTECT",       "$bProtect     $b %d - %s" },
     { "CSMSG_SET_TOYS",          "$bToys        $b %d - %s" },
     { "CSMSG_SET_CTCPREACTION",  "$bCTCPReaction$b %d - %s" },
     { "CSMSG_SET_TOPICREFRESH",  "$bTopicRefresh$b %d - %s" },
-    { "CSMSG_USET_NOAUTOOP",     "$bNoAutoOp    $b %s" },
-    { "CSMSG_USET_NOAUTOVOICE",  "$bNoAutoVoice $b %s" },
+    { "CSMSG_USET_AUTOOP",       "$bAutoOp      $b %s" },
+    { "CSMSG_USET_AUTOVOICE",    "$bAutoVoice   $b %s" },
     { "CSMSG_USET_AUTOINVITE",   "$bAutoInvite  $b %s" },
     { "CSMSG_USET_INFO",         "$bInfo        $b %s" },
 
@@ -294,6 +299,9 @@ static const struct message_entry msgtab[] = {
     { "CSMSG_DEHALFOPPED_USERS", "DeHalfopped users in $b%s$b." },
     { "CSMSG_VOICED_USERS", "Voiced users in $b%s$b." },
     { "CSMSG_DEVOICED_USERS", "Devoiced users in $b%s$b." },
+    { "CSMSG_VOICE_NONE", "Noone will be auto-voiced" },
+    { "CSMSG_VOICE_PEON", "PEONs will be auto-voiced" },
+    { "CSMSG_VOICE_ALL", "Everyone will be auto-voiced" },
     { "CSMSG_PROTECT_ALL", "Non-users and users will be protected from those of equal or lower access." },
     { "CSMSG_PROTECT_EQUAL", "Users will be protected from those of equal or lower access." },
     { "CSMSG_PROTECT_LOWER", "Users will be protected from those of lower access." },
@@ -622,7 +630,11 @@ static const struct {
 struct charOptionValues {
     char value;
     char *format_name;
-} protectValues[] = {
+} voiceValues[] = {
+    { 'n', "CSMSG_VOICE_NONE" },
+    { 'p', "CSMSG_VOICE_PEON" },
+    { 'a', "CSMSG_VOICE_ALL" }
+}, protectValues[] = {
     { 'a', "CSMSG_PROTECT_ALL" },
     { 'e', "CSMSG_PROTECT_EQUAL" },
     { 'l', "CSMSG_PROTECT_LOWER" },
@@ -652,8 +664,9 @@ static const struct {
     unsigned char count;
     struct charOptionValues *values;
 } charOptions[] = {
-    { "CSMSG_SET_PROTECT", "protect", 'l', 0, ArrayLength(protectValues), protectValues },
-    { "CSMSG_SET_TOYS", "toys", 'p', 6, ArrayLength(toysValues), toysValues },
+    { "CSMSG_SET_VOICE",        "voice",        'p', 99, ArrayLength(voiceValues), voiceValues },
+    { "CSMSG_SET_PROTECT",      "protect",      'l', 0, ArrayLength(protectValues), protectValues },
+    { "CSMSG_SET_TOYS",         "toys",         'p', 6, ArrayLength(toysValues), toysValues },
     { "CSMSG_SET_TOPICREFRESH", "topicrefresh", 'n', 8, ArrayLength(topicRefreshValues), topicRefreshValues },
     { "CSMSG_SET_CTCPREACTION", "ctcpreaction", 't', 10, ArrayLength(ctcpReactionValues), ctcpReactionValues }
 };
@@ -662,6 +675,9 @@ struct userData *helperList;
 struct chanData *channelList;
 static struct module *chanserv_module;
 static unsigned int userCount;
+unsigned int chanserv_read_version = 0; /* db version control */
+
+#define CHANSERV_DB_VERSION 2
 
 #define GetChannelUser(channel, handle) _GetChannelUser(channel, handle, 1, 0)
 #define GetChannelAccess(channel, handle) _GetChannelUser(channel, handle, 0, 0)
@@ -1169,6 +1185,7 @@ add_channel_user(struct chanData *channel, struct handle_info *handle, unsigned
         ud->u_next->u_prev = ud;
     ud->handle->channels = ud;
 
+    ud->flags = USER_FLAGS_DEFAULT;
     return ud;
 }
 
@@ -2636,7 +2653,7 @@ static CHANSERV_FUNC(cmd_up)
         change.args[0].mode = MODE_HALFOP;
         errmsg = "CSMSG_ALREADY_HALFOPPED";
     }
-    else if(uData->access >= UL_PEON /* channel->channel_info->lvlOpts[lvlGiveVoice]*/)
+    else if(uData->access >= UL_PEON && (channel->channel_info->chOpts[chVoice] == 'p' || channel->channel_info->chOpts[chVoice] == 'a'))
     {
         change.args[0].mode = MODE_VOICE;
         errmsg = "CSMSG_ALREADY_VOICED";
@@ -3342,7 +3359,7 @@ static CHANSERV_FUNC(cmd_myaccess)
             continue;
         sbuf.used = 0;
         string_buffer_append_printf(&sbuf, "[%s (%d", cData->channel->name, uData->access);
-        if(uData->flags != USER_AUTO_OP)
+        if(uData->flags == USER_AUTO_OP)
             string_buffer_append(&sbuf, ',');
         if(IsUserSuspended(uData))
             string_buffer_append(&sbuf, 's');
@@ -5422,6 +5439,11 @@ channel_multiple_option(enum charOption option, struct userNode *user, struct ch
     return 1;
 }
 
+static MODCMD_FUNC(chan_opt_voice)
+{
+    return channel_multiple_option(chVoice, CSFUNC_ARGS);
+}
+
 static MODCMD_FUNC(chan_opt_protect)
 {
     return channel_multiple_option(chProtect, CSFUNC_ARGS);
@@ -5543,7 +5565,7 @@ user_binary_option(char *name, unsigned long mask, struct userNode *user, struct
     return 1;
 }
 
-static MODCMD_FUNC(user_opt_noautoop)
+static MODCMD_FUNC(user_opt_autoop)
 {
     struct userData *uData;
 
@@ -5554,9 +5576,9 @@ static MODCMD_FUNC(user_opt_noautoop)
         return 0;
     }
     if(uData->access < UL_OP /*channel->channel_info->lvlOpts[lvlGiveOps]*/)
-        return user_binary_option("CSMSG_USET_NOAUTOVOICE", USER_AUTO_OP, CSFUNC_ARGS);
+        return user_binary_option("CSMSG_USET_AUTOVOICE", USER_AUTO_OP, CSFUNC_ARGS);
     else
-        return user_binary_option("CSMSG_USET_NOAUTOOP", USER_AUTO_OP, CSFUNC_ARGS);
+        return user_binary_option("CSMSG_USET_AUTOOP", USER_AUTO_OP, CSFUNC_ARGS);
     /* TODO: add halfops error message? or is the op one generic enough? */
 }
 
@@ -5623,7 +5645,7 @@ static CHANSERV_FUNC(cmd_uset)
     {
         char *options[] =
         {
-            "NoAutoOp", "AutoInvite", "Info"
+            "AutoOp", "AutoInvite", "Info"
         };
 
         if(!uset_shows_list.size)
@@ -6168,16 +6190,12 @@ handle_join(struct modeNode *mNode)
 
     if(channel->join_flooded)
     {
-        /* don't automatically give ops or voice during a join flood */
+        /* don't automatically give non users ops or voice during a join flood */
     }
-    /* I don't understand why we do this, so im removing it -rubin *
-    else if(cData->lvlOpts[lvlGiveOps] == 0)
-        modes |= MODE_CHANOP;
-    else if(cData->lvlOpts[lvlGiveHalfOps] == 0)
-        modes |= MODE_HALFOP;
-    else if(cData->lvlOpts[lvlGiveVoice] == 0)
+    /* EVERYONE is to get voice */
+    else if(cData->chOpts[chVoice] == 'a')
         modes |= MODE_VOICE;
-    */
+
     greeting = cData->greeting;
     if(user->handle_info)
     {
@@ -6199,14 +6217,14 @@ handle_join(struct modeNode *mNode)
         uData = GetTrueChannelAccess(cData, handle);
         if(uData && !IsUserSuspended(uData))
         {
-            /* Ops and above were handled by the above case. */
+            /* non users getting voice are handled above. */
             if(IsUserAutoOp(uData))
             {
                 if(uData->access >= UL_OP /*cData->lvlOpts[lvlGiveOps]*/)
                     modes |= MODE_CHANOP;
                 if(uData->access >= UL_HALFOP /*cData->lvlOpts[lvlGiveHalfOps]*/)
                     modes |= MODE_HALFOP;
-                else if(uData->access >= UL_PEON /* cData->lvlOpts[lvlGiveVoice] */)
+                else if(uData->access >= UL_PEON && cData->chOpts[chVoice] == 'p')
                     modes |= MODE_VOICE;
             }
             if(uData->access >= UL_PRESENT)
@@ -6848,6 +6866,18 @@ user_read_helper(const char *key, struct record_data *rd, struct chanData *chan)
 
     uData = add_channel_user(chan, handle, access, last_seen, inf);
     uData->flags = flags ? strtoul(flags, NULL, 0) : 0;
+
+    /* Upgrade: set autoop to the inverse of noautoop */
+    if(chanserv_read_version < 2)
+    {
+        /* if noautoop is true, set autoop false, and vice versa */
+        if(uData->flags & USER_NOAUTO_OP)
+            uData->flags = uData->flags & ~USER_AUTO_OP;
+        else
+            uData->flags = uData->flags | USER_AUTO_OP;
+        log_module(CS_LOG, LOG_INFO, "UPGRADE: to db version 2 from %u. Changing flag to %d for %s in %s.", chanserv_read_version, uData->flags, key, chan->channel->name);
+    }
+    
 }
 
 static void
@@ -7148,12 +7178,26 @@ chanserv_dnr_read(const char *key, struct record_data *hir)
         dnr->set = 0;
 }
 
+static void
+chanserv_version_read(struct dict *section)
+{
+    /* global var.. */
+    char *str;
+    str = database_get_data(section, KEY_VERSION_NUMBER, RECDB_QSTRING);
+    if(str)
+       chanserv_read_version = atoi(str);
+    log_module(CS_LOG, LOG_DEBUG, "Chanserv db version is %d.", chanserv_read_version);
+}
+
 static int
 chanserv_saxdb_read(struct dict *database)
 {
     struct dict *section;
     dict_iterator_t it;
 
+    if((section = database_get_data(database, KEY_VERSION_CONTROL, RECDB_OBJECT)))
+        chanserv_version_read(section);
+
     if((section = database_get_data(database, KEY_NOTE_TYPES, RECDB_OBJECT)))
         for(it = dict_first(section); it; it = iter_next(it))
             chanserv_note_type_read(iter_key(it), iter_data(it));
@@ -7352,6 +7396,11 @@ chanserv_saxdb_write(struct saxdb_context *ctx)
     dict_iterator_t it;
     struct chanData *channel;
 
+    /* Version Control*/
+    saxdb_start_record(ctx, KEY_VERSION_CONTROL, 1);
+      saxdb_write_int(ctx, KEY_VERSION_NUMBER, CHANSERV_DB_VERSION);
+    saxdb_end_record(ctx);
+
     /* Notes */
     saxdb_start_record(ctx, KEY_NOTE_TYPES, 1);
     for(it = dict_first(note_types); it; it = iter_next(it))
@@ -7544,6 +7593,7 @@ init_chanserv(const char *nick)
     /*DEFINE_CHANNEL_OPTION(giveops);
     DEFINE_CHANNEL_OPTION(givehalfops);
     */
+    DEFINE_CHANNEL_OPTION(voice);
     DEFINE_CHANNEL_OPTION(protect);
     DEFINE_CHANNEL_OPTION(enfmodes);
     DEFINE_CHANNEL_OPTION(enftopic);
@@ -7568,12 +7618,12 @@ init_chanserv(const char *nick)
     modcmd_register(chanserv_module, "set topic", chan_opt_defaulttopic, 1, 0, NULL);
 
     /* User options */
-    DEFINE_USER_OPTION(noautoop);
     DEFINE_USER_OPTION(autoinvite);
     DEFINE_USER_OPTION(info);
+    DEFINE_USER_OPTION(autoop);
 
     /* Alias uset autovoice to uset autoop. */
-    modcmd_register(chanserv_module, "uset noautovoice", user_opt_noautoop, 1, 0, NULL);
+    modcmd_register(chanserv_module, "uset autovoice", user_opt_autoop, 1, 0, NULL);
 
     note_types = dict_new();
     dict_set_free_data(note_types, chanserv_deref_note_type);
@@ -7584,6 +7634,7 @@ init_chanserv(const char *nick)
         service_register(chanserv)->trigger = '!';
         reg_chanmsg_func('\001', chanserv, chanserv_ctcp_check);
     }
+
     saxdb_register("ChanServ", chanserv_saxdb_read, chanserv_saxdb_write);
 
     if(chanserv_conf.channel_expire_frequency)
index 877272c4b44a804d380312cb8001a11f4edb0dff..657cf63d6eac5015fd317a3ab70abf8110fad454 100644 (file)
@@ -53,6 +53,7 @@ enum levelOption {
 };
 
 enum charOption {
+    chVoice,
     chProtect,
     chToys,
     chTopicRefresh,
@@ -113,12 +114,14 @@ struct chanData
     struct chanData    *next;
 };
 
-#define USER_AUTO_OP            0x00000001
+#define USER_NOAUTO_OP          0x00000001 /* OLD; Not used at all.. */
 #define USER_SUSPENDED          0x00000002
 #define USER_AUTO_INVITE        0x00000004
-#define USER_FLAGS_SIZE         7
+#define USER_AUTO_OP            0x00000008
+#define USER_FLAGS_SIZE         15
+#define USER_FLAGS_DEFAULT      USER_AUTO_OP
 
-#define IsUserAutoOp(USER)      (!((USER)->flags & USER_AUTO_OP))
+#define IsUserAutoOp(USER)      ((USER)->flags & USER_AUTO_OP)
 #define IsUserSuspended(USER)   ((USER)->flags & USER_SUSPENDED)
 #define IsUserAutoInvite(USER)  ((USER)->flags & USER_AUTO_INVITE)
 
index b8447bb17217630378b63413d6e607e782dd72cc..baf27398d4192f515652d3e2b73b1fa09331499a 100644 (file)
         "SETTERS:      Who may change channel settings (using $bSET$b).",
         "CTCPUSERS:    Who is allowed to send CTCPs to the channel.",
         "CTCPREACTION: What happens when a disallowed CTCP is sent to the channel.",
+        "VOICE:        Who should be auto-voiced in the channel.",
         "PROTECT:      The protection level $b$C$b provides.",
        "TOYS:         Toggles how $b$C$b will respond to toy commands (!8ball etc).",
         "TOPICREFRESH: Controls if (and how often) $b$C$b will reset the topic.",
         "If a topic mask is set, then a person may change the topic as long as it matches that mask $bor$b they have the above access.",
         "If no topic mask is set, then a person must have the above access to change the topic from the default.",
         "$uSee Also:$u set, set topic, set topicmask");
+"SET VOICE" ("/msg $C SET <#channel> VOICE <value>",
+        "This setting configures who $C auto-voices.  Valid settings are:",
+        "$b0$b  Noone will get voice",
+        "$b1$b  PEONs will get voice (default).",
+        "$b2$b  Everyone will get voice.",
+        "$uSee Also:$u set, uset autoop");
 "SET PROTECT" ("/msg $C SET <#channel> PROTECT <value>",
         "This setting restricts the protection that $C enforces.  Valid settings are:",
         "$b0$b  Non-users and users will be protected from those of equal or lower access",
          "The $buset$b command allows you to toggle various channel user settings. With no arguments, it will print the current values of all channel user options.",
          "$bOptions:$b",
          "INFO:       Sets the infoline that $C sends when you join the channel.",
-         "NOAUTOOP:   Enable or disable $C automatically opping you upon joining or authenticating.",
+         "AUTOOP:     Enable or disable $C automatically opping you upon joining or authenticating.",
         "AUTOINVITE: $C will invite you to this channel if you have access to and are not in when you authenticate if this setting is on.",
-         "NOTE: The NoAutoOp setting is equivalent to the !togop command in previous versions of X3.",
          "$uSee Also:$u set");
 "USET INFO" ("/msg $C USET <#channel> INFO <info>",
         "This command will set a user defined information message to be displayed when you join the channel. Set to '*' to clear the message.",
index 74555883823ecb99d005d6a49e8f164598487aa4..df203a778eead506815dfc25634d3090c1fd7a12 100644 (file)
@@ -47,7 +47,7 @@
 #define MODE_OPERSONLY          0x00080000 /* +O Opers only */
 #define MODE_NOQUITMSGS         0x00100000 /* +Q suppress messages from quit notices */
 #define MODE_NOAMSG             0x00200000 /* +T no multi-target messages */
-#define MODE_SSLONLY            0x00400000 /* +z ssl only */
+#define MODE_SSLONLY            0x00400000 /* +Z ssl only */
 #define MODE_HALFOP             0x00800000 /* +h USER */
 #define MODE_EXEMPT             0x01000000 /* +e exempt */
 #define MODE_REMOVE             0x80000000
index 9870e0309a199c46aa0298af4c8277498acaf556..a7611328dcbc5dd60ab8cfdb8227019bd8f57b94 100644 (file)
@@ -1,12 +1,35 @@
-"bind" ("/msg $S BIND <service> <bindname> <command> [additional args..]",
-        "Binds (adds) a command to an existing service.  $bbindname$b is the name of the new command for the service.  $bcommand$b may be one of:",
-        "  CommandName              To refer to a command on the same service.",
-        "  ServiceNick.CommandName  To refer to a command bound on a different service such as $O, $C, $N, etc.",
-        "  *ModuleName.CommandName  To bind a command directly from a module (note the asterisk before the module name).",
-        "  *ModuleName.*            To bind all commands from the named module, where ModuleName is one of OpServ, NickServ, ChanServ, modcmd, or others.",
-        "For simplicity, you cannot bind to a command that is itself an alias.  Certain commands will not bound with the last form; you must bind them by name.",
-        "(A command binding is very similar to an alias, but only pays the speed penalty for alias expansion when there are additional arguments in the binding.)",
-        "If you want to be able to bind $bfoo bar$b as a command, you need to bind $bfoo$b to modcmd.joiner first.",
+"bind" ("/msg $S BIND <ServiceNick> <BindName> [Nick|*Module.]<Command> [Arg [Arg[..]]]",
+        "Bind creates a command.  ",
+        "  $bServiceNick$b is which service the new command will work on.",
+        "  $bBindName$b is the name of the new command you are making.",
+        "  $bCommand$b  To refer to a command on the same service.",
+        "  $bNick$b     To refer to a command on a different ",
+        "           service such as $O, $C, $N, etc.",
+        "  $b*Module$b  To bind a command directly from a module such as",
+        "           ChanServ, OpServ, NickServ, modcmd, etc",
+        "           (note the asterisk before the module name).",
+        "  $barg(s)$b   Can be anything, or you can use $$1 $$2 $$3 etc",
+        "           which will be replaced with the arguments passed",
+        "           to the command. Use a - after ($$2-) to indicate",
+        "           that argument and all arguments after it.",
+        "$b$b",
+        "There is a special case to load ALL commands from a module:",
+        "/msg $S bind <serviceNick> * *<Module>.*   ",
+        "       You may need to run this after installing previously",
+        "       missing modules, or making changes such as enabling",
+        "       the email features, so all the commands are bound.",
+        "       Note: Certain(??) commands will not bind this way; ",
+        "       you must bind them by name.",
+        "$b$b",
+        "For simplicity, you cannot bind to a command that is an alias.",
+        "$b$b",
+        "If you want to bind $bfoo bar$b as a command, bind $bfoo$b to $b*modcmd.joiner$b first, unless foo is a builtin command such as uset, in which case use '\\' to escape the space (example: $bbind x3 uset\ autoop x3.uset\ autoop$b)",
+        "$b$b",
+        "$uExamples$u",
+        "  bind X3 autoop *chanserv.uset\\ autoop",
+        "  bind O3 murder o3.trace gline nick $$1 duration 1m reason $$2-",
+        "  bind X3 * *chanserv.*",
+        "$b$b",
         "$uSee also:$u unbind, joiner");
 
 "commands" "${index}";
index 0393b069c90835006ee6ad602b23efc86218dfb4..d2a625fe231a96935240ce3ce26418938ff714c0 100644 (file)
@@ -2237,6 +2237,7 @@ mod_chanmode_parse(struct chanNode *channel, char **modes, unsigned int argc, un
         case 'Q': do_chan_mode(MODE_NOQUITMSGS); break;
         case 'T': do_chan_mode(MODE_NOAMSG); break;
         case 'O': do_chan_mode(MODE_OPERSONLY); break;
+        case 'Z': do_chan_mode(MODE_SSLONLY); break;
        case 'z':
          if (!(flags & MCP_REGISTERED)) {
           do_chan_mode(MODE_REGISTERED);
@@ -2414,8 +2415,7 @@ mod_chanmode_announce(struct userNode *who, struct chanNode *channel, struct mod
         DO_MODE_CHAR(NOAMSG, 'T');
         DO_MODE_CHAR(OPERSONLY, 'O');
         DO_MODE_CHAR(REGISTERED, 'z');
-        // uncomment this for ssl support
-        //DO_MODE_CHAR(SSLONLY, 'Z');
+        DO_MODE_CHAR(SSLONLY, 'Z');
 #undef DO_MODE_CHAR
         if (change->modes_clear & channel->modes & MODE_KEY)
             mod_chanmode_append(&chbuf, 'k', channel->key);
@@ -2466,8 +2466,7 @@ mod_chanmode_announce(struct userNode *who, struct chanNode *channel, struct mod
         DO_MODE_CHAR(NOAMSG, 'T');
         DO_MODE_CHAR(OPERSONLY, 'O');
         DO_MODE_CHAR(REGISTERED, 'z');
-        // uncomment this for ssl support
-        //DO_MODE_CHAR(SSLONLY, 'Z');
+        DO_MODE_CHAR(SSLONLY, 'Z');
 #undef DO_MODE_CHAR
         if(change->modes_set & MODE_KEY)
             mod_chanmode_append(&chbuf, 'k', change->new_key);
@@ -2535,8 +2534,7 @@ mod_chanmode_format(struct mod_chanmode *change, char *outbuff)
         DO_MODE_CHAR(NOAMSG, 'T');
         DO_MODE_CHAR(OPERSONLY, 'O');
         DO_MODE_CHAR(REGISTERED, 'z');
-        // uncomment this for ssl support
-        //DO_MODE_CHAR(SSLONLY, 'Z');
+        DO_MODE_CHAR(SSLONLY, 'Z');
 #undef DO_MODE_CHAR
     }
     if (change->modes_set) {
@@ -2559,8 +2557,7 @@ mod_chanmode_format(struct mod_chanmode *change, char *outbuff)
         DO_MODE_CHAR(NOAMSG, 'T');
         DO_MODE_CHAR(OPERSONLY, 'O');
         DO_MODE_CHAR(REGISTERED, 'z');
-        // uncomment this for ssl support
-        //DO_MODE_CHAR(SSLONLY, 'Z');
+        DO_MODE_CHAR(SSLONLY, 'Z');
 #undef DO_MODE_CHAR
         switch (change->modes_set & (MODE_KEY|MODE_LIMIT)) {
         case MODE_KEY|MODE_LIMIT:
@@ -2615,6 +2612,7 @@ clear_chanmode(struct chanNode *channel, const char *modes)
         case 'T': remove |= MODE_NOAMSG; break;
         case 'O': remove |= MODE_OPERSONLY; break;
         case 'z': remove |= MODE_REGISTERED; break;
+        case 'Z': remove |= MODE_SSLONLY; break;
         }
     }