*** News 10/06/2021 -- EPIC5-2.1.6 (1981 - Impignorate) released Here

*** News 09/21/2021 -- Another round of clang static analysis
        Somewhere around here we did another round of static analysis
        with clang's analyzer, and fixed whatever it recommended.

*** News 09/19/2021 -- "reconnect" script has been reimplemented
        The reconnect script has been renamed to "reconnect.orig".
        If you want the original behavior, just /load reconnect.orig
        The new script is based on improvements we've made in epic5
        to make reconnection logic more reliable and dependable.

*** News 09/11/2021 -- New option,  $serverctl(GET x PADDR)
        The $serverctl(GET x PADDR) returns the server's presentation
        address.  This is "1.2.3.4" for ipv4, or "2600::1" for ipv6.
        This represents the IP address we're connected to.

*** News 09/11/2021 -- New /window operation, /WINDOW CLEARREGEX <regex>
        This was requested by Zlonix.

        The /WINDOW CLEARREGEX <regex> operation removes all items from
        the window's lastlog whose text (what you see on the screen)
        matches the <regex>.  Removing them from the lastlog removes
        them from the scrollback and your screen as well.  This is useful
        for making conversations with annoying bots go away retroactively.
        Example:        /window clearregex annoybot

*** News 09/11/2021 -- New /ON, /ON RECONNECT_REQUIRED
        The /ON RECONNECT_REQUIRED hook is thrown by the client when it
        feels that a reconnection intervention is appropriate.
        We are going to start this small, and build in more use cases
        as we go forward.

          1. When server is in ACTIVE state and the socket dies
          2. When a write to the server fails

        In these situations, your script should take whatever measures
        are necessary to save the state of windows, channels, etc,
        in preparation for the upcoming disconnection.

        This /ON is thrown while the server is in a state of chaos.
        The internal state of the system is wrong, and you must assume
        that the connection to the server has already been lost.

        YOU MUST _*_*_NOT_*_*_ try to do anything clever in this /on.
        If you have this idea of moving windows or servers or channels,
        please don't!  I recommend setting up /timer's and /defer's so
        you can do those sorts of changes away from the blast radius.

        YOU MUST _*_*_NEVER_*_*_ attempt to do any direct intervention
        in this /on -- instead, you should save information and create
        a timer to deal with the problem later.  YOU HAVE BEEN WARNED.

        /ON RECONNECT_REQUIRED currently provides this information
                $0      The server that unexpected failed on us.
                        Reconnection will be required.  Remember,
                        you cannot do reconnection in the /on, you
                        have to schedule it to happen "later"

*** News 09/08/2021 -- New /window operation, /WINDOW CLEARLEVEL [levels]
        This was requested by Zlonix.

        The /WINDOW CLEARLEVEL [levels] operation removes all items from
        the window's lastlog of the levels you specify.  Removing them
        from your lastlog removes them from your screen as well.  This is
        useful for making noise go away retroactively
        Example:        /window clearlevel joins,parts,quits,kicks

