updated copyright for release 1.1
[dyninst.git] / common / src / pathName.C
1 /*
2  * Copyright (c) 1996 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 // pathName.C
43
44 #include <pwd.h>
45 #include "util/h/pathName.h"
46
47 string expand_tilde_pathname(const string &dir) {
48    // e.g. convert "~tamches/hello" to "/u/t/a/tamches/hello",
49    // or convert "~/hello" to same.
50    // In the spirit of Tcl_TildeSubst
51    if (dir.length()==0)
52       return dir;
53
54    const char *dir_cstr = dir.string_of();
55    if (dir_cstr[0] != '~')
56       return dir;
57
58    // Now, there are two possibilities: a tilde by itself (e.g. ~/x/y or ~), or
59    // a tilde followed by a username.
60    if (dir_cstr[1] == '/' || dir_cstr[1] == '\0') {
61       // It's the first case.  We need to find the environment vrble HOME and use it.
62       // It it doesn't exist (but it always does, I think) then I don't know what
63       // to do.
64       char *home_dir = getenv("HOME");
65       if (home_dir == NULL)
66          return dir; // yikes
67
68       if (home_dir[strlen(home_dir)-1] == '/' && dir_cstr[1] != '\0')
69          return string(home_dir) + &dir_cstr[2];
70       else
71          return string(home_dir) + &dir_cstr[1];
72    }
73
74    // It's the second case.  We need to find the username.  It starts at
75    // dir_cstr[1] and ends at (but not including) the first '/' or '\0'.
76    string userName;
77
78    const char *ptr = strchr(&dir_cstr[1], '/');
79    if (ptr == NULL)
80       userName = string(&dir_cstr[1]);
81    else {
82       char user_name_buffer[200];
83       unsigned user_name_len = ptr - &dir_cstr[1];
84
85       for (unsigned j=0; j < user_name_len; j++)
86          user_name_buffer[j] = dir_cstr[1+j];
87
88       user_name_buffer[user_name_len] = '\0';
89       userName = user_name_buffer;
90    }
91
92    struct passwd *pwPtr = getpwnam(userName.string_of());
93    if (pwPtr == NULL) {
94       endpwent();
95       return dir; // something better needed...
96    }
97
98    string result = string(pwPtr->pw_dir) + string(ptr);
99    endpwent();
100    return result;
101 }