Annotation of OpenXM/src/kxx/oxmain.c, Revision 1.22
1.22 ! takayama 1: /* $OpenXM: OpenXM/src/kxx/oxmain.c,v 1.21 2005/02/28 12:53:44 takayama Exp $ */
1.1 maekawa 2: /* nullserver01 */
3: #include <stdio.h>
1.4 takayama 4: #include <fcntl.h>
1.10 takayama 5: #include <unistd.h>
1.1 maekawa 6: #include <sys/types.h>
7: #include <sys/socket.h>
8: #include <sys/time.h>
9: #include <netinet/in.h>
10: #include <netdb.h>
11: #include <signal.h>
12: #include <setjmp.h>
1.14 takayama 13: #include <stdlib.h>
1.1 maekawa 14: /* -lnsl -lsocket /usr/ucblib/libucb.a */
15: #include "ox_kan.h"
16: #include "serversm.h"
17:
1.4 takayama 18: #define SERVERNAME "ox_sm1"
1.1 maekawa 19:
1.14 takayama 20: extern char **environ;
1.1 maekawa 21: int OxCritical = 0;
22: int OxInterruptFlag = 0;
1.12 takayama 23: int OxTerminateMode = 0;
1.1 maekawa 24:
25: int SerialCurrentControl;
26:
27: int MyServerPid;
1.4 takayama 28: #define SERVERNAME_SIZE 4096
29: char ServerName[SERVERNAME_SIZE];
1.1 maekawa 30: int PacketMonitor = 0;
31: int Quiet = 0;
32:
33: int LocalMode = 1;
34: int NotifyPortnumber = 0;
1.4 takayama 35: int Do_not_use_control_stream_to_tell_no_server = 1;
36: static void errorToStartEngine(void);
37: static int findOxServer(char *server);
38: static void couldNotFind(char *s);
1.8 takayama 39: /* gcc -v -c hoge.c */
1.21 takayama 40: static void mywait();
1.15 takayama 41:
42: void *sGC_malloc(int n) {
43: return (void *)malloc(n);
44: }
1.1 maekawa 45:
46: main(int argc, char *argv[]) {
47: int fd;
48: int size;
49: char sname[1024];
50: int tmp[1];
51: char *buf;
52: int i;
53: int fdControl = -1; int portControl = 1200;
54: int fdStream = -1; int portStream = 1300;
55: int reverse = 0;
56: extern int OpenedSocket;
57: char portfile[1024];
1.12 takayama 58: char *pass = NULL;
1.18 takayama 59: char *passControl = NULL;
60: char *passData = NULL;
1.4 takayama 61: int result;
1.9 takayama 62: int sleepingTime = 0;
1.22 ! takayama 63: int authEncoding=0;
! 64: FILE *fp;
! 65: char *stmp;
1.12 takayama 66: extern int OxTerminateMode;
1.1 maekawa 67:
1.17 takayama 68: signal(SIGHUP,SIG_IGN); /* ignore x of xterm */
1.1 maekawa 69: strcpy(sname,"localhost");
70: strcpy(ServerName,SERVERNAME);
71: i = 1;
1.2 takayama 72: if (argc == 1) {
73: oxmainUsage();
1.12 takayama 74: exit(10);
1.2 takayama 75: }
1.1 maekawa 76: while (i<argc) {
77: if (strcmp(argv[i],"-host") == 0) {
78: i++;
79: if (i<argc) strcpy(sname,argv[i]);
80: }else if (strcmp(argv[i],"-data")==0) {
81: i++;
82: if (i<argc) sscanf(argv[i],"%d",&portStream);
83: }else if (strcmp(argv[i],"-control")==0) {
84: i++;
85: if (i<argc) sscanf(argv[i],"%d",&portControl);
86: }else if (strcmp(argv[i],"-ox") == 0) {
87: i++;
88: if (i<argc) strcpy(ServerName,argv[i]);
89: }else if (strcmp(argv[i],"-monitor") == 0) {
90: PacketMonitor = 1;
91: }else if (strcmp(argv[i],"-insecure") == 0) {
92: LocalMode = 0;
93: }else if (strcmp(argv[i],"-reverse") == 0) {
94: reverse = 1;
1.12 takayama 95: }else if (strcmp(argv[i],"-finish") == 0) {
96: OxTerminateMode = 1;
1.1 maekawa 97: }else if (strcmp(argv[i],"-portfile") == 0) {
98: i++;
99: if (i<argc) {
1.7 takayama 100: sscanf(argv[i],"%s",portfile);
101: portControl = 0;
102: portStream = 0;
103: NotifyPortnumber = 1;
1.1 maekawa 104: }
105: }else if (strcmp(argv[i],"-pass") == 0) {
106: i++;
107: if (i<argc) {
1.7 takayama 108: pass = argv[i];
1.1 maekawa 109: }
1.18 takayama 110: }else if (strcmp(argv[i],"-passData") == 0) {
111: i++;
112: if (i<argc) {
113: passData = argv[i];
114: }
115: }else if (strcmp(argv[i],"-passControl") == 0) {
116: i++;
117: if (i<argc) {
118: passControl = argv[i];
119: }
1.9 takayama 120: }else if (strcmp(argv[i],"-wait") == 0) {
121: i++;
122: if (i<argc) {
123: sscanf(argv[i],"%d",&sleepingTime);
124: }
1.22 ! takayama 125: }else if (strcmp(argv[i],"-authEncoding") == 0) {
! 126: i++;
! 127: if (strcmp(argv[i],"file") == 0) {
! 128: authEncoding = 1;
! 129: }else{
! 130: fprintf(stderr,"Unknown -authEncoding %s.\n",argv[i]);
! 131: oxmainUsage(); exit(10);
! 132: }
1.1 maekawa 133: }else {
134: fprintf(stderr,"Unknown option %s.\n",argv[i]);
135: oxmainUsage(); exit(10);
136: }
137: i++;
138: }
139:
1.4 takayama 140: if (Do_not_use_control_stream_to_tell_no_server) {
1.7 takayama 141: if (findOxServer(ServerName) < 0) {
142: fprintf(stderr,"Sleeping five seconds...\n");
143: sleep(5);
144: exit(-1);
145: }
1.9 takayama 146: }
147:
148: if (sleepingTime) {
149: fprintf(stderr,"Waiting to connect for %d seconds...\n",sleepingTime);
150: sleep(sleepingTime);
151: fprintf(stderr,"\nTrying to connect\n");
1.4 takayama 152: }
153:
1.18 takayama 154: if ((pass != NULL) && (passData == NULL)) {
155: passData = pass;
156: }
157: if ((pass != NULL) && (passControl == NULL)) {
158: passControl = pass;
159: }
160:
1.19 takayama 161: /* Decrypt passControl and passData, here. Lookup cryptmethod. */
1.22 ! takayama 162: if (authEncoding == 1) {
! 163: stmp = (char *)sGC_malloc(strlen(getenv("HOME"))+strlen(passControl)+
! 164: strlen(passData)+128);
! 165: sprintf(stmp,"%s/.openxm/tmp.opt/%s",(char *)getenv("HOME"),passControl);
! 166: fp = fopen(stmp,"r");
! 167: if (fp == NULL) { fprintf(stderr,"passControl file %s is not found.\n",stmp); exit(1);}
! 168: fgets(stmp,127,fp); passControl = stmp; fclose(fp);
! 169:
! 170: stmp = (char *)sGC_malloc(strlen(getenv("HOME"))+strlen(passControl)+
! 171: strlen(passData)+128);
! 172: sprintf(stmp,"%s/.openxm/tmp.opt/%s",(char *)getenv("HOME"),passData);
! 173: fp = fopen(stmp,"r");
! 174: if (fp == NULL) { fprintf(stderr,"passData file %s is not found.\n",stmp); exit(1);}
! 175: fgets(stmp,127,fp); passData = stmp; fclose(fp);
! 176: }
1.19 takayama 177:
1.1 maekawa 178: if (reverse) {
179: /* The order is very important. */
1.18 takayama 180: fdControl = socketConnectWithPass(sname,portControl,passControl);
181: fdStream = socketConnectWithPass(sname,portStream,passData);
1.1 maekawa 182:
183: fprintf(stderr,"Connected: control = %d, data = %d.\n",fdControl,fdStream);
1.7 takayama 184: result = 0;
1.5 takayama 185:
186:
1.20 takayama 187: if ((fdControl < 0) || (fdStream < 0)) {
188: fprintf(stderr,"Waiting for 10 seconds to show an error.\n");
189: sleep(10);
190: }
191:
1.1 maekawa 192: if (portControl != -1) {
193: MyServerPid = fork();
194: if (MyServerPid > 0 ) parentServerMain(fdControl,fdStream);
1.4 takayama 195: else result=childServerMain(fdControl,fdStream);
1.1 maekawa 196: }else{
1.4 takayama 197: result=childServerMain(fdControl,fdStream);
1.1 maekawa 198: }
1.4 takayama 199: /* This line will be never executed in case of success */
1.7 takayama 200: if (result < 0 ) {
201: errorToStartEngine();
202: }
1.1 maekawa 203: }
204:
205: /* non-reverse case. */
206: fprintf(stderr,"Hostname is %s \n",sname);
207: fprintf(stderr,"Port for data (-data) = %d \n",portStream);
208: fprintf(stderr,"Port for control message (-control) = %d \n",portControl);
209: fflush(NULL);
210:
211:
212: if (LocalMode) {
213: if (portControl != -1) {
214: fdControl = socketOpen(sname,portControl);
215: portControl = OpenedSocket;
216: if (NotifyPortnumber) {
1.7 takayama 217: oxWritePortFile(0,portControl,portfile);
1.1 maekawa 218: }
219: fdControl = socketAcceptLocal(fdControl);
220: fprintf(stderr,"\n control port %d : Connected.\n",portControl);
221: }
222: if (portStream != -1) {
223: fdStream = socketOpen(sname,portStream);
224: portStream = OpenedSocket;
225: if (NotifyPortnumber) {
1.7 takayama 226: oxWritePortFile(1,portStream,portfile);
1.1 maekawa 227: }
228: fdStream = socketAcceptLocal(fdStream);
229: fprintf(stderr,"\n stream port %d : Connected.\n",portStream);
230: }
231: }else{
232: if (portControl != -1) {
233: fdControl = socketOpen(sname,portControl);
234: portControl = OpenedSocket;
235: if (NotifyPortnumber) {
1.7 takayama 236: oxWritePortFile(0,portControl,portfile);
1.1 maekawa 237: }
238: fdControl = socketAccept(fdControl);
239: fprintf(stderr,"\n control port %d : Connected.\n",portControl);
240: }
241: if (portStream != -1) {
242: fdStream = socketOpen(sname,portStream);
243: portStream = OpenedSocket;
244: if (NotifyPortnumber) {
1.7 takayama 245: oxWritePortFile(1,portStream,portfile);
1.1 maekawa 246: }
247: fdStream = socketAccept(fdStream);
248: fprintf(stderr,"\n stream port %d : Connected.\n",portStream);
249: }
250: }
251:
1.19 takayama 252: if (passControl != NULL) {
253: char *s; int mm;
254: fprintf(stderr,"passControl\n");
255: mm = strlen(passControl);
256: s = (char *) malloc(mm+1);
257: if (s == NULL) {fprintf(stderr,"No more memory.\n"); exit(1); }
258: if (read(fdControl,s,mm+1) < 0) {
259: fprintf(stderr,"Read error to read passControl\n"); sleep(5); exit(1);
260: }
261: s[mm] = 0;
262: if (strcmp(s,passControl) != 0) {
263: fprintf(stderr,"s=%s and passControl=%s do not match.\n",s,passControl); sleep(5); exit(1);
264: }
265: free(s);
266: }
267: if (passData != NULL) {
268: char *s; int mm;
269: mm = strlen(passData);
270: fprintf(stderr,"passData\n");
271: s = (char *) malloc(mm+1);
272: if (s == NULL) {fprintf(stderr,"No more memory.\n"); exit(1); }
273: if (read(fdStream,s,mm+1) < 0) {
274: fprintf(stderr,"Read error to read passData\n");
275: errorToStartEngine();
276: }
277: if (strcmp(s,passData) != 0) {
278: fprintf(stderr,"s=%s and passData=%s do not match.\n",s,passData);
279: errorToStartEngine();
280: }
281: free(s);
282: }
1.1 maekawa 283:
1.20 takayama 284: if ((fdControl < 0) || (fdStream < 0)) {
285: fprintf(stderr,"Waiting for 10 seconds to show an error.\n");
286: sleep(10);
287: }
288:
289:
1.4 takayama 290: result = 0;
1.1 maekawa 291: if (portControl != -1) {
292: MyServerPid = fork();
293: if (MyServerPid > 0 ) parentServerMain(fdControl,fdStream);
1.4 takayama 294: else result = childServerMain(fdControl,fdStream);
1.1 maekawa 295: }else{
1.4 takayama 296: result = childServerMain(fdControl,fdStream);
1.1 maekawa 297: }
1.4 takayama 298: if (result < 0) errorToStartEngine();
299: }
1.1 maekawa 300:
1.4 takayama 301: static void errorToStartEngine(void) {
302: fprintf(stderr,"Failed to start the engine. Childing process is terminating.\n");
303: /* You have to tell to the control server that there is no engine.
1.7 takayama 304: And, the control server must tell the client that there is no
305: engine.
306: This part has not yet been implemented.
307: If you implement this, set Do_not_use_control_stream_to_tell_no_server to
308: zero.
309: */
1.20 takayama 310: sleep(10);
1.4 takayama 311: exit(-1);
1.1 maekawa 312: }
313:
314: oxmainUsage() {
315: fprintf(stderr,"Usage: \n");
316: fprintf(stderr," ox [-ox serverprogram -host name -data portnum -control portnum -monitor]\n");
1.18 takayama 317: fprintf(stderr," [-insecure -portfile fname -reverse -passControl xxxyyyzzz -passData pppqqqrrr]");
1.12 takayama 318: fprintf(stderr," [-finish]");
1.1 maekawa 319: fprintf(stderr,"\n");
1.2 takayama 320: fprintf(stderr,"-reverse: ox server connects to the client.\n");
1.18 takayama 321: fprintf(stderr," The client must give a one time password to ox server to connect to the client with -pass* option.\n");
1.2 takayama 322: fprintf(stderr," The one time password can be seen by ps command, so you must not use this one time password system on an untrustful host.\n");
323: fprintf(stderr," The one time password should be sent by a safe communication line like ssh and the ox server should be started by ssh. Do not use rsh\n");
1.18 takayama 324: fprintf(stderr," (The option -pass is obsolete.)\n");
1.2 takayama 325: fprintf(stderr," If -reverse is not given, the client connect to the ox server\n");
326: fprintf(stderr," See OpenXM/src/SSkan/Doc/ox.sm1, /sm1connectr\n");
327: fprintf(stderr,"-insecure : \n");
328: fprintf(stderr," If you access to the server from a localhost, you do not need one time password. However, if you access outside of the localhost, a one time password is required. To turn off this restriction, -insecure option is used.\n");
1.4 takayama 329: fprintf(stderr,"\n");
330: fprintf(stderr,"If ox fails to find the serverprogram, it tries to look for it in /usr/local/OpenXM/bin and $OpenXM_HOME/bin.\n");
331: fprintf(stderr,"\n");
1.2 takayama 332: fprintf(stderr,"Example 1:\n");
1.3 takayama 333: fprintf(stderr,"(Start the ox server): dc1%% ox -ox ~/OpenXM/bin/ox_sm1 -host dc1.math.kobe-u.ac.jp -insecure -control 1200 -data 1300\n");
1.2 takayama 334: fprintf(stderr,"(client): sm1\n ");
335: fprintf(stderr," (ox.sm1) run ; \n");
1.1 maekawa 336: fprintf(stderr," sm1>[(dc1.math.kobe-u.ac.jp) 1300 1200] oxconnect /ox.ccc set\n");
1.2 takayama 337: fprintf(stderr,"Example 2:\n");
338: fprintf(stderr,"(Start the ox server): dc1%% ox -ox ~/OpenXM/bin/ox_sm1\n");
339: fprintf(stderr,"(client): dc1%% sm1\n ");
340: fprintf(stderr," (ox.sm1) run ; \n");
341: fprintf(stderr," sm1>[(localhost) 1300 1200] oxconnect /ox.ccc set\n");
1.1 maekawa 342: fprintf(stderr,"\n");
343: }
344:
345: parentServerMain(int fdControl, int fdStream) {
346: int id;
347: int mtag;
348: int size;
349: int n;
350: int r;
351: int message = 1;
352: int controlByteOrder;
1.12 takayama 353: extern OxTerminateMode;
1.1 maekawa 354: extern void myServerExit();
355:
1.21 takayama 356: signal(SIGCHLD,mywait);
1.12 takayama 357: if (OxTerminateMode) {
358: /*
359: OxTerminateMode cannot be used if you run ox by xterm -exec ox ...
360: */
361: if (fork()) {
362: close(fdControl); close(fdStream);
363: /* Parent */
364: exit(0); /*Tell the caller that launching is successfully finished.*/
365: }
366: }
367:
1.13 takayama 368: controlByteOrder = oxTellMyByteOrder(fdControl,fdControl);
1.1 maekawa 369: /* Set the network byte order. */
370: fprintf(stderr,"controlByteOrder=%x\n",controlByteOrder);
371:
372:
373: signal(SIGINT,myServerExit);
374: while(1) {
375: mtag = oxfdGetOXheader(fdControl,&SerialCurrentControl);
376: /* get the message_tag */
377: /* message_body */
378: id = oxfdGetInt32(fdControl); /* get the function_id */
379: if (message) {printf("\n[control] control function_id is %d\n",id);}
380: switch( id ) {
381: case SM_control_kill:
382: if (message) printf("[control] control_kill\n");
383: oxSendResultOfControl(fdControl);
384: sleep(2);
385: myServerExit();
386: break;
387: case SM_control_reset_connection:
388: if (message) printf("[control] control_reset_connection.\n");
389: if (message) printf("Sending the SIGUSR1 signal to %d: ",MyServerPid);
390: r=kill(MyServerPid,SIGUSR1);
391: if (message) printf("Result = %d\n",r);
392: fflush(NULL);
1.7 takayama 393: /* oxSendResultOfControlInt32(fdControl,0); */
1.1 maekawa 394: break;
395: default:
396: fprintf(stderr,"[control] Unknown control message.\n");
397: fprintf(stderr,"Shutdown the server.");
398: myServerExit();
399: break;
400: }
401: }
402: }
403:
404: void myServerExit() {
405: printf("Sending the kill signal to the child.\n");
406: kill(MyServerPid,SIGKILL);
1.12 takayama 407: exit(0);
1.1 maekawa 408: }
409:
410: childServerMain(int fdControl, int fdStream) {
411: int i;
412: close(fdControl); /* close(0); dup(fdStream); */
413: dup2(fdStream,3);
414: dup2(fdStream,4);
1.4 takayama 415: /*close(0);
1.7 takayama 416: #include <sys/param.h>
417: for (i=5; i<NOFILE; i++) close(i);
418: */
1.4 takayama 419: if (!Do_not_use_control_stream_to_tell_no_server) {
1.7 takayama 420: if (findOxServer(ServerName) < 0) {
421: return(-1);
422: }
1.4 takayama 423: }
1.5 takayama 424: fprintf(stderr,"childServerMain: Starting the server %s\n",ServerName); fflush(NULL);
1.14 takayama 425:
426: /*
427: {
428: int i;
429: i=0;
430: while (environ[i] != NULL) {
431: fprintf(stderr,"%s ",environ[i++]);
432: }
433: fprintf(stderr,"\n");
434: }
435: */
436: /* bug: xterm of potato does not seem to pass the LD_LIBRARY_PATH.
437: So, the new gc does not work.
438: it is an workaround for OpenXM */
439: if (getenv("LD_LIBRARY_PATH") == (char *)NULL) {
440: char *s,*o;
441: fprintf(stderr,"Hmm... LD_LIBRARY_PATH does not seem to be set.\n");
442: o = getenv("OpenXM_HOME");
443: if (o == NULL) {
444: fprintf(stderr,"Giving up to set the LD_LIBRARY_PATH variable.\n");
445: }else{
446: s = (char *)malloc(strlen(o)+64);
447: sprintf(s,"LD_LIBRARY_PATH=%s/lib",o);
448: putenv(s);
449: }
450: }
451:
1.1 maekawa 452: if (PacketMonitor) {
1.14 takayama 453: if (execle(ServerName,ServerName,"-monitor",NULL,environ)) {
1.1 maekawa 454: fprintf(stderr,"%s cannot be executed with -monitor.\n",ServerName);
1.7 takayama 455: fflush(NULL);
456: return(-1);
1.1 maekawa 457: }
458: }else {
1.14 takayama 459: if (execle(ServerName,ServerName,NULL,environ)) {
1.1 maekawa 460: fprintf(stderr,"%s cannot be executed.\n",ServerName);
1.7 takayama 461: fflush(NULL);
462: return(-1);
1.1 maekawa 463: }
464: }
1.4 takayama 465: /* never reached. */
1.1 maekawa 466: }
467:
468:
469: /* These are dummy. It is defined in stackmachine.c */
470: unlockCtrlCForOx() { ; }
471: restoreLockCtrlCForOx() { ; }
472:
1.4 takayama 473: static int findOxServer(char *server) {
474: char *p;
475: char *p2;
476: if (strlen(server) == 0) return(-1);
1.10 takayama 477: /* fd = open(server,O_RDONLY); */
1.11 ohara 478: if (access(server,X_OK&R_OK) == 0) {
1.7 takayama 479: fprintf(stderr,"Starting OX server : %s\n",server);
480: return(0);
1.4 takayama 481: }
482: if (server[0] == '/') {
1.7 takayama 483: couldNotFind(server);
484: return(-1);
1.4 takayama 485: }
486: fprintf(stderr,"The server %s was not found. Trying to find it under OpenXM/bin\n",server);
487: p = getenv("OpenXM_HOME");
488: if (p == NULL) {
489: p = "/usr/local/OpenXM";
490: }
491: p2 = (char *) malloc(sizeof(char)*(strlen(p)+strlen("/bin/")+3+strlen(server)));
492: if (p2 == NULL) { fprintf(stderr,"No more memory.\n"); exit(10); }
493: strcpy(p2,p); strcat(p2,"/bin/"); strcat(p2,server);
1.10 takayama 494: /* fd = open(p2,O_RDONLY); */
1.11 ohara 495: if (access(p2,X_OK&R_OK) == 0) {
1.7 takayama 496: fprintf(stderr,"Starting OX server : %s\n",p2);
497: if (strlen(p2) < SERVERNAME_SIZE) strcpy(server,p2);
498: else {
499: couldNotFind("Too long ox server name.");
500: return(-1);
501: }
502: return(0);
1.4 takayama 503: }
504: couldNotFind(p2);
505: return(-1);
506: }
1.1 maekawa 507:
1.4 takayama 508: static void couldNotFind(char *s) {
509: fprintf(stderr,"OX server %s could not be found.\n",s);
510: }
1.1 maekawa 511:
512:
1.21 takayama 513: static void mywait() {
514: int status;
515: int pid;
516: int i,j;
517: /* signal(SIGCHLD,SIG_IGN); */
518: pid = wait(&status);
519: fprintf(stderr,"Control: child process %d is exiting.\n",pid);
520: fprintf(stderr,"Control: Shutting down the control server.\n");
521: sleep(2);
522: exit(0);
523: }
1.1 maekawa 524:
525:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>