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