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