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: - flen - size of `fullpath`
16: Output Parameter:
17: . fullpath - buffer to hold the full pathname
19: Level: developer
21: .seealso: `PetscGetRelativePath()`
22: @*/
23: PetscErrorCode PetscGetFullPath(const char path[], char fullpath[], size_t flen)
24: {
25: size_t ln;
26: PetscBool flg;
28: PetscFunctionBegin;
29: if (path[0] == '/') {
30: PetscCall(PetscStrncmp("/tmp_mnt/", path, 9, &flg));
31: if (flg) PetscCall(PetscStrncpy(fullpath, path + 8, flen));
32: else PetscCall(PetscStrncpy(fullpath, path, flen));
33: fullpath[flen - 1] = 0;
34: PetscFunctionReturn(PETSC_SUCCESS);
35: }
36: if (path[0] == '.' && path[1] == '/') {
37: PetscCall(PetscGetWorkingDirectory(fullpath, flen));
38: PetscCall(PetscStrlcat(fullpath, path + 1, flen));
39: PetscFunctionReturn(PETSC_SUCCESS);
40: }
42: PetscCall(PetscStrncpy(fullpath, path, flen));
43: fullpath[flen - 1] = 0;
44: /* Remove the various "special" forms (~username/ and ~/) */
45: if (fullpath[0] == '~') {
46: char tmppath[PETSC_MAX_PATH_LEN], *rest;
47: if (fullpath[1] == '/') {
48: PetscCall(PetscGetHomeDirectory(tmppath, PETSC_MAX_PATH_LEN));
49: rest = fullpath + 2;
50: } else {
51: #if defined(PETSC_HAVE_PWD_H)
52: struct passwd *pwde;
53: char *p, *name;
55: /* Find username */
56: name = fullpath + 1;
57: p = name;
58: while (*p && *p != '/') p++;
59: *p = 0;
60: rest = p + 1;
61: pwde = getpwnam(name);
62: if (!pwde) PetscFunctionReturn(PETSC_SUCCESS);
64: PetscCall(PetscStrncpy(tmppath, pwde->pw_dir, sizeof(tmppath)));
65: #else
66: PetscFunctionReturn(PETSC_SUCCESS);
67: #endif
68: }
69: PetscCall(PetscStrlen(tmppath, &ln));
70: if (tmppath[ln - 1] != '/') PetscCall(PetscStrlcat(tmppath + ln - 1, "/", sizeof(tmppath) - ln + 1));
71: PetscCall(PetscStrlcat(tmppath, rest, sizeof(tmppath)));
72: PetscCall(PetscStrncpy(fullpath, tmppath, flen));
73: fullpath[flen - 1] = 0;
74: } else {
75: PetscCall(PetscGetWorkingDirectory(fullpath, flen));
76: PetscCall(PetscStrlen(fullpath, &ln));
77: PetscCall(PetscStrncpy(fullpath + ln, "/", flen - ln));
78: fullpath[flen - 1] = 0;
79: PetscCall(PetscStrlen(fullpath, &ln));
80: if (path[0] == '.' && path[1] == '/') {
81: PetscCall(PetscStrlcat(fullpath, path + 2, flen));
82: } else {
83: PetscCall(PetscStrlcat(fullpath, path, flen));
84: }
85: fullpath[flen - 1] = 0;
86: }
88: /* Remove the automounter part of the path */
89: PetscCall(PetscStrncmp(fullpath, "/tmp_mnt/", 9, &flg));
90: if (flg) {
91: char tmppath[PETSC_MAX_PATH_LEN];
92: PetscCall(PetscStrncpy(tmppath, fullpath + 8, sizeof(tmppath)));
93: PetscCall(PetscStrncpy(fullpath, tmppath, flen));
94: }
95: /* We could try to handle things like the removal of .. etc */
96: PetscFunctionReturn(PETSC_SUCCESS);
97: }