Annotation of OpenXM/src/kan96xx/plugin/oxmisc.c, Revision 1.25
1.25 ! ohara 1: /* $OpenXM: OpenXM/src/kan96xx/plugin/oxmisc.c,v 1.24 2005/06/16 05:07:24 takayama Exp $ */
1.1 maekawa 2: #include <stdio.h>
1.25 ! ohara 3: #include <string.h>
1.1 maekawa 4: #include <sys/types.h>
5: #include <sys/stat.h>
6: #include <sys/socket.h>
7: #include <sys/time.h>
8: #include <netinet/in.h>
9: #include <netdb.h>
10: #include <fcntl.h>
11: #include <stdlib.h>
12: #include <unistd.h>
13: #include <signal.h>
14: #include <setjmp.h>
1.19 takayama 15: #include <errno.h>
1.5 takayama 16: #define SET_MYERROROUT { if (MyErrorOut == NULL) MyErrorOut=stdout; }
17: /* It is also defined in oxmisc2.c */
18: FILE *MyErrorOut = NULL;
1.1 maekawa 19:
20: /* Include files to understand object */
21: #include "../Kan/datatype.h"
22: #include "../Kan/stackm.h"
23: #include "../Kan/extern.h"
24:
25: #include "ox_kan.h"
26:
27: #define READBUFSIZE 5000
28:
1.8 takayama 29: int OxVersion = 200012030;
1.1 maekawa 30: int UseOXPacketSerial = 1;
31: int SerialOX = 1;
32: extern int Quiet;
33:
34: static char *OxPortFileName = ".ox.dummy";
35:
36:
37: int readOneByte(int fd) /* blocking */
38: {
39: static char data[1];
40: int size;
41: int ans;
42: int watch = 1;
43:
1.5 takayama 44: SET_MYERROROUT;
1.1 maekawa 45: if (fd < 0) {
46: fprintf(MyErrorOut,"readOneByte fd < 0 ??? .\n");
47: return(-1);
48: }
49:
50: if (oxSocketSelect0(fd,-1)) { /* block */
51: size = read(fd,data,1);
52: if (size == 0) {
1.7 takayama 53: fprintf(MyErrorOut,"oxSocketSelect0() returns 1, but there is no data. Your peer may be killed.\n");
1.1 maekawa 54: return(-1);
55: }
56: return(data[0]);
57: }else{
58: fprintf(MyErrorOut,"readOneByte: select error in block mode. Retrying.\n");
59: return(-1);
60: }
61: }
62:
63: int readOneByte_org(int fd) /* blocking */
64: {
65: static char data[READBUFSIZE];
66: static int thisFd = -1;
67: static int from = 0;
68: static int to = 0;
69: int size;
70: int ans;
71: int watch = 1;
72:
1.5 takayama 73: SET_MYERROROUT;
1.1 maekawa 74: if ((thisFd == -1) && (fd >= 0)) {thisFd = fd;}
75: if (fd < 0) {
76: fprintf(MyErrorOut,"readOneByte fd < 0 ??? .\n");
77: return(-1);
78: }
79:
80: if (fd != thisFd) {
81: fprintf(MyErrorOut,"readOneByte can be used only for one fd.\n");
82: fflush(NULL);
83: return(-1);
84: }
85: if (to > from) {
86: ans = data[from];
87: from++;
88: if (watch) {
89: printf("%2x ",ans);
90: fflush(stdout);
91: }
92: return(ans);
93: }
94:
95: while (1) {
96: if (oxSocketSelect0(fd,-1)) { /* block */
97: size = read(fd,data,READBUFSIZE-1);
98: if (size == 0) {
1.9 takayama 99: fprintf(MyErrorOut,"oxSocketSelect0() returns 1, but there is no data. Your peer may be killed.\n");
100: return(-1);
1.1 maekawa 101: }
102: from = 0;
103: to = size;
104: return(readOneByte(fd));
105: }else{
106: fprintf(MyErrorOut,"readOneByte: select error in block mode. Retrying.\n"); }
107: }
108: }
109:
110: int oxfdGetInt32(int fd)
111: {
112: char d[4];
113: int i;
114: for (i=0; i<4; i++) {
115: d[i] = readOneByte(fd);
116: }
117: return(ntohl(* ( (int *)d)));
118: }
119:
120: int oxGetInt32(ox_stream ostream)
121: {
122: char d[4];
123: int i;
124: for (i=0; i<4; i++) {
125: d[i] = fp2fgetc(ostream);
126: }
127: return(ntohl(* ( (int *)d)));
128: }
129: int oxGetCMOInt32(ox_stream ostream)
130: {
131: int id;
1.5 takayama 132: SET_MYERROROUT;
1.1 maekawa 133: id = oxGetInt32(ostream);
134: if (id != CMO_INT32) {
135: fprintf(MyErrorOut,"It is not CMO_INT32.\n");
136: return(0);
137: }
138: return(oxGetInt32(ostream));
139: }
140: char *oxGetCMOString(ox_stream ostream) {
141: int id;
142: int size;
143: char *r;
144: int i;
1.5 takayama 145: SET_MYERROROUT;
1.1 maekawa 146: id = oxGetInt32(ostream);
147: if (id != CMO_STRING) {
148: fprintf(MyErrorOut,"It is not CMO_STRING.\n");
149: return(NULL);
150: }
151: size = oxGetInt32(ostream);
152: if (size <0) {
153: return(NULL);
154: }else{
155: r = (char *)mymalloc(size+1);
156: for (i=0; i<size; i++) {
157: r[i] = fp2fgetc(ostream);
158: }
159: r[size] = '\0';
160: return(r);
161: }
162: }
163:
164: void oxfdSendSyncBall(int fd)
165: {
166: oxfdSendOXheader(fd,OX_SYNC_BALL,SerialOX++);
167: }
168:
169: void oxSendSyncBall(ox_stream os)
170: {
171: oxSendOXheader(os,OX_SYNC_BALL,SerialOX++);
172: }
173:
174: int oxWaitSyncBall(ox_stream ostream)
175: {
176: int sss;
177: int mtag;
178: while ((mtag = oxGetOXheader(ostream,&sss)) != OX_SYNC_BALL) {
179: fprintf(stderr,"Looking for the next message tag. mtag=%d\n",mtag);
1.9 takayama 180: /* or stdout */
1.1 maekawa 181: fflush(NULL);
182: }
183: }
184:
185: int oxWaitSyncBall_org(ox_stream ostream)
186: {
187: int mtag;
188: char data[4];
189: int c;
1.5 takayama 190: SET_MYERROROUT;
1.1 maekawa 191: data[0] = data[1] = data[2] = data[3] = 0xff;
192: while (1) {
193: /* This part should be revised so that this part understands
194: the cmo format.
1.9 takayama 195: */
1.1 maekawa 196:
197: if ((c = fp2fgetc(ostream)) < 0) {
198: /* never use read directory. readOneByte() is buffers every thing. */
199: fprintf(MyErrorOut,"End of file.\n");
200: return(-1);
201: }
202: data[0] = data[1];
203: data[1] = data[2];
204: data[2] = data[3];
205: data[3] = (char)c;
206: mtag = ntohl(*((int *)(data)));
207: if (mtag == OX_SYNC_BALL) {
208: printf("Found the OX_SYNC_BALL. \n");
209: fflush(NULL);
210: return(mtag);
211: }
212: fprintf(stderr,"Looking for the next message tag.. %2x, mtag=%d\n",c,mtag);
1.9 takayama 213: /* or stdout */
1.1 maekawa 214: fflush(NULL);
215: }
216: }
217:
218:
219: void oxfdSendCmoNull(int fd)
220: {
221: char data[4];
222: *((int *)&data[0]) = htonl(CMO_NULL);
223: write(fd,data,4);
224: fflush((FILE *)NULL);
225: }
226: void oxSendCmoNull(ox_stream os)
227: {
228: char data[4];
229: *((int *)&data[0]) = htonl(CMO_NULL);
230: fp2write(os,data,4);
231: fp2fflush(os);
232: }
233:
234: void oxSendCmoError(ox_stream os)
235: {
236: char data[4];
237: *((int *)&data[0]) = htonl(CMO_ERROR);
238: fp2write(os,data,4);
239: fp2fflush(os);
240: }
241:
242: void oxSendCmoError2(ox_stream os,char *s)
243: {
244: char data[4];
245: *((int *)&data[0]) = htonl(CMO_ERROR2);
246: fp2write(os,data,4);
247: fp2fflush(os);
248: oxSendCmoString(os,s);
249: }
250:
251: void oxfdSendInt32(int fd,int k)
252: {
253: char data[4];
254: *((int *)&data[0]) = htonl(k);
255: write(fd,data,4);
256: fflush((FILE *)NULL);
257: }
258: void oxSendInt32(ox_stream os,int k)
259: {
260: char data[4];
261: *((int *)&data[0]) = htonl(k);
262: fp2write(os,data,4);
263: fp2fflush(os);
264: }
265:
266: void oxfdSendCmoInt32(int fd,int k)
267: {
268: char data[4*2];
269: *((int *)&data[0]) = htonl(CMO_INT32);
270: *((int *)&data[4]) = htonl(k);
271: write(fd,data,4*2);
272: fflush((FILE *)NULL);
273: }
274: void oxSendCmoInt32(ox_stream os,int k)
275: {
276: char data[4*2];
277: *((int *)&data[0]) = htonl(CMO_INT32);
278: *((int *)&data[4]) = htonl(k);
279: fp2write(os,data,4*2);
280: fp2fflush(os);
281: }
282: void oxfdSendCmoString(int fd,char *s)
283: {
284: char data[4*2];
285: int n;
286: if (s == NULL) n = 0;
287: else {
288: n = strlen(s);
289: }
290: *((int *)&data[0]) = htonl(CMO_STRING);
291: *((int *)&data[4]) = htonl(n);
292: write(fd,data,4*2);
293: if (s != NULL) {
294: write(fd,s,n);
295: }
296: fflush((FILE *)NULL);
297: }
298:
299: void oxSendCmoString(ox_stream os,char *s)
300: {
301: char data[4*2];
302: int n;
303: if (s == NULL) n = 0;
304: else {
305: n = strlen(s);
306: }
307: *((int *)&data[0]) = htonl(CMO_STRING);
308: *((int *)&data[4]) = htonl(n);
309: fp2write(os,data,4*2);
310: if (s != NULL) {
311: fp2write(os,s,n);
312: }
313: fp2fflush(os);
314: }
315:
316:
317:
318: void oxReqPushString(ox_stream os, char *s)
319: {
320: oxSendOXheader(os,OX_DATA,SerialOX++);
321: oxSendCmoString(os,s);
322: }
323:
324: void oxSendResultOfControlInt32(int fd,int i)
325: {
326: char data[4*2];
327: oxfdSendOXheader(fd,OX_DATA,SerialOX++);
328: *((int *)&data[0]) = htonl(CMO_INT32);
329: *((int *)&data[4]) = htonl(i);
330: write(fd,data,4*2);
331: fflush((FILE *)NULL);
332: }
333:
334: void oxSendResultOfControl(int fd)
335: {
336: char data[4*1];
337: oxfdSendOXheader(fd,OX_DATA,SerialOX++);
338: *((int *)&data[0]) = htonl(CMO_NULL);
339: write(fd,data,4*1);
340: fflush((FILE *)NULL);
341: }
342:
343:
344:
345: void oxSendMathCap(ox_stream os,struct mathCap *mathcap)
346: {
1.4 takayama 347: int i,n,infosize,ncmo;
1.24 takayama 348: struct object mathinfo = OINIT;
1.1 maekawa 349: /* printf("ox sending mathcap\n"); fflush(stdout); */
350: mathinfo = *((struct object *)(mathcap->infop));
351: infosize = getoaSize(mathinfo);
352:
353: oxSendInt32(os,CMO_MATHCAP);
354:
355: oxSendInt32(os,CMO_LIST);
356: oxSendInt32(os,3);
357:
358: /* [0] */
359: oxSendInt32(os,CMO_LIST);
360: oxSendInt32(os,infosize);
361: oxSendCmoInt32(os,KopInteger(getoa(mathinfo,0)));
362: for (i=1; i<infosize; i++) {
363: oxSendCmoString(os,KopString(getoa(mathinfo,i)));
364: }
365:
366: /* [1] */
367: oxSendInt32(os,CMO_LIST);
368: oxSendInt32(os,mathcap->smSize);
369: n = mathcap->smSize;
370: for (i=0; i<n; i++) {
371: oxSendCmoInt32(os,(mathcap->sm)[i]);
372: }
373:
374: /* [2] */
375: oxSendInt32(os,CMO_LIST);
1.4 takayama 376: n = mathcap->oxSize;
377: oxSendInt32(os,n);
1.1 maekawa 378:
379: oxSendInt32(os,CMO_LIST);
1.4 takayama 380: oxSendInt32(os,2);
1.1 maekawa 381: for (i=0; i<n; i++) {
1.4 takayama 382: /* OX_DATA_xxx */
1.1 maekawa 383: oxSendCmoInt32(os,(mathcap->ox)[i]);
1.4 takayama 384: /* OX_DATA_xxx tags. In case of CMO, it is CMO tags. */
385: oxSendInt32(os,CMO_LIST);
386: oxSendInt32(os,mathcap->n);
387: ncmo = mathcap->n;
388: for (i=0; i<ncmo; i++) {
389: oxSendCmoInt32(os,(mathcap->cmo)[i]);
390: /* printf("i=%d %d, ",i,(mathcap->cmo)[i]); */
391: }
1.1 maekawa 392: }
393: /* printf("\n"); fflush(stdout); */
394: }
395:
396: void oxReqMathCap(ox_stream os) {
397: oxSendOXheader(os,OX_COMMAND,SerialOX++);
398: oxSendInt32(os,SM_mathcap);
399: fp2fflush(os);
400: }
401:
402: void oxReqSetMathCap(ox_stream os,struct mathCap *mathcap) {
403: oxSendOXheader(os,OX_DATA,SerialOX++);
404: oxSendMathCap(os,mathcap);
405: oxSendOXheader(os,OX_COMMAND,SerialOX++);
406: oxSendInt32(os,SM_setMathCap);
407: fp2fflush(os);
408: }
409: void oxReqPops(ox_stream os,int n) {
410: oxSendOXheader(os,OX_DATA,SerialOX++);
411: oxSendCmoInt32(os,n);
412: oxSendOXheader(os,OX_COMMAND,SerialOX++);
413: oxSendInt32(os,SM_pops);
414: fp2fflush(os);
415: }
416: void oxReqSetName(ox_stream os,char *s) {
417: oxSendOXheader(os,OX_DATA,SerialOX++);
418: oxSendCmoString(os,s);
419: oxSendOXheader(os,OX_COMMAND,SerialOX++);
420: oxSendInt32(os,SM_setName);
421: fp2fflush(os);
422: }
423: void oxReqEvalName(ox_stream os,char *s) {
424: oxSendOXheader(os,OX_DATA,SerialOX++);
425: oxSendCmoString(os,s);
426: oxSendOXheader(os,OX_COMMAND,SerialOX++);
427: oxSendInt32(os,SM_evalName);
428: fp2fflush(os);
429: }
430:
431: void oxReqExecuteStringByLocalParser(ox_stream os,char *s)
432: {
433: oxSendOXheader(os,OX_DATA,SerialOX++);
434: oxSendCmoString(os,s);
435: oxSendOXheader(os,OX_COMMAND,SerialOX++);
436: oxSendInt32(os,SM_executeStringByLocalParser);
437: fp2fflush(os);
438: }
439:
440: void oxReqExecuteFunction(ox_stream os,char *s)
441: {
442: oxSendOXheader(os,OX_DATA,SerialOX++);
443: oxSendCmoString(os,s);
444: oxSendOXheader(os,OX_COMMAND,SerialOX++);
445: oxSendInt32(os,SM_executeFunction);
446: fp2fflush(os);
447: }
448:
1.20 takayama 449: void oxReqExecuteFunctionWithOptionalArgument(ox_stream os,char *s)
450: {
451: oxSendOXheader(os,OX_DATA,SerialOX++);
452: oxSendCmoString(os,s);
453: oxSendOXheader(os,OX_COMMAND,SerialOX++);
454: oxSendInt32(os,SM_executeFunctionWithOptionalArgument);
455: fp2fflush(os);
456: }
457:
1.1 maekawa 458:
459: void oxReqPopString(ox_stream os)
460: {
461: oxSendOXheader(os,OX_COMMAND,SerialOX++);
462: oxSendInt32(os,SM_popString);
463: fp2fflush(os);
464: }
465:
466: void oxReqSingleOperand(ox_stream os,int smtag)
467: {
468: oxSendOXheader(os,OX_COMMAND,SerialOX++);
469: oxSendInt32(os,smtag);
470: fp2fflush(os);
471: }
472:
473:
474: void oxReqControlResetConnection(int fd) {
475: oxfdSendOXheader(fd,OX_COMMAND,SerialOX++);
476: oxfdSendInt32(fd,SM_control_reset_connection);
477: fflush(NULL);
478: }
479:
480: void oxReqControlKill(int fd) {
481: oxfdSendOXheader(fd,OX_COMMAND,SerialOX++);
482: oxfdSendInt32(fd,SM_control_kill);
483: fflush(NULL);
484: }
485:
486: void oxReqPopCMO(ox_stream os) {
487: oxSendOXheader(os,OX_COMMAND,SerialOX++);
488: oxSendInt32(os,SM_popCMO);
489: fp2fflush(os);
490: }
491:
492:
493: int oxGetResultOfControlInt32(int fd) {
494: int k; int sss;
1.5 takayama 495: SET_MYERROROUT;
1.1 maekawa 496: k = oxfdGetOXheader(fd,&sss);
497: if (k != OX_DATA) {
498: fprintf(MyErrorOut,"oxGetResultOfControlInt32: wrong header.");
499: return(-1);
500: }
501: k = oxfdGetInt32(fd); /* CMO_INT32 */
502: k = oxfdGetInt32(fd);
503: return(k);
504: }
505:
506: int oxclientMultiSelect(oxclientp clients[],int dataready[],
1.9 takayama 507: int controlready[], int size, int t)
1.1 maekawa 508: {
509: int i, ddd;
510: int fd;
511: int humanfd = 0;
512: fd_set readfds;
513: struct timeval timeout;
514:
1.5 takayama 515: SET_MYERROROUT;
1.1 maekawa 516: /** printf("(1)"); fflush(NULL); */
517: FD_ZERO(&readfds);
518: timeout.tv_sec = 0;
519: timeout.tv_usec = (long) t;
520:
521: ddd = 0; fd = 0;
522: for (i=0; i<size; i++) {
523: dataready[i] = controlready[i] = 0;
524: }
525: for (i=0; i<size; i++) {
526: if (clients[i]->humanio) {
527: fd = (fd<humanfd?humanfd:fd);
528: FD_SET(humanfd,&readfds);
529: if (oxSocketSelect0(humanfd,0)) {
1.9 takayama 530: ddd = dataready[i] = 1; controlready[i] = 0;
1.1 maekawa 531: }else{
1.9 takayama 532: dataready[i] = 0; controlready[i] = 0;
1.1 maekawa 533: }
534: }else{
1.9 takayama 535: if (clients[i]->controlport < 0) { /* For RFC_101 */
536: controlready[i] = 0;
537: }else{
538: fd = (fd<clients[i]->controlfd?clients[i]->controlfd:fd);
539: FD_SET(clients[i]->controlfd,&readfds);
540: if (oxSocketSelect0(clients[i]->controlfd,0)) {
541: ddd = controlready[i] = 1;
542: }else{
543: controlready[i] = 0;
544: }
545: }
1.1 maekawa 546: if (clients[i]->datafp2 != NULL) {
1.9 takayama 547: fd = (fd<clients[i]->datafp2->fd?clients[i]->datafp2->fd:fd);
548: FD_SET(clients[i]->datafp2->fd,&readfds);
549: if (fp2select(clients[i]->datafp2,0)) {
550: ddd = dataready[i] = 1;
551: }else{
552: dataready[i] = 0;
553: }
1.1 maekawa 554: }else{
1.9 takayama 555: dataready[i] = 0;
1.1 maekawa 556: }
557: }
558: }
559: if (t > 0 ) {
560: if (ddd) return(1);
561: if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,&timeout)<0) {
562: fprintf(MyErrorOut,"error");
563: return(-1);
564: }
565: return(oxclientMultiSelect(clients, dataready, controlready,size,0));
566: }else if (t == 0) {
567: return(ddd);
568: }else {
569: /** printf("(2)"); fflush(NULL); */
570: if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,(struct timeval *)NULL)<0) {
571: fprintf(MyErrorOut,"error");
572: return(-1);
573: }
574: /** printf("(3)"); fflush(NULL); */
575: return(oxclientMultiSelect(clients, dataready, controlready,size,0));
576: }
577: }
578:
579: int oxGetControl(oxclientp client)
1.9 takayama 580: /* synchronized. */
1.1 maekawa 581: {
582: int ans;
583: ox_stream os;
584: switch (client->cstate) {
585: case 1:
586: ans = oxGetResultOfControlInt32(client->controlfd);
587: client->cstate = 0;
588: return(ans);
589: default:
590: fprintf(MyErrorOut,"oxGet: unknown cstate.\n");
591: client->cstate = -1;
592: return(-1);
593: }
594:
595: return(-1);
596: }
597:
598: int oxInitClient(oxclientp client)
599: {
600: client->datafp2 = NULL;
601: client->dataport = 0;
602: client->controlport = 0;
603: client->controlfd = 0;
604: client->humanio = 0;
605: client->dstate = 0;
606: client->cstate = 0;
607: client->id = -1;
608: client->mathcapObjp = NULL;
609: client->controlByteOrder = OX_BYTE_NETWORK_BYTE_ORDER;
610: client->engineByteOrder = OX_BYTE_NETWORK_BYTE_ORDER;
1.15 takayama 611: client->engineID = -1;
1.1 maekawa 612: return(0);
613: }
614:
615: int oxIsThereErrorClient(oxclientp client) {
616: if (client == NULL) return(1);
617: if (client->dstate == -1) return(1);
618: if (client->cstate == -1) return(1);
619: return(0);
620: }
621:
1.23 takayama 622: oxclientp oxCreateClient(char *sname,int portStream,int portControl,
623: char *passControl, char *passData)
1.9 takayama 624: /* you also need to change oxCreateClient2. */
1.1 maekawa 625: {
626: int v = 0;
627: int fdControl = -1;
628: int fdStream = -1;
629: oxclientp client;
630: int controlByteOrder, engineByteOrder;
631: v = !Quiet;
632: if (portControl != -1) {
633: fdControl = socketConnect(sname,portControl);
634: if (v) fprintf(stderr,"\nControl port %d : Connected.\n",portControl);
635: }
636: if (portStream != -1) {
637: sleep(1); /* wait */
638: fdStream = socketConnect(sname,portStream);
639: if (v) fprintf(stderr,"\nStream port %d : Connected.\n",portStream);
640: }
641:
642: if (fdStream == -1 || fdControl == -1) {
643: fprintf(stderr,"\nOpen error in oxCreateClient.\n");
644: return(NULL);
1.23 takayama 645: }
646:
647: if (passControl != NULL) {
648: if (v) fprintf(stderr,"Sending password %s for the control channel.\n",
649: passControl);
650: if (write(fdControl,passControl,strlen(passControl)+1) < 0) {
651: fprintf(stderr,"oxCreateClient(): failed to send passControl.\n");
652: return(NULL);
653: }
654: }
655: if (passData != NULL) {
656: if (v) fprintf(stderr,"Sending password %s for the data channel.\n",
657: passData);
658: if (write(fdStream,passData,strlen(passData)+1) < 0) {
659: fprintf(stderr,"oxCreateClient(): failed to send passData.\n");
660: return(NULL);
661: }
1.1 maekawa 662: }
663:
664: controlByteOrder = oxSetByteOrder(fdControl);
665: if (v) fprintf(stderr,"Byte order for control process is %s.\n",
1.9 takayama 666: (controlByteOrder == 0? "network byte order":
667: (controlByteOrder == 1? "little indican":
668: "big indian")));
1.1 maekawa 669: engineByteOrder = oxSetByteOrder(fdStream);
670: if (v) fprintf(stderr,"Byte order for engine process is %s.\n",
1.9 takayama 671: (engineByteOrder == 0? "network byte order":
672: (engineByteOrder == 1? "little indican":
673: "big indian")));
1.1 maekawa 674:
675: client = (oxclientp) mymalloc(sizeof(oxclient));
676: oxInitClient(client);
677: client->datafp2 = fp2open(fdStream);
678: if (client->datafp2 == NULL) {
679: fprintf(stderr,"oxCreateClient(): fp2open(fd) failed.\n");
680: return(NULL);
681: }
682: client->dataport = portStream;
683: client->controlport = portControl;
684: client->controlfd = fdControl;
1.13 takayama 685: client->id = oxGetClientID();
1.1 maekawa 686: client->type = CLIENT_SOCKET; /* socket */
687: client->engineByteOrder = engineByteOrder;
688: client->controlByteOrder = controlByteOrder;
689: return(client);
690: }
691:
692: oxclientp oxCreateClientFile(char *fname,char *mode,char *controlName,char *cmode)
693: {
694: static int clnum = 0x8000;
695: int v = 0;
696: int fdControl = -1;
697: int fdStream = -1;
698: oxclientp client;
699: v = 1;
700: if (strcmp(mode,"w") == 0) {
701: fdStream = creat(fname,S_IWRITE|S_IREAD|S_IRGRP|S_IROTH);
702: if (fdStream < 0) {
703: fprintf(stderr,"\nCreat failed for %s\n",fname); return(NULL);
704: }
705: }else if (strcmp(mode,"r")==0) {
706: fdStream = open(fname,O_RDONLY);
707: if (fdStream < 0) {
708: fprintf(stderr,"\nOpen failed for %s\n",fname); return(NULL);
709: }
710: }else {
711: fprintf(stderr,"\nThe mode %s is not supported.\n",mode); return(NULL);
712: }
713:
714: if (strcmp(cmode,"w") == 0) {
715: fdControl = creat(controlName,S_IWRITE|S_IREAD|S_IRGRP|S_IROTH);
716: if (fdControl < 0) {
717: fprintf(stderr,"\nCreat failed for %s\n",controlName); return(NULL);
718: }
719: }else if (strcmp(cmode,"r")==0) {
720: fdControl = open(controlName,O_RDONLY);
721: if (fdControl < 0) {
722: fprintf(stderr,"\nOpen failed for %s\n",controlName); return(NULL);
723: }
724: }else if (strcmp(cmode,"rw")==0) {
725: fdControl = open(controlName,O_RDWR);
726: if (fdControl < 0) {
727: fprintf(stderr,"\nOpen failed for %s\n",controlName); return(NULL);
728: }
729: }else {
730: fprintf(stderr,"\nThe mode %s is not supported.\n",cmode); return(NULL);
731: }
732:
733:
734: client = (oxclientp) mymalloc(sizeof(oxclient));
735: oxInitClient(client);
736: client->datafp2 = fp2open(fdStream);
737: if (client->datafp2 == NULL) {
738: fprintf(stderr,"oxCreateClientFile(): fp2open(fd) failed.\n");
739: return(NULL);
740: }
741: client->dataport = 0;
742: client->controlport = 0;
743: client->controlfd = fdControl;
744: client->id = clnum; clnum++;
745: client->type = CLIENT_FILE;
746: client->engineByteOrder = OX_BYTE_NETWORK_BYTE_ORDER;
747: client->controlByteOrder = OX_BYTE_NETWORK_BYTE_ORDER;
748: return(client);
749: }
750:
751: void oxSendOXheader_generic(int type,int fd,ox_stream ox,
1.9 takayama 752: int k,int serial)
1.1 maekawa 753: {
754: static int ss = 0;
755: extern int UseOXPacketSerial;
756: if (serial >= 0) ss = serial;
757: else ss++;
758: if (ss < 0) ss=0;
759: if (type == 0) { /* fd */
760: oxfdSendInt32(fd,k);
761: if (UseOXPacketSerial) oxfdSendInt32(fd,ss);
762: }else {
763: oxSendInt32(ox,k);
764: if (UseOXPacketSerial) oxSendInt32(ox,ss);
765: }
766: }
767: void oxSendOXheader(ox_stream ostream,int k,int serial) {
768: oxSendOXheader_generic(1,-1,ostream,k,serial);
769: }
770: void oxfdSendOXheader(int fd,int k,int serial) {
771: oxSendOXheader_generic(0,fd,(ox_stream) NULL,k,serial);
772: }
773:
774: int oxfdGetOXheader(int fd,int *sss)
775: {
776: char d[4];
777: int i;
778: int m;
779:
780: for (i=0; i<4; i++) {
781: d[i] = readOneByte(fd);
782: }
783: m = ntohl(* ( (int *)d));
784: *sss = -1;
785: if (UseOXPacketSerial) {
786: for (i=0; i<4; i++) {
787: d[i] = readOneByte(fd);
788: }
789: *sss = ntohl(* ( (int *)d));
790: }
791: return(m);
792: }
793:
794: int oxGetOXheader(ox_stream ostream,int *sss)
795: {
796: char d[4];
797: int m;
798: int i;
799:
800: unlockCtrlCForOx(); /* temporary unlock */
801: while (fp2select(ostream,1000) == 0) ;
802: restoreLockCtrlCForOx();
803:
804: for (i=0; i<4; i++) {
805: d[i] = fp2fgetc(ostream);
806: }
807: m = ntohl(* ( (int *)d));
808: *sss = -1;
809: if (UseOXPacketSerial) {
810: for (i=0; i<4; i++) {
811: d[i] = fp2fgetc(ostream);
812: }
813: *sss = ntohl(* ( (int *)d));
814: }
815: return(m);
816: }
817:
818:
819: oxWritePortFile(int func,int port,char *fname) {
820: char name[1024];
821: FILE *fp;
822: strcpy(name,fname);
823: if (func == 0) {
824: strcat(name,".control");
825: fp = fopen(name,"w");
826: fprintf(fp,"%05d\n",port);
827: fclose(fp);
828: }else {
829: strcat(name,".data");
830: fp = fopen(name,"w");
831: fprintf(fp,"%05d\n",port);
832: fclose(fp);
833: }
834: }
835: oxReadPortFile(int func,char *fname) {
836: int port = 0;
837: char name[1024];
838: FILE *fp;
839: strcpy(name,fname);
840: if (func == 0) {
841: strcat(name,".control");
842: fp = fopen(name,"r");
843: fscanf(fp,"%d",&port);
844: fclose(fp);
845: }else {
846: strcat(name,".data");
847: fp = fopen(name,"r");
848: fscanf(fp,"%d",&port);
849: fclose(fp);
850: }
851: return(port);
852: }
853: char *oxGenPortFile(void) {
854: char *fname;
855: time_t tt;
856: char sstime[512];
857:
858: fname = (char *)malloc(1024*sizeof(char));
859: strcpy(fname,getenv("HOME"));
860: strcat(fname,"/.ox.");
861: tt = time(NULL);
862: sprintf(sstime,"%ld",(long) tt);
863: strcat(fname,sstime);
864: if (fname[strlen(fname)-1] == '\n') {
865: fname[strlen(fname)-1] = '\0';
866: }
867: /* fprintf(stderr,"OxPortFileName=%s\n",fname); */
868: OxPortFileName = fname;
869: return(fname);
870: }
871: int oxRemovePortFile(void) {
872: char fname[1024];
873: FILE *fp;
1.5 takayama 874: SET_MYERROROUT;
1.1 maekawa 875: strcpy(fname,OxPortFileName);
876: strcat(fname,".control");
877: if ((fp=fopen(fname,"r")) == NULL) {
878: }{
879: fclose(fp);
880: if (unlink(fname)) {
881: fprintf(MyErrorOut,"fail unlink.\n");
882: }
883:
884: }
885: strcpy(fname,OxPortFileName);
886: strcat(fname,".data");
887: if ((fp=fopen(fname,"r")) == NULL) {
888: }{
889: fclose(fp);
890: if (unlink(fname)) {
891: fprintf(MyErrorOut,"fail unlink.\n");
892: }
893: }
894: }
895:
896: char *oxGenPass(void) {
1.3 takayama 897: static int seed = 0;
1.1 maekawa 898: long p;
899: char *s;
1.21 takayama 900: int i,n;
1.3 takayama 901: if (seed == 0) {
902: seed = (int) time(NULL) + (int) &p;
903: srandom((unsigned int) seed);
904: }
1.21 takayama 905: s = (char *)malloc(128*sizeof(char));
906: if (s == NULL) { fprintf(stderr,"No more memory.\n"); return(s); }
907: n = (((int) s) + (int) time(NULL)) % 100;
908: for (i=0; i < n ; i++) random();
1.1 maekawa 909: p = random();
910: sprintf(s,"%ld",p);
911: return(s);
912: }
913:
914:
915: static void cancelConnection() {
1.12 takayama 916: #if defined(__CYGWIN__)
917: extern sigjmp_buf MyEnv_oxmisc;
918: #else
1.1 maekawa 919: extern jmp_buf MyEnv_oxmisc;
1.12 takayama 920: #endif
1.1 maekawa 921: signal(SIGALRM,SIG_IGN);
922: fprintf(stderr,"Time out in TCP/IP connection.\n");
1.12 takayama 923: #if defined(__CYGWIN__)
924: siglongjmp(MyEnv_oxmisc,1);
925: #else
1.1 maekawa 926: longjmp(MyEnv_oxmisc,1);
1.12 takayama 927: #endif
1.1 maekawa 928: }
929:
930: oxclientp oxCreateClient2(int fdstream,int portStream,
1.22 takayama 931: int fdcontrol,int portControl,int ipmask,
932: char *passControl, char *passData)
1.1 maekawa 933: {
934: int v = 0;
935: int fdControl = -1;
936: int fdStream = -1;
937: int m;
938:
939: char *s;
940: oxclientp client;
1.12 takayama 941: #if defined(__CYGWIN__)
942: extern sigjmp_buf MyEnv_oxmisc;
943: #else
944: extern jmp_buf MyEnv_oxmisc;
945: #endif
1.1 maekawa 946: int controlByteOrder, engineByteOrder;
947:
948: v = !Quiet;
1.12 takayama 949: #if defined(__CYGWIN__)
950: if (sigsetjmp(MyEnv_oxmisc,1)) {
951: #else
1.1 maekawa 952: if (setjmp(MyEnv_oxmisc)) {
1.12 takayama 953: #endif
1.1 maekawa 954: return(NULL);
955: }else{
956: }
1.11 takayama 957: alarm((unsigned int) 20); /* setup timeout. */
1.1 maekawa 958: signal(SIGALRM,cancelConnection);
959:
960: switch(ipmask) {
961: case 0:/* only local */
962: fdControl = socketAcceptLocal(fdcontrol);
963: fdStream = socketAcceptLocal(fdstream);
964: break;
965: default:/* any */
966: fdControl = socketAccept(fdcontrol);
967: fdStream = socketAccept(fdstream);
968: break;
969: }
970: if (v) fprintf(stderr,"\nControl port %d : Connected.\n",portControl);
971: if (v) fprintf(stderr,"\nStream port %d : Connected.\n",portStream);
972:
973: if (fdStream == -1 || fdControl == -1) {
1.16 takayama 974: fprintf(stderr,"\nOpen error in oxCreateClient2.\n");
975: fprintf(stderr,"fdStream=%d, fdControl=%d\n",fdStream,fdControl);
1.1 maekawa 976: return(NULL);
977: }
978:
1.6 takayama 979: /* Authentication by password. */
1.22 takayama 980: m = strlen(passControl)+strlen(passData);
1.10 takayama 981: if (m > 0) {
982: s = (char *)mymalloc(sizeof(char)*(m+1));
1.22 takayama 983: m = strlen(passControl); s[0] = 0;
1.10 takayama 984: read(fdControl,s,m+1); s[m] = '\0';
1.22 takayama 985: if (strcmp(s,passControl) != 0) {
986: fprintf(stderr,"s=%s, passControl=%s\n",s,passControl);
1.10 takayama 987: fprintf(stderr,"oxCreateClient2(): password authentication failed for control channel.\n");
988: close(fdControl);
989: return(NULL);
990: }
1.22 takayama 991: m = strlen(passData); s[0] = 0;
1.10 takayama 992: read(fdStream,s,m+1); s[m] = '\0';
1.22 takayama 993: if (strcmp(s,passData) != 0) {
994: fprintf(stderr,"s=%s, passData=%s\n",s,passData);
1.10 takayama 995: fprintf(stderr,"oxCreateClient2(): password authentication failed for data channel.\n");
996: close(fdStream);
997: return(NULL);
998: }
1.1 maekawa 999: }
1000: signal(SIGALRM,SIG_IGN);
1001:
1002: controlByteOrder = oxSetByteOrder(fdControl);
1003: if (v) fprintf(stderr,"Byte order for control process is %s.\n",
1.9 takayama 1004: (controlByteOrder == 0? "network byte order":
1005: (controlByteOrder == 1? "little indican":
1006: "big indian")));
1.1 maekawa 1007: engineByteOrder = oxSetByteOrder(fdStream);
1008: if (v) fprintf(stderr,"Byte order for engine process is %s.\n",
1.9 takayama 1009: (engineByteOrder == 0? "network byte order":
1010: (engineByteOrder == 1? "little indican":
1011: "big indian")));
1.1 maekawa 1012:
1013:
1014: client = (oxclientp) mymalloc(sizeof(oxclient));
1015: oxInitClient(client);
1016: client->datafp2 = fp2open(fdStream);
1017: if (client->datafp2 == NULL) {
1018: fprintf(stderr,"oxCreateClient2(): fp2open(fd) failed.\n");
1019: return(NULL);
1020: }
1021: client->dataport = portStream;
1022: client->controlport = portControl;
1023: client->controlfd = fdControl;
1.13 takayama 1024: client->id = oxGetClientID();
1.1 maekawa 1025: client->type = CLIENT_SOCKET; /* socket */
1026: client->engineByteOrder = engineByteOrder;
1027: client->controlByteOrder = controlByteOrder;
1028: return(client);
1029: }
1030:
1031: int oxSetByteOrder(int fd) {
1032: char data[1];
1033: int peertype;
1034: /* It is for client. read and next write. */
1035: /* oxSocketSelect0(fd,10); wait. */
1036: read(fd,data,1);
1037: peertype = (unsigned char) data[0];
1038:
1039: /* We support only Network byte order */
1040: data[0] = OX_BYTE_NETWORK_BYTE_ORDER;
1041: write(fd,data,1);
1042:
1043: return(OX_BYTE_NETWORK_BYTE_ORDER);
1044: }
1045:
1.17 takayama 1046: int oxTellMyByteOrder(int fdOut, int fdIn) {
1.1 maekawa 1047: char data[1];
1048: int peertype;
1049: /* It is for server. read and next write. */
1050:
1051: /* We support only Network byte order */
1052: data[0] = OX_BYTE_NETWORK_BYTE_ORDER;
1.17 takayama 1053: write(fdOut,data,1);
1054: fsync(fdOut); /* returns 0 if normal. Does it work for socket? */
1.1 maekawa 1055:
1.17 takayama 1056: read(fdIn,data,1); /* Read pear's byte order */
1.1 maekawa 1057:
1058: return(OX_BYTE_NETWORK_BYTE_ORDER);
1059: }
1060:
1061:
1.14 takayama 1062: struct object OxClientList[MAX_N_OF_CLIENT];
1063: int OxClientListn = 0;
1064:
1065: int oxGetClientID() {
1066: extern struct object OxClientList[];
1067: extern int OxClientListn;
1068: extern struct object Nobj;
1069: int i;
1070: for (i=0; i<OxClientListn; i++) {
1071: if ((OxClientList[i]).tag == Snull) {
1072: return i;
1073: }
1074: }
1075: i = OxClientListn;
1076: (OxClientList[i]).tag = Snull;
1077: if (OxClientListn < MAX_N_OF_CLIENT-1) {
1078: OxClientListn++;
1079: return i;
1080: }else{
1081: fprintf(MyErrorOut,"oxGetClientID(): the client table is full. Returns ID = 0.\n");
1082: return 0;
1083: }
1084: }
1.1 maekawa 1085:
1.18 takayama 1086: char *oxFIDtoStr(int id) {
1087: switch( id ) {
1088: case SM_mathcap:
1089: return "SM_mathcap"; break;
1090: case SM_setMathCap:
1091: return "SM_setMathCap"; break;
1092: case SM_pops:
1093: return "SM_pops"; break;
1094: case SM_getsp:
1095: return "SM_getsp"; break;
1096: case SM_dupErrors:
1097: return "SM_dupErrors"; break;
1098: case SM_pushCMOtag:
1099: return "SM_pushCMOtag"; break;
1100: case SM_setName:
1101: return "SM_setName"; break;
1102: case SM_evalName:
1103: return "SM_evalName"; break;
1104: case SM_executeStringByLocalParser:
1105: return "SM_executeStringByLocalParser"; break;
1106: case SM_executeFunction:
1107: return "SM_executeFunction"; break;
1.20 takayama 1108: case SM_executeFunctionWithOptionalArgument:
1109: return "SM_executeFunctionWithOptionalArgument"; break;
1.18 takayama 1110: case SM_popCMO:
1111: return "SM_popCMO"; break;
1112: case SM_popString:
1113: return "SM_popString"; break;
1114: case SM_shutdown:
1115: return "SM_shutdown"; break;
1116: case SM_beginBlock:
1117: return "SM_beginBlock"; break;
1118: case SM_endBlock:
1119: return "SM_endBlock"; break;
1120: default:
1121: return "Unknown to oxFIDtoStr"; break;
1122: }
1123: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>