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

Diff for /OpenXM/src/ox_toolkit/ox.c between version 1.12 and 1.13

version 1.12, 2000/03/10 12:24:38 version 1.13, 2000/10/10 05:23:20
Line 1 
Line 1 
 /* -*- mode: C; coding: euc-japan -*- */  /* -*- mode: C; coding: euc-japan -*- */
 /* $OpenXM: OpenXM/src/ox_toolkit/ox.c,v 1.11 2000/02/04 08:01:30 ohara Exp $ */  /* $OpenXM: OpenXM/src/ox_toolkit/ox.c,v 1.12 2000/03/10 12:24:38 ohara Exp $ */
   
 /*  /*
    This module includes functions for sending/receiveng CMO's.     This module includes functions for sending/receiveng CMO's.
Line 7 
Line 7 
    character set.     character set.
 */  */
   
   
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
Line 15 
Line 14 
 #include <errno.h>  #include <errno.h>
 #include <fcntl.h>  #include <fcntl.h>
 #include <sys/file.h>  #include <sys/file.h>
   #include <time.h>
   
 #include "mysocket.h"  #include "mysocket.h"
 #include "ox_toolkit.h"  #include "ox_toolkit.h"
 #include "parse.h"  #include "parse.h"
   
 static int          cmolen_cmo_int32(cmo_int32* c);  
 static int          cmolen_cmo_list(cmo_list* c);  
 static int          cmolen_cmo_mathcap(cmo_mathcap* c);  
 static int          cmolen_cmo_null(cmo_null* c);  
 static int          cmolen_cmo_string(cmo_string* c);  
 static int          cmolen_cmo_zz(cmo_zz* c);  
 static int          cmolen_cmo_monomial32(cmo_monomial32* c);  
   
 static int          dump_cmo_int32(cmo_int32* m);  
 static int          dump_cmo_list(cmo_list* m);  
 static int          dump_cmo_mathcap(cmo_mathcap* m);  
 static int          dump_cmo_null(cmo_null* m);  
 static int          dump_cmo_string(cmo_string* m);  
 static int          dump_cmo_monomial32(cmo_monomial32* c);  
 static int          dump_cmo_zz(cmo_zz* c);  
 static int          dump_string(char *s, int len);  
 static int          dump_integer(int x);  
 static int          dump_mpz(mpz_ptr mpz);  
   
 static int          login_with_otp(int fd, char* passwd);  
 static char         *create_otp();  
   
 /* CMO_xxx の値の順にならべること(デバッグのため) */  /* CMO_xxx の値の順にならべること(デバッグのため) */
 static cmo_null*         receive_cmo_null(int fd);  static cmo_null*         receive_cmo_null(OXFILE *oxfp);
 static cmo_int32*        receive_cmo_int32(int fd);  static cmo_int32*        receive_cmo_int32(OXFILE *oxfp);
 static cmo_string*       receive_cmo_string(int fd);  static cmo_string*       receive_cmo_string(OXFILE *oxfp);
 static cmo_mathcap*      receive_cmo_mathcap(int fd);  static cmo_mathcap*      receive_cmo_mathcap(OXFILE *oxfp);
 static cmo_list*         receive_cmo_list(int fd);  static cmo_list*         receive_cmo_list(OXFILE *oxfp);
 static cmo_monomial32*   receive_cmo_monomial32(int fd);  static cmo_monomial32*   receive_cmo_monomial32(OXFILE *oxfp);
 static cmo_zz*           receive_cmo_zz(int fd);  static cmo_zz*           receive_cmo_zz(OXFILE *oxfp);
 static cmo_zero*         receive_cmo_zero(int fd);  static cmo_zero*         receive_cmo_zero(OXFILE *oxfp);
 static cmo_dms_generic*  receive_cmo_dms_generic(int fd);  static cmo_dms_generic*  receive_cmo_dms_generic(OXFILE *oxfp);
 static cmo_ring_by_name* receive_cmo_ring_by_name(int fd);  static cmo_ring_by_name* receive_cmo_ring_by_name(OXFILE *oxfp);
 static cmo_distributed_polynomial* receive_cmo_distributed_polynomial(int fd);  static cmo_distributed_polynomial* receive_cmo_distributed_polynomial(OXFILE *oxfp);
   
 static cmo_error2*       receive_cmo_error2(int fd);  static cmo_error2*       receive_cmo_error2(OXFILE *oxfp);
 static void              receive_mpz(int fd, mpz_ptr mpz);  static void              receive_mpz(OXFILE *oxfp, mpz_ptr mpz);
   
 static int          send_cmo_null(int fd, cmo_null* c);  static int          send_cmo_null(OXFILE *oxfp, cmo_null* c);
 static int          send_cmo_int32(int fd, cmo_int32* m);  static int          send_cmo_int32(OXFILE *oxfp, cmo_int32* m);
 static int          send_cmo_string(int fd, cmo_string* m);  static int          send_cmo_string(OXFILE *oxfp, cmo_string* m);
 static int          send_cmo_mathcap(int fd, cmo_mathcap* c);  static int          send_cmo_mathcap(OXFILE *oxfp, cmo_mathcap* c);
 static int          send_cmo_list(int fd, cmo_list* c);  static int          send_cmo_list(OXFILE *oxfp, cmo_list* c);
 static int          send_cmo_monomial32(int fd, cmo_monomial32* c);  static int          send_cmo_monomial32(OXFILE *oxfp, cmo_monomial32* c);
 static int          send_cmo_zz(int fd, cmo_zz* c);  static int          send_cmo_zz(OXFILE *oxfp, cmo_zz* c);
 static int          send_cmo_error2(int fd, cmo_error2* c);  static int          send_cmo_error2(OXFILE *oxfp, cmo_error2* c);
 static int          send_mpz(int fd, mpz_ptr mpz);  static int          send_mpz(OXFILE *oxfp, mpz_ptr mpz);
 static int          send_cmo_distributed_polynomial(int fd, cmo_distributed_polynomial* c);  static int          send_cmo_distributed_polynomial(OXFILE *oxfp, cmo_distributed_polynomial* c);
   
 static void         resize_mpz(mpz_ptr mpz, int size);  
   
 static int          print_cmo_int32(cmo_int32* c);  
 static int          print_cmo_list(cmo_list* li);  
 static int          print_cmo_mathcap(cmo_mathcap* c);  
 static int          print_cmo_string(cmo_string* c);  
   
 static char*        new_string_set_cmo_null();  
 static char*        new_string_set_cmo_int32(int integer);  
 static char*        new_string_set_cmo_list(cmo_list *c);  
 static char*        new_string_set_cmo_zz(cmo_zz *c);  
   
 int ssh_ox_server(char *, char *, char *, short, short);  int ssh_ox_server(char *, char *, char *, short, short);
   
 int current_fd = 0;  OXFILE *current_fd = NULL;
 int set_current_fd(int fd)  void set_current_fd(OXFILE *oxfp)
 {  {
         current_fd = fd;      current_fd = oxfp;
 }  }
   
 /* hook functions. (yet not implemented) */  /* hook functions. (yet not implemented) */
Line 95  static hook_t hook_after_send_cmo  = NULL;
Line 61  static hook_t hook_after_send_cmo  = NULL;
   
 int add_hook_before_send_cmo(hook_t func)  int add_hook_before_send_cmo(hook_t func)
 {  {
         hook_before_send_cmo = func;      hook_before_send_cmo = func;
       return 0;
 }  }
   
 int add_hook_after_send_cmo(hook_t func)  int add_hook_after_send_cmo(hook_t func)
 {  {
         hook_after_send_cmo = func;      hook_after_send_cmo = func;
       return 0;
 }  }
   
 static cmo *call_hook_before_send_cmo(int fd, cmo *c)  static cmo *call_hook_before_send_cmo(OXFILE *oxfp, cmo *c)
 {  {
         if (hook_before_send_cmo != NULL) {      if (hook_before_send_cmo != NULL) {
                 return hook_before_send_cmo(fd, c);          return hook_before_send_cmo(oxfp, c);
         }      }
         return c;      return c;
 }  }
   
 static cmo *call_hook_after_send_cmo(int fd, cmo *c)  static cmo *call_hook_after_send_cmo(OXFILE *oxfp, cmo *c)
 {  {
         if (hook_after_send_cmo != NULL) {      if (hook_after_send_cmo != NULL) {
                 return hook_after_send_cmo(fd, c);          return hook_after_send_cmo(oxfp, c);
         }      }
         return c;      return c;
 }  }
   
   int oxf_read(void *buffer, size_t size, size_t num, OXFILE *oxfp)
   {
       return read(oxfp->fd, buffer, size*num);
   /*  return fread(buffer, size, num, oxfp->fp); */
   }
   
   int oxf_write(void *buffer, size_t size, size_t num, OXFILE *oxfp)
   {
       return write(oxfp->fd, buffer, size*num);
   /*  return fwrite(buffer, size, num, oxfp->fp); */
   }
   
 /* Handling an error. */  /* Handling an error. */
 static int current_received_serial = 0;  static int current_received_serial = 0;
   
