xref: /petsc/src/sys/fileio/fpath.c (revision 58d68138c660dfb4e9f5b03334792cd4f2ffd7cc)
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   size_t    ln;
23   PetscBool flg;
24 
25   PetscFunctionBegin;
26   if (path[0] == '/') {
27     PetscCall(PetscStrncmp("/tmp_mnt/", path, 9, &flg));
28     if (flg) PetscCall(PetscStrncpy(fullpath, path + 8, flen));
29     else PetscCall(PetscStrncpy(fullpath, path, flen));
30     fullpath[flen - 1] = 0;
31     PetscFunctionReturn(0);
32   }
33   if (path[0] == '.' && path[1] == '/') {
34     PetscCall(PetscGetWorkingDirectory(fullpath, flen));
35     PetscCall(PetscStrlcat(fullpath, path + 1, flen));
36     PetscFunctionReturn(0);
37   }
38 
39   PetscCall(PetscStrncpy(fullpath, path, flen));
40   fullpath[flen - 1] = 0;
41   /* Remove the various "special" forms (~username/ and ~/) */
42   if (fullpath[0] == '~') {
43     char tmppath[PETSC_MAX_PATH_LEN], *rest;
44     if (fullpath[1] == '/') {
45       PetscCall(PetscGetHomeDirectory(tmppath, PETSC_MAX_PATH_LEN));
46       rest = fullpath + 2;
47     } else {
48 #if defined(PETSC_HAVE_PWD_H)
49       struct passwd *pwde;
50       char          *p, *name;
51 
52       /* Find username */
53       name = fullpath + 1;
54       p    = name;
55       while (*p && *p != '/') p++;
56       *p   = 0;
57       rest = p + 1;
58       pwde = getpwnam(name);
59       if (!pwde) PetscFunctionReturn(0);
60 
61       PetscCall(PetscStrcpy(tmppath, pwde->pw_dir));
62 #else
63       PetscFunctionReturn(0);
64 #endif
65     }
66     PetscCall(PetscStrlen(tmppath, &ln));
67     if (tmppath[ln - 1] != '/') PetscCall(PetscStrcat(tmppath + ln - 1, "/"));
68     PetscCall(PetscStrcat(tmppath, rest));
69     PetscCall(PetscStrncpy(fullpath, tmppath, flen));
70     fullpath[flen - 1] = 0;
71   } else {
72     PetscCall(PetscGetWorkingDirectory(fullpath, flen));
73     PetscCall(PetscStrlen(fullpath, &ln));
74     PetscCall(PetscStrncpy(fullpath + ln, "/", flen - ln));
75     fullpath[flen - 1] = 0;
76     PetscCall(PetscStrlen(fullpath, &ln));
77     if (path[0] == '.' && path[1] == '/') {
78       PetscCall(PetscStrlcat(fullpath, path + 2, flen));
79     } else {
80       PetscCall(PetscStrlcat(fullpath, path, flen));
81     }
82     fullpath[flen - 1] = 0;
83   }
84 
85   /* Remove the automounter part of the path */
86   PetscCall(PetscStrncmp(fullpath, "/tmp_mnt/", 9, &flg));
87   if (flg) {
88     char tmppath[PETSC_MAX_PATH_LEN];
89     PetscCall(PetscStrcpy(tmppath, fullpath + 8));
90     PetscCall(PetscStrcpy(fullpath, tmppath));
91   }
92   /* We could try to handle things like the removal of .. etc */
93   PetscFunctionReturn(0);
94 }
95