[BACK]Return to oxf.c CVS log [TXT][DIR] Up to [local] / OpenXM / src / ox_toolkit

Diff for /OpenXM/src/ox_toolkit/oxf.c between version 1.1 and 1.22

version 1.1, 2000/10/10 05:23:21 version 1.22, 2015/08/21 00:53:53
Line 1 
Line 1 
 /* -*- mode: C; coding: euc-japan -*- */  /* -*- mode: C; coding: euc-japan -*- */
 /* $OpenXM$ */  /* $OpenXM: OpenXM/src/ox_toolkit/oxf.c,v 1.21 2015/08/05 00:59:05 noro Exp $ */
   
 /*  /*
    This module includes functions for sending/receiveng CMO's.     This module includes functions for sending/receiveng CMO's.
    Some commnets is written in Japanese by the EUC-JP coded     Some commnets are written in Japanese by the EUC-JP coded
    character set.     character set.
 */  */
   
Line 11 
Line 11 
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
 #include <unistd.h>  #include <unistd.h>
 #include <errno.h>  
 #include <fcntl.h>  #include <fcntl.h>
 #include <sys/file.h>  #include <sys/file.h>
 #include <sys/param.h>  #include <sys/param.h>
 #include <time.h>  #include <time.h>
   #include <limits.h>
   
   #if defined(__sun__)
   #include <netdb.h>
   #include <sys/types.h>
   #include <netinet/in.h>
   #endif
   
   #if defined(__sun__)
   #include <synch.h>
   #else
   #include <inttypes.h>
   #endif
   
 #include "mysocket.h"  #include "mysocket.h"
 #include "ox_toolkit.h"  #include "ox_toolkit.h"
   
   static mathcap *oxf_mathcap(OXFILE *oxfp);
   
   static int send_int32_lbo(OXFILE *oxfp, int int32);
   static int send_int32_nbo(OXFILE *oxfp, int int32);
   static int receive_int32_lbo(OXFILE *oxfp);
   static int receive_int32_nbo(OXFILE *oxfp);
   
   static int send_int64_nbo_le(OXFILE *oxfp, double int64);
   static int send_int64_lbo(OXFILE *oxfp, double int64);
   static double receive_int64_nbo_le(OXFILE *oxfp);
   static double receive_int64_lbo(OXFILE *oxfp);
   
   static void pipe_send_info(int fd, char *hostname, int port, char *password);
   
   /* translating double of little endian byte order to one of big endian. */
   double htonll_le(double n)
   {
       int i;
       double r;
           char *sp = (char *)&n, *dp = (char *)&r + sizeof(double)-1;
       for(i=0; i<sizeof(double); i++) {
                   *dp-- = *sp++;
       }
       return r;
   }
   
   /* enable write buffering */
   int oxf_setbuffer(OXFILE *oxfp, char *buf, int size)
   {
       if (buf == NULL && size > 0) {
           buf = MALLOC(size);
       }
       if (oxfp->wbuf != NULL) {
           oxf_flush(oxfp);
       }
       oxfp->wbuf = buf;
       oxfp->wbuf_size  = size;
       oxfp->wbuf_count = 0;
       return 0;
   }
   
   int oxf_read(void *buffer, size_t size, size_t num, OXFILE *oxfp)
   {
       int n = read(oxfp->fd, buffer, size*num);
       if (n <= 0) {
   #if 0
           oxfp->error = 1;
   #else
           exit(0);
   #endif
       }
       return n;
   }
   
   int oxf_write(void *buffer, size_t size, size_t num, OXFILE *oxfp)
   {
       size_t sz = size*num;
       if (oxfp->wbuf == NULL) { /* no buffering */
           return write(oxfp->fd, buffer, sz);
       }
       if ((oxfp->wbuf_count + sz) >= oxfp->wbuf_size) {
           oxf_flush(oxfp);
           return write(oxfp->fd, buffer, sz);
       }
       memcpy(oxfp->wbuf + oxfp->wbuf_count, buffer, sz);
       oxfp->wbuf_count += sz;
       return sz;
   }
   
   /* sending an object of int64 type with Network Byte Order. */
   static int send_int64_nbo_le(OXFILE *oxfp, double int64)
   {
       int64 = htonll_le(int64);
       return oxf_write(&int64, sizeof(double), 1, oxfp);
   }
   
   /* sending an object of int64 type with Local Byte Order. */
   static int send_int64_lbo(OXFILE *oxfp, double int64)
   {
       return oxf_write(&int64, sizeof(double), 1, oxfp);
   }
   
   /* receiving an object of int64 type with Network Byte Order. */
   static double receive_int64_nbo_le(OXFILE *oxfp)
   {
       double tag;
       oxf_read(&tag, sizeof(double), 1, oxfp);
       return htonll_le(tag);
   }
   
   /* receiving an object of int64 type with Local Byte Order. */
   static double receive_int64_lbo(OXFILE *oxfp)
   {
       double tag;
       oxf_read(&tag, sizeof(double), 1, oxfp);
       return tag;
   }
   
   /* sending an object of int32 type with Network Byte Order.
      (not equal to cmo_int32 type)  */
   static int send_int32_nbo(OXFILE *oxfp, int int32)
   {
       int32 = htonl(int32);
       return oxf_write(&int32, sizeof(int), 1, oxfp);
   }
   
   /* sending an object of int32 type with Local Byte Order.
      (not equal to cmo_int32 type)  */
   static int send_int32_lbo(OXFILE *oxfp, int int32)
   {
       return oxf_write(&int32, sizeof(int), 1, oxfp);
   }
   
   /* receiving an object of int32 type with Network Byte Order.
      (not equal to cmo_int32 type)  */
   static int receive_int32_nbo(OXFILE *oxfp)
   {
       int tag;
       oxf_read(&tag, sizeof(int), 1, oxfp);
       return ntohl(tag);
   }
   
   /* receiving an object of int32 type with Local Byte Order.
      (not equal to cmo_int32 type)  */
   static int receive_int32_lbo(OXFILE *oxfp)
   {
       int tag;
       oxf_read(&tag, sizeof(int), 1, oxfp);
       return tag;
   }
   
   /* (1) getting the fd by socket(2).
      (2) preparing a buffer by fdopen(fd, "a+"). (not "w+")
      (3) determing the byte order of the OX connection.
      (4) setting function pointers by oxf_setopt().
   */
 OXFILE *oxf_open(int fd)  OXFILE *oxf_open(int fd)
 {  {
     OXFILE *oxfp = (OXFILE *)malloc(sizeof(OXFILE));      OXFILE *oxfp = (OXFILE *)MALLOC(sizeof(OXFILE));
       oxfp = (OXFILE *)MALLOC(sizeof(OXFILE));
     oxfp->fd = fd;      oxfp->fd = fd;
     oxfp->send_int32    = send_int32_nbo;      oxfp->send_int32    = send_int32_nbo;
     oxfp->receive_int32 = receive_int32_nbo;      oxfp->receive_int32 = receive_int32_nbo;
         oxfp->control = NULL;      oxfp->serial_number = 0;
       oxfp->control = NULL;
       oxfp->error = 0;
       oxfp->mathcap = NULL;
       oxfp->wbuf = NULL;
       oxfp->wbuf_size = 0;
       oxfp->wbuf_count = 0;
       oxfp->send_double    = send_int64_lbo;
       oxfp->receive_double = receive_int64_lbo;
     return oxfp;      return oxfp;
     /* oxfp->fp = fdopen(fd, "a+"); */      /* oxfp->fp = fdopen(fd, "a+"); */
     /* return (oxfp->fp != NULL)? oxfp: NULL; */      /* return (oxfp->fp != NULL)? oxfp: NULL; */
 }  }
   
   int oxf_fileno(OXFILE *oxfp)
   {
       return oxfp->fd;
   }
   
 OXFILE *oxf_control(OXFILE *oxfp)  OXFILE *oxf_control(OXFILE *oxfp)
 {  {
         return oxfp->control;      return oxfp->control;
 }  }
   
 /* The function determines a byte order of integer on the OpenXM  /* The function determines a byte order of integer on the OpenXM
Line 54  void oxf_determine_byteorder_client(OXFILE *oxfp)
Line 216  void oxf_determine_byteorder_client(OXFILE *oxfp)
     oxf_setopt(oxfp, mode);      oxf_setopt(oxfp, mode);
 }  }
   
 /* Server 側ではこちらを用いる */  /* If the program is an OX server, then you must use this function. */
 /* いまの実装は dup されていることが前提になっている */  
 void oxf_determine_byteorder_server(OXFILE *oxfp)  void oxf_determine_byteorder_server(OXFILE *oxfp)
 {  {
     int  offer = OX_BYTE_LITTLE_ENDIAN;      int  offer = OX_BYTE_LITTLE_ENDIAN;
Line 70  void oxf_determine_byteorder_server(OXFILE *oxfp)
Line 231  void oxf_determine_byteorder_server(OXFILE *oxfp)
   
 void oxf_flush(OXFILE *oxfp)  void oxf_flush(OXFILE *oxfp)
 {  {
     /* fflush(oxfp->fp); */      if (oxfp->wbuf != NULL) {
           write(oxfp->fd, oxfp->wbuf, oxfp->wbuf_count);
           oxfp->wbuf_count = 0;
       }
 }  }
   
 void oxf_close(OXFILE *oxfp)  void oxf_close(OXFILE *oxfp)
 {  {
       oxf_flush(oxfp);
     close(oxfp->fd);      close(oxfp->fd);
     /* fclose(oxfp->fp); */  
 }  }
   
 #define OXF_SETOPT_NBO  0  #define OXF_SETOPT_NBO  0
Line 84  void oxf_close(OXFILE *oxfp)
Line 248  void oxf_close(OXFILE *oxfp)
   
 void oxf_setopt(OXFILE *oxfp, int mode)  void oxf_setopt(OXFILE *oxfp, int mode)
 {  {
     if (mode == OXF_SETOPT_LBO) {      int m = 1;
         oxfp->send_int32    = send_int32_lbo;      if (mode == OXF_SETOPT_NBO && *(char *)&m) {
         oxfp->receive_int32 = receive_int32_lbo;                  /* Little endian architecture. */
     }else if (mode == OXF_SETOPT_NBO) {                  oxfp->send_int32     = send_int32_nbo;
         oxfp->send_int32    = send_int32_nbo;                  oxfp->receive_int32  = receive_int32_nbo;
         oxfp->receive_int32 = receive_int32_nbo;                  oxfp->send_double    = send_int64_nbo_le;
                   oxfp->receive_double = receive_int64_nbo_le;
           }else {
                   oxfp->send_int32     = send_int32_lbo;
                   oxfp->receive_int32  = receive_int32_lbo;
                   oxfp->send_double    = send_int64_lbo;
                   oxfp->receive_double = receive_int64_lbo;
     }      }
 }  }
   
   int oxf_listen(int *portp)
   {
       char localhost[MAXHOSTNAMELEN];
       if (gethostname(localhost, MAXHOSTNAMELEN)==0) {
           return mysocketListen(localhost, portp);
       }
       return -1;
   }
   
 OXFILE *oxf_connect_active(char *hostname, short port)  OXFILE *oxf_connect_active(char *hostname, short port)
 {  {
     int fd = mysocketOpen(hostname, port);      int fd = mysocketOpen(hostname, port);
     return oxf_open(fd);      return (fd < 0)? NULL: oxf_open(fd);
 }  }
   
 OXFILE *oxf_connect_passive(int listened)  OXFILE *oxf_connect_passive(int listened)
 {  {
     int fd = mysocketAccept(listened);      int fd = mysocketAccept(listened);
     return oxf_open(fd);      return (fd < 0)? NULL: oxf_open(fd);
 }  }
   
 #define LENGTH_OF_ONETIME_PASSWORD 64  #define LENGTH_OF_ONETIME_PASSWORD 64
Line 110  OXFILE *oxf_connect_passive(int listened)
Line 289  OXFILE *oxf_connect_passive(int listened)
 /* a password generator. */  /* a password generator. */
 char *generate_otp()  char *generate_otp()
 {  {
         static char crypto[] = "%.,^_+-=/@0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";      static char crypto[] = "%.,^_+-=/@0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
     static char otp[LENGTH_OF_ONETIME_PASSWORD+1] = {0};      static char otp[LENGTH_OF_ONETIME_PASSWORD+1] = {0};
     int i;      int i;
   
Line 127  char *generate_otp()
Line 306  char *generate_otp()
 int oxf_confirm_client(OXFILE *oxfp, char *passwd)  int oxf_confirm_client(OXFILE *oxfp, char *passwd)
 {  {
     int len = strlen(passwd)+1;      int len = strlen(passwd)+1;
     char *buf = alloca(len);      char *buf = ALLOCA(len);
   
     oxf_read(buf, 1, len, oxfp);      oxf_read(buf, 1, len, oxfp);
     return !strcmp(passwd, buf);      return !strcmp(passwd, buf);
Line 138  int oxf_confirm_server(OXFILE *oxfp, char *passwd)
Line 317  int oxf_confirm_server(OXFILE *oxfp, char *passwd)
     return oxf_write(passwd, 1, strlen(passwd)+1, oxfp);      return oxf_write(passwd, 1, strlen(passwd)+1, oxfp);
 }  }
   
   __inline__
   static mathcap *oxf_mathcap(OXFILE *oxfp)
   {
       if (oxfp->mathcap == NULL) {
           oxfp->mathcap = new_mathcap();
       }
           return oxfp->mathcap;
   }
   
   cmo_mathcap *oxf_cmo_mathcap(OXFILE *oxfp)
   {
           return mathcap_get(oxf_mathcap(oxfp));
   }
   
   void oxf_mathcap_update(OXFILE *oxfp, cmo_mathcap *ob)
   {
       mathcap_update(oxf_mathcap(oxfp), ob);
   }
   
 /* example: which("xterm", getenv("PATH")); */  /* example: which("xterm", getenv("PATH")); */
 char *which(char *exe, const char *env)  char *which(char *exe, const char *env)
 {  {
     char *tok;      char *tok;
     char *path;      char *path;
     char delim[] = ":";      char delim[] = ":";
     char *e = alloca(strlen(env)+1);      char *e = ALLOCA(strlen(env)+1);
     strcpy(e, env);      strcpy(e, env);
     tok = strtok(e, delim);      tok = strtok(e, delim);
     while (tok != NULL) {      while (tok != NULL) {
         path = malloc(strlen(tok)+strlen(exe)+2);          path = MALLOC(strlen(tok)+strlen(exe)+2);
         sprintf(path, "%s/%s", tok, exe);          sprintf(path, "%s/%s", tok, exe);
         if (access(path, X_OK&R_OK) == 0) {          if (access(path, X_OK&R_OK) == 0) {
             return path;              return path;
         }          }
         free(path);          FREE(path);
         tok = strtok(NULL, delim);          tok = strtok(NULL, delim);
     }      }
     return NULL;      return NULL;
 }  }
   
 /* Remarks: ssh determines remote host by his name, i.e. by arg[0]. */  /* Remarks: ssh determines remote host by his name, i.e. by arg[0]. */
 int oxc_start(char *remote_host, short port, char *passwd)  int oxc_start(char *remote_host, int port, char *passwd)
 {  {
     char localhost[MAXHOSTNAMELEN];      char localhost[MAXHOSTNAMELEN];
     char ports[128];      char ports[128];
     int pid = 0;      int pid = 0;
     char *cmd = "echo";      char *cmd = "oxc";
 /*  char *cmd = "oxc"; */  
   
     if (gethostname(localhost, MAXHOSTNAMELEN)==0) {      if (gethostname(localhost, MAXHOSTNAMELEN)==0) {
         if ((pid = fork()) == 0) {          if ((pid = fork()) == 0) {
             sprintf(ports, "%d", port);              sprintf(ports, "%d", port);
 #ifdef DEBUG              ox_printf("oxf.c:: oxc_start() does %s(ssh) -f %s -h %s -p %s -c %s\n", remote_host, cmd, localhost, ports, passwd);
             fprintf(stderr, "oxf.c:: oxc_start() does %s(ssh) -f %s -h %s -p %s -c %s\n", remote_host, cmd, localhost, ports, passwd);  
 #endif  
             execlp("ssh", remote_host, "-f", cmd,              execlp("ssh", remote_host, "-f", cmd,
                   "-h", localhost, "-p", ports,"-c", passwd, NULL);                    "-h", localhost, "-p", ports,"-c", passwd, NULL);
         }          }
     }      }
     return pid;      return pid;
   }
   
   /* Remarks: ssh determines remote host by his name, i.e. by arg[0]. */
   int oxc_start_with_pipe(char *remote_host, int port, char *passwd)
   {
       char localhost[MAXHOSTNAMELEN];
       int  pid = 0;
       char *cmd = "oxc";
           int  pipefd[2];
   
       if (gethostname(localhost, MAXHOSTNAMELEN)==0) {
                   if (pipe(pipefd) < 0) {
                           return -1;
                   }
           if ((pid = fork()) == 0) {
                           dup2(pipefd[1], 0);
                           close(pipefd[0]);
                           close(pipefd[1]);
               execlp("ssh", remote_host, cmd, NULL);
                           exit(1);
           }
                   close(pipefd[1]);
                   pipe_send_info(pipefd[0], localhost, port, passwd);
       }
       return pid;
   }
   
   static void pipe_send_string(int fd, char *s)
   {
           int len  = strlen(s);
           int lenN = htonl(len);
           write(fd, &lenN, sizeof(int));
           write(fd, s, len+1);
   }
   
   static char *pipe_read_string()
   {
           int len;
           char *s;
           read(0, &len, sizeof(int));
           len = ntohl(len)+1;
           s = MALLOC(len);
           read(0, s, len);
           return s;
   }
   
   /* The data format used by pipe_send_info() is defined in OX-RFC-101. */
   void pipe_send_info(int fd, char *hostname, int port, char *password)
   {
           port = htonl(port);
           write(fd, &port, sizeof(int));
           pipe_send_string(fd, hostname);
           pipe_send_string(fd, password);
   }
   
   int pipe_read_info(char **hostname, int *port, char **password)
   {
           if (read(0, port, sizeof(int)) > 0) {
                   *port = ntohl(*port);
                   *hostname = pipe_read_string();
                   *password = pipe_read_string();
                   return 0;
           }
           return -1;
   }
   
   /*  Example: oxf_execute_cmd(oxfp, "ox_sm1"); */
   OXFILE *oxf_execute_cmd(OXFILE *oxfp, char *cmd)
   {
       int port = 0;
       int listened;
   
       if ((listened = oxf_listen(&port)) != -1) {
                   cmo_list *args =  list_appendl(NULL, list_append(new_cmo_list(), (cmo *)new_cmo_int32(port)), new_cmo_string(cmd), NULL);
                   send_ox_cmo(oxfp, (cmo *)args);
           send_ox_command(oxfp, SM_control_spawn_server);
           return oxf_connect_passive(listened);
       }
       return NULL;
 }  }

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.22

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>