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