xref: /petsc/src/sys/fileio/fpath.c (revision 45082d6442ec9e1b1f93dc9865927cf3ea3aa1d4)
1 
2 /*
3       Code for opening and closing files.
4 */
5 #include <petscsys.h>
6 #if defined(PETSC_HAVE_PWD_H)
7 #include <pwd.h>
8 #endif
9 #include <ctype.h>
10 #include <sys/stat.h>
11 #if defined(PETSC_HAVE_UNISTD_H)
12 #include <unistd.h>
13 #endif
14 #if defined(PETSC_HAVE_SYS_UTSNAME_H)
15 #include <sys/utsname.h>
16 #endif
17 #include <fcntl.h>
18 #if defined(PETSC_HAVE_SYS_SYSTEMINFO_H)
19 #include <sys/systeminfo.h>
20 #endif
21 
22 #undef __FUNCT__
23 #define __FUNCT__ "PetscGetFullPath"
24 /*@C
25    PetscGetFullPath - Given a filename, returns the fully qualified file name.
26 
27    Not Collective
28 
29    Input Parameters:
30 +  path     - pathname to qualify
31 .  fullpath - pointer to buffer to hold full pathname
32 -  flen     - size of fullpath
33 
34    Level: developer
35 
36    Concepts: full path
37    Concepts: path^full
38 
39 .seealso: PetscGetRelativePath()
40 @*/
41 PetscErrorCode  PetscGetFullPath(const char path[],char fullpath[],size_t flen)
42 {
43   PetscErrorCode ierr;
44   size_t         ln;
45   PetscBool      flg;
46 
47   PetscFunctionBegin;
48   if (path[0] == '/') {
49     ierr = PetscStrncmp("/tmp_mnt/",path,9,&flg);CHKERRQ(ierr);
50     if (flg) {ierr = PetscStrncpy(fullpath,path + 8,flen);CHKERRQ(ierr);}
51     else     {ierr = PetscStrncpy(fullpath,path,flen);CHKERRQ(ierr);}
52     PetscFunctionReturn(0);
53   }
54   ierr = PetscGetWorkingDirectory(fullpath,flen);CHKERRQ(ierr);
55   ierr = PetscStrlen(fullpath,&ln);CHKERRQ(ierr);
56   ierr = PetscStrncat(fullpath,"/",flen - ln);CHKERRQ(ierr);
57   if (path[0] == '.' && path[1] == '/') {
58     ierr = PetscStrlen(fullpath,&ln);CHKERRQ(ierr);
59     ierr = PetscStrncat(fullpath,path+2,flen - ln - 1);CHKERRQ(ierr);
60   } else {
61     ierr = PetscStrlen(fullpath,&ln);CHKERRQ(ierr);
62     ierr = PetscStrncat(fullpath,path,flen - ln - 1);CHKERRQ(ierr);
63   }
64 
65   /* Remove the various "special" forms (~username/ and ~/) */
66   if (fullpath[0] == '~') {
67     char tmppath[PETSC_MAX_PATH_LEN],*rest;
68     if (fullpath[1] == '/') {
69       ierr = PetscGetHomeDirectory(tmppath,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
70       rest = fullpath + 2;
71     } else {
72 #if defined(PETSC_HAVE_PWD_H)
73       struct passwd  *pwde;
74       char *p,*name;
75 
76       /* Find username */
77       name = fullpath + 1;
78       p    = name;
79       while (*p && *p != '/') p++;
80       *p   = 0;
81       rest = p + 1;
82       pwde = getpwnam(name);
83       if (!pwde) PetscFunctionReturn(0);
84 
85       ierr = PetscStrcpy(tmppath,pwde->pw_dir);CHKERRQ(ierr);
86 #else
87       PetscFunctionReturn(0);
88 #endif
89     }
90     ierr = PetscStrlen(tmppath,&ln);CHKERRQ(ierr);
91     if (tmppath[ln-1] != '/') {ierr = PetscStrcat(tmppath+ln-1,"/");CHKERRQ(ierr);}
92     ierr = PetscStrcat(tmppath,rest);CHKERRQ(ierr);
93     ierr = PetscStrncpy(fullpath,tmppath,flen);CHKERRQ(ierr);
94   }
95   /* Remove the automounter part of the path */
96   ierr = PetscStrncmp(fullpath,"/tmp_mnt/",9,&flg);CHKERRQ(ierr);
97   if (flg) {
98     char tmppath[PETSC_MAX_PATH_LEN];
99     ierr = PetscStrcpy(tmppath,fullpath + 8);CHKERRQ(ierr);
100     ierr = PetscStrcpy(fullpath,tmppath);CHKERRQ(ierr);
101   }
102   /* We could try to handle things like the removal of .. etc */
103   PetscFunctionReturn(0);
104 }
105