Actual source code: ftest.c
2: #include <petscsys.h>
3: #include <errno.h>
4: #if defined(PETSC_HAVE_PWD_H)
5: #include <pwd.h>
6: #endif
7: #include <ctype.h>
8: #include <sys/stat.h>
9: #if defined(PETSC_HAVE_UNISTD_H)
10: #include <unistd.h>
11: #endif
12: #if defined(PETSC_HAVE_SYS_UTSNAME_H)
13: #include <sys/utsname.h>
14: #endif
15: #if defined(PETSC_HAVE_IO_H)
16: #include <io.h>
17: #endif
18: #if defined(PETSC_HAVE_SYS_SYSTEMINFO_H)
19: #include <sys/systeminfo.h>
20: #endif
22: #if defined(PETSC_HAVE__ACCESS) || defined(PETSC_HAVE_ACCESS)
24: static PetscErrorCode PetscTestOwnership(const char fname[], char mode, uid_t fuid, gid_t fgid, int fmode, PetscBool *flg)
25: {
26: int m = R_OK;
28: if (mode == 'r') m = R_OK;
29: else if (mode == 'w') m = W_OK;
30: else if (mode == 'x') m = X_OK;
31: else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Mode must be one of r, w, or x");
32: #if defined(PETSC_HAVE_ACCESS)
33: if (!access(fname, m)) {
34: PetscInfo(NULL,"System call access() succeeded on file %s\n",fname);
35: *flg = PETSC_TRUE;
36: } else {
37: PetscInfo(NULL,"System call access() failed on file %s\n",fname);
38: *flg = PETSC_FALSE;
39: }
40: #else
42: if (!_access(fname, m)) *flg = PETSC_TRUE;
43: #endif
44: return 0;
45: }
47: #else /* PETSC_HAVE_ACCESS or PETSC_HAVE__ACCESS */
49: static PetscErrorCode PetscTestOwnership(const char fname[], char mode, uid_t fuid, gid_t fgid, int fmode, PetscBool *flg)
50: {
51: uid_t uid;
52: gid_t *gid = NULL;
53: int numGroups;
54: int rbit = S_IROTH;
55: int wbit = S_IWOTH;
56: int ebit = S_IXOTH;
57: #if !defined(PETSC_MISSING_GETGROUPS)
58: int err;
59: #endif
61: /* Get the number of supplementary group IDs */
62: #if !defined(PETSC_MISSING_GETGROUPS)
64: PetscMalloc1(numGroups+1, &gid);
65: #else
66: numGroups = 0;
67: #endif
69: /* Get the (effective) user and group of the caller */
70: uid = geteuid();
71: gid[0] = getegid();
73: /* Get supplementary group IDs */
74: #if !defined(PETSC_MISSING_GETGROUPS)
76: #endif
78: /* Test for accessibility */
79: if (fuid == uid) {
80: rbit = S_IRUSR;
81: wbit = S_IWUSR;
82: ebit = S_IXUSR;
83: } else {
84: int g;
86: for (g = 0; g <= numGroups; g++) {
87: if (fgid == gid[g]) {
88: rbit = S_IRGRP;
89: wbit = S_IWGRP;
90: ebit = S_IXGRP;
91: break;
92: }
93: }
94: }
95: PetscFree(gid);
97: if (mode == 'r') {
98: if (fmode & rbit) *flg = PETSC_TRUE;
99: } else if (mode == 'w') {
100: if (fmode & wbit) *flg = PETSC_TRUE;
101: } else if (mode == 'x') {
102: if (fmode & ebit) *flg = PETSC_TRUE;
103: }
104: return 0;
105: }
107: #endif /* PETSC_HAVE_ACCESS */
109: static PetscErrorCode PetscGetFileStat(const char fname[], uid_t *fileUid, gid_t *fileGid, int *fileMode,PetscBool *exists)
110: {
111: struct stat statbuf;
114: *fileMode = 0;
115: *exists = PETSC_FALSE;
116: #if defined(PETSC_HAVE_STAT_NO_CONST)
117: stat((char*) fname, &statbuf);
118: #else
119: stat(fname, &statbuf);
120: #endif
121: if (ierr) {
122: #if defined(EOVERFLOW)
124: #endif
125: PetscInfo(NULL,"System call stat() failed on file %s\n",fname);
126: *exists = PETSC_FALSE;
127: } else {
128: PetscInfo(NULL,"System call stat() succeeded on file %s\n",fname);
129: *exists = PETSC_TRUE;
130: *fileUid = statbuf.st_uid;
131: *fileGid = statbuf.st_gid;
132: *fileMode = statbuf.st_mode;
133: }
134: return 0;
135: }
137: /*@C
138: PetscTestFile - checks for the existence of a file
140: Not Collective
142: Input Parameters:
143: + fname - the filename
144: - mode - either 'r', 'w', 'x' or '\0'
146: Output Parameter:
147: . flg - the file exists and satisfies the mode
149: Level: intermediate
151: Notes: if mode is '\0', no permissions checks are performed
153: .seealso: PetscTestDirectory(), PetscLs()
154: @*/
155: PetscErrorCode PetscTestFile(const char fname[], char mode, PetscBool *flg)
156: {
157: uid_t fuid;
158: gid_t fgid;
159: int fmode;
160: PetscBool exists;
162: *flg = PETSC_FALSE;
163: if (!fname) return 0;
165: PetscGetFileStat(fname, &fuid, &fgid, &fmode, &exists);
166: if (!exists) return 0;
167: /* Except for systems that have this broken stat macros (rare), this is the correct way to check for a regular file */
168: if (!S_ISREG(fmode)) return 0;
169: /* return if asked to check for existence only */
170: if (mode == '\0') { *flg = exists; return 0; }
171: PetscTestOwnership(fname, mode, fuid, fgid, fmode, flg);
172: return 0;
173: }
175: /*@C
176: PetscTestDirectory - checks for the existence of a directory
178: Not Collective
180: Input Parameters:
181: + dirname - the directory name
182: - mode - either 'r', 'w', or 'x'
184: Output Parameter:
185: . flg - the directory exists and satisfies the mode
187: Level: intermediate
189: .seealso: PetscTestFile(), PetscLs()
190: @*/
191: PetscErrorCode PetscTestDirectory(const char dirname[],char mode,PetscBool *flg)
192: {
193: uid_t fuid;
194: gid_t fgid;
195: int fmode;
196: PetscBool exists;
198: *flg = PETSC_FALSE;
199: if (!dirname) return 0;
201: PetscGetFileStat(dirname, &fuid, &fgid, &fmode,&exists);
202: if (!exists) return 0;
203: /* Except for systems that have this broken stat macros (rare), this
204: is the correct way to check for a directory */
205: if (!S_ISDIR(fmode)) return 0;
207: PetscTestOwnership(dirname, mode, fuid, fgid, fmode, flg);
208: return 0;
209: }
211: /*@C
212: PetscLs - produce a listing of the files in a directory
214: Collective
216: Input Parameters:
217: + comm - the MPI communicator
218: . dirname - the directory name
219: - tlen - the length of the buffer found[]
221: Output Parameters:
222: + found - listing of files
223: - flg - the directory exists
225: Level: intermediate
227: .seealso: PetscTestFile(), PetscLs()
228: @*/
229: PetscErrorCode PetscLs(MPI_Comm comm,const char dirname[],char found[],size_t tlen,PetscBool *flg)
230: {
231: size_t len;
232: char *f,program[PETSC_MAX_PATH_LEN];
233: FILE *fp;
235: PetscStrcpy(program,"ls ");
236: PetscStrcat(program,dirname);
237: #if defined(PETSC_HAVE_POPEN)
238: PetscPOpen(comm,NULL,program,"r",&fp);
239: #else
240: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
241: #endif
242: f = fgets(found,tlen,fp);
243: if (f) *flg = PETSC_TRUE;
244: else *flg = PETSC_FALSE;
245: while (f) {
246: PetscStrlen(found,&len);
247: f = fgets(found+len,tlen-len,fp);
248: }
249: if (*flg) PetscInfo(NULL,"ls on %s gives \n%s\n",dirname,found);
250: #if defined(PETSC_HAVE_POPEN)
251: PetscPClose(comm,fp);
252: #else
253: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
254: #endif
255: return 0;
256: }