1 2 #include <petscsys.h> 3 #if defined(PETSC_HAVE_PWD_H) 4 #include <pwd.h> 5 #endif 6 7 /*@C 8 PetscGetFullPath - Given a filename, returns the fully qualified file name. 9 10 Not Collective 11 12 Input Parameters: 13 + path - pathname to qualify 14 - flen - size of `fullpath` 15 16 Output Parameter: 17 . fullpath - buffer to hold the full pathname 18 19 Level: developer 20 21 .seealso: `PetscGetRelativePath()` 22 @*/ 23 PetscErrorCode PetscGetFullPath(const char path[], char fullpath[], size_t flen) 24 { 25 size_t ln; 26 PetscBool flg; 27 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 } 41 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; 54 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); 63 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 } 87 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 } 98