1c6db04a5SJed Brown #include <petscsys.h> 2e5c89e4eSSatish Balay #if defined(PETSC_HAVE_PWD_H) 3e5c89e4eSSatish Balay #include <pwd.h> 4e5c89e4eSSatish Balay #endif 5e5c89e4eSSatish Balay 6e5c89e4eSSatish Balay /*@C 7e5c89e4eSSatish Balay PetscGetFullPath - Given a filename, returns the fully qualified file name. 8e5c89e4eSSatish Balay 9e5c89e4eSSatish Balay Not Collective 10e5c89e4eSSatish Balay 11e5c89e4eSSatish Balay Input Parameters: 12e5c89e4eSSatish Balay + path - pathname to qualify 1321532e8aSBarry Smith - flen - size of `fullpath` 1421532e8aSBarry Smith 1521532e8aSBarry Smith Output Parameter: 1621532e8aSBarry Smith . fullpath - buffer to hold the full pathname 17e5c89e4eSSatish Balay 18e5c89e4eSSatish Balay Level: developer 19e5c89e4eSSatish Balay 207255af2bSBarry Smith Note: 217255af2bSBarry Smith Converts `~username/` and `~/` to appropriate forms 227255af2bSBarry Smith 23*102f4e8dSBarry Smith Developer Note: 24*102f4e8dSBarry Smith On Microsoft Windows full paths may begin with DriveLetter\: so these must be properly handled 25*102f4e8dSBarry Smith 26db781477SPatrick Sanan .seealso: `PetscGetRelativePath()` 27e5c89e4eSSatish Balay @*/ 28d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscGetFullPath(const char path[], char fullpath[], size_t flen) 29d71ae5a4SJacob Faibussowitsch { 30e5c89e4eSSatish Balay size_t ln; 31ace3abfcSBarry Smith PetscBool flg; 32e5c89e4eSSatish Balay 33e5c89e4eSSatish Balay PetscFunctionBegin; 34e5c89e4eSSatish Balay if (path[0] == '/') { 359566063dSJacob Faibussowitsch PetscCall(PetscStrncmp("/tmp_mnt/", path, 9, &flg)); 369566063dSJacob Faibussowitsch if (flg) PetscCall(PetscStrncpy(fullpath, path + 8, flen)); 379566063dSJacob Faibussowitsch else PetscCall(PetscStrncpy(fullpath, path, flen)); 386c8deb01SJed Brown fullpath[flen - 1] = 0; 393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40e5c89e4eSSatish Balay } 41*102f4e8dSBarry Smith #if defined(PETSC_HAVE_WINDOWS_H) 42*102f4e8dSBarry Smith if (path[1] == ':') { 43*102f4e8dSBarry Smith PetscCall(PetscStrncpy(fullpath, path, flen)); 44*102f4e8dSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 45*102f4e8dSBarry Smith } 46*102f4e8dSBarry Smith #endif 479483a8a2SBarry Smith if (path[0] == '.' && path[1] == '/') { 489483a8a2SBarry Smith PetscCall(PetscGetWorkingDirectory(fullpath, flen)); 499483a8a2SBarry Smith PetscCall(PetscStrlcat(fullpath, path + 1, flen)); 503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 519483a8a2SBarry Smith } 52e5c89e4eSSatish Balay 539566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(fullpath, path, flen)); 546c8deb01SJed Brown fullpath[flen - 1] = 0; 55e5c89e4eSSatish Balay /* Remove the various "special" forms (~username/ and ~/) */ 56e5c89e4eSSatish Balay if (fullpath[0] == '~') { 5745082d64SJed Brown char tmppath[PETSC_MAX_PATH_LEN], *rest; 58e5c89e4eSSatish Balay if (fullpath[1] == '/') { 599566063dSJacob Faibussowitsch PetscCall(PetscGetHomeDirectory(tmppath, PETSC_MAX_PATH_LEN)); 6045082d64SJed Brown rest = fullpath + 2; 61e5c89e4eSSatish Balay } else { 6245082d64SJed Brown #if defined(PETSC_HAVE_PWD_H) 6345082d64SJed Brown struct passwd *pwde; 64e5c89e4eSSatish Balay char *p, *name; 65e5c89e4eSSatish Balay 66e5c89e4eSSatish Balay /* Find username */ 67e5c89e4eSSatish Balay name = fullpath + 1; 68e5c89e4eSSatish Balay p = name; 69e5c89e4eSSatish Balay while (*p && *p != '/') p++; 7045082d64SJed Brown *p = 0; 7145082d64SJed Brown rest = p + 1; 72e5c89e4eSSatish Balay pwde = getpwnam(name); 733ba16761SJacob Faibussowitsch if (!pwde) PetscFunctionReturn(PETSC_SUCCESS); 74e5c89e4eSSatish Balay 75c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(tmppath, pwde->pw_dir, sizeof(tmppath))); 7645082d64SJed Brown #else 773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7845082d64SJed Brown #endif 7945082d64SJed Brown } 809566063dSJacob Faibussowitsch PetscCall(PetscStrlen(tmppath, &ln)); 81c6a7a370SJeremy L Thompson if (tmppath[ln - 1] != '/') PetscCall(PetscStrlcat(tmppath + ln - 1, "/", sizeof(tmppath) - ln + 1)); 82c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(tmppath, rest, sizeof(tmppath))); 839566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(fullpath, tmppath, flen)); 846c8deb01SJed Brown fullpath[flen - 1] = 0; 856c8deb01SJed Brown } else { 869566063dSJacob Faibussowitsch PetscCall(PetscGetWorkingDirectory(fullpath, flen)); 879566063dSJacob Faibussowitsch PetscCall(PetscStrlen(fullpath, &ln)); 889566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(fullpath + ln, "/", flen - ln)); 896c8deb01SJed Brown fullpath[flen - 1] = 0; 909566063dSJacob Faibussowitsch PetscCall(PetscStrlen(fullpath, &ln)); 916c8deb01SJed Brown if (path[0] == '.' && path[1] == '/') { 929566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(fullpath, path + 2, flen)); 936c8deb01SJed Brown } else { 949566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(fullpath, path, flen)); 95e5c89e4eSSatish Balay } 966c8deb01SJed Brown fullpath[flen - 1] = 0; 976c8deb01SJed Brown } 986c8deb01SJed Brown 99e5c89e4eSSatish Balay /* Remove the automounter part of the path */ 1009566063dSJacob Faibussowitsch PetscCall(PetscStrncmp(fullpath, "/tmp_mnt/", 9, &flg)); 101e5c89e4eSSatish Balay if (flg) { 102e5c89e4eSSatish Balay char tmppath[PETSC_MAX_PATH_LEN]; 103c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(tmppath, fullpath + 8, sizeof(tmppath))); 104c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(fullpath, tmppath, flen)); 105e5c89e4eSSatish Balay } 106e5c89e4eSSatish Balay /* We could try to handle things like the removal of .. etc */ 1073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 108e5c89e4eSSatish Balay } 109