A native port of Lotus 1-2-3 to Linux.

Lotus 1-2-3 for Linux

This is a native port of Lotus 1-2-3 Release 3 to Linux. This is possible because Lotus 1-2-3 for UNIX SystemV used a trick called partial linking to workaround a technical limitation in early UNIX systems. Surprisingly, that can be used to modify it to support new platforms.

There's an article documenting how this is possible here.

Lotus 1-2-3 for Linux

Building

Dependencies

First, you need a version of binutils that is compiled with coff-i386 target support. You can check like this:

$ objdump --info | grep coff-i386

Note: Most distributions do not enable this for some reason.

Run the included binutils.sh to download and compile a version of binutils known to work for this.

Secondly, you need a copy of Lotus 1-2-3 for UNIX, you can download it here. Just place the raw disk images in the build directory and run extract.sh.

Finally, just run make.

Packages

The following packages are required

Ubuntu Fedora Debian (bookworm)
build-essential glibc-devel.i686 build-essential
gcc-multilib libgcc.i686 gcc-multilib
lib32ncurses-dev ncurses-static.i686 lib32ncurses-dev

Binutils

Unfortunately, most distributions do not enable coff-i386 support in binutils.

It's very easy to enable it yourself, download binutils and configure it with --enable-targets=all.

Note: binutils-2.38 is known to work, some earlier versions have been found to not work.

There's no need to install it, just build it with make.

When that's complete, copy objcopy and objdump from the binutils directory, and ld-new from the ld directory to 123elf directory.

Important: Remember to rename ld-new to ld.

The Makefile should automatically use the new binaries, and continue to build.

Running

Just run ./123.

Getting Started

  • There is a man page in ./root/lotus/man/man1/123.1, and a full manual available online here.

Lotus 1-2-3 has context sensitive online help, you can press F1 at most times to see some hints.

Note: You use use the / key to open the 123 menu!

If you've used any spreadsheet before, you should be able to get started quickly. Functions use @ instead of =, but the common functions like @SUM, @AVG, @INDEX, and even @HLOOKUP all work as you would expect.

FAQ

  • Q. How do I quit 123?

If the status indicator in the top right says READY, try /Quit Yes.

If it doesn't say READY (it might say ERROR, HELP POINT, MENU or something else), try hitting Esc until it goes back to READY.

Bugs

  • The keyboard map seems to be incomplete This seems to be working in xterm, please test other terminals!
  • Graphs don't work yet (we're working on it!, see #5).
  • Printing doesn't work yet.
  • File an issue if you notice something, there are probably lots of minor issues that can be fixed!

Security

By default, 123 allows Autoexec macros in worksheets. Lotus macros are very powerful, and can run shell commands, read and write arbitrary files, load plugins and so on.

However, you can disable Autoexec macros via /Worksheet Global Default Autoexec.

I am thinking of changing this default before we reach a first release, see #27.

If you disable Autoexec then in theory it's safe to open untrusted worksheets -- but this software hasn't been maintained for over 30 years, and may contain security bugs!

We can fix bugs with coffsyrup, by redirecting unsafe functions to new safe versions, so we will make a best effort to fix vulnerabilities if you report them!

