Hi Samuel, first, note that this is off-topic on tech@. If you see a need to continue the thread, please move it to misc@.
Samuel Marks wrote on Sun, Sep 05, 2021 at 02:10:14PM -0400: > WiP, basically just started this: > https://github.com/offscale/libacquire/tree/423b751/libacquire/openbsd_ftp I feel unsure what you are trying to achieve. The README.md in that directory is so terse that i don't really understand what the point is. > What: > - My project allows for switching between the HTTPS interface provided > by your OS, and libcurl's HTTPS interface. I don't really understand what that is supposed to mean either. > Why OpenBSD `ftp` port: > - I don't have a "pure" socket solution, and OpenBSD does not have a C > interface version of their `ftp` (like, `fetch` from FreeBSD does, for > example) > - SLOC is short > - It's from OpenBSD which gives certain trust for protocol conformity, > safety, security, lower rates of change, and all-in-all quality None of that applies to our current implementation of the ftp(1) client. Yes, like everything in OpenBSD, it did receive some auditing, some maintenance, and some feature additions helping security in the past. But all the same, our -current ftp(1) client consists of ancient, terribly ill-designed, technically totally outdated and obsolete code. So much so that developers felt it was time to throw it all away and write a completely new ftp(1) program from scratch. One developer started an effort to do so, and that new program can already do most of what ftp(1) should, but before it was completely ready for commit, the effort unfortunately somehow petered out, so we still have the old shit in the tree. > - Once the MSVC port is done, the port to other OSs should be > relatively trivial Porting OpenBSD software to other systems is often a good idea. Worthy examples include OpenSSH, OpenBGPD, OpenNTPD, OpenSMTPD, OpenIKED, LibreSSL, and there are likely many more. But OpenBSD ftp(1) is most definitely not a worthy target for porting. Just look at this utter mess: $ cd /usr/src/usr.bin/ftp/ $ grep jmp *.c cmds.c: (void)setjmp(jabort); cmds.c: (void)setjmp(jabort); cmds.c: (void)setjmp(jabort); cmds.c:jmp_buf abortprox; cmds.c: longjmp(abortprox, 1); cmds.c: if (setjmp(abortprox)) { fetch.c:static jmp_buf httpabort; fetch.c: if (setjmp(httpabort)) { fetch.c: if (setjmp(httpabort)) { fetch.c: longjmp(httpabort, 1); fetch.c: if (setjmp(toplevel)) { ftp.c:jmp_buf ptabort; ftp.c: longjmp(ptabort, 1); ftp.c:jmp_buf sendabort; ftp.c: longjmp(sendabort, 1); ftp.c: if (setjmp(sendabort)) { ftp.c: if (setjmp(sendabort)) ftp.c:jmp_buf recvabort; ftp.c: longjmp(recvabort, 1); ftp.c: if (setjmp(recvabort)) { ftp.c: if (setjmp(recvabort)) ftp.c: longjmp(ptabort, 1); ftp.c: if (setjmp(ptabort)) ftp.c:jmp_buf forceabort; ftp.c: longjmp(forceabort, 1); ftp.c: if (cout == NULL || setjmp(forceabort)) { main.c:jmp_buf toplevel; main.c: if (setjmp(toplevel)) main.c: top = setjmp(toplevel) == 0; main.c: longjmp(toplevel, 1); small.c:jmp_buf jabort; small.c: longjmp(jabort, 1); small.c: longjmp(jabort, 1); small.c: (void)setjmp(jabort); Or look at this in small.c: /* XXX - Signal race. */ /* ARGSUSED */ void mabort(int signo) { int save_errno = errno; alarmtimer(0); (void) write(fileno(ttyout), "\n\r", 2); #ifndef SMALL if (mflag && fromatty) { /* XXX signal race, crazy unbelievable stdio misuse */ if (confirm(mname, NULL)) { errno = save_errno; longjmp(jabort, 1); } } #endif /* !SMALL */ mflag = 0; errno = save_errno; longjmp(jabort, 1); } Then look at util.c what confirm() is. The word "unbelievable" is an accurate description of the situation. Or look at intr() in main.c. On top of calling longjmp(3), that signal handler also calls alarmtimer() in util.c, which happily does multiple non-atomic stores into a struct, then calls the function setitimer(2) which is not async-signal-safe either. Or the updateprogressmeter() signal handler in util.c. That one calls progressmeter() in the same file, which is just as bad as confirm(). We have a policy to mark broken code with /* XXX */ in the tree when it is found and whoever discovers the breakage has no time to fix it right away. But ftp(1) is so bad that i feel like i don't even have the time to mark stuff as broken. No matter where i look, almost all of it is broken. I'm usually a great fan of fixing broken code by step-by-step refactoring, even if it is broken in quite serious ways. But that is totally out of the question for OpenBSD ftp(1). That code is so thoroughly ill-designed throughout that starting over from scratch is the only viable option. > So, want me to finish working on this? It sounds like a waste of time to me. > - And if so, once it's ready, want me to offer it back to you? I have no idea what that is supposed to mean. Yours, Ingo