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