just cuz it seemed like a good one to get my feet wet with. :)
notes/questions:
- i assume that correct behavior is to set the svn:executable if
the file is actually executable by the user running svn. is
this correct? (as opposed to, for example, if *any* of the
executable bits are set).
- i created a helper method "is_executable" to determine if given
file is executable by current user. it seems like a pretty
general-purpose utility; but it's not currently used anywhere
other than this one place. should (things like) this go in the
public interface?
- it seems like new tests should be written for this functionality,
but i don't yet grok the existing test code well enough to be able
to work this in. maybe in a few days. let me know if you wish to
wait for the tests before accepting the patch.
- there is a note in the issue tracker that this mechanism should
defer to the mechanism described in issue 869 where applicable.
as issue 869 has not been done, this is not addressed by the patch.
- please critique. :)
:brian
Index: subversion/libsvn_client/commit.c
===================================================================
--- subversion/libsvn_client/commit.c
+++ subversion/libsvn_client/commit.c Mon Sep 23 22:07:22 2002
@@ -84,6 +84,58 @@
}
+/* Set *EXECUTABLE to TRUE if the file PATH is executable by the
+ * current user, otherwise set it to FALSE.
+ *
+ * Use POOL for any temporary allocation.
+ */
+static svn_error_t *
+is_executable(svn_boolean_t *executable,
+ const char *path,
+ apr_pool_t *pool)
+{
+ apr_finfo_t file_info;
+ apr_status_t apr_err;
+ apr_uid_t uid;
+ apr_gid_t gid;
+ svn_boolean_t is_user;
+ svn_boolean_t is_group;
+
+ /* Get file and user info. */
+ SVN_ERR (svn_io_stat (&file_info, path,
+ (APR_FINFO_PROT | APR_FINFO_OWNER),
+ pool));
+ apr_err = apr_current_userid (&uid, &gid, pool);
+
+ if (apr_err)
+ return svn_error_create(apr_err, 0, NULL, pool,
+ "Error getting UID of process.");
+
+ /* Check user's status relative to file. */
+ is_user = (apr_compare_users(uid, file_info.user) == APR_SUCCESS);
+ is_group = (apr_compare_groups(gid, file_info.group) == APR_SUCCESS);
+
+ /* Set executable flag, depending on permissions for those
+ statuses user holds (owner, group, or other). */
+ *executable = FALSE;
+ if (! (is_user || is_group))
+ {
+ *executable = (file_info.protection & APR_WEXECUTE);
+ }
+ else
+ {
+ /* We must check both "owner" and "group" independently. */
+ if (is_user)
+ *executable = (file_info.protection & APR_UEXECUTE);
+
+ if (is_group)
+ *executable |= (file_info.protection & APR_GEXECUTE);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+
/* Import file PATH as EDIT_PATH in the repository directory indicated
* by DIR_BATON in EDITOR.
*
@@ -112,6 +164,7 @@
apr_pool_t *subpool = svn_pool_create (hash_pool);
const char *filepath = apr_pstrdup (hash_pool, path);
struct imported_file *value = apr_palloc (hash_pool, sizeof (*value));
+ svn_boolean_t executable;
/* Add the file, using the pool from the FILES hash. */
SVN_ERR (editor->add_file (edit_path, dir_baton, NULL, SVN_INVALID_REVNUM,
@@ -123,6 +176,13 @@
if (mimetype)
SVN_ERR (editor->change_file_prop (file_baton, SVN_PROP_MIME_TYPE,
svn_string_create (mimetype, pool),
+ pool));
+
+ /* If the file is executable, add that as a property to the file. */
+ SVN_ERR (is_executable (&executable, path, pool));
+ if (executable)
+ SVN_ERR (editor->change_file_prop (file_baton, SVN_PROP_EXECUTABLE,
+ svn_string_create ("true", pool),
pool));
if (notify_func)
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Wed Sep 25 17:24:27 2002