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