12P by xguru 2022-05-25 | favorite | 댓글 4개
  • 30년된 Lotus의 Unix 버전을 Linux에 이식한 과정을 정리

배경

  • Lotus의 팬이라 기존 DOS버전을 리버스엔지니어링 하여 DosEmu용 디스플레이 드라이버를 만들어서 실행했음
  • 그러나 예전 로터스의 Add-in들은 불가능 했음, LPL 이라고 하는 특수언어로 개발되었고, 컴파일러/SDK가 없음
    → 그 시절 $395나 되는 유료 제품 이었고, 가진 사람을 찾지 못함
  • 그러다 90년대 BBS를 운영하던 SYSOP을 통해서 테이프 백업에서 SDK의 Warez 본을 구함
    → ADK(Add-in Development Kit) for Lotus 1-2-3
  • 그 BBS에는 Lotus 1-2-3 for Unix 의 Warez 버전도 있었음
    → 유명 Unix 오피스 경쟁제품인 SCO Professional 때문에 얼마 팔리지 않아서 잊힌 제품

Lotus 1-2-3 for Unix

  • TD0 라고 하는 80년대에 사용하던 압축 디스크 이미지 포맷으로 구성되어 있었음
  • samdisk 로 raw 디스크 이미지로 변환
  • 디스크 내용중에 1-2-3의 심볼이 포함된 object 파일이 포함되어 있는 것을 발견
    → 90년대 초에는 dlopen()이 많이 쓰이지 않았기 때문에 이런 것이 필요했다고

해킹

  • 이 오브젝트 파일로 인해서 Lotus 1-2-3 내부 구조에 대해 가졌던 많은 의문이 풀렸음
  • 만들고 있던 드라이버가 더 많은 일을 할 수 있게 됨

GNU objcopy

  • 이 오브젝트 파일이 컴파일 되었을 때는 Linux의 첫번째 버전도 출시 되지 않았었음
  • 하지만 objcopy 로 COFF 오브젝트 파일을 ELF로 변환 가능

Porting Problem

System Calls

  • 첫번째 문제는 Linux 와 UNIX가 같은 시스템 콜 인터페이스를 가지고 있지 않다는 것
  • UNIX는 lcall7 인터페이스를 사용하므로, open() 을 찾아서 glibc로 호출하도록 하기로 함
    → 이 심볼을 undefined로 바꿔버리면 링커가 알아서 하지 않을까?
    → 하지만 objcopy가 그렇게 동작하지는 않아서, 결국엔 강제로 지워주는 coffsyrup 이라는 도구를 작성
  • 호환되지 않는 몇몇 함수들을 objcopy + coffsyrup 으로 모두 변경
    → stat(), times(), uname(), fcntl(), ioctl()

Licensing

  • 물론 이 소프트웨어는 라이센스 없이는 동작하지 않음
  • 본인은 Lotus 1-2-3 박스도 가지는 정식 소유자고, 32년된 abandoware 이기도 하므로
    아마도 개발자인 Mitch Kapor도 이 라이센스 체크를 패스하는 것을 뭐라고 하지 않을거라 생각
    → (Mitch Kapor 는 Lotus를 개발한 것으로 유명하며, EFF의 공동 창립자 이기도 합니다.)
  • lic_init() 함수에서 LICENSE.000 파일에 날짜와 사용자/시스템 명이 있으면 동작하므로 이렇게 맞춰줘서 패스!

Result

  • 결과적으로 Lotus 1-2-3 가 새 OS(리눅스)로 포팅됨
  • 아직 꼬인 부분이 있지만 100% 사용 가능

맙소사...이게 머선.. ㅎㄷㄷ

덕중의 덕은 양덕이라더니.. 정말 그 말이 맞네요..

와.. 정말 대단한 열정. 전 Lotus는 그렇게 많이 쓰지는 않았고, 주로 멀티플랜을 썼어요
https://en.wikipedia.org/wiki/Multiplan

멀티플랜은 한글 버전도 나왔어서 그 시절에 한글이 제대로 지원 되던 것은 이 제품 뿐이었습니다.
94년에 단종은 되었지만, 국내에선 회사에서 사용중인 데가 많아서 97년 즈음까지 썼던것 같아요.
멀티플랜단종-도스시대의 종언

https://www.hellomarket.com/item/162929337

미개봉 한글 멀티플랜 패키지를 판매하는 게시물을 찾았네요.. 우어..