17d0a6c19SBarry Smith 2e5c89e4eSSatish Balay /* 3e5c89e4eSSatish Balay Code for opening and closing files. 4e5c89e4eSSatish Balay */ 5c6db04a5SJed Brown #include <petscsys.h> 6e5c89e4eSSatish Balay #if defined(PETSC_HAVE_PWD_H) 7e5c89e4eSSatish Balay #include <pwd.h> 8e5c89e4eSSatish Balay #endif 9e5c89e4eSSatish Balay #include <ctype.h> 10e5c89e4eSSatish Balay #include <sys/stat.h> 11e5c89e4eSSatish Balay #if defined(PETSC_HAVE_UNISTD_H) 12e5c89e4eSSatish Balay #include <unistd.h> 13e5c89e4eSSatish Balay #endif 14e5c89e4eSSatish Balay #if defined(PETSC_HAVE_SYS_UTSNAME_H) 15e5c89e4eSSatish Balay #include <sys/utsname.h> 16e5c89e4eSSatish Balay #endif 17e5c89e4eSSatish Balay #include <fcntl.h> 18e5c89e4eSSatish Balay #include <time.h> 19e5c89e4eSSatish Balay #if defined(PETSC_HAVE_SYS_SYSTEMINFO_H) 20e5c89e4eSSatish Balay #include <sys/systeminfo.h> 21e5c89e4eSSatish Balay #endif 22e5c89e4eSSatish Balay 23480cf27aSJed Brown /* 24480cf27aSJed Brown Private routine to delete tmp/shared storage 25480cf27aSJed Brown 26480cf27aSJed Brown This is called by MPI, not by users. 27480cf27aSJed Brown 2812801b39SBarry Smith Note: this is declared extern "C" because it is passed to MPI_Comm_create_keyval() 29480cf27aSJed Brown 30480cf27aSJed Brown */ 319371c9d4SSatish Balay PETSC_EXTERN PetscMPIInt MPIAPI Petsc_DelTmpShared(MPI_Comm comm, PetscMPIInt keyval, void *count_val, void *extra_state) { 32480cf27aSJed Brown PetscFunctionBegin; 339566063dSJacob Faibussowitsch PetscCallMPI(PetscInfo(NULL, "Deleting tmp/shared data in an MPI_Comm %ld\n", (long)comm)); 349566063dSJacob Faibussowitsch PetscCallMPI(PetscFree(count_val)); 35480cf27aSJed Brown PetscFunctionReturn(MPI_SUCCESS); 36480cf27aSJed Brown } 37e5c89e4eSSatish Balay 38e5c89e4eSSatish Balay /*@C 39e5c89e4eSSatish Balay PetscGetTmp - Gets the name of the tmp directory 40e5c89e4eSSatish Balay 41d083f849SBarry Smith Collective 42e5c89e4eSSatish Balay 43e5c89e4eSSatish Balay Input Parameters: 44e5c89e4eSSatish Balay + comm - MPI_Communicator that may share /tmp 45e5c89e4eSSatish Balay - len - length of string to hold name 46e5c89e4eSSatish Balay 47f899ff85SJose E. Roman Output Parameter: 48e5c89e4eSSatish Balay . dir - directory name 49e5c89e4eSSatish Balay 50e5c89e4eSSatish Balay Options Database Keys: 5110699b91SBarry Smith + -shared_tmp - indicates the directory is shared among the MPI ranks 5210699b91SBarry Smith . -not_shared_tmp - indicates the directory is not shared among the MPI ranks 5310699b91SBarry Smith - -tmp tmpdir - name of the directory you wish to use as /tmp 54e5c89e4eSSatish Balay 55e5c89e4eSSatish Balay Environmental Variables: 5610699b91SBarry Smith + PETSC_SHARED_TMP - indicates the directory is shared among the MPI ranks 5710699b91SBarry Smith . PETSC_NOT_SHARED_TMP - indicates the directory is not shared among the MPI ranks 5810699b91SBarry Smith - PETSC_TMP - name of the directory you wish to use as /tmp 59e5c89e4eSSatish Balay 60e5c89e4eSSatish Balay Level: developer 61e5c89e4eSSatish Balay 62e5c89e4eSSatish Balay @*/ 639371c9d4SSatish Balay PetscErrorCode PetscGetTmp(MPI_Comm comm, char dir[], size_t len) { 64ace3abfcSBarry Smith PetscBool flg; 65e5c89e4eSSatish Balay 66e5c89e4eSSatish Balay PetscFunctionBegin; 679566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetenv(comm, "PETSC_TMP", dir, len, &flg)); 68*48a46eb9SPierre Jolivet if (!flg) PetscCall(PetscStrncpy(dir, "/tmp", len)); 69e5c89e4eSSatish Balay PetscFunctionReturn(0); 70e5c89e4eSSatish Balay } 71e5c89e4eSSatish Balay 72e5c89e4eSSatish Balay /*@C 73e5c89e4eSSatish Balay PetscSharedTmp - Determines if all processors in a communicator share a 74e5c89e4eSSatish Balay /tmp or have different ones. 75e5c89e4eSSatish Balay 76d083f849SBarry Smith Collective 77e5c89e4eSSatish Balay 78e5c89e4eSSatish Balay Input Parameters: 79e5c89e4eSSatish Balay . comm - MPI_Communicator that may share /tmp 80e5c89e4eSSatish Balay 81e5c89e4eSSatish Balay Output Parameters: 82e5c89e4eSSatish Balay . shared - PETSC_TRUE or PETSC_FALSE 83e5c89e4eSSatish Balay 84e5c89e4eSSatish Balay Options Database Keys: 8510699b91SBarry Smith + -shared_tmp - indicates the directory is shared among the MPI ranks 8610699b91SBarry Smith . -not_shared_tmp - indicates the directory is not shared among the MPI ranks 8710699b91SBarry Smith - -tmp tmpdir - name of the directory you wish to use as /tmp 88e5c89e4eSSatish Balay 89e5c89e4eSSatish Balay Environmental Variables: 9010699b91SBarry Smith + PETSC_SHARED_TMP - indicates the directory is shared among the MPI ranks 9110699b91SBarry Smith . PETSC_NOT_SHARED_TMP - indicates the directory is not shared among the MPI ranks 9210699b91SBarry Smith - PETSC_TMP - name of the directory you wish to use as /tmp 93e5c89e4eSSatish Balay 94e5c89e4eSSatish Balay Level: developer 95e5c89e4eSSatish Balay 96e5c89e4eSSatish Balay Notes: 97e5c89e4eSSatish Balay Stores the status as a MPI attribute so it does not have 98e5c89e4eSSatish Balay to be redetermined each time. 99e5c89e4eSSatish Balay 100e5c89e4eSSatish Balay Assumes that all processors in a communicator either 101e5c89e4eSSatish Balay 1) have a common /tmp or 102a8c7a070SBarry Smith 2) each has a separate /tmp 103e5c89e4eSSatish Balay eventually we can write a fancier one that determines which processors 104e5c89e4eSSatish Balay share a common /tmp. 105e5c89e4eSSatish Balay 106e5c89e4eSSatish Balay This will be very slow on runs with a large number of processors since 107e5c89e4eSSatish Balay it requires O(p*p) file opens. 108e5c89e4eSSatish Balay 109e5c89e4eSSatish Balay If the environmental variable PETSC_TMP is set it will use this directory 110e5c89e4eSSatish Balay as the "/tmp" directory. 111e5c89e4eSSatish Balay 112e5c89e4eSSatish Balay @*/ 1139371c9d4SSatish Balay PetscErrorCode PetscSharedTmp(MPI_Comm comm, PetscBool *shared) { 114e5c89e4eSSatish Balay PetscMPIInt size, rank, *tagvalp, sum, cnt, i; 115ace3abfcSBarry Smith PetscBool flg, iflg; 116e5c89e4eSSatish Balay FILE *fd; 117e5c89e4eSSatish Balay static PetscMPIInt Petsc_Tmp_keyval = MPI_KEYVAL_INVALID; 118ed9cf6e9SBarry Smith int err; 119e5c89e4eSSatish Balay 120e5c89e4eSSatish Balay PetscFunctionBegin; 1219566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 122e5c89e4eSSatish Balay if (size == 1) { 123e5c89e4eSSatish Balay *shared = PETSC_TRUE; 124e5c89e4eSSatish Balay PetscFunctionReturn(0); 125e5c89e4eSSatish Balay } 126e5c89e4eSSatish Balay 1279566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetenv(comm, "PETSC_SHARED_TMP", NULL, 0, &flg)); 128e5c89e4eSSatish Balay if (flg) { 129e5c89e4eSSatish Balay *shared = PETSC_TRUE; 130e5c89e4eSSatish Balay PetscFunctionReturn(0); 131e5c89e4eSSatish Balay } 132e5c89e4eSSatish Balay 1339566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetenv(comm, "PETSC_NOT_SHARED_TMP", NULL, 0, &flg)); 134e5c89e4eSSatish Balay if (flg) { 135e5c89e4eSSatish Balay *shared = PETSC_FALSE; 136e5c89e4eSSatish Balay PetscFunctionReturn(0); 137e5c89e4eSSatish Balay } 138e5c89e4eSSatish Balay 139*48a46eb9SPierre Jolivet if (Petsc_Tmp_keyval == MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, Petsc_DelTmpShared, &Petsc_Tmp_keyval, NULL)); 140e5c89e4eSSatish Balay 1419566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_get_attr(comm, Petsc_Tmp_keyval, (void **)&tagvalp, (int *)&iflg)); 142e5c89e4eSSatish Balay if (!iflg) { 143e5c89e4eSSatish Balay char filename[PETSC_MAX_PATH_LEN], tmpname[PETSC_MAX_PATH_LEN]; 144e5c89e4eSSatish Balay 145e5c89e4eSSatish Balay /* This communicator does not yet have a shared tmp attribute */ 1469566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, &tagvalp)); 1479566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_set_attr(comm, Petsc_Tmp_keyval, tagvalp)); 148e5c89e4eSSatish Balay 1499566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetenv(comm, "PETSC_TMP", tmpname, 238, &iflg)); 150e5c89e4eSSatish Balay if (!iflg) { 1519566063dSJacob Faibussowitsch PetscCall(PetscStrcpy(filename, "/tmp")); 152e5c89e4eSSatish Balay } else { 1539566063dSJacob Faibussowitsch PetscCall(PetscStrcpy(filename, tmpname)); 154e5c89e4eSSatish Balay } 155e5c89e4eSSatish Balay 1569566063dSJacob Faibussowitsch PetscCall(PetscStrcat(filename, "/petsctestshared")); 1579566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 158e5c89e4eSSatish Balay 159e5c89e4eSSatish Balay /* each processor creates a /tmp file and all the later ones check */ 160e5c89e4eSSatish Balay /* this makes sure no subset of processors is shared */ 161e5c89e4eSSatish Balay *shared = PETSC_FALSE; 162e5c89e4eSSatish Balay for (i = 0; i < size - 1; i++) { 163e5c89e4eSSatish Balay if (rank == i) { 164e5c89e4eSSatish Balay fd = fopen(filename, "w"); 16528b400f6SJacob Faibussowitsch PetscCheck(fd, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to open test file %s", filename); 166ed9cf6e9SBarry Smith err = fclose(fd); 16728b400f6SJacob Faibussowitsch PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fclose() failed on file"); 168e5c89e4eSSatish Balay } 1699566063dSJacob Faibussowitsch PetscCallMPI(MPI_Barrier(comm)); 170e5c89e4eSSatish Balay if (rank >= i) { 171e5c89e4eSSatish Balay fd = fopen(filename, "r"); 172a297a907SKarl Rupp if (fd) cnt = 1; 173a297a907SKarl Rupp else cnt = 0; 174e5c89e4eSSatish Balay if (fd) { 175ed9cf6e9SBarry Smith err = fclose(fd); 17628b400f6SJacob Faibussowitsch PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fclose() failed on file"); 177e5c89e4eSSatish Balay } 178a297a907SKarl Rupp } else cnt = 0; 179a297a907SKarl Rupp 1801c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(&cnt, &sum, 1, MPI_INT, MPI_SUM, comm)); 181a297a907SKarl Rupp if (rank == i) unlink(filename); 182e5c89e4eSSatish Balay 183e5c89e4eSSatish Balay if (sum == size) { 184e5c89e4eSSatish Balay *shared = PETSC_TRUE; 185e5c89e4eSSatish Balay break; 18608401ef6SPierre Jolivet } else PetscCheck(sum == 1, PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Subset of processes share /tmp "); 187e5c89e4eSSatish Balay } 188e5c89e4eSSatish Balay *tagvalp = (int)*shared; 1899566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "processors %s %s\n", (*shared) ? "share" : "do NOT share", (iflg ? tmpname : "/tmp"))); 190a297a907SKarl Rupp } else *shared = (PetscBool)*tagvalp; 191e5c89e4eSSatish Balay PetscFunctionReturn(0); 192e5c89e4eSSatish Balay } 193e5c89e4eSSatish Balay 194e5c89e4eSSatish Balay /*@C 195f1a722f8SMatthew G. Knepley PetscSharedWorkingDirectory - Determines if all processors in a communicator share a working directory or have different ones. 196e5c89e4eSSatish Balay 197d083f849SBarry Smith Collective 198e5c89e4eSSatish Balay 1996b867d5aSJose E. Roman Input Parameter: 200e5c89e4eSSatish Balay . comm - MPI_Communicator that may share working directory 201e5c89e4eSSatish Balay 2026b867d5aSJose E. Roman Output Parameter: 203e5c89e4eSSatish Balay . shared - PETSC_TRUE or PETSC_FALSE 204e5c89e4eSSatish Balay 205e5c89e4eSSatish Balay Options Database Keys: 20610699b91SBarry Smith + -shared_working_directory - indicates the directory is shared among the MPI ranks 20710699b91SBarry Smith - -not_shared_working_directory - indicates the directory is shared among the MPI ranks 208e5c89e4eSSatish Balay 209e5c89e4eSSatish Balay Environmental Variables: 21010699b91SBarry Smith + PETSC_SHARED_WORKING_DIRECTORY - indicates the directory is shared among the MPI ranks 2113222ab0cSSatish Balay - PETSC_NOT_SHARED_WORKING_DIRECTORY - indicates the directory is shared among the MPI ranks 212e5c89e4eSSatish Balay 213e5c89e4eSSatish Balay Level: developer 214e5c89e4eSSatish Balay 215e5c89e4eSSatish Balay Notes: 216f1a722f8SMatthew G. Knepley Stores the status as a MPI attribute so it does not have to be redetermined each time. 217e5c89e4eSSatish Balay 218e5c89e4eSSatish Balay Assumes that all processors in a communicator either 219f1a722f8SMatthew G. Knepley $ 1) have a common working directory or 220f1a722f8SMatthew G. Knepley $ 2) each has a separate working directory 221f1a722f8SMatthew G. Knepley eventually we can write a fancier one that determines which processors share a common working directory. 222e5c89e4eSSatish Balay 223f1a722f8SMatthew G. Knepley This will be very slow on runs with a large number of processors since it requires O(p*p) file opens. 224e5c89e4eSSatish Balay @*/ 2259371c9d4SSatish Balay PetscErrorCode PetscSharedWorkingDirectory(MPI_Comm comm, PetscBool *shared) { 226e5c89e4eSSatish Balay PetscMPIInt size, rank, *tagvalp, sum, cnt, i; 227ace3abfcSBarry Smith PetscBool flg, iflg; 228e5c89e4eSSatish Balay FILE *fd; 229e5c89e4eSSatish Balay static PetscMPIInt Petsc_WD_keyval = MPI_KEYVAL_INVALID; 230ed9cf6e9SBarry Smith int err; 231e5c89e4eSSatish Balay 232e5c89e4eSSatish Balay PetscFunctionBegin; 2339566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 234e5c89e4eSSatish Balay if (size == 1) { 235e5c89e4eSSatish Balay *shared = PETSC_TRUE; 236e5c89e4eSSatish Balay PetscFunctionReturn(0); 237e5c89e4eSSatish Balay } 238e5c89e4eSSatish Balay 2399566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetenv(comm, "PETSC_SHARED_WORKING_DIRECTORY", NULL, 0, &flg)); 240e5c89e4eSSatish Balay if (flg) { 241e5c89e4eSSatish Balay *shared = PETSC_TRUE; 242e5c89e4eSSatish Balay PetscFunctionReturn(0); 243e5c89e4eSSatish Balay } 244e5c89e4eSSatish Balay 2459566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetenv(comm, "PETSC_NOT_SHARED_WORKING_DIRECTORY", NULL, 0, &flg)); 246e5c89e4eSSatish Balay if (flg) { 247e5c89e4eSSatish Balay *shared = PETSC_FALSE; 248e5c89e4eSSatish Balay PetscFunctionReturn(0); 249e5c89e4eSSatish Balay } 250e5c89e4eSSatish Balay 251*48a46eb9SPierre Jolivet if (Petsc_WD_keyval == MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, Petsc_DelTmpShared, &Petsc_WD_keyval, NULL)); 252e5c89e4eSSatish Balay 2539566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_get_attr(comm, Petsc_WD_keyval, (void **)&tagvalp, (int *)&iflg)); 254e5c89e4eSSatish Balay if (!iflg) { 255e5c89e4eSSatish Balay char filename[PETSC_MAX_PATH_LEN]; 256e5c89e4eSSatish Balay 257e5c89e4eSSatish Balay /* This communicator does not yet have a shared attribute */ 2589566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1, &tagvalp)); 2599566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_set_attr(comm, Petsc_WD_keyval, tagvalp)); 260e5c89e4eSSatish Balay 2619566063dSJacob Faibussowitsch PetscCall(PetscGetWorkingDirectory(filename, 240)); 2629566063dSJacob Faibussowitsch PetscCall(PetscStrcat(filename, "/petsctestshared")); 2639566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 264e5c89e4eSSatish Balay 265e5c89e4eSSatish Balay /* each processor creates a file and all the later ones check */ 266e5c89e4eSSatish Balay /* this makes sure no subset of processors is shared */ 267e5c89e4eSSatish Balay *shared = PETSC_FALSE; 268e5c89e4eSSatish Balay for (i = 0; i < size - 1; i++) { 269e5c89e4eSSatish Balay if (rank == i) { 270e5c89e4eSSatish Balay fd = fopen(filename, "w"); 27128b400f6SJacob Faibussowitsch PetscCheck(fd, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to open test file %s", filename); 272ed9cf6e9SBarry Smith err = fclose(fd); 27328b400f6SJacob Faibussowitsch PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fclose() failed on file"); 274e5c89e4eSSatish Balay } 2759566063dSJacob Faibussowitsch PetscCallMPI(MPI_Barrier(comm)); 276e5c89e4eSSatish Balay if (rank >= i) { 277e5c89e4eSSatish Balay fd = fopen(filename, "r"); 278a297a907SKarl Rupp if (fd) cnt = 1; 279a297a907SKarl Rupp else cnt = 0; 280e5c89e4eSSatish Balay if (fd) { 281ed9cf6e9SBarry Smith err = fclose(fd); 28228b400f6SJacob Faibussowitsch PetscCheck(!err, PETSC_COMM_SELF, PETSC_ERR_SYS, "fclose() failed on file"); 283e5c89e4eSSatish Balay } 284a297a907SKarl Rupp } else cnt = 0; 285a297a907SKarl Rupp 2861c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(&cnt, &sum, 1, MPI_INT, MPI_SUM, comm)); 287a297a907SKarl Rupp if (rank == i) unlink(filename); 288e5c89e4eSSatish Balay 289e5c89e4eSSatish Balay if (sum == size) { 290e5c89e4eSSatish Balay *shared = PETSC_TRUE; 291e5c89e4eSSatish Balay break; 29208401ef6SPierre Jolivet } else PetscCheck(sum == 1, PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Subset of processes share working directory"); 293e5c89e4eSSatish Balay } 294e5c89e4eSSatish Balay *tagvalp = (int)*shared; 295a297a907SKarl Rupp } else *shared = (PetscBool)*tagvalp; 2969566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "processors %s working directory\n", (*shared) ? "shared" : "do NOT share")); 297e5c89e4eSSatish Balay PetscFunctionReturn(0); 298e5c89e4eSSatish Balay } 299e5c89e4eSSatish Balay 300e5c89e4eSSatish Balay /*@C 3010c4f890aSBarry Smith PetscFileRetrieve - Obtains a file from a URL or compressed 302e5c89e4eSSatish Balay and copies into local disk space as uncompressed. 303e5c89e4eSSatish Balay 304d083f849SBarry Smith Collective 305e5c89e4eSSatish Balay 306d8d19677SJose E. Roman Input Parameters: 3070c4f890aSBarry Smith + comm - processors accessing the file 3080c4f890aSBarry Smith . url - name of file, including entire URL (with or without .gz) 3090c4f890aSBarry Smith - llen - length of localname 310e5c89e4eSSatish Balay 311d8d19677SJose E. Roman Output Parameters: 31208fb59bfSBarry Smith + localname - name of local copy of file - valid on only process zero 31308fb59bfSBarry Smith - found - if found or retrieved the file - valid on all processes 314e5c89e4eSSatish Balay 31595452b02SPatrick Sanan Notes: 31695452b02SPatrick Sanan if the file already exists local this function just returns without downloading it. 317e5c89e4eSSatish Balay 3180c4f890aSBarry Smith Level: intermediate 319e5c89e4eSSatish Balay @*/ 3209371c9d4SSatish Balay PetscErrorCode PetscFileRetrieve(MPI_Comm comm, const char url[], char localname[], size_t llen, PetscBool *found) { 32108fb59bfSBarry Smith char buffer[PETSC_MAX_PATH_LEN], *par, *tlocalname, name[PETSC_MAX_PATH_LEN]; 322e5c89e4eSSatish Balay FILE *fp; 323e5c89e4eSSatish Balay PetscMPIInt rank; 324e5c89e4eSSatish Balay size_t len = 0; 32508fb59bfSBarry Smith PetscBool flg1, flg2, flg3, flg4, download, compressed = PETSC_FALSE; 326e5c89e4eSSatish Balay 327e5c89e4eSSatish Balay PetscFunctionBegin; 3289566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 329dd400576SPatrick Sanan if (rank == 0) { 330e5c89e4eSSatish Balay *found = PETSC_FALSE; 331e5c89e4eSSatish Balay 3329566063dSJacob Faibussowitsch PetscCall(PetscStrstr(url, ".gz", &par)); 33308fb59bfSBarry Smith if (par) { 3349566063dSJacob Faibussowitsch PetscCall(PetscStrlen(par, &len)); 33508fb59bfSBarry Smith if (len == 3) compressed = PETSC_TRUE; 33608fb59bfSBarry Smith } 337e5c89e4eSSatish Balay 3389566063dSJacob Faibussowitsch PetscCall(PetscStrncmp(url, "ftp://", 6, &flg1)); 3399566063dSJacob Faibussowitsch PetscCall(PetscStrncmp(url, "http://", 7, &flg2)); 3409566063dSJacob Faibussowitsch PetscCall(PetscStrncmp(url, "file://", 7, &flg3)); 3419566063dSJacob Faibussowitsch PetscCall(PetscStrncmp(url, "https://", 8, &flg4)); 342a4772d12SBarry Smith download = (PetscBool)(flg1 || flg2 || flg3 || flg4); 34308fb59bfSBarry Smith 34408fb59bfSBarry Smith if (!download && !compressed) { 3459566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(localname, url, llen)); 3469566063dSJacob Faibussowitsch PetscCall(PetscTestFile(url, 'r', found)); 347487e5849SBarry Smith if (*found) { 3489566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Found file %s\n", url)); 349487e5849SBarry Smith } else { 3509566063dSJacob Faibussowitsch PetscCall(PetscInfo(NULL, "Did not find file %s\n", url)); 351487e5849SBarry Smith } 35208fb59bfSBarry Smith goto done; 353734f99bcSBarry Smith } 354734f99bcSBarry Smith 35505698389SBarry Smith /* look for uncompressed file in requested directory */ 35605698389SBarry Smith if (compressed) { 3579566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(localname, url, llen)); 3589566063dSJacob Faibussowitsch PetscCall(PetscStrstr(localname, ".gz", &par)); 35905698389SBarry Smith *par = 0; /* remove .gz extension */ 3609566063dSJacob Faibussowitsch PetscCall(PetscTestFile(localname, 'r', found)); 36105698389SBarry Smith if (*found) goto done; 36205698389SBarry Smith } 36305698389SBarry Smith 36405698389SBarry Smith /* look for file in current directory */ 3659566063dSJacob Faibussowitsch PetscCall(PetscStrrchr(url, '/', &tlocalname)); 3669566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(localname, tlocalname, llen)); 36708fb59bfSBarry Smith if (compressed) { 3689566063dSJacob Faibussowitsch PetscCall(PetscStrstr(localname, ".gz", &par)); 36908fb59bfSBarry Smith *par = 0; /* remove .gz extension */ 37008fb59bfSBarry Smith } 3719566063dSJacob Faibussowitsch PetscCall(PetscTestFile(localname, 'r', found)); 37208fb59bfSBarry Smith if (*found) goto done; 373e5c89e4eSSatish Balay 37408fb59bfSBarry Smith if (download) { 37508fb59bfSBarry Smith /* local file is not already here so use curl to get it */ 3769566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(localname, tlocalname, llen)); 3779566063dSJacob Faibussowitsch PetscCall(PetscStrcpy(buffer, "curl --fail --silent --show-error ")); 3789566063dSJacob Faibussowitsch PetscCall(PetscStrcat(buffer, url)); 3799566063dSJacob Faibussowitsch PetscCall(PetscStrcat(buffer, " > ")); 3809566063dSJacob Faibussowitsch PetscCall(PetscStrcat(buffer, localname)); 381e5c89e4eSSatish Balay #if defined(PETSC_HAVE_POPEN) 3829566063dSJacob Faibussowitsch PetscCall(PetscPOpen(PETSC_COMM_SELF, NULL, buffer, "r", &fp)); 3839566063dSJacob Faibussowitsch PetscCall(PetscPClose(PETSC_COMM_SELF, fp)); 384e5c89e4eSSatish Balay #else 385e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot run external programs on this machine"); 386e5c89e4eSSatish Balay #endif 3879566063dSJacob Faibussowitsch PetscCall(PetscTestFile(localname, 'r', found)); 3886e3a5469SBarry Smith if (*found) { 3896e3a5469SBarry Smith FILE *fd; 3906e3a5469SBarry Smith char buf[1024], *str, *substring; 3916e3a5469SBarry Smith 3926e3a5469SBarry Smith /* check if the file didn't exist so it downloaded an HTML message instead */ 3936e3a5469SBarry Smith fd = fopen(localname, "r"); 39428b400f6SJacob Faibussowitsch PetscCheck(fd, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscTestFile() indicates %s exists but fopen() cannot open it", localname); 3956e3a5469SBarry Smith str = fgets(buf, sizeof(buf) - 1, fd); 3966e3a5469SBarry Smith while (str) { 3979566063dSJacob Faibussowitsch PetscCall(PetscStrstr(buf, "<!DOCTYPE html>", &substring)); 39828b400f6SJacob Faibussowitsch PetscCheck(!substring, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unable to download %s it does not appear to exist at this URL, dummy HTML file was downloaded", url); 3999566063dSJacob Faibussowitsch PetscCall(PetscStrstr(buf, "Not Found", &substring)); 40028b400f6SJacob Faibussowitsch PetscCheck(!substring, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unable to download %s it does not appear to exist at this URL, dummy HTML file was downloaded", url); 4016e3a5469SBarry Smith str = fgets(buf, sizeof(buf) - 1, fd); 4026e3a5469SBarry Smith } 4036e3a5469SBarry Smith fclose(fd); 4046e3a5469SBarry Smith } 40508fb59bfSBarry Smith } else if (compressed) { 4069566063dSJacob Faibussowitsch PetscCall(PetscTestFile(url, 'r', found)); 40708fb59bfSBarry Smith if (!*found) goto done; 4089566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(localname, url, llen)); 40908fb59bfSBarry Smith } 41008fb59bfSBarry Smith if (compressed) { 4119566063dSJacob Faibussowitsch PetscCall(PetscStrrchr(localname, '/', &tlocalname)); 4129566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(name, tlocalname, PETSC_MAX_PATH_LEN)); 4139566063dSJacob Faibussowitsch PetscCall(PetscStrstr(name, ".gz", &par)); 41408fb59bfSBarry Smith *par = 0; /* remove .gz extension */ 41508fb59bfSBarry Smith /* uncompress file */ 4169566063dSJacob Faibussowitsch PetscCall(PetscStrcpy(buffer, "gzip -c -d ")); 4179566063dSJacob Faibussowitsch PetscCall(PetscStrcat(buffer, localname)); 4189566063dSJacob Faibussowitsch PetscCall(PetscStrcat(buffer, " > ")); 4199566063dSJacob Faibussowitsch PetscCall(PetscStrcat(buffer, name)); 42008fb59bfSBarry Smith #if defined(PETSC_HAVE_POPEN) 4219566063dSJacob Faibussowitsch PetscCall(PetscPOpen(PETSC_COMM_SELF, NULL, buffer, "r", &fp)); 4229566063dSJacob Faibussowitsch PetscCall(PetscPClose(PETSC_COMM_SELF, fp)); 42308fb59bfSBarry Smith #else 42408fb59bfSBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot run external programs on this machine"); 42508fb59bfSBarry Smith #endif 4269566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(localname, name, llen)); 4279566063dSJacob Faibussowitsch PetscCall(PetscTestFile(localname, 'r', found)); 428e5c89e4eSSatish Balay } 429e5c89e4eSSatish Balay } 430955d42a0SBarry Smith done: 4319566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(found, 1, MPIU_BOOL, 0, comm)); 4329566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(localname, llen, MPI_CHAR, 0, comm)); 433e5c89e4eSSatish Balay PetscFunctionReturn(0); 434e5c89e4eSSatish Balay } 435