diff -cB -x '*.o' -x Makefile -x 'config*' -x wget wget-1.11/src/url.c wget_dev/src/url.c
*** wget-1.11/src/url.c	Sat Jan 26 01:26:58 2008
--- wget_dev/src/url.c	Thu Feb  5 19:53:52 2009
***************
*** 1288,1293 ****
--- 1288,1294 ----
     query, normally '?'.  Since Windows cannot handle '?' as part of
     file name, we use '@' instead there.  */
  #define FN_QUERY_SEP (opt.restrict_files_os != restrict_windows ? '?' : '@')
+ #define FN_QUERY_SEP_STR (opt.restrict_files_os != restrict_windows ? "?" : "@")
  
  /* Quote path element, characters in [b, e), as file name, and append
     the quoted string to DEST.  Each character is quoted as per
***************
*** 1421,1441 ****
      }
  }
  
! /* Return a unique file name that matches the given URL as good as
     possible.  Does not create directories on the file system.  */
  
  char *
  url_file_name (const struct url *u)
  {
    struct growable fnres;        /* stands for "file name result" */
! 
    const char *u_file, *u_query;
!   char *fname, *unique;
  
    fnres.base = NULL;
    fnres.size = 0;
    fnres.tail = 0;
  
    /* Start with the directory prefix, if specified. */
    if (opt.dir_prefix)
      append_string (opt.dir_prefix, &fnres);
--- 1422,1449 ----
      }
  }
  
