Actual source code: fpath.c


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

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

 10:    Not Collective

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

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

 19:    Level: developer

 21: .seealso: `PetscGetRelativePath()`
 22: @*/
 23: PetscErrorCode PetscGetFullPath(const char path[], char fullpath[], size_t flen)
 24: {
 25:   size_t    ln;
 26:   PetscBool flg;

 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:   }

 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;

 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);

 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:   }

 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: }