xref: /petsc/src/sys/fileio/fpath.c (revision 7a5338279d92d13360d231b9bd26d284f35eaa49)
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