Actual source code: fpath.c
1: #include <petscsys.h>
2: #if defined(PETSC_HAVE_PWD_H)
3: #include <pwd.h>
4: #endif
6: /*@C
7: PetscGetFullPath - Given a filename, returns the fully qualified file name.
9: Not Collective
11: Input Parameters:
12: + path - pathname to qualify
13: - flen - size of `fullpath`
15: Output Parameter:
16: . fullpath - buffer to hold the full pathname
18: Level: developer
20: Note:
21: Converts `~username/` and `~/` to appropriate forms
23: Developer Note:
24: On Microsoft Windows full paths may begin with DriveLetter\: so these must be properly handled
26: .seealso: `PetscGetRelativePath()`
27: @*/
28: PetscErrorCode PetscGetFullPath(const char path[], char fullpath[], size_t flen)
29: {
30: size_t ln;
31: PetscBool flg;
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: }
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;
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);
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: }
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: }