1b967cddfSBarry Smith 20efc6a03SBarry Smith #include <petscwebclient.h> 3bb04b57dSBarry Smith #pragma clang diagnostic ignored "-Wdeprecated-declarations" 445e40e47SBarry Smith #pragma gcc diagnostic ignored "-Wdeprecated-declarations" 5b967cddfSBarry Smith 6b967cddfSBarry Smith static BIO *bio_err = NULL; 7b967cddfSBarry Smith 8b967cddfSBarry Smith #define PASSWORD "password" 9b967cddfSBarry Smith 104a285bdaSBarry Smith #if defined(PETSC_USE_SSL_CERTIFICATE) 11b967cddfSBarry Smith static int password_cb(char *buf,int num, int rwflag,void *userdata) 12b967cddfSBarry Smith { 13b967cddfSBarry Smith if (num < strlen(PASSWORD)+1) return(0); 14b967cddfSBarry Smith strcpy(buf,PASSWORD); 15b967cddfSBarry Smith return(strlen(PASSWORD)); 16b967cddfSBarry Smith } 17b967cddfSBarry Smith #endif 18b967cddfSBarry Smith 19b967cddfSBarry Smith static void sigpipe_handle(int x) 20b967cddfSBarry Smith { 21b967cddfSBarry Smith } 22b967cddfSBarry Smith 23b967cddfSBarry Smith #undef __FUNCT__ 24b967cddfSBarry Smith #define __FUNCT__ "PetscSSLInitializeContext" 25*4683183fSBarry Smith /*@C 26b967cddfSBarry Smith PetscSSLInitializeContext - Set up an SSL context suitable for initiating HTTPS requests. 27b967cddfSBarry Smith 28*4683183fSBarry Smith Output Parameter: 29*4683183fSBarry Smith . octx - the SSL_CTX to be passed to PetscHTTPSConnect 30b967cddfSBarry Smith 31*4683183fSBarry Smith Level: advanced 32*4683183fSBarry Smith 33*4683183fSBarry Smith If PETSc was ./configure -with-ssl-certificate requires the user have created a self-signed certificate with 3468e69593SBarry Smith $ saws/CA.pl -newcert (using the passphrase of password) 35b967cddfSBarry Smith $ cat newkey.pem newcert.pem > sslclient.pem 36b967cddfSBarry Smith 37b967cddfSBarry Smith and put the resulting file in either the current directory (with the application) or in the home directory. This seems kind of 38b967cddfSBarry Smith silly but it was all I could figure out. 39b967cddfSBarry Smith 40*4683183fSBarry Smith .seealso: PetscSSLDestroyContext(), PetscHTTPSConnect(), PetscHTTPSRequest() 41*4683183fSBarry Smith 42*4683183fSBarry Smith @*/ 43b967cddfSBarry Smith PetscErrorCode PetscSSLInitializeContext(SSL_CTX **octx) 44b967cddfSBarry Smith { 45b967cddfSBarry Smith SSL_CTX *ctx; 464a285bdaSBarry Smith #if defined(PETSC_USE_SSL_CERTIFICATE) 47b967cddfSBarry Smith char keyfile[PETSC_MAX_PATH_LEN]; 48b967cddfSBarry Smith PetscBool exists; 49b967cddfSBarry Smith PetscErrorCode ierr; 50b967cddfSBarry Smith #endif 51b967cddfSBarry Smith 52b967cddfSBarry Smith PetscFunctionBegin; 53b967cddfSBarry Smith if (!bio_err){ 54b967cddfSBarry Smith SSL_library_init(); 55b967cddfSBarry Smith SSL_load_error_strings(); 56b967cddfSBarry Smith bio_err = BIO_new_fp(stderr,BIO_NOCLOSE); 57b967cddfSBarry Smith } 58b967cddfSBarry Smith 59b967cddfSBarry Smith /* Set up a SIGPIPE handler */ 60b967cddfSBarry Smith signal(SIGPIPE,sigpipe_handle); 61b967cddfSBarry Smith 62d8dcb26dSBarry Smith ctx = SSL_CTX_new(SSLv23_method()); 635dc0f0a4SBarry Smith SSL_CTX_set_mode(ctx,SSL_MODE_AUTO_RETRY); 64b967cddfSBarry Smith 654a285bdaSBarry Smith #if defined(PETSC_USE_SSL_CERTIFICATE) 66b967cddfSBarry Smith /* Locate keyfile */ 67b967cddfSBarry Smith ierr = PetscStrcpy(keyfile,"sslclient.pem");CHKERRQ(ierr); 68b967cddfSBarry Smith ierr = PetscTestFile(keyfile,'r',&exists);CHKERRQ(ierr); 69b967cddfSBarry Smith if (!exists) { 70b967cddfSBarry Smith ierr = PetscGetHomeDirectory(keyfile,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 71b967cddfSBarry Smith ierr = PetscStrcat(keyfile,"/");CHKERRQ(ierr); 72b967cddfSBarry Smith ierr = PetscStrcat(keyfile,"sslclient.pem");CHKERRQ(ierr); 73b967cddfSBarry Smith ierr = PetscTestFile(keyfile,'r',&exists);CHKERRQ(ierr); 74b967cddfSBarry Smith if (!exists) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate sslclient.pem file in current directory or home directory"); 75b967cddfSBarry Smith } 76b967cddfSBarry Smith 77b967cddfSBarry Smith /* Load our keys and certificates*/ 78b967cddfSBarry Smith if (!(SSL_CTX_use_certificate_chain_file(ctx,keyfile))) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot read certificate file"); 79b967cddfSBarry Smith 80b967cddfSBarry Smith SSL_CTX_set_default_passwd_cb(ctx,password_cb); 81b967cddfSBarry Smith if (!(SSL_CTX_use_PrivateKey_file(ctx,keyfile,SSL_FILETYPE_PEM))) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot read key file"); 82b967cddfSBarry Smith #endif 83b967cddfSBarry Smith 84b967cddfSBarry Smith *octx = ctx; 85b967cddfSBarry Smith PetscFunctionReturn(0); 86b967cddfSBarry Smith } 87b967cddfSBarry Smith 88b967cddfSBarry Smith #undef __FUNCT__ 89b967cddfSBarry Smith #define __FUNCT__ "PetscSSLDestroyContext" 90*4683183fSBarry Smith /*@C 91*4683183fSBarry Smith PetscSSLDestroyContext - frees a SSL_CTX obtained with PetscSSLInitializeContext() 92*4683183fSBarry Smith 93*4683183fSBarry Smith Input Parameter: 94*4683183fSBarry Smith . ctx - the SSL_CTX 95*4683183fSBarry Smith 96*4683183fSBarry Smith Level: advanced 97*4683183fSBarry Smith 98*4683183fSBarry Smith .seealso: PetscSSLInitializeContext(), PetscHTTPSConnect() 99*4683183fSBarry Smith @*/ 100b967cddfSBarry Smith PetscErrorCode PetscSSLDestroyContext(SSL_CTX *ctx) 101b967cddfSBarry Smith { 102b967cddfSBarry Smith PetscFunctionBegin; 103b967cddfSBarry Smith SSL_CTX_free(ctx); 104b967cddfSBarry Smith PetscFunctionReturn(0); 105b967cddfSBarry Smith } 106b967cddfSBarry Smith 107b967cddfSBarry Smith #undef __FUNCT__ 10804102261SBarry Smith #define __FUNCT__ "PetscHTTPBuildRequest" 109*4683183fSBarry Smith static PetscErrorCode PetscHTTPBuildRequest(const char type[],const char url[],const char header[],const char ctype[],const char body[],char **outrequest) 110b967cddfSBarry Smith { 111b967cddfSBarry Smith char *request=0; 11293e1d32fSBarry Smith char contentlength[40],contenttype[80],*path,*host; 1137a3410edSBarry Smith size_t request_len,headlen,bodylen,contentlen,pathlen,hostlen,typelen,contenttypelen = 0; 114b967cddfSBarry Smith PetscErrorCode ierr; 115b967cddfSBarry Smith PetscBool flg; 116b967cddfSBarry Smith 117b967cddfSBarry Smith PetscFunctionBegin; 11893e1d32fSBarry Smith ierr = PetscStrallocpy(url,&host);CHKERRQ(ierr); 11993e1d32fSBarry Smith ierr = PetscStrchr(host,'/',&path);CHKERRQ(ierr); 12093e1d32fSBarry Smith if (!path) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"url must contain / it is %s",url); 121c245270aSBarry Smith *path = 0; 12293e1d32fSBarry Smith ierr = PetscStrlen(host,&hostlen);CHKERRQ(ierr); 12393e1d32fSBarry Smith 12493e1d32fSBarry Smith ierr = PetscStrchr(url,'/',&path);CHKERRQ(ierr); 12593e1d32fSBarry Smith ierr = PetscStrlen(path,&pathlen);CHKERRQ(ierr); 12693e1d32fSBarry Smith 127b967cddfSBarry Smith if (header) { 128b967cddfSBarry Smith ierr = PetscStrendswith(header,"\r\n",&flg);CHKERRQ(ierr); 129b967cddfSBarry Smith if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"header must end with \\r\\n"); 130b967cddfSBarry Smith } 131b967cddfSBarry Smith 132b967cddfSBarry Smith ierr = PetscStrlen(type,&typelen);CHKERRQ(ierr); 133b967cddfSBarry Smith if (ctype) { 134b967cddfSBarry Smith ierr = PetscSNPrintf(contenttype,80,"Content-Type: %s\r\n",ctype);CHKERRQ(ierr); 135b967cddfSBarry Smith ierr = PetscStrlen(contenttype,&contenttypelen);CHKERRQ(ierr); 136b967cddfSBarry Smith } 137b967cddfSBarry Smith ierr = PetscStrlen(header,&headlen);CHKERRQ(ierr); 138b967cddfSBarry Smith ierr = PetscStrlen(body,&bodylen);CHKERRQ(ierr); 139b967cddfSBarry Smith ierr = PetscSNPrintf(contentlength,40,"Content-Length: %d\r\n\r\n",(int)bodylen);CHKERRQ(ierr); 140b967cddfSBarry Smith ierr = PetscStrlen(contentlength,&contentlen);CHKERRQ(ierr); 141b967cddfSBarry Smith 142b967cddfSBarry Smith /* Now construct our HTTP request */ 14393e1d32fSBarry Smith request_len = typelen + 1 + pathlen + hostlen + 100 + headlen + contenttypelen + contentlen + bodylen + 1; 144fe278a28SBarry Smith ierr = PetscMalloc1(request_len,&request);CHKERRQ(ierr); 145b967cddfSBarry Smith ierr = PetscStrcpy(request,type);CHKERRQ(ierr); 146b967cddfSBarry Smith ierr = PetscStrcat(request," ");CHKERRQ(ierr); 14793e1d32fSBarry Smith ierr = PetscStrcat(request,path);CHKERRQ(ierr); 14893e1d32fSBarry Smith ierr = PetscStrcat(request," HTTP/1.1\r\nHost: ");CHKERRQ(ierr); 14993e1d32fSBarry Smith ierr = PetscStrcat(request,host);CHKERRQ(ierr); 15093e1d32fSBarry Smith ierr = PetscFree(host);CHKERRQ(ierr); 15193e1d32fSBarry Smith ierr = PetscStrcat(request,"\r\nUser-Agent:PETScClient\r\n");CHKERRQ(ierr); 152b967cddfSBarry Smith ierr = PetscStrcat(request,header);CHKERRQ(ierr); 153b967cddfSBarry Smith if (ctype) { 154b967cddfSBarry Smith ierr = PetscStrcat(request,contenttype);CHKERRQ(ierr); 155b967cddfSBarry Smith } 156b967cddfSBarry Smith ierr = PetscStrcat(request,contentlength);CHKERRQ(ierr); 157b967cddfSBarry Smith ierr = PetscStrcat(request,body);CHKERRQ(ierr); 158b967cddfSBarry Smith ierr = PetscStrlen(request,&request_len);CHKERRQ(ierr); 159b967cddfSBarry Smith ierr = PetscInfo1(NULL,"HTTPS request follows: \n%s\n",request);CHKERRQ(ierr); 160b967cddfSBarry Smith 16104102261SBarry Smith *outrequest = request; 16204102261SBarry Smith PetscFunctionReturn(0); 16304102261SBarry Smith } 16404102261SBarry Smith 16504102261SBarry Smith 16604102261SBarry Smith #undef __FUNCT__ 16704102261SBarry Smith #define __FUNCT__ "PetscHTTPSRequest" 168*4683183fSBarry Smith /*@C 16904102261SBarry Smith PetscHTTPSRequest - Send a request to an HTTPS server 17004102261SBarry Smith 17104102261SBarry Smith Input Parameters: 17204102261SBarry Smith + type - either "POST" or "GET" 17304102261SBarry Smith . url - URL of request host/path 17404102261SBarry Smith . header - additional header information, may be NULL 17504102261SBarry Smith . ctype - data type of body, for example application/json 17604102261SBarry Smith . body - data to send to server 17704102261SBarry Smith . ssl - obtained with PetscHTTPSConnect() 17804102261SBarry Smith - buffsize - size of buffer 17904102261SBarry Smith 18004102261SBarry Smith Output Parameter: 18104102261SBarry Smith . buff - everything returned from server 182*4683183fSBarry Smith 183*4683183fSBarry Smith Level: advanced 184*4683183fSBarry Smith 185*4683183fSBarry Smith .seealso: PetscHTTPRequest(), PetscHTTPSConnect(), PetscSSLInitializeContext(), PetscSSLDestroyContext(), PetscPullJSONValue() 186*4683183fSBarry Smith 187*4683183fSBarry Smith @*/ 18804102261SBarry Smith PetscErrorCode PetscHTTPSRequest(const char type[],const char url[],const char header[],const char ctype[],const char body[],SSL *ssl,char buff[],size_t buffsize) 18904102261SBarry Smith { 19004102261SBarry Smith char *request; 19104102261SBarry Smith int r; 19204102261SBarry Smith size_t request_len,len; 19304102261SBarry Smith PetscErrorCode ierr; 1945dc0f0a4SBarry Smith PetscBool foundbody = PETSC_FALSE; 19504102261SBarry Smith 19604102261SBarry Smith PetscFunctionBegin; 19704102261SBarry Smith ierr = PetscHTTPBuildRequest(type,url,header,ctype,body,&request);CHKERRQ(ierr); 19804102261SBarry Smith ierr = PetscStrlen(request,&request_len);CHKERRQ(ierr); 19904102261SBarry Smith 200d8dcb26dSBarry Smith r = SSL_write(ssl,request,(int)request_len); 201b967cddfSBarry Smith switch (SSL_get_error(ssl,r)){ 202b967cddfSBarry Smith case SSL_ERROR_NONE: 203d8dcb26dSBarry Smith if (request_len != (size_t)r) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Incomplete write to SSL socket"); 204b967cddfSBarry Smith break; 205b967cddfSBarry Smith default: 206b967cddfSBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SSL socket write problem"); 207b967cddfSBarry Smith } 208b967cddfSBarry Smith 2095dc0f0a4SBarry Smith /* Now read the server's response, globus sends it in two chunks hence must read a second time if needed */ 2105dc0f0a4SBarry Smith ierr = PetscMemzero(buff,buffsize);CHKERRQ(ierr); 2115dc0f0a4SBarry Smith len = 0; 2125dc0f0a4SBarry Smith foundbody = PETSC_FALSE; 2135dc0f0a4SBarry Smith do { 2145dc0f0a4SBarry Smith char *clen; 2155dc0f0a4SBarry Smith int cl; 2165dc0f0a4SBarry Smith size_t nlen; 2175dc0f0a4SBarry Smith 2185dc0f0a4SBarry Smith r = SSL_read(ssl,buff+len,(int)buffsize); 2195dc0f0a4SBarry Smith len += r; 220b967cddfSBarry Smith switch (SSL_get_error(ssl,r)){ 221b967cddfSBarry Smith case SSL_ERROR_NONE: 222b967cddfSBarry Smith break; 223b967cddfSBarry Smith case SSL_ERROR_ZERO_RETURN: 2245dc0f0a4SBarry Smith foundbody = PETSC_TRUE; 2255dc0f0a4SBarry Smith SSL_shutdown(ssl); 226b967cddfSBarry Smith break; 227b967cddfSBarry Smith case SSL_ERROR_SYSCALL: 2285dc0f0a4SBarry Smith foundbody = PETSC_TRUE; 229b967cddfSBarry Smith break; 230b967cddfSBarry Smith default: 231b967cddfSBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SSL read problem"); 232b967cddfSBarry Smith } 2335dc0f0a4SBarry Smith 2345dc0f0a4SBarry Smith ierr = PetscStrstr(buff,"Content-Length: ",&clen);CHKERRQ(ierr); 2355dc0f0a4SBarry Smith if (clen) { 2365dc0f0a4SBarry Smith clen += 15; 2375dc0f0a4SBarry Smith sscanf(clen,"%d",&cl); 2385dc0f0a4SBarry Smith if (!cl) foundbody = PETSC_TRUE; 2395dc0f0a4SBarry Smith else { 2405dc0f0a4SBarry Smith ierr = PetscStrstr(buff,"\r\n\r\n",&clen);CHKERRQ(ierr); 2415dc0f0a4SBarry Smith if (clen) { 2425dc0f0a4SBarry Smith ierr = PetscStrlen(clen,&nlen);CHKERRQ(ierr); 2435dc0f0a4SBarry Smith if (nlen-4 == (size_t) cl) foundbody = PETSC_TRUE; 2445dc0f0a4SBarry Smith } 2455dc0f0a4SBarry Smith } 2465dc0f0a4SBarry Smith } else { 2475dc0f0a4SBarry Smith /* if no content length than must leave because you don't know if you can read again */ 2485dc0f0a4SBarry Smith foundbody = PETSC_TRUE; 2495dc0f0a4SBarry Smith } 2505dc0f0a4SBarry Smith } while (!foundbody); 251b967cddfSBarry Smith ierr = PetscInfo1(NULL,"HTTPS result follows: \n%s\n",buff);CHKERRQ(ierr); 252b967cddfSBarry Smith 253b967cddfSBarry Smith SSL_free(ssl); 254b967cddfSBarry Smith ierr = PetscFree(request);CHKERRQ(ierr); 255b967cddfSBarry Smith PetscFunctionReturn(0); 256b967cddfSBarry Smith } 257b967cddfSBarry Smith 258b967cddfSBarry Smith #undef __FUNCT__ 25904102261SBarry Smith #define __FUNCT__ "PetscHTTPRequest" 260*4683183fSBarry Smith /*@C 26104102261SBarry Smith PetscHTTPRequest - Send a request to an HTTP server 26204102261SBarry Smith 26304102261SBarry Smith Input Parameters: 26404102261SBarry Smith + type - either "POST" or "GET" 26504102261SBarry Smith . url - URL of request host/path 26604102261SBarry Smith . header - additional header information, may be NULL 26704102261SBarry Smith . ctype - data type of body, for example application/json 26804102261SBarry Smith . body - data to send to server 26904102261SBarry Smith . sock - obtained with PetscOpenSocket() 27004102261SBarry Smith - buffsize - size of buffer 27104102261SBarry Smith 27204102261SBarry Smith Output Parameter: 27304102261SBarry Smith . buff - everything returned from server 274*4683183fSBarry Smith 275*4683183fSBarry Smith Level: advanced 276*4683183fSBarry Smith 277*4683183fSBarry Smith .seealso: PetscHTTPSRequest(), PetscOpenSocket(), PetscHTTPSConnect(), PetscPullJSONValue() 278*4683183fSBarry Smith @*/ 27904102261SBarry Smith PetscErrorCode PetscHTTPRequest(const char type[],const char url[],const char header[],const char ctype[],const char body[],int sock,char buff[],size_t buffsize) 28004102261SBarry Smith { 28104102261SBarry Smith char *request; 28204102261SBarry Smith size_t request_len; 28304102261SBarry Smith PetscErrorCode ierr; 28404102261SBarry Smith 28504102261SBarry Smith PetscFunctionBegin; 28604102261SBarry Smith ierr = PetscHTTPBuildRequest(type,url,header,ctype,body,&request);CHKERRQ(ierr); 28704102261SBarry Smith ierr = PetscStrlen(request,&request_len);CHKERRQ(ierr); 28804102261SBarry Smith 28904102261SBarry Smith ierr = PetscBinaryWrite(sock,request,request_len,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr); 29004102261SBarry Smith ierr = PetscFree(request);CHKERRQ(ierr); 29104102261SBarry Smith PetscBinaryRead(sock,buff,buffsize,PETSC_CHAR); 29204102261SBarry Smith buff[buffsize-1] = 0; 29304102261SBarry Smith ierr = PetscInfo1(NULL,"HTTP result follows: \n%s\n",buff);CHKERRQ(ierr); 29404102261SBarry Smith PetscFunctionReturn(0); 29504102261SBarry Smith } 29604102261SBarry Smith 29704102261SBarry Smith #undef __FUNCT__ 298b967cddfSBarry Smith #define __FUNCT__ "PetscHTTPSConnect" 299*4683183fSBarry Smith /*@C 300*4683183fSBarry Smith PetscHTTPSConnect - connect to a HTTPS server 301*4683183fSBarry Smith 302*4683183fSBarry Smith Input Parameters: 303*4683183fSBarry Smith + host - the name of the machine hosting the HTTPS server 304*4683183fSBarry Smith . port - the port number where the server is hosting, usually 443 305*4683183fSBarry Smith - ctx - value obtained with PetscSSLInitializeContext() 306*4683183fSBarry Smith 307*4683183fSBarry Smith Output Parameters: 308*4683183fSBarry Smith + sock - socket to connect 309*4683183fSBarry Smith - ssl - the argument passed to PetscHTTPSRequest() 310*4683183fSBarry Smith 311*4683183fSBarry Smith Level: advanced 312*4683183fSBarry Smith 313*4683183fSBarry Smith .seealso: PetscOpenSocket(), PetscHTTPSRequest(), PetscSSLInitializeContext() 314*4683183fSBarry Smith @*/ 315b967cddfSBarry Smith PetscErrorCode PetscHTTPSConnect(const char host[],int port,SSL_CTX *ctx,int *sock,SSL **ssl) 316b967cddfSBarry Smith { 317b967cddfSBarry Smith BIO *sbio; 318b967cddfSBarry Smith PetscErrorCode ierr; 319b967cddfSBarry Smith 320b967cddfSBarry Smith PetscFunctionBegin; 321b967cddfSBarry Smith /* Connect the TCP socket*/ 322b967cddfSBarry Smith ierr = PetscOpenSocket(host,port,sock);CHKERRQ(ierr); 323b967cddfSBarry Smith 324b967cddfSBarry Smith /* Connect the SSL socket */ 325b967cddfSBarry Smith *ssl = SSL_new(ctx); 326b967cddfSBarry Smith sbio = BIO_new_socket(*sock,BIO_NOCLOSE); 327b967cddfSBarry Smith SSL_set_bio(*ssl,sbio,sbio); 328b967cddfSBarry Smith if (SSL_connect(*ssl) <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SSL connect error"); 329b967cddfSBarry Smith PetscFunctionReturn(0); 330b967cddfSBarry Smith } 331b967cddfSBarry Smith 33268e69593SBarry Smith #undef __FUNCT__ 33368e69593SBarry Smith #define __FUNCT__ "PetscPullJSONValue" 334*4683183fSBarry Smith /*@C 335*4683183fSBarry Smith PetscPullJSONValue - Given a JSON response containing the substring with "key" : "value" where there may or not be spaces around the : returns the value. 336*4683183fSBarry Smith 337*4683183fSBarry Smith Input Parameters: 338*4683183fSBarry Smith + buff - the char array containing the possible values 339*4683183fSBarry Smith . key - the key of the requested value 340*4683183fSBarry Smith - valuelen - the length of the array to contain the value associated with the key 341*4683183fSBarry Smith 342*4683183fSBarry Smith Output Parameters: 343*4683183fSBarry Smith + value - the value obtained 344*4683183fSBarry Smith - found - flag indicating if the value was found in the buff 345*4683183fSBarry Smith 346*4683183fSBarry Smith Level: advanced 347*4683183fSBarry Smith 348*4683183fSBarry Smith @*/ 34968e69593SBarry Smith PetscErrorCode PetscPullJSONValue(const char buff[],const char key[],char value[],size_t valuelen,PetscBool *found) 35068e69593SBarry Smith { 35168e69593SBarry Smith PetscErrorCode ierr; 35268e69593SBarry Smith char *v,*w; 35368e69593SBarry Smith char work[256]; 35468e69593SBarry Smith size_t len; 35568e69593SBarry Smith 35668e69593SBarry Smith PetscFunctionBegin; 35768e69593SBarry Smith ierr = PetscStrcpy(work,"\"");CHKERRQ(ierr); 35868e69593SBarry Smith ierr = PetscStrncat(work,key,250);CHKERRQ(ierr); 35968e69593SBarry Smith ierr = PetscStrcat(work,"\":");CHKERRQ(ierr); 36068e69593SBarry Smith ierr = PetscStrstr(buff,work,&v);CHKERRQ(ierr); 36168e69593SBarry Smith ierr = PetscStrlen(work,&len);CHKERRQ(ierr); 36268e69593SBarry Smith if (v) { 36368e69593SBarry Smith v += len; 36468e69593SBarry Smith } else { 36568e69593SBarry Smith work[len++-1] = 0; 36668e69593SBarry Smith ierr = PetscStrcat(work," :");CHKERRQ(ierr); 36768e69593SBarry Smith ierr = PetscStrstr(buff,work,&v);CHKERRQ(ierr); 36868e69593SBarry Smith if (!v) { 36968e69593SBarry Smith *found = PETSC_FALSE; 37068e69593SBarry Smith PetscFunctionReturn(0); 37168e69593SBarry Smith } 37268e69593SBarry Smith v += len; 37368e69593SBarry Smith } 37468e69593SBarry Smith ierr = PetscStrchr(v,'\"',&v);CHKERRQ(ierr); 37568e69593SBarry Smith if (!v) { 37668e69593SBarry Smith *found = PETSC_FALSE; 37768e69593SBarry Smith PetscFunctionReturn(0); 37868e69593SBarry Smith } 37968e69593SBarry Smith ierr = PetscStrchr(v+1,'\"',&w);CHKERRQ(ierr); 38068e69593SBarry Smith if (!w) { 38168e69593SBarry Smith *found = PETSC_FALSE; 38268e69593SBarry Smith PetscFunctionReturn(0); 38368e69593SBarry Smith } 38468e69593SBarry Smith *found = PETSC_TRUE; 385c1f4622dSBarry Smith ierr = PetscStrncpy(value,v+1,PetscMin((size_t)(w-v),valuelen));CHKERRQ(ierr); 38668e69593SBarry Smith PetscFunctionReturn(0); 38768e69593SBarry Smith } 3885dc0f0a4SBarry Smith 3895dc0f0a4SBarry Smith #include <ctype.h> 3905dc0f0a4SBarry Smith 3915dc0f0a4SBarry Smith #undef __FUNCT__ 3925dc0f0a4SBarry Smith #define __FUNCT__ "PetscPushJSONValue" 393*4683183fSBarry Smith /*@C 394*4683183fSBarry Smith PetscPushJSONValue - Puts a "key" : "value" pair onto a string 3955dc0f0a4SBarry Smith 396*4683183fSBarry Smith Input Parameters: 397*4683183fSBarry Smith + buffer - the char array where the value will be put 398*4683183fSBarry Smith . key - the key value to be set 399*4683183fSBarry Smith . value - the value associated with the key 400*4683183fSBarry Smith - bufflen - the size of the buffer (currently ignored) 401*4683183fSBarry Smith 402*4683183fSBarry Smith Level: advanced 403*4683183fSBarry Smith 404*4683183fSBarry Smith Notes: Ignores lengths so can cause buffer overflow 405*4683183fSBarry Smith @*/ 4065dc0f0a4SBarry Smith PetscErrorCode PetscPushJSONValue(char buff[],const char key[],const char value[],size_t bufflen) 4075dc0f0a4SBarry Smith { 4085dc0f0a4SBarry Smith PetscErrorCode ierr; 4095dc0f0a4SBarry Smith size_t len; 4105dc0f0a4SBarry Smith PetscBool special; 4115dc0f0a4SBarry Smith 4125dc0f0a4SBarry Smith PetscFunctionBegin; 4135dc0f0a4SBarry Smith ierr = PetscStrcmp(value,"null",&special);CHKERRQ(ierr); 4145dc0f0a4SBarry Smith if (!special) { 4155dc0f0a4SBarry Smith ierr = PetscStrcmp(value,"true",&special);CHKERRQ(ierr); 4165dc0f0a4SBarry Smith } 4175dc0f0a4SBarry Smith if (!special) { 4185dc0f0a4SBarry Smith ierr = PetscStrcmp(value,"false",&special);CHKERRQ(ierr); 4195dc0f0a4SBarry Smith } 4205dc0f0a4SBarry Smith if (!special) { 4215dc0f0a4SBarry Smith PetscInt i; 4225dc0f0a4SBarry Smith 4235dc0f0a4SBarry Smith ierr = PetscStrlen(value,&len);CHKERRQ(ierr); 4245dc0f0a4SBarry Smith special = PETSC_TRUE; 4255dc0f0a4SBarry Smith for (i=0; i<(int)len; i++) { 4265dc0f0a4SBarry Smith if (!isdigit(value[i])) { 4275dc0f0a4SBarry Smith special = PETSC_FALSE; 4285dc0f0a4SBarry Smith break; 4295dc0f0a4SBarry Smith } 4305dc0f0a4SBarry Smith } 4315dc0f0a4SBarry Smith } 4325dc0f0a4SBarry Smith 4335dc0f0a4SBarry Smith ierr = PetscStrcat(buff,"\"");CHKERRQ(ierr); 4345dc0f0a4SBarry Smith ierr = PetscStrcat(buff,key);CHKERRQ(ierr); 4355dc0f0a4SBarry Smith ierr = PetscStrcat(buff,"\":");CHKERRQ(ierr); 4365dc0f0a4SBarry Smith if (!special) { 4375dc0f0a4SBarry Smith ierr = PetscStrcat(buff,"\"");CHKERRQ(ierr); 4385dc0f0a4SBarry Smith } 4395dc0f0a4SBarry Smith ierr = PetscStrcat(buff,value);CHKERRQ(ierr); 4405dc0f0a4SBarry Smith if (!special) { 4415dc0f0a4SBarry Smith ierr = PetscStrcat(buff,"\"");CHKERRQ(ierr); 4425dc0f0a4SBarry Smith } 4435dc0f0a4SBarry Smith PetscFunctionReturn(0); 4445dc0f0a4SBarry Smith } 445