Line 126  static int current_received_serial = 0;
Line 106  static int current_received_serial = 0;
 cmo_error2* make_error_object(int err_code, cmo *ob)  cmo_error2* make_error_object(int err_code, cmo *ob)
 {  {
     cmo_list* li = new_cmo_list();      cmo_list* li = new_cmo_list();
     append_cmo_list(li, (cmo *)new_cmo_int32(current_received_serial));      list_append(li, (cmo *)new_cmo_int32(current_received_serial));
     append_cmo_list(li, (cmo *)new_cmo_int32(err_code));      list_append(li, (cmo *)new_cmo_int32(err_code));
     append_cmo_list(li, ob);      list_append(li, ob);
     /* 他の情報を加えるならココ */      /* 他の情報を加えるならココ */
     return new_cmo_error2((cmo *)li);      return new_cmo_error2((cmo *)li);
 }  }
   
 #define DEFAULT_SERIAL_NUMBER 0x0000ffff  #define DEFAULT_SERIAL_NUMBER 0x0000ffff
 #define receive_serial_number(x)   (receive_int32(x))  #define receive_serial_number(x)   (receive_int32((x)))
   
 /* getting a next serial number. */  /* getting a next serial number. */
 int next_serial()  int next_serial(OXFILE *oxfp)
 {  {
   /*
     static int serial_number = DEFAULT_SERIAL_NUMBER;      static int serial_number = DEFAULT_SERIAL_NUMBER;
     return serial_number++;  */
       return oxfp->serial_number++;
 }  }
   
 /* sending an object of int32 type. (not equal to cmo_int32 type)  */  /* sending an object of int32 type. (not equal to cmo_int32 type)  */
 int send_int32(int fd, int int32)  int send_int32(OXFILE *oxfp, int int32)
 {  {
     int32 = htonl(int32);      return oxfp->send_int32(oxfp, int32);
     return write(fd, &int32, sizeof(int));  
 }  }
   
 /* receiving an object of int32 type. (not equal to cmo_int32 type)  */  /* sending an object of int32 type with Network Byte Order.
 int receive_int32(int fd)     (not equal to cmo_int32 type)  */
   int send_int32_nbo(OXFILE *oxfp, int int32)
 {  {
     int tag;      int32 = htonl(int32);
     read(fd, &tag, sizeof(int));      return oxf_write(&int32, sizeof(int), 1, oxfp);
     return ntohl(tag);  
 }  }
   
 /* receiving an (OX_tag, serial number)  */  /* sending an object of int32 type with Local Byte Order.
 int receive_ox_tag(int fd)     (not equal to cmo_int32 type)  */
   int send_int32_lbo(OXFILE *oxfp, int int32)
 {  {
     int serial;      return oxf_write(&int32, sizeof(int), 1, oxfp);
     int tag = receive_int32(fd);  
     current_received_serial = receive_serial_number(fd);  
     return tag;  
 }  }
   
 /* sending an (OX_tag, serial number)  */  /* receiving an object of int32 type. (not equal to cmo_int32 type)  */
 int send_ox_tag(int fd, int tag)  int receive_int32(OXFILE *oxfp)
 {  {
     send_int32(fd, tag);      return oxfp->receive_int32(oxfp);
     return send_int32(fd, next_serial());  
 }  }
   
 /* functions for a cmo_list */  /* receiving an object of int32 type with Network Byte Order.
 cell* new_cell()     (not equal to cmo_int32 type)  */
   int receive_int32_nbo(OXFILE *oxfp)
 {  {
     cell* h = malloc(sizeof(cell));      int tag;
     h->next = NULL;      oxf_read(&tag, sizeof(int), 1, oxfp);
     h->cmo  = NULL;      return ntohl(tag);
     return h;  
 }  }
   
 cell* next_cell(cell* this)  /* receiving an object of int32 type with Local Byte Order.
      (not equal to cmo_int32 type)  */
   int receive_int32_lbo(OXFILE *oxfp)
 {  {
     return this->next;      int tag;
       oxf_read(&tag, sizeof(int), 1, oxfp);
       return tag;
 }  }
   
 static cell *tail(cmo_list* this) {  /* socket システムコールなどで socket を開いたのち、
     cell *cp = this->head;     fdopen(sd, "a+") でバッファリングする。("w+" ではない)
     while (cp->next != NULL) {     バッファリングの後、バイトオーダを決定し、
         cp = cp->next;     oxf_setopt() で関数ポインタを設定し直す。*/
     }  
     return cp;  
 }  
   
 int append_cmo_list(cmo_list* this, cmo* newcmo)  /* receiving an (OX_tag, serial number)  */
   int receive_ox_tag(OXFILE *oxfp)
 {  {
     cell *cp = tail(this);      int tag = receive_int32(oxfp);
     cp->cmo  = newcmo;      current_received_serial = receive_serial_number(oxfp);
     cp->next = new_cell();      return tag;
     this->length++;  
     return 0;  
 }  }
   
 cmo *nth_cmo_list(cmo_list* this, int n)  /* sending an (OX_tag, serial number)  */
   int send_ox_tag(OXFILE *oxfp, int tag)
 {  {
         cell *cp = this->head;      send_int32(oxfp, tag);
         if(this->length <= n) {      return send_int32(oxfp, next_serial(oxfp));
                 return NULL;  
         }  
         while(n-- > 0) {  
                 cp = cp->next;  
         }  
         return cp->cmo;  
 }  }
   
 int length_cmo_list(cmo_list* this)  
 {  
     return this->length;  
 }  
   
 /* functions named receive_cmo_*. */  /* functions named receive_cmo_*. */
 static cmo_null* receive_cmo_null(int fd)  static cmo_null* receive_cmo_null(OXFILE *oxfp)
 {  {
     return new_cmo_null();      return new_cmo_null();
 }  }
   
 static cmo_int32* receive_cmo_int32(int fd)  static cmo_int32* receive_cmo_int32(OXFILE *oxfp)
 {  {
     int i = receive_int32(fd);      int i = receive_int32(oxfp);
     return new_cmo_int32(i);      return new_cmo_int32(i);
 }  }
   
 static cmo_string* receive_cmo_string(int fd)  static cmo_string* receive_cmo_string(OXFILE *oxfp)
 {  {
     int len = receive_int32(fd);      int len = receive_int32(oxfp);
     char* s = malloc(len+1);      char* s = malloc(len+1);
     memset(s, '\0', len+1);      memset(s, '\0', len+1);
     if (len > 0) {      if (len > 0) {
         read(fd, s, len);          oxf_read(s, 1, len, oxfp);
     }      }
     return new_cmo_string(s);      return new_cmo_string(s);
 }  }
   
 static cmo_mathcap* receive_cmo_mathcap(int fd)  static cmo_mathcap* receive_cmo_mathcap(OXFILE *oxfp)
 {  {
     cmo* ob = receive_cmo(fd);      cmo* ob = receive_cmo(oxfp);
     return new_cmo_mathcap(ob);      return new_cmo_mathcap(ob);
 }  }
   
 static cmo_list* receive_cmo_list(int fd)  static cmo_list* receive_cmo_list(OXFILE *oxfp)
 {  {
     cmo* ob;      cmo* ob;
     cmo_list* c = new_cmo_list();      cmo_list* c = new_cmo_list();
     int len = receive_int32(fd);      int len = receive_int32(oxfp);
   
     while (len>0) {      while (len>0) {
         ob = receive_cmo(fd);          ob = receive_cmo(oxfp);
         append_cmo_list(c, ob);          list_append(c, ob);
         len--;          len--;
     }      }
     return c;      return c;
 }  }
   
 static cmo_monomial32* receive_cmo_monomial32(int fd)  static cmo_monomial32* receive_cmo_monomial32(OXFILE *oxfp)
 {  {
     int i;      int i;
     int len = receive_int32(fd);      int len = receive_int32(oxfp);
     cmo_monomial32* c = new_cmo_monomial32(len);      cmo_monomial32* c = new_cmo_monomial32(len);
   
     for(i=0; i<len; i++) {      for(i=0; i<len; i++) {
         c->exps[i] = receive_int32(fd);          c->exps[i] = receive_int32(oxfp);
     }      }
     c->coef = receive_cmo(fd);      c->coef = receive_cmo(oxfp);
     return c;      return c;
 }  }
   
 static cmo_zz* receive_cmo_zz(int fd)  static cmo_zz* receive_cmo_zz(OXFILE *oxfp)
 {  {
     cmo_zz* c = new_cmo_zz();      cmo_zz* c = new_cmo_zz();
     receive_mpz(fd, c->mpz);      receive_mpz(oxfp, c->mpz);
     return c;      return c;
 }  }
   
 static cmo_zero* receive_cmo_zero(int fd)  static cmo_zero* receive_cmo_zero(OXFILE *oxfp)
 {  {
     return new_cmo_zero();      return new_cmo_zero();
 }  }
   
 static cmo_dms_generic* receive_cmo_dms_generic(int fd)  static cmo_dms_generic* receive_cmo_dms_generic(OXFILE *oxfp)
 {  {
     return new_cmo_dms_generic();      return new_cmo_dms_generic();
 }  }
   
 static cmo_ring_by_name* receive_cmo_ring_by_name(int fd)  static cmo_ring_by_name* receive_cmo_ring_by_name(OXFILE *oxfp)
 {  {
     cmo* ob = receive_cmo(fd);      cmo* ob = receive_cmo(oxfp);
         /* We need to check semantics but yet ... */      /* We need to check semantics but yet ... */
     return new_cmo_ring_by_name(ob);      return new_cmo_ring_by_name(ob);
 }  }
   
 static cmo_distributed_polynomial* receive_cmo_distributed_polynomial(int fd)  static cmo_distributed_polynomial* receive_cmo_distributed_polynomial(OXFILE *oxfp)
 {  {
     cmo* ob;      cmo* ob;
     cmo_distributed_polynomial* c = new_cmo_distributed_polynomial();      cmo_distributed_polynomial* c = new_cmo_distributed_polynomial();
     int len = receive_int32(fd);      int len = receive_int32(oxfp);
     c->ringdef = receive_cmo(fd);      c->ringdef = receive_cmo(oxfp);
   
     while (len>0) {      while (len>0) {
         ob = receive_cmo(fd);          ob = receive_cmo(oxfp);
         append_cmo_list((cmo_list *)c, ob);          list_append((cmo_list *)c, ob);
         len--;          len--;
     }      }
     return c;      return c;
 }  }
   
 static cmo_error2* receive_cmo_error2(int fd)  static cmo_error2* receive_cmo_error2(OXFILE *oxfp)
 {  {
     cmo* ob = receive_cmo(fd);      cmo* ob = receive_cmo(oxfp);
     return new_cmo_error2(ob);      return new_cmo_error2(ob);
 }  }
   
 /* receive_ox_tag() == OX_DATA の後に呼び出される */  /* receive_ox_tag() == OX_DATA の後に呼び出される */
 /* 関数ポインタを使った方がきれいに書けるような気がする.  */  /* 関数ポインタを使った方がきれいに書けるような気がする.  */
 /* if (foo[tag] != NULL) foo[tag](fd); とか */  /* if (foo[tag] != NULL) foo[tag](oxfp); とか */
   
 cmo* receive_cmo(int fd)  cmo* receive_cmo(OXFILE *oxfp)
 {  {
     cmo* m;      cmo* m;
     int tag;      int tag = receive_int32(oxfp);
     tag = receive_int32(fd);  
   
     switch(tag) {      switch(tag) {
     case CMO_NULL:      case CMO_NULL:
         m = receive_cmo_null(fd);          m = receive_cmo_null(oxfp);
         break;          break;
     case CMO_INT32:      case CMO_INT32:
         m = (cmo *)receive_cmo_int32(fd);          m = (cmo *)receive_cmo_int32(oxfp);
         break;          break;
     case CMO_STRING:      case CMO_STRING:
         m = (cmo *)receive_cmo_string(fd);          m = (cmo *)receive_cmo_string(oxfp);
         break;          break;
     case CMO_MATHCAP:      case CMO_MATHCAP:
         m = (cmo *)receive_cmo_mathcap(fd);          m = (cmo *)receive_cmo_mathcap(oxfp);
         break;          break;
     case CMO_LIST:      case CMO_LIST:
         m = (cmo *)receive_cmo_list(fd);          m = (cmo *)receive_cmo_list(oxfp);
         break;          break;
     case CMO_MONOMIAL32:      case CMO_MONOMIAL32:
         m = (cmo *)receive_cmo_monomial32(fd);          m = (cmo *)receive_cmo_monomial32(oxfp);
         break;          break;
     case CMO_ZZ:      case CMO_ZZ:
         m = (cmo *)receive_cmo_zz(fd);          m = (cmo *)receive_cmo_zz(oxfp);
         break;          break;
     case CMO_ZERO:      case CMO_ZERO:
         m = (cmo *)receive_cmo_zero(fd);          m = (cmo *)receive_cmo_zero(oxfp);
         break;          break;
     case CMO_DMS_GENERIC:      case CMO_DMS_GENERIC:
         m = (cmo *)receive_cmo_dms_generic(fd);          m = (cmo *)receive_cmo_dms_generic(oxfp);
         break;          break;
     case CMO_RING_BY_NAME:      case CMO_RING_BY_NAME:
         m = (cmo *)receive_cmo_ring_by_name(fd);          m = (cmo *)receive_cmo_ring_by_name(oxfp);
         break;          break;
     case CMO_DISTRIBUTED_POLYNOMIAL:      case CMO_DISTRIBUTED_POLYNOMIAL:
         m = (cmo *)receive_cmo_distributed_polynomial(fd);          m = (cmo *)receive_cmo_distributed_polynomial(oxfp);
         break;          break;
     case CMO_ERROR2:      case CMO_ERROR2:
         m = (cmo *)receive_cmo_error2(fd);          m = (cmo *)receive_cmo_error2(oxfp);
         break;          break;
     case CMO_DATUM:      case CMO_DATUM:
     case CMO_QQ:      case CMO_QQ:
     default:      default:
         fprintf(stderr, "the CMO (%d) is not implemented.\n", m->tag);          m = NULL;
           fprintf(stderr, "the CMO (%d) is not implemented.\n", tag);
     }      }
     return m;      return m;
 }  }
   
 static void receive_mpz(int fd, mpz_ptr mpz)  static void receive_mpz(OXFILE *oxfp, mpz_ptr mpz)
 {  {
     int i;      int i;
     int size  = receive_int32(fd);      int size  = receive_int32(oxfp);
     int len   = abs(size);      int len   = abs(size);
     resize_mpz(mpz, size);      resize_mpz(mpz, size);
   
     for(i=0; i<len; i++) {      for(i=0; i<len; i++) {
         mpz->_mp_d[i] = receive_int32(fd);          mpz->_mp_d[i] = receive_int32(oxfp);
     }      }
 }  }
   
 static void resize_mpz(mpz_ptr mpz, int size)  void send_ox_command(OXFILE *oxfp, int sm_command)
 {  {
     _mpz_realloc(mpz, abs(size));      send_ox_tag(oxfp, OX_COMMAND);
     mpz->_mp_size = size;      send_int32(oxfp, sm_command);
       oxf_flush(oxfp);
 }  }
   
 /* functions named new_cmo_*. */  void ox_close(OXFILE *sv)
 cmo_null* new_cmo_null()  
 {  {
     cmo_null* m = malloc(sizeof(cmo_null));      send_ox_command(oxf_control(sv), SM_control_kill);
     m->tag = CMO_NULL;  
     return m;  
 }  
   
 cmo_int32* new_cmo_int32(int i)  
 {  
     cmo_int32* c;  
     c = malloc(sizeof(cmo_int32));  
     c->tag     = CMO_INT32;  
     c->i = i;  
     return c;  
 }  
   
 cmo_string* new_cmo_string(char* s)  
 {  
     cmo_string* c = malloc(sizeof(cmo_string));  
     c->tag = CMO_STRING;  
     if (s != NULL) {  
         c->s = malloc(strlen(s)+1);  
         strcpy(c->s, s);  
     }else {  
         c->s = NULL;  
     }  
     return c;  
 }  
   
 cmo_mathcap* new_cmo_mathcap(cmo* ob)  
 {  
     cmo_mathcap* c = malloc(sizeof(cmo_mathcap));  
     c->tag = CMO_MATHCAP;  
     c->ob  = ob;  
     return c;  
 }  
   
 cmo_list* new_cmo_list()  
 {  
     cmo_list* c = malloc(sizeof(cmo_list));  
     c->tag    = CMO_LIST;  
     c->length = 0;  
     c->head->next = NULL;  
     return c;  
 }  
   
 cmo_monomial32* new_cmo_monomial32()  
 {  
     cmo_monomial32* c = malloc(sizeof(cmo_monomial32));  
     c->tag  = CMO_MONOMIAL32;  
     return c;  
 }  
   
 cmo_monomial32* new_cmo_monomial32_size(int size)  
 {  
     cmo_monomial32* c = new_cmo_monomial32();  
     if (size>0) {  
         c->length = size;  
         c->exps = malloc(sizeof(int)*size);  
     }  
     return c;  
 }  
   
 cmo_zz* new_cmo_zz()  
 {  
     cmo_zz* c = malloc(sizeof(cmo_zz));  
     c->tag  = CMO_ZZ;  
     mpz_init(c->mpz);  
     return c;  
 }  
   
 cmo_zz* new_cmo_zz_noinit()  
 {  
     cmo_zz* c = malloc(sizeof(cmo_zz));  
     c->tag  = CMO_ZZ;  
     return c;  
 }  
   
 cmo_zz* new_cmo_zz_set_si(int i)  
 {  
     cmo_zz* c = new_cmo_zz();  
     mpz_set_si(c->mpz, i);  
     return c;  
 }  
   
 cmo_zz* new_cmo_zz_set_mpz(mpz_ptr z)  
 {  
     cmo_zz* c = new_cmo_zz();  
     mpz_set(c->mpz, z);  
     return c;  
 }  
   
 cmo_zz *new_cmo_zz_set_string(char *s)  
 {  
     cmo_zz* c = new_cmo_zz_noinit();  
     mpz_init_set_str(c->mpz, s, 10);  
     return c;  
 }  
   
 cmo_zz* new_cmo_zz_size(int size)  
 {  
     cmo_zz* c = new_cmo_zz();  
     resize_mpz(c->mpz, size);  
     return c;  
 }  
   
 cmo_zero* new_cmo_zero()  
 {  
     cmo_zero* m = malloc(sizeof(cmo_zero));  
     m->tag = CMO_ZERO;  
     return m;  
 }  
   
 cmo_dms_generic* new_cmo_dms_generic()  
 {  
     cmo_dms_generic* m = malloc(sizeof(cmo_dms_generic));  
     m->tag = CMO_DMS_GENERIC;  
     return m;  
 }  
   
 cmo_ring_by_name* new_cmo_ring_by_name(cmo* ob)  
 {  
     cmo_ring_by_name* c = malloc(sizeof(cmo_ring_by_name));  
     c->tag = CMO_RING_BY_NAME;  
     c->ob  = ob;  
     return c;  
 }  
   
 cmo_indeterminate* new_cmo_indeterminate(cmo* ob)  
 {  
     cmo_indeterminate* c = malloc(sizeof(cmo_indeterminate));  
     c->tag = CMO_INDETERMINATE;  
     c->ob  = ob;  
     return c;  
 }  
   
 cmo_distributed_polynomial* new_cmo_distributed_polynomial()  
 {  
     cmo_distributed_polynomial* c = malloc(sizeof(cmo_distributed_polynomial));  
     c->tag     = CMO_DISTRIBUTED_POLYNOMIAL;  
     c->length  = 0;  
     c->head->next = NULL;  
     c->ringdef = NULL;  
     return c;  
 }  
   
 cmo_error2* new_cmo_error2(cmo* ob)  
 {  
     cmo_error2* c = malloc(sizeof(cmo_error2));  
     c->tag = CMO_ERROR2;  
     c->ob  = ob;  
     return c;  
 }  
   
 void send_ox_command(int fd, int sm_command)  
 {  
     send_ox_tag(fd, OX_COMMAND);  
     send_int32(fd, sm_command);  
 }  
   
 int print_cmo(cmo* c)  
 {  
     int tag = c->tag;  
   
     symbol_t symp = lookup_by_tag(tag);  
     if (symp != NULL) {  
         fprintf(stderr, "(%s", symp->key);  
     }else {  
         fprintf(stderr, "(%d", tag);  
     }  
   
     switch(tag) {  
     case CMO_LIST:  
         print_cmo_list((cmo_list *)c);  
         break;  
     case CMO_INT32:  
         print_cmo_int32((cmo_int32 *)c);  
         break;  
     case CMO_MATHCAP:  
     case CMO_INDETERMINATE:  
     case CMO_RING_BY_NAME:  
     case CMO_ERROR2:  
         print_cmo_mathcap((cmo_mathcap *)c);  
         break;  
     case CMO_STRING:  
         print_cmo_string((cmo_string *)c);  
         break;  
     case CMO_NULL:  
     case CMO_ZERO:  
     case CMO_DMS_GENERIC:  
         fprintf(stderr, ")");  
         break;  
     default:  
         fprintf(stderr, "print_cmo() does not know how to print.\n");  
     }  
 }  
   
 static int print_cmo_int32(cmo_int32* c)  
 {  
     fprintf(stderr, ", %d)", c->i);  
 }  
   
 static int print_cmo_list(cmo_list* li)  
 {  
     cell* cp = li->head;  
     while(cp->next != NULL) {  
         fprintf(stderr, ", ");  
         print_cmo(cp->cmo);  
         cp=cp->next;  
     }  
     fprintf(stderr, ")");  
 }  
   
 static int print_cmo_mathcap(cmo_mathcap* c)  
 {  
     fprintf(stderr, ", ");  
     print_cmo(c->ob);  
     fprintf(stderr, ")");  
 }  
   
 static int print_cmo_string(cmo_string* c)  
 {  
     fprintf(stderr, ", \"%s\")", c->s);  
 }  
   
 void ox_close(ox_file_t sv)  
 {  
     send_ox_command(sv->control, SM_control_kill);  
 #ifdef DEBUG  #ifdef DEBUG
     sleep(2);      sleep(2);
         /* We wait thar an OpenXM server terminates. */      /* We wait thar an OpenXM server terminates. */
     fprintf(stderr, "I have closed the connection to an Open XM server.\n");      fprintf(stderr, "I have closed the connection to an Open XM server.\n");
 #endif  #endif
 }  }
   
 void ox_shutdown(ox_file_t sv)  void ox_shutdown(OXFILE *sv)
 {  {
         /* We need to use SM_shutdown but yet ... */      /* We need to use SM_shutdown but yet ... */
         ox_close(sv);      ox_close(sv);
 }  }
   
 int ox_cmo_rpc(ox_file_t sv, char *function, int argc, cmo *argv[])  void ox_cmo_rpc(OXFILE *sv, char *function, int argc, cmo *argv[])
 {  {
         int i = argc;      int i = argc;
         while(i-- > 0) {      while(i-- > 0) {
                 send_ox_cmo(sv->stream, argv[i]);          send_ox_cmo(sv, argv[i]);
         }      }
         send_ox_cmo(sv->stream, (cmo *)new_cmo_int32(argc));      send_ox_cmo(sv, (cmo *)new_cmo_int32(argc));
         send_ox_cmo(sv->stream, (cmo *)new_cmo_string(function));      send_ox_cmo(sv, (cmo *)new_cmo_string(function));
         send_ox_command(sv->stream, SM_executeFunction);      send_ox_command(sv, SM_executeFunction);
 }  }
   
 void ox_execute_string(ox_file_t sv, char* s)  void ox_execute_string(OXFILE *sv, char* s)
 {  {
         send_ox_cmo(sv->stream, (cmo *)new_cmo_string(s));      send_ox_cmo(sv, (cmo *)new_cmo_string(s));
         send_ox_command(sv->stream, SM_executeStringByLocalParser);      send_ox_command(sv, SM_executeStringByLocalParser);
 }  }
   
 void ox_push_cmd(ox_file_t sv, int sm_code)  void ox_push_cmd(OXFILE *sv, int sm_code)
 {  {
     send_ox_command(sv->stream, sm_code);      send_ox_command(sv, sm_code);
 }  }
   
 cmo_mathcap* ox_mathcap(ox_file_t sv)  cmo_mathcap* ox_mathcap(OXFILE *sv)
 {  {
     send_ox_command(sv->stream, SM_mathcap);      send_ox_command(sv, SM_mathcap);
     send_ox_command(sv->stream, SM_popCMO);      send_ox_command(sv, SM_popCMO);
     receive_ox_tag(sv->stream);          /* OX_DATA */      receive_ox_tag(sv);          /* OX_DATA */
     return (cmo_mathcap *)receive_cmo(sv->stream);      return (cmo_mathcap *)receive_cmo(sv);
 }  }
   
 char* ox_popString(ox_file_t sv)  char* ox_popString(OXFILE *sv)
 {  {
     cmo_string* m = NULL;      cmo_string* m = NULL;
   
     send_ox_command(sv->stream, SM_popString);      send_ox_command(sv, SM_popString);
     receive_ox_tag(sv->stream); /* OX_DATA */      receive_ox_tag(sv); /* OX_DATA */
     m = (cmo_string *)receive_cmo(sv->stream);      m = (cmo_string *)receive_cmo(sv);
     return m->s;      return m->s;
 }  }
   
 int ox_pops(ox_file_t sv, int num)  void ox_pops(OXFILE *sv, int num)
 {  {
         send_ox_cmo(sv->stream, (cmo *)new_cmo_int32(num));      send_ox_cmo(sv, (cmo *)new_cmo_int32(num));
     send_ox_command(sv->stream, SM_pops);      send_ox_command(sv, SM_pops);
 }  }
   
 cmo* ox_pop_cmo(ox_file_t sv)  cmo* ox_pop_cmo(OXFILE *sv)
 {  {
     send_ox_command(sv->stream, SM_popCMO);      send_ox_command(sv, SM_popCMO);
     receive_ox_tag(sv->stream); /* OX_DATA */      receive_ox_tag(sv); /* OX_DATA */
     return receive_cmo(sv->stream);      return receive_cmo(sv);
 }  }
   
 void ox_push_cmo(ox_file_t sv, cmo *c)  void ox_push_cmo(OXFILE *sv, cmo *c)
 {  {
         send_ox_cmo(sv->stream, c);      send_ox_cmo(sv, c);
 }  }
   
 /* a dummy function for flushing a connection. */  /* a dummy function for flushing a connection. */
 int ox_flush(ox_file_t sv)  int ox_flush(OXFILE *sv)
 {  {
         return 1;      return 1;
 }  }
   
 /* a dummy password function. */  void ox_reset(OXFILE *sv)
 static char *create_otp()  
 {  {
     static char otp[] = "otpasswd";      send_ox_command(oxf_control(sv), SM_control_reset_connection);
     return otp;  
 }  
   
 /* proceeding an one time password. */      receive_ox_tag(oxf_control(sv));      /* OX_DATA */
 static int login_with_otp(int fd, char* passwd)      receive_cmo(oxf_control(sv));         /* (CMO_INT32, 0) */
 {  
     int len   = strlen(passwd)+1;  
     char *buf = alloca(len);  
     int n     = read(fd, buf, len);  
     int ret   = strcmp(passwd, buf);  
   
 #ifdef DEBUG      while(receive_ox_tag(sv) != OX_SYNC_BALL) {
     if (ret != 0) {          receive_cmo(sv); /* skipping a message. */
         fprintf(stderr, "Socket#%d: Login incorrect.\n", fd);  
     }else {  
         fprintf(stderr, "Socket#%d: login!.\n", fd);  
     }      }
     fprintf(stderr, "password = (%s), %d bytes.\n", passwd, len);  
     fprintf(stderr, "received = (%s), %d bytes.\n", buf, n);  
     fflush(stderr);  
 #endif  
   
     return ret;      send_ox_tag(sv, OX_SYNC_BALL);
 }  
   
 /* The environment variable OpenXM_HOME must be defined. */  
 static char *concat_openxm_home_bin(char *s)  
 {  
     char *path;  
     char *base;  
   
     /* if s includes '/' then it is not concaticated. */  
         if (strchr(s, '/') != NULL) {  
                 return s;  
         }  
   
         base = getenv("OpenXM_HOME");  
         path = malloc(strlen(base)+6+strlen(s));  
         sprintf(path, "%s/bin/%s", base, s);  
         return path;  
 }  
   
 /* example: which("xterm", getenv("PATH")); */  
 static char *which(char *prog, char *path_env)  
 {  
         char *tok;  
         char *path;  
         char delim[] = ":";  
         char *e = alloca(strlen(path_env)+1);  
         strcpy(e, path_env);  
         tok = strtok(e, delim);  
         while (tok != NULL) {  
                 char *path = malloc(strlen(tok)+strlen(prog)+2);  
                 sprintf(path, "%s/%s", tok, prog);  
                 if (access(path, X_OK&R_OK) == 0) {  
                         return path;  
                 }  
                 free(path);  
                 tok = strtok(NULL, delim);  
         }  
         return NULL;  
 }  
   
 static int mysocketAccept2(int fd, char *pass)  
 {  
     fd = mysocketAccept(fd);  
     if(login_with_otp(fd, pass)==0) {  
         decideByteOrderClient(fd, 0);  
         return fd;  
     }  
     close(fd);  
     return -1;  
 }  
   
 /* if it is not 0, then we use oxlog to execute ox. */  
 static int flag_ox_start_with_oxlog = 1;  
   
 /*  
    (-reverse 版の ox_start)  
    ox_start は クライアントが呼び出すための関数である.  
    サーバでは使われない.  ctl_prog はコントロールサーバであり,  
    -ox, -reverse, -data, -control, -pass, -host  
    というオプションを理解することを仮定する. dat_prog は計算サーバである.  
    接続時には, sv->control を先にオープンする.  
 */  
   
 ox_file_t ox_start(char* host, char* ctl_prog, char* dat_prog)  
 {  
     ox_file_t sv = NULL;  
     char *pass;  
     char ctl[128], dat[128];  
     short portControl = 0;  /* short! */  
     short portStream  = 0;  
         char *oxlog;  
   
         /* not overwrite */  
 #if 0  
         setenv("OpenXM_HOME", "/usr/local/OpenXM", 0);  
 #endif  
         if (getenv("OpenXM_HOME") == NULL) {  
                 putenv("OpenXM_HOME=/usr/local/OpenXM");  
         }  
   
         oxlog    = concat_openxm_home_bin("oxlog");  
         ctl_prog = concat_openxm_home_bin(ctl_prog);  
         dat_prog = concat_openxm_home_bin(dat_prog);  
   
     sv = malloc(sizeof(__ox_file_struct));  
     sv->control = mysocketListen(host, &portControl);  
     sv->stream  = mysocketListen(host, &portStream);  
   
     sprintf(ctl, "%d", portControl);  
     sprintf(dat, "%d", portStream);  
     pass = create_otp();  
   
     if (fork() == 0) {  
                 if (flag_ox_start_with_oxlog) {  
                         execl(oxlog, oxlog, "xterm", "-icon", "-e", ctl_prog,  
                                   "-reverse", "-ox", dat_prog,  
                                   "-data", dat, "-control", ctl, "-pass", pass,  
                                   "-host", host, NULL);  
                 }else {  
                         dup2(2, 1);  
                         dup2(open(tempnam("/tmp", "ox."), O_RDWR|O_CREAT|O_TRUNC, 0644),  2);  
                         execl(ctl_prog, ctl_prog, "-reverse", "-ox", dat_prog,  
                                   "-data", dat, "-control", ctl, "-pass", pass,  
                                   "-host", host, NULL);  
                 }  
                 exit(1);  
     }  
   
     if ((sv->control = mysocketAccept2(sv->control, pass)) == -1) {  
         close(sv->stream);  
         return NULL;  
     }  
     /* waiting 10 micro second. */  
     usleep(10);  
     if((sv->stream  = mysocketAccept2(sv->stream, pass)) == -1) {  
         return NULL;  
     }  
     return sv;  
 }  
   
 ox_file_t ox_start_remote_with_ssh(char *dat_prog, char* host)  
 {  
         ssh_ox_server(host, "ox", dat_prog, 1200, 1300);  
         return ox_start_insecure_nonreverse(host, 1200, 1300);  
 }  
   
 /* ssh -f host oxlog xterm -e ox -ox ox_asir ... */  
 int ssh_ox_server(char *host, char *ctl_prog, char *dat_prog, short portControl, short portStream)  
 {  
         char *oxlog;  
         char *ssh;  
   
         oxlog    = concat_openxm_home_bin("oxlog");  
         ctl_prog = concat_openxm_home_bin(ctl_prog);  
         dat_prog = concat_openxm_home_bin(dat_prog);  
   
         ssh = which("ssh", getenv("PATH"));  
   
         if (fork() == 0) {  
                 execl(ssh, ssh, "-f", host, oxlog, "xterm", "-icon",  
                           "-e", ctl_prog, "-insecure", "-ox", dat_prog,  
                           "-data", portStream, "-control", portControl,  
                           "-host", host, NULL);  
                 exit(1);  
         }  
 }  
   
 /*  
    (-insecure 版の ox_start)  まだ、中身はありません。  
    ox_start_insecure_nonreverse は クライアントが呼び出すための関数である.  
    接続時には, sv->control を先にオープンする.  
    既定値:  
    portControl = 1200  
    portStream  = 1300  
 */  
   
 ox_file_t ox_start_insecure_nonreverse(char* host, short portControl, short portStream)  
 {  
     ox_file_t sv = malloc(sizeof(__ox_file_struct));  
   
     sv->control = mysocketOpen(host, portControl);  
 #if 0  
     /* ox は insecure のとき byte order の決定が正しくできないようだ... */  
     decideByteOrderClient(sv->control, 0);  
 #endif  
     /* wainting 10 micro second. */  
     usleep(10);  
     sv->stream  = mysocketOpen(host, portStream);  
     decideByteOrderClient(sv->stream, 0);  
     return sv;  
 }  
   
 void ox_reset(ox_file_t sv)  
 {  
     send_ox_command(sv->control, SM_control_reset_connection);  
   
     receive_ox_tag(sv->control);      /* OX_DATA */  
     receive_cmo(sv->control);         /* (CMO_INT32, 0) */  
   
     while(receive_ox_tag(sv->stream) != OX_SYNC_BALL) {  
         receive_cmo(sv->stream); /* skipping a message. */  
     }  
   
     send_ox_tag(sv->stream, OX_SYNC_BALL);  
 #ifdef DEBUG  #ifdef DEBUG
     fprintf(stderr, "I have reset an Open XM server.\n");      fprintf(stderr, "I have reset an Open XM server.\n");
 #endif  #endif
 }  }
   
 /* the following functions are needed by bconv.c */  void send_ox(OXFILE *oxfp, ox *m)
   
 /* cmolen 関数は cmo の(送信時の)バイト長を返す. */  
 /* cmolen_XXX 関数は cmo_XXX の tag を除いたバイト長を返す. */  
   
 static int cmolen_cmo_null(cmo_null* c)  
 {  {
     return 0;  
 }  
   
 static int cmolen_cmo_int32(cmo_int32* c)  
 {  
     return sizeof(int);  
 }  
   
 static int cmolen_cmo_string(cmo_string* c)  
 {  
     return sizeof(int)+strlen(c->s);  
 }  
   
 static int cmolen_cmo_mathcap(cmo_mathcap* c)  
 {  
     return cmolen_cmo(c->ob);  
 }  
   
 static int cmolen_cmo_list(cmo_list* c)  
 {  
     int size = sizeof(int);  
     cell* cp = c->head;  
   
     while(cp->next != NULL) {  
         size += cmolen_cmo(cp->cmo);  
         cp = cp->next;  
     }  
     return size;  
 }  
   
 static int cmolen_cmo_monomial32(cmo_monomial32* c)  
 {  
     int len = (c->length + 1)*sizeof(int);  
     return len + cmolen_cmo(c->coef);  
 }  
   
 static int cmolen_cmo_zz(cmo_zz* c)  
 {  
     int len = abs(c->mpz->_mp_size);  
     return sizeof(len) + len*sizeof(int);  
 }  
   
 static int cmolen_cmo_distributed_polynomial(cmo_distributed_polynomial* c)  
 {  
     return cmolen_cmo_list((cmo_list *)c) + cmolen_cmo(c->ringdef);  
 }  
   
 /* calculating the length of the byte stream of given CMO.  */  
 int cmolen_cmo(cmo* c)  
 {  
     int size = sizeof(int);  
   
     switch(c->tag) {  
     case CMO_NULL:  
     case CMO_ZERO:  
     case CMO_DMS_GENERIC:  
         size += cmolen_cmo_null(c);  
         break;  
     case CMO_INT32:  
         size += cmolen_cmo_int32((cmo_int32 *)c);  
         break;  
     case CMO_STRING:  
         size += cmolen_cmo_string((cmo_string *)c);  
         break;  
     case CMO_MATHCAP:  
     case CMO_RING_BY_NAME:  
     case CMO_INDETERMINATE:  
     case CMO_ERROR2:  
         size += cmolen_cmo_mathcap((cmo_mathcap *)c);  
         break;  
     case CMO_LIST:  
         size += cmolen_cmo_list((cmo_list *)c);  
         break;  
     case CMO_MONOMIAL32:  
         size += cmolen_cmo_monomial32((cmo_monomial32 *)c);  
         break;  
     case CMO_ZZ:  
         size += cmolen_cmo_zz((cmo_zz *)c);  
         break;  
     case CMO_DISTRIBUTED_POLYNOMIAL:  
         size += cmolen_cmo_distributed_polynomial((cmo_distributed_polynomial *)c);  
         break;  
     default:  
     }  
     return size;  
 }  
   
 static int  d_ptr;  
 static char *d_buf;  
   
 int init_dump_buffer(char *s)  
 {  
     d_buf = s;  
     d_ptr = 0;  
 }  
   
 static int dump_cmo_null(cmo_null* m)  
 {  
     return 0;  
 }  
   
 static int dump_cmo_int32(cmo_int32* m)  
 {  
     dump_integer(m->i);  
 }  
   
 static int dump_cmo_string(cmo_string* m)  
 {  
     int len = strlen(m->s);  
     dump_integer(len);  
     dump_string(m->s, len);  
 }  
   
 static int dump_cmo_mathcap(cmo_mathcap* c)  
 {  
     dump_cmo(c->ob);  
 }  
   
 static int dump_cmo_list(cmo_list* m)  
 {  
     cell* cp = m->head;  
     int len = length_cmo_list(m);  
     dump_integer(len);  
   
     while(cp->next != NULL) {  
         dump_cmo(cp->cmo);  
         cp = cp->next;  
     }  
 }  
   
 static int dump_cmo_monomial32(cmo_monomial32* c)  
 {  
     int i;  
     int length = c->length;  
     dump_integer(c->length);  
     for(i=0; i<length; i++) {  
         dump_integer(c->exps[i]);  
     }  
     dump_cmo(c->coef);  
 }  
   
 static int dump_cmo_zz(cmo_zz* c)  
 {  
     dump_mpz(c->mpz);  
 }  
   
 static int dump_cmo_distributed_polynomial(cmo_distributed_polynomial* m)  
 {  
     cell* cp = m->head;  
     int len = length_cmo_list((cmo_list *)m);  
     dump_integer(len);  
     dump_cmo(m->ringdef);  
     while(cp != NULL) {  
         dump_cmo(cp->cmo);  
         cp = cp->next;  
     }  
 }  
   
 /* after its tag is sent, we invoke each functions. */  
 int dump_cmo(cmo* m)  
 {  
     dump_integer(m->tag);  
     switch(m->tag) {      switch(m->tag) {
     case CMO_NULL:      case OX_DATA:
     case CMO_ZERO:          send_ox_cmo(oxfp, ((ox_data *)m)->cmo);
     case CMO_DMS_GENERIC:  
         dump_cmo_null(m);  
         break;          break;
     case CMO_INT32:      case OX_COMMAND:
         dump_cmo_int32((cmo_int32 *)m);          send_ox_command(oxfp, ((ox_command *)m)->command);
         break;          break;
     case CMO_STRING:  
         dump_cmo_string((cmo_string *)m);  
         break;  
     case CMO_MATHCAP:  
     case CMO_RING_BY_NAME:  
     case CMO_INDETERMINATE:  
     case CMO_ERROR2:  
         dump_cmo_mathcap((cmo_mathcap *)m);  
         break;  
     case CMO_LIST:  
         dump_cmo_list((cmo_list *)m);  
         break;  
     case CMO_MONOMIAL32:  
         dump_cmo_monomial32((cmo_monomial32 *)m);  
         break;  
     case CMO_ZZ:  
         dump_cmo_zz((cmo_zz *)m);  
         break;  
     case CMO_DISTRIBUTED_POLYNOMIAL:  
         dump_cmo_distributed_polynomial((cmo_distributed_polynomial *)m);  
         break;  
     default:      default:
     }  
 }  
   
 static int dump_mpz(mpz_ptr mpz)  
 {  
     int i;  
     int len = abs(mpz->_mp_size);  
     dump_integer(mpz->_mp_size);  
     for(i=0; i<len; i++) {  
         dump_integer(mpz->_mp_d[i]);  
     }  
     return;  
 }  
   
 static int dump_string(char *s, int len)  
 {  
     memcpy(&d_buf[d_ptr], s, len);  
     d_ptr += len;  
 }  
   
 static int dump_integer(int x)  
 {  
     int nx = htonl(x);  
     dump_string((char *)&nx, sizeof(int));  
 }  
   
 int dump_ox_data(ox_data* m)  
 {  
     dump_integer(OX_DATA);  
     dump_integer(-1);  
     dump_cmo(m->cmo);  
 }  
   
 int dump_ox_command(ox_command* m)  
 {  
     dump_integer(OX_COMMAND);  
     dump_integer(-1);  
     dump_integer(m->command);  
 }  
   
 int send_ox(int fd, ox *m)  
 {  
     int code;  
         switch(m->tag) {  
         case OX_DATA:  
         send_ox_cmo(fd, ((ox_data *)m)->cmo);  
                 break;  
         case OX_COMMAND:  
                 send_ox_command(fd, ((ox_command *)m)->command);  
                 break;  
         default:  
 #if 0  
         /* CMO?? */          /* CMO?? */
         send_ox_cmo(s->stream, (cmo *)m);          send_ox_cmo(oxfp, (cmo *)m);
 #endif  
     }      }
 }  }
   
 int send_ox_cmo(int fd, cmo* m)  void send_ox_cmo(OXFILE *oxfp, cmo* m)
 {  {
     send_ox_tag(fd, OX_DATA);      send_ox_tag(oxfp, OX_DATA);
     send_cmo(fd, m);      send_cmo(oxfp, m);
       oxf_flush(oxfp);
 }  }
   
 /* send_cmo_* functions */  /* send_cmo_* functions */
 static int send_cmo_null(int fd, cmo_null* c)  static int send_cmo_null(OXFILE *oxfp, cmo_null* c)
 {  {
     return 0;      return 0;
 }  }
   
 static int send_cmo_int32(int fd, cmo_int32* m)  static int send_cmo_int32(OXFILE *oxfp, cmo_int32* m)
 {  {
     send_int32(fd, m->i);      return send_int32(oxfp, m->i);
 }  }
   
 static int send_cmo_string(int fd, cmo_string* m)  static int send_cmo_string(OXFILE *oxfp, cmo_string* m)
 {  {
     int len = (m->s != NULL)? strlen(m->s): 0;      int len = (m->s != NULL)? strlen(m->s): 0;
     send_int32(fd, len);      send_int32(oxfp, len);
     if (len > 0) {      if (len > 0) {
         write(fd, m->s, len);          oxf_write(m->s, 1, len, oxfp);
     }      }
     return 0;      return 0;
 }  }
   
 static int send_cmo_mathcap(int fd, cmo_mathcap* c)  static int send_cmo_mathcap(OXFILE *oxfp, cmo_mathcap* c)
 {  {
     send_cmo(fd, c->ob);      send_cmo(oxfp, c->ob);
     return 0;      return 0;
 }  }
   
 static int send_cmo_list(int fd, cmo_list* c)  static int send_cmo_list(OXFILE *oxfp, cmo_list* c)
 {  {
     cell* cp = c->head;      cell* el = list_first(c);
     int len = length_cmo_list(c);      int len = list_length(c);
     send_int32(fd, len);      send_int32(oxfp, len);
   
     while(cp->next != NULL) {      while(!list_endof(c, el)) {
         send_cmo(fd, cp->cmo);          send_cmo(oxfp, el->cmo);
         cp = cp->next;          el = list_next(el);
     }      }
     return 0;      return 0;
 }  }
   
 static int send_cmo_distributed_polynomial(int fd, cmo_distributed_polynomial* c)  static int send_cmo_distributed_polynomial(OXFILE *oxfp, cmo_distributed_polynomial* c)
 {  {
     cell* cp = c->head;      cell* el = list_first((cmo_list *)c);
     int len = length_cmo_list((cmo_list *)c);      int len = list_length((cmo_list *)c);
     send_int32(fd, len);      send_int32(oxfp, len);
     send_cmo(fd, c->ringdef);      send_cmo(oxfp, c->ringdef);
       while(!list_endof((cmo_list *)c, el)) {
     while(cp->next != NULL) {          send_cmo(oxfp, el->cmo);
         send_cmo(fd, cp->cmo);          el = list_next(el);
         cp = cp->next;  
     }      }
     return 0;      return 0;
 }  }
   
 static int send_cmo_monomial32(int fd, cmo_monomial32* c)  static int send_cmo_monomial32(OXFILE *oxfp, cmo_monomial32* c)
 {  {
     int i;      int i;
     int len = c->length;      int len = c->length;
     send_int32(fd, len);      send_int32(oxfp, len);
     for(i=0; i<len; i++) {      for(i=0; i<len; i++) {
         send_int32(fd, c->exps[i]);          send_int32(oxfp, c->exps[i]);
     }      }
     send_cmo(fd, c->coef);      send_cmo(oxfp, c->coef);
     return 0;      return 0;
 }  }
   
 static int send_cmo_zz(int fd, cmo_zz* c)  static int send_cmo_zz(OXFILE *oxfp, cmo_zz* c)
 {  {
     send_mpz(fd, c->mpz);      send_mpz(oxfp, c->mpz);
     return 0;      return 0;
 }  }
   
 static int send_cmo_error2(int fd, cmo_error2* c)  static int send_cmo_error2(OXFILE *oxfp, cmo_error2* c)
 {  {
     send_cmo(fd, c->ob);      send_cmo(oxfp, c->ob);
     return 0;      return 0;
 }  }
   
 /* sending a CMO.  (Remarks: OX_tag is already sent.) */  /* sending a CMO.  (Remarks: OX_tag is already sent.) */
 int send_cmo(int fd, cmo* c)  void send_cmo(OXFILE *oxfp, cmo* c)
 {  {
     int tag = c->tag;      int tag = c->tag;
   
         c = call_hook_before_send_cmo(fd, c);      c = call_hook_before_send_cmo(oxfp, c);
   
     send_int32(fd, tag);      send_int32(oxfp, tag);
     switch(tag) {      switch(tag) {
     case CMO_NULL:      case CMO_NULL:
     case CMO_ZERO:      case CMO_ZERO:
     case CMO_DMS_GENERIC:      case CMO_DMS_GENERIC:
         send_cmo_null(fd, c);  /* empty function. */          send_cmo_null(oxfp, c);  /* empty function. */
         break;          break;
     case CMO_INT32:      case CMO_INT32:
         send_cmo_int32(fd, (cmo_int32 *)c);          send_cmo_int32(oxfp, (cmo_int32 *)c);
         break;          break;
     case CMO_STRING:      case CMO_STRING:
         send_cmo_string(fd, (cmo_string *)c);          send_cmo_string(oxfp, (cmo_string *)c);
         break;          break;
     case CMO_MATHCAP:      case CMO_MATHCAP:
     case CMO_ERROR2:      case CMO_ERROR2:
     case CMO_RING_BY_NAME:      case CMO_RING_BY_NAME:
     case CMO_INDETERMINATE:      case CMO_INDETERMINATE:
         send_cmo_mathcap(fd, (cmo_mathcap *)c);          send_cmo_mathcap(oxfp, (cmo_mathcap *)c);
         break;          break;
     case CMO_LIST:      case CMO_LIST:
         send_cmo_list(fd, (cmo_list *)c);          send_cmo_list(oxfp, (cmo_list *)c);
         break;          break;
     case CMO_MONOMIAL32:      case CMO_MONOMIAL32:
         send_cmo_monomial32(fd, (cmo_monomial32 *)c);          send_cmo_monomial32(oxfp, (cmo_monomial32 *)c);
         break;          break;
     case CMO_ZZ:      case CMO_ZZ:
         send_cmo_zz(fd, (cmo_zz *)c);          send_cmo_zz(oxfp, (cmo_zz *)c);
         break;          break;
     case CMO_DISTRIBUTED_POLYNOMIAL:      case CMO_DISTRIBUTED_POLYNOMIAL:
         send_cmo_distributed_polynomial(fd, (cmo_distributed_polynomial *)c);          send_cmo_distributed_polynomial(oxfp, (cmo_distributed_polynomial *)c);
         break;          break;
     default:      default:
                 call_hook_after_send_cmo(fd, c);          call_hook_after_send_cmo(oxfp, c);
     }      }
 }  }
   
 static int send_mpz(int fd, mpz_ptr mpz)  static int send_mpz(OXFILE *oxfp, mpz_ptr mpz)
 {  {
     int i;      int i;
     int len = abs(mpz->_mp_size);      int len = abs(mpz->_mp_size);
     send_int32(fd, mpz->_mp_size);      send_int32(oxfp, mpz->_mp_size);
     for(i=0; i<len; i++) {      for(i=0; i<len; i++) {
         send_int32(fd, mpz->_mp_d[i]);          send_int32(oxfp, mpz->_mp_d[i]);
     }      }
     return 0;      return 0;
 }  }
