xref: /petsc/src/sys/fileio/ftest.c (revision 7d0a6c19129e7069c8a40e210b34ed62989173db)
1 
2 #include "petscsys.h"
3 #if defined(PETSC_HAVE_PWD_H)
4 #include <pwd.h>
5 #endif
6 #include <ctype.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #if defined(PETSC_HAVE_UNISTD_H)
10 #include <unistd.h>
11 #endif
12 #if defined(PETSC_HAVE_STDLIB_H)
13 #include <stdlib.h>
14 #endif
15 #if defined(PETSC_HAVE_SYS_UTSNAME_H)
16 #include <sys/utsname.h>
17 #endif
18 #if defined(PETSC_HAVE_IO_H)
19 #include <io.h>
20 #endif
21 #if defined(PETSC_HAVE_SYS_SYSTEMINFO_H)
22 #include <sys/systeminfo.h>
23 #endif
24 
25 #if defined (PETSC_HAVE__ACCESS) || defined(PETSC_HAVE_ACCESS)
26 
27 #undef __FUNCT__
28 #define __FUNCT__ "PetscTestOwnership"
29 static PetscErrorCode PetscTestOwnership(const char fname[], char mode, uid_t fuid, gid_t fgid, int fmode, PetscBool  *flg)
30 {
31   int m = R_OK;
32 
33   PetscFunctionBegin;
34   if (mode == 'r') m = R_OK;
35   else if (mode == 'w') m = W_OK;
36   else if (mode == 'x') m = X_OK;
37   else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Mode must be one of r, w, or x");
38 #if defined(PETSC_HAVE_ACCESS)
39   if(!access(fname, m))  *flg = PETSC_TRUE;
40 #else
41   if (m == X_OK) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP, "Unable to check execute permission for file %s", fname);
42   if(!_access(fname, m)) *flg = PETSC_TRUE;
43 #endif
44   PetscFunctionReturn(0);
45 }
46 
47 #else  /* PETSC_HAVE_ACCESS or PETSC_HAVE__ACCESS */
48 
49 #undef __FUNCT__
50 #define __FUNCT__ "PetscTestOwnership"
51 static PetscErrorCode PetscTestOwnership(const char fname[], char mode, uid_t fuid, gid_t fgid, int fmode, PetscBool  *flg)
52 {
53   uid_t          uid;
54   gid_t          *gid = PETSC_NULL;
55   int            numGroups;
56   int            rbit = S_IROTH;
57   int            wbit = S_IWOTH;
58   int            ebit = S_IXOTH;
59   PetscErrorCode ierr;
60 
61   PetscFunctionBegin;
62   /* Get the number of supplementary group IDs */
63 #if !defined(PETSC_MISSING_GETGROUPS)
64   numGroups = getgroups(0, gid); if (numGroups < 0) SETERRQ(PETSC_COMM_SELF,numGroups, "Unable to count supplementary group IDs");
65   ierr = PetscMalloc((numGroups+1) * sizeof(gid_t), &gid);CHKERRQ(ierr);
66 #else
67   numGroups = 0;
68 #endif
69 
70   /* Get the (effective) user and group of the caller */
71   uid    = geteuid();
72   gid[0] = getegid();
73 
74   /* Get supplementary group IDs */
75 #if !defined(PETSC_MISSING_GETGROUPS)
76   ierr = getgroups(numGroups, gid+1); if (ierr < 0) SETERRQ(PETSC_COMM_SELF,ierr, "Unable to obtain supplementary group IDs");
77 #endif
78 
79   /* Test for accessibility */
80   if (fuid == uid) {
81     rbit = S_IRUSR;
82     wbit = S_IWUSR;
83     ebit = S_IXUSR;
84   } else {
85     int g;
86 
87     for(g = 0; g <= numGroups; g++) {
88       if (fgid == gid[g]) {
89         rbit = S_IRGRP;
90         wbit = S_IWGRP;
91         ebit = S_IXGRP;
92         break;
93       }
94     }
95   }
96   ierr = PetscFree(gid);CHKERRQ(ierr);
97 
98   if (mode == 'r') {
99     if (fmode & rbit) *flg = PETSC_TRUE;
100   } else if (mode == 'w') {
101     if (fmode & wbit) *flg = PETSC_TRUE;
102   } else if (mode == 'x') {
103     if (fmode & ebit) *flg = PETSC_TRUE;
104   }
105   PetscFunctionReturn(0);
106 }
107 
108 #endif /* PETSC_HAVE_ACCESS */
109 
110 #undef __FUNCT__
111 #define __FUNCT__ "PetscGetFileStat"
112 static PetscErrorCode PetscGetFileStat(const char fname[], uid_t *fileUid, gid_t *fileGid, int *fileMode,PetscBool  *exists)
113 {
114   struct stat    statbuf;
115   PetscErrorCode ierr;
116 
117   PetscFunctionBegin;
118 #if defined(PETSC_HAVE_STAT_NO_CONST)
119   ierr = stat((char*) fname, &statbuf);
120 #else
121   ierr = stat(fname, &statbuf);
122 #endif
123   if (ierr) {
124     *exists = PETSC_FALSE;
125   } else {
126     *exists = PETSC_TRUE;
127     *fileUid  = statbuf.st_uid;
128     *fileGid  = statbuf.st_gid;
129     *fileMode = statbuf.st_mode;
130   }
131   PetscFunctionReturn(0);
132 }
133 
134 #undef __FUNCT__
135 #define __FUNCT__ "PetscTestFile"
136 PetscErrorCode  PetscTestFile(const char fname[], char mode, PetscBool  *flg)
137 {
138   uid_t          fuid;
139   gid_t          fgid;
140   int            fmode;
141   PetscErrorCode ierr;
142   PetscBool      exists;
143 
144   PetscFunctionBegin;
145   *flg = PETSC_FALSE;
146   if (!fname) PetscFunctionReturn(0);
147 
148   ierr = PetscGetFileStat(fname, &fuid, &fgid, &fmode,&exists);CHKERRQ(ierr);
149   if (!exists) PetscFunctionReturn(0);
150   /* Except for systems that have this broken stat macros (rare), this
151      is the correct way to check for a regular file */
152   if (!S_ISREG(fmode)) PetscFunctionReturn(0);
153 
154   ierr = PetscTestOwnership(fname, mode, fuid, fgid, fmode, flg);CHKERRQ(ierr);
155   PetscFunctionReturn(0);
156 }
157 
158 #undef __FUNCT__
159 #define __FUNCT__ "PetscTestDirectory"
160 PetscErrorCode  PetscTestDirectory(const char fname[],char mode,PetscBool  *flg)
161 {
162   uid_t          fuid;
163   gid_t          fgid;
164   int            fmode;
165   PetscErrorCode ierr;
166   PetscBool      exists;
167 
168   PetscFunctionBegin;
169   *flg = PETSC_FALSE;
170   if (!fname) PetscFunctionReturn(0);
171 
172   ierr = PetscGetFileStat(fname, &fuid, &fgid, &fmode,&exists);CHKERRQ(ierr);
173   if (!exists) PetscFunctionReturn(0);
174   /* Except for systems that have this broken stat macros (rare), this
175      is the correct way to check for a directory */
176   if (!S_ISDIR(fmode)) PetscFunctionReturn(0);
177 
178   ierr = PetscTestOwnership(fname, mode, fuid, fgid, fmode, flg);CHKERRQ(ierr);
179   PetscFunctionReturn(0);
180 }
181 
182 #undef __FUNCT__
183 #define __FUNCT__ "PetscLs"
184 PetscErrorCode  PetscLs(MPI_Comm comm,const char libname[],char found[],size_t tlen,PetscBool  *flg)
185 {
186   PetscErrorCode ierr;
187   size_t         len;
188   char           *f,program[PETSC_MAX_PATH_LEN];
189   FILE           *fp;
190 
191   PetscFunctionBegin;
192   ierr   = PetscStrcpy(program,"ls ");CHKERRQ(ierr);
193   ierr   = PetscStrcat(program,libname);CHKERRQ(ierr);
194 #if defined(PETSC_HAVE_POPEN)
195   ierr   = PetscPOpen(comm,PETSC_NULL,program,"r",&fp);CHKERRQ(ierr);
196 #else
197   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
198 #endif
199   f      = fgets(found,tlen,fp);
200   if (f) *flg = PETSC_TRUE; else *flg = PETSC_FALSE;
201   while (f) {
202     ierr  = PetscStrlen(found,&len);CHKERRQ(ierr);
203     f     = fgets(found+len,tlen-len,fp);
204   }
205   if (*flg) {ierr = PetscInfo2(0,"ls on %s gives \n%s\n",libname,found);CHKERRQ(ierr);}
206 #if defined(PETSC_HAVE_POPEN)
207   ierr   = PetscPClose(comm,fp);CHKERRQ(ierr);
208 #else
209   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
210 #endif
211   PetscFunctionReturn(0);
212 }
213