! /* Return a unique file name that matches the given URL as well as
     possible.  Does not create directories on the file system.  */
  
  char *
  url_file_name (const struct url *u)
  {
    struct growable fnres;        /* stands for "file name result" */
!   struct growable temp_fnres;
!   
    const char *u_file, *u_query;
!   char *fname, *unique, *fname_len_check;
!   
!   int len = 0, shortened = 0;
  
    fnres.base = NULL;
    fnres.size = 0;
    fnres.tail = 0;
  
+   temp_fnres.base = NULL;
+   temp_fnres.size = 0;
+   temp_fnres.tail = 0;
+   
    /* Start with the directory prefix, if specified. */
    if (opt.dir_prefix)
      append_string (opt.dir_prefix, &fnres);
***************
*** 1445,1450 ****
--- 1453,1459 ----
       directory structure.  */
    if (opt.dirstruct)
      {
+ 	  printf("in 'if (opt.dirstruct)' of url_file_name()...\n");
        if (opt.protocol_directories)
          {
            if (fnres.tail)
***************
*** 1474,1498 ****
        append_dir_structure (u, &fnres);
      }
  
    /* Add the file name. */
    if (fnres.tail)
      append_char ('/', &fnres);
-   u_file = *u->file ? u->file : "index.html";
-   append_uri_pathel (u_file, u_file + strlen (u_file), false, &fnres);
- 
-   /* Append "?query" to the file name. */
-   u_query = u->query && *u->query ? u->query : NULL;
-   if (u_query)
-     {
-       append_char (FN_QUERY_SEP, &fnres);
-       append_uri_pathel (u_query, u_query + strlen (u_query), true, &fnres);
-     }
  
    /* Zero-terminate the file name. */
    append_char ('\0', &fnres);
! 
    fname = fnres.base;
  
    /* Check the cases in which the unique extensions are not used:
       1) Clobbering is turned off (-nc).
       2) Retrieval with regetting.
--- 1483,1544 ----
        append_dir_structure (u, &fnres);
      }
  
+   /* I think this is a good place to make sure the path isn't already too
+    * long.  I have no idea how to deal with it if it is though.  So not
+    * checking. */
+ 
+   /* Create the filename. */
+   u_file = *u->file ? u->file : INDEX_HTML;
+   
+   /* Append "?query" to the file name and create fname_len_check. */
+   if( u->query && *u->query ) {
+ 	  u_query = u->query;
+ 	  fname_len_check = concat_strings(u_file, FN_QUERY_SEP_STR, u_query, NULL);
+   }
+   else {
+ 	  fname_len_check = strdupdelim( u_file, u_file + strlen(u_file));
+   }
+   
    /* Add the file name. */
    if (fnres.tail)
      append_char ('/', &fnres);
  
+   append_uri_pathel (fname_len_check, 
+   		  fname_len_check + strlen (fname_len_check), false, &temp_fnres);
+   
+   /* Check that the length of the file name is acceptable. */
+   free(fname_len_check);
+   fname_len_check = temp_fnres.base;
+   if( strlen(fname_len_check) > (get_name_max()-CHOMP_BUFFER) ) {
+ 	  len = strlen(fname_len_check);	  
+ 	  logprintf (LOG_NOTQUIET, "The name is too long, %d chars total.\n", len);
+ 	  logprintf (LOG_NOTQUIET, "Trying to shorten...\n");
+ 
+ 	  /* Shorten the file name. */
+ 	  fname_len_check[get_name_max()-CHOMP_BUFFER] = '\0';
+ 	  shortened = 1;
+ 	  
+ 	  logprintf (LOG_NOTQUIET, "New name is %s.\n", fname_len_check);
+   }
+ 
+   /* The filename has already been 'cleaned' by append_uri_pathel() above.  So,
+    * just append it. */
+   append_string( fname_len_check, &fnres );
+   
    /* Zero-terminate the file name. */
    append_char ('\0', &fnres);
!   
    fname = fnres.base;
+   
+   /* Make a final check that the path length is acceptable? */
  
+   /* Clean up the length-checking string. */
+     if( shortened ) {
+   	  len = get_name_max()-CHOMP_BUFFER;
+   	  fname_len_check[len] = 'x';
+     }
+     free(fname_len_check);
+   
    /* Check the cases in which the unique extensions are not used:
       1) Clobbering is turned off (-nc).
       2) Retrieval with regetting.
diff -cB -x '*.o' -x Makefile -x 'config*' -x wget wget-1.11/src/url.h wget_dev/src/url.h
*** wget-1.11/src/url.h	Sat Jan 26 01:26:58 2008
--- wget_dev/src/url.h	Thu Feb  5 16:44:34 2009
***************
*** 36,41 ****
--- 36,55 ----
  #define DEFAULT_FTP_PORT 21
  #define DEFAULT_HTTPS_PORT 443
  
+ #define INDEX_HTML "index.html"
+ 
+ /* This represents how many characters less than the OS max name length a file
+  * should be.  More precisely, a file name should be at most 
+  * (NAME_MAX - CHOMP_BUFFER) characters in length.  This number was arrived at
+  * by adding the lengths of all possible strings that could be appended to a 
+  * file name later in the code (e.g. '.orig', '.html', etc.).  This is 
+  * hopefully plenty of extra characters, but I am not guaranteeing that a file
+  * name will be of the proper length by the time the code wants to open a 
+  * file descriptor. */
+ #define CHOMP_BUFFER 19
+ 
+ #define CHOMP_FACTOR 3
+ 
  /* Specifies how, or whether, user auth information should be included
   * in URLs regenerated from URL parse structures. */
  enum url_auth_mode {
diff -cB -x '*.o' -x Makefile -x 'config*' -x wget wget-1.11/src/utils.c wget_dev/src/utils.c
*** wget-1.11/src/utils.c	Sat Jan 26 01:26:58 2008
--- wget_dev/src/utils.c	Thu Feb  5 19:54:49 2009
***************
*** 2130,2135 ****
--- 2130,2177 ----
    return buf;
  }
  
+ /* Get the maximum name length for the root file system. */
+ long
+ get_name_max()
+ {
+ 	static int already_defined = 0;
+ 	static long name_max;
+ 	long ret;
+ 	if( !already_defined ) {
+ 		errno = 0;
+ 		if ((ret = pathconf("/", _PC_NAME_MAX)) == -1){		
+ 			if (errno != 0)
+ 				perror("pathconf");
+ 		}
+ 		else {
+ 			name_max = ret;
+ 		}
+ 		already_defined = 1;
+ 	}
+ 	return name_max;
+ }
+ 
+ /* Get the maximum path length for the root file system. */
+ long
+ get_path_max()
+ {
+ 	static int already_defined = 0;
+ 	static long path_max;
+ 	long ret;
+ 	if( !already_defined ) {	
+ 		errno = 0;
+ 		if ((ret = pathconf("/", _PC_PATH_MAX)) == -1){		
+ 			if (errno != 0)
+ 				perror("pathconf");
+ 		}
+ 		else {
+ 			path_max = ret;
+ 		}
+ 		already_defined = 1;
+ 	}
+ 	return path_max;
+ }
+ 
  #ifdef TESTING
  
  const char *
diff -cB -x '*.o' -x Makefile -x 'config*' -x wget wget-1.11/src/utils.h wget_dev/src/utils.h
*** wget-1.11/src/utils.h	Sat Jan 26 01:26:58 2008
--- wget_dev/src/utils.h	Thu Feb  5 18:22:27 2009
***************
*** 126,129 ****
--- 126,131 ----
  
  const char *print_decimal (double);
  
+ long get_name_max();
+ long get_path_max();
  #endif /* UTILS_H */
