=================================================================== RCS file: /home/cvs/OpenXM/src/kan96xx/plugin/oxcgi.c,v retrieving revision 1.1 retrieving revision 1.8 diff -u -p -r1.1 -r1.8 --- OpenXM/src/kan96xx/plugin/oxcgi.c 2004/09/21 12:52:01 1.1 +++ OpenXM/src/kan96xx/plugin/oxcgi.c 2005/02/27 05:28:06 1.8 @@ -1 +1,625 @@ -/* $OpenXM$ */ +/* $OpenXM: OpenXM/src/kan96xx/plugin/oxcgi.c,v 1.7 2004/11/23 01:37:47 takayama Exp $ */ +#include +#include "datatype.h" +#include "stackm.h" +#include "extern.h" +#include "file2.h" +#include "oxcgi.h" + +static int ppp(char *s,int kstart,int kend, int vstart, int vend); +static int cgiHex(int p); + +static test1(); +static test2(); +static test3(); +static test4(); + +/* main() {KSstart();test4();} */ + +/* + [["URL","http://www.openxm.org"], + ["foo","value1"], <--- the first key value. + ["hoge","value2"] + ] + */ +struct object cgiUrlEncodingToKeyValuePair(char *s) { + int i,n,start; + int kstart,kend; /* start of key, end of key */ + int vstart,vend; /* start of value, end of value */ + int state; + int nOfPairs; + struct object rob; + struct object ob; + int k; + n = strlen(s); start = -1; + for (i=0; i ' ') { start = i; break; } + } + } + for (k=0; k<2; k++) { + /* k==0 path one. Count nOfPairs. */ + /* k==1 path two. generate array. */ + nOfPairs = 0; + i = start; + /* state 0, 1 : key + = + state 2, 3 : value + & + state 5 : after getting & + state 4 : after getting eof + state 6 + */ + state = 0; + while (1) { + switch(state) { + case 0: + kstart = kend = vstart = vend = -1; + if (s[i] <= ' ') { + state=6; break; + } else { + kstart = kend = i; + nOfPairs++; + i++; + state=1; + break; + } + case 1: + if (s[i] <= ' ') { + state=4; break; + }else if (s[i] == '=') { + state=2; i++; break; + }else { + kend = i; i++; break; + } + case 2: + vstart = vend = -1; + if (s[i] <= ' ') { + state=4; break; + }else if (s[i] == '&') { + state=5; break; + }else { + state=3; vstart=vend=i; i++; break; + } + case 3: + if (s[i] <= ' ') { + state=4; break; + }else if (s[i] == '&') { + state=5; break; + }else{ + vend=i; i++; break; + } + case 4: + if (k == 1) { + ob = newObjectArray(2); + putoa(ob,0,urlEncodedStringToObj(s,kstart,kend,0)); + putoa(ob,1,urlEncodedStringToObj(s,vstart,vend,0)); + putoa(rob,nOfPairs,ob); + } + state = -1; break; + case 5: + if (k == 1) { + ob = newObjectArray(2); + putoa(ob,0,urlEncodedStringToObj(s,kstart,kend,0)); + putoa(ob,1,urlEncodedStringToObj(s,vstart,vend,0)); + putoa(rob,nOfPairs,ob); + } + i++; state = 0; break; + case 6: state = -1; break; + default: break; + } + if (state < 0) break; + /* + if ((state == 4) || (state == 5)) { + ppp(s,kstart,kend,vstart,vend); + } + */ + } + if (k == 0) { + char *stmp; int ii; + rob = newObjectArray(nOfPairs+1); + ob = newObjectArray(2); + putoa(ob,0,KpoString("URL")); + stmp = sGC_malloc(start+2); + if (stmp == NULL) errorKan1("%s\n","No more memory."); + stmp[0] = 0; + for (ii=0; ii + +*/ +static int isUrlEncoding3(char s) { + if ((s == '.') || (s == '-') || (s == '_')) return(0); + if ((s >= 'A') && (s <= 'Z')) return(0); + if ((s >= 'a') && (s <= 'z')) return(0); + if ((s >= '0') && (s <= '9')) return(0); + if (s == ' ') return(0); + return(1); +} + +char *byteArrayToUrlEncoding(unsigned char *s,int size) { + int n,i,j; + char *r; + n = 0; + /* get Size */ + for (i=0; i= '0' && p <= '9') return (p-'0'); + if (p >= 'A' && p <= 'F') return (p-'A'+10); + if (p >= 'a' && p <= 'f') return (p-'a'+10); + errorKan1("%s\n","Invalid argument to cgiHex."); +} + +/* for debug */ +static int ppp(char *s,int kstart,int kend, int vstart, int vend) { + int i; + printf("%d %d %d %d\n",kstart,kend,vstart,vend); + if (kstart >= 0) { + printf("key="); + for (i=kstart; i<=kend; i++) putchar(s[i]); + printf("\n"); + } + if (vstart >= 0) { + printf("value="); + for (i=vstart; i<=vend; i++) putchar(s[i]); + printf("\n"); + } +} +static test1() { + char s[1000]; + cgiUrlEncodingToKeyValuePair("http://hoge.hoge?name=1231232&hoge=asdfsdf&foo=asdfasdf"); + cgiUrlEncodingToKeyValuePair("http://hoge.hoge?name=1231232&hoge=&foo=asdfasdf&"); + scanf("%s",s); + cgiUrlEncodingToKeyValuePair(s); +} +static test2() { + char s[1000]; + struct object ob; + ob=cgiUrlEncodingToKeyValuePair("http://hoge.hoge?name=1231232&hoge=asdfsdf&foo=asdfasdf"); + printObject(ob,1,stdout); + ob=cgiUrlEncodingToKeyValuePair("http://hoge.hoge?name=1231232&hoge=&foo=asdfasdf&hoge=A%41+%42%62y%21"); + printObject(ob,1,stdout); + scanf("%s",s); + ob=cgiUrlEncodingToKeyValuePair(s); + printObject(ob,1,stdout); +} + +static test4() { + char s[1000]; + struct object ob; + char *ts; + int size; + ob=cgiUrlEncodingToKeyValuePair("http://hoge.hoge?name=1231232&hoge=&foo=asdfasdf&hoge=A%41+%42%62y%21"); + printObject(ob,1,stdout); + ts = cgiKeyValuePairToUrlEncoding(ob); + printf("result=%s",ts); + + + ts = "Pragma: no-cache\nContent-Length: 2915\nContent-Type: text/html\nConnection: close\n\n
\n

 \n

