> > One important thing is missing from this discussion: what exactly is > > wrong with ftp(1)? > > The code is....to put it nicely....rather dated ;-)
First off, let's show the result of a grep. cmds.c: (void)setjmp(jabort); cmds.c: (void)setjmp(jabort); cmds.c: (void)setjmp(jabort); cmds.c: if (setjmp(abortprox)) { fetch.c: if (setjmp(httpabort)) { fetch.c: if (setjmp(httpabort)) { fetch.c: if (setjmp(toplevel)) { ftp.c: if (setjmp(sendabort)) { ftp.c: if (setjmp(sendabort)) ftp.c: if (setjmp(recvabort)) { ftp.c: if (setjmp(recvabort)) ftp.c: if (setjmp(ptabort)) ftp.c: if (cout == NULL || setjmp(forceabort)) { ftp_var.h:#include <setjmp.h> main.c: if (setjmp(toplevel)) main.c: top = setjmp(toplevel) == 0; small.c: (void)setjmp(jabort); I believe it is one of the last programs in the tree using such a fragile interface. Yes, setjmp can be used safely. All those global variables could be used right, too....