xref: /petsc/src/sys/fileio/fpath.c (revision 69f65dfb176f3d3e756fc44d2300fd6791726976)
1 
2 #include <petscsys.h>
3 #if defined(PETSC_HAVE_PWD_H)
4   #include <pwd.h>
5 #endif
6 
7 /*@C
8    PetscGetFullPath - Given a filename, returns the fully qualified file name.
9 
10    Not Collective
11 
12    Input Parameters:
13 +  path     - pathname to qualify
14 .  fullpath - pointer to buffer to hold full pathname
15 -  flen     - size of fullpath
16 
17    Level: developer
18 
19 .seealso: `PetscGetRelativePath()`
20 @*/
21 PetscErrorCode PetscGetFullPath(const char path[], char fullpath[], size_t flen)
22 {
23   size_t    ln;
24   PetscBool flg;
25 
26   PetscFunctionBegin;
27   if (path[0] == '/') {
28     PetscCall(PetscStrncmp("/tmp_mnt/", path, 9, &flg));
29     if (flg) PetscCall(PetscStrncpy(fullpath, path + 8, flen));
30     else PetscCall(PetscStrncpy(fullpath, path, flen));
31     fullpath[flen - 1] = 0;
32     PetscFunctionReturn(PETSC_SUCCESS);
33   }
34   if (path[0] == '.' && path[1] == '/') {
35     PetscCall(PetscGetWorkingDirectory(fullpath, flen));
36     PetscCall(PetscStrlcat(fullpath, path + 1, flen));
37     PetscFunctionReturn(PETSC_SUCCESS);
38   }
39 
40   PetscCall(PetscStrncpy(fullpath, path, flen));
41   fullpath[flen - 1] = 0;
42   /* Remove the various "special" forms (~username/ and ~/) */
43   if (fullpath[0] == '~') {
44     char tmppath[PETSC_MAX_PATH_LEN], *rest;
45     if (fullpath[1] == '/') {
46       PetscCall(PetscGetHomeDirectory(tmppath, PETSC_MAX_PATH_LEN));
47       rest = fullpath + 2;
48     } else {
49 #if defined(PETSC_HAVE_PWD_H)
50       struct passwd *pwde;
51       char          *p, *name;
52 
53       /* Find username */
54       name = fullpath + 1;
55       p    = name;
56       while (*p && *p != '/') p++;
57       *p   = 0;
58       rest = p + 1;
59       pwde = getpwnam(name);
60       if (!pwde) PetscFunctionReturn(PETSC_SUCCESS);
61 
62       PetscCall(PetscStrncpy(tmppath, pwde->pw_dir, sizeof(tmppath)));
63 #else
64       PetscFunctionReturn(PETSC_SUCCESS);
65 #endif
66     }
67     PetscCall(PetscStrlen(tmppath, &ln));
68     if (tmppath[ln - 1] != '/') PetscCall(PetscStrlcat(tmppath + ln - 1, "/", sizeof(tmppath) - ln + 1));
69     PetscCall(PetscStrlcat(tmppath, rest, sizeof(tmppath)));
70     PetscCall(PetscStrncpy(fullpath, tmppath, flen));
71     fullpath[flen - 1] = 0;
72   } else {
73     PetscCall(PetscGetWorkingDirectory(fullpath, flen));
74     PetscCall(PetscStrlen(fullpath, &ln));
75     PetscCall(PetscStrncpy(fullpath + ln, "/", flen - ln));
76     fullpath[flen - 1] = 0;
77     PetscCall(PetscStrlen(fullpath, &ln));
78     if (path[0] == '.' && path[1] == '/') {
79       PetscCall(PetscStrlcat(fullpath, path + 2, flen));
80     } else {
81       PetscCall(PetscStrlcat(fullpath, path, flen));
82     }
83     fullpath[flen - 1] = 0;
84   }
85 
86   /* Remove the automounter part of the path */
87   PetscCall(PetscStrncmp(fullpath, "/tmp_mnt/", 9, &flg));
88   if (flg) {
89     char tmppath[PETSC_MAX_PATH_LEN];
90     PetscCall(PetscStrncpy(tmppath, fullpath + 8, sizeof(tmppath)));
91     PetscCall(PetscStrncpy(fullpath, tmppath, flen));
92   }
93   /* We could try to handle things like the removal of .. etc */
94   PetscFunctionReturn(PETSC_SUCCESS);
95 }
96