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 @*/
PetscGetFullPath(const char path[],char fullpath[],size_t flen)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