From: "H. Hartzer" Subject: Re: [PATCH] Make incorrect ftp(1) usage more obvious To: "Theo de Raadt" Cc: Date: Sun, 04 May 2025 03:14:52 +0000 > Theo de Raadt wrote: >> >> I disagree strongly. >> >> We follow original POSIX getopt(3) rules in every program, using libc code. >> >> This applies to ALL commands. No commands are different. >> >> It means all options must be before non-option arguments. >> >> Placing options after non-options is going to break on any non-GLIBC/MUSL >> system, and you are going to need to get used to that being the wrong >> thing to do and put your arguments in the standards-mandated order. > > Let me put it this way. > > % ls /bin -FC > ls: -FC: No such file or directory > /bin: > [* cp* domainname* kill* mt* rm* sleep* > cat* cpio* echo* ksh* mv* rmdir* stty* > chgrp* csh* ed* ln* pax* sh* sync* > chio* date* eject* ls* ps* sha1* tar* > chmod* dd* expr* md5* pwd* sha256* test* > cksum* df* hostname* mkdir* rksh* sha512* > > > You want to add such a change to every command? Adding it just one, for your > finger memory convience, is not reasonable. Hi Theo, I appreciate you taking the time to respond to this. I'm glad that this thread at least seemed to lead to the discovery of an option parsing bug in grep. I personally like when programs are explicit about being used incorrectly. I know that I need to learn how to use them properly, of course. I also think that ls behaves very reasonably. However, in your example, ls does print an error helping inform the user that they made a mistake. ftp doesn't do that. While I personally prefer my original patch, does this patch seem better to you? Thank you, Henrich diff --git a/usr.bin/ftp/fetch.c b/usr.bin/ftp/fetch.c index 799cd7124af..94866c273ec 100644 --- a/usr.bin/ftp/fetch.c +++ b/usr.bin/ftp/fetch.c @@ -1276,6 +1276,7 @@ auto_fetch(int argc, char *argv[], char *outfile) username = pass = NULL; for (rval = 0; (rval == 0) && (argpos < argc); free(url), argpos++) { if (strchr(argv[argpos], ':') == NULL) + fprintf(ttyout, "%s isn't a valid URL.\n", argv[argpos]); break; free(username);