diff --git a/SuperNET/Makefile b/SuperNET/Makefile index 7310ee0d1..90045f33c 100644 --- a/SuperNET/Makefile +++ b/SuperNET/Makefile @@ -8,12 +8,12 @@ VALID_TOOLCHAINS := pnacl newlib glibc clang-newlib mac NACL_SDK_ROOT ?= $(abspath $(CURDIR)) - TARGET = SuperNET EXTRA= -D__PNACL include $(NACL_SDK_ROOT)/tools/common.mk +include SuperNET.sources CHROME_ARGS += --allow-nacl-socket-api=127.0.0.1 @@ -23,7 +23,7 @@ LIBS = crypto777 nanomsg curl ssl crypto z glibc-compat nacl_spawn ppapi nacl_i CFLAGS = -Wall -D__PNACL -fno-strict-aliasing $(EXTRA) LFLAGS = libs -SOURCES = main.c SuperNET.c +SOURCES = $(SOURCES) # Build rules generated by macros from common.mk: diff --git a/SuperNET/SuperNET.c b/SuperNET/SuperNET.c index d7a7a23ac..5f807e552 100644 --- a/SuperNET/SuperNET.c +++ b/SuperNET/SuperNET.c @@ -14,6 +14,139 @@ ******************************************************************************/ #include "SuperNET.h" +#define IGUANA_FORMS "[ \ +\ +{\"disp\":\"simple explorer\",\"agent\":\"ramchain\",\"method\":\"explore\",\"fields\":[{\"skip\":1,\"field\":\"search\",\"cols\":65,\"rows\":1}]}, \ +{\"disp\":\"block height\",\"agent\":\"ramchain\",\"method\":\"block\",\"fields\":[{\"field\":\"height\",\"cols\":10,\"rows\":1}]}, \ +{\"disp\":\"block hash\",\"agent\":\"ramchain\",\"method\":\"block\",\"fields\":[{\"field\":\"hash\",\"cols\":65,\"rows\":1}]}, \ +{\"disp\":\"txid\",\"agent\":\"ramchain\",\"method\":\"txid\",\"fields\":[{\"skip\":1,\"field\":\"hash\",\"cols\":65,\"rows\":1}]}, \ +{\"disp\":\"status\",\"agent\":\"ramchain\",\"method\":\"status\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":1,\"rows\":1}]}, \ +{\"disp\":\"bundleinfo\",\"agent\":\"ramchain\",\"method\":\"bundleinfo\",\"fields\":[{\"skip\":1,\"field\":\"height\",\"cols\":12,\"rows\":1}]}, \ +\ +{\"disp\":\"addcoin\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":8,\"rows\":1}]}, \ +{\"disp\":\"pausecoin\",\"agent\":\"iguana\",\"method\":\"pausecoin\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":1,\"rows\":1}]}, \ +{\"disp\":\"startcoin\",\"agent\":\"iguana\",\"method\":\"startcoin\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":1,\"rows\":1}]}, \ +{\"disp\":\"addnode\",\"agent\":\"iguana\",\"method\":\"addnode\",\"fields\":[{\"skip\":1,\"field\":\"ipaddr\",\"cols\":32,\"rows\":1}]}, \ +{\"disp\":\"maxpeers\",\"agent\":\"iguana\",\"method\":\"maxpeers\",\"fields\":[{\"skip\":1,\"field\":\"max\",\"cols\":8,\"rows\":1}]}, \ +{\"disp\":\"peers\",\"agent\":\"iguana\",\"method\":\"peers\",\"fields\":[{\"field\":\"coin\",\"cols\":16,\"rows\":1}]}, \ +{\"disp\":\"nodestatus\",\"agent\":\"iguana\",\"method\":\"nodestatus\",\"fields\":[{\"skip\":1,\"field\":\"ipaddr\",\"cols\":32,\"rows\":1}]}, \ +\ +{\"disp\":\"rates\",\"agent\":\"PAX\",\"method\":\"rates\",\"fields\":[{\"skip\":1,\"field\":\"peg\",\"cols\":16,\"rows\":1}]},\ +{\"disp\":\"prices\",\"agent\":\"PAX\",\"method\":\"prices\",\"fields\":[{\"skip\":1,\"field\":\"peg\",\"cols\":16,\"rows\":1}]},\ +{\"agent\":\"PAX\",\"method\":\"lock\",\"fields\":[{\"skip\":1,\"field\":\"peg\",\"cols\":16,\"rows\":1},{\"skip\":1,\"field\":\"lockdays\",\"cols\":6,\"rows\":1},{\"skip\":1,\"field\":\"units\",\"cols\":12,\"rows\":1}]}, \ +{\"agent\":\"PAX\",\"method\":\"redeem\",\"fields\":[{\"skip\":1,\"field\":\"txid\",\"cols\":65,\"rows\":1},{\"skip\":1,\"field\":\"dest\",\"cols\":65,\"rows\":1}]},\ +{\"disp\":\"balance\",\"agent\":\"PAX\",\"method\":\"balance\",\"fields\":[{\"skip\":1,\"field\":\"address\",\"cols\":44,\"rows\":1}]},\ +{\"agent\":\"PAX\",\"method\":\"rollover\",\"fields\":[{\"skip\":1,\"field\":\"txid\",\"cols\":16,\"rows\":1},{\"skip\":1,\"field\":\"newpeg\",\"cols\":16,\"rows\":1},{\"skip\":1,\"field\":\"newlockdays\",\"cols\":6,\"rows\":1}]},\ +{\"agent\":\"PAX\",\"method\":\"swap\",\"fields\":[{\"skip\":1,\"field\":\"txid\",\"cols\":16,\"rows\":1},{\"skip\":1,\"field\":\"othertxid\",\"cols\":16,\"rows\":1}]},\ +{\"agent\":\"PAX\",\"method\":\"bet\",\"fields\":[{\"skip\":1,\"field\":\"peg\",\"cols\":16,\"rows\":1},{\"skip\":1,\"field\":\"price\",\"cols\":16,\"rows\":1},{\"skip\":1,\"field\":\"amount\",\"cols\":16,\"rows\":1}]},\ +\ +{\"agent\":\"InstantDEX\",\"method\":\"placebid\",\"fields\":[{\"skip\":1,\"field\":\"base\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"rel\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"exchange\",\"cols\":16,\"rows\":1},{\"field\":\"price\",\"cols\":16,\"rows\":1},{\"field\":\"volume\",\"cols\":16,\"rows\":1}]}, \ +{\"agent\":\"InstantDEX\",\"method\":\"placeask\",\"fields\":[{\"skip\":1,\"field\":\"base\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"rel\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"exchange\",\"cols\":16,\"rows\":1},{\"field\":\"price\",\"cols\":16,\"rows\":1},{\"field\":\"volume\",\"cols\":16,\"rows\":1}]}, \ +{\"agent\":\"InstantDEX\",\"method\":\"orderbook\",\"fields\":[{\"skip\":1,\"field\":\"base\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"rel\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"exchange\",\"cols\":16,\"rows\":1}]}, \ +{\"disp\":\"orderstatus\",\"agent\":\"InstantDEX\",\"method\":\"orderstatus\",\"fields\":[{\"skip\":1,\"field\":\"orderid\",\"cols\":32,\"rows\":1}]}, \ +{\"disp\":\"cancelorder\",\"agent\":\"InstantDEX\",\"method\":\"cancelorder\",\"fields\":[{\"skip\":1,\"field\":\"orderid\",\"cols\":32,\"rows\":1}]}, \ +{\"disp\":\"balance\",\"agent\":\"InstantDEX\",\"method\":\"balance\",\"fields\":[{\"skip\":1,\"field\":\"exchange\",\"cols\":16,\"rows\":1}]}, \ +{\"newline\":0,\"disp\":\"allorderbooks\",\"agent\":\"InstantDEX\",\"method\":\"allorderbooks\",\"fields\":[{\"skip\":1,\"field\":\"allorderbooks\",\"cols\":1,\"rows\":1}]}, \ +{\"newline\":0,\"disp\":\"openorders\",\"agent\":\"InstantDEX\",\"method\":\"openorders\",\"fields\":[{\"skip\":1,\"field\":\"openorders\",\"cols\":1,\"rows\":1}]}, \ +{\"newline\":0,\"disp\":\"tradehistory\",\"agent\":\"InstantDEX\",\"method\":\"tradehistory\",\"fields\":[{\"skip\":1,\"field\":\"tradehistory\",\"cols\":1,\"rows\":1}]}, \ +{\"disp\":\"allexchanges\",\"agent\":\"InstantDEX\",\"method\":\"allexchanges\",\"fields\":[{\"skip\":1,\"field\":\"allexchanges\",\"cols\":1,\"rows\":1}]}, \ +\ +{\"agent\":\"pangea\",\"method\":\"bet\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":24,\"rows\":1},{\"skip\":1,\"field\":\"amount\",\"cols\":24,\"rows\":1}]}, \ +{\"disp\":\"call\",\"agent\":\"pangea\",\"method\":\"call\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":1,\"rows\":1}]}, \ +{\"disp\":\"fold\",\"agent\":\"pangea\",\"method\":\"fold\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":1,\"rows\":1}]}, \ +{\"disp\":\"status\",\"agent\":\"pangea\",\"method\":\"status\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":1,\"rows\":1}]}, \ +{\"disp\":\"hand history\",\"agent\":\"pangea\",\"method\":\"handhistory\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":1,\"rows\":1}]}, \ +{\"disp\":\"history\",\"agent\":\"pangea\",\"method\":\"history\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":1,\"rows\":1}]}, \ +{\"disp\":\"follow\",\"agent\":\"pangea\",\"method\":\"follow\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":24,\"rows\":1}]}, \ +{\"disp\":\"lobby\",\"agent\":\"pangea\",\"method\":\"lobby\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":8,\"rows\":1}]}, \ +{\"disp\":\"join\",\"agent\":\"pangea\",\"method\":\"join\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":24,\"rows\":1}]}, \ +{\"agent\":\"pangea\",\"method\":\"buyin\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"tableid\",\"cols\":24,\"rows\":1},{\"skip\":1,\"field\":\"amount\",\"cols\":12,\"rows\":1}]}, \ +{\"agent\":\"pangea\",\"method\":\"newtournament\",\"fields\":[{\"field\":\"mintables\",\"cols\":8,\"rows\":1},{\"field\":\"maxtables\",\"cols\":4,\"rows\":1},{\"field\":\"starttime\",\"cols\":16,\"rows\":1},{\"field\":\"prizefund\",\"cols\":12,\"rows\":1},{\"field\":\"coin\",\"cols\":12,\"rows\":1}]}, \ +{\"agent\":\"pangea\",\"method\":\"newtable\",\"fields\":[{\"field\":\"minplayers\",\"cols\":4,\"rows\":1},{\"field\":\"maxplayers\",\"cols\":4,\"rows\":1},{\"field\":\"rake\",\"cols\":4,\"rows\":1},{\"field\":\"bigblind\",\"cols\":12,\"rows\":1},{\"field\":\"ante\",\"cols\":12,\"rows\":1},{\"field\":\"minbuyin\",\"cols\":12,\"rows\":1},{\"field\":\"maxbuyin\",\"cols\":12,\"rows\":1}]}, \ +{\"disp\":\"leave\",\"agent\":\"pangea\",\"method\":\"leave\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":8,\"rows\":1}]}, \ +\ +{\"agent\":\"jumblr\",\"method\":\"send\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"amount\",\"cols\":13,\"rows\":1},{\"skip\":1,\"field\":\"address\",\"cols\":8,\"rows\":1}]}, \ +{\"agent\":\"jumblr\",\"method\":\"invoice\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"amount\",\"cols\":13,\"rows\":1},{\"skip\":1,\"field\":\"address\",\"cols\":8,\"rows\":1}]}, \ +{\"agent\":\"jumblr\",\"method\":\"shuffle\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"amount\",\"cols\":13,\"rows\":1}]}, \ +{\"agent\":\"jumblr\",\"method\":\"balance\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"address\",\"cols\":13,\"rows\":1}]}, \ +\ +{\"newline\":0,\"disp\":\"InstantDEX\",\"agent\":\"iguana\",\"method\":\"setagent\",\"fields\":[{\"field\":\"InstantDEX\",\"cols\":1,\"rows\":1}]}, \ +{\"newline\":0,\"disp\":\"PAX\",\"agent\":\"iguana\",\"method\":\"setagent\",\"fields\":[{\"field\":\"PAX\",\"cols\":1,\"rows\":1}]}, \ +{\"newline\":0,\"disp\":\"pangea\",\"agent\":\"iguana\",\"method\":\"setagent\",\"fields\":[{\"field\":\"pangea\",\"cols\":1,\"rows\":1}]}, \ +{\"newline\":0,\"disp\":\"jumblr\",\"agent\":\"iguana\",\"method\":\"setagent\",\"fields\":[{\"field\":\"jumblr\",\"cols\":1,\"rows\":1}]}, \ +{\"disp\":\"ramchain\",\"agent\":\"iguana\",\"method\":\"setagent\",\"fields\":[{\"field\":\"ramchain\",\"cols\":1,\"rows\":1}]}, \ +{\"newline\":0,\"disp\":\"iguana\",\"agent\":\"iguana\",\"method\":\"setagent\",\"fields\":[{\"field\":\"iguana\",\"cols\":1,\"rows\":1}]}, \ +\ +{\"agent\":\"hash\",\"method\":\"NXT\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":100,\"rows\":1}]}, \ +{\"agent\":\"hash\",\"method\":\"curve25519\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"rmd160_sha256\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"sha256_sha256\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"base64_encode\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"base64_decode\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"crc32\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"sha512\",\"fields\":[{\"skip\":1,\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"sha384\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"sha256\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"sha224\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"rmd320\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"rmd256\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"rmd160\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"rmd128\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"sha1\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"md2\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"md4\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"md5\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"tiger\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"whirlpool\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_sha512\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_sha384\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_sha256\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_sha224\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_rmd320\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_rmd256\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_rmd160\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_rmd128\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_sha1\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_md2\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_md4\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_md5\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_tiger\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_whirlpool\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}\ +]" + +char *HTMLheader = +" \ + \ + \ + \ + \ +iguana \ + \ + \ +\ + \ +"; + +// Link + +char *HTMLfooter = +" \ +\ + \ + \ +\ + \ + \ + \ + \ + \ + \ + \ +\ + \ +"; + +#define HTML_EMIT(str) if ( (str) != 0 && (str)[0] != 0 ) strcpy(&retbuf[size],str), size += (int32_t)strlen(str) /* struct endpoint find_epbits(struct relay_info *list,uint32_t ipbits,uint16_t port,int32_t type) @@ -265,3 +398,339 @@ void SuperNET_init(struct supernet_info *myinfo,char *jsonstr) init_SUPERNET_pullsock(myinfo,10,10); }*/ +int32_t Supernet_lineparse(char *key,int32_t keymax,char *value,int32_t valuemax,char *src) +{ + int32_t a,b,c,n = 0; + key[0] = value[0] = 0; + while ( (c= src[n]) == ' ' || c == '\t' || c == '\n' || c == '\t' ) + n++; + while ( (c= src[n]) != ':' && c != 0 ) + { + *key++ = c; + if ( ++n >= keymax-1 ) + { + *key = 0; + printf("lineparse overflow key.(%s)\n",src); + return(-1); + } + } + *key = 0; + if ( src[n] != ':' ) + return(n); + n++; + while ( (c= src[n]) == ' ' || c == '\t' ) + n++; + while ( (c= src[n]) != 0 && c != '\r' && c != '\n' ) + { + if ( c == '%' && (a= src[n+1]) != 0 && (b= src[n+2]) != 0 ) + c = ((unhex(a) << 4) | unhex(b)), n += 2; + *value++ = c; + n++; + if ( n >= valuemax-1 ) + { + *value = 0; + printf("lineparse overflow.(%s)\n",src); + return(-1); + } + } + *value = 0; + if ( src[n] != 0 ) + { + n++; + while ( (c= src[n]) == '\r' || c == '\n' ) + n++; + } + return(n); +} + +cJSON *SuperNET_urlconv(char *value,int32_t bufsize,char *urlstr) +{ + int32_t i,n,totallen,datalen,len = 0; cJSON *json,*array; char key[8192],*data; + json = cJSON_CreateObject(); + array = cJSON_CreateArray(); + totallen = (int32_t)strlen(urlstr); + while ( 1 ) + { + for (i=len; urlstr[i]!=0; i++) + if ( urlstr[i] == '\r' || urlstr[i] == '\n' ) + break; + if ( i == len && (urlstr[len] == '\r' || urlstr[len] == '\n') ) + { + len++; + continue; + } + urlstr[i] = 0; + if ( (n= Supernet_lineparse(key,sizeof(key),value,bufsize,&urlstr[len])) > 0 ) + { + if ( value[0] != 0 ) + jaddstr(json,key,value); + else jaddistr(array,key); + len += (n + 1); + if ( strcmp(key,"Content-Length") == 0 && (datalen= atoi(value)) > 0 ) + { + data = &urlstr[totallen - datalen]; + data[-1] = 0; + //printf("post.(%s) (%c)\n",data,data[0]); + jaddstr(json,"POST",data); + } + } else break; + } + jadd(json,"lines",array); + return(json); +} + +char *SuperNET_rpcparse(struct supernet_info *myinfo,char *retbuf,int32_t bufsize,int32_t *postflagp,char *urlstr,char *remoteaddr) +{ + cJSON *tokens,*argjson,*json = 0; char urlmethod[16],*data,url[1024],*retstr,*token = 0; int32_t i,j,n; + //printf("rpcparse.(%s)\n",urlstr); + for (i=0; i 0 ) + { + jaddstr(argjson,"agent",jstri(tokens,0)); + if ( n > 1 ) + jaddstr(argjson,"method",jstri(tokens,1)); + for (i=2; i (%s) postflag.%d (%s)\n",urlstr,cJSON_Print(json),*postflagp,jprint(argjson,0)); + return(retstr); + } + return(clonestr("{\"error\":\"couldnt process packet\"}")); +} + +#ifdef notyet +int32_t iguana_htmlgen(char *retbuf,int32_t bufsize,char *result,char *error,cJSON *json,char *tabname,char *origjsonstr) +{ + char *url = "http://127.0.0.1:7778"; + int i,j,m,size = 0,n,rows,cols; cJSON *array,*obj,*array2,*item,*tmp; + char formheader[512],formfooter[512],clickname[512],buf[512],fieldbuf[512],fieldindex[2],postjson[8192]; + char *disp,*fieldname,*button,*agent,*method,*str; + bufsize--; + HTML_EMIT("

"); + sprintf(buf,"
"); + //sprintf(buf,"
COIN: "); + //HTML_EMIT(buf); + //HTML_EMIT(" Agent: "); HTML_EMIT(Default_agent); + + HTML_EMIT("

