1*5dc0f0a4SBarry Smith #include <stdint.h> 2*5dc0f0a4SBarry Smith #include <stdlib.h> 3*5dc0f0a4SBarry Smith #include <petscwebclient.h> 4*5dc0f0a4SBarry Smith 5*5dc0f0a4SBarry Smith /* 6*5dc0f0a4SBarry Smith Encodes and decodes from MIME Base64 7*5dc0f0a4SBarry Smith */ 8*5dc0f0a4SBarry Smith static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 9*5dc0f0a4SBarry Smith 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 10*5dc0f0a4SBarry Smith 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 11*5dc0f0a4SBarry Smith 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 12*5dc0f0a4SBarry Smith 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 13*5dc0f0a4SBarry Smith 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 14*5dc0f0a4SBarry Smith 'w', 'x', 'y', 'z', '0', '1', '2', '3', 15*5dc0f0a4SBarry Smith '4', '5', '6', '7', '8', '9', '+', '/'}; 16*5dc0f0a4SBarry Smith 17*5dc0f0a4SBarry Smith static PetscErrorCode base64_encode(const unsigned char *data,unsigned char *encoded_data,size_t len) 18*5dc0f0a4SBarry Smith { 19*5dc0f0a4SBarry Smith static int mod_table[] = {0, 2, 1}; 20*5dc0f0a4SBarry Smith int i,j; 21*5dc0f0a4SBarry Smith size_t input_length,output_length; 22*5dc0f0a4SBarry Smith PetscErrorCode ierr; 23*5dc0f0a4SBarry Smith 24*5dc0f0a4SBarry Smith PetscFunctionBegin; 25*5dc0f0a4SBarry Smith ierr = PetscStrlen((const char*)data,&input_length);CHKERRQ(ierr); 26*5dc0f0a4SBarry Smith output_length = 4 * ((input_length + 2) / 3); 27*5dc0f0a4SBarry Smith if (output_length > len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Output length not large enough"); 28*5dc0f0a4SBarry Smith 29*5dc0f0a4SBarry Smith for (i = 0, j = 0; i < input_length;) { 30*5dc0f0a4SBarry Smith uint32_t octet_a = i < input_length ? (unsigned char)data[i++] : 0; 31*5dc0f0a4SBarry Smith uint32_t octet_b = i < input_length ? (unsigned char)data[i++] : 0; 32*5dc0f0a4SBarry Smith uint32_t octet_c = i < input_length ? (unsigned char)data[i++] : 0; 33*5dc0f0a4SBarry Smith uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c; 34*5dc0f0a4SBarry Smith 35*5dc0f0a4SBarry Smith encoded_data[j++] = encoding_table[(triple >> 3 * 6) & 0x3F]; 36*5dc0f0a4SBarry Smith encoded_data[j++] = encoding_table[(triple >> 2 * 6) & 0x3F]; 37*5dc0f0a4SBarry Smith encoded_data[j++] = encoding_table[(triple >> 1 * 6) & 0x3F]; 38*5dc0f0a4SBarry Smith encoded_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F]; 39*5dc0f0a4SBarry Smith } 40*5dc0f0a4SBarry Smith encoded_data[j] = 0; 41*5dc0f0a4SBarry Smith for (i = 0; i < mod_table[input_length % 3]; i++) encoded_data[output_length - 1 - i] = '='; 42*5dc0f0a4SBarry Smith PetscFunctionReturn(0); 43*5dc0f0a4SBarry Smith } 44*5dc0f0a4SBarry Smith 45*5dc0f0a4SBarry Smith PETSC_UNUSED static PetscErrorCode base64_decode(const unsigned char *data,unsigned char* decoded_data, size_t length) 46*5dc0f0a4SBarry Smith { 47*5dc0f0a4SBarry Smith static char decoding_table[257]; 48*5dc0f0a4SBarry Smith static int decode_table_built = 0; 49*5dc0f0a4SBarry Smith int i,j; 50*5dc0f0a4SBarry Smith PetscErrorCode ierr; 51*5dc0f0a4SBarry Smith size_t input_length,output_length; 52*5dc0f0a4SBarry Smith 53*5dc0f0a4SBarry Smith PetscFunctionBegin; 54*5dc0f0a4SBarry Smith if (!decode_table_built) { 55*5dc0f0a4SBarry Smith for (i = 0; i < 64; i++) decoding_table[(unsigned char) encoding_table[i]] = i; 56*5dc0f0a4SBarry Smith decode_table_built = 1; 57*5dc0f0a4SBarry Smith } 58*5dc0f0a4SBarry Smith 59*5dc0f0a4SBarry Smith ierr = PetscStrlen((const char*)data,&input_length);CHKERRQ(ierr); 60*5dc0f0a4SBarry Smith if (input_length % 4 != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Input length must be divisible by 4"); 61*5dc0f0a4SBarry Smith 62*5dc0f0a4SBarry Smith output_length = input_length / 4 * 3; 63*5dc0f0a4SBarry Smith if (data[input_length - 1] == '=') (output_length)--; 64*5dc0f0a4SBarry Smith if (data[input_length - 2] == '=') (output_length)--; 65*5dc0f0a4SBarry Smith if (output_length > length) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Output length too shore"); 66*5dc0f0a4SBarry Smith 67*5dc0f0a4SBarry Smith for (i = 0, j = 0; i < input_length;) { 68*5dc0f0a4SBarry Smith uint32_t sextet_a = data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]]; 69*5dc0f0a4SBarry Smith uint32_t sextet_b = data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]]; 70*5dc0f0a4SBarry Smith uint32_t sextet_c = data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]]; 71*5dc0f0a4SBarry Smith uint32_t sextet_d = data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]]; 72*5dc0f0a4SBarry Smith uint32_t triple = (sextet_a << 3 * 6) + (sextet_b << 2 * 6) + (sextet_c << 1 * 6) + (sextet_d << 0 * 6); 73*5dc0f0a4SBarry Smith 74*5dc0f0a4SBarry Smith if (j < output_length) decoded_data[j++] = (triple >> 2 * 8) & 0xFF; 75*5dc0f0a4SBarry Smith if (j < output_length) decoded_data[j++] = (triple >> 1 * 8) & 0xFF; 76*5dc0f0a4SBarry Smith if (j < output_length) decoded_data[j++] = (triple >> 0 * 8) & 0xFF; 77*5dc0f0a4SBarry Smith } 78*5dc0f0a4SBarry Smith decoded_data[j] = 0; 79*5dc0f0a4SBarry Smith PetscFunctionReturn(0); 80*5dc0f0a4SBarry Smith } 81*5dc0f0a4SBarry Smith 82*5dc0f0a4SBarry Smith #if defined(PETSC_HAVE_UNISTD_H) 83*5dc0f0a4SBarry Smith #include <unistd.h> 84*5dc0f0a4SBarry Smith #endif 85*5dc0f0a4SBarry Smith 86*5dc0f0a4SBarry Smith #undef __FUNCT__ 87*5dc0f0a4SBarry Smith #define __FUNCT__ "PetscGlobusAuthorize" 88*5dc0f0a4SBarry Smith /*@C 89*5dc0f0a4SBarry Smith PetscGlobusAuthorize - Get an access token allowing PETSc applications to make Globus file transfer requests 90*5dc0f0a4SBarry Smith 91*5dc0f0a4SBarry Smith Not collective, only the first process in MPI_Comm does anything 92*5dc0f0a4SBarry Smith 93*5dc0f0a4SBarry Smith Input Parameters: 94*5dc0f0a4SBarry Smith + comm - the MPI communicator 95*5dc0f0a4SBarry Smith - tokensize - size of the token array 96*5dc0f0a4SBarry Smith 97*5dc0f0a4SBarry Smith Output Parameters: 98*5dc0f0a4SBarry Smith . access_token - can be used with PetscGlobusUpLoad() for 30 days 99*5dc0f0a4SBarry Smith 100*5dc0f0a4SBarry Smith Notes: This call requires stdout and stdin access from process 0 on the MPI communicator 101*5dc0f0a4SBarry Smith 102*5dc0f0a4SBarry Smith You can run src/sys/webclient/examples/tutorials/globusobtainaccesstoken to get an access token 103*5dc0f0a4SBarry Smith 104*5dc0f0a4SBarry Smith .seealso: PetscGoogleDriveRefresh(), PetscGoogleDriveUpload(), PetscURLShorten(), PetscGlobusUpload() 105*5dc0f0a4SBarry Smith 106*5dc0f0a4SBarry Smith @*/ 107*5dc0f0a4SBarry Smith PetscErrorCode PetscGlobusAuthorize(MPI_Comm comm,char access_token[],size_t tokensize) 108*5dc0f0a4SBarry Smith { 109*5dc0f0a4SBarry Smith SSL_CTX *ctx; 110*5dc0f0a4SBarry Smith SSL *ssl; 111*5dc0f0a4SBarry Smith int sock; 112*5dc0f0a4SBarry Smith PetscErrorCode ierr; 113*5dc0f0a4SBarry Smith char buff[8*1024],*ptr,head[1024]; 114*5dc0f0a4SBarry Smith PetscMPIInt rank; 115*5dc0f0a4SBarry Smith size_t len; 116*5dc0f0a4SBarry Smith PetscBool found; 117*5dc0f0a4SBarry Smith 118*5dc0f0a4SBarry Smith PetscFunctionBegin; 119*5dc0f0a4SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 120*5dc0f0a4SBarry Smith if (!rank) { 121*5dc0f0a4SBarry Smith if (!isatty(fileno(PETSC_STDOUT))) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Requires users input/output"); 122*5dc0f0a4SBarry Smith ierr = PetscPrintf(comm,"Enter globus username:");CHKERRQ(ierr); 123*5dc0f0a4SBarry Smith ptr = fgets(buff, 1024, stdin); 124*5dc0f0a4SBarry Smith if (!ptr) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from stdin: %d", errno); 125*5dc0f0a4SBarry Smith ierr = PetscStrlen(buff,&len);CHKERRQ(ierr); 126*5dc0f0a4SBarry Smith buff[len-1] = ':'; /* remove carriage return at end of line */ 127*5dc0f0a4SBarry Smith 128*5dc0f0a4SBarry Smith ierr = PetscPrintf(comm,"Enter globus password:");CHKERRQ(ierr); 129*5dc0f0a4SBarry Smith ptr = fgets(buff+len, 1024-len, stdin); 130*5dc0f0a4SBarry Smith if (!ptr) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from stdin: %d", errno); 131*5dc0f0a4SBarry Smith ierr = PetscStrlen(buff,&len);CHKERRQ(ierr); 132*5dc0f0a4SBarry Smith buff[len-1] = '\0'; /* remove carriage return at end of line */ 133*5dc0f0a4SBarry Smith ierr = PetscStrcpy(head,"Authorization: Basic ");CHKERRQ(ierr); 134*5dc0f0a4SBarry Smith ierr = base64_encode((const unsigned char*)buff,(unsigned char*)(head+21),sizeof(head)-21);CHKERRQ(ierr); 135*5dc0f0a4SBarry Smith ierr = PetscStrcat(head,"\r\n");CHKERRQ(ierr); 136*5dc0f0a4SBarry Smith 137*5dc0f0a4SBarry Smith ierr = PetscSSLInitializeContext(&ctx);CHKERRQ(ierr); 138*5dc0f0a4SBarry Smith ierr = PetscHTTPSConnect("nexus.api.globusonline.org",443,ctx,&sock,&ssl);CHKERRQ(ierr); 139*5dc0f0a4SBarry 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); 140*5dc0f0a4SBarry Smith ierr = PetscSSLDestroyContext(ctx);CHKERRQ(ierr); 141*5dc0f0a4SBarry Smith close(sock); 142*5dc0f0a4SBarry Smith 143*5dc0f0a4SBarry Smith ierr = PetscPullJSONValue(buff,"access_token",access_token,tokensize,&found);CHKERRQ(ierr); 144*5dc0f0a4SBarry Smith if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Globus did not return access token"); 145*5dc0f0a4SBarry Smith 146*5dc0f0a4SBarry 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); 147*5dc0f0a4SBarry Smith ierr = PetscPrintf(comm,"programs with the option -globus_access_token %s\n",access_token);CHKERRQ(ierr); 148*5dc0f0a4SBarry Smith ierr = PetscPrintf(comm,"to access Globus automatically\n");CHKERRQ(ierr); 149*5dc0f0a4SBarry Smith } 150*5dc0f0a4SBarry Smith PetscFunctionReturn(0); 151*5dc0f0a4SBarry Smith } 152*5dc0f0a4SBarry Smith 153*5dc0f0a4SBarry Smith 154*5dc0f0a4SBarry Smith #undef __FUNCT__ 155*5dc0f0a4SBarry Smith #define __FUNCT__ "PetscGlobusGetTransfers" 156*5dc0f0a4SBarry Smith /*@C 157*5dc0f0a4SBarry Smith PetscGlobusGetTransfers - Get a record of current transfers requested from Globus 158*5dc0f0a4SBarry Smith 159*5dc0f0a4SBarry Smith Not collective, only the first process in MPI_Comm does anything 160*5dc0f0a4SBarry Smith 161*5dc0f0a4SBarry Smith Input Parameters: 162*5dc0f0a4SBarry Smith + comm - the MPI communicator 163*5dc0f0a4SBarry Smith . access_token - Globus access token, if NULL will check in options database for -globus_access_token XXX otherwise 164*5dc0f0a4SBarry Smith will call PetscGlobusAuthorize(). 165*5dc0f0a4SBarry Smith - buffsize - size of the buffer 166*5dc0f0a4SBarry Smith 167*5dc0f0a4SBarry Smith Output Parameters: 168*5dc0f0a4SBarry Smith . buff - location to put Globus information 169*5dc0f0a4SBarry Smith 170*5dc0f0a4SBarry Smith .seealso: PetscGoogleDriveRefresh(), PetscGoogleDriveUpload(), PetscURLShorten(), PetscGlobusUpload(), PetscGlobusAuthorize() 171*5dc0f0a4SBarry Smith 172*5dc0f0a4SBarry Smith @*/ 173*5dc0f0a4SBarry Smith PetscErrorCode PetscGlobusGetTransfers(MPI_Comm comm,const char access_token[],char buff[],size_t buffsize) 174*5dc0f0a4SBarry Smith { 175*5dc0f0a4SBarry Smith SSL_CTX *ctx; 176*5dc0f0a4SBarry Smith SSL *ssl; 177*5dc0f0a4SBarry Smith int sock; 178*5dc0f0a4SBarry Smith PetscErrorCode ierr; 179*5dc0f0a4SBarry Smith char head[4096]; 180*5dc0f0a4SBarry Smith PetscMPIInt rank; 181*5dc0f0a4SBarry Smith 182*5dc0f0a4SBarry Smith PetscFunctionBegin; 183*5dc0f0a4SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 184*5dc0f0a4SBarry Smith if (!rank) { 185*5dc0f0a4SBarry Smith ierr = PetscStrcpy(head,"Authorization : Globus-Goauthtoken ");CHKERRQ(ierr); 186*5dc0f0a4SBarry Smith if (access_token) { 187*5dc0f0a4SBarry Smith ierr = PetscStrcat(head,access_token);CHKERRQ(ierr); 188*5dc0f0a4SBarry Smith } else { 189*5dc0f0a4SBarry Smith PetscBool set; 190*5dc0f0a4SBarry Smith char accesstoken[4096]; 191*5dc0f0a4SBarry Smith ierr = PetscOptionsGetString(NULL,"-globus_access_token",accesstoken,sizeof(accesstoken),&set);CHKERRQ(ierr); 192*5dc0f0a4SBarry Smith if (!set) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Pass in Globus accesstoken or use -globus_access_token XXX"); 193*5dc0f0a4SBarry Smith ierr = PetscStrcat(head,accesstoken);CHKERRQ(ierr); 194*5dc0f0a4SBarry Smith } 195*5dc0f0a4SBarry Smith ierr = PetscStrcat(head,"\r\n");CHKERRQ(ierr); 196*5dc0f0a4SBarry Smith 197*5dc0f0a4SBarry Smith ierr = PetscSSLInitializeContext(&ctx);CHKERRQ(ierr); 198*5dc0f0a4SBarry Smith ierr = PetscHTTPSConnect("transfer.api.globusonline.org",443,ctx,&sock,&ssl);CHKERRQ(ierr); 199*5dc0f0a4SBarry Smith ierr = PetscHTTPSRequest("GET","transfer.api.globusonline.org/v0.10/tasksummary",head,"application/json",NULL,ssl,buff,buffsize);CHKERRQ(ierr); 200*5dc0f0a4SBarry Smith ierr = PetscSSLDestroyContext(ctx);CHKERRQ(ierr); 201*5dc0f0a4SBarry Smith close(sock); 202*5dc0f0a4SBarry Smith } 203*5dc0f0a4SBarry Smith PetscFunctionReturn(0); 204*5dc0f0a4SBarry Smith } 205*5dc0f0a4SBarry Smith 206*5dc0f0a4SBarry Smith #undef __FUNCT__ 207*5dc0f0a4SBarry Smith #define __FUNCT__ "PetscGlobusUpload" 208*5dc0f0a4SBarry Smith /*@C 209*5dc0f0a4SBarry Smith PetscGlobusUpload - Loads a file to Globus 210*5dc0f0a4SBarry Smith 211*5dc0f0a4SBarry Smith Not collective, only the first process in the MPI_Comm uploads the file 212*5dc0f0a4SBarry Smith 213*5dc0f0a4SBarry Smith Input Parameters: 214*5dc0f0a4SBarry Smith + comm - MPI communicator 215*5dc0f0a4SBarry Smith . access_token - obtained with PetscGlobusAuthorize(), pass NULL to use -globus_access_token XXX from the PETSc database 216*5dc0f0a4SBarry Smith - filename - file to upload 217*5dc0f0a4SBarry Smith 218*5dc0f0a4SBarry Smith Options Database: 219*5dc0f0a4SBarry Smith . -globus_access_token XXX 220*5dc0f0a4SBarry Smith 221*5dc0f0a4SBarry Smith .seealso: PetscURLShorten(), PetscGoogleDriveAuthorize(), PetscGoogleDriveRefresh(), PetscGlobusAuthorize() 222*5dc0f0a4SBarry Smith 223*5dc0f0a4SBarry Smith @*/ 224*5dc0f0a4SBarry Smith PetscErrorCode PetscGlobusUpload(MPI_Comm comm,const char access_token[],const char filename[]) 225*5dc0f0a4SBarry Smith { 226*5dc0f0a4SBarry Smith SSL_CTX *ctx; 227*5dc0f0a4SBarry Smith SSL *ssl; 228*5dc0f0a4SBarry Smith int sock; 229*5dc0f0a4SBarry Smith PetscErrorCode ierr; 230*5dc0f0a4SBarry Smith char head[4096],buff[8*1024],body[4096],submission_id[4096]; 231*5dc0f0a4SBarry Smith PetscMPIInt rank; 232*5dc0f0a4SBarry Smith PetscBool flg,found; 233*5dc0f0a4SBarry Smith 234*5dc0f0a4SBarry Smith PetscFunctionBegin; 235*5dc0f0a4SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 236*5dc0f0a4SBarry Smith if (!rank) { 237*5dc0f0a4SBarry Smith ierr = PetscTestFile(filename,'r',&flg);CHKERRQ(ierr); 238*5dc0f0a4SBarry Smith if (!flg) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to find file: %s",filename); 239*5dc0f0a4SBarry Smith 240*5dc0f0a4SBarry Smith ierr = PetscStrcpy(head,"Authorization : Globus-Goauthtoken ");CHKERRQ(ierr); 241*5dc0f0a4SBarry Smith if (access_token) { 242*5dc0f0a4SBarry Smith ierr = PetscStrcat(head,access_token);CHKERRQ(ierr); 243*5dc0f0a4SBarry Smith } else { 244*5dc0f0a4SBarry Smith PetscBool set; 245*5dc0f0a4SBarry Smith char accesstoken[4096]; 246*5dc0f0a4SBarry Smith ierr = PetscOptionsGetString(NULL,"-globus_access_token",accesstoken,sizeof(accesstoken),&set);CHKERRQ(ierr); 247*5dc0f0a4SBarry Smith if (!set) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Pass in Globus accesstoken or use -globus_access_token XXX"); 248*5dc0f0a4SBarry Smith ierr = PetscStrcat(head,accesstoken);CHKERRQ(ierr); 249*5dc0f0a4SBarry Smith } 250*5dc0f0a4SBarry Smith ierr = PetscStrcat(head,"\r\n");CHKERRQ(ierr); 251*5dc0f0a4SBarry Smith 252*5dc0f0a4SBarry Smith /* Get Globus submission id */ 253*5dc0f0a4SBarry Smith ierr = PetscSSLInitializeContext(&ctx);CHKERRQ(ierr); 254*5dc0f0a4SBarry Smith ierr = PetscHTTPSConnect("transfer.api.globusonline.org",443,ctx,&sock,&ssl);CHKERRQ(ierr); 255*5dc0f0a4SBarry Smith ierr = PetscHTTPSRequest("GET","transfer.api.globusonline.org/v0.10/submission_id",head,"application/json",NULL,ssl,buff,sizeof(buff));CHKERRQ(ierr); 256*5dc0f0a4SBarry Smith ierr = PetscSSLDestroyContext(ctx);CHKERRQ(ierr); 257*5dc0f0a4SBarry Smith close(sock); 258*5dc0f0a4SBarry Smith ierr = PetscPullJSONValue(buff,"value",submission_id,sizeof(submission_id),&found);CHKERRQ(ierr); 259*5dc0f0a4SBarry Smith if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Globus did not return submission id"); 260*5dc0f0a4SBarry Smith 261*5dc0f0a4SBarry Smith /* build JSON body of transfer request */ 262*5dc0f0a4SBarry Smith ierr = PetscStrcpy(body,"{");CHKERRQ(ierr); 263*5dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"submission_id",submission_id,sizeof(body));CHKERRQ(ierr); ierr = PetscStrcat(body,",");CHKERRQ(ierr); 264*5dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"DATA_TYPE","transfer",sizeof(body));CHKERRQ(ierr); ierr = PetscStrcat(body,",");CHKERRQ(ierr); 265*5dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"sync_level","null",sizeof(body));CHKERRQ(ierr); ierr = PetscStrcat(body,",");CHKERRQ(ierr); 266*5dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"source_endpoint","barryfsmith#MacBookPro",sizeof(body));CHKERRQ(ierr); ierr = PetscStrcat(body,",");CHKERRQ(ierr); 267*5dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"label","PETSc transfer label",sizeof(body));CHKERRQ(ierr); ierr = PetscStrcat(body,",");CHKERRQ(ierr); 268*5dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"length","1",sizeof(body));CHKERRQ(ierr); ierr = PetscStrcat(body,",");CHKERRQ(ierr); 269*5dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"destination_endpoint","mcs#home",sizeof(body));CHKERRQ(ierr); ierr = PetscStrcat(body,",");CHKERRQ(ierr); 270*5dc0f0a4SBarry Smith 271*5dc0f0a4SBarry Smith ierr = PetscStrcat(body,"\"DATA\": [ {");CHKERRQ(ierr); 272*5dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"source_path","/~/FEM_GPU.pdf",sizeof(body));CHKERRQ(ierr); ierr = PetscStrcat(body,",");CHKERRQ(ierr); 273*5dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"destination_path","/~/FEM_GPU.pdf",sizeof(body));CHKERRQ(ierr); ierr = PetscStrcat(body,",");CHKERRQ(ierr); 274*5dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"verify_size","null",sizeof(body));CHKERRQ(ierr); ierr = PetscStrcat(body,",");CHKERRQ(ierr); 275*5dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"recursive","false",sizeof(body));CHKERRQ(ierr); ierr = PetscStrcat(body,",");CHKERRQ(ierr); 276*5dc0f0a4SBarry Smith ierr = PetscPushJSONValue(body,"DATA_TYPE","transfer_item",sizeof(body));CHKERRQ(ierr); 277*5dc0f0a4SBarry Smith ierr = PetscStrcat(body,"} ] }");CHKERRQ(ierr); 278*5dc0f0a4SBarry Smith 279*5dc0f0a4SBarry Smith ierr = PetscSSLInitializeContext(&ctx);CHKERRQ(ierr); 280*5dc0f0a4SBarry Smith ierr = PetscHTTPSConnect("transfer.api.globusonline.org",443,ctx,&sock,&ssl);CHKERRQ(ierr); 281*5dc0f0a4SBarry Smith ierr = PetscHTTPSRequest("POST","transfer.api.globusonline.org/v0.10/transfer",head,"application/json",body,ssl,buff,sizeof(buff));CHKERRQ(ierr); 282*5dc0f0a4SBarry Smith ierr = PetscSSLDestroyContext(ctx);CHKERRQ(ierr); 283*5dc0f0a4SBarry Smith close(sock); 284*5dc0f0a4SBarry Smith ierr = PetscPullJSONValue(buff,"code",submission_id,sizeof(submission_id),&found);CHKERRQ(ierr); 285*5dc0f0a4SBarry Smith if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Globus did not return code on transfer"); 286*5dc0f0a4SBarry Smith ierr = PetscStrcmp(submission_id,"Accepted",&found);CHKERRQ(ierr); 287*5dc0f0a4SBarry Smith if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Globus did not accept transfer"); 288*5dc0f0a4SBarry Smith } 289*5dc0f0a4SBarry Smith PetscFunctionReturn(0); 290*5dc0f0a4SBarry Smith } 291*5dc0f0a4SBarry Smith 292*5dc0f0a4SBarry Smith 293