1 #include <petscsys.h>
2 #if defined(PETSC_HAVE_PWD_H)
3 #include <pwd.h>
4 #endif
5
6 /*@C
7 PetscGetFullPath - Given a filename, returns the fully qualified file name.
8
9 Not Collective
10
11 Input Parameters:
12 + path - pathname to qualify
13 - flen - size of `fullpath`
14
15 Output Parameter:
16 . fullpath - buffer to hold the full pathname
17
18 Level: developer
19
20 Note:
21 Converts `~username/` and `~/` to appropriate forms
22
23 Developer Note:
24 On Microsoft Windows full paths may begin with DriveLetter\: so these must be properly handled
25
26 .seealso: `PetscGetRelativePath()`
27 @*/
PetscGetFullPath(const char path[],char fullpath[],size_t flen)28 PetscErrorCode PetscGetFullPath(const char path[], char fullpath[], size_t flen)
29 {
30 size_t ln;
31 PetscBool flg;
32
33 PetscFunctionBegin;
34 if (path[0] == '/') {
35 PetscCall(PetscStrncmp("/tmp_mnt/", path, 9, &flg));
36 if (flg) PetscCall(PetscStrncpy(fullpath, path + 8, flen));
37 else PetscCall(PetscStrncpy(fullpath, path, flen));
38 fullpath[flen - 1] = 0;
39 PetscFunctionReturn(PETSC_SUCCESS);
40 }
41 #if defined(PETSC_HAVE_WINDOWS_H)
42 if (path[1] == ':') {
43 PetscCall(PetscStrncpy(fullpath, path, flen));
44 PetscFunctionReturn(PETSC_SUCCESS);
45 }
46 #endif
47 if (path[0] == '.' && path[1] == '/') {
48 PetscCall(PetscGetWorkingDirectory(fullpath, flen));
49 PetscCall(PetscStrlcat(fullpath, path + 1, flen));
50 PetscFunctionReturn(PETSC_SUCCESS);
51 }
52
53 PetscCall(PetscStrncpy(fullpath, path, flen));
54 fullpath[flen - 1] = 0;
55 /* Remove the various "special" forms (~username/ and ~/) */
56 if (fullpath[0] == '~') {
57 char tmppath[PETSC_MAX_PATH_LEN], *rest;
58 if (fullpath[1] == '/') {
59 PetscCall(PetscGetHomeDirectory(tmppath, PETSC_MAX_PATH_LEN));
60 rest = fullpath + 2;
61 } else {
62 #if defined(PETSC_HAVE_PWD_H)
63 struct passwd *pwde;
64 char *p, *name;
65
66 /* Find username */
67 name = fullpath + 1;
68 p = name;
69 while (*p && *p != '/') p++;
70 *p = 0;
71 rest = p + 1;
72 pwde = getpwnam(name);
73 if (!pwde) PetscFunctionReturn(PETSC_SUCCESS);
74
75 PetscCall(PetscStrncpy(tmppath, pwde->pw_dir, sizeof(tmppath)));
76 #else
77 PetscFunctionReturn(PETSC_SUCCESS);
78 #endif
79 }
80 PetscCall(PetscStrlen(tmppath, &ln));
81 if (tmppath[ln - 1] != '/') PetscCall(PetscStrlcat(tmppath + ln - 1, "/", sizeof(tmppath) - ln + 1));
82 PetscCall(PetscStrlcat(tmppath, rest, sizeof(tmppath)));
83 PetscCall(PetscStrncpy(fullpath, tmppath, flen));
84 fullpath[flen - 1] = 0;
85 } else {
86 PetscCall(PetscGetWorkingDirectory(fullpath, flen));
87 PetscCall(PetscStrlen(fullpath, &ln));
88 PetscCall(PetscStrncpy(fullpath + ln, "/", flen - ln));
89 fullpath[flen - 1] = 0;
90 PetscCall(PetscStrlen(fullpath, &ln));
91 if (path[0] == '.' && path[1] == '/') {
92 PetscCall(PetscStrlcat(fullpath, path + 2, flen));
93 } else {
94 PetscCall(PetscStrlcat(fullpath, path, flen));
95 }
96 fullpath[flen - 1] = 0;
97 }
98
99 /* Remove the automounter part of the path */
100 PetscCall(PetscStrncmp(fullpath, "/tmp_mnt/", 9, &flg));
101 if (flg) {
102 char tmppath[PETSC_MAX_PATH_LEN];
103 PetscCall(PetscStrncpy(tmppath, fullpath + 8, sizeof(tmppath)));
104 PetscCall(PetscStrncpy(fullpath, tmppath, flen));
105 }
106 /* We could try to handle things like the removal of .. etc */
107 PetscFunctionReturn(PETSC_SUCCESS);
108 }
109