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 PetscErrorCode ierr; 235dc0f0a4SBarry Smith 245dc0f0a4SBarry Smith PetscFunctionBegin; 255dc0f0a4SBarry Smith ierr = PetscStrlen((const char*)data,&input_length);CHKERRQ(ierr); 265dc0f0a4SBarry Smith output_length = 4 * ((input_length + 2) / 3); 275dc0f0a4SBarry Smith if (output_length > len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Output length not large enough"); 285dc0f0a4SBarry Smith 295dc0f0a4SBarry Smith for (i = 0, j = 0; i < input_length;) { 305dc0f0a4SBarry Smith uint32_t octet_a = i < input_length ? (unsigned char)data[i++] : 0; 315dc0f0a4SBarry Smith uint32_t octet_b = i < input_length ? (unsigned char)data[i++] : 0; 325dc0f0a4SBarry Smith uint32_t octet_c = i < input_length ? (unsigned char)data[i++] : 0; 335dc0f0a4SBarry Smith uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c; 345dc0f0a4SBarry Smith 355dc0f0a4SBarry Smith encoded_data[j++] = encoding_table[(triple >> 3 * 6) & 0x3F]; 365dc0f0a4SBarry Smith encoded_data[j++] = encoding_table[(triple >> 2 * 6) & 0x3F]; 375dc0f0a4SBarry Smith encoded_data[j++] = encoding_table[(triple >> 1 * 6) & 0x3F]; 385dc0f0a4SBarry Smith encoded_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F]; 395dc0f0a4SBarry Smith } 405dc0f0a4SBarry Smith encoded_data[j] = 0; 415dc0f0a4SBarry Smith for (i = 0; i < mod_table[input_length % 3]; i++) encoded_data[output_length - 1 - i] = '='; 425dc0f0a4SBarry Smith PetscFunctionReturn(0); 435dc0f0a4SBarry Smith } 445dc0f0a4SBarry Smith 455dc0f0a4SBarry Smith PETSC_UNUSED static PetscErrorCode base64_decode(const unsigned char *data,unsigned char* decoded_data, size_t length) 465dc0f0a4SBarry Smith { 475dc0f0a4SBarry Smith static char decoding_table[257]; 485dc0f0a4SBarry Smith static int decode_table_built = 0; 49c1f4622dSBarry Smith size_t i,j; 505dc0f0a4SBarry Smith PetscErrorCode ierr; 515dc0f0a4SBarry Smith size_t input_length,output_length; 525dc0f0a4SBarry Smith 535dc0f0a4SBarry Smith PetscFunctionBegin; 545dc0f0a4SBarry Smith if (!decode_table_built) { 555dc0f0a4SBarry Smith for (i = 0; i < 64; i++) decoding_table[(unsigned char) encoding_table[i]] = i; 565dc0f0a4SBarry Smith decode_table_built = 1; 575dc0f0a4SBarry Smith } 585dc0f0a4SBarry Smith 595dc0f0a4SBarry Smith ierr = PetscStrlen((const char*)data,&input_length);CHKERRQ(ierr); 605dc0f0a4SBarry Smith if (input_length % 4 != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Input length must be divisible by 4"); 615dc0f0a4SBarry Smith 625dc0f0a4SBarry Smith output_length = input_length / 4 * 3; 635dc0f0a4SBarry Smith if (data[input_length - 1] == '=') (output_length)--; 645dc0f0a4SBarry Smith if (data[input_length - 2] == '=') (output_length)--; 655dc0f0a4SBarry Smith if (output_length > length) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Output length too shore"); 665dc0f0a4SBarry Smith 675dc0f0a4SBarry Smith for (i = 0, j = 0; i < input_length;) { 685dc0f0a4SBarry Smith uint32_t sextet_a = data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]]; 695dc0f0a4SBarry Smith uint32_t sextet_b = data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]]; 705dc0f0a4SBarry Smith uint32_t sextet_c = data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]]; 715dc0f0a4SBarry Smith uint32_t sextet_d = data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]]; 725dc0f0a4SBarry Smith uint32_t triple = (sextet_a << 3 * 6) + (sextet_b << 2 * 6) + (sextet_c << 1 * 6) + (sextet_d << 0 * 6); 735dc0f0a4SBarry Smith 745dc0f0a4SBarry Smith if (j < output_length) decoded_data[j++] = (triple >> 2 * 8) & 0xFF; 755dc0f0a4SBarry Smith if (j < output_length) decoded_data[j++] = (triple >> 1 * 8) & 0xFF; 765dc0f0a4SBarry Smith if (j < output_length) decoded_data[j++] = (triple >> 0 * 8) & 0xFF; 775dc0f0a4SBarry Smith } 785dc0f0a4SBarry Smith decoded_data[j] = 0; 795dc0f0a4SBarry Smith PetscFunctionReturn(0); 805dc0f0a4SBarry Smith } 815dc0f0a4SBarry Smith 825dc0f0a4SBarry Smith #if defined(PETSC_HAVE_UNISTD_H) 835dc0f0a4SBarry Smith #include <unistd.h> 845dc0f0a4SBarry Smith #endif 855dc0f0a4SBarry Smith 865dc0f0a4SBarry Smith /*@C 875dc0f0a4SBarry Smith PetscGlobusAuthorize - Get an access token allowing PETSc applications to make Globus file transfer requests 885dc0f0a4SBarry Smith 895dc0f0a4SBarry Smith Not collective, only the first process in MPI_Comm does anything 905dc0f0a4SBarry Smith 915dc0f0a4SBarry Smith Input Parameters: 925dc0f0a4SBarry Smith + comm - the MPI communicator 935dc0f0a4SBarry Smith - tokensize - size of the token array 945dc0f0a4SBarry Smith 955dc0f0a4SBarry Smith Output Parameters: 965dc0f0a4SBarry Smith . access_token - can be used with PetscGlobusUpLoad() for 30 days 975dc0f0a4SBarry Smith 9895452b02SPatrick Sanan Notes: 9995452b02SPatrick Sanan This call requires stdout and stdin access from process 0 on the MPI communicator 1005dc0f0a4SBarry Smith 101c4762a1bSJed Brown You can run src/sys/webclient/tutorials/globusobtainaccesstoken to get an access token 1025dc0f0a4SBarry Smith 1032b26979fSBarry Smith Level: intermediate 1042b26979fSBarry Smith 1055dc0f0a4SBarry Smith .seealso: PetscGoogleDriveRefresh(), PetscGoogleDriveUpload(), PetscURLShorten(), PetscGlobusUpload() 1065dc0f0a4SBarry Smith 1075dc0f0a4SBarry Smith @*/ 1085dc0f0a4SBarry Smith PetscErrorCode PetscGlobusAuthorize(MPI_Comm comm,char access_token[],size_t tokensize) 1095dc0f0a4SBarry Smith { 1105dc0f0a4SBarry Smith SSL_CTX *ctx; 1115dc0f0a4SBarry Smith SSL *ssl; 1125dc0f0a4SBarry Smith int sock; 1135dc0f0a4SBarry Smith PetscErrorCode ierr; 1145dc0f0a4SBarry Smith char buff[8*1024],*ptr,head[1024]; 1155dc0f0a4SBarry Smith PetscMPIInt rank; 1165dc0f0a4SBarry Smith size_t len; 1175dc0f0a4SBarry Smith PetscBool found; 1185dc0f0a4SBarry Smith 1195dc0f0a4SBarry Smith PetscFunctionBegin; 120ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 1215dc0f0a4SBarry Smith if (!rank) { 1225dc0f0a4SBarry Smith if (!isatty(fileno(PETSC_STDOUT))) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Requires users input/output"); 1235dc0f0a4SBarry Smith ierr = PetscPrintf(comm,"Enter globus username:");CHKERRQ(ierr); 1245dc0f0a4SBarry Smith ptr = fgets(buff, 1024, stdin); 1255dc0f0a4SBarry Smith if (!ptr) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from stdin: %d", errno); 1265dc0f0a4SBarry Smith ierr = PetscStrlen(buff,&len);CHKERRQ(ierr); 1275dc0f0a4SBarry Smith buff[len-1] = ':'; /* remove carriage return at end of line */ 1285dc0f0a4SBarry Smith 1295dc0f0a4SBarry Smith ierr = PetscPrintf(comm,"Enter globus password:");CHKERRQ(ierr); 1305dc0f0a4SBarry Smith ptr = fgets(buff+len, 1024-len, stdin); 1315dc0f0a4SBarry Smith if (!ptr) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from stdin: %d", errno); 1325dc0f0a4SBarry Smith ierr = PetscStrlen(buff,&len);CHKERRQ(ierr); 1335dc0f0a4SBarry Smith buff[len-1] = '\0'; /* remove carriage return at end of line */ 1345dc0f0a4SBarry Smith ierr = PetscStrcpy(head,"Authorization: Basic ");CHKERRQ(ierr); 1355dc0f0a4SBarry Smith ierr = base64_encode((const unsigned char*)buff,(unsigned char*)(head+21),sizeof(head)-21);CHKERRQ(ierr); 1365dc0f0a4SBarry Smith ierr = PetscStrcat(head,"\r\n");CHKERRQ(ierr); 1375dc0f0a4SBarry Smith 1385dc0f0a4SBarry Smith ierr = PetscSSLInitializeContext(&ctx);CHKERRQ(ierr); 1395dc0f0a4SBarry Smith ierr = PetscHTTPSConnect("nexus.api.globusonline.org",443,ctx,&sock,&ssl);CHKERRQ(ierr); 1405dc0f0a4SBarry Smith ierr = PetscHTTPSRequest("GET","nexus.api.globusonline.org/goauth/token?grant_type=client_credentials",head,"application/x-www-form-urlencoded",NULL,ssl,buff,sizeof(buff));CHKERRQ(ierr); 1415dc0f0a4SBarry Smith ierr = PetscSSLDestroyContext(ctx);CHKERRQ(ierr); 1425dc0f0a4SBarry Smith close(sock); 1435dc0f0a4SBarry Smith 1445dc0f0a4SBarry Smith ierr = PetscPullJSONValue(buff,"access_token",access_token,tokensize,&found);CHKERRQ(ierr); 1455dc0f0a4SBarry Smith if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Globus did not return access token"); 1465dc0f0a4SBarry Smith 1475dc0f0a4SBarry Smith ierr = PetscPrintf(comm,"Here is your Globus access token, save it in a save place, in the future you can run PETSc\n");CHKERRQ(ierr); 1485dc0f0a4SBarry Smith ierr = PetscPrintf(comm,"programs with the option -globus_access_token %s\n",access_token);CHKERRQ(ierr); 1495dc0f0a4SBarry Smith ierr = PetscPrintf(comm,"to access Globus automatically\n");CHKERRQ(ierr); 1505dc0f0a4SBarry Smith } 1515dc0f0a4SBarry Smith PetscFunctionReturn(0); 1525dc0f0a4SBarry Smith } 1535dc0f0a4SBarry Smith 1545dc0f0a4SBarry Smith 1555dc0f0a4SBarry Smith /*@C 1565dc0f0a4SBarry Smith PetscGlobusGetTransfers - Get a record of current transfers requested from Globus 1575dc0f0a4SBarry Smith 1585dc0f0a4SBarry Smith Not collective, only the first process in MPI_Comm does anything 1595dc0f0a4SBarry Smith 1605dc0f0a4SBarry Smith Input Parameters: 1615dc0f0a4SBarry Smith + comm - the MPI communicator 1625dc0f0a4SBarry Smith . access_token - Globus access token, if NULL will check in options database for -globus_access_token XXX otherwise 1635dc0f0a4SBarry Smith will call PetscGlobusAuthorize(). 1645dc0f0a4SBarry Smith - buffsize - size of the buffer 1655dc0f0a4SBarry Smith 1665dc0f0a4SBarry Smith Output Parameters: 1675dc0f0a4SBarry Smith . buff - location to put Globus information 1685dc0f0a4SBarry Smith 1692b26979fSBarry Smith Level: intermediate 1702b26979fSBarry Smith 1715dc0f0a4SBarry Smith .seealso: PetscGoogleDriveRefresh(), PetscGoogleDriveUpload(), PetscURLShorten(), PetscGlobusUpload(), PetscGlobusAuthorize() 1725dc0f0a4SBarry Smith 1735dc0f0a4SBarry Smith @*/ 1745dc0f0a4SBarry Smith PetscErrorCode PetscGlobusGetTransfers(MPI_Comm comm,const char access_token[],char buff[],size_t buffsize) 1755dc0f0a4SBarry Smith { 1765dc0f0a4SBarry Smith SSL_CTX *ctx; 1775dc0f0a4SBarry Smith SSL *ssl; 1785dc0f0a4SBarry Smith int sock; 1795dc0f0a4SBarry Smith PetscErrorCode ierr; 1805dc0f0a4SBarry Smith char head[4096]; 1815dc0f0a4SBarry Smith PetscMPIInt rank; 1825dc0f0a4SBarry Smith 1835dc0f0a4SBarry Smith PetscFunctionBegin; 184ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 1855dc0f0a4SBarry Smith if (!rank) { 1865dc0f0a4SBarry Smith ierr = PetscStrcpy(head,"Authorization : Globus-Goauthtoken ");CHKERRQ(ierr); 1875dc0f0a4SBarry Smith if (access_token) { 1885dc0f0a4SBarry Smith ierr = PetscStrcat(head,access_token);CHKERRQ(ierr); 1895dc0f0a4SBarry Smith } else { 1905dc0f0a4SBarry Smith PetscBool set; 1915dc0f0a4SBarry Smith char accesstoken[4096]; 192c5929fdfSBarry Smith ierr = PetscOptionsGetString(NULL,NULL,"-globus_access_token",accesstoken,sizeof(accesstoken),&set);CHKERRQ(ierr); 1935dc0f0a4SBarry Smith if (!set) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Pass in Globus accesstoken or use -globus_access_token XXX"); 1945dc0f0a4SBarry Smith ierr = PetscStrcat(head,accesstoken);CHKERRQ(ierr); 1955dc0f0a4SBarry Smith } 1965dc0f0a4SBarry Smith ierr = PetscStrcat(head,"\r\n");CHKERRQ(ierr); 1975dc0f0a4SBarry Smith 1985dc0f0a4SBarry Smith ierr = PetscSSLInitializeContext(&ctx);CHKERRQ(ierr); 1995dc0f0a4SBarry Smith ierr = PetscHTTPSConnect("transfer.api.globusonline.org",443,ctx,&sock,&ssl);CHKERRQ(ierr); 2005dc0f0a4SBarry Smith ierr = PetscHTTPSRequest("GET","transfer.api.globusonline.org/v0.10/tasksummary",head,"application/json",NULL,ssl,buff,buffsize);CHKERRQ(ierr); 2015dc0f0a4SBarry Smith ierr = PetscSSLDestroyContext(ctx);CHKERRQ(ierr); 2025dc0f0a4SBarry Smith close(sock); 2035dc0f0a4SBarry Smith } 2045dc0f0a4SBarry Smith PetscFunctionReturn(0); 2055dc0f0a4SBarry Smith } 2065dc0f0a4SBarry Smith 2075dc0f0a4SBarry Smith /*@C 2085dc0f0a4SBarry Smith PetscGlobusUpload - Loads a file to Globus 2095dc0f0a4SBarry Smith 2105dc0f0a4SBarry Smith Not collective, only the first process in the MPI_Comm uploads the file 2115dc0f0a4SBarry Smith 2125dc0f0a4SBarry Smith Input Parameters: 2135dc0f0a4SBarry Smith + comm - MPI communicator 2145dc0f0a4SBarry Smith . access_token - obtained with PetscGlobusAuthorize(), pass NULL to use -globus_access_token XXX from the PETSc database 2155dc0f0a4SBarry Smith - filename - file to upload 2165dc0f0a4SBarry Smith 2175dc0f0a4SBarry Smith Options Database: 218*10699b91SBarry Smith . -globus_access_token XXX - the Globus token 2195dc0f0a4SBarry Smith 2202b26979fSBarry Smith Level: intermediate 2212b26979fSBarry Smith 2225dc0f0a4SBarry Smith .seealso: PetscURLShorten(), PetscGoogleDriveAuthorize(), PetscGoogleDriveRefresh(), PetscGlobusAuthorize() 2235dc0f0a4SBarry Smith 2245dc0f0a4SBarry Smith @*/ 2255dc0f0a4SBarry Smith PetscErrorCode PetscGlobusUpload(MPI_Comm comm,const char access_token[],const char filename[]) 2265dc0f0a4SBarry Smith { 2275dc0f0a4SBarry Smith SSL_CTX *ctx; 2285dc0f0a4SBarry Smith SSL *ssl; 2295dc0f0a4SBarry Smith int sock; 2305dc0f0a4SBarry Smith PetscErrorCode ierr; 2315dc0f0a4SBarry Smith char head[4096],buff[8*1024],body[4096],submission_id[4096]; 2325dc0f0a4SBarry Smith PetscMPIInt rank; 2335dc0f0a4SBarry Smith PetscBool flg,found; 2345dc0f0a4SBarry Smith 2355dc0f0a4SBarry Smith PetscFunctionBegin; 236ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 2375dc0f0a4SBarry Smith if (!rank) { 2385dc0f0a4SBarry Smith ierr = PetscTestFile(filename,'r',&flg);CHKERRQ(ierr); 2395dc0f0a4SBarry Smith if (!flg) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to find file: %s",filename); 2405dc0f0a4SBarry Smith 2415dc0f0a4SBarry Smith ierr = PetscStrcpy(head,"Authorization : Globus-Goauthtoken ");CHKERRQ(ierr); 2425dc0f0a4SBarry Smith if (access_token) { 2435dc0f0a4SBarry Smith ierr = PetscStrcat(head,access_token);CHKERRQ(ierr); 2445dc0f0a4SBarry Smith } else { 2455dc0f0a4SBarry Smith PetscBool set; 2465dc0f0a4SBarry Smith char accesstoken[4096]; 247c5929fdfSBarry Smith ierr = PetscOptionsGetString(NULL,NULL,"-globus_access_token",accesstoken,sizeof(accesstoken),&set);CHKERRQ(ierr); 2485dc0f0a4SBarry Smith if (!set) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Pass in Globus accesstoken or use -globus_access_token XXX"); 2495dc0f0a4SBarry Smith ierr = PetscStrcat(head,accesstoken);CHKERRQ(ierr); 2505dc0f0a4SBarry Smith } 2515dc0f0a4SBarry Smith ierr = PetscStrcat(head,"\r\n");CHKERRQ(ierr); 2525dc0f0a4SBarry Smith 2535dc0f0a4SBarry Smith /* Get Globus submission id */ 2545dc0f0a4SBarry Smith ierr = PetscSSLInitializeContext(&ctx);CHKERRQ(ierr); 2555dc0f0a4SBarry Smith ierr = PetscHTTPSConnect("transfer.api.globusonline.org",443,ctx,&sock,&ssl);CHKERRQ(ierr); 2565dc0f0a4SBarry Smith ierr = PetscHTTPSRequest("GET","transfer.api.globusonline.org/v0.10/submission_id",head,"application/json",NULL,ssl,buff,sizeof(buff));CHKERRQ(ierr); 2575dc0f0a4SBarry Smith ierr = PetscSSLDestroyContext(ctx);CHKERRQ(ierr); 2585dc0f0a4SBarry Smith close(sock); 2595dc0f0a4SBarry Smith ierr = PetscPullJSONValue(buff,"value",submission_id,sizeof(submission_id),&found);CHKERRQ(ierr); 2605dc0f0a4SBarry Smith if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Globus did not return submission id"); 2615dc0f0a4SBarry Smith 2625dc0f0a4SBarry Smith /* build JSON body of transfer request */ 2635dc0f0a4SBarry Smith ierr = PetscStrcpy(body,"{");CHKERRQ(ierr); 2645dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"submission_id",submission_id,sizeof(body));CHKERRQ(ierr); ierr = PetscStrcat(body,",");CHKERRQ(ierr); 2655dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"DATA_TYPE","transfer",sizeof(body));CHKERRQ(ierr); ierr = PetscStrcat(body,",");CHKERRQ(ierr); 2665dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"sync_level","null",sizeof(body));CHKERRQ(ierr); ierr = PetscStrcat(body,",");CHKERRQ(ierr); 2675dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"source_endpoint","barryfsmith#MacBookPro",sizeof(body));CHKERRQ(ierr); ierr = PetscStrcat(body,",");CHKERRQ(ierr); 2685dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"label","PETSc transfer label",sizeof(body));CHKERRQ(ierr); ierr = PetscStrcat(body,",");CHKERRQ(ierr); 2695dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"length","1",sizeof(body));CHKERRQ(ierr); ierr = PetscStrcat(body,",");CHKERRQ(ierr); 2705dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"destination_endpoint","mcs#home",sizeof(body));CHKERRQ(ierr); ierr = PetscStrcat(body,",");CHKERRQ(ierr); 2715dc0f0a4SBarry Smith 2725dc0f0a4SBarry Smith ierr = PetscStrcat(body,"\"DATA\": [ {");CHKERRQ(ierr); 2735dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"source_path","/~/FEM_GPU.pdf",sizeof(body));CHKERRQ(ierr); ierr = PetscStrcat(body,",");CHKERRQ(ierr); 2745dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"destination_path","/~/FEM_GPU.pdf",sizeof(body));CHKERRQ(ierr); ierr = PetscStrcat(body,",");CHKERRQ(ierr); 2755dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"verify_size","null",sizeof(body));CHKERRQ(ierr); ierr = PetscStrcat(body,",");CHKERRQ(ierr); 2765dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"recursive","false",sizeof(body));CHKERRQ(ierr); ierr = PetscStrcat(body,",");CHKERRQ(ierr); 2775dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"DATA_TYPE","transfer_item",sizeof(body));CHKERRQ(ierr); 2785dc0f0a4SBarry Smith ierr = PetscStrcat(body,"} ] }");CHKERRQ(ierr); 2795dc0f0a4SBarry Smith 2805dc0f0a4SBarry Smith ierr = PetscSSLInitializeContext(&ctx);CHKERRQ(ierr); 2815dc0f0a4SBarry Smith ierr = PetscHTTPSConnect("transfer.api.globusonline.org",443,ctx,&sock,&ssl);CHKERRQ(ierr); 2825dc0f0a4SBarry Smith ierr = PetscHTTPSRequest("POST","transfer.api.globusonline.org/v0.10/transfer",head,"application/json",body,ssl,buff,sizeof(buff));CHKERRQ(ierr); 2835dc0f0a4SBarry Smith ierr = PetscSSLDestroyContext(ctx);CHKERRQ(ierr); 2845dc0f0a4SBarry Smith close(sock); 2855dc0f0a4SBarry Smith ierr = PetscPullJSONValue(buff,"code",submission_id,sizeof(submission_id),&found);CHKERRQ(ierr); 2865dc0f0a4SBarry Smith if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Globus did not return code on transfer"); 2875dc0f0a4SBarry Smith ierr = PetscStrcmp(submission_id,"Accepted",&found);CHKERRQ(ierr); 2885dc0f0a4SBarry Smith if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Globus did not accept transfer"); 2895dc0f0a4SBarry Smith } 2905dc0f0a4SBarry Smith PetscFunctionReturn(0); 2915dc0f0a4SBarry Smith } 2925dc0f0a4SBarry Smith 2935dc0f0a4SBarry Smith 294