Re: [PATCH] APR turn off readonly/executable, add apr_file_attrs_get

2002-02-03 Thread Kevin Pilch-Bisson
On Sat, Feb 02, 2002 at 08:34:44PM +, Philip Martin wrote:
 +#ifdef APR_HAS_THREADS
 +status = apr_thread_mutex_lock(umask_mutex);
 +if (!APR_STATUS_IS_SUCCESS(status))
 +return status;
 +#endif

Shouldn't this be 
#if APR_HAS_THREADS

i.e. isn't it always defined to either 0 or 1.

And the rest below...

-- 
~
Kevin Pilch-Bissonhttp://www.pilch-bisson.net
 Historically speaking, the presences of wheels in Unix
 has never precluded their reinvention. - Larry Wall
~


pgpP6EZxQ9XTw.pgp
Description: PGP signature


Re: [PATCH] APR turn off readonly/executable, add apr_file_attrs_get

2002-02-03 Thread Cliff Woolley
On Sat, 2 Feb 2002, Kevin Pilch-Bisson wrote:

 On Sat, Feb 02, 2002 at 08:34:44PM +, Philip Martin wrote:
  +#ifdef APR_HAS_THREADS
  +status = apr_thread_mutex_lock(umask_mutex);
  +if (!APR_STATUS_IS_SUCCESS(status))
  +return status;
  +#endif

 Shouldn't this be
 #if APR_HAS_THREADS

 i.e. isn't it always defined to either 0 or 1.


Yes, it should be.

--Cliff

--
   Cliff Woolley
   [EMAIL PROTECTED]
   Charlottesville, VA




Re: [PATCH] APR turn off readonly/executable, add apr_file_attrs_get

2002-02-03 Thread Philip Martin
Cliff Woolley [EMAIL PROTECTED] writes:

 On Sat, 2 Feb 2002, Kevin Pilch-Bisson wrote:
 
  On Sat, Feb 02, 2002 at 08:34:44PM +, Philip Martin wrote:
   +#ifdef APR_HAS_THREADS
   +status = apr_thread_mutex_lock(umask_mutex);
   +if (!APR_STATUS_IS_SUCCESS(status))
   +return status;
   +#endif
 
  Shouldn't this be
  #if APR_HAS_THREADS
 
  i.e. isn't it always defined to either 0 or 1.
 
 
 Yes, it should be.

OK. I can make the mutex creation conditional as well.

-- 
Philip


[PATCH] APR turn off readonly/executable, add apr_file_attrs_get

2002-02-02 Thread Philip Martin
Greg Stein [EMAIL PROTECTED] writes:

 (btw, for completeness, we'd also want ways to turn off readonly and to the
 executable state)

Here's a patch that does that, and provides a way to query the
attributes. It also makes the permission setting by apr_file_attrs_set
respect the umask of the process. So when removing readonly, the world
write flag, for example, only gets set if the umask allows.


Index: file_io/unix/filestat.c
===
RCS file: /home/cvspublic/apr/file_io/unix/filestat.c,v
retrieving revision 1.49
diff -u -r1.49 filestat.c
--- file_io/unix/filestat.c 1 Feb 2002 01:40:38 -   1.49
+++ file_io/unix/filestat.c 2 Feb 2002 20:32:36 -
@@ -109,6 +109,42 @@
  */
 }
 
+/* This function is necessary because the APR mutex interface doesn't
+ * provide static mutex initialisation, i.e. there is nothing equivalent
+ * to PTHREAD_MUTEX_INITIALIZER. It's difficult to see how it could, given
+ * the need for a pool.
+ */
+static apr_thread_mutex_t *umask_mutex;
+apr_status_t apr_unix_setup_umask(apr_pool_t *cont)
+{
+   return apr_thread_mutex_create(umask_mutex, APR_THREAD_MUTEX_DEFAULT, 
cont);
+}
+
+static apr_status_t get_umask(apr_fileperms_t *umask_perms, apr_pool_t *cont)
+{
+apr_status_t status;
+mode_t umask_raw;
+
+#ifdef APR_HAS_THREADS
+status = apr_thread_mutex_lock(umask_mutex);
+if (!APR_STATUS_IS_SUCCESS(status))
+return status;
+#endif
+
+umask_raw = umask(0);
+umask(umask_raw);
+
+#ifdef APR_HAS_THREADS
+status = apr_thread_mutex_unlock(umask_mutex);
+if (!APR_STATUS_IS_SUCCESS(status))
+return status;
+#endif
+
+*umask_perms = apr_unix_mode2perms(umask_raw);
+
+return APR_SUCCESS;
+}
+
 APR_DECLARE(apr_status_t) apr_file_info_get(apr_finfo_t *finfo, 
 apr_int32_t wanted,
 apr_file_t *thefile)
