|
Lines 16-21
Link Here
|
| 16 |
#include "xmalloc.h" |
16 |
#include "xmalloc.h" |
| 17 |
#include "log.h" |
17 |
#include "log.h" |
| 18 |
#include "tildexpand.h" |
18 |
#include "tildexpand.h" |
|
|
19 |
#include "buffer.h" |
| 19 |
|
20 |
|
| 20 |
/* |
21 |
/* |
| 21 |
* Expands tildes in the file name. Returns data allocated by xmalloc. |
22 |
* Expands tildes in the file name. Returns data allocated by xmalloc. |
|
Lines 31-36
Link Here
|
| 31 |
char user[100]; |
32 |
char user[100]; |
| 32 |
int len; |
33 |
int len; |
| 33 |
|
34 |
|
|
|
35 |
pw = getpwuid(my_uid); /* Own home directory. */ |
| 36 |
if (!pw) |
| 37 |
fatal("Unknown user %100s.", user); |
| 38 |
|
| 39 |
filename = expand_filename(filename, pw); |
| 40 |
|
| 34 |
/* Return immediately if no tilde. */ |
41 |
/* Return immediately if no tilde. */ |
| 35 |
if (filename[0] != '~') |
42 |
if (filename[0] != '~') |
| 36 |
return xstrdup(filename); |
43 |
return xstrdup(filename); |
|
Lines 44-52
Link Here
|
| 44 |
userlen = cp - filename; /* Something after username. */ |
51 |
userlen = cp - filename; /* Something after username. */ |
| 45 |
else |
52 |
else |
| 46 |
userlen = strlen(filename); /* Nothing after username. */ |
53 |
userlen = strlen(filename); /* Nothing after username. */ |
| 47 |
if (userlen == 0) |
54 |
if (userlen != 0) { |
| 48 |
pw = getpwuid(my_uid); /* Own home directory. */ |
|
|
| 49 |
else { |
| 50 |
/* Tilde refers to someone elses home directory. */ |
55 |
/* Tilde refers to someone elses home directory. */ |
| 51 |
if (userlen > sizeof(user) - 1) |
56 |
if (userlen > sizeof(user) - 1) |
| 52 |
fatal("User name after tilde too long."); |
57 |
fatal("User name after tilde too long."); |
|
Lines 54-61
Link Here
|
| 54 |
user[userlen] = 0; |
59 |
user[userlen] = 0; |
| 55 |
pw = getpwnam(user); |
60 |
pw = getpwnam(user); |
| 56 |
} |
61 |
} |
| 57 |
if (!pw) |
|
|
| 58 |
fatal("Unknown user %100s.", user); |
| 59 |
|
62 |
|
| 60 |
/* If referring to someones home directory, return it now. */ |
63 |
/* If referring to someones home directory, return it now. */ |
| 61 |
if (!cp) { |
64 |
if (!cp) { |
|
Lines 68-72
Link Here
|
| 68 |
fatal("Home directory too long (%d > %d", len-1, MAXPATHLEN-1); |
71 |
fatal("Home directory too long (%d > %d", len-1, MAXPATHLEN-1); |
| 69 |
expanded = xmalloc(len); |
72 |
expanded = xmalloc(len); |
| 70 |
snprintf(expanded, len, "%s%s%s", pw->pw_dir, strcmp(pw->pw_dir, "/") ? "/" : "", cp + 1); |
73 |
snprintf(expanded, len, "%s%s%s", pw->pw_dir, strcmp(pw->pw_dir, "/") ? "/" : "", cp + 1); |
| 71 |
return expanded; |
74 |
return expand_filename(expanded, pw); |
|
|
75 |
} |
| 76 |
|
| 77 |
/* |
| 78 |
* Given a template and a passwd structure, build a filename |
| 79 |
* by substituting % tokenised options. Currently, %% becomes '%', |
| 80 |
* %h becomes the home directory and %u the username. |
| 81 |
* |
| 82 |
* This returns a buffer allocated by xmalloc. |
| 83 |
*/ |
| 84 |
char * |
| 85 |
expand_filename(const char *filename, struct passwd *pw) |
| 86 |
{ |
| 87 |
Buffer buffer; |
| 88 |
char *file; |
| 89 |
const char *cp; |
| 90 |
|
| 91 |
/* |
| 92 |
* Build the filename string in the buffer by making the appropriate |
| 93 |
* substitutions to the given file name. |
| 94 |
*/ |
| 95 |
buffer_init(&buffer); |
| 96 |
for (cp = filename; *cp; cp++) { |
| 97 |
if (cp[0] == '%' && cp[1] == '%') { |
| 98 |
buffer_append(&buffer, "%", 1); |
| 99 |
cp++; |
| 100 |
continue; |
| 101 |
} |
| 102 |
if (cp[0] == '%' && cp[1] == 'h') { |
| 103 |
buffer_append(&buffer, pw->pw_dir, strlen(pw->pw_dir)); |
| 104 |
cp++; |
| 105 |
continue; |
| 106 |
} |
| 107 |
if (cp[0] == '%' && cp[1] == 'u') { |
| 108 |
buffer_append(&buffer, pw->pw_name, |
| 109 |
strlen(pw->pw_name)); |
| 110 |
cp++; |
| 111 |
continue; |
| 112 |
} |
| 113 |
buffer_append(&buffer, cp, 1); |
| 114 |
} |
| 115 |
buffer_append(&buffer, "\0", 1); |
| 116 |
|
| 117 |
/* |
| 118 |
* Ensure that filename starts anchored. If not, be backward |
| 119 |
* compatible and prepend the '%h/' |
| 120 |
*/ |
| 121 |
file = xmalloc(MAXPATHLEN); |
| 122 |
cp = buffer_ptr(&buffer); |
| 123 |
if (*cp != '/' && *cp != '~') |
| 124 |
snprintf(file, MAXPATHLEN, "%s/%s", pw->pw_dir, cp); |
| 125 |
else |
| 126 |
strlcpy(file, cp, MAXPATHLEN); |
| 127 |
|
| 128 |
buffer_free(&buffer); |
| 129 |
return file; |
| 72 |
} |
130 |
} |
|
|
131 |
|