httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jim Jagielski <...@jaguNET.com>
Subject translate_userdir()
Date Mon, 18 Mar 1996 13:57:49 GMT
I'm not going to start a commit battle by reversing a commit that
I think is in error with justifying my position as clearly as
possible. Instead I will offer the below.

First of all, I think Alexei's improvements are worthwhile, however
I believe that his code as is stands may be in error and can cause
erroneous error logs and even Seg-Faults, due to NULL referencing.

As such, I'm including below my take on how the translate_userdir()
code should look. My comments are wordy not because that's how I want
them to be in the final code, but rather to hopefully explain why I
think the changes make sense... By putting the thought behind the code
_in_ the code, everyone can tag along and play :)

=============================
int translate_userdir (request_rec *r)
{
    void *server_conf = r->server->module_config;
    char *userdirs = (char *)get_module_config(server_conf, &userdir_module);
    char *name = r->uri;
    char *w, *dname, *redirect;
    char *x = NULL;

    if (userdirs == NULL || !strcasecmp(userdirs, "disabled") ||
        (name[0] != '/') || (name[1] != '~')) {
      return DECLINED;
    }

    while (*userdirs) {
      char *userdir = getword_conf (r->pool, &userdirs);
      char *filename = NULL;

      dname = name + 2;
      w = getword(r->pool, &dname, '/');

      if (!strcmp(w, ""))
	return DECLINED;

      /* The 'dname' funny business involves backing it up to capture
       * the '/' delimiting the "/~user" part from the rest of the URL,
       * in case there was one (the case where there wasn't being just
       * "GET /~user HTTP/1.0", for which we don't want to tack on a
       * '/' onto the filename).
       */
	
      if (dname[-1] == '/') --dname;

      if (strchr(userdir, '*'))
	x = getword(r->pool, &userdir, '*');

      if (userdir[0] == '/') {
	if (x) {
	  if (strchr(x, ':')) {
	    redirect = pstrcat(r->pool, x, w, userdir, dname, NULL);
	    table_set (r->headers_out, "Location", redirect);
	    return REDIRECT;
	  }
	  else
	    filename = pstrcat (r->pool, x, w, userdir, NULL);
	}
	else
	  filename = pstrcat (r->pool, userdir, "/", w, NULL);
      }
      else if (strchr(userdir, ':')) {
	redirect = pstrcat(r->pool, userdir, "/", w, dname, NULL);
	table_set (r->headers_out, "Location", redirect);
	return REDIRECT;
      }
      else {
	/*
	 * we are looking for a user...
	 */
	struct passwd *pw;
	if(pw=getpwnam(w)) {
	  /*
	   * we found him or her
	   */
#ifdef __EMX__
	  /* Need to manually add user name for OS/2 */
	  filename = pstrcat (r->pool, pw->pw_dir, w, "/", userdir, NULL);
#else
	  filename = pstrcat (r->pool, pw->pw_dir, "/", userdir, NULL);
#endif
	}
	else {
	  /*
	   * Ok. Let's get this straight. At this point we know
	   * that the getpwnam() call failed. Why? Because the user
	   * doesn't exist. This must mean that no matter what, we'll
	   * never find the right filename. We should return NOT_FOUND.
	   * We don't wait until we stat() because filename at this
	   * point is NULL.
	   */
	  return NOT_FOUND;
	}
      }

      /*
       * Now see if it exists: at this point we are
       * comfortably sure that filename isn't NULL since
       * one of the above has created it or else we shouldn't
       * have gotten this far.
       */
      if (stat(filename, &r->finfo) != -1) {
	r->filename = pstrcat(r->pool, filename, dname, NULL);
	return OK;
      }
      /*
       * At last entry? What does this mean? It means
       * that we've exhausted the list in UserDir. It
       * also means that, as seen from the above, that
       * the stat() of filename failed, or else we
       * wouldn't be here... No more possible choices
       * or permutations and the filename we think
       * we want, we can't stat(). Doesn't this sound
       * like a file-not-found condition? Shouldn't
       * we return that?
       */
      if (!*userdirs) 
	return NOT_FOUND;
    }

  return DECLINED;    
}
=============================
-- 
Jim Jagielski  << jim@jaguNET.com >>   |      "That's a Smith & Wesson,
  **  jaguNET Access Services  **      |       and you've had your six" 
      Email: info@jaguNET.com          |             - James Bond
++    http://www.jaguNET.com/         +++      Voice/Fax: 410-931-7060       ++

Mime
View raw message