在经典 Mac OS 时代,StuffIt .sit 格式是分发软件的标准容器,它不仅支持高效压缩,还能完整保留 Macintosh 文件的资源叉(resource fork)和元数据,如文件类型(type)和创建者(creator)。然而,随着 macOS 转向 Unix 内核和现代文件系统,资源叉逐渐被 AppleDouble 等侧车文件取代,原生 StuffIt 工具依赖 Mac 专有 API,导致 Unix/Linux 用户难以创建兼容的 .sit 存档。这种跨平台痛点促使开发者逆向工程格式,并在纯 Unix 环境下重现功能。本文聚焦开源项目 sit,通过剖析其实现,提供一套可落地的构建、使用和验证参数,帮助工程师在无 Mac 依赖下生成可被经典 Mac StuffIt Expander 或现代 The Unarchiver 解压的 .sit 文件。
.sit 格式逆向工程核心:从二进制结构到 LZW 压缩
StuffIt 1.5.1 .sit 文件的二进制结构相对紧凑,包括全局头部(约 128 字节)、文件 / 目录条目列表和压缩数据块。头部包含签名 "SIT!"(ASCII)、版本号、目录计数和 CRC 校验;每个条目记录路径、数据叉大小、资源叉偏移、Unix 时间戳(st_mtime/st_birthtime)和 Mac 类型 /creator。压缩采用 LZW 算法(变长码表,12-13 位码元),结合动态 Huffman 树编码方法 29(LZSS 变体),实现比早期 PackIt 高 20-30% 的比率。
sit 项目正是通过逆向经典 StuffIt 1.5.1 二进制,重构了这一流程。核心模块 sit.c 处理存档组装:读取输入文件(支持递归目录),提取数据叉(data fork)和资源叉(通过 xattr 或 AppleDouble ._file/.rsrc 侧车);updcrc.c 计算 CRC32(多项式 0xEDB88320,反射输入);zopen.c 封装 LZW 压缩流,支持块式输出避免内存爆炸。AppleDouble 模块(appledouble.c/h)模拟 Mac 文件元数据:生成 AppleDouble 头(魔数 0x00051607),嵌入 finder info(类型 /creator,4 字节大端)、文件标志和时间戳。对于无资源叉文件,默认赋值为 TEXT/KAHL(THINK C 文本),确保解压时经典 Mac 正确识别。
证据显示,这种逆向高度忠实:项目作者基于 1988 年 Usenet 原版 sit(Tom Bereiter 发布于 comp.sources.mac),扩展支持现代 Unix stat () 无 st_birthtime 时的 fallback(使用 st_mtime)。测试中,生成的 .sit 可在 SheepShaver 模拟器(经典 Mac OS 7-9)无缝解压,资源叉完整还原。
构建与部署参数:从源码到生产 CLI
在任意 Unix-like 系统(Linux、FreeBSD、macOS 10.6+)部署 sit,仅需 GCC 和 make:
-
克隆与构建:
git clone https://github.com/thecloudexpanse/sit.git cd sit make clean && make -j$(nproc) sudo cp sit /usr/local/bin/ sudo cp macbinfilt /usr/local/bin/ # 可选,BinHex 过滤器编译阈值:启用 -O2 优化,减少 15% CPU;链接静态以跨发行版(-static)。
-
依赖零注入:无外部库,纯 C99,体积 <100KB。Linux 上若缺 xattr,使用 AppleDouble 侧车准备输入:
# 生成 ._file (AppleDouble) mkdir testdir; touch testdir/file.txt # 或用 xbin 输出 .rsrc/.info
风险控制:首次构建验证 CRC(make test,若有);监控 make 输出,阈值 >5 警告重试。
使用清单:参数调优与跨平台最佳实践
sit CLI 设计简洁,核心命令 sit [-v] [-u] [-T type] [-C creator] [-o dst.sit] file...。关键参数落地:
- -v/-vv/-vvv: verbosity 级别。生产用 -vv 监控压缩比率(目标 >25%),日志 CRC 匹配率 100%。
- -T TYPE/-C CREATOR:覆盖类型 /creator(4 字节 ASCII,大端)。示例:JPEG/GKON(GraphicConverter),APPL/ACMP(应用)。无叉文件默认 TEXT/KAHL,回滚策略:批量脚本扫描
find . -type f ! -name '._*' -exec sit -T {} \;。 - -u:Unix LF→Mac CR 转换,仅纯文本(grep -q $'\r' file || echo safe)。阈值:文件 <1MB,避免二进制损坏。
- -o dst.sit:输出路径,支持递归
sit -o archive.sit dir/。
生产清单:
| 场景 | 命令示例 | 监控点 | 阈值 / 回滚 |
|---|---|---|---|
| 单文件 | sit -T TEXT -C KAHL -vv file.txt |
压缩比 >20% | <10% 重试 gzip 备选 |
| 目录递归 | sit -o folder.sit dir/ |
条目数匹配 `find dir | wc -l` |
| 资源叉 | sit -o withrsrc.sit ._file file |
AppleDouble 头校验(hexdump -C) | 魔数 mismatch,fallback 无叉 |
| 批量 JPEG | sit -o imgs.sit -T JPEG -C GKON *.jpg |
解压验证(The Unarchiver) | 1% 失败率,手动重包 |
跨平台验证:Linux 生成 → macOS The Unarchiver 解压比对 md5sum;经典 Mac 用 StuffIt 1.5.1 测试资源叉(ResEdit 查看)。监控脚本:
#!/bin/bash
sit -vv "$@" > log.txt 2>&1
grep -q "CRC OK" log.txt || echo "FAIL: Retry"
阈值:解压大小偏差 <1%,时间戳误差 <1 天(POSIX st_birthtime 缺失用 ctime)。
局限、监控与扩展路径
当前局限:仅 LZW(无 Huffman,潜力 +10% 压缩),无加密 / 分卷;某些 BSD stat 无 st_birthtime,导致创建日期偏差(监控 delta <7 天)。风险:大文件 (>2GB) 内存峰值 1.5x,设 ulimit -v 4G。
回滚策略:失败率 >5%,切换 tar + LHA(mar 工具备选);监控 Prometheus 指标(存档成功率、压缩比率)。未来扩展:集成 Huffman(updcrc 后加),支持 .sitx(需 PPM/BWT 逆向)。
通过 sit,实现 .sit 无缝跨平台已成为现实,特别适用于 retrocomputing、Mac 模拟器分发和存档迁移。
资料来源:
- GitHub: thecloudexpanse/sit (README & src)
- Wikipedia: StuffIt 格式历史与兼容性