home-expand.c revision cca4ba2a504d70a9fe9fee37f8433997359de52c
8c294c1cd4d721818a59684cf7f2b36123f79163Stephen Gallagher* Copyright (c) 2003-2013 Dovecot authors, see the included COPYING file */
8c294c1cd4d721818a59684cf7f2b36123f79163Stephen Gallagher
8c294c1cd4d721818a59684cf7f2b36123f79163Stephen Gallagher#include "lib.h"
8c294c1cd4d721818a59684cf7f2b36123f79163Stephen Gallagher#include "ipwd.h"
8c294c1cd4d721818a59684cf7f2b36123f79163Stephen Gallagher#include "home-expand.h"
c252d148fa8ab50aaaa8bbae7beb4d208025171dNikolai Kondrashov
9542512d7be40f2000298c86d3d2b728f4f0f65aStephen Gallagher#include <stdlib.h>
9542512d7be40f2000298c86d3d2b728f4f0f65aStephen Gallagher
9542512d7be40f2000298c86d3d2b728f4f0f65aStephen Gallagherint home_try_expand(const char **_path)
c6e39e15178675d0779e0ae855245774a09b4eb5Nikolai Kondrashov{
c6e39e15178675d0779e0ae855245774a09b4eb5Nikolai Kondrashov const char *path = *_path;
c6e39e15178675d0779e0ae855245774a09b4eb5Nikolai Kondrashov const char *name, *home, *p;
c6e39e15178675d0779e0ae855245774a09b4eb5Nikolai Kondrashov struct passwd pw;
c6e39e15178675d0779e0ae855245774a09b4eb5Nikolai Kondrashov
29c5542feb4c45865ea61be97e0e84a1d1f04918Jakub Hrozek if (path == NULL || *path != '~')
29c5542feb4c45865ea61be97e0e84a1d1f04918Jakub Hrozek return 0;
fd5a4eacd56700ffb08a73121aeacdc806cb0132Sumit Bose
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagher path++;
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagher if (*path == '/' || *path == '\0') {
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagher home = getenv("HOME");
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagher if (*path != '\0') path++;
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagher } else {
84ae5edab16ad6be5e3be956cb6fa031c1428eb5Stephen Gallagher p = strchr(path, '/');
9d453f1e8b28983b363b44c49b7cd701a994fd97Nikolai Kondrashov if (p == NULL) {
428db8a58c0c149d5efccc6d788f70916c1d34d7Jakub Hrozek name = path;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher path = "";
df4cc3a83c5d6700b6a09ff96cb4a6b1949b1aa9Stephen Gallagher } else {
df4cc3a83c5d6700b6a09ff96cb4a6b1949b1aa9Stephen Gallagher name = t_strdup_until(path, p);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher path = p+1;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher switch (i_getpwnam(name, &pw)) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher case -1:
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_error("getpwnam(%s) failed: %m", name);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher home = NULL;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher break;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher case 0:
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher home = NULL;
59744cff6edb106ae799b2321cb8731edadf409aStephen Gallagher break;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher default:
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher home = pw.pw_dir;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher break;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
8a5e793a0576250da80371e53aa3e7eba15cdb63Sumit Bose }
8a5e793a0576250da80371e53aa3e7eba15cdb63Sumit Bose
8a5e793a0576250da80371e53aa3e7eba15cdb63Sumit Bose if (home == NULL)
90fd1bbd6035cdab46faa3a695a2fb2be6508b17Sumit Bose return -1;
90fd1bbd6035cdab46faa3a695a2fb2be6508b17Sumit Bose
90fd1bbd6035cdab46faa3a695a2fb2be6508b17Sumit Bose if (*path == '\0')
af4ffe1001adcc0a96897e426d26444f07af9aa1Benjamin Franzke *_path = t_strdup(home);
af4ffe1001adcc0a96897e426d26444f07af9aa1Benjamin Franzke else
af4ffe1001adcc0a96897e426d26444f07af9aa1Benjamin Franzke *_path = t_strconcat(home, "/", path, NULL);
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose return 0;
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose}
1d1a0a019d8d4d9ab0f51ada03604cd2cada287eSumit Bose
f3c85d900c4663854cc7bbae7d9f77867ed1f69bSumit Boseconst char *home_expand(const char *path)
f3c85d900c4663854cc7bbae7d9f77867ed1f69bSumit Bose{
f3c85d900c4663854cc7bbae7d9f77867ed1f69bSumit Bose (void)home_try_expand(&path);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return path;
2a552e43581c74f51205c7141ec9f6e9542509f8Stephen Gallagher}
2a552e43581c74f51205c7141ec9f6e9542509f8Stephen Gallagher
41291f19dbc5bf14f20729959b852fa605fcc02dJakub Hrozekconst char *home_expand_tilde(const char *path, const char *home)
8214510f125879c3b1d247f2ce981ee20b5375d1Jakub Hrozek{
1a59af8245f183f22d87d067a90197d8e2ea958dJakub Hrozek if (path == NULL || *path != '~')
a5bb518446d5ce565d7ba819590a009cabb0b0b4Jakub Hrozek return path;
a8d1a344e580f29699aed9b88d87fc3c6f5d113bSimo Sorce
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (path[1] == '\0')
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return home;
d921c1eba437662437847279f251a0a5d8f70127Maxim if (path[1] != '/')
2cbdd12983eb85eddb90f64cfafb24eae5b448f4Jakub Hrozek return path;
b9c8ce2bdd4045782c243605a1b999098bedcffcNoam Meltzer
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher /* ~/ used */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return t_strconcat(home, path + 1, NULL);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher