Annotation of OpenXM/src/kxx/oxd-thread.c, Revision 1.2
1.1 takayama 1: /*
1.2 ! takayama 2: $OpenXM: OpenXM/src/kxx/oxd-thread.c,v 1.1 2002/11/10 12:15:48 takayama Exp $
1.1 takayama 3: */
4:
5: #include <stdio.h>
6: #include <stdlib.h>
7: #include <fcntl.h>
8: #include <unistd.h>
9: #include <sys/types.h>
10: #include <sys/socket.h>
11: #include <sys/time.h>
12: #include <netinet/in.h>
13: #include <netdb.h>
14: #include <signal.h>
15: #include <setjmp.h>
16: #include <pthread.h>
17: /* -lnsl -lsocket /usr/ucblib/libucb.a */
18: #include "ox_kan.h"
19: #include "serversm.h"
20:
21: /* #define DEBUG */
22:
23: char *getTag(char *s);
24: char *getKeyValue(char *s,char *key);
25: char *getBody(char *s);
26: char *getOpenXMpath(void);
27: void *xtagMalloc(int n);
28: void childServerMain(void *v);
29:
30: #define SERVERNAME_SIZE 4096
31: int Quiet = 0;
32: int Serial = 0;
33:
34: int LocalMode = 1;
35: static int findOxServer(char *server);
36: static void couldNotFind(char *s);
37: #define NOBODY 65534
38:
39: struct threadList {
40: pthread_t thread;
41: struct threadList *next;
42: };
43:
44: struct threadList *newThread() {
45: struct threadList * p;
46: p = (struct threadList *)malloc(sizeof(struct threadList));
47: if (p == NULL) {fprintf(stderr,"No more memory.\n"); exit(10);}
48: p->next = NULL;
49: return p;
50: }
51: main(int argc, char *argv[]) {
52: char sname[1024];
53: int i;
54: int fdControl = -1; int portControl = 8089;
55: extern int OpenedSocket;
56: extern int Serial;
57: int result;
58: int fd;
59: int uid;
60: int fdlist[2];
61: struct threadList *threads;
62: struct threadList root;
63: root.thread = (pthread_t) NULL;
64: root.next = NULL;
65: threads = &root;
66:
67: strcpy(sname,"localhost");
68: i = 1;
69: while (i<argc) {
70: if (strcmp(argv[i],"--port")==0) {
71: i++;
72: if (i<argc) sscanf(argv[i],"%d",&portControl);
73: }else if (strcmp(argv[i],"--insecure") == 0) {
74: LocalMode = 0;
75: }else {
76: fprintf(stderr,"Unknown option %s.\n",argv[i]);
77: oxdUsage(); exit(10);
78: }
79: i++;
80: }
81:
82: uid = getuid();
83: if (uid == 0) {
84: /* If I'm a super user, then change uid to nobody. */
85: if (setuid(NOBODY) != 0) {
86: oxdError("Failed to change uid to nobody (%d)\n",NOBODY);
87: }
88: fprintf(stderr,"uid is changed to nobody (%d).\n",NOBODY);
89: }
90:
91: if (LocalMode) {
92: if (portControl != -1) {
93: fdControl = socketOpen(sname,portControl);
94: if (fdControl < 0) oxdError("Could not open a socket. \n\nPerhaps, oxd is already running on your machine.\nTo start oxd on a different port xyz, start oxd by oxd --port xyz");
95: portControl = OpenedSocket;
96: while (1) {
97: /* fdControl : fd for the wait queue */
98: /* fd : accepted fd */
99: fprintf(stderr,"Waiting a connection... Serial=%d\n",Serial);
100: fflush(NULL);
101: fd = socketAcceptLocal2(fdControl);
102: if (fd < 0) oxdError("Failed to accept.");
103: fprintf(stderr,"\nConnected.\n");
104: Serial++;
105:
106: fdlist[0] = fd; fdlist[1] = 0;
107: fprintf(stderr,"fd (main) = %d\n",fd);
108: threads->next = newThread();
109: threads = threads->next;
110: if (pthread_create(&(threads->thread),
111: NULL,
112: (void *) childServerMain,
113: (void *) &(fdlist[0])) != 0) {
114: perror("Failed in pthread_create"), exit(1);
115: }
116: /* close(fd); */
117: }
118: }
119: threads = root.next;
120: while( threads != (struct threadList *)NULL) {
121: pthread_join(threads->thread,NULL);
122: threads = threads->next;
123: }
124: }else{
125: oxdError("Non-localmode is not supported.");
126: }
127: }
128:
129: oxdUsage() {
130: fprintf(stderr,"Usage: \n");
131: fprintf(stderr," oxd [--port xyz]\n");
132: fprintf(stderr,"\n");
133: }
134:
135: void exitServer(int n) {
136: extern Serial;
137: fprintf(stderr,"\nSerial=%d, Timeout. Exiting.\n",Serial);
138: pthread_exit(0); /* it is still buggy. */
139: }
140: void exitServer2(FILE *fp,char *s) {
141: extern Serial;
142: fprintf(stderr,"\nSerial=%d: %s\n",Serial,s);
143: fprintf(fp,"Error: %s\n",s);
144: fprintf(fp,"Close connection.\n",s);
145: fflush(NULL);
146: fclose(fp);
147: pthread_exit(0);
148: }
149: void childServerMain(void *v) {
150: FILE *fp;
151: #define SIZE 1024
152: char comm[SIZE+2];
153: char *status;
154: int id;
155: char *tag;
156: char *key;
157: char *home;
158: char *body;
159: char fname[SIZE*2];
160: char fnameBody[SIZE];
161: char ccc[SIZE*3];
162: extern int Serial;
163: char *openxm;
164: int resultCode;
165: int st;
166: int fd;
167:
168: fd = ((int *)v)[0];
169: fprintf(stderr,"fd (child) = %d\n",fd);
170: /* Starting oxd session */
171: signal(SIGALRM,exitServer);
172: alarm(60);
173: fp = fdopen(fd,"w+");
174: if (fp == NULL) oxdError("failed fdopen\n");
175:
176: #define GET_COMMAND {\
177: fprintf(fp,"?"); fflush(fp); \
178: status = fgets(comm,SIZE,fp); \
179: if (status == NULL) { \
180: fprintf(stderr,"End of Input.\n"); \
181: exit(0); \
182: } \
183: /* fprintf(fp,"%s\n",comm); fflush(fp);*/ /* Just echo for debugging. */ \
184: fprintf(stderr,"Serial=%d: command=%s\n",Serial,comm); }
185:
186: /* Login */
187: GET_COMMAND ;
188: tag = getTag(comm);
189: if (tag == NULL) {
190: exitServer2(fp,"expecting <login method=\"file\"/>");
191: return;
192: }
193: if (strcmp(tag,"login") != 0) {
194: exitServer2(fp,"expecting <login method=\"file\"/>");
195: return;
196: }
197: key =getKeyValue(comm,"method");
198: if (key == NULL || strcmp(key,"file") != 0) {
199: exitServer2(fp,"expecting <login method=\"file\"/>");
200: return;
201: }
202:
203: /* Out put a challenge. */
204: home = getenv("HOME");
205: if (home == NULL) oxdError("Set the HOME environmental variable.\n");
206: id = Serial*1000+getpid();
207: sprintf(fnameBody,".oxd%d",id);
208: sprintf(fname,"%s/%s",home,fnameBody);
209: fprintf(fp,"<challenge file=\"%s\"/>\n",fname); fflush(fp);
210:
211: /* Wait <done/> */
212: GET_COMMAND ;
213: tag = getTag(comm);
214: if ((tag == NULL) || (strcmp(tag,"done") != 0)) {
215: exitServer2(fp,"expecting <done>");
216: return;
217: }
218: if (access(fname,R_OK) == 0) {
219: sprintf(ccc,"rm -f %s",fname);
220: system(ccc);
221: }else{
222: exitServer2(fp,"Challenge file does not exist.");
223: return;
224: }
225:
226: /* Expect <launch> */
227: GET_COMMAND ;
228: tag = getTag(comm);
229: if ((tag == NULL) || (strcmp(tag,"launch")!=0)) {
230: exitServer2(fp,"expecting <launch> ox -ox ox_asir -reverse -data dport -control cport </launch>");
231: return;
232: }
233:
234: body = getBody(comm);
235: if (strlen(body) > SIZE*2) {
236: exitServer2(fp,"too big body.");
237: return;
238: }
239: openxm = getOpenXMpath();
240: sprintf(ccc,"%s %s &",openxm,body);
241: fprintf(stderr,"Serial=%d : Executing command=%s\n",Serial,ccc);
242: /* Old code.
243: fprintf(fp,"<bye/>\n"); fflush(NULL);
244: fclose(fp);
245: system(ccc);
246: fprintf(stderr,"Serial=%d : The following command is finished : %s\n",Serial,ccc);
247: */
248: /* New code. It requires ox with -finish option. */
249: resultCode = system(ccc);
250: fprintf(stderr,"Serial=%d : The following command is finished : %s, resultCode=%d\n",Serial,ccc,resultCode);
251: if (resultCode == 0) {
252: fprintf(fp,"<suceeded/>\n");
253: }else{
254: fprintf(fp,"<failed code=\"%d\"/>\n",resultCode);
255: }
256:
257: GET_COMMAND /* expect <login/> */
258:
259: fclose(fp); /* close the connection */
260: fprintf(stderr,"Waiting the termination of the child process (ox server).\n");
261: fflush(NULL);
262: wait(&st);
263: fprintf(stderr,"%d: The child process is terminated.\n",Serial);
264: /* exit(0); */
265: }
266:
267: char *getOpenXMpath() {
268: char *s;
269: char *sss;
270: s = getenv("OpenXM_HOME");
271: if (s == NULL) {
272: s = getenv("OPENXM_HOME");
273: }
274: if (s == NULL) sss="/usr/local/bin/openxm";
275: else {
276: sss = (char *) xtagMalloc(strlen(s)+20);
277: sprintf(sss,"%s/bin/openxm",s);
278: }
279: if (access(sss,X_OK&R_OK) == 0) {
280: }else{
281: oxdError("The shell script openxm does not exists. It is usually generated under OpenXM/rc");
282: }
283: return sss;
284: }
285:
286: /* These are dummy. It is defined in stackmachine.c */
287: unlockCtrlCForOx() { ; }
288: restoreLockCtrlCForOx() { ; }
289:
290: oxdError(char *s) {
291: fprintf(stderr,"%s\n",s);
292: exit(10);
293: }
294:
295:
296:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>