nntp(n)
β¨ NAME β¨
okay bestie, listen up β this is nntp, the Tcl client for the NNTP protocol. π
π SYNOPSIS π
here's the whole vibe, character for character:
package require Tcl 8.5 9
package require nntp ?0.2.3?
::nntp::nntp ?host? ?port? ?nntpName?
nntpName method ?arg arg ...?
nntpName article ?msgid?
nntpName authinfo ?user? ?pass?
nntpName body ?msgid?
nntpName configure
nntpName configure option
nntpName configure option value ...
nntpName cget option
nntpName date
nntpName group ?group?
nntpName head ?msgid?
nntpName help
nntpName last
nntpName list
nntpName listgroup ?group?
nntpName mode_reader
nntpName newgroups since
nntpName newnews
nntpName newnews since
nntpName newnews group ?since?
nntpName next
nntpName post article
nntpName slave
nntpName stat ?msgid?
nntpName quit
nntpName xgtitle ?group_pattern?
nntpName xhdr field ?range?
nntpName xover ?range?
nntpName xpat field range ?pattern_list?
π DESCRIPTION π
So the nntp package gives you a simple, Tcl-only client library for the NNTP protocol. π¦ No C extensions, no build drama, just vibes and Tcl. β¨
The way it works is lowkey iconic: it opens the standard NNTP socket on the server π, and then hands you a Tcl API so you can talk to all the NNTP protocol commands like the main character you are. π
And here's the part you need to know, fr fr: all server errors come back as Tcl errors (thrown) π which means you must catch them with the Tcl catch command. No sneaky ignoring them, bestie β they will absolutely jump out and ruin your whole script if you don't catch them. π
not me finding out the hard way that uncaught NNTP errors just... end you π catch them. periodt.
more coming in the next parts, don't go anywhere π
π COMMANDS π
Okay bestie, this is the good part. Every method you can call on your nntp object lives here. Buckle up. π
π Opening The Connection
::nntp::nntp ?host? ?port? ?nntpName?β opens a socket connection to the NNTP server you point at and creates a brand new nntp object with a global Tcl command attached to it, and that command's name isnntpName. That's the handle you use to poke at all the NNTP protocol commands for this fresh connection. Default port is"119"and the default host is"news", and you can override both of those with the environment variablesNNTPPORTandNNTPHOSTrespectively. π
Heads up: some commands this package supports are not part of the nntp rfc 977 (http://www.rfc-editor.org/rfc/rfc977.txt) and they will not be available (or implemented) on all nntp servers. Not every server is that girl, ok? π
The access command nntpName has this general shape:
nntpName method ?arg arg ...?
The method and the args decide exactly what the command does. Main character energy, honestly. β¨
π¦ All The Methods, One By One
nntpName article ?msgid?β asks the server for articlemsgidout of the current group. You get the article back as a valid tcl list containing the headers, then a blank line, then the body of the article. Every element in that list is exactly one line of the article. πnntpName authinfo ?user? ?pass?β sends authentication info (username and password) over to the server. Like showing your ID at the door. πnntpName body ?msgid?β asks the server for the body of the articlemsgidfrom the current group. Comes back as a valid tcl list, and each element in the list is one line of the body. No headers, just vibes. πnntpName configurenntpName configure optionnntpName configure option value ...nntpName cget optionβ these query and configure the options of the nntp connection object. Right now literally only one option is supported:-binary. When you set it, articles come back as binary data instead of text. The only methods affected by this arearticleandbody. π
One use case for this option would be downloading articles with yEnc encoded images. Even though they're encoded, the data is still mostly binary, and grabbing it as text will corrupt the information. So don't do that. π
Peep the package yencode for both the encoder and decoder of that kind of data.
nntpName dateβ asks the server for its current date. It comes back in the formatYYYYMMDDHHMMSS. Iconic little timestamp. βnntpName group ?group?β optionally sets the current group, and grabs info about the currently selected group. Returns the estimated number of articles in the group, then the number of the first article in the group, then the last article in the group, then the name of the group. In that order, no cap. π«ΆnntpName head ?msgid?β asks the server for the headers of the articlemsgidfrom the current group. Comes back as a valid tcl list, each element being one line of the headers of the article. πΈnntpName helpβ retrieves a list of the commands that are supported by the news server you're currently attached to. Server's own little menu. πnntpName lastβ sets the current article pointer to point at the previous message (if there is one) and returns themsgidof that message. Going back a page, bestie. β¬ οΈnntpName listβ returns a tcl list of valid newsgroups and associated info. Each newsgroup comes back as an element in the tcl list, formatted like this:
group last first p
where <group> is the name of the newsgroup, <last> is the number of the last known article currently in that newsgroup, <first> is the number of the first article currently in the newsgroup, and <p> is either 'y' or 'n' β saying whether posting to this newsgroup is allowed ('y') or prohibited ('n').
The <first> and <last> fields will always be numeric. They may have leading zeros. And if the <last> field evaluates to less than the <first> field, there are no articles currently on file in the newsgroup. Empty group, we've all been there. π
nntpName listgroup ?group?β asks the server for a list of all the messages (message numbers) in the group given by the argumentgroup, or in the current group if you didn't pass agroupargument at all.nntpName mode_readerβ asks the server for its nntp'MODE READER'response string. π§nntpName newgroups sinceβ asks the server for a list of all the new newsgroups created since the time given by the argumentsince. Thatsinceargument can be any time string understood byclock scan. The tcl list of newsgroups comes back in a similar form to the list of groups returned by thenntpName listcommand. Each element of the list looks like:
group last first p
where <group> is the name of the newsgroup, <last> is the number of the last known article currently in that newsgroup, <first> is the number of the first article currently in the newsgroup, and <p> is either 'y' or 'n' β whether posting to this newsgroup is allowed ('y') or prohibited ('n'). π
nntpName newnewsβ asks the server for a list of new articles posted to the current group in the last day. Fresh drops only. π₯nntpName newnews sinceβ asks the server for a list of new articles posted to the current group since the time given by the argumentsince. Again,sincecan be any time string understood byclock scan.nntpName newnews group ?since?β asks the server for a list of new articles posted to the group given by the argumentgroupsince the time given by the argumentsince(or in the past day if you didn't pass asinceargument). And yes,sincecan be any time string understood byclock scan. β¨nntpName nextβ sets the current article pointer to point at the next message (if there is one) and returns themsgidof that message. Scroll on. β‘οΈnntpName post articleβ posts an article of the form specified in RFC 1036 (http://www.rfc-editor.org/rfc/rfc1036.txt, successor to RFC 850) to the current news group. You're a poster now. πnntpName slaveβ identifies a connection as being made from a slave nntp server. This might be used to indicate that the connection is serving multiple people and should be given priority. Actual use is entirely implementation dependent and may vary from server to server. (It's giving "your mileage may vary", fr fr.)nntpName stat ?msgid?β thestatcommand is similar to thearticlecommand except that no text is returned. When you're selecting by message number within a group,statserves to set the current article pointer without sending text. The returned acknowledgment response will contain the message-id, which may be of some value. Usingstatto select by message-id is valid but of questionable value, since a selection by message-id does NOT alter the "current article pointer". Read that twice bestie. πnntpName quitβ gracefully closes the connection after sending a NNTP QUIT command down the socket. Leaving the party politely. πnntpName xgtitle ?group_pattern?β returns a tcl list where each element is of the form:
newsgroup description
If you specify a group_pattern, then only newsgroups that match the pattern will have their name and description returned. Filtered, hun. π¦
nntpName xhdr field ?range?β returns the specified header field value for the current message or for a list of messages from the current group.fieldis the title of a field in the header such asfrom,subject,date, etc. Ifrangeis not specified or is""then the current message is queried. The command returns a list of elements where each element has the form of:
msgid value
Where msgid is the number of the message and value is the value set for the queried field. The range argument can be in any of the following forms:
""β the current message is queried.msgid1-msgid2β all messages betweenmsgid1andmsgid2(includingmsgid1andmsgid2) are queried.msgid1 msgid2β all messages betweenmsgid1andmsgid2(includingmsgid1andmsgid2) are queried.
nntpName xover ?range?β returns header information for the current message or for a range of messages from the current group. The info comes back in a tcl list where each element is of the form:
msgid subject from date idstring bodysize headersize xref
If range is not specified or is "" then the current message is queried. The range argument can be in any of the following forms:
""β the current message is queried.msgid1-msgid2β all messages betweenmsgid1andmsgid2(includingmsgid1andmsgid2) are queried.msgid1 msgid2β all messages betweenmsgid1andmsgid2(includingmsgid1andmsgid2) are queried.
nntpName xpat field range ?pattern_list?β returns the specified header field value for a specified message or for a list of messages from the current group where the messages match the pattern(s) given in thepattern_list.fieldis the title of a field in the header such asfrom,subject,date, etc. The info comes back in a tcl list where each element is of the form:
msgid value
Where msgid is the number of the message and value is the value set for the queried field. The range argument can be in any of the following forms:
msgidβ the message specified bymsgidis queried.msgid1-msgid2β all messages betweenmsgid1andmsgid2(includingmsgid1andmsgid2) are queried.msgid1 msgid2β all messages betweenmsgid1andmsgid2(includingmsgid1andmsgid2) are queried.
π EXAMPLE π
Here's a bigger example for posting a single article. Steal it, it's yours bestie π«Ά
package require nntp
set n [nntp::nntp NNTP_SERVER]
$n post "From: USER@DOMAIN.EXT (USER_FULL)
Path: COMPUTERNAME!USERNAME
Newsgroups: alt.test
Subject: Tcl test post -ignore
Message-ID: <[pid][clock seconds]
@COMPUTERNAME>
Date: [clock format [clock seconds] -format "%a, %d %
b %y %H:%M:%S GMT" -gmt true]
Test message body"
And that's the whole posting ritual. β¨
π BUGS, IDEAS, FEEDBACK π
okay bestie, real talk: this doc and the whole package it describes are gonna have bugs. Like, undoubtedly. That's just how it is. Not being shady, just being honest fr fr π
So if you find something broken, please report it β and drop it in the category nntp of the Tcllib Trackers:
http://core.tcl.tk/tcllib/reportlist
And listen, it's not just bugs okay?? If you have ideas for enhancements for the package or the docs, send those too π We want the glow-up suggestions, not just the "this is broken" ones. Both are iconic. Both are welcome π«Ά
β¨ proposing code changes? read this part β¨
If you're gonna slide in with actual code changes, pls provide unified diffs β that's literally the output of:
diff -u
no cap, that's the format we want π
β οΈ also!! attachments are strongly preferred over inlined patches. This is a big deal, don't skip it.
Here's how you attach, step by step, so you don't get lost:
- Go to the Edit form of the ticket β do this immediately after its creation π
- Then use the left-most button in the secondary navigation bar π
That's it. That's the whole move. slay β¨
πΈ KEYWORDS πΈ
newsnntpnntpclientrfc 1036rfc 977
π CATEGORY π
Networking β that's the vibe, that's the whole vibe π¦
and that's a wrap on the whole page, bestie!! this doc was living its tcllib 0.2.3 era, version-tagged as nntp(n), and that's the tea π go forth and read your news, you main character ππ§ββοΈ
π¦ where this page comes from
- fedora 43: tcllib 2.0-3.fc43 Β· TCL
- fedora 44: tcllib 2.0-4.fc44 Β· TCL
- nixos 26.05: tcllib 2.0
- nixpkgs unstable: tcllib 2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms