KiTTY 发展史全解:从 2003 年 MOD_PERSO 个人补丁到独立 SSH 客户端的版本演进之路
KiTTY 发展史全解:从 2003 年 MOD_PERSO 个人补丁到独立 SSH 客户端的版本演进之路
本篇文章以 KiTTY 作者 Cyd 亲笔撰写的项目历史文档 docs/pages/history.md 为主体,完整梳理 KiTTY 从 2003 年诞生的个人补丁(MOD_PERSO/PERSOPORT)到 2022 年 0.77 版本为止的二十年演进脉络:包括 PuTTY 基线版本迭代、第三方补丁(RuTTY、TuTTY、PuTTYCyg 等)的合并与取舍、版本控制系统从无到 SVN 再到 Git 的三次迁移,以及作者放弃 Linux 移植的明确理由。文中所有版本号、时间点均以原文档与仓库内可验证文件为准,读者读完后既能完整掌握 KiTTY 的历史沿革与版本关键节点,也能明白"MOD_* 补丁体系"在当前仓库源码中的具体落点。
缘起:2003 年,一位运维工程师的"非分之想"
KiTTY 的故事始于 2003 年,当时作者 Cyd 还是一位运维工程师(ops),并非开发者,他基于 PuTTY 0.53 版本开始了自己的修改。那个年代没有任何源码管理工具(没有 git、svn、cvs),修改工作完全发生在作者自己的 Windows 桌面电脑上(使用 GCC 编译),成果只保存在一台工作机器的目录里——没有备份、没有版本、没有协作。
最初驱动他的只有两个朴素的需求:
- 自动化密码协商:当时需要通过 telnet(注意,不是 SSH)连接 Solaris 或 HP-UX 服务器,这些服务器没有 Linux 环境、也没有 GUI,每次登录都要手工等待密码提示并输入密码,效率极低。
- 每个终端窗口拥有专属图标:当同时打开大量终端窗口时,靠标题文字难以快速区分,如果能给每个窗口设置不同图标就能一眼定位。
正是这两个需求催生了 KiTTY 历史上第一个补丁——MOD_PERSO(在当时被命名为 PERSOPORT)。这个命名习惯一直延续到今天:在 kitty.h 中,MOD_PERSO 是一个贯穿全局的条件编译宏,它决定了软件的身份标识。从 kitty.h 可以看到,当定义了 MOD_PERSO 时,程序使用 KiTTY / kitty.ini / kitty.sav / kitty.exe 作为类名与默认文件名;否则回落到 PuTTY 原版的 PuTTY / putty.ini / putty.exe。也就是说,"KiTTY 就是 PuTTY 加上 MOD_PERSO" 这一论断可以从源码的预处理分支中得到直接印证。
此后作者养成了一个延续至今的工作习惯:每一次 PuTTY 官方发布新版本,都把自己的全部修改合并进去。这种"追着上游走"的模式,决定了 KiTTY 的命运始终与 PuTTY 的版本节奏深度绑定。
公开分享与补丁融合:2006 年,MOD_* 体系的诞生
2006 年,作者以版本 0.58 为起点,正式公开分享自己的工作,创建了 KiTTY 官方网站(9bis.net),源码以最简单的 .tar.gz 压缩包形式提供下载。
随着 KiTTY 逐渐被更多人使用,用户开始提出新需求:整合其他 PuTTY 分支的特性。这一时期被陆续整合的分支包括 LePuTTY、PuTTYTray、TuTTY、RuTTY 等,由此形成了 KiTTY 标志性的 MOD_* 补丁体系——每一个被整合进来的第三方功能,都以一个独立的 MOD_* 编译宏来标记。
这一体系在当前仓库的构建文件中仍然完整可见。在 0.76_My_PuTTY/windows/MAKEFILE.MINGW 中有一段明确的 "BEGIN MOD_PERSO ... END MOD_PERSO" 构建区块,集中列出了当前版本启用的一组编译宏:
MOD_PERSO(KiTTY 本体标识)MOD_BACKGROUNDIMAGE(背景图片,源自 covidimus 补丁)MOD_RECONNECT(自动重连)MOD_HYPERLINK(URL 超链接)MOD_ZMODEM(ZModem 文件传输)MOD_PROXY(代理选择器)MOD_STARTBUTTON、MOD_LAUNCHER(启动器)MOD_SAVEDUMP(按键记录转储)MOD_KEYMAPPING(按键映射)MOD_TUTTY、MOD_TUTTYCOLOR(TuTTY 特性)MOD_PORTKNOCKING(端口敲门)MOD_PUTTYX、MOD_WTS、MOD_PRINTCLIP(剪贴板打印)MOD_RUTTY(RuTTY 脚本补丁)MOD_ADB(adb 支持)MOD_FAR2L(FAR2L 相关编码转换)MOD_DISABLEALTGR、MOD_NOPASSWORD、MOD_NOTRANSPARENCY、MOD_NOHYPERLINK、MOD_PORTABLE等可选开关
仓库根目录下的一批独立子目录就是这些补丁的物理载体:rutty/(RuTTY 脚本引擎)、zmodem/(ZModem 协议)、url/(URL 超链接)、jpeg/ 与 base64/、bcrypt/、md5/、regex/、adb/、far2l/ 等。正如 0.75.md 中所说,KiTTY 是"由许多不同来源组合而成的代码拼布(code patchwork)"——这个比喻在仓库结构上得到了直观验证。
版本控制的三次迁移:2010 SVN → 2015 公开 SVN → 2018 Git
KiTTY 的源码管理历程本身就是一段"从零到现代"的演进史:
- 2010 年,在项目诞生 7 年之后,作者才开始使用版本控制系统。由于当时所在公司使用 subversion,KiTTY 也随之采用 SVN,第一个有版本编号记录的 KiTTY 版本是 0.60.66.30。
- 2015 年,在经历了 0.63 版本的"大爆炸"合并之后(见下文),作者意识到单打独斗难以为继,决定不仅分享源码,还分享版本控制仓库本身,在网站上开放了 SVN 仓库。
- 2018 年,随着版本 0.70 的发布,KiTTY 全面切换到 Git,GitHub 仓库于同年 10 月开放。
从 docs/pages/download.md 中可以看到这一迁移的终点:"SVN repository is not available anymore"(SVN 仓库已不再提供),源码的获取方式已完全转向 Git 仓库。
两次"大爆炸":0.63 与 0.71 的重构阵痛
在 history.md 与同目录的 0.71.md、0.75.md 中,作者反复用"revolution / big bang / adventure"来描述某些版本的合并难度,其中最典型的两次是:
2013 年底:PuTTY 0.63,会话设置结构完全重写
PuTTY 0.63 发布时,内部会话设置(session settings)结构被彻底重写。对于普通用户这只是参数调整,但对于需要把几百处 MOD_* 修改逐一搬移到新结构上的 KiTTY 而言,这是一次耗时巨大的工程。正是这次合并让作者下定决心寻求外部帮助,并在两年后(2015 年)开放了整个版本控制仓库。
2019 年:PuTTY 0.71,第三方补丁的"断舍离"
0.71 版本的差距甚至超过 0.63:会话设置管理再次进化、SSH 核心几乎完全重写、Windows 核心函数也全部重写。更关键的是,一部分并非作者本人编写、而只是被他合并进来的 MOD_ 补丁,在新版本下彻底损坏*。从 0.71.md 可以列出当时被牺牲的功能:
- PuTTYCrypt:从证书获取凭据(
sshpubk.c合并失败) - PuTTYCyg:在 KiTTY 窗口中内嵌运行 Cygwin 终端
- Zmodem:基于 ZModem 协议的文件传输
- covidimus:终端窗口背景图片(作者坦言"毫无用处……但我就是喜欢它",
window.c合并失败)
同时,Portability(便携模式)补丁在 0.71 中被完全重写。
这些被牺牲功能的"遗骸"在仓库中仍可追溯:
- 背景图片功能见 docs/pages/covidimus.md,标注"该功能自 0.71 起失效",配置入口
<a href="https://link.gitcode.com/i/948d3e4b5611e70032c37607a1cf679a" target="_blank">KiTTY] backgroundimage=yes仍保留在 [kitty_ini.txt 中; - Cygwin 内嵌功能见 docs/pages/PuTTYCyg.md,0.71 起失效后,官方以独立的 cygtermd 程序作为替代方案(详见 docs/pages/cygtermd.md),通过
kitty.exe -localproxy "C:\cygwin64\bin\cygtermd.exe /home/%USERNAME% /bin/bash -login" localhost命令仍可在 KiTTY 终端内启动 Cygwin 或 cmd.exe; - 仓库中 cthelper/ 目录(cygcfg.c、cygterm.c、ptyfork.c 等)正是当年 PuTTYCyg 集成遗留的辅助程序源码。
到 0.75 版本,又一批补丁无法延续,0.75.md 列出:TuTTY 颜色补丁(终端内下划线文字以不同颜色显示)、ADB 补丁、以及 GitHub Actions 自动构建。
这一阶段作者还做了一件对后续所有读者都重要的事:2019 年初决定全面改用英语(网站、代码注释、发布说明),年中将多语言网站改为基于 Markdown 文件的纯英语网站——仓库里 docs/pages/ 下全部以 Markdown 编写的功能文档(SessionsFilter、Portability、Shortcuts、AutomaticPassword 等)正是这一转型的成果。
2022 年 0.77:源码目录结构重组
2022 年中,PuTTY 0.77 发布,PuTTY 官方团队对源码文件结构进行了完全重组,大量文件被拆分进若干子目录。作者评价这是"一件好事:源码现在易读多了",但 KiTTY 的适配工作量又一次变得巨大。
有趣的是,这一重组趋势在当前仓库本身中就能看到两种布局的并存对比:
- 0.76_My_PuTTY/:采用 PuTTY 0.76 时代相对扁平的布局,
config.c、settings.c、ssh*.c、windows/*.c等文件平铺在根目录; - 0.76b_My_PuTTY/:已经采用重组后的分目录布局,分别设有
charset/、crypto/(aes.c、rsa.c、sha256.c 等)、keygen/、otherbackends/(raw.c、rlogin.c、telnet.c)、proxy/、ssh/、stubs/、terminal/、test/、utils/、windows/utils/等子目录。
两个目录的版本号也可以交叉验证:0.76_My_PuTTY/windows/version_major.txt 为 "0.76.0"、version_minor.txt 为 14(即 0.76.0.14);0.76b_My_PuTTY/windows/version_major.txt 为 "0.76.1"、version_minor.txt 为 13。从 README.md 的说明"KiTTY is a fork from version 0.76 of PuTTY"以及 HowToCompile.md 中以 0.76b_My_PuTTY/windows 作为编译目录来看,可以推断 0.76b_My_PuTTY 是当前仓库中采用新目录结构的活跃开发基线,而 0.76_My_PuTTY 保留着更早的布局——两套目录并存本身就是"每次上游重组都要重做一次合并"这段历史的实物见证。
平台策略:为什么 KiTTY 永远不做 Linux 版
在 history.md 的末尾,作者用相当直白的语言解释了他明确拒绝 Linux 移植的三点理由,值得原文引用式的准确转述:
- 历史原因:2003 年起步时根本没有考虑过 Linux;
- 技术风险:他并非所有 KiTTY 补丁的原作者(很多是整合而来),无法确认这些补丁能否在 Linux 上正常工作;
- 个人现实:作者本人也是 KiTTY 用户,但只在 Windows 上使用它——因为 Windows 是唯一默认不内置 SSH 客户端的主流桌面平台;当他在 Linux 图形环境下需要连接其他机器时,直接使用系统自带的
ssh命令即可,根本没有 KiTTY 的用武之地。他坦言:"我不知道怎么做到,也没有时间去做。KiTTY 不是我的正式工作。"
这一平台定位同样体现在仓库的事实层面:README.md 明确写着"KiTTY is only designed for the Microsoft Windows platform",构建目标 MAKEFILE.MINGW 也只存在于各版本的 windows/ 子目录下。
开源协作的现实与理念
作为一篇历史文档,history.md 的最后部分还坦率地记录了作者对开源协作的观察与态度:
- 他表示从未拒绝过任何有趣的补丁合并请求,也欢迎任何人提交补丁;
- 但现实是"这 13 年来收到的帮助少之又少"(截至写作时);
- 他特别指出一个现象:"人们常常把开源(open source)与自由软件(free software)混为一谈"——言下之意,免费获取并不等于义务奉献,维护者的精力与时间同样有限。
这段内容虽然不属于具体技术功能,却解释了 KiTTY 补丁体系的组织方式(作者自研 + 第三方整合 + 社区零星贡献),是理解 docs/navigation.md 中数十个功能文档(An icon for each session、Transparency、Port knocking、Automatic command 等)从何而来的背景。
结语:从历史文档到源码的"可追溯性"
回看 KiTTY 的二十年,一条清晰的线索贯穿始终:每一次 PuTTY 上游版本迭代,都触发一次 KiTTY 的合并与取舍;而 MOD_* 编译宏、根目录下的第三方补丁子目录、0.76_My_PuTTY 与 0.76b_My_PuTTY 两套源码布局,以及 docs/pages/ 中标注"broken from 0.71"的 covidimus.md、PuTTYCyg.md 等文档,共同构成了这段历史在仓库内的完整物证链。
对于想进一步深入研究 KiTTY 的读者,建议从以下仓库文件入手:
- 功能全貌:README.md 与 docs/navigation.md
- 默认配置全参数(Agent] / [ConfigBox] / [KiTTY] / [Shortcuts] 各节):[kitty_ini.txt
- MOD_* 编译宏清单:0.76_My_PuTTY/windows/MAKEFILE.MINGW
- 身份标识与默认文件名切换逻辑:kitty.h
- 版本号定义:0.76_My_PuTTY/windows/version_major.txt 与 0.76b_My_PuTTY/windows/version_major.txt
- 编译指南(MinGW32 本地编译与 Docker 交叉编译):HowToCompile.md
最后需要说明的是:本文章所述历史事实以作者亲笔的 docs/pages/history.md 为准,仓库源码仅用于印证其中可验证的部分;文中提及的第三方补丁(RuTTY、TuTTY、PuTTYCyg、covidimus 等)均来自原文档记录,其详细用法可继续查阅 docs/pages/ 下对应的功能文档。