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