Annotation of OpenXM/src/kan96xx/plugin/sm1Socket.c, Revision 1.1.1.1
1.1 maekawa 1: /* msg0s.c */
2: #include <stdio.h>
3: #include <sys/types.h>
4: #include <sys/socket.h>
5: #include <sys/time.h>
6: #include <netinet/in.h>
7: #include <netdb.h>
8:
9:
10: #include "datatype.h"
11: #include "stackm.h"
12: #include "extern.h"
13: #include "sm1Socket.h"
14:
15: extern int Quiet;
16: static void errorMsg1s(char *s);
17:
18: /* [(sm1.socket) (open) [optional integer port, optional string name] ] extension ; */
19: struct object KsocketOpen(struct object obj) {
20: char serverName[1024];
21: int portNumber;
22: struct object rob = NullObject;
23: struct hostent *myhost;
24: struct sockaddr_in me;
25: int s_waiting;
26: int on;
27: int tt;
28: extern int errno;
29:
30: if (obj.tag != Sarray) {
31: errorMsg1s("KsocketOpen([optional integer,optional string name])");
32: }
33: strcpy(serverName,"localhost");
34: portNumber = 0;
35: if (getoaSize(obj) >= 1) {
36: if ((getoa(obj,0)).tag != Sinteger) {
37: errorMsg1s("KsocketOpen([optional integer,optional string name]), the first argument must be an integer.");
38: }
39: portNumber = KopInteger(getoa(obj,0));
40: }
41: if (getoaSize(obj) >= 2) {
42: if ((getoa(obj,1)).tag != Sdollar) {
43: errorMsg1s("KsocketOpen([optional integer,optional string name]), the second argument must be a string.");
44: }
45: if (strlen(KopString(getoa(obj,1))) > 1023) {
46: errorMsg1s("Too long server name");
47: }
48: strcpy(serverName,KopString(getoa(obj,1)));
49: }
50:
51:
52: /* fprintf(stderr,"Hello from open.\n"); */
53: if ((myhost = gethostbyname(serverName)) == NULL) {
54: errorMsg1s("Bad server name.");
55: }
56: bzero((char *)&me,sizeof(me));
57: me.sin_family = AF_INET;
58: me.sin_port = htons(portNumber);
59: bcopy(myhost->h_addr,
60: &me.sin_addr,myhost->h_length);
61:
62: if ((s_waiting = socket(AF_INET,SOCK_STREAM,0)) < 0) {
63: errorMsg1s("Socket allocation is failed.");
64: }
65:
66: on=1; setsockopt(s_waiting,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
67: /* important */
68: if (bind(s_waiting,(struct sockaddr *) &me,sizeof(me)) == -1) {
69: fprintf(stderr,"Bind error. Error no is %d. See /usr/include/sys/errno.h.\n",errno);
70: errorMsg1s("cannot bind");
71: }
72:
73: tt = sizeof(me);
74: if (getsockname(s_waiting,(struct sockaddr *)&me,&tt) < 0) {
75: fprintf(stderr,"getsockname error. Error no is %d. See /usr/include/sys/errno.h.\n",errno);
76: errorMsg1s("cannot getsockname");
77: }
78:
79:
80: if (listen(s_waiting,1) < 0) {
81: errorMsg1s("Listen failed");
82: }
83: /*
84: fprintf(stderr,"Done the initialization. port =%d\n",ntohs(me.sin_port));
85: fprintf(stderr,"socket id = %d",accept(s_waiting,NULL,NULL)); */
86: rob = newObjectArray(2);
87: putoa(rob,0,KpoInteger(s_waiting));
88: putoa(rob,1,KpoInteger(ntohs(me.sin_port)));
89: return(rob);
90:
91: }
92:
93: /* [ integer port, optional string host default localhost]
94: [ integer socketid, integer port ] */
95: struct object KsocketConnect(struct object obj) {
96: char serverName[1024];
97: int portNumber;
98: struct hostent *servhost;
99: struct sockaddr_in server;
100: int socketid;
101: struct object robj = NullObject;
102:
103: if (obj.tag != Sarray) {
104: errorMsg1s("KsocketConnect( [ integer port, optional string host default localhost])");
105: }
106: strcpy(serverName,"localhost");
107: if (getoaSize(obj) < 1) {
108: errorMsg1s("You need to specify port number.\n");
109: }
110: if (getoaSize(obj) >= 1) {
111: if ((getoa(obj,0)).tag != Sinteger) {
112: errorMsg1s("KsocketConnect([integer port,optional string host]), the first argument must be an integer.");
113: }
114: portNumber = KopInteger(getoa(obj,0));
115: }
116: if (getoaSize(obj) >= 2) {
117: if ((getoa(obj,1)).tag != Sdollar) {
118: errorMsg1s("KsocketConnect([integer port,optional string host]), the second argument must be a string.");
119: }
120: if (strlen(KopString(getoa(obj,1))) > 1023) {
121: errorMsg1s("Too long server name");
122: }
123: strcpy(serverName,KopString(getoa(obj,1)));
124: }
125:
126:
127: if ((servhost = gethostbyname(serverName)) == NULL) {
128: errorMsg1s("bad server name.\n");
129: }
130: bzero((char *)&server,sizeof(server));
131: server.sin_family = AF_INET;
132: server.sin_port = htons(portNumber);
133: bcopy(servhost->h_addr,
134: (char *)&server.sin_addr,servhost->h_length);
135:
136: if ((socketid = socket(AF_INET,SOCK_STREAM,0)) <0) {
137: errorMsg1s("socket allocation is failed.\n");
138: }
139: if (!Quiet) {
140: fprintf(stderr,"Trying to connect port %d, ip=%x\n",ntohs(server.sin_port),server.sin_addr);
141: }
142: if (connect(socketid,(struct sockaddr *)&server,sizeof(server)) == -1) {
143: errorMsg1s("cannot connect");
144: }
145: /* fprintf(stderr,"connected.\n"); */
146: robj = newObjectArray(2);
147: putoa(robj,0,KpoInteger(socketid));
148: putoa(robj,1,KpoInteger(portNumber));
149: return(robj);
150: }
151:
152: /* [ integer socketid ]
153: [ integer newsocketid ] */
154: struct object KsocketAccept(struct object obj) {
155: struct object obj1;
156: struct object obj2;
157: struct object robj;
158: int s, news;
159:
160: if (obj.tag != Sarray) {
161: errorMsg1s("KsocketAccept([integer socketid])");
162: }
163: if (getoaSize(obj) < 1) {
164: errorMsg1s("KsocketAccept([integer socketid])");
165: }
166: obj1 = getoa(obj,0);
167: if (obj1.tag != Sinteger ) {
168: errorMsg1s("KsocketAccept([integer socketid]), argument must be integer.");
169: }
170: s = KopInteger(obj1);
171: if ((news = accept(s,NULL,NULL)) < 0) {
172: errorMsg1s("Error in accept.");
173: }
174: if (close(s) < 0) {
175: errorMsg1s("Error in closing the old socket.");
176: }
177: robj = newObjectArray(1);
178: putoa(robj,0,KpoInteger(news));
179: return(robj);
180: }
181:
182: int KsocketSelect0(int fd,int t) {
183: fd_set readfds;
184: struct timeval timeout;
185: extern int errno;
186: FD_ZERO(&readfds);
187: FD_SET(fd,&readfds);
188: timeout.tv_sec = 0;
189: timeout.tv_usec = (long) t;
190: if (t >= 0) {
191: if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,&timeout)<0) {
192: /* It must be fd+1 !, Not fd. */
193: fprintf(stderr,"Select error. Error no is %d. See /usr/include/sys/errno.h.\n",errno);
194: errorMsg1s("KsocketSelect0() : select failed.");
195: return(0);
196: }
197: }else{ /* block */
198: if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,(struct timeval *)NULL)<0) {
199: errorMsg1s("KsocketSelect0() : select failed.");
200: fprintf(stderr,"Select error. Error no is %d. See /usr/include/sys/errno.h.\n",errno);
201: return(0);
202: }
203: }
204: if (FD_ISSET(fd,&readfds)) return(1);
205: else return(0);
206: }
207:
208: /* [ integer socketid optional integer timeout default 0]
209: integer true or false
210: */
211: struct object KsocketSelect(struct object obj) {
212: struct object robj;
213: struct object ob1;
214: struct object ob2;
215: if (obj.tag != Sarray) {
216: errorMsg1s("KsocketSelect([ integer socketid optional integer timeout default 0]");
217: }
218: if (getoaSize(obj) < 1) {
219: errorMsg1s("KsocketSelect([ integer socketid optional integer timeout default 0]");
220: }
221: if (getoaSize(obj) >= 1) {
222: ob1 = getoa(obj,0);
223: ob2 = KpoInteger(0); /* default value */
224: }
225: if (getoaSize(obj) >= 2) {
226: ob2 = getoa(obj,1);
227: }
228: if (ob1.tag != Sinteger) {
229: errorMsg1s("KsocketSelect([ integer socketid optional integer timeout default 0] : the first argument must be an integer.");
230: }
231: if (ob2.tag != Sinteger) {
232: errorMsg1s("KsocketSelect([ integer socketid optional integer timeout default 0] : the second argument must be an integer.");
233: }
234: robj = KpoInteger( KsocketSelect0(KopInteger(ob1),KopInteger(ob2)) );
235: return(robj);
236: }
237:
238: struct object KsocketSelectMulti(struct object obj)
239: /* [ [integer socketid1, integer socketid2, ...]
240: optional integer timeout default 0]
241: [ result1, result2, ....]
242: */
243: {
244: struct object robj;
245: struct object ob1;
246: struct object ob2;
247: struct object ob3;
248: int size,i,fd,p,t;
249: fd_set readfds;
250: struct timeval timeout;
251: extern errno;
252: if (obj.tag != Sarray) {
253: errorMsg1s("KsocketSelectMulti([[sid1, sid2,...] optional integer timeout default 0]");
254: }
255: if (getoaSize(obj) < 1) {
256: errorMsg1s("KsocketSelectMulti([[sid1, sid2,...] optional integer timeout default 0]");
257: }
258: if (getoaSize(obj) >= 1) {
259: ob1 = getoa(obj,0);
260: ob2 = KpoInteger(0); /* default value */
261: }
262: if (getoaSize(obj) >= 2) {
263: ob2 = getoa(obj,1);
264: }
265: if (ob1.tag != Sarray) {
266: errorMsg1s("KsocketSelectMulti([[sid1, sid2, ...] optional integer timeout default 0] : the first argument must be an array.");
267: }
268: if (ob2.tag != Sinteger) {
269: errorMsg1s("KsocketSelectMulti([[sid1, sid2, ...] optional integer timeout default 0] : the second argument must be an integer.");
270: }
271: FD_ZERO(&readfds);
272: timeout.tv_sec = 0; t = KopInteger(ob2);
273: timeout.tv_usec = (long)t;
274:
275: size = getoaSize(ob1);
276: if (size < 1) {
277: errorMsg1s("KsocketSelectMulti: the first argument must be a non-empty array of integers.");
278: }
279: fd = 0;
280:
281: for (i=0; i<size; i++) {
282: ob3 = getoa(ob1,i);
283: if (ob3.tag != Sinteger) {
284: errorMsg1s("KsocketSelectMulti: the first argument must be an array of integers.");
285: }
286: p = KopInteger(ob3);
287: if (p > fd) fd = p;
288: FD_SET(p,&readfds);
289: /* printf("p = %d, fd=%d",p,fd); */
290: }
291:
292: if (t >= 0) {
293: if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,&timeout)<0) {
294: /* It must be fd+1 !, Not fd. */
295: fprintf(stderr,"Select error. Error no is %d. See /usr/include/sys/errno.h.\n",errno);
296: errorMsg1s("KsocketSelectMulti() : select failed.");
297: }
298: }else{ /* block */
299: if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,(struct timeval *)NULL)<0) {
300: fprintf(stderr,"Select error. Error no is %d. See /usr/include/sys/errno.h.\n",errno);
301: errorMsg1s("KsocketSelectMulti() : (block) select failed.");
302: }
303: }
304: robj = newObjectArray(size);
305: for (i=0; i<size; i++) {
306: if (FD_ISSET(KopInteger(getoa(ob1,i)),&readfds)) {
307: putoa(robj,i,KpoInteger(1));
308: }else{
309: putoa(robj,i,KpoInteger(0));
310: }
311: }
312:
313: return(robj);
314: }
315:
316:
317:
318:
319: static char Data00[1024];
320: /* [ integer socketid ]
321: string data
322: */
323: struct object KsocketRead(struct object obj) {
324: struct object ob1;
325: struct object robj = NullObject;
326: static int datasize = 1024;
327: static char *data = Data00;
328: char *tmp;
329: char *r;
330: int n;
331: int socketid;
332: int totalsize;
333:
334: if (obj.tag != Sarray) {
335: errorMsg1s("KsocketRead([integer socketid])");
336: }
337: if (getoaSize(obj) < 1) {
338: errorMsg1s("KsocketRead([integer socketid])");
339: }
340: ob1 = getoa(obj,0);
341: if (ob1.tag != Sinteger) {
342: errorMsg1s("KsocketRead([integer socketid]) : the argument must be integer.");
343: }
344: socketid = KopInteger(ob1);
345:
346: totalsize = 0;
347:
348: while (KsocketSelect0(socketid,0)) {
349: if (datasize - totalsize > 0) {
350: n = read(socketid,data+totalsize,datasize-totalsize);
351: if (n < 0) {
352: errorMsg1s("Read error.");
353: }
354: if (n < datasize-totalsize) {
355: totalsize += n;
356: break;
357: }else{ totalsize += n; }
358: if (totalsize == 0) {
359: errorMsg1s("Select returns 1, but there is no data to read.");
360: }
361: }else { /* increase the datasize */
362: tmp = (char *)GC_malloc(sizeof(char)*2*datasize);
363: /*I should use GC_malloc_atomic and free after finishing this function?*/
364: if (tmp == (char *)NULL) errorMsg1s("Out of Memory.");
365: bcopy(data,tmp,totalsize);
366: data = tmp;
367: datasize = 2*datasize;
368: }
369: }
370:
371: r = (char *)GC_malloc(sizeof(char)*(n+1));
372: if (r == (char *)NULL) errorMsg1s("Out of Memory.");
373: bcopy(data,r,totalsize);
374: robj = KpoString(r);
375:
376: return(robj);
377:
378: }
379:
380: /* [ integer socketid, string data ]
381: integer */
382: struct object KsocketWrite(struct object obj) {
383: struct object ob1;
384: struct object ob2;
385: int socketid;
386: int r;
387: if (obj.tag != Sarray) {
388: errorMsg1s("KsocketWrite([integer socketid, string data])");
389: }
390: if (getoaSize(obj) < 2) {
391: errorMsg1s("KsocketWrite([integer socketid, string data])");
392: }
393: ob1 = getoa(obj,0);
394: ob2 = getoa(obj,1);
395: if (ob1.tag != Sinteger) {
396: errorMsg1s("KsocketWrite([integer socketid, string data]) : the first argument must be an integer.");
397: }
398: socketid = KopInteger(ob1);
399: if (ob2.tag != Sdollar) {
400: errorMsg1s("KsocketWrite([integer socketid, string data]) : the second argument must be a string.");
401: }
402: r = write(socketid,KopString(ob2), strlen(KopString(ob2)));
403: return(KpoInteger(r));
404:
405: }
406: struct object KsocketClose(struct object obj) {
407: int socketid;
408: struct object ob1;
409: if (obj.tag != Sarray) {
410: errorMsg1s("KsocketClose([ integer socketid ])");
411: }
412: if (getoaSize(obj) != 1) {
413: errorMsg1s("KsocketClose([ integer socketid ])");
414: }
415: ob1 = getoa(obj,0);
416: if (ob1.tag != Sinteger) {
417: errorMsg1s("KsocketClose([ INTEGER socketid ])");
418: }
419: socketid = KopInteger(ob1);
420: return(KpoInteger(close(socketid)));
421: }
422:
423:
424: static void errorMsg1s(char *s) {
425: fprintf(stderr,"%s\n",s);
426: errorKan1("msg1s.c: %s\n",s);
427: }
428:
429:
430: /**************** new 1997, 11/23 *******************/
431: struct object KsocketReadByte(struct object obj);
432: struct object KsocketWriteByte(struct object obj);
433:
434: struct object KsocketReadByte(struct object obj) {
435: struct object ob1;
436: struct object robj = NullObject;
437: char data[2];
438: char *tmp;
439: char *r;
440: int n;
441: int socketid;
442:
443:
444: if (obj.tag != Sarray) {
445: errorMsg1s("KsocketReadByte([integer socketid])");
446: }
447: if (getoaSize(obj) < 1) {
448: errorMsg1s("KsocketReadByte([integer socketid])");
449: }
450: ob1 = getoa(obj,0);
451: if (ob1.tag != Sinteger) {
452: errorMsg1s("KsocketReadByte([integer socketid]) : the argument must be integer.");
453: }
454: socketid = KopInteger(ob1);
455:
456:
457: n = read(socketid,data,1);
458: if (n < 0) {
459: errorMsg1s("Read error.");
460: robj = KpoInteger(-1);
461: return(robj);
462: }
463: if (n == 0) {
464: errorMsg1s("Read returned without data.");
465: }
466:
467: robj = KpoInteger((int)((unsigned char)data[0]));
468: return(robj);
469:
470: }
471:
472: /* [ integer socketid, int ]
473: integer */
474: struct object KsocketWriteByte(struct object obj) {
475: struct object ob1;
476: struct object ob2;
477: int socketid;
478: int r;
479: char data[2];
480: if (obj.tag != Sarray) {
481: errorMsg1s("KsocketWriteByte([integer socketid, int])");
482: }
483: if (getoaSize(obj) < 2) {
484: errorMsg1s("KsocketWriteByte([integer socketid, int])");
485: }
486: ob1 = getoa(obj,0);
487: ob2 = getoa(obj,1);
488: if (ob1.tag != Sinteger) {
489: errorMsg1s("KsocketWriteByte([integer socketid, int]) : the first argument must be an integer.");
490: }
491: socketid = KopInteger(ob1);
492: if (ob2.tag != Sinteger) {
493: errorMsg1s("KsocketWriteByte([integer socketid, int]) : the second argument must be a string.");
494: }
495: data[0] = KopInteger(ob2);
496: r = write(socketid,data, 1);
497: return(KpoInteger(r));
498: }
499:
500: struct object Kplugin_sm1Socket(char *key,struct object obj) {
501: struct object robj = NullObject;
502: if (strcmp(key,"open") == 0) {
503: robj = KsocketOpen(obj);
504: }else if (strcmp(key,"connect") == 0) {
505: robj = KsocketConnect(obj);
506: }else if (strcmp(key,"accept") == 0) {
507: robj = KsocketAccept(obj);
508: }else if (strcmp(key,"select") == 0) {
509: robj = KsocketSelect(obj);
510: }else if (strcmp(key,"mselect") == 0) {
511: robj = KsocketSelectMulti(obj);
512: }else if (strcmp(key,"read") == 0) {
513: robj = KsocketRead(obj);
514: }else if (strcmp(key,"write") == 0) {
515: robj = KsocketWrite(obj);
516: }else if (strcmp(key,"read") == 0) {
517: robj = KsocketRead(obj);
518: }else if (strcmp(key,"readByte") == 0) {
519: robj = KsocketReadByte(obj);
520: }else if (strcmp(key,"writeByte") == 0) {
521: robj = KsocketWriteByte(obj);
522: }else if (strcmp(key,"close") == 0) {
523: robj = KsocketClose(obj);
524: }else {
525: errorMsg1s("Unknown tag for sm1.socket");
526: }
527: return(robj);
528: }
529:
530:
531:
532:
533:
534:
535:
536:
537:
538:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>