Actual source code: grpath.c

  1: #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for realpath() */
  2: #include <petscsys.h>
  3: #if defined(PETSC_HAVE_PWD_H)
  4: #include <pwd.h>
  5: #endif
  6: #include <ctype.h>
  7: #include <sys/stat.h>
  8: #if defined(PETSC_HAVE_UNISTD_H)
  9: #include <unistd.h>
 10: #endif
 11: #if defined(PETSC_HAVE_SYS_UTSNAME_H)
 12: #include <sys/utsname.h>
 13: #endif
 14: #if defined(PETSC_HAVE_SYS_SYSTEMINFO_H)
 15: #include <sys/systeminfo.h>
 16: #endif

 18: /*@C
 19:    PetscGetRealPath - Get the path without symbolic links etc. and in absolute form.

 21:    Not Collective

 23:    Input Parameter:
 24: .  path - path to resolve

 26:    Output Parameter:
 27: .  rpath - resolved path

 29:    Level: developer

 31:    Notes:
 32:    rpath is assumed to be of length PETSC_MAX_PATH_LEN.

 34:    Systems that use the automounter often generate absolute paths
 35:    of the form "/tmp_mnt....".  However, the automounter will fail to
 36:    mount this path if it is not already mounted, so we remove this from
 37:    the head of the line.  This may cause problems if, for some reason,
 38:    /tmp_mnt is valid and not the result of the automounter.

 40: .seealso: PetscGetFullPath()
 41: @*/
 42: PetscErrorCode  PetscGetRealPath(const char path[],char rpath[])
 43: {
 45:   char           tmp3[PETSC_MAX_PATH_LEN];
 46:   PetscBool      flg;
 47: #if !defined(PETSC_HAVE_REALPATH) && defined(PETSC_HAVE_READLINK)
 48:   char           tmp1[PETSC_MAX_PATH_LEN],tmp4[PETSC_MAX_PATH_LEN],*tmp2;
 49:   size_t         N,len,len1,len2;
 50:   int            n,m;
 51: #endif

 54: #if defined(PETSC_HAVE_REALPATH)
 55:   if (!realpath(path,rpath)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"realpath()");
 56: #elif defined(PETSC_HAVE_READLINK)
 57:   /* Algorithm: we move through the path, replacing links with the real paths.   */
 58:   PetscStrcpy(rpath,path);
 59:   PetscStrlen(rpath,&N);
 60:   while (N) {
 61:     PetscStrncpy(tmp1,rpath,N);
 62:     tmp1[N] = 0;
 63:     n       = readlink(tmp1,tmp3,PETSC_MAX_PATH_LEN);
 64:     if (n > 0) {
 65:       tmp3[n] = 0; /* readlink does not automatically add 0 to string end */
 66:       if (tmp3[0] != '/') {
 67:         PetscStrchr(tmp1,'/',&tmp2);
 68:         PetscStrlen(tmp1,&len1);
 69:         PetscStrlen(tmp2,&len2);
 70:         m       = len1 - len2;
 71:         PetscStrncpy(tmp4,tmp1,m);
 72:         tmp4[m] = 0;
 73:         PetscStrlen(tmp4,&len);
 74:         PetscStrlcat(tmp4,"/",PETSC_MAX_PATH_LEN);
 75:         PetscStrlcat(tmp4,tmp3,PETSC_MAX_PATH_LEN);
 76:         PetscGetRealPath(tmp4,rpath);
 77:         PetscStrlcat(rpath,path+N,PETSC_MAX_PATH_LEN);
 78:       } else {
 79:         PetscGetRealPath(tmp3,tmp1);
 80:         PetscStrncpy(rpath,tmp1,PETSC_MAX_PATH_LEN);
 81:         PetscStrlcat(rpath,path+N,PETSC_MAX_PATH_LEN);
 82:       }
 83:       return(0);
 84:     }
 85:     PetscStrchr(tmp1,'/',&tmp2);
 86:     if (tmp2) {
 87:       PetscStrlen(tmp1,&len1);
 88:       PetscStrlen(tmp2,&len2);
 89:       N    = len1 - len2;
 90:     } else {
 91:       PetscStrlen(tmp1,&N);
 92:     }
 93:   }
 94:   PetscStrncpy(rpath,path,PETSC_MAX_PATH_LEN);
 95: #else /* Just punt */
 96:   PetscStrcpy(rpath,path);
 97: #endif

 99:   /* remove garbage some automounters put at the beginning of the path */
100:   PetscStrncmp("/tmp_mnt/",rpath,9,&flg);
101:   if (flg) {
102:     PetscStrcpy(tmp3,rpath + 8);
103:     PetscStrcpy(rpath,tmp3);
104:   }
105:   return(0);
106: }