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