Index: include/channel_mode.h
===================================================================
--- include/channel_mode.h	(revision 735)
+++ include/channel_mode.h	(working copy)
@@ -55,6 +55,7 @@
 #define MODE_TOPICLIMIT 0x0008
 #define MODE_INVITEONLY 0x0010
 #define MODE_NOPRIVMSGS 0x0020
+#define MODE_SSLONLY    0x0020
 
 /* cache flags for silence on ban */
 #define CHFL_BAN_CHECKED  0x0080
Index: include/numeric.h
===================================================================
--- include/numeric.h	(revision 735)
+++ include/numeric.h	(working copy)
@@ -382,6 +382,7 @@
 /* 	ERR_LINKFAIL	     479	unreal */
 /*	ERR_CANNOTKNOCK	     480	unreal */
 /*	ERR_NOULINE	     480	austnet */
+#define ERR_SSLONLYCHAN      480
 #define ERR_NOPRIVILEGES     481
 #define ERR_CHANOPRIVSNEEDED 482
 #define ERR_CANTKILLSERVER   483
Index: src/channel_mode.c
===================================================================
--- src/channel_mode.c	(revision 735)
+++ src/channel_mode.c	(working copy)
@@ -282,6 +282,7 @@
   { MODE_PARANOID,   'p' },
   { MODE_SECRET,     's' },
   { MODE_TOPICLIMIT, 't' },
+  { MODE_SSLONLY,    'S' },
   { 0, '\0' }
 };
 
@@ -1257,7 +1258,7 @@
   {chm_nosuch, NULL},                             /* P */
   {chm_nosuch, NULL},                             /* Q */
   {chm_nosuch, NULL},                             /* R */
-  {chm_nosuch, NULL},                             /* S */
+  {chm_simple, MODE_SSLONLY},                     /* S */
   {chm_nosuch, NULL},                             /* T */
   {chm_nosuch, NULL},                             /* U */
   {chm_nosuch, NULL},                             /* V */
Index: src/messages.tab
===================================================================
--- src/messages.tab	(revision 735)
+++ src/messages.tab	(working copy)
@@ -504,7 +504,7 @@
 /* 477 */  {NULL, NULL, NULL},
 /* 478 */  {"ERR_BANLISTFULL", ":%s 478 %s %s %s :Channel ban list is full", NULL},
 /* 479 */  {"ERR_BADCHANNAME", ":%s 479 %s %s :Illegal channel name", NULL},
-/* 480 */  {NULL, NULL, NULL},
+/* 480 */  {"ERR_SSLONLYCHAN", ":%s 480 %s %s :Channot join channel (+S)", NULL},
 /* 481 */  {"ERR_NOPRIVILEGES", ":%s 481 %s :Permission Denied - You're not an IRC operator", NULL},
 /* 482 */  {"ERR_CHANOPRIVSNEEDED", ":%s 482 %s %s :You're not channel operator", NULL},
 /* 483 */  {"ERR_CANTKILLSERVER", ":%s 483 %s :You can't kill a server!", NULL},
Index: modules/core/m_sjoin.c
===================================================================
--- modules/core/m_sjoin.c	(revision 735)
+++ modules/core/m_sjoin.c	(working copy)
@@ -160,6 +160,9 @@
       case 'p':
         mode.mode |= MODE_PARANOID;
         break;
+      case 'S':
+        mode.mode |= MODE_SSLONLY;
+        break;
       case 'k':
         strlcpy(mode.key, parv[4 + args], sizeof(mode.key));
         args++;
@@ -616,7 +619,8 @@
   { MODE_SECRET,     's' },
   { MODE_MODERATED,  'm' },
   { MODE_INVITEONLY, 'i' },
-  { MODE_PARANOID,    'p' },
+  { MODE_PARANOID,   'p' },
+  { MODE_SSLONLY,    'S' },
   { 0, '\0' }
 };
 
Index: modules/core/m_join.c
===================================================================
--- modules/core/m_join.c	(revision 735)
+++ modules/core/m_join.c	(working copy)
@@ -80,6 +80,12 @@
   if (is_banned(chptr, source_p))
    return ERR_BANNEDFROMCHAN;
 
+#ifdef HAVE_LIBCRYPTO
+  if ((chptr->mode.mode & MODE_SSLONLY) &&
+      !(source_p->localClient->fd.ssl))
+    return ERR_SSLONLYCHAN;
+#endif
+      
   if (chptr->mode.mode & MODE_INVITEONLY)
     if (!dlinkFind(&source_p->localClient->invited, chptr))
       if (!ConfigChannel.use_invex || !find_bmask(source_p, &chptr->invexlist))
@@ -387,6 +393,9 @@
       case 'p':
         mode.mode |= MODE_PARANOID;
         break;
+      case 'S':
+        mode.mode |= MODE_SSLONLY;
+        break;
       case 'k':
         if (parc < 5 + args)
           return;
@@ -556,6 +565,7 @@
   { MODE_MODERATED,  'm' },
   { MODE_INVITEONLY, 'i' },
   { MODE_PARANOID,   'p' },
+  { MODE_SSLONLY,    'S' },
   { 0, '\0' }
 };
 

