├── .gitignore ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── README.md ├── _config.yml ├── _data └── modern.yml ├── _includes ├── c2s_structure.md ├── concepts.md ├── copyrights.html ├── ctcp-appendix.md ├── ietfwarning.html ├── messages │ ├── channel.md │ ├── connection.md │ ├── ircop.md │ ├── messages.md │ ├── optional.md │ ├── server_queries.md │ └── user_queries.md └── modern-appendix.md ├── _layouts └── default.html ├── _plugins ├── easy-ids.rb └── modern-ircdocs.rb ├── about.md ├── css ├── font-awesome.min.css ├── open-sans.css ├── pure-min.css └── screen.sass ├── ctcp.md ├── dcc.md ├── fonts ├── Bold │ ├── OpenSans-Bold.eot │ ├── OpenSans-Bold.svg │ ├── OpenSans-Bold.ttf │ ├── OpenSans-Bold.woff │ └── OpenSans-Bold.woff2 ├── BoldItalic │ ├── OpenSans-BoldItalic.eot │ ├── OpenSans-BoldItalic.svg │ ├── OpenSans-BoldItalic.ttf │ ├── OpenSans-BoldItalic.woff │ └── OpenSans-BoldItalic.woff2 ├── ExtraBold │ ├── OpenSans-ExtraBold.eot │ ├── OpenSans-ExtraBold.svg │ ├── OpenSans-ExtraBold.ttf │ ├── OpenSans-ExtraBold.woff │ └── OpenSans-ExtraBold.woff2 ├── ExtraBoldItalic │ ├── OpenSans-ExtraBoldItalic.eot │ ├── OpenSans-ExtraBoldItalic.svg │ ├── OpenSans-ExtraBoldItalic.ttf │ ├── OpenSans-ExtraBoldItalic.woff │ └── OpenSans-ExtraBoldItalic.woff2 ├── FontAwesome.otf ├── Italic │ ├── OpenSans-Italic.eot │ ├── OpenSans-Italic.svg │ ├── OpenSans-Italic.ttf │ ├── OpenSans-Italic.woff │ └── OpenSans-Italic.woff2 ├── Light │ ├── OpenSans-Light.eot │ ├── OpenSans-Light.svg │ ├── OpenSans-Light.ttf │ ├── OpenSans-Light.woff │ └── OpenSans-Light.woff2 ├── LightItalic │ ├── OpenSans-LightItalic.eot │ ├── OpenSans-LightItalic.svg │ ├── OpenSans-LightItalic.ttf │ ├── OpenSans-LightItalic.woff │ └── OpenSans-LightItalic.woff2 ├── Regular │ ├── OpenSans-Regular.eot │ ├── OpenSans-Regular.svg │ ├── OpenSans-Regular.ttf │ ├── OpenSans-Regular.woff │ └── OpenSans-Regular.woff2 ├── Semibold │ ├── OpenSans-Semibold.eot │ ├── OpenSans-Semibold.svg │ ├── OpenSans-Semibold.ttf │ ├── OpenSans-Semibold.woff │ └── OpenSans-Semibold.woff2 ├── SemiboldItalic │ ├── OpenSans-SemiboldItalic.eot │ ├── OpenSans-SemiboldItalic.svg │ ├── OpenSans-SemiboldItalic.ttf │ ├── OpenSans-SemiboldItalic.woff │ └── OpenSans-SemiboldItalic.woff2 ├── fontawesome-webfont.eot ├── fontawesome-webfont.svg ├── fontawesome-webfont.ttf ├── fontawesome-webfont.woff └── fontawesome-webfont.woff2 ├── formatting.md ├── impl.md ├── index.md ├── info ├── draft-hardy-irc-isupport-00.txt ├── draft-jallnutt-ircv3-unfinished.txt ├── draft-mitchell-irc-capabilities-01.txt ├── rfc1459.txt ├── rfc2810.txt ├── rfc2811.txt ├── rfc2812.txt └── rfc2813.txt └── js └── anchor.min.js /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/windows,osx,linux,jekyll 3 | 4 | ### Windows ### 5 | # Windows image file caches 6 | Thumbs.db 7 | ehthumbs.db 8 | 9 | # Folder config file 10 | Desktop.ini 11 | 12 | # Recycle Bin used on file shares 13 | $RECYCLE.BIN/ 14 | 15 | # Windows Installer files 16 | *.cab 17 | *.msi 18 | *.msm 19 | *.msp 20 | 21 | # Windows shortcuts 22 | *.lnk 23 | 24 | 25 | ### OSX ### 26 | .DS_Store 27 | .AppleDouble 28 | .LSOverride 29 | 30 | # Icon must end with two \r 31 | Icon 32 | 33 | 34 | # Thumbnails 35 | ._* 36 | 37 | # Files that might appear in the root of a volume 38 | .DocumentRevisions-V100 39 | .fseventsd 40 | .Spotlight-V100 41 | .TemporaryItems 42 | .Trashes 43 | .VolumeIcon.icns 44 | 45 | # Directories potentially created on remote AFP share 46 | .AppleDB 47 | .AppleDesktop 48 | Network Trash Folder 49 | Temporary Items 50 | .apdisk 51 | 52 | 53 | ### Linux ### 54 | *~ 55 | 56 | # KDE directory preferences 57 | .directory 58 | 59 | # Linux trash folder which might appear on any partition or disk 60 | .Trash-* 61 | 62 | 63 | ### Jekyll ### 64 | _site/ 65 | .sass-cache/ 66 | .jekyll-metadata 67 | .jekyll-cache 68 | .vscode 69 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem 'jekyll', '~> 4.2' 4 | 5 | gem "jekyll-sitemap", "~> 1.4" 6 | 7 | gem "jekyll-redirect-from", "~> 0.16.0" 8 | gem "jekyll-sass-converter", "~> 2.1" 9 | gem "jekyll-commonmark-ghpages", "~> 0.1.6" 10 | 11 | gem 'jekyll-toc' 12 | 13 | gem "webrick", "~> 1.7" 14 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | addressable (2.8.0) 5 | public_suffix (>= 2.0.2, < 5.0) 6 | colorator (1.1.0) 7 | commonmarker (0.17.13) 8 | ruby-enum (~> 0.5) 9 | concurrent-ruby (1.1.9) 10 | em-websocket (0.5.2) 11 | eventmachine (>= 0.12.9) 12 | http_parser.rb (~> 0.6.0) 13 | eventmachine (1.2.7) 14 | eventmachine (1.2.7-x64-mingw32) 15 | ffi (1.15.3) 16 | forwardable-extended (2.6.0) 17 | http_parser.rb (0.6.0) 18 | i18n (1.8.10) 19 | concurrent-ruby (~> 1.0) 20 | jekyll (4.2.0) 21 | addressable (~> 2.4) 22 | colorator (~> 1.0) 23 | em-websocket (~> 0.5) 24 | i18n (~> 1.0) 25 | jekyll-sass-converter (~> 2.0) 26 | jekyll-watch (~> 2.0) 27 | kramdown (~> 2.3) 28 | kramdown-parser-gfm (~> 1.0) 29 | liquid (~> 4.0) 30 | mercenary (~> 0.4.0) 31 | pathutil (~> 0.9) 32 | rouge (~> 3.0) 33 | safe_yaml (~> 1.0) 34 | terminal-table (~> 2.0) 35 | jekyll-commonmark (1.3.1) 36 | commonmarker (~> 0.14) 37 | jekyll (>= 3.7, < 5.0) 38 | jekyll-commonmark-ghpages (0.1.6) 39 | commonmarker (~> 0.17.6) 40 | jekyll-commonmark (~> 1.2) 41 | rouge (>= 2.0, < 4.0) 42 | jekyll-redirect-from (0.16.0) 43 | jekyll (>= 3.3, < 5.0) 44 | jekyll-sass-converter (2.1.0) 45 | sassc (> 2.0.1, < 3.0) 46 | jekyll-sitemap (1.4.0) 47 | jekyll (>= 3.7, < 5.0) 48 | jekyll-toc (0.17.1) 49 | jekyll (>= 3.9) 50 | nokogiri (~> 1.11) 51 | jekyll-watch (2.2.1) 52 | listen (~> 3.0) 53 | kramdown (2.3.1) 54 | rexml 55 | kramdown-parser-gfm (1.1.0) 56 | kramdown (~> 2.0) 57 | liquid (4.0.3) 58 | listen (3.7.0) 59 | rb-fsevent (~> 0.10, >= 0.10.3) 60 | rb-inotify (~> 0.9, >= 0.9.10) 61 | mercenary (0.4.0) 62 | mini_portile2 (2.8.0) 63 | nokogiri (1.13.9) 64 | mini_portile2 (~> 2.8.0) 65 | racc (~> 1.4) 66 | pathutil (0.16.2) 67 | forwardable-extended (~> 2.6) 68 | public_suffix (4.0.6) 69 | racc (1.6.0) 70 | rb-fsevent (0.11.0) 71 | rb-inotify (0.10.1) 72 | ffi (~> 1.0) 73 | rexml (3.2.5) 74 | rouge (3.26.0) 75 | ruby-enum (0.9.0) 76 | i18n 77 | safe_yaml (1.0.5) 78 | sassc (2.4.0) 79 | ffi (~> 1.9) 80 | sassc (2.4.0-x64-mingw32) 81 | ffi (~> 1.9) 82 | terminal-table (2.0.0) 83 | unicode-display_width (~> 1.1, >= 1.1.1) 84 | unicode-display_width (1.7.0) 85 | webrick (1.7.0) 86 | 87 | PLATFORMS 88 | x64-mingw32 89 | x86_64-linux 90 | 91 | DEPENDENCIES 92 | jekyll (~> 4.2) 93 | jekyll-commonmark-ghpages (~> 0.1.6) 94 | jekyll-redirect-from (~> 0.16.0) 95 | jekyll-sass-converter (~> 2.1) 96 | jekyll-sitemap (~> 1.4) 97 | jekyll-toc 98 | webrick (~> 1.7) 99 | 100 | BUNDLED WITH 101 | 2.2.26 102 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | We are not able to (re)license specifications based on IETF RFCs, or 2 | those that include contributions from other authors. This is mostly due to the 3 | ill-defined copyright status the source documents hold – particularly with 4 | regards to creating derivative works that are intended to become IETF specs at 5 | some point in the future. 6 | 7 | The following license applies to all text that is not derived from prior RFCs. 8 | 9 | --- 10 | 11 | Creative Commons Legal Code 12 | 13 | CC0 1.0 Universal 14 | 15 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 16 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 17 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 18 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 19 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 20 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 21 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 22 | HEREUNDER. 23 | 24 | Statement of Purpose 25 | 26 | The laws of most jurisdictions throughout the world automatically confer 27 | exclusive Copyright and Related Rights (defined below) upon the creator 28 | and subsequent owner(s) (each and all, an "owner") of an original work of 29 | authorship and/or a database (each, a "Work"). 30 | 31 | Certain owners wish to permanently relinquish those rights to a Work for 32 | the purpose of contributing to a commons of creative, cultural and 33 | scientific works ("Commons") that the public can reliably and without fear 34 | of later claims of infringement build upon, modify, incorporate in other 35 | works, reuse and redistribute as freely as possible in any form whatsoever 36 | and for any purposes, including without limitation commercial purposes. 37 | These owners may contribute to the Commons to promote the ideal of a free 38 | culture and the further production of creative, cultural and scientific 39 | works, or to gain reputation or greater distribution for their Work in 40 | part through the use and efforts of others. 41 | 42 | For these and/or other purposes and motivations, and without any 43 | expectation of additional consideration or compensation, the person 44 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 45 | is an owner of Copyright and Related Rights in the Work, voluntarily 46 | elects to apply CC0 to the Work and publicly distribute the Work under its 47 | terms, with knowledge of his or her Copyright and Related Rights in the 48 | Work and the meaning and intended legal effect of CC0 on those rights. 49 | 50 | 1. Copyright and Related Rights. A Work made available under CC0 may be 51 | protected by copyright and related or neighboring rights ("Copyright and 52 | Related Rights"). Copyright and Related Rights include, but are not 53 | limited to, the following: 54 | 55 | i. the right to reproduce, adapt, distribute, perform, display, 56 | communicate, and translate a Work; 57 | ii. moral rights retained by the original author(s) and/or performer(s); 58 | iii. publicity and privacy rights pertaining to a person's image or 59 | likeness depicted in a Work; 60 | iv. rights protecting against unfair competition in regards to a Work, 61 | subject to the limitations in paragraph 4(a), below; 62 | v. rights protecting the extraction, dissemination, use and reuse of data 63 | in a Work; 64 | vi. database rights (such as those arising under Directive 96/9/EC of the 65 | European Parliament and of the Council of 11 March 1996 on the legal 66 | protection of databases, and under any national implementation 67 | thereof, including any amended or successor version of such 68 | directive); and 69 | vii. other similar, equivalent or corresponding rights throughout the 70 | world based on applicable law or treaty, and any national 71 | implementations thereof. 72 | 73 | 2. Waiver. To the greatest extent permitted by, but not in contravention 74 | of, applicable law, Affirmer hereby overtly, fully, permanently, 75 | irrevocably and unconditionally waives, abandons, and surrenders all of 76 | Affirmer's Copyright and Related Rights and associated claims and causes 77 | of action, whether now known or unknown (including existing as well as 78 | future claims and causes of action), in the Work (i) in all territories 79 | worldwide, (ii) for the maximum duration provided by applicable law or 80 | treaty (including future time extensions), (iii) in any current or future 81 | medium and for any number of copies, and (iv) for any purpose whatsoever, 82 | including without limitation commercial, advertising or promotional 83 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 84 | member of the public at large and to the detriment of Affirmer's heirs and 85 | successors, fully intending that such Waiver shall not be subject to 86 | revocation, rescission, cancellation, termination, or any other legal or 87 | equitable action to disrupt the quiet enjoyment of the Work by the public 88 | as contemplated by Affirmer's express Statement of Purpose. 89 | 90 | 3. Public License Fallback. Should any part of the Waiver for any reason 91 | be judged legally invalid or ineffective under applicable law, then the 92 | Waiver shall be preserved to the maximum extent permitted taking into 93 | account Affirmer's express Statement of Purpose. In addition, to the 94 | extent the Waiver is so judged Affirmer hereby grants to each affected 95 | person a royalty-free, non transferable, non sublicensable, non exclusive, 96 | irrevocable and unconditional license to exercise Affirmer's Copyright and 97 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 98 | maximum duration provided by applicable law or treaty (including future 99 | time extensions), (iii) in any current or future medium and for any number 100 | of copies, and (iv) for any purpose whatsoever, including without 101 | limitation commercial, advertising or promotional purposes (the 102 | "License"). The License shall be deemed effective as of the date CC0 was 103 | applied by Affirmer to the Work. Should any part of the License for any 104 | reason be judged legally invalid or ineffective under applicable law, such 105 | partial invalidity or ineffectiveness shall not invalidate the remainder 106 | of the License, and in such case Affirmer hereby affirms that he or she 107 | will not (i) exercise any of his or her remaining Copyright and Related 108 | Rights in the Work or (ii) assert any associated claims and causes of 109 | action with respect to the Work, in either case contrary to Affirmer's 110 | express Statement of Purpose. 111 | 112 | 4. Limitations and Disclaimers. 113 | 114 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 115 | surrendered, licensed or otherwise affected by this document. 116 | b. Affirmer offers the Work as-is and makes no representations or 117 | warranties of any kind concerning the Work, express, implied, 118 | statutory or otherwise, including without limitation warranties of 119 | title, merchantability, fitness for a particular purpose, non 120 | infringement, or the absence of latent or other defects, accuracy, or 121 | the present or absence of errors, whether or not discoverable, all to 122 | the greatest extent permissible under applicable law. 123 | c. Affirmer disclaims responsibility for clearing rights of other persons 124 | that may apply to the Work or any use thereof, including without 125 | limitation any person's Copyright and Related Rights in the Work. 126 | Further, Affirmer disclaims responsibility for obtaining any necessary 127 | consents, permissions or other rights required for any use of the 128 | Work. 129 | d. Affirmer understands and acknowledges that Creative Commons is not a 130 | party to this document and has no duty or obligation with respect to 131 | this CC0 or use of the Work. 132 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Modern IRC Documents 2 | 3 | This site contains documents describing the IRC protocol and related technologies. The documents hosted here are intended to be useful to software developers working with IRC. 4 | 5 | * [Modern IRC Client Protocol](http://modern.ircdocs.horse/) document 6 | * [IRC Formatting](http://modern.ircdocs.horse/formatting.html) document 7 | * [Client-to-Client Protocol (CTCP)](http://modern.ircdocs.horse/ctcp.html) document 8 | 9 | For suggestions of other documents to create / maintain, please [create an issue](https://github.com/ircdocs/modern-irc/issues) or [send me an email](mailto:daniel@danieloaks.net)! 10 | 11 | The behaviour and constants described in these documents SHOULD converge, and/or be interoperable with the majority of IRC software. These documents should allow a client or server author to build software which can communicate with almost any other piece of IRC software it interacts with. 12 | 13 | These documents contain existing behaviour and what we consider best-practices for new software. Where external, up-to-date and authoritative specifications exist for commands/messages/behaviours, we prefer to link to those rather than needlessly rewrite them (see the Client Protocol's [`CAP`](http://modern.ircdocs.horse/#cap-message) message for an example of this). 14 | 15 | These documents aren't RFCs. I can see the content from them being used in RFCs in the future, but right now I'm just concerned with creating good documents that help push IRC forward. If someone is making up a proper RFC, feel free to use anything from these documents -- Just respect the authors section at the top of the document if a decent amount of text/structure is used from it. 16 | 17 | If something written in these documents isn't correct for or interoperable with an IRC client / server / network you know of, please open an issue or send me an [email](mailto:daniel@danieloaks.net). Pull requests are appreciated. 18 | 19 | --- 20 | 21 | 22 | ## Custom Liquid tags 23 | 24 | These custom Liquid tags simplify referring to different parts of the IRC protocol, and can be used in the Modern doc: 25 | 26 | {% commandheader WHO %} and {% messageheader WHO %} 27 | - create the WHO message header, with an appropriate ID 28 | 29 | {% command WHO %} and {% message WHO %} 30 | - link to the WHO message 31 | 32 | {% numericheader RPL_WELCOME %} 33 | - create the `RPL_WELCOME` numeric header 34 | - numeric data MUST exist in the `_data/modern.yml` file 35 | 36 | {% numeric RPL_WELCOME %} 37 | - link to the `RPL_WELCOME` numeric 38 | - numeric data MUST exist in the `_data/modern.yml` file 39 | 40 | {% isupportheader TARGMAX %} 41 | - create the ISUPPORT TARGMAX parameter header 42 | 43 | {% isupport TARGMAX %} 44 | - link to the TARGMAX ISUPPORT parameter 45 | 46 | 47 | --- 48 | 49 | 50 | ## Modern IRC Client Protocol 51 | 52 | This is an attempt to create an updated document about how the IRC client protocol works these days. 53 | 54 | We specify commands, messages and numerics as SHOULD and MUST based on how much of the IRC software out there today uses them (as well as the guidance of the RFCs and common-sense). Someone writing a client or server based off this document SHOULD end up with an implementation that interacts nicely with most IRC software and networks out there today. 55 | 56 | This ignores the S2S protocol. The reasons for this are discussed in the document. This document includes bits and pieces cherry-picked from the RFCs, [IRCv3](http://ircv3.net/), Internet-Drafts, and commands/replies that have generally been accepted by the IRC community. 57 | 58 | 59 | ## IRC Formatting 60 | 61 | Describes what I consider to be the formatting characters and methods understood by basically everything. This includes colors, bold, italics, formatting reset codes, etc. 62 | 63 | In this document, I describe what I think is the most sane way to interpret them. This includes the edge-cases that aren't normally explored in similar documents, based on what clients tend to do today. 64 | 65 | 66 | ## Client-to-Client Protocol (CTCP) 67 | 68 | Describes a subset of CTCP that is sane and lets software interoperate with most of the other IRC software out there today. Leaves out quoting mechanisms defined by earlier specifications that have not been widely implemented nor followed today, and defines the messages that most clients implementing CTCP should be aware of. 69 | 70 | ## Building 71 | 72 | Install dependencies: 73 | 74 | ``` 75 | bundle config set --local path 'vendor/bundle' 76 | bundle install 77 | ``` 78 | 79 | Then, either: 80 | 81 | * `bundle exec jekyll build` to write locally in `_site/` 82 | * `bundle exec jekyll serve --incremental` to start a webserver 83 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | exclude: 2 | - README.md 3 | - CNAME 4 | - Gemfile 5 | - Gemfile.lock 6 | plugins: 7 | - jekyll-sitemap 8 | - jekyll-redirect-from 9 | - jekyll-sass-converter 10 | - jekyll-toc 11 | excerpt_separator: 12 | -------------------------------------------------------------------------------- /_includes/c2s_structure.md: -------------------------------------------------------------------------------- 1 | While a client is connected to a server, they send a stream of bytes to each other. This stream contains messages separated by `CR` `('\r', 0x0D)` and `LF` `('\n', 0x0A)`. These messages may be sent at any time from either side, and may generate zero or more reply messages. 2 | 3 | Software SHOULD use the [UTF-8](http://tools.ietf.org/html/rfc3629) character encoding to encode and decode messages, with fallbacks as described in the [Character Encodings](#character-encodings) implementation considerations appendix. 4 | 5 | Names of IRC entities (clients, servers, channels) are casemapped. This prevents, for example, someone having the nickname `'Dan'` and someone else having the nickname `'dan'`, confusing other users. Servers MUST advertise the casemapping they use in the [`RPL_ISUPPORT`](#feature-advertisement) numeric that's sent when connection registration has completed. 6 | 7 | 8 | ## Message Format 9 | 10 | An IRC message is a single line, delimited by a pair of `CR` `('\r', 0x0D)` and `LF` `('\n', 0x0A)` characters. 11 | 12 | - When reading messages from a stream, read the incoming data into a buffer. Only parse and process a message once you encounter the `\r\n` at the end of it. If you encounter an empty message, silently ignore it. 13 | - When sending messages, ensure that a pair of `\r\n` characters follows every single message your software sends out. 14 | 15 | --- 16 | 17 | Messages have this format, as rough ABNF: 18 | 19 | message ::= ['@' SPACE] [':' SPACE] 20 | SPACE ::= %x20 *( %x20 ) ; space character(s) 21 | crlf ::= %x0D %x0A ; "carriage return" "linefeed" 22 | 23 | The specific parts of an IRC message are: 24 | 25 | - **tags**: Optional metadata on a message, starting with `('@', 0x40)`. 26 | - **source**: Optional note of where the message came from, starting with `(':', 0x3A)`. 27 | - **command**: The specific command this message represents. 28 | - **parameters**: If it exists, data relevant to this specific command. 29 | 30 | These message parts, and parameters themselves, are separated by one or more ASCII SPACE characters `(' ', 0x20)`. 31 | 32 | Most IRC servers limit messages to 512 bytes in length, including the trailing `CR-LF` characters. Implementations which include [message tags](https://ircv3.net/specs/extensions/message-tags.html) need to allow additional bytes for the **tags** section of a message; clients must allow 8191 additional bytes and servers must allow 4096 additional bytes. 33 | 34 | --- 35 | 36 | The following sections describe how to process each part, but here are a few complete example messages: 37 | 38 | :irc.example.com CAP LS * :multi-prefix extended-join sasl 39 | 40 | @id=234AB :dan!d@localhost PRIVMSG #chan :Hey what's up! 41 | 42 | CAP REQ :sasl 43 | 44 | 45 | ### Tags 46 | 47 | This is the format of the **tags** part: 48 | 49 | ::= [';' ]* 50 | ::= ['=' ] 51 | ::= [ ] [ '/' ] 52 | ::= '+' 53 | ::= 54 | ::= 55 | 56 | Basically, a series of `[=]` segments, separated by `(';', 0x3B)`. 57 | 58 | The **tags** part is optional, and MUST NOT be sent unless explicitly enabled by [a capability](#capability-negotiation). This message part starts with a leading `('@', 0x40)` character, which MUST be the first character of the message itself. The leading `('@', 0x40)` is stripped from the value before it gets processed further. 59 | 60 | Here are some examples of tags sections and how they could be represented as [JSON](https://www.json.org/) objects: 61 | 62 | @id=123AB;rose -> {"id": "123AB", "rose": ""} 63 | 64 | @url=;netsplit=tur,ty -> {"url": "", "netsplit": "tur,ty"} 65 | 66 | For more information on processing tags – including the naming and registration of them, and how to escape values – see the IRCv3 [Message Tags specification](http://ircv3.net/specs/core/message-tags-3.2.html). 67 | 68 | 69 | ### Source 70 | 71 | source ::= / ( [ "!" ] [ "@" ] ) 72 | nick ::= 73 | user ::= 74 | 75 | The **source** (formerly known as **prefix**) is optional and starts with a `(':', 0x3A)` character (which is stripped from the value), and if there are no tags it MUST be the first character of the message itself. 76 | 77 | The source indicates the true origin of a message. If the source is missing from a message, it's is assumed to have originated from the client/server on the other end of the connection the message was received on. 78 | 79 | Clients MUST NOT include a source when sending a message. 80 | 81 | Servers MAY include a source on any message, and MAY leave a source off of any message. Clients MUST be able to process any given message the same way whether it contains a source or does not contain one. 82 | 83 | 84 | ### Command 85 | 86 | command ::= letter* / 3digit 87 | 88 | The **command** must either be a valid IRC command or a numeric (a three-digit number represented as text). 89 | 90 | Information on specific commands / numerics can be found in the [Client Messages](#client-messages) and [Numerics](#numerics) sections, respectively. 91 | 92 | 93 | ### Parameters 94 | 95 | This is the format of the **parameters** part: 96 | 97 | parameters ::= *( SPACE middle ) [ SPACE ":" trailing ] 98 | nospcrlfcl ::= 99 | middle ::= nospcrlfcl *( ":" / nospcrlfcl ) 100 | trailing ::= *( ":" / " " / nospcrlfcl ) 101 | 102 | **Parameters** (or 'params') are extra pieces of information added to the end of a message. These parameters generally make up the 'data' portion of the message. What specific parameters mean changes for every single message. 103 | 104 | Parameters are a series of values separated by one or more ASCII SPACE characters `(' ', 0x20)`. However, this syntax is insufficient in two cases: a parameter that contains one or more spaces, and an empty parameter. To permit such parameters, the final parameter can be prepended with a `(':', 0x3A)` character, in which case that character is stripped and the rest of the message is treated as the final parameter, including any spaces it contains. Parameters that contain spaces, are empty, or begin with a `':'` character MUST be sent with a preceding `':'`; in other cases the use of a preceding `':'` on the final parameter is OPTIONAL. 105 | 106 | Software SHOULD AVOID sending more than 15 parameters, as older client protocol documents specified this was the maximum and some clients may have trouble reading more than this. However, clients MUST parse incoming messages with any number of them. 107 | 108 | Here are some examples of messages and how the parameters would be represented as [JSON](https://www.json.org/) lists: 109 | 110 | :irc.example.com CAP * LIST : -> ["*", "LIST", ""] 111 | 112 | CAP * LS :multi-prefix sasl -> ["*", "LS", "multi-prefix sasl"] 113 | 114 | CAP REQ :sasl message-tags foo -> ["REQ", "sasl message-tags foo"] 115 | 116 | :dan!d@localhost PRIVMSG #chan :Hey! -> ["#chan", "Hey!"] 117 | 118 | :dan!d@localhost PRIVMSG #chan Hey! -> ["#chan", "Hey!"] 119 | 120 | :dan!d@localhost PRIVMSG #chan ::-) -> ["#chan", ":-)"] 121 | 122 | As these examples show, a trailing parameter (a final parameter with a preceding `':'`) has the same semantics as any other parameter, and MUST NOT be treated specially or stored separately once the `':'` is stripped. 123 | 124 | ### Compatibility with incorrect software 125 | 126 | Servers SHOULD handle single `\n` character, and MAY handle a single `\r` character, as if it was a `\r\n` pair, to support existing clients that might send this. However, clients and servers alike MUST NOT send single `\r` or `\n` characters. 127 | 128 | Servers and clients SHOULD ignore empty lines. 129 | 130 | Servers SHOULD gracefully handle messages over the 512-bytes limit. They may: 131 | 132 | * Send an error numeric back, preferably {% numeric ERR_INPUTTOOLONG %} 133 | * Truncate on the 510th byte (and add `\r\n` at the end) or, preferably, on the last UTF-8 character or grapheme that fits. 134 | * Ignore the message or close the connection – but this may be confusing to users of buggy clients. 135 | 136 | Finally, clients and servers SHOULD NOT use more than one space (`\x20`) character as `SPACE` as defined in the grammar above. 137 | 138 | ## Numeric Replies 139 | 140 | Most messages sent from a client to a server generates a reply of some sort. The most common form of reply is the numeric reply, used for both errors and normal replies. Distinct from a normal message, a numeric reply MUST contain a `` and use a three-digit numeric as the command. A numeric reply SHOULD contain the target of the reply as the first parameter of the message. A numeric reply is not allowed to originate from a client. 141 | 142 | In all other respects, a numeric reply is just like a normal message. A list of numeric replies is supplied in the [Numerics](#numerics) section. 143 | 144 | 145 | ## Wildcard Expressions 146 | 147 | When wildcards are allowed in a string, it is referred to as a "mask". 148 | 149 | For string matching purposes, the protocol allows the use of two special characters: `('?', 0x3F)` to match one and only one character, and `('*', 0x2A)` to match any number of any characters. These two characters can be escaped using the `('\', 0x5C)` character. 150 | 151 | The ABNF syntax for this is: 152 | 153 | mask = *( nowild / noesc wildone / noesc wildmany ) 154 | wildone = %x3F 155 | wildmany = %x2A 156 | nowild = %x01-29 / %x2B-3E / %x40-FF 157 | ; any octet except NUL, "*", "?" 158 | noesc = %x01-5B / %x5D-FF 159 | ; any octet except NUL and "\" 160 | 161 | matchone = %x01-FF 162 | ; matches wildone 163 | matchmany = *matchone 164 | ; matches wildmany 165 | 166 | Examples: 167 | 168 | a?c ; Matches any string of 3 characters in length starting 169 | with "a" and ending with "c" 170 | 171 | a*c ; Matches any string of 2 or more characters in length 172 | starting with "a" and ending with "c" 173 | 174 | -------------------------------------------------------------------------------- /_includes/concepts.md: -------------------------------------------------------------------------------- 1 | This section describes concepts behind the implementation and organisation of the IRC protocol, which are useful in understanding how it works. 2 | 3 | 4 | ## Architectural 5 | 6 | A typical IRC network consists of servers and clients connected to those servers, with a good mix of IRC operators and channels. This section goes through each of those, what they are and a brief overview of them. 7 | 8 | ### Servers 9 | 10 | Servers form the backbone of IRC, providing a point to which clients may connect and talk to each other, and a point for other servers to connect to, forming an IRC network. 11 | 12 | The most common network configuration for IRC servers is that of a spanning tree [see the figure below], where each server acts as a central node for the rest of the network it sees. Other topologies are being experimented with, but right now there are none widely used in production. 13 | 14 | [ Server 15 ] [ Server 13 ] [ Server 14 ] 15 | / \ / 16 | / \ / 17 | [ Server 11 ] ------ [ Server 1 ] [ Server 12 ] 18 | / \ / 19 | / \ / 20 | [ Server 2 ] [ Server 3 ] 21 | / \ \ 22 | / \ \ 23 | [ Server 4 ] [ Server 5 ] [ Server 6 ] 24 | / | \ / 25 | / | \ / 26 | / | \____ / 27 | / | \ / 28 | [ Server 7 ] [ Server 8 ] [ Server 9 ] [ Server 10 ] 29 | 30 | : 31 | [ etc. ] 32 | : 33 | 34 |

