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