[or-cvs] Resolve FIXME items: make expand_filename handle ~ and ~use...
Nick Mathewson
nickm at seul.org
Wed Nov 10 14:23:34 UTC 2004
Update of /home/or/cvsroot/src/common
In directory moria.mit.edu:/tmp/cvs-serv32065/src/common
Modified Files:
util.c compat.c compat.h
Log Message:
Resolve FIXME items: make expand_filename handle ~ and ~username
Index: util.c
===================================================================
RCS file: /home/or/cvsroot/src/common/util.c,v
retrieving revision 1.176
retrieving revision 1.177
diff -u -d -r1.176 -r1.177
--- util.c 9 Nov 2004 20:04:00 -0000 1.176
+++ util.c 10 Nov 2004 14:23:31 -0000 1.177
@@ -958,22 +958,50 @@
char *expand_filename(const char *filename)
{
tor_assert(filename);
- /* XXXX Should eventually check for ~username/ */
- if (!strncmp(filename,"~/",2)) {
+ if (*filename == '~') {
size_t len;
- const char *home = getenv("HOME");
- char *result;
- if (!home) {
- log_fn(LOG_WARN, "Couldn't find $HOME environment variable while expanding %s", filename);
- return NULL;
+ char *home, *result;
+ const char *rest;
+
+ if (filename[1] == '/' || filename[1] == '\0') {
+ home = getenv("HOME");
+ if (!home) {
+ log_fn(LOG_WARN, "Couldn't find $HOME environment variable while expanding %s", filename);
+ return NULL;
+ }
+ home = tor_strdup(home);
+ rest = strlen(filename)>=2?(filename+2):NULL;
+ } else {
+#ifdef HAVE_PWD_H
+ char *username, *slash;
+ slash = strchr(filename, '/');
+ if (slash)
+ username = tor_strndup(filename+1,slash-filename-1);
+ else
+ username = tor_strdup(filename+1);
+ if (!(home = get_user_homedir(username))) {
+ log_fn(LOG_WARN,"Couldn't get homedir for %s",username);
+ tor_free(username);
+ return NULL;
+ }
+ tor_free(username);
+ rest = slash ? (slash+1) : NULL;
+#else
+ log_fn(LOG_WARN, "Couldn't expend homedir on system without pwd.h");
+ return tor_strdup(filename);
+#endif
}
- /* minus two characters for ~/, plus one for /, plus one for NUL.
+ tor_assert(home);
+ /* Remove trailing slash. */
+ if (strlen(home)>1 && !strcmpend(home,"/")) {
+ home[strlen(home)-1] = '\0';
+ }
+ /* Plus one for /, plus one for NUL.
* Round up to 16 in case we can't do math. */
- len = strlen(home)+strlen(filename)+16;
+ len = strlen(home)+strlen(rest)+16;
result = tor_malloc(len);
- tor_snprintf(result,len,"%s%s%s",home,
- (!strcmpend(home, "/")) ? "" : "/",
- filename+2);
+ tor_snprintf(result,len,"%s/%s",home,rest?rest:"");
+ tor_free(home);
return result;
} else {
return tor_strdup(filename);
Index: compat.c
===================================================================
RCS file: /home/or/cvsroot/src/common/compat.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- compat.c 10 Nov 2004 09:09:15 -0000 1.9
+++ compat.c 10 Nov 2004 14:23:31 -0000 1.10
@@ -390,6 +390,23 @@
return -1;
}
+#ifdef HAVE_PWD_H
+/** Allocate and return a string containing the home directory for the
+ * user <b>username</b>. Only works on posix-like systems */
+char *
+get_user_homedir(const char *username)
+{
+ struct passwd *pw;
+ tor_assert(username);
+
+ if (!(pw = getpwnam(username))) {
+ log_fn(LOG_ERR,"User '%s' not found.", username);
+ return NULL;
+ }
+ return tor_strdup(pw->pw_dir);
+}
+#endif
+
/** Set *addr to the IP address (in dotted-quad notation) stored in c.
* Return 1 on success, 0 if c is badly formatted. (Like inet_aton(c,addr),
* but works on Windows and Solaris.)
Index: compat.h
===================================================================
RCS file: /home/or/cvsroot/src/common/compat.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- compat.h 4 Nov 2004 22:33:20 -0000 1.6
+++ compat.h 10 Nov 2004 14:23:31 -0000 1.7
@@ -164,6 +164,9 @@
int set_max_file_descriptors(unsigned int required_min);
int switch_id(char *user, char *group);
+#ifdef HAVE_PWD_H
+char *get_user_homedir(const char *username);
+#endif
int spawn_func(int (*func)(void *), void *data);
void spawn_exit(void);
More information about the tor-commits
mailing list