diff options
Diffstat (limited to '')
-rw-r--r-- | lib/util/util_paths.c | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/lib/util/util_paths.c b/lib/util/util_paths.c new file mode 100644 index 0000000..ce93028 --- /dev/null +++ b/lib/util/util_paths.c @@ -0,0 +1,170 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Jeremy Allison 2001-2007 + Copyright (C) Simo Sorce 2001 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003 + Copyright (C) James Peach 2006 + Copyright (c) 2020 Andreas Schneider <asn@samba.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "replace.h" +#include "dynconfig/dynconfig.h" +#include "lib/util/util_paths.h" +#include "system/passwd.h" +#include "system/filesys.h" + +/** + * @brief Returns an absolute path to a file in the Samba modules directory. + * + * @param name File to find, relative to MODULESDIR. + * + * @retval Pointer to a string containing the full path. + **/ + +char *modules_path(TALLOC_CTX *mem_ctx, const char *name) +{ + return talloc_asprintf(mem_ctx, "%s/%s", get_dyn_MODULESDIR(), name); +} + +/** + * @brief Returns an absolute path to a file in the Samba data directory. + * + * @param name File to find, relative to CODEPAGEDIR. + * + * @retval Pointer to a talloc'ed string containing the full path. + **/ + +char *data_path(TALLOC_CTX *mem_ctx, const char *name) +{ + return talloc_asprintf(mem_ctx, "%s/%s", get_dyn_CODEPAGEDIR(), name); +} + +/** + * @brief Returns the platform specific shared library extension. + * + * @retval Pointer to a const char * containing the extension. + **/ + +const char *shlib_ext(void) +{ + return get_dyn_SHLIBEXT(); +} + +static char *get_user_home_dir(TALLOC_CTX *mem_ctx) +{ + struct passwd pwd = {0}; + struct passwd *pwdbuf = NULL; + char *buf = NULL; + char *out = NULL; + long int initlen; + size_t len; + int rc; + + initlen = sysconf(_SC_GETPW_R_SIZE_MAX); + if (initlen == -1) { + len = 1024; + } else { + len = (size_t)initlen; + } + buf = talloc_size(mem_ctx, len); + if (buf == NULL) { + return NULL; + } + + rc = getpwuid_r(getuid(), &pwd, buf, len, &pwdbuf); + while (rc == ERANGE) { + size_t newlen = 2 * len; + if (newlen < len) { + /* Overflow */ + goto done; + } + len = newlen; + buf = talloc_realloc_size(mem_ctx, buf, len); + if (buf == NULL) { + goto done; + } + rc = getpwuid_r(getuid(), &pwd, buf, len, &pwdbuf); + } + if (rc != 0 || pwdbuf == NULL ) { + const char *szPath = getenv("HOME"); + if (szPath == NULL) { + goto done; + } + len = strnlen(szPath, PATH_MAX); + if (len >= PATH_MAX) { + goto done; + } + out = talloc_strdup(mem_ctx, szPath); + goto done; + } + + out = talloc_strdup(mem_ctx, pwd.pw_dir); +done: + TALLOC_FREE(buf); + return out; +} + +char *path_expand_tilde(TALLOC_CTX *mem_ctx, const char *d) +{ + char *h = NULL, *r = NULL; + const char *p = NULL; + struct stat sb = {0}; + int rc; + + if (d[0] != '~') { + return talloc_strdup(mem_ctx, d); + } + d++; + + /* handle ~user/path */ + p = strchr(d, '/'); + if (p != NULL && p > d) { + struct passwd *pw; + size_t s = p - d; + char u[128]; + + if (s >= sizeof(u)) { + return NULL; + } + memcpy(u, d, s); + u[s] = '\0'; + + pw = getpwnam(u); + if (pw == NULL) { + return NULL; + } + h = talloc_strdup(mem_ctx, pw->pw_dir); + } else { + p = d; + h = get_user_home_dir(mem_ctx); + } + if (h == NULL) { + return NULL; + } + + rc = stat(h, &sb); + if (rc != 0) { + TALLOC_FREE(h); + return NULL; + } + + r = talloc_asprintf(mem_ctx, "%s%s", h, p); + TALLOC_FREE(h); + + return r; +} |