[PATCH] add strcpy_user_path() and use it in init-db.c and git.c

From: Eric Wong <normalperson@yhbt.net>
Date: 2005-12-24 23:20:16
strcpy_user_path(dest,src) acts just like strcpy() except tildes
in src are expanded appropriately to point to a user's home
directory.

The following expansions are supported:

~user/path	reads home directory from getpwnam()
~/path	 	reads home directory from $HOME env,
		or getpwuid() if $HOME is not set

This patch makes it easier for an ordinary user to share compiled
binaries across different machines, especially if they have different
account names and home directories on those machines.

Hint: build git with: make 'prefix=~'

Signed-off-by: Eric Wong <normalperson@yhbt.net>

---

 cache.h   |    1 +
 git.c     |    6 ++++++
 init-db.c |    3 ++-
 path.c    |   41 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 50 insertions(+), 1 deletions(-)

c46a17b746572e6d16aa026de50d7911eddf8664
diff --git a/cache.h b/cache.h
index c5ff4b7..041bf94 100644
--- a/cache.h
+++ b/cache.h
@@ -184,6 +184,7 @@ extern const unsigned char null_sha1[20]
 
 int git_mkstemp(char *path, size_t n, const char *template);
 
+char * strcpy_user_path(char *dest, const char *path);
 int safe_create_leading_directories(char *path);
 char *safe_strncpy(char *, const char *, size_t);
 char *enter_repo(char *path, int strict);
diff --git a/git.c b/git.c
index 434a3d9..15f4c69 100644
--- a/git.c
+++ b/git.c
@@ -12,6 +12,8 @@
 #include <termios.h>
 #include "git-compat-util.h"
 
+extern char * strcpy_user_path(char *dest, const char *path);
+
 #ifndef PATH_MAX
 # define PATH_MAX 4096
 #endif
@@ -234,6 +236,7 @@ int main(int argc, char **argv, char **e
 {
 	char git_command[PATH_MAX + 1];
 	char wd[PATH_MAX + 1];
+	char tmp[PATH_MAX + 1];
 	int i, len, show_help = 0;
 	char *exec_path = getenv("GIT_EXEC_PATH");
 
@@ -269,6 +272,9 @@ int main(int argc, char **argv, char **e
 			cmd_usage(NULL, NULL);
 	}
 
+	strcpy_user_path(tmp, exec_path);
+	exec_path = tmp;
+
 	if (i >= argc || show_help) {
 		if (i >= argc)
 			cmd_usage(exec_path, NULL);
diff --git a/init-db.c b/init-db.c
index ead37b5..468c93a 100644
--- a/init-db.c
+++ b/init-db.c
@@ -119,7 +119,8 @@ static void copy_templates(const char *g
 
 	if (!template_dir)
 		template_dir = DEFAULT_GIT_TEMPLATE_DIR;
-	strcpy(template_path, template_dir);
+	strcpy_user_path(template_path, template_dir);
+	
 	template_len = strlen(template_path);
 	if (template_path[template_len-1] != '/') {
 		template_path[template_len++] = '/';
diff --git a/path.c b/path.c
index 334b2bd..3caa188 100644
--- a/path.c
+++ b/path.c
@@ -131,6 +131,47 @@ int validate_symref(const char *path)
 	return -1;
 }
 
+char * strcpy_user_path(char *dest, const char *path)
+{
+	if (path[0] == '~') {
+		struct passwd *pw;
+
+		if (path[1] == '/' || path[1] == '\0') {
+			char *home;
+			
+			if (!(home = getenv("HOME"))) {
+				pw = getpwuid(getuid());
+				if (pw && pw->pw_dir)
+					home = pw->pw_dir;
+			}
+				
+			strcpy(dest, home);
+			
+			if (path[1] == '/')
+				strcat(dest, path + 1);
+		} else {
+			char *slash;
+			
+			if ((slash = strchr(path,'/'))) {
+				memcpy(pathname, path + 1, slash - path - 1);
+				pathname[slash - path] = '\0';
+				pw = getpwnam(pathname);
+			} else
+				pw = getpwnam(path + 1);
+
+			if (pw && pw->pw_dir) {
+				strcpy(dest, pw->pw_dir);
+				if (slash)
+					strcat(dest,slash);
+			} else
+				strcpy(dest, path);
+		}
+	} else
+		strcpy(dest, path);
+
+	return dest;
+}
+
 static char *user_path(char *buf, char *path, int sz)
 {
 	struct passwd *pw;
-- 
1.0.GIT
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Received on Sat Dec 24 23:21:04 2005

This archive was generated by hypermail 2.1.8 : 2005-12-24 23:21:11 EST