Format of a typical IRC network.

35 | 36 | There have been several terms created over time to describe the roles of different servers on an IRC network. Some of the most common terms are as follows: 37 | 38 | * **Hub**: A 'hub' is a server that connects to multiple other servers. For instance, in the figure above, Server 2, Server 3, and Server 4 would be examples of hub servers. 39 | * **Core Hub**: A 'core hub' is typically a hub server that connects fairly major parts of the IRC network together. What is considered a core hub will change depending on the size of a network and what the administrators of the network consider important. For instance, in the figure above, Server 1, Server 2, and Server 3 may be considered core hubs by the network administrators. 40 | * **Leaf**: A 'leaf' is a server that is only connected to a single other server on the network. Typically, leafs are the primary servers that handle client connections. In the figure above, Servers 7, 8, 10, 13, 14, and others would be considered leaf servers. 41 | * **Services**: A 'services' server is a special type of server that extends the capabilities of the server software on the network (ie, they provide *services* to the network). Services are not used on all networks, and the capabilities typically provided by them may be built-into server software itself rather than being provided by a separate software package. Features usually handled by services include client account registration (as are typically used for [SASL authentication](#authenticate-message)), channel registration (allowing client accounts to 'own' channels), and further modifications and extensions to the IRC protocol. 'Services' themselves are **not** specified in any way by the protocol, they are different from the [services](#services) defined by the RFCs. What they provide depends entirely on the software packages being run. 42 | 43 | A trend these days is to hide the real structure of a network from regular users. Networks that implement this may restrict or modify commands like {% command MAP %} so that regular users see every other server on the network as linked directly to the current server. When this is done, servers that do not handle client connections may also be hidden from users (hubs hidden in this way can be called 'hidden hubs'). Generally, IRC operators can always see the true structure of a network. 44 | 45 | These terms are not generally used in IRC protocol documentation, but may be used by the administrators of a network in order to differentiate the servers they run and their roles. 46 | 47 | Servers SHOULD pick a name which contains a dot character `(".", 0x2E)`. This can help clients disambiguate between server names and nicknames in a message source. 48 | 49 | ### Clients 50 | 51 | A client is anything connecting to a server that is not another server. Each client is distinguished from other clients by a unique nickname. In addition to the nickname, all servers must have the following information about all clients: the real name/address of the host that the client is connecting from, the username of the client on that host, and the server to which the client is connected. 52 | 53 | Nicknames are non-empty strings with the following restrictions: 54 | 55 | - They MUST NOT contain any of the following characters: space `(' ', 0x20)`, comma `(',', 0x2C)`, asterisk `('*', 0x2A)`, question mark `('?', 0x3F)`, exclamation mark `('!', 0x21)`, at sign `('@', 0x40)`. 56 | - They MUST NOT start with any of the following characters: dollar `('$', 0x24)`, colon `(':', 0x3A)`. 57 | - They MUST NOT start with a character listed as a [channel type](#channel-types), [channel membership prefix](#channel-membership-prefixes), or prefix listed in the IRCv3 [`multi-prefix` Extension](https://ircv3.net/specs/extensions/multi-prefix). 58 | - They SHOULD NOT contain any dot character `('.', 0x2E)`. 59 | 60 | Servers MAY have additional implementation-specific nickname restrictions and SHOULD avoid the use of nicknames which are ambiguous with commands or command parameters where this could lead to confusion or error. 61 | 62 | ### Services 63 | 64 | Services were a different kind of clients than users, defined in the [RFC2812](https://tools.ietf.org/html/rfc2812.html#section-1.2.2). They were to provide or collect information about the IRC network. They are no longer used now. As such the service-related messages (`SERVICE`, `SERVLIST` and `SQUERY`) are also deprecated. 65 | 66 | #### Operators 67 | 68 | To allow a reasonable amount of order to be kept within the IRC network, a special class of clients (operators) are allowed to perform general maintenance functions on the network. Although the powers granted to an operator can be considered as 'dangerous', they are nonetheless required. 69 | 70 | The tasks operators can perform vary with different server software and the specific privileges granted to each operator. Some can perform network maintenance tasks, such as disconnecting and reconnecting servers as needed to prevent long-term use of bad network routing. Some operators can also remove a user from their server or the IRC network by 'force', i.e. the operator is able to close the connection between a client and server. 71 | 72 | The justification for operators being able to remove users from the network is delicate since its abuse is both destructive and annoying. However, IRC network policies and administrators handle operators who abuse their privileges, and what is considered abuse by that network. 73 | 74 | ### Channels 75 | 76 | A channel is a named group of one or more clients. All clients in the channel will receive all messages addressed to that channel. The channel is created implicitly when the first client joins it, and the channel ceases to exist when the last client leaves it. While the channel exists, any client can reference the channel using the name of the channel. Networks that support the concept of 'channel ownership' may persist specific channels in some way while no clients are connected to them. 77 | 78 | Channel names are strings (beginning with specified prefix characters). Apart from the requirement of the first character being a valid [channel type](#channel-types) prefix character; the only restriction on a channel name is that it may not contain any spaces `(' ', 0x20)`, a control G / `BELL` `('^G', 0x07)`, or a comma `(',', 0x2C)` (which is used as a list item separator by the protocol). 79 | 80 | There are several types of channels used in the IRC protocol. The first standard type of channel is a [regular channel](#regular-channels-), which is known to all servers that are connected to the network. The prefix character for this type of channel is `('#', 0x23)`. The second type are server-specific or [local channels](#local-channels-), where the clients connected can only see and talk to other clients on the same server. The prefix character for this type of channel is `('&', 0x26)`. Other types of channels are described in the [Channel Types](#channel-types) section. 81 | 82 | Along with various channel types, there are also channel modes that can alter the characteristics and behaviour of individual channels. See the [Channel Modes](#channel-modes) section for more information on these. 83 | 84 | To create a new channel or become part of an existing channel, a user is required to join the channel using the {% message JOIN %} command. If the channel doesn't exist prior to joining, the channel is created and the creating user becomes a channel operator. If the channel already exists, whether or not the client successfully joins that channel depends on the modes currently set on the channel. For example, if the channel is set to `invite-only` mode (`+i`), the client only joins the channel if they have been invited by another user or they have been exempted from requiring an invite by the channel operators. 85 | 86 | Channels also contain a [topic](#topic-message). The topic is a line shown to all users when they join the channel, and all users in the channel are notified when the topic of a channel is changed. Channel topics commonly state channel rules, links, quotes from channel members, a general description of the channel, or whatever the [channel operators](#channel-operators) want to share with the clients in their channel. 87 | 88 | A user may be joined to several channels at once, but a limit may be imposed by the server as to how many channels a client can be in at one time. This limit is specified by the {% isupport CHANLIMIT %} `RPL_ISUPPORT` parameter. See the [Feature Advertisement](#feature-advertisement) section for more details on `RPL_ISUPPORT`. 89 | 90 | If the IRC network becomes disjoint because of a split between servers, the channel on either side is composed of only those clients which are connected to servers on the respective sides of the split, possibly ceasing to exist on one side. When the split is healed, the connecting servers ensure the network state is consistent between them. 91 | 92 | #### Channel Operators 93 | 94 | Channel operators (or "chanops") on a given channel are considered to 'run' or 'own' that channel. In recognition of this status, channel operators are endowed with certain powers which let them moderate and keep control of their channel. 95 | 96 | Most IRC operators do not concern themselves with 'channel politics'. In addition, a large number of networks leave the management of specific channels up to chanops where possible, and try not to interfere themselves. However, this is a matter of network policy, and it's best to consult the [Message of the Day](#motd-message) when looking at channel management. 97 | 98 | IRC servers may also define other levels of channel moderation. These can include 'halfop' (half operator), 'protected' (protected user/operator), 'founder' (channel founder), and any other positions the server wishes to define. These moderation levels have varying privileges and can execute, and not execute, various channel management commands based on what the server defines. 99 | 100 | The commands which may only be used by channel moderators include: 101 | 102 | - {% command KICK %}: Eject a client from the channel 103 | - {% command MODE %}: Change the channel's modes 104 | - {% command INVITE %}: Invite a client to an invite-only channel (mode +i) 105 | - {% command TOPIC %}: Change the channel topic in a mode +t channel 106 | 107 | Channel moderators are identified by the channel member prefix (`'@'` for standard channel operators, `'%'` for halfops) next to their nickname whenever it is associated with a channel (e.g. replies to the {% command NAMES %}, {% command WHO %}, and {% command WHOIS %} commands). 108 | 109 | Specific prefixes and moderation levels are covered in the [Channel Membership Prefixes](#channel-membership-prefixes) section. 110 | 111 | 112 | ## Communication Types 113 | 114 | *This section describes how current implementations deliver different classes of messages and is not normative.* 115 | 116 | This section ONLY deals with the spanning-tree topology, shown in the figure below. This is because spanning-tree is the topology specified and used in all IRC software today. Other topologies are being experimented with, but are not yet used in production by networks. 117 | 118 | 1--\ 119 | A D---4 120 | 2--/ \ / 121 | B----C 122 | / \ 123 | 3 E 124 | 125 | Servers: A, B, C, D, E Clients: 1, 2, 3, 4 126 | 127 |

Sample small IRC network.

128 | 129 | ### One-to-one communication 130 | 131 | Communication on a one-to-one basis is usually only performed by clients, since most server-server traffic is not a result of servers talking only to each other. 132 | 133 | Servers should be able to send a message from any one client to any other. Servers send a message in exactly one direction along the spanning tree to reach any client. Thus the path of a message being delivered is the shortest path between any two points on the spanning tree. 134 | 135 | The following examples all refer to the figure above. 136 | 137 | 1. A message between clients 1 and 2 is only seen by server A, which sends it straight to client 2. 138 | 139 | 2. A message between clients 1 and 3 is seen by servers A, B, and client 3. No other clients or servers are allowed to see the message. 140 | 141 | 3. A message between clients 2 and 4 is seen by servers A, B, C, D, and client 4 only. 142 | 143 | ### One-to-many communication 144 | 145 | The main goal of IRC is to provide a forum which allows easy and efficient conferencing (one to many conversations). IRC offers several means to achieve this, each serving its own purpose. 146 | 147 | #### To A Channel 148 | 149 | In IRC, the channel has a role equivalent to that of the multicast group; their existence is dynamic and the actual conversation carried out on a channel is generally sent only to servers which are supporting users on a given channel, and only once to every local link as each server is responsible for fanning the original message to ensure it will reach all recipients. 150 | 151 | The following examples all refer to the above figure: 152 | 153 | 4. Any channel with a single client in it. Messages to this channel go to the server and then nowhere else. 154 | 155 | 5. Two clients in a channel. All messages traverse a path as if they were private messages between the two clients outside a channel. 156 | 157 | 6. Clients 1, 2, and 3 are in a channel. All messages to this channel are sent to all clients and only those servers which must be traversed by the message if it were a private message to a single client. If client 1 sends a message, it goes back to client 2 and then via server B to client 3. 158 | 159 | #### To A Host/Server Mask 160 | 161 | To provide with some mechanism to send messages to a large body of related users, host and server mask messages are available. These messages are sent to users whose host or server information match that of the given mask. The messages are only sent to locations where the users are, in a fashion similar to that of channels. 162 | 163 | #### To A List 164 | 165 | The least efficient style of one-to-many conversation is through clients talking to a 'list' of targets (client, channel, ask). How this is done is almost self-explanatory: the client gives a list of destinations to which the message is to be delivered and the server breaks it up and dispatches a separate copy of the message to each given destination. 166 | 167 | This is not as efficient as using a channel since the destination list may be broken up and the dispatch sent without checking to make sure duplicates aren't sent down each path. 168 | 169 | ### One-To-All 170 | 171 | The one-to-all type of message is better described as a broadcast message, sent to all clients or servers or both. On a large network of users and servers, a single message can result in a lot of traffic being sent over the network in an effort to reach all of the desired destinations. 172 | 173 | For some class of messages, there is no option but to broadcast it to all servers to that the state information held by each server is consistent between them. 174 | 175 | #### Client-to-Client 176 | 177 | IRC Operators may be able to send a message to every client currently connected to the network. This depends on the specific features and commands implemented in the server software. 178 | 179 | #### Client-to-Server 180 | 181 | Most of the commands which result in a change of state information (such as channel membership, channel modes, user status, etc.) MUST be sent to all servers by default, and this distribution SHALL NOT be changed by the client. 182 | 183 | #### Server-to-Server 184 | 185 | While most messages between servers are distributed to all 'other' servers, this is only required for any message that affects a user, channel, or server. Since these are the basic items found in IRC, nearly all messages originating from a server are broadcast to all other connected servers. 186 | -------------------------------------------------------------------------------- /_includes/copyrights.html: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /_includes/ctcp-appendix.md: -------------------------------------------------------------------------------- 1 | # CTCP Message Registry 2 | 3 | _Extended formatting_ messages can have parameters, but usually do not generate an automatic reply. 4 | 5 | _Metadata queries_ do not have any parameters, but expect a reply with parameters as the response data. 6 | 7 | _Extended queries_ and replies may have parameters. 8 | 9 | We only cover messages that are widely-used by IRC software today. For more extensive lists, see the external `irc-defs` [ctcp messages](https://defs.ircdocs.horse/defs/ctcp.html) list. 10 | 11 | ### ACTION 12 | 13 | Type: Extended Formatting 14 | Params: ACTION 15 | 16 | This extended formatting message shows that `` should be displayed as a third-person _action_ or _emote_; in clients, it's generally activated with the command `/me`. 17 | 18 | `ACTION` is universally implemented and very commonly used. Clients MUST implement this CTCP message. 19 | 20 | *Example:* 21 | 22 | Raw: :dan!user@host PRIVMSG #ircv3 :\x01ACTION writes a specification\x01 23 | 24 | Formatted: * dan writes a specification 25 | 26 | ### CLIENTINFO 27 | 28 | Type: Metadata Query 29 | Reply: CLIENTINFO { } 30 | 31 | This metadata query returns a list of the CTCP messages that this client supports and implements. 32 | 33 | `CLIENTINFO` is widely implemented. Clients SHOULD implement this CTCP message. 34 | 35 | *Example:* 36 | 37 | Query: CLIENTINFO 38 | Response: CLIENTINFO ACTION DCC CLIENTINFO FINGER PING SOURCE TIME USERINFO VERSION 39 | 40 | ### DCC 41 | 42 | Type: Extended Query 43 | Params: DCC
44 | 45 | DCC (Direct Client-to-Client) is used to setup and control connections that go directly between clients, bypassing the IRC server. This is typically used for features that require a large amount of traffic between clients or simply wish to bypass the server itself such as file transfer, direct chat, and voice messages. 46 | 47 | Properly implementing the various DCC types requires a document all of its own, and are not described here. 48 | 49 | `DCC` is widely implemented. Clients MAY implement this CTCP message. 50 | 51 | ### FINGER 52 | 53 | Type: Metadata Query 54 | Reply: FINGER 55 | 56 | This metadata query returns miscellaneous info about the user, typically the same information that's held in their `realname` field. 57 | 58 | However, some implementations return the client name and version instead. 59 | 60 | `FINGER` is widely implemented, but largely obsolete. Clients MAY implement this CTCP message. 61 | 62 | *Example:* 63 | 64 | Query: FINGER 65 | Response: FINGER WeeChat 1.5 66 | 67 | ### PING 68 | 69 | Type: Extended Query 70 | Params: PING 71 | 72 | This extended query is used to confirm reachability with other clients and to check latency. When receiving a CTCP PING, the reply must contain exactly the same parameters as the original query. 73 | 74 | `PING` is universally implemented. Clients MUST implement this CTCP message. 75 | 76 | *Example:* 77 | 78 | Query: PING 1473523721 662865 79 | Response: PING 1473523721 662865 80 | 81 | Query: PING foo bar baz 82 | Response: PING foo bar baz 83 | 84 | ### SOURCE 85 | 86 | Type: Metadata Query 87 | Reply: SOURCE 88 | 89 | This metadata query is used to return the location of the source code for the client. 90 | 91 | `SOURCE` is rarely implemented. Clients MAY implement this CTCP message. 92 | 93 | *Example:* 94 | 95 | Query: SOURCE 96 | Response: SOURCE https://weechat.org/download 97 | 98 | ### TIME 99 | 100 | Type: Extended Query 101 | Params: TIME 102 | 103 | This extended query is used to return the client's local time in an unspecified human-readable format. We recommend ISO 8601 format, but raw `ctime()` output appears to be the most common in practice. 104 | 105 | New implementations SHOULD default to UTC time for privacy reasons. 106 | 107 | `TIME` is almost universally implemented. Clients SHOULD implement this CTCP message. 108 | 109 | *Example:* 110 | 111 | Query: TIME 112 | Response: TIME 2016-09-26T00:45:36Z 113 | 114 | ### VERSION 115 | 116 | Type: Metadata Query 117 | Reply: VERSION 118 | 119 | This metadata query is used to return the name and version of the client software in use. There is no specified format for the version string. 120 | 121 | `VERSION` is universally implemented. Clients MUST implement this CTCP message. 122 | 123 | *Example:* 124 | 125 | Query: VERSION 126 | Response: VERSION WeeChat 1.5-rc2 (git: v1.5-rc2-1-gc1441b1) (Apr 25 2016) 127 | 128 | ### USERINFO 129 | 130 | Type: Metadata Query 131 | Reply: USERINFO 132 | 133 | This metadata query returns miscellaneous info about the user, typically the same information that's held in their `realname` field. 134 | 135 | However, some implementations return ` ()` instead. 136 | 137 | `USERINFO` is widely implemented, but largely obsolete. Clients MAY implement this CTCP message. 138 | 139 | *Example:* 140 | 141 | Query: USERINFO 142 | Response: USERINFO fred (Fred Foobar) 143 | -------------------------------------------------------------------------------- /_includes/ietfwarning.html: -------------------------------------------------------------------------------- 1 |
2 |

NOTE: This document is being persued as an Internet-Draft for standardisation with the IETF.

3 |

This page is out of date, and you should look here for the document that replaces this:

4 |

5 | [Internet-Draft] - 6 | [Editor's HTML Draft] - 7 | [Editor's TXT Draft] - 8 | [Github] 9 |

10 |
11 | -------------------------------------------------------------------------------- /_includes/messages/channel.md: -------------------------------------------------------------------------------- 1 | This group of messages is concerned with manipulating channels, their properties (channel modes), and their contents (typically clients). 2 | 3 | These commands may be requests to the server, in which case the server will or will not grant the request. If a 'request' is granted, it will be acknowledged by the server sending a message containing the same information back to the client. This is to tell the user that the request was successful. These sort of 'request' commands will be noted in the message information. 4 | 5 | In implementing these messages, race conditions are inevitable when clients at opposing ends of a network send commands which will ultimately clash. Server-to-server protocols should be aware of this and make sure their protocol ensures consistent state across the entire network. 6 | 7 | ### JOIN message 8 | 9 | Command: JOIN 10 | Parameters: {,} [{,}] 11 | Alt Params: 0 12 | 13 | The `JOIN` command indicates that the client wants to join the given channel(s), each channel using the given key for it. The server receiving the command checks whether or not the client can join the given channel, and processes the request. Servers MUST process the parameters of this command as lists on incoming commands from clients, with the first `` being used for the first ``, the second `` being used for the second ``, etc. 14 | 15 | While a client is joined to a channel, they receive all relevant information about that channel including the `JOIN`, `PART`, `KICK`, and `MODE` messages affecting the channel. They receive all `PRIVMSG` and `NOTICE` messages sent to the channel, and they also receive `QUIT` messages from other clients joined to the same channel (to let them know those users have left the channel and the network). This allows them to keep track of other channel members and channel modes. 16 | 17 | If a client's `JOIN` command to the server is successful, the server MUST send, in this order: 18 | 19 | 1. A `JOIN` message with the client as the message `` and the channel they have joined as the first parameter of the message. 20 | 2. The channel's topic (with {% numeric RPL_TOPIC %} and optionally {% numeric RPL_TOPICWHOTIME %}), and no message if the channel does not have a topic. 21 | 3. A list of users currently joined to the channel (with one or more {% numeric RPL_NAMREPLY %} numerics followed by a single {% numeric RPL_ENDOFNAMES %} numeric). These `RPL_NAMREPLY` messages sent by the server MUST include the requesting client that has just joined the channel. 22 | 23 | The [key](#key-channel-mode), [client limit](#client-limit-channel-mode) , [ban](#ban-channel-mode) - [exception](#ban-exception-channel-mode), [invite-only](#invite-only-channel-mode) - [exception](#invite-exception-channel-mode), and other (depending on server software) channel modes affect whether or not a given client may join a channel. More information on each of these modes and how they affect the `JOIN` command is available in their respective sections. 24 | 25 | Servers MAY restrict the number of channels a client may be joined to at one time. This limit SHOULD be defined in the {% isupport CHANLIMIT %} `RPL_ISUPPORT` parameter. If the client cannot join this channel because they would be over their limit, they will receive an {% numeric ERR_TOOMANYCHANNELS %} reply and the command will fail. 26 | 27 | Note that this command also accepts the special argument of `("0", 0x30)` instead of any of the usual parameters, which requests that the sending client leave all channels they are currently connected to. The server will process this command as though the client had sent a {% command PART %} command for each channel they are a member of. 28 | 29 | This message may be sent from a server to a client to notify the client that someone has joined a channel. In this case, the message `` will be the client who is joining, and `` will be the channel which that client has joined. Servers SHOULD NOT send multiple channels in this message to clients, and SHOULD distribute these multiple-channel `JOIN` messages as a series of messages with a single channel name on each. 30 | 31 | Numeric Replies: 32 | 33 | * {% numeric ERR_NEEDMOREPARAMS %} 34 | * {% numeric ERR_NOSUCHCHANNEL %} 35 | * {% numeric ERR_TOOMANYCHANNELS %} 36 | * {% numeric ERR_BADCHANNELKEY %} 37 | * {% numeric ERR_BANNEDFROMCHAN %} 38 | * {% numeric ERR_CHANNELISFULL %} 39 | * {% numeric ERR_INVITEONLYCHAN %} 40 | * {% numeric ERR_BADCHANMASK %} 41 | * {% numeric RPL_TOPIC %} 42 | * {% numeric RPL_TOPICWHOTIME %} 43 | * {% numeric RPL_NAMREPLY %} 44 | * {% numeric RPL_ENDOFNAMES %} 45 | 46 | Command Examples: 47 | 48 | JOIN #foobar ; join channel #foobar. 49 | 50 | JOIN &foo fubar ; join channel &foo using key "fubar". 51 | 52 | JOIN #foo,&bar fubar ; join channel #foo using key "fubar" 53 | and &bar using no key. 54 | 55 | JOIN #foo,#bar fubar,foobar ; join channel #foo using key "fubar". 56 | and channel #bar using key "foobar". 57 | 58 | JOIN #foo,#bar ; join channels #foo and #bar. 59 | 60 | Message Examples: 61 | 62 | :WiZ JOIN #Twilight_zone ; WiZ is joining the channel 63 | #Twilight_zone 64 | 65 | :dan-!d@localhost JOIN #test ; dan- is joining the channel #test 66 | 67 | See also: 68 | 69 | * IRCv3 [`extended-join` Extension](https://ircv3.net/specs/extensions/extended-join) 70 | 71 | ### PART message 72 | 73 | Command: PART 74 | Parameters: {,} [] 75 | 76 | The `PART` command removes the client from the given channel(s). On sending a successful `PART` command, the user will receive a `PART` message from the server for each channel they have been removed from. `` is the reason that the client has left the channel(s). 77 | 78 | For each channel in the parameter of this command, if the channel exists and the client is not joined to it, they will receive an {% numeric ERR_NOTONCHANNEL %} reply and that channel will be ignored. If the channel does not exist, the client will receive an {% numeric ERR_NOSUCHCHANNEL %} reply and that channel will be ignored. 79 | 80 | This message may be sent from a server to a client to notify the client that someone has been removed from a channel. In this case, the message `` will be the client who is being removed, and `` will be the channel which that client has been removed from. Servers SHOULD NOT send multiple channels in this message to clients, and SHOULD distribute these multiple-channel `PART` messages as a series of messages with a single channel name on each. If a `PART` message is distributed in this way, `` (if it exists) should be on each of these messages. 81 | 82 | Numeric Replies: 83 | 84 | * {% numeric ERR_NEEDMOREPARAMS %} 85 | * {% numeric ERR_NOSUCHCHANNEL %} 86 | * {% numeric ERR_NOTONCHANNEL %} 87 | 88 | Command Examples: 89 | 90 | PART #twilight_zone ; leave channel "#twilight_zone" 91 | 92 | PART #oz-ops,&group5 ; leave both channels "&group5" and 93 | "#oz-ops". 94 | 95 | Message Examples: 96 | 97 | :dan-!d@localhost PART #test ; dan- is leaving the channel #test 98 | 99 | ### TOPIC message 100 | 101 | Command: TOPIC 102 | Parameters: [] 103 | 104 | The `TOPIC` command is used to change or view the topic of the given channel. If `` is not given, either `RPL_TOPIC` or `RPL_NOTOPIC` is returned specifying the current channel topic or lack of one. If `` is an empty string, the topic for the channel will be cleared. 105 | 106 | If the client sending this command is not joined to the given channel, and tries to view its' topic, the server MAY return the {% numeric ERR_NOTONCHANNEL %} numeric and have the command fail. 107 | 108 | If `RPL_TOPIC` is returned to the client sending this command, `RPL_TOPICWHOTIME` SHOULD also be sent to that client. 109 | 110 | If the [protected topic](#protected-topic-mode) mode is set on a channel, then clients MUST have appropriate channel permissions to modify the topic of that channel. If a client does not have appropriate channel permissions and tries to change the topic, the {% numeric ERR_CHANOPRIVSNEEDED %} numeric is returned and the command will fail. 111 | 112 | If the topic of a channel is changed or cleared, every client in that channel (including the author of the topic change) will receive a `TOPIC` command with the new topic as argument (or an empty argument if the topic was cleared) alerting them to how the topic has changed. If the `` param is provided but the same as the previous topic (ie. it is unchanged), servers MAY notify the author and/or other users anyway. 113 | 114 | Clients joining the channel in the future will receive a `RPL_TOPIC` numeric (or lack thereof) accordingly. 115 | 116 | Numeric Replies: 117 | 118 | * {% numeric ERR_NEEDMOREPARAMS %} 119 | * {% numeric ERR_NOSUCHCHANNEL %} 120 | * {% numeric ERR_NOTONCHANNEL %} 121 | * {% numeric ERR_CHANOPRIVSNEEDED %} 122 | * {% numeric RPL_NOTOPIC %} 123 | * {% numeric RPL_TOPIC %} 124 | * {% numeric RPL_TOPICWHOTIME %} 125 | 126 | Command Examples: 127 | 128 | TOPIC #test :New topic ; Setting the topic on "#test" to 129 | "New topic". 130 | 131 | TOPIC #test : ; Clearing the topic on "#test" 132 | 133 | TOPIC #test ; Checking the topic for "#test" 134 | 135 | ### NAMES message 136 | 137 | Command: NAMES 138 | Parameters: {,} 139 | 140 | The `NAMES` command is used to view the nicknames joined to a channel and their [channel membership prefixes](#channel-membership-prefixes). The param of this command is a list of channel names, delimited by a comma `(",", 0x2C)` character. 141 | 142 | The channel names are evaluated one-by-one. For each channel that exists and they are able to see the users in, the server returns one of more `RPL_NAMREPLY` numerics containing the users joined to the channel and a single `RPL_ENDOFNAMES` numeric. If the channel name is invalid or the channel does not exist, one `RPL_ENDOFNAMES` numeric containing the given channel name should be returned. If the given channel has the [secret](#secret-channel-mode) channel mode set and the user is not joined to that channel, one `RPL_ENDOFNAMES` numeric is returned. Users with the [invisible](#invisible-user-mode) user mode set are not shown in channel responses unless the requesting client is also joined to that channel. 143 | 144 | Servers MAY allow more than one target channel. They can advertise the maximum the number of target users per `NAMES` command via the {% isupport TARGMAX %} `RPL_ISUPPORT` parameter. 145 | 146 | Numeric Replies: 147 | 148 | * {% numeric RPL_NAMREPLY %} 149 | * {% numeric RPL_ENDOFNAMES %} 150 | 151 | Command Examples: 152 | 153 | NAMES #twilight_zone,#42 ; List all visible users on 154 | "#twilight_zone" and "#42". 155 | 156 | NAMES ; Attempt to list all visible users on 157 | the network, which SHOULD be responded to 158 | as specified above. 159 | 160 | See also: 161 | 162 | * IRCv3 [`multi-prefix` Extension](https://ircv3.net/specs/extensions/multi-prefix) 163 | * IRCv3 [`userhost-in-names` Extension](https://ircv3.net/specs/extensions/userhost-in-names) 164 | 165 | ### LIST message 166 | 167 | Command: LIST 168 | Parameters: [{,}] [{,}] 169 | 170 | The `LIST` command is used to get a list of channels along with some information about each channel. Both parameters to this command are optional as they have different syntaxes. 171 | 172 | The first possible parameter to this command is a list of channel names, delimited by a comma `(",", 0x2C)` character. If this parameter is given, the information for only the given channels is returned. If this parameter is not given, the information about all visible channels (those not hidden by the [secret](#secret-channel-mode) channel mode rules) is returned. 173 | 174 | The second possible parameter to this command is a list of conditions as defined in the {% isupport ELIST %} `RPL_ISUPPORT` parameter, delimited by a comma `(",", 0x2C)` character. Clients MUST NOT submit an `ELIST` condition unless the server has explicitly defined support for that condition with the `ELIST` token. If this parameter is supplied, the server filters the returned list of channels with the given conditions as specified in the {% isupport ELIST %} documentation. 175 | 176 | In response to a successful `LIST` command, the server MAY send one `RPL_LISTSTART` numeric, MUST send back zero or more `RPL_LIST` numerics, and MUST send back one `RPL_LISTEND` numeric. 177 | 178 | Numeric Replies: 179 | 180 | * {% numeric RPL_LISTSTART %} 181 | * {% numeric RPL_LIST %} 182 | * {% numeric RPL_LISTEND %} 183 | 184 | Command Examples: 185 | 186 | LIST ; Command to list all channels 187 | 188 | LIST #twilight_zone,#42 ; Command to list the channels 189 | "#twilight_zone" and "#42". 190 | 191 | LIST >3 ; Command to list all channels with 192 | more than three users. 193 | 194 | LIST C>60 ; Command to list all channels with 195 | created at least 60 minutes ago 196 | 197 | LIST T<60 ; Command to list all channels with 198 | a topic changed within the last 60 minutes 199 | 200 | ### INVITE message 201 | 202 | Command: INVITE 203 | Parameters: 204 | 205 | The `INVITE` command is used to invite a user to a channel. The parameter `` is the nickname of the person to be invited to the target channel ``. 206 | 207 | The target channel SHOULD exist (at least one user is on it). Otherwise, the server SHOULD reject the command with the `ERR_NOSUCHCHANNEL` numeric. 208 | 209 | Only members of the channel are allowed to invite other users. Otherwise, the server MUST reject the command with the `ERR_NOTONCHANNEL` numeric. 210 | 211 | Servers MAY reject the command with the `ERR_CHANOPRIVSNEEDED` numeric. In particular, they SHOULD reject it when the channel has [invite-only](#invite-only-channel-mode) mode set, and the user is not a channel operator. 212 | 213 | If the user is already on the target channel, the server MUST reject the command with the `ERR_USERONCHANNEL` numeric. 214 | 215 | When the invite is successful, the server MUST send a `RPL_INVITING` numeric to the command issuer, and an `INVITE` message, with the issuer as ``, to the target user. Other channel members SHOULD NOT be notified. 216 | 217 | Numeric Replies: 218 | 219 | * {% numeric RPL_INVITING %} 220 | * {% numeric ERR_NEEDMOREPARAMS %} 221 | * {% numeric ERR_NOSUCHCHANNEL %} 222 | * {% numeric ERR_NOTONCHANNEL %} 223 | * {% numeric ERR_CHANOPRIVSNEEDED %} 224 | * {% numeric ERR_USERONCHANNEL %} 225 | 226 | Command Examples: 227 | 228 | INVITE Wiz #foo_bar ; Invite Wiz to #foo_bar 229 | 230 | Message Examples: 231 | 232 | :dan-!d@localhost INVITE Wiz #test ; dan- has invited Wiz 233 | to the channel #test 234 | 235 | See also: 236 | 237 | * IRCv3 [`invite-notify` Extension](https://ircv3.net/specs/extensions/invite-notify) 238 | 239 | #### Invite list 240 | 241 | Servers MAY allow the `INVITE` with no parameter, and reply with a list of channels the sender is invited to as {% numeric RPL_INVITELIST %} numerics, ending with a {% numeric RPL_ENDOFINVITELIST %} numeric. 242 | 243 |
244 |

Some rare implementations use numerics 346/347 instead of 336/337 as `RPL_INVITELIST`/`RPL_ENDOFINVITELIST`. You should check the server you are using implements them as expected.

245 | 246 |

346/347 now generally stands for `RPL_INVEXLIST`/`RPL_ENDOFINVEXLIST`, used for invite-exception list.

247 |
248 | 249 | ### KICK message 250 | 251 | Command: KICK 252 | Parameters: *( "," ) [] 253 | 254 | The KICK command can be used to request the forced removal of a user from a channel. 255 | It causes the `` to be removed from the `` by force. 256 | 257 | This message may be sent from a server to a client to notify the client that someone has been removed from a channel. In this case, the message `` will be the client who sent the kick, and `` will be the channel which the target client has been removed from. 258 | 259 | If no comment is given, the server SHOULD use a default message instead. 260 | 261 | Servers MUST NOT send multiple users in this message to clients, and MUST distribute these multiple-user `KICK` messages as a series of messages with a single user name on each. 262 | This is necessary to maintain backward compatibility with existing client software. 263 | If a `KICK` message is distributed in this way, `` (if it exists) should be on each of these messages. 264 | 265 | Servers MAY limit the number of target users per `KICK` command via the [`TARGMAX` parameter of `RPL_ISUPPORT`](#targmax-parameter), and silently drop targets if the number of targets exceeds the limit. 266 | 267 | Numeric Replies: 268 | 269 | * {% numeric ERR_NEEDMOREPARAMS %} 270 | * {% numeric ERR_NOSUCHCHANNEL %} 271 | * {% numeric ERR_CHANOPRIVSNEEDED %} 272 | * {% numeric ERR_USERNOTINCHANNEL %} 273 | * {% numeric ERR_NOTONCHANNEL %} 274 | 275 | Deprecated Numeric Reply: 276 | 277 | * {% numeric ERR_BADCHANMASK %} 278 | 279 | Examples: 280 | 281 | KICK #Finnish Matthew ; Command to kick Matthew from 282 | #Finnish 283 | 284 | KICK &Melbourne Matthew ; Command to kick Matthew from 285 | &Melbourne 286 | 287 | KICK #Finnish John :Speaking English 288 | ; Command to kick John from #Finnish 289 | using "Speaking English" as the 290 | reason (comment). 291 | 292 | :WiZ!jto@tolsun.oulu.fi KICK #Finnish John 293 | ; KICK message on channel #Finnish 294 | from WiZ to remove John from channel 295 | 296 | -------------------------------------------------------------------------------- /_includes/messages/connection.md: -------------------------------------------------------------------------------- 1 | 2 | ### CAP message 3 | 4 | Command: CAP 5 | Parameters: [:] 6 | 7 | The `CAP` command is used for capability negotiation between a server and a client. 8 | 9 | The `CAP` message may be sent from the server to the client. 10 | 11 | For the exact semantics of the `CAP` command and subcommands, please see the [Capability Negotiation specification](https://ircv3.net/specs/extensions/capability-negotiation.html). 12 | 13 | ### AUTHENTICATE message 14 | 15 | Command: AUTHENTICATE 16 | 17 | The `AUTHENTICATE` command is used for SASL authentication between a server and a client. The client must support and successfully negotiate the `"sasl"` client capability (as listed below in the SASL specifications) before using this command. 18 | 19 | The `AUTHENTICATE` message may be sent from the server to the client. 20 | 21 | For the exact semantics of the `AUTHENTICATE` command and negotiating support for the `"sasl"` client capability, please see the [IRCv3.1](http://ircv3.net/specs/extensions/sasl-3.1.html) and [IRCv3.2](http://ircv3.net/specs/extensions/sasl-3.2.html) SASL Authentication specifications. 22 | 23 | ### PASS message 24 | 25 | Command: PASS 26 | Parameters: 27 | 28 | The `PASS` command is used to set a 'connection password'. If set, the password must be set before any attempt to register the connection is made. This requires that clients send a `PASS` command before sending the `NICK` / `USER` combination. 29 | 30 | The password supplied must match the one defined in the server configuration. It is possible to send multiple `PASS` commands before registering but only the last one sent is used for verification and it may not be changed once the client has been registered. 31 | 32 | If the password supplied does not match the password expected by the server, then the server SHOULD send {% numeric ERR_PASSWDMISMATCH %} and MAY then close the connection with {% message ERROR %}. Servers MUST send at least one of these two messages. 33 | 34 | Servers may also consider requiring [SASL authentication](#authenticate-message) upon connection as an alternative to this, when more information or an alternate form of identity verification is desired. 35 | 36 | Numeric replies: 37 | 38 | * {% numeric ERR_NEEDMOREPARAMS %} 39 | * {% numeric ERR_ALREADYREGISTERED %} 40 | * {% numeric ERR_PASSWDMISMATCH %} 41 | 42 | Command Example: 43 | 44 | PASS secretpasswordhere 45 | 46 | ### NICK message 47 | 48 | Command: NICK 49 | Parameters: 50 | 51 | The `NICK` command is used to give the client a nickname or change the previous one. 52 | 53 | If the server receives a `NICK` command from a client where the desired nickname is already in use on the network, it should issue an `ERR_NICKNAMEINUSE` numeric and ignore the `NICK` command. 54 | 55 | If the server does not accept the new nickname supplied by the client as valid (for instance, due to containing invalid characters), it should issue an `ERR_ERRONEUSNICKNAME` numeric and ignore the `NICK` command. 56 | Servers MUST allow at least all alphanumerical characters, square and curly brackets (`[]{}`), backslashes (`\`), and pipe (`|`) characters in nicknames, and MAY disallow digits as the first character. 57 | Servers MAY allow extra characters, as long as they do not introduce ambiguity in other commands, including: 58 | 59 | * no leading `#` character or other character advertized in {% isupport CHANTYPES %} 60 | * no leading colon (`:`) 61 | * no ASCII space 62 | 63 | If the server does not receive the `` parameter with the `NICK` command, it should issue an `ERR_NONICKNAMEGIVEN` numeric and ignore the `NICK` command. 64 | 65 | The `NICK` message may be sent from the server to clients to acknowledge their `NICK` command was successful, and to inform other clients about the change of nickname. In these cases, the `` of the message will be the old `nickname [ [ "!" user ] "@" host ]` of the user who is changing their nickname. 66 | 67 | Numeric Replies: 68 | 69 | * {% numeric ERR_NONICKNAMEGIVEN %} 70 | * {% numeric ERR_ERRONEUSNICKNAME %} 71 | * {% numeric ERR_NICKNAMEINUSE %} 72 | * {% numeric ERR_NICKCOLLISION %} 73 | 74 | Command Example: 75 | 76 | NICK Wiz ; Requesting the new nick "Wiz". 77 | 78 | Message Examples: 79 | 80 | :WiZ NICK Kilroy ; WiZ changed his nickname to Kilroy. 81 | 82 | :dan-!d@localhost NICK Mamoped 83 | ; dan- changed his nickname to Mamoped. 84 | 85 | ### USER message 86 | 87 | Command: USER 88 | Parameters: 0 * 89 | 90 | The `USER` command is used at the beginning of a connection to specify the username and realname of a new user. 91 | 92 | It must be noted that `` must be the last parameter because it may contain SPACE `(' ',` `0x20)` characters, and should be prefixed with a colon (`:`) if required. 93 | 94 | Servers MAY use the [Ident Protocol](http://tools.ietf.org/html/rfc1413) to look up the 'real username' of clients. If username lookups are enabled and a client does not have an Identity Server enabled, the username provided by the client SHOULD be prefixed by a tilde `('~', 0x7E)` to show that this value is user-set. 95 | 96 | The maximum length of `` may be specified by the {% isupport USERLEN %} `RPL_ISUPPORT` parameter. If this length is advertised, the username MUST be silently truncated to the given length before being used. 97 | The minimum length of `` is 1, ie. it MUST NOT be empty. If it is empty, the server SHOULD reject the command with [`ERR_NEEDMOREPARAMS`](#errneedmoreparams-461) (even if an empty parameter is provided); otherwise it MUST use a default value instead. 98 | 99 | The second and third parameters of this command SHOULD be sent as one zero `('0', 0x30)` and one asterisk character `('*', 0x2A)` by the client, as the meaning of these two parameters varies between different versions of the IRC protocol. 100 | 101 | Clients SHOULD use the nickname as a fallback value for `` and `` when they don't have a meaningful value to use. 102 | 103 | If a client tries to send the `USER` command after they have already completed registration with the server, the `ERR_ALREADYREGISTERED` reply should be sent and the attempt should fail. 104 | 105 | If the client sends a `USER` command after the server has successfully received a username using the Ident Protocol, the `` parameter from this command should be ignored in favour of the one received from the identity server. 106 | 107 | Numeric Replies: 108 | 109 | * {% numeric ERR_NEEDMOREPARAMS %} 110 | * {% numeric ERR_ALREADYREGISTERED %} 111 | 112 | Command Examples: 113 | 114 | USER guest 0 * :Ronnie Reagan 115 | ; No ident server 116 | ; User gets registered with username 117 | "~guest" and real name "Ronnie Reagan" 118 | 119 | USER guest 0 * :Ronnie Reagan 120 | ; Ident server gets contacted and 121 | returns the name "danp" 122 | ; User gets registered with username 123 | "danp" and real name "Ronnie Reagan" 124 | 125 | 126 | ### PING message 127 | 128 | Command: PING 129 | Parameters: 130 | 131 | The `PING` command is sent by either clients or servers to check the other side of the connection is still connected and/or to check for connection latency, at the application layer. 132 | 133 | The `` may be any non-empty string. 134 | 135 | When receiving a `PING` message, clients or servers must reply to it with a {% message PONG %} message with the same `` value. This allows either to match `PONG` with the `PING` they reply to, for example to compute latency. 136 | 137 | Clients should not send `PING` during connection registration, though servers may accept it. 138 | Servers may send `PING` during connection registration and clients must reply to them. 139 | 140 | Older versions of the protocol gave specific semantics to the `` and allowed an extra parameter; but these features are not consistently implemented and should not be relied on. Instead, the `` should be treated as an opaque value by the receiver. 141 | 142 | Numeric Replies: 143 | 144 | * {% numeric ERR_NEEDMOREPARAMS %} 145 | * {% numeric ERR_NOORIGIN %} 146 | 147 | Deprecated Numeric Reply: 148 | 149 | * {% numeric ERR_NOSUCHSERVER %} 150 | 151 | 152 | ### PONG message 153 | 154 | Command: PONG 155 | Parameters: [] 156 | 157 | The `PONG` command is used as a reply to {% message PING %} commands, by both clients and servers. 158 | The `` should be the same as the one in the `PING` message that triggered this `PONG`. 159 | 160 | Servers MUST send a `` parameter, and clients SHOULD ignore it. It exists for historical reasons, and indicates the name of the server sending the PONG. 161 | Clients MUST NOT send a `` parameter. 162 | 163 | Numeric Replies: 164 | 165 | * None 166 | 167 | 168 | ### OPER message 169 | 170 | Command: OPER 171 | Parameters: 172 | 173 | The `OPER` command is used by a normal user to obtain IRC operator privileges. Both parameters are required for the command to be successful. 174 | 175 | If the client does not send the correct password for the given name, the server replies with an `ERR_PASSWDMISMATCH` message and the request is not successful. 176 | 177 | If the client is not connecting from a valid host for the given name, the server replies with an `ERR_NOOPERHOST` message and the request is not successful. 178 | 179 | If the supplied name and password are both correct, and the user is connecting from a valid host, the `RPL_YOUREOPER` message is sent to the user. The user will also receive a {% command MODE %} message indicating their new user modes, and other messages may be sent. 180 | 181 | The `` specified by this command is separate to the accounts specified by SASL authentication, and is generally stored in the IRCd configuration. 182 | 183 | Numeric Replies: 184 | 185 | * {% numeric ERR_NEEDMOREPARAMS %} 186 | * {% numeric ERR_PASSWDMISMATCH %} 187 | * {% numeric ERR_NOOPERHOST %} 188 | * {% numeric RPL_YOUREOPER %} 189 | 190 | Command Example: 191 | 192 | OPER foo bar ; Attempt to register as an operator 193 | using a name of "foo" and the password "bar". 194 | 195 | ### QUIT message 196 | 197 | Command: QUIT 198 | Parameters: [] 199 | 200 | The `QUIT` command is used to terminate a client's connection to the server. The server acknowledges this by replying with an {% command ERROR %} message and closing the connection to the client. 201 | 202 | This message may also be sent from the server to a client to show that a client has exited from the network. This is typically only dispatched to clients that share a channel with the exiting user. When the `QUIT` message is sent to clients, `` represents the client that has exited the network. 203 | 204 | When connections are terminated by a client-sent `QUIT` command, servers SHOULD prepend `` with the ASCII string `"Quit: "` when sending `QUIT` messages to other clients, to represent that this user terminated the connection themselves. This applies even if `` is empty, in which case the reason sent to other clients SHOULD be just this `"Quit: "` string. However, clients SHOULD NOT change behaviour based on the prefix of `QUIT` message reasons, as this is not required behaviour from servers. 205 | 206 | When a netsplit (the disconnecting of two servers) occurs, a `QUIT` message is generated for each client that has exited the network, distributed in the same way as ordinary `QUIT` messages. The `` on these `QUIT` messages SHOULD be composed of the names of the two servers involved, separated by a SPACE `(' ', 0x20)`. The first name is that of the server which is still connected and the second name is that of the server which has become disconnected. If servers wish to hide or obscure the names of the servers involved, the `` on these messages MAY also be the literal ASCII string `"*.net *.split"` (i.e. the two server names are replaced with `"*.net"` and `"*.split"`). Software that implements the IRCv3 [`batch` Extension](http://ircv3.net/specs/extensions/batch-3.2.html) should also look at the [`netsplit` and `netjoin`](http://ircv3.net/specs/extensions/batch/netsplit-3.2.html) batch types. 207 | 208 | If a client connection is closed without the client issuing a `QUIT` command to the server, the server MUST distribute a `QUIT` message to other clients informing them of this, distributed in the same was an ordinary `QUIT` message. Servers MUST fill `` with a message reflecting the nature of the event which caused it to happen. For instance, `"Ping timeout: 120 seconds"`, `"Excess Flood"`, and `"Too many connections from this IP"` are examples of relevant reasons for closing or for a connection with a client to have been closed. 209 | 210 | Numeric Replies: 211 | 212 | * None 213 | 214 | Command Example: 215 | 216 | QUIT :Gone to have lunch ; Client exiting from the network 217 | 218 | Message Example: 219 | 220 | :dan-!d@localhost QUIT :Quit: Bye for now! 221 | ; dan- is exiting the network with 222 | the message: "Quit: Bye for now!" 223 | 224 | 225 | ### ERROR message 226 | 227 | Command: ERROR 228 | Parameters: 229 | 230 | This message is sent from a server to a client to report a fatal error, before terminating the client's connection. 231 | 232 | This MUST only be used to report fatal errors. Regular errors should use the appropriate numerics or the IRCv3 [standard replies](https://ircv3.net/specs/extensions/standard-replies) framework. 233 | 234 | Numeric Replies: 235 | 236 | * None 237 | 238 | Command Example: 239 | 240 | ERROR :Connection timeout ; Server closing a client connection because it 241 | is unresponsive. 242 | -------------------------------------------------------------------------------- /_includes/messages/ircop.md: -------------------------------------------------------------------------------- 1 | The following messages are typically reserved to server operators. 2 | 3 | ### KILL message 4 | 5 | Command: KILL 6 | Parameters: 7 | 8 | The `KILL` command is used to close the connection between a given client and the server they are connected to. `KILL` is a privileged command and is available only to IRC Operators. `` represents the user to be 'killed', and `` is shown to all users and to the user themselves upon being killed. 9 | 10 | When a `KILL` command is used, the client being killed receives the `KILL` message, and the `` of the message SHOULD be the operator who performed the command. The user being killed and every user sharing a channel with them receives a {% command QUIT %} message representing that they are leaving the network. The `` on this `QUIT` message typically has the form: `"Killed ( ())"` where `` is the nickname of the user who performed the `KILL`. The user being killed then receives the {% command ERROR %} message, typically containing a `` of `"Closing Link: (Killed ( ()))"`. After this, their connection is closed. 11 | 12 | If a `KILL` message is received by a client, it means that the user specified by `` is being killed. With certain servers, users may elect to receive `KILL` messages created for other users to keep an eye on the network. This behavior may also be restricted to operators. 13 | 14 | Clients can rejoin instantly after this command is performed on them. However, it can serve as a warning to a user to stop their activity. As it breaks the flow of data from the user, it can also be used to stop large amounts of 'flooding' from abusive users or due to accidents. Abusive users may not care and promptly reconnect and resume their abusive behaviour. In these cases, opers may look at the {% command KLINE %} command to keep them from rejoining the network for a longer time. 15 | 16 | As nicknames across an IRC network MUST be unique, if duplicates are found when servers join, one or both of the clients MAY be `KILL`ed and removed from the network. Servers may also handle this case in alternate ways that don't involve removing users from the network. 17 | 18 | Servers MAY restrict whether specific operators can remove users on other servers (remote users). If the operator tries to remove a remote user but is not privileged to, they should receive the {% numeric ERR_NOPRIVS %} numeric. 19 | 20 | `` SHOULD reflect why the `KILL` was performed. For user-generated `KILL`s, it is up to the user to provide an adequate reason. 21 | 22 | Numeric Replies: 23 | 24 | * {% numeric ERR_NOSUCHSERVER %} 25 | * {% numeric ERR_NEEDMOREPARAMS %} 26 | * {% numeric ERR_NOPRIVILEGES %} 27 | * {% numeric ERR_NOPRIVS %} 28 | 29 |
30 |

NOTE: The KILL message is weird, and I need to look at it more closely, add some examples, etc.

31 |
32 | 33 | ### REHASH message 34 | 35 | Command: REHASH 36 | Parameters: None 37 | 38 | The `REHASH` command is an administrative command which can be used by an operator to force the local server to re-read and process its configuration file. 39 | This may include other data, such as modules or TLS certificates. 40 | 41 | Servers MAY accept, as an optional argument, the name of a remote server that should be rehashed instead of the current one. 42 | 43 | Numeric replies: 44 | 45 | * {% numeric RPL_REHASHING %} 46 | * {% numeric ERR_NOPRIVILEGES %} 47 | 48 | Example: 49 | 50 | REHASH ; message from user with operator 51 | status to server asking it to reread 52 | its configuration file. 53 | 54 | ### RESTART message 55 | 56 | Command: RESTART 57 | Parameters: None 58 | 59 | An operator can use the restart command to force the server to restart itself. 60 | This message is optional since it may be viewed as a risk to allow arbitrary people to connect to a server as an operator and execute this command, causing (at least) a disruption to service. 61 | 62 | Numeric replies: 63 | 64 | * {% numeric ERR_NOPRIVILEGES %} 65 | 66 | Example: 67 | 68 | RESTART ; no parameters required. 69 | 70 | ### SQUIT message 71 | 72 | Command: SQUIT 73 | Parameters: 74 | 75 | The `SQUIT` command disconnects a server from the network. `SQUIT` is a privileged command and is only available to IRC Operators. `` is the reason why the server link is being disconnected. 76 | 77 | In a traditional spanning-tree topology, the command gets forwarded to the specified server. And the link between the specified server and the last server to propagate the command gets broken. 78 | 79 | Numeric replies: 80 | 81 | * {% numeric ERR_NOSUCHSERVER %} 82 | * {% numeric ERR_NEEDMOREPARAMS %} 83 | * {% numeric ERR_NOPRIVILEGES %} 84 | * {% numeric ERR_NOPRIVS %} 85 | 86 | Examples: 87 | 88 | SQUIT tolsun.oulu.fi :Bad Link ? ; Command to uplink of the server 89 | tolson.oulu.fi to terminate its 90 | connection with comment "Bad Link". 91 | 92 | -------------------------------------------------------------------------------- /_includes/messages/messages.md: -------------------------------------------------------------------------------- 1 | ### PRIVMSG message 2 | 3 | Command: PRIVMSG 4 | Parameters: {,} 5 | 6 | The `PRIVMSG` command is used to send private messages between users, as well as to send messages to channels. `` is the nickname of a client or the name of a channel. 7 | 8 | If `` is a channel name and the client is [banned](#ban-channel-mode) and not covered by a [ban exception](#ban-exception-channel-mode), the message will not be delivered and the command will silently fail. Channels with the [moderated](#moderated-channel-mode) mode active may block messages from certain users. Other channel modes may affect the delivery of the message or cause the message to be modified before delivery, and these modes are defined by the server software and configuration being used. 9 | 10 | If a message cannot be delivered to a channel, the server SHOULD respond with an {% numeric ERR_CANNOTSENDTOCHAN %} numeric to let the user know that this message could not be delivered. 11 | 12 | If `` is a channel name, it may be prefixed with one or more [channel membership prefix character (`@`, `+`, etc)](#channel-membership-prefixes) and the message will be delivered only to the members of that channel with the given or higher status in the channel. Servers that support this feature will list the prefixes which this is supported for in the {% isupport STATUSMSG %} `RPL_ISUPPORT` parameter, and this SHOULD NOT be attempted by clients unless the prefix has been advertised in this token. 13 | 14 | If `` is a user and that user has been set as away, the server may reply with an {% numeric RPL_AWAY %} numeric and the command will continue. 15 | 16 | The `PRIVMSG` message is sent from the server to client to deliver a message to that client. The `` of the message represents the user or server that sent the message, and the `` represents the target of that `PRIVMSG` (which may be the client, a channel, etc). 17 | 18 | When the `PRIVMSG` message is sent from a server to a client and `` starts with a dollar character `('$', 0x24)`, the message is a broadcast sent to all clients on one or multiple servers. 19 | 20 | Numeric Replies: 21 | 22 | * {% numeric ERR_NOSUCHNICK %} 23 | * {% numeric ERR_NOSUCHSERVER %} 24 | * {% numeric ERR_CANNOTSENDTOCHAN %} 25 | * ERR_TOOMANYTARGETS (407) 26 | * {% numeric ERR_NORECIPIENT %} 27 | * {% numeric ERR_NOTEXTTOSEND %} 28 | * ERR_NOTOPLEVEL (413) 29 | * ERR_WILDTOPLEVEL (414) 30 | * {% numeric RPL_AWAY %} 31 | 32 |
33 | There are strange "X@Y" target rules and such which are noted in the examples of the original PRIVMSG RFC section. We need to check to make sure modern servers actually process them properly, and if so then specify them. 34 |
35 | 36 | Command Examples: 37 | 38 | PRIVMSG Angel :yes I'm receiving it ! 39 | ; Command to send a message to Angel. 40 | 41 | PRIVMSG %#bunny :Hi! I have a problem! 42 | ; Command to send a message to halfops 43 | and chanops on #bunny. 44 | 45 | PRIVMSG @%#bunny :Hi! I have a problem! 46 | ; Command to send a message to halfops 47 | and chanops on #bunny. This command is 48 | functionally identical to the above 49 | command. 50 | 51 | Message Examples: 52 | 53 | :Angel PRIVMSG Wiz :Hello are you receiving this message ? 54 | ; Message from Angel to Wiz. 55 | 56 | :dan!~h@localhost PRIVMSG #coolpeople :Hi everyone! 57 | ; Message from dan to the channel 58 | #coolpeople 59 | 60 | ### NOTICE message 61 | 62 | Command: NOTICE 63 | Parameters: {,} 64 | 65 | The `NOTICE` command is used to send notices between users, as well as to send notices to channels. `` is interpreted the same way as it is for the {% command PRIVMSG %} command. 66 | 67 | The `NOTICE` message is used similarly to {% command PRIVMSG %}. The difference between `NOTICE` and {% command PRIVMSG %} is that automatic replies must never be sent in response to a `NOTICE` message. This rule also applies to servers -- they must not send any error back to the client on receipt of a `NOTICE` command. The intention of this is to avoid loops between a client automatically sending something in response to something it received. This is typically used by 'bots' (a client with a program, and not a user, controlling their actions) and also for server messages to clients. 68 | 69 | One thing for bot authors to note is that the `NOTICE` message may be interpreted differently by various clients. Some clients highlight or interpret any `NOTICE` sent to a channel in the same way that a `PRIVMSG` with their nickname gets interpreted. This means that users may be irritated by the use of `NOTICE` messages rather than `PRIVMSG` messages by clients or bots, and they are not commonly used by client bots for this reason. 70 | 71 | -------------------------------------------------------------------------------- /_includes/messages/optional.md: -------------------------------------------------------------------------------- 1 | These messages are not required for a server implementation to work, but SHOULD be implemented. If a command is not implemented, it MUST return the {% numeric ERR_UNKNOWNCOMMAND %} numeric. 2 | 3 | ### AWAY message 4 | 5 | Command: AWAY 6 | Parameters: [] 7 | 8 | The `AWAY` command lets clients indicate that their user is away. 9 | If this command is sent with a nonempty parameter (the 'away message') then the user is set to be away. If this command is sent with no parameters, or with the empty string as the parameter, the user is no longer away. 10 | 11 | The server acknowledges the change in away status by returning the {% numeric RPL_NOWAWAY %} and {% numeric RPL_UNAWAY %} numerics. 12 | If the [IRCv3 `away-notify` capability](https://ircv3.net/specs/extensions/away-notify.html) has been requested by a client, the server MAY also send that client `AWAY` messages to tell them how the away status of other users has changed. 13 | 14 | Servers SHOULD notify clients when a user they're interacting with is away when relevant, including sending these numerics: 15 | 16 | 1. {% numeric RPL_AWAY %}, with the away message, when a {% command PRIVMSG %} command is directed at the away user (not to a channel they are on). 17 | 2. {% numeric RPL_AWAY %}, with the away message, in replies to {% command WHOIS %} messages. 18 | 3. In the {% numeric RPL_USERHOST %} numeric, as the `+` or `-` character. 19 | 4. In the {% numeric RPL_WHOREPLY %} numeric, as the `H` or `G` character. 20 | 21 | Numeric Replies: 22 | 23 | * {% numeric RPL_UNAWAY %} 24 | * {% numeric RPL_NOWAWAY %} 25 | 26 | ### LINKS message 27 | 28 | Command: LINKS 29 | Parameters: None 30 | 31 | With LINKS, a user can list all servers which are known by the server answering the query, usually including the server itself. 32 | 33 | In replying to the LINKS message, a server MUST send replies back using zero or more {% numeric RPL_LINKS %} messages and mark the end of the list using a {% numeric RPL_ENDOFLINKS %} message. 34 | 35 | Servers MAY omit some or all servers on the network, including itself. 36 | 37 | Numeric Replies: 38 | 39 | * {% numeric RPL_LINKS %} 40 | * {% numeric RPL_ENDOFLINKS %} 41 | 42 | Reply Example: 43 | 44 | :My.Little.Server 364 nick services.example.org My.Little.Server :1 Anope IRC Services 45 | :My.Little.Server 364 nick My.Little.Server My.Little.Server :0 test server 46 | :My.Little.Server 365 nick * :End of /LINKS list. 47 | 48 | ### USERHOST message 49 | 50 | Command: USERHOST 51 | Parameters: { } 52 | 53 | The `USERHOST` command is used to return information about users with the given nicknames. The `USERHOST` command takes up to five nicknames, each a separate parameters. The nicknames are returned in {% numeric RPL_USERHOST %} numerics. 54 | 55 | Numeric Replies: 56 | 57 | * {% numeric ERR_NEEDMOREPARAMS %} 58 | * {% numeric RPL_USERHOST %} 59 | 60 | Command Examples: 61 | 62 | USERHOST Wiz Michael Marty p ;USERHOST request for information on 63 | nicks "Wiz", "Michael", "Marty" and "p" 64 | 65 | Reply Examples: 66 | 67 | :ircd.stealth.net 302 yournick :syrk=+syrk@millennium.stealth.net 68 | ; Reply for user syrk 69 | 70 | ### WALLOPS message 71 | 72 | Command: WALLOPS 73 | Parameters: 74 | 75 | The WALLOPS command is used to send a message to all currently connected users who have set the 'w' user mode for themselves. 76 | The `` SHOULD be non-empty. 77 | 78 | Servers MAY echo WALLOPS messages to their sender even if they don't have the 'w' user mode. 79 | 80 | Servers MAY send WALLOPS only to operators. 81 | 82 | Servers may generate it themselves, and MAY allow operators to send them. 83 | 84 | Numeric replies: 85 | 86 | * {% numeric ERR_NEEDMOREPARAMS %} 87 | * {% numeric ERR_NOPRIVILEGES %} 88 | * {% numeric ERR_NOPRIVS %} 89 | 90 | Examples: 91 | 92 | :csd.bu.edu WALLOPS :Connect '*.uiuc.edu 6667' from Joshua 93 | ;WALLOPS message from csd.bu.edu announcing 94 | a CONNECT message it received and acted 95 | upon from Joshua. 96 | 97 | -------------------------------------------------------------------------------- /_includes/messages/user_queries.md: -------------------------------------------------------------------------------- 1 | ### WHO message 2 | 3 | Command: WHO 4 | Parameters: 5 | 6 | This command is used to query a list of users who match the provided mask. 7 | The server will answer this command with zero, one or more [`RPL_WHOREPLY`](#rplwhoreply-352), and end the list with [`RPL_ENDOFWHO`](#rplendofwho-315). 8 | 9 | The mask can be one of the following: 10 | 11 | * A channel name, in which case the channel members are listed. 12 | * An exact nickname, in which case a single user is returned. 13 | * A mask pattern, in which case all visible users whose nickname matches are listed. Servers MAY match other user-specific values, such as the hostname, server, real name or username. Servers MAY not support mask patterns and return an empty list. 14 | 15 | Visible users are users who either aren't invisible ([user mode `+i`](#invisible-user-mode)) or have a common channel with the requesting client. 16 | Servers MAY filter or limit visible users replies arbitrarily. 17 | 18 | Numeric Replies: 19 | 20 | * {% numeric RPL_WHOREPLY %} 21 | * {% numeric RPL_ENDOFWHO %} 22 | 23 | See also: 24 | 25 | * IRCv3 [`multi-prefix` Extension](https://ircv3.net/specs/extensions/multi-prefix) 26 | * [WHOX](https://ircv3.net/specs/extensions/whox) 27 | 28 | #### Examples 29 | 30 | Command Examples: 31 | 32 | WHO emersion ; request information on user "emersion" 33 | WHO #ircv3 ; list users in the "#ircv3" channel 34 | 35 | Reply Examples: 36 | 37 | :calcium.libera.chat 352 dan #ircv3 ~emersion sourcehut/staff/emersion calcium.libera.chat emersion H :1 Simon Ser 38 | :calcium.libera.chat 315 dan emersion :End of WHO list 39 | ; Reply to WHO emersion 40 | 41 | :calcium.libera.chat 352 dan #ircv3 ~emersion sourcehut/staff/emersion calcium.libera.chat emersion H :1 Simon Ser 42 | :calcium.libera.chat 352 dan #ircv3 ~val limnoria/val calcium.libera.chat val H :1 Val 43 | :calcium.libera.chat 315 dan #ircv3 :End of WHO list 44 | ; Reply to WHO #ircv3 45 | 46 | ### WHOIS message 47 | 48 | Command: WHOIS 49 | Parameters: [] 50 | 51 | This command is used to query information about a particular user. 52 | The server SHOULD answer this command with numeric messages with information about the nick. 53 | 54 | The server SHOULD end its response (to a syntactically well-formed client message) with [`RPL_ENDOFWHOIS`](#rplendofwhois-318), even if it did not send any other numeric message. This allows clients to stop waiting for new numerics. In exceptional error conditions, servers MAY not reply to a `WHOIS` command. Clients SHOULD implement a hard timeout to avoid waiting for a reply which won't come. 55 | 56 | Client MUST NOT not assume all numeric messages are sent at once, as server can interleave other messages before the end of the WHOIS response. 57 | 58 | If the `` parameter is specified, it SHOULD be a server name or the nick of a user. Servers SHOULD send the query to a specific server with that name, or to the server `` is connected to, respectively. 59 | Typically, it is used by clients who want to know how long the user in question has been idle (as typically only the server the user is directly connected to knows that information, while everything else this command returns is globally known). 60 | 61 | The following numerics MAY be returned as part of the whois reply: 62 | 63 | * {% numeric ERR_NOSUCHNICK %} 64 | * {% numeric ERR_NOSUCHSERVER %} 65 | * {% numeric ERR_NONICKNAMEGIVEN %} 66 | * {% numeric RPL_WHOISCERTFP %} 67 | * {% numeric RPL_WHOISREGNICK %} 68 | * {% numeric RPL_WHOISUSER %} 69 | * {% numeric RPL_WHOISSERVER %} 70 | * {% numeric RPL_WHOISOPERATOR %} 71 | * {% numeric RPL_WHOISIDLE %} 72 | * {% numeric RPL_WHOISCHANNELS %} 73 | * {% numeric RPL_WHOISSPECIAL %} 74 | * {% numeric RPL_WHOISACCOUNT %} 75 | * {% numeric RPL_WHOISACTUALLY %} 76 | * {% numeric RPL_WHOISHOST %} 77 | * {% numeric RPL_WHOISMODES %} 78 | * {% numeric RPL_WHOISSECURE %} 79 | * {% numeric RPL_AWAY %} 80 | 81 | Servers typically send some of these numerics only to the client itself and to servers operators, as they contain privacy-sensitive information that should not be revealed to other users. 82 | 83 | Server implementers wishing to send information not covered by these numerics may send other vendor-specific numerics, such that: 84 | 85 | * the first and second parameters MUST be the client's nick, and the target nick, and 86 | * the last parameter SHOULD be designed to be human-readable, so that user interfaces can display unknown numerics 87 | 88 | Additionally, server implementers should consider submitting these to [IRCv3](https://ircv3.net/) for standardization, if relevant. 89 | 90 | #### Optional extensions 91 | 92 | This section describes extension to the common `WHOIS` command above. 93 | They exist mainly on historical servers, and are rarely implemented, because of resource usage they incur. 94 | 95 | * Servers MAY allow more than one target nick. 96 | They can advertise the maximum the number of target users per `WHOIS` command via the {% isupport TARGMAX %} `RPL_ISUPPORT` parameter, and silently drop targets if the number of targets exceeds the limit. 97 | 98 | * Servers MAY allow wildcards in ``. Servers who do SHOULD reply with information about all matching nicks. They may restrict what information is available in this case, to limit resource usage. 99 | 100 | * IRCv3 [`multi-prefix` Extension](https://ircv3.net/specs/extensions/multi-prefix) 101 | 102 | #### Examples 103 | 104 | Command Examples: 105 | 106 | WHOIS val ; request information on user "val" 107 | WHOIS val val ; request information on user "val", 108 | from the server they are on 109 | WHOIS calcium.libera.chat val ; request information on user "val", 110 | from server calcium.libera.chat 111 | 112 | Reply Example: 113 | 114 | :calcium.libera.chat 311 val val ~val limnoria/val * :Val 115 | :calcium.libera.chat 319 val val :#ircv3 #libera +#limnoria 116 | :calcium.libera.chat 319 val val :#weechat 117 | :calcium.libera.chat 312 val val calcium.libera.chat :Montreal, CA 118 | :calcium.libera.chat 671 val val :is using a secure connection [TLSv1.3, TLS_AES_256_GCM_SHA384] 119 | :calcium.libera.chat 317 val val 657 1628028154 :seconds idle, signon time 120 | :calcium.libera.chat 330 val val pinkieval :is logged in as 121 | :calcium.libera.chat 318 val val :End of /WHOIS list. 122 | 123 | ### WHOWAS message 124 | 125 | Command: WHOWAS 126 | Parameters: [] 127 | 128 | Whowas asks for information about a nickname which no longer exists. 129 | This may either be due to a nickname change or the user leaving IRC. 130 | In response to this query, the server searches through its nickname history, looking for any nicks which are lexically the same (no wild card matching here). 131 | The history is searched backward, returning the most recent entry first. 132 | If there are multiple entries, up to `` replies will be returned (or all of them if no `` parameter is given). 133 | 134 | If given, `` SHOULD be a positive number. Otherwise, a full search is done. 135 | 136 | Servers MUST reply with either {% numeric ERR_WASNOSUCHNICK %} or a non-empty list of WHOWAS entries, 137 | both followed with {% numeric RPL_ENDOFWHOWAS %} 138 | 139 | A WHOWAS entry is a series of numeric messages starting with {% numeric RPL_WHOWASUSER %}, optionally followed by other numerics relevant to that user, such as {% numeric RPL_WHOISACTUALLY %} and {% numeric RPL_WHOISSERVER %}. 140 | Clients MUST NOT assume any particular numeric other than {% numeric RPL_WHOWASUSER %} is present in a WHOWAS entry. 141 | 142 | If the `` argument is missing, they SHOULD send a single reply, using either {% numeric ERR_NONICKNAMEGIVEN %} or {% numeric ERR_NEEDMOREPARAMS %}. 143 | 144 | #### Examples 145 | 146 | Command Examples: 147 | 148 | WHOWAS someone 149 | WHOWAS someone 2 150 | 151 | Reply Examples: 152 | 153 | :inspircd.server.example 314 val someone ident3 127.0.0.1 * :Realname 154 | :inspircd.server.example 312 val someone My.Little.Server :Sun Mar 20 2022 10:59:26 155 | :inspircd.server.example 314 val someone ident2 127.0.0.1 * :Realname 156 | :inspircd.server.example 312 val someone My.Little.Server :Sun Mar 20 2022 10:59:16 157 | :inspircd.server.example 369 val someone :End of WHOWAS 158 | 159 | :ergo.server.example 314 val someone ~ident3 127.0.0.1 * Realname 160 | :ergo.server.example 314 val someone ~ident2 127.0.0.1 * Realname 161 | :ergo.server.example 369 val someone :End of WHOWAS 162 | 163 | :solanum.server.example 314 val someone ~ident3 localhost * :Realname 164 | :solanum.server.example 338 val someone 127.0.0.1 :actually using host 165 | :solanum.server.example 312 val someone solanum.server.example :Sun Mar 20 10:07:44 2022 166 | :solanum.server.example 314 val someone ~ident2 localhost * :Realname 167 | :solanum.server.example 338 val someone 127.0.0.1 :actually using host 168 | :solanum.server.example 312 val someone solanum.server.example :Sun Mar 20 10:07:34 2022 169 | :solanum.server.example 369 val someone :End of WHOWAS 170 | 171 | :server.example 406 val someone :There was no such nickname 172 | :server.example 369 val someone :End of WHOWAS 173 | 174 | -------------------------------------------------------------------------------- /_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% if page.html_title %}{{ page.html_title }}{% else %}{{ page.title }}{% endif %} 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 40 | {% if page.wip %} 41 |
42 | This document is a heavy work in progress
and should not be considered complete
43 |
44 | {% endif %} 45 | {% if page.ietf %} 46 |
47 | This document is now being worked on as an
Internet-Draft which you can find here and here
48 |
49 | {% endif %} 50 | 51 | 52 | 53 | {% if page.ietf %} 54 |
55 |

This document is out of date and is now being persued as an Internet-Draft for standardisation with the IETF. You should look here for the document that replaces this:

56 |

57 | [Internet-Draft] - 58 | [Editor's HTML Draft] - 59 | [Editor's TXT Draft] - 60 | [Github] 61 |

62 |
63 | {% endif %} 64 | 65 | 74 |
75 |
76 |

{{ page.title }}

77 | 78 |
79 | {% if page.toc %} 80 | {% assign content_array = content | split: site.excerpt_separator %} 81 | {% assign excerpt_only = content_array | first %} 82 | {% assign content_remainder = content_array | last %} 83 | {{ excerpt_only }} 84 |
85 |

Table of Contents

86 | {{ content_remainder | toc }} 87 | {% else %} 88 | {{ content }} 89 | {% endif %} 90 |
91 |
92 |
93 | 99 | 100 | 120 | 121 | -------------------------------------------------------------------------------- /_plugins/easy-ids.rb: -------------------------------------------------------------------------------- 1 | # written by daniel oaks 2 | # released under cc0 public domain 3 | 4 | # this lets you easily insert headers with custom IDs. 5 | # 6 | # e.g. 7 | # tag: 8 | # {% h3 message-VERSION %}_VERSION_ message{% endh3 %} 9 | # makes: 10 | #

VERSION message

11 | 12 | def slug(input) 13 | input.strip.gsub(/\s+/, " ") 14 | end 15 | 16 | module Jekyll 17 | class HeadingTagBlock < Liquid::Block 18 | def initialize(name, params, tokens) 19 | super 20 | @name = name 21 | @id = params 22 | end 23 | 24 | def render(context) 25 | text = super 26 | 27 | # markdowify text, then remove

tag. 28 | # see also https://talk.jekyllrb.com/t/markdown-parsing-order-in-custom-liquid-tags/4397/3 29 | text = context.registers[:site].find_converter_instance( 30 | Jekyll::Converters::Markdown 31 | ).convert(text).gsub(/<\/?p[^>]*>/, "").strip 32 | 33 | "<#{@name} id=\"#{slug(@id)}\">#{text}" 34 | end 35 | end 36 | end 37 | 38 | Liquid::Template.register_tag('h1', Jekyll::HeadingTagBlock) 39 | Liquid::Template.register_tag('h2', Jekyll::HeadingTagBlock) 40 | Liquid::Template.register_tag('h3', Jekyll::HeadingTagBlock) 41 | Liquid::Template.register_tag('h4', Jekyll::HeadingTagBlock) 42 | Liquid::Template.register_tag('h5', Jekyll::HeadingTagBlock) 43 | -------------------------------------------------------------------------------- /_plugins/modern-ircdocs.rb: -------------------------------------------------------------------------------- 1 | # written by daniel oaks 2 | # released under cc0 public domain 3 | 4 | # this lets you easily insert headers for numerics/commands/isupport and link to them 5 | # 6 | # {% commandheader WHO %} and {% messageheader WHO %} 7 | # - create the WHO message header, with an appropriate ID 8 | # 9 | # {% command WHO %} and {% message WHO %} 10 | # - link to the WHO message 11 | # 12 | # {% numericheader RPL_WELCOME %} 13 | # - create the RPL_WELCOME numeric header 14 | # - numeric data MUST exist in the _data/modern.yml file 15 | # 16 | # {% numeric RPL_WELCOME %} 17 | # - link to the RPL_WELCOME numeric 18 | # - numeric data MUST exist in the _data/modern.yml file 19 | # 20 | # {% isupportheader TARGMAX %} 21 | # - create the ISUPPORT TARGMAX parameter header 22 | # 23 | # {% isupport TARGMAX %} 24 | # - link to the TARGMAX ISUPPORT parameter 25 | 26 | def slug(input) 27 | input.strip.gsub(/\s+/, ' ') 28 | end 29 | 30 | def numericAnchor(name, numeric) 31 | "#{name.gsub(/_/, '').downcase}-#{numeric}" 32 | end 33 | 34 | module IRCdocsPlugin 35 | class MessageHeaderTag < Liquid::Tag 36 | def initialize(name, params, tokens) 37 | super 38 | @id = slug(params) 39 | end 40 | 41 | def render(context) 42 | super 43 | 44 | "

#{@id} Message

" 45 | end 46 | end 47 | 48 | class MessageTag < Liquid::Tag 49 | def initialize(name, params, tokens) 50 | super 51 | @id = slug(params) 52 | end 53 | 54 | def render(context) 55 | super 56 | 57 | "#{@id}" 58 | end 59 | end 60 | 61 | class NumericHeaderTag < Liquid::Tag 62 | def initialize(name, params, tokens) 63 | super 64 | @id = slug(params) 65 | end 66 | 67 | def render(context) 68 | super 69 | 70 | info = context.registers[:site].data['modern']['numerics'][@id] 71 | if info == nil 72 | raise "Numeric [#{@id}] is not defined in modern.yml" 73 | end 74 | 75 | "

#{@id} (#{info['numeric']})

" 76 | end 77 | end 78 | 79 | class NumericTag < Liquid::Tag 80 | def initialize(name, params, tokens) 81 | super 82 | @id = slug(params) 83 | end 84 | 85 | def render(context) 86 | super 87 | 88 | info = context.registers[:site].data['modern']['numerics'][@id] 89 | if info == nil 90 | raise "Numeric [#{@id}] is not defined in modern.yml" 91 | end 92 | 93 | "#{@id} (#{info['numeric']})" 94 | end 95 | end 96 | 97 | class IsupportHeaderTag < Liquid::Tag 98 | def initialize(name, params, tokens) 99 | super 100 | @id = slug(params) 101 | end 102 | 103 | def render(context) 104 | super 105 | 106 | "

#{@id} Parameter

" 107 | end 108 | end 109 | 110 | class IsupportTag < Liquid::Tag 111 | def initialize(name, params, tokens) 112 | super 113 | @id = slug(params) 114 | end 115 | 116 | def render(context) 117 | super 118 | 119 | "#{@id}" 120 | end 121 | end 122 | end 123 | 124 | Liquid::Template.register_tag('messageheader', IRCdocsPlugin::MessageHeaderTag) 125 | Liquid::Template.register_tag('commandheader', IRCdocsPlugin::MessageHeaderTag) 126 | Liquid::Template.register_tag('message', IRCdocsPlugin::MessageTag) 127 | Liquid::Template.register_tag('command', IRCdocsPlugin::MessageTag) 128 | Liquid::Template.register_tag('numericheader', IRCdocsPlugin::NumericHeaderTag) 129 | Liquid::Template.register_tag('numeric', IRCdocsPlugin::NumericTag) 130 | Liquid::Template.register_tag('isupportheader', IRCdocsPlugin::IsupportHeaderTag) 131 | Liquid::Template.register_tag('isupport', IRCdocsPlugin::IsupportTag) 132 | -------------------------------------------------------------------------------- /about.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: About 3 | layout: default 4 | --- 5 | 6 | This site contains documents describing the IRC protocol and related technologies (affectionately called the 'Modern docs'). The documents hosted here are intended to be useful to software developers working with IRC. They contain existing behaviour and what we consider best-practices for new software. 7 | 8 | If something written in these documents isn't correct for or interoperable with an IRC client / server / network you know of, please open an issue or send me an [email](mailto:daniel@danieloaks.net). Pull requests are appreciated. 9 | 10 | For suggestions of other documents to create / maintain, please [create an issue](https://github.com/ircdocs/modern-irc/issues) or [send me an email](mailto:daniel@danieloaks.net)! 11 | 12 | --- 13 | 14 | ## Guidelines 15 | 16 | These documents SHOULD NOT describe brand new behaviour, but existing behaviour present in IRC software and/or networks (new extensions are IRCv3's area). These documents should be useful to IRC developers **today**, not in 10 years time. 17 | 18 | The behaviour and constants described in these documents SHOULD converge, and/or be interoperable with the majority of IRC software. These documents should let a client or server author build software which can communicate with almost any other piece of IRC software it interacts with. 19 | 20 | Where external, up-to-date and authoritative specifications exist for commands/messages/behaviours, we prefer to link to those rather than needlessly rewrite them (see the Client Protocol's [`CAP`](http://modern.ircdocs.horse/#cap-message) message for an example of this). 21 | 22 | These document are not RFCs. Writing an RFC and putting it through the IETF process is a long slog that's probably going to be completed by someone else if at all, and whoever does it is free to use anything from these documents. Just respect the authors section at the top of the document if a decent amount of text is used from it. 23 | 24 | --- 25 | 26 | ## Living Specifications 27 | 28 | We consider the documents on this site to be 'living specifications'. This means they are updated as feedback is received for them and as the protocol is extended and grows. Bugs can be fixed, incorrect behaviours in the specifications can be corrected, and they can be extended as new behaviour becomes widespread. 29 | 30 | These documents are called 'specifications' rather than standards because they're descriptive, not prescriptive. These specifications are written in response to observed behaviour, rather than changing already-widespread behaviour to match what's written here. 31 | 32 | This term and our use of it is based on the WHATWG definition of a ['living standard'](https://wiki.whatwg.org/wiki/FAQ#What_does_.22Living_Standard.22_mean.3F). 33 | 34 | --- 35 | 36 | ## Are these documents standards or signed off by multiple vendors? 37 | 38 | These documents are explicitly not standards and not signed off by a collection of vendors. These documents are signed off by the editor of that document (though we gladly accept contributors and PRs). 39 | 40 | Regardless, I hope you find these documents useful and investigate protocol extensions with the [IRCv3 Working Group](http://ircv3.net). 41 | 42 | --- 43 | 44 | ## What are your plans for these documents? 45 | 46 | There have been questions about doing this work with IRCv3, the IETF, etc. I'm keeping it separate for now, and this section explains why. 47 | 48 | I started writing the Modern doc on my own site because I like being able to work at my own pace. When you introduce standards orgs like IRCv3 and the IETF, changes end up having to get signed-off by multiple people. This slows things down, and as a result I lose interest and stop putting time into it. Having the documents here lets me (and any other editors) work at their own pace, and put changes online without needing to worry about getting them approved or having to argue for them. 49 | 50 | That slower, multiple-people signoff process is necessary for new standards, and those other standards groups are great. However, I feel like those processes don't work as well for these documents in particular, with where they are right now and their aim. 51 | 52 | This work will probably end up being integrated into one of those groups down the line, and be submitted as some sort of RFC. However, for now I'm happy working on them, productively, with this sort of editor-focused process. 53 | -------------------------------------------------------------------------------- /css/open-sans.css: -------------------------------------------------------------------------------- 1 | /* BEGIN Light */ 2 | @font-face { 3 | font-family: 'Open Sans'; 4 | src: url("../fonts/Light/OpenSans-Light.eot?v=1.1.0"); 5 | src: url("../fonts/Light/OpenSans-Light.eot?#iefix&v=1.1.0") format("embedded-opentype"), url("../fonts/Light/OpenSans-Light.woff2?v=1.1.0") format("woff2"), url("../fonts/Light/OpenSans-Light.woff?v=1.1.0") format("woff"), url("../fonts/Light/OpenSans-Light.ttf?v=1.1.0") format("truetype"), url("../fonts/Light/OpenSans-Light.svg?v=1.1.0#Light") format("svg"); 6 | font-weight: 300; 7 | font-style: normal; } 8 | /* END Light */ 9 | /* BEGIN Light Italic */ 10 | @font-face { 11 | font-family: 'Open Sans'; 12 | src: url("../fonts/LightItalic/OpenSans-LightItalic.eot?v=1.1.0"); 13 | src: url("../fonts/LightItalic/OpenSans-LightItalic.eot?#iefix&v=1.1.0") format("embedded-opentype"), url("../fonts/LightItalic/OpenSans-LightItalic.woff2?v=1.1.0") format("woff2"), url("../fonts/LightItalic/OpenSans-LightItalic.woff?v=1.1.0") format("woff"), url("../fonts/LightItalic/OpenSans-LightItalic.ttf?v=1.1.0") format("truetype"), url("../fonts/LightItalic/OpenSans-LightItalic.svg?v=1.1.0#LightItalic") format("svg"); 14 | font-weight: 300; 15 | font-style: italic; } 16 | /* END Light Italic */ 17 | /* BEGIN Regular */ 18 | @font-face { 19 | font-family: 'Open Sans'; 20 | src: url("../fonts/Regular/OpenSans-Regular.eot?v=1.1.0"); 21 | src: url("../fonts/Regular/OpenSans-Regular.eot?#iefix&v=1.1.0") format("embedded-opentype"), url("../fonts/Regular/OpenSans-Regular.woff2?v=1.1.0") format("woff2"), url("../fonts/Regular/OpenSans-Regular.woff?v=1.1.0") format("woff"), url("../fonts/Regular/OpenSans-Regular.ttf?v=1.1.0") format("truetype"), url("../fonts/Regular/OpenSans-Regular.svg?v=1.1.0#Regular") format("svg"); 22 | font-weight: normal; 23 | font-style: normal; } 24 | /* END Regular */ 25 | /* BEGIN Italic */ 26 | @font-face { 27 | font-family: 'Open Sans'; 28 | src: url("../fonts/Italic/OpenSans-Italic.eot?v=1.1.0"); 29 | src: url("../fonts/Italic/OpenSans-Italic.eot?#iefix&v=1.1.0") format("embedded-opentype"), url("../fonts/Italic/OpenSans-Italic.woff2?v=1.1.0") format("woff2"), url("../fonts/Italic/OpenSans-Italic.woff?v=1.1.0") format("woff"), url("../fonts/Italic/OpenSans-Italic.ttf?v=1.1.0") format("truetype"), url("../fonts/Italic/OpenSans-Italic.svg?v=1.1.0#Italic") format("svg"); 30 | font-weight: normal; 31 | font-style: italic; } 32 | /* END Italic */ 33 | /* BEGIN Semibold */ 34 | @font-face { 35 | font-family: 'Open Sans'; 36 | src: url("../fonts/Semibold/OpenSans-Semibold.eot?v=1.1.0"); 37 | src: url("../fonts/Semibold/OpenSans-Semibold.eot?#iefix&v=1.1.0") format("embedded-opentype"), url("../fonts/Semibold/OpenSans-Semibold.woff2?v=1.1.0") format("woff2"), url("../fonts/Semibold/OpenSans-Semibold.woff?v=1.1.0") format("woff"), url("../fonts/Semibold/OpenSans-Semibold.ttf?v=1.1.0") format("truetype"), url("../fonts/Semibold/OpenSans-Semibold.svg?v=1.1.0#Semibold") format("svg"); 38 | font-weight: 600; 39 | font-style: normal; } 40 | /* END Semibold */ 41 | /* BEGIN Semibold Italic */ 42 | @font-face { 43 | font-family: 'Open Sans'; 44 | src: url("../fonts/SemiboldItalic/OpenSans-SemiboldItalic.eot?v=1.1.0"); 45 | src: url("../fonts/SemiboldItalic/OpenSans-SemiboldItalic.eot?#iefix&v=1.1.0") format("embedded-opentype"), url("../fonts/SemiboldItalic/OpenSans-SemiboldItalic.woff2?v=1.1.0") format("woff2"), url("../fonts/SemiboldItalic/OpenSans-SemiboldItalic.woff?v=1.1.0") format("woff"), url("../fonts/SemiboldItalic/OpenSans-SemiboldItalic.ttf?v=1.1.0") format("truetype"), url("../fonts/SemiboldItalic/OpenSans-SemiboldItalic.svg?v=1.1.0#SemiboldItalic") format("svg"); 46 | font-weight: 600; 47 | font-style: italic; } 48 | /* END Semibold Italic */ 49 | /* BEGIN Bold */ 50 | @font-face { 51 | font-family: 'Open Sans'; 52 | src: url("../fonts/Bold/OpenSans-Bold.eot?v=1.1.0"); 53 | src: url("../fonts/Bold/OpenSans-Bold.eot?#iefix&v=1.1.0") format("embedded-opentype"), url("../fonts/Bold/OpenSans-Bold.woff2?v=1.1.0") format("woff2"), url("../fonts/Bold/OpenSans-Bold.woff?v=1.1.0") format("woff"), url("../fonts/Bold/OpenSans-Bold.ttf?v=1.1.0") format("truetype"), url("../fonts/Bold/OpenSans-Bold.svg?v=1.1.0#Bold") format("svg"); 54 | font-weight: bold; 55 | font-style: normal; } 56 | /* END Bold */ 57 | /* BEGIN Bold Italic */ 58 | @font-face { 59 | font-family: 'Open Sans'; 60 | src: url("../fonts/BoldItalic/OpenSans-BoldItalic.eot?v=1.1.0"); 61 | src: url("../fonts/BoldItalic/OpenSans-BoldItalic.eot?#iefix&v=1.1.0") format("embedded-opentype"), url("../fonts/BoldItalic/OpenSans-BoldItalic.woff2?v=1.1.0") format("woff2"), url("../fonts/BoldItalic/OpenSans-BoldItalic.woff?v=1.1.0") format("woff"), url("../fonts/BoldItalic/OpenSans-BoldItalic.ttf?v=1.1.0") format("truetype"), url("../fonts/BoldItalic/OpenSans-BoldItalic.svg?v=1.1.0#BoldItalic") format("svg"); 62 | font-weight: bold; 63 | font-style: italic; } 64 | /* END Bold Italic */ 65 | /* BEGIN Extrabold */ 66 | @font-face { 67 | font-family: 'Open Sans'; 68 | src: url("../fonts/ExtraBold/OpenSans-ExtraBold.eot?v=1.1.0"); 69 | src: url("../fonts/ExtraBold/OpenSans-ExtraBold.eot?#iefix&v=1.1.0") format("embedded-opentype"), url("../fonts/ExtraBold/OpenSans-ExtraBold.woff2?v=1.1.0") format("woff2"), url("../fonts/ExtraBold/OpenSans-ExtraBold.woff?v=1.1.0") format("woff"), url("../fonts/ExtraBold/OpenSans-ExtraBold.ttf?v=1.1.0") format("truetype"), url("../fonts/ExtraBold/OpenSans-ExtraBold.svg?v=1.1.0#ExtraBold") format("svg"); 70 | font-weight: 800; 71 | font-style: normal; } 72 | /* END Extrabold */ 73 | /* BEGIN Extrabold Italic */ 74 | @font-face { 75 | font-family: 'Open Sans'; 76 | src: url("../fonts/ExtraBoldItalic/OpenSans-ExtraBoldItalic.eot?v=1.1.0"); 77 | src: url("../fonts/ExtraBoldItalic/OpenSans-ExtraBoldItalic.eot?#iefix&v=1.1.0") format("embedded-opentype"), url("../fonts/ExtraBoldItalic/OpenSans-ExtraBoldItalic.woff2?v=1.1.0") format("woff2"), url("../fonts/ExtraBoldItalic/OpenSans-ExtraBoldItalic.woff?v=1.1.0") format("woff"), url("../fonts/ExtraBoldItalic/OpenSans-ExtraBoldItalic.ttf?v=1.1.0") format("truetype"), url("../fonts/ExtraBoldItalic/OpenSans-ExtraBoldItalic.svg?v=1.1.0#ExtraBoldItalic") format("svg"); 78 | font-weight: 800; 79 | font-style: italic; } 80 | /* END Extrabold Italic */ 81 | 82 | /*# sourceMappingURL=open-sans.css.map */ 83 | -------------------------------------------------------------------------------- /css/pure-min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | Pure v0.6.0 3 | Copyright 2014 Yahoo! Inc. All rights reserved. 4 | Licensed under the BSD License. 5 | https://github.com/yahoo/pure/blob/master/LICENSE.md 6 | */ 7 | /*! 8 | normalize.css v^3.0 | MIT License | git.io/normalize 9 | Copyright (c) Nicolas Gallagher and Jonathan Neal 10 | */ 11 | /*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0;text-decoration:underline}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}.hidden,[hidden]{display:none!important}.pure-img{max-width:100%;height:auto;display:block}.pure-g{letter-spacing:-.31em;*letter-spacing:normal;*word-spacing:-.43em;text-rendering:optimizespeed;font-family:FreeSans,Arimo,"Droid Sans",Helvetica,Arial,sans-serif;display:-webkit-flex;-webkit-flex-flow:row wrap;display:-ms-flexbox;-ms-flex-flow:row wrap;-ms-align-content:flex-start;-webkit-align-content:flex-start;align-content:flex-start}.opera-only :-o-prefocus,.pure-g{word-spacing:-.43em}.pure-u{display:inline-block;*display:inline;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-g [class *="pure-u"]{font-family:sans-serif}.pure-u-1,.pure-u-1-1,.pure-u-1-2,.pure-u-1-3,.pure-u-2-3,.pure-u-1-4,.pure-u-3-4,.pure-u-1-5,.pure-u-2-5,.pure-u-3-5,.pure-u-4-5,.pure-u-5-5,.pure-u-1-6,.pure-u-5-6,.pure-u-1-8,.pure-u-3-8,.pure-u-5-8,.pure-u-7-8,.pure-u-1-12,.pure-u-5-12,.pure-u-7-12,.pure-u-11-12,.pure-u-1-24,.pure-u-2-24,.pure-u-3-24,.pure-u-4-24,.pure-u-5-24,.pure-u-6-24,.pure-u-7-24,.pure-u-8-24,.pure-u-9-24,.pure-u-10-24,.pure-u-11-24,.pure-u-12-24,.pure-u-13-24,.pure-u-14-24,.pure-u-15-24,.pure-u-16-24,.pure-u-17-24,.pure-u-18-24,.pure-u-19-24,.pure-u-20-24,.pure-u-21-24,.pure-u-22-24,.pure-u-23-24,.pure-u-24-24{display:inline-block;*display:inline;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-1-24{width:4.1667%;*width:4.1357%}.pure-u-1-12,.pure-u-2-24{width:8.3333%;*width:8.3023%}.pure-u-1-8,.pure-u-3-24{width:12.5%;*width:12.469%}.pure-u-1-6,.pure-u-4-24{width:16.6667%;*width:16.6357%}.pure-u-1-5{width:20%;*width:19.969%}.pure-u-5-24{width:20.8333%;*width:20.8023%}.pure-u-1-4,.pure-u-6-24{width:25%;*width:24.969%}.pure-u-7-24{width:29.1667%;*width:29.1357%}.pure-u-1-3,.pure-u-8-24{width:33.3333%;*width:33.3023%}.pure-u-3-8,.pure-u-9-24{width:37.5%;*width:37.469%}.pure-u-2-5{width:40%;*width:39.969%}.pure-u-5-12,.pure-u-10-24{width:41.6667%;*width:41.6357%}.pure-u-11-24{width:45.8333%;*width:45.8023%}.pure-u-1-2,.pure-u-12-24{width:50%;*width:49.969%}.pure-u-13-24{width:54.1667%;*width:54.1357%}.pure-u-7-12,.pure-u-14-24{width:58.3333%;*width:58.3023%}.pure-u-3-5{width:60%;*width:59.969%}.pure-u-5-8,.pure-u-15-24{width:62.5%;*width:62.469%}.pure-u-2-3,.pure-u-16-24{width:66.6667%;*width:66.6357%}.pure-u-17-24{width:70.8333%;*width:70.8023%}.pure-u-3-4,.pure-u-18-24{width:75%;*width:74.969%}.pure-u-19-24{width:79.1667%;*width:79.1357%}.pure-u-4-5{width:80%;*width:79.969%}.pure-u-5-6,.pure-u-20-24{width:83.3333%;*width:83.3023%}.pure-u-7-8,.pure-u-21-24{width:87.5%;*width:87.469%}.pure-u-11-12,.pure-u-22-24{width:91.6667%;*width:91.6357%}.pure-u-23-24{width:95.8333%;*width:95.8023%}.pure-u-1,.pure-u-1-1,.pure-u-5-5,.pure-u-24-24{width:100%}.pure-button{display:inline-block;zoom:1;line-height:normal;white-space:nowrap;vertical-align:middle;text-align:center;cursor:pointer;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.pure-button::-moz-focus-inner{padding:0;border:0}.pure-button{font-family:inherit;font-size:100%;padding:.5em 1em;color:#444;color:rgba(0,0,0,.8);border:1px solid #999;border:0 rgba(0,0,0,0);background-color:#E6E6E6;text-decoration:none;border-radius:2px}.pure-button-hover,.pure-button:hover,.pure-button:focus{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#1a000000', GradientType=0);background-image:-webkit-gradient(linear,0 0,0 100%,from(transparent),color-stop(40%,rgba(0,0,0,.05)),to(rgba(0,0,0,.1)));background-image:-webkit-linear-gradient(transparent,rgba(0,0,0,.05) 40%,rgba(0,0,0,.1));background-image:-moz-linear-gradient(top,rgba(0,0,0,.05) 0,rgba(0,0,0,.1));background-image:-o-linear-gradient(transparent,rgba(0,0,0,.05) 40%,rgba(0,0,0,.1));background-image:linear-gradient(transparent,rgba(0,0,0,.05) 40%,rgba(0,0,0,.1))}.pure-button:focus{outline:0}.pure-button-active,.pure-button:active{box-shadow:0 0 0 1px rgba(0,0,0,.15) inset,0 0 6px rgba(0,0,0,.2) inset;border-color:#000\9}.pure-button[disabled],.pure-button-disabled,.pure-button-disabled:hover,.pure-button-disabled:focus,.pure-button-disabled:active{border:0;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);filter:alpha(opacity=40);-khtml-opacity:.4;-moz-opacity:.4;opacity:.4;cursor:not-allowed;box-shadow:none}.pure-button-hidden{display:none}.pure-button::-moz-focus-inner{padding:0;border:0}.pure-button-primary,.pure-button-selected,a.pure-button-primary,a.pure-button-selected{background-color:#0078e7;color:#fff}.pure-form input[type=text],.pure-form input[type=password],.pure-form input[type=email],.pure-form input[type=url],.pure-form input[type=date],.pure-form input[type=month],.pure-form input[type=time],.pure-form input[type=datetime],.pure-form input[type=datetime-local],.pure-form input[type=week],.pure-form input[type=number],.pure-form input[type=search],.pure-form input[type=tel],.pure-form input[type=color],.pure-form select,.pure-form textarea{padding:.5em .6em;display:inline-block;border:1px solid #ccc;box-shadow:inset 0 1px 3px #ddd;border-radius:4px;vertical-align:middle;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.pure-form input:not([type]){padding:.5em .6em;display:inline-block;border:1px solid #ccc;box-shadow:inset 0 1px 3px #ddd;border-radius:4px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.pure-form input[type=color]{padding:.2em .5em}.pure-form input[type=text]:focus,.pure-form input[type=password]:focus,.pure-form input[type=email]:focus,.pure-form input[type=url]:focus,.pure-form input[type=date]:focus,.pure-form input[type=month]:focus,.pure-form input[type=time]:focus,.pure-form input[type=datetime]:focus,.pure-form input[type=datetime-local]:focus,.pure-form input[type=week]:focus,.pure-form input[type=number]:focus,.pure-form input[type=search]:focus,.pure-form input[type=tel]:focus,.pure-form input[type=color]:focus,.pure-form select:focus,.pure-form textarea:focus{outline:0;border-color:#129FEA}.pure-form input:not([type]):focus{outline:0;border-color:#129FEA}.pure-form input[type=file]:focus,.pure-form input[type=radio]:focus,.pure-form input[type=checkbox]:focus{outline:thin solid #129FEA;outline:1px auto #129FEA}.pure-form .pure-checkbox,.pure-form .pure-radio{margin:.5em 0;display:block}.pure-form input[type=text][disabled],.pure-form input[type=password][disabled],.pure-form input[type=email][disabled],.pure-form input[type=url][disabled],.pure-form input[type=date][disabled],.pure-form input[type=month][disabled],.pure-form input[type=time][disabled],.pure-form input[type=datetime][disabled],.pure-form input[type=datetime-local][disabled],.pure-form input[type=week][disabled],.pure-form input[type=number][disabled],.pure-form input[type=search][disabled],.pure-form input[type=tel][disabled],.pure-form input[type=color][disabled],.pure-form select[disabled],.pure-form textarea[disabled]{cursor:not-allowed;background-color:#eaeded;color:#cad2d3}.pure-form input:not([type])[disabled]{cursor:not-allowed;background-color:#eaeded;color:#cad2d3}.pure-form input[readonly],.pure-form select[readonly],.pure-form textarea[readonly]{background-color:#eee;color:#777;border-color:#ccc}.pure-form input:focus:invalid,.pure-form textarea:focus:invalid,.pure-form select:focus:invalid{color:#b94a48;border-color:#e9322d}.pure-form input[type=file]:focus:invalid:focus,.pure-form input[type=radio]:focus:invalid:focus,.pure-form input[type=checkbox]:focus:invalid:focus{outline-color:#e9322d}.pure-form select{height:2.25em;border:1px solid #ccc;background-color:#fff}.pure-form select[multiple]{height:auto}.pure-form label{margin:.5em 0 .2em}.pure-form fieldset{margin:0;padding:.35em 0 .75em;border:0}.pure-form legend{display:block;width:100%;padding:.3em 0;margin-bottom:.3em;color:#333;border-bottom:1px solid #e5e5e5}.pure-form-stacked input[type=text],.pure-form-stacked input[type=password],.pure-form-stacked input[type=email],.pure-form-stacked input[type=url],.pure-form-stacked input[type=date],.pure-form-stacked input[type=month],.pure-form-stacked input[type=time],.pure-form-stacked input[type=datetime],.pure-form-stacked input[type=datetime-local],.pure-form-stacked input[type=week],.pure-form-stacked input[type=number],.pure-form-stacked input[type=search],.pure-form-stacked input[type=tel],.pure-form-stacked input[type=color],.pure-form-stacked input[type=file],.pure-form-stacked select,.pure-form-stacked label,.pure-form-stacked textarea{display:block;margin:.25em 0}.pure-form-stacked input:not([type]){display:block;margin:.25em 0}.pure-form-aligned input,.pure-form-aligned textarea,.pure-form-aligned select,.pure-form-aligned .pure-help-inline,.pure-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.pure-form-aligned textarea{vertical-align:top}.pure-form-aligned .pure-control-group{margin-bottom:.5em}.pure-form-aligned .pure-control-group label{text-align:right;display:inline-block;vertical-align:middle;width:10em;margin:0 1em 0 0}.pure-form-aligned .pure-controls{margin:1.5em 0 0 11em}.pure-form input.pure-input-rounded,.pure-form .pure-input-rounded{border-radius:2em;padding:.5em 1em}.pure-form .pure-group fieldset{margin-bottom:10px}.pure-form .pure-group input,.pure-form .pure-group textarea{display:block;padding:10px;margin:0 0 -1px;border-radius:0;position:relative;top:-1px}.pure-form .pure-group input:focus,.pure-form .pure-group textarea:focus{z-index:3}.pure-form .pure-group input:first-child,.pure-form .pure-group textarea:first-child{top:1px;border-radius:4px 4px 0 0;margin:0}.pure-form .pure-group input:first-child:last-child,.pure-form .pure-group textarea:first-child:last-child{top:1px;border-radius:4px;margin:0}.pure-form .pure-group input:last-child,.pure-form .pure-group textarea:last-child{top:-2px;border-radius:0 0 4px 4px;margin:0}.pure-form .pure-group button{margin:.35em 0}.pure-form .pure-input-1{width:100%}.pure-form .pure-input-2-3{width:66%}.pure-form .pure-input-1-2{width:50%}.pure-form .pure-input-1-3{width:33%}.pure-form .pure-input-1-4{width:25%}.pure-form .pure-help-inline,.pure-form-message-inline{display:inline-block;padding-left:.3em;color:#666;vertical-align:middle;font-size:.875em}.pure-form-message{display:block;color:#666;font-size:.875em}@media only screen and (max-width :480px){.pure-form button[type=submit]{margin:.7em 0 0}.pure-form input:not([type]),.pure-form input[type=text],.pure-form input[type=password],.pure-form input[type=email],.pure-form input[type=url],.pure-form input[type=date],.pure-form input[type=month],.pure-form input[type=time],.pure-form input[type=datetime],.pure-form input[type=datetime-local],.pure-form input[type=week],.pure-form input[type=number],.pure-form input[type=search],.pure-form input[type=tel],.pure-form input[type=color],.pure-form label{margin-bottom:.3em;display:block}.pure-group input:not([type]),.pure-group input[type=text],.pure-group input[type=password],.pure-group input[type=email],.pure-group input[type=url],.pure-group input[type=date],.pure-group input[type=month],.pure-group input[type=time],.pure-group input[type=datetime],.pure-group input[type=datetime-local],.pure-group input[type=week],.pure-group input[type=number],.pure-group input[type=search],.pure-group input[type=tel],.pure-group input[type=color]{margin-bottom:0}.pure-form-aligned .pure-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.pure-form-aligned .pure-controls{margin:1.5em 0 0}.pure-form .pure-help-inline,.pure-form-message-inline,.pure-form-message{display:block;font-size:.75em;padding:.2em 0 .8em}}.pure-menu{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.pure-menu-fixed{position:fixed;left:0;top:0;z-index:3}.pure-menu-list,.pure-menu-item{position:relative}.pure-menu-list{list-style:none;margin:0;padding:0}.pure-menu-item{padding:0;margin:0;height:100%}.pure-menu-link,.pure-menu-heading{display:block;text-decoration:none;white-space:nowrap}.pure-menu-horizontal{width:100%;white-space:nowrap}.pure-menu-horizontal .pure-menu-list{display:inline-block}.pure-menu-horizontal .pure-menu-item,.pure-menu-horizontal .pure-menu-heading,.pure-menu-horizontal .pure-menu-separator{display:inline-block;*display:inline;zoom:1;vertical-align:middle}.pure-menu-item .pure-menu-item{display:block}.pure-menu-children{display:none;position:absolute;left:100%;top:0;margin:0;padding:0;z-index:3}.pure-menu-horizontal .pure-menu-children{left:0;top:auto;width:inherit}.pure-menu-allow-hover:hover>.pure-menu-children,.pure-menu-active>.pure-menu-children{display:block;position:absolute}.pure-menu-has-children>.pure-menu-link:after{padding-left:.5em;content:"\25B8";font-size:small}.pure-menu-horizontal .pure-menu-has-children>.pure-menu-link:after{content:"\25BE"}.pure-menu-scrollable{overflow-y:scroll;overflow-x:hidden}.pure-menu-scrollable .pure-menu-list{display:block}.pure-menu-horizontal.pure-menu-scrollable .pure-menu-list{display:inline-block}.pure-menu-horizontal.pure-menu-scrollable{white-space:nowrap;overflow-y:hidden;overflow-x:auto;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;padding:.5em 0}.pure-menu-horizontal.pure-menu-scrollable::-webkit-scrollbar{display:none}.pure-menu-separator{background-color:#ccc;height:1px;margin:.3em 0}.pure-menu-horizontal .pure-menu-separator{width:1px;height:1.3em;margin:0 .3em}.pure-menu-heading{text-transform:uppercase;color:#565d64}.pure-menu-link{color:#777}.pure-menu-children{background-color:#fff}.pure-menu-link,.pure-menu-disabled,.pure-menu-heading{padding:.5em 1em}.pure-menu-disabled{opacity:.5}.pure-menu-disabled .pure-menu-link:hover{background-color:transparent}.pure-menu-active>.pure-menu-link,.pure-menu-link:hover,.pure-menu-link:focus{background-color:#eee}.pure-menu-selected .pure-menu-link,.pure-menu-selected .pure-menu-link:visited{color:#000}.pure-table{border-collapse:collapse;border-spacing:0;empty-cells:show;border:1px solid #cbcbcb}.pure-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.pure-table td,.pure-table th{border-left:1px solid #cbcbcb;border-width:0 0 0 1px;font-size:inherit;margin:0;overflow:visible;padding:.5em 1em}.pure-table td:first-child,.pure-table th:first-child{border-left-width:0}.pure-table thead{background-color:#e0e0e0;color:#000;text-align:left;vertical-align:bottom}.pure-table td{background-color:transparent}.pure-table-odd td{background-color:#f2f2f2}.pure-table-striped tr:nth-child(2n-1) td{background-color:#f2f2f2}.pure-table-bordered td{border-bottom:1px solid #cbcbcb}.pure-table-bordered tbody>tr:last-child>td{border-bottom-width:0}.pure-table-horizontal td,.pure-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #cbcbcb}.pure-table-horizontal tbody>tr:last-child>td{border-bottom-width:0} 12 | -------------------------------------------------------------------------------- /css/screen.sass: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | // variables 5 | // 6 | $spec-width: 57rem 7 | $desktop-width: 57rem 8 | $mobile-width: 30rem 9 | $standard_font_family: "Open Sans", sans-serif 10 | $content_font_family: "Open Sans", sans-serif 11 | $mono_font_family: Consolas, "Andale Mono WT", "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", Monaco, "Courier New", Courier, monospace 12 | 13 | // Media queries 14 | // 15 | @mixin respond-to($media) 16 | @if $media == wide 17 | @media only screen and (min-width: $desktop-width) 18 | @content 19 | @else if $media == desktop 20 | @media only screen and (min-width: $mobile-width) and (max-width: $desktop-width) 21 | @content 22 | @else if $media == mobile 23 | @media only screen and (max-width: $mobile-width) 24 | @content 25 | 26 | // styling 27 | // 28 | html 29 | box-sizing: border-box 30 | *, *:before, *:after 31 | box-sizing: inherit 32 | 33 | // table stuff 34 | html, body 35 | font-family: $standard_font_family 36 | height: 100% 37 | 38 | #wrapper, #footer 39 | @media screen 40 | max-width: $spec-width 41 | margin: 0 auto 42 | @media print 43 | width: 100% 44 | padding: 1rem 45 | 46 | @media screen 47 | #wrapper 48 | padding-bottom: 0 49 | #footer 50 | padding-top: 0 51 | padding-bottom: 2.5rem // for ToC button 52 | 53 | #nav 54 | width: 100% 55 | background: #334 56 | color: #f7f7fa 57 | @media print 58 | display: none 59 | > div 60 | @include respond-to(wide) 61 | max-width: $desktop-width - 2rem 62 | margin: 0 auto 63 | padding: 0.25rem 0 0.2rem 64 | @include respond-to(desktop) 65 | margin: 0 1rem 66 | padding: 0.25rem 0 0.2rem 67 | @include respond-to(mobile) 68 | padding: 0.25rem 0.3rem 0.2rem 69 | a 70 | text-decoration: none 71 | color: #e7e7ff 72 | &:hover 73 | color: #ccf 74 | 75 | nav > a 76 | margin-left: 1.5rem 77 | &:first-child 78 | margin-left: 0 79 | @include respond-to(wide) 80 | margin-right: 2.75rem 81 | @include respond-to(desktop) 82 | margin-right: 2.75rem 83 | @include respond-to(mobile) 84 | display: block 85 | @include respond-to(mobile) 86 | &:nth-child(2) 87 | margin-left: 0 88 | i 89 | font-size: 0.9rem 90 | vertical-align: baseline 91 | 92 | .wordmark 93 | font-style: normal 94 | 95 | #content > h1:first-child 96 | margin-top: 0.5rem 97 | 98 | #spec 99 | h1 100 | page-break-before: always 101 | 102 | #hovering-ietf-warning 103 | color: #222222 104 | background: rgba(20,20,20,0.75) 105 | position: fixed 106 | top: 0 107 | left: 0 108 | width: 100% 109 | height: 100% 110 | > div 111 | max-width: calc(100% - 2rem) 112 | width: 37rem 113 | background: #fbfbfb 114 | margin: 7rem auto 1rem 115 | padding: 1.5rem 1.85rem 116 | border-radius: 1.5rem 117 | 118 | 119 | .copyright .line 120 | display: block 121 | color: #222 122 | 123 | a 124 | transition: color 0.2s 125 | font-style: italic 126 | text-decoration: none 127 | &:visited, &:active 128 | color: #9141d2 129 | &:hover 130 | text-decoration: underline 131 | 132 | h1 133 | color: #334 134 | .subtitle 135 | display: block 136 | font-size: 1.2rem 137 | color: #445 138 | font-weight: normal 139 | h2 140 | color: #3e3e4e 141 | margin-bottom: 1rem 142 | h3 143 | color: #445 144 | margin-bottom: 0.5rem 145 | h4 146 | color: #4e4e5e 147 | margin-bottom: 0.65rem 148 | 149 | h1, h2, h3, h4 150 | page-break-after: avoid 151 | a 152 | color: #33a 153 | &:hover 154 | color: #119 155 | 156 | p 157 | margin-top: 0.5rem 158 | + p 159 | margin-top: 1rem 160 | 161 | li 162 | + li 163 | margin-top: 0.9rem 164 | p 165 | &:first-child 166 | margin-top: 0 167 | &:last-child 168 | margin-bottom: 0 169 | 170 | #toc 171 | li 172 | margin-top: 0 173 | 174 | 175 | .displaynone 176 | display: none 177 | 178 | .warning, .note 179 | color: #fff 180 | border-radius: 1rem 181 | margin: 1.55rem auto 182 | padding: 1.2rem 1.3rem 183 | a 184 | color: #abf 185 | @media print 186 | color: #fff 187 | &:hover 188 | color: #78c 189 | p 190 | &:first-child 191 | margin-top: 0 192 | &:last-child 193 | margin-bottom: 0 194 | .note 195 | @media screen 196 | background: #4f5dc9 197 | @media print 198 | background: #444 199 | border: 0.5rem #222 dotted 200 | .warning 201 | @media screen 202 | background: #d54 203 | @media print 204 | background: #666 205 | border: 0.5rem #000 dashed 206 | 207 | .anchor 208 | color: #f53 209 | &:hover 210 | color: #c12 211 | 212 | hr 213 | @media screen 214 | border: #99b 0.2rem solid 215 | background: #99b 216 | border-radius: 2rem 217 | margin: 1.55rem auto 218 | @media print 219 | display: none 220 | 221 | pre 222 | font-size: 90% 223 | padding: 1rem 224 | border-radius: 0.5rem 225 | background: #ffb 226 | page-break-inside: avoid 227 | font-family: $mono_font_family 228 | tt 229 | font-family: $mono_font_family 230 | .reverse 231 | padding: 0 0.2rem 232 | font-family: $mono_font_family 233 | background: #000 234 | color: #fff 235 | font-weight: bold 236 | 237 | body 238 | counter-reset: figure 239 | 240 | .figure 241 | text-align: center 242 | color: #333 243 | display: block 244 | page-break-before: avoid 245 | &::before 246 | counter-increment: figure 247 | content: "Figure " counter(figure) ": " 248 | 249 | .edmark 250 | margin-left: 0.275rem 251 | font-size: 0.7rem 252 | vertical-align: 0.125rem 253 | 254 | #wiptag, #ietftag 255 | @media print 256 | display: none 257 | position: fixed 258 | bottom: 1rem 259 | right: 1rem 260 | padding: 0.3rem 0.6rem 261 | background: #d54 262 | border-radius: 0.36rem 263 | color: #fdfbfb 264 | font-family: $mono_font_family 265 | .detail 266 | display: none 267 | &:hover .detail, &:focus .detail 268 | display: block 269 | @media print 270 | display: none 271 | position: fixed 272 | bottom: 1rem 273 | @media only screen and (max-width: 60rem) 274 | bottom: 3rem 275 | right: 1rem 276 | padding: 0.3rem 0.6rem 277 | color: #222 278 | border-radius: 0.36rem 279 | background: rgba(250, 250, 250, 0.95) 280 | text-align: center 281 | font-family: $standard_font_family 282 | #wiptag::before 283 | content: "WIP" 284 | #ietftag::before 285 | content: "IETF" 286 | 287 | // irc colors 288 | .ircf-0 289 | color: #ffffff 290 | .ircf-1 291 | color: #000000 292 | .ircf-2 293 | color: #00007f 294 | .ircf-3 295 | color: #009300 296 | .ircf-4 297 | color: #ff0000 298 | .ircf-5 299 | color: #7f0000 300 | .ircf-6 301 | color: #9c009c 302 | .ircf-7 303 | color: #fc7f00 304 | .ircf-8 305 | color: #ffff00 306 | .ircf-9 307 | color: #00fc00 308 | .ircf-10 309 | color: #009393 310 | .ircf-11 311 | color: #00ffff 312 | .ircf-12 313 | color: #0000fc 314 | .ircf-13 315 | color: #ff00ff 316 | .ircf-14 317 | color: #7f7f7f 318 | .ircf-15 319 | color: #d2d2d2 320 | .ircf-99 321 | color: #000000 322 | 323 | .ircb-0 324 | background: #ffffff 325 | .ircb-1 326 | background: #000000 327 | .ircb-2 328 | background: #00007f 329 | .ircb-3 330 | background: #009300 331 | .ircb-4 332 | background: #ff0000 333 | .ircb-5 334 | background: #7f0000 335 | .ircb-6 336 | background: #9c009c 337 | .ircb-7 338 | background: #fc7f00 339 | .ircb-8 340 | background: #ffff00 341 | .ircb-9 342 | background: #00fc00 343 | .ircb-10 344 | background: #009393 345 | .ircb-11 346 | background: #00ffff 347 | .ircb-12 348 | background: #0000fc 349 | .ircb-13 350 | background: #ff00ff 351 | .ircb-14 352 | background: #7f7f7f 353 | .ircb-15 354 | background: #d2d2d2 355 | .ircb-99 356 | background: #ffffff 357 | 358 | .ircb 359 | font-weight: bold 360 | .irci 361 | font-style: italic 362 | 363 | @media print 364 | #darkmodebtn 365 | display: none 366 | 367 | #toc 368 | display: block !important 369 | page-break-before: always 370 | + ul 371 | padding: 0.5rem 0 372 | counter-reset: toc-lvl-1 373 | > li 374 | &::before 375 | content: counter(toc-lvl-1) 376 | counter-increment: toc-lvl-1 377 | padding-right: 1rem 378 | > ul 379 | counter-reset: toc-lvl-2 380 | > li 381 | &::before 382 | content: counter(toc-lvl-1) "." counter(toc-lvl-2) 383 | counter-increment: toc-lvl-2 384 | padding-right: 1rem 385 | > ul 386 | counter-reset: toc-lvl-3 387 | > li 388 | &::before 389 | content: counter(toc-lvl-1) "." counter(toc-lvl-2) "." counter(toc-lvl-3) 390 | counter-increment: toc-lvl-3 391 | padding-right: 1rem 392 | > ul 393 | counter-reset: toc-lvl-4 394 | > li 395 | &::before 396 | content: counter(toc-lvl-1) "." counter(toc-lvl-2) "." counter(toc-lvl-3) "." counter(toc-lvl-4) 397 | counter-increment: toc-lvl-4 398 | padding-right: 1rem 399 | &.parent-appendixes 400 | &.parent-appendixes-1 401 | counter-reset: toc-appendixes 402 | &::before 403 | content: "Appendix " counter(toc-appendixes, upper-alpha) ". " 404 | counter-increment: toc-appendixes 405 | padding: 0 406 | > ul, ol, li 407 | display: none 408 | ul, ol 409 | margin: 0 410 | list-style-type: none 411 | + ul 412 | margin: 0 413 | list-style: none 414 | li 415 | margin: 0 416 | padding-top: 0.25rem 417 | 418 | #spec 419 | &::before 420 | counter-reset: h-lvl-1 421 | h1 422 | counter-increment: h-lvl-1 423 | counter-reset: h-lvl-2 h-lvl-3 424 | &::before 425 | content: counter(h-lvl-1) 426 | padding-right: 1.2rem 427 | font-size: 1.25rem 428 | h2 429 | counter-increment: h-lvl-2 430 | counter-reset: h-lvl-3 431 | &::before 432 | content: counter(h-lvl-1) "." counter(h-lvl-2) 433 | padding-right: 1rem 434 | font-size: 1.25rem 435 | h3 436 | counter-increment: h-lvl-3 437 | &::before 438 | content: counter(h-lvl-1) "." counter(h-lvl-2) "." counter(h-lvl-3) 439 | padding-right: 1rem 440 | font-size: 1.25rem 441 | .toc-id-acknowledgements 442 | &::before 443 | content: "" 444 | padding-right: 0 445 | #appendixes 446 | &::before 447 | counter-reset: a-lvl-1 448 | h1 449 | counter-increment: a-lvl-1 450 | &::before 451 | content: "Appendix " counter(a-lvl-1, upper-alpha) ". " 452 | font-size: inherit 453 | padding-right: 0 454 | h3 455 | &::before 456 | content: none 457 | padding-right: 0 458 | #acknowledgements 459 | &::before 460 | content: "" 461 | padding-right: 0 462 | 463 | #darkmodebtn 464 | display: block 465 | position: fixed 466 | left: 0 467 | bottom: 0 468 | padding: 0.5rem 469 | font-size: 1.7rem 470 | 471 | // dark theme color changing transitions 472 | body, .warning, .note > div 473 | transition: background 0.2s, color 0.2s 474 | 475 | pre 476 | transition: background 0.2s 477 | 478 | .copyright .line, .figure, a, h1, h2, h3, h4 479 | transition: color 0.2s 480 | 481 | // dark theme 482 | body:not(.dark) 483 | .show-when-dark 484 | display: none 485 | body.dark 486 | background: #334 487 | color: #dddde3 488 | 489 | .show-when-light 490 | display: none 491 | 492 | .copyright .line 493 | color: #ccc 494 | 495 | .warning 496 | background: #63261e 497 | color: #efe9e9 498 | .note 499 | background: #1e2963 500 | color: #e9ebef 501 | 502 | .figure 503 | color: #d2dde3 504 | 505 | a 506 | color: #7a7aff 507 | &:visited, &:active 508 | color: #c194e6 509 | 510 | h1 511 | color: #ceceda 512 | h2 513 | color: #dadae1 514 | h3 515 | color: #c6c6d2 516 | h4 517 | color: #b7b7c3 518 | 519 | pre 520 | background: #282831 521 | -------------------------------------------------------------------------------- /ctcp.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Client-to-Client Protocol (CTCP) 3 | layout: default 4 | copyrights: 5 | - 6 | name: "Mantas Mikulėnas" 7 | email: "grawity@gmail.com" 8 | - 9 | name: "Daniel Oaks" 10 | org: "ircdocs" 11 | org_link: "http://ircdocs.horse/" 12 | email: "daniel@danieloaks.net" 13 | editor: true 14 | ietf: https://tools.ietf.org/html/draft-oakley-irc-ctcp-02 15 | ietf-html-editors-copy: https://rawgit.com/DanielOaks/irc-rfcs/master/dist/draft-oakley-irc-ctcp-latest.html 16 | ietf-txt-editors-copy: https://rawgit.com/DanielOaks/irc-rfcs/master/dist/draft-oakley-irc-ctcp-latest.txt 17 | toc: true 18 | --- 19 | 20 | {% include copyrights.html %} 21 | 22 |
23 |

This document intends to be a useful overview and reference of CTCP as it is implemented today. It is a living specification which is updated in response to feedback and implementations as they change. This document describes existing behaviour and what we consider best practices for new software.

24 |

If something written in here isn't interoperable with an IRC client you know of, please open an issue.

25 |
26 | 27 | {% include ietfwarning.html %} 28 | 29 | 30 | 31 | --- 32 | 33 | 34 | # Introduction 35 | 36 | The Client-to-Client Protocol (CTCP) has been in use on IRC for a very long time. Essentially, it provides a way for IRC clients to send each other messages that get parsed and displayed/responded to in special ways. Some examples of how CTCP is used today is to request special formatting on certain messages, query other clients for metadata, and initiate file transfers with other clients. 37 | 38 | The original CTCP specifications are lengthy and cover quoting mechanisms which are no longer implemented or followed today. In comparison, this document goes over the subset of CTCP which is commonly implemented and lets your software interact nicely with most other IRC software out there. 39 | 40 | The IRCv3 Working Group is investigating replacing some functions currently performed by CTCP with alternate methods such as [Metadata](https://github.com/ircv3/ircv3-specifications/issues/244) and [client-only message tags](http://ircv3.net/specs/core/message-tags-3.3.html), which should also allow these functions to be performed more widely and used to better effect. 41 | 42 | 43 | 44 | 45 | --- 46 | 47 | 48 | # Message Syntax 49 | 50 | The [`PRIVMSG`](/index.html#privmsg-message) and [`NOTICE`](/index.html#notice-message) messages are used to transmit CTCP frames. To create a CTCP message, you simply replace the body (i.e. the ``) of a `PRIVMSG` / `NOTICE` with the following: 51 | 52 | delim = %x01 53 | 54 | command = 1*( %x02-09 / %x0B-0C / %x0E-1F / %x21-FF ) 55 | ; any octet except NUL, delim, CR, LF, and " " 56 | 57 | params = 1*( %x02-09 / %x0B-0C / %x0E-FF ) 58 | ; any octet except NUL, delim, CR, and LF 59 | 60 | body = delim command [ SPACE params ] [ delim ] 61 | 62 | The final `` MUST be sent, but parsers SHOULD accept incoming messages which lack it (particularly for `CTCP ACTION`). This is due to how some software incorrectly implements message splitting. 63 | 64 | CTCP queries are sent with `PRIVMSG`, and replies are sent with `NOTICE`. In addition, CTCP queries sent to channels always generate private replies. 65 | 66 | Here are two examples of CTCP queries and replies: 67 | 68 | :dx PRIVMSG SaberUK :\x01VERSION\x01 69 | :SaberUK NOTICE dx :\x01VERSION Snak for Macintosh 4.13 English\x01 70 | 71 | :mt PRIVMSG #ircv3 :\x01PING 1473523796 918320\x01 72 | :Jobe NOTICE mt :\x01PING 1473523796 918320\x01 73 | 74 | 75 | ## Changes since 1994 specification 76 | 77 | The entire [`PRIVMSG`](/index.html#privmsg-message) / [`NOTICE`](/index.html#notice-message) message body must consist of either a CTCP message or plain text (non-CTCP). The original specification(s) allowed intermixing plain-text chunks and "tagged data" CTCP chunks, which has not been implemented widely enough for regular use. 78 | 79 | This document does not include any mechanism for quoting plain text (non-CTCP) messages, as opposed to the original "low-level quoting" specifications (as this has not been widely implemented). Likewise, it does not define any mechanism for quoting CTCP parameters, although individual CTCP message specifications may define their own quoting. 80 | 81 | 82 | --- 83 | 84 | 85 | # Message Types 86 | 87 | CTCP messages generally take on one of these types. These message types are defined here for informational purposes only (to simplify understanding), and aren't specified or differentiated by the protocol itself. 88 | 89 | Generally, channel-directed CTCPs should never cause an error reply. 90 | 91 | 92 | ## Extended Formatting 93 | 94 | This type of CTCP is used to request special formatting of a user-visible message. That is, to send a user-visible message that should be displayed differently from regular messages - e.g. as an action, a whisper, an announcement. 95 | 96 | Extended formatting CTCPs are sent as a `PRIVMSG`. There is no automatic response to this message type, as it is not a query nor reply. 97 | 98 | Extended formatting CTCPs are expected to be used in channels as well as between clients. However, many servers implement optional filtering to block CTCPs in channels (apart from `ACTION`). Because of this, any future extended-formatting CTCPs may be restricted to private messages. 99 | 100 | These CTCP messages are sent as a [`PRIVMSG`](/index.html#privmsg-message) and generate no reply. 101 | 102 | **Example:** 103 | 104 | :dan- PRIVMSG #ircv3 :\x01ACTION writes the best specifications!\x01 105 | 106 | 107 | ## Metadata Query 108 | 109 | This type of CTCP is used to provide _static_ information about the target client, user or connection. 110 | 111 | This CTCP takes the form of a query and a response (as a `PRIVMSG` and `NOTICE`, respectively). Due to how bouncers interact with multiple clients, there may sometimes be multiple responses to queries. 112 | 113 | Metadata queries MUST NOT require the recipient to implement any side effects (beyond sending the reply itself); if a CTCP message causes side effects by design, it should be categorized as an [extended query](#extended-query) instead. 114 | 115 | **Example:** 116 | 117 | :dx PRIVMSG SaberUK :\x01VERSION\x01 118 | :SaberUK NOTICE dx :\x01VERSION Your Mother 6.9\x01 119 | 120 | 121 | ## Extended Query 122 | 123 | This type of CTCP is used to provide _dynamic_ information or invoke actions from the client. 124 | 125 | This CTCP takes the form of a query and a response (as a `PRIVMSG` and `NOTICE`, respectively). 126 | 127 | Queries sent to a channel always generate private replies. 128 | 129 | **Example:** 130 | 131 | :mt PRIVMSG #ircv3 :\x01PING 1473523796 918320\x01 132 | :Jobe NOTICE mt :\x01PING 1473523796 918320\x01 133 | 134 | 135 | --- 136 | 137 | 138 |
139 | 140 | {% capture appendixes %}{% include ctcp-appendix.md %}{% endcapture %} 141 | {{ appendixes | markdownify }} 142 | 143 |
144 | -------------------------------------------------------------------------------- /dcc.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Direct Client-to-Client Protocol (DCC) 3 | layout: default 4 | wip: true 5 | copyrights: 6 | - 7 | name: "Daniel Oaks" 8 | org: "ircdocs" 9 | org_link: "http://ircdocs.horse/" 10 | email: "daniel@danieloaks.net" 11 | editor: true 12 | toc: true 13 | --- 14 | 15 | {% include copyrights.html %} 16 | 17 |
18 |

This document intends to be a useful overview and reference of DCC as it is implemented today. It is a living specification which is updated in response to feedback and implementations as they change. This document describes existing behaviour and what we consider best practices for new software.

19 |

If something written in here isn't interoperable with an IRC client you know of, please open an issue.

20 |
21 | 22 |
23 |

NOTE: This is NOWHERE NEAR FINISHED and may be ENTIRELY INACCURATE. Dragons be here, insane stuff be here.

24 |

Regardless of the accuracy of this specification, DCC in general is not encrypted (apart from the SDCC extension which is not widely-supported and does not verify any certificate details). I don't particularly like where DCC is at the moment, but with this document I'm hoping to start the discussion around properly encrypting direct connections, and/or building something that does so with the knowledge of what's currently out there.

25 |

You can contribute by sending pull requests to our Github repository!

26 |
27 | 28 | 29 | 30 | 31 | --- 32 | 33 | 34 | # Introduction 35 | 36 | The Direct Client-to-Client Protocol (DCC) has been the primary method of establishing connections directly between IRC clients for a long time now. Once established, DCC connections bypass the IRC network and servers, allowing for all sorts of data to be transferred between clients including files and direct chat sessions. 37 | 38 | There have been many extensions to DCC through the years, such as XDCC, SDCC and others. This document intends to describe DCC as it works today and provide a useful specification for new client authors implementing this feature. 39 | 40 | If you are a new software author implementing this feature, please keep in mind that **DCC has no encryption.** If you must implement DCC, please look at the [SDCC](#secure-dcc-sdcc) section at the bottom of this document so that you can implement even the most minor security measures for this protocol. 41 | 42 | 43 | 44 | --- 45 | 46 | 47 | # Architecture 48 | 49 | [CTCP](/ctcp.html) messages are used to initiate DCC sessions. Specifically, the [`DCC`](/ctcp.html#dcc) message is used to start and control DCC sessions. 50 | 51 | This section details the types of DCC available, and how to open DCC sessions. 52 | 53 | 54 | ## DCC Query Syntax 55 | 56 | The initial CTCP `DCC` query message has this format: 57 | 58 | DCC 59 | 60 | `` contains the type of DCC being initiated, such as `CHAT` or `SEND`. `` refers to a type-specific kind of argument, such as a filename. `` represents to the IP address which should be connected to, and `` refers to a valid port on which the connection should be established (the value of this parameter can also be `0`, in which case the rules below apply. 61 | 62 | ``, for legacy reasons, uses a 'fun' mixture of representations. For IPv4 hosts, this parameter is the string representation of the positive integer that is the IP address in network byte order (e.g. `127.0.0.1` is represented as `2130706433` in this param). For IPv6 hosts, clients instead support the standard, widely-implemented IPv6 hex representation separated by colons (e.g. `::1`). 63 | 64 | Note that for DCC queries to work, the querying client MUST know its' own public host address, or the address that the other client can use to access it. Clients have discovered this in various ways through the years, and this section doesn't yet describe how to do so. However, clients `MUST NOT` try to discover this through the [`RPL_WELCOME`](/index.html#rpl_welcome-001) numeric, as the prevalence of spoofed hostnames used today makes this infeasible on most public networks and introduces issues. 65 | 66 | ### Port 0 67 | 68 | When port 0 is advertised on a DCC query, it signals that the sending client wishes to open a connection but cannot (or does not wish to) explicitly offer a listening port. This is commonly called Reverse DCC or Firewall-bypassing DCC (we refer to it as Reverse DCC in this document). 69 | 70 | When a client receives a reverse DCC query, it means that the sending client wants the receiving client to establish the connection instead (with a valid port number in the `` parameter). If the receiving client wishes to continue, they'll send a request back to the client that originally sent them the query. 71 | 72 | Reverse DCC interacts a bit strangely with the `RESUME` type, and is outlined below in the specific section. 73 | 74 | 75 | ## DCC CHAT 76 | 77 | `CHAT` is used to establish chat sessions directly between clients. It should be noted that **plain DCC does not use any form of encryption and SHOULD be avoided.** 78 | 79 | ### Initiating Sessions 80 | 81 | To initiate a `DCC CHAT` session, send a `CTCP` query with the format: 82 | 83 | DCC CHAT 84 | 85 | Where `` is a holding string – we recommend just using `"chat"` here. `` and `` are the host and the port the recipient connect to in order to establish the connection. 86 | 87 | After receiving the query, the receiver will have the option of accepting or rejecting the chat request. End users MUST be given the option to either accept or ignore this request, as opening it will expose their public IP address. 88 | 89 | To accept a given chat request, open a TCP connection to the given port. To reject a given request, simply ignore the query and do not respond to it. 90 | 91 | ### Sending Messages 92 | 93 | After opening the direct TCP connection, clients will send lines to each other separated by the pair of characters `CR` `('\r', 0x0D)` and `LF` `('\n', 0x0A)`. 94 | 95 | There are no prepended commands or verbs such as `PRIVMSG` and `NOTICE`. 96 | 97 | #### ACTION 98 | 99 | If one wishes to perform a standard [`CTCP ACTION`](/ctcp.html#action)-like message, they should prefix the line with `"\x01ACTION "`. That is, the standard CTCP delimiter `('\x01', 0x01)`, the verb `"ACTION"`, and a single space, before sending the client's message. 100 | 101 | Clients that receive a line prefixed with `"\x01ACTION "` MUST display that line as a standard [`CTCP ACTION`](/ctcp.html#action) message would be displayed. 102 | 103 | *Example:* 104 | 105 | Raw: \x01ACTION writes a specification 106 | 107 | Formatted: * dan writes a specification 108 | 109 | 110 | ## DCC SEND 111 | 112 | `SEND` is used to send another client a given file. This is done directly between clients to avoid the overhead of having to transfer files through the IRC server. It should be noted that **plain DCC does not use any form of encryption and SHOULD be avoided.** 113 | 114 | ### Initiating Sessions 115 | 116 | To initiate a `DCC SEND` session, send a `CTCP` query with the format: 117 | 118 | DCC SEND 119 | 120 | `` is the filename of the file to be sent. `` and `` are the host and the port the recipient connect to in order to establish the connection. 121 | 122 | After receiving the query, the receiver will have the option of accepting or rejecting the file send request. End users MUST be given the option to either accept or ignore this request, as opening it will expose their public IP address, and automatically receiving files on certain systems may be used to exploit vulnerabilities. 123 | 124 | Clients SHOULD NOT allow saving files into system directories, directories that could affect the operation of the IRC client or the system as a whole. Clients SHOULD instead restrict saved files to a single directory chosen by the user or purposefully chosen to be the destination of received DCC files. End users MUST also be given the option to rename the file and save it under a different filename. 125 | 126 | To accept a given chat request, open a TCP connection to the given port. To reject a given request, simply ignore the query and do not respond to it. 127 | 128 | ### Sending The File 129 | 130 | After opening the direct TCP connection, the sending client sends the raw bytes of the file over the newly-established connection. 131 | 132 | ### Resuming The Send 133 | 134 | This section is not yet written. 135 | 136 | 137 | ## DCC RESUME 138 | 139 | This section is not yet written. 140 | 141 | 142 | ## DCC ACCEPT 143 | 144 | This section is not yet written. 145 | 146 | 147 | --- 148 | 149 | 150 | # Extensions 151 | 152 | These are various extensions that change how DCC connections are established and used. These are detailed here. 153 | 154 | 155 | ## Secure DCC (SDCC) 156 | 157 | In this method, the verb `SCHAT` is used instead of `CHAT` and `SSEND` is used instead of `SEND`. When using secure DCC, the direct TCP connection uses TLS rather than plaintext. 158 | 159 | Although it uses TLS, the certificate on either side is not verified in any way, which means this is still not secure by today's standards. However, it can help protect against dragnet data collection so it's still a definite step up from regular plaintext DCC. 160 | 161 | 162 | ## Reverse / Firewall-bypassing DCC 163 | 164 | This type of DCC request (that we call Reverse DCC) is used to bypass NAT and similar issues. The functionality is described above in the [Port 0](#port-0) section and relevant part of the [DCC RESUME](#dcc-resume) section. 165 | 166 | 167 | ## Extended DCC (XDCC) 168 | 169 | XDCC (originally an acronym for Xabi's DCC) is a set of additional commands to allow clients to list files available for download. As well, XDCC allows clients to request downloading a particular advertised file -- upon which a `DCC SEND` session will be established by the side advertising the file. 170 | -------------------------------------------------------------------------------- /fonts/Bold/OpenSans-Bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/Bold/OpenSans-Bold.eot -------------------------------------------------------------------------------- /fonts/Bold/OpenSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/Bold/OpenSans-Bold.ttf -------------------------------------------------------------------------------- /fonts/Bold/OpenSans-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/Bold/OpenSans-Bold.woff -------------------------------------------------------------------------------- /fonts/Bold/OpenSans-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/Bold/OpenSans-Bold.woff2 -------------------------------------------------------------------------------- /fonts/BoldItalic/OpenSans-BoldItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/BoldItalic/OpenSans-BoldItalic.eot -------------------------------------------------------------------------------- /fonts/BoldItalic/OpenSans-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/BoldItalic/OpenSans-BoldItalic.ttf -------------------------------------------------------------------------------- /fonts/BoldItalic/OpenSans-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/BoldItalic/OpenSans-BoldItalic.woff -------------------------------------------------------------------------------- /fonts/BoldItalic/OpenSans-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/BoldItalic/OpenSans-BoldItalic.woff2 -------------------------------------------------------------------------------- /fonts/ExtraBold/OpenSans-ExtraBold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/ExtraBold/OpenSans-ExtraBold.eot -------------------------------------------------------------------------------- /fonts/ExtraBold/OpenSans-ExtraBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/ExtraBold/OpenSans-ExtraBold.ttf -------------------------------------------------------------------------------- /fonts/ExtraBold/OpenSans-ExtraBold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/ExtraBold/OpenSans-ExtraBold.woff -------------------------------------------------------------------------------- /fonts/ExtraBold/OpenSans-ExtraBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/ExtraBold/OpenSans-ExtraBold.woff2 -------------------------------------------------------------------------------- /fonts/ExtraBoldItalic/OpenSans-ExtraBoldItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/ExtraBoldItalic/OpenSans-ExtraBoldItalic.eot -------------------------------------------------------------------------------- /fonts/ExtraBoldItalic/OpenSans-ExtraBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/ExtraBoldItalic/OpenSans-ExtraBoldItalic.ttf -------------------------------------------------------------------------------- /fonts/ExtraBoldItalic/OpenSans-ExtraBoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/ExtraBoldItalic/OpenSans-ExtraBoldItalic.woff -------------------------------------------------------------------------------- /fonts/ExtraBoldItalic/OpenSans-ExtraBoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/ExtraBoldItalic/OpenSans-ExtraBoldItalic.woff2 -------------------------------------------------------------------------------- /fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /fonts/Italic/OpenSans-Italic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/Italic/OpenSans-Italic.eot -------------------------------------------------------------------------------- /fonts/Italic/OpenSans-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/Italic/OpenSans-Italic.ttf -------------------------------------------------------------------------------- /fonts/Italic/OpenSans-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/Italic/OpenSans-Italic.woff -------------------------------------------------------------------------------- /fonts/Italic/OpenSans-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/Italic/OpenSans-Italic.woff2 -------------------------------------------------------------------------------- /fonts/Light/OpenSans-Light.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/Light/OpenSans-Light.eot -------------------------------------------------------------------------------- /fonts/Light/OpenSans-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/Light/OpenSans-Light.ttf -------------------------------------------------------------------------------- /fonts/Light/OpenSans-Light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/Light/OpenSans-Light.woff -------------------------------------------------------------------------------- /fonts/Light/OpenSans-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/Light/OpenSans-Light.woff2 -------------------------------------------------------------------------------- /fonts/LightItalic/OpenSans-LightItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/LightItalic/OpenSans-LightItalic.eot -------------------------------------------------------------------------------- /fonts/LightItalic/OpenSans-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/LightItalic/OpenSans-LightItalic.ttf -------------------------------------------------------------------------------- /fonts/LightItalic/OpenSans-LightItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/LightItalic/OpenSans-LightItalic.woff -------------------------------------------------------------------------------- /fonts/LightItalic/OpenSans-LightItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/LightItalic/OpenSans-LightItalic.woff2 -------------------------------------------------------------------------------- /fonts/Regular/OpenSans-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/Regular/OpenSans-Regular.eot -------------------------------------------------------------------------------- /fonts/Regular/OpenSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/Regular/OpenSans-Regular.ttf -------------------------------------------------------------------------------- /fonts/Regular/OpenSans-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/Regular/OpenSans-Regular.woff -------------------------------------------------------------------------------- /fonts/Regular/OpenSans-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/Regular/OpenSans-Regular.woff2 -------------------------------------------------------------------------------- /fonts/Semibold/OpenSans-Semibold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/Semibold/OpenSans-Semibold.eot -------------------------------------------------------------------------------- /fonts/Semibold/OpenSans-Semibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/Semibold/OpenSans-Semibold.ttf -------------------------------------------------------------------------------- /fonts/Semibold/OpenSans-Semibold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/Semibold/OpenSans-Semibold.woff -------------------------------------------------------------------------------- /fonts/Semibold/OpenSans-Semibold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/Semibold/OpenSans-Semibold.woff2 -------------------------------------------------------------------------------- /fonts/SemiboldItalic/OpenSans-SemiboldItalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/SemiboldItalic/OpenSans-SemiboldItalic.eot -------------------------------------------------------------------------------- /fonts/SemiboldItalic/OpenSans-SemiboldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/SemiboldItalic/OpenSans-SemiboldItalic.ttf -------------------------------------------------------------------------------- /fonts/SemiboldItalic/OpenSans-SemiboldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/SemiboldItalic/OpenSans-SemiboldItalic.woff -------------------------------------------------------------------------------- /fonts/SemiboldItalic/OpenSans-SemiboldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/SemiboldItalic/OpenSans-SemiboldItalic.woff2 -------------------------------------------------------------------------------- /fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ircdocs/modern-irc/f3529094c8561b13b89d40b8464f29fcd9c32a50/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /impl.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: So You're Implementing IRC Software? 3 | layout: default 4 | wip: true 5 | copyrights: 6 | - 7 | name: "Daniel Oaks" 8 | org: "ircdocs" 9 | org_link: "http://ircdocs.horse/" 10 | email: "daniel@danieloaks.net" 11 | editor: true 12 | --- 13 | 14 | {% include copyrights.html %} 15 | 16 |
17 |

This document's going to be updated as we find more pitfalls.

18 |

If you think of a new one, or find an error with this document, please open an issue.

19 |
20 | 21 | 22 | 23 | 24 | --- 25 | 26 | 27 | # Introduction 28 | 29 | IRC is touted as being one of the easiest protocols to implement. Just send `NICK` and `USER` and a few `JOIN` commands and you're done, right? 30 | 31 | Well, yes! But also, no. There are some common pitfalls, fragile patterns, and bad habits that IRC software tends to fall into. Here, we outline those and try to describe why and how to avoid them. We've also written up some nice-to-haves that are relatively common, but not really described anywhere. 32 | 33 | 34 | --- 35 | 36 | 37 | # The 'Trailing' Parameter 38 | 39 | Message parameters normally can't contain spaces (since parameters are separated by spaces). But if the last parameter on a message is prefixed by a colon (`":"`), then it's called a 'trailing' parameter and it can include space characters. 40 | 41 | Many clients and libraries split parameters into two sections: Normal parameters, and the Trailing parameter. You should NEVER DO THIS, EVER. The 'trailing' parameter is just a normal parameter, and MUST ALWAYS be just added on to the list of parameters. 42 | 43 | Here's how your IRC Message class should expose parameters to your IRC software, in a C-like language: 44 | 45 | ```c 46 | IRCMessage { 47 | []string Parameters 48 | // there is NO separate TrailingParameter variable 49 | } 50 | ``` 51 | 52 | The list of parameters that your IRC software uses and passes around should contain every normal parameter, and also the 'trailing' parameter. Treating the 'trailing' parameter as special or separate in any other way means that you WILL create broken, fragile software. 53 | 54 | ### Examples In The Wild 55 | 56 | - ["Various command parsers do not handle a colon before the last parameter"](https://github.com/hexchat/hexchat/issues/2271) 57 | - ["PR: Rework MODE/RPL_CHANMODEIS handling for trailing args"](https://github.com/znc/znc/pull/1661) 58 | - ["PR: Moving away from Event.Trailing"](https://github.com/lrstanley/girc/pull/36) 59 | - ["PR: strip colon, if present, from ACCOUNT value"](https://github.com/weechat/weechat/pull/1525) 60 | - ["PR: Remove Trailing param"](https://github.com/khlieng/dispatch/pull/4) 61 | 62 | 63 | ### Ways To Ensure This Doesn't Happen 64 | 65 | You can test your message parser against the [parser-tests](https://github.com/ircdocs/parser-tests/tree/master/tests) repo. Specifically the [`msg-split` test file](https://github.com/ircdocs/parser-tests/blob/master/tests/msg-split.yaml), which includes tests for this specific issue. 66 | 67 | 68 | --- 69 | 70 | 71 | # Tags/Prefixes Can Exist On Any Message 72 | 73 | A good practice for IRC software is to parse incoming IRC lines into a data structure, and then use that data structure everywhere. If your software, instead, just passes the raw line and then matches bytes and strings from the line, you're probably going to run into this issue. 74 | 75 | The gist is that if you enable a capability like [`server-time`](https://ircv3.net/specs/extensions/server-time-3.2.html), then ANY line from the server can contain a `@time` tag. You need to make sure that every command handler including `CAP`, `AUTHENTICATE`, `JOIN`, `PRIVMSG`, etc, can handle having a tag on the message. Along the same lines, any message can contain a `:server.example.com` prefix. 76 | 77 | ### Examples In The Wild 78 | 79 | - ["SASL AUTHENTICATE does not work with a prefix"](https://github.com/znc/znc/issues/1212) 80 | 81 | 82 | 83 | 84 | 94 | -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Modern IRC Client Protocol 3 | html_title: IRC Client Protocol Specification 4 | layout: default 5 | wip: true 6 | copyrights: 7 | - 8 | name: "Jack Allnutt" 9 | org: "Kiwi IRC" 10 | org_link: "https://kiwiirc.com/" 11 | email: "jack@allnutt.eu" 12 | - 13 | name: "Daniel Oaks" 14 | org: "ircdocs" 15 | org_link: "http://ircdocs.horse/" 16 | email: "daniel@danieloaks.net" 17 | - 18 | name: "Val Lorentz" 19 | org: "Limnoria" 20 | org_link: "https://limnoria.net" 21 | email: "vlorentz.ircdocs@isometry.eu" 22 | editor: true 23 | toc: true 24 | --- 25 | 26 | {% include copyrights.html %} 27 | 28 |
29 |

This document intends to be a useful overview and reference of the IRC client protocol as it is implemented today. It is a living specification which is updated in response to feedback and implementations as they change. This document describes existing behaviour and what I consider best practices for new software.

30 |

This is not a new protocol – it is the standard IRC protocol, just described in a single document with some already widely-implemented/accepted features and capabilities. Clients written to this spec will work with old and new servers, and servers written this way will service old and new clients.

31 |

TL;DR if a new RFC was released today describing how IRC works, this is what I think it would look like.

32 |

If something written in here isn't correct for or interoperable with an IRC server / network you know of, please open an issue or contact me.

33 |
34 | 35 |
36 |

NOTE: This is a WORK IN PROGRESS. All major points of the protocol are covered, but some common message and mode types are missing.

37 |

You can contribute by sending pull requests to our GitHub repository!

38 |
39 | 40 | --- 41 | 42 | 43 | # Introduction 44 | 45 | The Internet Relay Chat (IRC) protocol has been designed over a number of years, with multitudes of implementations and use cases appearing. This document describes the IRC Client-Server protocol. 46 | 47 | IRC is a text-based chat protocol which has proven itself valuable and useful. It is well-suited to running on many machines in a distributed fashion. A typical setup involves multiple servers connected in a distributed network. Messages are delivered through this network and state is maintained across it for the connected clients and active channels. 48 | 49 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119](http://tools.ietf.org/html/rfc2119). 50 | 51 | 52 | 53 | 54 | --- 55 | 56 | 57 | # IRC Concepts 58 | 59 | {% include concepts.md %} 60 | 61 | --- 62 | 63 | 64 | # Connection Setup 65 | 66 | IRC client-server connections work over TCP/IP. The standard ports for client-server connections are TCP/6667 for plaintext, and TCP/6697 for TLS connections. 67 | 68 | 69 | --- 70 | 71 | 72 | # Server-to-Server Protocol Structure 73 | 74 | Both [RFC1459](https://tools.ietf.org/html/rfc1459.html) and [RFC2813](https://tools.ietf.org/html/rfc2813.html) define a Server-to-Server protocol. But in the decades since, implementations have extended this protocol and diverged (see [TS6](https://github.com/grawity/irc-docs/blob/725a1f05b85d7a935986ae4f49b058e9b67e7ce9/server/ts6.txt) and [P10](http://web.mit.edu/klmitch/Sipb/devel/src/ircu2.10.11/doc/p10.html)), and servers have created entirely new protocols (see [InspIRCd](https://github.com/inspircd/inspircd)). The days where there was one Server-to-Server Protocol that everyone uses hasn't existed for a long time now. 75 | 76 | However, different IRC implementations don't _need_ to interact with each other. Networks generally run one server software across their entire network, and use the S2S protocol implemented by that server. The client protocol is important, but how servers on the network talk to each other is considered an implementation detail. 77 | 78 | 79 | --- 80 | 81 | 82 | # Client-to-Server Protocol Structure 83 | 84 | {% include c2s_structure.md %} 85 | 86 | --- 87 | 88 | 89 | # Connection Registration 90 | 91 | Immediately upon establishing a connection the client must attempt registration, without waiting for any banner message from the server. 92 | 93 | Until registration is complete, only a limited subset of commands SHOULD be accepted by the server. This is because it makes sense to require a registered (fully connected) client connection before allowing commands such as {% command JOIN %}, {% command PRIVMSG %} and others. 94 | 95 | The recommended order of commands during registration is as follows: 96 | 97 | 1. `CAP LS 302` 98 | 2. `PASS` 99 | 3. `NICK` and `USER` 100 | 4. [Capability Negotiation](#capability-negotiation) 101 | 5. `SASL` (if negotiated) 102 | 6. `CAP END` 103 | 104 | The commands specified in steps 1-3 should be sent on connection. If the server supports [capability negotiation](#capability-negotiation) then registration will be suspended and the client can negotiate client capabilities (steps 4-6). If the server does not support capability negotiation then registration will continue immediately without steps 4-6. 105 | 106 | 1. If the server supports capability negotiation, the {% command CAP %} command suspends the registration process and immediately starts the [capability negotiation](#capability-negotiation) process. `CAP LS 302` means that the client supports [version `302`](https://ircv3.net/specs/extensions/capability-negotiation.html#cap-ls-version) of client capability negotiation. The registration process is resumed when the client sends `CAP END` to the server. 107 | 108 | 2. The {% command PASS %} command is not required for the connection to be registered, but if included it MUST precede the latter of the {% command NICK %} and {% command USER %} commands. 109 | 110 | 3. The {% command NICK %} and {% command USER %} commands are used to set the user's nickname, username and "real name". Unless the registration is suspended by a {% command CAP %} negotiation, these commands will end the registration process. 111 | 112 | 4. The client should request advertised capabilities it wishes to enable here. 113 | 114 | 5. If the client supports [SASL authentication](#authenticate-message) and wishes to authenticate with the server, it should attempt this after a successful [`CAP ACK`](#cap-message) of the `sasl` capability is received and while registration is suspended. 115 | 116 | 6. If the server support capability negotiation, [`CAP END`](#cap-message) will end the negotiation period and resume the registration. 117 | 118 | If the server is waiting to complete a lookup of client information (such as hostname or ident for a username), there may be an arbitrary wait at some point during registration. Servers SHOULD set a reasonable timeout for these lookups. 119 | 120 | Additionally, some servers also send a {% message PING %} and require a matching {% command PONG %} from the client before continuing. This exchange may happen immediately on connection and at any time during connection registration, so clients MUST respond correctly to it. 121 | 122 | Upon successful completion of the registration process, the server MUST send, in this order: 123 | 124 | 1. {% numeric RPL_WELCOME %}, 125 | 2. {% numeric RPL_YOURHOST %}, 126 | 3. {% numeric RPL_CREATED %}, 127 | 4. {% numeric RPL_MYINFO %}, 128 | 5. at least one {% numeric RPL_ISUPPORT %} numeric to the client. 129 | 6. The server MAY then send other numerics and messages. 130 | 7. The server SHOULD then respond as though the client sent the {% command LUSERS %} command and return the appropriate numerics. 131 | 8. The server MUST then respond as though the client sent it the {% message MOTD %} command, i.e. it must send either the successful [Message of the Day](#motd-message) numerics or the {% numeric ERR_NOMOTD %} numeric. 132 | 9. If the user has client modes set on them automatically upon joining the network, the server SHOULD send the client the {% numeric RPL_UMODEIS %} reply or a {% message MODE %} message with the client as target, preferably the former. 133 | 134 | The first parameter of the {% numeric RPL_WELCOME %} message is the nickname assigned by the network to the client. Since it may differ from the nickname the client requested with the `NICK` command (due to, e.g. length limits or policy restrictions on nicknames), the client SHOULD use this parameter to determine its actual nickname at the time of connection. Subsequent nickname changes, client-initiated or not, will be communicated by the server sending a {% message NICK %} message. 135 | 136 | --- 137 | 138 | 139 | # Feature Advertisement 140 | 141 | IRC servers and networks implement many different IRC features, limits, and protocol options that clients should be aware of. The {% numeric RPL_ISUPPORT %} numeric is designed to advertise these features to clients on connection registration, providing a simple way for clients to change their behaviour based on what is implemented on the server. 142 | 143 | Once client registration is complete, the server MUST send at least one `RPL_ISUPPORT` numeric to the client. The server MAY send more than one `RPL_ISUPPORT` numeric and consecutive `RPL_ISUPPORT` numerics SHOULD be sent adjacent to each other. 144 | 145 | Clients SHOULD NOT assume a server supports a feature unless it has been advertised in `RPL_ISUPPORT`. For `RPL_ISUPPORT` parameters which specify a 'default' value, clients SHOULD assume the default value for these parameters until the server advertises these parameters itself. This is generally done for compatibility reasons with older versions of the IRC protocol that do not specify the `RPL_ISUPPORT` numeric and servers that do not advertise those specific tokens. 146 | 147 | For more information and specific details on tokens, see the {% numeric RPL_ISUPPORT %} reply. 148 | 149 | A list of `RPL_ISUPPORT` parameters is available in the [`RPL_ISUPPORT` Parameters](#rplisupport-parameters) section. 150 | 151 | 152 | --- 153 | 154 | 155 | # Capability Negotiation 156 | 157 | Over the years, various extensions to the IRC protocol have been made by server programmers. Often, these extensions are intended to conserve bandwidth, close loopholes left by the original protocol specification, or add new features for users or for server administrators. Most of these changes are backwards-compatible with the base protocol specifications: A command may be added, a reply may be extended to contain more parameters, etc. However, there are extensions which are designed to change protocol behaviour in a backwards-incompatible way. 158 | 159 | Capability Negotiation is a mechanism for the negotiation of protocol extensions, known as **client capabilities**, that makes sure servers implementing backwards-incompatible protocol extensions still interoperate with existing clients, and vice-versa. 160 | 161 | Clients implementing capability negotiation will still interoperate with servers that do not implement it; similarly, servers that implement capability negotiation will successfully communicate with clients that do not implement it. 162 | 163 | IRC is an asynchronous protocol, which means that clients may issue additional IRC commands while previous commands are being processed. Additionally, there is no guarantee of a specific kind of banner being issued upon connection. Some servers also do not complain about unknown commands during registration, which means that a client cannot reliably do passive implementation discovery at registration time. 164 | 165 | The solution to these problems is to allow for active capability negotiation, and to extend the registration process with this negotiation. If the server supports capability negotiation, the registration process will be suspended until negotiation is completed. If the server does not support this, then registration will complete immediately and the client will not use any capabilities. 166 | 167 | Capability negotiation is started by the client issuing a `CAP LS 302` command (indicating to the server support for IRCv3.2 capability negotiation). Negotiation is then performed with the `CAP REQ`, `CAP ACK`, and `CAP NAK` commands, and is ended with the `CAP END` command. 168 | 169 | If used during initial registration, and the server supports capability negotiation, the `CAP` command will suspend registration. Once capability negotiation has ended the registration process will continue. 170 | 171 | Clients and servers should implement capability negotiation and the `CAP` command based on the [Capability Negotiation specification](https://ircv3.net/specs/extensions/capability-negotiation.html). Updates, improvements, and new versions of capability negotiation are managed by the [IRCv3 Working Group](http://ircv3.net/irc/). 172 | 173 | 174 | --- 175 | 176 | 177 | # Client Messages 178 | 179 | Messages are client-to-server only unless otherwise specified. If messages may be sent from the server to a connected client, it will be noted in the message's description. For server-to-client messages of this type, the message `` usually indicates the client the message relates to, but this will be noted in the description. 180 | 181 | In message descriptions, 'command' refers to the message's behaviour when sent from a client to the server. Similarly, 'Command Examples' represent example messages sent from a client to the server, and 'Message Examples' represent example messages sent from the server to a client. If a command is sent from a client to a server with less parameters than the command requires to be processed, the server will reply with an {% numeric ERR_NEEDMOREPARAMS %} numeric and the command will fail. 182 | 183 | In the `"Parameters:"` section, optional parts or parameters are noted with square brackets as such: `"[]"`. Curly braces around a part of parameter indicate that it may be repeated zero or more times, for example: `"{,}"` indicates that there must be at least one ``, and that there may be additional keys separated by the comma `(",", 0x2C)` character. 184 | 185 | 186 | ## Connection Messages 187 | 188 | {% include messages/connection.md %} 189 | 190 | ## Channel Operations 191 | 192 | {% include messages/channel.md %} 193 | 194 | ## Server Queries and Commands 195 | 196 | {% include messages/server_queries.md %} 197 | 198 | ## Sending Messages 199 | 200 | {% include messages/messages.md %} 201 | 202 | ## User-Based Queries 203 | 204 | {% include messages/user_queries.md %} 205 | 206 | ## Operator Messages 207 | 208 | {% include messages/ircop.md %} 209 | 210 | ## Optional Messages 211 | 212 | {% include messages/optional.md %} 213 | 214 | 219 | 220 | --- 221 | 222 |
223 | 224 | {% capture appendixes %}{% include modern-appendix.md %}{% endcapture %} 225 | {{ appendixes | markdownify }} 226 | 227 |
228 | 229 | 230 | --- 231 | 232 | 233 | # Acknowledgements 234 | 235 | This document draws heavily from the original [RFC1459](https://tools.ietf.org/html/rfc1459) and [RFC2812](https://tools.ietf.org/html/rfc2812) IRC protocol specifications. 236 | 237 | Parts of this document come from the "IRC `RPL_ISUPPORT` Numeric Definition" Internet Draft authored by L. Hardy, E. Brocklesby, and K. Mitchell. Parts of this document come from the "IRC Client Capabilities Extension" Internet Draft authored by K. Mitchell, P. Lorier, L. Hardy, and P. Kucharski. Parts of this document come from the [IRCv3 Working Group](http://ircv3.net) specifications. 238 | 239 | Thanks to the following people for contributing to this document, or to helping with IRC specification efforts: 240 | 241 | Simon Butcher, dx, James Wheare, Stephanie Daugherty, Sadie, and all the IRC developers and documentation writers throughout the years. 242 | -------------------------------------------------------------------------------- /js/anchor.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * AnchorJS - v2.0.0 - 2015-10-31 3 | * https://github.com/bryanbraun/anchorjs 4 | * Copyright (c) 2015 Bryan Braun; Licensed MIT 5 | */ 6 | function AnchorJS(A){"use strict";function t(A){o.options.icon=o.options.hasOwnProperty("icon")?A.icon:"",o.options.visible=o.options.hasOwnProperty("visible")?A.visible:"hover",o.options.placement=o.options.hasOwnProperty("placement")?A.placement:"right",o.options.class=o.options.hasOwnProperty("class")?A.class:"",o.options.truncate=o.options.hasOwnProperty("truncate")?Math.floor(A.truncate):64}function e(){if(null===document.head.querySelector("style.anchorjs")){var A,t=document.createElement("style"),e=" .anchorjs-link { opacity: 0; text-decoration: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }",o=" *:hover > .anchorjs-link, .anchorjs-link:focus { opacity: 1; }",n=' @font-face { font-family: "anchorjs-icons"; font-style: normal; font-weight: normal; src: url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBTUAAAC8AAAAYGNtYXAWi9QdAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5Zgq29TcAAAF4AAABNGhlYWQEZM3pAAACrAAAADZoaGVhBhUDxgAAAuQAAAAkaG10eASAADEAAAMIAAAAFGxvY2EAKACuAAADHAAAAAxtYXhwAAgAVwAAAygAAAAgbmFtZQ5yJ3cAAANIAAAB2nBvc3QAAwAAAAAFJAAAACAAAwJAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpywPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6cv//f//AAAAAAAg6cv//f//AAH/4xY5AAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAACADEARAJTAsAAKwBUAAABIiYnJjQ/AT4BMzIWFxYUDwEGIicmND8BNjQnLgEjIgYPAQYUFxYUBw4BIwciJicmND8BNjIXFhQPAQYUFx4BMzI2PwE2NCcmNDc2MhcWFA8BDgEjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAEAAAABAACiToc1Xw889QALBAAAAAAA0XnFFgAAAADRecUWAAAAAAJTAsAAAAAIAAIAAAAAAAAAAQAAA8D/wAAABAAAAAAAAlMAAQAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAACAAAAAoAAMQAAAAAACgAUAB4AmgABAAAABQBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEADgAAAAEAAAAAAAIABwCfAAEAAAAAAAMADgBLAAEAAAAAAAQADgC0AAEAAAAAAAUACwAqAAEAAAAAAAYADgB1AAEAAAAAAAoAGgDeAAMAAQQJAAEAHAAOAAMAAQQJAAIADgCmAAMAAQQJAAMAHABZAAMAAQQJAAQAHADCAAMAAQQJAAUAFgA1AAMAAQQJAAYAHACDAAMAAQQJAAoANAD4YW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzVmVyc2lvbiAxLjAAVgBlAHIAcwBpAG8AbgAgADEALgAwYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzUmVndWxhcgBSAGUAZwB1AGwAYQByYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzRm9udCBnZW5lcmF0ZWQgYnkgSWNvTW9vbi4ARgBvAG4AdAAgAGcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAASQBjAG8ATQBvAG8AbgAuAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==) format("truetype"); }',i=" [data-anchorjs-icon]::after { content: attr(data-anchorjs-icon); }";t.className="anchorjs",t.appendChild(document.createTextNode("")),A=document.head.querySelector('[rel="stylesheet"], style'),void 0===A?document.head.appendChild(t):document.head.insertBefore(t,A),t.sheet.insertRule(e,t.sheet.cssRules.length),t.sheet.insertRule(o,t.sheet.cssRules.length),t.sheet.insertRule(i,t.sheet.cssRules.length),t.sheet.insertRule(n,t.sheet.cssRules.length)}}var o=this;this.options=A||{},t(A),this.add=function(A){var o,n,i,s,a,r,l,c,h,g,B,u;if(t(this.options),A){if("string"!=typeof A)throw new Error("The selector provided to AnchorJS was invalid.")}else A="h1, h2, h3, h4, h5, h6";if(o=document.querySelectorAll(A),0===o.length)return!1;for(e(),n=document.querySelectorAll("[id]"),i=[].map.call(n,function(A){return A.id}),a=0;a