*** News 09/08/2021 -- New statement type: block-with-arglist
        The ircII syntax now supports a new statement type, which I'm
        calling a "block with arglist"

                (arglist) {block}

        You could also think of this as an "inline anonymous function".
        For the purposes of the statement, $* is modified by (arglist)
        and then {block} is run.

        Please note there are several caveats to this:
          1. Arglist is not magic, it is syntactic sugar.  So it creates real
             local variables, and those local variables have their ordinary
             scope.  So they will persist after the end of the statement.
          2. The statement only modifies $* during the statement itself.
             So after {block} is run, $* goes back to what it was originally.
          3. Note that this is a *statement* and not a *block* so if you are
             working with something that expects a block, wrap it in {}s to
             create a block.
                if (# == 3) {(arg0, arg1, arg2) {... code ...}}
          4. Arglist processing isn't "free" so doing it in a tight loop will
             be slower than doing it outside of the loop

*** News 09/07/2021 -- Pass window refnum in /ON CHANNEL_LOST
        The /ON CHANNEL_LOST hook now provides the window that a channel
        was in as $2
                $0 - The server refnum of a channel
                $1 - The name of a channel
                $2 - The window refnum of a channel

*** News 09/06/2021 -- Functions for JSON document handling
        Some time ago some new functions appeared for handling
        JSON documents, but they were not documented.  So now
        I am going to document them!

        CONVERTING JSON DOCS TO /ASSIGNS
        --------------------------------
        Syntax:    $json_explode(varbase json-document)

        An example is worth a thousand words:

            $json_explode(e {"one": 1, "two": { "sub1", "hi", "sub2", "bye" })
        will result in three new assigns
                $e[one]         -> 1
                $e[two][sub1]   -> hi
                $e[two][sub2]   -> bye

        CONVERTING ASSIGNS TO JSON DOCS
        -------------------------------
        Syntax:    $json_implode(varbase)

        This converts everything under $varbase[*] into a JSON doc.

        HANDLING ERRORS
        --------------
        If there is an error, $json_error() will tell you about it.

*** News 09/06/2021 -- SSL handling improvements (take 2)
        The other day I posted some info on how the SSL handling has been
        improved.  But then things got revamped again, so I delete the old
        info and am replacing it with this info.

        1) Step one - You connect to an SSL server
         You connect to an irc server doing something like
                /SERVER irc.example.com:6697:type=irc-ssl
         This goes through connect()ing to the server, and then doing an
         SSL_connect() to set up the certificate exchange and TLS negotiation.

        2) Step two - The SSL handshake is completed
         After the SSL_connect() step has completed, we now have a fully
         functioning TLS socket with an SSL certificate.  Before we use the
         TLS socket, we're supposed to verify we trust the SSL certificate,
         to ensure we're talking to who we think we are.

        3) Step three - The client watches the certificate verification
         OpenSSL "verifies" the certificate and the client provides
         a C function to tag along for the ride.  The callback function
         is called every time:
           (1) An error is discovered, or
           (2) There are no (further) errors in a certificate.
         Thus, if a certificate is trusted, it will only report
         "no problems" for each link in the chain.

         This permits the client to trap and categorize every error that
         happens - some certificates have multiple problems!  There are
         three buckets the client uses:
                (1) Self-signed certificates
                (2) Incorrect-hostname certificates
                (3) Any other (serious) error
         The client tracks the "most serious error" (if there is one),
         using the above priorities.

        4) Step four - The cliet offers you /ON SSL_SERVER_CERT
          The client sets $serverctl(SET <refnum> SSL_ACCEPT_CERT -1)
          and then throws /ON SSL_SERVER_CERT.   The use of -1 is on
          purpose so the client can determine whether your /ON handler
          sets it to 0 or 1.

          If your handler does a $serverctl(SET <retval> SSL_ACCEPT_CERT 0|1)
          then that is taken as the final disposition of the handling, and
          nothing further occurs. (ie, it skips the rest of the steps)

          Parameters of /ON SSL_SERVER_CERT
                $0  The fd of the socket
                    (Use $serverctl(FROM_SERVER) to get the server refnum)
                $1  Certificate Subject, url-encoded
                $2  Certificate Issuer, url-encoded
                $3  Bits used in the public key
                $4  OpenSSL error code of the "most serious error"
                        (18 is "Self-signed certificate",
                         62 is "Hostname mismatch",
                         everything else is irregular/bad)
                $5  The SSL regime being used (ie, TLSv1.2)
                $6  The Certificate Hash
                $7  Was there a hostname mismatch?  0 = no error, 1 = error
                $8  Was there a self-signed error?  0 = no error, 1 = error
                $9  Was there another (serious) error?
                        0 = no other error 1 = other error
                $10 Was there any error of any kind?
                        0 = no errors of any kind, 1 = some kind of error

        5) Step five - The client makes a provisional decision
          Next, the client looks at the errors and decides whether
          it thinks the cert is ok.
            * Cert has no errors                   -> ACCEPT
            * Cert has "self signed" or "wrong hostname" error
              and /SET ACCEPT_INVALID_SSL_CERT ON  -> ACCEPT
            * Cert has "self signed" or "wrong hostname" error
              and /SET ACCEPT_INVALID_SSL_CERT OFF -> REJECT
            * Cert has any serious error           -> REJECT
          The client sets this provisional value with
                $serverctl(SET <refnum> SSL_ACCEPT_CERT 0|1)

        6) Step six - The client offers you /ON SERVER_SSL_EVAL
          Then, the client hooks /ON SERVER_SSL_EVAL.  At this point,
          all of the information your script needs to make a fully
          informed decision to accept or overrule the client's choice
          is available.  Your handler is not obligated to make any
          change, but it certainly can if it wants to

          Parameters of /ON SERVER_SSL_EVAL
                $0  The server refnum
                $1  The "ourname" of the server (what you /server'd to)
                $2  Was there any error at all?
                        0 = no errors of any kind   1 = some kind of error
                $3  Was there a hostname mismatch?  0 = no error, 1 = error
                $4  Was there a self-signed error?  0 = no error, 1 = error
                $5  Was there another (serious) error?
                        0 = no other error, 1 = other error
                $6  What does the client suggest?
                        0 = reject certificate, 1 = accept certificate

          Using $serverctl() to get info about the certificate
          Use $serverctl(GET <refnum> <item>) where <item> is:
                SSL_CIPHER              The encryption cipher being used
                SSL_PEM                 The certificate (in PEM format)
                SSL_CERT_HASH           The certificate's hash
                SSL_PKEY_BITS           The bits in the public key
                SSL_SUBJECT             Who the cert was issued to
                SSL_SUBJECT_URL         Who the cert was issued to (url-encoded)
                SSL_ISSUER              Who issued the cert
                SSL_ISSUER_URL          Who issued the cert (url-encoded)
                SSL_VERSION             What version of SSL being used (ie, TLSv1.2)
                SSL_SANS                Subject Alternate Names in the cert
                SSL_CHECKHOST_ERROR     Hostname Mismatch error - 0 (no) 1 (yes)
                SSL_SELF_SIGNED_ERROR   Self-signed error - 0 (no) 1 (yes)
                SSL_OTHER_ERROR         Any other (serious) error - 0 (no) 1 (yes)
                SSL_MOST_SERIOUS_ERROR  The OpenSSL error code of the most serious error
                                        18 (self-signed) and 62 (hostname mismatch)
                                        are considered non-serious (routine) errors
                SSL_VERIFY_ERROR        Any error at all - 0 (no) 1 (yes)
                SSL_ACCEPT_CERT         Is this cert headed for acceptance?  0 (no) 1 (yes)

           Use $serverctl(SET <refnum> SSL_ACCEPT_CERT 0) to reject the cert
           Use $serverctl(SET <refnum> SSL_ACCEPT_CERT 1) to accept the cert
           If you don't do anything, the client will do the most reasonable thing

        7) Step seven - The client moves forward
          Finally, everyone has had a chance to weigh in.
          Whatever the value of $serverctl(GET <refnum> SSL_ACCEPT_CERT)
          is after all this, is used to accept or reject the SSL connection.

*** News 09/02/2021 -- Configuring SSL Ciphers
        Now, if you know what you are doing, you can set
        the SSL Ciphersuites that the client will use for
        SSL connections, via
                /SET SSL_CIPHERS <stuff>
        If you don't know what you're doing, don't touch.
        The default value is "unset", which means we let
        openssl choose the ciphers for us.

*** News 09/02/2021 -- SSL Handling improvements
        [replaced -- see above]

*** News 08/30/2021 -- New server description field "ssl-strict"
        [this feature was removed]

`