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