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