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