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