xref: /petsc/src/sys/fileio/grpath.c (revision bce096a405b23f07feb1783633a56a7a90eceb89)
1 #define PETSC_DLL
2 
3 #include "petsc.h"
4 #include "petscsys.h"
5 #if defined(PETSC_HAVE_PWD_H)
6 #include <pwd.h>
7 #endif
8 #include <ctype.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #if defined(PETSC_HAVE_UNISTD_H)
12 #include <unistd.h>
13 #endif
14 #if defined(PETSC_HAVE_STDLIB_H)
15 #include <stdlib.h>
16 #endif
17 #if defined(PETSC_HAVE_SYS_UTSNAME_H)
18 #include <sys/utsname.h>
19 #endif
20 #if defined(PETSC_HAVE_SYS_SYSTEMINFO_H)
21 #include <sys/systeminfo.h>
22 #endif
23 #include "petscfix.h"
24 
25 #undef __FUNCT__
26 #define __FUNCT__ "PetscGetRealPath"
27 /*@C
28    PetscGetRealPath - Get the path without symbolic links etc. and in absolute form.
29 
30    Not Collective
31 
32    Input Parameter:
33 .  path - path to resolve
34 
35    Output Parameter:
36 .  rpath - resolved path
37 
38    Level: developer
39 
40    Notes:
41    rpath is assumed to be of length PETSC_MAX_PATH_LEN.
42 
43    Systems that use the automounter often generate absolute paths
44    of the form "/tmp_mnt....".  However, the automounter will fail to
45    mount this path if it is not already mounted, so we remove this from
46    the head of the line.  This may cause problems if, for some reason,
47    /tmp_mnt is valid and not the result of the automounter.
48 
49    Concepts: real path
50    Concepts: path^real
51 
52 .seealso: PetscGetFullPath()
53 @*/
54 PetscErrorCode PETSC_DLLEXPORT PetscGetRealPath(char path[],char rpath[])
55 {
56   PetscErrorCode ierr;
57   char           tmp3[PETSC_MAX_PATH_LEN];
58   PetscTruth     flg;
59 #if !defined(PETSC_HAVE_REALPATH) && defined(PETSC_HAVE_READLINK)
60   char           tmp1[PETSC_MAX_PATH_LEN],tmp4[PETSC_MAX_PATH_LEN],*tmp2;
61   size_t         N,len,len1,len2;
62   int            n,m;
63 #endif
64 
65   PetscFunctionBegin;
66 #if defined(PETSC_HAVE_REALPATH)
67   realpath(path,rpath);
68 #elif defined(PETSC_HAVE_READLINK)
69   /* Algorithm: we move through the path, replacing links with the real paths.   */
70   ierr = PetscStrcpy(rpath,path);CHKERRQ(ierr);
71   ierr = PetscStrlen(rpath,&N);CHKERRQ(ierr);
72   while (N) {
73     ierr = PetscStrncpy(tmp1,rpath,N);CHKERRQ(ierr);
74     tmp1[N] = 0;
75     n = readlink(tmp1,tmp3,PETSC_MAX_PATH_LEN);
76     if (n > 0) {
77       tmp3[n] = 0; /* readlink does not automatically add 0 to string end */
78       if (tmp3[0] != '/') {
79         ierr = PetscStrchr(tmp1,'/',&tmp2);CHKERRQ(ierr);
80         ierr = PetscStrlen(tmp1,&len1);CHKERRQ(ierr);
81         ierr = PetscStrlen(tmp2,&len2);CHKERRQ(ierr);
82         m    = len1 - len2;
83         ierr = PetscStrncpy(tmp4,tmp1,m);CHKERRQ(ierr);
84         tmp4[m] = 0;
85         ierr = PetscStrlen(tmp4,&len);CHKERRQ(ierr);
86         ierr = PetscStrncat(tmp4,"/",PETSC_MAX_PATH_LEN - len);CHKERRQ(ierr);
87         ierr = PetscStrlen(tmp4,&len);CHKERRQ(ierr);
88         ierr = PetscStrncat(tmp4,tmp3,PETSC_MAX_PATH_LEN - len);CHKERRQ(ierr);
89         ierr = PetscGetRealPath(tmp4,rpath);CHKERRQ(ierr);
90         ierr = PetscStrlen(rpath,&len);CHKERRQ(ierr);
91         ierr = PetscStrncat(rpath,path+N,PETSC_MAX_PATH_LEN - len);CHKERRQ(ierr);
92       } else {
93         ierr = PetscGetRealPath(tmp3,tmp1);CHKERRQ(ierr);
94         ierr = PetscStrncpy(rpath,tmp1,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
95         ierr = PetscStrlen(rpath,&len);CHKERRQ(ierr);
96         ierr = PetscStrncat(rpath,path+N,PETSC_MAX_PATH_LEN - len);CHKERRQ(ierr);
97       }
98       PetscFunctionReturn(0);
99     }
100     ierr = PetscStrchr(tmp1,'/',&tmp2);CHKERRQ(ierr);
101     if (tmp2) {
102       ierr = PetscStrlen(tmp1,&len1);CHKERRQ(ierr);
103       ierr = PetscStrlen(tmp2,&len2);CHKERRQ(ierr);
104       N    = len1 - len2;
105     } else {
106       ierr = PetscStrlen(tmp1,&N);CHKERRQ(ierr);
107     }
108   }
109   ierr = PetscStrncpy(rpath,path,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
110 #else /* Just punt */
111   ierr = PetscStrcpy(rpath,path);CHKERRQ(ierr);
112 #endif
113 
114   /* remove garbage some automounters put at the beginning of the path */
115   ierr = PetscStrncmp("/tmp_mnt/",rpath,9,&flg);CHKERRQ(ierr);
116   if (flg) {
117     ierr = PetscStrcpy(tmp3,rpath + 8);CHKERRQ(ierr);
118     ierr = PetscStrcpy(rpath,tmp3);CHKERRQ(ierr);
119   }
120   PetscFunctionReturn(0);
121 }
122