--- utils.c.old	2009-06-26 07:57:01.077636110 +0100
+++ utils.c	2009-06-26 07:57:52.965066602 +0100
@@ -380,6 +380,7 @@
   return err;
 }
 
+
 /* Does FILENAME exist?  This is quite a lousy implementation, since
    it supplies no error codes -- only a yes-or-no answer.  Thus it
    will return that a file does not exist if, e.g., the directory is
@@ -387,14 +388,33 @@
    proper way should, of course, be to have a third, error state,
    other than true/false, but that would introduce uncalled-for
    additional complexity to the callers.  */
+/* The previous implementation is insufficient for dealing with 
+   ENOTDIR error scenarios, i.e. if path/to/file is specified and
+   path/to is a file.
+
+   This may occur when a web server serves content /at/this/uri
+   and /at/this/uri/too
+   
+   If downloaded in that order, all content under /at/this/uri/...
+   would've failed to download. We check for ENOTDIR and report the
+   file exists as a workaround. unique_dir is later invoked. */
 bool
 file_exists_p (const char *filename)
 {
-#ifdef HAVE_ACCESS
-  return access (filename, F_OK) >= 0;
+  errno = 0;
+#ifdef HAVE_ACCESS  
+  int err = access (filename, F_OK);
+  if (errno != ENOTDIR) {
+    return err >= 0;
+  }
+  return true;
 #else
   struct_stat buf;
-  return stat (filename, &buf) >= 0;
+  int err = stat (filename, &buf);
+  if (errno != ENOTDIR) {
+    return err >= 0;
+  }
+  return true;
 #endif
 }
 
@@ -437,6 +457,53 @@
 #endif
 }
 
+/* a modified version of unique_name_1 to check for errors
+   down the path. will recurse up the path given until
+   ENOTDIR no longer occurs. will then add .n to that part of
+   the path and return it.
+*/
+static char * unique_dir (const char *path)
+{
+  int pathLength = strlen(path);
+  char * new = (char *) alloca(pathLength + 1 + 24); /* + '.' + a limited space for digits. */
+  /* nul fill the end of the temp string */
+  memset(new,'\0',pathLength+1+24);
+  memcpy(new, path, pathLength);
+  char * lastSlash;
+  int lastLength = 0;
+  do {
+    errno = 0; 
+    lastSlash = strrchr(new,'/');
+    *lastSlash = '\0';
+    lastLength = strlen(new);
+  } 
+  while (file_exists_p(new) && errno == ENOTDIR);
+  /* We've found the bit of the path that is causing ENOTDIR after
+     we're out of the loop above */
+  // Should use concat_strings for safety - can't get it to work though...
+  strcat(new, ".");
+  
+  /* loop in case another file happens to be in our way in the unique dir */
+  int count = 1;
+  do {
+    number_to_string(lastSlash+1,count++);
+  } while (file_exists_p(new) && file_non_directory_p(new));
+
+
+  /* copy the rest of the new string from original path */
+  strcat(new,&path[lastLength]);
+  /* do a final test to make sure our path is sound, in case we've descended
+     into a pre-existing directory.N/ and we run into ENOTDIR again */
+
+  errno = 0;
+  access(new, F_OK);
+  if (file_exists_p(new) && errno == ENOTDIR) {
+    return unique_dir(strdup(new));
+  }
+  return xstrdup(new);
+}
+
+
 /* stat file names named PREFIX.1, PREFIX.2, etc., until one that
    doesn't exist is found.  Return a freshly allocated copy of the
    unused file name.  */
@@ -448,14 +515,32 @@
   int plen = strlen (prefix);
   char *template = (char *)alloca (plen + 1 + 24);
   char *template_tail = template + plen;
+  char * new;
 
   memcpy (template, prefix, plen);
   *template_tail++ = '.';
+   /* This could be applied after we check ENOTDIR and make the
+     directory unique, we dont need to add it to the file
+     if we are already in a unique tree. */
+  number_to_string (template_tail, count++);
+  do {
+    int err = access(template, F_OK);
+    if (errno == ENOTDIR && err == -1) {
+      new = unique_dir(template);
+      plen = strlen(new);
+      /* restore the allocation for another round. */
+      template = (char *)alloca (plen + 1 + 24);
+      template_tail = template + plen;
+      /* get the nul in there as well (plen+1) */
+      memcpy (template, new, plen+1);
+    }
+  else {  
+      number_to_string (template_tail, count++);
+    }
+  }
+  while (file_exists_p (template) == -1);
 
-  do
-    number_to_string (template_tail, count++);
-  while (file_exists_p (template));
-
+  logprintf (LOG_VERBOSE, "Your corrected pathname is: %s\n", template);
   return xstrdup (template);
 }
