httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jeff Trawick <trawi...@bellsouth.net>
Subject [PATCH] move getpwnam hackery to APR
Date Sun, 12 Nov 2000 14:05:19 GMT
The following patch adds Unix support for apr_get_home_directory() to
APR.  

Bill Rowe will handle for Win32, at which point mod_userdir and
mod_rewrite will pick up the corresponding function on Win32.

In a nutshell: 
. if APR_HAS_HOME_DIR is non-zero, apr_get_home_directory() is
  provided 
. it is expected that all current APR platforms have it once Bill Rowe
  implements for NT and the Unix implementation is copied to OS/2 (but
  see OS/2 comment below)

To do:

. Is the interface appropriate for all known platforms?
. Can an OS/2 APR implementation handle the manual inclusion of the
  userid in the string?
. Add a Win32 implementation
. Is it APR_ENOTIMPL on Win9x?
. Update mod_rewrite to use this too.
. test this with mod_userdir :)

A separate issue still (to be moved to APR with this patch) is what to
do about _POSIX_THREAD_SAFE_FUNCTION/getpwnam[_r], but at least that
is out of user-level code.


Index: lib/apr/configure.in
===================================================================
RCS file: /home/cvspublic/apache-2.0/src/lib/apr/configure.in,v
retrieving revision 1.170
diff -u -r1.170 configure.in
--- lib/apr/configure.in	2000/11/11 06:05:58	1.170
+++ lib/apr/configure.in	2000/11/12 13:52:05
@@ -265,6 +265,7 @@
 AC_CHECK_HEADERS(netdb.h)
 AC_CHECK_HEADERS(osreldate.h)
 AC_CHECK_HEADERS(process.h)
+AC_CHECK_HEADERS(pwd.h)
 AC_CHECK_HEADERS(sys/sem.h)
 AC_CHECK_HEADERS(signal.h, signalh="1", signalh="0")
 AC_CHECK_HEADERS(stdarg.h, stdargh="1", stdargh="0")
Index: lib/apr/file_io/unix/dir.c
===================================================================
RCS file: /home/cvspublic/apache-2.0/src/lib/apr/file_io/unix/dir.c,v
retrieving revision 1.39
diff -u -r1.39 dir.c
--- lib/apr/file_io/unix/dir.c	2000/11/09 06:15:53	1.39
+++ lib/apr/file_io/unix/dir.c	2000/11/12 13:52:05
@@ -55,6 +55,12 @@
 #include "unix/fileio.h"
 #include "apr_strings.h"
 #include "apr_portable.h"
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
 
 static apr_status_t dir_cleanup(void *thedir)
 {
@@ -271,4 +277,29 @@
     return APR_SUCCESS;
 }
 
+apr_status_t apr_get_home_directory(char *buf, apr_size_t bufsize, const char *userid)
+{
+    struct passwd *pw;
+#if APR_HAS_THREADS && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+    struct passwd pwd;
+    char pwbuf[512];
+#endif
+
+#if APR_HAS_THREADS && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+    if (!getpwnam_r(userid, &pwd, pwbuf, sizeof(pwbuf), &pw)) {
+#else
+    if ((pw = getpwnam(userid)) != NULL) {
+#endif
+        if (strlen(pw->pw_dir) < bufsize) {
+            strcpy(buf, pw->pw_dir);
+        }
+        else {
+            return APR_EINVAL;
+        }
+    }
+    else {
+        return errno;
+    }
+    return APR_SUCCESS;
+}
   
Index: lib/apr/include/apr.h.in
===================================================================
RCS file: /home/cvspublic/apache-2.0/src/lib/apr/include/apr.h.in,v
retrieving revision 1.50
diff -u -r1.50 apr.h.in
--- lib/apr/include/apr.h.in	2000/11/11 06:05:59	1.50
+++ lib/apr/include/apr.h.in	2000/11/12 13:52:06
@@ -96,6 +96,7 @@
 #define APR_HAS_OTHER_CHILD       @oc@
 #define APR_HAS_DSO               @aprdso@
 #define APR_HAS_UNICODE_FS        0