"); + HTML_EMIT(origjsonstr); HTML_EMIT(" -> "); + HTML_EMIT(""); + formheader[0] = formfooter[0] = 0; + if ( (array= jarray(&n,json,"forms")) != 0 ) + { + for (i=0; i function click_%s()\n{\n",clickname); + HTML_EMIT(buf); + sprintf(postjson,"%s/%s",agent,method); + //printf("form.%s button.%s [%s]\n",formname,button,postjson); + if ( (array2= jarray(&m,item,"fields")) != 0 ) + { + //sprintf(buf,"COIN = document.COIN_NAME.value;\n"); + //sprintf(postjson+strlen(postjson),"/%s/' + %s + '","coin","COIN"); + for (j=0; j (%s)\n",j,jprint(obj,0)); + sprintf(fieldindex,"%c",'A'+j); + if ( (fieldname= jstr(obj,"field")) != 0 ) + { + sprintf(buf,"%s = document.%s.%s.value;\n",fieldindex,clickname,fieldname); + HTML_EMIT(buf); + //sprintf(postjson+strlen(postjson),",\"%s\":\"' + %s + '\"",fieldname,fieldindex); + if ( juint(obj,"skip") == 0 ) + sprintf(postjson+strlen(postjson),"/%s/' + %s + '",fieldname,fieldindex); + else sprintf(postjson+strlen(postjson),"/' + %s + '",fieldindex); + } + } + //strcat(postjson,"}"); + sprintf(&retbuf[size],"location.href = '%s/%s';\n}\r\n",url,postjson), size += strlen(&retbuf[size]); + sprintf(formheader,"
",clickname,url); + HTML_EMIT(formheader); + disp = jstr(item,"disp"); + for (j=0; j",fieldname); + else sprintf(buf,"",cols,rows,fieldname,cols == 1 ? "hidden" : ""); + str = disp==0?jstr(obj,"disp"):disp; + sprintf(&retbuf[size],"\r\n",str!=0?str:fieldname,buf), size += strlen(&retbuf[size]); + } + sprintf(formfooter,"\n
%s %s
",button,clickname); + HTML_EMIT(formfooter); + } + } + } + HTML_EMIT("

"); HTML_EMIT(""); HTML_EMIT("

"); + return((int32_t)strlen(retbuf)); +} +#undef HTML_EMIT + +char *SuperNET_htmlresponse(char *retbuf,int32_t bufsize,int32_t *remainsp,int32_t localaccess,char *retstr,int32_t freeflag) +{ + static char *html = " %s "; + char *result=0,*error=0; int32_t n; cJSON *json,*formsjson; + retbuf[0] = 0; + /*if ( localaccess == 0 ) + sprintf(retbuf+strlen(retbuf),"Access-Control-Allow-Origin: *\r\n"); + else sprintf(retbuf+strlen(retbuf),"Access-Control-Allow-Origin: null\r\n"); + sprintf(retbuf+strlen(retbuf),"Access-Control-Allow-Credentials: true\r\n"); + sprintf(retbuf+strlen(retbuf),"Access-Control-Allow-Headers: Authorization, Content-Type\r\n"); + sprintf(retbuf+strlen(retbuf),"Access-Control-Allow-Methods: GET, POST\r\n"); + sprintf(retbuf+strlen(retbuf),"Cache-Control: no-cache, no-store, must-revalidate\r\n"); + sprintf(retbuf+strlen(retbuf),"Content-type: text/html\r\n"); + sprintf(retbuf+strlen(retbuf),"Content-Length: %8d\r\n\r\n",n);*/ + sprintf(retbuf+strlen(retbuf),"\n\r"); + n = (int32_t)strlen(retbuf); + formsjson = cJSON_Parse(IGUANA_FORMS); + if ( (json= cJSON_Parse(retstr)) == 0 ) + json = cJSON_CreateObject(); + jadd(json,"forms",formsjson); + error = jstr(json,"error"); + result = jstr(json,"result"); + //printf("process.(%s)\n",jprint(formsjson,0)); + n = iguana_htmlgen(&retbuf[n],bufsize-n,result,error,json,"iguana",Currentjsonstr); + free_json(json); + if ( n == 0 ) + { + n = (int32_t)(strlen(html) + strlen(retstr) + 1); + sprintf(retbuf+strlen(retbuf),html,retstr); + } + if ( freeflag != 0 ) + free(retstr); + if ( n > bufsize ) + { + printf("htmlresponse overflowed buffer[%d] with %d\n",bufsize,n); + exit(-1); + } + *remainsp = n; + return(retbuf); +} +#endif diff --git a/SuperNET/SuperNET.h b/SuperNET/SuperNET.h index c9e7efb55..7a3f7fd29 100644 --- a/SuperNET/SuperNET.h +++ b/SuperNET/SuperNET.h @@ -20,7 +20,7 @@ #include "../includes/cJSON.h" #include "../includes/nanomsg/nn.h" -#define SUPERNET_PORT 7774 +#define SUPERNET_PORT 7778 #define SUPERNET_NETWORKTIMEOUT 10000 #define SUPERNET_POLLTIMEOUT 1 #define SUPERNET_APIUSLEEP (SUPERNET_POLLTIMEOUT * 10000) @@ -83,6 +83,8 @@ struct endpoint calc_epbits(char *transport,uint32_t ipbits,uint16_t port,int32_ int32_t badass_servers(char servers[][MAX_SERVERNAME],int32_t max,int32_t port); int32_t crackfoo_servers(char servers[][MAX_SERVERNAME],int32_t max,int32_t port); void SuperNET_init(); +char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *argjson,char *remoteaddr); +char *SuperNET_rpcparse(struct supernet_info *myinfo,char *retbuf,int32_t bufsize,int32_t *postflagp,char *urlstr,char *remoteaddr); extern int32_t PULLsock; extern struct relay_info RELAYS; diff --git a/SuperNET/m_osx b/SuperNET/m_osx index edf4f7b28..8ec8d6032 100755 --- a/SuperNET/m_osx +++ b/SuperNET/m_osx @@ -1 +1 @@ -gcc -o ../agents/SuperNET -O2 *.c ../agents/libcrypto777.a -lssl -lcrypto -lpthread -lm +gcc -o ../agents/SuperNET -O2 *.c ../agents/libcrypto777.a -lnanomsg -lssl -lcrypto -lpthread -lm diff --git a/SuperNET/m_unix b/SuperNET/m_unix index a2dff2084..8ec8d6032 100755 --- a/SuperNET/m_unix +++ b/SuperNET/m_unix @@ -1 +1 @@ -gcc -o ../agents/SuperNET -O2 *.c ../agents/libcrypto777.a -lssl -lcrypto -lpthread -lm +gcc -o ../agents/SuperNET -O2 *.c ../agents/libcrypto777.a -lnanomsg -lssl -lcrypto -lpthread -lm diff --git a/SuperNET/main.c b/SuperNET/main.c index 2d13dea5b..1ba57afe1 100644 --- a/SuperNET/main.c +++ b/SuperNET/main.c @@ -162,11 +162,6 @@ int32_t SuperNET_msgvalidate(struct supernet_msghdr *msg) return(msglen); } -char *SuperNET_JSON(struct supernet_info *myinfo,char *jsonstr) -{ - return(clonestr("{\"error\":\"SuperNET is just a stub for now\"}")); -} - int32_t nn_settimeouts(int32_t sock,int32_t sendtimeout,int32_t recvtimeout) { int32_t retrymillis,maxmillis; @@ -215,25 +210,10 @@ int32_t nn_createsocket(struct supernet_info *myinfo,char *endpoint,int32_t bind bits256 SuperNET_OPRETURN(struct supernet_info *myinfo,char *symbol,double fee,uint8_t *buf,int32_t len) { bits256 txid; + printf("send OPRETURN\n"); return(txid); } -/*int32_t SuperNET_OPRETURN(uint8_t *data,char *announce) -{ - static char *protocols[][2] = { {"pangea","GEA"}, {"peggy","PAX"} }; - int32_t i; - for (i=0; i= 0 ) + { + clilen = sizeof(cli_addr); + //printf("ACCEPT (%s:%d) on sock.%d\n","127.0.0.1",port,bindsock); + sock = accept(bindsock,(struct sockaddr *)&cli_addr,&clilen); + if ( sock < 0 ) + { + //printf("iguana_rpcloop ERROR on accept usock.%d\n",sock); + continue; + } + memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); + expand_ipbits(remoteaddr,ipbits); + memset(jsonbuf,0,sizeof(jsonbuf)); + remains = (int32_t)(sizeof(jsonbuf) - 1); + buf = jsonbuf; + recvlen = 0; + retstr = 0; + while ( remains > 0 ) + { + if ( (len= (int32_t)recv(sock,buf,remains,0)) < 0 ) + { + if ( errno == EAGAIN ) + { + printf("EAGAIN for len %d, remains.%d\n",len,remains); + usleep(10000); + } + break; + } + else + { + if ( len > 0 ) + { + remains -= len; + recvlen += len; + buf = &buf[len]; + retstr = SuperNET_rpcparse(myinfo,space,size,&postflag,jsonbuf,remoteaddr); + break; + } else usleep(10000); + } + } + if ( retstr != 0 ) + { + i = 0; + if ( postflag == 0 ) + { + //retstr = SuperNET_htmlresponse(space,size,&remains,1,retstr,1); + } + else remains = (int32_t)strlen(retstr); + printf("RETBUF.(%s)\n",retstr); + while ( remains > 0 ) + { + if ( (numsent= (int32_t)send(sock,&retstr[i],remains,MSG_NOSIGNAL)) < 0 ) + { + if ( errno != EAGAIN && errno != EWOULDBLOCK ) + { + //printf("%s: %s numsent.%d vs remains.%d len.%d errno.%d (%s) usock.%d\n",retstr,ipaddr,numsent,remains,recvlen,errno,strerror(errno),sock); + break; + } + } + else if ( remains > 0 ) + { + remains -= numsent; + i += numsent; + if ( remains > 0 ) + printf("iguana sent.%d remains.%d of len.%d\n",numsent,remains,recvlen); + } + } + if ( retstr != space ) + free(retstr); + } + //printf("done response sock.%d\n",sock); + closesocket(sock); + } +} + int32_t SuperNET_msgrecv(struct supernet_info *myinfo,struct supernet_agent *agent,uint8_t *_buf,int32_t maxlen) { int32_t len,recvlen; void *buf = _buf; struct supernet_msghdr H; @@ -647,7 +720,7 @@ void SuperNET_loop(struct supernet_info *myinfo) void SuperNET_main(void *arg) { - struct supernet_info MYINFO; cJSON *json,*array; uint16_t port; int32_t i,n = 0; + struct supernet_info MYINFO; int32_t i;//cJSON *json,*array; uint16_t port;,n = 0; memset(&MYINFO,0,sizeof(MYINFO)); if ( 1 ) { @@ -658,8 +731,8 @@ void SuperNET_main(void *arg) if ( MYINFO.POLLTIMEOUT == 0 ) MYINFO.POLLTIMEOUT = SUPERNET_POLLTIMEOUT; } - if ( arg == 0 || (json= cJSON_Parse(arg)) == 0 ) - SuperNET_acceptport(&MYINFO,MYINFO.port); + /*if ( arg == 0 || (json= cJSON_Parse(arg)) == 0 ) + SuperNET_acceptport(&MYINFO,MYINFO.acceptport); else { if ( (array= jarray(&n,json,"accept")) != 0 ) @@ -669,9 +742,9 @@ void SuperNET_main(void *arg) SuperNET_acceptport(&MYINFO,port); } free_json(json); - } - sleep(3); - printf("start SuperNET_loop on port.%u\n",MYINFO.port); + }*/ + printf("start SuperNET_loop on port.%u\n",SUPERNET_PORT); + OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)SuperNET_rpcloop,&MYINFO); for (i=0; i datenum + number of seconds + checkval = OS_conv_datenum(datenum,seconds/3600,(seconds/60)%60,seconds%60); // datenum+H:M:S -> unix time + if ( checkval != timestamp ) + printf("%s i.%lld timestamp.%-12llu -> (%d:%06d) -> checkval.%-12llu diff.[%lld]\n",tai_str(str,t),(long long)i,(long long)timestamp,datenum,seconds,(long long)checkval,(long long)(timestamp-checkval)); + } + printf("million tai compares in %.3f microseconds per encode/decode\n",1000. * (OS_milliseconds()-startmillis)/i); + } return 0; } #endif diff --git a/crypto777/ccgi.c b/crypto777/ccgi.c new file mode 100755 index 000000000..e42349033 --- /dev/null +++ b/crypto777/ccgi.c @@ -0,0 +1,1328 @@ +/* + * C CGI Library version 1.1 + * + * Author: Stephen C. Losen, University of Virginia + * + * Copyright 2009 Stephen C. Losen. Distributed under the terms + * of the GNU General Public License (GPL) + * + * C CGI is a C language library for parsing, decoding, storing and + * retrieving data passed from a web browser to a CGI program. C CGI + * supports URL encoded form data (application/x-www-form-urlencoded) + * and multipart (mutlipart/form-data), including file uploads. HTML + * cookies can also be stored and retrieved. + * + * The library builds one or more "variable lists" of type + * CGI_varlist. A list entry consists of a name (null terminated + * string) and one or more values (also null terminated strings) + * associated with the name. We allow multiple values because 1) + * some HTML form elements (such as checkboxes and selections) + * allow the form user to select multiple values and 2) different + * form elements may be given the same name. + * + * The library function CGI_lookup_all() searches a variable list for + * an entry with the specified name and returns the values in a + * null terminated array of pointers to null terminated strings. + * + * Variable list entries can be obtained iteratively with + * CGI_first_name(), CGI_next_name() and CGI_lookup_all(). + * + * For a file upload, the user provides a filename template that + * is passed to mkstemp() to create a new file to hold the data. + */ + +#include +#include +#include +#include +#include +#include +#include "../includes/ccgi.h" +#ifdef _WIN32 +#define mkstemp(name) _mktemp_s(name, sizeof(name)) +#endif + +/* CGI_val is an entry in a list of variable values */ + +typedef struct CGI_val CGI_val; + +struct CGI_val { + CGI_val *next; /* next entry on list */ + const char value[1]; /* variable value */ +}; + +/* + * CGI_varlist is an entry in a list of variables. The fields + * "iter" and "tail" are only used in the first list entry. + */ + +struct CGI_varlist { + CGI_varlist *next; /* next entry on list */ + CGI_varlist *tail; /* last entry on list */ + CGI_varlist *iter; /* list iteration pointer */ + int numvalue; /* number of values */ + CGI_val *value; /* linked list of values */ + CGI_val *valtail; /* last value on list */ + CGI_value *vector; /* array of values */ + const char varname[1]; /* variable name */ +}; + +/* strbuf is a string buffer of arbitrary size */ + +typedef struct { + int size; + char str[1]; +} +strbuf; + +/* mymalloc() is a malloc() wrapper that exits on failure */ + +static void * +mymalloc(int size) { + void *ret = malloc(size); + if (ret == 0) { + fputs("C CGI Library out of memory\n", stderr); + exit(1); + } + return ret; +} + +/* + * sb_get() creates or extends a strbuf + */ + +static strbuf * +sb_get(strbuf *sb, int len) { + int size; + for (size = 128; size < len; size += size) + ; + if (sb == 0) { + sb = (strbuf *) mymalloc(sizeof(*sb) + size); + } + else { + sb = (strbuf *) realloc(sb, sizeof(*sb) + size); + if (sb == 0) { + fputs("C CGI Library out of memory\n", stderr); + exit(1); + } + } + sb->size = size; + return sb; +} + +/* savechar() saves a character in a strbuf at index idx */ + +static strbuf * +savechar(strbuf *sb, int idx, int c) { + if (sb == 0 || idx >= sb->size) { + sb = sb_get(sb, idx + 1); + } + sb->str[idx] = c; + return sb; +} + +/* savestr() saves a string in a strbuf */ + +static strbuf * +savestr(strbuf *sb, const char *str) { + int len = (int)strlen(str); + if (sb == 0 || len >= sb->size) { + sb = sb_get(sb, len + 1); + } + strcpy(sb->str, str); + return sb; +} + +/* + * findvar() searches variable list "v" for an entry whose name + * is "varname" and returns a pointer to the entry or else null + * if not found. If varname is null then we return v->iter, + * which is the "current" variable entry. + */ + +static CGI_varlist * +findvar(CGI_varlist *v, const char *varname) { + if (varname == 0 && v != 0) { + return v->iter; + } + for (; v != 0; v = v->next) { + if (v->varname[0] == varname[0] && + strcmp(v->varname, varname) == 0) + { + break; + } + } + return v; +} + +/* + * hex() returns the numeric value of hexadecimal digit "digit" + * or returns -1 if "digit" is not a hexadecimal digit. + */ + +static int +hex(int digit) { + switch(digit) { + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + return digit - '0'; + + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + return 10 + digit - 'A'; + + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + return 10 + digit - 'a'; + + default: + return -1; + } +} + +/* urlcount() returns the number of bytes needed to URL encode a string */ + +static int +urlcount(const char *p, const char *keep) { + int k; + for (k = 0; *p != 0; p++) { + if (isalnum((int32_t)*p) || *p == ' ' || + (keep != 0 && strchr(keep, *p) != 0)) + { + k++; + } + else { + k += 3; + } + } + return k; +} + +/* + * urlencode() URL encodes string "in" into string "out" and + * returns a pointer to the null byte at the end of "out" + */ + +static char * +urlencode(const char *in, char *out, const char *keep) { + const char hexdigit[] = "0123456789ABCDEF"; + + for (; *in != 0; in++) { + if (isalnum((int32_t)*in) || + (keep != 0 && strchr(keep, *in) != 0)) + { + *out++ = *in; + } + else if (*in == ' ') { + *out++ = '+'; + } + else { + *out++ = '%'; + *out++ = hexdigit[(*in >> 4) & 0xf]; + *out++ = hexdigit[*in & 0xf]; + } + } + *out = 0; + return out; +} + +/* scanspaces() scans over spaces and tabs in a string */ + +static char * +scanspaces(char *p) { + while (*p == ' ' || *p == '\t') { + p++; + } + return p; +} + +/* + * scanattr() scans for an attribute such as name="value" or + * name=value; saving the attribute name in attr[0] and saving + * the attribute value in attr[1]. If successful, we return a + * pointer to where the scan ended, otherwise we return null. + * The input string is modified. + */ + +static char * +scanattr(char *p, char *attr[2]) { + int quote = 0; + + attr[0] = p = scanspaces(p); + while (*p != '=' && *p != 0) { + p++; + } + if (*p != '=' || p == attr[0]) { + return 0; + } + *p++ = 0; + if (*p == '"' || *p == '\'' || *p == '`') { + quote = *p++; + } + attr[1] = p; + if (quote != 0) { + while(*p != quote && *p != 0) { + p++; + } + if (*p != quote) { + return 0; + } + *p++ = 0; + if (*p == ';') { + p++; + } + } + else { + while (*p != ';' && *p != ' ' && *p != '\t' && + *p != '\r' && *p != '\n' && *p != 0) + { + p++; + } + if (*p != 0) { + *p++ = 0; + } + } + return p; +} + +/* + * scanheader() scans a line of input for a header name followed by + * a colon and the header value, such as: + * + * Content-Disposition: form-data; + * + * We place the header name in header[0] and the value in header[1]. + * If successful we return a pointer to the character where the scan + * ended, otherwise we return null. The input string is modified. + */ + +static char * +scanheader(char *p, char *header[2]) { + if (isalnum((int32_t)*p) == 0) { + return 0; + } + header[0] = p; + while (*p != ':' && *p != 0) { + p++; + } + if (*p != ':') { + return 0; + } + *p++ = 0; + header[1] = p = scanspaces(p); + while (*p != ';' && *p != '\r' && *p != '\n' && *p != 0) { + p++; + } + if (*p != 0) { + *p++ = 0; + } + return p; +} + +/* + * readline() reads characters from open file "in" into strbuf "line". + * We stop reading when we encounter '\n' or end of file. We null + * terminate "line" and return it. We return null if we encounter + * end of file without reading any characters. + */ + +static strbuf * +readline(strbuf *line, FILE *in) { + int c, i = 0; + + while ((c = getc(in)) != EOF) { + line = savechar(line, i++, c); + if (c == '\n') { + break; + } + } + if (i == 0) { + if (line != 0) { + free(line); + } + return 0; + } + return savechar(line, i, 0); /* null terminate */ +} + +/* + * copyvalue() reads bytes from open file "in", which contains + * "multipart/form-data", delimited by "boundary". We read + * bytes until we encounter the boundary. If the flag "wantfile" + * is true then we write the bytes (minus the boundary) to open + * file pointer "out" (or discard the output if "out" is NULL). + * Otherwise we copy the bytes to "value". + */ + +static strbuf * +copyvalue(const char *boundary, FILE *in, const int wantfile, + strbuf *value, FILE *out) +{ + int c, i, k, matched; + + matched = k = 0; + + while ((c = getc(in)) != EOF) { + + /* + * If we partially match the boundary, then we copy the + * entire matching prefix to the output. We do not need to + * backtrack and look for shorter matching prefixes because + * they cannot exist. The boundary always begins with '\r' + * and never contains another '\r'. + */ + + if (matched > 0 && c != boundary[matched]) { + for (i = 0; i < matched; i++) { + if (wantfile == 0) { + value = savechar(value, k++, boundary[i]); + } + else if (out != 0) { + fputc(boundary[i], out); + } + } + matched = 0; + } + + /* check for full or partial boundary match */ + + if (c == boundary[matched]) { + if (boundary[++matched] == 0) { + break; /* full match */ + } + continue; /* partial match */ + } + + /* no match, so copy byte to output */ + + if (wantfile == 0) { + value = savechar(value, k++, c); + } + else if (out != 0) { + fputc(c, out); + } + } + if (wantfile == 0) { + return savechar(value, k, 0); + } + return 0; +} + +/* + * read_multipart() reads form data encoded as "multipart/form-data" + * and adds form field names and values to variable list "v" and + * returns "v". + * + * The input is split into parts delimited by a boundary string. + * Each part starts with this header: + * + * Content-Disposition: form-data; name="fieldname"; filename="filename" + * + * where "fieldname" is the name of the form field. The "filename=" + * attribute is only present when this part contains file data for + * a file upload. A "Content-type:" header line may also be present + * with a file upload. After the header lines comes a blank line + * followed by the field data (or file data) terminated by "\r\n--" + * followed by the boundary string. If the boundary string is + * followed by "--\r\n" then this is the last part. + */ + +static CGI_varlist * +read_multipart(CGI_varlist *v, const char *template) { + const char *ctype, *name, *filename; + char *p, *token[2], *boundary, *localname = 0; + strbuf *bbuf = 0, *nbuf = 0, *fbuf = 0; + strbuf *line = 0, *value = 0; + int len, fd; + FILE *out; + + /* + * get the boundary string from the environment and prepend + * "\r\n--" to it. + */ + + if ((ctype = getenv("CONTENT_TYPE")) == 0 || + strncasecmp(ctype, "multipart/form-data;", len = 20) != 0) + { + return v; + } + bbuf = savestr(bbuf, ctype + len); + if (scanattr(bbuf->str, token) == 0 || + strcasecmp(token[0], "boundary") != 0) + { + goto cleanup; + } + boundary = token[1] - 4; + memcpy(boundary, "\r\n--", 4); + + /* + * first line is the boundary string, but with "\r\n" + * at the end rather than the start. + */ + + len = (int)strlen(boundary) - 2; + if ((line = readline(line, stdin)) == 0 || + strncmp(line->str, boundary + 2, len) != 0 || + line->str[len] != '\r' || line->str[len + 1] != '\n') + { + goto cleanup; + } + + /* read all the parts */ + + for (;;) { + + /* Scan header lines for the Content-Disposition: header */ + + name = filename = 0; + while ((line = readline(line, stdin)) != 0 && + (p = scanheader(line->str, token)) != 0) + { + if (strcasecmp(token[0], "Content-Disposition") != 0 || + strcasecmp(token[1], "form-data") != 0) + { + continue; + } + + /* Content-Disposition: has field name and file name */ + + while ((p = scanattr(p, token)) != 0) { + if (name == 0 && + strcasecmp(token[0], "name") == 0) + { + nbuf = savestr(nbuf, token[1]); + name = nbuf->str; + } + else if (filename == 0 && + strcasecmp(token[0], "filename") == 0) + { + fbuf = savestr(fbuf, token[1]); + filename = fbuf->str; + } + } + } + + /* after the headers is a blank line (just "\r\n") */ + + if (line == 0 || name == 0 || + line->str[0] != '\r' || line->str[1] != '\n') + { + break; + } + + /* + * If filename is non null (file upload) then we read file data, + * otherwise we read field data. In either case the data + * consists of everything up to, but not including the boundary. + */ + + if (filename != 0) { + + /* copy file data to newly created file */ + + out = 0; + if (template != 0 && *filename != 0) { + if (localname == 0) { + localname = (char *) mymalloc((int)strlen(template) + 1); + } + strcpy(localname, template); + if ((fd = mkstemp(localname)) >= 0) { + out = fdopen(fd, "wb"); + } + } + copyvalue(boundary, stdin, 1, 0, out); + if (out != 0) { + fclose(out); + v = CGI_add_var(v, name, localname); + v = CGI_add_var(v, name, filename); + } + } + else { + value = copyvalue(boundary, stdin, 0, value, 0); + v = CGI_add_var(v, name, value->str); + } + + /* + * read the rest of the line after the boundary. If we + * get "--\r\n" then this is the last field. Otherwise + * we presumably get "\r\n" and we continue. + */ + + if ((line = readline(line, stdin)) != 0 && + line->str[0] == '-' && line->str[1] == '-' && + line->str[2] == '\r' && line->str[3] == '\n') + { + break; + } + } + +cleanup: + if (bbuf != 0) { + free(bbuf); + } + if (nbuf != 0) { + free(nbuf); + } + if (fbuf != 0) { + free(fbuf); + } + if (line != 0) { + free(line); + } + if (value != 0) { + free(value); + } + if (localname != 0) { + free(localname); + } + return v; +} + +/* + * EXPORTED FUNCTIONS + * + * CGI_decode_url() returns a new string which is a copy of the input + * string with '+' converted to ' ' and %xx converted to the character + * whose hex numeric value is xx. + */ + +char * +CGI_decode_url(const char *p) { + char *out; + int i, k, L, R; + + if (p == 0) { + return 0; + } + out = (char *) mymalloc((int)strlen(p) + 1); + for (i = k = 0; p[i] != 0; i++) { + switch(p[i]) { + + case '+': + out[k++] = ' '; + continue; + + case '%': + if ((L = hex(p[i + 1])) >= 0 && + (R = hex(p[i + 2])) >= 0) + { + out[k++] = (L << 4) + R; + i += 2; + continue; + } + break; + } + out[k++] = p[i]; + } + out[k] = 0; + return out; +} + +/* + * CGI_encode_url() URL encodes a string and returns the result + * in memory from malloc(). + */ + +char * +CGI_encode_url(const char *p, const char *keep) { + char *out; + + if (p == 0) { + return 0; + } + out = mymalloc(urlcount(p, keep) + 1); + urlencode(p, out, keep); + return out; +} + +/* + * CGI_encode_query() takes a variable arg list of strings + * and encodes them into a URL query string of the form + * name1=value1&name2=value2 ... where each name and value + * is URL encoded. + */ + +char * +CGI_encode_query(const char *keep, ...) { + char *out, *p; + va_list ap; + const char *name, *value; + int k; + + /* calculate the size of the output string */ + + va_start(ap, keep); + k = 0; + while ((value = va_arg(ap, const char *)) != 0) { + k += urlcount(value, keep) + 1; + } + va_end(ap); + if (k == 0) { + return 0; + } + p = out = mymalloc(k); + + /* url encode each name=value pair */ + + va_start(ap, keep); + while ((name = va_arg(ap, const char *)) != 0 && + (value = va_arg(ap, const char *)) != 0) + { + if (p != out) { + *p++ = '&'; + } + p = urlencode(name, p, keep); + *p++ = '='; + p = urlencode(value, p, keep); + } + va_end(ap); + *p = 0; + return out; +} + +/* + * CGI_encode_varlist() encodes a CGI_varlist into a query + * string of the form name1=value1&name2=value2 ... where + * each name and value is URL encoded. + */ + +char * +CGI_encode_varlist(CGI_varlist *vlist, const char *keep) { + char *out, *p; + CGI_varlist *v; + CGI_val *value; + int k = 0; + + /* calculate size of the output string */ + + for (v = vlist; v != 0; v = v->next) { + for (value = v->value; value != 0; value = value->next) { + k += 2 + urlcount(v->varname, keep) + + urlcount(value->value, keep); + } + } + if (k == 0) { + return 0; + } + p = out = mymalloc(k); + + /* URL encode each name=value pair */ + + for (v = vlist; v != 0; v = v->next) { + for (value = v->value; value != 0; value = value->next) { + if (p != out) { + *p++ = '&'; + } + p = urlencode(v->varname, p, keep); + *p++ = '='; + p = urlencode(value->value, p, keep); + } + } + *p = 0; + return out; +} + +/* + * CGI_add_var() adds a new variable name and value to variable list + * "v" and returns the resulting list. If "v" is null or if the + * variable name is not on the list, then we create a new entry. + * We add the value to the appropriate list entry. + */ + +CGI_varlist * +CGI_add_var(CGI_varlist *v, const char *varname, const char *value) { + CGI_val *val; + CGI_varlist *v2; + + if (varname == 0 || value == 0) { + return v; + } + + /* create a new value */ + + val = (CGI_val *) mymalloc(sizeof(*val) + (int)strlen(value)); + strcpy((char *) val->value, value); + val->next = 0; + + /* + * find the list entry or else create a new one. Add the + * new value. We use "tail" pointers to keep the lists + * in the same order as the input. + */ + + if ((v2 = findvar(v, varname)) == 0) { + v2 = (CGI_varlist *) mymalloc((int)sizeof(*v2) + (int)strlen(varname)); + strcpy((char *) v2->varname, varname); + v2->value = val; + v2->numvalue = 1; + v2->next = v2->iter = v2->tail = 0; + v2->vector = 0; + if (v == 0) { + v = v2; + } + else { + v->tail->next = v2; + } + v->tail = v2; + } + else { + v2->valtail->next = val; + v2->numvalue++; + } + v2->valtail = val; + if (v2->vector != 0) { + free((void *)v2->vector); + v2->vector = 0; + } + v->iter = 0; + return v; +} + +/* + * CGI_decode_query() adds all the names and values in query string + * "query" to variable list "v" (which may be null) and returns the + * resulting variable list. The query string has the form + * + * name1=value1&name2=value2&name3=value3 + * + * We convert '+' to ' ' and convert %xx to the character whose + * hex numeric value is xx. + */ + +CGI_varlist * +CGI_decode_query(CGI_varlist *v, const char *query) { + char *buf; + const char *name, *value; + int i, k, L, R, done; + + if (query == 0) { + return v; + } + buf = (char *) mymalloc((int)strlen(query) + 1); + name = value = 0; + for (i = k = done = 0; done == 0; i++) { + switch (query[i]) { + + case '=': + if (name != 0) { + break; /* treat extraneous '=' as data */ + } + if (name == 0 && k > 0) { + name = buf; + buf[k++] = 0; + value = buf + k; + } + continue; + + case 0: + done = 1; /* fall through */ + + case '&': + buf[k] = 0; + if (name == 0 && k > 0) { + name = buf; + value = buf + k; + } + if (name != 0) { + v = CGI_add_var(v, name, value); + } + k = 0; + name = value = 0; + continue; + + case '+': + buf[k++] = ' '; + continue; + + case '%': + if ((L = hex(query[i + 1])) >= 0 && + (R = hex(query[i + 2])) >= 0) + { + buf[k++] = (L << 4) + R; + i += 2; + continue; + } + break; /* treat extraneous '%' as data */ + } + buf[k++] = query[i]; + } + free(buf); + return v; +} + +/* + * CGI_get_cookie() adds all the cookie names and values from the + * environment variable HTTP_COOKIE to variable list "v" (which + * may be null) and returns the resulting variable list. + */ + +CGI_varlist * +CGI_get_cookie(CGI_varlist *v) { + const char *env; + char *buf, *p, *cookie[2]; + + if ((env = getenv("HTTP_COOKIE")) == 0) { + return v; + } + buf = (char *) mymalloc((int)strlen(env) + 1); + p = strcpy(buf, env); + while ((p = scanattr(p, cookie)) != 0) { + v = CGI_add_var(v, cookie[0], cookie[1]); + } + free(buf); + return v; +} + +/* + * CGI_get_query() adds all the field names and values from the + * environment variable QUERY_STRING to variable list "v" (which + * may be null) and returns the resulting variable list. + */ + +CGI_varlist * +CGI_get_query(CGI_varlist *v) { + return CGI_decode_query(v, getenv("QUERY_STRING")); +} + +/* + * CGI_get_post() reads field names and values from stdin and adds + * them to variable list "v" (which may be null) and returns the + * resulting variable list. We accept input encoded as + * "application/x-www-form-urlencoded" or as "multipart/form-data". + * In the case of a file upload, we write to a new file created + * with mkstemp() and "template". If the template is null or if + * mkstemp() fails then we silently discard the uploaded file data. + * The local name of the file (created by mkstemp()) and the remote + * name (as specified by the user) can be obtained with + * CGI_lookup_all(v, fieldname). + */ + +CGI_varlist * +CGI_get_post(CGI_varlist *v, const char *template) { + const char *env; + char *buf; + int len; + + if ((env = getenv("CONTENT_TYPE")) != 0 && + strcasecmp(env, "application/x-www-form-urlencoded") == 0 && + (env = getenv("CONTENT_LENGTH")) != 0 && + (len = atoi(env)) > 0) + { + buf = (char *) mymalloc(len + 1); + if (fread(buf, 1, len, stdin) == len) { + buf[len] = 0; + v = CGI_decode_query(v, buf); + } + free(buf); + } + else { + v = read_multipart(v, template); + } + return v; +} + +/* + * CGI_get_all() returns a variable list that contains a combination of the + * following: cookie names and values from HTTP_COOKIE, field names and + * values from QUERY_STRING, and POSTed field names and values from stdin. + * File uploads are handled using "template" (see CGI_get_post()) + */ + +CGI_varlist * +CGI_get_all(const char *template) { + CGI_varlist *v = 0; + + v = CGI_get_cookie(v); + v = CGI_get_query(v); + v = CGI_get_post(v, template); + return v; +} + +/* CGI_free_varlist() frees all memory used by variable list "v" */ + +void +CGI_free_varlist(CGI_varlist *v) { + CGI_val *val, *valnext; + + if (v != 0) { + if (v->vector != 0) { + free((void *)v->vector); + } + for (val = v->value; val != 0; val = valnext) { + valnext = val->next; + free(val); + } + CGI_free_varlist(v->next); + free(v); + } +} + + +/* + * CGI_lookup() searches variable list "v" for an entry named + * "varname" and returns null if not found. Otherwise we return the + * first value associated with "varname", which is a null terminated + * string. If varname is null then we return the first value of the + * "current entry", which was set using the iterating functions + * CGI_first_name() and CGI_next_name(). + */ + +const char * +CGI_lookup(CGI_varlist *v, const char *varname) { + return (v = findvar(v, varname)) == 0 ? 0 : v->value->value; +} + +/* + * CGI_lookup_all() searches variable list "v" for an entry named + * "varname" and returns null if not found. Otherwise we return + * a pointer to a null terminated array of string pointers (see + * CGI_value) where each string is a value of the variable. If + * varname is null then we return the values of the "current entry", + * which was set using the iterating functions CGI_first_name() and + * CGI_next_name(). + */ + +CGI_value * +CGI_lookup_all(CGI_varlist *v, const char *varname) { + CGI_val *val; + int i; + + if ((v = findvar(v, varname)) == 0) { + return 0; + } + if (v->vector == 0) { + v->vector = (CGI_value *) + mymalloc(sizeof(CGI_value) * (v->numvalue + 1)); + i = 0; + + /* to initialize v->vector we must cast away const */ + + for (val = v->value; val != 0 && i < v->numvalue; + val = val->next) + { + ((const char **)v->vector)[i++] = val->value; + } + ((const char **)v->vector)[i] = 0; + } + return v->vector; +} + +/* + * CGI_first_name() returns the name of the first entry in + * variable list "v", or null if "v" is null. + */ + +const char * +CGI_first_name(CGI_varlist *v) { + return v == 0 ? 0 : (v->iter = v)->varname; +} + +/* + * CGI_next_name() returns the name of the next entry in variable list + * "v" after the most recent call to CGI_first_name() or CGI_next_name(). + * We return null if there are no more entries + */ + +const char * +CGI_next_name(CGI_varlist *v) { + return v == 0 || v->iter == 0 || (v->iter = v->iter->next) == 0 ? + 0 : v->iter->varname; +} + +/* + * CGI_encode_entity() converts null terminated string "in" to + * HTML entity encoding where > become > and < become < + * and & becomes & etc., and returns the result. Allocates + * memory for the result with malloc(). + */ + +char * +CGI_encode_entity(const char *in) { + char *out, *p; + int i, k; + + if (in == 0) { + return 0; + } + for (i = k = 0; in[i] != 0; i++) { + switch(in[i]) { + + case '<': + case '>': + k += 4; + break; + case '&': + case '\'': + case '\r': + case '\n': + k += 5; + break; + case '"': + k += 6; + break; + default: + k++; + break; + } + } + out = p = mymalloc(k + 1); + + for (i = 0; in[i] != 0; i++) { + switch(in[i]) { + + case '<': + *p++ = '&'; + *p++ = 'l'; + *p++ = 't'; + *p++ = ';'; + break; + case '>': + *p++ = '&'; + *p++ = 'g'; + *p++ = 't'; + *p++ = ';'; + break; + case '&': + *p++ = '&'; + *p++ = 'a'; + *p++ = 'm'; + *p++ = 'p'; + *p++ = ';'; + break; + case '\'': + *p++ = '&'; + *p++ = '#'; + *p++ = '3'; + *p++ = '9'; + *p++ = ';'; + break; + case '\r': + *p++ = '&'; + *p++ = '#'; + *p++ = '1'; + *p++ = '3'; + *p++ = ';'; + break; + case '\n': + *p++ = '&'; + *p++ = '#'; + *p++ = '1'; + *p++ = '0'; + *p++ = ';'; + break; + case '"': + *p++ = '&'; + *p++ = 'q'; + *p++ = 'u'; + *p++ = 'o'; + *p++ = 't'; + *p++ = ';'; + break; + default: + *p++ = in[i]; + break; + } + } + *p = 0; + return out; +} + +/* base64 conversion */ + +static const char b64encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz0123456789+/"; + +#define BAD 100 + +static const unsigned char b64decode[] = { + BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, + BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, + BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, + BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, + BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, + BAD, BAD, BAD, 62, BAD, BAD, BAD, 63, + 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, BAD, BAD, BAD, BAD, BAD, BAD, + + BAD, 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, BAD, BAD, BAD, BAD, BAD, + BAD, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, BAD, BAD, BAD, BAD, BAD, + + BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, + BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, + BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, + BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, + BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, + BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, + BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, + BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, + + BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, + BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, + BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, + BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, + BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, + BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, + BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, + BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD +}; + +/* + * CGI_decode_base64() decodes null terminated base64 encoded string p + * and returns the result. We store the length of the result in + * *len and we write a null byte after the last byte of the result. + * We allocate memory for the result with malloc(); + */ + +void * +CGI_decode_base64(const char *p, int *len) { + const unsigned char *in = (const unsigned char *) p; + unsigned char *out; + int save = 0, nbits = 0, sixbits; + int i, k; + + if (p == 0) { + return 0; + } + out = mymalloc(3 + 3 * (int)strlen(p) / 4); + + /* every four base64 input characters becomes three output bytes */ + + for (i = k = 0; in[i] != 0; i++) { + if ((sixbits = b64decode[in[i]]) == BAD) { + continue; + } + save |= sixbits << (18 - nbits); /* 4 x 6 bits in */ + if ((nbits += 6) == 24) { + out[k++] = save >> 16; /* 3 x 8 bits out */ + out[k++] = save >> 8; + out[k++] = save; + nbits = 0; + save = 0; + } + } + + /* convert leftover bits */ + + for (i = 16; i >= 0 && nbits >= 8; i -= 8) { + out[k++] = save >> i; + nbits -= 8; + } + out[k] = 0; + if (len != 0) { + *len = k; + } + return out; +} + +/* + * CGI_encode_base64() base64 encodes bytes in array p of length len + * and returns the result, which is a null terminated base64 encoded + * string. We allocate memory for the result with malloc(). + */ + +char * +CGI_encode_base64(const void *p, int len) { + const unsigned char *in = p; + char *out; + int save = 0, nbits = 0; + int i, k = 0; + + if (in == 0 || len <= 0) { + return 0; + } + out = mymalloc(4 + 4 * len / 3); + + /* every three input bytes becomes 4 base64 output characters */ + + for (i = 0; i < len; i++) { + save |= in[i] << (16 - nbits); /* 3 x 8 bits in */ + if ((nbits += 8) == 24) { + out[k++] = b64encode[(save >> 18) & 077]; /* 4 x 6 bits out */ + out[k++] = b64encode[(save >> 12) & 077]; + out[k++] = b64encode[(save >> 6) & 077]; + out[k++] = b64encode[ save & 077]; + nbits = 0; + save = 0; + } + } + + /* convert leftover bits */ + + if (nbits > 0) { + for (i = 18; i >= 0; i -= 6) { + if (nbits > 0) { + out[k++] = b64encode[(save >> i) & 077]; + nbits -= 6; + } + else { + out[k++] = '='; + } + } + } + out[k] = 0; + return out; +} + +/* hex conversion */ + +/* + * CGI_decode_hex() decodes null terminated hex encoded string p + * and returns the result. We store the length of the result in + * *len and we write a null byte after the last byte of the result. + * We allocate memory for the result with malloc(); + */ + +void * +CGI_decode_hex(const char *p, int *len) { + unsigned char *out; + int i, k, n, L, R; + + if (p == 0 || ((n = (int)strlen(p)) & 1)) { + return 0; /* length of input must be even */ + } + out = mymalloc(n / 2 + 1); + for (i = k = 0; i < n; i += 2) { + if ((L = hex(p[i])) >= 0 && (R = hex(p[i + 1])) >= 0) { + out[k++] = (L << 4) + R; + } + else { + free(out); + return 0; + } + } + out[k] = 0; + if (len != 0) { + *len = k; + } + return out; +} + +/* + * CGI_encode_hex() hex encodes bytes in array p of length len + * and returns the result, which is a null terminated hex encoded + * string. We allocate memory for the result with malloc(). + */ + +char * +CGI_encode_hex(const void *p, int len) { + const unsigned char *in = p; + int i, k; + char *out; + const char hexdigit[] = "0123456789ABCDEF"; + + if (in == 0 || len <= 0) { + return 0; + } + out = mymalloc(len * 2 + 1); + for (i = k = 0; i < len; i++) { + out[k++] = hexdigit[in[i] >> 4]; + out[k++] = hexdigit[in[i] & 0xf]; + } + out[k] = 0; + return out; +} diff --git a/crypto777/crypto777.sources b/crypto777/crypto777.sources new file mode 100644 index 000000000..0b8882e8a --- /dev/null +++ b/crypto777/crypto777.sources @@ -0,0 +1,11 @@ +JPEG_SRCS := ../crypto777/jpeg/jaricom.c ../crypto777/jpeg/jcapimin.c ../crypto777/jpeg/jcapistd.c ../crypto777/jpeg/jcarith.c ../crypto777/jpeg/jccoefct.c ../crypto777/jpeg/jccolor.c \ + ../crypto777/jpeg/jcdctmgr.c ../crypto777/jpeg/jchuff.c ../crypto777/jpeg/jcinit.c ../crypto777/jpeg/jcmainct.c ../crypto777/jpeg/jcmarker.c ../crypto777/jpeg/jcmaster.c \ + ../crypto777/jpeg/jcomapi.c ../crypto777/jpeg/jcparam.c ../crypto777/jpeg/jcprepct.c ../crypto777/jpeg/jcsample.c ../crypto777/jpeg/jctrans.c ../crypto777/jpeg/jdapimin.c \ + ../crypto777/jpeg/jdapistd.c ../crypto777/jpeg/jdarith.c ../crypto777/jpeg/jdatadst.c ../crypto777/jpeg/jdatasrc.c ../crypto777/jpeg/jdcoefct.c ../crypto777/jpeg/jdcolor.c \ + ../crypto777/jpeg/jddctmgr.c ../crypto777/jpeg/jdhuff.c ../crypto777/jpeg/jdinput.c ../crypto777/jpeg/jdmainct.c ../crypto777/jpeg/jdmarker.c ../crypto777/jpeg/jdmaster.c \ + ../crypto777/jpeg/jdmerge.c ../crypto777/jpeg/jdpostct.c ../crypto777/jpeg/jdsample.c ../crypto777/jpeg/jdtrans.c ../crypto777/jpeg/jerror.c ../crypto777/jpeg/jfdctflt.c \ + ../crypto777/jpeg/jfdctfst.c ../crypto777/jpeg/jfdctint.c ../crypto777/jpeg/jidctflt.c ../crypto777/jpeg/jidctfst.c ../crypto777/jpeg/jidctint.c ../crypto777/jpeg/jquant1.c \ + ../crypto777/jpeg/jquant2.c ../crypto777/jpeg/jutils.c ../crypto777/jpeg/jmemmgr.c ../crypto777/jpeg/jmemnobs.c + +CRYPTO777_SRCS := ../crypto777/ccgi.c ../crypto777/cJSON.c ../crypto777/iguana_utils.c ../crypto777/OS_nonportable.c ../crypto777/curve25519-donna.c ../crypto777/inet.c ../crypto777/OS_portable.c ../crypto777/curve25519.c ../crypto777/libgfshare.c ../crypto777/OS_time.c ../crypto777/hmac_sha512.c ../crypto777/ramcoder.c ../crypto777/SaM.c ../crypto777/iguana_OS.c ../crypto777/iguana_serdes.c $(JPEG_SRCS) + diff --git a/crypto777/inet.c b/crypto777/inet.c index ff0b486a6..0ef873257 100755 --- a/crypto777/inet.c +++ b/crypto777/inet.c @@ -19,6 +19,7 @@ #ifndef crypto777_inet_h #define crypto777_inet_h #include "OS_portable.h" +#include #ifdef _WIN32 #include diff --git a/crypto777/m_win32 b/crypto777/m_win32 index 161160b46..6b5486e36 100755 --- a/crypto777/m_win32 +++ b/crypto777/m_win32 @@ -1,2 +1 @@ -echo do equivalent of: gcc -c -O2 *.c jpeg/*.c jpeg/win/*.c -echo do equivalent of: rm ../agents/libcrypto777.a; ar rcu ../agents/libcrypto777.a *.o +make -f mingw32 diff --git a/crypto777/mingw b/crypto777/mingw new file mode 100755 index 000000000..ec2e9bfd1 --- /dev/null +++ b/crypto777/mingw @@ -0,0 +1,6 @@ +include crypto777.sources + +all: + $(TOOL_DIR)/$(MINGW)-gcc -D __MINGW -c $(CRYPTO777_SRCS) + $(TOOL_DIR)/$(MINGW)-ar rcu *.o ../agents/libcrypto777.a + diff --git a/crypto777/mingw32 b/crypto777/mingw32 new file mode 100755 index 000000000..311cdb763 --- /dev/null +++ b/crypto777/mingw32 @@ -0,0 +1,2 @@ +include ../mingw.path +include mingw diff --git a/crypto777/mingw64 b/crypto777/mingw64 new file mode 100755 index 000000000..c2d0741ec --- /dev/null +++ b/crypto777/mingw64 @@ -0,0 +1,3 @@ +include ../mingw.path +include mingw + diff --git a/deprecated/obsolete.h b/deprecated/obsolete.h index 7e1d83b73..0fe41f05b 100644 --- a/deprecated/obsolete.h +++ b/deprecated/obsolete.h @@ -10184,5 +10184,840 @@ void iguana_dedicatedrecv(void *arg) } else retjsonstr = clonestr("{\"error\":\"cant parse generic JSON\"}"); return(retjsonstr); }*/ - + + char *iguana_remoteparser(struct iguana_agent *agent,struct iguana_info *coin,char *method,cJSON *json) + { + int32_t i,n,remains,numsent; char *jsonstr = 0,*retstr = 0; uint8_t hdr[128]; + if ( agent->sock < 0 ) + agent->sock = iguana_socket(0,agent->hostname,agent->port); + if ( agent->sock >= 0 ) + { + i = 0; + jsonstr = jprint(json,0); + n = (int32_t)strlen(jsonstr) + 1; + remains = n; + //printf("RETBUF.(%s)\n",retbuf); + while ( remains > 0 ) + { + if ( (numsent= (int32_t)send(agent->sock,&jsonstr[i],remains,MSG_NOSIGNAL)) < 0 ) + { + if ( errno != EAGAIN && errno != EWOULDBLOCK ) + { + printf("%s: %s numsent.%d vs remains.%d of %d errno.%d (%s) usock.%d\n",jsonstr,agent->name,numsent,remains,n,errno,strerror(errno),agent->sock); + break; + } + } + else if ( remains > 0 ) + { + remains -= numsent; + i += numsent; + if ( remains > 0 ) + printf("iguana sent.%d remains.%d of len.%d\n",numsent,remains,n); + } + } + if ( (n= (int32_t)recv(agent->sock,hdr,sizeof(hdr),0)) >= 0 ) + { + remains = (hdr[0] + ((int32_t)hdr[1] << 8) + ((int32_t)hdr[2] << 16)); + retstr = mycalloc('p',1,remains + 1); + i = 0; + while ( remains > 0 ) + { + if ( (n= (int32_t)recv(agent->sock,&retstr[i],remains,0)) < 0 ) + { + if ( errno == EAGAIN ) + { + printf("EAGAIN for len %d, remains.%d\n",n,remains); + usleep(10000); + } + break; + } + else + { + if ( n > 0 ) + { + remains -= n; + i += n; + } else usleep(10000); + } + } + } + free(jsonstr); + } + if ( retstr == 0 ) + retstr = clonestr("{\"error\":\"null return\"}"); + return(retstr); + } + + struct iguana_agent *Agents[16]; + + cJSON *iguana_agentinfojson(struct iguana_agent *agent) + { + cJSON *json= cJSON_CreateObject(); + jaddstr(json,"name",agent->name); + jadd(json,"methods",agent->methods); + if ( agent->port != 0 ) + jaddnum(json,"port",agent->port); + else jaddstr(json,"type","builtin"); + return(json); + } + + char *iguana_addagent(char *name,char *(*parsefunc)(struct iguana_agent *agent,struct iguana_info *coin,char *method,cJSON *json),char *hostname,cJSON *methods,uint16_t port,char *pubkeystr,char *privkeystr) + { + int32_t i; struct iguana_agent *agent; char retbuf[8192]; + for (i=0; iname,name) == 0 ) + { + if ( pubkeystr != 0 && privkeystr != 0 && strlen(pubkeystr) == 64 && strlen(privkeystr) == 64 ) + { + decode_hex(agent->pubkey.bytes,sizeof(bits256),pubkeystr); + decode_hex(agent->privkey.bytes,sizeof(bits256),privkeystr); + } + if ( port != 0 && agent->port == 0 ) + { + if ( agent->sock >= 0 ) + close(agent->sock); + agent->port = port; + strcpy(agent->hostname,hostname); + agent->sock = iguana_socket(0,agent->hostname,port); + printf("set (%s) port.%d for %s -> sock.%d\n",hostname,port,agent->name,agent->sock); + } + if ( agent->port > 0 && agent->sock < 0 && agent->hostname[0] != 0 && (agent->sock= iguana_socket(0,agent->hostname,agent->port)) < 0 ) + return(clonestr("{\"result\":\"existing agent couldnt connect to remote agent\"}")); + else return(clonestr("{\"result\":\"agent already there\"}")); + } + } + for (i=0; iname,name,sizeof(agent->name)-1); + strncpy(agent->hostname,hostname,sizeof(agent->hostname)-1); + agent->methods = methods, agent->nummethods = cJSON_GetArraySize(methods); + agent->sock = -1; + agent->port = port; + agent->parsefunc = (void *)parsefunc; + if ( pubkeystr != 0 && privkeystr != 0 && strlen(pubkeystr) == 64 && strlen(privkeystr) == 64 ) + { + decode_hex(agent->pubkey.bytes,sizeof(bits256),pubkeystr); + decode_hex(agent->privkey.bytes,sizeof(bits256),privkeystr); + } + if ( port > 0 ) + { + if ( (agent->sock= iguana_socket(0,hostname,port)) < 0 ) + return(clonestr("{\"result\":\"agent added, but couldnt connect to remote agent\"}")); + } + sprintf(retbuf,"{\"result\":\"agent added\",\"name\"\"%s\",\"methods\":%s,\"hostname\":\"%s\",\"port\":%u,\"sock\":%d}",agent->name,jprint(agent->methods,0),agent->hostname,agent->port,agent->sock); + return(clonestr(retbuf)); + } + } + return(clonestr("{\"error\":\"no more agent slots available\"}")); + } + else if ( strcmp(method,"addagent") == 0 ) + { + char *hostname = "127.0.0.1",*name; uint16_t port; + if ( (name= jstr(json,"name")) != 0 && (methods= jarray(&n,json,"methods")) != 0 ) + { + if ( (port= juint(json,"port")) != 0 ) + { + if ( (hostname= jstr(json,"host")) == 0 ) + { + if ( (hostname= jstr(json,"ipaddr")) == 0 ) + hostname = "127.0.0.1"; + } + if ( hostname == 0 ) + return(clonestr("{\"error\":\"no host specified for remote agent\"}")); + } + else if ( strcmp(name,"pangea") != 0 && strcmp(name,"InstantDEX") != 0 && strcmp(name,"jumblr") != 0 ) + return(clonestr("{\"error\":\"no port specified for remote agent\"}")); + return(iguana_addagent(name,iguana_remoteparser,hostname,methods,port,jstr(json,"pubkey"),jstr(json,"privkey"))); + } else return(clonestr("{\"error\":\"cant addagent without name and methods\"}")); + } + if ( (retstr= iguana_addagent("ramchain",ramchain_parser,"127.0.0.1",cJSON_Parse("[\"block\", \"tx\", \"txs\", \"rawtx\", \"balance\", \"totalreceived\", \"totalsent\", \"utxo\", \"status\"]"),0,0,0)) != 0 ) + printf("%s\n",retstr), free(retstr); + + + /*void iguana_issuejsonstrM(void *arg) + { + cJSON *json; int32_t fd; char *retjsonstr,*jsonstr = arg; + retjsonstr = iguana_JSON(jsonstr); + if ( (json= cJSON_Parse(jsonstr)) != 0 ) + { + if ( (fd= juint(json,"retdest")) > 0 ) + { + send(fd,jsonstr,(int32_t)strlen(jsonstr)+1,MSG_NOSIGNAL); + } + free_json(json); + return; + } + printf("%s\n",retjsonstr); + free(retjsonstr);//,strlen(retjsonstr)+1); + free(jsonstr);//,strlen(jsonstr)+1); + }*/ + + int32_t iguana_rpctestvector(struct iguana_info *coin,char *checkstr,char *jsonstr,int32_t maxlen,int32_t testi) + { + int32_t len,checklen; + sprintf(jsonstr,"{\"rpc.%s testvector.%d\"}",coin->symbol,testi); + sprintf(checkstr,"{\"rpc.%s testvector.%d checkstr should have all info needed to verify the rpc request\"}",coin->symbol,testi); + len = (int32_t)strlen(jsonstr); + checklen = (int32_t)strlen(checkstr); + if ( len > maxlen || checklen > maxlen ) + printf("iguana_rpctestvector: i was bad and overflowed buffer len.%d checklen.%d\n",len,checklen), exit(-1); + if ( checklen > len ) + len = checklen; + return(len); + } + + int32_t iguana_rpctestcheck(struct iguana_info *coin,char *jsonstr,char *retjsonstr) + { + if ( (rand() % 100) == 0 ) // 1% failure rate + return(-1); + else return(0); + } + + int32_t iguana_rpctest(struct iguana_info *coin) + { + /* static int32_t testi,good,bad; + char *retjsonstr,jsonstr[4096],checkstr[sizeof(jsonstr)]; // should be big enough + //if ( (rand() % 1000) < 999 ) // if no test active, just return 0 + return(0); + if ( iguana_rpctestvector(coin,checkstr,jsonstr,sizeof(jsonstr),testi++) > 0 ) + { + retjsonstr = iguana_rpc(coin,jsonstr); + if ( iguana_rpctestcheck(coin,jsonstr,retjsonstr) < 0 ) + bad++, printf("rpctestcheck.%s error: (%s) -> (%s) | good.%d bad.%d %.2f%%\n",coin->symbol,jsonstr,retjsonstr,good,bad,100.*(double)good/(good+bad)); + else good++; + free(retjsonstr); + return(1); // indicates was active + }*/ + return(0); + } + + char *iguana_agentjson(char *name,struct iguana_info *coin,char *method,cJSON *json,char *remoteaddr) + { + cJSON *retjson = 0,*array,*methods,*obj; int32_t i,n,j; struct iguana_agent *agent; + if ( strcmp(name,"SuperNET") != 0 ) + { + for (i=0; iname,name) == 0 ) + { + if ( agent->parsefunc != 0 ) + { + for (j=0; jnummethods; j++) + { + if ( (obj= jitem(agent->methods,j)) != 0 ) + { + if ( strcmp(method,jstr(obj,0)) == 0 ) + return((*agent->parsefunc)(agent,method,json,remoteaddr)); + } + } + return(clonestr("{\"result\":\"agent doesnt have method\"}")); + } else return(clonestr("{\"result\":\"agent doesnt have parsefunc\"}")); + } + } + } + else if ( remoteaddr == 0 || strcmp(remoteaddr,"127.0.0.1") != 0 ) // public api + { + char *coinstr; int32_t j,k,l,r,rr; struct iguana_peer *addr; + array = 0; + if ( strcmp(method,"getpeers") == 0 ) + { + if ( (coinstr= jstr(json,"coin")) != 0 ) + { + if ( (array= iguana_peersjson(iguana_coinfind(coinstr),1)) == 0 ) + return(clonestr("{\"error\":\"coin not found\"}")); + } + else + { + n = 0; + array = cJSON_CreateArray(); + r = rand(); + for (i=0; ipeers.active[l]; + if ( addr->usock >= 0 && addr->supernet != 0 ) + { + jaddistr(array,addr->ipaddr); + if ( ++n >= 64 ) + break; + } + } + } + } + } + if ( array != 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"agent","SuperNET"); + jaddstr(retjson,"method","mypeers"); + jaddstr(retjson,"result","peers found"); + jadd(retjson,"peers",array); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"no peers found\"}")); + } + else if ( strcmp(method,"mypeers") == 0 ) + { + printf("mypeers from %s\n",remoteaddr!=0?remoteaddr:"local"); + } + } + else // local api + { + if ( strcmp(method,"list") == 0 ) + { + retjson = cJSON_CreateObject(); + array = cJSON_CreateArray(); + for (i=0; isymbol[0] != 0 ) + jaddistr(array,Coins[i]->symbol); + } + jadd(retjson,"coins",array); + array = cJSON_CreateArray(); + for (i=0; iname[0] != 0 ) + jaddi(array,iguana_agentinfojson(Agents[i])); + } + jadd(retjson,"agents",array); + return(jprint(retjson,1)); + } + else if ( strcmp(method,"peers") == 0 ) + { + retjson = cJSON_CreateObject(); + array = cJSON_CreateArray(); + for (i=0; isymbol[0] != 0 ) + jaddi(array,iguana_peersjson(Coins[i],0)); + } + jadd(retjson,"allpeers",array); + return(jprint(retjson,1)); + } + } + return(clonestr("{\"result\":\"stub processed generic json\"}")); + } + + char *iguana_jsonstr(struct iguana_info *coin,char *jsonstr,char *remoteaddr) + { + cJSON *json; char *retjsonstr,*methodstr,*agentstr; + //printf("iguana_jsonstr.(%s)\n",jsonstr); + if ( (json= cJSON_Parse(jsonstr)) != 0 ) + { + if ( (methodstr= jstr(json,"method")) != 0 ) + { + if ( (agentstr= jstr(json,"agent")) == 0 || strcmp(agentstr,"iguana") == 0 ) + retjsonstr = iguana_coinjson(coin,methodstr,json); + else retjsonstr = iguana_agentjson(agentstr,coin,methodstr,json,remoteaddr); + } else retjsonstr = clonestr("{\"error\":\"no method in JSON\"}"); + free_json(json); + } else retjsonstr = clonestr("{\"error\":\"cant parse JSON\"}"); + printf("iguana_jsonstr.(%s)\n",retjsonstr); + return(retjsonstr); + } + char *iguana_htmlget(char *space,int32_t max,int32_t *jsonflagp,char *path,char *remoteaddr,int32_t localaccess) + { + char *iguana_coinjson(struct iguana_info *coin,char *method,cJSON *json); + struct iguana_info *coin = 0; cJSON *json; bits256 hash2; int32_t height,i; + char buf[64],jsonstr[1024],coinstr[64],*retstr; + for (i=0; path[i]!=0; i++) + if ( path[i] == ' ' ) + break; + path[i] = 0; + if ( path[strlen(path)-1] == '/' ) + path[strlen(path)-1] = 0; + if ( strncmp(path,"/api",strlen("/api")) == 0 ) + { + *jsonflagp = 1; + path += strlen("/api"); + } else *jsonflagp = 0; + iguana_coinset(coinstr,path); + if ( coinstr[0] != 0 ) + coin = iguana_coinfind(coinstr); + else coin = 0; + if ( strncmp(path,"/bitmap",strlen("/bitmap")) == 0 ) + { + path += strlen("/bitmap"); + *jsonflagp = 2; + iguana_bitmap(space,max,path); + return(space); + } + //printf("GETCHECK.(%s)\n",path); + if ( strncmp(path,"/ramchain/",strlen("/ramchain/")) == 0 ) + { + path += strlen("/ramchain/"); + if ( strncmp(path,"block/",strlen("block/")) == 0 ) + { + path += strlen("block/"); + if ( strncmp(path,"height/",strlen("height/")) == 0 ) + { + height = atoi(path + strlen("height/")); + sprintf(Currentjsonstr,"{\"agent\":\"ramchain\",\"method\":\"block\",\"coin\":\"%s\",\"height\":%d,\"txids\":1}",coinstr,height); + return(iguana_ramchain_glue(coin,"block",Currentjsonstr)); + } + else if ( strncmp(path,"hash/",strlen("hash/")) == 0 ) + { + decode_hex(hash2.bytes,sizeof(hash2),path + strlen("hash/")); + char str[65]; printf("ramchain blockhash.%s\n",bits256_str(str,hash2)); + sprintf(Currentjsonstr,"{\"agent\":\"ramchain\",\"method\":\"block\",\"coin\":\"%s\",\"hash\":\"%s\",\"txids\":1}",coinstr,str); + return(iguana_ramchain_glue(coin,"block",Currentjsonstr)); + } + } + else if ( strncmp(path,"txid/",strlen("txid/")) == 0 ) + { + decode_hex(hash2.bytes,sizeof(hash2),path + strlen("txid/")); + char str[65]; bits256_str(str,hash2); + sprintf(Currentjsonstr,"{\"agent\":\"ramchain\",\"method\":\"tx\",\"coin\":\"%s\",\"txid\":\"%s\"}",coinstr,str); + return(iguana_ramchain_glue(coin,"tx",Currentjsonstr)); + } + else if ( strncmp(path,"explore/",strlen("explore/")) == 0 ) + { + path += strlen("explore/"); + if ( coin != 0 ) + { + sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"explore\",\"coin\":\"%s\",\"search\":\"%s\"}",coinstr,path); + } else sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"explore\",\"search\":\"%s\"}",path); + return(iguana_ramchain_glue(coin,"explore",Currentjsonstr)); + } + else if ( strncmp(path,"bundleinfo/",strlen("bundleinfo/")) == 0 ) + { + path += strlen("bundleinfo/"); + sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"bundleinfo\",\"coin\":\"%s\",\"height\":%d}",coinstr,atoi(path)); + + } + else + { + sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"%s\",\"coin\":\"%s\"}",path,coinstr); + return(iguana_ramchain_glue(coin,path,Currentjsonstr)); + } + } + else if ( strncmp(path,"/hash/",strlen("/hash/")) == 0 ) + { + path += strlen("/hash/"); + return(iguana_hashparse(path)); + } + else if ( strncmp(path,"/iguana/",strlen("/iguana/")) == 0 ) + { + strcpy(Currentjsonstr,path); + path += strlen("/iguana/"); + if ( strncmp(path,"setagent/",strlen("setagent/")) == 0 ) + { + path += strlen("setagent/"); + if ( strncmp(path,"ramchain",strlen("ramchain")) == 0 || strncmp(path,"iguana",strlen("iguana")) == 0 || strncmp(path,"InstantDEX",strlen("InstantDEX")) == 0 || strncmp(path,"pangea",strlen("pangea")) == 0 || strncmp(path,"PAX",strlen("PAX")) == 0 || strncmp(path,"ALL",strlen("ALL")) == 0 || strncmp(path,"jumblr",strlen("jumblr")) == 0 ) + { + if ( strncmp(Default_agent,path,strlen(path)) == 0 ) + { + strcpy(Default_agent,"ALL"); + return(clonestr("{\"result\":\"ALL agents selected\"}")); + } + strcpy(Default_agent,path); + if ( Default_agent[strlen(Default_agent)-1] == '/' ) + Default_agent[strlen(Default_agent)-1] = 0; + sprintf(buf,"{\"result\":\"agent selected\",\"name\":\"%s\"}",path); + return(clonestr(buf)); + } + return(clonestr("{\"error\":\"invalid agent specified\"}")); + } + else + { + if ( strncmp(path,"peers/",strlen("peers/")) == 0 ) + { + path += strlen("peers/"); + if ( coin != 0 ) + { + sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"peers\",\"coin\":\"%s\"}",coinstr); + } else sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"peers\"}"); + json = cJSON_Parse(Currentjsonstr); + retstr = iguana_coinjson(coin,"peers",json); + free_json(json); + return(retstr); + } + else if ( coin != 0 ) + { + if ( strncmp(path,"addnode/",strlen("addnode/")) == 0 ) + { + path += strlen("addnode/"); + sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"addnode\",\"coin\":\"%s\",\"ipaddr\":\"%s\"}",coinstr,path); + json = cJSON_Parse(Currentjsonstr); + retstr = iguana_coinjson(coin,"addnode",json); + free_json(json); + return(retstr); + } + else if ( strncmp(path,"nodestatus/",strlen("nodestatus/")) == 0 ) + { + path += strlen("nodestatus/"); + sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"nodestatus\",\"coin\":\"%s\",\"ipaddr\":\"%s\"}",coinstr,path); + json = cJSON_Parse(Currentjsonstr); + retstr = iguana_coinjson(coin,"nodestatus",json); + free_json(json); + return(retstr); + } + else if ( strncmp(path,"addcoin",strlen("addcoin")) == 0 ) + { + path += strlen("addcoin"); + iguana_coinset(buf,path); + if ( (coin= iguana_coinadd(buf)) != 0 ) + { + sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"addcoin\",\"coin\":\"%s\"}",buf); + json = cJSON_Parse(Currentjsonstr); + retstr = iguana_coinjson(coin,"addcoin",json); + free_json(json); + } + else retstr = clonestr("{\"error\":\"cant create coin\"}"); + return(retstr); + } + else if ( strncmp(path,"startcoin",strlen("startcoin")) == 0 ) + { + path += strlen("startcoin"); + iguana_coinset(buf,path); + if ( (coin= iguana_coinfind(buf)) != 0 ) + { + sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"startcoin\",\"coin\":\"%s\"}",buf); + json = cJSON_Parse(Currentjsonstr); + retstr = iguana_coinjson(coin,"startcoin",json); + free_json(json); + } + else retstr = clonestr("{\"error\":\"cant create coin\"}"); + return(retstr); + } + else if ( strncmp(path,"pausecoin",strlen("pausecoin")) == 0 ) + { + path += strlen("pausecoin"); + iguana_coinset(buf,path); + if ( (coin= iguana_coinfind(buf)) != 0 ) + { + sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"pausecoin\",\"coin\":\"%s\"}",buf); + json = cJSON_Parse(Currentjsonstr); + retstr = iguana_coinjson(coin,"pausecoin",json); + free_json(json); + } + else retstr = clonestr("{\"error\":\"cant create coin\"}"); + return(retstr); + } + else if ( strncmp(path,"maxpeers/",strlen("maxpeers/")) == 0 ) + { + path += strlen("maxpeers/"); + sprintf(Currentjsonstr,"{\"agent\":\"iguana\",\"method\":\"maxpeers\",\"coin\":\"%s\",\"max\":%d}",coinstr,atoi(path)); + json = cJSON_Parse(Currentjsonstr); + retstr = iguana_coinjson(coin,"maxpeers",json); + free_json(json); + return(retstr); + } + return(clonestr("{\"result\":\"iguana method not found\"}")); + } + return(clonestr("{\"result\":\"iguana method needs coin\"}")); + } + } + else if ( strncmp(path,"/InstantDEX/",strlen("/InstantDEX/")) == 0 ) + { + double price,volume; char base[16],rel[16],exchange[16]; + path += strlen("/InstantDEX/"); + jsonstr[0] = 0; + if ( strncmp(path,"placebid/",strlen("placebid/")) == 0 ) + { + path += strlen("placebid/"); + if ( iguana_InstantDEX(jsonstr,path,"placebid") == 0 ) + return(clonestr("{\"error\":\"error with placebid parameters\"}")); + } + else if ( strncmp(path,"placeask/",strlen("placeask/")) == 0 ) + { + path += strlen("placeask/"); + if ( iguana_InstantDEX(jsonstr,path,"placeask") == 0 ) + return(clonestr("{\"error\":\"error with placeask parameters\"}")); + } + else if ( strncmp(path,"orderbook/",strlen("orderbook/")) == 0 ) + { + path += strlen("orderbook/"); + iguana_parsebidask(base,rel,exchange,&price,&volume,path); + if ( exchange[0] == 0 ) + strcpy(exchange,"active"); + sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"orderbook\",\"base\":\"%s\",\"rel\":\"%s\",\"exchange\":\"%s\",\"allfields\":1}",base,rel,exchange); + } + else if ( strncmp(path,"orderstatus/",strlen("orderstatus/")) == 0 ) + { + path += strlen("orderstatus/"); + sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"orderstatus\",\"orderid\":\"%s\"}",path); + } + else if ( strncmp(path,"cancelorder/",strlen("cancelorder/")) == 0 ) + { + path += strlen("cancelorder/"); + sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"cancelorder\",\"orderid\":\"%s\"}",path); + } + else if ( strncmp(path,"balance/",strlen("balance/")) == 0 ) + { + path += strlen("balance/"); + iguana_parsebidask(base,rel,exchange,&price,&volume,path); + if ( path[0] != ' ' && path[0] != '/' ) + sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"balance\",\"exchange\":\"%s\"}",path); + else sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"balance\"}"); + } + else if ( strncmp(path,"openorders",strlen("openorders")) == 0 ) + { + path += strlen("openorders"); + sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"openorders\"}"); + } + else if ( strncmp(path,"tradehistory",strlen("tradehistory")) == 0 ) + { + path += strlen("tradehistory"); + sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"tradehistory\"}"); + } + else if ( strncmp(path,"allorderbooks",strlen("allorderbooks")) == 0 ) + { + path += strlen("allorderbooks"); + sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"allorderbooks\"}"); + } + else if ( strncmp(path,"allexchanges",strlen("allexchanges")) == 0 ) + { + path += strlen("allexchanges"); + sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"allexchanges\"}"); + } + if ( jsonstr[0] != 0 ) + { + strcpy(Currentjsonstr,jsonstr); + return(clonestr(jsonstr)); + //return(InstantDEX(jsonstr,remoteaddr,localaccess)); + } + return(clonestr("{\"error\":\"unrecognized InstantDEX API call\"}")); + } + else if ( strncmp(path,"/pangea/",strlen("/pangea/")) == 0 ) + { + path += strlen("/pangea/"); + } + else if ( strncmp(path,"/jumblr/",strlen("/jumblr/")) == 0 ) + { + path += strlen("/jumblr/"); + } + else printf("no match to (%s)\n",path); + return(0); + } + + char *iguana_rpcparse(char *retbuf,int32_t bufsize,int32_t *postflagp,char *jsonstr) + { + cJSON *json = 0; int32_t i,n,localaccess,datalen,postflag = 0; + char *key,*reststr,*str,*retstr,remoteaddr[65],porturl[65],*data = 0,*value,*agent = "SuperNET"; + //printf("rpcparse.(%s)\n",jsonstr); + localaccess = 1; + if ( (str= strstr("Referer: ",jsonstr)) != 0 ) + { + for (i=0; str[i]!=' '&&str[i]!=0&&str[i]!='\n'&&str[i]!='\r'; i++) + remoteaddr[i] = str[i]; + remoteaddr[i] = 0; + } else strcpy(remoteaddr,"127.0.0.1"); // need to verify this + *postflagp = 0; + if ( strncmp("POST",jsonstr,4) == 0 ) + jsonstr += 6, *postflagp = postflag = 1; + else if ( strncmp("GET",jsonstr,3) == 0 ) + { + jsonstr += 4; + str = 0; + sprintf(porturl,"Referer: http://127.0.0.1:%u",IGUANA_RPCPORT); + if ( (str= iguana_htmlget(retbuf,bufsize,postflagp,jsonstr,remoteaddr,localaccess)) == 0 && (reststr= strstr(jsonstr,porturl)) != 0 ) + { + reststr += strlen(porturl); + str = iguana_htmlget(retbuf,bufsize,postflagp,reststr,remoteaddr,localaccess); + } + if ( str != 0 ) + { + if ( *postflagp == 0 ) + { + json = cJSON_CreateObject(); + jaddstr(json,"result",str); + if ( str != retbuf ) + free(str); + str = cJSON_Print(json); + free_json(json); + } + return(str); + } + jsonstr++; + } + else return(0); + n = (int32_t)strlen(jsonstr); + for (i=0; i 0 ) + { + jsonstr[i] = 0; + agent = jsonstr; + jsonstr += i; + } + jsonstr++; + json = cJSON_CreateObject(); + jaddstr(json,"agent",agent); + while ( 1 ) + { + n = (int32_t)strlen(jsonstr); + key = jsonstr; + value = 0; + for (i=0; i 0. && volume > 0. ) + { + sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"%s\",\"base\":\"%s\",\"rel\":\"%s\",\"exchange\":\"%s\",\"price\":\%0.8f,\"volume\":%0.8f}",method,base,rel,exchange,price,volume); + return(jsonstr); + } + else return(0); + } + return(0); + } + + void iguana_coinset(char *buf,char *path) + { + int32_t i; + if ( path[0] == '/' ) + path++; + for (i=0; i<8&&path[i]!=0&&path[i]!=' '&&path[i]!='/'; i++) + buf[i] = path[i]; + buf[i] = 0; + touppercase(buf); + } + + char *iguana_ramchain_glue(struct iguana_info *coin,char *method,char *jsonstr) + { + cJSON *json; char *retstr; + json = cJSON_Parse(jsonstr); + retstr = ramchain_parser(0,method,json); + free_json(json); + return(retstr); + } #endif diff --git a/iguana/Makefile b/iguana/Makefile index 53acc4163..518be082b 100644 --- a/iguana/Makefile +++ b/iguana/Makefile @@ -10,14 +10,11 @@ VALID_TOOLCHAINS := pnacl newlib glibc clang-newlib mac NACL_SDK_ROOT ?= $(abspath $(CURDIR)) TARGET = iguana -TARGETI = InstantDEX -TARGETP = pangea -TARGETX = PAX EXTRA= -D__PNACL include $(NACL_SDK_ROOT)/tools/common.mk - +include iguana.sources CHROME_ARGS += --allow-nacl-socket-api=127.0.0.1 DEPS = nacl_io @@ -26,14 +23,6 @@ LIBS = crypto777 curl ssl crypto z glibc-compat nacl_spawn ppapi nacl_io ppapi_ CFLAGS = -Wall -D__PNACL -fno-strict-aliasing $(EXTRA) LFLAGS = libs -SOURCES = main.c iguana777.c iguana_wallet.c iguana_init.c iguana_json.c iguana_recv.c iguana_chains.c iguana_ramchain.c iguana_bitmap.c iguana_rpc.c iguana_bundles.c iguana_pubkeys.c iguana_msg.c iguana_html.c iguana_blocks.c iguana_peers.c - -SOURCESI = InstantDEX/main.c InstantDEX/InstantDEX_main.c InstantDEX/prices777.c - -SOURCESP = pangea/main.c pangea/cards777.c pangea/pangea777.c pangea/pangeafunds.c pangea/poker.c pangea/tourney777.c - -SOURCESX = peggy/main.c peggy/peggy777.c peggy/peggytx.c peggy/txidind777.c peggy/opreturn777.c quotes777.c - # Build rules generated by macros from common.mk: $(foreach dep,$(DEPS),$(eval $(call DEPEND_RULE,$(dep)))) diff --git a/iguana/SuperNET.c b/iguana/SuperNET.c new file mode 100644 index 000000000..ded022edf --- /dev/null +++ b/iguana/SuperNET.c @@ -0,0 +1,507 @@ +/****************************************************************************** + * Copyright © 2014-2015 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#include "../crypto777/OS_portable.h" +#include "SuperNET.h" + +void SuperNET_rpcloop(void *args) +{ + struct supernet_info *myinfo = args; + int32_t recvlen,bindsock,postflag,sock,remains,jsonflag,numsent,len; socklen_t clilen; + char remoteaddr[64],jsonbuf[8192],*buf,*retstr,*space;//,*retbuf; ,n,i,m + struct sockaddr_in cli_addr; uint32_t ipbits,i; uint16_t port; + int32_t size = 1024 * 1024 * 2; + port = SUPERNET_PORT; + bindsock = iguana_socket(1,"127.0.0.1",port); + printf("SuperNET_rpcloop 127.0.0.1:%d bind sock.%d\n",port,bindsock); + space = calloc(1,size); + while ( bindsock >= 0 ) + { + clilen = sizeof(cli_addr); + //printf("ACCEPT (%s:%d) on sock.%d\n","127.0.0.1",port,bindsock); + sock = accept(bindsock,(struct sockaddr *)&cli_addr,&clilen); + if ( sock < 0 ) + { + //printf("iguana_rpcloop ERROR on accept usock.%d\n",sock); + continue; + } + memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); + expand_ipbits(remoteaddr,ipbits); + memset(jsonbuf,0,sizeof(jsonbuf)); + remains = (int32_t)(sizeof(jsonbuf) - 1); + buf = jsonbuf; + recvlen = 0; + retstr = 0; + while ( remains > 0 ) + { + if ( (len= (int32_t)recv(sock,buf,remains,0)) < 0 ) + { + if ( errno == EAGAIN ) + { + printf("EAGAIN for len %d, remains.%d\n",len,remains); + usleep(10000); + } + break; + } + else + { + if ( len > 0 ) + { + remains -= len; + recvlen += len; + buf = &buf[len]; + retstr = SuperNET_rpcparse(myinfo,space,size,&jsonflag,&postflag,jsonbuf,remoteaddr); + break; + } else usleep(10000); + } + } + if ( retstr != 0 ) + { + i = 0; + if ( postflag == 0 && jsonflag == 0 ) + retstr = SuperNET_htmlresponse(space,size,&remains,1,retstr,1); + else remains = (int32_t)strlen(retstr); + printf("RETBUF.(%s)\n",retstr); + while ( remains > 0 ) + { + if ( (numsent= (int32_t)send(sock,&retstr[i],remains,MSG_NOSIGNAL)) < 0 ) + { + if ( errno != EAGAIN && errno != EWOULDBLOCK ) + { + //printf("%s: %s numsent.%d vs remains.%d len.%d errno.%d (%s) usock.%d\n",retstr,ipaddr,numsent,remains,recvlen,errno,strerror(errno),sock); + break; + } + } + else if ( remains > 0 ) + { + remains -= numsent; + i += numsent; + if ( remains > 0 ) + printf("iguana sent.%d remains.%d of len.%d\n",numsent,remains,recvlen); + } + } + if ( retstr != space ) + free(retstr); + } + //printf("done response sock.%d\n",sock); + closesocket(sock); + } +} +/* +struct endpoint find_epbits(struct relay_info *list,uint32_t ipbits,uint16_t port,int32_t type) +{ + int32_t i; struct endpoint epbits; + memset(&epbits,0,sizeof(epbits)); + if ( list != 0 && list->num > 0 ) + { + if ( type >= 0 ) + type = nn_portoffset(type); + for (i=0; inum&&i<(int32_t)(sizeof(list->connections)/sizeof(*list->connections)); i++) + if ( list->connections[i].ipbits == ipbits && (port == 0 || port == list->connections[i].port) && (type < 0 || type == list->connections[i].nn) ) + return(list->connections[i]); + } + return(epbits); +} + +int32_t add_relay(struct relay_info *list,struct endpoint epbits) +{ + list->connections[list->num % (sizeof(list->connections)/sizeof(*list->connections))] = epbits, list->num++; + if ( list->num > (sizeof(list->connections)/sizeof(*list->connections)) ) + printf("add_relay warning num.%d > %ld\n",list->num,(long)(sizeof(list->connections)/sizeof(*list->connections))); + return(list->num); +} + +int32_t nn_add_lbservers(struct supernet_info *myinfo,uint16_t port,uint16_t globalport,uint16_t relaysport,int32_t priority,int32_t sock,char servers[][MAX_SERVERNAME],int32_t num) +{ + int32_t i; char endpoint[512],pubendpoint[512]; struct endpoint epbits; uint32_t ipbits; + if ( num > 0 && servers != 0 && nn_setsockopt(sock,NN_SOL_SOCKET,NN_SNDPRIO,&priority,sizeof(priority)) >= 0 ) + { + for (i=0; i= 0 ) + { + printf("+R%s ",endpoint); + add_relay(&myinfo->active,epbits); + } + if ( myinfo->subclient >= 0 ) + { + if ( myinfo->iamrelay != 0 ) + { + epbits = calc_epbits("tcp",ipbits,relaysport,NN_PUB); + expand_epbits(pubendpoint,epbits); + if ( nn_connect(myinfo->subclient,pubendpoint) >= 0 ) + printf("+P%s ",pubendpoint); + } + epbits = calc_epbits("tcp",ipbits,globalport,NN_PUB); + expand_epbits(pubendpoint,epbits); + if ( nn_connect(myinfo->subclient,pubendpoint) >= 0 ) + printf("+P%s ",pubendpoint); + } + } + } + printf("added priority.%d\n",priority); + priority++; + } else printf("error setting priority.%d (%s)\n",priority,nn_errstr()); + return(priority); +} + +int32_t _lb_socket(struct supernet_info *myinfo,uint16_t port,uint16_t globalport,uint16_t relaysport,int32_t maxmillis,char servers[][MAX_SERVERNAME],int32_t num,char backups[][MAX_SERVERNAME],int32_t numbacks,char failsafes[][MAX_SERVERNAME],int32_t numfailsafes) +{ + int32_t lbsock,timeout,retrymillis,priority = 1; + if ( (lbsock= nn_socket(AF_SP,NN_REQ)) >= 0 ) + { + retrymillis = (maxmillis / 30) + 1; + printf("!!!!!!!!!!!! lbsock.%d !!!!!!!!!!!\n",lbsock); + if ( nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_RECONNECT_IVL,&retrymillis,sizeof(retrymillis)) < 0 ) + printf("error setting NN_REQ NN_RECONNECT_IVL_MAX socket %s\n",nn_errstr()); + else if ( nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_RECONNECT_IVL_MAX,&maxmillis,sizeof(maxmillis)) < 0 ) + fprintf(stderr,"error setting NN_REQ NN_RECONNECT_IVL_MAX socket %s\n",nn_errstr()); + timeout = SUPERNET_NETWORKTIMEOUT; + if ( 1 && nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)) < 0 ) + printf("error setting NN_SOL_SOCKET NN_RCVTIMEO socket %s\n",nn_errstr()); + timeout = 100; + if ( 1 && nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)) < 0 ) + printf("error setting NN_SOL_SOCKET NN_SNDTIMEO socket %s\n",nn_errstr()); + if ( num > 0 ) + priority = nn_add_lbservers(myinfo,port,globalport,relaysport,priority,lbsock,servers,num); + if ( numbacks > 0 ) + priority = nn_add_lbservers(myinfo,port,globalport,relaysport,priority,lbsock,backups,numbacks); + if ( numfailsafes > 0 ) + priority = nn_add_lbservers(myinfo,port,globalport,relaysport,priority,lbsock,failsafes,numfailsafes); + } else printf("error getting req socket %s\n",nn_errstr()); + //printf("myinfo->lb.num %d\n",myinfo->lb.num); + return(lbsock); +} + +int32_t nn_lbsocket(struct supernet_info *myinfo,int32_t maxmillis,int32_t port,uint16_t globalport,uint16_t relaysport) +{ + char Cservers[32][MAX_SERVERNAME],Bservers[32][MAX_SERVERNAME],failsafes[4][MAX_SERVERNAME]; + int32_t n,m,lbsock,numfailsafes = 0; + printf("redo lbsocket()\n"), exit(-1); + //strcpy(failsafes[numfailsafes++],"5.9.56.103"); + //strcpy(failsafes[numfailsafes++],"5.9.102.210"); + // n = crackfoo_servers(Cservers,sizeof(Cservers)/sizeof(*Cservers),port); + // m = badass_servers(Bservers,sizeof(Bservers)/sizeof(*Bservers),port); + lbsock = _lb_socket(myinfo,port,globalport,relaysport,maxmillis,Bservers,m,Cservers,n*0,failsafes,numfailsafes); + return(lbsock); +} + +void add_standard_fields(char *request) +{ + cJSON *json; uint64_t tag; + if ( (json= cJSON_Parse(request)) != 0 ) + { + if ( get_API_nxt64bits(cJSON_GetObjectItem(json,"NXT")) == 0 ) + { + randombytes((void *)&tag,sizeof(tag)); + sprintf(request + strlen(request) - 1,",\"NXT\":\"%s\",\"tag\":\"%llu\"}",myinfo->NXTADDR,(long long)tag); + if ( myinfo->iamrelay != 0 && (myinfo->hostname[0] != 0 || myinfo->ipaddr[0] != 0) ) + sprintf(request + strlen(request) - 1,",\"iamrelay\":\"%s\"}",myinfo->hostname[0]!=0?myinfo->hostname:myinfo->myipaddr); + } + free_json(json); + } +} + +char *nn_loadbalanced(struct supernet_info *myinfo,uint8_t *data,int32_t len) +{ + char *msg,*jsonstr = 0; + int32_t sendlen,i,lbsock,recvlen = 0; + if ( (lbsock= myinfo->lbclient) < 0 ) + return(clonestr("{\"error\":\"invalid load balanced socket\"}")); + for (i=0; i<10; i++) + if ( (nn_socket_status(lbsock,1) & NN_POLLOUT) != 0 ) + break; + if ( myinfo->Debuglevel > 2 ) + printf("sock.%d NN_LBSEND.(%s)\n",lbsock,data); + //fprintf(stderr,"send to network\n"); + if ( (sendlen= nn_send(lbsock,data,len,0)) == len ) + { + for (i=0; i<10; i++) + if ( (nn_socket_status(lbsock,1) & NN_POLLIN) != 0 ) + break; + if ( (recvlen= nn_recv(lbsock,&msg,NN_MSG,0)) > 0 ) + { + if ( myinfo->Debuglevel > 2 ) + printf("LBRECV.(%s)\n",msg); + jsonstr = clonestr((char *)msg); + nn_freemsg(msg); + } + else + { + printf("nn_loadbalanced got recvlen.%d %s\n",recvlen,nn_errstr()); + jsonstr = clonestr("{\"error\":\"lb recv error, probably timeout\"}"); + } + } else printf("got sendlen.%d instead of %d %s\n",sendlen,len,nn_errstr()), jsonstr = clonestr("{\"error\":\"lb send error\"}"); + return(jsonstr); +} + +cJSON *relay_json(struct relay_info *list) +{ + cJSON *json,*array; char endpoint[512]; int32_t i; + if ( list == 0 || list->num == 0 ) + return(0); + array = cJSON_CreateArray(); + for (i=0; inum&&i<(int32_t)(sizeof(list->connections)/sizeof(*list->connections)); i++) + { + expand_epbits(endpoint,list->connections[i]); + jaddistr(array,endpoint); + } + json = cJSON_CreateObject(); + jadd(json,"endpoints",array); + //cJSON_AddItemToObject(json,"type",cJSON_CreateString(nn_typestr(list->mytype))); + //cJSON_AddItemToObject(json,"dest",cJSON_CreateString(nn_typestr(list->desttype))); + jaddnum(json,"total",list->num); + return(json); +} + +char *relays_jsonstr(struct supernet_info *myinfo,char *jsonstr,cJSON *argjson) +{ + cJSON *json; + if ( myinfo->iamrelay != 0 && myinfo->ipaddr[0] != 0 ) + { + json = cJSON_CreateObject(); + jaddstr(json,"relay",myinfo->ipaddr); + if ( myinfo->active.num > 0 ) + jadd(json,"relays",relay_json(&myinfo->active)); + return(jprint(json,1)); + } + else return(clonestr("{\"error\":\"get relay list from relay\"}")); +} + +int32_t init_SUPERNET_pullsock(struct supernet_info *myinfo,int32_t sendtimeout,int32_t recvtimeout) +{ + char bindaddr[64],*transportstr; int32_t iter; + myinfo->pullsock = -1; + if ( (myinfo->pullsock= nn_socket(AF_SP,NN_PULL)) < 0 ) + { + printf("error creating pullsock %s\n",nn_strerror(nn_errno())); + return(-1); + } + printf("got pullsock.%d\n",myinfo->pullsock); + if ( nn_settimeouts(myinfo->pullsock,sendtimeout,recvtimeout) < 0 ) + { + printf("error settime pullsock timeouts %s\n",nn_strerror(nn_errno())); + return(-1); + } + printf("PULLsock.%d\n",myinfo->pullsock); + for (iter=0; iter<2; iter++) + { + transportstr = (iter == 0) ? "ipc" : "inproc"; + sprintf(bindaddr,"%s://SuperNET.agents",transportstr); + if ( nn_bind(myinfo->pullsock,bindaddr) < 0 ) + { + printf("error binding pullsock to (%s) %s\n",bindaddr,nn_strerror(nn_errno())); + return(-1); + } + } + return(0); +} + +void busdata_init(struct supernet_info *myinfo,int32_t sendtimeout,int32_t recvtimeout,int32_t firstiter) +{ + char endpoint[512]; int32_t i; + myinfo->servicesock = myinfo->pubglobal = myinfo->pubrelays = myinfo->lbserver = -1; + endpoint[0] = 0; + if ( (myinfo->subclient= nn_createsocket(myinfo,endpoint,0,"NN_SUB",NN_SUB,0,sendtimeout,recvtimeout)) >= 0 ) + { + myinfo->pfd[myinfo->numservers++].fd = myinfo->subclient, printf("numservers.%d\n",myinfo->numservers); + nn_setsockopt(myinfo->subclient,NN_SUB,NN_SUB_SUBSCRIBE,"",0); + } else printf("error creating subclient\n"); + myinfo->lbclient = nn_lbsocket(myinfo,SUPERNET_NETWORKTIMEOUT,SUPERNET_PORT + LB_OFFSET,myinfo->port + PUBGLOBALS_OFFSET,myinfo->port + PUBRELAYS_OFFSET); + printf("LBclient.%d port.%d\n",myinfo->lbclient,SUPERNET_PORT + LB_OFFSET); + sprintf(endpoint,"%s://%s:%u",myinfo->transport,myinfo->ipaddr,myinfo->serviceport); + if ( (myinfo->servicesock= nn_createsocket(myinfo,endpoint,1,"NN_REP",NN_REP,myinfo->serviceport,sendtimeout,recvtimeout)) >= 0 ) + myinfo->pfd[myinfo->numservers++].fd = myinfo->servicesock, printf("numservers.%d\n",myinfo->numservers); + else printf("error creating servicesock\n"); + for (i=0; inumservers; i++) + myinfo->pfd[i].events = NN_POLLIN | NN_POLLOUT; + printf("myinfo->iamrelay %d, numservers.%d ipaddr.(%s://%s) port.%d serviceport.%d\n",myinfo->iamrelay,myinfo->numservers,myinfo->transport,myinfo->ipaddr,myinfo->port,myinfo->serviceport); +} + +void SuperNET_init(struct supernet_info *myinfo,char *jsonstr) +{ + char *str; + if ( jsonstr != 0 && (str= SuperNET_JSON(myinfo,jsonstr)) != 0 ) + free(str); + busdata_init(myinfo,10,1,0); + init_SUPERNET_pullsock(myinfo,10,10); +}*/ + +int32_t Supernet_lineparse(char *key,int32_t keymax,char *value,int32_t valuemax,char *src) +{ + int32_t a,b,c,n = 0; + key[0] = value[0] = 0; + while ( (c= src[n]) == ' ' || c == '\t' || c == '\n' || c == '\t' ) + n++; + while ( (c= src[n]) != ':' && c != 0 ) + { + *key++ = c; + if ( ++n >= keymax-1 ) + { + *key = 0; + printf("lineparse overflow key.(%s)\n",src); + return(-1); + } + } + *key = 0; + if ( src[n] != ':' ) + return(n); + n++; + while ( (c= src[n]) == ' ' || c == '\t' ) + n++; + while ( (c= src[n]) != 0 && c != '\r' && c != '\n' ) + { + if ( c == '%' && (a= src[n+1]) != 0 && (b= src[n+2]) != 0 ) + c = ((unhex(a) << 4) | unhex(b)), n += 2; + *value++ = c; + n++; + if ( n >= valuemax-1 ) + { + *value = 0; + printf("lineparse overflow.(%s)\n",src); + return(-1); + } + } + *value = 0; + if ( src[n] != 0 ) + { + n++; + while ( (c= src[n]) == '\r' || c == '\n' ) + n++; + } + return(n); +} + +cJSON *SuperNET_urlconv(char *value,int32_t bufsize,char *urlstr) +{ + int32_t i,n,totallen,datalen,len = 0; cJSON *json,*array; char key[8192],*data; + json = cJSON_CreateObject(); + array = cJSON_CreateArray(); + totallen = (int32_t)strlen(urlstr); + while ( 1 ) + { + for (i=len; urlstr[i]!=0; i++) + if ( urlstr[i] == '\r' || urlstr[i] == '\n' ) + break; + if ( i == len && (urlstr[len] == '\r' || urlstr[len] == '\n') ) + { + len++; + continue; + } + urlstr[i] = 0; + if ( (n= Supernet_lineparse(key,sizeof(key),value,bufsize,&urlstr[len])) > 0 ) + { + if ( value[0] != 0 ) + jaddstr(json,key,value); + else jaddistr(array,key); + len += (n + 1); + if ( strcmp(key,"Content-Length") == 0 && (datalen= atoi(value)) > 0 ) + { + data = &urlstr[totallen - datalen]; + data[-1] = 0; + //printf("post.(%s) (%c)\n",data,data[0]); + jaddstr(json,"POST",data); + } + } else break; + } + jadd(json,"lines",array); + return(json); +} + +char *SuperNET_rpcparse(struct supernet_info *myinfo,char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *postflagp,char *urlstr,char *remoteaddr) +{ + cJSON *tokens,*argjson,*json = 0; char urlmethod[16],*data,url[1024],*retstr,*token = 0; int32_t i,j,n; + //printf("rpcparse.(%s)\n",urlstr); + for (i=0; i 0 ) + { + jaddstr(argjson,"agent",jstri(tokens,0)); + if ( n > 1 ) + jaddstr(argjson,"method",jstri(tokens,1)); + for (i=2; i (%s) postflag.%d (%s)\n",urlstr,cJSON_Print(json),*postflagp,jprint(argjson,0)); + return(retstr); + } + return(clonestr("{\"error\":\"couldnt process packet\"}")); +} + diff --git a/iguana/SuperNET.h b/iguana/SuperNET.h new file mode 100644 index 000000000..4b5deadd6 --- /dev/null +++ b/iguana/SuperNET.h @@ -0,0 +1,91 @@ +/****************************************************************************** + * Copyright © 2014-2015 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#ifndef INCLUDED_SUPERNET_H +#define INCLUDED_SUPERNET_H + +#include "../crypto777/OS_portable.h" +#include "../includes/cJSON.h" +#include "../includes/nanomsg/nn.h" + +#define SUPERNET_PORT 7778 +#define SUPERNET_NETWORKTIMEOUT 10000 +#define SUPERNET_POLLTIMEOUT 1 +#define SUPERNET_APIUSLEEP (SUPERNET_POLLTIMEOUT * 10000) +#define SUPERNET_MAXAGENTS 64 +#define NXT_TOKEN_LEN 160 +#define nn_errstr() nn_strerror(nn_errno()) + +/*#define LB_OFFSET 1 +#define PUBGLOBALS_OFFSET 2 +#define PUBRELAYS_OFFSET 3 + + +#define MAX_SERVERNAME 128 +struct relayargs +{ + char name[16],endpoint[MAX_SERVERNAME]; + int32_t sock,type,bindflag,sendtimeout,recvtimeout; +}; +struct relay_info { int32_t sock,num,mytype,desttype; struct endpoint connections[1 << CONNECTION_NUMBITS]; };*/ + +#define CONNECTION_NUMBITS 10 +struct endpoint { queue_t nnrecvQ; int32_t nnsock,nnind; uint64_t ipbits:32,port:16,transport:2,nn:4,directind:CONNECTION_NUMBITS; }; + +struct direct_connection { char handler[16]; struct endpoint epbits; int32_t sock; }; + +struct supernet_msghdr { uint8_t type,serlen[3]; char command[16]; uint8_t hdrdata[44]; uint8_t data[]; }; + +struct supernet_agent +{ + struct queueitem DL; queue_t recvQ; uint64_t totalrecv,totalsent; + int32_t (*recvfunc)(void *myinfo,struct supernet_agent *,struct supernet_msghdr *msg,uint8_t *data,int32_t datalen); + cJSON *networks; + char name[9],ipaddr[64],reppoint[64],pubpoint[64]; int32_t reqsock,repsock,pubsock,subsock; + uint32_t ipbits,dead; int32_t num,sock; uint16_t port,pubport,repport; +}; + +struct supernet_info +{ + char ipaddr[64],transport[8]; int32_t APISLEEP; int32_t iamrelay; uint64_t my64bits; uint64_t ipbits; + int32_t Debuglevel,readyflag,dead,POLLTIMEOUT; + //int32_t pullsock,subclient,lbclient,lbserver,servicesock,pubglobal,pubrelays,numservers; + bits256 privkey,pubkey; + uint16_t port,serviceport,acceptport; + struct nn_pollfd pfd[SUPERNET_MAXAGENTS]; //struct relay_info active; + struct supernet_agent agents[SUPERNET_MAXAGENTS]; queue_t acceptQ; int32_t numagents; +}; + +struct supernet_endpoint +{ + char name[64]; struct endpoint ep; + int32_t (*nnrecvfunc)(struct supernet_info *,struct supernet_endpoint *,int32_t ind,uint8_t *msg,int32_t nnlen); + queue_t nnrecvQ; + int32_t nnsock,num; struct endpoint eps[]; +}; + +void expand_epbits(char *endpoint,struct endpoint epbits); +struct endpoint calc_epbits(char *transport,uint32_t ipbits,uint16_t port,int32_t type); + +void SuperNET_init(); +char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr); + +char *pangea_parser(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr); +char *ramchain_parser(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr); +char *iguana_parser(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr); +char *InstantDEX_parser(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr); + +#endif + diff --git a/iguana/iguana.sources b/iguana/iguana.sources index 23a485ba6..50b735bff 100755 --- a/iguana/iguana.sources +++ b/iguana/iguana.sources @@ -1,9 +1 @@ -SOURCES := iguana_wallet.c iguana_pubkeys.c iguana_recv.c iguana_bundles.c iguana_msg.c iguana_rpc.c iguana777.c iguana_chains.c iguana_peers.c iguana_accept.c iguana_html.c iguana_bitmap.c iguana_init.c iguana_ramchain.c iguana_blocks.c iguana_json.c ../crypto777/cJSON.c ../crypto777/iguana_utils.c ../crypto777/OS_nonportable.c ../crypto777/curve25519-donna.c ../crypto777/inet.c ../crypto777/OS_portable.c ../crypto777/curve25519.c ../crypto777/libgfshare.c ../crypto777/OS_time.c ../crypto777/hmac_sha512.c ../crypto777/ramcoder.c ../crypto777/SaM.c ../crypto777/iguana_OS.c ../crypto777/iguana_serdes.c ../crypto777/jpeg/jaricom.c ../crypto777/jpeg/jcapimin.c ../crypto777/jpeg/jcapistd.c ../crypto777/jpeg/jcarith.c ../crypto777/jpeg/jccoefct.c ../crypto777/jpeg/jccolor.c \ - ../crypto777/jpeg/jcdctmgr.c ../crypto777/jpeg/jchuff.c ../crypto777/jpeg/jcinit.c ../crypto777/jpeg/jcmainct.c ../crypto777/jpeg/jcmarker.c ../crypto777/jpeg/jcmaster.c \ - ../crypto777/jpeg/jcomapi.c ../crypto777/jpeg/jcparam.c ../crypto777/jpeg/jcprepct.c ../crypto777/jpeg/jcsample.c ../crypto777/jpeg/jctrans.c ../crypto777/jpeg/jdapimin.c \ - ../crypto777/jpeg/jdapistd.c ../crypto777/jpeg/jdarith.c ../crypto777/jpeg/jdatadst.c ../crypto777/jpeg/jdatasrc.c ../crypto777/jpeg/jdcoefct.c ../crypto777/jpeg/jdcolor.c \ - ../crypto777/jpeg/jddctmgr.c ../crypto777/jpeg/jdhuff.c ../crypto777/jpeg/jdinput.c ../crypto777/jpeg/jdmainct.c ../crypto777/jpeg/jdmarker.c ../crypto777/jpeg/jdmaster.c \ - ../crypto777/jpeg/jdmerge.c ../crypto777/jpeg/jdpostct.c ../crypto777/jpeg/jdsample.c ../crypto777/jpeg/jdtrans.c ../crypto777/jpeg/jerror.c ../crypto777/jpeg/jfdctflt.c \ - ../crypto777/jpeg/jfdctfst.c ../crypto777/jpeg/jfdctint.c ../crypto777/jpeg/jidctflt.c ../crypto777/jpeg/jidctfst.c ../crypto777/jpeg/jidctint.c ../crypto777/jpeg/jquant1.c \ - ../crypto777/jpeg/jquant2.c ../crypto777/jpeg/jutils.c ../crypto777/jpeg/jmemmgr.c ../crypto777/jpeg/jmemnobs.c main.c - +SOURCES := iguana_wallet.c iguana_html.c iguana_pubkeys.c iguana_recv.c iguana_bundles.c iguana_msg.c iguana_rpc.c iguana777.c iguana_chains.c iguana_peers.c iguana_accept.c iguana_bitmap.c iguana_init.c iguana_ramchain.c iguana_blocks.c iguana_json.c $(CRYPTO777_SRCS) main.c diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 0c5e8da7d..04106ab28 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -284,7 +284,7 @@ int32_t iguana_helpertask(FILE *fp,struct OS_memspace *mem,struct OS_memspace *m void iguana_helper(void *arg) { - FILE *fp = 0; char fname[512],name[64],*helpername = 0; cJSON *argjson=0; int32_t i,flag; + FILE *fp = 0; char fname[512],name[64],*helpername = 0; cJSON *argjson=0; int32_t flag; struct iguana_helper *ptr; struct iguana_info *coin; struct OS_memspace MEM,*MEMB; if ( arg != 0 && (argjson= cJSON_Parse(arg)) != 0 ) helpername = jstr(argjson,"name"); @@ -302,6 +302,7 @@ void iguana_helper(void *arg) MEMB = mycalloc('b',IGUANA_MAXBUNDLESIZE,sizeof(*MEMB)); while ( 1 ) { + iguana_jsonQ(); flag = 0; if ( (ptr= queue_dequeue(&helperQ,0)) != 0 ) { @@ -316,11 +317,11 @@ void iguana_helper(void *arg) } if ( flag == 0 ) { - for (i=0; ilaunched != 0 ) flag += iguana_rpctest(coin); - } + }*/ if ( flag == 0 ) usleep(10000); } diff --git a/iguana/iguana777.h b/iguana/iguana777.h index b83bd6038..03009f3f3 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -132,7 +132,7 @@ extern int32_t IGUANA_NUMHELPERS; #define IGUANA_ALLOC_MULT 1.1 #define IGUANA_ALLOC_INCR 1000 -#define IGUANA_JSONTIMEOUT 10000 +#define IGUANA_JSONTIMEOUT 1000 #define IGUANA_MAPRECVDATA 1 #define IGUANA_MAPTXIDITEMS 2 @@ -432,7 +432,7 @@ struct iguana_info struct iguana_bitmap screen; //struct pollfd fds[IGUANA_MAXPEERS]; struct iguana_peer bindaddr; int32_t numsocks; struct OS_memspace TXMEM; - queue_t acceptQ,bundlesQ,hdrsQ,blocksQ,priorityQ,possibleQ,jsonQ,finishedQ,TerminateQ,cacheQ; + queue_t acceptQ,bundlesQ,hdrsQ,blocksQ,priorityQ,possibleQ,TerminateQ,cacheQ; double parsemillis,avetime; uint32_t Launched[8],Terminated[8]; portable_mutex_t peers_mutex,blocks_mutex; struct iguana_bundle *bundles[IGUANA_MAXBUNDLES]; @@ -477,7 +477,7 @@ int32_t iguana_rwblock(int32_t rwflag,bits256 *hash2p,uint8_t *serialized,struct int32_t iguana_serialize_block(bits256 *hash2p,uint8_t serialized[sizeof(struct iguana_msgblock)],struct iguana_block *block); void iguana_blockconv(struct iguana_block *dest,struct iguana_msgblock *msg,bits256 hash2,int32_t height); //void iguana_freetx(struct iguana_msgtx *tx,int32_t n); -int32_t iguana_parser(struct iguana_info *coin,struct iguana_peer *addr,struct OS_memspace *rawmem,struct OS_memspace *txmem,struct OS_memspace *hashmem,struct iguana_msghdr *H,uint8_t *data,int32_t datalen); +int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struct OS_memspace *rawmem,struct OS_memspace *txmem,struct OS_memspace *hashmem,struct iguana_msghdr *H,uint8_t *data,int32_t datalen); // send message int32_t iguana_validatehdr(struct iguana_msghdr *H); @@ -559,7 +559,7 @@ double dxblend(double *destp,double val,double decay); // json int32_t iguana_processjsonQ(struct iguana_info *coin); // reentrant, can be called during any idletime -char *iguana_JSON(struct iguana_info *coin,char *jsonstr,char *remoteaddr); +char *iguana_JSON(char *jsonstr); char *SuperNET_p2p(struct iguana_info *coin,int32_t *delaymillisp,char *ipaddr,uint8_t *data,int32_t datalen); char *mbstr(char *str,double); @@ -670,11 +670,14 @@ int32_t iguana_send_supernet(struct iguana_info *coin,struct iguana_peer *addr,c struct iguana_waccount *iguana_waccountfind(struct iguana_info *coin,char *account); struct iguana_waccount *iguana_waccountadd(struct iguana_info *coin,char *walletaccount,struct iguana_waddress *waddr); -int32_t iguana_waccountswitch(struct iguana_info *coin,struct iguana_waddress *waddr,char *coinaddr); -struct iguana_waddress *iguana_waddressfind(struct iguana_info *coin,char *coinaddr); +int32_t iguana_waccountswitch(struct iguana_info *coin,char *account,struct iguana_waccount *oldwaddr,int32_t oldind,char *coinaddr); +struct iguana_waddress *iguana_waddresscalc(struct iguana_info *coin,struct iguana_waddress *addr,bits256 privkey); +struct iguana_waccount *iguana_waddressfind(struct iguana_info *coin,int32_t *indp,char *coinaddr); char *iguana_coinjson(struct iguana_info *coin,char *method,cJSON *json); cJSON *iguana_peersjson(struct iguana_info *coin,int32_t addronly); int32_t btc_priv2wip(char *wipstr,uint8_t privkey[32],uint8_t addrtype); int32_t btc_pub2rmd(uint8_t rmd160[20],uint8_t pubkey[33]); +int32_t iguana_launchcoin(char *symbol,cJSON *json); +int32_t iguana_jsonQ(); #endif diff --git a/iguana/iguana_bitmap.c b/iguana/iguana_bitmap.c index 1a8d57880..678af8bd2 100755 --- a/iguana/iguana_bitmap.c +++ b/iguana/iguana_bitmap.c @@ -123,7 +123,7 @@ void gen_jpegfile(char *fname,int32_t quality,uint8_t *bitmap,int32_t width,int3 int row_stride; /* physical row width in image buffer */ cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); - if ((outfile = fopen(fname, "wb")) == NULL) + if ( (outfile= fopen(fname,"wb")) == NULL) { fprintf(stderr, "can't open %s\n", fname); exit(1); @@ -1131,11 +1131,10 @@ void iguana_bitmap(char *space,int32_t max,char *name) //sprintf(space,"Content-type: text/standard\r\n"); //sprintf(space+strlen(space),"Content-Length: %ld\r\n\r\n",strlen(buf)); //strcpy(space,buf); - //printf("bitmap.[%s]\n",space); + printf("bitmap.[%s]\n",space); } else { - sprintf(space,"{\"name\":\"%s\",\"status\":\"%s\",\"amplitude\":%u,\"width\":%d,\"height\":%d,\"pixels\":[",name,coin!=0?coin->statusstr:"no coin",rect->amplitude,rect->width,rect->height), len = (int32_t)strlen(space); ptr = rect->data; h = rect->height, w = rect->width; for (y=0; ysymbol) == 0 ) { + printf("found.(%s)\n",name); iguana_chaininit(chain,strcmp(chain->symbol,"BTC") == 0); return(chain); } diff --git a/iguana/iguana_html.c b/iguana/iguana_html.c index 83c4178b4..a87762154 100755 --- a/iguana/iguana_html.c +++ b/iguana/iguana_html.c @@ -14,7 +14,7 @@ ******************************************************************************/ #include "iguana777.h" -#include "../includes/cJSON.h" +#include "SuperNET.h" char Default_agent[64] = { "ALL" }; #define IGUANA_FORMS "[ \ @@ -152,552 +152,6 @@ char *HTMLfooter = #define HTML_EMIT(str) if ( (str) != 0 && (str)[0] != 0 ) strcpy(&retbuf[size],str), size += (int32_t)strlen(str) char Prevjsonstr[1024],Currentjsonstr[1024]; -char *iguana_rpc(char *agent,cJSON *json,char *data,int32_t datalen,char *remoteaddr) -{ - //printf("agent.(%s) json.(%s) data[%d] %s\n",agent,jprint(json,0),datalen,data!=0?data:""); - if ( data == 0 ) - return(iguana_JSON(0,jprint(json,0),remoteaddr)); - else return(iguana_JSON(0,data,remoteaddr)); -} - -void iguana_urldecode(char *str) -{ - int32_t a,b,c; char *dest = str; - while ( (c= *str) != 0 ) - { - if ( c == '%' && (a= str[1]) != 0 && (b= str[2]) != 0 ) - *dest++ = (unhex(a)<<4) | unhex(b); - else *dest++ = c; - } - *dest = 0; -} - -char *iguana_parsebidask(char *base,char *rel,char *exchange,double *pricep,double *volumep,char *line) -{ - int32_t i; - for (i=0; i<16&&line[i]!='/'&&line[i]!=0; i++) - base[i] = line[i]; - base[i] = 0; - touppercase(base); - line += (i + 1); - for (i=0; i<16&&line[i]!='/'&&line[i]!=0; i++) - rel[i] = line[i]; - rel[i] = 0; - touppercase(rel); - line += (i + 1); - for (i=0; i<16&&line[i]!='/'&&line[i]!=0; i++) - exchange[i] = line[i]; - exchange[i] = 0; - line += (i + 1); - if ( strncmp(line,"price/",strlen("price/")) == 0 ) - { - line += strlen("price/"); - *pricep = atof(line); - if ( (line= strstr(line,"volume/")) != 0 ) - { - line += strlen("volume/"); - *volumep = atof(line); - for (i=0; i<16&&line[i]!=0; i++) - if ( line[i] == '/' ) - { - i++; - break; - } - return(line+i); - } - } - return(0); -} - -char *iguana_InstantDEX(char *jsonstr,char *path,char *method) -{ - char *str,base[64],rel[64],exchange[64]; double price,volume; - if ( (str= iguana_parsebidask(base,rel,exchange,&price,&volume,path)) != 0 ) - { - if ( price > 0. && volume > 0. ) - { - sprintf(jsonstr,"{\"agent\":\"InstantDEX\",\"method\":\"%s\",\"base\":\"%s\",\"rel\":\"%s\",\"exchange\":\"%s\",\"price\":\%0.8f,\"volume\":%0.8f}",method,base,rel,exchange,price,volume); - return(jsonstr); - } - else return(0); - } - return(0); -} - -void iguana_coinset(char *buf,char *path) -{ - int32_t i; - if ( path[0] == '/' ) - path++; - for (i=0; i<8&&path[i]!=0&&path[i]!=' '&&path[i]!='/'; i++) - buf[i] = path[i]; - buf[i] = 0; - touppercase(buf); -} - -char *iguana_ramchain_glue(struct iguana_info *coin,char *method,char *jsonstr) -{ - char *ramchain_parser(struct iguana_agent *agent,struct iguana_info *coin,char *method,cJSON *json); - cJSON *json; char *retstr; - json = cJSON_Parse(jsonstr); - retstr = ramchain_parser(0,coin,method,json); - free_json(json); - return(retstr); -} - -char *iguana_hashparse(char *path) -{ - int32_t i,j,len,iter,n; uint8_t databuf[512]; - char hexstr[1025],password[512],hashname[512],*name,*msg; cJSON *json; - typedef void (*hashfunc)(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); - typedef char *(*hmacfunc)(char *dest,char *key,int32_t key_size,char *message); - struct hashfunc_entry { char *name; hashfunc hashfunc; }; - struct hmacfunc_entry { char *name; hmacfunc hmacfunc; }; - struct hashfunc_entry hashes[] = { {"NXT",calc_NXTaddr}, {"curve25519",calc_curve25519_str }, {"base64_encode",calc_base64_encodestr}, {"base64_decode",calc_base64_decodestr}, {"crc32",calc_crc32str}, {"rmd160_sha256",rmd160ofsha256}, {"sha256_sha256",sha256_sha256}, {"sha256",vcalc_sha256}, {"sha512",calc_sha512}, {"sha384",calc_sha384}, {"sha224",calc_sha224}, {"rmd160",calc_rmd160}, {"rmd256",calc_rmd256}, {"rmd320",calc_rmd320}, {"rmd128",calc_rmd128}, {"sha1",calc_sha1}, {"md5",calc_md5str}, {"tiger",calc_tiger}, {"whirlpool",calc_whirlpool} }; - struct hmacfunc_entry hmacs[] = { {"hmac_sha256",hmac_sha256_str}, {"hmac_sha512",hmac_sha512_str}, {"hmac_sha384",hmac_sha384_str}, {"hmac_sha224",hmac_sha224_str}, {"hmac_rmd160",hmac_rmd160_str}, {"hmac_rmd256",hmac_rmd256_str}, {"hmac_rmd320",hmac_rmd320_str}, {"hmac_rmd128",hmac_rmd128_str}, {"hmac_sha1",hmac_sha1_str}, {"hmac_md5",hmac_md5_str}, {"hmac_tiger",hmac_tiger_str}, {"hmac_whirlpool",hmac_whirlpool_str} }; - n = (int32_t)sizeof(hashes)/sizeof(*hashes); - for (j=0; j 0 ) - { - jsonstr[i] = 0; - agent = jsonstr; - jsonstr += i; - } - jsonstr++; - json = cJSON_CreateObject(); - jaddstr(json,"agent",agent); - while ( 1 ) - { - n = (int32_t)strlen(jsonstr); - key = jsonstr; - value = 0; - for (i=0; i

"); + HTML_EMIT(" SuperUGLY GUI>

"); sprintf(buf,"
"); - //sprintf(buf,"
COIN: "); - //HTML_EMIT(buf); - if ( 0 ) - { - sprintf(formfooter,"\t","InstantDEX","iguana49_setagent"); HTML_EMIT(formfooter); - sprintf(formfooter,"\t","PAX","iguana50_setagent"); HTML_EMIT(formfooter); - sprintf(formfooter,"\t","pangea","iguana51_setagent"); HTML_EMIT(formfooter); - sprintf(formfooter,"\t","jumblr","iguana52_setagent"); HTML_EMIT(formfooter); - sprintf(formfooter,"\t","ramchain","iguana53_setagent"); HTML_EMIT(formfooter); - sprintf(formfooter,"\t","iguana","iguana54_setagent"); HTML_EMIT(formfooter); - } - HTML_EMIT(" Agent: "); HTML_EMIT(Default_agent); - HTML_EMIT("

"); HTML_EMIT(origjsonstr); HTML_EMIT(" -> "); - HTML_EMIT("",cols,rows,fieldname,cols == 1 ? "hidden" : ""); + else sprintf(buf,"",cols,rows,fieldname,cols == 1 ? "hidden" : ""); str = disp==0?jstr(obj,"disp"):disp; - sprintf(&retbuf[size],"%s %s \r\n",str!=0?str:fieldname,buf), size += strlen(&retbuf[size]); + sprintf(&retbuf[size],"%s %s \r\n",str!=0?str:fieldname,buf), size += strlen(&retbuf[size]); } sprintf(formfooter," \n",button,clickname); HTML_EMIT(formfooter); @@ -858,7 +304,7 @@ function iguana_poll( )\ char *iguana_htmlresponse(char *retbuf,int32_t bufsize,int32_t *remainsp,int32_t localaccess,char *retstr,int32_t freeflag) { - static char *html = " %s "; + //static char *html = " %s "; char *result=0,*error=0; int32_t n; cJSON *json,*formsjson; retbuf[0] = 0; /*if ( localaccess == 0 ) @@ -873,7 +319,7 @@ char *iguana_htmlresponse(char *retbuf,int32_t bufsize,int32_t *remainsp,int32_t sprintf(retbuf+strlen(retbuf),"\n\r"); n = (int32_t)strlen(retbuf); formsjson = cJSON_Parse(IGUANA_FORMS); - if ( (json= cJSON_Parse(retstr)) == 0 ) + if ( retstr == 0 || (json= cJSON_Parse(retstr)) == 0 ) json = cJSON_CreateObject(); jadd(json,"forms",formsjson); error = jstr(json,"error"); @@ -881,11 +327,11 @@ char *iguana_htmlresponse(char *retbuf,int32_t bufsize,int32_t *remainsp,int32_t //printf("process.(%s)\n",jprint(formsjson,0)); n = iguana_htmlgen(&retbuf[n],bufsize-n,result,error,json,"iguana",Currentjsonstr); free_json(json); - if ( n == 0 ) + /*if ( n == 0 ) { n = (int32_t)(strlen(html) + strlen(retstr) + 1); sprintf(retbuf+strlen(retbuf),html,retstr); - } + }*/ if ( freeflag != 0 ) free(retstr); if ( n > bufsize ) @@ -897,10 +343,180 @@ char *iguana_htmlresponse(char *retbuf,int32_t bufsize,int32_t *remainsp,int32_t return(retbuf); } +int32_t Supernet_lineparse(char *key,int32_t keymax,char *value,int32_t valuemax,char *src) +{ + int32_t a,b,c,n = 0; + key[0] = value[0] = 0; + while ( (c= src[n]) == ' ' || c == '\t' || c == '\n' || c == '\t' ) + n++; + while ( (c= src[n]) != ':' && c != 0 ) + { + *key++ = c; + if ( ++n >= keymax-1 ) + { + *key = 0; + printf("lineparse overflow key.(%s)\n",src); + return(-1); + } + } + *key = 0; + if ( src[n] != ':' ) + return(n); + n++; + while ( (c= src[n]) == ' ' || c == '\t' ) + n++; + while ( (c= src[n]) != 0 && c != '\r' && c != '\n' ) + { + if ( c == '%' && (a= src[n+1]) != 0 && (b= src[n+2]) != 0 ) + c = ((unhex(a) << 4) | unhex(b)), n += 2; + *value++ = c; + n++; + if ( n >= valuemax-1 ) + { + *value = 0; + printf("lineparse overflow.(%s)\n",src); + return(-1); + } + } + *value = 0; + if ( src[n] != 0 ) + { + n++; + while ( (c= src[n]) == '\r' || c == '\n' ) + n++; + } + return(n); +} + +cJSON *SuperNET_urlconv(char *value,int32_t bufsize,char *urlstr) +{ + int32_t i,n,totallen,datalen,len = 0; cJSON *json,*array; char key[8192],*data; + json = cJSON_CreateObject(); + array = cJSON_CreateArray(); + totallen = (int32_t)strlen(urlstr); + while ( 1 ) + { + for (i=len; urlstr[i]!=0; i++) + if ( urlstr[i] == '\r' || urlstr[i] == '\n' ) + break; + if ( i == len && (urlstr[len] == '\r' || urlstr[len] == '\n') ) + { + len++; + continue; + } + urlstr[i] = 0; + if ( (n= Supernet_lineparse(key,sizeof(key),value,bufsize,&urlstr[len])) > 0 ) + { + if ( value[0] != 0 ) + jaddstr(json,key,value); + else jaddistr(array,key); + len += (n + 1); + if ( strcmp(key,"Content-Length") == 0 && (datalen= atoi(value)) > 0 ) + { + data = &urlstr[totallen - datalen]; + data[-1] = 0; + //printf("post.(%s) (%c)\n",data,data[0]); + jaddstr(json,"POST",data); + } + } else break; + } + jadd(json,"lines",array); + return(json); +} + +char *SuperNET_rpcparse(struct supernet_info *myinfo,char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *postflagp,char *urlstr,char *remoteaddr) +{ + cJSON *tokens,*argjson,*json = 0; char urlmethod[16],*data,url[1024],*retstr,*token = 0; int32_t i,j,n; + //printf("rpcparse.(%s)\n",urlstr); + for (i=0; i 0 ) + { + jaddstr(argjson,"agent",jstri(tokens,0)); + if ( n > 1 ) + jaddstr(argjson,"method",jstri(tokens,1)); + for (i=2; i (%s) postflag.%d (%s)\n",urlstr,cJSON_Print(json),*postflagp,retstr); + return(retstr); + } + return(clonestr("{\"error\":\"couldnt process packet\"}")); +} + void iguana_rpcloop(void *args) { - int32_t recvlen,bindsock,postflag,sock,remains,numsent,len; socklen_t clilen; - char ipaddr[64],jsonbuf[8192],*buf,*retstr,*space;//,*retbuf; ,n,i,m + struct supernet_info *myinfo = args; + int32_t recvlen,bindsock,postflag,sock,remains,numsent,jsonflag,len; socklen_t clilen; + char remoteaddr[64],jsonbuf[8192],*buf,*retstr,*space;//,*retbuf; ,n,i,m struct sockaddr_in cli_addr; uint32_t ipbits,i,size = IGUANA_WIDTH*IGUANA_HEIGHT*16 + 512; uint16_t port; port = IGUANA_RPCPORT; bindsock = iguana_socket(1,"127.0.0.1",port); @@ -917,7 +533,7 @@ void iguana_rpcloop(void *args) continue; } memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); - expand_ipbits(ipaddr,ipbits); + expand_ipbits(remoteaddr,ipbits); //printf("RPC.%d for %x (%s)\n",sock,ipbits,ipaddr); //printf("%p got.(%s) from %s | usock.%d ready.%u dead.%u\n",addr,H.command,addr->ipaddr,addr->usock,addr->ready,addr->dead); memset(jsonbuf,0,sizeof(jsonbuf)); @@ -943,18 +559,23 @@ void iguana_rpcloop(void *args) remains -= len; recvlen += len; buf = &buf[len]; + retstr = SuperNET_rpcparse(myinfo,space,size,&jsonflag,&postflag,jsonbuf,remoteaddr); + break; } else usleep(10000); //printf("got.(%s) %d remains.%d of total.%d\n",jsonbuf,recvlen,remains,len); - retstr = iguana_rpcparse(space,size,&postflag,jsonbuf); + //retstr = iguana_rpcparse(space,size,&postflag,jsonbuf); break; } } + if ( retstr == 0 ) + retstr = iguana_htmlresponse(space,size,&remains,1,retstr,retstr != space); if ( retstr != 0 ) { i = 0; - if ( postflag == 0 ) - retstr = iguana_htmlresponse(space,size,&remains,1,retstr,1); + if ( 0 && postflag == 0 ) + retstr = iguana_htmlresponse(space,size,&remains,1,retstr,retstr != space); else remains = (int32_t)strlen(retstr); + //printf("POSTFLAG.%d\n",postflag); //printf("RETBUF.(%s)\n",retstr); while ( remains > 0 ) { @@ -981,6 +602,6 @@ void iguana_rpcloop(void *args) strcpy(Prevjsonstr,Currentjsonstr); Currentjsonstr[0] = 0; //printf("done response sock.%d\n",sock); - close(sock); + closesocket(sock); } } \ No newline at end of file diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index 8348fd075..76bfe9fe7 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -32,8 +32,6 @@ void iguana_initQs(struct iguana_info *coin) iguana_initQ(&coin->blocksQ,"blocksQ"); iguana_initQ(&coin->priorityQ,"priorityQ"); iguana_initQ(&coin->possibleQ,"possibleQ"); - iguana_initQ(&coin->jsonQ,"jsonQ"); - iguana_initQ(&coin->finishedQ,"finishedQ"); iguana_initQ(&coin->cacheQ,"cacheQ"); iguana_initQ(&coin->TerminateQ,"TerminateQ"); for (i=0; iname); - jadd(json,"methods",agent->methods); - if ( agent->port != 0 ) - jaddnum(json,"port",agent->port); - else jaddstr(json,"type","builtin"); - return(json); -} - -char *iguana_remoteparser(struct iguana_agent *agent,struct iguana_info *coin,char *method,cJSON *json) -{ - int32_t i,n,remains,numsent; char *jsonstr = 0,*retstr = 0; uint8_t hdr[128]; - if ( agent->sock < 0 ) - agent->sock = iguana_socket(0,agent->hostname,agent->port); - if ( agent->sock >= 0 ) - { - i = 0; - jsonstr = jprint(json,0); - n = (int32_t)strlen(jsonstr) + 1; - remains = n; - //printf("RETBUF.(%s)\n",retbuf); - while ( remains > 0 ) - { - if ( (numsent= (int32_t)send(agent->sock,&jsonstr[i],remains,MSG_NOSIGNAL)) < 0 ) - { - if ( errno != EAGAIN && errno != EWOULDBLOCK ) - { - printf("%s: %s numsent.%d vs remains.%d of %d errno.%d (%s) usock.%d\n",jsonstr,agent->name,numsent,remains,n,errno,strerror(errno),agent->sock); - break; - } - } - else if ( remains > 0 ) - { - remains -= numsent; - i += numsent; - if ( remains > 0 ) - printf("iguana sent.%d remains.%d of len.%d\n",numsent,remains,n); - } - } - if ( (n= (int32_t)recv(agent->sock,hdr,sizeof(hdr),0)) >= 0 ) - { - remains = (hdr[0] + ((int32_t)hdr[1] << 8) + ((int32_t)hdr[2] << 16)); - retstr = mycalloc('p',1,remains + 1); - i = 0; - while ( remains > 0 ) - { - if ( (n= (int32_t)recv(agent->sock,&retstr[i],remains,0)) < 0 ) - { - if ( errno == EAGAIN ) - { - printf("EAGAIN for len %d, remains.%d\n",n,remains); - usleep(10000); - } - break; - } - else - { - if ( n > 0 ) - { - remains -= n; - i += n; - } else usleep(10000); - } - } - } - free(jsonstr); - } - if ( retstr == 0 ) - retstr = clonestr("{\"error\":\"null return\"}"); - return(retstr); -} - -char *iguana_addagent(char *name,char *(*parsefunc)(struct iguana_agent *agent,struct iguana_info *coin,char *method,cJSON *json),char *hostname,cJSON *methods,uint16_t port,char *pubkeystr,char *privkeystr) -{ - int32_t i; struct iguana_agent *agent; char retbuf[8192]; - for (i=0; iname,name) == 0 ) - { - if ( pubkeystr != 0 && privkeystr != 0 && strlen(pubkeystr) == 64 && strlen(privkeystr) == 64 ) - { - decode_hex(agent->pubkey.bytes,sizeof(bits256),pubkeystr); - decode_hex(agent->privkey.bytes,sizeof(bits256),privkeystr); - } - if ( port != 0 && agent->port == 0 ) - { - if ( agent->sock >= 0 ) - close(agent->sock); - agent->port = port; - strcpy(agent->hostname,hostname); - agent->sock = iguana_socket(0,agent->hostname,port); - printf("set (%s) port.%d for %s -> sock.%d\n",hostname,port,agent->name,agent->sock); - } - if ( agent->port > 0 && agent->sock < 0 && agent->hostname[0] != 0 && (agent->sock= iguana_socket(0,agent->hostname,agent->port)) < 0 ) - return(clonestr("{\"result\":\"existing agent couldnt connect to remote agent\"}")); - else return(clonestr("{\"result\":\"agent already there\"}")); - } - } - for (i=0; iname,name,sizeof(agent->name)-1); - strncpy(agent->hostname,hostname,sizeof(agent->hostname)-1); - agent->methods = methods, agent->nummethods = cJSON_GetArraySize(methods); - agent->sock = -1; - agent->port = port; - agent->parsefunc = (void *)parsefunc; - if ( pubkeystr != 0 && privkeystr != 0 && strlen(pubkeystr) == 64 && strlen(privkeystr) == 64 ) - { - decode_hex(agent->pubkey.bytes,sizeof(bits256),pubkeystr); - decode_hex(agent->privkey.bytes,sizeof(bits256),privkeystr); - } - if ( port > 0 ) - { - if ( (agent->sock= iguana_socket(0,hostname,port)) < 0 ) - return(clonestr("{\"result\":\"agent added, but couldnt connect to remote agent\"}")); - } - sprintf(retbuf,"{\"result\":\"agent added\",\"name\"\"%s\",\"methods\":%s,\"hostname\":\"%s\",\"port\":%u,\"sock\":%d}",agent->name,jprint(agent->methods,0),agent->hostname,agent->port,agent->sock); - return(clonestr(retbuf)); - } - } - return(clonestr("{\"error\":\"no more agent slots available\"}")); -} - -char *iguana_agentjson(char *name,struct iguana_info *coin,char *method,cJSON *json,char *remoteaddr) -{ - cJSON *retjson = 0,*array,*methods,*obj; int32_t i,n,j; struct iguana_agent *agent; - if ( strcmp(name,"SuperNET") != 0 ) - { - for (i=0; iname,name) == 0 ) - { - if ( agent->parsefunc != 0 ) - { - for (j=0; jnummethods; j++) - { - if ( (obj= jitem(agent->methods,j)) != 0 ) - { - if ( strcmp(method,jstr(obj,0)) == 0 ) - return((*agent->parsefunc)(agent,method,json,remoteaddr)); - } - } - return(clonestr("{\"result\":\"agent doesnt have method\"}")); - } else return(clonestr("{\"result\":\"agent doesnt have parsefunc\"}")); - } - } - } - else if ( remoteaddr == 0 || strcmp(remoteaddr,"127.0.0.1") != 0 ) // public api - { - char *coinstr; int32_t j,k,l,r,rr; struct iguana_peer *addr; - array = 0; - if ( strcmp(method,"getpeers") == 0 ) - { - if ( (coinstr= jstr(json,"coin")) != 0 ) - { - if ( (array= iguana_peersjson(iguana_coinfind(coinstr),1)) == 0 ) - return(clonestr("{\"error\":\"coin not found\"}")); - } - else - { - n = 0; - array = cJSON_CreateArray(); - r = rand(); - for (i=0; ipeers.active[l]; - if ( addr->usock >= 0 && addr->supernet != 0 ) - { - jaddistr(array,addr->ipaddr); - if ( ++n >= 64 ) - break; - } - } - } - } - } - if ( array != 0 ) - { - retjson = cJSON_CreateObject(); - jaddstr(retjson,"agent","SuperNET"); - jaddstr(retjson,"method","mypeers"); - jaddstr(retjson,"result","peers found"); - jadd(retjson,"peers",array); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"no peers found\"}")); - } - else if ( strcmp(method,"mypeers") == 0 ) - { - printf("mypeers from %s\n",remoteaddr!=0?remoteaddr:"local"); - } - } - else // local api - { - if ( strcmp(method,"list") == 0 ) - { - retjson = cJSON_CreateObject(); - array = cJSON_CreateArray(); - for (i=0; isymbol[0] != 0 ) - jaddistr(array,Coins[i]->symbol); - } - jadd(retjson,"coins",array); - array = cJSON_CreateArray(); - for (i=0; iname[0] != 0 ) - jaddi(array,iguana_agentinfojson(Agents[i])); - } - jadd(retjson,"agents",array); - return(jprint(retjson,1)); - } - else if ( strcmp(method,"peers") == 0 ) - { - retjson = cJSON_CreateObject(); - array = cJSON_CreateArray(); - for (i=0; isymbol[0] != 0 ) - jaddi(array,iguana_peersjson(Coins[i],0)); - } - jadd(retjson,"allpeers",array); - return(jprint(retjson,1)); - } - else if ( strcmp(method,"addagent") == 0 ) - { - char *hostname = "127.0.0.1",*name; uint16_t port; - if ( (name= jstr(json,"name")) != 0 && (methods= jarray(&n,json,"methods")) != 0 ) - { - if ( (port= juint(json,"port")) != 0 ) - { - if ( (hostname= jstr(json,"host")) == 0 ) - { - if ( (hostname= jstr(json,"ipaddr")) == 0 ) - hostname = "127.0.0.1"; - } - if ( hostname == 0 ) - return(clonestr("{\"error\":\"no host specified for remote agent\"}")); - } - else if ( strcmp(name,"pangea") != 0 && strcmp(name,"InstantDEX") != 0 && strcmp(name,"jumblr") != 0 ) - return(clonestr("{\"error\":\"no port specified for remote agent\"}")); - return(iguana_addagent(name,iguana_remoteparser,hostname,methods,port,jstr(json,"pubkey"),jstr(json,"privkey"))); - } else return(clonestr("{\"error\":\"cant addagent without name and methods\"}")); - } - } - return(clonestr("{\"result\":\"stub processed generic json\"}")); -} - char *iguana_coinjson(struct iguana_info *coin,char *method,cJSON *json) { int32_t i,max,retval; struct iguana_peer *addr; char *ipaddr; cJSON *retjson = 0; @@ -422,244 +152,101 @@ char *iguana_coinjson(struct iguana_info *coin,char *method,cJSON *json) return(clonestr("{\"error\":\"unhandled request\"}")); } -char *iguana_jsonstr(struct iguana_info *coin,char *jsonstr,char *remoteaddr) +char *iguana_parser(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr) { - cJSON *json; char *retjsonstr,*methodstr,*agentstr; - //printf("iguana_jsonstr.(%s)\n",jsonstr); - if ( (json= cJSON_Parse(jsonstr)) != 0 ) + char *coinstr,SYM[16]; int32_t j,k,l,r,rr; struct iguana_peer *addr; + cJSON *retjson = 0,*array; int32_t i,n; struct iguana_info *coin; char *symbol; + printf("remoteaddr.(%s)\n",remoteaddr!=0?remoteaddr:"local"); + if ( remoteaddr == 0 || remoteaddr[0] == 0 || strcmp(remoteaddr,"127.0.0.1") == 0 ) // local (private) api { - if ( (methodstr= jstr(json,"method")) != 0 ) - { - if ( (agentstr= jstr(json,"agent")) == 0 || strcmp(agentstr,"iguana") == 0 ) - retjsonstr = iguana_coinjson(coin,methodstr,json); - else retjsonstr = iguana_agentjson(agentstr,coin,methodstr,json,remoteaddr); - } else retjsonstr = clonestr("{\"error\":\"no method in JSON\"}"); - free_json(json); - } else retjsonstr = clonestr("{\"error\":\"cant parse JSON\"}"); - printf("iguana_jsonstr.(%s)\n",retjsonstr); - return(retjsonstr); -} - -int32_t iguana_processjsonQ(struct iguana_info *coin) // reentrant, can be called during any idletime -{ - struct iguana_jsonitem *ptr; - if ( (ptr= queue_dequeue(&coin->finishedQ,0)) != 0 ) - { - if ( ptr->expired != 0 ) - { - *ptr->retjsonstrp = clonestr("{\"error\":\"request timeout\"}"); - printf("garbage collection: expired.(%s)\n",ptr->jsonstr); - myfree(ptr,ptr->allocsize); - } else queue_enqueue("finishedQ",&coin->finishedQ,&ptr->DL,0); - } - if ( (ptr= queue_dequeue(&coin->jsonQ,0)) != 0 ) - { - //printf("process.(%s)\n",ptr->jsonstr); - if ( (*ptr->retjsonstrp= iguana_jsonstr(ptr->fallback==0?coin:0,ptr->jsonstr,ptr->remoteaddr)) == 0 ) - *ptr->retjsonstrp = clonestr("{\"error\":\"null return from iguana_jsonstr\"}"); - queue_enqueue("finishedQ",&coin->finishedQ,&ptr->DL,0); - return(1); - } - return(0); -} - -char *iguana_blockingjsonstr(struct iguana_info *coin,char *jsonstr,uint64_t tag,int32_t maxmillis,char *remoteaddr) -{ - struct iguana_jsonitem *ptr; char *retjsonstr = 0; int32_t fallback = 0,len,allocsize; double expiration = OS_milliseconds() + maxmillis; - if ( coin == 0 ) - coin = iguana_coinfind("BTCD"), fallback = 1; - if ( coin != 0 ) - { - //printf("blocking case.(%s)\n",jsonstr); - len = (int32_t)strlen(jsonstr); - allocsize = sizeof(*ptr) + len + 1; - ptr = mycalloc('J',1,allocsize); - ptr->allocsize = allocsize; - ptr->fallback = fallback; - ptr->retjsonstrp = &retjsonstr; - safecopy(ptr->remoteaddr,remoteaddr,sizeof(ptr->remoteaddr)); - memcpy(ptr->jsonstr,jsonstr,len+1); - queue_enqueue("jsonQ",&coin->jsonQ,&ptr->DL,0); - while ( OS_milliseconds() < expiration ) + if ( strcmp(method,"list") == 0 ) { - usleep(100); - if ( retjsonstr != 0 ) + retjson = cJSON_CreateObject(); + array = cJSON_CreateArray(); + for (i=0; ifinishedQ,&ptr->DL,allocsize,1); - return(retjsonstr); + if ( Coins[i] != 0 && Coins[i]->symbol[0] != 0 ) + jaddistr(array,Coins[i]->symbol); } - usleep(1000); - } - printf("(%s) expired\n",jsonstr); - ptr->expired = (uint32_t)time(NULL); - return(clonestr("{\"error\":\"iguana jsonstr expired\"}")); - } - return(clonestr("{\"error\":\"iguana blockingjsonstr cant get coin_info\"}")); -} - -char *iguana_JSON(struct iguana_info *coin,char *jsonstr,char *remoteaddr) -{ - cJSON *json,*retjson; uint64_t tag; uint32_t timeout; int32_t retval,localaccess = 0; - char *method,*retjsonstr,*symbol,*retstr = 0; - if ( remoteaddr == 0 || strcmp(remoteaddr,"127.0.0.1") == 0 ) // || strcmp(remoteaddr,myipaddr) == 0 ) - localaccess = 1; - printf("iguana_JSON.(%s) from %s\n",jsonstr,localaccess==0?remoteaddr:"local access"); - if ( (json= cJSON_Parse(jsonstr)) != 0 ) - { - if ( localaccess != 0 && (method= jstr(json,"method")) != 0 && strcmp(method,"addcoin") == 0 ) - { - if ( (retval= iguana_launchcoin(jstr(json,"coin"),json)) > 0 ) - return(clonestr("{\"result\":\"launched coin\"}")); - else if ( retval == 0 ) return(clonestr("{\"result\":\"coin already launched\"}")); - else return(clonestr("{\"error\":\"error launching coin\"}")); - } - if ( (tag= j64bits(json,"tag")) == 0 ) - OS_randombytes((uint8_t *)&tag,sizeof(tag)); - if ( (symbol= jstr(json,"coin")) != 0 ) - { - coin = iguana_coinfind(symbol); - if ( coin != 0 && localaccess != 0 && coin->launched == 0 ) - iguana_launchcoin(symbol,json); + jadd(retjson,"coins",array); + return(jprint(retjson,1)); } - if ( (timeout= juint(json,"timeout")) == 0 ) - timeout = IGUANA_JSONTIMEOUT; - if ( (retjsonstr= iguana_blockingjsonstr(coin,jsonstr,tag,timeout,remoteaddr)) != 0 ) + else if ( strcmp(method,"allpeers") == 0 ) { - //printf("retjsonstr.(%s)\n",retjsonstr); - if ( (retjson= cJSON_Parse(retjsonstr)) == 0 ) + retjson = cJSON_CreateObject(); + array = cJSON_CreateArray(); + for (i=0; isymbol[0] != 0 ) + jaddi(array,iguana_peersjson(Coins[i],0)); } - jdelete(retjson,"tag"); - jadd64bits(retjson,"tag",tag); - retstr = jprint(retjson,1); - //printf("retstr.(%s) retjsonstr.%p retjson.%p\n",retstr,retjsonstr,retjson); - free(retjsonstr);//,strlen(retjsonstr)+1); + jadd(retjson,"allpeers",array); + return(jprint(retjson,1)); } - free_json(json); - } else retstr = clonestr("{\"error\":\"cant parse JSON\"}"); - if ( retstr == 0 ) - retstr = clonestr("{\"error\":\"null return\"}"); - return(retstr); -} - -char *SuperNET_p2p(struct iguana_info *coin,int32_t *delaymillisp,char *ipaddr,uint8_t *data,int32_t datalen) -{ - cJSON *json,*retjson; char *retstr = 0; - if ( (json= cJSON_Parse((char *)data)) != 0 ) - { - printf("GOT >>>>>>>> SUPERNET P2P.(%s)\n",(char *)data); - if ( (retstr = iguana_JSON(coin,(char *)data,ipaddr)) != 0 ) + else { - if ( (retjson= cJSON_Parse(retstr)) != 0 ) + if ( (symbol= jstr(json,"coin")) != 0 && strlen(symbol) < sizeof(SYM)-1 ) { - if ( jobj(retjson,"result") != 0 || jobj(retjson,"error") != 0 || jobj(retjson,"method") == 0 ) + strcpy(SYM,symbol); + touppercase(SYM); + if ( (coin= iguana_coinfind(SYM)) == 0 ) { - free(retstr); - retstr = 0; + if ( strcmp(method,"addcoin") == 0 ) + coin = iguana_coinadd(SYM); } - free_json(retjson); + if ( coin != 0 ) + return(iguana_coinjson(coin,method,json)); + else return(clonestr("{\"error\":\"cant get coin info\"}")); } } - free_json(json); - } - return(retstr); -} - -/*void iguana_issuejsonstrM(void *arg) -{ - cJSON *json; int32_t fd; char *retjsonstr,*jsonstr = arg; - retjsonstr = iguana_JSON(jsonstr); - if ( (json= cJSON_Parse(jsonstr)) != 0 ) - { - if ( (fd= juint(json,"retdest")) > 0 ) - { - send(fd,jsonstr,(int32_t)strlen(jsonstr)+1,MSG_NOSIGNAL); - } - free_json(json); - return; } - printf("%s\n",retjsonstr); - free(retjsonstr);//,strlen(retjsonstr)+1); - free(jsonstr);//,strlen(jsonstr)+1); -}*/ - -void iguana_main(void *arg) -{ - char helperstr[64],*helperargs,*coinargs=0,*retstr,*secret,*jsonstr = arg; - int32_t i,len,flag; cJSON *json; uint8_t secretbuf[512]; - // portable_OS_init()? - mycalloc(0,0,0); + array = 0; + if ( strcmp(method,"getpeers") == 0 ) { - char str[65]; struct tai t; double startmillis; int32_t datenum,seconds; uint64_t i,checkval,timestamp,now = (uint32_t)time(NULL); - startmillis = OS_milliseconds(); - for (i=0; i<1000000; i++) + if ( (coinstr= jstr(json,"coin")) != 0 ) { - timestamp = now - (rand() % 100000000LL); // range -100000000LL to +500000000LL - datenum = OS_conv_unixtime(&t,&seconds,timestamp); // gmtime -> datenum + number of seconds - checkval = OS_conv_datenum(datenum,seconds/3600,(seconds/60)%60,seconds%60); // datenum+H:M:S -> unix time - if ( checkval != timestamp ) - printf("%s i.%lld timestamp.%-12llu -> (%d:%06d) -> checkval.%-12llu diff.[%lld]\n",tai_str(str,t),(long long)i,(long long)timestamp,datenum,seconds,(long long)checkval,(long long)(timestamp-checkval)); + if ( (array= iguana_peersjson(iguana_coinfind(coinstr),1)) == 0 ) + return(clonestr("{\"error\":\"coin not found\"}")); } - printf("million tai compares in %.3f microseconds per encode/decode\n",1000. * (OS_milliseconds()-startmillis)/i); - } - if ( (retstr= iguana_addagent("ramchain",ramchain_parser,"127.0.0.1",cJSON_Parse("[\"block\", \"tx\", \"txs\", \"rawtx\", \"balance\", \"totalreceived\", \"totalsent\", \"utxo\", \"status\"]"),0,0,0)) != 0 ) - printf("%s\n",retstr), free(retstr); - if ( (retstr= iguana_addagent("pangea",pangea_parser,"127.0.0.1",cJSON_Parse("[\"test\"]"),0,0,0)) != 0 ) - printf("%s\n",retstr), free(retstr); - if ( (retstr= iguana_addagent("InstantDEX",InstantDEX_parser,"127.0.0.1",cJSON_Parse("[\"test\"]"),0,0,0)) != 0 ) - printf("%s\n",retstr), free(retstr); - if ( (retstr= iguana_addagent("jumblr",jumblr_parser,"127.0.0.1",cJSON_Parse("[\"test\"]"),0,0,0)) != 0 ) - printf("%s\n",retstr), free(retstr); - iguana_initQ(&helperQ,"helperQ"); - OS_ensure_directory("confs"); - OS_ensure_directory("DB"); - OS_ensure_directory("tmp"); - if ( jsonstr != 0 && (json= cJSON_Parse(jsonstr)) != 0 ) - { - if ( jobj(json,"numhelpers") != 0 ) - IGUANA_NUMHELPERS = juint(json,"numhelpers"); - if ( (secret= jstr(json,"secret")) != 0 ) + else { - len = (int32_t)strlen(secret); - if ( is_hexstr(secret,0) != 0 && len <= (sizeof(secretbuf)<<1) ) + n = 0; + array = cJSON_CreateArray(); + r = rand(); + for (i=0; i>= 1; - decode_hex(secretbuf,len,secret); - } else vcalc_sha256(0,secretbuf,(void *)secret,len), len = sizeof(bits256); + j = (r + i) % IGUANA_MAXCOINS; + if ( (coin= Coins[j]) != 0 ) + { + rr = rand(); + for (k=0; kpeers.active[l]; + if ( addr->usock >= 0 && addr->supernet != 0 ) + { + jaddistr(array,addr->ipaddr); + if ( ++n >= 64 ) + break; + } + } + } + } } - if ( jobj(json,"coins") != 0 ) - coinargs = jsonstr; - } - if ( IGUANA_NUMHELPERS == 0 ) - IGUANA_NUMHELPERS = 1; - for (i=0; isymbol[0] != 0 ) - flag += iguana_processjsonQ(Coins[i]); - if ( flag == 0 ) - usleep(100000); + printf("mypeers from %s\n",remoteaddr!=0?remoteaddr:"local"); } + return(clonestr("{\"result\":\"stub processed generic json\"}")); } + diff --git a/iguana/iguana_msg.c b/iguana/iguana_msg.c index f1127ad4e..17e0a0e72 100755 --- a/iguana/iguana_msg.c +++ b/iguana/iguana_msg.c @@ -422,7 +422,7 @@ int32_t iguana_send_hashes(struct iguana_info *coin,char *command,struct iguana_ return(retval); } -int32_t iguana_parser(struct iguana_info *coin,struct iguana_peer *addr,struct OS_memspace *rawmem,struct OS_memspace *txmem,struct OS_memspace *hashmem,struct iguana_msghdr *H,uint8_t *data,int32_t recvlen) +int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struct OS_memspace *rawmem,struct OS_memspace *txmem,struct OS_memspace *hashmem,struct iguana_msghdr *H,uint8_t *data,int32_t recvlen) { uint8_t serialized[512]; char *retstr; int32_t i,retval,delay,srvmsg,bloom,intvectors,len= -100; uint64_t nonce,x; uint32_t type; bits256 hash2; diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index e952f664f..f2de86f8b 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -480,7 +480,7 @@ void iguana_parsebuf(struct iguana_info *coin,struct iguana_peer *addr,struct ig iguana_meminit(&addr->HASHMEM,"HASHPTRS",0,256,0);//IGUANA_MAXPACKETSIZE*16,0); //printf("Init %s memory %p %p %p\n",addr->ipaddr,addr->RAWMEM.ptr,addr->TXDATA.ptr,addr->HASHMEM.ptr); } - if ( iguana_parser(coin,addr,&addr->RAWMEM,&addr->TXDATA,&addr->HASHMEM,H,buf,len) < 0 || addr->dead != 0 ) + if ( iguana_msgparser(coin,addr,&addr->RAWMEM,&addr->TXDATA,&addr->HASHMEM,H,buf,len) < 0 || addr->dead != 0 ) { printf("%p addr->dead.%d or parser break at %u\n",&addr->dead,addr->dead,(uint32_t)time(NULL)); addr->dead = (uint32_t)time(NULL); @@ -706,7 +706,7 @@ uint32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr) free_queueitem(ipaddr); return((uint32_t)time(NULL)); } - else if ( coin->peers.active[i].ipaddr != 0 ) + else if ( coin->peers.active[i].ipaddr[0] != 0 ) n++; } if ( n >= coin->MAXPEERS-(coin->MAXPEERS>>3)-1 ) diff --git a/iguana/iguana_rpc.c b/iguana/iguana_rpc.c index 009b03075..986d8bbee 100755 --- a/iguana/iguana_rpc.c +++ b/iguana/iguana_rpc.c @@ -14,60 +14,7 @@ ******************************************************************************/ #include "iguana777.h" - -int32_t iguana_rpctestvector(struct iguana_info *coin,char *checkstr,char *jsonstr,int32_t maxlen,int32_t testi) -{ - int32_t len,checklen; - sprintf(jsonstr,"{\"rpc.%s testvector.%d\"}",coin->symbol,testi); - sprintf(checkstr,"{\"rpc.%s testvector.%d checkstr should have all info needed to verify the rpc request\"}",coin->symbol,testi); - len = (int32_t)strlen(jsonstr); - checklen = (int32_t)strlen(checkstr); - if ( len > maxlen || checklen > maxlen ) - printf("iguana_rpctestvector: i was bad and overflowed buffer len.%d checklen.%d\n",len,checklen), exit(-1); - if ( checklen > len ) - len = checklen; - return(len); -} - -int32_t iguana_rpctestcheck(struct iguana_info *coin,char *jsonstr,char *retjsonstr) -{ - if ( (rand() % 100) == 0 ) // 1% failure rate - return(-1); - else return(0); -} - -int32_t iguana_rpctest(struct iguana_info *coin) -{ -/* static int32_t testi,good,bad; - char *retjsonstr,jsonstr[4096],checkstr[sizeof(jsonstr)]; // should be big enough - //if ( (rand() % 1000) < 999 ) // if no test active, just return 0 - return(0); - if ( iguana_rpctestvector(coin,checkstr,jsonstr,sizeof(jsonstr),testi++) > 0 ) - { - retjsonstr = iguana_rpc(coin,jsonstr); - if ( iguana_rpctestcheck(coin,jsonstr,retjsonstr) < 0 ) - bad++, printf("rpctestcheck.%s error: (%s) -> (%s) | good.%d bad.%d %.2f%%\n",coin->symbol,jsonstr,retjsonstr,good,bad,100.*(double)good/(good+bad)); - else good++; - free(retjsonstr); - return(1); // indicates was active - }*/ - return(0); -} - -char *pangea_parser(struct iguana_agent *agent,struct iguana_info *coin,char *method,cJSON *json) -{ - return(clonestr("{\"error\":\"pangea API is not yet\"}")); -} - -char *InstantDEX_parser(struct iguana_agent *agent,struct iguana_info *coin,char *method,cJSON *json) -{ - return(clonestr("{\"error\":\"InstantDEX API is not yet\"}")); -} - -char *jumblr_parser(struct iguana_agent *agent,struct iguana_info *coin,char *method,cJSON *json) -{ - return(clonestr("{\"error\":\"jumblr API is not yet\"}")); -} +#include "SuperNET.h" struct iguana_txid *iguana_blocktx(struct iguana_info *coin,struct iguana_txid *tx,struct iguana_block *block,int32_t i) { @@ -441,9 +388,9 @@ char *iguana_jsoncheck(char *retstr,int32_t freeflag) return(0); } -char *ramchain_parser(struct iguana_agent *agent,struct iguana_info *coin,char *method,cJSON *json) +char *ramchain_parser(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr) { - char *symbol,*str,*retstr; int32_t height; cJSON *argjson,*obj; + char *symbol,*str,*retstr; int32_t height; cJSON *argjson,*obj; struct iguana_info *coin = 0; /*{"agent":"ramchain","method":"block","coin":"BTCD","hash":""} {"agent":"ramchain","method":"block","coin":"BTCD","height":345600} {"agent":"ramchain","method":"tx","coin":"BTCD","txid":""} @@ -506,8 +453,8 @@ char *ramchain_parser(struct iguana_agent *agent,struct iguana_info *coin,char * return(ramchain_coinparser(coin,method,json)); } -/* -#define RPCARGS struct iguana_info *coin,struct iguana_wallet *wallet,cJSON *params[],int32_t n,char *origstr,char *remoteaddr + +#define RPCARGS struct supernet_info *myinfo,struct iguana_info *coin,cJSON *params[],int32_t n,cJSON *json,char *remoteaddr // MAP bitcoin RPC to SuperNET JSONstr // MAP REST to SuperNET JSONstr @@ -524,15 +471,17 @@ static char *stop(RPCARGS) static char *sendalert(RPCARGS) { + return(0); } static char *SuperNET(RPCARGS) { - return(iguana_JSON(coin,origstr,remoteaddr)); + return(SuperNET_JSON(myinfo,json,remoteaddr)); } static char *getrawmempool(RPCARGS) { + return(0); } // peers @@ -558,10 +507,11 @@ static char *getpeerinfo(RPCARGS) static char *addnode(RPCARGS) { // addnode version 0.8 Attempts add or remove from the addnode list or try a connection to once. N + return(0); } // address and pubkeys -int32_t iguana_waddresscalc(struct iguana_info *coin,struct iguana_waddress *addr,bits256 privkey) +struct iguana_waddress *iguana_waddresscalc(struct iguana_info *coin,struct iguana_waddress *addr,bits256 privkey) { memset(addr,0,sizeof(*addr)); addr->privkey = privkey; @@ -569,9 +519,15 @@ int32_t iguana_waddresscalc(struct iguana_info *coin,struct iguana_waddress *add { addr->wiptype = coin->chain->wipval; addr->type = coin->chain->pubval; - return(0); + return(addr); } - return(-1); + return(0); +} + +int32_t iguana_addressvalidate(struct iguana_info *coin,char *coinaddr) +{ + // verify checksum bytes + return(0); } static char *validateretstr(struct iguana_info *coin,char *coinaddr) @@ -611,6 +567,7 @@ static char *validatepubkey(RPCARGS) static char *createmultisig(RPCARGS) { + return(0); } // blockchain @@ -637,43 +594,53 @@ static char *getblockcount(RPCARGS) static char *getblock(RPCARGS) { + return(0); } static char *getblockhash(RPCARGS) { + return(0); } static char *gettransaction(RPCARGS) { + return(0); } static char *listtransactions(RPCARGS) { + return(0); } static char *getreceivedbyaddress(RPCARGS) { + return(0); } static char *listreceivedbyaddress(RPCARGS) { + return(0); } static char *listsinceblock(RPCARGS) { + return(0); } // waccount and waddress funcs static char *getreceivedbyaccount(RPCARGS) { + return(0); } static char *listreceivedbyaccount(RPCARGS) { + return(0); } static char *addmultisigaddress(RPCARGS) { + return(0); } static char *getnewaddress(RPCARGS) @@ -712,13 +679,14 @@ static char *makekeypair(RPCARGS) static char *getaccountaddress(RPCARGS) { - struct iguana_waddress *waddr,addr; char str[67]; char *account,*coinaddr; cJSON *retjson; - if ( params[0] != 0 && (coinaddr= jstr(params[0],0)) != 0 ) + struct iguana_waccount *wacct; struct iguana_waddress *waddr=0,addr; char str[67]; char *account; cJSON *retjson; + if ( params[0] != 0 && (account= jstr(params[0],0)) != 0 ) { - if ( (waddr= iguana_waccountfind(coin,account)) == 0 ) + if ( (wacct= iguana_waccountfind(coin,account)) == 0 ) { if ( (waddr= iguana_waddresscalc(coin,&addr,rand256(1))) == 0 ) return(clonestr("{\"error\":\"cant generate address\"}")); + iguana_waccountswitch(coin,account,0,-1,addr.coinaddr); } retjson = cJSON_CreateObject(); jaddstr(retjson,"result",waddr->coinaddr); @@ -736,17 +704,17 @@ static char *getaccountaddress(RPCARGS) static char *setaccount(RPCARGS) { - struct iguana_waddress *waddr,addr; char *account,*coinaddr; + struct iguana_waccount *wacct; struct iguana_waddress *waddr=0,addr; int32_t ind=-1; char *account,*coinaddr; if ( params[0] != 0 && (coinaddr= jstr(params[0],0)) != 0 && params[1] != 0 && (account= jstr(params[1],0)) != 0 ) { if ( iguana_addressvalidate(coin,coinaddr) < 0 ) return(clonestr("{\"error\":\"invalid coin address\"}")); - if ( (waddr= iguana_waddressfind(coin,coinaddr)) == 0 ) + if ( (wacct= iguana_waddressfind(coin,&ind,coinaddr)) == 0 ) { if ( (waddr= iguana_waddresscalc(coin,&addr,rand256(1))) == 0 ) return(clonestr("{\"error\":\"cant generate address\"}")); } - iguana_waccountswitch(coin,waddr,coinaddr); + iguana_waccountswitch(coin,account,wacct,ind,coinaddr); return(clonestr("{\"result\":\"account set\"}")); } return(clonestr("{\"error\":\"need address and account\"}")); @@ -754,15 +722,15 @@ static char *setaccount(RPCARGS) static char *getaccount(RPCARGS) { - struct iguana_waddress *waddr,addr; char *account,*coinaddr; cJSON *retjson; + struct iguana_waccount *wacct; char *coinaddr; cJSON *retjson; int32_t ind; if ( params[0] != 0 && (coinaddr= jstr(params[0],0)) != 0 ) { if ( iguana_addressvalidate(coin,coinaddr) < 0 ) return(clonestr("{\"error\":\"invalid coin address\"}")); - if ( (waddr= iguana_waccountfind(coin,account)) == 0 ) + if ( (wacct= iguana_waddressfind(coin,&ind,coinaddr)) == 0 ) return(clonestr("{\"result\":\"no account for address\"}")); retjson = cJSON_CreateObject(); - jaddstr(retjson,"result",waddr->account); + jaddstr(retjson,"result",wacct->account); return(jprint(retjson,1)); } return(clonestr("{\"error\":\"need address\"}")); @@ -770,11 +738,11 @@ static char *getaccount(RPCARGS) static char *getaddressesbyaccount(RPCARGS) { - struct iguana_waccount *subset; char *account; cJSON *retjson,*array; + struct iguana_waccount *subset; struct iguana_waddress *waddr,*tmp; char *account; cJSON *retjson,*array; retjson = cJSON_CreateObject(); + array = cJSON_CreateArray(); if ( params[0] != 0 && (account= jstr(params[0],0)) != 0 ) { - array = cJSON_CreateArray(); if ( (subset= iguana_waccountfind(coin,account)) != 0 ) { HASH_ITER(hh,subset->waddrs,waddr,tmp) @@ -789,91 +757,116 @@ static char *getaddressesbyaccount(RPCARGS) static char *listaddressgroupings(RPCARGS) { + return(0); } static char *getbalance(RPCARGS) { + return(0); } // wallet static char *listaccounts(RPCARGS) { + return(0); } static char *dumpprivkey(RPCARGS) { + return(0); } static char *importprivkey(RPCARGS) { + return(0); } static char *dumpwallet(RPCARGS) { + return(0); } static char *importwallet(RPCARGS) { + return(0); } static char *walletpassphrase(RPCARGS) { + return(0); } static char *walletpassphrasechange(RPCARGS) { + return(0); } static char *walletlock(RPCARGS) { + return(0); } static char *encryptwallet(RPCARGS) { + return(0); } static char *checkwallet(RPCARGS) { + return(0); } static char *repairwallet(RPCARGS) { + return(0); +} + +static char *backupwallet(RPCARGS) +{ + return(0); } // messages static char *signmessage(RPCARGS) { + return(0); } static char *verifymessage(RPCARGS) { + return(0); } // unspents static char *listunspent(RPCARGS) { + return(0); } static char *lockunspent(RPCARGS) { + return(0); } static char *listlockunspent(RPCARGS) { + return(0); } static char *gettxout(RPCARGS) { + return(0); } static char *gettxoutsetinfo(RPCARGS) { + return(0); } // payments static char *sendtoaddress(RPCARGS) { - struct iguana_waddress *waddr,addr; char *account,*coinaddr,*comment=0,*comment2=0; double amount = -1.; + char *coinaddr,*comment=0,*comment2=0; double amount = -1.; //sendtoaddress [comment] [comment-to] is a real and is rounded to 8 decimal places. Returns the transaction ID if successful. Y if ( params[0] != 0 && (coinaddr= jstr(params[0],0)) != 0 && params[1] != 0 && is_cJSON_Number(params[1]) != 0 ) { @@ -882,60 +875,74 @@ static char *sendtoaddress(RPCARGS) amount = jdouble(params[1],0); comment = jstr(params[2],0); comment2 = jstr(params[3],0); - printf("need to generate send %.8f to %s [%s] [%s]\n",dstr(amount),coinaddr,comment!=0?comment:"",comment2!=0comment2:""); + printf("need to generate send %.8f to %s [%s] [%s]\n",dstr(amount),coinaddr,comment!=0?comment:"",comment2!=0?comment2:""); } return(clonestr("{\"error\":\"need address and amount\"}")); } -static char *move(RPCARGS) +static char *movecmd(RPCARGS) { + return(0); } static char *sendfrom(RPCARGS) { + return(0); } static char *sendmany(RPCARGS) { + return(0); } static char *settxfee(RPCARGS) { + return(0); } // rawtransaction static char *getrawtransaction(RPCARGS) { + return(0); } static char *createrawtransaction(RPCARGS) { + return(0); } static char *decoderawtransaction(RPCARGS) { + return(0); } static char *decodescript(RPCARGS) { + return(0); } static char *signrawtransaction(RPCARGS) { + return(0); } static char *sendrawtransaction(RPCARGS) { + return(0); } static char *resendtx(RPCARGS) { + return(0); } static char *getrawchangeaddress(RPCARGS) { + return(0); } +#define true 1 +#define false 0 struct RPC_info { char *name; char *(*rpcfunc)(RPCARGS); int32_t flag0,flag1; } RPCcalls[] = { { "help", &help, true, true }, @@ -996,13 +1003,14 @@ struct RPC_info { char *name; char *(*rpcfunc)(RPCARGS); int32_t flag0,flag1; } { "makekeypair", &makekeypair, false, true}, { "sendalert", &sendalert, false, false}, // - { "addnode", &addnode, false, false}, + { "createmultisig", &createmultisig, false, false}, + { "addnode", &addnode, false, false}, { "getrawmempool", &getrawmempool, false, false}, { "getrawchangeaddress", &getrawchangeaddress, false, false}, { "listlockunspent", &listlockunspent, false, false}, { "lockunspent", &lockunspent, false, false}, { "gettxout", &gettxout, false, false}, - { "gettxoutsetinfo", &gettxoutsetinfo, false, false}] + { "gettxoutsetinfo", &gettxoutsetinfo, false, false} #ifdef PEGGY //{ "peggytx", &peggytx, true, false }, //{ "peggypayments", &peggypayments, true, false }, @@ -1024,38 +1032,38 @@ struct RPC_info { char *name; char *(*rpcfunc)(RPCARGS); int32_t flag0,flag1; } // { "reservebalance", &reservebalance, false, true}, }; -char *iguana_bitcoinrpc(struct iguana_info *coin,struct iguana_wallet *wallet,char *method,cJSON *params,int32_t n,char *origstr,char *remoteaddr) +char *iguana_bitcoinrpc(struct supernet_info *myinfo,struct iguana_info *coin,char *method,cJSON *params[16],int32_t n,cJSON *json,char *remoteaddr) { int32_t i; for (i=0; i 1 ) for (i=1; isymbol,waddr->account,waddr->coinaddr,coinaddr); return(0); } -struct iguana_waddress *iguana_waddressfind(struct iguana_info *coin,char *coinaddr) +struct iguana_waccount *iguana_waddressfind(struct iguana_info *coin,int32_t *indp,char *coinaddr) { return(0); } diff --git a/iguana/main.c b/iguana/main.c index 3cb3240ad..1183d4fa8 100644 --- a/iguana/main.c +++ b/iguana/main.c @@ -22,6 +22,7 @@ #include "../pnacl_main.h" #include "iguana777.h" +#include "SuperNET.h" // ALL globals must be here! struct iguana_info *Coins[IGUANA_MAXCOINS]; @@ -29,7 +30,7 @@ int32_t USE_JAY,FIRST_EXTERNAL,IGUANA_disableNXT,Debuglevel; uint32_t prices777_NXTBLOCK,MAX_DEPTH = 100; char NXTAPIURL[256],IGUANA_NXTADDR[256],IGUANA_NXTACCTSECRET[256]; uint64_t IGUANA_MY64BITS; -queue_t helperQ; +queue_t helperQ,jsonQ,finishedQ; static int32_t initflag; #ifdef __linux__ int32_t IGUANA_NUMHELPERS = 4; @@ -37,626 +38,284 @@ int32_t IGUANA_NUMHELPERS = 4; int32_t IGUANA_NUMHELPERS = 1; #endif -#ifdef oldway -void *iguana(void *arg) +char *hash_parser(struct supernet_info *myinfo,char *hashname,cJSON *json,char *remoteaddr) { - if ( arg == 0 ) -#ifdef __linux__ - arg = 0;//"{\"coins\":[{\"name\":\"BTCD\",\"maxpeers\":128,\"initialheight\":400000,\"services\":1,\"peers\":[\"127.0.0.1\"]}]}"; - //arg = "{\"coins\":[{\"name\":\"BTCD\",\"services\":1,\"maxrecvcache\":64,\"peers\":[\"127.0.0.1\",\"107.170.13.184\",\"108.58.252.82\",\"207.182.151.130\",\"70.106.255.189\"]}]}"; -#else - arg = 0;//"{\"coins\":[{\"name\":\"BTCD\",\"maxpeers\":128,\"initialheight\":400000,\"services\":1,\"peers\":[\"127.0.0.1\"]}]}"; -#endif - PostMessage("iguana start.(%s)\n",(char *)arg); - while ( initflag == 0 ) - sleep(1); - iguana_main(arg); - return(0); -} - -#ifdef __PNACL -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "includes/ppapi/c/ppb.h" -#include "includes/ppapi/c/ppb_var.h" -#include "includes/ppapi/c/ppb_instance.h" -#include "includes/ppapi/c/ppb_messaging.h" -#include "includes/ppapi/c/ppb_var_array.h" -#include "includes/ppapi/c/ppb_var_dictionary.h" -#include "includes/ppapi/c/pp_errors.h" -#include "includes/ppapi/c/ppp_messaging.h" -#include "includes/ppapi/c/ppp_instance.h" -typedef int (*PSMainFunc_t)(int argc, char *argv[]); - -#if defined(WIN32) -#define va_copy(d, s) ((d) = (s)) -#endif - -#ifndef __PNACL -int32_t PSGetInstanceId() -{ - return(4); -} -#endif - -typedef int (*HandleFunc)(struct PP_Var params,struct PP_Var* out_var,const char** error); -typedef struct { const char* name; HandleFunc function; } FuncNameMapping; -static PP_Instance g_instance = 0; -static PPB_GetInterface g_get_browser_interface = NULL; -static PPB_Messaging* g_ppb_messaging = NULL; -PPB_Var* g_ppb_var = NULL; -PPB_VarArray* g_ppb_var_array = NULL; -PPB_VarDictionary* g_ppb_var_dictionary = NULL; -int Handle_iguana(struct PP_Var params,struct PP_Var *output,const char **out_error); -static FuncNameMapping g_function_map[] = { { "iguana", Handle_iguana }, { NULL, NULL } }; -struct PP_Var CStrToVar(const char* str) { return g_ppb_var->VarFromUtf8(str, (int32_t)strlen(str)); } - -char *VprintfToNewString(const char* format, va_list args) -{ - va_list args_copy; int length; char *buffer; int result; - va_copy(args_copy, args); - length = vsnprintf(NULL, 0, format, args); - buffer = (char*)malloc(length + 1); // +1 for NULL-terminator. - result = vsnprintf(&buffer[0], length + 1, format, args_copy); - if ( result != length ) + int32_t i,len,iter,n; uint8_t databuf[512]; + char hexstr[1025],*password,*name,*msg; + typedef void (*hashfunc)(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len); + typedef char *(*hmacfunc)(char *dest,char *key,int32_t key_size,char *message); + struct hashfunc_entry { char *name; hashfunc hashfunc; }; + struct hmacfunc_entry { char *name; hmacfunc hmacfunc; }; + struct hashfunc_entry hashes[] = { {"NXT",calc_NXTaddr}, {"curve25519",calc_curve25519_str }, {"base64_encode",calc_base64_encodestr}, {"base64_decode",calc_base64_decodestr}, {"crc32",calc_crc32str}, {"rmd160_sha256",rmd160ofsha256}, {"sha256_sha256",sha256_sha256}, {"sha256",vcalc_sha256}, {"sha512",calc_sha512}, {"sha384",calc_sha384}, {"sha224",calc_sha224}, {"rmd160",calc_rmd160}, {"rmd256",calc_rmd256}, {"rmd320",calc_rmd320}, {"rmd128",calc_rmd128}, {"sha1",calc_sha1}, {"md5",calc_md5str}, {"tiger",calc_tiger}, {"whirlpool",calc_whirlpool} }; + struct hmacfunc_entry hmacs[] = { {"hmac_sha256",hmac_sha256_str}, {"hmac_sha512",hmac_sha512_str}, {"hmac_sha384",hmac_sha384_str}, {"hmac_sha224",hmac_sha224_str}, {"hmac_rmd160",hmac_rmd160_str}, {"hmac_rmd256",hmac_rmd256_str}, {"hmac_rmd320",hmac_rmd320_str}, {"hmac_rmd128",hmac_rmd128_str}, {"hmac_sha1",hmac_sha1_str}, {"hmac_md5",hmac_md5_str}, {"hmac_tiger",hmac_tiger_str}, {"hmac_whirlpool",hmac_whirlpool_str} }; + if ( (msg= jstr(json,"message")) == 0 ) + return(clonestr("{\"error\":\"no message to hash\"}")); + password = jstr(json,"password"); + n = (int32_t)sizeof(hashes)/sizeof(*hashes); + printf("msg.(%s) password.(%s)\n",msg,password!=0?password:""); + for (iter=0; iter<2; iter++) { - assert(0); - return NULL; + for (i=0; iVarFromUtf8(string, (int32_t)strlen(string)); - free(string); - return var; + return(clonestr("{\"error\":\"jumblr API is not yet\"}")); } -static const char *VarToCStr(struct PP_Var var) +char *pangea_parser(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr) { - uint32_t length; char *new_str; const char *str = g_ppb_var->VarToUtf8(var, &length); - if ( str == NULL ) - return NULL; - new_str = (char*)malloc(length + 1); - memcpy(new_str, str, length); // str is NOT NULL-terminated. Copy using memcpy. - new_str[length] = 0; - return new_str; + return(clonestr("{\"error\":\"jumblr API is not yet\"}")); } -struct PP_Var GetDictVar(struct PP_Var dict, const char* key) +char *SuperNET_jsonstr(struct supernet_info *myinfo,char *jsonstr,char *remoteaddr) { - struct PP_Var key_var = CStrToVar(key); - struct PP_Var value = g_ppb_var_dictionary->Get(dict, key_var); - g_ppb_var->Release(key_var); - return value; + cJSON *json; char *agent,*method; + if ( (json= cJSON_Parse(jsonstr)) != 0 ) + { + if ( (agent= jstr(json,"agent")) != 0 && (method= jstr(json,"method")) != 0 ) + { + if ( strcmp(agent,"iguana") == 0 ) + return(iguana_parser(myinfo,method,json,remoteaddr)); + else if ( strcmp(agent,"ramchain") == 0 ) + return(ramchain_parser(myinfo,method,json,remoteaddr)); + else if ( strcmp(agent,"InstantDEX") == 0 ) + return(InstantDEX_parser(myinfo,method,json,remoteaddr)); + else if ( strcmp(agent,"pangea") == 0 ) + return(pangea_parser(myinfo,method,json,remoteaddr)); + else if ( strcmp(agent,"jumblr") == 0 ) + return(jumblr_parser(myinfo,method,json,remoteaddr)); + else if ( strcmp(agent,"hash") == 0 ) + return(hash_parser(myinfo,method,json,remoteaddr)); + } + return(clonestr("{\"error\":\"need both agent and method\"}")); + } + return(clonestr("{\"error\":\"couldnt parse SuperNET_JSON\"}")); } -void PostMessage(const char* format, ...) -{ - va_list args; - va_start(args, format); -#ifdef __PNACL - struct PP_Var var; - var = VprintfToVar(format, args); - g_ppb_messaging->PostMessage(g_instance, var); - g_ppb_var->Release(var); -#else - printf(format,args); -#endif - va_end(args); -} +struct iguana_jsonitem { struct queueitem DL; struct supernet_info *myinfo; uint32_t fallback,expired,allocsize; char **retjsonstrp; char remoteaddr[64]; char jsonstr[]; }; -/** - * Given a message from JavaScript, parse it for functions and parameters. - * - * The format of the message is: - * { - * "cmd": , - * "args": [, , ...] - * } - * - * @param[in] message The message to parse. - * @param[out] out_function The function name. - * @param[out] out_params A PP_Var array. - * @return 0 if successful, otherwise 1. - */ -static int ParseMessage(struct PP_Var message,const char **out_function,struct PP_Var *out_params) +int32_t iguana_jsonQ() { - if ( message.type != PP_VARTYPE_DICTIONARY ) - return(1); - struct PP_Var cmd_value = GetDictVar(message, "cmd"); - *out_function = VarToCStr(cmd_value); - g_ppb_var->Release(cmd_value); - *out_params = GetDictVar(message, "args"); - PostMessage("Parse.(%s) cmd.(%s)\n",*out_function,VarToCStr(*out_params)); - if ( cmd_value.type != PP_VARTYPE_STRING ) - return(1); - if ( out_params->type != PP_VARTYPE_ARRAY ) + struct iguana_jsonitem *ptr; + if ( (ptr= queue_dequeue(&finishedQ,0)) != 0 ) + { + if ( ptr->expired != 0 ) + { + *ptr->retjsonstrp = clonestr("{\"error\":\"request timeout\"}"); + printf("garbage collection: expired.(%s)\n",ptr->jsonstr); + myfree(ptr,ptr->allocsize); + } else queue_enqueue("finishedQ",&finishedQ,&ptr->DL,0); + } + if ( (ptr= queue_dequeue(&jsonQ,0)) != 0 ) + { + printf("process.(%s)\n",ptr->jsonstr); + if ( (*ptr->retjsonstrp= SuperNET_jsonstr(ptr->myinfo,ptr->jsonstr,ptr->remoteaddr)) == 0 ) + *ptr->retjsonstrp = clonestr("{\"error\":\"null return from iguana_jsonstr\"}"); + printf("finished.(%s)\n",ptr->jsonstr); + queue_enqueue("finishedQ",&finishedQ,&ptr->DL,0); return(1); + } return(0); } -static HandleFunc GetFunctionByName(const char* function_name) +char *iguana_blockingjsonstr(struct supernet_info *myinfo,char *jsonstr,uint64_t tag,int32_t maxmillis,char *remoteaddr) { - FuncNameMapping* map_iter = g_function_map; - for (; map_iter->name; ++map_iter) + struct iguana_jsonitem *ptr; char *retjsonstr = 0; int32_t len,allocsize; double expiration; + expiration = OS_milliseconds() + maxmillis; + //printf("blocking case.(%s)\n",jsonstr); + len = (int32_t)strlen(jsonstr); + allocsize = sizeof(*ptr) + len + 1; + ptr = mycalloc('J',1,allocsize); + ptr->allocsize = allocsize; + ptr->myinfo = myinfo; + ptr->retjsonstrp = &retjsonstr; + safecopy(ptr->remoteaddr,remoteaddr,sizeof(ptr->remoteaddr)); + memcpy(ptr->jsonstr,jsonstr,len+1); + queue_enqueue("jsonQ",&jsonQ,&ptr->DL,0); + while ( OS_milliseconds() < expiration ) { - if (strcmp(map_iter->name, function_name) == 0) - return map_iter->function; + usleep(100); + if ( retjsonstr != 0 ) + { + printf("blocking retjsonstr.(%s)\n",retjsonstr); + queue_delete(&finishedQ,&ptr->DL,allocsize,1); + return(retjsonstr); + } + usleep(1000); } - return NULL; + //printf("(%s) expired\n",jsonstr); + ptr->expired = (uint32_t)time(NULL); + return(clonestr("{\"error\":\"iguana jsonstr expired\"}")); } -/** - * Handle as message from JavaScript on the worker thread. - * - * @param[in] message The message to parse and handle. - */ -static void HandleMessage(struct PP_Var message) +char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr) { - const char *function_name,*error; struct PP_Var params,result_var; - if ( ParseMessage(message, &function_name, ¶ms) != 0 ) + cJSON *retjson; uint64_t tag; uint32_t timeout; char *jsonstr; char *retjsonstr,*retstr = 0; + if ( json != 0 ) { - PostMessage("Error: Unable to parse message"); - return; - } - HandleFunc function = GetFunctionByName(function_name); - if ( function == 0 ) - { - PostMessage("Error: Unknown function \"%s\"", function_name); // Function name wasn't found. - return; - } - // Function name was found, call it. - int result = (*function)(params, &result_var, &error); - if ( result != 0 ) - { - if ( error != NULL ) + /*if ( localaccess != 0 && (method= jstr(json,"method")) != 0 && strcmp(method,"addcoin") == 0 ) { - PostMessage("Error: \"%s\" failed: %s.", function_name, error); - free((void*)error); + if ( (retval= iguana_launchcoin(jstr(json,"coin"),json)) > 0 ) + return(clonestr("{\"result\":\"launched coin\"}")); + else if ( retval == 0 ) return(clonestr("{\"result\":\"coin already launched\"}")); + else return(clonestr("{\"error\":\"error launching coin\"}")); + }*/ + if ( (tag= j64bits(json,"tag")) == 0 ) + OS_randombytes((uint8_t *)&tag,sizeof(tag)); + /*if ( (symbol= jstr(json,"coin")) != 0 ) + { + coin = iguana_coinfind(symbol); + if ( coin != 0 && localaccess != 0 && coin->launched == 0 ) + iguana_launchcoin(symbol,json); + }*/ + if ( (timeout= juint(json,"timeout")) == 0 ) + timeout = IGUANA_JSONTIMEOUT; + jsonstr = jprint(json,0); + if ( (retjsonstr= iguana_blockingjsonstr(myinfo,jsonstr,tag,timeout,remoteaddr)) != 0 ) + { + //printf("retjsonstr.(%s)\n",retjsonstr); + if ( (retjson= cJSON_Parse(retjsonstr)) == 0 ) + retjson = cJSON_Parse("{\"error\":\"cant parse retjsonstr\"}"); + jdelete(retjson,"tag"); + jadd64bits(retjson,"tag",tag); + retstr = jprint(retjson,1); + //printf("retstr.(%s) retjsonstr.%p retjson.%p\n",retstr,retjsonstr,retjson); + free(retjsonstr);//,strlen(retjsonstr)+1); } - else PostMessage("Error: \"%s\" failed.", function_name); - return; - } - // Function returned an output dictionary. Send it to JavaScript. - g_ppb_messaging->PostMessage(g_instance, result_var); - g_ppb_var->Release(result_var); + free(jsonstr); + } else retstr = clonestr("{\"error\":\"cant parse JSON\"}"); + if ( retstr == 0 ) + retstr = clonestr("{\"error\":\"null return\"}"); + return(retstr); } -#define MAX_QUEUE_SIZE 256 - -// A mutex that guards |g_queue|. -static pthread_mutex_t g_queue_mutex; -// A condition variable that is signalled when |g_queue| is not empty. -static pthread_cond_t g_queue_not_empty_cond; - -/** A circular queue of messages from JavaScript to be handled. - * - * If g_queue_start < g_queue_end: - * all elements in the range [g_queue_start, g_queue_end) are valid. - * If g_queue_start > g_queue_end: - * all elements in the ranges [0, g_queue_end) and - * [g_queue_start, MAX_QUEUE_SIZE) are valid. - * If g_queue_start == g_queue_end, and g_queue_size > 0: - * all elements in the g_queue are valid. - * If g_queue_start == g_queue_end, and g_queue_size == 0: - * No elements are valid. */ -static struct PP_Var g_queue[MAX_QUEUE_SIZE]; -static int g_queue_start = 0; // The index of the head of the queue -static int g_queue_end = 0; // The index of the tail of the queue, non-inclusive. -static int g_queue_size = 0; -// NOTE: this function assumes g_queue_mutex lock is held. @return non-zero if the queue is empty -static int IsQueueEmpty() { return g_queue_size == 0; } -// NOTE: this function assumes g_queue_mutex lock is held. @return non-zero if the queue is full -static int IsQueueFull() { return g_queue_size == MAX_QUEUE_SIZE; } - -void InitializeMessageQueue() +char *iguana_JSON(char *jsonstr) { - pthread_mutex_init(&g_queue_mutex, NULL); - pthread_cond_init(&g_queue_not_empty_cond, NULL); -} - -int EnqueueMessage(struct PP_Var message) -{ - pthread_mutex_lock(&g_queue_mutex); - // We shouldn't block the main thread waiting for the queue to not be full, so just drop the message. - if ( IsQueueFull() != 0) + char *retstr=0; cJSON *json; + if ( (json= cJSON_Parse(jsonstr)) != 0 ) { - PostMessage("EnqueueMessage: full Q, drop message\n"); - pthread_mutex_unlock(&g_queue_mutex); - return(0); + retstr = SuperNET_JSON(0,json,"127.0.0.1"); + free_json(json); } - g_queue[g_queue_end] = message; - g_queue_end = (g_queue_end + 1) % MAX_QUEUE_SIZE; - g_queue_size++; - pthread_cond_signal(&g_queue_not_empty_cond); - pthread_mutex_unlock(&g_queue_mutex); - return 1; -} - -struct PP_Var DequeueMessage() -{ - struct PP_Var message; - pthread_mutex_lock(&g_queue_mutex); - while ( IsQueueEmpty() != 0 ) - pthread_cond_wait(&g_queue_not_empty_cond, &g_queue_mutex); - message = g_queue[g_queue_start]; - g_queue_start = (g_queue_start + 1) % MAX_QUEUE_SIZE; - g_queue_size--; - pthread_mutex_unlock(&g_queue_mutex); - return(message); + if ( retstr == 0 ) + retstr = clonestr("{\"error\":\"cant parse jsonstr from pnacl\"}"); + return(retstr); } -/** - * A worker thread that handles messages from JavaScript. - * @param[in] user_data Unused. - * @return unused. - */ -void *HandleMessageThread(void *user_data) +char *SuperNET_p2p(struct iguana_info *coin,int32_t *delaymillisp,char *ipaddr,uint8_t *data,int32_t datalen) { - while ( 1 ) + cJSON *json,*retjson; char *agent,*method,*retstr = 0; + if ( (json= cJSON_Parse((char *)data)) != 0 ) { - struct PP_Var message = DequeueMessage(); - HandleMessage(message); - g_ppb_var->Release(message); + printf("GOT >>>>>>>> SUPERNET P2P.(%s) from.%s\n",(char *)data,coin->symbol); + if ( (agent= jstr(json,"agent")) != 0 && (method= jstr(json,"method")) != 0 ) + { + jaddstr(json,"fromp2p",coin->symbol); + if ( (retstr= SuperNET_JSON(0,json,ipaddr)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( jobj(retjson,"result") != 0 || jobj(retjson,"error") != 0 || jobj(retjson,"method") == 0 ) + { + free(retstr); + retstr = 0; + } + free_json(retjson); + } + } + } + free_json(json); } + return(retstr); } -#include -#include -#include -#include -#include -#undef mount -#undef umount - -static PP_Bool Instance_DidCreate(PP_Instance instance,uint32_t argc,const char* argn[],const char* argv[]) -{ - int nacl_io_init_ppapi(PP_Instance instance, PPB_GetInterface get_interface); - static pthread_t g_handle_message_thread; - static pthread_t iguana_thread; - int64_t allocsize; - g_instance = instance; - // By default, nacl_io mounts / to pass through to the original NaCl - // filesystem (which doesn't do much). Let's remount it to a memfs - // filesystem. - InitializeMessageQueue(); - pthread_create(&g_handle_message_thread, NULL, &HandleMessageThread, NULL); - pthread_create(&iguana_thread,NULL,&iguana,OS_filestr(&allocsize,"iguana.conf")); - nacl_io_init_ppapi(instance,g_get_browser_interface); - umount("/"); - mount("", "/memfs", "memfs", 0, ""); - mount("", /* source */ - "/", /* target */ - "html5fs", /* filesystemtype */ - 0, /* mountflags */ - "type=PERSISTENT,expected_size=10000000000"); /* data */ - mount("", /* source. Use relative URL */ - "/http", /* target */ - "httpfs", /* filesystemtype */ - 0, /* mountflags */ - ""); /* data */ - PostMessage("finished DidCreate\n"); - initflag = 1; - return PP_TRUE; -} - -static void Instance_DidDestroy(PP_Instance instance) { } - -static void Instance_DidChangeView(PP_Instance instance,PP_Resource view_resource) { } - -static void Instance_DidChangeFocus(PP_Instance instance, PP_Bool has_focus) { } - -static PP_Bool Instance_HandleDocumentLoad(PP_Instance instance,PP_Resource url_loader) -{ - // NaCl modules do not need to handle the document load function. - return PP_FALSE; -} - -static void Messaging_HandleMessage(PP_Instance instance,struct PP_Var message) +void iguana_main(void *arg) { - if ( message.type != PP_VARTYPE_DICTIONARY ) // Special case for jspipe input handling - { - PostMessage("Got unexpected message type: %d\n", message.type); - return; - } - struct PP_Var pipe_var = CStrToVar("pipe"); - struct PP_Var pipe_name = g_ppb_var_dictionary->Get(message, pipe_var); - g_ppb_var->Release(pipe_var); - if ( pipe_name.type == PP_VARTYPE_STRING ) // Special case for jspipe input handling + struct supernet_info MYINFO; char helperstr[64],*helperargs,*coinargs=0,*secret,*jsonstr = arg; + int32_t i,len,flag; cJSON *json; uint8_t secretbuf[512]; + mycalloc(0,0,0); + iguana_initQ(&helperQ,"helperQ"); + OS_ensure_directory("confs"); + OS_ensure_directory("DB"); + OS_ensure_directory("tmp"); + memset(&MYINFO,0,sizeof(MYINFO)); + if ( jsonstr != 0 && (json= cJSON_Parse(jsonstr)) != 0 ) { - char file_name[PATH_MAX]; - snprintf(file_name, PATH_MAX, "/dev/%s", VarToCStr(pipe_name)); - int fd = open(file_name, O_RDONLY); - g_ppb_var->Release(pipe_name); - if ( fd < 0 ) + if ( jobj(json,"numhelpers") != 0 ) + IGUANA_NUMHELPERS = juint(json,"numhelpers"); + if ( (secret= jstr(json,"secret")) != 0 ) { - PostMessage("Warning: opening %s failed.", file_name); - goto done; + len = (int32_t)strlen(secret); + if ( is_hexstr(secret,0) != 0 && len == 128 ) + { + len >>= 1; + decode_hex(secretbuf,len,secret); + } else vcalc_sha256(0,secretbuf,(void *)secret,len), len = sizeof(bits256); + memcpy(MYINFO.privkey.bytes,secretbuf,sizeof(MYINFO.privkey)); } - //if ( ioctl(fd, NACL_IOC_HANDLEMESSAGE, &message) != 0 ) - // PostMessage("Error: ioctl on %s failed: %s", file_name, strerror(errno)); - close(fd); - goto done; + if ( jobj(json,"coins") != 0 ) + coinargs = jsonstr; } - g_ppb_var->AddRef(message); - if ( !EnqueueMessage(message) ) + if ( IGUANA_NUMHELPERS == 0 ) + IGUANA_NUMHELPERS = 1; + for (i=0; iRelease(message); - PostMessage("Warning: dropped message because the queue was full."); + sprintf(helperstr,"{\"name\":\"helper.%d\"}",i); + helperargs = clonestr(helperstr); + iguana_launch(iguana_coinadd("BTCD"),"iguana_helper",iguana_helper,helperargs,IGUANA_PERMTHREAD); } -done: - g_ppb_var->Release(pipe_name); -} - -#define GET_INTERFACE(var, type, name) \ -var = (type*)(get_browser(name)); \ -if (!var) { \ -printf("Unable to get interface " name "\n"); \ -return PP_ERROR_FAILED; \ -} - -//PP_EXPORT -int32_t PPP_InitializeModule(PP_Module a_module_id,PPB_GetInterface get_browser) -{ - g_get_browser_interface = get_browser; - GET_INTERFACE(g_ppb_messaging, PPB_Messaging, PPB_MESSAGING_INTERFACE); - GET_INTERFACE(g_ppb_var, PPB_Var, PPB_VAR_INTERFACE); - GET_INTERFACE(g_ppb_var_array, PPB_VarArray, PPB_VAR_ARRAY_INTERFACE); - GET_INTERFACE(g_ppb_var_dictionary, PPB_VarDictionary, PPB_VAR_DICTIONARY_INTERFACE); - return PP_OK; -} - -//PP_EXPORT -const void *PPP_GetInterface(const char* interface_name) -{ - if ( strcmp(interface_name,PPP_INSTANCE_INTERFACE) == 0 ) + iguana_launch(iguana_coinadd("BTCD"),"rpcloop",iguana_rpcloop,iguana_coinadd("BTCD"),IGUANA_PERMTHREAD); + if ( coinargs != 0 ) + iguana_launch(iguana_coinadd("BTCD"),"iguana_coins",iguana_coins,coinargs,IGUANA_PERMTHREAD); + else if ( 1 ) { - static PPP_Instance instance_interface = +#ifdef __APPLE__ + sleep(1); + char *str; + if ( (str= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":128,\"maxpeers\":16,\"coin\":\"BTCD\",\"active\":1}"),0)) != 0 ) { - &Instance_DidCreate, - &Instance_DidDestroy, - &Instance_DidChangeView, - &Instance_DidChangeFocus, - &Instance_HandleDocumentLoad, - }; - return &instance_interface; - } - else if ( strcmp(interface_name, PPP_MESSAGING_INTERFACE) == 0 ) - { - static PPP_Messaging messaging_interface = { &Messaging_HandleMessage }; - return &messaging_interface; - } - return NULL; -} - -//PP_EXPORT -void PPP_ShutdownModule() { } - -#define CHECK_PARAM_COUNT(name, expected) \ -if (GetNumParams(params) != expected) { \ -*out_error = PrintfToNewString(#name " takes " #expected " parameters." \ -" Got %d", GetNumParams(params)); \ -return 1; \ -} - -#define PARAM_STRING(index, var) \ -char* var; \ -uint32_t var##_len; \ -if (GetParamString(params, index, &var, &var##_len, out_error)) { \ -return 1; \ -} - -#define CREATE_RESPONSE(name) CreateResponse(output, #name, out_error) -#define RESPONSE_STRING(var) AppendResponseString(output, var, out_error) -#define RESPONSE_INT(var) AppendResponseInt(output, var, out_error) -#define MAX_PARAMS 4 -static char* g_ParamStrings[MAX_PARAMS]; -/** - * Get the number of parameters. - * @param[in] params The parameter array. - * @return uint32_t The number of parameters in the array. - */ -static uint32_t GetNumParams(struct PP_Var params) { - return g_ppb_var_array->GetLength(params); -} - - -/** - * Create a response PP_Var to send back to JavaScript. - * @param[out] response_var The response PP_Var. - * @param[in] cmd The name of the function that is being executed. - * @param[out] out_error An error message, if this call failed. - */ -static void CreateResponse(struct PP_Var* response_var, - const char* cmd, - const char** out_error) { - PP_Bool result; - - struct PP_Var dict_var = g_ppb_var_dictionary->Create(); - struct PP_Var cmd_key = CStrToVar("cmd"); - struct PP_Var cmd_value = CStrToVar(cmd); - - result = g_ppb_var_dictionary->Set(dict_var, cmd_key, cmd_value); - g_ppb_var->Release(cmd_key); - g_ppb_var->Release(cmd_value); - - if (!result) { - g_ppb_var->Release(dict_var); - *out_error = - PrintfToNewString("Unable to set \"cmd\" key in result dictionary"); - return; - } - - struct PP_Var args_key = CStrToVar("args"); - struct PP_Var args_value = g_ppb_var_array->Create(); - result = g_ppb_var_dictionary->Set(dict_var, args_key, args_value); - g_ppb_var->Release(args_key); - g_ppb_var->Release(args_value); - - if (!result) { - g_ppb_var->Release(dict_var); - *out_error = - PrintfToNewString("Unable to set \"args\" key in result dictionary"); - return; - } - - *response_var = dict_var; -} -/** - * Append a PP_Var to the response dictionary. - * @param[in,out] response_var The response PP_var. - * @param[in] value The value to add to the response args. - * @param[out] out_error An error message, if this call failed. - */ -static void AppendResponseVar(struct PP_Var* response_var, - struct PP_Var value, - const char** out_error) { - struct PP_Var args_value = GetDictVar(*response_var, "args"); - uint32_t args_length = g_ppb_var_array->GetLength(args_value); - PP_Bool result = g_ppb_var_array->Set(args_value, args_length, value); - if (!result) { - // Release the dictionary that was there before. - g_ppb_var->Release(*response_var); - - // Return an error message instead. - *response_var = PP_MakeUndefined(); - *out_error = PrintfToNewString("Unable to append value to result"); - return; - } -} - -/** - * Append a string to the response dictionary. - * @param[in,out] response_var The response PP_var. - * @param[in] value The value to add to the response args. - * @param[out] out_error An error message, if this call failed. - */ -static void AppendResponseString(struct PP_Var* response_var, - const char* value, - const char** out_error) { - struct PP_Var value_var = CStrToVar(value); - AppendResponseVar(response_var, value_var, out_error); - g_ppb_var->Release(value_var); -} - -/** - * Get a parameter at |index| as a string. - * @param[in] params The parameter array. - * @param[in] index The index in |params| to get. - * @param[out] out_string The output string. - * @param[out] out_string_len The length of the output string. - * @param[out] out_error An error message, if this operation failed. - * @return int 0 if successful, otherwise 1. - */ -static int GetParamString(struct PP_Var params, - uint32_t index, - char** out_string, - uint32_t* out_string_len, - const char** out_error) { - if (index >= MAX_PARAMS) { - *out_error = PrintfToNewString("Param index %u >= MAX_PARAMS (%d)", - index, MAX_PARAMS); - return 1; - } - - struct PP_Var value = g_ppb_var_array->Get(params, index); - if (value.type != PP_VARTYPE_STRING) { - *out_error = - PrintfToNewString("Expected param at index %d to be a string not.%d", index,value.type); - return 1; + printf("got.(%s)\n",str); + free(str); + } +#endif } - - uint32_t length; - const char* var_str = g_ppb_var->VarToUtf8(value, &length); - - char* string = (char*)malloc(length + 1); - memcpy(string, var_str, length); - string[length] = 0; - - /* Put the allocated string in g_ParamStrings. This keeps us from leaking - * each parameter string, without having to do manual cleanup in every - * Handle* function below. - */ - free(g_ParamStrings[index]); - g_ParamStrings[index] = string; - - - *out_string = string; - *out_string_len = length; - return 0; -} - -int Handle_iguana(struct PP_Var params,struct PP_Var *output,const char **out_error) -{ - char *iguana_JSON(char *); - char *retstr; - PostMessage("inside Handle_iguana\n"); - CHECK_PARAM_COUNT(iguana, 1); - PARAM_STRING(0,jsonstr); - retstr = iguana_JSON(jsonstr); - CREATE_RESPONSE(iguana); - RESPONSE_STRING(retstr); - return 0; -} - -int example_main() -{ - PostMessage("Started example main.\n"); - //g_pInputEvent = (PPB_InputEvent*) PSGetInterface(PPB_INPUT_EVENT_INTERFACE); - //g_pKeyboardInput = (PPB_KeyboardInputEvent*)PSGetInterface(PPB_KEYBOARD_INPUT_EVENT_INTERFACE); - //g_pMouseInput = (PPB_MouseInputEvent*) PSGetInterface(PPB_MOUSE_INPUT_EVENT_INTERFACE); - //g_pTouchInput = (PPB_TouchInputEvent*) PSGetInterface(PPB_TOUCH_INPUT_EVENT_INTERFACE); - //PSEventSetFilter(PSE_ALL); + if ( arg != 0 ) + SuperNET_JSON(&MYINFO,cJSON_Parse(arg),0); + //init_InstantDEX(); while ( 1 ) { - sleep(777); - /* Process all waiting events without blocking - PSEvent* event; - while ((event = PSEventTryAcquire()) != NULL) { - ProcessEvent(event); - PSEventRelease(event); - }*/ + //flag = 0; + //for (i=0; isymbol[0] != 0 ) + // flag += iguana_processjsonQ(Coins[i]); + flag = iguana_jsonQ(); + if ( flag == 0 ) + usleep(100000); } - return 0; } -PSMainFunc_t PSUserMainGet() -{ - return(example_main); -} -#else -int main(int argc, const char * argv[]) -{ - char *jsonstr; - if ( argc < 2 ) - jsonstr = 0; - else jsonstr = (char *)argv[1]; - initflag = 1; - printf("main\n"); - iguana(jsonstr); - return 0; -} -#endif -#endif diff --git a/iguana/mingw32 b/iguana/mingw32 index ed1e15c4f..ea3a9299b 100755 --- a/iguana/mingw32 +++ b/iguana/mingw32 @@ -1,5 +1,4 @@ -TOOL_DIR := /usr/local/gcc-4.8.0-qt-4.8.4-for-mingw32/win32-gcc/bin -MINGW := i586-mingw32 +include ../mingw.path LIBS := ../win/libcrypto.a ../win/libssl.a ../win/libpthreadGC2.a -lws2_32 -lgdi32 include mingw diff --git a/iguana/mingw64 b/iguana/mingw64 index 3937e43db..15defbe70 100755 --- a/iguana/mingw64 +++ b/iguana/mingw64 @@ -1,6 +1,3 @@ -TOOL_DIR := /usr/local/gcc-4.8.0-qt-4.8.4-for-mingw64/win64-gcc/bin -MINGW := i686-mingw64 +include ../mingw.path64 LIBS := ../win/libcrypto.a ../win/libs/libssl.a ../win/libpthreadGC2_64.a -lws2_64 -lgdi64 - include mingw - diff --git a/includes/ccgi.h b/includes/ccgi.h new file mode 100755 index 000000000..c0f2f99e0 --- /dev/null +++ b/includes/ccgi.h @@ -0,0 +1,64 @@ +/* + * C CGI Library version 1.1 + * + * Copyright 2009 Stephen C. Losen. Distributed under the terms + * of the GNU General Public License (GPL) + */ + +#ifndef _CCGI_H +#define _CCGI_H + +typedef struct CGI_varlist CGI_varlist; + +typedef const char * const CGI_value; + +char *CGI_decode_url(const char *p); + +char *CGI_encode_url(const char *p, const char *keep); + +char *CGI_encode_entity(const char *p); + +char *CGI_encode_base64(const void *p, int len); + +void *CGI_decode_base64(const char *p, int *len); + +char *CGI_encode_hex(const void *p, int len); + +void *CGI_decode_hex(const char *p, int *len); + +char *CGI_encrypt(const void *p, int len, const char *password); + +void *CGI_decrypt(const char *p, int *len, const char *password); + +char *CGI_encode_query(const char *keep, ...); + +char *CGI_encode_varlist(CGI_varlist *v, const char *keep); + +CGI_varlist *CGI_decode_query(CGI_varlist *v, const char *query); + +CGI_varlist *CGI_get_cookie(CGI_varlist *v); + +CGI_varlist *CGI_get_query(CGI_varlist *v); + +CGI_varlist *CGI_get_post(CGI_varlist *v, const char *template); + +CGI_varlist *CGI_get_all(const char *template); + +CGI_varlist *CGI_add_var(CGI_varlist *v, const char *varname, + const char *value); + +void CGI_free_varlist(CGI_varlist *v); + +CGI_value *CGI_lookup_all(CGI_varlist *v, const char *varname); + +const char *CGI_lookup(CGI_varlist *v, const char *varname); + +const char *CGI_first_name(CGI_varlist *v); + +const char *CGI_next_name(CGI_varlist *v); + +void CGI_prefork_server(const char *host, int port, const char *pidfile, + int maxproc, int minidle, int maxidle, int maxreq, + void (*callback)(void)); + +#endif diff --git a/m_unix b/m_unix index 1b6fdf124..c39b4ce45 100755 --- a/m_unix +++ b/m_unix @@ -1,3 +1,3 @@ git pull cd iguana; ./m_unix; cd .. -cd SuperNET; ./m_unix; cd .. +#cd SuperNET; ./m_unix; cd .. diff --git a/mingw.path b/mingw.path new file mode 100644 index 000000000..93e0dc13e --- /dev/null +++ b/mingw.path @@ -0,0 +1,2 @@ +TOOL_DIR := /usr/local/gcc-4.8.0-qt-4.8.4-for-mingw32/win32-gcc/bin +MINGW := i586-mingw32 diff --git a/mingw.path64 b/mingw.path64 new file mode 100644 index 000000000..c66bf9aef --- /dev/null +++ b/mingw.path64 @@ -0,0 +1,2 @@ +TOOL_DIR := /usr/local/gcc-4.8.0-qt-4.8.4-for-mingw64/win64-gcc/bin +MINGW := i686-mingw64 diff --git a/pangea/main.c b/pangea/main.c index 25ae66cf9..951795872 100644 --- a/pangea/main.c +++ b/pangea/main.c @@ -13,6 +13,7 @@ * * ******************************************************************************/ +#ifdef STANDALONE #define CHROMEAPP_NAME pangea #define CHROMEAPP_STR "pangea" #define CHROMEAPP_CONF "pangea.conf" @@ -33,4 +34,11 @@ void pangea_main(void *arg) char *pangea_JSON(char *jsonstr) { return(clonestr("{\"error\":\"pangea is just a stub for now\"}")); -} \ No newline at end of file +} +#else + +char *pangea_parser(struct supernet_info *myinfo,char *method,cJSON *json) +{ + return(clonestr("{\"error\":\"pangea API is not yet\"}")); +} +#endif diff --git a/win/libcurl.a b/win/libcurl.a new file mode 100644 index 000000000..768133dde Binary files /dev/null and b/win/libcurl.a differ diff --git a/win/libcurldll.a b/win/libcurldll.a new file mode 100644 index 000000000..15cf86362 Binary files /dev/null and b/win/libcurldll.a differ