15dc0f0a4SBarry Smith #include <petscwebclient.h> 2bb04b57dSBarry Smith #pragma clang diagnostic ignored "-Wdeprecated-declarations" 345e40e47SBarry Smith #pragma gcc diagnostic ignored "-Wdeprecated-declarations" 45dc0f0a4SBarry Smith 55dc0f0a4SBarry Smith /* 65dc0f0a4SBarry Smith Encodes and decodes from MIME Base64 75dc0f0a4SBarry Smith */ 85dc0f0a4SBarry Smith static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 95dc0f0a4SBarry Smith 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 105dc0f0a4SBarry Smith 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 115dc0f0a4SBarry Smith 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 125dc0f0a4SBarry Smith 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 135dc0f0a4SBarry Smith 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 145dc0f0a4SBarry Smith 'w', 'x', 'y', 'z', '0', '1', '2', '3', 155dc0f0a4SBarry Smith '4', '5', '6', '7', '8', '9', '+', '/'}; 165dc0f0a4SBarry Smith 175dc0f0a4SBarry Smith static PetscErrorCode base64_encode(const unsigned char *data,unsigned char *encoded_data,size_t len) 185dc0f0a4SBarry Smith { 19f5b927afSBarry Smith static size_t mod_table[] = {0, 2, 1}; 20f5b927afSBarry Smith size_t i,j; 215dc0f0a4SBarry Smith size_t input_length,output_length; 225dc0f0a4SBarry Smith 235dc0f0a4SBarry Smith PetscFunctionBegin; 249566063dSJacob Faibussowitsch PetscCall(PetscStrlen((const char*)data,&input_length)); 255dc0f0a4SBarry Smith output_length = 4 * ((input_length + 2) / 3); 26*08401ef6SPierre Jolivet PetscCheck(output_length <= len,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Output length not large enough"); 275dc0f0a4SBarry Smith 285dc0f0a4SBarry Smith for (i = 0, j = 0; i < input_length;) { 295dc0f0a4SBarry Smith uint32_t octet_a = i < input_length ? (unsigned char)data[i++] : 0; 305dc0f0a4SBarry Smith uint32_t octet_b = i < input_length ? (unsigned char)data[i++] : 0; 315dc0f0a4SBarry Smith uint32_t octet_c = i < input_length ? (unsigned char)data[i++] : 0; 325dc0f0a4SBarry Smith uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c; 335dc0f0a4SBarry Smith 345dc0f0a4SBarry Smith encoded_data[j++] = encoding_table[(triple >> 3 * 6) & 0x3F]; 355dc0f0a4SBarry Smith encoded_data[j++] = encoding_table[(triple >> 2 * 6) & 0x3F]; 365dc0f0a4SBarry Smith encoded_data[j++] = encoding_table[(triple >> 1 * 6) & 0x3F]; 375dc0f0a4SBarry Smith encoded_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F]; 385dc0f0a4SBarry Smith } 395dc0f0a4SBarry Smith encoded_data[j] = 0; 405dc0f0a4SBarry Smith for (i = 0; i < mod_table[input_length % 3]; i++) encoded_data[output_length - 1 - i] = '='; 415dc0f0a4SBarry Smith PetscFunctionReturn(0); 425dc0f0a4SBarry Smith } 435dc0f0a4SBarry Smith 445dc0f0a4SBarry Smith PETSC_UNUSED static PetscErrorCode base64_decode(const unsigned char *data,unsigned char* decoded_data, size_t length) 455dc0f0a4SBarry Smith { 465dc0f0a4SBarry Smith static char decoding_table[257]; 475dc0f0a4SBarry Smith static int decode_table_built = 0; 48c1f4622dSBarry Smith size_t i,j; 495dc0f0a4SBarry Smith size_t input_length,output_length; 505dc0f0a4SBarry Smith 515dc0f0a4SBarry Smith PetscFunctionBegin; 525dc0f0a4SBarry Smith if (!decode_table_built) { 535dc0f0a4SBarry Smith for (i = 0; i < 64; i++) decoding_table[(unsigned char) encoding_table[i]] = i; 545dc0f0a4SBarry Smith decode_table_built = 1; 555dc0f0a4SBarry Smith } 565dc0f0a4SBarry Smith 579566063dSJacob Faibussowitsch PetscCall(PetscStrlen((const char*)data,&input_length)); 58*08401ef6SPierre Jolivet PetscCheck(input_length % 4 == 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Input length must be divisible by 4"); 595dc0f0a4SBarry Smith 605dc0f0a4SBarry Smith output_length = input_length / 4 * 3; 615dc0f0a4SBarry Smith if (data[input_length - 1] == '=') (output_length)--; 625dc0f0a4SBarry Smith if (data[input_length - 2] == '=') (output_length)--; 63*08401ef6SPierre Jolivet PetscCheck(output_length <= length,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Output length too shore"); 645dc0f0a4SBarry Smith 655dc0f0a4SBarry Smith for (i = 0, j = 0; i < input_length;) { 665dc0f0a4SBarry Smith uint32_t sextet_a = data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]]; 675dc0f0a4SBarry Smith uint32_t sextet_b = data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]]; 685dc0f0a4SBarry Smith uint32_t sextet_c = data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]]; 695dc0f0a4SBarry Smith uint32_t sextet_d = data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]]; 705dc0f0a4SBarry Smith uint32_t triple = (sextet_a << 3 * 6) + (sextet_b << 2 * 6) + (sextet_c << 1 * 6) + (sextet_d << 0 * 6); 715dc0f0a4SBarry Smith 725dc0f0a4SBarry Smith if (j < output_length) decoded_data[j++] = (triple >> 2 * 8) & 0xFF; 735dc0f0a4SBarry Smith if (j < output_length) decoded_data[j++] = (triple >> 1 * 8) & 0xFF; 745dc0f0a4SBarry Smith if (j < output_length) decoded_data[j++] = (triple >> 0 * 8) & 0xFF; 755dc0f0a4SBarry Smith } 765dc0f0a4SBarry Smith decoded_data[j] = 0; 775dc0f0a4SBarry Smith PetscFunctionReturn(0); 785dc0f0a4SBarry Smith } 795dc0f0a4SBarry Smith 805dc0f0a4SBarry Smith #if defined(PETSC_HAVE_UNISTD_H) 815dc0f0a4SBarry Smith #include <unistd.h> 825dc0f0a4SBarry Smith #endif 835dc0f0a4SBarry Smith 845dc0f0a4SBarry Smith /*@C 855dc0f0a4SBarry Smith PetscGlobusAuthorize - Get an access token allowing PETSc applications to make Globus file transfer requests 865dc0f0a4SBarry Smith 875dc0f0a4SBarry Smith Not collective, only the first process in MPI_Comm does anything 885dc0f0a4SBarry Smith 895dc0f0a4SBarry Smith Input Parameters: 905dc0f0a4SBarry Smith + comm - the MPI communicator 915dc0f0a4SBarry Smith - tokensize - size of the token array 925dc0f0a4SBarry Smith 935dc0f0a4SBarry Smith Output Parameters: 945dc0f0a4SBarry Smith . access_token - can be used with PetscGlobusUpLoad() for 30 days 955dc0f0a4SBarry Smith 9695452b02SPatrick Sanan Notes: 9795452b02SPatrick Sanan This call requires stdout and stdin access from process 0 on the MPI communicator 985dc0f0a4SBarry Smith 99c4762a1bSJed Brown You can run src/sys/webclient/tutorials/globusobtainaccesstoken to get an access token 1005dc0f0a4SBarry Smith 1012b26979fSBarry Smith Level: intermediate 1022b26979fSBarry Smith 1035dc0f0a4SBarry Smith .seealso: PetscGoogleDriveRefresh(), PetscGoogleDriveUpload(), PetscURLShorten(), PetscGlobusUpload() 1045dc0f0a4SBarry Smith 1055dc0f0a4SBarry Smith @*/ 1065dc0f0a4SBarry Smith PetscErrorCode PetscGlobusAuthorize(MPI_Comm comm,char access_token[],size_t tokensize) 1075dc0f0a4SBarry Smith { 1085dc0f0a4SBarry Smith SSL_CTX *ctx; 1095dc0f0a4SBarry Smith SSL *ssl; 1105dc0f0a4SBarry Smith int sock; 1115dc0f0a4SBarry Smith char buff[8*1024],*ptr,head[1024]; 1125dc0f0a4SBarry Smith PetscMPIInt rank; 1135dc0f0a4SBarry Smith size_t len; 1145dc0f0a4SBarry Smith PetscBool found; 1155dc0f0a4SBarry Smith 1165dc0f0a4SBarry Smith PetscFunctionBegin; 1179566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm,&rank)); 118dd400576SPatrick Sanan if (rank == 0) { 1192c71b3e2SJacob Faibussowitsch PetscCheckFalse(!isatty(fileno(PETSC_STDOUT)),PETSC_COMM_SELF,PETSC_ERR_USER,"Requires users input/output"); 1209566063dSJacob Faibussowitsch PetscCall(PetscPrintf(comm,"Enter globus username:")); 1215dc0f0a4SBarry Smith ptr = fgets(buff, 1024, stdin); 12228b400f6SJacob Faibussowitsch PetscCheck(ptr,PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from stdin: %d", errno); 1239566063dSJacob Faibussowitsch PetscCall(PetscStrlen(buff,&len)); 1245dc0f0a4SBarry Smith buff[len-1] = ':'; /* remove carriage return at end of line */ 1255dc0f0a4SBarry Smith 1269566063dSJacob Faibussowitsch PetscCall(PetscPrintf(comm,"Enter globus password:")); 1275dc0f0a4SBarry Smith ptr = fgets(buff+len, 1024-len, stdin); 12828b400f6SJacob Faibussowitsch PetscCheck(ptr,PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from stdin: %d", errno); 1299566063dSJacob Faibussowitsch PetscCall(PetscStrlen(buff,&len)); 1305dc0f0a4SBarry Smith buff[len-1] = '\0'; /* remove carriage return at end of line */ 1319566063dSJacob Faibussowitsch PetscCall(PetscStrcpy(head,"Authorization: Basic ")); 1329566063dSJacob Faibussowitsch PetscCall(base64_encode((const unsigned char*)buff,(unsigned char*)(head+21),sizeof(head)-21)); 1339566063dSJacob Faibussowitsch PetscCall(PetscStrcat(head,"\r\n")); 1345dc0f0a4SBarry Smith 1359566063dSJacob Faibussowitsch PetscCall(PetscSSLInitializeContext(&ctx)); 1369566063dSJacob Faibussowitsch PetscCall(PetscHTTPSConnect("nexus.api.globusonline.org",443,ctx,&sock,&ssl)); 1379566063dSJacob Faibussowitsch PetscCall(PetscHTTPSRequest("GET","nexus.api.globusonline.org/goauth/token?grant_type=client_credentials",head,"application/x-www-form-urlencoded",NULL,ssl,buff,sizeof(buff))); 1389566063dSJacob Faibussowitsch PetscCall(PetscSSLDestroyContext(ctx)); 1395dc0f0a4SBarry Smith close(sock); 1405dc0f0a4SBarry Smith 1419566063dSJacob Faibussowitsch PetscCall(PetscPullJSONValue(buff,"access_token",access_token,tokensize,&found)); 14228b400f6SJacob Faibussowitsch PetscCheck(found,PETSC_COMM_SELF,PETSC_ERR_LIB,"Globus did not return access token"); 1435dc0f0a4SBarry Smith 1449566063dSJacob Faibussowitsch PetscCall(PetscPrintf(comm,"Here is your Globus access token, save it in a save place, in the future you can run PETSc\n")); 1459566063dSJacob Faibussowitsch PetscCall(PetscPrintf(comm,"programs with the option -globus_access_token %s\n",access_token)); 1469566063dSJacob Faibussowitsch PetscCall(PetscPrintf(comm,"to access Globus automatically\n")); 1475dc0f0a4SBarry Smith } 1485dc0f0a4SBarry Smith PetscFunctionReturn(0); 1495dc0f0a4SBarry Smith } 1505dc0f0a4SBarry Smith 1515dc0f0a4SBarry Smith /*@C 1525dc0f0a4SBarry Smith PetscGlobusGetTransfers - Get a record of current transfers requested from Globus 1535dc0f0a4SBarry Smith 1545dc0f0a4SBarry Smith Not collective, only the first process in MPI_Comm does anything 1555dc0f0a4SBarry Smith 1565dc0f0a4SBarry Smith Input Parameters: 1575dc0f0a4SBarry Smith + comm - the MPI communicator 1585dc0f0a4SBarry Smith . access_token - Globus access token, if NULL will check in options database for -globus_access_token XXX otherwise 1595dc0f0a4SBarry Smith will call PetscGlobusAuthorize(). 1605dc0f0a4SBarry Smith - buffsize - size of the buffer 1615dc0f0a4SBarry Smith 1625dc0f0a4SBarry Smith Output Parameters: 1635dc0f0a4SBarry Smith . buff - location to put Globus information 1645dc0f0a4SBarry Smith 1652b26979fSBarry Smith Level: intermediate 1662b26979fSBarry Smith 1675dc0f0a4SBarry Smith .seealso: PetscGoogleDriveRefresh(), PetscGoogleDriveUpload(), PetscURLShorten(), PetscGlobusUpload(), PetscGlobusAuthorize() 1685dc0f0a4SBarry Smith 1695dc0f0a4SBarry Smith @*/ 1705dc0f0a4SBarry Smith PetscErrorCode PetscGlobusGetTransfers(MPI_Comm comm,const char access_token[],char buff[],size_t buffsize) 1715dc0f0a4SBarry Smith { 1725dc0f0a4SBarry Smith SSL_CTX *ctx; 1735dc0f0a4SBarry Smith SSL *ssl; 1745dc0f0a4SBarry Smith int sock; 1755dc0f0a4SBarry Smith char head[4096]; 1765dc0f0a4SBarry Smith PetscMPIInt rank; 1775dc0f0a4SBarry Smith 1785dc0f0a4SBarry Smith PetscFunctionBegin; 1799566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm,&rank)); 180dd400576SPatrick Sanan if (rank == 0) { 1819566063dSJacob Faibussowitsch PetscCall(PetscStrcpy(head,"Authorization : Globus-Goauthtoken ")); 1825dc0f0a4SBarry Smith if (access_token) { 1839566063dSJacob Faibussowitsch PetscCall(PetscStrcat(head,access_token)); 1845dc0f0a4SBarry Smith } else { 1855dc0f0a4SBarry Smith PetscBool set; 1865dc0f0a4SBarry Smith char accesstoken[4096]; 1879566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetString(NULL,NULL,"-globus_access_token",accesstoken,sizeof(accesstoken),&set)); 18828b400f6SJacob Faibussowitsch PetscCheck(set,PETSC_COMM_SELF,PETSC_ERR_USER,"Pass in Globus accesstoken or use -globus_access_token XXX"); 1899566063dSJacob Faibussowitsch PetscCall(PetscStrcat(head,accesstoken)); 1905dc0f0a4SBarry Smith } 1919566063dSJacob Faibussowitsch PetscCall(PetscStrcat(head,"\r\n")); 1925dc0f0a4SBarry Smith 1939566063dSJacob Faibussowitsch PetscCall(PetscSSLInitializeContext(&ctx)); 1949566063dSJacob Faibussowitsch PetscCall(PetscHTTPSConnect("transfer.api.globusonline.org",443,ctx,&sock,&ssl)); 1959566063dSJacob Faibussowitsch PetscCall(PetscHTTPSRequest("GET","transfer.api.globusonline.org/v0.10/tasksummary",head,"application/json",NULL,ssl,buff,buffsize)); 1969566063dSJacob Faibussowitsch PetscCall(PetscSSLDestroyContext(ctx)); 1975dc0f0a4SBarry Smith close(sock); 1985dc0f0a4SBarry Smith } 1995dc0f0a4SBarry Smith PetscFunctionReturn(0); 2005dc0f0a4SBarry Smith } 2015dc0f0a4SBarry Smith 2025dc0f0a4SBarry Smith /*@C 2035dc0f0a4SBarry Smith PetscGlobusUpload - Loads a file to Globus 2045dc0f0a4SBarry Smith 2055dc0f0a4SBarry Smith Not collective, only the first process in the MPI_Comm uploads the file 2065dc0f0a4SBarry Smith 2075dc0f0a4SBarry Smith Input Parameters: 2085dc0f0a4SBarry Smith + comm - MPI communicator 2095dc0f0a4SBarry Smith . access_token - obtained with PetscGlobusAuthorize(), pass NULL to use -globus_access_token XXX from the PETSc database 2105dc0f0a4SBarry Smith - filename - file to upload 2115dc0f0a4SBarry Smith 2125dc0f0a4SBarry Smith Options Database: 21310699b91SBarry Smith . -globus_access_token XXX - the Globus token 2145dc0f0a4SBarry Smith 2152b26979fSBarry Smith Level: intermediate 2162b26979fSBarry Smith 2175dc0f0a4SBarry Smith .seealso: PetscURLShorten(), PetscGoogleDriveAuthorize(), PetscGoogleDriveRefresh(), PetscGlobusAuthorize() 2185dc0f0a4SBarry Smith 2195dc0f0a4SBarry Smith @*/ 2205dc0f0a4SBarry Smith PetscErrorCode PetscGlobusUpload(MPI_Comm comm,const char access_token[],const char filename[]) 2215dc0f0a4SBarry Smith { 2225dc0f0a4SBarry Smith SSL_CTX *ctx; 2235dc0f0a4SBarry Smith SSL *ssl; 2245dc0f0a4SBarry Smith int sock; 2255dc0f0a4SBarry Smith char head[4096],buff[8*1024],body[4096],submission_id[4096]; 2265dc0f0a4SBarry Smith PetscMPIInt rank; 2275dc0f0a4SBarry Smith PetscBool flg,found; 2285dc0f0a4SBarry Smith 2295dc0f0a4SBarry Smith PetscFunctionBegin; 2309566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm,&rank)); 231dd400576SPatrick Sanan if (rank == 0) { 2329566063dSJacob Faibussowitsch PetscCall(PetscTestFile(filename,'r',&flg)); 23328b400f6SJacob Faibussowitsch PetscCheck(flg,PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to find file: %s",filename); 2345dc0f0a4SBarry Smith 2359566063dSJacob Faibussowitsch PetscCall(PetscStrcpy(head,"Authorization : Globus-Goauthtoken ")); 2365dc0f0a4SBarry Smith if (access_token) { 2379566063dSJacob Faibussowitsch PetscCall(PetscStrcat(head,access_token)); 2385dc0f0a4SBarry Smith } else { 2395dc0f0a4SBarry Smith PetscBool set; 2405dc0f0a4SBarry Smith char accesstoken[4096]; 2419566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetString(NULL,NULL,"-globus_access_token",accesstoken,sizeof(accesstoken),&set)); 24228b400f6SJacob Faibussowitsch PetscCheck(set,PETSC_COMM_SELF,PETSC_ERR_USER,"Pass in Globus accesstoken or use -globus_access_token XXX"); 2439566063dSJacob Faibussowitsch PetscCall(PetscStrcat(head,accesstoken)); 2445dc0f0a4SBarry Smith } 2459566063dSJacob Faibussowitsch PetscCall(PetscStrcat(head,"\r\n")); 2465dc0f0a4SBarry Smith 2475dc0f0a4SBarry Smith /* Get Globus submission id */ 2489566063dSJacob Faibussowitsch PetscCall(PetscSSLInitializeContext(&ctx)); 2499566063dSJacob Faibussowitsch PetscCall(PetscHTTPSConnect("transfer.api.globusonline.org",443,ctx,&sock,&ssl)); 2509566063dSJacob Faibussowitsch PetscCall(PetscHTTPSRequest("GET","transfer.api.globusonline.org/v0.10/submission_id",head,"application/json",NULL,ssl,buff,sizeof(buff))); 2519566063dSJacob Faibussowitsch PetscCall(PetscSSLDestroyContext(ctx)); 2525dc0f0a4SBarry Smith close(sock); 2539566063dSJacob Faibussowitsch PetscCall(PetscPullJSONValue(buff,"value",submission_id,sizeof(submission_id),&found)); 25428b400f6SJacob Faibussowitsch PetscCheck(found,PETSC_COMM_SELF,PETSC_ERR_LIB,"Globus did not return submission id"); 2555dc0f0a4SBarry Smith 2565dc0f0a4SBarry Smith /* build JSON body of transfer request */ 2579566063dSJacob Faibussowitsch PetscCall(PetscStrcpy(body,"{")); 2589566063dSJacob Faibussowitsch PetscCall(PetscPushJSONValue(body,"submission_id",submission_id,sizeof(body))); PetscCall(PetscStrcat(body,",")); 2599566063dSJacob Faibussowitsch PetscCall(PetscPushJSONValue(body,"DATA_TYPE","transfer",sizeof(body))); PetscCall(PetscStrcat(body,",")); 2609566063dSJacob Faibussowitsch PetscCall(PetscPushJSONValue(body,"sync_level","null",sizeof(body))); PetscCall(PetscStrcat(body,",")); 2619566063dSJacob Faibussowitsch PetscCall(PetscPushJSONValue(body,"source_endpoint","barryfsmith#MacBookPro",sizeof(body))); PetscCall(PetscStrcat(body,",")); 2629566063dSJacob Faibussowitsch PetscCall(PetscPushJSONValue(body,"label","PETSc transfer label",sizeof(body))); PetscCall(PetscStrcat(body,",")); 2639566063dSJacob Faibussowitsch PetscCall(PetscPushJSONValue(body,"length","1",sizeof(body))); PetscCall(PetscStrcat(body,",")); 2649566063dSJacob Faibussowitsch PetscCall(PetscPushJSONValue(body,"destination_endpoint","mcs#home",sizeof(body))); PetscCall(PetscStrcat(body,",")); 2655dc0f0a4SBarry Smith 2669566063dSJacob Faibussowitsch PetscCall(PetscStrcat(body,"\"DATA\": [ {")); 2679566063dSJacob Faibussowitsch PetscCall(PetscPushJSONValue(body,"source_path","/~/FEM_GPU.pdf",sizeof(body))); PetscCall(PetscStrcat(body,",")); 2689566063dSJacob Faibussowitsch PetscCall(PetscPushJSONValue(body,"destination_path","/~/FEM_GPU.pdf",sizeof(body))); PetscCall(PetscStrcat(body,",")); 2699566063dSJacob Faibussowitsch PetscCall(PetscPushJSONValue(body,"verify_size","null",sizeof(body))); PetscCall(PetscStrcat(body,",")); 2709566063dSJacob Faibussowitsch PetscCall(PetscPushJSONValue(body,"recursive","false",sizeof(body))); PetscCall(PetscStrcat(body,",")); 2719566063dSJacob Faibussowitsch PetscCall(PetscPushJSONValue(body,"DATA_TYPE","transfer_item",sizeof(body))); 2729566063dSJacob Faibussowitsch PetscCall(PetscStrcat(body,"} ] }")); 2735dc0f0a4SBarry Smith 2749566063dSJacob Faibussowitsch PetscCall(PetscSSLInitializeContext(&ctx)); 2759566063dSJacob Faibussowitsch PetscCall(PetscHTTPSConnect("transfer.api.globusonline.org",443,ctx,&sock,&ssl)); 2769566063dSJacob Faibussowitsch PetscCall(PetscHTTPSRequest("POST","transfer.api.globusonline.org/v0.10/transfer",head,"application/json",body,ssl,buff,sizeof(buff))); 2779566063dSJacob Faibussowitsch PetscCall(PetscSSLDestroyContext(ctx)); 2785dc0f0a4SBarry Smith close(sock); 2799566063dSJacob Faibussowitsch PetscCall(PetscPullJSONValue(buff,"code",submission_id,sizeof(submission_id),&found)); 28028b400f6SJacob Faibussowitsch PetscCheck(found,PETSC_COMM_SELF,PETSC_ERR_LIB,"Globus did not return code on transfer"); 2819566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(submission_id,"Accepted",&found)); 28228b400f6SJacob Faibussowitsch PetscCheck(found,PETSC_COMM_SELF,PETSC_ERR_LIB,"Globus did not accept transfer"); 2835dc0f0a4SBarry Smith } 2845dc0f0a4SBarry Smith PetscFunctionReturn(0); 2855dc0f0a4SBarry Smith } 286