+#define APR_HAS_HOME_DIR          1
 
 /* This macro tells APR that it is safe to make a file masquerade as a 
  * socket.  This is necessary, because some platforms support poll'ing
Index: lib/apr/include/apr_file_io.h
===================================================================
RCS file: /home/cvspublic/apache-2.0/src/lib/apr/include/apr_file_io.h,v
retrieving revision 1.73
diff -u -r1.73 apr_file_io.h
--- lib/apr/include/apr_file_io.h	2000/11/10 15:19:53	1.73
+++ lib/apr/include/apr_file_io.h	2000/11/12 13:52:07
@@ -682,6 +682,18 @@
 APR_DECLARE(int) apr_fprintf(apr_file_t *fptr, const char *format, ...)
         __attribute__((format(printf,2,3)));
 
+/***
+ * Get the home directory for a specified userid.
+ * @param buf Storage to be filled in with the user id
+ * @param bufsize Size of user id buffer
+ * @param userid The userid
+ * @deffunc apr_status_t apr_get_home_directory(const char *userid, char *buf, apr_size_t
bufsize)
+ * @tip If the buffer is not large enough to contain the home directory
+ * and a terminating '\0', APR_EINVAL will be returned.
+ * @tip This function is available only if APR_HAS_HOME_DIR is defined.
+ */
+apr_status_t apr_get_home_directory(char *buf, apr_size_t bufsize, const char *userid);
+
 #ifdef __cplusplus
 }
 #endif
Index: modules/standard/mod_userdir.c
===================================================================
RCS file: /home/cvspublic/apache-2.0/src/modules/standard/mod_userdir.c,v
retrieving revision 1.26
diff -u -r1.26 mod_userdir.c
--- modules/standard/mod_userdir.c	2000/11/10 23:52:18	1.26
+++ modules/standard/mod_userdir.c	2000/11/12 13:52:13
@@ -103,9 +103,6 @@
 #ifdef HAVE_UNIX_SUEXEC
 #include "unixd.h"        /* Contains the suexec_identity hook used on Unix */
 #endif
-#ifdef HAVE_PWD_H
-#include <pwd.h>
-#endif
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
@@ -320,29 +317,23 @@
             return HTTP_MOVED_TEMPORARILY;
         }
         else {
-#ifdef WIN32
-            /* Need to figure out home dirs on NT */
-            return DECLINED;
-#else                           /* WIN32 */
-            struct passwd *pw;
-
-#if APR_HAS_THREADS && defined(HAVE_GETPWNAM_R)
-            struct passwd pwd;
-            size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
-            char *buf = apr_pcalloc(r->pool, buflen);
+#if APR_HAS_HOME_DIR
+            char homedir[512];
 
-            if (!getpwnam_r(w, &pwd, buf, buflen, &pw)) {
-#else
-            if ((pw = getpwnam(w))) {
-#endif
-#ifdef OS2
+            if (apr_get_home_directory(homedir, sizeof(homedir), w) == APR_SUCCESS) {
+#ifdef OS2      /* XXX should this OS/2 logic move to APR? */
                 /* Need to manually add user name for OS/2 */
-                filename = apr_pstrcat(r->pool, pw->pw_dir, w, "/", userdir, NULL);
+                filename = apr_pstrcat(r->pool, homedir, w, "/", userdir, NULL);
 #else
-                filename = apr_pstrcat(r->pool, pw->pw_dir, "/", userdir, NULL);
+                filename = apr_pstrcat(r->pool, homedir, "/", userdir, NULL);
 #endif
             }
-#endif                          /* WIN32 */
+            else {
+                /* XXX old code ignored this error... */
+            }
+#else
+            return DECLINED;
+#endif
         }
 
         /*


-- 
Jeff Trawick | trawick@ibm.net | PGP public key at web site:
     http://www.geocities.com/SiliconValley/Park/9289/
          Born in Roswell... married an alien...

Mime
View raw message