Owner
Comments
  • "Cannot initialize system file configuration"

    System: Ubuntu 22.04 64b 123elf version: 199b81f400410d23b633ce00edd803bb4a327fd2 Terminal: Konsole (same issue with xterm)

    I made a successful binary using the provided scripts and makefile, but executing it just returns a "123: Cannot initialize system file configuration" error. image Trying to run it with gdb doesn't return any form of crash or error message, it terminates normally.

    Maybe I skipped some configuration step, but the binary seems fine.

  • ubuntu x64 ncurses lib missing

    ubuntu x64 ncurses lib missing

    Hi

    I've tried to build on

    # lsb_release -a
    No LSB modules are available.
    Distributor ID: Ubuntu
    Description:    Ubuntu 20.04.4 LTS
    Release:        20.04
    Codename:       focal
    

    First build binutils with --prefix=/home/user/opt --enable-targets=all And then

    $ make
    cc -m32 -ggdb3 -O0 -Wno-multichar  -m32 -ggdb3 -O0 -Wno-multichar -B. -Wl,-b,coff-i386  coffsyrup.c  -lncurses -o coffsyrup
    ./ld: cannot find -lncurses: No such file or directory
    collect2: error: ld returned 1 exit status
    make: *** [<builtin>: coffsyrup] Error 1
    

    Installing every ncurses* pkg with 32-bit versions didn't help

    # dpkg -l | grep curses | awk '{print $2}'
    lib32ncurses6
    libncurses-dev:amd64
    libncurses5-dev:amd64
    libncurses6:amd64
    libncursesw5-dev:amd64
    libncursesw6:amd64
    mtr-tiny
    ncurses-base
    ncurses-bin
    ncurses-term
    pinentry-curses
    

    Changing Makefile also didn't help LDLIBS = -lncurses -L/usr/lib/x86_64-linux-gnu

    $ make
    cc -m32 -ggdb3 -O0 -Wno-multichar  -m32 -ggdb3 -O0 -Wno-multichar -B. -Wl,-b,coff-i386  coffsyrup.c  -lncurses -L/usr/lib/x86_64-linux-gnu -o coffsyrup
    ./ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libncurses.so.6 when searching for libncurses.so.6
    ./ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libncurses.so.6 when searching for libncurses.so.6
    ./ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libtinfo.so when searching for -ltinfo
    ./ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libtinfo.a when searching for -ltinfo
    ./ld: cannot find -ltinfo: No such file or directory
    ./ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libtinfo.so when searching for -ltinfo
    ./ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libgcc_s.so.1 when searching for libgcc_s.so.1
    collect2: error: ld returned 1 exit status
    make: *** [<builtin>: coffsyrup] Error 1
    

    Even with LDLIBS = -lncurses -L/usr/lib32

    $ make
    cc -m32 -ggdb3 -O0 -Wno-multichar  -m32 -ggdb3 -O0 -Wno-multichar -B. -Wl,-b,coff-i386  coffsyrup.c  -lncurses -L/usr/lib32 -o coffsyrup
    ./ld: cannot find -lncurses: No such file or directory
    collect2: error: ld returned 1 exit status
    make: *** [<builtin>: coffsyrup] Error 1
    
  • Segfault getuid@GLIBC_2.0

    Segfault [email protected]_2.0

    I am using Ubuntu 20.04 and managed to compile it, however it segfaults right after the initial popup showing license information.

    Compilation output:

    $ make
    cc forceplt.o -lc -m32 -ggdb3 -O0 -fno-stack-protector -lc -m32 -ggdb3 -O0 -fno-stack-protector -B. -Wl,-b,coff-i386 -no-pie 123.o dl_init.o main.o wrappers.o patch.o -o 123 -lncurses
    ./ld: forceplt.o: in function `__require_ref':
    (.text+0x470): warning: the use of `tmpnam' is dangerous, better use `mkstemp'
    ./ld: (.text+0x466): warning: the use of `tempnam' is dangerous, better use `mkstemp'
    ./ld: (.text+0x47a): warning: gtty is not implemented and will always fail
    ./ld: (.text+0x47f): warning: stty is not implemented and will always fail
    123: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=284e6f6d00cb478dfe08fbabf732df59e61a4507, for GNU/Linux 3.2.0, with debug_info, not stripped
       text	   data	    bss	    dec	    hex	filename
     943897	 136840	  41328	1122065	 111f11	123
    Copy l123set.cf to ~/.l123set and 1-2-3 should be ready!
    

    GDB output:

    Reading symbols from ./123...
    (gdb) run
    Starting program: ~/123elf/123 
    
    Program received signal SIGSEGV, Segmentation fault.
    0x08127031 in [email protected]_2.0 ()
    (gdb) bt
    #0  0x08127031 in [email protected]_2.0 ()
    #1  0x08112093 in __unix_main ()
    #2  0x0812e987 in main (argc=1, argv=0xffffd5e4, envp=0xffffd5ec) at main.c:19
    

    When using gdb it jumps straight into the SIGSEGV.

    I have tried to uncomment that syscall in redefine.lst but then it crashes on another call:

    Program received signal SIGSEGV, Segmentation fault.
    0x08127031 in [email protected]_2.0 ()
    (gdb) bt
    #0  0x08127031 in [email protected]_2.0 ()
    #1  0x0812e987 in main (argc=1, argv=0xffffd5e4, envp=0xffffd5ec) at main.c:19
    

    Any ideas?

  • Re-implement shell functionality

    Re-implement shell functionality

    "/System" is supposed to redirect to a command shell, useful for macros. However, the terminal would mess up. Symbol "symbol" is now overridden by the combination of termio and posix_spawn, which respect the original terminal configurations.

    Close #15

  • Make program installable and independent of user's working directory

    Make program installable and independent of user's working directory

    Currently program doesn't start if not invoked from the code repo directory:

    $ pwd
    /
    $ /tmp/123elf/123 -f unix -w "/tmp/123/root/lotus/123.v10/smpfiles/income.wk3"
    123: can't access directory </proc/self/cwd/root/lotus/123.v10>, errno = 13
    123: impossible d'acceder au repertoire </proc/self/cwd/root/lotus/123.v10>, erreur = 13
    

    We should have a make install script that will, roughly:

    • copy the binary into /usr/local/bin/123 (where user can change the /usr/local prefix)
    • copy the man page into /usr/local/man/man1/123.1
    • copy other needed files from root/lotus/ into e.g. /usr/local/share/lotus/, and the program should be able to find them there
  • Support for keymap editing

    Support for keymap editing

    It's hard to press some keys in some terminals, I've noticed F10 doesn't work in gnome-terminal.

    I really need to figure out the keymap file format and make a utility that can edit it.

    I think this is a slightly over-engineered file format that has a serialized n-ary tree of key sequences.

    For example, PgUp might generate \e[6~ and might generate \e[C

    It could be stored like this:

                    \e
                    /\
                   [  Escape
                  /\
                 6  C
                /\   \
               ~  ?  Right
               |
              PgUp
    

    This way you navigate the tree to figure out what the user just pressed.

  • adds install target

    adds install target

    adds install target to be system wide Limitation observed:

    1. lotus try to access some file when launching in the shared folder, it seems to only make the welcome screen stuck but haven't tested further (it also try to change the ownership of those files)
    2. lotus have it's own terminfo library I've changed the launcher shim to overwrite the TERM to xterm since I was using st and lotus didn't have it.
  • "setup file damaged, please run setup123"

    Tried compiling with the official instructions on Arch Linux and get this error when I run ./123:

    123: setup file </home/ironveil/.l123set> damaged, please run setup123

    Not sure what went wrong, even after a fresh recompile it still persists. I can add any more information if needed

  • Search for runtime files in shared directory, to support system-wide installation

    Search for runtime files in shared directory, to support system-wide installation

    Check directories relative to the directory the executable is run from.

    If runtime files dir is not found under ${exedir}/root/lotus, try searching in ${exedir}/../share/lotus.

    This should help support system-wide installation and packaging.

    Related to issue #66

  • gunzip 1.6 on Ubuntu 18.04 fails to unzip `.z` files

    gunzip 1.6 on Ubuntu 18.04 fails to unzip `.z` files

    In extract.sh, the find ... gunzip step fails with

    invalid compressed data--code out of range

    for many files using gunzip 1.6 on Ubuntu 18.04. I tried a few other ways to extract the .z files on my Linux machine, but the one that worked was using gunzip 272.250.1 on MacOS.

  • I don't understand the instructions

    I don't understand the instructions

    I really can't understand from the instructions what to do.

    I am running a Debian 11 system. The output of objdump --info | grep coff-i386 is blank. From this I assume I do not have a copy of binutils which supports coff-i386.

    So what should I do next?

    I won't go into explaining what I tried to do because this will just confuse matters.

  • question around using 1-2-3 to view live data?

    question around using 1-2-3 to view live data?

    Is it possible to "push" some data to a running 1-2-3 session from an external binary? And refresh 1-2-3 automatically (i.e. view live data)

  • @INFO(

    @INFO("osreturncode") isn't working

    I think if you do this, the result should be 123:

    123 -e '{system "exit 123"}@INFO("osreturncode")~'
    

    It isn't, it's 31488 ... which is 123 << 8, so maybe it's the wrong endianness or something?

  • OpenBSD port

    OpenBSD port

    Project now builds using the feature branch from https://github.com/taviso/123elf/pull/86

    It segfaults at runtime in init_terminal_settings in wrappers.c, when ioctl(2) (called by tcgetattr(3)) attempts to write to this memory location:

    static struct termios original;
    

    ioctl(2) fails with errno == 14 (EFAULT, "Bad address").

    Is it possible that there is some unsafe programming practice at play here that OpenBSD catches?

  • Port to FreeBSD

    Port to FreeBSD

    • Ported to FreeBSD
    • Makefile now compatible with both GNU make and BSD make

    Caveat: needs GNU binutils 2.38 which is not yet in the FreeBSD ports tree, and binutils.sh will not compile it cleanly as configuration fails to include headers /usr/local/include. Did not want to go down this rabbit hole for now, as perhaps arrival of binutils 2.38 in FreeBSD ports will solve it.

    Closes https://github.com/taviso/123elf/issues/81

  • /File Retrieve glob is case sensitive

    /File Retrieve glob is case sensitive

    A user pointed out over email that the default glob for /File Retrieve is *.wk?, but a user migrating from DOS might reasonably expect their .WK3 files to show up.

    Should the default glob include these?

  • FreeBSD port

    FreeBSD port

    ld (GNU binutils 2.37) segfaults when attempting to link 123 on FreeBSD:

    (gdb) run
    Starting program: /usr/local/bin/ld --eh-frame-hdr -dynamic-linker /libexec/ld-elf.so.1 --hash-style=both --enable-new-dtags -m elf_i386_fbsd -o bin/123 /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtbegin.o -L/usr/lib forceplt.o -lc -b coff-i386 123.o dl_init.o main.o wrappers.o patch.o filemap.o graphics.o draw.o ttydraw/ttydraw.a atfuncs/atfuncs.a forceplt.o --whole-archive ttydraw/ttydraw.a atfuncs/atfuncs.a --no-whole-archive -lncurses -lm -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/crtend.o /usr/lib/crtn.o
    
    Program received signal SIGSEGV, Segmentation fault.
    Address not mapped to object.
    strcmp () at /usr/src/lib/libc/i386/string/strcmp.S:64
    64      /usr/src/lib/libc/i386/string/strcmp.S: No such file or directory.
    (gdb) bt
    #0  strcmp () at /usr/src/lib/libc/i386/string/strcmp.S:64
    #1  0x0068271a in _bfd_generic_link_add_one_symbol ()
    #2  0x006db5cd in _bfd_coff_link_add_symbols ()
    #3  0x005a9a42 in load_symbols ()
    #4  0x005af57f in open_input_bfds ()
    #5  0x005ace97 in lang_process ()
    #6  0x005b507d in main ()
    (gdb) 
    
C++11 port of docopt

docopt.cpp: A C++11 Port Contents docopt creates beautiful command-line interfaces Isn't it awesome how getopt (and boost::program_options for you fan

Jun 8, 2022
Port of ani-cli with more features 😉

Port of ani-cli with more features ??

May 19, 2022
crypted admin shell: SSH-like strong crypto remote admin shell for Linux, BSD, Android, Solaris and OSX
crypted admin shell: SSH-like strong crypto remote admin shell for Linux, BSD, Android, Solaris and OSX

crypted admin shell: SSH-like strong crypto remote admin shell for Linux, BSD, Android, Solaris and OSX

Jun 15, 2022
Graphs the activity of a chia harvester in a linux terminal.
Graphs the activity of a chia harvester in a linux terminal.

Chia Harvest Graph Monitor for Chia Harvesting Introduction The chiaharvestgraph tool will graph Chia Harvesting activity in a linux terminal. Use a 2

Jun 3, 2022
a simple to use linux terminal

a simple to use linux terminal

Feb 17, 2022
Toybox: all-in-one Linux command line.

Toybox: all-in-one Linux command line.

Jun 19, 2022
Free open-source modern C++17 / C++20 framework to create console, forms (GUI like WinForms) and unit test applications on Microsoft Windows, Apple macOS and Linux.
Free open-source modern C++17 / C++20 framework to create console, forms (GUI like WinForms) and unit test applications on Microsoft Windows, Apple macOS and Linux.

xtd Modern C++17/20 framework to create console (CLI), forms (GUI like WinForms) and tunit (unit tests like Microsoft Unit Testing Framework) applicat

Jun 15, 2022
Linux Shell Implementation In C - Language

Linux-Shell ASSIGNMENT 2 Name : Naman Anand Roll no : 200101070 SUBJECT : CS242 ASSIGNMENT : 2 COMPILING AND FOR RUNNING COMMANDS :-> 1)gcc -o 2001010

Oct 30, 2021
A command-line tool to generate Linux manual pages from C source code.

mangen A command-line tool to generate Linux manual pages from C source code. Description mangen is, as said above, a program to generate Linux manual

Nov 15, 2021
Linux Shell Implementation In C - Language

Linux-Mini-Shell This is a C code for Linux Shell (a mini version). The code is designed to work properly in LINUX terminal. To compile the code and r

Dec 1, 2021
FastReport.Cloud console tool for Linux and perhaps some other OSes

FastReport Cloud console shell This is a simple console shell to FastReport Cloud service. Prerequests GNU packages for build shell: curl-development

Feb 10, 2022
Lotus 1-2-3 R4D Display Driver for DOSEMU
Lotus 1-2-3 R4D Display Driver for DOSEMU

Lotus 1-2-3 R4D Display Driver for DOSEMU2 This is a WIP display driver for Lotus 1-2-3 R4D to enable support for arbitrary text resolutions in DOSEMU

Jun 13, 2022
Port-Fin(port finder) is a tool which scans for open and closed port on a website/host.
Port-Fin(port finder) is a tool which scans for open and closed port on a website/host.

Port-Fin(port finder) is a tool which scans for open and closed port on a website/host. This tool scans the state of the well known/common ports.

Dec 14, 2021
Minimal Linux Live (MLL) is a tiny educational Linux distribution, which is designed to be built from scratch by using a collection of automated shell scripts. Minimal Linux Live offers a core environment with just the Linux kernel, GNU C library, and Busybox userland utilities.
Minimal Linux Live (MLL) is a tiny educational Linux distribution, which is designed to be built from scratch by using a collection of automated shell scripts. Minimal Linux Live offers a core environment with just the Linux kernel, GNU C library, and Busybox userland utilities.

Minimal Linux Live (MLL) is a tiny educational Linux distribution, which is designed to be built from scratch by using a collection of automated shell scripts. Minimal Linux Live offers a core environment with just the Linux kernel, GNU C library, and Busybox userland utilities.

Jun 13, 2022
FFmpeg Kit for applications. Supports Android, Flutter, iOS, macOS, React Native and tvOS. Supersedes MobileFFmpeg, flutter_ffmpeg and react-native-ffmpeg.
FFmpeg Kit for applications. Supports Android, Flutter, iOS, macOS, React Native and tvOS. Supersedes MobileFFmpeg, flutter_ffmpeg and react-native-ffmpeg.

FFmpeg Kit for applications. Supports Android, Flutter, iOS, macOS, React Native and tvOS. Supersedes MobileFFmpeg, flutter_ffmpeg and react-native-ffmpeg.

Jun 18, 2022
Plays native alert sound and shows native dialogs/alerts in your Flutter app.
Plays native alert sound and shows native dialogs/alerts in your Flutter app.

flutter_platform_alert 2021 © Weizhong Yang a.k.a zonble. A simple plugin to present native alerts, including playing alert sounds and showing alert d

Jun 18, 2022
React-native-quick-sqlite - ⚡️ The fastest SQLite implementation for react-native.
React-native-quick-sqlite - ⚡️ The fastest SQLite implementation for react-native.

React Native Quick SQLite The **fastest** SQLite implementation for react-native. Copy typeORM patch-package from example dir npm i react-nati

Jun 22, 2022
Visual Studio native debugger extension to help debug native applications using Mono.
Visual Studio native debugger extension to help debug native applications using Mono.

Unity Mixed Callstack UnityMixedCallstack is a Visual Studio 2017/2019 extension to help debug native applications embedding Mono, like Unity. If you

Apr 1, 2022
Linux/X11 tool for intercepting mouse events and executing commands. Written in Kotlin Native.

XMG XMG (X11 Mouse Grabber) is a Linux/X11 tool for intercepting mouse button press events and triggering actions. It's a way of making use of the ext

Sep 11, 2021
Native ApprovalTests for C++ on Linux, Mac and Windows

Approval Tests for C++ ⬇️ Download the latest version (v.10.8.0) of the single header file here. ?? Read the Docs Contents What are Approval Tests? Re

May 27, 2022