Actual source code: fpath.c

  1: #include <petscsys.h>
  2: #if defined(PETSC_HAVE_PWD_H)
  3:   #include <pwd.h>
  4: #endif

  6: /*@C
  7:   PetscGetFullPath - Given a filename, returns the fully qualified file name.

  9:   Not Collective

 11:   Input Parameters:
 12: + path - pathname to qualify
 13: - flen - size of `fullpath`

 15:   Output Parameter:
 16: . fullpath - buffer to hold the full pathname

 18:   Level: developer

 20:   Note:
 21:   Converts `~username/` and `~/` to appropriate forms

 23:   Developer Note:
 24:   On Microsoft Windows full paths may begin with DriveLetter\: so these must be properly handled

 26: .seealso: `PetscGetRelativePath()`
 27: @*/
 28: PetscErrorCode PetscGetFullPath(const char path[], char fullpath[], size_t flen)
 29: {
 30:   size_t    ln;
 31:   PetscBool flg;

 33:   PetscFunctionBegin;
 34:   if (path[0] == '/') {
 35:     PetscCall(PetscStrncmp("/tmp_mnt/", path, 9, &flg));
 36:     if (flg) PetscCall(PetscStrncpy(fullpath, path + 8, flen));
 37:     else PetscCall(PetscStrncpy(fullpath, path, flen));
 38:     fullpath[flen - 1] = 0;
 39:     PetscFunctionReturn(PETSC_SUCCESS);
 40:   }
 41: #if defined(PETSC_HAVE_WINDOWS_H)
 42:   if (path[1] == ':') {
 43:     PetscCall(PetscStrncpy(fullpath, path, flen));
 44:     PetscFunctionReturn(PETSC_SUCCESS);
 45:   }
 46: #endif
 47:   if (path[0] == '.' && path[1] == '/') {
 48:     PetscCall(PetscGetWorkingDirectory(fullpath, flen));
 49:     PetscCall(PetscStrlcat(fullpath, path + 1, flen));
 50:     PetscFunctionReturn(PETSC_SUCCESS);
 51:   }

 53:   PetscCall(PetscStrncpy(fullpath, path, flen));
 54:   fullpath[flen - 1] = 0;
 55:   /* Remove the various "special" forms (~username/ and ~/) */
 56:   if (fullpath[0] == '~') {
 57:     char tmppath[PETSC_MAX_PATH_LEN], *rest;
 58:     if (fullpath[1] == '/') {
 59:       PetscCall(PetscGetHomeDirectory(tmppath, PETSC_MAX_PATH_LEN));
 60:       rest = fullpath + 2;
 61:     } else {
 62: #if defined(PETSC_HAVE_PWD_H)
 63:       struct passwd *pwde;
 64:       char          *p, *name;

 66:       /* Find username */
 67:       name = fullpath + 1;
 68:       p    = name;
 69:       while (*p && *p != '/') p++;
 70:       *p   = 0;
 71:       rest = p + 1;
 72:       pwde = getpwnam(name);
 73:       if (!pwde) PetscFunctionReturn(PETSC_SUCCESS);

 75:       PetscCall(PetscStrncpy(tmppath, pwde->pw_dir, sizeof(tmppath)));
 76: #else
 77:       PetscFunctionReturn(PETSC_SUCCESS);
 78: #endif
 79:     }
 80:     PetscCall(PetscStrlen(tmppath, &ln));
 81:     if (tmppath[ln - 1] != '/') PetscCall(PetscStrlcat(tmppath + ln - 1, "/", sizeof(tmppath) - ln + 1));
 82:     PetscCall(PetscStrlcat(tmppath, rest, sizeof(tmppath)));
 83:     PetscCall(PetscStrncpy(fullpath, tmppath, flen));
 84:     fullpath[flen - 1] = 0;
 85:   } else {
 86:     PetscCall(PetscGetWorkingDirectory(fullpath, flen));
 87:     PetscCall(PetscStrlen(fullpath, &ln));
 88:     PetscCall(PetscStrncpy(fullpath + ln, "/", flen - ln));
 89:     fullpath[flen - 1] = 0;
 90:     PetscCall(PetscStrlen(fullpath, &ln));
 91:     if (path[0] == '.' && path[1] == '/') {
 92:       PetscCall(PetscStrlcat(fullpath, path + 2, flen));
 93:     } else {
 94:       PetscCall(PetscStrlcat(fullpath, path, flen));
 95:     }
 96:     fullpath[flen - 1] = 0;
 97:   }

 99:   /* Remove the automounter part of the path */
100:   PetscCall(PetscStrncmp(fullpath, "/tmp_mnt/", 9, &flg));
101:   if (flg) {
102:     char tmppath[PETSC_MAX_PATH_LEN];
103:     PetscCall(PetscStrncpy(tmppath, fullpath + 8, sizeof(tmppath)));
104:     PetscCall(PetscStrncpy(fullpath, tmppath, flen));
105:   }
106:   /* We could try to handle things like the removal of .. etc */
107:   PetscFunctionReturn(PETSC_SUCCESS);
108: }