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