/* * tilde.c: Expand ~/ and ~user/ style pathnames * * $Id: tilde.c,v 1.1 1996/09/26 20:21:51 mb Exp mb $ * * Copyright (c) 1996 Martin Buck * Read COPYING for more information * */ #include #include #include #include #include #include "safe_malloc.h" #include "tilde.h" /* Expand filenames with leading ~/ or ~user/. Returns NULL, if user doesn't exist. Returned * string points to statically allocated storage and may be overwritten by subsequent calls. */ char * tilde_expand(const char *dir) { static char *ret = NULL; char *home, *user; int userlen; struct passwd *pw; if (ret) { free(ret); ret = NULL; } if (*dir == '~') { userlen = strcspn(dir + 1, "/"); /* Expand ~/ */ if (!userlen) { if (!(home = getenv("HOME")) && (pw = getpwuid(getuid()))) { home = pw->pw_dir; } if (home) { ret = sstrdup(home); ret = sstrapp(ret, &dir[1]); } /* Expand ~user/ */ } else { user = smalloc(userlen); memcpy(user, dir + 1, userlen); if ((pw = getpwnam(user)) && pw->pw_dir) { ret = sstrdup(pw->pw_dir); ret = sstrapp(ret, &dir[userlen + 1]); } free(user); } } else { ret = sstrdup(dir); } return ret; } /* Like tilde_expand(), but uses srealloc() to resize original string instead of using * static storage. */ int tilde_expand_realloc(char **dir) { char *str; if ((str = tilde_expand(*dir))) { *dir = srealloc(*dir, strlen(str) + 1); strcpy(*dir, str); return 0; } else { return -1; } }