yrc, a Unix IRC client: genesis

Filed under: Software, yrc — Jacob Welsh @ 18:44

The problem I chose to tackle in February 2017 was the need for secure real-time communications in my planned business. "Secure" here didn't mean in the cryptographic sense, but rather having a guarantee, or at least as close to one as could be practically had, that there exists no "magic packet" that could be sent from the outside network to compromise the terminal, at least through this particular hole.

Many of the traditional IRC clients were written in C, a notoriously poor language for providing any sort of guarantee, and inevitably seemed to be loaded with "features" I didn't need, and thus potential for nasty surprises, and reams of code to read if I wished to audit. On the ultra-minimalist end of the spectrum there was ii, but it was way to little, for instance in providing awareness of connection state or tracking multiple channels. (It was telling that they suggested a far more complex program, "multitail", for this.)

At the same time, I was interested in sharpening my skills in network and UI programming; I'd done the latter in various environments including Visual Basic, Qt, PyQt, and urwid, but hadn't found the elusive sweet spot. I decided to take a shot at writing my own client using a high-level language and low-level terminal facilities. "How hard can it be, it's just an event loop, displaying text, parsing a simple protocol, an input state machine and so forth." Hah.

I did make the practical compromise of using Python, due to its fairly robust system interface, rather than, say, the Scheme interpreter I'd been hacking together around the same time. Initially I used the bindings for the classic "ncurses" library. One nice thing it does is track screen state so you can render however inefficiently and screen updates will be sent differentially: originally good for slow serial connections and still good for slow network connections. The other supposed benefit was portability across terminal types. I soon found it to be nothing but trouble, an additional layer of crufty complexity and the supposed portability not being watertight. So I switched my reference to the original DEC VT100 user guide, from which modern Unix terminals are more or less derived, and found the experience altogether more pleasant.

Some 2400 lines of code and a couple revisions later, I have something that I find more or less usable.

Major things that it does NOT intend to support include Unicode and SSL. Notable missing features it ought to have, quoting the manual, include:

  • Prompt history, kill/yank commands
  • Indication of nick mentions (ring bell + bold the window name?)
  • Tab completion (nicks, slash commands)
  • Formatting for displayed messages (e.g. bold sender, highlight own nick)
  • Finish mode/op and close-net commands
  • Filtering of inbound PMs (/ignore or similar)
  • Scrolling based on rendered lines rather than messages
  • Scrolling + more efficient navigation of window list

A fairly detailed manual is included, so see within to learn more.

Download Vpatches

(Hash algorithm is Keccak with 256-bit capacity and 512-bit output. This is aping the previous vpatches I've seen; I do not know the rationale for these parameters.)


  1. Presses fine as it is. Do you use own V and Keccak implementation?

    And had a chuckle at "microsoftesque"!

    Comment by Diana Coman — 2019-11-14 @ 20:00

  2. [...] valued at $2,500. Software7: Bitcoin, GnuPG, Gales Linux, Gales Scheme, Gales Bitcoin Wallet, yrc IRC [...]

    Pingback by JWRD Computing: The why, how, what and way forward. « Dorion Mode — 2019-11-16 @ 03:53

  3. I did a Keccak implementation in C (your articles and collected references on the subject were helpful). It can plug into the perl/python/awk V implementations by pipe. I'm aware that phf's vtools are more robust though.

    Comment by Jacob Welsh — 2019-11-17 @ 19:48

  4. Updated for genesis naming.

    Comment by Jacob Welsh — 2019-12-13 @ 06:15

  5. [...] Install an IRC client and register a nick with #freenode 5 ; Jacob Welsh (WoT: jfw) genesis'd his IRC client, yrc. [...]

    Pingback by Contribution Guidelines for TMSR OS « Dorion Mode — 2019-12-14 @ 06:32

  6. [...] yrc, the Unix Internet Relay Chat (IRC) client. Common modern chat services require the use of the providers' proprietary software clients and servers. IRC is an Internet Standard chat protocol which can be deployed to implement your own privately operated chat network. [...]

    Pingback by Protect What Matters with JWRD « Dorion Mode — 2020-05-02 @ 02:17

  7. My attempt to run this on Python 2.6.6 raised the hopes and then killed them promptly: initial screen is fine and neat but then it runs into compatibility trouble at /connect so I guess it's really Python 2.7, sadly. If it's any help, here's the error I got:

    File "", line 371, in rand_int
    nbytes = (n.bit_length() + 7) / 8
    AttributeError: 'int' object has no attribute 'bit_length'

    Comment by Diana Coman — 2020-05-28 @ 17:56

  8. Adding to it:
    1. the weird: apparently the requirement is even > python 2.7.16 since on said python 2.7.16, the above STILL fails quite the same. A dig through Python docs such as they are seem to list that bit_length() function as "new in version 2.7" indeed but experience adds "not in 2.7.16" (or at least not in 2.7.16 from centos repos...)
    2. the use a bigger hammer solution: the bit_length function turns out to be a relatively short packaging of a few lines of code (possibly packaged in order to make sure one needs to update Python or something); one might but I don't so here's the content of that fabled bit_length, just use the code and be done with it:

    def bit_length(self):
    s = bin(self) # binary representation: bin(-37) --> '-0b100101'
    s = s.lstrip('-0b') # remove leading zeros and minus sign
    return len(s) # len('100101') --> 6

    Comment by Diana Coman — 2020-05-28 @ 18:33

  9. :

    yrctest: jfw yrc looks pretty neat, once the bit_length trouble was sorted; the lack of tab-completion though sucks.
    jfw: diana_coman: hey thanks for testing
    jfw: the tab completion is one among several noted sucks. maybe I'll give the whole thing another pass soon
    diana_coman: jfw: no worries; now I realised I should give it another go on 2.16 after the fix to that bit_length, huh
    jfw: weird that you got that error on 2.7.16; I'm running on a Debian 2.7.3 and otherwise tested on 2.7.13
    jfw: and I woulda thought bit_length would be some efficient internal thing, not "convert to binary string and count digits" lol
    diana_coman: jfw: well, not that I *expected* it was that but ...such said the docs, why would I argue with them.
    yrctest: would you look at that, it works with python 2.6.6 too!
    jfw: oh I see, it's "equivalent to" that but the 2.7 implementation is indeed internal.
    jfw: nice!
    diana_coman: huh, I basically "backported an irc client, in one hour!!11"
    diana_coman: well, alternatively it may be called "messing about with python and irc for one hour" but anyways
    jfw: well seems to be messing about with a useful output at least.
    diana_coman: tsk
    diana_coman: jfw: ftr it was the neat layout of yrc that got me to look at that bit_length thing a bit more
    jfw: diana_coman: good to know. and no 'ncurses' involved either
    jfw: diana_coman: what was the 'tsk' to there - the devoicing?
    diana_coman: jfw: indeed, no (n)curses either; and yes, tsk was to deedbot
    diana_coman: I guess now I got yrc working even on 2.6.6, I'll just have to switch, huh

    Re bit_length, I'm fine to go with the "stringifying" version, it's not any kind of hot spot here.

    Comment by Jacob Welsh — 2020-05-28 @ 19:28

  10. [...] revisit now my IRC client from the other side of seven months since initial public release and a full year since my last round of development on it. Its usage in this interval has been [...]

    Pingback by yrc re-genesis and patch for smooth scrolling and other fixes « Fixpoint — 2020-06-08 @ 06:50

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by MP-WP. Copyright Jacob Welsh.