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