@@ -142,26 +178,84 @@
 {
 apr_status_t status;
 apr_finfo_t finfo;
+apr_fileperms_t mask;
+apr_fileperms_t attr_perms;
 
 status = apr_stat(finfo, fname, APR_FINFO_PROT, cont);
 if (!APR_STATUS_IS_SUCCESS(status))
 return status;
 
 if (attributes  APR_FILE_ATTR_READONLY) {
+/* Make readonly by removing all write bits */
 finfo.protection = ~APR_UWRITE;
 finfo.protection = ~APR_GWRITE;
 finfo.protection = ~APR_WWRITE;
 }
+else {
+/* Make non-readonly by setting all write bits permitted by umask */
+attr_perms = APR_UWRITE | APR_GWRITE | APR_WWRITE;
+status = get_umask(mask, cont);
+if (!APR_STATUS_IS_SUCCESS(status))
+return status;
+attr_perms = ~mask;
+finfo.protection |= attr_perms;
+}
+
 if (attributes  APR_FILE_ATTR_EXECUTABLE) {
-/* ### TODO: should this be umask'd? */
-finfo.protection |= APR_UEXECUTE;
-finfo.protection |= APR_GEXECUTE;
-finfo.protection |= APR_WEXECUTE;
+/* Make executable by setting all execute bits permitted by umask */
+attr_perms = APR_UEXECUTE | APR_GEXECUTE | APR_WEXECUTE;
+status = get_umask(mask, cont);
+if (!APR_STATUS_IS_SUCCESS(status))
+return status;
+attr_perms = ~mask;
+finfo.protection |= attr_perms;
+}
+else {
+/* Make non-executable by removing all execute bits */
+finfo.protection = ~APR_UEXECUTE;
+finfo.protection = ~APR_GEXECUTE;
+finfo.protection = ~APR_WEXECUTE;
 }
 
return apr_file_perms_set(fname, finfo.protection);
 }
   
+APR_DECLARE(apr_status_t) apr_file_attrs_get(const char *fname,
+ apr_fileattrs_t *attributes,
+ apr_pool_t *cont)
+{
+apr_status_t status;
+apr_finfo_t finfo;
+apr_fileperms_t perm_mask;
+mode_t mask;
+
+status = apr_stat(finfo, fname, APR_FINFO_PROT, cont);
+if (!APR_STATUS_IS_SUCCESS(status))
+return status;
+
+*attributes = 0;
+
+/* All the write bits */
+perm_mask = APR_UWRITE | APR_GWRITE | APR_WWRITE;
+
+/* Claim readonly only if no write bits are set */
+if (!(finfo.protection  perm_mask))
+*attributes |= APR_FILE_ATTR_READONLY;
+
+/* All the execute bits allowed by umask */
+perm_mask = APR_UEXECUTE | APR_GEXECUTE | APR_WEXECUTE;
+status = get_umask(mask, cont);
+if (!APR_STATUS_IS_SUCCESS(status))
+   return status;
+perm_mask = ~mask;
+
+/* Claim executable only if all execute bits are set */
+if ((finfo.protection  perm_mask) == perm_mask)
+*attributes |= APR_FILE_ATTR_EXECUTABLE;
+
+return APR_SUCCESS;
+}
+
 APR_DECLARE(apr_status_t) apr_stat(apr_finfo_t *finfo, 
const char *fname, 
apr_int32_t wanted,