17d0a6c19SBarry Smith 2c6db04a5SJed Brown #include <petscsys.h> 3e5c89e4eSSatish Balay #if defined(PETSC_HAVE_PWD_H) 4e5c89e4eSSatish Balay #include <pwd.h> 5e5c89e4eSSatish Balay #endif 6e5c89e4eSSatish Balay 7e5c89e4eSSatish Balay /*@C 8e5c89e4eSSatish Balay PetscGetFullPath - Given a filename, returns the fully qualified file name. 9e5c89e4eSSatish Balay 10e5c89e4eSSatish Balay Not Collective 11e5c89e4eSSatish Balay 12e5c89e4eSSatish Balay Input Parameters: 13e5c89e4eSSatish Balay + path - pathname to qualify 14*21532e8aSBarry Smith - flen - size of `fullpath` 15*21532e8aSBarry Smith 16*21532e8aSBarry Smith Output Parameter: 17*21532e8aSBarry Smith . fullpath - buffer to hold the full pathname 18e5c89e4eSSatish Balay 19e5c89e4eSSatish Balay Level: developer 20e5c89e4eSSatish Balay 21db781477SPatrick Sanan .seealso: `PetscGetRelativePath()` 22e5c89e4eSSatish Balay @*/ 23d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscGetFullPath(const char path[], char fullpath[], size_t flen) 24d71ae5a4SJacob Faibussowitsch { 25e5c89e4eSSatish Balay size_t ln; 26ace3abfcSBarry Smith PetscBool flg; 27e5c89e4eSSatish Balay 28e5c89e4eSSatish Balay PetscFunctionBegin; 29e5c89e4eSSatish Balay if (path[0] == '/') { 309566063dSJacob Faibussowitsch PetscCall(PetscStrncmp("/tmp_mnt/", path, 9, &flg)); 319566063dSJacob Faibussowitsch if (flg) PetscCall(PetscStrncpy(fullpath, path + 8, flen)); 329566063dSJacob Faibussowitsch else PetscCall(PetscStrncpy(fullpath, path, flen)); 336c8deb01SJed Brown fullpath[flen - 1] = 0; 343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35e5c89e4eSSatish Balay } 369483a8a2SBarry Smith if (path[0] == '.' && path[1] == '/') { 379483a8a2SBarry Smith PetscCall(PetscGetWorkingDirectory(fullpath, flen)); 389483a8a2SBarry Smith PetscCall(PetscStrlcat(fullpath, path + 1, flen)); 393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 409483a8a2SBarry Smith } 41e5c89e4eSSatish Balay 429566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(fullpath, path, flen)); 436c8deb01SJed Brown fullpath[flen - 1] = 0; 44e5c89e4eSSatish Balay /* Remove the various "special" forms (~username/ and ~/) */ 45e5c89e4eSSatish Balay if (fullpath[0] == '~') { 4645082d64SJed Brown char tmppath[PETSC_MAX_PATH_LEN], *rest; 47e5c89e4eSSatish Balay if (fullpath[1] == '/') { 489566063dSJacob Faibussowitsch PetscCall(PetscGetHomeDirectory(tmppath, PETSC_MAX_PATH_LEN)); 4945082d64SJed Brown rest = fullpath + 2; 50e5c89e4eSSatish Balay } else { 5145082d64SJed Brown #if defined(PETSC_HAVE_PWD_H) 5245082d64SJed Brown struct passwd *pwde; 53e5c89e4eSSatish Balay char *p, *name; 54e5c89e4eSSatish Balay 55e5c89e4eSSatish Balay /* Find username */ 56e5c89e4eSSatish Balay name = fullpath + 1; 57e5c89e4eSSatish Balay p = name; 58e5c89e4eSSatish Balay while (*p && *p != '/') p++; 5945082d64SJed Brown *p = 0; 6045082d64SJed Brown rest = p + 1; 61e5c89e4eSSatish Balay pwde = getpwnam(name); 623ba16761SJacob Faibussowitsch if (!pwde) PetscFunctionReturn(PETSC_SUCCESS); 63e5c89e4eSSatish Balay 64c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(tmppath, pwde->pw_dir, sizeof(tmppath))); 6545082d64SJed Brown #else 663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6745082d64SJed Brown #endif 6845082d64SJed Brown } 699566063dSJacob Faibussowitsch PetscCall(PetscStrlen(tmppath, &ln)); 70c6a7a370SJeremy L Thompson if (tmppath[ln - 1] != '/') PetscCall(PetscStrlcat(tmppath + ln - 1, "/", sizeof(tmppath) - ln + 1)); 71c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(tmppath, rest, sizeof(tmppath))); 729566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(fullpath, tmppath, flen)); 736c8deb01SJed Brown fullpath[flen - 1] = 0; 746c8deb01SJed Brown } else { 759566063dSJacob Faibussowitsch PetscCall(PetscGetWorkingDirectory(fullpath, flen)); 769566063dSJacob Faibussowitsch PetscCall(PetscStrlen(fullpath, &ln)); 779566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(fullpath + ln, "/", flen - ln)); 786c8deb01SJed Brown fullpath[flen - 1] = 0; 799566063dSJacob Faibussowitsch PetscCall(PetscStrlen(fullpath, &ln)); 806c8deb01SJed Brown if (path[0] == '.' && path[1] == '/') { 819566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(fullpath, path + 2, flen)); 826c8deb01SJed Brown } else { 839566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(fullpath, path, flen)); 84e5c89e4eSSatish Balay } 856c8deb01SJed Brown fullpath[flen - 1] = 0; 866c8deb01SJed Brown } 876c8deb01SJed Brown 88e5c89e4eSSatish Balay /* Remove the automounter part of the path */ 899566063dSJacob Faibussowitsch PetscCall(PetscStrncmp(fullpath, "/tmp_mnt/", 9, &flg)); 90e5c89e4eSSatish Balay if (flg) { 91e5c89e4eSSatish Balay char tmppath[PETSC_MAX_PATH_LEN]; 92c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(tmppath, fullpath + 8, sizeof(tmppath))); 93c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(fullpath, tmppath, flen)); 94e5c89e4eSSatish Balay } 95e5c89e4eSSatish Balay /* We could try to handle things like the removal of .. etc */ 963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 97e5c89e4eSSatish Balay } 98