Annotation of OpenXM/src/kan96xx/plugin/sm1Socket.c, Revision 1.19
1.19 ! takayama 1: /* $OpenXM: OpenXM/src/kan96xx/plugin/sm1Socket.c,v 1.18 2004/11/23 00:02:55 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) {
1.18 takayama 64: perror("gethostbyname"); errorMsg1s("Bad server name.");
1.1 maekawa 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) {
1.18 takayama 73: perror("socket"); errorMsg1s("Socket allocation is failed.");
1.1 maekawa 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);
1.18 takayama 80: perror("bind"); errorMsg1s("cannot bind");
1.1 maekawa 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);
1.18 takayama 86: perror("getsockname"); errorMsg1s("cannot getsockname");
1.1 maekawa 87: }
88:
89:
1.6 takayama 90: if (listen(s_waiting,MAX_LISTEN_QUEUE) < 0) {
1.18 takayama 91: perror("listen"); errorMsg1s("Listen failed");
1.1 maekawa 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) {
1.18 takayama 138: perror("gethostbyname"); errorMsg1s("bad server name.\n");
1.1 maekawa 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) {
1.18 takayama 147: perror("socket"); errorMsg1s("socket allocation is failed.\n");
1.1 maekawa 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) {
1.18 takayama 153: perror("connect"); errorMsg1s("cannot connect");
1.1 maekawa 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) {
1.19 ! takayama 165: struct object obj1 = OINIT;
! 166: struct object obj2 = OINIT;
! 167: struct object robj = OINIT;
1.1 maekawa 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) {
1.18 takayama 185: perror("accept"); errorMsg1s("Error in accept. Retry failed.");
1.15 takayama 186: }
1.1 maekawa 187: }
188: if (close(s) < 0) {
1.18 takayama 189: perror("close"); errorMsg1s("Error in closing the old socket.");
1.1 maekawa 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) {
1.19 ! takayama 205: struct object obj1 = OINIT;
! 206: struct object obj2 = OINIT;
! 207: struct object robj = OINIT;
1.13 takayama 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) {
1.18 takayama 225: perror("accept"); errorMsg1s("Error in accept. Retry failed.");
1.15 takayama 226: }
1.13 takayama 227: }
228: if (close(s) < 0) {
1.18 takayama 229: perror("close"); errorMsg1s("Error in closing the old socket.");
1.13 takayama 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);
1.18 takayama 247: perror("select"); errorMsg1s("KsocketSelect0() : select failed.");
1.1 maekawa 248: return(0);
249: }
250: }else{ /* block */
251: if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,(struct timeval *)NULL)<0) {
1.18 takayama 252: perror("select"); errorMsg1s("KsocketSelect0() : select failed.");
1.1 maekawa 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) {
1.19 ! takayama 265: struct object robj = OINIT;
! 266: struct object ob1 = OINIT;
! 267: struct object ob2 = OINIT;
1.1 maekawa 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: {
1.19 ! takayama 297: struct object robj = OINIT;
! 298: struct object ob1 = OINIT;
! 299: struct object ob2 = OINIT;
! 300: struct object ob3 = OINIT;
1.1 maekawa 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);
1.18 takayama 348: perror("select"); errorMsg1s("KsocketSelectMulti() : select failed.");
1.1 maekawa 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);
1.18 takayama 353: perror("select"); errorMsg1s("KsocketSelectMulti() : (block) select failed.");
1.1 maekawa 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) {
1.19 ! takayama 376: struct object ob1 = OINIT;
1.1 maekawa 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.18 takayama 404: perror("read");
1.3 takayama 405: errorMsg1s("Read error.");
1.1 maekawa 406: }
407: if (n < datasize-totalsize) {
1.3 takayama 408: totalsize += n;
409: break;
1.1 maekawa 410: }else{ totalsize += n; }
411: if (totalsize == 0) {
1.3 takayama 412: errorMsg1s("Select returns 1, but there is no data to read.");
1.1 maekawa 413: }
414: }else { /* increase the datasize */
1.16 takayama 415: tmp = (char *)sGC_malloc(sizeof(char)*2*datasize);
416: /*I should use sGC_malloc_atomic and free after finishing this function?*/
1.1 maekawa 417: if (tmp == (char *)NULL) errorMsg1s("Out of Memory.");
418: bcopy(data,tmp,totalsize);
419: data = tmp;
420: datasize = 2*datasize;
421: }
422: }
423:
1.16 takayama 424: r = (char *)sGC_malloc(sizeof(char)*(totalsize+1));
1.1 maekawa 425: if (r == (char *)NULL) errorMsg1s("Out of Memory.");
426: bcopy(data,r,totalsize);
1.5 takayama 427: r[totalsize] = 0;
428: robj = KpoString(r); /* BUG: it works only for reading string from TCP/IP
429: stream. */
1.1 maekawa 430:
431: return(robj);
432:
433: }
434:
435: /* [ integer socketid, string data ]
436: integer */
437: struct object KsocketWrite(struct object obj) {
1.19 ! takayama 438: struct object ob1 = OINIT;
! 439: struct object ob2 = OINIT;
1.1 maekawa 440: int socketid;
441: int r;
1.18 takayama 442: int k,k0;
443: char *s;
1.1 maekawa 444: if (obj.tag != Sarray) {
445: errorMsg1s("KsocketWrite([integer socketid, string data])");
446: }
447: if (getoaSize(obj) < 2) {
448: errorMsg1s("KsocketWrite([integer socketid, string data])");
449: }
450: ob1 = getoa(obj,0);
451: ob2 = getoa(obj,1);
452: if (ob1.tag != Sinteger) {
453: errorMsg1s("KsocketWrite([integer socketid, string data]) : the first argument must be an integer.");
454: }
455: socketid = KopInteger(ob1);
456: if (ob2.tag != Sdollar) {
457: errorMsg1s("KsocketWrite([integer socketid, string data]) : the second argument must be a string.");
458: }
1.18 takayama 459: s = KopString(ob2);
460: k0 = k = strlen(s);
461: while (1) {
462: r = write(socketid,s,k);
463: if (r < 0) {
464: perror("write"); errorMsg1s("KsocketWrite: write failed.");
465: }
466: if (r >= k) break;
467: k -= r;
468: s = &(s[r]);
469: }
470: return(KpoInteger(k0));
1.1 maekawa 471:
472: }
473: struct object KsocketClose(struct object obj) {
474: int socketid;
1.19 ! takayama 475: struct object ob1 = OINIT;
1.1 maekawa 476: if (obj.tag != Sarray) {
477: errorMsg1s("KsocketClose([ integer socketid ])");
478: }
479: if (getoaSize(obj) != 1) {
480: errorMsg1s("KsocketClose([ integer socketid ])");
481: }
482: ob1 = getoa(obj,0);
483: if (ob1.tag != Sinteger) {
484: errorMsg1s("KsocketClose([ INTEGER socketid ])");
485: }
486: socketid = KopInteger(ob1);
487: return(KpoInteger(close(socketid)));
488: }
489:
490:
491: static void errorMsg1s(char *s) {
492: fprintf(stderr,"%s\n",s);
493: errorKan1("msg1s.c: %s\n",s);
494: }
495:
496:
497: /**************** new 1997, 11/23 *******************/
498: struct object KsocketReadByte(struct object obj);
499: struct object KsocketWriteByte(struct object obj);
500:
501: struct object KsocketReadByte(struct object obj) {
1.19 ! takayama 502: struct object ob1 = OINIT;
1.1 maekawa 503: struct object robj = NullObject;
504: char data[2];
505: char *tmp;
506: char *r;
507: int n;
508: int socketid;
509:
510:
511: if (obj.tag != Sarray) {
512: errorMsg1s("KsocketReadByte([integer socketid])");
513: }
514: if (getoaSize(obj) < 1) {
515: errorMsg1s("KsocketReadByte([integer socketid])");
516: }
517: ob1 = getoa(obj,0);
518: if (ob1.tag != Sinteger) {
519: errorMsg1s("KsocketReadByte([integer socketid]) : the argument must be integer.");
520: }
521: socketid = KopInteger(ob1);
522:
523:
524: n = read(socketid,data,1);
525: if (n < 0) {
1.18 takayama 526: perror("read");
1.1 maekawa 527: errorMsg1s("Read error.");
528: robj = KpoInteger(-1);
529: return(robj);
530: }
531: if (n == 0) {
532: errorMsg1s("Read returned without data.");
533: }
534:
535: robj = KpoInteger((int)((unsigned char)data[0]));
536: return(robj);
537:
538: }
539:
540: /* [ integer socketid, int ]
541: integer */
542: struct object KsocketWriteByte(struct object obj) {
1.19 ! takayama 543: struct object ob1 = OINIT;
! 544: struct object ob2 = OINIT;
1.1 maekawa 545: int socketid;
1.4 takayama 546: int r,i,n,kk,r0;
547: #define DATA_SIZE 1024
548: char data[DATA_SIZE];
1.1 maekawa 549: if (obj.tag != Sarray) {
1.4 takayama 550: errorMsg1s("KsocketWriteByte([integer socketid, int | array of int])");
1.1 maekawa 551: }
552: if (getoaSize(obj) < 2) {
1.4 takayama 553: errorMsg1s("KsocketWriteByte([integer socketid, int | array of int])");
1.1 maekawa 554: }
555: ob1 = getoa(obj,0);
556: ob2 = getoa(obj,1);
557: if (ob1.tag != Sinteger) {
1.4 takayama 558: errorMsg1s("KsocketWriteByte([integer socketid, int | array of int]) : the first argument must be an integer.");
1.1 maekawa 559: }
560: socketid = KopInteger(ob1);
1.4 takayama 561: if (ob2.tag != Sinteger && ob2.tag != Sarray) {
562: errorMsg1s("KsocketWriteByte([integer socketid, int | array of int]) : the second argument must be an integer or an array of integers.");
563: }
564: if (ob2.tag == Sinteger) {
565: data[0] = KopInteger(ob2);
566: r = write(socketid,data, 1);
1.18 takayama 567: if (r < 0) {
568: perror("write"); errorMsg1s("KsocketWriteByte: write error");
569: }
1.4 takayama 570: }else{
571: n = getoaSize(ob2); kk = 0; r = 0;
572: for (i=0; i<n; i++) {
573: if (getoa(ob2,i).tag != Sinteger)
1.18 takayama 574: errorMsg1s("KsocketWriteByte([integer socketid, int | array of int]) : elements of the second argument must be integers.");
1.4 takayama 575: data[kk] = KopInteger(getoa(ob2,i));
576: kk++;
577: if (kk >= DATA_SIZE) {
1.18 takayama 578: r0 = write(socketid,data,kk);
579: if (r0 < 0) { perror("write"); errorMsg1s("write failed."); }
580: if (r0 != kk) {
581: fprintf(stderr,"Warning: Could not write to the socket.\n");
582: return(KpoInteger(r+r0)); /* bug: we should retry. */
583: }
1.4 takayama 584: r += r0;
1.18 takayama 585: kk = 0;
1.4 takayama 586: }
587: }
588: if (kk > 0) {
589: r0 = write(socketid,data,kk);
1.18 takayama 590: if (r0 < 0) { perror("write"); errorMsg1s("write failed."); }
1.4 takayama 591: if (r0 != kk) {
1.18 takayama 592: fprintf(stderr,"Warning: Could not write to the socket.\n");
593: return(KpoInteger(r+r0));
1.4 takayama 594: }
595: r += r0;
596: }
1.1 maekawa 597: }
598: return(KpoInteger(r));
599: }
600:
1.7 takayama 601: struct object KsocketReadHTTP(struct object socketObj) {
602: /* Read until two empty line appears. */
1.19 ! takayama 603: struct object ob = OINIT;
! 604: struct object ob1 = OINIT;
! 605: struct object nob = OINIT;
1.5 takayama 606: char *s;
607: char *sss;
608: char *tmp;
609: int i;
610: int flag;
1.7 takayama 611: int flagmax = 1;
1.5 takayama 612: int datasize;
1.7 takayama 613: int last;
1.8 takayama 614: int contentLength=-1;
1.13 takayama 615: int socketid;
1.14 takayama 616: extern int Post_debug;
1.13 takayama 617: nob = NullObject;
618:
619: if (socketObj.tag != Sarray) {
620: errorMsg1s("KsocketReadHTTP([integer socketid])");
621: }
622: if (getoaSize(socketObj) < 1) {
623: errorMsg1s("KsocketReadHTTP([integer socketid])");
624: }
625: ob1 = getoa(socketObj,0);
626: if (ob1.tag != Sinteger) {
627: errorMsg1s("KsocketReadHTTP([integer socketid]) : the argument must be integer.");
628: }
629: socketid = KopInteger(ob1);
630:
631: if (KsocketSelect0(socketid,-1) != 1) {
632: return(nob);
633: }
1.5 takayama 634: ob = KsocketRead(socketObj);
635: s = KopString(ob);
1.8 takayama 636: if (strncmp(s,"POST",4) == 0) flagmax=2; /* for IE */
1.7 takayama 637: else flagmax=1;
1.5 takayama 638: flag = 0;
639: for (i=strlen(s)-1; i>=0; i--) {
640: if ((s[i] == '\n') && (i==0)) {
1.7 takayama 641: ++flag;
1.5 takayama 642: }else if ((s[i] == '\n') && (s[i-1] == '\n')) {
1.7 takayama 643: ++flag;
1.5 takayama 644: }else if ((s[i] == 0xd) && (s[i+1] == 0xa) && (i == 0)) {
1.7 takayama 645: ++flag;
1.5 takayama 646: }else if ((s[i] == 0xa) && (s[i-1] == 0xd) && (s[i+1] == 0xd) && (s[i+2] == 0xa)) {
1.7 takayama 647: ++flag;
1.5 takayama 648: }
649: }
1.7 takayama 650: if (flag >= flagmax) return ob;
1.5 takayama 651: datasize = strlen(s);
652: sss = s;
1.7 takayama 653: if ((s[strlen(s)-1] == '\n') ||
654: (s[strlen(s)-2] == 0xd) && (s[strlen(s)-1] == 0xa)) {
655: last = 1;
656: }else last = 0;
1.5 takayama 657:
1.7 takayama 658: while (flag < flagmax) {
1.8 takayama 659: contentLength = getContentLength(sss);
660: if (contentLength != -1) {
661: if (contentLength <= getReceivedContentLength(sss)) {
662: break;
663: }
664: }
1.14 takayama 665: if (Post_debug) {
666: fprintf(stderr,"Waiting in socketReadBlock. flagmax(0d,0a)=%d, content-length=%d, received content-length=%d\n",flagmax,contentLength,getReceivedContentLength(sss));
667: }
1.13 takayama 668: if (strlen(s) == 0) {
669: fprintf(stderr,"No data. Perhaps connection is closed by foreign host.\n");
670: return nob;
1.5 takayama 671: }else{
672: /* for debugging. */
1.14 takayama 673: if (Post_debug) {
674: for (i=0; i<strlen(sss); i++) {
675: if ((sss[i] >= ' ') && (sss[i] < 0x7f)) {
676: fprintf(stderr,"%c",sss[i]);
677: }else{
678: fprintf(stderr,"(%3x)",sss[i]);
679: if (sss[i] == 0xa) fprintf(stderr,"\n");
680: }
681:
1.8 takayama 682: }
1.14 takayama 683: fprintf(stderr,"\n");
1.5 takayama 684: }
685: }
1.13 takayama 686:
687: if (KsocketSelect0(socketid,-1) != 1) {
688: return nob;
689: }
1.5 takayama 690: ob = KsocketRead(socketObj);
691: s = KopString(ob);
692: for (i=strlen(s)-1; i>=0; i--) {
1.7 takayama 693: if ((s[i] == '\n') && (i==0) && last) {
694: ++flag;
1.5 takayama 695: }else if ((s[i] == '\n') && (s[i-1] == '\n')) {
1.7 takayama 696: ++flag;
697: }else if ((s[i] == 0xd) && (s[i+1] == 0xa) && (i==0) && last) {
698: ++flag;
1.5 takayama 699: }else if ((s[i] == 0xa) && (s[i-1] == 0xd) && (s[i+1] == 0xd) && (s[i+2] == 0xa)) {
1.7 takayama 700: ++flag;
1.5 takayama 701: }
702: }
703: if (datasize-1 <= strlen(sss)+strlen(s)) {
1.16 takayama 704: tmp = (char *)sGC_malloc(sizeof(char)*2*(datasize+strlen(s))+1);
1.5 takayama 705: if (tmp == (char *)NULL) errorMsg1s("Out of Memory.");
706: strcpy(tmp,sss);
707: strcat(tmp,s);
708: datasize = 2*(datasize+strlen(s));
709: sss = tmp;
710: }else{
711: strcat(sss,s);
712: }
1.7 takayama 713:
714: if ((s[strlen(s)-1] == '\n') ||
715: (s[strlen(s)-2] == 0xd) && (s[strlen(s)-1] == 0xa)) {
716: last = 1;
717: }else last = 0;
718:
1.5 takayama 719: }
720:
721: return KpoString(sss);
722:
723: }
724:
1.1 maekawa 725: struct object Kplugin_sm1Socket(char *key,struct object obj) {
726: struct object robj = NullObject;
727: if (strcmp(key,"open") == 0) {
728: robj = KsocketOpen(obj);
729: }else if (strcmp(key,"connect") == 0) {
730: robj = KsocketConnect(obj);
731: }else if (strcmp(key,"accept") == 0) {
732: robj = KsocketAccept(obj);
1.13 takayama 733: }else if (strcmp(key,"accept2") == 0) {
734: robj = KsocketAccept2(obj);
1.1 maekawa 735: }else if (strcmp(key,"select") == 0) {
736: robj = KsocketSelect(obj);
737: }else if (strcmp(key,"mselect") == 0) {
738: robj = KsocketSelectMulti(obj);
739: }else if (strcmp(key,"read") == 0) {
740: robj = KsocketRead(obj);
1.7 takayama 741: }else if (strcmp(key,"readHTTP") == 0) {
742: robj = KsocketReadHTTP(obj);
1.11 takayama 743: }else if (strcmp(key,"gethostname") == 0) {
744: robj = KsocketGetHostName();
745: }else if (strcmp(key,"write") == 0) {
1.1 maekawa 746: robj = KsocketWrite(obj);
747: }else if (strcmp(key,"read") == 0) {
748: robj = KsocketRead(obj);
749: }else if (strcmp(key,"readByte") == 0) {
750: robj = KsocketReadByte(obj);
751: }else if (strcmp(key,"writeByte") == 0) {
752: robj = KsocketWriteByte(obj);
753: }else if (strcmp(key,"close") == 0) {
754: robj = KsocketClose(obj);
755: }else {
756: errorMsg1s("Unknown tag for sm1.socket");
757: }
758: return(robj);
759: }
760:
761:
1.8 takayama 762: static int getContentLength(char *s) {
763: int n;
1.10 takayama 764: int i,j;
1.8 takayama 765: int len = -1;
1.10 takayama 766: char *s1 = "content-length:";
767: char s0[256];
768: int m;
769: m = strlen(s1);
1.8 takayama 770: n = strlen(s);
771: for (i=0; i<n; i++) {
1.10 takayama 772: strncpy(s0,&(s[i]),m+1);
773: for (j=0; j<m; j++) {
774: if ((s0[j] >= 'A') && (s0[j] <= 'Z')) s0[j] = s0[j]+0x20;
775: }
776: if (strncmp(s0,s1,strlen(s1)) == 0) {
777: sscanf(&(s[i+strlen(s1)]),"%d",&len);
778: break;
779: }
1.8 takayama 780: }
781: return len;
782: }
783: static int getReceivedContentLength(char *s) {
784: int n;
785: int i;
786: int start;
787: start = -1;
788: n = strlen(s);
789: for (i=0; i<n; i++) {
790: if ((s[i] == '\n') && (s[i+1] == '\n')) {
791: start = i+2; break;
792: }else if ((s[i] == 0xd) && (s[i+1] == 0xa) && (s[i+2] == 0xd) && (s[i+3] == 0xa)) {
793: start = i+4;
794: }
795: }
796: if (start == -1) return 0;
797: return (n-start);
798: }
1.1 maekawa 799:
800:
1.11 takayama 801: struct object KsocketGetHostName(void) {
802: char name[1024];
803: char *s;
804: struct object rob = NullObject;
805: if (gethostname(name,1023) != 0) {
806: return rob;
807: }
1.16 takayama 808: s = (char *)sGC_malloc(sizeof(char)*(strlen(name)+2));
1.11 takayama 809: if (s == (char *)NULL) errorMsg1s("Out of Memory.");
810: strcpy(s,name);
811: return(KpoString(s));
812: }
1.1 maekawa 813:
814:
815:
816:
817:
818:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>