[BACK]Return to oxd-thread.c CVS log [TXT][DIR] Up to [local] / OpenXM / src / kxx

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>