first version
[dyninst.git] / common / src / pathName.C
1 // pathName.C
2
3 #include <pwd.h>
4 #include "util/h/pathName.h"
5
6 string expand_tilde_pathname(const string &dir) {
7    // e.g. convert "~tamches/hello" to "/u/t/a/tamches/hello",
8    // or convert "~/hello" to same.
9    // In the spirit of Tcl_TildeSubst
10    if (dir.length()==0)
11       return dir;
12
13    const char *dir_cstr = dir.string_of();
14    if (dir_cstr[0] != '~')
15       return dir;
16
17    // Now, there are two possibilities: a tilde by itself (e.g. ~/x/y or ~), or
18    // a tilde followed by a username.
19    if (dir_cstr[1] == '/' || dir_cstr[1] == '\0') {
20       // It's the first case.  We need to find the environment vrble HOME and use it.
21       // It it doesn't exist (but it always does, I think) then I don't know what
22       // to do.
23       char *home_dir = getenv("HOME");
24       if (home_dir == NULL)
25          return dir; // yikes
26
27       if (home_dir[strlen(home_dir)-1] == '/' && dir_cstr[1] != '\0')
28          return string(home_dir) + &dir_cstr[2];
29       else
30          return string(home_dir) + &dir_cstr[1];
31    }
32
33    // It's the second case.  We need to find the username.  It starts at
34    // dir_cstr[1] and ends at (but not including) the first '/' or '\0'.
35    string userName;
36
37    const char *ptr = strchr(&dir_cstr[1], '/');
38    if (ptr == NULL)
39       userName = string(&dir_cstr[1]);
40    else {
41       char user_name_buffer[200];
42       unsigned user_name_len = ptr - &dir_cstr[1];
43
44       for (unsigned j=0; j < user_name_len; j++)
45          user_name_buffer[j] = dir_cstr[1+j];
46
47       user_name_buffer[user_name_len] = '\0';
48       userName = user_name_buffer;
49    }
50
51    struct passwd *pwPtr = getpwnam(userName.string_of());
52    if (pwPtr == NULL) {
53       endpwent();
54       return dir; // something better needed...
55    }
56
57    string result = string(pwPtr->pw_dir) + string(ptr);
58    endpwent();
59    return result;
60 }