"; + + ob=cgiHttpToKeyValuePair(ts,strlen(ts)); + printObject(ob,1,stdout); + ts = cgiKeyValuePairToHttp(ob,&size); + printf("result:\n%s",ts); + +} +/* end for debug */ + + +char *cgiKeyValuePairToUrlEncoding(struct object ob) { + FILE2 *fp; + int size; + fp = fp2open(-1); + if (fp == NULL) errorKan1("%s\n","cgiKeyValuePairToUrlEncoding: open error."); + cgiKeyValuePairToUrlEncodingFile2(ob,fp); + return fp2fcloseInString(fp,&size); +} +int checkKeyValuePairFormat(struct object ob,char *msg) { + int i,n; + struct object eob,eob0,eob1; + static char *fmt = NULL; + int size; + char *ss; + size = 1024; + if (fmt == NULL) fmt = sGC_malloc(size); + if (fmt == NULL) errorKan1("%s\n","No more memory."); + for (i=0; i 1 ) fp2fputc('?',fp); + }else{ + fp2fputs(key,fp); fp2fputc('=',fp); + if (eob1.tag == Snull) ; + else if (eob1.tag == Sdollar) { + s = KopString(eob1); + fp2fputs(byteArrayToUrlEncoding((unsigned char *)s, strlen(s)),fp); + }else if (eob1.tag == SbyteArray) { + fp2fputs(byteArrayToUrlEncoding(KopByteArray(eob1),getByteArraySize(eob1)),fp); + }else{ + errorKan1("%s\n","Value is not string nor byte array."); + } + if (i < n-1) fp2fputc('&',fp); + } + } + return(fp2fflush(fp)); +} + +static struct object rStringToObj(char *s,int vstart,int vend,int mode) { + /* mode has not yet been used. */ + struct object rob; + char *sss; int i; + int bytearray; + bytearray=0; + if (vend < vstart) return NullObject; + for (i=vstart; i<= vend; i++) { + if (s[i] == 0) bytearray=1; + } + if (bytearray) { + rob = newByteArrayFromStr(&(s[vstart]),vend-vstart+1); + return(rob); + } + sss = (char *)sGC_malloc(vend-vstart+1); + if (sss == NULL) errorKan1("%s\n","No more memory."); + for (i=vstart; i<=vend; i++) { + sss[i-vstart] = s[i]; sss[i-vstart+1] = 0; + } + rob = KpoString(sss); + return(rob); +} + +/* + [["Content-Body$,"Body"], + ["key1","value1"], + ["key2","value2"], + ... + ] +*/ +struct object cgiHttpToKeyValuePair(char *s,int size) { + int ssize,i,j,k; + int nOfPairs, startbody,state, kstart,kend,vstart, vend,startline,endline; + int nextstart,path; + struct object rob,ob; + ssize = strlen(s); + nOfPairs = 0; startbody = -1; + /* state==0 : readline and set startline and endline; state = 1; + state==1 : if the line is empty, then state=10; + Determine kstart,kend (key) and vstart,vend (value); state=0; + state==10 : Read the body. + */ + for (path=0; path<2; path++) { + if (path == 1) { + rob = newObjectArray(nOfPairs+1); nOfPairs = 0; + } + i = 0; state=0; + while (i ' ') {kstart = j; break;} + } + for (j=kstart; j<=endline; j++) { + if (s[j] == ':') { kend=j-1; break; } + } + for (j=kend+2; j<=endline; j++) { + if (s[j] > ' ') {vstart = j; break; } + } + for (j=vend; j >= vstart; j--) { + if (s[j] > ' ') { vend=j; break;} + else vend = j-1; + } + /* ppp(s,kstart,kend,vstart,vend); */ + nOfPairs++; + if (path == 1) { + ob = newObjectArray(2); + putoa(ob,0,rStringToObj(s,kstart,kend,0)); + putoa(ob,1,rStringToObj(s,vstart,vend,0)); + putoa(rob,nOfPairs,ob); + } + state = 0; + } + }else { + startbody = i; + if (path == 1) { + ob = newObjectArray(2); + putoa(ob,0,KpoString("Content-Body")); + putoa(ob,1,rStringToObj(s,startbody,size-1,0)); + putoa(rob,0,ob); + } + break; + } + } + } + return rob; +} + +char *cgiKeyValuePairToHttp(struct object ob,int *sizep) { + char *s; + FILE2 *fp; + int size; + fp=fp2open(-1); + cgiKeyValuePairToHttpFile2(ob,fp); + s = fp2fcloseInString(fp,sizep); + return(s); +} + +int cgiKeyValuePairToHttpFile2(struct object ob,FILE2 *fp) { + int n,i; + struct object eob,eob0,eob1; + char *key, *s; + checkKeyValuePairFormat(ob,"cgiKeyValuePairToHttpFile2"); + n = getoaSize(ob); + if (n == 0) return(0); + for (i=1; i \n

"; + + ob=cgiHttpToKeyValuePair(s,strlen(s)); + printObject(ob,1,stdout); + + s = "Pragma:\nContent-Length: 2915\r\nContent-Type: text/html\nConnection: close\n\n
\n

 \n

"; + ob=cgiHttpToKeyValuePair(s,strlen(s)); + printObject(ob,1,stdout); + + s = "Pragma\nContent-Length 2915\r\nContent-Type text/html\nConnection: close\n\n
\n

 \n

"; + ob=cgiHttpToKeyValuePair(s,strlen(s)); + printObject(ob,1,stdout); + + { + char *s; + s = "This is a pen.com? !@#0989\n"; + printf("\n%s\n",byteArrayToUrlEncoding((unsigned char *)s,strlen(s))); + } +} + +struct object cgiKeyValuePairToUrlEncodingString(struct object ob) { + char *s; + s = cgiKeyValuePairToUrlEncoding(ob); + if (s == NULL) return NullObject; + return KpoString(s); +} +struct object cgiKeyValuePairToHttpString(struct object ob) { + int size; + char *s; + s = cgiKeyValuePairToHttp(ob,&size); + if (s == NULL) return NullObject; + return KpoString(s); +} + +struct object KooStringToUrlEncoding(struct object sob) { + unsigned char *s; + char *rs; + int n; + if (sob.tag == Sdollar) { + s = (unsigned char *) KopString(sob); + n = strlen((char *)s); + }else if (sob.tag == SbyteArray) { + s = KopByteArray(sob); + n = getByteArraySize(sob); + }else errorKan1("%s\n","KooStringToUrlEncoding: argument must be a string or a bytearray."); + rs = byteArrayToUrlEncoding(s,n); + return KpoString(rs); +} + +struct object KooUrlEncodedStringToObj(struct object sob) { + char *s; + int n; + if (sob.tag == Sdollar) { + s = KopString(sob); + n = strlen((char *)s); + }else if (sob.tag == SbyteArray) { + s = KopByteArray(sob); + n = getByteArraySize(sob); + }else errorKan1("%s\n","KooUrlEncodedStringToObj: argument must be a string."); + return urlEncodedStringToObj(s,0,n-1,0); +} + +static struct object toTokens(char *s,int *sep,int nsep) { + /* s is the input, and sep are the separators. */ + /* -1 means <=' ' are separators */ + int nOfTokens,n,i,done,k,start,sav; + struct object rob; + char *t; + + rob = NullObject; + if (nsep < 1) return rob; + if (sep[0] != -1) { + fprintf(stderr,"cgiToTokens: Not implemeted for this separator.\n"); + return rob; + } + + /* Count the number of tokens */ + n = strlen(s); i = 0; nOfTokens=0; + while (i < n) { + done = 0; + while (s[i] <= ' ') { + i++; if (i >= n) { done=1; break;} + } + if (done==1) break; + nOfTokens++; + while (s[i] > ' ') { + i++; if (i >= n) { done=1; break; } + } + if (done == 1) break; + } + + rob = newObjectArray(nOfTokens); + n = strlen(s); i = 0; k = 0; + while (i < n) { + done = 0; + while (s[i] <= ' ') { + i++; if (i >= n) { done=1; break;} + } + if (done==1) break; + start = i; + while (s[i] > ' ') { + i++; if (i >= n) { done=1; break; } + } + t = (char *) GC_malloc(i-start+1); + if (t == NULL) { fprintf(stderr,"No more memory.\n"); exit(10); } + t[i-start] = 0; + strncpy(t,&(s[start]),i-start); + putoa(rob,k,KpoString(t)); + k++; + if (done == 1) break; + } + + return rob; +} + +struct object KooToTokens(struct object ob,struct object sep) { + char *s; + int n; + int tmp[1]; + tmp[0] = -1; + if (ob.tag == Sdollar) { + s = KopString(ob); + n = strlen((char *)s); + }else errorKan1("%s\n","KooToTokens: the first argument must be a string."); + if (sep.tag == Sarray) { + if (getoaSize(sep) != 0) { + errorKan1("%s\n","This separators have not been implemented."); + } + }else errorKan1("%s\n","KooToTokens: the second argument(separators) must be an array."); + return toTokens(s,tmp,1); +}