Actual source code: fpath.c
2: #include <petscsys.h>
3: #if defined(PETSC_HAVE_PWD_H)
4: #include <pwd.h>
5: #endif
7: /*@C
8: PetscGetFullPath - Given a filename, returns the fully qualified file name.
10: Not Collective
12: Input Parameters:
13: + path - pathname to qualify
14: . fullpath - pointer to buffer to hold full pathname
15: - flen - size of fullpath
17: Level: developer
19: .seealso: `PetscGetRelativePath()`
20: @*/
21: PetscErrorCode PetscGetFullPath(const char path[], char fullpath[], size_t flen)
22: {
23: size_t ln;
24: PetscBool flg;
26: PetscFunctionBegin;
27: if (path[0] == '/') {
28: PetscCall(PetscStrncmp("/tmp_mnt/", path, 9, &flg));
29: if (flg) PetscCall(PetscStrncpy(fullpath, path + 8, flen));
30: else PetscCall(PetscStrncpy(fullpath, path, flen));
31: fullpath[flen - 1] = 0;
32: PetscFunctionReturn(PETSC_SUCCESS);
33: }
34: if (path[0] == '.' && path[1] == '/') {
35: PetscCall(PetscGetWorkingDirectory(fullpath, flen));
36: PetscCall(PetscStrlcat(fullpath, path + 1, flen));
37: PetscFunctionReturn(PETSC_SUCCESS);
38: }
40: PetscCall(PetscStrncpy(fullpath, path, flen));
41: fullpath[flen - 1] = 0;
42: /* Remove the various "special" forms (~username/ and ~/) */
43: if (fullpath[0] == '~') {
44: char tmppath[PETSC_MAX_PATH_LEN], *rest;
45: if (fullpath[1] == '/') {
46: PetscCall(PetscGetHomeDirectory(tmppath, PETSC_MAX_PATH_LEN));
47: rest = fullpath + 2;
48: } else {
49: #if defined(PETSC_HAVE_PWD_H)
50: struct passwd *pwde;
51: char *p, *name;
53: /* Find username */
54: name = fullpath + 1;
55: p = name;
56: while (*p && *p != '/') p++;
57: *p = 0;
58: rest = p + 1;
59: pwde = getpwnam(name);
60: if (!pwde) PetscFunctionReturn(PETSC_SUCCESS);
62: PetscCall(PetscStrncpy(tmppath, pwde->pw_dir, sizeof(tmppath)));
63: #else
64: PetscFunctionReturn(PETSC_SUCCESS);
65: #endif
66: }
67: PetscCall(PetscStrlen(tmppath, &ln));
68: if (tmppath[ln - 1] != '/') PetscCall(PetscStrlcat(tmppath + ln - 1, "/", sizeof(tmppath) - ln + 1));
69: PetscCall(PetscStrlcat(tmppath, rest, sizeof(tmppath)));
70: PetscCall(PetscStrncpy(fullpath, tmppath, flen));
71: fullpath[flen - 1] = 0;
72: } else {
73: PetscCall(PetscGetWorkingDirectory(fullpath, flen));
74: PetscCall(PetscStrlen(fullpath, &ln));
75: PetscCall(PetscStrncpy(fullpath + ln, "/", flen - ln));
76: fullpath[flen - 1] = 0;
77: PetscCall(PetscStrlen(fullpath, &ln));
78: if (path[0] == '.' && path[1] == '/') {
79: PetscCall(PetscStrlcat(fullpath, path + 2, flen));
80: } else {
81: PetscCall(PetscStrlcat(fullpath, path, flen));
82: }
83: fullpath[flen - 1] = 0;
84: }
86: /* Remove the automounter part of the path */
87: PetscCall(PetscStrncmp(fullpath, "/tmp_mnt/", 9, &flg));
88: if (flg) {
89: char tmppath[PETSC_MAX_PATH_LEN];
90: PetscCall(PetscStrncpy(tmppath, fullpath + 8, sizeof(tmppath)));
91: PetscCall(PetscStrncpy(fullpath, tmppath, flen));
92: }
93: /* We could try to handle things like the removal of .. etc */
94: PetscFunctionReturn(PETSC_SUCCESS);
95: }