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