summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2005-05-26 12:02:14 +1000
committerDamien Miller <djm@mindrot.org>2005-05-26 12:02:14 +1000
commit5fd38c0ed985d7d699e6be1ff5d211cac130b71e (patch)
treeaa80a3f2b1e522b6f83805ab582645df2049f6ab /misc.c
parent1b0de9a04127eeec9a5352abd16113bb8faa494c (diff)
downloadopenssh-git-5fd38c0ed985d7d699e6be1ff5d211cac130b71e.tar.gz
- djm@cvs.openbsd.org 2005/04/09 04:32:54
[misc.c misc.h tildexpand.c Makefile.in] replace tilde_expand_filename with a simpler implementation, ahead of more whacking; ok deraadt@
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c47
1 files changed, 46 insertions, 1 deletions
diff --git a/misc.c b/misc.c
index 7adbcea1..4bc07a42 100644
--- a/misc.c
+++ b/misc.c
@@ -23,7 +23,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: misc.c,v 1.29 2005/03/10 22:01:05 deraadt Exp $");
+RCSID("$OpenBSD: misc.c,v 1.30 2005/04/09 04:32:54 djm Exp $");
#include "misc.h"
#include "log.h"
@@ -376,6 +376,51 @@ addargs(arglist *args, char *fmt, ...)
}
/*
+ * Expands tildes in the file name. Returns data allocated by xmalloc.
+ * Warning: this calls getpw*.
+ */
+char *
+tilde_expand_filename(const char *filename, uid_t uid)
+{
+ const char *path;
+ char user[128], ret[MAXPATHLEN];
+ struct passwd *pw;
+ int len;
+
+ if (*filename != '~')
+ return (xstrdup(filename));
+ filename++;
+
+ path = strchr(filename, '/');
+ if (path != NULL && path > filename) { /* ~user/path */
+ if (path - filename > sizeof(user) - 1)
+ fatal("tilde_expand_filename: ~username too long");
+ memcpy(user, filename, path - filename);
+ user[path - filename] = '\0';
+ if ((pw = getpwnam(user)) == NULL)
+ fatal("tilde_expand_filename: No such user %s", user);
+ } else if ((pw = getpwuid(uid)) == NULL) /* ~/path */
+ fatal("tilde_expand_filename: No such uid %d", uid);
+
+ if (strlcpy(ret, pw->pw_dir, sizeof(ret)) >= sizeof(ret))
+ fatal("tilde_expand_filename: Path too long");
+
+ /* Make sure directory has a trailing '/' */
+ len = strlen(pw->pw_dir);
+ if ((len == 0 || pw->pw_dir[len - 1] != '/') &&
+ strlcat(ret, "/", sizeof(ret)) >= sizeof(ret))
+ fatal("tilde_expand_filename: Path too long");
+
+ /* Skip leading '/' from specified path */
+ if (path != NULL)
+ filename = path + 1;
+ if (strlcat(ret, filename, sizeof(ret)) >= sizeof(ret))
+ fatal("tilde_expand_filename: Path too long");
+
+ return (xstrdup(ret));
+}
+
+/*
* Read an entire line from a public key file into a static buffer, discarding
* lines that exceed the buffer size. Returns 0 on success, -1 on failure.
*/