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