Line 1335  ox_sync_ball* new_ox_sync_ball()
Line 635  ox_sync_ball* new_ox_sync_ball()
     ox_sync_ball *m = malloc(sizeof(ox_sync_ball));      ox_sync_ball *m = malloc(sizeof(ox_sync_ball));
     m->tag = OX_SYNC_BALL;      m->tag = OX_SYNC_BALL;
     return m;      return m;
 }  
   
 #define ID_TEMP   "(CMO_LIST, (CMO_INT32, %d), (CMO_STRING, \"%s\"), (CMO_STRING, \"%s\"), (CMO_STRING, \"%s\"))"  
   
 static cmo_list* make_list_of_id(int ver, char* ver_s, char* sysname)  
 {  
     cmo_list *cap;  
     char buff[512];  
   
     sprintf(buff, ID_TEMP, ver, sysname, ver_s, getenv("HOSTTYPE"));  
     init_parser(buff);  
     cap = (cmo_list *)parse();  
   
     return cap;  
 }  
   
 static cmo_list *make_list_of_tag(int type)  
 {  
     cmo_list *li = new_cmo_list();  
     symbol_t symp;  
     int i = 0;  
     while((symp = lookup(i++))->key != NULL) {  
         if (symp->type == type) {  
             append_cmo_list(li, (cmo *)new_cmo_int32(symp->tag));  
         }  
     }  
     return li;  
 }  
   
 cmo* make_mathcap_object(int version, char *id_string)  
 {  
     char *sysname    = "ox_math";  
     cmo_list *li     = new_cmo_list();  
     cmo_list *li_1st = make_list_of_id(version, id_string, sysname);  
     cmo_list *li_2nd = make_list_of_tag(IS_SM);  
     cmo_list *li_3rd = new_cmo_list();  
     cmo_list *li_cmo = make_list_of_tag(IS_CMO);  
   
     cmo_list *li_ox_data  = new_cmo_list();  
     append_cmo_list(li_ox_data,  (cmo *)new_cmo_int32(OX_DATA));  
     append_cmo_list(li_ox_data,  (cmo *)li_cmo);  
     append_cmo_list(li_3rd, (cmo *)li_ox_data);  
   
     append_cmo_list(li, (cmo *)li_1st);  
     append_cmo_list(li, (cmo *)li_2nd);  
     append_cmo_list(li, (cmo *)li_3rd);  
   
     return (cmo *)new_cmo_mathcap((cmo *)li);  
 }  
   
 /* ファイルディスクリプタ fd の通信路での integer の byte order を決定する */  
 /* 実際には order (0,1,or 0xFF)をみてはいない */  
 int decideByteOrderClient(oxfd fd, int order)  
 {  
     char zero = OX_BYTE_NETWORK_BYTE_ORDER;  
     char dest;  
     read(fd, &dest, sizeof(char));  
     write(fd, &zero, sizeof(char));  
     return 0;  
 }  
   
 /* Server 側ではこちらを用いる */  
 /* いまの実装は dup されていることが前提になっている */  
 int decideByteOrderServer(oxfd fd, int order)  
 {  
     char zero = OX_BYTE_NETWORK_BYTE_ORDER;  
     char dest;  
     write(fd, &zero, sizeof(char));  
     read(fd, &dest, sizeof(char));  
     return 0;  
 }  
   
 /* cmo と string (ここではC言語のstring) の変換関数群 */  
 static char *new_string_set_cmo_zz(cmo_zz *c)  
 {  
     return mpz_get_str(NULL, 10, c->mpz);  
 }  
   
 static char *new_string_set_cmo_null()  
 {  
     static char* null_string = "";  
     return null_string;  
 }  
   
 static char *new_string_set_cmo_int32(int integer)  
 {  
     char buff[1024];  
     char *s;  
   
     sprintf(buff, "%d", integer);  
     s = malloc(strlen(buff)+1);  
     strcpy(s, buff);  
   
     return s;  
 }  
   
 static char *new_string_set_cmo_list(cmo_list *m)  
 {  
     char *s;  
     int i;  
     int size = 0;  
     int len = length_cmo_list(m);  
     char **sp = malloc(len*sizeof(cmo *));  
   
     cell *cp = m->head;  
     for(i = 0; i < len; i++) {  
         sp[i] = new_string_set_cmo(cp->cmo);  
         size += strlen(sp[i]) + 3;  
         cp = cp->next;  
     }  
     s = malloc(size+2);  
     strcpy(s, "[ ");  
     for(i = 0; i < len - 1; i++) {  
         strcat(s, sp[i]);  
         strcat(s, " , ");  
     }  
     strcat(s, sp[len-1]);  
     strcat(s, " ]");  
     free(sp);  
     return s;  
 }  
   
 char *new_string_set_cmo(cmo *m)  
 {  
     symbol_t symp;  
     switch(m->tag) {  
     case CMO_ZZ:  
         return new_string_set_cmo_zz((cmo_zz *)m);  
     case CMO_INT32:  
         return new_string_set_cmo_int32(((cmo_int32 *)m)->i);  
     case CMO_STRING:  
         return ((cmo_string *)m)->s;  
     case CMO_NULL:  
         return new_string_set_cmo_null();  
     case CMO_LIST:  
         return new_string_set_cmo_list((cmo_list *)m);  
     default:  
 #ifdef DEBUG  
         symp = lookup_by_tag(m->tag);  
         fprintf(stderr, "I do not know how to convert %s to a string.\n", symp->key);  
 #endif  
         /* yet not implemented. */  
         return NULL;  
     }  
 }  }

Legend:
Removed from v.1.12  
changed lines
  Added in v.1.13

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