I'm working on a DOS server based on mTCP and a Linux FUSE client which can talk to it and expose the DOS system's filesystem to Linux.
I've got various, shifting goals:
- Back up DOS systems using rsync-based tools like rsnapshot or dirvish, and in some cases Git
- Back up the contents of compressed volumes (that nobody understands the format of) as above
- Compare and synchronise what is on a DOS system against a backup or a mounted disk image using rsync
- Use Git to manage the source code for the server I'm working on (the Git repo's .git directory wouldn't live on the DOS filesystem, instead I'd mount the DOS filesystem inside the Git repo)
- Use DOS as a development environment because it's fun
I could certainly back up an emulated DOS system using rsync or similar by just mounting the disk image, but can't do the same for some compressed volume files.
I spent some time looking at/for existing network file systems, but nothing seemed to be suitable:
- SMB/CIFS: Linux's smbclient and mount -t cifs don't seem to want to talk to Microsoft Workgroup Add-on for MS-DOS. It looks like this broke somewhere between Samba versions 1 and 2, which I think was last century. I don't want to maintain a fork of Samba again, I did that at work once and it just changes too much without explanation. I don't think they'd accept patches because even support for plain text authentication is deprecated - I think they want to move away from supporting my use case, not toward it, which I think makes sense.
- NetWare Lite: ncpfs was removed from the Linux kernel some time ago.
- NFS: I could find an NFS version 2 server for DOS, but the Linux kernel no longer supports NFS version 2.
- FTP: I could run an mTCP FTP server and get a Linux FUSE client to mount it, but whereas FAT stores time stamps accurate to 2 seconds, an FTP directory listing might just say "Sep 22 2024" without telling you the time at all, and FTP isn't a great match for a filesystem - it doesn't support random access to files.
So I have an interesting project to work on now, and I think I have read-only mounts working well enough with an emulated machine that I get the same results rsyncing from my FUSE-mounted filesystem vs. using the Linux kernel's "msdos" filesystem.
It should be possible to make clients for FreeBSD, macOS and Windows too - I believe they all have (probably not identical) FUSE implementations.
Would anyone else find this useful? What would you want to use it for?
Use Git to manage the source code for the server I'm working on (the Git repo's .git directory wouldn't live on the DOS filesystem, instead I'd mount the DOS filesystem inside the Git repo)
Use DOS as a development environment because it's fun
NetWare Lite: ncpfs was removed from the Linux kernel some time ago.
As far as I know, NetWare Lite is not really NCP, but Personal NetWare (the sucessor of NetWare Lite that was bundled with Novell DOS 7) is. One telltale sign is that for diskless boot, you need to load an 8K TSR (BOOTNCP) on an NetWare Lite server, but just a 500 byte TSR (NEARSERV) on a Personal NetWare server. NEARSERV just responds to the "get nearest server" broadcast sent by the boot ROM first to find an NCP server that can be booted from.
As far as I know, NetWare Lite is not really NCP, but Personal NetWare (the sucessor of NetWare Lite that was bundled with Novell DOS 7) is. One telltale sign is that for diskless boot, you need to load an 8K TSR (BOOTNCP) on an NetWare Lite server, but just a 500 byte TSR (NEARSERV) on a Personal NetWare server. NEARSERV just responds to the "get nearest server" broadcast sent by the boot ROM first to find an NCP server that can be booted from.
Oh wow, thanks for the info, I'm glad I didn't spend time trying that option out then - lucky ncpfs was already removed from the kernel 😁 Interesting, https://tldp.org/HOWTO/IPX-HOWTO-9.html says:
The ncpfs package will work with Novell fileservers of version 3.x and later, it will not work the Novell 2.x.
I figured NetWare 3.x and NetWare Lite were from around the same time, and I think I used ncpfs with NetWare 3.x in the past, but I suppose NetWare Lite may have been based on NetWare 2.x then.
I would definitely find this useful, and use it for the use cases you mentioned above.
Thanks for the feedback! I hope you don't mind some more questions, so I can see if I'm on the right track:
I forgot to mention that I plan for this to be a DOS server that accepts just one connection at a time, with the intent that nothing else is running on the DOS machine - it's not a TSR, but something more akin to the server for InterLink or some other serial/parallel file sharing server in my mind. To be fair I've done most of my testing with it running under DESQview - since that's my development environment - but I haven't tried to do anything like access the same file from both DOS and the Linux client. Does that sound okay? Really I just don't want to have to pass through file locking requests to DOS, at least not yet - it's probably not actually that hard, but I don't think I need it yet.
Another limitation: no Long File Name support yet, although it probably wouldn't be too hard to add.
Also, you might know something about a problem I was trying to deal with in the last few days - from my work-in-progress README:
1Character set for directory and file name encoding 2-------------------------------------------------- 3 4`-o charset=NAME` may be used to request that the character 5set/encoding `NAME` be used for decoding names received from DOS and 6encoding those sent to it. 7 8The default is `cp437`. 9 10FIXME: For what cases is this suitable? Original DOS? US English 11DOS? DOS without COUNTRY= or something? 12 13The Linux kernel's `msdos` filesystem has `codepage` and `iocharset` 14mount options, but these seem to be broken in recent Linux kernels. 15To get behavior equivalent to a recent Linux kernel, use 16`-o charset=ascii`. 17 18FIXME: show examples
I don't really know much about this, since I'm lucky enough that all the characters I ever cared to put in a filename were ASCII; do you have experience with using non-ASCII characters in filenames?
All I know is that I have some old Windows 98 SE installation where I found that the "sendto" folder's short file name for the shortcut for sending to floppy disk showed up as "3½flop~1.lnk" when using my client with cp437, but when I mounted the drive using the kernel's FAT support (sudo mount -t msdos ... /dev/loop0p1) it showed up as "3\#253flop~1.lnk". I was able to get the same result when I got my client to use Python's ASCII encoding with the "surrogateescape" option. My assumption is that DOS would have just displayed characters found in filenames using whatever the current character set was, and the default is CP437, so that is a sensible default for my client, but I'm not totally sure on this.
I would definitely find this useful, and use it for the use cases you mentioned above.
Thanks for the feedback! I hope you don't mind some more questions, so I can see if I'm on the right track:
I forgot to mention that I plan for this to be a DOS server that accepts just one connection at a time, with the intent that nothing else is running on the DOS machine - it's not a TSR, but something more akin to the server for InterLink or some other serial/parallel file sharing server in my mind. To be fair I've done most of my testing with it running under DESQview - since that's my development environment - but I haven't tried to do anything like access the same file from both DOS and the Linux client. Does that sound okay? Really I just don't want to have to pass through file locking requests to DOS, at least not yet - it's probably not actually that hard, but I don't think I need it yet.
Standalone application sounds fine. Currently, if I develop low-level stuff (which doesn't work in the Win98 DOS box) for DOS I want to track in git, the use case is to boot DOS, do some development work, reboot to Windows 9x, copy the source files to my modern machine (my main machine is a windows machine, and I can access the shares on Windows 9x computers from it without problems), do git stuff there and reboot the retro box to DOS. Just starting a server, and being able to run things like "git status", "git diff" and "git commit" directly using the data from the DOS system sound like a huge efficiency improvement.
dosheawrote on 2025-08-31, 00:44:Also, you might know something about a problem I was trying to deal with in the last few days - from my work-in-progress README: […] Show full quote
Also, you might know something about a problem I was trying to deal with in the last few days - from my work-in-progress README:
1Character set for directory and file name encoding
I don't really know much about this, since I'm lucky enough that all the characters I ever cared to put in a filename were ASCII; do you have experience with using non-ASCII characters in filenames?
First, a clarification: When I write DOS, this does not include Windows 95 and up supporting Long File Names, but this is about classic DOS (up to 6.22).
Yeah, I've seen (although not used very much) non-ASCII characters in DOS filenames. As I am from Germany, we have the letter variants ä, ö and ü, which could make sense in file names as well. Support for these letters in filenames is perfectly in the DOS kernel itself, properly making them case insensitive, but DOS applications often did not support upcasing/downcasing these letters and didn't bother to use the DOS filename case translation services. DOS always reports filenames upper-case (as it is stored on the medium), and programs that want to display lowercase filenames need to down-case the letters inside that program. So if I have a file called "TÜR.TXT" (German for "DOOR.TXT"), that's how DOS will return the name on findfirst/findnext, and a significant amount of applications that want to display lowercase filenames will mis-display this name as "tÜr.txt" instead of "tür.txt".
The case handling (e.g. for file names) is configured using the "COUNTRY" statement in config.sys. Using a disk that has been written with a different county setting than your current one is not a supported use-case in DOS. For example, CP437 does not include upper-case accented letters except É, so if I create a french file called "hôtel.txt", it will be created as "HôTEL.TXT" on the medium. Microsoft recommends use of codepage 850 in Europe, which does include the character Ô (at character code E2), which is "Γ" (Greek letter capital Gamma) in CP437. So if I try to open the file called "HôTEL.TXT" (this is the same, no matter whether encoded as CP437 or CP850) on a system using CP850, DOS will not find that file, because no matter whether I pass "hôtel.txt" or "HÔTEL.TXT" or a diffent mixed-case variant of it, DOS is going to search for "HÔTEL.TXT" (interpreted as CP850) or "HΓTEL.TXT" (interpreted as CP437), the second character having the byte value E2, and can not find the file "HôTEL.TXT" (the second character having the byte value 93) that is actually present.
So you can only make correct sense of DOS filenames if you know the encoding they are in (just like with 8-bit text files).
All I know is that I have some old Windows 98 SE installation where I found that the "sendto" folder's short file name for the shortcut for sending to floppy disk showed up as "3½flop~1.lnk" when using my client with cp437, but when I mounted the drive using the kernel's FAT support (sudo mount -t msdos ... /dev/loop0p1) it showed up as "3\#253flop~1.lnk". I was able to get the same result when I got my client to use Python's ASCII encoding with the "surrogateescape" option. My assumption is that DOS would have just displayed characters found in filenames using whatever the current character set was, and the default is CP437, so that is a sensible default for my client, but I'm not totally sure on this.
Exactly that's correct. You should be able to mount the disk with -t msdos -o codepage=437,iocharset=utf8. That codepage value is the documented default, so likely only the iocharset parameter is important. This will make the linux kernel translate between utf8 for the userspace interface and codepage 437 on the disk.
I think it makes sense for to use cp437 with your client by default, but it might be even smarter if you can use the current code page of the DOS systems.