Annotation of OpenXM/src/kan96xx/plugin/sm1Socket.c, Revision 1.17
1.17 ! takayama 1: /* $OpenXM: OpenXM/src/kan96xx/plugin/sm1Socket.c,v 1.16 2004/02/23 09:03:43 takayama Exp $ */
1.1 maekawa 2: /* msg0s.c */
3: #include <stdio.h>
4: #include <sys/types.h>
5: #include <sys/socket.h>
6: #include <sys/time.h>
7: #include <netinet/in.h>
8: #include <netdb.h>
1.17 ! takayama 9: #include <errno.h>
1.1 maekawa 10:
11:
12: #include "datatype.h"
13: #include "stackm.h"
14: #include "extern.h"
15: #include "sm1Socket.h"
16:
17: extern int Quiet;
1.14 takayama 18: static int Post_debug=0;
1.1 maekawa 19: static void errorMsg1s(char *s);
1.8 takayama 20: static int getContentLength(char *s);
21: static int getReceivedContentLength(char *s);
1.6 takayama 22: #define MAX_LISTEN_QUEUE 3
1.1 maekawa 23:
24: /* [(sm1.socket) (open) [optional integer port, optional string name] ] extension ; */
25: struct object KsocketOpen(struct object obj) {
26: char serverName[1024];
27: int portNumber;
28: struct object rob = NullObject;
29: struct hostent *myhost;
30: struct sockaddr_in me;
31: int s_waiting;
32: int on;
33: int tt;
1.14 takayama 34: extern int Post_debug;
35:
36: if ((char *)getenv("OXWEB_DEBUG") != NULL) {
37: Post_debug = 1;
38: }
1.1 maekawa 39:
40: if (obj.tag != Sarray) {
41: errorMsg1s("KsocketOpen([optional integer,optional string name])");
42: }
43: strcpy(serverName,"localhost");
44: portNumber = 0;
45: if (getoaSize(obj) >= 1) {
46: if ((getoa(obj,0)).tag != Sinteger) {
47: errorMsg1s("KsocketOpen([optional integer,optional string name]), the first argument must be an integer.");
48: }
49: portNumber = KopInteger(getoa(obj,0));
50: }
51: if (getoaSize(obj) >= 2) {
52: if ((getoa(obj,1)).tag != Sdollar) {
53: errorMsg1s("KsocketOpen([optional integer,optional string name]), the second argument must be a string.");
54: }
55: if (strlen(KopString(getoa(obj,1))) > 1023) {
56: errorMsg1s("Too long server name");
57: }
58: strcpy(serverName,KopString(getoa(obj,1)));
59: }
60:
61:
62: /* fprintf(stderr,"Hello from open.\n"); */
63: if ((myhost = gethostbyname(serverName)) == NULL) {
64: errorMsg1s("Bad server name.");
65: }
66: bzero((char *)&me,sizeof(me));
67: me.sin_family = AF_INET;
68: me.sin_port = htons(portNumber);
69: bcopy(myhost->h_addr,
1.3 takayama 70: &me.sin_addr,myhost->h_length);
1.1 maekawa 71:
72: if ((s_waiting = socket(AF_INET,SOCK_STREAM,0)) < 0) {
73: errorMsg1s("Socket allocation is failed.");
74: }
75:
76: on=1; setsockopt(s_waiting,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
77: /* important */
78: if (bind(s_waiting,(struct sockaddr *) &me,sizeof(me)) == -1) {
79: fprintf(stderr,"Bind error. Error no is %d. See /usr/include/sys/errno.h.\n",errno);
80: errorMsg1s("cannot bind");
81: }
82:
83: tt = sizeof(me);
84: if (getsockname(s_waiting,(struct sockaddr *)&me,&tt) < 0) {
85: fprintf(stderr,"getsockname error. Error no is %d. See /usr/include/sys/errno.h.\n",errno);
86: errorMsg1s("cannot getsockname");
87: }
88:
89:
1.6 takayama 90: if (listen(s_waiting,MAX_LISTEN_QUEUE) < 0) {
1.1 maekawa 91: errorMsg1s("Listen failed");
92: }
93: /*
1.3 takayama 94: fprintf(stderr,"Done the initialization. port =%d\n",ntohs(me.sin_port));
95: fprintf(stderr,"socket id = %d",accept(s_waiting,NULL,NULL)); */
1.1 maekawa 96: rob = newObjectArray(2);
97: putoa(rob,0,KpoInteger(s_waiting));
98: putoa(rob,1,KpoInteger(ntohs(me.sin_port)));
99: return(rob);
100:
101: }
102:
103: /* [ integer port, optional string host default localhost]
104: [ integer socketid, integer port ] */
105: struct object KsocketConnect(struct object obj) {
106: char serverName[1024];
107: int portNumber;
108: struct hostent *servhost;
109: struct sockaddr_in server;
110: int socketid;
111: struct object robj = NullObject;
112:
113: if (obj.tag != Sarray) {
114: errorMsg1s("KsocketConnect( [ integer port, optional string host default localhost])");
115: }
116: strcpy(serverName,"localhost");
117: if (getoaSize(obj) < 1) {
118: errorMsg1s("You need to specify port number.\n");
119: }
120: if (getoaSize(obj) >= 1) {
121: if ((getoa(obj,0)).tag != Sinteger) {
122: errorMsg1s("KsocketConnect([integer port,optional string host]), the first argument must be an integer.");
123: }
124: portNumber = KopInteger(getoa(obj,0));
125: }
126: if (getoaSize(obj) >= 2) {
127: if ((getoa(obj,1)).tag != Sdollar) {
128: errorMsg1s("KsocketConnect([integer port,optional string host]), the second argument must be a string.");
129: }
130: if (strlen(KopString(getoa(obj,1))) > 1023) {
131: errorMsg1s("Too long server name");
132: }
133: strcpy(serverName,KopString(getoa(obj,1)));
134: }
135:
136:
137: if ((servhost = gethostbyname(serverName)) == NULL) {
138: errorMsg1s("bad server name.\n");
139: }
140: bzero((char *)&server,sizeof(server));
141: server.sin_family = AF_INET;
142: server.sin_port = htons(portNumber);
143: bcopy(servhost->h_addr,
1.3 takayama 144: (char *)&server.sin_addr,servhost->h_length);
1.1 maekawa 145:
146: if ((socketid = socket(AF_INET,SOCK_STREAM,0)) <0) {
147: errorMsg1s("socket allocation is failed.\n");
148: }
149: if (!Quiet) {
150: fprintf(stderr,"Trying to connect port %d, ip=%x\n",ntohs(server.sin_port),server.sin_addr);
151: }
152: if (connect(socketid,(struct sockaddr *)&server,sizeof(server)) == -1) {
153: errorMsg1s("cannot connect");
154: }
155: /* fprintf(stderr,"connected.\n"); */
156: robj = newObjectArray(2);
157: putoa(robj,0,KpoInteger(socketid));
158: putoa(robj,1,KpoInteger(portNumber));
159: return(robj);
160: }
161:
162: /* [ integer socketid ]
163: [ integer newsocketid ] */
164: struct object KsocketAccept(struct object obj) {
165: struct object obj1;
166: struct object obj2;
167: struct object robj;
168: int s, news;
169:
170: if (obj.tag != Sarray) {
171: errorMsg1s("KsocketAccept([integer socketid])");
172: }
173: if (getoaSize(obj) < 1) {
174: errorMsg1s("KsocketAccept([integer socketid])");
175: }
176: obj1 = getoa(obj,0);
177: if (obj1.tag != Sinteger ) {
178: errorMsg1s("KsocketAccept([integer socketid]), argument must be integer.");
179: }
180: s = KopInteger(obj1);
181: if ((news = accept(s,NULL,NULL)) < 0) {
1.15 takayama 182: fprintf(stderr,"Error in accept. Retrying (KsocketAccept).\n");
183: /* Code added for strange behavior on cygwin. */
184: if ((news = accept(s,NULL,NULL)) < 0) {
185: errorMsg1s("Error in accept. Retry failed.");
186: }
1.1 maekawa 187: }
188: if (close(s) < 0) {
189: errorMsg1s("Error in closing the old socket.");
190: }
191: robj = newObjectArray(1);
192: putoa(robj,0,KpoInteger(news));
193: return(robj);
194: }
195:
1.13 takayama 196: /* [ integer socketid ]
197: [ integer newsocketid ] */
198: /* It does not close the listening socket. You can call it as
199: ls = open.
200: fd=accept2(ls). close(fd).
201: fd=accept2(ls). close(fd).
202: ....
203: */
204: struct object KsocketAccept2(struct object obj) {
205: struct object obj1;
206: struct object obj2;
207: struct object robj;
208: int s, news;
209:
210: if (obj.tag != Sarray) {
211: errorMsg1s("KsocketAccept([integer socketid])");
212: }
213: if (getoaSize(obj) < 1) {
214: errorMsg1s("KsocketAccept([integer socketid])");
215: }
216: obj1 = getoa(obj,0);
217: if (obj1.tag != Sinteger ) {
218: errorMsg1s("KsocketAccept([integer socketid]), argument must be integer.");
219: }
220: s = KopInteger(obj1);
221: if ((news = accept(s,NULL,NULL)) < 0) {
1.15 takayama 222: fprintf(stderr,"Error in accept. Retrying (KsocketAccept2).\n");
223: /* Code added for strange behavior on cygwin. */
224: if ((news = accept(s,NULL,NULL)) < 0) {
225: errorMsg1s("Error in accept. Retry failed.");
226: }
1.13 takayama 227: }
228: if (close(s) < 0) {
229: errorMsg1s("Error in closing the old socket.");
230: }
231: robj = newObjectArray(1);
232: putoa(robj,0,KpoInteger(news));
233: return(robj);
234: }
235:
1.1 maekawa 236: int KsocketSelect0(int fd,int t) {
237: fd_set readfds;
238: struct timeval timeout;
239: FD_ZERO(&readfds);
240: FD_SET(fd,&readfds);
241: timeout.tv_sec = 0;
242: timeout.tv_usec = (long) t;
243: if (t >= 0) {
244: if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,&timeout)<0) {
245: /* It must be fd+1 !, Not fd. */
246: fprintf(stderr,"Select error. Error no is %d. See /usr/include/sys/errno.h.\n",errno);
247: errorMsg1s("KsocketSelect0() : select failed.");
248: return(0);
249: }
250: }else{ /* block */
251: if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,(struct timeval *)NULL)<0) {
252: errorMsg1s("KsocketSelect0() : select failed.");
253: fprintf(stderr,"Select error. Error no is %d. See /usr/include/sys/errno.h.\n",errno);
254: return(0);
255: }
256: }
257: if (FD_ISSET(fd,&readfds)) return(1);
258: else return(0);
259: }
260:
261: /* [ integer socketid optional integer timeout default 0]
262: integer true or false
263: */
264: struct object KsocketSelect(struct object obj) {
265: struct object robj;
266: struct object ob1;
267: struct object ob2;
268: if (obj.tag != Sarray) {
269: errorMsg1s("KsocketSelect([ integer socketid optional integer timeout default 0]");
270: }
271: if (getoaSize(obj) < 1) {
272: errorMsg1s("KsocketSelect([ integer socketid optional integer timeout default 0]");
273: }
274: if (getoaSize(obj) >= 1) {
275: ob1 = getoa(obj,0);
276: ob2 = KpoInteger(0); /* default value */
277: }
278: if (getoaSize(obj) >= 2) {
279: ob2 = getoa(obj,1);
280: }
281: if (ob1.tag != Sinteger) {
282: errorMsg1s("KsocketSelect([ integer socketid optional integer timeout default 0] : the first argument must be an integer.");
283: }
284: if (ob2.tag != Sinteger) {
285: errorMsg1s("KsocketSelect([ integer socketid optional integer timeout default 0] : the second argument must be an integer.");
286: }
287: robj = KpoInteger( KsocketSelect0(KopInteger(ob1),KopInteger(ob2)) );
288: return(robj);
289: }
290:
291: struct object KsocketSelectMulti(struct object obj)
1.3 takayama 292: /* [ [integer socketid1, integer socketid2, ...]
1.1 maekawa 293: optional integer timeout default 0]
294: [ result1, result2, ....]
295: */
296: {
297: struct object robj;
298: struct object ob1;
299: struct object ob2;
300: struct object ob3;
301: int size,i,fd,p,t;
302: fd_set readfds;
303: struct timeval timeout;
304: if (obj.tag != Sarray) {
305: errorMsg1s("KsocketSelectMulti([[sid1, sid2,...] optional integer timeout default 0]");
306: }
307: if (getoaSize(obj) < 1) {
308: errorMsg1s("KsocketSelectMulti([[sid1, sid2,...] optional integer timeout default 0]");
309: }
310: if (getoaSize(obj) >= 1) {
311: ob1 = getoa(obj,0);
312: ob2 = KpoInteger(0); /* default value */
313: }
314: if (getoaSize(obj) >= 2) {
315: ob2 = getoa(obj,1);
316: }
317: if (ob1.tag != Sarray) {
318: errorMsg1s("KsocketSelectMulti([[sid1, sid2, ...] optional integer timeout default 0] : the first argument must be an array.");
319: }
320: if (ob2.tag != Sinteger) {
321: errorMsg1s("KsocketSelectMulti([[sid1, sid2, ...] optional integer timeout default 0] : the second argument must be an integer.");
322: }
323: FD_ZERO(&readfds);
324: timeout.tv_sec = 0; t = KopInteger(ob2);
325: timeout.tv_usec = (long)t;
326:
327: size = getoaSize(ob1);
328: if (size < 1) {
329: errorMsg1s("KsocketSelectMulti: the first argument must be a non-empty array of integers.");
330: }
331: fd = 0;
332:
333: for (i=0; i<size; i++) {
334: ob3 = getoa(ob1,i);
335: if (ob3.tag != Sinteger) {
336: errorMsg1s("KsocketSelectMulti: the first argument must be an array of integers.");
337: }
338: p = KopInteger(ob3);
339: if (p > fd) fd = p;
340: FD_SET(p,&readfds);
341: /* printf("p = %d, fd=%d",p,fd); */
342: }
343:
344: if (t >= 0) {
345: if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,&timeout)<0) {
346: /* It must be fd+1 !, Not fd. */
347: fprintf(stderr,"Select error. Error no is %d. See /usr/include/sys/errno.h.\n",errno);
348: errorMsg1s("KsocketSelectMulti() : select failed.");
349: }
350: }else{ /* block */
351: if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,(struct timeval *)NULL)<0) {
352: fprintf(stderr,"Select error. Error no is %d. See /usr/include/sys/errno.h.\n",errno);
353: errorMsg1s("KsocketSelectMulti() : (block) select failed.");
354: }
355: }
356: robj = newObjectArray(size);
357: for (i=0; i<size; i++) {
358: if (FD_ISSET(KopInteger(getoa(ob1,i)),&readfds)) {
359: putoa(robj,i,KpoInteger(1));
360: }else{
361: putoa(robj,i,KpoInteger(0));
362: }
363: }
364:
365: return(robj);
366: }
367:
368:
369:
370:
371: static char Data00[1024];
372: /* [ integer socketid ]
373: string data
374: */
375: struct object KsocketRead(struct object obj) {
376: struct object ob1;
377: struct object robj = NullObject;
378: static int datasize = 1024;
379: static char *data = Data00;
380: char *tmp;
381: char *r;
382: int n;
383: int socketid;
384: int totalsize;
385:
386: if (obj.tag != Sarray) {
387: errorMsg1s("KsocketRead([integer socketid])");
388: }
389: if (getoaSize(obj) < 1) {
390: errorMsg1s("KsocketRead([integer socketid])");
391: }
392: ob1 = getoa(obj,0);
393: if (ob1.tag != Sinteger) {
394: errorMsg1s("KsocketRead([integer socketid]) : the argument must be integer.");
395: }
396: socketid = KopInteger(ob1);
397:
398: totalsize = 0;
399:
400: while (KsocketSelect0(socketid,0)) {
401: if (datasize - totalsize > 0) {
402: n = read(socketid,data+totalsize,datasize-totalsize);
403: if (n < 0) {
1.3 takayama 404: errorMsg1s("Read error.");
1.1 maekawa 405: }
406: if (n < datasize-totalsize) {
1.3 takayama 407: totalsize += n;
408: break;
1.1 maekawa 409: }else{ totalsize += n; }
410: if (totalsize == 0) {
1.3 takayama 411: errorMsg1s("Select returns 1, but there is no data to read.");
1.1 maekawa 412: }
413: }else { /* increase the datasize */
1.16 takayama 414: tmp = (char *)sGC_malloc(sizeof(char)*2*datasize);
415: /*I should use sGC_malloc_atomic and free after finishing this function?*/
1.1 maekawa 416: if (tmp == (char *)NULL) errorMsg1s("Out of Memory.");
417: bcopy(data,tmp,totalsize);
418: data = tmp;
419: datasize = 2*datasize;
420: }
421: }
422:
1.16 takayama 423: r = (char *)sGC_malloc(sizeof(char)*(totalsize+1));
1.1 maekawa 424: if (r == (char *)NULL) errorMsg1s("Out of Memory.");
425: bcopy(data,r,totalsize);
1.5 takayama 426: r[totalsize] = 0;
427: robj = KpoString(r); /* BUG: it works only for reading string from TCP/IP
428: stream. */
1.1 maekawa 429:
430: return(robj);
431:
432: }
433:
434: /* [ integer socketid, string data ]
435: integer */
436: struct object KsocketWrite(struct object obj) {
437: struct object ob1;
438: struct object ob2;
439: int socketid;
440: int r;
441: if (obj.tag != Sarray) {
442: errorMsg1s("KsocketWrite([integer socketid, string data])");
443: }
444: if (getoaSize(obj) < 2) {
445: errorMsg1s("KsocketWrite([integer socketid, string data])");
446: }
447: ob1 = getoa(obj,0);
448: ob2 = getoa(obj,1);
449: if (ob1.tag != Sinteger) {
450: errorMsg1s("KsocketWrite([integer socketid, string data]) : the first argument must be an integer.");
451: }
452: socketid = KopInteger(ob1);
453: if (ob2.tag != Sdollar) {
454: errorMsg1s("KsocketWrite([integer socketid, string data]) : the second argument must be a string.");
455: }
456: r = write(socketid,KopString(ob2), strlen(KopString(ob2)));
457: return(KpoInteger(r));
458:
459: }
460: struct object KsocketClose(struct object obj) {
461: int socketid;
462: struct object ob1;
463: if (obj.tag != Sarray) {
464: errorMsg1s("KsocketClose([ integer socketid ])");
465: }
466: if (getoaSize(obj) != 1) {
467: errorMsg1s("KsocketClose([ integer socketid ])");
468: }
469: ob1 = getoa(obj,0);
470: if (ob1.tag != Sinteger) {
471: errorMsg1s("KsocketClose([ INTEGER socketid ])");
472: }
473: socketid = KopInteger(ob1);
474: return(KpoInteger(close(socketid)));
475: }
476:
477:
478: static void errorMsg1s(char *s) {
479: fprintf(stderr,"%s\n",s);
480: errorKan1("msg1s.c: %s\n",s);
481: }
482:
483:
484: /**************** new 1997, 11/23 *******************/
485: struct object KsocketReadByte(struct object obj);
486: struct object KsocketWriteByte(struct object obj);
487:
488: struct object KsocketReadByte(struct object obj) {
489: struct object ob1;
490: struct object robj = NullObject;
491: char data[2];
492: char *tmp;
493: char *r;
494: int n;
495: int socketid;
496:
497:
498: if (obj.tag != Sarray) {
499: errorMsg1s("KsocketReadByte([integer socketid])");
500: }
501: if (getoaSize(obj) < 1) {
502: errorMsg1s("KsocketReadByte([integer socketid])");
503: }
504: ob1 = getoa(obj,0);
505: if (ob1.tag != Sinteger) {
506: errorMsg1s("KsocketReadByte([integer socketid]) : the argument must be integer.");
507: }
508: socketid = KopInteger(ob1);
509:
510:
511: n = read(socketid,data,1);
512: if (n < 0) {
513: errorMsg1s("Read error.");
514: robj = KpoInteger(-1);
515: return(robj);
516: }
517: if (n == 0) {
518: errorMsg1s("Read returned without data.");
519: }
520:
521: robj = KpoInteger((int)((unsigned char)data[0]));
522: return(robj);
523:
524: }
525:
526: /* [ integer socketid, int ]
527: integer */
528: struct object KsocketWriteByte(struct object obj) {
529: struct object ob1;
530: struct object ob2;
531: int socketid;
1.4 takayama 532: int r,i,n,kk,r0;
533: #define DATA_SIZE 1024
534: char data[DATA_SIZE];
1.1 maekawa 535: if (obj.tag != Sarray) {
1.4 takayama 536: errorMsg1s("KsocketWriteByte([integer socketid, int | array of int])");
1.1 maekawa 537: }
538: if (getoaSize(obj) < 2) {
1.4 takayama 539: errorMsg1s("KsocketWriteByte([integer socketid, int | array of int])");
1.1 maekawa 540: }
541: ob1 = getoa(obj,0);
542: ob2 = getoa(obj,1);
543: if (ob1.tag != Sinteger) {
1.4 takayama 544: errorMsg1s("KsocketWriteByte([integer socketid, int | array of int]) : the first argument must be an integer.");
1.1 maekawa 545: }
546: socketid = KopInteger(ob1);
1.4 takayama 547: if (ob2.tag != Sinteger && ob2.tag != Sarray) {
548: errorMsg1s("KsocketWriteByte([integer socketid, int | array of int]) : the second argument must be an integer or an array of integers.");
549: }
550: if (ob2.tag == Sinteger) {
551: data[0] = KopInteger(ob2);
552: r = write(socketid,data, 1);
553: }else{
554: n = getoaSize(ob2); kk = 0; r = 0;
555: for (i=0; i<n; i++) {
556: if (getoa(ob2,i).tag != Sinteger)
557: errorMsg1s("KsocketWriteByte([integer socketid, int | array of int]) : elements of the second argument must be integers.");
558: data[kk] = KopInteger(getoa(ob2,i));
559: kk++;
560: if (kk >= DATA_SIZE) {
561: r0 = write(socketid,data,kk);
562: if (r0 != kk) {
563: fprintf(stderr,"Warning: Could not write to the socket.\n");
564: return(KpoInteger(r+r0));
565: }
566: r += r0;
567: kk = 0;
568: }
569: }
570: if (kk > 0) {
571: r0 = write(socketid,data,kk);
572: if (r0 != kk) {
573: fprintf(stderr,"Warning: Could not write to the socket.\n");
574: return(KpoInteger(r+r0));
575: }
576: r += r0;
577: }
1.1 maekawa 578: }
579: return(KpoInteger(r));
580: }
581:
1.7 takayama 582: struct object KsocketReadHTTP(struct object socketObj) {
583: /* Read until two empty line appears. */
1.5 takayama 584: struct object ob;
1.13 takayama 585: struct object ob1;
586: struct object nob;
1.5 takayama 587: char *s;
588: char *sss;
589: char *tmp;
590: int i;
591: int flag;
1.7 takayama 592: int flagmax = 1;
1.5 takayama 593: int datasize;
1.7 takayama 594: int last;
1.8 takayama 595: int contentLength=-1;
1.13 takayama 596: int socketid;
1.14 takayama 597: extern int Post_debug;
1.13 takayama 598: nob = NullObject;
599:
600: if (socketObj.tag != Sarray) {
601: errorMsg1s("KsocketReadHTTP([integer socketid])");
602: }
603: if (getoaSize(socketObj) < 1) {
604: errorMsg1s("KsocketReadHTTP([integer socketid])");
605: }
606: ob1 = getoa(socketObj,0);
607: if (ob1.tag != Sinteger) {
608: errorMsg1s("KsocketReadHTTP([integer socketid]) : the argument must be integer.");
609: }
610: socketid = KopInteger(ob1);
611:
612: if (KsocketSelect0(socketid,-1) != 1) {
613: return(nob);
614: }
1.5 takayama 615: ob = KsocketRead(socketObj);
616: s = KopString(ob);
1.8 takayama 617: if (strncmp(s,"POST",4) == 0) flagmax=2; /* for IE */
1.7 takayama 618: else flagmax=1;
1.5 takayama 619: flag = 0;
620: for (i=strlen(s)-1; i>=0; i--) {
621: if ((s[i] == '\n') && (i==0)) {
1.7 takayama 622: ++flag;
1.5 takayama 623: }else if ((s[i] == '\n') && (s[i-1] == '\n')) {
1.7 takayama 624: ++flag;
1.5 takayama 625: }else if ((s[i] == 0xd) && (s[i+1] == 0xa) && (i == 0)) {
1.7 takayama 626: ++flag;
1.5 takayama 627: }else if ((s[i] == 0xa) && (s[i-1] == 0xd) && (s[i+1] == 0xd) && (s[i+2] == 0xa)) {
1.7 takayama 628: ++flag;
1.5 takayama 629: }
630: }
1.7 takayama 631: if (flag >= flagmax) return ob;
1.5 takayama 632: datasize = strlen(s);
633: sss = s;
1.7 takayama 634: if ((s[strlen(s)-1] == '\n') ||
635: (s[strlen(s)-2] == 0xd) && (s[strlen(s)-1] == 0xa)) {
636: last = 1;
637: }else last = 0;
1.5 takayama 638:
1.7 takayama 639: while (flag < flagmax) {
1.8 takayama 640: contentLength = getContentLength(sss);
641: if (contentLength != -1) {
642: if (contentLength <= getReceivedContentLength(sss)) {
643: break;
644: }
645: }
1.14 takayama 646: if (Post_debug) {
647: fprintf(stderr,"Waiting in socketReadBlock. flagmax(0d,0a)=%d, content-length=%d, received content-length=%d\n",flagmax,contentLength,getReceivedContentLength(sss));
648: }
1.13 takayama 649: if (strlen(s) == 0) {
650: fprintf(stderr,"No data. Perhaps connection is closed by foreign host.\n");
651: return nob;
1.5 takayama 652: }else{
653: /* for debugging. */
1.14 takayama 654: if (Post_debug) {
655: for (i=0; i<strlen(sss); i++) {
656: if ((sss[i] >= ' ') && (sss[i] < 0x7f)) {
657: fprintf(stderr,"%c",sss[i]);
658: }else{
659: fprintf(stderr,"(%3x)",sss[i]);
660: if (sss[i] == 0xa) fprintf(stderr,"\n");
661: }
662:
1.8 takayama 663: }
1.14 takayama 664: fprintf(stderr,"\n");
1.5 takayama 665: }
666: }
1.13 takayama 667:
668: if (KsocketSelect0(socketid,-1) != 1) {
669: return nob;
670: }
1.5 takayama 671: ob = KsocketRead(socketObj);
672: s = KopString(ob);
673: for (i=strlen(s)-1; i>=0; i--) {
1.7 takayama 674: if ((s[i] == '\n') && (i==0) && last) {
675: ++flag;
1.5 takayama 676: }else if ((s[i] == '\n') && (s[i-1] == '\n')) {
1.7 takayama 677: ++flag;
678: }else if ((s[i] == 0xd) && (s[i+1] == 0xa) && (i==0) && last) {
679: ++flag;
1.5 takayama 680: }else if ((s[i] == 0xa) && (s[i-1] == 0xd) && (s[i+1] == 0xd) && (s[i+2] == 0xa)) {
1.7 takayama 681: ++flag;
1.5 takayama 682: }
683: }
684: if (datasize-1 <= strlen(sss)+strlen(s)) {
1.16 takayama 685: tmp = (char *)sGC_malloc(sizeof(char)*2*(datasize+strlen(s))+1);
1.5 takayama 686: if (tmp == (char *)NULL) errorMsg1s("Out of Memory.");
687: strcpy(tmp,sss);
688: strcat(tmp,s);
689: datasize = 2*(datasize+strlen(s));
690: sss = tmp;
691: }else{
692: strcat(sss,s);
693: }
1.7 takayama 694:
695: if ((s[strlen(s)-1] == '\n') ||
696: (s[strlen(s)-2] == 0xd) && (s[strlen(s)-1] == 0xa)) {
697: last = 1;
698: }else last = 0;
699:
1.5 takayama 700: }
701:
702: return KpoString(sss);
703:
704: }
705:
1.1 maekawa 706: struct object Kplugin_sm1Socket(char *key,struct object obj) {
707: struct object robj = NullObject;
708: if (strcmp(key,"open") == 0) {
709: robj = KsocketOpen(obj);
710: }else if (strcmp(key,"connect") == 0) {
711: robj = KsocketConnect(obj);
712: }else if (strcmp(key,"accept") == 0) {
713: robj = KsocketAccept(obj);
1.13 takayama 714: }else if (strcmp(key,"accept2") == 0) {
715: robj = KsocketAccept2(obj);
1.1 maekawa 716: }else if (strcmp(key,"select") == 0) {
717: robj = KsocketSelect(obj);
718: }else if (strcmp(key,"mselect") == 0) {
719: robj = KsocketSelectMulti(obj);
720: }else if (strcmp(key,"read") == 0) {
721: robj = KsocketRead(obj);
1.7 takayama 722: }else if (strcmp(key,"readHTTP") == 0) {
723: robj = KsocketReadHTTP(obj);
1.11 takayama 724: }else if (strcmp(key,"gethostname") == 0) {
725: robj = KsocketGetHostName();
726: }else if (strcmp(key,"write") == 0) {
1.1 maekawa 727: robj = KsocketWrite(obj);
728: }else if (strcmp(key,"read") == 0) {
729: robj = KsocketRead(obj);
730: }else if (strcmp(key,"readByte") == 0) {
731: robj = KsocketReadByte(obj);
732: }else if (strcmp(key,"writeByte") == 0) {
733: robj = KsocketWriteByte(obj);
734: }else if (strcmp(key,"close") == 0) {
735: robj = KsocketClose(obj);
736: }else {
737: errorMsg1s("Unknown tag for sm1.socket");
738: }
739: return(robj);
740: }
741:
742:
1.8 takayama 743: static int getContentLength(char *s) {
744: int n;
1.10 takayama 745: int i,j;
1.8 takayama 746: int len = -1;
1.10 takayama 747: char *s1 = "content-length:";
748: char s0[256];
749: int m;
750: m = strlen(s1);
1.8 takayama 751: n = strlen(s);
752: for (i=0; i<n; i++) {
1.10 takayama 753: strncpy(s0,&(s[i]),m+1);
754: for (j=0; j<m; j++) {
755: if ((s0[j] >= 'A') && (s0[j] <= 'Z')) s0[j] = s0[j]+0x20;
756: }
757: if (strncmp(s0,s1,strlen(s1)) == 0) {
758: sscanf(&(s[i+strlen(s1)]),"%d",&len);
759: break;
760: }
1.8 takayama 761: }
762: return len;
763: }
764: static int getReceivedContentLength(char *s) {
765: int n;
766: int i;
767: int start;
768: start = -1;
769: n = strlen(s);
770: for (i=0; i<n; i++) {
771: if ((s[i] == '\n') && (s[i+1] == '\n')) {
772: start = i+2; break;
773: }else if ((s[i] == 0xd) && (s[i+1] == 0xa) && (s[i+2] == 0xd) && (s[i+3] == 0xa)) {
774: start = i+4;
775: }
776: }
777: if (start == -1) return 0;
778: return (n-start);
779: }
1.1 maekawa 780:
781:
1.11 takayama 782: struct object KsocketGetHostName(void) {
783: char name[1024];
784: char *s;
785: struct object rob = NullObject;
786: if (gethostname(name,1023) != 0) {
787: return rob;
788: }
1.16 takayama 789: s = (char *)sGC_malloc(sizeof(char)*(strlen(name)+2));
1.11 takayama 790: if (s == (char *)NULL) errorMsg1s("Out of Memory.");
791: strcpy(s,name);
792: return(KpoString(s));
793: }
1.1 maekawa 794:
795:
796:
797:
798:
799:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>