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: .  fullpath - pointer to buffer to hold full pathname
 15: -  flen     - size of fullpath

 17:    Level: developer

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

 26:   PetscFunctionBegin;
 27:   if (path[0] == '/') {
 28:     PetscCall(PetscStrncmp("/tmp_mnt/", path, 9, &flg));
 29:     if (flg) PetscCall(PetscStrncpy(fullpath, path + 8, flen));
 30:     else PetscCall(PetscStrncpy(fullpath, path, flen));
 31:     fullpath[flen - 1] = 0;
 32:     PetscFunctionReturn(PETSC_SUCCESS);
 33:   }
 34:   if (path[0] == '.' && path[1] == '/') {
 35:     PetscCall(PetscGetWorkingDirectory(fullpath, flen));
 36:     PetscCall(PetscStrlcat(fullpath, path + 1, flen));
 37:     PetscFunctionReturn(PETSC_SUCCESS);
 38:   }

 40:   PetscCall(PetscStrncpy(fullpath, path, flen));
 41:   fullpath[flen - 1] = 0;
 42:   /* Remove the various "special" forms (~username/ and ~/) */
 43:   if (fullpath[0] == '~') {
 44:     char tmppath[PETSC_MAX_PATH_LEN], *rest;
 45:     if (fullpath[1] == '/') {
 46:       PetscCall(PetscGetHomeDirectory(tmppath, PETSC_MAX_PATH_LEN));
 47:       rest = fullpath + 2;
 48:     } else {
 49: #if defined(PETSC_HAVE_PWD_H)
 50:       struct passwd *pwde;
 51:       char          *p, *name;

 53:       /* Find username */
 54:       name = fullpath + 1;
 55:       p    = name;
 56:       while (*p && *p != '/') p++;
 57:       *p   = 0;
 58:       rest = p + 1;
 59:       pwde = getpwnam(name);
 60:       if (!pwde) PetscFunctionReturn(PETSC_SUCCESS);

 62:       PetscCall(PetscStrcpy(tmppath, pwde->pw_dir));
 63: #else
 64:       PetscFunctionReturn(PETSC_SUCCESS);
 65: #endif
 66:     }
 67:     PetscCall(PetscStrlen(tmppath, &ln));
 68:     if (tmppath[ln - 1] != '/') PetscCall(PetscStrcat(tmppath + ln - 1, "/"));
 69:     PetscCall(PetscStrcat(tmppath, rest));
 70:     PetscCall(PetscStrncpy(fullpath, tmppath, flen));
 71:     fullpath[flen - 1] = 0;
 72:   } else {
 73:     PetscCall(PetscGetWorkingDirectory(fullpath, flen));
 74:     PetscCall(PetscStrlen(fullpath, &ln));
 75:     PetscCall(PetscStrncpy(fullpath + ln, "/", flen - ln));
 76:     fullpath[flen - 1] = 0;
 77:     PetscCall(PetscStrlen(fullpath, &ln));
 78:     if (path[0] == '.' && path[1] == '/') {
 79:       PetscCall(PetscStrlcat(fullpath, path + 2, flen));
 80:     } else {
 81:       PetscCall(PetscStrlcat(fullpath, path, flen));
 82:     }
 83:     fullpath[flen - 1] = 0;
 84:   }

 86:   /* Remove the automounter part of the path */
 87:   PetscCall(PetscStrncmp(fullpath, "/tmp_mnt/", 9, &flg));
 88:   if (flg) {
 89:     char tmppath[PETSC_MAX_PATH_LEN];
 90:     PetscCall(PetscStrcpy(tmppath, fullpath + 8));
 91:     PetscCall(PetscStrcpy(fullpath, tmppath));
 92:   }
 93:   /* We could try to handle things like the removal of .. etc */
 94:   PetscFunctionReturn(PETSC_SUCCESS);
 95: }