xref: /petsc/src/sys/fileio/fpath.c (revision 7255af2bd2331935c12adb05db5efab3771c4d24)
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 
20*7255af2bSBarry Smith   Note:
21*7255af2bSBarry Smith   Converts `~username/` and `~/` to appropriate forms
22*7255af2bSBarry Smith 
23db781477SPatrick Sanan .seealso: `PetscGetRelativePath()`
24e5c89e4eSSatish Balay @*/
25d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscGetFullPath(const char path[], char fullpath[], size_t flen)
26d71ae5a4SJacob Faibussowitsch {
27e5c89e4eSSatish Balay   size_t    ln;
28ace3abfcSBarry Smith   PetscBool flg;
29e5c89e4eSSatish Balay 
30e5c89e4eSSatish Balay   PetscFunctionBegin;
31e5c89e4eSSatish Balay   if (path[0] == '/') {
329566063dSJacob Faibussowitsch     PetscCall(PetscStrncmp("/tmp_mnt/", path, 9, &flg));
339566063dSJacob Faibussowitsch     if (flg) PetscCall(PetscStrncpy(fullpath, path + 8, flen));
349566063dSJacob Faibussowitsch     else PetscCall(PetscStrncpy(fullpath, path, flen));
356c8deb01SJed Brown     fullpath[flen - 1] = 0;
363ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
37e5c89e4eSSatish Balay   }
389483a8a2SBarry Smith   if (path[0] == '.' && path[1] == '/') {
399483a8a2SBarry Smith     PetscCall(PetscGetWorkingDirectory(fullpath, flen));
409483a8a2SBarry Smith     PetscCall(PetscStrlcat(fullpath, path + 1, flen));
413ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
429483a8a2SBarry Smith   }
43e5c89e4eSSatish Balay 
449566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(fullpath, path, flen));
456c8deb01SJed Brown   fullpath[flen - 1] = 0;
46e5c89e4eSSatish Balay   /* Remove the various "special" forms (~username/ and ~/) */
47e5c89e4eSSatish Balay   if (fullpath[0] == '~') {
4845082d64SJed Brown     char tmppath[PETSC_MAX_PATH_LEN], *rest;
49e5c89e4eSSatish Balay     if (fullpath[1] == '/') {
509566063dSJacob Faibussowitsch       PetscCall(PetscGetHomeDirectory(tmppath, PETSC_MAX_PATH_LEN));
5145082d64SJed Brown       rest = fullpath + 2;
52e5c89e4eSSatish Balay     } else {
5345082d64SJed Brown #if defined(PETSC_HAVE_PWD_H)
5445082d64SJed Brown       struct passwd *pwde;
55e5c89e4eSSatish Balay       char          *p, *name;
56e5c89e4eSSatish Balay 
57e5c89e4eSSatish Balay       /* Find username */
58e5c89e4eSSatish Balay       name = fullpath + 1;
59e5c89e4eSSatish Balay       p    = name;
60e5c89e4eSSatish Balay       while (*p && *p != '/') p++;
6145082d64SJed Brown       *p   = 0;
6245082d64SJed Brown       rest = p + 1;
63e5c89e4eSSatish Balay       pwde = getpwnam(name);
643ba16761SJacob Faibussowitsch       if (!pwde) PetscFunctionReturn(PETSC_SUCCESS);
65e5c89e4eSSatish Balay 
66c6a7a370SJeremy L Thompson       PetscCall(PetscStrncpy(tmppath, pwde->pw_dir, sizeof(tmppath)));
6745082d64SJed Brown #else
683ba16761SJacob Faibussowitsch       PetscFunctionReturn(PETSC_SUCCESS);
6945082d64SJed Brown #endif
7045082d64SJed Brown     }
719566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(tmppath, &ln));
72c6a7a370SJeremy L Thompson     if (tmppath[ln - 1] != '/') PetscCall(PetscStrlcat(tmppath + ln - 1, "/", sizeof(tmppath) - ln + 1));
73c6a7a370SJeremy L Thompson     PetscCall(PetscStrlcat(tmppath, rest, sizeof(tmppath)));
749566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(fullpath, tmppath, flen));
756c8deb01SJed Brown     fullpath[flen - 1] = 0;
766c8deb01SJed Brown   } else {
779566063dSJacob Faibussowitsch     PetscCall(PetscGetWorkingDirectory(fullpath, flen));
789566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(fullpath, &ln));
799566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(fullpath + ln, "/", flen - ln));
806c8deb01SJed Brown     fullpath[flen - 1] = 0;
819566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(fullpath, &ln));
826c8deb01SJed Brown     if (path[0] == '.' && path[1] == '/') {
839566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(fullpath, path + 2, flen));
846c8deb01SJed Brown     } else {
859566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(fullpath, path, flen));
86e5c89e4eSSatish Balay     }
876c8deb01SJed Brown     fullpath[flen - 1] = 0;
886c8deb01SJed Brown   }
896c8deb01SJed Brown 
90e5c89e4eSSatish Balay   /* Remove the automounter part of the path */
919566063dSJacob Faibussowitsch   PetscCall(PetscStrncmp(fullpath, "/tmp_mnt/", 9, &flg));
92e5c89e4eSSatish Balay   if (flg) {
93e5c89e4eSSatish Balay     char tmppath[PETSC_MAX_PATH_LEN];
94c6a7a370SJeremy L Thompson     PetscCall(PetscStrncpy(tmppath, fullpath + 8, sizeof(tmppath)));
95c6a7a370SJeremy L Thompson     PetscCall(PetscStrncpy(fullpath, tmppath, flen));
96e5c89e4eSSatish Balay   }
97e5c89e4eSSatish Balay   /* We could try to handle things like the removal of .. etc */
983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
99e5c89e4eSSatish Balay }
100