Date: Tue, 24 Nov 2009 10:50:16 -0800 From: Jeremy Chadwick <freebsd@jdc.parodius.com> To: freebsd-stable@freebsd.org Subject: Re: 8.0-RC USB/FS problem Message-ID: <20091124185016.GA3433@icarus.home.lan> In-Reply-To: <20091124181654.GI89004@dan.emsphone.com> References: <CB2DD11991B27C4F99935E6229450D3203950A1C@STORK.scenix.com> <200911240933.19329.hselasky@c2i.net> <CB2DD11991B27C4F99935E6229450D3203950A2A@STORK.scenix.com> <200911241813.23616.hselasky@c2i.net> <20091124174714.GA2240@icarus.home.lan> <20091124181654.GI89004@dan.emsphone.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Nov 24, 2009 at 12:16:54PM -0600, Dan Nelson wrote: > In the last episode (Nov 24), Jeremy Chadwick said: > > On Tue, Nov 24, 2009 at 06:13:21PM +0100, Hans Petter Selasky wrote: > > > On Tuesday 24 November 2009 17:58:47 Guojun Jin wrote: > > > > Sorry for the typo -- it is public not pub in the middle. The others should > > > > be all public. > > > > > > > > http:/www.daemonfun.com/archives/public/USB/crash1-reset.bz2 > > > > > > > > > > %fetch http:/www.daemonfun.com/archives/public/USB/crash1-reset.bz2 > > > fetch: http:/www.daemonfun.com/archives/public/USB/crash1-reset.bz2: No address record > > > > The above issue is unrelated to the USB/FS problem. It looks like > > fetch(1) has a parser bug. Note the text portion between the URI and URL > > is colon-slash not colon-slash-slash like it should be. > > That's a typo in the URL, not a bug in fetch :) It's a bug in libfetch, specifically the fetchParseURL(3) function. Relevant code from src/usr.bin/fetch/fetch.c: 312 static int 313 fetch(char *URL, const char *path) 314 { 315 struct url *url; ... 342 /* parse URL */ 343 if ((url = fetchParseURL(URL)) == NULL) { 344 warnx("%s: parse error", URL); 345 goto failure; 346 } The man page for fetchParseURL(3) claims: fetchParseURL() takes a URL in the form of a null-terminated string and splits it into its components function according to the Common Internet Scheme Syntax detailed in RFC1738. A regular expression which produces this syntax is: <scheme>:(//(<user>(:<pwd>)?@)?<host>(:<port>)?)?/(<document>)? If the URL does not seem to begin with a scheme name, the following syn- tax is assumed: ((<user>(:<pwd>)?@)?<host>(:<port>)?)?/(<document>)? ..... fetchParseURL() returns a pointer to a struct url containing the individ- ual components of the URL. If it is unable to allocate memory, or the URL is syntactically incorrect, fetchParseURL() returns a NULL pointer. If we add some debugging code *before* the "scheme assumption" portion of fetch.c (which actually looks at the hostname portion and if it starts with "ftp" assumes the scheme is FTP, "http" = HTTP, etc.): 348 printf("fetchParseURL() successful. struct details:\n"); 349 printf("url->scheme = %s\n", url->scheme); 350 printf("url->user = %s\n", url->user); 351 printf("url->pwd = %s\n", url->pwd); 352 printf("url->host = %s\n", url->host); 353 printf("url->port = %d\n", url->port); 354 printf("url->doc = %s\n", url->doc); ...we end up with this: $ ./fetch http:/www.daemonfun.com/ fetchParseURL() successful. struct details: url->scheme = http url->user = url->pwd = url->host = url->port = 0 url->doc = /www.daemonfun.com/ fetch: http:/www.daemonfun.com/: No address record Here we can see the libfetch code properly works out the scheme (URI) on its own (which means the "assumption part" of the man page should not play a role here) -- but incorrectly parses the remaining portion of the URL. In this situation, fetchParseURL(3) should return NULL. The code in fetch.c continues on to call fetchXGet(3) with the above struct data (some of it gets modified, but that's besides the point), and the result is fetchXGet(3) returning NULL (indicating the fetch failed in some way), which gets us here: 463 f = fetchXGet(url, &us, flags); ... 468 if (f == NULL) { 469 warnx("%s: %s", URL, fetchLastErrString); 470 if (i_flag && strcmp(url->scheme, SCHEME_HTTP) == 0 471 && fetchLastErrCode == FETCH_OK 472 && strcmp(fetchLastErrString, "Not Modified") == 0) { 473 /* HTTP Not Modified Response, return OK. */ 474 r = 0; 475 goto done; 476 } else 477 goto failure; 478 } We modify some code to add some debugging to validate that warnx() is what's returning the error message: 469 warnx("fetchXGet() returned NULL: %s: %s", URL, fetchLastErrString); ...and we end up with: fetch: fetchXGet() returned NULL: http:/www.daemonfun.com/: No address record I guess I'll be the one to file the PR. -- | Jeremy Chadwick jdc@parodius.com | | Parodius Networking http://www.parodius.com/ | | UNIX Systems Administrator Mountain View, CA, USA | | Making life hard for others since 1977. PGP: 4BD6C0CB |
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20091124185016.GA3433>