[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.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>