9
* Expands the initial ~ of a Unix filename and returns the absolute
10
* file name. Otherwise it returns the file name unchanged.
13
DllExport int call_conv expand_file()
15
unsigned char *file_name;
16
unsigned char *expanded_file_name;
20
register unsigned char *new_dir, *p, *user_name;
22
file_name = (unsigned char *)ptoc_string(1);
24
/* If file_name is absolute, flush ...// and detect /./ and /../.
25
If no /./ or /../ we can return right away. */
27
if (file_name[0] == '/')
29
p = file_name; lose = 0;
32
if (p[0] == '/' && p[1] == '/')
34
if (p[0] == '/' && p[1] == '~')
35
file_name = p + 1, lose = 1;
36
if (p[0] == '/' && p[1] == '.'
37
&& (p[2] == '/' || p[2] == 0
38
|| (p[2] == '.' && (p[3] == '/' || p[3] == 0))))
44
ctop_string(2, file_name);
49
/* Now determine directory to start with and put it in new_dir */
53
if (file_name[0] == '~' && file_name[1] == '/') /* prefix ~/ */
55
if (!(new_dir = (unsigned char *) getenv("HOME")))
56
new_dir = (unsigned char *) "";
59
else /* prefix ~username/ */
61
for (p = file_name; *p && (*p != '/'); p++);
62
user_name = (unsigned char *) alloca(p - file_name + 1);
63
bcopy ((char *) file_name, user_name, p - file_name);
64
user_name[p - file_name] = 0;
66
pw = (struct passwd *) getpwnam(user_name + 1);
69
fprintf(stderr, "++Error: \"%s\" is not a registered user\n", user_name + 1);
70
ctop_string(2, file_name); /* return the input file name unchanged */
75
new_dir = (unsigned char *) pw -> pw_dir;
78
/* Now concatenate the directory and name to new space in the stack frame */
80
tlen = (new_dir ? strlen(new_dir) + 1 : 0) + strlen(file_name) + 1;
81
expanded_file_name = (unsigned char *) alloca(tlen);
82
if (new_dir) strcpy(expanded_file_name, new_dir);
83
strcat(expanded_file_name, file_name);
86
/* Make sure you insert the newly created symbol into the symbol table. */
88
ctop_string(2, (unsigned char *) string_find(expanded_file_name, 1));